@coffer-org/web-ui 4.0.0 → 6.0.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/components/ui/copy-button.d.ts +6 -0
- package/dist/components/ui/copy-button.js +28 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal-link.d.ts +15 -0
- package/dist/internal-link.js +66 -0
- package/dist/layout.js +3 -3
- package/dist/registry.d.ts +2 -1
- package/dist/registry.js +1 -0
- package/dist/render/activate.d.ts +4 -0
- package/dist/render/activate.js +11 -0
- package/dist/render/blocks/balance.js +3 -2
- package/dist/render/blocks/block-shell.d.ts +1 -0
- package/dist/render/blocks/block-shell.js +4 -0
- package/dist/render/blocks/chart.js +2 -1
- package/dist/render/blocks/compare.js +2 -1
- package/dist/render/blocks/countdown.js +2 -1
- package/dist/render/blocks/idcard.js +2 -1
- package/dist/render/blocks/journal.js +2 -1
- package/dist/render/blocks/ledger.js +2 -2
- package/dist/render/blocks/manifest.js +2 -1
- package/dist/render/blocks/masthead.js +2 -1
- package/dist/render/blocks/meter.js +2 -2
- package/dist/render/blocks/nutrition.js +2 -2
- package/dist/render/blocks/plaque.js +2 -1
- package/dist/render/blocks/receipt.js +2 -2
- package/dist/render/blocks/score.js +2 -2
- package/dist/render/blocks/stats.js +3 -2
- package/dist/render/blocks/table.js +5 -4
- package/dist/render/chrome.d.ts +21 -3
- package/dist/render/chrome.js +46 -6
- package/dist/render/core/dimensions.js +1 -1
- package/dist/render/core/embed.js +8 -1
- package/dist/render/core/money.js +1 -1
- package/dist/render/core/range.js +1 -1
- package/dist/render/core/reminder.js +1 -1
- package/dist/render/core/text.js +57 -3
- package/dist/render/core/weight.js +1 -1
- package/dist/render/datum.d.ts +4 -0
- package/dist/render/datum.js +16 -0
- package/dist/render/dispatch.js +4 -2
- package/dist/render/field-frame.d.ts +1 -1
- package/dist/render/field-frame.js +20 -9
- package/dist/render/markdown-view.js +33 -4
- package/dist/render/popover-field.js +10 -19
- package/dist/render/widgets/display.js +2 -1
- package/dist/render/widgets/edit.js +2 -2
- package/dist/render/widgets/fixed-collection.js +2 -1
- package/dist/render/widgets/group-widgets.js +1 -1
- package/dist/render/widgets/group.js +2 -1
- package/dist/render/widgets/table-group.js +4 -3
- package/dist/types.d.ts +2 -0
- package/package.json +2 -2
|
@@ -15,7 +15,7 @@ import { Plus } from 'lucide-react';
|
|
|
15
15
|
import { RecordInline } from "../../components/RecordInline.js";
|
|
16
16
|
import { RemoveBtn, AddBtn, MultipleChips, CheckLegend, colsToCheckRow, checkRowToCols, Dash, } from "../shared.js";
|
|
17
17
|
import { FieldSlot } from "../dispatch.js";
|
|
18
|
-
import { FieldLabel } from "../chrome.js";
|
|
18
|
+
import { FieldLabel, CHROME_LABEL_CLS } from "../chrome.js";
|
|
19
19
|
import { measuredChipContent, measuredUnitLabel } from "./display.js";
|
|
20
20
|
import { ChecklistRow } from "./checklist-row.js";
|
|
21
21
|
import { ChecklistContent, clientChecklistContentFields } from "./checklist-content.js";
|
|
@@ -238,7 +238,7 @@ export function KeyValueWidget({ value, onChange, multiple = true, option, keyLa
|
|
|
238
238
|
const canAdd = multiple || rows.length < 1;
|
|
239
239
|
return (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(FlowRow, { items: rows.map((item, idx) => ({
|
|
240
240
|
key: String(idx),
|
|
241
|
-
node: (_jsxs("div", { className: "flex flex-col gap-0.5 w-56 max-w-full min-w-0", children: [_jsxs("div", { className: "flex items-center gap-1 min-w-0", children: [_jsx(Input, { placeholder: kLabel, value: item.key, className:
|
|
241
|
+
node: (_jsxs("div", { className: "flex flex-col gap-0.5 w-56 max-w-full min-w-0", children: [_jsxs("div", { className: "flex items-center gap-1 min-w-0", children: [_jsx(Input, { placeholder: kLabel, value: item.key, className: `h-6 px-1 ${CHROME_LABEL_CLS}`, autoComplete: "off", onChange: (e) => save(rows.map((x, i) => (i === idx ? { ...x, key: e.target.value } : x))) }), _jsx(RemoveBtn, { onClick: () => save(rows.filter((_, i) => i !== idx)) })] }), _jsx(FieldSlot, { bare: true, field: option, value: item.value, mode: "edit", onChange: (v) => updatePairValue(idx, String(v)), recordCtx: recordCtx })] })),
|
|
242
242
|
})) }), canAdd && (_jsxs(AddBtn, { onClick: () => setRows((r) => [...r, { key: '', value: '' }]), children: [kLabel, "/", vLabel] }))] }));
|
|
243
243
|
}
|
|
244
244
|
function parseMeasuredItems(value) {
|
|
@@ -8,6 +8,7 @@ import { FlowRow } from "./flow-row.js";
|
|
|
8
8
|
import { subFull } from "./group.js";
|
|
9
9
|
import { useGroupEdit } from "./group-edit.js";
|
|
10
10
|
import { useHybridScope } from "../hybrid-scope.js";
|
|
11
|
+
import { datumClass } from "../datum.js";
|
|
11
12
|
export function FixedCollection({ group, value, onChange, recordCtx, mode = 'edit', }) {
|
|
12
13
|
const { t } = useTranslation();
|
|
13
14
|
const depth = useGroupDepth();
|
|
@@ -29,6 +30,6 @@ export function FixedCollection({ group, value, onChange, recordCtx, mode = 'edi
|
|
|
29
30
|
return (_jsxs("fieldset", { className: `${groupScopeClass(depth)} flex flex-col min-w-0 ${STACK}`, children: [_jsx(GroupTitle, { as: "legend", label: t(group.label), icon: groupIcon(group), actions: live ? null : g.actions }), _jsx("div", { className: `flex flex-col ${STACK}`, children: rows.map((row, idx) => (_jsx(Rail, { children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsxs("div", { className: "flex flex-col gap-0.5 min-w-0 shrink-0", children: [by.type.label ? _jsx(FieldLabel, { label: t(by.type.label) }) : null, _jsx("span", { className: "text-sm px-1 py-2", children: fmtOptionLabel(t, { options: byOpts }, String(row[by.key] ?? '')) })] }), _jsx("div", { className: "flex-1 min-w-0", children: _jsx(FlowRow, { items: valueFields.map((sub) => ({
|
|
30
31
|
key: sub.key,
|
|
31
32
|
full: subFull(sub.type),
|
|
32
|
-
node: editing ? (_jsx("div", { className: "flex flex-col gap-0.5 min-w-0", children: _jsx(FieldSlot, { field: sub.type, value: row[sub.key] ?? '', onChange: (v) => update(idx, sub.key, v), label: sub.type.label ? t(sub.type.label) : undefined, mode: "edit", recordCtx: recordCtx }) })) : (_jsxs("div", { className:
|
|
33
|
+
node: editing ? (_jsx("div", { className: "flex flex-col gap-0.5 min-w-0", children: _jsx(FieldSlot, { field: sub.type, value: row[sub.key] ?? '', onChange: (v) => update(idx, sub.key, v), label: sub.type.label ? t(sub.type.label) : undefined, mode: "edit", recordCtx: recordCtx }) })) : (_jsxs("div", { className: `flex flex-col gap-0.5 min-w-0 ${datumClass(sub.type)}`.trim(), children: [sub.type.label ? _jsx(FieldLabel, { label: t(sub.type.label) }) : null, _jsx(FieldSlot, { field: sub.type, fieldKey: live ? sub.key : undefined, value: row[sub.key] ?? '', onChange: live ? (v) => update(idx, sub.key, v) : undefined, mode: "view", bare: !live, recordCtx: recordCtx })] })),
|
|
33
34
|
})) }) })] }) }, String(row[by.key])))) })] }));
|
|
34
35
|
}
|
|
@@ -37,5 +37,5 @@ function ChecklistPage({ el, value, recordCtx, mode }) {
|
|
|
37
37
|
return (_jsx(ChecklistGroup, { group: el, value: value, onChange: (v) => void write(v), recordCtx: recordCtx, mode: mode }));
|
|
38
38
|
}
|
|
39
39
|
registerRenderer({ kinds: ['per-weekday'], layout: 'block', Page: WeekdayGroupPage, editor: 'custom' });
|
|
40
|
-
registerRenderer({ kinds: ['url'], layout: 'block', Page: UrlGroupPage });
|
|
40
|
+
registerRenderer({ kinds: ['url'], layout: 'block', Page: UrlGroupPage, activate: 'value' });
|
|
41
41
|
registerRenderer({ kinds: ['checklist'], layout: 'block', Page: ChecklistPage, editor: 'custom' });
|
|
@@ -12,6 +12,7 @@ import { useFieldErrors } from "../field-errors.js";
|
|
|
12
12
|
import { GroupField } from "./group-field.js";
|
|
13
13
|
import { useGroupEdit } from "./group-edit.js";
|
|
14
14
|
import { useHybridScope } from "../hybrid-scope.js";
|
|
15
|
+
import { datumClass } from "../datum.js";
|
|
15
16
|
import { FlowRow } from "./flow-row.js";
|
|
16
17
|
import { fieldLayout } from "../../registry.js";
|
|
17
18
|
export const subFull = (f) => fieldLayout(f) === 'block';
|
|
@@ -75,7 +76,7 @@ function CollectionCell({ sub, row, group, recordCtx, onChange, }) {
|
|
|
75
76
|
const { t } = useTranslation();
|
|
76
77
|
const live = useHybridScope() && Boolean(onChange);
|
|
77
78
|
const wired = live ? onChange : undefined;
|
|
78
|
-
return (_jsxs("div", { className:
|
|
79
|
+
return (_jsxs("div", { className: `flex flex-col gap-0.5 min-w-0 ${datumClass(sub.type)}`.trim(), children: [sub.type.label ? _jsx(FieldLabel, { label: t(sub.type.label) }) : null, _jsx(FieldSlot, { field: sub.type, fieldKey: live ? sub.key : undefined, value: row[sub.key] ?? '', mode: "view", bare: !live, recordCtx: recordCtx, onChange: wired })] }));
|
|
79
80
|
}
|
|
80
81
|
export function CollectionView({ group, value, onChange, recordCtx, actions, editable = false, }) {
|
|
81
82
|
const { t } = useTranslation();
|
|
@@ -6,10 +6,11 @@ import { hasValue, hasChildren, isNamedField, isStorageGroup } from '@coffer-org
|
|
|
6
6
|
import { FieldSlot } from "../dispatch.js";
|
|
7
7
|
import { useFieldErrors } from "../field-errors.js";
|
|
8
8
|
import { AddBtn, usedElsewhere } from "../shared.js";
|
|
9
|
-
import { GroupTitle, groupIcon, useGroupDepth, GroupDepthProvider, groupScopeClass } from "../chrome.js";
|
|
9
|
+
import { GroupTitle, groupIcon, useGroupDepth, GroupDepthProvider, groupScopeClass, ChromeLabel } from "../chrome.js";
|
|
10
10
|
import { Button } from "../../components/ui/button.js";
|
|
11
11
|
import { useGroupEdit } from "./group-edit.js";
|
|
12
12
|
import { useHybridScope } from "../hybrid-scope.js";
|
|
13
|
+
import { datumClass } from "../datum.js";
|
|
13
14
|
export function TableGroup({ group, value, onChange, recordCtx, mode, }) {
|
|
14
15
|
const { t } = useTranslation();
|
|
15
16
|
const errorAt = useFieldErrors();
|
|
@@ -49,8 +50,8 @@ export function TableGroup({ group, value, onChange, recordCtx, mode, }) {
|
|
|
49
50
|
};
|
|
50
51
|
const addRow = () => (live ? setPending((ps) => [...ps, {}]) : setRows([...rows, {}]));
|
|
51
52
|
const rowTools = isEdit || live;
|
|
52
|
-
const header = (_jsx("thead", { children: _jsxs("tr", { className: "border-b border-border/60 bg-muted/15", children: [subs.map((s, i) => (_jsx("th", { className: `text-left
|
|
53
|
-
const body = (_jsx("tbody", { className: "divide-y divide-border/30", children: rows.map((row, idx) => (_jsxs("tr", { className: "align-top hover:bg-muted/10 transition-colors", children: [subs.map((s, i) => (_jsx("td", { className: `px-3.5 py-2.5 min-h-10 ${isGrowCol(s, i) ? 'min-w-[140px]' : 'min-w-[90px]'}
|
|
53
|
+
const header = (_jsx("thead", { children: _jsxs("tr", { className: "border-b border-border/60 bg-muted/15", children: [subs.map((s, i) => (_jsx("th", { className: `text-left px-3.5 py-2.5 ${isGrowCol(s, i) ? 'w-full min-w-[140px]' : 'whitespace-nowrap min-w-[90px]'}`, children: _jsx(ChromeLabel, { children: colLabel(s) ? t(colLabel(s)) : '' }) }, colKey(s)))), rowTools && _jsx("th", { className: "w-10 px-2", "aria-hidden": true })] }) }));
|
|
54
|
+
const body = (_jsx("tbody", { className: "divide-y divide-border/30", children: rows.map((row, idx) => (_jsxs("tr", { className: "align-top hover:bg-muted/10 transition-colors", children: [subs.map((s, i) => (_jsx("td", { className: `px-3.5 py-2.5 min-h-10 ${isGrowCol(s, i) ? 'min-w-[140px]' : 'min-w-[90px]'} ${datumClass(colSlot(s).field)}`.trim(), children: _jsx(FieldSlot, { ...colSlot(s), value: row[colKey(s)] ?? (hasValue(s) ? '' : null), excludeValues: usedElsewhere(rows, unique, colKey(s), idx), onChange: (v) => update(idx, colKey(s), v), fieldKey: live ? colKey(s) : undefined, mode: isEdit ? 'edit' : 'view', bare: !live, recordCtx: recordCtx, error: isStorageGroup(group) ? errorAt([group.key, idx, colKey(s)]) : undefined }) }, colKey(s)))), rowTools && (_jsx("td", { className: "px-2 py-2 min-h-10 w-10", children: _jsx(Button, { type: "button", variant: "outline", size: "iconSm", onClick: () => removeRow(idx), title: t('actions.delete'), className: "rounded-lg text-muted hover:border-danger hover:text-danger", children: _jsx(Trash2, { size: 14 }) }) }))] }, idx))) }));
|
|
54
55
|
const tableEl = (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("div", { className: "overflow-x-auto rounded-lg border border-border/60 bg-card/20 shadow-2xs", children: _jsxs("table", { className: "w-full border-collapse text-sm", children: [header, body] }) }), rowTools && _jsx(AddBtn, { onClick: addRow, children: t('form.addRow') })] }));
|
|
55
56
|
if (mode !== 'view')
|
|
56
57
|
return tableEl;
|
package/dist/types.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export interface FieldValueProps {
|
|
|
48
48
|
}
|
|
49
49
|
export type PickerSize = 'small' | 'large' | 'modal';
|
|
50
50
|
export type EditorMode = 'popover' | 'modal' | 'inplace' | 'custom';
|
|
51
|
+
export type ActivateMode = 'edit' | 'value';
|
|
51
52
|
export interface FieldPickerProps {
|
|
52
53
|
field: FieldMeta;
|
|
53
54
|
draft: unknown;
|
|
@@ -80,5 +81,6 @@ export interface FieldRenderer {
|
|
|
80
81
|
pickerSize?: PickerSize | ((field: FieldMeta) => PickerSize);
|
|
81
82
|
Picker?: FC<FieldPickerProps>;
|
|
82
83
|
editor?: EditorMode;
|
|
84
|
+
activate?: ActivateMode;
|
|
83
85
|
keys?: (value: unknown, field: FieldMeta, ctx: FieldKeyCtx) => FieldKey[];
|
|
84
86
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coffer-org/web-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=24"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"postpack": "node ../../scripts/swap-exports.mjs src"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@coffer-org/sdk": "^
|
|
28
|
+
"@coffer-org/sdk": "^6.0.0",
|
|
29
29
|
"@ark-ui/react": "^5.37.2",
|
|
30
30
|
"@base-ui/react": "^1.5.0",
|
|
31
31
|
"@icons-pack/react-simple-icons": "^13.13.0",
|