@astryxdesign/core 0.6.3-canary.f22695a → 0.6.3

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.
Files changed (118) hide show
  1. package/dist/Button/Button.d.ts.map +1 -1
  2. package/dist/Button/Button.js +28 -13
  3. package/dist/Chat/ChatLayout.d.ts +0 -19
  4. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  5. package/dist/Chat/ChatLayout.js +0 -19
  6. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  7. package/dist/Chat/ChatLayoutScrollButton.js +34 -44
  8. package/dist/Citation/Citation.d.ts +1 -1
  9. package/dist/Citation/Citation.d.ts.map +1 -1
  10. package/dist/Citation/Citation.js +2 -3
  11. package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
  12. package/dist/CodeBlock/highlightRanges.js +3 -14
  13. package/dist/Icon/Icon.d.ts +31 -6
  14. package/dist/Icon/Icon.d.ts.map +1 -1
  15. package/dist/Icon/Icon.js +71 -8
  16. package/dist/Link/useLinkComponent.d.ts +15 -5
  17. package/dist/Link/useLinkComponent.d.ts.map +1 -1
  18. package/dist/Link/useLinkComponent.js +51 -34
  19. package/dist/Markdown/Markdown.js +2 -2
  20. package/dist/Markdown/url.d.ts +0 -2
  21. package/dist/Markdown/url.d.ts.map +1 -1
  22. package/dist/Markdown/url.js +2 -8
  23. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  24. package/dist/PowerSearch/PowerSearchValueEditor.js +0 -5
  25. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  26. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  27. package/dist/TopNav/TopNavMenu.js +2 -3
  28. package/dist/astryx.css +4 -2
  29. package/dist/hooks/useClickableContainer.d.ts +1 -10
  30. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  31. package/dist/hooks/useClickableContainer.js +4 -15
  32. package/dist/index.d.ts +0 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +0 -3
  35. package/dist/theme/generateThemeRules.d.ts +7 -13
  36. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  37. package/dist/theme/generateThemeRules.js +35 -131
  38. package/package.json +4 -9
  39. package/src/Button/Button.doc.mjs +5 -5
  40. package/src/Button/Button.tsx +13 -15
  41. package/src/Chat/ChatLayout.doc.mjs +4 -12
  42. package/src/Chat/ChatLayout.test.tsx +0 -28
  43. package/src/Chat/ChatLayout.tsx +0 -19
  44. package/src/Chat/ChatLayoutScrollButton.test.tsx +0 -31
  45. package/src/Chat/ChatLayoutScrollButton.tsx +14 -31
  46. package/src/Citation/Citation.doc.mjs +2 -2
  47. package/src/Citation/Citation.test.tsx +0 -17
  48. package/src/Citation/Citation.tsx +2 -4
  49. package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
  50. package/src/CodeBlock/highlightRanges.test.ts +1 -143
  51. package/src/CodeBlock/highlightRanges.ts +5 -15
  52. package/src/Icon/Icon.doc.mjs +5 -7
  53. package/src/Icon/Icon.spec.md +40 -81
  54. package/src/Icon/Icon.test.tsx +3 -6
  55. package/src/Icon/Icon.tsx +68 -20
  56. package/src/IconButton/IconButton.doc.mjs +3 -3
  57. package/src/IconButton/IconButton.test.tsx +0 -40
  58. package/src/Item/Item.doc.mjs +2 -2
  59. package/src/Link/Link.doc.mjs +4 -6
  60. package/src/Link/LinkProvider.doc.mjs +2 -2
  61. package/src/Link/useLinkComponent.test.tsx +0 -333
  62. package/src/Link/useLinkComponent.ts +57 -29
  63. package/src/List/ListItem.doc.mjs +2 -2
  64. package/src/Markdown/Markdown.doc.mjs +2 -2
  65. package/src/Markdown/Markdown.spec.md +15 -19
  66. package/src/Markdown/Markdown.test.tsx +0 -52
  67. package/src/Markdown/Markdown.tsx +2 -2
  68. package/src/Markdown/parser.test.ts +0 -20
  69. package/src/Markdown/url.ts +3 -9
  70. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +0 -51
  71. package/src/PowerSearch/PowerSearchValueEditor.tsx +0 -4
  72. package/src/Token/Token.doc.mjs +2 -2
  73. package/src/TopNav/TopNavMenu.doc.mjs +2 -2
  74. package/src/TopNav/TopNavMenu.test.tsx +0 -30
  75. package/src/TopNav/TopNavMenu.tsx +2 -7
  76. package/src/hooks/useClickableContainer.ts +4 -20
  77. package/src/index.ts +0 -3
  78. package/src/tailwind-theme.css +6 -0
  79. package/src/theme/Theme.test.tsx +0 -32
  80. package/src/theme/generateThemeRules.test.ts +2 -470
  81. package/src/theme/generateThemeRules.ts +51 -219
  82. package/src/theme/tokenValueCompat.test.ts +1 -4
  83. package/dist/Icon/IconDefaultSizeContext.d.ts +0 -4
  84. package/dist/Icon/IconDefaultSizeContext.d.ts.map +0 -1
  85. package/dist/Icon/IconDefaultSizeContext.js +0 -18
  86. package/dist/Icon/IconSize.stylex.d.ts +0 -65
  87. package/dist/Icon/IconSize.stylex.d.ts.map +0 -1
  88. package/dist/Icon/IconSize.stylex.js +0 -75
  89. package/dist/Timer/Timer.d.ts +0 -49
  90. package/dist/Timer/Timer.d.ts.map +0 -1
  91. package/dist/Timer/Timer.js +0 -158
  92. package/dist/Timer/index.d.ts +0 -9
  93. package/dist/Timer/index.d.ts.map +0 -1
  94. package/dist/Timer/index.js +0 -10
  95. package/dist/theme/declarationBoundary.d.ts +0 -17
  96. package/dist/theme/declarationBoundary.d.ts.map +0 -1
  97. package/dist/theme/declarationBoundary.js +0 -343
  98. package/dist/utils/safeUrl.d.ts +0 -11
  99. package/dist/utils/safeUrl.d.ts.map +0 -1
  100. package/dist/utils/safeUrl.js +0 -78
  101. package/src/Chat/ChatLayout.spec.md +0 -271
  102. package/src/Chat/ChatLayoutScrollButton.spec.md +0 -338
  103. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +0 -514
  104. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +0 -740
  105. package/src/Icon/IconDefaultSizeContext.ts +0 -23
  106. package/src/Icon/IconSize.stylex.ts +0 -70
  107. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +0 -261
  108. package/src/Markdown/Markdown.renderBoundary.test.tsx +0 -72
  109. package/src/Timer/Timer.doc.mjs +0 -183
  110. package/src/Timer/Timer.spec.md +0 -215
  111. package/src/Timer/Timer.test.tsx +0 -302
  112. package/src/Timer/Timer.tsx +0 -258
  113. package/src/Timer/index.ts +0 -11
  114. package/src/hooks/useClickableContainer.test.tsx +0 -236
  115. package/src/theme/declarationBoundary.test.ts +0 -126
  116. package/src/theme/declarationBoundary.ts +0 -347
  117. package/src/utils/safeUrl.test.ts +0 -88
  118. package/src/utils/safeUrl.ts +0 -85
@@ -9,17 +9,11 @@
9
9
  * Used by both the runtime path (Theme injects <style>) and the build
10
10
  * path (`astryx theme build` pre-compiles to CSS files).
11
11
  *
12
- * Every consumer-supplied declaration is checked by declarationBoundary.ts
13
- * before it is emitted, so a value can never end its declaration or rule
14
- * early. A refused declaration is dropped and reported in the supplied
15
- * warnings array (build receipts), or through `console.warn` (runtime).
16
- *
17
12
  * Extracted from defineTheme.ts to reduce cyclomatic complexity and provide
18
13
  * a clear single-responsibility module for CSS generation.
19
14
  *
20
- * @input DefinedTheme (resolved theme object from defineTheme), optional warnings array
21
- * @output CSS rule strings, split by layer (component vs prose), and warning text
22
- * for each dropped declaration
15
+ * @input DefinedTheme (resolved theme object from defineTheme)
16
+ * @output CSS rule strings, split by layer (component vs prose)
23
17
  * @position packages/core/src/theme/generateThemeRules.ts
24
18
  */
25
19
 
@@ -32,10 +26,6 @@ import {parseStyleKey} from '../utils/parseStyleKey';
32
26
  import {getDerivedVars} from './derivedVarRegistry';
33
27
  import {dataTokenDefaults} from './domainTokens/dataTokens';
34
28
  import {cssVar, classPrefix, dataAttrNamespace} from '../naming';
35
- import {
36
- checkDeclarationName,
37
- checkDeclarationValue,
38
- } from './declarationBoundary';
39
29
 
40
30
  /**
41
31
  * Theme @scope selectors.
@@ -376,117 +366,6 @@ function expandContainerPadding(
376
366
  return tokens;
377
367
  }
378
368
 
379
- // =============================================================================
380
- // Declaration assembly: a declaration always stays one declaration
381
- // =============================================================================
382
-
383
- type DiagnosticSink = (message: string) => void;
384
-
385
- const warnToConsole: DiagnosticSink = message => {
386
- console.warn(`[astryx theme] ${message}`);
387
- };
388
-
389
- /** Build receipts collect warning text; runtime callers warn by default. */
390
- function diagnosticSink(warnings: string[] | undefined): DiagnosticSink {
391
- return warnings ? message => warnings.push(message) : warnToConsole;
392
- }
393
-
394
- /** Shorten an authored value for a one-line message. */
395
- function previewValue(value: string): string {
396
- const oneLine = JSON.stringify(value);
397
- return oneLine.length > 80 ? `${oneLine.slice(0, 77)}..."` : oneLine;
398
- }
399
-
400
- function reportDrop(
401
- sink: DiagnosticSink,
402
- property: string,
403
- value: string,
404
- location: string,
405
- reason: string,
406
- ): void {
407
- sink(
408
- `dropped "${property}" in ${location}: ${reason} (value: ${previewValue(value)})`,
409
- );
410
- }
411
-
412
- /**
413
- * True when `name: value;` stays exactly one declaration; otherwise reports
414
- * the drop and returns false. Both checks follow CSS syntax, so valid CSS a
415
- * browser keeps inside one declaration (a `data:` URI, `Gill\ Sans`, a closed
416
- * comment, a vendor-prefixed property) is never refused; see
417
- * declarationBoundary.ts for the rules.
418
- */
419
- function acceptDeclaration(
420
- property: string,
421
- value: string,
422
- location: string,
423
- sink: DiagnosticSink,
424
- ): boolean {
425
- const reason = checkDeclarationName(property) ?? checkDeclarationValue(value);
426
- if (reason === null) {
427
- return true;
428
- }
429
- reportDrop(sink, property, value, location, reason);
430
- return false;
431
- }
432
-
433
- /**
434
- * Assemble `prop: value;` lines, dropping (and reporting) any entry whose
435
- * property or value could not stay a single declaration. Theme definitions
436
- * are code, but apps do assemble them from stored input (brand colors,
437
- * white-labeling), so the generated stylesheet must never extend beyond the
438
- * declarations it means to emit.
439
- */
440
- function joinDeclarations(
441
- entries: [string, string][],
442
- location: string,
443
- sink: DiagnosticSink,
444
- mapProp: (prop: string) => string = p => p,
445
- ): string {
446
- const lines: string[] = [];
447
- for (const [rawProp, rawValue] of entries) {
448
- // Legacy unenrolled tokens retain non-string values. Scan the same text
449
- // interpolation has always emitted, without changing the normalized theme.
450
- const value = `${rawValue}`;
451
- const prop = mapProp(rawProp);
452
- if (acceptDeclaration(prop, value, location, sink)) {
453
- lines.push(` ${prop}: ${value};`);
454
- }
455
- }
456
- return lines.join('\n');
457
- }
458
-
459
- /** The `:scope` token block for portable and theme-local token values. */
460
- function tokenBlock(
461
- source: ThemeRuleSource,
462
- location: string,
463
- sink: DiagnosticSink,
464
- ): string | null {
465
- const declarations = [
466
- joinDeclarations(Object.entries(source.tokens), `${location}tokens`, sink),
467
- joinDeclarations(
468
- Object.entries(source.localTokens ?? {}),
469
- `${location}localTokens`,
470
- sink,
471
- ),
472
- ]
473
- .filter(block => block.length > 0)
474
- .join('\n');
475
- const hasEntries =
476
- Object.keys(source.tokens).length > 0 ||
477
- Object.keys(source.localTokens ?? {}).length > 0;
478
- return hasEntries ? ` :scope {\n${declarations}\n }` : null;
479
- }
480
-
481
- /** `components.button["variant:secondary"]`-style location for a rule. */
482
- function componentLocation(
483
- prefix: string,
484
- component: string,
485
- key: string,
486
- ): string {
487
- return `${prefix}components.${component}[${JSON.stringify(key)}]`;
488
- }
489
-
490
369
  // =============================================================================
491
370
  // Public API
492
371
  // =============================================================================
@@ -514,12 +393,9 @@ export interface ThemeRuleSource {
514
393
  components?: ComponentStyleMap;
515
394
  }
516
395
 
517
- export function generateThemeRules(
518
- theme: ThemeRuleSource,
519
- warnings?: string[],
520
- ): string[] {
396
+ export function generateThemeRules(theme: ThemeRuleSource): string[] {
521
397
  const parts: string[] = [];
522
- const sink = diagnosticSink(warnings);
398
+ const tokens = theme.tokens;
523
399
 
524
400
  // Bare prose rules reference semantic variables instead of baking the root
525
401
  // value. That lets adaptation token writes take effect through CSS alone
@@ -527,9 +403,15 @@ export function generateThemeRules(
527
403
  const val = (key: string): string => `var(${key})`;
528
404
 
529
405
  // 1. Token block — CSS custom properties on :scope
530
- const tokenRules = tokenBlock(theme, '', sink);
531
- if (tokenRules !== null) {
532
- parts.push(tokenRules);
406
+ const tokenEntries = [
407
+ ...Object.entries(tokens),
408
+ ...Object.entries(theme.localTokens ?? {}),
409
+ ];
410
+ if (tokenEntries.length > 0) {
411
+ const declarations = tokenEntries
412
+ .map(([prop, value]) => ` ${prop}: ${value};`)
413
+ .join('\n');
414
+ parts.push(` :scope {\n${declarations}\n }`);
533
415
  }
534
416
 
535
417
  // 1b. Base font — apply the theme's declared body font to the scope root.
@@ -538,14 +420,14 @@ export function generateThemeRules(
538
420
  // sets a page font. `font-family` inherits, so one rule on :scope covers
539
421
  // the tree. Only emitted when the theme declares a body font, so a bare
540
422
  // theme still contributes no scope rules of its own.
541
- if (theme.tokens['--font-family-body']) {
423
+ if (tokens['--font-family-body']) {
542
424
  parts.push(` :scope {\n font-family: var(--font-family-body);\n }`);
543
425
  }
544
426
 
545
427
  // 2. Component overrides: stable .astryx-* target classes combined with
546
428
  // reflected data-* selectors for visual props and runtime states.
547
429
  if (theme.components) {
548
- generateComponentRules(theme.components, parts, {sink});
430
+ generateComponentRules(theme.components, parts);
549
431
  }
550
432
 
551
433
  // 3. Prose HTML element rules (h1-h6, p, small, code, hr)
@@ -641,13 +523,6 @@ function generateHeadingWeightOverrides(
641
523
  }
642
524
  }
643
525
 
644
- /**
645
- * The `fontWeight` a heading rule authors for `styleKey`, or undefined when
646
- * it has none. A value that cannot stay one declaration is treated as not
647
- * authored, so the override falls back to the inherited or token weight
648
- * instead of interpolating it; the drop itself is reported where that same
649
- * rule's declarations are emitted, so it is not reported twice here.
650
- */
651
526
  function getAuthoredHeadingWeight(
652
527
  headingRuleMap: Record<string, unknown>,
653
528
  styleKey: string,
@@ -657,20 +532,13 @@ function getAuthoredHeadingWeight(
657
532
  return undefined;
658
533
  }
659
534
  const fontWeight = (rule as Record<string, unknown>).fontWeight;
660
- return typeof fontWeight === 'string' &&
661
- checkDeclarationValue(fontWeight) === null
662
- ? fontWeight
663
- : undefined;
535
+ return typeof fontWeight === 'string' ? fontWeight : undefined;
664
536
  }
665
537
 
666
538
  /** Options shared by root, adaptation, and media-surface component lowering. */
667
539
  interface ComponentRuleOptions {
668
540
  resetInheritedPaddingSpecificity?: boolean;
669
541
  surface?: MediaSurface;
670
- /** Receives dropped declarations; defaults to `console.warn`. */
671
- sink?: DiagnosticSink;
672
- /** Location prefix for diagnostics, e.g. `onDark.` or `adaptations[0].`. */
673
- location?: string;
674
542
  }
675
543
 
676
544
  /**
@@ -687,8 +555,6 @@ function generateComponentRules(
687
555
  {
688
556
  resetInheritedPaddingSpecificity = false,
689
557
  surface,
690
- sink = warnToConsole,
691
- location: locationPrefix = '',
692
558
  }: ComponentRuleOptions = {},
693
559
  ): void {
694
560
  for (const [component, rules] of Object.entries(components)) {
@@ -700,7 +566,6 @@ function generateComponentRules(
700
566
 
701
567
  const suffix = parseStyleKey(key);
702
568
  const baseSelector = componentSelector(component, suffix, surface);
703
- const location = componentLocation(locationPrefix, component, key);
704
569
 
705
570
  // Separate regular properties from pseudo-class overrides
706
571
  const props: [string, string][] = [];
@@ -709,14 +574,7 @@ function generateComponentRules(
709
574
  for (const [prop, value] of entries) {
710
575
  if (prop.startsWith(':') && typeof value === 'object') {
711
576
  pseudos.push([prop, value]);
712
- } else if (
713
- acceptDeclaration(
714
- toKebabCase(prop),
715
- `${value as string}`,
716
- location,
717
- sink,
718
- )
719
- ) {
577
+ } else {
720
578
  props.push([prop, value as string]);
721
579
  }
722
580
  }
@@ -796,12 +654,9 @@ function generateComponentRules(
796
654
 
797
655
  // Emit base rule
798
656
  if (finalProps.length > 0) {
799
- const declarations = joinDeclarations(
800
- finalProps,
801
- location,
802
- sink,
803
- toKebabCase,
804
- );
657
+ const declarations = finalProps
658
+ .map(([prop, value]) => ` ${toKebabCase(prop)}: ${value};`)
659
+ .join('\n');
805
660
  parts.push(` ${baseSelector} {\n${declarations}\n }`);
806
661
  }
807
662
 
@@ -809,12 +664,9 @@ function generateComponentRules(
809
664
  for (const [pseudo, pseudoStyles] of pseudos) {
810
665
  const pseudoEntries = Object.entries(pseudoStyles);
811
666
  if (pseudoEntries.length > 0) {
812
- const declarations = joinDeclarations(
813
- pseudoEntries,
814
- `${location}[${JSON.stringify(pseudo)}]`,
815
- sink,
816
- toKebabCase,
817
- );
667
+ const declarations = pseudoEntries
668
+ .map(([prop, value]) => ` ${toKebabCase(prop)}: ${value};`)
669
+ .join('\n');
818
670
  parts.push(
819
671
  ` ${appendPseudoToSelectorList(baseSelector, pseudo)} {\n${declarations}\n }`,
820
672
  );
@@ -980,11 +832,8 @@ function generateSizeOverrides(
980
832
  * Component rules (tokens, stable .astryx-* targets plus data-* selectors) are
981
833
  * that need to beat StyleX — they stay in astryx-theme (above StyleX layers).
982
834
  */
983
- export function generateThemeRulesSplit(
984
- theme: DefinedTheme,
985
- warnings?: string[],
986
- ): ThemeRulesSplit {
987
- const allRules = generateThemeRules(theme, warnings);
835
+ export function generateThemeRulesSplit(theme: DefinedTheme): ThemeRulesSplit {
836
+ const allRules = generateThemeRules(theme);
988
837
 
989
838
  const prose: string[] = [];
990
839
  const component: string[] = [];
@@ -1008,29 +857,22 @@ export function generateThemeRulesSplit(
1008
857
  * to media contexts — only tokens change. Themes can further customize
1009
858
  * via onDark.components / onLight.components.
1010
859
  */
1011
- export function generateOnMediaCSS(
1012
- theme: DefinedTheme,
1013
- warnings?: string[],
1014
- ): string {
860
+ export function generateOnMediaCSS(theme: DefinedTheme): string {
1015
861
  const parts: string[] = [];
1016
862
  const scopeSelector = themeScopeStart(theme.name);
1017
- const sink = diagnosticSink(warnings);
1018
863
 
1019
864
  for (const surface of ['dark', 'light'] as const) {
1020
865
  const onMedia = surface === 'dark' ? theme.__onDark : theme.__onLight;
1021
866
  if (!onMedia) {
1022
867
  continue;
1023
868
  }
1024
- const location = surface === 'dark' ? 'onDark.' : 'onLight.';
1025
869
 
1026
870
  // Token overrides
1027
871
  const tokenEntries = Object.entries(onMedia.tokens);
1028
872
  if (tokenEntries.length > 0) {
1029
- const declarations = joinDeclarations(
1030
- tokenEntries,
1031
- `${location}tokens`,
1032
- sink,
1033
- );
873
+ const declarations = tokenEntries
874
+ .map(([prop, value]) => ` ${prop}: ${value};`)
875
+ .join('\n');
1034
876
  parts.push(` ${mediaSelector(surface)} {\n${declarations}\n }`);
1035
877
  }
1036
878
 
@@ -1040,8 +882,6 @@ export function generateOnMediaCSS(
1040
882
  generateComponentRules(onMedia.components, parts, {
1041
883
  resetInheritedPaddingSpecificity: true,
1042
884
  surface,
1043
- sink,
1044
- location,
1045
885
  });
1046
886
  generateColorOverrides(onMedia.components, parts, surface);
1047
887
  generateSizeOverrides(onMedia.components, parts, surface);
@@ -1065,22 +905,22 @@ export function generateOnMediaCSS(
1065
905
  }
1066
906
 
1067
907
  /** Generate only the declarations one adaptation rule writes. */
1068
- function generateAdaptationRuleRules(
1069
- rule: ThemeRuleSource,
1070
- location: string,
1071
- sink: DiagnosticSink,
1072
- ): string[] {
908
+ function generateAdaptationRuleRules(rule: ThemeRuleSource): string[] {
1073
909
  const parts: string[] = [];
1074
- const tokens = tokenBlock(rule, location, sink);
1075
- if (tokens !== null) {
1076
- parts.push(tokens);
910
+ const tokenEntries = [
911
+ ...Object.entries(rule.tokens),
912
+ ...Object.entries(rule.localTokens ?? {}),
913
+ ];
914
+ if (tokenEntries.length > 0) {
915
+ const declarations = tokenEntries
916
+ .map(([prop, value]) => ` ${prop}: ${value};`)
917
+ .join('\n');
918
+ parts.push(` :scope {\n${declarations}\n }`);
1077
919
  }
1078
920
 
1079
921
  if (rule.components) {
1080
922
  generateComponentRules(rule.components, parts, {
1081
923
  resetInheritedPaddingSpecificity: true,
1082
- sink,
1083
- location,
1084
924
  });
1085
925
  generateColorOverrides(rule.components, parts);
1086
926
  generateSizeOverrides(rule.components, parts);
@@ -1118,11 +958,7 @@ function generateAdaptationMediaBlock(
1118
958
  * rule. Bare prose follows semantic variables, so token writes need no duplicate
1119
959
  * prose selectors here.
1120
960
  */
1121
- export function generateAdaptationCSS(
1122
- theme: DefinedTheme,
1123
- warnings?: string[],
1124
- ): ThemeCSSOutput {
1125
- const sink = diagnosticSink(warnings);
961
+ export function generateAdaptationCSS(theme: DefinedTheme): ThemeCSSOutput {
1126
962
  // Built themes can reach this compiler without passing through defineTheme.
1127
963
  // Validate retained metadata even when it has no rules (and therefore emits
1128
964
  // no CSS): width points remain observable through AppShell and inheritance.
@@ -1156,12 +992,8 @@ export function generateAdaptationCSS(
1156
992
  // active whenever the later condition matches, even if the earlier condition
1157
993
  // does not. Pairwise merging cannot repair that: multiple mutually exclusive
1158
994
  // earlier rules can each overlap one broad later rule.
1159
- for (const [index, rule] of rules.entries()) {
1160
- const parts = generateAdaptationRuleRules(
1161
- rule,
1162
- `adaptations[${index}].`,
1163
- sink,
1164
- );
995
+ for (const rule of rules) {
996
+ const parts = generateAdaptationRuleRules(rule);
1165
997
  if (parts.length === 0) {
1166
998
  continue;
1167
999
  }
@@ -1207,9 +1039,12 @@ export function generateAdaptationCSS(
1207
1039
  return {prose: '', component: blocks.join('\n\n')};
1208
1040
  }
1209
1041
 
1210
- /** Indent the rule start without rewriting newlines inside authored values. */
1042
+ /** Indent a generated rule one level further, for nesting inside `@media`. */
1211
1043
  function indentRule(rule: string): string {
1212
- return ` ${rule}`;
1044
+ return rule
1045
+ .split('\n')
1046
+ .map(line => (line.length > 0 ? ` ${line}` : line))
1047
+ .join('\n');
1213
1048
  }
1214
1049
 
1215
1050
  /**
@@ -1250,11 +1085,8 @@ export function generateDataTokenDefaultsCSS(): string {
1250
1085
  * The theme-independent `--color-data-*` defaults are not part of this output:
1251
1086
  * see `generateDataTokenDefaultsCSS`.
1252
1087
  */
1253
- export function generateThemeCSS(
1254
- theme: DefinedTheme,
1255
- warnings?: string[],
1256
- ): ThemeCSSOutput {
1257
- const {component, prose} = generateThemeRulesSplit(theme, warnings);
1088
+ export function generateThemeCSS(theme: DefinedTheme): ThemeCSSOutput {
1089
+ const {component, prose} = generateThemeRulesSplit(theme);
1258
1090
  const scopeSelector = themeScopeStart(theme.name);
1259
1091
  const scopeTo = THEME_SCOPE_TO;
1260
1092
 
@@ -1274,14 +1106,14 @@ export function generateThemeCSS(
1274
1106
 
1275
1107
  // Adaptations follow the root theme in authored order. Media-surface rules
1276
1108
  // follow adaptations so onDark/onLight keep their specified precedence.
1277
- const adaptationCss = generateAdaptationCSS(theme, warnings);
1109
+ const adaptationCss = generateAdaptationCSS(theme);
1278
1110
  if (adaptationCss.component) {
1279
1111
  componentCss = componentCss
1280
1112
  ? `${componentCss}\n\n${adaptationCss.component}`
1281
1113
  : adaptationCss.component;
1282
1114
  }
1283
1115
 
1284
- const onMediaCss = generateOnMediaCSS(theme, warnings);
1116
+ const onMediaCss = generateOnMediaCSS(theme);
1285
1117
  if (onMediaCss) {
1286
1118
  componentCss = componentCss
1287
1119
  ? `${componentCss}\n\n${onMediaCss}`
@@ -22,7 +22,7 @@
22
22
  */
23
23
 
24
24
  import {describe, expect, it} from 'vitest';
25
- import {defineTheme, generateThemeCSS} from './defineTheme';
25
+ import {defineTheme} from './defineTheme';
26
26
  import {resolveTokenValue} from './resolveThemeValues';
27
27
 
28
28
  /** Exactly what the pre-extraction implementation did with each shape. */
@@ -43,9 +43,6 @@ describe('root token values keep their historical acceptance', () => {
43
43
  });
44
44
 
45
45
  expect(theme.tokens['--color-background-body']).toBe(expected);
46
- expect(generateThemeCSS(theme).component).toContain(
47
- `--color-background-body: ${String(expected)};`,
48
- );
49
46
  });
50
47
 
51
48
  it('still resolves the documented shapes', () => {
@@ -1,4 +0,0 @@
1
- import type { IconSize } from './IconSize.stylex';
2
- export declare const IconDefaultSizeProvider: import("react").Provider<"xsm" | "sm" | "lg" | "md" | null>;
3
- export declare function useIconSize(size: IconSize | undefined): IconSize;
4
- //# sourceMappingURL=IconDefaultSizeContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IconDefaultSizeContext.d.ts","sourceRoot":"","sources":["../../src/Icon/IconDefaultSizeContext.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAKhD,eAAO,MAAM,uBAAuB,6DAAkC,CAAC;AAEvE,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAGhE"}
@@ -1,18 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- 'use client';
4
-
5
- /**
6
- * @file IconDefaultSizeContext.ts
7
- * @input Uses React context and an optional Icon size prop
8
- * @output Supplies a component-owned default size to descendant Icon instances
9
- * @position Internal Icon sizing context; consumed by Icon and icon-slot owners
10
- */
11
- import { createContext, use } from 'react';
12
- const IconDefaultSizeContext = /*#__PURE__*/createContext(null);
13
- IconDefaultSizeContext.displayName = 'IconDefaultSizeContext';
14
- export const IconDefaultSizeProvider = IconDefaultSizeContext.Provider;
15
- export function useIconSize(size) {
16
- const contextualSize = use(IconDefaultSizeContext);
17
- return size ?? contextualSize ?? 'md';
18
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * @file IconSize.stylex.ts
3
- * @input Defines the Icon size scale
4
- * @output Exports shared Icon size types and StyleX styles
5
- * @position Internal Icon sizing source; consumed by Icon and icon-slot owners
6
- */
7
- import * as stylex from '@stylexjs/stylex';
8
- /**
9
- * Icon sizes are expressed in `rem` so they scale with the root font-size.
10
- * Values are the px-equivalents at a 16px root: 12, 16, 20, and 24px.
11
- */
12
- declare const iconSizeValues: {
13
- readonly xsm: "0.75rem";
14
- readonly sm: "1rem";
15
- readonly md: "1.25rem";
16
- readonly lg: "1.5rem";
17
- };
18
- export type IconSize = keyof typeof iconSizeValues;
19
- /** Size styles for direct SVG icon components. */
20
- export declare const iconSizeStyles: Readonly<{
21
- readonly xsm: Readonly<{
22
- readonly width: stylex.StyleXClassNameFor<"width", "0.75rem">;
23
- readonly height: stylex.StyleXClassNameFor<"height", "0.75rem">;
24
- }>;
25
- readonly sm: Readonly<{
26
- readonly width: stylex.StyleXClassNameFor<"width", "1rem">;
27
- readonly height: stylex.StyleXClassNameFor<"height", "1rem">;
28
- }>;
29
- readonly md: Readonly<{
30
- readonly width: stylex.StyleXClassNameFor<"width", "1.25rem">;
31
- readonly height: stylex.StyleXClassNameFor<"height", "1.25rem">;
32
- }>;
33
- readonly lg: Readonly<{
34
- readonly width: stylex.StyleXClassNameFor<"width", "1.5rem">;
35
- readonly height: stylex.StyleXClassNameFor<"height", "1.5rem">;
36
- }>;
37
- }>;
38
- /**
39
- * Size styles for icon boxes and string-based registry icons. `fontSize`
40
- * keeps 1em-based icons in step with the box.
41
- */
42
- export declare const iconBoxSizeStyles: Readonly<{
43
- readonly xsm: Readonly<{
44
- readonly width: stylex.StyleXClassNameFor<"width", "0.75rem">;
45
- readonly height: stylex.StyleXClassNameFor<"height", "0.75rem">;
46
- readonly fontSize: stylex.StyleXClassNameFor<"fontSize", "0.75rem">;
47
- }>;
48
- readonly sm: Readonly<{
49
- readonly width: stylex.StyleXClassNameFor<"width", "1rem">;
50
- readonly height: stylex.StyleXClassNameFor<"height", "1rem">;
51
- readonly fontSize: stylex.StyleXClassNameFor<"fontSize", "1rem">;
52
- }>;
53
- readonly md: Readonly<{
54
- readonly width: stylex.StyleXClassNameFor<"width", "1.25rem">;
55
- readonly height: stylex.StyleXClassNameFor<"height", "1.25rem">;
56
- readonly fontSize: stylex.StyleXClassNameFor<"fontSize", "1.25rem">;
57
- }>;
58
- readonly lg: Readonly<{
59
- readonly width: stylex.StyleXClassNameFor<"width", "1.5rem">;
60
- readonly height: stylex.StyleXClassNameFor<"height", "1.5rem">;
61
- readonly fontSize: stylex.StyleXClassNameFor<"fontSize", "1.5rem">;
62
- }>;
63
- }>;
64
- export {};
65
- //# sourceMappingURL=IconSize.stylex.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"IconSize.stylex.d.ts","sourceRoot":"","sources":["../../src/Icon/IconSize.stylex.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAE3C;;;GAGG;AACH,QAAA,MAAM,cAAc;;;;;CAKV,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,cAAc,CAAC;AAEnD,kDAAkD;AAClD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;EAiBzB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;EAqB5B,CAAC"}
@@ -1,75 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /**
4
- * @file IconSize.stylex.ts
5
- * @input Defines the Icon size scale
6
- * @output Exports shared Icon size types and StyleX styles
7
- * @position Internal Icon sizing source; consumed by Icon and icon-slot owners
8
- */
9
-
10
- import * as stylex from '@stylexjs/stylex';
11
-
12
- /**
13
- * Icon sizes are expressed in `rem` so they scale with the root font-size.
14
- * Values are the px-equivalents at a 16px root: 12, 16, 20, and 24px.
15
- */
16
- const iconSizeValues = {
17
- xsm: '0.75rem',
18
- sm: '1rem',
19
- md: '1.25rem',
20
- lg: '1.5rem'
21
- };
22
- /** Size styles for direct SVG icon components. */
23
- export const iconSizeStyles = {
24
- xsm: {
25
- kzqmXN: "x1jw3ynk",
26
- kZKoxP: "xvle69y",
27
- $$css: true
28
- },
29
- sm: {
30
- kzqmXN: "xcdlrvm",
31
- kZKoxP: "x1l36t39",
32
- $$css: true
33
- },
34
- md: {
35
- kzqmXN: "xwqq7k2",
36
- kZKoxP: "xmll18r",
37
- $$css: true
38
- },
39
- lg: {
40
- kzqmXN: "xp8d6y2",
41
- kZKoxP: "xam5rvr",
42
- $$css: true
43
- }
44
- };
45
-
46
- /**
47
- * Size styles for icon boxes and string-based registry icons. `fontSize`
48
- * keeps 1em-based icons in step with the box.
49
- */
50
- export const iconBoxSizeStyles = {
51
- xsm: {
52
- kzqmXN: "x1jw3ynk",
53
- kZKoxP: "xvle69y",
54
- kGuDYH: "xboafo0",
55
- $$css: true
56
- },
57
- sm: {
58
- kzqmXN: "xcdlrvm",
59
- kZKoxP: "x1l36t39",
60
- kGuDYH: "x1jchvi3",
61
- $$css: true
62
- },
63
- md: {
64
- kzqmXN: "xwqq7k2",
65
- kZKoxP: "xmll18r",
66
- kGuDYH: "x1603h9y",
67
- $$css: true
68
- },
69
- lg: {
70
- kzqmXN: "xp8d6y2",
71
- kZKoxP: "xam5rvr",
72
- kGuDYH: "xngnso2",
73
- $$css: true
74
- }
75
- };