@bmsuisse/ui 0.16.1 → 0.16.2

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.ts CHANGED
@@ -55,7 +55,7 @@ declare const DialogContent: react.ForwardRefExoticComponent<Omit<DialogPrimitiv
55
55
  declare const DialogHeader: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
56
56
  declare const DialogTitle: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & react.RefAttributes<HTMLHeadingElement>, "ref"> & react.RefAttributes<HTMLHeadingElement>>;
57
57
  declare const DialogDescription: react.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & react.RefAttributes<HTMLParagraphElement>, "ref"> & react.RefAttributes<HTMLParagraphElement>>;
58
- declare const DialogBody: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
58
+ declare const DialogBody: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
59
59
  declare const DialogFooter: ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => ReactElement;
60
60
 
61
61
  declare const Popover: react.FC<PopoverPrimitive.PopoverProps>;
package/dist/index.js CHANGED
@@ -168,7 +168,7 @@ var Badge = ({ className, variant, ...props }) => /* @__PURE__ */ jsx6("div", {
168
168
  // src/primitives/dialog.tsx
169
169
  import * as DialogPrimitive from "@radix-ui/react-dialog";
170
170
  import { X } from "lucide-react";
171
- import { forwardRef as forwardRef5 } from "react";
171
+ import { forwardRef as forwardRef5, useCallback, useLayoutEffect, useRef } from "react";
172
172
  import { jsx as jsx7, jsxs } from "react/jsx-runtime";
173
173
  var Dialog = DialogPrimitive.Root;
174
174
  var DialogTrigger = DialogPrimitive.Trigger;
@@ -188,7 +188,7 @@ var DialogContent = forwardRef5(({ className, children, showCloseButton = true,
188
188
  {
189
189
  ref,
190
190
  className: cn(
191
- "fixed left-1/2 top-1/2 z-50 flex max-h-[85vh] w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border bg-background shadow-lg",
191
+ "fixed left-1/2 top-1/2 z-50 flex max-h-[85vh] [--dialog-divider:color-mix(in_oklab,var(--color-foreground)_12%,transparent)] dark:[--dialog-divider:var(--color-border)] w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border bg-background shadow-lg",
192
192
  className
193
193
  ),
194
194
  ...props,
@@ -213,7 +213,17 @@ DialogContent.displayName = "DialogContent";
213
213
  var DialogHeader = ({
214
214
  className,
215
215
  ...props
216
- }) => /* @__PURE__ */ jsx7("div", { className: cn("flex shrink-0 flex-col gap-1.5 px-6 pt-6", className), ...props });
216
+ }) => /* @__PURE__ */ jsx7(
217
+ "div",
218
+ {
219
+ "data-slot": "dialog-header",
220
+ className: cn(
221
+ "flex shrink-0 flex-col gap-1.5 bg-background px-6 pb-3 pt-6 transition-shadow [&:has(+[data-overflow-top])]:shadow-[inset_0_-1px_0_var(--dialog-divider)]",
222
+ className
223
+ ),
224
+ ...props
225
+ }
226
+ );
217
227
  var DialogTitle = forwardRef5(({ className, ...props }, ref) => /* @__PURE__ */ jsx7(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
218
228
  DialogTitle.displayName = "DialogTitle";
219
229
  var DialogDescription = forwardRef5(({ className, ...props }, ref) => /* @__PURE__ */ jsx7(
@@ -225,17 +235,77 @@ var DialogDescription = forwardRef5(({ className, ...props }, ref) => /* @__PURE
225
235
  }
226
236
  ));
227
237
  DialogDescription.displayName = "DialogDescription";
228
- var DialogBody = ({
229
- className,
230
- ...props
231
- }) => /* @__PURE__ */ jsx7("div", { className: cn("min-h-0 flex-1 overflow-y-auto px-6 pb-6", className), ...props });
238
+ function useScrollEdges(ref) {
239
+ useLayoutEffect(() => {
240
+ const el = ref.current;
241
+ if (!el) return void 0;
242
+ const update = () => {
243
+ el.toggleAttribute("data-overflow-top", el.scrollTop > 0.5);
244
+ el.toggleAttribute(
245
+ "data-overflow-bottom",
246
+ el.scrollTop + el.clientHeight < el.scrollHeight - 0.5
247
+ );
248
+ };
249
+ update();
250
+ el.addEventListener("scroll", update, { passive: true });
251
+ const resizeObserver = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(update);
252
+ const observeChildren = () => {
253
+ if (!resizeObserver) return;
254
+ resizeObserver.disconnect();
255
+ resizeObserver.observe(el);
256
+ for (const child of Array.from(el.children)) resizeObserver.observe(child);
257
+ };
258
+ observeChildren();
259
+ const mutationObserver = typeof MutationObserver === "undefined" ? void 0 : new MutationObserver(() => {
260
+ observeChildren();
261
+ update();
262
+ });
263
+ mutationObserver?.observe(el, { childList: true });
264
+ return () => {
265
+ el.removeEventListener("scroll", update);
266
+ resizeObserver?.disconnect();
267
+ mutationObserver?.disconnect();
268
+ };
269
+ }, [ref]);
270
+ }
271
+ var DialogBody = forwardRef5(
272
+ ({ className, ...props }, forwardedRef) => {
273
+ const ref = useRef(null);
274
+ useScrollEdges(ref);
275
+ const setRefs = useCallback(
276
+ (node) => {
277
+ ref.current = node;
278
+ if (typeof forwardedRef === "function") forwardedRef(node);
279
+ else if (forwardedRef) forwardedRef.current = node;
280
+ },
281
+ [forwardedRef]
282
+ );
283
+ return /* @__PURE__ */ jsx7(
284
+ "div",
285
+ {
286
+ ref: setRefs,
287
+ "data-slot": "dialog-body",
288
+ className: cn(
289
+ "min-h-0 flex-1 overflow-y-auto px-6 pb-6 pt-1 empty:pb-3 empty:pt-0 [&:empty:has(+[data-slot=dialog-footer])]:hidden [&:has(+[data-slot=dialog-footer])]:pb-1",
290
+ className
291
+ ),
292
+ ...props
293
+ }
294
+ );
295
+ }
296
+ );
297
+ DialogBody.displayName = "DialogBody";
232
298
  var DialogFooter = ({
233
299
  className,
234
300
  ...props
235
301
  }) => /* @__PURE__ */ jsx7(
236
302
  "div",
237
303
  {
238
- className: cn("-mt-6 flex shrink-0 justify-end gap-2 px-6 pb-6 pt-4", className),
304
+ "data-slot": "dialog-footer",
305
+ className: cn(
306
+ "flex shrink-0 justify-end gap-2 bg-background px-6 pb-6 pt-3 transition-shadow [[data-overflow-bottom]+&]:shadow-[inset_0_1px_0_var(--dialog-divider)] [[data-slot=dialog-body]:empty+&]:pt-1 [[data-slot=dialog-header]+&]:pt-1",
307
+ className
308
+ ),
239
309
  ...props
240
310
  }
241
311
  );
@@ -644,7 +714,7 @@ DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
644
714
  import { cva as cva3 } from "class-variance-authority";
645
715
  import * as DialogPrimitive2 from "@radix-ui/react-dialog";
646
716
  import { X as X2 } from "lucide-react";
647
- import { forwardRef as forwardRef15, useEffect, useRef, useState } from "react";
717
+ import { forwardRef as forwardRef15, useEffect, useRef as useRef2, useState } from "react";
648
718
  import { jsx as jsx18, jsxs as jsxs5 } from "react/jsx-runtime";
649
719
  var Sheet = DialogPrimitive2.Root;
650
720
  var SheetTrigger = DialogPrimitive2.Trigger;
@@ -695,7 +765,7 @@ var SheetContent = forwardRef15(
695
765
  }, []);
696
766
  const [dragHeight, setDragHeight] = useState(null);
697
767
  const [isDragging, setIsDragging] = useState(false);
698
- const dragStart = useRef(null);
768
+ const dragStart = useRef2(null);
699
769
  const canResize = resizable && side === "bottom";
700
770
  const onHandlePointerDown = (e) => {
701
771
  const popup = e.currentTarget.closest('[data-slot="sheet-content"]');
@@ -966,7 +1036,7 @@ var FormModal = ({
966
1036
  };
967
1037
 
968
1038
  // src/patterns/modal/ResponsivePanel.tsx
969
- import { useRef as useRef2, useState as useState6 } from "react";
1039
+ import { useRef as useRef3, useState as useState6 } from "react";
970
1040
 
971
1041
  // src/lib/useMediaQuery.ts
972
1042
  import { useEffect as useEffect2, useState as useState5 } from "react";
@@ -1022,8 +1092,8 @@ var cornerGripPosition = {
1022
1092
  function useDesktopPanelGeometry() {
1023
1093
  const [style, setStyle] = useState6(void 0);
1024
1094
  const [isDragging, setIsDragging] = useState6(false);
1025
- const drag = useRef2(null);
1026
- const lastRect = useRef2(null);
1095
+ const drag = useRef3(null);
1096
+ const lastRect = useRef3(null);
1027
1097
  const beginDrag = (mode, corner) => (e) => {
1028
1098
  const content = e.currentTarget.closest('[data-slot="dialog-content"]');
1029
1099
  if (!(content instanceof HTMLElement)) return;
@@ -1287,7 +1357,7 @@ function FormField({
1287
1357
 
1288
1358
  // src/patterns/combobox/Combobox.tsx
1289
1359
  import { Check as Check4, ChevronsUpDown, X as X3 } from "lucide-react";
1290
- import { useEffect as useEffect3, useMemo, useRef as useRef3, useState as useState8 } from "react";
1360
+ import { useEffect as useEffect3, useMemo, useRef as useRef4, useState as useState8 } from "react";
1291
1361
 
1292
1362
  // src/lib/optionGrouping.ts
1293
1363
  function groupMembers(options, group) {
@@ -1428,7 +1498,7 @@ function Combobox(props) {
1428
1498
  const [open, setOpen] = useState8(false);
1429
1499
  const [search, setSearch] = useState8("");
1430
1500
  const [activeIndex, setActiveIndex] = useState8(0);
1431
- const inputRef = useRef3(null);
1501
+ const inputRef = useRef4(null);
1432
1502
  const selectedValues = useMemo(
1433
1503
  () => props.multiple ? props.value : props.value ? [props.value] : [],
1434
1504
  [props.multiple, props.value]
@@ -1646,7 +1716,7 @@ function Combobox(props) {
1646
1716
 
1647
1717
  // src/patterns/tag-combobox/TagCombobox.tsx
1648
1718
  import { X as X4 } from "lucide-react";
1649
- import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState9 } from "react";
1719
+ import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef5, useState as useState9 } from "react";
1650
1720
  import { jsx as jsx29, jsxs as jsxs13 } from "react/jsx-runtime";
1651
1721
  function TagCombobox({
1652
1722
  options,
@@ -1669,8 +1739,8 @@ function TagCombobox({
1669
1739
  const [open, setOpen] = useState9(false);
1670
1740
  const [search, setSearch] = useState9("");
1671
1741
  const [activeIndex, setActiveIndex] = useState9(0);
1672
- const inputRef = useRef4(null);
1673
- const fieldRef = useRef4(null);
1742
+ const inputRef = useRef5(null);
1743
+ const fieldRef = useRef5(null);
1674
1744
  const selectedOptions = useMemo2(
1675
1745
  () => value.map((v) => options.find((o) => o.value === v) ?? { value: v, label: v }),
1676
1746
  [options, value]
@@ -2570,9 +2640,9 @@ function NavGroup({
2570
2640
  // src/patterns/sidebar/Sidebar.tsx
2571
2641
  import { PanelLeftClose, PanelLeftOpen } from "lucide-react";
2572
2642
  import {
2573
- useCallback,
2643
+ useCallback as useCallback2,
2574
2644
  useEffect as useEffect5,
2575
- useRef as useRef5,
2645
+ useRef as useRef6,
2576
2646
  useState as useState11
2577
2647
  } from "react";
2578
2648
  import { Fragment as Fragment4, jsx as jsx40, jsxs as jsxs22 } from "react/jsx-runtime";
@@ -2597,7 +2667,7 @@ function Sidebar({
2597
2667
  const [internalWidth, setInternalWidth] = useState11(defaultWidth);
2598
2668
  const currentWidth = width ?? internalWidth;
2599
2669
  const [isDragging, setIsDragging] = useState11(false);
2600
- const setWidth = useCallback(
2670
+ const setWidth = useCallback2(
2601
2671
  (next) => {
2602
2672
  const clamped = Math.min(maxWidth, Math.max(minWidth, next));
2603
2673
  onWidthChange?.(clamped);
@@ -2605,7 +2675,7 @@ function Sidebar({
2605
2675
  },
2606
2676
  [maxWidth, minWidth, onWidthChange, width]
2607
2677
  );
2608
- const dragStartRef = useRef5(null);
2678
+ const dragStartRef = useRef6(null);
2609
2679
  const handlePointerDown = (event) => {
2610
2680
  event.currentTarget.setPointerCapture(event.pointerId);
2611
2681
  dragStartRef.current = { x: event.clientX, width: currentWidth };
@@ -2687,7 +2757,7 @@ function Sidebar({
2687
2757
  ) }) });
2688
2758
  }
2689
2759
  function SidebarNav({ children, className, ...rest }) {
2690
- const ref = useRef5(null);
2760
+ const ref = useRef6(null);
2691
2761
  const [showFade, setShowFade] = useState11(false);
2692
2762
  useEffect5(() => {
2693
2763
  const el = ref.current;
@@ -2799,7 +2869,7 @@ import { Mic, MicOff } from "lucide-react";
2799
2869
  import { forwardRef as forwardRef18 } from "react";
2800
2870
 
2801
2871
  // src/patterns/ai/useSpeechRecognition.ts
2802
- import { useCallback as useCallback2, useEffect as useEffect6, useRef as useRef6, useState as useState13 } from "react";
2872
+ import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef7, useState as useState13 } from "react";
2803
2873
  function getCtor() {
2804
2874
  if (typeof window === "undefined") return void 0;
2805
2875
  const w = window;
@@ -2835,18 +2905,18 @@ function useSpeechRecognition({
2835
2905
  const [listening, setListening] = useState13(false);
2836
2906
  const [interim, setInterim] = useState13("");
2837
2907
  const [error, setError] = useState13(null);
2838
- const recognitionRef = useRef6(null);
2839
- const onResultRef = useRef6(onResult);
2840
- const onErrorRef = useRef6(onError);
2841
- const engineRef = useRef6(engine);
2908
+ const recognitionRef = useRef7(null);
2909
+ const onResultRef = useRef7(onResult);
2910
+ const onErrorRef = useRef7(onError);
2911
+ const engineRef = useRef7(engine);
2842
2912
  onResultRef.current = onResult;
2843
2913
  onErrorRef.current = onError;
2844
2914
  engineRef.current = engine;
2845
2915
  const supported = engine !== void 0 || getCtor() !== void 0;
2846
- const stop = useCallback2(() => {
2916
+ const stop = useCallback3(() => {
2847
2917
  recognitionRef.current?.stop();
2848
2918
  }, []);
2849
- const start = useCallback2(() => {
2919
+ const start = useCallback3(() => {
2850
2920
  if (recognitionRef.current) return;
2851
2921
  const recognition = engineRef.current ? engineRef.current() : browserEngine();
2852
2922
  if (!recognition) return;
@@ -2879,7 +2949,7 @@ function useSpeechRecognition({
2879
2949
  setListening(true);
2880
2950
  recognition.start();
2881
2951
  }, [lang]);
2882
- const toggle = useCallback2(() => {
2952
+ const toggle = useCallback3(() => {
2883
2953
  if (recognitionRef.current) stop();
2884
2954
  else start();
2885
2955
  }, [start, stop]);
@@ -3039,7 +3109,7 @@ function VoiceTranscript({
3039
3109
  }
3040
3110
 
3041
3111
  // src/patterns/stepper/Stepper.tsx
3042
- import { useEffect as useEffect7, useRef as useRef7 } from "react";
3112
+ import { useEffect as useEffect7, useRef as useRef8 } from "react";
3043
3113
  import { Check as Check5, Plus } from "lucide-react";
3044
3114
  import { jsx as jsx45, jsxs as jsxs27 } from "react/jsx-runtime";
3045
3115
  function Stepper({
@@ -3053,7 +3123,7 @@ function Stepper({
3053
3123
  scrollTestId = "stepper-scroll",
3054
3124
  newTestId
3055
3125
  }) {
3056
- const stepRefs = useRef7(/* @__PURE__ */ new Map());
3126
+ const stepRefs = useRef8(/* @__PURE__ */ new Map());
3057
3127
  useEffect7(() => {
3058
3128
  const activeStep = stepRefs.current.get(step);
3059
3129
  activeStep?.scrollIntoView({ block: "nearest", inline: "center" });