@cueplusplus/ui 0.21.0 → 0.23.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +1 -1
  3. package/dist/elements/markdown.d.ts +29 -9
  4. package/dist/elements/markdown.js +102 -13
  5. package/dist/forms/_chassis.d.ts +9 -1
  6. package/dist/forms/_chassis.js +11 -3
  7. package/dist/overlays/_surface.d.ts +1 -1
  8. package/dist/styles.css +69 -0
  9. package/dist/system/_paint-stroke-sunken.js +22 -2
  10. package/dist/system/_paint-stroke-surface-1.js +5 -1
  11. package/dist/system/_paint-stroke-surface-2.js +5 -1
  12. package/dist/system/_style-disabled.js +1 -7
  13. package/dist/theming/contrast.d.ts +2 -2
  14. package/dist/theming/contrast.js +2 -2
  15. package/dist/theming/create-theme.js +15 -6
  16. package/dist/theming/index.d.ts +2 -2
  17. package/dist/theming/index.js +2 -2
  18. package/dist/theming/serialize.js +2 -1
  19. package/manifest/components/alert-dialog.json +1 -0
  20. package/manifest/components/autocomplete.json +2 -0
  21. package/manifest/components/button.json +0 -3
  22. package/manifest/components/card.json +1 -0
  23. package/manifest/components/channel-matrix.json +1 -0
  24. package/manifest/components/chart-tooltip-content.json +1 -0
  25. package/manifest/components/checkbox-group.json +0 -3
  26. package/manifest/components/checkbox.json +0 -3
  27. package/manifest/components/color-field.json +1 -0
  28. package/manifest/components/color-picker.json +1 -0
  29. package/manifest/components/combobox.json +2 -0
  30. package/manifest/components/command-palette.json +1 -0
  31. package/manifest/components/composer.json +1 -0
  32. package/manifest/components/context-menu.json +1 -0
  33. package/manifest/components/date-field.json +1 -0
  34. package/manifest/components/date-picker.json +1 -0
  35. package/manifest/components/date-range-picker.json +1 -0
  36. package/manifest/components/dialog.json +1 -0
  37. package/manifest/components/dmx-bar.json +1 -0
  38. package/manifest/components/dmx-strip.json +1 -0
  39. package/manifest/components/drawer.json +1 -0
  40. package/manifest/components/dropdown-menu.json +1 -0
  41. package/manifest/components/env-var-input.json +1 -0
  42. package/manifest/components/hover-card.json +1 -0
  43. package/manifest/components/input-group.json +1 -0
  44. package/manifest/components/input.json +1 -0
  45. package/manifest/components/markdown-text.json +16 -2
  46. package/manifest/components/menubar.json +1 -0
  47. package/manifest/components/multi-select.json +2 -0
  48. package/manifest/components/musical-time-input.json +1 -0
  49. package/manifest/components/navigation-menu.json +1 -0
  50. package/manifest/components/number-field.json +1 -0
  51. package/manifest/components/otp-field.json +1 -0
  52. package/manifest/components/password-input.json +1 -0
  53. package/manifest/components/popover.json +1 -0
  54. package/manifest/components/scrub-input.json +1 -0
  55. package/manifest/components/search-input.json +1 -0
  56. package/manifest/components/select.json +2 -0
  57. package/manifest/components/sheet.json +1 -0
  58. package/manifest/components/switch.json +0 -3
  59. package/manifest/components/tags-input.json +2 -0
  60. package/manifest/components/textarea.json +1 -0
  61. package/manifest/components/theme-configurator.json +1 -0
  62. package/manifest/components/time-field.json +1 -0
  63. package/manifest/components/toast.json +1 -0
  64. package/manifest/components/toggle.json +0 -3
  65. package/manifest/components/tooltip.json +1 -0
  66. package/manifest/manifest.json +49 -49
  67. package/manifest/tokens.json +5 -1
  68. package/package.json +15 -5
@@ -1,5 +1,5 @@
1
1
  import { formatColorString } from "../color/_convert.js";
2
- import { WCAG_AA_NON_TEXT, WCAG_AA_TEXT, contrastRatio, contrastReport } from "./contrast.js";
2
+ import { WCAG_AA_NON_TEXT, WCAG_AA_TEXT, contrastRatio, contrastReport, edgeToContrast } from "./contrast.js";
3
3
  import { RESOLVED_MONO, assertCssValue, assertThemeName, derivedTokens, serializeSystemModeAliases, serializeThemeCss, themeSelector, tokenProperty } from "./serialize.js";
4
4
  import { COLOR_CONTRACT, resolve } from "@cueplusplus/theme-base";
5
5
  import { clampChroma, converter, formatHex, inGamut, parse } from "culori";
@@ -462,7 +462,10 @@ function createTheme(anchors) {
462
462
  if (anchors.radiusScale !== void 0 && !(anchors.radiusScale > 0)) throw new TypeError(`radiusScale must be a positive number, got ${anchors.radiusScale}`);
463
463
  const dark = resolveDark(anchors, preset.dark);
464
464
  const light = anchors.supportsLight ?? preset.light !== null ? resolveLight(dark, preset.light) : null;
465
- const derived = Object.entries(derivedTokens());
465
+ const fieldEdge = (colors) => edgeToContrast(colors["border"], colors["surface-1"], colors["fg"]);
466
+ const derivedFor = (colors) => Object.entries(derivedTokens()).map(([property, value]) => property === tokenProperty("field-edge") ? [property, fieldEdge(colors)] : [property, value]);
467
+ const derived = derivedFor(dark.colors);
468
+ const derivedLight = light === null ? null : derivedFor(light.colors);
466
469
  const fonts = resolveFonts$1(anchors, preset.fonts);
467
470
  const radius = anchors.radiusScale === void 0 ? null : radiusBlocks(name, anchors.radiusScale);
468
471
  const darkPaletteSections = [
@@ -482,7 +485,7 @@ function createTheme(anchors) {
482
485
  }]];
483
486
  const lightSections = light === null ? null : [{ declarations: colorDeclarations(light.colors) }, {
484
487
  comment: DERIVED_COMMENT,
485
- declarations: derived
488
+ declarations: derivedLight ?? derived
486
489
  }];
487
490
  const blocks = [
488
491
  {
@@ -502,10 +505,16 @@ function createTheme(anchors) {
502
505
  ];
503
506
  const inputs = [{
504
507
  mode: "dark",
505
- tokens: dark.colors
508
+ tokens: {
509
+ ...dark.colors,
510
+ "field-edge": fieldEdge(dark.colors)
511
+ }
506
512
  }, ...light === null ? [] : [{
507
513
  mode: "light",
508
- tokens: light.colors,
514
+ tokens: {
515
+ ...light.colors,
516
+ "field-edge": fieldEdge(light.colors)
517
+ },
509
518
  provisional: light.provisional
510
519
  }]];
511
520
  const explicitCss = serializeThemeCss(blocks, { banner: `@cueplusplus/ui — theme "${name}"` }).trimEnd();
@@ -522,7 +531,7 @@ function createTheme(anchors) {
522
531
  sections: lightSections ?? darkPaletteSections
523
532
  }])}\n`,
524
533
  tokens: Object.fromEntries(darkSections.flatMap((section) => section.declarations)),
525
- light: light === null ? null : Object.fromEntries([...colorDeclarations(light.colors), ...derived]),
534
+ light: light === null ? null : Object.fromEntries([...colorDeclarations(light.colors), ...derivedLight ?? derived]),
526
535
  report: contrastReport(inputs)
527
536
  };
528
537
  }
@@ -1,4 +1,4 @@
1
- import { CONTRAST_REQUIREMENTS, ContrastCheck, ContrastInput, ContrastReport, ContrastRequirement, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, contrastRatio, contrastReport, relativeLuminance } from "./contrast.js";
1
+ import { CONTRAST_REQUIREMENTS, ContrastCheck, ContrastInput, ContrastReport, ContrastRequirement, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, contrastRatio, contrastReport, edgeToContrast, relativeLuminance } from "./contrast.js";
2
2
  import { ACCENT_FG_MINIMUM, ACCENT_HOVER_LIGHTNESS_STEP, BORDER_LIGHTNESS_STEPS, CreatedTheme, FG_MUTED_LIGHTNESS_STEP, FG_SUBTLE_LIGHTNESS_STEP, INK_RAMP_CHROMA_SCALE, LIGHT_GROUND_COMPRESSION, SELECTION_ACCENT_PERCENT, SUNKEN_LIGHTNESS_STEP, SURFACE_LIGHTNESS_STEPS, THEME_COLOR_TOKENS, ThemeAnchors, ThemeColorToken, createTheme } from "./create-theme.js";
3
3
  import { CUE_TOKEN_PREFIX, DERIVED_TOKEN_TEMPLATES, RESOLVED_MONO, SerializeThemeCssOptions, THEME_NAME_PATTERN, ThemeBlock, ThemeBlockSection, ThemeSelectorOptions, assertCssValue, assertThemeName, derivedTokens, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty } from "./serialize.js";
4
- export { ACCENT_FG_MINIMUM, ACCENT_HOVER_LIGHTNESS_STEP, BORDER_LIGHTNESS_STEPS, CONTRAST_REQUIREMENTS, CUE_TOKEN_PREFIX, type ContrastCheck, type ContrastInput, type ContrastReport, type ContrastRequirement, type CreatedTheme, DERIVED_TOKEN_TEMPLATES, FG_MUTED_LIGHTNESS_STEP, FG_SUBTLE_LIGHTNESS_STEP, INK_RAMP_CHROMA_SCALE, LIGHT_GROUND_COMPRESSION, RESOLVED_MONO, SELECTION_ACCENT_PERCENT, SUNKEN_LIGHTNESS_STEP, SURFACE_LIGHTNESS_STEPS, type SerializeThemeCssOptions, THEME_COLOR_TOKENS, THEME_NAME_PATTERN, type ThemeAnchors, type ThemeBlock, type ThemeBlockSection, type ThemeColorToken, type ThemeSelectorOptions, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, assertCssValue, assertThemeName, contrastRatio, contrastReport, createTheme, derivedTokens, relativeLuminance, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty };
4
+ export { ACCENT_FG_MINIMUM, ACCENT_HOVER_LIGHTNESS_STEP, BORDER_LIGHTNESS_STEPS, CONTRAST_REQUIREMENTS, CUE_TOKEN_PREFIX, type ContrastCheck, type ContrastInput, type ContrastReport, type ContrastRequirement, type CreatedTheme, DERIVED_TOKEN_TEMPLATES, FG_MUTED_LIGHTNESS_STEP, FG_SUBTLE_LIGHTNESS_STEP, INK_RAMP_CHROMA_SCALE, LIGHT_GROUND_COMPRESSION, RESOLVED_MONO, SELECTION_ACCENT_PERCENT, SUNKEN_LIGHTNESS_STEP, SURFACE_LIGHTNESS_STEPS, type SerializeThemeCssOptions, THEME_COLOR_TOKENS, THEME_NAME_PATTERN, type ThemeAnchors, type ThemeBlock, type ThemeBlockSection, type ThemeColorToken, type ThemeSelectorOptions, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, assertCssValue, assertThemeName, contrastRatio, contrastReport, createTheme, derivedTokens, edgeToContrast, relativeLuminance, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty };
@@ -1,4 +1,4 @@
1
- import { CONTRAST_REQUIREMENTS, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, contrastRatio, contrastReport, relativeLuminance } from "./contrast.js";
1
+ import { CONTRAST_REQUIREMENTS, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, contrastRatio, contrastReport, edgeToContrast, relativeLuminance } from "./contrast.js";
2
2
  import { CUE_TOKEN_PREFIX, DERIVED_TOKEN_TEMPLATES, RESOLVED_MONO, THEME_NAME_PATTERN, assertCssValue, assertThemeName, derivedTokens, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty } from "./serialize.js";
3
3
  import { ACCENT_FG_MINIMUM, ACCENT_HOVER_LIGHTNESS_STEP, BORDER_LIGHTNESS_STEPS, FG_MUTED_LIGHTNESS_STEP, FG_SUBTLE_LIGHTNESS_STEP, INK_RAMP_CHROMA_SCALE, LIGHT_GROUND_COMPRESSION, SELECTION_ACCENT_PERCENT, SUNKEN_LIGHTNESS_STEP, SURFACE_LIGHTNESS_STEPS, THEME_COLOR_TOKENS, createTheme } from "./create-theme.js";
4
- export { ACCENT_FG_MINIMUM, ACCENT_HOVER_LIGHTNESS_STEP, BORDER_LIGHTNESS_STEPS, CONTRAST_REQUIREMENTS, CUE_TOKEN_PREFIX, DERIVED_TOKEN_TEMPLATES, FG_MUTED_LIGHTNESS_STEP, FG_SUBTLE_LIGHTNESS_STEP, INK_RAMP_CHROMA_SCALE, LIGHT_GROUND_COMPRESSION, RESOLVED_MONO, SELECTION_ACCENT_PERCENT, SUNKEN_LIGHTNESS_STEP, SURFACE_LIGHTNESS_STEPS, THEME_COLOR_TOKENS, THEME_NAME_PATTERN, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, assertCssValue, assertThemeName, contrastRatio, contrastReport, createTheme, derivedTokens, relativeLuminance, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty };
4
+ export { ACCENT_FG_MINIMUM, ACCENT_HOVER_LIGHTNESS_STEP, BORDER_LIGHTNESS_STEPS, CONTRAST_REQUIREMENTS, CUE_TOKEN_PREFIX, DERIVED_TOKEN_TEMPLATES, FG_MUTED_LIGHTNESS_STEP, FG_SUBTLE_LIGHTNESS_STEP, INK_RAMP_CHROMA_SCALE, LIGHT_GROUND_COMPRESSION, RESOLVED_MONO, SELECTION_ACCENT_PERCENT, SUNKEN_LIGHTNESS_STEP, SURFACE_LIGHTNESS_STEPS, THEME_COLOR_TOKENS, THEME_NAME_PATTERN, WCAG_AAA_TEXT, WCAG_AA_NON_TEXT, WCAG_AA_TEXT, assertCssValue, assertThemeName, contrastRatio, contrastReport, createTheme, derivedTokens, edgeToContrast, relativeLuminance, serializeThemeBlock, serializeThemeCss, themeSelector, tokenProperty };
@@ -242,7 +242,8 @@ const DERIVED_TOKEN_TEMPLATES = [
242
242
  ["accent-fill", "var(--cue-accent)"],
243
243
  ["accent-fill-fg", "var(--cue-accent-fg)"],
244
244
  ["accent-fill-hover", "var(--cue-accent-hover)"],
245
- ["shade", "var(--cue-fg)"]
245
+ ["shade", "var(--cue-fg)"],
246
+ ["field-edge", "var(--cue-border)"]
246
247
  ];
247
248
  /**
248
249
  * {@link DERIVED_TOKEN_TEMPLATES} as a property → value map.
@@ -172,6 +172,7 @@
172
172
  "--cue-fg",
173
173
  "--cue-fg-muted",
174
174
  "--cue-font-mono",
175
+ "--cue-ground",
175
176
  "--cue-leading-ui",
176
177
  "--cue-paint-rim-width",
177
178
  "--cue-paint-scrim-filter",
@@ -222,6 +222,7 @@
222
222
  "--cue-focus",
223
223
  "--cue-focus-ring",
224
224
  "--cue-font-mono",
225
+ "--cue-ground",
225
226
  "--cue-hair-strong",
226
227
  "--cue-icon-sm",
227
228
  "--cue-info",
@@ -275,6 +276,7 @@
275
276
  "--cue-style-disabled-ink",
276
277
  "--cue-style-disabled-opacity",
277
278
  "--cue-style-display-variation",
279
+ "--cue-style-field-fill",
278
280
  "--cue-style-field-focus-offset",
279
281
  "--cue-style-field-hover-edge",
280
282
  "--cue-style-field-pad",
@@ -124,9 +124,6 @@
124
124
  "--cue-paint-glow-ink-hover",
125
125
  "--cue-paint-rest-shade",
126
126
  "--cue-paint-shadow-scale",
127
- "--cue-paint-stroke-angle",
128
- "--cue-paint-stroke-from",
129
- "--cue-paint-stroke-to",
130
127
  "--cue-radius-control",
131
128
  "--cue-space-4",
132
129
  "--cue-space-5",
@@ -113,6 +113,7 @@
113
113
  "--cue-fg",
114
114
  "--cue-fg-muted",
115
115
  "--cue-font-mono",
116
+ "--cue-ground",
116
117
  "--cue-leading-ui",
117
118
  "--cue-paint-rest-shade",
118
119
  "--cue-paint-rim-ink",
@@ -198,6 +198,7 @@
198
198
  "--cue-focus",
199
199
  "--cue-focus-ring",
200
200
  "--cue-font-mono",
201
+ "--cue-ground",
201
202
  "--cue-leading-ui",
202
203
  "--cue-paint-rim-width",
203
204
  "--cue-paint-scrim-filter",
@@ -100,6 +100,7 @@
100
100
  "--cue-fg-muted",
101
101
  "--cue-fg-subtle",
102
102
  "--cue-font-mono",
103
+ "--cue-ground",
103
104
  "--cue-leading-ui",
104
105
  "--cue-paint-rim-width",
105
106
  "--cue-paint-scrim-filter",
@@ -43,9 +43,6 @@
43
43
  "--cue-icon-sm",
44
44
  "--cue-paint-rest-shade",
45
45
  "--cue-paint-shadow-scale",
46
- "--cue-paint-stroke-angle",
47
- "--cue-paint-stroke-from",
48
- "--cue-paint-stroke-to",
49
46
  "--cue-radius-control",
50
47
  "--cue-radius-scale",
51
48
  "--cue-space-2",
@@ -68,9 +68,6 @@
68
68
  "--cue-icon-sm",
69
69
  "--cue-paint-rest-shade",
70
70
  "--cue-paint-shadow-scale",
71
- "--cue-paint-stroke-angle",
72
- "--cue-paint-stroke-from",
73
- "--cue-paint-stroke-to",
74
71
  "--cue-radius-control",
75
72
  "--cue-radius-scale",
76
73
  "--cue-space-2",
@@ -89,6 +89,7 @@
89
89
  "--cue-style-disabled-fill",
90
90
  "--cue-style-disabled-ink",
91
91
  "--cue-style-disabled-opacity",
92
+ "--cue-style-field-fill",
92
93
  "--cue-style-field-focus-offset",
93
94
  "--cue-style-field-hover-edge",
94
95
  "--cue-style-field-pad",
@@ -223,6 +223,7 @@
223
223
  "--cue-style-disabled-fill",
224
224
  "--cue-style-disabled-ink",
225
225
  "--cue-style-disabled-opacity",
226
+ "--cue-style-field-fill",
226
227
  "--cue-style-field-focus-offset",
227
228
  "--cue-style-field-hover-edge",
228
229
  "--cue-style-field-pad",
@@ -224,6 +224,7 @@
224
224
  "--cue-focus",
225
225
  "--cue-focus-ring",
226
226
  "--cue-font-mono",
227
+ "--cue-ground",
227
228
  "--cue-hair-strong",
228
229
  "--cue-icon-md",
229
230
  "--cue-icon-sm",
@@ -278,6 +279,7 @@
278
279
  "--cue-style-disabled-ink",
279
280
  "--cue-style-disabled-opacity",
280
281
  "--cue-style-display-variation",
282
+ "--cue-style-field-fill",
281
283
  "--cue-style-field-focus-offset",
282
284
  "--cue-style-field-hover-edge",
283
285
  "--cue-style-field-pad",
@@ -159,6 +159,7 @@
159
159
  "--cue-fg-muted",
160
160
  "--cue-fg-subtle",
161
161
  "--cue-font-mono",
162
+ "--cue-ground",
162
163
  "--cue-icon-md",
163
164
  "--cue-icon-sm",
164
165
  "--cue-leading-ui",
@@ -225,6 +225,7 @@
225
225
  "--cue-style-disabled-fill",
226
226
  "--cue-style-disabled-ink",
227
227
  "--cue-style-disabled-opacity",
228
+ "--cue-style-field-fill",
228
229
  "--cue-style-field-focus-offset",
229
230
  "--cue-style-field-hover-edge",
230
231
  "--cue-style-field-pad",
@@ -93,6 +93,7 @@
93
93
  "--cue-fg",
94
94
  "--cue-fg-muted",
95
95
  "--cue-font-mono",
96
+ "--cue-ground",
96
97
  "--cue-leading-ui",
97
98
  "--cue-paint-rim-width",
98
99
  "--cue-paint-scrim-filter",
@@ -80,6 +80,7 @@
80
80
  "--cue-style-disabled-fill",
81
81
  "--cue-style-disabled-ink",
82
82
  "--cue-style-disabled-opacity",
83
+ "--cue-style-field-fill",
83
84
  "--cue-style-field-focus-offset",
84
85
  "--cue-style-field-hover-edge",
85
86
  "--cue-style-field-pad",
@@ -243,6 +243,7 @@
243
243
  "--cue-style-disabled-fill",
244
244
  "--cue-style-disabled-ink",
245
245
  "--cue-style-disabled-opacity",
246
+ "--cue-style-field-fill",
246
247
  "--cue-style-field-focus-offset",
247
248
  "--cue-style-field-hover-edge",
248
249
  "--cue-style-field-pad",
@@ -243,6 +243,7 @@
243
243
  "--cue-style-disabled-fill",
244
244
  "--cue-style-disabled-ink",
245
245
  "--cue-style-disabled-opacity",
246
+ "--cue-style-field-fill",
246
247
  "--cue-style-field-focus-offset",
247
248
  "--cue-style-field-hover-edge",
248
249
  "--cue-style-field-pad",
@@ -167,6 +167,7 @@
167
167
  "--cue-fg",
168
168
  "--cue-fg-muted",
169
169
  "--cue-font-mono",
170
+ "--cue-ground",
170
171
  "--cue-leading-ui",
171
172
  "--cue-paint-rim-width",
172
173
  "--cue-paint-scrim-filter",
@@ -65,6 +65,7 @@
65
65
  "--cue-fg",
66
66
  "--cue-fg-muted",
67
67
  "--cue-font-mono",
68
+ "--cue-ground",
68
69
  "--cue-leading-ui",
69
70
  "--cue-paint-rim-width",
70
71
  "--cue-paint-scrim-filter",
@@ -75,6 +75,7 @@
75
75
  "--cue-fg",
76
76
  "--cue-fg-muted",
77
77
  "--cue-font-mono",
78
+ "--cue-ground",
78
79
  "--cue-leading-ui",
79
80
  "--cue-paint-rim-width",
80
81
  "--cue-paint-scrim-filter",
@@ -161,6 +161,7 @@
161
161
  "--cue-fg",
162
162
  "--cue-fg-muted",
163
163
  "--cue-font-mono",
164
+ "--cue-ground",
164
165
  "--cue-leading-ui",
165
166
  "--cue-paint-rim-width",
166
167
  "--cue-paint-scrim-filter",
@@ -222,6 +222,7 @@
222
222
  "--cue-fg-muted",
223
223
  "--cue-fg-subtle",
224
224
  "--cue-font-mono",
225
+ "--cue-ground",
225
226
  "--cue-icon-sm",
226
227
  "--cue-leading-ui",
227
228
  "--cue-paint-rim-width",
@@ -180,6 +180,7 @@
180
180
  "--cue-style-disabled-fill",
181
181
  "--cue-style-disabled-ink",
182
182
  "--cue-style-disabled-opacity",
183
+ "--cue-style-field-fill",
183
184
  "--cue-style-field-focus-offset",
184
185
  "--cue-style-field-hover-edge",
185
186
  "--cue-style-field-pad",
@@ -147,6 +147,7 @@
147
147
  "--cue-fg",
148
148
  "--cue-fg-muted",
149
149
  "--cue-font-mono",
150
+ "--cue-ground",
150
151
  "--cue-leading-ui",
151
152
  "--cue-paint-rim-width",
152
153
  "--cue-paint-scrim-filter",
@@ -100,6 +100,7 @@
100
100
  "--cue-style-disabled-fill",
101
101
  "--cue-style-disabled-ink",
102
102
  "--cue-style-disabled-opacity",
103
+ "--cue-style-field-fill",
103
104
  "--cue-style-field-focus-offset",
104
105
  "--cue-style-field-hover-edge",
105
106
  "--cue-style-field-pad",
@@ -96,6 +96,7 @@
96
96
  "--cue-style-disabled-fill",
97
97
  "--cue-style-disabled-ink",
98
98
  "--cue-style-disabled-opacity",
99
+ "--cue-style-field-fill",
99
100
  "--cue-style-field-focus-offset",
100
101
  "--cue-style-field-hover-edge",
101
102
  "--cue-style-field-pad",
@@ -4,11 +4,13 @@
4
4
  "group": "elements",
5
5
  "importPath": "@cueplusplus/ui/elements/markdown",
6
6
  "peerDependencies": [
7
+ "mdast-util-gfm-table",
8
+ "micromark-extension-gfm-table",
7
9
  "react-markdown",
8
10
  "rehype-sanitize"
9
11
  ],
10
12
  "clientOnly": true,
11
- "description": "Model output, rendered.\n\nThe one component in this library that turns a string into markup, and the\nonly one that has to be argued for rather than described. Everywhere else —\n`Message`, `AskBox`, every element in this group — text is text: a string\narrives from a model and is placed in the DOM as characters, because a\ncomponent that quietly parsed it would put every consumer of this library one\nprompt away from an injection. This one parses, so it states in full what it\nwill and will not do with what it is given.\n\n**Threat model.** The input is hostile. Assume the string was written by a\nmodel that was told to write it by a web page it fetched, a file it read, or\na tool result it did not verify — the practical shape of prompt injection is\nnot \"the model turned evil\", it is \"the model faithfully relayed an\nattacker's bytes\". Three things follow.\n\n- **No raw HTML, ever, and not by filtering it.** Markup in the source has no\n path to the DOM, and the first reason is an absence rather than a setting.\n `react-markdown` hands `remark-rehype` its own `allowDangerousHtml: true`\n and spreads it *over* whatever `remarkRehypeOptions` says, so the option\n cannot be turned off from here and `<img onerror=…>` does become a `raw`\n node. A `raw` node is a span of source text rather than an element, and the\n one thing that turns it into markup is `rehype-raw`. Nothing in this package\n depends on that plugin, and a test asserts it never will — so the string has\n no parser to reach. `rehype-sanitize` then drops the `raw` type outright,\n and react-markdown's own `skipHtml` removes whatever is left. Three gates,\n none of which is a deny-list of dangerous tags. A `<script>`, an\n `<iframe>`, an `<svg>` and an `onclick=` are all the same non-event: there\n is nothing in the tree for them to be.\n- **Attributes are enumerated, not filtered.** An element that is not in the\n schema renders nothing; an element that is renders only the attributes\n named beside it — `href`/`title` on a link, `src`/`alt`/`title` on an\n image, `language-…` on a `code`. No element in the subset accepts `id`,\n `style`, `srcset`, `formaction` or any `on*` handler, so none of them has\n an attribute to arrive on.\n- **URLs are allow-listed twice.** `http`, `https` and `mailto` on both\n `href` and `src`; a relative URL stays relative; everything else — a\n `javascript:` link, a `data:text/html` image, `vbscript:`, `blob:`,\n `file:`, `//host` — loses the attribute and leaves an inert element\n behind. Every link also carries `rel=\"noopener noreferrer nofollow\"`,\n which is not a prop: reverse tabnabbing, referrer leakage of a private\n console URL, and SEO laundering through a transcript are all things a\n caller should not be able to turn off by accident.\n\n**The subset.** Paragraphs, ATX and setext headings, bullet and ordered\nlists, block quotes, thematic breaks, fenced and indented code, inline code,\nemphasis, strong, strikethrough, links, images, and hard breaks. No GFM\nplugin is enabled, so no tables, task lists, footnotes or autolink literals —\nan explicit `<https://…>` autolink still works. Fenced blocks are plain text\nunless {@link MarkdownTextProps.renderCodeBlock} is given.\n\n**Streaming.** Pass `streaming` while the turn is arriving and the token the\nmodel is halfway through typing is hidden rather than rendered as\npunctuation: no asterisks flickering through every bold run, no half-written\nURL, no fence that opens a code block one frame and closes it the next. The\nwords appear as they arrive; only their formatting waits for the closing\ntoken.\n\n`react-markdown` and `rehype-sanitize` are optional peers of this subpath\nalone, which is why this component is not re-exported from\n`@cueplusplus/ui/elements`: a console that renders a transcript without\nmarkdown should install neither.",
13
+ "description": "Model output, rendered.\n\nThe one component in this library that turns a string into markup, and the\nonly one that has to be argued for rather than described. Everywhere else —\n`Message`, `AskBox`, every element in this group — text is text: a string\narrives from a model and is placed in the DOM as characters, because a\ncomponent that quietly parsed it would put every consumer of this library one\nprompt away from an injection. This one parses, so it states in full what it\nwill and will not do with what it is given.\n\n**Threat model.** The input is hostile. Assume the string was written by a\nmodel that was told to write it by a web page it fetched, a file it read, or\na tool result it did not verify — the practical shape of prompt injection is\nnot \"the model turned evil\", it is \"the model faithfully relayed an\nattacker's bytes\". Three things follow.\n\n- **No raw HTML, ever, and not by filtering it.** Markup in the source has no\n path to the DOM, and the first reason is an absence rather than a setting.\n `react-markdown` hands `remark-rehype` its own `allowDangerousHtml: true`\n and spreads it *over* whatever `remarkRehypeOptions` says, so the option\n cannot be turned off from here and `<img onerror=…>` does become a `raw`\n node. A `raw` node is a span of source text rather than an element, and the\n one thing that turns it into markup is `rehype-raw`. Nothing in this package\n depends on that plugin, and a test asserts it never will — so the string has\n no parser to reach. `rehype-sanitize` then drops the `raw` type outright,\n and react-markdown's own `skipHtml` removes whatever is left. Three gates,\n none of which is a deny-list of dangerous tags. A `<script>`, an\n `<iframe>`, an `<svg>` and an `onclick=` are all the same non-event: there\n is nothing in the tree for them to be.\n- **Attributes are enumerated, not filtered.** An element that is not in the\n schema renders nothing; an element that is renders only the attributes\n named beside it — `href`/`title` on a link, `src`/`alt`/`title` on an\n image, `language-…` on a `code`, and `align` on a table cell, held to\n `left`, `center` or `right`. No element in the subset accepts `id`,\n `style`, `srcset`, `formaction` or any `on*` handler, so none of them has\n an attribute to arrive on; the one inline style anything carries is a\n cell's `text-align`, which the renderer writes from that `align`.\n- **URLs are allow-listed twice.** `http`, `https` and `mailto` on both\n `href` and `src`; a relative URL stays relative; everything else — a\n `javascript:` link, a `data:text/html` image, `vbscript:`, `blob:`,\n `file:`, `//host` — loses the attribute and leaves an inert element\n behind. Every link also carries `rel=\"noopener noreferrer nofollow\"`,\n which is not a prop: reverse tabnabbing, referrer leakage of a private\n console URL, and SEO laundering through a transcript are all things a\n caller should not be able to turn off by accident.\n\n**The subset.** Paragraphs, ATX and setext headings, bullet and ordered\nlists, block quotes, thematic breaks, fenced and indented code, inline code,\nemphasis, strong, strikethrough, links, images, hard breaks, and GitHub\ntables. Tables are the one part of GFM the parser reads, each column aligned\nas its delimiter row says and wrapped in a named region that scrolls\nsideways; task lists, footnotes and autolink literals stay out — an explicit\n`<https://…>` autolink still works. Fenced blocks are plain text unless\n{@link MarkdownTextProps.renderCodeBlock} is given, and\n{@link MarkdownTextProps.remarkPlugins} adds parser plugins without widening\nthe subset.\n\n**Streaming.** Pass `streaming` while the turn is arriving and the token the\nmodel is halfway through typing is hidden rather than rendered as\npunctuation: no asterisks flickering through every bold run, no half-written\nURL, no fence that opens a code block one frame and closes it the next. The\nwords appear as they arrive; only their formatting waits for the closing\ntoken.\n\n`react-markdown`, `rehype-sanitize` and GFM's table pair\n(`micromark-extension-gfm-table`, `mdast-util-gfm-table`) are optional peers\nof this subpath alone, which is why this component is not re-exported from\n`@cueplusplus/ui/elements`: a console that renders a transcript without\nmarkdown should install none of them.",
12
14
  "props": [
13
15
  {
14
16
  "name": "children",
@@ -71,6 +73,17 @@
71
73
  "kind": "callback",
72
74
  "fixture": "callback.log"
73
75
  }
76
+ },
77
+ {
78
+ "name": "remarkPlugins",
79
+ "type": "PluggableList | null",
80
+ "required": false,
81
+ "defaultValue": null,
82
+ "description": "More remark plugins, run after the component's own table syntax.\n\nA seam for the parser, not for the page: whatever a plugin adds to the\ntree still passes the same sanitizer, so a plugin can change what the\nmarkdown *means* — a mention syntax, a glossary link — but cannot widen\nwhat renders. An element outside the subset is dropped, and an attribute\nthe schema does not name never arrives.",
83
+ "control": {
84
+ "kind": "opaque",
85
+ "nullable": true
86
+ }
74
87
  }
75
88
  ],
76
89
  "typeReferences": [
@@ -95,6 +108,7 @@
95
108
  "--cue-space-3",
96
109
  "--cue-space-5",
97
110
  "--cue-style-focus-width",
111
+ "--cue-surface-2",
98
112
  "--cue-text-body",
99
113
  "--cue-text-emphasis",
100
114
  "--cue-text-label",
@@ -105,7 +119,7 @@
105
119
  "examples": [
106
120
  {
107
121
  "title": "Usage",
108
- "code": "<Message agent=\"researcher\">\n <MarkdownText>{turn.text}</MarkdownText>\n</Message>\n<MarkdownText streaming={turn.status === \"running\"}>{turn.text}</MarkdownText>\n<MarkdownText renderCodeBlock={({ language, code }) => <Highlight lang={language} code={code} />}>\n {answer}\n</MarkdownText>",
122
+ "code": "<Message agent=\"researcher\">\n <MarkdownText>{turn.text}</MarkdownText>\n</Message>\n<MarkdownText streaming={turn.status === \"running\"}>{turn.text}</MarkdownText>\n<MarkdownText renderCodeBlock={({ language, code }) => <Highlight lang={language} code={code} />}>\n {answer}\n</MarkdownText>\n<MarkdownText remarkPlugins={[remarkMentions]}>{turn.text}</MarkdownText>",
109
123
  "language": "tsx"
110
124
  }
111
125
  ],
@@ -143,6 +143,7 @@
143
143
  "--cue-focus",
144
144
  "--cue-focus-ring",
145
145
  "--cue-font-mono",
146
+ "--cue-ground",
146
147
  "--cue-leading-ui",
147
148
  "--cue-paint-rim-width",
148
149
  "--cue-paint-scrim-filter",
@@ -215,6 +215,7 @@
215
215
  "--cue-focus",
216
216
  "--cue-focus-ring",
217
217
  "--cue-font-mono",
218
+ "--cue-ground",
218
219
  "--cue-hair-strong",
219
220
  "--cue-icon-sm",
220
221
  "--cue-info",
@@ -268,6 +269,7 @@
268
269
  "--cue-style-disabled-ink",
269
270
  "--cue-style-disabled-opacity",
270
271
  "--cue-style-display-variation",
272
+ "--cue-style-field-fill",
271
273
  "--cue-style-field-focus-offset",
272
274
  "--cue-style-field-hover-edge",
273
275
  "--cue-style-field-pad",
@@ -128,6 +128,7 @@
128
128
  "--cue-style-disabled-fill",
129
129
  "--cue-style-disabled-ink",
130
130
  "--cue-style-disabled-opacity",
131
+ "--cue-style-field-fill",
131
132
  "--cue-style-field-focus-offset",
132
133
  "--cue-style-field-hover-edge",
133
134
  "--cue-style-field-pad",
@@ -229,6 +229,7 @@
229
229
  "--cue-focus",
230
230
  "--cue-focus-ring",
231
231
  "--cue-font-mono",
232
+ "--cue-ground",
232
233
  "--cue-icon-sm",
233
234
  "--cue-leading-ui",
234
235
  "--cue-paint-rim-width",
@@ -117,6 +117,7 @@
117
117
  "--cue-style-disabled-fill",
118
118
  "--cue-style-disabled-ink",
119
119
  "--cue-style-disabled-opacity",
120
+ "--cue-style-field-fill",
120
121
  "--cue-style-field-focus-offset",
121
122
  "--cue-style-field-hover-edge",
122
123
  "--cue-style-field-pad",
@@ -150,6 +150,7 @@
150
150
  "--cue-style-disabled-fill",
151
151
  "--cue-style-disabled-ink",
152
152
  "--cue-style-disabled-opacity",
153
+ "--cue-style-field-fill",
153
154
  "--cue-style-field-focus-offset",
154
155
  "--cue-style-field-hover-edge",
155
156
  "--cue-style-field-pad",
@@ -158,6 +158,7 @@
158
158
  "--cue-style-disabled-fill",
159
159
  "--cue-style-disabled-ink",
160
160
  "--cue-style-disabled-opacity",
161
+ "--cue-style-field-fill",
161
162
  "--cue-style-field-focus-offset",
162
163
  "--cue-style-field-hover-edge",
163
164
  "--cue-style-field-pad",
@@ -177,6 +177,7 @@
177
177
  "--cue-fg",
178
178
  "--cue-fg-muted",
179
179
  "--cue-font-mono",
180
+ "--cue-ground",
180
181
  "--cue-leading-ui",
181
182
  "--cue-paint-rim-width",
182
183
  "--cue-paint-scrim-filter",
@@ -244,6 +244,7 @@
244
244
  "--cue-style-disabled-fill",
245
245
  "--cue-style-disabled-ink",
246
246
  "--cue-style-disabled-opacity",
247
+ "--cue-style-field-fill",
247
248
  "--cue-style-field-focus-offset",
248
249
  "--cue-style-field-hover-edge",
249
250
  "--cue-style-field-pad",
@@ -182,6 +182,7 @@
182
182
  "--cue-style-disabled-fill",
183
183
  "--cue-style-disabled-ink",
184
184
  "--cue-style-disabled-opacity",
185
+ "--cue-style-field-fill",
185
186
  "--cue-style-field-focus-offset",
186
187
  "--cue-style-field-hover-edge",
187
188
  "--cue-style-field-pad",
@@ -202,6 +202,7 @@
202
202
  "--cue-focus",
203
203
  "--cue-focus-ring",
204
204
  "--cue-font-mono",
205
+ "--cue-ground",
205
206
  "--cue-icon-md",
206
207
  "--cue-icon-sm",
207
208
  "--cue-paint-rest-shade",
@@ -235,6 +236,7 @@
235
236
  "--cue-style-disabled-fill",
236
237
  "--cue-style-disabled-ink",
237
238
  "--cue-style-disabled-opacity",
239
+ "--cue-style-field-fill",
238
240
  "--cue-style-field-focus-offset",
239
241
  "--cue-style-field-hover-edge",
240
242
  "--cue-style-field-pad",
@@ -167,6 +167,7 @@
167
167
  "--cue-fg",
168
168
  "--cue-fg-muted",
169
169
  "--cue-font-mono",
170
+ "--cue-ground",
170
171
  "--cue-leading-ui",
171
172
  "--cue-paint-rim-width",
172
173
  "--cue-paint-scrim-filter",
@@ -65,9 +65,6 @@
65
65
  "--cue-focus",
66
66
  "--cue-focus-ring",
67
67
  "--cue-font-mono",
68
- "--cue-paint-stroke-angle",
69
- "--cue-paint-stroke-from",
70
- "--cue-paint-stroke-to",
71
68
  "--cue-space-3",
72
69
  "--cue-style-body-weight",
73
70
  "--cue-style-check-edge",
@@ -215,6 +215,7 @@
215
215
  "--cue-focus",
216
216
  "--cue-focus-ring",
217
217
  "--cue-font-mono",
218
+ "--cue-ground",
218
219
  "--cue-hair-strong",
219
220
  "--cue-icon-sm",
220
221
  "--cue-info",
@@ -268,6 +269,7 @@
268
269
  "--cue-style-disabled-ink",
269
270
  "--cue-style-disabled-opacity",
270
271
  "--cue-style-display-variation",
272
+ "--cue-style-field-fill",
271
273
  "--cue-style-field-focus-offset",
272
274
  "--cue-style-field-hover-edge",
273
275
  "--cue-style-field-pad",
@@ -92,6 +92,7 @@
92
92
  "--cue-style-disabled-fill",
93
93
  "--cue-style-disabled-ink",
94
94
  "--cue-style-disabled-opacity",
95
+ "--cue-style-field-fill",
95
96
  "--cue-style-field-focus-offset",
96
97
  "--cue-style-field-hover-edge",
97
98
  "--cue-style-field-pad",
@@ -127,6 +127,7 @@
127
127
  "--cue-fg-subtle",
128
128
  "--cue-font-mono",
129
129
  "--cue-font-sans",
130
+ "--cue-ground",
130
131
  "--cue-icon-sm",
131
132
  "--cue-leading-ui",
132
133
  "--cue-paint-rim-width",
@@ -80,6 +80,7 @@
80
80
  "--cue-style-disabled-fill",
81
81
  "--cue-style-disabled-ink",
82
82
  "--cue-style-disabled-opacity",
83
+ "--cue-style-field-fill",
83
84
  "--cue-style-field-focus-offset",
84
85
  "--cue-style-field-hover-edge",
85
86
  "--cue-style-field-pad",
@@ -78,6 +78,7 @@
78
78
  "--cue-focus",
79
79
  "--cue-focus-ring",
80
80
  "--cue-font-mono",
81
+ "--cue-ground",
81
82
  "--cue-icon-md",
82
83
  "--cue-icon-sm",
83
84
  "--cue-info",
@@ -103,9 +103,6 @@
103
103
  "--cue-font-mono",
104
104
  "--cue-icon-md",
105
105
  "--cue-icon-sm",
106
- "--cue-paint-stroke-angle",
107
- "--cue-paint-stroke-from",
108
- "--cue-paint-stroke-to",
109
106
  "--cue-radius-control",
110
107
  "--cue-space-3",
111
108
  "--cue-space-4",
@@ -146,6 +146,7 @@
146
146
  "--cue-fg",
147
147
  "--cue-fg-muted",
148
148
  "--cue-font-mono",
149
+ "--cue-ground",
149
150
  "--cue-leading-ui",
150
151
  "--cue-paint-rim-width",
151
152
  "--cue-paint-scrim-filter",