@allxsmith/bestax-bulma 5.26.0 → 5.26.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/index.cjs CHANGED
@@ -12192,7 +12192,7 @@ const Calendar = ({ value, focusedDate, onSelect, onFocusedDateChange, min, max,
12192
12192
  Calendar.displayName = 'Calendar';
12193
12193
 
12194
12194
  const isBrowser = typeof window !== 'undefined';
12195
- const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'bottom-left', appendToBody = false, className, trapFocus = true, closeOnClickOutside = true, closeOnEscape = true, ariaLabel, ariaLabelledBy, role = 'dialog', id, }) => {
12195
+ const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'bottom-left', appendToBody = false, className, trapFocus = true, closeOnClickOutside = true, closeOnEscape = true, ariaLabel, ariaLabelledBy, role = 'dialog', id, restoreFocusRef, }) => {
12196
12196
  const panelRef = React.useRef(null);
12197
12197
  const resolved = useAnchoredPosition(anchorRef, panelRef, {
12198
12198
  active: isOpen,
@@ -12229,7 +12229,10 @@ const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'botto
12229
12229
  document.addEventListener('keydown', handler);
12230
12230
  return () => document.removeEventListener('keydown', handler);
12231
12231
  }, [isOpen, closeOnEscape, onClose]);
12232
- useFocusTrap(panelRef, { active: isOpen && trapFocus });
12232
+ useFocusTrap(panelRef, {
12233
+ active: isOpen && trapFocus,
12234
+ restoreFocus: restoreFocusRef ?? true,
12235
+ });
12233
12236
  const panelClass = usePrefixedClassNames('picker-popover', {
12234
12237
  'is-active': isOpen,
12235
12238
  [`is-${resolved.position}`]: true,
@@ -12634,6 +12637,37 @@ function useSegmentedEntry(params) {
12634
12637
  // change. Kept in a ref because key handlers read+update synchronously
12635
12638
  // within the same event tick.
12636
12639
  const typedDigitsRef = React.useRef('');
12640
+ // The text focus seeded an empty picker with, until the user edits it or
12641
+ // leaves. While the text still matches it, nothing has been typed.
12642
+ const seedRef = React.useRef(null);
12643
+ // Whether the input's current focus is the one a closing popover handed
12644
+ // back, until focus leaves the picker.
12645
+ const handedBackRef = React.useRef(false);
12646
+ // A seed the popover never turned into a value closes with it, wherever
12647
+ // focus goes, so a dismissed empty field stays empty.
12648
+ //
12649
+ // As the popover closes, its focus trap hands focus back to the input. That
12650
+ // focus is not the user arriving: it must not open the popover again under
12651
+ // `openOnFocus`, or seed an empty picker that leaving would then commit.
12652
+ // `closingRef` is set in the layout phase of the commit that closes it and
12653
+ // cleared by that commit's effects, and React runs a commit's effect
12654
+ // cleanups, the trap's among them, before any of its effects, so a focus
12655
+ // in between is the one handed back.
12656
+ const closingRef = React.useRef(false);
12657
+ const wasOpenRef = React.useRef(isOpen);
12658
+ React.useLayoutEffect(() => {
12659
+ if (wasOpenRef.current && !isOpen) {
12660
+ closingRef.current = true;
12661
+ if (!value && seedRef.current !== null && text === seedRef.current) {
12662
+ setText('');
12663
+ }
12664
+ seedRef.current = null;
12665
+ }
12666
+ wasOpenRef.current = isOpen;
12667
+ }, [isOpen, value, text, setText]);
12668
+ React.useEffect(() => {
12669
+ closingRef.current = false;
12670
+ }, [isOpen]);
12637
12671
  // Segment mode is unavailable for disabled / read-only / non-editable
12638
12672
  // pickers and for Intl-options / variable-width formats (segmentMap null).
12639
12673
  const segmentEditable = !!segmentMap && !!editable && !disabled && !readOnly;
@@ -12690,6 +12724,7 @@ function useSegmentedEntry(params) {
12690
12724
  // segment mode is inactive.
12691
12725
  if (activeSegmentIdx !== null && segmentEditable)
12692
12726
  return;
12727
+ seedRef.current = null;
12693
12728
  setText(e.target.value);
12694
12729
  }, [activeSegmentIdx, segmentEditable, setText]);
12695
12730
  const handleBlur = React.useCallback((e) => {
@@ -12707,6 +12742,16 @@ function useSegmentedEntry(params) {
12707
12742
  }
12708
12743
  setActiveSegmentIdx(null);
12709
12744
  typedDigitsRef.current = '';
12745
+ seedRef.current = null;
12746
+ const handedBack = handedBackRef.current;
12747
+ handedBackRef.current = false;
12748
+ // Leaving after a dismiss commits only what was typed since. Text that
12749
+ // still shows the value wasn't, and re-parsing it could drop what the
12750
+ // format leaves out, such as seconds.
12751
+ if (handedBack && value && text === formatFn(value, format, locale)) {
12752
+ onBlur?.(e);
12753
+ return;
12754
+ }
12710
12755
  const parsed = tryParse(text);
12711
12756
  if (parsed && isAllowed(parsed)) {
12712
12757
  commitValue(parsed);
@@ -12729,13 +12774,19 @@ function useSegmentedEntry(params) {
12729
12774
  onBlur,
12730
12775
  ]);
12731
12776
  const handleFocus = React.useCallback((e) => {
12732
- if (openOnFocus && popover && !disabled && !readOnly)
12777
+ const handedBack = closingRef.current;
12778
+ handedBackRef.current = handedBack;
12779
+ if (!handedBack && openOnFocus && popover && !disabled && !readOnly) {
12733
12780
  setOpen(true);
12781
+ }
12734
12782
  // Enter segment mode: prime an initial value (so editing works even when
12735
- // empty), seed the text, and highlight the first editable segment.
12783
+ // empty), seed the text, and highlight the first editable segment. The
12784
+ // segment base doesn't need the seed, so focus handed back skips it.
12736
12785
  if (segmentEditable && segmentMap) {
12737
- if (!value) {
12738
- setText(formatFn(makeBaseDate(), format, locale));
12786
+ if (!value && !handedBack) {
12787
+ const seed = formatFn(makeBaseDate(), format, locale);
12788
+ seedRef.current = seed;
12789
+ setText(seed);
12739
12790
  }
12740
12791
  typedDigitsRef.current = '';
12741
12792
  setActiveSegmentIdx(segmentMap.editable[0]);
@@ -13202,7 +13253,7 @@ const DateInputBase = React.forwardRef((props, ref) => {
13202
13253
  return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsxRuntime.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 && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
13203
13254
  if (canOpen)
13204
13255
  setOpen(!open);
13205
- }, disabled: !canOpen, "aria-label": chooseLabel, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: chooseLabel, id: popoverId, children: calendar }))] }));
13256
+ }, disabled: !canOpen, "aria-label": chooseLabel, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: handlePopoverClose, anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: chooseLabel, id: popoverId, restoreFocusRef: inputRef, children: calendar }))] }));
13206
13257
  });
13207
13258
  DateInputBase.displayName = 'DateInputBase';
13208
13259
 
@@ -14175,9 +14226,6 @@ const TimeInputBase = React.forwardRef((props, ref) => {
14175
14226
  const mobileFooterClass = usePrefixedClassNames('timeinput-footer-mobile');
14176
14227
  const mobileFooterResetClass = usePrefixedClassNames('timeinput-footer-reset');
14177
14228
  const mobileFooterDoneClass = usePrefixedClassNames('timeinput-footer-done');
14178
- // Set from the moment the popover starts to close until the close has
14179
- // committed. See `setOpenFromInput`.
14180
- const closingRef = React.useRef(false);
14181
14229
  const setOpen = React.useCallback((next) => {
14182
14230
  setOpenState(prev => {
14183
14231
  if (prev === next)
@@ -14187,26 +14235,11 @@ const TimeInputBase = React.forwardRef((props, ref) => {
14187
14235
  onOpen?.();
14188
14236
  }
14189
14237
  else {
14190
- closingRef.current = true;
14191
14238
  onClose?.();
14192
14239
  }
14193
14240
  return next;
14194
14241
  });
14195
14242
  }, [onOpen, onClose, value]);
14196
- // React runs a commit's effect cleanups before any of its effects, so on a
14197
- // close this runs after the popover's focus trap has handed focus back.
14198
- React.useEffect(() => {
14199
- closingRef.current = false;
14200
- }, [open]);
14201
- // As the popover closes, its focus trap hands focus back to the input.
14202
- // That focus is not the user arriving, so under `openOnFocus` it must not
14203
- // open the popover again. The input asks to open only on focus, click or
14204
- // ArrowDown, so a request while a close commits can only be that one.
14205
- const setOpenFromInput = React.useCallback((next) => {
14206
- if (next && closingRef.current)
14207
- return;
14208
- setOpen(next);
14209
- }, [setOpen]);
14210
14243
  React.useEffect(() => {
14211
14244
  setText(value ? formatTime(value, defaultFormat, locale) : '');
14212
14245
  }, [value, defaultFormat, locale]);
@@ -14263,7 +14296,7 @@ const TimeInputBase = React.forwardRef((props, ref) => {
14263
14296
  openOnFocus,
14264
14297
  closeOnSelect,
14265
14298
  isOpen: open,
14266
- setOpen: setOpenFromInput,
14299
+ setOpen,
14267
14300
  inputRef,
14268
14301
  containerRef,
14269
14302
  onFocus,
@@ -14315,7 +14348,7 @@ const TimeInputBase = React.forwardRef((props, ref) => {
14315
14348
  return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsxRuntime.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 && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
14316
14349
  if (canOpen)
14317
14350
  setOpen(!open);
14318
- }, disabled: !canOpen, "aria-label": t.chooseTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseTime, id: popoverId, children: panel }))] }));
14351
+ }, disabled: !canOpen, "aria-label": t.chooseTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseTime, id: popoverId, restoreFocusRef: inputRef, children: panel }))] }));
14319
14352
  });
14320
14353
  TimeInputBase.displayName = 'TimeInputBase';
14321
14354
 
@@ -14607,7 +14640,7 @@ const DateTimeInputBase = React.forwardRef((props, ref) => {
14607
14640
  return (jsxRuntime.jsxs("div", { ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), ...cleanRest, children: [jsxRuntime.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 && (jsxRuntime.jsx("button", { type: "button", className: triggerClass, onClick: () => {
14608
14641
  if (canOpen)
14609
14642
  setOpen(!open);
14610
- }, disabled: !canOpen, "aria-label": t.chooseDateTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateTime, id: popoverId, children: panel }))] }));
14643
+ }, disabled: !canOpen, "aria-label": t.chooseDateTime, "aria-haspopup": "dialog", "aria-controls": popoverId, "aria-expanded": open, tabIndex: canOpen ? 0 : -1, children: jsxRuntime.jsx(Icon, { name: triggerIconName, size: size }) })), popover && (jsxRuntime.jsx(PickerPopover, { isOpen: open, onClose: () => setOpen(false), anchorRef: containerRef, position: position, appendToBody: appendToBody, ariaLabel: t.chooseDateTime, id: popoverId, restoreFocusRef: inputRef, children: panel }))] }));
14611
14644
  });
14612
14645
  DateTimeInputBase.displayName = 'DateTimeInputBase';
14613
14646