@trackunit/react-form-components 1.7.5 → 1.7.10
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/index.cjs.js +33 -18
- package/index.esm.js +34 -19
- package/package.json +8 -8
- package/src/components/Select/SelectMenuItem/SelectMenuItem.d.ts +8 -3
- package/src/components/Select/TagsContainer.d.ts +2 -1
- package/src/components/Select/useCustomComponents.d.ts +2 -1
- package/src/components/Select/useSelect.d.ts +7 -1
package/index.cjs.js
CHANGED
|
@@ -2051,8 +2051,13 @@ const cvaSelectMenu = cssClassVarianceUtilities.cvaMerge(["relative", "p-1", "gr
|
|
|
2051
2051
|
* @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
|
|
2052
2052
|
* @returns {ReactElement} SingleSelectMenuItem
|
|
2053
2053
|
*/
|
|
2054
|
-
const SingleSelectMenuItem = ({ label, icon, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
|
|
2055
|
-
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, focused: focused, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription,
|
|
2054
|
+
const SingleSelectMenuItem = ({ label, icon, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }) => {
|
|
2055
|
+
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, focused: focused, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription, optionPrefix: react.isValidElement(optionPrefix)
|
|
2056
|
+
? react.cloneElement(optionPrefix, {
|
|
2057
|
+
className: "mr-1 flex items-center",
|
|
2058
|
+
size: "medium",
|
|
2059
|
+
})
|
|
2060
|
+
: optionPrefix, prefix: icon, selected: selected, suffix: selected ? jsxRuntime.jsx(reactComponents.Icon, { className: "block text-blue-600", name: "Check", size: "medium" }) : undefined }));
|
|
2056
2061
|
};
|
|
2057
2062
|
/**
|
|
2058
2063
|
* A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
|
|
@@ -2060,11 +2065,16 @@ const SingleSelectMenuItem = ({ label, icon, onClick, selected, focused, dataTes
|
|
|
2060
2065
|
* @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
|
|
2061
2066
|
* @returns {ReactElement} multi select menu item
|
|
2062
2067
|
*/
|
|
2063
|
-
const MultiSelectMenuItem = ({ label, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
|
|
2068
|
+
const MultiSelectMenuItem = ({ label, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }) => {
|
|
2064
2069
|
return (jsxRuntime.jsx(reactComponents.MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, focused: focused, label: label, onClick: e => {
|
|
2065
2070
|
e.stopPropagation();
|
|
2066
2071
|
onClick && onClick(e);
|
|
2067
|
-
}, optionLabelDescription: optionLabelDescription,
|
|
2072
|
+
}, optionLabelDescription: optionLabelDescription, optionPrefix: react.isValidElement(optionPrefix)
|
|
2073
|
+
? react.cloneElement(optionPrefix, {
|
|
2074
|
+
className: "mr-1 flex items-center",
|
|
2075
|
+
size: "medium",
|
|
2076
|
+
})
|
|
2077
|
+
: optionPrefix, prefix: jsxRuntime.jsx(Checkbox, { checked: selected, className: "gap-x-0", disabled: disabled, onChange: () => null, onClick: e => {
|
|
2068
2078
|
e.stopPropagation();
|
|
2069
2079
|
}, readOnly: false }), selected: selected }));
|
|
2070
2080
|
};
|
|
@@ -2081,7 +2091,7 @@ const TagWithWidth = ({ onWidthKnown, children, ...rest }) => {
|
|
|
2081
2091
|
react.useLayoutEffect(() => {
|
|
2082
2092
|
onWidthKnown && onWidthKnown({ width: ref.current?.offsetWidth || 0 });
|
|
2083
2093
|
}, [ref, onWidthKnown]);
|
|
2084
|
-
return (jsxRuntime.jsx(reactComponents.Tag, { ref: ref, ...rest, children: children }));
|
|
2094
|
+
return (jsxRuntime.jsx(reactComponents.Tag, { ref: ref, ...rest, icon: react.isValidElement(rest.icon) ? react.cloneElement(rest.icon, { size: "small" }) : rest.icon, children: children }));
|
|
2085
2095
|
};
|
|
2086
2096
|
|
|
2087
2097
|
/**
|
|
@@ -2130,7 +2140,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
|
|
|
2130
2140
|
...acc,
|
|
2131
2141
|
elements: [
|
|
2132
2142
|
...acc.elements,
|
|
2133
|
-
jsxRuntime.jsx(TagWithWidth, { color: "white", disabled: disabled, onWidthKnown: ({ width: reportedWidth }) => setCounterWidth(reportedWidth), children: jsxRuntime.jsxs("div", { className: cvaSelectCounter(), "data-testid": "select-counter", children: ["+", acc.counter] }) }, item.text + index),
|
|
2143
|
+
jsxRuntime.jsx(TagWithWidth, { color: "white", disabled: disabled, icon: item.Icon, onWidthKnown: ({ width: reportedWidth }) => setCounterWidth(reportedWidth), children: jsxRuntime.jsxs("div", { className: cvaSelectCounter(), "data-testid": "select-counter", children: ["+", acc.counter] }) }, item.text + index),
|
|
2134
2144
|
],
|
|
2135
2145
|
};
|
|
2136
2146
|
}
|
|
@@ -2143,7 +2153,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
|
|
|
2143
2153
|
...acc,
|
|
2144
2154
|
elements: [
|
|
2145
2155
|
...acc.elements,
|
|
2146
|
-
jsxRuntime.jsx(TagWithWidth, { className: "inline-flex shrink-0", color: item.disabled ? "neutral" : "white", dataTestId: `${item.text}-tag`, disabled: disabled, onClose: e => {
|
|
2156
|
+
jsxRuntime.jsx(TagWithWidth, { className: "inline-flex shrink-0", color: item.disabled ? "neutral" : "white", dataTestId: `${item.text}-tag`, disabled: disabled, icon: item.Icon, onClose: e => {
|
|
2147
2157
|
e.stopPropagation();
|
|
2148
2158
|
item.onClick();
|
|
2149
2159
|
}, onWidthKnown: onWidthKnownHandler, children: item.text }, item.text + index),
|
|
@@ -2177,7 +2187,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
|
|
|
2177
2187
|
* @param {ReactNode} prefix a prefix element
|
|
2178
2188
|
* @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
|
|
2179
2189
|
*/
|
|
2180
|
-
const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEnabled, dataTestId, maxSelectedDisplayCount, prefix, hasError, fieldSize, getOptionLabelDescription, }) => {
|
|
2190
|
+
const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEnabled, dataTestId, maxSelectedDisplayCount, prefix, hasError, fieldSize, getOptionLabelDescription, getOptionPrefix, }) => {
|
|
2181
2191
|
const [t] = useTranslation();
|
|
2182
2192
|
// perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
|
|
2183
2193
|
const customComponents = react.useMemo(() => {
|
|
@@ -2194,6 +2204,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2194
2204
|
const searchInput = props && props.children && props.children[1];
|
|
2195
2205
|
return (jsxRuntime.jsx(ReactSelect.components.ValueContainer, { ...props, isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsxRuntime.jsx(TagsContainer, { disabled: disabled, items: tags
|
|
2196
2206
|
? tags.map(({ props: tagProps }) => {
|
|
2207
|
+
const optionPrefix = tagProps.data && getOptionPrefix ? getOptionPrefix(tagProps.data) : null;
|
|
2197
2208
|
return {
|
|
2198
2209
|
text: tagProps.children,
|
|
2199
2210
|
onClick: disabled
|
|
@@ -2203,6 +2214,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2203
2214
|
tagProps.removeProps.onClick && tagProps.removeProps.onClick(e);
|
|
2204
2215
|
},
|
|
2205
2216
|
disabled: disabled,
|
|
2217
|
+
Icon: optionPrefix,
|
|
2206
2218
|
};
|
|
2207
2219
|
})
|
|
2208
2220
|
: [], postFix: searchInput, width: "100%" })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [tags
|
|
@@ -2244,7 +2256,8 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2244
2256
|
}) }));
|
|
2245
2257
|
},
|
|
2246
2258
|
SingleValue: props => {
|
|
2247
|
-
|
|
2259
|
+
const optionPrefix = getOptionPrefix ? getOptionPrefix(props.data) : null;
|
|
2260
|
+
return (jsxRuntime.jsx(ReactSelect.components.SingleValue, { ...props, className: props.isDisabled ? "text-slate-700" : "", children: jsxRuntime.jsxs("div", { className: "flex items-center gap-1", "data-testid": dataTestId + "-singleValue", children: [optionPrefix !== null ? optionPrefix : null, props.children, getOptionLabelDescription && getOptionLabelDescription(props.data) ? (jsxRuntime.jsxs("span", { className: "text-secondary-400 ml-1", children: ["(", getOptionLabelDescription(props.data), ")"] })) : null] }) }));
|
|
2248
2261
|
},
|
|
2249
2262
|
Menu: props => {
|
|
2250
2263
|
return (jsxRuntime.jsx(ReactSelect.components.Menu, { ...props, className: cvaSelectMenuList({ menuIsOpen: props.selectProps.menuIsOpen }) }));
|
|
@@ -2277,22 +2290,23 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2277
2290
|
...props.innerProps,
|
|
2278
2291
|
role: "option",
|
|
2279
2292
|
onClick: () => { },
|
|
2280
|
-
}, children: props.isMulti ? (jsxRuntime.jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) : (jsxRuntime.jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) }));
|
|
2293
|
+
}, children: props.isMulti ? (jsxRuntime.jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data), optionPrefix: getOptionPrefix?.(props.data) })) : (jsxRuntime.jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data), optionPrefix: getOptionPrefix?.(props.data) })) }));
|
|
2281
2294
|
},
|
|
2282
2295
|
...componentsProps,
|
|
2283
2296
|
};
|
|
2284
2297
|
}, [
|
|
2285
2298
|
componentsProps,
|
|
2286
|
-
disabled,
|
|
2287
|
-
fieldSize,
|
|
2288
|
-
getOptionLabelDescription,
|
|
2289
|
-
hasError,
|
|
2290
2299
|
maxSelectedDisplayCount,
|
|
2291
|
-
|
|
2292
|
-
readOnly,
|
|
2300
|
+
disabled,
|
|
2293
2301
|
setMenuIsEnabled,
|
|
2294
|
-
|
|
2302
|
+
readOnly,
|
|
2295
2303
|
dataTestId,
|
|
2304
|
+
t,
|
|
2305
|
+
prefix,
|
|
2306
|
+
hasError,
|
|
2307
|
+
getOptionLabelDescription,
|
|
2308
|
+
fieldSize,
|
|
2309
|
+
getOptionPrefix,
|
|
2296
2310
|
]);
|
|
2297
2311
|
return customComponents;
|
|
2298
2312
|
};
|
|
@@ -2405,7 +2419,7 @@ const useCustomStyles = ({ refContainer, maxSelectedDisplayCount, styles, disabl
|
|
|
2405
2419
|
* @param {SelectProps} props - The props for the Select component
|
|
2406
2420
|
* @returns {UseSelectProps} Select component
|
|
2407
2421
|
*/
|
|
2408
|
-
const useSelect = ({ id, className, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange, getOptionLabelDescription, fieldSize = "medium", ...props }) => {
|
|
2422
|
+
const useSelect = ({ id, className, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange, getOptionLabelDescription, getOptionPrefix, fieldSize = "medium", ...props }) => {
|
|
2409
2423
|
const refContainer = react.useRef(document.createElement("div"));
|
|
2410
2424
|
const { customStyles } = useCustomStyles({
|
|
2411
2425
|
refContainer,
|
|
@@ -2427,6 +2441,7 @@ const useSelect = ({ id, className, dataTestId = "select", prefix, async, maxMen
|
|
|
2427
2441
|
hasError,
|
|
2428
2442
|
fieldSize,
|
|
2429
2443
|
getOptionLabelDescription,
|
|
2444
|
+
getOptionPrefix,
|
|
2430
2445
|
});
|
|
2431
2446
|
const menuPlacement = "auto";
|
|
2432
2447
|
const openMenuHandler = async () => {
|
package/index.esm.js
CHANGED
|
@@ -4,7 +4,7 @@ import { IconButton, Icon, Tooltip, useGeometry, useIsTextTruncated, Text, Headi
|
|
|
4
4
|
import { useCopyToClipboard } from 'usehooks-ts';
|
|
5
5
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
6
6
|
import { themeSpacing } from '@trackunit/ui-design-tokens';
|
|
7
|
-
import { forwardRef, useRef, useImperativeHandle, useMemo, useState, useCallback, useEffect, cloneElement, createContext, useContext, useLayoutEffect } from 'react';
|
|
7
|
+
import { forwardRef, useRef, useImperativeHandle, useMemo, useState, useCallback, useEffect, cloneElement, createContext, useContext, isValidElement, useLayoutEffect } from 'react';
|
|
8
8
|
import { titleCase } from 'string-ts';
|
|
9
9
|
import { uuidv4, nonNullable } from '@trackunit/shared-utils';
|
|
10
10
|
import { Temporal } from '@js-temporal/polyfill';
|
|
@@ -2050,8 +2050,13 @@ const cvaSelectMenu = cvaMerge(["relative", "p-1", "grid", "gap-1"]);
|
|
|
2050
2050
|
* @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
|
|
2051
2051
|
* @returns {ReactElement} SingleSelectMenuItem
|
|
2052
2052
|
*/
|
|
2053
|
-
const SingleSelectMenuItem = ({ label, icon, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
|
|
2054
|
-
return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, focused: focused, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription,
|
|
2053
|
+
const SingleSelectMenuItem = ({ label, icon, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }) => {
|
|
2054
|
+
return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, focused: focused, label: label, onClick: onClick, optionLabelDescription: optionLabelDescription, optionPrefix: isValidElement(optionPrefix)
|
|
2055
|
+
? cloneElement(optionPrefix, {
|
|
2056
|
+
className: "mr-1 flex items-center",
|
|
2057
|
+
size: "medium",
|
|
2058
|
+
})
|
|
2059
|
+
: optionPrefix, prefix: icon, selected: selected, suffix: selected ? jsx(Icon, { className: "block text-blue-600", name: "Check", size: "medium" }) : undefined }));
|
|
2055
2060
|
};
|
|
2056
2061
|
/**
|
|
2057
2062
|
* A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
|
|
@@ -2059,11 +2064,16 @@ const SingleSelectMenuItem = ({ label, icon, onClick, selected, focused, dataTes
|
|
|
2059
2064
|
* @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
|
|
2060
2065
|
* @returns {ReactElement} multi select menu item
|
|
2061
2066
|
*/
|
|
2062
|
-
const MultiSelectMenuItem = ({ label, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, fieldSize, }) => {
|
|
2067
|
+
const MultiSelectMenuItem = ({ label, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }) => {
|
|
2063
2068
|
return (jsx(MenuItem, { dataTestId: dataTestId, disabled: disabled, fieldSize: fieldSize, focused: focused, label: label, onClick: e => {
|
|
2064
2069
|
e.stopPropagation();
|
|
2065
2070
|
onClick && onClick(e);
|
|
2066
|
-
}, optionLabelDescription: optionLabelDescription,
|
|
2071
|
+
}, optionLabelDescription: optionLabelDescription, optionPrefix: isValidElement(optionPrefix)
|
|
2072
|
+
? cloneElement(optionPrefix, {
|
|
2073
|
+
className: "mr-1 flex items-center",
|
|
2074
|
+
size: "medium",
|
|
2075
|
+
})
|
|
2076
|
+
: optionPrefix, prefix: jsx(Checkbox, { checked: selected, className: "gap-x-0", disabled: disabled, onChange: () => null, onClick: e => {
|
|
2067
2077
|
e.stopPropagation();
|
|
2068
2078
|
}, readOnly: false }), selected: selected }));
|
|
2069
2079
|
};
|
|
@@ -2080,7 +2090,7 @@ const TagWithWidth = ({ onWidthKnown, children, ...rest }) => {
|
|
|
2080
2090
|
useLayoutEffect(() => {
|
|
2081
2091
|
onWidthKnown && onWidthKnown({ width: ref.current?.offsetWidth || 0 });
|
|
2082
2092
|
}, [ref, onWidthKnown]);
|
|
2083
|
-
return (jsx(Tag, { ref: ref, ...rest, children: children }));
|
|
2093
|
+
return (jsx(Tag, { ref: ref, ...rest, icon: isValidElement(rest.icon) ? cloneElement(rest.icon, { size: "small" }) : rest.icon, children: children }));
|
|
2084
2094
|
};
|
|
2085
2095
|
|
|
2086
2096
|
/**
|
|
@@ -2129,7 +2139,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
|
|
|
2129
2139
|
...acc,
|
|
2130
2140
|
elements: [
|
|
2131
2141
|
...acc.elements,
|
|
2132
|
-
jsx(TagWithWidth, { color: "white", disabled: disabled, onWidthKnown: ({ width: reportedWidth }) => setCounterWidth(reportedWidth), children: jsxs("div", { className: cvaSelectCounter(), "data-testid": "select-counter", children: ["+", acc.counter] }) }, item.text + index),
|
|
2142
|
+
jsx(TagWithWidth, { color: "white", disabled: disabled, icon: item.Icon, onWidthKnown: ({ width: reportedWidth }) => setCounterWidth(reportedWidth), children: jsxs("div", { className: cvaSelectCounter(), "data-testid": "select-counter", children: ["+", acc.counter] }) }, item.text + index),
|
|
2133
2143
|
],
|
|
2134
2144
|
};
|
|
2135
2145
|
}
|
|
@@ -2142,7 +2152,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
|
|
|
2142
2152
|
...acc,
|
|
2143
2153
|
elements: [
|
|
2144
2154
|
...acc.elements,
|
|
2145
|
-
jsx(TagWithWidth, { className: "inline-flex shrink-0", color: item.disabled ? "neutral" : "white", dataTestId: `${item.text}-tag`, disabled: disabled, onClose: e => {
|
|
2155
|
+
jsx(TagWithWidth, { className: "inline-flex shrink-0", color: item.disabled ? "neutral" : "white", dataTestId: `${item.text}-tag`, disabled: disabled, icon: item.Icon, onClose: e => {
|
|
2146
2156
|
e.stopPropagation();
|
|
2147
2157
|
item.onClick();
|
|
2148
2158
|
}, onWidthKnown: onWidthKnownHandler, children: item.text }, item.text + index),
|
|
@@ -2176,7 +2186,7 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 6, postFix, disabled
|
|
|
2176
2186
|
* @param {ReactNode} prefix a prefix element
|
|
2177
2187
|
* @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
|
|
2178
2188
|
*/
|
|
2179
|
-
const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEnabled, dataTestId, maxSelectedDisplayCount, prefix, hasError, fieldSize, getOptionLabelDescription, }) => {
|
|
2189
|
+
const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEnabled, dataTestId, maxSelectedDisplayCount, prefix, hasError, fieldSize, getOptionLabelDescription, getOptionPrefix, }) => {
|
|
2180
2190
|
const [t] = useTranslation();
|
|
2181
2191
|
// perhaps it should not be wrap in memo (causing some issues with opening and closing on mobiles)
|
|
2182
2192
|
const customComponents = useMemo(() => {
|
|
@@ -2193,6 +2203,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2193
2203
|
const searchInput = props && props.children && props.children[1];
|
|
2194
2204
|
return (jsx(components.ValueContainer, { ...props, isDisabled: props.selectProps.isDisabled, children: maxSelectedDisplayCount === undefined ? (jsx(TagsContainer, { disabled: disabled, items: tags
|
|
2195
2205
|
? tags.map(({ props: tagProps }) => {
|
|
2206
|
+
const optionPrefix = tagProps.data && getOptionPrefix ? getOptionPrefix(tagProps.data) : null;
|
|
2196
2207
|
return {
|
|
2197
2208
|
text: tagProps.children,
|
|
2198
2209
|
onClick: disabled
|
|
@@ -2202,6 +2213,7 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2202
2213
|
tagProps.removeProps.onClick && tagProps.removeProps.onClick(e);
|
|
2203
2214
|
},
|
|
2204
2215
|
disabled: disabled,
|
|
2216
|
+
Icon: optionPrefix,
|
|
2205
2217
|
};
|
|
2206
2218
|
})
|
|
2207
2219
|
: [], postFix: searchInput, width: "100%" })) : (jsxs(Fragment, { children: [tags
|
|
@@ -2243,7 +2255,8 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2243
2255
|
}) }));
|
|
2244
2256
|
},
|
|
2245
2257
|
SingleValue: props => {
|
|
2246
|
-
|
|
2258
|
+
const optionPrefix = getOptionPrefix ? getOptionPrefix(props.data) : null;
|
|
2259
|
+
return (jsx(components.SingleValue, { ...props, className: props.isDisabled ? "text-slate-700" : "", children: jsxs("div", { className: "flex items-center gap-1", "data-testid": dataTestId + "-singleValue", children: [optionPrefix !== null ? optionPrefix : null, props.children, getOptionLabelDescription && getOptionLabelDescription(props.data) ? (jsxs("span", { className: "text-secondary-400 ml-1", children: ["(", getOptionLabelDescription(props.data), ")"] })) : null] }) }));
|
|
2247
2260
|
},
|
|
2248
2261
|
Menu: props => {
|
|
2249
2262
|
return (jsx(components.Menu, { ...props, className: cvaSelectMenuList({ menuIsOpen: props.selectProps.menuIsOpen }) }));
|
|
@@ -2276,22 +2289,23 @@ const useCustomComponents = ({ componentsProps, disabled, readOnly, setMenuIsEna
|
|
|
2276
2289
|
...props.innerProps,
|
|
2277
2290
|
role: "option",
|
|
2278
2291
|
onClick: () => { },
|
|
2279
|
-
}, children: props.isMulti ? (jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) : (jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data) })) }));
|
|
2292
|
+
}, children: props.isMulti ? (jsx(MultiSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data), optionPrefix: getOptionPrefix?.(props.data) })) : (jsx(SingleSelectMenuItem, { ...componentProps, dataTestId: typeof props.label === "string" ? props.label : undefined, disabled: disabled || props.isDisabled, fieldSize: fieldSize, optionLabelDescription: getOptionLabelDescription?.(props.data), optionPrefix: getOptionPrefix?.(props.data) })) }));
|
|
2280
2293
|
},
|
|
2281
2294
|
...componentsProps,
|
|
2282
2295
|
};
|
|
2283
2296
|
}, [
|
|
2284
2297
|
componentsProps,
|
|
2285
|
-
disabled,
|
|
2286
|
-
fieldSize,
|
|
2287
|
-
getOptionLabelDescription,
|
|
2288
|
-
hasError,
|
|
2289
2298
|
maxSelectedDisplayCount,
|
|
2290
|
-
|
|
2291
|
-
readOnly,
|
|
2299
|
+
disabled,
|
|
2292
2300
|
setMenuIsEnabled,
|
|
2293
|
-
|
|
2301
|
+
readOnly,
|
|
2294
2302
|
dataTestId,
|
|
2303
|
+
t,
|
|
2304
|
+
prefix,
|
|
2305
|
+
hasError,
|
|
2306
|
+
getOptionLabelDescription,
|
|
2307
|
+
fieldSize,
|
|
2308
|
+
getOptionPrefix,
|
|
2295
2309
|
]);
|
|
2296
2310
|
return customComponents;
|
|
2297
2311
|
};
|
|
@@ -2404,7 +2418,7 @@ const useCustomStyles = ({ refContainer, maxSelectedDisplayCount, styles, disabl
|
|
|
2404
2418
|
* @param {SelectProps} props - The props for the Select component
|
|
2405
2419
|
* @returns {UseSelectProps} Select component
|
|
2406
2420
|
*/
|
|
2407
|
-
const useSelect = ({ id, className, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange, getOptionLabelDescription, fieldSize = "medium", ...props }) => {
|
|
2421
|
+
const useSelect = ({ id, className, dataTestId = "select", prefix, async, maxMenuHeight = 200, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix = "", onMenuOpen, onMenuClose, maxSelectedDisplayCount = undefined, isClearable = false, isSearchable = true, onMenuScrollToBottom, styles, filterOption, onInputChange, getOptionLabelDescription, getOptionPrefix, fieldSize = "medium", ...props }) => {
|
|
2408
2422
|
const refContainer = useRef(document.createElement("div"));
|
|
2409
2423
|
const { customStyles } = useCustomStyles({
|
|
2410
2424
|
refContainer,
|
|
@@ -2426,6 +2440,7 @@ const useSelect = ({ id, className, dataTestId = "select", prefix, async, maxMen
|
|
|
2426
2440
|
hasError,
|
|
2427
2441
|
fieldSize,
|
|
2428
2442
|
getOptionLabelDescription,
|
|
2443
|
+
getOptionPrefix,
|
|
2429
2444
|
});
|
|
2430
2445
|
const menuPlacement = "auto";
|
|
2431
2446
|
const openMenuHandler = async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-form-components",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.10",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"zod": "^3.23.8",
|
|
17
17
|
"react-hook-form": "7.62.0",
|
|
18
18
|
"tailwind-merge": "^2.0.0",
|
|
19
|
-
"@trackunit/css-class-variance-utilities": "1.6.
|
|
20
|
-
"@trackunit/react-components": "1.7.
|
|
21
|
-
"@trackunit/ui-icons": "1.6.
|
|
22
|
-
"@trackunit/shared-utils": "1.8.
|
|
23
|
-
"@trackunit/ui-design-tokens": "1.6.
|
|
24
|
-
"@trackunit/i18n-library-translation": "1.6.
|
|
19
|
+
"@trackunit/css-class-variance-utilities": "1.6.30",
|
|
20
|
+
"@trackunit/react-components": "1.7.41",
|
|
21
|
+
"@trackunit/ui-icons": "1.6.29",
|
|
22
|
+
"@trackunit/shared-utils": "1.8.30",
|
|
23
|
+
"@trackunit/ui-design-tokens": "1.6.31",
|
|
24
|
+
"@trackunit/i18n-library-translation": "1.6.33",
|
|
25
25
|
"string-ts": "^2.0.0",
|
|
26
|
-
"@trackunit/react-test-setup": "1.3.
|
|
26
|
+
"@trackunit/react-test-setup": "1.3.30",
|
|
27
27
|
"@js-temporal/polyfill": "^0.5.1"
|
|
28
28
|
},
|
|
29
29
|
"module": "./index.esm.js",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommonProps } from "@trackunit/react-components";
|
|
2
|
-
import { MouseEventHandler, ReactElement } from "react";
|
|
2
|
+
import { MouseEventHandler, ReactElement, ReactNode } from "react";
|
|
3
3
|
import { FormComponentSizes } from "../../../types";
|
|
4
4
|
interface SelectMenuItemProps extends CommonProps {
|
|
5
5
|
/**
|
|
@@ -29,6 +29,11 @@ interface SelectMenuItemProps extends CommonProps {
|
|
|
29
29
|
* Such as a description or a hint for the option
|
|
30
30
|
*/
|
|
31
31
|
optionLabelDescription?: string;
|
|
32
|
+
/**
|
|
33
|
+
* A React element to render before the label value itself
|
|
34
|
+
* This is typically used to render an icon.
|
|
35
|
+
*/
|
|
36
|
+
optionPrefix?: ReactNode;
|
|
32
37
|
/**
|
|
33
38
|
* The size of the selected item
|
|
34
39
|
*/
|
|
@@ -47,12 +52,12 @@ export interface SingleSelectMenuItemProps extends SelectMenuItemProps {
|
|
|
47
52
|
* @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
|
|
48
53
|
* @returns {ReactElement} SingleSelectMenuItem
|
|
49
54
|
*/
|
|
50
|
-
export declare const SingleSelectMenuItem: ({ label, icon, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, fieldSize, }: SingleSelectMenuItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
export declare const SingleSelectMenuItem: ({ label, icon, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }: SingleSelectMenuItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
51
56
|
/**
|
|
52
57
|
* A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
|
|
53
58
|
*
|
|
54
59
|
* @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
|
|
55
60
|
* @returns {ReactElement} multi select menu item
|
|
56
61
|
*/
|
|
57
|
-
export declare const MultiSelectMenuItem: ({ label, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, fieldSize, }: SelectMenuItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
62
|
+
export declare const MultiSelectMenuItem: ({ label, onClick, selected, focused, dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }: SelectMenuItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
58
63
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactElement } from "react";
|
|
1
|
+
import { ReactElement, ReactNode } from "react";
|
|
2
2
|
interface TagsContainerItem {
|
|
3
3
|
/**
|
|
4
4
|
* A text value to be passed to tags inside container
|
|
@@ -12,6 +12,7 @@ interface TagsContainerItem {
|
|
|
12
12
|
* A flag to set tags to readonly mode (without close button)
|
|
13
13
|
*/
|
|
14
14
|
disabled: boolean;
|
|
15
|
+
Icon?: ReactNode;
|
|
15
16
|
}
|
|
16
17
|
interface TagsContainerProps {
|
|
17
18
|
/**
|
|
@@ -17,7 +17,7 @@ import { FormComponentSizes } from "../../types";
|
|
|
17
17
|
* @param {ReactNode} prefix a prefix element
|
|
18
18
|
* @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
|
|
19
19
|
*/
|
|
20
|
-
export declare const useCustomComponents: <Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ componentsProps, disabled, readOnly, setMenuIsEnabled, dataTestId, maxSelectedDisplayCount, prefix, hasError, fieldSize, getOptionLabelDescription, }: {
|
|
20
|
+
export declare const useCustomComponents: <Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ componentsProps, disabled, readOnly, setMenuIsEnabled, dataTestId, maxSelectedDisplayCount, prefix, hasError, fieldSize, getOptionLabelDescription, getOptionPrefix, }: {
|
|
21
21
|
componentsProps: Partial<SelectComponents<Option, IsMulti, Group>> | undefined;
|
|
22
22
|
disabled: boolean;
|
|
23
23
|
readOnly: boolean;
|
|
@@ -28,4 +28,5 @@ export declare const useCustomComponents: <Option, IsMulti extends boolean = fal
|
|
|
28
28
|
hasError?: boolean;
|
|
29
29
|
fieldSize?: FormComponentSizes;
|
|
30
30
|
getOptionLabelDescription?: (option: Option) => string | undefined;
|
|
31
|
+
getOptionPrefix?: (option: Option) => ReactNode;
|
|
31
32
|
}) => Partial<SelectComponents<Option, IsMulti, Group>>;
|
|
@@ -122,6 +122,12 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
|
|
|
122
122
|
* @memberof SelectProps
|
|
123
123
|
*/
|
|
124
124
|
getOptionLabelDescription?: (option: Option) => string | undefined;
|
|
125
|
+
/**
|
|
126
|
+
* This callback returns
|
|
127
|
+
*
|
|
128
|
+
* @memberof SelectProps
|
|
129
|
+
*/
|
|
130
|
+
getOptionPrefix?: (option: Option) => ReactNode;
|
|
125
131
|
/**
|
|
126
132
|
* The size of the select component.
|
|
127
133
|
* Large = 40px, Medium = 32px, Small = 28px.
|
|
@@ -144,5 +150,5 @@ interface UseSelectProps<Option, IsMulti extends boolean = false, Group extends
|
|
|
144
150
|
* @param {SelectProps} props - The props for the Select component
|
|
145
151
|
* @returns {UseSelectProps} Select component
|
|
146
152
|
*/
|
|
147
|
-
export declare const useSelect: <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ id, className, dataTestId, prefix, async, maxMenuHeight, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix, onMenuOpen, onMenuClose, maxSelectedDisplayCount, isClearable, isSearchable, onMenuScrollToBottom, styles, filterOption, onInputChange, getOptionLabelDescription, fieldSize, ...props }: SelectProps<Option, IsAsync, IsMulti, Group>) => UseSelectProps<Option, IsMulti, Group>;
|
|
153
|
+
export declare const useSelect: <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ id, className, dataTestId, prefix, async, maxMenuHeight, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix, onMenuOpen, onMenuClose, maxSelectedDisplayCount, isClearable, isSearchable, onMenuScrollToBottom, styles, filterOption, onInputChange, getOptionLabelDescription, getOptionPrefix, fieldSize, ...props }: SelectProps<Option, IsAsync, IsMulti, Group>) => UseSelectProps<Option, IsMulti, Group>;
|
|
148
154
|
export {};
|