tailwindcss-react-aria-components 1.0.0-rc.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwindcss-react-aria-components",
3
- "version": "1.0.0-rc.0",
3
+ "version": "1.0.0",
4
4
  "description": "A Tailwind plugin that adds variants for data attributes in React Aria Components",
5
5
  "license": "Apache-2.0",
6
6
  "main": "src/index.js",
@@ -25,5 +25,5 @@
25
25
  "publishConfig": {
26
26
  "access": "public"
27
27
  },
28
- "gitHead": "9ce2f674eab2cc8912800d3162dcf00a1ce94274"
28
+ "gitHead": "86b38c87868ce7f262e0df905e5ac4eb2653791d"
29
29
  }
package/src/index.js CHANGED
@@ -1,35 +1,45 @@
1
- import plugin from 'tailwindcss/plugin';
1
+ const plugin = require('tailwindcss/plugin');
2
2
 
3
+ // Order of these is important because it determines which states win in a conflict.
4
+ // We mostly follow Tailwind's defaults, adding our additional states following the categories they define.
5
+ // https://github.com/tailwindlabs/tailwindcss/blob/304c2bad6cb5fcb62754a4580b1c8f4c16b946ea/src/corePlugins.js#L83
3
6
  const attributes = {
4
7
  boolean: [
5
- ['hover', 'hovered'],
6
- ['focus', 'focused'],
7
- 'focus-visible',
8
- 'focus-within',
9
- 'pressed',
10
- 'disabled',
11
- 'drop-target',
12
- 'dragging',
13
- 'empty',
14
- 'allows-dragging',
8
+ // Conditions
15
9
  'allows-removing',
16
10
  'allows-sorting',
17
- ['placeholder-shown', 'placeholder'],
18
- 'selected',
19
- 'indeterminate',
20
- ['read-only', 'readonly'],
21
- 'required',
11
+ 'allows-dragging',
12
+
13
+ // States
14
+ 'open',
22
15
  'entering',
23
16
  'exiting',
24
- 'open',
17
+ 'indeterminate',
18
+ ['placeholder-shown', 'placeholder'],
19
+ 'current',
20
+ 'required',
25
21
  'unavailable',
22
+ 'invalid',
23
+ ['read-only', 'readonly'],
26
24
  'outside-month',
27
25
  'outside-visible-range',
26
+
27
+ // Content
28
+ 'empty',
29
+
30
+ // Interactive states
31
+ 'focus-within',
32
+ ['hover', 'hovered'],
33
+ ['focus', 'focused'],
34
+ 'focus-visible',
35
+ 'pressed',
36
+ 'selected',
28
37
  'selection-start',
29
38
  'selection-end',
30
- 'current',
31
- 'invalid',
32
- 'resizing'
39
+ 'dragging',
40
+ 'drop-target',
41
+ 'resizing',
42
+ 'disabled'
33
43
  ],
34
44
  enum: {
35
45
  placement: ['left', 'right', 'top', 'bottom'],
@@ -56,15 +66,27 @@ const nativeVariantSelectors = new Map([
56
66
  ['hovered', ':hover'],
57
67
  ['focused', ':focus'],
58
68
  ['readonly', ':read-only'],
59
- ['open', '[open]'],
69
+ ['open', '[open]']
70
+ ]);
71
+
72
+ // Variants where both native and RAC attributes should apply. We don't override these.
73
+ const nativeMergeSelectors = new Map([
60
74
  ['placeholder', ':placeholder-shown']
61
75
  ]);
62
76
 
63
77
  // If no prefix is specified, we want to avoid overriding native variants on non-RAC components, so we only target elements with the data-rac attribute for those variants.
64
- let getSelector = (prefix, attributeName, attributeValue) => {
78
+ let getSelector = (prefix, attributeName, attributeValue, hoverOnlyWhenSupported) => {
65
79
  let baseSelector = attributeValue ? `[data-${attributeName}="${attributeValue}"]` : `[data-${attributeName}]`;
66
- if (prefix === '' && nativeVariantSelectors.has(attributeName)) {
67
- return [`&:where([data-rac])${baseSelector}`, `&:where(:not([data-rac]))${nativeVariantSelectors.get(attributeName)}`];
80
+ let nativeSelector = nativeVariantSelectors.get(attributeName);
81
+ if (prefix === '' && nativeSelector) {
82
+ let wrappedNativeSelector = `&:where(:not([data-rac]))${nativeSelector}`;
83
+ let nativeSelectorGenerator = wrappedNativeSelector;
84
+ if (nativeSelector === ':hover' && hoverOnlyWhenSupported) {
85
+ nativeSelectorGenerator = wrap => `@media (hover: hover) and (pointer: fine) { ${wrap(wrappedNativeSelector)} }`;
86
+ }
87
+ return [`&:where([data-rac])${baseSelector}`, nativeSelectorGenerator];
88
+ } else if (prefix === '' && nativeMergeSelectors.has(attributeName)) {
89
+ return [`&${baseSelector}`, `&${nativeMergeSelectors.get(attributeName)}`];
68
90
  } else {
69
91
  return `&${baseSelector}`;
70
92
  }
@@ -78,43 +100,56 @@ let mapSelector = (selector, fn) => {
78
100
  }
79
101
  };
80
102
 
103
+ let wrapSelector = (selector, wrap) => {
104
+ if (typeof selector === 'function') {
105
+ return selector(wrap);
106
+ } else {
107
+ return wrap(selector);
108
+ }
109
+ };
110
+
81
111
  let addVariants = (variantName, selectors, addVariant, matchVariant) => {
82
- addVariant(variantName, selectors);
112
+ addVariant(variantName, mapSelector(selectors, selector => wrapSelector(selector, s => s)));
83
113
  matchVariant(
84
114
  'group',
85
115
  (_, {modifier}) =>
86
116
  modifier
87
- ? mapSelector(selectors, selector => `:merge(.group\\/${modifier})${selector.slice(1)} &`)
88
- : mapSelector(selectors, selector => `:merge(.group)${selector.slice(1)} &`),
117
+ ? mapSelector(selectors, selector => wrapSelector(selector, s => `:merge(.group\\/${modifier})${s.slice(1)} &`))
118
+ : mapSelector(selectors, selector => wrapSelector(selector, s => `:merge(.group)${s.slice(1)} &`)),
89
119
  {values: {[variantName]: variantName}}
90
120
  );
91
121
  matchVariant(
92
122
  'peer',
93
123
  (_, {modifier}) =>
94
124
  modifier
95
- ? mapSelector(selectors, selector => `:merge(.peer\\/${modifier})${selector.slice(1)} ~ &`)
96
- : mapSelector(selectors, selector => `:merge(.peer)${selector.slice(1)} ~ &`),
125
+ ? mapSelector(selectors, selector => wrapSelector(selector, s => `:merge(.peer\\/${modifier})${s.slice(1)} ~ &`))
126
+ : mapSelector(selectors, selector => wrapSelector(selector, s => `:merge(.peer)${s.slice(1)} ~ &`)),
97
127
  {values: {[variantName]: variantName}}
98
128
  );
99
129
  };
100
130
 
101
- module.exports = plugin.withOptions((options) => (({addVariant, matchVariant}) => {
131
+ module.exports = plugin.withOptions((options) => (({addVariant, matchVariant, config}) => {
102
132
  let prefix = options?.prefix ? `${options.prefix}-` : '';
133
+ let future = config().future;
134
+ let hoverOnlyWhenSupported = future === 'all' || future?.hoverOnlyWhenSupported;
135
+
136
+ // Enum attributes go first because currently they are all non-interactive states.
137
+ Object.keys(attributes.enum).forEach((attributeName) => {
138
+ attributes.enum[attributeName].forEach(
139
+ (attributeValue) => {
140
+ let name = shortNames[attributeName] || attributeName;
141
+ let variantName = `${prefix}${name}-${attributeValue}`;
142
+ let selectors = getSelector(prefix, attributeName, attributeValue, hoverOnlyWhenSupported);
143
+ addVariants(variantName, selectors, addVariant, matchVariant);
144
+ }
145
+ );
146
+ });
147
+
103
148
  attributes.boolean.forEach((attribute) => {
104
149
  let variantName = Array.isArray(attribute) ? attribute[0] : attribute;
105
150
  variantName = `${prefix}${variantName}`;
106
151
  let attributeName = Array.isArray(attribute) ? attribute[1] : attribute;
107
- let selectors = getSelector(prefix, attributeName);
152
+ let selectors = getSelector(prefix, attributeName, null, hoverOnlyWhenSupported);
108
153
  addVariants(variantName, selectors, addVariant, matchVariant);
109
154
  });
110
- Object.keys(attributes.enum).forEach((attributeName) => {
111
- attributes.enum[attributeName].forEach(
112
- (attributeValue) => {
113
- let name = shortNames[attributeName] || attributeName;
114
- let variantName = `${prefix}${name}-${attributeValue}`;
115
- let selectors = getSelector(prefix, attributeName, attributeValue);
116
- addVariants(variantName, selectors, addVariant, matchVariant);
117
- }
118
- );
119
- });
120
155
  }));
package/src/index.test.js CHANGED
@@ -5,13 +5,14 @@ const postcss = require('postcss');
5
5
  let html = String.raw;
6
6
  let css = String.raw;
7
7
 
8
- function run({options, content}) {
8
+ function run({options, content, future = {}}) {
9
9
  let {currentTestName} = expect.getState();
10
10
  let config = {
11
11
  plugins: [require('./index.js')(options)],
12
12
  corePlugins: {preflight: false},
13
13
  theme: {colors: {red: 'red'}},
14
- content: [{raw: content}]
14
+ content: [{raw: content}],
15
+ future
15
16
  };
16
17
 
17
18
  return postcss(tailwind(config)).process(
@@ -26,91 +27,87 @@ test('variants', async () => {
26
27
  let content = html`<div data-rac className="hover:bg-red focus:bg-red focus-visible:bg-red focus-within:bg-red pressed:bg-red disabled:bg-red drop-target:bg-red dragging:bg-red empty:bg-red allows-dragging:bg-red allows-removing:bg-red allows-sorting:bg-red placeholder-shown:bg-red selected:bg-red indeterminate:bg-red read-only:bg-red required:bg-red entering:bg-red exiting:bg-red open:bg-red unavailable:bg-red outside-month:bg-red outside-visible-range:bg-red selection-start:bg-red selection-end:bg-red current:bg-red invalid:bg-red resizing:bg-red placement-left:bg-red placement-right:bg-red placement-top:bg-red placement-bottom:bg-red type-literal:bg-red type-year:bg-red type-month:bg-red type-day:bg-red layout-grid:bg-red layout-stack:bg-red orientation-horizontal:bg-red orientation-vertical:bg-red selection-single:bg-red selection-multiple:bg-red resizable-right:bg-red resizable-left:bg-red resizable-both:bg-red sort-ascending:bg-red sort-descending:bg-red group-pressed:bg-red peer-pressed:bg-red group-hover:bg-red group/custom-name group-hover/custom-name:bg-red peer-pressed/custom-name:bg-red"></div>`;
27
28
  return run({content}).then((result) => {
28
29
  expect(result.css).toContain(css`
29
- .hover\:bg-red:where([data-rac])[data-hovered] {
30
- --tw-bg-opacity: 1;
31
- background-color: rgb(255 0 0 / var(--tw-bg-opacity))
32
- }
33
- .hover\:bg-red:where(:not([data-rac])):hover {
30
+ .placement-left\:bg-red[data-placement="left"] {
34
31
  --tw-bg-opacity: 1;
35
32
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
36
33
  }
37
- .group\/custom-name:where([data-rac])[data-hovered] .group-hover\/custom-name\:bg-red {
34
+ .placement-right\:bg-red[data-placement="right"] {
38
35
  --tw-bg-opacity: 1;
39
36
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
40
37
  }
41
- .group:where([data-rac])[data-hovered] .group-hover\:bg-red {
38
+ .placement-top\:bg-red[data-placement="top"] {
42
39
  --tw-bg-opacity: 1;
43
40
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
44
41
  }
45
- .group\/custom-name:where(:not([data-rac])):hover .group-hover\/custom-name\:bg-red {
42
+ .placement-bottom\:bg-red[data-placement="bottom"] {
46
43
  --tw-bg-opacity: 1;
47
44
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
48
45
  }
49
- .group:where(:not([data-rac])):hover .group-hover\:bg-red {
46
+ .type-literal\:bg-red[data-type="literal"] {
50
47
  --tw-bg-opacity: 1;
51
48
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
52
49
  }
53
- .focus\:bg-red:where([data-rac])[data-focused] {
50
+ .type-year\:bg-red[data-type="year"] {
54
51
  --tw-bg-opacity: 1;
55
52
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
56
53
  }
57
- .focus\:bg-red:where(:not([data-rac])):focus {
54
+ .type-month\:bg-red[data-type="month"] {
58
55
  --tw-bg-opacity: 1;
59
56
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
60
57
  }
61
- .focus-visible\:bg-red:where([data-rac])[data-focus-visible] {
58
+ .type-day\:bg-red[data-type="day"] {
62
59
  --tw-bg-opacity: 1;
63
60
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
64
61
  }
65
- .focus-visible\:bg-red:where(:not([data-rac])):focus-visible {
62
+ .layout-grid\:bg-red[data-layout="grid"] {
66
63
  --tw-bg-opacity: 1;
67
64
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
68
65
  }
69
- .focus-within\:bg-red:where([data-rac])[data-focus-within] {
66
+ .layout-stack\:bg-red[data-layout="stack"] {
70
67
  --tw-bg-opacity: 1;
71
68
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
72
69
  }
73
- .focus-within\:bg-red:where(:not([data-rac])):focus-within {
70
+ .orientation-horizontal\:bg-red[data-orientation="horizontal"] {
74
71
  --tw-bg-opacity: 1;
75
72
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
76
73
  }
77
- .pressed\:bg-red[data-pressed] {
74
+ .orientation-vertical\:bg-red[data-orientation="vertical"] {
78
75
  --tw-bg-opacity: 1;
79
76
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
80
77
  }
81
- .group[data-pressed] .group-pressed\:bg-red {
78
+ .selection-single\:bg-red[data-selection-mode="single"] {
82
79
  --tw-bg-opacity: 1;
83
80
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
84
81
  }
85
- .peer\/custom-name[data-pressed] ~ .peer-pressed\/custom-name\:bg-red {
82
+ .selection-multiple\:bg-red[data-selection-mode="multiple"] {
86
83
  --tw-bg-opacity: 1;
87
84
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
88
85
  }
89
- .peer[data-pressed] ~ .peer-pressed\:bg-red {
86
+ .resizable-right\:bg-red[data-resizable-direction="right"] {
90
87
  --tw-bg-opacity: 1;
91
88
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
92
89
  }
93
- .disabled\:bg-red:where([data-rac])[data-disabled] {
90
+ .resizable-left\:bg-red[data-resizable-direction="left"] {
94
91
  --tw-bg-opacity: 1;
95
92
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
96
93
  }
97
- .disabled\:bg-red:where(:not([data-rac])):disabled {
94
+ .resizable-both\:bg-red[data-resizable-direction="both"] {
98
95
  --tw-bg-opacity: 1;
99
96
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
100
97
  }
101
- .drop-target\:bg-red[data-drop-target] {
98
+ .sort-ascending\:bg-red[data-sort-direction="ascending"] {
102
99
  --tw-bg-opacity: 1;
103
100
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
104
101
  }
105
- .dragging\:bg-red[data-dragging] {
102
+ .sort-descending\:bg-red[data-sort-direction="descending"] {
106
103
  --tw-bg-opacity: 1;
107
104
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
108
105
  }
109
- .empty\:bg-red:where([data-rac])[data-empty] {
106
+ .allows-removing\:bg-red[data-allows-removing] {
110
107
  --tw-bg-opacity: 1;
111
108
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
112
109
  }
113
- .empty\:bg-red:where(:not([data-rac])):empty {
110
+ .allows-sorting\:bg-red[data-allows-sorting] {
114
111
  --tw-bg-opacity: 1;
115
112
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
116
113
  }
@@ -118,39 +115,39 @@ test('variants', async () => {
118
115
  --tw-bg-opacity: 1;
119
116
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
120
117
  }
121
- .allows-removing\:bg-red[data-allows-removing] {
118
+ .open\:bg-red:where([data-rac])[data-open] {
122
119
  --tw-bg-opacity: 1;
123
120
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
124
121
  }
125
- .allows-sorting\:bg-red[data-allows-sorting] {
122
+ .open\:bg-red:where(:not([data-rac]))[open] {
126
123
  --tw-bg-opacity: 1;
127
124
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
128
125
  }
129
- .placeholder-shown\:bg-red:where([data-rac])[data-placeholder] {
126
+ .entering\:bg-red[data-entering] {
130
127
  --tw-bg-opacity: 1;
131
128
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
132
129
  }
133
- .placeholder-shown\:bg-red:where(:not([data-rac])):placeholder-shown {
130
+ .exiting\:bg-red[data-exiting] {
134
131
  --tw-bg-opacity: 1;
135
132
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
136
133
  }
137
- .selected\:bg-red[data-selected] {
134
+ .indeterminate\:bg-red:where([data-rac])[data-indeterminate] {
138
135
  --tw-bg-opacity: 1;
139
136
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
140
137
  }
141
- .indeterminate\:bg-red:where([data-rac])[data-indeterminate] {
138
+ .indeterminate\:bg-red:where(:not([data-rac])):indeterminate {
142
139
  --tw-bg-opacity: 1;
143
140
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
144
141
  }
145
- .indeterminate\:bg-red:where(:not([data-rac])):indeterminate {
142
+ .placeholder-shown\:bg-red[data-placeholder] {
146
143
  --tw-bg-opacity: 1;
147
144
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
148
145
  }
149
- .read-only\:bg-red:where([data-rac])[data-readonly] {
146
+ .placeholder-shown\:bg-red:placeholder-shown {
150
147
  --tw-bg-opacity: 1;
151
148
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
152
149
  }
153
- .read-only\:bg-red:where(:not([data-rac])):read-only {
150
+ .current\:bg-red[data-current] {
154
151
  --tw-bg-opacity: 1;
155
152
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
156
153
  }
@@ -162,23 +159,23 @@ test('variants', async () => {
162
159
  --tw-bg-opacity: 1;
163
160
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
164
161
  }
165
- .entering\:bg-red[data-entering] {
162
+ .unavailable\:bg-red[data-unavailable] {
166
163
  --tw-bg-opacity: 1;
167
164
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
168
165
  }
169
- .exiting\:bg-red[data-exiting] {
166
+ .invalid\:bg-red:where([data-rac])[data-invalid] {
170
167
  --tw-bg-opacity: 1;
171
168
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
172
169
  }
173
- .open\:bg-red:where([data-rac])[data-open] {
170
+ .invalid\:bg-red:where(:not([data-rac])):invalid {
174
171
  --tw-bg-opacity: 1;
175
172
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
176
173
  }
177
- .open\:bg-red:where(:not([data-rac]))[open] {
174
+ .read-only\:bg-red:where([data-rac])[data-readonly] {
178
175
  --tw-bg-opacity: 1;
179
176
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
180
177
  }
181
- .unavailable\:bg-red[data-unavailable] {
178
+ .read-only\:bg-red:where(:not([data-rac])):read-only {
182
179
  --tw-bg-opacity: 1;
183
180
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
184
181
  }
@@ -190,103 +187,107 @@ test('variants', async () => {
190
187
  --tw-bg-opacity: 1;
191
188
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
192
189
  }
193
- .selection-start\:bg-red[data-selection-start] {
190
+ .empty\:bg-red:where([data-rac])[data-empty] {
194
191
  --tw-bg-opacity: 1;
195
192
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
196
193
  }
197
- .selection-end\:bg-red[data-selection-end] {
194
+ .empty\:bg-red:where(:not([data-rac])):empty {
198
195
  --tw-bg-opacity: 1;
199
196
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
200
197
  }
201
- .current\:bg-red[data-current] {
198
+ .focus-within\:bg-red:where([data-rac])[data-focus-within] {
202
199
  --tw-bg-opacity: 1;
203
200
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
204
201
  }
205
- .invalid\:bg-red:where([data-rac])[data-invalid] {
202
+ .focus-within\:bg-red:where(:not([data-rac])):focus-within {
206
203
  --tw-bg-opacity: 1;
207
204
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
208
205
  }
209
- .invalid\:bg-red:where(:not([data-rac])):invalid {
206
+ .hover\:bg-red:where([data-rac])[data-hovered] {
210
207
  --tw-bg-opacity: 1;
211
208
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
212
209
  }
213
- .resizing\:bg-red[data-resizing] {
210
+ .hover\:bg-red:where(:not([data-rac])):hover {
214
211
  --tw-bg-opacity: 1;
215
212
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
216
213
  }
217
- .placement-left\:bg-red[data-placement="left"] {
214
+ .group\/custom-name:where([data-rac])[data-hovered] .group-hover\/custom-name\:bg-red {
218
215
  --tw-bg-opacity: 1;
219
216
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
220
217
  }
221
- .placement-right\:bg-red[data-placement="right"] {
218
+ .group:where([data-rac])[data-hovered] .group-hover\:bg-red {
222
219
  --tw-bg-opacity: 1;
223
220
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
224
221
  }
225
- .placement-top\:bg-red[data-placement="top"] {
222
+ .group\/custom-name:where(:not([data-rac])):hover .group-hover\/custom-name\:bg-red {
226
223
  --tw-bg-opacity: 1;
227
224
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
228
225
  }
229
- .placement-bottom\:bg-red[data-placement="bottom"] {
226
+ .group:where(:not([data-rac])):hover .group-hover\:bg-red {
230
227
  --tw-bg-opacity: 1;
231
228
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
232
229
  }
233
- .type-literal\:bg-red[data-type="literal"] {
230
+ .focus\:bg-red:where([data-rac])[data-focused] {
234
231
  --tw-bg-opacity: 1;
235
232
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
236
233
  }
237
- .type-year\:bg-red[data-type="year"] {
234
+ .focus\:bg-red:where(:not([data-rac])):focus {
238
235
  --tw-bg-opacity: 1;
239
236
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
240
237
  }
241
- .type-month\:bg-red[data-type="month"] {
238
+ .focus-visible\:bg-red:where([data-rac])[data-focus-visible] {
242
239
  --tw-bg-opacity: 1;
243
240
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
244
241
  }
245
- .type-day\:bg-red[data-type="day"] {
242
+ .focus-visible\:bg-red:where(:not([data-rac])):focus-visible {
246
243
  --tw-bg-opacity: 1;
247
244
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
248
245
  }
249
- .layout-grid\:bg-red[data-layout="grid"] {
246
+ .pressed\:bg-red[data-pressed] {
250
247
  --tw-bg-opacity: 1;
251
248
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
252
249
  }
253
- .layout-stack\:bg-red[data-layout="stack"] {
250
+ .group[data-pressed] .group-pressed\:bg-red {
254
251
  --tw-bg-opacity: 1;
255
252
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
256
253
  }
257
- .orientation-horizontal\:bg-red[data-orientation="horizontal"] {
254
+ .peer\/custom-name[data-pressed] ~ .peer-pressed\/custom-name\:bg-red {
258
255
  --tw-bg-opacity: 1;
259
256
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
260
257
  }
261
- .orientation-vertical\:bg-red[data-orientation="vertical"] {
258
+ .peer[data-pressed] ~ .peer-pressed\:bg-red {
262
259
  --tw-bg-opacity: 1;
263
260
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
264
261
  }
265
- .selection-single\:bg-red[data-selection-mode="single"] {
262
+ .selected\:bg-red[data-selected] {
266
263
  --tw-bg-opacity: 1;
267
264
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
268
265
  }
269
- .selection-multiple\:bg-red[data-selection-mode="multiple"] {
266
+ .selection-start\:bg-red[data-selection-start] {
270
267
  --tw-bg-opacity: 1;
271
268
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
272
269
  }
273
- .resizable-right\:bg-red[data-resizable-direction="right"] {
270
+ .selection-end\:bg-red[data-selection-end] {
274
271
  --tw-bg-opacity: 1;
275
272
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
276
273
  }
277
- .resizable-left\:bg-red[data-resizable-direction="left"] {
274
+ .dragging\:bg-red[data-dragging] {
278
275
  --tw-bg-opacity: 1;
279
276
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
280
277
  }
281
- .resizable-both\:bg-red[data-resizable-direction="both"] {
278
+ .drop-target\:bg-red[data-drop-target] {
282
279
  --tw-bg-opacity: 1;
283
280
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
284
281
  }
285
- .sort-ascending\:bg-red[data-sort-direction="ascending"] {
282
+ .resizing\:bg-red[data-resizing] {
286
283
  --tw-bg-opacity: 1;
287
284
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
288
285
  }
289
- .sort-descending\:bg-red[data-sort-direction="descending"] {
286
+ .disabled\:bg-red:where([data-rac])[data-disabled] {
287
+ --tw-bg-opacity: 1;
288
+ background-color: rgb(255 0 0 / var(--tw-bg-opacity))
289
+ }
290
+ .disabled\:bg-red:where(:not([data-rac])):disabled {
290
291
  --tw-bg-opacity: 1;
291
292
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
292
293
  }`
@@ -298,123 +299,123 @@ test('variants with prefix', async () => {
298
299
  let content = html`<div data-rac className="rac-hover:bg-red rac-focus:bg-red rac-focus-visible:bg-red rac-focus-within:bg-red rac-pressed:bg-red rac-disabled:bg-red rac-drop-target:bg-red rac-dragging:bg-red rac-empty:bg-red rac-allows-dragging:bg-red rac-allows-removing:bg-red rac-allows-sorting:bg-red rac-placeholder-shown:bg-red rac-selected:bg-red rac-indeterminate:bg-red rac-read-only:bg-red rac-required:bg-red rac-entering:bg-red rac-exiting:bg-red rac-open:bg-red rac-unavailable:bg-red rac-outside-month:bg-red rac-outside-visible-range:bg-red rac-selection-start:bg-red rac-selection-end:bg-red rac-current:bg-red rac-invalid:bg-red rac-resizing:bg-red rac-placement-left:bg-red rac-placement-right:bg-red rac-placement-top:bg-red rac-placement-bottom:bg-red rac-type-literal:bg-red rac-type-year:bg-red rac-type-month:bg-red rac-type-day:bg-red rac-layout-grid:bg-red rac-layout-stack:bg-red rac-orientation-horizontal:bg-red rac-orientation-vertical:bg-red rac-selection-single:bg-red rac-selection-multiple:bg-red rac-resizable-right:bg-red rac-resizable-left:bg-red rac-resizable-both:bg-red rac-sort-ascending:bg-red rac-sort-descending:bg-red group-rac-pressed:bg-red group/custom-name group-rac-hover/custom-name:bg-red peer-rac-pressed:bg-red peer-rac-pressed/custom-name:bg-red"></div>`;
299
300
  return run({content, options: {prefix: 'rac'}}).then((result) => {
300
301
  expect(result.css).toContain(css`
301
- .rac-hover\:bg-red[data-hovered] {
302
+ .rac-placement-left\:bg-red[data-placement="left"] {
302
303
  --tw-bg-opacity: 1;
303
304
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
304
305
  }
305
- .group\/custom-name[data-hovered] .group-rac-hover\/custom-name\:bg-red {
306
+ .rac-placement-right\:bg-red[data-placement="right"] {
306
307
  --tw-bg-opacity: 1;
307
308
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
308
309
  }
309
- .rac-focus\:bg-red[data-focused] {
310
+ .rac-placement-top\:bg-red[data-placement="top"] {
310
311
  --tw-bg-opacity: 1;
311
312
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
312
313
  }
313
- .rac-focus-visible\:bg-red[data-focus-visible] {
314
+ .rac-placement-bottom\:bg-red[data-placement="bottom"] {
314
315
  --tw-bg-opacity: 1;
315
316
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
316
317
  }
317
- .rac-focus-within\:bg-red[data-focus-within] {
318
+ .rac-type-literal\:bg-red[data-type="literal"] {
318
319
  --tw-bg-opacity: 1;
319
320
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
320
321
  }
321
- .rac-pressed\:bg-red[data-pressed] {
322
+ .rac-type-year\:bg-red[data-type="year"] {
322
323
  --tw-bg-opacity: 1;
323
324
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
324
325
  }
325
- .group[data-pressed] .group-rac-pressed\:bg-red {
326
+ .rac-type-month\:bg-red[data-type="month"] {
326
327
  --tw-bg-opacity: 1;
327
328
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
328
329
  }
329
- .peer\/custom-name[data-pressed] ~ .peer-rac-pressed\/custom-name\:bg-red {
330
+ .rac-type-day\:bg-red[data-type="day"] {
330
331
  --tw-bg-opacity: 1;
331
332
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
332
333
  }
333
- .peer[data-pressed] ~ .peer-rac-pressed\:bg-red {
334
+ .rac-layout-grid\:bg-red[data-layout="grid"] {
334
335
  --tw-bg-opacity: 1;
335
336
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
336
337
  }
337
- .rac-disabled\:bg-red[data-disabled] {
338
+ .rac-layout-stack\:bg-red[data-layout="stack"] {
338
339
  --tw-bg-opacity: 1;
339
340
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
340
341
  }
341
- .rac-drop-target\:bg-red[data-drop-target] {
342
+ .rac-orientation-horizontal\:bg-red[data-orientation="horizontal"] {
342
343
  --tw-bg-opacity: 1;
343
344
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
344
345
  }
345
- .rac-dragging\:bg-red[data-dragging] {
346
+ .rac-orientation-vertical\:bg-red[data-orientation="vertical"] {
346
347
  --tw-bg-opacity: 1;
347
348
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
348
349
  }
349
- .rac-empty\:bg-red[data-empty] {
350
+ .rac-selection-single\:bg-red[data-selection-mode="single"] {
350
351
  --tw-bg-opacity: 1;
351
352
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
352
353
  }
353
- .rac-allows-dragging\:bg-red[data-allows-dragging] {
354
+ .rac-selection-multiple\:bg-red[data-selection-mode="multiple"] {
354
355
  --tw-bg-opacity: 1;
355
356
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
356
357
  }
357
- .rac-allows-removing\:bg-red[data-allows-removing] {
358
+ .rac-resizable-right\:bg-red[data-resizable-direction="right"] {
358
359
  --tw-bg-opacity: 1;
359
360
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
360
361
  }
361
- .rac-allows-sorting\:bg-red[data-allows-sorting] {
362
+ .rac-resizable-left\:bg-red[data-resizable-direction="left"] {
362
363
  --tw-bg-opacity: 1;
363
364
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
364
365
  }
365
- .rac-placeholder-shown\:bg-red[data-placeholder] {
366
+ .rac-resizable-both\:bg-red[data-resizable-direction="both"] {
366
367
  --tw-bg-opacity: 1;
367
368
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
368
369
  }
369
- .rac-selected\:bg-red[data-selected] {
370
+ .rac-sort-ascending\:bg-red[data-sort-direction="ascending"] {
370
371
  --tw-bg-opacity: 1;
371
372
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
372
373
  }
373
- .rac-indeterminate\:bg-red[data-indeterminate] {
374
+ .rac-sort-descending\:bg-red[data-sort-direction="descending"] {
374
375
  --tw-bg-opacity: 1;
375
376
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
376
377
  }
377
- .rac-read-only\:bg-red[data-readonly] {
378
+ .rac-allows-removing\:bg-red[data-allows-removing] {
378
379
  --tw-bg-opacity: 1;
379
380
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
380
381
  }
381
- .rac-required\:bg-red[data-required] {
382
+ .rac-allows-sorting\:bg-red[data-allows-sorting] {
382
383
  --tw-bg-opacity: 1;
383
384
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
384
385
  }
385
- .rac-entering\:bg-red[data-entering] {
386
+ .rac-allows-dragging\:bg-red[data-allows-dragging] {
386
387
  --tw-bg-opacity: 1;
387
388
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
388
389
  }
389
- .rac-exiting\:bg-red[data-exiting] {
390
+ .rac-open\:bg-red[data-open] {
390
391
  --tw-bg-opacity: 1;
391
392
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
392
393
  }
393
- .rac-open\:bg-red[data-open] {
394
+ .rac-entering\:bg-red[data-entering] {
394
395
  --tw-bg-opacity: 1;
395
396
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
396
397
  }
397
- .rac-unavailable\:bg-red[data-unavailable] {
398
+ .rac-exiting\:bg-red[data-exiting] {
398
399
  --tw-bg-opacity: 1;
399
400
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
400
401
  }
401
- .rac-outside-month\:bg-red[data-outside-month] {
402
+ .rac-indeterminate\:bg-red[data-indeterminate] {
402
403
  --tw-bg-opacity: 1;
403
404
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
404
405
  }
405
- .rac-outside-visible-range\:bg-red[data-outside-visible-range] {
406
+ .rac-placeholder-shown\:bg-red[data-placeholder] {
406
407
  --tw-bg-opacity: 1;
407
408
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
408
409
  }
409
- .rac-selection-start\:bg-red[data-selection-start] {
410
+ .rac-current\:bg-red[data-current] {
410
411
  --tw-bg-opacity: 1;
411
412
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
412
413
  }
413
- .rac-selection-end\:bg-red[data-selection-end] {
414
+ .rac-required\:bg-red[data-required] {
414
415
  --tw-bg-opacity: 1;
415
416
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
416
417
  }
417
- .rac-current\:bg-red[data-current] {
418
+ .rac-unavailable\:bg-red[data-unavailable] {
418
419
  --tw-bg-opacity: 1;
419
420
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
420
421
  }
@@ -422,86 +423,103 @@ test('variants with prefix', async () => {
422
423
  --tw-bg-opacity: 1;
423
424
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
424
425
  }
425
- .rac-resizing\:bg-red[data-resizing] {
426
+ .rac-read-only\:bg-red[data-readonly] {
426
427
  --tw-bg-opacity: 1;
427
428
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
428
429
  }
429
- .rac-placement-left\:bg-red[data-placement="left"] {
430
+ .rac-outside-month\:bg-red[data-outside-month] {
430
431
  --tw-bg-opacity: 1;
431
432
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
432
433
  }
433
- .rac-placement-right\:bg-red[data-placement="right"] {
434
+ .rac-outside-visible-range\:bg-red[data-outside-visible-range] {
434
435
  --tw-bg-opacity: 1;
435
436
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
436
437
  }
437
- .rac-placement-top\:bg-red[data-placement="top"] {
438
+ .rac-empty\:bg-red[data-empty] {
438
439
  --tw-bg-opacity: 1;
439
440
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
440
441
  }
441
- .rac-placement-bottom\:bg-red[data-placement="bottom"] {
442
+ .rac-focus-within\:bg-red[data-focus-within] {
442
443
  --tw-bg-opacity: 1;
443
444
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
444
445
  }
445
- .rac-type-literal\:bg-red[data-type="literal"] {
446
+ .rac-hover\:bg-red[data-hovered] {
446
447
  --tw-bg-opacity: 1;
447
448
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
448
449
  }
449
- .rac-type-year\:bg-red[data-type="year"] {
450
+ .group\/custom-name[data-hovered] .group-rac-hover\/custom-name\:bg-red {
450
451
  --tw-bg-opacity: 1;
451
452
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
452
453
  }
453
- .rac-type-month\:bg-red[data-type="month"] {
454
+ .rac-focus\:bg-red[data-focused] {
454
455
  --tw-bg-opacity: 1;
455
456
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
456
457
  }
457
- .rac-type-day\:bg-red[data-type="day"] {
458
+ .rac-focus-visible\:bg-red[data-focus-visible] {
458
459
  --tw-bg-opacity: 1;
459
460
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
460
461
  }
461
- .rac-layout-grid\:bg-red[data-layout="grid"] {
462
+ .rac-pressed\:bg-red[data-pressed] {
462
463
  --tw-bg-opacity: 1;
463
464
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
464
465
  }
465
- .rac-layout-stack\:bg-red[data-layout="stack"] {
466
+ .group[data-pressed] .group-rac-pressed\:bg-red {
466
467
  --tw-bg-opacity: 1;
467
468
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
468
469
  }
469
- .rac-orientation-horizontal\:bg-red[data-orientation="horizontal"] {
470
+ .peer\/custom-name[data-pressed] ~ .peer-rac-pressed\/custom-name\:bg-red {
470
471
  --tw-bg-opacity: 1;
471
472
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
472
473
  }
473
- .rac-orientation-vertical\:bg-red[data-orientation="vertical"] {
474
+ .peer[data-pressed] ~ .peer-rac-pressed\:bg-red {
474
475
  --tw-bg-opacity: 1;
475
476
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
476
477
  }
477
- .rac-selection-single\:bg-red[data-selection-mode="single"] {
478
+ .rac-selected\:bg-red[data-selected] {
478
479
  --tw-bg-opacity: 1;
479
480
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
480
481
  }
481
- .rac-selection-multiple\:bg-red[data-selection-mode="multiple"] {
482
+ .rac-selection-start\:bg-red[data-selection-start] {
482
483
  --tw-bg-opacity: 1;
483
484
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
484
485
  }
485
- .rac-resizable-right\:bg-red[data-resizable-direction="right"] {
486
+ .rac-selection-end\:bg-red[data-selection-end] {
486
487
  --tw-bg-opacity: 1;
487
488
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
488
489
  }
489
- .rac-resizable-left\:bg-red[data-resizable-direction="left"] {
490
+ .rac-dragging\:bg-red[data-dragging] {
490
491
  --tw-bg-opacity: 1;
491
492
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
492
493
  }
493
- .rac-resizable-both\:bg-red[data-resizable-direction="both"] {
494
+ .rac-drop-target\:bg-red[data-drop-target] {
494
495
  --tw-bg-opacity: 1;
495
496
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
496
497
  }
497
- .rac-sort-ascending\:bg-red[data-sort-direction="ascending"] {
498
+ .rac-resizing\:bg-red[data-resizing] {
498
499
  --tw-bg-opacity: 1;
499
500
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
500
501
  }
501
- .rac-sort-descending\:bg-red[data-sort-direction="descending"] {
502
+ .rac-disabled\:bg-red[data-disabled] {
502
503
  --tw-bg-opacity: 1;
503
504
  background-color: rgb(255 0 0 / var(--tw-bg-opacity))
504
505
  }`
505
506
  );
506
507
  });
507
508
  });
509
+
510
+ test('hoverOnlyWhenSupported', () => {
511
+ let content = html`<div data-rac className="hover:bg-red"></div>`;
512
+ return run({content, future: {hoverOnlyWhenSupported: true}}).then((result) => {
513
+ expect(result.css).toContain(css`
514
+ .hover\:bg-red:where([data-rac])[data-hovered] {
515
+ --tw-bg-opacity: 1;
516
+ background-color: rgb(255 0 0 / var(--tw-bg-opacity))
517
+ }
518
+ @media (hover: hover) and (pointer: fine) {
519
+ .hover\:bg-red:where(:not([data-rac])):hover {
520
+ --tw-bg-opacity: 1;
521
+ background-color: rgb(255 0 0 / var(--tw-bg-opacity))
522
+ }
523
+ }`);
524
+ });
525
+ });