@homebound/beam 3.23.0 → 3.24.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/Css.json +3 -0
- package/dist/index.cjs +55 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +55 -24
- package/dist/index.js.map +1 -1
- package/dist/truss.css +2 -0
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1219,6 +1219,18 @@ declare class CssBuilder<T extends Properties, S extends StyleKind = "buildtime"
|
|
|
1219
1219
|
float(value: Properties["float"]): CssBuilder<T & {
|
|
1220
1220
|
float: csstype.Property.Float | undefined;
|
|
1221
1221
|
}, S>;
|
|
1222
|
+
/** Sets `fontStyle: "italic"`. */
|
|
1223
|
+
get fsyi(): CssBuilder<T & {
|
|
1224
|
+
fontStyle: csstype.Property.FontStyle | undefined;
|
|
1225
|
+
}, S>;
|
|
1226
|
+
/** Sets `fontStyle: "normal"`. */
|
|
1227
|
+
get fsynm(): CssBuilder<T & {
|
|
1228
|
+
fontStyle: csstype.Property.FontStyle | undefined;
|
|
1229
|
+
}, S>;
|
|
1230
|
+
/** Sets `fontStyle: value`. */
|
|
1231
|
+
fsy(value: Properties["fontStyle"]): CssBuilder<T & {
|
|
1232
|
+
fontStyle: csstype.Property.FontStyle | undefined;
|
|
1233
|
+
}, S>;
|
|
1222
1234
|
/** Sets `fontWeight: "normal"`. */
|
|
1223
1235
|
get fwn(): CssBuilder<T & {
|
|
1224
1236
|
fontWeight: csstype.Property.FontWeight | undefined;
|
|
@@ -6708,6 +6720,22 @@ type ComboBoxBaseProps<O, V extends Value> = {
|
|
|
6708
6720
|
hideErrorMessage?: boolean;
|
|
6709
6721
|
multiline?: boolean;
|
|
6710
6722
|
onSearch?: (search: string) => void;
|
|
6723
|
+
/**
|
|
6724
|
+
* Called when the user explicitly selects the synthetic add-new row from the dropdown.
|
|
6725
|
+
* Only supported on single-select fields.
|
|
6726
|
+
*
|
|
6727
|
+
* While the user types, a pseudo-option (e.g. `Add "my value"`) appears at the bottom of the
|
|
6728
|
+
* filtered list when the trimmed input does not exactly match an existing option label
|
|
6729
|
+
* (case-insensitive). It is not shown when the input is empty, or when the input exactly matches
|
|
6730
|
+
* an existing label (e.g. typing "banana" when "Banana" exists).
|
|
6731
|
+
*
|
|
6732
|
+
* The user must focus that row (e.g. arrow down) and confirm with Enter or click; pressing Enter
|
|
6733
|
+
* on the typed text alone does not invoke this callback.
|
|
6734
|
+
*
|
|
6735
|
+
* This callback does not update the field value or call `onSelect` — callers create the new
|
|
6736
|
+
* option (often async) and set `value` themselves, same as before. Beam cannot auto-select here
|
|
6737
|
+
* because the new option's id typically comes from the caller's save/create logic after this fires.
|
|
6738
|
+
*/
|
|
6711
6739
|
onAddNew?: (v: string) => void;
|
|
6712
6740
|
/**
|
|
6713
6741
|
* When true (default), options are sorted alphabetically by their label.
|
package/dist/index.d.ts
CHANGED
|
@@ -1219,6 +1219,18 @@ declare class CssBuilder<T extends Properties, S extends StyleKind = "buildtime"
|
|
|
1219
1219
|
float(value: Properties["float"]): CssBuilder<T & {
|
|
1220
1220
|
float: csstype.Property.Float | undefined;
|
|
1221
1221
|
}, S>;
|
|
1222
|
+
/** Sets `fontStyle: "italic"`. */
|
|
1223
|
+
get fsyi(): CssBuilder<T & {
|
|
1224
|
+
fontStyle: csstype.Property.FontStyle | undefined;
|
|
1225
|
+
}, S>;
|
|
1226
|
+
/** Sets `fontStyle: "normal"`. */
|
|
1227
|
+
get fsynm(): CssBuilder<T & {
|
|
1228
|
+
fontStyle: csstype.Property.FontStyle | undefined;
|
|
1229
|
+
}, S>;
|
|
1230
|
+
/** Sets `fontStyle: value`. */
|
|
1231
|
+
fsy(value: Properties["fontStyle"]): CssBuilder<T & {
|
|
1232
|
+
fontStyle: csstype.Property.FontStyle | undefined;
|
|
1233
|
+
}, S>;
|
|
1222
1234
|
/** Sets `fontWeight: "normal"`. */
|
|
1223
1235
|
get fwn(): CssBuilder<T & {
|
|
1224
1236
|
fontWeight: csstype.Property.FontWeight | undefined;
|
|
@@ -6708,6 +6720,22 @@ type ComboBoxBaseProps<O, V extends Value> = {
|
|
|
6708
6720
|
hideErrorMessage?: boolean;
|
|
6709
6721
|
multiline?: boolean;
|
|
6710
6722
|
onSearch?: (search: string) => void;
|
|
6723
|
+
/**
|
|
6724
|
+
* Called when the user explicitly selects the synthetic add-new row from the dropdown.
|
|
6725
|
+
* Only supported on single-select fields.
|
|
6726
|
+
*
|
|
6727
|
+
* While the user types, a pseudo-option (e.g. `Add "my value"`) appears at the bottom of the
|
|
6728
|
+
* filtered list when the trimmed input does not exactly match an existing option label
|
|
6729
|
+
* (case-insensitive). It is not shown when the input is empty, or when the input exactly matches
|
|
6730
|
+
* an existing label (e.g. typing "banana" when "Banana" exists).
|
|
6731
|
+
*
|
|
6732
|
+
* The user must focus that row (e.g. arrow down) and confirm with Enter or click; pressing Enter
|
|
6733
|
+
* on the typed text alone does not invoke this callback.
|
|
6734
|
+
*
|
|
6735
|
+
* This callback does not update the field value or call `onSelect` — callers create the new
|
|
6736
|
+
* option (often async) and set `value` themselves, same as before. Beam cannot auto-select here
|
|
6737
|
+
* because the new option's id typically comes from the caller's save/create logic after this fires.
|
|
6738
|
+
*/
|
|
6711
6739
|
onAddNew?: (v: string) => void;
|
|
6712
6740
|
/**
|
|
6713
6741
|
* When true (default), options are sorted alphabetically by their label.
|
package/dist/index.js
CHANGED
|
@@ -1166,6 +1166,19 @@ var CssBuilder = class _CssBuilder {
|
|
|
1166
1166
|
float(value) {
|
|
1167
1167
|
return this.add("float", value);
|
|
1168
1168
|
}
|
|
1169
|
+
// fontStyle
|
|
1170
|
+
/** Sets `fontStyle: "italic"`. */
|
|
1171
|
+
get fsyi() {
|
|
1172
|
+
return this.add("fontStyle", "italic");
|
|
1173
|
+
}
|
|
1174
|
+
/** Sets `fontStyle: "normal"`. */
|
|
1175
|
+
get fsynm() {
|
|
1176
|
+
return this.add("fontStyle", "normal");
|
|
1177
|
+
}
|
|
1178
|
+
/** Sets `fontStyle: value`. */
|
|
1179
|
+
fsy(value) {
|
|
1180
|
+
return this.add("fontStyle", value);
|
|
1181
|
+
}
|
|
1169
1182
|
// fontWeight
|
|
1170
1183
|
/** Sets `fontWeight: "normal"`. */
|
|
1171
1184
|
get fwn() {
|
|
@@ -12441,29 +12454,36 @@ function ComboBoxBase(props) {
|
|
|
12441
12454
|
} = props;
|
|
12442
12455
|
const labelStyle = otherProps.labelStyle ?? fieldProps?.labelStyle ?? "above";
|
|
12443
12456
|
const getOptionLabel = useCallback10(
|
|
12444
|
-
(o) => unsetLabel && o === unsetOption ? unsetLabel : onAddNew && o
|
|
12457
|
+
(o) => unsetLabel && o === unsetOption ? unsetLabel : onAddNew && isAddNewOption(o) ? o.name : propOptionLabel(o),
|
|
12445
12458
|
// propOptionLabel is basically always a lambda, so don't dep on it
|
|
12446
12459
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12447
|
-
[unsetLabel]
|
|
12460
|
+
[unsetLabel, onAddNew]
|
|
12448
12461
|
);
|
|
12449
12462
|
const getOptionValue = useCallback10(
|
|
12450
|
-
(o) => unsetLabel && o === unsetOption ? void 0 : onAddNew && o
|
|
12463
|
+
(o) => unsetLabel && o === unsetOption ? void 0 : onAddNew && isAddNewOption(o) ? o.id : propOptionValue(o),
|
|
12451
12464
|
// propOptionValue is basically always a lambda, so don't dep on it
|
|
12452
12465
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12453
|
-
[unsetLabel]
|
|
12466
|
+
[unsetLabel, onAddNew]
|
|
12454
12467
|
);
|
|
12455
12468
|
const getOptionMenuLabel = useCallback10(
|
|
12456
|
-
(o) =>
|
|
12469
|
+
(o) => {
|
|
12470
|
+
const isAddNew = Boolean(onAddNew) && isAddNewOption(o);
|
|
12471
|
+
if (propOptionMenuLabel) {
|
|
12472
|
+
return propOptionMenuLabel(o, Boolean(unsetLabel) && o === unsetOption, isAddNew);
|
|
12473
|
+
}
|
|
12474
|
+
const label = getOptionLabel(o);
|
|
12475
|
+
return isAddNew ? /* @__PURE__ */ jsx57("span", { className: "fsyi", children: label }) : label;
|
|
12476
|
+
},
|
|
12457
12477
|
// propOptionMenuLabel is basically always a lambda, so don't dep on it
|
|
12458
12478
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12459
|
-
[unsetLabel, getOptionLabel]
|
|
12479
|
+
[unsetLabel, getOptionLabel, onAddNew]
|
|
12460
12480
|
);
|
|
12461
12481
|
const options = useMemo16(
|
|
12462
|
-
() => initializeOptions(propOptions, getOptionValue, getOptionLabel, unsetLabel,
|
|
12482
|
+
() => initializeOptions(propOptions, getOptionValue, getOptionLabel, unsetLabel, autoSort),
|
|
12463
12483
|
// If the caller is using { current, load, options }, memoize on only `current` and `options` values.
|
|
12464
12484
|
// ...and don't bother on memoizing on getOptionValue b/c it's basically always a lambda
|
|
12465
12485
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12466
|
-
Array.isArray(propOptions) ? [propOptions, unsetLabel,
|
|
12486
|
+
Array.isArray(propOptions) ? [propOptions, unsetLabel, autoSort] : [propOptions.current, propOptions.options, unsetLabel, autoSort]
|
|
12467
12487
|
);
|
|
12468
12488
|
const values = useMemo16(() => propValues ?? [], [propValues]);
|
|
12469
12489
|
const inputStylePalette = useMemo16(() => propsInputStylePalette, [propsInputStylePalette]);
|
|
@@ -12485,9 +12505,8 @@ function ComboBoxBase(props) {
|
|
|
12485
12505
|
const {
|
|
12486
12506
|
searchValue
|
|
12487
12507
|
} = fieldState;
|
|
12488
|
-
const
|
|
12489
|
-
|
|
12490
|
-
}, [options, searchValue, getOptionLabel, contains]);
|
|
12508
|
+
const addNewOption = useMemo16(() => getAddNewOption(searchValue, options, getOptionLabel, onAddNew), [searchValue, options, getOptionLabel, onAddNew]);
|
|
12509
|
+
const filteredOptions = useMemo16(() => !searchValue ? options : addNewOption ? [...options.filter((o) => contains(getOptionLabel(o), searchValue)), addNewOption] : options.filter((o) => contains(getOptionLabel(o), searchValue)), [options, searchValue, getOptionLabel, contains, addNewOption]);
|
|
12491
12510
|
function resetField() {
|
|
12492
12511
|
setFieldState((prevState) => ({
|
|
12493
12512
|
...prevState,
|
|
@@ -12578,9 +12597,9 @@ function ComboBoxBase(props) {
|
|
|
12578
12597
|
onSelect([], []);
|
|
12579
12598
|
return;
|
|
12580
12599
|
}
|
|
12581
|
-
const selectedOption =
|
|
12582
|
-
if (
|
|
12583
|
-
onAddNew(fieldState.inputValue);
|
|
12600
|
+
const selectedOption = filteredOptions.find((o) => valueToKey(getOptionValue(o)) === key);
|
|
12601
|
+
if (onAddNew && isAddNewOption(selectedOption) && fieldState.inputValue) {
|
|
12602
|
+
onAddNew(fieldState.inputValue.trim());
|
|
12584
12603
|
return;
|
|
12585
12604
|
}
|
|
12586
12605
|
onSelect([keyToValue(key)], selectedOption ? [selectedOption] : []);
|
|
@@ -12675,7 +12694,7 @@ function ComboBoxBase(props) {
|
|
|
12675
12694
|
function getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText, readOnly) {
|
|
12676
12695
|
return selectedOptions.length === 1 ? getOptionLabel(selectedOptions[0]) : readOnly && selectedOptions.length > 0 ? selectedOptions.map(getOptionLabel).join(", ") : multiselect && selectedOptions.length === 0 ? nothingSelectedText : "";
|
|
12677
12696
|
}
|
|
12678
|
-
function initializeOptions(optionsOrLoad, getOptionValue, getOptionLabel, unsetLabel,
|
|
12697
|
+
function initializeOptions(optionsOrLoad, getOptionValue, getOptionLabel, unsetLabel, autoSort) {
|
|
12679
12698
|
const result = [];
|
|
12680
12699
|
if (unsetLabel) {
|
|
12681
12700
|
result.push(unsetOption);
|
|
@@ -12703,9 +12722,6 @@ function initializeOptions(optionsOrLoad, getOptionValue, getOptionLabel, unsetL
|
|
|
12703
12722
|
}
|
|
12704
12723
|
}
|
|
12705
12724
|
result.push(...autoSort ? sortOptions(userOptions, getOptionLabel) : userOptions);
|
|
12706
|
-
if (addNew) {
|
|
12707
|
-
result.push(addNewOption);
|
|
12708
|
-
}
|
|
12709
12725
|
return result;
|
|
12710
12726
|
}
|
|
12711
12727
|
function sortOptions(options, getOptionLabel) {
|
|
@@ -12716,10 +12732,25 @@ function sortOptions(options, getOptionLabel) {
|
|
|
12716
12732
|
});
|
|
12717
12733
|
}
|
|
12718
12734
|
var unsetOption = {};
|
|
12719
|
-
var
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
}
|
|
12735
|
+
var addNewOptionId = "beam_new";
|
|
12736
|
+
function isAddNewOption(o) {
|
|
12737
|
+
return typeof o === "object" && o !== null && "id" in o && o.id === addNewOptionId;
|
|
12738
|
+
}
|
|
12739
|
+
function getAddNewOption(searchValue, options, getOptionLabel, onAddNew) {
|
|
12740
|
+
if (!onAddNew) return void 0;
|
|
12741
|
+
const normalizedSearch = searchValue?.trim().toLowerCase();
|
|
12742
|
+
if (!normalizedSearch) return void 0;
|
|
12743
|
+
const trimmedSearch = searchValue.trim();
|
|
12744
|
+
const matchesExistingOption = options.some((o) => {
|
|
12745
|
+
if (o === unsetOption) return false;
|
|
12746
|
+
return getOptionLabel(o).trim().toLowerCase() === normalizedSearch;
|
|
12747
|
+
});
|
|
12748
|
+
if (matchesExistingOption) return void 0;
|
|
12749
|
+
return {
|
|
12750
|
+
id: addNewOptionId,
|
|
12751
|
+
name: `Add "${trimmedSearch}"`
|
|
12752
|
+
};
|
|
12753
|
+
}
|
|
12723
12754
|
function disabledOptionToKeyedTuple(disabledOption) {
|
|
12724
12755
|
if (typeof disabledOption === "object" && disabledOption !== null) {
|
|
12725
12756
|
return [valueToKey(disabledOption.value), disabledOption.reason];
|
|
@@ -19164,7 +19195,7 @@ function hydrateDateRange(value) {
|
|
|
19164
19195
|
|
|
19165
19196
|
// src/components/Filters/selectedFilterLabelUtils.ts
|
|
19166
19197
|
function resolveOptionSelectedFilterLabel(optionsOrLoad, getOptionValue, getOptionLabel, value) {
|
|
19167
|
-
const options = initializeOptions(optionsOrLoad, getOptionValue, getOptionLabel, void 0, false
|
|
19198
|
+
const options = initializeOptions(optionsOrLoad, getOptionValue, getOptionLabel, void 0, false);
|
|
19168
19199
|
const match = options.find((o) => getOptionValue(o) === value);
|
|
19169
19200
|
return match ? getOptionLabel(match) : String(value);
|
|
19170
19201
|
}
|
|
@@ -20028,7 +20059,7 @@ function GridTableLayoutComponent(props) {
|
|
|
20028
20059
|
}, [visibleColumnIds, layoutState]);
|
|
20029
20060
|
const visibleColumnsStorageKey = layoutState?.persistedColumnsStorageKey;
|
|
20030
20061
|
const tableActionsEl = /* @__PURE__ */ jsx147(TableActions, { right: (hasHideableColumns || withCardView) && /* @__PURE__ */ jsxs74("div", { className: "df gap1", children: [
|
|
20031
|
-
hasHideableColumns && /* @__PURE__ */ jsx147(EditColumnsButton, { columns, api, tooltip: "Display columns", ...tid.editColumnsButton }),
|
|
20062
|
+
hasHideableColumns && view === "list" && /* @__PURE__ */ jsx147(EditColumnsButton, { columns, api, tooltip: "Display columns", ...tid.editColumnsButton }),
|
|
20032
20063
|
withCardView && /* @__PURE__ */ jsx147(ViewToggleButton, { view, onChange: setView })
|
|
20033
20064
|
] }), xss: {
|
|
20034
20065
|
paddingTop: "pt3",
|