@almadar/ui 5.160.0 → 5.162.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +924 -891
- package/dist/avl/index.js +914 -881
- package/dist/components/index.cjs +944 -934
- package/dist/components/index.d.cts +156 -31
- package/dist/components/index.d.ts +156 -31
- package/dist/components/index.js +931 -924
- package/dist/hooks/index.cjs +25 -49
- package/dist/hooks/index.js +25 -49
- package/dist/locales/index.cjs +75 -147
- package/dist/locales/index.js +75 -147
- package/dist/providers/index.cjs +911 -882
- package/dist/providers/index.js +901 -872
- package/dist/runtime/index.cjs +920 -887
- package/dist/runtime/index.js +910 -877
- package/locales/ar.json +25 -49
- package/locales/en.json +25 -49
- package/locales/sl.json +25 -49
- package/package.json +5 -5
|
@@ -24025,8 +24025,9 @@ function DataGrid({
|
|
|
24025
24025
|
const titleField = fieldDefs.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fieldDefs[0];
|
|
24026
24026
|
const badgeFields = fieldDefs.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
24027
24027
|
const bodyFields = fieldDefs.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
|
|
24028
|
-
const
|
|
24029
|
-
const
|
|
24028
|
+
const inlineCap = Math.min(maxInlineActions ?? 1, 1);
|
|
24029
|
+
const inlineCardActions = actionDefs.filter((a) => a.variant === "primary").slice(0, inlineCap);
|
|
24030
|
+
const menuCardActions = actionDefs.filter((a) => !inlineCardActions.includes(a));
|
|
24030
24031
|
const fireAction = (action, itemData) => {
|
|
24031
24032
|
if (action.navigatesTo) {
|
|
24032
24033
|
const url = action.navigatesTo.replace(
|
|
@@ -24046,6 +24047,9 @@ function DataGrid({
|
|
|
24046
24047
|
e.stopPropagation();
|
|
24047
24048
|
fireAction(action, itemData);
|
|
24048
24049
|
};
|
|
24050
|
+
const cardClickAction = actionDefs.find((a) => a.variant !== "danger");
|
|
24051
|
+
const handleCardClick = cardClickAction ? (itemData) => () => fireAction(cardClickAction, itemData) : void 0;
|
|
24052
|
+
const stopCardClick = handleCardClick ? (e) => e.stopPropagation() : void 0;
|
|
24049
24053
|
const hasRenderProp = typeof children === "function";
|
|
24050
24054
|
React77.useEffect(() => {
|
|
24051
24055
|
if (data.length > 0 && !hasRenderProp && fieldDefs.length === 0) {
|
|
@@ -24117,55 +24121,40 @@ function DataGrid({
|
|
|
24117
24121
|
{
|
|
24118
24122
|
"data-entity-row": true,
|
|
24119
24123
|
"data-entity-id": id,
|
|
24120
|
-
|
|
24124
|
+
onClick: handleCardClick?.(itemData),
|
|
24125
|
+
className: cn("relative group/rowactions", handleCardClick && "cursor-pointer", isSelected && "ring-2 ring-primary rounded-lg"),
|
|
24121
24126
|
children: [
|
|
24122
24127
|
children(itemData, index),
|
|
24123
|
-
actionDefs.length > 0 && /* @__PURE__ */ jsxRuntime.
|
|
24124
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
24125
|
-
|
|
24126
|
-
|
|
24127
|
-
|
|
24128
|
-
|
|
24129
|
-
|
|
24130
|
-
|
|
24131
|
-
|
|
24132
|
-
|
|
24133
|
-
|
|
24134
|
-
|
|
24135
|
-
|
|
24136
|
-
|
|
24137
|
-
|
|
24138
|
-
|
|
24139
|
-
|
|
24140
|
-
)),
|
|
24141
|
-
maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
|
|
24142
|
-
exports.Menu,
|
|
24143
|
-
{
|
|
24144
|
-
position: "bottom-end",
|
|
24145
|
-
trigger: /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24146
|
-
items: actionDefs.slice(maxInlineActions).map((action) => ({
|
|
24147
|
-
label: action.label,
|
|
24148
|
-
icon: action.icon,
|
|
24149
|
-
event: action.event,
|
|
24150
|
-
onClick: () => fireAction(action, itemData)
|
|
24151
|
-
}))
|
|
24152
|
-
}
|
|
24153
|
-
)
|
|
24154
|
-
] }),
|
|
24155
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "hidden [@media(pointer:coarse)]:block rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
24128
|
+
actionDefs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { onClick: stopCardClick, className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: [
|
|
24129
|
+
inlineCardActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
24130
|
+
exports.Button,
|
|
24131
|
+
{
|
|
24132
|
+
variant: "primary",
|
|
24133
|
+
size: "sm",
|
|
24134
|
+
onClick: handleActionClick(action, itemData),
|
|
24135
|
+
"data-testid": `action-${action.event}`,
|
|
24136
|
+
"data-row-id": String(itemData.id),
|
|
24137
|
+
children: [
|
|
24138
|
+
action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
|
|
24139
|
+
action.label
|
|
24140
|
+
]
|
|
24141
|
+
},
|
|
24142
|
+
idx
|
|
24143
|
+
)),
|
|
24144
|
+
menuCardActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
24156
24145
|
exports.Menu,
|
|
24157
24146
|
{
|
|
24158
24147
|
position: "bottom-end",
|
|
24159
24148
|
trigger: /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24160
|
-
items:
|
|
24149
|
+
items: menuCardActions.map((action) => ({
|
|
24161
24150
|
label: action.label,
|
|
24162
24151
|
icon: action.icon,
|
|
24163
|
-
|
|
24152
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
24164
24153
|
onClick: () => fireAction(action, itemData)
|
|
24165
24154
|
}))
|
|
24166
24155
|
}
|
|
24167
|
-
)
|
|
24168
|
-
] })
|
|
24156
|
+
)
|
|
24157
|
+
] }) })
|
|
24169
24158
|
]
|
|
24170
24159
|
},
|
|
24171
24160
|
id
|
|
@@ -24179,12 +24168,14 @@ function DataGrid({
|
|
|
24179
24168
|
{
|
|
24180
24169
|
"data-entity-row": true,
|
|
24181
24170
|
"data-entity-id": id,
|
|
24171
|
+
onClick: handleCardClick?.(itemData),
|
|
24182
24172
|
className: cn(
|
|
24183
24173
|
"bg-card rounded-lg",
|
|
24184
24174
|
"border border-border",
|
|
24185
24175
|
"shadow-elevation-card hover:shadow-elevation-dialog",
|
|
24186
24176
|
"hover:border-primary transition-all",
|
|
24187
24177
|
"flex flex-col",
|
|
24178
|
+
handleCardClick && "cursor-pointer",
|
|
24188
24179
|
isSelected && "ring-2 ring-primary border-primary"
|
|
24189
24180
|
),
|
|
24190
24181
|
children: [
|
|
@@ -24234,53 +24225,35 @@ function DataGrid({
|
|
|
24234
24225
|
] }, field.name);
|
|
24235
24226
|
}) })
|
|
24236
24227
|
] }),
|
|
24237
|
-
|
|
24238
|
-
|
|
24228
|
+
actionDefs.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", onClick: stopCardClick, className: "flex-shrink-0", children: [
|
|
24229
|
+
inlineCardActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
24239
24230
|
exports.Button,
|
|
24240
24231
|
{
|
|
24241
|
-
variant:
|
|
24232
|
+
variant: "primary",
|
|
24242
24233
|
size: "sm",
|
|
24243
24234
|
onClick: handleActionClick(action, itemData),
|
|
24244
24235
|
"data-testid": `action-${action.event}`,
|
|
24245
24236
|
"data-row-id": String(itemData.id),
|
|
24246
24237
|
"aria-label": action.label,
|
|
24247
24238
|
title: action.label,
|
|
24248
|
-
className: cn(
|
|
24249
|
-
action.variant === "primary" ? void 0 : "text-muted-foreground hover:text-foreground",
|
|
24250
|
-
action.icon && "px-2"
|
|
24251
|
-
),
|
|
24239
|
+
className: cn(action.icon && "px-2"),
|
|
24252
24240
|
children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
|
|
24253
24241
|
},
|
|
24254
24242
|
idx
|
|
24255
24243
|
)),
|
|
24256
|
-
|
|
24244
|
+
menuCardActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
24257
24245
|
exports.Menu,
|
|
24258
24246
|
{
|
|
24259
24247
|
position: "bottom-end",
|
|
24260
24248
|
trigger: /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24261
|
-
items:
|
|
24249
|
+
items: menuCardActions.map((action) => ({
|
|
24262
24250
|
label: action.label,
|
|
24263
24251
|
icon: action.icon,
|
|
24264
|
-
|
|
24252
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
24265
24253
|
onClick: () => fireAction(action, itemData)
|
|
24266
24254
|
}))
|
|
24267
24255
|
}
|
|
24268
|
-
)
|
|
24269
|
-
dangerActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
24270
|
-
exports.Button,
|
|
24271
|
-
{
|
|
24272
|
-
variant: "ghost",
|
|
24273
|
-
size: "sm",
|
|
24274
|
-
onClick: handleActionClick(action, itemData),
|
|
24275
|
-
"data-testid": `action-${action.event}`,
|
|
24276
|
-
"data-row-id": String(itemData.id),
|
|
24277
|
-
"aria-label": action.label,
|
|
24278
|
-
title: action.label,
|
|
24279
|
-
className: "text-error hover:text-error hover:bg-error/10 px-2",
|
|
24280
|
-
children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
|
|
24281
|
-
},
|
|
24282
|
-
`danger-${idx}`
|
|
24283
|
-
))
|
|
24256
|
+
)
|
|
24284
24257
|
] })
|
|
24285
24258
|
] }) }),
|
|
24286
24259
|
bodyFields.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "px-4 pt-2 pb-4 flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
@@ -24522,54 +24495,59 @@ function DataList({
|
|
|
24522
24495
|
if (!itemActions || itemActions.length === 0) return null;
|
|
24523
24496
|
const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
|
|
24524
24497
|
const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
|
|
24525
|
-
return
|
|
24526
|
-
|
|
24527
|
-
|
|
24528
|
-
|
|
24529
|
-
|
|
24530
|
-
|
|
24531
|
-
|
|
24532
|
-
|
|
24533
|
-
|
|
24534
|
-
|
|
24535
|
-
action
|
|
24536
|
-
|
|
24537
|
-
|
|
24538
|
-
|
|
24539
|
-
|
|
24540
|
-
|
|
24541
|
-
|
|
24542
|
-
|
|
24543
|
-
|
|
24544
|
-
|
|
24545
|
-
|
|
24546
|
-
|
|
24547
|
-
|
|
24548
|
-
|
|
24549
|
-
|
|
24550
|
-
|
|
24551
|
-
|
|
24552
|
-
|
|
24553
|
-
|
|
24554
|
-
|
|
24555
|
-
|
|
24556
|
-
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
24560
|
-
|
|
24561
|
-
|
|
24562
|
-
|
|
24563
|
-
|
|
24564
|
-
|
|
24498
|
+
return (
|
|
24499
|
+
// stopPropagation at the cluster: the "⋯" trigger opens the overflow
|
|
24500
|
+
// menu without also firing the row's default click (inline buttons
|
|
24501
|
+
// already stop it in handleActionClick; the Menu panel is portaled).
|
|
24502
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", onClick: rowClickEvent ? (e) => e.stopPropagation() : void 0, className: "flex-shrink-0", children: [
|
|
24503
|
+
inline.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
24504
|
+
exports.Button,
|
|
24505
|
+
{
|
|
24506
|
+
variant: action.variant ?? "ghost",
|
|
24507
|
+
size: "sm",
|
|
24508
|
+
onClick: handleActionClick(action, itemData),
|
|
24509
|
+
"data-testid": `action-${action.event}`,
|
|
24510
|
+
"data-row-id": String(itemData.id),
|
|
24511
|
+
className: cn(
|
|
24512
|
+
action.variant === "danger" && "text-error hover:bg-error/10",
|
|
24513
|
+
// Must sit on the Button itself: the variant's own text colour
|
|
24514
|
+
// beats an inherited one from the row wrapper.
|
|
24515
|
+
onPrimary && "!text-primary-foreground hover:bg-primary-foreground/15"
|
|
24516
|
+
),
|
|
24517
|
+
children: [
|
|
24518
|
+
action.icon && renderIconInput2(action.icon, { size: "xs", className: "mr-1" }),
|
|
24519
|
+
action.label
|
|
24520
|
+
]
|
|
24521
|
+
},
|
|
24522
|
+
idx
|
|
24523
|
+
)),
|
|
24524
|
+
overflow.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
24525
|
+
exports.Menu,
|
|
24526
|
+
{
|
|
24527
|
+
position: "bottom-end",
|
|
24528
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24529
|
+
items: overflow.map((action) => ({
|
|
24530
|
+
label: action.label,
|
|
24531
|
+
icon: action.icon,
|
|
24532
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
24533
|
+
onClick: () => eventBus.emit(`UI:${action.event}`, {
|
|
24534
|
+
id: itemData.id,
|
|
24535
|
+
row: itemData
|
|
24536
|
+
})
|
|
24537
|
+
}))
|
|
24538
|
+
}
|
|
24539
|
+
)
|
|
24540
|
+
] })
|
|
24541
|
+
);
|
|
24565
24542
|
};
|
|
24543
|
+
const rowClickEvent = itemClickEvent || itemActions?.find((a) => a.variant !== "danger")?.event;
|
|
24566
24544
|
const handleRowClick = (itemData) => () => {
|
|
24567
|
-
if (!
|
|
24545
|
+
if (!rowClickEvent) return;
|
|
24568
24546
|
const payload = {
|
|
24569
24547
|
id: itemData.id,
|
|
24570
24548
|
row: itemData
|
|
24571
24549
|
};
|
|
24572
|
-
eventBus.emit(`UI:${
|
|
24550
|
+
eventBus.emit(`UI:${rowClickEvent}`, payload);
|
|
24573
24551
|
};
|
|
24574
24552
|
if (isLoading) {
|
|
24575
24553
|
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "secondary", children: t("loading.items") }) });
|
|
@@ -24617,10 +24595,10 @@ function DataList({
|
|
|
24617
24595
|
{
|
|
24618
24596
|
"data-entity-row": true,
|
|
24619
24597
|
"data-entity-id": id,
|
|
24620
|
-
onClick:
|
|
24598
|
+
onClick: rowClickEvent ? handleRowClick(itemData) : void 0,
|
|
24621
24599
|
className: cn(
|
|
24622
24600
|
"flex px-4 group/rowactions",
|
|
24623
|
-
|
|
24601
|
+
rowClickEvent && "cursor-pointer",
|
|
24624
24602
|
isSent ? "justify-end" : "justify-start"
|
|
24625
24603
|
),
|
|
24626
24604
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -24696,7 +24674,7 @@ function DataList({
|
|
|
24696
24674
|
const id2 = itemData.id || String(index);
|
|
24697
24675
|
const actions = renderItemActions(itemData);
|
|
24698
24676
|
return wrapDnd(
|
|
24699
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { "data-entity-row": true, "data-entity-id": id2, onClick:
|
|
24677
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { "data-entity-row": true, "data-entity-id": id2, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn("relative group/rowactions", rowClickEvent && "cursor-pointer"), children: [
|
|
24700
24678
|
children(itemData, index),
|
|
24701
24679
|
actions && /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: [
|
|
24702
24680
|
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5 [@media(pointer:coarse)]:hidden", children: actions }),
|
|
@@ -24708,7 +24686,6 @@ function DataList({
|
|
|
24708
24686
|
items: (itemActions ?? []).map((action) => ({
|
|
24709
24687
|
label: action.label,
|
|
24710
24688
|
icon: action.icon,
|
|
24711
|
-
event: action.event,
|
|
24712
24689
|
variant: action.variant === "danger" ? "danger" : "default",
|
|
24713
24690
|
onClick: () => eventBus.emit(`UI:${action.event}`, {
|
|
24714
24691
|
id: itemData.id,
|
|
@@ -24725,7 +24702,7 @@ function DataList({
|
|
|
24725
24702
|
const id = itemData.id || String(index);
|
|
24726
24703
|
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
24727
24704
|
return wrapDnd(
|
|
24728
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { "data-entity-row": true, "data-entity-id": id, onClick:
|
|
24705
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { "data-entity-row": true, "data-entity-id": id, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn(rowClickEvent && "cursor-pointer"), children: [
|
|
24729
24706
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
24730
24707
|
exports.Box,
|
|
24731
24708
|
{
|
|
@@ -33352,7 +33329,7 @@ var init_MapView = __esm({
|
|
|
33352
33329
|
shadowSize: [41, 41]
|
|
33353
33330
|
});
|
|
33354
33331
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
33355
|
-
const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback108, useState:
|
|
33332
|
+
const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback108, useState: useState106 } = React77__namespace.default;
|
|
33356
33333
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
33357
33334
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
33358
33335
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -33397,7 +33374,7 @@ var init_MapView = __esm({
|
|
|
33397
33374
|
showAttribution = true
|
|
33398
33375
|
}) {
|
|
33399
33376
|
const eventBus = useEventBus2();
|
|
33400
|
-
const [clickedPosition, setClickedPosition] =
|
|
33377
|
+
const [clickedPosition, setClickedPosition] = useState106(null);
|
|
33401
33378
|
const handleMapClick = useCallback108((lat, lng) => {
|
|
33402
33379
|
if (showClickedPin) {
|
|
33403
33380
|
setClickedPosition({ lat, lng });
|
|
@@ -37759,741 +37736,775 @@ var init_PositionedCanvas = __esm({
|
|
|
37759
37736
|
exports.PositionedCanvas.displayName = "PositionedCanvas";
|
|
37760
37737
|
}
|
|
37761
37738
|
});
|
|
37762
|
-
function
|
|
37763
|
-
|
|
37764
|
-
|
|
37765
|
-
|
|
37739
|
+
function safeUrl(raw, kinds) {
|
|
37740
|
+
const url = raw.trim();
|
|
37741
|
+
if (url.startsWith("#") || url.startsWith("/")) return url;
|
|
37742
|
+
const lower = url.toLowerCase();
|
|
37743
|
+
for (const kind of kinds) {
|
|
37744
|
+
if (lower.startsWith(kind)) return url;
|
|
37745
|
+
}
|
|
37746
|
+
return null;
|
|
37766
37747
|
}
|
|
37767
|
-
function
|
|
37768
|
-
|
|
37769
|
-
|
|
37770
|
-
const
|
|
37771
|
-
|
|
37772
|
-
|
|
37773
|
-
|
|
37774
|
-
|
|
37775
|
-
|
|
37748
|
+
function sanitizeNode(el) {
|
|
37749
|
+
const children = Array.from(el.children);
|
|
37750
|
+
for (const child of children) {
|
|
37751
|
+
const tag = child.tagName.toLowerCase();
|
|
37752
|
+
if (DROP_TAGS.has(tag)) {
|
|
37753
|
+
child.remove();
|
|
37754
|
+
continue;
|
|
37755
|
+
}
|
|
37756
|
+
const allowed = ALLOWED_ATTRS[tag];
|
|
37757
|
+
if (!allowed) {
|
|
37758
|
+
sanitizeNode(child);
|
|
37759
|
+
child.replaceWith(...Array.from(child.childNodes));
|
|
37760
|
+
continue;
|
|
37761
|
+
}
|
|
37762
|
+
for (const attr of Array.from(child.attributes)) {
|
|
37763
|
+
const name = attr.name.toLowerCase();
|
|
37764
|
+
if (!allowed.includes(name)) {
|
|
37765
|
+
child.removeAttribute(attr.name);
|
|
37766
|
+
continue;
|
|
37767
|
+
}
|
|
37768
|
+
if (name === "href") {
|
|
37769
|
+
const url = safeUrl(attr.value, ["http://", "https://", "mailto:"]);
|
|
37770
|
+
if (url === null) child.removeAttribute(attr.name);
|
|
37771
|
+
else child.setAttribute("href", url);
|
|
37772
|
+
}
|
|
37773
|
+
if (name === "src") {
|
|
37774
|
+
const url = safeUrl(attr.value, ["http://", "https://", "data:image/"]);
|
|
37775
|
+
if (url === null) child.remove();
|
|
37776
|
+
else child.setAttribute("src", url);
|
|
37777
|
+
}
|
|
37778
|
+
}
|
|
37779
|
+
sanitizeNode(child);
|
|
37780
|
+
}
|
|
37776
37781
|
}
|
|
37777
|
-
function
|
|
37778
|
-
|
|
37779
|
-
|
|
37780
|
-
|
|
37781
|
-
|
|
37782
|
-
|
|
37783
|
-
|
|
37784
|
-
children: [
|
|
37785
|
-
{ id: nextBlockId("li"), type: "paragraph", content: "" }
|
|
37786
|
-
]
|
|
37787
|
-
};
|
|
37788
|
-
case "image":
|
|
37789
|
-
return {
|
|
37790
|
-
id: nextBlockId(type),
|
|
37791
|
-
type,
|
|
37792
|
-
content: "",
|
|
37793
|
-
metadata: { url: "", caption: "" }
|
|
37794
|
-
};
|
|
37795
|
-
case "code":
|
|
37796
|
-
return {
|
|
37797
|
-
id: nextBlockId(type),
|
|
37798
|
-
type,
|
|
37799
|
-
content: "",
|
|
37800
|
-
metadata: { language: "plaintext" }
|
|
37801
|
-
};
|
|
37802
|
-
case "divider":
|
|
37803
|
-
return { id: nextBlockId(type), type };
|
|
37804
|
-
default:
|
|
37805
|
-
return { id: nextBlockId(type), type, content: "" };
|
|
37782
|
+
function sanitizeRichHtml(html) {
|
|
37783
|
+
if (!html || typeof html !== "string") return "";
|
|
37784
|
+
if (typeof window === "undefined" || typeof DOMParser === "undefined") return "";
|
|
37785
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
37786
|
+
sanitizeNode(doc.body);
|
|
37787
|
+
if (!doc.body.querySelector("img, hr") && (doc.body.textContent ?? "").trim().length === 0) {
|
|
37788
|
+
return "";
|
|
37806
37789
|
}
|
|
37790
|
+
return doc.body.innerHTML.replace(//g, "");
|
|
37791
|
+
}
|
|
37792
|
+
function htmlIsEmpty(el) {
|
|
37793
|
+
if (el.querySelector("img, hr")) return false;
|
|
37794
|
+
return (el.textContent ?? "").trim().length === 0;
|
|
37807
37795
|
}
|
|
37808
|
-
function
|
|
37809
|
-
|
|
37796
|
+
function closestBlock(node, root) {
|
|
37797
|
+
let cur = node;
|
|
37798
|
+
while (cur && cur !== root) {
|
|
37799
|
+
if (cur instanceof Element && BLOCK_TAGS.has(cur.tagName)) return cur;
|
|
37800
|
+
cur = cur.parentNode;
|
|
37801
|
+
}
|
|
37802
|
+
return null;
|
|
37810
37803
|
}
|
|
37811
|
-
function
|
|
37812
|
-
return
|
|
37804
|
+
function RichTextStyles() {
|
|
37805
|
+
return /* @__PURE__ */ jsxRuntime.jsx("style", { children: RICH_TEXT_CSS });
|
|
37813
37806
|
}
|
|
37814
|
-
function
|
|
37807
|
+
function readToolbarState(root) {
|
|
37808
|
+
const sel = window.getSelection();
|
|
37809
|
+
if (!sel || sel.rangeCount === 0) return IDLE_TOOLBAR;
|
|
37810
|
+
const anchor = sel.anchorNode;
|
|
37811
|
+
if (!anchor || !root.contains(anchor)) return IDLE_TOOLBAR;
|
|
37812
|
+
let block = null;
|
|
37813
|
+
let link = false;
|
|
37814
|
+
let node = anchor;
|
|
37815
|
+
while (node && node !== root) {
|
|
37816
|
+
if (node instanceof Element) {
|
|
37817
|
+
const tag = node.tagName.toLowerCase();
|
|
37818
|
+
if (!block && (tag === "h1" || tag === "h2" || tag === "h3" || tag === "blockquote" || tag === "pre")) {
|
|
37819
|
+
block = tag;
|
|
37820
|
+
}
|
|
37821
|
+
if (tag === "a") link = true;
|
|
37822
|
+
}
|
|
37823
|
+
node = node.parentNode;
|
|
37824
|
+
}
|
|
37815
37825
|
return {
|
|
37816
|
-
|
|
37817
|
-
|
|
37818
|
-
|
|
37819
|
-
|
|
37820
|
-
|
|
37821
|
-
|
|
37822
|
-
|
|
37826
|
+
bold: document.queryCommandState("bold"),
|
|
37827
|
+
italic: document.queryCommandState("italic"),
|
|
37828
|
+
underline: document.queryCommandState("underline"),
|
|
37829
|
+
strikeThrough: document.queryCommandState("strikeThrough"),
|
|
37830
|
+
block,
|
|
37831
|
+
bullets: document.queryCommandState("insertUnorderedList"),
|
|
37832
|
+
numbers: document.queryCommandState("insertOrderedList"),
|
|
37833
|
+
link
|
|
37823
37834
|
};
|
|
37824
37835
|
}
|
|
37825
|
-
function
|
|
37826
|
-
|
|
37827
|
-
|
|
37828
|
-
|
|
37829
|
-
|
|
37830
|
-
|
|
37831
|
-
|
|
37832
|
-
|
|
37833
|
-
|
|
37834
|
-
|
|
37835
|
-
|
|
37836
|
-
|
|
37836
|
+
function ToolbarButton({ icon: IconCmp, label, active, onExec }) {
|
|
37837
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
37838
|
+
exports.Button,
|
|
37839
|
+
{
|
|
37840
|
+
type: "button",
|
|
37841
|
+
variant: "ghost",
|
|
37842
|
+
size: "sm",
|
|
37843
|
+
"aria-label": label,
|
|
37844
|
+
"aria-pressed": active,
|
|
37845
|
+
title: label,
|
|
37846
|
+
className: cn(
|
|
37847
|
+
"h-8 w-8 p-0 gap-0 justify-center",
|
|
37848
|
+
active && "bg-muted text-foreground"
|
|
37849
|
+
),
|
|
37850
|
+
onMouseDown: (e) => {
|
|
37851
|
+
e.preventDefault();
|
|
37852
|
+
onExec();
|
|
37853
|
+
},
|
|
37854
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(IconCmp, { size: 15 })
|
|
37837
37855
|
}
|
|
37838
|
-
|
|
37839
|
-
|
|
37840
|
-
|
|
37841
|
-
|
|
37842
|
-
|
|
37843
|
-
|
|
37844
|
-
|
|
37845
|
-
|
|
37846
|
-
|
|
37847
|
-
|
|
37848
|
-
|
|
37849
|
-
|
|
37850
|
-
|
|
37851
|
-
|
|
37852
|
-
|
|
37853
|
-
|
|
37854
|
-
|
|
37855
|
-
|
|
37856
|
-
|
|
37857
|
-
|
|
37858
|
-
|
|
37859
|
-
|
|
37860
|
-
|
|
37861
|
-
|
|
37862
|
-
|
|
37863
|
-
|
|
37856
|
+
);
|
|
37857
|
+
}
|
|
37858
|
+
var CHANGE_DEBOUNCE_MS, ALLOWED_ATTRS, DROP_TAGS, MD_BLOCK_PREFIXES, BLOCK_TAGS, MD_INLINE_RULES, RICH_TEXT_CSS, IDLE_TOOLBAR; exports.RichTextEditor = void 0;
|
|
37859
|
+
var init_RichTextEditor = __esm({
|
|
37860
|
+
"components/core/molecules/RichTextEditor.tsx"() {
|
|
37861
|
+
"use client";
|
|
37862
|
+
init_cn();
|
|
37863
|
+
init_Box();
|
|
37864
|
+
init_Button();
|
|
37865
|
+
init_useEventBus();
|
|
37866
|
+
CHANGE_DEBOUNCE_MS = 400;
|
|
37867
|
+
ALLOWED_ATTRS = {
|
|
37868
|
+
p: [],
|
|
37869
|
+
h1: [],
|
|
37870
|
+
h2: [],
|
|
37871
|
+
h3: [],
|
|
37872
|
+
h4: [],
|
|
37873
|
+
ul: [],
|
|
37874
|
+
ol: [],
|
|
37875
|
+
li: [],
|
|
37876
|
+
blockquote: [],
|
|
37877
|
+
pre: [],
|
|
37878
|
+
code: [],
|
|
37879
|
+
b: [],
|
|
37880
|
+
strong: [],
|
|
37881
|
+
i: [],
|
|
37882
|
+
em: [],
|
|
37883
|
+
u: [],
|
|
37884
|
+
s: [],
|
|
37885
|
+
strike: [],
|
|
37886
|
+
br: [],
|
|
37887
|
+
hr: [],
|
|
37888
|
+
div: [],
|
|
37889
|
+
span: [],
|
|
37890
|
+
a: ["href"],
|
|
37891
|
+
img: ["src", "alt"]
|
|
37892
|
+
};
|
|
37893
|
+
DROP_TAGS = /* @__PURE__ */ new Set(["script", "style", "iframe", "object", "embed", "link", "meta", "form", "input", "button", "textarea", "select"]);
|
|
37894
|
+
MD_BLOCK_PREFIXES = {
|
|
37895
|
+
"#": { kind: "block", tag: "h1" },
|
|
37896
|
+
"##": { kind: "block", tag: "h2" },
|
|
37897
|
+
"###": { kind: "block", tag: "h3" },
|
|
37898
|
+
">": { kind: "block", tag: "blockquote" },
|
|
37899
|
+
"```": { kind: "block", tag: "pre" },
|
|
37900
|
+
"-": { kind: "list", command: "insertUnorderedList" },
|
|
37901
|
+
"*": { kind: "list", command: "insertUnorderedList" },
|
|
37902
|
+
"1.": { kind: "list", command: "insertOrderedList" }
|
|
37903
|
+
};
|
|
37904
|
+
BLOCK_TAGS = /* @__PURE__ */ new Set(["P", "DIV", "LI", "H1", "H2", "H3", "H4", "BLOCKQUOTE", "PRE"]);
|
|
37905
|
+
MD_INLINE_RULES = [
|
|
37906
|
+
{ pattern: /\*\*([^*\n]+)\*\*$/, wrap: "strong" },
|
|
37907
|
+
{ pattern: /(^|[^*])\*([^*\n]+)\*$/, wrap: "em" },
|
|
37908
|
+
{ pattern: /`([^`\n]+)`$/, wrap: "code" }
|
|
37909
|
+
];
|
|
37910
|
+
RICH_TEXT_CSS = `
|
|
37911
|
+
.almadar-rich-text { line-height: 1.7; color: var(--color-foreground); }
|
|
37912
|
+
.almadar-rich-text h1 { font-size: 1.875rem; font-weight: 700; line-height: 1.25; margin: 1.25em 0 0.4em; }
|
|
37913
|
+
.almadar-rich-text h2 { font-size: 1.5rem; font-weight: 650; line-height: 1.3; margin: 1.1em 0 0.4em; }
|
|
37914
|
+
.almadar-rich-text h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.35; margin: 1em 0 0.35em; }
|
|
37915
|
+
.almadar-rich-text h1:first-child, .almadar-rich-text h2:first-child, .almadar-rich-text h3:first-child { margin-top: 0; }
|
|
37916
|
+
.almadar-rich-text p { margin: 0.5em 0; }
|
|
37917
|
+
.almadar-rich-text ul { list-style: disc; padding-inline-start: 1.5rem; margin: 0.5em 0; }
|
|
37918
|
+
.almadar-rich-text ol { list-style: decimal; padding-inline-start: 1.5rem; margin: 0.5em 0; }
|
|
37919
|
+
.almadar-rich-text li { margin: 0.25em 0; }
|
|
37920
|
+
.almadar-rich-text blockquote { border-inline-start: 3px solid var(--color-primary); padding-inline-start: 1rem; font-style: italic; color: var(--color-muted-foreground); margin: 0.75em 0; }
|
|
37921
|
+
.almadar-rich-text pre { background: var(--color-muted); border: 1px solid var(--color-border); border-radius: 0.375rem; padding: 0.75rem 1rem; font-family: ui-monospace, monospace; font-size: 0.875em; white-space: pre-wrap; margin: 0.75em 0; }
|
|
37922
|
+
.almadar-rich-text code { font-family: ui-monospace, monospace; font-size: 0.875em; background: var(--color-muted); border-radius: 0.25rem; padding: 0.1em 0.35em; }
|
|
37923
|
+
.almadar-rich-text pre code { background: transparent; padding: 0; }
|
|
37924
|
+
.almadar-rich-text a { color: var(--color-primary); text-decoration: underline; }
|
|
37925
|
+
.almadar-rich-text hr { border: none; border-top: 1px solid var(--color-border); margin: 1.25em 0; }
|
|
37926
|
+
.almadar-rich-text img { max-width: 100%; border-radius: 0.375rem; }
|
|
37927
|
+
`;
|
|
37928
|
+
IDLE_TOOLBAR = {
|
|
37929
|
+
bold: false,
|
|
37930
|
+
italic: false,
|
|
37931
|
+
underline: false,
|
|
37932
|
+
strikeThrough: false,
|
|
37933
|
+
block: null,
|
|
37934
|
+
bullets: false,
|
|
37935
|
+
numbers: false,
|
|
37936
|
+
link: false
|
|
37937
|
+
};
|
|
37938
|
+
exports.RichTextEditor = ({
|
|
37939
|
+
value,
|
|
37940
|
+
onChange,
|
|
37941
|
+
changeEvent,
|
|
37942
|
+
readOnly = false,
|
|
37943
|
+
placeholder,
|
|
37944
|
+
showToolbar = true,
|
|
37945
|
+
className
|
|
37946
|
+
}) => {
|
|
37947
|
+
const { t } = hooks.useTranslate();
|
|
37948
|
+
const ref = React77.useRef(null);
|
|
37949
|
+
const [toolbar, setToolbar] = React77.useState(IDLE_TOOLBAR);
|
|
37950
|
+
const [empty, setEmpty] = React77.useState(() => !value || !sanitizeRichHtml(value).trim());
|
|
37951
|
+
const eventBus = useEventBus();
|
|
37952
|
+
const onChangeRef = React77.useRef(onChange);
|
|
37953
|
+
const changeEventRef = React77.useRef(changeEvent);
|
|
37954
|
+
React77.useEffect(() => {
|
|
37955
|
+
onChangeRef.current = onChange;
|
|
37956
|
+
changeEventRef.current = changeEvent;
|
|
37957
|
+
}, [onChange, changeEvent]);
|
|
37958
|
+
const emitTimerRef = React77.useRef(null);
|
|
37959
|
+
const emitNow = React77.useCallback(() => {
|
|
37960
|
+
const el = ref.current;
|
|
37961
|
+
if (!el) return;
|
|
37962
|
+
const html = sanitizeRichHtml(el.innerHTML);
|
|
37963
|
+
onChangeRef.current?.(html);
|
|
37964
|
+
const evt = changeEventRef.current;
|
|
37965
|
+
if (evt) eventBus.emit(`UI:${evt}`, { value: html });
|
|
37966
|
+
}, [eventBus]);
|
|
37967
|
+
const scheduleEmit = React77.useCallback(() => {
|
|
37968
|
+
if (emitTimerRef.current) clearTimeout(emitTimerRef.current);
|
|
37969
|
+
emitTimerRef.current = setTimeout(() => {
|
|
37970
|
+
emitTimerRef.current = null;
|
|
37971
|
+
emitNow();
|
|
37972
|
+
}, CHANGE_DEBOUNCE_MS);
|
|
37973
|
+
}, [emitNow]);
|
|
37974
|
+
const flushEmit = React77.useCallback(() => {
|
|
37975
|
+
if (!emitTimerRef.current) return;
|
|
37976
|
+
clearTimeout(emitTimerRef.current);
|
|
37977
|
+
emitTimerRef.current = null;
|
|
37978
|
+
emitNow();
|
|
37979
|
+
}, [emitNow]);
|
|
37980
|
+
React77.useEffect(() => () => {
|
|
37981
|
+
if (emitTimerRef.current) {
|
|
37982
|
+
clearTimeout(emitTimerRef.current);
|
|
37983
|
+
emitTimerRef.current = null;
|
|
37984
|
+
emitNow();
|
|
37985
|
+
}
|
|
37986
|
+
}, [emitNow]);
|
|
37987
|
+
React77.useEffect(() => {
|
|
37988
|
+
if (readOnly) return;
|
|
37989
|
+
const el = ref.current;
|
|
37990
|
+
if (!el) return;
|
|
37991
|
+
if (document.activeElement === el) return;
|
|
37992
|
+
const next = sanitizeRichHtml(value ?? "") || "<p><br></p>";
|
|
37993
|
+
if (el.innerHTML !== next) {
|
|
37994
|
+
el.innerHTML = next;
|
|
37995
|
+
setEmpty(htmlIsEmpty(el));
|
|
37996
|
+
}
|
|
37997
|
+
}, [readOnly, value]);
|
|
37998
|
+
React77.useEffect(() => {
|
|
37999
|
+
if (readOnly) return;
|
|
38000
|
+
document.execCommand("defaultParagraphSeparator", false, "p");
|
|
38001
|
+
}, [readOnly]);
|
|
38002
|
+
React77.useEffect(() => {
|
|
38003
|
+
if (readOnly || !showToolbar) return;
|
|
38004
|
+
const onSelectionChange = () => {
|
|
38005
|
+
const el = ref.current;
|
|
38006
|
+
if (!el) return;
|
|
38007
|
+
setToolbar(readToolbarState(el));
|
|
38008
|
+
};
|
|
38009
|
+
document.addEventListener("selectionchange", onSelectionChange);
|
|
38010
|
+
return () => document.removeEventListener("selectionchange", onSelectionChange);
|
|
38011
|
+
}, [readOnly, showToolbar]);
|
|
38012
|
+
const tryInlineMarkdown = React77.useCallback(() => {
|
|
38013
|
+
const root = ref.current;
|
|
38014
|
+
if (!root) return false;
|
|
38015
|
+
const sel = window.getSelection();
|
|
38016
|
+
if (!sel || !sel.isCollapsed || sel.rangeCount === 0) return false;
|
|
38017
|
+
const node = sel.anchorNode;
|
|
38018
|
+
if (!node || node.nodeType !== Node.TEXT_NODE || !root.contains(node)) return false;
|
|
38019
|
+
if (node.parentElement?.closest("code, pre")) return false;
|
|
38020
|
+
const text = (node.textContent ?? "").slice(0, sel.anchorOffset);
|
|
38021
|
+
for (const rule of MD_INLINE_RULES) {
|
|
38022
|
+
const m = rule.pattern.exec(text);
|
|
38023
|
+
if (!m) continue;
|
|
38024
|
+
const inner = rule.wrap === "em" ? m[2] : m[1];
|
|
38025
|
+
if (!inner || !inner.trim()) continue;
|
|
38026
|
+
const lead = rule.wrap === "em" ? m[1]?.length ?? 0 : 0;
|
|
38027
|
+
const range = document.createRange();
|
|
38028
|
+
range.setStart(node, m.index + lead);
|
|
38029
|
+
range.setEnd(node, sel.anchorOffset);
|
|
38030
|
+
const el = document.createElement(rule.wrap);
|
|
38031
|
+
el.textContent = inner;
|
|
38032
|
+
range.deleteContents();
|
|
38033
|
+
range.insertNode(el);
|
|
38034
|
+
const after = document.createTextNode("\u200B");
|
|
38035
|
+
el.parentNode?.insertBefore(after, el.nextSibling);
|
|
38036
|
+
const caret = document.createRange();
|
|
38037
|
+
caret.setStart(after, 1);
|
|
38038
|
+
caret.collapse(true);
|
|
38039
|
+
sel.removeAllRanges();
|
|
38040
|
+
sel.addRange(caret);
|
|
38041
|
+
return true;
|
|
38042
|
+
}
|
|
38043
|
+
return false;
|
|
38044
|
+
}, []);
|
|
38045
|
+
const tryBlockMarkdown = React77.useCallback(() => {
|
|
38046
|
+
const root = ref.current;
|
|
38047
|
+
if (!root) return false;
|
|
38048
|
+
const sel = window.getSelection();
|
|
38049
|
+
if (!sel || !sel.isCollapsed || sel.rangeCount === 0) return false;
|
|
38050
|
+
const node = sel.anchorNode;
|
|
38051
|
+
if (!node || node.nodeType !== Node.TEXT_NODE || !root.contains(node)) return false;
|
|
38052
|
+
const block = closestBlock(node, root);
|
|
38053
|
+
if (block ? block.firstChild !== node : root.firstChild !== node) return false;
|
|
38054
|
+
const prefix = (node.textContent ?? "").slice(0, sel.anchorOffset);
|
|
38055
|
+
const rule = MD_BLOCK_PREFIXES[prefix];
|
|
38056
|
+
if (!rule) return false;
|
|
38057
|
+
if (node.parentElement?.closest("pre, code")) return false;
|
|
38058
|
+
if (rule.kind === "list" && node.parentElement?.closest("li")) return false;
|
|
38059
|
+
node.deleteData(0, prefix.length);
|
|
38060
|
+
const caret = document.createRange();
|
|
38061
|
+
caret.setStart(node, 0);
|
|
38062
|
+
caret.collapse(true);
|
|
38063
|
+
sel.removeAllRanges();
|
|
38064
|
+
sel.addRange(caret);
|
|
38065
|
+
if (rule.kind === "list") {
|
|
38066
|
+
const container = block ?? node.parentElement;
|
|
38067
|
+
const list = document.createElement(rule.command === "insertOrderedList" ? "ol" : "ul");
|
|
38068
|
+
const li = document.createElement("li");
|
|
38069
|
+
if (block) {
|
|
38070
|
+
while (block.firstChild) li.appendChild(block.firstChild);
|
|
38071
|
+
list.appendChild(li);
|
|
38072
|
+
block.replaceWith(list);
|
|
38073
|
+
} else if (container) {
|
|
38074
|
+
li.appendChild(node);
|
|
38075
|
+
list.appendChild(li);
|
|
38076
|
+
container.appendChild(list);
|
|
38077
|
+
}
|
|
38078
|
+
if (!li.firstChild) li.appendChild(document.createElement("br"));
|
|
38079
|
+
const liCaret = document.createRange();
|
|
38080
|
+
liCaret.selectNodeContents(li);
|
|
38081
|
+
liCaret.collapse(true);
|
|
38082
|
+
sel.removeAllRanges();
|
|
38083
|
+
sel.addRange(liCaret);
|
|
38084
|
+
} else {
|
|
38085
|
+
document.execCommand("formatBlock", false, rule.tag);
|
|
38086
|
+
}
|
|
38087
|
+
return true;
|
|
38088
|
+
}, []);
|
|
38089
|
+
const afterEdit = React77.useCallback(() => {
|
|
38090
|
+
const el = ref.current;
|
|
38091
|
+
if (!el) return;
|
|
38092
|
+
tryInlineMarkdown();
|
|
38093
|
+
setEmpty(htmlIsEmpty(el));
|
|
38094
|
+
setToolbar(readToolbarState(el));
|
|
38095
|
+
scheduleEmit();
|
|
38096
|
+
}, [scheduleEmit, tryInlineMarkdown]);
|
|
38097
|
+
const handleKeyDown = React77.useCallback((e) => {
|
|
38098
|
+
if (e.key === " " && tryBlockMarkdown()) {
|
|
38099
|
+
e.preventDefault();
|
|
38100
|
+
afterEdit();
|
|
38101
|
+
}
|
|
38102
|
+
}, [afterEdit, tryBlockMarkdown]);
|
|
38103
|
+
const execInline = React77.useCallback((command) => {
|
|
38104
|
+
document.execCommand(command, false);
|
|
38105
|
+
afterEdit();
|
|
38106
|
+
}, [afterEdit]);
|
|
38107
|
+
const execBlock = React77.useCallback((tag) => {
|
|
38108
|
+
const next = toolbar.block === tag ? "p" : tag;
|
|
38109
|
+
document.execCommand("formatBlock", false, next);
|
|
38110
|
+
afterEdit();
|
|
38111
|
+
}, [afterEdit, toolbar.block]);
|
|
38112
|
+
const execList = React77.useCallback((command) => {
|
|
38113
|
+
document.execCommand(command, false);
|
|
38114
|
+
afterEdit();
|
|
38115
|
+
}, [afterEdit]);
|
|
38116
|
+
const execLink = React77.useCallback(() => {
|
|
38117
|
+
if (toolbar.link) {
|
|
38118
|
+
document.execCommand("unlink", false);
|
|
38119
|
+
afterEdit();
|
|
38120
|
+
return;
|
|
38121
|
+
}
|
|
38122
|
+
const url = window.prompt(t("richTextEditor.linkPrompt"));
|
|
38123
|
+
if (!url) return;
|
|
38124
|
+
const safe = safeUrl(url, ["http://", "https://", "mailto:"]) ?? `https://${url}`;
|
|
38125
|
+
document.execCommand("createLink", false, safe);
|
|
38126
|
+
afterEdit();
|
|
38127
|
+
}, [afterEdit, t, toolbar.link]);
|
|
38128
|
+
const execRule = React77.useCallback(() => {
|
|
38129
|
+
document.execCommand("insertHorizontalRule", false);
|
|
38130
|
+
afterEdit();
|
|
38131
|
+
}, [afterEdit]);
|
|
38132
|
+
if (readOnly) {
|
|
38133
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: cn("almadar-rich-text max-w-none", className), children: [
|
|
38134
|
+
/* @__PURE__ */ jsxRuntime.jsx(RichTextStyles, {}),
|
|
38135
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { dangerouslySetInnerHTML: { __html: sanitizeRichHtml(value ?? "") } })
|
|
38136
|
+
] });
|
|
38137
|
+
}
|
|
38138
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: cn("flex flex-col gap-2", className), children: [
|
|
38139
|
+
/* @__PURE__ */ jsxRuntime.jsx(RichTextStyles, {}),
|
|
38140
|
+
showToolbar && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38141
|
+
exports.Box,
|
|
38142
|
+
{
|
|
38143
|
+
role: "toolbar",
|
|
38144
|
+
"aria-label": t("richTextEditor.editorToolbar"),
|
|
38145
|
+
className: cn(
|
|
38146
|
+
"sticky top-0 z-10 flex flex-wrap items-center gap-0.5 self-start",
|
|
38147
|
+
"rounded-md border border-border bg-background/95 px-1 py-0.5 shadow-sm"
|
|
38148
|
+
),
|
|
38149
|
+
children: [
|
|
38150
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Bold, label: t("richTextEditor.bold"), active: toolbar.bold, onExec: () => execInline("bold") }),
|
|
38151
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Italic, label: t("richTextEditor.italic"), active: toolbar.italic, onExec: () => execInline("italic") }),
|
|
38152
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Underline, label: t("richTextEditor.underline"), active: toolbar.underline, onExec: () => execInline("underline") }),
|
|
38153
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Strikethrough, label: t("richTextEditor.strikethrough"), active: toolbar.strikeThrough, onExec: () => execInline("strikeThrough") }),
|
|
38154
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "mx-1 h-5 w-px bg-border" }),
|
|
38155
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Heading1, label: t("richTextEditor.heading1"), active: toolbar.block === "h1", onExec: () => execBlock("h1") }),
|
|
38156
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Heading2, label: t("richTextEditor.heading2"), active: toolbar.block === "h2", onExec: () => execBlock("h2") }),
|
|
38157
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Heading3, label: t("richTextEditor.heading3"), active: toolbar.block === "h3", onExec: () => execBlock("h3") }),
|
|
38158
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "mx-1 h-5 w-px bg-border" }),
|
|
38159
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.List, label: t("richTextEditor.bulletList"), active: toolbar.bullets, onExec: () => execList("insertUnorderedList") }),
|
|
38160
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.ListOrdered, label: t("richTextEditor.numberedList"), active: toolbar.numbers, onExec: () => execList("insertOrderedList") }),
|
|
38161
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "mx-1 h-5 w-px bg-border" }),
|
|
38162
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Quote, label: t("richTextEditor.quote"), active: toolbar.block === "blockquote", onExec: () => execBlock("blockquote") }),
|
|
38163
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Code, label: t("richTextEditor.code"), active: toolbar.block === "pre", onExec: () => execBlock("pre") }),
|
|
38164
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Link, label: toolbar.link ? t("richTextEditor.removeLink") : t("richTextEditor.link"), active: toolbar.link, onExec: execLink }),
|
|
38165
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolbarButton, { icon: LucideIcons2.Minus, label: t("richTextEditor.divider"), onExec: execRule })
|
|
38166
|
+
]
|
|
38167
|
+
}
|
|
38168
|
+
),
|
|
38169
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38170
|
+
exports.Box,
|
|
38171
|
+
{
|
|
38172
|
+
ref,
|
|
38173
|
+
contentEditable: true,
|
|
38174
|
+
suppressContentEditableWarning: true,
|
|
38175
|
+
role: "textbox",
|
|
38176
|
+
"aria-multiline": "true",
|
|
38177
|
+
"aria-label": t("richTextEditor.editorSurface"),
|
|
38178
|
+
"data-placeholder": placeholder ?? t("richTextEditor.placeholder"),
|
|
38179
|
+
"data-empty": empty ? "true" : "false",
|
|
38180
|
+
className: cn(
|
|
38181
|
+
"almadar-rich-text max-w-none min-h-[8rem] outline-none",
|
|
38182
|
+
"data-[empty=true]:before:content-[attr(data-placeholder)]",
|
|
38183
|
+
"data-[empty=true]:before:text-muted-foreground/60",
|
|
38184
|
+
"data-[empty=true]:before:pointer-events-none",
|
|
38185
|
+
"data-[empty=true]:before:absolute",
|
|
38186
|
+
"relative cursor-text"
|
|
38187
|
+
),
|
|
38188
|
+
onInput: afterEdit,
|
|
38189
|
+
onKeyDown: handleKeyDown,
|
|
38190
|
+
onBlur: flushEmit
|
|
38191
|
+
}
|
|
38192
|
+
)
|
|
38193
|
+
] });
|
|
37864
38194
|
};
|
|
38195
|
+
exports.RichTextEditor.displayName = "RichTextEditor";
|
|
37865
38196
|
}
|
|
37866
|
-
|
|
37867
|
-
|
|
38197
|
+
});
|
|
38198
|
+
function renderIconInput4(icon, props) {
|
|
38199
|
+
return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, ...props });
|
|
37868
38200
|
}
|
|
37869
|
-
function
|
|
38201
|
+
function DocumentPanel({
|
|
38202
|
+
id,
|
|
38203
|
+
title,
|
|
38204
|
+
subtitle,
|
|
38205
|
+
value,
|
|
38206
|
+
actions,
|
|
38207
|
+
maxInlineActions,
|
|
38208
|
+
editing = false,
|
|
38209
|
+
titleCommitEvent,
|
|
38210
|
+
contentChangeEvent,
|
|
38211
|
+
editEvent,
|
|
38212
|
+
doneEvent,
|
|
38213
|
+
editLabel,
|
|
38214
|
+
doneLabel,
|
|
38215
|
+
autosaveHint,
|
|
38216
|
+
placeholder,
|
|
38217
|
+
className
|
|
38218
|
+
}) {
|
|
38219
|
+
const eventBus = useEventBus();
|
|
37870
38220
|
const { t } = hooks.useTranslate();
|
|
37871
|
-
const [
|
|
37872
|
-
const
|
|
37873
|
-
|
|
37874
|
-
|
|
37875
|
-
|
|
37876
|
-
|
|
37877
|
-
|
|
37878
|
-
|
|
38221
|
+
const [titleDraft, setTitleDraft] = React77.useState(null);
|
|
38222
|
+
const recordId = id ?? "";
|
|
38223
|
+
const actionDefs = actions ?? [];
|
|
38224
|
+
const inlineCap = Math.min(maxInlineActions ?? 1, 1);
|
|
38225
|
+
const inlineActions = actionDefs.filter((a) => a.variant === "primary").slice(0, inlineCap);
|
|
38226
|
+
const menuActions = actionDefs.filter((a) => !inlineActions.includes(a));
|
|
38227
|
+
const fireAction = (action) => {
|
|
38228
|
+
if (!action.event) return;
|
|
38229
|
+
eventBus.emit(`UI:${action.event}`, { id: recordId, title: title ?? "" });
|
|
38230
|
+
};
|
|
38231
|
+
const commitTitle = () => {
|
|
38232
|
+
if (!titleCommitEvent) return;
|
|
38233
|
+
const next = (titleDraft ?? "").trim();
|
|
38234
|
+
setTitleDraft(null);
|
|
38235
|
+
if (!next || next === title) return;
|
|
38236
|
+
eventBus.emit(`UI:${titleCommitEvent}`, { title: next, id: recordId });
|
|
38237
|
+
};
|
|
38238
|
+
const untitled = t("documentPanel.untitled") || "Untitled";
|
|
38239
|
+
const titleNode = titleCommitEvent && titleDraft !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
38240
|
+
exports.Input,
|
|
38241
|
+
{
|
|
38242
|
+
value: titleDraft,
|
|
38243
|
+
autoFocus: true,
|
|
38244
|
+
"aria-label": t("common.title"),
|
|
38245
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
38246
|
+
onFocus: (e) => e.currentTarget.select(),
|
|
38247
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
38248
|
+
onBlur: commitTitle,
|
|
38249
|
+
onKeyDown: (e) => {
|
|
38250
|
+
if (e.key === "Enter") {
|
|
38251
|
+
e.preventDefault();
|
|
38252
|
+
commitTitle();
|
|
38253
|
+
} else if (e.key === "Escape") {
|
|
38254
|
+
e.preventDefault();
|
|
38255
|
+
setTitleDraft(null);
|
|
38256
|
+
}
|
|
38257
|
+
},
|
|
38258
|
+
"data-testid": "document-title-input"
|
|
37879
38259
|
}
|
|
37880
|
-
|
|
37881
|
-
|
|
37882
|
-
|
|
37883
|
-
|
|
37884
|
-
|
|
37885
|
-
|
|
37886
|
-
|
|
37887
|
-
{
|
|
37888
|
-
|
|
37889
|
-
|
|
37890
|
-
|
|
37891
|
-
|
|
37892
|
-
|
|
37893
|
-
|
|
37894
|
-
|
|
37895
|
-
|
|
37896
|
-
|
|
37897
|
-
|
|
37898
|
-
|
|
37899
|
-
|
|
37900
|
-
|
|
37901
|
-
|
|
37902
|
-
|
|
38260
|
+
) : titleCommitEvent ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
38261
|
+
exports.Box,
|
|
38262
|
+
{
|
|
38263
|
+
role: "button",
|
|
38264
|
+
tabIndex: 0,
|
|
38265
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
38266
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
38267
|
+
onKeyDown: (e) => {
|
|
38268
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
38269
|
+
e.preventDefault();
|
|
38270
|
+
setTitleDraft(title ?? "");
|
|
38271
|
+
}
|
|
38272
|
+
},
|
|
38273
|
+
"data-testid": "document-title-editable",
|
|
38274
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h2", weight: "bold", className: cn(!title && "text-muted-foreground"), children: title || untitled })
|
|
38275
|
+
}
|
|
38276
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "h2", weight: "bold", children: title || untitled });
|
|
38277
|
+
const emitWithId = (event) => () => {
|
|
38278
|
+
if (event) eventBus.emit(`UI:${event}`, { id: recordId });
|
|
38279
|
+
};
|
|
38280
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { variant: "elevated", className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: "p-6 sm:p-8", children: [
|
|
38281
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
38282
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
38283
|
+
titleNode,
|
|
38284
|
+
subtitle ? /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", color: "secondary", children: subtitle }) : null
|
|
38285
|
+
] }),
|
|
38286
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { gap: "xs", className: "flex-shrink-0 pt-1 items-center", children: editing ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
38287
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", className: "hidden sm:block", children: autosaveHint ?? (t("documentPanel.autosaveHint") || "") }),
|
|
38288
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "primary", size: "sm", onClick: emitWithId(doneEvent), "data-testid": "document-done", children: doneLabel ?? (t("documentPanel.done") || "Done") })
|
|
38289
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
38290
|
+
editEvent && /* @__PURE__ */ jsxRuntime.jsxs(exports.Button, { variant: "ghost", size: "sm", onClick: emitWithId(editEvent), "data-testid": "document-edit", children: [
|
|
38291
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "edit", size: "xs", className: "mr-1" }),
|
|
38292
|
+
editLabel ?? (t("documentPanel.edit") || "Edit")
|
|
38293
|
+
] }),
|
|
38294
|
+
inlineActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38295
|
+
exports.Button,
|
|
38296
|
+
{
|
|
38297
|
+
variant: "primary",
|
|
38298
|
+
size: "sm",
|
|
38299
|
+
onClick: () => fireAction(action),
|
|
38300
|
+
"data-testid": `action-${action.event}`,
|
|
38301
|
+
children: [
|
|
38302
|
+
action.icon && renderIconInput4(action.icon, { size: "xs", className: "mr-1" }),
|
|
38303
|
+
action.label
|
|
38304
|
+
]
|
|
38305
|
+
},
|
|
38306
|
+
idx
|
|
38307
|
+
)),
|
|
38308
|
+
menuActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38309
|
+
exports.Menu,
|
|
38310
|
+
{
|
|
38311
|
+
position: "bottom-end",
|
|
38312
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(exports.Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
38313
|
+
items: menuActions.map((action) => ({
|
|
38314
|
+
label: action.label,
|
|
38315
|
+
icon: action.icon,
|
|
38316
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
38317
|
+
onClick: () => fireAction(action)
|
|
38318
|
+
}))
|
|
38319
|
+
}
|
|
38320
|
+
)
|
|
38321
|
+
] }) })
|
|
38322
|
+
] }),
|
|
38323
|
+
editing ? /* @__PURE__ */ jsxRuntime.jsx(exports.RichTextEditor, { value, changeEvent: contentChangeEvent, placeholder }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
37903
38324
|
exports.Box,
|
|
37904
38325
|
{
|
|
37905
|
-
|
|
38326
|
+
onClick: emitWithId(editEvent),
|
|
37906
38327
|
className: cn(
|
|
37907
|
-
"
|
|
37908
|
-
"
|
|
37909
|
-
"py-1 text-sm"
|
|
38328
|
+
"rounded-md px-1 -mx-1 min-h-[16rem]",
|
|
38329
|
+
editEvent && "cursor-text transition-colors hover:bg-muted/30"
|
|
37910
38330
|
),
|
|
37911
|
-
|
|
37912
|
-
|
|
37913
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
37914
|
-
exports.Button,
|
|
37915
|
-
{
|
|
37916
|
-
type: "button",
|
|
37917
|
-
variant: "ghost",
|
|
37918
|
-
role: "menuitem",
|
|
37919
|
-
className: "flex w-full items-center gap-2 px-2 py-1.5 text-left justify-start rounded-none",
|
|
37920
|
-
onClick: () => {
|
|
37921
|
-
onDuplicate();
|
|
37922
|
-
setOpen(false);
|
|
37923
|
-
},
|
|
37924
|
-
children: [
|
|
37925
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "plus", className: "w-3.5 h-3.5" }),
|
|
37926
|
-
" ",
|
|
37927
|
-
t("richBlockEditor.duplicate")
|
|
37928
|
-
]
|
|
37929
|
-
}
|
|
37930
|
-
),
|
|
37931
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
37932
|
-
exports.Button,
|
|
37933
|
-
{
|
|
37934
|
-
type: "button",
|
|
37935
|
-
variant: "ghost",
|
|
37936
|
-
role: "menuitem",
|
|
37937
|
-
className: "flex w-full items-center gap-2 px-2 py-1.5 text-left text-destructive hover:bg-muted justify-start rounded-none",
|
|
37938
|
-
onClick: () => {
|
|
37939
|
-
onDelete();
|
|
37940
|
-
setOpen(false);
|
|
37941
|
-
},
|
|
37942
|
-
children: [
|
|
37943
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "trash", className: "w-3.5 h-3.5" }),
|
|
37944
|
-
" ",
|
|
37945
|
-
t("common.delete")
|
|
37946
|
-
]
|
|
37947
|
-
}
|
|
37948
|
-
),
|
|
37949
|
-
CHANGEABLE_TYPES.includes(block.type) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
37950
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "my-1 border-t border-border" }),
|
|
37951
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "px-2 py-1 text-xs uppercase tracking-wide text-muted-foreground", children: t("richBlockEditor.turnInto") }),
|
|
37952
|
-
CHANGEABLE_TYPES.filter((bt) => bt !== block.type).map((bt) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
37953
|
-
exports.Button,
|
|
37954
|
-
{
|
|
37955
|
-
type: "button",
|
|
37956
|
-
variant: "ghost",
|
|
37957
|
-
role: "menuitem",
|
|
37958
|
-
className: "flex w-full items-center gap-2 px-2 py-1.5 text-left justify-start rounded-none",
|
|
37959
|
-
onClick: () => {
|
|
37960
|
-
onChangeType(bt);
|
|
37961
|
-
setOpen(false);
|
|
37962
|
-
},
|
|
37963
|
-
children: t(BLOCK_TYPE_LABEL_KEY[bt])
|
|
37964
|
-
},
|
|
37965
|
-
bt
|
|
37966
|
-
))
|
|
37967
|
-
] })
|
|
37968
|
-
]
|
|
38331
|
+
"data-testid": "document-body",
|
|
38332
|
+
children: value && value !== "" ? /* @__PURE__ */ jsxRuntime.jsx(exports.RichTextEditor, { value, readOnly: true }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "muted", children: placeholder ?? (t("documentPanel.placeholder") || "") })
|
|
37969
38333
|
}
|
|
37970
38334
|
)
|
|
37971
|
-
] });
|
|
38335
|
+
] }) });
|
|
37972
38336
|
}
|
|
37973
|
-
|
|
37974
|
-
|
|
37975
|
-
|
|
37976
|
-
|
|
37977
|
-
|
|
37978
|
-
|
|
37979
|
-
|
|
37980
|
-
|
|
37981
|
-
|
|
37982
|
-
|
|
37983
|
-
|
|
37984
|
-
|
|
37985
|
-
|
|
37986
|
-
|
|
37987
|
-
|
|
37988
|
-
|
|
37989
|
-
|
|
37990
|
-
},
|
|
37991
|
-
const handleInput = React77.useCallback(
|
|
37992
|
-
(e) => {
|
|
37993
|
-
onValueChange(e.currentTarget.textContent ?? "");
|
|
37994
|
-
},
|
|
37995
|
-
[onValueChange]
|
|
37996
|
-
);
|
|
37997
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
37998
|
-
exports.Box,
|
|
37999
|
-
{
|
|
38000
|
-
as: tag,
|
|
38001
|
-
ref,
|
|
38002
|
-
contentEditable: !readOnly,
|
|
38003
|
-
suppressContentEditableWarning: true,
|
|
38004
|
-
role: readOnly ? void 0 : "textbox",
|
|
38005
|
-
"aria-label": ariaLabel,
|
|
38006
|
-
"aria-multiline": "true",
|
|
38007
|
-
"data-placeholder": placeholder,
|
|
38008
|
-
className: cn(
|
|
38009
|
-
"outline-none focus-visible:ring-1 focus-visible:ring-ring rounded-sm",
|
|
38010
|
-
"empty:before:content-[attr(data-placeholder)] empty:before:text-muted-foreground/60",
|
|
38011
|
-
className
|
|
38012
|
-
),
|
|
38013
|
-
onInput: handleInput
|
|
38014
|
-
}
|
|
38015
|
-
);
|
|
38337
|
+
var init_DocumentPanel = __esm({
|
|
38338
|
+
"components/core/molecules/DocumentPanel.tsx"() {
|
|
38339
|
+
"use client";
|
|
38340
|
+
init_cn();
|
|
38341
|
+
init_useEventBus();
|
|
38342
|
+
init_Box();
|
|
38343
|
+
init_Stack();
|
|
38344
|
+
init_Typography();
|
|
38345
|
+
init_Button();
|
|
38346
|
+
init_Card();
|
|
38347
|
+
init_Icon();
|
|
38348
|
+
init_Input();
|
|
38349
|
+
init_Menu();
|
|
38350
|
+
init_RichTextEditor();
|
|
38351
|
+
}
|
|
38352
|
+
});
|
|
38353
|
+
function renderIconInput5(icon, props) {
|
|
38354
|
+
return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { icon, ...props });
|
|
38016
38355
|
}
|
|
38017
|
-
function
|
|
38018
|
-
|
|
38019
|
-
|
|
38020
|
-
|
|
38021
|
-
|
|
38022
|
-
|
|
38023
|
-
|
|
38024
|
-
|
|
38025
|
-
|
|
38356
|
+
function fieldName(field) {
|
|
38357
|
+
return field.name ?? field.key ?? "";
|
|
38358
|
+
}
|
|
38359
|
+
function relationLabel(value) {
|
|
38360
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date) return null;
|
|
38361
|
+
for (const key of ["name", "title", "label"]) {
|
|
38362
|
+
const candidate = value[key];
|
|
38363
|
+
if (typeof candidate === "string" && candidate !== "") return candidate;
|
|
38364
|
+
}
|
|
38365
|
+
const id = value.id;
|
|
38366
|
+
return id !== void 0 && id !== null ? String(id) : null;
|
|
38367
|
+
}
|
|
38368
|
+
function fieldKind(field, value) {
|
|
38369
|
+
if (field.kind) return field.kind;
|
|
38370
|
+
if (field.options && field.options.length > 0) return "select";
|
|
38371
|
+
if (typeof value === "boolean" || field.format === "boolean") return "boolean";
|
|
38372
|
+
if (Array.isArray(value) || relationLabel(value ?? null) !== null) return "readonly";
|
|
38373
|
+
return "text";
|
|
38374
|
+
}
|
|
38375
|
+
function DocumentDetails({
|
|
38376
|
+
entity,
|
|
38377
|
+
fields,
|
|
38378
|
+
metaCommitEvent,
|
|
38379
|
+
title,
|
|
38380
|
+
className
|
|
38026
38381
|
}) {
|
|
38382
|
+
const eventBus = useEventBus();
|
|
38027
38383
|
const { t } = hooks.useTranslate();
|
|
38028
|
-
const
|
|
38029
|
-
|
|
38030
|
-
|
|
38031
|
-
);
|
|
38032
|
-
const
|
|
38033
|
-
(
|
|
38034
|
-
|
|
38035
|
-
|
|
38036
|
-
|
|
38037
|
-
|
|
38038
|
-
|
|
38039
|
-
|
|
38040
|
-
|
|
38041
|
-
|
|
38042
|
-
|
|
38043
|
-
|
|
38044
|
-
|
|
38045
|
-
|
|
38046
|
-
|
|
38047
|
-
|
|
38048
|
-
|
|
38049
|
-
|
|
38050
|
-
|
|
38051
|
-
|
|
38052
|
-
|
|
38053
|
-
|
|
38054
|
-
|
|
38055
|
-
|
|
38056
|
-
|
|
38057
|
-
|
|
38058
|
-
|
|
38059
|
-
|
|
38060
|
-
|
|
38061
|
-
|
|
38062
|
-
|
|
38063
|
-
|
|
38064
|
-
|
|
38065
|
-
}
|
|
38066
|
-
|
|
38067
|
-
|
|
38068
|
-
|
|
38069
|
-
|
|
38070
|
-
|
|
38071
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38072
|
-
Editable,
|
|
38073
|
-
{
|
|
38074
|
-
tag: "h1",
|
|
38075
|
-
value: block.content ?? "",
|
|
38076
|
-
readOnly,
|
|
38077
|
-
placeholder: placeholder ?? t("richBlockEditor.placeholder.heading1"),
|
|
38078
|
-
ariaLabel: t("richBlockEditor.aria.heading1Block"),
|
|
38079
|
-
className: "text-3xl font-bold leading-tight",
|
|
38080
|
-
onValueChange: setContent
|
|
38081
|
-
}
|
|
38082
|
-
);
|
|
38083
|
-
case "heading-2":
|
|
38084
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38085
|
-
Editable,
|
|
38086
|
-
{
|
|
38087
|
-
tag: "h2",
|
|
38088
|
-
value: block.content ?? "",
|
|
38089
|
-
readOnly,
|
|
38090
|
-
placeholder: placeholder ?? t("richBlockEditor.placeholder.heading2"),
|
|
38091
|
-
ariaLabel: t("richBlockEditor.aria.heading2Block"),
|
|
38092
|
-
className: "text-2xl font-semibold leading-tight",
|
|
38093
|
-
onValueChange: setContent
|
|
38094
|
-
}
|
|
38095
|
-
);
|
|
38096
|
-
case "heading-3":
|
|
38097
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38098
|
-
Editable,
|
|
38099
|
-
{
|
|
38100
|
-
tag: "h3",
|
|
38101
|
-
value: block.content ?? "",
|
|
38102
|
-
readOnly,
|
|
38103
|
-
placeholder: placeholder ?? t("richBlockEditor.placeholder.heading3"),
|
|
38104
|
-
ariaLabel: t("richBlockEditor.aria.heading3Block"),
|
|
38105
|
-
className: "text-xl font-semibold leading-tight",
|
|
38106
|
-
onValueChange: setContent
|
|
38107
|
-
}
|
|
38108
|
-
);
|
|
38109
|
-
case "quote":
|
|
38110
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38111
|
-
Editable,
|
|
38112
|
-
{
|
|
38113
|
-
tag: "blockquote",
|
|
38114
|
-
value: block.content ?? "",
|
|
38115
|
-
readOnly,
|
|
38116
|
-
placeholder: placeholder ?? t("richBlockEditor.placeholder.quote"),
|
|
38117
|
-
ariaLabel: t("richBlockEditor.aria.quoteBlock"),
|
|
38118
|
-
className: "border-l-4 border-primary/60 pl-4 italic text-muted-foreground",
|
|
38119
|
-
onValueChange: setContent
|
|
38120
|
-
}
|
|
38121
|
-
);
|
|
38122
|
-
case "code":
|
|
38123
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "rounded-md border border-border bg-muted/40", children: [
|
|
38124
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex items-center justify-between border-b border-border px-3 py-1 text-xs text-muted-foreground", children: [
|
|
38125
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", variant: "caption", className: "uppercase tracking-wide", children: t("richBlockEditor.blockType.code") }),
|
|
38126
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38127
|
-
exports.Input,
|
|
38128
|
-
{
|
|
38129
|
-
inputType: "text",
|
|
38130
|
-
value: String(block.metadata?.language ?? "plaintext"),
|
|
38131
|
-
"aria-label": t("richBlockEditor.aria.codeLanguage"),
|
|
38132
|
-
className: cn(
|
|
38133
|
-
"h-6 w-32 rounded-sm border border-border bg-background",
|
|
38134
|
-
"px-2 text-xs outline-none focus:ring-1 focus:ring-ring"
|
|
38135
|
-
),
|
|
38136
|
-
onChange: (e) => setMetadata("language", e.target.value)
|
|
38137
|
-
}
|
|
38138
|
-
),
|
|
38139
|
-
readOnly && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", variant: "caption", className: "text-xs", children: String(block.metadata?.language ?? "plaintext") })
|
|
38140
|
-
] }),
|
|
38141
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38142
|
-
Editable,
|
|
38143
|
-
{
|
|
38144
|
-
tag: "pre",
|
|
38145
|
-
value: block.content ?? "",
|
|
38146
|
-
readOnly,
|
|
38147
|
-
placeholder: placeholder ?? t("richBlockEditor.placeholder.code"),
|
|
38148
|
-
ariaLabel: t("richBlockEditor.aria.codeBlock"),
|
|
38149
|
-
className: "block whitespace-pre-wrap p-3 font-mono text-sm leading-relaxed",
|
|
38150
|
-
onValueChange: setContent
|
|
38151
|
-
}
|
|
38152
|
-
)
|
|
38153
|
-
] });
|
|
38154
|
-
case "divider":
|
|
38155
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { className: "my-2" });
|
|
38156
|
-
case "image": {
|
|
38157
|
-
const url = String(block.metadata?.url ?? "");
|
|
38158
|
-
const caption = String(block.metadata?.caption ?? "");
|
|
38159
|
-
const imgProps = {
|
|
38160
|
-
src: url,
|
|
38161
|
-
alt: caption || t("richBlockEditor.embeddedImage"),
|
|
38162
|
-
className: "max-h-96 w-full rounded-md border border-border object-contain"
|
|
38163
|
-
};
|
|
38164
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "space-y-2", children: [
|
|
38165
|
-
url ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { as: "img", ...imgProps }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38166
|
-
exports.Box,
|
|
38167
|
-
{
|
|
38168
|
-
className: cn(
|
|
38169
|
-
"flex h-32 items-center justify-center",
|
|
38170
|
-
"rounded-md border border-dashed border-border",
|
|
38171
|
-
"text-sm text-muted-foreground"
|
|
38172
|
-
),
|
|
38173
|
-
children: [
|
|
38174
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "image", className: "mr-2 w-4 h-4" }),
|
|
38175
|
-
" ",
|
|
38176
|
-
t("richBlockEditor.noImageUrl")
|
|
38177
|
-
]
|
|
38178
|
-
}
|
|
38179
|
-
),
|
|
38180
|
-
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex flex-col gap-2 sm:flex-row", children: [
|
|
38181
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38182
|
-
exports.Input,
|
|
38183
|
-
{
|
|
38184
|
-
inputType: "url",
|
|
38185
|
-
value: url,
|
|
38186
|
-
placeholder: "https://example.com/image.png",
|
|
38187
|
-
"aria-label": t("richBlockEditor.aria.imageUrl"),
|
|
38188
|
-
className: cn(
|
|
38189
|
-
"h-8 flex-1 rounded-sm border border-border bg-background",
|
|
38190
|
-
"px-2 text-sm outline-none focus:ring-1 focus:ring-ring"
|
|
38191
|
-
),
|
|
38192
|
-
onChange: (e) => setMetadata("url", e.target.value)
|
|
38193
|
-
}
|
|
38194
|
-
),
|
|
38195
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38196
|
-
exports.Input,
|
|
38197
|
-
{
|
|
38198
|
-
inputType: "text",
|
|
38199
|
-
value: caption,
|
|
38200
|
-
placeholder: t("richBlockEditor.placeholder.caption"),
|
|
38201
|
-
"aria-label": t("richBlockEditor.aria.imageCaption"),
|
|
38202
|
-
className: cn(
|
|
38203
|
-
"h-8 flex-1 rounded-sm border border-border bg-background",
|
|
38204
|
-
"px-2 text-sm outline-none focus:ring-1 focus:ring-ring"
|
|
38205
|
-
),
|
|
38206
|
-
onChange: (e) => setMetadata("caption", e.target.value)
|
|
38207
|
-
}
|
|
38208
|
-
)
|
|
38209
|
-
] }),
|
|
38210
|
-
readOnly && caption && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", className: "text-center text-muted-foreground", children: caption })
|
|
38211
|
-
] });
|
|
38384
|
+
const [fieldDraft, setFieldDraft] = React77.useState(null);
|
|
38385
|
+
const recordId = entity?.id !== void 0 && entity?.id !== null ? String(entity.id) : "";
|
|
38386
|
+
const fieldDefs = (fields ?? []).filter((f3) => fieldName(f3) !== "");
|
|
38387
|
+
if (fieldDefs.length === 0) return null;
|
|
38388
|
+
const commitField = (name, next, current) => {
|
|
38389
|
+
setFieldDraft(null);
|
|
38390
|
+
if (!metaCommitEvent || next === current) return;
|
|
38391
|
+
eventBus.emit(`UI:${metaCommitEvent}`, { id: recordId, patch: { id: recordId, [name]: next } });
|
|
38392
|
+
};
|
|
38393
|
+
const renderValue = (field) => {
|
|
38394
|
+
const name = fieldName(field);
|
|
38395
|
+
const raw = getNestedValue(entity ?? {}, name);
|
|
38396
|
+
const kind = fieldKind(field, raw);
|
|
38397
|
+
const label = field.label ?? field.header ?? humanizeFieldName(name);
|
|
38398
|
+
if (kind === "boolean") {
|
|
38399
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38400
|
+
exports.Switch,
|
|
38401
|
+
{
|
|
38402
|
+
checked: Boolean(raw),
|
|
38403
|
+
disabled: !metaCommitEvent,
|
|
38404
|
+
"aria-label": label,
|
|
38405
|
+
onChange: (checked) => commitField(name, checked, Boolean(raw))
|
|
38406
|
+
}
|
|
38407
|
+
);
|
|
38408
|
+
}
|
|
38409
|
+
if (kind === "select") {
|
|
38410
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38411
|
+
exports.Select,
|
|
38412
|
+
{
|
|
38413
|
+
value: raw !== void 0 && raw !== null ? String(raw) : "",
|
|
38414
|
+
disabled: !metaCommitEvent,
|
|
38415
|
+
"aria-label": label,
|
|
38416
|
+
className: "h-8 w-full",
|
|
38417
|
+
options: (field.options ?? []).map((opt) => ({ value: opt, label: humanizeEnumValue(opt) })),
|
|
38418
|
+
onChange: (e) => commitField(name, e.target.value, raw)
|
|
38419
|
+
}
|
|
38420
|
+
);
|
|
38421
|
+
}
|
|
38422
|
+
if (kind === "readonly" || !metaCommitEvent) {
|
|
38423
|
+
if (Array.isArray(raw)) {
|
|
38424
|
+
if (raw.length === 0) {
|
|
38425
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", color: "secondary", children: "\u2014" });
|
|
38426
|
+
}
|
|
38427
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { gap: "xs", className: "flex-wrap", children: raw.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: "default", children: relationLabel(item) ?? humanizeEnumValue(String(item)) }, i)) });
|
|
38212
38428
|
}
|
|
38213
|
-
|
|
38214
|
-
|
|
38215
|
-
|
|
38216
|
-
|
|
38217
|
-
|
|
38218
|
-
|
|
38219
|
-
|
|
38220
|
-
|
|
38221
|
-
|
|
38222
|
-
|
|
38223
|
-
|
|
38224
|
-
|
|
38225
|
-
|
|
38226
|
-
|
|
38227
|
-
|
|
38228
|
-
|
|
38229
|
-
|
|
38230
|
-
|
|
38231
|
-
|
|
38232
|
-
|
|
38233
|
-
|
|
38234
|
-
|
|
38235
|
-
|
|
38236
|
-
|
|
38237
|
-
|
|
38238
|
-
|
|
38239
|
-
|
|
38240
|
-
|
|
38241
|
-
|
|
38242
|
-
|
|
38243
|
-
|
|
38244
|
-
|
|
38245
|
-
|
|
38246
|
-
|
|
38247
|
-
|
|
38248
|
-
|
|
38249
|
-
|
|
38250
|
-
|
|
38251
|
-
|
|
38252
|
-
|
|
38253
|
-
|
|
38254
|
-
exports.Button,
|
|
38255
|
-
{
|
|
38256
|
-
type: "button",
|
|
38257
|
-
variant: "ghost",
|
|
38258
|
-
className: cn(
|
|
38259
|
-
"inline-flex items-center gap-1 text-xs text-muted-foreground",
|
|
38260
|
-
"hover:text-foreground p-0 h-auto"
|
|
38261
|
-
),
|
|
38262
|
-
onClick: addListItem,
|
|
38263
|
-
children: [
|
|
38264
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "plus", className: "w-3 h-3" }),
|
|
38265
|
-
" ",
|
|
38266
|
-
t("richBlockEditor.addItem")
|
|
38267
|
-
]
|
|
38268
|
-
}
|
|
38269
|
-
) })
|
|
38270
|
-
]
|
|
38429
|
+
const shown2 = raw === void 0 || raw === null || raw === "" ? "\u2014" : relationLabel(raw) ?? formatValue(raw, field.format);
|
|
38430
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", className: "break-words", children: shown2 });
|
|
38431
|
+
}
|
|
38432
|
+
if (fieldDraft?.name === name) {
|
|
38433
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38434
|
+
exports.Input,
|
|
38435
|
+
{
|
|
38436
|
+
value: fieldDraft.value,
|
|
38437
|
+
autoFocus: true,
|
|
38438
|
+
"aria-label": label,
|
|
38439
|
+
className: "h-8 w-full",
|
|
38440
|
+
onChange: (e) => setFieldDraft({ name, value: e.target.value }),
|
|
38441
|
+
onBlur: () => commitField(name, fieldDraft.value.trim(), raw),
|
|
38442
|
+
onKeyDown: (e) => {
|
|
38443
|
+
if (e.key === "Enter") {
|
|
38444
|
+
e.preventDefault();
|
|
38445
|
+
commitField(name, fieldDraft.value.trim(), raw);
|
|
38446
|
+
} else if (e.key === "Escape") {
|
|
38447
|
+
e.preventDefault();
|
|
38448
|
+
setFieldDraft(null);
|
|
38449
|
+
}
|
|
38450
|
+
},
|
|
38451
|
+
"data-testid": `document-property-input-${name}`
|
|
38452
|
+
}
|
|
38453
|
+
);
|
|
38454
|
+
}
|
|
38455
|
+
const shown = raw === void 0 || raw === null || raw === "" ? "\u2014" : relationLabel(raw) ?? formatValue(raw, field.format);
|
|
38456
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38457
|
+
exports.Box,
|
|
38458
|
+
{
|
|
38459
|
+
role: "button",
|
|
38460
|
+
tabIndex: 0,
|
|
38461
|
+
className: cn(
|
|
38462
|
+
"cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
38463
|
+
(raw === void 0 || raw === null || raw === "") && "text-muted-foreground"
|
|
38464
|
+
),
|
|
38465
|
+
onClick: () => setFieldDraft({ name, value: raw !== void 0 && raw !== null ? String(raw) : "" }),
|
|
38466
|
+
onKeyDown: (e) => {
|
|
38467
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
38468
|
+
e.preventDefault();
|
|
38469
|
+
setFieldDraft({ name, value: raw !== void 0 && raw !== null ? String(raw) : "" });
|
|
38271
38470
|
}
|
|
38272
|
-
|
|
38471
|
+
},
|
|
38472
|
+
"data-testid": `document-property-${name}`,
|
|
38473
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "small", className: "break-words", children: shown })
|
|
38273
38474
|
}
|
|
38274
|
-
|
|
38275
|
-
default:
|
|
38276
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38277
|
-
Editable,
|
|
38278
|
-
{
|
|
38279
|
-
tag: "p",
|
|
38280
|
-
value: block.content ?? "",
|
|
38281
|
-
readOnly,
|
|
38282
|
-
placeholder: placeholder ?? t("richBlockEditor.placeholder.paragraph"),
|
|
38283
|
-
ariaLabel: t("richBlockEditor.aria.paragraphBlock"),
|
|
38284
|
-
className: "leading-7",
|
|
38285
|
-
onValueChange: setContent
|
|
38286
|
-
}
|
|
38287
|
-
);
|
|
38288
|
-
}
|
|
38475
|
+
);
|
|
38289
38476
|
};
|
|
38290
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38291
|
-
exports.
|
|
38292
|
-
{
|
|
38293
|
-
|
|
38294
|
-
|
|
38295
|
-
|
|
38296
|
-
|
|
38297
|
-
|
|
38298
|
-
|
|
38299
|
-
|
|
38300
|
-
|
|
38301
|
-
|
|
38302
|
-
|
|
38303
|
-
|
|
38304
|
-
readOnly,
|
|
38305
|
-
onDelete,
|
|
38306
|
-
onDuplicate,
|
|
38307
|
-
onChangeType
|
|
38308
|
-
}
|
|
38309
|
-
) }),
|
|
38310
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "min-w-0 flex-1", children: renderBody() })
|
|
38311
|
-
]
|
|
38312
|
-
}
|
|
38313
|
-
);
|
|
38477
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Card, { variant: "bordered", className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "sm", className: "p-4", children: [
|
|
38478
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "secondary", weight: "medium", className: "uppercase tracking-wide", children: title ?? (t("documentDetails.title") || "Details") }),
|
|
38479
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.VStack, { gap: "sm", children: fieldDefs.map((field) => {
|
|
38480
|
+
const name = fieldName(field);
|
|
38481
|
+
const label = field.label ?? field.header ?? humanizeFieldName(name);
|
|
38482
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", children: [
|
|
38483
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", className: "items-center", children: [
|
|
38484
|
+
field.icon && renderIconInput5(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
38485
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: label })
|
|
38486
|
+
] }),
|
|
38487
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "min-w-0", children: renderValue(field) })
|
|
38488
|
+
] }, name);
|
|
38489
|
+
}) })
|
|
38490
|
+
] }) });
|
|
38314
38491
|
}
|
|
38315
|
-
var
|
|
38316
|
-
|
|
38317
|
-
"components/core/molecules/RichBlockEditor.tsx"() {
|
|
38492
|
+
var init_DocumentDetails = __esm({
|
|
38493
|
+
"components/core/molecules/DocumentDetails.tsx"() {
|
|
38318
38494
|
"use client";
|
|
38319
38495
|
init_cn();
|
|
38320
|
-
|
|
38321
|
-
|
|
38322
|
-
|
|
38496
|
+
init_format();
|
|
38497
|
+
init_getNestedValue();
|
|
38498
|
+
init_useEventBus();
|
|
38323
38499
|
init_Box();
|
|
38324
|
-
|
|
38325
|
-
|
|
38500
|
+
init_Stack();
|
|
38501
|
+
init_Typography();
|
|
38502
|
+
init_Badge();
|
|
38503
|
+
init_Card();
|
|
38326
38504
|
init_Icon();
|
|
38327
|
-
|
|
38328
|
-
|
|
38329
|
-
|
|
38330
|
-
{ type: "heading-1", labelKey: "richBlockEditor.toolbar.h1", icon: LucideIcons2.Heading1 },
|
|
38331
|
-
{ type: "heading-2", labelKey: "richBlockEditor.toolbar.h2", icon: LucideIcons2.Heading2 },
|
|
38332
|
-
{ type: "heading-3", labelKey: "richBlockEditor.toolbar.h3", icon: LucideIcons2.Heading3 },
|
|
38333
|
-
{ type: "bullet-list", labelKey: "richBlockEditor.toolbar.bulletList", icon: LucideIcons2.List },
|
|
38334
|
-
{ type: "numbered-list", labelKey: "richBlockEditor.toolbar.numbered", icon: LucideIcons2.ListOrdered },
|
|
38335
|
-
{ type: "quote", labelKey: "richBlockEditor.toolbar.quote", icon: LucideIcons2.Quote },
|
|
38336
|
-
{ type: "code", labelKey: "richBlockEditor.toolbar.code", icon: LucideIcons2.Code },
|
|
38337
|
-
{ type: "divider", labelKey: "richBlockEditor.toolbar.divider", icon: LucideIcons2.Minus },
|
|
38338
|
-
{ type: "image", labelKey: "richBlockEditor.toolbar.image", icon: LucideIcons2.Image }
|
|
38339
|
-
];
|
|
38340
|
-
BLOCK_TYPE_LABEL_KEY = {
|
|
38341
|
-
paragraph: "richBlockEditor.blockType.paragraph",
|
|
38342
|
-
"heading-1": "richBlockEditor.blockType.heading1",
|
|
38343
|
-
"heading-2": "richBlockEditor.blockType.heading2",
|
|
38344
|
-
"heading-3": "richBlockEditor.blockType.heading3",
|
|
38345
|
-
"bullet-list": "richBlockEditor.blockType.bulletList",
|
|
38346
|
-
"numbered-list": "richBlockEditor.blockType.numberedList",
|
|
38347
|
-
quote: "richBlockEditor.blockType.quote",
|
|
38348
|
-
code: "richBlockEditor.blockType.code",
|
|
38349
|
-
divider: "richBlockEditor.blockType.divider",
|
|
38350
|
-
image: "richBlockEditor.blockType.image"
|
|
38351
|
-
};
|
|
38352
|
-
CHANGEABLE_TYPES = [
|
|
38353
|
-
"paragraph",
|
|
38354
|
-
"heading-1",
|
|
38355
|
-
"heading-2",
|
|
38356
|
-
"heading-3",
|
|
38357
|
-
"bullet-list",
|
|
38358
|
-
"numbered-list",
|
|
38359
|
-
"quote",
|
|
38360
|
-
"code"
|
|
38361
|
-
];
|
|
38362
|
-
_idSeq = 0;
|
|
38363
|
-
BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
38364
|
-
"paragraph",
|
|
38365
|
-
"heading-1",
|
|
38366
|
-
"heading-2",
|
|
38367
|
-
"heading-3",
|
|
38368
|
-
"bullet-list",
|
|
38369
|
-
"numbered-list",
|
|
38370
|
-
"quote",
|
|
38371
|
-
"code",
|
|
38372
|
-
"divider",
|
|
38373
|
-
"image"
|
|
38374
|
-
]);
|
|
38375
|
-
exports.RichBlockEditor = ({
|
|
38376
|
-
initialBlocks,
|
|
38377
|
-
onChange,
|
|
38378
|
-
changeEvent,
|
|
38379
|
-
readOnly = false,
|
|
38380
|
-
placeholder,
|
|
38381
|
-
enableBlocks = true,
|
|
38382
|
-
showToolbar = true,
|
|
38383
|
-
className
|
|
38384
|
-
}) => {
|
|
38385
|
-
const { t } = hooks.useTranslate();
|
|
38386
|
-
const [blocks, setBlocks] = React77.useState(
|
|
38387
|
-
() => normalizeBlocks(initialBlocks)
|
|
38388
|
-
);
|
|
38389
|
-
const onChangeRef = React77.useRef(onChange);
|
|
38390
|
-
React77.useEffect(() => {
|
|
38391
|
-
onChangeRef.current = onChange;
|
|
38392
|
-
}, [onChange]);
|
|
38393
|
-
const eventBus = useEventBus();
|
|
38394
|
-
const changeEventRef = React77.useRef(changeEvent);
|
|
38395
|
-
React77.useEffect(() => {
|
|
38396
|
-
changeEventRef.current = changeEvent;
|
|
38397
|
-
}, [changeEvent]);
|
|
38398
|
-
const commit = React77.useCallback((next) => {
|
|
38399
|
-
setBlocks(next);
|
|
38400
|
-
onChangeRef.current?.(next);
|
|
38401
|
-
const evt = changeEventRef.current;
|
|
38402
|
-
if (evt) eventBus.emit(`UI:${evt}`, { blocks: next });
|
|
38403
|
-
}, [eventBus]);
|
|
38404
|
-
const handleAppend = React77.useCallback(
|
|
38405
|
-
(type) => {
|
|
38406
|
-
if (readOnly) return;
|
|
38407
|
-
commit([...blocks, createBlock(type)]);
|
|
38408
|
-
},
|
|
38409
|
-
[blocks, commit, readOnly]
|
|
38410
|
-
);
|
|
38411
|
-
const handleUpdate = React77.useCallback(
|
|
38412
|
-
(id, updater) => {
|
|
38413
|
-
commit(replaceBlock(blocks, id, updater));
|
|
38414
|
-
},
|
|
38415
|
-
[blocks, commit]
|
|
38416
|
-
);
|
|
38417
|
-
const handleDelete = React77.useCallback(
|
|
38418
|
-
(id) => {
|
|
38419
|
-
const next = removeBlock(blocks, id);
|
|
38420
|
-
commit(next.length > 0 ? next : [createBlock("paragraph")]);
|
|
38421
|
-
},
|
|
38422
|
-
[blocks, commit]
|
|
38423
|
-
);
|
|
38424
|
-
const handleDuplicate = React77.useCallback(
|
|
38425
|
-
(id) => {
|
|
38426
|
-
const target = blocks.find((b) => b.id === id);
|
|
38427
|
-
if (!target) return;
|
|
38428
|
-
commit(insertAfter(blocks, id, duplicateBlock(target)));
|
|
38429
|
-
},
|
|
38430
|
-
[blocks, commit]
|
|
38431
|
-
);
|
|
38432
|
-
const handleChangeType = React77.useCallback(
|
|
38433
|
-
(id, type) => {
|
|
38434
|
-
commit(
|
|
38435
|
-
replaceBlock(blocks, id, (b) => changeBlockType(b, type))
|
|
38436
|
-
);
|
|
38437
|
-
},
|
|
38438
|
-
[blocks, commit]
|
|
38439
|
-
);
|
|
38440
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38441
|
-
exports.Card,
|
|
38442
|
-
{
|
|
38443
|
-
variant: "bordered",
|
|
38444
|
-
padding: "none",
|
|
38445
|
-
className: cn("flex flex-col text-card-foreground", className),
|
|
38446
|
-
children: [
|
|
38447
|
-
enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38448
|
-
exports.Box,
|
|
38449
|
-
{
|
|
38450
|
-
role: "toolbar",
|
|
38451
|
-
"aria-label": t("richBlockEditor.editorToolbar"),
|
|
38452
|
-
className: cn(
|
|
38453
|
-
"flex flex-wrap items-center gap-1",
|
|
38454
|
-
"border-b border-border bg-muted/30 px-2 py-2"
|
|
38455
|
-
),
|
|
38456
|
-
children: TOOLBAR_ENTRIES.map((entry) => {
|
|
38457
|
-
const Icon2 = entry.icon;
|
|
38458
|
-
const entryLabel = t(entry.labelKey);
|
|
38459
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38460
|
-
exports.Button,
|
|
38461
|
-
{
|
|
38462
|
-
type: "button",
|
|
38463
|
-
variant: "ghost",
|
|
38464
|
-
size: "sm",
|
|
38465
|
-
"aria-label": t("richBlockEditor.insertEntry", { label: entryLabel }),
|
|
38466
|
-
title: entryLabel,
|
|
38467
|
-
onClick: () => handleAppend(entry.type),
|
|
38468
|
-
children: [
|
|
38469
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon2, { size: 14 }),
|
|
38470
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", variant: "caption", className: "ml-1 hidden text-xs sm:inline", children: entryLabel })
|
|
38471
|
-
]
|
|
38472
|
-
},
|
|
38473
|
-
entry.type
|
|
38474
|
-
);
|
|
38475
|
-
})
|
|
38476
|
-
}
|
|
38477
|
-
),
|
|
38478
|
-
/* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex flex-col gap-1 px-3 py-3", children: blocks.map((block) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
38479
|
-
BlockRow,
|
|
38480
|
-
{
|
|
38481
|
-
block,
|
|
38482
|
-
readOnly,
|
|
38483
|
-
showAffordances: enableBlocks,
|
|
38484
|
-
placeholder,
|
|
38485
|
-
onUpdate: (updater) => handleUpdate(block.id, updater),
|
|
38486
|
-
onDelete: () => handleDelete(block.id),
|
|
38487
|
-
onDuplicate: () => handleDuplicate(block.id),
|
|
38488
|
-
onChangeType: (type) => handleChangeType(block.id, type)
|
|
38489
|
-
},
|
|
38490
|
-
block.id
|
|
38491
|
-
)) })
|
|
38492
|
-
]
|
|
38493
|
-
}
|
|
38494
|
-
);
|
|
38495
|
-
};
|
|
38496
|
-
exports.RichBlockEditor.displayName = "RichBlockEditor";
|
|
38505
|
+
init_Input();
|
|
38506
|
+
init_Select();
|
|
38507
|
+
init_Switch();
|
|
38497
38508
|
}
|
|
38498
38509
|
});
|
|
38499
38510
|
function collectInitiallyCollapsed(nodes, acc) {
|
|
@@ -43167,7 +43178,9 @@ var init_molecules2 = __esm({
|
|
|
43167
43178
|
init_QrScanner();
|
|
43168
43179
|
init_OptionConstraintGroup();
|
|
43169
43180
|
init_PositionedCanvas();
|
|
43170
|
-
|
|
43181
|
+
init_RichTextEditor();
|
|
43182
|
+
init_DocumentPanel();
|
|
43183
|
+
init_DocumentDetails();
|
|
43171
43184
|
init_ReplyTree();
|
|
43172
43185
|
init_BranchingLogicBuilder();
|
|
43173
43186
|
init_VersionDiff();
|
|
@@ -43667,8 +43680,8 @@ var init_DataTable = __esm({
|
|
|
43667
43680
|
DataTable.displayName = "DataTable";
|
|
43668
43681
|
}
|
|
43669
43682
|
});
|
|
43670
|
-
function getBadgeVariant(
|
|
43671
|
-
const name =
|
|
43683
|
+
function getBadgeVariant(fieldName2, value) {
|
|
43684
|
+
const name = fieldName2.toLowerCase();
|
|
43672
43685
|
const val = String(value).toLowerCase();
|
|
43673
43686
|
if (name.includes("status")) {
|
|
43674
43687
|
if (val.includes("complete") || val.includes("done") || val.includes("active"))
|
|
@@ -43684,12 +43697,12 @@ function getBadgeVariant(fieldName, value) {
|
|
|
43684
43697
|
}
|
|
43685
43698
|
return "default";
|
|
43686
43699
|
}
|
|
43687
|
-
function formatFieldValue2(value,
|
|
43700
|
+
function formatFieldValue2(value, fieldName2) {
|
|
43688
43701
|
if (typeof value === "number") {
|
|
43689
|
-
if (
|
|
43702
|
+
if (fieldName2.toLowerCase().includes("progress") || fieldName2.toLowerCase().includes("percent")) {
|
|
43690
43703
|
return `${value}%`;
|
|
43691
43704
|
}
|
|
43692
|
-
if (
|
|
43705
|
+
if (fieldName2.toLowerCase().includes("budget") || fieldName2.toLowerCase().includes("cost")) {
|
|
43693
43706
|
return `$${value.toLocaleString()}`;
|
|
43694
43707
|
}
|
|
43695
43708
|
return value.toLocaleString();
|
|
@@ -43699,7 +43712,7 @@ function formatFieldValue2(value, fieldName) {
|
|
|
43699
43712
|
}
|
|
43700
43713
|
return String(value);
|
|
43701
43714
|
}
|
|
43702
|
-
function renderRichFieldValue(value,
|
|
43715
|
+
function renderRichFieldValue(value, fieldName2, fieldType, meta) {
|
|
43703
43716
|
if (value === void 0 || value === null) return "\u2014";
|
|
43704
43717
|
const str2 = String(value);
|
|
43705
43718
|
switch (fieldType) {
|
|
@@ -43710,7 +43723,7 @@ function renderRichFieldValue(value, fieldName, fieldType, meta) {
|
|
|
43710
43723
|
"img",
|
|
43711
43724
|
{
|
|
43712
43725
|
src: str2,
|
|
43713
|
-
alt: formatFieldLabel(
|
|
43726
|
+
alt: formatFieldLabel(fieldName2),
|
|
43714
43727
|
className: "max-w-full max-h-64 rounded-md object-contain",
|
|
43715
43728
|
loading: "lazy"
|
|
43716
43729
|
}
|
|
@@ -43845,9 +43858,9 @@ function renderRichFieldValue(value, fieldName, fieldType, meta) {
|
|
|
43845
43858
|
return /* @__PURE__ */ jsxRuntime.jsx("a", { href: `tel:${str2}`, className: "text-primary hover:underline", children: str2 });
|
|
43846
43859
|
default:
|
|
43847
43860
|
if (meta?.values && meta.values.length > 0 && meta.values.includes(str2)) {
|
|
43848
|
-
return /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: getBadgeVariant(
|
|
43861
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: getBadgeVariant(fieldName2, str2), children: humanizeEnumValue(str2) });
|
|
43849
43862
|
}
|
|
43850
|
-
return formatFieldValue2(value,
|
|
43863
|
+
return formatFieldValue2(value, fieldName2);
|
|
43851
43864
|
}
|
|
43852
43865
|
}
|
|
43853
43866
|
function normalizeFieldDefs(fields) {
|
|
@@ -44690,7 +44703,21 @@ var init_Form = __esm({
|
|
|
44690
44703
|
const normalizedInitialData = React77__namespace.default.useMemo(() => {
|
|
44691
44704
|
const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
|
|
44692
44705
|
const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
|
|
44693
|
-
|
|
44706
|
+
const merged = entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
|
|
44707
|
+
const toId = (value) => {
|
|
44708
|
+
if (value === null || value === void 0 || typeof value !== "object" || value instanceof Date) return value;
|
|
44709
|
+
if (Array.isArray(value)) {
|
|
44710
|
+
return value.map(
|
|
44711
|
+
(item) => item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && item.id !== void 0 && item.id !== null ? String(item.id) : item
|
|
44712
|
+
);
|
|
44713
|
+
}
|
|
44714
|
+
return value.id !== void 0 && value.id !== null ? String(value.id) : value;
|
|
44715
|
+
};
|
|
44716
|
+
const normalized = {};
|
|
44717
|
+
for (const [key, value] of Object.entries(merged)) {
|
|
44718
|
+
normalized[key] = key === "id" ? value : toId(value);
|
|
44719
|
+
}
|
|
44720
|
+
return normalized;
|
|
44694
44721
|
}, [entity, initialData]);
|
|
44695
44722
|
const entityDerivedFields = React77__namespace.default.useMemo(() => {
|
|
44696
44723
|
if (fields && fields.length > 0) return void 0;
|
|
@@ -44819,8 +44846,8 @@ var init_Form = __esm({
|
|
|
44819
44846
|
checkViolations(name, newFormData);
|
|
44820
44847
|
};
|
|
44821
44848
|
const isFieldVisible = React77__namespace.default.useCallback(
|
|
44822
|
-
(
|
|
44823
|
-
const condition = conditionalFields[
|
|
44849
|
+
(fieldName2) => {
|
|
44850
|
+
const condition = conditionalFields[fieldName2];
|
|
44824
44851
|
if (!condition) return true;
|
|
44825
44852
|
return Boolean(evaluateFormExpression(condition, evalContext));
|
|
44826
44853
|
},
|
|
@@ -44866,9 +44893,9 @@ var init_Form = __esm({
|
|
|
44866
44893
|
};
|
|
44867
44894
|
const handleInvalid = (e) => {
|
|
44868
44895
|
const target = e.target;
|
|
44869
|
-
const
|
|
44896
|
+
const fieldName2 = target.getAttribute("data-field-name") ?? target.name ?? "";
|
|
44870
44897
|
const fieldMessage = target.validationMessage || "Invalid value";
|
|
44871
|
-
debug("forms", "invalid", { mode: formMode, fieldName, fieldMessage });
|
|
44898
|
+
debug("forms", "invalid", { mode: formMode, fieldName: fieldName2, fieldMessage });
|
|
44872
44899
|
queueMicrotask(() => {
|
|
44873
44900
|
const form = formRef.current;
|
|
44874
44901
|
if (!form) return;
|
|
@@ -44904,22 +44931,22 @@ var init_Form = __esm({
|
|
|
44904
44931
|
};
|
|
44905
44932
|
const renderField = React77__namespace.default.useCallback(
|
|
44906
44933
|
(field) => {
|
|
44907
|
-
const
|
|
44908
|
-
if (!
|
|
44909
|
-
if (!isFieldVisible(
|
|
44934
|
+
const fieldName2 = field.name || field.field;
|
|
44935
|
+
if (!fieldName2) return null;
|
|
44936
|
+
if (!isFieldVisible(fieldName2)) {
|
|
44910
44937
|
return null;
|
|
44911
44938
|
}
|
|
44912
44939
|
const inputType = determineInputType(field);
|
|
44913
|
-
const label = field.label ||
|
|
44914
|
-
const currentValue2 = formData[
|
|
44915
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", "data-field":
|
|
44940
|
+
const label = field.label || fieldName2.charAt(0).toUpperCase() + fieldName2.slice(1).replace(/([A-Z])/g, " $1");
|
|
44941
|
+
const currentValue2 = formData[fieldName2] ?? field.defaultValue ?? "";
|
|
44942
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(exports.VStack, { gap: "xs", "data-field": fieldName2, children: [
|
|
44916
44943
|
inputType !== "checkbox" && /* @__PURE__ */ jsxRuntime.jsxs(exports.Typography, { as: "label", variant: "label", weight: "bold", children: [
|
|
44917
44944
|
label,
|
|
44918
44945
|
field.required && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { as: "span", color: "error", className: "ml-1", children: "*" })
|
|
44919
44946
|
] }),
|
|
44920
|
-
renderFieldInput(field,
|
|
44947
|
+
renderFieldInput(field, fieldName2, inputType, currentValue2, label),
|
|
44921
44948
|
field.hint && /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "caption", color: "muted", children: field.hint })
|
|
44922
|
-
] },
|
|
44949
|
+
] }, fieldName2);
|
|
44923
44950
|
},
|
|
44924
44951
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
44925
44952
|
);
|
|
@@ -44948,8 +44975,8 @@ var init_Form = __esm({
|
|
|
44948
44975
|
}
|
|
44949
44976
|
return field;
|
|
44950
44977
|
}).map((field) => {
|
|
44951
|
-
const
|
|
44952
|
-
const override = fieldOverrides?.find((o) => o.name ===
|
|
44978
|
+
const fieldName2 = field.name || field.field;
|
|
44979
|
+
const override = fieldOverrides?.find((o) => o.name === fieldName2);
|
|
44953
44980
|
if (!override) return field;
|
|
44954
44981
|
return {
|
|
44955
44982
|
...field,
|
|
@@ -45005,11 +45032,11 @@ var init_Form = __esm({
|
|
|
45005
45032
|
] }, section.id);
|
|
45006
45033
|
}).filter(Boolean);
|
|
45007
45034
|
}, [sections, isSectionVisible, collapsedSections, renderField, gap]);
|
|
45008
|
-
function renderFieldInput(field,
|
|
45035
|
+
function renderFieldInput(field, fieldName2, inputType, currentValue2, label) {
|
|
45009
45036
|
const commonProps = {
|
|
45010
|
-
id:
|
|
45011
|
-
name:
|
|
45012
|
-
"data-field-name":
|
|
45037
|
+
id: fieldName2,
|
|
45038
|
+
name: fieldName2,
|
|
45039
|
+
"data-field-name": fieldName2,
|
|
45013
45040
|
required: field.required,
|
|
45014
45041
|
disabled: isLoading,
|
|
45015
45042
|
placeholder: field.placeholder,
|
|
@@ -45023,7 +45050,7 @@ var init_Form = __esm({
|
|
|
45023
45050
|
...commonProps,
|
|
45024
45051
|
label: label + (field.required ? " *" : ""),
|
|
45025
45052
|
checked: Boolean(currentValue2),
|
|
45026
|
-
onChange: (e) => handleChange(
|
|
45053
|
+
onChange: (e) => handleChange(fieldName2, e.target.checked)
|
|
45027
45054
|
}
|
|
45028
45055
|
);
|
|
45029
45056
|
case "textarea":
|
|
@@ -45032,7 +45059,7 @@ var init_Form = __esm({
|
|
|
45032
45059
|
{
|
|
45033
45060
|
...commonProps,
|
|
45034
45061
|
value: String(currentValue2),
|
|
45035
|
-
onChange: (e) => handleChange(
|
|
45062
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45036
45063
|
minLength: field.min,
|
|
45037
45064
|
maxLength: field.max
|
|
45038
45065
|
}
|
|
@@ -45045,14 +45072,14 @@ var init_Form = __esm({
|
|
|
45045
45072
|
...commonProps,
|
|
45046
45073
|
options,
|
|
45047
45074
|
value: String(currentValue2),
|
|
45048
|
-
onValueChange: (v) => handleChange(
|
|
45075
|
+
onValueChange: (v) => handleChange(fieldName2, v),
|
|
45049
45076
|
placeholder: field.placeholder || `Select ${label}...`
|
|
45050
45077
|
}
|
|
45051
45078
|
);
|
|
45052
45079
|
}
|
|
45053
45080
|
case "relation": {
|
|
45054
|
-
const relationOptions = relationsData[
|
|
45055
|
-
const relationLoading = relationsLoading[
|
|
45081
|
+
const relationOptions = relationsData[fieldName2] || [];
|
|
45082
|
+
const relationLoading = relationsLoading[fieldName2] || false;
|
|
45056
45083
|
if (field.relation?.cardinality !== void 0 && MANY_CARDINALITIES.includes(field.relation.cardinality)) {
|
|
45057
45084
|
const selectedValues = Array.isArray(currentValue2) ? currentValue2.map((v) => String(v)) : [];
|
|
45058
45085
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -45064,7 +45091,7 @@ var init_Form = __esm({
|
|
|
45064
45091
|
clearable: true,
|
|
45065
45092
|
options: [...relationOptions],
|
|
45066
45093
|
value: selectedValues,
|
|
45067
|
-
onValueChange: (value) => handleChange(
|
|
45094
|
+
onValueChange: (value) => handleChange(fieldName2, Array.isArray(value) ? value : [value]),
|
|
45068
45095
|
placeholder: field.placeholder || `Select ${label}...`
|
|
45069
45096
|
}
|
|
45070
45097
|
);
|
|
@@ -45074,7 +45101,7 @@ var init_Form = __esm({
|
|
|
45074
45101
|
{
|
|
45075
45102
|
...commonProps,
|
|
45076
45103
|
value: currentValue2 ? String(currentValue2) : void 0,
|
|
45077
|
-
onChange: (value) => handleChange(
|
|
45104
|
+
onChange: (value) => handleChange(fieldName2, value),
|
|
45078
45105
|
options: relationOptions,
|
|
45079
45106
|
isLoading: relationLoading,
|
|
45080
45107
|
placeholder: field.placeholder || `Select ${label}...`,
|
|
@@ -45091,7 +45118,7 @@ var init_Form = __esm({
|
|
|
45091
45118
|
placeholder: field.placeholder,
|
|
45092
45119
|
disabled: isLoading,
|
|
45093
45120
|
value: arrayValue,
|
|
45094
|
-
onChange: (next) => handleChange(
|
|
45121
|
+
onChange: (next) => handleChange(fieldName2, [...next])
|
|
45095
45122
|
}
|
|
45096
45123
|
);
|
|
45097
45124
|
}
|
|
@@ -45103,7 +45130,7 @@ var init_Form = __esm({
|
|
|
45103
45130
|
type: "number",
|
|
45104
45131
|
value: currentValue2 !== void 0 && currentValue2 !== "" ? String(currentValue2) : "",
|
|
45105
45132
|
onChange: (e) => handleChange(
|
|
45106
|
-
|
|
45133
|
+
fieldName2,
|
|
45107
45134
|
e.target.value ? Number(e.target.value) : void 0
|
|
45108
45135
|
),
|
|
45109
45136
|
min: field.min,
|
|
@@ -45120,7 +45147,7 @@ var init_Form = __esm({
|
|
|
45120
45147
|
icon: LucideIcons2.DollarSign,
|
|
45121
45148
|
value: currentValue2 !== void 0 && currentValue2 !== "" ? String(currentValue2) : "",
|
|
45122
45149
|
onChange: (e) => handleChange(
|
|
45123
|
-
|
|
45150
|
+
fieldName2,
|
|
45124
45151
|
e.target.value ? Number(e.target.value) : void 0
|
|
45125
45152
|
),
|
|
45126
45153
|
min: field.min,
|
|
@@ -45138,7 +45165,7 @@ var init_Form = __esm({
|
|
|
45138
45165
|
const f3 = files[0];
|
|
45139
45166
|
if (!f3) return;
|
|
45140
45167
|
const reader = new FileReader();
|
|
45141
|
-
reader.onload = () => handleChange(
|
|
45168
|
+
reader.onload = () => handleChange(fieldName2, {
|
|
45142
45169
|
name: f3.name,
|
|
45143
45170
|
mimeType: f3.type,
|
|
45144
45171
|
sizeBytes: f3.size,
|
|
@@ -45155,7 +45182,7 @@ var init_Form = __esm({
|
|
|
45155
45182
|
...commonProps,
|
|
45156
45183
|
type: "date",
|
|
45157
45184
|
value: formatDateValue(currentValue2),
|
|
45158
|
-
onChange: (e) => handleChange(
|
|
45185
|
+
onChange: (e) => handleChange(fieldName2, e.target.value)
|
|
45159
45186
|
}
|
|
45160
45187
|
);
|
|
45161
45188
|
case "datetime-local":
|
|
@@ -45165,7 +45192,7 @@ var init_Form = __esm({
|
|
|
45165
45192
|
...commonProps,
|
|
45166
45193
|
type: "datetime-local",
|
|
45167
45194
|
value: formatDateTimeValue(currentValue2),
|
|
45168
|
-
onChange: (e) => handleChange(
|
|
45195
|
+
onChange: (e) => handleChange(fieldName2, e.target.value)
|
|
45169
45196
|
}
|
|
45170
45197
|
);
|
|
45171
45198
|
case "email":
|
|
@@ -45175,7 +45202,7 @@ var init_Form = __esm({
|
|
|
45175
45202
|
...commonProps,
|
|
45176
45203
|
type: "email",
|
|
45177
45204
|
value: String(currentValue2),
|
|
45178
|
-
onChange: (e) => handleChange(
|
|
45205
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45179
45206
|
minLength: field.min,
|
|
45180
45207
|
maxLength: field.max
|
|
45181
45208
|
}
|
|
@@ -45187,7 +45214,7 @@ var init_Form = __esm({
|
|
|
45187
45214
|
...commonProps,
|
|
45188
45215
|
type: "url",
|
|
45189
45216
|
value: String(currentValue2),
|
|
45190
|
-
onChange: (e) => handleChange(
|
|
45217
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45191
45218
|
minLength: field.min,
|
|
45192
45219
|
maxLength: field.max
|
|
45193
45220
|
}
|
|
@@ -45199,7 +45226,7 @@ var init_Form = __esm({
|
|
|
45199
45226
|
...commonProps,
|
|
45200
45227
|
type: "password",
|
|
45201
45228
|
value: String(currentValue2),
|
|
45202
|
-
onChange: (e) => handleChange(
|
|
45229
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45203
45230
|
minLength: field.min,
|
|
45204
45231
|
maxLength: field.max
|
|
45205
45232
|
}
|
|
@@ -45212,7 +45239,7 @@ var init_Form = __esm({
|
|
|
45212
45239
|
...commonProps,
|
|
45213
45240
|
type: "text",
|
|
45214
45241
|
value: String(currentValue2),
|
|
45215
|
-
onChange: (e) => handleChange(
|
|
45242
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45216
45243
|
minLength: field.min,
|
|
45217
45244
|
maxLength: field.max
|
|
45218
45245
|
}
|
|
@@ -45569,7 +45596,7 @@ function entityFieldsFromListItem(item) {
|
|
|
45569
45596
|
}
|
|
45570
45597
|
return result;
|
|
45571
45598
|
}
|
|
45572
|
-
function getStatusStyle(
|
|
45599
|
+
function getStatusStyle(fieldName2, value) {
|
|
45573
45600
|
const val = String(value).toLowerCase();
|
|
45574
45601
|
if (val.includes("complete") || val.includes("done"))
|
|
45575
45602
|
return STATUS_STYLES.complete;
|
|
@@ -45585,12 +45612,12 @@ function getStatusStyle(fieldName, value) {
|
|
|
45585
45612
|
if (val.includes("low")) return STATUS_STYLES.low;
|
|
45586
45613
|
return STATUS_STYLES.default;
|
|
45587
45614
|
}
|
|
45588
|
-
function formatValue3(value,
|
|
45615
|
+
function formatValue3(value, fieldName2) {
|
|
45589
45616
|
if (typeof value === "number") {
|
|
45590
|
-
if (
|
|
45617
|
+
if (fieldName2.toLowerCase().includes("progress") || fieldName2.toLowerCase().includes("percent")) {
|
|
45591
45618
|
return `${value}%`;
|
|
45592
45619
|
}
|
|
45593
|
-
if (
|
|
45620
|
+
if (fieldName2.toLowerCase().includes("budget") || fieldName2.toLowerCase().includes("cost")) {
|
|
45594
45621
|
return new Intl.NumberFormat("en-US", {
|
|
45595
45622
|
style: "currency",
|
|
45596
45623
|
currency: "USD",
|
|
@@ -45613,8 +45640,8 @@ function formatValue3(value, fieldName) {
|
|
|
45613
45640
|
}
|
|
45614
45641
|
return String(value);
|
|
45615
45642
|
}
|
|
45616
|
-
function formatFieldLabel2(
|
|
45617
|
-
return humanizeFieldName(
|
|
45643
|
+
function formatFieldLabel2(fieldName2) {
|
|
45644
|
+
return humanizeFieldName(fieldName2).replace(/\sId$/, "").trim();
|
|
45618
45645
|
}
|
|
45619
45646
|
var STATUS_STYLES, StatusBadge, ProgressIndicator; exports.List = void 0;
|
|
45620
45647
|
var init_List = __esm({
|
|
@@ -45682,9 +45709,9 @@ var init_List = __esm({
|
|
|
45682
45709
|
};
|
|
45683
45710
|
StatusBadge = ({
|
|
45684
45711
|
value,
|
|
45685
|
-
fieldName
|
|
45712
|
+
fieldName: fieldName2
|
|
45686
45713
|
}) => {
|
|
45687
|
-
const style = getStatusStyle(
|
|
45714
|
+
const style = getStatusStyle(fieldName2, value);
|
|
45688
45715
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
45689
45716
|
exports.Typography,
|
|
45690
45717
|
{
|
|
@@ -48597,8 +48624,8 @@ var init_StatCard = __esm({
|
|
|
48597
48624
|
return items.length;
|
|
48598
48625
|
}
|
|
48599
48626
|
if (field.includes(":")) {
|
|
48600
|
-
const [
|
|
48601
|
-
return items.filter((item) => item[
|
|
48627
|
+
const [fieldName2, fieldValue] = field.split(":");
|
|
48628
|
+
return items.filter((item) => item[fieldName2] === fieldValue).length;
|
|
48602
48629
|
}
|
|
48603
48630
|
const fieldExistsOnItems = items.some((item) => field in item);
|
|
48604
48631
|
if (fieldExistsOnItems) {
|
|
@@ -50118,6 +50145,8 @@ var init_component_registry_generated = __esm({
|
|
|
50118
50145
|
init_DocSearch();
|
|
50119
50146
|
init_DocSidebar();
|
|
50120
50147
|
init_DocTOC();
|
|
50148
|
+
init_DocumentDetails();
|
|
50149
|
+
init_DocumentPanel();
|
|
50121
50150
|
init_DocumentViewer();
|
|
50122
50151
|
init_DrawFxLayer();
|
|
50123
50152
|
init_DrawGroup();
|
|
@@ -50227,7 +50256,7 @@ var init_component_registry_generated = __esm({
|
|
|
50227
50256
|
init_RelationSelect();
|
|
50228
50257
|
init_RepeatableFormSection();
|
|
50229
50258
|
init_ReplyTree();
|
|
50230
|
-
|
|
50259
|
+
init_RichTextEditor();
|
|
50231
50260
|
init_RuntimeDebugger2();
|
|
50232
50261
|
init_ScaledDiagram();
|
|
50233
50262
|
init_ScoreDisplay();
|
|
@@ -50390,6 +50419,8 @@ var init_component_registry_generated = __esm({
|
|
|
50390
50419
|
"DocSearch": DocSearch,
|
|
50391
50420
|
"DocSidebar": exports.DocSidebar,
|
|
50392
50421
|
"DocTOC": exports.DocTOC,
|
|
50422
|
+
"DocumentDetails": DocumentDetails,
|
|
50423
|
+
"DocumentPanel": DocumentPanel,
|
|
50393
50424
|
"DocumentViewer": exports.DocumentViewer,
|
|
50394
50425
|
"DrawFxLayer": DrawFxLayer,
|
|
50395
50426
|
"DrawGroup": DrawGroup,
|
|
@@ -50501,7 +50532,7 @@ var init_component_registry_generated = __esm({
|
|
|
50501
50532
|
"RelationSelect": exports.RelationSelect,
|
|
50502
50533
|
"RepeatableFormSection": exports.RepeatableFormSection,
|
|
50503
50534
|
"ReplyTree": exports.ReplyTree,
|
|
50504
|
-
"
|
|
50535
|
+
"RichTextEditor": exports.RichTextEditor,
|
|
50505
50536
|
"RuntimeDebugger": RuntimeDebugger,
|
|
50506
50537
|
"ScaledDiagram": exports.ScaledDiagram,
|
|
50507
50538
|
"ScoreDisplay": ScoreDisplay,
|
|
@@ -50655,10 +50686,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
50655
50686
|
}
|
|
50656
50687
|
if (field && typeof field === "object" && !Array.isArray(field) && !React77__namespace.default.isValidElement(field) && !(field instanceof Date)) {
|
|
50657
50688
|
const obj = field;
|
|
50658
|
-
const
|
|
50659
|
-
if (!
|
|
50689
|
+
const fieldName2 = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
|
|
50690
|
+
if (!fieldName2) return field;
|
|
50660
50691
|
if (obj.type || obj.inputType) return field;
|
|
50661
|
-
const entityField = fieldMap.get(
|
|
50692
|
+
const entityField = fieldMap.get(fieldName2);
|
|
50662
50693
|
if (!entityField) return field;
|
|
50663
50694
|
const enriched = { ...obj, type: entityField.type };
|
|
50664
50695
|
if (entityField.required && !("required" in obj)) {
|
|
@@ -50708,9 +50739,9 @@ function enrichDetailFields(fields, entityDef) {
|
|
|
50708
50739
|
}
|
|
50709
50740
|
if (field && typeof field === "object" && !Array.isArray(field) && !React77__namespace.default.isValidElement(field) && !(field instanceof Date)) {
|
|
50710
50741
|
const obj = field;
|
|
50711
|
-
const
|
|
50712
|
-
if (!
|
|
50713
|
-
const meta = metaFor(
|
|
50742
|
+
const fieldName2 = typeof obj.key === "string" ? obj.key : typeof obj.name === "string" ? obj.name : void 0;
|
|
50743
|
+
if (!fieldName2 || obj.type) return field;
|
|
50744
|
+
const meta = metaFor(fieldName2);
|
|
50714
50745
|
return meta ? { ...obj, ...meta } : field;
|
|
50715
50746
|
}
|
|
50716
50747
|
return field;
|
|
@@ -51549,9 +51580,9 @@ function UISlotRenderer({
|
|
|
51549
51580
|
"ui-slot-renderer relative min-h-full",
|
|
51550
51581
|
className
|
|
51551
51582
|
), children: [
|
|
51552
|
-
/* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex min-h-full", children: [
|
|
51553
|
-
/* @__PURE__ */ jsxRuntime.jsx(UISlotComponent, { slot: "sidebar", className: "ui-slot-sidebar min-w-0 shrink-0" }),
|
|
51554
|
-
/* @__PURE__ */ jsxRuntime.jsx(UISlotComponent, { slot: "main", className: "ui-slot-main flex-1 min-h-[200px]" })
|
|
51583
|
+
/* @__PURE__ */ jsxRuntime.jsxs(exports.Box, { className: "flex min-h-full flex-col lg:flex-row", children: [
|
|
51584
|
+
/* @__PURE__ */ jsxRuntime.jsx(UISlotComponent, { slot: "sidebar", className: "ui-slot-sidebar min-w-0 lg:shrink-0" }),
|
|
51585
|
+
/* @__PURE__ */ jsxRuntime.jsx(UISlotComponent, { slot: "main", className: "ui-slot-main flex-1 min-w-0 min-h-[200px]" })
|
|
51555
51586
|
] }),
|
|
51556
51587
|
/* @__PURE__ */ jsxRuntime.jsx(UISlotComponent, { slot: "modal", portal: true }),
|
|
51557
51588
|
/* @__PURE__ */ jsxRuntime.jsx(UISlotComponent, { slot: "drawer", portal: true }),
|
|
@@ -53539,54 +53570,6 @@ var en_default = {
|
|
|
53539
53570
|
"template.faq": "Frequently Asked Questions",
|
|
53540
53571
|
"template.ourTeam": "Our Team",
|
|
53541
53572
|
"template.caseStudies": "Case Studies",
|
|
53542
|
-
"richBlockEditor.toolbar.text": "Text",
|
|
53543
|
-
"richBlockEditor.toolbar.h1": "H1",
|
|
53544
|
-
"richBlockEditor.toolbar.h2": "H2",
|
|
53545
|
-
"richBlockEditor.toolbar.h3": "H3",
|
|
53546
|
-
"richBlockEditor.toolbar.bulletList": "Bullet list",
|
|
53547
|
-
"richBlockEditor.toolbar.numbered": "Numbered",
|
|
53548
|
-
"richBlockEditor.toolbar.quote": "Quote",
|
|
53549
|
-
"richBlockEditor.toolbar.code": "Code",
|
|
53550
|
-
"richBlockEditor.toolbar.divider": "Divider",
|
|
53551
|
-
"richBlockEditor.toolbar.image": "Image",
|
|
53552
|
-
"richBlockEditor.blockType.paragraph": "Text",
|
|
53553
|
-
"richBlockEditor.blockType.heading1": "Heading 1",
|
|
53554
|
-
"richBlockEditor.blockType.heading2": "Heading 2",
|
|
53555
|
-
"richBlockEditor.blockType.heading3": "Heading 3",
|
|
53556
|
-
"richBlockEditor.blockType.bulletList": "Bullet list",
|
|
53557
|
-
"richBlockEditor.blockType.numberedList": "Numbered list",
|
|
53558
|
-
"richBlockEditor.blockType.quote": "Quote",
|
|
53559
|
-
"richBlockEditor.blockType.code": "Code",
|
|
53560
|
-
"richBlockEditor.blockType.divider": "Divider",
|
|
53561
|
-
"richBlockEditor.blockType.image": "Image",
|
|
53562
|
-
"richBlockEditor.blockActions": "Block actions",
|
|
53563
|
-
"richBlockEditor.duplicate": "Duplicate",
|
|
53564
|
-
"richBlockEditor.turnInto": "Turn into",
|
|
53565
|
-
"richBlockEditor.placeholder.heading1": "Heading 1",
|
|
53566
|
-
"richBlockEditor.placeholder.heading2": "Heading 2",
|
|
53567
|
-
"richBlockEditor.placeholder.heading3": "Heading 3",
|
|
53568
|
-
"richBlockEditor.placeholder.quote": "Quote",
|
|
53569
|
-
"richBlockEditor.placeholder.code": "Enter code",
|
|
53570
|
-
"richBlockEditor.placeholder.paragraph": "Start writing...",
|
|
53571
|
-
"richBlockEditor.placeholder.listItem": "List item",
|
|
53572
|
-
"richBlockEditor.placeholder.caption": "Caption (optional)",
|
|
53573
|
-
"richBlockEditor.aria.heading1Block": "Heading 1 block",
|
|
53574
|
-
"richBlockEditor.aria.heading2Block": "Heading 2 block",
|
|
53575
|
-
"richBlockEditor.aria.heading3Block": "Heading 3 block",
|
|
53576
|
-
"richBlockEditor.aria.quoteBlock": "Quote block",
|
|
53577
|
-
"richBlockEditor.aria.codeBlock": "Code block",
|
|
53578
|
-
"richBlockEditor.aria.codeLanguage": "Code language",
|
|
53579
|
-
"richBlockEditor.aria.imageUrl": "Image URL",
|
|
53580
|
-
"richBlockEditor.aria.imageCaption": "Image caption",
|
|
53581
|
-
"richBlockEditor.aria.listItem": "List item",
|
|
53582
|
-
"richBlockEditor.aria.removeListItem": "Remove list item",
|
|
53583
|
-
"richBlockEditor.aria.paragraphBlock": "Paragraph block",
|
|
53584
|
-
"richBlockEditor.embeddedImage": "Embedded image",
|
|
53585
|
-
"richBlockEditor.noImageUrl": "No image URL set",
|
|
53586
|
-
"richBlockEditor.addItem": "Add item",
|
|
53587
|
-
"richBlockEditor.insertParagraphBelow": "Insert paragraph below",
|
|
53588
|
-
"richBlockEditor.editorToolbar": "Block editor toolbar",
|
|
53589
|
-
"richBlockEditor.insertEntry": "Insert {{label}}",
|
|
53590
53573
|
"versionDiff.compare": "Compare",
|
|
53591
53574
|
"versionDiff.to": "to",
|
|
53592
53575
|
"versionDiff.beforeRevision": "Before revision",
|
|
@@ -53934,7 +53917,31 @@ var en_default = {
|
|
|
53934
53917
|
"td.survivedAllWaves": "Survived all waves!",
|
|
53935
53918
|
"td.victory": "Victory!",
|
|
53936
53919
|
"td.wave": "Wave",
|
|
53937
|
-
"td.waveInProgress": "Wave in progress\u2026"
|
|
53920
|
+
"td.waveInProgress": "Wave in progress\u2026",
|
|
53921
|
+
"documentDetails.title": "Details",
|
|
53922
|
+
"documentPanel.untitled": "Untitled",
|
|
53923
|
+
"documentPanel.edit": "Edit",
|
|
53924
|
+
"documentPanel.done": "Done",
|
|
53925
|
+
"documentPanel.autosaveHint": "Saves as you type",
|
|
53926
|
+
"documentPanel.placeholder": "Start writing\u2026",
|
|
53927
|
+
"richTextEditor.editorToolbar": "Formatting toolbar",
|
|
53928
|
+
"richTextEditor.editorSurface": "Rich text editor",
|
|
53929
|
+
"richTextEditor.bold": "Bold",
|
|
53930
|
+
"richTextEditor.italic": "Italic",
|
|
53931
|
+
"richTextEditor.underline": "Underline",
|
|
53932
|
+
"richTextEditor.strikethrough": "Strikethrough",
|
|
53933
|
+
"richTextEditor.heading1": "Heading 1",
|
|
53934
|
+
"richTextEditor.heading2": "Heading 2",
|
|
53935
|
+
"richTextEditor.heading3": "Heading 3",
|
|
53936
|
+
"richTextEditor.bulletList": "Bullet list",
|
|
53937
|
+
"richTextEditor.numberedList": "Numbered list",
|
|
53938
|
+
"richTextEditor.quote": "Quote",
|
|
53939
|
+
"richTextEditor.code": "Code",
|
|
53940
|
+
"richTextEditor.link": "Add link",
|
|
53941
|
+
"richTextEditor.removeLink": "Remove link",
|
|
53942
|
+
"richTextEditor.divider": "Divider",
|
|
53943
|
+
"richTextEditor.linkPrompt": "Link address",
|
|
53944
|
+
"richTextEditor.placeholder": "Start writing\u2026"
|
|
53938
53945
|
};
|
|
53939
53946
|
|
|
53940
53947
|
// hooks/useTranslate.ts
|
|
@@ -53955,7 +53962,7 @@ var I18nContext = React77.createContext({
|
|
|
53955
53962
|
});
|
|
53956
53963
|
I18nContext.displayName = "I18nContext";
|
|
53957
53964
|
var I18nProvider = I18nContext.Provider;
|
|
53958
|
-
function
|
|
53965
|
+
function useTranslate116() {
|
|
53959
53966
|
return React77.useContext(I18nContext);
|
|
53960
53967
|
}
|
|
53961
53968
|
function createTranslate(messages) {
|
|
@@ -54275,6 +54282,8 @@ exports.DayCell = DayCell;
|
|
|
54275
54282
|
exports.DialogueBubble = DialogueBubble;
|
|
54276
54283
|
exports.DocPagination = DocPagination;
|
|
54277
54284
|
exports.DocSearch = DocSearch;
|
|
54285
|
+
exports.DocumentDetails = DocumentDetails;
|
|
54286
|
+
exports.DocumentPanel = DocumentPanel;
|
|
54278
54287
|
exports.DomStateMachineVisualizer = exports.StateMachineView;
|
|
54279
54288
|
exports.EditorCheckbox = EditorCheckbox;
|
|
54280
54289
|
exports.EditorSelect = EditorSelect;
|
|
@@ -54355,6 +54364,7 @@ exports.resolveFrame = resolveFrame;
|
|
|
54355
54364
|
exports.resolveSheetDirection = resolveSheetDirection;
|
|
54356
54365
|
exports.rows = rows;
|
|
54357
54366
|
exports.runTickFrame = runTickFrame;
|
|
54367
|
+
exports.sanitizeRichHtml = sanitizeRichHtml;
|
|
54358
54368
|
exports.screenToIso = screenToIso;
|
|
54359
54369
|
exports.str = str;
|
|
54360
54370
|
exports.tickAnimationState = tickAnimationState;
|
|
@@ -54403,7 +54413,7 @@ exports.useSharedEntityStoreContext = useSharedEntityStoreContext;
|
|
|
54403
54413
|
exports.useSwipeGesture = useSwipeGesture;
|
|
54404
54414
|
exports.useTapReveal = useTapReveal;
|
|
54405
54415
|
exports.useTraitListens = useTraitListens;
|
|
54406
|
-
exports.useTranslate =
|
|
54416
|
+
exports.useTranslate = useTranslate116;
|
|
54407
54417
|
exports.useUIEvents = useUIEvents;
|
|
54408
54418
|
exports.useUISlotManager = useUISlotManager;
|
|
54409
54419
|
exports.useUnitSpriteAtlas = useUnitSpriteAtlas;
|