@astryxdesign/core 0.7.1-canary.e897146 → 0.7.1-canary.f2beffa

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 (72) hide show
  1. package/dist/Button/Button.d.ts +1 -1
  2. package/dist/Button/Button.d.ts.map +1 -1
  3. package/dist/Button/Button.js +5 -2
  4. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  5. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  6. package/dist/CodeBlock/CodeBlock.js +133 -22
  7. package/dist/CodeBlock/tokenizer.d.ts +39 -0
  8. package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
  9. package/dist/CodeBlock/tokenizer.js +108 -0
  10. package/dist/Dialog/Dialog.d.ts +1 -1
  11. package/dist/Dialog/Dialog.d.ts.map +1 -1
  12. package/dist/Dialog/Dialog.js +16 -5
  13. package/dist/Dialog/DialogHeader.d.ts +1 -1
  14. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  15. package/dist/Dialog/DialogHeader.js +7 -7
  16. package/dist/InputGroup/InputGroup.d.ts +2 -4
  17. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  18. package/dist/InputGroup/InputGroup.js +2 -4
  19. package/dist/InputGroup/groupStyles.d.ts +10 -2
  20. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  21. package/dist/InputGroup/groupStyles.js +19 -2
  22. package/dist/Markdown/Markdown.d.ts.map +1 -1
  23. package/dist/Markdown/Markdown.js +19 -3
  24. package/dist/astryx.css +19 -0
  25. package/dist/theme/syntax/SyntaxTheme.d.ts.map +1 -1
  26. package/dist/theme/syntax/SyntaxTheme.js +43 -2
  27. package/dist/theme/syntax/defineSyntaxTheme.d.ts +18 -5
  28. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  29. package/dist/theme/syntax/defineSyntaxTheme.js +38 -9
  30. package/dist/theme/syntax/index.d.ts +1 -1
  31. package/dist/theme/syntax/index.d.ts.map +1 -1
  32. package/dist/theme/syntax/tokens.d.ts +12 -2
  33. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  34. package/dist/theme/syntax/tokens.js +25 -4
  35. package/package.json +3 -3
  36. package/src/Button/Button.test.tsx +37 -0
  37. package/src/Button/Button.tsx +5 -1
  38. package/src/CodeBlock/CodeBlock.doc.mjs +7 -0
  39. package/src/CodeBlock/CodeBlock.spec.md +12 -12
  40. package/src/CodeBlock/CodeBlock.test.tsx +78 -0
  41. package/src/CodeBlock/CodeBlock.tsx +176 -7
  42. package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +93 -0
  43. package/src/CodeBlock/tokenizer.test.ts +112 -0
  44. package/src/CodeBlock/tokenizer.ts +106 -0
  45. package/src/Dialog/Dialog.test.tsx +27 -1
  46. package/src/Dialog/Dialog.tsx +16 -5
  47. package/src/Dialog/DialogHeader.test.tsx +27 -2
  48. package/src/Dialog/DialogHeader.tsx +7 -8
  49. package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +21 -14
  50. package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +21 -14
  51. package/src/InputGroup/InputGroup.doc.mjs +11 -1
  52. package/src/InputGroup/InputGroup.tsx +2 -4
  53. package/src/InputGroup/groupStyles.ts +40 -2
  54. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +142 -0
  55. package/src/Link/__tests__/Link.a11y.renders.tsx +97 -0
  56. package/src/Link/__tests__/Link.a11y.states.ts +104 -0
  57. package/src/Link/__tests__/Link.a11y.test.tsx +127 -0
  58. package/src/Markdown/Markdown.spec.md +3 -3
  59. package/src/Markdown/Markdown.test.tsx +38 -0
  60. package/src/Markdown/Markdown.tsx +20 -2
  61. package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +22 -15
  62. package/src/Selector/Selector.spec.md +23 -13
  63. package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +25 -18
  64. package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +19 -12
  65. package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +21 -14
  66. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +18 -11
  67. package/src/theme/syntax/SyntaxTheme.tsx +46 -5
  68. package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +91 -0
  69. package/src/theme/syntax/defineSyntaxTheme.ts +75 -15
  70. package/src/theme/syntax/index.ts +5 -1
  71. package/src/theme/syntax/tokens.ts +32 -2
  72. package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +40 -0
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file Button.tsx
3
- * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator)
3
+ * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator), group contexts
4
4
  * @output Exports Button component, ButtonProps, ButtonVariant types
5
5
  * @position Core implementation; consumed by index.ts, tested by Button.test.tsx
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file Button.tsx
7
- * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator)
7
+ * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator), group contexts
8
8
  * @output Exports Button component, ButtonProps, ButtonVariant types
9
9
  * @position Core implementation; consumed by index.ts, tested by Button.test.tsx
10
10
  *
@@ -29,6 +29,8 @@ import { iconBoxSizeStyles } from "../Icon/IconSize.stylex.js";
29
29
  import { EDGE_COMP_ATTR } from "../Layout/edgeCompensation.stylex.js";
30
30
  import { useSize } from "../SizeContext/SizeContext.js";
31
31
  import { useButtonGroup } from "../ButtonGroup/ButtonGroupContext.js";
32
+ import { useInputGroup } from "../InputGroup/InputGroupContext.js";
33
+ import { groupStyles as inputGroupStyles } from "../InputGroup/groupStyles.js";
32
34
  import { mergeProps } from "../utils/index.js";
33
35
  import { useMergedRefs } from "../hooks/useMergedRefs.js";
34
36
  import { useLinkComponent } from "../Link/useLinkComponent.js";
@@ -347,6 +349,7 @@ export function Button({
347
349
  const t = useTranslator();
348
350
  const size = useSize(sizeProp, 'md');
349
351
  const buttonGroup = useButtonGroup();
352
+ const inputGroup = useInputGroup();
350
353
  const [isPending, startTransition] = useTransition();
351
354
  // clickAction is normally fire-once (submit/save/pay), so a same-tick
352
355
  // double-click must dedupe — which neither isPending nor useOptimistic do.
@@ -428,7 +431,7 @@ export function Button({
428
431
  } : null;
429
432
 
430
433
  // Shared StyleX props for both button and link rendering
431
- const sharedStylexProps = focusOutlineProps.focusVisible(styles.base, sizeStyles[size], isIconOnly && styles.iconOnly, interactionOverlayStyles.backgroundImage, buttonDisabled && styles.inactive, visuallyDisabled && styles.disabled, useAriaDisabled && styles.ariaDisabled, renderAsLink && styles.link, !buttonGroup && styles.pressable, buttonGroup && (buttonGroup.orientation === 'horizontal' ? groupStyles.horizontal : groupStyles.vertical), buttonGroup && (variant === 'primary' || variant === 'destructive') && (buttonGroup.orientation === 'horizontal' ? groupStyles.onSolidHorizontal : groupStyles.onSolidVertical),
434
+ const sharedStylexProps = focusOutlineProps.focusVisible(styles.base, sizeStyles[size], isIconOnly && styles.iconOnly, interactionOverlayStyles.backgroundImage, buttonDisabled && styles.inactive, visuallyDisabled && styles.disabled, useAriaDisabled && styles.ariaDisabled, renderAsLink && styles.link, !buttonGroup && styles.pressable, buttonGroup && (buttonGroup.orientation === 'horizontal' ? groupStyles.horizontal : groupStyles.vertical), inputGroup != null && buttonGroup == null && inputGroupStyles.buttonAddon, buttonGroup && (variant === 'primary' || variant === 'destructive') && (buttonGroup.orientation === 'horizontal' ? groupStyles.onSolidHorizontal : groupStyles.onSolidVertical),
432
435
  // Standalone floating buttons only — a grouped button's elevation is owned
433
436
  // by the ButtonGroup so the shared surface lifts as one unit.
434
437
  !buttonGroup && elevationStyles[elevation], width != null && dynamicStyles.width(width),
@@ -9,6 +9,15 @@ export interface CodeBlockProps extends BaseProps<HTMLPreElement> {
9
9
  hasLanguageLabel?: boolean;
10
10
  hasLineNumbers?: boolean;
11
11
  highlightLines?: number[];
12
+ /**
13
+ * Render the code as a unified diff over `language`: lines starting with
14
+ * `+` are added, `-` removed, `@@` is a hunk header (a `--- `/`+++ ` pair
15
+ * directly before one is a file header), anything else is context; the
16
+ * label reads `diff` or `<language> diff`. The glyph sits in its own column and the rest of every line
17
+ * keeps the language's syntax highlighting. Copy still returns the exact
18
+ * source, glyphs included.
19
+ */
20
+ isDiff?: boolean;
12
21
  hasCopyButton?: boolean;
13
22
  onCopy?: () => void;
14
23
  isWrapped?: boolean;
@@ -58,7 +67,7 @@ export interface CodeBlockProps extends BaseProps<HTMLPreElement> {
58
67
  * <CodeBlock code="const x = 42;" language="javascript" />
59
68
  * ```
60
69
  */
61
- export declare function CodeBlock({ code, language, title, hasLanguageLabel, hasLineNumbers, highlightLines, hasCopyButton, onCopy, isWrapped, maxHeight, isCollapsible, collapsibleThreshold, size, width: widthProp, container, tokenizer: customTokenizer, highlightMode, syntaxTheme, xstyle, className, style, ref, ...props }: CodeBlockProps): React.JSX.Element;
70
+ export declare function CodeBlock({ code, language, title, hasLanguageLabel, hasLineNumbers, highlightLines, isDiff, hasCopyButton, onCopy, isWrapped, maxHeight, isCollapsible, collapsibleThreshold, size, width: widthProp, container, tokenizer: customTokenizer, highlightMode, syntaxTheme, xstyle, className, style, ref, ...props }: CodeBlockProps): React.JSX.Element;
62
71
  export declare namespace CodeBlock {
63
72
  var displayName: string;
64
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../src/CodeBlock/CodeBlock.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA8B5C,OAAO,EAAc,KAAK,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AA+WxE,MAAM,WAAW,cAAe,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC/D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AAqPD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,QAAsB,EACtB,KAAK,EACL,gBAAuB,EACvB,cAAsB,EACtB,cAAc,EACd,aAAoB,EACpB,MAAM,EACN,SAAiB,EACjB,SAAS,EACT,aAAqB,EACrB,oBAAyB,EACzB,IAAW,EACX,KAAK,EAAE,SAAyB,EAChC,SAAkB,EAClB,SAAS,EAAE,eAAe,EAC1B,aAAsB,EACtB,WAAW,EACX,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,cAAc,qBA0PhB;yBAlRe,SAAS"}
1
+ {"version":3,"file":"CodeBlock.d.ts","sourceRoot":"","sources":["../../src/CodeBlock/CodeBlock.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAgC5C,OAAO,EAAc,KAAK,qBAAqB,EAAC,MAAM,iBAAiB,CAAC;AAwcxE,MAAM,WAAW,cAAe,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC/D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,KACb;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC5C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AAgSD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,QAAsB,EACtB,KAAK,EACL,gBAAuB,EACvB,cAAsB,EACtB,cAAc,EACd,MAAc,EACd,aAAoB,EACpB,MAAM,EACN,SAAiB,EACjB,SAAS,EACT,aAAqB,EACrB,oBAAyB,EACzB,IAAW,EACX,KAAK,EAAE,SAAyB,EAChC,SAAkB,EAClB,SAAS,EAAE,eAAe,EAC1B,aAAsB,EACtB,WAAW,EACX,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,cAAc,qBAmRhB;yBA5Se,SAAS"}
@@ -18,7 +18,7 @@ import { useClipboard } from "../hooks/useClipboard.js";
18
18
  import { useScrollableArea } from "../hooks/useScrollableArea.js";
19
19
  import { Icon } from "../Icon/index.js";
20
20
  import { IconButton } from "../IconButton/index.js";
21
- import { tokenize, tokenizeAsync, flatTokensToLines, SYNC_TOKENIZE_THRESHOLD } from "./tokenizer.js";
21
+ import { tokenize, tokenizeAsync, splitDiffLines, flatTokensToLines, SYNC_TOKENIZE_THRESHOLD } from "./tokenizer.js";
22
22
  import { ensureHighlightStyles } from "./highlightStyles.js";
23
23
  import { applyHighlightRangesChunked } from "./highlightRanges.js";
24
24
  import { themeProps } from "../utils/themeProps.js";
@@ -115,6 +115,7 @@ const styles = {
115
115
  code: {
116
116
  k1xSpc: "x1lliihq",
117
117
  kUk6DE: "x98rzlu",
118
+ k7Eaqz: "xk8lq53",
118
119
  k8WAf4: "x8o8v82",
119
120
  kg3NbH: "x1pzlopt",
120
121
  kogj98: "x1ghz6dp",
@@ -127,6 +128,7 @@ const styles = {
127
128
  $$css: true
128
129
  },
129
130
  codeWrapped: {
131
+ k7Eaqz: "x15x72sd",
130
132
  khDVqt: "x126k92a",
131
133
  kTgw9: "x1yn0g08",
132
134
  kHjlTd: "x1mzt3pk",
@@ -145,6 +147,61 @@ const styles = {
145
147
  kloYau: "x2q1x1w",
146
148
  $$css: true
147
149
  },
150
+ line: {
151
+ kLWn49: "x17iicif",
152
+ $$css: true
153
+ },
154
+ lineNumbered: {
155
+ k1xSpc: "xrvj5dj",
156
+ kumcoG: "x1xx4m37",
157
+ k1C7PZ: "xf5zn4v",
158
+ kgeoSG: "x46gnpd",
159
+ krRUto: "x17gn2l9",
160
+ kOrBnS: "x19ds33d",
161
+ kKZZS1: "x1wnbjh8",
162
+ kxBb7d: "xtkarl4",
163
+ kUY6Iu: "x1rbqspl",
164
+ kQcDng: "x3nzp0f",
165
+ $$css: true
166
+ },
167
+ lineHighlighted: {
168
+ kWkggS: "xgcxg3y",
169
+ kUOVxO: "x1ng9b9t",
170
+ kg3NbH: "x1pzlopt",
171
+ $$css: true
172
+ },
173
+ lineAdded: {
174
+ kWkggS: "xjqijk9",
175
+ kUOVxO: "x1ng9b9t",
176
+ kg3NbH: "x1pzlopt",
177
+ kxBb7d: "x147exv5",
178
+ $$css: true
179
+ },
180
+ lineRemoved: {
181
+ kWkggS: "xv48ua2",
182
+ kUOVxO: "x1ng9b9t",
183
+ kg3NbH: "x1pzlopt",
184
+ kxBb7d: "x16hy5kr",
185
+ $$css: true
186
+ },
187
+ lineDiffHeader: {
188
+ kWkggS: "x11ds9ch",
189
+ kMwMTN: "xt5rlkq",
190
+ kUOVxO: "x1ng9b9t",
191
+ kg3NbH: "x1pzlopt",
192
+ $$css: true
193
+ },
194
+ lineDiff: {
195
+ k1xSpc: "xrvj5dj",
196
+ kumcoG: "xrnahuw",
197
+ k1C7PZ: "xak3so",
198
+ $$css: true
199
+ },
200
+ lineDiffNumbered: {
201
+ kumcoG: "x1v9b7p9",
202
+ k1C7PZ: "x1o1pmfc",
203
+ $$css: true
204
+ },
148
205
  sizeSm: {
149
206
  kGuDYH: "x141an7d",
150
207
  $$css: true
@@ -179,40 +236,34 @@ const CodeChunk = /*#__PURE__*/React.memo(function CodeChunk({
179
236
  lines,
180
237
  startIndex,
181
238
  highlightSet,
239
+ diffKinds,
182
240
  renderLineContent,
183
241
  lineNumbers
184
242
  }) {
185
243
  return /*#__PURE__*/_jsx(_Fragment, {
186
244
  children: lines.map((line, j) => {
187
245
  const i = startIndex + j;
246
+ const diffKind = diffKinds?.[i];
188
247
  return /*#__PURE__*/_jsx("div", {
189
248
  "data-line": i + 1,
190
- ...{
191
- 0: {
192
- className: "x17iicif"
193
- },
194
- 2: {
195
- className: "x17iicif xrvj5dj x1xx4m37 xf5zn4v x46gnpd x17gn2l9 x19ds33d x1wnbjh8 xtkarl4 x1rbqspl x3nzp0f"
196
- },
197
- 1: {
198
- className: "x17iicif xgcxg3y x1ng9b9t x1pzlopt"
199
- },
200
- 3: {
201
- className: "x17iicif xrvj5dj x1xx4m37 xf5zn4v x46gnpd x17gn2l9 x19ds33d x1wnbjh8 xtkarl4 x1rbqspl x3nzp0f xgcxg3y x1ng9b9t x1pzlopt"
202
- }
203
- }[!!lineNumbers << 1 | !!(highlightSet?.has(i + 1) ?? false) << 0],
249
+ "data-diff": diffKind === 'context' ? undefined : diffKind,
250
+ ...stylex.props(styles.line, lineNumbers && styles.lineNumbered, diffKinds != null && styles.lineDiff, diffKinds != null && lineNumbers && styles.lineDiffNumbered, diffKind === 'added' && styles.lineAdded, diffKind === 'removed' && styles.lineRemoved, diffKind === 'header' && styles.lineDiffHeader,
251
+ // Last on purpose: a highlight replaces a diff tint rather than
252
+ // stacking on it, so tokens keep their single-paint contrast.
253
+ (highlightSet?.has(i + 1) ?? false) && styles.lineHighlighted),
204
254
  children: renderLineContent(line, i)
205
255
  }, i);
206
256
  })
207
257
  });
208
258
  });
209
- function renderLines(lines, highlightSet, renderLineContent, lineNumbers, chunkSize = LINE_CHUNK_SIZE) {
259
+ function renderLines(lines, highlightSet, diffKinds, renderLineContent, lineNumbers, chunkSize = LINE_CHUNK_SIZE) {
210
260
  chunkSize = Math.max(1, Math.floor(chunkSize));
211
261
  if (lines.length < LINE_CHUNK_THRESHOLD) {
212
262
  return /*#__PURE__*/_jsx(CodeChunk, {
213
263
  lines: lines,
214
264
  startIndex: 0,
215
265
  highlightSet: highlightSet,
266
+ diffKinds: diffKinds,
216
267
  renderLineContent: renderLineContent,
217
268
  lineNumbers: lineNumbers
218
269
  });
@@ -234,6 +285,7 @@ function renderLines(lines, highlightSet, renderLineContent, lineNumbers, chunkS
234
285
  lines: chunkLines,
235
286
  startIndex: start,
236
287
  highlightSet: highlightSet,
288
+ diffKinds: diffKinds,
237
289
  renderLineContent: renderLineContent,
238
290
  lineNumbers: lineNumbers
239
291
  })
@@ -350,6 +402,8 @@ function SpanCodeContent({
350
402
  lines,
351
403
  tokenLines,
352
404
  highlightSet,
405
+ diffKinds,
406
+ diff,
353
407
  isWrapped,
354
408
  sizeStyle,
355
409
  hasLineNumbers,
@@ -360,6 +414,49 @@ function SpanCodeContent({
360
414
  }, []);
361
415
  const renderLineContent = useCallback((line, lineIndex) => {
362
416
  const tokens = tokenLines[lineIndex] ?? [];
417
+ if (diff) {
418
+ // Header rows show their raw text; every other row shows its glyph in
419
+ // the marker column and the base-language tokens of the rest.
420
+ const kind = diff.kinds[lineIndex];
421
+ const content = kind === 'header' ? line : diff.content[lineIndex];
422
+ return /*#__PURE__*/_jsxs(_Fragment, {
423
+ children: [/*#__PURE__*/_jsx("span", {
424
+ "data-diff-marker": "",
425
+ ...{
426
+ 0: {
427
+ className: "xv1l7n4 x87ps6o x1sdyfia"
428
+ },
429
+ 4: {
430
+ className: "xv1l7n4 x87ps6o x1sdyfia x6w1cxl x1pezmd8"
431
+ },
432
+ 2: {
433
+ className: "x87ps6o x1sdyfia x1wxerb0"
434
+ },
435
+ 6: {
436
+ className: "x87ps6o x1sdyfia x6w1cxl x1pezmd8 x1wxerb0"
437
+ },
438
+ 1: {
439
+ className: "x87ps6o x1sdyfia x103bwea"
440
+ },
441
+ 5: {
442
+ className: "x87ps6o x1sdyfia x6w1cxl x1pezmd8 x103bwea"
443
+ },
444
+ 3: {
445
+ className: "x87ps6o x1sdyfia x103bwea"
446
+ },
447
+ 7: {
448
+ className: "x87ps6o x1sdyfia x6w1cxl x1pezmd8 x103bwea"
449
+ }
450
+ }[!!hasLineNumbers << 2 | !!(kind === 'added') << 1 | !!(kind === 'removed') << 0],
451
+ children: diff.glyphs[lineIndex] || ' '
452
+ }), /*#__PURE__*/_jsx("span", {
453
+ ...{
454
+ className: "xeuugli"
455
+ },
456
+ children: kind === 'header' ? content || '\u200b' : buildSpanLine(content, tokens)
457
+ })]
458
+ });
459
+ }
363
460
  // Wrap tokens in a single element so they occupy one grid cell when line
364
461
  // numbers are on (see `lineNumbered`); an inline span is a no-op when off.
365
462
  return /*#__PURE__*/_jsx("span", {
@@ -368,10 +465,10 @@ function SpanCodeContent({
368
465
  },
369
466
  children: buildSpanLine(line, tokens)
370
467
  });
371
- }, [tokenLines]);
468
+ }, [tokenLines, diff, hasLineNumbers]);
372
469
  return /*#__PURE__*/_jsx("code", {
373
470
  ...stylex.props(styles.code, sizeStyle, isWrapped && styles.codeWrapped, hasLineNumbers && styles.codeNumbered, hasLineNumbers && dynamicStyles.gutterWidth(maxDigits)),
374
- children: renderLines(lines, highlightSet, renderLineContent, hasLineNumbers)
471
+ children: renderLines(lines, highlightSet, diffKinds, renderLineContent, hasLineNumbers)
375
472
  });
376
473
  }
377
474
 
@@ -383,6 +480,7 @@ function RangeCodeContent({
383
480
  lines,
384
481
  tokenLines,
385
482
  highlightSet,
483
+ diffKinds,
386
484
  isWrapped,
387
485
  sizeStyle,
388
486
  hasLineNumbers,
@@ -408,7 +506,7 @@ function RangeCodeContent({
408
506
  return /*#__PURE__*/_jsx("code", {
409
507
  ref: codeRef,
410
508
  ...stylex.props(styles.code, sizeStyle, isWrapped && styles.codeWrapped, hasLineNumbers && styles.codeNumbered, hasLineNumbers && dynamicStyles.gutterWidth(maxDigits)),
411
- children: renderLines(lines, highlightSet, renderLineContent, hasLineNumbers)
509
+ children: renderLines(lines, highlightSet, diffKinds, renderLineContent, hasLineNumbers)
412
510
  });
413
511
  }
414
512
 
@@ -432,6 +530,7 @@ export function CodeBlock({
432
530
  hasLanguageLabel = true,
433
531
  hasLineNumbers = false,
434
532
  highlightLines,
533
+ isDiff = false,
435
534
  hasCopyButton = true,
436
535
  onCopy,
437
536
  isWrapped = false,
@@ -460,7 +559,7 @@ export function CodeBlock({
460
559
  } = useClipboard({
461
560
  announce: t('@astryx.codeBlock.copied')
462
561
  });
463
- const useSpans = highlightMode === 'spans' || highlightMode === 'auto' && !hasHighlightAPI() || highlightMode === 'auto' && isSafari();
562
+ const useSpans = isDiff || highlightMode === 'spans' || highlightMode === 'auto' && !hasHighlightAPI() || highlightMode === 'auto' && isSafari();
464
563
  const lines = useMemo(() => {
465
564
  const l = code.split('\n');
466
565
  if (l.length > 1 && l[l.length - 1] === '') {
@@ -468,7 +567,13 @@ export function CodeBlock({
468
567
  }
469
568
  return l;
470
569
  }, [code]);
471
- const tokenLines = useTokenLines(code, language, customTokenizer);
570
+
571
+ // In diff mode the base language sees the code with the glyph column set
572
+ // aside, so a `tsx` diff still highlights as `tsx` on every line; headers
573
+ // contribute an empty line and are rendered as their raw text.
574
+ const diff = useMemo(() => isDiff ? splitDiffLines(lines) : null, [isDiff, lines]);
575
+ const tokenLines = useTokenLines(diff ? diff.content.join('\n') : code, language, customTokenizer);
576
+ const diffKinds = diff?.kinds ?? null;
472
577
  const highlightSet = useMemo(() => highlightLines ? new Set(highlightLines) : null, [highlightLines]);
473
578
  const handleCopy = useCallback(async () => {
474
579
  const didCopy = await copy(code);
@@ -479,7 +584,10 @@ export function CodeBlock({
479
584
  const sizeStyle = size === 'sm' ? styles.sizeSm : styles.sizeMd;
480
585
  // Digits in the largest line number — sizes the gutter column width.
481
586
  const maxLineDigits = String(lines.length).length;
482
- const languageLabel = hasLanguageLabel && language !== 'plaintext' ? language : null;
587
+ // With the diff layer on, the label and viewport name say so: `diff` over
588
+ // plaintext, `tsx diff` over a language — so a diff keeps its header,
589
+ // collapse control, and a name that still matches a `diff` fence.
590
+ const languageLabel = !hasLanguageLabel ? null : isDiff ? language === 'plaintext' ? 'diff' : `${language} diff` : language !== 'plaintext' ? language : null;
483
591
  const showHeader = title != null || languageLabel != null;
484
592
 
485
593
  // A collapsed body must never outlive the visible header that controls it.
@@ -606,6 +714,8 @@ export function CodeBlock({
606
714
  lines: lines,
607
715
  tokenLines: tokenLines,
608
716
  highlightSet: highlightSet,
717
+ diffKinds: diffKinds,
718
+ diff: diff,
609
719
  isWrapped: isWrapped,
610
720
  sizeStyle: sizeStyle,
611
721
  hasLineNumbers: hasLineNumbers,
@@ -614,6 +724,7 @@ export function CodeBlock({
614
724
  lines: lines,
615
725
  tokenLines: tokenLines,
616
726
  highlightSet: highlightSet,
727
+ diffKinds: diffKinds,
617
728
  isWrapped: isWrapped,
618
729
  sizeStyle: sizeStyle,
619
730
  hasLineNumbers: hasLineNumbers,
@@ -8,6 +8,45 @@ export type SyntaxToken = {
8
8
  * line-relative start/end offsets (0 = start of line).
9
9
  */
10
10
  export type TokenLine = SyntaxToken[];
11
+ /** How a unified-diff line reads: what it adds, removes, frames, or keeps. */
12
+ export type DiffLineKind = 'added' | 'removed' | 'header' | 'context';
13
+ /**
14
+ * Read a Markdown fence info string the way CodeBlock renders it: `diff` is
15
+ * the diff layer over plaintext, `diff-<lang>` (the common convention) is the
16
+ * diff layer over `<lang>`, anything else is a language.
17
+ */
18
+ export declare function parseFenceLanguage(info: string | undefined): {
19
+ language: string;
20
+ isDiff: boolean;
21
+ };
22
+ /**
23
+ * Split a diff into the glyph column and the code the base language sees:
24
+ * every added, removed, or space-led context line loses its first character
25
+ * (the `+`, `-`, or space); a context line with no leading space keeps all
26
+ * of it; header lines contribute an empty line so offsets stay per line.
27
+ */
28
+ export declare function splitDiffLines(lines: ReadonlyArray<string>): {
29
+ kinds: DiffLineKind[];
30
+ glyphs: string[];
31
+ content: string[];
32
+ };
33
+ /**
34
+ * Classify one line of a unified diff by its first character: `+` added,
35
+ * `-` removed, `@@` header, anything else context. A `--- ` line (with its
36
+ * space) directly followed by a `+++ ` line and then an `@@` line is a file
37
+ * header (both lines), wherever it occurs; every other `---`/`+++` line is
38
+ * removed or added, so a removed line that starts with `--` — `---i;`
39
+ * included — is never misread. The glyph is part of the text and is never
40
+ * removed.
41
+ */
42
+ export declare function diffLineKind(line: string, { isFileHeader }?: {
43
+ isFileHeader?: boolean;
44
+ }): DiffLineKind;
45
+ /**
46
+ * The indexes of the `--- `/`+++ ` lines (unified-diff form, with the space)
47
+ * that form a file header directly before an `@@`; `---i;` is a change.
48
+ */
49
+ export declare function fileHeaderLines(lines: ReadonlyArray<string>): Set<number>;
11
50
  /** Threshold below which we tokenize synchronously (characters). */
12
51
  export declare const SYNC_TOKENIZE_THRESHOLD = 2000;
13
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../src/CodeBlock/tokenizer.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,WAAW,GAAG;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,EAAE,CAAC;AAsStC,oEAAoE;AACpE,eAAO,MAAM,uBAAuB,OAAO,CAAC;AA+D5C;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAiBpE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,SAAS,EAAE,CAAC,CA2BtB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,EACxD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,EAAE,EACpD,IAAI,EAAE,MAAM,GACX,SAAS,EAAE,CA4Bb"}
1
+ {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../src/CodeBlock/tokenizer.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,WAAW,GAAG;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,WAAW,EAAE,CAAC;AAsStC,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,CAUA;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG;IAC5D,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAuBA;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,EAAC,YAAoB,EAAC,GAAE;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAM,GACpD,YAAY,CAWd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAazE;AAMD,oEAAoE;AACpE,eAAO,MAAM,uBAAuB,OAAO,CAAC;AA+D5C;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAiBpE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,SAAS,EAAE,CAAC,CA2BtB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,EACxD,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,EAAE,EACpD,IAAI,EAAE,MAAM,GACX,SAAS,EAAE,CA4Bb"}
@@ -524,6 +524,114 @@ function buildLanguagePatterns(lang) {
524
524
  }
525
525
  }
526
526
 
527
+ // ---------------------------------------------------------------------------
528
+ // Diff lines
529
+ // ---------------------------------------------------------------------------
530
+
531
+ /** How a unified-diff line reads: what it adds, removes, frames, or keeps. */
532
+
533
+ /**
534
+ * Read a Markdown fence info string the way CodeBlock renders it: `diff` is
535
+ * the diff layer over plaintext, `diff-<lang>` (the common convention) is the
536
+ * diff layer over `<lang>`, anything else is a language.
537
+ */
538
+ export function parseFenceLanguage(info) {
539
+ const value = (info ?? '').trim();
540
+ if (value === 'diff') {
541
+ return {
542
+ language: 'plaintext',
543
+ isDiff: true
544
+ };
545
+ }
546
+ const layered = /^diff-(.+)$/.exec(value);
547
+ if (layered) {
548
+ return {
549
+ language: layered[1],
550
+ isDiff: true
551
+ };
552
+ }
553
+ return {
554
+ language: value || 'plaintext',
555
+ isDiff: false
556
+ };
557
+ }
558
+
559
+ /**
560
+ * Split a diff into the glyph column and the code the base language sees:
561
+ * every added, removed, or space-led context line loses its first character
562
+ * (the `+`, `-`, or space); a context line with no leading space keeps all
563
+ * of it; header lines contribute an empty line so offsets stay per line.
564
+ */
565
+ export function splitDiffLines(lines) {
566
+ const kinds = [];
567
+ const glyphs = [];
568
+ const content = [];
569
+ const fileHeaders = fileHeaderLines(lines);
570
+ lines.forEach((line, index) => {
571
+ const kind = diffLineKind(line, {
572
+ isFileHeader: fileHeaders.has(index)
573
+ });
574
+ kinds.push(kind);
575
+ if (kind === 'header') {
576
+ glyphs.push('');
577
+ content.push('');
578
+ } else if (kind === 'context' && !line.startsWith(' ')) {
579
+ // A context line without its leading space (an unindented diff, or
580
+ // an empty line) has no glyph: the marker column is empty and the
581
+ // whole line is code.
582
+ glyphs.push('');
583
+ content.push(line);
584
+ } else {
585
+ glyphs.push(line.slice(0, 1));
586
+ content.push(line.slice(1));
587
+ }
588
+ });
589
+ return {
590
+ kinds,
591
+ glyphs,
592
+ content
593
+ };
594
+ }
595
+
596
+ /**
597
+ * Classify one line of a unified diff by its first character: `+` added,
598
+ * `-` removed, `@@` header, anything else context. A `--- ` line (with its
599
+ * space) directly followed by a `+++ ` line and then an `@@` line is a file
600
+ * header (both lines), wherever it occurs; every other `---`/`+++` line is
601
+ * removed or added, so a removed line that starts with `--` — `---i;`
602
+ * included — is never misread. The glyph is part of the text and is never
603
+ * removed.
604
+ */
605
+ export function diffLineKind(line, {
606
+ isFileHeader = false
607
+ } = {}) {
608
+ if (line.startsWith('@@') || isFileHeader) {
609
+ return 'header';
610
+ }
611
+ if (line.startsWith('+')) {
612
+ return 'added';
613
+ }
614
+ if (line.startsWith('-')) {
615
+ return 'removed';
616
+ }
617
+ return 'context';
618
+ }
619
+
620
+ /**
621
+ * The indexes of the `--- `/`+++ ` lines (unified-diff form, with the space)
622
+ * that form a file header directly before an `@@`; `---i;` is a change.
623
+ */
624
+ export function fileHeaderLines(lines) {
625
+ const headers = new Set();
626
+ for (let i = 0; i + 2 < lines.length; i++) {
627
+ if (lines[i].startsWith('--- ') && lines[i + 1].startsWith('+++ ') && lines[i + 2].startsWith('@@')) {
628
+ headers.add(i);
629
+ headers.add(i + 1);
630
+ }
631
+ }
632
+ return headers;
633
+ }
634
+
527
635
  // ---------------------------------------------------------------------------
528
636
  // Core tokenizer
529
637
  // ---------------------------------------------------------------------------
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file Dialog.tsx
3
3
  * @input Uses React, DialogHTMLAttributes, ReactNode, container (Layout), DialogContext, layerTextReset,
4
- * layerStructureReset, modalOutlet, interactionModality
4
+ * layerStructureReset, modalOutlet, interactionModality, chainEventHandlers
5
5
  * @output Exports Dialog component, DialogProps, DialogVariant, DialogPurpose types
6
6
  * @position Core implementation; consumed by index.ts, tested by Dialog.test.tsx
7
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA2B5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAKhD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAyB9C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,4EAA4E;AAC5E,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAuBD,2FAA2F;AAC3F,eAAO,MAAM,uCAAuC;;;;;;;;;;;CAW1C,CAAC;AAoJX;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc;;;;;EAUpE;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,QAAgB,EAChB,YAAY,EACZ,KAAW,EACX,SAAmB,EACnB,QAAQ,EACR,OAAoB,EACpB,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,sCAiUb;yBAjVe,MAAM"}
1
+ {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA2B5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAMhD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAyB9C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,4EAA4E;AAC5E,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAuBD,2FAA2F;AAC3F,eAAO,MAAM,uCAAuC;;;;;;;;;;;CAW1C,CAAC;AAoJX;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc;;;;;EAUpE;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,QAAgB,EAChB,YAAY,EACZ,KAAW,EACX,SAAmB,EACnB,QAAQ,EACR,OAAoB,EACpB,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,sCA2Ub;yBA3Ve,MAAM"}
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @file Dialog.tsx
7
7
  * @input Uses React, DialogHTMLAttributes, ReactNode, container (Layout), DialogContext, layerTextReset,
8
- * layerStructureReset, modalOutlet, interactionModality
8
+ * layerStructureReset, modalOutlet, interactionModality, chainEventHandlers
9
9
  * @output Exports Dialog component, DialogProps, DialogVariant, DialogPurpose types
10
10
  * @position Core implementation; consumed by index.ts, tested by Dialog.test.tsx
11
11
  *
@@ -41,6 +41,7 @@ import { colorVars, radiusVars, durationVars, easeVars, shadowVars, spacingVars
41
41
  import { container } from "../Layout/container.stylex.js";
42
42
  import { paddingStyles, containerPaddingInlineVarStyles, containerPaddingBlockStartVarStyles, containerPaddingBlockEndVarStyles, spacingStepToToken, overlayPaddingReset } from "../Layout/padding.stylex.js";
43
43
  import { mergeProps } from "../utils/index.js";
44
+ import { chainEventHandlers } from "../utils/chainEventHandlers.js";
44
45
  import { devWarn } from "../utils/devWarning.js";
45
46
  import { DialogContext } from "./DialogContext.js";
46
47
  import { themeProps } from "../utils/themeProps.js";
@@ -489,12 +490,22 @@ export function Dialog({
489
490
  })
490
491
  });
491
492
 
492
- // Filter out native open to prevent InvalidStateError when accidentally passed
493
+ // Filter out native open to prevent InvalidStateError when accidentally passed.
494
+ // Keep the consumer click handler separate so the modal path can compose it
495
+ // with Dialog-owned behavior without changing the inline preview path.
493
496
  const hasPosition = position != null && !isFullscreen;
497
+ const {
498
+ onClick: onClickProp,
499
+ ...propsWithoutClick
500
+ } = props;
494
501
  const {
495
502
  open: _open,
496
503
  ...safeProps
497
- } = props;
504
+ } = propsWithoutClick;
505
+ const inlineSafeProps = {
506
+ ...safeProps,
507
+ onClick: onClickProp
508
+ };
498
509
 
499
510
  // --- Inline rendering path (for documentation previews) ---
500
511
  if (isInline) {
@@ -502,7 +513,7 @@ export function Dialog({
502
513
  return null;
503
514
  }
504
515
  return /*#__PURE__*/_jsx("div", {
505
- ...safeProps,
516
+ ...inlineSafeProps,
506
517
  ...mergeProps(themeProps('dialog', {
507
518
  variant
508
519
  }), stylex.props(layerTextReset.reset, layerStructureReset.reset, styles.inlineWrapper, overlayPaddingReset.reset, standardSizing && dynamicStyles.sizing(standardSizing.width, standardSizing.maxWidth, standardSizing.maxHeight), isFullscreen && styles.fullscreen, xstyle), className, style),
@@ -526,7 +537,7 @@ export function Dialog({
526
537
  const o = resolveDialogPositionOffsets(position);
527
538
  return dynamicStyles.position(o.top, o.insetInlineStart, o.insetInlineEnd, o.bottom);
528
539
  })(), isFullscreen && styles.fullscreen, isFullscreen && isOpen && styles.fullscreenOpen, xstyle), className, style),
529
- onClick: handleClick,
540
+ onClick: chainEventHandlers(handleClick, onClickProp),
530
541
  onCancel: handleCancel,
531
542
  "aria-modal": "true"
532
543
  // The default aria-labelledby (from a DialogHeader title) is set
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file DialogHeader.tsx
3
- * @input Uses React, StyleX, LayoutHeader, Button, Icon, Heading, Text, DialogContext, mergeProps, themeProps
3
+ * @input Uses React, StyleX, LayoutHeader, Button, Icon, Heading, Text, DialogContext, isRenderable, mergeProps, themeProps
4
4
  * @output Exports DialogHeader component and DialogHeaderProps
5
5
  * @position Dialog header component; used with Dialog and Layout
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"DialogHeader.d.ts","sourceRoot":"","sources":["../../src/Dialog/DialogHeader.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAQxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA2C5C,MAAM,WAAW,iBAAkB,SAAQ,SAAS,CAAC,cAAc,CAAC;IAClE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;;;;;OASG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IAEzB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IAExD;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,0BAA0B,EAC1B,UAAU,EACV,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,iBAAiB,+BA2GnB;yBAxHe,YAAY"}
1
+ {"version":3,"file":"DialogHeader.d.ts","sourceRoot":"","sources":["../../src/Dialog/DialogHeader.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAQxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA2C5C,MAAM,WAAW,iBAAkB,SAAQ,SAAS,CAAC,cAAc,CAAC;IAClE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;;;;;OASG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IAEzB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IAExD;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,0BAA0B,EAC1B,UAAU,EACV,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,iBAAiB,+BA0GnB;yBAvHe,YAAY"}