Skip to content
This repository has been archived by the owner on Jun 11, 2021. It is now read-only.

feat: swap Preact with React #34

Merged
merged 3 commits into from
Mar 3, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ module.exports = {
},
settings: {
react: {
pragma: 'React',
version: 'detect',
pragma: 'h',
},
'import/resolver': {
node: {
Expand Down Expand Up @@ -36,14 +36,5 @@ module.exports = {
'import/no-extraneous-dependencies': 'off',
},
},
{
files: ['packages/website/**/*'],
settings: {
react: {
pragma: 'React',
version: 'detect',
},
},
},
],
};
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = api => {
],
],
plugins: [
['@babel/plugin-transform-react-jsx', { pragma: 'h' }],
['@babel/plugin-transform-react-jsx'],
!isTest && [
'inline-replace-variables',
{
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"@testing-library/jest-dom": "5.1.1",
"@testing-library/preact": "1.0.2",
"@testing-library/user-event": "10.0.0",
"@types/react": "^16.9.23",
"@types/react-dom": "^16.9.5",
"@typescript-eslint/eslint-plugin": "2.19.0",
"@typescript-eslint/parser": "2.19.0",
"algoliasearch": "4.0.2",
Expand All @@ -66,8 +68,9 @@
"jest": "25.1.0",
"jest-watch-typeahead": "0.4.2",
"lerna": "3.20.2",
"preact": "10.3.1",
"prettier": "1.19.1",
"react": "16.13.0",
"react-dom": "16.13.0",
"rollup": "1.31.0",
"rollup-plugin-babel": "4.3.3",
"rollup-plugin-commonjs": "10.1.0",
Expand Down
11 changes: 8 additions & 3 deletions packages/autocomplete-core/src/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import { getAutocompleteSetters } from './setters';

import { PublicAutocompleteOptions, AutocompleteApi } from './types';

function createAutocomplete<TItem extends {}>(
function createAutocomplete<
TItem extends {},
TEvent = Event,
TMouseEvent = MouseEvent,
TKeyboardEvent = KeyboardEvent
>(
options: PublicAutocompleteOptions<TItem>
): AutocompleteApi<TItem> {
): AutocompleteApi<TItem, TEvent, TMouseEvent, TKeyboardEvent> {
const props = getDefaultProps(options);
const store = createStore(stateReducer, props);

Expand All @@ -28,7 +33,7 @@ function createAutocomplete<TItem extends {}>(
getItemProps,
getLabelProps,
getMenuProps,
} = getPropGetters({
} = getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
store,
props,
setHighlightedIndex,
Expand Down
46 changes: 27 additions & 19 deletions packages/autocomplete-core/src/propGetters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface GetPropGettersOptions<TItem> extends AutocompleteSetters<TItem> {
props: AutocompleteOptions<TItem>;
}

export function getPropGetters<TItem>({
export function getPropGetters<TItem, TEvent, TMouseEvent, TKeyboardEvent>({
store,
props,
setHighlightedIndex,
Expand Down Expand Up @@ -50,7 +50,10 @@ export function getPropGetters<TItem>({
].some(contextNode => {
return (
contextNode &&
(isOrContainsNode(contextNode, event.target as Node) ||
(isOrContainsNode(
contextNode,
((event as unknown) as TouchEvent).target as Node
eunjae-lee marked this conversation as resolved.
Show resolved Hide resolved
) ||
isOrContainsNode(
contextNode,
props.environment.document.activeElement!
Expand Down Expand Up @@ -84,18 +87,18 @@ export function getPropGetters<TItem>({
role: 'combobox',
'aria-expanded': store.getState().isOpen,
'aria-haspopup': 'listbox',
'aria-owns': store.getState().isOpen ? `${props.id}-menu` : null,
'aria-owns': store.getState().isOpen ? `${props.id}-menu` : undefined,
'aria-labelledby': `${props.id}-label`,
...rest,
};
};

const getFormProps: GetFormProps = providedProps => {
const getFormProps: GetFormProps<TEvent> = providedProps => {
const { inputElement, ...rest } = providedProps;

return {
onSubmit: event => {
event.preventDefault();
((event as unknown) as Event).preventDefault();

props.onSubmit({
state: store.getState(),
Expand All @@ -115,7 +118,7 @@ export function getPropGetters<TItem>({
}
},
onReset: event => {
event.preventDefault();
((event as unknown) as Event).preventDefault();

if (props.openOnFocus) {
onInput({
Expand All @@ -140,7 +143,11 @@ export function getPropGetters<TItem>({
};
};

const getInputProps: GetInputProps = providedProps => {
const getInputProps: GetInputProps<
TEvent,
TMouseEvent,
TKeyboardEvent
> = providedProps => {
function onFocus() {
// We want to trigger a query when `openOnFocus` is true
// because the dropdown should open with the current query.
Expand Down Expand Up @@ -168,22 +175,23 @@ export function getPropGetters<TItem>({
'aria-activedescendant':
store.getState().isOpen && store.getState().highlightedIndex !== null
? `${props.id}-item-${store.getState().highlightedIndex}`
: null,
'aria-controls': store.getState().isOpen ? `${props.id}-menu` : null,
: undefined,
'aria-controls': store.getState().isOpen ? `${props.id}-menu` : undefined,
'aria-labelledby': `${props.id}-label`,
value: store.getState().query,
id: `${props.id}-input`,
autoComplete: 'off',
autoCorrect: 'off',
autoCapitalize: 'off',
spellCheck: false,
autofocus: props.autoFocus,
autoFocus: props.autoFocus,
placeholder: props.placeholder,
// @TODO: see if this accessibility attribute is necessary
// 'aria-expanded': store.getStore().isOpen,
onInput: (event: InputEvent) => {
onChange: event => {
onInput({
query: (event.currentTarget as HTMLInputElement).value,
query: (((event as unknown) as Event)
.currentTarget as HTMLInputElement).value,
store,
props,
setHighlightedIndex,
Expand All @@ -194,9 +202,9 @@ export function getPropGetters<TItem>({
setContext,
});
},
onKeyDown: (event: KeyboardEvent) => {
onKeyDown: event => {
onKeyDown({
event,
event: (event as unknown) as KeyboardEvent,
store,
props,
setHighlightedIndex,
Expand Down Expand Up @@ -235,7 +243,7 @@ export function getPropGetters<TItem>({
};
};

const getItemProps: GetItemProps<any> = providedProps => {
const getItemProps: GetItemProps<any, TMouseEvent> = providedProps => {
const { item, source, ...rest } = providedProps;

return {
Expand Down Expand Up @@ -271,14 +279,14 @@ export function getPropGetters<TItem>({
});
}
},
onMouseDown(event: MouseEvent) {
onMouseDown(event) {
// Prevents the `activeElement` from being changed to the item so it
// can remain with the current `activeElement`.
event.preventDefault();
((event as unknown) as MouseEvent).preventDefault();
},
onClick(event: MouseEvent) {
onClick(event) {
// We ignore all modified clicks to support default browsers' behavior.
if (isSpecialClick(event)) {
if (isSpecialClick((event as unknown) as MouseEvent)) {
return;
}

Expand Down
18 changes: 14 additions & 4 deletions packages/autocomplete-core/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,19 @@ import { AutocompleteAccessibilityGetters } from './getters';
import { AutocompleteSetters } from './setters';
import { AutocompleteState } from './state';

export interface AutocompleteApi<TItem>
export interface AutocompleteApi<
TItem,
TEvent = Event,
TMouseEvent = MouseEvent,
TKeyboardEvent = KeyboardEvent
>
extends AutocompleteSetters<TItem>,
AutocompleteAccessibilityGetters<TItem> {}
AutocompleteAccessibilityGetters<
TItem,
TEvent,
TMouseEvent,
TKeyboardEvent
> {}

export interface AutocompleteSuggestion<TItem> {
source: AutocompleteSource<TItem>;
Expand All @@ -27,14 +37,14 @@ interface OnSelectParams<TItem>
extends ItemParams<TItem>,
AutocompleteSetters<TItem> {
state: AutocompleteState<TItem>;
event: Event;
event: any;
}

type OnHighlightParams<TItem> = OnSelectParams<TItem>;

interface OnSubmitParams<TItem> extends AutocompleteSetters<TItem> {
state: AutocompleteState<TItem>;
event: Event;
event: any;
}

interface OnInputParams<TItem> extends AutocompleteSetters<TItem> {
Expand Down
54 changes: 34 additions & 20 deletions packages/autocomplete-core/src/types/getters.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { AutocompleteSource } from './api';

export interface AutocompleteAccessibilityGetters<TItem> {
export interface AutocompleteAccessibilityGetters<
TItem,
TEvent = Event,
TMouseEvent = MouseEvent,
TKeyboardEvent = KeyboardEvent
> {
getEnvironmentProps: GetEnvironmentProps;
getRootProps: GetRootProps;
getFormProps: GetFormProps;
getInputProps: GetInputProps;
getItemProps: GetItemProps<TItem>;
getFormProps: GetFormProps<TEvent>;
getInputProps: GetInputProps<TEvent, TMouseEvent, TKeyboardEvent>;
getItemProps: GetItemProps<TItem, TMouseEvent>;
getLabelProps: GetLabelProps;
getMenuProps: GetMenuProps;
}
Expand All @@ -25,53 +30,62 @@ export type GetRootProps = (props?: {
}) => {
role: string;
'aria-expanded': boolean;
'aria-haspopup': string;
'aria-owns': string | null;
'aria-haspopup':
| boolean
| 'dialog'
| 'menu'
| 'true'
| 'false'
| 'grid'
| 'listbox'
| 'tree'
| undefined;
'aria-owns': string | undefined;
'aria-labelledby': string;
};

export type GetFormProps = (props: {
export type GetFormProps<TEvent = Event> = (props: {
[key: string]: unknown;
inputElement: HTMLInputElement | null;
}) => {
onSubmit(event: Event): void;
onReset(event: Event): void;
onSubmit(event: TEvent): void;
onReset(event: TEvent): void;
};

export type GetInputProps = (props: {
export type GetInputProps<TEvent, TMouseEvent, TKeyboardEvent> = (props: {
[key: string]: unknown;
inputElement: HTMLInputElement;
}) => {
id: string;
value: string;
autofocus: boolean;
autoFocus: boolean;
placeholder: string;
autoComplete: 'on' | 'off';
autoCorrect: 'on' | 'off';
autoCapitalize: 'on' | 'off';
spellCheck: boolean;
'aria-autocomplete': 'none' | 'inline' | 'list' | 'both';
'aria-activedescendant': string | null;
'aria-controls': string | null;
'aria-activedescendant': string | undefined;
'aria-controls': string | undefined;
'aria-labelledby': string;
onInput(event: Event): void;
onKeyDown(event: KeyboardEvent): void;
onChange(event: TEvent): void;
onKeyDown(event: TKeyboardEvent): void;
onFocus(): void;
onBlur(): void;
onClick(event: MouseEvent): void;
onClick(event: TMouseEvent): void;
};

export type GetItemProps<TItem> = (props: {
export type GetItemProps<TItem, TMouseEvent = MouseEvent> = (props: {
[key: string]: unknown;
item: TItem;
source: AutocompleteSource<TItem>;
}) => {
id: string;
role: string;
'aria-selected': boolean;
onMouseMove(event: MouseEvent): void;
onMouseDown(event: MouseEvent): void;
onClick(event: MouseEvent): void;
onMouseMove(event: TMouseEvent): void;
onMouseDown(event: TMouseEvent): void;
onClick(event: TMouseEvent): void;
};

export type GetLabelProps = (props?: {
Expand Down
2 changes: 1 addition & 1 deletion packages/autocomplete-react/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ module.exports = api => {
},
],
],
plugins: [['@babel/plugin-transform-react-jsx', { pragma: 'h' }]],
plugins: [['@babel/plugin-transform-react-jsx']],
};
};
7 changes: 5 additions & 2 deletions packages/autocomplete-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
"dependencies": {
"@francoischalifour/autocomplete-core": "^1.0.0-alpha.10",
"@francoischalifour/autocomplete-preset-algolia": "^1.0.0-alpha.10",
"@popperjs/core": "^2.0.0",
"preact": "^10.0.0"
"@popperjs/core": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0",
"react-dom": "^16.8.0"
}
}
5 changes: 5 additions & 0 deletions packages/autocomplete-react/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ import { sharedPlugins } from '../autocomplete-core/rollup.config';

export default {
input: 'src/index.ts',
external: ['react', 'react-dom'],
output: {
file: 'dist/umd/index.js',
format: 'umd',
sourcemap: true,
name,
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
plugins: [json(), ...sharedPlugins],
};
Loading