@arkyn/components 3.0.8 → 3.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/calendar/_calendarProvider.d.ts.map +1 -1
- package/dist/components/calendar/calendarTableTd/index.d.ts.map +1 -1
- package/dist/components/currencyInput/index.d.ts +1 -1
- package/dist/components/datePicker/datePickerCalendarContainer/index.d.ts +1 -0
- package/dist/components/datePicker/datePickerCalendarContainer/index.d.ts.map +1 -1
- package/dist/components/datePicker/datePickerContainer/index.d.ts +5 -1
- package/dist/components/datePicker/datePickerContainer/index.d.ts.map +1 -1
- package/dist/components/datePicker/index.d.ts.map +1 -1
- package/dist/components/drawer/drawerContainer/index.d.ts.map +1 -1
- package/dist/components/googleAnalytics/snippets/generateGAElements.d.ts.map +1 -1
- package/dist/components/googleTagManager/snippets/appendToDataLayer.d.ts.map +1 -1
- package/dist/components/googleTagManager/snippets/generateGTMElements.d.ts.map +1 -1
- package/dist/components/imageUpload/index.d.ts +1 -1
- package/dist/components/input/index.d.ts +1 -1
- package/dist/components/modal/modalContainer/index.d.ts.map +1 -1
- package/dist/components/multiSelect/index.d.ts +1 -1
- package/dist/components/multiSelect/index.d.ts.map +1 -1
- package/dist/components/multiSelect/multiSelectContainer/index.d.ts +6 -1
- package/dist/components/multiSelect/multiSelectContainer/index.d.ts.map +1 -1
- package/dist/components/multiSelect/multiSelectOption/index.d.ts +2 -0
- package/dist/components/multiSelect/multiSelectOption/index.d.ts.map +1 -1
- package/dist/components/multiSelect/multiSelectOptionsContainer/index.d.ts +1 -0
- package/dist/components/multiSelect/multiSelectOptionsContainer/index.d.ts.map +1 -1
- package/dist/components/popover/index.d.ts.map +1 -1
- package/dist/components/richText/index.d.ts +1 -1
- package/dist/components/richText/index.d.ts.map +1 -1
- package/dist/components/select/index.d.ts +1 -1
- package/dist/components/select/index.d.ts.map +1 -1
- package/dist/components/select/selectContainer/index.d.ts +6 -1
- package/dist/components/select/selectContainer/index.d.ts.map +1 -1
- package/dist/components/select/selectOption/index.d.ts +2 -0
- package/dist/components/select/selectOption/index.d.ts.map +1 -1
- package/dist/components/select/selectOptionsContainer/index.d.ts +1 -0
- package/dist/components/select/selectOptionsContainer/index.d.ts.map +1 -1
- package/dist/hooks/useEscapeKey.d.ts +24 -0
- package/dist/hooks/useEscapeKey.d.ts.map +1 -0
- package/dist/hooks/useFlipPosition.d.ts +38 -0
- package/dist/hooks/useFlipPosition.d.ts.map +1 -0
- package/dist/hooks/useFocusTrap.d.ts +28 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/index.js +1120 -881
- package/dist/index.js.map +1 -1
- package/dist/modules/components/calendar/_calendarProvider.js +47 -34
- package/dist/modules/components/calendar/_calendarProvider.js.map +1 -1
- package/dist/modules/components/calendar/calendarTableTd/index.js +7 -2
- package/dist/modules/components/calendar/calendarTableTd/index.js.map +1 -1
- package/dist/modules/components/calendar/calendarTableTd/styles.css +1 -1
- package/dist/modules/components/calendar/styles.css +2 -2
- package/dist/modules/components/currencyInput/index.js.map +1 -1
- package/dist/modules/components/datePicker/datePickerCalendarContainer/index.js +12 -16
- package/dist/modules/components/datePicker/datePickerCalendarContainer/index.js.map +1 -1
- package/dist/modules/components/datePicker/datePickerContainer/index.js +9 -2
- package/dist/modules/components/datePicker/datePickerContainer/index.js.map +1 -1
- package/dist/modules/components/datePicker/index.js +63 -44
- package/dist/modules/components/datePicker/index.js.map +1 -1
- package/dist/modules/components/datePicker/styles.css +4 -4
- package/dist/modules/components/drawer/drawerContainer/index.js +31 -23
- package/dist/modules/components/drawer/drawerContainer/index.js.map +1 -1
- package/dist/modules/components/facebookPixel/pixel.js +1 -1
- package/dist/modules/components/facebookPixel/pixel.js.map +1 -1
- package/dist/modules/components/googleAnalytics/snippets/generateGAElements.js +7 -6
- package/dist/modules/components/googleAnalytics/snippets/generateGAElements.js.map +1 -1
- package/dist/modules/components/googleTagManager/snippets/appendToDataLayer.js +7 -6
- package/dist/modules/components/googleTagManager/snippets/appendToDataLayer.js.map +1 -1
- package/dist/modules/components/googleTagManager/snippets/generateGTMElements.js +20 -14
- package/dist/modules/components/googleTagManager/snippets/generateGTMElements.js.map +1 -1
- package/dist/modules/components/imageUpload/index.js.map +1 -1
- package/dist/modules/components/input/index.js.map +1 -1
- package/dist/modules/components/modal/modalContainer/index.js +30 -22
- package/dist/modules/components/modal/modalContainer/index.js.map +1 -1
- package/dist/modules/components/multiSelect/index.js +119 -79
- package/dist/modules/components/multiSelect/index.js.map +1 -1
- package/dist/modules/components/multiSelect/multiSelectContainer/index.js +10 -2
- package/dist/modules/components/multiSelect/multiSelectContainer/index.js.map +1 -1
- package/dist/modules/components/multiSelect/multiSelectOption/index.js +7 -3
- package/dist/modules/components/multiSelect/multiSelectOption/index.js.map +1 -1
- package/dist/modules/components/multiSelect/multiSelectOption/styles.css +1 -1
- package/dist/modules/components/multiSelect/multiSelectOptionsContainer/index.js +19 -23
- package/dist/modules/components/multiSelect/multiSelectOptionsContainer/index.js.map +1 -1
- package/dist/modules/components/multiSelect/styles.css +1 -1
- package/dist/modules/components/popover/index.js +23 -17
- package/dist/modules/components/popover/index.js.map +1 -1
- package/dist/modules/components/richText/index.js +1 -1
- package/dist/modules/components/richText/index.js.map +1 -1
- package/dist/modules/components/searchPlaces.js +1 -1
- package/dist/modules/components/searchPlaces.js.map +1 -1
- package/dist/modules/components/select/index.js +120 -80
- package/dist/modules/components/select/index.js.map +1 -1
- package/dist/modules/components/select/selectContainer/index.js +10 -2
- package/dist/modules/components/select/selectContainer/index.js.map +1 -1
- package/dist/modules/components/select/selectOption/index.js +5 -2
- package/dist/modules/components/select/selectOption/index.js.map +1 -1
- package/dist/modules/components/select/selectOption/styles.css +1 -1
- package/dist/modules/components/select/selectOptionsContainer/index.js +18 -23
- package/dist/modules/components/select/selectOptionsContainer/index.js.map +1 -1
- package/dist/modules/components/select/styles.css +1 -1
- package/dist/modules/hooks/useEscapeKey.js +18 -0
- package/dist/modules/hooks/useEscapeKey.js.map +1 -0
- package/dist/modules/hooks/useFlipPosition.js +26 -0
- package/dist/modules/hooks/useFlipPosition.js.map +1 -0
- package/dist/modules/hooks/useFocusTrap.js +44 -0
- package/dist/modules/hooks/useFocusTrap.js.map +1 -0
- package/dist/modules/utils/escapeForInlineScript.js +14 -0
- package/dist/modules/utils/escapeForInlineScript.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/utils/escapeForInlineScript.d.ts +23 -0
- package/dist/utils/escapeForInlineScript.d.ts.map +1 -0
- package/package.json +16 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEscapeKey.js","names":[],"sources":["../../../src/hooks/useEscapeKey.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\n/**\n * useEscapeKey, invokes a callback when the `Escape` key is pressed while active.\n *\n * Listens on `document`, so it fires regardless of which descendant currently\n * has focus. The callback is always the latest one passed in, without\n * re-attaching the listener on every render.\n *\n * Used internally by `ModalContainer`, `DrawerContainer`, and `Popover` to\n * close the overlay on Escape.\n *\n * @param isActive - When `true`, the Escape key listener is attached.\n * @param onEscape - Called when Escape is pressed while `isActive` is `true`.\n *\n * @example\n * ```tsx\n * function CustomOverlay({ isOpen, onClose }) {\n * useEscapeKey(isOpen, onClose);\n * return isOpen ? <div role=\"dialog\">...</div> : null;\n * }\n * ```\n */\n\nfunction useEscapeKey(isActive: boolean, onEscape: () => void): void {\n\tconst onEscapeRef = useRef(onEscape);\n\tonEscapeRef.current = onEscape;\n\n\tuseEffect(() => {\n\t\tif (!isActive) return;\n\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (event.key === \"Escape\") onEscapeRef.current();\n\t\t}\n\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"keydown\", handleKeyDown);\n\t\t};\n\t}, [isActive]);\n}\n\nexport { useEscapeKey };\n"],"mappings":";;AAwBA,SAAS,EAAa,GAAmB,GAA4B;CACpE,IAAM,IAAc,EAAO,CAAQ;CAGnC,AAFA,EAAY,UAAU,GAEtB,QAAgB;EACf,IAAI,CAAC,GAAU;EAEf,SAAS,EAAc,GAAsB;GAC5C,AAAI,EAAM,QAAQ,YAAU,EAAY,QAAQ;EACjD;EAIA,OAFA,SAAS,iBAAiB,WAAW,CAAa,SAErC;GACZ,SAAS,oBAAoB,WAAW,CAAa;EACtD;CACD,GAAG,CAAC,CAAQ,CAAC;AACd"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useEffect as e, useState as t } from "react";
|
|
2
|
+
//#region src/hooks/useFlipPosition.ts
|
|
3
|
+
function n(n, r, i) {
|
|
4
|
+
let [a, o] = t("bottom");
|
|
5
|
+
return e(() => {
|
|
6
|
+
if (!r) return;
|
|
7
|
+
function e() {
|
|
8
|
+
if (!n.current) return;
|
|
9
|
+
let e = n.current.parentElement;
|
|
10
|
+
if (!e) return;
|
|
11
|
+
let t = e.getBoundingClientRect();
|
|
12
|
+
window.innerHeight - t.bottom < i && t.top > i ? o("top") : o("bottom");
|
|
13
|
+
}
|
|
14
|
+
return e(), window.addEventListener("resize", e), () => {
|
|
15
|
+
window.removeEventListener("resize", e);
|
|
16
|
+
};
|
|
17
|
+
}, [
|
|
18
|
+
n,
|
|
19
|
+
r,
|
|
20
|
+
i
|
|
21
|
+
]), a;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { n as useFlipPosition };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=useFlipPosition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFlipPosition.js","names":[],"sources":["../../../src/hooks/useFlipPosition.ts"],"sourcesContent":["import { type RefObject, useEffect, useState } from \"react\";\n\ntype FlipPosition = \"bottom\" | \"top\";\n\n/**\n * useFlipPosition, computes whether a floating panel should render `\"bottom\"`\n * or `\"top\"` relative to its anchor, flipping to `\"top\"` when there isn't\n * enough viewport space below it.\n *\n * The anchor used for the calculation is `containerRef.current.parentElement`,\n * matching how `SelectOptionsContainer`, `MultiSelectOptionsContainer`, and\n * `DatePickerCalendarContainer` render their floating panel as a sibling\n * positioned relative to that parent.\n *\n * Recomputes when `isActive` becomes `true`, and again on every `resize`\n * event while `isActive` stays `true`, so the position stays correct if the\n * viewport is resized while the panel is open.\n *\n * Only positioning is handled here — no selection, focus, or keyboard logic.\n *\n * @param containerRef - Ref to the floating panel element (its `parentElement` is used as the anchor).\n * @param isActive - When `true`, the position is computed and kept up to date.\n * @param estimatedContainerHeight - Estimated height (px) of the floating panel, used to decide if it fits below the anchor.\n * @returns `\"bottom\"` or `\"top\"`.\n *\n * @example\n * ```tsx\n * function CustomFloatingPanel({ isOpen }) {\n * const containerRef = useRef<HTMLDivElement>(null);\n * const position = useFlipPosition(containerRef, isOpen, 300);\n * return isOpen ? (\n * <div ref={containerRef} className={`panel ${position}`} />\n * ) : null;\n * }\n * ```\n */\n\nfunction useFlipPosition(\n\tcontainerRef: RefObject<HTMLElement | null>,\n\tisActive: boolean,\n\testimatedContainerHeight: number,\n): FlipPosition {\n\tconst [position, setPosition] = useState<FlipPosition>(\"bottom\");\n\n\tuseEffect(() => {\n\t\tif (!isActive) return;\n\n\t\tfunction checkContainerPosition() {\n\t\t\tif (!containerRef.current) return;\n\n\t\t\tconst parentElement = containerRef.current.parentElement;\n\t\t\tif (!parentElement) return;\n\n\t\t\tconst parentRect = parentElement.getBoundingClientRect();\n\t\t\tconst viewportHeight = window.innerHeight;\n\n\t\t\tconst spaceBelow = viewportHeight - parentRect.bottom;\n\n\t\t\tif (\n\t\t\t\tspaceBelow < estimatedContainerHeight &&\n\t\t\t\tparentRect.top > estimatedContainerHeight\n\t\t\t) {\n\t\t\t\tsetPosition(\"top\");\n\t\t\t} else {\n\t\t\t\tsetPosition(\"bottom\");\n\t\t\t}\n\t\t}\n\n\t\tcheckContainerPosition();\n\n\t\twindow.addEventListener(\"resize\", checkContainerPosition);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"resize\", checkContainerPosition);\n\t\t};\n\t}, [containerRef, isActive, estimatedContainerHeight]);\n\n\treturn position;\n}\n\nexport type { FlipPosition };\nexport { useFlipPosition };\n"],"mappings":";;AAqCA,SAAS,EACR,GACA,GACA,GACe;CACf,IAAM,CAAC,GAAU,KAAe,EAAuB,QAAQ;CAmC/D,OAjCA,QAAgB;EACf,IAAI,CAAC,GAAU;EAEf,SAAS,IAAyB;GACjC,IAAI,CAAC,EAAa,SAAS;GAE3B,IAAM,IAAgB,EAAa,QAAQ;GAC3C,IAAI,CAAC,GAAe;GAEpB,IAAM,IAAa,EAAc,sBAAsB;GAKvD,AAJuB,OAAO,cAEM,EAAW,SAGjC,KACb,EAAW,MAAM,IAEjB,EAAY,KAAK,IAEjB,EAAY,QAAQ;EAEtB;EAMA,OAJA,EAAuB,GAEvB,OAAO,iBAAiB,UAAU,CAAsB,SAE3C;GACZ,OAAO,oBAAoB,UAAU,CAAsB;EAC5D;CACD,GAAG;EAAC;EAAc;EAAU;CAAwB,CAAC,GAE9C;AACR"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useEffect as e, useRef as t } from "react";
|
|
2
|
+
//#region src/hooks/useFocusTrap.ts
|
|
3
|
+
var n = [
|
|
4
|
+
"a[href]",
|
|
5
|
+
"area[href]",
|
|
6
|
+
"button:not([disabled])",
|
|
7
|
+
"input:not([disabled])",
|
|
8
|
+
"select:not([disabled])",
|
|
9
|
+
"textarea:not([disabled])",
|
|
10
|
+
"iframe",
|
|
11
|
+
"[tabindex]:not([tabindex='-1'])"
|
|
12
|
+
].join(", ");
|
|
13
|
+
function r(e) {
|
|
14
|
+
return Array.from(e.querySelectorAll(n));
|
|
15
|
+
}
|
|
16
|
+
function i(n, i) {
|
|
17
|
+
let a = t(null);
|
|
18
|
+
e(() => {
|
|
19
|
+
if (!n) return;
|
|
20
|
+
let e = i.current;
|
|
21
|
+
if (!e) return;
|
|
22
|
+
let t = e;
|
|
23
|
+
a.current = document.activeElement;
|
|
24
|
+
let [o] = r(t);
|
|
25
|
+
(o ?? t).focus();
|
|
26
|
+
function s(e) {
|
|
27
|
+
if (e.key !== "Tab") return;
|
|
28
|
+
let n = r(t);
|
|
29
|
+
if (n.length === 0) {
|
|
30
|
+
e.preventDefault(), t.focus();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let i = n[0], a = n[n.length - 1], o = document.activeElement;
|
|
34
|
+
e.shiftKey && o === i ? (e.preventDefault(), a.focus()) : !e.shiftKey && o === a && (e.preventDefault(), i.focus());
|
|
35
|
+
}
|
|
36
|
+
return document.addEventListener("keydown", s), () => {
|
|
37
|
+
document.removeEventListener("keydown", s), a.current?.focus(), a.current = null;
|
|
38
|
+
};
|
|
39
|
+
}, [n, i]);
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { i as useFocusTrap };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=useFocusTrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFocusTrap.js","names":[],"sources":["../../../src/hooks/useFocusTrap.ts"],"sourcesContent":["import { type RefObject, useEffect, useRef } from \"react\";\n\nconst FOCUSABLE_SELECTOR = [\n\t\"a[href]\",\n\t\"area[href]\",\n\t\"button:not([disabled])\",\n\t\"input:not([disabled])\",\n\t\"select:not([disabled])\",\n\t\"textarea:not([disabled])\",\n\t\"iframe\",\n\t\"[tabindex]:not([tabindex='-1'])\",\n].join(\", \");\n\nfunction getFocusableElements(container: HTMLElement): HTMLElement[] {\n\treturn Array.from(\n\t\tcontainer.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR),\n\t);\n}\n\n/**\n * useFocusTrap, keeps keyboard focus inside a container while `isActive`.\n *\n * On activation, saves the currently focused element and moves focus to the\n * first focusable descendant of `containerRef.current` (or to the container\n * itself when it has none). While active, `Tab`/`Shift+Tab` cycle focus\n * between the first and last focusable descendants instead of leaving the\n * container. On deactivation (or unmount), focus is restored to the element\n * that was focused right before activation.\n *\n * Used internally by `ModalContainer`, `DrawerContainer`, and `Popover`.\n *\n * @param isActive - When `true`, focus is moved into and trapped inside the container.\n * @param containerRef - Ref to the container that should trap focus. Give the element `tabIndex={-1}` so it can still receive focus when it has no focusable children.\n *\n * @example\n * ```tsx\n * function CustomOverlay({ isOpen }) {\n * const containerRef = useRef<HTMLDivElement>(null);\n * useFocusTrap(isOpen, containerRef);\n * return isOpen ? <div ref={containerRef} tabIndex={-1}>...</div> : null;\n * }\n * ```\n */\n\nfunction useFocusTrap(\n\tisActive: boolean,\n\tcontainerRef: RefObject<HTMLElement | null>,\n): void {\n\tconst previouslyFocused = useRef<HTMLElement | null>(null);\n\n\tuseEffect(() => {\n\t\tif (!isActive) return;\n\n\t\tconst container: HTMLElement | null = containerRef.current;\n\t\tif (!container) return;\n\t\tconst dialogNode: HTMLElement = container;\n\n\t\tpreviouslyFocused.current = document.activeElement as HTMLElement | null;\n\n\t\tconst [firstFocusable] = getFocusableElements(dialogNode);\n\t\t(firstFocusable ?? dialogNode).focus();\n\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (event.key !== \"Tab\") return;\n\n\t\t\tconst focusable = getFocusableElements(dialogNode);\n\n\t\t\tif (focusable.length === 0) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tdialogNode.focus();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst first = focusable[0];\n\t\t\tconst last = focusable[focusable.length - 1];\n\t\t\tconst active = document.activeElement;\n\n\t\t\tif (event.shiftKey && active === first) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tlast.focus();\n\t\t\t} else if (!event.shiftKey && active === last) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tfirst.focus();\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"keydown\", handleKeyDown);\n\t\t\tpreviouslyFocused.current?.focus();\n\t\t\tpreviouslyFocused.current = null;\n\t\t};\n\t}, [isActive, containerRef]);\n}\n\nexport { useFocusTrap };\n"],"mappings":";;AAEA,IAAM,IAAqB;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC,CAAC,KAAK,IAAI;AAEX,SAAS,EAAqB,GAAuC;CACpE,OAAO,MAAM,KACZ,EAAU,iBAA8B,CAAkB,CAC3D;AACD;AA2BA,SAAS,EACR,GACA,GACO;CACP,IAAM,IAAoB,EAA2B,IAAI;CAEzD,QAAgB;EACf,IAAI,CAAC,GAAU;EAEf,IAAM,IAAgC,EAAa;EACnD,IAAI,CAAC,GAAW;EAChB,IAAM,IAA0B;EAEhC,EAAkB,UAAU,SAAS;EAErC,IAAM,CAAC,KAAkB,EAAqB,CAAU;EACxD,CAAC,KAAkB,EAAA,CAAY,MAAM;EAErC,SAAS,EAAc,GAAsB;GAC5C,IAAI,EAAM,QAAQ,OAAO;GAEzB,IAAM,IAAY,EAAqB,CAAU;GAEjD,IAAI,EAAU,WAAW,GAAG;IAE3B,AADA,EAAM,eAAe,GACrB,EAAW,MAAM;IACjB;GACD;GAEA,IAAM,IAAQ,EAAU,IAClB,IAAO,EAAU,EAAU,SAAS,IACpC,IAAS,SAAS;GAExB,AAAI,EAAM,YAAY,MAAW,KAChC,EAAM,eAAe,GACrB,EAAK,MAAM,KACD,CAAC,EAAM,YAAY,MAAW,MACxC,EAAM,eAAe,GACrB,EAAM,MAAM;EAEd;EAIA,OAFA,SAAS,iBAAiB,WAAW,CAAa,SAErC;GAGZ,AAFA,SAAS,oBAAoB,WAAW,CAAa,GACrD,EAAkB,SAAS,MAAM,GACjC,EAAkB,UAAU;EAC7B;CACD,GAAG,CAAC,GAAU,CAAY,CAAC;AAC5B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/utils/escapeForInlineScript.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
return JSON.stringify(e ?? "").replace(/</g, "\\u003C");
|
|
4
|
+
}
|
|
5
|
+
function t(e) {
|
|
6
|
+
return JSON.stringify(e).replace(/</g, "\\u003C");
|
|
7
|
+
}
|
|
8
|
+
function n(e) {
|
|
9
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e);
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { n as isValidJsIdentifier, t as toSafeScriptJson, e as toSafeScriptString };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=escapeForInlineScript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escapeForInlineScript.js","names":[],"sources":["../../../src/utils/escapeForInlineScript.ts"],"sourcesContent":["/**\n * Serializes a value so it can be embedded as a JS string literal inside an inline\n * `<script>` snippet. Wraps `JSON.stringify` (which already escapes quotes/backslashes/\n * control characters) and additionally escapes `<` so a value containing `</script>`\n * can't prematurely close the surrounding script tag.\n *\n * @example\n * ```typescript\n * `gtag('config', ${toSafeScriptString(measurementId)});`\n * // measurementId = \"G-XXXX\" -> gtag('config', \"G-XXXX\");\n * // measurementId = \"\\\"); alert(1); //\" -> gtag('config', \"\\\"); alert(1); //\");\n * ```\n */\nfunction toSafeScriptString(value: unknown): string {\n\treturn JSON.stringify(value ?? \"\").replace(/</g, \"\\\\u003C\");\n}\n\n/**\n * Serializes an object/array to JSON for embedding inside an inline `<script>` snippet,\n * escaping `<` so a value containing `</script>` can't prematurely close the script tag.\n */\nfunction toSafeScriptJson(value: unknown): string {\n\treturn JSON.stringify(value).replace(/</g, \"\\\\u003C\");\n}\n\n/** Whether `name` is a valid bare JS identifier (safe to use as `window.<name>`). */\nfunction isValidJsIdentifier(name: string): boolean {\n\treturn /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);\n}\n\nexport { isValidJsIdentifier, toSafeScriptJson, toSafeScriptString };\n"],"mappings":";AAaA,SAAS,EAAmB,GAAwB;CACnD,OAAO,KAAK,UAAU,KAAS,EAAE,CAAC,CAAC,QAAQ,MAAM,SAAS;AAC3D;AAMA,SAAS,EAAiB,GAAwB;CACjD,OAAO,KAAK,UAAU,CAAK,CAAC,CAAC,QAAQ,MAAM,SAAS;AACrD;AAGA,SAAS,EAAoB,GAAuB;CACnD,OAAO,6BAA6B,KAAK,CAAI;AAC9C"}
|