@povio/ui 3.2.4-rc.1 → 3.2.4-rc.11

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.
Files changed (27) hide show
  1. package/dist/components/buttons/Button/button.cva.d.ts +1 -1
  2. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +2 -2
  3. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +2 -2
  4. package/dist/components/inputs/DateTime/shared/useFirefoxDateSegmentSelectionGuard.d.ts +2 -0
  5. package/dist/components/inputs/DateTime/shared/useFirefoxDateSegmentSelectionGuard.js +33 -0
  6. package/dist/components/inputs/Input/NumberInput/NumberInput.js +2 -1
  7. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +2 -1
  8. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +56 -2
  9. package/dist/components/inputs/Selection/Select/QuerySelect.js +69 -15
  10. package/dist/components/inputs/Selection/shared/SelectDesktop.js +160 -390
  11. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -1
  12. package/dist/components/inputs/Selection/shared/SelectInput.js +142 -131
  13. package/dist/components/inputs/Selection/shared/querySelect.utils.d.ts +1 -0
  14. package/dist/components/inputs/Selection/shared/querySelect.utils.js +1 -0
  15. package/dist/components/inputs/Selection/shared/select.context.js +19 -9
  16. package/dist/components/inputs/shared/input.cva.js +1 -1
  17. package/dist/components/shared/pagination/minWidth.cva.d.ts +1 -1
  18. package/dist/helpers/dynamicColumns.js +2 -1
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.js +2 -1
  21. package/dist/utils/date-time.utils.js +21 -11
  22. package/dist/utils/intl.utils.d.ts +7 -0
  23. package/dist/utils/intl.utils.js +38 -0
  24. package/dist/utils/intl.utils.spec.d.ts +1 -0
  25. package/package.json +1 -1
  26. package/dist/components/inputs/DateTime/shared/usePreserveExternalFocusOnUnmount.d.ts +0 -2
  27. package/dist/components/inputs/DateTime/shared/usePreserveExternalFocusOnUnmount.js +0 -32
@@ -92,7 +92,7 @@ export declare const buttonIconSizeDefinition: {
92
92
  export type ButtonIconSizeConfig = NonNullable<typeof buttonIconSizeDefinition.config>;
93
93
  export declare const buttonTypography: (props: {
94
94
  readonly width?: "fill" | "hug" | null | undefined;
95
- readonly size?: "none" | "s" | "xs" | "m" | "l" | null | undefined;
95
+ readonly size?: "none" | "xs" | "s" | "m" | "l" | null | undefined;
96
96
  readonly color?: "error" | "primary" | "dual" | "secondary" | "success" | "warning" | null | undefined;
97
97
  readonly variant?: "text" | "contained" | "outlined" | "subtle" | "ghost" | null | undefined;
98
98
  readonly inverted?: boolean | null | undefined;
@@ -8,7 +8,7 @@ import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
8
8
  import { DateField } from "./DateField.js";
9
9
  import { datePickerInputContentRowDefinition } from "./datePickerInput.cva.js";
10
10
  import { renderDatePickerTodayIcon } from "./datePickerTodayIcon.js";
11
- import { usePreserveExternalFocusOnUnmount } from "./usePreserveExternalFocusOnUnmount.js";
11
+ import { useFirefoxDateSegmentSelectionGuard } from "./useFirefoxDateSegmentSelectionGuard.js";
12
12
  import { InputClear } from "../../shared/InputClear.js";
13
13
  import { c } from "react/compiler-runtime";
14
14
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -59,7 +59,7 @@ var DatePickerInput = (t0) => {
59
59
  const dateFieldRef = useRef(null);
60
60
  const endDateFieldRef = useRef(null);
61
61
  const containerRef = useRef(null);
62
- usePreserveExternalFocusOnUnmount(containerRef);
62
+ useFirefoxDateSegmentSelectionGuard(containerRef);
63
63
  const t8 = isValueControlled ? fieldValue ?? null : fieldProps.value ?? null;
64
64
  let t9;
65
65
  if ($[4] !== autoFixYear || $[5] !== fieldProps || $[6] !== t8) {
@@ -4,7 +4,7 @@ import { UIConfig } from "../../../../config/uiConfig.context.js";
4
4
  import { InlineIconButton } from "../../../buttons/InlineIconButton/InlineIconButton.js";
5
5
  import { FormFieldLabel } from "../../FormField/FormFieldLabel.js";
6
6
  import { inputBaseDefinition, inputSizeDefinition } from "../../shared/input.cva.js";
7
- import { usePreserveExternalFocusOnUnmount } from "./usePreserveExternalFocusOnUnmount.js";
7
+ import { useFirefoxDateSegmentSelectionGuard } from "./useFirefoxDateSegmentSelectionGuard.js";
8
8
  import { InputClear } from "../../shared/InputClear.js";
9
9
  import { TimeField } from "./TimeField.js";
10
10
  import { c } from "react/compiler-runtime";
@@ -37,7 +37,7 @@ var TimePickerInput = (t0) => {
37
37
  const { focusWithinProps } = useFocusWithin(t2);
38
38
  const { isFocusVisible } = useFocusVisible();
39
39
  const containerRef = useRef(null);
40
- usePreserveExternalFocusOnUnmount(containerRef);
40
+ useFirefoxDateSegmentSelectionGuard(containerRef);
41
41
  const hidePlaceholder = as === "floating" && !state.value && !isFocused;
42
42
  let t3;
43
43
  if ($[3] !== state.segments) {
@@ -0,0 +1,2 @@
1
+ import { RefObject } from 'react';
2
+ export declare const useFirefoxDateSegmentSelectionGuard: (containerRef: RefObject<HTMLElement | null>) => void;
@@ -0,0 +1,33 @@
1
+ import { c } from "react/compiler-runtime";
2
+ import { useLayoutEffect } from "react";
3
+ import { isFirefox } from "@react-aria/utils";
4
+ //#region src/components/inputs/DateTime/shared/useFirefoxDateSegmentSelectionGuard.ts
5
+ var isEditableElement = (element) => element instanceof HTMLElement && (element.matches("input, textarea") || element.isContentEditable);
6
+ var useFirefoxDateSegmentSelectionGuard = (containerRef) => {
7
+ const $ = c(3);
8
+ let t0;
9
+ let t1;
10
+ if ($[0] !== containerRef) {
11
+ t0 = () => {
12
+ const container = containerRef.current;
13
+ if (!container || !isFirefox()) return;
14
+ const onSelectionChange = (event) => {
15
+ const activeElement = document.activeElement;
16
+ const selection = window.getSelection();
17
+ if (isEditableElement(activeElement) && !container.contains(activeElement) && selection?.anchorNode && container.contains(selection.anchorNode)) event.stopImmediatePropagation();
18
+ };
19
+ document.addEventListener("selectionchange", onSelectionChange, true);
20
+ return () => document.removeEventListener("selectionchange", onSelectionChange, true);
21
+ };
22
+ t1 = [containerRef];
23
+ $[0] = containerRef;
24
+ $[1] = t0;
25
+ $[2] = t1;
26
+ } else {
27
+ t0 = $[1];
28
+ t1 = $[2];
29
+ }
30
+ useLayoutEffect(t0, t1);
31
+ };
32
+ //#endregion
33
+ export { useFirefoxDateSegmentSelectionGuard };
@@ -2,6 +2,7 @@ import { UIOverrides } from "../../../../config/uiOverrides.context.js";
2
2
  import { UIConfig } from "../../../../config/uiConfig.context.js";
3
3
  import { FormField } from "../../FormField/FormField.js";
4
4
  import { inputBaseDefinition } from "../../shared/input.cva.js";
5
+ import { IntlUtils } from "../../../../utils/intl.utils.js";
5
6
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
6
7
  import { InputFrame } from "../../Skeleton/InputFrame.js";
7
8
  import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
@@ -338,7 +339,7 @@ var NumberInputInner = (t0) => {
338
339
  if (!renderInput) {
339
340
  const staticValue = props.value ?? props.defaultValue;
340
341
  const formatOptions = props.formatOptions ?? ui.numberInput.formatOptions;
341
- const displayValue = getStaticNumberDisplayValue(staticValue, new Intl.NumberFormat(locale, formatOptions)) ?? "";
342
+ const displayValue = getStaticNumberDisplayValue(staticValue, IntlUtils.getNumberFormatter(locale, formatOptions)) ?? "";
342
343
  const hasValue = displayValue !== "";
343
344
  const as = props.as ?? ui.input.as;
344
345
  let isDisabled = !!props.isDisabled;
@@ -2,6 +2,7 @@ import { UIOverrides } from "../../../../config/uiOverrides.context.js";
2
2
  import { UIConfig } from "../../../../config/uiConfig.context.js";
3
3
  import { FormFieldLabel } from "../../FormField/FormFieldLabel.js";
4
4
  import { inputBaseDefinition, inputSizeDefinition } from "../../shared/input.cva.js";
5
+ import { IntlUtils } from "../../../../utils/intl.utils.js";
5
6
  import { InputClear } from "../../shared/InputClear.js";
6
7
  import { InputFrame } from "../../Skeleton/InputFrame.js";
7
8
  import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
@@ -381,7 +382,7 @@ var NumberRangeInputInner = (t0) => {
381
382
  if (!renderInput) {
382
383
  const staticValue = normalizeRangeValue(props.value, props.minValue, props.maxValue);
383
384
  const formatOptions = props.formatOptions ?? ui.numberInput.formatOptions;
384
- const formatter = new Intl.NumberFormat(locale, formatOptions);
385
+ const formatter = IntlUtils.getNumberFormatter(locale, formatOptions);
385
386
  const minDisplay = getStaticNumberDisplayValue(staticValue.min, formatter);
386
387
  const maxDisplay = getStaticNumberDisplayValue(staticValue.max, formatter);
387
388
  const hasValue = minDisplay !== null || maxDisplay !== null;
@@ -8,7 +8,7 @@ import { useState } from "react";
8
8
  import { mergeRefs } from "@react-aria/utils";
9
9
  import { Controller } from "react-hook-form";
10
10
  //#region src/components/inputs/Selection/Autocomplete/QueryAutocomplete.tsx
11
- var QueryAutocompleteContent = ({ query, queryParams, queryOptions, queryMap, resolveSelectedItemsWithIds, leadingContent, ...props }) => {
11
+ var LoadedQueryAutocompleteContent = ({ query, queryParams, queryOptions, queryMap, resolveSelectedItemsWithIds, isQueryEnabledInitially = false, leadingContent, ...props }) => {
12
12
  "use no memo";
13
13
  const ui = UIConfig.useConfig();
14
14
  const [search, setSearch] = useState("");
@@ -20,6 +20,8 @@ var QueryAutocompleteContent = ({ query, queryParams, queryOptions, queryMap, re
20
20
  mapInitialToSelectItem: props.mapInitialToSelectItem
21
21
  });
22
22
  const shouldEnableInitialQuery = selectedIdsToResolve.count > 0;
23
+ const isInitialQueryDisabled = props.isInitialQueryDisabled ?? ui.queryAutocomplete?.isInitialQueryDisabled;
24
+ const shouldDisableInitialQuery = !isQueryEnabledInitially && !shouldEnableInitialQuery && (selectedIdsToResolve.isResolvedByInitialSelection || isInitialQueryDisabled);
23
25
  const { items, totalItems, isLoading, handleEnableQuery, hasNextPage, fetchNextPage } = useQueryAutocomplete({
24
26
  query,
25
27
  queryParams,
@@ -27,7 +29,7 @@ var QueryAutocompleteContent = ({ query, queryParams, queryOptions, queryMap, re
27
29
  mapItems: (data) => getQueryItems(data, queryMap),
28
30
  resolveSelectedItemsWithIds: resolveSelectedItemsWithIds ?? ui.queryAutocomplete?.resolveSelectedItemsWithIds,
29
31
  search,
30
- initialQueryState: shouldEnableInitialQuery ? false : props.isInitialQueryDisabled ?? ui.queryAutocomplete?.isInitialQueryDisabled,
32
+ initialQueryState: shouldDisableInitialQuery,
31
33
  selectedIdsToResolve: selectedIdsToResolve.items
32
34
  });
33
35
  const handleChange = (value_0) => {
@@ -55,6 +57,58 @@ var QueryAutocompleteContent = ({ query, queryParams, queryOptions, queryMap, re
55
57
  onLoadMore: fetchNextPage
56
58
  });
57
59
  };
60
+ var QueryAutocompleteContent = (props) => {
61
+ const $ = c(9);
62
+ const [isQueryMounted, setIsQueryMounted] = useState(false);
63
+ const value = "value" in props ? props.value : void 0;
64
+ if (!getSelectionIdsToResolve({
65
+ initialSelection: props.initialSelection,
66
+ value,
67
+ mapInitialToSelectItem: props.mapInitialToSelectItem
68
+ }).isResolvedByInitialSelection || isQueryMounted) {
69
+ let t0;
70
+ if ($[0] !== isQueryMounted || $[1] !== props) {
71
+ t0 = /* @__PURE__ */ jsx(LoadedQueryAutocompleteContent, {
72
+ ...props,
73
+ isQueryEnabledInitially: isQueryMounted
74
+ });
75
+ $[0] = isQueryMounted;
76
+ $[1] = props;
77
+ $[2] = t0;
78
+ } else t0 = $[2];
79
+ return t0;
80
+ }
81
+ let autocompleteProps;
82
+ if ($[3] !== props) {
83
+ const { query: _, queryParams: _queryParams, queryOptions: _queryOptions, queryMap: _queryMap, resolveSelectedItemsWithIds: _resolveSelectedItemsWithIds, isInitialQueryDisabled: _isInitialQueryDisabled, ...t0 } = props;
84
+ autocompleteProps = t0;
85
+ $[3] = props;
86
+ $[4] = autocompleteProps;
87
+ } else autocompleteProps = $[4];
88
+ let t0;
89
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
90
+ t0 = () => setIsQueryMounted(true);
91
+ $[5] = t0;
92
+ } else t0 = $[5];
93
+ const mountQuery = t0;
94
+ let t1;
95
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
96
+ t1 = [];
97
+ $[6] = t1;
98
+ } else t1 = $[6];
99
+ let t2;
100
+ if ($[7] !== autocompleteProps) {
101
+ t2 = /* @__PURE__ */ jsx(Autocomplete, {
102
+ ...autocompleteProps,
103
+ items: t1,
104
+ onMouseEnter: mountQuery,
105
+ onFocusCapture: mountQuery
106
+ });
107
+ $[7] = autocompleteProps;
108
+ $[8] = t2;
109
+ } else t2 = $[8];
110
+ return t2;
111
+ };
58
112
  var QueryAutocomplete = (props) => {
59
113
  const $ = c(16);
60
114
  if ("formControl" in props && props.formControl) {
@@ -8,9 +8,10 @@ import { useState } from "react";
8
8
  import { mergeRefs } from "@react-aria/utils";
9
9
  import { Controller } from "react-hook-form";
10
10
  //#region src/components/inputs/Selection/Select/QuerySelect.tsx
11
- var QuerySelectContent = (t0) => {
11
+ var LoadedQuerySelectContent = (t0) => {
12
12
  const $ = c(31);
13
- const { query, queryParams, queryOptions, queryMap, resolveSelectedItemsWithIds, ...props } = t0;
13
+ const { query, queryParams, queryOptions, queryMap, resolveSelectedItemsWithIds, isQueryEnabledInitially: t1, ...props } = t0;
14
+ const isQueryEnabledInitially = t1 === void 0 ? false : t1;
14
15
  const ui = UIConfig.useConfig();
15
16
  const [search, setSearch] = useState("");
16
17
  const isSearchable = props.isSearchable ?? ui.select.isSearchable;
@@ -21,32 +22,33 @@ var QuerySelectContent = (t0) => {
21
22
  mapInitialToSelectItem: props.mapInitialToSelectItem
22
23
  });
23
24
  const shouldEnableInitialQuery = selectedIdsToResolve.count > 0;
24
- let t1;
25
+ const isInitialQueryDisabled = props.isInitialQueryDisabled ?? ui.querySelect?.isInitialQueryDisabled;
26
+ const shouldDisableInitialQuery = !isQueryEnabledInitially && !shouldEnableInitialQuery && (selectedIdsToResolve.isResolvedByInitialSelection || isInitialQueryDisabled);
27
+ let t2;
25
28
  if ($[0] !== queryMap) {
26
- t1 = (data) => getQueryItems(data, queryMap);
29
+ t2 = (data) => getQueryItems(data, queryMap);
27
30
  $[0] = queryMap;
28
- $[1] = t1;
29
- } else t1 = $[1];
30
- const t2 = resolveSelectedItemsWithIds ?? ui.querySelect?.resolveSelectedItemsWithIds;
31
- const t3 = isSearchable ? search : void 0;
32
- const t4 = shouldEnableInitialQuery ? false : props.isInitialQueryDisabled ?? ui.querySelect?.isInitialQueryDisabled;
31
+ $[1] = t2;
32
+ } else t2 = $[1];
33
+ const t3 = resolveSelectedItemsWithIds ?? ui.querySelect?.resolveSelectedItemsWithIds;
34
+ const t4 = isSearchable ? search : void 0;
33
35
  let t5;
34
- if ($[2] !== query || $[3] !== queryOptions || $[4] !== queryParams || $[5] !== selectedIdsToResolve.items || $[6] !== t1 || $[7] !== t2 || $[8] !== t3 || $[9] !== t4) {
36
+ if ($[2] !== query || $[3] !== queryOptions || $[4] !== queryParams || $[5] !== selectedIdsToResolve.items || $[6] !== shouldDisableInitialQuery || $[7] !== t2 || $[8] !== t3 || $[9] !== t4) {
35
37
  t5 = {
36
38
  query,
37
39
  queryParams,
38
40
  queryOptions,
39
- mapItems: t1,
40
- resolveSelectedItemsWithIds: t2,
41
- search: t3,
42
- initialQueryState: t4,
41
+ mapItems: t2,
42
+ resolveSelectedItemsWithIds: t3,
43
+ search: t4,
44
+ initialQueryState: shouldDisableInitialQuery,
43
45
  selectedIdsToResolve: selectedIdsToResolve.items
44
46
  };
45
47
  $[2] = query;
46
48
  $[3] = queryOptions;
47
49
  $[4] = queryParams;
48
50
  $[5] = selectedIdsToResolve.items;
49
- $[6] = t1;
51
+ $[6] = shouldDisableInitialQuery;
50
52
  $[7] = t2;
51
53
  $[8] = t3;
52
54
  $[9] = t4;
@@ -117,6 +119,58 @@ var QuerySelectContent = (t0) => {
117
119
  } else t9 = $[30];
118
120
  return t9;
119
121
  };
122
+ var QuerySelectContent = (props) => {
123
+ const $ = c(9);
124
+ const [isQueryMounted, setIsQueryMounted] = useState(false);
125
+ const value = "value" in props ? props.value : void 0;
126
+ if (!getSelectionIdsToResolve({
127
+ initialSelection: props.initialSelection,
128
+ value,
129
+ mapInitialToSelectItem: props.mapInitialToSelectItem
130
+ }).isResolvedByInitialSelection || isQueryMounted) {
131
+ let t0;
132
+ if ($[0] !== isQueryMounted || $[1] !== props) {
133
+ t0 = /* @__PURE__ */ jsx(LoadedQuerySelectContent, {
134
+ ...props,
135
+ isQueryEnabledInitially: isQueryMounted
136
+ });
137
+ $[0] = isQueryMounted;
138
+ $[1] = props;
139
+ $[2] = t0;
140
+ } else t0 = $[2];
141
+ return t0;
142
+ }
143
+ let selectProps;
144
+ if ($[3] !== props) {
145
+ const { query: _, queryParams: _queryParams, queryOptions: _queryOptions, queryMap: _queryMap, resolveSelectedItemsWithIds: _resolveSelectedItemsWithIds, isInitialQueryDisabled: _isInitialQueryDisabled, ...t0 } = props;
146
+ selectProps = t0;
147
+ $[3] = props;
148
+ $[4] = selectProps;
149
+ } else selectProps = $[4];
150
+ let t0;
151
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
152
+ t0 = () => setIsQueryMounted(true);
153
+ $[5] = t0;
154
+ } else t0 = $[5];
155
+ const mountQuery = t0;
156
+ let t1;
157
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
158
+ t1 = [];
159
+ $[6] = t1;
160
+ } else t1 = $[6];
161
+ let t2;
162
+ if ($[7] !== selectProps) {
163
+ t2 = /* @__PURE__ */ jsx(Select, {
164
+ ...selectProps,
165
+ items: t1,
166
+ onMouseEnter: mountQuery,
167
+ onFocusCapture: mountQuery
168
+ });
169
+ $[7] = selectProps;
170
+ $[8] = t2;
171
+ } else t2 = $[8];
172
+ return t2;
173
+ };
120
174
  var QuerySelect = (props) => {
121
175
  const $ = c(16);
122
176
  if ("formControl" in props && props.formControl) {