Skip to content

Commit

Permalink
feat: add Select component (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
korvin89 authored Feb 4, 2022
1 parent 7de5055 commit 3b9246a
Show file tree
Hide file tree
Showing 28 changed files with 1,592 additions and 8 deletions.
8 changes: 4 additions & 4 deletions src/components/List/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class List<T = unknown> extends React.Component<ListProps<T>, ListState<T
break;
}
case 'Enter': {
if (activeItem && !isNaN(activeItem) && this.props.onItemClick) {
if (typeof activeItem === 'number' && this.props.onItemClick) {
this.props.onItemClick(this.state.items[activeItem], activeItem, true);
}
break;
Expand Down Expand Up @@ -203,7 +203,7 @@ export class List<T = unknown> extends React.Component<ListProps<T>, ListState<T
itemClassName={this.props.itemClassName}
active={active}
selected={index === this.props.selectedItemIndex}
onMouseMove={this.onItemMouseMove}
onActivate={this.onItemActivate}
onClick={this.props.onItemClick}
/>
);
Expand Down Expand Up @@ -401,7 +401,7 @@ export class List<T = unknown> extends React.Component<ListProps<T>, ListState<T
});
};

private onItemMouseMove = (index: number) => {
private onItemActivate = (index?: number) => {
if (!this.state.sorting) {
this.activateItem(index, false);
}
Expand Down Expand Up @@ -431,7 +431,7 @@ export class List<T = unknown> extends React.Component<ListProps<T>, ListState<T

if (typeof itemHeight === 'function') {
const {items} = this.state;
return itemHeight(items[index]);
return itemHeight(items[index], index);
}
return itemHeight;
};
Expand Down
9 changes: 6 additions & 3 deletions src/components/List/components/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ type ListItemProps<T> = {
sortable?: boolean;
sortHandleAlign?: ListSortHandleAlign;
style?: React.CSSProperties;
onActivate: (index?: number) => void;
renderItem?: ListProps<T>['renderItem'];
onClick?: ListProps<T>['onItemClick'];
onMouseMove?: (index: number) => void;
};

const defaultRenderItem = <T extends unknown>(item: T) => String(item);
Expand All @@ -43,7 +43,8 @@ export class ListItem<T = unknown> extends React.Component<ListItemProps<T>> {
)}
style={style}
onClick={this.onClick}
onMouseMove={this.onMouseMove}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
ref={this.ref}
>
{this.renderSortIcon()}
Expand All @@ -70,5 +71,7 @@ export class ListItem<T = unknown> extends React.Component<ListItemProps<T>> {

private onClick = () => this.props.onClick?.(this.props.item, this.props.itemIndex);

private onMouseMove = () => this.props.onMouseMove?.(this.props.itemIndex);
private onMouseEnter = () => this.props.onActivate(this.props.itemIndex);

private onMouseLeave = () => this.props.onActivate(undefined);
}
2 changes: 1 addition & 1 deletion src/components/List/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type ListProps<T = unknown> = {
filter?: string;
activeItemIndex?: number;
selectedItemIndex?: number;
itemHeight?: number | ((item: ListItemData<T>) => number);
itemHeight?: number | ((item: ListItemData<T>, itemIndex: number) => number);
itemsHeight?: number | ((items: T[]) => number);
virtualized?: boolean;
filterable?: boolean;
Expand Down
6 changes: 6 additions & 0 deletions src/components/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const KeyCode = {
BACKSPACE: 'Backspace',
ENTER: 'Enter',
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values#whitespace_keys
SPACEBAR: ' ',
};
16 changes: 16 additions & 0 deletions src/components/icons/Chevron.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';

export function Chevron(props: React.SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
width="16"
height="16"
fill="currentColor"
{...props}
>
<path d="M3.50172 5.44253C3.19384 5.16544 2.71962 5.19039 2.44253 5.49828C2.16544 5.80616 2.19039 6.28038 2.49828 6.55747L3.50172 5.44253ZM8 10.5L7.49828 11.0575C7.7835 11.3142 8.2165 11.3142 8.50172 11.0575L8 10.5ZM13.5017 6.55747C13.8096 6.28038 13.8346 5.80616 13.5575 5.49828C13.2804 5.19039 12.8062 5.16544 12.4983 5.44253L13.5017 6.55747ZM2.49828 6.55747L7.49828 11.0575L8.50172 9.94253L3.50172 5.44253L2.49828 6.55747ZM8.50172 11.0575L13.5017 6.55747L12.4983 5.44253L7.49828 9.94253L8.50172 11.0575Z" />
</svg>
);
}
22 changes: 22 additions & 0 deletions src/components/icons/Tick.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

export function Tick(props: React.SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
width="16"
height="16"
fill="none"
{...props}
>
<path
d="M3 7.75L6.75 11.5L13 4"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
40 changes: 40 additions & 0 deletions src/components/unstable/Select/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
| Property | Type | Default | Description |
| :------------------ | :-------------------------------------- | :-------------- | :----------------------------------------------------------------------------------------------------------- |
| onUpdate | `function` | `-` | Fires when an alteration to the Select value is committed by the user |
| renderOption | `function` | `-` | Used to render user options |
| getOptionHeight | `function` | `-` | Used to set height of customized user options. It needs in case of `options.length > 50` |
| [options](#options) | `(SelectOption \| SelectOptionGroup)[]` | `-` | Options to select |
| view | `string` | `'normal'` | Control [view](https://github.com/yandex-cloud/uikit/blob/main/src/components/TextInput/types.ts#L4) |
| size | `string` | `'m'` | Control/options [size](https://github.com/yandex-cloud/uikit/blob/main/src/components/TextInput/types.ts#L6) |
| pin | `string` | `'round-round'` | Control [border view](https://github.com/yandex-cloud/uikit/blob/main/src/components/TextInput/types.ts#L8) |
| width | `string \| number` | `undefined` | Control width |
| popupWidth | `number` | `-` | Popup width |
| name | `string` | `-` | Name of the control |
| className | `string` | `-` | Control className |
| label | `string` | `-` | Control label |
| placeholder | `string` | `-` | Placeholder text |
| value | `string[]` | `-` | Values that represent selected options |
| defaultValue | `string[]` | `-` | Default values that represent selected options in case of using uncontrolled state |
| multiple | `boolean` | `false` | Indicates that multiple options can be selected in the list |
| disabled | `boolean` | `false` | Indicates that the user cannot interact with the control |

---

#### Options

You can check `ControlGroupOption` [here](https://github.com/yandex-cloud/uikit/blob/main/src/components/types.ts#L29)

```typescript
type SelectOption = ControlGroupOption & {
text?: string;
data?: any;
};

type SelectOptionGroup = {
label: string;
options?: SelectOption[];
children?:
| React.ReactElement<SelectOption, typeof Option>
| React.ReactElement<SelectOption, typeof Option>[];
};
```
Loading

0 comments on commit 3b9246a

Please sign in to comment.