@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.
@@ -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, src_1.useTestIds)(props, label);
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: src_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: src_1.navLink }, { children: buttonContent }), void 0))) : ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonAttrs, { children: buttonContent }), void 0));
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
- if ((isDisabled && typeof disabled !== "boolean") || tooltip) {
48
- return ((0, jsx_runtime_1.jsx)(Tooltip_1.Tooltip, Object.assign({ title: isDisabled && typeof disabled !== "boolean" ? disabled : tooltip, placement: "top" }, { children: button }), void 0));
49
- }
50
- return button;
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
- if ((isDisabled && typeof disabled !== "boolean") || tooltip) {
37
- return ((0, jsx_runtime_1.jsx)(components_1.Tooltip, Object.assign({ title: isDisabled && typeof disabled !== "boolean" ? disabled : tooltip, placement: "top" }, { children: button }), void 0));
38
- }
39
- return button;
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.$;
@@ -8,6 +8,7 @@ export interface PresentationFieldProps {
8
8
  borderless?: boolean;
9
9
  compact?: boolean;
10
10
  typeScale?: Typography;
11
+ visuallyDisabled?: false;
11
12
  }
12
13
  export declare type PresentationContextProps = {
13
14
  fieldProps?: PresentationFieldProps;
@@ -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, toggleCollapse } = (0, react_1.useContext)(components_1.GridCollapseContext);
10
- const iconKey = isCollapsed ? "chevronRight" : "chevronDown";
11
- const headerIconKey = isCollapsed ? "chevronsRight" : "chevronsDown";
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: toggleCollapse, icon: isHeader ? headerIconKey : iconKey }, void 0);
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: Record<string, NestedCardStyle>;
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
- toggleCollapse(): void;
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, toggleCollapsedId] = useToggleIds(rows, persistCollapse);
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
- as,
114
- columns,
115
- row,
116
- style,
117
- rowStyles,
118
- stickyHeader,
119
- stickyOffset,
120
- isCollapsed,
121
- toggleCollapsedId,
122
- // TODO: How will this effect with memoization?
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
- toggleCollapsedId,
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
- return ((0, jsx_runtime_1.jsx)(react_virtuoso_1.Virtuoso, { ref: virtuosoRef, components: { List: VirtualRoot(style, columns, id, firstLastColumnWidth, xss) },
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, isCollapsed, toggleCollapsedId, openCards, ...others } = props;
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 currentCard = openCards && openCards.length > 0 && openCards[openCards.length - 1];
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
- const div = ((0, jsx_runtime_1.jsxs)(Row, Object.assign({ css: rowCss }, others, { children: [openCards && (0, nestedCards_1.maybeAddCardPadding)(openCards, "first", maybeStickyHeaderStyles), columns.map((column, columnIndex) => {
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
- }), openCards && (0, nestedCards_1.maybeAddCardPadding)(openCards, "final", maybeStickyHeaderStyles)] }), void 0));
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
- toggleCollapse: () => { },
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
- // Create the stable `toggleId`, i.e. we are purposefully passing an (almost) empty dep list
653
- const toggleId = (0, react_1.useCallback)((id) => {
654
- // We have different behavior when going from expand/collapse all.
655
- if (id === "header") {
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
- else {
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
- if (persistCollapse) {
690
- localStorage.setItem(persistCollapse, JSON.stringify(collapsedIds));
691
- }
692
- // Trigger a re-render
693
- setTick(collapsedIds.join(","));
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
- [rows]);
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, toggleId];
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(): NestedCardStyle[];
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: NestedCardStyle[], kind: "open" | "close"): Chrome;
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: NestedCardStyle[]): Chrome;
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(card);
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 [...this.openCards];
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].reverse().forEach((card, i) => {
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].reverse().forEach((card) => {
116
- 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);
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
- const field = ((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) => {
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, jsx_runtime_1.jsxs)("div", Object.assign({ ref: wrapperRef, css: {
164
- ...chipStyles,
165
- ...Css_1.Css.dif.relative.p0.mwPx(32).if(!value).bgGray200.$,
166
- ...(visualFocus ? Css_1.Css.bshFocus.$ : {}),
167
- ...(showInput ? Css_1.Css.dn.$ : {}),
168
- } }, { 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: {
169
- ...Css_1.Css.tl.br16.pxPx(10).pyPx(2).outline0.if(showClearButton).prPx(4).borderRadius("16px 0 0 16px").$,
170
- ...(isDisabled ? Css_1.Css.cursorNotAllowed.gray700.$ : {}),
171
- "&:hover:not(:disabled)": Css_1.Css.bgGray400.if(!value).bgGray300.$,
172
- }, 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: {
173
- ...Css_1.Css.prPx(4).borderRadius("0 16px 16px 0").outline0.$,
174
- "&:hover": Css_1.Css.bgGray400.$,
175
- ...(isClearFocused ? Css_1.Css.boxShadow(`0px 0px 0px 2px rgba(3,105,161,1)`).$ : {}),
176
- }, onClick: () => {
177
- onSelect(undefined, undefined);
178
- (0, utils_1.maybeCall)(onBlur);
179
- setIsClearFocused(false);
180
- }, "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), 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));
181
- const tooltipText = selectHookProps.isDisabled && typeof disabled !== "boolean" ? disabled : undefined;
182
- return tooltipText ? ((0, jsx_runtime_1.jsx)(components_1.Tooltip, Object.assign({ title: tooltipText, placement: "top" }, { children: field }), void 0)) : (field);
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 "./DateField.css";
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: {
@@ -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 = false, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly = false, format = "short", iconLeft = false, ...others } = props;
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: disabled,
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: disabled || readOnly,
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: disabled, css: Css_1.Css.if(disabled).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));
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;
@@ -1,6 +1,4 @@
1
- import "tributejs/dist/tribute.css";
2
1
  import "trix/dist/trix";
3
- import "trix/dist/trix.css";
4
2
  export interface RichTextFieldProps {
5
3
  /** The initial html value to show in the trix editor. */
6
4
  value: string | undefined;
@@ -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
- require("tributejs/dist/tribute.css");
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 = (_d = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.typeScale) !== null && _d !== void 0 ? _d : "sm";
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: Css_1.Css.cursorNotAllowed.gray400.bgGray100.if(contrast).gray500.bgGray700.$,
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
- ? (_e = inputProps.value) === null || _e === void 0 ? void 0 : _e.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)))
85
- : inputProps.value] }), void 0)), !readOnly && ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
86
- ...fieldStyles.inputWrapper,
87
- ...(inputProps.disabled ? fieldStyles.disabled : {}),
88
- ...(isFocused && !readOnly ? fieldStyles.focus : {}),
89
- ...(isHovered && !inputProps.disabled && !readOnly && !isFocused ? fieldStyles.hover : {}),
90
- ...(errorMsg ? fieldStyles.error : {}),
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
- ...(multiline ? Css_1.Css.h100.p1.add("resize", "none").if(borderless).pPx(4).$ : Css_1.Css.truncate.$),
97
- ...xss,
98
- } }, tid), void 0), isFocused && clearable && onChange && inputProps.value && ((0, jsx_runtime_1.jsx)(components_1.IconButton, { icon: "xCircle", color: Css_1.Palette.Gray700, onClick: () => {
99
- var _a;
100
- onChange(undefined);
101
- // Reset focus to input element
102
- (_a = fieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
103
- } }, 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)), 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));
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.91.9",
3
+ "version": "2.93.2",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",