@yurikilian/lex4 0.3.2 → 1.0.1
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/README.md +71 -4
- package/dist/components/EditorSidebar.d.ts.map +1 -1
- package/dist/components/HeaderFooterActions.d.ts.map +1 -1
- package/dist/components/HeaderFooterToggle.d.ts.map +1 -1
- package/dist/components/HistorySidebar.d.ts.map +1 -1
- package/dist/components/Lex4Editor.d.ts.map +1 -1
- package/dist/components/PageBody.d.ts.map +1 -1
- package/dist/components/Toolbar.d.ts.map +1 -1
- package/dist/components/VariablePanel.d.ts.map +1 -1
- package/dist/components/VariablePicker.d.ts.map +1 -1
- package/dist/extensions/ast-extension.d.ts +9 -0
- package/dist/extensions/ast-extension.d.ts.map +1 -1
- package/dist/extensions/extension-context.d.ts +3 -1
- package/dist/extensions/extension-context.d.ts.map +1 -1
- package/dist/extensions/types.d.ts +12 -0
- package/dist/extensions/types.d.ts.map +1 -1
- package/dist/extensions/variables-extension.d.ts +6 -0
- package/dist/extensions/variables-extension.d.ts.map +1 -1
- package/dist/lex4-editor.cjs +390 -383
- package/dist/lex4-editor.cjs.map +1 -1
- package/dist/lex4-editor.js +390 -383
- package/dist/lex4-editor.js.map +1 -1
- package/dist/lexical/theme.d.ts +1 -1
- package/dist/style.css +789 -695
- package/dist/types/editor-handle.d.ts +12 -7
- package/dist/types/editor-handle.d.ts.map +1 -1
- package/dist/types/editor-props.d.ts +2 -1
- package/dist/types/editor-props.d.ts.map +1 -1
- package/dist/variables/variable-node.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/lex4-editor.js
CHANGED
|
@@ -1740,21 +1740,21 @@ const EditorSidebar = ({
|
|
|
1740
1740
|
return /* @__PURE__ */ jsxs(
|
|
1741
1741
|
"aside",
|
|
1742
1742
|
{
|
|
1743
|
-
className: "
|
|
1743
|
+
className: "lex4-sidebar",
|
|
1744
1744
|
"data-testid": testId,
|
|
1745
1745
|
children: [
|
|
1746
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
1746
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-sidebar-header", children: [
|
|
1747
1747
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1748
|
-
/* @__PURE__ */ jsx("h2", { className: "
|
|
1749
|
-
subtitle && /* @__PURE__ */ jsx("p", { className: "
|
|
1748
|
+
/* @__PURE__ */ jsx("h2", { className: "lex4-sidebar-title", children: title }),
|
|
1749
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "lex4-sidebar-subtitle", children: subtitle })
|
|
1750
1750
|
] }),
|
|
1751
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
1751
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-sidebar-actions", children: [
|
|
1752
1752
|
headerActions,
|
|
1753
1753
|
onClose && /* @__PURE__ */ jsx(
|
|
1754
1754
|
"button",
|
|
1755
1755
|
{
|
|
1756
1756
|
type: "button",
|
|
1757
|
-
className: "
|
|
1757
|
+
className: "lex4-sidebar-action-btn",
|
|
1758
1758
|
"data-testid": "close-editor-sidebar",
|
|
1759
1759
|
onClick: onClose,
|
|
1760
1760
|
"aria-label": t.sidebar.close,
|
|
@@ -1763,7 +1763,7 @@ const EditorSidebar = ({
|
|
|
1763
1763
|
)
|
|
1764
1764
|
] })
|
|
1765
1765
|
] }),
|
|
1766
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
1766
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-sidebar-body", children })
|
|
1767
1767
|
]
|
|
1768
1768
|
}
|
|
1769
1769
|
);
|
|
@@ -1795,7 +1795,7 @@ const HistorySidebar = () => {
|
|
|
1795
1795
|
"aria-label": t.history.clearHistory,
|
|
1796
1796
|
onMouseDown: (e) => e.preventDefault(),
|
|
1797
1797
|
onClick: () => clearHistory("manual"),
|
|
1798
|
-
className: "
|
|
1798
|
+
className: "lex4-sidebar-action-btn",
|
|
1799
1799
|
"data-testid": "clear-history",
|
|
1800
1800
|
children: /* @__PURE__ */ jsx(Trash2, { size: 13 })
|
|
1801
1801
|
}
|
|
@@ -1812,27 +1812,27 @@ const HistorySidebar = () => {
|
|
|
1812
1812
|
children: visibleEntries.length === 0 ? /* @__PURE__ */ jsx(
|
|
1813
1813
|
"div",
|
|
1814
1814
|
{
|
|
1815
|
-
className: "
|
|
1815
|
+
className: "lex4-history-empty",
|
|
1816
1816
|
"data-testid": "history-empty",
|
|
1817
1817
|
children: t.history.empty
|
|
1818
1818
|
}
|
|
1819
|
-
) : /* @__PURE__ */ jsx("ol", { className: "
|
|
1819
|
+
) : /* @__PURE__ */ jsx("ol", { className: "lex4-history-list", "data-testid": "history-entry-list", children: visibleEntries.map((entry, reversedIndex) => {
|
|
1820
1820
|
const actualIndex = historyEntries.length - reversedIndex - 1;
|
|
1821
1821
|
const isCurrent = actualIndex === historyCursor - 1;
|
|
1822
1822
|
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
1823
1823
|
"button",
|
|
1824
1824
|
{
|
|
1825
1825
|
type: "button",
|
|
1826
|
-
className: `
|
|
1826
|
+
className: `lex4-history-entry ${isCurrent ? "active" : ""}`,
|
|
1827
1827
|
"data-testid": `history-entry-${actualIndex}`,
|
|
1828
1828
|
"data-history-current": isCurrent ? "true" : "false",
|
|
1829
1829
|
onClick: () => jumpToHistoryEntry2(actualIndex),
|
|
1830
|
-
children: /* @__PURE__ */ jsxs("div", { className: "
|
|
1831
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
1832
|
-
/* @__PURE__ */ jsx("div", { className: `
|
|
1833
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
1830
|
+
children: /* @__PURE__ */ jsxs("div", { className: "lex4-history-entry-row", children: [
|
|
1831
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-history-entry-content", children: [
|
|
1832
|
+
/* @__PURE__ */ jsx("div", { className: `lex4-history-entry-label${isCurrent ? " current" : ""}`, children: entry.label }),
|
|
1833
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-history-entry-source", children: t.regions[entry.source] ?? entry.source })
|
|
1834
1834
|
] }),
|
|
1835
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
1835
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-history-entry-time", children: formatTimestamp(entry.timestamp) })
|
|
1836
1836
|
] })
|
|
1837
1837
|
}
|
|
1838
1838
|
) }, entry.id);
|
|
@@ -1848,11 +1848,11 @@ const HeaderFooterToggle = ({
|
|
|
1848
1848
|
return /* @__PURE__ */ jsxs(
|
|
1849
1849
|
"label",
|
|
1850
1850
|
{
|
|
1851
|
-
className: "
|
|
1851
|
+
className: "lex4-hf-toggle",
|
|
1852
1852
|
"data-testid": "header-footer-toggle",
|
|
1853
1853
|
children: [
|
|
1854
|
-
/* @__PURE__ */ jsx(Rows3, { size: 14, className: "
|
|
1855
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
1854
|
+
/* @__PURE__ */ jsx(Rows3, { size: 14, className: "lex4-hf-toggle-icon" }),
|
|
1855
|
+
/* @__PURE__ */ jsx("span", { className: "lex4-hf-toggle-label", children: t.headerFooter.label }),
|
|
1856
1856
|
/* @__PURE__ */ jsx(
|
|
1857
1857
|
"button",
|
|
1858
1858
|
{
|
|
@@ -1861,22 +1861,10 @@ const HeaderFooterToggle = ({
|
|
|
1861
1861
|
"aria-checked": enabled,
|
|
1862
1862
|
onMouseDown: (e) => e.preventDefault(),
|
|
1863
1863
|
onClick: () => onToggle(!enabled),
|
|
1864
|
-
className:
|
|
1865
|
-
|
|
1866
|
-
transition-colors duration-200
|
|
1867
|
-
${enabled ? "bg-blue-500" : "bg-gray-300"}
|
|
1868
|
-
`,
|
|
1864
|
+
className: "lex4-hf-switch",
|
|
1865
|
+
style: { backgroundColor: enabled ? "var(--lex4-color-primary)" : "var(--lex4-color-text-disabled)" },
|
|
1869
1866
|
"data-testid": "header-footer-switch",
|
|
1870
|
-
children: /* @__PURE__ */ jsx(
|
|
1871
|
-
"span",
|
|
1872
|
-
{
|
|
1873
|
-
className: `
|
|
1874
|
-
inline-block h-3 w-3 rounded-full bg-white shadow-sm
|
|
1875
|
-
transition-transform duration-200
|
|
1876
|
-
${enabled ? "translate-x-3.5" : "translate-x-0.5"}
|
|
1877
|
-
`
|
|
1878
|
-
}
|
|
1879
|
-
)
|
|
1867
|
+
children: /* @__PURE__ */ jsx("span", { className: "lex4-hf-switch-knob" })
|
|
1880
1868
|
}
|
|
1881
1869
|
)
|
|
1882
1870
|
]
|
|
@@ -1918,17 +1906,14 @@ const HeaderFooterActions = ({
|
|
|
1918
1906
|
action();
|
|
1919
1907
|
close();
|
|
1920
1908
|
};
|
|
1921
|
-
return /* @__PURE__ */ jsxs("div", { ref: containerRef,
|
|
1909
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, style: { position: "relative" }, "data-testid": "header-footer-actions", children: [
|
|
1922
1910
|
/* @__PURE__ */ jsxs(
|
|
1923
1911
|
"button",
|
|
1924
1912
|
{
|
|
1925
1913
|
type: "button",
|
|
1926
1914
|
onMouseDown: (e) => e.preventDefault(),
|
|
1927
1915
|
onClick: () => setOpen(!open),
|
|
1928
|
-
className:
|
|
1929
|
-
flex h-7 items-center gap-1 rounded px-1.5 text-xs transition-colors
|
|
1930
|
-
${open ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-100 hover:text-gray-900"}
|
|
1931
|
-
`,
|
|
1916
|
+
className: "lex4-settings-trigger",
|
|
1932
1917
|
"data-testid": "header-footer-menu-trigger",
|
|
1933
1918
|
"aria-expanded": open,
|
|
1934
1919
|
"aria-haspopup": "true",
|
|
@@ -1941,12 +1926,12 @@ const HeaderFooterActions = ({
|
|
|
1941
1926
|
open && /* @__PURE__ */ jsxs(
|
|
1942
1927
|
"div",
|
|
1943
1928
|
{
|
|
1944
|
-
className: "
|
|
1929
|
+
className: "lex4-settings-menu",
|
|
1945
1930
|
role: "menu",
|
|
1946
1931
|
"data-testid": "header-footer-menu",
|
|
1947
1932
|
children: [
|
|
1948
1933
|
/* @__PURE__ */ jsx(SectionLabel, { children: "Page counter" }),
|
|
1949
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
1934
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-settings-counter-grid", "data-testid": "page-counter-mode", children: PAGE_COUNTER_OPTIONS.map(({ value, label }) => /* @__PURE__ */ jsx(
|
|
1950
1935
|
"button",
|
|
1951
1936
|
{
|
|
1952
1937
|
type: "button",
|
|
@@ -1954,10 +1939,7 @@ const HeaderFooterActions = ({
|
|
|
1954
1939
|
"aria-checked": pageCounterMode === value,
|
|
1955
1940
|
onMouseDown: (e) => e.preventDefault(),
|
|
1956
1941
|
onClick: () => onPageCounterModeChange(value),
|
|
1957
|
-
className:
|
|
1958
|
-
rounded px-2 py-1 text-xs text-left transition-colors
|
|
1959
|
-
${pageCounterMode === value ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-600 hover:bg-gray-100"}
|
|
1960
|
-
`,
|
|
1942
|
+
className: "lex4-settings-counter-btn",
|
|
1961
1943
|
"data-testid": `page-counter-${value}`,
|
|
1962
1944
|
children: label
|
|
1963
1945
|
},
|
|
@@ -2030,7 +2012,7 @@ const HeaderFooterActions = ({
|
|
|
2030
2012
|
)
|
|
2031
2013
|
] });
|
|
2032
2014
|
};
|
|
2033
|
-
const SectionLabel = ({ children }) => /* @__PURE__ */ jsx("div", { className: "
|
|
2015
|
+
const SectionLabel = ({ children }) => /* @__PURE__ */ jsx("div", { className: "lex4-settings-label", children });
|
|
2034
2016
|
const MenuItem = ({ icon, label, onClick, disabled, testId }) => /* @__PURE__ */ jsxs(
|
|
2035
2017
|
"button",
|
|
2036
2018
|
{
|
|
@@ -2039,7 +2021,7 @@ const MenuItem = ({ icon, label, onClick, disabled, testId }) => /* @__PURE__ */
|
|
|
2039
2021
|
onMouseDown: (e) => e.preventDefault(),
|
|
2040
2022
|
onClick,
|
|
2041
2023
|
disabled,
|
|
2042
|
-
className: "
|
|
2024
|
+
className: "lex4-settings-item",
|
|
2043
2025
|
"data-testid": testId,
|
|
2044
2026
|
children: [
|
|
2045
2027
|
icon,
|
|
@@ -2047,7 +2029,7 @@ const MenuItem = ({ icon, label, onClick, disabled, testId }) => /* @__PURE__ */
|
|
|
2047
2029
|
]
|
|
2048
2030
|
}
|
|
2049
2031
|
);
|
|
2050
|
-
const MenuDivider = () => /* @__PURE__ */ jsx("div", { className: "
|
|
2032
|
+
const MenuDivider = () => /* @__PURE__ */ jsx("div", { className: "lex4-settings-divider" });
|
|
2051
2033
|
function resolveExtensions(extensions) {
|
|
2052
2034
|
const resolved = {
|
|
2053
2035
|
nodes: [],
|
|
@@ -2056,6 +2038,8 @@ function resolveExtensions(extensions) {
|
|
|
2056
2038
|
sidePanels: [],
|
|
2057
2039
|
providers: [],
|
|
2058
2040
|
themeOverrides: {},
|
|
2041
|
+
cssVariables: {},
|
|
2042
|
+
rootClassNames: [],
|
|
2059
2043
|
handleFactories: []
|
|
2060
2044
|
};
|
|
2061
2045
|
for (const ext of extensions) {
|
|
@@ -2067,6 +2051,10 @@ function resolveExtensions(extensions) {
|
|
|
2067
2051
|
if (ext.themeOverrides) {
|
|
2068
2052
|
resolved.themeOverrides = { ...resolved.themeOverrides, ...ext.themeOverrides };
|
|
2069
2053
|
}
|
|
2054
|
+
if (ext.cssVariables) {
|
|
2055
|
+
Object.assign(resolved.cssVariables, ext.cssVariables);
|
|
2056
|
+
}
|
|
2057
|
+
if (ext.rootClassName) resolved.rootClassNames.push(ext.rootClassName);
|
|
2070
2058
|
if (ext.handleMethods) resolved.handleFactories.push(ext.handleMethods);
|
|
2071
2059
|
}
|
|
2072
2060
|
return resolved;
|
|
@@ -2078,14 +2066,27 @@ const EMPTY_RESOLVED = {
|
|
|
2078
2066
|
sidePanels: [],
|
|
2079
2067
|
providers: [],
|
|
2080
2068
|
themeOverrides: {},
|
|
2069
|
+
cssVariables: {},
|
|
2070
|
+
rootClassNames: [],
|
|
2081
2071
|
handleFactories: []
|
|
2082
2072
|
};
|
|
2083
2073
|
const ExtensionResolvedContext = createContext(EMPTY_RESOLVED);
|
|
2074
|
+
function arraysEqual(a, b) {
|
|
2075
|
+
if (a.length !== b.length) return false;
|
|
2076
|
+
for (let i = 0; i < a.length; i++) {
|
|
2077
|
+
if (a[i] !== b[i]) return false;
|
|
2078
|
+
}
|
|
2079
|
+
return true;
|
|
2080
|
+
}
|
|
2084
2081
|
const ExtensionProvider = ({ extensions, children }) => {
|
|
2085
|
-
const
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
)
|
|
2082
|
+
const prevNamesRef = useRef([]);
|
|
2083
|
+
const resolvedRef = useRef(EMPTY_RESOLVED);
|
|
2084
|
+
const currentNames = (extensions ?? []).map((e) => e.name);
|
|
2085
|
+
if (!arraysEqual(currentNames, prevNamesRef.current)) {
|
|
2086
|
+
resolvedRef.current = extensions && extensions.length > 0 ? resolveExtensions(extensions) : EMPTY_RESOLVED;
|
|
2087
|
+
prevNamesRef.current = currentNames;
|
|
2088
|
+
}
|
|
2089
|
+
const resolved = resolvedRef.current;
|
|
2089
2090
|
let wrapped = /* @__PURE__ */ jsx(Fragment, { children });
|
|
2090
2091
|
for (let i = resolved.providers.length - 1; i >= 0; i--) {
|
|
2091
2092
|
const Provider = resolved.providers[i];
|
|
@@ -2392,11 +2393,11 @@ const Toolbar = () => {
|
|
|
2392
2393
|
return /* @__PURE__ */ jsxs(
|
|
2393
2394
|
"div",
|
|
2394
2395
|
{
|
|
2395
|
-
className: "lex4-toolbar
|
|
2396
|
+
className: "lex4-toolbar",
|
|
2396
2397
|
"data-testid": "toolbar",
|
|
2397
2398
|
children: [
|
|
2398
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2399
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2399
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-row", children: [
|
|
2400
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "history-controls", children: [
|
|
2400
2401
|
/* @__PURE__ */ jsx(
|
|
2401
2402
|
ToolbarIconButton,
|
|
2402
2403
|
{
|
|
@@ -2419,12 +2420,12 @@ const Toolbar = () => {
|
|
|
2419
2420
|
)
|
|
2420
2421
|
] }),
|
|
2421
2422
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
2422
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2423
|
-
/* @__PURE__ */ jsx(Type, { size: 14, className: "
|
|
2423
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group-gap", children: [
|
|
2424
|
+
/* @__PURE__ */ jsx(Type, { size: 14, className: "lex4-toolbar-icon" }),
|
|
2424
2425
|
/* @__PURE__ */ jsx(
|
|
2425
2426
|
"select",
|
|
2426
2427
|
{
|
|
2427
|
-
className: "
|
|
2428
|
+
className: "lex4-toolbar-select",
|
|
2428
2429
|
"data-testid": "font-selector",
|
|
2429
2430
|
defaultValue: "Calibri",
|
|
2430
2431
|
onChange: handleFontChange,
|
|
@@ -2432,12 +2433,12 @@ const Toolbar = () => {
|
|
|
2432
2433
|
}
|
|
2433
2434
|
)
|
|
2434
2435
|
] }),
|
|
2435
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2436
|
-
/* @__PURE__ */ jsx(ALargeSmall, { size: 14, className: "
|
|
2436
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group-gap", children: [
|
|
2437
|
+
/* @__PURE__ */ jsx(ALargeSmall, { size: 14, className: "lex4-toolbar-icon" }),
|
|
2437
2438
|
/* @__PURE__ */ jsx(
|
|
2438
2439
|
"select",
|
|
2439
2440
|
{
|
|
2440
|
-
className: "
|
|
2441
|
+
className: "lex4-toolbar-select lex4-toolbar-select-narrow",
|
|
2441
2442
|
"data-testid": "font-size-selector",
|
|
2442
2443
|
defaultValue: "12",
|
|
2443
2444
|
onChange: handleFontSizeChange,
|
|
@@ -2446,21 +2447,21 @@ const Toolbar = () => {
|
|
|
2446
2447
|
)
|
|
2447
2448
|
] }),
|
|
2448
2449
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
2449
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2450
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "format-group", children: [
|
|
2450
2451
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.bold, testId: "btn-bold", onClick: handleBold, children: /* @__PURE__ */ jsx(Bold, { size: 15 }) }),
|
|
2451
2452
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.italic, testId: "btn-italic", onClick: handleItalic, children: /* @__PURE__ */ jsx(Italic, { size: 15 }) }),
|
|
2452
2453
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.underline, testId: "btn-underline", onClick: handleUnderline, children: /* @__PURE__ */ jsx(Underline, { size: 15 }) }),
|
|
2453
2454
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.strikethrough, testId: "btn-strike", onClick: handleStrikethrough, children: /* @__PURE__ */ jsx(Strikethrough, { size: 15 }) })
|
|
2454
2455
|
] }),
|
|
2455
2456
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
2456
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2457
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "align-group", children: [
|
|
2457
2458
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignLeft, testId: "btn-align-left", onClick: handleAlignLeft, children: /* @__PURE__ */ jsx(TextAlignStart, { size: 15 }) }),
|
|
2458
2459
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignCenter, testId: "btn-align-center", onClick: handleAlignCenter, children: /* @__PURE__ */ jsx(TextAlignCenter, { size: 15 }) }),
|
|
2459
2460
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.alignRight, testId: "btn-align-right", onClick: handleAlignRight, children: /* @__PURE__ */ jsx(TextAlignEnd, { size: 15 }) }),
|
|
2460
2461
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.justify, testId: "btn-align-justify", onClick: handleAlignJustify, children: /* @__PURE__ */ jsx(TextAlignJustify, { size: 15 }) })
|
|
2461
2462
|
] }),
|
|
2462
2463
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
2463
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2464
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-toolbar-group", "data-testid": "list-group", children: [
|
|
2464
2465
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.numberedList, testId: "btn-list-number", onClick: handleListNumber, children: /* @__PURE__ */ jsx(ListOrdered, { size: 15 }) }),
|
|
2465
2466
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.bulletList, testId: "btn-list-bullet", onClick: handleListBullet, children: /* @__PURE__ */ jsx(List, { size: 15 }) }),
|
|
2466
2467
|
/* @__PURE__ */ jsx(ToolbarIconButton, { title: t.toolbar.indent, testId: "btn-indent", onClick: handleIndent, children: /* @__PURE__ */ jsx(ListIndentIncrease, { size: 15 }) }),
|
|
@@ -2470,7 +2471,7 @@ const Toolbar = () => {
|
|
|
2470
2471
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
2471
2472
|
toolbarItems.map((ToolbarItem, idx) => /* @__PURE__ */ jsx(ToolbarItem, {}, idx))
|
|
2472
2473
|
] }),
|
|
2473
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
2474
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-toolbar-end", children: /* @__PURE__ */ jsx(
|
|
2474
2475
|
ToolbarIconButton,
|
|
2475
2476
|
{
|
|
2476
2477
|
title: historySidebarOpen ? t.toolbar.closeHistory : t.toolbar.openHistory,
|
|
@@ -2481,7 +2482,7 @@ const Toolbar = () => {
|
|
|
2481
2482
|
}
|
|
2482
2483
|
) })
|
|
2483
2484
|
] }),
|
|
2484
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
2485
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-hf-row", children: [
|
|
2485
2486
|
/* @__PURE__ */ jsx(
|
|
2486
2487
|
HeaderFooterToggle,
|
|
2487
2488
|
{
|
|
@@ -2524,15 +2525,12 @@ const ToolbarIconButton = ({
|
|
|
2524
2525
|
disabled,
|
|
2525
2526
|
onMouseDown: (e) => e.preventDefault(),
|
|
2526
2527
|
onClick,
|
|
2527
|
-
className: `
|
|
2528
|
-
flex h-7 w-7 items-center justify-center rounded transition-colors
|
|
2529
|
-
${disabled ? "cursor-not-allowed text-gray-300" : active ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-100 hover:text-gray-900"}
|
|
2530
|
-
`,
|
|
2528
|
+
className: `lex4-toolbar-btn${active ? " active" : ""}`,
|
|
2531
2529
|
"data-testid": testId,
|
|
2532
2530
|
children
|
|
2533
2531
|
}
|
|
2534
2532
|
);
|
|
2535
|
-
const Divider = () => /* @__PURE__ */ jsx("div", { className: "
|
|
2533
|
+
const Divider = () => /* @__PURE__ */ jsx("div", { className: "lex4-toolbar-separator" });
|
|
2536
2534
|
function computeBodyHeight(headerHeight, footerHeight) {
|
|
2537
2535
|
const verticalMargins = PAGE_MARGIN_PX * 2;
|
|
2538
2536
|
return A4_HEIGHT_PX - headerHeight - footerHeight - verticalMargins;
|
|
@@ -2839,33 +2837,33 @@ function usePagination(document2, dispatch) {
|
|
|
2839
2837
|
};
|
|
2840
2838
|
}
|
|
2841
2839
|
const lexicalTheme = {
|
|
2842
|
-
root: "lex4-root
|
|
2843
|
-
paragraph: "lex4-paragraph
|
|
2840
|
+
root: "lex4-root",
|
|
2841
|
+
paragraph: "lex4-paragraph",
|
|
2844
2842
|
heading: {
|
|
2845
|
-
h1: "
|
|
2846
|
-
h2: "
|
|
2847
|
-
h3: "
|
|
2848
|
-
h4: "
|
|
2849
|
-
h5: "
|
|
2843
|
+
h1: "lex4-heading lex4-heading-h1",
|
|
2844
|
+
h2: "lex4-heading lex4-heading-h2",
|
|
2845
|
+
h3: "lex4-heading lex4-heading-h3",
|
|
2846
|
+
h4: "lex4-heading lex4-heading-h4",
|
|
2847
|
+
h5: "lex4-heading lex4-heading-h5"
|
|
2850
2848
|
},
|
|
2851
2849
|
text: {
|
|
2852
|
-
bold: "
|
|
2853
|
-
italic: "italic",
|
|
2854
|
-
underline: "underline",
|
|
2855
|
-
strikethrough: "
|
|
2856
|
-
underlineStrikethrough: "underline
|
|
2850
|
+
bold: "lex4-text-bold",
|
|
2851
|
+
italic: "lex4-text-italic",
|
|
2852
|
+
underline: "lex4-text-underline",
|
|
2853
|
+
strikethrough: "lex4-text-strikethrough",
|
|
2854
|
+
underlineStrikethrough: "lex4-text-underline lex4-text-strikethrough"
|
|
2857
2855
|
},
|
|
2858
2856
|
list: {
|
|
2859
2857
|
nested: {
|
|
2860
|
-
listitem: "
|
|
2858
|
+
listitem: "lex4-listitem-nested"
|
|
2861
2859
|
},
|
|
2862
|
-
ol: "list
|
|
2863
|
-
ul: "list
|
|
2860
|
+
ol: "lex4-list lex4-list-ordered",
|
|
2861
|
+
ul: "lex4-list lex4-list-unordered",
|
|
2864
2862
|
listitem: "lex4-listitem",
|
|
2865
2863
|
listitemChecked: "lex4-listitem-checked",
|
|
2866
2864
|
listitemUnchecked: "lex4-listitem-unchecked"
|
|
2867
2865
|
},
|
|
2868
|
-
quote: "
|
|
2866
|
+
quote: "lex4-quote"
|
|
2869
2867
|
};
|
|
2870
2868
|
const DEFAULT_NODES = [HeadingNode, QuoteNode, ListNode, ListItemNode];
|
|
2871
2869
|
function createEditorConfig(mode, pageId, extraNodes = [], themeOverrides = {}) {
|
|
@@ -3756,8 +3754,7 @@ const PageBody = ({
|
|
|
3756
3754
|
return /* @__PURE__ */ jsx(
|
|
3757
3755
|
"div",
|
|
3758
3756
|
{
|
|
3759
|
-
className: "lex4-page-body
|
|
3760
|
-
style: { overflow: "hidden" },
|
|
3757
|
+
className: "lex4-page-body",
|
|
3761
3758
|
"data-testid": `page-body-${pageId}`,
|
|
3762
3759
|
onFocus,
|
|
3763
3760
|
children: /* @__PURE__ */ jsxs(LexicalComposer, { initialConfig: config, children: [
|
|
@@ -3767,11 +3764,10 @@ const PageBody = ({
|
|
|
3767
3764
|
contentEditable: /* @__PURE__ */ jsx(
|
|
3768
3765
|
ContentEditable,
|
|
3769
3766
|
{
|
|
3770
|
-
className: "
|
|
3771
|
-
style: { overflow: "visible" }
|
|
3767
|
+
className: "lex4-page-body-editable"
|
|
3772
3768
|
}
|
|
3773
3769
|
),
|
|
3774
|
-
placeholder: /* @__PURE__ */ jsx("div", { className: "
|
|
3770
|
+
placeholder: /* @__PURE__ */ jsx("div", { className: "lex4-page-placeholder", children: t.body.placeholder }),
|
|
3775
3771
|
ErrorBoundary: LexicalErrorBoundary
|
|
3776
3772
|
}
|
|
3777
3773
|
),
|
|
@@ -3899,7 +3895,7 @@ const PageHeader = ({
|
|
|
3899
3895
|
return /* @__PURE__ */ jsxs(
|
|
3900
3896
|
"div",
|
|
3901
3897
|
{
|
|
3902
|
-
className: "lex4-page-header
|
|
3898
|
+
className: "lex4-page-header",
|
|
3903
3899
|
style: { maxHeight: MAX_HEADER_HEIGHT_PX, overflow: "clip" },
|
|
3904
3900
|
"data-testid": `page-header-${pageId}`,
|
|
3905
3901
|
children: [
|
|
@@ -3911,10 +3907,10 @@ const PageHeader = ({
|
|
|
3911
3907
|
ContentEditable,
|
|
3912
3908
|
{
|
|
3913
3909
|
ref: contentRef,
|
|
3914
|
-
className: `
|
|
3910
|
+
className: `lex4-page-hf-editable${hasPageCounter ? " lex4-page-hf-narrow" : ""}`
|
|
3915
3911
|
}
|
|
3916
3912
|
),
|
|
3917
|
-
placeholder: /* @__PURE__ */ jsx("div", { className: `
|
|
3913
|
+
placeholder: /* @__PURE__ */ jsx("div", { className: `lex4-page-hf-placeholder${hasPageCounter ? " lex4-page-hf-narrow" : ""}`, children: t.header.placeholder }),
|
|
3918
3914
|
ErrorBoundary: LexicalErrorBoundary
|
|
3919
3915
|
}
|
|
3920
3916
|
),
|
|
@@ -3926,7 +3922,7 @@ const PageHeader = ({
|
|
|
3926
3922
|
pageCounterLabel && /* @__PURE__ */ jsx(
|
|
3927
3923
|
"div",
|
|
3928
3924
|
{
|
|
3929
|
-
className: "
|
|
3925
|
+
className: "lex4-page-counter",
|
|
3930
3926
|
"data-testid": `page-counter-header-${pageId}`,
|
|
3931
3927
|
children: pageCounterLabel
|
|
3932
3928
|
}
|
|
@@ -3979,7 +3975,7 @@ const PageFooter = ({
|
|
|
3979
3975
|
return /* @__PURE__ */ jsxs(
|
|
3980
3976
|
"div",
|
|
3981
3977
|
{
|
|
3982
|
-
className: "lex4-page-footer
|
|
3978
|
+
className: "lex4-page-footer",
|
|
3983
3979
|
style: { maxHeight: MAX_FOOTER_HEIGHT_PX, overflow: "clip" },
|
|
3984
3980
|
"data-testid": `page-footer-${pageId}`,
|
|
3985
3981
|
children: [
|
|
@@ -3991,10 +3987,10 @@ const PageFooter = ({
|
|
|
3991
3987
|
ContentEditable,
|
|
3992
3988
|
{
|
|
3993
3989
|
ref: contentRef,
|
|
3994
|
-
className: `
|
|
3990
|
+
className: `lex4-page-hf-editable${hasPageCounter ? " lex4-page-hf-narrow" : ""}`
|
|
3995
3991
|
}
|
|
3996
3992
|
),
|
|
3997
|
-
placeholder: /* @__PURE__ */ jsx("div", { className: `
|
|
3993
|
+
placeholder: /* @__PURE__ */ jsx("div", { className: `lex4-page-hf-placeholder${hasPageCounter ? " lex4-page-hf-narrow" : ""}`, children: t.footer.placeholder }),
|
|
3998
3994
|
ErrorBoundary: LexicalErrorBoundary
|
|
3999
3995
|
}
|
|
4000
3996
|
),
|
|
@@ -4006,7 +4002,7 @@ const PageFooter = ({
|
|
|
4006
4002
|
pageCounterLabel && /* @__PURE__ */ jsx(
|
|
4007
4003
|
"div",
|
|
4008
4004
|
{
|
|
4009
|
-
className: "
|
|
4005
|
+
className: "lex4-page-counter",
|
|
4010
4006
|
"data-testid": `page-counter-footer-${pageId}`,
|
|
4011
4007
|
children: pageCounterLabel
|
|
4012
4008
|
}
|
|
@@ -4064,7 +4060,7 @@ const PageView = React.memo(({
|
|
|
4064
4060
|
return /* @__PURE__ */ jsxs(
|
|
4065
4061
|
"div",
|
|
4066
4062
|
{
|
|
4067
|
-
className: "lex4-page
|
|
4063
|
+
className: "lex4-page",
|
|
4068
4064
|
style: {
|
|
4069
4065
|
width: A4_WIDTH_PX,
|
|
4070
4066
|
height: A4_HEIGHT_PX,
|
|
@@ -4349,7 +4345,7 @@ const DocumentView = () => {
|
|
|
4349
4345
|
return /* @__PURE__ */ jsx(
|
|
4350
4346
|
"div",
|
|
4351
4347
|
{
|
|
4352
|
-
className: "lex4-document-view
|
|
4348
|
+
className: "lex4-document-view",
|
|
4353
4349
|
"data-testid": "document-view",
|
|
4354
4350
|
tabIndex: -1,
|
|
4355
4351
|
children: document2.pages.map((page, index) => /* @__PURE__ */ jsx(
|
|
@@ -4368,6 +4364,247 @@ const DocumentView = () => {
|
|
|
4368
4364
|
}
|
|
4369
4365
|
);
|
|
4370
4366
|
};
|
|
4367
|
+
const AST_VERSION = "1.0.0";
|
|
4368
|
+
const IS_BOLD = 1;
|
|
4369
|
+
const IS_ITALIC = 2;
|
|
4370
|
+
const IS_STRIKETHROUGH = 4;
|
|
4371
|
+
const IS_UNDERLINE = 8;
|
|
4372
|
+
function decodeFormatBitmask(format) {
|
|
4373
|
+
const marks = {};
|
|
4374
|
+
if (format & IS_BOLD) marks.bold = true;
|
|
4375
|
+
if (format & IS_ITALIC) marks.italic = true;
|
|
4376
|
+
if (format & IS_UNDERLINE) marks.underline = true;
|
|
4377
|
+
if (format & IS_STRIKETHROUGH) marks.strikethrough = true;
|
|
4378
|
+
return marks;
|
|
4379
|
+
}
|
|
4380
|
+
function extractFontFamily(style) {
|
|
4381
|
+
const match = style.match(/font-family:\s*([^;]+)/);
|
|
4382
|
+
return match ? match[1].trim().replace(/['"]/g, "") : void 0;
|
|
4383
|
+
}
|
|
4384
|
+
function extractFontSizePt(style) {
|
|
4385
|
+
const match = style.match(/font-size:\s*(\d+(?:\.\d+)?)\s*pt/);
|
|
4386
|
+
return match ? parseFloat(match[1]) : void 0;
|
|
4387
|
+
}
|
|
4388
|
+
function buildTextMarks(format, style) {
|
|
4389
|
+
const formatMarks = decodeFormatBitmask(format);
|
|
4390
|
+
const fontFamily = style ? extractFontFamily(style) : void 0;
|
|
4391
|
+
const fontSize = style ? extractFontSizePt(style) : void 0;
|
|
4392
|
+
const marks = {
|
|
4393
|
+
...formatMarks,
|
|
4394
|
+
...fontFamily ? { fontFamily } : {},
|
|
4395
|
+
...fontSize ? { fontSize } : {}
|
|
4396
|
+
};
|
|
4397
|
+
return Object.keys(marks).length > 0 ? marks : void 0;
|
|
4398
|
+
}
|
|
4399
|
+
function mapInlineNode(node) {
|
|
4400
|
+
switch (node.type) {
|
|
4401
|
+
case "text":
|
|
4402
|
+
return mapTextNode(node);
|
|
4403
|
+
case "variable-node":
|
|
4404
|
+
return mapVariableNode(node);
|
|
4405
|
+
case "linebreak":
|
|
4406
|
+
return mapLineBreak();
|
|
4407
|
+
default:
|
|
4408
|
+
return { type: "text", text: "" };
|
|
4409
|
+
}
|
|
4410
|
+
}
|
|
4411
|
+
function mapTextNode(node) {
|
|
4412
|
+
const marks = buildTextMarks(node.format, node.style);
|
|
4413
|
+
return {
|
|
4414
|
+
type: "text",
|
|
4415
|
+
text: node.text,
|
|
4416
|
+
...marks ? { marks } : {}
|
|
4417
|
+
};
|
|
4418
|
+
}
|
|
4419
|
+
function mapVariableNode(node) {
|
|
4420
|
+
return {
|
|
4421
|
+
type: "variable",
|
|
4422
|
+
key: node.variableKey
|
|
4423
|
+
};
|
|
4424
|
+
}
|
|
4425
|
+
function mapLineBreak() {
|
|
4426
|
+
return { type: "linebreak" };
|
|
4427
|
+
}
|
|
4428
|
+
function mapInlineNodes(nodes) {
|
|
4429
|
+
return nodes.map(mapInlineNode);
|
|
4430
|
+
}
|
|
4431
|
+
const ALIGN_LEFT = 1;
|
|
4432
|
+
const ALIGN_CENTER = 2;
|
|
4433
|
+
const ALIGN_RIGHT = 3;
|
|
4434
|
+
const ALIGN_JUSTIFY = 4;
|
|
4435
|
+
function decodeAlignment(format) {
|
|
4436
|
+
if (typeof format === "string") {
|
|
4437
|
+
if (["left", "center", "right", "justify"].includes(format)) {
|
|
4438
|
+
return format;
|
|
4439
|
+
}
|
|
4440
|
+
return void 0;
|
|
4441
|
+
}
|
|
4442
|
+
if (typeof format !== "number" || format === 0) return void 0;
|
|
4443
|
+
switch (format) {
|
|
4444
|
+
case ALIGN_LEFT:
|
|
4445
|
+
return "left";
|
|
4446
|
+
case ALIGN_CENTER:
|
|
4447
|
+
return "center";
|
|
4448
|
+
case ALIGN_RIGHT:
|
|
4449
|
+
return "right";
|
|
4450
|
+
case ALIGN_JUSTIFY:
|
|
4451
|
+
return "justify";
|
|
4452
|
+
default:
|
|
4453
|
+
return void 0;
|
|
4454
|
+
}
|
|
4455
|
+
}
|
|
4456
|
+
function mapBlockNode(node) {
|
|
4457
|
+
switch (node.type) {
|
|
4458
|
+
case "paragraph":
|
|
4459
|
+
return mapParagraph(node);
|
|
4460
|
+
case "heading":
|
|
4461
|
+
return mapHeading(node);
|
|
4462
|
+
case "list":
|
|
4463
|
+
return mapList(node);
|
|
4464
|
+
case "quote":
|
|
4465
|
+
return mapBlockQuote(node);
|
|
4466
|
+
default:
|
|
4467
|
+
return {
|
|
4468
|
+
type: "paragraph",
|
|
4469
|
+
children: mapInlineChildren(node)
|
|
4470
|
+
};
|
|
4471
|
+
}
|
|
4472
|
+
}
|
|
4473
|
+
function mapParagraph(node) {
|
|
4474
|
+
const alignment = decodeAlignment(node.format);
|
|
4475
|
+
const indent = node.indent && node.indent > 0 ? node.indent : void 0;
|
|
4476
|
+
return {
|
|
4477
|
+
type: "paragraph",
|
|
4478
|
+
...alignment ? { alignment } : {},
|
|
4479
|
+
...indent ? { indent } : {},
|
|
4480
|
+
children: mapInlineChildren(node)
|
|
4481
|
+
};
|
|
4482
|
+
}
|
|
4483
|
+
function mapHeading(node) {
|
|
4484
|
+
var _a;
|
|
4485
|
+
const alignment = decodeAlignment(node.format);
|
|
4486
|
+
const tagMatch = (_a = node.tag) == null ? void 0 : _a.match(/^h(\d)$/);
|
|
4487
|
+
const level = tagMatch ? parseInt(tagMatch[1], 10) : 1;
|
|
4488
|
+
return {
|
|
4489
|
+
type: "heading",
|
|
4490
|
+
level,
|
|
4491
|
+
...alignment ? { alignment } : {},
|
|
4492
|
+
children: mapInlineChildren(node)
|
|
4493
|
+
};
|
|
4494
|
+
}
|
|
4495
|
+
function mapList(node) {
|
|
4496
|
+
const listType = node.listType === "number" ? "ordered" : "unordered";
|
|
4497
|
+
const items = (node.children ?? []).filter((c) => c.type === "listitem").map(mapListItem);
|
|
4498
|
+
return {
|
|
4499
|
+
type: "list",
|
|
4500
|
+
listType,
|
|
4501
|
+
items
|
|
4502
|
+
};
|
|
4503
|
+
}
|
|
4504
|
+
function mapListItem(node) {
|
|
4505
|
+
const inlineChildren = [];
|
|
4506
|
+
let nestedList;
|
|
4507
|
+
for (const child of node.children ?? []) {
|
|
4508
|
+
if (child.type === "list") {
|
|
4509
|
+
nestedList = mapList(child);
|
|
4510
|
+
} else {
|
|
4511
|
+
const mapped = mapInlineNodes([child]);
|
|
4512
|
+
inlineChildren.push(...mapped);
|
|
4513
|
+
}
|
|
4514
|
+
}
|
|
4515
|
+
return {
|
|
4516
|
+
type: "list-item",
|
|
4517
|
+
children: inlineChildren,
|
|
4518
|
+
...nestedList ? { nestedList } : {}
|
|
4519
|
+
};
|
|
4520
|
+
}
|
|
4521
|
+
function mapBlockQuote(node) {
|
|
4522
|
+
return {
|
|
4523
|
+
type: "blockquote",
|
|
4524
|
+
children: mapInlineChildren(node)
|
|
4525
|
+
};
|
|
4526
|
+
}
|
|
4527
|
+
function mapInlineChildren(node) {
|
|
4528
|
+
if (!node.children || node.children.length === 0) return [];
|
|
4529
|
+
return mapInlineNodes(node.children);
|
|
4530
|
+
}
|
|
4531
|
+
function mapBlockNodes(nodes) {
|
|
4532
|
+
return nodes.map(mapBlockNode);
|
|
4533
|
+
}
|
|
4534
|
+
function mapEditorStateToContent(state) {
|
|
4535
|
+
if (!state || !state.root || !state.root.children) {
|
|
4536
|
+
return null;
|
|
4537
|
+
}
|
|
4538
|
+
const blocks = mapBlockNodes(state.root.children);
|
|
4539
|
+
return { blocks };
|
|
4540
|
+
}
|
|
4541
|
+
function mapEditorStateToBlocks(state) {
|
|
4542
|
+
if (!state || !state.root || !state.root.children) {
|
|
4543
|
+
return [];
|
|
4544
|
+
}
|
|
4545
|
+
return mapBlockNodes(state.root.children);
|
|
4546
|
+
}
|
|
4547
|
+
const MARGIN_MM = Math.round(PAGE_MARGIN_PX / PX_PER_MM * 10) / 10;
|
|
4548
|
+
function serializeDocument(document2, variableDefinitions = []) {
|
|
4549
|
+
const pages = document2.pages.map(
|
|
4550
|
+
(page, index) => serializePage(page, index)
|
|
4551
|
+
);
|
|
4552
|
+
const metadata = buildMetadata(variableDefinitions);
|
|
4553
|
+
return {
|
|
4554
|
+
version: AST_VERSION,
|
|
4555
|
+
page: {
|
|
4556
|
+
format: "A4",
|
|
4557
|
+
widthMm: 210,
|
|
4558
|
+
heightMm: 297,
|
|
4559
|
+
margins: {
|
|
4560
|
+
topMm: MARGIN_MM,
|
|
4561
|
+
rightMm: MARGIN_MM,
|
|
4562
|
+
bottomMm: MARGIN_MM,
|
|
4563
|
+
leftMm: MARGIN_MM
|
|
4564
|
+
}
|
|
4565
|
+
},
|
|
4566
|
+
headerFooter: {
|
|
4567
|
+
enabled: document2.headerFooterEnabled,
|
|
4568
|
+
pageCounterMode: document2.pageCounterMode,
|
|
4569
|
+
defaultHeader: document2.pages.length > 0 ? mapEditorStateToContent(document2.pages[0].headerState) : null,
|
|
4570
|
+
defaultFooter: document2.pages.length > 0 ? mapEditorStateToContent(document2.pages[0].footerState) : null
|
|
4571
|
+
},
|
|
4572
|
+
pages,
|
|
4573
|
+
metadata
|
|
4574
|
+
};
|
|
4575
|
+
}
|
|
4576
|
+
function serializePage(page, pageIndex) {
|
|
4577
|
+
return {
|
|
4578
|
+
pageIndex,
|
|
4579
|
+
body: mapEditorStateToBlocks(page.bodyState),
|
|
4580
|
+
header: mapEditorStateToContent(page.headerState),
|
|
4581
|
+
footer: mapEditorStateToContent(page.footerState)
|
|
4582
|
+
};
|
|
4583
|
+
}
|
|
4584
|
+
function buildMetadata(variableDefinitions) {
|
|
4585
|
+
const variables = {};
|
|
4586
|
+
for (const def of variableDefinitions) {
|
|
4587
|
+
variables[def.key] = {
|
|
4588
|
+
key: def.key,
|
|
4589
|
+
label: def.label,
|
|
4590
|
+
...def.description ? { description: def.description } : {},
|
|
4591
|
+
...def.valueType ? { valueType: def.valueType } : {},
|
|
4592
|
+
...def.group ? { group: def.group } : {}
|
|
4593
|
+
};
|
|
4594
|
+
}
|
|
4595
|
+
return { variables };
|
|
4596
|
+
}
|
|
4597
|
+
function buildSavePayload(ast, options) {
|
|
4598
|
+
return {
|
|
4599
|
+
document: ast,
|
|
4600
|
+
...(options == null ? void 0 : options.exportTarget) ? { exportTarget: options.exportTarget } : {},
|
|
4601
|
+
...(options == null ? void 0 : options.documentId) ? { documentId: options.documentId } : {},
|
|
4602
|
+
...(options == null ? void 0 : options.metadata) ? { metadata: options.metadata } : {}
|
|
4603
|
+
};
|
|
4604
|
+
}
|
|
4605
|
+
function serializeDocumentJson(ast) {
|
|
4606
|
+
return JSON.stringify(ast, null, 2);
|
|
4607
|
+
}
|
|
4371
4608
|
function selectEntireDocument(rootElement, selectionBuffer) {
|
|
4372
4609
|
if (!rootElement || !selectionBuffer) {
|
|
4373
4610
|
return;
|
|
@@ -4391,6 +4628,7 @@ function isFormFieldTarget(target) {
|
|
|
4391
4628
|
}
|
|
4392
4629
|
const EditorChrome = ({
|
|
4393
4630
|
captureHistoryShortcutsOnWindow,
|
|
4631
|
+
onSave,
|
|
4394
4632
|
className
|
|
4395
4633
|
}) => {
|
|
4396
4634
|
const {
|
|
@@ -4401,7 +4639,7 @@ const EditorChrome = ({
|
|
|
4401
4639
|
undo,
|
|
4402
4640
|
redo
|
|
4403
4641
|
} = useDocument();
|
|
4404
|
-
const { sidePanels } = useExtensions();
|
|
4642
|
+
const { sidePanels, cssVariables, rootClassNames } = useExtensions();
|
|
4405
4643
|
const rootRef = useRef(null);
|
|
4406
4644
|
const selectionBufferRef = useRef(null);
|
|
4407
4645
|
const clearGlobalSelection = useCallback(() => {
|
|
@@ -4463,12 +4701,22 @@ const EditorChrome = ({
|
|
|
4463
4701
|
});
|
|
4464
4702
|
return;
|
|
4465
4703
|
}
|
|
4704
|
+
if (key === "s" && onSave) {
|
|
4705
|
+
event.preventDefault();
|
|
4706
|
+
event.stopPropagation();
|
|
4707
|
+
const ast = serializeDocument(document2);
|
|
4708
|
+
const json = serializeDocumentJson(ast);
|
|
4709
|
+
onSave({ document: document2, ast, json });
|
|
4710
|
+
return;
|
|
4711
|
+
}
|
|
4466
4712
|
if (handleHistoryShortcut(event)) {
|
|
4467
4713
|
return;
|
|
4468
4714
|
}
|
|
4469
4715
|
}, [
|
|
4716
|
+
document2,
|
|
4470
4717
|
dispatch,
|
|
4471
4718
|
handleHistoryShortcut,
|
|
4719
|
+
onSave,
|
|
4472
4720
|
setGlobalSelectionActive
|
|
4473
4721
|
]);
|
|
4474
4722
|
const handleMouseDownCapture = useCallback((event) => {
|
|
@@ -4486,9 +4734,13 @@ const EditorChrome = ({
|
|
|
4486
4734
|
const editableRoots = ((_a = rootRef.current) == null ? void 0 : _a.querySelectorAll(
|
|
4487
4735
|
'[data-testid^="page-body-"] [data-lexical-editor="true"]'
|
|
4488
4736
|
)) ?? [];
|
|
4737
|
+
const root = rootRef.current;
|
|
4738
|
+
const styles = root ? getComputedStyle(root) : null;
|
|
4739
|
+
const selBg = (styles == null ? void 0 : styles.getPropertyValue("--lex4-color-selection-bg").trim()) || GLOBAL_SELECTION_BACKGROUND;
|
|
4740
|
+
const selFg = (styles == null ? void 0 : styles.getPropertyValue("--lex4-color-selection-text").trim()) || GLOBAL_SELECTION_FOREGROUND;
|
|
4489
4741
|
editableRoots.forEach((editableRoot) => {
|
|
4490
|
-
editableRoot.style.backgroundColor = globalSelectionActive ?
|
|
4491
|
-
editableRoot.style.color = globalSelectionActive ?
|
|
4742
|
+
editableRoot.style.backgroundColor = globalSelectionActive ? selBg : "";
|
|
4743
|
+
editableRoot.style.color = globalSelectionActive ? selFg : "";
|
|
4492
4744
|
editableRoot.style.caretColor = globalSelectionActive ? "transparent" : "";
|
|
4493
4745
|
});
|
|
4494
4746
|
}, [globalSelectionActive, document2.pages.length]);
|
|
@@ -4521,11 +4773,14 @@ const EditorChrome = ({
|
|
|
4521
4773
|
window.removeEventListener("beforeinput", handleWindowBeforeInput, { capture: true });
|
|
4522
4774
|
};
|
|
4523
4775
|
}, [captureHistoryShortcutsOnWindow, clearGlobalSelection, handleHistoryShortcut, redo, undo]);
|
|
4776
|
+
const rootClassName = ["lex4-editor", ...rootClassNames, className].filter(Boolean).join(" ");
|
|
4777
|
+
const extensionStyle = Object.keys(cssVariables).length > 0 ? cssVariables : void 0;
|
|
4524
4778
|
return /* @__PURE__ */ jsxs(
|
|
4525
4779
|
"div",
|
|
4526
4780
|
{
|
|
4527
4781
|
ref: rootRef,
|
|
4528
|
-
className:
|
|
4782
|
+
className: rootClassName,
|
|
4783
|
+
style: extensionStyle,
|
|
4529
4784
|
"data-testid": "lex4-editor",
|
|
4530
4785
|
"data-global-selection-active": globalSelectionActive ? "true" : "false",
|
|
4531
4786
|
onKeyDownCapture: handleKeyDownCapture,
|
|
@@ -4539,12 +4794,12 @@ const EditorChrome = ({
|
|
|
4539
4794
|
"data-testid": "global-selection-buffer",
|
|
4540
4795
|
readOnly: true,
|
|
4541
4796
|
tabIndex: -1,
|
|
4542
|
-
className: "
|
|
4797
|
+
className: "lex4-selection-buffer"
|
|
4543
4798
|
}
|
|
4544
4799
|
),
|
|
4545
4800
|
/* @__PURE__ */ jsx(Toolbar, {}),
|
|
4546
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
4547
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
4801
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-canvas", children: [
|
|
4802
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-canvas-scroll", children: /* @__PURE__ */ jsx(DocumentView, {}) }),
|
|
4548
4803
|
sidePanels.map((Panel, idx) => /* @__PURE__ */ jsx(Panel, {}, idx)),
|
|
4549
4804
|
/* @__PURE__ */ jsx(HistorySidebar, {})
|
|
4550
4805
|
] })
|
|
@@ -4552,7 +4807,7 @@ const EditorChrome = ({
|
|
|
4552
4807
|
}
|
|
4553
4808
|
);
|
|
4554
4809
|
};
|
|
4555
|
-
const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, className }, ref) => {
|
|
4810
|
+
const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, onSave, className }, ref) => {
|
|
4556
4811
|
const { document: doc, activeEditor } = useDocument();
|
|
4557
4812
|
const { handleFactories } = useExtensions();
|
|
4558
4813
|
const getDocument = useCallback(() => doc, [doc]);
|
|
@@ -4570,6 +4825,7 @@ const EditorWithHandle = forwardRef(({ captureHistoryShortcutsOnWindow, classNam
|
|
|
4570
4825
|
EditorChrome,
|
|
4571
4826
|
{
|
|
4572
4827
|
captureHistoryShortcutsOnWindow,
|
|
4828
|
+
onSave,
|
|
4573
4829
|
className
|
|
4574
4830
|
}
|
|
4575
4831
|
);
|
|
@@ -4579,6 +4835,7 @@ const Lex4Editor = forwardRef(({
|
|
|
4579
4835
|
captureHistoryShortcutsOnWindow = true,
|
|
4580
4836
|
initialDocument,
|
|
4581
4837
|
onDocumentChange,
|
|
4838
|
+
onSave,
|
|
4582
4839
|
extensions,
|
|
4583
4840
|
translations,
|
|
4584
4841
|
className
|
|
@@ -4593,6 +4850,7 @@ const Lex4Editor = forwardRef(({
|
|
|
4593
4850
|
{
|
|
4594
4851
|
ref,
|
|
4595
4852
|
captureHistoryShortcutsOnWindow,
|
|
4853
|
+
onSave,
|
|
4596
4854
|
className
|
|
4597
4855
|
}
|
|
4598
4856
|
)
|
|
@@ -4665,247 +4923,6 @@ function useHeaderFooter(maxHeight, onHeightChange) {
|
|
|
4665
4923
|
}, []);
|
|
4666
4924
|
return { attachRef };
|
|
4667
4925
|
}
|
|
4668
|
-
const AST_VERSION = "1.0.0";
|
|
4669
|
-
const IS_BOLD = 1;
|
|
4670
|
-
const IS_ITALIC = 2;
|
|
4671
|
-
const IS_STRIKETHROUGH = 4;
|
|
4672
|
-
const IS_UNDERLINE = 8;
|
|
4673
|
-
function decodeFormatBitmask(format) {
|
|
4674
|
-
const marks = {};
|
|
4675
|
-
if (format & IS_BOLD) marks.bold = true;
|
|
4676
|
-
if (format & IS_ITALIC) marks.italic = true;
|
|
4677
|
-
if (format & IS_UNDERLINE) marks.underline = true;
|
|
4678
|
-
if (format & IS_STRIKETHROUGH) marks.strikethrough = true;
|
|
4679
|
-
return marks;
|
|
4680
|
-
}
|
|
4681
|
-
function extractFontFamily(style) {
|
|
4682
|
-
const match = style.match(/font-family:\s*([^;]+)/);
|
|
4683
|
-
return match ? match[1].trim().replace(/['"]/g, "") : void 0;
|
|
4684
|
-
}
|
|
4685
|
-
function extractFontSizePt(style) {
|
|
4686
|
-
const match = style.match(/font-size:\s*(\d+(?:\.\d+)?)\s*pt/);
|
|
4687
|
-
return match ? parseFloat(match[1]) : void 0;
|
|
4688
|
-
}
|
|
4689
|
-
function buildTextMarks(format, style) {
|
|
4690
|
-
const formatMarks = decodeFormatBitmask(format);
|
|
4691
|
-
const fontFamily = style ? extractFontFamily(style) : void 0;
|
|
4692
|
-
const fontSize = style ? extractFontSizePt(style) : void 0;
|
|
4693
|
-
const marks = {
|
|
4694
|
-
...formatMarks,
|
|
4695
|
-
...fontFamily ? { fontFamily } : {},
|
|
4696
|
-
...fontSize ? { fontSize } : {}
|
|
4697
|
-
};
|
|
4698
|
-
return Object.keys(marks).length > 0 ? marks : void 0;
|
|
4699
|
-
}
|
|
4700
|
-
function mapInlineNode(node) {
|
|
4701
|
-
switch (node.type) {
|
|
4702
|
-
case "text":
|
|
4703
|
-
return mapTextNode(node);
|
|
4704
|
-
case "variable-node":
|
|
4705
|
-
return mapVariableNode(node);
|
|
4706
|
-
case "linebreak":
|
|
4707
|
-
return mapLineBreak();
|
|
4708
|
-
default:
|
|
4709
|
-
return { type: "text", text: "" };
|
|
4710
|
-
}
|
|
4711
|
-
}
|
|
4712
|
-
function mapTextNode(node) {
|
|
4713
|
-
const marks = buildTextMarks(node.format, node.style);
|
|
4714
|
-
return {
|
|
4715
|
-
type: "text",
|
|
4716
|
-
text: node.text,
|
|
4717
|
-
...marks ? { marks } : {}
|
|
4718
|
-
};
|
|
4719
|
-
}
|
|
4720
|
-
function mapVariableNode(node) {
|
|
4721
|
-
return {
|
|
4722
|
-
type: "variable",
|
|
4723
|
-
key: node.variableKey
|
|
4724
|
-
};
|
|
4725
|
-
}
|
|
4726
|
-
function mapLineBreak() {
|
|
4727
|
-
return { type: "linebreak" };
|
|
4728
|
-
}
|
|
4729
|
-
function mapInlineNodes(nodes) {
|
|
4730
|
-
return nodes.map(mapInlineNode);
|
|
4731
|
-
}
|
|
4732
|
-
const ALIGN_LEFT = 1;
|
|
4733
|
-
const ALIGN_CENTER = 2;
|
|
4734
|
-
const ALIGN_RIGHT = 3;
|
|
4735
|
-
const ALIGN_JUSTIFY = 4;
|
|
4736
|
-
function decodeAlignment(format) {
|
|
4737
|
-
if (typeof format === "string") {
|
|
4738
|
-
if (["left", "center", "right", "justify"].includes(format)) {
|
|
4739
|
-
return format;
|
|
4740
|
-
}
|
|
4741
|
-
return void 0;
|
|
4742
|
-
}
|
|
4743
|
-
if (typeof format !== "number" || format === 0) return void 0;
|
|
4744
|
-
switch (format) {
|
|
4745
|
-
case ALIGN_LEFT:
|
|
4746
|
-
return "left";
|
|
4747
|
-
case ALIGN_CENTER:
|
|
4748
|
-
return "center";
|
|
4749
|
-
case ALIGN_RIGHT:
|
|
4750
|
-
return "right";
|
|
4751
|
-
case ALIGN_JUSTIFY:
|
|
4752
|
-
return "justify";
|
|
4753
|
-
default:
|
|
4754
|
-
return void 0;
|
|
4755
|
-
}
|
|
4756
|
-
}
|
|
4757
|
-
function mapBlockNode(node) {
|
|
4758
|
-
switch (node.type) {
|
|
4759
|
-
case "paragraph":
|
|
4760
|
-
return mapParagraph(node);
|
|
4761
|
-
case "heading":
|
|
4762
|
-
return mapHeading(node);
|
|
4763
|
-
case "list":
|
|
4764
|
-
return mapList(node);
|
|
4765
|
-
case "quote":
|
|
4766
|
-
return mapBlockQuote(node);
|
|
4767
|
-
default:
|
|
4768
|
-
return {
|
|
4769
|
-
type: "paragraph",
|
|
4770
|
-
children: mapInlineChildren(node)
|
|
4771
|
-
};
|
|
4772
|
-
}
|
|
4773
|
-
}
|
|
4774
|
-
function mapParagraph(node) {
|
|
4775
|
-
const alignment = decodeAlignment(node.format);
|
|
4776
|
-
const indent = node.indent && node.indent > 0 ? node.indent : void 0;
|
|
4777
|
-
return {
|
|
4778
|
-
type: "paragraph",
|
|
4779
|
-
...alignment ? { alignment } : {},
|
|
4780
|
-
...indent ? { indent } : {},
|
|
4781
|
-
children: mapInlineChildren(node)
|
|
4782
|
-
};
|
|
4783
|
-
}
|
|
4784
|
-
function mapHeading(node) {
|
|
4785
|
-
var _a;
|
|
4786
|
-
const alignment = decodeAlignment(node.format);
|
|
4787
|
-
const tagMatch = (_a = node.tag) == null ? void 0 : _a.match(/^h(\d)$/);
|
|
4788
|
-
const level = tagMatch ? parseInt(tagMatch[1], 10) : 1;
|
|
4789
|
-
return {
|
|
4790
|
-
type: "heading",
|
|
4791
|
-
level,
|
|
4792
|
-
...alignment ? { alignment } : {},
|
|
4793
|
-
children: mapInlineChildren(node)
|
|
4794
|
-
};
|
|
4795
|
-
}
|
|
4796
|
-
function mapList(node) {
|
|
4797
|
-
const listType = node.listType === "number" ? "ordered" : "unordered";
|
|
4798
|
-
const items = (node.children ?? []).filter((c) => c.type === "listitem").map(mapListItem);
|
|
4799
|
-
return {
|
|
4800
|
-
type: "list",
|
|
4801
|
-
listType,
|
|
4802
|
-
items
|
|
4803
|
-
};
|
|
4804
|
-
}
|
|
4805
|
-
function mapListItem(node) {
|
|
4806
|
-
const inlineChildren = [];
|
|
4807
|
-
let nestedList;
|
|
4808
|
-
for (const child of node.children ?? []) {
|
|
4809
|
-
if (child.type === "list") {
|
|
4810
|
-
nestedList = mapList(child);
|
|
4811
|
-
} else {
|
|
4812
|
-
const mapped = mapInlineNodes([child]);
|
|
4813
|
-
inlineChildren.push(...mapped);
|
|
4814
|
-
}
|
|
4815
|
-
}
|
|
4816
|
-
return {
|
|
4817
|
-
type: "list-item",
|
|
4818
|
-
children: inlineChildren,
|
|
4819
|
-
...nestedList ? { nestedList } : {}
|
|
4820
|
-
};
|
|
4821
|
-
}
|
|
4822
|
-
function mapBlockQuote(node) {
|
|
4823
|
-
return {
|
|
4824
|
-
type: "blockquote",
|
|
4825
|
-
children: mapInlineChildren(node)
|
|
4826
|
-
};
|
|
4827
|
-
}
|
|
4828
|
-
function mapInlineChildren(node) {
|
|
4829
|
-
if (!node.children || node.children.length === 0) return [];
|
|
4830
|
-
return mapInlineNodes(node.children);
|
|
4831
|
-
}
|
|
4832
|
-
function mapBlockNodes(nodes) {
|
|
4833
|
-
return nodes.map(mapBlockNode);
|
|
4834
|
-
}
|
|
4835
|
-
function mapEditorStateToContent(state) {
|
|
4836
|
-
if (!state || !state.root || !state.root.children) {
|
|
4837
|
-
return null;
|
|
4838
|
-
}
|
|
4839
|
-
const blocks = mapBlockNodes(state.root.children);
|
|
4840
|
-
return { blocks };
|
|
4841
|
-
}
|
|
4842
|
-
function mapEditorStateToBlocks(state) {
|
|
4843
|
-
if (!state || !state.root || !state.root.children) {
|
|
4844
|
-
return [];
|
|
4845
|
-
}
|
|
4846
|
-
return mapBlockNodes(state.root.children);
|
|
4847
|
-
}
|
|
4848
|
-
const MARGIN_MM = Math.round(PAGE_MARGIN_PX / PX_PER_MM * 10) / 10;
|
|
4849
|
-
function serializeDocument(document2, variableDefinitions = []) {
|
|
4850
|
-
const pages = document2.pages.map(
|
|
4851
|
-
(page, index) => serializePage(page, index)
|
|
4852
|
-
);
|
|
4853
|
-
const metadata = buildMetadata(variableDefinitions);
|
|
4854
|
-
return {
|
|
4855
|
-
version: AST_VERSION,
|
|
4856
|
-
page: {
|
|
4857
|
-
format: "A4",
|
|
4858
|
-
widthMm: 210,
|
|
4859
|
-
heightMm: 297,
|
|
4860
|
-
margins: {
|
|
4861
|
-
topMm: MARGIN_MM,
|
|
4862
|
-
rightMm: MARGIN_MM,
|
|
4863
|
-
bottomMm: MARGIN_MM,
|
|
4864
|
-
leftMm: MARGIN_MM
|
|
4865
|
-
}
|
|
4866
|
-
},
|
|
4867
|
-
headerFooter: {
|
|
4868
|
-
enabled: document2.headerFooterEnabled,
|
|
4869
|
-
pageCounterMode: document2.pageCounterMode,
|
|
4870
|
-
defaultHeader: document2.pages.length > 0 ? mapEditorStateToContent(document2.pages[0].headerState) : null,
|
|
4871
|
-
defaultFooter: document2.pages.length > 0 ? mapEditorStateToContent(document2.pages[0].footerState) : null
|
|
4872
|
-
},
|
|
4873
|
-
pages,
|
|
4874
|
-
metadata
|
|
4875
|
-
};
|
|
4876
|
-
}
|
|
4877
|
-
function serializePage(page, pageIndex) {
|
|
4878
|
-
return {
|
|
4879
|
-
pageIndex,
|
|
4880
|
-
body: mapEditorStateToBlocks(page.bodyState),
|
|
4881
|
-
header: mapEditorStateToContent(page.headerState),
|
|
4882
|
-
footer: mapEditorStateToContent(page.footerState)
|
|
4883
|
-
};
|
|
4884
|
-
}
|
|
4885
|
-
function buildMetadata(variableDefinitions) {
|
|
4886
|
-
const variables = {};
|
|
4887
|
-
for (const def of variableDefinitions) {
|
|
4888
|
-
variables[def.key] = {
|
|
4889
|
-
key: def.key,
|
|
4890
|
-
label: def.label,
|
|
4891
|
-
...def.description ? { description: def.description } : {},
|
|
4892
|
-
...def.valueType ? { valueType: def.valueType } : {},
|
|
4893
|
-
...def.group ? { group: def.group } : {}
|
|
4894
|
-
};
|
|
4895
|
-
}
|
|
4896
|
-
return { variables };
|
|
4897
|
-
}
|
|
4898
|
-
function buildSavePayload(ast, options) {
|
|
4899
|
-
return {
|
|
4900
|
-
document: ast,
|
|
4901
|
-
...(options == null ? void 0 : options.exportTarget) ? { exportTarget: options.exportTarget } : {},
|
|
4902
|
-
...(options == null ? void 0 : options.documentId) ? { documentId: options.documentId } : {},
|
|
4903
|
-
...(options == null ? void 0 : options.metadata) ? { metadata: options.metadata } : {}
|
|
4904
|
-
};
|
|
4905
|
-
}
|
|
4906
|
-
function serializeDocumentJson(ast) {
|
|
4907
|
-
return JSON.stringify(ast, null, 2);
|
|
4908
|
-
}
|
|
4909
4926
|
function astExtension() {
|
|
4910
4927
|
return {
|
|
4911
4928
|
name: "ast",
|
|
@@ -5031,7 +5048,7 @@ function VariableChip({ variableKey }) {
|
|
|
5031
5048
|
return /* @__PURE__ */ jsx(
|
|
5032
5049
|
"span",
|
|
5033
5050
|
{
|
|
5034
|
-
className: "lex4-variable-chip
|
|
5051
|
+
className: "lex4-variable-chip",
|
|
5035
5052
|
"data-testid": `variable-chip-${variableKey}`,
|
|
5036
5053
|
title: variableKey,
|
|
5037
5054
|
children: label
|
|
@@ -5104,12 +5121,12 @@ const VariablePicker = ({ onInsert, disabled = false }) => {
|
|
|
5104
5121
|
document.addEventListener("mousedown", handler);
|
|
5105
5122
|
return () => document.removeEventListener("mousedown", handler);
|
|
5106
5123
|
}, [open]);
|
|
5107
|
-
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "
|
|
5124
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "lex4-variable-picker", children: [
|
|
5108
5125
|
/* @__PURE__ */ jsx(
|
|
5109
5126
|
"button",
|
|
5110
5127
|
{
|
|
5111
5128
|
type: "button",
|
|
5112
|
-
className: "
|
|
5129
|
+
className: "lex4-variable-picker-btn",
|
|
5113
5130
|
"data-testid": "variable-picker-button",
|
|
5114
5131
|
disabled: disabled || definitions.length === 0,
|
|
5115
5132
|
onClick: () => setOpen(!open),
|
|
@@ -5120,14 +5137,13 @@ const VariablePicker = ({ onInsert, disabled = false }) => {
|
|
|
5120
5137
|
open && /* @__PURE__ */ jsxs(
|
|
5121
5138
|
"div",
|
|
5122
5139
|
{
|
|
5123
|
-
className: "
|
|
5140
|
+
className: "lex4-variable-picker-dropdown",
|
|
5124
5141
|
"data-testid": "variable-picker-dropdown",
|
|
5125
5142
|
children: [
|
|
5126
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
5143
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-variable-picker-search", children: /* @__PURE__ */ jsx(
|
|
5127
5144
|
"input",
|
|
5128
5145
|
{
|
|
5129
5146
|
type: "text",
|
|
5130
|
-
className: "w-full rounded border border-gray-200 px-2 py-1 text-xs\n focus:border-blue-400 focus:outline-none",
|
|
5131
5147
|
placeholder: "Search variables...",
|
|
5132
5148
|
"data-testid": "variable-picker-search",
|
|
5133
5149
|
value: filter,
|
|
@@ -5135,20 +5151,20 @@ const VariablePicker = ({ onInsert, disabled = false }) => {
|
|
|
5135
5151
|
autoFocus: true
|
|
5136
5152
|
}
|
|
5137
5153
|
) }),
|
|
5138
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
5139
|
-
Object.keys(grouped).length === 0 && /* @__PURE__ */ jsx("div", { className: "
|
|
5154
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-variable-picker-list", children: [
|
|
5155
|
+
Object.keys(grouped).length === 0 && /* @__PURE__ */ jsx("div", { className: "lex4-variable-picker-empty", children: "No variables found" }),
|
|
5140
5156
|
Object.entries(grouped).map(([group, defs]) => /* @__PURE__ */ jsxs("div", { children: [
|
|
5141
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
5157
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-variable-picker-group-label", children: group }),
|
|
5142
5158
|
defs.map((def) => /* @__PURE__ */ jsxs(
|
|
5143
5159
|
"button",
|
|
5144
5160
|
{
|
|
5145
5161
|
type: "button",
|
|
5146
|
-
className: "
|
|
5162
|
+
className: "lex4-variable-picker-option",
|
|
5147
5163
|
"data-testid": `variable-option-${def.key}`,
|
|
5148
5164
|
onClick: () => handleInsert(def.key),
|
|
5149
5165
|
children: [
|
|
5150
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
5151
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
5166
|
+
/* @__PURE__ */ jsx("span", { className: "lex4-variable-picker-key", children: `{{${def.key}}}` }),
|
|
5167
|
+
/* @__PURE__ */ jsx("span", { className: "lex4-variable-picker-label", children: def.label })
|
|
5152
5168
|
]
|
|
5153
5169
|
},
|
|
5154
5170
|
def.key
|
|
@@ -5206,20 +5222,20 @@ const VariablePanel = ({ open, onClose }) => {
|
|
|
5206
5222
|
"button",
|
|
5207
5223
|
{
|
|
5208
5224
|
type: "button",
|
|
5209
|
-
className: "
|
|
5225
|
+
className: "lex4-sidebar-action-btn",
|
|
5210
5226
|
title: t.variables.refreshVariables,
|
|
5211
5227
|
"data-testid": "btn-refresh-variables",
|
|
5212
5228
|
children: /* @__PURE__ */ jsx(RefreshCw, { size: 12 })
|
|
5213
5229
|
}
|
|
5214
5230
|
),
|
|
5215
5231
|
children: [
|
|
5216
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
5217
|
-
/* @__PURE__ */ jsx(Search, { size: 14, className: "
|
|
5232
|
+
/* @__PURE__ */ jsx("div", { className: "lex4-variable-search-container", children: /* @__PURE__ */ jsxs("div", { className: "lex4-variable-search-wrapper", children: [
|
|
5233
|
+
/* @__PURE__ */ jsx(Search, { size: 14, className: "lex4-variable-search-icon" }),
|
|
5218
5234
|
/* @__PURE__ */ jsx(
|
|
5219
5235
|
"input",
|
|
5220
5236
|
{
|
|
5221
5237
|
type: "text",
|
|
5222
|
-
className: "
|
|
5238
|
+
className: "lex4-variable-search-input",
|
|
5223
5239
|
placeholder: t.variables.searchPlaceholder,
|
|
5224
5240
|
"data-testid": "variable-panel-search",
|
|
5225
5241
|
value: filter,
|
|
@@ -5227,25 +5243,19 @@ const VariablePanel = ({ open, onClose }) => {
|
|
|
5227
5243
|
}
|
|
5228
5244
|
)
|
|
5229
5245
|
] }) }),
|
|
5230
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
5231
|
-
Object.keys(grouped).length === 0 && /* @__PURE__ */ jsx("div", { className: "
|
|
5232
|
-
Object.entries(grouped).map(([group, defs]) => /* @__PURE__ */ jsx("div", { className: "
|
|
5246
|
+
/* @__PURE__ */ jsxs("div", { className: "lex4-variable-list", children: [
|
|
5247
|
+
Object.keys(grouped).length === 0 && /* @__PURE__ */ jsx("div", { className: "lex4-variable-list-empty", children: t.variables.noVariablesFound }),
|
|
5248
|
+
Object.entries(grouped).map(([group, defs]) => /* @__PURE__ */ jsx("div", { className: "lex4-variable-group", children: /* @__PURE__ */ jsx("div", { children: defs.map((def) => /* @__PURE__ */ jsxs(
|
|
5233
5249
|
"button",
|
|
5234
5250
|
{
|
|
5235
5251
|
type: "button",
|
|
5236
|
-
className: "
|
|
5252
|
+
className: "lex4-variable-list-item",
|
|
5237
5253
|
"data-testid": `variable-panel-${def.key}`,
|
|
5238
5254
|
onClick: () => handleInsert(def.key),
|
|
5239
5255
|
disabled: !activeEditor,
|
|
5240
5256
|
children: [
|
|
5241
|
-
/* @__PURE__ */ jsx(
|
|
5242
|
-
|
|
5243
|
-
{
|
|
5244
|
-
className: "inline-flex items-center rounded-full border border-blue-300 bg-white\n px-2 py-0.5 text-[11px] font-medium text-blue-700\n group-hover:border-blue-400 group-hover:bg-blue-50",
|
|
5245
|
-
children: def.label
|
|
5246
|
-
}
|
|
5247
|
-
),
|
|
5248
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-gray-400", children: group })
|
|
5257
|
+
/* @__PURE__ */ jsx("span", { className: "lex4-variable-badge", children: def.label }),
|
|
5258
|
+
/* @__PURE__ */ jsx("span", { className: "lex4-variable-group-label", children: group })
|
|
5249
5259
|
]
|
|
5250
5260
|
},
|
|
5251
5261
|
def.key
|
|
@@ -5299,10 +5309,7 @@ const VariablePanelToggle = () => {
|
|
|
5299
5309
|
"aria-label": panelOpen ? t.variables.closePanel : t.variables.openPanel,
|
|
5300
5310
|
onMouseDown: (e) => e.preventDefault(),
|
|
5301
5311
|
onClick: () => setPanelOpen(!panelOpen),
|
|
5302
|
-
className: `
|
|
5303
|
-
flex h-7 w-7 items-center justify-center rounded transition-colors
|
|
5304
|
-
${panelOpen ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-100 hover:text-gray-900"}
|
|
5305
|
-
`,
|
|
5312
|
+
className: `lex4-toolbar-btn${panelOpen ? " active" : ""}`,
|
|
5306
5313
|
"data-testid": "toggle-variable-panel",
|
|
5307
5314
|
children: /* @__PURE__ */ jsx(Braces, { size: 15 })
|
|
5308
5315
|
}
|