@nxds/core 0.9.0 → 0.10.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.
@@ -15,8 +15,8 @@ type DeepReadonly<T> = T extends object ? {
15
15
  type CatalogueFamily = 'borderwidth' | 'breakpoint' | 'color' | 'motion' | 'radius' | 'shadow' | 'spacing' | 'typography' | 'z-index';
16
16
  /**
17
17
  * Canonical identity: an identifier in the `--nx-*` custom property scheme.
18
- * Most tokens declare it in the generated CSS. Typography and shadow styles
19
- * and breakpoints do not; they declare a theme property or a utility instead.
18
+ * Most tokens declare it in the generated CSS. Typography styles and
19
+ * breakpoints do not; they declare a utility or a theme property instead.
20
20
  */
21
21
  type CatalogueTokenName = `--nx-${string}`;
22
22
  /** Another name that maps onto the canonical token. */
@@ -52,7 +52,7 @@ interface CatalogueDeclaration {
52
52
  interface CatalogueVariant {
53
53
  /**
54
54
  * The theme mode the value applies in (`light` / `dark` for a runtime
55
- * colour or a shadow layer), or `null` when it applies in both.
55
+ * colour or a shadow), or `null` when it applies in both.
56
56
  */
57
57
  readonly mode: Mode | null;
58
58
  /**
@@ -68,8 +68,8 @@ interface CatalogueVariant {
68
68
  readonly authoredValue: TokenValue | null;
69
69
  /**
70
70
  * What the generated CSS declares: one custom property for a scalar or a
71
- * shadow style (`--nx-spacing-4`, or `--breakpoint-md` and `--shadow-sm` for
72
- * a token declared only under `@theme`), or the `@utility` body for a
71
+ * shadow style (`--nx-spacing-4`, `--nx-shadow-sm`, or `--breakpoint-md`
72
+ * for a token declared only under `@theme`), or the `@utility` body for a
73
73
  * typography style.
74
74
  */
75
75
  readonly declarations: readonly CatalogueDeclaration[];
@@ -106,6 +106,7 @@ interface CatalogueToken {
106
106
  /**
107
107
  * Every nxds token, identified by its `--nx-*` name: primitives, runtime
108
108
  * colours, spacing, z-index, breakpoints, and typography and shadow styles.
109
+ * Shadow layer primitives only compose the shadow styles.
109
110
  * Runtime colours are computed from `DEFAULT_NXDS_APPEARANCE` in explicit
110
111
  * light and dark modes; each variant records the appearance it used.
111
112
  */
@@ -15,8 +15,8 @@ type DeepReadonly<T> = T extends object ? {
15
15
  type CatalogueFamily = 'borderwidth' | 'breakpoint' | 'color' | 'motion' | 'radius' | 'shadow' | 'spacing' | 'typography' | 'z-index';
16
16
  /**
17
17
  * Canonical identity: an identifier in the `--nx-*` custom property scheme.
18
- * Most tokens declare it in the generated CSS. Typography and shadow styles
19
- * and breakpoints do not; they declare a theme property or a utility instead.
18
+ * Most tokens declare it in the generated CSS. Typography styles and
19
+ * breakpoints do not; they declare a utility or a theme property instead.
20
20
  */
21
21
  type CatalogueTokenName = `--nx-${string}`;
22
22
  /** Another name that maps onto the canonical token. */
@@ -52,7 +52,7 @@ interface CatalogueDeclaration {
52
52
  interface CatalogueVariant {
53
53
  /**
54
54
  * The theme mode the value applies in (`light` / `dark` for a runtime
55
- * colour or a shadow layer), or `null` when it applies in both.
55
+ * colour or a shadow), or `null` when it applies in both.
56
56
  */
57
57
  readonly mode: Mode | null;
58
58
  /**
@@ -68,8 +68,8 @@ interface CatalogueVariant {
68
68
  readonly authoredValue: TokenValue | null;
69
69
  /**
70
70
  * What the generated CSS declares: one custom property for a scalar or a
71
- * shadow style (`--nx-spacing-4`, or `--breakpoint-md` and `--shadow-sm` for
72
- * a token declared only under `@theme`), or the `@utility` body for a
71
+ * shadow style (`--nx-spacing-4`, `--nx-shadow-sm`, or `--breakpoint-md`
72
+ * for a token declared only under `@theme`), or the `@utility` body for a
73
73
  * typography style.
74
74
  */
75
75
  readonly declarations: readonly CatalogueDeclaration[];
@@ -106,6 +106,7 @@ interface CatalogueToken {
106
106
  /**
107
107
  * Every nxds token, identified by its `--nx-*` name: primitives, runtime
108
108
  * colours, spacing, z-index, breakpoints, and typography and shadow styles.
109
+ * Shadow layer primitives only compose the shadow styles.
109
110
  * Runtime colours are computed from `DEFAULT_NXDS_APPEARANCE` in explicit
110
111
  * light and dark modes; each variant records the appearance it used.
111
112
  */
@@ -2502,10 +2502,33 @@ var color_default = {
2502
2502
  }
2503
2503
  };
2504
2504
 
2505
+ // src/lib/token-scales.generated.ts
2506
+ var PRIMITIVE_PALETTE_NAMES = [
2507
+ "green",
2508
+ "emerald",
2509
+ "teal",
2510
+ "cyan",
2511
+ "sky",
2512
+ "indigo",
2513
+ "violet",
2514
+ "purple",
2515
+ "fuchsia",
2516
+ "pink",
2517
+ "slate",
2518
+ "rose",
2519
+ "lime",
2520
+ "yellow",
2521
+ "blue",
2522
+ "gray",
2523
+ "zinc",
2524
+ "neutral",
2525
+ "stone",
2526
+ "red",
2527
+ "orange",
2528
+ "amber"
2529
+ ];
2530
+
2505
2531
  // src/lib/primitive-palette.ts
2506
- var PRIMITIVE_PALETTE_NAMES = Object.keys(color_default).filter(
2507
- (name) => name !== "white" && name !== "black"
2508
- );
2509
2532
  var rampCache = /* @__PURE__ */ new Map();
2510
2533
  function getPaletteRamp(palette) {
2511
2534
  if (!PRIMITIVE_PALETTE_NAMES.includes(palette)) {
@@ -3168,6 +3191,15 @@ function formatShadowStyle(tokenPath, value, primitiveMap) {
3168
3191
  const isInset = tokenPath.length === 1 && tokenPath[0] === "inner";
3169
3192
  return formatShadowComposite(value, primitiveMap, isInset);
3170
3193
  }
3194
+ function inlineVariables(value, values) {
3195
+ return value.replace(/var\((--[\w-]+)\)/g, (reference, name) => {
3196
+ const literal = values.get(name);
3197
+ if (literal === void 0) {
3198
+ throw new Error(`inlineVariables: ${reference} has no value`);
3199
+ }
3200
+ return literal;
3201
+ });
3202
+ }
3171
3203
  var TYPOGRAPHY_PROPERTIES = [
3172
3204
  ["fontFamily", "font-family"],
3173
3205
  ["fontSize", "font-size"],
@@ -3317,24 +3349,117 @@ function borderColorAliasName(tokenName) {
3317
3349
  }
3318
3350
 
3319
3351
  // src/catalogue/descriptions.ts
3320
- var FOREGROUND_DESCRIPTIONS = Object.fromEntries(
3321
- COLOR_FAMILIES.flatMap((family) => [
3322
- [
3323
- `${family}-foreground`,
3324
- `Foreground on ${family}-background. The surface relationship defines this role, not text alone: text and icons share it, and contrasting control parts or indicators may use it on the same surface. Other pairings require contrast coverage.`
3325
- ],
3326
- [
3327
- `${family}-subtle-foreground`,
3328
- `Foreground on ${family}-subtle. The surface relationship defines this role, not text alone: text and icons share it, and contrasting indicators may use it on that surface. Use on neutral surfaces only with contrast coverage for the intended content tier.`
3329
- ]
3330
- ])
3331
- );
3332
- var RUNTIME_COLOR_DESCRIPTIONS = {
3352
+ var FAMILY_ROLES = {
3353
+ primary: "the main action on a surface",
3354
+ secondary: "a supporting action beside a primary one",
3355
+ success: "a completed or healthy state",
3356
+ warning: "a state that needs attention soon",
3357
+ error: "a failed, invalid or destructive state",
3358
+ information: "neutral guidance or a status update"
3359
+ };
3360
+ var FAMILY_TEMPLATES = {
3361
+ background: (family, role) => `Solid fill for buttons, badges and other strong emphasis in this family. Pair with ${family}-foreground. Marks ${role}.`,
3362
+ "background-hover": (family) => `${family}-background while the pointer is over the control.`,
3363
+ "background-active": (family) => `${family}-background while the control is pressed.`,
3364
+ foreground: (family) => `Foreground on ${family}-background. The surface relationship defines this role, not text alone: text and icons share it, and contrasting control parts or indicators may use it on the same surface. Other pairings require contrast coverage.`,
3365
+ disabled: () => "Fill of a disabled control in this family. Pair with disabled-foreground.",
3366
+ subtle: (family, role) => `Tinted fill for light badges, alerts and selected rows on background or container. Pair with ${family}-subtle-foreground. Marks ${role}.`,
3367
+ "subtle-foreground": (family) => `Foreground on ${family}-subtle. The surface relationship defines this role, not text alone: text and icons share it, and contrasting indicators may use it on that surface. Use on neutral surfaces only with contrast coverage for the intended content tier.`,
3368
+ "subtle-hover": (family) => `${family}-subtle while the pointer is over the control.`,
3369
+ "subtle-active": (family) => `${family}-subtle while the control is pressed.`,
3370
+ border: () => "Border of an outlined control or alert in this family, on background or container.",
3371
+ "border-active": (family) => `${family}-border while the control is pressed or selected.`
3372
+ };
3373
+ function familyRole(name) {
3374
+ for (const family of COLOR_FAMILIES) {
3375
+ if (name === `border-${family}-active`) return [family, "border-active"];
3376
+ if (name.startsWith(`${family}-`)) {
3377
+ return [family, name.slice(family.length + 1)];
3378
+ }
3379
+ }
3380
+ return void 0;
3381
+ }
3382
+ var NEUTRAL_DESCRIPTIONS = {
3383
+ background: "Page background, the base surface everything sits on. Pair with foreground.",
3384
+ "background-hover": "Row or ghost-control hover on background. Pair with foreground.",
3385
+ "background-active": "Row or ghost-control press and selection on background. Pair with foreground.",
3386
+ muted: "Quiet fill for wells, code, skeletons and inactive tracks on background. Pair with muted-foreground.",
3333
3387
  "muted-extralight": "Quietest muted surface \u2014 sits between background and muted for barely-there fills (empty states, subtle panels).",
3388
+ container: "Card and panel surface on background. Pair with container-foreground.",
3389
+ "container-hover": "Row or control hover inside a container.",
3390
+ "container-active": "Row or control press and selection inside a container.",
3391
+ popover: "Surface of menus, popovers, tooltips and dialogs. Pair with popover-foreground.",
3392
+ "popover-hover": "Highlighted menu row inside a popover.",
3393
+ "popover-active": "Pressed or checked menu row inside a popover.",
3394
+ "control-background": "Rail of neutral controls: switch tracks, slider tracks, segmented tabs. Also the hover fill on a neutral control rail.",
3395
+ "control-background-hover": "control-background while the pointer is over it.",
3396
+ "control-thumb": "Thumb of switches and sliders, on control-background.",
3397
+ "nav-background": "Sidebar and navigation surface. Pair with nav-foreground.",
3398
+ "nav-item-hover": "Navigation item hover on nav-background.",
3399
+ "nav-item-active": "Current navigation item on nav-background.",
3400
+ "nav-border": "Border between the sidebar and the page, and inside it.",
3401
+ disabled: "Fill of a disabled neutral control or input. Pair with disabled-foreground.",
3402
+ "border-focus": "Border of a focused input, on background or container.",
3403
+ foreground: "Body text and icons on background, muted and the hover fills.",
3404
+ "container-foreground": "Text and icons on container.",
3405
+ "popover-foreground": "Text and icons on popover and its row fills.",
3406
+ "nav-foreground": "Navigation text and icons on nav-background.",
3334
3407
  "muted-foreground": "It's a gray that softens contrast so primary content stands forward.",
3408
+ "nav-muted-foreground": "Secondary navigation text, such as group labels, on nav-background.",
3335
3409
  "muted-foreground-subtle": "Tertiary text tier below muted-foreground - helper text, captions, divider labels.",
3336
- ...FOREGROUND_DESCRIPTIONS
3410
+ "disabled-foreground": "Text and icons of a disabled control, on disabled and the family disabled fills.",
3411
+ "border-default": "Default border of inputs, cards, tables and separators, on background or container.",
3412
+ "border-disabled": "Border of a disabled control.",
3413
+ "border-hairline": "Faint divider between rows and grouped items.",
3414
+ "chart-categorical-1": "First chart series, on container or background. Series colours stay in order.",
3415
+ "chart-categorical-2": "Second chart series, on container or background.",
3416
+ "chart-categorical-3": "Third chart series, on container or background.",
3417
+ "chart-categorical-4": "Fourth chart series, on container or background.",
3418
+ "chart-categorical-5": "Fifth chart series, on container or background.",
3419
+ "focus-default": "Focus ring of every interactive control, on any surface.",
3420
+ "focus-error": "Focus ring of an invalid control.",
3421
+ "background-hover-alpha": "Translucent hover fill for controls that sit on an image or an unknown surface.",
3422
+ "border-default-alpha": "Translucent border for controls that sit on an image or an unknown surface.",
3423
+ overlay: "Scrim behind dialogs, sheets and drawers.",
3424
+ "popover-alpha": "Translucent popover surface for frosted overlays.",
3425
+ "popover-backdrop": "Backdrop behind a frosted popover."
3337
3426
  };
3427
+ var REGISTRY_NAMES = SEMANTIC_TOKEN_REGISTRY.map(
3428
+ (token2) => token2.name
3429
+ );
3430
+ function familyDescriptions() {
3431
+ const used = /* @__PURE__ */ new Set();
3432
+ const entries = REGISTRY_NAMES.flatMap((name) => {
3433
+ const match = familyRole(name);
3434
+ if (!match) return [];
3435
+ const [family, role] = match;
3436
+ const template = FAMILY_TEMPLATES[role];
3437
+ if (!template) return [];
3438
+ used.add(role);
3439
+ return [[name, template(family, FAMILY_ROLES[family])]];
3440
+ });
3441
+ const unused = Object.keys(FAMILY_TEMPLATES).filter(
3442
+ (role) => !used.has(role)
3443
+ );
3444
+ if (unused.length > 0) {
3445
+ throw new Error(
3446
+ `FAMILY_TEMPLATES describes ${unused.join(", ")}, which no registry colour has.`
3447
+ );
3448
+ }
3449
+ return entries;
3450
+ }
3451
+ function neutralDescriptions() {
3452
+ const unknown = Object.keys(NEUTRAL_DESCRIPTIONS).filter(
3453
+ (name) => !REGISTRY_NAMES.includes(name)
3454
+ );
3455
+ if (unknown.length > 0) {
3456
+ throw new Error(
3457
+ `NEUTRAL_DESCRIPTIONS describes ${unknown.join(", ")}, which the registry doesn't have.`
3458
+ );
3459
+ }
3460
+ return Object.entries(NEUTRAL_DESCRIPTIONS);
3461
+ }
3462
+ var RUNTIME_COLOR_DESCRIPTIONS = Object.fromEntries([...neutralDescriptions(), ...familyDescriptions()]);
3338
3463
 
3339
3464
  // tokens/primitives/borderwidth/borderwidth-fine.json
3340
3465
  var borderwidth_fine_default = {
@@ -11115,21 +11240,46 @@ function typographyStyleEntry(lookup) {
11115
11240
  };
11116
11241
  };
11117
11242
  }
11118
- function shadowStyleEntry(lookup) {
11119
- return ({ leaf }) => {
11243
+ function shadowLayerSets(layers, lookup) {
11244
+ const sets = /* @__PURE__ */ new Map();
11245
+ for (const { preset, mode, leaf } of layers) {
11246
+ const key = `${preset}/${mode}`;
11247
+ const set = sets.get(key) ?? { preset, mode, values: /* @__PURE__ */ new Map() };
11248
+ set.values.set(
11249
+ primitiveName("shadow", leaf.path),
11250
+ resolveValue(leaf.value, lookup, leaf.type, leaf.path)
11251
+ );
11252
+ sets.set(key, set);
11253
+ }
11254
+ return [...sets.values()];
11255
+ }
11256
+ function shadowStyleTokens(layers, lookup) {
11257
+ const sets = shadowLayerSets(layers, lookup);
11258
+ return styleLeaves("shadow", SHADOW_STYLES_FILE).map(({ leaf }) => {
11120
11259
  const key = pathToCssVarPrefixed(leaf.path, "shadow");
11121
- const property = `--${key}`;
11260
+ const name = `--nx-${key}`;
11261
+ const composite = formatShadowStyle(leaf.path, leaf.value, lookup);
11122
11262
  return {
11123
- name: `--nx-${key}`,
11124
- aliases: [cssVariable(property)],
11125
- declarations: [
11126
- {
11127
- property,
11128
- value: formatShadowStyle(leaf.path, leaf.value, lookup)
11129
- }
11130
- ]
11263
+ name,
11264
+ family: "shadow",
11265
+ group: leafGroup("shadow", leaf.path),
11266
+ type: leaf.type,
11267
+ description: leaf.description ?? null,
11268
+ aliases: [cssVariable(`--${key}`)],
11269
+ control: PRESET_CONTROLS.shadow ?? null,
11270
+ variants: sets.map(({ preset, mode, values }) => ({
11271
+ mode,
11272
+ preset,
11273
+ source: { file: SHADOW_STYLES_FILE, path: leaf.path },
11274
+ appearance: null,
11275
+ authoredValue: structuredClone(leaf.value),
11276
+ declarations: [
11277
+ { property: name, value: inlineVariables(composite, values) }
11278
+ ],
11279
+ references: []
11280
+ }))
11131
11281
  };
11132
- };
11282
+ });
11133
11283
  }
11134
11284
  function styleLeaves(family, file) {
11135
11285
  return fileLeaves(family, file, SINGLE_SOURCE).filter(
@@ -11191,8 +11341,13 @@ function runtimeColorTokens() {
11191
11341
  function createTokenCatalogue() {
11192
11342
  const primitives = PRIMITIVE_FAMILIES.flatMap(primitiveLeaves);
11193
11343
  const lookup = primitiveLookup(primitives);
11344
+ const shadowLayers = primitives.filter(({ family }) => family === "shadow");
11194
11345
  return [
11195
- ...authoredTokens(primitives, lookup, primitiveEntry(lookup)),
11346
+ ...authoredTokens(
11347
+ primitives.filter((leaf) => leaf.family !== "shadow"),
11348
+ lookup,
11349
+ primitiveEntry(lookup)
11350
+ ),
11196
11351
  ...runtimeColorTokens(),
11197
11352
  ...authoredTokens(spacingLeaves(), lookup, spacingEntry),
11198
11353
  ...authoredTokens(
@@ -11210,11 +11365,7 @@ function createTokenCatalogue() {
11210
11365
  lookup,
11211
11366
  typographyStyleEntry(lookup)
11212
11367
  ),
11213
- ...authoredTokens(
11214
- styleLeaves("shadow", SHADOW_STYLES_FILE),
11215
- lookup,
11216
- shadowStyleEntry(lookup)
11217
- )
11368
+ ...shadowStyleTokens(shadowLayers, lookup)
11218
11369
  ];
11219
11370
  }
11220
11371
  export {