@sustaina/shared-ui 1.25.0 → 1.27.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/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +86 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +86 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2447,7 +2447,10 @@ var ConditionDropdownInput = ({ row, control, fieldSchema, onClear }) => /* @__P
|
|
|
2447
2447
|
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select value" })
|
|
2448
2448
|
}
|
|
2449
2449
|
) }),
|
|
2450
|
-
/* @__PURE__ */ jsx(SelectContent, { className: "w-full min-w-[unset]", children: fieldSchema && "options" in fieldSchema && fieldSchema.options.map((opt) => /* @__PURE__ */
|
|
2450
|
+
/* @__PURE__ */ jsx(SelectContent, { className: "w-full min-w-[unset]", children: fieldSchema && "options" in fieldSchema && fieldSchema.options.map((opt) => /* @__PURE__ */ jsxs(SelectItem, { value: opt.value, className: cn(opt.labelStyle), children: [
|
|
2451
|
+
opt.decorator,
|
|
2452
|
+
opt.label
|
|
2453
|
+
] }, opt.value)) })
|
|
2451
2454
|
] }),
|
|
2452
2455
|
hasValue && /* @__PURE__ */ jsx(
|
|
2453
2456
|
ClearButton,
|
|
@@ -2518,7 +2521,8 @@ var LookupSelect = ({
|
|
|
2518
2521
|
suggestionDebounce = 250,
|
|
2519
2522
|
noOptionsMessage = "No records found. Please try a different search.",
|
|
2520
2523
|
loadingMessage = "Loading...",
|
|
2521
|
-
dropdownPortalId
|
|
2524
|
+
dropdownPortalId,
|
|
2525
|
+
multiple = false
|
|
2522
2526
|
}) => {
|
|
2523
2527
|
const [inputValue, setInputValue] = useState("");
|
|
2524
2528
|
const inputRef = useRef(null);
|
|
@@ -2535,6 +2539,7 @@ var LookupSelect = ({
|
|
|
2535
2539
|
const assignDropdownContentRef = useCallback((node) => {
|
|
2536
2540
|
dropdownContentRef.current = node;
|
|
2537
2541
|
}, []);
|
|
2542
|
+
const [activeSuggestionIndex, setActiveSuggestionIndex] = useState(-1);
|
|
2538
2543
|
const dropdownPortalElement = useMemo(() => {
|
|
2539
2544
|
if (typeof document === "undefined") return null;
|
|
2540
2545
|
if (dropdownPortalId) {
|
|
@@ -2543,7 +2548,9 @@ var LookupSelect = ({
|
|
|
2543
2548
|
}
|
|
2544
2549
|
return document.body;
|
|
2545
2550
|
}, [dropdownPortalId]);
|
|
2546
|
-
const limitReached = value.length >= maxTags;
|
|
2551
|
+
const limitReached = multiple && value.length >= maxTags;
|
|
2552
|
+
const selectedValue = !multiple && value.length > 0 ? value[0] : void 0;
|
|
2553
|
+
const selectedLabel = selectedValue ? optionLabels[selectedValue] ?? selectedValue : void 0;
|
|
2547
2554
|
const upsertOptionLabels = useCallback((options) => {
|
|
2548
2555
|
setOptionLabels((prev) => {
|
|
2549
2556
|
let next = null;
|
|
@@ -2562,13 +2569,17 @@ var LookupSelect = ({
|
|
|
2562
2569
|
const trimmed = val.trim();
|
|
2563
2570
|
if (!trimmed) return;
|
|
2564
2571
|
if (value.includes(trimmed)) return;
|
|
2565
|
-
if (
|
|
2566
|
-
|
|
2572
|
+
if (multiple) {
|
|
2573
|
+
if (value.length >= maxTags) return;
|
|
2574
|
+
onChange([...value, trimmed]);
|
|
2575
|
+
} else {
|
|
2576
|
+
onChange([trimmed]);
|
|
2577
|
+
}
|
|
2567
2578
|
setInputValue("");
|
|
2568
2579
|
setSuggestions([]);
|
|
2569
2580
|
setIsDropdownOpen(false);
|
|
2570
2581
|
},
|
|
2571
|
-
[value, onChange, maxTags]
|
|
2582
|
+
[value, onChange, maxTags, multiple]
|
|
2572
2583
|
);
|
|
2573
2584
|
const removeTag = useCallback(
|
|
2574
2585
|
(index) => {
|
|
@@ -2578,17 +2589,6 @@ var LookupSelect = ({
|
|
|
2578
2589
|
},
|
|
2579
2590
|
[value, onChange]
|
|
2580
2591
|
);
|
|
2581
|
-
const handleKeyDown = useCallback(
|
|
2582
|
-
(e) => {
|
|
2583
|
-
if (e.key === "Enter" || e.key === ",") {
|
|
2584
|
-
e.preventDefault();
|
|
2585
|
-
}
|
|
2586
|
-
if (e.key === "Backspace" && !inputValue) {
|
|
2587
|
-
removeTag(value.length - 1);
|
|
2588
|
-
}
|
|
2589
|
-
},
|
|
2590
|
-
[inputValue, removeTag, value.length]
|
|
2591
|
-
);
|
|
2592
2592
|
const handleClear = useCallback(() => {
|
|
2593
2593
|
setInputValue("");
|
|
2594
2594
|
setSuggestions([]);
|
|
@@ -2607,6 +2607,33 @@ var LookupSelect = ({
|
|
|
2607
2607
|
},
|
|
2608
2608
|
[addTag, upsertOptionLabels]
|
|
2609
2609
|
);
|
|
2610
|
+
const handleKeyDown = useCallback(
|
|
2611
|
+
(e) => {
|
|
2612
|
+
if (e.key === "ArrowDown" && suggestions.length > 0) {
|
|
2613
|
+
e.preventDefault();
|
|
2614
|
+
setIsDropdownOpen(true);
|
|
2615
|
+
setActiveSuggestionIndex((prev) => Math.min(prev + 1, suggestions.length - 1));
|
|
2616
|
+
return;
|
|
2617
|
+
}
|
|
2618
|
+
if (e.key === "ArrowUp" && suggestions.length > 0) {
|
|
2619
|
+
e.preventDefault();
|
|
2620
|
+
setActiveSuggestionIndex((prev) => Math.max(prev - 1, 0));
|
|
2621
|
+
return;
|
|
2622
|
+
}
|
|
2623
|
+
if (e.key === "Enter" && activeSuggestionIndex >= 0 && suggestions[activeSuggestionIndex]) {
|
|
2624
|
+
e.preventDefault();
|
|
2625
|
+
handleSuggestionSelect(suggestions[activeSuggestionIndex]);
|
|
2626
|
+
return;
|
|
2627
|
+
}
|
|
2628
|
+
if (e.key === "," || e.key === "Enter") {
|
|
2629
|
+
e.preventDefault();
|
|
2630
|
+
}
|
|
2631
|
+
if (e.key === "Backspace" && !inputValue) {
|
|
2632
|
+
removeTag(value.length - 1);
|
|
2633
|
+
}
|
|
2634
|
+
},
|
|
2635
|
+
[suggestions, activeSuggestionIndex, handleSuggestionSelect, inputValue, removeTag, value.length]
|
|
2636
|
+
);
|
|
2610
2637
|
const updateDropdownPosition = useCallback(() => {
|
|
2611
2638
|
if (!dropdownPortalElement || !containerRef.current) return;
|
|
2612
2639
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -2633,6 +2660,7 @@ var LookupSelect = ({
|
|
|
2633
2660
|
}
|
|
2634
2661
|
setLoading(true);
|
|
2635
2662
|
setFetchError(null);
|
|
2663
|
+
setIsDropdownOpen(true);
|
|
2636
2664
|
const requestId = ++requestIdRef.current;
|
|
2637
2665
|
fetchDelayRef.current = setTimeout(() => {
|
|
2638
2666
|
fetchSuggestions(query).then((items) => {
|
|
@@ -2686,21 +2714,33 @@ var LookupSelect = ({
|
|
|
2686
2714
|
window.removeEventListener("scroll", handleReposition, true);
|
|
2687
2715
|
};
|
|
2688
2716
|
}, [dropdownPortalElement, isDropdownOpen, updateDropdownPosition]);
|
|
2717
|
+
useEffect(() => {
|
|
2718
|
+
if (suggestions.length === 0) {
|
|
2719
|
+
setActiveSuggestionIndex(-1);
|
|
2720
|
+
return;
|
|
2721
|
+
}
|
|
2722
|
+
setActiveSuggestionIndex((prev) => {
|
|
2723
|
+
if (prev === -1) return 0;
|
|
2724
|
+
if (prev >= suggestions.length) return suggestions.length - 1;
|
|
2725
|
+
return prev;
|
|
2726
|
+
});
|
|
2727
|
+
}, [suggestions]);
|
|
2689
2728
|
const resolvedPlaceholder = placeholder2 ?? "Select";
|
|
2690
2729
|
const showDropdown = isDropdownOpen && !fetchError;
|
|
2691
2730
|
const dropdownContent = /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg", children: loading ? /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-sm text-inherit", children: loadingMessage }) : suggestions.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center px-3 py-4 text-sm text-inherit text-center", children: [
|
|
2692
|
-
/* @__PURE__ */ jsx(not_found_default, { className: "w-full max-w-
|
|
2731
|
+
/* @__PURE__ */ jsx(not_found_default, { className: "w-full max-w-20 h-auto" }),
|
|
2693
2732
|
/* @__PURE__ */ jsx("span", { className: "pt-3", children: noOptionsMessage })
|
|
2694
|
-
] }) : /* @__PURE__ */ jsx("ul", { className: "max-h-48 overflow-y-auto py-1", children: suggestions.map((option) => {
|
|
2695
|
-
const disabled = value.includes(option.value) || limitReached;
|
|
2733
|
+
] }) : /* @__PURE__ */ jsx("ul", { className: "max-h-48 overflow-y-auto py-1", children: suggestions.map((option, index) => {
|
|
2734
|
+
const disabled = value.includes(option.value) || multiple && limitReached;
|
|
2696
2735
|
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
2697
2736
|
"button",
|
|
2698
2737
|
{
|
|
2699
2738
|
type: "button",
|
|
2700
|
-
className: `flex w-full items-center justify-between px-3 py-2 text-left text-sm transition
|
|
2701
|
-
${disabled ? "cursor-not-allowed text-gray-400" : "text-gray-700"}`,
|
|
2739
|
+
className: `flex w-full items-center justify-between px-3 py-2 text-left text-sm transition
|
|
2740
|
+
${disabled ? "cursor-not-allowed text-gray-400" : index === activeSuggestionIndex ? "bg-gray-100 text-gray-900" : "hover:bg-gray-100 text-gray-700"}`,
|
|
2702
2741
|
onClick: () => handleSuggestionSelect(option),
|
|
2703
2742
|
disabled,
|
|
2743
|
+
"aria-selected": index === activeSuggestionIndex,
|
|
2704
2744
|
children: /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label })
|
|
2705
2745
|
}
|
|
2706
2746
|
) }, option.value);
|
|
@@ -2719,16 +2759,16 @@ var LookupSelect = ({
|
|
|
2719
2759
|
/* @__PURE__ */ jsxs(
|
|
2720
2760
|
"div",
|
|
2721
2761
|
{
|
|
2722
|
-
className: `flex min-h-
|
|
2762
|
+
className: `flex min-h-9 items-center gap-3 rounded-md border bg-white px-3 transition-all
|
|
2723
2763
|
${error ? "border-red-500 focus-within:ring-red-500" : "border-gray-300 "}`,
|
|
2724
2764
|
children: [
|
|
2725
2765
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-wrap content-start gap-1 overflow-y-auto max-h-[72px] hide-scrollbar pr-4", children: [
|
|
2726
|
-
value.map((tag, i) => {
|
|
2766
|
+
multiple && value.map((tag, i) => {
|
|
2727
2767
|
const label = optionLabels[tag] ?? tag;
|
|
2728
2768
|
return /* @__PURE__ */ jsxs(
|
|
2729
2769
|
"span",
|
|
2730
2770
|
{
|
|
2731
|
-
className: "flex items-center gap-1 rounded-lg border border-[#f0f0f0] bg-[#f9f9f9] px-2 py-1 my-1 text-sm text-inherit max-w-full break-
|
|
2771
|
+
className: "flex items-center gap-1 rounded-lg border border-[#f0f0f0] bg-[#f9f9f9] px-2 py-1 my-1 text-sm text-inherit max-w-full wrap-break-word",
|
|
2732
2772
|
children: [
|
|
2733
2773
|
/* @__PURE__ */ jsx("span", { className: "whitespace-pre-wrap break-all", children: label }),
|
|
2734
2774
|
/* @__PURE__ */ jsx(
|
|
@@ -2737,6 +2777,7 @@ var LookupSelect = ({
|
|
|
2737
2777
|
type: "button",
|
|
2738
2778
|
onClick: () => removeTag(i),
|
|
2739
2779
|
className: "text-inherit transition hover:text-red-500",
|
|
2780
|
+
"aria-label": `Remove ${label}`,
|
|
2740
2781
|
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
2741
2782
|
}
|
|
2742
2783
|
)
|
|
@@ -2745,7 +2786,8 @@ var LookupSelect = ({
|
|
|
2745
2786
|
`${tag}-${i}`
|
|
2746
2787
|
);
|
|
2747
2788
|
}),
|
|
2748
|
-
!
|
|
2789
|
+
!multiple && selectedLabel && /* @__PURE__ */ jsx("span", { className: "truncate text-sm text-gray-700", children: selectedLabel }),
|
|
2790
|
+
/* @__PURE__ */ jsx(
|
|
2749
2791
|
"input",
|
|
2750
2792
|
{
|
|
2751
2793
|
ref: inputRef,
|
|
@@ -2760,7 +2802,7 @@ var LookupSelect = ({
|
|
|
2760
2802
|
},
|
|
2761
2803
|
placeholder: value.length === 0 && resolvedPlaceholder || "",
|
|
2762
2804
|
className: "min-w-[120px] flex-1 border-none bg-transparent py-1 text-sm text-gray-600 placeholder:text-gray-400 outline-none",
|
|
2763
|
-
disabled: limitReached
|
|
2805
|
+
disabled: multiple && limitReached
|
|
2764
2806
|
}
|
|
2765
2807
|
)
|
|
2766
2808
|
] }),
|
|
@@ -2820,7 +2862,8 @@ var ConditionLookupInput = ({
|
|
|
2820
2862
|
noOptionsMessage: fieldSchema?.noOptionsMessage,
|
|
2821
2863
|
loadingMessage: fieldSchema?.loadingMessage,
|
|
2822
2864
|
dropdownPortalId,
|
|
2823
|
-
"data-testid": "advsearch-lookup-list"
|
|
2865
|
+
"data-testid": "advsearch-lookup-list",
|
|
2866
|
+
multiple: true
|
|
2824
2867
|
}
|
|
2825
2868
|
) }),
|
|
2826
2869
|
/* @__PURE__ */ jsx(FormMessage, { className: "absolute left-0 top-full mt-1 text-xs text-red-600" })
|
|
@@ -6265,7 +6308,8 @@ var FormulaEditor = ({
|
|
|
6265
6308
|
onChange,
|
|
6266
6309
|
onSelectSuggestion,
|
|
6267
6310
|
field,
|
|
6268
|
-
fieldState
|
|
6311
|
+
fieldState,
|
|
6312
|
+
mode = "edit"
|
|
6269
6313
|
}) => {
|
|
6270
6314
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
6271
6315
|
const lastEmittedValueRef = useRef(null);
|
|
@@ -6282,27 +6326,22 @@ var FormulaEditor = ({
|
|
|
6282
6326
|
const prefixMap = useMemo(() => buildPrefixMap(normalizedConfigs), [normalizedConfigs]);
|
|
6283
6327
|
const configLookup = useMemo(() => {
|
|
6284
6328
|
const lookup = /* @__PURE__ */ new Map();
|
|
6285
|
-
normalizedConfigs.forEach((config) =>
|
|
6286
|
-
lookup.set(config.prefix, config);
|
|
6287
|
-
});
|
|
6329
|
+
normalizedConfigs.forEach((config) => lookup.set(config.prefix, config));
|
|
6288
6330
|
return lookup;
|
|
6289
6331
|
}, [normalizedConfigs]);
|
|
6290
6332
|
const allowedOperators = useMemo(() => operators.map((operator) => operator.value), [operators]);
|
|
6291
6333
|
const displayError = errorMessage ?? fieldState?.error?.message;
|
|
6292
6334
|
const hasError = Boolean(displayError);
|
|
6293
|
-
const
|
|
6335
|
+
const isEditorReadOnly = mode === "display";
|
|
6336
|
+
const isEditorDisabled = disabled || loading || isEditorReadOnly;
|
|
6294
6337
|
const convertValueToContent = useCallback(
|
|
6295
6338
|
(input) => {
|
|
6296
6339
|
if (!input) return "";
|
|
6297
6340
|
const trimmed = input.trim();
|
|
6298
6341
|
if (!trimmed) return "";
|
|
6299
6342
|
const parsedJSON = tryParseJSON(trimmed);
|
|
6300
|
-
if (parsedJSON && parsedJSON.type === "doc")
|
|
6301
|
-
|
|
6302
|
-
}
|
|
6303
|
-
if (looksLikeHTML(trimmed)) {
|
|
6304
|
-
return input;
|
|
6305
|
-
}
|
|
6343
|
+
if (parsedJSON && parsedJSON.type === "doc") return parsedJSON;
|
|
6344
|
+
if (looksLikeHTML(trimmed)) return input;
|
|
6306
6345
|
return buildDocFromRaw(input, prefixMap, configLookup);
|
|
6307
6346
|
},
|
|
6308
6347
|
[configLookup, prefixMap]
|
|
@@ -6333,7 +6372,7 @@ var FormulaEditor = ({
|
|
|
6333
6372
|
hasError ? "border border-destructive" : "border focus-visible:border-ring",
|
|
6334
6373
|
"w-full rounded-lg bg-white px-4 py-3",
|
|
6335
6374
|
"overflow-y-auto whitespace-pre-wrap wrap-break-word focus:outline-none",
|
|
6336
|
-
|
|
6375
|
+
isEditorDisabled && "pointer-events-none",
|
|
6337
6376
|
editorClassName
|
|
6338
6377
|
),
|
|
6339
6378
|
...loading ? { "aria-busy": "true" } : {}
|
|
@@ -6342,8 +6381,8 @@ var FormulaEditor = ({
|
|
|
6342
6381
|
});
|
|
6343
6382
|
useEffect(() => {
|
|
6344
6383
|
if (!editor) return;
|
|
6345
|
-
editor.setEditable(!
|
|
6346
|
-
}, [editor,
|
|
6384
|
+
editor.setEditable(!isEditorDisabled);
|
|
6385
|
+
}, [editor, isEditorDisabled]);
|
|
6347
6386
|
useEffect(() => {
|
|
6348
6387
|
if (!editor || resolvedContent === void 0) return;
|
|
6349
6388
|
if (ignorePropValueRef.current && typeof value === "string" && value === lastEmittedValueRef.current) {
|
|
@@ -6377,9 +6416,7 @@ var FormulaEditor = ({
|
|
|
6377
6416
|
className: "relative",
|
|
6378
6417
|
"aria-busy": loading,
|
|
6379
6418
|
onFocus: () => {
|
|
6380
|
-
if (editor && !editor.isFocused)
|
|
6381
|
-
editor.chain().focus().run();
|
|
6382
|
-
}
|
|
6419
|
+
if (editor && !editor.isFocused) editor.chain().focus().run();
|
|
6383
6420
|
},
|
|
6384
6421
|
children: [
|
|
6385
6422
|
/* @__PURE__ */ jsx(EditorContent, { editor }),
|
|
@@ -6391,14 +6428,14 @@ var FormulaEditor = ({
|
|
|
6391
6428
|
spinnerClassName: "size-6 text-sus-blue-3"
|
|
6392
6429
|
}
|
|
6393
6430
|
),
|
|
6394
|
-
/* @__PURE__ */ jsx(
|
|
6431
|
+
!isEditorReadOnly && /* @__PURE__ */ jsx(
|
|
6395
6432
|
Button,
|
|
6396
6433
|
{
|
|
6397
6434
|
type: "button",
|
|
6398
6435
|
variant: "ghost",
|
|
6399
6436
|
size: "icon",
|
|
6400
6437
|
className: "absolute bottom-2 right-4 h-6 w-6 rounded-full bg-white shadow",
|
|
6401
|
-
disabled:
|
|
6438
|
+
disabled: isEditorDisabled,
|
|
6402
6439
|
onClick: () => setIsExpanded((prev) => !prev),
|
|
6403
6440
|
children: isExpanded ? /* @__PURE__ */ jsx(Minimize2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Maximize2, { className: "h-4 w-4" })
|
|
6404
6441
|
}
|
|
@@ -6407,13 +6444,13 @@ var FormulaEditor = ({
|
|
|
6407
6444
|
}
|
|
6408
6445
|
),
|
|
6409
6446
|
hasError && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", role: "alert", children: displayError }),
|
|
6410
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-end gap-2 py-2", children: operators.map((operator) => /* @__PURE__ */ jsx(
|
|
6447
|
+
mode === "edit" && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-end gap-2 py-2", children: operators.map((operator) => /* @__PURE__ */ jsx(
|
|
6411
6448
|
Button,
|
|
6412
6449
|
{
|
|
6413
6450
|
type: "button",
|
|
6414
6451
|
onClick: () => insertOperator(operator.value),
|
|
6415
6452
|
className: "min-w-10 rounded-sm px-3 bg-sus-blue-3",
|
|
6416
|
-
disabled:
|
|
6453
|
+
disabled: isEditorDisabled,
|
|
6417
6454
|
children: operator.label
|
|
6418
6455
|
},
|
|
6419
6456
|
operator.value
|