@traefik-labs/faency 12.1.0 → 12.2.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/CodeBlock/CodeBlock.cjs +104 -44
- package/dist/components/CodeBlock/CodeBlock.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.js +106 -46
- package/dist/components/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.themes.cjs +18 -0
- package/dist/components/CodeBlock/CodeBlock.themes.cjs.map +1 -0
- package/dist/components/CodeBlock/CodeBlock.themes.js +19 -0
- package/dist/components/CodeBlock/CodeBlock.themes.js.map +1 -0
- package/dist/components/CodeBlock/CodeBlock.vanilla.cjs +111 -56
- package/dist/components/CodeBlock/CodeBlock.vanilla.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.vanilla.css.cjs +12 -10
- package/dist/components/CodeBlock/CodeBlock.vanilla.css.cjs.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.vanilla.css.js +13 -11
- package/dist/components/CodeBlock/CodeBlock.vanilla.css.js.map +1 -1
- package/dist/components/CodeBlock/CodeBlock.vanilla.js +114 -59
- package/dist/components/CodeBlock/CodeBlock.vanilla.js.map +1 -1
- package/dist/faency.css +1826 -1800
- package/dist/index.d.ts +104 -6
- package/dist/stitches.config.cjs +4 -0
- package/dist/stitches.config.cjs.map +1 -1
- package/dist/stitches.config.js +19 -15
- package/dist/stitches.config.js.map +1 -1
- package/dist/styles/themes.css.cjs +1 -0
- package/dist/styles/themes.css.cjs.map +1 -1
- package/dist/styles/themes.css.js +1 -0
- package/dist/styles/themes.css.js.map +1 -1
- package/package.json +3 -1
|
@@ -14,7 +14,6 @@ const Pre = stitches_config.styled("pre", {
|
|
|
14
14
|
borderRadius: "$2",
|
|
15
15
|
overflow: "auto",
|
|
16
16
|
border: "1px solid $colors$deepBlue3",
|
|
17
|
-
position: "relative",
|
|
18
17
|
fontSize: "$2",
|
|
19
18
|
lineHeight: 1.6,
|
|
20
19
|
variants: {
|
|
@@ -25,82 +24,143 @@ const Pre = stitches_config.styled("pre", {
|
|
|
25
24
|
});
|
|
26
25
|
const CopyButtonWrapper = stitches_config.styled("div", {
|
|
27
26
|
position: "absolute",
|
|
28
|
-
right: "$4",
|
|
29
27
|
zIndex: 1,
|
|
30
28
|
variants: {
|
|
31
|
-
|
|
32
|
-
top: { top: "$2" },
|
|
33
|
-
|
|
29
|
+
position: {
|
|
30
|
+
top: { top: "$2", right: "$3" },
|
|
31
|
+
topLeft: { top: "$2", left: "$3" },
|
|
32
|
+
bottomRight: { bottom: "$2", right: "$3" },
|
|
33
|
+
bottomLeft: { bottom: "$2", left: "$3" }
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
defaultVariants: {
|
|
37
|
-
|
|
37
|
+
position: "top"
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
const CodeBlock = React.forwardRef(
|
|
41
41
|
({
|
|
42
|
-
lang,
|
|
42
|
+
lang = "text",
|
|
43
43
|
code,
|
|
44
44
|
copyable = false,
|
|
45
45
|
copyText,
|
|
46
46
|
copiedText,
|
|
47
|
-
copyButtonAlign = "top",
|
|
47
|
+
copyButtonAlign = "top right",
|
|
48
|
+
onCopy,
|
|
48
49
|
noBorder,
|
|
49
50
|
wrapText = false,
|
|
50
51
|
colorScheme,
|
|
51
52
|
maxHeight = 424,
|
|
52
53
|
css,
|
|
54
|
+
style,
|
|
55
|
+
className,
|
|
53
56
|
...props
|
|
54
57
|
}, ref) => {
|
|
55
58
|
const systemScheme = colorSchemeContext.useColorScheme();
|
|
56
59
|
const resolvedScheme = colorScheme ?? systemScheme;
|
|
57
60
|
const prismTheme = resolvedScheme === "dark" ? prismReactRenderer.themes.nightOwl : prismReactRenderer.themes.nightOwlLight;
|
|
61
|
+
const isBottom = copyButtonAlign.includes("bottom");
|
|
62
|
+
const isLeft = copyButtonAlign.includes("left");
|
|
63
|
+
const buttonPosition = isBottom ? isLeft ? "bottomLeft" : "bottomRight" : isLeft ? "topLeft" : "top";
|
|
58
64
|
const [copied, setCopied] = React.useState(false);
|
|
65
|
+
const preRef = React.useRef(
|
|
66
|
+
null
|
|
67
|
+
);
|
|
68
|
+
const buttonWrapperRef = React.useRef(null);
|
|
69
|
+
const setPreRef = React.useCallback(
|
|
70
|
+
(node) => {
|
|
71
|
+
preRef.current = node;
|
|
72
|
+
if (typeof ref === "function") ref(node);
|
|
73
|
+
else if (ref) ref.current = node;
|
|
74
|
+
},
|
|
75
|
+
[ref]
|
|
76
|
+
);
|
|
77
|
+
React.useLayoutEffect(() => {
|
|
78
|
+
if (!copyable) return;
|
|
79
|
+
const pre = preRef.current;
|
|
80
|
+
const wrapper = buttonWrapperRef.current;
|
|
81
|
+
if (!pre || !wrapper) return;
|
|
82
|
+
const isBottomAlign = isBottom;
|
|
83
|
+
const borderH = noBorder ? 0 : 2;
|
|
84
|
+
const update = () => {
|
|
85
|
+
if (!isLeft) {
|
|
86
|
+
const vScrollbar = Math.max(0, pre.offsetWidth - pre.clientWidth - borderH);
|
|
87
|
+
wrapper.style.right = `${16 + vScrollbar}px`;
|
|
88
|
+
}
|
|
89
|
+
if (isBottomAlign) {
|
|
90
|
+
const hScrollbar = Math.max(0, pre.offsetHeight - pre.clientHeight - borderH);
|
|
91
|
+
wrapper.style.bottom = `${8 + hScrollbar}px`;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
update();
|
|
95
|
+
const observer = new ResizeObserver(update);
|
|
96
|
+
observer.observe(pre);
|
|
97
|
+
return () => observer.disconnect();
|
|
98
|
+
}, [copyable, isBottom, isLeft, noBorder]);
|
|
59
99
|
const handleCopy = async () => {
|
|
60
100
|
try {
|
|
61
101
|
await navigator.clipboard.writeText(code);
|
|
62
102
|
setCopied(true);
|
|
103
|
+
onCopy?.();
|
|
63
104
|
setTimeout(() => setCopied(false), 1500);
|
|
64
105
|
} catch {
|
|
65
106
|
}
|
|
66
107
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
const copyButton = copyable ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
109
|
+
Button.Button,
|
|
110
|
+
{
|
|
111
|
+
variant: "secondary",
|
|
112
|
+
ghost: true,
|
|
113
|
+
size: "small",
|
|
114
|
+
type: "button",
|
|
115
|
+
onClick: handleCopy,
|
|
116
|
+
css: {
|
|
117
|
+
color: "$hiContrast",
|
|
118
|
+
gap: "$1",
|
|
119
|
+
backgroundColor: "$codeBlockCopyButtonBg",
|
|
120
|
+
height: "32px"
|
|
121
|
+
},
|
|
122
|
+
children: [
|
|
123
|
+
/* @__PURE__ */ jsxRuntime.jsx(AccessibleIcon.AccessibleIcon, { label: copied ? "Copied" : "Copy", children: copied ? /* @__PURE__ */ jsxRuntime.jsx(reactIcons.CheckIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(reactIcons.CopyIcon, {}) }),
|
|
124
|
+
copied ? copiedText : copyText
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
) : null;
|
|
128
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
129
|
+
prismReactRenderer.Highlight,
|
|
130
|
+
{
|
|
131
|
+
theme: prismTheme,
|
|
132
|
+
code,
|
|
133
|
+
language: prismReactRenderer.Prism.languages[lang] != null ? lang : "text",
|
|
134
|
+
children: ({
|
|
135
|
+
className: highlightClass,
|
|
136
|
+
style: highlightStyle,
|
|
137
|
+
tokens,
|
|
138
|
+
getLineProps,
|
|
139
|
+
getTokenProps
|
|
140
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs(Box.Box, { css: { position: "relative", ...css }, children: [
|
|
141
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
142
|
+
Pre,
|
|
94
143
|
{
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
144
|
+
ref: setPreRef,
|
|
145
|
+
className: [highlightClass, className].filter(Boolean).join(" "),
|
|
146
|
+
style: { maxHeight, ...highlightStyle, backgroundColor: "inherit", ...style },
|
|
147
|
+
noBorder,
|
|
148
|
+
...props,
|
|
149
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Box.Box, { css: { p: "$4", ...copyable && isBottom ? { pb: "$7" } : {} }, children: tokens.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
150
|
+
"div",
|
|
151
|
+
{
|
|
152
|
+
...getLineProps({ line }),
|
|
153
|
+
style: wrapText ? { whiteSpace: "pre-wrap", wordBreak: "break-all" } : void 0,
|
|
154
|
+
children: line.map((token, key) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...getTokenProps({ token }) }, key))
|
|
155
|
+
},
|
|
156
|
+
i
|
|
157
|
+
)) })
|
|
158
|
+
}
|
|
159
|
+
),
|
|
160
|
+
copyButton && /* @__PURE__ */ jsxRuntime.jsx(CopyButtonWrapper, { ref: buttonWrapperRef, position: buttonPosition, children: copyButton })
|
|
161
|
+
] })
|
|
162
|
+
}
|
|
163
|
+
);
|
|
104
164
|
}
|
|
105
165
|
);
|
|
106
166
|
CodeBlock.displayName = "CodeBlock";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.cjs","sources":["../../../components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["import { CheckIcon, CopyIcon } from '@radix-ui/react-icons';\nimport { Highlight, Language, themes } from 'prism-react-renderer';\nimport React, { ComponentProps, forwardRef, useState } from 'react';\n\nimport { CSS, styled } from '../../stitches.config';\nimport { AccessibleIcon } from '../AccessibleIcon';\nimport { Box } from '../Box';\nimport { Button } from '../Button';\nimport { useColorScheme } from '../colorSchemeContext';\n\nconst Pre = styled('pre', {\n m: 0,\n borderRadius: '$2',\n overflow: 'auto',\n border: '1px solid $colors$deepBlue3',\n position: 'relative',\n fontSize: '$2',\n lineHeight: 1.6,\n\n variants: {\n noBorder: {\n true: { border: 'none' },\n },\n },\n});\n\nconst CopyButtonWrapper = styled('div', {\n position: 'absolute',\n right: '$4',\n zIndex: 1,\n\n variants: {\n align: {\n top: { top: '$2' },\n bottom: { bottom: '$2' },\n },\n },\n\n defaultVariants: {\n align: 'top',\n },\n});\n\nexport type CodeBlockProps = {\n lang: Language;\n code: string;\n copyable?: boolean;\n copyText?: string;\n copiedText?: string;\n copyButtonAlign?: 'top' | 'bottom';\n noBorder?: boolean;\n wrapText?: boolean;\n colorScheme?: 'light' | 'dark';\n maxHeight?: number | string;\n css?: CSS;\n} & Omit<ComponentProps<typeof Pre>, 'css'>;\n\nexport const CodeBlock = forwardRef<HTMLPreElement, CodeBlockProps>(\n (\n {\n lang,\n code,\n copyable = false,\n copyText,\n copiedText,\n copyButtonAlign = 'top',\n noBorder,\n wrapText = false,\n colorScheme,\n maxHeight = 424,\n css,\n ...props\n },\n ref,\n ) => {\n const systemScheme = useColorScheme();\n const resolvedScheme = colorScheme ?? systemScheme;\n const prismTheme = resolvedScheme === 'dark' ? themes.nightOwl : themes.nightOwlLight;\n\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n } catch {\n // clipboard write failed (e.g. permission denied) — leave UI unchanged\n }\n };\n\n return (\n <Highlight theme={prismTheme} code={code} language={lang}>\n {({ className, style, tokens, getLineProps, getTokenProps }) => (\n <Box css={{ position: 'relative', ...css }}>\n {copyable && (\n <CopyButtonWrapper align={copyButtonAlign}>\n <Button\n variant=\"secondary\"\n ghost\n size=\"small\"\n type=\"button\"\n onClick={handleCopy}\n css={{ color: '$hiContrast', gap: '$1' }}\n >\n <AccessibleIcon label={copied ? 'Copied' : 'Copy'}>\n {copied ? <CheckIcon /> : <CopyIcon />}\n </AccessibleIcon>\n {copied ? copiedText : copyText}\n </Button>\n </CopyButtonWrapper>\n )}\n <Pre\n ref={ref}\n className={className}\n style={{ ...style, backgroundColor: 'transparent' }}\n noBorder={noBorder}\n css={{ maxHeight }}\n {...props}\n >\n <Box css={{ p: '$4' }}>\n {tokens.map((line, i) => (\n <div\n key={i}\n {...getLineProps({ line })}\n style={wrapText ? { whiteSpace: 'normal' } : undefined}\n >\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token })} />\n ))}\n </div>\n ))}\n </Box>\n </Pre>\n </Box>\n )}\n </Highlight>\n );\n },\n);\n\nCodeBlock.displayName = 'CodeBlock';\n"],"names":["styled","forwardRef","useColorScheme","themes","useState","jsx","Highlight","jsxs","Box","Button","AccessibleIcon","CheckIcon","CopyIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeBlock.cjs","sources":["../../../components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["import './prism-extend';\n\nimport { CheckIcon, CopyIcon } from '@radix-ui/react-icons';\nimport { Highlight, Language, Prism, themes } from 'prism-react-renderer';\nimport React, {\n ComponentProps,\n forwardRef,\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { CSS, styled } from '../../stitches.config';\nimport { AccessibleIcon } from '../AccessibleIcon';\nimport { Box } from '../Box';\nimport { Button } from '../Button';\nimport { useColorScheme } from '../colorSchemeContext';\nimport type { CodeBlockCopyButtonAlign, CodeBlockLanguage } from './index';\n\nconst Pre = styled('pre', {\n m: 0,\n borderRadius: '$2',\n overflow: 'auto',\n border: '1px solid $colors$deepBlue3',\n fontSize: '$2',\n lineHeight: 1.6,\n\n variants: {\n noBorder: {\n true: { border: 'none' },\n },\n },\n});\n\nconst CopyButtonWrapper = styled('div', {\n position: 'absolute',\n zIndex: 1,\n variants: {\n position: {\n top: { top: '$2', right: '$3' },\n topLeft: { top: '$2', left: '$3' },\n bottomRight: { bottom: '$2', right: '$3' },\n bottomLeft: { bottom: '$2', left: '$3' },\n },\n },\n\n defaultVariants: {\n position: 'top',\n },\n});\n\nexport type CodeBlockProps = {\n lang?: CodeBlockLanguage;\n code: string;\n copyable?: boolean;\n copyText?: string;\n copiedText?: string;\n copyButtonAlign?: CodeBlockCopyButtonAlign;\n onCopy?: () => void;\n noBorder?: boolean;\n wrapText?: boolean;\n colorScheme?: 'light' | 'dark';\n maxHeight?: number | string;\n css?: CSS;\n} & Omit<ComponentProps<typeof Pre>, 'css'>;\n\nexport const CodeBlock = forwardRef<HTMLPreElement, CodeBlockProps>(\n (\n {\n lang = 'text',\n code,\n copyable = false,\n copyText,\n copiedText,\n copyButtonAlign = 'top right',\n onCopy,\n noBorder,\n wrapText = false,\n colorScheme,\n maxHeight = 424,\n css,\n style,\n className,\n ...props\n },\n ref,\n ) => {\n const systemScheme = useColorScheme();\n const resolvedScheme = colorScheme ?? systemScheme;\n const prismTheme = resolvedScheme === 'dark' ? themes.nightOwl : themes.nightOwlLight;\n\n const isBottom = copyButtonAlign.includes('bottom');\n const isLeft = copyButtonAlign.includes('left');\n const buttonPosition = isBottom\n ? isLeft\n ? 'bottomLeft'\n : 'bottomRight'\n : isLeft\n ? 'topLeft'\n : 'top';\n\n const [copied, setCopied] = useState(false);\n\n const preRef = useRef<HTMLPreElement | null>(\n null,\n ) as React.MutableRefObject<HTMLPreElement | null>;\n const buttonWrapperRef = useRef<HTMLDivElement>(null);\n\n const setPreRef = useCallback(\n (node: HTMLPreElement | null) => {\n preRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLPreElement | null>).current = node;\n },\n [ref],\n );\n\n useLayoutEffect(() => {\n if (!copyable) return;\n const pre = preRef.current;\n const wrapper = buttonWrapperRef.current;\n if (!pre || !wrapper) return;\n\n const isBottomAlign = isBottom;\n const borderH = noBorder ? 0 : 2;\n\n const update = () => {\n if (!isLeft) {\n const vScrollbar = Math.max(0, pre.offsetWidth - pre.clientWidth - borderH);\n wrapper.style.right = `${16 + vScrollbar}px`;\n }\n if (isBottomAlign) {\n const hScrollbar = Math.max(0, pre.offsetHeight - pre.clientHeight - borderH);\n wrapper.style.bottom = `${8 + hScrollbar}px`;\n }\n };\n\n update();\n const observer = new ResizeObserver(update);\n observer.observe(pre);\n return () => observer.disconnect();\n }, [copyable, isBottom, isLeft, noBorder]);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n onCopy?.();\n setTimeout(() => setCopied(false), 1500);\n } catch {\n // clipboard write failed (e.g. permission denied) — leave UI unchanged\n }\n };\n\n const copyButton = copyable ? (\n <Button\n variant=\"secondary\"\n ghost\n size=\"small\"\n type=\"button\"\n onClick={handleCopy}\n css={{\n color: '$hiContrast',\n gap: '$1',\n backgroundColor: '$codeBlockCopyButtonBg',\n height: '32px',\n }}\n >\n <AccessibleIcon label={copied ? 'Copied' : 'Copy'}>\n {copied ? <CheckIcon /> : <CopyIcon />}\n </AccessibleIcon>\n {copied ? copiedText : copyText}\n </Button>\n ) : null;\n\n return (\n <Highlight\n theme={prismTheme}\n code={code}\n language={(Prism.languages[lang] != null ? lang : 'text') as Language}\n >\n {({\n className: highlightClass,\n style: highlightStyle,\n tokens,\n getLineProps,\n getTokenProps,\n }) => (\n <Box css={{ position: 'relative', ...css }}>\n <Pre\n ref={setPreRef}\n className={[highlightClass, className].filter(Boolean).join(' ')}\n style={{ maxHeight, ...highlightStyle, backgroundColor: 'inherit', ...style }}\n noBorder={noBorder}\n {...props}\n >\n <Box css={{ p: '$4', ...(copyable && isBottom ? { pb: '$7' } : {}) }}>\n {tokens.map((line, i) => (\n <div\n key={i}\n {...getLineProps({ line })}\n style={\n wrapText ? { whiteSpace: 'pre-wrap', wordBreak: 'break-all' } : undefined\n }\n >\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token })} />\n ))}\n </div>\n ))}\n </Box>\n </Pre>\n {copyButton && (\n <CopyButtonWrapper ref={buttonWrapperRef} position={buttonPosition}>\n {copyButton}\n </CopyButtonWrapper>\n )}\n </Box>\n )}\n </Highlight>\n );\n },\n);\n\nCodeBlock.displayName = 'CodeBlock';\n"],"names":["styled","forwardRef","useColorScheme","themes","useState","useRef","useCallback","useLayoutEffect","jsxs","Button","jsx","AccessibleIcon","CheckIcon","CopyIcon","Highlight","Prism","Box"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CheckIcon, CopyIcon } from "@radix-ui/react-icons";
|
|
3
|
-
import { themes, Highlight } from "prism-react-renderer";
|
|
4
|
-
import { forwardRef, useState } from "react";
|
|
3
|
+
import { themes, Highlight, Prism } from "prism-react-renderer";
|
|
4
|
+
import { forwardRef, useState, useRef, useCallback, useLayoutEffect } from "react";
|
|
5
5
|
import { styled } from "../../stitches.config.js";
|
|
6
6
|
import { useColorScheme } from "../colorSchemeContext.js";
|
|
7
7
|
import { Box } from "../Box/Box.js";
|
|
@@ -12,7 +12,6 @@ const Pre = styled("pre", {
|
|
|
12
12
|
borderRadius: "$2",
|
|
13
13
|
overflow: "auto",
|
|
14
14
|
border: "1px solid $colors$deepBlue3",
|
|
15
|
-
position: "relative",
|
|
16
15
|
fontSize: "$2",
|
|
17
16
|
lineHeight: 1.6,
|
|
18
17
|
variants: {
|
|
@@ -23,82 +22,143 @@ const Pre = styled("pre", {
|
|
|
23
22
|
});
|
|
24
23
|
const CopyButtonWrapper = styled("div", {
|
|
25
24
|
position: "absolute",
|
|
26
|
-
right: "$4",
|
|
27
25
|
zIndex: 1,
|
|
28
26
|
variants: {
|
|
29
|
-
|
|
30
|
-
top: { top: "$2" },
|
|
31
|
-
|
|
27
|
+
position: {
|
|
28
|
+
top: { top: "$2", right: "$3" },
|
|
29
|
+
topLeft: { top: "$2", left: "$3" },
|
|
30
|
+
bottomRight: { bottom: "$2", right: "$3" },
|
|
31
|
+
bottomLeft: { bottom: "$2", left: "$3" }
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
defaultVariants: {
|
|
35
|
-
|
|
35
|
+
position: "top"
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
const CodeBlock = forwardRef(
|
|
39
39
|
({
|
|
40
|
-
lang,
|
|
40
|
+
lang = "text",
|
|
41
41
|
code,
|
|
42
42
|
copyable = false,
|
|
43
43
|
copyText,
|
|
44
44
|
copiedText,
|
|
45
|
-
copyButtonAlign = "top",
|
|
45
|
+
copyButtonAlign = "top right",
|
|
46
|
+
onCopy,
|
|
46
47
|
noBorder,
|
|
47
48
|
wrapText = false,
|
|
48
49
|
colorScheme,
|
|
49
50
|
maxHeight = 424,
|
|
50
51
|
css,
|
|
52
|
+
style,
|
|
53
|
+
className,
|
|
51
54
|
...props
|
|
52
55
|
}, ref) => {
|
|
53
56
|
const systemScheme = useColorScheme();
|
|
54
57
|
const resolvedScheme = colorScheme ?? systemScheme;
|
|
55
58
|
const prismTheme = resolvedScheme === "dark" ? themes.nightOwl : themes.nightOwlLight;
|
|
59
|
+
const isBottom = copyButtonAlign.includes("bottom");
|
|
60
|
+
const isLeft = copyButtonAlign.includes("left");
|
|
61
|
+
const buttonPosition = isBottom ? isLeft ? "bottomLeft" : "bottomRight" : isLeft ? "topLeft" : "top";
|
|
56
62
|
const [copied, setCopied] = useState(false);
|
|
63
|
+
const preRef = useRef(
|
|
64
|
+
null
|
|
65
|
+
);
|
|
66
|
+
const buttonWrapperRef = useRef(null);
|
|
67
|
+
const setPreRef = useCallback(
|
|
68
|
+
(node) => {
|
|
69
|
+
preRef.current = node;
|
|
70
|
+
if (typeof ref === "function") ref(node);
|
|
71
|
+
else if (ref) ref.current = node;
|
|
72
|
+
},
|
|
73
|
+
[ref]
|
|
74
|
+
);
|
|
75
|
+
useLayoutEffect(() => {
|
|
76
|
+
if (!copyable) return;
|
|
77
|
+
const pre = preRef.current;
|
|
78
|
+
const wrapper = buttonWrapperRef.current;
|
|
79
|
+
if (!pre || !wrapper) return;
|
|
80
|
+
const isBottomAlign = isBottom;
|
|
81
|
+
const borderH = noBorder ? 0 : 2;
|
|
82
|
+
const update = () => {
|
|
83
|
+
if (!isLeft) {
|
|
84
|
+
const vScrollbar = Math.max(0, pre.offsetWidth - pre.clientWidth - borderH);
|
|
85
|
+
wrapper.style.right = `${16 + vScrollbar}px`;
|
|
86
|
+
}
|
|
87
|
+
if (isBottomAlign) {
|
|
88
|
+
const hScrollbar = Math.max(0, pre.offsetHeight - pre.clientHeight - borderH);
|
|
89
|
+
wrapper.style.bottom = `${8 + hScrollbar}px`;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
update();
|
|
93
|
+
const observer = new ResizeObserver(update);
|
|
94
|
+
observer.observe(pre);
|
|
95
|
+
return () => observer.disconnect();
|
|
96
|
+
}, [copyable, isBottom, isLeft, noBorder]);
|
|
57
97
|
const handleCopy = async () => {
|
|
58
98
|
try {
|
|
59
99
|
await navigator.clipboard.writeText(code);
|
|
60
100
|
setCopied(true);
|
|
101
|
+
onCopy?.();
|
|
61
102
|
setTimeout(() => setCopied(false), 1500);
|
|
62
103
|
} catch {
|
|
63
104
|
}
|
|
64
105
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
const copyButton = copyable ? /* @__PURE__ */ jsxs(
|
|
107
|
+
Button,
|
|
108
|
+
{
|
|
109
|
+
variant: "secondary",
|
|
110
|
+
ghost: true,
|
|
111
|
+
size: "small",
|
|
112
|
+
type: "button",
|
|
113
|
+
onClick: handleCopy,
|
|
114
|
+
css: {
|
|
115
|
+
color: "$hiContrast",
|
|
116
|
+
gap: "$1",
|
|
117
|
+
backgroundColor: "$codeBlockCopyButtonBg",
|
|
118
|
+
height: "32px"
|
|
119
|
+
},
|
|
120
|
+
children: [
|
|
121
|
+
/* @__PURE__ */ jsx(AccessibleIcon, { label: copied ? "Copied" : "Copy", children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {}) }),
|
|
122
|
+
copied ? copiedText : copyText
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
) : null;
|
|
126
|
+
return /* @__PURE__ */ jsx(
|
|
127
|
+
Highlight,
|
|
128
|
+
{
|
|
129
|
+
theme: prismTheme,
|
|
130
|
+
code,
|
|
131
|
+
language: Prism.languages[lang] != null ? lang : "text",
|
|
132
|
+
children: ({
|
|
133
|
+
className: highlightClass,
|
|
134
|
+
style: highlightStyle,
|
|
135
|
+
tokens,
|
|
136
|
+
getLineProps,
|
|
137
|
+
getTokenProps
|
|
138
|
+
}) => /* @__PURE__ */ jsxs(Box, { css: { position: "relative", ...css }, children: [
|
|
139
|
+
/* @__PURE__ */ jsx(
|
|
140
|
+
Pre,
|
|
92
141
|
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
142
|
+
ref: setPreRef,
|
|
143
|
+
className: [highlightClass, className].filter(Boolean).join(" "),
|
|
144
|
+
style: { maxHeight, ...highlightStyle, backgroundColor: "inherit", ...style },
|
|
145
|
+
noBorder,
|
|
146
|
+
...props,
|
|
147
|
+
children: /* @__PURE__ */ jsx(Box, { css: { p: "$4", ...copyable && isBottom ? { pb: "$7" } : {} }, children: tokens.map((line, i) => /* @__PURE__ */ jsx(
|
|
148
|
+
"div",
|
|
149
|
+
{
|
|
150
|
+
...getLineProps({ line }),
|
|
151
|
+
style: wrapText ? { whiteSpace: "pre-wrap", wordBreak: "break-all" } : void 0,
|
|
152
|
+
children: line.map((token, key) => /* @__PURE__ */ jsx("span", { ...getTokenProps({ token }) }, key))
|
|
153
|
+
},
|
|
154
|
+
i
|
|
155
|
+
)) })
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
copyButton && /* @__PURE__ */ jsx(CopyButtonWrapper, { ref: buttonWrapperRef, position: buttonPosition, children: copyButton })
|
|
159
|
+
] })
|
|
160
|
+
}
|
|
161
|
+
);
|
|
102
162
|
}
|
|
103
163
|
);
|
|
104
164
|
CodeBlock.displayName = "CodeBlock";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.js","sources":["../../../components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["import { CheckIcon, CopyIcon } from '@radix-ui/react-icons';\nimport { Highlight, Language, themes } from 'prism-react-renderer';\nimport React, {
|
|
1
|
+
{"version":3,"file":"CodeBlock.js","sources":["../../../components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["import './prism-extend';\n\nimport { CheckIcon, CopyIcon } from '@radix-ui/react-icons';\nimport { Highlight, Language, Prism, themes } from 'prism-react-renderer';\nimport React, {\n ComponentProps,\n forwardRef,\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { CSS, styled } from '../../stitches.config';\nimport { AccessibleIcon } from '../AccessibleIcon';\nimport { Box } from '../Box';\nimport { Button } from '../Button';\nimport { useColorScheme } from '../colorSchemeContext';\nimport type { CodeBlockCopyButtonAlign, CodeBlockLanguage } from './index';\n\nconst Pre = styled('pre', {\n m: 0,\n borderRadius: '$2',\n overflow: 'auto',\n border: '1px solid $colors$deepBlue3',\n fontSize: '$2',\n lineHeight: 1.6,\n\n variants: {\n noBorder: {\n true: { border: 'none' },\n },\n },\n});\n\nconst CopyButtonWrapper = styled('div', {\n position: 'absolute',\n zIndex: 1,\n variants: {\n position: {\n top: { top: '$2', right: '$3' },\n topLeft: { top: '$2', left: '$3' },\n bottomRight: { bottom: '$2', right: '$3' },\n bottomLeft: { bottom: '$2', left: '$3' },\n },\n },\n\n defaultVariants: {\n position: 'top',\n },\n});\n\nexport type CodeBlockProps = {\n lang?: CodeBlockLanguage;\n code: string;\n copyable?: boolean;\n copyText?: string;\n copiedText?: string;\n copyButtonAlign?: CodeBlockCopyButtonAlign;\n onCopy?: () => void;\n noBorder?: boolean;\n wrapText?: boolean;\n colorScheme?: 'light' | 'dark';\n maxHeight?: number | string;\n css?: CSS;\n} & Omit<ComponentProps<typeof Pre>, 'css'>;\n\nexport const CodeBlock = forwardRef<HTMLPreElement, CodeBlockProps>(\n (\n {\n lang = 'text',\n code,\n copyable = false,\n copyText,\n copiedText,\n copyButtonAlign = 'top right',\n onCopy,\n noBorder,\n wrapText = false,\n colorScheme,\n maxHeight = 424,\n css,\n style,\n className,\n ...props\n },\n ref,\n ) => {\n const systemScheme = useColorScheme();\n const resolvedScheme = colorScheme ?? systemScheme;\n const prismTheme = resolvedScheme === 'dark' ? themes.nightOwl : themes.nightOwlLight;\n\n const isBottom = copyButtonAlign.includes('bottom');\n const isLeft = copyButtonAlign.includes('left');\n const buttonPosition = isBottom\n ? isLeft\n ? 'bottomLeft'\n : 'bottomRight'\n : isLeft\n ? 'topLeft'\n : 'top';\n\n const [copied, setCopied] = useState(false);\n\n const preRef = useRef<HTMLPreElement | null>(\n null,\n ) as React.MutableRefObject<HTMLPreElement | null>;\n const buttonWrapperRef = useRef<HTMLDivElement>(null);\n\n const setPreRef = useCallback(\n (node: HTMLPreElement | null) => {\n preRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLPreElement | null>).current = node;\n },\n [ref],\n );\n\n useLayoutEffect(() => {\n if (!copyable) return;\n const pre = preRef.current;\n const wrapper = buttonWrapperRef.current;\n if (!pre || !wrapper) return;\n\n const isBottomAlign = isBottom;\n const borderH = noBorder ? 0 : 2;\n\n const update = () => {\n if (!isLeft) {\n const vScrollbar = Math.max(0, pre.offsetWidth - pre.clientWidth - borderH);\n wrapper.style.right = `${16 + vScrollbar}px`;\n }\n if (isBottomAlign) {\n const hScrollbar = Math.max(0, pre.offsetHeight - pre.clientHeight - borderH);\n wrapper.style.bottom = `${8 + hScrollbar}px`;\n }\n };\n\n update();\n const observer = new ResizeObserver(update);\n observer.observe(pre);\n return () => observer.disconnect();\n }, [copyable, isBottom, isLeft, noBorder]);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n onCopy?.();\n setTimeout(() => setCopied(false), 1500);\n } catch {\n // clipboard write failed (e.g. permission denied) — leave UI unchanged\n }\n };\n\n const copyButton = copyable ? (\n <Button\n variant=\"secondary\"\n ghost\n size=\"small\"\n type=\"button\"\n onClick={handleCopy}\n css={{\n color: '$hiContrast',\n gap: '$1',\n backgroundColor: '$codeBlockCopyButtonBg',\n height: '32px',\n }}\n >\n <AccessibleIcon label={copied ? 'Copied' : 'Copy'}>\n {copied ? <CheckIcon /> : <CopyIcon />}\n </AccessibleIcon>\n {copied ? copiedText : copyText}\n </Button>\n ) : null;\n\n return (\n <Highlight\n theme={prismTheme}\n code={code}\n language={(Prism.languages[lang] != null ? lang : 'text') as Language}\n >\n {({\n className: highlightClass,\n style: highlightStyle,\n tokens,\n getLineProps,\n getTokenProps,\n }) => (\n <Box css={{ position: 'relative', ...css }}>\n <Pre\n ref={setPreRef}\n className={[highlightClass, className].filter(Boolean).join(' ')}\n style={{ maxHeight, ...highlightStyle, backgroundColor: 'inherit', ...style }}\n noBorder={noBorder}\n {...props}\n >\n <Box css={{ p: '$4', ...(copyable && isBottom ? { pb: '$7' } : {}) }}>\n {tokens.map((line, i) => (\n <div\n key={i}\n {...getLineProps({ line })}\n style={\n wrapText ? { whiteSpace: 'pre-wrap', wordBreak: 'break-all' } : undefined\n }\n >\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token })} />\n ))}\n </div>\n ))}\n </Box>\n </Pre>\n {copyButton && (\n <CopyButtonWrapper ref={buttonWrapperRef} position={buttonPosition}>\n {copyButton}\n </CopyButtonWrapper>\n )}\n </Box>\n )}\n </Highlight>\n );\n },\n);\n\nCodeBlock.displayName = 'CodeBlock';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
exports.Theme = void 0;
|
|
4
|
+
((Theme2) => {
|
|
5
|
+
function getLight() {
|
|
6
|
+
return {
|
|
7
|
+
codeBlockCopyButtonBg: "transparent"
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
Theme2.getLight = getLight;
|
|
11
|
+
function getDark() {
|
|
12
|
+
return {
|
|
13
|
+
codeBlockCopyButtonBg: "transparent"
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
Theme2.getDark = getDark;
|
|
17
|
+
})(exports.Theme || (exports.Theme = {}));
|
|
18
|
+
//# sourceMappingURL=CodeBlock.themes.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlock.themes.cjs","sources":["../../../components/CodeBlock/CodeBlock.themes.ts"],"sourcesContent":["import { Property } from '@stitches/react/types/css';\n\nexport namespace Theme {\n type Colors = {\n codeBlockCopyButtonBg: Property.Color;\n };\n\n export function getLight(): Colors {\n return {\n codeBlockCopyButtonBg: 'transparent',\n };\n }\n\n export function getDark(): Colors {\n return {\n codeBlockCopyButtonBg: 'transparent',\n };\n }\n}\n"],"names":["Theme"],"mappings":";;AAEiBA,QAAAA,QAAAA;AAAAA,CAAV,CAAUA,WAAV;AAKE,WAAS,WAAmB;AACjC,WAAO;AAAA,MACL,uBAAuB;AAAA,IAAA;AAAA,EAE3B;AAJOA,SAAS,WAAA;AAMT,WAAS,UAAkB;AAChC,WAAO;AAAA,MACL,uBAAuB;AAAA,IAAA;AAAA,EAE3B;AAJOA,SAAS,UAAA;AAAA,GAXDA,QAAAA,UAAAA,gBAAA,CAAA,EAAA;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
var Theme;
|
|
2
|
+
((Theme2) => {
|
|
3
|
+
function getLight() {
|
|
4
|
+
return {
|
|
5
|
+
codeBlockCopyButtonBg: "transparent"
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
Theme2.getLight = getLight;
|
|
9
|
+
function getDark() {
|
|
10
|
+
return {
|
|
11
|
+
codeBlockCopyButtonBg: "transparent"
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
Theme2.getDark = getDark;
|
|
15
|
+
})(Theme || (Theme = {}));
|
|
16
|
+
export {
|
|
17
|
+
Theme
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=CodeBlock.themes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlock.themes.js","sources":["../../../components/CodeBlock/CodeBlock.themes.ts"],"sourcesContent":["import { Property } from '@stitches/react/types/css';\n\nexport namespace Theme {\n type Colors = {\n codeBlockCopyButtonBg: Property.Color;\n };\n\n export function getLight(): Colors {\n return {\n codeBlockCopyButtonBg: 'transparent',\n };\n }\n\n export function getDark(): Colors {\n return {\n codeBlockCopyButtonBg: 'transparent',\n };\n }\n}\n"],"names":["Theme"],"mappings":"AAEO,IAAU;AAAA,CAAV,CAAUA,WAAV;AAKE,WAAS,WAAmB;AACjC,WAAO;AAAA,MACL,uBAAuB;AAAA,IAAA;AAAA,EAE3B;AAJOA,SAAS,WAAA;AAMT,WAAS,UAAkB;AAChC,WAAO;AAAA,MACL,uBAAuB;AAAA,IAAA;AAAA,EAE3B;AAJOA,SAAS,UAAA;AAAA,GAXD,UAAA,QAAA,CAAA,EAAA;"}
|