UNPKG

@kwiz/fluentui

Version:
94 lines 4.39 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { Dropdown, makeStyles, mergeClasses, Option } from '@fluentui/react-components'; import { CommonLogger, filterEmptyEntries, firstOrNull, isNotEmptyArray, isNotEmptyString, isNullOrUndefined } from '@kwiz/common'; import React, { useMemo, useState } from 'react'; import { useKWIZFluentContext } from '../helpers/context-internal'; import { useControlledStateTracker } from '../helpers/use-controlled-state-tracker'; const logger = new CommonLogger("DropdownEX"); const useStyles = makeStyles({ root: { minWidth: "auto" }, filter: { position: "absolute", zIndex: 1, top: "-8px", right: 0 } }); function cleanupValue(value) { //netsuite sometimes puts   in option values for padding return value.replace(/ /g, ' '); } function $DropdownEX(props, ref) { const classes = useStyles(); const ctx = useKWIZFluentContext(); const { valueToUse, setValue } = useControlledStateTracker({ name: "DropdownEX", value: props.selected, defaultValue: props.defaultSelected }); //normalized as array const selected = Array.isArray(valueToUse) ? valueToUse : isNullOrUndefined(valueToUse) ? [] : [valueToUse]; //sometimes control will lose value when re-rendered //use case: public forms when editing other fields after the dropdown was set //re-set the text value manually to fix let text = useMemo(() => { return filterEmptyEntries(selected.map(s => { let v = firstOrNull(props.items, i => i.key === s); return v ? cleanupValue(v.value) : ''; })).join(', '); }, [selected, props.items]); const [filter, setFilter] = useState(""); const items = useMemo(() => { const itms = props.items; if (isNotEmptyArray(itms)) { if (isNotEmptyString(filter)) return itms.filter(i => i.value.toLowerCase().includes(filter)); } return itms; }, [props.items, filter]); const itemOptions = useMemo(() => { return items.map(i => { let valueAsText = cleanupValue(i.value); let padding = 0; //replace any space or   at start of valueAsText with padding. while (valueAsText.startsWith(' ')) { padding++; valueAsText = valueAsText.slice(1); } return _jsx(Option, { value: i.key, text: valueAsText, children: i.option ? i.option : _jsxs(_Fragment, { children: [padding > 0 ? _jsx("span", { style: { minWidth: `${4 * padding}px` } }) : undefined, valueAsText] }) }, i.key); }); }, [items]); return (_jsx(Dropdown, Object.assign({}, props, { onSelect: undefined, className: mergeClasses(classes.root, props.className), ref: ref, clearable: !props.required && !props.multiselect, appearance: ctx.inputAppearance, mountNode: ctx.mountNode, //clear filter every time we open the dropdown onOpenChange: () => { if (isNotEmptyString(filter)) setFilter(""); }, onKeyDown: (e) => { if (e.key.match(/^[a-z0-9]$/i)) { e.defaultPrevented = true; setFilter(`${filter}${e.key}`.toLowerCase()); } else if (e.key === "Backspace") { setFilter(filter.slice(0, filter.length - 1)); } }, selectedOptions: selected, value: text, onOptionSelect: (e, data) => { let o = firstOrNull(props.items, i => i.key === data.optionValue); if (props.multiselect) { let current = data.selectedOptions.map(s => firstOrNull(props.items, i => i.key === s)); setValue(current.map(o => o.key)); props.onSelect(o, current); } else { setValue(o === null || o === void 0 ? void 0 : o.key); props.onSelect(o); } }, children: itemOptions }))); } export const DropdownEX = React.forwardRef($DropdownEX); /** @deprecated use normal DropdownEX it is now generic */ export function getDropdownEX() { logger.i.warn('getDropdownEX is deprecated. use DropdownEX it now supports generic types'); return React.forwardRef(($DropdownEX)); } //# sourceMappingURL=dropdown.js.map