@onereach/styles 27.0.2-beta.6105.0 → 27.0.2-beta.6107.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.6105.0",
3
+ "version": "27.0.2-beta.6107.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.6105.0",
44
+ "@onereach/font-icons": "^27.0.2-beta.6107.0",
45
45
  "postcss-nested": "6.2.0",
46
46
  "tailwindcss": "4.3.2"
47
47
  },
@@ -4,6 +4,8 @@ const postcssNested = require('postcss-nested');
4
4
  const screens = require('../screens.json');
5
5
  const {
6
6
  importantMarker,
7
+ legacyImportantClasses,
8
+ toTailwind4ImportantClass,
7
9
  } = require('../tailwind/compatibility/important');
8
10
  const {
9
11
  legacySpacingAliasEntries,
@@ -16,6 +18,9 @@ const legacyStateVariantOrder = new Map(
16
18
  Object.keys(coreVariants)
17
19
  .map((variant, index) => [variant, index]),
18
20
  );
21
+ const legacyImportantSuffixClasses = new Set(
22
+ legacyImportantClasses.map(toTailwind4ImportantClass),
23
+ );
19
24
 
20
25
  const legacySpacingAliases = legacySpacingAliasEntries(spacing)
21
26
  .sort(([, left], [, right]) => right.length - left.length);
@@ -23,6 +28,17 @@ const legacySpacingUtilityPattern = /^-?(?:p(?:[xytrblse])?|m(?:[xytrblse])?|gap
23
28
  const responsiveVariantOrder = new Map(
24
29
  ['xs', ...Object.keys(screens)].map((variant, index) => [variant, index]),
25
30
  );
31
+ const legacyPseudoElementVariants = new Map([
32
+ ['after', '::after'],
33
+ ['backdrop', '::backdrop'],
34
+ ['before', '::before'],
35
+ ['file', '::file-selector-button'],
36
+ ['first-letter', '::first-letter'],
37
+ ['first-line', '::first-line'],
38
+ ['marker', '::marker'],
39
+ ['placeholder', '::placeholder'],
40
+ ['selection', '::selection'],
41
+ ]);
26
42
  const legacyTransformValue = [
27
43
  'translate(var(--tw-translate-x, 0), var(--tw-translate-y, 0))',
28
44
  'rotate(var(--tw-rotate, 0))',
@@ -61,6 +77,20 @@ const legacyComponentFactoryNames = [
61
77
  'typography',
62
78
  'layout',
63
79
  ].sort((left, right) => right.length - left.length);
80
+ const legacyComponentFactoryOrder = new Map([
81
+ 'layout',
82
+ 'typography',
83
+ 'iconography',
84
+ 'theme-preset-1',
85
+ 'theme-preset-2',
86
+ 'theme-preset-3',
87
+ 'theme-preset-4',
88
+ 'theme-foreground',
89
+ 'theme-background',
90
+ 'theme-border',
91
+ 'theme-divider',
92
+ 'theme-outline',
93
+ ].map((factory, index) => [factory, index]));
64
94
  const legacyCoreUtilities = new Map([
65
95
  ['leading-none', [
66
96
  ['line-height', '1'],
@@ -119,18 +149,27 @@ function tailwindV4Compat() {
119
149
  await flattenUtilityLayers(root);
120
150
 
121
151
  utilityLayers(root).forEach((layer) => {
152
+ restoreLegacyImportantClassNames(layer);
122
153
  restoreLegacyGroupHover(layer);
154
+ restoreLegacyPseudoElementStateOrder(layer);
123
155
  restoreStackedVariantOrder(layer);
124
156
  restoreLegacySpacingClassNames(layer);
125
157
  restoreImportantDeclarations(layer);
126
158
  restoreLegacyCoreUtilities(layer);
159
+ restoreLegacyBorderWidthUtilities(layer);
127
160
  restoreLegacyTransformUtilities(layer);
128
161
  restoreArbitraryValueOrder(layer);
129
162
  reorderLegacyComponentValueSiblings(layer);
130
163
  reorderLegacyStateVariantSiblings(layer);
164
+ reorderLegacyOutlineSiblings(layer);
131
165
  reorderResponsiveVariantSiblings(layer);
132
166
  });
133
167
  restoreLegacyComponentLayers(root);
168
+ componentLayers(root).forEach((layer) => {
169
+ reorderLegacyComponentFactorySiblings(layer);
170
+ reorderResponsiveVariantSiblings(layer);
171
+ });
172
+ restoreLegacyImportantLayers(root);
134
173
  },
135
174
  };
136
175
  }
@@ -142,8 +181,7 @@ function restoreNestedVariantOrder(root) {
142
181
  const variants = classSegments(className).slice(0, -1);
143
182
  const arbitraryIndex = variants.findIndex((variant) => variant.startsWith('[&'));
144
183
 
145
- return variants.includes('children')
146
- || arbitraryIndex > 0;
184
+ return variants.includes('children') || arbitraryIndex >= 0;
147
185
  });
148
186
 
149
187
  if (!candidate) return;
@@ -233,6 +271,16 @@ function utilityLayers(root) {
233
271
  return layers;
234
272
  }
235
273
 
274
+ function componentLayers(root) {
275
+ const layers = [];
276
+
277
+ root.walkAtRules('layer', (layer) => {
278
+ if (layer.params.trim() === 'components') layers.push(layer);
279
+ });
280
+
281
+ return layers;
282
+ }
283
+
236
284
  function restoreLegacyComponentLayers(root) {
237
285
  utilityLayers(root).forEach((utilityLayer) => {
238
286
  const componentNodes = extractLegacyComponentNodes(utilityLayer);
@@ -340,6 +388,56 @@ function reorderLegacyComponentValueSiblings(container) {
340
388
  });
341
389
  }
342
390
 
391
+ function reorderLegacyComponentFactorySiblings(container) {
392
+ const nodes = container.nodes ?? [];
393
+ const componentNodes = nodes.flatMap((node, index) => {
394
+ const selectors = [];
395
+
396
+ if (node.type === 'rule') selectors.push(node.selector);
397
+ node.walkRules?.((rule) => selectors.push(rule.selector));
398
+
399
+ const selectorClassNames = selectors.flatMap(classNames);
400
+ const factory = selectorClassNames
401
+ .map(baseUtility)
402
+ .flatMap((utility) => [...legacyComponentFactoryOrder.keys()]
403
+ .filter((candidate) => utility.startsWith(`${candidate}-`)))
404
+ .at(0);
405
+
406
+ if (!factory) return [];
407
+
408
+ return [{
409
+ index,
410
+ node,
411
+ order: legacyComponentFactoryOrder.get(factory),
412
+ state: selectorClassNames.some((className) => (
413
+ classSegments(className)
414
+ .slice(0, -1)
415
+ .some((segment) => legacyStateVariantOrder.has(segment))
416
+ )),
417
+ }];
418
+ });
419
+ const componentSet = new Set(componentNodes.map(({ node }) => node));
420
+ const sorted = [...componentNodes].sort((left, right) => (
421
+ Number(left.state) - Number(right.state)
422
+ || left.order - right.order
423
+ || left.index - right.index
424
+ ));
425
+
426
+ if (componentNodes.length > 0) {
427
+ container.nodes = [
428
+ ...nodes.filter((node) => !componentSet.has(node)),
429
+ ...sorted.map(({ node }) => node),
430
+ ];
431
+ container.nodes.forEach((node) => {
432
+ node.parent = container;
433
+ });
434
+ }
435
+
436
+ container.nodes?.forEach((node) => {
437
+ if (node.nodes) reorderLegacyComponentFactorySiblings(node);
438
+ });
439
+ }
440
+
343
441
  function restoreStackedVariantOrder(root) {
344
442
  root.walkRules((rule) => {
345
443
  const candidate = classNames(rule.selector)
@@ -442,6 +540,89 @@ function restoreImportantDeclarations(root) {
442
540
  });
443
541
  }
444
542
 
543
+ function restoreLegacyImportantClassNames(root) {
544
+ root.walkRules((rule) => {
545
+ const aliases = rule.selectors.flatMap((selector) => (
546
+ classNames(selector)
547
+ .filter((className) => legacyImportantSuffixClasses.has(className))
548
+ .map((className) => {
549
+ const segments = classSegments(className);
550
+ const utility = segments.pop().slice(0, -1);
551
+ const legacyClassName = [...segments, `!${utility}`].join(':');
552
+
553
+ return selector.replace(
554
+ `.${escapeClassName(className)}`,
555
+ `.${escapeClassName(legacyClassName)}`,
556
+ );
557
+ })
558
+ ));
559
+
560
+ const uniqueAliases = [...new Set(aliases)];
561
+
562
+ if (uniqueAliases.length === 0) return;
563
+
564
+ const aliasRule = rule.clone({ selectors: uniqueAliases });
565
+
566
+ aliasRule.raws.onereachLegacyImportant = true;
567
+ rule.after(aliasRule);
568
+ });
569
+ }
570
+
571
+ function restoreLegacyImportantLayers(root) {
572
+ utilityLayers(root).forEach((utilityLayer) => {
573
+ const legacyImportantNodes = extractMarkedLegacyImportantNodes(utilityLayer);
574
+
575
+ if (legacyImportantNodes.length === 0) return;
576
+
577
+ let componentLayer = utilityLayer.prev();
578
+
579
+ if (
580
+ componentLayer?.type !== 'atrule'
581
+ || componentLayer.name !== 'layer'
582
+ || componentLayer.params.trim() !== 'components'
583
+ ) {
584
+ componentLayer = postcss.atRule({
585
+ name: 'layer',
586
+ params: 'components',
587
+ });
588
+ utilityLayer.before(componentLayer);
589
+ }
590
+
591
+ componentLayer.append(legacyImportantNodes);
592
+ });
593
+ }
594
+
595
+ function extractMarkedLegacyImportantNodes(container) {
596
+ return [...(container.nodes ?? [])].flatMap((node) => {
597
+ if (node.type === 'rule') {
598
+ if (!node.raws.onereachLegacyImportant) return [];
599
+
600
+ delete node.raws.onereachLegacyImportant;
601
+ node.remove();
602
+ return [node];
603
+ }
604
+
605
+ if (!node.nodes) return [];
606
+
607
+ const childNodes = extractMarkedLegacyImportantNodes(node);
608
+
609
+ if (childNodes.length === 0) return [];
610
+ if (node.type === 'atrule' && node.name === 'layer' && node.params === 'utilities') {
611
+ if (node.nodes.length === 0) node.remove();
612
+
613
+ return childNodes;
614
+ }
615
+
616
+ const wrapper = node.clone();
617
+
618
+ wrapper.removeAll();
619
+ wrapper.append(childNodes);
620
+ if (node.nodes.length === 0) node.remove();
621
+
622
+ return [wrapper];
623
+ });
624
+ }
625
+
445
626
  function restoreLegacyCoreUtilities(root) {
446
627
  const restoredContainers = new WeakSet();
447
628
 
@@ -481,6 +662,25 @@ function restoreLegacyCoreUtilities(root) {
481
662
  });
482
663
  }
483
664
 
665
+ function restoreLegacyBorderWidthUtilities(root) {
666
+ root.walkRules((rule) => {
667
+ const isBorderWidthUtility = classNames(rule.selector)
668
+ .map(baseUtility)
669
+ .some((utility) => (
670
+ /^border(?:-[xytrblse])?(?:-(?:0|1|2|4|8|\[[^\]]+]))?$/.test(utility)
671
+ ));
672
+
673
+ if (!isBorderWidthUtility) return;
674
+
675
+ rule.walkDecls((declaration) => {
676
+ if (
677
+ declaration.prop === 'border-style'
678
+ || declaration.prop === '--tw-border-style'
679
+ ) declaration.remove();
680
+ });
681
+ });
682
+ }
683
+
484
684
  function restoreLegacyTransformUtilities(root) {
485
685
  root.walkRules((rule) => {
486
686
  const utility = classNames(rule.selector)
@@ -558,6 +758,30 @@ function restoreLegacyGroupHover(root) {
558
758
  });
559
759
  }
560
760
 
761
+ function restoreLegacyPseudoElementStateOrder(root) {
762
+ root.walkRules((rule) => {
763
+ rule.selectors = rule.selectors.map((selector) => {
764
+ const pseudoElement = classNames(selector)
765
+ .flatMap((className) => classSegments(className).slice(0, -1))
766
+ .map((variant) => legacyPseudoElementVariants.get(variant))
767
+ .find((pseudo) => pseudo && selector.includes(pseudo));
768
+
769
+ if (!pseudoElement) return selector;
770
+
771
+ const pseudoIndex = selector.indexOf(pseudoElement);
772
+ const suffix = selector.slice(pseudoIndex + pseudoElement.length);
773
+
774
+ if (!suffix || !/^[:[]/.test(suffix)) return selector;
775
+
776
+ return [
777
+ selector.slice(0, pseudoIndex),
778
+ suffix,
779
+ pseudoElement,
780
+ ].join('');
781
+ });
782
+ });
783
+ }
784
+
561
785
  function restoreLegacyGroupHoverSelector(selector) {
562
786
  const candidate = classNames(selector)
563
787
  .map((className) => ({
@@ -727,6 +951,56 @@ function compareVariantOrders(left, right) {
727
951
  return 0;
728
952
  }
729
953
 
954
+ function reorderLegacyOutlineSiblings(container) {
955
+ const groups = new Map();
956
+
957
+ container.nodes?.forEach((node, index) => {
958
+ if (node.type !== 'rule') return;
959
+
960
+ const candidate = classNames(node.selector)
961
+ .map((className) => ({
962
+ className,
963
+ utility: baseUtility(className),
964
+ }))
965
+ .find(({ utility }) => (
966
+ utility === 'outline-none'
967
+ || utility.startsWith('outline-offset-')
968
+ ));
969
+
970
+ if (!candidate) return;
971
+
972
+ const variants = classSegments(candidate.className).slice(0, -1).join(':');
973
+ const important = candidate.className.startsWith('!')
974
+ || candidate.className.endsWith('!');
975
+ const key = `${variants}\0${important}`;
976
+ const group = groups.get(key) ?? [];
977
+
978
+ group.push({
979
+ index,
980
+ node,
981
+ order: candidate.utility === 'outline-none' ? 0 : 1,
982
+ });
983
+ groups.set(key, group);
984
+ });
985
+
986
+ groups.forEach((group) => {
987
+ const sorted = [...group].sort((left, right) => (
988
+ left.order - right.order || left.index - right.index
989
+ ));
990
+
991
+ group.forEach(({ index }, sortedIndex) => {
992
+ const node = sorted[sortedIndex].node;
993
+
994
+ container.nodes[index] = node;
995
+ node.parent = container;
996
+ });
997
+ });
998
+
999
+ container.nodes?.forEach((node) => {
1000
+ if (node.nodes) reorderLegacyOutlineSiblings(node);
1001
+ });
1002
+ }
1003
+
730
1004
  function reorderArbitraryValueSiblings(container) {
731
1005
  const groups = new Map();
732
1006
 
@@ -800,6 +1074,13 @@ function reorderResponsiveVariantSiblings(container) {
800
1074
  }
801
1075
 
802
1076
  function responsiveVariantForNode(node) {
1077
+ if (node.type === 'atrule' && node.name === 'media') {
1078
+ const screen = Object.entries(screens)
1079
+ .find(([, minWidth]) => node.params.includes(`min-width: ${minWidth}`));
1080
+
1081
+ if (screen) return screen[0];
1082
+ }
1083
+
803
1084
  const selectors = [];
804
1085
 
805
1086
  if (node.type === 'rule') selectors.push(node.selector);
@@ -1,4 +1,18 @@
1
1
  const importantMarker = '--or-tailwind-v3-important';
2
+ const legacyImportantClasses = [
3
+ 'dark:disabled:!bg-on-disabled-dark',
4
+ 'dark:invalid:read-only:!border-transparent',
5
+ 'dark:read-only:!border-transparent',
6
+ 'disabled:!bg-on-disabled',
7
+ 'first:children:!ms-0',
8
+ 'invalid:!border-dashed',
9
+ 'invalid:read-only:!border-transparent',
10
+ 'last:children:!me-0',
11
+ 'md:!my-0',
12
+ 'md:!pb-[7px]',
13
+ 'md:!pt-[6px]',
14
+ 'read-only:!border-transparent',
15
+ ];
2
16
 
3
17
  function markImportant(declarations) {
4
18
  return {
@@ -7,7 +21,16 @@ function markImportant(declarations) {
7
21
  };
8
22
  }
9
23
 
24
+ function toTailwind4ImportantClass(className) {
25
+ const segments = className.split(':');
26
+ const utility = segments.pop();
27
+
28
+ return [...segments, `${utility.replace(/^!/, '')}!`].join(':');
29
+ }
30
+
10
31
  module.exports = {
11
32
  importantMarker,
33
+ legacyImportantClasses,
12
34
  markImportant,
35
+ toTailwind4ImportantClass,
13
36
  };
@@ -27,6 +27,10 @@ const spacingUtilities = [
27
27
  'max-w',
28
28
  'max-h',
29
29
  ];
30
+ const {
31
+ legacyImportantClasses,
32
+ toTailwind4ImportantClass,
33
+ } = require('./important');
30
34
 
31
35
  const childrenUtilities = spacingUtilities.filter((utility) => (
32
36
  /^(?:p[trblxyse]?|m[trblxyse]?)$/.test(utility)
@@ -38,6 +42,10 @@ const stateVariants = ['dark', 'hover', 'mobile', 'desktop'];
38
42
  function generateLegacyCompatibilityCss({ spacing, screens }) {
39
43
  const candidates = new Set();
40
44
 
45
+ legacyImportantClasses.forEach((className) => {
46
+ candidates.add(toTailwind4ImportantClass(className));
47
+ });
48
+
41
49
  legacySpacingAliasEntries(spacing).forEach(([, alias]) => {
42
50
  spacingUtilities.forEach((utility) => {
43
51
  addCandidateVariants(candidates, `${utility}-${alias}`, screens);
@@ -37,6 +37,7 @@ module.exports = {
37
37
  color: resolveThemeValue(theme, `textColor.on-${token}` + suffix),
38
38
  backgroundColor: resolveThemeValue(theme, `backgroundColor.${token}` + suffix),
39
39
 
40
+ borderStyle: 'none',
40
41
  outlineStyle: 'none',
41
42
 
42
43
  [variants['mobile']]: {
@@ -77,6 +78,7 @@ module.exports = {
77
78
  color: resolveThemeValue(theme, `textColor.${token}` + suffix),
78
79
  backgroundColor: resolveThemeValue(theme, `backgroundColor.${token}-opacity-0-08` + suffix),
79
80
 
81
+ borderStyle: 'none',
80
82
  outlineStyle: 'none',
81
83
 
82
84
  [variants['mobile']]: {
@@ -117,6 +119,7 @@ module.exports = {
117
119
  color: resolveThemeValue(theme, `textColor.${token}` + suffix),
118
120
  backgroundColor: 'transparent',
119
121
 
122
+ borderStyle: 'none',
120
123
  outlineStyle: 'none',
121
124
 
122
125
  [variants['mobile']]: {
@@ -157,6 +160,7 @@ module.exports = {
157
160
  color: resolveThemeValue(theme, `textColor.${token}` + suffix),
158
161
  backgroundColor: 'transparent',
159
162
 
163
+ borderStyle: 'none',
160
164
  outlineStyle: 'none',
161
165
 
162
166
  [variants['mobile']]: {