@open-mercato/ui 0.6.1-develop.3256.1.fe3dec2464 → 0.6.1-develop.3276.1.1fcd145078
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/.turbo/turbo-build.log +1 -1
- package/dist/backend/CrudForm.js +46 -129
- package/dist/backend/CrudForm.js.map +3 -3
- package/dist/backend/DataTable.js +10 -3
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/EmptyState.js +1 -47
- package/dist/backend/EmptyState.js.map +2 -2
- package/dist/backend/FilterOverlay.js +31 -26
- package/dist/backend/FilterOverlay.js.map +2 -2
- package/dist/backend/FlashMessages.js +23 -25
- package/dist/backend/FlashMessages.js.map +2 -2
- package/dist/backend/JsonBuilder.js +4 -2
- package/dist/backend/JsonBuilder.js.map +2 -2
- package/dist/backend/LogList.js +49 -0
- package/dist/backend/LogList.js.map +7 -0
- package/dist/backend/crud/CollapsibleGroup.js +13 -3
- package/dist/backend/crud/CollapsibleGroup.js.map +2 -2
- package/dist/backend/detail/InlineEditors.js +80 -32
- package/dist/backend/detail/InlineEditors.js.map +2 -2
- package/dist/backend/inputs/ComboboxInput.js +60 -6
- package/dist/backend/inputs/ComboboxInput.js.map +2 -2
- package/dist/backend/inputs/DatePicker.js +6 -142
- package/dist/backend/inputs/DatePicker.js.map +2 -2
- package/dist/backend/inputs/DateTimePicker.js +6 -182
- package/dist/backend/inputs/DateTimePicker.js.map +2 -2
- package/dist/backend/inputs/TagsInput.js +16 -19
- package/dist/backend/inputs/TagsInput.js.map +2 -2
- package/dist/backend/inputs/TimeInput.js +1 -1
- package/dist/backend/inputs/TimeInput.js.map +2 -2
- package/dist/backend/inputs/TimePicker.js +83 -72
- package/dist/backend/inputs/TimePicker.js.map +2 -2
- package/dist/backend/utils/customFieldForms.js +2 -2
- package/dist/backend/utils/customFieldForms.js.map +1 -1
- package/dist/portal/components/PortalEmptyState.js +13 -9
- package/dist/portal/components/PortalEmptyState.js.map +2 -2
- package/dist/primitives/accordion.js +137 -0
- package/dist/primitives/accordion.js.map +7 -0
- package/dist/primitives/alert.js +180 -12
- package/dist/primitives/alert.js.map +2 -2
- package/dist/primitives/calendar.js +122 -32
- package/dist/primitives/calendar.js.map +2 -2
- package/dist/primitives/compact-select.js +47 -0
- package/dist/primitives/compact-select.js.map +7 -0
- package/dist/primitives/counter-input.js +174 -0
- package/dist/primitives/counter-input.js.map +7 -0
- package/dist/primitives/date-picker-helpers.js +79 -0
- package/dist/primitives/date-picker-helpers.js.map +7 -0
- package/dist/primitives/date-picker.js +216 -0
- package/dist/primitives/date-picker.js.map +7 -0
- package/dist/primitives/date-range-picker.js +239 -0
- package/dist/primitives/date-range-picker.js.map +7 -0
- package/dist/primitives/digit-input.js +157 -0
- package/dist/primitives/digit-input.js.map +7 -0
- package/dist/primitives/empty-state.js +93 -0
- package/dist/primitives/empty-state.js.map +7 -0
- package/dist/primitives/inline-input.js +29 -0
- package/dist/primitives/inline-input.js.map +7 -0
- package/dist/primitives/inline-select.js +41 -0
- package/dist/primitives/inline-select.js.map +7 -0
- package/dist/primitives/notification-stack.js +116 -0
- package/dist/primitives/notification-stack.js.map +7 -0
- package/dist/primitives/notification.js +62 -0
- package/dist/primitives/notification.js.map +7 -0
- package/dist/primitives/rich-editor.js +1230 -0
- package/dist/primitives/rich-editor.js.map +7 -0
- package/dist/primitives/select.js +1 -0
- package/dist/primitives/select.js.map +2 -2
- package/dist/primitives/skeleton.js +55 -0
- package/dist/primitives/skeleton.js.map +7 -0
- package/dist/primitives/tag-input.js +186 -0
- package/dist/primitives/tag-input.js.map +7 -0
- package/dist/primitives/tag.js +66 -13
- package/dist/primitives/tag.js.map +2 -2
- package/dist/primitives/time-picker.js +793 -0
- package/dist/primitives/time-picker.js.map +7 -0
- package/package.json +4 -3
- package/src/backend/CrudForm.tsx +61 -113
- package/src/backend/DataTable.tsx +17 -5
- package/src/backend/EmptyState.tsx +13 -63
- package/src/backend/FilterOverlay.tsx +38 -22
- package/src/backend/FlashMessages.tsx +23 -24
- package/src/backend/JsonBuilder.tsx +4 -2
- package/src/backend/LogList.tsx +109 -0
- package/src/backend/__tests__/CrudForm.datetime.test.tsx +12 -7
- package/src/backend/__tests__/FilterOverlay.dateRange.test.tsx +89 -0
- package/src/backend/__tests__/LogList.test.tsx +163 -0
- package/src/backend/crud/CollapsibleGroup.tsx +17 -3
- package/src/backend/detail/InlineEditors.tsx +78 -25
- package/src/backend/detail/__tests__/InlineEditors.test.tsx +81 -1
- package/src/backend/inputs/ComboboxInput.tsx +81 -9
- package/src/backend/inputs/DatePicker.tsx +28 -155
- package/src/backend/inputs/DateTimePicker.tsx +25 -193
- package/src/backend/inputs/TagsInput.tsx +10 -13
- package/src/backend/inputs/TimeInput.tsx +2 -1
- package/src/backend/inputs/TimePicker.tsx +99 -70
- package/src/backend/inputs/__tests__/ComboboxInput.test.tsx +133 -0
- package/src/backend/inputs/__tests__/TimePicker.test.tsx +2 -2
- package/src/backend/utils/__tests__/richTextSanitizer.test.ts +5 -2
- package/src/backend/utils/customFieldForms.ts +2 -2
- package/src/portal/components/PortalEmptyState.tsx +27 -22
- package/src/primitives/__tests__/accordion.test.tsx +197 -0
- package/src/primitives/__tests__/alert.test.tsx +204 -0
- package/src/primitives/__tests__/compact-select.test.tsx +98 -0
- package/src/primitives/__tests__/counter-input.test.tsx +165 -0
- package/src/primitives/__tests__/date-picker.test.tsx +221 -0
- package/src/primitives/__tests__/date-range-picker.test.tsx +173 -0
- package/src/primitives/__tests__/digit-input.test.tsx +168 -0
- package/src/primitives/__tests__/empty-state.test.tsx +154 -0
- package/src/primitives/__tests__/inline-input.test.tsx +100 -0
- package/src/primitives/__tests__/inline-select.test.tsx +103 -0
- package/src/primitives/__tests__/notification-stack.test.tsx +174 -0
- package/src/primitives/__tests__/notification.test.tsx +119 -0
- package/src/primitives/__tests__/rich-editor.test.tsx +411 -0
- package/src/primitives/__tests__/skeleton.test.tsx +76 -0
- package/src/primitives/__tests__/tag-input.test.tsx +198 -0
- package/src/primitives/__tests__/tag.test.tsx +123 -0
- package/src/primitives/__tests__/time-picker.test.tsx +392 -0
- package/src/primitives/accordion.tsx +225 -0
- package/src/primitives/alert.tsx +234 -24
- package/src/primitives/calendar.tsx +146 -38
- package/src/primitives/compact-select.tsx +59 -0
- package/src/primitives/counter-input.tsx +211 -0
- package/src/primitives/date-picker-helpers.ts +96 -0
- package/src/primitives/date-picker.tsx +290 -0
- package/src/primitives/date-range-picker.tsx +281 -0
- package/src/primitives/digit-input.tsx +208 -0
- package/src/primitives/empty-state.tsx +140 -0
- package/src/primitives/inline-input.tsx +55 -0
- package/src/primitives/inline-select.tsx +74 -0
- package/src/primitives/notification-stack.tsx +185 -0
- package/src/primitives/notification.tsx +136 -0
- package/src/primitives/rich-editor.tsx +1578 -0
- package/src/primitives/select.tsx +1 -0
- package/src/primitives/skeleton.tsx +70 -0
- package/src/primitives/tag-input.tsx +223 -0
- package/src/primitives/tag.tsx +69 -10
- package/src/primitives/time-picker.tsx +1059 -0
package/.turbo/turbo-build.log
CHANGED
package/dist/backend/CrudForm.js
CHANGED
|
@@ -93,7 +93,7 @@ import { useGroupOrder } from "./crud/useGroupOrder.js";
|
|
|
93
93
|
import { InjectedField } from "./injection/InjectedField.js";
|
|
94
94
|
import { evaluateInjectedVisibility } from "./injection/visibility-utils.js";
|
|
95
95
|
import { ComponentReplacementHandles } from "@open-mercato/shared/modules/widgets/component-registry";
|
|
96
|
-
import {
|
|
96
|
+
import { RichEditor } from "../primitives/rich-editor.js";
|
|
97
97
|
const EMPTY_OPTIONS = [];
|
|
98
98
|
const SELECT_CLEAR_SENTINEL = "__crudform_select_clear__";
|
|
99
99
|
const FOCUSABLE_SELECTOR = '[data-crud-focus-target], input:not([type="hidden"]):not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
@@ -2913,120 +2913,27 @@ const MarkdownEditor = React.memo(function MarkdownEditor2({ value = "", onChang
|
|
|
2913
2913
|
}
|
|
2914
2914
|
) });
|
|
2915
2915
|
}, (prev, next) => prev.value === next.value);
|
|
2916
|
-
const
|
|
2916
|
+
const HtmlRichEditorField = React.memo(function HtmlRichEditorField2({ value = "", onChange }) {
|
|
2917
2917
|
const t = useT();
|
|
2918
|
-
const
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
applyingExternal.current = false;
|
|
2938
|
-
});
|
|
2939
|
-
}
|
|
2940
|
-
}, [value]);
|
|
2941
|
-
const exec = (cmd, arg) => {
|
|
2942
|
-
const el = ref.current;
|
|
2943
|
-
if (!el) return;
|
|
2944
|
-
el.focus();
|
|
2945
|
-
try {
|
|
2946
|
-
document.execCommand(cmd, false, arg);
|
|
2947
|
-
} catch {
|
|
2948
|
-
}
|
|
2949
|
-
};
|
|
2950
|
-
const onKeyDown = (e) => {
|
|
2951
|
-
const isMod = e.metaKey || e.ctrlKey;
|
|
2952
|
-
if (!isMod) return;
|
|
2953
|
-
const k = e.key.toLowerCase();
|
|
2954
|
-
if (k === "b") {
|
|
2955
|
-
e.preventDefault();
|
|
2956
|
-
exec("bold");
|
|
2957
|
-
}
|
|
2958
|
-
if (k === "i") {
|
|
2959
|
-
e.preventDefault();
|
|
2960
|
-
exec("italic");
|
|
2961
|
-
}
|
|
2962
|
-
if (k === "u") {
|
|
2963
|
-
e.preventDefault();
|
|
2964
|
-
exec("underline");
|
|
2965
|
-
}
|
|
2966
|
-
};
|
|
2967
|
-
const onPaste = (e) => {
|
|
2968
|
-
const html = e.clipboardData.getData("text/html");
|
|
2969
|
-
const text = e.clipboardData.getData("text/plain");
|
|
2970
|
-
const sanitizedPaste = sanitizeRichTextPasteContent(html, text);
|
|
2971
|
-
if (!sanitizedPaste) return;
|
|
2972
|
-
e.preventDefault();
|
|
2973
|
-
exec(sanitizedPaste.command, sanitizedPaste.value);
|
|
2974
|
-
};
|
|
2975
|
-
return /* @__PURE__ */ jsxs("div", { className: "w-full rounded border", children: [
|
|
2976
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 px-2 py-1 border-b", children: [
|
|
2977
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "h-auto px-2 py-0.5 text-xs", onMouseDown: (e) => e.preventDefault(), onClick: () => exec("bold"), children: boldLabel }),
|
|
2978
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "h-auto px-2 py-0.5 text-xs", onMouseDown: (e) => e.preventDefault(), onClick: () => exec("italic"), children: italicLabel }),
|
|
2979
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "h-auto px-2 py-0.5 text-xs", onMouseDown: (e) => e.preventDefault(), onClick: () => exec("underline"), children: underlineLabel }),
|
|
2980
|
-
/* @__PURE__ */ jsx("span", { className: "mx-2 text-muted-foreground", children: "|" }),
|
|
2981
|
-
/* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", className: "h-auto px-2 py-0.5 text-xs", onMouseDown: (e) => e.preventDefault(), onClick: () => exec("insertUnorderedList"), children: [
|
|
2982
|
-
"\u2022 ",
|
|
2983
|
-
listLabel
|
|
2984
|
-
] }),
|
|
2985
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "h-auto px-2 py-0.5 text-xs", onMouseDown: (e) => e.preventDefault(), onClick: () => exec("formatBlock", "<h3>"), children: heading3Label }),
|
|
2986
|
-
/* @__PURE__ */ jsx(
|
|
2987
|
-
Button,
|
|
2988
|
-
{
|
|
2989
|
-
variant: "ghost",
|
|
2990
|
-
size: "sm",
|
|
2991
|
-
className: "h-auto px-2 py-0.5 text-xs",
|
|
2992
|
-
onMouseDown: (e) => e.preventDefault(),
|
|
2993
|
-
onClick: () => {
|
|
2994
|
-
const url = sanitizeRichTextHref(window.prompt(linkUrlPrompt));
|
|
2995
|
-
if (url) exec("createLink", url);
|
|
2996
|
-
},
|
|
2997
|
-
children: linkLabel
|
|
2998
|
-
}
|
|
2999
|
-
)
|
|
3000
|
-
] }),
|
|
3001
|
-
/* @__PURE__ */ jsx(
|
|
3002
|
-
"div",
|
|
3003
|
-
{
|
|
3004
|
-
ref,
|
|
3005
|
-
className: "w-full px-2 py-2 min-h-[100px] sm:min-h-[160px] focus-visible:outline-none prose prose-sm max-w-none",
|
|
3006
|
-
contentEditable: true,
|
|
3007
|
-
suppressContentEditableWarning: true,
|
|
3008
|
-
onKeyDown,
|
|
3009
|
-
onPaste,
|
|
3010
|
-
onInput: () => {
|
|
3011
|
-
if (!applyingExternal.current) typingRef.current = true;
|
|
3012
|
-
},
|
|
3013
|
-
onBlur: () => {
|
|
3014
|
-
const el = ref.current;
|
|
3015
|
-
if (!el) return;
|
|
3016
|
-
typingRef.current = false;
|
|
3017
|
-
const sanitizedValue = sanitizeHtmlRichText(el.innerHTML);
|
|
3018
|
-
if (el.innerHTML !== sanitizedValue) {
|
|
3019
|
-
applyingExternal.current = true;
|
|
3020
|
-
el.innerHTML = sanitizedValue;
|
|
3021
|
-
requestAnimationFrame(() => {
|
|
3022
|
-
applyingExternal.current = false;
|
|
3023
|
-
});
|
|
3024
|
-
}
|
|
3025
|
-
onChange(sanitizedValue);
|
|
3026
|
-
}
|
|
3027
|
-
}
|
|
3028
|
-
)
|
|
3029
|
-
] });
|
|
2918
|
+
const labels = React.useMemo(() => ({
|
|
2919
|
+
bold: t("ui.forms.richtext.bold"),
|
|
2920
|
+
italic: t("ui.forms.richtext.italic"),
|
|
2921
|
+
underline: t("ui.forms.richtext.underline"),
|
|
2922
|
+
unorderedList: t("ui.forms.richtext.list"),
|
|
2923
|
+
orderedList: t("ui.forms.richtext.orderedList", "Numbered list"),
|
|
2924
|
+
heading: t("ui.forms.richtext.heading", "Heading"),
|
|
2925
|
+
heading1: t("ui.forms.richtext.heading1", "Heading 1"),
|
|
2926
|
+
heading2: t("ui.forms.richtext.heading2", "Heading 2"),
|
|
2927
|
+
heading3: t("ui.forms.richtext.heading3"),
|
|
2928
|
+
paragraph: t("ui.forms.richtext.paragraph", "Paragraph"),
|
|
2929
|
+
link: t("ui.forms.richtext.link"),
|
|
2930
|
+
linkUrlPrompt: t("ui.forms.richtext.linkUrlPrompt"),
|
|
2931
|
+
placeholder: t("ui.forms.richtext.placeholder"),
|
|
2932
|
+
comment: t("ui.forms.richtext.comment", "Add comment"),
|
|
2933
|
+
mention: t("ui.forms.richtext.mention", "Mention"),
|
|
2934
|
+
more: t("ui.forms.richtext.more", "More")
|
|
2935
|
+
}), [t]);
|
|
2936
|
+
return /* @__PURE__ */ jsx(RichEditor, { value, onChange, variant: "full", labels });
|
|
3030
2937
|
}, (prev, next) => prev.value === next.value);
|
|
3031
2938
|
const SimpleMarkdownEditor = React.memo(function SimpleMarkdownEditor2({ value = "", onChange }) {
|
|
3032
2939
|
const t = useT();
|
|
@@ -3252,25 +3159,33 @@ const FieldControl = React.memo(
|
|
|
3252
3159
|
}
|
|
3253
3160
|
),
|
|
3254
3161
|
field.type === "date" && /* @__PURE__ */ jsx(
|
|
3255
|
-
|
|
3162
|
+
DatePicker,
|
|
3256
3163
|
{
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3164
|
+
value: typeof value === "string" && value ? parseISO(value) : value instanceof Date ? value : null,
|
|
3165
|
+
onChange: (date) => setValue(field.id, date ? format(date, "yyyy-MM-dd") : void 0),
|
|
3166
|
+
disabled,
|
|
3167
|
+
readOnly,
|
|
3168
|
+
placeholder,
|
|
3169
|
+
minDate: builtin?.minDate,
|
|
3170
|
+
maxDate: builtin?.maxDate,
|
|
3171
|
+
displayFormat: builtin?.displayFormat,
|
|
3172
|
+
closeOnSelect: builtin?.closeOnSelect,
|
|
3173
|
+
locale: builtin?.locale
|
|
3263
3174
|
}
|
|
3264
3175
|
),
|
|
3265
3176
|
field.type === "datetime-local" && /* @__PURE__ */ jsx(
|
|
3266
|
-
|
|
3177
|
+
DateTimePicker,
|
|
3267
3178
|
{
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3179
|
+
value: typeof value === "string" && value ? new Date(value) : value instanceof Date ? value : null,
|
|
3180
|
+
onChange: (date) => setValue(field.id, date ? format(date, "yyyy-MM-dd'T'HH:mm") : void 0),
|
|
3181
|
+
disabled,
|
|
3182
|
+
readOnly,
|
|
3183
|
+
placeholder,
|
|
3184
|
+
minuteStep: builtin?.minuteStep,
|
|
3185
|
+
minDate: builtin?.minDate,
|
|
3186
|
+
maxDate: builtin?.maxDate,
|
|
3187
|
+
displayFormat: builtin?.displayFormat,
|
|
3188
|
+
locale: builtin?.locale
|
|
3274
3189
|
}
|
|
3275
3190
|
),
|
|
3276
3191
|
field.type === "datepicker" && /* @__PURE__ */ jsx(
|
|
@@ -3328,7 +3243,7 @@ const FieldControl = React.memo(
|
|
|
3328
3243
|
}
|
|
3329
3244
|
),
|
|
3330
3245
|
field.type === "richtext" && builtin?.editor === "simple" && /* @__PURE__ */ jsx(SimpleMarkdownEditor, { value: String(value ?? ""), onChange: fieldSetValue }),
|
|
3331
|
-
field.type === "richtext" && builtin?.editor === "html" && /* @__PURE__ */ jsx(
|
|
3246
|
+
field.type === "richtext" && builtin?.editor === "html" && /* @__PURE__ */ jsx(HtmlRichEditorField, { value: String(value ?? ""), onChange: fieldSetValue }),
|
|
3332
3247
|
field.type === "richtext" && (!builtin?.editor || builtin.editor !== "simple" && builtin.editor !== "html") && /* @__PURE__ */ jsx(MarkdownEditor, { value: String(value ?? ""), onChange: fieldSetValue }),
|
|
3333
3248
|
field.type === "tags" && /* @__PURE__ */ jsx(
|
|
3334
3249
|
TagsInput,
|
|
@@ -3353,6 +3268,8 @@ const FieldControl = React.memo(
|
|
|
3353
3268
|
placeholder,
|
|
3354
3269
|
autoFocus: autoFocusField,
|
|
3355
3270
|
suggestions: builtin?.suggestions ? builtin.suggestions : options.map((opt) => ({ value: opt.value, label: opt.label })),
|
|
3271
|
+
seedOptions: builtin?.seedOptions ? builtin.seedOptions.map((opt) => ({ value: opt.value, label: opt.label })) : void 0,
|
|
3272
|
+
resolveLabel: builtin?.resolveLabel,
|
|
3356
3273
|
loadSuggestions: typeof builtin?.loadOptions === "function" ? async (query) => {
|
|
3357
3274
|
const opts = await loadFieldOptions(field, query);
|
|
3358
3275
|
return opts.map((opt) => ({ value: opt.value, label: opt.label }));
|