@helpwave/hightide 0.8.7 → 0.8.9

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.mjs CHANGED
@@ -10148,7 +10148,7 @@ var useControlledState = ({
10148
10148
  onValueChangeStable(resolved);
10149
10149
  }, [onValueChangeStable, isControlled]);
10150
10150
  const value = isControlled ? controlledValue : internalValue;
10151
- return [value, setState];
10151
+ return [value, setState, isControlled];
10152
10152
  };
10153
10153
 
10154
10154
  // src/components/layout/Expandable.tsx
@@ -11038,65 +11038,67 @@ function sortByDomOrder(infos) {
11038
11038
  return elA.compareDocumentPosition(elB) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
11039
11039
  });
11040
11040
  }
11041
- function getNextEnabledIdInOrder(sortedInfos, currentActiveId) {
11042
- const enabled = sortedInfos.filter((t) => !t.disabled);
11043
- if (enabled.length === 0) return null;
11044
- const currentIndex = sortedInfos.findIndex((t) => t.id === currentActiveId);
11045
- const startIndex = currentIndex >= 0 ? (currentIndex + 1) % sortedInfos.length : 0;
11046
- for (let i = 0; i < sortedInfos.length; i++) {
11047
- const idx = (startIndex + i) % sortedInfos.length;
11048
- if (!sortedInfos[idx].disabled) return sortedInfos[idx].id;
11049
- }
11050
- return null;
11051
- }
11052
11041
  var TabContext = createContext8(null);
11053
11042
  function useTabContext() {
11054
11043
  const context = useContext8(TabContext);
11055
11044
  if (!context) throw new Error("useTabContext must be used inside a <TabView>");
11056
11045
  return context;
11057
11046
  }
11058
- function TabSwitcher({ children }) {
11059
- const [state, setState] = useState15({
11060
- activeId: null,
11061
- infos: []
11047
+ function TabSwitcher({ children, activeId: controlledActiveId, onActiveIdChange, initialActiveId }) {
11048
+ const [activeId, setActiveId] = useControlledState({
11049
+ value: controlledActiveId,
11050
+ defaultValue: initialActiveId ?? null,
11051
+ onValueChange: onActiveIdChange
11062
11052
  });
11053
+ const [tabInfos, setTabInfos] = useState15([]);
11063
11054
  const [portalState, setPortalState] = useState15(null);
11064
11055
  const subscribe = useCallback13((info) => {
11065
11056
  const id = info.id;
11066
- setState((prevState) => {
11067
- const existingIndex = prevState.infos.findIndex((t) => t.id === id);
11068
- const infos = existingIndex >= 0 ? prevState.infos.map((t, i) => i === existingIndex ? { ...t, ...info } : t) : [...prevState.infos, info];
11069
- const ordered = sortByDomOrder(infos);
11070
- const activeIsDisabled = prevState.activeId !== null && infos.some((t) => t.id === prevState.activeId && t.disabled);
11071
- const activeId = activeIsDisabled ? getNextEnabledIdInOrder(ordered, prevState.activeId) : prevState.activeId ?? (info.disabled ? getNextEnabledIdInOrder(ordered, null) : id);
11072
- return { activeId, infos: ordered };
11057
+ setTabInfos((prevState) => {
11058
+ const existingIndex = prevState.findIndex((t) => t.id === id);
11059
+ const infos = existingIndex >= 0 ? prevState.map((t, i) => i === existingIndex ? { ...t, ...info } : t) : [...prevState, info];
11060
+ return sortByDomOrder(infos);
11073
11061
  });
11074
11062
  return () => {
11075
- setState((prevState) => {
11076
- const infos = prevState.infos.filter((t) => t.id !== id);
11077
- const activeTab = prevState.activeId !== null ? infos.find((t) => t.id === prevState.activeId) : null;
11078
- const activeIsUnregisteredOrDisabled = prevState.activeId === id || activeTab?.disabled === true;
11079
- const nextId = prevState.activeId === id ? getNextEnabledIdInOrder(prevState.infos, id) : getNextEnabledIdInOrder(infos, prevState.activeId);
11080
- const activeId = activeIsUnregisteredOrDisabled ? nextId : prevState.activeId;
11081
- return { activeId, infos };
11063
+ setTabInfos((prevState) => {
11064
+ return prevState.filter((t) => t.id !== id);
11082
11065
  });
11083
11066
  };
11084
11067
  }, []);
11085
- const registerPortal = useCallback13((state2) => {
11086
- setPortalState(state2);
11087
- }, []);
11088
- const setActiveId = useCallback13((activeId) => {
11089
- setState((prevState) => ({ ...prevState, activeId }));
11068
+ useEffect16(() => {
11069
+ const active = tabInfos.find((value) => value.id === activeId);
11070
+ if (!active || !active.disabled) return;
11071
+ const firstEnabled = tabInfos.find((value) => !value.disabled);
11072
+ if (firstEnabled) {
11073
+ setActiveId(firstEnabled.id);
11074
+ } else {
11075
+ setActiveId(null);
11076
+ }
11077
+ }, [activeId, setActiveId, tabInfos]);
11078
+ const registerPortal = useCallback13((state) => {
11079
+ setPortalState(state);
11090
11080
  }, []);
11081
+ const changeActiveId = useCallback13((activeId2) => {
11082
+ const info = tabInfos.find((value) => value.id === activeId2);
11083
+ if (info && info.disabled) return;
11084
+ setActiveId(activeId2);
11085
+ }, [setActiveId, tabInfos]);
11086
+ const resolvedActiveId = () => {
11087
+ const active = tabInfos.find((value) => value.id === activeId);
11088
+ if (!!active && !active.disabled) return activeId;
11089
+ const firstEnabled = tabInfos.find((value) => !value.disabled);
11090
+ if (firstEnabled) return firstEnabled.id;
11091
+ return tabInfos[0]?.id ?? null;
11092
+ };
11091
11093
  return /* @__PURE__ */ jsx25(
11092
11094
  TabContext.Provider,
11093
11095
  {
11094
11096
  value: {
11095
11097
  tabs: {
11096
- activeId: state.activeId,
11097
- setActiveId,
11098
+ activeId: resolvedActiveId(),
11099
+ setActiveId: changeActiveId,
11098
11100
  subscribe,
11099
- info: state.infos
11101
+ infos: tabInfos
11100
11102
  },
11101
11103
  portal: {
11102
11104
  id: portalState?.id ?? null,
@@ -11110,20 +11112,20 @@ function TabSwitcher({ children }) {
11110
11112
  }
11111
11113
  function TabList({ ...props }) {
11112
11114
  const { tabs } = useTabContext();
11113
- const { info, activeId, setActiveId: setActive } = tabs;
11115
+ const { infos, activeId, setActiveId: setActive } = tabs;
11114
11116
  const refs = useRef14({});
11115
11117
  const onKeyDown = (e) => {
11116
- const idx = info.findIndex((tab) => tab.id === activeId);
11118
+ const idx = infos.findIndex((tab) => tab.id === activeId);
11117
11119
  if (idx === -1) return;
11118
11120
  const step = e.key === "ArrowRight" ? 1 : e.key === "ArrowLeft" ? -1 : 0;
11119
11121
  if (step === 0) return;
11120
11122
  let nextIdx = idx;
11121
- for (let i = 0; i < info.length; i++) {
11122
- nextIdx = (nextIdx + step + info.length) % info.length;
11123
- if (!info[nextIdx].disabled) break;
11123
+ for (let i = 0; i < infos.length; i++) {
11124
+ nextIdx = (nextIdx + step + infos.length) % infos.length;
11125
+ if (!infos[nextIdx].disabled) break;
11124
11126
  }
11125
- if (info[nextIdx].disabled) return;
11126
- const nextId = info[nextIdx].id;
11127
+ if (infos[nextIdx].disabled) return;
11128
+ const nextId = infos[nextIdx].id;
11127
11129
  setActive(nextId);
11128
11130
  refs.current[nextId]?.focus();
11129
11131
  };
@@ -11135,8 +11137,8 @@ function TabList({ ...props }) {
11135
11137
  onKeyDown,
11136
11138
  role: "tablist",
11137
11139
  "aria-orientation": "horizontal",
11138
- style: { "--tab-count": info.length, ...props.style },
11139
- children: info.map((tabInfo) => {
11140
+ style: { "--tab-count": infos.length, ...props.style },
11141
+ children: infos.map((tabInfo) => {
11140
11142
  const isDisabled = !!tabInfo.disabled;
11141
11143
  const isActive = activeId === tabInfo.id;
11142
11144
  return /* @__PURE__ */ jsx25(
@@ -11153,7 +11155,7 @@ function TabList({ ...props }) {
11153
11155
  role: "tab",
11154
11156
  "aria-selected": isActive,
11155
11157
  "aria-disabled": isDisabled,
11156
- "aria-controls": activeId,
11158
+ "aria-controls": tabInfo.id,
11157
11159
  tabIndex: isActive && !isDisabled ? 0 : -1,
11158
11160
  children: tabInfo.label
11159
11161
  },
@@ -11183,9 +11185,9 @@ function TabView({ ...props }) {
11183
11185
  }
11184
11186
  );
11185
11187
  }
11186
- function TabPanel({ label, forceMount = false, disabled = false, ...props }) {
11188
+ function TabPanel({ label, forceMount = false, disabled = false, initiallyActive = false, ...props }) {
11187
11189
  const { tabs, portal } = useTabContext();
11188
- const { subscribe, activeId } = tabs;
11190
+ const { subscribe, activeId, setActiveId } = tabs;
11189
11191
  const generatedId = useId6();
11190
11192
  const id = props.id ?? "tab-panel-" + generatedId;
11191
11193
  const labelId = "tab-list-button-" + generatedId;
@@ -11193,6 +11195,15 @@ function TabPanel({ label, forceMount = false, disabled = false, ...props }) {
11193
11195
  useEffect16(() => {
11194
11196
  return subscribe({ id, label, labelId, disabled, ref });
11195
11197
  }, [id, label, labelId, disabled, subscribe]);
11198
+ const [hasAnnouncedIntialliyActive, setHasAnnouncedIntialliyActive] = useState15(false);
11199
+ useEffect16(() => {
11200
+ if (!hasAnnouncedIntialliyActive) {
11201
+ if (initiallyActive) {
11202
+ setActiveId(id);
11203
+ }
11204
+ setHasAnnouncedIntialliyActive(true);
11205
+ }
11206
+ }, [hasAnnouncedIntialliyActive, id, initiallyActive, setActiveId]);
11196
11207
  const isActive = activeId === id;
11197
11208
  const content = /* @__PURE__ */ jsx25(
11198
11209
  "div",
@@ -11932,7 +11943,7 @@ var Input = forwardRef11(function Input2({
11932
11943
  const {
11933
11944
  restartTimer,
11934
11945
  clearTimer
11935
- } = useDelay({ delay, disabled: !afterDelay });
11946
+ } = useDelay({ delay, disabled: !afterDelay || props.disabled || props.readOnly });
11936
11947
  const innerRef = useRef19(null);
11937
11948
  useImperativeHandle7(forwardedRef, () => innerRef.current);
11938
11949
  const { focusNext } = useFocusManagement();
@@ -14383,10 +14394,10 @@ var TableSortButton = ({
14383
14394
 
14384
14395
  // src/components/layout/table/TableFilterButton.tsx
14385
14396
  import { FilterIcon } from "lucide-react";
14386
- import { useEffect as useEffect32, useId as useId15, useMemo as useMemo26, useRef as useRef30, useState as useState30 } from "react";
14397
+ import { useEffect as useEffect39, useId as useId15, useMemo as useMemo28, useRef as useRef31, useState as useState34 } from "react";
14387
14398
 
14388
14399
  // src/components/user-interaction/input/DateTimeInput.tsx
14389
- import { forwardRef as forwardRef17, useCallback as useCallback25, useEffect as useEffect31, useId as useId13, useImperativeHandle as useImperativeHandle11, useMemo as useMemo24, useRef as useRef29, useState as useState28 } from "react";
14400
+ import { forwardRef as forwardRef17, useCallback as useCallback26, useEffect as useEffect38, useId as useId13, useImperativeHandle as useImperativeHandle11, useMemo as useMemo26, useRef as useRef30, useState as useState32 } from "react";
14390
14401
  import { CalendarIcon } from "lucide-react";
14391
14402
  import clsx24 from "clsx";
14392
14403
 
@@ -15174,181 +15185,581 @@ var DateTimePickerDialog = ({
15174
15185
  ] });
15175
15186
  };
15176
15187
 
15177
- // src/components/user-interaction/input/DateTimeInput.tsx
15178
- import { Fragment as Fragment7, jsx as jsx66, jsxs as jsxs36 } from "react/jsx-runtime";
15179
- var DateTimeInput = forwardRef17(function DateTimeInput2({
15180
- id: inputId,
15181
- value,
15182
- initialValue = null,
15183
- onValueChange,
15184
- onEditComplete,
15185
- allowRemove = false,
15186
- containerProps,
15187
- mode = "date",
15188
- pickerProps,
15189
- outsideClickCloses = true,
15190
- onDialogOpeningChange,
15191
- disabled = false,
15192
- readOnly = false,
15193
- invalid = false,
15194
- required = false,
15195
- ...props
15196
- }, forwardedRef) {
15197
- const translation = useHightideTranslation();
15198
- const [isOpen, setIsOpen] = useState28(false);
15199
- const [state, setState] = useControlledState({
15200
- value,
15201
- onValueChange,
15202
- defaultValue: initialValue
15203
- });
15204
- const [dialogValue, setDialogValue] = useState28(state ?? /* @__PURE__ */ new Date());
15205
- const [dateString, setDateString] = useState28(state ? DateUtils.toInputString(state, mode) : "");
15206
- useEffect31(() => {
15207
- setDialogValue(state ?? /* @__PURE__ */ new Date());
15208
- setDateString(state ? DateUtils.toInputString(state, mode) : "");
15209
- }, [mode, state]);
15210
- const changeOpenWrapper = useCallback25((isOpen2) => {
15211
- onDialogOpeningChange?.(isOpen2);
15212
- setIsOpen(isOpen2);
15213
- }, [onDialogOpeningChange]);
15214
- const generatedId = useId13();
15215
- const ids = useMemo24(() => ({
15216
- input: inputId ?? `date-time-input-${generatedId}`,
15217
- popup: `date-time-input-popup-${generatedId}`,
15218
- label: `date-time-input-label-${generatedId}`
15219
- }), [generatedId, inputId]);
15220
- const innerRef = useRef29(null);
15221
- useImperativeHandle11(forwardedRef, () => innerRef.current);
15188
+ // src/hooks/focus/useFocusGuards.ts
15189
+ import { useEffect as useEffect31 } from "react";
15190
+ var selectorName = "data-hw-focus-guard";
15191
+ function FocusGuard() {
15192
+ const element = document.createElement("div");
15193
+ element.setAttribute(selectorName, "");
15194
+ element.tabIndex = 0;
15195
+ element.style.border = "none";
15196
+ element.style.outline = "none";
15197
+ element.style.boxShadow = "none";
15198
+ element.style.opacity = "0";
15199
+ element.style.position = "fixed";
15200
+ element.style.pointerEvents = "none";
15201
+ return element;
15202
+ }
15203
+ var FocusGuardsService = class _FocusGuardsService {
15204
+ constructor() {
15205
+ this.count = 0;
15206
+ }
15207
+ static getInstance() {
15208
+ if (!_FocusGuardsService.instance) {
15209
+ _FocusGuardsService.instance = new _FocusGuardsService();
15210
+ }
15211
+ return _FocusGuardsService.instance;
15212
+ }
15213
+ add() {
15214
+ const edgeGuards = document.querySelectorAll(`[${selectorName}]`);
15215
+ document.body.insertAdjacentElement("afterbegin", edgeGuards[0] ?? FocusGuard());
15216
+ document.body.insertAdjacentElement("beforeend", edgeGuards[1] ?? FocusGuard());
15217
+ this.count++;
15218
+ }
15219
+ remove() {
15220
+ if (this.count === 1) {
15221
+ document.querySelectorAll(`[${selectorName}]`).forEach((node) => node.remove());
15222
+ }
15223
+ this.count--;
15224
+ }
15225
+ };
15226
+ var useFocusGuards = () => {
15222
15227
  useEffect31(() => {
15223
- if (readOnly || disabled) {
15224
- changeOpenWrapper(false);
15228
+ FocusGuardsService.getInstance().add();
15229
+ return () => {
15230
+ FocusGuardsService.getInstance().remove();
15231
+ };
15232
+ }, []);
15233
+ };
15234
+
15235
+ // src/hooks/focus/useFocusOnceVisible.ts
15236
+ import React6, { useEffect as useEffect32 } from "react";
15237
+ var useFocusOnceVisible = (ref, disable = false) => {
15238
+ const [hasUsedFocus, setHasUsedFocus] = React6.useState(false);
15239
+ useEffect32(() => {
15240
+ if (disable || hasUsedFocus) {
15241
+ return;
15225
15242
  }
15226
- }, [changeOpenWrapper, readOnly, disabled]);
15227
- return /* @__PURE__ */ jsxs36(Fragment7, { children: [
15228
- /* @__PURE__ */ jsxs36("div", { ...containerProps, className: clsx24("relative w-full", containerProps?.className), children: [
15229
- /* @__PURE__ */ jsx66(
15230
- "input",
15231
- {
15232
- ...props,
15233
- ref: innerRef,
15234
- id: ids.input,
15235
- value: dateString,
15236
- onChange: (event) => {
15237
- const date = event.target.valueAsDate;
15238
- if (date) {
15239
- setState(date);
15240
- } else {
15241
- setDateString(event.target.value);
15242
- }
15243
- },
15244
- type: mode === "date" ? "date" : mode === "time" ? "time" : "datetime-local",
15245
- ...PropsUtil.dataAttributes.interactionStates({ disabled, readOnly, invalid, required }),
15246
- "data-name": props["data-name"] ?? "date-time-input",
15247
- "data-value": PropsUtil.dataAttributes.bool(!!state || !!dateString),
15248
- ...PropsUtil.aria.interactionStates({ disabled, readOnly, invalid, required }, props)
15249
- }
15250
- ),
15251
- /* @__PURE__ */ jsx66(Visibility, { isVisible: !readOnly, children: /* @__PURE__ */ jsx66(
15252
- IconButton,
15253
- {
15254
- tooltip: translation("sDateTimeSelect", { datetimeMode: mode }),
15255
- coloringStyle: "text",
15256
- color: "neutral",
15257
- size: "sm",
15258
- className: "absolute right-1 top-1/2 -translate-y-1/2",
15259
- disabled,
15260
- onClick: () => {
15261
- changeOpenWrapper(true);
15262
- },
15263
- "aria-haspopup": "dialog",
15264
- "aria-expanded": isOpen,
15265
- "aria-controls": isOpen ? ids.popup : void 0,
15266
- children: /* @__PURE__ */ jsx66(CalendarIcon, { className: "size-5" })
15267
- }
15268
- ) })
15269
- ] }),
15270
- /* @__PURE__ */ jsx66(
15271
- PopUp,
15272
- {
15273
- id: ids.popup,
15274
- isOpen,
15275
- anchor: innerRef,
15276
- options: {
15277
- verticalAlignment: "afterEnd",
15278
- horizontalAlignment: "center",
15279
- gap: 4
15280
- },
15281
- outsideClickOptions: { refs: [innerRef], active: outsideClickCloses },
15282
- onClose: () => {
15283
- changeOpenWrapper(false);
15284
- onEditComplete?.(state);
15285
- },
15286
- role: "dialog",
15287
- "aria-labelledby": ids.label,
15288
- className: "flex-col-2 p-2",
15289
- children: /* @__PURE__ */ jsx66(
15290
- DateTimePickerDialog,
15291
- {
15292
- value: dialogValue,
15293
- allowRemove,
15294
- onValueChange: setDialogValue,
15295
- onEditComplete: (value2) => {
15296
- setState(value2);
15297
- onEditComplete?.(value2);
15298
- changeOpenWrapper(false);
15299
- },
15300
- pickerProps,
15301
- mode
15302
- }
15303
- )
15243
+ const observer = new IntersectionObserver(([entry]) => {
15244
+ if (entry.isIntersecting && !hasUsedFocus) {
15245
+ ref.current?.focus();
15246
+ setHasUsedFocus(hasUsedFocus);
15304
15247
  }
15305
- )
15306
- ] });
15307
- });
15308
-
15309
- // src/components/layout/table/TableFilterPopups.tsx
15310
- import { useId as useId14, useMemo as useMemo25, useState as useState29 } from "react";
15248
+ }, {
15249
+ threshold: 0.1
15250
+ });
15251
+ if (ref.current) {
15252
+ observer.observe(ref.current);
15253
+ }
15254
+ return () => observer.disconnect();
15255
+ }, [disable, hasUsedFocus, ref]);
15256
+ };
15311
15257
 
15312
- // src/components/user-interaction/select/MultiSelect.tsx
15313
- import { forwardRef as forwardRef18 } from "react";
15314
- import { jsx as jsx67, jsxs as jsxs37 } from "react/jsx-runtime";
15315
- var MultiSelect = forwardRef18(function MultiSelect2({
15316
- children,
15317
- contentPanelProps,
15318
- buttonProps,
15319
- ...props
15320
- }, ref) {
15321
- return /* @__PURE__ */ jsxs37(MultiSelectRoot, { ...props, children: [
15322
- /* @__PURE__ */ jsx67(MultiSelectButton, { ref, ...buttonProps }),
15323
- /* @__PURE__ */ jsx67(MultiSelectContent, { ...contentPanelProps, children })
15324
- ] });
15325
- });
15258
+ // src/hooks/focus/useIsMounted.ts
15259
+ import { useEffect as useEffect33, useLayoutEffect as useLayoutEffect7, useState as useState28 } from "react";
15260
+ var isClient = typeof window !== "undefined" && typeof document !== "undefined";
15261
+ var useIsomorphicEffect = isClient ? useLayoutEffect7 : useEffect33;
15262
+ var useIsMounted = () => {
15263
+ const [isMounted, setIsMounted] = useState28(false);
15264
+ useIsomorphicEffect(() => {
15265
+ setIsMounted(true);
15266
+ return () => {
15267
+ setIsMounted(false);
15268
+ };
15269
+ }, []);
15270
+ return isMounted;
15271
+ };
15326
15272
 
15327
- // src/components/layout/table/TableFilterPopups.tsx
15328
- import {
15329
- ArrowRight,
15330
- ArrowLeft,
15331
- ChevronRight as ChevronRight4,
15332
- ChevronLeft as ChevronLeft4,
15333
- CheckCircle2,
15334
- XCircle,
15335
- Equal,
15336
- EqualNot,
15337
- TextInitial,
15338
- SearchCheck,
15339
- SearchX,
15340
- CircleDashed,
15341
- CircleDot
15342
- } from "lucide-react";
15273
+ // src/hooks/useHandleRefs.ts
15274
+ import { useEffect as useEffect34, useRef as useRef29 } from "react";
15275
+ function useHandleRefs(handleRef) {
15276
+ const refs = useRef29([]);
15277
+ useEffect34(() => {
15278
+ refs.current = Object.keys(handleRef?.current ?? {}).map(
15279
+ () => ({ current: null })
15280
+ );
15281
+ const values = Object.values(handleRef?.current ?? {});
15282
+ values.forEach((el, i) => {
15283
+ refs.current[i].current = el;
15284
+ });
15285
+ });
15286
+ return refs.current;
15287
+ }
15343
15288
 
15344
- // src/components/user-interaction/Checkbox.tsx
15345
- import { Check as Check2, Minus as Minus2 } from "lucide-react";
15346
- import { useCallback as useCallback26 } from "react";
15347
- import { jsx as jsx68, jsxs as jsxs38 } from "react/jsx-runtime";
15348
- var Checkbox = ({
15349
- value: controlledValue,
15350
- initialValue = false,
15351
- indeterminate,
15289
+ // src/hooks/useLogUnstableDependencies.ts
15290
+ import React7 from "react";
15291
+ function useLogUnstableDependencies(name, value) {
15292
+ const prev = React7.useRef(null);
15293
+ React7.useEffect(() => {
15294
+ if (!prev.current) {
15295
+ prev.current = value;
15296
+ return;
15297
+ }
15298
+ const changes = {};
15299
+ for (const key of Object.keys(value)) {
15300
+ if (prev.current[key] !== value[key]) {
15301
+ changes[key] = {
15302
+ prev: prev.current[key],
15303
+ next: value[key]
15304
+ };
15305
+ }
15306
+ }
15307
+ if (Object.keys(changes).length > 0) {
15308
+ console.info(`[${name}] changed`, changes);
15309
+ }
15310
+ prev.current = value;
15311
+ });
15312
+ }
15313
+
15314
+ // src/hooks/useOverwritableState.ts
15315
+ import { useEffect as useEffect35, useState as useState29 } from "react";
15316
+ var useOverwritableState = (overwriteValue, onChange) => {
15317
+ const [state, setState] = useState29(overwriteValue);
15318
+ useEffect35(() => {
15319
+ setState(overwriteValue);
15320
+ }, [overwriteValue]);
15321
+ const onChangeWrapper = (action) => {
15322
+ const resolved = resolveSetState(action, state);
15323
+ setState(resolved);
15324
+ onChange?.(resolved);
15325
+ };
15326
+ return [state, onChangeWrapper];
15327
+ };
15328
+
15329
+ // src/hooks/useRerender.ts
15330
+ import { useReducer as useReducer2 } from "react";
15331
+ var useRerender = () => {
15332
+ return useReducer2(() => ({}), {})[1];
15333
+ };
15334
+
15335
+ // src/hooks/useSearch.ts
15336
+ import { useCallback as useCallback25, useEffect as useEffect36, useMemo as useMemo24, useState as useState30 } from "react";
15337
+
15338
+ // src/utils/simpleSearch.ts
15339
+ var MultiSubjectSearchWithMapping = (search, objects, mapping) => {
15340
+ return objects.filter((object) => {
15341
+ const mappedSearchKeywords = mapping(object)?.map((value) => value.toLowerCase().trim());
15342
+ if (!mappedSearchKeywords) {
15343
+ return true;
15344
+ }
15345
+ return search.every((searchValue) => !!mappedSearchKeywords.find((value) => !!value && value.includes(searchValue.toLowerCase().trim())));
15346
+ });
15347
+ };
15348
+ var MultiSearchWithMapping = (search, objects, mapping) => {
15349
+ return objects.filter((object) => {
15350
+ const mappedSearchKeywords = mapping(object)?.map((value) => value.toLowerCase().trim());
15351
+ if (!mappedSearchKeywords) {
15352
+ return true;
15353
+ }
15354
+ return !!mappedSearchKeywords.find((value) => value.includes(search.toLowerCase().trim()));
15355
+ });
15356
+ };
15357
+ var SimpleSearchWithMapping = (search, objects, mapping) => {
15358
+ return MultiSearchWithMapping(search, objects, (value) => [mapping(value)]);
15359
+ };
15360
+ var SimpleSearch = (search, objects) => {
15361
+ return SimpleSearchWithMapping(search, objects, (value) => value);
15362
+ };
15363
+
15364
+ // src/hooks/useSearch.ts
15365
+ var useSearch = ({
15366
+ list,
15367
+ initialSearch,
15368
+ searchMapping,
15369
+ additionalSearchTags,
15370
+ isSearchInstant = true,
15371
+ sortingFunction,
15372
+ filter,
15373
+ disabled = false
15374
+ }) => {
15375
+ const [search, setSearch] = useState30(initialSearch ?? "");
15376
+ const [result, setResult] = useState30(list);
15377
+ const searchTags = useMemo24(() => additionalSearchTags ?? [], [additionalSearchTags]);
15378
+ const updateSearch = useCallback25((newSearch) => {
15379
+ const usedSearch = newSearch ?? search;
15380
+ if (newSearch) {
15381
+ setSearch(search);
15382
+ }
15383
+ setResult(MultiSubjectSearchWithMapping([usedSearch, ...searchTags], list, searchMapping));
15384
+ }, [searchTags, list, search, searchMapping]);
15385
+ useEffect36(() => {
15386
+ if (isSearchInstant) {
15387
+ setResult(MultiSubjectSearchWithMapping([search, ...searchTags], list, searchMapping));
15388
+ }
15389
+ }, [searchTags, isSearchInstant, list, search, searchMapping, additionalSearchTags]);
15390
+ const filteredResult = useMemo24(() => {
15391
+ if (!filter) {
15392
+ return result;
15393
+ }
15394
+ return result.filter(filter);
15395
+ }, [result, filter]);
15396
+ const sortedAndFilteredResult = useMemo24(() => {
15397
+ if (!sortingFunction) {
15398
+ return filteredResult;
15399
+ }
15400
+ return filteredResult.sort(sortingFunction);
15401
+ }, [filteredResult, sortingFunction]);
15402
+ const usedResult = useMemo24(() => {
15403
+ if (!disabled) {
15404
+ return sortedAndFilteredResult;
15405
+ }
15406
+ return list;
15407
+ }, [disabled, list, sortedAndFilteredResult]);
15408
+ return {
15409
+ result: usedResult,
15410
+ hasResult: usedResult.length > 0,
15411
+ allItems: list,
15412
+ updateSearch,
15413
+ search,
15414
+ setSearch
15415
+ };
15416
+ };
15417
+
15418
+ // src/hooks/useUpdatingDateString.ts
15419
+ import { useEffect as useEffect37, useState as useState31 } from "react";
15420
+ var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, date }) => {
15421
+ const { locale: contextLocale } = useLocale();
15422
+ const locale = localeOverride ?? contextLocale;
15423
+ const [dateAndTimeStrings, setDateAndTimeStrings] = useState31({
15424
+ compareDate: date,
15425
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
15426
+ relative: DateUtils.formatRelative(date, locale)
15427
+ });
15428
+ useEffect37(() => {
15429
+ setDateAndTimeStrings({
15430
+ compareDate: date,
15431
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
15432
+ relative: DateUtils.formatRelative(date, locale)
15433
+ });
15434
+ }, [date, absoluteFormat, locale]);
15435
+ useEffect37(() => {
15436
+ let timeoutId;
15437
+ const startTimer = () => {
15438
+ const now = /* @__PURE__ */ new Date();
15439
+ const diff = Math.abs((date.getTime() - now.getTime()) / 1e3);
15440
+ let delayInSeconds;
15441
+ if (diff < DateUtils.timesInSeconds.minute) {
15442
+ delayInSeconds = DateUtils.timesInSeconds.second;
15443
+ } else if (diff < DateUtils.timesInSeconds.hour) {
15444
+ delayInSeconds = DateUtils.timesInSeconds.minute;
15445
+ } else {
15446
+ delayInSeconds = DateUtils.timesInSeconds.hour;
15447
+ }
15448
+ timeoutId = setInterval(() => {
15449
+ setDateAndTimeStrings({
15450
+ compareDate: date,
15451
+ absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
15452
+ relative: DateUtils.formatRelative(date, locale)
15453
+ });
15454
+ }, delayInSeconds * 1e3 / 2);
15455
+ };
15456
+ startTimer();
15457
+ return () => clearInterval(timeoutId);
15458
+ }, [absoluteFormat, date, locale]);
15459
+ return {
15460
+ absolute: dateAndTimeStrings.absolute,
15461
+ relative: dateAndTimeStrings.relative
15462
+ };
15463
+ };
15464
+
15465
+ // src/utils/emailValidation.ts
15466
+ var validateEmail = (email) => {
15467
+ return /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(email);
15468
+ };
15469
+
15470
+ // src/hooks/useValidators.ts
15471
+ import { useMemo as useMemo25 } from "react";
15472
+ var notEmpty = (value) => {
15473
+ if (!value) {
15474
+ return "notEmpty";
15475
+ }
15476
+ };
15477
+ var boundsValidator = (length, bounds) => {
15478
+ const [min, max] = bounds;
15479
+ if (min !== void 0 && max !== void 0 && (length === void 0 || length < min || length > max)) {
15480
+ return "range";
15481
+ }
15482
+ if (min !== void 0 && (length === void 0 || length < min)) {
15483
+ return "lower";
15484
+ }
15485
+ if (max !== void 0 && length !== void 0 && length > max) {
15486
+ return "upper";
15487
+ }
15488
+ return "none";
15489
+ };
15490
+ var lengthValidator = (value, bounds) => {
15491
+ const mapping = {
15492
+ range: "outOfRangeString",
15493
+ lower: "tooShort",
15494
+ upper: "tooLong",
15495
+ none: void 0
15496
+ };
15497
+ return mapping[boundsValidator(value?.length, bounds)];
15498
+ };
15499
+ var selectionValidator = (value, bounds) => {
15500
+ const mapping = {
15501
+ range: "outOfRangeSelectionItems",
15502
+ lower: "tooFewSelectionItems",
15503
+ upper: "tooManySelectionItems",
15504
+ none: void 0
15505
+ };
15506
+ return mapping[boundsValidator(value?.length, bounds)];
15507
+ };
15508
+ var emailValidator = (value) => {
15509
+ if (!value || !validateEmail(value)) {
15510
+ return "invalidEmail";
15511
+ }
15512
+ };
15513
+ var UseValidators = {
15514
+ notEmpty,
15515
+ length: lengthValidator,
15516
+ email: emailValidator,
15517
+ selection: selectionValidator
15518
+ };
15519
+ var useTranslatedValidators = () => {
15520
+ const translation = useHightideTranslation();
15521
+ return useMemo25(() => ({
15522
+ notEmpty: (value) => {
15523
+ const result = notEmpty(value);
15524
+ if (result) {
15525
+ return translation(result);
15526
+ }
15527
+ },
15528
+ length: (value, length) => {
15529
+ const [min, max] = length;
15530
+ const result = lengthValidator(value, length);
15531
+ if (result) {
15532
+ return translation(result, { min, max });
15533
+ }
15534
+ },
15535
+ email: (value) => {
15536
+ const result = emailValidator(value ?? "");
15537
+ if (result) {
15538
+ return translation(result);
15539
+ }
15540
+ },
15541
+ selection: (value, length) => {
15542
+ const [min, max] = length;
15543
+ const result = selectionValidator(value, length);
15544
+ if (result) {
15545
+ return translation(
15546
+ result,
15547
+ { min, max }
15548
+ );
15549
+ }
15550
+ }
15551
+ }), [translation]);
15552
+ };
15553
+
15554
+ // src/components/user-interaction/input/DateTimeInput.tsx
15555
+ import { Fragment as Fragment7, jsx as jsx66, jsxs as jsxs36 } from "react/jsx-runtime";
15556
+ var DateTimeInput = forwardRef17(function DateTimeInput2({
15557
+ id: inputId,
15558
+ value,
15559
+ initialValue = null,
15560
+ onValueChange,
15561
+ onEditComplete,
15562
+ allowRemove = false,
15563
+ containerProps,
15564
+ mode = "date",
15565
+ pickerProps,
15566
+ outsideClickCloses = true,
15567
+ onDialogOpeningChange,
15568
+ disabled = false,
15569
+ readOnly = false,
15570
+ invalid = false,
15571
+ required = false,
15572
+ ...props
15573
+ }, forwardedRef) {
15574
+ const translation = useHightideTranslation();
15575
+ const [isOpen, setIsOpen] = useState32(false);
15576
+ const [state, setState] = useControlledState({
15577
+ value,
15578
+ onValueChange,
15579
+ defaultValue: initialValue
15580
+ });
15581
+ const [dialogValue, setDialogValue] = useState32(state ?? /* @__PURE__ */ new Date());
15582
+ const [stringInputState, setStringInputState] = useState32({
15583
+ state: state ? DateUtils.toInputString(state, mode) : "",
15584
+ date: void 0
15585
+ });
15586
+ useEffect38(() => {
15587
+ setDialogValue(state ?? /* @__PURE__ */ new Date());
15588
+ setStringInputState({
15589
+ state: state ? DateUtils.toInputString(state, mode) : "",
15590
+ date: void 0
15591
+ });
15592
+ }, [mode, state]);
15593
+ const changeOpenWrapper = useCallback26((isOpen2) => {
15594
+ onDialogOpeningChange?.(isOpen2);
15595
+ setIsOpen(isOpen2);
15596
+ }, [onDialogOpeningChange]);
15597
+ const generatedId = useId13();
15598
+ const ids = useMemo26(() => ({
15599
+ input: inputId ?? `date-time-input-${generatedId}`,
15600
+ popup: `date-time-input-popup-${generatedId}`,
15601
+ label: `date-time-input-label-${generatedId}`
15602
+ }), [generatedId, inputId]);
15603
+ const innerRef = useRef30(null);
15604
+ useImperativeHandle11(forwardedRef, () => innerRef.current);
15605
+ useEffect38(() => {
15606
+ if (readOnly || disabled) {
15607
+ changeOpenWrapper(false);
15608
+ }
15609
+ }, [changeOpenWrapper, readOnly, disabled]);
15610
+ const {
15611
+ restartTimer,
15612
+ clearTimer
15613
+ } = useDelay({ delay: 2e3, disabled: disabled || readOnly });
15614
+ return /* @__PURE__ */ jsxs36(Fragment7, { children: [
15615
+ /* @__PURE__ */ jsxs36("div", { ...containerProps, className: clsx24("relative w-full", containerProps?.className), children: [
15616
+ /* @__PURE__ */ jsx66(
15617
+ "input",
15618
+ {
15619
+ ...props,
15620
+ ref: innerRef,
15621
+ id: ids.input,
15622
+ value: stringInputState.state,
15623
+ onChange: (event) => {
15624
+ const date = event.target.valueAsDate;
15625
+ if (date) {
15626
+ restartTimer(() => {
15627
+ innerRef.current?.blur();
15628
+ setState(date);
15629
+ onEditComplete?.(date);
15630
+ });
15631
+ } else {
15632
+ clearTimer();
15633
+ }
15634
+ setStringInputState({
15635
+ state: event.target.value,
15636
+ date: event.target.valueAsDate ?? void 0
15637
+ });
15638
+ },
15639
+ onBlur: (event) => {
15640
+ props.onBlur?.(event);
15641
+ clearTimer();
15642
+ if (stringInputState.date) {
15643
+ setState(stringInputState.date);
15644
+ onEditComplete?.(stringInputState.date);
15645
+ } else {
15646
+ if (innerRef.current) {
15647
+ innerRef.current.value = "";
15648
+ }
15649
+ setStringInputState({
15650
+ state: state ? DateUtils.toInputString(state, mode) : "",
15651
+ date: void 0
15652
+ });
15653
+ }
15654
+ },
15655
+ type: mode === "date" ? "date" : mode === "time" ? "time" : "datetime-local",
15656
+ ...PropsUtil.dataAttributes.interactionStates({ disabled, readOnly, invalid, required }),
15657
+ "data-name": props["data-name"] ?? "date-time-input",
15658
+ "data-value": PropsUtil.dataAttributes.bool(!!state || !!stringInputState),
15659
+ ...PropsUtil.aria.interactionStates({ disabled, readOnly, invalid, required }, props)
15660
+ }
15661
+ ),
15662
+ /* @__PURE__ */ jsx66(Visibility, { isVisible: !readOnly, children: /* @__PURE__ */ jsx66(
15663
+ IconButton,
15664
+ {
15665
+ tooltip: translation("sDateTimeSelect", { datetimeMode: mode }),
15666
+ coloringStyle: "text",
15667
+ color: "neutral",
15668
+ size: "sm",
15669
+ className: "absolute right-1 top-1/2 -translate-y-1/2",
15670
+ disabled,
15671
+ onClick: () => {
15672
+ changeOpenWrapper(true);
15673
+ },
15674
+ "aria-haspopup": "dialog",
15675
+ "aria-expanded": isOpen,
15676
+ "aria-controls": isOpen ? ids.popup : void 0,
15677
+ children: /* @__PURE__ */ jsx66(CalendarIcon, { className: "size-5" })
15678
+ }
15679
+ ) })
15680
+ ] }),
15681
+ /* @__PURE__ */ jsx66(
15682
+ PopUp,
15683
+ {
15684
+ id: ids.popup,
15685
+ isOpen,
15686
+ anchor: innerRef,
15687
+ options: {
15688
+ verticalAlignment: "afterEnd",
15689
+ horizontalAlignment: "center",
15690
+ gap: 4
15691
+ },
15692
+ outsideClickOptions: { refs: [innerRef], active: outsideClickCloses },
15693
+ onClose: () => {
15694
+ changeOpenWrapper(false);
15695
+ onEditComplete?.(state);
15696
+ },
15697
+ role: "dialog",
15698
+ "aria-labelledby": ids.label,
15699
+ className: "flex-col-2 p-2",
15700
+ children: /* @__PURE__ */ jsx66(
15701
+ DateTimePickerDialog,
15702
+ {
15703
+ value: dialogValue,
15704
+ allowRemove,
15705
+ onValueChange: setDialogValue,
15706
+ onEditComplete: (value2) => {
15707
+ setState(value2);
15708
+ onEditComplete?.(value2);
15709
+ changeOpenWrapper(false);
15710
+ },
15711
+ pickerProps,
15712
+ mode
15713
+ }
15714
+ )
15715
+ }
15716
+ )
15717
+ ] });
15718
+ });
15719
+
15720
+ // src/components/layout/table/TableFilterPopups.tsx
15721
+ import { useId as useId14, useMemo as useMemo27, useState as useState33 } from "react";
15722
+
15723
+ // src/components/user-interaction/select/MultiSelect.tsx
15724
+ import { forwardRef as forwardRef18 } from "react";
15725
+ import { jsx as jsx67, jsxs as jsxs37 } from "react/jsx-runtime";
15726
+ var MultiSelect = forwardRef18(function MultiSelect2({
15727
+ children,
15728
+ contentPanelProps,
15729
+ buttonProps,
15730
+ ...props
15731
+ }, ref) {
15732
+ return /* @__PURE__ */ jsxs37(MultiSelectRoot, { ...props, children: [
15733
+ /* @__PURE__ */ jsx67(MultiSelectButton, { ref, ...buttonProps }),
15734
+ /* @__PURE__ */ jsx67(MultiSelectContent, { ...contentPanelProps, children })
15735
+ ] });
15736
+ });
15737
+
15738
+ // src/components/layout/table/TableFilterPopups.tsx
15739
+ import {
15740
+ ArrowRight,
15741
+ ArrowLeft,
15742
+ ChevronRight as ChevronRight4,
15743
+ ChevronLeft as ChevronLeft4,
15744
+ CheckCircle2,
15745
+ XCircle,
15746
+ Equal,
15747
+ EqualNot,
15748
+ TextInitial,
15749
+ SearchCheck,
15750
+ SearchX,
15751
+ CircleDashed,
15752
+ CircleDot
15753
+ } from "lucide-react";
15754
+
15755
+ // src/components/user-interaction/Checkbox.tsx
15756
+ import { Check as Check2, Minus as Minus2 } from "lucide-react";
15757
+ import { useCallback as useCallback27 } from "react";
15758
+ import { jsx as jsx68, jsxs as jsxs38 } from "react/jsx-runtime";
15759
+ var Checkbox = ({
15760
+ value: controlledValue,
15761
+ initialValue = false,
15762
+ indeterminate,
15352
15763
  required = false,
15353
15764
  invalid = false,
15354
15765
  disabled = false,
@@ -15361,7 +15772,7 @@ var Checkbox = ({
15361
15772
  }) => {
15362
15773
  const onEditCompleteStable = useEventCallbackStabilizer(onEditComplete);
15363
15774
  const onValueChangeStable = useEventCallbackStabilizer(onValueChange);
15364
- const onChangeWrapper = useCallback26((value2) => {
15775
+ const onChangeWrapper = useCallback27((value2) => {
15365
15776
  onValueChangeStable(value2);
15366
15777
  onEditCompleteStable(value2);
15367
15778
  }, [onValueChangeStable, onEditCompleteStable]);
@@ -15584,7 +15995,7 @@ var TextFilter = ({ filterValue, onFilterValueChange }) => {
15584
15995
  const operator = filterValue?.operator ?? "textContains";
15585
15996
  const parameter = filterValue?.parameter ?? {};
15586
15997
  const id = useId14();
15587
- const availableOperators = useMemo25(() => [
15998
+ const availableOperators = useMemo27(() => [
15588
15999
  ...TableFilterOperator.text,
15589
16000
  ...TableFilterOperator.generic
15590
16001
  ], []);
@@ -15644,7 +16055,7 @@ var NumberFilter = ({ filterValue, onFilterValueChange }) => {
15644
16055
  const translation = useHightideTranslation();
15645
16056
  const operator = filterValue?.operator ?? "numberBetween";
15646
16057
  const parameter = filterValue?.parameter ?? {};
15647
- const availableOperators = useMemo25(() => [
16058
+ const availableOperators = useMemo27(() => [
15648
16059
  ...TableFilterOperator.number,
15649
16060
  ...TableFilterOperator.generic
15650
16061
  ], []);
@@ -15735,9 +16146,9 @@ var DateFilter = ({ filterValue, onFilterValueChange }) => {
15735
16146
  };
15736
16147
  const operator = filterValue?.operator ?? "dateBetween";
15737
16148
  const parameter = filterValue?.parameter ?? {};
15738
- const [temporaryMinDateValue, setTemporaryMinDateValue] = useState29(null);
15739
- const [temporaryMaxDateValue, setTemporaryMaxDateValue] = useState29(null);
15740
- const availableOperators = useMemo25(() => [
16149
+ const [temporaryMinDateValue, setTemporaryMinDateValue] = useState33(null);
16150
+ const [temporaryMaxDateValue, setTemporaryMaxDateValue] = useState33(null);
16151
+ const availableOperators = useMemo27(() => [
15741
16152
  ...TableFilterOperator.date,
15742
16153
  ...TableFilterOperator.generic
15743
16154
  ], []);
@@ -15860,9 +16271,9 @@ var DatetimeFilter = ({ filterValue, onFilterValueChange }) => {
15860
16271
  };
15861
16272
  const operator = filterValue?.operator ?? "dateTimeBetween";
15862
16273
  const parameter = filterValue?.parameter ?? {};
15863
- const [temporaryMinDateValue, setTemporaryMinDateValue] = useState29(null);
15864
- const [temporaryMaxDateValue, setTemporaryMaxDateValue] = useState29(null);
15865
- const availableOperators = useMemo25(() => [
16274
+ const [temporaryMinDateValue, setTemporaryMinDateValue] = useState33(null);
16275
+ const [temporaryMaxDateValue, setTemporaryMaxDateValue] = useState33(null);
16276
+ const availableOperators = useMemo27(() => [
15866
16277
  ...TableFilterOperator.dateTime,
15867
16278
  ...TableFilterOperator.generic
15868
16279
  ], []);
@@ -15979,7 +16390,7 @@ var DatetimeFilter = ({ filterValue, onFilterValueChange }) => {
15979
16390
  };
15980
16391
  var BooleanFilter = ({ filterValue, onFilterValueChange }) => {
15981
16392
  const operator = filterValue?.operator ?? "booleanIsTrue";
15982
- const availableOperators = useMemo25(() => [
16393
+ const availableOperators = useMemo27(() => [
15983
16394
  ...TableFilterOperator.boolean,
15984
16395
  ...TableFilterOperator.generic
15985
16396
  ], []);
@@ -16003,11 +16414,11 @@ var TagsFilter = ({ columnId, filterValue, onFilterValueChange }) => {
16003
16414
  const { table } = useTableStateWithoutSizingContext();
16004
16415
  const operator = filterValue?.operator ?? "tagsContains";
16005
16416
  const parameter = filterValue?.parameter ?? {};
16006
- const availableOperators = useMemo25(() => [
16417
+ const availableOperators = useMemo27(() => [
16007
16418
  ...TableFilterOperator.multiTags,
16008
16419
  ...TableFilterOperator.generic
16009
16420
  ], []);
16010
- const availableTags = useMemo25(() => {
16421
+ const availableTags = useMemo27(() => {
16011
16422
  const column = table.getColumn(columnId);
16012
16423
  if (!column) return [];
16013
16424
  return column.columnDef.meta?.filterData?.tags ?? [];
@@ -16054,11 +16465,11 @@ var TagsSingleFilter = ({ columnId, filterValue, onFilterValueChange }) => {
16054
16465
  const { table } = useTableStateWithoutSizingContext();
16055
16466
  const operator = filterValue?.operator ?? "tagsSingleContains";
16056
16467
  const parameter = filterValue?.parameter ?? {};
16057
- const availableOperators = useMemo25(() => [
16468
+ const availableOperators = useMemo27(() => [
16058
16469
  ...TableFilterOperator.singleTag,
16059
16470
  ...TableFilterOperator.generic
16060
16471
  ], []);
16061
- const availableTags = useMemo25(() => {
16472
+ const availableTags = useMemo27(() => {
16062
16473
  const column = table.getColumn(columnId);
16063
16474
  if (!column) return [];
16064
16475
  return column.columnDef.meta?.filterData?.tags ?? [];
@@ -16117,7 +16528,7 @@ var TagsSingleFilter = ({ columnId, filterValue, onFilterValueChange }) => {
16117
16528
  };
16118
16529
  var GenericFilter = ({ filterValue, onFilterValueChange }) => {
16119
16530
  const operator = filterValue?.operator ?? "notUndefined";
16120
- const availableOperators = useMemo25(() => [
16531
+ const availableOperators = useMemo27(() => [
16121
16532
  ...TableFilterOperator.generic
16122
16533
  ], []);
16123
16534
  return /* @__PURE__ */ jsx69("div", { className: "flex-col-2 gap-2", children: /* @__PURE__ */ jsx69(
@@ -16166,18 +16577,18 @@ var TableFilterButton = ({
16166
16577
  }) => {
16167
16578
  const translation = useHightideTranslation();
16168
16579
  const columnFilterValue = column.getFilterValue();
16169
- const [filterValue, setFilterValue] = useState30(columnFilterValue);
16580
+ const [filterValue, setFilterValue] = useState34(columnFilterValue);
16170
16581
  const hasFilter = !!filterValue;
16171
- const anchorRef = useRef30(null);
16172
- const containerRef = useRef30(null);
16173
- const [isOpen, setIsOpen] = useState30(false);
16582
+ const anchorRef = useRef31(null);
16583
+ const containerRef = useRef31(null);
16584
+ const [isOpen, setIsOpen] = useState34(false);
16174
16585
  const id = useId15();
16175
- const ids = useMemo26(() => ({
16586
+ const ids = useMemo28(() => ({
16176
16587
  button: `table-filter-button-${id}`,
16177
16588
  popup: `table-filter-popup-${id}`,
16178
16589
  label: `table-filter-label-${id}`
16179
16590
  }), [id]);
16180
- useEffect32(() => {
16591
+ useEffect39(() => {
16181
16592
  setFilterValue(columnFilterValue);
16182
16593
  }, [columnFilterValue]);
16183
16594
  const isTagsFilter = filterType === "multiTags" || filterType === "singleTag";
@@ -16252,11 +16663,11 @@ var TableFilterButton = ({
16252
16663
  };
16253
16664
 
16254
16665
  // src/components/layout/table/TableHeader.tsx
16255
- import { useCallback as useCallback27, useEffect as useEffect33 } from "react";
16666
+ import { useCallback as useCallback28, useEffect as useEffect40 } from "react";
16256
16667
  import { Fragment as Fragment9, jsx as jsx71, jsxs as jsxs41 } from "react/jsx-runtime";
16257
16668
  var TableHeader = ({ isSticky = false }) => {
16258
16669
  const { table } = useTableStateWithoutSizingContext();
16259
- const handleResizeMove = useCallback27((e) => {
16670
+ const handleResizeMove = useCallback28((e) => {
16260
16671
  if (!table.getState().columnSizingInfo.isResizingColumn) return;
16261
16672
  const currentX = "touches" in e ? e.touches[0].clientX : e.clientX;
16262
16673
  const deltaOffset = currentX - (table.getState().columnSizingInfo.startOffset ?? 0);
@@ -16272,7 +16683,7 @@ var TableHeader = ({ isSticky = false }) => {
16272
16683
  deltaOffset
16273
16684
  }));
16274
16685
  }, [table]);
16275
- const handleResizeEnd = useCallback27(() => {
16686
+ const handleResizeEnd = useCallback28(() => {
16276
16687
  if (!table.getState().columnSizingInfo.isResizingColumn) return;
16277
16688
  const newWidth = (table.getState().columnSizingInfo.startSize ?? 0) + (table.getState().columnSizingInfo.deltaOffset ?? 0);
16278
16689
  table.setColumnSizing((prev) => {
@@ -16290,7 +16701,7 @@ var TableHeader = ({ isSticky = false }) => {
16290
16701
  startSize: null
16291
16702
  });
16292
16703
  }, [table]);
16293
- useEffect33(() => {
16704
+ useEffect40(() => {
16294
16705
  window.addEventListener("pointermove", handleResizeMove);
16295
16706
  window.addEventListener("pointerup", handleResizeEnd);
16296
16707
  return () => {
@@ -16459,7 +16870,7 @@ var TablePagination = ({ allowChangingPageSize = true, pageSizeOptions, ...props
16459
16870
  };
16460
16871
 
16461
16872
  // src/components/layout/table/TableWithSelectionProvider.tsx
16462
- import { useCallback as useCallback28, useMemo as useMemo27 } from "react";
16873
+ import { useCallback as useCallback29, useMemo as useMemo29 } from "react";
16463
16874
  import { jsx as jsx74 } from "react/jsx-runtime";
16464
16875
  var TableWithSelectionProvider = ({
16465
16876
  children,
@@ -16472,7 +16883,7 @@ var TableWithSelectionProvider = ({
16472
16883
  ...props
16473
16884
  }) => {
16474
16885
  const translation = useHightideTranslation();
16475
- const columnDef = useMemo27(() => [
16886
+ const columnDef = useMemo29(() => [
16476
16887
  {
16477
16888
  id: selectionRowId,
16478
16889
  header: ({ table }) => {
@@ -16515,7 +16926,7 @@ var TableWithSelectionProvider = ({
16515
16926
  TableProvider,
16516
16927
  {
16517
16928
  ...props,
16518
- fillerRowCell: useCallback28((columnId, table) => {
16929
+ fillerRowCell: useCallback29((columnId, table) => {
16519
16930
  if (columnId === selectionRowId) {
16520
16931
  return /* @__PURE__ */ jsx74(Checkbox, { value: false, disabled: true });
16521
16932
  }
@@ -16533,7 +16944,7 @@ var TableWithSelectionProvider = ({
16533
16944
  rowSelection,
16534
16945
  ...state
16535
16946
  },
16536
- onRowClick: useCallback28((row, table) => {
16947
+ onRowClick: useCallback29((row, table) => {
16537
16948
  if (!disableClickRowClickSelection) {
16538
16949
  row.toggleSelected();
16539
16950
  }
@@ -16575,7 +16986,7 @@ var TableWithSelection = ({
16575
16986
  };
16576
16987
 
16577
16988
  // src/components/layout/table/TableColumn.tsx
16578
- import { memo as memo2, useEffect as useEffect34, useMemo as useMemo28, useState as useState31 } from "react";
16989
+ import { memo as memo2, useEffect as useEffect41, useMemo as useMemo30, useState as useState35 } from "react";
16579
16990
  import { jsx as jsx76 } from "react/jsx-runtime";
16580
16991
  var TableColumnComponent = ({
16581
16992
  filterType,
@@ -16587,11 +16998,11 @@ var TableColumnComponent = ({
16587
16998
  "TableColumn: For filterType === multiTags or singleTag, filterData.tags must be set.",
16588
16999
  (filterType === "multiTags" || filterType === "singleTag") && props.meta?.filterData?.tags === void 0
16589
17000
  );
16590
- const [column] = useState31({
17001
+ const [column] = useState35({
16591
17002
  ...props,
16592
17003
  filterFn
16593
17004
  });
16594
- useEffect34(() => {
17005
+ useEffect41(() => {
16595
17006
  const unsubscribe = registerColumn(column);
16596
17007
  return () => {
16597
17008
  unsubscribe();
@@ -16606,27 +17017,27 @@ var TableColumnFactory = () => memo2(
16606
17017
  }
16607
17018
  );
16608
17019
  var TableColumn = (props) => {
16609
- const TableColumnComponent2 = useMemo28(() => TableColumnFactory(), []);
17020
+ const TableColumnComponent2 = useMemo30(() => TableColumnFactory(), []);
16610
17021
  return /* @__PURE__ */ jsx76(TableColumnComponent2, { ...props });
16611
17022
  };
16612
17023
 
16613
17024
  // src/components/layout/table/TableColumnSwitcher.tsx
16614
- import { useMemo as useMemo29, useRef as useRef31, useId as useId16 } from "react";
17025
+ import { useMemo as useMemo31, useRef as useRef32, useId as useId16 } from "react";
16615
17026
  import { ChevronUp as ChevronUp3, ChevronDown as ChevronDown5, ChevronLeft as ChevronLeft5, ChevronRight as ChevronRight5, Eye, EyeOff, Pin, PinOff, ArrowLeftRightIcon } from "lucide-react";
16616
17027
  import { Fragment as Fragment10, jsx as jsx77, jsxs as jsxs45 } from "react/jsx-runtime";
16617
17028
  var TableColumnSwitcherPopUp = ({ ...props }) => {
16618
17029
  const { table } = useTableStateWithoutSizingContext();
16619
17030
  const translation = useHightideTranslation();
16620
- const containerRef = useRef31(null);
17031
+ const containerRef = useRef32(null);
16621
17032
  const generatedId = useId16();
16622
- const ids = useMemo29(() => ({
17033
+ const ids = useMemo31(() => ({
16623
17034
  popup: props.id ?? `table-column-picker-popup-${generatedId}`,
16624
17035
  label: `table-column-picker-label-${generatedId}`
16625
17036
  }), [generatedId, props.id]);
16626
17037
  const tableState = table.getState();
16627
17038
  const columnOrder = tableState.columnOrder;
16628
17039
  const columnPinning = tableState.columnPinning;
16629
- const columns = useMemo29(() => {
17040
+ const columns = useMemo31(() => {
16630
17041
  const allColumns = table.getAllColumns();
16631
17042
  const leftPinned = [];
16632
17043
  const unpinned = [];
@@ -16884,7 +17295,7 @@ var TableColumnSwitcher = ({ buttonProps, ...props }) => {
16884
17295
  };
16885
17296
 
16886
17297
  // src/components/user-interaction/CopyToClipboardWrapper.tsx
16887
- import { useState as useState32 } from "react";
17298
+ import { useState as useState36 } from "react";
16888
17299
  import { clsx as clsx28 } from "clsx";
16889
17300
 
16890
17301
  // src/utils/writeToClipboard.ts
@@ -16907,7 +17318,7 @@ var CopyToClipboardWrapper = ({
16907
17318
  ...props
16908
17319
  }) => {
16909
17320
  const translation = useHightideTranslation();
16910
- const [isShowingConfirmation, setIsShowingConfirmation] = useState32(false);
17321
+ const [isShowingConfirmation, setIsShowingConfirmation] = useState36(false);
16911
17322
  return /* @__PURE__ */ jsxs46(
16912
17323
  TooltipRoot,
16913
17324
  {
@@ -16956,7 +17367,7 @@ var CopyToClipboardWrapper = ({
16956
17367
  };
16957
17368
 
16958
17369
  // src/components/user-interaction/Menu.tsx
16959
- import { useCallback as useCallback29, useRef as useRef32, useState as useState33 } from "react";
17370
+ import { useCallback as useCallback30, useRef as useRef33, useState as useState37 } from "react";
16960
17371
  import clsx29 from "clsx";
16961
17372
  import { Fragment as Fragment11, jsx as jsx79, jsxs as jsxs47 } from "react/jsx-runtime";
16962
17373
  var MenuItem = ({
@@ -16982,8 +17393,8 @@ var Menu = ({
16982
17393
  disabled = false,
16983
17394
  ...props
16984
17395
  }) => {
16985
- const triggerRef = useRef32(null);
16986
- const [isOpen, setIsOpen] = useState33(false);
17396
+ const triggerRef = useRef33(null);
17397
+ const [isOpen, setIsOpen] = useState37(false);
16987
17398
  const bag = {
16988
17399
  isOpen,
16989
17400
  close: () => setIsOpen(false),
@@ -16991,7 +17402,7 @@ var Menu = ({
16991
17402
  disabled
16992
17403
  };
16993
17404
  return /* @__PURE__ */ jsxs47(Fragment11, { children: [
16994
- trigger(bag, useCallback29((el) => triggerRef.current = el, [])),
17405
+ trigger(bag, useCallback30((el) => triggerRef.current = el, [])),
16995
17406
  /* @__PURE__ */ jsx79(
16996
17407
  PopUp,
16997
17408
  {
@@ -17013,7 +17424,7 @@ var Menu = ({
17013
17424
  };
17014
17425
 
17015
17426
  // src/components/user-interaction/ScrollPicker.tsx
17016
- import { useCallback as useCallback30, useEffect as useEffect35, useState as useState34 } from "react";
17427
+ import { useCallback as useCallback31, useEffect as useEffect42, useState as useState38 } from "react";
17017
17428
  import clsx30 from "clsx";
17018
17429
  import { jsx as jsx80, jsxs as jsxs48 } from "react/jsx-runtime";
17019
17430
  var up = 1;
@@ -17034,7 +17445,7 @@ var ScrollPicker = ({
17034
17445
  transition,
17035
17446
  items,
17036
17447
  lastTimeStamp
17037
- }, setAnimation] = useState34({
17448
+ }, setAnimation] = useState38({
17038
17449
  targetIndex: selectedIndex,
17039
17450
  currentIndex: disabled ? selectedIndex : 0,
17040
17451
  velocity: 0,
@@ -17050,7 +17461,7 @@ var ScrollPicker = ({
17050
17461
  const itemHeight = 40;
17051
17462
  const distance = 8;
17052
17463
  const containerHeight = itemHeight * (itemsShownCount - 2) + distance * (itemsShownCount - 2 + 1);
17053
- const getDirection = useCallback30((targetIndex, currentIndex2, transition2, length) => {
17464
+ const getDirection = useCallback31((targetIndex, currentIndex2, transition2, length) => {
17054
17465
  if (targetIndex === currentIndex2) {
17055
17466
  return transition2 > 0 ? up : down;
17056
17467
  }
@@ -17060,7 +17471,7 @@ var ScrollPicker = ({
17060
17471
  }
17061
17472
  return distanceForward >= length / 2 ? down : up;
17062
17473
  }, []);
17063
- const animate = useCallback30((timestamp, startTime) => {
17474
+ const animate = useCallback31((timestamp, startTime) => {
17064
17475
  setAnimation((prevState) => {
17065
17476
  const {
17066
17477
  targetIndex,
@@ -17133,7 +17544,7 @@ var ScrollPicker = ({
17133
17544
  };
17134
17545
  });
17135
17546
  }, [disabled, getDirection, onChange]);
17136
- useEffect35(() => {
17547
+ useEffect42(() => {
17137
17548
  requestAnimationFrame((timestamp) => animate(timestamp, lastTimeStamp));
17138
17549
  });
17139
17550
  const opacity = (transition2, index, itemsCount) => {
@@ -17211,7 +17622,7 @@ var ScrollPicker = ({
17211
17622
  };
17212
17623
 
17213
17624
  // src/components/user-interaction/Switch.tsx
17214
- import { useCallback as useCallback31 } from "react";
17625
+ import { useCallback as useCallback32 } from "react";
17215
17626
  import { jsx as jsx81 } from "react/jsx-runtime";
17216
17627
  var Switch = ({
17217
17628
  value: controlledValue,
@@ -17226,7 +17637,7 @@ var Switch = ({
17226
17637
  }) => {
17227
17638
  const onEditCompleteStable = useEventCallbackStabilizer(onEditComplete);
17228
17639
  const onValueChangeStable = useEventCallbackStabilizer(onValueChange);
17229
- const onChangeWrapper = useCallback31((value2) => {
17640
+ const onChangeWrapper = useCallback32((value2) => {
17230
17641
  onValueChangeStable(!value2);
17231
17642
  onEditCompleteStable(!value2);
17232
17643
  }, [onValueChangeStable, onEditCompleteStable]);
@@ -17266,7 +17677,7 @@ var Switch = ({
17266
17677
  };
17267
17678
 
17268
17679
  // src/components/user-interaction/Textarea.tsx
17269
- import { forwardRef as forwardRef19, useCallback as useCallback32, useId as useId17 } from "react";
17680
+ import { forwardRef as forwardRef19, useCallback as useCallback33, useId as useId17 } from "react";
17270
17681
  import clsx31 from "clsx";
17271
17682
  import { jsx as jsx82, jsxs as jsxs49 } from "react/jsx-runtime";
17272
17683
  var Textarea = forwardRef19(function Textarea2({
@@ -17285,7 +17696,7 @@ var Textarea = forwardRef19(function Textarea2({
17285
17696
  });
17286
17697
  const { restartTimer, clearTimer } = useDelay(saveDelayOptions);
17287
17698
  const onEditCompleteStable = useEventCallbackStabilizer(onEditComplete);
17288
- const onEditCompleteWrapper = useCallback32((text) => {
17699
+ const onEditCompleteWrapper = useCallback33((text) => {
17289
17700
  onEditCompleteStable(text);
17290
17701
  clearTimer();
17291
17702
  }, [onEditCompleteStable, clearTimer]);
@@ -17397,7 +17808,7 @@ var TimeDisplay = ({
17397
17808
 
17398
17809
  // src/components/user-interaction/input/InsideLabelInput.tsx
17399
17810
  import { useId as useId18 } from "react";
17400
- import { forwardRef as forwardRef20, useState as useState35 } from "react";
17811
+ import { forwardRef as forwardRef20, useState as useState39 } from "react";
17401
17812
  import clsx32 from "clsx";
17402
17813
  import { jsx as jsx84, jsxs as jsxs50 } from "react/jsx-runtime";
17403
17814
  var InsideLabelInput = forwardRef20(function InsideLabelInput2({
@@ -17413,7 +17824,7 @@ var InsideLabelInput = forwardRef20(function InsideLabelInput2({
17413
17824
  onValueChange,
17414
17825
  defaultValue: initialValue
17415
17826
  });
17416
- const [isFocused, setIsFocused] = useState35(false);
17827
+ const [isFocused, setIsFocused] = useState39(false);
17417
17828
  const generatedId = useId18();
17418
17829
  const id = customId ?? generatedId;
17419
17830
  return /* @__PURE__ */ jsxs50("div", { className: clsx32("relative"), children: [
@@ -17503,7 +17914,7 @@ var SearchBar = ({
17503
17914
  };
17504
17915
 
17505
17916
  // src/components/user-interaction/input/ToggleableInput.tsx
17506
- import { forwardRef as forwardRef21, useEffect as useEffect36, useImperativeHandle as useImperativeHandle12, useRef as useRef33, useState as useState36 } from "react";
17917
+ import { forwardRef as forwardRef21, useEffect as useEffect43, useImperativeHandle as useImperativeHandle12, useRef as useRef34, useState as useState40 } from "react";
17507
17918
  import { Pencil } from "lucide-react";
17508
17919
  import clsx34 from "clsx";
17509
17920
  import { jsx as jsx86, jsxs as jsxs52 } from "react/jsx-runtime";
@@ -17520,10 +17931,10 @@ var ToggleableInput = forwardRef21(function ToggleableInput2({
17520
17931
  onValueChange,
17521
17932
  defaultValue: initialValue
17522
17933
  });
17523
- const [isEditing, setIsEditing] = useState36(initialState !== "display");
17524
- const innerRef = useRef33(null);
17934
+ const [isEditing, setIsEditing] = useState40(initialState !== "display");
17935
+ const innerRef = useRef34(null);
17525
17936
  useImperativeHandle12(forwardedRef, () => innerRef.current);
17526
- useEffect36(() => {
17937
+ useEffect43(() => {
17527
17938
  if (isEditing) {
17528
17939
  innerRef.current?.focus();
17529
17940
  }
@@ -17733,7 +18144,7 @@ var DateProperty = ({
17733
18144
  import { List } from "lucide-react";
17734
18145
 
17735
18146
  // src/components/user-interaction/select/MultiSelectChipDisplay.tsx
17736
- import { forwardRef as forwardRef22, useEffect as useEffect37, useImperativeHandle as useImperativeHandle13, useRef as useRef34 } from "react";
18147
+ import { forwardRef as forwardRef22, useEffect as useEffect44, useImperativeHandle as useImperativeHandle13, useRef as useRef35 } from "react";
17737
18148
  import { XIcon as XIcon2, Plus } from "lucide-react";
17738
18149
  import { jsx as jsx90, jsxs as jsxs55 } from "react/jsx-runtime";
17739
18150
  var MultiSelectChipDisplayButton = forwardRef22(function MultiSelectChipDisplayButton2({
@@ -17743,7 +18154,7 @@ var MultiSelectChipDisplayButton = forwardRef22(function MultiSelectChipDisplayB
17743
18154
  const translation = useHightideTranslation();
17744
18155
  const { state, trigger, item, ids, setIds } = useSelectContext();
17745
18156
  const { register, unregister, toggleOpen } = trigger;
17746
- useEffect37(() => {
18157
+ useEffect44(() => {
17747
18158
  if (id) {
17748
18159
  setIds((prev) => ({
17749
18160
  ...prev,
@@ -17751,9 +18162,9 @@ var MultiSelectChipDisplayButton = forwardRef22(function MultiSelectChipDisplayB
17751
18162
  }));
17752
18163
  }
17753
18164
  }, [id, setIds]);
17754
- const innerRef = useRef34(null);
18165
+ const innerRef = useRef35(null);
17755
18166
  useImperativeHandle13(ref, () => innerRef.current);
17756
- useEffect37(() => {
18167
+ useEffect44(() => {
17757
18168
  register(innerRef);
17758
18169
  return () => unregister();
17759
18170
  }, [register, unregister]);
@@ -17990,463 +18401,97 @@ var SingleSelectProperty = ({
17990
18401
  className: "flex-row-2 w-full items-center justify-between",
17991
18402
  hideExpansionIcon: true,
17992
18403
  "data-name": "property-input"
17993
- }
17994
- ),
17995
- /* @__PURE__ */ jsx93(SelectContent, { children })
17996
- ]
17997
- }
17998
- )
17999
- }
18000
- )
18001
- }
18002
- );
18003
- };
18004
-
18005
- // src/components/user-interaction/properties/TextProperty.tsx
18006
- import { Text } from "lucide-react";
18007
- import { jsx as jsx94 } from "react/jsx-runtime";
18008
- var TextProperty = ({
18009
- value,
18010
- readOnly,
18011
- onValueChange,
18012
- onEditComplete,
18013
- ...baseProps
18014
- }) => {
18015
- const translation = useHightideTranslation();
18016
- const hasValue = value !== void 0;
18017
- return /* @__PURE__ */ jsx94(
18018
- PropertyBase,
18019
- {
18020
- ...baseProps,
18021
- hasValue,
18022
- icon: /* @__PURE__ */ jsx94(Text, { size: 24 }),
18023
- children: ({ invalid }) => /* @__PURE__ */ jsx94(
18024
- Textarea,
18025
- {
18026
- "data-name": "property-input",
18027
- className: "w-full",
18028
- "data-invalid": PropsUtil.dataAttributes.bool(invalid),
18029
- rows: 5,
18030
- value: value ?? "",
18031
- readOnly,
18032
- placeholder: translation("text"),
18033
- onValueChange: (value2) => onValueChange?.(value2),
18034
- onEditComplete: (value2) => onEditComplete?.(value2)
18035
- }
18036
- )
18037
- }
18038
- );
18039
- };
18040
-
18041
- // src/components/utils/Transition.tsx
18042
- import { useEffect as useEffect38, useState as useState37 } from "react";
18043
- function Transition({
18044
- children,
18045
- show,
18046
- includeAnimation = true
18047
- }) {
18048
- const [isOpen, setIsOpen] = useState37(show);
18049
- const [isTransitioning, setIsTransitioning] = useState37(!isOpen);
18050
- const isUsingReducedMotion = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : true;
18051
- useEffect38(() => {
18052
- setIsOpen(show);
18053
- setIsTransitioning(true);
18054
- }, [show]);
18055
- const onAnimationEnd = () => setIsTransitioning(false);
18056
- const bag = {
18057
- isOpen,
18058
- isTransitioning,
18059
- isUsingReducedMotion,
18060
- data: {
18061
- "data-open": isOpen && !isTransitioning ? "" : void 0,
18062
- "data-opening": isOpen && isTransitioning ? "" : void 0,
18063
- "data-closing": !isOpen && isTransitioning ? "" : void 0,
18064
- "data-closed": !isOpen && !isTransitioning ? "" : void 0
18065
- },
18066
- handlers: {
18067
- onTransitionEnd: () => setIsTransitioning(false),
18068
- onTransitionCancel: () => setIsTransitioning(false),
18069
- onAnimationEnd: includeAnimation ? onAnimationEnd : void 0
18070
- }
18071
- };
18072
- return BagFunctionUtil.resolve(children, bag);
18073
- }
18074
-
18075
- // src/global-contexts/HightideProvider.tsx
18076
- import { jsx as jsx95 } from "react/jsx-runtime";
18077
- var HightideProvider = ({
18078
- children,
18079
- theme,
18080
- locale,
18081
- config
18082
- }) => {
18083
- return /* @__PURE__ */ jsx95(LocaleProvider, { ...locale, children: /* @__PURE__ */ jsx95(ThemeProvider, { ...theme, children: /* @__PURE__ */ jsx95(HightideConfigProvider, { ...config, children }) }) });
18084
- };
18085
-
18086
- // src/hooks/focus/useFocusGuards.ts
18087
- import { useEffect as useEffect39 } from "react";
18088
- var selectorName = "data-hw-focus-guard";
18089
- function FocusGuard() {
18090
- const element = document.createElement("div");
18091
- element.setAttribute(selectorName, "");
18092
- element.tabIndex = 0;
18093
- element.style.border = "none";
18094
- element.style.outline = "none";
18095
- element.style.boxShadow = "none";
18096
- element.style.opacity = "0";
18097
- element.style.position = "fixed";
18098
- element.style.pointerEvents = "none";
18099
- return element;
18100
- }
18101
- var FocusGuardsService = class _FocusGuardsService {
18102
- constructor() {
18103
- this.count = 0;
18104
- }
18105
- static getInstance() {
18106
- if (!_FocusGuardsService.instance) {
18107
- _FocusGuardsService.instance = new _FocusGuardsService();
18108
- }
18109
- return _FocusGuardsService.instance;
18110
- }
18111
- add() {
18112
- const edgeGuards = document.querySelectorAll(`[${selectorName}]`);
18113
- document.body.insertAdjacentElement("afterbegin", edgeGuards[0] ?? FocusGuard());
18114
- document.body.insertAdjacentElement("beforeend", edgeGuards[1] ?? FocusGuard());
18115
- this.count++;
18116
- }
18117
- remove() {
18118
- if (this.count === 1) {
18119
- document.querySelectorAll(`[${selectorName}]`).forEach((node) => node.remove());
18120
- }
18121
- this.count--;
18122
- }
18123
- };
18124
- var useFocusGuards = () => {
18125
- useEffect39(() => {
18126
- FocusGuardsService.getInstance().add();
18127
- return () => {
18128
- FocusGuardsService.getInstance().remove();
18129
- };
18130
- }, []);
18131
- };
18132
-
18133
- // src/hooks/focus/useFocusOnceVisible.ts
18134
- import React6, { useEffect as useEffect40 } from "react";
18135
- var useFocusOnceVisible = (ref, disable = false) => {
18136
- const [hasUsedFocus, setHasUsedFocus] = React6.useState(false);
18137
- useEffect40(() => {
18138
- if (disable || hasUsedFocus) {
18139
- return;
18140
- }
18141
- const observer = new IntersectionObserver(([entry]) => {
18142
- if (entry.isIntersecting && !hasUsedFocus) {
18143
- ref.current?.focus();
18144
- setHasUsedFocus(hasUsedFocus);
18145
- }
18146
- }, {
18147
- threshold: 0.1
18148
- });
18149
- if (ref.current) {
18150
- observer.observe(ref.current);
18151
- }
18152
- return () => observer.disconnect();
18153
- }, [disable, hasUsedFocus, ref]);
18154
- };
18155
-
18156
- // src/hooks/focus/useIsMounted.ts
18157
- import { useEffect as useEffect41, useLayoutEffect as useLayoutEffect7, useState as useState38 } from "react";
18158
- var isClient = typeof window !== "undefined" && typeof document !== "undefined";
18159
- var useIsomorphicEffect = isClient ? useLayoutEffect7 : useEffect41;
18160
- var useIsMounted = () => {
18161
- const [isMounted, setIsMounted] = useState38(false);
18162
- useIsomorphicEffect(() => {
18163
- setIsMounted(true);
18164
- return () => {
18165
- setIsMounted(false);
18166
- };
18167
- }, []);
18168
- return isMounted;
18169
- };
18170
-
18171
- // src/hooks/useHandleRefs.ts
18172
- import { useEffect as useEffect42, useRef as useRef35 } from "react";
18173
- function useHandleRefs(handleRef) {
18174
- const refs = useRef35([]);
18175
- useEffect42(() => {
18176
- refs.current = Object.keys(handleRef?.current ?? {}).map(
18177
- () => ({ current: null })
18178
- );
18179
- const values = Object.values(handleRef?.current ?? {});
18180
- values.forEach((el, i) => {
18181
- refs.current[i].current = el;
18182
- });
18183
- });
18184
- return refs.current;
18185
- }
18186
-
18187
- // src/hooks/useLogUnstableDependencies.ts
18188
- import React7 from "react";
18189
- function useLogUnstableDependencies(name, value) {
18190
- const prev = React7.useRef(null);
18191
- React7.useEffect(() => {
18192
- if (!prev.current) {
18193
- prev.current = value;
18194
- return;
18195
- }
18196
- const changes = {};
18197
- for (const key of Object.keys(value)) {
18198
- if (prev.current[key] !== value[key]) {
18199
- changes[key] = {
18200
- prev: prev.current[key],
18201
- next: value[key]
18202
- };
18203
- }
18204
- }
18205
- if (Object.keys(changes).length > 0) {
18206
- console.info(`[${name}] changed`, changes);
18207
- }
18208
- prev.current = value;
18209
- });
18210
- }
18211
-
18212
- // src/hooks/useOverwritableState.ts
18213
- import { useEffect as useEffect43, useState as useState39 } from "react";
18214
- var useOverwritableState = (overwriteValue, onChange) => {
18215
- const [state, setState] = useState39(overwriteValue);
18216
- useEffect43(() => {
18217
- setState(overwriteValue);
18218
- }, [overwriteValue]);
18219
- const onChangeWrapper = (action) => {
18220
- const resolved = resolveSetState(action, state);
18221
- setState(resolved);
18222
- onChange?.(resolved);
18223
- };
18224
- return [state, onChangeWrapper];
18225
- };
18226
-
18227
- // src/hooks/useRerender.ts
18228
- import { useReducer as useReducer2 } from "react";
18229
- var useRerender = () => {
18230
- return useReducer2(() => ({}), {})[1];
18231
- };
18232
-
18233
- // src/hooks/useSearch.ts
18234
- import { useCallback as useCallback33, useEffect as useEffect44, useMemo as useMemo30, useState as useState40 } from "react";
18235
-
18236
- // src/utils/simpleSearch.ts
18237
- var MultiSubjectSearchWithMapping = (search, objects, mapping) => {
18238
- return objects.filter((object) => {
18239
- const mappedSearchKeywords = mapping(object)?.map((value) => value.toLowerCase().trim());
18240
- if (!mappedSearchKeywords) {
18241
- return true;
18242
- }
18243
- return search.every((searchValue) => !!mappedSearchKeywords.find((value) => !!value && value.includes(searchValue.toLowerCase().trim())));
18244
- });
18245
- };
18246
- var MultiSearchWithMapping = (search, objects, mapping) => {
18247
- return objects.filter((object) => {
18248
- const mappedSearchKeywords = mapping(object)?.map((value) => value.toLowerCase().trim());
18249
- if (!mappedSearchKeywords) {
18250
- return true;
18404
+ }
18405
+ ),
18406
+ /* @__PURE__ */ jsx93(SelectContent, { children })
18407
+ ]
18408
+ }
18409
+ )
18410
+ }
18411
+ )
18251
18412
  }
18252
- return !!mappedSearchKeywords.find((value) => value.includes(search.toLowerCase().trim()));
18253
- });
18254
- };
18255
- var SimpleSearchWithMapping = (search, objects, mapping) => {
18256
- return MultiSearchWithMapping(search, objects, (value) => [mapping(value)]);
18257
- };
18258
- var SimpleSearch = (search, objects) => {
18259
- return SimpleSearchWithMapping(search, objects, (value) => value);
18413
+ );
18260
18414
  };
18261
18415
 
18262
- // src/hooks/useSearch.ts
18263
- var useSearch = ({
18264
- list,
18265
- initialSearch,
18266
- searchMapping,
18267
- additionalSearchTags,
18268
- isSearchInstant = true,
18269
- sortingFunction,
18270
- filter,
18271
- disabled = false
18416
+ // src/components/user-interaction/properties/TextProperty.tsx
18417
+ import { Text } from "lucide-react";
18418
+ import { jsx as jsx94 } from "react/jsx-runtime";
18419
+ var TextProperty = ({
18420
+ value,
18421
+ readOnly,
18422
+ onValueChange,
18423
+ onEditComplete,
18424
+ ...baseProps
18272
18425
  }) => {
18273
- const [search, setSearch] = useState40(initialSearch ?? "");
18274
- const [result, setResult] = useState40(list);
18275
- const searchTags = useMemo30(() => additionalSearchTags ?? [], [additionalSearchTags]);
18276
- const updateSearch = useCallback33((newSearch) => {
18277
- const usedSearch = newSearch ?? search;
18278
- if (newSearch) {
18279
- setSearch(search);
18280
- }
18281
- setResult(MultiSubjectSearchWithMapping([usedSearch, ...searchTags], list, searchMapping));
18282
- }, [searchTags, list, search, searchMapping]);
18283
- useEffect44(() => {
18284
- if (isSearchInstant) {
18285
- setResult(MultiSubjectSearchWithMapping([search, ...searchTags], list, searchMapping));
18286
- }
18287
- }, [searchTags, isSearchInstant, list, search, searchMapping, additionalSearchTags]);
18288
- const filteredResult = useMemo30(() => {
18289
- if (!filter) {
18290
- return result;
18291
- }
18292
- return result.filter(filter);
18293
- }, [result, filter]);
18294
- const sortedAndFilteredResult = useMemo30(() => {
18295
- if (!sortingFunction) {
18296
- return filteredResult;
18297
- }
18298
- return filteredResult.sort(sortingFunction);
18299
- }, [filteredResult, sortingFunction]);
18300
- const usedResult = useMemo30(() => {
18301
- if (!disabled) {
18302
- return sortedAndFilteredResult;
18426
+ const translation = useHightideTranslation();
18427
+ const hasValue = value !== void 0;
18428
+ return /* @__PURE__ */ jsx94(
18429
+ PropertyBase,
18430
+ {
18431
+ ...baseProps,
18432
+ hasValue,
18433
+ icon: /* @__PURE__ */ jsx94(Text, { size: 24 }),
18434
+ children: ({ invalid }) => /* @__PURE__ */ jsx94(
18435
+ Textarea,
18436
+ {
18437
+ "data-name": "property-input",
18438
+ className: "w-full",
18439
+ "data-invalid": PropsUtil.dataAttributes.bool(invalid),
18440
+ rows: 5,
18441
+ value: value ?? "",
18442
+ readOnly,
18443
+ placeholder: translation("text"),
18444
+ onValueChange: (value2) => onValueChange?.(value2),
18445
+ onEditComplete: (value2) => onEditComplete?.(value2)
18446
+ }
18447
+ )
18303
18448
  }
18304
- return list;
18305
- }, [disabled, list, sortedAndFilteredResult]);
18306
- return {
18307
- result: usedResult,
18308
- hasResult: usedResult.length > 0,
18309
- allItems: list,
18310
- updateSearch,
18311
- search,
18312
- setSearch
18313
- };
18449
+ );
18314
18450
  };
18315
18451
 
18316
- // src/hooks/useUpdatingDateString.ts
18452
+ // src/components/utils/Transition.tsx
18317
18453
  import { useEffect as useEffect45, useState as useState41 } from "react";
18318
- var useUpdatingDateString = ({ absoluteFormat = "dateTime", localeOverride, date }) => {
18319
- const { locale: contextLocale } = useLocale();
18320
- const locale = localeOverride ?? contextLocale;
18321
- const [dateAndTimeStrings, setDateAndTimeStrings] = useState41({
18322
- compareDate: date,
18323
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
18324
- relative: DateUtils.formatRelative(date, locale)
18325
- });
18326
- useEffect45(() => {
18327
- setDateAndTimeStrings({
18328
- compareDate: date,
18329
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
18330
- relative: DateUtils.formatRelative(date, locale)
18331
- });
18332
- }, [date, absoluteFormat, locale]);
18454
+ function Transition({
18455
+ children,
18456
+ show,
18457
+ includeAnimation = true
18458
+ }) {
18459
+ const [isOpen, setIsOpen] = useState41(show);
18460
+ const [isTransitioning, setIsTransitioning] = useState41(!isOpen);
18461
+ const isUsingReducedMotion = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : true;
18333
18462
  useEffect45(() => {
18334
- let timeoutId;
18335
- const startTimer = () => {
18336
- const now = /* @__PURE__ */ new Date();
18337
- const diff = Math.abs((date.getTime() - now.getTime()) / 1e3);
18338
- let delayInSeconds;
18339
- if (diff < DateUtils.timesInSeconds.minute) {
18340
- delayInSeconds = DateUtils.timesInSeconds.second;
18341
- } else if (diff < DateUtils.timesInSeconds.hour) {
18342
- delayInSeconds = DateUtils.timesInSeconds.minute;
18343
- } else {
18344
- delayInSeconds = DateUtils.timesInSeconds.hour;
18345
- }
18346
- timeoutId = setInterval(() => {
18347
- setDateAndTimeStrings({
18348
- compareDate: date,
18349
- absolute: DateUtils.formatAbsolute(date, locale, absoluteFormat),
18350
- relative: DateUtils.formatRelative(date, locale)
18351
- });
18352
- }, delayInSeconds * 1e3 / 2);
18353
- };
18354
- startTimer();
18355
- return () => clearInterval(timeoutId);
18356
- }, [absoluteFormat, date, locale]);
18357
- return {
18358
- absolute: dateAndTimeStrings.absolute,
18359
- relative: dateAndTimeStrings.relative
18360
- };
18361
- };
18362
-
18363
- // src/utils/emailValidation.ts
18364
- var validateEmail = (email) => {
18365
- return /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(email);
18366
- };
18367
-
18368
- // src/hooks/useValidators.ts
18369
- import { useMemo as useMemo31 } from "react";
18370
- var notEmpty = (value) => {
18371
- if (!value) {
18372
- return "notEmpty";
18373
- }
18374
- };
18375
- var boundsValidator = (length, bounds) => {
18376
- const [min, max] = bounds;
18377
- if (min !== void 0 && max !== void 0 && (length === void 0 || length < min || length > max)) {
18378
- return "range";
18379
- }
18380
- if (min !== void 0 && (length === void 0 || length < min)) {
18381
- return "lower";
18382
- }
18383
- if (max !== void 0 && length !== void 0 && length > max) {
18384
- return "upper";
18385
- }
18386
- return "none";
18387
- };
18388
- var lengthValidator = (value, bounds) => {
18389
- const mapping = {
18390
- range: "outOfRangeString",
18391
- lower: "tooShort",
18392
- upper: "tooLong",
18393
- none: void 0
18394
- };
18395
- return mapping[boundsValidator(value?.length, bounds)];
18396
- };
18397
- var selectionValidator = (value, bounds) => {
18398
- const mapping = {
18399
- range: "outOfRangeSelectionItems",
18400
- lower: "tooFewSelectionItems",
18401
- upper: "tooManySelectionItems",
18402
- none: void 0
18403
- };
18404
- return mapping[boundsValidator(value?.length, bounds)];
18405
- };
18406
- var emailValidator = (value) => {
18407
- if (!value || !validateEmail(value)) {
18408
- return "invalidEmail";
18409
- }
18410
- };
18411
- var UseValidators = {
18412
- notEmpty,
18413
- length: lengthValidator,
18414
- email: emailValidator,
18415
- selection: selectionValidator
18416
- };
18417
- var useTranslatedValidators = () => {
18418
- const translation = useHightideTranslation();
18419
- return useMemo31(() => ({
18420
- notEmpty: (value) => {
18421
- const result = notEmpty(value);
18422
- if (result) {
18423
- return translation(result);
18424
- }
18425
- },
18426
- length: (value, length) => {
18427
- const [min, max] = length;
18428
- const result = lengthValidator(value, length);
18429
- if (result) {
18430
- return translation(result, { min, max });
18431
- }
18432
- },
18433
- email: (value) => {
18434
- const result = emailValidator(value ?? "");
18435
- if (result) {
18436
- return translation(result);
18437
- }
18463
+ setIsOpen(show);
18464
+ setIsTransitioning(true);
18465
+ }, [show]);
18466
+ const onAnimationEnd = () => setIsTransitioning(false);
18467
+ const bag = {
18468
+ isOpen,
18469
+ isTransitioning,
18470
+ isUsingReducedMotion,
18471
+ data: {
18472
+ "data-open": isOpen && !isTransitioning ? "" : void 0,
18473
+ "data-opening": isOpen && isTransitioning ? "" : void 0,
18474
+ "data-closing": !isOpen && isTransitioning ? "" : void 0,
18475
+ "data-closed": !isOpen && !isTransitioning ? "" : void 0
18438
18476
  },
18439
- selection: (value, length) => {
18440
- const [min, max] = length;
18441
- const result = selectionValidator(value, length);
18442
- if (result) {
18443
- return translation(
18444
- result,
18445
- { min, max }
18446
- );
18447
- }
18477
+ handlers: {
18478
+ onTransitionEnd: () => setIsTransitioning(false),
18479
+ onTransitionCancel: () => setIsTransitioning(false),
18480
+ onAnimationEnd: includeAnimation ? onAnimationEnd : void 0
18448
18481
  }
18449
- }), [translation]);
18482
+ };
18483
+ return BagFunctionUtil.resolve(children, bag);
18484
+ }
18485
+
18486
+ // src/global-contexts/HightideProvider.tsx
18487
+ import { jsx as jsx95 } from "react/jsx-runtime";
18488
+ var HightideProvider = ({
18489
+ children,
18490
+ theme,
18491
+ locale,
18492
+ config
18493
+ }) => {
18494
+ return /* @__PURE__ */ jsx95(LocaleProvider, { ...locale, children: /* @__PURE__ */ jsx95(ThemeProvider, { ...theme, children: /* @__PURE__ */ jsx95(HightideConfigProvider, { ...config, children }) }) });
18450
18495
  };
18451
18496
 
18452
18497
  // src/utils/builder.ts