@almadar/ui 5.159.0 → 5.161.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 +958 -912
- package/dist/avl/index.js +947 -901
- package/dist/components/index.cjs +978 -955
- package/dist/components/index.d.cts +156 -31
- package/dist/components/index.d.ts +156 -31
- package/dist/components/index.js +964 -944
- 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 +934 -892
- package/dist/providers/index.js +934 -892
- package/dist/runtime/index.cjs +953 -907
- package/dist/runtime/index.js +943 -897
- package/locales/ar.json +25 -49
- package/locales/en.json +25 -49
- package/locales/sl.json +25 -49
- package/package.json +5 -5
package/dist/components/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { EventBusContext, useTraitScopeChain, useCurrentPagePath, useGameAudioCo
|
|
|
7
7
|
export { GameAudioContext, GameAudioProvider, useGameAudioContext, useNavStack } from '@almadar/ui/providers';
|
|
8
8
|
import { createLogger, isLogLevelEnabled } from '@almadar/logger';
|
|
9
9
|
import * as LucideIcons2 from 'lucide-react';
|
|
10
|
-
import { X, List, Printer, ChevronRight, ChevronLeft, Check, Copy, RotateCcw, Play, Terminal, CheckCircle, XCircle, ChevronDown, Search, ChevronUp, MoreHorizontal, ArrowLeft, DollarSign, Package, Calendar, Pencil, Eye, Image as Image$1, Upload, ZoomIn, TrendingUp, TrendingDown, Minus, AlertCircle, Circle, Clock, CheckCircle2, Loader2, Code, FileText, WrapText, HelpCircle,
|
|
10
|
+
import { X, List, Printer, ChevronRight, ChevronLeft, Check, Copy, RotateCcw, Play, Terminal, CheckCircle, XCircle, ChevronDown, Search, ChevronUp, MoreHorizontal, ArrowLeft, DollarSign, Package, Calendar, Pencil, Eye, Image as Image$1, Upload, ZoomIn, TrendingUp, TrendingDown, Minus, AlertCircle, Circle, Clock, CheckCircle2, Loader2, Code, FileText, WrapText, HelpCircle, Bold, Italic, Underline, Strikethrough, Heading1, Heading2, Heading3, ListOrdered, Quote, Link as Link$1, GitBranch, Plus, ArrowRight, Trash, Menu as Menu$1, AlertTriangle, Trash2, Eraser, ZoomOut, Download, Lightbulb, PauseCircle, Link2 } from 'lucide-react';
|
|
11
11
|
import { useTranslate } from '@almadar/ui/hooks';
|
|
12
12
|
import { useUISlots, useTheme } from '@almadar/ui/context';
|
|
13
13
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
@@ -23950,8 +23950,9 @@ function DataGrid({
|
|
|
23950
23950
|
const titleField = fieldDefs.find((f3) => f3.variant === "h3" || f3.variant === "h4") ?? fieldDefs[0];
|
|
23951
23951
|
const badgeFields = fieldDefs.filter((f3) => f3.variant === "badge" && f3 !== titleField);
|
|
23952
23952
|
const bodyFields = fieldDefs.filter((f3) => f3 !== titleField && !badgeFields.includes(f3));
|
|
23953
|
-
const
|
|
23954
|
-
const
|
|
23953
|
+
const inlineCap = Math.min(maxInlineActions ?? 1, 1);
|
|
23954
|
+
const inlineCardActions = actionDefs.filter((a) => a.variant === "primary").slice(0, inlineCap);
|
|
23955
|
+
const menuCardActions = actionDefs.filter((a) => !inlineCardActions.includes(a));
|
|
23955
23956
|
const fireAction = (action, itemData) => {
|
|
23956
23957
|
if (action.navigatesTo) {
|
|
23957
23958
|
const url = action.navigatesTo.replace(
|
|
@@ -23971,6 +23972,9 @@ function DataGrid({
|
|
|
23971
23972
|
e.stopPropagation();
|
|
23972
23973
|
fireAction(action, itemData);
|
|
23973
23974
|
};
|
|
23975
|
+
const cardClickAction = actionDefs.find((a) => a.variant !== "danger");
|
|
23976
|
+
const handleCardClick = cardClickAction ? (itemData) => () => fireAction(cardClickAction, itemData) : void 0;
|
|
23977
|
+
const stopCardClick = handleCardClick ? (e) => e.stopPropagation() : void 0;
|
|
23974
23978
|
const hasRenderProp = typeof children === "function";
|
|
23975
23979
|
useEffect(() => {
|
|
23976
23980
|
if (data.length > 0 && !hasRenderProp && fieldDefs.length === 0) {
|
|
@@ -24042,55 +24046,40 @@ function DataGrid({
|
|
|
24042
24046
|
{
|
|
24043
24047
|
"data-entity-row": true,
|
|
24044
24048
|
"data-entity-id": id,
|
|
24045
|
-
|
|
24049
|
+
onClick: handleCardClick?.(itemData),
|
|
24050
|
+
className: cn("relative group/rowactions", handleCardClick && "cursor-pointer", isSelected && "ring-2 ring-primary rounded-lg"),
|
|
24046
24051
|
children: [
|
|
24047
24052
|
children(itemData, index),
|
|
24048
|
-
actionDefs.length > 0 && /* @__PURE__ */
|
|
24049
|
-
/* @__PURE__ */ jsxs(
|
|
24050
|
-
|
|
24051
|
-
|
|
24052
|
-
|
|
24053
|
-
|
|
24054
|
-
|
|
24055
|
-
|
|
24056
|
-
|
|
24057
|
-
|
|
24058
|
-
|
|
24059
|
-
|
|
24060
|
-
|
|
24061
|
-
|
|
24062
|
-
|
|
24063
|
-
|
|
24064
|
-
|
|
24065
|
-
)),
|
|
24066
|
-
maxInlineActions != null && actionDefs.length > maxInlineActions && /* @__PURE__ */ jsx(
|
|
24067
|
-
Menu,
|
|
24068
|
-
{
|
|
24069
|
-
position: "bottom-end",
|
|
24070
|
-
trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24071
|
-
items: actionDefs.slice(maxInlineActions).map((action) => ({
|
|
24072
|
-
label: action.label,
|
|
24073
|
-
icon: action.icon,
|
|
24074
|
-
event: action.event,
|
|
24075
|
-
onClick: () => fireAction(action, itemData)
|
|
24076
|
-
}))
|
|
24077
|
-
}
|
|
24078
|
-
)
|
|
24079
|
-
] }),
|
|
24080
|
-
/* @__PURE__ */ jsx(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__ */ jsx(
|
|
24053
|
+
actionDefs.length > 0 && /* @__PURE__ */ jsx(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__ */ jsxs(HStack, { gap: "xs", className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: [
|
|
24054
|
+
inlineCardActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
24055
|
+
Button,
|
|
24056
|
+
{
|
|
24057
|
+
variant: "primary",
|
|
24058
|
+
size: "sm",
|
|
24059
|
+
onClick: handleActionClick(action, itemData),
|
|
24060
|
+
"data-testid": `action-${action.event}`,
|
|
24061
|
+
"data-row-id": String(itemData.id),
|
|
24062
|
+
children: [
|
|
24063
|
+
action.icon && renderIconInput(action.icon, { size: "xs", className: "mr-1" }),
|
|
24064
|
+
action.label
|
|
24065
|
+
]
|
|
24066
|
+
},
|
|
24067
|
+
idx
|
|
24068
|
+
)),
|
|
24069
|
+
menuCardActions.length > 0 && /* @__PURE__ */ jsx(
|
|
24081
24070
|
Menu,
|
|
24082
24071
|
{
|
|
24083
24072
|
position: "bottom-end",
|
|
24084
24073
|
trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24085
|
-
items:
|
|
24074
|
+
items: menuCardActions.map((action) => ({
|
|
24086
24075
|
label: action.label,
|
|
24087
24076
|
icon: action.icon,
|
|
24088
|
-
|
|
24077
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
24089
24078
|
onClick: () => fireAction(action, itemData)
|
|
24090
24079
|
}))
|
|
24091
24080
|
}
|
|
24092
|
-
)
|
|
24093
|
-
] })
|
|
24081
|
+
)
|
|
24082
|
+
] }) })
|
|
24094
24083
|
]
|
|
24095
24084
|
},
|
|
24096
24085
|
id
|
|
@@ -24104,12 +24093,14 @@ function DataGrid({
|
|
|
24104
24093
|
{
|
|
24105
24094
|
"data-entity-row": true,
|
|
24106
24095
|
"data-entity-id": id,
|
|
24096
|
+
onClick: handleCardClick?.(itemData),
|
|
24107
24097
|
className: cn(
|
|
24108
24098
|
"bg-card rounded-lg",
|
|
24109
24099
|
"border border-border",
|
|
24110
24100
|
"shadow-elevation-card hover:shadow-elevation-dialog",
|
|
24111
24101
|
"hover:border-primary transition-all",
|
|
24112
24102
|
"flex flex-col",
|
|
24103
|
+
handleCardClick && "cursor-pointer",
|
|
24113
24104
|
isSelected && "ring-2 ring-primary border-primary"
|
|
24114
24105
|
),
|
|
24115
24106
|
children: [
|
|
@@ -24159,53 +24150,35 @@ function DataGrid({
|
|
|
24159
24150
|
] }, field.name);
|
|
24160
24151
|
}) })
|
|
24161
24152
|
] }),
|
|
24162
|
-
|
|
24163
|
-
|
|
24153
|
+
actionDefs.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", onClick: stopCardClick, className: "flex-shrink-0", children: [
|
|
24154
|
+
inlineCardActions.map((action, idx) => /* @__PURE__ */ jsx(
|
|
24164
24155
|
Button,
|
|
24165
24156
|
{
|
|
24166
|
-
variant:
|
|
24157
|
+
variant: "primary",
|
|
24167
24158
|
size: "sm",
|
|
24168
24159
|
onClick: handleActionClick(action, itemData),
|
|
24169
24160
|
"data-testid": `action-${action.event}`,
|
|
24170
24161
|
"data-row-id": String(itemData.id),
|
|
24171
24162
|
"aria-label": action.label,
|
|
24172
24163
|
title: action.label,
|
|
24173
|
-
className: cn(
|
|
24174
|
-
action.variant === "primary" ? void 0 : "text-muted-foreground hover:text-foreground",
|
|
24175
|
-
action.icon && "px-2"
|
|
24176
|
-
),
|
|
24164
|
+
className: cn(action.icon && "px-2"),
|
|
24177
24165
|
children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
|
|
24178
24166
|
},
|
|
24179
24167
|
idx
|
|
24180
24168
|
)),
|
|
24181
|
-
|
|
24169
|
+
menuCardActions.length > 0 && /* @__PURE__ */ jsx(
|
|
24182
24170
|
Menu,
|
|
24183
24171
|
{
|
|
24184
24172
|
position: "bottom-end",
|
|
24185
24173
|
trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24186
|
-
items:
|
|
24174
|
+
items: menuCardActions.map((action) => ({
|
|
24187
24175
|
label: action.label,
|
|
24188
24176
|
icon: action.icon,
|
|
24189
|
-
|
|
24177
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
24190
24178
|
onClick: () => fireAction(action, itemData)
|
|
24191
24179
|
}))
|
|
24192
24180
|
}
|
|
24193
|
-
)
|
|
24194
|
-
dangerActions.map((action, idx) => /* @__PURE__ */ jsx(
|
|
24195
|
-
Button,
|
|
24196
|
-
{
|
|
24197
|
-
variant: "ghost",
|
|
24198
|
-
size: "sm",
|
|
24199
|
-
onClick: handleActionClick(action, itemData),
|
|
24200
|
-
"data-testid": `action-${action.event}`,
|
|
24201
|
-
"data-row-id": String(itemData.id),
|
|
24202
|
-
"aria-label": action.label,
|
|
24203
|
-
title: action.label,
|
|
24204
|
-
className: "text-error hover:text-error hover:bg-error/10 px-2",
|
|
24205
|
-
children: action.icon ? renderIconInput(action.icon, { size: "xs" }) : action.label
|
|
24206
|
-
},
|
|
24207
|
-
`danger-${idx}`
|
|
24208
|
-
))
|
|
24181
|
+
)
|
|
24209
24182
|
] })
|
|
24210
24183
|
] }) }),
|
|
24211
24184
|
bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 pt-2 pb-4 flex-1", children: /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
@@ -24226,8 +24199,8 @@ function DataGrid({
|
|
|
24226
24199
|
}
|
|
24227
24200
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
24228
24201
|
field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
24229
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
24230
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
|
|
24202
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
24203
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
|
|
24231
24204
|
] }, field.name);
|
|
24232
24205
|
}) })
|
|
24233
24206
|
] }) })
|
|
@@ -24447,54 +24420,59 @@ function DataList({
|
|
|
24447
24420
|
if (!itemActions || itemActions.length === 0) return null;
|
|
24448
24421
|
const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
|
|
24449
24422
|
const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
|
|
24450
|
-
return
|
|
24451
|
-
|
|
24452
|
-
|
|
24453
|
-
|
|
24454
|
-
|
|
24455
|
-
|
|
24456
|
-
|
|
24457
|
-
|
|
24458
|
-
|
|
24459
|
-
|
|
24460
|
-
action
|
|
24461
|
-
|
|
24462
|
-
|
|
24463
|
-
|
|
24464
|
-
|
|
24465
|
-
|
|
24466
|
-
|
|
24467
|
-
|
|
24468
|
-
|
|
24469
|
-
|
|
24470
|
-
|
|
24471
|
-
|
|
24472
|
-
|
|
24473
|
-
|
|
24474
|
-
|
|
24475
|
-
|
|
24476
|
-
|
|
24477
|
-
|
|
24478
|
-
|
|
24479
|
-
|
|
24480
|
-
|
|
24481
|
-
|
|
24482
|
-
|
|
24483
|
-
|
|
24484
|
-
|
|
24485
|
-
|
|
24486
|
-
|
|
24487
|
-
|
|
24488
|
-
|
|
24489
|
-
|
|
24423
|
+
return (
|
|
24424
|
+
// stopPropagation at the cluster: the "⋯" trigger opens the overflow
|
|
24425
|
+
// menu without also firing the row's default click (inline buttons
|
|
24426
|
+
// already stop it in handleActionClick; the Menu panel is portaled).
|
|
24427
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", onClick: rowClickEvent ? (e) => e.stopPropagation() : void 0, className: "flex-shrink-0", children: [
|
|
24428
|
+
inline.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
24429
|
+
Button,
|
|
24430
|
+
{
|
|
24431
|
+
variant: action.variant ?? "ghost",
|
|
24432
|
+
size: "sm",
|
|
24433
|
+
onClick: handleActionClick(action, itemData),
|
|
24434
|
+
"data-testid": `action-${action.event}`,
|
|
24435
|
+
"data-row-id": String(itemData.id),
|
|
24436
|
+
className: cn(
|
|
24437
|
+
action.variant === "danger" && "text-error hover:bg-error/10",
|
|
24438
|
+
// Must sit on the Button itself: the variant's own text colour
|
|
24439
|
+
// beats an inherited one from the row wrapper.
|
|
24440
|
+
onPrimary && "!text-primary-foreground hover:bg-primary-foreground/15"
|
|
24441
|
+
),
|
|
24442
|
+
children: [
|
|
24443
|
+
action.icon && renderIconInput2(action.icon, { size: "xs", className: "mr-1" }),
|
|
24444
|
+
action.label
|
|
24445
|
+
]
|
|
24446
|
+
},
|
|
24447
|
+
idx
|
|
24448
|
+
)),
|
|
24449
|
+
overflow.length > 0 && /* @__PURE__ */ jsx(
|
|
24450
|
+
Menu,
|
|
24451
|
+
{
|
|
24452
|
+
position: "bottom-end",
|
|
24453
|
+
trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
24454
|
+
items: overflow.map((action) => ({
|
|
24455
|
+
label: action.label,
|
|
24456
|
+
icon: action.icon,
|
|
24457
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
24458
|
+
onClick: () => eventBus.emit(`UI:${action.event}`, {
|
|
24459
|
+
id: itemData.id,
|
|
24460
|
+
row: itemData
|
|
24461
|
+
})
|
|
24462
|
+
}))
|
|
24463
|
+
}
|
|
24464
|
+
)
|
|
24465
|
+
] })
|
|
24466
|
+
);
|
|
24490
24467
|
};
|
|
24468
|
+
const rowClickEvent = itemClickEvent || itemActions?.find((a) => a.variant !== "danger")?.event;
|
|
24491
24469
|
const handleRowClick = (itemData) => () => {
|
|
24492
|
-
if (!
|
|
24470
|
+
if (!rowClickEvent) return;
|
|
24493
24471
|
const payload = {
|
|
24494
24472
|
id: itemData.id,
|
|
24495
24473
|
row: itemData
|
|
24496
24474
|
};
|
|
24497
|
-
eventBus.emit(`UI:${
|
|
24475
|
+
eventBus.emit(`UI:${rowClickEvent}`, payload);
|
|
24498
24476
|
};
|
|
24499
24477
|
if (isLoading) {
|
|
24500
24478
|
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") }) });
|
|
@@ -24542,10 +24520,10 @@ function DataList({
|
|
|
24542
24520
|
{
|
|
24543
24521
|
"data-entity-row": true,
|
|
24544
24522
|
"data-entity-id": id,
|
|
24545
|
-
onClick:
|
|
24523
|
+
onClick: rowClickEvent ? handleRowClick(itemData) : void 0,
|
|
24546
24524
|
className: cn(
|
|
24547
24525
|
"flex px-4 group/rowactions",
|
|
24548
|
-
|
|
24526
|
+
rowClickEvent && "cursor-pointer",
|
|
24549
24527
|
isSent ? "justify-end" : "justify-start"
|
|
24550
24528
|
),
|
|
24551
24529
|
children: /* @__PURE__ */ jsxs(
|
|
@@ -24621,7 +24599,7 @@ function DataList({
|
|
|
24621
24599
|
const id2 = itemData.id || String(index);
|
|
24622
24600
|
const actions = renderItemActions(itemData);
|
|
24623
24601
|
return wrapDnd(
|
|
24624
|
-
/* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick:
|
|
24602
|
+
/* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn("relative group/rowactions", rowClickEvent && "cursor-pointer"), children: [
|
|
24625
24603
|
children(itemData, index),
|
|
24626
24604
|
actions && /* @__PURE__ */ jsxs(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: [
|
|
24627
24605
|
/* @__PURE__ */ jsx(Box, { className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5 [@media(pointer:coarse)]:hidden", children: actions }),
|
|
@@ -24633,7 +24611,6 @@ function DataList({
|
|
|
24633
24611
|
items: (itemActions ?? []).map((action) => ({
|
|
24634
24612
|
label: action.label,
|
|
24635
24613
|
icon: action.icon,
|
|
24636
|
-
event: action.event,
|
|
24637
24614
|
variant: action.variant === "danger" ? "danger" : "default",
|
|
24638
24615
|
onClick: () => eventBus.emit(`UI:${action.event}`, {
|
|
24639
24616
|
id: itemData.id,
|
|
@@ -24650,12 +24627,16 @@ function DataList({
|
|
|
24650
24627
|
const id = itemData.id || String(index);
|
|
24651
24628
|
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
24652
24629
|
return wrapDnd(
|
|
24653
|
-
/* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id, onClick:
|
|
24630
|
+
/* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn(rowClickEvent && "cursor-pointer"), children: [
|
|
24654
24631
|
/* @__PURE__ */ jsxs(
|
|
24655
24632
|
Box,
|
|
24656
24633
|
{
|
|
24657
24634
|
className: cn(
|
|
24658
|
-
|
|
24635
|
+
// items-start, not items-center: a multi-line row (title + meta +
|
|
24636
|
+
// progress) centred its action cluster in the vertical middle, so
|
|
24637
|
+
// the buttons floated between the meta fields instead of anchoring
|
|
24638
|
+
// to the title they act on (U-DATALIST-ACTIONS-FLOAT-MID-ROW).
|
|
24639
|
+
"group flex items-start gap-4 transition-all duration-fast",
|
|
24659
24640
|
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
24660
24641
|
"hover:bg-muted/80",
|
|
24661
24642
|
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
@@ -24686,11 +24667,19 @@ function DataList({
|
|
|
24686
24667
|
if (value === void 0 || value === null || value === "") return null;
|
|
24687
24668
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
24688
24669
|
field.icon && renderIconInput2(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
24689
|
-
/* @__PURE__ */ jsxs(
|
|
24690
|
-
|
|
24691
|
-
|
|
24692
|
-
|
|
24693
|
-
|
|
24670
|
+
/* @__PURE__ */ jsxs(
|
|
24671
|
+
Typography,
|
|
24672
|
+
{
|
|
24673
|
+
variant: "caption",
|
|
24674
|
+
color: "secondary",
|
|
24675
|
+
className: cn(field.format !== "boolean" && "sr-only"),
|
|
24676
|
+
children: [
|
|
24677
|
+
field.label ?? fieldLabel3(field.name),
|
|
24678
|
+
":"
|
|
24679
|
+
]
|
|
24680
|
+
}
|
|
24681
|
+
),
|
|
24682
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
|
|
24694
24683
|
] }, field.name);
|
|
24695
24684
|
}) }),
|
|
24696
24685
|
progressFields.map((field) => {
|
|
@@ -24709,7 +24698,7 @@ function DataList({
|
|
|
24709
24698
|
]
|
|
24710
24699
|
}
|
|
24711
24700
|
),
|
|
24712
|
-
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "
|
|
24701
|
+
(isCard || isCompact) && !isLast && /* @__PURE__ */ jsx(Box, { className: cn("border-b border-border/40", isCompact ? "mx-4" : "mx-6") })
|
|
24713
24702
|
] }, id)
|
|
24714
24703
|
);
|
|
24715
24704
|
};
|
|
@@ -24719,7 +24708,13 @@ function DataList({
|
|
|
24719
24708
|
{
|
|
24720
24709
|
className: cn(
|
|
24721
24710
|
isCard && "bg-card rounded-xl border border-border shadow-elevation-dialog overflow-hidden",
|
|
24722
|
-
|
|
24711
|
+
// `gap-*` is inert on a block container, and Box only emits a display
|
|
24712
|
+
// class when its `display` prop is set — so every non-card list had
|
|
24713
|
+
// been asking for a gap that CSS silently dropped. flex-col makes it
|
|
24714
|
+
// real. `compact` keeps gap-0 on purpose: it separates with the row
|
|
24715
|
+
// divider above instead, never both (Almadar_UI_Beauty.md 6).
|
|
24716
|
+
!isCard && "flex flex-col",
|
|
24717
|
+
!isCard && !isCompact && gapClass,
|
|
24723
24718
|
listLookStyles[look],
|
|
24724
24719
|
className
|
|
24725
24720
|
),
|
|
@@ -33259,7 +33254,7 @@ var init_MapView = __esm({
|
|
|
33259
33254
|
shadowSize: [41, 41]
|
|
33260
33255
|
});
|
|
33261
33256
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
33262
|
-
const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback108, useState:
|
|
33257
|
+
const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback108, useState: useState106 } = React77__default;
|
|
33263
33258
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
33264
33259
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
33265
33260
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -33304,7 +33299,7 @@ var init_MapView = __esm({
|
|
|
33304
33299
|
showAttribution = true
|
|
33305
33300
|
}) {
|
|
33306
33301
|
const eventBus = useEventBus2();
|
|
33307
|
-
const [clickedPosition, setClickedPosition] =
|
|
33302
|
+
const [clickedPosition, setClickedPosition] = useState106(null);
|
|
33308
33303
|
const handleMapClick = useCallback108((lat, lng) => {
|
|
33309
33304
|
if (showClickedPin) {
|
|
33310
33305
|
setClickedPosition({ lat, lng });
|
|
@@ -37666,741 +37661,775 @@ var init_PositionedCanvas = __esm({
|
|
|
37666
37661
|
PositionedCanvas.displayName = "PositionedCanvas";
|
|
37667
37662
|
}
|
|
37668
37663
|
});
|
|
37669
|
-
function
|
|
37670
|
-
|
|
37671
|
-
|
|
37672
|
-
|
|
37673
|
-
|
|
37674
|
-
|
|
37675
|
-
if (!Array.isArray(raw) || raw.length === 0) return [createBlock("paragraph")];
|
|
37676
|
-
return raw.map((row) => {
|
|
37677
|
-
const entity = row;
|
|
37678
|
-
const rawType = entity.type;
|
|
37679
|
-
const type = typeof rawType === "string" && BLOCK_TYPES.has(rawType) ? rawType : "paragraph";
|
|
37680
|
-
const id = typeof entity.id === "string" && entity.id ? entity.id : nextBlockId(type);
|
|
37681
|
-
return { ...entity, id, type };
|
|
37682
|
-
});
|
|
37683
|
-
}
|
|
37684
|
-
function createBlock(type) {
|
|
37685
|
-
switch (type) {
|
|
37686
|
-
case "bullet-list":
|
|
37687
|
-
case "numbered-list":
|
|
37688
|
-
return {
|
|
37689
|
-
id: nextBlockId(type),
|
|
37690
|
-
type,
|
|
37691
|
-
children: [
|
|
37692
|
-
{ id: nextBlockId("li"), type: "paragraph", content: "" }
|
|
37693
|
-
]
|
|
37694
|
-
};
|
|
37695
|
-
case "image":
|
|
37696
|
-
return {
|
|
37697
|
-
id: nextBlockId(type),
|
|
37698
|
-
type,
|
|
37699
|
-
content: "",
|
|
37700
|
-
metadata: { url: "", caption: "" }
|
|
37701
|
-
};
|
|
37702
|
-
case "code":
|
|
37703
|
-
return {
|
|
37704
|
-
id: nextBlockId(type),
|
|
37705
|
-
type,
|
|
37706
|
-
content: "",
|
|
37707
|
-
metadata: { language: "plaintext" }
|
|
37708
|
-
};
|
|
37709
|
-
case "divider":
|
|
37710
|
-
return { id: nextBlockId(type), type };
|
|
37711
|
-
default:
|
|
37712
|
-
return { id: nextBlockId(type), type, content: "" };
|
|
37664
|
+
function safeUrl(raw, kinds) {
|
|
37665
|
+
const url = raw.trim();
|
|
37666
|
+
if (url.startsWith("#") || url.startsWith("/")) return url;
|
|
37667
|
+
const lower = url.toLowerCase();
|
|
37668
|
+
for (const kind of kinds) {
|
|
37669
|
+
if (lower.startsWith(kind)) return url;
|
|
37713
37670
|
}
|
|
37671
|
+
return null;
|
|
37714
37672
|
}
|
|
37715
|
-
function
|
|
37716
|
-
|
|
37717
|
-
|
|
37718
|
-
|
|
37719
|
-
|
|
37720
|
-
|
|
37721
|
-
|
|
37722
|
-
return {
|
|
37723
|
-
...block,
|
|
37724
|
-
id: nextBlockId(block.type),
|
|
37725
|
-
children: block.children?.map((child) => ({
|
|
37726
|
-
...child,
|
|
37727
|
-
id: nextBlockId("li")
|
|
37728
|
-
})),
|
|
37729
|
-
metadata: block.metadata ? { ...block.metadata } : void 0
|
|
37730
|
-
};
|
|
37731
|
-
}
|
|
37732
|
-
function insertAfter(blocks, targetId, inserted) {
|
|
37733
|
-
const idx = blocks.findIndex((b) => b.id === targetId);
|
|
37734
|
-
if (idx === -1) return [...blocks, inserted];
|
|
37735
|
-
const next = blocks.slice();
|
|
37736
|
-
next.splice(idx + 1, 0, inserted);
|
|
37737
|
-
return next;
|
|
37738
|
-
}
|
|
37739
|
-
function changeBlockType(block, type) {
|
|
37740
|
-
if (block.type === type) return block;
|
|
37741
|
-
if (type === "bullet-list" || type === "numbered-list") {
|
|
37742
|
-
if (block.children && block.children.length > 0) {
|
|
37743
|
-
return { ...block, type };
|
|
37673
|
+
function sanitizeNode(el) {
|
|
37674
|
+
const children = Array.from(el.children);
|
|
37675
|
+
for (const child of children) {
|
|
37676
|
+
const tag = child.tagName.toLowerCase();
|
|
37677
|
+
if (DROP_TAGS.has(tag)) {
|
|
37678
|
+
child.remove();
|
|
37679
|
+
continue;
|
|
37744
37680
|
}
|
|
37745
|
-
const
|
|
37746
|
-
|
|
37747
|
-
|
|
37748
|
-
|
|
37749
|
-
|
|
37750
|
-
|
|
37751
|
-
|
|
37752
|
-
|
|
37753
|
-
|
|
37754
|
-
|
|
37755
|
-
|
|
37681
|
+
const allowed = ALLOWED_ATTRS[tag];
|
|
37682
|
+
if (!allowed) {
|
|
37683
|
+
sanitizeNode(child);
|
|
37684
|
+
child.replaceWith(...Array.from(child.childNodes));
|
|
37685
|
+
continue;
|
|
37686
|
+
}
|
|
37687
|
+
for (const attr of Array.from(child.attributes)) {
|
|
37688
|
+
const name = attr.name.toLowerCase();
|
|
37689
|
+
if (!allowed.includes(name)) {
|
|
37690
|
+
child.removeAttribute(attr.name);
|
|
37691
|
+
continue;
|
|
37692
|
+
}
|
|
37693
|
+
if (name === "href") {
|
|
37694
|
+
const url = safeUrl(attr.value, ["http://", "https://", "mailto:"]);
|
|
37695
|
+
if (url === null) child.removeAttribute(attr.name);
|
|
37696
|
+
else child.setAttribute("href", url);
|
|
37697
|
+
}
|
|
37698
|
+
if (name === "src") {
|
|
37699
|
+
const url = safeUrl(attr.value, ["http://", "https://", "data:image/"]);
|
|
37700
|
+
if (url === null) child.remove();
|
|
37701
|
+
else child.setAttribute("src", url);
|
|
37702
|
+
}
|
|
37703
|
+
}
|
|
37704
|
+
sanitizeNode(child);
|
|
37756
37705
|
}
|
|
37757
|
-
|
|
37758
|
-
|
|
37759
|
-
|
|
37760
|
-
|
|
37761
|
-
|
|
37762
|
-
|
|
37763
|
-
|
|
37706
|
+
}
|
|
37707
|
+
function sanitizeRichHtml(html) {
|
|
37708
|
+
if (!html || typeof html !== "string") return "";
|
|
37709
|
+
if (typeof window === "undefined" || typeof DOMParser === "undefined") return "";
|
|
37710
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
37711
|
+
sanitizeNode(doc.body);
|
|
37712
|
+
if (!doc.body.querySelector("img, hr") && (doc.body.textContent ?? "").trim().length === 0) {
|
|
37713
|
+
return "";
|
|
37764
37714
|
}
|
|
37765
|
-
|
|
37766
|
-
|
|
37767
|
-
|
|
37768
|
-
|
|
37769
|
-
|
|
37770
|
-
|
|
37771
|
-
|
|
37715
|
+
return doc.body.innerHTML.replace(//g, "");
|
|
37716
|
+
}
|
|
37717
|
+
function htmlIsEmpty(el) {
|
|
37718
|
+
if (el.querySelector("img, hr")) return false;
|
|
37719
|
+
return (el.textContent ?? "").trim().length === 0;
|
|
37720
|
+
}
|
|
37721
|
+
function closestBlock(node, root) {
|
|
37722
|
+
let cur = node;
|
|
37723
|
+
while (cur && cur !== root) {
|
|
37724
|
+
if (cur instanceof Element && BLOCK_TAGS.has(cur.tagName)) return cur;
|
|
37725
|
+
cur = cur.parentNode;
|
|
37772
37726
|
}
|
|
37773
|
-
|
|
37774
|
-
return { id: block.id, type, content: seed };
|
|
37727
|
+
return null;
|
|
37775
37728
|
}
|
|
37776
|
-
function
|
|
37777
|
-
|
|
37778
|
-
|
|
37779
|
-
|
|
37780
|
-
|
|
37781
|
-
|
|
37782
|
-
|
|
37783
|
-
|
|
37784
|
-
|
|
37729
|
+
function RichTextStyles() {
|
|
37730
|
+
return /* @__PURE__ */ jsx("style", { children: RICH_TEXT_CSS });
|
|
37731
|
+
}
|
|
37732
|
+
function readToolbarState(root) {
|
|
37733
|
+
const sel = window.getSelection();
|
|
37734
|
+
if (!sel || sel.rangeCount === 0) return IDLE_TOOLBAR;
|
|
37735
|
+
const anchor = sel.anchorNode;
|
|
37736
|
+
if (!anchor || !root.contains(anchor)) return IDLE_TOOLBAR;
|
|
37737
|
+
let block = null;
|
|
37738
|
+
let link = false;
|
|
37739
|
+
let node = anchor;
|
|
37740
|
+
while (node && node !== root) {
|
|
37741
|
+
if (node instanceof Element) {
|
|
37742
|
+
const tag = node.tagName.toLowerCase();
|
|
37743
|
+
if (!block && (tag === "h1" || tag === "h2" || tag === "h3" || tag === "blockquote" || tag === "pre")) {
|
|
37744
|
+
block = tag;
|
|
37785
37745
|
}
|
|
37746
|
+
if (tag === "a") link = true;
|
|
37786
37747
|
}
|
|
37787
|
-
|
|
37788
|
-
|
|
37789
|
-
|
|
37790
|
-
|
|
37791
|
-
|
|
37792
|
-
|
|
37793
|
-
|
|
37794
|
-
|
|
37795
|
-
|
|
37796
|
-
|
|
37797
|
-
|
|
37798
|
-
|
|
37799
|
-
"inline-flex items-center justify-center",
|
|
37800
|
-
"h-6 w-6 rounded-sm p-0 gap-0",
|
|
37801
|
-
"text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
37802
|
-
"opacity-0 group-hover:opacity-100 focus-visible:opacity-100",
|
|
37803
|
-
"transition-opacity"
|
|
37804
|
-
),
|
|
37805
|
-
onClick: () => setOpen((v) => !v),
|
|
37806
|
-
children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", className: "w-3.5 h-3.5" })
|
|
37807
|
-
}
|
|
37808
|
-
),
|
|
37809
|
-
open && /* @__PURE__ */ jsxs(
|
|
37810
|
-
Box,
|
|
37811
|
-
{
|
|
37812
|
-
role: "menu",
|
|
37813
|
-
className: cn(
|
|
37814
|
-
"absolute right-0 z-10 mt-1 w-44",
|
|
37815
|
-
"rounded-container border border-border bg-popover shadow-elevation-popover",
|
|
37816
|
-
"py-1 text-sm"
|
|
37817
|
-
),
|
|
37818
|
-
children: [
|
|
37819
|
-
/* @__PURE__ */ jsx(Box, { className: "px-2 py-1 text-xs uppercase tracking-wide text-muted-foreground", children: t(BLOCK_TYPE_LABEL_KEY[block.type]) }),
|
|
37820
|
-
/* @__PURE__ */ jsxs(
|
|
37821
|
-
Button,
|
|
37822
|
-
{
|
|
37823
|
-
type: "button",
|
|
37824
|
-
variant: "ghost",
|
|
37825
|
-
role: "menuitem",
|
|
37826
|
-
className: "flex w-full items-center gap-2 px-2 py-1.5 text-left justify-start rounded-none",
|
|
37827
|
-
onClick: () => {
|
|
37828
|
-
onDuplicate();
|
|
37829
|
-
setOpen(false);
|
|
37830
|
-
},
|
|
37831
|
-
children: [
|
|
37832
|
-
/* @__PURE__ */ jsx(Icon, { name: "plus", className: "w-3.5 h-3.5" }),
|
|
37833
|
-
" ",
|
|
37834
|
-
t("richBlockEditor.duplicate")
|
|
37835
|
-
]
|
|
37836
|
-
}
|
|
37837
|
-
),
|
|
37838
|
-
/* @__PURE__ */ jsxs(
|
|
37839
|
-
Button,
|
|
37840
|
-
{
|
|
37841
|
-
type: "button",
|
|
37842
|
-
variant: "ghost",
|
|
37843
|
-
role: "menuitem",
|
|
37844
|
-
className: "flex w-full items-center gap-2 px-2 py-1.5 text-left text-destructive hover:bg-muted justify-start rounded-none",
|
|
37845
|
-
onClick: () => {
|
|
37846
|
-
onDelete();
|
|
37847
|
-
setOpen(false);
|
|
37848
|
-
},
|
|
37849
|
-
children: [
|
|
37850
|
-
/* @__PURE__ */ jsx(Icon, { name: "trash", className: "w-3.5 h-3.5" }),
|
|
37851
|
-
" ",
|
|
37852
|
-
t("common.delete")
|
|
37853
|
-
]
|
|
37854
|
-
}
|
|
37855
|
-
),
|
|
37856
|
-
CHANGEABLE_TYPES.includes(block.type) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
37857
|
-
/* @__PURE__ */ jsx(Box, { className: "my-1 border-t border-border" }),
|
|
37858
|
-
/* @__PURE__ */ jsx(Box, { className: "px-2 py-1 text-xs uppercase tracking-wide text-muted-foreground", children: t("richBlockEditor.turnInto") }),
|
|
37859
|
-
CHANGEABLE_TYPES.filter((bt) => bt !== block.type).map((bt) => /* @__PURE__ */ jsx(
|
|
37860
|
-
Button,
|
|
37861
|
-
{
|
|
37862
|
-
type: "button",
|
|
37863
|
-
variant: "ghost",
|
|
37864
|
-
role: "menuitem",
|
|
37865
|
-
className: "flex w-full items-center gap-2 px-2 py-1.5 text-left justify-start rounded-none",
|
|
37866
|
-
onClick: () => {
|
|
37867
|
-
onChangeType(bt);
|
|
37868
|
-
setOpen(false);
|
|
37869
|
-
},
|
|
37870
|
-
children: t(BLOCK_TYPE_LABEL_KEY[bt])
|
|
37871
|
-
},
|
|
37872
|
-
bt
|
|
37873
|
-
))
|
|
37874
|
-
] })
|
|
37875
|
-
]
|
|
37876
|
-
}
|
|
37877
|
-
)
|
|
37878
|
-
] });
|
|
37748
|
+
node = node.parentNode;
|
|
37749
|
+
}
|
|
37750
|
+
return {
|
|
37751
|
+
bold: document.queryCommandState("bold"),
|
|
37752
|
+
italic: document.queryCommandState("italic"),
|
|
37753
|
+
underline: document.queryCommandState("underline"),
|
|
37754
|
+
strikeThrough: document.queryCommandState("strikeThrough"),
|
|
37755
|
+
block,
|
|
37756
|
+
bullets: document.queryCommandState("insertUnorderedList"),
|
|
37757
|
+
numbers: document.queryCommandState("insertOrderedList"),
|
|
37758
|
+
link
|
|
37759
|
+
};
|
|
37879
37760
|
}
|
|
37880
|
-
function
|
|
37881
|
-
tag,
|
|
37882
|
-
value,
|
|
37883
|
-
readOnly,
|
|
37884
|
-
placeholder,
|
|
37885
|
-
className,
|
|
37886
|
-
ariaLabel,
|
|
37887
|
-
onValueChange
|
|
37888
|
-
}) {
|
|
37889
|
-
const ref = useRef(null);
|
|
37890
|
-
useEffect(() => {
|
|
37891
|
-
const el = ref.current;
|
|
37892
|
-
if (!el) return;
|
|
37893
|
-
const isFocused = document.activeElement === el;
|
|
37894
|
-
if (!isFocused && el.textContent !== value) {
|
|
37895
|
-
el.textContent = value;
|
|
37896
|
-
}
|
|
37897
|
-
}, [value]);
|
|
37898
|
-
const handleInput = useCallback(
|
|
37899
|
-
(e) => {
|
|
37900
|
-
onValueChange(e.currentTarget.textContent ?? "");
|
|
37901
|
-
},
|
|
37902
|
-
[onValueChange]
|
|
37903
|
-
);
|
|
37761
|
+
function ToolbarButton({ icon: IconCmp, label, active, onExec }) {
|
|
37904
37762
|
return /* @__PURE__ */ jsx(
|
|
37905
|
-
|
|
37763
|
+
Button,
|
|
37906
37764
|
{
|
|
37907
|
-
|
|
37908
|
-
|
|
37909
|
-
|
|
37910
|
-
|
|
37911
|
-
|
|
37912
|
-
|
|
37913
|
-
"aria-multiline": "true",
|
|
37914
|
-
"data-placeholder": placeholder,
|
|
37765
|
+
type: "button",
|
|
37766
|
+
variant: "ghost",
|
|
37767
|
+
size: "sm",
|
|
37768
|
+
"aria-label": label,
|
|
37769
|
+
"aria-pressed": active,
|
|
37770
|
+
title: label,
|
|
37915
37771
|
className: cn(
|
|
37916
|
-
"
|
|
37917
|
-
"
|
|
37918
|
-
className
|
|
37772
|
+
"h-8 w-8 p-0 gap-0 justify-center",
|
|
37773
|
+
active && "bg-muted text-foreground"
|
|
37919
37774
|
),
|
|
37920
|
-
|
|
37775
|
+
onMouseDown: (e) => {
|
|
37776
|
+
e.preventDefault();
|
|
37777
|
+
onExec();
|
|
37778
|
+
},
|
|
37779
|
+
children: /* @__PURE__ */ jsx(IconCmp, { size: 15 })
|
|
37921
37780
|
}
|
|
37922
37781
|
);
|
|
37923
37782
|
}
|
|
37924
|
-
|
|
37925
|
-
|
|
37926
|
-
|
|
37927
|
-
|
|
37928
|
-
|
|
37929
|
-
|
|
37930
|
-
|
|
37931
|
-
|
|
37932
|
-
|
|
37933
|
-
|
|
37934
|
-
|
|
37935
|
-
|
|
37936
|
-
|
|
37937
|
-
|
|
37938
|
-
|
|
37939
|
-
|
|
37940
|
-
|
|
37941
|
-
|
|
37942
|
-
|
|
37943
|
-
|
|
37944
|
-
|
|
37945
|
-
|
|
37946
|
-
|
|
37947
|
-
|
|
37948
|
-
|
|
37949
|
-
|
|
37950
|
-
|
|
37951
|
-
|
|
37952
|
-
|
|
37953
|
-
|
|
37954
|
-
|
|
37955
|
-
|
|
37956
|
-
|
|
37957
|
-
|
|
37958
|
-
|
|
37959
|
-
|
|
37960
|
-
|
|
37961
|
-
|
|
37962
|
-
|
|
37963
|
-
|
|
37964
|
-
|
|
37965
|
-
|
|
37966
|
-
|
|
37967
|
-
|
|
37968
|
-
|
|
37969
|
-
|
|
37970
|
-
|
|
37971
|
-
|
|
37972
|
-
|
|
37973
|
-
|
|
37974
|
-
|
|
37975
|
-
|
|
37976
|
-
|
|
37977
|
-
|
|
37978
|
-
|
|
37979
|
-
|
|
37980
|
-
|
|
37981
|
-
|
|
37982
|
-
|
|
37983
|
-
|
|
37984
|
-
|
|
37985
|
-
|
|
37986
|
-
|
|
37987
|
-
|
|
37988
|
-
|
|
37989
|
-
|
|
37990
|
-
|
|
37991
|
-
|
|
37992
|
-
|
|
37993
|
-
|
|
37994
|
-
|
|
37995
|
-
|
|
37996
|
-
|
|
37997
|
-
|
|
37998
|
-
|
|
37999
|
-
|
|
38000
|
-
|
|
38001
|
-
|
|
38002
|
-
|
|
38003
|
-
|
|
38004
|
-
|
|
38005
|
-
|
|
38006
|
-
|
|
38007
|
-
|
|
38008
|
-
|
|
38009
|
-
|
|
38010
|
-
|
|
38011
|
-
|
|
38012
|
-
|
|
38013
|
-
|
|
38014
|
-
|
|
38015
|
-
|
|
38016
|
-
|
|
38017
|
-
|
|
38018
|
-
|
|
38019
|
-
|
|
38020
|
-
|
|
38021
|
-
|
|
38022
|
-
|
|
38023
|
-
|
|
38024
|
-
|
|
38025
|
-
|
|
38026
|
-
|
|
38027
|
-
|
|
38028
|
-
);
|
|
38029
|
-
|
|
38030
|
-
|
|
38031
|
-
|
|
38032
|
-
|
|
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
|
-
|
|
37783
|
+
var CHANGE_DEBOUNCE_MS, ALLOWED_ATTRS, DROP_TAGS, MD_BLOCK_PREFIXES, BLOCK_TAGS, MD_INLINE_RULES, RICH_TEXT_CSS, IDLE_TOOLBAR, RichTextEditor;
|
|
37784
|
+
var init_RichTextEditor = __esm({
|
|
37785
|
+
"components/core/molecules/RichTextEditor.tsx"() {
|
|
37786
|
+
"use client";
|
|
37787
|
+
init_cn();
|
|
37788
|
+
init_Box();
|
|
37789
|
+
init_Button();
|
|
37790
|
+
init_useEventBus();
|
|
37791
|
+
CHANGE_DEBOUNCE_MS = 400;
|
|
37792
|
+
ALLOWED_ATTRS = {
|
|
37793
|
+
p: [],
|
|
37794
|
+
h1: [],
|
|
37795
|
+
h2: [],
|
|
37796
|
+
h3: [],
|
|
37797
|
+
h4: [],
|
|
37798
|
+
ul: [],
|
|
37799
|
+
ol: [],
|
|
37800
|
+
li: [],
|
|
37801
|
+
blockquote: [],
|
|
37802
|
+
pre: [],
|
|
37803
|
+
code: [],
|
|
37804
|
+
b: [],
|
|
37805
|
+
strong: [],
|
|
37806
|
+
i: [],
|
|
37807
|
+
em: [],
|
|
37808
|
+
u: [],
|
|
37809
|
+
s: [],
|
|
37810
|
+
strike: [],
|
|
37811
|
+
br: [],
|
|
37812
|
+
hr: [],
|
|
37813
|
+
div: [],
|
|
37814
|
+
span: [],
|
|
37815
|
+
a: ["href"],
|
|
37816
|
+
img: ["src", "alt"]
|
|
37817
|
+
};
|
|
37818
|
+
DROP_TAGS = /* @__PURE__ */ new Set(["script", "style", "iframe", "object", "embed", "link", "meta", "form", "input", "button", "textarea", "select"]);
|
|
37819
|
+
MD_BLOCK_PREFIXES = {
|
|
37820
|
+
"#": { kind: "block", tag: "h1" },
|
|
37821
|
+
"##": { kind: "block", tag: "h2" },
|
|
37822
|
+
"###": { kind: "block", tag: "h3" },
|
|
37823
|
+
">": { kind: "block", tag: "blockquote" },
|
|
37824
|
+
"```": { kind: "block", tag: "pre" },
|
|
37825
|
+
"-": { kind: "list", command: "insertUnorderedList" },
|
|
37826
|
+
"*": { kind: "list", command: "insertUnorderedList" },
|
|
37827
|
+
"1.": { kind: "list", command: "insertOrderedList" }
|
|
37828
|
+
};
|
|
37829
|
+
BLOCK_TAGS = /* @__PURE__ */ new Set(["P", "DIV", "LI", "H1", "H2", "H3", "H4", "BLOCKQUOTE", "PRE"]);
|
|
37830
|
+
MD_INLINE_RULES = [
|
|
37831
|
+
{ pattern: /\*\*([^*\n]+)\*\*$/, wrap: "strong" },
|
|
37832
|
+
{ pattern: /(^|[^*])\*([^*\n]+)\*$/, wrap: "em" },
|
|
37833
|
+
{ pattern: /`([^`\n]+)`$/, wrap: "code" }
|
|
37834
|
+
];
|
|
37835
|
+
RICH_TEXT_CSS = `
|
|
37836
|
+
.almadar-rich-text { line-height: 1.7; color: var(--color-foreground); }
|
|
37837
|
+
.almadar-rich-text h1 { font-size: 1.875rem; font-weight: 700; line-height: 1.25; margin: 1.25em 0 0.4em; }
|
|
37838
|
+
.almadar-rich-text h2 { font-size: 1.5rem; font-weight: 650; line-height: 1.3; margin: 1.1em 0 0.4em; }
|
|
37839
|
+
.almadar-rich-text h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.35; margin: 1em 0 0.35em; }
|
|
37840
|
+
.almadar-rich-text h1:first-child, .almadar-rich-text h2:first-child, .almadar-rich-text h3:first-child { margin-top: 0; }
|
|
37841
|
+
.almadar-rich-text p { margin: 0.5em 0; }
|
|
37842
|
+
.almadar-rich-text ul { list-style: disc; padding-inline-start: 1.5rem; margin: 0.5em 0; }
|
|
37843
|
+
.almadar-rich-text ol { list-style: decimal; padding-inline-start: 1.5rem; margin: 0.5em 0; }
|
|
37844
|
+
.almadar-rich-text li { margin: 0.25em 0; }
|
|
37845
|
+
.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; }
|
|
37846
|
+
.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; }
|
|
37847
|
+
.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; }
|
|
37848
|
+
.almadar-rich-text pre code { background: transparent; padding: 0; }
|
|
37849
|
+
.almadar-rich-text a { color: var(--color-primary); text-decoration: underline; }
|
|
37850
|
+
.almadar-rich-text hr { border: none; border-top: 1px solid var(--color-border); margin: 1.25em 0; }
|
|
37851
|
+
.almadar-rich-text img { max-width: 100%; border-radius: 0.375rem; }
|
|
37852
|
+
`;
|
|
37853
|
+
IDLE_TOOLBAR = {
|
|
37854
|
+
bold: false,
|
|
37855
|
+
italic: false,
|
|
37856
|
+
underline: false,
|
|
37857
|
+
strikeThrough: false,
|
|
37858
|
+
block: null,
|
|
37859
|
+
bullets: false,
|
|
37860
|
+
numbers: false,
|
|
37861
|
+
link: false
|
|
37862
|
+
};
|
|
37863
|
+
RichTextEditor = ({
|
|
37864
|
+
value,
|
|
37865
|
+
onChange,
|
|
37866
|
+
changeEvent,
|
|
37867
|
+
readOnly = false,
|
|
37868
|
+
placeholder,
|
|
37869
|
+
showToolbar = true,
|
|
37870
|
+
className
|
|
37871
|
+
}) => {
|
|
37872
|
+
const { t } = useTranslate();
|
|
37873
|
+
const ref = useRef(null);
|
|
37874
|
+
const [toolbar, setToolbar] = useState(IDLE_TOOLBAR);
|
|
37875
|
+
const [empty, setEmpty] = useState(() => !value || !sanitizeRichHtml(value).trim());
|
|
37876
|
+
const eventBus = useEventBus();
|
|
37877
|
+
const onChangeRef = useRef(onChange);
|
|
37878
|
+
const changeEventRef = useRef(changeEvent);
|
|
37879
|
+
useEffect(() => {
|
|
37880
|
+
onChangeRef.current = onChange;
|
|
37881
|
+
changeEventRef.current = changeEvent;
|
|
37882
|
+
}, [onChange, changeEvent]);
|
|
37883
|
+
const emitTimerRef = useRef(null);
|
|
37884
|
+
const emitNow = useCallback(() => {
|
|
37885
|
+
const el = ref.current;
|
|
37886
|
+
if (!el) return;
|
|
37887
|
+
const html = sanitizeRichHtml(el.innerHTML);
|
|
37888
|
+
onChangeRef.current?.(html);
|
|
37889
|
+
const evt = changeEventRef.current;
|
|
37890
|
+
if (evt) eventBus.emit(`UI:${evt}`, { value: html });
|
|
37891
|
+
}, [eventBus]);
|
|
37892
|
+
const scheduleEmit = useCallback(() => {
|
|
37893
|
+
if (emitTimerRef.current) clearTimeout(emitTimerRef.current);
|
|
37894
|
+
emitTimerRef.current = setTimeout(() => {
|
|
37895
|
+
emitTimerRef.current = null;
|
|
37896
|
+
emitNow();
|
|
37897
|
+
}, CHANGE_DEBOUNCE_MS);
|
|
37898
|
+
}, [emitNow]);
|
|
37899
|
+
const flushEmit = useCallback(() => {
|
|
37900
|
+
if (!emitTimerRef.current) return;
|
|
37901
|
+
clearTimeout(emitTimerRef.current);
|
|
37902
|
+
emitTimerRef.current = null;
|
|
37903
|
+
emitNow();
|
|
37904
|
+
}, [emitNow]);
|
|
37905
|
+
useEffect(() => () => {
|
|
37906
|
+
if (emitTimerRef.current) {
|
|
37907
|
+
clearTimeout(emitTimerRef.current);
|
|
37908
|
+
emitTimerRef.current = null;
|
|
37909
|
+
emitNow();
|
|
37910
|
+
}
|
|
37911
|
+
}, [emitNow]);
|
|
37912
|
+
useEffect(() => {
|
|
37913
|
+
if (readOnly) return;
|
|
37914
|
+
const el = ref.current;
|
|
37915
|
+
if (!el) return;
|
|
37916
|
+
if (document.activeElement === el) return;
|
|
37917
|
+
const next = sanitizeRichHtml(value ?? "") || "<p><br></p>";
|
|
37918
|
+
if (el.innerHTML !== next) {
|
|
37919
|
+
el.innerHTML = next;
|
|
37920
|
+
setEmpty(htmlIsEmpty(el));
|
|
37921
|
+
}
|
|
37922
|
+
}, [readOnly, value]);
|
|
37923
|
+
useEffect(() => {
|
|
37924
|
+
if (readOnly) return;
|
|
37925
|
+
document.execCommand("defaultParagraphSeparator", false, "p");
|
|
37926
|
+
}, [readOnly]);
|
|
37927
|
+
useEffect(() => {
|
|
37928
|
+
if (readOnly || !showToolbar) return;
|
|
37929
|
+
const onSelectionChange = () => {
|
|
37930
|
+
const el = ref.current;
|
|
37931
|
+
if (!el) return;
|
|
37932
|
+
setToolbar(readToolbarState(el));
|
|
38070
37933
|
};
|
|
38071
|
-
|
|
38072
|
-
|
|
38073
|
-
|
|
38074
|
-
|
|
38075
|
-
|
|
38076
|
-
|
|
38077
|
-
|
|
38078
|
-
|
|
38079
|
-
|
|
38080
|
-
|
|
38081
|
-
|
|
38082
|
-
|
|
38083
|
-
|
|
38084
|
-
|
|
38085
|
-
|
|
38086
|
-
|
|
38087
|
-
!
|
|
38088
|
-
|
|
38089
|
-
|
|
38090
|
-
|
|
38091
|
-
|
|
38092
|
-
|
|
38093
|
-
|
|
38094
|
-
|
|
38095
|
-
|
|
38096
|
-
|
|
38097
|
-
|
|
38098
|
-
|
|
38099
|
-
|
|
38100
|
-
|
|
38101
|
-
|
|
38102
|
-
|
|
38103
|
-
|
|
38104
|
-
|
|
38105
|
-
|
|
38106
|
-
|
|
38107
|
-
|
|
38108
|
-
|
|
38109
|
-
|
|
38110
|
-
|
|
38111
|
-
|
|
38112
|
-
|
|
38113
|
-
|
|
38114
|
-
|
|
38115
|
-
|
|
38116
|
-
|
|
38117
|
-
|
|
37934
|
+
document.addEventListener("selectionchange", onSelectionChange);
|
|
37935
|
+
return () => document.removeEventListener("selectionchange", onSelectionChange);
|
|
37936
|
+
}, [readOnly, showToolbar]);
|
|
37937
|
+
const tryInlineMarkdown = useCallback(() => {
|
|
37938
|
+
const root = ref.current;
|
|
37939
|
+
if (!root) return false;
|
|
37940
|
+
const sel = window.getSelection();
|
|
37941
|
+
if (!sel || !sel.isCollapsed || sel.rangeCount === 0) return false;
|
|
37942
|
+
const node = sel.anchorNode;
|
|
37943
|
+
if (!node || node.nodeType !== Node.TEXT_NODE || !root.contains(node)) return false;
|
|
37944
|
+
if (node.parentElement?.closest("code, pre")) return false;
|
|
37945
|
+
const text = (node.textContent ?? "").slice(0, sel.anchorOffset);
|
|
37946
|
+
for (const rule of MD_INLINE_RULES) {
|
|
37947
|
+
const m = rule.pattern.exec(text);
|
|
37948
|
+
if (!m) continue;
|
|
37949
|
+
const inner = rule.wrap === "em" ? m[2] : m[1];
|
|
37950
|
+
if (!inner || !inner.trim()) continue;
|
|
37951
|
+
const lead = rule.wrap === "em" ? m[1]?.length ?? 0 : 0;
|
|
37952
|
+
const range = document.createRange();
|
|
37953
|
+
range.setStart(node, m.index + lead);
|
|
37954
|
+
range.setEnd(node, sel.anchorOffset);
|
|
37955
|
+
const el = document.createElement(rule.wrap);
|
|
37956
|
+
el.textContent = inner;
|
|
37957
|
+
range.deleteContents();
|
|
37958
|
+
range.insertNode(el);
|
|
37959
|
+
const after = document.createTextNode("\u200B");
|
|
37960
|
+
el.parentNode?.insertBefore(after, el.nextSibling);
|
|
37961
|
+
const caret = document.createRange();
|
|
37962
|
+
caret.setStart(after, 1);
|
|
37963
|
+
caret.collapse(true);
|
|
37964
|
+
sel.removeAllRanges();
|
|
37965
|
+
sel.addRange(caret);
|
|
37966
|
+
return true;
|
|
37967
|
+
}
|
|
37968
|
+
return false;
|
|
37969
|
+
}, []);
|
|
37970
|
+
const tryBlockMarkdown = useCallback(() => {
|
|
37971
|
+
const root = ref.current;
|
|
37972
|
+
if (!root) return false;
|
|
37973
|
+
const sel = window.getSelection();
|
|
37974
|
+
if (!sel || !sel.isCollapsed || sel.rangeCount === 0) return false;
|
|
37975
|
+
const node = sel.anchorNode;
|
|
37976
|
+
if (!node || node.nodeType !== Node.TEXT_NODE || !root.contains(node)) return false;
|
|
37977
|
+
const block = closestBlock(node, root);
|
|
37978
|
+
if (block ? block.firstChild !== node : root.firstChild !== node) return false;
|
|
37979
|
+
const prefix = (node.textContent ?? "").slice(0, sel.anchorOffset);
|
|
37980
|
+
const rule = MD_BLOCK_PREFIXES[prefix];
|
|
37981
|
+
if (!rule) return false;
|
|
37982
|
+
if (node.parentElement?.closest("pre, code")) return false;
|
|
37983
|
+
if (rule.kind === "list" && node.parentElement?.closest("li")) return false;
|
|
37984
|
+
node.deleteData(0, prefix.length);
|
|
37985
|
+
const caret = document.createRange();
|
|
37986
|
+
caret.setStart(node, 0);
|
|
37987
|
+
caret.collapse(true);
|
|
37988
|
+
sel.removeAllRanges();
|
|
37989
|
+
sel.addRange(caret);
|
|
37990
|
+
if (rule.kind === "list") {
|
|
37991
|
+
const container = block ?? node.parentElement;
|
|
37992
|
+
const list = document.createElement(rule.command === "insertOrderedList" ? "ol" : "ul");
|
|
37993
|
+
const li = document.createElement("li");
|
|
37994
|
+
if (block) {
|
|
37995
|
+
while (block.firstChild) li.appendChild(block.firstChild);
|
|
37996
|
+
list.appendChild(li);
|
|
37997
|
+
block.replaceWith(list);
|
|
37998
|
+
} else if (container) {
|
|
37999
|
+
li.appendChild(node);
|
|
38000
|
+
list.appendChild(li);
|
|
38001
|
+
container.appendChild(list);
|
|
38002
|
+
}
|
|
38003
|
+
if (!li.firstChild) li.appendChild(document.createElement("br"));
|
|
38004
|
+
const liCaret = document.createRange();
|
|
38005
|
+
liCaret.selectNodeContents(li);
|
|
38006
|
+
liCaret.collapse(true);
|
|
38007
|
+
sel.removeAllRanges();
|
|
38008
|
+
sel.addRange(liCaret);
|
|
38009
|
+
} else {
|
|
38010
|
+
document.execCommand("formatBlock", false, rule.tag);
|
|
38011
|
+
}
|
|
38012
|
+
return true;
|
|
38013
|
+
}, []);
|
|
38014
|
+
const afterEdit = useCallback(() => {
|
|
38015
|
+
const el = ref.current;
|
|
38016
|
+
if (!el) return;
|
|
38017
|
+
tryInlineMarkdown();
|
|
38018
|
+
setEmpty(htmlIsEmpty(el));
|
|
38019
|
+
setToolbar(readToolbarState(el));
|
|
38020
|
+
scheduleEmit();
|
|
38021
|
+
}, [scheduleEmit, tryInlineMarkdown]);
|
|
38022
|
+
const handleKeyDown = useCallback((e) => {
|
|
38023
|
+
if (e.key === " " && tryBlockMarkdown()) {
|
|
38024
|
+
e.preventDefault();
|
|
38025
|
+
afterEdit();
|
|
38026
|
+
}
|
|
38027
|
+
}, [afterEdit, tryBlockMarkdown]);
|
|
38028
|
+
const execInline = useCallback((command) => {
|
|
38029
|
+
document.execCommand(command, false);
|
|
38030
|
+
afterEdit();
|
|
38031
|
+
}, [afterEdit]);
|
|
38032
|
+
const execBlock = useCallback((tag) => {
|
|
38033
|
+
const next = toolbar.block === tag ? "p" : tag;
|
|
38034
|
+
document.execCommand("formatBlock", false, next);
|
|
38035
|
+
afterEdit();
|
|
38036
|
+
}, [afterEdit, toolbar.block]);
|
|
38037
|
+
const execList = useCallback((command) => {
|
|
38038
|
+
document.execCommand(command, false);
|
|
38039
|
+
afterEdit();
|
|
38040
|
+
}, [afterEdit]);
|
|
38041
|
+
const execLink = useCallback(() => {
|
|
38042
|
+
if (toolbar.link) {
|
|
38043
|
+
document.execCommand("unlink", false);
|
|
38044
|
+
afterEdit();
|
|
38045
|
+
return;
|
|
38046
|
+
}
|
|
38047
|
+
const url = window.prompt(t("richTextEditor.linkPrompt"));
|
|
38048
|
+
if (!url) return;
|
|
38049
|
+
const safe = safeUrl(url, ["http://", "https://", "mailto:"]) ?? `https://${url}`;
|
|
38050
|
+
document.execCommand("createLink", false, safe);
|
|
38051
|
+
afterEdit();
|
|
38052
|
+
}, [afterEdit, t, toolbar.link]);
|
|
38053
|
+
const execRule = useCallback(() => {
|
|
38054
|
+
document.execCommand("insertHorizontalRule", false);
|
|
38055
|
+
afterEdit();
|
|
38056
|
+
}, [afterEdit]);
|
|
38057
|
+
if (readOnly) {
|
|
38058
|
+
return /* @__PURE__ */ jsxs(Box, { className: cn("almadar-rich-text max-w-none", className), children: [
|
|
38059
|
+
/* @__PURE__ */ jsx(RichTextStyles, {}),
|
|
38060
|
+
/* @__PURE__ */ jsx(Box, { dangerouslySetInnerHTML: { __html: sanitizeRichHtml(value ?? "") } })
|
|
38118
38061
|
] });
|
|
38119
38062
|
}
|
|
38120
|
-
|
|
38121
|
-
|
|
38122
|
-
|
|
38123
|
-
return /* @__PURE__ */ jsxs(
|
|
38063
|
+
return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col gap-2", className), children: [
|
|
38064
|
+
/* @__PURE__ */ jsx(RichTextStyles, {}),
|
|
38065
|
+
showToolbar && /* @__PURE__ */ jsxs(
|
|
38124
38066
|
Box,
|
|
38125
38067
|
{
|
|
38126
|
-
|
|
38068
|
+
role: "toolbar",
|
|
38069
|
+
"aria-label": t("richTextEditor.editorToolbar"),
|
|
38127
38070
|
className: cn(
|
|
38128
|
-
"
|
|
38129
|
-
|
|
38071
|
+
"sticky top-0 z-10 flex flex-wrap items-center gap-0.5 self-start",
|
|
38072
|
+
"rounded-md border border-border bg-background/95 px-1 py-0.5 shadow-sm"
|
|
38130
38073
|
),
|
|
38131
38074
|
children: [
|
|
38132
|
-
|
|
38133
|
-
|
|
38134
|
-
|
|
38135
|
-
|
|
38136
|
-
|
|
38137
|
-
|
|
38138
|
-
|
|
38139
|
-
|
|
38140
|
-
|
|
38141
|
-
|
|
38142
|
-
|
|
38143
|
-
|
|
38144
|
-
|
|
38145
|
-
|
|
38146
|
-
|
|
38147
|
-
|
|
38148
|
-
type: "button",
|
|
38149
|
-
variant: "ghost",
|
|
38150
|
-
"aria-label": t("richBlockEditor.aria.removeListItem"),
|
|
38151
|
-
className: cn(
|
|
38152
|
-
"h-5 w-5 shrink-0 rounded-sm text-muted-foreground p-0 gap-0",
|
|
38153
|
-
"opacity-0 group-hover/item:opacity-100 hover:bg-muted hover:text-foreground"
|
|
38154
|
-
),
|
|
38155
|
-
onClick: () => removeListItem(child.id),
|
|
38156
|
-
children: /* @__PURE__ */ jsx(Icon, { name: "trash", className: "w-3 h-3" })
|
|
38157
|
-
}
|
|
38158
|
-
)
|
|
38159
|
-
] }, child.id)),
|
|
38160
|
-
!readOnly && showAffordances && /* @__PURE__ */ jsx(Box, { as: "li", className: "list-none pl-0", children: /* @__PURE__ */ jsxs(
|
|
38161
|
-
Button,
|
|
38162
|
-
{
|
|
38163
|
-
type: "button",
|
|
38164
|
-
variant: "ghost",
|
|
38165
|
-
className: cn(
|
|
38166
|
-
"inline-flex items-center gap-1 text-xs text-muted-foreground",
|
|
38167
|
-
"hover:text-foreground p-0 h-auto"
|
|
38168
|
-
),
|
|
38169
|
-
onClick: addListItem,
|
|
38170
|
-
children: [
|
|
38171
|
-
/* @__PURE__ */ jsx(Icon, { name: "plus", className: "w-3 h-3" }),
|
|
38172
|
-
" ",
|
|
38173
|
-
t("richBlockEditor.addItem")
|
|
38174
|
-
]
|
|
38175
|
-
}
|
|
38176
|
-
) })
|
|
38075
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Bold, label: t("richTextEditor.bold"), active: toolbar.bold, onExec: () => execInline("bold") }),
|
|
38076
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Italic, label: t("richTextEditor.italic"), active: toolbar.italic, onExec: () => execInline("italic") }),
|
|
38077
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Underline, label: t("richTextEditor.underline"), active: toolbar.underline, onExec: () => execInline("underline") }),
|
|
38078
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Strikethrough, label: t("richTextEditor.strikethrough"), active: toolbar.strikeThrough, onExec: () => execInline("strikeThrough") }),
|
|
38079
|
+
/* @__PURE__ */ jsx(Box, { className: "mx-1 h-5 w-px bg-border" }),
|
|
38080
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Heading1, label: t("richTextEditor.heading1"), active: toolbar.block === "h1", onExec: () => execBlock("h1") }),
|
|
38081
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Heading2, label: t("richTextEditor.heading2"), active: toolbar.block === "h2", onExec: () => execBlock("h2") }),
|
|
38082
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Heading3, label: t("richTextEditor.heading3"), active: toolbar.block === "h3", onExec: () => execBlock("h3") }),
|
|
38083
|
+
/* @__PURE__ */ jsx(Box, { className: "mx-1 h-5 w-px bg-border" }),
|
|
38084
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: List, label: t("richTextEditor.bulletList"), active: toolbar.bullets, onExec: () => execList("insertUnorderedList") }),
|
|
38085
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: ListOrdered, label: t("richTextEditor.numberedList"), active: toolbar.numbers, onExec: () => execList("insertOrderedList") }),
|
|
38086
|
+
/* @__PURE__ */ jsx(Box, { className: "mx-1 h-5 w-px bg-border" }),
|
|
38087
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Quote, label: t("richTextEditor.quote"), active: toolbar.block === "blockquote", onExec: () => execBlock("blockquote") }),
|
|
38088
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Code, label: t("richTextEditor.code"), active: toolbar.block === "pre", onExec: () => execBlock("pre") }),
|
|
38089
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Link$1, label: toolbar.link ? t("richTextEditor.removeLink") : t("richTextEditor.link"), active: toolbar.link, onExec: execLink }),
|
|
38090
|
+
/* @__PURE__ */ jsx(ToolbarButton, { icon: Minus, label: t("richTextEditor.divider"), onExec: execRule })
|
|
38177
38091
|
]
|
|
38178
38092
|
}
|
|
38179
|
-
)
|
|
38180
|
-
|
|
38181
|
-
|
|
38182
|
-
default:
|
|
38183
|
-
return /* @__PURE__ */ jsx(
|
|
38184
|
-
Editable,
|
|
38093
|
+
),
|
|
38094
|
+
/* @__PURE__ */ jsx(
|
|
38095
|
+
Box,
|
|
38185
38096
|
{
|
|
38186
|
-
|
|
38187
|
-
|
|
38188
|
-
|
|
38189
|
-
|
|
38190
|
-
|
|
38191
|
-
|
|
38192
|
-
|
|
38097
|
+
ref,
|
|
38098
|
+
contentEditable: true,
|
|
38099
|
+
suppressContentEditableWarning: true,
|
|
38100
|
+
role: "textbox",
|
|
38101
|
+
"aria-multiline": "true",
|
|
38102
|
+
"aria-label": t("richTextEditor.editorSurface"),
|
|
38103
|
+
"data-placeholder": placeholder ?? t("richTextEditor.placeholder"),
|
|
38104
|
+
"data-empty": empty ? "true" : "false",
|
|
38105
|
+
className: cn(
|
|
38106
|
+
"almadar-rich-text max-w-none min-h-[8rem] outline-none",
|
|
38107
|
+
"data-[empty=true]:before:content-[attr(data-placeholder)]",
|
|
38108
|
+
"data-[empty=true]:before:text-muted-foreground/60",
|
|
38109
|
+
"data-[empty=true]:before:pointer-events-none",
|
|
38110
|
+
"data-[empty=true]:before:absolute",
|
|
38111
|
+
"relative cursor-text"
|
|
38112
|
+
),
|
|
38113
|
+
onInput: afterEdit,
|
|
38114
|
+
onKeyDown: handleKeyDown,
|
|
38115
|
+
onBlur: flushEmit
|
|
38193
38116
|
}
|
|
38194
|
-
)
|
|
38195
|
-
|
|
38117
|
+
)
|
|
38118
|
+
] });
|
|
38119
|
+
};
|
|
38120
|
+
RichTextEditor.displayName = "RichTextEditor";
|
|
38121
|
+
}
|
|
38122
|
+
});
|
|
38123
|
+
function renderIconInput4(icon, props) {
|
|
38124
|
+
return typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsx(Icon, { icon, ...props });
|
|
38125
|
+
}
|
|
38126
|
+
function DocumentPanel({
|
|
38127
|
+
entity,
|
|
38128
|
+
title,
|
|
38129
|
+
subtitle,
|
|
38130
|
+
value,
|
|
38131
|
+
actions,
|
|
38132
|
+
maxInlineActions,
|
|
38133
|
+
editing = false,
|
|
38134
|
+
titleCommitEvent,
|
|
38135
|
+
contentChangeEvent,
|
|
38136
|
+
editEvent,
|
|
38137
|
+
doneEvent,
|
|
38138
|
+
editLabel,
|
|
38139
|
+
doneLabel,
|
|
38140
|
+
autosaveHint,
|
|
38141
|
+
placeholder,
|
|
38142
|
+
className
|
|
38143
|
+
}) {
|
|
38144
|
+
const eventBus = useEventBus();
|
|
38145
|
+
const { t } = useTranslate();
|
|
38146
|
+
const [titleDraft, setTitleDraft] = useState(null);
|
|
38147
|
+
const recordId = entity?.id !== void 0 && entity?.id !== null ? String(entity.id) : "";
|
|
38148
|
+
const actionDefs = actions ?? [];
|
|
38149
|
+
const inlineCap = Math.min(maxInlineActions ?? 1, 1);
|
|
38150
|
+
const inlineActions = actionDefs.filter((a) => a.variant === "primary").slice(0, inlineCap);
|
|
38151
|
+
const menuActions = actionDefs.filter((a) => !inlineActions.includes(a));
|
|
38152
|
+
const fireAction = (action) => {
|
|
38153
|
+
if (!action.event) return;
|
|
38154
|
+
eventBus.emit(`UI:${action.event}`, { id: recordId, row: entity });
|
|
38196
38155
|
};
|
|
38197
|
-
|
|
38156
|
+
const commitTitle = () => {
|
|
38157
|
+
if (!titleCommitEvent) return;
|
|
38158
|
+
const next = (titleDraft ?? "").trim();
|
|
38159
|
+
setTitleDraft(null);
|
|
38160
|
+
if (!next || next === title) return;
|
|
38161
|
+
eventBus.emit(`UI:${titleCommitEvent}`, { title: next, id: recordId });
|
|
38162
|
+
};
|
|
38163
|
+
const untitled = t("documentPanel.untitled") || "Untitled";
|
|
38164
|
+
const titleNode = titleCommitEvent && titleDraft !== null ? /* @__PURE__ */ jsx(
|
|
38165
|
+
Input,
|
|
38166
|
+
{
|
|
38167
|
+
value: titleDraft,
|
|
38168
|
+
autoFocus: true,
|
|
38169
|
+
"aria-label": t("common.title"),
|
|
38170
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
38171
|
+
onFocus: (e) => e.currentTarget.select(),
|
|
38172
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
38173
|
+
onBlur: commitTitle,
|
|
38174
|
+
onKeyDown: (e) => {
|
|
38175
|
+
if (e.key === "Enter") {
|
|
38176
|
+
e.preventDefault();
|
|
38177
|
+
commitTitle();
|
|
38178
|
+
} else if (e.key === "Escape") {
|
|
38179
|
+
e.preventDefault();
|
|
38180
|
+
setTitleDraft(null);
|
|
38181
|
+
}
|
|
38182
|
+
},
|
|
38183
|
+
"data-testid": "document-title-input"
|
|
38184
|
+
}
|
|
38185
|
+
) : titleCommitEvent ? /* @__PURE__ */ jsx(
|
|
38198
38186
|
Box,
|
|
38199
38187
|
{
|
|
38200
|
-
|
|
38201
|
-
|
|
38202
|
-
|
|
38203
|
-
),
|
|
38204
|
-
|
|
38205
|
-
|
|
38206
|
-
|
|
38207
|
-
|
|
38208
|
-
|
|
38188
|
+
role: "button",
|
|
38189
|
+
tabIndex: 0,
|
|
38190
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
38191
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
38192
|
+
onKeyDown: (e) => {
|
|
38193
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
38194
|
+
e.preventDefault();
|
|
38195
|
+
setTitleDraft(title ?? "");
|
|
38196
|
+
}
|
|
38197
|
+
},
|
|
38198
|
+
"data-testid": "document-title-editable",
|
|
38199
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", className: cn(!title && "text-muted-foreground"), children: title || untitled })
|
|
38200
|
+
}
|
|
38201
|
+
) : /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || untitled });
|
|
38202
|
+
const emitWithId = (event) => () => {
|
|
38203
|
+
if (event) eventBus.emit(`UI:${event}`, { id: recordId });
|
|
38204
|
+
};
|
|
38205
|
+
return /* @__PURE__ */ jsx(Card, { variant: "elevated", className: cn("w-full", className), children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: "p-6 sm:p-8", children: [
|
|
38206
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
38207
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
38208
|
+
titleNode,
|
|
38209
|
+
subtitle ? /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: subtitle }) : null
|
|
38210
|
+
] }),
|
|
38211
|
+
/* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0 pt-1 items-center", children: editing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38212
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", className: "hidden sm:block", children: autosaveHint ?? (t("documentPanel.autosaveHint") || "") }),
|
|
38213
|
+
/* @__PURE__ */ jsx(Button, { variant: "primary", size: "sm", onClick: emitWithId(doneEvent), "data-testid": "document-done", children: doneLabel ?? (t("documentPanel.done") || "Done") })
|
|
38214
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38215
|
+
editEvent && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: emitWithId(editEvent), "data-testid": "document-edit", children: [
|
|
38216
|
+
/* @__PURE__ */ jsx(Icon, { name: "edit", size: "xs", className: "mr-1" }),
|
|
38217
|
+
editLabel ?? (t("documentPanel.edit") || "Edit")
|
|
38218
|
+
] }),
|
|
38219
|
+
inlineActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
38220
|
+
Button,
|
|
38209
38221
|
{
|
|
38210
|
-
|
|
38211
|
-
|
|
38212
|
-
|
|
38213
|
-
|
|
38214
|
-
|
|
38222
|
+
variant: "primary",
|
|
38223
|
+
size: "sm",
|
|
38224
|
+
onClick: () => fireAction(action),
|
|
38225
|
+
"data-testid": `action-${action.event}`,
|
|
38226
|
+
children: [
|
|
38227
|
+
action.icon && renderIconInput4(action.icon, { size: "xs", className: "mr-1" }),
|
|
38228
|
+
action.label
|
|
38229
|
+
]
|
|
38230
|
+
},
|
|
38231
|
+
idx
|
|
38232
|
+
)),
|
|
38233
|
+
menuActions.length > 0 && /* @__PURE__ */ jsx(
|
|
38234
|
+
Menu,
|
|
38235
|
+
{
|
|
38236
|
+
position: "bottom-end",
|
|
38237
|
+
trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
38238
|
+
items: menuActions.map((action) => ({
|
|
38239
|
+
label: action.label,
|
|
38240
|
+
icon: action.icon,
|
|
38241
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
38242
|
+
onClick: () => fireAction(action)
|
|
38243
|
+
}))
|
|
38215
38244
|
}
|
|
38216
|
-
)
|
|
38217
|
-
|
|
38218
|
-
|
|
38219
|
-
}
|
|
38220
|
-
|
|
38245
|
+
)
|
|
38246
|
+
] }) })
|
|
38247
|
+
] }),
|
|
38248
|
+
editing ? /* @__PURE__ */ jsx(RichTextEditor, { value, changeEvent: contentChangeEvent, placeholder }) : /* @__PURE__ */ jsx(
|
|
38249
|
+
Box,
|
|
38250
|
+
{
|
|
38251
|
+
onClick: emitWithId(editEvent),
|
|
38252
|
+
className: cn(
|
|
38253
|
+
"rounded-md px-1 -mx-1 min-h-[16rem]",
|
|
38254
|
+
editEvent && "cursor-text transition-colors hover:bg-muted/30"
|
|
38255
|
+
),
|
|
38256
|
+
"data-testid": "document-body",
|
|
38257
|
+
children: value && value !== "" ? /* @__PURE__ */ jsx(RichTextEditor, { value, readOnly: true }) : /* @__PURE__ */ jsx(Typography, { variant: "body", color: "muted", children: placeholder ?? (t("documentPanel.placeholder") || "") })
|
|
38258
|
+
}
|
|
38259
|
+
)
|
|
38260
|
+
] }) });
|
|
38221
38261
|
}
|
|
38222
|
-
var
|
|
38223
|
-
|
|
38224
|
-
"components/core/molecules/RichBlockEditor.tsx"() {
|
|
38262
|
+
var init_DocumentPanel = __esm({
|
|
38263
|
+
"components/core/molecules/DocumentPanel.tsx"() {
|
|
38225
38264
|
"use client";
|
|
38226
38265
|
init_cn();
|
|
38227
|
-
|
|
38266
|
+
init_useEventBus();
|
|
38267
|
+
init_Box();
|
|
38268
|
+
init_Stack();
|
|
38228
38269
|
init_Typography();
|
|
38229
38270
|
init_Button();
|
|
38230
|
-
|
|
38231
|
-
init_Divider();
|
|
38232
|
-
init_Input();
|
|
38271
|
+
init_Card();
|
|
38233
38272
|
init_Icon();
|
|
38234
|
-
|
|
38235
|
-
|
|
38236
|
-
|
|
38237
|
-
|
|
38238
|
-
|
|
38239
|
-
|
|
38240
|
-
|
|
38241
|
-
|
|
38242
|
-
|
|
38243
|
-
|
|
38244
|
-
|
|
38245
|
-
|
|
38246
|
-
|
|
38247
|
-
|
|
38248
|
-
|
|
38249
|
-
|
|
38250
|
-
|
|
38251
|
-
|
|
38252
|
-
|
|
38253
|
-
|
|
38254
|
-
|
|
38255
|
-
|
|
38256
|
-
|
|
38257
|
-
|
|
38258
|
-
|
|
38259
|
-
|
|
38260
|
-
|
|
38261
|
-
|
|
38262
|
-
|
|
38263
|
-
|
|
38264
|
-
|
|
38265
|
-
|
|
38266
|
-
|
|
38267
|
-
|
|
38268
|
-
|
|
38269
|
-
|
|
38270
|
-
|
|
38271
|
-
|
|
38272
|
-
|
|
38273
|
-
|
|
38274
|
-
|
|
38275
|
-
|
|
38276
|
-
|
|
38277
|
-
|
|
38278
|
-
|
|
38279
|
-
|
|
38280
|
-
|
|
38281
|
-
|
|
38282
|
-
|
|
38283
|
-
|
|
38284
|
-
|
|
38285
|
-
|
|
38286
|
-
|
|
38287
|
-
|
|
38288
|
-
|
|
38289
|
-
|
|
38290
|
-
|
|
38291
|
-
|
|
38292
|
-
|
|
38293
|
-
const [blocks, setBlocks] = useState(
|
|
38294
|
-
() => normalizeBlocks(initialBlocks)
|
|
38295
|
-
);
|
|
38296
|
-
const onChangeRef = useRef(onChange);
|
|
38297
|
-
useEffect(() => {
|
|
38298
|
-
onChangeRef.current = onChange;
|
|
38299
|
-
}, [onChange]);
|
|
38300
|
-
const eventBus = useEventBus();
|
|
38301
|
-
const changeEventRef = useRef(changeEvent);
|
|
38302
|
-
useEffect(() => {
|
|
38303
|
-
changeEventRef.current = changeEvent;
|
|
38304
|
-
}, [changeEvent]);
|
|
38305
|
-
const commit = useCallback((next) => {
|
|
38306
|
-
setBlocks(next);
|
|
38307
|
-
onChangeRef.current?.(next);
|
|
38308
|
-
const evt = changeEventRef.current;
|
|
38309
|
-
if (evt) eventBus.emit(`UI:${evt}`, { blocks: next });
|
|
38310
|
-
}, [eventBus]);
|
|
38311
|
-
const handleAppend = useCallback(
|
|
38312
|
-
(type) => {
|
|
38313
|
-
if (readOnly) return;
|
|
38314
|
-
commit([...blocks, createBlock(type)]);
|
|
38315
|
-
},
|
|
38316
|
-
[blocks, commit, readOnly]
|
|
38317
|
-
);
|
|
38318
|
-
const handleUpdate = useCallback(
|
|
38319
|
-
(id, updater) => {
|
|
38320
|
-
commit(replaceBlock(blocks, id, updater));
|
|
38321
|
-
},
|
|
38322
|
-
[blocks, commit]
|
|
38323
|
-
);
|
|
38324
|
-
const handleDelete = useCallback(
|
|
38325
|
-
(id) => {
|
|
38326
|
-
const next = removeBlock(blocks, id);
|
|
38327
|
-
commit(next.length > 0 ? next : [createBlock("paragraph")]);
|
|
38328
|
-
},
|
|
38329
|
-
[blocks, commit]
|
|
38330
|
-
);
|
|
38331
|
-
const handleDuplicate = useCallback(
|
|
38332
|
-
(id) => {
|
|
38333
|
-
const target = blocks.find((b) => b.id === id);
|
|
38334
|
-
if (!target) return;
|
|
38335
|
-
commit(insertAfter(blocks, id, duplicateBlock(target)));
|
|
38336
|
-
},
|
|
38337
|
-
[blocks, commit]
|
|
38273
|
+
init_Input();
|
|
38274
|
+
init_Menu();
|
|
38275
|
+
init_RichTextEditor();
|
|
38276
|
+
}
|
|
38277
|
+
});
|
|
38278
|
+
function renderIconInput5(icon, props) {
|
|
38279
|
+
return typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsx(Icon, { icon, ...props });
|
|
38280
|
+
}
|
|
38281
|
+
function fieldName(field) {
|
|
38282
|
+
return field.name ?? field.key ?? "";
|
|
38283
|
+
}
|
|
38284
|
+
function relationLabel(value) {
|
|
38285
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date) return null;
|
|
38286
|
+
for (const key of ["name", "title", "label"]) {
|
|
38287
|
+
const candidate = value[key];
|
|
38288
|
+
if (typeof candidate === "string" && candidate !== "") return candidate;
|
|
38289
|
+
}
|
|
38290
|
+
const id = value.id;
|
|
38291
|
+
return id !== void 0 && id !== null ? String(id) : null;
|
|
38292
|
+
}
|
|
38293
|
+
function fieldKind(field, value) {
|
|
38294
|
+
if (field.kind) return field.kind;
|
|
38295
|
+
if (field.options && field.options.length > 0) return "select";
|
|
38296
|
+
if (typeof value === "boolean" || field.format === "boolean") return "boolean";
|
|
38297
|
+
if (Array.isArray(value) || relationLabel(value ?? null) !== null) return "readonly";
|
|
38298
|
+
return "text";
|
|
38299
|
+
}
|
|
38300
|
+
function DocumentDetails({
|
|
38301
|
+
entity,
|
|
38302
|
+
fields,
|
|
38303
|
+
metaCommitEvent,
|
|
38304
|
+
title,
|
|
38305
|
+
className
|
|
38306
|
+
}) {
|
|
38307
|
+
const eventBus = useEventBus();
|
|
38308
|
+
const { t } = useTranslate();
|
|
38309
|
+
const [fieldDraft, setFieldDraft] = useState(null);
|
|
38310
|
+
const recordId = entity?.id !== void 0 && entity?.id !== null ? String(entity.id) : "";
|
|
38311
|
+
const fieldDefs = (fields ?? []).filter((f3) => fieldName(f3) !== "");
|
|
38312
|
+
if (fieldDefs.length === 0) return null;
|
|
38313
|
+
const commitField = (name, next, current) => {
|
|
38314
|
+
setFieldDraft(null);
|
|
38315
|
+
if (!metaCommitEvent || next === current) return;
|
|
38316
|
+
eventBus.emit(`UI:${metaCommitEvent}`, { id: recordId, patch: { id: recordId, [name]: next } });
|
|
38317
|
+
};
|
|
38318
|
+
const renderValue = (field) => {
|
|
38319
|
+
const name = fieldName(field);
|
|
38320
|
+
const raw = getNestedValue(entity ?? {}, name);
|
|
38321
|
+
const kind = fieldKind(field, raw);
|
|
38322
|
+
const label = field.label ?? field.header ?? humanizeFieldName(name);
|
|
38323
|
+
if (kind === "boolean") {
|
|
38324
|
+
return /* @__PURE__ */ jsx(
|
|
38325
|
+
Switch,
|
|
38326
|
+
{
|
|
38327
|
+
checked: Boolean(raw),
|
|
38328
|
+
disabled: !metaCommitEvent,
|
|
38329
|
+
"aria-label": label,
|
|
38330
|
+
onChange: (checked) => commitField(name, checked, Boolean(raw))
|
|
38331
|
+
}
|
|
38338
38332
|
);
|
|
38339
|
-
|
|
38340
|
-
|
|
38341
|
-
|
|
38342
|
-
|
|
38343
|
-
|
|
38344
|
-
|
|
38345
|
-
|
|
38333
|
+
}
|
|
38334
|
+
if (kind === "select") {
|
|
38335
|
+
return /* @__PURE__ */ jsx(
|
|
38336
|
+
Select,
|
|
38337
|
+
{
|
|
38338
|
+
value: raw !== void 0 && raw !== null ? String(raw) : "",
|
|
38339
|
+
disabled: !metaCommitEvent,
|
|
38340
|
+
"aria-label": label,
|
|
38341
|
+
className: "h-8 w-full",
|
|
38342
|
+
options: (field.options ?? []).map((opt) => ({ value: opt, label: humanizeEnumValue(opt) })),
|
|
38343
|
+
onChange: (e) => commitField(name, e.target.value, raw)
|
|
38344
|
+
}
|
|
38346
38345
|
);
|
|
38347
|
-
|
|
38348
|
-
|
|
38346
|
+
}
|
|
38347
|
+
if (kind === "readonly" || !metaCommitEvent) {
|
|
38348
|
+
if (Array.isArray(raw)) {
|
|
38349
|
+
if (raw.length === 0) {
|
|
38350
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: "\u2014" });
|
|
38351
|
+
}
|
|
38352
|
+
return /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: raw.map((item, i) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: relationLabel(item) ?? humanizeEnumValue(String(item)) }, i)) });
|
|
38353
|
+
}
|
|
38354
|
+
const shown2 = raw === void 0 || raw === null || raw === "" ? "\u2014" : relationLabel(raw) ?? formatValue(raw, field.format);
|
|
38355
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "small", className: "break-words", children: shown2 });
|
|
38356
|
+
}
|
|
38357
|
+
if (fieldDraft?.name === name) {
|
|
38358
|
+
return /* @__PURE__ */ jsx(
|
|
38359
|
+
Input,
|
|
38349
38360
|
{
|
|
38350
|
-
|
|
38351
|
-
|
|
38352
|
-
|
|
38353
|
-
|
|
38354
|
-
|
|
38355
|
-
|
|
38356
|
-
|
|
38357
|
-
|
|
38358
|
-
|
|
38359
|
-
|
|
38360
|
-
|
|
38361
|
-
|
|
38362
|
-
|
|
38363
|
-
|
|
38364
|
-
|
|
38365
|
-
|
|
38366
|
-
return /* @__PURE__ */ jsxs(
|
|
38367
|
-
Button,
|
|
38368
|
-
{
|
|
38369
|
-
type: "button",
|
|
38370
|
-
variant: "ghost",
|
|
38371
|
-
size: "sm",
|
|
38372
|
-
"aria-label": t("richBlockEditor.insertEntry", { label: entryLabel }),
|
|
38373
|
-
title: entryLabel,
|
|
38374
|
-
onClick: () => handleAppend(entry.type),
|
|
38375
|
-
children: [
|
|
38376
|
-
/* @__PURE__ */ jsx(Icon2, { size: 14 }),
|
|
38377
|
-
/* @__PURE__ */ jsx(Typography, { as: "span", variant: "caption", className: "ml-1 hidden text-xs sm:inline", children: entryLabel })
|
|
38378
|
-
]
|
|
38379
|
-
},
|
|
38380
|
-
entry.type
|
|
38381
|
-
);
|
|
38382
|
-
})
|
|
38383
|
-
}
|
|
38384
|
-
),
|
|
38385
|
-
/* @__PURE__ */ jsx(Box, { className: "flex flex-col gap-1 px-3 py-3", children: blocks.map((block) => /* @__PURE__ */ jsx(
|
|
38386
|
-
BlockRow,
|
|
38387
|
-
{
|
|
38388
|
-
block,
|
|
38389
|
-
readOnly,
|
|
38390
|
-
showAffordances: enableBlocks,
|
|
38391
|
-
placeholder,
|
|
38392
|
-
onUpdate: (updater) => handleUpdate(block.id, updater),
|
|
38393
|
-
onDelete: () => handleDelete(block.id),
|
|
38394
|
-
onDuplicate: () => handleDuplicate(block.id),
|
|
38395
|
-
onChangeType: (type) => handleChangeType(block.id, type)
|
|
38396
|
-
},
|
|
38397
|
-
block.id
|
|
38398
|
-
)) })
|
|
38399
|
-
]
|
|
38361
|
+
value: fieldDraft.value,
|
|
38362
|
+
autoFocus: true,
|
|
38363
|
+
"aria-label": label,
|
|
38364
|
+
className: "h-8 w-full",
|
|
38365
|
+
onChange: (e) => setFieldDraft({ name, value: e.target.value }),
|
|
38366
|
+
onBlur: () => commitField(name, fieldDraft.value.trim(), raw),
|
|
38367
|
+
onKeyDown: (e) => {
|
|
38368
|
+
if (e.key === "Enter") {
|
|
38369
|
+
e.preventDefault();
|
|
38370
|
+
commitField(name, fieldDraft.value.trim(), raw);
|
|
38371
|
+
} else if (e.key === "Escape") {
|
|
38372
|
+
e.preventDefault();
|
|
38373
|
+
setFieldDraft(null);
|
|
38374
|
+
}
|
|
38375
|
+
},
|
|
38376
|
+
"data-testid": `document-property-input-${name}`
|
|
38400
38377
|
}
|
|
38401
38378
|
);
|
|
38402
|
-
}
|
|
38403
|
-
|
|
38379
|
+
}
|
|
38380
|
+
const shown = raw === void 0 || raw === null || raw === "" ? "\u2014" : relationLabel(raw) ?? formatValue(raw, field.format);
|
|
38381
|
+
return /* @__PURE__ */ jsx(
|
|
38382
|
+
Box,
|
|
38383
|
+
{
|
|
38384
|
+
role: "button",
|
|
38385
|
+
tabIndex: 0,
|
|
38386
|
+
className: cn(
|
|
38387
|
+
"cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
38388
|
+
(raw === void 0 || raw === null || raw === "") && "text-muted-foreground"
|
|
38389
|
+
),
|
|
38390
|
+
onClick: () => setFieldDraft({ name, value: raw !== void 0 && raw !== null ? String(raw) : "" }),
|
|
38391
|
+
onKeyDown: (e) => {
|
|
38392
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
38393
|
+
e.preventDefault();
|
|
38394
|
+
setFieldDraft({ name, value: raw !== void 0 && raw !== null ? String(raw) : "" });
|
|
38395
|
+
}
|
|
38396
|
+
},
|
|
38397
|
+
"data-testid": `document-property-${name}`,
|
|
38398
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "break-words", children: shown })
|
|
38399
|
+
}
|
|
38400
|
+
);
|
|
38401
|
+
};
|
|
38402
|
+
return /* @__PURE__ */ jsx(Card, { variant: "bordered", className: cn("w-full", className), children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", className: "p-4", children: [
|
|
38403
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", weight: "medium", className: "uppercase tracking-wide", children: title ?? (t("documentDetails.title") || "Details") }),
|
|
38404
|
+
/* @__PURE__ */ jsx(VStack, { gap: "sm", children: fieldDefs.map((field) => {
|
|
38405
|
+
const name = fieldName(field);
|
|
38406
|
+
const label = field.label ?? field.header ?? humanizeFieldName(name);
|
|
38407
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "xs", children: [
|
|
38408
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
38409
|
+
field.icon && renderIconInput5(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
38410
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: label })
|
|
38411
|
+
] }),
|
|
38412
|
+
/* @__PURE__ */ jsx(Box, { className: "min-w-0", children: renderValue(field) })
|
|
38413
|
+
] }, name);
|
|
38414
|
+
}) })
|
|
38415
|
+
] }) });
|
|
38416
|
+
}
|
|
38417
|
+
var init_DocumentDetails = __esm({
|
|
38418
|
+
"components/core/molecules/DocumentDetails.tsx"() {
|
|
38419
|
+
"use client";
|
|
38420
|
+
init_cn();
|
|
38421
|
+
init_format();
|
|
38422
|
+
init_getNestedValue();
|
|
38423
|
+
init_useEventBus();
|
|
38424
|
+
init_Box();
|
|
38425
|
+
init_Stack();
|
|
38426
|
+
init_Typography();
|
|
38427
|
+
init_Badge();
|
|
38428
|
+
init_Card();
|
|
38429
|
+
init_Icon();
|
|
38430
|
+
init_Input();
|
|
38431
|
+
init_Select();
|
|
38432
|
+
init_Switch();
|
|
38404
38433
|
}
|
|
38405
38434
|
});
|
|
38406
38435
|
function collectInitiallyCollapsed(nodes, acc) {
|
|
@@ -43074,7 +43103,9 @@ var init_molecules2 = __esm({
|
|
|
43074
43103
|
init_QrScanner();
|
|
43075
43104
|
init_OptionConstraintGroup();
|
|
43076
43105
|
init_PositionedCanvas();
|
|
43077
|
-
|
|
43106
|
+
init_RichTextEditor();
|
|
43107
|
+
init_DocumentPanel();
|
|
43108
|
+
init_DocumentDetails();
|
|
43078
43109
|
init_ReplyTree();
|
|
43079
43110
|
init_BranchingLogicBuilder();
|
|
43080
43111
|
init_VersionDiff();
|
|
@@ -43574,8 +43605,8 @@ var init_DataTable = __esm({
|
|
|
43574
43605
|
DataTable.displayName = "DataTable";
|
|
43575
43606
|
}
|
|
43576
43607
|
});
|
|
43577
|
-
function getBadgeVariant(
|
|
43578
|
-
const name =
|
|
43608
|
+
function getBadgeVariant(fieldName2, value) {
|
|
43609
|
+
const name = fieldName2.toLowerCase();
|
|
43579
43610
|
const val = String(value).toLowerCase();
|
|
43580
43611
|
if (name.includes("status")) {
|
|
43581
43612
|
if (val.includes("complete") || val.includes("done") || val.includes("active"))
|
|
@@ -43591,12 +43622,12 @@ function getBadgeVariant(fieldName, value) {
|
|
|
43591
43622
|
}
|
|
43592
43623
|
return "default";
|
|
43593
43624
|
}
|
|
43594
|
-
function formatFieldValue2(value,
|
|
43625
|
+
function formatFieldValue2(value, fieldName2) {
|
|
43595
43626
|
if (typeof value === "number") {
|
|
43596
|
-
if (
|
|
43627
|
+
if (fieldName2.toLowerCase().includes("progress") || fieldName2.toLowerCase().includes("percent")) {
|
|
43597
43628
|
return `${value}%`;
|
|
43598
43629
|
}
|
|
43599
|
-
if (
|
|
43630
|
+
if (fieldName2.toLowerCase().includes("budget") || fieldName2.toLowerCase().includes("cost")) {
|
|
43600
43631
|
return `$${value.toLocaleString()}`;
|
|
43601
43632
|
}
|
|
43602
43633
|
return value.toLocaleString();
|
|
@@ -43606,7 +43637,7 @@ function formatFieldValue2(value, fieldName) {
|
|
|
43606
43637
|
}
|
|
43607
43638
|
return String(value);
|
|
43608
43639
|
}
|
|
43609
|
-
function renderRichFieldValue(value,
|
|
43640
|
+
function renderRichFieldValue(value, fieldName2, fieldType, meta) {
|
|
43610
43641
|
if (value === void 0 || value === null) return "\u2014";
|
|
43611
43642
|
const str2 = String(value);
|
|
43612
43643
|
switch (fieldType) {
|
|
@@ -43617,7 +43648,7 @@ function renderRichFieldValue(value, fieldName, fieldType, meta) {
|
|
|
43617
43648
|
"img",
|
|
43618
43649
|
{
|
|
43619
43650
|
src: str2,
|
|
43620
|
-
alt: formatFieldLabel(
|
|
43651
|
+
alt: formatFieldLabel(fieldName2),
|
|
43621
43652
|
className: "max-w-full max-h-64 rounded-md object-contain",
|
|
43622
43653
|
loading: "lazy"
|
|
43623
43654
|
}
|
|
@@ -43752,9 +43783,9 @@ function renderRichFieldValue(value, fieldName, fieldType, meta) {
|
|
|
43752
43783
|
return /* @__PURE__ */ jsx("a", { href: `tel:${str2}`, className: "text-primary hover:underline", children: str2 });
|
|
43753
43784
|
default:
|
|
43754
43785
|
if (meta?.values && meta.values.length > 0 && meta.values.includes(str2)) {
|
|
43755
|
-
return /* @__PURE__ */ jsx(Badge, { variant: getBadgeVariant(
|
|
43786
|
+
return /* @__PURE__ */ jsx(Badge, { variant: getBadgeVariant(fieldName2, str2), children: humanizeEnumValue(str2) });
|
|
43756
43787
|
}
|
|
43757
|
-
return formatFieldValue2(value,
|
|
43788
|
+
return formatFieldValue2(value, fieldName2);
|
|
43758
43789
|
}
|
|
43759
43790
|
}
|
|
43760
43791
|
function normalizeFieldDefs(fields) {
|
|
@@ -44224,16 +44255,11 @@ var init_DetailPanel = __esm({
|
|
|
44224
44255
|
footer
|
|
44225
44256
|
] })
|
|
44226
44257
|
] }) });
|
|
44227
|
-
|
|
44228
|
-
Box,
|
|
44229
|
-
|
|
44230
|
-
|
|
44231
|
-
|
|
44232
|
-
className
|
|
44233
|
-
),
|
|
44234
|
-
children: content
|
|
44235
|
-
}
|
|
44236
|
-
);
|
|
44258
|
+
if (!slideOver) {
|
|
44259
|
+
return /* @__PURE__ */ jsx(Box, { className, children: content });
|
|
44260
|
+
}
|
|
44261
|
+
const panel = /* @__PURE__ */ jsx(Box, { className: cn("fixed inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
|
|
44262
|
+
return typeof document === "undefined" ? panel : createPortal(panel, document.body);
|
|
44237
44263
|
};
|
|
44238
44264
|
DetailPanel.displayName = "DetailPanel";
|
|
44239
44265
|
}
|
|
@@ -44602,7 +44628,21 @@ var init_Form = __esm({
|
|
|
44602
44628
|
const normalizedInitialData = React77__default.useMemo(() => {
|
|
44603
44629
|
const entityRowAsInitial = isPlainEntityRow(entity) ? entity : void 0;
|
|
44604
44630
|
const callerInitial = initialData !== null && typeof initialData === "object" && !Array.isArray(initialData) ? initialData : {};
|
|
44605
|
-
|
|
44631
|
+
const merged = entityRowAsInitial !== void 0 ? { ...entityRowAsInitial, ...callerInitial } : callerInitial;
|
|
44632
|
+
const toId = (value) => {
|
|
44633
|
+
if (value === null || value === void 0 || typeof value !== "object" || value instanceof Date) return value;
|
|
44634
|
+
if (Array.isArray(value)) {
|
|
44635
|
+
return value.map(
|
|
44636
|
+
(item) => item !== null && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && item.id !== void 0 && item.id !== null ? String(item.id) : item
|
|
44637
|
+
);
|
|
44638
|
+
}
|
|
44639
|
+
return value.id !== void 0 && value.id !== null ? String(value.id) : value;
|
|
44640
|
+
};
|
|
44641
|
+
const normalized = {};
|
|
44642
|
+
for (const [key, value] of Object.entries(merged)) {
|
|
44643
|
+
normalized[key] = key === "id" ? value : toId(value);
|
|
44644
|
+
}
|
|
44645
|
+
return normalized;
|
|
44606
44646
|
}, [entity, initialData]);
|
|
44607
44647
|
const entityDerivedFields = React77__default.useMemo(() => {
|
|
44608
44648
|
if (fields && fields.length > 0) return void 0;
|
|
@@ -44731,8 +44771,8 @@ var init_Form = __esm({
|
|
|
44731
44771
|
checkViolations(name, newFormData);
|
|
44732
44772
|
};
|
|
44733
44773
|
const isFieldVisible = React77__default.useCallback(
|
|
44734
|
-
(
|
|
44735
|
-
const condition = conditionalFields[
|
|
44774
|
+
(fieldName2) => {
|
|
44775
|
+
const condition = conditionalFields[fieldName2];
|
|
44736
44776
|
if (!condition) return true;
|
|
44737
44777
|
return Boolean(evaluateFormExpression(condition, evalContext));
|
|
44738
44778
|
},
|
|
@@ -44778,9 +44818,9 @@ var init_Form = __esm({
|
|
|
44778
44818
|
};
|
|
44779
44819
|
const handleInvalid = (e) => {
|
|
44780
44820
|
const target = e.target;
|
|
44781
|
-
const
|
|
44821
|
+
const fieldName2 = target.getAttribute("data-field-name") ?? target.name ?? "";
|
|
44782
44822
|
const fieldMessage = target.validationMessage || "Invalid value";
|
|
44783
|
-
debug("forms", "invalid", { mode: formMode, fieldName, fieldMessage });
|
|
44823
|
+
debug("forms", "invalid", { mode: formMode, fieldName: fieldName2, fieldMessage });
|
|
44784
44824
|
queueMicrotask(() => {
|
|
44785
44825
|
const form = formRef.current;
|
|
44786
44826
|
if (!form) return;
|
|
@@ -44816,22 +44856,22 @@ var init_Form = __esm({
|
|
|
44816
44856
|
};
|
|
44817
44857
|
const renderField = React77__default.useCallback(
|
|
44818
44858
|
(field) => {
|
|
44819
|
-
const
|
|
44820
|
-
if (!
|
|
44821
|
-
if (!isFieldVisible(
|
|
44859
|
+
const fieldName2 = field.name || field.field;
|
|
44860
|
+
if (!fieldName2) return null;
|
|
44861
|
+
if (!isFieldVisible(fieldName2)) {
|
|
44822
44862
|
return null;
|
|
44823
44863
|
}
|
|
44824
44864
|
const inputType = determineInputType(field);
|
|
44825
|
-
const label = field.label ||
|
|
44826
|
-
const currentValue2 = formData[
|
|
44827
|
-
return /* @__PURE__ */ jsxs(VStack, { gap: "xs", "data-field":
|
|
44865
|
+
const label = field.label || fieldName2.charAt(0).toUpperCase() + fieldName2.slice(1).replace(/([A-Z])/g, " $1");
|
|
44866
|
+
const currentValue2 = formData[fieldName2] ?? field.defaultValue ?? "";
|
|
44867
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "xs", "data-field": fieldName2, children: [
|
|
44828
44868
|
inputType !== "checkbox" && /* @__PURE__ */ jsxs(Typography, { as: "label", variant: "label", weight: "bold", children: [
|
|
44829
44869
|
label,
|
|
44830
44870
|
field.required && /* @__PURE__ */ jsx(Typography, { as: "span", color: "error", className: "ml-1", children: "*" })
|
|
44831
44871
|
] }),
|
|
44832
|
-
renderFieldInput(field,
|
|
44872
|
+
renderFieldInput(field, fieldName2, inputType, currentValue2, label),
|
|
44833
44873
|
field.hint && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "muted", children: field.hint })
|
|
44834
|
-
] },
|
|
44874
|
+
] }, fieldName2);
|
|
44835
44875
|
},
|
|
44836
44876
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
44837
44877
|
);
|
|
@@ -44860,8 +44900,8 @@ var init_Form = __esm({
|
|
|
44860
44900
|
}
|
|
44861
44901
|
return field;
|
|
44862
44902
|
}).map((field) => {
|
|
44863
|
-
const
|
|
44864
|
-
const override = fieldOverrides?.find((o) => o.name ===
|
|
44903
|
+
const fieldName2 = field.name || field.field;
|
|
44904
|
+
const override = fieldOverrides?.find((o) => o.name === fieldName2);
|
|
44865
44905
|
if (!override) return field;
|
|
44866
44906
|
return {
|
|
44867
44907
|
...field,
|
|
@@ -44917,11 +44957,11 @@ var init_Form = __esm({
|
|
|
44917
44957
|
] }, section.id);
|
|
44918
44958
|
}).filter(Boolean);
|
|
44919
44959
|
}, [sections, isSectionVisible, collapsedSections, renderField, gap]);
|
|
44920
|
-
function renderFieldInput(field,
|
|
44960
|
+
function renderFieldInput(field, fieldName2, inputType, currentValue2, label) {
|
|
44921
44961
|
const commonProps = {
|
|
44922
|
-
id:
|
|
44923
|
-
name:
|
|
44924
|
-
"data-field-name":
|
|
44962
|
+
id: fieldName2,
|
|
44963
|
+
name: fieldName2,
|
|
44964
|
+
"data-field-name": fieldName2,
|
|
44925
44965
|
required: field.required,
|
|
44926
44966
|
disabled: isLoading,
|
|
44927
44967
|
placeholder: field.placeholder,
|
|
@@ -44935,7 +44975,7 @@ var init_Form = __esm({
|
|
|
44935
44975
|
...commonProps,
|
|
44936
44976
|
label: label + (field.required ? " *" : ""),
|
|
44937
44977
|
checked: Boolean(currentValue2),
|
|
44938
|
-
onChange: (e) => handleChange(
|
|
44978
|
+
onChange: (e) => handleChange(fieldName2, e.target.checked)
|
|
44939
44979
|
}
|
|
44940
44980
|
);
|
|
44941
44981
|
case "textarea":
|
|
@@ -44944,7 +44984,7 @@ var init_Form = __esm({
|
|
|
44944
44984
|
{
|
|
44945
44985
|
...commonProps,
|
|
44946
44986
|
value: String(currentValue2),
|
|
44947
|
-
onChange: (e) => handleChange(
|
|
44987
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
44948
44988
|
minLength: field.min,
|
|
44949
44989
|
maxLength: field.max
|
|
44950
44990
|
}
|
|
@@ -44957,14 +44997,14 @@ var init_Form = __esm({
|
|
|
44957
44997
|
...commonProps,
|
|
44958
44998
|
options,
|
|
44959
44999
|
value: String(currentValue2),
|
|
44960
|
-
onValueChange: (v) => handleChange(
|
|
45000
|
+
onValueChange: (v) => handleChange(fieldName2, v),
|
|
44961
45001
|
placeholder: field.placeholder || `Select ${label}...`
|
|
44962
45002
|
}
|
|
44963
45003
|
);
|
|
44964
45004
|
}
|
|
44965
45005
|
case "relation": {
|
|
44966
|
-
const relationOptions = relationsData[
|
|
44967
|
-
const relationLoading = relationsLoading[
|
|
45006
|
+
const relationOptions = relationsData[fieldName2] || [];
|
|
45007
|
+
const relationLoading = relationsLoading[fieldName2] || false;
|
|
44968
45008
|
if (field.relation?.cardinality !== void 0 && MANY_CARDINALITIES.includes(field.relation.cardinality)) {
|
|
44969
45009
|
const selectedValues = Array.isArray(currentValue2) ? currentValue2.map((v) => String(v)) : [];
|
|
44970
45010
|
return /* @__PURE__ */ jsx(
|
|
@@ -44976,7 +45016,7 @@ var init_Form = __esm({
|
|
|
44976
45016
|
clearable: true,
|
|
44977
45017
|
options: [...relationOptions],
|
|
44978
45018
|
value: selectedValues,
|
|
44979
|
-
onValueChange: (value) => handleChange(
|
|
45019
|
+
onValueChange: (value) => handleChange(fieldName2, Array.isArray(value) ? value : [value]),
|
|
44980
45020
|
placeholder: field.placeholder || `Select ${label}...`
|
|
44981
45021
|
}
|
|
44982
45022
|
);
|
|
@@ -44986,7 +45026,7 @@ var init_Form = __esm({
|
|
|
44986
45026
|
{
|
|
44987
45027
|
...commonProps,
|
|
44988
45028
|
value: currentValue2 ? String(currentValue2) : void 0,
|
|
44989
|
-
onChange: (value) => handleChange(
|
|
45029
|
+
onChange: (value) => handleChange(fieldName2, value),
|
|
44990
45030
|
options: relationOptions,
|
|
44991
45031
|
isLoading: relationLoading,
|
|
44992
45032
|
placeholder: field.placeholder || `Select ${label}...`,
|
|
@@ -45003,7 +45043,7 @@ var init_Form = __esm({
|
|
|
45003
45043
|
placeholder: field.placeholder,
|
|
45004
45044
|
disabled: isLoading,
|
|
45005
45045
|
value: arrayValue,
|
|
45006
|
-
onChange: (next) => handleChange(
|
|
45046
|
+
onChange: (next) => handleChange(fieldName2, [...next])
|
|
45007
45047
|
}
|
|
45008
45048
|
);
|
|
45009
45049
|
}
|
|
@@ -45015,7 +45055,7 @@ var init_Form = __esm({
|
|
|
45015
45055
|
type: "number",
|
|
45016
45056
|
value: currentValue2 !== void 0 && currentValue2 !== "" ? String(currentValue2) : "",
|
|
45017
45057
|
onChange: (e) => handleChange(
|
|
45018
|
-
|
|
45058
|
+
fieldName2,
|
|
45019
45059
|
e.target.value ? Number(e.target.value) : void 0
|
|
45020
45060
|
),
|
|
45021
45061
|
min: field.min,
|
|
@@ -45032,7 +45072,7 @@ var init_Form = __esm({
|
|
|
45032
45072
|
icon: DollarSign,
|
|
45033
45073
|
value: currentValue2 !== void 0 && currentValue2 !== "" ? String(currentValue2) : "",
|
|
45034
45074
|
onChange: (e) => handleChange(
|
|
45035
|
-
|
|
45075
|
+
fieldName2,
|
|
45036
45076
|
e.target.value ? Number(e.target.value) : void 0
|
|
45037
45077
|
),
|
|
45038
45078
|
min: field.min,
|
|
@@ -45050,7 +45090,7 @@ var init_Form = __esm({
|
|
|
45050
45090
|
const f3 = files[0];
|
|
45051
45091
|
if (!f3) return;
|
|
45052
45092
|
const reader = new FileReader();
|
|
45053
|
-
reader.onload = () => handleChange(
|
|
45093
|
+
reader.onload = () => handleChange(fieldName2, {
|
|
45054
45094
|
name: f3.name,
|
|
45055
45095
|
mimeType: f3.type,
|
|
45056
45096
|
sizeBytes: f3.size,
|
|
@@ -45067,7 +45107,7 @@ var init_Form = __esm({
|
|
|
45067
45107
|
...commonProps,
|
|
45068
45108
|
type: "date",
|
|
45069
45109
|
value: formatDateValue(currentValue2),
|
|
45070
|
-
onChange: (e) => handleChange(
|
|
45110
|
+
onChange: (e) => handleChange(fieldName2, e.target.value)
|
|
45071
45111
|
}
|
|
45072
45112
|
);
|
|
45073
45113
|
case "datetime-local":
|
|
@@ -45077,7 +45117,7 @@ var init_Form = __esm({
|
|
|
45077
45117
|
...commonProps,
|
|
45078
45118
|
type: "datetime-local",
|
|
45079
45119
|
value: formatDateTimeValue(currentValue2),
|
|
45080
|
-
onChange: (e) => handleChange(
|
|
45120
|
+
onChange: (e) => handleChange(fieldName2, e.target.value)
|
|
45081
45121
|
}
|
|
45082
45122
|
);
|
|
45083
45123
|
case "email":
|
|
@@ -45087,7 +45127,7 @@ var init_Form = __esm({
|
|
|
45087
45127
|
...commonProps,
|
|
45088
45128
|
type: "email",
|
|
45089
45129
|
value: String(currentValue2),
|
|
45090
|
-
onChange: (e) => handleChange(
|
|
45130
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45091
45131
|
minLength: field.min,
|
|
45092
45132
|
maxLength: field.max
|
|
45093
45133
|
}
|
|
@@ -45099,7 +45139,7 @@ var init_Form = __esm({
|
|
|
45099
45139
|
...commonProps,
|
|
45100
45140
|
type: "url",
|
|
45101
45141
|
value: String(currentValue2),
|
|
45102
|
-
onChange: (e) => handleChange(
|
|
45142
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45103
45143
|
minLength: field.min,
|
|
45104
45144
|
maxLength: field.max
|
|
45105
45145
|
}
|
|
@@ -45111,7 +45151,7 @@ var init_Form = __esm({
|
|
|
45111
45151
|
...commonProps,
|
|
45112
45152
|
type: "password",
|
|
45113
45153
|
value: String(currentValue2),
|
|
45114
|
-
onChange: (e) => handleChange(
|
|
45154
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45115
45155
|
minLength: field.min,
|
|
45116
45156
|
maxLength: field.max
|
|
45117
45157
|
}
|
|
@@ -45124,7 +45164,7 @@ var init_Form = __esm({
|
|
|
45124
45164
|
...commonProps,
|
|
45125
45165
|
type: "text",
|
|
45126
45166
|
value: String(currentValue2),
|
|
45127
|
-
onChange: (e) => handleChange(
|
|
45167
|
+
onChange: (e) => handleChange(fieldName2, e.target.value),
|
|
45128
45168
|
minLength: field.min,
|
|
45129
45169
|
maxLength: field.max
|
|
45130
45170
|
}
|
|
@@ -45481,7 +45521,7 @@ function entityFieldsFromListItem(item) {
|
|
|
45481
45521
|
}
|
|
45482
45522
|
return result;
|
|
45483
45523
|
}
|
|
45484
|
-
function getStatusStyle(
|
|
45524
|
+
function getStatusStyle(fieldName2, value) {
|
|
45485
45525
|
const val = String(value).toLowerCase();
|
|
45486
45526
|
if (val.includes("complete") || val.includes("done"))
|
|
45487
45527
|
return STATUS_STYLES.complete;
|
|
@@ -45497,12 +45537,12 @@ function getStatusStyle(fieldName, value) {
|
|
|
45497
45537
|
if (val.includes("low")) return STATUS_STYLES.low;
|
|
45498
45538
|
return STATUS_STYLES.default;
|
|
45499
45539
|
}
|
|
45500
|
-
function formatValue3(value,
|
|
45540
|
+
function formatValue3(value, fieldName2) {
|
|
45501
45541
|
if (typeof value === "number") {
|
|
45502
|
-
if (
|
|
45542
|
+
if (fieldName2.toLowerCase().includes("progress") || fieldName2.toLowerCase().includes("percent")) {
|
|
45503
45543
|
return `${value}%`;
|
|
45504
45544
|
}
|
|
45505
|
-
if (
|
|
45545
|
+
if (fieldName2.toLowerCase().includes("budget") || fieldName2.toLowerCase().includes("cost")) {
|
|
45506
45546
|
return new Intl.NumberFormat("en-US", {
|
|
45507
45547
|
style: "currency",
|
|
45508
45548
|
currency: "USD",
|
|
@@ -45525,8 +45565,8 @@ function formatValue3(value, fieldName) {
|
|
|
45525
45565
|
}
|
|
45526
45566
|
return String(value);
|
|
45527
45567
|
}
|
|
45528
|
-
function formatFieldLabel2(
|
|
45529
|
-
return humanizeFieldName(
|
|
45568
|
+
function formatFieldLabel2(fieldName2) {
|
|
45569
|
+
return humanizeFieldName(fieldName2).replace(/\sId$/, "").trim();
|
|
45530
45570
|
}
|
|
45531
45571
|
var STATUS_STYLES, StatusBadge, ProgressIndicator, List3;
|
|
45532
45572
|
var init_List = __esm({
|
|
@@ -45594,9 +45634,9 @@ var init_List = __esm({
|
|
|
45594
45634
|
};
|
|
45595
45635
|
StatusBadge = ({
|
|
45596
45636
|
value,
|
|
45597
|
-
fieldName
|
|
45637
|
+
fieldName: fieldName2
|
|
45598
45638
|
}) => {
|
|
45599
|
-
const style = getStatusStyle(
|
|
45639
|
+
const style = getStatusStyle(fieldName2, value);
|
|
45600
45640
|
return /* @__PURE__ */ jsxs(
|
|
45601
45641
|
Typography,
|
|
45602
45642
|
{
|
|
@@ -48509,8 +48549,8 @@ var init_StatCard = __esm({
|
|
|
48509
48549
|
return items.length;
|
|
48510
48550
|
}
|
|
48511
48551
|
if (field.includes(":")) {
|
|
48512
|
-
const [
|
|
48513
|
-
return items.filter((item) => item[
|
|
48552
|
+
const [fieldName2, fieldValue] = field.split(":");
|
|
48553
|
+
return items.filter((item) => item[fieldName2] === fieldValue).length;
|
|
48514
48554
|
}
|
|
48515
48555
|
const fieldExistsOnItems = items.some((item) => field in item);
|
|
48516
48556
|
if (fieldExistsOnItems) {
|
|
@@ -50030,6 +50070,8 @@ var init_component_registry_generated = __esm({
|
|
|
50030
50070
|
init_DocSearch();
|
|
50031
50071
|
init_DocSidebar();
|
|
50032
50072
|
init_DocTOC();
|
|
50073
|
+
init_DocumentDetails();
|
|
50074
|
+
init_DocumentPanel();
|
|
50033
50075
|
init_DocumentViewer();
|
|
50034
50076
|
init_DrawFxLayer();
|
|
50035
50077
|
init_DrawGroup();
|
|
@@ -50139,7 +50181,7 @@ var init_component_registry_generated = __esm({
|
|
|
50139
50181
|
init_RelationSelect();
|
|
50140
50182
|
init_RepeatableFormSection();
|
|
50141
50183
|
init_ReplyTree();
|
|
50142
|
-
|
|
50184
|
+
init_RichTextEditor();
|
|
50143
50185
|
init_RuntimeDebugger2();
|
|
50144
50186
|
init_ScaledDiagram();
|
|
50145
50187
|
init_ScoreDisplay();
|
|
@@ -50302,6 +50344,8 @@ var init_component_registry_generated = __esm({
|
|
|
50302
50344
|
"DocSearch": DocSearch,
|
|
50303
50345
|
"DocSidebar": DocSidebar,
|
|
50304
50346
|
"DocTOC": DocTOC,
|
|
50347
|
+
"DocumentDetails": DocumentDetails,
|
|
50348
|
+
"DocumentPanel": DocumentPanel,
|
|
50305
50349
|
"DocumentViewer": DocumentViewer,
|
|
50306
50350
|
"DrawFxLayer": DrawFxLayer,
|
|
50307
50351
|
"DrawGroup": DrawGroup,
|
|
@@ -50413,7 +50457,7 @@ var init_component_registry_generated = __esm({
|
|
|
50413
50457
|
"RelationSelect": RelationSelect,
|
|
50414
50458
|
"RepeatableFormSection": RepeatableFormSection,
|
|
50415
50459
|
"ReplyTree": ReplyTree,
|
|
50416
|
-
"
|
|
50460
|
+
"RichTextEditor": RichTextEditor,
|
|
50417
50461
|
"RuntimeDebugger": RuntimeDebugger,
|
|
50418
50462
|
"ScaledDiagram": ScaledDiagram,
|
|
50419
50463
|
"ScoreDisplay": ScoreDisplay,
|
|
@@ -50567,10 +50611,10 @@ function enrichFormFields(fields, entityDef) {
|
|
|
50567
50611
|
}
|
|
50568
50612
|
if (field && typeof field === "object" && !Array.isArray(field) && !React77__default.isValidElement(field) && !(field instanceof Date)) {
|
|
50569
50613
|
const obj = field;
|
|
50570
|
-
const
|
|
50571
|
-
if (!
|
|
50614
|
+
const fieldName2 = typeof obj.name === "string" ? obj.name : typeof obj.field === "string" ? obj.field : void 0;
|
|
50615
|
+
if (!fieldName2) return field;
|
|
50572
50616
|
if (obj.type || obj.inputType) return field;
|
|
50573
|
-
const entityField = fieldMap.get(
|
|
50617
|
+
const entityField = fieldMap.get(fieldName2);
|
|
50574
50618
|
if (!entityField) return field;
|
|
50575
50619
|
const enriched = { ...obj, type: entityField.type };
|
|
50576
50620
|
if (entityField.required && !("required" in obj)) {
|
|
@@ -50620,9 +50664,9 @@ function enrichDetailFields(fields, entityDef) {
|
|
|
50620
50664
|
}
|
|
50621
50665
|
if (field && typeof field === "object" && !Array.isArray(field) && !React77__default.isValidElement(field) && !(field instanceof Date)) {
|
|
50622
50666
|
const obj = field;
|
|
50623
|
-
const
|
|
50624
|
-
if (!
|
|
50625
|
-
const meta = metaFor(
|
|
50667
|
+
const fieldName2 = typeof obj.key === "string" ? obj.key : typeof obj.name === "string" ? obj.name : void 0;
|
|
50668
|
+
if (!fieldName2 || obj.type) return field;
|
|
50669
|
+
const meta = metaFor(fieldName2);
|
|
50626
50670
|
return meta ? { ...obj, ...meta } : field;
|
|
50627
50671
|
}
|
|
50628
50672
|
return field;
|
|
@@ -51461,9 +51505,9 @@ function UISlotRenderer({
|
|
|
51461
51505
|
"ui-slot-renderer relative min-h-full",
|
|
51462
51506
|
className
|
|
51463
51507
|
), children: [
|
|
51464
|
-
/* @__PURE__ */ jsxs(Box, { className: "flex min-h-full", children: [
|
|
51465
|
-
/* @__PURE__ */ jsx(UISlotComponent, { slot: "sidebar", className: "ui-slot-sidebar min-w-0 shrink-0" }),
|
|
51466
|
-
/* @__PURE__ */ jsx(UISlotComponent, { slot: "main", className: "ui-slot-main flex-1 min-h-[200px]" })
|
|
51508
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex min-h-full flex-col lg:flex-row", children: [
|
|
51509
|
+
/* @__PURE__ */ jsx(UISlotComponent, { slot: "sidebar", className: "ui-slot-sidebar min-w-0 lg:shrink-0" }),
|
|
51510
|
+
/* @__PURE__ */ jsx(UISlotComponent, { slot: "main", className: "ui-slot-main flex-1 min-w-0 min-h-[200px]" })
|
|
51467
51511
|
] }),
|
|
51468
51512
|
/* @__PURE__ */ jsx(UISlotComponent, { slot: "modal", portal: true }),
|
|
51469
51513
|
/* @__PURE__ */ jsx(UISlotComponent, { slot: "drawer", portal: true }),
|
|
@@ -53451,54 +53495,6 @@ var en_default = {
|
|
|
53451
53495
|
"template.faq": "Frequently Asked Questions",
|
|
53452
53496
|
"template.ourTeam": "Our Team",
|
|
53453
53497
|
"template.caseStudies": "Case Studies",
|
|
53454
|
-
"richBlockEditor.toolbar.text": "Text",
|
|
53455
|
-
"richBlockEditor.toolbar.h1": "H1",
|
|
53456
|
-
"richBlockEditor.toolbar.h2": "H2",
|
|
53457
|
-
"richBlockEditor.toolbar.h3": "H3",
|
|
53458
|
-
"richBlockEditor.toolbar.bulletList": "Bullet list",
|
|
53459
|
-
"richBlockEditor.toolbar.numbered": "Numbered",
|
|
53460
|
-
"richBlockEditor.toolbar.quote": "Quote",
|
|
53461
|
-
"richBlockEditor.toolbar.code": "Code",
|
|
53462
|
-
"richBlockEditor.toolbar.divider": "Divider",
|
|
53463
|
-
"richBlockEditor.toolbar.image": "Image",
|
|
53464
|
-
"richBlockEditor.blockType.paragraph": "Text",
|
|
53465
|
-
"richBlockEditor.blockType.heading1": "Heading 1",
|
|
53466
|
-
"richBlockEditor.blockType.heading2": "Heading 2",
|
|
53467
|
-
"richBlockEditor.blockType.heading3": "Heading 3",
|
|
53468
|
-
"richBlockEditor.blockType.bulletList": "Bullet list",
|
|
53469
|
-
"richBlockEditor.blockType.numberedList": "Numbered list",
|
|
53470
|
-
"richBlockEditor.blockType.quote": "Quote",
|
|
53471
|
-
"richBlockEditor.blockType.code": "Code",
|
|
53472
|
-
"richBlockEditor.blockType.divider": "Divider",
|
|
53473
|
-
"richBlockEditor.blockType.image": "Image",
|
|
53474
|
-
"richBlockEditor.blockActions": "Block actions",
|
|
53475
|
-
"richBlockEditor.duplicate": "Duplicate",
|
|
53476
|
-
"richBlockEditor.turnInto": "Turn into",
|
|
53477
|
-
"richBlockEditor.placeholder.heading1": "Heading 1",
|
|
53478
|
-
"richBlockEditor.placeholder.heading2": "Heading 2",
|
|
53479
|
-
"richBlockEditor.placeholder.heading3": "Heading 3",
|
|
53480
|
-
"richBlockEditor.placeholder.quote": "Quote",
|
|
53481
|
-
"richBlockEditor.placeholder.code": "Enter code",
|
|
53482
|
-
"richBlockEditor.placeholder.paragraph": "Start writing...",
|
|
53483
|
-
"richBlockEditor.placeholder.listItem": "List item",
|
|
53484
|
-
"richBlockEditor.placeholder.caption": "Caption (optional)",
|
|
53485
|
-
"richBlockEditor.aria.heading1Block": "Heading 1 block",
|
|
53486
|
-
"richBlockEditor.aria.heading2Block": "Heading 2 block",
|
|
53487
|
-
"richBlockEditor.aria.heading3Block": "Heading 3 block",
|
|
53488
|
-
"richBlockEditor.aria.quoteBlock": "Quote block",
|
|
53489
|
-
"richBlockEditor.aria.codeBlock": "Code block",
|
|
53490
|
-
"richBlockEditor.aria.codeLanguage": "Code language",
|
|
53491
|
-
"richBlockEditor.aria.imageUrl": "Image URL",
|
|
53492
|
-
"richBlockEditor.aria.imageCaption": "Image caption",
|
|
53493
|
-
"richBlockEditor.aria.listItem": "List item",
|
|
53494
|
-
"richBlockEditor.aria.removeListItem": "Remove list item",
|
|
53495
|
-
"richBlockEditor.aria.paragraphBlock": "Paragraph block",
|
|
53496
|
-
"richBlockEditor.embeddedImage": "Embedded image",
|
|
53497
|
-
"richBlockEditor.noImageUrl": "No image URL set",
|
|
53498
|
-
"richBlockEditor.addItem": "Add item",
|
|
53499
|
-
"richBlockEditor.insertParagraphBelow": "Insert paragraph below",
|
|
53500
|
-
"richBlockEditor.editorToolbar": "Block editor toolbar",
|
|
53501
|
-
"richBlockEditor.insertEntry": "Insert {{label}}",
|
|
53502
53498
|
"versionDiff.compare": "Compare",
|
|
53503
53499
|
"versionDiff.to": "to",
|
|
53504
53500
|
"versionDiff.beforeRevision": "Before revision",
|
|
@@ -53846,7 +53842,31 @@ var en_default = {
|
|
|
53846
53842
|
"td.survivedAllWaves": "Survived all waves!",
|
|
53847
53843
|
"td.victory": "Victory!",
|
|
53848
53844
|
"td.wave": "Wave",
|
|
53849
|
-
"td.waveInProgress": "Wave in progress\u2026"
|
|
53845
|
+
"td.waveInProgress": "Wave in progress\u2026",
|
|
53846
|
+
"documentDetails.title": "Details",
|
|
53847
|
+
"documentPanel.untitled": "Untitled",
|
|
53848
|
+
"documentPanel.edit": "Edit",
|
|
53849
|
+
"documentPanel.done": "Done",
|
|
53850
|
+
"documentPanel.autosaveHint": "Saves as you type",
|
|
53851
|
+
"documentPanel.placeholder": "Start writing\u2026",
|
|
53852
|
+
"richTextEditor.editorToolbar": "Formatting toolbar",
|
|
53853
|
+
"richTextEditor.editorSurface": "Rich text editor",
|
|
53854
|
+
"richTextEditor.bold": "Bold",
|
|
53855
|
+
"richTextEditor.italic": "Italic",
|
|
53856
|
+
"richTextEditor.underline": "Underline",
|
|
53857
|
+
"richTextEditor.strikethrough": "Strikethrough",
|
|
53858
|
+
"richTextEditor.heading1": "Heading 1",
|
|
53859
|
+
"richTextEditor.heading2": "Heading 2",
|
|
53860
|
+
"richTextEditor.heading3": "Heading 3",
|
|
53861
|
+
"richTextEditor.bulletList": "Bullet list",
|
|
53862
|
+
"richTextEditor.numberedList": "Numbered list",
|
|
53863
|
+
"richTextEditor.quote": "Quote",
|
|
53864
|
+
"richTextEditor.code": "Code",
|
|
53865
|
+
"richTextEditor.link": "Add link",
|
|
53866
|
+
"richTextEditor.removeLink": "Remove link",
|
|
53867
|
+
"richTextEditor.divider": "Divider",
|
|
53868
|
+
"richTextEditor.linkPrompt": "Link address",
|
|
53869
|
+
"richTextEditor.placeholder": "Start writing\u2026"
|
|
53850
53870
|
};
|
|
53851
53871
|
|
|
53852
53872
|
// hooks/useTranslate.ts
|
|
@@ -53867,7 +53887,7 @@ var I18nContext = createContext({
|
|
|
53867
53887
|
});
|
|
53868
53888
|
I18nContext.displayName = "I18nContext";
|
|
53869
53889
|
var I18nProvider = I18nContext.Provider;
|
|
53870
|
-
function
|
|
53890
|
+
function useTranslate116() {
|
|
53871
53891
|
return useContext(I18nContext);
|
|
53872
53892
|
}
|
|
53873
53893
|
function createTranslate(messages) {
|
|
@@ -54149,4 +54169,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
|
|
|
54149
54169
|
});
|
|
54150
54170
|
}
|
|
54151
54171
|
|
|
54152
|
-
export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgoGraphCanvas, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmojiPicker, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, FxOverlay, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, LearningScene3D, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree,
|
|
54172
|
+
export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgoGraphCanvas, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentDetails, DocumentPanel, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmojiPicker, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, FxOverlay, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, LearningScene3D, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NotifyListener, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichTextEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, arrowBetween, billboardLabel, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, cylinderBetween, get3DClickPayload, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, meshSphere, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, registerCodeLanguageLoader, renderPatternValue, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, sanitizeRichHtml, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useMediaQuery, useOrbitalHistory, usePresence, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate116 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
|