@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 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(BaseTooltip.Positioner, { side, align, sideOffset: 6, className: "sc-tooltip__positioner", children: /* @__PURE__ */ jsxs6(BaseTooltip.Popup, { role: "tooltip", className: cx("sc-tooltip", className), children: [
770
- /* @__PURE__ */ jsx7(BaseTooltip.Arrow, { className: "sc-tooltip__arrow" }),
771
- content
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
- return /* @__PURE__ */ jsx9(BaseMenu.Portal, { children: /* @__PURE__ */ jsx9(BaseMenu.Positioner, { side, align, sideOffset, className: "sc-menu__positioner", children: /* @__PURE__ */ jsx9(BaseMenu.Popup, { className: cx("sc-menu", className), ...rest, children }) }) });
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 current = controlled ? value : internal;
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 && current != null && !disabled && !readOnly;
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: current,
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 current = value ?? null;
1537
- const hasValueText = valueText != null || showValue && current !== null;
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: current,
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 subscribe = useCallback2(
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 useSyncExternalStore(
2494
- subscribe,
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 current = controlled ? files : uncontrolledFiles;
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(current);
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" : current.length > 0 ? "Drop another file to replace it, or" : "Drop a file 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, current)) {
2918
- settledRef.current = current;
2986
+ if (sameFiles(inPond, current2)) {
2987
+ settledRef.current = current2;
2919
2988
  return;
2920
2989
  }
2921
- targetRef.current = current;
2922
- for (const item of idle) if (!current.includes(item.file)) pond.removeFile(item.id);
2923
- const toAdd = current.filter((file) => !inPond.includes(file));
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
- }, [current, pondVersion]);
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 = current >= 0 && current < n;
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[current] + gap : 0);
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 === current) continue;
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, current, count) {
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 === current) flags.push(true);
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 current = items.findIndex((item) => item.current);
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(current);
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 = 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 === current) return;
3191
+ } else if (fit.current === current2) return;
3123
3192
  const m = measured.current;
3124
3193
  if (!m) return;
3125
- setFit({ signature, current, ...solve(m, current, fit.overflowing) });
3126
- }, [measuring, signature, current, fit]);
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, current, fit.count);
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 current = step > from && step <= from + chapter.steps;
3544
- const done = Math.min(chapter.steps, Math.max(0, step - 1 - from)) + (current ? 0.5 : 0);
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": current ? "step" : void 0,
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": current ? "step" : void 0,
3670
+ "aria-current": current2 ? "step" : void 0,
3600
3671
  "data-done": done || void 0,
3601
3672
  ...rest,
3602
3673
  children: [