@keboola/design 6.3.0 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mermaid.js CHANGED
@@ -7,6 +7,7 @@ import { Root as Root$1, Trigger, Portal, Content } from '@radix-ui/react-toolti
7
7
  import { cva } from 'class-variance-authority';
8
8
  import { keboolaLegacySidebar, keboolaLegacyTopnav } from '@keboola/brand-registry';
9
9
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
10
+ import { createPortal } from 'react-dom';
10
11
  import DOMPurify from 'dompurify';
11
12
  import { Root, Slottable } from '@radix-ui/react-slot';
12
13
  import * as lucide_react_star from 'lucide-react';
@@ -225,6 +226,7 @@ var Tooltip = ({
225
226
  placement = "right",
226
227
  forceHide = false,
227
228
  forceShow = false,
229
+ delayDuration,
228
230
  // trigger props
229
231
  triggerAsChild = false
230
232
  }) => {
@@ -244,6 +246,7 @@ var Tooltip = ({
244
246
  {
245
247
  open: !!tooltip && (open || forceShow) && !forceHide,
246
248
  onOpenChange: setOpen,
249
+ delayDuration,
247
250
  disableHoverableContent: isActionVariant,
248
251
  children: [
249
252
  /* @__PURE__ */ jsx(
@@ -316,7 +319,8 @@ var Skeleton = ({ height = "md", className, count = 1 }) => {
316
319
  var icons_exports = {};
317
320
  __export(icons_exports, {
318
321
  Google: () => Google,
319
- Keboola: () => Keboola
322
+ Keboola: () => Keboola,
323
+ Microsoft: () => Microsoft
320
324
  });
321
325
  __reExport(icons_exports, lucide_react_star);
322
326
  var Google = forwardRef(
@@ -375,6 +379,7 @@ var Keboola = forwardRef(
375
379
  width: size,
376
380
  height: size,
377
381
  viewBox: "0 0 300 512",
382
+ overflow: "visible",
378
383
  fill: color,
379
384
  className: cn("lucide", className),
380
385
  ...rest,
@@ -386,6 +391,29 @@ var Keboola = forwardRef(
386
391
  )
387
392
  );
388
393
  Keboola.displayName = "Keboola";
394
+ var Microsoft = forwardRef(
395
+ ({ size = 24, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(
396
+ "svg",
397
+ {
398
+ ref,
399
+ xmlns: "http://www.w3.org/2000/svg",
400
+ width: size,
401
+ height: size,
402
+ viewBox: "0 0 21 21",
403
+ fill: "none",
404
+ className: cn("lucide", className),
405
+ ...rest,
406
+ children: [
407
+ /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "10", height: "10", fill: "#F25022" }),
408
+ /* @__PURE__ */ jsx("rect", { x: "11", y: "0", width: "10", height: "10", fill: "#7FBA00" }),
409
+ /* @__PURE__ */ jsx("rect", { x: "0", y: "11", width: "10", height: "10", fill: "#00A4EF" }),
410
+ /* @__PURE__ */ jsx("rect", { x: "11", y: "11", width: "10", height: "10", fill: "#FFB900" }),
411
+ children
412
+ ]
413
+ }
414
+ )
415
+ );
416
+ Microsoft.displayName = "Microsoft";
389
417
  var variants = cva(
390
418
  [
391
419
  "tailwindcss-preflight",
@@ -810,10 +838,13 @@ var ClipboardButton = ({
810
838
  var MIN_SCALE = 0.5;
811
839
  var MAX_SCALE = 3;
812
840
  var ZOOM_STEP = 0.1;
813
- var ZoomableSvg = ({ html, copyText, className }) => {
841
+ var ZoomableSvg = ({ html, copyText, className, allowForeignObject }) => {
814
842
  const safeHtml = useMemo(
815
- () => DOMPurify.sanitize(html, { USE_PROFILES: { svg: true, svgFilters: true } }),
816
- [html]
843
+ () => DOMPurify.sanitize(html, {
844
+ USE_PROFILES: { svg: true, svgFilters: true },
845
+ ...allowForeignObject ? { ADD_TAGS: ["foreignObject"] } : {}
846
+ }),
847
+ [html, allowForeignObject]
817
848
  );
818
849
  const containerRef = useRef(null);
819
850
  const [scale, setScale] = useState(1);
@@ -842,7 +873,7 @@ var ZoomableSvg = ({ html, copyText, className }) => {
842
873
  };
843
874
  el.addEventListener("wheel", onWheel, { passive: false });
844
875
  return () => el.removeEventListener("wheel", onWheel);
845
- }, []);
876
+ }, [isFullscreen]);
846
877
  const didDragRef = useRef(false);
847
878
  const handleMouseDown = useCallback(
848
879
  (e) => {
@@ -949,14 +980,18 @@ var ZoomableSvg = ({ html, copyText, className }) => {
949
980
  }
950
981
  );
951
982
  if (isFullscreen) {
952
- return /* @__PURE__ */ jsx(
953
- "div",
954
- {
955
- role: "presentation",
956
- className: "tw-fixed tw-inset-0 tw-z-[1060] tw-bg-muted tw-p-4",
957
- onClick: stopPropagation,
958
- children: diagramContent
959
- }
983
+ return createPortal(
984
+ /* @__PURE__ */ jsx(
985
+ "div",
986
+ {
987
+ role: "presentation",
988
+ "data-testid": "zoomable-svg-fullscreen",
989
+ className: "tailwindcss-preflight tw-fixed tw-inset-0 tw-z-[1060] tw-bg-muted tw-p-4",
990
+ onClick: stopPropagation,
991
+ children: diagramContent
992
+ }
993
+ ),
994
+ document.body
960
995
  );
961
996
  }
962
997
  return /* @__PURE__ */ jsx(
@@ -970,15 +1005,47 @@ var ZoomableSvg = ({ html, copyText, className }) => {
970
1005
  }
971
1006
  );
972
1007
  };
1008
+
1009
+ // src/blocks/MermaidDiagram/svgTransforms.ts
1010
+ var HTML_TAG = /<[^>]+>/g;
1011
+ var FOREIGN_OBJECT = /(<foreignObject\b[^>]*>)([\s\S]*?)(<\/foreignObject>)/g;
1012
+ var ROOT_SVG_TAG = /^(\s*<svg\b)([^>]*)(>)/i;
1013
+ var flattenForeignObjectLabels = (svg) => svg.replace(FOREIGN_OBJECT, (_match, open, inner, close) => {
1014
+ const text = inner.replace(HTML_TAG, " ").replace(/\s+/g, " ").trim();
1015
+ return `${open}${text}${close}`;
1016
+ });
1017
+ var STYLE_ATTR = /\s+style="([^"]*)"/i;
1018
+ var makeResponsive = (svgString) => {
1019
+ const viewBoxMatch = svgString.match(/viewBox="[^"]*\s([\d.]+)\s[\d.]+"/);
1020
+ const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : void 0;
1021
+ return svgString.replace(ROOT_SVG_TAG, (_match, open, attrs, close) => {
1022
+ const existingStyle = attrs.match(STYLE_ATTR)?.[1] ?? "";
1023
+ const styleDecls = existingStyle.replace(/max-width:\s*[^;"]*;?\s*/gi, "").replace(/\s+/g, " ").trim().replace(/;$/, "");
1024
+ let nextAttrs = attrs.replace(/\s+width="[^"]*"/i, "").replace(/\s+height="[^"]*"/i, "").replace(STYLE_ATTR, "");
1025
+ nextAttrs += ' width="100%"';
1026
+ const styleParts = [styleDecls, vbWidth ? `max-width: ${vbWidth}px` : ""].filter(Boolean).join("; ");
1027
+ if (styleParts) nextAttrs += ` style="${styleParts}"`;
1028
+ return `${open}${nextAttrs}${close}`;
1029
+ });
1030
+ };
973
1031
  var PRIMARY_FALLBACK_CHANNELS = "31 143 255";
974
1032
  var resolvePrimary = () => {
975
1033
  const channels = typeof document === "undefined" ? PRIMARY_FALLBACK_CHANNELS : getComputedStyle(document.documentElement).getPropertyValue("--color-primary").trim() || PRIMARY_FALLBACK_CHANNELS;
976
1034
  return `rgb(${channels})`;
977
1035
  };
978
1036
  var mermaidPromise = null;
1037
+ var registerLucideIconPack = (m) => {
1038
+ m.registerIconPacks([
1039
+ {
1040
+ name: "lucide",
1041
+ loader: () => import('@iconify-json/lucide/icons.json').then((mod) => mod.default)
1042
+ }
1043
+ ]);
1044
+ };
979
1045
  var getMermaid = () => {
980
1046
  if (!mermaidPromise) {
981
1047
  mermaidPromise = import('mermaid').then((m) => {
1048
+ registerLucideIconPack(m.default);
982
1049
  m.default.initialize({
983
1050
  startOnLoad: false,
984
1051
  securityLevel: "strict",
@@ -1042,7 +1109,9 @@ var getMermaid = () => {
1042
1109
  return mermaidPromise;
1043
1110
  };
1044
1111
  var stripFontImports = (svg) => svg.replace(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*\);?\s*/g, "");
1112
+ var hasIconSyntax = (code) => /@\{[^}]*\bicon\s*:/.test(code) || /\b(?:icon|service|group)\b[^\n(]*\(\s*[\w-]+:/.test(code) || /\bfa[bslr]?:fa-/.test(code);
1045
1113
  var tryFastRender = (code) => {
1114
+ if (hasIconSyntax(code)) return null;
1046
1115
  try {
1047
1116
  return stripFontImports(
1048
1117
  renderMermaidSVG(code, {
@@ -1052,27 +1121,11 @@ var tryFastRender = (code) => {
1052
1121
  font: "Inter, system-ui, sans-serif"
1053
1122
  })
1054
1123
  );
1055
- } catch {
1124
+ } catch (err) {
1125
+ console.debug("[MermaidDiagram] fast render unavailable, using async fallback:", err);
1056
1126
  return null;
1057
1127
  }
1058
1128
  };
1059
- var makeResponsive = (svgString) => {
1060
- const viewBoxMatch = svgString.match(/viewBox="[^"]*\s([\d.]+)\s[\d.]+"/);
1061
- const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : void 0;
1062
- let result = svgString.replace(/(<svg[^>]*?)\s+width="[^"]*"/i, '$1 width="100%"').replace(/(<svg[^>]*?)\s+height="[^"]*"/i, "$1");
1063
- if (!vbWidth) return result;
1064
- const hasStyle = /(<svg[^>]*?)\s+style="([^"]*)"/i.test(result);
1065
- if (hasStyle) {
1066
- result = result.replace(/(<svg[^>]*?)\s+style="([^"]*)"/i, (_m, pre, styles) => {
1067
- const cleaned = styles.replace(/max-width:\s*[^;"]*;?\s*/g, "").trim();
1068
- const combined = [cleaned, `max-width: ${vbWidth}px`].filter(Boolean).join("; ");
1069
- return `${pre} style="${combined}"`;
1070
- });
1071
- } else {
1072
- result = result.replace(/<svg/, `<svg style="max-width: ${vbWidth}px"`);
1073
- }
1074
- return result;
1075
- };
1076
1129
  var RENDER_DEBOUNCE_MS = 300;
1077
1130
  var svgCache = /* @__PURE__ */ new Map();
1078
1131
  var resolveSyncSvg = (code) => {
@@ -1113,8 +1166,9 @@ var MermaidDiagram = ({ code }) => {
1113
1166
  try {
1114
1167
  const result = await mermaidModule.default.render(rendererId, code, container);
1115
1168
  if (renderIdRef.current === currentRenderId && result) {
1116
- svgCache.set(code, result.svg);
1117
- setSvg(result.svg);
1169
+ const svgOutput = flattenForeignObjectLabels(result.svg);
1170
+ svgCache.set(code, svgOutput);
1171
+ setSvg(svgOutput);
1118
1172
  setRenderFailed(false);
1119
1173
  }
1120
1174
  } finally {
@@ -1161,7 +1215,8 @@ var MermaidDiagram = ({ code }) => {
1161
1215
  copyText: `\`\`\`mermaid
1162
1216
  ${code}
1163
1217
  \`\`\``,
1164
- className: "tw-my-3"
1218
+ className: "tw-my-3",
1219
+ allowForeignObject: true
1165
1220
  },
1166
1221
  code
1167
1222
  );