@arkyn/components 3.0.9 → 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/datePicker/datePickerCalendarContainer/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/multiSelect/multiSelectOptionsContainer/index.d.ts.map +1 -1
- package/dist/components/richText/index.d.ts.map +1 -1
- package/dist/components/select/selectOptionsContainer/index.d.ts.map +1 -1
- package/dist/hooks/useFlipPosition.d.ts +38 -0
- package/dist/hooks/useFlipPosition.d.ts.map +1 -0
- package/dist/index.js +538 -511
- 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/datePicker/datePickerCalendarContainer/index.js +12 -19
- package/dist/modules/components/datePicker/datePickerCalendarContainer/index.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/multiSelect/multiSelectOptionsContainer/index.js +21 -28
- package/dist/modules/components/multiSelect/multiSelectOptionsContainer/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/select/selectOptionsContainer/index.js +21 -28
- package/dist/modules/components/select/selectOptionsContainer/index.js.map +1 -1
- package/dist/modules/hooks/useFlipPosition.js +26 -0
- package/dist/modules/hooks/useFlipPosition.js.map +1 -0
- package/dist/modules/utils/escapeForInlineScript.js +14 -0
- package/dist/modules/utils/escapeForInlineScript.js.map +1 -0
- package/dist/utils/escapeForInlineScript.d.ts +23 -0
- package/dist/utils/escapeForInlineScript.d.ts.map +1 -0
- package/package.json +9 -6
|
@@ -1,42 +1,55 @@
|
|
|
1
1
|
import { ViewService as e } from "./_viewService.js";
|
|
2
|
-
import { createContext as t,
|
|
3
|
-
import { jsx as
|
|
2
|
+
import { createContext as t, useCallback as n, useContext as r, useMemo as i, useState as a } from "react";
|
|
3
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
4
4
|
//#region src/components/calendar/_calendarProvider.tsx
|
|
5
|
-
var
|
|
6
|
-
function
|
|
7
|
-
return
|
|
5
|
+
var s = t({});
|
|
6
|
+
function c() {
|
|
7
|
+
return r(s);
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
9
|
+
var l = new e();
|
|
10
|
+
function u(e) {
|
|
11
|
+
let { calendarType: t, children: r, defaultValue: c, defaultViewValue: u = /* @__PURE__ */ new Date(), language: d = "pt-BR", onChange: f, onChangeView: p, value: m, viewValue: h } = e, g = t === "single" ? [c || /* @__PURE__ */ new Date(), c || /* @__PURE__ */ new Date()] : c || [/* @__PURE__ */ new Date(), /* @__PURE__ */ new Date()], [_, v] = a(u), [y, b] = a(g), x = h || _, S = m ? t === "single" ? [m, m] : m : y, C = n((e) => {
|
|
12
|
+
let n = [new Date(e[0]), new Date(e[1])];
|
|
13
|
+
f && t === "range" && f(n), f && t === "single" && f(n[0]), b(n);
|
|
14
|
+
}, [t, f]), w = n((e) => {
|
|
15
|
+
p && p(e), v(e);
|
|
16
|
+
}, [p]), T = n((e, n, r) => l.changeDay(e, n, r, t, S, C, w), [
|
|
17
|
+
t,
|
|
18
|
+
S,
|
|
19
|
+
C,
|
|
20
|
+
w
|
|
21
|
+
]), E = n((e) => l.changeMonth(e, x, w), [x, w]), D = n((e) => l.changeYear(e, x, w), [x, w]), O = n(() => l.nextMonth(x, w), [x, w]), k = n(() => l.previousMonth(x, w), [x, w]), A = i(() => ({
|
|
22
|
+
valueDate: S,
|
|
23
|
+
viewDate: x,
|
|
24
|
+
currentDate: x.toLocaleDateString(d).slice(3),
|
|
25
|
+
currentDay: l.currentDay(x),
|
|
26
|
+
currentMonth: l.currentMonth(x),
|
|
27
|
+
currentYear: l.currentYear(x),
|
|
28
|
+
listWeek: l.listWeek(d),
|
|
29
|
+
listMonths: l.listMonths(x, d),
|
|
30
|
+
listYears: l.listYears(100),
|
|
31
|
+
listMatrix: l.listMatrix(x, S),
|
|
32
|
+
changeDay: T,
|
|
33
|
+
changeMonth: E,
|
|
34
|
+
changeYear: D,
|
|
35
|
+
nextMonth: O,
|
|
36
|
+
previousMonth: k
|
|
37
|
+
}), [
|
|
38
|
+
S,
|
|
39
|
+
x,
|
|
40
|
+
d,
|
|
41
|
+
T,
|
|
42
|
+
E,
|
|
43
|
+
D,
|
|
44
|
+
O,
|
|
45
|
+
k
|
|
46
|
+
]);
|
|
47
|
+
return /* @__PURE__ */ o(s.Provider, {
|
|
48
|
+
value: A,
|
|
49
|
+
children: r
|
|
37
50
|
});
|
|
38
51
|
}
|
|
39
52
|
//#endregion
|
|
40
|
-
export {
|
|
53
|
+
export { u as CalendarProvider, c as useCalendar };
|
|
41
54
|
|
|
42
55
|
//# sourceMappingURL=_calendarProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_calendarProvider.js","names":[],"sources":["../../../../src/components/calendar/_calendarProvider.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"_calendarProvider.js","names":[],"sources":["../../../../src/components/calendar/_calendarProvider.tsx"],"sourcesContent":["import {\n\tcreateContext,\n\ttype ReactNode,\n\tuseCallback,\n\tuseContext,\n\tuseMemo,\n\tuseState,\n} from \"react\";\nimport { type CalendarMatrix, ViewService } from \"./_viewService\";\n\ntype CalendarContextProps = {\n\tvalueDate: Date[];\n\tviewDate: Date;\n\tcurrentDate: string;\n\tcurrentDay: string;\n\tcurrentMonth: string;\n\tcurrentYear: string;\n\tlistWeek: string[];\n\tlistMonths: { label: string; value: string }[];\n\tlistYears: { label: string; value: string }[];\n\tlistMatrix: CalendarMatrix;\n\tchangeDay: (day: number, month: number, year: number) => void;\n\tchangeMonth: (month: number) => void;\n\tchangeYear: (year: number) => void;\n\tnextMonth: () => void;\n\tpreviousMonth: () => void;\n};\n\ntype SingleCalendarProviderProps = {\n\tchildren: ReactNode;\n\tcalendarType: \"single\";\n\tlanguage?: string;\n\tonChangeView?: (date: Date) => void;\n\tdefaultValue?: Date;\n\tonChange?: (date: Date) => void;\n\tvalue?: Date;\n\tviewValue?: Date;\n\tdefaultViewValue?: Date;\n};\n\ntype RangeCalendarProviderProps = {\n\tchildren: ReactNode;\n\tcalendarType: \"range\";\n\tlanguage?: string;\n\tonChangeView?: (date: Date) => void;\n\tdefaultValue?: [Date, Date];\n\tonChange?: (date: [Date, Date]) => void;\n\tvalue?: [Date, Date];\n\tviewValue?: Date;\n\tdefaultViewValue?: Date;\n};\n\ntype CalendarProviderProps =\n\t| SingleCalendarProviderProps\n\t| RangeCalendarProviderProps;\n\nconst CalendarContext = createContext({} as CalendarContextProps);\n\nfunction useCalendar() {\n\treturn useContext(CalendarContext);\n}\n\n// Stateless — safe to share a single instance instead of instantiating on every render.\nconst viewService = new ViewService();\n\nfunction CalendarProvider(props: CalendarProviderProps) {\n\tconst {\n\t\tcalendarType,\n\t\tchildren,\n\t\tdefaultValue: rawDefaultValue,\n\t\tdefaultViewValue = new Date(),\n\t\tlanguage = \"pt-BR\",\n\t\tonChange,\n\t\tonChangeView,\n\t\tvalue,\n\t\tviewValue,\n\t} = props;\n\n\tconst defaultValue: [Date, Date] =\n\t\tcalendarType === \"single\"\n\t\t\t? [rawDefaultValue || new Date(), rawDefaultValue || new Date()]\n\t\t\t: rawDefaultValue || [new Date(), new Date()];\n\n\tconst [rawViewDate, rawSetViewDate] = useState(defaultViewValue);\n\tconst [rawValueDate, rawSetValueDate] = useState<[Date, Date]>(defaultValue);\n\n\tconst viewDate = viewValue || rawViewDate;\n\tconst valueDate: [Date, Date] = value\n\t\t? calendarType === \"single\"\n\t\t\t? [value, value]\n\t\t\t: value\n\t\t: rawValueDate;\n\n\tconst setValueDate = useCallback(\n\t\t(newValue: [Date, Date]) => {\n\t\t\tconst normalizedValue: [Date, Date] = [\n\t\t\t\tnew Date(newValue[0]),\n\t\t\t\tnew Date(newValue[1]),\n\t\t\t];\n\n\t\t\tif (onChange && calendarType === \"range\") {\n\t\t\t\tonChange(normalizedValue);\n\t\t\t}\n\n\t\t\tif (onChange && calendarType === \"single\") {\n\t\t\t\tonChange(normalizedValue[0]);\n\t\t\t}\n\n\t\t\trawSetValueDate(normalizedValue);\n\t\t},\n\t\t[calendarType, onChange],\n\t);\n\n\tconst setViewDate = useCallback(\n\t\t(date: Date) => {\n\t\t\tif (onChangeView) onChangeView(date);\n\t\t\trawSetViewDate(date);\n\t\t},\n\t\t[onChangeView],\n\t);\n\n\tconst changeDay = useCallback(\n\t\t(day: number, month: number, year: number) =>\n\t\t\tviewService.changeDay(\n\t\t\t\tday,\n\t\t\t\tmonth,\n\t\t\t\tyear,\n\t\t\t\tcalendarType,\n\t\t\t\tvalueDate,\n\t\t\t\tsetValueDate,\n\t\t\t\tsetViewDate,\n\t\t\t),\n\t\t[calendarType, valueDate, setValueDate, setViewDate],\n\t);\n\n\tconst changeMonth = useCallback(\n\t\t(month: number) => viewService.changeMonth(month, viewDate, setViewDate),\n\t\t[viewDate, setViewDate],\n\t);\n\n\tconst changeYear = useCallback(\n\t\t(year: number) => viewService.changeYear(year, viewDate, setViewDate),\n\t\t[viewDate, setViewDate],\n\t);\n\n\tconst nextMonth = useCallback(\n\t\t() => viewService.nextMonth(viewDate, setViewDate),\n\t\t[viewDate, setViewDate],\n\t);\n\n\tconst previousMonth = useCallback(\n\t\t() => viewService.previousMonth(viewDate, setViewDate),\n\t\t[viewDate, setViewDate],\n\t);\n\n\tconst contextValue = useMemo<CalendarContextProps>(\n\t\t() => ({\n\t\t\tvalueDate,\n\t\t\tviewDate,\n\t\t\tcurrentDate: viewDate.toLocaleDateString(language).slice(3),\n\t\t\tcurrentDay: viewService.currentDay(viewDate),\n\t\t\tcurrentMonth: viewService.currentMonth(viewDate),\n\t\t\tcurrentYear: viewService.currentYear(viewDate),\n\t\t\tlistWeek: viewService.listWeek(language),\n\t\t\tlistMonths: viewService.listMonths(viewDate, language),\n\t\t\tlistYears: viewService.listYears(100),\n\t\t\tlistMatrix: viewService.listMatrix(viewDate, valueDate),\n\t\t\tchangeDay,\n\t\t\tchangeMonth,\n\t\t\tchangeYear,\n\t\t\tnextMonth,\n\t\t\tpreviousMonth,\n\t\t}),\n\t\t[\n\t\t\tvalueDate,\n\t\t\tviewDate,\n\t\t\tlanguage,\n\t\t\tchangeDay,\n\t\t\tchangeMonth,\n\t\t\tchangeYear,\n\t\t\tnextMonth,\n\t\t\tpreviousMonth,\n\t\t],\n\t);\n\n\treturn (\n\t\t<CalendarContext.Provider value={contextValue}>\n\t\t\t{children}\n\t\t</CalendarContext.Provider>\n\t);\n}\n\nexport { CalendarProvider, useCalendar };\n"],"mappings":";;;;AAwDA,IAAM,IAAkB,EAAc,CAAC,CAAyB;AAEhE,SAAS,IAAc;CACtB,OAAO,EAAW,CAAe;AAClC;AAGA,IAAM,IAAc,IAAI,EAAY;AAEpC,SAAS,EAAiB,GAA8B;CACvD,IAAM,EACL,iBACA,aACA,cAAc,GACd,sCAAmB,IAAI,KAAK,GAC5B,cAAW,SACX,aACA,iBACA,UACA,iBACG,GAEE,IACL,MAAiB,WACd,CAAC,qBAAmB,IAAI,KAAK,GAAG,qBAAmB,IAAI,KAAK,CAAC,IAC7D,KAAmB,iBAAC,IAAI,KAAK,mBAAG,IAAI,KAAK,CAAC,GAExC,CAAC,GAAa,KAAkB,EAAS,CAAgB,GACzD,CAAC,GAAc,KAAmB,EAAuB,CAAY,GAErE,IAAW,KAAa,GACxB,IAA0B,IAC7B,MAAiB,WAChB,CAAC,GAAO,CAAK,IACb,IACD,GAEG,IAAe,GACnB,MAA2B;EAC3B,IAAM,IAAgC,CACrC,IAAI,KAAK,EAAS,EAAE,GACpB,IAAI,KAAK,EAAS,EAAE,CACrB;EAUA,AARI,KAAY,MAAiB,WAChC,EAAS,CAAe,GAGrB,KAAY,MAAiB,YAChC,EAAS,EAAgB,EAAE,GAG5B,EAAgB,CAAe;CAChC,GACA,CAAC,GAAc,CAAQ,CACxB,GAEM,IAAc,GAClB,MAAe;EAEf,AADI,KAAc,EAAa,CAAI,GACnC,EAAe,CAAI;CACpB,GACA,CAAC,CAAY,CACd,GAEM,IAAY,GAChB,GAAa,GAAe,MAC5B,EAAY,UACX,GACA,GACA,GACA,GACA,GACA,GACA,CACD,GACD;EAAC;EAAc;EAAW;EAAc;CAAW,CACpD,GAEM,IAAc,GAClB,MAAkB,EAAY,YAAY,GAAO,GAAU,CAAW,GACvE,CAAC,GAAU,CAAW,CACvB,GAEM,IAAa,GACjB,MAAiB,EAAY,WAAW,GAAM,GAAU,CAAW,GACpE,CAAC,GAAU,CAAW,CACvB,GAEM,IAAY,QACX,EAAY,UAAU,GAAU,CAAW,GACjD,CAAC,GAAU,CAAW,CACvB,GAEM,IAAgB,QACf,EAAY,cAAc,GAAU,CAAW,GACrD,CAAC,GAAU,CAAW,CACvB,GAEM,IAAe,SACb;EACN;EACA;EACA,aAAa,EAAS,mBAAmB,CAAQ,CAAC,CAAC,MAAM,CAAC;EAC1D,YAAY,EAAY,WAAW,CAAQ;EAC3C,cAAc,EAAY,aAAa,CAAQ;EAC/C,aAAa,EAAY,YAAY,CAAQ;EAC7C,UAAU,EAAY,SAAS,CAAQ;EACvC,YAAY,EAAY,WAAW,GAAU,CAAQ;EACrD,WAAW,EAAY,UAAU,GAAG;EACpC,YAAY,EAAY,WAAW,GAAU,CAAS;EACtD;EACA;EACA;EACA;EACA;CACD,IACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,CACD;CAEA,OACC,kBAAC,EAAgB,UAAjB;EAA0B,OAAO;EAC/B;CACwB,CAAA;AAE5B"}
|
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useFlipPosition as e } from "../../../hooks/useFlipPosition.js";
|
|
2
|
+
import { useScrollLock as t } from "../../../hooks/useScrollLock.js";
|
|
2
3
|
/* empty css */
|
|
3
|
-
import {
|
|
4
|
-
import { jsx as
|
|
4
|
+
import { useRef as n } from "react";
|
|
5
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
5
6
|
//#region src/components/datePicker/datePickerCalendarContainer/index.tsx
|
|
6
|
-
function
|
|
7
|
-
let { children:
|
|
8
|
-
return
|
|
9
|
-
c
|
|
10
|
-
|
|
11
|
-
let e = l.current.parentElement;
|
|
12
|
-
if (!e) return;
|
|
13
|
-
let t = e.getBoundingClientRect();
|
|
14
|
-
window.innerHeight - t.bottom < 420 && t.top > 420 ? d("top") : d("bottom");
|
|
15
|
-
})();
|
|
16
|
-
}, [c]), c ? /* @__PURE__ */ i("div", {
|
|
17
|
-
ref: l,
|
|
18
|
-
id: s,
|
|
7
|
+
function i(i) {
|
|
8
|
+
let { children: a, id: o, isFocused: s } = i, c = n(null), l = e(c, s, 420);
|
|
9
|
+
return t(s), s ? /* @__PURE__ */ r("div", {
|
|
10
|
+
ref: c,
|
|
11
|
+
id: o,
|
|
19
12
|
role: "dialog",
|
|
20
13
|
"aria-modal": "false",
|
|
21
|
-
className: `arkynDatePickerCalendarContainer ${
|
|
22
|
-
children:
|
|
14
|
+
className: `arkynDatePickerCalendarContainer ${l}`,
|
|
15
|
+
children: a
|
|
23
16
|
}) : null;
|
|
24
17
|
}
|
|
25
18
|
//#endregion
|
|
26
|
-
export {
|
|
19
|
+
export { i as DatePickerCalendarContainer };
|
|
27
20
|
|
|
28
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/components/datePicker/datePickerCalendarContainer/index.tsx"],"sourcesContent":["import { type ReactNode,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/components/datePicker/datePickerCalendarContainer/index.tsx"],"sourcesContent":["import { type ReactNode, useRef } from \"react\";\n\nimport { useFlipPosition } from \"../../../hooks/useFlipPosition\";\nimport { useScrollLock } from \"../../../hooks/useScrollLock\";\n\nimport \"./styles.css\";\n\ntype DatePickerCalendarContainerProps = {\n\tid?: string;\n\tisFocused: boolean;\n\tchildren: ReactNode;\n};\n\nfunction DatePickerCalendarContainer(props: DatePickerCalendarContainerProps) {\n\tconst { children, id, isFocused } = props;\n\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\tconst position = useFlipPosition(containerRef, isFocused, 420);\n\n\tuseScrollLock(isFocused);\n\n\tif (!isFocused) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tid={id}\n\t\t\trole=\"dialog\"\n\t\t\taria-modal=\"false\"\n\t\t\tclassName={`arkynDatePickerCalendarContainer ${position}`}\n\t\t>\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport { DatePickerCalendarContainer };\n"],"mappings":";;;;;;AAaA,SAAS,EAA4B,GAAyC;CAC7E,IAAM,EAAE,aAAU,OAAI,iBAAc,GAE9B,IAAe,EAAuB,IAAI,GAC1C,IAAW,EAAgB,GAAc,GAAW,GAAG;CAM7D,OAJA,EAAc,CAAS,GAElB,IAGJ,kBAAC,OAAD;EACC,KAAK;EACD;EACJ,MAAK;EACL,cAAW;EACX,WAAW,oCAAoC;EAE9C;CACG,CAAA,IAXiB;AAaxB"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
import { toSafeScriptString as e } from "../../../utils/escapeForInlineScript.js";
|
|
1
2
|
//#region src/components/googleAnalytics/snippets/generateGAElements.ts
|
|
2
|
-
function
|
|
3
|
-
let { measurementId:
|
|
4
|
-
return
|
|
5
|
-
src: `https://www.googletagmanager.com/gtag/js?id=${
|
|
3
|
+
function t(t) {
|
|
4
|
+
let { measurementId: n } = t;
|
|
5
|
+
return n || console.warn("Google Analytics Measurement ID is required"), {
|
|
6
|
+
src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(n)}`,
|
|
6
7
|
script: `
|
|
7
8
|
window.dataLayer = window.dataLayer || [];
|
|
8
9
|
function gtag(){dataLayer.push(arguments);}
|
|
9
10
|
gtag('js', new Date());
|
|
10
|
-
gtag('config',
|
|
11
|
+
gtag('config', ${e(n)});`
|
|
11
12
|
};
|
|
12
13
|
}
|
|
13
14
|
//#endregion
|
|
14
|
-
export {
|
|
15
|
+
export { t as generateGAElements };
|
|
15
16
|
|
|
16
17
|
//# sourceMappingURL=generateGAElements.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateGAElements.js","names":[],"sources":["../../../../../src/components/googleAnalytics/snippets/generateGAElements.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"generateGAElements.js","names":[],"sources":["../../../../../src/components/googleAnalytics/snippets/generateGAElements.ts"],"sourcesContent":["import { toSafeScriptString } from \"../../../utils/escapeForInlineScript\";\n\ntype GenerateGAElementsProps = {\n\tmeasurementId: string;\n};\n\nfunction generateGAElements(props: GenerateGAElementsProps) {\n\tconst { measurementId } = props;\n\n\tif (!measurementId)\n\t\tconsole.warn(\"Google Analytics Measurement ID is required\");\n\n\tconst src = `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(measurementId)}`;\n\n\tconst script = `\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n gtag('config', ${toSafeScriptString(measurementId)});`;\n\n\treturn {\n\t\tsrc,\n\t\tscript,\n\t};\n}\n\nexport { generateGAElements };\n"],"mappings":";;AAMA,SAAS,EAAmB,GAAgC;CAC3D,IAAM,EAAE,qBAAkB;CAa1B,OAXK,KACJ,QAAQ,KAAK,6CAA6C,GAUpD;EACN,KAAA,+CAT0D,mBAAmB,CAAa;EAU1F,QAAA;;;;qBAJmB,EAAmB,CAAa,EAAE;CAKtD;AACD"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { isValidJsIdentifier as e, toSafeScriptJson as t } from "../../../utils/escapeForInlineScript.js";
|
|
1
2
|
//#region src/components/googleTagManager/snippets/appendToDataLayer.ts
|
|
2
|
-
function
|
|
3
|
-
let { dataLayer:
|
|
4
|
-
return `
|
|
5
|
-
window.${
|
|
6
|
-
window.${
|
|
3
|
+
function n(n) {
|
|
4
|
+
let { dataLayer: r, dataLayerName: i } = n, a = e(i) ? i : "dataLayer";
|
|
5
|
+
return a !== i && console.warn(`Invalid dataLayerName "${i}", falling back to "dataLayer"`), `
|
|
6
|
+
window.${a} = window.${a} || [];
|
|
7
|
+
window.${a}.push(${t(r)})`;
|
|
7
8
|
}
|
|
8
9
|
//#endregion
|
|
9
|
-
export {
|
|
10
|
+
export { n as appendToDataLayer };
|
|
10
11
|
|
|
11
12
|
//# sourceMappingURL=appendToDataLayer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appendToDataLayer.js","names":[],"sources":["../../../../../src/components/googleTagManager/snippets/appendToDataLayer.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"appendToDataLayer.js","names":[],"sources":["../../../../../src/components/googleTagManager/snippets/appendToDataLayer.ts"],"sourcesContent":["import {\n\tisValidJsIdentifier,\n\ttoSafeScriptJson,\n} from \"../../../utils/escapeForInlineScript\";\n\ntype AppendToDataLayer = {\n\tdataLayer: Record<string, string>;\n\tdataLayerName: string;\n};\n\nfunction appendToDataLayer(props: AppendToDataLayer) {\n\tconst { dataLayer, dataLayerName } = props;\n\n\tconst safeDataLayerName = isValidJsIdentifier(dataLayerName)\n\t\t? dataLayerName\n\t\t: \"dataLayer\";\n\n\tif (safeDataLayerName !== dataLayerName) {\n\t\tconsole.warn(\n\t\t\t`Invalid dataLayerName \"${dataLayerName}\", falling back to \"dataLayer\"`,\n\t\t);\n\t}\n\n\treturn `\n window.${safeDataLayerName} = window.${safeDataLayerName} || [];\n window.${safeDataLayerName}.push(${toSafeScriptJson(dataLayer)})`;\n}\n\nexport { appendToDataLayer };\n"],"mappings":";;AAUA,SAAS,EAAkB,GAA0B;CACpD,IAAM,EAAE,cAAW,qBAAkB,GAE/B,IAAoB,EAAoB,CAAa,IACxD,IACA;CAQH,OANI,MAAsB,KACzB,QAAQ,KACP,0BAA0B,EAAc,+BACzC,GAGM;WACG,EAAkB,YAAY,EAAkB;WAChD,EAAkB,QAAQ,EAAiB,CAAS,EAAE;AACjE"}
|
|
@@ -1,25 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isValidJsIdentifier as e, toSafeScriptString as t } from "../../../utils/escapeForInlineScript.js";
|
|
2
|
+
import { appendToDataLayer as n } from "./appendToDataLayer.js";
|
|
2
3
|
//#region src/components/googleTagManager/snippets/generateGTMElements.ts
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
function r(e) {
|
|
5
|
+
return encodeURIComponent(e).replace(/'/g, "%27");
|
|
6
|
+
}
|
|
7
|
+
function i(i) {
|
|
8
|
+
let { id: a, events: o, dataLayer: s, dataLayerName: c, preview: l, auth: u } = i, d = `>m_auth=${r(u)}`, f = `>m_preview=${r(l)}`, p = r(a);
|
|
9
|
+
a || console.warn("GTM Id is required");
|
|
10
|
+
let m = `
|
|
11
|
+
<iframe src="https://www.googletagmanager.com/ns.html?id=${p}${d}${f}>m_cookies_win=x"
|
|
12
|
+
height="0" width="0" style="display:none;visibility:hidden" id="tag-manager"></iframe>`, h = e(c) ? c : "dataLayer";
|
|
13
|
+
return {
|
|
14
|
+
iframe: m,
|
|
9
15
|
script: `
|
|
10
16
|
(function(w,d,s,l,i){w[l]=w[l]||[];
|
|
11
|
-
w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js', ${JSON.stringify(
|
|
17
|
+
w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js', ${JSON.stringify(o).slice(1, -1).replace(/</g, "\\u003C")}});
|
|
12
18
|
var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
|
|
13
|
-
j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl+'${
|
|
19
|
+
j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl+'${d}${f}>m_cookies_win=x';
|
|
14
20
|
f.parentNode.insertBefore(j,f);
|
|
15
|
-
})(window,document,'script'
|
|
16
|
-
dataLayerVar:
|
|
17
|
-
dataLayer:
|
|
18
|
-
dataLayerName:
|
|
21
|
+
})(window,document,'script',${t(h)},${t(a)});`,
|
|
22
|
+
dataLayerVar: n({
|
|
23
|
+
dataLayer: s,
|
|
24
|
+
dataLayerName: c
|
|
19
25
|
})
|
|
20
26
|
};
|
|
21
27
|
}
|
|
22
28
|
//#endregion
|
|
23
|
-
export {
|
|
29
|
+
export { i as generateGTMElements };
|
|
24
30
|
|
|
25
31
|
//# sourceMappingURL=generateGTMElements.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateGTMElements.js","names":[],"sources":["../../../../../src/components/googleTagManager/snippets/generateGTMElements.ts"],"sourcesContent":["import { appendToDataLayer } from \"./appendToDataLayer\";\n\ntype GenerateGTMElementsProps = {\n\tid: string;\n\tevents: Record<string, string>;\n\tdataLayer: Record<string, string>;\n\tdataLayerName: string;\n\tpreview: string;\n\tauth: string;\n};\n\nfunction generateGTMElements(props: GenerateGTMElementsProps) {\n\tconst { id, events, dataLayer, dataLayerName, preview, auth } = props;\n\n\tconst gtmAuth = `>m_auth=${auth}`;\n\tconst gtmPreview = `>m_preview=${preview}`;\n\n\tif (!id) console.warn(\"GTM Id is required\");\n\n\tconst iframe = `\n <iframe src=\"https://www.googletagmanager.com/ns.html?id=${
|
|
1
|
+
{"version":3,"file":"generateGTMElements.js","names":[],"sources":["../../../../../src/components/googleTagManager/snippets/generateGTMElements.ts"],"sourcesContent":["import {\n\tisValidJsIdentifier,\n\ttoSafeScriptString,\n} from \"../../../utils/escapeForInlineScript\";\nimport { appendToDataLayer } from \"./appendToDataLayer\";\n\ntype GenerateGTMElementsProps = {\n\tid: string;\n\tevents: Record<string, string>;\n\tdataLayer: Record<string, string>;\n\tdataLayerName: string;\n\tpreview: string;\n\tauth: string;\n};\n\n/**\n * URL-encodes a value for safe use as a query-string value that is also embedded\n * inside a single-quoted JS string literal. `encodeURIComponent` alone leaves `'`\n * unescaped, which would otherwise let the value break out of that string literal.\n */\nfunction toSafeUrlQueryValue(value: string): string {\n\treturn encodeURIComponent(value).replace(/'/g, \"%27\");\n}\n\nfunction generateGTMElements(props: GenerateGTMElementsProps) {\n\tconst { id, events, dataLayer, dataLayerName, preview, auth } = props;\n\n\tconst gtmAuth = `>m_auth=${toSafeUrlQueryValue(auth)}`;\n\tconst gtmPreview = `>m_preview=${toSafeUrlQueryValue(preview)}`;\n\tconst safeId = toSafeUrlQueryValue(id);\n\n\tif (!id) console.warn(\"GTM Id is required\");\n\n\tconst iframe = `\n <iframe src=\"https://www.googletagmanager.com/ns.html?id=${safeId}${gtmAuth}${gtmPreview}>m_cookies_win=x\"\n height=\"0\" width=\"0\" style=\"display:none;visibility:hidden\" id=\"tag-manager\"></iframe>`;\n\n\tconst safeDataLayerName = isValidJsIdentifier(dataLayerName)\n\t\t? dataLayerName\n\t\t: \"dataLayer\";\n\n\tconst script = `\n (function(w,d,s,l,i){w[l]=w[l]||[];\n w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js', ${JSON.stringify(\n\t\t\t\tevents,\n\t\t\t)\n\t\t\t\t.slice(1, -1)\n\t\t\t\t.replace(/</g, \"\\\\u003C\")}});\n var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';\n j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl+'${gtmAuth}${gtmPreview}>m_cookies_win=x';\n f.parentNode.insertBefore(j,f);\n })(window,document,'script',${toSafeScriptString(safeDataLayerName)},${toSafeScriptString(id)});`;\n\n\tconst dataLayerVar = appendToDataLayer({ dataLayer, dataLayerName });\n\n\treturn {\n\t\tiframe,\n\t\tscript,\n\t\tdataLayerVar,\n\t};\n}\n\nexport { generateGTMElements };\n"],"mappings":";;;AAoBA,SAAS,EAAoB,GAAuB;CACnD,OAAO,mBAAmB,CAAK,CAAC,CAAC,QAAQ,MAAM,KAAK;AACrD;AAEA,SAAS,EAAoB,GAAiC;CAC7D,IAAM,EAAE,OAAI,WAAQ,cAAW,kBAAe,YAAS,YAAS,GAE1D,IAAU,aAAa,EAAoB,CAAI,KAC/C,IAAa,gBAAgB,EAAoB,CAAO,KACxD,IAAS,EAAoB,CAAE;CAErC,AAAK,KAAI,QAAQ,KAAK,oBAAoB;CAE1C,IAAM,IAAS;+DAC+C,IAAS,IAAU,EAAW;+FAGtF,IAAoB,EAAoB,CAAa,IACxD,IACA;CAgBH,OAAO;EACN;EACA,QAAA;;qEAdmE,KAAK,UACtE,CACD,CAAC,CACC,MAAM,GAAG,EAAE,CAAC,CACZ,QAAQ,MAAM,SAAS,EAAE;;+EAEiD,IAAU,EAAW;;kCAElE,EAAmB,CAAiB,EAAE,GAAG,EAAmB,CAAE,EAAE;EAOhG,cALoB,EAAkB;GAAE;GAAW;EAAc,CAKjE;CACD;AACD"}
|
|
@@ -1,41 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useFlipPosition as e } from "../../../hooks/useFlipPosition.js";
|
|
2
|
+
import { useScrollLock as t } from "../../../hooks/useScrollLock.js";
|
|
3
|
+
import { Input as n } from "../../input/index.js";
|
|
3
4
|
/* empty css */
|
|
4
|
-
import {
|
|
5
|
-
import { jsx as
|
|
6
|
-
import { Search as
|
|
5
|
+
import { useRef as r } from "react";
|
|
6
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
7
|
+
import { Search as o } from "lucide-react";
|
|
7
8
|
//#region src/components/multiSelect/multiSelectOptionsContainer/index.tsx
|
|
8
|
-
function
|
|
9
|
-
let { children:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
let e = h.current.parentElement;
|
|
14
|
-
if (!e) return;
|
|
15
|
-
let t = e.getBoundingClientRect();
|
|
16
|
-
window.innerHeight - t.bottom < 300 && t.top > 300 ? _("top") : _("bottom");
|
|
17
|
-
})();
|
|
18
|
-
}, [d]);
|
|
19
|
-
function v(e) {
|
|
20
|
-
f && m(e.target.value);
|
|
9
|
+
function s(s) {
|
|
10
|
+
let { children: c, id: l, isFocused: u, isSearchable: d, search: f, onSearch: p } = s, m = r(null), h = e(m, u, 300);
|
|
11
|
+
t(u);
|
|
12
|
+
function g(e) {
|
|
13
|
+
d && p(e.target.value);
|
|
21
14
|
}
|
|
22
|
-
return
|
|
23
|
-
ref:
|
|
24
|
-
id:
|
|
15
|
+
return u ? /* @__PURE__ */ a("div", {
|
|
16
|
+
ref: m,
|
|
17
|
+
id: l,
|
|
25
18
|
role: "listbox",
|
|
26
19
|
"aria-multiselectable": "true",
|
|
27
|
-
className: `arkynMultiSelectOptionsContainer ${
|
|
28
|
-
children: [
|
|
20
|
+
className: `arkynMultiSelectOptionsContainer ${h}`,
|
|
21
|
+
children: [d && /* @__PURE__ */ i(n, {
|
|
29
22
|
type: "search",
|
|
30
23
|
name: "search-select",
|
|
31
24
|
variant: "underline",
|
|
32
|
-
leftIcon:
|
|
33
|
-
value:
|
|
34
|
-
onChange:
|
|
35
|
-
}),
|
|
25
|
+
leftIcon: o,
|
|
26
|
+
value: f,
|
|
27
|
+
onChange: g
|
|
28
|
+
}), c]
|
|
36
29
|
}) : null;
|
|
37
30
|
}
|
|
38
31
|
//#endregion
|
|
39
|
-
export {
|
|
32
|
+
export { s as MultiSelectOptionsContainer };
|
|
40
33
|
|
|
41
34
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/components/multiSelect/multiSelectOptionsContainer/index.tsx"],"sourcesContent":["import { Search } from \"lucide-react\";\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/components/multiSelect/multiSelectOptionsContainer/index.tsx"],"sourcesContent":["import { Search } from \"lucide-react\";\nimport { type ChangeEvent, type ReactNode, useRef } from \"react\";\n\nimport { useFlipPosition } from \"../../../hooks/useFlipPosition\";\nimport { useScrollLock } from \"../../../hooks/useScrollLock\";\nimport { Input } from \"../../input\";\n\nimport \"./styles.css\";\n\ntype MultiSelectOptionsContainerProps = {\n\tid?: string;\n\tisFocused: boolean;\n\tisSearchable: boolean;\n\tchildren: ReactNode;\n\tsearch: string;\n\tonSearch: (value: string) => void;\n};\n\nfunction MultiSelectOptionsContainer(props: MultiSelectOptionsContainerProps) {\n\tconst { children, id, isFocused, isSearchable, search, onSearch } = props;\n\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\tconst position = useFlipPosition(containerRef, isFocused, 300);\n\n\tuseScrollLock(isFocused);\n\n\tfunction handleSearch(e: ChangeEvent<HTMLInputElement>) {\n\t\tif (!isSearchable) return;\n\t\tonSearch(e.target.value);\n\t}\n\n\tif (!isFocused) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tid={id}\n\t\t\trole=\"listbox\"\n\t\t\taria-multiselectable=\"true\"\n\t\t\tclassName={`arkynMultiSelectOptionsContainer ${position}`}\n\t\t>\n\t\t\t{isSearchable && (\n\t\t\t\t<Input\n\t\t\t\t\ttype=\"search\"\n\t\t\t\t\tname=\"search-select\"\n\t\t\t\t\tvariant=\"underline\"\n\t\t\t\t\tleftIcon={Search}\n\t\t\t\t\tvalue={search}\n\t\t\t\t\tonChange={handleSearch}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport { MultiSelectOptionsContainer };\n"],"mappings":";;;;;;;;AAkBA,SAAS,EAA4B,GAAyC;CAC7E,IAAM,EAAE,aAAU,OAAI,cAAW,iBAAc,WAAQ,gBAAa,GAE9D,IAAe,EAAuB,IAAI,GAC1C,IAAW,EAAgB,GAAc,GAAW,GAAG;CAE7D,EAAc,CAAS;CAEvB,SAAS,EAAa,GAAkC;EAClD,KACL,EAAS,EAAE,OAAO,KAAK;CACxB;CAIA,OAFK,IAGJ,kBAAC,OAAD;EACC,KAAK;EACD;EACJ,MAAK;EACL,wBAAqB;EACrB,WAAW,oCAAoC;YALhD,CAOE,KACA,kBAAC,GAAD;GACC,MAAK;GACL,MAAK;GACL,SAAQ;GACR,UAAU;GACV,OAAO;GACP,UAAU;EACV,CAAA,GAGD,CACG;MAtBiB;AAwBxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/richText/index.tsx"],"sourcesContent":["import { isHotkey } from \"is-hotkey\";\nimport {\n\tAlignCenter,\n\tAlignJustify,\n\tAlignLeft,\n\tAlignRight,\n\tBold,\n\tCode,\n\tHeading1,\n\tHeading2,\n\tItalic,\n\tQuote,\n\tUnderline,\n} from \"lucide-react\";\nimport { useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport { createEditor, type Descendant } from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, Slate, withReact } from \"slate-react\";\nimport { useForm } from \"../../hooks/useForm\";\nimport { clearLinkMarkAtBoundary } from \"../../services/clearLinkMarkAtBoundary\";\nimport { extractTextFromNode } from \"../../services/extractTextFromNode\";\nimport { FieldTemplate } from \"../../services/fieldTemplate\";\nimport { toggleMark } from \"../../services/toggleMark\";\nimport { hotKeys, initialValue } from \"../../templates/richTextTemplates\";\nimport type {\n\tRichTextHiddenButtonKey,\n\tRichTextProps,\n} from \"../../types/richTextTypes\";\nimport { BlockButton } from \"./blockButton\";\nimport { Element } from \"./element\";\nimport { InsertImage } from \"./insertImage\";\nimport { InsertLink } from \"./insertLink\";\nimport { InsertVideo } from \"./insertVideo\";\nimport { Leaf } from \"./leaf\";\nimport { MarkButton } from \"./markButton\";\nimport { Toolbar } from \"./toolbar\";\nimport \"./styles.css\";\n\n/**\n * RichText, WYSIWYG rich-text editor built on Slate.js with a configurable toolbar.\n *\n * **Toolbar features:** bold, italic, underline, code, H1/H2, block quote, alignment (left/center/right/justify), image, video, and link insertion.\n * Pressing Space or Enter right after a link automatically stops new text from continuing to be part of that link.\n *\n * Editor content is stored as a Slate JSON string in a hidden `<input>` for form submission.\n * Integrates with `useForm` to display validation errors by field name.\n *\n * @param props.name - Field name for form submission. Required.\n * @param props.label - Label text displayed above the editor.\n * @param props.hiddenButtons - Toolbar button keys to hide (e.g. `[\"image\", \"code\"]`).\n * @param props.imageConfig - Enables image insertion; contains the upload endpoint and modal labels.\n * @param props.videoConfig - Customizes the video insertion modal labels.\n * @param props.linkConfig - Customizes the link insertion modal labels.\n * @param props.defaultValue - Initial editor content as a Slate JSON string. Default: \"[]\"\n * @param props.maxLimit - Maximum character count. Default: 10000\n * @param props.enforceCharacterLimit - Prevents typing past `maxLimit`. Default: false\n * @param props.onChangeCharactersCount - Callback fired on every keystroke, receives the current character count.\n * @param props.onChange - Callback fired when editor content changes, receives the Slate `Descendant[]`.\n * @param props.baseErrorMessage - Custom error message (overrides `useForm` context error).\n * @param props.isError - Forces the error visual state.\n * @param props.id - Custom id for the editable area element.\n * @param props.showAsterisk - Appends `*` to the label.\n * @param props.orientation - Layout direction. Default: \"vertical\"\n * @param props.unShowFieldTemplate - Skips wrapper, label, and error rendering. Default: false\n *\n * @returns RichText JSX element wrapped in `FieldTemplate`.\n *\n * @example\n * ```tsx\n * // Basic\n * <RichText name=\"content\" />\n *\n * // With character limit and hidden toolbar buttons\n * <RichText\n * name=\"description\"\n * label=\"Description\"\n * maxLimit={500}\n * enforceCharacterLimit\n * hiddenButtons={[\"image\", \"video\", \"code\"]}\n * onChangeCharactersCount={(n) => setCharCount(n)}\n * />\n *\n * // With image upload support\n * <RichText\n * name=\"article\"\n * label=\"Article Body\"\n * imageConfig={{ action: \"/api/upload\" }}\n * />\n *\n * // With custom link insertion modal labels\n * <RichText\n * name=\"article\"\n * label=\"Article Body\"\n * linkConfig={{ modalTitle: \"Add a link\" }}\n * />\n * ```\n */\n\nfunction RichText(props: RichTextProps) {\n\tconst {\n\t\tname,\n\t\thiddenButtons,\n\t\timageConfig,\n\t\tvideoConfig,\n\t\tlinkConfig,\n\t\tclassName: wrapperClassName = \"\",\n\t\tdefaultValue = \"[]\",\n\t\tenforceCharacterLimit = false,\n\t\tonChangeCharactersCount,\n\t\tbaseErrorMessage,\n\t\tmaxLimit = 10000,\n\t\tonChange,\n\t\tisError: baseIsError,\n\t\tlabel,\n\t\tshowAsterisk,\n\t\tid,\n\t\torientation = \"vertical\",\n\t\tunShowFieldTemplate = false,\n\t} = props;\n\n\tconst editor = useMemo(() => withHistory(withReact(createEditor())), []);\n\n\tconst { fieldErrors } = useForm();\n\n\tconst defaultNodes = useMemo((): Descendant[] => {\n\t\ttry {\n\t\t\tconst parsedNodes = JSON.parse(defaultValue);\n\t\t\tif (!Array.isArray(parsedNodes) || parsedNodes.length === 0) {\n\t\t\t\treturn structuredClone(initialValue);\n\t\t\t}\n\n\t\t\tconst isValidNodes = parsedNodes.every(\n\t\t\t\t(node) =>\n\t\t\t\t\ttypeof node === \"object\" &&\n\t\t\t\t\tnode !== null &&\n\t\t\t\t\t\"type\" in node &&\n\t\t\t\t\t\"children\" in node,\n\t\t\t);\n\n\t\t\treturn isValidNodes ? parsedNodes : structuredClone(initialValue);\n\t\t} catch (_error) {\n\t\t\treturn structuredClone(initialValue);\n\t\t}\n\t}, [defaultValue]);\n\n\tconst textFromNodes = extractTextFromNode(defaultNodes);\n\n\tconst [charactersCount, setCharactersCount] = useState(textFromNodes.length);\n\tconst [inputValue, setInputValue] = useState(\n\t\tJSON.stringify(defaultNodes) || \"[]\",\n\t);\n\n\tconst [onFocus, setOnFocus] = useState(false);\n\n\tconst ref = useRef<HTMLInputElement>(null);\n\tconst generatedId = useId();\n\tconst inputId = id || generatedId;\n\n\tconst errorMessage = baseErrorMessage || fieldErrors?.[name];\n\tconst isError = baseIsError || !!errorMessage;\n\n\tconst renderLeaf = useCallback(Leaf, []);\n\tconst renderElement = useCallback(Element, []);\n\n\tfunction handleChange(value: Descendant[]) {\n\t\tconst text = extractTextFromNode(value);\n\n\t\tsetCharactersCount(text.length);\n\t\tonChangeCharactersCount?.(text.length);\n\n\t\tif (enforceCharacterLimit && text.length >= maxLimit) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetInputValue(JSON.stringify(value));\n\t\tonChange?.(value);\n\t}\n\n\tconst focusClass = onFocus ? \"focusTrue\" : \"focusFalse\";\n\tconst errorClass = isError\n\t\t? \"errorTrue\"\n\t\t: maxLimit < charactersCount\n\t\t\t? \"errorTrue\"\n\t\t\t: \"errorFalse\";\n\n\tconst className = `arkynRichText ${errorClass} ${focusClass}`;\n\n\tconst restatesCharacters = maxLimit - charactersCount;\n\n\tfunction buttonIsNotHidden(format: RichTextHiddenButtonKey) {\n\t\treturn !hiddenButtons?.includes(format);\n\t}\n\n\treturn (\n\t\t<FieldTemplate\n\t\t\tname={name}\n\t\t\tlabel={label}\n\t\t\tshowAsterisk={showAsterisk}\n\t\t\tclassName={wrapperClassName}\n\t\t\terrorMessage={errorMessage}\n\t\t\tunShowFieldTemplate={unShowFieldTemplate}\n\t\t\torientation={orientation}\n\t\t>\n\t\t\t<Slate\n\t\t\t\teditor={editor}\n\t\t\t\tinitialValue={defaultNodes}\n\t\t\t\tonChange={handleChange}\n\t\t\t\tonValueChange={handleChange}\n\t\t\t>\n\t\t\t\t<div className={className}>\n\t\t\t\t\t<Toolbar>\n\t\t\t\t\t\t{buttonIsNotHidden(\"headingOne\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"headingOne\" icon={Heading1} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"headingTwo\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"headingTwo\" icon={Heading2} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"blockQuote\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"blockQuote\" icon={Quote} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"bold\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"bold\" icon={Bold} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"italic\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"italic\" icon={Italic} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"underline\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"underline\" icon={Underline} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"code\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"code\" icon={Code} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"left\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"left\" icon={AlignLeft} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"right\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"right\" icon={AlignRight} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"center\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"center\" icon={AlignCenter} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"justify\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"justify\" icon={AlignJustify} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{imageConfig && buttonIsNotHidden(\"image\") && (\n\t\t\t\t\t\t\t<InsertImage {...imageConfig} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"video\") && <InsertVideo {...videoConfig} />}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"link\") && <InsertLink {...linkConfig} />}\n\t\t\t\t\t</Toolbar>\n\n\t\t\t\t\t<Editable\n\t\t\t\t\t\tclassName=\"editorContainer\"\n\t\t\t\t\t\trenderElement={renderElement}\n\t\t\t\t\t\trenderLeaf={renderLeaf}\n\t\t\t\t\t\tspellCheck\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\tid={inputId}\n\t\t\t\t\t\tonFocus={() => setOnFocus(true)}\n\t\t\t\t\t\tonBlur={() => setOnFocus(false)}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.key === \" \" || event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tclearLinkMarkAtBoundary(editor);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfor (const hotkey in hotKeys) {\n\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: intentional\n\t\t\t\t\t\t\t\tif (isHotkey(hotkey, event as any)) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tconst mark = hotKeys[hotkey as keyof typeof hotKeys];\n\t\t\t\t\t\t\t\t\ttoggleMark(editor, mark);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{restatesCharacters < 0 && (\n\t\t\t\t\t\t<div className=\"restatesCharacters\">{restatesCharacters}</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<input\n\t\t\t\t\ttype=\"hidden\"\n\t\t\t\t\tname={name}\n\t\t\t\t\tvalue={inputValue.slice(0, maxLimit)}\n\t\t\t\t/>\n\n\t\t\t\t<input type=\"hidden\" name={`${name}Count`} value={charactersCount} />\n\t\t\t</Slate>\n\t\t</FieldTemplate>\n\t);\n}\n\nexport { RichText };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAkGA,SAAS,EAAS,GAAsB;CACvC,IAAM,EACL,SACA,kBACA,gBACA,gBACA,eACA,WAAW,IAAmB,IAC9B,kBAAe,MACf,2BAAwB,IACxB,4BACA,qBACA,cAAW,KACX,cACA,SAAS,GACT,UACA,iBACA,QACA,kBAAc,YACd,0BAAsB,OACnB,GAEE,IAAS,QAAc,EAAY,EAAU,EAAa,CAAC,CAAC,GAAG,CAAC,CAAC,GAEjE,EAAE,oBAAgB,EAAQ,GAE1B,IAAe,QAA4B;EAChD,IAAI;GACH,IAAM,IAAc,KAAK,MAAM,CAAY;GAa3C,OAZI,CAAC,MAAM,QAAQ,CAAW,KAAK,EAAY,WAAW,IAClD,gBAAgB,CAAY,IAGf,EAAY,OAC/B,MACA,OAAO,KAAS,cAChB,KACA,UAAU,KACV,cAAc,CAGT,IAAe,IAAc,gBAAgB,CAAY;EACjE,QAAiB;GAChB,OAAO,gBAAgB,CAAY;EACpC;CACD,GAAG,CAAC,CAAY,CAAC,GAIX,CAAC,GAAiB,MAAsB,EAFxB,EAAoB,CAEa,CAAA,CAAc,MAAM,GACrE,CAAC,IAAY,MAAiB,EACnC,KAAK,UAAU,CAAY,KAAK,IACjC,GAEM,CAAC,IAAS,KAAc,EAAS,EAAK,GAEtC,IAAM,GAAyB,IAAI,GACnC,KAAc,EAAM,GACpB,KAAU,MAAM,IAEhB,IAAe,KAAoB,KAAc,IACjD,KAAU,KAAe,CAAC,CAAC,GAE3B,KAAa,EAAY,IAAM,CAAC,CAAC,GACjC,KAAgB,EAAY,GAAS,CAAC,CAAC;CAE7C,SAAS,EAAa,GAAqB;EAC1C,IAAM,IAAO,EAAoB,CAAK;EAEtC,GAAmB,EAAK,MAAM,GAC9B,IAA0B,EAAK,MAAM,GAEjC,OAAyB,EAAK,UAAU,OAI5C,GAAc,KAAK,UAAU,CAAK,CAAC,GACnC,KAAW,CAAK;CACjB;CASA,IAAM,KAAY,iBANC,MAEhB,IAAW,IADX,cAGC,aAE0C,GAP3B,KAAU,cAAc,gBASrC,IAAqB,IAAW;CAEtC,SAAS,EAAkB,GAAiC;EAC3D,OAAO,CAAC,GAAe,SAAS,CAAM;CACvC;CAEA,OACC,kBAAC,GAAD;EACO;EACC;EACO;EACd,WAAW;EACG;EACO;EACR;YAEb,kBAAC,GAAD;GACS;GACR,cAAc;GACd,UAAU;GACV,eAAe;aAJhB;IAMC,kBAAC,OAAD;KAAgB;eAAhB;MACC,kBAAC,GAAD,EAAA,UAAA;OACE,EAAkB,YAAY,KAC9B,kBAAC,GAAD;QAAa,QAAO;QAAa,MAAM;OAAW,CAAA;OAGlD,EAAkB,YAAY,KAC9B,kBAAC,GAAD;QAAa,QAAO;QAAa,MAAM;OAAW,CAAA;OAGlD,EAAkB,YAAY,KAC9B,kBAAC,GAAD;QAAa,QAAO;QAAa,MAAM;OAAQ,CAAA;OAG/C,EAAkB,MAAM,KACxB,kBAAC,GAAD;QAAY,QAAO;QAAO,MAAM;OAAO,CAAA;OAGvC,EAAkB,QAAQ,KAC1B,kBAAC,GAAD;QAAY,QAAO;QAAS,MAAM;OAAS,CAAA;OAG3C,EAAkB,WAAW,KAC7B,kBAAC,GAAD;QAAY,QAAO;QAAY,MAAM;OAAY,CAAA;OAGjD,EAAkB,MAAM,KACxB,kBAAC,GAAD;QAAY,QAAO;QAAO,MAAM;OAAO,CAAA;OAGvC,EAAkB,MAAM,KACxB,kBAAC,GAAD;QAAa,QAAO;QAAO,MAAM;OAAY,CAAA;OAG7C,EAAkB,OAAO,KACzB,kBAAC,GAAD;QAAa,QAAO;QAAQ,MAAM;OAAa,CAAA;OAG/C,EAAkB,QAAQ,KAC1B,kBAAC,GAAD;QAAa,QAAO;QAAS,MAAM;OAAc,CAAA;OAGjD,EAAkB,SAAS,KAC3B,kBAAC,GAAD;QAAa,QAAO;QAAU,MAAM;OAAe,CAAA;OAGnD,KAAe,EAAkB,OAAO,KACxC,kBAAC,GAAD,EAAa,GAAI,EAAc,CAAA;OAG/B,EAAkB,OAAO,KAAK,kBAAC,IAAD,EAAa,GAAI,EAAc,CAAA;OAE7D,EAAkB,MAAM,KAAK,kBAAC,IAAD,EAAY,GAAI,EAAa,CAAA;MACnD,EAAA,CAAA;MAET,kBAAC,GAAD;OACC,WAAU;OACK;OACH;OACZ,YAAA;OACK;OACL,IAAI;OACJ,eAAe,EAAW,EAAI;OAC9B,cAAc,EAAW,EAAK;OAC9B,YAAY,MAAU;QACrB,CAAI,EAAM,QAAQ,OAAO,EAAM,QAAQ,YACtC,EAAwB,CAAM;QAG/B,KAAK,IAAM,KAAU,GAEpB,IAAI,EAAS,GAAQ,CAAY,GAAG;SACnC,EAAM,eAAe;SACrB,IAAM,IAAO,EAAQ;SACrB,EAAW,GAAQ,CAAI;QACxB;OAEF;MACA,CAAA;MAEA,IAAqB,KACrB,kBAAC,OAAD;OAAK,WAAU;iBAAsB;MAAwB,CAAA;KAE1D;;IAEL,kBAAC,SAAD;KACC,MAAK;KACC;KACN,OAAO,GAAW,MAAM,GAAG,CAAQ;IACnC,CAAA;IAED,kBAAC,SAAD;KAAO,MAAK;KAAS,MAAM,GAAG,EAAK;KAAQ,OAAO;IAAkB,CAAA;GAC9D;;CACO,CAAA;AAEjB"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/richText/index.tsx"],"sourcesContent":["import { isHotkey } from \"is-hotkey\";\nimport {\n\tAlignCenter,\n\tAlignJustify,\n\tAlignLeft,\n\tAlignRight,\n\tBold,\n\tCode,\n\tHeading1,\n\tHeading2,\n\tItalic,\n\tQuote,\n\tUnderline,\n} from \"lucide-react\";\nimport { useCallback, useId, useMemo, useRef, useState } from \"react\";\nimport { createEditor, type Descendant } from \"slate\";\nimport { withHistory } from \"slate-history\";\nimport { Editable, Slate, withReact } from \"slate-react\";\nimport { useForm } from \"../../hooks/useForm\";\nimport { clearLinkMarkAtBoundary } from \"../../services/clearLinkMarkAtBoundary\";\nimport { extractTextFromNode } from \"../../services/extractTextFromNode\";\nimport { FieldTemplate } from \"../../services/fieldTemplate\";\nimport { toggleMark } from \"../../services/toggleMark\";\nimport { hotKeys, initialValue } from \"../../templates/richTextTemplates\";\nimport type {\n\tRichTextHiddenButtonKey,\n\tRichTextProps,\n} from \"../../types/richTextTypes\";\nimport { BlockButton } from \"./blockButton\";\nimport { Element } from \"./element\";\nimport { InsertImage } from \"./insertImage\";\nimport { InsertLink } from \"./insertLink\";\nimport { InsertVideo } from \"./insertVideo\";\nimport { Leaf } from \"./leaf\";\nimport { MarkButton } from \"./markButton\";\nimport { Toolbar } from \"./toolbar\";\nimport \"./styles.css\";\n\n/**\n * RichText, WYSIWYG rich-text editor built on Slate.js with a configurable toolbar.\n *\n * **Toolbar features:** bold, italic, underline, code, H1/H2, block quote, alignment (left/center/right/justify), image, video, and link insertion.\n * Pressing Space or Enter right after a link automatically stops new text from continuing to be part of that link.\n *\n * Editor content is stored as a Slate JSON string in a hidden `<input>` for form submission.\n * Integrates with `useForm` to display validation errors by field name.\n *\n * @param props.name - Field name for form submission. Required.\n * @param props.label - Label text displayed above the editor.\n * @param props.hiddenButtons - Toolbar button keys to hide (e.g. `[\"image\", \"code\"]`).\n * @param props.imageConfig - Enables image insertion; contains the upload endpoint and modal labels.\n * @param props.videoConfig - Customizes the video insertion modal labels.\n * @param props.linkConfig - Customizes the link insertion modal labels.\n * @param props.defaultValue - Initial editor content as a Slate JSON string. Default: \"[]\"\n * @param props.maxLimit - Maximum character count. Default: 10000\n * @param props.enforceCharacterLimit - Prevents typing past `maxLimit`. Default: false\n * @param props.onChangeCharactersCount - Callback fired on every keystroke, receives the current character count.\n * @param props.onChange - Callback fired when editor content changes, receives the Slate `Descendant[]`.\n * @param props.baseErrorMessage - Custom error message (overrides `useForm` context error).\n * @param props.isError - Forces the error visual state.\n * @param props.id - Custom id for the editable area element.\n * @param props.showAsterisk - Appends `*` to the label.\n * @param props.orientation - Layout direction. Default: \"vertical\"\n * @param props.unShowFieldTemplate - Skips wrapper, label, and error rendering. Default: false\n *\n * @returns RichText JSX element wrapped in `FieldTemplate`.\n *\n * @example\n * ```tsx\n * // Basic\n * <RichText name=\"content\" />\n *\n * // With character limit and hidden toolbar buttons\n * <RichText\n * name=\"description\"\n * label=\"Description\"\n * maxLimit={500}\n * enforceCharacterLimit\n * hiddenButtons={[\"image\", \"video\", \"code\"]}\n * onChangeCharactersCount={(n) => setCharCount(n)}\n * />\n *\n * // With image upload support\n * <RichText\n * name=\"article\"\n * label=\"Article Body\"\n * imageConfig={{ action: \"/api/upload\" }}\n * />\n *\n * // With custom link insertion modal labels\n * <RichText\n * name=\"article\"\n * label=\"Article Body\"\n * linkConfig={{ modalTitle: \"Add a link\" }}\n * />\n * ```\n */\n\nfunction RichText(props: RichTextProps) {\n\tconst {\n\t\tname,\n\t\thiddenButtons,\n\t\timageConfig,\n\t\tvideoConfig,\n\t\tlinkConfig,\n\t\tclassName: wrapperClassName = \"\",\n\t\tdefaultValue = \"[]\",\n\t\tenforceCharacterLimit = false,\n\t\tonChangeCharactersCount,\n\t\tbaseErrorMessage,\n\t\tmaxLimit = 10000,\n\t\tonChange,\n\t\tisError: baseIsError,\n\t\tlabel,\n\t\tshowAsterisk,\n\t\tid,\n\t\torientation = \"vertical\",\n\t\tunShowFieldTemplate = false,\n\t} = props;\n\n\tconst editor = useMemo(() => withHistory(withReact(createEditor())), []);\n\n\tconst { fieldErrors } = useForm();\n\n\tconst defaultNodes = useMemo((): Descendant[] => {\n\t\ttry {\n\t\t\tconst parsedNodes = JSON.parse(defaultValue);\n\t\t\tif (!Array.isArray(parsedNodes) || parsedNodes.length === 0) {\n\t\t\t\treturn structuredClone(initialValue);\n\t\t\t}\n\n\t\t\tconst isValidNodes = parsedNodes.every(\n\t\t\t\t(node) =>\n\t\t\t\t\ttypeof node === \"object\" &&\n\t\t\t\t\tnode !== null &&\n\t\t\t\t\t\"type\" in node &&\n\t\t\t\t\t\"children\" in node,\n\t\t\t);\n\n\t\t\treturn isValidNodes ? parsedNodes : structuredClone(initialValue);\n\t\t} catch (_error) {\n\t\t\treturn structuredClone(initialValue);\n\t\t}\n\t}, [defaultValue]);\n\n\tconst textFromNodes = extractTextFromNode(defaultNodes);\n\n\tconst [charactersCount, setCharactersCount] = useState(textFromNodes.length);\n\tconst [inputValue, setInputValue] = useState(\n\t\tJSON.stringify(defaultNodes) || \"[]\",\n\t);\n\n\tconst [onFocus, setOnFocus] = useState(false);\n\n\tconst ref = useRef<HTMLInputElement>(null);\n\tconst generatedId = useId();\n\tconst inputId = id || generatedId;\n\n\tconst errorMessage = baseErrorMessage || fieldErrors?.[name];\n\tconst isError = baseIsError || !!errorMessage;\n\n\tconst renderLeaf = useCallback(Leaf, []);\n\tconst renderElement = useCallback(Element, []);\n\n\tfunction handleChange(value: Descendant[]) {\n\t\tconst text = extractTextFromNode(value);\n\n\t\tsetCharactersCount(text.length);\n\t\tonChangeCharactersCount?.(text.length);\n\n\t\tif (enforceCharacterLimit && text.length >= maxLimit) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetInputValue(JSON.stringify(value));\n\t\tonChange?.(value);\n\t}\n\n\tconst focusClass = onFocus ? \"focusTrue\" : \"focusFalse\";\n\tconst errorClass = isError\n\t\t? \"errorTrue\"\n\t\t: maxLimit < charactersCount\n\t\t\t? \"errorTrue\"\n\t\t\t: \"errorFalse\";\n\n\tconst className = `arkynRichText ${errorClass} ${focusClass}`;\n\n\tconst restatesCharacters = maxLimit - charactersCount;\n\n\tfunction buttonIsNotHidden(format: RichTextHiddenButtonKey) {\n\t\treturn !hiddenButtons?.includes(format);\n\t}\n\n\treturn (\n\t\t<FieldTemplate\n\t\t\tname={name}\n\t\t\tlabel={label}\n\t\t\tshowAsterisk={showAsterisk}\n\t\t\tclassName={wrapperClassName}\n\t\t\terrorMessage={errorMessage}\n\t\t\tunShowFieldTemplate={unShowFieldTemplate}\n\t\t\torientation={orientation}\n\t\t>\n\t\t\t<Slate\n\t\t\t\teditor={editor}\n\t\t\t\tinitialValue={defaultNodes}\n\t\t\t\tonChange={handleChange}\n\t\t\t\tonValueChange={handleChange}\n\t\t\t>\n\t\t\t\t<div className={className}>\n\t\t\t\t\t<Toolbar>\n\t\t\t\t\t\t{buttonIsNotHidden(\"headingOne\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"headingOne\" icon={Heading1} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"headingTwo\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"headingTwo\" icon={Heading2} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"blockQuote\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"blockQuote\" icon={Quote} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"bold\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"bold\" icon={Bold} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"italic\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"italic\" icon={Italic} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"underline\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"underline\" icon={Underline} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"code\") && (\n\t\t\t\t\t\t\t<MarkButton format=\"code\" icon={Code} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"left\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"left\" icon={AlignLeft} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"right\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"right\" icon={AlignRight} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"center\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"center\" icon={AlignCenter} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"justify\") && (\n\t\t\t\t\t\t\t<BlockButton format=\"justify\" icon={AlignJustify} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{imageConfig && buttonIsNotHidden(\"image\") && (\n\t\t\t\t\t\t\t<InsertImage {...imageConfig} />\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"video\") && <InsertVideo {...videoConfig} />}\n\n\t\t\t\t\t\t{buttonIsNotHidden(\"link\") && <InsertLink {...linkConfig} />}\n\t\t\t\t\t</Toolbar>\n\n\t\t\t\t\t<Editable\n\t\t\t\t\t\tclassName=\"editorContainer\"\n\t\t\t\t\t\trenderElement={renderElement}\n\t\t\t\t\t\trenderLeaf={renderLeaf}\n\t\t\t\t\t\tspellCheck\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\tid={inputId}\n\t\t\t\t\t\tonFocus={() => setOnFocus(true)}\n\t\t\t\t\t\tonBlur={() => setOnFocus(false)}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.key === \" \" || event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tclearLinkMarkAtBoundary(editor);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfor (const hotkey in hotKeys) {\n\t\t\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: intentional\n\t\t\t\t\t\t\t\tif (isHotkey(hotkey, event as any)) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tconst mark = hotKeys[hotkey as keyof typeof hotKeys];\n\t\t\t\t\t\t\t\t\ttoggleMark(editor, mark);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{restatesCharacters < 0 && (\n\t\t\t\t\t\t<div className=\"restatesCharacters\">{restatesCharacters}</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<input type=\"hidden\" name={name} value={inputValue} />\n\n\t\t\t\t<input type=\"hidden\" name={`${name}Count`} value={charactersCount} />\n\t\t\t</Slate>\n\t\t</FieldTemplate>\n\t);\n}\n\nexport { RichText };\n"],"mappings":"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"}
|
|
@@ -1,40 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useFlipPosition as e } from "../../../hooks/useFlipPosition.js";
|
|
2
|
+
import { useScrollLock as t } from "../../../hooks/useScrollLock.js";
|
|
3
|
+
import { Input as n } from "../../input/index.js";
|
|
3
4
|
/* empty css */
|
|
4
|
-
import {
|
|
5
|
-
import { jsx as
|
|
6
|
-
import { Search as
|
|
5
|
+
import { useRef as r } from "react";
|
|
6
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
7
|
+
import { Search as o } from "lucide-react";
|
|
7
8
|
//#region src/components/select/selectOptionsContainer/index.tsx
|
|
8
|
-
function
|
|
9
|
-
let { children:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
let e = h.current.parentElement;
|
|
14
|
-
if (!e) return;
|
|
15
|
-
let t = e.getBoundingClientRect();
|
|
16
|
-
window.innerHeight - t.bottom < 300 && t.top > 300 ? _("top") : _("bottom");
|
|
17
|
-
})();
|
|
18
|
-
}, [d]);
|
|
19
|
-
function v(e) {
|
|
20
|
-
f && m(e.target.value);
|
|
9
|
+
function s(s) {
|
|
10
|
+
let { children: c, id: l, isFocused: u, isSearchable: d, search: f, onSearch: p } = s, m = r(null), h = e(m, u, 300);
|
|
11
|
+
t(u);
|
|
12
|
+
function g(e) {
|
|
13
|
+
d && p(e.target.value);
|
|
21
14
|
}
|
|
22
|
-
return
|
|
23
|
-
ref:
|
|
24
|
-
id:
|
|
15
|
+
return u ? /* @__PURE__ */ a("div", {
|
|
16
|
+
ref: m,
|
|
17
|
+
id: l,
|
|
25
18
|
role: "listbox",
|
|
26
|
-
className: `arkynSelectOptionsContainer ${
|
|
27
|
-
children: [
|
|
19
|
+
className: `arkynSelectOptionsContainer ${h}`,
|
|
20
|
+
children: [d && /* @__PURE__ */ i(n, {
|
|
28
21
|
type: "search",
|
|
29
22
|
name: "search-select",
|
|
30
23
|
variant: "underline",
|
|
31
|
-
leftIcon:
|
|
32
|
-
value:
|
|
33
|
-
onChange:
|
|
34
|
-
}),
|
|
24
|
+
leftIcon: o,
|
|
25
|
+
value: f,
|
|
26
|
+
onChange: g
|
|
27
|
+
}), c]
|
|
35
28
|
}) : null;
|
|
36
29
|
}
|
|
37
30
|
//#endregion
|
|
38
|
-
export {
|
|
31
|
+
export { s as SelectOptionsContainer };
|
|
39
32
|
|
|
40
33
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/components/select/selectOptionsContainer/index.tsx"],"sourcesContent":["import { Search } from \"lucide-react\";\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/components/select/selectOptionsContainer/index.tsx"],"sourcesContent":["import { Search } from \"lucide-react\";\nimport { type ChangeEvent, type ReactNode, useRef } from \"react\";\n\nimport { useFlipPosition } from \"../../../hooks/useFlipPosition\";\nimport { useScrollLock } from \"../../../hooks/useScrollLock\";\nimport { Input } from \"../../input\";\n\nimport \"./styles.css\";\n\ntype SelectOptionsContainerProps = {\n\tid?: string;\n\tisFocused: boolean;\n\tisSearchable: boolean;\n\tchildren: ReactNode;\n\tsearch: string;\n\tonSearch: (value: string) => void;\n};\n\nfunction SelectOptionsContainer(props: SelectOptionsContainerProps) {\n\tconst { children, id, isFocused, isSearchable, search, onSearch } = props;\n\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\tconst position = useFlipPosition(containerRef, isFocused, 300);\n\n\tuseScrollLock(isFocused);\n\n\tfunction handleSearch(e: ChangeEvent<HTMLInputElement>) {\n\t\tif (!isSearchable) return;\n\t\tonSearch(e.target.value);\n\t}\n\n\tif (!isFocused) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tid={id}\n\t\t\trole=\"listbox\"\n\t\t\tclassName={`arkynSelectOptionsContainer ${position}`}\n\t\t>\n\t\t\t{isSearchable && (\n\t\t\t\t<Input\n\t\t\t\t\ttype=\"search\"\n\t\t\t\t\tname=\"search-select\"\n\t\t\t\t\tvariant=\"underline\"\n\t\t\t\t\tleftIcon={Search}\n\t\t\t\t\tvalue={search}\n\t\t\t\t\tonChange={handleSearch}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n\nexport { SelectOptionsContainer };\n"],"mappings":";;;;;;;;AAkBA,SAAS,EAAuB,GAAoC;CACnE,IAAM,EAAE,aAAU,OAAI,cAAW,iBAAc,WAAQ,gBAAa,GAE9D,IAAe,EAAuB,IAAI,GAC1C,IAAW,EAAgB,GAAc,GAAW,GAAG;CAE7D,EAAc,CAAS;CAEvB,SAAS,EAAa,GAAkC;EAClD,KACL,EAAS,EAAE,OAAO,KAAK;CACxB;CAIA,OAFK,IAGJ,kBAAC,OAAD;EACC,KAAK;EACD;EACJ,MAAK;EACL,WAAW,+BAA+B;YAJ3C,CAME,KACA,kBAAC,GAAD;GACC,MAAK;GACL,MAAK;GACL,SAAQ;GACR,UAAU;GACV,OAAO;GACP,UAAU;EACV,CAAA,GAGD,CACG;MArBiB;AAuBxB"}
|
|
@@ -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,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
|