@seeqdev/qomponents 0.0.183 → 0.0.185
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/README.md +5 -19
- package/dist/example/.eslintrc.cjs +2 -6
- package/dist/example/README.md +0 -3
- package/dist/example/src/Example.tsx +7 -7
- package/dist/example/tsconfig.json +2 -8
- package/dist/example/tsconfig.node.json +1 -3
- package/dist/example/vite.config.ts +1 -1
- package/dist/index.esm.js +784 -523
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +781 -520
- package/dist/index.js.map +1 -1
- package/dist/src/Accordion/Accordion.js +8 -0
- package/dist/src/Accordion/Accordion.stories.js +96 -0
- package/dist/src/Accordion/Accordion.test.js +54 -0
- package/dist/src/Accordion/Accordion.types.js +1 -0
- package/dist/src/Accordion/index.js +1 -0
- package/dist/src/Alert/Alert.js +33 -0
- package/dist/src/Alert/Alert.stories.d.ts +13 -5
- package/dist/src/Alert/Alert.stories.js +72 -0
- package/dist/src/Alert/Alert.test.js +49 -0
- package/dist/src/Alert/Alert.types.js +1 -0
- package/dist/src/Alert/index.js +1 -0
- package/dist/src/Button/Button.js +107 -0
- package/dist/src/Button/Button.stories.js +74 -0
- package/dist/src/Button/Button.test.js +65 -0
- package/dist/src/Button/Button.types.d.ts +4 -4
- package/dist/src/Button/Button.types.js +4 -0
- package/dist/src/Button/index.d.ts +1 -1
- package/dist/src/Button/index.js +1 -0
- package/dist/src/ButtonGroup/ButtonGroup.js +34 -0
- package/dist/src/ButtonGroup/ButtonGroup.stories.js +328 -0
- package/dist/src/ButtonGroup/ButtonGroup.test.js +65 -0
- package/dist/src/ButtonGroup/ButtonGroup.types.js +1 -0
- package/dist/src/ButtonGroup/index.js +1 -0
- package/dist/src/ButtonWithDropdown/ButtonWithDropdown.js +46 -0
- package/dist/src/ButtonWithDropdown/ButtonWithDropdown.stories.js +119 -0
- package/dist/src/ButtonWithDropdown/ButtonWithDropdown.test.js +92 -0
- package/dist/src/ButtonWithDropdown/ButtonWithDropdown.types.js +1 -0
- package/dist/src/ButtonWithDropdown/index.js +1 -0
- package/dist/src/ButtonWithPopover/ButtonWithPopover.js +54 -0
- package/dist/src/ButtonWithPopover/ButtonWithPopover.stories.js +51 -0
- package/dist/src/ButtonWithPopover/ButtonWithPopover.test.js +80 -0
- package/dist/src/ButtonWithPopover/ButtonWithPopover.types.js +1 -0
- package/dist/src/ButtonWithPopover/index.js +1 -0
- package/dist/src/Carousel/Carousel.js +80 -0
- package/dist/src/Carousel/Carousel.stories.js +100 -0
- package/dist/src/Carousel/Carousel.test.js +47 -0
- package/dist/src/Carousel/Carousel.types.js +1 -0
- package/dist/src/Carousel/index.js +1 -0
- package/dist/src/Checkbox/Checkbox.js +24 -0
- package/dist/src/Checkbox/Checkbox.stories.js +21 -0
- package/dist/src/Checkbox/Checkbox.test.js +93 -0
- package/dist/src/Checkbox/Checkbox.types.js +1 -0
- package/dist/src/Checkbox/index.js +1 -0
- package/dist/src/Collapse/Collapse.js +16 -0
- package/dist/src/Collapse/Collapse.stories.js +28 -0
- package/dist/src/Collapse/Collapse.test.js +16 -0
- package/dist/src/Collapse/Collapse.types.js +1 -0
- package/dist/src/Collapse/index.js +1 -0
- package/dist/src/Icon/Icon.js +55 -0
- package/dist/src/Icon/Icon.stories.js +31 -0
- package/dist/src/Icon/Icon.test.js +54 -0
- package/dist/src/Icon/Icon.types.d.ts +1 -1
- package/dist/src/Icon/Icon.types.js +15 -0
- package/dist/src/Icon/index.js +1 -0
- package/dist/src/InputGroup/InputGroup.js +33 -0
- package/dist/src/InputGroup/InputGroup.stories.js +144 -0
- package/dist/src/InputGroup/InputGroup.test.js +41 -0
- package/dist/src/InputGroup/InputGroup.types.js +1 -0
- package/dist/src/InputGroup/index.js +1 -0
- package/dist/src/Modal/Modal.js +86 -0
- package/dist/src/Modal/Modal.stories.js +79 -0
- package/dist/src/Modal/Modal.test.js +107 -0
- package/dist/src/Modal/Modal.types.js +1 -0
- package/dist/src/Modal/index.js +1 -0
- package/dist/src/ProgressBar/ProgressBar.js +71 -0
- package/dist/src/ProgressBar/ProgressBar.stories.js +46 -0
- package/dist/src/ProgressBar/ProgressBar.test.js +42 -0
- package/dist/src/ProgressBar/ProgressBar.types.js +1 -0
- package/dist/src/ProgressBar/index.js +1 -0
- package/dist/src/SeeqActionDropdown/SeeqActionDropdown.js +41 -0
- package/dist/src/SeeqActionDropdown/SeeqActionDropdown.stories.js +73 -0
- package/dist/src/SeeqActionDropdown/SeeqActionDropdown.test.js +72 -0
- package/dist/src/SeeqActionDropdown/SeeqActionDropdown.types.d.ts +0 -5
- package/dist/src/SeeqActionDropdown/SeeqActionDropdown.types.js +1 -0
- package/dist/src/SeeqActionDropdown/index.js +1 -0
- package/dist/src/SeeqActionDropdown/variants.js +34 -0
- package/dist/src/Select/Select.js +171 -0
- package/dist/src/Select/Select.stories.js +50 -0
- package/dist/src/Select/Select.test.js +176 -0
- package/dist/src/Select/Select.types.js +1 -0
- package/dist/src/Select/index.js +2 -0
- package/dist/src/Slider/Slider.js +11 -0
- package/dist/src/Slider/Slider.stories.js +37 -0
- package/dist/src/Slider/Slider.test.js +31 -0
- package/dist/src/Slider/Slider.types.js +1 -0
- package/dist/src/Slider/index.js +1 -0
- package/dist/src/SvgIcon/SvgIcon.js +27 -0
- package/dist/src/SvgIcon/SvgIcon.stories.js +26 -0
- package/dist/src/SvgIcon/SvgIcon.test.js +40 -0
- package/dist/src/SvgIcon/SvgIcon.types.d.ts +1 -1
- package/dist/src/SvgIcon/SvgIcon.types.js +2 -0
- package/dist/src/SvgIcon/index.js +1 -0
- package/dist/src/Tabs/Tabs.js +18 -0
- package/dist/src/Tabs/Tabs.stories.js +83 -0
- package/dist/src/Tabs/Tabs.test.js +91 -0
- package/dist/src/Tabs/Tabs.types.js +1 -0
- package/dist/src/Tabs/index.js +1 -0
- package/dist/src/TextArea/TextArea.js +54 -0
- package/dist/src/TextArea/TextArea.stories.js +21 -0
- package/dist/src/TextArea/TextArea.test.js +129 -0
- package/dist/src/TextArea/TextArea.types.js +1 -0
- package/dist/src/TextArea/index.js +1 -0
- package/dist/src/TextField/TextField.js +85 -0
- package/dist/src/TextField/TextField.stories.js +30 -0
- package/dist/src/TextField/TextField.test.js +40 -0
- package/dist/src/TextField/TextField.types.js +1 -0
- package/dist/src/TextField/index.js +1 -0
- package/dist/src/ToolbarButton/ToolbarButton.js +58 -0
- package/dist/src/ToolbarButton/ToolbarButton.stories.js +63 -0
- package/dist/src/ToolbarButton/ToolbarButton.test.js +89 -0
- package/dist/src/ToolbarButton/ToolbarButton.types.d.ts +1 -1
- package/dist/src/ToolbarButton/ToolbarButton.types.js +1 -0
- package/dist/src/ToolbarButton/index.js +1 -0
- package/dist/src/Tooltip/QTip.stories.js +22 -0
- package/dist/src/Tooltip/QTip.types.js +1 -0
- package/dist/src/Tooltip/QTipPerformance.stories.js +27 -0
- package/dist/src/Tooltip/Qtip.js +168 -0
- package/dist/src/Tooltip/Tooltip.js +34 -0
- package/dist/src/Tooltip/Tooltip.stories.js +20 -0
- package/dist/src/Tooltip/Tooltip.types.d.ts +1 -1
- package/dist/src/Tooltip/Tooltip.types.js +2 -0
- package/dist/src/Tooltip/TooltipPerformance.stories.js +25 -0
- package/dist/src/Tooltip/index.js +2 -0
- package/dist/src/Tooltip/qTip.utilities.js +10 -0
- package/dist/src/index.js +47 -0
- package/dist/src/setupTests.js +5 -0
- package/dist/src/types.js +25 -0
- package/dist/src/utils/browserId.d.ts +3 -3
- package/dist/src/utils/browserId.js +28 -0
- package/dist/src/utils/svg.js +19 -0
- package/dist/src/utils/validateStyleDimension.js +13 -0
- package/dist/src/utils/validateStyleDimension.test.js +19 -0
- package/dist/styles.css +3410 -2791
- package/package.json +22 -17
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import { render, screen } from '@testing-library/react';
|
|
4
|
+
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import Icon from '../Icon';
|
|
6
|
+
import SeeqActionDropdown from './SeeqActionDropdown';
|
|
7
|
+
describe('SeeqActionDropdown', () => {
|
|
8
|
+
const mockOnClick = jest.fn();
|
|
9
|
+
const testId = 'trigger-icon';
|
|
10
|
+
class Context {
|
|
11
|
+
props = {
|
|
12
|
+
trigger: (_jsx(Icon, { icon: "fc-more", type: "text", testId: testId, extraClassNames: "tw-text-sq-text-color dark:tw-text-sq-white tw-w-[18px]" })),
|
|
13
|
+
containerTestId: 'basic-dropdown1',
|
|
14
|
+
tooltip: 'This is a small dropdown.',
|
|
15
|
+
tooltipDelay: 0,
|
|
16
|
+
tooltipPlacement: 'top',
|
|
17
|
+
variant: 'create-workbench',
|
|
18
|
+
isHtmlTooltip: false,
|
|
19
|
+
seeqActionDropdownItems: [
|
|
20
|
+
{ display: 'Orange', icon: 'fc-data-file', action: mockOnClick, enabled: true },
|
|
21
|
+
{ display: 'Mango', icon: 'fc-user-community', action: mockOnClick, enabled: true },
|
|
22
|
+
{ display: 'Guava', icon: 'fc-user-community', action: mockOnClick },
|
|
23
|
+
{ display: 'Banana', icon: 'fc-user-community', action: mockOnClick },
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
let tc;
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
tc = new Context();
|
|
30
|
+
jest.clearAllMocks();
|
|
31
|
+
});
|
|
32
|
+
const renderSeeqActionDropdown = (props) => render(_jsx(SeeqActionDropdown, { ...props }));
|
|
33
|
+
const openDropdown = async () => {
|
|
34
|
+
const popover = screen.getByTestId(testId);
|
|
35
|
+
await userEvent.click(popover);
|
|
36
|
+
};
|
|
37
|
+
test('renders trigger and opens dropdown content on trigger click', async () => {
|
|
38
|
+
renderSeeqActionDropdown(tc.props);
|
|
39
|
+
expect(screen.getByTestId('trigger-icon')).toBeInTheDocument();
|
|
40
|
+
await openDropdown();
|
|
41
|
+
expect(screen.getByText('Orange')).toBeInTheDocument();
|
|
42
|
+
});
|
|
43
|
+
test('renders dividers correctly', async () => {
|
|
44
|
+
tc.props.seeqActionDropdownItems[1].divider = true;
|
|
45
|
+
renderSeeqActionDropdown(tc.props);
|
|
46
|
+
expect(screen.getByTestId('trigger-icon')).toBeInTheDocument();
|
|
47
|
+
await openDropdown();
|
|
48
|
+
expect(screen.getByText('Orange')).toBeInTheDocument();
|
|
49
|
+
expect(screen.getByTestId('dropdown-divider-1')).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
test('calls onClick handler when dropdown item is selected', async () => {
|
|
52
|
+
renderSeeqActionDropdown(tc.props);
|
|
53
|
+
await openDropdown();
|
|
54
|
+
const item1 = screen.getByText('Orange');
|
|
55
|
+
await userEvent.click(item1);
|
|
56
|
+
expect(mockOnClick).toHaveBeenCalledTimes(1);
|
|
57
|
+
});
|
|
58
|
+
test('closes dropdown when item is clicked', async () => {
|
|
59
|
+
renderSeeqActionDropdown(tc.props);
|
|
60
|
+
await openDropdown();
|
|
61
|
+
const item1 = screen.getByText('Orange');
|
|
62
|
+
await userEvent.click(item1);
|
|
63
|
+
expect(mockOnClick).toHaveBeenCalledTimes(1);
|
|
64
|
+
expect(screen.queryByText('Orange')).not.toBeInTheDocument();
|
|
65
|
+
});
|
|
66
|
+
test('does not open when disabled', async () => {
|
|
67
|
+
tc.props.disabled = true;
|
|
68
|
+
renderSeeqActionDropdown(tc.props);
|
|
69
|
+
await openDropdown();
|
|
70
|
+
expect(screen.queryByText('Orange')).not.toBeInTheDocument();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -20,11 +20,6 @@ export interface SeeqActionDropdownItems {
|
|
|
20
20
|
* Use this to customize icon appearance beyond standard styling.
|
|
21
21
|
*/
|
|
22
22
|
iconExtraClassNames?: string;
|
|
23
|
-
/**
|
|
24
|
-
* Additional CSS classes to apply to the dropdown icon container.
|
|
25
|
-
* Use this to customize the icon's appearance beyond default Seeq styling.
|
|
26
|
-
*/
|
|
27
|
-
iconContainerExtraClassNames?: string;
|
|
28
23
|
/**
|
|
29
24
|
* Main display text for the dropdown item.
|
|
30
25
|
* This is the primary text that users see and click on to trigger the action.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './SeeqActionDropdown';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Icon from '../Icon/Icon';
|
|
3
|
+
import { isSvgIcon } from '../utils/svg';
|
|
4
|
+
import SvgIcon from '../SvgIcon/SvgIcon';
|
|
5
|
+
export const SeeqActionDropdownItem = (item) => {
|
|
6
|
+
let renderIcon = _jsx(_Fragment, {});
|
|
7
|
+
if (item.icon) {
|
|
8
|
+
renderIcon = isSvgIcon(item.icon) ? (_jsx(SvgIcon, { icon: item.icon, extraClassNames: 'tw-rounded-[3px] tw-h-8 tw-w-8 tw-p-1 tw-flex tw-justify-center tw-items-center tw-bg-sq-color-dark' +
|
|
9
|
+
' dark:tw-text-sq-white tw-text-[22px] tw-text-sq-white ' +
|
|
10
|
+
item.iconExtraClassNames, ...item })) : (_jsx(Icon, { icon: item.icon, type: "text", extraClassNames: 'tw-rounded-[3px] tw-h-8 tw-w-8 tw-flex tw-justify-center tw-items-center tw-bg-sq-color-dark dark:tw-text-sq-white tw-text-[1.375rem] tw-text-sq-white ' +
|
|
11
|
+
item.iconExtraClassNames }));
|
|
12
|
+
}
|
|
13
|
+
return (_jsxs("div", { className: "tw-flex-col tw-flex tw-p-[10px] tw-pl-5 tw-w-[600px]", children: [
|
|
14
|
+
_jsxs("div", { className: "tw-flex tw-flex-row tw-gap-2 tw-items-end", children: [renderIcon, _jsx("h4", { className: "tw-text-base tw-font-[600] tw-leading-[20px] mb-0", children: item.display })
|
|
15
|
+
] }), _jsx("div", { className: "tw-text-[0.8125rem] tw-font-normal", children: item.text })
|
|
16
|
+
] }));
|
|
17
|
+
};
|
|
18
|
+
export const ViewWorkbench = (item) => {
|
|
19
|
+
let renderIcon = _jsx(_Fragment, {});
|
|
20
|
+
if (item.icon) {
|
|
21
|
+
renderIcon = isSvgIcon(item.icon) ? (_jsx(SvgIcon, { icon: item.icon, extraClassNames: 'tw-flex tw-w-5 tw-justify-center tw-items-center tw-text-[1.25rem] dark:tw-text-sq-white' +
|
|
22
|
+
' tw-text-sq-text-color ' +
|
|
23
|
+
item.iconExtraClassNames, type: "default", ...item })) : (_jsx(Icon, { icon: item.icon, type: "text", extraClassNames: 'tw-flex tw-justify-center tw-items-center tw-text-[1.25rem] dark:tw-text-sq-white' +
|
|
24
|
+
' tw-text-sq-text-color ' +
|
|
25
|
+
item.iconExtraClassNames }));
|
|
26
|
+
}
|
|
27
|
+
return (_jsx("div", { className: "tw-flex-col tw-flex tw-p-[10px]", children: _jsxs("div", { className: "tw-flex tw-flex-row tw-gap-2 tw-items-end", children: [renderIcon, _jsx("div", { className: "tw-text-[0.8125rem]", children: item.display })
|
|
28
|
+
] }) }));
|
|
29
|
+
};
|
|
30
|
+
export const InsertSeeqContent = (item) => {
|
|
31
|
+
return (_jsxs("div", { className: "tw-flex-col tw-flex tw-justify-start tw-p-[10px] tw-font-normal tw-text-left tw-text-sq-text-color dark:tw-text-sq-dark-text", children: [
|
|
32
|
+
_jsx("h5", { className: "tw-text-[1rem] tw-font-medium tw-text-sq-color-dark tw-leading-[18px]", children: item.display }), _jsx("div", { className: "tw-text-[0.8125rem] tw-text-sq-text-color dark:tw-text-sq-dark-text !tw-mt-1", children: item.text })
|
|
33
|
+
] }));
|
|
34
|
+
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import '../styles.css';
|
|
3
|
+
import { createFilter, default as ReactSelect } from 'react-select';
|
|
4
|
+
import CreatableSelect from 'react-select/creatable';
|
|
5
|
+
const baseClasses = ['focus:tw-ring-0', 'disabled:tw-cursor-not-allowed'].join(' ');
|
|
6
|
+
const containerStyles = ['tw-bg-white', 'dark:tw-bg-sq-dark-background'].join(' ');
|
|
7
|
+
const errorClasses = 'tw-border-sq-danger-color';
|
|
8
|
+
const borderColorClasses = ['tw-border-sq-disabled-gray', 'dark:tw-border-sq-dark-disabled-gray'].join(' ');
|
|
9
|
+
const borderStyles = ['tw-border-solid', 'tw-border'].join(' ');
|
|
10
|
+
const borderActiveClasses = [
|
|
11
|
+
'hover:tw-border-sq-color-dark',
|
|
12
|
+
'focus-within:tw-border-sq-color-dark',
|
|
13
|
+
'active:tw-border-sq-color-dark',
|
|
14
|
+
'dark:hover:tw-border-sq-color-dark-dark',
|
|
15
|
+
'dark:focus-within:tw-border-sq-color-dark-dark',
|
|
16
|
+
'dark:active:tw-border-sq-color-dark-dark',
|
|
17
|
+
].join(' ');
|
|
18
|
+
const textStyles = ['tw-text-sq-text-color', 'dark:tw-text-sq-dark-text', 'tw-text-sm'].join(' ');
|
|
19
|
+
const textActiveStyles = [
|
|
20
|
+
'hover:tw-text-sq-color-dark',
|
|
21
|
+
'dark:tw-text-sq-dark-disabled-gray',
|
|
22
|
+
'dark:hover:tw-text-sq-color-dark-dark',
|
|
23
|
+
].join(' ');
|
|
24
|
+
const menuStyles = [
|
|
25
|
+
'tw-border-solid',
|
|
26
|
+
'tw-border',
|
|
27
|
+
'tw-rounded-b',
|
|
28
|
+
'tw-border-sq-disabled-gray',
|
|
29
|
+
'dark:tw-border-sq-dark-disabled-gray',
|
|
30
|
+
'tw-whitespace-nowrap',
|
|
31
|
+
'tw-min-w-fit',
|
|
32
|
+
'!tw-z-[9999]',
|
|
33
|
+
].join(' ');
|
|
34
|
+
const menuListStyles = [
|
|
35
|
+
'tw-rounded-b',
|
|
36
|
+
'tw-bg-white',
|
|
37
|
+
'dark:tw-bg-sq-dark-background',
|
|
38
|
+
'tw-min-w-fit',
|
|
39
|
+
'!tw-z-[9999]',
|
|
40
|
+
'specSelectMenu',
|
|
41
|
+
].join(' ');
|
|
42
|
+
const groupHeadingStyles = [
|
|
43
|
+
'tw-bg-sq-light-gray',
|
|
44
|
+
'dark:tw-bg-sq-dark-disabled-gray',
|
|
45
|
+
'tw-text-sq-darkish-gray',
|
|
46
|
+
'tw-py-1',
|
|
47
|
+
'tw-px-2.5',
|
|
48
|
+
'specSelectGroupHeading',
|
|
49
|
+
].join(' ');
|
|
50
|
+
const optionStyles = [
|
|
51
|
+
'hover:tw-bg-sq-gray-highlight',
|
|
52
|
+
'hover:tw-cursor-pointer',
|
|
53
|
+
'dark:hover:tw-bg-sq-gray-highlight-dark',
|
|
54
|
+
'tw-py-1',
|
|
55
|
+
'tw-px-2.5',
|
|
56
|
+
'specSelectOption',
|
|
57
|
+
].join(' ');
|
|
58
|
+
const disabledClasses = ['tw-bg-sq-field-disabled-gray', '!tw-cursor-not-allowed', 'tw-opacity-50'].join(' ');
|
|
59
|
+
const dropDownIndicatorStyles = `tw-text-sq-disabled-gray ${textActiveStyles} specOpenIt`;
|
|
60
|
+
const placeholderStyles = ['tw-text-gray-400', 'dark:tw-text-sq-dark-text-lighter', 'specOpenSelect'].join(' ');
|
|
61
|
+
const multiValueStyles = [
|
|
62
|
+
'tw-bg-sq-disabled-gray',
|
|
63
|
+
'dark:tw-bg-sq-multi-gray-dark',
|
|
64
|
+
'tw-text-sm',
|
|
65
|
+
'tw-py-0.5',
|
|
66
|
+
'tw-px-1',
|
|
67
|
+
'tw-m-0.5',
|
|
68
|
+
'tw-rounded-sm',
|
|
69
|
+
'specOpenSelect',
|
|
70
|
+
].join(' ');
|
|
71
|
+
/**
|
|
72
|
+
* Select Component
|
|
73
|
+
* - based on react-select (https://react-select.com/)
|
|
74
|
+
*
|
|
75
|
+
* For ease of testing most of the elements of this select can be identified by classNames prefixed with "spec".
|
|
76
|
+
*
|
|
77
|
+
*/
|
|
78
|
+
const Select = ({ options, value, placeholder = 'select', noOptionsMessage = 'no matching options', isSearchable = true, creatable = false, isMulti = false, isClearable = false, closeMenuOnSelect = true, id, inputId, menuPortalTarget, getOptionLabel, getSelectedValueLabel, getOptionValue, onChange, menuIsOpen, menuPlacement = 'auto', extraClassNames, controlClassNames = '', inputGroup, filterConfig, filterOption, small = false, isDisabled = false, showError = false, isLoading = false, formatGroupLabel, onRemove, defaultValue, onMenuOpen, onMenuClose, components, onMenuInputFocus, onInputChange, inputValue, }) => {
|
|
79
|
+
const getOptionOrSelectedLabel = (option, { context }) => {
|
|
80
|
+
const getSelectedOptionLabel = getSelectedValueLabel ? getSelectedValueLabel : getOptionLabel;
|
|
81
|
+
if (getOptionLabel || getSelectedValueLabel) {
|
|
82
|
+
if (context === 'value') {
|
|
83
|
+
return getSelectedOptionLabel ? getSelectedOptionLabel(option) : option.label;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return getOptionLabel ? getOptionLabel(option) : option.label;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
return option.label;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const interceptOnChange = (newValue, actionMeta) => {
|
|
94
|
+
if (isMulti && onRemove && actionMeta.action === 'remove-value') {
|
|
95
|
+
onRemove({ id: actionMeta.removedValue });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
onChange(newValue);
|
|
99
|
+
};
|
|
100
|
+
const props = {
|
|
101
|
+
id,
|
|
102
|
+
value,
|
|
103
|
+
inputId,
|
|
104
|
+
placeholder,
|
|
105
|
+
closeMenuOnSelect,
|
|
106
|
+
blurInputOnSelect: closeMenuOnSelect,
|
|
107
|
+
isSearchable: creatable ? true : isSearchable,
|
|
108
|
+
isMulti,
|
|
109
|
+
isClearable,
|
|
110
|
+
isLoading,
|
|
111
|
+
defaultValue,
|
|
112
|
+
noOptionsMessage: () => noOptionsMessage,
|
|
113
|
+
menuPortalTarget,
|
|
114
|
+
menuIsOpen,
|
|
115
|
+
onChange: interceptOnChange,
|
|
116
|
+
unstyled: true,
|
|
117
|
+
menuPlacement,
|
|
118
|
+
formatOptionLabel: getOptionOrSelectedLabel,
|
|
119
|
+
formatGroupLabel,
|
|
120
|
+
getOptionValue,
|
|
121
|
+
options,
|
|
122
|
+
isDisabled,
|
|
123
|
+
onMenuOpen,
|
|
124
|
+
onMenuClose,
|
|
125
|
+
components,
|
|
126
|
+
onMenuInputFocus,
|
|
127
|
+
onInputChange,
|
|
128
|
+
inputValue,
|
|
129
|
+
hideSelectedOptions: isMulti,
|
|
130
|
+
filterOption: filterOption ? filterOption : filterConfig ? createFilter(filterConfig) : undefined,
|
|
131
|
+
classNames: {
|
|
132
|
+
control: ({ menuIsOpen }) => {
|
|
133
|
+
let border = menuIsOpen ? 'tw-rounded-t-md' : 'tw-rounded-md';
|
|
134
|
+
// if it's on the left side of the input group make sure the right side is straight and not curved
|
|
135
|
+
if (inputGroup === 'left') {
|
|
136
|
+
border = menuIsOpen ? 'tw-rounded-tl-md' : 'tw-rounded-l-md';
|
|
137
|
+
}
|
|
138
|
+
else if (inputGroup === 'right') {
|
|
139
|
+
border = menuIsOpen ? 'tw-rounded-tr-md' : 'tw-rounded-r-md';
|
|
140
|
+
}
|
|
141
|
+
const appliedClasses = `${borderStyles} ${isDisabled ? '' : borderActiveClasses} ${border} ${showError ? errorClasses : borderColorClasses} ${small ? 'reactSelectMinHeightSmall' : 'reactSelectMinHeight'} ${controlClassNames}`;
|
|
142
|
+
return `${appliedClasses} ${baseClasses} ${containerStyles} specSelectControl ${isDisabled ? disabledClasses : ''} ${small ? 'tw-pl-2 tw-pr-1' : 'tw-pl-2.5 tw-pr-1.5'}`;
|
|
143
|
+
},
|
|
144
|
+
placeholder: () => placeholderStyles,
|
|
145
|
+
container: ({ selectProps }) => {
|
|
146
|
+
const containerBorderStyles = selectProps?.menuIsOpen ? 'tw-rounded-t-md' : 'tw-rounded-md';
|
|
147
|
+
return `${textStyles} ${extraClassNames} ${containerBorderStyles} !tw-pointer-events-auto`;
|
|
148
|
+
},
|
|
149
|
+
input: () => textStyles + ' specSelectInput',
|
|
150
|
+
menuList: () => menuListStyles,
|
|
151
|
+
menu: () => menuStyles,
|
|
152
|
+
menuPortal: () => '!tw-z-[9000]',
|
|
153
|
+
dropdownIndicator: () => dropDownIndicatorStyles,
|
|
154
|
+
option: ({ isSelected, isDisabled }) => {
|
|
155
|
+
let classes = optionStyles;
|
|
156
|
+
if (isDisabled) {
|
|
157
|
+
classes += ' specDisabledOption ';
|
|
158
|
+
}
|
|
159
|
+
return isSelected ? classes + ' tw-bg-sq-colored-hover dark:tw-bg-sq-colored-hover-dark' : classes;
|
|
160
|
+
},
|
|
161
|
+
singleValue: () => 'specOpenSelect',
|
|
162
|
+
multiValue: () => multiValueStyles,
|
|
163
|
+
multiValueRemove: () => 'hover:tw-text-sq-danger-color specSelectMultiValueRemove',
|
|
164
|
+
clearIndicator: () => 'tw-text-sq-disabled-gray hover:tw-text-sq-danger-color specClearSelect',
|
|
165
|
+
group: () => 'specSelectGroup',
|
|
166
|
+
groupHeading: () => groupHeadingStyles,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
return creatable ? _jsx(CreatableSelect, { ...props }) : _jsx(ReactSelect, { ...props });
|
|
170
|
+
};
|
|
171
|
+
export default Select;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Select from './Select';
|
|
3
|
+
import TextField from '../TextField';
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Select',
|
|
6
|
+
};
|
|
7
|
+
export const AllSelectVariants = () => {
|
|
8
|
+
const options = [
|
|
9
|
+
{ value: 'a', label: 'Chocolate' },
|
|
10
|
+
{ value: 'b', label: 'Strawberry' },
|
|
11
|
+
{ value: 'c', label: 'Vanilla' },
|
|
12
|
+
{ value: 'd', label: 'Rocky Road' },
|
|
13
|
+
{ value: 'e', label: 'Crazy Cow' },
|
|
14
|
+
{ value: 'f', label: 'Almond Joy' },
|
|
15
|
+
{ value: 'g', label: 'All of the above' },
|
|
16
|
+
];
|
|
17
|
+
const colorOptions = [
|
|
18
|
+
{ value: 'h', label: 'pink' },
|
|
19
|
+
{ value: 'i', label: 'purple' },
|
|
20
|
+
{ value: 'j', label: 'green' },
|
|
21
|
+
{ value: 'k', label: 'red' },
|
|
22
|
+
];
|
|
23
|
+
const groupedOptions = [
|
|
24
|
+
{
|
|
25
|
+
label: 'Ice Cream Flavors',
|
|
26
|
+
options: options,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: 'Colors',
|
|
30
|
+
options: colorOptions,
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
const customColorOption = (dropdownProps) => {
|
|
34
|
+
return _jsx("div", { style: { color: dropdownProps.data.label }, children: dropdownProps.data.label });
|
|
35
|
+
};
|
|
36
|
+
const allSelects = () => (_jsxs(_Fragment, { children: [
|
|
37
|
+
_jsx("div", { className: "tw-p-5", children: _jsx(Select, { id: "hello", onChange: () => { }, options: options, placeholder: "single value" }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { id: "hello", onChange: () => { }, options: options, placeholder: "single value - small", small: true }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { id: "disabled", onChange: () => { }, options: options, placeholder: "disabled", isDisabled: true }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { id: "error", onChange: () => { }, options: options, placeholder: "error", showError: true }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, options: options, placeholder: "stays open", closeMenuOnSelect: false, creatable: true }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, options: groupedOptions, placeholder: "grouped" }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, options: options, creatable: true, placeholder: "create option" }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, options: options, isClearable: true, placeholder: "clearable" }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, options: options, placeholder: "multi-select", isMulti: true, isSearchable: false }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, placeholder: "type to search", options: options, isSearchable: true }) }), _jsxs("div", { className: "tw-p-5 tw-flex tw-flex-row", children: [
|
|
38
|
+
_jsx(Select, { onChange: () => { }, placeholder: "type to search", options: options, inputGroup: "left", extraClassNames: "tw-w-[200px] tw-flex-2" }), _jsx(TextField, { extraClassNames: "tw-flex-1 tw-min-w-24", onChange: () => { }, placeholder: "change me", inputGroup: "right" })
|
|
39
|
+
] }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, options: colorOptions, placeholder: "custom option", components: { Option: (dropdownProps) => customColorOption(dropdownProps) } }) }), _jsx("div", { className: "tw-p-5", children: _jsx(Select, { onChange: () => { }, options: colorOptions, placeholder: "custom option", controlClassNames: "tw-border-0", components: { Option: (dropdownProps) => customColorOption(dropdownProps) } }) })
|
|
40
|
+
] }));
|
|
41
|
+
const renderAllVariations = () => (_jsxs(_Fragment, { children: [allSelects(), _jsx("div", { className: "tw-dark tw-bg-sq-dark-background", children: allSelects() })
|
|
42
|
+
] }));
|
|
43
|
+
return (_jsxs("div", { className: "tw-grid tw-grid-cols-4", children: [
|
|
44
|
+
_jsxs("div", { className: "color_topic", children: [
|
|
45
|
+
_jsx("b", { children: "Topic Colors" }), renderAllVariations()] }), _jsxs("div", { className: "color_analysis", children: [
|
|
46
|
+
_jsx("b", { children: "Analysis Colors" }), renderAllVariations()] }), _jsxs("div", { className: "color_datalab", children: [
|
|
47
|
+
_jsx("b", { children: "Datalab Colors" }), renderAllVariations()] }), _jsxs("div", { className: "color_vantage", children: [
|
|
48
|
+
_jsx("b", { children: "Vantage Colors" }), renderAllVariations()] })
|
|
49
|
+
] }));
|
|
50
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import { render, screen } from '@testing-library/react';
|
|
4
|
+
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import Select from './Select';
|
|
6
|
+
describe('Select', () => {
|
|
7
|
+
class Context {
|
|
8
|
+
testId = 'selectTestId';
|
|
9
|
+
label = 'button label';
|
|
10
|
+
options = [
|
|
11
|
+
{ label: 'vanilla', value: 'a' },
|
|
12
|
+
{ label: 'chocolate', value: 'b' },
|
|
13
|
+
{ label: 'strawberry', value: 'c' },
|
|
14
|
+
];
|
|
15
|
+
otherOptions = [
|
|
16
|
+
{ label: 'red', value: 'd' },
|
|
17
|
+
{ label: 'green', value: 'e' },
|
|
18
|
+
];
|
|
19
|
+
groupedOptions = [
|
|
20
|
+
{
|
|
21
|
+
label: 'Ice Cream Flavors',
|
|
22
|
+
options: this.options,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: 'Colors',
|
|
26
|
+
options: this.otherOptions,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
props = {
|
|
30
|
+
onChange: jest.fn(),
|
|
31
|
+
options: this.options,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
let tc;
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
tc = new Context();
|
|
37
|
+
});
|
|
38
|
+
const openSelect = async () => {
|
|
39
|
+
const select = document.querySelector(`.specOpenSelect`);
|
|
40
|
+
await userEvent.click(select);
|
|
41
|
+
};
|
|
42
|
+
const renderSelect = (props) => render(_jsx("div", { id: "wrapper", children: _jsx(Select, { ...props }) }));
|
|
43
|
+
it('renders the select', () => {
|
|
44
|
+
renderSelect(tc.props);
|
|
45
|
+
expect(document.querySelector('.specSelectControl')).toBeInTheDocument();
|
|
46
|
+
});
|
|
47
|
+
it('displays options', async () => {
|
|
48
|
+
renderSelect(tc.props);
|
|
49
|
+
await openSelect();
|
|
50
|
+
expect(document.querySelectorAll('.specSelectOption')).toHaveLength(3);
|
|
51
|
+
});
|
|
52
|
+
it('displays grouped options', async () => {
|
|
53
|
+
renderSelect({ ...tc.props, options: tc.groupedOptions });
|
|
54
|
+
await openSelect();
|
|
55
|
+
expect(document.querySelectorAll('.specSelectOption')).toHaveLength(5);
|
|
56
|
+
expect(document.querySelectorAll('.specSelectGroupHeading')).toHaveLength(2);
|
|
57
|
+
expect(document.querySelectorAll('.specSelectGroup')).toHaveLength(2);
|
|
58
|
+
});
|
|
59
|
+
it('reflects error state', () => {
|
|
60
|
+
renderSelect({ ...tc.props, showError: true });
|
|
61
|
+
expect(document.querySelector('.specSelectControl')).toHaveClass('tw-border-sq-danger-color');
|
|
62
|
+
});
|
|
63
|
+
it('reflects custom render function for option', async () => {
|
|
64
|
+
const getOptionLabel = (option) => (_jsxs("div", { children: [option.label, _jsx("br", {}),
|
|
65
|
+
"custom formatting applied"] }));
|
|
66
|
+
renderSelect({ ...tc.props, getOptionLabel });
|
|
67
|
+
await openSelect();
|
|
68
|
+
expect(document.querySelectorAll('.specSelectOption')[0]).toHaveTextContent('custom formatting applied');
|
|
69
|
+
});
|
|
70
|
+
it('reflects custom render for selected option', async () => {
|
|
71
|
+
const getSelectedValueLabel = (option) => (_jsxs("div", { children: [option.label, _jsx("br", {}),
|
|
72
|
+
"the chosen one"] }));
|
|
73
|
+
renderSelect({ ...tc.props, getSelectedValueLabel });
|
|
74
|
+
await openSelect();
|
|
75
|
+
await userEvent.click(screen.getByText(tc.options[0].label));
|
|
76
|
+
expect(document.querySelectorAll('.specOpenSelect')[0]).toHaveTextContent('the chosen one');
|
|
77
|
+
});
|
|
78
|
+
it('renders the provided value as selected', () => {
|
|
79
|
+
const value = tc.options[1];
|
|
80
|
+
renderSelect({ ...tc.props, value });
|
|
81
|
+
expect(document.querySelectorAll('.specOpenSelect')[0]).toHaveTextContent(value.label);
|
|
82
|
+
});
|
|
83
|
+
it('renders the provided placeholder', () => {
|
|
84
|
+
const placeholder = 'choose your favorite flavor';
|
|
85
|
+
renderSelect({ ...tc.props, placeholder });
|
|
86
|
+
expect(screen.getByText(placeholder)).toBeInTheDocument();
|
|
87
|
+
});
|
|
88
|
+
it('renders the provided noOptionsMessage', async () => {
|
|
89
|
+
const noOptionsMessage = 'Nothing to see here.';
|
|
90
|
+
renderSelect({ ...tc.props, noOptionsMessage, options: [] });
|
|
91
|
+
await openSelect();
|
|
92
|
+
expect(screen.getByText(noOptionsMessage)).toBeInTheDocument();
|
|
93
|
+
});
|
|
94
|
+
it('supports multi selection', async () => {
|
|
95
|
+
const isMulti = true;
|
|
96
|
+
renderSelect({ ...tc.props, isMulti });
|
|
97
|
+
await openSelect();
|
|
98
|
+
await userEvent.click(screen.getByText(tc.options[0].label));
|
|
99
|
+
await openSelect();
|
|
100
|
+
await userEvent.click(screen.getByText(tc.options[1].label));
|
|
101
|
+
expect(document.querySelectorAll('.specOpenSelect')).toHaveLength(2);
|
|
102
|
+
});
|
|
103
|
+
it('renders isClearable', async () => {
|
|
104
|
+
const isClearable = true;
|
|
105
|
+
const placeholder = 'no worries - you can clear this.';
|
|
106
|
+
renderSelect({ ...tc.props, isClearable, placeholder });
|
|
107
|
+
await openSelect();
|
|
108
|
+
await userEvent.click(screen.getByText(tc.options[0].label));
|
|
109
|
+
expect(document.querySelectorAll('.specOpenSelect')[0]).toHaveTextContent(tc.options[0].label);
|
|
110
|
+
expect(document.querySelector('.specClearSelect')).toBeInTheDocument();
|
|
111
|
+
await userEvent.click(document.querySelector('.specClearSelect'));
|
|
112
|
+
expect(document.querySelectorAll('.specOpenSelect')[0]).toHaveTextContent(placeholder);
|
|
113
|
+
});
|
|
114
|
+
it('supports menuIsOpen', async () => {
|
|
115
|
+
const menuIsOpen = true;
|
|
116
|
+
renderSelect({ ...tc.props, menuIsOpen, menuPortalTarget: document.querySelector('#wrapper') });
|
|
117
|
+
expect(document.querySelectorAll('.specSelectOption')).toHaveLength(tc.options.length);
|
|
118
|
+
});
|
|
119
|
+
it('supports closeMenuOnSelect', async () => {
|
|
120
|
+
const closeMenuOnSelect = false;
|
|
121
|
+
renderSelect({ ...tc.props, closeMenuOnSelect });
|
|
122
|
+
await openSelect();
|
|
123
|
+
await userEvent.click(screen.getByText(tc.options[1].label));
|
|
124
|
+
await userEvent.click(screen.getByText(tc.options[2].label));
|
|
125
|
+
expect(document.querySelectorAll('.specOpenSelect')[0]).toHaveTextContent(tc.options[2].label);
|
|
126
|
+
});
|
|
127
|
+
it('removes selected option from multi-select options list', async () => {
|
|
128
|
+
const closeMenuOnSelect = false;
|
|
129
|
+
renderSelect({ ...tc.props, isMulti: true, closeMenuOnSelect });
|
|
130
|
+
await openSelect();
|
|
131
|
+
await userEvent.click(screen.getByText(tc.options[1].label));
|
|
132
|
+
await userEvent.click(screen.getByText(tc.options[2].label));
|
|
133
|
+
expect(document.querySelectorAll('.specSelectOption')).toHaveLength(tc.options.length - 2);
|
|
134
|
+
});
|
|
135
|
+
it('calls onChange handler', async () => {
|
|
136
|
+
const onChange = jest.fn();
|
|
137
|
+
renderSelect({ ...tc.props, onChange });
|
|
138
|
+
await openSelect();
|
|
139
|
+
await userEvent.click(screen.getByText(tc.options[1].label));
|
|
140
|
+
expect(onChange).toHaveBeenCalledWith(tc.options[1]);
|
|
141
|
+
});
|
|
142
|
+
it('includes inputId', async () => {
|
|
143
|
+
const inputId = 'idMe';
|
|
144
|
+
renderSelect({ ...tc.props, inputId });
|
|
145
|
+
expect(document.querySelector(`#${inputId}`)).toBeInTheDocument();
|
|
146
|
+
});
|
|
147
|
+
it('supports creating options', async () => {
|
|
148
|
+
const inputId = 'idMe';
|
|
149
|
+
const favorite = 'Almond Joy';
|
|
150
|
+
renderSelect({ ...tc.props, creatable: true, inputId });
|
|
151
|
+
await openSelect();
|
|
152
|
+
await userEvent.type(document.querySelector(`#${inputId}`), favorite);
|
|
153
|
+
expect(screen.getByText(`Create "${favorite}"`)).toBeInTheDocument();
|
|
154
|
+
});
|
|
155
|
+
it('supports onMenuOpen', async () => {
|
|
156
|
+
const onMenuOpen = jest.fn();
|
|
157
|
+
renderSelect({ ...tc.props, onMenuOpen });
|
|
158
|
+
await openSelect();
|
|
159
|
+
expect(onMenuOpen).toHaveBeenCalled();
|
|
160
|
+
});
|
|
161
|
+
it('supports onMenuClose', async () => {
|
|
162
|
+
const onMenuClose = jest.fn();
|
|
163
|
+
renderSelect({ ...tc.props, onMenuClose });
|
|
164
|
+
await openSelect();
|
|
165
|
+
await userEvent.click(screen.getByText(tc.options[0].label));
|
|
166
|
+
expect(onMenuClose).toHaveBeenCalled();
|
|
167
|
+
});
|
|
168
|
+
it('supports custom components', async () => {
|
|
169
|
+
const components = {
|
|
170
|
+
DropdownIndicator: () => _jsx("div", { className: "custom", children: "Custom Dropdown" }),
|
|
171
|
+
};
|
|
172
|
+
renderSelect({ ...tc.props, components });
|
|
173
|
+
await openSelect();
|
|
174
|
+
expect(document.querySelector('.custom')).toBeInTheDocument();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as RadixSlider from '@radix-ui/react-slider';
|
|
3
|
+
/**
|
|
4
|
+
* Slider .
|
|
5
|
+
*/
|
|
6
|
+
export const Slider = (props) => {
|
|
7
|
+
const { onValueChange, onPointerUp, id, value, name, disabled = false, rootExtraClassNames = '', trackExtraClassNames = '', rangeExtraClassNames = '', thumbExtraClassNames = '', step, min, max, } = props;
|
|
8
|
+
return (_jsxs(RadixSlider.Root, { className: `tw-relative tw-flex tw-h-5 tw-w-full tw-touch-none tw-select-none tw-items-center ${rootExtraClassNames}`, defaultValue: [value], value: [value], onValueChange: (value) => onValueChange && onValueChange(value), onPointerUp: (e) => onPointerUp && onPointerUp(e), name: name, id: id, max: max, min: min, disabled: disabled, step: step, children: [
|
|
9
|
+
_jsx(RadixSlider.Track, { className: `tw-relative tw-h-[5px] tw-grow tw-rounded-[4px] tw-bg-sq-dark-gray dark:tw-bg-sq-dark-disabled-gray ${trackExtraClassNames}`, children: _jsx(RadixSlider.Range, { className: `tw-absolute tw-h-full tw-rounded-full ${rangeExtraClassNames}` }) }), _jsx(RadixSlider.Thumb, { className: `tw-block tw-h-[15px] tw-w-[15px] tw-rounded-full tw-bg-sq-color-dark active:tw-bg-sq-color-dark-dark focus:outline-none focus-visible:tw-outline-none aria-disabled:tw-bg-sq-dark-gray dark:aria-disabled:tw-bg-sq-dark-disabled-gray tw-transition tw-ease-in-out ${thumbExtraClassNames}`, "aria-disabled": disabled })
|
|
10
|
+
] }));
|
|
11
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Slider } from './Slider';
|
|
4
|
+
import { QTip } from '../Tooltip';
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Slider',
|
|
7
|
+
};
|
|
8
|
+
export const AllSliders = () => {
|
|
9
|
+
const [value1, setValue1] = React.useState(0);
|
|
10
|
+
const [value2, setValue2] = React.useState(0);
|
|
11
|
+
const renderAllVariations = () => (_jsxs(_Fragment, { children: [
|
|
12
|
+
_jsxs("div", { className: "tw-p-4 light", children: [
|
|
13
|
+
_jsx("div", { className: "tw-p-4", children: _jsx(Slider, { min: 0, max: 10, value: 4 }) }), _jsx("div", { className: "tw-p-4", children: _jsx(Slider, { min: 0, max: 10, value: 10 }) }), _jsx("div", { className: "tw-p-4", children: _jsx(Slider, { value: 0, min: 0, max: 10 }) }), _jsxs("div", { className: "tw-p-4", children: [
|
|
14
|
+
_jsx("div", { children: "1 Step" }), _jsx(Slider, { value: value1, min: 0, max: 20, step: 4, onValueChange: (v) => setValue1(v[0]) })
|
|
15
|
+
] }), _jsxs("div", { className: "tw-p-4", children: [
|
|
16
|
+
_jsx("div", { children: "10 Steps" }), _jsx(Slider, { value: value2, min: 0, max: 20, step: 10, onValueChange: (v) => setValue2(v[0]) })
|
|
17
|
+
] }), _jsxs("div", { className: "tw-p-4", children: [
|
|
18
|
+
_jsx("div", { className: "tw-sq-text-color", children: "Disabled" }), _jsx(Slider, { value: 10, min: 0, max: 20, step: 10, disabled: true })
|
|
19
|
+
] })
|
|
20
|
+
] }), _jsxs("div", { className: "tw-p-4 tw-dark tw-bg-sq-dark-background", children: [
|
|
21
|
+
_jsx("div", { className: "tw-p-4", children: _jsx(Slider, { min: 0, max: 10, value: 4 }) }), _jsx("div", { className: "tw-p-4", children: _jsx(Slider, { min: 0, max: 10, value: 10 }) }), _jsx("div", { className: "tw-p-4", children: _jsx(Slider, { value: 0, min: 0, max: 10 }) }), _jsxs("div", { className: "tw-p-4", children: [
|
|
22
|
+
_jsx("div", { className: "dark:tw-text-white", children: "1 Step" }), _jsx(Slider, { value: value1, min: 0, max: 20, step: 4, onValueChange: (v) => setValue1(v[0]) })
|
|
23
|
+
] }), _jsxs("div", { className: "tw-p-4", children: [
|
|
24
|
+
_jsx("div", { className: "dark:tw-text-white", children: "10 Steps" }), _jsx(Slider, { value: value2, min: 0, max: 20, step: 10, onValueChange: (v) => setValue2(v[0]) })
|
|
25
|
+
] }), _jsxs("div", { className: "tw-p-4", children: [
|
|
26
|
+
_jsx("div", { className: "dark:tw-text-white", children: "Disabled" }), _jsx(Slider, { value: 10, min: 0, max: 20, step: 10, disabled: true })
|
|
27
|
+
] })
|
|
28
|
+
] })
|
|
29
|
+
] }));
|
|
30
|
+
return (_jsxs("div", { className: "tw-grid tw-grid-cols-4 tw-gap-4", children: [
|
|
31
|
+
_jsx(QTip, {}), _jsxs("div", { className: "color_topic", children: [
|
|
32
|
+
_jsx("b", { children: "Topic Colors" }), renderAllVariations()] }), _jsxs("div", { className: "color_analysis", children: [
|
|
33
|
+
_jsx("b", { children: "Analysis Colors" }), renderAllVariations()] }), _jsxs("div", { className: "color_datalab", children: [
|
|
34
|
+
_jsx("b", { children: "Datalab Colors" }), renderAllVariations()] }), _jsxs("div", { className: "color_vantage", children: [
|
|
35
|
+
_jsx("b", { children: "Vantage Colors" }), renderAllVariations()] })
|
|
36
|
+
] }));
|
|
37
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import { Slider } from './Slider';
|
|
4
|
+
describe('Slider Component', () => {
|
|
5
|
+
const defaultProps = {
|
|
6
|
+
onValueChange: jest.fn(),
|
|
7
|
+
onPointerUp: jest.fn(),
|
|
8
|
+
id: 'test-slider',
|
|
9
|
+
value: 50,
|
|
10
|
+
name: 'slider',
|
|
11
|
+
disabled: false,
|
|
12
|
+
testId: 'slider',
|
|
13
|
+
step: 1,
|
|
14
|
+
min: 0,
|
|
15
|
+
max: 100,
|
|
16
|
+
};
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
global.ResizeObserver = jest.fn().mockImplementation(() => {
|
|
19
|
+
return { observe: jest.fn(), disconnect: jest.fn(), unobserve: jest.fn() };
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
it('renders without crashing', () => {
|
|
23
|
+
const { getByRole } = render(_jsx(Slider, { ...defaultProps }));
|
|
24
|
+
expect(getByRole('slider')).toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
it('is disabled when disabled prop is true', () => {
|
|
27
|
+
const { getByRole } = render(_jsx(Slider, { ...defaultProps, disabled: true }));
|
|
28
|
+
const thumb = getByRole('slider');
|
|
29
|
+
expect(thumb).toHaveAttribute('data-disabled', '');
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Slider as default } from './Slider';
|