UNPKG

@payfit/unity-components

Version:

255 lines (254 loc) 9.09 kB
import { Icon as e } from "../icon/Icon.js"; import { Spinner as t } from "../spinner/Spinner.js"; import { CircularIconButton as n } from "../icon-button/CircularIconButton.js"; import { Badge as r } from "../badge/Badge.js"; import { Search as ee } from "../search/Search.js"; import { reactAriaValueToSet as i, setToReactAriaDefaultValue as te, setToReactAriaValue as ne } from "./utils/selection-adapter.js"; import { MultiSelectContext as re } from "./Multiselect.context.js"; import { forwardRef as a, useCallback as o, useMemo as s, useRef as c, useState as l } from "react"; import { uyTv as u } from "@payfit/unity-themes"; import { jsx as d, jsxs as f } from "react/jsx-runtime"; import { useIntl as ie } from "react-intl"; import { Button as ae, ButtonContext as oe } from "react-aria-components/Button"; import { Separator as se } from "react-aria-components/Separator"; import { ListBox as p } from "react-aria-components/ListBox"; import { Popover as ce } from "react-aria-components/Popover"; import { Autocomplete as le, useFilter as ue } from "react-aria-components/Autocomplete"; import { Select as de } from "react-aria-components/Select"; //#region src/components/multi-select/MultiSelect.tsx var fe = u({ slots: { root: "uy:relative uy:flex uy:flex-col uy:gap-100 uy:w-full", trigger: "uy:relative uy:h-5.5 uy:sm:h-500 uy:flex uy:items-center uy:justify-between uy:py-125 uy:sm:py-100 uy:px-150 uy:w-full uy:border uy:border-solid uy:rounded-100 uy:sm:rounded-75 uy:focus-visible:outline-none uy:focus-visible:ring-2 uy:focus-visible:ring-utility-focus-ring uy:focus-visible:ring-offset-2 uy:active:not([disabled]):border-border-form-active uy:pointer-events-auto!", inputValue: "uy:flex-1 uy:typography-body uy:text-left uy:line-clamp-1", state: "uy:grow-0 uy:outline-none uy:typography-body uy:placeholder:text-content-neutral-lowest uy:inline-flex uy:gap-50 uy:items-center uy:px-100", suffix: "uy:text-content-neutral-lowest", clearButton: "uy:absolute uy:right-[36px] uy:top-1/2 uy:z-10 uy:-translate-y-1/2", popover: "uy:shadow-300 uy:z-50 uy:w-(--trigger-width) uy:max-h-[min(var(--popover-available-height,300px),300px)] uy:rounded-100 uy:sm:rounded-75 uy:border uy:border-solid uy:border-border-neutral uy:bg-surface-neutral uy:overflow-y-auto uy:overflow-x-hidden uy:outline-none", list: "uy:p-100 uy:overflow-y-auto uy:overflow-x-hidden" }, variants: { isDisabled: { true: { trigger: "uy:bg-surface-form-disabled uy:cursor-not-allowed uy:border-border-form-disabled uy:text-content-form-disabled", inputValue: "uy:text-content-form-disabled!", state: "uy:text-content-form-disabled", suffix: "uy:text-content-form-disabled" } }, isReadOnly: { true: { trigger: "uy:bg-surface-form-disabled uy:cursor-not-allowed uy:border-border-form-disabled", inputValue: "uy:text-content-form-disabled", state: "uy:text-content-form-disabled", suffix: "uy:text-content-form-disabled" } }, isInvalid: { true: { trigger: "uy:bg-surface-form-error uy:border-border-form-error", inputValue: "uy:text-content-form-error", state: "uy:text-content-form-error" } }, isEmpty: { true: { inputValue: "uy:text-content-neutral-lowest" }, false: { inputValue: "uy:text-content-form-enabled" } } }, compoundVariants: [{ isInvalid: !1, isDisabled: !1, isReadOnly: !1, className: { trigger: "uy:border-border-form-enabled uy:bg-surface-form-enabled", inputValue: "uy:text-content-form-enabled uy:bg-surface-form-enabled", state: "uy:text-content-neutral-disabled" } }, { isEmpty: !0, isDisabled: !1, isReadOnly: !1, isInvalid: !1, className: { inputValue: "uy:text-content-neutral-lowest" } }] }); function m(e) { return e instanceof Map; } function pe(e) { return !Object.prototype.hasOwnProperty.call(e, "items"); } function h(e) { return typeof e == "object" && e && "value" in e && (typeof e.value == "string" || typeof e.value == "number") ? e.value : typeof e == "object" && e && "id" in e && (typeof e.id == "string" || typeof e.id == "number") ? e.id : typeof e == "string" || typeof e == "number" ? e : String(e); } var g = (e) => Array.from(e).map(String).join(", "), _ = (e) => Array.from(e).map((e) => h(e)).join(", "); function v(a, u) { let v = ie(), y = c(null), me = c(null), [he, b] = l(!1), x = pe(a), S = a, C = a, { placeholder: w, isDisabled: T, isReadOnly: E, isLoading: D, isInvalid: O, onClearButtonPress: k, onBlur: ge, onFocus: _e, onChange: A, onOpenChange: j, value: M, defaultValue: N, isSearchable: P, renderValue: F, maxVisibleItems: I = 7, children: L, searchOptions: ve, ...ye } = a, [R, be] = l(() => new Set(N ?? [])), z = x ? void 0 : S.items, B = x ? void 0 : S.getItemValue, V = M !== void 0, H = s(() => V ? new Set(M) : R, [ V, M, R ]), U = F ?? (x ? g : _), W = o((e) => x || !B ? h(e) : B(e), [B, x]), G = o(() => x || !z ? [] : m(z) ? Array.from(z.values()).flat() : Array.from(z), [z, x]), xe = s(() => { if (x) return new Set(H); let e = G(), t = /* @__PURE__ */ new Set(); return H.forEach((n) => { let r = e.find((e) => W(e) === n); r && t.add(r); }), t; }, [ G, x, W, H ]), K = Array.from(xe), q = Math.max(K.length - I, 0), J = H.size > 0 && !T && !E && !D, { root: Se, trigger: Ce, inputValue: we, state: Te, suffix: Ee, clearButton: De, popover: Y, list: X } = fe({ isDisabled: !!T, isReadOnly: !!E, isInvalid: !!O, isEmpty: H.size === 0 }), Oe = s(() => { if (K.length === 0) return w; let e = K.slice(0, I); return U(new Set(e)); }, [ I, w, U, K ]), Z = o((e) => { V || be(e), A?.(e); }, [V, A]), ke = o((e) => { Z(i(e)); }, [Z]), Ae = o(() => { Z(/* @__PURE__ */ new Set()), k?.(); }, [k, Z]), je = o((e) => { b(e), j?.(e); }, [b, j]), Q = o(() => { if (x) return C.children; if (!z) return null; if (m(z)) { let e = z; return Array.from(e.entries()).map(([e, t]) => L(e, t)); } return Array.from(z).map((e) => L(e)); }, [ L, z, x, C.children ]), $ = s(() => Q(), [Q]), { contains: Me } = ue(ve ?? { sensitivity: "base" }); return /* @__PURE__ */ d(de, { ...ye, ref: y, className: Se(), isDisabled: T || E, isInvalid: O, onBlur: ge, onChange: ke, onFocus: _e, onOpenChange: je, placeholder: w, selectionMode: "multiple", shouldCloseOnSelect: !1, value: ne(H), defaultValue: te(N), allowsEmptyCollection: !0, children: /* @__PURE__ */ f(re.Provider, { value: { isSearchable: P, maxVisibleItems: I, selectedKeys: H }, children: [ /* @__PURE__ */ f(ae, { ref: u, className: Ce(), "data-dd-privacy": "mask", isDisabled: T || E, "aria-invalid": O, "aria-readonly": E, children: [ /* @__PURE__ */ d("span", { className: we(), translate: "no", children: H.size > 0 ? Oe : w }), /* @__PURE__ */ f("span", { className: Te(), children: [ D && /* @__PURE__ */ d(t, { color: "inherit", size: "small", label: v.formatMessage({ id: "unity:component:form-field:form-input:spinner:label", defaultMessage: "Loading" }) }), O && /* @__PURE__ */ d(e, { src: "WarningCircleOutlined", color: "content.form.invalid", alt: v.formatMessage({ id: "unity:component:form-field:form-input:error:alt", defaultMessage: "Error" }) }), q > 0 && /* @__PURE__ */ f(r, { variant: "numeric", children: ["+", q] }), J && /* @__PURE__ */ d("span", { className: "uy:w-300 uy:shrink-0", "aria-hidden": !0 }) ] }), /* @__PURE__ */ d(e, { className: Ee(), src: he ? "CaretUpOutlined" : "CaretDownOutlined", role: "presentation" }) ] }), J && /* @__PURE__ */ d(oe.Provider, { value: null, children: /* @__PURE__ */ d(n, { title: v.formatMessage({ id: "unity:component:common:clear:title", defaultMessage: "Clear" }), className: De(), icon: "CloseOutlined", onPress: Ae, asElement: "button" }) }), /* @__PURE__ */ d(ce, { ref: me, offset: 1, containerPadding: 8, className: Y(), children: P ? /* @__PURE__ */ f(le, { filter: Me, children: [ /* @__PURE__ */ d("div", { className: "uy:m-100", children: /* @__PURE__ */ d(ee, { label: v.formatMessage({ id: "unity:component:select:search:label", defaultMessage: "Search options" }), "data-dd-privacy": "mask" }) }), /* @__PURE__ */ d(se, { className: "uy:mx-100 uy:border-t uy:border-border-neutral uy:border-solid" }), /* @__PURE__ */ d(p, { className: X(), children: $ }) ] }) : /* @__PURE__ */ d(p, { className: X(), children: $ }) }) ] }) }); } var y = a(v); y.displayName = "MultiSelect"; //#endregion export { y as MultiSelect };