@react-aria/datepicker 3.0.0-nightly.1602 → 3.0.0-nightly.1612

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/main.js CHANGED
@@ -4,6 +4,7 @@ var $IwcIq$react = require("react");
4
4
  var $IwcIq$reactarialabel = require("@react-aria/label");
5
5
  var $IwcIq$reactariai18n = require("@react-aria/i18n");
6
6
  var $IwcIq$reactariainteractions = require("@react-aria/interactions");
7
+ var $IwcIq$internationalizeddate = require("@internationalized/date");
7
8
  var $IwcIq$internationalizednumber = require("@internationalized/number");
8
9
  var $IwcIq$reactariaspinbutton = require("@react-aria/spinbutton");
9
10
  var $IwcIq$internationalizedmessage = require("@internationalized/message");
@@ -258,9 +259,9 @@ function $715562ad3b4cced4$export$4a931266a3838b86(state, ref1, disableArrowNavi
258
259
  }while (last)
259
260
  }
260
261
  // Now go backwards until we find an element that is not a placeholder.
261
- while(target === null || target === void 0 ? void 0 : target.getAttribute('aria-placeholder')){
262
+ while(target === null || target === void 0 ? void 0 : target.hasAttribute('data-placeholder')){
262
263
  let prev = walker.previousNode();
263
- if (prev && prev.getAttribute('aria-placeholder')) target = prev;
264
+ if (prev && prev.hasAttribute('data-placeholder')) target = prev;
264
265
  else break;
265
266
  }
266
267
  if (target) target.focus();
@@ -467,6 +468,7 @@ function $e90ae7c26a69c6b1$export$42df105a73306d51(props, state, ref) {
467
468
 
468
469
 
469
470
 
471
+
470
472
  function $934ac650a0aceb4b$export$d42c60378c8168f8() {
471
473
  let { locale: locale } = $IwcIq$reactariai18n.useLocale();
472
474
  return $IwcIq$react.useMemo(()=>{
@@ -501,7 +503,7 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
501
503
  let { locale: locale } = $IwcIq$reactariai18n.useLocale();
502
504
  let displayNames = $934ac650a0aceb4b$export$d42c60378c8168f8();
503
505
  let { ariaLabel: ariaLabel , ariaLabelledBy: ariaLabelledBy , ariaDescribedBy: ariaDescribedBy , focusManager: focusManager } = $4acc2f407c169e55$export$653eddfc964b0f8a.get(state);
504
- let textValue = segment.text;
506
+ let textValue = segment.isPlaceholder ? '' : segment.text;
505
507
  let options = $IwcIq$react.useMemo(()=>state.dateFormatter.resolvedOptions()
506
508
  , [
507
509
  state.dateFormatter
@@ -515,11 +517,14 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
515
517
  hour12: options.hour12,
516
518
  timeZone: options.timeZone
517
519
  });
518
- if (segment.type === 'month') {
520
+ if (segment.type === 'month' && !segment.isPlaceholder) {
519
521
  let monthTextValue = monthDateFormatter.format(state.dateValue);
520
522
  textValue = monthTextValue !== textValue ? `${textValue} – ${monthTextValue}` : monthTextValue;
521
- } else if (segment.type === 'hour') textValue = hourDateFormatter.format(state.dateValue);
523
+ } else if (segment.type === 'hour' && !segment.isPlaceholder) textValue = hourDateFormatter.format(state.dateValue);
522
524
  let { spinButtonProps: spinButtonProps } = $IwcIq$reactariaspinbutton.useSpinButton({
525
+ // The ARIA spec says aria-valuenow is optional if there's no value, but aXe seems to require it.
526
+ // This doesn't seem to have any negative effects with real AT since we also use aria-valuetext.
527
+ // https://github.com/dequelabs/axe-core/issues/3505
523
528
  value: segment.value,
524
529
  textValue: textValue,
525
530
  minValue: segment.minValue,
@@ -573,14 +578,6 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
573
578
  if (e.key === 'a' && ($IwcIq$reactariautils.isMac() ? e.metaKey : e.ctrlKey)) e.preventDefault();
574
579
  if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return;
575
580
  switch(e.key){
576
- case 'Enter':
577
- e.preventDefault();
578
- e.stopPropagation();
579
- if (segment.isPlaceholder && !state.isReadOnly) state.confirmPlaceholder(segment.type);
580
- focusManager.focusNext();
581
- break;
582
- case 'Tab':
583
- break;
584
581
  case 'Backspace':
585
582
  case 'Delete':
586
583
  // Safari on iOS does not fire beforeinput for the backspace key because the cursor is at the start.
@@ -614,6 +611,42 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
614
611
  }, [
615
612
  amPmFormatter
616
613
  ]);
614
+ // Get a list of formatted era names so users can type the first character to choose one.
615
+ let eraFormatter = $IwcIq$reactariai18n.useDateFormatter({
616
+ year: 'numeric',
617
+ era: 'narrow',
618
+ timeZone: 'UTC'
619
+ });
620
+ let eras1 = $IwcIq$react.useMemo(()=>{
621
+ if (segment.type !== 'era') return [];
622
+ let date = $IwcIq$internationalizeddate.toCalendar(new $IwcIq$internationalizeddate.CalendarDate(1, 1, 1), state.calendar);
623
+ let eras = state.calendar.getEras().map((era)=>{
624
+ let eraDate = date.set({
625
+ year: 1,
626
+ month: 1,
627
+ day: 1,
628
+ era: era
629
+ }).toDate('UTC');
630
+ let parts = eraFormatter.formatToParts(eraDate);
631
+ let formatted = parts.find((p)=>p.type === 'era'
632
+ ).value;
633
+ return {
634
+ era: era,
635
+ formatted: formatted
636
+ };
637
+ });
638
+ // Remove the common prefix from formatted values. This is so that in calendars with eras like
639
+ // ERA0 and ERA1 (e.g. Ethiopic), users can press "0" and "1" to select an era. In other cases,
640
+ // the first letter is used.
641
+ let prefixLength = $5c015c6316d1904d$var$commonPrefixLength(eras.map((era)=>era.formatted
642
+ ));
643
+ if (prefixLength) for (let era1 of eras)era1.formatted = era1.formatted.slice(prefixLength);
644
+ return eras;
645
+ }, [
646
+ eraFormatter,
647
+ state.calendar,
648
+ segment.type
649
+ ]);
617
650
  let onInput = (key)=>{
618
651
  if (state.isDisabled || state.isReadOnly) return;
619
652
  let newValue = enteredKeys.current + key;
@@ -624,6 +657,16 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
624
657
  else break;
625
658
  focusManager.focusNext();
626
659
  break;
660
+ case 'era':
661
+ {
662
+ let matched = eras1.find((e)=>startsWith(e.formatted, key)
663
+ );
664
+ if (matched) {
665
+ state.setSegment('era', matched.era);
666
+ focusManager.focusNext();
667
+ }
668
+ break;
669
+ }
627
670
  case 'day':
628
671
  case 'hour':
629
672
  case 'minute':
@@ -661,14 +704,9 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
661
704
  let onFocus = ()=>{
662
705
  enteredKeys.current = '';
663
706
  $IwcIq$reactariautils.scrollIntoView($IwcIq$reactariautils.getScrollParent(ref.current), ref.current);
664
- // Safari requires that a selection is set or it won't fire input events.
665
- // Since usePress disables text selection, this won't happen by default.
666
- ref.current.style.webkitUserSelect = 'text';
667
- ref.current.style.userSelect = 'text';
707
+ // Collapse selection to start or Chrome won't fire input events.
668
708
  let selection = window.getSelection();
669
709
  selection.collapse(ref.current);
670
- ref.current.style.webkitUserSelect = 'none';
671
- ref.current.style.userSelect = 'none';
672
710
  };
673
711
  let compositionRef = $IwcIq$react.useRef('');
674
712
  // @ts-ignore - TODO: possibly old TS version? doesn't fail in my editor...
@@ -708,6 +746,19 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
708
746
  $IwcIq$reactariautils.useEvent(ref, 'selectstart', (e)=>{
709
747
  e.preventDefault();
710
748
  });
749
+ $IwcIq$reactariautils.useLayoutEffect(()=>{
750
+ let element = ref.current;
751
+ return ()=>{
752
+ // If the focused segment is removed, focus the previous one, or the next one if there was no previous one.
753
+ if (document.activeElement === element) {
754
+ let prev = focusManager.focusPrevious();
755
+ if (!prev) focusManager.focusNext();
756
+ }
757
+ };
758
+ }, [
759
+ ref,
760
+ focusManager
761
+ ]);
711
762
  // spinbuttons cannot be focused with VoiceOver on iOS.
712
763
  let touchPropOverrides = $IwcIq$reactariautils.isIOS() || segment.type === 'timeZoneName' ? {
713
764
  role: 'textbox',
@@ -747,8 +798,8 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
747
798
  ...touchPropOverrides,
748
799
  'aria-invalid': state.validationState === 'invalid' ? 'true' : undefined,
749
800
  'aria-describedby': ariaDescribedBy,
750
- 'aria-placeholder': segment.isPlaceholder ? segment.text : undefined,
751
801
  'aria-readonly': state.isReadOnly || !segment.isEditable ? 'true' : undefined,
802
+ 'data-placeholder': segment.isPlaceholder || undefined,
752
803
  contentEditable: isEditable,
753
804
  suppressContentEditableWarning: isEditable,
754
805
  spellCheck: isEditable ? 'false' : undefined,
@@ -756,14 +807,12 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
756
807
  autoCorrect: isEditable ? 'off' : undefined,
757
808
  // Capitalization was changed in React 17...
758
809
  [parseInt(($parcel$interopDefault($IwcIq$react)).version, 10) >= 17 ? 'enterKeyHint' : 'enterkeyhint']: isEditable ? 'next' : undefined,
759
- inputMode: state.isDisabled || segment.type === 'dayPeriod' || !isEditable ? undefined : 'numeric',
810
+ inputMode: state.isDisabled || segment.type === 'dayPeriod' || segment.type === 'era' || !isEditable ? undefined : 'numeric',
760
811
  tabIndex: state.isDisabled ? undefined : 0,
761
812
  onKeyDown: onKeyDown,
762
813
  onFocus: onFocus,
763
814
  style: {
764
- caretColor: 'transparent',
765
- userSelect: 'none',
766
- WebkitUserSelect: 'none'
815
+ caretColor: 'transparent'
767
816
  },
768
817
  // Prevent pointer events from reaching useDatePickerGroup, and allow native browser behavior to focus the segment.
769
818
  onPointerDown (e) {
@@ -775,7 +824,16 @@ function $5c015c6316d1904d$export$1315d136e6f7581(segment, state, ref) {
775
824
  })
776
825
  };
777
826
  }
778
-
827
+ function $5c015c6316d1904d$var$commonPrefixLength(strings) {
828
+ // Sort the strings, and compare the characters in the first and last to find the common prefix.
829
+ strings.sort();
830
+ let first = strings[0];
831
+ let last = strings[strings.length - 1];
832
+ for(let i = 0; i < first.length; i++){
833
+ if (first[i] !== last[i]) return i;
834
+ }
835
+ return 0;
836
+ }
779
837
 
780
838
 
781
839
 
@@ -815,11 +873,6 @@ function $20f695b1b69e6b9e$export$12fd5f0e9f4bb192(props, state, ref) {
815
873
  let buttonId = $IwcIq$reactariautils.useId();
816
874
  let dialogId = $IwcIq$reactariautils.useId();
817
875
  let groupProps = $715562ad3b4cced4$export$4a931266a3838b86(state, ref);
818
- let { focusWithinProps: focusWithinProps } = $IwcIq$reactariainteractions.useFocusWithin({
819
- onBlurWithin () {
820
- state.confirmPlaceholder();
821
- }
822
- });
823
876
  let ariaDescribedBy = [
824
877
  descProps['aria-describedby'],
825
878
  fieldProps['aria-describedby']
@@ -849,7 +902,7 @@ function $20f695b1b69e6b9e$export$12fd5f0e9f4bb192(props, state, ref) {
849
902
  };
850
903
  let domProps = $IwcIq$reactariautils.filterDOMProps(props);
851
904
  return {
852
- groupProps: $IwcIq$reactariautils.mergeProps(domProps, groupProps, fieldProps, descProps, focusWithinProps, {
905
+ groupProps: $IwcIq$reactariautils.mergeProps(domProps, groupProps, fieldProps, descProps, {
853
906
  role: 'group',
854
907
  'aria-disabled': props.isDisabled || null,
855
908
  'aria-describedby': ariaDescribedBy