-
-
Notifications
You must be signed in to change notification settings - Fork 180
/
state.ts
98 lines (90 loc) · 4.73 KB
/
state.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { Style } from '../../utils/style';
/*
* See MDN web docs for more information
* https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
*/
export function generateStates (
variantOrder: string[]
): { [key: string]: () => Style } {
const states: { [key: string]: () => Style } = {
// Interactive links/buttons
hover: () => new Style().pseudoClass('hover'),
focus: () => new Style().pseudoClass('focus'),
active: () => new Style().pseudoClass('active'),
visited: () => new Style().pseudoClass('visited'),
link: () => new Style().pseudoClass('link'),
target: () => new Style().pseudoClass('target'),
'focus-visible': () => new Style().pseudoClass('focus-visible'),
'focus-within': () => new Style().pseudoClass('focus-within'),
// Form element states
checked: () => new Style().pseudoClass('checked'),
'not-checked': () => new Style().pseudoClass('not(:checked)'),
default: () => new Style().pseudoClass('default'),
disabled: () => new Style().pseudoClass('disabled'),
enabled: () => new Style().pseudoClass('enabled'),
indeterminate: () => new Style().pseudoClass('indeterminate'),
invalid: () => new Style().pseudoClass('invalid'),
valid: () => new Style().pseudoClass('valid'),
optional: () => new Style().pseudoClass('optional'),
required: () => new Style().pseudoClass('required'),
'placeholder-shown': () => new Style().pseudoClass('placeholder-shown'),
'read-only': () => new Style().pseudoClass('read-only'),
'read-write': () => new Style().pseudoClass('read-write'),
// Child selectors
'not-disabled': () => new Style().pseudoClass('not(:disabled)'),
'first-of-type': () => new Style().pseudoClass('first-of-type'),
'not-first-of-type': () => new Style().pseudoClass('not(:first-of-type)'),
'last-of-type': () => new Style().pseudoClass('last-of-type'),
'not-last-of-type': () => new Style().pseudoClass('not(:last-of-type)'),
first: () => new Style().pseudoClass('first-child'),
last: () => new Style().pseudoClass('last-child'),
'not-first': () => new Style().pseudoClass('not(:first-child)'),
'not-last': () => new Style().pseudoClass('not(:last-child)'),
'only-child': () => new Style().pseudoClass('only-child'),
'not-only-child': () => new Style().pseudoClass('not(:only-child)'),
'only-of-type': () => new Style().pseudoClass('only-of-type'),
'not-only-of-type': () => new Style().pseudoClass('not(:only-of-type)'),
even: () => new Style().pseudoClass('nth-child(even)'),
odd: () => new Style().pseudoClass('nth-child(odd)'),
'even-of-type': () => new Style().pseudoClass('nth-of-type(even)'),
'odd-of-type': () => new Style().pseudoClass('nth-of-type(odd)'),
root: () => new Style().pseudoClass('root'),
empty: () => new Style().pseudoClass('empty'),
// Pseudo elements
before: () => new Style().pseudoElement('before'),
after: () => new Style().pseudoElement('after'),
'first-letter': () => new Style().pseudoElement('first-letter'),
'first-line': () => new Style().pseudoElement('first-line'),
'file-selector-button': () => new Style().pseudoElement('file-selector-button'),
file: () => new Style().pseudoElement('file-selector-button'),
selection: () => new Style().pseudoElement('selection'),
marker: () => new Style().wrapSelector(selector => `${selector} *::marker, ${selector}::marker`),
svg: () => new Style().child('svg'),
all: () => new Style().child('*'),
children: () => new Style().child('> *'),
siblings: () => new Style().child('~ *'),
sibling: () => new Style().child('+ *'),
// https://www.w3schools.com/CSS/css_pseudo_elements.asp
// Directions
ltr: () => new Style().wrapSelector(selector => `[dir='ltr'] ${selector}, [dir='ltr']${selector}`),
rtl: () => new Style().wrapSelector(selector => `[dir='rtl'] ${selector}, [dir='rtl']${selector}`),
// Group states
// You'll need to add className="group" to an ancestor to make these work
// https://github.com/ben-rogerson/twin.macro/blob/master/docs/group.md
'group-hover': () => new Style().parent('.group:hover'),
'group-focus': () => new Style().parent('.group:focus'),
'group-active': () => new Style().parent('.group:active'),
'group-visited': () => new Style().parent('.group:visited'),
// Motion control
// https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion
'motion-safe': () => new Style().atRule('@media (prefers-reduced-motion: no-preference)'),
'motion-reduce': () => new Style().atRule('@media (prefers-reduced-motion: reduce)'),
};
const orderedStates: typeof states = {};
variantOrder.forEach((v) => {
if (v in states) {
orderedStates[v] = states[v];
}
});
return orderedStates;
}