@workday/canvas-kit-preview-react
Version:
Canvas Kit Preview is made up of components that have the full design and a11y review, are part of the DS ecosystem and are approved for use in product. The API's could be subject to change, but not without strong communication and migration strategies.
84 lines (83 loc) • 3.51 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useMultiSelectModel = void 0;
const react_1 = __importDefault(require("react"));
const common_1 = require("@workday/canvas-kit-react/common");
const combobox_1 = require("@workday/canvas-kit-react/combobox");
const collection_1 = require("@workday/canvas-kit-react/collection");
/**
* `MultiSelectModel` extends the {@link ComboboxModel}. Selecting items from
* the menu will dispatch an
* [input](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event) event on the
* input which should work with form libraries, automation and autofill.
*
* ```tsx
* const model = useMultiSelectModel({items: ['Mobile', 'Phone', 'E-Mail']})
*
* <MultiSelect model={model}>
* ...
* </MultiSelect>
* ```
*/
exports.useMultiSelectModel = (0, common_1.createModelHook)({
defaultConfig: {
...combobox_1.useComboboxModel.defaultConfig,
mode: 'multiple',
shouldVirtualize: false,
},
requiredConfig: {
...combobox_1.useComboboxModel.requiredConfig,
},
contextOverride: combobox_1.useComboboxModel.Context,
})(config => {
const cachedSelectedRef = react_1.default.useRef([]);
const model = (0, combobox_1.useComboboxModel)(combobox_1.useComboboxModel.mergeConfig(config, {
onHide() {
setSelectedItems(cachedSelected);
model.events.goTo({ id: '' });
},
onFilterChange() {
model.events.goTo({ id: '' });
},
}));
const [selectedItems, setSelectedItems] = react_1.default.useState(() => {
return (config.initialSelectedIds === 'all' ? [] : config.initialSelectedIds)
.map(id => model.navigation.getItem(id, model))
.filter(item => item);
});
const cachedSelected = react_1.default.useMemo(() => (model.state.selectedIds === 'all' ? [] : model.state.selectedIds)
// try to find the item in the navigation. If it isn't there, maybe it is filtered out currently and we can find it from previous cached
.map(id => model.navigation.getItem(id, model) || cachedSelectedRef.current.find(i => i.id === id))
.filter(item => item),
// eslint-disable-next-line react-hooks/exhaustive-deps
[model.state.selectedIds]);
cachedSelectedRef.current = cachedSelected;
// The `listbox` of pills under the MultiSelect combobox input.
const selected = (0, collection_1.useListModel)({
orientation: 'horizontal',
onRemove({ id }) {
model.events.select({ id });
setSelectedItems(cachedSelected.filter(item => item.id !== id));
},
shouldVirtualize: false,
items: model.state.visibility === 'hidden' ? cachedSelected : selectedItems,
});
return {
selected: {
...selected,
state: {
...selected.state,
cursorId: react_1.default.useMemo(() => {
var _a;
return selected.state.items.find(item => item.id === selected.state.cursorId)
? selected.state.cursorId
: ((_a = selected.state.items[0]) === null || _a === void 0 ? void 0 : _a.id) || '';
}, [selected.state.items, selected.state.cursorId]),
},
},
...model,
};
});
;