@jobber/components 8.23.0 → 8.23.1
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 +1 -1
- package/dist/Autocomplete/index.mjs +1 -1
- package/dist/Card/index.cjs +4 -4
- package/dist/Card/index.mjs +4 -4
- package/dist/Chip/index.cjs +1 -1
- package/dist/Chip/index.mjs +1 -1
- package/dist/Chips/InternalChipDismissible/hooks/index.cjs +1 -1
- package/dist/Chips/InternalChipDismissible/hooks/index.mjs +1 -1
- package/dist/Chips/InternalChipDismissible/index.cjs +1 -1
- package/dist/Chips/InternalChipDismissible/index.mjs +1 -1
- package/dist/Chips/index.cjs +1 -1
- package/dist/Chips/index.mjs +1 -1
- package/dist/ComboboxChipRemove-cjs.js +668 -379
- package/dist/ComboboxChipRemove-es.js +508 -219
- package/dist/ConfirmationModal/index.cjs +1 -1
- package/dist/ConfirmationModal/index.mjs +1 -1
- package/dist/DataDump/index.cjs +4 -4
- package/dist/DataDump/index.mjs +4 -4
- package/dist/DataList/components/DataListActions/index.cjs +1 -1
- package/dist/DataList/components/DataListActions/index.mjs +1 -1
- package/dist/DataList/components/DataListBulkActions/index.cjs +1 -1
- package/dist/DataList/components/DataListBulkActions/index.mjs +1 -1
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +1 -1
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +1 -1
- package/dist/DataList/components/DataListFilters/index.cjs +1 -1
- package/dist/DataList/components/DataListFilters/index.mjs +1 -1
- package/dist/DataList/components/DataListHeader/index.cjs +1 -1
- package/dist/DataList/components/DataListHeader/index.mjs +1 -1
- package/dist/DataList/components/DataListItem/index.cjs +1 -1
- package/dist/DataList/components/DataListItem/index.mjs +1 -1
- package/dist/DataList/components/DataListItemActions/index.cjs +1 -1
- package/dist/DataList/components/DataListItemActions/index.mjs +1 -1
- package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +1 -1
- package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +1 -1
- package/dist/DataList/components/DataListItems/index.cjs +1 -1
- package/dist/DataList/components/DataListItems/index.mjs +1 -1
- package/dist/DataList/components/DataListLayout/index.cjs +1 -1
- package/dist/DataList/components/DataListLayout/index.mjs +1 -1
- package/dist/DataList/components/DataListLayoutActions/index.cjs +1 -1
- package/dist/DataList/components/DataListLayoutActions/index.mjs +1 -1
- package/dist/DataList/index.cjs +1 -1
- package/dist/DataList/index.mjs +1 -1
- package/dist/DatePicker/index.cjs +1 -1
- package/dist/DatePicker/index.mjs +1 -1
- package/dist/Dialog/index.cjs +3 -3
- package/dist/Dialog/index.mjs +3 -3
- package/dist/DrawerDescription-cjs.js +32 -33
- package/dist/DrawerDescription-es.js +19 -20
- package/dist/DrawerTitle-cjs.js +7 -5
- package/dist/DrawerTitle-es.js +7 -5
- package/dist/FilterPicker/components/FilterPickerActivator/index.cjs +1 -1
- package/dist/FilterPicker/components/FilterPickerActivator/index.mjs +1 -1
- package/dist/FilterPicker/components/FilterPickerContent/index.cjs +1 -1
- package/dist/FilterPicker/components/FilterPickerContent/index.mjs +1 -1
- package/dist/FilterPicker/components/FilterPickerTrigger/index.cjs +1 -1
- package/dist/FilterPicker/components/FilterPickerTrigger/index.mjs +1 -1
- package/dist/FilterPicker/index.cjs +1 -1
- package/dist/FilterPicker/index.mjs +1 -1
- package/dist/FormFieldWrapper-cjs.js +2 -2
- package/dist/FormFieldWrapper-es.js +2 -2
- package/dist/FormatFile/index.cjs +1 -1
- package/dist/FormatFile/index.mjs +1 -1
- package/dist/Gallery/index.cjs +1 -1
- package/dist/Gallery/index.mjs +1 -1
- package/dist/InputDate/index.cjs +1 -1
- package/dist/InputDate/index.mjs +1 -1
- package/dist/InputNumberExperimental-cjs.js +319 -102
- package/dist/InputNumberExperimental-es.js +321 -104
- package/dist/LightBox/index.cjs +1 -1
- package/dist/LightBox/index.mjs +1 -1
- package/dist/Menu/index.cjs +4 -4
- package/dist/Menu/index.mjs +4 -4
- package/dist/MenuSubmenuTrigger-cjs.js +545 -498
- package/dist/MenuSubmenuTrigger-es.js +490 -443
- package/dist/Modal/index.cjs +1 -1
- package/dist/Modal/index.mjs +1 -1
- package/dist/NumberFieldInput-cjs.js +609 -496
- package/dist/NumberFieldInput-es.js +612 -498
- package/dist/Page/index.cjs +4 -4
- package/dist/Page/index.mjs +4 -4
- package/dist/Popover/index.cjs +1 -1
- package/dist/Popover/index.mjs +1 -1
- package/dist/ScrollAreaViewport-cjs.js +326 -601
- package/dist/ScrollAreaViewport-es.js +278 -548
- package/dist/SelectGroupLabel-cjs.js +494 -528
- package/dist/SelectGroupLabel-es.js +411 -445
- package/dist/Separator-cjs.js +1 -0
- package/dist/Separator-es.js +1 -0
- package/dist/Tooltip/index.cjs +1 -1
- package/dist/Tooltip/index.mjs +1 -1
- package/dist/docs/InputTime/InputTime.md +8 -0
- package/dist/docs/SelectPrimitive/SelectPrimitive.md +38 -25
- package/dist/floating-ui.react-cjs.js +586 -10
- package/dist/floating-ui.react-dom-cjs.js +92 -92
- package/dist/floating-ui.react-dom-es.js +1 -1
- package/dist/floating-ui.react-es.js +580 -4
- package/dist/floating-ui.utils-cjs.js +159 -0
- package/dist/floating-ui.utils-es.js +136 -0
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{ToolbarRootContext-cjs.js → isElementDisabled-cjs.js} +5 -0
- package/dist/{ToolbarRootContext-es.js → isElementDisabled-es.js} +5 -1
- package/dist/primitives/BottomSheet/index.cjs +3 -3
- package/dist/primitives/BottomSheet/index.mjs +3 -3
- package/dist/primitives/ComboboxPrimitive/index.cjs +2 -2
- package/dist/primitives/ComboboxPrimitive/index.mjs +2 -2
- package/dist/primitives/InputNumberExperimental/index.cjs +1 -1
- package/dist/primitives/InputNumberExperimental/index.mjs +1 -1
- package/dist/primitives/SelectPrimitive/index.cjs +5 -5
- package/dist/primitives/SelectPrimitive/index.mjs +5 -5
- package/dist/primitives/index.cjs +4 -4
- package/dist/primitives/index.mjs +4 -4
- package/dist/resolveAriaLabelledBy-cjs.js +5 -0
- package/dist/resolveAriaLabelledBy-es.js +5 -1
- package/dist/{CSPContext-cjs.js → scrollEdges-cjs.js} +30 -2
- package/dist/{CSPContext-es.js → scrollEdges-es.js} +28 -3
- package/dist/styles.css +9 -3
- package/dist/unstyledPrimitives/index.cjs +1217 -639
- package/dist/unstyledPrimitives/index.mjs +1163 -585
- package/dist/useButton-cjs.js +283 -317
- package/dist/useButton-es.js +277 -298
- package/dist/useCompositeListItem-cjs.js +328 -279
- package/dist/useCompositeListItem-es.js +293 -246
- package/dist/useLabel-cjs.js +11 -1
- package/dist/useLabel-es.js +11 -2
- package/dist/useLabelableId-cjs.js +37 -91
- package/dist/useLabelableId-es.js +37 -90
- package/dist/useRenderElement-cjs.js +81 -26
- package/dist/useRenderElement-es.js +81 -27
- package/dist/{InternalBackdrop-cjs.js → useScrollLock-cjs.js} +1286 -1220
- package/dist/{InternalBackdrop-es.js → useScrollLock-es.js} +1250 -1207
- package/package.json +3 -3
- package/dist/index.esm-cjs.js +0 -738
- package/dist/index.esm-es.js +0 -712
package/dist/useLabel-cjs.js
CHANGED
|
@@ -4,6 +4,16 @@ var floatingUi_utils_dom = require('./floating-ui.utils.dom-cjs.js');
|
|
|
4
4
|
var useButton = require('./useButton-cjs.js');
|
|
5
5
|
var useLabelableId = require('./useLabelableId-cjs.js');
|
|
6
6
|
|
|
7
|
+
function stringifyLocale(locale) {
|
|
8
|
+
if (Array.isArray(locale)) {
|
|
9
|
+
return locale.map(value => stringifyLocale(value)).join(',');
|
|
10
|
+
}
|
|
11
|
+
if (locale == null) {
|
|
12
|
+
return '';
|
|
13
|
+
}
|
|
14
|
+
return String(locale);
|
|
15
|
+
}
|
|
16
|
+
|
|
7
17
|
function useRegisteredLabelId(idProp, setLabelId) {
|
|
8
18
|
const id = useButton.useBaseUiId(idProp);
|
|
9
19
|
useButton.useIsoLayoutEffect(() => {
|
|
@@ -77,9 +87,9 @@ function focusElementWithVisible(element) {
|
|
|
77
87
|
element.focus({
|
|
78
88
|
// Available from Chrome 144+ (January 2026).
|
|
79
89
|
// Safari and Firefox already support it.
|
|
80
|
-
// @ts-expect-error not available in types yet
|
|
81
90
|
focusVisible: true
|
|
82
91
|
});
|
|
83
92
|
}
|
|
84
93
|
|
|
94
|
+
exports.stringifyLocale = stringifyLocale;
|
|
85
95
|
exports.useLabel = useLabel;
|
package/dist/useLabel-es.js
CHANGED
|
@@ -2,6 +2,16 @@ import { a as isHTMLElement } from './floating-ui.utils.dom-es.js';
|
|
|
2
2
|
import { u as useBaseUiId, a as useIsoLayoutEffect, b as useStableCallback, g as getTarget, o as ownerDocument } from './useButton-es.js';
|
|
3
3
|
import { u as useLabelableContext } from './useLabelableId-es.js';
|
|
4
4
|
|
|
5
|
+
function stringifyLocale(locale) {
|
|
6
|
+
if (Array.isArray(locale)) {
|
|
7
|
+
return locale.map(value => stringifyLocale(value)).join(',');
|
|
8
|
+
}
|
|
9
|
+
if (locale == null) {
|
|
10
|
+
return '';
|
|
11
|
+
}
|
|
12
|
+
return String(locale);
|
|
13
|
+
}
|
|
14
|
+
|
|
5
15
|
function useRegisteredLabelId(idProp, setLabelId) {
|
|
6
16
|
const id = useBaseUiId(idProp);
|
|
7
17
|
useIsoLayoutEffect(() => {
|
|
@@ -75,9 +85,8 @@ function focusElementWithVisible(element) {
|
|
|
75
85
|
element.focus({
|
|
76
86
|
// Available from Chrome 144+ (January 2026).
|
|
77
87
|
// Safari and Firefox already support it.
|
|
78
|
-
// @ts-expect-error not available in types yet
|
|
79
88
|
focusVisible: true
|
|
80
89
|
});
|
|
81
90
|
}
|
|
82
91
|
|
|
83
|
-
export { useLabel as u };
|
|
92
|
+
export { stringifyLocale as s, useLabel as u };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var ReactDOM = require('react-dom');
|
|
4
|
-
var useButton = require('./useButton-cjs.js');
|
|
5
3
|
var React = require('react');
|
|
4
|
+
var useButton = require('./useButton-cjs.js');
|
|
6
5
|
var useRenderElement = require('./useRenderElement-cjs.js');
|
|
7
6
|
var floatingUi_utils_dom = require('./floating-ui.utils.dom-cjs.js');
|
|
8
7
|
|
|
@@ -23,7 +22,6 @@ function _interopNamespaceDefault(e) {
|
|
|
23
22
|
return Object.freeze(n);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
var ReactDOM__namespace = /*#__PURE__*/_interopNamespaceDefault(ReactDOM);
|
|
27
25
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
28
26
|
|
|
29
27
|
let FieldControlDataAttributes = /*#__PURE__*/function (FieldControlDataAttributes) {
|
|
@@ -32,11 +30,11 @@ let FieldControlDataAttributes = /*#__PURE__*/function (FieldControlDataAttribut
|
|
|
32
30
|
*/
|
|
33
31
|
FieldControlDataAttributes["disabled"] = "data-disabled";
|
|
34
32
|
/**
|
|
35
|
-
* Present when the field is in valid state.
|
|
33
|
+
* Present when the field is in a valid state.
|
|
36
34
|
*/
|
|
37
35
|
FieldControlDataAttributes["valid"] = "data-valid";
|
|
38
36
|
/**
|
|
39
|
-
* Present when the field is in invalid state.
|
|
37
|
+
* Present when the field is in an invalid state.
|
|
40
38
|
*/
|
|
41
39
|
FieldControlDataAttributes["invalid"] = "data-invalid";
|
|
42
40
|
/**
|
|
@@ -98,7 +96,7 @@ const fieldValidityMapping = {
|
|
|
98
96
|
}
|
|
99
97
|
};
|
|
100
98
|
|
|
101
|
-
const
|
|
99
|
+
const DEFAULT_FIELD_ROOT_CONTEXT = {
|
|
102
100
|
invalid: undefined,
|
|
103
101
|
name: undefined,
|
|
104
102
|
validityData: {
|
|
@@ -126,15 +124,18 @@ const FieldRootContext = /*#__PURE__*/React__namespace.createContext({
|
|
|
126
124
|
markedDirtyRef: {
|
|
127
125
|
current: false
|
|
128
126
|
},
|
|
127
|
+
registerFieldControl: useRenderElement.NOOP,
|
|
129
128
|
validation: {
|
|
130
|
-
getValidationProps: (props = useRenderElement.EMPTY_OBJECT) => props,
|
|
131
|
-
getInputValidationProps: (props = useRenderElement.EMPTY_OBJECT) => props,
|
|
129
|
+
getValidationProps: (_disabled, props = useRenderElement.EMPTY_OBJECT) => props,
|
|
132
130
|
inputRef: {
|
|
133
131
|
current: null
|
|
134
132
|
},
|
|
135
|
-
|
|
133
|
+
registerInput: useRenderElement.NOOP,
|
|
134
|
+
commit: async () => {},
|
|
135
|
+
change: useRenderElement.NOOP
|
|
136
136
|
}
|
|
137
|
-
}
|
|
137
|
+
};
|
|
138
|
+
const FieldRootContext = /*#__PURE__*/React__namespace.createContext(DEFAULT_FIELD_ROOT_CONTEXT);
|
|
138
139
|
if (process.env.NODE_ENV !== "production") FieldRootContext.displayName = "FieldRootContext";
|
|
139
140
|
function useFieldRootContext(optional = true) {
|
|
140
141
|
const context = React__namespace.useContext(FieldRootContext);
|
|
@@ -144,18 +145,31 @@ function useFieldRootContext(optional = true) {
|
|
|
144
145
|
return context;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
148
|
+
function useRegisterFieldControl(controlRef, id, value, getFormValueOverride, enabled = true, name) {
|
|
149
|
+
const {
|
|
150
|
+
registerFieldControl
|
|
151
|
+
} = useFieldRootContext();
|
|
152
|
+
const sourceRef = React__namespace.useRef(null);
|
|
153
|
+
if (!sourceRef.current) {
|
|
154
|
+
sourceRef.current = Symbol();
|
|
155
|
+
}
|
|
156
|
+
useButton.useIsoLayoutEffect(() => {
|
|
157
|
+
const source = sourceRef.current;
|
|
158
|
+
if (!source || !enabled) {
|
|
159
|
+
return undefined;
|
|
157
160
|
}
|
|
158
|
-
|
|
161
|
+
const registration = {
|
|
162
|
+
controlRef,
|
|
163
|
+
getValue: getFormValueOverride,
|
|
164
|
+
id,
|
|
165
|
+
name,
|
|
166
|
+
value
|
|
167
|
+
};
|
|
168
|
+
registerFieldControl(source, registration);
|
|
169
|
+
return () => {
|
|
170
|
+
registerFieldControl(source, undefined);
|
|
171
|
+
};
|
|
172
|
+
}, [controlRef, enabled, getFormValueOverride, id, name, registerFieldControl, value]);
|
|
159
173
|
}
|
|
160
174
|
|
|
161
175
|
const FormContext = /*#__PURE__*/React__namespace.createContext({
|
|
@@ -176,74 +190,6 @@ function useFormContext() {
|
|
|
176
190
|
return React__namespace.useContext(FormContext);
|
|
177
191
|
}
|
|
178
192
|
|
|
179
|
-
function useField(params) {
|
|
180
|
-
const {
|
|
181
|
-
enabled = true,
|
|
182
|
-
value,
|
|
183
|
-
id,
|
|
184
|
-
name,
|
|
185
|
-
controlRef,
|
|
186
|
-
commit
|
|
187
|
-
} = params;
|
|
188
|
-
const {
|
|
189
|
-
formRef
|
|
190
|
-
} = useFormContext();
|
|
191
|
-
const {
|
|
192
|
-
invalid,
|
|
193
|
-
markedDirtyRef,
|
|
194
|
-
validityData,
|
|
195
|
-
setValidityData
|
|
196
|
-
} = useFieldRootContext();
|
|
197
|
-
const getValue = useButton.useStableCallback(params.getValue);
|
|
198
|
-
useButton.useIsoLayoutEffect(() => {
|
|
199
|
-
if (!enabled) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
let initialValue = value;
|
|
203
|
-
if (initialValue === undefined) {
|
|
204
|
-
initialValue = getValue();
|
|
205
|
-
}
|
|
206
|
-
if (validityData.initialValue === null && initialValue !== null) {
|
|
207
|
-
setValidityData(prev => ({
|
|
208
|
-
...prev,
|
|
209
|
-
initialValue
|
|
210
|
-
}));
|
|
211
|
-
}
|
|
212
|
-
}, [enabled, setValidityData, value, validityData.initialValue, getValue]);
|
|
213
|
-
useButton.useIsoLayoutEffect(() => {
|
|
214
|
-
if (!enabled || !id) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
formRef.current.fields.set(id, {
|
|
218
|
-
getValue,
|
|
219
|
-
name,
|
|
220
|
-
controlRef,
|
|
221
|
-
validityData: getCombinedFieldValidityData(validityData, invalid),
|
|
222
|
-
validate(flushSync = true) {
|
|
223
|
-
let nextValue = value;
|
|
224
|
-
if (nextValue === undefined) {
|
|
225
|
-
nextValue = getValue();
|
|
226
|
-
}
|
|
227
|
-
markedDirtyRef.current = true;
|
|
228
|
-
if (!flushSync) {
|
|
229
|
-
commit(nextValue);
|
|
230
|
-
} else {
|
|
231
|
-
// Synchronously update the validity state so the submit event can be prevented.
|
|
232
|
-
ReactDOM__namespace.flushSync(() => commit(nextValue));
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
}, [commit, controlRef, enabled, formRef, getValue, id, invalid, markedDirtyRef, name, validityData, value]);
|
|
237
|
-
useButton.useIsoLayoutEffect(() => {
|
|
238
|
-
const fields = formRef.current.fields;
|
|
239
|
-
return () => {
|
|
240
|
-
if (id) {
|
|
241
|
-
fields.delete(id);
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
}, [formRef, id]);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
193
|
/**
|
|
248
194
|
* A context for providing [labelable elements](https://html.spec.whatwg.org/multipage/forms.html#category-label)\
|
|
249
195
|
* with an accessible name (label) and description.
|
|
@@ -319,14 +265,14 @@ function useLabelableId(params = {}) {
|
|
|
319
265
|
return controlId ?? defaultId;
|
|
320
266
|
}
|
|
321
267
|
|
|
268
|
+
exports.DEFAULT_FIELD_ROOT_CONTEXT = DEFAULT_FIELD_ROOT_CONTEXT;
|
|
322
269
|
exports.DEFAULT_FIELD_STATE_ATTRIBUTES = DEFAULT_FIELD_STATE_ATTRIBUTES;
|
|
323
270
|
exports.DEFAULT_VALIDITY_STATE = DEFAULT_VALIDITY_STATE;
|
|
324
271
|
exports.FieldRootContext = FieldRootContext;
|
|
325
272
|
exports.LabelableContext = LabelableContext;
|
|
326
273
|
exports.fieldValidityMapping = fieldValidityMapping;
|
|
327
|
-
exports.getCombinedFieldValidityData = getCombinedFieldValidityData;
|
|
328
|
-
exports.useField = useField;
|
|
329
274
|
exports.useFieldRootContext = useFieldRootContext;
|
|
330
275
|
exports.useFormContext = useFormContext;
|
|
331
276
|
exports.useLabelableContext = useLabelableContext;
|
|
332
277
|
exports.useLabelableId = useLabelableId;
|
|
278
|
+
exports.useRegisterFieldControl = useRegisterFieldControl;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import * as ReactDOM from 'react-dom';
|
|
2
|
-
import { b as useStableCallback, a as useIsoLayoutEffect, u as useBaseUiId } from './useButton-es.js';
|
|
3
1
|
import * as React from 'react';
|
|
4
|
-
import {
|
|
2
|
+
import { a as useIsoLayoutEffect, u as useBaseUiId, b as useStableCallback } from './useButton-es.js';
|
|
3
|
+
import { N as NOOP, E as EMPTY_OBJECT, f as formatErrorMessage, a as useRefWithInit } from './useRenderElement-es.js';
|
|
5
4
|
import { b as isElement } from './floating-ui.utils.dom-es.js';
|
|
6
5
|
|
|
7
6
|
let FieldControlDataAttributes = /*#__PURE__*/function (FieldControlDataAttributes) {
|
|
@@ -10,11 +9,11 @@ let FieldControlDataAttributes = /*#__PURE__*/function (FieldControlDataAttribut
|
|
|
10
9
|
*/
|
|
11
10
|
FieldControlDataAttributes["disabled"] = "data-disabled";
|
|
12
11
|
/**
|
|
13
|
-
* Present when the field is in valid state.
|
|
12
|
+
* Present when the field is in a valid state.
|
|
14
13
|
*/
|
|
15
14
|
FieldControlDataAttributes["valid"] = "data-valid";
|
|
16
15
|
/**
|
|
17
|
-
* Present when the field is in invalid state.
|
|
16
|
+
* Present when the field is in an invalid state.
|
|
18
17
|
*/
|
|
19
18
|
FieldControlDataAttributes["invalid"] = "data-invalid";
|
|
20
19
|
/**
|
|
@@ -76,7 +75,7 @@ const fieldValidityMapping = {
|
|
|
76
75
|
}
|
|
77
76
|
};
|
|
78
77
|
|
|
79
|
-
const
|
|
78
|
+
const DEFAULT_FIELD_ROOT_CONTEXT = {
|
|
80
79
|
invalid: undefined,
|
|
81
80
|
name: undefined,
|
|
82
81
|
validityData: {
|
|
@@ -104,15 +103,18 @@ const FieldRootContext = /*#__PURE__*/React.createContext({
|
|
|
104
103
|
markedDirtyRef: {
|
|
105
104
|
current: false
|
|
106
105
|
},
|
|
106
|
+
registerFieldControl: NOOP,
|
|
107
107
|
validation: {
|
|
108
|
-
getValidationProps: (props = EMPTY_OBJECT) => props,
|
|
109
|
-
getInputValidationProps: (props = EMPTY_OBJECT) => props,
|
|
108
|
+
getValidationProps: (_disabled, props = EMPTY_OBJECT) => props,
|
|
110
109
|
inputRef: {
|
|
111
110
|
current: null
|
|
112
111
|
},
|
|
113
|
-
|
|
112
|
+
registerInput: NOOP,
|
|
113
|
+
commit: async () => {},
|
|
114
|
+
change: NOOP
|
|
114
115
|
}
|
|
115
|
-
}
|
|
116
|
+
};
|
|
117
|
+
const FieldRootContext = /*#__PURE__*/React.createContext(DEFAULT_FIELD_ROOT_CONTEXT);
|
|
116
118
|
if (process.env.NODE_ENV !== "production") FieldRootContext.displayName = "FieldRootContext";
|
|
117
119
|
function useFieldRootContext(optional = true) {
|
|
118
120
|
const context = React.useContext(FieldRootContext);
|
|
@@ -122,18 +124,31 @@ function useFieldRootContext(optional = true) {
|
|
|
122
124
|
return context;
|
|
123
125
|
}
|
|
124
126
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
function useRegisterFieldControl(controlRef, id, value, getFormValueOverride, enabled = true, name) {
|
|
128
|
+
const {
|
|
129
|
+
registerFieldControl
|
|
130
|
+
} = useFieldRootContext();
|
|
131
|
+
const sourceRef = React.useRef(null);
|
|
132
|
+
if (!sourceRef.current) {
|
|
133
|
+
sourceRef.current = Symbol();
|
|
134
|
+
}
|
|
135
|
+
useIsoLayoutEffect(() => {
|
|
136
|
+
const source = sourceRef.current;
|
|
137
|
+
if (!source || !enabled) {
|
|
138
|
+
return undefined;
|
|
135
139
|
}
|
|
136
|
-
|
|
140
|
+
const registration = {
|
|
141
|
+
controlRef,
|
|
142
|
+
getValue: getFormValueOverride,
|
|
143
|
+
id,
|
|
144
|
+
name,
|
|
145
|
+
value
|
|
146
|
+
};
|
|
147
|
+
registerFieldControl(source, registration);
|
|
148
|
+
return () => {
|
|
149
|
+
registerFieldControl(source, undefined);
|
|
150
|
+
};
|
|
151
|
+
}, [controlRef, enabled, getFormValueOverride, id, name, registerFieldControl, value]);
|
|
137
152
|
}
|
|
138
153
|
|
|
139
154
|
const FormContext = /*#__PURE__*/React.createContext({
|
|
@@ -154,74 +169,6 @@ function useFormContext() {
|
|
|
154
169
|
return React.useContext(FormContext);
|
|
155
170
|
}
|
|
156
171
|
|
|
157
|
-
function useField(params) {
|
|
158
|
-
const {
|
|
159
|
-
enabled = true,
|
|
160
|
-
value,
|
|
161
|
-
id,
|
|
162
|
-
name,
|
|
163
|
-
controlRef,
|
|
164
|
-
commit
|
|
165
|
-
} = params;
|
|
166
|
-
const {
|
|
167
|
-
formRef
|
|
168
|
-
} = useFormContext();
|
|
169
|
-
const {
|
|
170
|
-
invalid,
|
|
171
|
-
markedDirtyRef,
|
|
172
|
-
validityData,
|
|
173
|
-
setValidityData
|
|
174
|
-
} = useFieldRootContext();
|
|
175
|
-
const getValue = useStableCallback(params.getValue);
|
|
176
|
-
useIsoLayoutEffect(() => {
|
|
177
|
-
if (!enabled) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
let initialValue = value;
|
|
181
|
-
if (initialValue === undefined) {
|
|
182
|
-
initialValue = getValue();
|
|
183
|
-
}
|
|
184
|
-
if (validityData.initialValue === null && initialValue !== null) {
|
|
185
|
-
setValidityData(prev => ({
|
|
186
|
-
...prev,
|
|
187
|
-
initialValue
|
|
188
|
-
}));
|
|
189
|
-
}
|
|
190
|
-
}, [enabled, setValidityData, value, validityData.initialValue, getValue]);
|
|
191
|
-
useIsoLayoutEffect(() => {
|
|
192
|
-
if (!enabled || !id) {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
formRef.current.fields.set(id, {
|
|
196
|
-
getValue,
|
|
197
|
-
name,
|
|
198
|
-
controlRef,
|
|
199
|
-
validityData: getCombinedFieldValidityData(validityData, invalid),
|
|
200
|
-
validate(flushSync = true) {
|
|
201
|
-
let nextValue = value;
|
|
202
|
-
if (nextValue === undefined) {
|
|
203
|
-
nextValue = getValue();
|
|
204
|
-
}
|
|
205
|
-
markedDirtyRef.current = true;
|
|
206
|
-
if (!flushSync) {
|
|
207
|
-
commit(nextValue);
|
|
208
|
-
} else {
|
|
209
|
-
// Synchronously update the validity state so the submit event can be prevented.
|
|
210
|
-
ReactDOM.flushSync(() => commit(nextValue));
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}, [commit, controlRef, enabled, formRef, getValue, id, invalid, markedDirtyRef, name, validityData, value]);
|
|
215
|
-
useIsoLayoutEffect(() => {
|
|
216
|
-
const fields = formRef.current.fields;
|
|
217
|
-
return () => {
|
|
218
|
-
if (id) {
|
|
219
|
-
fields.delete(id);
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
}, [formRef, id]);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
172
|
/**
|
|
226
173
|
* A context for providing [labelable elements](https://html.spec.whatwg.org/multipage/forms.html#category-label)\
|
|
227
174
|
* with an accessible name (label) and description.
|
|
@@ -297,4 +244,4 @@ function useLabelableId(params = {}) {
|
|
|
297
244
|
return controlId ?? defaultId;
|
|
298
245
|
}
|
|
299
246
|
|
|
300
|
-
export { DEFAULT_VALIDITY_STATE as D, FieldRootContext as F, LabelableContext as L, useFormContext as a, useFieldRootContext as b, useLabelableId as c,
|
|
247
|
+
export { DEFAULT_VALIDITY_STATE as D, FieldRootContext as F, LabelableContext as L, useFormContext as a, useFieldRootContext as b, useLabelableId as c, useRegisterFieldControl as d, DEFAULT_FIELD_ROOT_CONTEXT as e, fieldValidityMapping as f, DEFAULT_FIELD_STATE_ATTRIBUTES as g, useLabelableContext as u };
|
|
@@ -55,7 +55,7 @@ const EMPTY_PROPS = {};
|
|
|
55
55
|
* Props can either be provided as objects or as functions that take the previous props as an argument.
|
|
56
56
|
* The function will receive the merged props up to that point (going from left to right):
|
|
57
57
|
* so in the case of `(obj1, obj2, fn, obj3)`, `fn` will receive the merged props of `obj1` and `obj2`.
|
|
58
|
-
* The function is responsible for chaining event handlers if needed (
|
|
58
|
+
* The function is responsible for chaining event handlers if needed (that is, we don't run the merge logic).
|
|
59
59
|
*
|
|
60
60
|
* Event handlers returned by the functions are not automatically prevented when `preventBaseUIHandler` is called.
|
|
61
61
|
* They must check `event.baseUIHandlerPrevented` themselves and bail out if it's true.
|
|
@@ -71,21 +71,23 @@ const EMPTY_PROPS = {};
|
|
|
71
71
|
*/
|
|
72
72
|
|
|
73
73
|
function mergeProps(a, b, c, d, e) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
if (!c && !d && !e && !a) {
|
|
75
|
+
return createInitialMergedProps(b);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// We need to mutably own `merged`.
|
|
79
|
+
let merged = createInitialMergedProps(a);
|
|
78
80
|
if (b) {
|
|
79
|
-
merged =
|
|
81
|
+
merged = mergeInto(merged, b);
|
|
80
82
|
}
|
|
81
83
|
if (c) {
|
|
82
|
-
merged =
|
|
84
|
+
merged = mergeInto(merged, c);
|
|
83
85
|
}
|
|
84
86
|
if (d) {
|
|
85
|
-
merged =
|
|
87
|
+
merged = mergeInto(merged, d);
|
|
86
88
|
}
|
|
87
89
|
if (e) {
|
|
88
|
-
merged =
|
|
90
|
+
merged = mergeInto(merged, e);
|
|
89
91
|
}
|
|
90
92
|
return merged;
|
|
91
93
|
}
|
|
@@ -109,24 +111,46 @@ function mergePropsN(props) {
|
|
|
109
111
|
return EMPTY_PROPS;
|
|
110
112
|
}
|
|
111
113
|
if (props.length === 1) {
|
|
112
|
-
return
|
|
114
|
+
return createInitialMergedProps(props[0]);
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
// We need to mutably own `merged
|
|
116
|
-
let merged =
|
|
117
|
-
...resolvePropsGetter(props[0], EMPTY_PROPS)
|
|
118
|
-
};
|
|
117
|
+
// We need to mutably own `merged`.
|
|
118
|
+
let merged = createInitialMergedProps(props[0]);
|
|
119
119
|
for (let i = 1; i < props.length; i += 1) {
|
|
120
|
-
merged =
|
|
120
|
+
merged = mergeInto(merged, props[i]);
|
|
121
121
|
}
|
|
122
122
|
return merged;
|
|
123
123
|
}
|
|
124
|
-
function
|
|
124
|
+
function createInitialMergedProps(inputProps) {
|
|
125
125
|
if (isPropsGetter(inputProps)) {
|
|
126
|
-
|
|
126
|
+
// Getter-returned handlers intentionally keep their existing semantics.
|
|
127
|
+
return {
|
|
128
|
+
...resolvePropsGetter(inputProps, EMPTY_PROPS)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return copyInitialProps(inputProps);
|
|
132
|
+
}
|
|
133
|
+
function mergeInto(merged, inputProps) {
|
|
134
|
+
if (isPropsGetter(inputProps)) {
|
|
135
|
+
return resolvePropsGetter(inputProps, merged);
|
|
127
136
|
}
|
|
128
137
|
return mutablyMergeInto(merged, inputProps);
|
|
129
138
|
}
|
|
139
|
+
function copyInitialProps(inputProps) {
|
|
140
|
+
const copiedProps = {
|
|
141
|
+
...inputProps
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// `copiedProps` is our fresh own-object copy, so iterating with `for...in` is safe here.
|
|
145
|
+
// eslint-disable-next-line guard-for-in
|
|
146
|
+
for (const propName in copiedProps) {
|
|
147
|
+
const propValue = copiedProps[propName];
|
|
148
|
+
if (isEventHandler(propName, propValue)) {
|
|
149
|
+
copiedProps[propName] = wrapEventHandler(propValue);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return copiedProps;
|
|
153
|
+
}
|
|
130
154
|
|
|
131
155
|
/**
|
|
132
156
|
* Merges two sets of props. In case of conflicts, the external props take precedence.
|
|
@@ -183,23 +207,36 @@ function mergeEventHandlers(ourHandler, theirHandler) {
|
|
|
183
207
|
return ourHandler;
|
|
184
208
|
}
|
|
185
209
|
if (!ourHandler) {
|
|
186
|
-
return theirHandler;
|
|
210
|
+
return wrapEventHandler(theirHandler);
|
|
187
211
|
}
|
|
188
|
-
return
|
|
212
|
+
return (...args) => {
|
|
213
|
+
const event = args[0];
|
|
189
214
|
if (isSyntheticEvent(event)) {
|
|
190
215
|
const baseUIEvent = event;
|
|
191
216
|
makeEventPreventable(baseUIEvent);
|
|
192
|
-
const result = theirHandler(
|
|
217
|
+
const result = theirHandler(...args);
|
|
193
218
|
if (!baseUIEvent.baseUIHandlerPrevented) {
|
|
194
|
-
ourHandler?.(
|
|
219
|
+
ourHandler?.(...args);
|
|
195
220
|
}
|
|
196
221
|
return result;
|
|
197
222
|
}
|
|
198
|
-
const result = theirHandler(
|
|
199
|
-
ourHandler?.(
|
|
223
|
+
const result = theirHandler(...args);
|
|
224
|
+
ourHandler?.(...args);
|
|
200
225
|
return result;
|
|
201
226
|
};
|
|
202
227
|
}
|
|
228
|
+
function wrapEventHandler(handler) {
|
|
229
|
+
if (!handler) {
|
|
230
|
+
return handler;
|
|
231
|
+
}
|
|
232
|
+
return (...args) => {
|
|
233
|
+
const event = args[0];
|
|
234
|
+
if (isSyntheticEvent(event)) {
|
|
235
|
+
makeEventPreventable(event);
|
|
236
|
+
}
|
|
237
|
+
return handler(...args);
|
|
238
|
+
};
|
|
239
|
+
}
|
|
203
240
|
function makeEventPreventable(event) {
|
|
204
241
|
event.preventBaseUIHandler = () => {
|
|
205
242
|
event.baseUIHandlerPrevented = true;
|
|
@@ -484,7 +521,12 @@ function useRenderElementProps(componentProps, params = {}) {
|
|
|
484
521
|
const className = enabled ? resolveClassName(classNameProp, state) : undefined;
|
|
485
522
|
const style = enabled ? resolveStyle(styleProp, state) : undefined;
|
|
486
523
|
const stateProps = enabled ? getStateAttributesProps(state, stateAttributesMapping) : EMPTY_OBJECT;
|
|
487
|
-
const
|
|
524
|
+
const resolvedProps = enabled && props ? resolveRenderFunctionProps(props) : undefined;
|
|
525
|
+
|
|
526
|
+
// Ensure outProps is always a new mutable object when enabled, never EMPTY_OBJECT.
|
|
527
|
+
// This prevents potential TypeError when setting ref, className, or style properties,
|
|
528
|
+
// since EMPTY_OBJECT is frozen and mutations would fail in strict mode.
|
|
529
|
+
const outProps = enabled ? mergeObjects(stateProps, resolvedProps) ?? {} : EMPTY_OBJECT;
|
|
488
530
|
|
|
489
531
|
// SAFETY: The `useMergedRefs` functions use a single hook to store the same value,
|
|
490
532
|
// switching between them at runtime is safe. If this assertion fails, React will
|
|
@@ -512,12 +554,20 @@ function useRenderElementProps(componentProps, params = {}) {
|
|
|
512
554
|
}
|
|
513
555
|
return outProps;
|
|
514
556
|
}
|
|
557
|
+
function resolveRenderFunctionProps(props) {
|
|
558
|
+
if (Array.isArray(props)) {
|
|
559
|
+
return mergePropsN(props);
|
|
560
|
+
}
|
|
561
|
+
return mergeProps(undefined, props);
|
|
562
|
+
}
|
|
515
563
|
|
|
516
564
|
// The symbol React uses internally for lazy components
|
|
517
565
|
// https://github.com/facebook/react/blob/a0566250b210499b4c5677f5ac2eedbd71d51a1b/packages/shared/ReactSymbols.js#L31
|
|
518
566
|
//
|
|
519
567
|
// TODO delete once https://github.com/facebook/react/issues/32392 is fixed
|
|
520
568
|
const REACT_LAZY_TYPE = Symbol.for('react.lazy');
|
|
569
|
+
const COMPONENT_IDENTIFIER_PATTERN = /^[A-Z][A-Za-z0-9$]*$/;
|
|
570
|
+
const LOWERCASE_CHARACTER_PATTERN = /[a-z]/;
|
|
521
571
|
function evaluateRenderProp(element, render, props, state) {
|
|
522
572
|
if (render) {
|
|
523
573
|
if (typeof render === 'function') {
|
|
@@ -546,6 +596,8 @@ function evaluateRenderProp(element, render, props, state) {
|
|
|
546
596
|
// so we can throw before with custom message.
|
|
547
597
|
if (process.env.NODE_ENV !== 'production') {
|
|
548
598
|
if (! /*#__PURE__*/React__namespace.isValidElement(newElement)) {
|
|
599
|
+
// TODO: fix mui/no-guarded-throw
|
|
600
|
+
// eslint-disable-next-line mui/no-guarded-throw
|
|
549
601
|
throw new Error(['Base UI: The `render` prop was provided an invalid React element as `React.isValidElement(render)` is `false`.', 'A valid React element must be provided to the `render` prop because it is cloned with props to replace the default element.', 'https://base-ui.com/r/invalid-render-prop'].join('\n'));
|
|
550
602
|
}
|
|
551
603
|
}
|
|
@@ -565,8 +617,10 @@ function warnIfRenderPropLooksLikeComponent(renderFn) {
|
|
|
565
617
|
if (functionName.length === 0) {
|
|
566
618
|
return;
|
|
567
619
|
}
|
|
568
|
-
|
|
569
|
-
|
|
620
|
+
if (!COMPONENT_IDENTIFIER_PATTERN.test(functionName)) {
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
if (!LOWERCASE_CHARACTER_PATTERN.test(functionName)) {
|
|
570
624
|
return;
|
|
571
625
|
}
|
|
572
626
|
warn(`The \`render\` prop received a function named \`${functionName}\` that starts with an uppercase letter.`, 'This usually means a React component was passed directly as `render={Component}`.', 'Base UI calls `render` as a plain function, which can break the Rules of Hooks during reconciliation.', 'If this is an intentional render callback, rename it to start with a lowercase letter.', 'Use `render={<Component />}` or `render={(props) => <Component {...props} />}` instead.', 'https://base-ui.com/r/invalid-render-prop');
|
|
@@ -599,3 +653,4 @@ exports.mergeProps = mergeProps;
|
|
|
599
653
|
exports.useMergedRefs = useMergedRefs;
|
|
600
654
|
exports.useRefWithInit = useRefWithInit;
|
|
601
655
|
exports.useRenderElement = useRenderElement;
|
|
656
|
+
exports.warn = warn;
|