@allxsmith/bestax-bulma 5.26.0 → 5.26.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/index.cjs +80 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +80 -28
- package/dist/index.esm.js.map +1 -1
- package/dist/types/form/DateInputBase.d.ts +6 -1
- package/dist/types/form/DateTimeInputBase.d.ts +6 -1
- package/dist/types/form/TimeInputBase.d.ts +6 -1
- package/dist/types/form/_pickerInternals/PickerPopover.d.ts +7 -0
- package/dist/types/form/_pickerInternals/useSegmentedEntry.d.ts +5 -0
- package/dist/types/helpers/Theme.d.ts +9 -0
- package/dist/types-cjs/form/DateInputBase.d.ts +6 -1
- package/dist/types-cjs/form/DateTimeInputBase.d.ts +6 -1
- package/dist/types-cjs/form/TimeInputBase.d.ts +6 -1
- package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +7 -0
- package/dist/types-cjs/form/_pickerInternals/useSegmentedEntry.d.ts +5 -0
- package/dist/types-cjs/helpers/Theme.d.ts +9 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -12190,7 +12190,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min, max,
|
|
|
12190
12190
|
Calendar.displayName = 'Calendar';
|
|
12191
12191
|
|
|
12192
12192
|
const isBrowser = typeof window !== 'undefined';
|
|
12193
|
-
const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'bottom-left', appendToBody = false, className, trapFocus = true, closeOnClickOutside = true, closeOnEscape = true, ariaLabel, ariaLabelledBy, role = 'dialog', id, }) => {
|
|
12193
|
+
const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'bottom-left', appendToBody = false, className, trapFocus = true, closeOnClickOutside = true, closeOnEscape = true, ariaLabel, ariaLabelledBy, role = 'dialog', id, restoreFocusRef, }) => {
|
|
12194
12194
|
const panelRef = useRef(null);
|
|
12195
12195
|
const resolved = useAnchoredPosition(anchorRef, panelRef, {
|
|
12196
12196
|
active: isOpen,
|
|
@@ -12227,7 +12227,10 @@ const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'botto
|
|
|
12227
12227
|
document.addEventListener('keydown', handler);
|
|
12228
12228
|
return () => document.removeEventListener('keydown', handler);
|
|
12229
12229
|
}, [isOpen, closeOnEscape, onClose]);
|
|
12230
|
-
useFocusTrap(panelRef, {
|
|
12230
|
+
useFocusTrap(panelRef, {
|
|
12231
|
+
active: isOpen && trapFocus,
|
|
12232
|
+
restoreFocus: restoreFocusRef ?? true,
|
|
12233
|
+
});
|
|
12231
12234
|
const panelClass = usePrefixedClassNames('picker-popover', {
|
|
12232
12235
|
'is-active': isOpen,
|
|
12233
12236
|
[`is-${resolved.position}`]: true,
|
|
@@ -12632,6 +12635,37 @@ function useSegmentedEntry(params) {
|
|
|
12632
12635
|
// change. Kept in a ref because key handlers read+update synchronously
|
|
12633
12636
|
// within the same event tick.
|
|
12634
12637
|
const typedDigitsRef = useRef('');
|
|
12638
|
+
// The text focus seeded an empty picker with, until the user edits it or
|
|
12639
|
+
// leaves. While the text still matches it, nothing has been typed.
|
|
12640
|
+
const seedRef = useRef(null);
|
|
12641
|
+
// Whether the input's current focus is the one a closing popover handed
|
|
12642
|
+
// back, until focus leaves the picker.
|
|
12643
|
+
const handedBackRef = useRef(false);
|
|
12644
|
+
// A seed the popover never turned into a value closes with it, wherever
|
|
12645
|
+
// focus goes, so a dismissed empty field stays empty.
|
|
12646
|
+
//
|
|
12647
|
+
// As the popover closes, its focus trap hands focus back to the input. That
|
|
12648
|
+
// focus is not the user arriving: it must not open the popover again under
|
|
12649
|
+
// `openOnFocus`, or seed an empty picker that leaving would then commit.
|
|
12650
|
+
// `closingRef` is set in the layout phase of the commit that closes it and
|
|
12651
|
+
// cleared by that commit's effects, and React runs a commit's effect
|
|
12652
|
+
// cleanups, the trap's among them, before any of its effects, so a focus
|
|
12653
|
+
// in between is the one handed back.
|
|
12654
|
+
const closingRef = useRef(false);
|
|
12655
|
+
const wasOpenRef = useRef(isOpen);
|
|
12656
|
+
useLayoutEffect(() => {
|
|
12657
|
+
if (wasOpenRef.current && !isOpen) {
|
|
12658
|
+
closingRef.current = true;
|
|
12659
|
+
if (!value && seedRef.current !== null && text === seedRef.current) {
|
|
12660
|
+
setText('');
|
|
12661
|
+
}
|
|
12662
|
+
seedRef.current = null;
|
|
12663
|
+
}
|
|
12664
|
+
wasOpenRef.current = isOpen;
|
|
12665
|
+
}, [isOpen, value, text, setText]);
|
|
12666
|
+
useEffect(() => {
|
|
12667
|
+
closingRef.current = false;
|
|
12668
|
+
}, [isOpen]);
|
|
12635
12669
|
// Segment mode is unavailable for disabled / read-only / non-editable
|
|
12636
12670
|
// pickers and for Intl-options / variable-width formats (segmentMap null).
|
|
12637
12671
|
const segmentEditable = !!segmentMap && !!editable && !disabled && !readOnly;
|
|
@@ -12688,6 +12722,7 @@ function useSegmentedEntry(params) {
|
|
|
12688
12722
|
// segment mode is inactive.
|
|
12689
12723
|
if (activeSegmentIdx !== null && segmentEditable)
|
|
12690
12724
|
return;
|
|
12725
|
+
seedRef.current = null;
|
|
12691
12726
|
setText(e.target.value);
|
|
12692
12727
|
}, [activeSegmentIdx, segmentEditable, setText]);
|
|
12693
12728
|
const handleBlur = useCallback((e) => {
|
|
@@ -12705,6 +12740,16 @@ function useSegmentedEntry(params) {
|
|
|
12705
12740
|
}
|
|
12706
12741
|
setActiveSegmentIdx(null);
|
|
12707
12742
|
typedDigitsRef.current = '';
|
|
12743
|
+
seedRef.current = null;
|
|
12744
|
+
const handedBack = handedBackRef.current;
|
|
12745
|
+
handedBackRef.current = false;
|
|
12746
|
+
// Leaving after a dismiss commits only what was typed since. Text that
|
|
12747
|
+
// still shows the value wasn't, and re-parsing it could drop what the
|
|
12748
|
+
// format leaves out, such as seconds.
|
|
12749
|
+
if (handedBack && value && text === formatFn(value, format, locale)) {
|
|
12750
|
+
onBlur?.(e);
|
|
12751
|
+
return;
|
|
12752
|
+
}
|
|
12708
12753
|
const parsed = tryParse(text);
|
|
12709
12754
|
if (parsed && isAllowed(parsed)) {
|
|
12710
12755
|
commitValue(parsed);
|
|
@@ -12727,13 +12772,19 @@ function useSegmentedEntry(params) {
|
|
|
12727
12772
|
onBlur,
|
|
12728
12773
|
]);
|
|
12729
12774
|
const handleFocus = useCallback((e) => {
|
|
12730
|
-
|
|
12775
|
+
const handedBack = closingRef.current;
|
|
12776
|
+
handedBackRef.current = handedBack;
|
|
12777
|
+
if (!handedBack && openOnFocus && popover && !disabled && !readOnly) {
|
|
12731
12778
|
setOpen(true);
|
|
12779
|
+
}
|
|
12732
12780
|
// Enter segment mode: prime an initial value (so editing works even when
|
|
12733
|
-
// empty), seed the text, and highlight the first editable segment.
|
|
12781
|
+
// empty), seed the text, and highlight the first editable segment. The
|
|
12782
|
+
// segment base doesn't need the seed, so focus handed back skips it.
|
|
12734
12783
|
if (segmentEditable && segmentMap) {
|
|
12735
|
-
if (!value) {
|
|
12736
|
-
|
|
12784
|
+
if (!value && !handedBack) {
|
|
12785
|
+
const seed = formatFn(makeBaseDate(), format, locale);
|
|
12786
|
+
seedRef.current = seed;
|
|
12787
|
+
setText(seed);
|
|
12737
12788
|
}
|
|
12738
12789
|
typedDigitsRef.current = '';
|
|
12739
12790
|
setActiveSegmentIdx(segmentMap.editable[0]);
|
|
@@ -13200,7 +13251,7 @@ const DateInputBase = forwardRef((props, ref) => {
|
|
|
13200
13251
|
return (jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsx("button", { type: "button", className: triggerClass, onClick: () => {
|
|
13201
13252
|
if (canOpen)
|
|
13202
13253
|
setOpen(!open);
|
|
13203
|
-
}, disabled: !canOpen, "aria-label": chooseLabel, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsx(PickerPopover, { isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: chooseLabel, id: popoverId, children: calendar }))] }));
|
|
13254
|
+
}, disabled: !canOpen, "aria-label": chooseLabel, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsx(PickerPopover, { isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: chooseLabel, id: popoverId, restoreFocusRef: inputRef, children: calendar }))] }));
|
|
13204
13255
|
});
|
|
13205
13256
|
DateInputBase.displayName = 'DateInputBase';
|
|
13206
13257
|
|
|
@@ -14173,9 +14224,6 @@ const TimeInputBase = forwardRef((props, ref) => {
|
|
|
14173
14224
|
const mobileFooterClass = usePrefixedClassNames('timeinput-footer-mobile');
|
|
14174
14225
|
const mobileFooterResetClass = usePrefixedClassNames('timeinput-footer-reset');
|
|
14175
14226
|
const mobileFooterDoneClass = usePrefixedClassNames('timeinput-footer-done');
|
|
14176
|
-
// Set from the moment the popover starts to close until the close has
|
|
14177
|
-
// committed. See `setOpenFromInput`.
|
|
14178
|
-
const closingRef = useRef(false);
|
|
14179
14227
|
const setOpen = useCallback((next) => {
|
|
14180
14228
|
setOpenState(prev => {
|
|
14181
14229
|
if (prev === next)
|
|
@@ -14185,26 +14233,11 @@ const TimeInputBase = forwardRef((props, ref) => {
|
|
|
14185
14233
|
onOpen?.();
|
|
14186
14234
|
}
|
|
14187
14235
|
else {
|
|
14188
|
-
closingRef.current = true;
|
|
14189
14236
|
onClose?.();
|
|
14190
14237
|
}
|
|
14191
14238
|
return next;
|
|
14192
14239
|
});
|
|
14193
14240
|
}, [onOpen, onClose, value]);
|
|
14194
|
-
// React runs a commit's effect cleanups before any of its effects, so on a
|
|
14195
|
-
// close this runs after the popover's focus trap has handed focus back.
|
|
14196
|
-
useEffect(() => {
|
|
14197
|
-
closingRef.current = false;
|
|
14198
|
-
}, [open]);
|
|
14199
|
-
// As the popover closes, its focus trap hands focus back to the input.
|
|
14200
|
-
// That focus is not the user arriving, so under `openOnFocus` it must not
|
|
14201
|
-
// open the popover again. The input asks to open only on focus, click or
|
|
14202
|
-
// ArrowDown, so a request while a close commits can only be that one.
|
|
14203
|
-
const setOpenFromInput = useCallback((next) => {
|
|
14204
|
-
if (next && closingRef.current)
|
|
14205
|
-
return;
|
|
14206
|
-
setOpen(next);
|
|
14207
|
-
}, [setOpen]);
|
|
14208
14241
|
useEffect(() => {
|
|
14209
14242
|
setText(value ? formatTime(value, defaultFormat, locale) : '');
|
|
14210
14243
|
}, [value, defaultFormat, locale]);
|
|
@@ -14261,7 +14294,7 @@ const TimeInputBase = forwardRef((props, ref) => {
|
|
|
14261
14294
|
openOnFocus,
|
|
14262
14295
|
closeOnSelect,
|
|
14263
14296
|
isOpen: open,
|
|
14264
|
-
setOpen
|
|
14297
|
+
setOpen,
|
|
14265
14298
|
inputRef,
|
|
14266
14299
|
containerRef,
|
|
14267
14300
|
onFocus,
|
|
@@ -14313,7 +14346,7 @@ const TimeInputBase = forwardRef((props, ref) => {
|
|
|
14313
14346
|
return (jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsx("button", { type: "button", className: triggerClass, onClick: () => {
|
|
14314
14347
|
if (canOpen)
|
|
14315
14348
|
setOpen(!open);
|
|
14316
|
-
}, disabled: !canOpen, "aria-label": t.chooseTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseTime, id: popoverId, children: panel }))] }));
|
|
14349
|
+
}, disabled: !canOpen, "aria-label": t.chooseTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseTime, id: popoverId, restoreFocusRef: inputRef, children: panel }))] }));
|
|
14317
14350
|
});
|
|
14318
14351
|
TimeInputBase.displayName = 'TimeInputBase';
|
|
14319
14352
|
|
|
@@ -14605,7 +14638,7 @@ const DateTimeInputBase = forwardRef((props, ref) => {
|
|
|
14605
14638
|
return (jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsx("input", { ref: combinedRef, type: "text", role: "combobox", "aria-haspopup": "dialog", "aria-expanded": open, "aria-controls": popoverId, autoComplete: "off", className: inputClass, value: text, placeholder: placeholder, disabled: disabled, readOnly: inputReadOnlyAttr, name: name, form: form, required: required, id: id, ...inputHandlers }), popover && triggerIcon && (jsx("button", { type: "button", className: triggerClass, onClick: () => {
|
|
14606
14639
|
if (canOpen)
|
|
14607
14640
|
setOpen(!open);
|
|
14608
|
-
}, disabled: !canOpen, "aria-label": t.chooseDateTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateTime, id: popoverId, children: panel }))] }));
|
|
14641
|
+
}, disabled: !canOpen, "aria-label": t.chooseDateTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateTime, id: popoverId, restoreFocusRef: inputRef, children: panel }))] }));
|
|
14609
14642
|
});
|
|
14610
14643
|
DateTimeInputBase.displayName = 'DateTimeInputBase';
|
|
14611
14644
|
|
|
@@ -15522,6 +15555,25 @@ const Theme = ({ bulmaVars = {}, children, className, isRoot = false, colorMode,
|
|
|
15522
15555
|
}
|
|
15523
15556
|
return { bulmaVarProps: varProps, otherProps: otherPropsObj };
|
|
15524
15557
|
}, [restProps]);
|
|
15558
|
+
// Everything left in `otherProps` lands on the wrapper div, as a helper
|
|
15559
|
+
// class or an attribute, and so does `className`. A root Theme renders no
|
|
15560
|
+
// wrapper, so under `isRoot` all of it is dropped. `radius` and `columnGap`
|
|
15561
|
+
// are not in `otherProps`; the checks above cover them.
|
|
15562
|
+
if (isRoot) {
|
|
15563
|
+
const dropped = Object.entries(otherProps)
|
|
15564
|
+
.filter(([, value]) => value !== undefined && value !== null && value !== false)
|
|
15565
|
+
.map(([key]) => key);
|
|
15566
|
+
if (className) {
|
|
15567
|
+
dropped.unshift('className');
|
|
15568
|
+
}
|
|
15569
|
+
if (dropped.length > 0) {
|
|
15570
|
+
warnOnce('Theme:root-dropped-props', `[bestax-bulma] <Theme isRoot>: a root Theme renders no wrapper ` +
|
|
15571
|
+
`element, so ${dropped.join(', ')} ` +
|
|
15572
|
+
`${dropped.length === 1 ? 'has' : 'have'} nothing to apply to. ` +
|
|
15573
|
+
'Put helper props and classes on an element inside the Theme ' +
|
|
15574
|
+
'instead.');
|
|
15575
|
+
}
|
|
15576
|
+
}
|
|
15525
15577
|
// Use Bulma classes for styling (only when not isRoot). Only a helper value
|
|
15526
15578
|
// of `radius` reaches the helper; a legacy string went to the variable.
|
|
15527
15579
|
const { bulmaHelperClasses, rest } = useBulmaClasses({
|