@homebound/beam 2.93.0 → 2.94.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/components/Table/CollapseToggle.js +5 -4
- package/dist/components/Table/GridTable.d.ts +4 -3
- package/dist/components/Table/GridTable.js +58 -49
- package/dist/components/Table/nestedCards.d.ts +4 -4
- package/dist/components/Table/nestedCards.js +16 -10
- package/dist/components/Tooltip.d.ts +1 -1
- package/dist/components/Tooltip.js +6 -2
- package/dist/inputs/DateField.mock.js +1 -1
- package/dist/inputs/MultiSelectField.mock.js +2 -2
- package/dist/inputs/SelectField.mock.js +1 -1
- package/dist/inputs/TextFieldBase.js +30 -31
- package/dist/inputs/internal/SelectFieldBase.d.ts +2 -2
- package/dist/inputs/internal/SelectFieldBase.js +5 -2
- package/dist/inputs/internal/SelectFieldInput.d.ts +1 -0
- package/dist/inputs/internal/SelectFieldInput.js +1 -1
- package/package.json +1 -1
|
@@ -6,13 +6,14 @@ const react_1 = require("react");
|
|
|
6
6
|
const components_1 = require("..");
|
|
7
7
|
function CollapseToggle(props) {
|
|
8
8
|
const { row } = props;
|
|
9
|
-
const { isCollapsed,
|
|
10
|
-
const
|
|
11
|
-
const
|
|
9
|
+
const { isCollapsed, toggleCollapsed } = (0, react_1.useContext)(components_1.GridCollapseContext);
|
|
10
|
+
const toggleOnClick = (0, react_1.useCallback)(() => toggleCollapsed(row.id), [row.id, toggleCollapsed]);
|
|
11
|
+
const iconKey = isCollapsed(row.id) ? "chevronRight" : "chevronDown";
|
|
12
|
+
const headerIconKey = isCollapsed(row.id) ? "chevronsRight" : "chevronsDown";
|
|
12
13
|
const isHeader = row.kind === "header";
|
|
13
14
|
if (!isHeader && (!props.row.children || props.row.children.length === 0)) {
|
|
14
15
|
return null;
|
|
15
16
|
}
|
|
16
|
-
return (0, jsx_runtime_1.jsx)(components_1.IconButton, { onClick:
|
|
17
|
+
return (0, jsx_runtime_1.jsx)(components_1.IconButton, { onClick: toggleOnClick, icon: isHeader ? headerIconKey : iconKey }, void 0);
|
|
17
18
|
}
|
|
18
19
|
exports.CollapseToggle = CollapseToggle;
|
|
@@ -40,6 +40,7 @@ export interface GridStyle {
|
|
|
40
40
|
/** Default content to put into an empty cell */
|
|
41
41
|
emptyCell?: ReactNode;
|
|
42
42
|
}
|
|
43
|
+
export declare type NestedCardStyleByKind = Record<string, NestedCardStyle>;
|
|
43
44
|
export interface NestedCardsStyle {
|
|
44
45
|
/** Space between each card. */
|
|
45
46
|
spacerPx: number;
|
|
@@ -50,7 +51,7 @@ export interface NestedCardsStyle {
|
|
|
50
51
|
*
|
|
51
52
|
* Entries are optional, i.e. you can leave out kinds and they won't be wrapped/turned into cards.
|
|
52
53
|
*/
|
|
53
|
-
kinds:
|
|
54
|
+
kinds: NestedCardStyleByKind;
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
57
|
* Styles for making cards nested within other cards.
|
|
@@ -308,8 +309,8 @@ export declare function applyRowFn<R extends Kinded>(column: GridColumn<R>, row:
|
|
|
308
309
|
* prop).
|
|
309
310
|
*/
|
|
310
311
|
declare type GridCollapseContextProps = {
|
|
311
|
-
isCollapsed: boolean;
|
|
312
|
-
|
|
312
|
+
isCollapsed: (id: string) => boolean;
|
|
313
|
+
toggleCollapsed(id: string): void;
|
|
313
314
|
};
|
|
314
315
|
export declare const GridCollapseContext: React.Context<GridCollapseContextProps>;
|
|
315
316
|
export declare function matchesFilter(maybeContent: ReactNode | GridCellContent, filter: string): boolean;
|
|
@@ -83,7 +83,7 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
83
83
|
function GridTable(props) {
|
|
84
84
|
var _a;
|
|
85
85
|
const { id = "grid-table", as = "div", columns, rows, style = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = "0", xss, sorting, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, setRowCount, observeRows, persistCollapse, api, } = props;
|
|
86
|
-
const [collapsedIds,
|
|
86
|
+
const [collapsedIds, collapseAllContext, collapseRowContext] = useToggleIds(rows, persistCollapse);
|
|
87
87
|
// We only use this in as=virtual mode, but keep this here for rowLookup to use
|
|
88
88
|
const virtuosoRef = (0, react_1.useRef)(null);
|
|
89
89
|
if (api) {
|
|
@@ -109,26 +109,18 @@ function GridTable(props) {
|
|
|
109
109
|
// We only pass sortState to header rows, b/c non-headers rows shouldn't have to re-render on sorting
|
|
110
110
|
// changes, and so by not passing the sortProps, it means the data rows' React.memo will still cache them.
|
|
111
111
|
const sortProps = row.kind === "header" ? { sorting, sortState, setSortKey } : { sorting };
|
|
112
|
-
// We only pass `isCollapsed` as a prop so that the row only re-renders when it itself has
|
|
113
|
-
// changed from collapsed/non-collapsed, and not other row's entering/leaving collapsedIds.
|
|
114
|
-
// Note that we do memoized on toggleCollapsedId, but it's stable thanks to useToggleIds.
|
|
115
|
-
const isCollapsed = collapsedIds.includes(row.id);
|
|
116
112
|
const RowComponent = observeRows ? ObservedGridRow : MemoizedGridRow;
|
|
117
|
-
return ((0, jsx_runtime_1.jsx)(RowComponent, Object.assign({}, {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// At least for non-nested card tables, we make this undefined so it will be fine.
|
|
129
|
-
openCards: nestedCards ? nestedCards.currentOpenCards() : undefined,
|
|
130
|
-
...sortProps,
|
|
131
|
-
}), `${row.kind}-${row.id}`));
|
|
113
|
+
return ((0, jsx_runtime_1.jsx)(exports.GridCollapseContext.Provider, Object.assign({ value: row.kind === "header" ? collapseAllContext : collapseRowContext }, { children: (0, jsx_runtime_1.jsx)(RowComponent, Object.assign({}, {
|
|
114
|
+
as,
|
|
115
|
+
columns,
|
|
116
|
+
row,
|
|
117
|
+
style,
|
|
118
|
+
rowStyles,
|
|
119
|
+
stickyHeader,
|
|
120
|
+
stickyOffset,
|
|
121
|
+
openCards: nestedCards ? nestedCards.currentOpenCards() : undefined,
|
|
122
|
+
...sortProps,
|
|
123
|
+
}), `${row.kind}-${row.id}`) }), void 0));
|
|
132
124
|
}
|
|
133
125
|
// Split out the header rows from the data rows so that we can put an `infoMessage` in between them (if needed).
|
|
134
126
|
const headerRows = [];
|
|
@@ -184,7 +176,8 @@ function GridTable(props) {
|
|
|
184
176
|
stickyHeader,
|
|
185
177
|
stickyOffset,
|
|
186
178
|
collapsedIds,
|
|
187
|
-
|
|
179
|
+
collapseAllContext,
|
|
180
|
+
collapseRowContext,
|
|
188
181
|
observeRows,
|
|
189
182
|
]);
|
|
190
183
|
let tooManyClientSideRows = false;
|
|
@@ -418,7 +411,7 @@ function getFirstOrLastCellCss(style, columnIndex, columns) {
|
|
|
418
411
|
}
|
|
419
412
|
// We extract GridRow to its own mini-component primarily so we can React.memo'ize it.
|
|
420
413
|
function GridRow(props) {
|
|
421
|
-
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sorting, sortState, setSortKey,
|
|
414
|
+
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sorting, sortState, setSortKey, openCards, ...others } = props;
|
|
422
415
|
// We treat the "header" kind as special for "good defaults" styling
|
|
423
416
|
const isHeader = row.kind === "header";
|
|
424
417
|
const rowStyle = rowStyles === null || rowStyles === void 0 ? void 0 : rowStyles[row.kind];
|
|
@@ -438,10 +431,16 @@ function GridRow(props) {
|
|
|
438
431
|
...maybeApplyFunction(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowCss),
|
|
439
432
|
};
|
|
440
433
|
const Row = as === "table" ? "tr" : "div";
|
|
441
|
-
const
|
|
434
|
+
const openCardStyles = typeof openCards === "string"
|
|
435
|
+
? openCards
|
|
436
|
+
.split(":")
|
|
437
|
+
.map((openCardKind) => style.nestedCards.kinds[openCardKind])
|
|
438
|
+
.filter((style) => style)
|
|
439
|
+
: undefined;
|
|
440
|
+
const currentCard = openCardStyles && openCardStyles[openCardStyles.length - 1];
|
|
442
441
|
let currentColspan = 1;
|
|
443
442
|
const maybeStickyHeaderStyles = isHeader && stickyHeader ? Css_1.Css.sticky.top(stickyOffset).z1.$ : undefined;
|
|
444
|
-
|
|
443
|
+
return ((0, jsx_runtime_1.jsxs)(Row, Object.assign({ css: rowCss }, others, { children: [openCardStyles && (0, nestedCards_1.maybeAddCardPadding)(openCardStyles, "first", maybeStickyHeaderStyles), columns.map((column, columnIndex) => {
|
|
445
444
|
var _a;
|
|
446
445
|
// Decrement colspan count and skip if greater than 1.
|
|
447
446
|
if (currentColspan > 1) {
|
|
@@ -491,15 +490,7 @@ function GridRow(props) {
|
|
|
491
490
|
? rowClickRenderFn(as)
|
|
492
491
|
: defaultRenderFn(as);
|
|
493
492
|
return renderFn(columnIndex, cellCss, content, row, rowStyle);
|
|
494
|
-
}),
|
|
495
|
-
// Because of useToggleIds, this provider should basically never trigger a re-render, which is
|
|
496
|
-
// good because we don't want the context to change and re-render every row just because some
|
|
497
|
-
// other unrelated rows have collapsed/uncollapsed.
|
|
498
|
-
const collapseContext = (0, react_1.useMemo)(() => ({
|
|
499
|
-
isCollapsed,
|
|
500
|
-
toggleCollapse: () => toggleCollapsedId(row.id),
|
|
501
|
-
}), [isCollapsed, toggleCollapsedId, row]);
|
|
502
|
-
return (0, jsx_runtime_1.jsx)(exports.GridCollapseContext.Provider, Object.assign({ value: collapseContext }, { children: div }), void 0);
|
|
493
|
+
}), openCardStyles && (0, nestedCards_1.maybeAddCardPadding)(openCardStyles, "final", maybeStickyHeaderStyles)] }), void 0));
|
|
503
494
|
}
|
|
504
495
|
// Fix to work with generics, see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/37087#issuecomment-656596623
|
|
505
496
|
const MemoizedGridRow = react_1.default.memo(GridRow);
|
|
@@ -553,8 +544,8 @@ const defaultRenderFn = (as) => (key, css, content) => {
|
|
|
553
544
|
return ((0, jsx_runtime_1.jsx)(Row, Object.assign({ css: { ...css, ...tableRowStyles(as) } }, { children: content }), key));
|
|
554
545
|
};
|
|
555
546
|
exports.GridCollapseContext = react_1.default.createContext({
|
|
556
|
-
isCollapsed: false,
|
|
557
|
-
|
|
547
|
+
isCollapsed: (id) => false,
|
|
548
|
+
toggleCollapsed: (id) => { },
|
|
558
549
|
});
|
|
559
550
|
/** Sets up the `GridContext` so that header cells can access the current sort settings. */
|
|
560
551
|
const headerRenderFn = (columns, column, sortState, setSortKey, as) => (key, css, content) => {
|
|
@@ -659,10 +650,15 @@ function useToggleIds(rows, persistCollapse) {
|
|
|
659
650
|
const [collapsedIds] = (0, react_1.useState)(getCollapsedRows(persistCollapse));
|
|
660
651
|
// Use this to trigger the component to re-render even though we're not calling `setList`
|
|
661
652
|
const [tick, setTick] = (0, react_1.useState)("");
|
|
662
|
-
//
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
653
|
+
// Checking whether something is collapsed does not depend on anything
|
|
654
|
+
const isCollapsed = (0, react_1.useCallback)((id) => collapsedIds.includes(id),
|
|
655
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
656
|
+
[]);
|
|
657
|
+
const collapseAllContext = (0, react_1.useMemo)(() => {
|
|
658
|
+
// Create the stable `toggleCollapsed`, i.e. we are purposefully passing an (almost) empty dep list
|
|
659
|
+
// Since only toggling all rows required knowledge of what the rows are
|
|
660
|
+
const toggleAll = (_id) => {
|
|
661
|
+
// We have different behavior when going from expand/collapse all.
|
|
666
662
|
const isAllCollapsed = collapsedIds[0] === "header";
|
|
667
663
|
collapsedIds.splice(0, collapsedIds.length);
|
|
668
664
|
if (isAllCollapsed) {
|
|
@@ -685,8 +681,20 @@ function useToggleIds(rows, persistCollapse) {
|
|
|
685
681
|
// And then mark all parent rows as collapsed.
|
|
686
682
|
collapsedIds.push(...parentIds);
|
|
687
683
|
}
|
|
688
|
-
|
|
689
|
-
|
|
684
|
+
if (persistCollapse) {
|
|
685
|
+
localStorage.setItem(persistCollapse, JSON.stringify(collapsedIds));
|
|
686
|
+
}
|
|
687
|
+
// Trigger a re-render
|
|
688
|
+
setTick(collapsedIds.join(","));
|
|
689
|
+
};
|
|
690
|
+
return { isCollapsed, toggleCollapsed: toggleAll };
|
|
691
|
+
},
|
|
692
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
693
|
+
[rows]);
|
|
694
|
+
const collapseRowContext = (0, react_1.useMemo)(() => {
|
|
695
|
+
// Create the stable `toggleCollapsed`, i.e. we are purposefully passing an empty dep list
|
|
696
|
+
// Since toggling a single row does not need to know about the other rows
|
|
697
|
+
const toggleRow = (id) => {
|
|
690
698
|
// This is the regular/non-header behavior to just add/remove the individual row id
|
|
691
699
|
const i = collapsedIds.indexOf(id);
|
|
692
700
|
if (i === -1) {
|
|
@@ -695,21 +703,22 @@ function useToggleIds(rows, persistCollapse) {
|
|
|
695
703
|
else {
|
|
696
704
|
collapsedIds.splice(i, 1);
|
|
697
705
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
706
|
+
if (persistCollapse) {
|
|
707
|
+
localStorage.setItem(persistCollapse, JSON.stringify(collapsedIds));
|
|
708
|
+
}
|
|
709
|
+
// Trigger a re-render
|
|
710
|
+
setTick(collapsedIds.join(","));
|
|
711
|
+
};
|
|
712
|
+
return { isCollapsed, toggleCollapsed: toggleRow };
|
|
704
713
|
},
|
|
705
714
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
706
|
-
[
|
|
715
|
+
[]);
|
|
707
716
|
// Return a copy of the list, b/c we want external useMemos that do explicitly use the
|
|
708
717
|
// entire list as a dep to re-render whenever the list is changed (which they need to
|
|
709
718
|
// see as new list identity).
|
|
710
719
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
711
720
|
const copy = (0, react_1.useMemo)(() => [...collapsedIds], [tick, collapsedIds]);
|
|
712
|
-
return [copy,
|
|
721
|
+
return [copy, collapseAllContext, collapseRowContext];
|
|
713
722
|
}
|
|
714
723
|
/** GridTable as Table utility to apply <tr> element override styles */
|
|
715
724
|
const tableRowStyles = (as, column) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
|
-
import { GridColumn, GridDataRow, GridStyle, Kinded, NestedCardStyle, RowTuple } from "./GridTable";
|
|
2
|
+
import { GridColumn, GridDataRow, GridStyle, Kinded, NestedCardsStyle, NestedCardStyle, NestedCardStyleByKind, RowTuple } from "./GridTable";
|
|
3
3
|
/**
|
|
4
4
|
* A helper class to create our nested card DOM shenanigans.
|
|
5
5
|
*
|
|
@@ -27,7 +27,7 @@ export declare class NestedCards {
|
|
|
27
27
|
addSpacer(): void;
|
|
28
28
|
done(): void;
|
|
29
29
|
/** Return a stable copy of the cards, so it won't change as we keep going. */
|
|
30
|
-
currentOpenCards():
|
|
30
|
+
currentOpenCards(): string;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* Draws the rounded corners (either open or close) for a new card.
|
|
@@ -42,7 +42,7 @@ export declare class NestedCards {
|
|
|
42
42
|
* I.e. due to the flatness of our DOM, we inherently have to add a "close"
|
|
43
43
|
* row separate from the card's actual content.
|
|
44
44
|
*/
|
|
45
|
-
export declare function makeOpenOrCloseCard(openCards:
|
|
45
|
+
export declare function makeOpenOrCloseCard(openCards: string[], cardStyles: NestedCardStyleByKind, kind: "open" | "close"): Chrome;
|
|
46
46
|
/**
|
|
47
47
|
* For the first or last cell of actual content, wrap them in divs that re-create the
|
|
48
48
|
* outer cards' padding + background.
|
|
@@ -54,7 +54,7 @@ export declare function maybeAddCardPadding(openCards: NestedCardStyle[], column
|
|
|
54
54
|
* Our height is not based on `openCards`, b/c for the top-most level, we won't
|
|
55
55
|
* have any open cards, but still want a space between top-level cards.
|
|
56
56
|
*/
|
|
57
|
-
export declare function makeSpacer(height: number, openCards:
|
|
57
|
+
export declare function makeSpacer(height: number, openCards: string[], styles: NestedCardsStyle): Chrome;
|
|
58
58
|
/**
|
|
59
59
|
* Takes the current buffer of close row(s), spacers, and open row, and creates a single chrome DOM row.
|
|
60
60
|
*
|
|
@@ -19,26 +19,26 @@ class NestedCards {
|
|
|
19
19
|
const card = this.styles.kinds[row.kind];
|
|
20
20
|
// If this kind doesn't have a card defined, don't put it on the card stack
|
|
21
21
|
if (card) {
|
|
22
|
-
this.openCards.push(
|
|
23
|
-
this.chromeBuffer.push(makeOpenOrCloseCard(this.openCards, "open"));
|
|
22
|
+
this.openCards.push(row.kind);
|
|
23
|
+
this.chromeBuffer.push(makeOpenOrCloseCard(this.openCards, this.styles.kinds, "open"));
|
|
24
24
|
}
|
|
25
25
|
// But always close previous cards if needed
|
|
26
26
|
maybeCreateChromeRow(this.columns, this.filteredRows, this.chromeBuffer);
|
|
27
27
|
return !!card;
|
|
28
28
|
}
|
|
29
29
|
closeCard() {
|
|
30
|
-
this.chromeBuffer.push(makeOpenOrCloseCard(this.openCards, "close"));
|
|
30
|
+
this.chromeBuffer.push(makeOpenOrCloseCard(this.openCards, this.styles.kinds, "close"));
|
|
31
31
|
this.openCards.pop();
|
|
32
32
|
}
|
|
33
33
|
addSpacer() {
|
|
34
|
-
this.chromeBuffer.push(makeSpacer(this.styles.spacerPx, this.openCards));
|
|
34
|
+
this.chromeBuffer.push(makeSpacer(this.styles.spacerPx, this.openCards, this.styles));
|
|
35
35
|
}
|
|
36
36
|
done() {
|
|
37
37
|
maybeCreateChromeRow(this.columns, this.filteredRows, this.chromeBuffer);
|
|
38
38
|
}
|
|
39
39
|
/** Return a stable copy of the cards, so it won't change as we keep going. */
|
|
40
40
|
currentOpenCards() {
|
|
41
|
-
return
|
|
41
|
+
return this.openCards.join(":");
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
exports.NestedCards = NestedCards;
|
|
@@ -55,7 +55,7 @@ exports.NestedCards = NestedCards;
|
|
|
55
55
|
* I.e. due to the flatness of our DOM, we inherently have to add a "close"
|
|
56
56
|
* row separate from the card's actual content.
|
|
57
57
|
*/
|
|
58
|
-
function makeOpenOrCloseCard(openCards, kind) {
|
|
58
|
+
function makeOpenOrCloseCard(openCards, cardStyles, kind) {
|
|
59
59
|
const scopeCards = [...openCards];
|
|
60
60
|
return () => {
|
|
61
61
|
let div = (0, jsx_runtime_1.jsx)("div", {}, void 0);
|
|
@@ -67,7 +67,10 @@ function makeOpenOrCloseCard(openCards, kind) {
|
|
|
67
67
|
// | card1 | card2 / ... card3 ... \ card2 | card1 |
|
|
68
68
|
// | card1 | card2 | ... card3 ... | card2 | card1 |
|
|
69
69
|
//
|
|
70
|
-
[...scopeCards]
|
|
70
|
+
[...scopeCards]
|
|
71
|
+
.map((cardKind) => cardStyles[cardKind])
|
|
72
|
+
.reverse()
|
|
73
|
+
.forEach((card, i) => {
|
|
71
74
|
const first = i === 0;
|
|
72
75
|
div = ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: {
|
|
73
76
|
...Css_1.Css.bgColor(card.bgColor).pxPx(card.pxPx).$,
|
|
@@ -106,14 +109,17 @@ exports.maybeAddCardPadding = maybeAddCardPadding;
|
|
|
106
109
|
* Our height is not based on `openCards`, b/c for the top-most level, we won't
|
|
107
110
|
* have any open cards, but still want a space between top-level cards.
|
|
108
111
|
*/
|
|
109
|
-
function makeSpacer(height, openCards) {
|
|
112
|
+
function makeSpacer(height, openCards, styles) {
|
|
110
113
|
const scopeCards = [...openCards];
|
|
111
114
|
return () => {
|
|
112
115
|
let div = (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.hPx(height).$ }, void 0);
|
|
113
116
|
// Start at the current/inside card, and wrap outward padding + borders.
|
|
114
117
|
// | card1 | card2 | ... card3 ... | card2 | card1 |
|
|
115
|
-
[...scopeCards]
|
|
116
|
-
|
|
118
|
+
[...scopeCards]
|
|
119
|
+
.map((cardKind) => styles.kinds[cardKind])
|
|
120
|
+
.reverse()
|
|
121
|
+
.forEach((card) => {
|
|
122
|
+
div = ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.bgColor(card.bgColor).pxPx(card.pxPx).if(!!card.bColor).bc(card.bColor).bl.br.$ }, { children: div }), void 0));
|
|
117
123
|
});
|
|
118
124
|
return div;
|
|
119
125
|
};
|
|
@@ -10,5 +10,5 @@ interface TooltipProps {
|
|
|
10
10
|
export declare function Tooltip(props: TooltipProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
11
11
|
export declare type Placement = "top" | "bottom" | "left" | "right" | "auto";
|
|
12
12
|
export declare function maybeTooltip(props: TooltipProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
13
|
-
export declare function resolveTooltip(disabled?: boolean | ReactNode, tooltip?: ReactNode): ReactNode | undefined;
|
|
13
|
+
export declare function resolveTooltip(disabled?: boolean | ReactNode, tooltip?: ReactNode, readOnly?: boolean | ReactNode): ReactNode | undefined;
|
|
14
14
|
export {};
|
|
@@ -54,8 +54,12 @@ function maybeTooltip(props) {
|
|
|
54
54
|
}
|
|
55
55
|
exports.maybeTooltip = maybeTooltip;
|
|
56
56
|
// Helper function for resolving showing the Tooltip text via a 'disabled' prop, or the 'tooltip' prop.
|
|
57
|
-
function resolveTooltip(disabled, tooltip) {
|
|
57
|
+
function resolveTooltip(disabled, tooltip, readOnly) {
|
|
58
58
|
// If `disabled` is a ReactNode, then return that. Otherwise, return `tooltip`
|
|
59
|
-
return typeof disabled !== "boolean" && disabled
|
|
59
|
+
return typeof disabled !== "boolean" && disabled
|
|
60
|
+
? disabled
|
|
61
|
+
: typeof readOnly !== "boolean" && readOnly
|
|
62
|
+
? readOnly
|
|
63
|
+
: tooltip !== null && tooltip !== void 0 ? tooltip : undefined;
|
|
60
64
|
}
|
|
61
65
|
exports.resolveTooltip = resolveTooltip;
|
|
@@ -14,6 +14,6 @@ function DateField(props) {
|
|
|
14
14
|
const { value } = e.target;
|
|
15
15
|
setValue(value);
|
|
16
16
|
onChange((0, date_fns_1.parse)(value, "MM/dd/yy", new Date()));
|
|
17
|
-
}, onBlur: () => (0, utils_1.maybeCall)(onBlur), onFocus: () => (0, utils_1.maybeCall)(onFocus) }), void 0));
|
|
17
|
+
}, onBlur: () => (0, utils_1.maybeCall)(onBlur), onFocus: () => (0, utils_1.maybeCall)(onFocus), disabled: !!props.disabled, readOnly: props.readOnly }), void 0));
|
|
18
18
|
}
|
|
19
19
|
exports.DateField = DateField;
|
|
@@ -7,7 +7,7 @@ const utils_1 = require("../utils");
|
|
|
7
7
|
function MultiSelectField(props) {
|
|
8
8
|
const { getOptionValue = (o) => o.id, // if unset, assume O implements HasId
|
|
9
9
|
getOptionLabel = (o) => o.name, // if unset, assume O implements HasName
|
|
10
|
-
values, options, onSelect, readOnly = false, errorMsg, onFocus, onBlur, } = props;
|
|
10
|
+
values, options, onSelect, readOnly = false, errorMsg, onFocus, onBlur, disabled, } = props;
|
|
11
11
|
const tid = (0, utils_1.useTestIds)(props, "multiSelect");
|
|
12
12
|
return ((0, jsx_runtime_1.jsxs)("select", Object.assign({}, tid, {
|
|
13
13
|
// We're cheating and assume the values are strings...what we should really do is either:
|
|
@@ -37,7 +37,7 @@ function MultiSelectField(props) {
|
|
|
37
37
|
onBlur();
|
|
38
38
|
},
|
|
39
39
|
// Read Only does not apply to `select` fields, instead we'll add in disabled for tests to verify.
|
|
40
|
-
disabled: readOnly, "data-error": !!errorMsg, "data-errormsg": errorMsg, "data-readonly": readOnly }, { children: [(0, jsx_runtime_1.jsx)("option", { disabled: true, value: "" }, void 0), options.map((option, i) => {
|
|
40
|
+
disabled: !!(readOnly || disabled), "data-error": !!errorMsg, "data-errormsg": errorMsg, "data-readonly": readOnly }, { children: [(0, jsx_runtime_1.jsx)("option", { disabled: true, value: "" }, void 0), options.map((option, i) => {
|
|
41
41
|
return ((0, jsx_runtime_1.jsx)("option", Object.assign({ value: getOptionValue(option) }, { children: getOptionLabel(option) }), i));
|
|
42
42
|
})] }), void 0));
|
|
43
43
|
}
|
|
@@ -23,7 +23,7 @@ function SelectField(props) {
|
|
|
23
23
|
onBlur();
|
|
24
24
|
},
|
|
25
25
|
// Read Only does not apply to `select` fields, instead we'll add in disabled for tests to verify.
|
|
26
|
-
disabled: disabled || readOnly, "data-error": !!errorMsg, "data-errormsg": errorMsg, "data-readonly": readOnly }, { children: [(0, jsx_runtime_1.jsx)("option", { disabled: true, value: "" }, void 0), options.map((option, i) => {
|
|
26
|
+
disabled: !!(disabled || readOnly), "data-error": !!errorMsg, "data-errormsg": errorMsg, "data-readonly": readOnly }, { children: [(0, jsx_runtime_1.jsx)("option", { disabled: true, value: "" }, void 0), options.map((option, i) => {
|
|
27
27
|
return ((0, jsx_runtime_1.jsx)("option", Object.assign({ value: `${getOptionValue(option)}` }, { children: getOptionLabel(option) }), i));
|
|
28
28
|
})] }), void 0));
|
|
29
29
|
}
|
|
@@ -77,36 +77,35 @@ function TextFieldBase(props) {
|
|
|
77
77
|
}, onFocus);
|
|
78
78
|
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: fieldStyles.container }, groupProps, focusWithinProps, { children: [label && !inlineLabel && (
|
|
79
79
|
// set `hidden` if being rendered as a compound field
|
|
80
|
-
(0, jsx_runtime_1.jsx)(Label_1.Label, Object.assign({ labelProps: labelProps, hidden: hideLabel || compound, label: label, suffix: labelSuffix, contrast: contrast }, tid.label), void 0)),
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}), errorMsg && !compound && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, Object.assign({ id: errorMessageId, errorMsg: errorMsg }, tid.errorMsg), void 0), helperText && !compound && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, Object.assign({ helperText: helperText }, tid.helperText), void 0)] }), void 0));
|
|
80
|
+
(0, jsx_runtime_1.jsx)(Label_1.Label, Object.assign({ labelProps: labelProps, hidden: hideLabel || compound, label: label, suffix: labelSuffix, contrast: contrast }, tid.label), void 0)), (0, components_1.maybeTooltip)({
|
|
81
|
+
title: tooltip,
|
|
82
|
+
placement: "top",
|
|
83
|
+
children: readOnly ? ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
84
|
+
// Use input wrapper to get common styles, but then we need to override some
|
|
85
|
+
...fieldStyles.inputWrapperReadOnly,
|
|
86
|
+
...(multiline ? Css_1.Css.fdc.aifs.childGap2.$ : Css_1.Css.truncate.$),
|
|
87
|
+
...xss,
|
|
88
|
+
}, "data-readonly": "true" }, tid, { children: [!multiline && inlineLabel && label && !hideLabel && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, Object.assign({ labelProps: labelProps, label: label }, tid.label), void 0)), multiline
|
|
89
|
+
? (_f = inputProps.value) === null || _f === void 0 ? void 0 : _f.split("\n\n").map((p, i) => ((0, jsx_runtime_1.jsx)("p", Object.assign({ css: Css_1.Css.my1.$ }, { children: p.split("\n").map((sentence, j) => ((0, jsx_runtime_1.jsxs)("span", { children: [sentence, (0, jsx_runtime_1.jsx)("br", {}, void 0)] }, j))) }), i)))
|
|
90
|
+
: inputProps.value] }), void 0)) : ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
91
|
+
...fieldStyles.inputWrapper,
|
|
92
|
+
...(inputProps.disabled ? fieldStyles.disabled : {}),
|
|
93
|
+
...(isFocused && !readOnly ? fieldStyles.focus : {}),
|
|
94
|
+
...(isHovered && !inputProps.disabled && !readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
95
|
+
...(errorMsg ? fieldStyles.error : {}),
|
|
96
|
+
...Css_1.Css.if(multiline).aifs.px0.mhPx(textAreaMinHeight).$,
|
|
97
|
+
} }, hoverProps, { ref: inputWrapRef }, { children: [!multiline && inlineLabel && label && !hideLabel && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, Object.assign({ labelProps: labelProps, label: label }, tid.label), void 0)), !multiline && startAdornment && (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.df.aic.fs0.br4.pr1.$ }, { children: startAdornment }), void 0), (0, jsx_runtime_1.jsx)(ElementType, Object.assign({}, (0, react_aria_1.mergeProps)(inputProps, { onBlur, onFocus: onFocusChained, onChange: onDomChange }, { "aria-invalid": Boolean(errorMsg), ...(hideLabel ? { "aria-label": label } : {}) }), (errorMsg ? { "aria-errormessage": errorMessageId } : {}), { ref: fieldRef, rows: multiline ? 1 : undefined, css: {
|
|
98
|
+
...fieldStyles.input,
|
|
99
|
+
...(inputProps.disabled ? fieldStyles.disabled : {}),
|
|
100
|
+
...(isHovered && !inputProps.disabled && !readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
101
|
+
...(multiline ? Css_1.Css.h100.p1.add("resize", "none").if(borderless).pPx(4).$ : Css_1.Css.truncate.$),
|
|
102
|
+
...xss,
|
|
103
|
+
} }, tid), void 0), isFocused && clearable && onChange && inputProps.value && ((0, jsx_runtime_1.jsx)(components_1.IconButton, { icon: "xCircle", color: Css_1.Palette.Gray700, onClick: () => {
|
|
104
|
+
var _a;
|
|
105
|
+
onChange(undefined);
|
|
106
|
+
// Reset focus to input element
|
|
107
|
+
(_a = fieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
108
|
+
} }, void 0)), !multiline && endAdornment && (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.df.aic.pl1.fs0.$ }, { children: endAdornment }), void 0)] }), void 0)),
|
|
109
|
+
}), errorMsg && !compound && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, Object.assign({ id: errorMessageId, errorMsg: errorMsg }, tid.errorMsg), void 0), helperText && !compound && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, Object.assign({ helperText: helperText }, tid.helperText), void 0)] }), void 0));
|
|
111
110
|
}
|
|
112
111
|
exports.TextFieldBase = TextFieldBase;
|
|
@@ -25,7 +25,7 @@ export interface SelectFieldBaseProps<O, V extends Value> extends BeamSelectFiel
|
|
|
25
25
|
export declare function SelectFieldBase<O, V extends Value>(props: SelectFieldBaseProps<O, V>): JSX.Element;
|
|
26
26
|
export interface BeamSelectFieldBaseProps<T, V extends Value> extends BeamFocusableProps, PresentationFieldProps {
|
|
27
27
|
disabledOptions?: V[];
|
|
28
|
-
disabled?: boolean;
|
|
28
|
+
disabled?: boolean | ReactNode;
|
|
29
29
|
required?: boolean;
|
|
30
30
|
errorMsg?: string;
|
|
31
31
|
helperText?: string | ReactNode;
|
|
@@ -35,7 +35,7 @@ export interface BeamSelectFieldBaseProps<T, V extends Value> extends BeamFocusa
|
|
|
35
35
|
label: string;
|
|
36
36
|
/** Renders the label inside the input field, i.e. for filters. */
|
|
37
37
|
inlineLabel?: boolean;
|
|
38
|
-
readOnly?: boolean;
|
|
38
|
+
readOnly?: boolean | ReactNode;
|
|
39
39
|
onBlur?: () => void;
|
|
40
40
|
onFocus?: () => void;
|
|
41
41
|
sizeToContent?: boolean;
|
|
@@ -5,6 +5,7 @@ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const react_aria_1 = require("react-aria");
|
|
7
7
|
const react_stately_1 = require("react-stately");
|
|
8
|
+
const components_1 = require("../../components");
|
|
8
9
|
const internal_1 = require("../../components/internal");
|
|
9
10
|
const Css_1 = require("../../Css");
|
|
10
11
|
const ListBox_1 = require("./ListBox");
|
|
@@ -21,8 +22,10 @@ const Value_1 = require("../Value");
|
|
|
21
22
|
*/
|
|
22
23
|
function SelectFieldBase(props) {
|
|
23
24
|
var _a;
|
|
24
|
-
const { compact, disabled
|
|
25
|
+
const { compact, disabled, errorMsg, helperText, label, hideLabel, required, inlineLabel, readOnly, onSelect, fieldDecoration, options, onBlur, onFocus, multiselect = false, getOptionLabel, getOptionValue, getOptionMenuLabel = getOptionLabel, sizeToContent = false, values, nothingSelectedText = "", contrast, disabledOptions, borderless, ...otherProps } = props;
|
|
25
26
|
const { contains } = (0, react_aria_1.useFilter)({ sensitivity: "base" });
|
|
27
|
+
const isDisabled = !!disabled;
|
|
28
|
+
const isReadOnly = !!readOnly;
|
|
26
29
|
function onSelectionChange(keys) {
|
|
27
30
|
var _a;
|
|
28
31
|
// Close menu upon selection change only for Single selection mode
|
|
@@ -185,6 +188,6 @@ function SelectFieldBase(props) {
|
|
|
185
188
|
// Ensures the menu never gets too small.
|
|
186
189
|
minWidth: 200,
|
|
187
190
|
};
|
|
188
|
-
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.df.fdc.w100.maxw((0, Css_1.px)(550)).$, ref: comboBoxRef }, { children: [(0, jsx_runtime_1.jsx)(SelectFieldInput_1.SelectFieldInput, Object.assign({}, otherProps, { buttonProps: buttonProps, buttonRef: triggerRef, compact: compact, errorMsg: errorMsg, helperText: helperText, fieldDecoration: fieldDecoration, inputProps: inputProps, inputRef: inputRef, inputWrapRef: inputWrapRef, isDisabled: isDisabled, required: required, isReadOnly: isReadOnly, state: state, onBlur: onBlur, onFocus: onFocus, inlineLabel: inlineLabel, label: label, hideLabel: hideLabel, labelProps: labelProps, selectedOptions: fieldState.selectedOptions, getOptionValue: getOptionValue, getOptionLabel: getOptionLabel, sizeToContent: sizeToContent, contrast: contrast, nothingSelectedText: nothingSelectedText, borderless: borderless }), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: triggerRef, popoverRef: popoverRef, positionProps: positionProps, onClose: () => state.close(), isOpen: state.isOpen, minWidth: 200 }, { children: (0, jsx_runtime_1.jsx)(ListBox_1.ListBox, Object.assign({}, listBoxProps, { positionProps: positionProps, state: state, listBoxRef: listBoxRef, selectedOptions: fieldState.selectedOptions, getOptionLabel: getOptionLabel, getOptionValue: (o) => (0, Value_1.valueToKey)(getOptionValue(o)), contrast: contrast }), void 0) }), void 0))] }), void 0));
|
|
191
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.df.fdc.w100.maxw((0, Css_1.px)(550)).$, ref: comboBoxRef }, { children: [(0, jsx_runtime_1.jsx)(SelectFieldInput_1.SelectFieldInput, Object.assign({}, otherProps, { buttonProps: buttonProps, buttonRef: triggerRef, compact: compact, errorMsg: errorMsg, helperText: helperText, fieldDecoration: fieldDecoration, inputProps: inputProps, inputRef: inputRef, inputWrapRef: inputWrapRef, isDisabled: isDisabled, required: required, isReadOnly: isReadOnly, state: state, onBlur: onBlur, onFocus: onFocus, inlineLabel: inlineLabel, label: label, hideLabel: hideLabel, labelProps: labelProps, selectedOptions: fieldState.selectedOptions, getOptionValue: getOptionValue, getOptionLabel: getOptionLabel, sizeToContent: sizeToContent, contrast: contrast, nothingSelectedText: nothingSelectedText, borderless: borderless, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly) }), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: triggerRef, popoverRef: popoverRef, positionProps: positionProps, onClose: () => state.close(), isOpen: state.isOpen, minWidth: 200 }, { children: (0, jsx_runtime_1.jsx)(ListBox_1.ListBox, Object.assign({}, listBoxProps, { positionProps: positionProps, state: state, listBoxRef: listBoxRef, selectedOptions: fieldState.selectedOptions, getOptionLabel: getOptionLabel, getOptionValue: (o) => (0, Value_1.valueToKey)(getOptionValue(o)), contrast: contrast }), void 0) }), void 0))] }), void 0));
|
|
189
192
|
}
|
|
190
193
|
exports.SelectFieldBase = SelectFieldBase;
|
|
@@ -26,6 +26,7 @@ interface SelectFieldInputProps<O, V extends Value> extends PresentationFieldPro
|
|
|
26
26
|
sizeToContent: boolean;
|
|
27
27
|
contrast?: boolean;
|
|
28
28
|
nothingSelectedText: string;
|
|
29
|
+
tooltip?: ReactNode;
|
|
29
30
|
}
|
|
30
31
|
export declare function SelectFieldInput<O, V extends Value>(props: SelectFieldInputProps<O, V>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
31
32
|
export {};
|
|
@@ -16,7 +16,7 @@ function SelectFieldInput(props) {
|
|
|
16
16
|
const showNumSelection = isMultiSelect && state.selectionManager.selectedKeys.size > 1;
|
|
17
17
|
// For MultiSelect only show the `fieldDecoration` when input is not in focus.
|
|
18
18
|
const showFieldDecoration = (!isMultiSelect || (isMultiSelect && !isFocused)) && fieldDecoration && selectedOptions.length === 1;
|
|
19
|
-
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, otherProps, { inputRef: inputRef, inputWrapRef: inputWrapRef, label: label, readOnly: isReadOnly, hideLabel: hideLabel, labelProps: labelProps, inlineLabel: inlineLabel, compact: compact, required: required, errorMsg: errorMsg, helperText: helperText, contrast: contrast, xss: !inlineLabel ? Css_1.Css.fw5.$ : {}, startAdornment: (showNumSelection && ((0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.wPx(16).hPx(16).fs0.br100.bgLightBlue700.white.tinyEm.df.aic.jcc.$ }, { children: state.selectionManager.selectedKeys.size }), void 0))) ||
|
|
19
|
+
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, otherProps, { inputRef: inputRef, inputWrapRef: inputWrapRef, label: label, readOnly: isReadOnly, hideLabel: hideLabel, labelProps: labelProps, inlineLabel: inlineLabel, compact: compact, required: required, errorMsg: errorMsg, helperText: helperText, contrast: contrast, xss: !inlineLabel && !isReadOnly ? Css_1.Css.fw5.$ : {}, startAdornment: (showNumSelection && ((0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.wPx(16).hPx(16).fs0.br100.bgLightBlue700.white.tinyEm.df.aic.jcc.$ }, { children: state.selectionManager.selectedKeys.size }), void 0))) ||
|
|
20
20
|
(showFieldDecoration && fieldDecoration(selectedOptions[0])), endAdornment: !isReadOnly && ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonProps, { disabled: isDisabled, ref: buttonRef, css: {
|
|
21
21
|
...Css_1.Css.br4.outline0.gray700.if(contrast).gray400.$,
|
|
22
22
|
...(isDisabled ? Css_1.Css.cursorNotAllowed.gray400.if(contrast).gray600.$ : {}),
|