@homebound/beam 2.317.2 → 2.318.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AutoSaveIndicator.js +4 -1
- package/dist/components/BeamContext.js +4 -1
- package/dist/components/CssReset.js +25 -4
- package/dist/components/DnDGrid/useDnDGridItem.js +4 -1
- package/dist/components/IconButton.js +4 -1
- package/dist/components/Label.d.ts +2 -1
- package/dist/components/Label.js +2 -2
- package/dist/components/Modal/Modal.js +8 -2
- package/dist/components/ScrollShadows.js +6 -1
- package/dist/components/Snackbar/useSnackbar.js +4 -1
- package/dist/components/SuperDrawer/SuperDrawer.js +4 -1
- package/dist/components/SuperDrawer/useSuperDrawer.js +8 -2
- package/dist/components/Table/GridTable.js +4 -1
- package/dist/components/Table/hooks/useSetupColumnSizes.js +8 -2
- package/dist/components/internal/Menu.js +2 -0
- package/dist/components/internal/MenuItem.js +10 -0
- package/dist/hooks/usePersistedFilter.js +4 -1
- package/dist/inputs/ChipSelectField.js +4 -1
- package/dist/inputs/ChipTextField.js +4 -1
- package/dist/inputs/DateFields/DateFieldBase.js +4 -1
- package/dist/inputs/RichTextField.js +4 -1
- package/dist/inputs/TextAreaField.js +4 -28
- package/dist/inputs/TextFieldBase.js +5 -5
- package/dist/inputs/TreeSelectField/TreeOption.js +10 -0
- package/dist/inputs/TreeSelectField/TreeSelectField.js +16 -4
- package/dist/inputs/hooks/useGrowingTextField.d.ts +9 -0
- package/dist/inputs/hooks/useGrowingTextField.js +37 -0
- package/dist/inputs/internal/ComboBoxBase.d.ts +1 -0
- package/dist/inputs/internal/ComboBoxBase.js +20 -5
- package/dist/inputs/internal/ComboBoxInput.d.ts +1 -0
- package/dist/inputs/internal/ComboBoxInput.js +16 -2
- package/dist/inputs/internal/ListBox.js +4 -1
- package/dist/inputs/internal/VirtualizedOptions.js +4 -1
- package/package.json +15 -15
|
@@ -17,7 +17,10 @@ function AutoSaveIndicator({ hideOnIdle, doNotReset }) {
|
|
|
17
17
|
* state should clear before the next Indicator mounts
|
|
18
18
|
*/
|
|
19
19
|
return () => resetStatus();
|
|
20
|
-
},
|
|
20
|
+
},
|
|
21
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
22
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
23
|
+
[]);
|
|
21
24
|
switch (status) {
|
|
22
25
|
case _1.AutoSaveStatus.IDLE:
|
|
23
26
|
return hideOnIdle ? null : (0, jsx_runtime_1.jsx)(Indicator, { icon: "cloudSave" });
|
|
@@ -60,7 +60,10 @@ function BeamProvider({ children, ...presentationProps }) {
|
|
|
60
60
|
drawerCanCloseDetailsChecks,
|
|
61
61
|
sdHeaderDiv,
|
|
62
62
|
};
|
|
63
|
-
},
|
|
63
|
+
},
|
|
64
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
65
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
|
+
[modalBodyDiv, modalFooterDiv]);
|
|
64
67
|
return ((0, jsx_runtime_1.jsx)(exports.BeamContext.Provider, { value: { ...context }, children: (0, jsx_runtime_1.jsx)(PresentationContext_1.PresentationProvider, { ...presentationProps, children: (0, jsx_runtime_1.jsx)(Layout_1.RightPaneProvider, { children: (0, jsx_runtime_1.jsx)(index_1.AutoSaveStatusProvider, { children: (0, jsx_runtime_1.jsx)(SnackbarContext_1.SnackbarProvider, { children: (0, jsx_runtime_1.jsxs)(ToastContext_1.ToastProvider, { children: [(0, jsx_runtime_1.jsxs)(react_aria_1.OverlayProvider, { children: [children, modalRef.current && (0, jsx_runtime_1.jsx)(Modal_1.Modal, { ...modalRef.current })] }), (0, jsx_runtime_1.jsx)(SuperDrawer_1.SuperDrawer, {})] }) }) }) }) }) }));
|
|
65
68
|
}
|
|
66
69
|
exports.BeamProvider = BeamProvider;
|
|
@@ -118,8 +118,16 @@ Improve consistency of default fonts in all browsers. (https://github.com/sindre
|
|
|
118
118
|
*/
|
|
119
119
|
|
|
120
120
|
body {
|
|
121
|
-
font-family:
|
|
122
|
-
|
|
121
|
+
font-family:
|
|
122
|
+
system-ui,
|
|
123
|
+
-apple-system,
|
|
124
|
+
/* Firefox supports this but not yet system-ui */ "Segoe UI",
|
|
125
|
+
Roboto,
|
|
126
|
+
Helvetica,
|
|
127
|
+
Arial,
|
|
128
|
+
sans-serif,
|
|
129
|
+
"Apple Color Emoji",
|
|
130
|
+
"Segoe UI Emoji";
|
|
123
131
|
}
|
|
124
132
|
|
|
125
133
|
/*
|
|
@@ -376,8 +384,21 @@ const tailwindPreflightReset = (0, react_1.css) `
|
|
|
376
384
|
* to override it to ensure consistency even when using the default theme.
|
|
377
385
|
*/
|
|
378
386
|
html {
|
|
379
|
-
font-family:
|
|
380
|
-
|
|
387
|
+
font-family:
|
|
388
|
+
Inter,
|
|
389
|
+
ui-sans-serif,
|
|
390
|
+
system-ui,
|
|
391
|
+
-apple-system,
|
|
392
|
+
BlinkMacSystemFont,
|
|
393
|
+
"Segoe UI",
|
|
394
|
+
Roboto,
|
|
395
|
+
"Helvetica Neue",
|
|
396
|
+
Arial,
|
|
397
|
+
"Noto Sans",
|
|
398
|
+
sans-serif,
|
|
399
|
+
"Apple Color Emoji",
|
|
400
|
+
"Segoe UI Emoji",
|
|
401
|
+
"Segoe UI Symbol",
|
|
381
402
|
"Noto Color Emoji"; /* 1 */
|
|
382
403
|
line-height: 1.5; /* 2 */
|
|
383
404
|
}
|
|
@@ -25,7 +25,10 @@ function useDnDGridItem(props) {
|
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
27
|
};
|
|
28
|
-
},
|
|
28
|
+
},
|
|
29
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
30
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
|
+
[dragEl, id, itemRef]);
|
|
29
32
|
return { dragHandleProps, dragItemProps };
|
|
30
33
|
}
|
|
31
34
|
exports.useDnDGridItem = useDnDGridItem;
|
|
@@ -29,7 +29,10 @@ function IconButton(props) {
|
|
|
29
29
|
...(isHovered && (contrast ? exports.iconButtonContrastStylesHover : exports.iconButtonStylesHover)),
|
|
30
30
|
...(isFocusVisible || forceFocusStyles ? iconButtonStylesFocus : {}),
|
|
31
31
|
...(isDisabled && iconButtonStylesDisabled),
|
|
32
|
-
}),
|
|
32
|
+
}),
|
|
33
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
34
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35
|
+
[isHovered, isFocusVisible, isDisabled, compact]);
|
|
33
36
|
const iconColor = contrast ? contrastIconColor : defaultIconColor;
|
|
34
37
|
const buttonAttrs = {
|
|
35
38
|
...testIds,
|
|
@@ -5,9 +5,10 @@ interface LabelProps {
|
|
|
5
5
|
suffix?: string;
|
|
6
6
|
hidden?: boolean;
|
|
7
7
|
contrast?: boolean;
|
|
8
|
+
multiline?: boolean;
|
|
8
9
|
}
|
|
9
10
|
/** An internal helper component for rendering form labels. */
|
|
10
11
|
export declare const Label: React.MemoExoticComponent<(props: LabelProps) => import("@emotion/react/jsx-runtime").JSX.Element>;
|
|
11
12
|
/** Used for showing labels within text fields. */
|
|
12
|
-
export declare function InlineLabel({ labelProps, label, contrast, ...others }: LabelProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare function InlineLabel({ labelProps, label, contrast, multiline, ...others }: LabelProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
13
14
|
export {};
|
package/dist/components/Label.js
CHANGED
|
@@ -15,7 +15,7 @@ exports.Label = react_1.default.memo((props) => {
|
|
|
15
15
|
return hidden ? (0, jsx_runtime_1.jsx)(react_aria_1.VisuallyHidden, { children: labelEl }) : labelEl;
|
|
16
16
|
});
|
|
17
17
|
/** Used for showing labels within text fields. */
|
|
18
|
-
function InlineLabel({ labelProps, label, contrast, ...others }) {
|
|
19
|
-
return ((0, jsx_runtime_1.jsxs)("label", { ...labelProps, ...others, css: Css_1.Css.smMd.nowrap.gray900.prPx(4).add("color", "currentColor").$, children: [label, ":"] }));
|
|
18
|
+
function InlineLabel({ labelProps, label, contrast, multiline = false, ...others }) {
|
|
19
|
+
return ((0, jsx_runtime_1.jsxs)("label", { ...labelProps, ...others, css: Css_1.Css.smMd.nowrap.gray900.prPx(4).add("color", "currentColor").asc.if(multiline).asfs.pt1.$, children: [label, ":"] }));
|
|
20
20
|
}
|
|
21
21
|
exports.InlineLabel = InlineLabel;
|
|
@@ -52,7 +52,10 @@ function Modal(props) {
|
|
|
52
52
|
if (forceScrolling === undefined && !isFixedHeight) {
|
|
53
53
|
setHasScroll(target.scrollHeight > target.clientHeight);
|
|
54
54
|
}
|
|
55
|
-
},
|
|
55
|
+
},
|
|
56
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
57
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
|
+
[]),
|
|
56
59
|
});
|
|
57
60
|
// Even though we use raw-divs for the createPortal calls, we do actually need to
|
|
58
61
|
// use refs + useEffect to stitch those raw divs back into the React component tree.
|
|
@@ -60,7 +63,10 @@ function Modal(props) {
|
|
|
60
63
|
modalHeaderRef.current.appendChild(modalHeaderDiv);
|
|
61
64
|
modalBodyRef.current.appendChild(modalBodyDiv);
|
|
62
65
|
modalFooterRef.current.appendChild(modalFooterDiv);
|
|
63
|
-
},
|
|
66
|
+
},
|
|
67
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
68
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
69
|
+
[modalBodyRef, modalFooterRef, modalHeaderRef]);
|
|
64
70
|
return ((0, jsx_runtime_1.jsx)(react_aria_1.OverlayContainer, { children: (0, jsx_runtime_1.jsx)(components_1.AutoSaveStatusProvider, { children: (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.underlay.z4.$, ...underlayProps, ...testId.underlay, children: (0, jsx_runtime_1.jsx)(react_aria_1.FocusScope, { contain: true, restoreFocus: true, autoFocus: true, children: (0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.br24.bgWhite.bshModal.overflowHidden
|
|
65
71
|
.maxh("90vh")
|
|
66
72
|
.df.fdc.wPx(width)
|
|
@@ -37,9 +37,14 @@ function ScrollShadows(props) {
|
|
|
37
37
|
const boxSize = horizontal ? clientWidth : clientHeight;
|
|
38
38
|
setShowStartShadow(start > 0);
|
|
39
39
|
setShowEndShadow(start + boxSize < end);
|
|
40
|
-
},
|
|
40
|
+
},
|
|
41
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
42
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
|
+
[]);
|
|
41
44
|
// Use a ResizeObserver to update the scroll props to determine if the shadows should be shown.
|
|
42
45
|
// This executes on render and subsequent resizes which could be due to content/`children` changes (such as responses from APIs).
|
|
46
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
48
|
const onResize = (0, react_1.useCallback)(() => scrollRef.current && updateScrollProps(scrollRef.current), []);
|
|
44
49
|
(0, utils_1.useResizeObserver)({ ref: scrollRef, onResize });
|
|
45
50
|
return ((0, jsx_runtime_1.jsxs)("div", { css: src_1.Css.relative.overflowHidden
|
|
@@ -19,7 +19,10 @@ function useSnackbar() {
|
|
|
19
19
|
}
|
|
20
20
|
return returnValue;
|
|
21
21
|
});
|
|
22
|
-
},
|
|
22
|
+
},
|
|
23
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
24
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
25
|
+
[]);
|
|
23
26
|
const triggerNotice = (0, react_1.useCallback)((props) => {
|
|
24
27
|
var _a;
|
|
25
28
|
// Sets `noticeId` to the current value of `snackbarId` and then increments.
|
|
@@ -51,7 +51,10 @@ function SuperDrawer() {
|
|
|
51
51
|
if (((_a = headerRef.current) === null || _a === void 0 ? void 0 : _a.childNodes.length) === 0 && content) {
|
|
52
52
|
headerRef.current.appendChild(sdHeaderDiv);
|
|
53
53
|
}
|
|
54
|
-
},
|
|
54
|
+
},
|
|
55
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
56
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
+
[headerRef, content]);
|
|
55
58
|
return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { children: content && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.Global, { styles: { body: Css_1.Css.overflowHidden.$ } }), (0, react_1.createElement)(framer_motion_1.motion.div, { ...testId,
|
|
56
59
|
// Key is required for framer-motion animations
|
|
57
60
|
key: "superDrawer",
|
|
@@ -85,7 +85,10 @@ function useSuperDrawer() {
|
|
|
85
85
|
onClose();
|
|
86
86
|
},
|
|
87
87
|
};
|
|
88
|
-
},
|
|
88
|
+
},
|
|
89
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
90
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
91
|
+
[canCloseChecks, canCloseDetailsChecks, contentStack, modalState, openModal]);
|
|
89
92
|
// useMemo the actions separately from the dynamic isDrawerOpen value
|
|
90
93
|
const actions = (0, react_1.useMemo)(() => {
|
|
91
94
|
return {
|
|
@@ -131,7 +134,10 @@ function useSuperDrawer() {
|
|
|
131
134
|
];
|
|
132
135
|
},
|
|
133
136
|
};
|
|
134
|
-
},
|
|
137
|
+
},
|
|
138
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
139
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
140
|
+
[canCloseChecks, canCloseDetailsChecks, closeActions, contentStack]);
|
|
135
141
|
return {
|
|
136
142
|
...actions,
|
|
137
143
|
...closeActions,
|
|
@@ -105,7 +105,10 @@ function GridTable(props) {
|
|
|
105
105
|
// to avoid "Cannot update component during render" errors.
|
|
106
106
|
api.tableState.setColumns(columnsWithIds, visibleColumnsStorageKey);
|
|
107
107
|
return api;
|
|
108
|
-
},
|
|
108
|
+
},
|
|
109
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
110
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
111
|
+
[props.api]);
|
|
109
112
|
const style = (0, TableStyles_1.resolveStyles)(maybeStyle);
|
|
110
113
|
const { tableState } = api;
|
|
111
114
|
tableState.onRowSelect = onRowSelect;
|
|
@@ -43,7 +43,10 @@ function useSetupColumnSizes(style, columns, resizeRef, expandedColumnIds) {
|
|
|
43
43
|
const width = (_a = resizeRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth;
|
|
44
44
|
width && setTableAndColumnWidths(width);
|
|
45
45
|
}
|
|
46
|
-
},
|
|
46
|
+
},
|
|
47
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
48
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
49
|
+
[columns, setTableAndColumnWidths]);
|
|
47
50
|
const setTableAndColumnWidthsDebounced = (0, use_debounce_1.useDebouncedCallback)(setTableAndColumnWidths, 100);
|
|
48
51
|
const onResize = (0, react_1.useCallback)(() => {
|
|
49
52
|
const target = resizeRef.current;
|
|
@@ -56,7 +59,10 @@ function useSetupColumnSizes(style, columns, resizeRef, expandedColumnIds) {
|
|
|
56
59
|
setTableAndColumnWidthsDebounced(target.clientWidth);
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
|
-
},
|
|
62
|
+
},
|
|
63
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
64
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
65
|
+
[tableWidth, setTableAndColumnWidths, setTableAndColumnWidthsDebounced]);
|
|
60
66
|
(0, utils_1.useResizeObserver)({ ref: resizeRef, onResize });
|
|
61
67
|
return columnSizes;
|
|
62
68
|
}
|
|
@@ -59,6 +59,8 @@ function Menu(props) {
|
|
|
59
59
|
const tid = (0, utils_1.useTestIds)(props);
|
|
60
60
|
// Bulk updates of MenuItems below. If we find this to be of sluggish performance, then we can change to be more surgical in our updating.
|
|
61
61
|
// If our list of items change, update the "items" menu section. (key is based on label in `getKey` above)
|
|
62
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
63
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
62
64
|
(0, react_1.useEffect)(() => filteredTree.update("items", { label: "items", items }), [items]);
|
|
63
65
|
return ((0, jsx_runtime_1.jsx)(react_aria_1.FocusScope, { children: (0, jsx_runtime_1.jsxs)("div", {
|
|
64
66
|
// Using `max-height: inherit` allows us to take advantage of the height set on the overlay container, which updates based on the available space for the overlay within the viewport
|
|
@@ -22,10 +22,20 @@ function MenuItemImpl(props) {
|
|
|
22
22
|
const isDisabled = Boolean(disabled);
|
|
23
23
|
const isSelected = state.selectionManager.selectedKeys.has(label);
|
|
24
24
|
const isFocused = state.selectionManager.focusedKey === item.key;
|
|
25
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
26
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
25
27
|
const ref = (0, react_1.useRef)(null);
|
|
28
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
29
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
26
30
|
const history = (0, react_router_1.useHistory)();
|
|
31
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
32
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
27
33
|
const { hoverProps, isHovered } = (0, react_aria_1.useHover)({});
|
|
34
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
35
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
28
36
|
const tid = (0, utils_1.useTestIds)(props);
|
|
37
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
38
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
29
39
|
const { menuItemProps } = (0, react_aria_1.useMenuItem)({
|
|
30
40
|
key: item.key,
|
|
31
41
|
isDisabled,
|
|
@@ -36,7 +36,10 @@ function usePersistedFilter({ storageKey, filterDefs }) {
|
|
|
36
36
|
// current storedFilter, use query params filter
|
|
37
37
|
setStoredFilter(queryParamsFilter);
|
|
38
38
|
}
|
|
39
|
-
},
|
|
39
|
+
},
|
|
40
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
41
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
42
|
+
[storedFilter, setStoredFilter, setQueryParams, queryParamsFilter]);
|
|
40
43
|
return { setFilter, filter };
|
|
41
44
|
}
|
|
42
45
|
exports.usePersistedFilter = usePersistedFilter;
|
|
@@ -80,7 +80,10 @@ function ChipSelectField(props) {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
firstRender.current = false;
|
|
83
|
-
},
|
|
83
|
+
},
|
|
84
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
85
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
|
+
[options]);
|
|
84
87
|
const selectChildren = (0, react_1.useMemo)(() => listData.items.map((s) => {
|
|
85
88
|
if (isListBoxSection(s)) {
|
|
86
89
|
return ((0, jsx_runtime_1.jsx)(react_stately_1.Section, { title: s.title, items: s.options, children: (item) => {
|
|
@@ -38,7 +38,10 @@ function ChipTextField(props) {
|
|
|
38
38
|
(0, react_1.useEffect)(() => {
|
|
39
39
|
var _a;
|
|
40
40
|
autoFocus && ((_a = fieldRef.current) === null || _a === void 0 ? void 0 : _a.focus());
|
|
41
|
-
},
|
|
41
|
+
},
|
|
42
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
43
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
44
|
+
[]);
|
|
42
45
|
// React doesn't like contentEditable because it takes the children of the node out of React's scope. This is fine in this case as it is just a text value and we are managing it.
|
|
43
46
|
return ((0, jsx_runtime_1.jsx)("span", { ref: fieldRef, contentEditable: true, suppressContentEditableWarning: true, "aria-required": required, "aria-label": label, onKeyDown: (e) => {
|
|
44
47
|
if (e.key === "Enter") {
|
|
@@ -133,7 +133,10 @@ function DateFieldBase(props) {
|
|
|
133
133
|
props.onChange(undefined);
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
|
-
},
|
|
136
|
+
},
|
|
137
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
138
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
139
|
+
[isRangeMode, props.onChange]);
|
|
137
140
|
// If showing the short date format, "01/01/20", so set size to 8. If medium (Wed, Nov 23) use 10 characters (leaving out the `,` character in the count because it is so small)
|
|
138
141
|
// Otherwise the long format can be `undefined`.
|
|
139
142
|
// Setting the size attribute only impacts the fields when displayed in a container that doesn't allow the field to grow to its max width, such as in an inline container.
|
|
@@ -86,7 +86,10 @@ function RichTextField(props) {
|
|
|
86
86
|
// The <trix-editor /> web component's `trix-initialize` event may fire before a `useEffect` hook in the component is executed, making it difficult ot attach the event listener locally.
|
|
87
87
|
window.addEventListener("trix-initialize", onEditorInit);
|
|
88
88
|
return id;
|
|
89
|
-
},
|
|
89
|
+
},
|
|
90
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
91
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
92
|
+
[]);
|
|
90
93
|
(0, react_2.useEffect)(() => {
|
|
91
94
|
// If our value prop changes (without the change coming from us), reload it
|
|
92
95
|
if (!readOnly && editor && value !== currentHtml.current) {
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TextAreaField = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
-
const utils_1 = require("@react-aria/utils");
|
|
6
5
|
const react_1 = require("react");
|
|
7
6
|
const react_aria_1 = require("react-aria");
|
|
8
7
|
const components_1 = require("../components");
|
|
8
|
+
const useGrowingTextField_1 = require("./hooks/useGrowingTextField");
|
|
9
9
|
const TextFieldBase_1 = require("./TextFieldBase");
|
|
10
|
-
const
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
11
|
/** Returns a <textarea /> element that auto-adjusts height based on the field's value */
|
|
12
12
|
function TextAreaField(props) {
|
|
13
13
|
const { value = "", disabled = false, readOnly = false, onBlur, onFocus, preventNewLines, onEnter, ...otherProps } = props;
|
|
@@ -16,31 +16,7 @@ function TextAreaField(props) {
|
|
|
16
16
|
const textFieldProps = { ...otherProps, value, isDisabled, isReadOnly };
|
|
17
17
|
const inputRef = (0, react_1.useRef)(null);
|
|
18
18
|
const inputWrapRef = (0, react_1.useRef)(null);
|
|
19
|
-
|
|
20
|
-
const onHeightChange = (0, react_1.useCallback)(() => {
|
|
21
|
-
const input = inputRef.current;
|
|
22
|
-
const inputWrap = inputWrapRef.current;
|
|
23
|
-
if (input && inputWrap) {
|
|
24
|
-
const prevAlignment = input.style.alignSelf;
|
|
25
|
-
input.style.alignSelf = "start";
|
|
26
|
-
input.style.height = "auto";
|
|
27
|
-
// Adding 2px to height avoids showing the scrollbar. This is to compensate for the border due to `box-sizing: border-box;`
|
|
28
|
-
inputWrap.style.height = `${input.scrollHeight + 2}px`;
|
|
29
|
-
// Set the textarea's height back to 100% so it takes up the full `inputWrap`
|
|
30
|
-
input.style.height = "100%";
|
|
31
|
-
input.style.alignSelf = prevAlignment;
|
|
32
|
-
}
|
|
33
|
-
}, [inputRef]);
|
|
34
|
-
(0, utils_1.useLayoutEffect)(() => {
|
|
35
|
-
if (inputRef.current) {
|
|
36
|
-
// Temp hack until we can figure out a better way to ensure proper measurements when rendered through a portal (i.e. Modals)
|
|
37
|
-
if (inputRef.current.scrollHeight === 0) {
|
|
38
|
-
setTimeout(() => onHeightChange(), 0);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
onHeightChange();
|
|
42
|
-
}
|
|
43
|
-
}, [onHeightChange, value, inputRef]);
|
|
19
|
+
(0, useGrowingTextField_1.useGrowingTextField)({ inputRef, inputWrapRef, value });
|
|
44
20
|
const { labelProps, inputProps } = (0, react_aria_1.useTextField)({
|
|
45
21
|
...textFieldProps,
|
|
46
22
|
inputElementType: "textarea",
|
|
@@ -51,7 +27,7 @@ function TextAreaField(props) {
|
|
|
51
27
|
// Prevent user from typing the new line character
|
|
52
28
|
if (e.key === "Enter") {
|
|
53
29
|
e.preventDefault();
|
|
54
|
-
(0,
|
|
30
|
+
(0, utils_1.maybeCall)(onEnter);
|
|
55
31
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
56
32
|
}
|
|
57
33
|
},
|
|
@@ -101,7 +101,7 @@ function TextFieldBase(props) {
|
|
|
101
101
|
...fieldStyles.inputWrapperReadOnly,
|
|
102
102
|
...(multiline ? Css_1.Css.fdc.aifs.gap2.$ : Css_1.Css.if(wrap === false).truncate.$),
|
|
103
103
|
...xss,
|
|
104
|
-
}, "data-readonly": "true", ...tid, children: [
|
|
104
|
+
}, "data-readonly": "true", ...tid, children: [labelStyle === "inline" && label && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { multiline: multiline, labelProps: labelProps, label: label, ...tid.label })), multiline
|
|
105
105
|
? (_g = inputProps.value) === null || _g === void 0 ? void 0 : _g.split("\n\n").map((p, i) => ((0, jsx_runtime_1.jsx)("p", { 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", {})] }, j))) }, i)))
|
|
106
106
|
: inputProps.value] })) : ((0, jsx_runtime_1.jsxs)("div", { css: {
|
|
107
107
|
...fieldStyles.inputWrapper,
|
|
@@ -110,19 +110,19 @@ function TextFieldBase(props) {
|
|
|
110
110
|
...(showHover ? fieldStyles.hover : {}),
|
|
111
111
|
// Only show error styles if the field is not disabled, following the pattern that the error message is also hidden
|
|
112
112
|
...(errorMsg && !inputProps.disabled ? fieldStyles.error : {}),
|
|
113
|
-
...Css_1.Css.if(multiline).aifs.
|
|
114
|
-
}, ...hoverProps, ref: inputWrapRef, children: [
|
|
113
|
+
...Css_1.Css.if(multiline).aifs.mhPx(textAreaMinHeight).$,
|
|
114
|
+
}, ...hoverProps, ref: inputWrapRef, children: [labelStyle === "inline" && label && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { multiline: multiline, labelProps: labelProps, label: label, ...tid.label })), startAdornment && (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.asc.fs0.br4.pr1.$, children: startAdornment }), (0, jsx_runtime_1.jsx)(ElementType, { ...(0, react_aria_1.mergeProps)(inputProps, { onBlur, onFocus: onFocusChained, onChange: onDomChange }, { "aria-invalid": Boolean(errorMsg), ...(labelStyle === "hidden" ? { "aria-label": label } : {}) }), ...(errorMsg ? { "aria-errormessage": errorMessageId } : {}), ref: fieldRef, rows: multiline ? 1 : undefined, css: {
|
|
115
115
|
...fieldStyles.input,
|
|
116
116
|
...(inputProps.disabled ? fieldStyles.disabled : {}),
|
|
117
117
|
...(showHover ? fieldStyles.hover : {}),
|
|
118
|
-
...(multiline ? Css_1.Css.h100.
|
|
118
|
+
...(multiline ? Css_1.Css.h100.py1.add("resize", "none").$ : Css_1.Css.truncate.$),
|
|
119
119
|
...xss,
|
|
120
120
|
}, ...tid }), isFocused && clearable && onChange && inputProps.value && ((0, jsx_runtime_1.jsx)(components_1.IconButton, { icon: "xCircle", color: Css_1.Palette.Gray700, onClick: () => {
|
|
121
121
|
var _a;
|
|
122
122
|
onChange(undefined);
|
|
123
123
|
// Reset focus to input element
|
|
124
124
|
(_a = fieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
125
|
-
} })), errorInTooltip && errorMsg && !hideErrorMessage && ((0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.pl1.fs0.$, children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "error", color: Css_1.Palette.Red600, tooltip: errorMsg }) })),
|
|
125
|
+
} })), errorInTooltip && errorMsg && !hideErrorMessage && ((0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.asc.pl1.fs0.$, children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "error", color: Css_1.Palette.Red600, tooltip: errorMsg }) })), endAdornment && (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.asc.pl1.fs0.$, children: endAdornment })] })),
|
|
126
126
|
}), labelStyle !== "left" &&
|
|
127
127
|
(alwaysShowHelperText || (!compound && !inputProps.disabled && !inputProps.readOnly)) && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [errorMsg && !errorInTooltip && ((0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, { id: errorMessageId, errorMsg: errorMsg, hidden: hideErrorMessage, ...tid.errorMsg })), helperText && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, { helperText: helperText, ...tid.helperText })] }))] }), labelStyle === "left" &&
|
|
128
128
|
(alwaysShowHelperText ||
|
|
@@ -18,10 +18,20 @@ function TreeOption(props) {
|
|
|
18
18
|
if (!leveledOption)
|
|
19
19
|
return null;
|
|
20
20
|
const [option, level] = leveledOption;
|
|
21
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
22
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
21
23
|
const ref = (0, react_1.useRef)(null);
|
|
24
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
25
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
22
26
|
const { hoverProps, isHovered } = (0, react_aria_1.useHover)({});
|
|
27
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
28
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
23
29
|
const tid = (0, utils_1.useTestIds)(props, "treeOption");
|
|
30
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
31
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
24
32
|
const { collapsedKeys, setCollapsedKeys, getOptionValue } = (0, TreeSelectField_1.useTreeSelectFieldProvider)();
|
|
33
|
+
// TODO: validate this eslint-disable with https://app.shortcut.com/homebound-team/story/40045
|
|
34
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
25
35
|
const { optionProps, isDisabled, isFocused, isSelected } = (0, react_aria_1.useOption)({ key: item.key, shouldSelectOnPressUp: true, shouldFocusOnHover: false }, state, ref);
|
|
26
36
|
// If this item is not selected, then determine if some of its children are selected to show the indeterminate state.
|
|
27
37
|
// Note: If `isSelected` will be true if all of the children were selected. That auto-parent-selection happens in the `onSelect` callback in TreeSelectField.
|
|
@@ -40,7 +40,10 @@ function TreeSelectField(props) {
|
|
|
40
40
|
getOptionLabel = (opt) => opt.name, // if unset, assume O implements HasName
|
|
41
41
|
options, onSelect, values, defaultCollapsed = false, ...otherProps } = props;
|
|
42
42
|
const [collapsedKeys, setCollapsedKeys] = (0, react_1.useState)(Array.isArray(options) && defaultCollapsed ? options.map((o) => getOptionValue(o)) : []);
|
|
43
|
-
const contextValue = (0, react_1.useMemo)(() => ({ collapsedKeys, setCollapsedKeys, getOptionValue }),
|
|
43
|
+
const contextValue = (0, react_1.useMemo)(() => ({ collapsedKeys, setCollapsedKeys, getOptionValue }),
|
|
44
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
45
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
[collapsedKeys, setCollapsedKeys]);
|
|
44
47
|
return ((0, jsx_runtime_1.jsx)(exports.CollapsedContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsx)(TreeSelectFieldBase, { ...otherProps, options: options, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, values: values, onSelect: ({ all, leaf, root }) => {
|
|
45
48
|
onSelect({ all, leaf, root });
|
|
46
49
|
} }) }));
|
|
@@ -136,7 +139,10 @@ function TreeSelectFieldBase(props) {
|
|
|
136
139
|
}));
|
|
137
140
|
}
|
|
138
141
|
reactToCollapse.current = true;
|
|
139
|
-
},
|
|
142
|
+
},
|
|
143
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
144
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
145
|
+
[collapsedKeys]);
|
|
140
146
|
// Update the filtered options when the input value changes
|
|
141
147
|
const onInputChange = (0, react_1.useCallback)((inputValue) => {
|
|
142
148
|
setFieldState((prevState) => {
|
|
@@ -147,7 +153,10 @@ function TreeSelectFieldBase(props) {
|
|
|
147
153
|
filteredOptions: prevState.allOptions.flatMap((o) => levelOptions(o, 0, inputValue.length > 0).filter(([option]) => contains(getOptionLabel(option), inputValue))),
|
|
148
154
|
};
|
|
149
155
|
});
|
|
150
|
-
},
|
|
156
|
+
},
|
|
157
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
158
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
159
|
+
[setFieldState]);
|
|
151
160
|
// Handle loading of the options in the case that they are loaded via a Promise.
|
|
152
161
|
const maybeInitLoad = (0, react_1.useCallback)(async (options, fieldState, setFieldState) => {
|
|
153
162
|
if (!Array.isArray(options)) {
|
|
@@ -162,7 +171,10 @@ function TreeSelectFieldBase(props) {
|
|
|
162
171
|
optionsLoading: false,
|
|
163
172
|
}));
|
|
164
173
|
}
|
|
165
|
-
},
|
|
174
|
+
},
|
|
175
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
176
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
177
|
+
[]);
|
|
166
178
|
// Only on the first open of the listbox, we want to load the options if they haven't been loaded yet.
|
|
167
179
|
const firstOpen = (0, react_1.useRef)(true);
|
|
168
180
|
function onOpenChange(isOpen) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { MutableRefObject } from "react";
|
|
2
|
+
interface GrowingTextFieldProps {
|
|
3
|
+
inputRef: MutableRefObject<HTMLTextAreaElement | HTMLInputElement | null>;
|
|
4
|
+
inputWrapRef: MutableRefObject<HTMLDivElement | null>;
|
|
5
|
+
value: number | string | readonly string[] | undefined;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function useGrowingTextField({ inputRef, inputWrapRef, value, disabled }: GrowingTextFieldProps): void;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useGrowingTextField = void 0;
|
|
4
|
+
const utils_1 = require("@react-aria/utils");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
function useGrowingTextField({ inputRef, inputWrapRef, value, disabled }) {
|
|
7
|
+
// not in stately because this is so we know when to re-measure, which is a spectrum design
|
|
8
|
+
const onHeightChange = (0, react_1.useCallback)(() => {
|
|
9
|
+
if (disabled)
|
|
10
|
+
return;
|
|
11
|
+
const input = inputRef.current;
|
|
12
|
+
const inputWrap = inputWrapRef.current;
|
|
13
|
+
if (input && inputWrap) {
|
|
14
|
+
const prevAlignment = input.style.alignSelf;
|
|
15
|
+
input.style.alignSelf = "start";
|
|
16
|
+
input.style.height = "auto";
|
|
17
|
+
// Adding 2px to height avoids showing the scrollbar. This is to compensate for the border due to `box-sizing: border-box;`
|
|
18
|
+
inputWrap.style.height = `${input.scrollHeight + 2}px`;
|
|
19
|
+
// Set the textarea's height back to 100% so it takes up the full `inputWrap`
|
|
20
|
+
input.style.height = "100%";
|
|
21
|
+
input.style.alignSelf = prevAlignment;
|
|
22
|
+
}
|
|
23
|
+
}, [inputRef, disabled, inputWrapRef]);
|
|
24
|
+
(0, utils_1.useLayoutEffect)(() => {
|
|
25
|
+
if (disabled)
|
|
26
|
+
return;
|
|
27
|
+
if (inputRef.current) {
|
|
28
|
+
// Temp hack until we can figure out a better way to ensure proper measurements when rendered through a portal (i.e. Modals)
|
|
29
|
+
if (inputRef.current.scrollHeight === 0) {
|
|
30
|
+
setTimeout(() => onHeightChange(), 0);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
onHeightChange();
|
|
34
|
+
}
|
|
35
|
+
}, [onHeightChange, value, inputRef, disabled]);
|
|
36
|
+
}
|
|
37
|
+
exports.useGrowingTextField = useGrowingTextField;
|
|
@@ -50,6 +50,7 @@ export interface ComboBoxBaseProps<O, V extends Value> extends BeamFocusableProp
|
|
|
50
50
|
*/
|
|
51
51
|
unsetLabel?: string;
|
|
52
52
|
hideErrorMessage?: boolean;
|
|
53
|
+
multiline?: boolean;
|
|
53
54
|
}
|
|
54
55
|
/**
|
|
55
56
|
* Provides a non-native select/dropdown widget that allows the user to type to filter the options.
|
|
@@ -30,11 +30,20 @@ function ComboBoxBase(props) {
|
|
|
30
30
|
// Call `initializeOptions` to prepend the `unset` option if the `unsetLabel` was provided.
|
|
31
31
|
const maybeOptions = (0, react_1.useMemo)(() => initializeOptions(options, unsetLabel), [options, unsetLabel]);
|
|
32
32
|
// Memoize the callback functions and handle the `unset` option if provided.
|
|
33
|
-
const getOptionLabel = (0, react_1.useCallback)((o) => (unsetLabel && o === exports.unsetOption ? unsetLabel : props.getOptionLabel(o)),
|
|
34
|
-
|
|
33
|
+
const getOptionLabel = (0, react_1.useCallback)((o) => (unsetLabel && o === exports.unsetOption ? unsetLabel : props.getOptionLabel(o)),
|
|
34
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
[props.getOptionLabel, unsetLabel]);
|
|
37
|
+
const getOptionValue = (0, react_1.useCallback)((o) => (unsetLabel && o === exports.unsetOption ? undefined : props.getOptionValue(o)),
|
|
38
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
39
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
+
[props.getOptionValue, unsetLabel]);
|
|
35
41
|
const getOptionMenuLabel = (0, react_1.useCallback)((o) => props.getOptionMenuLabel
|
|
36
42
|
? props.getOptionMenuLabel(o, Boolean(unsetLabel) && o === exports.unsetOption)
|
|
37
|
-
: getOptionLabel(o),
|
|
43
|
+
: getOptionLabel(o),
|
|
44
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
45
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
[props.getOptionValue, unsetLabel, getOptionLabel]);
|
|
38
47
|
const { contains } = (0, react_aria_1.useFilter)({ sensitivity: "base" });
|
|
39
48
|
const isDisabled = !!disabled;
|
|
40
49
|
const isReadOnly = !!readOnly;
|
|
@@ -203,7 +212,10 @@ function ComboBoxBase(props) {
|
|
|
203
212
|
};
|
|
204
213
|
});
|
|
205
214
|
}
|
|
206
|
-
},
|
|
215
|
+
},
|
|
216
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
217
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
218
|
+
[values]);
|
|
207
219
|
(0, react_1.useEffect)(() => {
|
|
208
220
|
// When options are an array, then use them as-is.
|
|
209
221
|
// If options are an object, then use the `initial` array if the menu has not been opened
|
|
@@ -231,7 +243,10 @@ function ComboBoxBase(props) {
|
|
|
231
243
|
};
|
|
232
244
|
});
|
|
233
245
|
}
|
|
234
|
-
},
|
|
246
|
+
},
|
|
247
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
248
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
249
|
+
[maybeOptions]);
|
|
235
250
|
// For the most part, the returned props contain `aria-*` and `id` attributes for accessibility purposes.
|
|
236
251
|
const { buttonProps: triggerProps, inputProps, listBoxProps, labelProps, } = (0, react_aria_1.useComboBox)({
|
|
237
252
|
...comboBoxProps,
|
|
@@ -28,6 +28,7 @@ interface ComboBoxInputProps<O, V extends Value> extends PresentationFieldProps
|
|
|
28
28
|
resetField: VoidFunction;
|
|
29
29
|
hideErrorMessage?: boolean;
|
|
30
30
|
isTree?: boolean;
|
|
31
|
+
multiline?: boolean;
|
|
31
32
|
}
|
|
32
33
|
export declare function ComboBoxInput<O, V extends Value>(props: ComboBoxInputProps<O, V>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
33
34
|
export {};
|
|
@@ -5,20 +5,27 @@ 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 components_1 = require("../../components");
|
|
8
|
+
const PresentationContext_1 = require("../../components/PresentationContext");
|
|
8
9
|
const Css_1 = require("../../Css");
|
|
10
|
+
const useGrowingTextField_1 = require("../hooks/useGrowingTextField");
|
|
9
11
|
const TextFieldBase_1 = require("../TextFieldBase");
|
|
10
12
|
const TreeSelectField_1 = require("../TreeSelectField/TreeSelectField");
|
|
11
13
|
const utils_1 = require("../TreeSelectField/utils");
|
|
12
14
|
const utils_2 = require("../../utils");
|
|
13
15
|
function ComboBoxInput(props) {
|
|
14
|
-
const { inputProps, buttonProps, buttonRef, errorMsg, state, fieldDecoration, onBlur, onFocus, selectedOptions, getOptionValue, getOptionLabel, sizeToContent = false, contrast = false, nothingSelectedText, resetField, isTree, listBoxRef, ...otherProps } = props;
|
|
16
|
+
const { inputProps, buttonProps, buttonRef, errorMsg, state, fieldDecoration, onBlur, onFocus, selectedOptions, getOptionValue, getOptionLabel, sizeToContent = false, contrast = false, nothingSelectedText, resetField, isTree, listBoxRef, inputRef, inputWrapRef, multiline = false, ...otherProps } = props;
|
|
17
|
+
const { wrap = false } = (0, PresentationContext_1.usePresentationContext)();
|
|
18
|
+
// Allow the field to wrap whether the caller has explicitly set `multiline=true` or the `PresentationContext.wrap=true`
|
|
19
|
+
const allowWrap = wrap || multiline;
|
|
15
20
|
const { collapsedKeys, setCollapsedKeys } = (0, TreeSelectField_1.useTreeSelectFieldProvider)();
|
|
16
21
|
const [isFocused, setIsFocused] = (0, react_1.useState)(false);
|
|
17
22
|
const isMultiSelect = state.selectionManager.selectionMode === "multiple";
|
|
18
23
|
const showNumSelection = isMultiSelect && state.selectionManager.selectedKeys.size > 1;
|
|
19
24
|
// For MultiSelect only show the `fieldDecoration` when input is not in focus.
|
|
20
25
|
const showFieldDecoration = (!isMultiSelect || (isMultiSelect && !isFocused)) && fieldDecoration && selectedOptions.length === 1;
|
|
21
|
-
|
|
26
|
+
const multilineProps = allowWrap ? { textAreaMinHeight: 0, multiline: true } : {};
|
|
27
|
+
(0, useGrowingTextField_1.useGrowingTextField)({ disabled: !allowWrap, inputRef, inputWrapRef, value: inputProps.value });
|
|
28
|
+
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, { ...otherProps, ...multilineProps, inputRef: inputRef, inputWrapRef: inputWrapRef, errorMsg: errorMsg, contrast: contrast, xss: otherProps.labelStyle !== "inline" && !inputProps.readOnly ? Css_1.Css.fw5.$ : {}, startAdornment: (showNumSelection && ((0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.wPx(16).hPx(16).fs0.br100.bgBlue700.white.tinySb.df.aic.jcc.$, "data-testid": "selectedOptionsCount", children: state.selectionManager.selectedKeys.size }))) ||
|
|
22
29
|
(showFieldDecoration && fieldDecoration(selectedOptions[0])), endAdornment: !inputProps.readOnly && ((0, jsx_runtime_1.jsx)("button", { ...buttonProps, disabled: inputProps.disabled, ref: buttonRef, css: {
|
|
23
30
|
...Css_1.Css.br4.outline0.gray700.if(contrast).gray400.$,
|
|
24
31
|
...(inputProps.disabled ? Css_1.Css.cursorNotAllowed.gray400.if(contrast).gray600.$ : {}),
|
|
@@ -78,6 +85,13 @@ function ComboBoxInput(props) {
|
|
|
78
85
|
}
|
|
79
86
|
inputProps.onKeyDown && inputProps.onKeyDown(e);
|
|
80
87
|
},
|
|
88
|
+
onChange: (e) => {
|
|
89
|
+
// Prevent user from entering any content that has new line characters.
|
|
90
|
+
const target = e.target;
|
|
91
|
+
target.value = target.value.replace(/[\n\r]/g, "");
|
|
92
|
+
// Call existing onChange handler if any.
|
|
93
|
+
inputProps.onChange && inputProps.onChange(e);
|
|
94
|
+
},
|
|
81
95
|
onBlur: (e) => {
|
|
82
96
|
var _a;
|
|
83
97
|
// Do not call onBlur if readOnly or interacting within the input wrapper (such as the menu trigger button), or anything within the listbox.
|
|
@@ -51,7 +51,10 @@ function ListBox(props) {
|
|
|
51
51
|
onListHeightChange(virtuosoListHeight.current);
|
|
52
52
|
}
|
|
53
53
|
firstRender.current = false;
|
|
54
|
-
},
|
|
54
|
+
},
|
|
55
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
56
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
+
[state.selectionManager.selectedKeys.size]);
|
|
55
58
|
return ((0, jsx_runtime_1.jsxs)("div", { css: {
|
|
56
59
|
// If `horizontalLayout`, then that means `labelStyle === "left"`. In this case the label the the field both take 50% of the horizontal space.
|
|
57
60
|
// Add `w50` in that case to ensure the ListBox is only the width of the field. If the width definitions ever change, we need to update here as well.
|
|
@@ -21,7 +21,10 @@ function VirtualizedOptions(props) {
|
|
|
21
21
|
if (scrollOnFocus && virtuosoRef.current && (focusedItem === null || focusedItem === void 0 ? void 0 : focusedItem.index)) {
|
|
22
22
|
virtuosoRef.current.scrollToIndex({ index: focusedItem.index, align: "center" });
|
|
23
23
|
}
|
|
24
|
-
},
|
|
24
|
+
},
|
|
25
|
+
// TODO: validate this eslint-disable. It was automatically ignored as part of https://app.shortcut.com/homebound-team/story/40033/enable-react-hooks-exhaustive-deps-for-react-projects
|
|
26
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
27
|
+
[focusedItem]);
|
|
25
28
|
return ((0, jsx_runtime_1.jsx)(react_virtuoso_1.Virtuoso, { ref: virtuosoRef, totalListHeightChanged: onListHeightChange, totalCount: items.length, ...(process.env.NODE_ENV === "test"
|
|
26
29
|
? {
|
|
27
30
|
// We don't really need to set this, but it's handy for tests, which would
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homebound/beam",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.318.0",
|
|
4
4
|
"author": "Homebound",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -75,24 +75,24 @@
|
|
|
75
75
|
"@emotion/babel-preset-css-prop": "^11.10.0",
|
|
76
76
|
"@emotion/jest": "^11.10.5",
|
|
77
77
|
"@emotion/react": "^11.10.6",
|
|
78
|
-
"@homebound/eslint-config": "1.
|
|
78
|
+
"@homebound/eslint-config": "^1.8.0",
|
|
79
79
|
"@homebound/rtl-react-router-utils": "1.0.3",
|
|
80
80
|
"@homebound/rtl-utils": "^2.65.0",
|
|
81
81
|
"@homebound/truss": "^1.131.0",
|
|
82
82
|
"@homebound/tsconfig": "^1.0.3",
|
|
83
83
|
"@semantic-release/exec": "^6.0.3",
|
|
84
84
|
"@semantic-release/git": "^10.0.1",
|
|
85
|
-
"@storybook/addon-docs": "^7.
|
|
86
|
-
"@storybook/addon-essentials": "^7.
|
|
87
|
-
"@storybook/addon-interactions": "^7.
|
|
88
|
-
"@storybook/addon-links": "^7.
|
|
89
|
-
"@storybook/addon-mdx-gfm": "^7.
|
|
90
|
-
"@storybook/addons": "^7.
|
|
91
|
-
"@storybook/manager-api": "^7.
|
|
85
|
+
"@storybook/addon-docs": "^7.4.5",
|
|
86
|
+
"@storybook/addon-essentials": "^7.4.5",
|
|
87
|
+
"@storybook/addon-interactions": "^7.4.5",
|
|
88
|
+
"@storybook/addon-links": "^7.4.5",
|
|
89
|
+
"@storybook/addon-mdx-gfm": "^7.4.5",
|
|
90
|
+
"@storybook/addons": "^7.4.5",
|
|
91
|
+
"@storybook/manager-api": "^7.4.5",
|
|
92
92
|
"@storybook/mdx2-csf": "^1.1.0",
|
|
93
|
-
"@storybook/react": "^7.
|
|
94
|
-
"@storybook/react-vite": "^7.
|
|
95
|
-
"@storybook/testing-library": "^0.2.
|
|
93
|
+
"@storybook/react": "^7.4.5",
|
|
94
|
+
"@storybook/react-vite": "^7.4.5",
|
|
95
|
+
"@storybook/testing-library": "^0.2.1",
|
|
96
96
|
"@testing-library/jest-dom": "^6.1.2",
|
|
97
97
|
"@testing-library/react": "^14.0.0",
|
|
98
98
|
"@tsconfig/recommended": "^1.0.2",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"chromatic": "^6.17.0",
|
|
110
110
|
"conventional-changelog-conventionalcommits": "^5.0.0",
|
|
111
111
|
"eslint": "^8.12.0",
|
|
112
|
-
"eslint-plugin-storybook": "^0.6.
|
|
112
|
+
"eslint-plugin-storybook": "^0.6.14",
|
|
113
113
|
"husky": "^5.1.1",
|
|
114
114
|
"identity-obj-proxy": "^3.0.0",
|
|
115
115
|
"jest": "^29.4.3",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"react": "^18.2.0",
|
|
124
124
|
"react-dom": "^18.2.0",
|
|
125
125
|
"semantic-release": "^20.1.0",
|
|
126
|
-
"storybook": "^7.
|
|
126
|
+
"storybook": "^7.4.5",
|
|
127
127
|
"storybook-addon-designs": "beta",
|
|
128
128
|
"ts-jest": "^29.0.5",
|
|
129
129
|
"ts-node": "^10.9.1",
|
|
@@ -139,5 +139,5 @@
|
|
|
139
139
|
"@types/react": "18.0.28",
|
|
140
140
|
"react-router": "5.3.4"
|
|
141
141
|
},
|
|
142
|
-
"packageManager": "yarn@3.3
|
|
142
|
+
"packageManager": "yarn@3.6.3"
|
|
143
143
|
}
|