@g4rcez/components 0.2.4 → 0.2.5

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.
@@ -18,7 +18,7 @@ export var spacing = {
18
18
  };
19
19
  export var zIndex = {
20
20
  normal: "1",
21
- navbar: "19",
21
+ navbar: "22",
22
22
  calendar: "2",
23
23
  overlay: "21",
24
24
  tooltip: "20",
@@ -8,7 +8,7 @@ import { AnimatePresence, motion, useMotionValue } from "motion/react";
8
8
  import { Fragment, useId } from "react";
9
9
  import { useMediaQuery } from "../../hooks/use-media-query";
10
10
  import { useRemoveScroll } from "../../hooks/use-remove-scroll";
11
- import { css } from "../../lib/dom";
11
+ import { css, mergeRefs } from "../../lib/dom";
12
12
  const animationDuration = "600ms";
13
13
  const drawerLeft = {
14
14
  exit: { translateX: ["0%", "-30%"], opacity: 0, animationDuration },
@@ -86,7 +86,7 @@ const fetchPosition = (isDesktop, forceType, propsType, propsPosition) => {
86
86
  return forceType ? positions[type] : positions.sheet;
87
87
  };
88
88
  export const Modal = ({ open, title, footer, asChild, trigger, children, layoutId, onChange, className, resizer = true, closable = true, forceType = false, overlayClassName = "", type: _type = "dialog", position: propsPosition, overlayClickClose = false, ariaTitle, ...props }) => {
89
- useRemoveScroll(open);
89
+ const removeScrollRef = useRemoveScroll(open, "overflow-hidden");
90
90
  const headingId = useId();
91
91
  const descriptionId = useId();
92
92
  const isDesktop = useMediaQuery("(min-width: 64rem)");
@@ -103,7 +103,7 @@ export const Modal = ({ open, title, footer, asChild, trigger, children, layoutI
103
103
  const Trigger = trigger;
104
104
  const floatingSize = useMotionValue(undefined);
105
105
  const onClose = () => onChange(false);
106
- return (_jsxs(Fragment, { children: [trigger ? (_jsx(Fragment, { children: asChild ? (_jsx(Slot, { ref: refs.setReference, ...getReferenceProps({ layoutId: layoutId }), children: Trigger })) : (_jsx(motion.button, { ref: refs.setReference, ...getReferenceProps(), layoutId: layoutId, type: "button", children: Trigger })) })) : null, _jsx(FloatingPortal, { children: _jsx(AnimatePresence, { mode: "wait", presenceAffectsLayout: true, children: open ? (_jsx(FloatingOverlay, { lockScroll: false, className: css(`inset-0 isolate z-overlay h-[100dvh] !overflow-clip bg-floating-overlay/70 ${type === "drawer" ? "" : "flex items-start justify-center p-10"}`, overlayClassName), children: _jsx(FloatingFocusManager, { visuallyHiddenDismiss: true, modal: true, closeOnFocusOut: true, context: context, children: _jsxs(motion.div, { ...props, exit: "exit", animate: "enter", initial: "initial", variants: animation, "data-component": "modal", ref: refs.setFloating, "aria-modal": open, layoutId: layoutId, className: css(variants({ position, type }), className), style: type === "drawer" ? { width: floatingSize } : { height: floatingSize }, ...(title
106
+ return (_jsxs(Fragment, { children: [trigger ? (_jsx(Fragment, { children: asChild ? (_jsx(Slot, { ref: refs.setReference, ...getReferenceProps({ layoutId: layoutId }), children: Trigger })) : (_jsx(motion.button, { ref: refs.setReference, ...getReferenceProps(), layoutId: layoutId, type: "button", children: Trigger })) })) : null, _jsx(FloatingPortal, { children: _jsx(AnimatePresence, { mode: "wait", presenceAffectsLayout: true, children: open ? (_jsx(FloatingOverlay, { lockScroll: false, className: css(`inset-0 isolate z-overlay h-[100dvh] !overflow-clip bg-floating-overlay/70 ${type === "drawer" ? "" : "flex items-start justify-center p-10"}`, overlayClassName), children: _jsx(FloatingFocusManager, { visuallyHiddenDismiss: true, modal: true, closeOnFocusOut: true, context: context, children: _jsxs(motion.div, { ...props, exit: "exit", animate: "enter", "aria-modal": open, initial: "initial", layoutId: layoutId, variants: animation, "data-component": "modal", ref: mergeRefs(refs.setFloating, removeScrollRef), className: css(variants({ position, type }), className), style: type === "drawer" ? { width: floatingSize } : { height: floatingSize }, ...(title
107
107
  ? {
108
108
  "aria-labelledby": headingId,
109
109
  "aria-describedby": descriptionId,
@@ -1 +1 @@
1
- {"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../../../src/components/form/autocomplete.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAoF,MAAM,OAAO,CAAC;AAOzG,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;CAAE,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,qBAAqB,EAAE,CAAC;CACpC,CAAC;AAiCF,eAAO,MAAM,YAAY,yGAyWxB,CAAC"}
1
+ {"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../../../src/components/form/autocomplete.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAoF,MAAM,OAAO,CAAC;AAQzG,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;CAAE,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,qBAAqB,EAAE,CAAC;CACpC,CAAC;AAmCF,eAAO,MAAM,YAAY,yGA4VxB,CAAC"}
@@ -8,8 +8,9 @@ import { forwardRef, Fragment, useEffect, useRef, useState } from "react";
8
8
  import { flushSync } from "react-dom";
9
9
  import { Virtuoso } from "react-virtuoso";
10
10
  import { Is } from "sidekicker";
11
+ import { useRemoveScroll } from "../../hooks/use-remove-scroll";
11
12
  import { useTranslations } from "../../hooks/use-translations";
12
- import { css, dispatchInput, initializeInputDataset } from "../../lib/dom";
13
+ import { css, dispatchInput, getRemainingSize, initializeInputDataset, mergeRefs } from "../../lib/dom";
13
14
  import { safeRegex } from "../../lib/fns";
14
15
  import { InputField } from "./input-field";
15
16
  const Frag = (props) => _jsx(Fragment, { children: props.children });
@@ -22,20 +23,20 @@ const transitionStyles = {
22
23
  const fuzzyOptions = { caseSensitive: false, sort: false };
23
24
  const emptyRef = [];
24
25
  const List = forwardRef(function VirtualList(props, ref) {
25
- return (_jsx(motion.ul, { ...props, ref: ref, className: "w-full rounded-lg border-b border-tooltip-border last:border-transparent", children: _jsx(AnimatePresence, { children: props.children }) }));
26
+ return (_jsx(motion.ul, { ...props, ref: ref, className: "w-full overscroll-contain rounded-lg border-b border-tooltip-border last:border-transparent", children: _jsx(AnimatePresence, { children: props.children }) }));
26
27
  });
27
28
  const Item = forwardRef(function VirtualItem({ item, context, ...props }, ref) {
28
29
  return _jsx(motion.li, { ...props, ref: ref, className: "first:rounded-t-lg last:rounded-t-lg" });
29
30
  });
30
31
  const components = { List, Item };
31
- const DEFAULT_SIZE = 320;
32
32
  const MIN_SIZE = 40;
33
33
  export const Autocomplete = forwardRef(({ left, error, right, loading, options, container, rightLabel, interactive, emptyMessage, optionalText, labelClassName, feedback = null, hideLeft = false, required = false, dynamicOption = false, ...props }, externalRef) => {
34
+ const scroller = useRef(null);
34
35
  const fieldset = useRef(null);
35
36
  const virtuoso = useRef(null);
36
37
  const defaults = props.value ?? props.defaultValue ?? "";
37
38
  const translation = useTranslations();
38
- const [h, setH] = useState(() => Math.min(DEFAULT_SIZE, MIN_SIZE * options.length));
39
+ const [h, setH] = useState(() => Math.min(320, MIN_SIZE * options.length));
39
40
  const [open, setOpen] = useState(false);
40
41
  const [shadow, setShadow] = useState("");
41
42
  const [value, setValue] = useState(defaults);
@@ -53,6 +54,7 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
53
54
  ]
54
55
  : options;
55
56
  const list = new Fuzzy(innerOptions, ["value", "label"], fuzzyOptions).search(shadow);
57
+ const removeScrollRef = useRemoveScroll(open, "block-only");
56
58
  const setClosed = () => {
57
59
  setOpen(false);
58
60
  setH(0);
@@ -61,35 +63,10 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
61
63
  const pattern = dynamicOption
62
64
  ? undefined
63
65
  : `^(${options.map((x) => `${safeRegex(x.value)}${x.label ? "|" + safeRegex(x.label) : ""}`).join("|")})$`;
64
- useEffect(() => {
65
- if (props.value) {
66
- const item = options.find((x) => x.value === props.value);
67
- setValue(item?.label ?? props.value);
68
- }
69
- }, [props.value]);
70
- useEffect(() => {
71
- if (!open)
72
- setH(0);
73
- }, [open]);
74
- useEffect(() => {
75
- if (!open)
76
- return;
77
- const ul = refs.floating;
78
- if (ul.current === null)
79
- return;
80
- let size = 0;
81
- const items = Array.from(ul.current.querySelectorAll("li")).slice(0, Math.min(displayList.length, 10));
82
- items.forEach((x) => {
83
- const rect = x.getBoundingClientRect();
84
- size += rect.height;
85
- });
86
- const s = Math.min(size, DEFAULT_SIZE);
87
- setH(s);
88
- }, [shadow, open]);
89
66
  const { x, y, strategy, refs, context } = useFloating({
90
67
  open,
91
68
  transform: true,
92
- strategy: "absolute",
69
+ placement: "bottom-start",
93
70
  onOpenChange: setOpen,
94
71
  whileElementsMounted: autoUpdate,
95
72
  middleware: [
@@ -97,22 +74,14 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
97
74
  size({
98
75
  padding: 10,
99
76
  elementContext: "reference",
100
- apply(a) {
101
- const w = fieldset.current.getBoundingClientRect().width;
102
- const ul = a.elements.floating.querySelector("ul");
77
+ apply(args) {
78
+ const ul = args.elements.floating.querySelector("ul");
103
79
  const fullSize = ul?.getBoundingClientRect().height || 0;
104
- const maxH = Math.min(fullSize < MIN_SIZE ? DEFAULT_SIZE : fullSize, DEFAULT_SIZE);
105
- flushSync(() => setTimeout(() => {
106
- const currentH = ul?.getBoundingClientRect().height ?? 0;
107
- if (currentH < MIN_SIZE)
108
- return void setH(maxH);
109
- return void setH(Math.min(currentH, DEFAULT_SIZE));
110
- }, 50));
111
- Object.assign(a.elements.floating.style, {
112
- width: `${w}px`,
113
- maxWidth: `${w}px`,
114
- maxHeight: `${DEFAULT_SIZE}`,
115
- });
80
+ const DEFAULT_SIZE = getRemainingSize(refs.reference.current, window.innerHeight);
81
+ const maxH = Math.min(fullSize < MIN_SIZE ? DEFAULT_SIZE : fullSize, DEFAULT_SIZE, args.availableHeight);
82
+ const size = displayList.length === 0 ? MIN_SIZE : Math.min(maxH, DEFAULT_SIZE, fullSize);
83
+ const mw = `${fieldset.current.getBoundingClientRect().width}px`;
84
+ Object.assign(args.elements.floating.style, { width: mw, maxWidth: mw, height: size });
116
85
  },
117
86
  }),
118
87
  ],
@@ -132,9 +101,23 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
132
101
  focusItemOnOpen: "auto",
133
102
  openOnArrowKeyDown: true,
134
103
  scrollItemIntoView: true,
135
- // onNavigate: (n) => setIndex((prev) => n ?? prev)
136
104
  }),
137
105
  ]);
106
+ useEffect(() => {
107
+ if (props.value) {
108
+ const item = options.find((x) => x.value === props.value);
109
+ setValue(item?.label ?? props.value);
110
+ }
111
+ }, [props.value]);
112
+ useEffect(() => {
113
+ if (!open)
114
+ return setH(0);
115
+ const inputRef = refs.reference;
116
+ if (inputRef.current === null)
117
+ return;
118
+ const s = getRemainingSize(inputRef.current, window.innerHeight);
119
+ setTimeout(() => setH(Math.min(s, displayList.length * MIN_SIZE)), 100);
120
+ }, [shadow, open, refs.reference]);
138
121
  useEffect(() => {
139
122
  const input = refs.reference.current;
140
123
  if (!input)
@@ -226,15 +209,17 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
226
209
  }
227
210
  }
228
211
  },
229
- }), "data-value": value, "data-error": !!error, "data-name": id, "data-target": id, required: required, value: open ? shadow : label || value, "aria-autocomplete": "list", autoComplete: "off", className: css("input placeholder-input-mask group h-input-height w-full flex-1", "rounded-md bg-transparent px-input-x py-input-y text-foreground", "outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary", "group-error:text-danger group-error:placeholder-input-mask-error", "group-focus-within:border-primary group-hover:border-primary", props.className) }), _jsx("input", { id: id, name: id, type: "hidden", "data-origin": id, ref: externalRef, required: required, defaultValue: props.value || value || undefined }), _jsx(FloatingPortal, { preserveTabOrder: true, children: open ? (_jsx(FloatingFocusManager, { guards: true, returnFocus: false, context: context, initialFocus: -1, visuallyHiddenDismiss: true, children: _jsxs(motion.ul, { ...getFloatingProps({
230
- ref: refs.setFloating,
231
- style: {
232
- ...transitions.styles,
233
- top: y ?? 0,
234
- position: strategy,
235
- left: (x ?? 0) + (value ? 36 : 25),
236
- },
237
- }), initial: false, "data-floating": "true", animate: { height: isEmpty ? "auto" : h }, className: "isolate z-floating m-0 origin-[top_center] list-none overscroll-contain rounded-b-lg rounded-t-lg border border-floating-border bg-floating-background p-0 text-foreground shadow-floating", children: [isEmpty ? (_jsx("li", { role: "option", className: "w-full border-b border-tooltip-border last:border-transparent", children: _jsx("span", { className: "flex w-full justify-between p-2 text-left text-disabled", children: emptyMessage || translation.autocompleteEmpty }) })) : null, _jsx(Virtuoso, { ref: virtuoso, hidden: isEmpty, data: displayList, style: { height: h }, components: components, className: "rounded-lg border-floating-border bg-floating-background p-0 text-foreground", itemContent: (i, option) => {
212
+ }), "data-value": value, "data-error": !!error, "data-name": id, "data-target": id, required: required, value: open ? shadow : label || value, "aria-autocomplete": "list", autoComplete: "off", className: css("input placeholder-input-mask group h-input-height w-full flex-1", "rounded-md bg-transparent px-input-x py-input-y text-foreground", "outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary", "group-error:text-danger group-error:placeholder-input-mask-error", "group-focus-within:border-primary group-hover:border-primary", props.className) }), _jsx("input", { id: id, name: id, type: "hidden", "data-origin": id, ref: externalRef, required: required, defaultValue: props.value || value || undefined }), _jsx(FloatingPortal, { preserveTabOrder: true, children: open ? (_jsx(FloatingFocusManager, { modal: true, guards: true, returnFocus: false, context: context, initialFocus: -1, visuallyHiddenDismiss: true, children: _jsxs(motion.div, { ...getFloatingProps({
213
+ ref: mergeRefs(removeScrollRef, refs.setFloating),
214
+ style: { ...transitions.styles, left: x, top: y ?? 0, position: strategy },
215
+ }), initial: false, "data-floating": "true", animate: { height: isEmpty ? "auto" : h }, className: "isolate z-floating m-0 max-h-80 origin-[top_center] list-none overscroll-contain rounded-b-lg rounded-t-lg border border-floating-border bg-floating-background p-0 text-foreground shadow-floating ease-in-out", onAnimationComplete: () => {
216
+ if (!open)
217
+ return setH(0);
218
+ const ul = refs.floating.current;
219
+ const li = ul.querySelectorAll("li").item(0);
220
+ const sum = (li ? li.getBoundingClientRect().height : MIN_SIZE) * displayList.length;
221
+ return flushSync(() => setH(sum + 2));
222
+ }, children: [isEmpty ? (_jsx("div", { role: "option", className: "w-full border-b border-tooltip-border last:border-transparent", children: _jsx("span", { className: "flex w-full justify-between p-2 text-left text-disabled", children: emptyMessage || translation.autocompleteEmpty }) })) : null, _jsx(Virtuoso, { overscan: 40, ref: virtuoso, hidden: isEmpty, data: displayList, style: { height: h }, defaultItemHeight: MIN_SIZE, components: components, scrollerRef: (e) => void (scroller.current = e), className: "max-h-80 overscroll-contain rounded-lg border-floating-border bg-floating-background p-0 text-foreground", itemContent: (i, option) => {
238
223
  const Label = option.Render ?? Frag;
239
224
  const active = value === option.value || value === option.label;
240
225
  const selected = index === i;
@@ -248,7 +233,7 @@ export const Autocomplete = forwardRef(({ left, error, right, loading, options,
248
233
  "aria-selected": active,
249
234
  "aria-busy": option.disabled,
250
235
  onClick: () => onSelect(option, i),
251
- className: `cursor-pointer w-full p-2 text-left ${active ? "bg-primary-hover text-primary-foreground" : ""} ${selected ? "bg-floating-hover text-floating-foreground" : ""}`,
236
+ className: `cursor-pointer min-h-10 hover:bg-floating-hover w-full p-2 text-left ${active ? "bg-primary-hover text-primary-foreground" : ""} ${selected ? "bg-floating-hover text-floating-foreground" : ""}`,
252
237
  }), children: _jsx(Label, { ...props, label: option.label, value: option.value, children: children }) }));
253
238
  } })] }) })) : null })] }));
254
239
  });
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select.d.ts","sourceRoot":"","sources":["../../../../src/components/form/multi-select.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAOlH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CACnC,eAAe,CAAC,OAAO,CAAC,EACxB;IACI,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACjD,CACJ,CAAC;AA0DF,eAAO,MAAM,WAAW,wGAkYvB,CAAC"}
1
+ {"version":3,"file":"multi-select.d.ts","sourceRoot":"","sources":["../../../../src/components/form/multi-select.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAA6F,MAAM,OAAO,CAAC;AAQlH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAc,eAAe,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CACnC,eAAe,CAAC,OAAO,CAAC,EACxB;IACI,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACjD,CACJ,CAAC;AA4DF,eAAO,MAAM,WAAW,wGAsZvB,CAAC"}
@@ -7,13 +7,15 @@ import { AnimatePresence, motion } from "motion/react";
7
7
  import React, { forwardRef, Fragment, useEffect, useMemo, useRef, useState } from "react";
8
8
  import { flushSync } from "react-dom";
9
9
  import { Virtuoso } from "react-virtuoso";
10
+ import { useRemoveScroll } from "../../hooks/use-remove-scroll";
10
11
  import { useTranslations } from "../../hooks/use-translations";
11
12
  import { Dict } from "../../lib/dict";
12
- import { css, initializeInputDataset } from "../../lib/dom";
13
+ import { css, getRemainingSize, initializeInputDataset } from "../../lib/dom";
13
14
  import { noop } from "../../lib/fns";
14
15
  import { Tag } from "../core/tag";
15
16
  import { Checkbox } from "./checkbox";
16
17
  import { InputField } from "./input-field";
18
+ const MIN_SIZE = 40;
17
19
  const Frag = (props) => _jsx(Fragment, { children: props.children });
18
20
  const transitionStyles = {
19
21
  duration: 300,
@@ -84,20 +86,13 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
84
86
  ]
85
87
  : options;
86
88
  const list = new Fuzzy(innerOptions, ["value", "label"], fuzzyOptions).search(shadow);
87
- useEffect(() => {
88
- if (!open)
89
- setH(0);
90
- }, [open]);
91
- useEffect(() => {
92
- if (props.value) {
93
- setValue(new Dict(props.value.map((x) => [x, map.get(x)])));
94
- }
95
- }, [props.value, map]);
89
+ const removeScrollRef = useRemoveScroll(open, "block-only");
96
90
  const displayList = list.filter((x) => x.hidden !== true);
97
91
  const isEmpty = displayList.length === 0;
98
92
  const { x, y, strategy, refs, context } = useFloating({
99
93
  open,
100
94
  transform: true,
95
+ placement: "bottom-start",
101
96
  strategy: "absolute",
102
97
  onOpenChange: setOpen,
103
98
  whileElementsMounted: autoUpdate,
@@ -106,18 +101,14 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
106
101
  size({
107
102
  padding: 10,
108
103
  elementContext: "reference",
109
- apply(a) {
110
- if (fieldset.current === null)
111
- return;
112
- const w = fieldset.current.getBoundingClientRect().width;
113
- const maxH = 360;
114
- flushSync(() => setTimeout(() => setH(maxH), 200));
115
- Object.assign(a.elements.floating.style, {
116
- width: `${w}px`,
117
- maxWidth: `${w}px`,
118
- maxHeight: isEmpty ? "auto" : `${maxH}px`,
119
- height: isEmpty ? "auto" : `${maxH}px`,
120
- });
104
+ apply(args) {
105
+ const ul = args.elements.floating.querySelector("ul");
106
+ const fullSize = ul?.getBoundingClientRect().height || 0;
107
+ const DEFAULT_SIZE = getRemainingSize(refs.reference.current, window.innerHeight);
108
+ const maxH = Math.min(fullSize < MIN_SIZE ? DEFAULT_SIZE : fullSize, DEFAULT_SIZE, args.availableHeight);
109
+ const size = displayList.length === 0 ? MIN_SIZE : Math.min(maxH, DEFAULT_SIZE, fullSize);
110
+ const mw = `${fieldset.current.getBoundingClientRect().width}px`;
111
+ Object.assign(args.elements.floating.style, { width: mw, maxWidth: mw, height: size });
121
112
  },
122
113
  }),
123
114
  ],
@@ -140,6 +131,20 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
140
131
  onNavigate: (n) => setIndex((prev) => n ?? prev),
141
132
  }),
142
133
  ]);
134
+ useEffect(() => {
135
+ if (!open)
136
+ return setH(0);
137
+ const inputRef = refs.reference;
138
+ if (inputRef.current === null)
139
+ return;
140
+ const s = getRemainingSize(inputRef.current, window.innerHeight);
141
+ setTimeout(() => setH(Math.min(s, displayList.length * 40)), 100);
142
+ }, [shadow, open, refs.reference]);
143
+ useEffect(() => {
144
+ if (props.value) {
145
+ setValue(new Dict(props.value.map((x) => [x, map.get(x)])));
146
+ }
147
+ }, [props.value, map]);
143
148
  useEffect(() => {
144
149
  const input = refs.reference.current;
145
150
  if (!input)
@@ -190,24 +195,22 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
190
195
  };
191
196
  const id = props.id || props.name;
192
197
  const tags = value.map((x, i) => (_jsx(Tag, { size: "small", icon: _jsx("button", { type: "button", className: "text-current hover:text-danger focus:text-danger", onClick: (e) => {
198
+ e.preventDefault();
193
199
  e.stopPropagation();
194
200
  onSelect(x, i);
201
+ setOpen(false);
195
202
  }, children: _jsx(XIcon, { size: 14 }) }), children: x.label ?? x.value }, `MultiSelect-${x.value}-x`)));
196
- return (_jsxs(InputField, { ...props, left: left, error: error, ref: fieldset, form: props.form, name: props.name, feedback: feedback, hideLeft: hideLeft, required: required, title: props.title, container: container, rightLabel: rightLabel, interactive: interactive, id: props.name || props.id, optionalText: optionalText, componentName: "autocomplete", labelClassName: labelClassName, placeholder: props.placeholder, right: _jsxs("span", { className: "flex items-center gap-0.5", children: [right, _jsxs("button", { type: "button", className: "transition-colors link:text-primary", onClick: onCaretDownClick, children: [_jsx(ChevronDown, { size: 20 }), _jsx("span", { className: "sr-only", children: translation.inputCaretDown })] }), value ? (_jsx("button", { type: "button", onClick: onClose, className: "transition-colors link:text-danger", children: _jsx("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z", fill: "currentColor", fillRule: "evenodd", clipRule: "evenodd" }) }) })) : null] }), children: [_jsx("button", { ...getReferenceProps({
203
+ const scrollableContainerStyle = { height: isEmpty ? "0" : value.size === 0 ? h - 49 : h - 86 };
204
+ return (_jsxs(InputField, { ...props, left: left, error: error, ref: fieldset, form: props.form, name: props.name, feedback: feedback, hideLeft: hideLeft, required: required, title: props.title, container: container, rightLabel: rightLabel, interactive: interactive, id: props.name || props.id, optionalText: optionalText, componentName: "autocomplete", labelClassName: labelClassName, placeholder: props.placeholder, right: _jsxs("span", { className: "flex items-center gap-0.5", children: [right, _jsxs("button", { type: "button", className: "transition-colors link:text-primary", onClick: onCaretDownClick, children: [_jsx(ChevronDown, { size: 20 }), _jsx("span", { className: "sr-only", children: translation.inputCaretDown })] }), value ? (_jsx("button", { type: "button", onClick: onClose, className: "transition-colors link:text-danger", children: _jsx("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z", fill: "currentColor", fillRule: "evenodd", clipRule: "evenodd" }) }) })) : null] }), children: [_jsx("li", { ...getReferenceProps({
197
205
  ...props,
198
206
  onFocus,
199
207
  id: `${id}-shadow`,
200
208
  name: `${id}-shadow`,
201
209
  ref: refs.setReference,
202
- }), type: "button", "data-name": id, "data-target": id, "data-shadow": "true", "data-error": !!error, "aria-autocomplete": "list", "data-value": deriveValue.join(","), value: open ? shadow : label || value, className: css("input placeholder-input-mask group h-input-height w-full", "rounded-md bg-transparent px-input-x py-input-y text-foreground", "outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary", "group-error:text-danger group-error:placeholder-input-mask-error", "group-focus-within:border-primary group-hover:border-primary", "flex flex-row items-center gap-2 whitespace-nowrap text-left", "max-w-full overflow-x-auto truncate overflow-ellipsis", props.className), children: _jsx(OverflowControl, { label: selectedLabel, children: tags }) }), _jsx("input", { id: id, name: id, type: "hidden", "data-origin": id, ref: externalRef, required: required, defaultValue: props.value || deriveValue || undefined }), _jsx(FloatingPortal, { preserveTabOrder: true, children: open ? (_jsx(FloatingFocusManager, { modal: true, guards: true, returnFocus: false, context: context, initialFocus: -1, visuallyHiddenDismiss: true, children: _jsxs("div", { ...getFloatingProps({
210
+ }), tabIndex: 0, role: "button", "data-name": id, "data-target": id, "data-shadow": "true", "data-error": !!error, "aria-autocomplete": "list", "data-value": deriveValue.join(","), value: open ? shadow : label || value, className: css("input placeholder-input-mask group h-input-height w-full", "rounded-md bg-transparent px-input-x py-input-y text-foreground", "outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary", "group-error:text-danger group-error:placeholder-input-mask-error", "group-focus-within:border-primary group-hover:border-primary", "flex flex-row items-center gap-2 whitespace-nowrap text-left", "max-w-full overflow-x-auto truncate overflow-ellipsis", props.className), children: _jsx(OverflowControl, { label: selectedLabel, children: tags }) }), _jsx("input", { id: id, name: id, type: "hidden", "data-origin": id, ref: externalRef, required: required, defaultValue: props.value || deriveValue || undefined }), _jsx(FloatingPortal, { preserveTabOrder: true, children: open ? (_jsx(FloatingFocusManager, { modal: true, guards: true, returnFocus: false, context: context, initialFocus: -1, visuallyHiddenDismiss: true, children: _jsxs("div", { ...getFloatingProps({
203
211
  ref: refs.setFloating,
204
- style: {
205
- ...transitions.styles,
206
- top: y ?? 0,
207
- position: strategy,
208
- left: (x ?? 0) + (value ? 26 : 18),
209
- },
210
- }), "data-floating": "true", className: "isolate z-floating m-0 w-full origin-[top_center] list-none overscroll-contain rounded-b-lg rounded-t-lg border border-floating-border bg-floating-background p-0 text-foreground shadow-floating", children: [_jsx("input", { autoFocus: true, value: shadow, onChange: onChange, title: props.title, placeholder: translation.multiSelectInnerPlaceholder, onKeyDown: (event) => {
212
+ style: { ...transitions.styles, top: y ?? 0, position: strategy, left: x },
213
+ }), "data-floating": "true", className: "isolate z-floating m-0 max-h-80 w-full origin-[top_center] list-none overscroll-contain rounded-b-lg rounded-t-lg border border-floating-border bg-floating-background p-0 text-foreground shadow-floating", children: [_jsx("input", { autoFocus: true, value: shadow, onChange: onChange, title: props.title, placeholder: translation.multiSelectInnerPlaceholder, onKeyDown: (event) => {
211
214
  if (event.key === "ArrowDown") {
212
215
  let next = index + 1;
213
216
  if (next > displayList.length - 1)
@@ -236,23 +239,30 @@ export const MultiSelect = forwardRef(({ left, error, right, options, container,
236
239
  return onSelect(displayList[0], 0);
237
240
  }
238
241
  }
239
- }, className: "input placeholder-input-mask group mb-1 h-10 w-full flex-1 border-b border-input-border bg-transparent px-input-x py-input-y outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary" }), isEmpty ? (_jsx("li", { role: "option", className: "w-full border-b border-tooltip-border last:border-transparent", children: _jsx("span", { className: "flex w-full justify-between p-2 text-left text-disabled", children: emptyMessage || translation.autocompleteEmpty }) })) : null, isEmpty ? null : (_jsx(Virtuoso, { ref: virtuoso, hidden: isEmpty, data: displayList, components: components, style: { height: isEmpty ? "0" : value.size === 0 ? h - 49 : h - 86 }, className: "border-floating-border bg-floating-background p-0 text-foreground", itemContent: (i, option) => {
240
- const Label = option.Render ?? Frag;
241
- const active = value.has(option.value) || value.has(option.label ?? "");
242
- const selected = index === i;
243
- const children = option.label ?? option.value;
244
- return (_jsxs("button", { "data-value": option.value, ...getItemProps({
245
- ref: (node) => void (listRef.current[i] = node),
246
- role: "option",
247
- type: "button",
248
- "aria-checked": active,
249
- "aria-current": active,
250
- "aria-selected": active,
251
- "aria-busy": option.disabled,
252
- onClick: () => onSelect(option, i),
253
- }), className: `flex w-full max-w-full cursor-pointer items-center justify-start p-2 text-left hover:bg-floating-hover focus:bg-floating-hover ${active || selected ? "bg-floating-hover text-floating-foreground" : ""}`, children: [_jsx(Checkbox, { onChange: noop, checked: active, "aria-checked": active, onClick: (e) => {
254
- e.stopPropagation();
255
- onSelect(option, i);
256
- } }), _jsx(Label, { ...props, label: option.label, value: option.value, children: children })] }));
257
- } })), value.size === 0 ? null : (_jsx("div", { className: "sticky bottom-0 flex w-full flex-nowrap items-center gap-2 overflow-x-auto rounded-b-lg bg-floating-background p-2", children: tags }))] }) })) : null })] }));
242
+ }, className: "input placeholder-input-mask group mb-1 h-10 w-full flex-1 border-b border-input-border bg-transparent px-input-x py-input-y outline-none transition-colors focus:ring-2 focus:ring-inset focus:ring-primary" }), isEmpty ? (_jsx("li", { role: "option", className: "w-full border-b border-tooltip-border last:border-transparent", children: _jsx("span", { className: "flex w-full justify-between p-2 text-left text-disabled", children: emptyMessage || translation.autocompleteEmpty }) })) : null, isEmpty ? null : (_jsx(motion.div, { initial: false, "data-floating": "true", ref: removeScrollRef, animate: { height: isEmpty ? "auto" : h }, style: scrollableContainerStyle, className: "max-h-80 w-full overscroll-contain", onAnimationComplete: () => {
243
+ if (!open)
244
+ return setH(0);
245
+ const ul = refs.floating.current;
246
+ const li = ul.querySelectorAll("li").item(0);
247
+ const sum = (li ? li.getBoundingClientRect().height : 40) * displayList.length;
248
+ return flushSync(() => setH(sum + 2));
249
+ }, children: _jsx(Virtuoso, { ref: virtuoso, hidden: isEmpty, data: displayList, components: components, style: scrollableContainerStyle, className: "max-h-80 border-floating-border bg-floating-background p-0 text-foreground", itemContent: (i, option) => {
250
+ const Label = option.Render ?? Frag;
251
+ const active = value.has(option.value) || value.has(option.label ?? "");
252
+ const selected = index === i;
253
+ const children = option.label ?? option.value;
254
+ return (_jsxs("button", { "data-value": option.value, ...getItemProps({
255
+ ref: (node) => void (listRef.current[i] = node),
256
+ role: "option",
257
+ type: "button",
258
+ "aria-checked": active,
259
+ "aria-current": active,
260
+ "aria-selected": active,
261
+ "aria-busy": option.disabled,
262
+ onClick: () => onSelect(option, i),
263
+ }), className: `flex w-full max-w-full cursor-pointer items-center justify-start p-2 text-left hover:bg-floating-hover focus:bg-floating-hover ${active || selected ? "bg-floating-hover text-floating-foreground" : ""}`, children: [_jsx(Checkbox, { onChange: noop, checked: active, "aria-checked": active, onClick: (e) => {
264
+ e.stopPropagation();
265
+ onSelect(option, i);
266
+ } }), _jsx(Label, { ...props, label: option.label, value: option.value, children: children })] }));
267
+ } }) })), value.size === 0 ? null : (_jsx("div", { className: "sticky bottom-0 flex w-full flex-nowrap items-center gap-2 overflow-x-auto rounded-b-lg bg-floating-background p-2", children: tags }))] }) })) : null })] }));
258
268
  });
@@ -1,2 +1,4 @@
1
- export declare const useRemoveScroll: (remove: boolean) => void;
1
+ type ScrollRemoveStyle = "overflow-hidden" | "block-only";
2
+ export declare const useRemoveScroll: <T extends HTMLElement>(remove: boolean, removeStyle?: ScrollRemoveStyle) => import("react").RefObject<T | null>;
3
+ export {};
2
4
  //# sourceMappingURL=use-remove-scroll.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-remove-scroll.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-remove-scroll.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe,GAAI,QAAQ,OAAO,SA4B9C,CAAC"}
1
+ {"version":3,"file":"use-remove-scroll.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-remove-scroll.ts"],"names":[],"mappings":"AAMA,KAAK,iBAAiB,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAE1D,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,WAAW,EAAE,QAAQ,OAAO,EAAE,cAAa,iBAAqC,wCAkDzH,CAAC"}
@@ -1,34 +1,58 @@
1
1
  import { useEffect, useRef } from "react";
2
+ import { Is, onlyNumbers } from "sidekicker";
2
3
  import { hasVerticalScroll } from "../lib/dom";
3
4
  import { isMobile, isSsr } from "../lib/fns";
4
5
  import { useIsCoarseDevice } from "./use-is-coarse-device";
5
- export const useRemoveScroll = (remove) => {
6
+ export const useRemoveScroll = (remove, removeStyle = "overflow-hidden") => {
7
+ const ref = useRef(null);
6
8
  const isCoarseDevice = useIsCoarseDevice();
7
9
  const prev = useRef(isSsr() ? "" : document.documentElement.style.overflowY);
8
10
  useEffect(() => {
9
11
  const html = document.documentElement;
10
- if (remove) {
11
- prev.current = document.documentElement.style.overflowY;
12
- html.style.overflowY = "hidden";
13
- if (isCoarseDevice || isMobile())
14
- return;
15
- html.style.padding = hasVerticalScroll(html) ? "0 15px 0 0" : "";
12
+ if (removeStyle === "overflow-hidden") {
13
+ if (remove) {
14
+ prev.current = document.documentElement.style.overflowY;
15
+ html.style.overflowY = "hidden";
16
+ if (isCoarseDevice || isMobile())
17
+ return;
18
+ html.style.padding = hasVerticalScroll(html) ? "0 15px 0 0" : "";
19
+ }
20
+ else {
21
+ html.style.padding = "";
22
+ document.documentElement.style.overflowY = prev.current;
23
+ }
16
24
  }
17
- else {
18
- html.style.padding = "";
19
- document.documentElement.style.overflowY = prev.current;
20
- }
21
- }, [remove, isCoarseDevice]);
25
+ }, [remove, isCoarseDevice, removeStyle]);
22
26
  useEffect(() => {
23
27
  if (!remove)
24
28
  return;
25
29
  const controller = new AbortController();
26
30
  const html = document.documentElement;
27
- const removeScroll = (e) => (e.target === html && remove ? e.preventDefault() : undefined);
31
+ const removeScroll = (e) => {
32
+ const el = ref.current;
33
+ if (el) {
34
+ if (el.contains(e.target)) {
35
+ const rect = el.getBoundingClientRect();
36
+ const realHeight = el.style.height ? Number(onlyNumbers(el.style.height)) : null;
37
+ const scrollable = Is.number(realHeight) ? realHeight : rect.height;
38
+ const hasScroll = el.scrollHeight <= scrollable;
39
+ if (scrollable === el.scrollHeight)
40
+ return remove ? e.preventDefault() : undefined;
41
+ if (hasScroll)
42
+ return;
43
+ return remove ? e.preventDefault() : undefined;
44
+ }
45
+ }
46
+ if (e.currentTarget === document.documentElement) {
47
+ return remove ? e.preventDefault() : undefined;
48
+ }
49
+ return remove ? e.preventDefault() : undefined;
50
+ };
28
51
  html.addEventListener("wheel", removeScroll, { signal: controller.signal, passive: false });
29
52
  html.addEventListener("scroll", removeScroll, { signal: controller.signal, passive: false });
30
53
  return () => {
31
54
  controller.abort();
32
55
  };
33
56
  }, [remove]);
57
+ return ref;
34
58
  };
@@ -10,4 +10,5 @@ export declare const dispatchInput: (input: HTMLInputElement | undefined | null)
10
10
  };
11
11
  export declare const initializeInputDataset: (input: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement) => () => void;
12
12
  export declare const hasVerticalScroll: (htmlElement: HTMLElement) => boolean;
13
+ export declare const getRemainingSize: (element: HTMLElement, windowSize: number) => number;
13
14
  //# sourceMappingURL=dom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/lib/dom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3D,eAAO,MAAM,SAAS,GACjB,CAAC,EAAE,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,KAAG,WAAW,CAAC,CAAC,CAS3E,CAAC;AAEN,eAAO,MAAM,gBAAgB,GAAI,GAAG,GAAG,KAAG,CAAC,IAAI,KAAK,CAAC,YAQpD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,GAAG,GAAG,gCAAmB,CAAC;AAEpD,eAAO,MAAM,GAAG,GAAI,GAAG,QAAQ,UAAU,EAAE,WAA0B,CAAC;AAEtE,eAAO,MAAM,aAAa,GAAI,OAAO,gBAAgB,GAAG,SAAS,GAAG,IAAI;;;CAIvE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,eAIvG,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,aAAa,WAAW,YAAwD,CAAC"}
1
+ {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/lib/dom.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3D,eAAO,MAAM,SAAS,GACjB,CAAC,EAAE,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,KAAG,WAAW,CAAC,CAAC,CAS3E,CAAC;AAEN,eAAO,MAAM,gBAAgB,GAAI,GAAG,GAAG,KAAG,CAAC,IAAI,KAAK,CAAC,YAQpD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,GAAG,GAAG,gCAAmB,CAAC;AAEpD,eAAO,MAAM,GAAG,GAAI,GAAG,QAAQ,UAAU,EAAE,WAA0B,CAAC;AAEtE,eAAO,MAAM,aAAa,GAAI,OAAO,gBAAgB,GAAG,SAAS,GAAG,IAAI;;;CAIvE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,eAIvG,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,aAAa,WAAW,YAAwD,CAAC;AAEnH,eAAO,MAAM,gBAAgB,GAAI,SAAS,WAAW,EAAE,YAAY,MAAM,WAGxE,CAAC"}
@@ -33,3 +33,7 @@ export const initializeInputDataset = (input) => {
33
33
  return () => input.removeEventListener("focus", focus);
34
34
  };
35
35
  export const hasVerticalScroll = (htmlElement) => htmlElement.scrollHeight > htmlElement.clientHeight;
36
+ export const getRemainingSize = (element, windowSize) => {
37
+ const rect = element.getBoundingClientRect();
38
+ return Math.abs(windowSize - rect.bottom);
39
+ };
@@ -18,7 +18,7 @@ export const spacing = {
18
18
  };
19
19
  export const zIndex = {
20
20
  normal: "1",
21
- navbar: "19",
21
+ navbar: "22",
22
22
  calendar: "2",
23
23
  overlay: "21",
24
24
  tooltip: "20",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@g4rcez/components",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "sideEffects": false,
5
5
  "private": false,
6
6
  "packageManager": "pnpm@10.7.0",
@@ -57,7 +57,7 @@
57
57
  "react-remove-scroll-bar": "2.3.8",
58
58
  "react-use-measure": "2.1.7",
59
59
  "react-virtuoso": "4.12.6",
60
- "sidekicker": "0.1.9",
60
+ "sidekicker": "0.1.10",
61
61
  "storage-manager-js": "4.2.6-5",
62
62
  "tailwind-merge": "3.0.2",
63
63
  "the-mask-input": "3.3.13",