@keboola/design 13.2.0 → 14.0.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/AGENTS.md +5 -1
- package/CHANGELOG.md +161 -0
- package/COMPONENT-API.md +52 -42
- package/dist/{AIKit-C5FbKjwa.js → AIKit-BRSZ3nY7.js} +2216 -302
- package/dist/AIKit-BRSZ3nY7.js.map +1 -0
- package/dist/{Alert-DuAGeYyM.js → Alert-CZ0dDsuk.js} +2 -2
- package/dist/{Alert-DuAGeYyM.js.map → Alert-CZ0dDsuk.js.map} +1 -1
- package/dist/{BrandEditor-Dq168RJc.js → BrandEditor-CN2HJ_12.js} +5 -5
- package/dist/{BrandEditor-Dq168RJc.js.map → BrandEditor-CN2HJ_12.js.map} +1 -1
- package/dist/{Breadcrumb-CUyYu5Bi.js → Breadcrumb-BnIlsoIH.js} +54 -12
- package/dist/Breadcrumb-BnIlsoIH.js.map +1 -0
- package/dist/{Checkbox-D9rafoKh.js → Checkbox-uFE8XLT_.js} +2 -2
- package/dist/{Checkbox-D9rafoKh.js.map → Checkbox-uFE8XLT_.js.map} +1 -1
- package/dist/{Clipboard-BHWUodAx.js → Clipboard-D-9XOqy4.js} +2 -2
- package/dist/{Clipboard-BHWUodAx.js.map → Clipboard-D-9XOqy4.js.map} +1 -1
- package/dist/{ClipboardButton-Urg-kZbh.js → ClipboardButton-DxvZG_H0.js} +2 -2
- package/dist/{ClipboardButton-Urg-kZbh.js.map → ClipboardButton-DxvZG_H0.js.map} +1 -1
- package/dist/{CodeEditor-Y0iE-SwV.js → CodeEditor-BfRSCKEs.js} +5 -5
- package/dist/{CodeEditor-Y0iE-SwV.js.map → CodeEditor-BfRSCKEs.js.map} +1 -1
- package/dist/{ColorInput-D1nC0X6i.js → ColorInput-CDKH8q_f.js} +2 -2
- package/dist/{ColorInput-D1nC0X6i.js.map → ColorInput-CDKH8q_f.js.map} +1 -1
- package/dist/{ColorModeSwitch-Cxee8jnB.js → ColorModeSwitch-DR6J2U6M.js} +2 -2
- package/dist/{ColorModeSwitch-Cxee8jnB.js.map → ColorModeSwitch-DR6J2U6M.js.map} +1 -1
- package/dist/{Combobox-B1Kjoy5J.js → Combobox-CEesMe2M.js} +240 -38
- package/dist/Combobox-CEesMe2M.js.map +1 -0
- package/dist/{Command-BuOA3V18.js → Command-T3MLRaen.js} +8 -4
- package/dist/Command-T3MLRaen.js.map +1 -0
- package/dist/{CopyField-DsOVtV2Q.js → CopyField-CNbCHw9a.js} +2 -2
- package/dist/{CopyField-DsOVtV2Q.js.map → CopyField-CNbCHw9a.js.map} +1 -1
- package/dist/{DateInput-BlKkequE.js → DateInput-ClK1lCxz.js} +2 -2
- package/dist/{DateInput-BlKkequE.js.map → DateInput-ClK1lCxz.js.map} +1 -1
- package/dist/{DateRangeInput-DOxJHw8V.js → DateRangeInput-DtlAffS1.js} +2 -2
- package/dist/{DateRangeInput-DOxJHw8V.js.map → DateRangeInput-DtlAffS1.js.map} +1 -1
- package/dist/{DropdownMenu-DtRYcKEx.js → DropdownMenu-B1gGvZoh.js} +2 -2
- package/dist/{DropdownMenu-DtRYcKEx.js.map → DropdownMenu-B1gGvZoh.js.map} +1 -1
- package/dist/{FieldItem-Cf1E3rfQ.js → FieldItem-CYvJyjiI.js} +3 -3
- package/dist/{FieldItem-Cf1E3rfQ.js.map → FieldItem-CYvJyjiI.js.map} +1 -1
- package/dist/{Form-CuaAn-lR.js → Form-CD55zJiy.js} +5 -5
- package/dist/{Form-CuaAn-lR.js.map → Form-CD55zJiy.js.map} +1 -1
- package/dist/{FormGroup-D4O96YPm.js → FormGroup-DiYFdEhH.js} +3 -3
- package/dist/{FormGroup-D4O96YPm.js.map → FormGroup-DiYFdEhH.js.map} +1 -1
- package/dist/{HoverCard-Cy6nhg4u.js → HoverCard-BBdPYqEf.js} +2 -2
- package/dist/HoverCard-BBdPYqEf.js.map +1 -0
- package/dist/{InlineEdit-DSMIEUUa.js → InlineEdit-D5RdunZo.js} +3 -3
- package/dist/{InlineEdit-DSMIEUUa.js.map → InlineEdit-D5RdunZo.js.map} +1 -1
- package/dist/{Kbd-Du93F3o4.js → Kbd-3YM7NQO4.js} +2 -2
- package/dist/{Kbd-Du93F3o4.js.map → Kbd-3YM7NQO4.js.map} +1 -1
- package/dist/MermaidDiagram-CeiOkI60.js +199 -0
- package/dist/MermaidDiagram-CeiOkI60.js.map +1 -0
- package/dist/{Modal-DQIauzar.js → Modal-DMZRswk4.js} +4 -3
- package/dist/Modal-DMZRswk4.js.map +1 -0
- package/dist/{MultiActionButtonGroup-xKqiucAN.js → MultiActionButtonGroup-CEv_txvz.js} +2 -2
- package/dist/{MultiActionButtonGroup-xKqiucAN.js.map → MultiActionButtonGroup-CEv_txvz.js.map} +1 -1
- package/dist/{RadioGroup-C2vk5acr.js → RadioGroup-C8EC3fqO.js} +2 -2
- package/dist/{RadioGroup-C2vk5acr.js.map → RadioGroup-C8EC3fqO.js.map} +1 -1
- package/dist/{Search-CVrv3hqf.js → Search-aaUMI4ix.js} +2 -2
- package/dist/{Search-CVrv3hqf.js.map → Search-aaUMI4ix.js.map} +1 -1
- package/dist/{SearchInput-BnU6YHgT.js → SearchInput-Dxi2GK4n.js} +2 -2
- package/dist/{SearchInput-BnU6YHgT.js.map → SearchInput-Dxi2GK4n.js.map} +1 -1
- package/dist/{SectionNav-XlhvXXdF.js → SectionNav-BnHOMLtE.js} +3 -3
- package/dist/{SectionNav-XlhvXXdF.js.map → SectionNav-BnHOMLtE.js.map} +1 -1
- package/dist/Sheet-utw4_rUa.js.map +1 -1
- package/dist/{Sidebar-CKaxOPwY.js → Sidebar-BAmux2Uj.js} +5 -5
- package/dist/{Sidebar-CKaxOPwY.js.map → Sidebar-BAmux2Uj.js.map} +1 -1
- package/dist/{Slider-Rcc2qVct.js → Slider-DbzzSDRV.js} +2 -2
- package/dist/{Slider-Rcc2qVct.js.map → Slider-DbzzSDRV.js.map} +1 -1
- package/dist/{Table-CgSC-fSo.js → Table-CilEvpMq.js} +62 -3
- package/dist/Table-CilEvpMq.js.map +1 -0
- package/dist/{TextInput-B5TDDOty.js → TextInput-K2DSDs5O.js} +2 -2
- package/dist/{TextInput-B5TDDOty.js.map → TextInput-K2DSDs5O.js.map} +1 -1
- package/dist/{ThemeProvider-Dt9b67sW.js → ThemeProvider-C8yaKlM1.js} +2 -2
- package/dist/{ThemeProvider-Dt9b67sW.js.map → ThemeProvider-C8yaKlM1.js.map} +1 -1
- package/dist/ToggleAllTooltip-Dlmq-yqS.js +37 -0
- package/dist/ToggleAllTooltip-Dlmq-yqS.js.map +1 -0
- package/dist/{ZoomableSvg-D8sXKpoV.js → ZoomableSvg-Dh1OstPN.js} +84 -80
- package/dist/ZoomableSvg-Dh1OstPN.js.map +1 -0
- package/dist/editors.js +3 -3
- package/dist/flint.js +10 -45
- package/dist/flint.js.map +1 -1
- package/dist/highlightCode-D354tCXO.js +81 -0
- package/dist/highlightCode-D354tCXO.js.map +1 -0
- package/dist/index.d.ts +792 -346
- package/dist/index.js +35 -35
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChipEditor.js +1 -1
- package/dist/internal/blocks/ClipboardButton.js +1 -1
- package/dist/internal/blocks/ColorInput.js +1 -1
- package/dist/internal/blocks/ColorModeSwitch.js +1 -1
- package/dist/internal/blocks/Command.js +1 -1
- package/dist/internal/blocks/CopyField.js +1 -1
- package/dist/internal/blocks/DateInput.js +1 -1
- package/dist/internal/blocks/DateRangeInput.js +1 -1
- package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js.map +1 -1
- package/dist/internal/blocks/ExportMenu.js +2 -2
- package/dist/internal/blocks/Form/connectors/ComboboxField.js +2 -2
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
- package/dist/internal/blocks/Form.js +1 -1
- package/dist/internal/blocks/FormGroup.js +1 -1
- package/dist/internal/blocks/InlineEdit.js +1 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
- package/dist/internal/blocks/MultiCombobox.js +204 -68
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/PasswordInput.js +1 -1
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +2 -2
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/TimeInput.js +1 -1
- package/dist/internal/components/Alert.js +1 -1
- package/dist/internal/components/Avatar.js +1 -1
- package/dist/internal/components/Breadcrumb.js +1 -1
- package/dist/internal/components/Checkbox.js +1 -1
- package/dist/internal/components/Clipboard.js +1 -1
- package/dist/internal/components/CollapsiblePanel.js +1 -1
- package/dist/internal/components/Combobox.js +1 -1
- package/dist/internal/components/DropdownMenu.js +1 -1
- package/dist/internal/components/HoverCard.js +1 -1
- package/dist/internal/components/Kbd.js +1 -1
- package/dist/internal/components/Modal.js +1 -1
- package/dist/internal/components/RadioGroup.js +1 -1
- package/dist/internal/components/Search.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Skeleton/Skeleton.js +1 -1
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/Table.js +1 -1
- package/dist/internal/components/ThemeProvider.js +1 -1
- package/dist/internal/components/Tooltip.js +1 -1
- package/dist/internal/components/Truncated.js +1 -1
- package/dist/internal/components/ZoomableSvg.js +1 -1
- package/dist/internal/utils.js +1 -1
- package/dist/markdown-editor.js +6 -6
- package/dist/mermaid.d.ts +1 -2
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.js +98 -11
- package/dist/rjsf.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/svgCache-Dhmbe-7i.js +26 -0
- package/dist/svgCache-Dhmbe-7i.js.map +1 -0
- package/dist/svgTransforms-Hnvev3Vs.js +38 -0
- package/dist/svgTransforms-Hnvev3Vs.js.map +1 -0
- package/dist/testing.js +1 -1
- package/dist/{themeTokens-7DEab0kp.js → themeTokens-l2Fsfcs7.js} +3 -12
- package/dist/themeTokens-l2Fsfcs7.js.map +1 -0
- package/dist/{utils-p6tjltbX.js → utils-LQ4jJA-9.js} +18 -2
- package/dist/utils-LQ4jJA-9.js.map +1 -0
- package/dist/vega.js +1 -1
- package/dist/vegaTheme-BrmVoPEz.js +49 -0
- package/dist/vegaTheme-BrmVoPEz.js.map +1 -0
- package/dist/{vegaTheme-VQMWTlBw.js → vegaTokens-Ce07C0DH.js} +36 -44
- package/dist/vegaTokens-Ce07C0DH.js.map +1 -0
- package/package.json +3 -4
- package/src/styles.css +4 -4
- package/dist/AIKit-C5FbKjwa.js.map +0 -1
- package/dist/Breadcrumb-CUyYu5Bi.js.map +0 -1
- package/dist/Combobox-B1Kjoy5J.js.map +0 -1
- package/dist/Command-BuOA3V18.js.map +0 -1
- package/dist/DiagramSource-jTwmmi9g.js +0 -11
- package/dist/DiagramSource-jTwmmi9g.js.map +0 -1
- package/dist/HoverCard-Cy6nhg4u.js.map +0 -1
- package/dist/MermaidDiagram-D2ThT8Q-.js +0 -302
- package/dist/MermaidDiagram-D2ThT8Q-.js.map +0 -1
- package/dist/Modal-DQIauzar.js.map +0 -1
- package/dist/Table-CgSC-fSo.js.map +0 -1
- package/dist/ZoomableSvg-D8sXKpoV.js.map +0 -1
- package/dist/svgTransforms-Dw2hRA-i.js +0 -51
- package/dist/svgTransforms-Dw2hRA-i.js.map +0 -1
- package/dist/themeTokens-7DEab0kp.js.map +0 -1
- package/dist/utils-p6tjltbX.js.map +0 -1
- package/dist/vegaTheme-VQMWTlBw.js.map +0 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/blocks/DiagramShared/svgCache.ts
|
|
2
|
+
/**
|
|
3
|
+
* A diagram SVG cache that survives remounts.
|
|
4
|
+
*
|
|
5
|
+
* - Keyed by theme key + code: colours are baked into the markup.
|
|
6
|
+
* - Bounded and evicted oldest-first (`Map` insertion order): entries run to hundreds of KB.
|
|
7
|
+
*/
|
|
8
|
+
const createSvgCache = (maxEntries = 24) => {
|
|
9
|
+
const entries = /* @__PURE__ */ new Map();
|
|
10
|
+
return {
|
|
11
|
+
get: (key) => entries.get(key),
|
|
12
|
+
has: (key) => entries.has(key),
|
|
13
|
+
set: (key, svg) => {
|
|
14
|
+
if (!entries.has(key) && entries.size >= maxEntries) {
|
|
15
|
+
const oldest = entries.keys().next();
|
|
16
|
+
if (!oldest.done) entries.delete(oldest.value);
|
|
17
|
+
}
|
|
18
|
+
entries.set(key, svg);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
const diagramCacheKey = (code, themeKey) => `${themeKey}\n${code}`;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { createSvgCache, diagramCacheKey };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=svgCache-Dhmbe-7i.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svgCache-Dhmbe-7i.js","names":[],"sources":["../src/blocks/DiagramShared/svgCache.ts"],"sourcesContent":["/**\n * A diagram SVG cache that survives remounts.\n *\n * - Keyed by theme key + code: colours are baked into the markup.\n * - Bounded and evicted oldest-first (`Map` insertion order): entries run to hundreds of KB.\n */\nexport const createSvgCache = (maxEntries = 24) => {\n const entries = new Map<string, string>();\n\n return {\n get: (key: string): string | undefined => entries.get(key),\n has: (key: string): boolean => entries.has(key),\n set: (key: string, svg: string): void => {\n // Overwriting an existing key adds no entry, so it must not evict one.\n if (!entries.has(key) && entries.size >= maxEntries) {\n const oldest = entries.keys().next();\n if (!oldest.done) entries.delete(oldest.value);\n }\n entries.set(key, svg);\n },\n };\n};\n\nexport const diagramCacheKey = (code: string, themeKey: string): string => `${themeKey}\\n${code}`;\n"],"mappings":";;;;;;;AAMA,MAAa,kBAAkB,aAAa,OAAO;CACjD,MAAM,0BAAU,IAAI,IAAoB;CAExC,OAAO;EACL,MAAM,QAAoC,QAAQ,IAAI,GAAG;EACzD,MAAM,QAAyB,QAAQ,IAAI,GAAG;EAC9C,MAAM,KAAa,QAAsB;GAEvC,IAAI,CAAC,QAAQ,IAAI,GAAG,KAAK,QAAQ,QAAQ,YAAY;IACnD,MAAM,SAAS,QAAQ,KAAK,CAAC,CAAC,KAAK;IACnC,IAAI,CAAC,OAAO,MAAM,QAAQ,OAAO,OAAO,KAAK;GAC/C;GACA,QAAQ,IAAI,KAAK,GAAG;EACtB;CACF;AACF;AAEA,MAAa,mBAAmB,MAAc,aAA6B,GAAG,SAAS,IAAI"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { cn } from "./classNames-DcGnTh2N.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/blocks/DiagramShared/DiagramSource.tsx
|
|
4
|
+
const DiagramSource = ({ code }) => /* @__PURE__ */ jsx("pre", {
|
|
5
|
+
className: cn("tw:my-3 tw:overflow-auto tw:whitespace-pre-wrap tw:break-all", "tw:py-3 tw:px-4", "tw:bg-muted", "tw:rounded-md tw:text-muted-foreground", "tw:text-sm tw:font-mono"),
|
|
6
|
+
children: /* @__PURE__ */ jsx("code", { children: code })
|
|
7
|
+
});
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/blocks/DiagramShared/svgTransforms.ts
|
|
10
|
+
const ROOT_SVG_TAG = /^(\s*<svg\b)([^>]*)(>)/i;
|
|
11
|
+
const STYLE_ATTR = /\s+style="([^"]*)"/i;
|
|
12
|
+
/**
|
|
13
|
+
* Makes the root `<svg>` fluid: `width="100%"`, `max-width` from the viewBox, no fixed height.
|
|
14
|
+
*
|
|
15
|
+
* - Only the root tag: inner icon `<svg>`s keep their fixed size.
|
|
16
|
+
* - Keeps `style` (minus `max-width`): Pele's theme vars live there.
|
|
17
|
+
* - `extraStyle` declarations follow the existing ones, so they win over the same property.
|
|
18
|
+
*/
|
|
19
|
+
const makeResponsive = (svgString, extraStyle = "") => {
|
|
20
|
+
const viewBoxMatch = svgString.match(/viewBox="[^"]*\s([\d.]+)\s[\d.]+"/);
|
|
21
|
+
const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : void 0;
|
|
22
|
+
return svgString.replace(ROOT_SVG_TAG, (_match, open, attrs, close) => {
|
|
23
|
+
const styleDecls = (attrs.match(STYLE_ATTR)?.[1] ?? "").replace(/max-width:\s*[^;"]*;?\s*/gi, "").replace(/\s+/g, " ").trim().replace(/;$/, "");
|
|
24
|
+
let nextAttrs = attrs.replace(/\s+width="[^"]*"/i, "").replace(/\s+height="[^"]*"/i, "").replace(STYLE_ATTR, "");
|
|
25
|
+
nextAttrs += " width=\"100%\"";
|
|
26
|
+
const styleParts = [
|
|
27
|
+
styleDecls,
|
|
28
|
+
extraStyle,
|
|
29
|
+
vbWidth ? `max-width: ${vbWidth}px` : ""
|
|
30
|
+
].filter(Boolean).join("; ");
|
|
31
|
+
if (styleParts) nextAttrs += ` style="${styleParts}"`;
|
|
32
|
+
return `${open}${nextAttrs}${close}`;
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { DiagramSource, makeResponsive };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=svgTransforms-Hnvev3Vs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svgTransforms-Hnvev3Vs.js","names":[],"sources":["../src/blocks/DiagramShared/DiagramSource.tsx","../src/blocks/DiagramShared/svgTransforms.ts"],"sourcesContent":["import { cn } from '../../utils';\n\n// The raw source of a diagram/chart fence, shown muted when rendering failed —\n// the shared failure fallback of MermaidDiagram and FlintChart.\nexport const DiagramSource = ({ code }: { code: string }) => (\n <pre\n className={cn(\n 'tw:my-3 tw:overflow-auto tw:whitespace-pre-wrap tw:break-all',\n 'tw:py-3 tw:px-4',\n 'tw:bg-muted',\n 'tw:rounded-md tw:text-muted-foreground',\n 'tw:text-sm tw:font-mono',\n )}\n >\n <code>{code}</code>\n </pre>\n);\n","// Post-processing of diagram SVG output (Pele, vega) before ZoomableSvg's DOMPurify pass.\n\n// Root <svg> open tag only; nested icon <svg>s must not match.\nconst ROOT_SVG_TAG = /^(\\s*<svg\\b)([^>]*)(>)/i;\n\nconst STYLE_ATTR = /\\s+style=\"([^\"]*)\"/i;\n\n/**\n * Makes the root `<svg>` fluid: `width=\"100%\"`, `max-width` from the viewBox, no fixed height.\n *\n * - Only the root tag: inner icon `<svg>`s keep their fixed size.\n * - Keeps `style` (minus `max-width`): Pele's theme vars live there.\n * - `extraStyle` declarations follow the existing ones, so they win over the same property.\n */\nexport const makeResponsive = (svgString: string, extraStyle = ''): string => {\n const viewBoxMatch = svgString.match(/viewBox=\"[^\"]*\\s([\\d.]+)\\s[\\d.]+\"/);\n const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : undefined;\n\n return svgString.replace(ROOT_SVG_TAG, (_match, open: string, attrs: string, close: string) => {\n const existingStyle = attrs.match(STYLE_ATTR)?.[1] ?? '';\n const styleDecls = existingStyle\n .replace(/max-width:\\s*[^;\"]*;?\\s*/gi, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/;$/, '');\n\n let nextAttrs = attrs\n .replace(/\\s+width=\"[^\"]*\"/i, '')\n .replace(/\\s+height=\"[^\"]*\"/i, '')\n .replace(STYLE_ATTR, '');\n\n nextAttrs += ' width=\"100%\"';\n\n const styleParts = [styleDecls, extraStyle, vbWidth ? `max-width: ${vbWidth}px` : '']\n .filter(Boolean)\n .join('; ');\n if (styleParts) nextAttrs += ` style=\"${styleParts}\"`;\n\n return `${open}${nextAttrs}${close}`;\n });\n};\n"],"mappings":";;;AAIA,MAAa,iBAAiB,EAAE,WAC9B,oBAAC,OAAD;CACE,WAAW,GACT,gEACA,mBACA,eACA,0CACA,yBACF;CAEA,UAAA,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA;AACf,CAAA;;;ACZP,MAAM,eAAe;AAErB,MAAM,aAAa;;;;;;;;AASnB,MAAa,kBAAkB,WAAmB,aAAa,OAAe;CAC5E,MAAM,eAAe,UAAU,MAAM,mCAAmC;CACxE,MAAM,UAAU,eAAe,KAAK,MAAM,OAAO,aAAa,EAAE,CAAC,IAAI,KAAA;CAErE,OAAO,UAAU,QAAQ,eAAe,QAAQ,MAAc,OAAe,UAAkB;EAE7F,MAAM,cADgB,MAAM,MAAM,UAAU,CAAC,GAAG,MAAM,GAAA,CAEnD,QAAQ,8BAA8B,EAAE,CAAC,CACzC,QAAQ,QAAQ,GAAG,CAAC,CACpB,KAAK,CAAC,CACN,QAAQ,MAAM,EAAE;EAEnB,IAAI,YAAY,MACb,QAAQ,qBAAqB,EAAE,CAAC,CAChC,QAAQ,sBAAsB,EAAE,CAAC,CACjC,QAAQ,YAAY,EAAE;EAEzB,aAAa;EAEb,MAAM,aAAa;GAAC;GAAY;GAAY,UAAU,cAAc,QAAQ,MAAM;EAAE,CAAC,CAClF,OAAO,OAAO,CAAC,CACf,KAAK,IAAI;EACZ,IAAI,YAAY,aAAa,WAAW,WAAW;EAEnD,OAAO,GAAG,OAAO,YAAY;CAC/B,CAAC;AACH"}
|
package/dist/testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArgoDesignContext } from "./context-U293r3v-.js";
|
|
2
|
-
import { ThemeProvider } from "./ThemeProvider-
|
|
2
|
+
import { ThemeProvider } from "./ThemeProvider-C8yaKlM1.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { keboola, keboolaLegacySidebar } from "@keboola/brand-registry";
|
|
5
5
|
import { render } from "@testing-library/react";
|
|
@@ -10,22 +10,13 @@ const resolveToken = (token, fallbackChannels, alpha) => {
|
|
|
10
10
|
const channels = typeof document === "undefined" ? fallbackChannels : getComputedStyle(document.documentElement).getPropertyValue(`--${token}`).trim() || fallbackChannels;
|
|
11
11
|
return format(channels, alpha);
|
|
12
12
|
};
|
|
13
|
-
/**
|
|
13
|
+
/** A token reader bound to one `getComputedStyle` snapshot, answering the raw `"R G B"` channels. */
|
|
14
14
|
const createChannelResolver = (from) => {
|
|
15
15
|
const element = from ?? (typeof document === "undefined" ? null : document.documentElement);
|
|
16
16
|
const computed = element === null ? null : getComputedStyle(element);
|
|
17
17
|
return (token, fallbackChannels) => computed?.getPropertyValue(`--${token}`).trim() || fallbackChannels;
|
|
18
18
|
};
|
|
19
|
-
/**
|
|
20
|
-
* A {@link resolveToken} bound to one `getComputedStyle` snapshot, for building a whole palette.
|
|
21
|
-
*
|
|
22
|
-
* - Create one per palette build, never at module level — tokens change with scheme and brand.
|
|
23
|
-
*/
|
|
24
|
-
const createTokenResolver = (from) => {
|
|
25
|
-
const resolve = createChannelResolver(from);
|
|
26
|
-
return (token, fallbackChannels, alpha) => format(resolve(token, fallbackChannels), alpha);
|
|
27
|
-
};
|
|
28
19
|
//#endregion
|
|
29
|
-
export { createChannelResolver,
|
|
20
|
+
export { createChannelResolver, resolveToken };
|
|
30
21
|
|
|
31
|
-
//# sourceMappingURL=themeTokens-
|
|
22
|
+
//# sourceMappingURL=themeTokens-l2Fsfcs7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themeTokens-l2Fsfcs7.js","names":[],"sources":["../src/utils/themeTokens.ts"],"sourcesContent":["const format = (channels: string, alpha?: number): string =>\n alpha === undefined ? `rgb(${channels})` : `rgb(${channels} / ${alpha})`;\n\n/**\n * A semantic `--*` token as the `rgb(...)` the browser currently computes on `<html>`.\n *\n * - For consumers that need a concrete colour string, not a Tailwind class.\n * - Falls back to `fallbackChannels` with no document or undefined token (tests load no CSS).\n */\nexport const resolveToken = (token: string, fallbackChannels: string, alpha?: number): string => {\n const channels =\n typeof document === 'undefined'\n ? fallbackChannels\n : getComputedStyle(document.documentElement).getPropertyValue(`--${token}`).trim() ||\n fallbackChannels;\n return format(channels, alpha);\n};\n\n/** A token reader bound to one `getComputedStyle` snapshot, answering the raw `\"R G B\"` channels. */\nexport const createChannelResolver = (from?: Element | null) => {\n // `from`: a node inside a `ThemeScope`, whose tokens differ from `<html>`'s.\n const element = from ?? (typeof document === 'undefined' ? null : document.documentElement);\n const computed = element === null ? null : getComputedStyle(element);\n\n return (token: string, fallbackChannels: string): string =>\n computed?.getPropertyValue(`--${token}`).trim() || fallbackChannels;\n};\n"],"mappings":";AAAA,MAAM,UAAU,UAAkB,UAChC,UAAU,KAAA,IAAY,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,MAAM;;;;;;;AAQxE,MAAa,gBAAgB,OAAe,kBAA0B,UAA2B;CAC/F,MAAM,WACJ,OAAO,aAAa,cAChB,mBACA,iBAAiB,SAAS,eAAe,CAAC,CAAC,iBAAiB,KAAK,OAAO,CAAC,CAAC,KAAK,KAC/E;CACN,OAAO,OAAO,UAAU,KAAK;AAC/B;;AAGA,MAAa,yBAAyB,SAA0B;CAE9D,MAAM,UAAU,SAAS,OAAO,aAAa,cAAc,OAAO,SAAS;CAC3E,MAAM,WAAW,YAAY,OAAO,OAAO,iBAAiB,OAAO;CAEnE,QAAQ,OAAe,qBACrB,UAAU,iBAAiB,KAAK,OAAO,CAAC,CAAC,KAAK,KAAK;AACvD"}
|
|
@@ -75,9 +75,13 @@ const tooltipVariants = cva([
|
|
|
75
75
|
"tw:max-h-96",
|
|
76
76
|
"tw:overflow-y-auto",
|
|
77
77
|
"tw:z-[1060]",
|
|
78
|
+
"tw:[&_hr]:my-3",
|
|
79
|
+
"tw:[&_hr]:border-current/20",
|
|
80
|
+
"tw:[&_p:last-of-type]:mb-0",
|
|
78
81
|
"tw:rounded",
|
|
79
82
|
"tw:bg-neutral-800",
|
|
80
83
|
"tw:text-white",
|
|
84
|
+
"tw:data-[tooltip-content=true]:[&_a]:text-inherit",
|
|
81
85
|
"tw:data-[argo=true]:rounded-popover",
|
|
82
86
|
"tw:data-[argo=true]:border",
|
|
83
87
|
"tw:data-[argo=true]:border-solid",
|
|
@@ -153,6 +157,17 @@ const TooltipRoot = ({ children, delayDuration = DELAY_SHOW_TOOLTIP, ...rest })
|
|
|
153
157
|
children
|
|
154
158
|
});
|
|
155
159
|
//#endregion
|
|
160
|
+
//#region src/components/Tooltip/TooltipTitle.tsx
|
|
161
|
+
/**
|
|
162
|
+
* Small uppercase heading above a rich tooltip's body copy.
|
|
163
|
+
*
|
|
164
|
+
* - Takes the tooltip's text colour, so it reads on both the legacy and the argo chrome.
|
|
165
|
+
*/
|
|
166
|
+
const TooltipTitle = ({ className, ...rest }) => /* @__PURE__ */ jsx("div", {
|
|
167
|
+
className: cn("tw:mb-2 tw:text-xs tw:leading-5 tw:font-semibold tw:uppercase", className),
|
|
168
|
+
...rest
|
|
169
|
+
});
|
|
170
|
+
//#endregion
|
|
156
171
|
//#region src/components/Tooltip/TooltipTrigger.tsx
|
|
157
172
|
/**
|
|
158
173
|
* Radix stamps the tooltip's own open/closed `data-state` onto the trigger. Merged onto an
|
|
@@ -255,6 +270,7 @@ const Tooltip = ({ tooltip, children, className, keepOpenOnTriggerClick = false,
|
|
|
255
270
|
Tooltip.Root = TooltipRoot;
|
|
256
271
|
Tooltip.Content = TooltipContent;
|
|
257
272
|
Tooltip.Trigger = TooltipTrigger;
|
|
273
|
+
Tooltip.Title = TooltipTitle;
|
|
258
274
|
//#endregion
|
|
259
275
|
//#region src/utils/decorators.tsx
|
|
260
276
|
const withTooltipProvider = (Story) => /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(Story, {}) });
|
|
@@ -338,6 +354,6 @@ const splitEntry = (entry, separator) => {
|
|
|
338
354
|
});
|
|
339
355
|
};
|
|
340
356
|
//#endregion
|
|
341
|
-
export { DEFAULT_ENTRY_SEPARATOR, HINT_UNDERLINE_CLASS_NAME, Tooltip, TooltipProvider, copyToClipboard, createChangeInputEvent, createPrefixedString, debounce, isMac, keyCodes, noop, splitEntry, useSHA256, withHiddenFullscreen, withTooltipProvider, withVisualSettle };
|
|
357
|
+
export { DEFAULT_ENTRY_SEPARATOR, HINT_UNDERLINE_CLASS_NAME, Tooltip, TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger, copyToClipboard, createChangeInputEvent, createPrefixedString, debounce, isMac, keyCodes, noop, splitEntry, useSHA256, withHiddenFullscreen, withTooltipProvider, withVisualSettle };
|
|
342
358
|
|
|
343
|
-
//# sourceMappingURL=utils-
|
|
359
|
+
//# sourceMappingURL=utils-LQ4jJA-9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-LQ4jJA-9.js","names":["Root"],"sources":["../src/utils/copyToClipboard.ts","../src/utils/createChangeInputEvent.ts","../src/constants/keyCodes.ts","../src/components/Tooltip/TooltipContent.tsx","../src/components/Tooltip/TooltipRoot.tsx","../src/components/Tooltip/TooltipTitle.tsx","../src/components/Tooltip/TooltipTrigger.tsx","../src/components/Tooltip/Tooltip.tsx","../src/utils/decorators.tsx","../src/utils/createPrefixedString.ts","../src/utils/noop.ts","../src/utils/debounce.ts","../src/utils/isMac.ts","../src/utils/useSHA256.ts","../src/utils/splitEntry.ts"],"sourcesContent":["/**\n * The async Clipboard API requires the document to be focused and rejects with\n * `NotAllowedError: Document is not focused` otherwise — which is the normal state\n * for a page inside an iframe that has not taken focus, such as Storybook's canvas\n * or an embedded preview. `execCommand` has no such requirement because it copies\n * the selection of a node we focus ourselves, so it covers that gap.\n */\nconst copyViaSelection = (text: string) => {\n const node = document.createElement('textarea');\n node.value = text;\n node.setAttribute('readonly', '');\n node.style.cssText = 'position:fixed;top:0;left:0;opacity:0';\n document.body.append(node);\n node.select();\n\n try {\n return document.execCommand('copy');\n } finally {\n node.remove();\n }\n};\n\nexport const copyToClipboard = async (text: string) => {\n try {\n await navigator.clipboard.writeText(text);\n } catch (error) {\n if (!copyViaSelection(text)) throw error;\n }\n};\n","import type { ChangeEvent } from 'react';\n\nexport const createChangeInputEvent = (input: HTMLInputElement) => {\n const changeEvent: ChangeEvent<HTMLInputElement> = {\n target: input,\n currentTarget: input,\n type: 'change',\n nativeEvent: new Event('change', { bubbles: true }),\n bubbles: true,\n cancelable: false,\n defaultPrevented: false,\n eventPhase: 2, // AT_TARGET\n isTrusted: false,\n preventDefault: () => {},\n isDefaultPrevented: () => false,\n stopPropagation: () => {},\n isPropagationStopped: () => false,\n persist: () => {},\n timeStamp: Date.now(),\n };\n\n Object.defineProperty(changeEvent, 'target', {\n value: input,\n writable: false,\n });\n\n return changeEvent;\n};\n","export const keyCodes = {\n ENTER: 'Enter',\n ESCAPE: 'Escape',\n SPACE: ' ',\n};\n","import type { ComponentProps } from 'react';\nimport { Content, Portal } from '@radix-ui/react-tooltip';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\n\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nconst tooltipVariants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:inline-block',\n 'tw:wrap-anywhere',\n 'tw:max-h-96',\n 'tw:overflow-y-auto',\n // Above Modal (1051) and every popup (1055); a hover card stays at 1051.\n 'tw:z-[1060]',\n\n // rich content\n 'tw:[&_hr]:my-3',\n 'tw:[&_hr]:border-current/20',\n 'tw:[&_p:last-of-type]:mb-0',\n\n // legacy (dark) chrome — default\n 'tw:rounded',\n 'tw:bg-neutral-800',\n 'tw:text-white',\n 'tw:data-[tooltip-content=true]:[&_a]:text-inherit',\n\n // argo chrome overrides\n 'tw:data-[argo=true]:rounded-popover',\n 'tw:data-[argo=true]:border',\n 'tw:data-[argo=true]:border-solid',\n 'tw:data-[argo=true]:border-border',\n 'tw:data-[argo=true]:bg-popover',\n 'tw:data-[argo=true]:text-popover-foreground',\n 'tw:data-[argo=true]:shadow-md',\n\n // argo open animation\n 'tw:data-[argo=true]:data-[state=delayed-open]:animate-in',\n 'tw:data-[argo=true]:data-[state=instant-open]:animate-in',\n 'tw:data-[argo=true]:data-[state=delayed-open]:fade-in-0',\n 'tw:data-[argo=true]:data-[state=instant-open]:fade-in-0',\n 'tw:data-[argo=true]:data-[state=delayed-open]:zoom-in-95',\n 'tw:data-[argo=true]:data-[state=instant-open]:zoom-in-95',\n\n // argo closed animation\n 'tw:data-[argo=true]:data-[state=closed]:animate-out',\n 'tw:data-[argo=true]:data-[state=closed]:fade-out-0',\n 'tw:data-[argo=true]:data-[state=closed]:zoom-out-95',\n\n // argo position animation\n 'tw:data-[argo=true]:data-[side=bottom]:slide-in-from-top-2',\n 'tw:data-[argo=true]:data-[side=left]:slide-in-from-right-2',\n 'tw:data-[argo=true]:data-[side=right]:slide-in-from-left-2',\n 'tw:data-[argo=true]:data-[side=top]:slide-in-from-bottom-2',\n ],\n {\n defaultVariants: {\n variant: 'action',\n },\n variants: {\n variant: {\n action: [\n 'tw:max-w-fit',\n 'tw:px-3',\n 'tw:py-2',\n\n 'tw:text-center',\n 'tw:text-xs',\n 'tw:font-medium',\n // Uppercase on legacy chrome only; argo reads standard case.\n 'tw:data-[tooltip-content=true]:uppercase',\n 'tw:data-[tooltip-content=true]:tracking-wider',\n ],\n explanatory: [\n 'tw:max-w-80',\n 'tw:px-4',\n 'tw:py-3',\n 'tw:text-left',\n\n 'tw:text-sm',\n 'tw:font-normal',\n ],\n },\n },\n },\n);\n\ntype Props = {\n keepOpenOnPointerDownOutside?: boolean;\n /** Force argo (`true`) or legacy (`false`) chrome; `undefined` follows the brand. */\n argo?: boolean;\n placement?: ComponentProps<typeof Content>['side'];\n} & Omit<ComponentProps<typeof Content>, 'side'> &\n VariantProps<typeof tooltipVariants>;\n\nexport const TooltipContent = ({\n className,\n variant,\n keepOpenOnPointerDownOutside = false,\n argo,\n children,\n onPointerDownOutside,\n sideOffset = 8,\n collisionPadding = 8,\n hideWhenDetached = true,\n placement = 'right',\n ...rest\n}: Props) => {\n const brandIsArgo = useArgoDesign();\n const renderArgo = argo ?? brandIsArgo;\n\n const handlePointerDownOutside: ComponentProps<typeof Content>['onPointerDownOutside'] = (\n event,\n ) => {\n if (keepOpenOnPointerDownOutside) event.preventDefault();\n onPointerDownOutside?.(event);\n };\n\n return (\n <Portal>\n <Content\n {...rest}\n // styles.css inverts nested `.tw\\:prose` on the dark chrome.\n data-tooltip-content={renderArgo ? undefined : true}\n data-argo={renderArgo}\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n onPointerDownOutside={handlePointerDownOutside}\n className={tooltipVariants({ className, variant })}\n hideWhenDetached={hideWhenDetached}\n side={placement}\n >\n {children}\n </Content>\n </Portal>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Root } from '@radix-ui/react-tooltip';\n\ntype Props = ComponentProps<typeof Root>;\n\nconst DELAY_SHOW_TOOLTIP = 300;\n\nexport const TooltipRoot = ({ children, delayDuration = DELAY_SHOW_TOOLTIP, ...rest }: Props) => (\n <Root {...rest} delayDuration={delayDuration}>\n {children}\n </Root>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\n/**\n * Small uppercase heading above a rich tooltip's body copy.\n *\n * - Takes the tooltip's text colour, so it reads on both the legacy and the argo chrome.\n */\nexport const TooltipTitle = ({ className, ...rest }: ComponentProps<'div'>) => (\n <div\n className={cn('tw:mb-2 tw:text-xs tw:leading-5 tw:font-semibold tw:uppercase', className)}\n {...rest}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { Trigger } from '@radix-ui/react-tooltip';\n\nimport { cn } from '../../utils';\n\n/**\n * Radix stamps the tooltip's own open/closed `data-state` onto the trigger. Merged onto an\n * `asChild` child that keeps a `data-state` of its own — `ToggleGroup.Item`, `Switch`, a `Tabs`\n * trigger — it wins, because those primitives spread incoming props *after* their own attribute.\n * The child then silently loses every `data-[state=…]` style it has, which is usually the only\n * thing marking it as selected.\n *\n * The tooltip's trigger state is styled nowhere, so it is dropped before it reaches the child.\n */\nconst WithoutTooltipState = ({\n children,\n ...props\n // `Slot`'s own props, plus the one attribute this exists to remove: React's types declare no\n // `data-*`, so it has to be named to be destructured away.\n}: ComponentProps<typeof Slot> & { 'data-state'?: string }) => {\n const { 'data-state': _tooltipState, ...rest } = props;\n\n return <Slot {...rest}>{children}</Slot>;\n};\n\ntype Props = {\n keepOpenOnClick?: boolean;\n} & ComponentProps<typeof Trigger>;\n\nexport const TooltipTrigger = ({\n ref,\n children,\n className,\n keepOpenOnClick = false,\n onClick,\n onPointerDown,\n asChild,\n ...rest\n}: Props) => {\n const handleClick: ComponentProps<typeof Trigger>['onClick'] = (event) => {\n if (keepOpenOnClick) event.preventDefault();\n onClick?.(event);\n };\n\n const handlePointerDown: ComponentProps<typeof Trigger>['onPointerDown'] = (event) => {\n if (keepOpenOnClick) event.preventDefault();\n onPointerDown?.(event);\n };\n\n return (\n <Trigger\n {...rest}\n asChild\n ref={ref}\n className={cn('tailwindcss-preflight', className)}\n onClick={handleClick}\n onPointerDown={handlePointerDown}\n >\n {asChild ? (\n <WithoutTooltipState>{children}</WithoutTooltipState>\n ) : (\n // Default-mode trigger wraps children in a span so Radix has a\n // single DOM element to attach handlers to. `tailwindcss-preflight`\n // (merged in via Slot) activates Tailwind's preflight inside the\n // span, which sets `svg { display: block }` — without an inline-flex\n // container that would stack any bare Lucide icon onto its own\n // line. `tw:inline-flex tw:items-center` keeps icon + text aligned.\n <span className=\"tw:inline-flex tw:items-center\">{children}</span>\n )}\n </Trigger>\n );\n};\n","import { useState } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport type { Content, Trigger } from '@radix-ui/react-tooltip';\nimport { Provider } from '@radix-ui/react-tooltip';\n\nimport { keyCodes } from '../../constants/keyCodes';\n\nimport { TooltipContent } from './TooltipContent';\nimport { TooltipRoot } from './TooltipRoot';\nimport { TooltipTitle } from './TooltipTitle';\nimport { TooltipTrigger } from './TooltipTrigger';\n\nconst ACTION_TOOLTIP_LIMIT = 30;\n\n/**\n * New-design-only DOM; a trigger inside it gets the argo tooltip whatever the brand.\n *\n * - Matched on DOM ancestry, not React context, so overlays portaled to `document.body` follow the brand.\n */\nconst NEW_DESIGN_CHROME_SELECTOR = '[data-slot=\"navbar\"], [data-slot=\"sidebar\"]';\n\nexport const HINT_UNDERLINE_CLASS_NAME =\n 'tw:cursor-help tw:underline tw:decoration-dashed tw:decoration-neutral-300 tw:underline-offset-2';\n\ntype TriggerProps = {\n triggerAsChild?: boolean;\n};\n\nexport type Props = {\n /** Stays open on trigger click (click-to-copy feedback). */\n keepOpenOnTriggerClick?: boolean;\n /** Plain text only — interactive content belongs in `HoverCard` / `Popover`. */\n tooltip: ReactNode;\n children: ReactNode;\n placement?: ComponentProps<typeof Content>['side'];\n /** Hides it regardless of hover. */\n forceHide?: boolean;\n /** Shows it regardless of hover (e.g. guided tours). */\n forceShow?: boolean;\n /** In ms; defaults to the shared 300ms. */\n delayDuration?: number;\n /** Dashed-underline hover hint on the trigger. */\n hintUnderline?: boolean;\n /** Force one chrome. Default: argo inside `Navbar` / `Sidebar` DOM, else the brand's. */\n chrome?: 'argo' | 'legacy';\n className?: string;\n} & TriggerProps &\n Pick<ComponentProps<typeof TooltipContent>, 'variant' | 'className'>;\n\n/** Mount once at the app root so tooltips share delay state. */\nexport const TooltipProvider = Provider;\n\n/**\n * Short plain-text label on hover or focus.\n *\n * - Use for icon-only buttons, disabled controls, truncated values.\n * - Rich content → `HoverCard`; links or buttons → `Popover` (they break a11y here).\n * - `variant` defaults to `\"explanatory\"` for strings over 30 chars, else `\"action\"`.\n *\n * @see RECIPES.md#disabled-button-tooltip\n */\nexport const Tooltip = ({\n tooltip,\n children,\n className,\n keepOpenOnTriggerClick = false,\n variant,\n placement = 'right',\n forceHide = false,\n forceShow = false,\n delayDuration,\n chrome,\n triggerAsChild = false,\n hintUnderline = false,\n}: Props) => {\n const [open, setOpen] = useState(false);\n const [triggerElement, setTriggerElement] = useState<HTMLElement | null>(null);\n\n const argo = (() => {\n if (chrome) return chrome === 'argo';\n if (triggerElement?.closest(NEW_DESIGN_CHROME_SELECTOR)) return true;\n return undefined;\n })();\n\n const resolvedVariant = (() => {\n if (!!variant) return variant;\n if (typeof tooltip === 'string' && tooltip.length > ACTION_TOOLTIP_LIMIT) return 'explanatory';\n\n return 'action';\n })();\n\n const isActionVariant = resolvedVariant === 'action';\n\n const handleKeyUp: ComponentProps<typeof Trigger>['onKeyUp'] = (event) => {\n if (![keyCodes.ENTER, keyCodes.SPACE].includes(event.key)) return;\n event.stopPropagation();\n };\n\n return (\n <TooltipRoot\n open={!!tooltip && (open || forceShow) && !forceHide}\n onOpenChange={setOpen}\n delayDuration={delayDuration}\n disableHoverableContent={isActionVariant}\n >\n <TooltipTrigger\n ref={setTriggerElement}\n asChild={triggerAsChild}\n keepOpenOnClick={keepOpenOnTriggerClick}\n onKeyUp={handleKeyUp}\n className={hintUnderline ? HINT_UNDERLINE_CLASS_NAME : undefined}\n >\n {children}\n </TooltipTrigger>\n\n <TooltipContent\n className={className}\n variant={resolvedVariant}\n placement={placement}\n argo={argo}\n keepOpenOnPointerDownOutside={keepOpenOnTriggerClick}\n >\n {tooltip}\n </TooltipContent>\n </TooltipRoot>\n );\n};\n\nTooltip.Root = TooltipRoot;\nTooltip.Content = TooltipContent;\nTooltip.Trigger = TooltipTrigger;\nTooltip.Title = TooltipTitle;\n","import type { ComponentType } from 'react';\n\nimport { TooltipProvider } from '../components/Tooltip';\n\nexport const withTooltipProvider = (Story: ComponentType) => (\n <TooltipProvider>\n <Story />\n </TooltipProvider>\n);\n\n// Marks a story whose final render arrives asynchronously (lazy chunk, debounced\n// parse). The visual suite waits for every `[data-skeleton]` inside this box to\n// unmount before capturing, so the baseline is the settled content, never the\n// placeholder it briefly shows.\nexport const withVisualSettle = (Story: ComponentType) => (\n <div data-visual-settle>\n <Story />\n </div>\n);\n\n// position:fixed only fills the Storybook iframe, not the browser window.\nexport const withHiddenFullscreen = (Story: ComponentType) => (\n <div className=\"tw:[&_[aria-label=Fullscreen]]:hidden\">\n <Story />\n </div>\n);\n","export const createPrefixedString = (prefix: string) => (literals: TemplateStringsArray) =>\n literals.reduce((acc, literal) => acc + literal, `${prefix}-`);\n","export const noop = () => void 0;\n","type DebouncedFn<T extends (...args: any[]) => void> = {\n (...args: Parameters<T>): void;\n cancel: () => void;\n};\n\nexport const debounce = <T extends (...args: any[]) => void>(\n fn: T,\n delay: number,\n): DebouncedFn<T> => {\n let timeoutId: ReturnType<typeof setTimeout>;\n const debounced = (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n debounced.cancel = () => clearTimeout(timeoutId);\n return debounced;\n};\n","// Platform detection\ntype NavigatorUAData = {\n platform: string;\n brands: { brand: string; version: string }[];\n mobile: boolean;\n};\n\nconst getIsMac = (): boolean => {\n // Modern approach using navigator.userAgentData\n if (typeof navigator !== 'undefined' && 'userAgentData' in navigator) {\n const platform = (navigator.userAgentData as NavigatorUAData).platform;\n\n if (typeof platform === 'string') {\n return platform.toLowerCase() === 'macos';\n }\n }\n\n if (typeof navigator !== 'undefined' && typeof navigator.platform === 'string') {\n return navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n }\n\n // Server-side rendering fallback\n return false;\n};\n\nexport const isMac = getIsMac();\n","import { useEffect, useState } from 'react';\n\n// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\nconst sha256 = async (text: string) => {\n const msgUint8 = new TextEncoder().encode(text);\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n};\n\nexport const useSHA256 = (text?: string) => {\n const [hash, setHash] = useState('');\n\n useEffect(() => {\n if (!text) return;\n let cancelled = false;\n sha256(text).then((h) => {\n if (!cancelled) setHash(h);\n });\n return () => {\n cancelled = true;\n };\n }, [text]);\n\n // Empty input has no hash — derive it during render instead of syncing state\n // in the effect (avoids the extra render and a stale-value frame).\n return text ? hash : '';\n};\n","/** The separator a typed entry is split on when the caller names none. */\nexport const DEFAULT_ENTRY_SEPARATOR = ',';\n\n/**\n * The strings one typed entry stands for.\n *\n * - Parts are trimmed; blanks dropped.\n * - Repeats collapse case-insensitively, matching the combobox's display-string matching.\n * - A `null` separator returns the entry verbatim, untrimmed — the caller must reject blank text.\n */\nexport const splitEntry = (entry: string, separator: string | RegExp | null): string[] => {\n if (separator === null) return [entry];\n\n const seen = new Set<string>();\n return entry\n .split(separator)\n .map((part) => part.trim())\n .filter((part) => {\n if (part === '') return false;\n const key = part.toLowerCase();\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n"],"mappings":"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"}
|
package/dist/vega.js
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { SERIES_TOKENS, createVegaColorResolver } from "./vegaTokens-Ce07C0DH.js";
|
|
2
|
+
//#region src/vega/vegaTheme.ts
|
|
3
|
+
const CHART_FONT = "Inter, system-ui, sans-serif";
|
|
4
|
+
/**
|
|
5
|
+
* The design system's Vega-Lite chart look, following scheme and brand.
|
|
6
|
+
*
|
|
7
|
+
* - `range.category` is `--chart-1..5`, the same palette as `@keboola/design/charts`.
|
|
8
|
+
* - A range set on the spec's own scale still wins (Flint charts rely on it).
|
|
9
|
+
* - Colours are concrete `rgb()` strings — vega never reads the stylesheet — so rebuild on a
|
|
10
|
+
* scheme or brand change; `useVegaTheme` does.
|
|
11
|
+
*/
|
|
12
|
+
const vegaTheme = (scheme, from) => {
|
|
13
|
+
const token = createVegaColorResolver(scheme, from);
|
|
14
|
+
const label = token("muted-foreground");
|
|
15
|
+
const heading = token("foreground");
|
|
16
|
+
const line = token("border");
|
|
17
|
+
return {
|
|
18
|
+
background: "transparent",
|
|
19
|
+
font: CHART_FONT,
|
|
20
|
+
axis: {
|
|
21
|
+
labelColor: label,
|
|
22
|
+
titleColor: heading,
|
|
23
|
+
gridColor: token("border", .6),
|
|
24
|
+
domainColor: line,
|
|
25
|
+
tickColor: line
|
|
26
|
+
},
|
|
27
|
+
legend: {
|
|
28
|
+
labelColor: label,
|
|
29
|
+
titleColor: heading
|
|
30
|
+
},
|
|
31
|
+
header: {
|
|
32
|
+
labelColor: label,
|
|
33
|
+
titleColor: heading
|
|
34
|
+
},
|
|
35
|
+
title: {
|
|
36
|
+
color: heading,
|
|
37
|
+
subtitleColor: label
|
|
38
|
+
},
|
|
39
|
+
text: { color: heading },
|
|
40
|
+
range: {
|
|
41
|
+
category: SERIES_TOKENS.map((name) => token(name)),
|
|
42
|
+
ramp: [token("accent"), token("chart-1")]
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { vegaTheme };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=vegaTheme-BrmVoPEz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vegaTheme-BrmVoPEz.js","names":[],"sources":["../src/vega/vegaTheme.ts"],"sourcesContent":["import type { Config } from 'vega-lite';\n\nimport type { ResolvedColorScheme } from '../components/ThemeProvider/types';\n\nimport { createVegaColorResolver, SERIES_TOKENS } from './vegaTokens';\n\nconst CHART_FONT = 'Inter, system-ui, sans-serif';\n\n/**\n * The design system's Vega-Lite chart look, following scheme and brand.\n *\n * - `range.category` is `--chart-1..5`, the same palette as `@keboola/design/charts`.\n * - A range set on the spec's own scale still wins (Flint charts rely on it).\n * - Colours are concrete `rgb()` strings — vega never reads the stylesheet — so rebuild on a\n * scheme or brand change; `useVegaTheme` does.\n */\nexport const vegaTheme = (scheme: ResolvedColorScheme, from?: Element | null): Config => {\n const token = createVegaColorResolver(scheme, from);\n\n const label = token('muted-foreground');\n const heading = token('foreground');\n const line = token('border');\n\n return {\n background: 'transparent',\n font: CHART_FONT,\n axis: {\n labelColor: label,\n titleColor: heading,\n gridColor: token('border', 0.6),\n domainColor: line,\n tickColor: line,\n },\n legend: { labelColor: label, titleColor: heading },\n header: { labelColor: label, titleColor: heading },\n title: { color: heading, subtitleColor: label },\n text: { color: heading },\n range: {\n category: SERIES_TOKENS.map((name) => token(name)),\n ramp: [token('accent'), token('chart-1')],\n },\n };\n};\n"],"mappings":";;AAMA,MAAM,aAAa;;;;;;;;;AAUnB,MAAa,aAAa,QAA6B,SAAkC;CACvF,MAAM,QAAQ,wBAAwB,QAAQ,IAAI;CAElD,MAAM,QAAQ,MAAM,kBAAkB;CACtC,MAAM,UAAU,MAAM,YAAY;CAClC,MAAM,OAAO,MAAM,QAAQ;CAE3B,OAAO;EACL,YAAY;EACZ,MAAM;EACN,MAAM;GACJ,YAAY;GACZ,YAAY;GACZ,WAAW,MAAM,UAAU,EAAG;GAC9B,aAAa;GACb,WAAW;EACb;EACA,QAAQ;GAAE,YAAY;GAAO,YAAY;EAAQ;EACjD,QAAQ;GAAE,YAAY;GAAO,YAAY;EAAQ;EACjD,OAAO;GAAE,OAAO;GAAS,eAAe;EAAM;EAC9C,MAAM,EAAE,OAAO,QAAQ;EACvB,OAAO;GACL,UAAU,cAAc,KAAK,SAAS,MAAM,IAAI,CAAC;GACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC;EAC1C;CACF;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createChannelResolver } from "./themeTokens-
|
|
1
|
+
import { createChannelResolver } from "./themeTokens-l2Fsfcs7.js";
|
|
2
2
|
//#region src/vega/vegaTokens.ts
|
|
3
3
|
/**
|
|
4
4
|
* Serializes `"R G B"` channels comma-separated, the only form vega parses.
|
|
@@ -67,6 +67,18 @@ const FALLBACK_CHANNELS = {
|
|
|
67
67
|
card: {
|
|
68
68
|
light: "255 255 255",
|
|
69
69
|
dark: "34 34 40"
|
|
70
|
+
},
|
|
71
|
+
muted: {
|
|
72
|
+
light: "241 245 249",
|
|
73
|
+
dark: "38 38 45"
|
|
74
|
+
},
|
|
75
|
+
primary: {
|
|
76
|
+
light: "37 99 235",
|
|
77
|
+
dark: "31 143 255"
|
|
78
|
+
},
|
|
79
|
+
destructive: {
|
|
80
|
+
light: "220 38 38",
|
|
81
|
+
dark: "229 72 77"
|
|
70
82
|
}
|
|
71
83
|
};
|
|
72
84
|
/**
|
|
@@ -81,52 +93,32 @@ const createVegaColorResolver = (scheme, from) => {
|
|
|
81
93
|
const resolve = createChannelResolver(from);
|
|
82
94
|
return (token, alpha) => vegaRgb(resolve(token, FALLBACK_CHANNELS[token][scheme]), alpha);
|
|
83
95
|
};
|
|
84
|
-
//#endregion
|
|
85
|
-
//#region src/vega/vegaTheme.ts
|
|
86
|
-
const CHART_FONT = "Inter, system-ui, sans-serif";
|
|
87
96
|
/**
|
|
88
|
-
*
|
|
97
|
+
* How the second palette tier (series 6-10) is derived from the core hues.
|
|
89
98
|
*
|
|
90
|
-
* -
|
|
91
|
-
*
|
|
92
|
-
* -
|
|
93
|
-
* scheme or brand change; `useVegaTheme` does.
|
|
99
|
+
* - Each hue moves *away* from its surface: darker on light, lighter on dark.
|
|
100
|
+
* Darkening on dark would drop contrast from ~6.7:1 to ~3.7:1.
|
|
101
|
+
* - `amount` is the fraction of the distance travelled toward `towards`.
|
|
94
102
|
*/
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
titleColor: heading
|
|
113
|
-
},
|
|
114
|
-
header: {
|
|
115
|
-
labelColor: label,
|
|
116
|
-
titleColor: heading
|
|
117
|
-
},
|
|
118
|
-
title: {
|
|
119
|
-
color: heading,
|
|
120
|
-
subtitleColor: label
|
|
121
|
-
},
|
|
122
|
-
text: { color: heading },
|
|
123
|
-
range: {
|
|
124
|
-
category: SERIES_TOKENS.map((name) => token(name)),
|
|
125
|
-
ramp: [token("accent"), token("chart-1")]
|
|
126
|
-
}
|
|
127
|
-
};
|
|
103
|
+
const TIER_TWO_SHIFT = {
|
|
104
|
+
light: {
|
|
105
|
+
towards: 0,
|
|
106
|
+
amount: .38
|
|
107
|
+
},
|
|
108
|
+
dark: {
|
|
109
|
+
towards: 255,
|
|
110
|
+
amount: .35
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
/** A series colour's second-tier variant; an input not shaped like `rgb()` comes back unchanged. */
|
|
114
|
+
const tierTwoColour = (colour, scheme) => {
|
|
115
|
+
const channels = colour.match(/\d+/g);
|
|
116
|
+
if (!channels || channels.length < 3) return colour;
|
|
117
|
+
const { towards, amount } = TIER_TWO_SHIFT[scheme];
|
|
118
|
+
const shifted = channels.slice(0, 3).map((c) => Math.round(Number(c) + (towards - Number(c)) * amount));
|
|
119
|
+
return vegaRgb(shifted.join(" "));
|
|
128
120
|
};
|
|
129
121
|
//#endregion
|
|
130
|
-
export { SERIES_TOKENS, createVegaColorResolver,
|
|
122
|
+
export { SERIES_TOKENS, createVegaColorResolver, tierTwoColour };
|
|
131
123
|
|
|
132
|
-
//# sourceMappingURL=
|
|
124
|
+
//# sourceMappingURL=vegaTokens-Ce07C0DH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vegaTokens-Ce07C0DH.js","names":[],"sources":["../src/vega/vegaTokens.ts"],"sourcesContent":["import type { ResolvedColorScheme } from '../components/ThemeProvider/types';\nimport { createChannelResolver } from '../utils/themeTokens';\n\n/**\n * Serializes `\"R G B\"` channels comma-separated, the only form vega parses.\n *\n * - vega reads colours through d3-color 3.1, which answers `null` for the\n * space-separated CSS Color 4 form the rest of the package emits.\n * - A flat fill survives that anyway — the string reaches the SVG attribute and\n * the browser parses it. An interpolated one does not: both endpoints of a\n * sequential ramp collapse, and a quantitative scale paints solid black.\n */\nconst vegaRgb = (channels: string, alpha?: number): string => {\n const c = channels.split(/\\s+/).join(', ');\n return alpha === undefined ? `rgb(${c})` : `rgba(${c}, ${alpha})`;\n};\n\n/** The `--chart-*` slots, in series order. */\nexport const SERIES_TOKENS = ['chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5'] as const;\n\n/**\n * Fallback channels for the tokens a vega chart reads, mirroring the `:root` /\n * `[data-theme='dark']` blocks of `styles.css`. The resolver reaches these only\n * when the live custom property is missing — SSR, or a unit test that loads no\n * CSS.\n */\nconst FALLBACK_CHANNELS = {\n foreground: { light: '30 41 59', dark: '229 230 236' },\n 'muted-foreground': { light: '100 116 139', dark: '141 144 153' },\n border: { light: '229 231 235', dark: '52 53 62' },\n 'chart-1': { light: '31 143 255', dark: '92 173 255' },\n 'chart-2': { light: '0 194 135', dark: '0 230 161' },\n 'chart-3': { light: '146 92 255', dark: '173 133 255' },\n 'chart-4': { light: '245 147 0', dark: '255 190 92' },\n 'chart-5': { light: '237 94 223', dark: '242 140 232' },\n // The sequential ramp's low end and the surface it must stay legible against.\n accent: { light: '224 242 254', dark: '30 58 95' },\n card: { light: '255 255 255', dark: '34 34 40' },\n // Diagram surfaces and accents (`MermaidDiagram`).\n muted: { light: '241 245 249', dark: '38 38 45' },\n primary: { light: '37 99 235', dark: '31 143 255' },\n destructive: { light: '220 38 38', dark: '229 72 77' },\n} as const;\n\nexport type VegaTokenName = keyof typeof FALLBACK_CHANNELS;\n\n/**\n * A vega-serializing token resolver bound to one `getComputedStyle` snapshot.\n *\n * - Answers `rgb(R, G, B)` / `rgba(R, G, B, a)` — see {@link vegaRgb}.\n * - Falls back per scheme when the custom property is not painted.\n * - Build one per palette, never at module level: the values change whenever\n * the scheme or the brand does.\n */\nexport const createVegaColorResolver = (scheme: ResolvedColorScheme, from?: Element | null) => {\n const resolve = createChannelResolver(from);\n\n return (token: VegaTokenName, alpha?: number): string =>\n vegaRgb(resolve(token, FALLBACK_CHANNELS[token][scheme]), alpha);\n};\n\n/**\n * How the second palette tier (series 6-10) is derived from the core hues.\n *\n * - Each hue moves *away* from its surface: darker on light, lighter on dark.\n * Darkening on dark would drop contrast from ~6.7:1 to ~3.7:1.\n * - `amount` is the fraction of the distance travelled toward `towards`.\n */\nconst TIER_TWO_SHIFT = {\n light: { towards: 0, amount: 0.38 },\n dark: { towards: 255, amount: 0.35 },\n} as const;\n\n/** A series colour's second-tier variant; an input not shaped like `rgb()` comes back unchanged. */\nexport const tierTwoColour = (colour: string, scheme: ResolvedColorScheme): string => {\n const channels = colour.match(/\\d+/g);\n if (!channels || channels.length < 3) return colour;\n const { towards, amount } = TIER_TWO_SHIFT[scheme];\n const shifted = channels\n .slice(0, 3)\n .map((c) => Math.round(Number(c) + (towards - Number(c)) * amount));\n return vegaRgb(shifted.join(' '));\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,WAAW,UAAkB,UAA2B;CAC5D,MAAM,IAAI,SAAS,MAAM,KAAK,CAAC,CAAC,KAAK,IAAI;CACzC,OAAO,UAAU,KAAA,IAAY,OAAO,EAAE,KAAK,QAAQ,EAAE,IAAI,MAAM;AACjE;;AAGA,MAAa,gBAAgB;CAAC;CAAW;CAAW;CAAW;CAAW;AAAS;;;;;;;AAQnF,MAAM,oBAAoB;CACxB,YAAY;EAAE,OAAO;EAAY,MAAM;CAAc;CACrD,oBAAoB;EAAE,OAAO;EAAe,MAAM;CAAc;CAChE,QAAQ;EAAE,OAAO;EAAe,MAAM;CAAW;CACjD,WAAW;EAAE,OAAO;EAAc,MAAM;CAAa;CACrD,WAAW;EAAE,OAAO;EAAa,MAAM;CAAY;CACnD,WAAW;EAAE,OAAO;EAAc,MAAM;CAAc;CACtD,WAAW;EAAE,OAAO;EAAa,MAAM;CAAa;CACpD,WAAW;EAAE,OAAO;EAAc,MAAM;CAAc;CAEtD,QAAQ;EAAE,OAAO;EAAe,MAAM;CAAW;CACjD,MAAM;EAAE,OAAO;EAAe,MAAM;CAAW;CAE/C,OAAO;EAAE,OAAO;EAAe,MAAM;CAAW;CAChD,SAAS;EAAE,OAAO;EAAa,MAAM;CAAa;CAClD,aAAa;EAAE,OAAO;EAAa,MAAM;CAAY;AACvD;;;;;;;;;AAYA,MAAa,2BAA2B,QAA6B,SAA0B;CAC7F,MAAM,UAAU,sBAAsB,IAAI;CAE1C,QAAQ,OAAsB,UAC5B,QAAQ,QAAQ,OAAO,kBAAkB,MAAM,CAAC,OAAO,GAAG,KAAK;AACnE;;;;;;;;AASA,MAAM,iBAAiB;CACrB,OAAO;EAAE,SAAS;EAAG,QAAQ;CAAK;CAClC,MAAM;EAAE,SAAS;EAAK,QAAQ;CAAK;AACrC;;AAGA,MAAa,iBAAiB,QAAgB,WAAwC;CACpF,MAAM,WAAW,OAAO,MAAM,MAAM;CACpC,IAAI,CAAC,YAAY,SAAS,SAAS,GAAG,OAAO;CAC7C,MAAM,EAAE,SAAS,WAAW,eAAe;CAC3C,MAAM,UAAU,SACb,MAAM,GAAG,CAAC,CAAC,CACX,KAAK,MAAM,KAAK,MAAM,OAAO,CAAC,KAAK,UAAU,OAAO,CAAC,KAAK,MAAM,CAAC;CACpE,OAAO,QAAQ,QAAQ,KAAK,GAAG,CAAC;AAClC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keboola/design",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "Keboola UI platform design system — shadcn-aligned React primitives, Keboola-branded blocks, and the form bindings built on TanStack Form.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -194,7 +194,7 @@
|
|
|
194
194
|
"@codemirror/state": "^6.7.1",
|
|
195
195
|
"@codemirror/view": "^6.43.9",
|
|
196
196
|
"@iconify-json/lucide": "^1.2.118",
|
|
197
|
-
"@keboola/brand-registry": "^2.
|
|
197
|
+
"@keboola/brand-registry": "^2.1.0",
|
|
198
198
|
"@keboola/codemirror-lang-sql": "^0.7.3",
|
|
199
199
|
"@keboola/tailwind-config": "^1.2.0",
|
|
200
200
|
"@lexical/code": "^0.42.0",
|
|
@@ -236,7 +236,6 @@
|
|
|
236
236
|
"@testing-library/jest-dom": "^7.0.1",
|
|
237
237
|
"@uiw/codemirror-theme-github": "^4.25.11",
|
|
238
238
|
"@uiw/react-codemirror": "^4.25.11",
|
|
239
|
-
"beautiful-mermaid": "^1.1.3",
|
|
240
239
|
"boring-avatars": "^2.0.4",
|
|
241
240
|
"class-variance-authority": "^0.7.1",
|
|
242
241
|
"clsx": "^2.1.1",
|
|
@@ -247,8 +246,8 @@
|
|
|
247
246
|
"input-otp": "^1.4.2",
|
|
248
247
|
"lexical": "^0.42.0",
|
|
249
248
|
"lucide-react": "^1.17.0",
|
|
250
|
-
"mermaid": "^11.17.2",
|
|
251
249
|
"node-diff3": "^3.2.0",
|
|
250
|
+
"pele": "^1.6.0",
|
|
252
251
|
"react-day-picker": "^10.0.1",
|
|
253
252
|
"react-dropzone": "^14.2.3",
|
|
254
253
|
"react-markdown": "^10.1.0",
|
package/src/styles.css
CHANGED
|
@@ -284,10 +284,10 @@
|
|
|
284
284
|
a sticky table header it read as a glowing seam. `--shadow-table` is softer than
|
|
285
285
|
`--shadow-raised` because the header casts a full-width band.
|
|
286
286
|
|
|
287
|
-
Reaches rules that read `var(--shadow-table)` / `var(--shadow-card)` directly,
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
Reaches only rules that read `var(--shadow-table)` / `var(--shadow-card)` directly,
|
|
288
|
+
and no rule in this repo does. It does NOT reach the `shadow-table` / `shadow-card`
|
|
289
|
+
Tailwind utilities: those are `@theme` tokens (theme.css), so v4 inlines the light
|
|
290
|
+
literal into the generated class at build time. Making the
|
|
291
291
|
utilities scheme-aware needs the token to carry a `var(--runtime, fallback)`
|
|
292
292
|
shape, which is a separate change with control-ui / boilerplate to verify against. */
|
|
293
293
|
--shadow-card: 0px 1px 4px rgb(0 0 0 / 0.4);
|