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

Commit

Permalink
feat: swap Preact with React (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
francoischalifour authored Mar 3, 2020
1 parent 074c92d commit e0f2568
Show file tree
Hide file tree
Showing 19 changed files with 338 additions and 247 deletions.
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
41 changes: 23 additions & 18 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 @@ -84,18 +84,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 +115,7 @@ export function getPropGetters<TItem>({
}
},
onReset: event => {
event.preventDefault();
((event as unknown) as Event).preventDefault();

if (props.openOnFocus) {
onInput({
Expand All @@ -140,7 +140,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 +172,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 +199,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 +240,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 +276,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

0 comments on commit e0f2568

Please sign in to comment.