@plumile/ui 0.1.146 → 0.1.150

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.
Files changed (72) hide show
  1. package/README.md +3 -0
  2. package/lib/esm/admin/theme/adminSurface.css.js +0 -2
  3. package/lib/esm/atomic/atoms/textarea/textarea.css.js +2 -0
  4. package/lib/esm/atomic/molecules/markdown/components/MarkdownCodeCopyButton.js +19 -35
  5. package/lib/esm/atomic/molecules/markdown/components/MarkdownCodeCopyButton.js.map +1 -1
  6. package/lib/esm/atomic/molecules/markdown/components/MarkdownEmphasis.css.js +0 -1
  7. package/lib/esm/atomic/molecules/markdown/components/MarkdownSubscript.css.js +1 -0
  8. package/lib/esm/backoffice/atoms/copyable_text/CopyableText.js +22 -42
  9. package/lib/esm/backoffice/atoms/copyable_text/CopyableText.js.map +1 -1
  10. package/lib/esm/backoffice/molecules/backoffice_json_viewer/BackofficeJsonViewer.js +2 -1
  11. package/lib/esm/backoffice/molecules/backoffice_json_viewer/BackofficeJsonViewer.js.map +1 -1
  12. package/lib/esm/backoffice/shared/copyWithExecCommand.js +1 -14
  13. package/lib/esm/hooks/useClipboardCopy.js +31 -0
  14. package/lib/esm/hooks/useClipboardCopy.js.map +1 -0
  15. package/lib/esm/index.js +223 -221
  16. package/lib/esm/node_modules/@shikijs/core/dist/index.js +99 -96
  17. package/lib/esm/node_modules/@shikijs/core/dist/index.js.map +1 -1
  18. package/lib/esm/node_modules/@shikijs/core/node_modules/@shikijs/types/dist/index.js.map +1 -1
  19. package/lib/esm/node_modules/@shikijs/primitive/dist/index.js +91 -85
  20. package/lib/esm/node_modules/@shikijs/primitive/dist/index.js.map +1 -1
  21. package/lib/esm/node_modules/@shikijs/primitive/node_modules/@shikijs/types/dist/index.js.map +1 -1
  22. package/lib/esm/node_modules/@vitest/runner/dist/chunk-artifact.js.map +1 -1
  23. package/lib/esm/node_modules/cytoscape/dist/cytoscape.esm.js +1 -1
  24. package/lib/esm/node_modules/cytoscape/dist/cytoscape.esm.js.map +1 -1
  25. package/lib/esm/node_modules/react-shiki/dist/index.js +1 -1
  26. package/lib/esm/node_modules/shiki/dist/bundle-full.js +1 -1
  27. package/lib/esm/node_modules/shiki/dist/bundle-full.js.map +1 -1
  28. package/lib/esm/node_modules/shiki/dist/{chunk-CtajNgzt.js → chunk-D1SwGrFN.js} +2 -2
  29. package/lib/esm/node_modules/shiki/dist/chunk-D1SwGrFN.js.map +1 -0
  30. package/lib/esm/node_modules/shiki/dist/engine-oniguruma.js +1 -1
  31. package/lib/esm/node_modules/shiki/dist/engine-oniguruma.js.map +1 -1
  32. package/lib/esm/node_modules/shiki/dist/{langs-bundle-full-DfKZStlK.js → langs-bundle-full-YTHnHqaM.js} +2 -2
  33. package/lib/esm/node_modules/shiki/dist/{langs-bundle-full-DfKZStlK.js.map → langs-bundle-full-YTHnHqaM.js.map} +1 -1
  34. package/lib/esm/node_modules/shiki/dist/themes.js.map +1 -1
  35. package/lib/esm/node_modules/shiki/node_modules/@shikijs/engine-oniguruma/dist/index.js.map +1 -1
  36. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/apex.js +1 -1
  37. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/apex.js.map +1 -1
  38. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/c3.js +1 -1
  39. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/c3.js.map +1 -1
  40. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/csharp.js +1 -1
  41. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/csharp.js.map +1 -1
  42. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/hack.js +1 -1
  43. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/hack.js.map +1 -1
  44. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/julia.js +1 -1
  45. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/julia.js.map +1 -1
  46. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/just.js +1 -1
  47. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/just.js.map +1 -1
  48. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/latex.js +1 -1
  49. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/latex.js.map +1 -1
  50. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/luau.js +1 -1
  51. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/luau.js.map +1 -1
  52. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/php.js +1 -1
  53. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/php.js.map +1 -1
  54. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/sql.js +1 -1
  55. package/lib/esm/node_modules/shiki/node_modules/@shikijs/langs/dist/sql.js.map +1 -1
  56. package/lib/esm/node_modules/shiki/node_modules/@shikijs/themes/dist/vesper.js +1 -1
  57. package/lib/esm/node_modules/shiki/node_modules/@shikijs/themes/dist/vesper.js.map +1 -1
  58. package/lib/esm/shared/clipboard.js +55 -0
  59. package/lib/esm/shared/clipboard.js.map +1 -0
  60. package/lib/types/atomic/molecules/markdown/components/MarkdownCodeCopyButton.d.ts.map +1 -1
  61. package/lib/types/backoffice/atoms/copyable_text/CopyableText.d.ts.map +1 -1
  62. package/lib/types/backoffice/shared/copyWithExecCommand.d.ts +1 -1
  63. package/lib/types/backoffice/shared/copyWithExecCommand.d.ts.map +1 -1
  64. package/lib/types/hooks/useClipboardCopy.d.ts +9 -0
  65. package/lib/types/hooks/useClipboardCopy.d.ts.map +1 -0
  66. package/lib/types/index.d.ts +2 -0
  67. package/lib/types/index.d.ts.map +1 -1
  68. package/lib/types/shared/clipboard.d.ts +9 -0
  69. package/lib/types/shared/clipboard.d.ts.map +1 -0
  70. package/package.json +4 -4
  71. package/lib/esm/backoffice/shared/copyWithExecCommand.js.map +0 -1
  72. package/lib/esm/node_modules/shiki/dist/chunk-CtajNgzt.js.map +0 -1
package/README.md CHANGED
@@ -129,6 +129,9 @@ flat mental model.
129
129
  - `HighlightCode` is the general code-display primitive. It supports a badge,
130
130
  copy action, placeholder text, highlighted HTML/React content, and a plain
131
131
  preformatted fallback.
132
+ - `copyTextToClipboard`, `copyRichClipboard`, and `useClipboardCopy` provide
133
+ shared clipboard behavior with rich multi-format writes where browsers
134
+ support them and text fallbacks everywhere else.
132
135
  - `BackofficeJsonViewer` is the canonical structured JSON viewer for
133
136
  backoffice surfaces. It safely stringifies unknown values, exposes copy and
134
137
  collapse/expand controls, and accepts max-height and label overrides.
@@ -6,8 +6,6 @@
6
6
  /* empty css */
7
7
  /* empty css */
8
8
  /* empty css */
9
- /* empty css */
10
- /* empty css */
11
9
  import { createRuntimeFn as e } from "@vanilla-extract/recipes/createRuntimeFn";
12
10
  //#region src/admin/theme/adminSurface.css.ts
13
11
  var t = e({
@@ -1,4 +1,6 @@
1
1
  /* empty css */
2
+ /* empty css */
3
+ /* empty css */
2
4
  /* empty css */
3
5
  import { createRuntimeFn as e } from "@vanilla-extract/recipes/createRuntimeFn";
4
6
  //#region src/atomic/atoms/textarea/textarea.css.ts
@@ -1,46 +1,30 @@
1
1
  import { useUiTranslation as e } from "../../../../i18n/useUiTranslation.js";
2
- import { MarkdownCopySuccessSvg as t } from "../../../../icons/markdown/MarkdownCopySuccessSvg.js";
3
- import { MarkdownCopySvg as n } from "../../../../icons/markdown/MarkdownCopySvg.js";
4
- import { copyButton as r, icon as i, label as a } from "./MarkdownCodeCopyButton.css.js";
5
- import { useCallback as o, useEffect as s, useRef as c, useState as l } from "react";
6
- import { jsx as u, jsxs as d } from "react/jsx-runtime";
2
+ import t from "../../../../hooks/useClipboardCopy.js";
3
+ import { MarkdownCopySuccessSvg as n } from "../../../../icons/markdown/MarkdownCopySuccessSvg.js";
4
+ import { MarkdownCopySvg as r } from "../../../../icons/markdown/MarkdownCopySvg.js";
5
+ import { copyButton as i, icon as a, label as o } from "./MarkdownCodeCopyButton.css.js";
6
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
7
7
  //#region src/atomic/molecules/markdown/components/MarkdownCodeCopyButton.tsx
8
- var f = ({ code: f }) => {
9
- let { t: p } = e(), [m, h] = l(!1), g = c(null);
10
- s(() => () => {
11
- g.current != null && window.clearTimeout(g.current);
12
- }, []);
13
- let _ = o(async () => {
14
- try {
15
- let e;
16
- if (typeof navigator < "u" && (e = navigator.clipboard), e != null && typeof e.writeText == "function") await e.writeText(f);
17
- else {
18
- let e = document.createElement("textarea");
19
- e.value = f, e.setAttribute("readonly", ""), e.style.position = "absolute", e.style.left = "-9999px", document.body.appendChild(e), e.select(), document.execCommand("copy"), document.body.removeChild(e);
20
- }
21
- h(!0), g.current != null && window.clearTimeout(g.current), g.current = window.setTimeout(() => {
22
- h(!1), g.current = null;
23
- }, 2e3);
24
- } catch {}
25
- }, [f]), v = p("markdown.code.copyTitle");
26
- m && (v = p("markdown.code.copiedTitle"));
27
- let y = /* @__PURE__ */ u(n, { className: i });
28
- m && (y = /* @__PURE__ */ u(t, { className: i }));
29
- let b = p("markdown.code.copy");
30
- return m && (b = p("markdown.code.copied")), /* @__PURE__ */ d("button", {
31
- className: r,
8
+ var l = ({ code: l }) => {
9
+ let { t: u } = e(), { copiedKey: d, copyText: f } = t(), p = d === l, m = u("markdown.code.copyTitle");
10
+ p && (m = u("markdown.code.copiedTitle"));
11
+ let h = /* @__PURE__ */ s(r, { className: a });
12
+ p && (h = /* @__PURE__ */ s(n, { className: a }));
13
+ let g = u("markdown.code.copy");
14
+ return p && (g = u("markdown.code.copied")), /* @__PURE__ */ c("button", {
15
+ className: i,
32
16
  onClick: () => {
33
- _().catch(() => {});
17
+ f(l, l).catch(() => {});
34
18
  },
35
- title: v,
19
+ title: m,
36
20
  type: "button",
37
- children: [y, /* @__PURE__ */ u("span", {
38
- className: a,
39
- children: b
21
+ children: [h, /* @__PURE__ */ s("span", {
22
+ className: o,
23
+ children: g
40
24
  })]
41
25
  });
42
26
  };
43
27
  //#endregion
44
- export { f as MarkdownCodeCopyButton };
28
+ export { l as MarkdownCodeCopyButton };
45
29
 
46
30
  //# sourceMappingURL=MarkdownCodeCopyButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownCodeCopyButton.js","names":[],"sources":["../../../../../../src/atomic/molecules/markdown/components/MarkdownCodeCopyButton.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState, type JSX } from 'react';\n\nimport { MarkdownCopySuccessSvg } from '../../../../icons/markdown/MarkdownCopySuccessSvg.js';\nimport { MarkdownCopySvg } from '../../../../icons/markdown/MarkdownCopySvg.js';\nimport { useUiTranslation } from '../../../../i18n/useUiTranslation.js';\n\nimport {\n copyButton,\n icon as iconClass,\n label,\n} from './MarkdownCodeCopyButton.css.js';\n\ntype Props = {\n code: string;\n};\n\nexport const MarkdownCodeCopyButton = ({ code }: Props): JSX.Element => {\n const { t } = useUiTranslation();\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<number | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current != null) {\n window.clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n try {\n let clipboard: Clipboard | undefined;\n if (typeof navigator !== 'undefined') {\n clipboard = navigator.clipboard;\n }\n if (clipboard != null && typeof clipboard.writeText === 'function') {\n await clipboard.writeText(code);\n } else {\n const textarea = document.createElement('textarea');\n textarea.value = code;\n textarea.setAttribute('readonly', '');\n textarea.style.position = 'absolute';\n textarea.style.left = '-9999px';\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n }\n setCopied(true);\n if (timeoutRef.current != null) {\n window.clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = window.setTimeout(() => {\n setCopied(false);\n timeoutRef.current = null;\n }, 2000);\n } catch {\n // silently ignore copy failures\n }\n }, [code]);\n\n let buttonTitle = t('markdown.code.copyTitle');\n if (copied) {\n buttonTitle = t('markdown.code.copiedTitle');\n }\n\n let iconElement: JSX.Element = <MarkdownCopySvg className={iconClass} />;\n if (copied) {\n iconElement = <MarkdownCopySuccessSvg className={iconClass} />;\n }\n\n let labelText = t('markdown.code.copy');\n if (copied) {\n labelText = t('markdown.code.copied');\n }\n\n return (\n <button\n className={copyButton}\n onClick={() => {\n handleCopy().catch(() => {\n // ignore copy failures surfaced via promise rejection\n });\n }}\n title={buttonTitle}\n type=\"button\"\n >\n {iconElement}\n <span className={label}>{labelText}</span>\n </button>\n );\n};\n"],"mappings":";;;;;;;AAgBA,IAAa,KAA0B,EAAE,cAA+B;CACtE,IAAM,EAAE,SAAM,EAAiB,GACzB,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAa,EAAsB,IAAI;CAE7C,cACe;EACX,AAAI,EAAW,WAAW,QACxB,OAAO,aAAa,EAAW,OAAO;CAE1C,GACC,CAAC,CAAC;CAEL,IAAM,IAAa,EAAY,YAAY;EACzC,IAAI;GACF,IAAI;GAIJ,IAHI,OAAO,YAAc,QACvB,IAAY,UAAU,YAEpB,KAAa,QAAQ,OAAO,EAAU,aAAc,YACtD,MAAM,EAAU,UAAU,CAAI;QACzB;IACL,IAAM,IAAW,SAAS,cAAc,UAAU;IAQlD,AAPA,EAAS,QAAQ,GACjB,EAAS,aAAa,YAAY,EAAE,GACpC,EAAS,MAAM,WAAW,YAC1B,EAAS,MAAM,OAAO,WACtB,SAAS,KAAK,YAAY,CAAQ,GAClC,EAAS,OAAO,GAChB,SAAS,YAAY,MAAM,GAC3B,SAAS,KAAK,YAAY,CAAQ;GACpC;GAKA,AAJA,EAAU,EAAI,GACV,EAAW,WAAW,QACxB,OAAO,aAAa,EAAW,OAAO,GAExC,EAAW,UAAU,OAAO,iBAAiB;IAE3C,AADA,EAAU,EAAK,GACf,EAAW,UAAU;GACvB,GAAG,GAAI;EACT,QAAQ,CAER;CACF,GAAG,CAAC,CAAI,CAAC,GAEL,IAAc,EAAE,yBAAyB;CAC7C,AAAI,MACF,IAAc,EAAE,2BAA2B;CAG7C,IAAI,IAA2B,kBAAC,GAAD,EAAiB,WAAW,EAAY,CAAA;CACvE,AAAI,MACF,IAAc,kBAAC,GAAD,EAAwB,WAAW,EAAY,CAAA;CAG/D,IAAI,IAAY,EAAE,oBAAoB;CAKtC,OAJI,MACF,IAAY,EAAE,sBAAsB,IAIpC,kBAAC,UAAD;EACE,WAAW;EACX,eAAe;GACb,EAAW,EAAE,YAAY,CAEzB,CAAC;EACH;EACA,OAAO;EACP,MAAK;YARP,CAUG,GACD,kBAAC,QAAD;GAAM,WAAW;aAAQ;EAAgB,CAAA,CACnC;;AAEZ"}
1
+ {"version":3,"file":"MarkdownCodeCopyButton.js","names":[],"sources":["../../../../../../src/atomic/molecules/markdown/components/MarkdownCodeCopyButton.tsx"],"sourcesContent":["import { type JSX } from 'react';\n\nimport { useClipboardCopy } from '../../../../hooks/useClipboardCopy.js';\nimport { MarkdownCopySuccessSvg } from '../../../../icons/markdown/MarkdownCopySuccessSvg.js';\nimport { MarkdownCopySvg } from '../../../../icons/markdown/MarkdownCopySvg.js';\nimport { useUiTranslation } from '../../../../i18n/useUiTranslation.js';\n\nimport {\n copyButton,\n icon as iconClass,\n label,\n} from './MarkdownCodeCopyButton.css.js';\n\ntype Props = {\n code: string;\n};\n\nexport const MarkdownCodeCopyButton = ({ code }: Props): JSX.Element => {\n const { t } = useUiTranslation();\n const { copiedKey, copyText } = useClipboardCopy();\n const copied = copiedKey === code;\n\n let buttonTitle = t('markdown.code.copyTitle');\n if (copied) {\n buttonTitle = t('markdown.code.copiedTitle');\n }\n\n let iconElement: JSX.Element = <MarkdownCopySvg className={iconClass} />;\n if (copied) {\n iconElement = <MarkdownCopySuccessSvg className={iconClass} />;\n }\n\n let labelText = t('markdown.code.copy');\n if (copied) {\n labelText = t('markdown.code.copied');\n }\n\n return (\n <button\n className={copyButton}\n onClick={() => {\n copyText(code, code).catch(() => {\n // ignore copy failures surfaced via promise rejection\n });\n }}\n title={buttonTitle}\n type=\"button\"\n >\n {iconElement}\n <span className={label}>{labelText}</span>\n </button>\n );\n};\n"],"mappings":";;;;;;;AAiBA,IAAa,KAA0B,EAAE,cAA+B;CACtE,IAAM,EAAE,SAAM,EAAiB,GACzB,EAAE,cAAW,gBAAa,EAAiB,GAC3C,IAAS,MAAc,GAEzB,IAAc,EAAE,yBAAyB;CAC7C,AAAI,MACF,IAAc,EAAE,2BAA2B;CAG7C,IAAI,IAA2B,kBAAC,GAAD,EAAiB,WAAW,EAAY,CAAA;CACvE,AAAI,MACF,IAAc,kBAAC,GAAD,EAAwB,WAAW,EAAY,CAAA;CAG/D,IAAI,IAAY,EAAE,oBAAoB;CAKtC,OAJI,MACF,IAAY,EAAE,sBAAsB,IAIpC,kBAAC,UAAD;EACE,WAAW;EACX,eAAe;GACb,EAAS,GAAM,CAAI,EAAE,YAAY,CAEjC,CAAC;EACH;EACA,OAAO;EACP,MAAK;YARP,CAUG,GACD,kBAAC,QAAD;GAAM,WAAW;aAAQ;EAAgB,CAAA,CACnC;;AAEZ"}
@@ -1,5 +1,4 @@
1
1
  /* empty css */
2
- /* empty css */
3
2
  /* empty css */
4
3
  //#region src/atomic/molecules/markdown/components/MarkdownEmphasis.css.ts
5
4
  var e = "_1pjwgns1 _1pjwgns0 txvbqb1o";
@@ -1,4 +1,5 @@
1
1
  /* empty css */
2
+ /* empty css */
2
3
  /* empty css */
3
4
  //#region src/atomic/molecules/markdown/components/MarkdownSubscript.css.ts
4
5
  var e = "_1x14aer1 _1x14aer0 txvbqb96 txvbqb80";
@@ -1,63 +1,43 @@
1
1
  import { cx as e } from "../../../theme/tools.js";
2
2
  import { Button as t } from "../../../atomic/atoms/button/Button.js";
3
- import { copyWithExecCommand as n } from "../../shared/copyWithExecCommand.js";
3
+ import n from "../../../hooks/useClipboardCopy.js";
4
4
  import { feedback as r, root as i, value as a, valueNoTruncate as o } from "./copyableText.css.js";
5
- import { useCallback as s, useEffect as c, useMemo as l, useRef as u, useState as d } from "react";
6
- import { jsx as f, jsxs as p } from "react/jsx-runtime";
7
- import { useTranslation as m } from "react-i18next";
5
+ import { useMemo as s } from "react";
6
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ import { useTranslation as u } from "react-i18next";
8
8
  //#region src/backoffice/atoms/copyable_text/CopyableText.tsx
9
- var h = ({ value: h, copyValue: g, className: _, truncate: v = !0, copyLabel: y, copiedLabel: b }) => {
10
- let { t: x } = m("ui", { useSuspense: !1 }), [S, C] = d(!1), w = u(null), T = y ?? x("backoffice.copyableText.copy", { defaultValue: "Copy" }), E = b ?? x("backoffice.copyableText.copied", { defaultValue: "Copied" }), D = g ?? h, O = l(() => {
9
+ var d = ({ value: d, copyValue: f, className: p, truncate: m = !0, copyLabel: h, copiedLabel: g }) => {
10
+ let { t: _ } = u("ui", { useSuspense: !1 }), { copiedKey: v, copyText: y } = n(1400), b = h ?? _("backoffice.copyableText.copy", { defaultValue: "Copy" }), x = g ?? _("backoffice.copyableText.copied", { defaultValue: "Copied" }), S = f ?? d, C = S, w = v === C, T = s(() => {
11
11
  let t = null;
12
- return v || (t = o), e(a, t, _);
13
- }, [_, v]), k = s(() => {
14
- w.current != null && (window.clearTimeout(w.current), w.current = null);
15
- }, []);
16
- c(() => () => {
17
- k();
18
- }, [k]);
19
- let A = s(async () => {
20
- k();
21
- let e = !1;
22
- try {
23
- if (typeof navigator < "u") {
24
- let { clipboard: t } = navigator;
25
- await t.writeText(D), e = !0;
26
- }
27
- } catch {
28
- e = !1;
29
- }
30
- e ||= n(D), e && (C(!0), w.current = window.setTimeout(() => {
31
- C(!1), w.current = null;
32
- }, 1400));
33
- }, [k, D]), j = () => {
34
- A().catch(() => {});
35
- }, M = null;
36
- return S && (M = /* @__PURE__ */ f("span", {
12
+ return m || (t = o), e(a, t, p);
13
+ }, [p, m]), E = () => {
14
+ y(S, C).catch(() => {});
15
+ }, D = null;
16
+ return w && (D = /* @__PURE__ */ c("span", {
37
17
  className: r,
38
18
  role: "status",
39
19
  "aria-live": "polite",
40
- children: E
41
- })), /* @__PURE__ */ p("span", {
20
+ children: x
21
+ })), /* @__PURE__ */ l("span", {
42
22
  className: i,
43
23
  children: [
44
- /* @__PURE__ */ f("span", {
45
- className: O,
46
- title: h,
47
- children: h
24
+ /* @__PURE__ */ c("span", {
25
+ className: T,
26
+ title: d,
27
+ children: d
48
28
  }),
49
- /* @__PURE__ */ f(t, {
29
+ /* @__PURE__ */ c(t, {
50
30
  type: "button",
51
31
  variant: "secondary",
52
32
  size: "small",
53
- onClick: j,
54
- children: T
33
+ onClick: E,
34
+ children: b
55
35
  }),
56
- M
36
+ D
57
37
  ]
58
38
  });
59
39
  };
60
40
  //#endregion
61
- export { h as CopyableText, h as default };
41
+ export { d as CopyableText, d as default };
62
42
 
63
43
  //# sourceMappingURL=CopyableText.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CopyableText.js","names":[],"sources":["../../../../../src/backoffice/atoms/copyable_text/CopyableText.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type JSX,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '../../../atomic/atoms/button/Button.js';\nimport { cx } from '../../../theme/tools.js';\nimport { copyWithExecCommand } from '../../shared/copyWithExecCommand.js';\n\nimport * as styles from './copyableText.css.js';\n\nexport type CopyableTextProps = {\n value: string;\n copyValue?: string;\n className?: string;\n truncate?: boolean;\n copyLabel?: string;\n copiedLabel?: string;\n};\n\nexport const CopyableText = ({\n value,\n copyValue,\n className,\n truncate = true,\n copyLabel,\n copiedLabel,\n}: CopyableTextProps): JSX.Element => {\n const { t } = useTranslation('ui', { useSuspense: false });\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<number | null>(null);\n const resolvedCopyLabel =\n copyLabel ??\n t('backoffice.copyableText.copy', {\n defaultValue: 'Copy',\n });\n const resolvedCopiedLabel =\n copiedLabel ??\n t('backoffice.copyableText.copied', {\n defaultValue: 'Copied',\n });\n\n const resolvedCopyValue = copyValue ?? value;\n\n const displayClassName = useMemo(() => {\n let noTruncateClass: string | null = null;\n if (!truncate) {\n noTruncateClass = styles.valueNoTruncate;\n }\n return cx(styles.value, noTruncateClass, className);\n }, [className, truncate]);\n\n const clearTimer = useCallback(() => {\n if (timeoutRef.current != null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n }, []);\n\n useEffect(() => {\n return () => {\n clearTimer();\n };\n }, [clearTimer]);\n\n const handleCopy = useCallback(async () => {\n clearTimer();\n let ok = false;\n try {\n if (typeof navigator !== 'undefined') {\n const { clipboard } = navigator;\n await clipboard.writeText(resolvedCopyValue);\n ok = true;\n }\n } catch {\n ok = false;\n }\n\n if (!ok) {\n ok = copyWithExecCommand(resolvedCopyValue);\n }\n\n if (ok) {\n setCopied(true);\n timeoutRef.current = window.setTimeout(() => {\n setCopied(false);\n timeoutRef.current = null;\n }, 1400);\n }\n }, [clearTimer, resolvedCopyValue]);\n\n const handleCopyClick = () => {\n handleCopy().catch(() => {});\n };\n\n let feedbackNode: JSX.Element | null = null;\n if (copied) {\n feedbackNode = (\n <span className={styles.feedback} role=\"status\" aria-live=\"polite\">\n {resolvedCopiedLabel}\n </span>\n );\n }\n\n return (\n <span className={styles.root}>\n <span className={displayClassName} title={value}>\n {value}\n </span>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={handleCopyClick}\n >\n {resolvedCopyLabel}\n </Button>\n {feedbackNode}\n </span>\n );\n};\n\nexport default CopyableText;\n"],"mappings":";;;;;;;;AAyBA,IAAa,KAAgB,EAC3B,OAAA,GACA,cACA,cACA,cAAW,IACX,cACA,qBACoC;CACpC,IAAM,EAAE,SAAM,EAAe,MAAM,EAAE,aAAa,GAAM,CAAC,GACnD,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAa,EAAsB,IAAI,GACvC,IACJ,KACA,EAAE,gCAAgC,EAChC,cAAc,OAChB,CAAC,GACG,IACJ,KACA,EAAE,kCAAkC,EAClC,cAAc,SAChB,CAAC,GAEG,IAAoB,KAAa,GAEjC,IAAmB,QAAc;EACrC,IAAI,IAAiC;EAIrC,OAHK,MACH,IAAkB,IAEb,EAAG,GAAc,GAAiB,CAAS;CACpD,GAAG,CAAC,GAAW,CAAQ,CAAC,GAElB,IAAa,QAAkB;EACnC,AAAI,EAAW,WAAW,SACxB,OAAO,aAAa,EAAW,OAAO,GACtC,EAAW,UAAU;CAEzB,GAAG,CAAC,CAAC;CAEL,cACe;EACX,EAAW;CACb,GACC,CAAC,CAAU,CAAC;CAEf,IAAM,IAAa,EAAY,YAAY;EACzC,EAAW;EACX,IAAI,IAAK;EACT,IAAI;GACF,IAAI,OAAO,YAAc,KAAa;IACpC,IAAM,EAAE,iBAAc;IAEtB,AADA,MAAM,EAAU,UAAU,CAAiB,GAC3C,IAAK;GACP;EACF,QAAQ;GACN,IAAK;EACP;EAMA,AAJA,AACE,MAAK,EAAoB,CAAiB,GAGxC,MACF,EAAU,EAAI,GACd,EAAW,UAAU,OAAO,iBAAiB;GAE3C,AADA,EAAU,EAAK,GACf,EAAW,UAAU;EACvB,GAAG,IAAI;CAEX,GAAG,CAAC,GAAY,CAAiB,CAAC,GAE5B,UAAwB;EAC5B,EAAW,EAAE,YAAY,CAAC,CAAC;CAC7B,GAEI,IAAmC;CASvC,OARI,MACF,IACE,kBAAC,QAAD;EAAM,WAAW;EAAiB,MAAK;EAAS,aAAU;YACvD;CACG,CAAA,IAKR,kBAAC,QAAD;EAAM,WAAW;YAAjB;GACE,kBAAC,QAAD;IAAM,WAAW;IAAkB,OAAO;cACvC;GACG,CAAA;GACN,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,MAAK;IACL,SAAS;cAER;GACK,CAAA;GACP;EACG;;AAEV"}
1
+ {"version":3,"file":"CopyableText.js","names":[],"sources":["../../../../../src/backoffice/atoms/copyable_text/CopyableText.tsx"],"sourcesContent":["import { useMemo, type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '../../../atomic/atoms/button/Button.js';\nimport { useClipboardCopy } from '../../../hooks/useClipboardCopy.js';\nimport { cx } from '../../../theme/tools.js';\n\nimport * as styles from './copyableText.css.js';\n\nexport type CopyableTextProps = {\n value: string;\n copyValue?: string;\n className?: string;\n truncate?: boolean;\n copyLabel?: string;\n copiedLabel?: string;\n};\n\nexport const CopyableText = ({\n value,\n copyValue,\n className,\n truncate = true,\n copyLabel,\n copiedLabel,\n}: CopyableTextProps): JSX.Element => {\n const { t } = useTranslation('ui', { useSuspense: false });\n const { copiedKey, copyText } = useClipboardCopy(1400);\n const resolvedCopyLabel =\n copyLabel ??\n t('backoffice.copyableText.copy', {\n defaultValue: 'Copy',\n });\n const resolvedCopiedLabel =\n copiedLabel ??\n t('backoffice.copyableText.copied', {\n defaultValue: 'Copied',\n });\n\n const resolvedCopyValue = copyValue ?? value;\n const copyKey = resolvedCopyValue;\n const copied = copiedKey === copyKey;\n\n const displayClassName = useMemo(() => {\n let noTruncateClass: string | null = null;\n if (!truncate) {\n noTruncateClass = styles.valueNoTruncate;\n }\n return cx(styles.value, noTruncateClass, className);\n }, [className, truncate]);\n\n const handleCopyClick = () => {\n copyText(resolvedCopyValue, copyKey).catch(() => {});\n };\n\n let feedbackNode: JSX.Element | null = null;\n if (copied) {\n feedbackNode = (\n <span className={styles.feedback} role=\"status\" aria-live=\"polite\">\n {resolvedCopiedLabel}\n </span>\n );\n }\n\n return (\n <span className={styles.root}>\n <span className={displayClassName} title={value}>\n {value}\n </span>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={handleCopyClick}\n >\n {resolvedCopyLabel}\n </Button>\n {feedbackNode}\n </span>\n );\n};\n\nexport default CopyableText;\n"],"mappings":";;;;;;;;AAkBA,IAAa,KAAgB,EAC3B,OAAA,GACA,cACA,cACA,cAAW,IACX,cACA,qBACoC;CACpC,IAAM,EAAE,SAAM,EAAe,MAAM,EAAE,aAAa,GAAM,CAAC,GACnD,EAAE,cAAW,gBAAa,EAAiB,IAAI,GAC/C,IACJ,KACA,EAAE,gCAAgC,EAChC,cAAc,OAChB,CAAC,GACG,IACJ,KACA,EAAE,kCAAkC,EAClC,cAAc,SAChB,CAAC,GAEG,IAAoB,KAAa,GACjC,IAAU,GACV,IAAS,MAAc,GAEvB,IAAmB,QAAc;EACrC,IAAI,IAAiC;EAIrC,OAHK,MACH,IAAkB,IAEb,EAAG,GAAc,GAAiB,CAAS;CACpD,GAAG,CAAC,GAAW,CAAQ,CAAC,GAElB,UAAwB;EAC5B,EAAS,GAAmB,CAAO,EAAE,YAAY,CAAC,CAAC;CACrD,GAEI,IAAmC;CASvC,OARI,MACF,IACE,kBAAC,QAAD;EAAM,WAAW;EAAiB,MAAK;EAAS,aAAU;YACvD;CACG,CAAA,IAKR,kBAAC,QAAD;EAAM,WAAW;YAAjB;GACE,kBAAC,QAAD;IAAM,WAAW;IAAkB,OAAO;cACvC;GACG,CAAA;GACN,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,MAAK;IACL,SAAS;cAER;GACK,CAAA;GACP;EACG;;AAEV"}
@@ -1,6 +1,7 @@
1
1
  import { cx as e } from "../../../theme/tools.js";
2
2
  import { Button as t } from "../../../atomic/atoms/button/Button.js";
3
- import { copyWithExecCommand as n } from "../../shared/copyWithExecCommand.js";
3
+ import { copyWithExecCommand as n } from "../../../shared/clipboard.js";
4
+ import "../../shared/copyWithExecCommand.js";
4
5
  import { actions as r, container as i, header as a, pre as o, title as s, truncated as c } from "./backofficeJsonViewer.css.js";
5
6
  import { useCallback as l, useMemo as u, useState as d } from "react";
6
7
  import { jsx as f, jsxs as p } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeJsonViewer.js","names":[],"sources":["../../../../../src/backoffice/molecules/backoffice_json_viewer/BackofficeJsonViewer.tsx"],"sourcesContent":["import { useCallback, useMemo, useState, type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '../../../atomic/atoms/button/Button.js';\nimport { cx } from '../../../theme/tools.js';\nimport { copyWithExecCommand } from '../../shared/copyWithExecCommand.js';\n\nimport * as styles from './backofficeJsonViewer.css.js';\n\nexport type BackofficeJsonViewerProps = {\n value: unknown;\n title?: string;\n className?: string;\n maxHeight?: string;\n truncate?: boolean;\n truncateLabel?: string;\n expandLabel?: string;\n copyLabel?: string;\n copiedLabel?: string;\n};\n\nexport const BackofficeJsonViewer = ({\n value,\n title,\n className,\n maxHeight,\n truncate = false,\n truncateLabel,\n expandLabel,\n copyLabel,\n copiedLabel,\n}: BackofficeJsonViewerProps): JSX.Element => {\n const { t } = useTranslation('ui');\n const [isCollapsed, setIsCollapsed] = useState(truncate);\n const [copied, setCopied] = useState(false);\n const resolvedTitle = title ?? t('backoffice.jsonViewer.title');\n const resolvedTruncateLabel =\n truncateLabel ?? t('backoffice.jsonViewer.collapse');\n const resolvedExpandLabel = expandLabel ?? t('backoffice.jsonViewer.expand');\n const resolvedCopyLabel = copyLabel ?? t('backoffice.jsonViewer.copy');\n const resolvedCopiedLabel = copiedLabel ?? t('backoffice.jsonViewer.copied');\n\n const jsonText = useMemo(() => {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return JSON.stringify({\n error: t('backoffice.jsonViewer.serializationError'),\n });\n }\n }, [t, value]);\n\n const handleCopy = useCallback(async () => {\n let ok = false;\n try {\n if (typeof navigator !== 'undefined') {\n await navigator.clipboard.writeText(jsonText);\n ok = true;\n }\n } catch {\n ok = false;\n }\n\n if (!ok) {\n ok = copyWithExecCommand(jsonText);\n }\n\n if (ok) {\n setCopied(true);\n window.setTimeout(() => {\n setCopied(false);\n }, 1400);\n }\n }, [jsonText]);\n\n const preStyle = useMemo(() => {\n if (maxHeight == null) {\n return undefined;\n }\n return { maxHeight };\n }, [maxHeight]);\n\n let copyButtonLabel = resolvedCopyLabel;\n if (copied) {\n copyButtonLabel = resolvedCopiedLabel;\n }\n\n let collapseButtonLabel = resolvedTruncateLabel;\n if (isCollapsed) {\n collapseButtonLabel = resolvedExpandLabel;\n }\n\n return (\n <div className={cx(styles.container, className)}>\n <div className={styles.header}>\n <span className={styles.title}>{resolvedTitle}</span>\n <div className={styles.actions}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n handleCopy().catch(() => {});\n }}\n >\n {copyButtonLabel}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n setIsCollapsed((v) => {\n return !v;\n });\n }}\n >\n {collapseButtonLabel}\n </Button>\n </div>\n </div>\n <pre\n className={cx(styles.pre, { [styles.truncated]: isCollapsed })}\n style={preStyle}\n >\n {jsonText}\n </pre>\n </div>\n );\n};\n\nexport default BackofficeJsonViewer;\n"],"mappings":";;;;;;;;AAqBA,IAAa,KAAwB,EACnC,UACA,OAAA,GACA,cACA,cACA,cAAW,IACX,kBACA,gBACA,cACA,qBAC4C;CAC5C,IAAM,EAAE,SAAM,EAAe,IAAI,GAC3B,CAAC,GAAa,KAAkB,EAAS,CAAQ,GACjD,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAgB,KAAS,EAAE,6BAA6B,GACxD,IACJ,KAAiB,EAAE,gCAAgC,GAC/C,IAAsB,KAAe,EAAE,8BAA8B,GACrE,IAAoB,KAAa,EAAE,4BAA4B,GAC/D,IAAsB,KAAe,EAAE,8BAA8B,GAErE,IAAW,QAAc;EAC7B,IAAI;GACF,OAAO,KAAK,UAAU,GAAO,MAAM,CAAC;EACtC,QAAQ;GACN,OAAO,KAAK,UAAU,EACpB,OAAO,EAAE,0CAA0C,EACrD,CAAC;EACH;CACF,GAAG,CAAC,GAAG,CAAK,CAAC,GAEP,IAAa,EAAY,YAAY;EACzC,IAAI,IAAK;EACT,IAAI;GACF,AAAI,OAAO,YAAc,QACvB,MAAM,UAAU,UAAU,UAAU,CAAQ,GAC5C,IAAK;EAET,QAAQ;GACN,IAAK;EACP;EAMA,AAJA,AACE,MAAK,EAAoB,CAAQ,GAG/B,MACF,EAAU,EAAI,GACd,OAAO,iBAAiB;GACtB,EAAU,EAAK;EACjB,GAAG,IAAI;CAEX,GAAG,CAAC,CAAQ,CAAC,GAEP,IAAW,QAAc;EACzB,SAAa,MAGjB,OAAO,EAAE,aAAU;CACrB,GAAG,CAAC,CAAS,CAAC,GAEV,IAAkB;CACtB,AAAI,MACF,IAAkB;CAGpB,IAAI,IAAsB;CAK1B,OAJI,MACF,IAAsB,IAItB,kBAAC,OAAD;EAAK,WAAW,EAAG,GAAkB,CAAS;YAA9C,CACE,kBAAC,OAAD;GAAK,WAAW;aAAhB,CACE,kBAAC,QAAD;IAAM,WAAW;cAAe;GAAoB,CAAA,GACpD,kBAAC,OAAD;IAAK,WAAW;cAAhB,CACE,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACL,eAAe;MACb,EAAW,EAAE,YAAY,CAAC,CAAC;KAC7B;eAEC;IACK,CAAA,GACR,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACL,eAAe;MACb,GAAgB,MACP,CAAC,CACT;KACH;eAEC;IACK,CAAA,CACL;KACF;MACL,kBAAC,OAAD;GACE,WAAW,EAAG,GAAY,GAAG,IAAmB,EAAY,CAAC;GAC7D,OAAO;aAEN;EACE,CAAA,CACF;;AAET"}
1
+ {"version":3,"file":"BackofficeJsonViewer.js","names":[],"sources":["../../../../../src/backoffice/molecules/backoffice_json_viewer/BackofficeJsonViewer.tsx"],"sourcesContent":["import { useCallback, useMemo, useState, type JSX } from 'react';\nimport { useTranslation } from 'react-i18next';\n\nimport { Button } from '../../../atomic/atoms/button/Button.js';\nimport { cx } from '../../../theme/tools.js';\nimport { copyWithExecCommand } from '../../shared/copyWithExecCommand.js';\n\nimport * as styles from './backofficeJsonViewer.css.js';\n\nexport type BackofficeJsonViewerProps = {\n value: unknown;\n title?: string;\n className?: string;\n maxHeight?: string;\n truncate?: boolean;\n truncateLabel?: string;\n expandLabel?: string;\n copyLabel?: string;\n copiedLabel?: string;\n};\n\nexport const BackofficeJsonViewer = ({\n value,\n title,\n className,\n maxHeight,\n truncate = false,\n truncateLabel,\n expandLabel,\n copyLabel,\n copiedLabel,\n}: BackofficeJsonViewerProps): JSX.Element => {\n const { t } = useTranslation('ui');\n const [isCollapsed, setIsCollapsed] = useState(truncate);\n const [copied, setCopied] = useState(false);\n const resolvedTitle = title ?? t('backoffice.jsonViewer.title');\n const resolvedTruncateLabel =\n truncateLabel ?? t('backoffice.jsonViewer.collapse');\n const resolvedExpandLabel = expandLabel ?? t('backoffice.jsonViewer.expand');\n const resolvedCopyLabel = copyLabel ?? t('backoffice.jsonViewer.copy');\n const resolvedCopiedLabel = copiedLabel ?? t('backoffice.jsonViewer.copied');\n\n const jsonText = useMemo(() => {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return JSON.stringify({\n error: t('backoffice.jsonViewer.serializationError'),\n });\n }\n }, [t, value]);\n\n const handleCopy = useCallback(async () => {\n let ok = false;\n try {\n if (typeof navigator !== 'undefined') {\n await navigator.clipboard.writeText(jsonText);\n ok = true;\n }\n } catch {\n ok = false;\n }\n\n if (!ok) {\n ok = copyWithExecCommand(jsonText);\n }\n\n if (ok) {\n setCopied(true);\n window.setTimeout(() => {\n setCopied(false);\n }, 1400);\n }\n }, [jsonText]);\n\n const preStyle = useMemo(() => {\n if (maxHeight == null) {\n return undefined;\n }\n return { maxHeight };\n }, [maxHeight]);\n\n let copyButtonLabel = resolvedCopyLabel;\n if (copied) {\n copyButtonLabel = resolvedCopiedLabel;\n }\n\n let collapseButtonLabel = resolvedTruncateLabel;\n if (isCollapsed) {\n collapseButtonLabel = resolvedExpandLabel;\n }\n\n return (\n <div className={cx(styles.container, className)}>\n <div className={styles.header}>\n <span className={styles.title}>{resolvedTitle}</span>\n <div className={styles.actions}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n handleCopy().catch(() => {});\n }}\n >\n {copyButtonLabel}\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n setIsCollapsed((v) => {\n return !v;\n });\n }}\n >\n {collapseButtonLabel}\n </Button>\n </div>\n </div>\n <pre\n className={cx(styles.pre, { [styles.truncated]: isCollapsed })}\n style={preStyle}\n >\n {jsonText}\n </pre>\n </div>\n );\n};\n\nexport default BackofficeJsonViewer;\n"],"mappings":";;;;;;;;;AAqBA,IAAa,KAAwB,EACnC,UACA,OAAA,GACA,cACA,cACA,cAAW,IACX,kBACA,gBACA,cACA,qBAC4C;CAC5C,IAAM,EAAE,SAAM,EAAe,IAAI,GAC3B,CAAC,GAAa,KAAkB,EAAS,CAAQ,GACjD,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAgB,KAAS,EAAE,6BAA6B,GACxD,IACJ,KAAiB,EAAE,gCAAgC,GAC/C,IAAsB,KAAe,EAAE,8BAA8B,GACrE,IAAoB,KAAa,EAAE,4BAA4B,GAC/D,IAAsB,KAAe,EAAE,8BAA8B,GAErE,IAAW,QAAc;EAC7B,IAAI;GACF,OAAO,KAAK,UAAU,GAAO,MAAM,CAAC;EACtC,QAAQ;GACN,OAAO,KAAK,UAAU,EACpB,OAAO,EAAE,0CAA0C,EACrD,CAAC;EACH;CACF,GAAG,CAAC,GAAG,CAAK,CAAC,GAEP,IAAa,EAAY,YAAY;EACzC,IAAI,IAAK;EACT,IAAI;GACF,AAAI,OAAO,YAAc,QACvB,MAAM,UAAU,UAAU,UAAU,CAAQ,GAC5C,IAAK;EAET,QAAQ;GACN,IAAK;EACP;EAMA,AAJA,AACE,MAAK,EAAoB,CAAQ,GAG/B,MACF,EAAU,EAAI,GACd,OAAO,iBAAiB;GACtB,EAAU,EAAK;EACjB,GAAG,IAAI;CAEX,GAAG,CAAC,CAAQ,CAAC,GAEP,IAAW,QAAc;EACzB,SAAa,MAGjB,OAAO,EAAE,aAAU;CACrB,GAAG,CAAC,CAAS,CAAC,GAEV,IAAkB;CACtB,AAAI,MACF,IAAkB;CAGpB,IAAI,IAAsB;CAK1B,OAJI,MACF,IAAsB,IAItB,kBAAC,OAAD;EAAK,WAAW,EAAG,GAAkB,CAAS;YAA9C,CACE,kBAAC,OAAD;GAAK,WAAW;aAAhB,CACE,kBAAC,QAAD;IAAM,WAAW;cAAe;GAAoB,CAAA,GACpD,kBAAC,OAAD;IAAK,WAAW;cAAhB,CACE,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACL,eAAe;MACb,EAAW,EAAE,YAAY,CAAC,CAAC;KAC7B;eAEC;IACK,CAAA,GACR,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACL,eAAe;MACb,GAAgB,MACP,CAAC,CACT;KACH;eAEC;IACK,CAAA,CACL;KACF;MACL,kBAAC,OAAD;GACE,WAAW,EAAG,GAAY,GAAG,IAAmB,EAAY,CAAC;GAC7D,OAAO;aAEN;EACE,CAAA,CACF;;AAET"}
@@ -1,15 +1,2 @@
1
- //#region src/backoffice/shared/copyWithExecCommand.ts
2
- function e(e) {
3
- try {
4
- let t = document.createElement("textarea");
5
- t.value = e, t.setAttribute("readonly", "true"), t.style.position = "fixed", t.style.top = "-1000px", t.style.left = "-1000px", document.body.appendChild(t), t.select();
6
- let n = document.execCommand("copy");
7
- return document.body.removeChild(t), n;
8
- } catch {
9
- return !1;
10
- }
11
- }
12
- //#endregion
1
+ import { copyWithExecCommand as e } from "../../shared/clipboard.js";
13
2
  export { e as copyWithExecCommand };
14
-
15
- //# sourceMappingURL=copyWithExecCommand.js.map
@@ -0,0 +1,31 @@
1
+ import { copyRichClipboard as e, copyTextToClipboard as t } from "../shared/clipboard.js";
2
+ import { useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
3
+ //#region src/hooks/useClipboardCopy.ts
4
+ function o(o = 2e3) {
5
+ let [s, c] = a(null), l = i(null), u = n(() => {
6
+ l.current != null && (window.clearTimeout(l.current), l.current = null);
7
+ }, []);
8
+ r(() => () => {
9
+ u();
10
+ }, [u]);
11
+ let d = n((e) => {
12
+ e != null && (c(e), u(), l.current = window.setTimeout(() => {
13
+ c(null), l.current = null;
14
+ }, o));
15
+ }, [u, o]);
16
+ return {
17
+ copiedKey: s,
18
+ copyText: n(async (e, n) => {
19
+ let r = await t(e);
20
+ return r && d(n), r;
21
+ }, [d]),
22
+ copyRich: n(async (t, n) => {
23
+ let r = await e(t);
24
+ return r && d(n), r;
25
+ }, [d])
26
+ };
27
+ }
28
+ //#endregion
29
+ export { o as default, o as useClipboardCopy };
30
+
31
+ //# sourceMappingURL=useClipboardCopy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useClipboardCopy.js","names":[],"sources":["../../../src/hooks/useClipboardCopy.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport {\n copyRichClipboard,\n copyTextToClipboard,\n type RichClipboardContent,\n} from '../shared/clipboard.js';\n\nexport type UseClipboardCopyResult = {\n copiedKey: string | null;\n copyText: (value: string, key?: string) => Promise<boolean>;\n copyRich: (content: RichClipboardContent, key?: string) => Promise<boolean>;\n};\n\n/** Copy text or rich content while tracking a short-lived copied state. */\nexport function useClipboardCopy(timeoutMs = 2000): UseClipboardCopyResult {\n const [copiedKey, setCopiedKey] = useState<string | null>(null);\n const timeoutRef = useRef<number | null>(null);\n\n const clearTimer = useCallback((): void => {\n if (timeoutRef.current != null) {\n window.clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n }, []);\n\n useEffect(() => {\n return () => {\n clearTimer();\n };\n }, [clearTimer]);\n\n const markCopied = useCallback(\n (key?: string): void => {\n if (key == null) {\n return;\n }\n\n setCopiedKey(key);\n clearTimer();\n timeoutRef.current = window.setTimeout(() => {\n setCopiedKey(null);\n timeoutRef.current = null;\n }, timeoutMs);\n },\n [clearTimer, timeoutMs],\n );\n\n const copyText = useCallback(\n async (value: string, key?: string): Promise<boolean> => {\n const copied = await copyTextToClipboard(value);\n if (copied) {\n markCopied(key);\n }\n return copied;\n },\n [markCopied],\n );\n\n const copyRich = useCallback(\n async (content: RichClipboardContent, key?: string): Promise<boolean> => {\n const copied = await copyRichClipboard(content);\n if (copied) {\n markCopied(key);\n }\n return copied;\n },\n [markCopied],\n );\n\n return { copiedKey, copyText, copyRich };\n}\n\nexport default useClipboardCopy;\n"],"mappings":";;;AAeA,SAAgB,EAAiB,IAAY,KAA8B;CACzE,IAAM,CAAC,GAAW,KAAgB,EAAwB,IAAI,GACxD,IAAa,EAAsB,IAAI,GAEvC,IAAa,QAAwB;EACzC,AAAI,EAAW,WAAW,SACxB,OAAO,aAAa,EAAW,OAAO,GACtC,EAAW,UAAU;CAEzB,GAAG,CAAC,CAAC;CAEL,cACe;EACX,EAAW;CACb,GACC,CAAC,CAAU,CAAC;CAEf,IAAM,IAAa,GAChB,MAAuB;EAClB,KAAO,SAIX,EAAa,CAAG,GAChB,EAAW,GACX,EAAW,UAAU,OAAO,iBAAiB;GAE3C,AADA,EAAa,IAAI,GACjB,EAAW,UAAU;EACvB,GAAG,CAAS;CACd,GACA,CAAC,GAAY,CAAS,CACxB;CAwBA,OAAO;EAAE;EAAW,UAtBH,EACf,OAAO,GAAe,MAAmC;GACvD,IAAM,IAAS,MAAM,EAAoB,CAAK;GAI9C,OAHI,KACF,EAAW,CAAG,GAET;EACT,GACA,CAAC,CAAU,CAcO;EAAU,UAXb,EACf,OAAO,GAA+B,MAAmC;GACvE,IAAM,IAAS,MAAM,EAAkB,CAAO;GAI9C,OAHI,KACF,EAAW,CAAG,GAET;EACT,GACA,CAAC,CAAU,CAGiB;CAAS;AACzC"}