@trackunit/react-components 0.1.64 → 0.1.65
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.js +300 -208
- package/package.json +3 -2
- package/src/components/ActionButton/ActionButton.d.ts +1 -5
- package/src/components/PhoneField/PhoneField.d.ts +28 -0
- package/src/components/PhoneInput/CountryCodeSelect.d.ts +16 -0
- package/src/components/PhoneInput/CountryCodes.d.ts +5 -0
- package/src/components/PhoneInput/PhoneInput.d.ts +17 -12
- package/src/components/index.d.ts +1 -0
package/index.js
CHANGED
|
@@ -11,12 +11,13 @@ import { DayPicker as DayPicker$1 } from 'react-day-picker';
|
|
|
11
11
|
import { enGB, enUS, da, de, cs, nl, fr, fi, hu, it, nb, pl, pt, ru, ro, es, sv, ja, th } from 'date-fns/locale';
|
|
12
12
|
import { useClickOutside } from 'react-browser-hooks';
|
|
13
13
|
import usePortal from 'react-useportal';
|
|
14
|
-
import { HelmetProvider, Helmet } from 'react-helmet-async';
|
|
15
14
|
import ReactSelect, { components } from 'react-select';
|
|
16
15
|
export { default as ValueType } from 'react-select';
|
|
17
16
|
import ReactAsyncCreatableSelect from 'react-select/async-creatable';
|
|
18
17
|
import ReactCreatableSelect from 'react-select/creatable';
|
|
19
18
|
import ReactAsyncSelect from 'react-select/async';
|
|
19
|
+
import { getCountries, getCountryCallingCode } from 'libphonenumber-js';
|
|
20
|
+
import { HelmetProvider, Helmet } from 'react-helmet-async';
|
|
20
21
|
import { color } from '@trackunit/ui-design-tokens';
|
|
21
22
|
|
|
22
23
|
const docs = {
|
|
@@ -97,7 +98,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
97
98
|
* @returns {JSX.Element} Spinner component
|
|
98
99
|
*/
|
|
99
100
|
const Spinner = ({ mode = "light", size = "medium", centering = "centered", className, containerClassName, dataTestId, }) => {
|
|
100
|
-
return (jsx(Container$
|
|
101
|
+
return (jsx(Container$a, Object.assign({ "$mode": mode, "$centering": centering, className: containerClassName }, { children: jsx(StyledSpinner$1, { "$size": size, "$mode": mode, role: "spinbutton", className: className, "data-testid": dataTestId }) })));
|
|
101
102
|
};
|
|
102
103
|
const getSpinnerStyles = () => ({ $size }) => {
|
|
103
104
|
switch ($size) {
|
|
@@ -127,7 +128,7 @@ const StyledSpinner$1 = tw.span `
|
|
|
127
128
|
${p => (p.$mode === "dark" ? tws `tu-spinner--dark` : null)}
|
|
128
129
|
${getSpinnerStyles()}
|
|
129
130
|
`;
|
|
130
|
-
const Container$
|
|
131
|
+
const Container$a = tw.div `
|
|
131
132
|
tu-spinner--container
|
|
132
133
|
${getCenteringStyles()}
|
|
133
134
|
|
|
@@ -439,7 +440,7 @@ const Alert = ({ color = "info", title, className, children, primaryAction, seco
|
|
|
439
440
|
ref && ref.current && ref.current.scrollIntoView && ref.current.scrollIntoView();
|
|
440
441
|
}
|
|
441
442
|
}, [ref, autoScroll]);
|
|
442
|
-
return (jsxs(Container$
|
|
443
|
+
return (jsxs(Container$9, Object.assign({ "$color": color, className: className, "data-testid": dataTestId, "$inline": inline, ref: ref, role: "alert" }, { children: [jsx(IconContainer$1, Object.assign({ "$inline": inline }, { children: getIconFromColor() })), jsxs(Content$1, Object.assign({ "$inline": inline }, { children: [jsxs(ContentDetails, { children: [jsx(ContentBody, { children: body }), onClose && !inline ? (jsx(CloseButtonContainer, Object.assign({ "$inline": inline }, { children: jsx(IconButton, { size: "small", variant: "transparent", color: "secondary", onClick: onClose, icon: jsx(Icon, { name: "XMarkIcon", size: "small" }), title: "Close Alert", circular: true }) }))) : null] }), (primaryAction || secondaryAction || onClose) && (jsxs(RightAligned, Object.assign({ "$inline": inline }, { children: [secondaryAction && (jsx(Button, Object.assign({ size: "small", variant: "transparent", color: getButtonColor(), onClick: secondaryAction.onClick, loading: secondaryAction === null || secondaryAction === void 0 ? void 0 : secondaryAction.loading }, { children: secondaryAction.label }))), primaryAction && (jsx(Button, Object.assign({ size: "small", color: getButtonColor(), onClick: primaryAction.onClick, loading: primaryAction === null || primaryAction === void 0 ? void 0 : primaryAction.loading }, { children: primaryAction.label }))), onClose && inline ? (jsx(CloseButtonContainer, Object.assign({ "$inline": inline }, { children: jsx(IconButton, { size: "small", variant: "transparent", color: "secondary", onClick: onClose, icon: jsx(Icon, { name: "XMarkIcon", size: "small" }), title: "Close Alert", circular: true }) }))) : null] })))] }))] })));
|
|
443
444
|
};
|
|
444
445
|
const CloseButtonContainer = tw.div `
|
|
445
446
|
${p => (p.$inline ? tws `tu-alert__close-button-container--inline` : tws `tu-alert__close-button-container`)}
|
|
@@ -453,7 +454,7 @@ const getBackgroundColor = () => ({ $color }) => {
|
|
|
453
454
|
};
|
|
454
455
|
return colors[$color];
|
|
455
456
|
};
|
|
456
|
-
const Container$
|
|
457
|
+
const Container$9 = tw.div `
|
|
457
458
|
tu-alert
|
|
458
459
|
${p => (p.$inline ? tws `tu-alert--inline` : null)}
|
|
459
460
|
${getBackgroundColor()}
|
|
@@ -654,9 +655,9 @@ const StyledDensityContainer = twx(DensityContainer) `
|
|
|
654
655
|
* @returns {JSX.Element} CardFooter component
|
|
655
656
|
*/
|
|
656
657
|
const CardFooter = ({ dataTestId, className, children, density, hideSeparator = false }) => {
|
|
657
|
-
return (jsx(Container$
|
|
658
|
+
return (jsx(Container$8, Object.assign({ dataTestId: dataTestId, className: className, "$hideSeparator": hideSeparator, density: density, direction: "row" }, { children: children })));
|
|
658
659
|
};
|
|
659
|
-
const Container$
|
|
660
|
+
const Container$8 = twx(DensityContainer) `
|
|
660
661
|
tu-card__footer-density-container
|
|
661
662
|
${p => p.$hideSeparator && tws `tu-card__footer-density-container--borderless`}
|
|
662
663
|
`;
|
|
@@ -703,13 +704,13 @@ const StyledHeading = tw.div `
|
|
|
703
704
|
* @returns {JSX.Element} CardHeader component
|
|
704
705
|
*/
|
|
705
706
|
const CardHeader = ({ heading, headingVariant = "primary", subHeading, onClose, dataTestId, className, children, accessories, density, extraClassName, hideSeparator = false, }) => {
|
|
706
|
-
return (jsx(Root$8, Object.assign({ dataTestId: dataTestId, className: className, "$hideSeparator": hideSeparator, density: density }, { children: jsxs(Container$
|
|
707
|
+
return (jsx(Root$8, Object.assign({ dataTestId: dataTestId, className: className, "$hideSeparator": hideSeparator, density: density }, { children: jsxs(Container$7, { children: [jsxs("div", Object.assign({ className: extraClassName }, { children: [jsxs(HeadingContainer$1, { children: [jsx(Heading$1, Object.assign({ className: "self-center", variant: headingVariant }, { children: heading })), accessories] }), subHeading && (jsx(Heading$1, Object.assign({ subtle: true, variant: "subtitle" }, { children: subHeading }))), children] })), onClose && (jsx(IconButton, { dataTestId: "card-header-close-button", variant: "transparent", color: "secondary", onClick: onClose, icon: jsx(Icon, { name: "XMarkIcon", size: "small" }), className: "!h-min" }))] }) })));
|
|
707
708
|
};
|
|
708
709
|
const Root$8 = twx(DensityContainer) `
|
|
709
710
|
tu-card__header-density-container
|
|
710
711
|
${p => p.$hideSeparator && tws `tu-card__header-density-container--borderless`}
|
|
711
712
|
`;
|
|
712
|
-
const Container$
|
|
713
|
+
const Container$7 = tw.div `
|
|
713
714
|
tu-card__header
|
|
714
715
|
`;
|
|
715
716
|
const HeadingContainer$1 = tw.div `
|
|
@@ -980,9 +981,9 @@ const PopoverLink = twx(Link) `
|
|
|
980
981
|
* @returns {JSX.Element} PopoverTitle component
|
|
981
982
|
*/
|
|
982
983
|
const PopoverTitle = ({ children, action, divider = false, className, dataTestId }) => {
|
|
983
|
-
return (jsxs(Container$
|
|
984
|
+
return (jsxs(Container$6, Object.assign({ "$divider": divider, className: className, "data-testid": dataTestId }, { children: [jsx(StyledText$1, Object.assign({ type: "div", subtle: true, size: "small", weight: "bold", uppercase: true }, { children: children })), action] })));
|
|
984
985
|
};
|
|
985
|
-
const Container$
|
|
986
|
+
const Container$6 = tw.div `
|
|
986
987
|
tu-popover-title-container
|
|
987
988
|
${p => p.$divider && `tu-popover-title-container--divider`}
|
|
988
989
|
`;
|
|
@@ -1320,9 +1321,9 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
|
|
|
1320
1321
|
*/
|
|
1321
1322
|
const Indicator = (_a) => {
|
|
1322
1323
|
var { dataTestId, icon, label, color = "unknown", withBackground = true, withLabel = true, ping = false } = _a, rest = __rest(_a, ["dataTestId", "icon", "label", "color", "withBackground", "withLabel", "ping"]);
|
|
1323
|
-
return (jsxs(Container$
|
|
1324
|
+
return (jsxs(Container$5, Object.assign({ "$color": color, "data-testid": dataTestId }, rest, { title: !withLabel ? label : undefined }, { children: [jsxs(IconBackground, Object.assign({ "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", "$withBackground": withBackground }, { children: [ping && jsx(Ping, { "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" }), icon] })), label !== undefined && withLabel && (jsx(Label$1, Object.assign({ "data-testid": dataTestId ? `${dataTestId}-label` : "indicator-label" }, { children: label })))] })));
|
|
1324
1325
|
};
|
|
1325
|
-
const Container$
|
|
1326
|
+
const Container$5 = tw.div `
|
|
1326
1327
|
tu-indicator
|
|
1327
1328
|
${({ $color }) => {
|
|
1328
1329
|
switch ($color) {
|
|
@@ -1405,12 +1406,12 @@ const Ping = tw.span `
|
|
|
1405
1406
|
*/
|
|
1406
1407
|
const MenuItem = ({ className, dataTestId, label, children, selected, focused, prefix, suffix, disabled, onClick, }) => {
|
|
1407
1408
|
const containerProps = useContainerProps({ className, dataTestId });
|
|
1408
|
-
return (jsxs(Container$
|
|
1409
|
+
return (jsxs(Container$4, Object.assign({}, containerProps, { onClick: e => {
|
|
1409
1410
|
e.stopPropagation();
|
|
1410
1411
|
onClick && onClick(e);
|
|
1411
1412
|
}, "$selected": selected, "$focused": focused, tabIndex: 0, "$disabled": disabled }, { children: [prefix && (jsx(Prefix, Object.assign({ "$selected": selected, "data-testid": dataTestId && `${dataTestId}-prefix` }, { children: prefix }))), children !== null && children !== void 0 ? children : jsx(Label, Object.assign({ "data-testid": dataTestId && `${dataTestId}-label` }, { children: label })), suffix && (jsx(Suffix, Object.assign({ "$selected": selected, "data-testid": dataTestId && `${dataTestId}-suffix` }, { children: suffix })))] })));
|
|
1412
1413
|
};
|
|
1413
|
-
const Container$
|
|
1414
|
+
const Container$4 = tw.div `
|
|
1414
1415
|
group tu-menu-item
|
|
1415
1416
|
${({ $selected }) => ($selected ? tws `tu-menu-item--selected ` : "tu-menu-item--unselected")}
|
|
1416
1417
|
${({ $focused }) => ($focused ? tws `tu-menu-item--focused ` : "")}
|
|
@@ -1439,9 +1440,9 @@ const MenuList = (_a) => {
|
|
|
1439
1440
|
var { dataTestId, className, children, withStickyHeader = false, showDivider = false } = _a; __rest(_a, ["dataTestId", "className", "children", "withStickyHeader", "showDivider"]);
|
|
1440
1441
|
const childrenArr = Children.toArray(children);
|
|
1441
1442
|
const isLastItem = (index) => index === childrenArr.length - 1;
|
|
1442
|
-
return (jsx(Container$
|
|
1443
|
+
return (jsx(Container$3, Object.assign({ "$withStickyHeader": withStickyHeader, "data-testid": dataTestId, className: className, tabIndex: 0 }, { children: Children.map(childrenArr, (menuItem, index) => (jsxs(Fragment, { children: [menuItem, showDivider && !isLastItem(index) && jsx(Divider, {})] }))) })));
|
|
1443
1444
|
};
|
|
1444
|
-
const Container$
|
|
1445
|
+
const Container$3 = tw.div `
|
|
1445
1446
|
tu-menu-list
|
|
1446
1447
|
${props => props.$withStickyHeader && tws `tu-menu-list--sticky-header`}
|
|
1447
1448
|
`;
|
|
@@ -1751,192 +1752,6 @@ const TextStyled = twx(Text$1) `
|
|
|
1751
1752
|
tu-pagination__text
|
|
1752
1753
|
`;
|
|
1753
1754
|
|
|
1754
|
-
/**
|
|
1755
|
-
* A Phone Input component is used for input of the type tel.
|
|
1756
|
-
*
|
|
1757
|
-
* It has an ActionButton which sends an phone call to the specified number using "tel:" link.
|
|
1758
|
-
*
|
|
1759
|
-
* Extends props of BaseInput.
|
|
1760
|
-
*
|
|
1761
|
-
* A reference to the input element is provided as the `ref` prop.
|
|
1762
|
-
* For specific input types make sure to use the corresponding input component.
|
|
1763
|
-
*/
|
|
1764
|
-
const PhoneInput = React.forwardRef((_a, ref) => {
|
|
1765
|
-
var { dataTestId, fieldSize = "medium", disableAction = false } = _a, rest = __rest(_a, ["dataTestId", "fieldSize", "disableAction"]);
|
|
1766
|
-
const [phoneNumber, setPhoneNumber] = React.useState("");
|
|
1767
|
-
const callNumber = () => {
|
|
1768
|
-
return window.open(`tel:${phoneNumber}`);
|
|
1769
|
-
};
|
|
1770
|
-
return (jsx(BaseInput, Object.assign({ ref: ref, dataTestId: dataTestId, fieldSize: fieldSize, type: "tel", onChange: e => setPhoneNumber(e.target.value), actions: !disableAction && (jsx(ActionButton, { value: phoneNumber, type: "PHONE_NUMBER", onClick: callNumber, dataTestId: dataTestId && `${dataTestId}-phoneIcon`, iconSize: fieldSize })) }, rest)));
|
|
1771
|
-
});
|
|
1772
|
-
|
|
1773
|
-
function useConfirmExit(confirmExit, when = true) {
|
|
1774
|
-
const { navigator } = useContext(UNSAFE_NavigationContext);
|
|
1775
|
-
useEffect(() => {
|
|
1776
|
-
if (!when) {
|
|
1777
|
-
return;
|
|
1778
|
-
}
|
|
1779
|
-
const push = navigator.push;
|
|
1780
|
-
navigator.push = (...args) => {
|
|
1781
|
-
const result = confirmExit();
|
|
1782
|
-
if (result !== false) {
|
|
1783
|
-
push(...args);
|
|
1784
|
-
}
|
|
1785
|
-
};
|
|
1786
|
-
return () => {
|
|
1787
|
-
navigator.push = push;
|
|
1788
|
-
};
|
|
1789
|
-
}, [navigator, confirmExit, when]);
|
|
1790
|
-
}
|
|
1791
|
-
/**
|
|
1792
|
-
* The usePrompt hook.
|
|
1793
|
-
*
|
|
1794
|
-
* @param {string} message -
|
|
1795
|
-
* @param {boolean} when -
|
|
1796
|
-
* @returns {void} void
|
|
1797
|
-
*/
|
|
1798
|
-
const usePrompt = (message, when = true) => {
|
|
1799
|
-
useEffect(() => {
|
|
1800
|
-
if (when) {
|
|
1801
|
-
window.onbeforeunload = function () {
|
|
1802
|
-
return message;
|
|
1803
|
-
};
|
|
1804
|
-
}
|
|
1805
|
-
return () => {
|
|
1806
|
-
window.onbeforeunload = null;
|
|
1807
|
-
};
|
|
1808
|
-
}, [message, when]);
|
|
1809
|
-
const confirmExit = useCallback(() => {
|
|
1810
|
-
const confirm = window.confirm(message);
|
|
1811
|
-
return confirm;
|
|
1812
|
-
}, [message]);
|
|
1813
|
-
useConfirmExit(confirmExit, when);
|
|
1814
|
-
};
|
|
1815
|
-
/**
|
|
1816
|
-
* The Prompt function.
|
|
1817
|
-
*
|
|
1818
|
-
* @param {PromptProps} Props -
|
|
1819
|
-
* @returns {void} void
|
|
1820
|
-
*/
|
|
1821
|
-
const Prompt = ({ when, message }) => {
|
|
1822
|
-
usePrompt(message, when);
|
|
1823
|
-
return null;
|
|
1824
|
-
};
|
|
1825
|
-
|
|
1826
|
-
const RadioGroupContext = React.createContext(null);
|
|
1827
|
-
|
|
1828
|
-
/**
|
|
1829
|
-
* Use radio buttons when you have a group of mutually exclusive choices and only one selection from the group is allowed.
|
|
1830
|
-
*
|
|
1831
|
-
* Radio buttons are used for mutually exclusive choices, not for multiple choices. Only one radio button can be selected at a time. When a user chooses a new item, the previous choice is automatically deselected.
|
|
1832
|
-
*
|
|
1833
|
-
* _**Do use** Radio buttons in forms, settings, or selections in a list._
|
|
1834
|
-
*
|
|
1835
|
-
* _**Do not use** Radio buttons if a user can select many option from a list, use checkboxes instead of radio buttons._
|
|
1836
|
-
*
|
|
1837
|
-
* @param {RadioGroupProps} props - The props for the RadioGroup component
|
|
1838
|
-
* @returns {JSX.Element} RadioGroup component
|
|
1839
|
-
*/
|
|
1840
|
-
const RadioGroup = ({ children, id, name, value, disabled, onChange, label, inline, className, dataTestId, isInvalid, }) => {
|
|
1841
|
-
return (jsx(FormGroup, Object.assign({ label: label, dataTestId: dataTestId && `${dataTestId}-FormGroup` }, { children: jsx(Flex, Object.assign({ "$inline": inline, className: className, "data-testid": dataTestId }, { children: jsx(RadioGroupContext.Provider, Object.assign({ value: {
|
|
1842
|
-
id,
|
|
1843
|
-
value,
|
|
1844
|
-
name: name || id,
|
|
1845
|
-
onChange,
|
|
1846
|
-
disabled,
|
|
1847
|
-
isInvalid,
|
|
1848
|
-
} }, { children: children })) })) })));
|
|
1849
|
-
};
|
|
1850
|
-
RadioGroup.displayName = "RadioGroup";
|
|
1851
|
-
const Flex = tw.div `
|
|
1852
|
-
${({ $inline }) => ($inline ? tws `tu-radiogroup--inline` : tws `tu-radiogroup`)}
|
|
1853
|
-
`;
|
|
1854
|
-
|
|
1855
|
-
/**
|
|
1856
|
-
* The RadioItem component.
|
|
1857
|
-
*
|
|
1858
|
-
* @param {RadioItemProps} props - The props for the RadioItem component
|
|
1859
|
-
* @returns {JSX.Element} RadioItem component
|
|
1860
|
-
*/
|
|
1861
|
-
const RadioItem = ({ label, value, dataTestId, className, description }) => {
|
|
1862
|
-
const groupCtx = React.useContext(RadioGroupContext);
|
|
1863
|
-
const isChecked = (groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.value) === value;
|
|
1864
|
-
return (jsxs(InputWrapper, Object.assign({ className: className, htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, "data-testid": dataTestId && `${dataTestId}-Wrapper` }, { children: [jsx(Input, { id: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, type: "radio", value: value, checked: isChecked, "$disabled": groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled, "$isInvalid": groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.isInvalid, onChange: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.onChange, "data-testid": dataTestId, "$checked": isChecked }), jsxs(LabelContainer$1, { children: [jsx(Label$2, Object.assign({ htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, dataTestId: dataTestId && `${dataTestId}-Label`, disabled: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled, isInvalid: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.isInvalid }, { children: label })), description && (jsx(Description$1, Object.assign({ htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, "data-testid": dataTestId && `${dataTestId}-Description`, "$disabled": groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled }, { children: description })))] })] })));
|
|
1865
|
-
};
|
|
1866
|
-
const InputWrapper = tw.label `tu-radioitem__wrapper`;
|
|
1867
|
-
const Input = tw.input `
|
|
1868
|
-
tu-radioitem
|
|
1869
|
-
${({ $checked }) => $checked && tws `tu-radioitem--checked`}
|
|
1870
|
-
${({ $disabled }) => $disabled && tws `tu-radioitem--disabled`}
|
|
1871
|
-
${({ $isInvalid }) => $isInvalid && tws `tu-radioitem--invalid`}
|
|
1872
|
-
`;
|
|
1873
|
-
const LabelContainer$1 = tw.div `tu-radioitem__label-container`;
|
|
1874
|
-
const Description$1 = tw.label `
|
|
1875
|
-
tu-radioitem__description
|
|
1876
|
-
${({ $disabled }) => $disabled && tws `tu-radioitem__description--disabled`}
|
|
1877
|
-
`;
|
|
1878
|
-
|
|
1879
|
-
/**
|
|
1880
|
-
* A thin wrapper around the `BaseInput` component for text input fields.
|
|
1881
|
-
*
|
|
1882
|
-
* NOTE: If shown with a label, please use the `TextField` component instead.
|
|
1883
|
-
*/
|
|
1884
|
-
const TextInput = forwardRef((props, ref) => (jsx(BaseInput, Object.assign({ ref: ref, type: "text" }, props))));
|
|
1885
|
-
|
|
1886
|
-
/**
|
|
1887
|
-
* The Search component is used to render a search input field.
|
|
1888
|
-
*
|
|
1889
|
-
* @param {SearchProps} props - The props for the Search component
|
|
1890
|
-
* @returns {JSX.Element} Search component
|
|
1891
|
-
*/
|
|
1892
|
-
const Search = (_a) => {
|
|
1893
|
-
var { className, placeholder = "Search", value, widenInputOnFocus, showBorderWhenNotInFocus = false, disabled, onKeyUp, onChange, onFocus, onBlur, name, onClear, dataTestId, autoComplete = "on", ref } = _a, rest = __rest(_a, ["className", "placeholder", "value", "widenInputOnFocus", "showBorderWhenNotInFocus", "disabled", "onKeyUp", "onChange", "onFocus", "onBlur", "name", "onClear", "dataTestId", "autoComplete", "ref"]);
|
|
1894
|
-
return (jsx(StyledTextInput, Object.assign({}, rest, { ref: ref, dataTestId: dataTestId, name: name, className: className, "$widenOnFocus": widenInputOnFocus, "$showBorderWhenNotInFocus": showBorderWhenNotInFocus, placeholder: placeholder, prefix: jsx(Icon, { name: "MagnifyingGlassIcon", size: "medium" }), suffix: onClear ? (jsx("button", Object.assign({ "data-testid": dataTestId && `${dataTestId}_suffix_component`, onClick: () => {
|
|
1895
|
-
onClear();
|
|
1896
|
-
} }, { children: jsx(Icon, { name: "XMarkIcon", size: "small" }) }))) : undefined, value: value, disabled: disabled, onChange: onChange, onKeyUp: onKeyUp, onFocus: onFocus, onBlur: onBlur, autoComplete: autoComplete })));
|
|
1897
|
-
};
|
|
1898
|
-
const StyledTextInput = twx(TextInput) `
|
|
1899
|
-
tu-search
|
|
1900
|
-
${({ $showBorderWhenNotInFocus }) => $showBorderWhenNotInFocus && tws `tu-search--border`}
|
|
1901
|
-
${({ $widenOnFocus }) => $widenOnFocus && tws `tu-search--widen-on-focus`}
|
|
1902
|
-
`;
|
|
1903
|
-
|
|
1904
|
-
/**
|
|
1905
|
-
* The Spacer component is used for adding a bit of space in the ui.
|
|
1906
|
-
*
|
|
1907
|
-
* @param {SpacerProps} props - The props for the Spacer component
|
|
1908
|
-
* @returns {JSX.Element} Spacer component
|
|
1909
|
-
*/
|
|
1910
|
-
const Spacer = ({ minHeight, border = false, dataTestId }) => {
|
|
1911
|
-
return jsx(Space, { "data-testid": dataTestId, "$minHeight": minHeight, "$border": border });
|
|
1912
|
-
};
|
|
1913
|
-
const GetSpacerHeight = () => ({ $minHeight }) => {
|
|
1914
|
-
switch ($minHeight) {
|
|
1915
|
-
case "normal":
|
|
1916
|
-
return tws `tu-spacer--normal`;
|
|
1917
|
-
case "large":
|
|
1918
|
-
return tws `tu-spacer--large`;
|
|
1919
|
-
default:
|
|
1920
|
-
return "";
|
|
1921
|
-
}
|
|
1922
|
-
};
|
|
1923
|
-
const Space = tw.div `
|
|
1924
|
-
${p => `${p.$border ? `tu-spacer--border` : null}`}
|
|
1925
|
-
${GetSpacerHeight()}
|
|
1926
|
-
`;
|
|
1927
|
-
|
|
1928
|
-
/**
|
|
1929
|
-
* The SectionHeader component is used on sections to set the section title.
|
|
1930
|
-
*
|
|
1931
|
-
* @param {SectionHeaderProps} props - The props for the section header component
|
|
1932
|
-
* @returns {JSX.Element} SectionHeader component
|
|
1933
|
-
*/
|
|
1934
|
-
const SectionHeader = ({ title, subtitle, dataTestId, addon }) => {
|
|
1935
|
-
return (jsxs(SectionHeaderContainer, { children: [jsx(HelmetProvider, { children: jsx(Helmet, { title: title }) }), jsxs(StyledFlex, { children: [jsx(Heading$1, Object.assign({ variant: "secondary", dataTestId: dataTestId }, { children: title })), addon] }), subtitle && (jsx(Heading$1, Object.assign({ variant: "subtitle", subtle: true }, { children: subtitle }))), jsx(Spacer, { minHeight: "normal" })] }));
|
|
1936
|
-
};
|
|
1937
|
-
const SectionHeaderContainer = tw.div `tu-section-header`;
|
|
1938
|
-
const StyledFlex = tw.div `tu-section-header__flex`;
|
|
1939
|
-
|
|
1940
1755
|
/**
|
|
1941
1756
|
* The SelectContainer component.
|
|
1942
1757
|
*
|
|
@@ -1944,9 +1759,9 @@ const StyledFlex = tw.div `tu-section-header__flex`;
|
|
|
1944
1759
|
* @returns {JSX.Element} SelectContainer component
|
|
1945
1760
|
*/
|
|
1946
1761
|
const SelectContainer$1 = ({ children, label, hideLabel, id, hasError, error, description, info, dataTestId, isDisabled, }) => {
|
|
1947
|
-
return (jsxs(Container$
|
|
1762
|
+
return (jsxs(Container$2, Object.assign({ "data-testid": dataTestId, "$hasError": hasError, "$isDisabled": isDisabled }, { children: [label && !hideLabel && jsx(Label$2, Object.assign({ htmlFor: id }, { children: label })), children, (hasError || info) && (jsx(InformativeText, Object.assign({ size: "small", "$hasError": hasError !== null && hasError !== void 0 ? hasError : false }, { children: hasError ? error : info })))] })));
|
|
1948
1763
|
};
|
|
1949
|
-
const Container$
|
|
1764
|
+
const Container$2 = tw.label `
|
|
1950
1765
|
tu-select__container
|
|
1951
1766
|
tu-select
|
|
1952
1767
|
${({ $hasError }) => ($hasError ? tws `tu-select--invalid` : null)}
|
|
@@ -2105,11 +1920,11 @@ const TagsContainer = ({ items, width = "100%", itemsGap = 5, postFix }) => {
|
|
|
2105
1920
|
return null;
|
|
2106
1921
|
})
|
|
2107
1922
|
.filter(element => element !== null);
|
|
2108
|
-
return (jsxs(Container, Object.assign({ style: {
|
|
1923
|
+
return (jsxs(Container$1, Object.assign({ style: {
|
|
2109
1924
|
width: `${width}`,
|
|
2110
1925
|
}, "$ready": isReady, ref: containerRef }, { children: [renderedElements, postFix] })));
|
|
2111
1926
|
};
|
|
2112
|
-
const Container = tw.div `
|
|
1927
|
+
const Container$1 = tw.div `
|
|
2113
1928
|
tu-select__dynamic-tag--container
|
|
2114
1929
|
${({ $ready }) => {
|
|
2115
1930
|
return $ready ? tws `visible` : tws `invisible`;
|
|
@@ -2380,6 +2195,283 @@ const SelectContainer = tw.div `
|
|
|
2380
2195
|
`;
|
|
2381
2196
|
Select.displayName = "Select";
|
|
2382
2197
|
|
|
2198
|
+
const COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND = ["53", "98", "211", "247", "249", "383", "850", "963"];
|
|
2199
|
+
const ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND = [
|
|
2200
|
+
"1242",
|
|
2201
|
+
"1246",
|
|
2202
|
+
"1264",
|
|
2203
|
+
"1268",
|
|
2204
|
+
"1284",
|
|
2205
|
+
"1340",
|
|
2206
|
+
"1345",
|
|
2207
|
+
"1441",
|
|
2208
|
+
"1473",
|
|
2209
|
+
"1649",
|
|
2210
|
+
"1664",
|
|
2211
|
+
"1670",
|
|
2212
|
+
"1671",
|
|
2213
|
+
"1684",
|
|
2214
|
+
"1721",
|
|
2215
|
+
"1758",
|
|
2216
|
+
"1767",
|
|
2217
|
+
"1784",
|
|
2218
|
+
"1809",
|
|
2219
|
+
"1868",
|
|
2220
|
+
"1869",
|
|
2221
|
+
"1876",
|
|
2222
|
+
"379",
|
|
2223
|
+
"5999",
|
|
2224
|
+
"881",
|
|
2225
|
+
"882",
|
|
2226
|
+
"883",
|
|
2227
|
+
];
|
|
2228
|
+
const countryCodesSet = [
|
|
2229
|
+
...new Set(getCountries().map(code => getCountryCallingCode(code))),
|
|
2230
|
+
...ADDITIONAL_COUNTRY_CODES_SUPPORTED_BY_BACKEND,
|
|
2231
|
+
]
|
|
2232
|
+
.filter(code => !COUNTRY_CODES_NOT_SUPPORTED_BY_BACKEND.includes(code))
|
|
2233
|
+
.sort((a, b) => Number(a) - Number(b));
|
|
2234
|
+
const countryCodes = countryCodesSet.map(code => ({ label: `+${code}`, value: code }));
|
|
2235
|
+
|
|
2236
|
+
/**
|
|
2237
|
+
* The CountryCodeSelect component is used to select a country code for a phone number.
|
|
2238
|
+
*
|
|
2239
|
+
* @param {CountryCodeSelectProps} props - The props for the CountryCodeSelect component
|
|
2240
|
+
* @returns {JSX.Element} CountryCodeSelect component
|
|
2241
|
+
*/
|
|
2242
|
+
const CountryCodeSelect = ({ excludedCountries, countryCode, isInvalid, setCountryCode, }) => {
|
|
2243
|
+
const [isCountryCodeMissing, setIsCountryCodeMissing] = useState(false);
|
|
2244
|
+
useEffect(() => {
|
|
2245
|
+
countryCode && setIsCountryCodeMissing(false);
|
|
2246
|
+
}, [countryCode]);
|
|
2247
|
+
const filteredCodes = countryCodes.filter(code => {
|
|
2248
|
+
return !(excludedCountries === null || excludedCountries === void 0 ? void 0 : excludedCountries.some(excludedCode => excludedCode.value === code.value));
|
|
2249
|
+
});
|
|
2250
|
+
return (jsx(Select, { className: "w-28", "aria-invalid": isCountryCodeMissing, options: filteredCodes.map(code => code), value: filteredCodes.find(({ value: currentValue }) => currentValue === countryCode), onChange: input => {
|
|
2251
|
+
setCountryCode(input === null || input === void 0 ? void 0 : input.value);
|
|
2252
|
+
}, placeholder: "+45", hasError: isCountryCodeMissing || isInvalid, maxMenuHeight: 200 }));
|
|
2253
|
+
};
|
|
2254
|
+
|
|
2255
|
+
/**
|
|
2256
|
+
* A component for inputting phone numbers with an optional action button for initiating a phone call.
|
|
2257
|
+
*
|
|
2258
|
+
* @param {string} [dataTestId] - The data test ID for the component.
|
|
2259
|
+
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
2260
|
+
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
2261
|
+
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
2262
|
+
* @returns {JSX.Element} - The PhoneInput component.
|
|
2263
|
+
*/
|
|
2264
|
+
const PhoneInput = forwardRef((_a, ref) => {
|
|
2265
|
+
var { dataTestId, isInvalid, disabled = false, fieldSize = "medium", disableAction = false } = _a, rest = __rest(_a, ["dataTestId", "isInvalid", "disabled", "fieldSize", "disableAction"]);
|
|
2266
|
+
const [phoneNumber, setPhoneNumber] = useState();
|
|
2267
|
+
const [renderAsInvalid, setRenderAsInvalid] = useState(false);
|
|
2268
|
+
const [countryCode, setCountryCode] = useState(undefined);
|
|
2269
|
+
const [isPhoneNumberInvalid, setIsPhoneNumberInvalid] = useState(false);
|
|
2270
|
+
const handlePhoneNumberChange = (e) => {
|
|
2271
|
+
const input = e.target.value;
|
|
2272
|
+
setIsPhoneNumberInvalid(!Boolean(input));
|
|
2273
|
+
setPhoneNumber(input);
|
|
2274
|
+
};
|
|
2275
|
+
useEffect(() => {
|
|
2276
|
+
setRenderAsInvalid(isInvalid || isPhoneNumberInvalid);
|
|
2277
|
+
}, [isInvalid, isPhoneNumberInvalid]);
|
|
2278
|
+
return (jsxs(Container, { children: [jsx(CountryCodeSelect, { isInvalid: renderAsInvalid, countryCode: countryCode, setCountryCode: setCountryCode }), jsx(BaseInput, Object.assign({ ref: ref, dataTestId: dataTestId, isInvalid: renderAsInvalid, fieldSize: fieldSize, type: "tel", value: phoneNumber, onChange: handlePhoneNumberChange, disabled: disabled, actions: !disableAction && (jsx(ActionButton, { disabled: !countryCode || !phoneNumber || disabled || renderAsInvalid, value: `${countryCode}${phoneNumber}`, type: "PHONE_NUMBER", dataTestId: dataTestId && `${dataTestId}-phoneIcon`, iconSize: fieldSize })) }, rest))] }));
|
|
2279
|
+
});
|
|
2280
|
+
const Container = tw.div `
|
|
2281
|
+
grid
|
|
2282
|
+
grid-cols-min-fr
|
|
2283
|
+
gap-2
|
|
2284
|
+
`;
|
|
2285
|
+
|
|
2286
|
+
/**
|
|
2287
|
+
* The PhoneField component is used to enter phone number.
|
|
2288
|
+
* It is a wrapper around the PhoneInput component and the FormGroup component.
|
|
2289
|
+
* It is used to render a phone number field with a label, a tip, a help text, a help addon and an error message.
|
|
2290
|
+
*
|
|
2291
|
+
* @param {string} [label] - The label for the component.
|
|
2292
|
+
* @param {string} [tip] - The tip for the component.
|
|
2293
|
+
* @param {string} [helpText] - The help text for the component.
|
|
2294
|
+
* @param {string} [helpAddon] - The help addon for the component.
|
|
2295
|
+
* @param {string} [errorMessage] - The error message for the component.
|
|
2296
|
+
* @param {string} [defaultValue] - The default value for the component.
|
|
2297
|
+
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
2298
|
+
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
2299
|
+
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
2300
|
+
* @returns {JSX.Element} - The PhoneField component.
|
|
2301
|
+
*/
|
|
2302
|
+
const PhoneField = forwardRef((_a, ref) => {
|
|
2303
|
+
var { label, tip, helpText, isInvalid, errorMessage, value, helpAddon, className, defaultValue, dataTestId } = _a, rest = __rest(_a, ["label", "tip", "helpText", "isInvalid", "errorMessage", "value", "helpAddon", "className", "defaultValue", "dataTestId"]);
|
|
2304
|
+
const renderAsInvalid = isInvalid || Boolean(errorMessage);
|
|
2305
|
+
return (jsx(FormGroup, Object.assign({ label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon, disabled: rest.disabled, className: className, dataTestId: dataTestId && `${dataTestId}-FormGroup` }, { children: jsx(PhoneInput, Object.assign({ value: value || defaultValue, isInvalid: renderAsInvalid }, rest)) })));
|
|
2306
|
+
});
|
|
2307
|
+
|
|
2308
|
+
function useConfirmExit(confirmExit, when = true) {
|
|
2309
|
+
const { navigator } = useContext(UNSAFE_NavigationContext);
|
|
2310
|
+
useEffect(() => {
|
|
2311
|
+
if (!when) {
|
|
2312
|
+
return;
|
|
2313
|
+
}
|
|
2314
|
+
const push = navigator.push;
|
|
2315
|
+
navigator.push = (...args) => {
|
|
2316
|
+
const result = confirmExit();
|
|
2317
|
+
if (result !== false) {
|
|
2318
|
+
push(...args);
|
|
2319
|
+
}
|
|
2320
|
+
};
|
|
2321
|
+
return () => {
|
|
2322
|
+
navigator.push = push;
|
|
2323
|
+
};
|
|
2324
|
+
}, [navigator, confirmExit, when]);
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* The usePrompt hook.
|
|
2328
|
+
*
|
|
2329
|
+
* @param {string} message -
|
|
2330
|
+
* @param {boolean} when -
|
|
2331
|
+
* @returns {void} void
|
|
2332
|
+
*/
|
|
2333
|
+
const usePrompt = (message, when = true) => {
|
|
2334
|
+
useEffect(() => {
|
|
2335
|
+
if (when) {
|
|
2336
|
+
window.onbeforeunload = function () {
|
|
2337
|
+
return message;
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
return () => {
|
|
2341
|
+
window.onbeforeunload = null;
|
|
2342
|
+
};
|
|
2343
|
+
}, [message, when]);
|
|
2344
|
+
const confirmExit = useCallback(() => {
|
|
2345
|
+
const confirm = window.confirm(message);
|
|
2346
|
+
return confirm;
|
|
2347
|
+
}, [message]);
|
|
2348
|
+
useConfirmExit(confirmExit, when);
|
|
2349
|
+
};
|
|
2350
|
+
/**
|
|
2351
|
+
* The Prompt function.
|
|
2352
|
+
*
|
|
2353
|
+
* @param {PromptProps} Props -
|
|
2354
|
+
* @returns {void} void
|
|
2355
|
+
*/
|
|
2356
|
+
const Prompt = ({ when, message }) => {
|
|
2357
|
+
usePrompt(message, when);
|
|
2358
|
+
return null;
|
|
2359
|
+
};
|
|
2360
|
+
|
|
2361
|
+
const RadioGroupContext = React.createContext(null);
|
|
2362
|
+
|
|
2363
|
+
/**
|
|
2364
|
+
* Use radio buttons when you have a group of mutually exclusive choices and only one selection from the group is allowed.
|
|
2365
|
+
*
|
|
2366
|
+
* Radio buttons are used for mutually exclusive choices, not for multiple choices. Only one radio button can be selected at a time. When a user chooses a new item, the previous choice is automatically deselected.
|
|
2367
|
+
*
|
|
2368
|
+
* _**Do use** Radio buttons in forms, settings, or selections in a list._
|
|
2369
|
+
*
|
|
2370
|
+
* _**Do not use** Radio buttons if a user can select many option from a list, use checkboxes instead of radio buttons._
|
|
2371
|
+
*
|
|
2372
|
+
* @param {RadioGroupProps} props - The props for the RadioGroup component
|
|
2373
|
+
* @returns {JSX.Element} RadioGroup component
|
|
2374
|
+
*/
|
|
2375
|
+
const RadioGroup = ({ children, id, name, value, disabled, onChange, label, inline, className, dataTestId, isInvalid, }) => {
|
|
2376
|
+
return (jsx(FormGroup, Object.assign({ label: label, dataTestId: dataTestId && `${dataTestId}-FormGroup` }, { children: jsx(Flex, Object.assign({ "$inline": inline, className: className, "data-testid": dataTestId }, { children: jsx(RadioGroupContext.Provider, Object.assign({ value: {
|
|
2377
|
+
id,
|
|
2378
|
+
value,
|
|
2379
|
+
name: name || id,
|
|
2380
|
+
onChange,
|
|
2381
|
+
disabled,
|
|
2382
|
+
isInvalid,
|
|
2383
|
+
} }, { children: children })) })) })));
|
|
2384
|
+
};
|
|
2385
|
+
RadioGroup.displayName = "RadioGroup";
|
|
2386
|
+
const Flex = tw.div `
|
|
2387
|
+
${({ $inline }) => ($inline ? tws `tu-radiogroup--inline` : tws `tu-radiogroup`)}
|
|
2388
|
+
`;
|
|
2389
|
+
|
|
2390
|
+
/**
|
|
2391
|
+
* The RadioItem component.
|
|
2392
|
+
*
|
|
2393
|
+
* @param {RadioItemProps} props - The props for the RadioItem component
|
|
2394
|
+
* @returns {JSX.Element} RadioItem component
|
|
2395
|
+
*/
|
|
2396
|
+
const RadioItem = ({ label, value, dataTestId, className, description }) => {
|
|
2397
|
+
const groupCtx = React.useContext(RadioGroupContext);
|
|
2398
|
+
const isChecked = (groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.value) === value;
|
|
2399
|
+
return (jsxs(InputWrapper, Object.assign({ className: className, htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, "data-testid": dataTestId && `${dataTestId}-Wrapper` }, { children: [jsx(Input, { id: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, type: "radio", value: value, checked: isChecked, "$disabled": groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled, "$isInvalid": groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.isInvalid, onChange: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.onChange, "data-testid": dataTestId, "$checked": isChecked }), jsxs(LabelContainer$1, { children: [jsx(Label$2, Object.assign({ htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, dataTestId: dataTestId && `${dataTestId}-Label`, disabled: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled, isInvalid: groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.isInvalid }, { children: label })), description && (jsx(Description$1, Object.assign({ htmlFor: `${groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.id} ${label}`, "data-testid": dataTestId && `${dataTestId}-Description`, "$disabled": groupCtx === null || groupCtx === void 0 ? void 0 : groupCtx.disabled }, { children: description })))] })] })));
|
|
2400
|
+
};
|
|
2401
|
+
const InputWrapper = tw.label `tu-radioitem__wrapper`;
|
|
2402
|
+
const Input = tw.input `
|
|
2403
|
+
tu-radioitem
|
|
2404
|
+
${({ $checked }) => $checked && tws `tu-radioitem--checked`}
|
|
2405
|
+
${({ $disabled }) => $disabled && tws `tu-radioitem--disabled`}
|
|
2406
|
+
${({ $isInvalid }) => $isInvalid && tws `tu-radioitem--invalid`}
|
|
2407
|
+
`;
|
|
2408
|
+
const LabelContainer$1 = tw.div `tu-radioitem__label-container`;
|
|
2409
|
+
const Description$1 = tw.label `
|
|
2410
|
+
tu-radioitem__description
|
|
2411
|
+
${({ $disabled }) => $disabled && tws `tu-radioitem__description--disabled`}
|
|
2412
|
+
`;
|
|
2413
|
+
|
|
2414
|
+
/**
|
|
2415
|
+
* A thin wrapper around the `BaseInput` component for text input fields.
|
|
2416
|
+
*
|
|
2417
|
+
* NOTE: If shown with a label, please use the `TextField` component instead.
|
|
2418
|
+
*/
|
|
2419
|
+
const TextInput = forwardRef((props, ref) => (jsx(BaseInput, Object.assign({ ref: ref, type: "text" }, props))));
|
|
2420
|
+
|
|
2421
|
+
/**
|
|
2422
|
+
* The Search component is used to render a search input field.
|
|
2423
|
+
*
|
|
2424
|
+
* @param {SearchProps} props - The props for the Search component
|
|
2425
|
+
* @returns {JSX.Element} Search component
|
|
2426
|
+
*/
|
|
2427
|
+
const Search = (_a) => {
|
|
2428
|
+
var { className, placeholder = "Search", value, widenInputOnFocus, showBorderWhenNotInFocus = false, disabled, onKeyUp, onChange, onFocus, onBlur, name, onClear, dataTestId, autoComplete = "on", ref } = _a, rest = __rest(_a, ["className", "placeholder", "value", "widenInputOnFocus", "showBorderWhenNotInFocus", "disabled", "onKeyUp", "onChange", "onFocus", "onBlur", "name", "onClear", "dataTestId", "autoComplete", "ref"]);
|
|
2429
|
+
return (jsx(StyledTextInput, Object.assign({}, rest, { ref: ref, dataTestId: dataTestId, name: name, className: className, "$widenOnFocus": widenInputOnFocus, "$showBorderWhenNotInFocus": showBorderWhenNotInFocus, placeholder: placeholder, prefix: jsx(Icon, { name: "MagnifyingGlassIcon", size: "medium" }), suffix: onClear ? (jsx("button", Object.assign({ "data-testid": dataTestId && `${dataTestId}_suffix_component`, onClick: () => {
|
|
2430
|
+
onClear();
|
|
2431
|
+
} }, { children: jsx(Icon, { name: "XMarkIcon", size: "small" }) }))) : undefined, value: value, disabled: disabled, onChange: onChange, onKeyUp: onKeyUp, onFocus: onFocus, onBlur: onBlur, autoComplete: autoComplete })));
|
|
2432
|
+
};
|
|
2433
|
+
const StyledTextInput = twx(TextInput) `
|
|
2434
|
+
tu-search
|
|
2435
|
+
${({ $showBorderWhenNotInFocus }) => $showBorderWhenNotInFocus && tws `tu-search--border`}
|
|
2436
|
+
${({ $widenOnFocus }) => $widenOnFocus && tws `tu-search--widen-on-focus`}
|
|
2437
|
+
`;
|
|
2438
|
+
|
|
2439
|
+
/**
|
|
2440
|
+
* The Spacer component is used for adding a bit of space in the ui.
|
|
2441
|
+
*
|
|
2442
|
+
* @param {SpacerProps} props - The props for the Spacer component
|
|
2443
|
+
* @returns {JSX.Element} Spacer component
|
|
2444
|
+
*/
|
|
2445
|
+
const Spacer = ({ minHeight, border = false, dataTestId }) => {
|
|
2446
|
+
return jsx(Space, { "data-testid": dataTestId, "$minHeight": minHeight, "$border": border });
|
|
2447
|
+
};
|
|
2448
|
+
const GetSpacerHeight = () => ({ $minHeight }) => {
|
|
2449
|
+
switch ($minHeight) {
|
|
2450
|
+
case "normal":
|
|
2451
|
+
return tws `tu-spacer--normal`;
|
|
2452
|
+
case "large":
|
|
2453
|
+
return tws `tu-spacer--large`;
|
|
2454
|
+
default:
|
|
2455
|
+
return "";
|
|
2456
|
+
}
|
|
2457
|
+
};
|
|
2458
|
+
const Space = tw.div `
|
|
2459
|
+
${p => `${p.$border ? `tu-spacer--border` : null}`}
|
|
2460
|
+
${GetSpacerHeight()}
|
|
2461
|
+
`;
|
|
2462
|
+
|
|
2463
|
+
/**
|
|
2464
|
+
* The SectionHeader component is used on sections to set the section title.
|
|
2465
|
+
*
|
|
2466
|
+
* @param {SectionHeaderProps} props - The props for the section header component
|
|
2467
|
+
* @returns {JSX.Element} SectionHeader component
|
|
2468
|
+
*/
|
|
2469
|
+
const SectionHeader = ({ title, subtitle, dataTestId, addon }) => {
|
|
2470
|
+
return (jsxs(SectionHeaderContainer, { children: [jsx(HelmetProvider, { children: jsx(Helmet, { title: title }) }), jsxs(StyledFlex, { children: [jsx(Heading$1, Object.assign({ variant: "secondary", dataTestId: dataTestId }, { children: title })), addon] }), subtitle && (jsx(Heading$1, Object.assign({ variant: "subtitle", subtle: true }, { children: subtitle }))), jsx(Spacer, { minHeight: "normal" })] }));
|
|
2471
|
+
};
|
|
2472
|
+
const SectionHeaderContainer = tw.div `tu-section-header`;
|
|
2473
|
+
const StyledFlex = tw.div `tu-section-header__flex`;
|
|
2474
|
+
|
|
2383
2475
|
/**
|
|
2384
2476
|
* A hook used to detect what children are overflowing a container.
|
|
2385
2477
|
*
|
|
@@ -3090,4 +3182,4 @@ const Layout = tw.div `
|
|
|
3090
3182
|
tu-layout-TwoColumnLayout
|
|
3091
3183
|
`;
|
|
3092
3184
|
|
|
3093
|
-
export { ActionButton, Alert, Badge, BaseInput, Button, Card, CardBody, CardFooter, CardHeader, Checkbox, Collapse, ContentGridArea, CopyableText, CreatableSelect, DateField, DateInput, DayPicker, DayPickerPopover, DayRangePicker, DensityContainer, Drawer, DropZone, EmailField, EmailInput, ExternalLink, FilterListMapLayout, FormGroup, FullWidthRepeatingLayout, GridArea, Heading$1 as Heading, Icon, IconButton, Indicator, IntrinsicallyResponsiveGrid, Label$2 as Label, MenuItem, MenuList, MinTopFullContentLayout, Modal, ModalBackdrop, MoreMenu, MultiSelectMenuItem, NavGridArea, NumberField, NumberInput, PageHeader, Pagination, PhoneInput, Popover, PopoverList, PopoverListItem, PopoverTitle, Prompt, ROLE_CARD, RadioGroup, RadioItem, Search, SectionHeader, Select, SelectPrefix, Sidebar, SingleSelectMenuItem, SkeletonLines, Spacer, Spinner, StarButton, Tag, Text$1 as Text, TextArea, TextAreaField, TextField, TextInput, Timeline, TimelineElement, Tip, TitleGridArea, TitleNavContentLayout, Toggle, Tooltip, TwoColumnLayout, UploadField, UploadInput, ValueBar, docs, getDevicePixelRatio, getOrderedOptions, getValueBarColorByValue, isMultiValue, useContainerProps, useCustomComponents, useDebounce, useDevicePixelRatio, useLocalStorage, useModal, usePrompt, useTimeout };
|
|
3185
|
+
export { ActionButton, Alert, Badge, BaseInput, Button, Card, CardBody, CardFooter, CardHeader, Checkbox, Collapse, ContentGridArea, CopyableText, CreatableSelect, DateField, DateInput, DayPicker, DayPickerPopover, DayRangePicker, DensityContainer, Drawer, DropZone, EmailField, EmailInput, ExternalLink, FilterListMapLayout, FormGroup, FullWidthRepeatingLayout, GridArea, Heading$1 as Heading, Icon, IconButton, Indicator, IntrinsicallyResponsiveGrid, Label$2 as Label, MenuItem, MenuList, MinTopFullContentLayout, Modal, ModalBackdrop, MoreMenu, MultiSelectMenuItem, NavGridArea, NumberField, NumberInput, PageHeader, Pagination, PhoneField, PhoneInput, Popover, PopoverList, PopoverListItem, PopoverTitle, Prompt, ROLE_CARD, RadioGroup, RadioItem, Search, SectionHeader, Select, SelectPrefix, Sidebar, SingleSelectMenuItem, SkeletonLines, Spacer, Spinner, StarButton, Tag, Text$1 as Text, TextArea, TextAreaField, TextField, TextInput, Timeline, TimelineElement, Tip, TitleGridArea, TitleNavContentLayout, Toggle, Tooltip, TwoColumnLayout, UploadField, UploadInput, ValueBar, docs, getDevicePixelRatio, getOrderedOptions, getValueBarColorByValue, isMultiValue, useContainerProps, useCustomComponents, useDebounce, useDevicePixelRatio, useLocalStorage, useModal, usePrompt, useTimeout };
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.65",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@trackunit/css-core": "0.0.74",
|
|
8
8
|
"@trackunit/tailwind-styled-components": "0.0.54",
|
|
9
|
-
"react": "18.2.0",
|
|
10
9
|
"@trackunit/ui-design-tokens": "0.0.60",
|
|
10
|
+
"react": "18.2.0",
|
|
11
11
|
"react-use": "17.4.0",
|
|
12
12
|
"date-fns": "2.29.3",
|
|
13
13
|
"react-day-picker": "8.3.7",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"@trackunit/ui-icons": "0.0.60",
|
|
16
16
|
"react-browser-hooks": "2.2.4",
|
|
17
17
|
"react-useportal": "1.0.17",
|
|
18
|
+
"libphonenumber-js": "1.10.24",
|
|
18
19
|
"react-router-dom": "6.4.5",
|
|
19
20
|
"react-helmet-async": "1.3.0",
|
|
20
21
|
"react-select": "5.7.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
2
|
import { CommonProps } from "../../common";
|
|
3
3
|
import { ButtonCommonProps } from "../buttons";
|
|
4
4
|
type ActionType = "PHONE_NUMBER" | "WEB_ADDRESS" | "EMAIL";
|
|
@@ -12,10 +12,6 @@ interface ActionButtonProps extends ButtonCommonProps, CommonProps {
|
|
|
12
12
|
* The value to be passed into the button.
|
|
13
13
|
*/
|
|
14
14
|
value?: string | null;
|
|
15
|
-
/**
|
|
16
|
-
* The onClick event.
|
|
17
|
-
*/
|
|
18
|
-
onClick?: (e: React.MouseEvent) => void;
|
|
19
15
|
/**
|
|
20
16
|
* The size of the icon.
|
|
21
17
|
*/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { FormGroupProps } from "../FormGroup/FormGroup";
|
|
3
|
+
import { PhoneInputProps } from "../PhoneInput/PhoneInput";
|
|
4
|
+
type FormGroupExposedProps = Pick<FormGroupProps, "label" | "tip" | "helpText" | "helpAddon">;
|
|
5
|
+
export interface PhoneFieldProps extends FormGroupExposedProps, PhoneInputProps {
|
|
6
|
+
/**
|
|
7
|
+
* If a value is set, the field is rendered in its invalid state.
|
|
8
|
+
*/
|
|
9
|
+
errorMessage?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The PhoneField component is used to enter phone number.
|
|
13
|
+
* It is a wrapper around the PhoneInput component and the FormGroup component.
|
|
14
|
+
* It is used to render a phone number field with a label, a tip, a help text, a help addon and an error message.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} [label] - The label for the component.
|
|
17
|
+
* @param {string} [tip] - The tip for the component.
|
|
18
|
+
* @param {string} [helpText] - The help text for the component.
|
|
19
|
+
* @param {string} [helpAddon] - The help addon for the component.
|
|
20
|
+
* @param {string} [errorMessage] - The error message for the component.
|
|
21
|
+
* @param {string} [defaultValue] - The default value for the component.
|
|
22
|
+
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
23
|
+
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
24
|
+
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
25
|
+
* @returns {JSX.Element} - The PhoneField component.
|
|
26
|
+
*/
|
|
27
|
+
export declare const PhoneField: import("react").ForwardRefExoticComponent<PhoneFieldProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from "react";
|
|
2
|
+
import { CountryCode } from "./CountryCodes";
|
|
3
|
+
interface CountryCodeSelectProps {
|
|
4
|
+
excludedCountries?: CountryCode;
|
|
5
|
+
countryCode?: string;
|
|
6
|
+
setCountryCode: Dispatch<SetStateAction<string | undefined>>;
|
|
7
|
+
isInvalid?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The CountryCodeSelect component is used to select a country code for a phone number.
|
|
11
|
+
*
|
|
12
|
+
* @param {CountryCodeSelectProps} props - The props for the CountryCodeSelect component
|
|
13
|
+
* @returns {JSX.Element} CountryCodeSelect component
|
|
14
|
+
*/
|
|
15
|
+
export declare const CountryCodeSelect: ({ excludedCountries, countryCode, isInvalid, setCountryCode, }: CountryCodeSelectProps) => JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
import { CommonProps } from "../../common";
|
|
1
|
+
/// <reference types="react" />
|
|
3
2
|
import { BaseInputProps } from "../BaseInput";
|
|
4
|
-
|
|
3
|
+
type BaseInputExposedProps = Omit<BaseInputProps, "actions">;
|
|
4
|
+
export interface PhoneInputProps extends BaseInputExposedProps {
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* To disable the action button.
|
|
7
|
+
*
|
|
8
|
+
* @default false
|
|
9
|
+
* @memberof PhoneInputProps
|
|
10
|
+
* @example
|
|
11
|
+
* <PhoneInput disableAction />
|
|
7
12
|
*/
|
|
8
13
|
disableAction?: boolean;
|
|
9
14
|
}
|
|
10
15
|
/**
|
|
11
|
-
* A
|
|
16
|
+
* A component for inputting phone numbers with an optional action button for initiating a phone call.
|
|
12
17
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* For specific input types make sure to use the corresponding input component.
|
|
18
|
+
* @param {string} [dataTestId] - The data test ID for the component.
|
|
19
|
+
* @param {boolean} [disabled=false] - Whether the component is disabled or not.
|
|
20
|
+
* @param {string} [fieldSize="medium"] - The size of the input field.
|
|
21
|
+
* @param {boolean} [disableAction=false] - Whether the action button is disabled or not.
|
|
22
|
+
* @returns {JSX.Element} - The PhoneInput component.
|
|
19
23
|
*/
|
|
20
|
-
export declare const PhoneInput:
|
|
24
|
+
export declare const PhoneInput: import("react").ForwardRefExoticComponent<PhoneInputProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
25
|
+
export {};
|
|
@@ -26,6 +26,7 @@ export * from "./NumberField/NumberField";
|
|
|
26
26
|
export * from "./NumberInput/NumberInput";
|
|
27
27
|
export * from "./PageHeader";
|
|
28
28
|
export * from "./Pagination/Pagination";
|
|
29
|
+
export * from "./PhoneField/PhoneField";
|
|
29
30
|
export * from "./PhoneInput";
|
|
30
31
|
export * from "./Popover";
|
|
31
32
|
export * from "./Popover/Popover";
|