@homebound/beam 2.91.9 → 2.93.2
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/Button.js +8 -8
- package/dist/components/IconButton.js +5 -4
- package/dist/components/PresentationContext.d.ts +1 -0
- package/dist/components/Table/CollapseToggle.js +5 -4
- package/dist/components/Table/GridTable.d.ts +10 -3
- package/dist/components/Table/GridTable.js +70 -51
- package/dist/components/Table/nestedCards.d.ts +4 -4
- package/dist/components/Table/nestedCards.js +16 -10
- package/dist/components/Tooltip.d.ts +2 -0
- package/dist/components/Tooltip.js +12 -1
- package/dist/inputs/ChipSelectField.js +23 -21
- package/dist/inputs/DateField.d.ts +3 -6
- package/dist/inputs/DateField.js +6 -6
- package/dist/inputs/DateField.mock.js +1 -1
- package/dist/inputs/RichTextField.d.ts +0 -2
- package/dist/inputs/RichTextField.js +1 -2
- package/dist/inputs/TextFieldBase.d.ts +2 -2
- package/dist/inputs/TextFieldBase.js +29 -22
- package/package.json +1 -1
|
@@ -5,18 +5,17 @@ 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_router_dom_1 = require("react-router-dom");
|
|
8
|
-
const src_1 = require("..");
|
|
9
8
|
const components_1 = require("./");
|
|
10
|
-
const Tooltip_1 = require("./Tooltip");
|
|
11
9
|
const Css_1 = require("../Css");
|
|
12
10
|
const utils_1 = require("../utils");
|
|
11
|
+
const useTestIds_1 = require("../utils/useTestIds");
|
|
13
12
|
function Button(props) {
|
|
14
13
|
const { onClick: onPress, disabled, endAdornment, menuTriggerProps, tooltip, openInNew, ...otherProps } = props;
|
|
15
14
|
const isDisabled = !!disabled;
|
|
16
15
|
const ariaProps = { onPress, isDisabled, ...otherProps, ...menuTriggerProps };
|
|
17
16
|
const { label, icon, variant = "primary", size = "sm", buttonRef } = ariaProps;
|
|
18
17
|
const ref = buttonRef || (0, react_1.useRef)(null);
|
|
19
|
-
const tid = (0,
|
|
18
|
+
const tid = (0, useTestIds_1.useTestIds)(props, label);
|
|
20
19
|
const { buttonProps, isPressed } = (0, react_aria_1.useButton)({
|
|
21
20
|
...ariaProps,
|
|
22
21
|
onPress: typeof onPress === "string" ? utils_1.noop : onPress,
|
|
@@ -42,12 +41,13 @@ function Button(props) {
|
|
|
42
41
|
},
|
|
43
42
|
...tid,
|
|
44
43
|
};
|
|
45
|
-
const button = typeof onPress === "string" ? ((0, utils_1.isAbsoluteUrl)(onPress) || openInNew ? ((0, jsx_runtime_1.jsxs)("a", Object.assign({}, buttonAttrs, { href: onPress, className:
|
|
44
|
+
const button = typeof onPress === "string" ? ((0, utils_1.isAbsoluteUrl)(onPress) || openInNew ? ((0, jsx_runtime_1.jsxs)("a", Object.assign({}, buttonAttrs, { href: onPress, className: components_1.navLink, target: "_blank", rel: "noreferrer noopener" }, { children: [buttonContent, (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.ml1.$ }, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "linkExternal" }, void 0) }), void 0)] }), void 0)) : ((0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({}, buttonAttrs, { to: onPress, className: components_1.navLink }, { children: buttonContent }), void 0))) : ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonAttrs, { children: buttonContent }), void 0));
|
|
46
45
|
// If we're disabled b/c of a non-boolean ReactNode, or the caller specified tooltip text, then show it in a tooltip
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
return (0, components_1.maybeTooltip)({
|
|
47
|
+
title: (0, components_1.resolveTooltip)(disabled, tooltip),
|
|
48
|
+
placement: "top",
|
|
49
|
+
children: button,
|
|
50
|
+
});
|
|
51
51
|
}
|
|
52
52
|
exports.Button = Button;
|
|
53
53
|
function getButtonStyles(variant, size) {
|
|
@@ -33,10 +33,11 @@ function IconButton(props) {
|
|
|
33
33
|
const buttonContent = ((0, jsx_runtime_1.jsx)(components_1.Icon, { icon: icon, color: color || (isDisabled ? Css_1.Palette.Gray400 : Css_1.Palette.Gray900), inc: inc }, void 0));
|
|
34
34
|
const button = typeof onPress === "string" ? ((0, utils_1.isAbsoluteUrl)(onPress) || openInNew ? ((0, jsx_runtime_1.jsx)("a", Object.assign({}, buttonAttrs, { href: onPress, className: components_1.navLink, target: "_blank", rel: "noreferrer noopener" }, { children: buttonContent }), void 0)) : ((0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({}, buttonAttrs, { to: onPress, className: components_1.navLink }, { children: buttonContent }), void 0))) : ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonAttrs, { children: buttonContent }), void 0));
|
|
35
35
|
// If we're disabled b/c of a non-boolean ReactNode, or the caller specified tooltip text, then show it in a tooltip
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
return (0, components_1.maybeTooltip)({
|
|
37
|
+
title: (0, components_1.resolveTooltip)(disabled, tooltip),
|
|
38
|
+
placement: "top",
|
|
39
|
+
children: button,
|
|
40
|
+
});
|
|
40
41
|
}
|
|
41
42
|
exports.IconButton = IconButton;
|
|
42
43
|
const iconButtonStylesReset = Css_1.Css.hPx(28).wPx(28).br8.bTransparent.bsSolid.bw2.bgTransparent.cursorPointer.outline0.p0.dif.aic.jcc.transition.$;
|
|
@@ -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.
|
|
@@ -152,7 +153,13 @@ export interface GridTableProps<R extends Kinded, S, X> {
|
|
|
152
153
|
*/
|
|
153
154
|
persistCollapse?: string;
|
|
154
155
|
xss?: X;
|
|
156
|
+
/** Experimental API allowing one to scroll to a table index. Primarily intended for stories at the moment */
|
|
157
|
+
api?: MutableRefObject<GridTableApi | undefined>;
|
|
155
158
|
}
|
|
159
|
+
/** NOTE: This API is experimental and primarily intended for story and testing purposes */
|
|
160
|
+
export declare type GridTableApi = {
|
|
161
|
+
scrollToIndex: (index: number) => void;
|
|
162
|
+
};
|
|
156
163
|
/**
|
|
157
164
|
* Renders data in our table layout.
|
|
158
165
|
*
|
|
@@ -302,8 +309,8 @@ export declare function applyRowFn<R extends Kinded>(column: GridColumn<R>, row:
|
|
|
302
309
|
* prop).
|
|
303
310
|
*/
|
|
304
311
|
declare type GridCollapseContextProps = {
|
|
305
|
-
isCollapsed: boolean;
|
|
306
|
-
|
|
312
|
+
isCollapsed: (id: string) => boolean;
|
|
313
|
+
toggleCollapsed(id: string): void;
|
|
307
314
|
};
|
|
308
315
|
export declare const GridCollapseContext: React.Context<GridCollapseContextProps>;
|
|
309
316
|
export declare function matchesFilter(maybeContent: ReactNode | GridCellContent, filter: string): boolean;
|
|
@@ -82,10 +82,15 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
82
82
|
*/
|
|
83
83
|
function GridTable(props) {
|
|
84
84
|
var _a;
|
|
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, } = props;
|
|
86
|
-
const [collapsedIds,
|
|
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, 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
|
+
if (api) {
|
|
90
|
+
api.current = {
|
|
91
|
+
scrollToIndex: (index) => virtuosoRef.current && virtuosoRef.current.scrollToIndex(index),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
89
94
|
const [sortState, setSortKey] = (0, useSortState_1.useSortState)(columns, sorting);
|
|
90
95
|
// Disclaimer that technically even though this is a useMemo, sortRows is mutating `rows` directly
|
|
91
96
|
const maybeSorted = (0, react_1.useMemo)(() => {
|
|
@@ -104,26 +109,18 @@ function GridTable(props) {
|
|
|
104
109
|
// We only pass sortState to header rows, b/c non-headers rows shouldn't have to re-render on sorting
|
|
105
110
|
// changes, and so by not passing the sortProps, it means the data rows' React.memo will still cache them.
|
|
106
111
|
const sortProps = row.kind === "header" ? { sorting, sortState, setSortKey } : { sorting };
|
|
107
|
-
// We only pass `isCollapsed` as a prop so that the row only re-renders when it itself has
|
|
108
|
-
// changed from collapsed/non-collapsed, and not other row's entering/leaving collapsedIds.
|
|
109
|
-
// Note that we do memoized on toggleCollapsedId, but it's stable thanks to useToggleIds.
|
|
110
|
-
const isCollapsed = collapsedIds.includes(row.id);
|
|
111
112
|
const RowComponent = observeRows ? ObservedGridRow : MemoizedGridRow;
|
|
112
|
-
return ((0, jsx_runtime_1.jsx)(RowComponent, Object.assign({}, {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// At least for non-nested card tables, we make this undefined so it will be fine.
|
|
124
|
-
openCards: nestedCards ? nestedCards.currentOpenCards() : undefined,
|
|
125
|
-
...sortProps,
|
|
126
|
-
}), `${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));
|
|
127
124
|
}
|
|
128
125
|
// Split out the header rows from the data rows so that we can put an `infoMessage` in between them (if needed).
|
|
129
126
|
const headerRows = [];
|
|
@@ -179,7 +176,8 @@ function GridTable(props) {
|
|
|
179
176
|
stickyHeader,
|
|
180
177
|
stickyOffset,
|
|
181
178
|
collapsedIds,
|
|
182
|
-
|
|
179
|
+
collapseAllContext,
|
|
180
|
+
collapseRowContext,
|
|
183
181
|
observeRows,
|
|
184
182
|
]);
|
|
185
183
|
let tooManyClientSideRows = false;
|
|
@@ -258,7 +256,12 @@ function renderTable(style, id, columns, headerRows, filteredRows, firstRowMessa
|
|
|
258
256
|
* [3]: https://github.com/tannerlinsley/react-virtual/issues/108
|
|
259
257
|
*/
|
|
260
258
|
function renderVirtual(style, id, columns, headerRows, filteredRows, firstRowMessage, stickyHeader, firstLastColumnWidth, xss, virtuosoRef) {
|
|
261
|
-
|
|
259
|
+
var _a;
|
|
260
|
+
const { paddingBottom } = (_a = style.rootCss) !== null && _a !== void 0 ? _a : {};
|
|
261
|
+
return ((0, jsx_runtime_1.jsx)(react_virtuoso_1.Virtuoso, { ref: virtuosoRef, components: {
|
|
262
|
+
List: VirtualRoot(style, columns, id, firstLastColumnWidth, xss),
|
|
263
|
+
Footer: () => (0, jsx_runtime_1.jsx)("div", { css: { paddingBottom } }, void 0),
|
|
264
|
+
},
|
|
262
265
|
// Pin/sticky both the header row(s) + firstRowMessage to the top
|
|
263
266
|
topItemCount: (stickyHeader ? headerRows.length : 0) + (firstRowMessage ? 1 : 0), itemSize: (el) => {
|
|
264
267
|
const maybeContentsDiv = el.firstElementChild;
|
|
@@ -408,7 +411,7 @@ function getFirstOrLastCellCss(style, columnIndex, columns) {
|
|
|
408
411
|
}
|
|
409
412
|
// We extract GridRow to its own mini-component primarily so we can React.memo'ize it.
|
|
410
413
|
function GridRow(props) {
|
|
411
|
-
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;
|
|
412
415
|
// We treat the "header" kind as special for "good defaults" styling
|
|
413
416
|
const isHeader = row.kind === "header";
|
|
414
417
|
const rowStyle = rowStyles === null || rowStyles === void 0 ? void 0 : rowStyles[row.kind];
|
|
@@ -428,10 +431,16 @@ function GridRow(props) {
|
|
|
428
431
|
...maybeApplyFunction(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowCss),
|
|
429
432
|
};
|
|
430
433
|
const Row = as === "table" ? "tr" : "div";
|
|
431
|
-
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];
|
|
432
441
|
let currentColspan = 1;
|
|
433
442
|
const maybeStickyHeaderStyles = isHeader && stickyHeader ? Css_1.Css.sticky.top(stickyOffset).z1.$ : undefined;
|
|
434
|
-
|
|
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) => {
|
|
435
444
|
var _a;
|
|
436
445
|
// Decrement colspan count and skip if greater than 1.
|
|
437
446
|
if (currentColspan > 1) {
|
|
@@ -481,15 +490,7 @@ function GridRow(props) {
|
|
|
481
490
|
? rowClickRenderFn(as)
|
|
482
491
|
: defaultRenderFn(as);
|
|
483
492
|
return renderFn(columnIndex, cellCss, content, row, rowStyle);
|
|
484
|
-
}),
|
|
485
|
-
// Because of useToggleIds, this provider should basically never trigger a re-render, which is
|
|
486
|
-
// good because we don't want the context to change and re-render every row just because some
|
|
487
|
-
// other unrelated rows have collapsed/uncollapsed.
|
|
488
|
-
const collapseContext = (0, react_1.useMemo)(() => ({
|
|
489
|
-
isCollapsed,
|
|
490
|
-
toggleCollapse: () => toggleCollapsedId(row.id),
|
|
491
|
-
}), [isCollapsed, toggleCollapsedId, row]);
|
|
492
|
-
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));
|
|
493
494
|
}
|
|
494
495
|
// Fix to work with generics, see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/37087#issuecomment-656596623
|
|
495
496
|
const MemoizedGridRow = react_1.default.memo(GridRow);
|
|
@@ -543,8 +544,8 @@ const defaultRenderFn = (as) => (key, css, content) => {
|
|
|
543
544
|
return ((0, jsx_runtime_1.jsx)(Row, Object.assign({ css: { ...css, ...tableRowStyles(as) } }, { children: content }), key));
|
|
544
545
|
};
|
|
545
546
|
exports.GridCollapseContext = react_1.default.createContext({
|
|
546
|
-
isCollapsed: false,
|
|
547
|
-
|
|
547
|
+
isCollapsed: (id) => false,
|
|
548
|
+
toggleCollapsed: (id) => { },
|
|
548
549
|
});
|
|
549
550
|
/** Sets up the `GridContext` so that header cells can access the current sort settings. */
|
|
550
551
|
const headerRenderFn = (columns, column, sortState, setSortKey, as) => (key, css, content) => {
|
|
@@ -649,10 +650,15 @@ function useToggleIds(rows, persistCollapse) {
|
|
|
649
650
|
const [collapsedIds] = (0, react_1.useState)(getCollapsedRows(persistCollapse));
|
|
650
651
|
// Use this to trigger the component to re-render even though we're not calling `setList`
|
|
651
652
|
const [tick, setTick] = (0, react_1.useState)("");
|
|
652
|
-
//
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
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.
|
|
656
662
|
const isAllCollapsed = collapsedIds[0] === "header";
|
|
657
663
|
collapsedIds.splice(0, collapsedIds.length);
|
|
658
664
|
if (isAllCollapsed) {
|
|
@@ -675,8 +681,20 @@ function useToggleIds(rows, persistCollapse) {
|
|
|
675
681
|
// And then mark all parent rows as collapsed.
|
|
676
682
|
collapsedIds.push(...parentIds);
|
|
677
683
|
}
|
|
678
|
-
|
|
679
|
-
|
|
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) => {
|
|
680
698
|
// This is the regular/non-header behavior to just add/remove the individual row id
|
|
681
699
|
const i = collapsedIds.indexOf(id);
|
|
682
700
|
if (i === -1) {
|
|
@@ -685,21 +703,22 @@ function useToggleIds(rows, persistCollapse) {
|
|
|
685
703
|
else {
|
|
686
704
|
collapsedIds.splice(i, 1);
|
|
687
705
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
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 };
|
|
694
713
|
},
|
|
695
714
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
696
|
-
[
|
|
715
|
+
[]);
|
|
697
716
|
// Return a copy of the list, b/c we want external useMemos that do explicitly use the
|
|
698
717
|
// entire list as a dep to re-render whenever the list is changed (which they need to
|
|
699
718
|
// see as new list identity).
|
|
700
719
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
701
720
|
const copy = (0, react_1.useMemo)(() => [...collapsedIds], [tick, collapsedIds]);
|
|
702
|
-
return [copy,
|
|
721
|
+
return [copy, collapseAllContext, collapseRowContext];
|
|
703
722
|
}
|
|
704
723
|
/** GridTable as Table utility to apply <tr> element override styles */
|
|
705
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
|
};
|
|
@@ -9,4 +9,6 @@ interface TooltipProps {
|
|
|
9
9
|
}
|
|
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
|
+
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;
|
|
12
14
|
export {};
|
|
@@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.Tooltip = void 0;
|
|
22
|
+
exports.resolveTooltip = exports.maybeTooltip = exports.Tooltip = void 0;
|
|
23
23
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
24
24
|
const react_1 = __importStar(require("react"));
|
|
25
25
|
const react_aria_1 = require("react-aria");
|
|
@@ -48,3 +48,14 @@ function Popper({ triggerRef, content, placement = "auto" }) {
|
|
|
48
48
|
});
|
|
49
49
|
return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: popperRef, style: styles.popper }, attributes.popper, { css: Css_1.Css.maxw("320px").bgGray900.white.px1.py("4px").br4.xs.z999.$ }, { children: [(0, jsx_runtime_1.jsx)("div", { ref: setArrowRef, style: { ...styles.arrow }, id: "arrow" }, void 0), content] }), void 0), document.body);
|
|
50
50
|
}
|
|
51
|
+
// Helper function to conditionally wrap component with Tooltip if necessary.
|
|
52
|
+
function maybeTooltip(props) {
|
|
53
|
+
return props.title ? (0, jsx_runtime_1.jsx)(Tooltip, Object.assign({}, props), void 0) : props.children;
|
|
54
|
+
}
|
|
55
|
+
exports.maybeTooltip = maybeTooltip;
|
|
56
|
+
// Helper function for resolving showing the Tooltip text via a 'disabled' prop, or the 'tooltip' prop.
|
|
57
|
+
function resolveTooltip(disabled, tooltip) {
|
|
58
|
+
// If `disabled` is a ReactNode, then return that. Otherwise, return `tooltip`
|
|
59
|
+
return typeof disabled !== "boolean" && disabled ? disabled : tooltip !== null && tooltip !== void 0 ? tooltip : undefined;
|
|
60
|
+
}
|
|
61
|
+
exports.resolveTooltip = resolveTooltip;
|
|
@@ -157,29 +157,31 @@ function ChipSelectField(props) {
|
|
|
157
157
|
// Trigger onBlur to initiate any auto-saving behavior.
|
|
158
158
|
(0, utils_1.maybeCall)(onBlur);
|
|
159
159
|
}, [setShowInput]);
|
|
160
|
-
|
|
160
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showInput && onCreateNew && ((0, jsx_runtime_1.jsx)(CreateNewField, Object.assign({ onBlur: removeCreateNewField, onEnter: async (value) => {
|
|
161
161
|
await onCreateNew(value);
|
|
162
162
|
removeCreateNewField();
|
|
163
|
-
} }, tid.createNewField), void 0)), (0,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
163
|
+
} }, tid.createNewField), void 0)), (0, components_1.maybeTooltip)({
|
|
164
|
+
title: (0, components_1.resolveTooltip)(disabled),
|
|
165
|
+
placement: "top",
|
|
166
|
+
children: ((0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: wrapperRef, css: {
|
|
167
|
+
...chipStyles,
|
|
168
|
+
...Css_1.Css.dif.relative.p0.mwPx(32).if(!value).bgGray200.$,
|
|
169
|
+
...(visualFocus ? Css_1.Css.bshFocus.$ : {}),
|
|
170
|
+
...(showInput ? Css_1.Css.dn.$ : {}),
|
|
171
|
+
} }, { children: [(0, jsx_runtime_1.jsx)(Label_1.Label, Object.assign({ label: label, labelProps: labelProps, hidden: true }, tid.label), void 0), (0, jsx_runtime_1.jsx)("button", Object.assign({}, (0, react_aria_1.mergeProps)(focusProps, buttonProps), { ref: buttonRef, css: {
|
|
172
|
+
...Css_1.Css.tl.br16.pxPx(10).pyPx(2).outline0.if(showClearButton).prPx(4).borderRadius("16px 0 0 16px").$,
|
|
173
|
+
...(isDisabled ? Css_1.Css.cursorNotAllowed.gray700.$ : {}),
|
|
174
|
+
"&:hover:not(:disabled)": Css_1.Css.bgGray400.if(!value).bgGray300.$,
|
|
175
|
+
}, title: state.selectedItem ? state.selectedItem.textValue : placeholder }, tid, { children: (0, jsx_runtime_1.jsx)("span", Object.assign({}, valueProps, { css: Css_1.Css.lineClamp1.breakAll.$ }, { children: state.selectedItem ? state.selectedItem.textValue : placeholder }), void 0) }), void 0), showClearButton && ((0, jsx_runtime_1.jsx)("button", Object.assign({}, clearFocusProps, { css: {
|
|
176
|
+
...Css_1.Css.prPx(4).borderRadius("0 16px 16px 0").outline0.$,
|
|
177
|
+
"&:hover": Css_1.Css.bgGray400.$,
|
|
178
|
+
...(isClearFocused ? Css_1.Css.boxShadow(`0px 0px 0px 2px rgba(3,105,161,1)`).$ : {}),
|
|
179
|
+
}, onClick: () => {
|
|
180
|
+
onSelect(undefined, undefined);
|
|
181
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
182
|
+
setIsClearFocused(false);
|
|
183
|
+
}, "aria-label": "Remove" }, tid.clearButton, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "x", inc: typeScale === "xs" ? 2 : undefined }, void 0) }), void 0))] }), void 0)),
|
|
184
|
+
}), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: buttonRef, popoverRef: popoverRef, positionProps: overlayProps, onClose: state.close, isOpen: state.isOpen, shouldCloseOnBlur: true }, { children: (0, jsx_runtime_1.jsx)(ListBox_1.ListBox, Object.assign({}, menuProps, { listBoxRef: listBoxRef, state: state, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, positionProps: overlayProps }), void 0) }), void 0))] }, void 0));
|
|
183
185
|
}
|
|
184
186
|
exports.ChipSelectField = ChipSelectField;
|
|
185
187
|
exports.persistentItemPrefix = "persistentItem:";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import "./
|
|
3
|
-
export interface DateFieldProps {
|
|
2
|
+
import { TextFieldBaseProps } from "./TextFieldBase";
|
|
3
|
+
export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "hideLabel" | "compact"> {
|
|
4
4
|
value: Date | undefined;
|
|
5
5
|
label: string;
|
|
6
6
|
onChange: (value: Date) => void;
|
|
@@ -8,7 +8,7 @@ export interface DateFieldProps {
|
|
|
8
8
|
onBlur?: () => void;
|
|
9
9
|
/** Called when the component is in focus. */
|
|
10
10
|
onFocus?: () => void;
|
|
11
|
-
disabled?: boolean;
|
|
11
|
+
disabled?: boolean | ReactNode;
|
|
12
12
|
errorMsg?: string;
|
|
13
13
|
required?: boolean;
|
|
14
14
|
readOnly?: boolean;
|
|
@@ -16,11 +16,8 @@ export interface DateFieldProps {
|
|
|
16
16
|
/** Renders the label inside the input field, i.e. for filters. */
|
|
17
17
|
inlineLabel?: boolean;
|
|
18
18
|
placeholder?: string;
|
|
19
|
-
compact?: boolean;
|
|
20
19
|
format?: keyof typeof dateFormats;
|
|
21
20
|
iconLeft?: boolean;
|
|
22
|
-
hideLabel?: boolean;
|
|
23
|
-
borderless?: boolean;
|
|
24
21
|
}
|
|
25
22
|
export declare function DateField(props: DateFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
26
23
|
declare const dateFormats: {
|
package/dist/inputs/DateField.js
CHANGED
|
@@ -14,9 +14,8 @@ const DatePickerOverlay_1 = require("./internal/DatePickerOverlay");
|
|
|
14
14
|
const TextFieldBase_1 = require("./TextFieldBase");
|
|
15
15
|
const utils_1 = require("../utils");
|
|
16
16
|
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
17
|
-
require("./DateField.css");
|
|
18
17
|
function DateField(props) {
|
|
19
|
-
const { label, disabled
|
|
18
|
+
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly = false, format = "short", iconLeft = false, ...others } = props;
|
|
20
19
|
const inputRef = (0, react_1.useRef)(null);
|
|
21
20
|
const inputWrapRef = (0, react_1.useRef)(null);
|
|
22
21
|
const buttonRef = (0, react_1.useRef)(null);
|
|
@@ -26,6 +25,7 @@ function DateField(props) {
|
|
|
26
25
|
const dateFormat = getDateFormat(format);
|
|
27
26
|
const [inputValue, setInputValue] = (0, react_1.useState)(value ? formatDate(value, dateFormat) : "");
|
|
28
27
|
const tid = (0, utils_1.useTestIds)(props, (0, defaultTestId_1.defaultTestId)(label));
|
|
28
|
+
const isDisabled = !!disabled;
|
|
29
29
|
(0, react_1.useEffect)(() => {
|
|
30
30
|
// Avoid updating any WIP values.
|
|
31
31
|
if (!isFocused) {
|
|
@@ -35,7 +35,7 @@ function DateField(props) {
|
|
|
35
35
|
const textFieldProps = {
|
|
36
36
|
...others,
|
|
37
37
|
label,
|
|
38
|
-
isDisabled
|
|
38
|
+
isDisabled,
|
|
39
39
|
isReadOnly: readOnly,
|
|
40
40
|
"aria-haspopup": "dialog",
|
|
41
41
|
value: inputValue,
|
|
@@ -86,7 +86,7 @@ function DateField(props) {
|
|
|
86
86
|
const { triggerProps, overlayProps } = (0, react_aria_1.useOverlayTrigger)({ type: "dialog" }, state, buttonRef);
|
|
87
87
|
const { buttonProps } = (0, react_aria_1.useButton)({
|
|
88
88
|
...triggerProps,
|
|
89
|
-
isDisabled:
|
|
89
|
+
isDisabled: isDisabled || readOnly,
|
|
90
90
|
// When pressed or focused then move focus the input, which will select the text and trigger the DatePicker to open
|
|
91
91
|
onPress: () => { var _a; return (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
|
|
92
92
|
onFocus: () => { var _a; return (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
|
|
@@ -107,7 +107,7 @@ function DateField(props) {
|
|
|
107
107
|
// How do other applications handle this defined sizing? Appears they use hard coded widths depending on format, which is similar here (using `size` instead of css `width`).
|
|
108
108
|
// But would also need to allow for the input to be `fullWidth`, which is basically also what we're accomplishing here... so maybe fine?
|
|
109
109
|
const inputSize = format === "short" ? 8 : format === "medium" ? 10 : undefined;
|
|
110
|
-
const calendarButton = ((0, jsx_runtime_1.jsx)("button", Object.assign({ ref: buttonRef }, buttonProps, { disabled:
|
|
110
|
+
const calendarButton = ((0, jsx_runtime_1.jsx)("button", Object.assign({ ref: buttonRef }, buttonProps, { disabled: isDisabled, css: Css_1.Css.if(isDisabled).cursorNotAllowed.$, tabIndex: -1 }, tid.calendarButton, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "calendar", color: Css_1.Palette.Gray700 }, void 0) }), void 0));
|
|
111
111
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, textFieldProps, { readOnly: readOnly, errorMsg: errorMsg, helperText: helperText, required: required, labelProps: labelProps, inputProps: { ...triggerProps, ...inputProps, size: inputSize }, inputRef: inputRef, inputWrapRef: inputWrapRef, inlineLabel: inlineLabel, onChange: (v) => {
|
|
112
112
|
// hide the calendar if the user is manually entering the date
|
|
113
113
|
state.close();
|
|
@@ -119,7 +119,7 @@ function DateField(props) {
|
|
|
119
119
|
onChange(parsed);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
}, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton }, others), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: inputWrapRef, popoverRef: overlayRef, positionProps: { ...overlayProps, ...positionProps }, onClose: state.close, isOpen: state.isOpen }, { children: (0, jsx_runtime_1.jsx)(DatePickerOverlay_1.DatePickerOverlay, Object.assign({ state: state, value: value, positionProps: positionProps, onChange: (d) => {
|
|
122
|
+
}, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton, tooltip: isDisabled && typeof disabled !== "boolean" ? disabled : undefined }, others), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: inputWrapRef, popoverRef: overlayRef, positionProps: { ...overlayProps, ...positionProps }, onClose: state.close, isOpen: state.isOpen }, { children: (0, jsx_runtime_1.jsx)(DatePickerOverlay_1.DatePickerOverlay, Object.assign({ state: state, value: value, positionProps: positionProps, onChange: (d) => {
|
|
123
123
|
setInputValue(formatDate(d, dateFormat));
|
|
124
124
|
onChange(d);
|
|
125
125
|
} }, tid.datePicker), void 0) }), void 0))] }, void 0));
|
|
@@ -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;
|
|
@@ -12,9 +12,8 @@ const Label_1 = require("../components/Label");
|
|
|
12
12
|
const Css_1 = require("../Css");
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
14
|
const tributejs_1 = __importDefault(require("tributejs"));
|
|
15
|
-
|
|
15
|
+
// import "tributejs/dist/tribute.css";
|
|
16
16
|
require("trix/dist/trix");
|
|
17
|
-
require("trix/dist/trix.css");
|
|
18
17
|
/**
|
|
19
18
|
* Provides a simple rich text editor based on trix.
|
|
20
19
|
*
|
|
@@ -2,7 +2,7 @@ import type { NumberFieldAria } from "@react-aria/numberfield";
|
|
|
2
2
|
import { InputHTMLAttributes, LabelHTMLAttributes, MutableRefObject, ReactNode, TextareaHTMLAttributes } from "react";
|
|
3
3
|
import { Only } from "../Css";
|
|
4
4
|
import { BeamTextFieldProps, TextFieldXss } from "../interfaces";
|
|
5
|
-
interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "label" | "required" | "readOnly" | "errorMsg" | "onBlur" | "onFocus" | "helperText" | "hideLabel" | "placeholder" | "compact" | "borderless" | "xss">, Partial<Pick<BeamTextFieldProps<X>, "onChange">> {
|
|
5
|
+
export interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "label" | "required" | "readOnly" | "errorMsg" | "onBlur" | "onFocus" | "helperText" | "hideLabel" | "placeholder" | "compact" | "borderless" | "visuallyDisabled" | "xss">, Partial<Pick<BeamTextFieldProps<X>, "onChange">> {
|
|
6
6
|
labelProps?: LabelHTMLAttributes<HTMLLabelElement>;
|
|
7
7
|
inputProps: InputHTMLAttributes<HTMLInputElement> | TextareaHTMLAttributes<HTMLTextAreaElement>;
|
|
8
8
|
inputRef?: MutableRefObject<HTMLInputElement | HTMLTextAreaElement | null>;
|
|
@@ -15,6 +15,6 @@ interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "label" | "r
|
|
|
15
15
|
contrast?: boolean;
|
|
16
16
|
clearable?: boolean;
|
|
17
17
|
textAreaMinHeight?: number;
|
|
18
|
+
tooltip?: ReactNode;
|
|
18
19
|
}
|
|
19
20
|
export declare function TextFieldBase<X extends Only<TextFieldXss, X>>(props: TextFieldBaseProps<X>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
20
|
-
export {};
|
|
@@ -15,10 +15,10 @@ const defaultTestId_1 = require("../utils/defaultTestId");
|
|
|
15
15
|
const useTestIds_1 = require("../utils/useTestIds");
|
|
16
16
|
// Used by both TextField and TextArea
|
|
17
17
|
function TextFieldBase(props) {
|
|
18
|
-
var _a, _b, _c, _d, _e;
|
|
18
|
+
var _a, _b, _c, _d, _e, _f;
|
|
19
19
|
const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
|
|
20
|
-
const { label, required, labelProps, hideLabel = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.hideLabel) !== null && _a !== void 0 ? _a : false, inputProps, inputRef, inputWrapRef, groupProps, compact = (_b = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.compact) !== null && _b !== void 0 ? _b : false, errorMsg, helperText, multiline = false, readOnly, onChange, onBlur, onFocus, xss, endAdornment, startAdornment, inlineLabel, contrast = false, borderless = (_c = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.borderless) !== null && _c !== void 0 ? _c : false, textAreaMinHeight = 96, clearable = false, } = props;
|
|
21
|
-
const typeScale = (
|
|
20
|
+
const { label, required, labelProps, hideLabel = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.hideLabel) !== null && _a !== void 0 ? _a : false, inputProps, inputRef, inputWrapRef, groupProps, compact = (_b = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.compact) !== null && _b !== void 0 ? _b : false, errorMsg, helperText, multiline = false, readOnly, onChange, onBlur, onFocus, xss, endAdornment, startAdornment, inlineLabel, contrast = false, borderless = (_c = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.borderless) !== null && _c !== void 0 ? _c : false, textAreaMinHeight = 96, clearable = false, tooltip, visuallyDisabled = (_d = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.visuallyDisabled) !== null && _d !== void 0 ? _d : true, } = props;
|
|
21
|
+
const typeScale = (_e = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.typeScale) !== null && _e !== void 0 ? _e : "sm";
|
|
22
22
|
const internalProps = props.internalProps || {};
|
|
23
23
|
const { compound = false } = internalProps;
|
|
24
24
|
const errorMessageId = `${inputProps.id}-error`;
|
|
@@ -57,7 +57,9 @@ function TextFieldBase(props) {
|
|
|
57
57
|
},
|
|
58
58
|
hover: Css_1.Css.bgGray100.if(contrast).bgGray600.bGray600.$,
|
|
59
59
|
focus: borderless ? Css_1.Css.bshFocus.$ : Css_1.Css.bLightBlue700.if(contrast).bLightBlue500.$,
|
|
60
|
-
disabled:
|
|
60
|
+
disabled: visuallyDisabled
|
|
61
|
+
? Css_1.Css.cursorNotAllowed.gray400.bgGray100.if(contrast).gray500.bgGray700.$
|
|
62
|
+
: Css_1.Css.cursorNotAllowed.$,
|
|
61
63
|
error: Css_1.Css.bRed600.if(contrast).bRed400.$,
|
|
62
64
|
};
|
|
63
65
|
// Watch for each WIP change, convert empty to undefined, and call the user's onChange
|
|
@@ -81,25 +83,30 @@ function TextFieldBase(props) {
|
|
|
81
83
|
...(multiline ? Css_1.Css.fdc.aifs.childGap2.$ : Css_1.Css.truncate.$),
|
|
82
84
|
...xss,
|
|
83
85
|
}, "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
|
|
84
|
-
? (
|
|
85
|
-
: inputProps.value] }), void 0)), !readOnly &&
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
...Css_1.Css.if(multiline).aifs.px0.mhPx(textAreaMinHeight).$,
|
|
92
|
-
} }, 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: {
|
|
93
|
-
...fieldStyles.input,
|
|
86
|
+
? (_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)))
|
|
87
|
+
: inputProps.value] }), void 0)), !readOnly &&
|
|
88
|
+
(0, components_1.maybeTooltip)({
|
|
89
|
+
title: tooltip,
|
|
90
|
+
placement: "top",
|
|
91
|
+
children: ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
92
|
+
...fieldStyles.inputWrapper,
|
|
94
93
|
...(inputProps.disabled ? fieldStyles.disabled : {}),
|
|
94
|
+
...(isFocused && !readOnly ? fieldStyles.focus : {}),
|
|
95
95
|
...(isHovered && !inputProps.disabled && !readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
96
|
-
...(
|
|
97
|
-
...
|
|
98
|
-
} },
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
...(errorMsg ? fieldStyles.error : {}),
|
|
97
|
+
...Css_1.Css.if(multiline).aifs.px0.mhPx(textAreaMinHeight).$,
|
|
98
|
+
} }, 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: {
|
|
99
|
+
...fieldStyles.input,
|
|
100
|
+
...(inputProps.disabled ? fieldStyles.disabled : {}),
|
|
101
|
+
...(isHovered && !inputProps.disabled && !readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
102
|
+
...(multiline ? Css_1.Css.h100.p1.add("resize", "none").if(borderless).pPx(4).$ : Css_1.Css.truncate.$),
|
|
103
|
+
...xss,
|
|
104
|
+
} }, tid), void 0), isFocused && clearable && onChange && inputProps.value && ((0, jsx_runtime_1.jsx)(components_1.IconButton, { icon: "xCircle", color: Css_1.Palette.Gray700, onClick: () => {
|
|
105
|
+
var _a;
|
|
106
|
+
onChange(undefined);
|
|
107
|
+
// Reset focus to input element
|
|
108
|
+
(_a = fieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
109
|
+
} }, 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)),
|
|
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));
|
|
104
111
|
}
|
|
105
112
|
exports.TextFieldBase = TextFieldBase;
|