@talixo-ds/options-input 1.0.6 → 1.0.8

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.
Files changed (42) hide show
  1. package/dist/esm/index.css +2 -0
  2. package/dist/esm/index.css.map +1 -0
  3. package/dist/esm/index.js +2 -0
  4. package/dist/esm/index.js.map +1 -0
  5. package/dist/index.css +2 -0
  6. package/dist/index.css.map +1 -0
  7. package/dist/{options-input.d.ts → index.d.mts} +22 -8
  8. package/dist/index.d.ts +57 -2
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/package.json +35 -7
  12. package/dist/components/min-max-value-label.d.ts +0 -7
  13. package/dist/components/min-max-value-label.js +0 -4
  14. package/dist/components/min-max-value-label.js.map +0 -1
  15. package/dist/components/options-input-content-item.d.ts +0 -9
  16. package/dist/components/options-input-content-item.js +0 -19
  17. package/dist/components/options-input-content-item.js.map +0 -1
  18. package/dist/components/options-input-dropdown-item.d.ts +0 -12
  19. package/dist/components/options-input-dropdown-item.js +0 -54
  20. package/dist/components/options-input-dropdown-item.js.map +0 -1
  21. package/dist/options-input.js +0 -140
  22. package/dist/options-input.js.map +0 -1
  23. package/dist/types.d.ts +0 -13
  24. package/dist/types.js +0 -2
  25. package/dist/types.js.map +0 -1
  26. package/dist/utils.d.ts +0 -1
  27. package/dist/utils.js +0 -2
  28. package/dist/utils.js.map +0 -1
  29. package/src/__tests__/options-input.spec.tsx +0 -163
  30. package/src/__tests__/utils.spec.ts +0 -12
  31. package/src/components/__tests__/min-max-value-label.spec.tsx +0 -24
  32. package/src/components/__tests__/options-input-content-item.spec.tsx +0 -57
  33. package/src/components/__tests__/options-input-dropdown-item.spec.tsx +0 -126
  34. package/src/components/min-max-value-label.tsx +0 -19
  35. package/src/components/options-input-content-item.tsx +0 -72
  36. package/src/components/options-input-dropdown-item.tsx +0 -161
  37. package/src/index.ts +0 -2
  38. package/src/options-input.tsx +0 -353
  39. package/src/styles.scss +0 -54
  40. package/src/types.ts +0 -14
  41. package/src/utils.ts +0 -2
  42. package/tsconfig.build.json +0 -8
@@ -1,140 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useState, useEffect, useCallback, useMemo, useRef } from "react";
3
- import classNames from "classnames";
4
- import Box from "@mui/material/Box";
5
- import List from "@mui/material/List";
6
- import Popper from "@mui/material/Popper";
7
- import ClickAwayListener from "@mui/material/ClickAwayListener";
8
- import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
9
- import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
10
- import * as DesignSystemIcons from "@talixo-ds/icons";
11
- import OptionsInputContentItem from "./components/options-input-content-item";
12
- import OptionsInputDropdownItem from "./components/options-input-dropdown-item";
13
- import { red } from "@mui/material/colors";
14
- import "./styles.scss";
15
- import "@emotion/react";
16
- import "@emotion/styled";
17
- import { capitalize } from "./utils";
18
- export const OptionsInput = ({ options, onChange, onFocus, onBlur, persistentOptions = [], defaultValue, displayMinMax = false, disabled = false, readOnly = false, id, className, itemsGap = 1, containerSx = [], error = false, helperText, helperTextSx, ...rest }) => {
19
- const [currentOptions, setCurrentOptions] = useState([]);
20
- const [inputContainerWidth, setInputContainerWidth] = useState(0);
21
- const inputContainerRef = useRef();
22
- const [anchorEl, setAnchorEl] = useState();
23
- const open = !!anchorEl;
24
- useEffect(() => setCurrentOptions(options.map((option) => {
25
- const quantity = defaultValue?.[option.id] ?? 0;
26
- return {
27
- ...option,
28
- quantity,
29
- inputQuantity: quantity
30
- };
31
- })), [options, defaultValue]);
32
- useEffect(() => {
33
- setInputContainerWidth(inputContainerRef?.current?.clientWidth ?? 0);
34
- }, [inputContainerRef?.current?.clientWidth]);
35
- const optionsExceedingBoundaries = useMemo(() => currentOptions.reduce((exceedingOptions, { quantity, id, label }) => {
36
- const option = options.find((option) => option.id === id);
37
- if (label &&
38
- quantity !== undefined &&
39
- ((option?.max !== undefined && option?.max < quantity) ||
40
- (option?.min !== undefined && option?.min > quantity))) {
41
- return [...exceedingOptions, label];
42
- }
43
- return exceedingOptions;
44
- }, []), [currentOptions, options]);
45
- const isError = useMemo(() => error || !!optionsExceedingBoundaries.length, [error, optionsExceedingBoundaries]);
46
- const toggleInput = useCallback((event) => {
47
- const { currentTarget } = event;
48
- if (!disabled && !readOnly) {
49
- setTimeout(() => {
50
- setAnchorEl((currentAnchor) => currentAnchor ? undefined : currentTarget);
51
- }, 0);
52
- }
53
- }, [disabled, readOnly, setAnchorEl]);
54
- const onInputFocus = () => {
55
- if (onFocus) {
56
- onFocus(currentOptions.reduce((currentValues, currentOption) => ({
57
- ...currentValues,
58
- [currentOption.id]: currentOption.quantity
59
- }), {}));
60
- }
61
- };
62
- const onInputBlur = () => {
63
- if (onBlur) {
64
- onBlur(currentOptions.reduce((currentValues, currentOption) => ({
65
- ...currentValues,
66
- [currentOption.id]: currentOption.quantity
67
- }), {}));
68
- }
69
- };
70
- const onValueChange = (optionId, newValue) => {
71
- const newQuantity = Number.isNaN(Number(newValue)) ? 0 : Number(newValue);
72
- const newCurrentOptions = currentOptions.map((option) => {
73
- const maxQuantity = newQuantity > (option?.max ?? Infinity) ? option?.max : newQuantity;
74
- return {
75
- ...option,
76
- ...(optionId === option.id && {
77
- quantity: newQuantity < (option?.min ?? -Infinity) ? option?.min : maxQuantity,
78
- inputQuantity: newValue
79
- })
80
- };
81
- });
82
- if (onChange) {
83
- onChange(newCurrentOptions.reduce((currentValues, currentOption) => ({
84
- ...currentValues,
85
- [currentOption.id]: currentOption.quantity
86
- }), {}));
87
- }
88
- setCurrentOptions(newCurrentOptions);
89
- };
90
- const onDropdownItemBlur = (optionId) => () => setCurrentOptions(currentOptions.map((option) => {
91
- if (optionId !== option.id)
92
- return option;
93
- const finalQuantity = Number.isNaN(Number(option?.inputQuantity))
94
- ? 0
95
- : Number(option?.inputQuantity);
96
- const maxQuantity = finalQuantity > (option?.max ?? Infinity) ? option?.max : finalQuantity;
97
- return {
98
- ...option,
99
- inputQuantity: finalQuantity < (option?.min ?? -Infinity) ? option?.min : maxQuantity
100
- };
101
- }));
102
- return (_jsxs(_Fragment, { children: [_jsxs(Box, { children: [_jsxs(Box, { id: id, onClick: toggleInput, onBlur: onInputBlur, onFocus: onInputFocus, ref: inputContainerRef, className: classNames("options-input__container", className, {
103
- "options-input__container--open": open,
104
- "options-input__container--disabled": disabled,
105
- "options-input__container--read-only": readOnly,
106
- "options-input__container--error": isError
107
- }), sx: [
108
- { "&:hover": { borderColor: "#d3d3d3" } },
109
- ...(Array.isArray(containerSx) ? containerSx : [containerSx]),
110
- open && {
111
- borderColor: (theme) => theme.palette.primary.main,
112
- "&:hover": { borderColor: (theme) => theme.palette.primary.main }
113
- },
114
- isError && {
115
- borderColor: red[700],
116
- "&:hover": { borderColor: red[700] }
117
- }
118
- ], "data-testid": rest["data-testid"] || "options-input-container", tabIndex: 0, children: [_jsx(Box, { display: "flex", gap: itemsGap, children: currentOptions
119
- .filter(({ quantity, id: optionId, icon }) => !!(DesignSystemIcons[capitalize(icon)] &&
120
- (quantity !== 0 || persistentOptions?.includes(optionId))))
121
- .map((option) => (_jsx(OptionsInputContentItem, { item: option, disabled: disabled, displayMinMax: displayMinMax, error: !!(option?.label && optionsExceedingBoundaries.includes(option.label)) }, option.id))) }), !readOnly &&
122
- (open ? (_jsx(KeyboardArrowUpIcon, { sx: { color: isError ? red[700] : "primary" } })) : (_jsx(KeyboardArrowDownIcon, { sx: {
123
- color: (theme) => disabled ? theme.palette.grey[400] : theme.palette.action.focus
124
- } })))] }), (helperText || isError) && (_jsx(Box, { sx: {
125
- fontSize: "small",
126
- ...(helperTextSx || {}),
127
- ...(isError ? { color: red[700] } : {})
128
- }, marginTop: 1, marginLeft: 2, width: inputContainerWidth, children: optionsExceedingBoundaries.length
129
- ? (() => {
130
- const messagePluralForm = optionsExceedingBoundaries.length > 1 ? "s" : "";
131
- return `Value${messagePluralForm} for ${optionsExceedingBoundaries.join(", ")} option${messagePluralForm} ${messagePluralForm ? "are" : "is"} out of range.`;
132
- })()
133
- : helperText }))] }), _jsx(ClickAwayListener, { onClickAway: () => open && setAnchorEl(undefined), children: _jsx(Popper, { open: open, placement: "bottom-start", anchorEl: anchorEl, sx: (theme) => ({ zIndex: theme.zIndex.modal }), children: _jsx(List, { disablePadding: true, "data-testid": "options-dropdown-list", className: "options-input__dropdown-items-list", sx: {
134
- bgcolor: "Background",
135
- border: (theme) => `thin solid ${isError ? red[700] : theme.palette.primary.main}`
136
- }, children: currentOptions
137
- .filter(({ icon }) => !!DesignSystemIcons[capitalize(icon)])
138
- .map((option, index) => (_jsx(OptionsInputDropdownItem, { item: option, onBlur: onDropdownItemBlur(option.id), onChange: onValueChange, index: index, displayMinMax: displayMinMax, error: isError }, option.id))) }) }) })] }));
139
- };
140
- //# sourceMappingURL=options-input.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"options-input.js","sourceRoot":"","sources":["../src/options-input.tsx"],"names":[],"mappings":"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"}
package/dist/types.d.ts DELETED
@@ -1,13 +0,0 @@
1
- export interface OptionsInputOption {
2
- id: string;
3
- icon: string;
4
- label?: string;
5
- details?: string;
6
- min?: number;
7
- max?: number;
8
- quantity?: number;
9
- inputQuantity?: string | number;
10
- }
11
- export interface OptionsInputValue {
12
- [key: string]: number;
13
- }
package/dist/types.js DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/dist/utils.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare const capitalize: (str: string) => string;
package/dist/utils.js DELETED
@@ -1,2 +0,0 @@
1
- export const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2
- //# sourceMappingURL=utils.js.map
package/dist/utils.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE,CACzC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC"}
@@ -1,163 +0,0 @@
1
- import {
2
- render,
3
- screen,
4
- fireEvent,
5
- waitFor,
6
- act
7
- } from "@testing-library/react";
8
- import { OptionsInput } from "../options-input";
9
-
10
- const props = {
11
- options: [
12
- {
13
- id: "luggage",
14
- icon: "luggage",
15
- label: "luggage",
16
- details: "This is your luggage",
17
- min: 0,
18
- max: 9
19
- },
20
- {
21
- id: "dog",
22
- icon: "this icon does not exist",
23
- label: "dog",
24
- min: 0,
25
- max: 3
26
- },
27
- {
28
- id: "sport-equipment",
29
- icon: "football",
30
- label: "sport equipment",
31
- min: 0,
32
- max: 1
33
- }
34
- ],
35
- id: "test-id",
36
- defaultValue: { luggage: 2, "sport-equipment": 5 },
37
- persistentOptions: ["sport-equipment"],
38
- className: "test-class",
39
- onChange: vi.fn(),
40
- onFocus: vi.fn(),
41
- onBlur: vi.fn()
42
- };
43
-
44
- describe("OptionsInput", () => {
45
- it("should display invalid value error message for items with invalid value", () => {
46
- const { queryByText } = render(<OptionsInput {...props} />);
47
-
48
- expect(
49
- queryByText("Value for sport equipment option is out of range.")
50
- ).toBeInTheDocument();
51
- });
52
-
53
- describe("events", () => {
54
- it("should open input dropdown properly", async () => {
55
- const { getAllByTestId } = render(<OptionsInput {...props} />);
56
- const optionsInputContainer = getAllByTestId("options-input-container")[0];
57
-
58
- act(() => {
59
- fireEvent.click(optionsInputContainer!);
60
- });
61
-
62
- await waitFor(() => {
63
- expect(screen.queryByTestId("options-dropdown-list")).toBeInTheDocument();
64
- });
65
- });
66
-
67
- it("should not open dropdown when input is disabled", async () => {
68
- const { getAllByTestId } = render(<OptionsInput {...props} disabled />);
69
-
70
- const optionsInputContainer = getAllByTestId("options-input-container")[0];
71
-
72
- act(() => {
73
- fireEvent.click(optionsInputContainer!);
74
- });
75
-
76
- await waitFor(() => {
77
- expect(
78
- screen.queryByTestId("options-dropdown-list")
79
- ).not.toBeInTheDocument();
80
- });
81
- });
82
-
83
- it("should handle input focus properly", () => {
84
- const { getAllByTestId } = render(<OptionsInput {...props} />);
85
-
86
- const optionsInputContainer = getAllByTestId("options-input-container")[0];
87
-
88
- act(() => {
89
- fireEvent.focus(optionsInputContainer!);
90
- });
91
-
92
- expect(props.onFocus).toHaveBeenCalledWith({
93
- dog: 0,
94
- luggage: 2,
95
- "sport-equipment": 5
96
- });
97
- });
98
-
99
- it("should handle input blur properly", () => {
100
- const { getAllByTestId } = render(<OptionsInput {...props} />);
101
-
102
- const optionsInputContainer = getAllByTestId("options-input-container")[0];
103
-
104
- act(() => {
105
- fireEvent.blur(optionsInputContainer!);
106
- });
107
-
108
- expect(props.onBlur).toHaveBeenCalledWith({
109
- dog: 0,
110
- luggage: 2,
111
- "sport-equipment": 5
112
- });
113
- });
114
-
115
- it("should handle input option change properly", async () => {
116
- const { getByTestId } = render(<OptionsInput {...props} />);
117
-
118
- const optionsInputContainer = getByTestId("options-input-container");
119
-
120
- fireEvent.click(optionsInputContainer);
121
-
122
- await waitFor(() => screen.findAllByTestId("dropdown-item-input"));
123
-
124
- const optionCountInput = screen.getAllByTestId("dropdown-item-input")[0];
125
-
126
- act(() => {
127
- fireEvent.change(optionCountInput!, { target: { value: 9 } });
128
- });
129
-
130
- expect(props.onChange).toHaveBeenCalledWith({
131
- dog: 0,
132
- luggage: 9,
133
- "sport-equipment": 5
134
- });
135
-
136
- expect(screen.getAllByTestId("option-item")[0]).toHaveTextContent("9");
137
- });
138
-
139
- it("should handle input option blur properly", async () => {
140
- const { getAllByTestId } = render(<OptionsInput {...props} />);
141
-
142
- const optionsInputContainer = getAllByTestId("options-input-container")[0];
143
-
144
- fireEvent.click(optionsInputContainer!);
145
-
146
- await waitFor(() => {
147
- const optionCountInput = screen.getAllByTestId("dropdown-item-input")[0];
148
-
149
- act(() => {
150
- fireEvent.change(optionCountInput!, { target: { value: 500 } });
151
- });
152
-
153
- expect(optionCountInput).toHaveAttribute("value", "500");
154
-
155
- act(() => {
156
- fireEvent.blur(optionCountInput!);
157
- });
158
-
159
- expect(optionCountInput).toHaveAttribute("value", "9");
160
- });
161
- });
162
- });
163
- });
@@ -1,12 +0,0 @@
1
- import { capitalize } from "../utils";
2
-
3
- test("capitalize util converts string properly", () => {
4
- const example = "hello world";
5
- const expected = "Hello world";
6
-
7
- const result1 = capitalize(example);
8
- expect(result1).toBe(expected);
9
-
10
- const result2 = capitalize(expected);
11
- expect(result2).toBe(expected);
12
- });
@@ -1,24 +0,0 @@
1
- import { render } from "@testing-library/react";
2
- import { MinMaxValueLabel } from "../min-max-value-label";
3
-
4
- describe("MinMaxValueLabel", () => {
5
- it("should render with min value", () => {
6
- const { queryByText } = render(<MinMaxValueLabel min={0} color="black" />);
7
-
8
- expect(queryByText("min: 0")).toBeInTheDocument();
9
- });
10
-
11
- it("should render with max value", () => {
12
- const { queryByText } = render(
13
- <MinMaxValueLabel max={100} color={(theme) => theme.palette.primary.main} />
14
- );
15
-
16
- expect(queryByText("max: 100")).toBeInTheDocument();
17
- });
18
-
19
- it("should render with min and max value", () => {
20
- const { queryByText } = render(<MinMaxValueLabel max={100} min={0} />);
21
-
22
- expect(queryByText("min: 0, max: 100")).toBeInTheDocument();
23
- });
24
- });
@@ -1,57 +0,0 @@
1
- import { fireEvent, render, waitFor } from "@testing-library/react";
2
- import OptionsInputContentItem, {
3
- type OptionsInputContentItemProps
4
- } from "../options-input-content-item";
5
-
6
- const props = {
7
- item: {
8
- id: "luggage",
9
- icon: "luggage",
10
- label: "luggage",
11
- details: "This is your luggage",
12
- min: -10,
13
- max: 10,
14
- quantity: 0,
15
- inputQuantity: 0
16
- },
17
- displayMinMax: true
18
- } satisfies OptionsInputContentItemProps;
19
-
20
- describe("OptionsInputDropdownItem", () => {
21
- it("should render properly and show tooltip with proper content on hover", async () => {
22
- const { queryByTestId, queryByText, getByTestId } = render(
23
- <OptionsInputContentItem {...props} />
24
- );
25
-
26
- expect(queryByTestId("LuggageIcon")).toBeInTheDocument();
27
- expect(queryByText("0")).toBeInTheDocument();
28
-
29
- const icon = getByTestId("LuggageIcon");
30
-
31
- fireEvent.mouseOver(icon);
32
-
33
- await waitFor(() => {
34
- expect(queryByText("This is your luggage")).toBeInTheDocument();
35
- expect(queryByText("luggage")).toBeInTheDocument();
36
- });
37
- });
38
-
39
- it("should not render tooltip when there is no label", async () => {
40
- const { queryByTestId, queryByText, getByTestId } = render(
41
- <OptionsInputContentItem
42
- item={{ ...props.item, label: undefined, quantity: 1 }}
43
- />
44
- );
45
-
46
- expect(queryByTestId("LuggageIcon")).toBeInTheDocument();
47
- expect(queryByText("1")).toBeInTheDocument();
48
-
49
- const icon = getByTestId("LuggageIcon");
50
-
51
- fireEvent.mouseOver(icon);
52
-
53
- await waitFor(() => {
54
- expect(queryByText("This is your luggage")).not.toBeInTheDocument();
55
- });
56
- });
57
- });
@@ -1,126 +0,0 @@
1
- import { render, fireEvent } from "@testing-library/react";
2
- import OptionsInputDropdownItem, {
3
- type OptionsInputDropdownItemProps
4
- } from "../options-input-dropdown-item";
5
-
6
- const onChangeMock = vi.fn();
7
- const onBlurMock = vi.fn();
8
-
9
- const props = {
10
- item: {
11
- id: "luggage-id",
12
- icon: "luggage",
13
- details: "This is your luggage. Please, keep your attention not to lose it.",
14
- min: -10,
15
- max: 10,
16
- quantity: 0,
17
- inputQuantity: 0
18
- },
19
- onBlur: onBlurMock,
20
- onChange: onChangeMock,
21
- index: 1
22
- } satisfies OptionsInputDropdownItemProps;
23
-
24
- describe("OptionsInputDropdownItem", () => {
25
- afterEach(() => {
26
- vi.clearAllMocks();
27
- });
28
-
29
- afterAll(() => {
30
- vi.restoreAllMocks();
31
- });
32
-
33
- it("should call onChange on text field edit", () => {
34
- const { getByTestId } = render(<OptionsInputDropdownItem {...props} />);
35
-
36
- const input = getByTestId("dropdown-item-input");
37
-
38
- fireEvent.change(input, { target: { value: "10" } });
39
-
40
- expect(onChangeMock).toHaveBeenCalledTimes(1);
41
- expect(onChangeMock).toHaveBeenCalledWith("luggage-id", "10");
42
-
43
- fireEvent.blur(input);
44
- expect(onBlurMock).toHaveBeenCalledTimes(1);
45
- });
46
-
47
- it("should call onChange on increment button click", () => {
48
- const { getAllByRole } = render(<OptionsInputDropdownItem {...props} />);
49
-
50
- const buttons = getAllByRole("button");
51
-
52
- fireEvent.click(buttons[0]!);
53
-
54
- expect(onChangeMock).toHaveBeenCalledTimes(1);
55
- expect(onChangeMock).toHaveBeenCalledWith("luggage-id", 1);
56
- });
57
-
58
- it("should call onChange on increment button click when value is below min", () => {
59
- const { getAllByRole } = render(
60
- <OptionsInputDropdownItem
61
- {...{
62
- ...props,
63
- item: {
64
- ...props.item,
65
- quantity: -20,
66
- inputQuantity: -20
67
- }
68
- }}
69
- />
70
- );
71
-
72
- const buttons = getAllByRole("button");
73
-
74
- fireEvent.click(buttons[0]!);
75
-
76
- expect(onChangeMock).toHaveBeenCalledTimes(1);
77
- expect(onChangeMock).toHaveBeenCalledWith("luggage-id", -10);
78
- });
79
-
80
- it("should call onChange on decrement button click", () => {
81
- const { getAllByRole } = render(<OptionsInputDropdownItem {...props} />);
82
-
83
- const buttons = getAllByRole("button");
84
-
85
- fireEvent.click(buttons[1]!);
86
-
87
- expect(onChangeMock).toHaveBeenCalledTimes(1);
88
- expect(onChangeMock).toHaveBeenCalledWith("luggage-id", -1);
89
- });
90
-
91
- it("should call onChange on decrement button click when value is above max", () => {
92
- const { getAllByRole } = render(
93
- <OptionsInputDropdownItem
94
- {...{
95
- ...props,
96
- item: {
97
- ...props.item,
98
- quantity: 20,
99
- inputQuantity: 20
100
- }
101
- }}
102
- />
103
- );
104
-
105
- const buttons = getAllByRole("button");
106
-
107
- fireEvent.click(buttons[1]!);
108
-
109
- expect(onChangeMock).toHaveBeenCalledTimes(1);
110
- expect(onChangeMock).toHaveBeenCalledWith("luggage-id", 10);
111
- });
112
-
113
- it("should expand details content", () => {
114
- const { getByTestId } = render(<OptionsInputDropdownItem {...props} />);
115
-
116
- expect(getByTestId("option-details")).toHaveTextContent(
117
- props.item.details.slice(0, 15)
118
- );
119
-
120
- const optionDetailsContainer = getByTestId("option-details-container");
121
-
122
- fireEvent.mouseEnter(optionDetailsContainer);
123
-
124
- expect(getByTestId("option-details")).toHaveTextContent(props.item.details);
125
- });
126
- });
@@ -1,19 +0,0 @@
1
- import Typography, { type TypographyProps } from "@mui/material/Typography";
2
-
3
- export type MinMaxValueLabelProps = {
4
- min?: number;
5
- max?: number;
6
- color?: TypographyProps["color"];
7
- };
8
-
9
- export const MinMaxValueLabel = ({
10
- min,
11
- max,
12
- color
13
- }: MinMaxValueLabelProps) => (
14
- <Typography variant="caption" color={color} sx={{ my: 0 }}>
15
- {!Number.isNaN(Number(min)) && `min: ${min}`}
16
- {!Number.isNaN(Number(max)) && !Number.isNaN(Number(min)) && ", "}
17
- {!Number.isNaN(Number(max)) && `max: ${max}`}
18
- </Typography>
19
- );
@@ -1,72 +0,0 @@
1
- import Tooltip from "@mui/material/Tooltip";
2
- import Box from "@mui/material/Box";
3
- import Typography from "@mui/material/Typography";
4
- import * as DesignSystemIcons from "@talixo-ds/icons";
5
- import { MinMaxValueLabel } from "./min-max-value-label";
6
- import { capitalize } from "../utils";
7
- import type { OptionsInputOption } from "../types";
8
- import { red } from "@mui/material/colors";
9
- import { useMemo } from "react";
10
-
11
- export type OptionsInputContentItemProps = {
12
- item: OptionsInputOption;
13
- disabled?: boolean;
14
- displayMinMax?: boolean;
15
- error?: boolean;
16
- };
17
-
18
- const OptionsInputContentItem = ({
19
- item: { quantity, details, label, max, min, icon },
20
- displayMinMax = false,
21
- disabled = false,
22
- error = false
23
- }: OptionsInputContentItemProps) => {
24
- const Icon =
25
- DesignSystemIcons[capitalize(icon) as keyof typeof DesignSystemIcons] || null;
26
- const itemsColor = useMemo(() => {
27
- const defaultItemColor = quantity === 0 || disabled ? "#a4a5b2" : "#000000";
28
-
29
- return error ? red[700] : defaultItemColor;
30
- }, [error, quantity, disabled]);
31
-
32
- return (
33
- <Box
34
- display="flex"
35
- alignItems="center"
36
- gap={0.5}
37
- color={itemsColor}
38
- data-testid="option-item"
39
- >
40
- {label ? (
41
- <Tooltip
42
- title={
43
- <Box display="flex" flexDirection="column">
44
- <Typography variant="caption" fontWeight={600} sx={{ my: 0 }}>
45
- {label}
46
- </Typography>
47
- {details && (
48
- <Typography variant="caption" sx={{ my: 0 }}>
49
- {details}
50
- </Typography>
51
- )}
52
- {displayMinMax && <MinMaxValueLabel min={min} max={max} />}
53
- </Box>
54
- }
55
- placement="top"
56
- arrow
57
- >
58
- <span>
59
- <Icon fontSize="medium" sx={{ color: itemsColor }} />
60
- </span>
61
- </Tooltip>
62
- ) : (
63
- <Icon fontSize="medium" sx={{ color: itemsColor }} />
64
- )}
65
- <Typography variant="h6" color={itemsColor}>
66
- {quantity}
67
- </Typography>
68
- </Box>
69
- );
70
- };
71
-
72
- export default OptionsInputContentItem;