Skip to content

Commit

Permalink
feat(AutoComplete): add canary component
Browse files Browse the repository at this point in the history
  • Loading branch information
gizeasy committed Oct 15, 2024
1 parent e522089 commit 010986e
Show file tree
Hide file tree
Showing 51 changed files with 3,523 additions and 114 deletions.
43 changes: 43 additions & 0 deletions src/components/AutoCompleteCanary/AutoComplete.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';

import { AutoCompleteTypeText } from './AutoCompleteTypeText';
import { AutoCompleteTypeTextArray } from './AutoCompleteTypeTextArray';
import {
AutoCompleteComponent,
AutoCompleteGroupDefault,
AutoCompleteItemDefault,
AutoCompleteProps,
AutoCompleteTypeComponent,
} from './types';

const typeMap: Record<
string,
AutoCompleteTypeComponent<string> | AutoCompleteTypeComponent<'textarray'>
> = {
text: AutoCompleteTypeText,
textarray: AutoCompleteTypeTextArray,
};

const AutoCompleteRender = <
TYPE extends string,
ITEM = AutoCompleteItemDefault,
GROUP = AutoCompleteGroupDefault,
>(
props: AutoCompleteProps<TYPE, ITEM, GROUP>,
ref: React.Ref<HTMLDivElement>,
) => {
const Component = typeMap[props.type || 'text'] || typeMap.text;

return (
<Component
ref={ref}
{...(props as unknown as AutoCompleteTypeComponent<TYPE, ITEM, GROUP>)}
/>
);
};

export const AutoComplete = React.forwardRef(
AutoCompleteRender,
) as AutoCompleteComponent;

export * from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React, { forwardRef, useRef } from 'react';

import { SelectDropdown } from '##/components/SelectComponents/SelectDropdown';
import {
defaultPropForm,
defaultPropSize,
defaultPropView,
} from '##/components/SelectComponentsDeprecated/types';
import { TextFieldTypeText } from '##/components/TextFieldCanary';
import { useForkRef } from '##/hooks/useForkRef';

import { withDefaultGetters } from '../helpers';
import { AutoCompleteTypeComponent } from '../types';
import { useAutoComplete } from '../useAutoComplete';
import { useRenderItemDefault } from '../useRenderItemDefault';

export const AutoCompleteTypeText: AutoCompleteTypeComponent<string> =
forwardRef((props, componentRef) => {
const {
items = [],
groups = [],
disabled = false,
getItemLabel,
getItemKey,
isLoading,
getItemGroupKey,
getGroupKey,
getGroupLabel,
inputRef,
onFocus,
dropdownRef: dropdownRefProp,
dropdownClassName,
dropdownForm = 'default',
value,
form = defaultPropForm,
view = defaultPropView,
size = defaultPropSize,
onChange,
style,
renderItem,
searchFunction,
id,
name,
className,
virtualScroll,
onScrollToBottom,
onDropdownOpen,
dropdownOpen,
ignoreOutsideClicksRefs,
...otherProps
} = withDefaultGetters(props);

const dropdownRef = useRef<HTMLDivElement | null>(null);
const controlRef = useRef<HTMLDivElement>(null);

const {
getOptionProps,
isOpen,
getKeyProps,
visibleItems,
handleInputFocus,
inputRef: inputControlRef,
optionsRefs,
handleChange,
} = useAutoComplete({
items,
groups,
onChange,
dropdownRef,
disabled,
searchValue: value || '',
getItemLabel,
getItemKey,
getItemGroupKey,
getGroupKey,
onFocus,
searchFunction,
isLoading,
onDropdownOpen,
dropdownOpen,
ignoreOutsideClicksRefs: [controlRef, ...(ignoreOutsideClicksRefs || [])],
});

const renderItemDefault = useRenderItemDefault(
getItemLabel,
disabled,
size,
dropdownForm,
);

return (
<>
<TextFieldTypeText
{...getKeyProps()}
form={form}
view={view}
id={id}
className={className}
name={name}
disabled={disabled}
ref={useForkRef([controlRef, componentRef])}
inputRef={useForkRef([inputRef, inputControlRef])}
onChange={handleChange}
onFocus={handleInputFocus}
value={value}
style={style}
size={size}
{...otherProps}
/>
<SelectDropdown
isOpen={isOpen}
size={size}
controlRef={controlRef}
getOptionProps={getOptionProps}
dropdownRef={useForkRef([dropdownRef, dropdownRefProp])}
form={dropdownForm}
className={dropdownClassName}
renderItem={renderItem || renderItemDefault}
getGroupLabel={getGroupLabel}
visibleItems={visibleItems}
isLoading={isLoading}
hasItems={items.length !== 0}
itemsRefs={optionsRefs}
virtualScroll
style={
typeof style?.zIndex === 'number'
? { zIndex: style.zIndex + 1 }
: undefined
}
onScrollToBottom={onScrollToBottom}
/>
</>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AutoCompleteTypeText';
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React, { forwardRef, useRef } from 'react';

import { SelectDropdown } from '##/components/SelectComponents/SelectDropdown';
import {
defaultPropForm,
defaultPropSize,
defaultPropView,
} from '##/components/SelectComponentsDeprecated/types';
import { TextFieldTypeTextArray } from '##/components/TextFieldCanary';
import { useForkRef } from '##/hooks/useForkRef';

import { withDefaultGetters } from '../helpers';
import { AutoCompleteTypeComponent } from '../types';
import { useAutoComplete } from '../useAutoComplete';
import { useRenderItemDefault } from '../useRenderItemDefault';

export const AutoCompleteTypeTextArray: AutoCompleteTypeComponent<'textarray'> =
forwardRef((props, componentRef) => {
const withDefaultGettersProps = withDefaultGetters(props);
const {
items = [],
groups = [],
disabled = false,
getItemLabel,
getItemKey,
isLoading,
getItemGroupKey,
getGroupKey,
getGroupLabel,
inputRef,
onFocus,
dropdownRef: dropdownRefProp,
dropdownClassName,
dropdownForm = 'default',
value,
form = defaultPropForm,
view = defaultPropView,
size = defaultPropSize,
onChange,
style,
renderItem,
searchFunction,
id,
name,
className,
virtualScroll,
onScrollToBottom,
onDropdownOpen,
dropdownOpen,
ignoreOutsideClicksRefs,
onInputChange,
inputValue,
...otherProps
} = withDefaultGettersProps;

const dropdownRef = useRef<HTMLDivElement | null>(null);
const controlRef = useRef<HTMLDivElement>(null);

const {
getOptionProps,
isOpen,
getKeyProps,
visibleItems,
handleInputFocus,
inputRef: inputControlRef,
optionsRefs,
handleChange,
highlightedIndex,
} = useAutoComplete({
items,
groups,
onChange: onInputChange,
dropdownRef,
disabled,
searchValue: inputValue || '',
getItemLabel,
getItemKey,
getItemGroupKey,
getGroupKey,
onFocus,
searchFunction,
isLoading,
onDropdownOpen,
dropdownOpen,
ignoreOutsideClicksRefs: [controlRef, ...(ignoreOutsideClicksRefs || [])],
});

const renderItemDefault = useRenderItemDefault(
getItemLabel,
disabled,
size,
dropdownForm,
);

return (
<>
<TextFieldTypeTextArray
{...getKeyProps()}
form={form}
view={view}
id={id}
className={className}
name={name}
disabled={disabled}
ref={useForkRef([controlRef, componentRef])}
inputRef={useForkRef([inputRef, inputControlRef])}
onFocus={handleInputFocus}
onChange={highlightedIndex < 0 ? onChange : undefined}
onInputChange={handleChange}
value={value}
style={style}
size={size}
{...otherProps}
/>
<SelectDropdown
isOpen={isOpen}
size={size}
controlRef={controlRef}
getOptionProps={getOptionProps}
dropdownRef={useForkRef([dropdownRef, dropdownRefProp])}
form={dropdownForm}
className={dropdownClassName}
renderItem={renderItem || renderItemDefault}
getGroupLabel={getGroupLabel}
visibleItems={visibleItems}
isLoading={isLoading}
hasItems={items.length !== 0}
itemsRefs={optionsRefs}
virtualScroll
style={
typeof style?.zIndex === 'number'
? { zIndex: style.zIndex + 1 }
: undefined
}
onScrollToBottom={onScrollToBottom}
/>
</>
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AutoCompleteTypeTextArray';
Loading

0 comments on commit 010986e

Please sign in to comment.