@wallarm-org/design-system 0.22.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.
- package/dist/components/Attribute/Attribute.d.ts +9 -0
- package/dist/components/Attribute/Attribute.js +33 -0
- package/dist/components/Attribute/AttributeLabel.d.ts +6 -0
- package/dist/components/Attribute/AttributeLabel.js +16 -0
- package/dist/components/Attribute/AttributeLabelDescription.d.ts +6 -0
- package/dist/components/Attribute/AttributeLabelDescription.js +16 -0
- package/dist/components/Attribute/AttributeLabelInfo.d.ts +7 -0
- package/dist/components/Attribute/AttributeLabelInfo.js +29 -0
- package/dist/components/Attribute/AttributeValue.d.ts +6 -0
- package/dist/components/Attribute/AttributeValue.js +25 -0
- package/dist/components/Attribute/index.d.ts +5 -0
- package/dist/components/Attribute/index.js +6 -0
- package/dist/components/CodeSnippet/CodeSnippetActions.js +1 -1
- package/dist/components/CodeSnippet/CodeSnippetCode.js +21 -16
- package/dist/components/CodeSnippet/CodeSnippetContent.js +10 -10
- package/dist/components/CodeSnippet/CodeSnippetContext.d.ts +8 -0
- package/dist/components/CodeSnippet/CodeSnippetLineNumbers.js +10 -7
- package/dist/components/CodeSnippet/CodeSnippetRoot.d.ts +4 -1
- package/dist/components/CodeSnippet/CodeSnippetRoot.js +54 -3
- package/dist/components/CodeSnippet/InlineCodeSnippet.js +1 -1
- package/dist/components/CodeSnippet/index.d.ts +2 -0
- package/dist/components/CodeSnippet/index.js +2 -1
- package/dist/components/CodeSnippet/internal/CodeSnippetHighlights.js +7 -8
- package/dist/components/CodeSnippet/internal/ColorStickColumn.d.ts +2 -2
- package/dist/components/CodeSnippet/internal/ColorStickColumn.js +8 -8
- package/dist/components/CodeSnippet/internal/FoldColumn.d.ts +3 -0
- package/dist/components/CodeSnippet/internal/FoldColumn.js +42 -0
- package/dist/components/CodeSnippet/internal/FoldSummaryLine.d.ts +8 -0
- package/dist/components/CodeSnippet/internal/FoldSummaryLine.js +20 -0
- package/dist/components/CodeSnippet/internal/FoldToggle.d.ts +7 -0
- package/dist/components/CodeSnippet/internal/FoldToggle.js +19 -0
- package/dist/components/CodeSnippet/internal/PrefixColumn.d.ts +2 -2
- package/dist/components/CodeSnippet/internal/PrefixColumn.js +8 -8
- package/dist/components/CodeSnippet/internal/ShowMoreButton.js +2 -2
- package/dist/components/CodeSnippet/lib/foldUtils.d.ts +28 -0
- package/dist/components/CodeSnippet/lib/foldUtils.js +80 -0
- package/dist/components/CodeSnippet/lib/httpFolds.d.ts +27 -0
- package/dist/components/CodeSnippet/lib/httpFolds.js +36 -0
- package/dist/components/Flex/Flex.d.ts +1 -1
- package/dist/components/SegmentedControl/SegmentedControlSeparator.d.ts +1 -1
- package/dist/components/Separator/Separator.d.ts +1 -1
- package/dist/components/Skeleton/Skeleton.d.ts +1 -1
- package/dist/components/Stack/Stack.d.ts +1 -1
- package/dist/hooks/useCopyTooltip.js +5 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/metadata/components.json +1496 -26
- package/dist/theme/index.css +1 -0
- package/dist/theme/semantic.css +32 -25
- package/dist/theme/utilities/code-snippet-bg.css +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
export interface AttributeProps extends HTMLAttributes<HTMLDivElement>, TestableProps {
|
|
4
|
+
ref?: Ref<HTMLDivElement>;
|
|
5
|
+
/** Show skeleton placeholders instead of children */
|
|
6
|
+
loading?: boolean;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare const Attribute: FC<AttributeProps>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { TestIdProvider } from "../../utils/testId.js";
|
|
4
|
+
import { Skeleton } from "../Skeleton/index.js";
|
|
5
|
+
const Attribute = ({ ref, loading = false, children, className, 'data-testid': testId, ...props })=>/*#__PURE__*/ jsx(TestIdProvider, {
|
|
6
|
+
value: testId,
|
|
7
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
8
|
+
...props,
|
|
9
|
+
ref: ref,
|
|
10
|
+
"data-testid": testId,
|
|
11
|
+
"data-slot": "attribute",
|
|
12
|
+
className: cn('flex flex-col', className),
|
|
13
|
+
children: loading ? /*#__PURE__*/ jsxs(Fragment, {
|
|
14
|
+
children: [
|
|
15
|
+
/*#__PURE__*/ jsx(Skeleton, {
|
|
16
|
+
width: "82px",
|
|
17
|
+
height: "16px",
|
|
18
|
+
rounded: 6
|
|
19
|
+
}),
|
|
20
|
+
/*#__PURE__*/ jsx("div", {
|
|
21
|
+
className: "pt-4",
|
|
22
|
+
children: /*#__PURE__*/ jsx(Skeleton, {
|
|
23
|
+
width: "100%",
|
|
24
|
+
height: "24px",
|
|
25
|
+
rounded: 6
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
}) : children
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
Attribute.displayName = 'Attribute';
|
|
33
|
+
export { Attribute };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
const AttributeLabel = ({ ref, children, className, ...props })=>{
|
|
5
|
+
const testId = useTestId('label');
|
|
6
|
+
return /*#__PURE__*/ jsx("div", {
|
|
7
|
+
...props,
|
|
8
|
+
ref: ref,
|
|
9
|
+
"data-testid": testId,
|
|
10
|
+
"data-slot": "attribute-label",
|
|
11
|
+
className: cn('flex items-center gap-4 flex-wrap font-sans-display text-sm font-normal text-text-secondary', className),
|
|
12
|
+
children: children
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
AttributeLabel.displayName = 'AttributeLabel';
|
|
16
|
+
export { AttributeLabel };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
export interface AttributeLabelDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {
|
|
3
|
+
ref?: Ref<HTMLParagraphElement>;
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const AttributeLabelDescription: FC<AttributeLabelDescriptionProps>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../utils/cn.js";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
const AttributeLabelDescription = ({ ref, children, className, ...props })=>{
|
|
5
|
+
const testId = useTestId("label-description");
|
|
6
|
+
return /*#__PURE__*/ jsx("p", {
|
|
7
|
+
...props,
|
|
8
|
+
ref: ref,
|
|
9
|
+
"data-testid": testId,
|
|
10
|
+
"data-slot": "attribute-label-description",
|
|
11
|
+
className: cn('basis-full', className),
|
|
12
|
+
children: children
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
AttributeLabelDescription.displayName = "AttributeLabelDescription";
|
|
16
|
+
export { AttributeLabelDescription };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
|
+
export interface AttributeLabelInfoProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
|
|
3
|
+
ref?: Ref<HTMLSpanElement>;
|
|
4
|
+
/** Tooltip content */
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare const AttributeLabelInfo: FC<AttributeLabelInfoProps>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Info } from "../../icons/index.js";
|
|
3
|
+
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/index.js";
|
|
5
|
+
const AttributeLabelInfo = ({ ref, children, ...props })=>{
|
|
6
|
+
const testId = useTestId('label-info');
|
|
7
|
+
return /*#__PURE__*/ jsxs(Tooltip, {
|
|
8
|
+
children: [
|
|
9
|
+
/*#__PURE__*/ jsx(TooltipTrigger, {
|
|
10
|
+
asChild: true,
|
|
11
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
12
|
+
...props,
|
|
13
|
+
ref: ref,
|
|
14
|
+
"data-testid": testId,
|
|
15
|
+
"data-slot": "attribute-label-info",
|
|
16
|
+
className: "inline-flex cursor-help",
|
|
17
|
+
children: /*#__PURE__*/ jsx(Info, {
|
|
18
|
+
size: "md"
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
}),
|
|
22
|
+
/*#__PURE__*/ jsx(TooltipContent, {
|
|
23
|
+
children: children
|
|
24
|
+
})
|
|
25
|
+
]
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
AttributeLabelInfo.displayName = 'AttributeLabelInfo';
|
|
29
|
+
export { AttributeLabelInfo };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type FC, type HTMLAttributes, type ReactNode, type Ref } from 'react';
|
|
2
|
+
export interface AttributeValueProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
ref?: Ref<HTMLDivElement>;
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const AttributeValue: FC<AttributeValueProps>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Children } from "react";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
import { useTestId } from "../../utils/testId.js";
|
|
5
|
+
import { Text } from "../Text/index.js";
|
|
6
|
+
function isEmpty(children) {
|
|
7
|
+
return null == children || false === children || 0 === Children.count(children);
|
|
8
|
+
}
|
|
9
|
+
const AttributeValue = ({ ref, children, className, ...props })=>{
|
|
10
|
+
const testId = useTestId('value');
|
|
11
|
+
return /*#__PURE__*/ jsx("div", {
|
|
12
|
+
...props,
|
|
13
|
+
ref: ref,
|
|
14
|
+
"data-testid": testId,
|
|
15
|
+
"data-slot": "attribute-value",
|
|
16
|
+
className: cn('pt-4 min-h-[28px] flex items-center', className),
|
|
17
|
+
children: isEmpty(children) ? /*#__PURE__*/ jsx(Text, {
|
|
18
|
+
size: "sm",
|
|
19
|
+
color: "secondary",
|
|
20
|
+
children: "—"
|
|
21
|
+
}) : children
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
AttributeValue.displayName = 'AttributeValue';
|
|
25
|
+
export { AttributeValue };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { Attribute, type AttributeProps } from './Attribute';
|
|
2
|
+
export { AttributeLabel, type AttributeLabelProps } from './AttributeLabel';
|
|
3
|
+
export { AttributeLabelDescription, type AttributeLabelDescriptionProps, } from './AttributeLabelDescription';
|
|
4
|
+
export { AttributeLabelInfo, type AttributeLabelInfoProps } from './AttributeLabelInfo';
|
|
5
|
+
export { AttributeValue, type AttributeValueProps } from './AttributeValue';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Attribute } from "./Attribute.js";
|
|
2
|
+
import { AttributeLabel } from "./AttributeLabel.js";
|
|
3
|
+
import { AttributeLabelDescription } from "./AttributeLabelDescription.js";
|
|
4
|
+
import { AttributeLabelInfo } from "./AttributeLabelInfo.js";
|
|
5
|
+
import { AttributeValue } from "./AttributeValue.js";
|
|
6
|
+
export { Attribute, AttributeLabel, AttributeLabelDescription, AttributeLabelInfo, AttributeValue };
|
|
@@ -7,7 +7,7 @@ const CodeSnippetActions = ({ className, ref, ...props })=>{
|
|
|
7
7
|
ref: ref,
|
|
8
8
|
"data-slot": "code-snippet-actions",
|
|
9
9
|
"data-testid": testId,
|
|
10
|
-
className: cn('flex items-center gap-4 ml-auto px-6 rounded-tr-6', className),
|
|
10
|
+
className: cn('flex items-center gap-4 ml-auto px-6 rounded-tr-6 code-snippet-bg', className),
|
|
11
11
|
...props
|
|
12
12
|
});
|
|
13
13
|
};
|
|
@@ -1,57 +1,62 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useTestId } from "../../utils/testId.js";
|
|
3
|
-
import { MIN_HIDDEN_LINES_THRESHOLD } from "./CodeSnippetContext.js";
|
|
4
3
|
import { useCodeSnippet } from "./hooks/index.js";
|
|
5
4
|
import { CodeContent, CodeLine, TokenizedCodeLine } from "./internal/index.js";
|
|
5
|
+
import { FoldSummaryLine } from "./internal/FoldSummaryLine.js";
|
|
6
6
|
import { SIZE_LINE_HEIGHT_CLASSES } from "./lib/lineStyles.js";
|
|
7
7
|
import { splitTextByRanges } from "./lib/lineUtils.js";
|
|
8
8
|
const CodeSnippetCode = ({ className, ...props })=>{
|
|
9
9
|
const testId = useTestId('code');
|
|
10
|
-
const { code, tokens, isLoading, wrapLines,
|
|
10
|
+
const { code, tokens, isLoading, wrapLines, lines, size, inlineGutter, showLineNumbers, visibleDisplayItems, toggleFold } = useCodeSnippet();
|
|
11
11
|
const lineHeightClass = SIZE_LINE_HEIGHT_CLASSES[size];
|
|
12
|
-
const
|
|
13
|
-
|
|
12
|
+
const renderFoldSummary = (item)=>/*#__PURE__*/ jsx(FoldSummaryLine, {
|
|
13
|
+
fold: item.fold,
|
|
14
|
+
lineCount: item.lineCount,
|
|
15
|
+
lineHeightClass: lineHeightClass,
|
|
16
|
+
onToggle: ()=>toggleFold(item.fold.id)
|
|
17
|
+
}, `fold-${item.fold.id}`);
|
|
14
18
|
if (isLoading || !tokens) {
|
|
15
19
|
const codeLines = code.split('\n');
|
|
16
|
-
const visibleLines = shouldClip ? codeLines.slice(0, maxLines) : codeLines;
|
|
17
20
|
return /*#__PURE__*/ jsx(CodeContent, {
|
|
18
21
|
wrapLines: wrapLines,
|
|
19
22
|
className: className,
|
|
20
23
|
...props,
|
|
21
24
|
"data-testid": testId,
|
|
22
|
-
children:
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
+
children: visibleDisplayItems.map((item)=>{
|
|
26
|
+
if ('fold-summary' === item.type) return renderFoldSummary(item);
|
|
27
|
+
const line = codeLines[item.index] ?? '';
|
|
28
|
+
const lineConfig = lines.get(item.lineNumber);
|
|
25
29
|
const ranges = lineConfig?.ranges;
|
|
26
30
|
const hasRanges = ranges && ranges.length > 0;
|
|
27
31
|
return /*#__PURE__*/ jsx(CodeLine, {
|
|
28
32
|
lineConfig: lineConfig,
|
|
29
33
|
lineHeightClass: lineHeightClass,
|
|
30
34
|
showInlineGutter: inlineGutter,
|
|
31
|
-
lineNumber: showLineNumbers ? lineNumber : void 0,
|
|
35
|
+
lineNumber: showLineNumbers ? item.lineNumber : void 0,
|
|
32
36
|
children: hasRanges ? splitTextByRanges(line, ranges, lineConfig?.color).map((segment, i)=>/*#__PURE__*/ jsx("span", {
|
|
33
37
|
className: segment.rangeColor,
|
|
34
38
|
children: segment.content
|
|
35
39
|
}, i)) : line
|
|
36
|
-
}, lineNumber);
|
|
40
|
+
}, item.lineNumber);
|
|
37
41
|
})
|
|
38
42
|
});
|
|
39
43
|
}
|
|
40
|
-
const visibleTokens = shouldClip ? tokens.slice(0, maxLines) : tokens;
|
|
41
44
|
return /*#__PURE__*/ jsx(CodeContent, {
|
|
42
45
|
wrapLines: wrapLines,
|
|
43
46
|
className: className,
|
|
44
47
|
...props,
|
|
45
48
|
"data-testid": testId,
|
|
46
|
-
children:
|
|
47
|
-
|
|
49
|
+
children: visibleDisplayItems.map((item)=>{
|
|
50
|
+
if ('fold-summary' === item.type) return renderFoldSummary(item);
|
|
51
|
+
const lineTokens = tokens[item.index];
|
|
52
|
+
if (!lineTokens) return null;
|
|
48
53
|
return /*#__PURE__*/ jsx(TokenizedCodeLine, {
|
|
49
54
|
tokens: lineTokens,
|
|
50
|
-
lineConfig: lines.get(lineNumber),
|
|
55
|
+
lineConfig: lines.get(item.lineNumber),
|
|
51
56
|
lineHeightClass: lineHeightClass,
|
|
52
57
|
showInlineGutter: inlineGutter,
|
|
53
|
-
lineNumber: showLineNumbers ? lineNumber : void 0
|
|
54
|
-
}, lineNumber);
|
|
58
|
+
lineNumber: showLineNumbers ? item.lineNumber : void 0
|
|
59
|
+
}, item.lineNumber);
|
|
55
60
|
})
|
|
56
61
|
});
|
|
57
62
|
};
|
|
@@ -7,21 +7,22 @@ import { CodeSnippetContext } from "./CodeSnippetContext.js";
|
|
|
7
7
|
import { useCodeSnippet } from "./hooks/index.js";
|
|
8
8
|
import { CodeSnippetHighlights } from "./internal/CodeSnippetHighlights.js";
|
|
9
9
|
import { ColorStickColumn } from "./internal/ColorStickColumn.js";
|
|
10
|
+
import { FoldColumn } from "./internal/FoldColumn.js";
|
|
10
11
|
import { PrefixColumn } from "./internal/PrefixColumn.js";
|
|
11
12
|
import { SIZE_LINE_HEIGHT_CLASSES } from "./lib/lineStyles.js";
|
|
12
13
|
const CodeSnippetContent = ({ className, children, nativeScroll = false, ...props })=>{
|
|
13
14
|
const testId = useTestId('content');
|
|
14
15
|
const context = useCodeSnippet();
|
|
15
|
-
const { wrapLines, lines,
|
|
16
|
+
const { wrapLines, lines, visibleDisplayItems, folds, size } = context;
|
|
17
|
+
const hasFolds = folds.length > 0;
|
|
16
18
|
const hasHighlights = Array.from(lines.values()).some((config)=>null != config.color);
|
|
17
19
|
const hasAnyPrefix = Array.from(lines.values()).some((config)=>null != config.prefix);
|
|
18
|
-
const lineCount = totalLines;
|
|
19
20
|
const lineHeightClass = SIZE_LINE_HEIGHT_CLASSES[size];
|
|
20
21
|
const childrenArray = Children.toArray(children);
|
|
21
22
|
const lineNumbersElement = childrenArray.find((child)=>/*#__PURE__*/ isValidElement(child) && child.type?.displayName === 'CodeSnippetLineNumbers');
|
|
22
23
|
const otherChildren = childrenArray.filter((child)=>!/*#__PURE__*/ isValidElement(child) || child.type?.displayName !== 'CodeSnippetLineNumbers');
|
|
23
24
|
const hasLineNumbers = Boolean(lineNumbersElement);
|
|
24
|
-
const needsGutterElements = hasHighlights || hasLineNumbers || hasAnyPrefix;
|
|
25
|
+
const needsGutterElements = hasHighlights || hasLineNumbers || hasAnyPrefix || hasFolds;
|
|
25
26
|
const useInlineGutter = wrapLines && needsGutterElements;
|
|
26
27
|
const hasGutter = !wrapLines && needsGutterElements;
|
|
27
28
|
const overriddenContext = useMemo(()=>({
|
|
@@ -39,18 +40,17 @@ const CodeSnippetContent = ({ className, children, nativeScroll = false, ...prop
|
|
|
39
40
|
!wrapLines && hasHighlights && /*#__PURE__*/ jsx(CodeSnippetHighlights, {}),
|
|
40
41
|
hasGutter && /*#__PURE__*/ jsxs("div", {
|
|
41
42
|
"data-slot": "code-snippet-gutter",
|
|
42
|
-
className: "sticky left-0 z-20 flex shrink-0 py-8 -my-8 mr-8
|
|
43
|
+
className: "sticky left-0 z-20 flex shrink-0 py-8 -my-8 mr-8 code-snippet-bg [contain:paint]",
|
|
43
44
|
children: [
|
|
44
45
|
hasHighlights && /*#__PURE__*/ jsx(ColorStickColumn, {
|
|
45
|
-
|
|
46
|
-
startingLineNumber: startingLineNumber,
|
|
46
|
+
visibleDisplayItems: visibleDisplayItems,
|
|
47
47
|
lines: lines,
|
|
48
48
|
lineHeightClass: lineHeightClass
|
|
49
49
|
}),
|
|
50
50
|
lineNumbersElement,
|
|
51
|
+
hasFolds && /*#__PURE__*/ jsx(FoldColumn, {}),
|
|
51
52
|
hasAnyPrefix && /*#__PURE__*/ jsx(PrefixColumn, {
|
|
52
|
-
|
|
53
|
-
startingLineNumber: startingLineNumber,
|
|
53
|
+
visibleDisplayItems: visibleDisplayItems,
|
|
54
54
|
lines: lines,
|
|
55
55
|
lineHeightClass: lineHeightClass
|
|
56
56
|
})
|
|
@@ -68,14 +68,14 @@ const CodeSnippetContent = ({ className, children, nativeScroll = false, ...prop
|
|
|
68
68
|
if (nativeScroll) return /*#__PURE__*/ jsx("div", {
|
|
69
69
|
"data-slot": "code-snippet-content",
|
|
70
70
|
"data-testid": testId,
|
|
71
|
-
className: cn('min-h-0', wrapLines ? 'overflow-y-auto overflow-x-hidden' : 'overflow-auto', className),
|
|
71
|
+
className: cn('min-h-0 overscroll-none', wrapLines ? 'overflow-y-auto overflow-x-hidden' : 'overflow-auto', className),
|
|
72
72
|
...props,
|
|
73
73
|
children: innerContent
|
|
74
74
|
});
|
|
75
75
|
return /*#__PURE__*/ jsx("div", {
|
|
76
76
|
"data-slot": "code-snippet-content",
|
|
77
77
|
"data-testid": testId,
|
|
78
|
-
className: cn('min-h-0', className),
|
|
78
|
+
className: cn('min-h-0 [&_[data-part=viewport]]:overscroll-none', className),
|
|
79
79
|
...props,
|
|
80
80
|
children: /*#__PURE__*/ jsxs(ScrollArea, {
|
|
81
81
|
children: [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import type { SyntaxAdapter, Token } from './adapters/types';
|
|
3
|
+
import type { DisplayItem, FoldRegion } from './lib/foldUtils';
|
|
3
4
|
export type CodeSnippetSize = 'sm' | 'md' | 'lg';
|
|
4
5
|
export type LineColor = 'danger' | 'warning' | 'info' | 'success' | 'brand' | 'ai' | 'neutral';
|
|
5
6
|
export type LineTextStyle = 'regular' | 'medium' | 'italic';
|
|
@@ -39,6 +40,13 @@ export type CodeSnippetContextValue<TLanguage extends string = string> = {
|
|
|
39
40
|
showLineNumbers: boolean;
|
|
40
41
|
lines: Map<number, LineConfig>;
|
|
41
42
|
totalLines: number;
|
|
43
|
+
/** All display items (post-fold, pre-clip). Used for ShowMore counting. */
|
|
44
|
+
displayItems: DisplayItem[];
|
|
45
|
+
/** Display items clipped to maxLines. All rendering components should iterate this. */
|
|
46
|
+
visibleDisplayItems: DisplayItem[];
|
|
47
|
+
folds: FoldRegion[];
|
|
48
|
+
collapsedFolds: Set<string>;
|
|
49
|
+
toggleFold: (foldId: string) => void;
|
|
42
50
|
isExpanded: boolean;
|
|
43
51
|
maxLines: number;
|
|
44
52
|
isFullscreen: boolean;
|
|
@@ -5,7 +5,7 @@ import { useCodeSnippet } from "./hooks/index.js";
|
|
|
5
5
|
import { LINE_COLOR_STYLES, SIZE_LINE_HEIGHT_CLASSES } from "./lib/lineStyles.js";
|
|
6
6
|
const CodeSnippetLineNumbers = ({ className, ...props })=>{
|
|
7
7
|
const testId = useTestId('line-numbers');
|
|
8
|
-
const { tokens,
|
|
8
|
+
const { tokens, visibleDisplayItems, lines, size } = useCodeSnippet();
|
|
9
9
|
const lineHeightClass = SIZE_LINE_HEIGHT_CLASSES[size];
|
|
10
10
|
if (!tokens) return null;
|
|
11
11
|
return /*#__PURE__*/ jsx("div", {
|
|
@@ -13,14 +13,17 @@ const CodeSnippetLineNumbers = ({ className, ...props })=>{
|
|
|
13
13
|
"data-testid": testId,
|
|
14
14
|
className: cn('flex flex-col text-text-secondary select-none text-right', className),
|
|
15
15
|
...props,
|
|
16
|
-
children:
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
children: visibleDisplayItems.map((item)=>{
|
|
17
|
+
if ('fold-summary' === item.type) return /*#__PURE__*/ jsx("span", {
|
|
18
|
+
className: cn(lineHeightClass, 'px-8'),
|
|
19
|
+
children: item.fold.startLine
|
|
20
|
+
}, `fold-${item.fold.id}`);
|
|
21
|
+
const lineConfig = lines.get(item.lineNumber);
|
|
19
22
|
const colorStyles = lineConfig?.color ? LINE_COLOR_STYLES[lineConfig.color] : void 0;
|
|
20
23
|
return /*#__PURE__*/ jsx("span", {
|
|
21
|
-
className: cn(lineHeightClass, 'px-8
|
|
22
|
-
children: lineNumber
|
|
23
|
-
}, lineNumber);
|
|
24
|
+
className: cn(lineHeightClass, 'px-8', colorStyles?.text, colorStyles?.bg),
|
|
25
|
+
children: item.lineNumber
|
|
26
|
+
}, item.lineNumber);
|
|
24
27
|
})
|
|
25
28
|
});
|
|
26
29
|
};
|
|
@@ -2,6 +2,7 @@ import type { HTMLAttributes, ReactNode, Ref } from 'react';
|
|
|
2
2
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
3
|
import { type TestableProps } from '../../utils/testId';
|
|
4
4
|
import { type LineConfig } from './CodeSnippetContext';
|
|
5
|
+
import { type FoldRegion } from './lib/foldUtils';
|
|
5
6
|
declare const codeSnippetRootVariants: (props?: ({
|
|
6
7
|
size?: "sm" | "md" | "lg" | null | undefined;
|
|
7
8
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -21,13 +22,15 @@ export type CodeSnippetRootProps<TLanguage extends string = string> = CodeSnippe
|
|
|
21
22
|
wrapLines?: boolean;
|
|
22
23
|
/** Max lines before collapsing (for ShowMore) */
|
|
23
24
|
maxLines?: number;
|
|
25
|
+
/** Foldable regions that can be collapsed/expanded */
|
|
26
|
+
folds?: FoldRegion[];
|
|
24
27
|
/** Callback when code is copied */
|
|
25
28
|
onCopy?: (code: string) => void;
|
|
26
29
|
/** Child components */
|
|
27
30
|
children?: ReactNode;
|
|
28
31
|
};
|
|
29
32
|
export declare const CodeSnippetRoot: {
|
|
30
|
-
<TLanguage extends string = string>({ code, language, size, lines, startingLineNumber, wrapLines: initialWrapLines, maxLines, onCopy, className, children, "data-testid": testId, ...props }: CodeSnippetRootProps<TLanguage>): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
<TLanguage extends string = string>({ code, language, size, lines, startingLineNumber, wrapLines: initialWrapLines, maxLines, folds: foldsProp, onCopy, className, children, "data-testid": testId, ...props }: CodeSnippetRootProps<TLanguage>): import("react/jsx-runtime").JSX.Element;
|
|
31
34
|
displayName: string;
|
|
32
35
|
};
|
|
33
36
|
export {};
|
|
@@ -5,10 +5,11 @@ import { cva } from "class-variance-authority";
|
|
|
5
5
|
import { cn } from "../../utils/cn.js";
|
|
6
6
|
import { TestIdProvider } from "../../utils/testId.js";
|
|
7
7
|
import { plainAdapter } from "./adapters/plain.js";
|
|
8
|
-
import { CodeSnippetContext } from "./CodeSnippetContext.js";
|
|
8
|
+
import { CodeSnippetContext, MIN_HIDDEN_LINES_THRESHOLD } from "./CodeSnippetContext.js";
|
|
9
9
|
import { useAdapter } from "./hooks/index.js";
|
|
10
10
|
import { ShowMoreButton } from "./internal/ShowMoreButton.js";
|
|
11
|
-
|
|
11
|
+
import { buildDisplayItems, validateFolds } from "./lib/foldUtils.js";
|
|
12
|
+
const codeSnippetRootVariants = cva("relative code-snippet-bg rounded-6 font-mono text-syntax-no-syntax overflow-hidden flex flex-col [&::selection]:bg-[var(--color-syntax-highlight-selected-highlight)] [&::selection]:text-[var(--color-syntax-highlight-selected-code)] [&_*::selection]:bg-[var(--color-syntax-highlight-selected-highlight)] [&_*::selection]:text-[var(--color-syntax-highlight-selected-code)] [&>[data-slot=code-snippet-actions]]:absolute [&>[data-slot=code-snippet-actions]]:right-0 [&>[data-slot=code-snippet-actions]]:top-0 [&>[data-slot=code-snippet-actions]]:z-30 [&>[data-slot=code-snippet-actions]]:p-6 [&>[data-slot=code-snippet-actions]]:rounded-br-6 [&>[data-slot=code-snippet-actions]]:rounded-tl-6", {
|
|
12
13
|
variants: {
|
|
13
14
|
size: {
|
|
14
15
|
sm: 'text-xs leading-sm',
|
|
@@ -20,7 +21,8 @@ const codeSnippetRootVariants = cva("relative bg-component-code-snippet-bg round
|
|
|
20
21
|
size: 'sm'
|
|
21
22
|
}
|
|
22
23
|
});
|
|
23
|
-
const
|
|
24
|
+
const EMPTY_LINES = {};
|
|
25
|
+
const CodeSnippetRoot = ({ code, language = 'text', size = 'sm', lines = EMPTY_LINES, startingLineNumber = 1, wrapLines: initialWrapLines = false, maxLines = 0, folds: foldsProp, onCopy, className, children, 'data-testid': testId, ...props })=>{
|
|
24
26
|
const adapterContext = useAdapter();
|
|
25
27
|
const [wrapLines, setWrapLines] = useState(initialWrapLines);
|
|
26
28
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
@@ -79,6 +81,45 @@ const CodeSnippetRoot = ({ code, language = 'text', size = 'sm', lines = {}, sta
|
|
|
79
81
|
onCopy
|
|
80
82
|
]);
|
|
81
83
|
const totalLines = tokens?.length ?? code.split('\n').length;
|
|
84
|
+
const validatedFolds = useMemo(()=>foldsProp ? validateFolds(foldsProp, totalLines, startingLineNumber) : [], [
|
|
85
|
+
foldsProp,
|
|
86
|
+
totalLines,
|
|
87
|
+
startingLineNumber
|
|
88
|
+
]);
|
|
89
|
+
const computeCollapsedFolds = useCallback((folds)=>{
|
|
90
|
+
if (!folds) return new Set();
|
|
91
|
+
return new Set(folds.filter((f)=>false !== f.defaultCollapsed).map((f)=>f.id));
|
|
92
|
+
}, []);
|
|
93
|
+
const [collapsedFolds, setCollapsedFolds] = useState(()=>computeCollapsedFolds(foldsProp));
|
|
94
|
+
useEffect(()=>{
|
|
95
|
+
setCollapsedFolds(computeCollapsedFolds(foldsProp));
|
|
96
|
+
}, [
|
|
97
|
+
foldsProp,
|
|
98
|
+
computeCollapsedFolds
|
|
99
|
+
]);
|
|
100
|
+
const toggleFold = useCallback((foldId)=>{
|
|
101
|
+
setCollapsedFolds((prev)=>{
|
|
102
|
+
const next = new Set(prev);
|
|
103
|
+
if (next.has(foldId)) next.delete(foldId);
|
|
104
|
+
else next.add(foldId);
|
|
105
|
+
return next;
|
|
106
|
+
});
|
|
107
|
+
}, []);
|
|
108
|
+
const displayItems = useMemo(()=>buildDisplayItems(totalLines, validatedFolds, collapsedFolds, startingLineNumber), [
|
|
109
|
+
totalLines,
|
|
110
|
+
validatedFolds,
|
|
111
|
+
collapsedFolds,
|
|
112
|
+
startingLineNumber
|
|
113
|
+
]);
|
|
114
|
+
const visibleDisplayItems = useMemo(()=>{
|
|
115
|
+
const hiddenRows = displayItems.length - maxLines;
|
|
116
|
+
const shouldClip = maxLines > 0 && !isExpanded && hiddenRows >= MIN_HIDDEN_LINES_THRESHOLD;
|
|
117
|
+
return shouldClip ? displayItems.slice(0, maxLines) : displayItems;
|
|
118
|
+
}, [
|
|
119
|
+
displayItems,
|
|
120
|
+
maxLines,
|
|
121
|
+
isExpanded
|
|
122
|
+
]);
|
|
82
123
|
const contextValue = useMemo(()=>({
|
|
83
124
|
code,
|
|
84
125
|
language,
|
|
@@ -94,6 +135,11 @@ const CodeSnippetRoot = ({ code, language = 'text', size = 'sm', lines = {}, sta
|
|
|
94
135
|
v
|
|
95
136
|
])),
|
|
96
137
|
totalLines,
|
|
138
|
+
displayItems,
|
|
139
|
+
visibleDisplayItems,
|
|
140
|
+
folds: validatedFolds,
|
|
141
|
+
collapsedFolds,
|
|
142
|
+
toggleFold,
|
|
97
143
|
isExpanded,
|
|
98
144
|
maxLines,
|
|
99
145
|
isFullscreen,
|
|
@@ -112,6 +158,11 @@ const CodeSnippetRoot = ({ code, language = 'text', size = 'sm', lines = {}, sta
|
|
|
112
158
|
startingLineNumber,
|
|
113
159
|
lines,
|
|
114
160
|
totalLines,
|
|
161
|
+
displayItems,
|
|
162
|
+
visibleDisplayItems,
|
|
163
|
+
validatedFolds,
|
|
164
|
+
collapsedFolds,
|
|
165
|
+
toggleFold,
|
|
115
166
|
isExpanded,
|
|
116
167
|
maxLines,
|
|
117
168
|
isFullscreen,
|
|
@@ -4,7 +4,7 @@ import { cva } from "class-variance-authority";
|
|
|
4
4
|
import { useCopyTooltip } from "../../hooks/index.js";
|
|
5
5
|
import { cn } from "../../utils/cn.js";
|
|
6
6
|
import { Tooltip, TooltipContent, TooltipTrigger } from "../Tooltip/index.js";
|
|
7
|
-
const inlineCodeSnippetVariants = cva("inline-flex items-center
|
|
7
|
+
const inlineCodeSnippetVariants = cva("inline-flex items-center code-snippet-bg rounded-6 font-mono font-normal text-syntax-no-syntax", {
|
|
8
8
|
variants: {
|
|
9
9
|
size: {
|
|
10
10
|
sm: 'text-xs px-4 py-2',
|
|
@@ -16,3 +16,5 @@ export { CodeSnippetTitle, type CodeSnippetTitleProps } from './CodeSnippetTitle
|
|
|
16
16
|
export { CodeSnippetWrapButton, type CodeSnippetWrapButtonProps } from './CodeSnippetWrapButton';
|
|
17
17
|
export { useAdapter, useCodeSnippet } from './hooks';
|
|
18
18
|
export { InlineCodeSnippet, type InlineCodeSnippetProps } from './InlineCodeSnippet';
|
|
19
|
+
export { type FoldRegion } from './lib/foldUtils';
|
|
20
|
+
export { getHttpFolds, HTTP_FOLD_ID, type HttpFoldOptions, type HttpFoldSectionOptions, } from './lib/httpFolds';
|
|
@@ -14,4 +14,5 @@ import { CodeSnippetTitle } from "./CodeSnippetTitle.js";
|
|
|
14
14
|
import { CodeSnippetWrapButton } from "./CodeSnippetWrapButton.js";
|
|
15
15
|
import { useAdapter, useCodeSnippet } from "./hooks/index.js";
|
|
16
16
|
import { InlineCodeSnippet } from "./InlineCodeSnippet.js";
|
|
17
|
-
|
|
17
|
+
import { HTTP_FOLD_ID, getHttpFolds } from "./lib/httpFolds.js";
|
|
18
|
+
export { CodeSnippetActions, CodeSnippetAdapterProvider, CodeSnippetCode, CodeSnippetContent, CodeSnippetCopyButton, CodeSnippetFullscreenButton, CodeSnippetHeader, CodeSnippetLineNumbers, CodeSnippetRoot, CodeSnippetTab, CodeSnippetTabs, CodeSnippetTitle, CodeSnippetWrapButton, HTTP_FOLD_ID, InlineCodeSnippet, getHttpFolds, loadHighlightJsAdapter, loadPrismAdapter, loadShikiAdapter, plainAdapter, useAdapter, useCodeSnippet };
|
|
@@ -3,22 +3,21 @@ import { cn } from "../../../utils/cn.js";
|
|
|
3
3
|
import { useCodeSnippet } from "../hooks/index.js";
|
|
4
4
|
import { LINE_COLOR_STYLES, SIZE_LINE_HEIGHT_CLASSES } from "../lib/lineStyles.js";
|
|
5
5
|
const CodeSnippetHighlights = ()=>{
|
|
6
|
-
const {
|
|
7
|
-
const lineCount = totalLines;
|
|
6
|
+
const { visibleDisplayItems, lines, size } = useCodeSnippet();
|
|
8
7
|
const lineHeightClass = SIZE_LINE_HEIGHT_CLASSES[size];
|
|
9
8
|
return /*#__PURE__*/ jsx("div", {
|
|
10
9
|
"data-slot": "code-snippet-highlights",
|
|
11
10
|
className: "absolute inset-0 z-0 flex flex-col py-8 pointer-events-none",
|
|
12
11
|
"aria-hidden": "true",
|
|
13
|
-
children:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const lineConfig = lines.get(lineNumber);
|
|
12
|
+
children: visibleDisplayItems.map((item)=>{
|
|
13
|
+
if ('fold-summary' === item.type) return /*#__PURE__*/ jsx("div", {
|
|
14
|
+
className: lineHeightClass
|
|
15
|
+
}, `fold-${item.fold.id}`);
|
|
16
|
+
const lineConfig = lines.get(item.lineNumber);
|
|
18
17
|
const colorStyles = lineConfig?.color ? LINE_COLOR_STYLES[lineConfig.color] : null;
|
|
19
18
|
return /*#__PURE__*/ jsx("div", {
|
|
20
19
|
className: cn(lineHeightClass, colorStyles?.bg)
|
|
21
|
-
}, lineNumber);
|
|
20
|
+
}, item.lineNumber);
|
|
22
21
|
})
|
|
23
22
|
});
|
|
24
23
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { FC } from 'react';
|
|
2
2
|
import type { LineConfig } from '../CodeSnippetContext';
|
|
3
|
+
import type { DisplayItem } from '../lib/foldUtils';
|
|
3
4
|
/** Color stick column component - renders color indicators for each line */
|
|
4
5
|
export declare const ColorStickColumn: FC<{
|
|
5
|
-
|
|
6
|
-
startingLineNumber: number;
|
|
6
|
+
visibleDisplayItems: DisplayItem[];
|
|
7
7
|
lines: Map<number, LineConfig>;
|
|
8
8
|
lineHeightClass: string;
|
|
9
9
|
}>;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../../utils/cn.js";
|
|
3
3
|
import { LINE_COLOR_STYLES } from "../lib/lineStyles.js";
|
|
4
|
-
const ColorStickColumn = ({
|
|
4
|
+
const ColorStickColumn = ({ visibleDisplayItems, lines, lineHeightClass })=>/*#__PURE__*/ jsx("div", {
|
|
5
5
|
className: "flex flex-col",
|
|
6
6
|
"data-slot": "code-snippet-color-stick",
|
|
7
|
-
children:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const lineConfig = lines.get(lineNumber);
|
|
7
|
+
children: visibleDisplayItems.map((item)=>{
|
|
8
|
+
if ('fold-summary' === item.type) return /*#__PURE__*/ jsx("span", {
|
|
9
|
+
className: cn(lineHeightClass, 'border-l-2 pl-12 border-transparent')
|
|
10
|
+
}, `fold-${item.fold.id}`);
|
|
11
|
+
const lineConfig = lines.get(item.lineNumber);
|
|
12
12
|
const colorStyles = lineConfig?.color ? LINE_COLOR_STYLES[lineConfig.color] : void 0;
|
|
13
13
|
return /*#__PURE__*/ jsx("span", {
|
|
14
|
-
className: cn(lineHeightClass, 'border-l-2 pl-12',
|
|
15
|
-
}, lineNumber);
|
|
14
|
+
className: cn(lineHeightClass, 'border-l-2 pl-12', colorStyles?.border ?? 'border-transparent', colorStyles?.bg)
|
|
15
|
+
}, item.lineNumber);
|
|
16
16
|
})
|
|
17
17
|
});
|
|
18
18
|
export { ColorStickColumn };
|