@octanejs/select 0.1.13 → 0.1.14

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/src/select.tsrx CHANGED
@@ -185,10 +185,11 @@ export type RawSelectRequiredPropKeys =
185
185
  | 'unstyled'
186
186
  | 'value';
187
187
 
188
- export type RawSelectProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>> =
189
- Omit<SelectProps<Option, IsMulti, Group>, RawSelectRequiredPropKeys> & Required<
190
- Pick<SelectProps<Option, IsMulti, Group>, RawSelectRequiredPropKeys>
191
- >;
188
+ export type RawSelectProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>> = Omit<
189
+ SelectProps<Option, IsMulti, Group>,
190
+ RawSelectRequiredPropKeys
191
+ > &
192
+ Required<Pick<SelectProps<Option, IsMulti, Group>, RawSelectRequiredPropKeys>>;
192
193
 
193
194
  export interface SelectInstance<
194
195
  Option = unknown,
@@ -259,9 +260,8 @@ export const defaultProps = {
259
260
  options: [],
260
261
  pageSize: 5,
261
262
  placeholder: 'Select...',
262
- screenReaderStatus: ({ count }: { count: number }) => `${count} result${
263
- count !== 1 ? 's' : ''
264
- } available`,
263
+ screenReaderStatus: ({ count }: { count: number }) =>
264
+ `${count} result${count !== 1 ? 's' : ''} available`,
265
265
  styles: {},
266
266
  tabIndex: 0,
267
267
  tabSelectsValue: true,
@@ -299,48 +299,51 @@ function isSelected<Option, IsMulti extends boolean, Group extends GroupBase<Opt
299
299
  return selectValue.some((value) => props.getOptionValue(value) === candidate);
300
300
  }
301
301
 
302
- type RequiredSelectProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>> =
303
- SelectProps<Option, IsMulti, Group> & {
304
- 'aria-live': 'off' | 'polite' | 'assertive';
305
- captureMenuScroll: boolean;
306
- classNames: ClassNamesConfig<Option, IsMulti, Group>;
307
- closeMenuOnSelect: boolean;
308
- closeMenuOnScroll: boolean | ((event: Event) => boolean);
309
- components: SelectComponentsConfig;
310
- controlShouldRenderValue: boolean;
311
- filterOption: ((option: FilterOptionOption<Option>, inputValue: string) => boolean) | null;
312
- formatGroupLabel: (group: Group) => OctaneNode;
313
- getOptionLabel: GetOptionLabel<Option>;
314
- getOptionValue: GetOptionValue<Option>;
315
- inputValue: string;
316
- isDisabled: boolean;
317
- isLoading: boolean;
318
- isMulti: IsMulti;
319
- isOptionDisabled: (option: Option, selectValue: Options<Option>) => boolean;
320
- isRtl: boolean;
321
- loadingMessage: (value: { inputValue: string }) => OctaneNode;
322
- maxMenuHeight: number;
323
- menuIsOpen: boolean;
324
- menuPlacement: 'auto' | 'bottom' | 'top';
325
- menuPosition: 'absolute' | 'fixed';
326
- menuShouldBlockScroll: boolean;
327
- menuShouldScrollIntoView: boolean;
328
- minMenuHeight: number;
329
- noOptionsMessage: (value: { inputValue: string }) => OctaneNode;
330
- onChange: (value: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => void;
331
- onInputChange: (newValue: string, actionMeta: InputActionMeta) => void;
332
- onMenuClose: () => void;
333
- onMenuOpen: () => void;
334
- openMenuOnClick: boolean;
335
- options: OptionsOrGroups<Option, Group>;
336
- pageSize: number;
337
- placeholder: OctaneNode;
338
- screenReaderStatus: (value: { count: number }) => string;
339
- styles: StylesConfig<Option, IsMulti, Group>;
340
- tabIndex: number;
341
- tabSelectsValue: boolean;
342
- unstyled: boolean;
343
- };
302
+ type RequiredSelectProps<
303
+ Option,
304
+ IsMulti extends boolean,
305
+ Group extends GroupBase<Option>,
306
+ > = SelectProps<Option, IsMulti, Group> & {
307
+ 'aria-live': 'off' | 'polite' | 'assertive';
308
+ captureMenuScroll: boolean;
309
+ classNames: ClassNamesConfig<Option, IsMulti, Group>;
310
+ closeMenuOnSelect: boolean;
311
+ closeMenuOnScroll: boolean | ((event: Event) => boolean);
312
+ components: SelectComponentsConfig;
313
+ controlShouldRenderValue: boolean;
314
+ filterOption: ((option: FilterOptionOption<Option>, inputValue: string) => boolean) | null;
315
+ formatGroupLabel: (group: Group) => OctaneNode;
316
+ getOptionLabel: GetOptionLabel<Option>;
317
+ getOptionValue: GetOptionValue<Option>;
318
+ inputValue: string;
319
+ isDisabled: boolean;
320
+ isLoading: boolean;
321
+ isMulti: IsMulti;
322
+ isOptionDisabled: (option: Option, selectValue: Options<Option>) => boolean;
323
+ isRtl: boolean;
324
+ loadingMessage: (value: { inputValue: string }) => OctaneNode;
325
+ maxMenuHeight: number;
326
+ menuIsOpen: boolean;
327
+ menuPlacement: 'auto' | 'bottom' | 'top';
328
+ menuPosition: 'absolute' | 'fixed';
329
+ menuShouldBlockScroll: boolean;
330
+ menuShouldScrollIntoView: boolean;
331
+ minMenuHeight: number;
332
+ noOptionsMessage: (value: { inputValue: string }) => OctaneNode;
333
+ onChange: (value: OnChangeValue<Option, IsMulti>, actionMeta: ActionMeta<Option>) => void;
334
+ onInputChange: (newValue: string, actionMeta: InputActionMeta) => void;
335
+ onMenuClose: () => void;
336
+ onMenuOpen: () => void;
337
+ openMenuOnClick: boolean;
338
+ options: OptionsOrGroups<Option, Group>;
339
+ pageSize: number;
340
+ placeholder: OctaneNode;
341
+ screenReaderStatus: (value: { count: number }) => string;
342
+ styles: StylesConfig<Option, IsMulti, Group>;
343
+ tabIndex: number;
344
+ tabSelectsValue: boolean;
345
+ unstyled: boolean;
346
+ };
344
347
 
345
348
  export function buildCategorizedOptions<
346
349
  Option,
@@ -362,12 +365,12 @@ export function buildCategorizedOptions<
362
365
  });
363
366
  const focusable = (option: CategorizedOption<Option>) =>
364
367
  (!hideSelected || !option.isSelected) &&
365
- (props.filterOption
366
- ? props.filterOption(
367
- { label: option.label, value: option.value, data: option.data },
368
- props.inputValue ?? '',
369
- )
370
- : true);
368
+ (props.filterOption
369
+ ? props.filterOption(
370
+ { label: option.label, value: option.value, data: option.data },
371
+ props.inputValue ?? '',
372
+ )
373
+ : true);
371
374
  const result: CategorizedGroupOrOption<Option, Group>[] = [];
372
375
  props.options.forEach((item, outerIndex) => {
373
376
  if (typeof item === 'object' && item !== null && 'options' in item) {
@@ -511,9 +514,8 @@ const defaultAriaLiveMessages = {
511
514
  isSelected: boolean;
512
515
  isAppleDevice: boolean;
513
516
  }) {
514
- const index = (values: readonly Option[]) => values.length
515
- ? `${values.indexOf(props.focused) + 1} of ${values.length}`
516
- : '';
517
+ const index = (values: readonly Option[]) =>
518
+ values.length ? `${values.indexOf(props.focused) + 1} of ${values.length}` : '';
517
519
  if (props.context === 'value') {
518
520
  return `value ${props.label} focused, ${index(props.selectValue)}.`;
519
521
  }
@@ -554,42 +556,40 @@ function LiveRegion<Option, IsMulti extends boolean, Group extends GroupBase<Opt
554
556
  })
555
557
  | null;
556
558
  const selected =
557
- selection?.removedValue ?? selection?.option ??
558
- (selection && !Array.isArray(selection.value) ? selection.value as Option : undefined);
559
+ selection?.removedValue ??
560
+ selection?.option ??
561
+ (selection && !Array.isArray(selection.value) ? (selection.value as Option) : undefined);
559
562
  const selectedMany = selection?.options ?? selection?.removedValues;
560
563
  const ariaSelected =
561
564
  selection && messages.onChange
562
- ? messages.onChange(
563
- {
564
- ...selection,
565
- isDisabled: selected
566
- ? props.selectProps.isOptionDisabled(selected, props.selectValue)
567
- : false,
568
- label: selected ? props.selectProps.getOptionLabel(selected) : '',
569
- labels: selectedMany ? selectedMany.map(props.selectProps.getOptionLabel) : [],
570
- } as never,
571
- )
565
+ ? messages.onChange({
566
+ ...selection,
567
+ isDisabled: selected
568
+ ? props.selectProps.isOptionDisabled(selected, props.selectValue)
569
+ : false,
570
+ label: selected ? props.selectProps.getOptionLabel(selected) : '',
571
+ labels: selectedMany ? selectedMany.map(props.selectProps.getOptionLabel) : [],
572
+ } as never)
572
573
  : '';
573
574
  const focused = props.focusedOption ?? props.focusedValue;
574
575
  const ariaFocused =
575
576
  focused && messages.onFocus
576
- ? messages.onFocus(
577
- {
578
- context: focused === props.focusedOption ? 'menu' : 'value',
579
- focused,
580
- isDisabled: props.selectProps.isOptionDisabled(focused, props.selectValue),
581
- isSelected: Boolean(
582
- props.focusedOption && props.selectValue.includes(props.focusedOption),
583
- ),
584
- label: props.selectProps.getOptionLabel(focused),
585
- options: props.focusableOptions,
586
- selectValue: props.selectValue,
587
- isAppleDevice: props.isAppleDevice,
588
- } as never,
589
- )
577
+ ? messages.onFocus({
578
+ context: focused === props.focusedOption ? 'menu' : 'value',
579
+ focused,
580
+ isDisabled: props.selectProps.isOptionDisabled(focused, props.selectValue),
581
+ isSelected: Boolean(
582
+ props.focusedOption && props.selectValue.includes(props.focusedOption),
583
+ ),
584
+ label: props.selectProps.getOptionLabel(focused),
585
+ options: props.focusableOptions,
586
+ selectValue: props.selectValue,
587
+ isAppleDevice: props.isAppleDevice,
588
+ } as never)
590
589
  : '';
591
590
  const ariaResults =
592
- props.selectProps.menuIsOpen && props.selectProps.options.length &&
591
+ props.selectProps.menuIsOpen &&
592
+ props.selectProps.options.length &&
593
593
  !props.selectProps.isLoading &&
594
594
  messages.onFilter
595
595
  ? messages.onFilter({
@@ -600,33 +600,27 @@ function LiveRegion<Option, IsMulti extends boolean, Group extends GroupBase<Opt
600
600
  })
601
601
  : '';
602
602
  const isInitialFocus = selection?.action === 'initial-input-focus';
603
- const context =
604
- props.focusedValue
605
- ? 'value'
606
- : props.selectProps.menuIsOpen
607
- ? 'menu'
608
- : 'input';
603
+ const context = props.focusedValue ? 'value' : props.selectProps.menuIsOpen ? 'menu' : 'input';
609
604
  const ariaGuidance =
610
- messages.guidance?.(
611
- {
612
- 'aria-label': props.selectProps['aria-label'],
613
- context,
614
- isDisabled: props.focusedOption
615
- ? props.selectProps.isOptionDisabled(props.focusedOption, props.selectValue)
616
- : false,
617
- isMulti: Boolean(props.selectProps.isMulti),
618
- isSearchable: props.selectProps.isSearchable,
619
- tabSelectsValue: props.selectProps.tabSelectsValue,
620
- isInitialFocus,
621
- } as never,
622
- ) ??
623
- '';
624
- const screenReaderText = <>
625
- <span id="aria-selection">{ariaSelected}</span>
626
- <span id="aria-focused">{ariaFocused}</span>
627
- <span id="aria-results">{ariaResults}</span>
628
- <span id="aria-guidance">{ariaGuidance}</span>
629
- </>;
605
+ messages.guidance?.({
606
+ 'aria-label': props.selectProps['aria-label'],
607
+ context,
608
+ isDisabled: props.focusedOption
609
+ ? props.selectProps.isOptionDisabled(props.focusedOption, props.selectValue)
610
+ : false,
611
+ isMulti: Boolean(props.selectProps.isMulti),
612
+ isSearchable: props.selectProps.isSearchable,
613
+ tabSelectsValue: props.selectProps.tabSelectsValue,
614
+ isInitialFocus,
615
+ } as never) ?? '';
616
+ const screenReaderText = (
617
+ <>
618
+ <span id="aria-selection">{ariaSelected}</span>
619
+ <span id="aria-focused">{ariaFocused}</span>
620
+ <span id="aria-results">{ariaResults}</span>
621
+ <span id="aria-guidance">{ariaGuidance}</span>
622
+ </>
623
+ );
630
624
  <>
631
625
  <span id={props.id} className={resolved.className}>
632
626
  {isInitialFocus ? screenReaderText : null}
@@ -647,7 +641,7 @@ function isAppleDevice() {
647
641
  if (typeof window === 'undefined' || window.navigator == null) return false;
648
642
  const platform = window.navigator.platform;
649
643
  const isMac = /^Mac/i.test(platform);
650
- return /^iPhone|^iPad/i.test(platform) || isMac && navigator.maxTouchPoints > 1 || isMac;
644
+ return /^iPhone|^iPad/i.test(platform) || (isMac && navigator.maxTouchPoints > 1) || isMac;
651
645
  }
652
646
 
653
647
  export function Select<
@@ -746,15 +740,16 @@ export function Select<
746
740
  const nextFocusedOption =
747
741
  focusedOption && focusableOptions.includes(focusedOption)
748
742
  ? focusedOption
749
- : focusableOptions[0] ?? null;
743
+ : (focusableOptions[0] ?? null);
750
744
  if (nextFocusedOption !== focusedOption) setFocusedOption(nextFocusedOption);
751
745
  }, [props.options, props.value, props.menuIsOpen, props.inputValue, focusedOption]);
752
746
  useEffect(() => {
753
747
  const prev = prevFocusReconcileRef.current;
754
748
  const changed =
755
- props.value !== prev.value || props.options !== prev.options ||
756
- props.menuIsOpen !== prev.menuIsOpen ||
757
- props.inputValue !== prev.inputValue;
749
+ props.value !== prev.value ||
750
+ props.options !== prev.options ||
751
+ props.menuIsOpen !== prev.menuIsOpen ||
752
+ props.inputValue !== prev.inputValue;
758
753
  if (!changed) return;
759
754
  prevFocusReconcileRef.current = {
760
755
  options: props.options,
@@ -764,10 +759,9 @@ export function Select<
764
759
  };
765
760
  const lastSelectValue = prevSelectValueRef.current;
766
761
  prevSelectValueRef.current = selectValue;
767
- const nextFocusedValue =
768
- clearFocusValueOnUpdateRef.current
769
- ? getNextFocusedValue(focusedValue, lastSelectValue, selectValue)
770
- : null;
762
+ const nextFocusedValue = clearFocusValueOnUpdateRef.current
763
+ ? getNextFocusedValue(focusedValue, lastSelectValue, selectValue)
764
+ : null;
771
765
  clearFocusValueOnUpdateRef.current = false;
772
766
  if (nextFocusedValue !== focusedValue) setFocusedValue(nextFocusedValue);
773
767
  }, [props.options, props.value, props.menuIsOpen, props.inputValue, selectValue, focusedValue]);
@@ -786,11 +780,8 @@ export function Select<
786
780
  };
787
781
  const getClassNames = (name: string, componentProps: unknown) =>
788
782
  props.classNames[name as StyleKey]?.(componentProps);
789
- const cx = (state: Record<string, boolean>, ...names: (string | undefined)[]) => classNames(
790
- props.classNamePrefix,
791
- state,
792
- ...names,
793
- );
783
+ const cx = (state: Record<string, boolean>, ...names: (string | undefined)[]) =>
784
+ classNames(props.classNamePrefix, state, ...names);
794
785
 
795
786
  const closeMenu = () => {
796
787
  props.onInputChange('', {
@@ -810,8 +801,9 @@ export function Select<
810
801
  const target = event.target;
811
802
  if (
812
803
  target instanceof HTMLElement &&
813
- (target === document.documentElement || target === document.body)
814
- ) props.onMenuClose();
804
+ (target === document.documentElement || target === document.body)
805
+ )
806
+ props.onMenuClose();
815
807
  };
816
808
  document.addEventListener('scroll', onScroll, true);
817
809
  return () => document.removeEventListener('scroll', onScroll, true);
@@ -827,16 +819,20 @@ export function Select<
827
819
  const onTouchMove = (event: TouchEvent) => {
828
820
  const touch = event.touches.item(0);
829
821
  if (!touch) return;
830
- userIsDragging.current = Math.abs(touch.clientX - initialTouch.current.x) > 5 ||
822
+ userIsDragging.current =
823
+ Math.abs(touch.clientX - initialTouch.current.x) > 5 ||
831
824
  Math.abs(touch.clientY - initialTouch.current.y) > 5;
832
825
  };
833
826
  const onTouchEnd = (event: TouchEvent) => {
834
827
  if (!userIsDragging.current) {
835
828
  const target = event.target as Node;
836
829
  if (
837
- controlRef.current && !controlRef.current.contains(target) && menuListRef.current &&
838
- !menuListRef.current.contains(target)
839
- ) inputRef.current?.blur();
830
+ controlRef.current &&
831
+ !controlRef.current.contains(target) &&
832
+ menuListRef.current &&
833
+ !menuListRef.current.contains(target)
834
+ )
835
+ inputRef.current?.blur();
840
836
  }
841
837
  initialTouch.current = { x: 0, y: 0 };
842
838
  };
@@ -876,14 +872,12 @@ export function Select<
876
872
  option,
877
873
  );
878
874
  } else if (props.isOptionDisabled(option, selectValue)) {
879
- setAriaSelection(
880
- {
881
- action: 'select-option',
882
- option,
883
- name: props.name,
884
- value: option,
885
- } as AriaSelection<Option, IsMulti>,
886
- );
875
+ setAriaSelection({
876
+ action: 'select-option',
877
+ option,
878
+ name: props.name,
879
+ value: option,
880
+ } as AriaSelection<Option, IsMulti>);
887
881
  return;
888
882
  } else if (props.isMulti) {
889
883
  setValue([...selectValue, option] as OnChangeValue<Option, IsMulti>, 'select-option', option);
@@ -911,7 +905,7 @@ export function Select<
911
905
  const nextValue = valueTernary(
912
906
  props.isMulti,
913
907
  newValue,
914
- newValue[0] ?? null as Option,
908
+ newValue[0] ?? (null as Option),
915
909
  ) as OnChangeValue<Option, IsMulti>;
916
910
  const actionMeta = {
917
911
  action: 'remove-value',
@@ -930,7 +924,7 @@ export function Select<
930
924
  const nextValue = valueTernary(
931
925
  props.isMulti,
932
926
  newValue,
933
- newValue[0] ?? null as Option,
927
+ newValue[0] ?? (null as Option),
934
928
  ) as OnChangeValue<Option, IsMulti>;
935
929
  const actionMeta = {
936
930
  action: 'pop-value',
@@ -962,8 +956,7 @@ export function Select<
962
956
  const focusOption = (direction: FocusDirection = 'first') => {
963
957
  if (!focusableOptions.length) return;
964
958
  if (ariaSelection?.action === 'initial-input-focus') setAriaSelection(null);
965
- const current =
966
- focusedOption ? focusableOptions.indexOf(focusedOption) : -1;
959
+ const current = focusedOption ? focusableOptions.indexOf(focusedOption) : -1;
967
960
  const index =
968
961
  direction === 'first'
969
962
  ? 0
@@ -985,8 +978,7 @@ export function Select<
985
978
  const focusValue = (direction: 'previous' | 'next') => {
986
979
  if (!props.isMulti || !selectValue.length) return;
987
980
  if (ariaSelection?.action === 'initial-input-focus') setAriaSelection(null);
988
- const current =
989
- focusedValue ? selectValue.indexOf(focusedValue) : -1;
981
+ const current = focusedValue ? selectValue.indexOf(focusedValue) : -1;
990
982
  const next =
991
983
  direction === 'previous'
992
984
  ? current === 0
@@ -1008,12 +1000,9 @@ export function Select<
1008
1000
  const selectedIndex =
1009
1001
  !props.isMulti && selectValue.length ? focusableOptions.indexOf(selectValue[0]) : -1;
1010
1002
  setFocusedOption(
1011
- focusableOptions[selectedIndex > -1
1012
- ? selectedIndex
1013
- : direction === 'first'
1014
- ? 0
1015
- : focusableOptions.length - 1] ??
1016
- null,
1003
+ focusableOptions[
1004
+ selectedIndex > -1 ? selectedIndex : direction === 'first' ? 0 : focusableOptions.length - 1
1005
+ ] ?? null,
1017
1006
  );
1018
1007
  props.onMenuOpen();
1019
1008
  };
@@ -1039,13 +1028,7 @@ export function Select<
1039
1028
  selectOption,
1040
1029
  setValue,
1041
1030
  }),
1042
- [
1043
- categorized,
1044
- focusableOptions,
1045
- props.getOptionLabel,
1046
- props.getOptionValue,
1047
- selectValue,
1048
- ],
1031
+ [categorized, focusableOptions, props.getOptionLabel, props.getOptionValue, selectValue],
1049
1032
  );
1050
1033
 
1051
1034
  const onKeyDown = (event: KeyboardEvent) => {
@@ -1107,9 +1090,13 @@ export function Select<
1107
1090
  case 'Tab':
1108
1091
  if (isComposing) return;
1109
1092
  if (
1110
- !event.shiftKey && props.tabSelectsValue && props.menuIsOpen && focusedOption &&
1111
- !(props.openMenuOnFocus && selectValue.includes(focusedOption))
1112
- ) selectOption(focusedOption);
1093
+ !event.shiftKey &&
1094
+ props.tabSelectsValue &&
1095
+ props.menuIsOpen &&
1096
+ focusedOption &&
1097
+ !(props.openMenuOnFocus && selectValue.includes(focusedOption))
1098
+ )
1099
+ selectOption(focusedOption);
1113
1100
  else return;
1114
1101
  break;
1115
1102
  case ' ':
@@ -1166,58 +1153,58 @@ export function Select<
1166
1153
  };
1167
1154
 
1168
1155
  const valueUI =
1169
- !selectValue.length || !props.controlShouldRenderValue
1170
- ? props.inputValue
1171
- ? null
1172
- : <Components.Placeholder
1173
- {...commonProps}
1174
- key="placeholder"
1175
- isDisabled={props.isDisabled}
1176
- isFocused={isFocused}
1177
- innerProps={{ id: elementId('placeholder') }}
1178
- >{props.placeholder}</Components.Placeholder>
1179
- : props.isMulti
1180
- ? selectValue.map(
1181
- (option, index) => <Components.MultiValue
1182
- {...commonProps}
1183
- key={`${props.getOptionLabel(option)}-${props.getOptionValue(option)}`}
1184
- components={{
1185
- Container: Components.MultiValueContainer,
1186
- Label: Components.MultiValueLabel,
1187
- Remove: Components.MultiValueRemove,
1188
- }}
1189
- data={option}
1190
- index={index}
1191
- isDisabled={props.isDisabled}
1192
- isFocused={focusedValue === option}
1193
- removeProps={{
1194
- onClick: () => removeValue(option),
1195
- onMouseDown: (event: MouseEvent) => event.preventDefault(),
1196
- onTouchEnd: () => {
1197
- if (!userIsDragging.current) removeValue(option);
1198
- },
1199
- }}
1200
- >{formatOption(option, 'value')}</Components.MultiValue>,
1201
- )
1202
- : props.inputValue
1203
- ? null
1204
- : <Components.SingleValue
1205
- {...commonProps}
1206
- data={selectValue[0]}
1207
- isDisabled={props.isDisabled}
1208
- >{formatOption(selectValue[0], 'value')}</Components.SingleValue>;
1156
+ !selectValue.length || !props.controlShouldRenderValue ? (
1157
+ props.inputValue ? null : (
1158
+ <Components.Placeholder
1159
+ {...commonProps}
1160
+ key="placeholder"
1161
+ isDisabled={props.isDisabled}
1162
+ isFocused={isFocused}
1163
+ innerProps={{ id: elementId('placeholder') }}
1164
+ >
1165
+ {props.placeholder}
1166
+ </Components.Placeholder>
1167
+ )
1168
+ ) : props.isMulti ? (
1169
+ selectValue.map((option, index) => (
1170
+ <Components.MultiValue
1171
+ {...commonProps}
1172
+ key={`${props.getOptionLabel(option)}-${props.getOptionValue(option)}`}
1173
+ components={{
1174
+ Container: Components.MultiValueContainer,
1175
+ Label: Components.MultiValueLabel,
1176
+ Remove: Components.MultiValueRemove,
1177
+ }}
1178
+ data={option}
1179
+ index={index}
1180
+ isDisabled={props.isDisabled}
1181
+ isFocused={focusedValue === option}
1182
+ removeProps={{
1183
+ onClick: () => removeValue(option),
1184
+ onMouseDown: (event: MouseEvent) => event.preventDefault(),
1185
+ onTouchEnd: () => {
1186
+ if (!userIsDragging.current) removeValue(option);
1187
+ },
1188
+ }}
1189
+ >
1190
+ {formatOption(option, 'value')}
1191
+ </Components.MultiValue>
1192
+ ))
1193
+ ) : props.inputValue ? null : (
1194
+ <Components.SingleValue {...commonProps} data={selectValue[0]} isDisabled={props.isDisabled}>
1195
+ {formatOption(selectValue[0], 'value')}
1196
+ </Components.SingleValue>
1197
+ );
1209
1198
 
1210
1199
  const inputId = props.inputId || elementId('input');
1211
1200
  const handleInputFocus = (event: FocusEvent) => {
1212
1201
  setInputIsHidden(false);
1213
1202
  setIsFocused(true);
1214
- setAriaSelection(
1215
- {
1216
- action: 'initial-input-focus',
1217
- value: valueTernary(props.isMulti, selectValue, selectValue[0] ?? null as Option),
1218
- options: selectValue,
1219
- } as AriaSelection<Option, IsMulti>,
1220
- );
1203
+ setAriaSelection({
1204
+ action: 'initial-input-focus',
1205
+ value: valueTernary(props.isMulti, selectValue, selectValue[0] ?? (null as Option)),
1206
+ options: selectValue,
1207
+ } as AriaSelection<Option, IsMulti>);
1221
1208
  props.onFocus?.(event);
1222
1209
  if (props.openMenuOnFocus) openMenu('first');
1223
1210
  };
@@ -1235,12 +1222,11 @@ export function Select<
1235
1222
  setFocusedValue(null);
1236
1223
  setIsFocused(false);
1237
1224
  };
1238
- const ariaDescribedBy =
1239
- selectValue.length
1240
- ? ariaSelection?.action === 'initial-input-focus'
1241
- ? elementId('live-region')
1242
- : undefined
1243
- : elementId('placeholder');
1225
+ const ariaDescribedBy = selectValue.length
1226
+ ? ariaSelection?.action === 'initial-input-focus'
1227
+ ? elementId('live-region')
1228
+ : undefined
1229
+ : elementId('placeholder');
1244
1230
  function focusedOptionId(): string {
1245
1231
  if (!focusedOption) return '';
1246
1232
  for (const item of categorized) {
@@ -1256,8 +1242,7 @@ export function Select<
1256
1242
  }
1257
1243
  return '';
1258
1244
  }
1259
- const ariaActiveDescendant =
1260
- appleDevice ? undefined : focusedOptionId();
1245
+ const ariaActiveDescendant = appleDevice ? undefined : focusedOptionId();
1261
1246
  const commonInputAttributes: Omit<Octane.JSX.IntrinsicElements['input'], 'ref'> & {
1262
1247
  ref?: Octane.Ref<HTMLInputElement>;
1263
1248
  } = {
@@ -1281,56 +1266,57 @@ export function Select<
1281
1266
  'aria-describedby': ariaDescribedBy,
1282
1267
  ref: inputRef,
1283
1268
  };
1284
- const inputUI =
1285
- !props.isSearchable
1286
- ? <input
1287
- {...commonInputAttributes}
1288
- className={resolveStyle(dummyInputStyle).className}
1289
- inputMode="none"
1290
- value=""
1291
- onInput={() => {}}
1292
- aria-readonly="true"
1293
- />
1294
- : <Components.Input
1295
- {...commonProps}
1296
- autoCapitalize="none"
1297
- autoComplete="off"
1298
- autoCorrect="off"
1299
- id={inputId}
1300
- innerRef={inputRef}
1301
- isDisabled={props.isDisabled}
1302
- isHidden={inputIsHidden}
1303
- onBlur={commonInputAttributes.onBlur}
1304
- onInput={(event: InputEvent) => {
1305
- const target = event.currentTarget as HTMLInputElement;
1306
- setInputIsHidden(false);
1307
- props.onInputChange(target.value, {
1308
- action: 'input-change',
1309
- prevInputValue: props.inputValue ?? '',
1310
- });
1311
- if (!props.menuIsOpen) props.onMenuOpen();
1312
- }}
1313
- onFocus={handleInputFocus}
1314
- spellCheck="false"
1315
- onCompositionStart={() => setIsComposing(true)}
1316
- onCompositionEnd={() => setIsComposing(false)}
1317
- tabIndex={props.tabIndex}
1318
- form={props.form}
1319
- type="text"
1320
- value={props.inputValue ?? ''}
1321
- aria-autocomplete="list"
1322
- aria-expanded={props.menuIsOpen}
1323
- aria-haspopup="true"
1324
- aria-errormessage={props['aria-errormessage']}
1325
- aria-invalid={props['aria-invalid']}
1326
- aria-label={props['aria-label']}
1327
- aria-labelledby={props['aria-labelledby']}
1328
- aria-required={props.required}
1329
- role="combobox"
1330
- aria-activedescendant={ariaActiveDescendant}
1331
- aria-controls={props.menuIsOpen ? elementId('listbox') : undefined}
1332
- aria-describedby={ariaDescribedBy}
1333
- />;
1269
+ const inputUI = !props.isSearchable ? (
1270
+ <input
1271
+ {...commonInputAttributes}
1272
+ className={resolveStyle(dummyInputStyle).className}
1273
+ inputMode="none"
1274
+ value=""
1275
+ onInput={() => {}}
1276
+ aria-readonly="true"
1277
+ />
1278
+ ) : (
1279
+ <Components.Input
1280
+ {...commonProps}
1281
+ autoCapitalize="none"
1282
+ autoComplete="off"
1283
+ autoCorrect="off"
1284
+ id={inputId}
1285
+ innerRef={inputRef}
1286
+ isDisabled={props.isDisabled}
1287
+ isHidden={inputIsHidden}
1288
+ onBlur={commonInputAttributes.onBlur}
1289
+ onInput={(event: InputEvent) => {
1290
+ const target = event.currentTarget as HTMLInputElement;
1291
+ setInputIsHidden(false);
1292
+ props.onInputChange(target.value, {
1293
+ action: 'input-change',
1294
+ prevInputValue: props.inputValue ?? '',
1295
+ });
1296
+ if (!props.menuIsOpen) props.onMenuOpen();
1297
+ }}
1298
+ onFocus={handleInputFocus}
1299
+ spellCheck="false"
1300
+ onCompositionStart={() => setIsComposing(true)}
1301
+ onCompositionEnd={() => setIsComposing(false)}
1302
+ tabIndex={props.tabIndex}
1303
+ form={props.form}
1304
+ type="text"
1305
+ value={props.inputValue ?? ''}
1306
+ aria-autocomplete="list"
1307
+ aria-expanded={props.menuIsOpen}
1308
+ aria-haspopup="true"
1309
+ aria-errormessage={props['aria-errormessage']}
1310
+ aria-invalid={props['aria-invalid']}
1311
+ aria-label={props['aria-label']}
1312
+ aria-labelledby={props['aria-labelledby']}
1313
+ aria-required={props.required}
1314
+ role="combobox"
1315
+ aria-activedescendant={ariaActiveDescendant}
1316
+ aria-controls={props.menuIsOpen ? elementId('listbox') : undefined}
1317
+ aria-describedby={ariaDescribedBy}
1318
+ />
1319
+ );
1334
1320
 
1335
1321
  const onOptionHover = (option: Option) => {
1336
1322
  if (blockOptionHover.current || focusedOption === option) return;
@@ -1339,171 +1325,193 @@ export function Select<
1339
1325
  const renderOption = (option: CategorizedOption<Option>, id: string) => {
1340
1326
  const optionIsFocused = focusedOption === option.data;
1341
1327
  const optionId = elementId(`option-${id}`);
1342
- return <Components.Option
1343
- {...commonProps}
1344
- key={optionId}
1345
- data={option.data}
1346
- innerRef={optionIsFocused ? focusedOptionRef : null}
1347
- innerProps={{
1348
- id: optionId,
1349
- onClick: option.isDisabled ? undefined : () => selectOption(option.data),
1350
- onMouseMove: option.isDisabled ? undefined : () => onOptionHover(option.data),
1351
- onMouseOver: option.isDisabled ? undefined : () => onOptionHover(option.data),
1352
- onTouchEnd: option.isDisabled
1353
- ? undefined
1354
- : () => {
1355
- if (!userIsDragging.current) selectOption(option.data);
1356
- },
1357
- tabIndex: -1,
1358
- role: 'option',
1359
- 'aria-selected': appleDevice ? undefined : option.isSelected,
1360
- }}
1361
- isDisabled={option.isDisabled}
1362
- isFocused={optionIsFocused}
1363
- isSelected={option.isSelected}
1364
- label={option.label}
1365
- type="option"
1366
- >{formatOption(option.data, 'menu')}</Components.Option>;
1328
+ return (
1329
+ <Components.Option
1330
+ {...commonProps}
1331
+ key={optionId}
1332
+ data={option.data}
1333
+ innerRef={optionIsFocused ? focusedOptionRef : null}
1334
+ innerProps={{
1335
+ id: optionId,
1336
+ onClick: option.isDisabled ? undefined : () => selectOption(option.data),
1337
+ onMouseMove: option.isDisabled ? undefined : () => onOptionHover(option.data),
1338
+ onMouseOver: option.isDisabled ? undefined : () => onOptionHover(option.data),
1339
+ onTouchEnd: option.isDisabled
1340
+ ? undefined
1341
+ : () => {
1342
+ if (!userIsDragging.current) selectOption(option.data);
1343
+ },
1344
+ tabIndex: -1,
1345
+ role: 'option',
1346
+ 'aria-selected': appleDevice ? undefined : option.isSelected,
1347
+ }}
1348
+ isDisabled={option.isDisabled}
1349
+ isFocused={optionIsFocused}
1350
+ isSelected={option.isSelected}
1351
+ label={option.label}
1352
+ type="option"
1353
+ >
1354
+ {formatOption(option.data, 'menu')}
1355
+ </Components.Option>
1356
+ );
1367
1357
  };
1368
1358
 
1369
1359
  let menuUI: OctaneNode = null;
1370
1360
  if (props.menuIsOpen) {
1371
- const children =
1372
- categorized.length
1373
- ? categorized.map(
1374
- (item) => item.type === 'group'
1375
- ? <Components.Group
1376
- {...commonProps}
1377
- key={elementId(`group-${item.index}`)}
1378
- Heading={Components.GroupHeading}
1379
- data={item.data}
1380
- headingProps={{
1381
- id: `${elementId(`group-${item.index}`)}-heading`,
1382
- data: item.data,
1383
- }}
1384
- label={props.formatGroupLabel(item.data)}
1385
- options={item.options}
1386
- >{item.options.map(
1387
- (option) => renderOption(option, `${item.index}-${option.index}`),
1388
- )}</Components.Group>
1389
- : renderOption(item, String(item.index)),
1390
- )
1391
- : props.isLoading
1392
- ? props.loadingMessage({ inputValue: props.inputValue ?? '' })
1393
- : props.noOptionsMessage({ inputValue: props.inputValue ?? '' });
1361
+ const children = categorized.length
1362
+ ? categorized.map((item) =>
1363
+ item.type === 'group' ? (
1364
+ <Components.Group
1365
+ {...commonProps}
1366
+ key={elementId(`group-${item.index}`)}
1367
+ Heading={Components.GroupHeading}
1368
+ data={item.data}
1369
+ headingProps={{
1370
+ id: `${elementId(`group-${item.index}`)}-heading`,
1371
+ data: item.data,
1372
+ }}
1373
+ label={props.formatGroupLabel(item.data)}
1374
+ options={item.options}
1375
+ >
1376
+ {item.options.map((option) => renderOption(option, `${item.index}-${option.index}`))}
1377
+ </Components.Group>
1378
+ ) : (
1379
+ renderOption(item, String(item.index))
1380
+ ),
1381
+ )
1382
+ : props.isLoading
1383
+ ? props.loadingMessage({ inputValue: props.inputValue ?? '' })
1384
+ : props.noOptionsMessage({ inputValue: props.inputValue ?? '' });
1394
1385
  if (children === null) {
1395
1386
  menuUI = null;
1396
1387
  } else {
1397
- const renderedChildren =
1398
- categorized.length
1399
- ? children
1400
- : props.isLoading
1401
- ? <Components.LoadingMessage {...commonProps}>{children}</Components.LoadingMessage>
1402
- : <Components.NoOptionsMessage
1403
- {...commonProps}
1404
- >{children}</Components.NoOptionsMessage>;
1405
- const menuElement = <Components.Menu
1406
- {...commonProps}
1407
- innerRef={menuRef}
1408
- innerProps={{
1409
- onMouseDown: (event: MouseEvent) => {
1410
- event.stopPropagation();
1411
- event.preventDefault();
1412
- },
1413
- onMouseMove: (event: MouseEvent) => {
1414
- blockOptionHover.current = false;
1415
- event.stopPropagation();
1416
- },
1417
- }}
1418
- isLoading={props.isLoading}
1419
- placement={menuPlacement}
1420
- minMenuHeight={props.minMenuHeight}
1421
- maxMenuHeight={menuMaxHeight}
1422
- menuPlacement={props.menuPlacement}
1423
- menuPosition={props.menuPosition}
1424
- menuShouldScrollIntoView={props.menuShouldScrollIntoView}
1425
- >
1426
- <Components.MenuList
1388
+ const renderedChildren = categorized.length ? (
1389
+ children
1390
+ ) : props.isLoading ? (
1391
+ <Components.LoadingMessage {...commonProps}>{children}</Components.LoadingMessage>
1392
+ ) : (
1393
+ <Components.NoOptionsMessage {...commonProps}>{children}</Components.NoOptionsMessage>
1394
+ );
1395
+ const menuElement = (
1396
+ <Components.Menu
1427
1397
  {...commonProps}
1428
- innerRef={menuListRef}
1398
+ innerRef={menuRef}
1429
1399
  innerProps={{
1430
- role: 'listbox',
1431
- 'aria-multiselectable': Boolean(props.isMulti),
1432
- id: elementId('listbox'),
1400
+ onMouseDown: (event: MouseEvent) => {
1401
+ event.stopPropagation();
1402
+ event.preventDefault();
1403
+ },
1404
+ onMouseMove: (event: MouseEvent) => {
1405
+ blockOptionHover.current = false;
1406
+ event.stopPropagation();
1407
+ },
1433
1408
  }}
1434
- maxHeight={menuMaxHeight}
1435
- focusedOption={focusedOption}
1436
- >{renderedChildren}</Components.MenuList>
1437
- </Components.Menu>;
1438
- menuUI = props.menuPortalTarget || props.menuPosition === 'fixed'
1439
- ? <Components.MenuPortal
1409
+ isLoading={props.isLoading}
1410
+ placement={menuPlacement}
1411
+ minMenuHeight={props.minMenuHeight}
1412
+ maxMenuHeight={menuMaxHeight}
1413
+ menuPlacement={props.menuPlacement}
1414
+ menuPosition={props.menuPosition}
1415
+ menuShouldScrollIntoView={props.menuShouldScrollIntoView}
1416
+ >
1417
+ <Components.MenuList
1418
+ {...commonProps}
1419
+ innerRef={menuListRef}
1420
+ innerProps={{
1421
+ role: 'listbox',
1422
+ 'aria-multiselectable': Boolean(props.isMulti),
1423
+ id: elementId('listbox'),
1424
+ }}
1425
+ maxHeight={menuMaxHeight}
1426
+ focusedOption={focusedOption}
1427
+ >
1428
+ {renderedChildren}
1429
+ </Components.MenuList>
1430
+ </Components.Menu>
1431
+ );
1432
+ menuUI =
1433
+ props.menuPortalTarget || props.menuPosition === 'fixed' ? (
1434
+ <Components.MenuPortal
1440
1435
  {...commonProps}
1441
1436
  appendTo={props.menuPortalTarget ?? undefined}
1442
1437
  controlElement={controlRef.current}
1443
1438
  innerProps={{}}
1444
1439
  menuPlacement={menuPlacement}
1445
1440
  menuPosition={props.menuPosition}
1446
- >{menuElement}</Components.MenuPortal>
1447
- : menuElement;
1441
+ >
1442
+ {menuElement}
1443
+ </Components.MenuPortal>
1444
+ ) : (
1445
+ menuElement
1446
+ );
1448
1447
  if (props.menuShouldBlockScroll) {
1449
1448
  const unlockedMenu = menuUI;
1450
- menuUI = <>
1451
- <div
1452
- className={resolveStyle(scrollBlockerStyle).className}
1453
- onClick={(event: MouseEvent) => {
1454
- const target = event.target as HTMLElement;
1455
- (target.ownerDocument.activeElement as HTMLElement | null)?.blur();
1456
- }}
1457
- />
1458
- {unlockedMenu}
1459
- </>;
1449
+ menuUI = (
1450
+ <>
1451
+ <div
1452
+ className={resolveStyle(scrollBlockerStyle).className}
1453
+ onClick={(event: MouseEvent) => {
1454
+ const target = event.target as HTMLElement;
1455
+ (target.ownerDocument.activeElement as HTMLElement | null)?.blur();
1456
+ }}
1457
+ />
1458
+ {unlockedMenu}
1459
+ </>
1460
+ );
1460
1461
  }
1461
1462
  }
1462
1463
  }
1463
1464
 
1464
1465
  let formField: OctaneNode = null;
1465
1466
  if (props.required && !selectValue.length && !props.isDisabled) {
1466
- formField = <input
1467
- required={true}
1468
- name={props.name}
1469
- tabIndex={-1}
1470
- aria-hidden="true"
1471
- onFocus={(event: FocusEvent) => {
1472
- event.preventDefault();
1473
- event.stopPropagation();
1474
- inputRef.current?.focus();
1475
- }}
1476
- className={resolveStyle(requiredInputStyle).className}
1477
- value=""
1478
- onInput={() => {}}
1479
- />;
1467
+ formField = (
1468
+ <input
1469
+ required={true}
1470
+ name={props.name}
1471
+ tabIndex={-1}
1472
+ aria-hidden="true"
1473
+ onFocus={(event: FocusEvent) => {
1474
+ event.preventDefault();
1475
+ event.stopPropagation();
1476
+ inputRef.current?.focus();
1477
+ }}
1478
+ className={resolveStyle(requiredInputStyle).className}
1479
+ value=""
1480
+ onInput={() => {}}
1481
+ />
1482
+ );
1480
1483
  } else if (props.name && !props.isDisabled) {
1481
1484
  if (props.isMulti) {
1482
- formField = props.delimiter
1483
- ? <input
1484
- name={props.name}
1485
- type="hidden"
1486
- value={selectValue.map(props.getOptionValue).join(props.delimiter)}
1487
- />
1488
- : <div>
1489
- {selectValue.length
1490
- ? selectValue.map(
1491
- (option, index) =>
1492
- <input
1493
- key={`i-${index}`}
1494
- name={props.name}
1495
- type="hidden"
1496
- value={props.getOptionValue(option)}
1497
- />,
1498
- )
1499
- : <input name={props.name} type="hidden" value="" />}
1500
- </div>;
1485
+ formField = props.delimiter ? (
1486
+ <input
1487
+ name={props.name}
1488
+ type="hidden"
1489
+ value={selectValue.map(props.getOptionValue).join(props.delimiter)}
1490
+ />
1491
+ ) : (
1492
+ <div>
1493
+ {selectValue.length ? (
1494
+ selectValue.map((option, index) => (
1495
+ <input
1496
+ key={`i-${index}`}
1497
+ name={props.name}
1498
+ type="hidden"
1499
+ value={props.getOptionValue(option)}
1500
+ />
1501
+ ))
1502
+ ) : (
1503
+ <input name={props.name} type="hidden" value="" />
1504
+ )}
1505
+ </div>
1506
+ );
1501
1507
  } else {
1502
- formField = <input
1503
- name={props.name}
1504
- type="hidden"
1505
- value={selectValue[0] ? props.getOptionValue(selectValue[0]) : ''}
1506
- />;
1508
+ formField = (
1509
+ <input
1510
+ name={props.name}
1511
+ type="hidden"
1512
+ value={selectValue[0] ? props.getOptionValue(selectValue[0]) : ''}
1513
+ />
1514
+ );
1507
1515
  }
1508
1516
  }
1509
1517
  <Components.SelectContainer
@@ -1542,15 +1550,13 @@ export function Select<
1542
1550
  {createElement(Components.ValueContainer, {
1543
1551
  ...commonProps,
1544
1552
  isDisabled: props.isDisabled,
1545
- children: props.isMulti && Array.isArray(valueUI)
1546
- ? [
1547
- ...valueUI,
1548
- createElement(Fragment, { key: 'select-input', children: inputUI }),
1549
- ]
1550
- : [
1551
- createElement(Fragment, { key: 'select-value', children: valueUI }),
1552
- createElement(Fragment, { key: 'select-input', children: inputUI }),
1553
- ],
1553
+ children:
1554
+ props.isMulti && Array.isArray(valueUI)
1555
+ ? [...valueUI, createElement(Fragment, { key: 'select-input', children: inputUI })]
1556
+ : [
1557
+ createElement(Fragment, { key: 'select-value', children: valueUI }),
1558
+ createElement(Fragment, { key: 'select-input', children: inputUI }),
1559
+ ],
1554
1560
  })}
1555
1561
  </>
1556
1562
  } @else {
@@ -1560,50 +1566,52 @@ export function Select<
1560
1566
  </Components.ValueContainer>
1561
1567
  }
1562
1568
  <Components.IndicatorsContainer {...commonProps} isDisabled={props.isDisabled}>
1563
- {(props.isClearable ?? Boolean(props.isMulti)) && selectValue.length && !props.isDisabled &&
1564
- !props.isLoading
1565
- ? <Components.ClearIndicator
1566
- {...commonProps}
1567
- innerProps={{
1568
- 'aria-hidden': 'true',
1569
- onMouseDown: handleClearPointerEnd,
1570
- onTouchEnd: (event: TouchEvent) => {
1571
- if (!userIsDragging.current) handleClearPointerEnd(event);
1572
- },
1573
- }}
1574
- isDisabled={props.isDisabled}
1575
- isFocused={isFocused}
1576
- />
1577
- : null}
1578
- {props.isLoading
1579
- ? <Components.LoadingIndicator
1580
- {...commonProps}
1581
- innerProps={{ 'aria-hidden': 'true' }}
1582
- isDisabled={props.isDisabled}
1583
- isFocused={isFocused}
1584
- />
1585
- : null}
1586
- {Components.DropdownIndicator && Components.IndicatorSeparator
1587
- ? <Components.IndicatorSeparator
1588
- {...commonProps}
1589
- isDisabled={props.isDisabled}
1590
- isFocused={isFocused}
1591
- />
1592
- : null}
1593
- {Components.DropdownIndicator
1594
- ? <Components.DropdownIndicator
1595
- {...commonProps}
1596
- innerProps={{
1597
- 'aria-hidden': 'true',
1598
- onMouseDown: handleDropdownPointerEnd,
1599
- onTouchEnd: (event: TouchEvent) => {
1600
- if (!userIsDragging.current) handleDropdownPointerEnd(event);
1601
- },
1602
- }}
1603
- isDisabled={props.isDisabled}
1604
- isFocused={isFocused}
1605
- />
1606
- : null}
1569
+ {(props.isClearable ?? Boolean(props.isMulti)) &&
1570
+ selectValue.length &&
1571
+ !props.isDisabled &&
1572
+ !props.isLoading ? (
1573
+ <Components.ClearIndicator
1574
+ {...commonProps}
1575
+ innerProps={{
1576
+ 'aria-hidden': 'true',
1577
+ onMouseDown: handleClearPointerEnd,
1578
+ onTouchEnd: (event: TouchEvent) => {
1579
+ if (!userIsDragging.current) handleClearPointerEnd(event);
1580
+ },
1581
+ }}
1582
+ isDisabled={props.isDisabled}
1583
+ isFocused={isFocused}
1584
+ />
1585
+ ) : null}
1586
+ {props.isLoading ? (
1587
+ <Components.LoadingIndicator
1588
+ {...commonProps}
1589
+ innerProps={{ 'aria-hidden': 'true' }}
1590
+ isDisabled={props.isDisabled}
1591
+ isFocused={isFocused}
1592
+ />
1593
+ ) : null}
1594
+ {Components.DropdownIndicator && Components.IndicatorSeparator ? (
1595
+ <Components.IndicatorSeparator
1596
+ {...commonProps}
1597
+ isDisabled={props.isDisabled}
1598
+ isFocused={isFocused}
1599
+ />
1600
+ ) : null}
1601
+ {Components.DropdownIndicator ? (
1602
+ <Components.DropdownIndicator
1603
+ {...commonProps}
1604
+ innerProps={{
1605
+ 'aria-hidden': 'true',
1606
+ onMouseDown: handleDropdownPointerEnd,
1607
+ onTouchEnd: (event: TouchEvent) => {
1608
+ if (!userIsDragging.current) handleDropdownPointerEnd(event);
1609
+ },
1610
+ }}
1611
+ isDisabled={props.isDisabled}
1612
+ isFocused={isFocused}
1613
+ />
1614
+ ) : null}
1607
1615
  </Components.IndicatorsContainer>
1608
1616
  </Components.Control>
1609
1617
  {menuUI}
@@ -1615,7 +1623,6 @@ export type PublicBaseSelectProps<
1615
1623
  Option,
1616
1624
  IsMulti extends boolean,
1617
1625
  Group extends GroupBase<Option>,
1618
- > =
1619
- SelectProps<Option, IsMulti, Group>;
1626
+ > = SelectProps<Option, IsMulti, Group>;
1620
1627
 
1621
1628
  export const baseComponents = builtinComponents;