@keboola/design 11.2.0 → 11.4.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 +42 -14
- package/CHANGELOG.md +424 -0
- package/COMPONENT-API.md +33 -32
- package/dist/{AIKit-DiS0CVOW.js → AIKit-DDg5DBCG.js} +156 -76
- package/dist/AIKit-DDg5DBCG.js.map +1 -0
- package/dist/{Alert-DfZq9kGe.js → Alert-DHJFrWnS.js} +3 -3
- package/dist/{Alert-DfZq9kGe.js.map → Alert-DHJFrWnS.js.map} +1 -1
- package/dist/{AlertModal-Dp_XuJBW.js → AlertModal-BGJdaRRj.js} +3 -3
- package/dist/{AlertModal-Dp_XuJBW.js.map → AlertModal-BGJdaRRj.js.map} +1 -1
- package/dist/{AppShell-B5GQN6Zs.js → AppShell-DRgJxpXW.js} +29 -10
- package/dist/AppShell-DRgJxpXW.js.map +1 -0
- package/dist/{BrandEditor-DyzgfVkl.js → BrandEditor-Go7w8Zj2.js} +7 -7
- package/dist/{BrandEditor-DyzgfVkl.js.map → BrandEditor-Go7w8Zj2.js.map} +1 -1
- package/dist/{BrandLogo-CJkRd0F8.js → BrandLogo-Dmi7jo21.js} +2 -2
- package/dist/{BrandLogo-CJkRd0F8.js.map → BrandLogo-Dmi7jo21.js.map} +1 -1
- package/dist/{Breadcrumb-Frst8MTA.js → Breadcrumb-uEkM6adI.js} +3 -3
- package/dist/{Breadcrumb-Frst8MTA.js.map → Breadcrumb-uEkM6adI.js.map} +1 -1
- package/dist/{Button-6xBX0nNl.js → Button-DsRrU5F1.js} +6 -5
- package/dist/Button-DsRrU5F1.js.map +1 -0
- package/dist/{Card-BAoZ35CV.js → Card-Dyo7055Q.js} +2 -2
- package/dist/{Card-BAoZ35CV.js.map → Card-Dyo7055Q.js.map} +1 -1
- package/dist/{Checkbox-GJ8-srt4.js → Checkbox-fC0BuO2B.js} +3 -3
- package/dist/{Checkbox-GJ8-srt4.js.map → Checkbox-fC0BuO2B.js.map} +1 -1
- package/dist/{Clipboard-CBJZiviP.js → Clipboard-ChPdiUy3.js} +2 -2
- package/dist/{Clipboard-CBJZiviP.js.map → Clipboard-ChPdiUy3.js.map} +1 -1
- package/dist/{ClipboardButton-ClcluT0C.js → ClipboardButton-D9pDjgkB.js} +3 -3
- package/dist/{ClipboardButton-ClcluT0C.js.map → ClipboardButton-D9pDjgkB.js.map} +1 -1
- package/dist/{CodeEditor-DyaN-Ij2.js → CodeEditor-Cxy3HnKH.js} +244 -113
- package/dist/CodeEditor-Cxy3HnKH.js.map +1 -0
- package/dist/{ColorInput-B8z4j4Y_.js → ColorInput-Bxj-1eLT.js} +3 -3
- package/dist/{ColorInput-B8z4j4Y_.js.map → ColorInput-Bxj-1eLT.js.map} +1 -1
- package/dist/{ColorModeSwitch-dZFZyqy1.js → ColorModeSwitch-CsWLiTBX.js} +3 -3
- package/dist/{ColorModeSwitch-dZFZyqy1.js.map → ColorModeSwitch-CsWLiTBX.js.map} +1 -1
- package/dist/{Combobox-Dgm6Z4ib.js → Combobox-Cs_1pj2q.js} +31 -24
- package/dist/Combobox-Cs_1pj2q.js.map +1 -0
- package/dist/{Command-C0aZfVTq.js → Command-B7ML9YMv.js} +6 -6
- package/dist/{Command-C0aZfVTq.js.map → Command-B7ML9YMv.js.map} +1 -1
- package/dist/{CopyField-BJ96zvXs.js → CopyField-BO_sh-HO.js} +2 -2
- package/dist/{CopyField-BJ96zvXs.js.map → CopyField-BO_sh-HO.js.map} +1 -1
- package/dist/{DateInput-B3UdzRfW.js → DateInput-ZdaMQo5i.js} +4 -4
- package/dist/{DateInput-B3UdzRfW.js.map → DateInput-ZdaMQo5i.js.map} +1 -1
- package/dist/{DatePicker-Dw3DpbUh.js → DatePicker-nA8YdE84.js} +2 -2
- package/dist/{DatePicker-Dw3DpbUh.js.map → DatePicker-nA8YdE84.js.map} +1 -1
- package/dist/{DateRangeInput-DTuySEiq.js → DateRangeInput-DkvNh_sT.js} +4 -4
- package/dist/{DateRangeInput-DTuySEiq.js.map → DateRangeInput-DkvNh_sT.js.map} +1 -1
- package/dist/{DateRangePicker-DCmMHg4s.js → DateRangePicker-DjSUFjh4.js} +6 -6
- package/dist/{DateRangePicker-DCmMHg4s.js.map → DateRangePicker-DjSUFjh4.js.map} +1 -1
- package/dist/{DropdownMenu-t90tVw6l.js → DropdownMenu-CASr-jgl.js} +2 -2
- package/dist/{DropdownMenu-t90tVw6l.js.map → DropdownMenu-CASr-jgl.js.map} +1 -1
- package/dist/{FieldItem-D-h1NeBo.js → FieldItem-CCd9-xnp.js} +3 -3
- package/dist/{FieldItem-D-h1NeBo.js.map → FieldItem-CCd9-xnp.js.map} +1 -1
- package/dist/{FieldItem-CAPj9lj3.d.ts → FieldItem-vhIJW4pj.d.ts} +2 -10
- package/dist/{FileUpload-BRv0TaZk.js → FileUpload-ABThVZyg.js} +2 -2
- package/dist/{FileUpload-BRv0TaZk.js.map → FileUpload-ABThVZyg.js.map} +1 -1
- package/dist/{Form-DHvcFoEi.js → Form-k6PH-em3.js} +8 -8
- package/dist/{Form-DHvcFoEi.js.map → Form-k6PH-em3.js.map} +1 -1
- package/dist/{FormGroup-C41n65cE.js → FormGroup-DbcDtrgU.js} +3 -3
- package/dist/{FormGroup-C41n65cE.js.map → FormGroup-DbcDtrgU.js.map} +1 -1
- package/dist/{FullScreenModal-Cb3PGgh4.js → FullScreenModal-BvPuYibe.js} +3 -3
- package/dist/{FullScreenModal-Cb3PGgh4.js.map → FullScreenModal-BvPuYibe.js.map} +1 -1
- package/dist/{HoverCard-WfDkLK1s.js → HoverCard-B9ZMJxjn.js} +2 -2
- package/dist/{HoverCard-WfDkLK1s.js.map → HoverCard-B9ZMJxjn.js.map} +1 -1
- package/dist/{InputGroup-CdTq8H7c.js → InputGroup-BnLHY0eq.js} +3 -3
- package/dist/{InputGroup-CdTq8H7c.js.map → InputGroup-BnLHY0eq.js.map} +1 -1
- package/dist/{Kbd-CxHAo1oo.js → Kbd-CvSM3D3-.js} +2 -2
- package/dist/{Kbd-CxHAo1oo.js.map → Kbd-CvSM3D3-.js.map} +1 -1
- package/dist/MarkedText-DNGEUVWc.js +67 -0
- package/dist/MarkedText-DNGEUVWc.js.map +1 -0
- package/dist/{MermaidDiagram-ChL3WIQT.js → MermaidDiagram-WkonYErO.js} +6 -87
- package/dist/MermaidDiagram-WkonYErO.js.map +1 -0
- package/dist/{Modal-wqG8nJiK.js → Modal-Coj-H02o.js} +16 -4
- package/dist/Modal-Coj-H02o.js.map +1 -0
- package/dist/{MultiActionButtonGroup-BiIIubiL.js → MultiActionButtonGroup-CxWH7yWK.js} +3 -3
- package/dist/{MultiActionButtonGroup-BiIIubiL.js.map → MultiActionButtonGroup-CxWH7yWK.js.map} +1 -1
- package/dist/{Navbar-BfaPeLUL.js → Navbar-B2UsolVU.js} +3 -3
- package/dist/{Navbar-BfaPeLUL.js.map → Navbar-B2UsolVU.js.map} +1 -1
- package/dist/{PageToolbar-OQg3mPF-.js → PageToolbar-DnbFt14Q.js} +3 -3
- package/dist/{PageToolbar-OQg3mPF-.js.map → PageToolbar-DnbFt14Q.js.map} +1 -1
- package/dist/{Pagination-Cjfda8KG.js → Pagination-C_b7Xhey.js} +2 -2
- package/dist/{Pagination-Cjfda8KG.js.map → Pagination-C_b7Xhey.js.map} +1 -1
- package/dist/{Popconfirm-D7_vfxFd.js → Popconfirm-CILjmzKI.js} +3 -3
- package/dist/{Popconfirm-D7_vfxFd.js.map → Popconfirm-CILjmzKI.js.map} +1 -1
- package/dist/{Popover-CzeHjvrB.js → Popover-BEbQrC_P.js} +22 -19
- package/dist/Popover-BEbQrC_P.js.map +1 -0
- package/dist/{RadioGroup-sIveSsNa.js → RadioGroup-XFzFd1ti.js} +3 -3
- package/dist/{RadioGroup-sIveSsNa.js.map → RadioGroup-XFzFd1ti.js.map} +1 -1
- package/dist/{Search-3UiqNZRj.js → Search-4Bxtt8hS.js} +2 -2
- package/dist/{Search-3UiqNZRj.js.map → Search-4Bxtt8hS.js.map} +1 -1
- package/dist/{SearchInput-C7dF_Ir-.js → SearchInput-f_oY9T4Z.js} +3 -3
- package/dist/{SearchInput-C7dF_Ir-.js.map → SearchInput-f_oY9T4Z.js.map} +1 -1
- package/dist/{SectionNav-8NoTOKO8.js → SectionNav-BpJlisbT.js} +4 -4
- package/dist/{SectionNav-8NoTOKO8.js.map → SectionNav-BpJlisbT.js.map} +1 -1
- package/dist/{Select-Is0VkePH.js → Select-DpcgKqKB.js} +32 -21
- package/dist/Select-DpcgKqKB.js.map +1 -0
- package/dist/{Sheet-Dw9BDvjI.js → Sheet-Chf0kX1E.js} +3 -3
- package/dist/{Sheet-Dw9BDvjI.js.map → Sheet-Chf0kX1E.js.map} +1 -1
- package/dist/{Sidebar-Dcb4rinA.js → Sidebar-Cm6I4dE1.js} +9 -7
- package/dist/{Sidebar-Dcb4rinA.js.map → Sidebar-Cm6I4dE1.js.map} +1 -1
- package/dist/{Slider-BOPfMOMm.js → Slider-pPC_3gz9.js} +3 -3
- package/dist/{Slider-BOPfMOMm.js.map → Slider-pPC_3gz9.js.map} +1 -1
- package/dist/{Switch-CX2A0v50.js → Switch-ChfPKcTE.js} +2 -2
- package/dist/{Switch-CX2A0v50.js.map → Switch-ChfPKcTE.js.map} +1 -1
- package/dist/{Tabs-UMQuDoW8.js → Tabs-eB974xJf.js} +2 -2
- package/dist/{Tabs-UMQuDoW8.js.map → Tabs-eB974xJf.js.map} +1 -1
- package/dist/{TextInput-CMuN1WfY.js → TextInput-DHM6dHmn.js} +3 -3
- package/dist/{TextInput-CMuN1WfY.js.map → TextInput-DHM6dHmn.js.map} +1 -1
- package/dist/{ThemeProvider-QncUrfJn.js → ThemeProvider-DrQJtzpd.js} +90 -14
- package/dist/ThemeProvider-DrQJtzpd.js.map +1 -0
- package/dist/{TimePicker-D9zktB8A.js → TimePicker-BGeqc-Ed.js} +2 -2
- package/dist/{TimePicker-D9zktB8A.js.map → TimePicker-BGeqc-Ed.js.map} +1 -1
- package/dist/{Toast-DQSbs3oA.js → Toast-Dr6Uw7ao.js} +2 -2
- package/dist/{Toast-DQSbs3oA.js.map → Toast-Dr6Uw7ao.js.map} +1 -1
- package/dist/{ZoomableSvg-CZEu6sAq.js → ZoomableSvg-BWnDkR61.js} +4 -4
- package/dist/{ZoomableSvg-CZEu6sAq.js.map → ZoomableSvg-BWnDkR61.js.map} +1 -1
- package/dist/{context-KxxeMHbR.js → context-D7X470dy.js} +5 -34
- package/dist/context-D7X470dy.js.map +1 -0
- package/dist/defaults-i_xG2F_1.js +32 -0
- package/dist/defaults-i_xG2F_1.js.map +1 -0
- package/dist/editors.d.ts +12 -2
- package/dist/editors.js +20 -12
- package/dist/editors.js.map +1 -1
- package/dist/findLiteralMatches-BGBw8Vbl.js +62 -0
- package/dist/findLiteralMatches-BGBw8Vbl.js.map +1 -0
- package/dist/flint.d.ts +15 -0
- package/dist/flint.js +212 -0
- package/dist/flint.js.map +1 -0
- package/dist/index.d.ts +725 -533
- package/dist/index.js +60 -57
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/AppShell.js +2 -2
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChartPanel.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/{DiagramSkeleton-lwBS2YBa.js → internal/blocks/DiagramShared/DiagramSkeleton.js} +3 -3
- package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js.map +1 -0
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
- package/dist/internal/blocks/ErrorState.js +1 -1
- package/dist/internal/blocks/ExportMenu.js +5 -5
- package/dist/internal/blocks/ExportMenu.js.map +1 -1
- 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/MultiActionButtonGroup.js +1 -1
- package/dist/internal/blocks/MultiCombobox.js +15 -11
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +1 -1
- package/dist/internal/blocks/PageToolbar.js +1 -1
- package/dist/internal/blocks/PasswordInput.js +2 -2
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +3 -3
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +2 -2
- package/dist/internal/blocks/StatCard.js +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/Textarea.js +1 -1
- package/dist/internal/blocks/TimeInput.js +3 -3
- package/dist/internal/components/Alert.js +1 -1
- package/dist/internal/components/AlertModal.js +1 -1
- package/dist/internal/components/Avatar.js +1 -1
- package/dist/internal/components/BrandLogo.js +1 -1
- package/dist/internal/components/Breadcrumb.js +1 -1
- package/dist/internal/components/Button.js +1 -1
- package/dist/internal/components/Card.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/DatePicker.js +1 -1
- package/dist/internal/components/DateRangePicker.js +1 -1
- package/dist/internal/components/DropdownMenu.js +1 -1
- package/dist/internal/components/FileUpload.js +1 -1
- package/dist/internal/components/FullScreenModal.js +1 -1
- package/dist/internal/components/HoverCard.js +1 -1
- package/dist/internal/components/InputGroup.js +1 -1
- package/dist/internal/components/Kbd.js +1 -1
- package/dist/internal/components/MarkedText.js +1 -1
- package/dist/internal/components/Modal.js +1 -1
- package/dist/internal/components/Navbar.js +1 -1
- package/dist/internal/components/Pagination.js +1 -1
- package/dist/internal/components/Popconfirm.js +1 -1
- package/dist/internal/components/Popover.js +1 -1
- package/dist/internal/components/RadioGroup.js +1 -1
- package/dist/internal/components/Search.js +1 -1
- package/dist/internal/components/Select.js +1 -1
- package/dist/internal/components/Sheet.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/Switch.js +1 -1
- package/dist/internal/components/Tabs.js +1 -1
- package/dist/internal/components/ThemeProvider.js +4 -3
- package/dist/internal/components/TimePicker.js +1 -1
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Toggle.js +3 -3
- package/dist/internal/components/Toggle.js.map +1 -1
- package/dist/internal/components/Tooltip.js +1 -1
- package/dist/internal/components/Truncated.js +16 -8
- package/dist/internal/components/Truncated.js.map +1 -1
- package/dist/internal/components/ZoomableSvg.js +1 -1
- package/dist/internal/utils.js +3 -3
- package/dist/markdown-editor.js +7 -7
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.js +11 -11
- package/dist/{styles-DSUP_-9Z.js → styles-BAFscjSV.js} +4 -3
- package/dist/styles-BAFscjSV.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/svgTransforms-C9njt92h.js +89 -0
- package/dist/svgTransforms-C9njt92h.js.map +1 -0
- package/dist/testing.js +4 -3
- package/dist/testing.js.map +1 -1
- package/dist/{themeTokens-BNg98Mu9.js → themeTokens-D70HeNVF.js} +13 -6
- package/dist/{themeTokens-BNg98Mu9.js.map → themeTokens-D70HeNVF.js.map} +1 -1
- package/dist/{toast-CjkURw0M.js → toast-DIC0iNRf.js} +3 -3
- package/dist/toast-DIC0iNRf.js.map +1 -0
- package/dist/types-BPcAjMG0.d.ts +10 -0
- package/dist/{useColorSchemeState-CYqcUfSH.js → useColorSchemeState-klihG9-i.js} +2 -2
- package/dist/{useColorSchemeState-CYqcUfSH.js.map → useColorSchemeState-klihG9-i.js.map} +1 -1
- package/dist/{utils-D0c5VAyF.js → utils-B5Z52hYs.js} +2 -2
- package/dist/{utils-D0c5VAyF.js.map → utils-B5Z52hYs.js.map} +1 -1
- package/dist/vega.d.ts +46 -0
- package/dist/vega.js +26 -0
- package/dist/vega.js.map +1 -0
- package/dist/vegaTheme-DfoEQhOy.js +146 -0
- package/dist/vegaTheme-DfoEQhOy.js.map +1 -0
- package/package.json +28 -9
- package/src/styles.css +27 -4
- package/dist/AIKit-DiS0CVOW.js.map +0 -1
- package/dist/AppShell-B5GQN6Zs.js.map +0 -1
- package/dist/Button-6xBX0nNl.js.map +0 -1
- package/dist/CodeEditor-DyaN-Ij2.js.map +0 -1
- package/dist/Combobox-Dgm6Z4ib.js.map +0 -1
- package/dist/DiagramSkeleton-lwBS2YBa.js.map +0 -1
- package/dist/MarkedText-Ckbft5mw.js +0 -44
- package/dist/MarkedText-Ckbft5mw.js.map +0 -1
- package/dist/MermaidDiagram-ChL3WIQT.js.map +0 -1
- package/dist/Modal-wqG8nJiK.js.map +0 -1
- package/dist/Popover-CzeHjvrB.js.map +0 -1
- package/dist/Select-Is0VkePH.js.map +0 -1
- package/dist/ThemeProvider-QncUrfJn.js.map +0 -1
- package/dist/context-KxxeMHbR.js.map +0 -1
- package/dist/escapeStringRegexp-8MxP2knR.js +0 -6
- package/dist/escapeStringRegexp-8MxP2knR.js.map +0 -1
- package/dist/styles-DSUP_-9Z.js.map +0 -1
- package/dist/toast-CjkURw0M.js.map +0 -1
package/dist/flint.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { DiagramSkeleton } from "./internal/blocks/DiagramShared/DiagramSkeleton.js";
|
|
2
|
+
import { ZoomableSvg } from "./ZoomableSvg-BWnDkR61.js";
|
|
3
|
+
import { useThemeAttributes } from "./themeTokens-D70HeNVF.js";
|
|
4
|
+
import { SERIES_TOKENS, createVegaColorResolver, vegaRgb, vegaTheme } from "./vegaTheme-DfoEQhOy.js";
|
|
5
|
+
import { DiagramSource, makeResponsive } from "./svgTransforms-C9njt92h.js";
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
//#region src/blocks/FlintChart/flintTheme.ts
|
|
9
|
+
/**
|
|
10
|
+
* How the second palette tier (series 6-10) is derived from the core hues.
|
|
11
|
+
*
|
|
12
|
+
* - Each core hue is pushed *away* from its own surface, so the tier stays
|
|
13
|
+
* in-family but reads as a distinct series: darkened on light, lightened on
|
|
14
|
+
* dark. A single "multiply the channels" rule would darken in both, which on
|
|
15
|
+
* a dark surface moves toward the backdrop — measured, that drops contrast
|
|
16
|
+
* from ~6.7:1 to ~3.7:1, while lightening raises it to ~9:1.
|
|
17
|
+
* - `amount` is the fraction of the distance travelled toward black (light) or
|
|
18
|
+
* white (dark).
|
|
19
|
+
*/
|
|
20
|
+
const TIER_TWO_SHIFT = {
|
|
21
|
+
light: {
|
|
22
|
+
towards: 0,
|
|
23
|
+
amount: .38
|
|
24
|
+
},
|
|
25
|
+
dark: {
|
|
26
|
+
towards: 255,
|
|
27
|
+
amount: .35
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Move an `rgb()` string's channels a fraction of the way toward `towards`
|
|
32
|
+
* (0 = black, 255 = white). Returns the input unchanged if it is not that shape.
|
|
33
|
+
*/
|
|
34
|
+
const shiftChannels = (colour, towards, amount) => {
|
|
35
|
+
const channels = colour.match(/\d+/g);
|
|
36
|
+
if (!channels || channels.length < 3) return colour;
|
|
37
|
+
const shifted = channels.slice(0, 3).map((c) => Math.round(Number(c) + (towards - Number(c)) * amount));
|
|
38
|
+
return vegaRgb(shifted.join(" "));
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Put the design system's categorical chart palette on a Flint input.
|
|
42
|
+
*
|
|
43
|
+
* Series colours are resolved by flint itself during assembly (they land in the
|
|
44
|
+
* Vega-Lite `color` scale's `range`), so unlike the chrome in `vegaTheme` they
|
|
45
|
+
* cannot be set through the compile `config` — they ride `theme_spec.ink.series`
|
|
46
|
+
* on the input instead.
|
|
47
|
+
*
|
|
48
|
+
* `--chart-1..5` is the decorative palette the recharts wrappers in
|
|
49
|
+
* `@keboola/design/charts` already use, so a Flint chart now matches the rest of
|
|
50
|
+
* the platform's data-viz, follows the colour scheme, and re-skins with a brand
|
|
51
|
+
* that overrides `colors.chart` / `colorsDark.chart`.
|
|
52
|
+
*
|
|
53
|
+
* An author-supplied `theme_spec` wins: a fence that names a Flint house (or its
|
|
54
|
+
* own spec) asked for that look deliberately, so it is passed through untouched.
|
|
55
|
+
*
|
|
56
|
+
* `null` is not such a spec. The input is `JSON.parse`d model output, where
|
|
57
|
+
* `"theme_spec": null` is valid JSON, and flint dereferences the value while
|
|
58
|
+
* assembling (`reading 'extends'`) — so leaving it in place throws and the chart
|
|
59
|
+
* falls back to raw source. It is replaced, exactly like a missing one.
|
|
60
|
+
*/
|
|
61
|
+
const withFlintSeriesPalette = (input, scheme) => {
|
|
62
|
+
if (input.theme_spec !== void 0 && input.theme_spec !== null) return input;
|
|
63
|
+
const token = createVegaColorResolver(scheme);
|
|
64
|
+
const categorical = SERIES_TOKENS.map((name) => token(name));
|
|
65
|
+
return {
|
|
66
|
+
...input,
|
|
67
|
+
theme_spec: { ink: {
|
|
68
|
+
surface: { canvas: token("card") },
|
|
69
|
+
series: {
|
|
70
|
+
categorical,
|
|
71
|
+
categoricalExtended: [...categorical, ...categorical.map((colour) => shiftChannels(colour, TIER_TWO_SHIFT[scheme].towards, TIER_TWO_SHIFT[scheme].amount))],
|
|
72
|
+
overflow: token("muted-foreground"),
|
|
73
|
+
sequential: {
|
|
74
|
+
stops: [token("accent"), token("chart-1")],
|
|
75
|
+
space: "lab",
|
|
76
|
+
endpointsAgainstSurface: true
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} }
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/blocks/FlintChart/renderFlintSvg.ts
|
|
84
|
+
/**
|
|
85
|
+
* Compile a Flint `ChartAssemblyInput` to a static SVG string.
|
|
86
|
+
*
|
|
87
|
+
* - `assembleVegaLite` returns a Vega-Lite spec carrying `_`-prefixed internal
|
|
88
|
+
* hint keys (`_width`, `_options`, `_transform`, …) that are not part of the
|
|
89
|
+
* Vega-Lite schema — they are stripped before compiling.
|
|
90
|
+
* - `config` (the scheme-following theme) rides the compile options; flint's
|
|
91
|
+
* spec-side config sets no colours, so the two cannot conflict on merge.
|
|
92
|
+
* - The Vega view renders headless (`renderer: 'none'`); nothing mounts to the
|
|
93
|
+
* DOM, `toSVG()` is the only output.
|
|
94
|
+
*/
|
|
95
|
+
const renderFlintSvg = async (runtime, input, config) => {
|
|
96
|
+
const assembled = runtime.assembleVegaLite(input);
|
|
97
|
+
const vlSpec = Object.fromEntries(Object.entries(assembled).filter(([key]) => !key.startsWith("_")));
|
|
98
|
+
const { spec } = runtime.vegaLite.compile(vlSpec, { config });
|
|
99
|
+
const view = new runtime.vega.View(runtime.vega.parse(spec), { renderer: "none" });
|
|
100
|
+
try {
|
|
101
|
+
await view.runAsync();
|
|
102
|
+
return await view.toSVG();
|
|
103
|
+
} finally {
|
|
104
|
+
view.finalize();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/blocks/FlintChart/FlintChart.tsx
|
|
109
|
+
let runtimePromise = null;
|
|
110
|
+
const getFlintRuntime = () => {
|
|
111
|
+
if (!runtimePromise) runtimePromise = Promise.all([
|
|
112
|
+
import("flint-chart/vegalite"),
|
|
113
|
+
import("vega"),
|
|
114
|
+
import("vega-lite")
|
|
115
|
+
]).then(([flint, vega, vegaLite]) => ({
|
|
116
|
+
assembleVegaLite: flint.assembleVegaLite,
|
|
117
|
+
vega,
|
|
118
|
+
vegaLite
|
|
119
|
+
})).catch((err) => {
|
|
120
|
+
runtimePromise = null;
|
|
121
|
+
throw err;
|
|
122
|
+
});
|
|
123
|
+
return runtimePromise;
|
|
124
|
+
};
|
|
125
|
+
const RENDER_DEBOUNCE_MS = 300;
|
|
126
|
+
const MAX_SOURCE_CHARS = 2e5;
|
|
127
|
+
const MAX_CACHED_CHARTS = 24;
|
|
128
|
+
const svgCache = /* @__PURE__ */ new Map();
|
|
129
|
+
const cacheSvg = (key, svg) => {
|
|
130
|
+
if (!svgCache.has(key) && svgCache.size >= MAX_CACHED_CHARTS) {
|
|
131
|
+
const oldest = svgCache.keys().next();
|
|
132
|
+
if (!oldest.done) svgCache.delete(oldest.value);
|
|
133
|
+
}
|
|
134
|
+
svgCache.set(key, svg);
|
|
135
|
+
};
|
|
136
|
+
const chartCacheKey = (code, themeKey) => `${themeKey}\n${code}`;
|
|
137
|
+
const prevThemeKeyOf = (key) => key.slice(0, key.indexOf("\n"));
|
|
138
|
+
const FlintChart = ({ code, renderActions }) => {
|
|
139
|
+
const { scheme, cacheKey: themeKey } = useThemeAttributes();
|
|
140
|
+
const cacheKey = chartCacheKey(code, themeKey);
|
|
141
|
+
const [svg, setSvg] = useState(() => svgCache.get(cacheKey) ?? null);
|
|
142
|
+
const [renderFailed, setRenderFailed] = useState(false);
|
|
143
|
+
const [prevKey, setPrevKey] = useState(cacheKey);
|
|
144
|
+
const [prevCode, setPrevCode] = useState(code);
|
|
145
|
+
if (cacheKey !== prevKey) {
|
|
146
|
+
const cached = svgCache.get(cacheKey);
|
|
147
|
+
const sameThemeStillStreaming = themeKey === prevThemeKeyOf(prevKey) && code.startsWith(prevCode);
|
|
148
|
+
setPrevKey(cacheKey);
|
|
149
|
+
setPrevCode(code);
|
|
150
|
+
if (cached) setSvg(cached);
|
|
151
|
+
else if (!sameThemeStillStreaming) setSvg(null);
|
|
152
|
+
setRenderFailed(false);
|
|
153
|
+
}
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
if (svgCache.has(cacheKey)) return;
|
|
156
|
+
let cancelled = false;
|
|
157
|
+
let graceTimer;
|
|
158
|
+
const debounceTimer = setTimeout(() => {
|
|
159
|
+
if (code.length > MAX_SOURCE_CHARS) {
|
|
160
|
+
console.error(`[FlintChart] source exceeds ${MAX_SOURCE_CHARS} characters (${code.length}); not rendering`);
|
|
161
|
+
setSvg(null);
|
|
162
|
+
setRenderFailed(true);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
let input;
|
|
166
|
+
try {
|
|
167
|
+
input = JSON.parse(code);
|
|
168
|
+
} catch (err) {
|
|
169
|
+
graceTimer = setTimeout(() => {
|
|
170
|
+
console.debug("[FlintChart] source never became parseable JSON:", err);
|
|
171
|
+
setSvg(null);
|
|
172
|
+
setRenderFailed(true);
|
|
173
|
+
}, 1200);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
getFlintRuntime().then(async (runtime) => {
|
|
177
|
+
if (cancelled) return;
|
|
178
|
+
const svgOutput = makeResponsive(await renderFlintSvg(runtime, withFlintSeriesPalette(input, scheme), vegaTheme(scheme)));
|
|
179
|
+
if (cancelled) return;
|
|
180
|
+
cacheSvg(cacheKey, svgOutput);
|
|
181
|
+
setSvg(svgOutput);
|
|
182
|
+
setRenderFailed(false);
|
|
183
|
+
}).catch((err) => {
|
|
184
|
+
if (cancelled) return;
|
|
185
|
+
console.error("[FlintChart] render failed:", err);
|
|
186
|
+
setSvg(null);
|
|
187
|
+
setRenderFailed(true);
|
|
188
|
+
});
|
|
189
|
+
}, RENDER_DEBOUNCE_MS);
|
|
190
|
+
return () => {
|
|
191
|
+
cancelled = true;
|
|
192
|
+
clearTimeout(debounceTimer);
|
|
193
|
+
if (graceTimer) clearTimeout(graceTimer);
|
|
194
|
+
};
|
|
195
|
+
}, [
|
|
196
|
+
cacheKey,
|
|
197
|
+
code,
|
|
198
|
+
scheme
|
|
199
|
+
]);
|
|
200
|
+
if (renderFailed) return /* @__PURE__ */ jsx(DiagramSource, { code });
|
|
201
|
+
if (svg) return /* @__PURE__ */ jsx(ZoomableSvg, {
|
|
202
|
+
html: svg,
|
|
203
|
+
copyText: `\`\`\`flint\n${code}\n\`\`\``,
|
|
204
|
+
className: "tw:my-3",
|
|
205
|
+
renderActions
|
|
206
|
+
}, svg);
|
|
207
|
+
return /* @__PURE__ */ jsx(DiagramSkeleton, {});
|
|
208
|
+
};
|
|
209
|
+
//#endregion
|
|
210
|
+
export { FlintChart };
|
|
211
|
+
|
|
212
|
+
//# sourceMappingURL=flint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flint.js","names":[],"sources":["../src/blocks/FlintChart/flintTheme.ts","../src/blocks/FlintChart/renderFlintSvg.ts","../src/blocks/FlintChart/FlintChart.tsx"],"sourcesContent":["import type { ChartAssemblyInput } from 'flint-chart';\n\nimport type { ResolvedColorScheme } from '../../components/ThemeProvider/types';\nimport { createVegaColorResolver, SERIES_TOKENS, vegaRgb } from '../../vega/vegaTokens';\n\n/**\n * How the second palette tier (series 6-10) is derived from the core hues.\n *\n * - Each core hue is pushed *away* from its own surface, so the tier stays\n * in-family but reads as a distinct series: darkened on light, lightened on\n * dark. A single \"multiply the channels\" rule would darken in both, which on\n * a dark surface moves toward the backdrop — measured, that drops contrast\n * from ~6.7:1 to ~3.7:1, while lightening raises it to ~9:1.\n * - `amount` is the fraction of the distance travelled toward black (light) or\n * white (dark).\n */\nconst TIER_TWO_SHIFT = {\n light: { towards: 0, amount: 0.38 },\n dark: { towards: 255, amount: 0.35 },\n} as const;\n\n/**\n * Move an `rgb()` string's channels a fraction of the way toward `towards`\n * (0 = black, 255 = white). Returns the input unchanged if it is not that shape.\n */\nconst shiftChannels = (colour: string, towards: number, amount: number): string => {\n const channels = colour.match(/\\d+/g);\n if (!channels || channels.length < 3) return colour;\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\n/**\n * Put the design system's categorical chart palette on a Flint input.\n *\n * Series colours are resolved by flint itself during assembly (they land in the\n * Vega-Lite `color` scale's `range`), so unlike the chrome in `vegaTheme` they\n * cannot be set through the compile `config` — they ride `theme_spec.ink.series`\n * on the input instead.\n *\n * `--chart-1..5` is the decorative palette the recharts wrappers in\n * `@keboola/design/charts` already use, so a Flint chart now matches the rest of\n * the platform's data-viz, follows the colour scheme, and re-skins with a brand\n * that overrides `colors.chart` / `colorsDark.chart`.\n *\n * An author-supplied `theme_spec` wins: a fence that names a Flint house (or its\n * own spec) asked for that look deliberately, so it is passed through untouched.\n *\n * `null` is not such a spec. The input is `JSON.parse`d model output, where\n * `\"theme_spec\": null` is valid JSON, and flint dereferences the value while\n * assembling (`reading 'extends'`) — so leaving it in place throws and the chart\n * falls back to raw source. It is replaced, exactly like a missing one.\n */\nexport const withFlintSeriesPalette = (\n input: ChartAssemblyInput,\n scheme: ResolvedColorScheme,\n): ChartAssemblyInput => {\n if (input.theme_spec !== undefined && input.theme_spec !== null) return input;\n\n const token = createVegaColorResolver(scheme);\n const categorical = SERIES_TOKENS.map((name) => token(name));\n\n return {\n ...input,\n theme_spec: {\n ink: {\n // `endpointsAgainstSurface` below needs to know what the chart sits on.\n surface: { canvas: token('card') },\n series: {\n categorical,\n // Past five series flint drops `categorical` wholesale for its own\n // `tableau10` — brand-blind and scheme-blind — so a six-region or\n // seven-month split would silently stop following the theme. The\n // extended set keeps those on our hues: a second tier shifted away\n // from the surface (darker on light, lighter on dark, per\n // `TIER_TWO_SHIFT`), distinct from the core five but the same family.\n categoricalExtended: [\n ...categorical,\n ...categorical.map((colour) =>\n shiftChannels(colour, TIER_TWO_SHIFT[scheme].towards, TIER_TWO_SHIFT[scheme].amount),\n ),\n ],\n // The tail past even the extended set.\n overflow: token('muted-foreground'),\n // A quantitative `color` field takes this ramp instead of the\n // categorical set. Without it flint synthesises `[black, series[0]]`,\n // which puts pure black at the low end in *both* schemes — invisible\n // cells on a dark surface.\n sequential: {\n stops: [token('accent'), token('chart-1')],\n space: 'lab',\n endpointsAgainstSurface: true,\n },\n },\n },\n },\n };\n};\n","import type { ChartAssemblyInput } from 'flint-chart';\nimport type { assembleVegaLite } from 'flint-chart/vegalite';\nimport type * as vega from 'vega';\nimport type * as vegaLite from 'vega-lite';\nimport type { Config, TopLevelSpec } from 'vega-lite';\n\n// The subset of the lazily imported modules the render pipeline needs. Kept as\n// a parameter (not module state) so the pipeline is unit-testable with a fake\n// runtime, without mocking dynamic imports.\nexport type FlintRuntime = {\n assembleVegaLite: typeof assembleVegaLite;\n vega: Pick<typeof vega, 'View' | 'parse'>;\n vegaLite: Pick<typeof vegaLite, 'compile'>;\n};\n\n/**\n * Compile a Flint `ChartAssemblyInput` to a static SVG string.\n *\n * - `assembleVegaLite` returns a Vega-Lite spec carrying `_`-prefixed internal\n * hint keys (`_width`, `_options`, `_transform`, …) that are not part of the\n * Vega-Lite schema — they are stripped before compiling.\n * - `config` (the scheme-following theme) rides the compile options; flint's\n * spec-side config sets no colours, so the two cannot conflict on merge.\n * - The Vega view renders headless (`renderer: 'none'`); nothing mounts to the\n * DOM, `toSVG()` is the only output.\n */\nexport const renderFlintSvg = async (\n runtime: FlintRuntime,\n input: ChartAssemblyInput,\n config: Config,\n): Promise<string> => {\n const assembled: Record<string, unknown> = runtime.assembleVegaLite(input);\n // `assembleVegaLite` is typed loosely upstream; once the hint keys are gone\n // the remainder is the Vega-Lite spec `compile` expects, which TypeScript\n // cannot see through the untyped boundary — hence the assertion.\n const vlSpec = Object.fromEntries(\n Object.entries(assembled).filter(([key]) => !key.startsWith('_')),\n ) as unknown as TopLevelSpec;\n const { spec } = runtime.vegaLite.compile(vlSpec, { config });\n const view = new runtime.vega.View(runtime.vega.parse(spec), { renderer: 'none' });\n try {\n await view.runAsync();\n return await view.toSVG();\n } finally {\n view.finalize();\n }\n};\n","import { useEffect, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport type { ChartAssemblyInput } from 'flint-chart';\n\nimport { useThemeAttributes } from '../../components/ThemeProvider/useThemeAttributes';\nimport { ZoomableSvg } from '../../components/ZoomableSvg';\nimport { vegaTheme } from '../../vega/vegaTheme';\nimport { DiagramSkeleton } from '../DiagramShared/DiagramSkeleton';\nimport { DiagramSource } from '../DiagramShared/DiagramSource';\nimport { makeResponsive } from '../DiagramShared/svgTransforms';\n\nimport { withFlintSeriesPalette } from './flintTheme';\nimport type { FlintRuntime } from './renderFlintSvg';\nimport { renderFlintSvg } from './renderFlintSvg';\n\nlet runtimePromise: Promise<FlintRuntime> | null = null;\n\n// One memoized promise for the heavy chart stack (flint-chart + vega +\n// vega-lite), reset on failure so a transient chunk-load error can retry on the\n// next render — mirrors `getMermaid()` in `MermaidDiagram`.\nconst getFlintRuntime = (): Promise<FlintRuntime> => {\n if (!runtimePromise) {\n runtimePromise = Promise.all([\n import('flint-chart/vegalite'),\n import('vega'),\n import('vega-lite'),\n ])\n .then(([flint, vega, vegaLite]) => ({\n assembleVegaLite: flint.assembleVegaLite,\n vega,\n vegaLite,\n }))\n .catch((err) => {\n runtimePromise = null;\n throw err;\n });\n }\n return runtimePromise;\n};\n\nconst RENDER_DEBOUNCE_MS = 300;\n\n// No prefix of a JSON document parses, so while a ```flint fence streams in the\n// source is unparseable in exactly the same way a broken one is. Unparseable\n// source is treated as still-streaming (skeleton stays up) until it has been\n// unchanged this long — only then is it shown as raw source.\nconst PARSE_GRACE_MS = 1500;\n\n// Ceiling on the fence source, in characters. `JSON.parse` plus vega's compile\n// and layout are synchronous, so an oversized payload — a model dumping a raw\n// table into the block — would block the main thread and freeze the chat. The\n// prompt caps inline data at ~50 rows; this sits far above a legitimate spec of\n// that size while still refusing anything pathological.\nconst MAX_SOURCE_CHARS = 200_000;\n\n// Module-level SVG cache — persists across component remounts (e.g. tab switches\n// that cause React to remount the tree). The chart chrome colours are baked into\n// the markup, so the key is the code *plus* the theme key (scheme + brand): the\n// same spec is a different SVG under a different colour scheme or brand.\n// Values are stored already `makeResponsive`d, so the string identity is stable\n// and ZoomableSvg's sanitize memo never re-runs for an unchanged chart.\n//\n// Bounded, and evicted oldest-first: a vega SVG is mark-per-datum, so entries run\n// to hundreds of KB, and a long chat visits many distinct charts. `Map` iterates\n// in insertion order, so the first key is the oldest.\nconst MAX_CACHED_CHARTS = 24;\nconst svgCache = new Map<string, string>();\n\nconst cacheSvg = (key: string, svg: string): void => {\n // Overwriting an existing key adds no entry, so it must not evict one — two\n // instances of the same chart both missing the cache and both writing would\n // otherwise cost an unrelated chart its slot.\n if (!svgCache.has(key) && svgCache.size >= MAX_CACHED_CHARTS) {\n const oldest = svgCache.keys().next();\n if (!oldest.done) svgCache.delete(oldest.value);\n }\n svgCache.set(key, svg);\n};\n\nconst chartCacheKey = (code: string, themeKey: string): string => `${themeKey}\\n${code}`;\n\n// The theme half of a cache key — used to tell \"same theme, more source\" (a spec\n// still streaming) from a theme/brand switch, which must not keep a stale chart.\nconst prevThemeKeyOf = (key: string): string => key.slice(0, key.indexOf('\\n'));\n\ntype Props = {\n /** Raw source of a ```flint fence — a flint-chart `ChartAssemblyInput` as pure JSON\n * (`data.values` rows, optional `semantic_types`, and a `chart_spec` naming the\n * chartType and encodings). Rendered through the Vega-Lite backend. */\n code: string;\n /** Extra toolbar controls (e.g. an `ExportMenu`), forwarded to `ZoomableSvg`.\n * Receives the sanitized SVG. Omit to keep the default toolbar. */\n renderActions?: (safeSvg: string) => ReactNode;\n};\n\nexport const FlintChart = ({ code, renderActions }: Props) => {\n // Re-renders whenever the active colour scheme or brand changes, so the chart\n // chrome is re-rendered in the new palette instead of staying a light island\n // on a dark page — same contract as MermaidDiagram.\n const { scheme, cacheKey: themeKey } = useThemeAttributes();\n const cacheKey = chartCacheKey(code, themeKey);\n\n const [svg, setSvg] = useState<string | null>(() => svgCache.get(cacheKey) ?? null);\n const [renderFailed, setRenderFailed] = useState(false);\n\n // Synchronously reset stale state when the code or the theme changes, to avoid\n // a one-frame flash.\n //\n // A cache hit is applied immediately. On a miss the previous SVG is dropped\n // unless *only* the tail of the source grew — i.e. the same spec still\n // streaming in, where holding the last good chart avoids a skeleton flicker\n // between chunks. Anything else (a different spec, or a new theme/brand) must\n // clear: the colours are baked into the markup, so keeping it would show a\n // light chart on a dark page, and keeping a chart for a spec that is no longer\n // on screen is simply wrong.\n const [prevKey, setPrevKey] = useState(cacheKey);\n const [prevCode, setPrevCode] = useState(code);\n if (cacheKey !== prevKey) {\n const cached = svgCache.get(cacheKey);\n const sameThemeStillStreaming =\n themeKey === prevThemeKeyOf(prevKey) && code.startsWith(prevCode);\n setPrevKey(cacheKey);\n setPrevCode(code);\n if (cached) setSvg(cached);\n else if (!sameThemeStillStreaming) setSvg(null);\n setRenderFailed(false);\n }\n\n useEffect(() => {\n if (svgCache.has(cacheKey)) return;\n\n let cancelled = false;\n let graceTimer: ReturnType<typeof setTimeout> | undefined;\n\n const debounceTimer = setTimeout(() => {\n if (code.length > MAX_SOURCE_CHARS) {\n // Not a streaming artifact — a fence this size never becomes renderable,\n // so fail straight to the source instead of waiting out the grace period.\n console.error(\n `[FlintChart] source exceeds ${MAX_SOURCE_CHARS} characters (${code.length}); not rendering`,\n );\n setSvg(null);\n setRenderFailed(true);\n return;\n }\n\n let input: ChartAssemblyInput;\n try {\n input = JSON.parse(code);\n } catch (err) {\n // Likely a fence still streaming — declare failure (and log the parse\n // error) only if the code is still unchanged when the grace period ends.\n graceTimer = setTimeout(() => {\n console.debug('[FlintChart] source never became parseable JSON:', err);\n setSvg(null);\n setRenderFailed(true);\n }, PARSE_GRACE_MS - RENDER_DEBOUNCE_MS);\n return;\n }\n\n getFlintRuntime()\n .then(async (runtime) => {\n if (cancelled) return;\n // Theme resolved at render time, off the live CSS variables — the\n // scheme comes out of the same read as the cache key, so the palette\n // can never be resolved under one scheme and cached under the other.\n const svgOutput = makeResponsive(\n await renderFlintSvg(runtime, withFlintSeriesPalette(input, scheme), vegaTheme(scheme)),\n );\n if (cancelled) return;\n cacheSvg(cacheKey, svgOutput);\n setSvg(svgOutput);\n setRenderFailed(false);\n })\n .catch((err) => {\n if (cancelled) return;\n console.error('[FlintChart] render failed:', err);\n setSvg(null);\n setRenderFailed(true);\n });\n }, RENDER_DEBOUNCE_MS);\n\n return () => {\n cancelled = true;\n clearTimeout(debounceTimer);\n if (graceTimer) clearTimeout(graceTimer);\n };\n }, [cacheKey, code, scheme]);\n\n if (renderFailed) {\n return <DiagramSource code={code} />;\n }\n\n if (svg) {\n return (\n <ZoomableSvg\n // Keyed by the rendered SVG, not the source: while the same fence is\n // still streaming the chart is deliberately held (see above), and keying\n // on `code` would remount it on every chunk — dropping the reader's\n // zoom/pan and re-running the DOMPurify pass over an identical chart.\n key={svg}\n html={svg}\n copyText={`\\`\\`\\`flint\\n${code}\\n\\`\\`\\``}\n className=\"tw:my-3\"\n renderActions={renderActions}\n />\n );\n }\n\n return <DiagramSkeleton />;\n};\n"],"mappings":"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"}
|