UNPKG

@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.

66 lines (65 loc) 5.8 kB
import React from 'react'; import { system } from '@workday/canvas-tokens-web'; import { caretDownSmallIcon, searchIcon } from '@workday/canvas-system-icons-web'; import { composeHooks, createElemPropsHook, createSubcomponent, } from '@workday/canvas-kit-react/common'; import { createStencil, handleCsProp } from '@workday/canvas-kit-styling'; import { InputGroup, TextInput } from '@workday/canvas-kit-react/text-input'; import { SystemIcon } from '@workday/canvas-kit-react/icon'; import { useComboboxInput, useComboboxInputConstrained } from '@workday/canvas-kit-react/combobox'; import { useMultiSelectModel } from './useMultiSelectModel'; import { MultiSelectedList } from './MultiSelectedList'; export const multiSelectStencil = createStencil({ base: { name: "xrlq26", styles: "box-sizing:border-box;border:1px solid var(--cnvs-sys-color-border-input-default);display:flex;flex-direction:column;background-color:var(--cnvs-sys-color-bg-default);border-radius:var(--cnvs-sys-shape-x1);min-height:var(--cnvs-sys-space-x10);transition:0.2s box-shadow, 0.2s border-color;margin:0;&:hover, &.hover{border-color:var(--cnvs-sys-color-border-input-strong);}&:focus-within{border-color:var(--cnvs-sys-color-border-primary-default);box-shadow:inset 0 0 0 1px var(--cnvs-sys-color-border-primary-default);}& [data-part=\"user-input\"]{font-family:var(--cnvs-sys-font-family-default);font-weight:var(--cnvs-sys-font-weight-normal);line-height:var(--cnvs-sys-line-height-subtext-large);font-size:var(--cnvs-sys-font-size-subtext-large);letter-spacing:var(--cnvs-base-letter-spacing-150);background-color:var(--cnvs-sys-color-bg-transparent);border-radius:var(--cnvs-sys-shape-x1);border:none !important;box-shadow:none !important;outline-width:0px;&:where(:not([aria-autocomplete])){caret-color:transparent;cursor:default;&::selection{background-color:transparent;}}}& :where([data-part=\"form-input\"]){position:absolute;top:var(--cnvs-sys-space-zero);bottom:var(--cnvs-sys-space-zero);left:var(--cnvs-sys-space-zero);right:var(--cnvs-sys-space-zero);opacity:var(--cnvs-sys-opacity-zero);cursor:default;pointer-events:none;}& :where([data-part=\"separator\"]){background-color:var(--cnvs-sys-color-border-divider);height:1px;margin:var(--cnvs-sys-space-zero) var(--cnvs-sys-space-x2);}& :where([data-part=\"list\"]){display:flex;gap:var(--cnvs-sys-space-x2);padding:var(--cnvs-sys-space-x2);flex-wrap:wrap;}" } }, "multi-select-5f5351"); export const useMultiSelectInput = composeHooks(createElemPropsHook(useMultiSelectModel)((model, ref) => { return { onKeyDown(event) { // Space bar key is hit and menu is open if (event.key === ' ' && model.state.visibility === 'visible') { const id = model.state.cursorId; // There are 2 modes. Search mode and navigation mode. Searching clears the cursor. Using // the down arrow enables the cursor and thus navigation mode. // - Navigation mode: toggle cursor item // - Search mode: enter a space in the search if (id) { model.events.select({ id }); event.preventDefault(); } } if ((event.key === 'ArrowDown' || event.key === 'ArrowUp') && model.state.visibility === 'hidden') { // prevent navigating vertically on the input model.events.show(event); event.preventDefault(); } }, }; }), useComboboxInputConstrained, useComboboxInput); export const MultiSelectInput = createSubcomponent(TextInput)({ modelHook: useMultiSelectModel, elemPropsHook: useMultiSelectInput, })(({ className, cs, style, 'aria-labelledby': ariaLabelledBy, removeLabel, formInputProps, ...elemProps }, Element, model) => { return (React.createElement("div", { ...handleCsProp({ className, cs, style }, multiSelectStencil({})) }, React.createElement(InputGroup, null, React.createElement(InputGroup.Input, { "data-part": "form-input", ...formInputProps }), React.createElement(InputGroup.Input, { "data-part": "user-input", as: Element, "aria-labelledby": ariaLabelledBy, readOnly: true, ...elemProps }), React.createElement(InputGroup.InnerEnd, { pointerEvents: "none" }, React.createElement(SystemIcon, { icon: caretDownSmallIcon }))), React.createElement(MultiSelectedList, { removeLabel: removeLabel }))); }); export const MultiSelectSearchInput = createSubcomponent(TextInput)({ modelHook: useMultiSelectModel, elemPropsHook: useMultiSelectInput, })(({ className, cs, style, 'aria-labelledby': ariaLabelledBy, removeLabel, formInputProps, ref, ...elemProps }, Element, model) => { return (React.createElement("div", { ...handleCsProp({ className, cs, style }, multiSelectStencil({})) }, React.createElement(InputGroup, null, React.createElement(InputGroup.InnerStart, { pointerEvents: "none", width: system.space.x8 }, React.createElement(SystemIcon, { icon: searchIcon, size: system.space.x4 })), React.createElement(InputGroup.Input, { "data-part": "form-input", placeholder: null, ...formInputProps }), React.createElement(InputGroup.Input, { "data-part": "user-input", as: Element, "aria-labelledby": ariaLabelledBy, ...elemProps }), React.createElement(InputGroup.InnerEnd, { width: system.space.x4 }, React.createElement(InputGroup.ClearButton, null)), React.createElement(InputGroup.InnerEnd, { pointerEvents: "none" }, React.createElement(SystemIcon, { icon: caretDownSmallIcon }))), React.createElement(MultiSelectedList, { removeLabel: removeLabel }))); });