@teambit/explorer.ui.command-bar
Advanced tools
Comparing version 1.2.0 to 2.0.0
/// <reference types="react" /> | ||
export declare function Preview(): JSX.Element; | ||
export declare function AsyncSearch(): JSX.Element; | ||
export declare function MixedResults(): JSX.Element; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Preview = void 0; | ||
const react_1 = __importDefault(require("react")); | ||
exports.MixedResults = exports.AsyncSearch = exports.Preview = void 0; | ||
const react_1 = __importStar(require("react")); | ||
const command_bar_1 = require("./command-bar"); | ||
function search() { | ||
return [ | ||
{ id: '1', children: 'hello', action: () => { } }, | ||
{ id: '2', children: 'world', action: () => { } }, | ||
{ id: '3', children: 'what', action: () => { } }, | ||
{ id: '4', children: 'is', action: () => { } }, | ||
{ id: '5', children: 'up', action: () => { } }, | ||
]; | ||
const use_searcher_1 = require("./command-bar/use-searcher"); | ||
var run = 0; | ||
function delay() { | ||
return new Promise((resolve) => setTimeout(resolve, 300 + Math.random() * 1000)); | ||
} | ||
function delayedSearch(term, limit) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield delay(); | ||
return search(term, limit); | ||
}); | ||
} | ||
function search(term, limit) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return term | ||
.slice(0, limit) | ||
.split('') | ||
.map((char, idx) => { | ||
const text = char + Math.round(Math.random() * 100).toString(); | ||
return { | ||
id: `${++run}_${idx}`, | ||
children: text, | ||
action: () => { | ||
console.log('[cmd-bar] action:', text); | ||
}, | ||
}; | ||
}); | ||
}); | ||
} | ||
function Preview() { | ||
return react_1.default.createElement(command_bar_1.CommandBar, { style: { fontFamily: 'sans-serif', margin: 40, fontSize: 20 }, searcher: search, visible: true }); | ||
const results = (0, use_searcher_1.useSearcher)(search); | ||
return react_1.default.createElement(command_bar_1.CommandBar, Object.assign({ style: { fontFamily: 'sans-serif', margin: 40, fontSize: 20 } }, results, { visible: true })); | ||
} | ||
exports.Preview = Preview; | ||
function AsyncSearch() { | ||
const results = (0, use_searcher_1.useSearcher)(delayedSearch); | ||
return react_1.default.createElement(command_bar_1.CommandBar, Object.assign({ style: { fontFamily: 'sans-serif', margin: 40, fontSize: 20 } }, results, { visible: true })); | ||
} | ||
exports.AsyncSearch = AsyncSearch; | ||
function MixedResults() { | ||
const [value, setValue] = (0, react_1.useState)(''); | ||
const results1 = (0, use_searcher_1.useSearcher)(search, { value }); | ||
const results2 = (0, use_searcher_1.useSearcher)(delayedSearch, { value }); | ||
return (react_1.default.createElement(command_bar_1.CommandBar, { style: { fontFamily: 'sans-serif', margin: 40, fontSize: 20 }, items: [...results1.items, ...results2.items], loading: results1.loading || results2.loading, value: value, onChange: setValue, visible: true })); | ||
} | ||
exports.MixedResults = MixedResults; | ||
//# sourceMappingURL=command-bar.compositions.js.map |
@@ -11,3 +11,3 @@ "use strict"; | ||
it('should focus when autofocused', () => { | ||
const { getByPlaceholderText } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, placeholder: "test target", searcher: MockSearcher })); | ||
const { getByPlaceholderText } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, placeholder: "test target", items: [] })); | ||
const focusedElement = document.activeElement; | ||
@@ -18,3 +18,3 @@ const target = getByPlaceholderText('test target'); | ||
it('should not focus when no autofocused', () => { | ||
const { getByPlaceholderText } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { placeholder: "test target", searcher: MockSearcher })); | ||
const { getByPlaceholderText } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { placeholder: "test target", items: [] })); | ||
const focusedElement = document.activeElement; | ||
@@ -25,13 +25,13 @@ const target = getByPlaceholderText('test target'); | ||
it('should focus when component becomes visible, when auto focus is enabled', () => { | ||
const { getByPlaceholderText, rerender } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: false, placeholder: "test target", searcher: MockSearcher })); | ||
const { getByPlaceholderText, rerender } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: false, placeholder: "test target", items: [] })); | ||
// sanity | ||
expect(document.activeElement).not.toHaveProperty('placeholder', 'test target'); | ||
rerender(react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: true, placeholder: "test target", searcher: MockSearcher })); | ||
rerender(react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: true, placeholder: "test target", items: [] })); | ||
expect(document.activeElement).toBe(getByPlaceholderText('test target')); | ||
}); | ||
it('should not focus when component becomes visible, when auto focus is disabled', () => { | ||
const { getByPlaceholderText, rerender } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { visible: false, placeholder: "test target", searcher: MockSearcher })); | ||
const { getByPlaceholderText, rerender } = (0, react_2.render)(react_1.default.createElement(command_bar_1.CommandBar, { visible: false, placeholder: "test target", items: [] })); | ||
// sanity | ||
expect(document.activeElement).not.toHaveProperty('placeholder', 'test target'); | ||
rerender(react_1.default.createElement(command_bar_1.CommandBar, { visible: true, placeholder: "test target", searcher: MockSearcher })); | ||
rerender(react_1.default.createElement(command_bar_1.CommandBar, { visible: true, placeholder: "test target", items: [] })); | ||
expect(document.activeElement).not.toBe(getByPlaceholderText('test target')); | ||
@@ -42,3 +42,3 @@ }); | ||
const { getByPlaceholderText, rerender } = (0, react_2.render)(react_1.default.createElement(react_1.default.Fragment, null, | ||
react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, placeholder: "test target", searcher: MockSearcher }), | ||
react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, placeholder: "test target", items: [] }), | ||
react_1.default.createElement("input", { placeholder: "another element" }))); | ||
@@ -49,3 +49,3 @@ // ensure something else is focused | ||
rerender(react_1.default.createElement(react_1.default.Fragment, null, | ||
react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: false, placeholder: "test target", searcher: MockSearcher }), | ||
react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: false, placeholder: "test target", items: [] }), | ||
react_1.default.createElement("input", { placeholder: "another element" }))); | ||
@@ -56,3 +56,3 @@ // sanity | ||
rerender(react_1.default.createElement(react_1.default.Fragment, null, | ||
react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: true, placeholder: "test target", searcher: MockSearcher }), | ||
react_1.default.createElement(command_bar_1.CommandBar, { autofocus: true, visible: true, placeholder: "test target", items: [] }), | ||
react_1.default.createElement("input", { placeholder: "another element" }))); | ||
@@ -62,5 +62,9 @@ expect(getByPlaceholderText('test target')).toBe(document.activeElement); | ||
}); | ||
function MockSearcher() { | ||
return []; | ||
} | ||
// function MockedCommandBar(props: Partial<CommandBarProps>) { | ||
// const results = useSearcher(MockSearcher); | ||
// return <CommandBar {...results} {...props} />; | ||
// } | ||
// function MockSearcher() { | ||
// return []; | ||
// } | ||
//# sourceMappingURL=command-bar.spec.js.map |
/// <reference types="react" /> | ||
import { CardProps } from '@teambit/base-ui.surfaces.card'; | ||
import { SearchResult } from '../search-result'; | ||
export declare type Searcher = (term: string, limit: number) => SearchResult[] | Promise<SearchResult[]>; | ||
export declare type CommandBarProps = { | ||
searcher: (term: string, limit: number) => SearchResult[]; | ||
/** number of search results to show */ | ||
resultsLimit?: number; | ||
items: SearchResult[]; | ||
loading?: boolean; | ||
visible?: boolean; | ||
@@ -16,2 +16,2 @@ onVisibilityChange?: (nextVisible: boolean) => void; | ||
} & Omit<CardProps, 'defaultValue' | 'onChange'>; | ||
export declare function CommandBar({ elevation, className, visible, searcher, resultsLimit, onVisibilityChange: setVisibility, placeholder, value, defaultValue, onChange, autofocus, ...rest }: CommandBarProps): JSX.Element; | ||
export declare function CommandBar({ elevation, className, visible, items, loading, onVisibilityChange: setVisibility, placeholder, value, defaultValue, onChange, autofocus, ...rest }: CommandBarProps): JSX.Element; |
@@ -39,17 +39,18 @@ "use strict"; | ||
const classnames_1 = __importDefault(require("classnames")); | ||
const base_ui_surfaces_card_1 = require("@teambit/base-ui.surfaces.card"); | ||
const previous_1 = __importDefault(require("@react-hook/previous")); | ||
const use_optionally_controlled_state_1 = __importDefault(require("use-optionally-controlled-state")); | ||
const base_ui_surfaces_card_1 = require("@teambit/base-ui.surfaces.card"); | ||
const autocomplete_input_1 = require("../autocomplete-input"); | ||
const command_bar_item_1 = require("../command-bar-item"); | ||
const command_bar_module_scss_1 = __importDefault(require("./command-bar.module.scss")); | ||
const _1d_nav_1 = require("./1d-nav"); | ||
function CommandBar(_a) { | ||
var { elevation, className, visible = true, searcher, resultsLimit = 5, onVisibilityChange: setVisibility, placeholder = 'Search anything', value, defaultValue = '', onChange, autofocus } = _a, rest = __rest(_a, ["elevation", "className", "visible", "searcher", "resultsLimit", "onVisibilityChange", "placeholder", "value", "defaultValue", "onChange", "autofocus"]); | ||
var { elevation, className, visible = true, items, loading, onVisibilityChange: setVisibility, placeholder = 'Search anything', value, defaultValue = '', onChange, autofocus } = _a, rest = __rest(_a, ["elevation", "className", "visible", "items", "loading", "onVisibilityChange", "placeholder", "value", "defaultValue", "onChange", "autofocus"]); | ||
const [term = '', setTerm] = (0, use_optionally_controlled_state_1.default)({ controlledValue: value, initialValue: defaultValue, onChange }); | ||
(0, react_1.useEffect)(() => setTerm(defaultValue), [visible]); // reset on visibility change | ||
const results = (0, react_1.useMemo)(() => searcher(term, resultsLimit), [term, searcher, resultsLimit]); | ||
const idxNav = use1dNav(results.length); | ||
(0, react_1.useEffect)(() => idxNav.reset(), [results]); // reset on results change | ||
const idxNav = (0, _1d_nav_1.useNav1D)(items.length); | ||
useAutoReset(items, idxNav); | ||
const handleEnter = () => { | ||
setVisibility === null || setVisibility === void 0 ? void 0 : setVisibility(false); | ||
const current = results[idxNav.activeIdx]; | ||
const current = items[idxNav.activeIdx]; | ||
current === null || current === void 0 ? void 0 : current.action(); | ||
@@ -65,6 +66,6 @@ }; | ||
react_1.default.createElement(autocomplete_input_1.AutoCompleteInput, { value: term, focus: autofocus ? visible : undefined, autoFocus: autofocus, keyHandlers: keyHandlers, className: command_bar_module_scss_1.default.input, placeholder: placeholder, onChange: (e) => setTerm(e.target.value), onBlur: () => setVisibility === null || setVisibility === void 0 ? void 0 : setVisibility(false) }), | ||
react_1.default.createElement("div", { className: command_bar_module_scss_1.default.results }, results.map((_a, idx) => { | ||
react_1.default.createElement("div", { className: (0, classnames_1.default)(command_bar_module_scss_1.default.results, loading && command_bar_module_scss_1.default.loading) }, items.map((_a, idx) => { | ||
var { action, id } = _a, result = __rest(_a, ["action", "id"]); | ||
return (react_1.default.createElement(command_bar_item_1.CommandBarItem, Object.assign({ key: id, active: idx === idxNav.activeIdx, | ||
// mouseDown happens before blur, which closes the command bar | ||
// execute action before blur, which closes the command bar | ||
onMouseDown: () => action() }, result))); | ||
@@ -74,15 +75,21 @@ })))); | ||
exports.CommandBar = CommandBar; | ||
const MIN_IDX = 0; | ||
function use1dNav(length, startIdx = 0) { | ||
const [activeIdx, setActive] = (0, react_1.useState)(startIdx); | ||
const increment = (0, react_1.useCallback)(() => setActive((x) => Math.min(x + 1, length - 1)), [length]); | ||
const decrement = (0, react_1.useCallback)(() => setActive((x) => Math.max(x - 1, MIN_IDX)), []); | ||
const reset = (0, react_1.useCallback)(() => setActive(startIdx), [startIdx]); | ||
return { | ||
activeIdx, | ||
increment, | ||
decrement, | ||
reset, | ||
}; | ||
function useAutoReset(items, idxNav) { | ||
const currentIdx = idxNav.activeIdx; | ||
const previousIdx = (0, previous_1.default)(currentIdx); | ||
const current = items[currentIdx]; | ||
const previous = (0, previous_1.default)(current); | ||
const previousExists = !!(previous === null || previous === void 0 ? void 0 : previous.id); | ||
const didIndexMove = currentIdx !== previousIdx; | ||
const newItemLocation = !didIndexMove && previousExists ? items.findIndex((item) => item.id === (previous === null || previous === void 0 ? void 0 : previous.id)) : undefined; | ||
const { reset } = idxNav; | ||
(0, react_1.useEffect)(() => { | ||
if (newItemLocation === undefined) | ||
return; | ||
if (newItemLocation == -1) { | ||
reset(); | ||
return; | ||
} | ||
reset(newItemLocation); | ||
}, [newItemLocation]); | ||
} | ||
//# sourceMappingURL=command-bar.js.map |
import Fuse from 'fuse.js'; | ||
import { SearchResult } from './search-result'; | ||
declare type SearcherOptions = { | ||
declare type SearcherOptions<IndexedItem = any> = { | ||
/** properties to include in fuzzy search */ | ||
searchKeys: Fuse.FuseOptionKey[]; | ||
searchKeys: Fuse.FuseOptionKey<IndexedItem>[]; | ||
}; | ||
@@ -7,0 +7,0 @@ export declare type FuzzySearchItem<T> = Fuse.FuseResult<T>; |
{ | ||
"name": "@teambit/explorer.ui.command-bar", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"homepage": "https://bit.dev/teambit/explorer/ui/command-bar", | ||
@@ -9,9 +9,11 @@ "main": "dist/index.js", | ||
"name": "ui/command-bar", | ||
"version": "1.2.0" | ||
"version": "2.0.0" | ||
}, | ||
"dependencies": { | ||
"fuse.js": "6.5.3", | ||
"memoize-one": "6.0.0", | ||
"classnames": "2.3.1", | ||
"use-optionally-controlled-state": "1.1.0", | ||
"fuse.js": "^6.5.3", | ||
"memoize-one": "^6.0.0", | ||
"classnames": "^2.3.1", | ||
"@react-hook/previous": "1.0.1", | ||
"use-optionally-controlled-state": "^1.1.0", | ||
"use-debounce": "^8.0.1", | ||
"core-js": "^3.0.0", | ||
@@ -23,2 +25,3 @@ "@teambit/ui-foundation.ui.constants.z-indexes": "0.0.487", | ||
"devDependencies": { | ||
"@types/react": "^17.0.8", | ||
"@testing-library/react": "^12.1.5", | ||
@@ -29,7 +32,5 @@ "@types/testing-library__jest-dom": "5.9.5", | ||
"@types/react-dom": "^17.0.5", | ||
"@types/react": "^17.0.8", | ||
"@types/node": "12.20.4" | ||
}, | ||
"peerDependencies": { | ||
"@types/react": "17.0.0", | ||
"react-dom": "^16.8.0 || ^17.0.0", | ||
@@ -39,28 +40,2 @@ "react": "^16.8.0 || ^17.0.0" | ||
"license": "Apache-2.0", | ||
"bit": { | ||
"bindingPrefix": "@teambit", | ||
"env": {}, | ||
"overrides": { | ||
"dependencies": { | ||
"core-js": "^3.0.0", | ||
"react-dom": "-", | ||
"react": "-" | ||
}, | ||
"devDependencies": { | ||
"@types/testing-library__jest-dom": "5.9.5", | ||
"@babel/runtime": "7.12.18", | ||
"@types/jest": "^26.0.0", | ||
"@types/react-dom": "^17.0.5", | ||
"@types/react": "^17.0.8", | ||
"@types/node": "12.20.4", | ||
"@types/mocha": "-", | ||
"react-dom": "-", | ||
"react": "-" | ||
}, | ||
"peerDependencies": { | ||
"react-dom": "^16.8.0 || ^17.0.0", | ||
"react": "^16.8.0 || ^17.0.0" | ||
} | ||
} | ||
}, | ||
"private": false, | ||
@@ -67,0 +42,0 @@ "repository": { |
@@ -5,5 +5,5 @@ import Fuse from 'fuse.js'; | ||
type SearcherOptions = { | ||
type SearcherOptions<IndexedItem = any> = { | ||
/** properties to include in fuzzy search */ | ||
searchKeys: Fuse.FuseOptionKey[]; | ||
searchKeys: Fuse.FuseOptionKey<IndexedItem>[]; | ||
}; | ||
@@ -10,0 +10,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
93025
75
1143
12
+ Added@react-hook/previous@1.0.1
+ Addeduse-debounce@^8.0.1
+ Added@react-hook/previous@1.0.1(transitive)
+ Addedclassnames@2.5.1(transitive)
+ Addedfuse.js@6.6.2(transitive)
+ Addeduse-debounce@8.0.4(transitive)
+ Addeduse-optionally-controlled-state@1.2.0(transitive)
- Removed@types/prop-types@15.7.14(transitive)
- Removed@types/react@17.0.0(transitive)
- Removedclassnames@2.3.1(transitive)
- Removedcsstype@3.1.3(transitive)
- Removedfuse.js@6.5.3(transitive)
- Removeduse-optionally-controlled-state@1.1.0(transitive)
Updatedclassnames@^2.3.1
Updatedfuse.js@^6.5.3
Updatedmemoize-one@^6.0.0