@povio/ui 2.3.0-rc.3 → 2.3.0-rc.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.
@@ -12,6 +12,7 @@ import { FormField } from "../../FormField/FormField.js";
12
12
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
13
13
  import { InputFrame } from "../../Skeleton/InputFrame.js";
14
14
  import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
15
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
15
16
  import { jsx, jsxs } from "react/jsx-runtime";
16
17
  import { clsx } from "clsx";
17
18
  import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
@@ -69,6 +70,7 @@ var DatePickerBase = (props) => {
69
70
  const handleBlur = (val) => {
70
71
  onBlur?.({ target: { value: val } });
71
72
  };
73
+ const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
72
74
  const dialogState = useDatePickerState({
73
75
  ...rest,
74
76
  defaultValue: value || rest.defaultValue,
@@ -88,6 +90,7 @@ var DatePickerBase = (props) => {
88
90
  }
89
91
  onChange?.(normalizedValue);
90
92
  dialogState.setValue(normalizedValue);
93
+ debouncedBlur(normalizedValue);
91
94
  if (normalizedValue) {
92
95
  calendarState.setFocusedDate(normalizedValue);
93
96
  return;
@@ -313,6 +316,8 @@ var DatePicker = ({ fullIso = true, granularity = "day", minValue, maxValue, ren
313
316
  onStaticInteract: renderRealInput,
314
317
  actionContent: staticTodayIcon,
315
318
  actionContentPlacement: todayIconPlacement === "fieldLabel" ? "content-row" : "content-wrapper",
319
+ wrapContentAndTrailing: true,
320
+ contentAndTrailingClassName: "gap-2!",
316
321
  trailingClassName: "py-0! pl-0!",
317
322
  trailingContent: showDropdown ? ui.dateInput.calendarIcon : void 0,
318
323
  children: staticSegments
@@ -661,6 +661,8 @@ var DateRangePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput,
661
661
  onStaticInteract: renderRealInput,
662
662
  actionContent: staticTodayIcon,
663
663
  actionContentPlacement: todayIconPlacement === "fieldLabel" ? "content-row" : "content-wrapper",
664
+ wrapContentAndTrailing: true,
665
+ contentAndTrailingClassName: "gap-2!",
664
666
  trailingClassName: "py-0! pl-0!",
665
667
  trailingContent: showDropdown ? ui.dateInput.calendarIcon : void 0,
666
668
  children: staticSegments
@@ -304,6 +304,8 @@ var DateTimePicker = ({ fullIso = true, renderStaticInput, ...props }) => {
304
304
  onStaticInteract: renderRealInput,
305
305
  actionContent: staticTodayIcon,
306
306
  actionContentPlacement: todayIconPlacement === "fieldLabel" ? "content-row" : "content-wrapper",
307
+ wrapContentAndTrailing: true,
308
+ contentAndTrailingClassName: "gap-2!",
307
309
  trailingClassName: "py-0! pl-0!",
308
310
  trailingContent: showDropdown ? ui.dateInput.dateTimeIcon : void 0,
309
311
  children: staticSegments
@@ -209,6 +209,7 @@ var TimePicker = ({ renderStaticInput, ...props }) => {
209
209
  },
210
210
  renderStatic: true,
211
211
  onStaticInteract: renderRealInput,
212
+ wrapContentAndTrailing: true,
212
213
  trailingClassName: "py-0! pl-0!",
213
214
  trailingContent: showDropdown ? ui.dateInput.timeIcon : void 0,
214
215
  children: staticSegments
@@ -26,13 +26,14 @@ var TextInputBase = (props) => {
26
26
  const isClearable = isClearableProp ?? ui.input.isClearable;
27
27
  const textFieldRef = useRef(null);
28
28
  const { isFocusVisible } = useFocusVisible();
29
+ const inputValue = value ?? "";
29
30
  const { labelProps, inputProps } = useTextField({
30
31
  ...rest,
31
32
  label,
32
33
  isDisabled,
33
34
  isInvalid: !!error,
34
35
  isRequired,
35
- value,
36
+ value: inputValue,
36
37
  onChange,
37
38
  onBlur
38
39
  }, textFieldRef);
@@ -61,7 +62,7 @@ var TextInputBase = (props) => {
61
62
  leadingIcon,
62
63
  trailingIcon,
63
64
  isClearable,
64
- value,
65
+ value: inputValue,
65
66
  onChange,
66
67
  onBlur
67
68
  };
@@ -6,6 +6,7 @@ import { jsx } from "react/jsx-runtime";
6
6
  import { useState } from "react";
7
7
  //#region src/components/inputs/Selection/Autocomplete/QueryAutocomplete.tsx
8
8
  var QueryAutocomplete = ({ query, queryParams, queryOptions, queryMap, leadingContent, ...props }) => {
9
+ "use no memo";
9
10
  const ui = UIConfig.useConfig();
10
11
  const [search, setSearch] = useState("");
11
12
  const { onChange, ...restProps } = props;
@@ -1,4 +1,5 @@
1
1
  import { ArrowDropDownIcon } from "../../../../assets/icons/ArrowDropDown.js";
2
+ import { Typography } from "../../../text/Typography/Typography.js";
2
3
  import { UIConfig } from "../../../../config/uiConfig.context.js";
3
4
  import { InputFrame } from "../../Skeleton/InputFrame.js";
4
5
  import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
@@ -34,7 +35,7 @@ function Select({ renderStaticInput, ...props }) {
34
35
  const ui = UIConfig.useConfig();
35
36
  const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
36
37
  const rootRef = useRef(null);
37
- const { renderRealInput, replayStaticInputChange } = useStaticInputHandoff({
38
+ const { renderRealInput, replayStaticInputChange, replayStaticInputPress } = useStaticInputHandoff({
38
39
  inputRef: rootRef,
39
40
  renderInput,
40
41
  setRenderInput,
@@ -81,10 +82,17 @@ function Select({ renderStaticInput, ...props }) {
81
82
  dataHasSelection: !isEmpty,
82
83
  dataHasSearch: false
83
84
  };
84
- const buttonContent = isMultiple && !isEmpty ? /* @__PURE__ */ jsx(Fragment, { children: "\xA0" }) : isEmpty ? /* @__PURE__ */ jsx("span", {
85
- className: "text-text-default-3",
85
+ const buttonContent = isMultiple && !isEmpty ? /* @__PURE__ */ jsx(Fragment, { children: "\xA0" }) : isEmpty ? /* @__PURE__ */ jsx(Typography, {
86
+ size: "label-1",
87
+ as: "span",
88
+ className: "block truncate text-text-default-3",
86
89
  children: placeholder
87
- }) : displayValue;
90
+ }) : /* @__PURE__ */ jsx(Typography, {
91
+ size: "label-1",
92
+ as: "span",
93
+ className: "block truncate",
94
+ children: displayValue
95
+ });
88
96
  return /* @__PURE__ */ jsx(InputFrame, {
89
97
  ...props,
90
98
  isDisabled,
@@ -111,7 +119,7 @@ function Select({ renderStaticInput, ...props }) {
111
119
  "aria-expanded": false,
112
120
  value: inputValue,
113
121
  placeholder: shouldRenderPlaceholderAfterValue ? props.placeholder : placeholder ?? void 0,
114
- className: clsx("w-full flex-1 bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.inputClassName),
122
+ className: clsx("w-full flex-1 bg-transparent text-label-1 outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.inputClassName),
115
123
  onChange: (event) => replayStaticInputChange(event.target.value),
116
124
  ...dataAttributeProps,
117
125
  "data-rac": true
@@ -121,6 +129,7 @@ function Select({ renderStaticInput, ...props }) {
121
129
  tabIndex: -1,
122
130
  "data-type": "select-trigger",
123
131
  className: clsx("w-full truncate bg-transparent text-start outline-none disabled:text-interactive-text-secondary-disabled", isMultiple && !isEmpty && "absolute inset-0 z-0"),
132
+ onPointerDown: replayStaticInputPress,
124
133
  ...dataAttributeProps,
125
134
  "data-rac": true,
126
135
  children: buttonContent
@@ -3,4 +3,4 @@ import { Key } from 'react-aria-components';
3
3
  import { SelectItem } from './select.types';
4
4
  export type QueryFn<TData = any> = (...args: any[]) => UseQueryResult<TData> | UseInfiniteQueryResult<TData>;
5
5
  export type QueryDataType<TQueryFn extends QueryFn> = Exclude<ReturnType<TQueryFn>["data"], undefined>;
6
- export declare const getQueryItems: <TQueryFn extends QueryFn, TKey extends Key = Key>(data: QueryDataType<TQueryFn> | undefined, queryMap?: (data: QueryDataType<TQueryFn>) => SelectItem<TKey>[]) => SelectItem<TKey>[];
6
+ export declare const getQueryItems: <TQueryFn extends QueryFn, TKey extends Key = Key>(data: QueryDataType<TQueryFn> | undefined, queryMap?: (data: QueryDataType<TQueryFn>) => SelectItem<TKey>[]) => any;
@@ -1,8 +1,14 @@
1
1
  //#region src/components/inputs/Selection/shared/querySelect.utils.ts
2
+ var isQueryItemsPage = (page) => {
3
+ return !!page && typeof page === "object" && "items" in page && Array.isArray(page.items);
4
+ };
2
5
  var getQueryItems = (data, queryMap) => {
3
6
  if (!data) return [];
4
7
  if (queryMap) return queryMap(data);
5
- if (Array.isArray(data)) return data;
8
+ if (Array.isArray(data)) {
9
+ if (data.every(isQueryItemsPage)) return data.flatMap((page) => page.items);
10
+ return data;
11
+ }
6
12
  if (typeof data === "object" && data !== null) {
7
13
  if ("items" in data && Array.isArray(data.items)) return data.items;
8
14
  if ("pages" in data && Array.isArray(data.pages)) return data.pages.flatMap((page) => page && typeof page === "object" && "items" in page && Array.isArray(page.items) ? page.items : []);
@@ -1,5 +1,5 @@
1
- import { useSelectItems } from "./useSelectItems.js";
2
1
  import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
2
+ import { useSelectItems } from "./useSelectItems.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { createContext, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
5
5
  //#region src/components/inputs/Selection/shared/select.context.tsx
@@ -69,6 +69,7 @@ export interface InputFrameProps extends InputVariantProps, Partial<FormFieldPro
69
69
  inputClassName?: string;
70
70
  contentClassName?: string;
71
71
  contentWrapperClassName?: string;
72
+ contentAndTrailingClassName?: string;
72
73
  wrapContentAndTrailing?: boolean;
73
74
  labelPlacement?: InputFrameLabelPlacement;
74
75
  trailingClassName?: string;
@@ -19,7 +19,7 @@ var InputFrame = (props) => {
19
19
  const inputContentWrapperCva = UIStyle.useCva("input.contentWrapperCva", inputContentWrapper);
20
20
  const typographyCva = UIStyle.useCva("typography.cva", typography);
21
21
  const generatedInputId = useId();
22
- const { ref, children, formFieldRef, labelProps: labelPropsProp, headerProps, error, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isHeaderHidden, hideLabel: hideLabelProp, headerClassName, errorClassName, className, leadingContent, leadingIcon, actionContent, actionContentPlacement = "content-wrapper", trailingContent, trailingIcon, trailingAction, unit, isLoading, action, isClearable: isClearableProp, showClear, renderStatic, onStaticInteract, clearClassName, onClear, dataAttributes, typographySize, id: idProp, inputClassName, contentClassName, contentWrapperClassName, wrapContentAndTrailing, labelPlacement = "content-wrapper", trailingClassName, onMouseEnter, onFocusCapture, variant: variantProp, as: asProp, size: sizeProp } = props;
22
+ const { ref, children, formFieldRef, labelProps: labelPropsProp, headerProps, error, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isHeaderHidden, hideLabel: hideLabelProp, headerClassName, errorClassName, className, leadingContent, leadingIcon, actionContent, actionContentPlacement = "content-wrapper", trailingContent, trailingIcon, trailingAction, unit, isLoading, action, isClearable: isClearableProp, showClear, renderStatic, onStaticInteract, clearClassName, onClear, dataAttributes, typographySize, id: idProp, inputClassName, contentClassName, contentWrapperClassName, contentAndTrailingClassName, wrapContentAndTrailing, labelPlacement = "content-wrapper", trailingClassName, onMouseEnter, onFocusCapture, variant: variantProp, as: asProp, size: sizeProp } = props;
23
23
  const as = asProp ?? ui.input.as;
24
24
  const size = sizeProp ?? ui.input.size;
25
25
  const variant = variantProp ?? ui.input.variant;
@@ -136,7 +136,7 @@ var InputFrame = (props) => {
136
136
  ]
137
137
  }) : null;
138
138
  const inputFrameContent = wrapContentAndTrailing ? /* @__PURE__ */ jsxs("div", {
139
- className: "flex w-full items-center gap-input-gap-input-text-to-elements",
139
+ className: clsx("flex w-full items-center gap-input-gap-input-text-to-elements", contentAndTrailingClassName),
140
140
  children: [contentRow, trailingRow]
141
141
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [contentRow, trailingRow] });
142
142
  return /* @__PURE__ */ jsx(TooltipWrapper, {
@@ -9,5 +9,6 @@ export declare const useStaticInputHandoff: <TElement extends HTMLElement = HTML
9
9
  shouldFocus: boolean;
10
10
  renderRealInput: (focus: boolean) => void;
11
11
  replayStaticInputChange: (value: string) => void;
12
+ replayStaticInputPress: () => void;
12
13
  };
13
14
  export {};
@@ -3,18 +3,23 @@ import { useLayoutEffect, useRef, useState } from "react";
3
3
  var useStaticInputHandoff = ({ inputRef, renderInput, setRenderInput, getFocusTarget }) => {
4
4
  const [shouldFocus, setShouldFocus] = useState(false);
5
5
  const pendingStaticChangeRef = useRef(null);
6
+ const shouldReplayStaticPressRef = useRef(false);
6
7
  useLayoutEffect(() => {
7
8
  if (!renderInput || !shouldFocus) return;
8
- const focusRealInput = (replayPendingChange) => {
9
+ const focusRealInput = (replayPendingInteraction) => {
9
10
  const input = inputRef.current;
10
11
  const pendingValue = pendingStaticChangeRef.current;
11
12
  const focusTarget = input ? getFocusTarget?.(input) ?? input : null;
12
- if (replayPendingChange && focusTarget instanceof HTMLInputElement && pendingValue != null) {
13
+ if (replayPendingInteraction && focusTarget instanceof HTMLInputElement && pendingValue != null) {
13
14
  (Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set)?.call(focusTarget, pendingValue);
14
15
  focusTarget.dispatchEvent(new Event("input", { bubbles: true }));
15
16
  pendingStaticChangeRef.current = null;
16
17
  }
17
18
  focusTarget?.focus();
19
+ if (replayPendingInteraction && shouldReplayStaticPressRef.current) {
20
+ shouldReplayStaticPressRef.current = false;
21
+ focusTarget?.click();
22
+ }
18
23
  };
19
24
  focusRealInput(true);
20
25
  const frame = requestAnimationFrame(() => {
@@ -40,6 +45,11 @@ var useStaticInputHandoff = ({ inputRef, renderInput, setRenderInput, getFocusTa
40
45
  pendingStaticChangeRef.current = value;
41
46
  setShouldFocus(true);
42
47
  setRenderInput(true);
48
+ },
49
+ replayStaticInputPress: () => {
50
+ shouldReplayStaticPressRef.current = true;
51
+ setShouldFocus(true);
52
+ setRenderInput(true);
43
53
  }
44
54
  };
45
55
  };
@@ -1,3 +1,4 @@
1
+ "use no memo";
1
2
  import { ChevronDownIcon } from "../../assets/icons/ChevronDown.js";
2
3
  import { ChevronUpIcon } from "../../assets/icons/ChevronUp.js";
3
4
  import { UIStyle } from "../../config/uiStyle.context.js";
@@ -26,8 +27,8 @@ var CustomCellContext = (context) => {
26
27
  value: context.getValue()
27
28
  };
28
29
  };
29
- var CellRender = (Comp, props) => {
30
- const rendered = typeof Comp === "function" ? Comp(props) : Comp;
30
+ var renderCell = (Comp, props) => {
31
+ const rendered = flexRender(Comp, props);
31
32
  return typeof rendered === "string" ? /* @__PURE__ */ jsx(CellText, { children: rendered }) : rendered;
32
33
  };
33
34
  var RowDragHandleCell = ({ rowId }) => {
@@ -68,7 +69,7 @@ var DraggableRow = ({ row, showCellBorder, onRowClick, onDoubleClick, tableRowCv
68
69
  return /* @__PURE__ */ jsx("td", {
69
70
  tabIndex: -1,
70
71
  className: clsx(tableDataCva({ hasRightBorder: cellIndex > 0 && showCellBorder }), columnMeta.cellClass, columnMeta.width),
71
- children: CellRender(cell.column.columnDef.cell, CustomCellContext(cell.getContext()))
72
+ children: renderCell(cell.column.columnDef.cell, CustomCellContext(cell.getContext()))
72
73
  }, cell.id);
73
74
  })
74
75
  });
@@ -245,7 +246,7 @@ var Table = ({ items, showCellBorder, columns, onRowClick, onDoubleClick, classN
245
246
  return /* @__PURE__ */ jsx("td", {
246
247
  tabIndex: -1,
247
248
  className: clsx(tableDataCva({ hasRightBorder: cellIndex > 0 && showCellBorder }), columnMeta.cellClass, columnMeta.width),
248
- children: CellRender(cell.column.columnDef.cell, CustomCellContext(cell.getContext()))
249
+ children: renderCell(cell.column.columnDef.cell, CustomCellContext(cell.getContext()))
249
250
  }, cell.id);
250
251
  })
251
252
  }, row.id);
@@ -5,6 +5,7 @@ var isFilterSearchParams = (params) => {
5
5
  return typeof params === "object" && params !== null && "filter" in params;
6
6
  };
7
7
  var useQueryAutocomplete = ({ query, queryParams, queryOptions, mapItems, initialQueryState, search }) => {
8
+ "use no memo";
8
9
  const [isQueryEnabled, setIsQueryEnabled] = useState(!initialQueryState);
9
10
  const queryResult = query(search === void 0 ? queryParams : {
10
11
  ...queryParams,
@@ -34,7 +35,7 @@ var useQueryAutocomplete = ({ query, queryParams, queryOptions, mapItems, initia
34
35
  const totalItems = infiniteQueryResult?.data?.pages?.[0]?.totalItems;
35
36
  const items = useMemo(() => {
36
37
  if (!data) return [];
37
- return mapItems(isInfiniteQuery ? data.pages?.flatMap((page) => page?.items ?? []) : data);
38
+ return mapItems(isInfiniteQuery ? data.pages : data);
38
39
  }, [
39
40
  data,
40
41
  isInfiniteQuery,
package/dist/index.js CHANGED
@@ -69,9 +69,9 @@ import { useLongPressRepeat } from "./hooks/useLongPressRepeat.js";
69
69
  import { useScrollableListBox } from "./hooks/useScrollableListBox.js";
70
70
  import { DateTimeUtils } from "./utils/date-time.utils.js";
71
71
  import { FormField } from "./components/inputs/FormField/FormField.js";
72
+ import { useDebounceCallback } from "./hooks/useDebounceCallback.js";
72
73
  import { DatePicker } from "./components/inputs/DateTime/DatePicker/DatePicker.js";
73
74
  import { Tag } from "./components/text/Tag/Tag.js";
74
- import { useDebounceCallback } from "./hooks/useDebounceCallback.js";
75
75
  import { useIntersectionObserver } from "./hooks/useIntersectionObserver.js";
76
76
  import { TextInput } from "./components/inputs/Input/TextInput/TextInput.js";
77
77
  import { Select } from "./components/inputs/Selection/Select/Select.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@povio/ui",
3
- "version": "2.3.0-rc.3",
3
+ "version": "2.3.0-rc.5",
4
4
  "type": "module",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",