Skip to content

Commit 5b55b0a

Browse files
authored
Adds theme keypaths to our sx prop type for better autocomplete (#1544)
* Adds theme keypaths to our sx prop type for better autocomplete * Changeset patch -> minor
1 parent 32a3166 commit 5b55b0a

File tree

5 files changed

+122
-2
lines changed

5 files changed

+122
-2
lines changed

.changeset/silly-coins-sit.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/components': minor
3+
---
4+
5+
The sx prop now has types that will inform autocomplete for color and shadow values that are key paths into the theme.

src/__tests__/KeyPaths.types.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {KeyPaths} from '../utils/types/KeyPaths'
2+
3+
type NestedObject = {
4+
a: string
5+
b: {
6+
b1: string
7+
b2: string
8+
}
9+
}
10+
11+
export function generatesKeyPathsFromObject(x: KeyPaths<NestedObject>): 'a' | 'b.b1' | 'b.b2' {
12+
return x
13+
}

src/sx.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
1-
import css, {SystemStyleObject} from '@styled-system/css'
1+
import css, {SystemCssProperties, SystemStyleObject} from '@styled-system/css'
2+
import {ThemeColorPaths, ThemeShadowPaths} from './theme'
3+
import {ColorProps, ShadowProps} from 'styled-system'
4+
5+
export type BetterCssProperties = {
6+
[K in keyof SystemCssProperties]: K extends keyof ColorProps
7+
? ThemeColorPaths | SystemCssProperties[K]
8+
: K extends keyof ShadowProps
9+
? ThemeShadowPaths | SystemCssProperties[K]
10+
: SystemCssProperties[K]
11+
}
12+
13+
export type BetterSystemStyleObject = BetterCssProperties | SystemStyleObject
214

315
export interface SxProp {
4-
sx?: SystemStyleObject
16+
sx?: BetterSystemStyleObject
517
}
618

719
const sx = (props: SxProp) => css(props.sx)

src/theme.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,89 @@
11
import {theme} from './theme-preval'
2+
import {KeyPaths} from './utils/types/KeyPaths'
23

34
export default theme
5+
6+
// NOTE: for now, ThemeColors and ThemeShadows are handcrafted types. It would be nice if these
7+
// were exports from primitives (or a different shape but derived from those exports).
8+
9+
type ThemeColors = {
10+
fg: {
11+
default: string
12+
muted: string
13+
subtle: string
14+
onEmphasis: string
15+
}
16+
canvas: {
17+
default: string
18+
overlay: string
19+
inset: string
20+
subtle: string
21+
}
22+
border: {
23+
default: string
24+
muted: string
25+
subtle: string
26+
}
27+
28+
// Roles
29+
neutral: {
30+
emphasisPlus: string
31+
emphasis: string
32+
muted: string
33+
subtle: string
34+
}
35+
accent: {
36+
fg: string
37+
emphasis: string
38+
muted: string
39+
subtle: string
40+
}
41+
success: {
42+
fg: string
43+
emphasis: string
44+
muted: string
45+
subtle: string
46+
}
47+
attention: {
48+
fg: string
49+
emphasis: string
50+
muted: string
51+
subtle: string
52+
}
53+
severe: {
54+
fg: string
55+
emphasis: string
56+
muted: string
57+
subtle: string
58+
}
59+
danger: {
60+
fg: string
61+
emphasis: string
62+
muted: string
63+
subtle: string
64+
}
65+
done: {
66+
fg: string
67+
emphasis: string
68+
muted: string
69+
subtle: string
70+
}
71+
sponsors: {
72+
fg: string
73+
emphasis: string
74+
muted: string
75+
subtle: string
76+
}
77+
}
78+
79+
type ThemeShadows = {
80+
shadow: {
81+
small: string
82+
medium: string
83+
large: string
84+
extraLarge: string
85+
}
86+
}
87+
88+
export type ThemeColorPaths = KeyPaths<ThemeColors>
89+
export type ThemeShadowPaths = KeyPaths<ThemeShadows>

src/utils/types/KeyPaths.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Produces a union of dot-delimited keypaths to the string values in a nested object:
2+
export type KeyPaths<O extends Record<string, unknown>> = {
3+
[K in keyof O]: K extends string ? (O[K] extends string ? `${K}` : `${K}.${KeyPaths<O[K]>}`) : never
4+
}[keyof O]

0 commit comments

Comments
 (0)