Skip to content

Commit

Permalink
📝 added disabled prop in documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
harshzalavadiya committed May 11, 2020
1 parent f495519 commit cc3dc95
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 49 deletions.
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const Example: React.FC = () => {
const options = [
{ label: "Grapes 🍇", value: "grapes" },
{ label: "Mango 🥭", value: "mango" },
{ label: "Strawberry 🍓", value: "strawberry" },
{ label: "Strawberry 🍓", value: "strawberry", disabled: true },
];

const [selected, setSelected] = useState([]);
Expand All @@ -56,22 +56,22 @@ export default Example;

## 👀 Props

| Prop | Description | Type | Default |
| --------------------- | ---------------------------------- | ------------------ | -------------- |
| `labelledBy` | value for `aria-labelledby` | `string` | |
| `options` | options for dropdown | `[{label, value}]` | |
| `value` | pre-selected rows | `[{label, value}]` | `[]` |
| `focusSearchOnOpen` | focus on search input when opening | `boolean` | `true` |
| `hasSelectAll` | toggle 'Select All' option | `boolean` | `true` |
| `isLoading` | show spinner on select | `boolean` | `false` |
| `shouldToggleOnHover` | toggle dropdown on hover option | `boolean` | `false` |
| `overrideStrings` | Override default strings for i18n | `object` | |
| `onChange` | onChange callback | `function` | |
| `disabled` | disable dropdown | `boolean` | `false` |
| `selectAllLabel` | _select all_ label | `string` | |
| `disableSearch` | hide search textbox | `boolean` | `false` |
| `filterOptions` | custom filter options | `function` | Fuzzy Search |
| `className` | class name for parent component | `string` | `multi-select` |
| Prop | Description | Type | Default |
| --------------------- | ---------------------------------- | ---------------------------- | -------------- |
| `labelledBy` | value for `aria-labelledby` | `string` | |
| `options` | options for dropdown | `[{label, value, disabled}]` | |
| `value` | pre-selected rows | `[{label, value}]` | `[]` |
| `focusSearchOnOpen` | focus on search input when opening | `boolean` | `true` |
| `hasSelectAll` | toggle 'Select All' option | `boolean` | `true` |
| `isLoading` | show spinner on select | `boolean` | `false` |
| `shouldToggleOnHover` | toggle dropdown on hover option | `boolean` | `false` |
| `overrideStrings` | Override default strings for i18n | `object` | |
| `onChange` | onChange callback | `function` | |
| `disabled` | disable dropdown | `boolean` | `false` |
| `selectAllLabel` | _select all_ label | `string` | |
| `disableSearch` | hide search textbox | `boolean` | `false` |
| `filterOptions` | custom filter options | `function` | Fuzzy Search |
| `className` | class name for parent component | `string` | `multi-select` |

### 🔍 Custom filter logic

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"lint": "tsdx lint",
"prepare": "tsdx build && filesize",
"storybook": "start-storybook -p 6006",
"format": "prettier --write src/**/*",
"build-storybook": "build-storybook"
},
"peerDependencies": {
Expand All @@ -41,6 +42,7 @@
"@types/react-dom": "^16.9.7",
"babel-loader": "^8.1.0",
"husky": "^4.2.5",
"prettier": "^2.0.5",
"react": "^16.13.1",
"react-docgen-typescript-loader": "^3.7.2",
"react-dom": "^16.13.1",
Expand Down
6 changes: 3 additions & 3 deletions src/lib/fuzzy-match-utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function filterOptions(
.filter(({ label, value }) => label != null && value != null)
// Create a {score, Option} pair for each Option based on its label's
// similarity to the filter text.
.map(option => ({
.map((option) => ({
option: option,
score: typeaheadSimilarity(
cleanUpText(option.label, substitutions),
Expand All @@ -46,11 +46,11 @@ export function filterOptions(
}))
// Only include matches of the entire substring, with a slight
// affordance for transposition or extra characters.
.filter(pair => pair.score >= cleanFilter.length - 2)
.filter((pair) => pair.score >= cleanFilter.length - 2)
// Sort 'em by order of their score.
.sort((a, b) => b.score - a.score)
// …and grab the original Options back from their pairs.
.map(pair => pair.option)
.map((pair) => pair.option)
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/multi-select/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const Dropdown = ({
onMenuToggle && onMenuToggle(expanded);
}, [expanded]);

const handleKeyDown = e => {
const handleKeyDown = (e) => {
switch (e.which) {
case 27: // Escape
case 38: // Up Arrow
Expand All @@ -108,7 +108,7 @@ const Dropdown = ({
const handleHover = (iexpanded: boolean) => {
shouldToggleOnHover && setExpanded(iexpanded);
};
const handleFocus = e => {
const handleFocus = (e) => {
e.target === wrapper && !hasFocus && setHasFocus(true);
};
const handleBlur = () => hasFocus && setHasFocus(false);
Expand Down
2 changes: 1 addition & 1 deletion src/multi-select/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const DropdownHeader = ({ value, options, valueRenderer, overrideStrings }) => {
const allSelected = value.length === options.length;
const customText = valueRenderer && valueRenderer(value, options);

const getSelectedText = () => value.map(s => s.label).join(", ");
const getSelectedText = () => value.map((s) => s.label).join(", ");

if (noneSelected) {
return (
Expand Down
39 changes: 25 additions & 14 deletions src/select-panel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Select-all item, and the list of options.
*/
import { css } from "goober";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";

import { filterOptions } from "../lib/fuzzy-match-utils";
import getString from "../lib/get-string";
Expand All @@ -28,7 +28,7 @@ interface ISelectPanelProps {

enum FocusType {
SEARCH = -1,
NONE,
NONE = 0,
}

const SelectSearchContainer = css({
Expand Down Expand Up @@ -62,32 +62,46 @@ export const SelectPanel = (props: ISelectPanelProps) => {
focusSearchOnOpen ? FocusType.SEARCH : FocusType.NONE
);

const [selectAllLength, setSelectAllLength] = useState(0);
const selectAllOption = {
label: selectAllLabel || getString("selectAll", overrideStrings),
value: "",
};

const selectAll = () => onChange(options);

const selectNone = () => onChange([]);
useEffect(() => {
setSelectAllLength(selectAllValues(true).length);
// eslint-disable-next-line
}, [options]);

const selectAllValues = (checked) => {
const selectedValues = value.map((o) => o.value);
return options.filter(({ disabled, value }) => {
if (checked) {
return !disabled || selectedValues.includes(value);
}
return disabled && selectedValues.includes(value);
});
};

const selectAllChanged = (checked: boolean) =>
checked ? selectAll() : selectNone();
const selectAllChanged = (checked: boolean) => {
const newOptions = selectAllValues(checked);
onChange(newOptions);
};

const handleSearchChange = e => {
const handleSearchChange = (e) => {
setSearchText(e.target.value);
setFocusIndex(FocusType.SEARCH);
};

const handleItemClicked = (index: number) => setFocusIndex(index);

const handleKeyDown = e => {
const handleKeyDown = (e) => {
switch (e.which) {
case 38: // Up Arrow
if (e.altKey) {
return;
}
updateFocus(FocusType.SEARCH);
updateFocus(-1);
break;
case 40: // Down Arrow
if (e.altKey) {
Expand All @@ -106,8 +120,6 @@ export const SelectPanel = (props: ISelectPanelProps) => {
setFocusIndex(FocusType.SEARCH);
};

const allAreSelected = () => options.length === value.length;

const filteredOptions = () =>
customFilterOptions
? customFilterOptions(options, searchText)
Expand All @@ -131,15 +143,14 @@ export const SelectPanel = (props: ISelectPanelProps) => {
aria-describedby={getString("search", overrideStrings)}
onChange={handleSearchChange}
onFocus={handleSearchFocus}
onBlur={handleSearchFocus}
/>
</div>
)}

{hasSelectAll && (
<SelectItem
focused={focusIndex === 0}
checked={allAreSelected()}
checked={selectAllLength === value.length}
option={selectAllOption}
onSelectionChanged={selectAllChanged}
onClick={() => handleItemClicked(0)}
Expand Down
10 changes: 5 additions & 5 deletions src/select-panel/select-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const ItemContainer = css({
display: "block",
padding: "var(--rmsc-spacing)",
outline: "0",
"&:hover": {
"&:hover,&:focus": {
background: "var(--rmsc-hover)",
},
"&.selected": {
Expand All @@ -45,24 +45,24 @@ const SelectItem = ({
useEffect(() => {
updateFocus();
// eslint-disable-next-line
}, []);
}, [focused]);

const toggleChecked = () => {
onSelectionChanged(!checked);
};

const handleClick = e => {
const handleClick = (e) => {
toggleChecked();
onClick(e);
};

const updateFocus = () => {
if (focused && itemRef) {
if (focused && !disabled && itemRef) {
itemRef.current.focus();
}
};

const handleKeyDown = e => {
const handleKeyDown = (e) => {
switch (e.which) {
case 13: // Enter
case 32: // Space
Expand Down
6 changes: 3 additions & 3 deletions src/select-panel/select-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ const SelectList = ({
<SelectItem
focused={focusIndex === i}
option={o}
onSelectionChanged={c => handleSelectionChanged(o, c)}
checked={value.find(s => s.value === o.value) ? true : false}
onClick={e => onClick(e, i)}
onSelectionChanged={(c) => handleSelectionChanged(o, c)}
checked={value.find((s) => s.value === o.value) ? true : false}
onClick={(e) => onClick(e, i)}
itemRenderer={ItemRenderer}
disabled={o.disabled || disabled}
/>
Expand Down
36 changes: 32 additions & 4 deletions stories/default.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
decorators: [withKnobs],
};

export const toStorybook = () => {
export const ExampleDefault = () => {
const options = [
{ label: "Grapes 🍇", value: "grapes" },
{ label: "Mango 🥭", value: "mango" },
Expand All @@ -30,14 +30,42 @@ export const toStorybook = () => {
value={selected}
disabled={boolean("disabled", false)}
onChange={setSelected}
onMenuToggle={(s)=>{console.log("Select Toggle: ", s)}}
onMenuToggle={s => {
console.log("Select Toggle: ", s);
}}
labelledBy={text("labelledBy", "Select Fruits")}
className={text("className", "multi-select")}
/>
</div>
);
};

toStorybook.story = {
name: "default",
ExampleDefault.story = {
name: "Default",
};

export const ExampleDisabled = () => {
const options = [
{ label: "Grapes 🍇", value: "grapes" },
{ label: "Mango 🥭", value: "mango", disabled: true },
{ label: "Strawberry 🍓", value: "strawberry" },
];

const [selected, setSelected] = useState([]);

return (
<div>
<pre>{JSON.stringify(selected)}</pre>
<MultiSelect
options={options}
value={selected}
onChange={setSelected}
labelledBy={text("labelledBy", "Select Fruits")}
/>
</div>
);
};

ExampleDisabled.story = {
name: "Disabled",
};
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9266,6 +9266,11 @@ prettier@^1.16.4, prettier@^1.19.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==

prettier@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4"
integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==

pretty-error@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
Expand Down

0 comments on commit cc3dc95

Please sign in to comment.