Skip to content

Commit

Permalink
feat: new react-dropdown component
Browse files Browse the repository at this point in the history
  • Loading branch information
Federico Zivolo committed Jan 31, 2019
1 parent b628148 commit 38e20e8
Show file tree
Hide file tree
Showing 18 changed files with 3,752 additions and 21 deletions.
251 changes: 251 additions & 0 deletions flow-typed/npm/downshift_v2.x.x.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
/**
* Flowtype definitions for index
* Generated by Flowgen from a Typescript Definition
* Flowgen v1.2.0
* Author: [Joar Wilk](http://twitter.com/joarwilk)
* Repo: http://github.com/joarwilk/flowgen
*/

// These types have been copied from the Downshift repository
// they aren't high quality and so we need to occasionally patch them when needed

import React from 'react'

declare module downshift {
declare type StateChangeTypes = {
unknown: '__autocomplete_unknown__',
mouseUp: '__autocomplete_mouseup__',
itemMouseEnter: '__autocomplete_item_mouseenter__',
keyDownArrowUp: '__autocomplete_keydown_arrow_up__',
keyDownArrowDown: '__autocomplete_keydown_arrow_down__',
keyDownEscape: '__autocomplete_keydown_escape__',
keyDownEnter: '__autocomplete_keydown_enter__',
clickItem: '__autocomplete_click_item__',
blurInput: '__autocomplete_blur_input__',
changeInput: '__autocomplete_change_input__',
keyDownSpaceButton: '__autocomplete_keydown_space_button__',
clickButton: '__autocomplete_click_button__',
blurButton: '__autocomplete_blur_button__',
controlledPropUpdatedSelectedItem: '__autocomplete_controlled_prop_updated_selected_item__',
}
declare type StateChangeValues =
| '__autocomplete_unknown__'
| '__autocomplete_mouseup__'
| '__autocomplete_item_mouseenter__'
| '__autocomplete_keydown_arrow_up__'
| '__autocomplete_keydown_arrow_down__'
| '__autocomplete_keydown_escape__'
| '__autocomplete_keydown_enter__'
| '__autocomplete_click_item__'
| '__autocomplete_blur_input__'
| '__autocomplete_change_input__'
| '__autocomplete_keydown_space_button__'
| '__autocomplete_click_button__'
| '__autocomplete_blur_button__'
| '__autocomplete_controlled_prop_updated_selected_item__'
declare type Callback = () => void
declare export interface DownshiftState<Item> {
highlightedIndex: number | null;
inputValue: string | null;
isOpen: boolean;
selectedItem: Item;
}
declare export interface DownshiftProps<Item> {
defaultSelectedItem?: Item;
defaultHighlightedIndex?: number | null;
defaultInputValue?: string;
defaultIsOpen?: boolean;
itemToString?: (item: Item) => string;
selectedItemChanged?: (prevItem: Item, item: Item) => boolean;
getA11yStatusMessage?: (options: A11yStatusMessageOptions<Item>) => string;
onChange?: (
selectedItem: Item,
stateAndHelpers: ControllerStateAndHelpers<Item>,
) => void;
onSelect?: (
selectedItem: Item,
stateAndHelpers: ControllerStateAndHelpers<Item>,
) => void;
onStateChange?: (
options: StateChangeOptions<Item>,
stateAndHelpers: ControllerStateAndHelpers<Item>,
) => void;
onInputValueChange?: (
inputValue: string,
stateAndHelpers: ControllerStateAndHelpers<Item>,
) => void;
stateReducer?: (
state: DownshiftState<Item>,
changes: StateChangeOptions<Item>,
) => StateChangeOptions<Item>;
itemCount?: number;
highlightedIndex?: number;
inputValue?: string;
isOpen?: boolean;
selectedItem?: Item;
children: ChildrenFunction<Item>;
id?: string;
environment?: Environment;
onOuterClick?: () => void;
onUserAction?: (
options: StateChangeOptions<Item>,
stateAndHelpers: ControllerStateAndHelpers<Item>,
) => void;
}
declare export interface Environment {
addEventListener: typeof window.addEventListener;
removeEventListener: typeof window.removeEventListener;
document: Document;
}
declare export interface A11yStatusMessageOptions<Item> {
highlightedIndex: number | null;
inputValue: string;
isOpen: boolean;
itemToString: (item: Item) => string;
previousResultCount: number;
resultCount: number;
selectedItem: Item;
}
declare export interface StateChangeOptions<Item> {
type: StateChangeValues;
highlightedIndex: number;
inputValue: string;
isOpen: boolean;
selectedItem: Item;
}
declare export type StateChangeFunction<Item> = (
state: DownshiftState<Item>,
) => StateChangeOptions<Item>

declare export type GetRootPropsReturn = {
role: 'combobox';
'aria-expanded': boolean;
'aria-haspopup': 'listbox';
'aria-owns': string | null;
'aria-labelledby': string;
}
declare export interface GetRootPropsOptions {
refKey: string;
}

declare type GetToggleButtonCallbacks = {
onMouseMove: (e: SyntheticEvent<Element>) => void;
onMouseDown: (e: SyntheticEvent<Element>) => void;
onBlur: (e: SyntheticEvent<Element>) => void;
} | {
onPress: (e: SyntheticEvent<Element>) => void; // should be react native type
} | {}
declare export type GetToggleButtonReturn = {
type: 'button';
role: 'button';
'aria-label': 'close menu' | 'open menu';
'aria-haspopup': true;
'data-toggle': true;
} & GetInputPropsCallbacks
declare export interface getToggleButtonPropsOptions
extends React.HTMLProps<HTMLButtonElement> {}

declare export interface GetLabelPropsReturn {
htmlFor: string;
id: string;
}
declare export interface GetLabelPropsOptions
extends React.HTMLProps<HTMLLabelElement> {}

declare export type getMenuPropsReturn = {
role: 'listbox';
'aria-labelledby': string | null;
id: string;
}

declare type GetInputPropsCallbacks = ({
onKeyDown: (e: SyntheticEvent<Element>) => void;
onBlur: (e: SyntheticEvent<Element>) => void;
} & ({
onInput: (e: SyntheticEvent<Element>) => void;
} | {
onChangeText: (e: SyntheticEvent<Element>) => void;
} | {
onChange: (e: SyntheticEvent<Element>) => void;
})) | {}
declare export type GetInputPropsReturn = {
'aria-autocomplete': 'list';
'aria-activedescendant': string | null;
'aria-controls': string | null;
'aria-labelledby': string;
autoComplete: 'off';
value: string;
id: string;
} & GetInputPropsCallbacks;
declare export interface GetInputPropsOptions
extends React.HTMLProps<HTMLInputElement> {}

declare type GetItemPropsCallbacks = {
onMouseMove: (e: SyntheticEvent<Element>) => void;
onMouseDown: (e: SyntheticEvent<Element>) => void;
} & ({
onPress: (e: SyntheticEvent<Element>) => void;
} | {
onClick: (e: SyntheticEvent<Element>) => void;
})
declare export type GetItemPropsReturn = {
id: string;
role: 'option';
'aria-selected': boolean;
} & GetItemPropsCallbacks
declare export type GetItemPropsOptions<Item> = {
index?: number,
item: Item,
}

declare export interface PropGetters<Item> {
getRootProps: <T:{}>(options: GetRootPropsOptions & T) => GetRootPropsReturn & T;
getButtonProps: <T:{}>(options?: getToggleButtonPropsOptions & T) => GetToggleButtonReturn & T;
getToggleButtonProps: <T:{}>(options?: getToggleButtonPropsOptions & T) => GetToggleButtonReturn & T;
getLabelProps: <T:{}>(options?: GetLabelPropsOptions & T) => GetLabelPropsReturn & T;
getMenuProps: <T:{}>(options?: T) => getMenuPropsReturn & T;
getInputProps: <T:{}>(options?: GetInputPropsOptions & T) => GetInputPropsReturn & T;
getItemProps: <T:Object>(options: GetItemPropsOptions<Item> & T) => GetItemPropsReturn & T;
}
declare export interface Actions<Item> {
reset: (otherStateToSet?: {}, cb?: Callback) => void;
openMenu: (cb?: Callback) => void;
closeMenu: (cb?: Callback) => void;
toggleMenu: (otherStateToSet?: {}, cb?: Callback) => void;
selectItem: (item: Item, otherStateToSet?: {}, cb?: Callback) => void;
selectItemAtIndex: (
index: number,
otherStateToSet?: {},
cb?: Callback,
) => void;
selectHighlightedItem: (otherStateToSet?: {}, cb?: Callback) => void;
setHighlightedIndex: (
index: number,
otherStateToSet?: {},
cb?: Callback,
) => void;
clearSelection: (cb?: Callback) => void;
clearItems: () => void;
setItemCount: (count: number) => void;
unsetItemCount: () => void;
setState: (
stateToSet: StateChangeOptions<Item> | StateChangeFunction<Item>,
cb?: Callback,
) => void;
// props
itemToString: (item: Item) => string;
}
declare export type ControllerStateAndHelpers<Item> = DownshiftState<Item> &
PropGetters<Item> &
Actions<Item>
declare export type ChildrenFunction<Item> = (
options: ControllerStateAndHelpers<Item>,
) => React.ReactNode
declare export type DownshiftType<Item> = Class<
React.Component<DownshiftProps<Item>, DownshiftState<Item>>,
> & {
stateChangeTypes: StateChangeTypes,
}
declare var DownshiftComponent: DownshiftType<any>
declare export default DownshiftComponent
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
"@quid/theme": "^1.0.0",
"builder-init": "^0.5.1",
"customize-cra": "^0.2.7",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.1",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.8.0",
"enzyme-to-json": "^3.3.5",
"eslint-plugin-flow-header": "^0.2.0",
"eslint-plugin-notice": "^0.7.7",
Expand Down
31 changes: 31 additions & 0 deletions packages/react-dropdown/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
A feature complete "dropdown" component built with React and Downshift.

It supports most of the possible use cases, included category grouping, two column layout, and more.

#### Installation

```bash
npm install --save @quid/react-dropdown

# or

yarn add @quid/react-dropdown
```

#### Usage

```jsx static
import Dropdown from '@quid/react-dropdown';

const items = [
{ id: 1, label: 'One' },
{ id: 2, label: 'Two' },
{ id: 3, label: 'Three' },
{ id: 4, label: 'Four' },
{ id: 5, label: 'Five' },
];

<Dropdown items={items} selectedItems={[items[0]]}>
{({ getInputProps }) => <input readOnly {...getInputProps()} />}
</Dropdown>;
```
37 changes: 37 additions & 0 deletions packages/react-dropdown/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@quid/react-dropdown",
"version": "1.0.0",
"description": "React dropdown component with ARIA accessibility and advanced functionalities",
"main": "dist/index.js",
"main:umd": "dist/index.umd.js",
"module": "dist/index.es.js",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/quid/ui-framework.git"
},
"scripts": {
"start": "microbundle watch",
"prepare": "microbundle build --jsx React.createElement && flow-copy-source --ignore '{__mocks__/*,*.test}.js' src dist",
"test": "cd ../.. && yarn test --testPathPattern packages/react-dropdown"
},
"devDependencies": {
"flow-copy-source": "^2.0.2",
"microbundle": "^0.8.3",
"react": "^16.0.0"
},
"peerDependencies": {
"react": "15||16"
},
"dependencies": {
"@emotion/core": "^10.0.6",
"@emotion/css": "^10.0.6",
"@emotion/styled": "^10.0.6",
"@quid/react-core": "^1.0.0",
"@quid/theme": "^1.0.0",
"color": "^3.1.0",
"downshift": "^3.2.0",
"popper.js": "^1.14.7",
"react-popper": "^1.3.3"
}
}
Loading

0 comments on commit 38e20e8

Please sign in to comment.