@jobber/components 9.6.1 → 9.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Autocomplete/index.cjs +2 -0
- package/dist/Autocomplete/index.mjs +2 -0
- package/dist/Autocomplete-cjs.js +5 -4
- package/dist/Autocomplete-es.js +2 -1
- package/dist/Card/index.cjs +2 -1
- package/dist/Card/index.mjs +2 -1
- package/dist/Chip/index.cjs +2 -0
- package/dist/Chip/index.mjs +2 -0
- package/dist/Chips/InternalChipDismissible/hooks/index.cjs +2 -0
- package/dist/Chips/InternalChipDismissible/hooks/index.mjs +2 -0
- package/dist/Chips/InternalChipDismissible/index.cjs +2 -0
- package/dist/Chips/InternalChipDismissible/index.mjs +2 -0
- package/dist/Chips/index.cjs +2 -0
- package/dist/Chips/index.mjs +2 -0
- package/dist/Combobox/index.cjs +4 -2
- package/dist/Combobox/index.mjs +4 -2
- package/dist/{ComboboxSeparator-cjs.js → ComboboxChipRemove-cjs.js} +455 -501
- package/dist/{ComboboxSeparator-es.js → ComboboxChipRemove-es.js} +456 -500
- package/dist/ComboboxPrimitive-cjs.js +30 -29
- package/dist/ComboboxPrimitive-es.js +3 -2
- package/dist/ConfirmationModal/index.cjs +2 -0
- package/dist/ConfirmationModal/index.mjs +2 -0
- package/dist/DataDump/index.cjs +2 -1
- package/dist/DataDump/index.mjs +2 -1
- package/dist/DataList/components/DataListActions/index.cjs +2 -0
- package/dist/DataList/components/DataListActions/index.mjs +2 -0
- package/dist/DataList/components/DataListBulkActions/index.cjs +2 -0
- package/dist/DataList/components/DataListBulkActions/index.mjs +2 -0
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +2 -0
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +2 -0
- package/dist/DataList/components/DataListFilters/index.cjs +2 -0
- package/dist/DataList/components/DataListFilters/index.mjs +2 -0
- package/dist/DataList/components/DataListHeader/index.cjs +2 -0
- package/dist/DataList/components/DataListHeader/index.mjs +2 -0
- package/dist/DataList/components/DataListItem/index.cjs +2 -0
- package/dist/DataList/components/DataListItem/index.mjs +2 -0
- package/dist/DataList/components/DataListItemActions/index.cjs +2 -0
- package/dist/DataList/components/DataListItemActions/index.mjs +2 -0
- package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +2 -0
- package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +2 -0
- package/dist/DataList/components/DataListItems/index.cjs +2 -0
- package/dist/DataList/components/DataListItems/index.mjs +2 -0
- package/dist/DataList/components/DataListLayout/index.cjs +2 -0
- package/dist/DataList/components/DataListLayout/index.mjs +2 -0
- package/dist/DataList/components/DataListLayoutActions/index.cjs +2 -0
- package/dist/DataList/components/DataListLayoutActions/index.mjs +2 -0
- package/dist/DataList/index.cjs +2 -0
- package/dist/DataList/index.mjs +2 -0
- package/dist/DatePicker/index.cjs +2 -0
- package/dist/DatePicker/index.mjs +2 -0
- package/dist/DatePicker-cjs.js +5 -4
- package/dist/DatePicker-es.js +2 -1
- package/dist/Dialog/index.cjs +2 -1
- package/dist/Dialog/index.mjs +2 -1
- package/dist/DrawerDescription-cjs.js +99 -268
- package/dist/DrawerDescription-es.js +103 -270
- package/dist/DrawerTitle-cjs.js +6 -2
- package/dist/DrawerTitle-es.js +7 -3
- package/dist/FieldDescription-cjs.js +181 -184
- package/dist/FieldDescription-es.js +184 -187
- package/dist/FilterPicker/components/FilterPickerActivator/index.cjs +2 -0
- package/dist/FilterPicker/components/FilterPickerActivator/index.mjs +2 -0
- package/dist/FilterPicker/components/FilterPickerContent/index.cjs +2 -0
- package/dist/FilterPicker/components/FilterPickerContent/index.mjs +2 -0
- package/dist/FilterPicker/components/FilterPickerTrigger/index.cjs +2 -0
- package/dist/FilterPicker/components/FilterPickerTrigger/index.mjs +2 -0
- package/dist/FilterPicker/index.cjs +2 -0
- package/dist/FilterPicker/index.mjs +2 -0
- package/dist/FilterPickerContent-cjs.js +5 -4
- package/dist/FilterPickerContent-es.js +2 -1
- package/dist/FormatFile/index.cjs +2 -0
- package/dist/FormatFile/index.mjs +2 -0
- package/dist/Gallery/index.cjs +2 -0
- package/dist/Gallery/index.mjs +2 -0
- package/dist/InputDate/index.cjs +2 -0
- package/dist/InputDate/index.mjs +2 -0
- package/dist/InputNumber/index.cjs +2 -1
- package/dist/InputNumber/index.mjs +2 -1
- package/dist/LightBox/index.cjs +2 -0
- package/dist/LightBox/index.mjs +2 -0
- package/dist/Menu/index.cjs +2 -1
- package/dist/Menu/index.mjs +2 -1
- package/dist/Menu-cjs.js +5 -4
- package/dist/Menu-es.js +2 -1
- package/dist/MenuSubmenuTrigger-cjs.js +164 -206
- package/dist/MenuSubmenuTrigger-es.js +152 -194
- package/dist/Modal/index.cjs +2 -0
- package/dist/Modal/index.mjs +3 -1
- package/dist/NumberFieldInput-cjs.js +308 -187
- package/dist/NumberFieldInput-es.js +308 -187
- package/dist/Page/index.cjs +2 -1
- package/dist/Page/index.mjs +2 -1
- package/dist/Popover/index.cjs +2 -0
- package/dist/Popover/index.mjs +2 -0
- package/dist/Popover-cjs.js +8 -7
- package/dist/Popover-es.js +2 -1
- package/dist/ScrollAreaViewport-cjs.js +1093 -747
- package/dist/ScrollAreaViewport-es.js +1081 -734
- package/dist/Select/index.cjs +2 -1
- package/dist/Select/index.mjs +2 -1
- package/dist/SelectGroupLabel-cjs.js +306 -207
- package/dist/SelectGroupLabel-es.js +302 -203
- package/dist/Tooltip/index.cjs +2 -0
- package/dist/Tooltip/index.mjs +2 -0
- package/dist/Tooltip-cjs.js +7 -6
- package/dist/Tooltip-es.js +2 -1
- package/dist/dialogReturnFocus-cjs.js +1 -1
- package/dist/dialogReturnFocus-es.js +2 -2
- package/dist/floating-ui.react-cjs.js +192 -2564
- package/dist/floating-ui.react-dom-cjs.js +2103 -0
- package/dist/floating-ui.react-dom-es.js +2072 -0
- package/dist/floating-ui.react-es.js +156 -2519
- package/dist/floating-ui.utils-cjs.js +342 -0
- package/dist/floating-ui.utils-es.js +300 -0
- package/dist/index.cjs +4 -3
- package/dist/index.mjs +4 -3
- package/dist/primitives/BottomSheet/index.cjs +1 -1
- package/dist/primitives/BottomSheet/index.mjs +1 -1
- package/dist/primitives/ComboboxPrimitive/index.cjs +4 -2
- package/dist/primitives/ComboboxPrimitive/index.mjs +4 -2
- package/dist/primitives/SelectPrimitive/index.cjs +2 -0
- package/dist/primitives/SelectPrimitive/index.mjs +2 -0
- package/dist/primitives/index.cjs +3 -2
- package/dist/primitives/index.mjs +3 -2
- package/dist/scrollEdges-cjs.js +11 -1
- package/dist/scrollEdges-es.js +11 -1
- package/dist/unstyledPrimitives/index.cjs +478 -720
- package/dist/unstyledPrimitives/index.mjs +421 -663
- package/dist/useCompositeListItem-cjs.js +361 -2108
- package/dist/useCompositeListItem-es.js +331 -2076
- package/dist/useLabel-cjs.js +3 -2
- package/dist/useLabel-es.js +3 -2
- package/dist/useRenderElement-cjs.js +7 -9
- package/dist/useRenderElement-es.js +7 -9
- package/dist/useScrollLock-cjs.js +344 -819
- package/dist/useScrollLock-es.js +296 -732
- package/dist/useScrollToActive-cjs.js +5 -4
- package/dist/useScrollToActive-es.js +2 -1
- package/package.json +3 -3
- package/dist/scrollable-cjs.js +0 -58
- package/dist/scrollable-es.js +0 -54
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { a as useRefWithInit, m as mergeProps, E as EMPTY_OBJECT,
|
|
2
|
+
import { u as useBaseUiId, b as useStableCallback, k as useTimeout, a as useIsoLayoutEffect, S as SafeReact, l as error, t as transitionStatusMapping, m as useTransitionStatus, f as useOpenChangeComplete } from './useScrollLock-es.js';
|
|
3
|
+
import { u as useLabelableContext, L as LabelableContext, a as useFormContext, D as DEFAULT_VALIDITY_STATE, f as fieldValidityMapping, F as FieldRootContext, b as useFieldRootContext } from './useCompositeListItem-es.js';
|
|
4
|
+
import { f as formatErrorMessage, a as useRefWithInit, m as mergeProps, E as EMPTY_OBJECT, u as useRenderElement } from './useRenderElement-es.js';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
6
6
|
import { u as useLabel } from './useLabel-es.js';
|
|
7
7
|
|
|
@@ -14,6 +14,77 @@ function useFieldItemContext() {
|
|
|
14
14
|
return context;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
const FieldsetRootContext = /*#__PURE__*/React.createContext(undefined);
|
|
18
|
+
if (process.env.NODE_ENV !== "production") FieldsetRootContext.displayName = "FieldsetRootContext";
|
|
19
|
+
function useFieldsetRootContext(optional = false) {
|
|
20
|
+
const context = React.useContext(FieldsetRootContext);
|
|
21
|
+
if (!context && !optional) {
|
|
22
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: FieldsetRootContext is missing. Fieldset parts must be placed within <Fieldset.Root>.' : formatErrorMessage(86));
|
|
23
|
+
}
|
|
24
|
+
return context;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const LabelableProvider = function LabelableProvider(props) {
|
|
28
|
+
const defaultId = useBaseUiId();
|
|
29
|
+
const initialControlId = props.controlId === undefined ? defaultId : props.controlId;
|
|
30
|
+
const [controlId, setControlIdState] = React.useState(initialControlId);
|
|
31
|
+
const [labelId, setLabelId] = React.useState(props.labelId);
|
|
32
|
+
const [messageIds, setMessageIds] = React.useState([]);
|
|
33
|
+
const registrationsRef = useRefWithInit(() => new Map());
|
|
34
|
+
const {
|
|
35
|
+
messageIds: parentMessageIds
|
|
36
|
+
} = useLabelableContext();
|
|
37
|
+
const registerControlId = useStableCallback((source, nextId) => {
|
|
38
|
+
const registrations = registrationsRef.current;
|
|
39
|
+
if (nextId === undefined) {
|
|
40
|
+
registrations.delete(source);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
registrations.set(source, nextId);
|
|
44
|
+
|
|
45
|
+
// Only flush when registering, not when unregistering.
|
|
46
|
+
// This prevents loops during rapid unmount/remount cycles (e.g. React Activity).
|
|
47
|
+
// The next registration will pick up the correct state.
|
|
48
|
+
setControlIdState(prev => {
|
|
49
|
+
if (registrations.size === 0) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
let nextControlId;
|
|
53
|
+
for (const id of registrations.values()) {
|
|
54
|
+
if (prev !== undefined && id === prev) {
|
|
55
|
+
return prev;
|
|
56
|
+
}
|
|
57
|
+
if (nextControlId === undefined) {
|
|
58
|
+
nextControlId = id;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return nextControlId;
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
const getDescriptionProps = React.useCallback(externalProps => {
|
|
65
|
+
const ids = externalProps['aria-describedby'] ? externalProps['aria-describedby'].split(' ') : [];
|
|
66
|
+
ids.push(...parentMessageIds, ...messageIds);
|
|
67
|
+
return {
|
|
68
|
+
...externalProps,
|
|
69
|
+
'aria-describedby': Array.from(new Set(ids)).join(' ') || undefined
|
|
70
|
+
};
|
|
71
|
+
}, [parentMessageIds, messageIds]);
|
|
72
|
+
const contextValue = React.useMemo(() => ({
|
|
73
|
+
controlId,
|
|
74
|
+
registerControlId,
|
|
75
|
+
labelId,
|
|
76
|
+
setLabelId,
|
|
77
|
+
messageIds,
|
|
78
|
+
setMessageIds,
|
|
79
|
+
getDescriptionProps
|
|
80
|
+
}), [controlId, registerControlId, labelId, setLabelId, messageIds, setMessageIds, getDescriptionProps]);
|
|
81
|
+
return /*#__PURE__*/jsx(LabelableContext.Provider, {
|
|
82
|
+
value: contextValue,
|
|
83
|
+
children: props.children
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
if (process.env.NODE_ENV !== "production") LabelableProvider.displayName = "LabelableProvider";
|
|
87
|
+
|
|
17
88
|
/**
|
|
18
89
|
* Combines the field's client-side, stateful validity data with the external invalid state to
|
|
19
90
|
* determine the field's true validity.
|
|
@@ -29,35 +100,34 @@ function getCombinedFieldValidityData(validityData, invalid) {
|
|
|
29
100
|
}
|
|
30
101
|
|
|
31
102
|
const validityKeys = Object.keys(DEFAULT_VALIDITY_STATE);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* disabled, or whose `form` attribute explicitly associates them with another form, are excluded.
|
|
35
|
-
* DOM position only matters when it associates the input with a different form. Otherwise, field
|
|
36
|
-
* registration is context-driven, so portaled inputs (for example inside a dialog) still belong to
|
|
37
|
-
* the form for both validation and values projected into `onFormSubmit`.
|
|
38
|
-
*/
|
|
39
|
-
function isEligibleInput(input, formElement) {
|
|
40
|
-
if (input.matches(':disabled')) {
|
|
103
|
+
function isOnlyValueMissing(state) {
|
|
104
|
+
if (!state || state.valid || !state.valueMissing) {
|
|
41
105
|
return false;
|
|
42
106
|
}
|
|
43
|
-
|
|
44
|
-
|
|
107
|
+
let onlyValueMissing = false;
|
|
108
|
+
for (const key of validityKeys) {
|
|
109
|
+
if (key === 'valid') {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (key === 'valueMissing') {
|
|
113
|
+
onlyValueMissing = state[key];
|
|
114
|
+
} else if (state[key]) {
|
|
115
|
+
onlyValueMissing = false;
|
|
116
|
+
}
|
|
45
117
|
}
|
|
46
|
-
|
|
47
|
-
// React context crosses portal boundaries. An unassociated portaled input still participates in
|
|
48
|
-
// contextual validation, unless an explicit `form` attribute opts it out of the surrounding Form.
|
|
49
|
-
return input.form === null && !input.hasAttribute('form');
|
|
118
|
+
return onlyValueMissing;
|
|
50
119
|
}
|
|
51
120
|
|
|
52
121
|
/**
|
|
53
122
|
* Picks the input whose native validity should represent a field that owns several inputs (such as a
|
|
54
|
-
* checkbox
|
|
55
|
-
*
|
|
123
|
+
* checkbox group). Prefers the first enabled currently-invalid input, where "first" follows Set
|
|
124
|
+
* insertion order (mount order), and otherwise returns the first enabled input. Disabled inputs are
|
|
125
|
+
* skipped because they don't participate in native constraint validation.
|
|
56
126
|
*/
|
|
57
|
-
function findRepresentativeInput(inputs
|
|
127
|
+
function findRepresentativeInput(inputs) {
|
|
58
128
|
let fallback = null;
|
|
59
|
-
for (const input of inputs
|
|
60
|
-
if (
|
|
129
|
+
for (const input of inputs) {
|
|
130
|
+
if (input.disabled) {
|
|
61
131
|
continue;
|
|
62
132
|
}
|
|
63
133
|
if (!input.validity.valid) {
|
|
@@ -68,14 +138,17 @@ function findRepresentativeInput(inputs, formElement) {
|
|
|
68
138
|
return fallback;
|
|
69
139
|
}
|
|
70
140
|
function clearCustomValidity(element, inputs) {
|
|
71
|
-
|
|
141
|
+
let didClearElement = false;
|
|
142
|
+
for (const input of inputs) {
|
|
72
143
|
input.setCustomValidity('');
|
|
144
|
+
didClearElement ||= input === element;
|
|
145
|
+
}
|
|
146
|
+
if (!didClearElement) {
|
|
147
|
+
element.setCustomValidity('');
|
|
73
148
|
}
|
|
74
|
-
element?.setCustomValidity('');
|
|
75
149
|
}
|
|
76
150
|
function useFieldValidation(params) {
|
|
77
151
|
const {
|
|
78
|
-
elementRef,
|
|
79
152
|
formRef
|
|
80
153
|
} = useFormContext();
|
|
81
154
|
const {
|
|
@@ -87,7 +160,7 @@ function useFieldValidation(params) {
|
|
|
87
160
|
markedDirtyRef,
|
|
88
161
|
state,
|
|
89
162
|
shouldValidateOnChange,
|
|
90
|
-
|
|
163
|
+
getRegisteredFieldId
|
|
91
164
|
} = params;
|
|
92
165
|
const {
|
|
93
166
|
controlId,
|
|
@@ -95,27 +168,32 @@ function useFieldValidation(params) {
|
|
|
95
168
|
} = useLabelableContext();
|
|
96
169
|
const timeout = useTimeout();
|
|
97
170
|
const inputRef = React.useRef(null);
|
|
98
|
-
const registeredInputs = useRefWithInit(() => new
|
|
171
|
+
const registeredInputs = useRefWithInit(() => new Set()).current;
|
|
99
172
|
const validationCommitIdRef = React.useRef(0);
|
|
100
173
|
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
174
|
+
// Checkbox groups register several inputs against a single field. Track them so a `required`
|
|
175
|
+
// checkbox can't be satisfied by another input in the group, matching native per-checkbox behavior.
|
|
176
|
+
const registerInput = React.useCallback(element => {
|
|
177
|
+
if (!element) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
registeredInputs.add(element);
|
|
106
181
|
return () => {
|
|
107
182
|
registeredInputs.delete(element);
|
|
108
183
|
};
|
|
109
184
|
}, [registeredInputs]);
|
|
110
|
-
const getInputControl = useStableCallback(() => {
|
|
111
|
-
const element = findRepresentativeInput(registeredInputs, elementRef.current);
|
|
112
|
-
return element && registeredInputs.get(element)?.controlRef.current || null;
|
|
113
|
-
});
|
|
114
185
|
const commit = useStableCallback(async (value, revalidate = false) => {
|
|
186
|
+
// A field can own several inputs (a checkbox group), but only the last-mounted one wins the shared
|
|
187
|
+
// `inputRef`. Validate against the registry instead so every input counts; `inputRef` is the
|
|
188
|
+
// fallback only when no registered input applies (none registered, or all of them disabled).
|
|
189
|
+
const element = findRepresentativeInput(registeredInputs) ?? inputRef.current;
|
|
190
|
+
if (!element) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
115
193
|
validationCommitIdRef.current += 1;
|
|
116
194
|
const validationCommitId = validationCommitIdRef.current;
|
|
117
195
|
function updateRegisteredFieldValidity(nextValidityData, externalInvalid = invalid) {
|
|
118
|
-
const fieldId =
|
|
196
|
+
const fieldId = getRegisteredFieldId() ?? controlId;
|
|
119
197
|
if (fieldId == null) {
|
|
120
198
|
return;
|
|
121
199
|
}
|
|
@@ -129,31 +207,8 @@ function useFieldValidation(params) {
|
|
|
129
207
|
validityData: validityDataWithFormErrors
|
|
130
208
|
});
|
|
131
209
|
}
|
|
132
|
-
function publishAllValid(input, externalInvalid) {
|
|
133
|
-
const nextValidityData = {
|
|
134
|
-
value,
|
|
135
|
-
state: {
|
|
136
|
-
...DEFAULT_VALIDITY_STATE,
|
|
137
|
-
valid: true
|
|
138
|
-
},
|
|
139
|
-
error: '',
|
|
140
|
-
errors: [],
|
|
141
|
-
initialValue: validityData.initialValue
|
|
142
|
-
};
|
|
143
|
-
clearCustomValidity(input, registeredInputs);
|
|
144
|
-
updateRegisteredFieldValidity(nextValidityData, externalInvalid);
|
|
145
|
-
setValidityData(nextValidityData);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// A field can own several inputs (such as a checkbox or radio group), but only the last-mounted
|
|
149
|
-
// one wins the shared `inputRef`. Validate against the registry instead so every input counts;
|
|
150
|
-
// `inputRef` is the fallback only when no inputs are registered.
|
|
151
|
-
const element = registeredInputs.size > 0 ? findRepresentativeInput(registeredInputs, elementRef.current) : inputRef.current;
|
|
152
|
-
// A field with no eligible input has no native constraint, but its custom validator still
|
|
153
|
-
// applies to the logical value at the configured validation boundary.
|
|
154
|
-
|
|
155
210
|
if (revalidate) {
|
|
156
|
-
if (state.valid !== false
|
|
211
|
+
if (state.valid !== false) {
|
|
157
212
|
return;
|
|
158
213
|
}
|
|
159
214
|
const currentNativeValidity = element.validity;
|
|
@@ -161,20 +216,39 @@ function useFieldValidation(params) {
|
|
|
161
216
|
// The 'valueMissing' (required) condition has been resolved by the user typing.
|
|
162
217
|
// Temporarily mark the field as valid for this onChange event.
|
|
163
218
|
// Other native errors (e.g., typeMismatch) will be caught by full validation on blur or submit.
|
|
219
|
+
const nextValidityData = {
|
|
220
|
+
value,
|
|
221
|
+
state: {
|
|
222
|
+
...DEFAULT_VALIDITY_STATE,
|
|
223
|
+
valid: true
|
|
224
|
+
},
|
|
225
|
+
error: '',
|
|
226
|
+
errors: [],
|
|
227
|
+
initialValue: validityData.initialValue
|
|
228
|
+
};
|
|
229
|
+
clearCustomValidity(element, registeredInputs);
|
|
230
|
+
|
|
164
231
|
// The required value is now present; ignore stale external invalid state for this pass.
|
|
165
|
-
|
|
232
|
+
updateRegisteredFieldValidity(nextValidityData, false);
|
|
233
|
+
setValidityData(nextValidityData);
|
|
166
234
|
return;
|
|
167
235
|
}
|
|
168
236
|
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
237
|
+
// Value is still missing, or other conditions apply.
|
|
238
|
+
// Let's use a representation of current validity for isOnlyValueMissing.
|
|
239
|
+
const currentNativeValidityObject = validityKeys.reduce((acc, key) => {
|
|
240
|
+
acc[key] = currentNativeValidity[key];
|
|
241
|
+
return acc;
|
|
242
|
+
}, {});
|
|
243
|
+
|
|
244
|
+
// If it's (still) natively invalid due to something other than just valueMissing,
|
|
245
|
+
// then bail from this revalidation on change to avoid "scolding" for other errors.
|
|
246
|
+
if (!currentNativeValidityObject.valid && !isOnlyValueMissing(currentNativeValidityObject)) {
|
|
247
|
+
return;
|
|
174
248
|
}
|
|
175
249
|
|
|
176
|
-
//
|
|
177
|
-
//
|
|
250
|
+
// If valueMissing is still true AND it's the only issue, or if the field is now natively valid,
|
|
251
|
+
// let it fall through to the main validation logic below.
|
|
178
252
|
}
|
|
179
253
|
function getState(el) {
|
|
180
254
|
const computedState = validityKeys.reduce((acc, key) => {
|
|
@@ -204,16 +278,10 @@ function useFieldValidation(params) {
|
|
|
204
278
|
timeout.clear();
|
|
205
279
|
let result = null;
|
|
206
280
|
let validationErrors = [];
|
|
207
|
-
|
|
208
|
-
// With no representative input the field carries no native constraint, so start from an
|
|
209
|
-
// all-valid native state and let the custom `validate` result below decide the outcome.
|
|
210
|
-
const nextState = element ? getState(element) : {
|
|
211
|
-
...DEFAULT_VALIDITY_STATE,
|
|
212
|
-
valid: true
|
|
213
|
-
};
|
|
281
|
+
const nextState = getState(element);
|
|
214
282
|
let defaultValidationMessage;
|
|
215
283
|
const isValidatingOnChange = shouldValidateOnChange();
|
|
216
|
-
if (element
|
|
284
|
+
if (element.validationMessage && !isValidatingOnChange) {
|
|
217
285
|
// not validating on change, if there is a `validationMessage` from
|
|
218
286
|
// native validity, set errors and skip calling the custom validate fn
|
|
219
287
|
defaultValidationMessage = element.validationMessage;
|
|
@@ -242,20 +310,20 @@ function useFieldValidation(params) {
|
|
|
242
310
|
nextState.customError = true;
|
|
243
311
|
if (Array.isArray(result)) {
|
|
244
312
|
validationErrors = result;
|
|
245
|
-
element
|
|
313
|
+
element.setCustomValidity(result.join('\n'));
|
|
246
314
|
} else if (result) {
|
|
247
315
|
validationErrors = [result];
|
|
248
|
-
element
|
|
316
|
+
element.setCustomValidity(result);
|
|
249
317
|
}
|
|
250
318
|
} else if (isValidatingOnChange) {
|
|
251
319
|
// validate function returned no errors, if validating on change
|
|
252
320
|
// we need to clear the custom validity state
|
|
253
321
|
clearCustomValidity(element, registeredInputs);
|
|
254
322
|
nextState.customError = false;
|
|
255
|
-
if (element
|
|
323
|
+
if (element.validationMessage) {
|
|
256
324
|
defaultValidationMessage = element.validationMessage;
|
|
257
325
|
validationErrors = [element.validationMessage];
|
|
258
|
-
} else if (
|
|
326
|
+
} else if (element.validity.valid && !nextState.valid) {
|
|
259
327
|
nextState.valid = true;
|
|
260
328
|
}
|
|
261
329
|
}
|
|
@@ -290,85 +358,12 @@ function useFieldValidation(params) {
|
|
|
290
358
|
return React.useMemo(() => ({
|
|
291
359
|
getValidationProps,
|
|
292
360
|
inputRef,
|
|
293
|
-
registeredInputs,
|
|
294
361
|
registerInput,
|
|
295
|
-
getInputControl,
|
|
296
362
|
commit,
|
|
297
363
|
change
|
|
298
|
-
}), [getValidationProps,
|
|
364
|
+
}), [getValidationProps, registerInput, commit, change]);
|
|
299
365
|
}
|
|
300
366
|
|
|
301
|
-
const FieldsetRootContext = /*#__PURE__*/React.createContext(undefined);
|
|
302
|
-
if (process.env.NODE_ENV !== "production") FieldsetRootContext.displayName = "FieldsetRootContext";
|
|
303
|
-
function useFieldsetRootContext(optional = false) {
|
|
304
|
-
const context = React.useContext(FieldsetRootContext);
|
|
305
|
-
if (!context && !optional) {
|
|
306
|
-
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: FieldsetRootContext is missing. Fieldset parts must be placed within <Fieldset.Root>.' : formatErrorMessage(86));
|
|
307
|
-
}
|
|
308
|
-
return context;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
const LabelableProvider = function LabelableProvider(props) {
|
|
312
|
-
const defaultId = useBaseUiId();
|
|
313
|
-
const initialControlId = props.controlId === undefined ? defaultId : props.controlId;
|
|
314
|
-
const [controlId, setControlIdState] = React.useState(initialControlId);
|
|
315
|
-
const [labelId, setLabelId] = React.useState(props.labelId);
|
|
316
|
-
const [messageIds, setMessageIds] = React.useState([]);
|
|
317
|
-
const registrationsRef = useRefWithInit(() => new Map());
|
|
318
|
-
const {
|
|
319
|
-
messageIds: parentMessageIds
|
|
320
|
-
} = useLabelableContext();
|
|
321
|
-
const registerControlId = useStableCallback((source, nextId) => {
|
|
322
|
-
const registrations = registrationsRef.current;
|
|
323
|
-
if (nextId === undefined) {
|
|
324
|
-
registrations.delete(source);
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
registrations.set(source, nextId);
|
|
328
|
-
|
|
329
|
-
// Only flush when registering, not when unregistering.
|
|
330
|
-
// This prevents loops during rapid unmount/remount cycles (e.g. React Activity).
|
|
331
|
-
// The next registration will pick up the correct state.
|
|
332
|
-
setControlIdState(prev => {
|
|
333
|
-
if (registrations.size === 0) {
|
|
334
|
-
return undefined;
|
|
335
|
-
}
|
|
336
|
-
let nextControlId;
|
|
337
|
-
for (const id of registrations.values()) {
|
|
338
|
-
if (prev !== undefined && id === prev) {
|
|
339
|
-
return prev;
|
|
340
|
-
}
|
|
341
|
-
if (nextControlId === undefined) {
|
|
342
|
-
nextControlId = id;
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
return nextControlId;
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
const getDescriptionProps = React.useCallback(externalProps => {
|
|
349
|
-
const ids = externalProps['aria-describedby'] ? externalProps['aria-describedby'].split(' ') : [];
|
|
350
|
-
ids.push(...parentMessageIds, ...messageIds);
|
|
351
|
-
return {
|
|
352
|
-
...externalProps,
|
|
353
|
-
'aria-describedby': Array.from(new Set(ids)).join(' ') || undefined
|
|
354
|
-
};
|
|
355
|
-
}, [parentMessageIds, messageIds]);
|
|
356
|
-
const contextValue = React.useMemo(() => ({
|
|
357
|
-
controlId,
|
|
358
|
-
registerControlId,
|
|
359
|
-
labelId,
|
|
360
|
-
setLabelId,
|
|
361
|
-
messageIds,
|
|
362
|
-
setMessageIds,
|
|
363
|
-
getDescriptionProps
|
|
364
|
-
}), [controlId, registerControlId, labelId, setLabelId, messageIds, setMessageIds, getDescriptionProps]);
|
|
365
|
-
return /*#__PURE__*/jsx(LabelableContext.Provider, {
|
|
366
|
-
value: contextValue,
|
|
367
|
-
children: props.children
|
|
368
|
-
});
|
|
369
|
-
};
|
|
370
|
-
if (process.env.NODE_ENV !== "production") LabelableProvider.displayName = "LabelableProvider";
|
|
371
|
-
|
|
372
367
|
function useFieldControlRegistration(params) {
|
|
373
368
|
const {
|
|
374
369
|
commit,
|
|
@@ -376,7 +371,7 @@ function useFieldControlRegistration(params) {
|
|
|
376
371
|
markedDirtyRef,
|
|
377
372
|
name,
|
|
378
373
|
setRegisteredFieldName,
|
|
379
|
-
|
|
374
|
+
setRegisteredFieldId,
|
|
380
375
|
setValidityData,
|
|
381
376
|
validityData
|
|
382
377
|
} = params;
|
|
@@ -385,7 +380,7 @@ function useFieldControlRegistration(params) {
|
|
|
385
380
|
} = useFormContext();
|
|
386
381
|
const activeFieldControlSourceRef = React.useRef(null);
|
|
387
382
|
const registrationRef = React.useRef(null);
|
|
388
|
-
const
|
|
383
|
+
const fallbackControlRef = React.useRef(null);
|
|
389
384
|
const getValueForForm = useStableCallback(() => {
|
|
390
385
|
const registration = registrationRef.current;
|
|
391
386
|
if (!registration) {
|
|
@@ -416,7 +411,7 @@ function useFieldControlRegistration(params) {
|
|
|
416
411
|
formRef.current.fields.set(registration.id, {
|
|
417
412
|
getValue: getValueForForm,
|
|
418
413
|
name: name ?? registration.name,
|
|
419
|
-
controlRef: registration.controlRef,
|
|
414
|
+
controlRef: registration.controlRef ?? fallbackControlRef,
|
|
420
415
|
validityData: getCombinedFieldValidityData(validityData, invalid),
|
|
421
416
|
validate
|
|
422
417
|
});
|
|
@@ -426,23 +421,18 @@ function useFieldControlRegistration(params) {
|
|
|
426
421
|
formRef.current.fields.delete(id);
|
|
427
422
|
}
|
|
428
423
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
// back as a brand new registration. Capturing more than once would turn whichever value the
|
|
433
|
-
// control happens to hold at that point into the initial value, so a modified field would read
|
|
434
|
-
// pristine and its real initial value would read dirty. Consumers that want a fresh baseline
|
|
435
|
-
// remount or key `<Field.Root>` itself.
|
|
436
|
-
function captureInitialValue(registration) {
|
|
437
|
-
if (initialValueCapturedRef.current) {
|
|
424
|
+
function syncInitialValue() {
|
|
425
|
+
const registration = registrationRef.current;
|
|
426
|
+
if (!registration) {
|
|
438
427
|
return;
|
|
439
428
|
}
|
|
440
|
-
initialValueCapturedRef.current = true;
|
|
441
429
|
const initialValue = getRegistrationValue(registration);
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
430
|
+
if (validityData.initialValue === null && initialValue !== null) {
|
|
431
|
+
setValidityData(prev => ({
|
|
432
|
+
...prev,
|
|
433
|
+
initialValue
|
|
434
|
+
}));
|
|
435
|
+
}
|
|
446
436
|
}
|
|
447
437
|
useIsoLayoutEffect(() => {
|
|
448
438
|
const registration = registrationRef.current;
|
|
@@ -453,7 +443,7 @@ function useFieldControlRegistration(params) {
|
|
|
453
443
|
formRef.current.fields.set(registration.id, {
|
|
454
444
|
getValue: getValueForForm,
|
|
455
445
|
name: name ?? registration.name,
|
|
456
|
-
controlRef: registration.controlRef,
|
|
446
|
+
controlRef: registration.controlRef ?? fallbackControlRef,
|
|
457
447
|
validityData: getCombinedFieldValidityData(validityData, invalid),
|
|
458
448
|
validate
|
|
459
449
|
});
|
|
@@ -474,7 +464,7 @@ function useFieldControlRegistration(params) {
|
|
|
474
464
|
deleteRegistration();
|
|
475
465
|
registrationRef.current = null;
|
|
476
466
|
setRegisteredFieldName(undefined);
|
|
477
|
-
|
|
467
|
+
setRegisteredFieldId(undefined);
|
|
478
468
|
}
|
|
479
469
|
return;
|
|
480
470
|
}
|
|
@@ -484,11 +474,11 @@ function useFieldControlRegistration(params) {
|
|
|
484
474
|
if (!name) {
|
|
485
475
|
setRegisteredFieldName(registration.name);
|
|
486
476
|
}
|
|
487
|
-
|
|
477
|
+
setRegisteredFieldId(registration.id);
|
|
488
478
|
if (previousId && previousId !== registration.id) {
|
|
489
479
|
deleteRegistration(previousId);
|
|
490
480
|
}
|
|
491
|
-
|
|
481
|
+
syncInitialValue();
|
|
492
482
|
refreshRegistration();
|
|
493
483
|
});
|
|
494
484
|
return [validate, register];
|
|
@@ -533,6 +523,10 @@ const FieldRootInner = /*#__PURE__*/React.forwardRef(function FieldRootInner(com
|
|
|
533
523
|
markedDirtyRef.current = dirtyProp;
|
|
534
524
|
}
|
|
535
525
|
}, [dirtyProp]);
|
|
526
|
+
const getRegisteredFieldId = React.useCallback(() => registeredFieldIdRef.current, []);
|
|
527
|
+
const setRegisteredFieldId = React.useCallback(id => {
|
|
528
|
+
registeredFieldIdRef.current = id;
|
|
529
|
+
}, []);
|
|
536
530
|
const setDirty = useStableCallback(value => {
|
|
537
531
|
if (dirtyProp !== undefined) {
|
|
538
532
|
return;
|
|
@@ -559,11 +553,7 @@ const FieldRootInner = /*#__PURE__*/React.forwardRef(function FieldRootInner(com
|
|
|
559
553
|
value: null,
|
|
560
554
|
initialValue: null
|
|
561
555
|
});
|
|
562
|
-
|
|
563
|
-
// App-controlled invalidity (the `invalid` prop and `<Form>` errors) keeps the field marked
|
|
564
|
-
// invalid even while disabled. Only computed validity (native constraints and `validate`)
|
|
565
|
-
// is suppressed when disabled, matching `:disabled` not participating in constraint validation.
|
|
566
|
-
const valid = !invalid && (disabled ? null : validityData.state.valid);
|
|
556
|
+
const valid = disabled ? null : !invalid && validityData.state.valid;
|
|
567
557
|
const state = React.useMemo(() => ({
|
|
568
558
|
disabled,
|
|
569
559
|
touched,
|
|
@@ -581,7 +571,7 @@ const FieldRootInner = /*#__PURE__*/React.forwardRef(function FieldRootInner(com
|
|
|
581
571
|
markedDirtyRef,
|
|
582
572
|
state,
|
|
583
573
|
shouldValidateOnChange,
|
|
584
|
-
|
|
574
|
+
getRegisteredFieldId
|
|
585
575
|
});
|
|
586
576
|
const [validateFieldControl, registerFieldControl] = useFieldControlRegistration({
|
|
587
577
|
commit: validation.commit,
|
|
@@ -589,7 +579,7 @@ const FieldRootInner = /*#__PURE__*/React.forwardRef(function FieldRootInner(com
|
|
|
589
579
|
markedDirtyRef,
|
|
590
580
|
name,
|
|
591
581
|
setRegisteredFieldName,
|
|
592
|
-
|
|
582
|
+
setRegisteredFieldId,
|
|
593
583
|
setValidityData,
|
|
594
584
|
validityData
|
|
595
585
|
});
|
|
@@ -602,16 +592,23 @@ const FieldRootInner = /*#__PURE__*/React.forwardRef(function FieldRootInner(com
|
|
|
602
592
|
validityData,
|
|
603
593
|
setValidityData,
|
|
604
594
|
disabled,
|
|
595
|
+
touched,
|
|
605
596
|
setTouched,
|
|
597
|
+
dirty,
|
|
606
598
|
setDirty,
|
|
599
|
+
filled,
|
|
607
600
|
setFilled,
|
|
601
|
+
focused,
|
|
608
602
|
setFocused,
|
|
603
|
+
validate,
|
|
609
604
|
validationMode,
|
|
605
|
+
validationDebounceTime,
|
|
610
606
|
shouldValidateOnChange,
|
|
611
607
|
state,
|
|
608
|
+
markedDirtyRef,
|
|
612
609
|
registerFieldControl,
|
|
613
610
|
validation
|
|
614
|
-
}), [invalid, effectiveName, validityData, disabled, setTouched, setDirty, setFilled, setFocused, validationMode, shouldValidateOnChange, state, registerFieldControl, validation]);
|
|
611
|
+
}), [invalid, effectiveName, validityData, disabled, touched, setTouched, dirty, setDirty, filled, setFilled, focused, setFocused, validate, validationMode, validationDebounceTime, shouldValidateOnChange, state, registerFieldControl, validation]);
|
|
615
612
|
const element = useRenderElement('div', componentProps, {
|
|
616
613
|
ref: forwardedRef,
|
|
617
614
|
state,
|
|
@@ -768,13 +765,13 @@ const FieldError = /*#__PURE__*/React.forwardRef(function FieldError(componentPr
|
|
|
768
765
|
} else if (validityData.errors.length > 1) {
|
|
769
766
|
error = validityData.errors;
|
|
770
767
|
}
|
|
771
|
-
let errorMessage = error;
|
|
768
|
+
let errorMessage = error ?? '';
|
|
772
769
|
if (Array.isArray(error)) {
|
|
773
770
|
errorMessage = error.length > 1 ? /*#__PURE__*/jsx("ul", {
|
|
774
771
|
children: error.map(message => /*#__PURE__*/jsx("li", {
|
|
775
772
|
children: message
|
|
776
773
|
}, message))
|
|
777
|
-
}) : error[0];
|
|
774
|
+
}) : error[0] ?? '';
|
|
778
775
|
}
|
|
779
776
|
const errorKey = Array.isArray(error) ? JSON.stringify(error) : error;
|
|
780
777
|
if (rendered && errorKey !== lastRenderedMessageKey) {
|
|
@@ -18,8 +18,10 @@ require('../../../useAtlantisI18n-cjs.js');
|
|
|
18
18
|
require('../../../AtlantisContext-cjs.js');
|
|
19
19
|
require('../../../Tooltip-cjs.js');
|
|
20
20
|
require('../../../floating-ui.react-cjs.js');
|
|
21
|
+
require('../../../floating-ui.utils-cjs.js');
|
|
21
22
|
require('react/jsx-runtime');
|
|
22
23
|
require('react-dom');
|
|
24
|
+
require('../../../floating-ui.react-dom-cjs.js');
|
|
23
25
|
require('framer-motion');
|
|
24
26
|
require('../../../FilterPickerProvider-cjs.js');
|
|
25
27
|
require('../../../constants-cjs.js');
|
|
@@ -16,8 +16,10 @@ import '../../../useAtlantisI18n-es.js';
|
|
|
16
16
|
import '../../../AtlantisContext-es.js';
|
|
17
17
|
import '../../../Tooltip-es.js';
|
|
18
18
|
import '../../../floating-ui.react-es.js';
|
|
19
|
+
import '../../../floating-ui.utils-es.js';
|
|
19
20
|
import 'react/jsx-runtime';
|
|
20
21
|
import 'react-dom';
|
|
22
|
+
import '../../../floating-ui.react-dom-es.js';
|
|
21
23
|
import 'framer-motion';
|
|
22
24
|
import '../../../FilterPickerProvider-es.js';
|
|
23
25
|
import '../../../constants-es.js';
|
|
@@ -4,8 +4,10 @@ var FilterPickerContent = require('../../../FilterPickerContent-cjs.js');
|
|
|
4
4
|
require('react');
|
|
5
5
|
require('classnames');
|
|
6
6
|
require('../../../floating-ui.react-cjs.js');
|
|
7
|
+
require('../../../floating-ui.utils-cjs.js');
|
|
7
8
|
require('react/jsx-runtime');
|
|
8
9
|
require('react-dom');
|
|
10
|
+
require('../../../floating-ui.react-dom-cjs.js');
|
|
9
11
|
require('../../../FilterPickerContentSearch-cjs.js');
|
|
10
12
|
require('../../../Icon-cjs.js');
|
|
11
13
|
require('@jobber/design');
|
|
@@ -2,8 +2,10 @@ export { F as FilterPickerContent } from '../../../FilterPickerContent-es.js';
|
|
|
2
2
|
import 'react';
|
|
3
3
|
import 'classnames';
|
|
4
4
|
import '../../../floating-ui.react-es.js';
|
|
5
|
+
import '../../../floating-ui.utils-es.js';
|
|
5
6
|
import 'react/jsx-runtime';
|
|
6
7
|
import 'react-dom';
|
|
8
|
+
import '../../../floating-ui.react-dom-es.js';
|
|
7
9
|
import '../../../FilterPickerContentSearch-es.js';
|
|
8
10
|
import '../../../Icon-es.js';
|
|
9
11
|
import '@jobber/design';
|
|
@@ -16,8 +16,10 @@ require('../../../AtlantisContext-cjs.js');
|
|
|
16
16
|
require('../../../Typography-cjs.js');
|
|
17
17
|
require('../../../Tooltip-cjs.js');
|
|
18
18
|
require('../../../floating-ui.react-cjs.js');
|
|
19
|
+
require('../../../floating-ui.utils-cjs.js');
|
|
19
20
|
require('react/jsx-runtime');
|
|
20
21
|
require('react-dom');
|
|
22
|
+
require('../../../floating-ui.react-dom-cjs.js');
|
|
21
23
|
require('framer-motion');
|
|
22
24
|
require('../../../FilterPickerProvider-cjs.js');
|
|
23
25
|
|
|
@@ -14,7 +14,9 @@ import '../../../AtlantisContext-es.js';
|
|
|
14
14
|
import '../../../Typography-es.js';
|
|
15
15
|
import '../../../Tooltip-es.js';
|
|
16
16
|
import '../../../floating-ui.react-es.js';
|
|
17
|
+
import '../../../floating-ui.utils-es.js';
|
|
17
18
|
import 'react/jsx-runtime';
|
|
18
19
|
import 'react-dom';
|
|
20
|
+
import '../../../floating-ui.react-dom-es.js';
|
|
19
21
|
import 'framer-motion';
|
|
20
22
|
import '../../../FilterPickerProvider-es.js';
|