@salemcobalt/ui 0.2.0-rc.34 → 0.2.0-rc.35
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.js +114 -43
- package/dist/index.js.map +1 -1
- package/dist/styles.css +27 -10
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -743,6 +743,51 @@ import { useRender as useRender2 } from "@base-ui/react/use-render";
|
|
|
743
743
|
|
|
744
744
|
// src/components/Tooltip/Tooltip.tsx
|
|
745
745
|
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
746
|
+
|
|
747
|
+
// src/utils/useSafeAreaPadding.ts
|
|
748
|
+
import { useSyncExternalStore } from "react";
|
|
749
|
+
var EDGE = 5;
|
|
750
|
+
var NONE = { top: EDGE, right: EDGE, bottom: EDGE, left: EDGE };
|
|
751
|
+
var current = NONE;
|
|
752
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
753
|
+
function measure() {
|
|
754
|
+
const probe = document.createElement("div");
|
|
755
|
+
probe.setAttribute("data-sc-safe-area-probe", "");
|
|
756
|
+
probe.style.cssText = "position:fixed;visibility:hidden;pointer-events:none;padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px)";
|
|
757
|
+
document.body.appendChild(probe);
|
|
758
|
+
const style = getComputedStyle(probe);
|
|
759
|
+
const px = (value) => EDGE + (parseFloat(value) || 0);
|
|
760
|
+
const next = {
|
|
761
|
+
top: px(style.paddingTop),
|
|
762
|
+
right: px(style.paddingRight),
|
|
763
|
+
bottom: px(style.paddingBottom),
|
|
764
|
+
left: px(style.paddingLeft)
|
|
765
|
+
};
|
|
766
|
+
probe.remove();
|
|
767
|
+
if (next.top === current.top && next.right === current.right && next.bottom === current.bottom && next.left === current.left) {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
current = next;
|
|
771
|
+
listeners.forEach((listener) => listener());
|
|
772
|
+
}
|
|
773
|
+
function subscribe(onChange) {
|
|
774
|
+
if (listeners.size === 0) window.addEventListener("resize", measure);
|
|
775
|
+
listeners.add(onChange);
|
|
776
|
+
measure();
|
|
777
|
+
return () => {
|
|
778
|
+
listeners.delete(onChange);
|
|
779
|
+
if (listeners.size === 0) window.removeEventListener("resize", measure);
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
function useSafeAreaPadding() {
|
|
783
|
+
return useSyncExternalStore(
|
|
784
|
+
subscribe,
|
|
785
|
+
() => current,
|
|
786
|
+
() => NONE
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// src/components/Tooltip/Tooltip.tsx
|
|
746
791
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
747
792
|
function TooltipBase({
|
|
748
793
|
content,
|
|
@@ -757,6 +802,7 @@ function TooltipBase({
|
|
|
757
802
|
disabled,
|
|
758
803
|
className
|
|
759
804
|
}) {
|
|
805
|
+
const collisionPadding = useSafeAreaPadding();
|
|
760
806
|
return /* @__PURE__ */ jsxs6(
|
|
761
807
|
BaseTooltip.Root,
|
|
762
808
|
{
|
|
@@ -766,10 +812,20 @@ function TooltipBase({
|
|
|
766
812
|
disabled,
|
|
767
813
|
children: [
|
|
768
814
|
/* @__PURE__ */ jsx7(BaseTooltip.Trigger, { render: children, delay, closeDelay }),
|
|
769
|
-
/* @__PURE__ */ jsx7(BaseTooltip.Portal, { children: /* @__PURE__ */ jsx7(
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
815
|
+
/* @__PURE__ */ jsx7(BaseTooltip.Portal, { children: /* @__PURE__ */ jsx7(
|
|
816
|
+
BaseTooltip.Positioner,
|
|
817
|
+
{
|
|
818
|
+
side,
|
|
819
|
+
align,
|
|
820
|
+
sideOffset: 6,
|
|
821
|
+
collisionPadding,
|
|
822
|
+
className: "sc-tooltip__positioner",
|
|
823
|
+
children: /* @__PURE__ */ jsxs6(BaseTooltip.Popup, { role: "tooltip", className: cx("sc-tooltip", className), children: [
|
|
824
|
+
/* @__PURE__ */ jsx7(BaseTooltip.Arrow, { className: "sc-tooltip__arrow" }),
|
|
825
|
+
content
|
|
826
|
+
] })
|
|
827
|
+
}
|
|
828
|
+
) })
|
|
773
829
|
]
|
|
774
830
|
}
|
|
775
831
|
);
|
|
@@ -866,7 +922,18 @@ function Content2({
|
|
|
866
922
|
children,
|
|
867
923
|
...rest
|
|
868
924
|
}) {
|
|
869
|
-
|
|
925
|
+
const collisionPadding = useSafeAreaPadding();
|
|
926
|
+
return /* @__PURE__ */ jsx9(BaseMenu.Portal, { children: /* @__PURE__ */ jsx9(
|
|
927
|
+
BaseMenu.Positioner,
|
|
928
|
+
{
|
|
929
|
+
side,
|
|
930
|
+
align,
|
|
931
|
+
sideOffset,
|
|
932
|
+
collisionPadding,
|
|
933
|
+
className: "sc-menu__positioner",
|
|
934
|
+
children: /* @__PURE__ */ jsx9(BaseMenu.Popup, { className: cx("sc-menu", className), ...rest, children })
|
|
935
|
+
}
|
|
936
|
+
) });
|
|
870
937
|
}
|
|
871
938
|
function useItemBody({
|
|
872
939
|
icon,
|
|
@@ -1195,12 +1262,13 @@ function Select({
|
|
|
1195
1262
|
const items = options.flatMap((entry) => isGroup(entry) ? entry.options : [entry]);
|
|
1196
1263
|
const [internal, setInternal] = useState(defaultValue ?? null);
|
|
1197
1264
|
const controlled = value !== void 0;
|
|
1198
|
-
const
|
|
1265
|
+
const current2 = controlled ? value : internal;
|
|
1199
1266
|
const setValue = (next) => {
|
|
1200
1267
|
if (!controlled) setInternal(next);
|
|
1201
1268
|
onValueChange?.(next);
|
|
1202
1269
|
};
|
|
1203
|
-
const canClear = clearable &&
|
|
1270
|
+
const canClear = clearable && current2 != null && !disabled && !readOnly;
|
|
1271
|
+
const collisionPadding = useSafeAreaPadding();
|
|
1204
1272
|
const onTriggerKeyDown = (event) => {
|
|
1205
1273
|
if (canClear && (event.key === "Backspace" || event.key === "Delete")) {
|
|
1206
1274
|
event.preventDefault();
|
|
@@ -1224,7 +1292,7 @@ function Select({
|
|
|
1224
1292
|
BaseSelect.Root,
|
|
1225
1293
|
{
|
|
1226
1294
|
items,
|
|
1227
|
-
value:
|
|
1295
|
+
value: current2,
|
|
1228
1296
|
onValueChange: (next) => setValue(next),
|
|
1229
1297
|
disabled,
|
|
1230
1298
|
required,
|
|
@@ -1262,6 +1330,7 @@ function Select({
|
|
|
1262
1330
|
{
|
|
1263
1331
|
className: "sc-select__positioner",
|
|
1264
1332
|
sideOffset: 4,
|
|
1333
|
+
collisionPadding,
|
|
1265
1334
|
alignItemWithTrigger: false,
|
|
1266
1335
|
children: /* @__PURE__ */ jsx13(BaseSelect.Popup, { className: "sc-select__popup", children: /* @__PURE__ */ jsx13(BaseSelect.List, { children: options.map(
|
|
1267
1336
|
(entry, i) => isGroup(entry) ? /* @__PURE__ */ jsxs11(BaseSelect.Group, { className: "sc-select__group", children: [
|
|
@@ -1533,12 +1602,12 @@ function Progress({
|
|
|
1533
1602
|
className,
|
|
1534
1603
|
...rest
|
|
1535
1604
|
}) {
|
|
1536
|
-
const
|
|
1537
|
-
const hasValueText = valueText != null || showValue &&
|
|
1605
|
+
const current2 = value ?? null;
|
|
1606
|
+
const hasValueText = valueText != null || showValue && current2 !== null;
|
|
1538
1607
|
return /* @__PURE__ */ jsxs17(
|
|
1539
1608
|
BaseProgress.Root,
|
|
1540
1609
|
{
|
|
1541
|
-
value:
|
|
1610
|
+
value: current2,
|
|
1542
1611
|
max,
|
|
1543
1612
|
min,
|
|
1544
1613
|
getAriaValueText: (formatted) => typeof valueText === "string" ? valueText : formatted ?? "",
|
|
@@ -2478,9 +2547,9 @@ function fileTypeLabel(file) {
|
|
|
2478
2547
|
}
|
|
2479
2548
|
|
|
2480
2549
|
// src/utils/useMediaQuery.ts
|
|
2481
|
-
import { useCallback as useCallback2, useSyncExternalStore } from "react";
|
|
2550
|
+
import { useCallback as useCallback2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2482
2551
|
function useMediaQuery(query) {
|
|
2483
|
-
const
|
|
2552
|
+
const subscribe2 = useCallback2(
|
|
2484
2553
|
(onChange) => {
|
|
2485
2554
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {
|
|
2486
2555
|
};
|
|
@@ -2490,8 +2559,8 @@ function useMediaQuery(query) {
|
|
|
2490
2559
|
},
|
|
2491
2560
|
[query]
|
|
2492
2561
|
);
|
|
2493
|
-
return
|
|
2494
|
-
|
|
2562
|
+
return useSyncExternalStore2(
|
|
2563
|
+
subscribe2,
|
|
2495
2564
|
() => typeof window.matchMedia === "function" && window.matchMedia(query).matches,
|
|
2496
2565
|
() => false
|
|
2497
2566
|
);
|
|
@@ -2646,7 +2715,7 @@ function FileInput({
|
|
|
2646
2715
|
const messagesId = `${id}messages`;
|
|
2647
2716
|
const controlled = files !== void 0;
|
|
2648
2717
|
const [uncontrolledFiles, setUncontrolledFiles] = useState6(defaultFiles ?? []);
|
|
2649
|
-
const
|
|
2718
|
+
const current2 = controlled ? files : uncontrolledFiles;
|
|
2650
2719
|
const [rejections, setRejections] = useState6([]);
|
|
2651
2720
|
const [inputId, setInputId] = useState6();
|
|
2652
2721
|
const [previewFile, setPreviewFile] = useState6(null);
|
|
@@ -2658,21 +2727,21 @@ function FileInput({
|
|
|
2658
2727
|
const moduleRef = useRef4(null);
|
|
2659
2728
|
const patchRef = useRef4(() => {
|
|
2660
2729
|
});
|
|
2661
|
-
const settledRef = useRef4(
|
|
2730
|
+
const settledRef = useRef4(current2);
|
|
2662
2731
|
const targetRef = useRef4(null);
|
|
2663
2732
|
const acceptList = parseAccept(accept);
|
|
2664
2733
|
const acceptAttr = acceptList.join(",");
|
|
2665
2734
|
const maxBytes = parseSize(maxFileSize);
|
|
2666
2735
|
const messages = [...rejections, ...error != null ? [error] : []];
|
|
2667
2736
|
const isInvalid = invalid || messages.length > 0;
|
|
2668
|
-
const idleText = idleLabel ?? (multiple ? "Drop files here or" :
|
|
2737
|
+
const idleText = idleLabel ?? (multiple ? "Drop files here or" : current2.length > 0 ? "Drop another file to replace it, or" : "Drop a file here or");
|
|
2669
2738
|
const live = {
|
|
2670
2739
|
acceptList,
|
|
2671
2740
|
acceptLabel: acceptLabel ?? describeAccept(acceptList),
|
|
2672
2741
|
maxBytes,
|
|
2673
2742
|
maxFiles: multiple ? maxFiles : 1,
|
|
2674
2743
|
multiple,
|
|
2675
|
-
current,
|
|
2744
|
+
current: current2,
|
|
2676
2745
|
controlled,
|
|
2677
2746
|
onFilesChange,
|
|
2678
2747
|
labelId,
|
|
@@ -2914,15 +2983,15 @@ function FileInput({
|
|
|
2914
2983
|
const items = pond.getFiles();
|
|
2915
2984
|
const idle = items.filter((item) => item.status === mod.FileStatus.IDLE);
|
|
2916
2985
|
const inPond = idle.map((item) => item.file);
|
|
2917
|
-
if (sameFiles(inPond,
|
|
2918
|
-
settledRef.current =
|
|
2986
|
+
if (sameFiles(inPond, current2)) {
|
|
2987
|
+
settledRef.current = current2;
|
|
2919
2988
|
return;
|
|
2920
2989
|
}
|
|
2921
|
-
targetRef.current =
|
|
2922
|
-
for (const item of idle) if (!
|
|
2923
|
-
const toAdd =
|
|
2990
|
+
targetRef.current = current2;
|
|
2991
|
+
for (const item of idle) if (!current2.includes(item.file)) pond.removeFile(item.id);
|
|
2992
|
+
const toAdd = current2.filter((file) => !inPond.includes(file));
|
|
2924
2993
|
if (toAdd.length > 0) void pond.addFiles(toAdd);
|
|
2925
|
-
}, [
|
|
2994
|
+
}, [current2, pondVersion]);
|
|
2926
2995
|
const ready = pondVersion > 0;
|
|
2927
2996
|
return /* @__PURE__ */ jsxs25(
|
|
2928
2997
|
"div",
|
|
@@ -3001,15 +3070,15 @@ function rowWidth(widths, gap) {
|
|
|
3001
3070
|
for (const w of widths) total += w;
|
|
3002
3071
|
return widths.length > 1 ? total + gap * (widths.length - 1) : total;
|
|
3003
3072
|
}
|
|
3004
|
-
function fitCount({ widths, current, available, more, gap }) {
|
|
3073
|
+
function fitCount({ widths, current: current2, available, more, gap }) {
|
|
3005
3074
|
const n = widths.length;
|
|
3006
|
-
const hasCurrent =
|
|
3075
|
+
const hasCurrent = current2 >= 0 && current2 < n;
|
|
3007
3076
|
const others = hasCurrent ? n - 1 : n;
|
|
3008
3077
|
if (rowWidth(widths, gap) <= available + EPSILON) return others;
|
|
3009
|
-
let used = more + (hasCurrent ? widths[
|
|
3078
|
+
let used = more + (hasCurrent ? widths[current2] + gap : 0);
|
|
3010
3079
|
let count = 0;
|
|
3011
3080
|
for (let i = 0; i < n; i++) {
|
|
3012
|
-
if (i ===
|
|
3081
|
+
if (i === current2) continue;
|
|
3013
3082
|
const next = used + widths[i] + gap;
|
|
3014
3083
|
if (next > available + EPSILON) break;
|
|
3015
3084
|
used = next;
|
|
@@ -3017,11 +3086,11 @@ function fitCount({ widths, current, available, more, gap }) {
|
|
|
3017
3086
|
}
|
|
3018
3087
|
return count;
|
|
3019
3088
|
}
|
|
3020
|
-
function inlineFlags(length,
|
|
3089
|
+
function inlineFlags(length, current2, count) {
|
|
3021
3090
|
const flags = [];
|
|
3022
3091
|
let seen = 0;
|
|
3023
3092
|
for (let i = 0; i < length; i++) {
|
|
3024
|
-
if (i ===
|
|
3093
|
+
if (i === current2) flags.push(true);
|
|
3025
3094
|
else flags.push(seen++ < count);
|
|
3026
3095
|
}
|
|
3027
3096
|
return flags;
|
|
@@ -3080,7 +3149,7 @@ function PriorityNav({
|
|
|
3080
3149
|
...rest
|
|
3081
3150
|
}) {
|
|
3082
3151
|
const signature = signatureOf(items);
|
|
3083
|
-
const
|
|
3152
|
+
const current2 = items.findIndex((item) => item.current);
|
|
3084
3153
|
const [fit, setFit] = useState7({ signature: null, current: -1, count: 0, overflowing: false });
|
|
3085
3154
|
const [open, setOpen] = useState7(false);
|
|
3086
3155
|
const panelId = useId5();
|
|
@@ -3089,7 +3158,7 @@ function PriorityNav({
|
|
|
3089
3158
|
const toggleRef = useRef5(null);
|
|
3090
3159
|
const panelRef = useRef5(null);
|
|
3091
3160
|
const measured = useRef5(null);
|
|
3092
|
-
const currentRef = useRef5(
|
|
3161
|
+
const currentRef = useRef5(current2);
|
|
3093
3162
|
const fitRef = useRef5(fit);
|
|
3094
3163
|
const hysteresisRef = useRef5(overflowHysteresis);
|
|
3095
3164
|
const onOverflowRef = useRef5(onOverflowChange);
|
|
@@ -3099,7 +3168,7 @@ function PriorityNav({
|
|
|
3099
3168
|
});
|
|
3100
3169
|
const measuring = fit.signature !== signature;
|
|
3101
3170
|
useLayoutEffect2(() => {
|
|
3102
|
-
currentRef.current =
|
|
3171
|
+
currentRef.current = current2;
|
|
3103
3172
|
fitRef.current = fit;
|
|
3104
3173
|
hysteresisRef.current = overflowHysteresis;
|
|
3105
3174
|
onOverflowRef.current = onOverflowChange;
|
|
@@ -3119,11 +3188,11 @@ function PriorityNav({
|
|
|
3119
3188
|
gap: parseFloat(getComputedStyle(list).columnGap) || 0,
|
|
3120
3189
|
available: list.clientWidth
|
|
3121
3190
|
};
|
|
3122
|
-
} else if (fit.current ===
|
|
3191
|
+
} else if (fit.current === current2) return;
|
|
3123
3192
|
const m = measured.current;
|
|
3124
3193
|
if (!m) return;
|
|
3125
|
-
setFit({ signature, current, ...solve(m,
|
|
3126
|
-
}, [measuring, signature,
|
|
3194
|
+
setFit({ signature, current: current2, ...solve(m, current2, fit.overflowing) });
|
|
3195
|
+
}, [measuring, signature, current2, fit]);
|
|
3127
3196
|
useEffect5(() => {
|
|
3128
3197
|
const list = listRef.current;
|
|
3129
3198
|
const more = moreRef.current;
|
|
@@ -3165,7 +3234,7 @@ function PriorityNav({
|
|
|
3165
3234
|
live = false;
|
|
3166
3235
|
};
|
|
3167
3236
|
}, []);
|
|
3168
|
-
const flags = measuring ? null : inlineFlags(items.length,
|
|
3237
|
+
const flags = measuring ? null : inlineFlags(items.length, current2, fit.count);
|
|
3169
3238
|
const overflow = flags ? items.filter((_, i) => !flags[i]) : [];
|
|
3170
3239
|
const expanded = open && overflow.length > 0;
|
|
3171
3240
|
const overflowBadges = overflow.map(badgeOf).filter((b) => b !== null);
|
|
@@ -3340,6 +3409,7 @@ function Content3({
|
|
|
3340
3409
|
children,
|
|
3341
3410
|
...rest
|
|
3342
3411
|
}) {
|
|
3412
|
+
const collisionPadding = useSafeAreaPadding();
|
|
3343
3413
|
return /* @__PURE__ */ jsx32(BasePopover.Portal, { children: /* @__PURE__ */ jsx32(
|
|
3344
3414
|
BasePopover.Positioner,
|
|
3345
3415
|
{
|
|
@@ -3348,6 +3418,7 @@ function Content3({
|
|
|
3348
3418
|
sideOffset: sideOffset ?? (arrow ? 8 : 4),
|
|
3349
3419
|
anchor,
|
|
3350
3420
|
collisionAvoidance: COLLISION_AVOIDANCE,
|
|
3421
|
+
collisionPadding,
|
|
3351
3422
|
className: "sc-popover__positioner",
|
|
3352
3423
|
children: /* @__PURE__ */ jsxs27(BasePopover.Popup, { className: cx("sc-popover", className), ...rest, children: [
|
|
3353
3424
|
arrow ? /* @__PURE__ */ jsx32(BasePopover.Arrow, { className: "sc-popover__arrow" }) : null,
|
|
@@ -3540,15 +3611,15 @@ function Progress2({
|
|
|
3540
3611
|
label ? /* @__PURE__ */ jsx34("div", { className: "sc-flow__progress-label", children: label }) : null,
|
|
3541
3612
|
/* @__PURE__ */ jsx34("ol", { className: "sc-flow__segments", "aria-label": listLabel, children: chapters.map((chapter, i) => {
|
|
3542
3613
|
const from = starts[i];
|
|
3543
|
-
const
|
|
3544
|
-
const done = Math.min(chapter.steps, Math.max(0, step - 1 - from)) + (
|
|
3614
|
+
const current2 = step > from && step <= from + chapter.steps;
|
|
3615
|
+
const done = Math.min(chapter.steps, Math.max(0, step - 1 - from)) + (current2 ? 0.5 : 0);
|
|
3545
3616
|
const percent = chapter.steps > 0 ? Math.min(100, done / chapter.steps * 100) : 0;
|
|
3546
3617
|
return /* @__PURE__ */ jsxs29(
|
|
3547
3618
|
"li",
|
|
3548
3619
|
{
|
|
3549
3620
|
className: "sc-flow__segment",
|
|
3550
3621
|
style: { flexGrow: chapter.steps },
|
|
3551
|
-
"aria-current":
|
|
3622
|
+
"aria-current": current2 ? "step" : void 0,
|
|
3552
3623
|
children: [
|
|
3553
3624
|
/* @__PURE__ */ jsx34("span", { className: "sc-flow__segment-fill", style: { inlineSize: `${percent}%` } }),
|
|
3554
3625
|
/* @__PURE__ */ jsx34("span", { className: "sc-visually-hidden", children: chapter.label })
|
|
@@ -3582,7 +3653,7 @@ function RailGroup({ label, className, children, ...rest }) {
|
|
|
3582
3653
|
] });
|
|
3583
3654
|
}
|
|
3584
3655
|
function RailItem({
|
|
3585
|
-
current = false,
|
|
3656
|
+
current: current2 = false,
|
|
3586
3657
|
done = false,
|
|
3587
3658
|
doneLabel = "done",
|
|
3588
3659
|
adornment,
|
|
@@ -3596,7 +3667,7 @@ function RailItem({
|
|
|
3596
3667
|
{
|
|
3597
3668
|
type,
|
|
3598
3669
|
className: cx("sc-flow__rail-item", className),
|
|
3599
|
-
"aria-current":
|
|
3670
|
+
"aria-current": current2 ? "step" : void 0,
|
|
3600
3671
|
"data-done": done || void 0,
|
|
3601
3672
|
...rest,
|
|
3602
3673
|
children: [
|