@onereach/styles 27.0.2-beta.6104.0 → 27.0.2-beta.6105.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": "@onereach/styles",
3
- "version": "27.0.2-beta.6104.0",
3
+ "version": "27.0.2-beta.6105.0",
4
4
  "description": "Styles for or-ui-next",
5
5
  "license": "Apache-2.0",
6
6
  "files": [
@@ -41,7 +41,7 @@
41
41
  "test:contract": "node --test tests/*.test.cjs"
42
42
  },
43
43
  "dependencies": {
44
- "@onereach/font-icons": "^27.0.2-beta.6104.0",
44
+ "@onereach/font-icons": "^27.0.2-beta.6105.0",
45
45
  "postcss-nested": "6.2.0",
46
46
  "tailwindcss": "4.3.2"
47
47
  },
@@ -1,13 +1,21 @@
1
+ const postcss = require('postcss');
2
+ const postcssNested = require('postcss-nested');
3
+
4
+ const screens = require('../screens.json');
1
5
  const {
2
6
  importantMarker,
3
7
  } = require('../tailwind/compatibility/important');
4
8
  const {
5
9
  legacySpacingAliasEntries,
6
10
  } = require('../tailwind/compatibility/legacy-spacing');
7
- const postcss = require('postcss');
8
- const postcssNested = require('postcss-nested');
11
+ const coreVariants = require('../tailwind/plugins/core').variants;
12
+ const themePresetValues = require('../tailwind/plugins/theme-preset').values;
9
13
  const spacing = require('../tailwind.config.preset.v4').theme.spacing;
10
- const screens = require('../screens.json');
14
+
15
+ const legacyStateVariantOrder = new Map(
16
+ Object.keys(coreVariants)
17
+ .map((variant, index) => [variant, index]),
18
+ );
11
19
 
12
20
  const legacySpacingAliases = legacySpacingAliasEntries(spacing)
13
21
  .sort(([, left], [, right]) => right.length - left.length);
@@ -15,6 +23,44 @@ const legacySpacingUtilityPattern = /^-?(?:p(?:[xytrblse])?|m(?:[xytrblse])?|gap
15
23
  const responsiveVariantOrder = new Map(
16
24
  ['xs', ...Object.keys(screens)].map((variant, index) => [variant, index]),
17
25
  );
26
+ const legacyTransformValue = [
27
+ 'translate(var(--tw-translate-x, 0), var(--tw-translate-y, 0))',
28
+ 'rotate(var(--tw-rotate, 0))',
29
+ 'skewX(var(--tw-skew-x, 0))',
30
+ 'skewY(var(--tw-skew-y, 0))',
31
+ 'scaleX(var(--tw-scale-x, 1))',
32
+ 'scaleY(var(--tw-scale-y, 1))',
33
+ ].join(' ');
34
+ const legacyComponentFactories = [
35
+ ['theme-outline', require('../tailwind/plugins/theme-outline').values],
36
+ ['theme-background', require('../tailwind/plugins/theme-background').values],
37
+ ['theme-foreground', require('../tailwind/plugins/theme-foreground').values],
38
+ ['theme-preset-1', themePresetValues],
39
+ ['theme-preset-2', themePresetValues],
40
+ ['theme-preset-3', themePresetValues],
41
+ ['theme-preset-4', themePresetValues],
42
+ ['theme-divider', require('../tailwind/plugins/theme-divider').values],
43
+ ['theme-border', require('../tailwind/plugins/theme-border').values],
44
+ ]
45
+ .map(([factory, values]) => [
46
+ factory,
47
+ new Map(Object.keys(values).map((value, index) => [value, index])),
48
+ ])
49
+ .sort(([left], [right]) => right.length - left.length);
50
+ const legacyComponentFactoryNames = [
51
+ 'theme-background',
52
+ 'theme-foreground',
53
+ 'theme-preset-1',
54
+ 'theme-preset-2',
55
+ 'theme-preset-3',
56
+ 'theme-preset-4',
57
+ 'theme-divider',
58
+ 'theme-outline',
59
+ 'theme-border',
60
+ 'iconography',
61
+ 'typography',
62
+ 'layout',
63
+ ].sort((left, right) => right.length - left.length);
18
64
  const legacyCoreUtilities = new Map([
19
65
  ['leading-none', [
20
66
  ['line-height', '1'],
@@ -24,6 +70,9 @@ const legacyCoreUtilities = new Map([
24
70
  ['line-height', 'inherit'],
25
71
  ['color', 'inherit'],
26
72
  ]],
73
+ ['outline', [
74
+ ['outline-style', 'solid'],
75
+ ]],
27
76
  ['outline-none', [
28
77
  ['outline', '2px solid transparent'],
29
78
  ['outline-offset', '2px'],
@@ -41,6 +90,12 @@ const legacyCoreUtilities = new Map([
41
90
  const legacyCoreReplacementProps = new Map([
42
91
  ['leading-none', new Set(['--tw-leading', 'line-height'])],
43
92
  ['text-inherit', new Set(['font-size', 'line-height', 'color'])],
93
+ ['outline', new Set([
94
+ '--tw-outline-style',
95
+ 'outline',
96
+ 'outline-style',
97
+ 'outline-width',
98
+ ])],
44
99
  ['outline-none', new Set([
45
100
  '--tw-outline-style',
46
101
  'outline',
@@ -60,29 +115,40 @@ function tailwindV4Compat() {
60
115
  return {
61
116
  postcssPlugin: 'onereach-tailwind-v4-compat',
62
117
  async OnceExit(root) {
63
- utilityLayers(root).forEach(restoreNestedChildrenVariantOrder);
118
+ utilityLayers(root).forEach(restoreNestedVariantOrder);
64
119
  await flattenUtilityLayers(root);
65
120
 
66
121
  utilityLayers(root).forEach((layer) => {
122
+ restoreLegacyGroupHover(layer);
67
123
  restoreStackedVariantOrder(layer);
68
124
  restoreLegacySpacingClassNames(layer);
69
125
  restoreImportantDeclarations(layer);
70
126
  restoreLegacyCoreUtilities(layer);
127
+ restoreLegacyTransformUtilities(layer);
71
128
  restoreArbitraryValueOrder(layer);
129
+ reorderLegacyComponentValueSiblings(layer);
130
+ reorderLegacyStateVariantSiblings(layer);
72
131
  reorderResponsiveVariantSiblings(layer);
73
132
  });
133
+ restoreLegacyComponentLayers(root);
74
134
  },
75
135
  };
76
136
  }
77
137
 
78
- function restoreNestedChildrenVariantOrder(root) {
138
+ function restoreNestedVariantOrder(root) {
79
139
  root.walkRules((candidateRule) => {
80
140
  const candidate = classNames(candidateRule.selector)
81
- .find((className) => className.split(':').includes('children'));
141
+ .find((className) => {
142
+ const variants = classSegments(className).slice(0, -1);
143
+ const arbitraryIndex = variants.findIndex((variant) => variant.startsWith('[&'));
144
+
145
+ return variants.includes('children')
146
+ || arbitraryIndex > 0;
147
+ });
82
148
 
83
149
  if (!candidate) return;
84
150
 
85
- const segments = candidate.split(':');
151
+ const segments = classSegments(candidate);
86
152
  const variantDepth = segments.length - 1;
87
153
 
88
154
  const paths = nestedContainerPaths(candidateRule, variantDepth);
@@ -106,6 +172,29 @@ function restoreNestedChildrenVariantOrder(root) {
106
172
  });
107
173
  }
108
174
 
175
+ function classSegments(className) {
176
+ const segments = [];
177
+ let bracketDepth = 0;
178
+ let segment = '';
179
+
180
+ for (const character of className) {
181
+ if (character === '[') bracketDepth += 1;
182
+ if (character === ']') bracketDepth -= 1;
183
+
184
+ if (character === ':' && bracketDepth === 0) {
185
+ segments.push(segment);
186
+ segment = '';
187
+ continue;
188
+ }
189
+
190
+ segment += character;
191
+ }
192
+
193
+ segments.push(segment);
194
+
195
+ return segments;
196
+ }
197
+
109
198
  function nestedContainerPaths(container, depth, containers = []) {
110
199
  if (depth === 0) {
111
200
  return [{
@@ -144,6 +233,113 @@ function utilityLayers(root) {
144
233
  return layers;
145
234
  }
146
235
 
236
+ function restoreLegacyComponentLayers(root) {
237
+ utilityLayers(root).forEach((utilityLayer) => {
238
+ const componentNodes = extractLegacyComponentNodes(utilityLayer);
239
+
240
+ if (componentNodes.length === 0) return;
241
+
242
+ const componentLayer = postcss.atRule({
243
+ name: 'layer',
244
+ params: 'components',
245
+ });
246
+
247
+ componentLayer.append(componentNodes);
248
+ utilityLayer.before(componentLayer);
249
+ });
250
+ }
251
+
252
+ function extractLegacyComponentNodes(container) {
253
+ return [...(container.nodes ?? [])].flatMap((node) => {
254
+ if (node.type === 'rule') {
255
+ const isLegacyComponent = classNames(node.selector)
256
+ .map(baseUtility)
257
+ .some((utility) => legacyComponentFactoryNames
258
+ .some((factory) => utility.startsWith(`${factory}-`)));
259
+
260
+ if (!isLegacyComponent) return [];
261
+
262
+ node.remove();
263
+ return [node];
264
+ }
265
+
266
+ if (!node.nodes) return [];
267
+
268
+ const childNodes = extractLegacyComponentNodes(node);
269
+
270
+ if (childNodes.length === 0) return [];
271
+ if (node.type === 'atrule' && node.name === 'layer' && node.params === 'utilities') {
272
+ if (node.nodes.length === 0) node.remove();
273
+
274
+ return childNodes;
275
+ }
276
+
277
+ const wrapper = node.clone();
278
+
279
+ wrapper.removeAll();
280
+ wrapper.append(childNodes);
281
+ if (node.nodes.length === 0) node.remove();
282
+
283
+ return [wrapper];
284
+ });
285
+ }
286
+
287
+ function reorderLegacyComponentValueSiblings(container) {
288
+ const groups = new Map();
289
+
290
+ container.nodes?.forEach((node, index) => {
291
+ if (node.type !== 'rule') return;
292
+
293
+ const candidate = classNames(node.selector)
294
+ .map((className) => ({
295
+ className,
296
+ utility: baseUtility(className),
297
+ }))
298
+ .map((entry) => ({
299
+ ...entry,
300
+ factory: legacyComponentFactories
301
+ .find(([factory]) => entry.utility.startsWith(`${factory}-`)),
302
+ }))
303
+ .find(({ factory }) => factory);
304
+
305
+ if (!candidate) return;
306
+
307
+ const [factory, valueOrder] = candidate.factory;
308
+ const value = candidate.utility.slice(factory.length + 1);
309
+ const order = valueOrder.get(value);
310
+
311
+ if (order === undefined) return;
312
+
313
+ const variants = classSegments(candidate.className).slice(0, -1).join(':');
314
+ const key = `${factory}\0${variants}`;
315
+ const group = groups.get(key) ?? [];
316
+
317
+ group.push({
318
+ index,
319
+ node,
320
+ order,
321
+ });
322
+ groups.set(key, group);
323
+ });
324
+
325
+ groups.forEach((group) => {
326
+ const sorted = [...group].sort((left, right) => (
327
+ left.order - right.order || left.index - right.index
328
+ ));
329
+
330
+ group.forEach(({ index }, sortedIndex) => {
331
+ const node = sorted[sortedIndex].node;
332
+
333
+ container.nodes[index] = node;
334
+ node.parent = container;
335
+ });
336
+ });
337
+
338
+ container.nodes?.forEach((node) => {
339
+ if (node.nodes) reorderLegacyComponentValueSiblings(node);
340
+ });
341
+ }
342
+
147
343
  function restoreStackedVariantOrder(root) {
148
344
  root.walkRules((rule) => {
149
345
  const candidate = classNames(rule.selector)
@@ -255,6 +451,9 @@ function restoreLegacyCoreUtilities(root) {
255
451
  .find((className) => legacyCoreUtilities.has(className));
256
452
 
257
453
  if (!utility) return;
454
+ if (!candidateRule.selectors.every((selector) => classNames(selector)
455
+ .map(baseUtility)
456
+ .includes(utility))) return;
258
457
 
259
458
  const declarations = legacyCoreUtilities.get(utility);
260
459
  const replacedProps = legacyCoreReplacementProps.get(utility);
@@ -271,18 +470,156 @@ function restoreLegacyCoreUtilities(root) {
271
470
  .filter((declaration) => replacedProps.has(declaration.prop))
272
471
  .forEach((declaration) => declaration.remove());
273
472
  declarations.slice().reverse().forEach(([prop, value]) => {
274
- container.prepend({ prop, value, important });
473
+ container.prepend({
474
+ prop,
475
+ value,
476
+ important,
477
+ });
275
478
  });
276
479
  restoredContainers.add(container);
277
480
  });
278
481
  });
279
482
  }
280
483
 
484
+ function restoreLegacyTransformUtilities(root) {
485
+ root.walkRules((rule) => {
486
+ const utility = classNames(rule.selector)
487
+ .map(baseUtility)
488
+ .find((className) => (
489
+ /^-?rotate-(?![xy]-)/.test(className)
490
+ || /^-?translate-[xy]-/.test(className)
491
+ || /^-?skew-[xy]-/.test(className)
492
+ || /^scale(?:-[xy])?-/.test(className)
493
+ ));
494
+
495
+ if (!utility) return;
496
+ if (!rule.selectors.every((selector) => classNames(selector)
497
+ .map(baseUtility)
498
+ .includes(utility))) return;
499
+
500
+ const declarations = directDeclarations(rule);
501
+ const important = declarations.some((declaration) => declaration.important);
502
+ const rotate = declarations.find((declaration) => declaration.prop === 'rotate');
503
+ const translate = declarations.find((declaration) => declaration.prop === 'translate');
504
+ const scale = declarations.find((declaration) => declaration.prop === 'scale');
505
+ const transform = declarations.find((declaration) => declaration.prop === 'transform');
506
+
507
+ if (rotate) {
508
+ rotate.cloneBefore({
509
+ prop: '--tw-rotate',
510
+ value: rotate.value,
511
+ important,
512
+ });
513
+ rotate.remove();
514
+ }
515
+ translate?.remove();
516
+ scale?.remove();
517
+ transform?.remove();
518
+ declarations
519
+ .filter(({ prop }) => prop === '--tw-scale-z')
520
+ .forEach((declaration) => declaration.remove());
521
+ declarations
522
+ .filter(({ prop }) => prop === '--tw-skew-x' || prop === '--tw-skew-y')
523
+ .forEach((declaration) => {
524
+ declaration.value = declaration.value.replace(/^skew[XY]\((.*)\)$/, '$1');
525
+ });
526
+ rule.append({
527
+ prop: 'transform',
528
+ value: legacyTransformValue,
529
+ important,
530
+ });
531
+ });
532
+ }
533
+
534
+ function restoreLegacyGroupHover(root) {
535
+ const restoredByParent = new WeakMap();
536
+
537
+ root.walkRules((rule) => {
538
+ const selectors = rule.selectors.map(restoreLegacyGroupHoverSelector);
539
+
540
+ if (selectors.every((selector, index) => selector === rule.selectors[index])) return;
541
+
542
+ rule.selectors = [...new Set(selectors)];
543
+
544
+ const signature = [
545
+ rule.selector,
546
+ ...directDeclarations(rule)
547
+ .map(({ prop, value, important }) => `${prop}:${value}:${important}`),
548
+ ].join('\0');
549
+ const restored = restoredByParent.get(rule.parent) ?? new Set();
550
+
551
+ if (restored.has(signature)) {
552
+ rule.remove();
553
+ return;
554
+ }
555
+
556
+ restored.add(signature);
557
+ restoredByParent.set(rule.parent, restored);
558
+ });
559
+ }
560
+
561
+ function restoreLegacyGroupHoverSelector(selector) {
562
+ const candidate = classNames(selector)
563
+ .map((className) => ({
564
+ className,
565
+ variant: classSegments(className)
566
+ .find((segment) => segment === 'group-hover' || segment.startsWith('group-hover/')),
567
+ }))
568
+ .find(({ variant }) => variant);
569
+
570
+ if (!candidate) return selector;
571
+
572
+ const groupName = `group${candidate.variant.slice('group-hover'.length)}`;
573
+ const groupSelector = `.${escapeClassName(groupName)}`;
574
+ const compoundStart = selector.indexOf(`:is(:where(${groupSelector})`);
575
+
576
+ if (compoundStart < 0) return selector;
577
+
578
+ const compoundEnd = closingParenthesis(selector, compoundStart + 3);
579
+
580
+ if (compoundEnd < 0) return selector;
581
+
582
+ return [
583
+ `${groupSelector}:hover `,
584
+ selector.slice(0, compoundStart),
585
+ selector.slice(compoundEnd + 1),
586
+ ].join('');
587
+ }
588
+
589
+ function closingParenthesis(value, openingIndex) {
590
+ let depth = 0;
591
+
592
+ for (let index = openingIndex;index < value.length;index += 1) {
593
+ if (value[index] === '(') depth += 1;
594
+ if (value[index] === ')') depth -= 1;
595
+ if (depth === 0) return index;
596
+ }
597
+
598
+ return -1;
599
+ }
600
+
281
601
  function classNames(selector) {
282
602
  const names = [];
603
+ let attributeDepth = 0;
283
604
 
284
- for (let index = 0; index < selector.length; index += 1) {
285
- if (selector[index] !== '.' || selector[index - 1] === '\\') continue;
605
+ for (let index = 0;index < selector.length;index += 1) {
606
+ if (selector[index] === '\\') {
607
+ index += 1;
608
+ continue;
609
+ }
610
+ if (selector[index] === '[') {
611
+ attributeDepth += 1;
612
+ continue;
613
+ }
614
+ if (selector[index] === ']') {
615
+ attributeDepth -= 1;
616
+ continue;
617
+ }
618
+ if (
619
+ attributeDepth > 0
620
+ || selector[index] !== '.'
621
+ || selector[index - 1] === '\\'
622
+ ) continue;
286
623
 
287
624
  let name = '';
288
625
  index += 1;
@@ -335,6 +672,61 @@ function restoreArbitraryValueOrder(root) {
335
672
  });
336
673
  }
337
674
 
675
+ function reorderLegacyStateVariantSiblings(container) {
676
+ const nodes = container.nodes ?? [];
677
+ const stateNodes = nodes.flatMap((node, index) => {
678
+ if (node.type !== 'rule') return [];
679
+
680
+ const variants = classNames(node.selector)
681
+ .map((className) => classSegments(className)
682
+ .slice(0, -1)
683
+ .filter((segment) => legacyStateVariantOrder.has(segment))
684
+ .map((segment) => legacyStateVariantOrder.get(segment))
685
+ .reverse())
686
+ .find((order) => order.length > 0);
687
+
688
+ if (!variants) return [];
689
+
690
+ return [{
691
+ index,
692
+ node,
693
+ order: variants,
694
+ }];
695
+ });
696
+ const stateSet = new Set(stateNodes.map(({ node }) => node));
697
+ const sorted = [...stateNodes].sort((left, right) => (
698
+ Math.min(...left.order) - Math.min(...right.order)
699
+ || compareVariantOrders(left.order, right.order)
700
+ || left.index - right.index
701
+ ));
702
+
703
+ if (stateNodes.length > 0) {
704
+ container.nodes = [
705
+ ...nodes.filter((node) => !stateSet.has(node)),
706
+ ...sorted.map(({ node }) => node),
707
+ ];
708
+ container.nodes.forEach((node) => {
709
+ node.parent = container;
710
+ });
711
+ }
712
+
713
+ container.nodes?.forEach((node) => {
714
+ if (node.nodes) reorderLegacyStateVariantSiblings(node);
715
+ });
716
+ }
717
+
718
+ function compareVariantOrders(left, right) {
719
+ const length = Math.max(left.length, right.length);
720
+
721
+ for (let index = 0;index < length;index += 1) {
722
+ const difference = (left[index] ?? -1) - (right[index] ?? -1);
723
+
724
+ if (difference !== 0) return difference;
725
+ }
726
+
727
+ return 0;
728
+ }
729
+
338
730
  function reorderArbitraryValueSiblings(container) {
339
731
  const groups = new Map();
340
732
 
@@ -357,7 +749,11 @@ function reorderArbitraryValueSiblings(container) {
357
749
  const key = `${normalizedCandidate}\0${declarationSignature.join('\0')}`;
358
750
  const group = groups.get(key) ?? [];
359
751
 
360
- group.push({ candidate, index, node });
752
+ group.push({
753
+ candidate,
754
+ index,
755
+ node,
756
+ });
361
757
  groups.set(key, group);
362
758
  });
363
759