@homebound/beam 4.56.3 → 4.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +107 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +107 -107
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -8724,8 +8724,8 @@ type MenuSelectFieldBaseProps<O, V extends Value> = {
|
|
|
8724
8724
|
getOptionValue?: (opt: O) => V;
|
|
8725
8725
|
/** String used in the trigger and the option's accessible name. Defaults to `option.name`. */
|
|
8726
8726
|
getOptionLabel?: (opt: O) => string;
|
|
8727
|
-
/** Custom content for the menu row. Falls back to `getOptionLabel`. */
|
|
8728
|
-
getOptionMenuLabel?: (opt: O) => ReactNode;
|
|
8727
|
+
/** Custom content for the menu row. Falls back to `getOptionLabel`. `isUnsetOpt` is true for the `unsetLabel` row. */
|
|
8728
|
+
getOptionMenuLabel?: (opt: O, isUnsetOpt: boolean) => ReactNode;
|
|
8729
8729
|
/** Extra text the menu search matches, in addition to `getOptionLabel`. */
|
|
8730
8730
|
getOptionSearchText?: (opt: O) => string | readonly string[];
|
|
8731
8731
|
/** Sort options by `getOptionLabel`. On by default. `MenuTreeSelectField` defaults this to false. */
|
|
@@ -8756,6 +8756,8 @@ type MenuSelectFieldProps<O, V extends Value> = MenuSelectFieldBaseProps<O, V> &
|
|
|
8756
8756
|
/** Value proposed by an AI model; puts the field in AI mode. */
|
|
8757
8757
|
proposedValue?: V;
|
|
8758
8758
|
onSelect: (value: V | undefined, opt: O | undefined) => void;
|
|
8759
|
+
/** `unsetLabel` row that clears the field. Stays first when options are sorted. Unlike `nothingSelectedText`, it is a selectable option. */
|
|
8760
|
+
unsetLabel?: string;
|
|
8759
8761
|
};
|
|
8760
8762
|
/** Which selected options to surface: every one, only leaves, or only the highest selected ancestors. */
|
|
8761
8763
|
type TreeSelectionDisplay = "all" | "leaf" | "root";
|
package/dist/index.d.ts
CHANGED
|
@@ -8724,8 +8724,8 @@ type MenuSelectFieldBaseProps<O, V extends Value> = {
|
|
|
8724
8724
|
getOptionValue?: (opt: O) => V;
|
|
8725
8725
|
/** String used in the trigger and the option's accessible name. Defaults to `option.name`. */
|
|
8726
8726
|
getOptionLabel?: (opt: O) => string;
|
|
8727
|
-
/** Custom content for the menu row. Falls back to `getOptionLabel`. */
|
|
8728
|
-
getOptionMenuLabel?: (opt: O) => ReactNode;
|
|
8727
|
+
/** Custom content for the menu row. Falls back to `getOptionLabel`. `isUnsetOpt` is true for the `unsetLabel` row. */
|
|
8728
|
+
getOptionMenuLabel?: (opt: O, isUnsetOpt: boolean) => ReactNode;
|
|
8729
8729
|
/** Extra text the menu search matches, in addition to `getOptionLabel`. */
|
|
8730
8730
|
getOptionSearchText?: (opt: O) => string | readonly string[];
|
|
8731
8731
|
/** Sort options by `getOptionLabel`. On by default. `MenuTreeSelectField` defaults this to false. */
|
|
@@ -8756,6 +8756,8 @@ type MenuSelectFieldProps<O, V extends Value> = MenuSelectFieldBaseProps<O, V> &
|
|
|
8756
8756
|
/** Value proposed by an AI model; puts the field in AI mode. */
|
|
8757
8757
|
proposedValue?: V;
|
|
8758
8758
|
onSelect: (value: V | undefined, opt: O | undefined) => void;
|
|
8759
|
+
/** `unsetLabel` row that clears the field. Stays first when options are sorted. Unlike `nothingSelectedText`, it is a selectable option. */
|
|
8760
|
+
unsetLabel?: string;
|
|
8759
8761
|
};
|
|
8760
8762
|
/** Which selected options to surface: every one, only leaves, or only the highest selected ancestors. */
|
|
8761
8763
|
type TreeSelectionDisplay = "all" | "leaf" | "root";
|
package/dist/index.js
CHANGED
|
@@ -18647,6 +18647,89 @@ import { trussProps as trussProps76 } from "@homebound/truss/runtime";
|
|
|
18647
18647
|
// src/inputs/MenuSelectField/MenuSelectField.tsx
|
|
18648
18648
|
import { useMemo as useMemo29 } from "react";
|
|
18649
18649
|
|
|
18650
|
+
// src/inputs/Value.ts
|
|
18651
|
+
var VALUE_PREFIX = "__VALUE--";
|
|
18652
|
+
function keyToValue(key) {
|
|
18653
|
+
if (typeof key === "number") {
|
|
18654
|
+
return key;
|
|
18655
|
+
} else if (typeof key === "string") {
|
|
18656
|
+
if (key === `${VALUE_PREFIX}null` || key === "__VALUE:null") {
|
|
18657
|
+
return null;
|
|
18658
|
+
} else if (key === `${VALUE_PREFIX}undefined` || key === "__VALUE:undefined") {
|
|
18659
|
+
return void 0;
|
|
18660
|
+
} else if (key.startsWith(`${VALUE_PREFIX}boolean--`) || key.startsWith("__VALUE:boolean:")) {
|
|
18661
|
+
const parts = key.includes("--boolean--") ? key.split("--") : key.split(":");
|
|
18662
|
+
return parts[parts.length - 1] === "true";
|
|
18663
|
+
} else if (key.startsWith(`${VALUE_PREFIX}number--`) || key.startsWith("__VALUE:number:")) {
|
|
18664
|
+
const parts = key.includes("--number--") ? key.split("--") : key.split(":");
|
|
18665
|
+
return Number(parts[parts.length - 1]);
|
|
18666
|
+
} else {
|
|
18667
|
+
return key;
|
|
18668
|
+
}
|
|
18669
|
+
} else {
|
|
18670
|
+
throw new Error(`Unsupported key ${key}`);
|
|
18671
|
+
}
|
|
18672
|
+
}
|
|
18673
|
+
function valueToKey(value) {
|
|
18674
|
+
if (typeof value === "string") {
|
|
18675
|
+
return value;
|
|
18676
|
+
} else if (typeof value === "number") {
|
|
18677
|
+
return `${VALUE_PREFIX}number--${value}`;
|
|
18678
|
+
} else if (typeof value === "boolean") {
|
|
18679
|
+
return `${VALUE_PREFIX}boolean--${value}`;
|
|
18680
|
+
} else if (value === null) {
|
|
18681
|
+
return `${VALUE_PREFIX}null`;
|
|
18682
|
+
} else if (value === void 0) {
|
|
18683
|
+
return `${VALUE_PREFIX}undefined`;
|
|
18684
|
+
} else {
|
|
18685
|
+
throw new Error(`Unsupported value ${value}`);
|
|
18686
|
+
}
|
|
18687
|
+
}
|
|
18688
|
+
|
|
18689
|
+
// src/inputs/internal/selectFieldHelpers.ts
|
|
18690
|
+
function initializeOptions(optionsOrLoad, getOptionValue, getOptionLabel, unsetLabel, autoSort) {
|
|
18691
|
+
const result = [];
|
|
18692
|
+
if (unsetLabel) {
|
|
18693
|
+
result.push(unsetOption);
|
|
18694
|
+
}
|
|
18695
|
+
const userOptions = [];
|
|
18696
|
+
if (Array.isArray(optionsOrLoad)) {
|
|
18697
|
+
userOptions.push(...optionsOrLoad);
|
|
18698
|
+
} else {
|
|
18699
|
+
const { options, current: current2 } = optionsOrLoad;
|
|
18700
|
+
if (options) {
|
|
18701
|
+
userOptions.push(...options);
|
|
18702
|
+
}
|
|
18703
|
+
if (current2) {
|
|
18704
|
+
const toCheck = Array.isArray(current2) ? current2 : [current2];
|
|
18705
|
+
toCheck.forEach((current3) => {
|
|
18706
|
+
const value = getOptionValue(current3);
|
|
18707
|
+
const found = options && options.find((o) => getOptionValue(o) === value);
|
|
18708
|
+
if (!found) {
|
|
18709
|
+
userOptions.push(current3);
|
|
18710
|
+
}
|
|
18711
|
+
});
|
|
18712
|
+
}
|
|
18713
|
+
}
|
|
18714
|
+
result.push(...autoSort ? sortOptions(userOptions, getOptionLabel) : userOptions);
|
|
18715
|
+
return result;
|
|
18716
|
+
}
|
|
18717
|
+
var unsetOption = {};
|
|
18718
|
+
function disabledOptionToKeyedTuple(disabledOption) {
|
|
18719
|
+
if (typeof disabledOption === "object" && disabledOption !== null) {
|
|
18720
|
+
return [valueToKey(disabledOption.value), disabledOption.reason];
|
|
18721
|
+
} else {
|
|
18722
|
+
return [valueToKey(disabledOption), void 0];
|
|
18723
|
+
}
|
|
18724
|
+
}
|
|
18725
|
+
function sortOptions(options, getOptionLabel) {
|
|
18726
|
+
return [...options].sort((a, b) => {
|
|
18727
|
+
const labelA = getOptionLabel(a).toLowerCase();
|
|
18728
|
+
const labelB = getOptionLabel(b).toLowerCase();
|
|
18729
|
+
return labelA.localeCompare(labelB);
|
|
18730
|
+
});
|
|
18731
|
+
}
|
|
18732
|
+
|
|
18650
18733
|
// src/inputs/MenuSelectField/internal/AnchoredOverlay.tsx
|
|
18651
18734
|
import { useRef as useRef32 } from "react";
|
|
18652
18735
|
import { FocusScope as FocusScope4 } from "react-aria";
|
|
@@ -19646,89 +19729,6 @@ import { useId as useId4, useLayoutEffect as useLayoutEffect8, useMemo as useMem
|
|
|
19646
19729
|
import { ListKeyboardDelegate, useFilter as useFilter2, useFocusRing as useFocusRing10, useHover as useHover13 } from "react-aria";
|
|
19647
19730
|
import { Item as Item2, useListState } from "react-stately";
|
|
19648
19731
|
|
|
19649
|
-
// src/inputs/Value.ts
|
|
19650
|
-
var VALUE_PREFIX = "__VALUE--";
|
|
19651
|
-
function keyToValue(key) {
|
|
19652
|
-
if (typeof key === "number") {
|
|
19653
|
-
return key;
|
|
19654
|
-
} else if (typeof key === "string") {
|
|
19655
|
-
if (key === `${VALUE_PREFIX}null` || key === "__VALUE:null") {
|
|
19656
|
-
return null;
|
|
19657
|
-
} else if (key === `${VALUE_PREFIX}undefined` || key === "__VALUE:undefined") {
|
|
19658
|
-
return void 0;
|
|
19659
|
-
} else if (key.startsWith(`${VALUE_PREFIX}boolean--`) || key.startsWith("__VALUE:boolean:")) {
|
|
19660
|
-
const parts = key.includes("--boolean--") ? key.split("--") : key.split(":");
|
|
19661
|
-
return parts[parts.length - 1] === "true";
|
|
19662
|
-
} else if (key.startsWith(`${VALUE_PREFIX}number--`) || key.startsWith("__VALUE:number:")) {
|
|
19663
|
-
const parts = key.includes("--number--") ? key.split("--") : key.split(":");
|
|
19664
|
-
return Number(parts[parts.length - 1]);
|
|
19665
|
-
} else {
|
|
19666
|
-
return key;
|
|
19667
|
-
}
|
|
19668
|
-
} else {
|
|
19669
|
-
throw new Error(`Unsupported key ${key}`);
|
|
19670
|
-
}
|
|
19671
|
-
}
|
|
19672
|
-
function valueToKey(value) {
|
|
19673
|
-
if (typeof value === "string") {
|
|
19674
|
-
return value;
|
|
19675
|
-
} else if (typeof value === "number") {
|
|
19676
|
-
return `${VALUE_PREFIX}number--${value}`;
|
|
19677
|
-
} else if (typeof value === "boolean") {
|
|
19678
|
-
return `${VALUE_PREFIX}boolean--${value}`;
|
|
19679
|
-
} else if (value === null) {
|
|
19680
|
-
return `${VALUE_PREFIX}null`;
|
|
19681
|
-
} else if (value === void 0) {
|
|
19682
|
-
return `${VALUE_PREFIX}undefined`;
|
|
19683
|
-
} else {
|
|
19684
|
-
throw new Error(`Unsupported value ${value}`);
|
|
19685
|
-
}
|
|
19686
|
-
}
|
|
19687
|
-
|
|
19688
|
-
// src/inputs/internal/selectFieldHelpers.ts
|
|
19689
|
-
function initializeOptions(optionsOrLoad, getOptionValue, getOptionLabel, unsetLabel, autoSort) {
|
|
19690
|
-
const result = [];
|
|
19691
|
-
if (unsetLabel) {
|
|
19692
|
-
result.push(unsetOption);
|
|
19693
|
-
}
|
|
19694
|
-
const userOptions = [];
|
|
19695
|
-
if (Array.isArray(optionsOrLoad)) {
|
|
19696
|
-
userOptions.push(...optionsOrLoad);
|
|
19697
|
-
} else {
|
|
19698
|
-
const { options, current: current2 } = optionsOrLoad;
|
|
19699
|
-
if (options) {
|
|
19700
|
-
userOptions.push(...options);
|
|
19701
|
-
}
|
|
19702
|
-
if (current2) {
|
|
19703
|
-
const toCheck = Array.isArray(current2) ? current2 : [current2];
|
|
19704
|
-
toCheck.forEach((current3) => {
|
|
19705
|
-
const value = getOptionValue(current3);
|
|
19706
|
-
const found = options && options.find((o) => getOptionValue(o) === value);
|
|
19707
|
-
if (!found) {
|
|
19708
|
-
userOptions.push(current3);
|
|
19709
|
-
}
|
|
19710
|
-
});
|
|
19711
|
-
}
|
|
19712
|
-
}
|
|
19713
|
-
result.push(...autoSort ? sortOptions(userOptions, getOptionLabel) : userOptions);
|
|
19714
|
-
return result;
|
|
19715
|
-
}
|
|
19716
|
-
var unsetOption = {};
|
|
19717
|
-
function disabledOptionToKeyedTuple(disabledOption) {
|
|
19718
|
-
if (typeof disabledOption === "object" && disabledOption !== null) {
|
|
19719
|
-
return [valueToKey(disabledOption.value), disabledOption.reason];
|
|
19720
|
-
} else {
|
|
19721
|
-
return [valueToKey(disabledOption), void 0];
|
|
19722
|
-
}
|
|
19723
|
-
}
|
|
19724
|
-
function sortOptions(options, getOptionLabel) {
|
|
19725
|
-
return [...options].sort((a, b) => {
|
|
19726
|
-
const labelA = getOptionLabel(a).toLowerCase();
|
|
19727
|
-
const labelB = getOptionLabel(b).toLowerCase();
|
|
19728
|
-
return labelA.localeCompare(labelB);
|
|
19729
|
-
});
|
|
19730
|
-
}
|
|
19731
|
-
|
|
19732
19732
|
// src/inputs/MenuSelectField/internal/menuTree.ts
|
|
19733
19733
|
function buildMenuTree(roots, getKey, getChildren) {
|
|
19734
19734
|
const nodes = /* @__PURE__ */ new Map();
|
|
@@ -19910,10 +19910,11 @@ import { jsx as jsx115 } from "react/jsx-runtime";
|
|
|
19910
19910
|
function useMenuSelectField(props) {
|
|
19911
19911
|
const {
|
|
19912
19912
|
options: optionsProp,
|
|
19913
|
-
getOptionValue = defaultOptionValue,
|
|
19914
|
-
getOptionLabel = defaultOptionLabel,
|
|
19913
|
+
getOptionValue: propGetOptionValue = defaultOptionValue,
|
|
19914
|
+
getOptionLabel: propGetOptionLabel = defaultOptionLabel,
|
|
19915
19915
|
getOptionMenuLabel,
|
|
19916
19916
|
getOptionSearchText,
|
|
19917
|
+
unsetLabel,
|
|
19917
19918
|
autoSort = true,
|
|
19918
19919
|
onSearch,
|
|
19919
19920
|
disabledOptions,
|
|
@@ -19956,11 +19957,13 @@ function useMenuSelectField(props) {
|
|
|
19956
19957
|
const [search, setSearch] = useState31("");
|
|
19957
19958
|
const [optionsLoading, setOptionsLoading] = useState31(false);
|
|
19958
19959
|
const didRequestOptionsRef = useRef36(false);
|
|
19960
|
+
const getOptionLabel = (option) => unsetLabel && option === unsetOption ? unsetLabel : propGetOptionLabel(option);
|
|
19961
|
+
const getOptionValue = (option) => unsetLabel && option === unsetOption ? void 0 : propGetOptionValue(option);
|
|
19959
19962
|
const options = useMemo28(
|
|
19960
|
-
() => initializeOptions(optionsProp, getOptionValue, getOptionLabel,
|
|
19963
|
+
() => initializeOptions(optionsProp, getOptionValue, getOptionLabel, unsetLabel, autoSort),
|
|
19961
19964
|
// getOptionValue and getOptionLabel are typically inline lambdas
|
|
19962
19965
|
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
19963
|
-
[optionsProp, autoSort]
|
|
19966
|
+
[optionsProp, autoSort, unsetLabel]
|
|
19964
19967
|
);
|
|
19965
19968
|
const { hoverProps, isHovered } = useHover13({});
|
|
19966
19969
|
const { focusProps, isFocusVisible } = useFocusRing10();
|
|
@@ -20027,10 +20030,12 @@ function useMenuSelectField(props) {
|
|
|
20027
20030
|
);
|
|
20028
20031
|
}, [menuTree, allOptions, search, serverSearch, contains, expandedKeys, searchCollapsedKeys]);
|
|
20029
20032
|
const filteredOptions = useMemo28(
|
|
20030
|
-
() => menuTree || !search || serverSearch ? options : options.filter(
|
|
20033
|
+
() => menuTree || !search || serverSearch ? options : options.filter(
|
|
20034
|
+
(option) => unsetLabel && option === unsetOption ? contains(getOptionLabel(option), search) : matchesSearch(option, search, getOptionLabel, getOptionSearchText, contains)
|
|
20035
|
+
),
|
|
20031
20036
|
// getOptionLabel and getOptionSearchText are typically inline lambdas
|
|
20032
20037
|
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
20033
|
-
[menuTree, options, search, serverSearch, contains]
|
|
20038
|
+
[menuTree, options, search, serverSearch, contains, unsetLabel]
|
|
20034
20039
|
);
|
|
20035
20040
|
function onSelectionChange(keys) {
|
|
20036
20041
|
if (keys === "all") return;
|
|
@@ -20080,7 +20085,7 @@ function useMenuSelectField(props) {
|
|
|
20080
20085
|
}, [treeRows, filteredOptions]);
|
|
20081
20086
|
const state = useListState({
|
|
20082
20087
|
items: collectionItems,
|
|
20083
|
-
children: (item) => /* @__PURE__ */ jsx115(Item2, { textValue: getOptionLabel(item.option), children: getOptionMenuLabel ? getOptionMenuLabel(item.option) : getOptionLabel(item.option) }, item.key),
|
|
20088
|
+
children: (item) => /* @__PURE__ */ jsx115(Item2, { textValue: getOptionLabel(item.option), children: getOptionMenuLabel ? getOptionMenuLabel(item.option, Boolean(unsetLabel) && item.option === unsetOption) : getOptionLabel(item.option) }, item.key),
|
|
20084
20089
|
selectionMode: multiple ? "multiple" : "single",
|
|
20085
20090
|
selectedKeys: selectedRowKeys,
|
|
20086
20091
|
disabledKeys: disabledRowKeys,
|
|
@@ -20471,17 +20476,24 @@ function BaseMenuSelectField(props) {
|
|
|
20471
20476
|
// src/inputs/MenuSelectField/MenuSelectField.tsx
|
|
20472
20477
|
import { jsx as jsx117 } from "react/jsx-runtime";
|
|
20473
20478
|
function MenuSelectField(props) {
|
|
20474
|
-
const { value, proposedValue, onSelect, ...rest } = props;
|
|
20475
|
-
const values = useMemo29(() =>
|
|
20479
|
+
const { value, proposedValue, onSelect, unsetLabel, ...rest } = props;
|
|
20480
|
+
const values = useMemo29(() => {
|
|
20481
|
+
if (value !== void 0) return [value];
|
|
20482
|
+
return unsetLabel ? [void 0] : [];
|
|
20483
|
+
}, [value, unsetLabel]);
|
|
20476
20484
|
const proposedValues = useMemo29(() => proposedValue === void 0 ? void 0 : [proposedValue], [proposedValue]);
|
|
20477
20485
|
return /* @__PURE__ */ jsx117(
|
|
20478
20486
|
BaseMenuSelectField,
|
|
20479
20487
|
{
|
|
20480
20488
|
...rest,
|
|
20489
|
+
unsetLabel,
|
|
20481
20490
|
selectionMode: "single",
|
|
20482
20491
|
values,
|
|
20483
20492
|
proposedValues,
|
|
20484
|
-
onCommit: (next, opts) =>
|
|
20493
|
+
onCommit: (next, opts) => {
|
|
20494
|
+
const option = opts[0];
|
|
20495
|
+
onSelect(next[0], option === unsetOption ? void 0 : option);
|
|
20496
|
+
}
|
|
20485
20497
|
}
|
|
20486
20498
|
);
|
|
20487
20499
|
}
|
|
@@ -31499,7 +31511,6 @@ import { jsx as jsx241 } from "react/jsx-runtime";
|
|
|
31499
31511
|
function singleFilter(props) {
|
|
31500
31512
|
return (key) => new SingleFilter(key, props);
|
|
31501
31513
|
}
|
|
31502
|
-
var allOption = {};
|
|
31503
31514
|
var SingleFilter = class extends BaseFilter {
|
|
31504
31515
|
formatSelectedFilterLabel(value) {
|
|
31505
31516
|
const { options } = this.props;
|
|
@@ -31507,26 +31518,15 @@ var SingleFilter = class extends BaseFilter {
|
|
|
31507
31518
|
return resolveOptionSelectedFilterLabel(options, getOptionValue, getOptionLabel, value);
|
|
31508
31519
|
}
|
|
31509
31520
|
render(value, setValue, tid, inModal, vertical) {
|
|
31510
|
-
const { label, defaultValue,
|
|
31511
|
-
const { getOptionValue, getOptionLabel } = optionReaders2(this.props);
|
|
31512
|
-
const unsetText = nothingSelectedText ?? "All";
|
|
31513
|
-
const isStaticList = Array.isArray(maybeOptions);
|
|
31514
|
-
const options = isStaticList ? [
|
|
31515
|
-
allOption,
|
|
31516
|
-
...initializeOptions(maybeOptions, getOptionValue, getOptionLabel, void 0, autoSort ?? true)
|
|
31517
|
-
] : maybeOptions;
|
|
31521
|
+
const { label, defaultValue, nothingSelectedText, unsetLabel, ...props } = this.props;
|
|
31518
31522
|
return /* @__PURE__ */ jsx241(
|
|
31519
31523
|
MenuSelectField,
|
|
31520
31524
|
{
|
|
31521
31525
|
...props,
|
|
31522
|
-
|
|
31523
|
-
options,
|
|
31524
|
-
getOptionValue: (option) => option === allOption ? void 0 : getOptionValue(option),
|
|
31525
|
-
getOptionLabel: (option) => option === allOption ? unsetText : getOptionLabel(option),
|
|
31526
|
+
unsetLabel: unsetLabel ?? nothingSelectedText ?? "All",
|
|
31526
31527
|
value,
|
|
31527
31528
|
label: this.label,
|
|
31528
31529
|
labelStyle: inModal ? "hidden" : !inModal && !vertical ? "inline" : "above",
|
|
31529
|
-
nothingSelectedText: unsetText,
|
|
31530
31530
|
onSelect: (next) => setValue(next || void 0),
|
|
31531
31531
|
...this.testId(tid)
|
|
31532
31532
|
}
|