@astryxdesign/core 0.7.1-canary.ec71b55 → 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.
- package/dist/Button/Button.d.ts +1 -1
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +5 -2
- package/dist/CodeBlock/CodeBlock.d.ts +10 -1
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +133 -22
- package/dist/CodeBlock/tokenizer.d.ts +39 -0
- package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
- package/dist/CodeBlock/tokenizer.js +108 -0
- package/dist/Dialog/Dialog.d.ts +1 -1
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +16 -5
- package/dist/Dialog/DialogHeader.d.ts +1 -1
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +7 -7
- package/dist/InputGroup/InputGroup.d.ts +2 -4
- package/dist/InputGroup/InputGroup.d.ts.map +1 -1
- package/dist/InputGroup/InputGroup.js +2 -4
- package/dist/InputGroup/groupStyles.d.ts +10 -2
- package/dist/InputGroup/groupStyles.d.ts.map +1 -1
- package/dist/InputGroup/groupStyles.js +19 -2
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +19 -3
- package/dist/astryx.css +19 -0
- package/dist/theme/syntax/SyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/SyntaxTheme.js +43 -2
- package/dist/theme/syntax/defineSyntaxTheme.d.ts +18 -5
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +38 -9
- package/dist/theme/syntax/index.d.ts +1 -1
- package/dist/theme/syntax/index.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.d.ts +12 -2
- package/dist/theme/syntax/tokens.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.js +25 -4
- package/package.json +3 -3
- package/src/Button/Button.test.tsx +37 -0
- package/src/Button/Button.tsx +5 -1
- package/src/CodeBlock/CodeBlock.doc.mjs +7 -0
- package/src/CodeBlock/CodeBlock.spec.md +12 -12
- package/src/CodeBlock/CodeBlock.test.tsx +78 -0
- package/src/CodeBlock/CodeBlock.tsx +176 -7
- package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +93 -0
- package/src/CodeBlock/tokenizer.test.ts +112 -0
- package/src/CodeBlock/tokenizer.ts +106 -0
- package/src/Dialog/Dialog.test.tsx +27 -1
- package/src/Dialog/Dialog.tsx +16 -5
- package/src/Dialog/DialogHeader.test.tsx +27 -2
- package/src/Dialog/DialogHeader.tsx +7 -8
- package/src/InputGroup/InputGroup.doc.mjs +11 -1
- package/src/InputGroup/InputGroup.tsx +2 -4
- package/src/InputGroup/groupStyles.ts +40 -2
- package/src/Link/__tests__/Link.a11y.chromium.spec.ts +142 -0
- package/src/Link/__tests__/Link.a11y.renders.tsx +97 -0
- package/src/Link/__tests__/Link.a11y.states.ts +104 -0
- package/src/Link/__tests__/Link.a11y.test.tsx +127 -0
- package/src/Markdown/Markdown.spec.md +3 -3
- package/src/Markdown/Markdown.test.tsx +38 -0
- package/src/Markdown/Markdown.tsx +20 -2
- package/src/Selector/Selector.spec.md +23 -13
- package/src/theme/syntax/SyntaxTheme.tsx +46 -5
- package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +91 -0
- package/src/theme/syntax/defineSyntaxTheme.ts +75 -15
- package/src/theme/syntax/index.ts +5 -1
- package/src/theme/syntax/tokens.ts +32 -2
- package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +40 -0
package/dist/Button/Button.d.ts
CHANGED
|
@@ -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":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAwB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAE,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"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"}
|
package/dist/Button/Button.js
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
// ---------------------------------------------------------------------------
|
package/dist/Dialog/Dialog.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/Dialog/Dialog.js
CHANGED
|
@@ -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
|
-
} =
|
|
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
|
-
...
|
|
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,+
|
|
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"}
|