├── .babelrc
├── .gitignore
├── README.md
├── assets
└── sample.gif
├── build
└── index.js
├── demo
├── demo.js
└── index.html
├── package.json
├── src
├── components
│ ├── MenuItem.jsx
│ └── MenuSection.jsx
├── containers
│ └── QuickSelectMenu.jsx
└── react-qsm.css
├── webpack.config.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env", "react"],
3 | "plugins": ["transform-class-properties", "transform-object-rest-spread"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | public/bundle.js
3 | .vscode
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Quick-Select Menu
2 |
3 | Light-weight quick-select menu with fuzzy search. Inspired by the [vs-code command palette.](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette)
4 |
5 | 
6 |
7 | ## Table of Contents
8 |
9 | - [Usage](#usage)
10 | - [Installation](#installation)
11 | - [Props](#props)
12 | - [menuSection Properties](#menusection-properties)
13 | - [Styling](#styling)
14 | - [Future Plans](#future-plans)
15 |
16 | ## Usage
17 |
18 | The code below creates the demo you see above.
19 |
20 | ```javascript
21 | import React, { Component } from 'react';
22 | import ReactDOM from 'react-dom';
23 | import QuickSelectMenu from 'react-qsm';
24 | import './react-qsm.css';
25 |
26 | const sections = [
27 | {
28 | label: 'recently opened',
29 | items: [{ label: 'demo.js' }, { label: 'index.html' }]
30 | },
31 | {
32 | prefix: '>',
33 | label: 'recently used',
34 | items: [{ label: 'Preferences: Open User Settings' }, { label: 'Sync: Upload Settings' }]
35 | },
36 | {
37 | prefix: '>',
38 | label: 'other commands',
39 | items: [{ label: 'Add Cursor Above' }, { label: 'Add Cursor Below' }]
40 | },
41 | {
42 | prefix: '?',
43 | label: 'help',
44 | items: [{ label: '... Go to file' }, { label: '# Go to symbol in workspace' }]
45 | }
46 | ];
47 |
48 | const onMenuItemSelect = item => console.log(item);
49 |
50 | ReactDOM.render(
51 | ,
52 | document.getElementById('root')
53 | );
54 | ```
55 |
56 | ## Installation
57 |
58 | `yarn add react-qsm` or `npm install --save react-qsm`
59 |
60 | ## Props
61 |
62 | | Prop | Type | Required | default | Description |
63 | | :---------------- | :------------------- | :-------------------------: | :------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64 | | menuSections | _array[menuSection]_ | ✓ | | Array of menuSections. These contain all of the data for the menuItems as well. |
65 | | onMenuItemSelect | _function_ | | | Callback to fire when a menu item is selected. A menuItem will be passed into this callback as the only argument. |
66 | | onMenuItemFocus | _function_ | | | Callback to fire when a menu item is focused. A menuItem will be passed into this callback as the only argument. |
67 | | defaultValue | _string_ | | '' | Initial text value of the input. If provided, this would likely be a section prefix. |
68 | | maxItemsToDisplay | _number_ | | Infinity | Maximum number of items to display in the quick select menu at once . |
69 | | renderInput | _function_ | | | Custom input to render. If this prop is specified, you MUST also make use of the `value` prop(see below) and pass along the given props to the callback function of `renderInput` for react-qsm to function properly. IE: `renderInput={props => }` |
70 | | value | _string_ | if renderInput is specified | | The current value of the custom input supplied to renderInput. This should only be used when rendering a custom input. |
71 |
72 | | className | _string_ | | 'react-qsm' | Class name for the menu wrapper (div) |
73 | | inputClassName | _string_ | | 'qsm-input' | Class name for the menu input (input) |
74 | | menuSectionWrapperClassName | _string_ | | 'qsm-menu-sections-wrapper' | Class name for the menu sections wrapper (div) |
75 | | menuSectionClassName | _string_ | | 'qsm-menu-section' | Class name for a menu section (div) |
76 | | menuSectionLabelClassName | _string_ | | 'qsm-menu-section-label' | Class name for a menu label (h2) |
77 | | menuItemClassName | _string_ | | 'qsm-menu-item | Class name for a menu item (li) |
78 |
79 | ### menuSection Properties
80 |
81 | | Prop | Type | Required | Description |
82 | | :----- | :-------------- | :------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83 | | items | _array[object]_ | ✓ | Array of item objects, which will be passed to `onMenuItemSelect` when selected. The only required property in these objects is `label`, but you can put whatever you want in here (ie `id`). |
84 | | label | _string_ | | A label to display for your section. |
85 | | prefix | _string_ | | A prefix to match at the beginning of the input field in order to display this section. If a prefix for a section is provided, the input box **must** match the prefix to display this section. If a prefix is provided for _any_ section, sections without a prefix will not match when the input box matches the provided prefix. |
86 |
87 | ## Styling
88 |
89 | - There is a minimal and clean stylesheet to get you on your feet quickly located at react-qsm/src/react-qsm.css.
90 | - If you have questions on ways to import a stylesheet, consult the documentation of your build system.
91 |
92 | ## Future Plans
93 |
94 | - Ability to add components to both the left and right side of a menu item. This would allow things like icons to be displayed next to a label.
95 |
--------------------------------------------------------------------------------
/assets/sample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amorijs/react-qsm/77e68189ebae7e3f6b86ba9e9cbe9b5c327d5f15/assets/sample.gif
--------------------------------------------------------------------------------
/demo/demo.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import ReactDOM from 'react-dom';
3 | import QuickSelectMenu from '../src/containers/QuickSelectMenu.jsx';
4 | import '../src/react-qsm.css';
5 |
6 | const sections = [
7 | {
8 | label: 'recently opened',
9 | items: [{ label: 'demo.js' }, { label: 'index.html' }]
10 | },
11 | {
12 | prefix: '>',
13 | label: 'recently used',
14 | items: [{ label: 'Preferences: Open User Settings' }, { label: 'Sync: Upload Settings' }]
15 | },
16 | {
17 | prefix: '>',
18 | label: 'other commands',
19 | items: [{ label: 'Add Cursor Above' }, { label: 'Add Cursor Below' }]
20 | },
21 | {
22 | prefix: '?',
23 | label: 'help',
24 | items: [{ label: '... Go to file' }, { label: '# Go to symbol in workspace' }]
25 | }
26 | ];
27 |
28 | const onMenuItemSelect = item => console.log(item);
29 |
30 | ReactDOM.render(
31 | ,
37 | document.getElementById('root')
38 | );
39 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |