@hlf-fe/pulmo-ui 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -54
- package/dist/components/buttons/button/button.js +1 -1
- package/dist/components/buttons/button/button.stories.js +6 -1
- package/dist/components/buttons/loading-button/loading-button.d.ts +14 -0
- package/dist/components/buttons/loading-button/loading-button.js +26 -0
- package/dist/components/buttons/loading-button/loading-button.stories.d.ts +7 -0
- package/dist/components/buttons/loading-button/loading-button.stories.js +23 -0
- package/dist/components/buttons/text-button/text-button.d.ts +20 -0
- package/dist/components/buttons/text-button/text-button.js +61 -0
- package/dist/components/buttons/text-button/text-button.stories.d.ts +6 -0
- package/dist/components/buttons/text-button/text-button.stories.js +16 -0
- package/dist/components/decorator/decorator.d.ts +7 -0
- package/dist/components/decorator/decorator.js +13 -0
- package/dist/components/feedback/alert/alert.d.ts +17 -0
- package/dist/components/feedback/alert/alert.js +68 -0
- package/dist/components/feedback/alert/alert.stories.d.ts +6 -0
- package/dist/components/feedback/alert/alert.stories.js +23 -0
- package/dist/components/icons/chevron-left-icon/chevron-left-icon.d.ts +7 -0
- package/dist/components/icons/chevron-left-icon/chevron-left-icon.js +3 -0
- package/dist/components/icons/chevron-left-icon/chevron-left-icon.stories.d.ts +6 -0
- package/dist/components/icons/chevron-left-icon/chevron-left-icon.stories.js +14 -0
- package/dist/components/icons/chevron-right-icon/chevron-right-icon.d.ts +7 -0
- package/dist/components/icons/chevron-right-icon/chevron-right-icon.js +3 -0
- package/dist/components/icons/chevron-right-icon/chevron-right-icon.stories.d.ts +6 -0
- package/dist/components/icons/chevron-right-icon/chevron-right-icon.stories.js +14 -0
- package/dist/components/icons/close-icon/close-icon.d.ts +12 -0
- package/dist/components/icons/close-icon/close-icon.js +9 -0
- package/dist/components/icons/close-icon/close-icon.stories.d.ts +6 -0
- package/dist/components/icons/close-icon/close-icon.stories.js +16 -0
- package/dist/components/icons/exclamation-mark-icon/exclamation-mark-icon.d.ts +3 -0
- package/dist/components/icons/exclamation-mark-icon/exclamation-mark-icon.js +3 -0
- package/dist/components/icons/exclamation-mark-icon/exclamation-mark-icon.stories.d.ts +6 -0
- package/dist/components/icons/exclamation-mark-icon/exclamation-mark-icon.stories.js +16 -0
- package/dist/components/icons/loading-spinner/loading-spinner.d.ts +20 -0
- package/dist/components/icons/loading-spinner/loading-spinner.js +32 -0
- package/dist/components/icons/loading-spinner/loading-spinner.stories.d.ts +6 -0
- package/dist/components/icons/loading-spinner/loading-spinner.stories.js +18 -0
- package/dist/components/icons/search-icon/search-icon.d.ts +5 -0
- package/dist/components/icons/search-icon/search-icon.js +3 -0
- package/dist/components/icons/search-icon/search-icon.stories.d.ts +6 -0
- package/dist/components/icons/search-icon/search-icon.stories.js +18 -0
- package/dist/components/icons/toggable-chevron/toggable-chevron.d.ts +12 -0
- package/dist/components/icons/toggable-chevron/toggable-chevron.js +20 -0
- package/dist/components/icons/toggable-chevron/toggable-chevron.stories.d.ts +7 -0
- package/dist/components/icons/toggable-chevron/toggable-chevron.stories.js +21 -0
- package/dist/components/icons/toggable-plus-minus-icon/toggable-plus-minus-icon.d.ts +6 -0
- package/dist/components/icons/toggable-plus-minus-icon/toggable-plus-minus-icon.js +13 -0
- package/dist/components/icons/toggable-plus-minus-icon/toggable-plus-minus-icon.stories.d.ts +7 -0
- package/dist/components/icons/toggable-plus-minus-icon/toggable-plus-minus-icon.stories.js +21 -0
- package/dist/components/icons/warning-icon/warning-icon.d.ts +3 -0
- package/dist/components/icons/warning-icon/warning-icon.js +3 -0
- package/dist/components/icons/warning-icon/warning-icon.stories.d.ts +6 -0
- package/dist/components/icons/warning-icon/warning-icon.stories.js +16 -0
- package/dist/components/inputs/dropdown/dropdown-list-item.d.ts +6 -0
- package/dist/components/inputs/dropdown/dropdown-list-item.js +33 -0
- package/dist/components/inputs/dropdown/dropdown.d.ts +13 -0
- package/dist/components/inputs/dropdown/dropdown.js +109 -0
- package/dist/components/inputs/dropdown/dropdown.stories.d.ts +7 -0
- package/dist/components/inputs/dropdown/dropdown.stories.js +84 -0
- package/dist/components/inputs/form-error/form-error.d.ts +11 -0
- package/dist/components/inputs/form-error/form-error.js +16 -0
- package/dist/components/inputs/form-error/form-error.stories.d.ts +6 -0
- package/dist/components/inputs/form-error/form-error.stories.js +22 -0
- package/dist/components/inputs/form-label/form-label.d.ts +7 -0
- package/dist/components/inputs/form-label/form-label.js +12 -0
- package/dist/components/inputs/form-label/form-label.stories.d.ts +6 -0
- package/dist/components/inputs/form-label/form-label.stories.js +16 -0
- package/dist/components/inputs/text-field/text-field.d.ts +32 -0
- package/dist/components/inputs/text-field/text-field.js +65 -0
- package/dist/components/inputs/text-field/text-field.stories.d.ts +11 -0
- package/dist/components/inputs/text-field/text-field.stories.js +51 -0
- package/dist/components/layout/accordion/accordion.d.ts +13 -0
- package/dist/components/layout/accordion/accordion.js +115 -0
- package/dist/components/layout/accordion/accordion.stories.d.ts +6 -0
- package/dist/components/layout/accordion/accordion.stories.js +14 -0
- package/dist/components/layout/container/container.d.ts +10 -0
- package/dist/components/layout/container/container.js +19 -0
- package/dist/components/layout/container/container.stories.d.ts +9 -0
- package/dist/components/layout/container/container.stories.js +47 -0
- package/dist/components/layout/image/image.d.ts +22 -0
- package/dist/components/layout/image/image.js +27 -0
- package/dist/components/layout/image/image.stories.d.ts +6 -0
- package/dist/components/layout/image/image.stories.js +33 -0
- package/dist/components/modules/email-signup-form/email-signup-form.d.ts +16 -0
- package/dist/components/modules/email-signup-form/email-signup-form.js +63 -0
- package/dist/components/modules/email-signup-form/email-signup-form.stories.d.ts +9 -0
- package/dist/components/modules/email-signup-form/email-signup-form.stories.js +51 -0
- package/dist/components/modules/entry-list/entry-list.d.ts +27 -0
- package/dist/components/modules/entry-list/entry-list.js +54 -0
- package/dist/components/modules/entry-list/entry-list.stories.d.ts +6 -0
- package/dist/components/modules/entry-list/entry-list.stories.js +14 -0
- package/dist/components/navigation/pagination/pagination.d.ts +12 -0
- package/dist/components/navigation/pagination/pagination.js +114 -0
- package/dist/components/navigation/pagination/pagination.stories.d.ts +6 -0
- package/dist/components/navigation/pagination/pagination.stories.js +21 -0
- package/dist/constants/general.d.ts +4 -0
- package/dist/constants/general.js +5 -0
- package/dist/hoc/withDefaultTheme.d.ts +1 -1
- package/dist/hoc/withDefaultTheme.js +4 -8
- package/dist/index.d.ts +40 -2
- package/dist/index.js +42 -2
- package/dist/styles/mixins.js +8 -4
- package/dist/styles/theme.d.ts +11 -9
- package/dist/styles/theme.js +12 -11
- package/package.json +78 -67
- package/dist/App.d.ts +0 -3
- package/dist/App.js +0 -10
- package/dist/main.d.ts +0 -1
- package/dist/main.js +0 -6
- package/dist/stories/Button.d.ts +0 -14
- package/dist/stories/Button.js +0 -20
- package/dist/stories/Button.stories.d.ts +0 -23
- package/dist/stories/Button.stories.js +0 -44
- package/dist/stories/Header.d.ts +0 -12
- package/dist/stories/Header.js +0 -4
- package/dist/stories/Header.stories.d.ts +0 -18
- package/dist/stories/Header.stories.js +0 -26
- package/dist/stories/Page.d.ts +0 -3
- package/dist/stories/Page.js +0 -7
- package/dist/stories/Page.stories.d.ts +0 -12
- package/dist/stories/Page.stories.js +0 -24
- package/dist/styles/styles/mixins/theme-mixins.d.ts +0 -5
- package/dist/styles/styles/mixins/theme-mixins.js +0 -37
- package/dist/styles/styles/mixins/units.d.ts +0 -3
- package/dist/styles/styles/mixins/units.js +0 -3
- package/dist/styles/styles/mixins.d.ts +0 -48
- package/dist/styles/styles/mixins.js +0 -336
- package/dist/styles/styles/theme.d.ts +0 -135
- package/dist/styles/styles/theme.js +0 -77
- package/dist/styles/types.d.ts +0 -3
- package/dist/styles/types.js +0 -1
- package/dist/styles/withDefaultTheme.d.ts +0 -1
- package/dist/styles/withDefaultTheme.js +0 -12
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styled, { keyframes } from "styled-components";
|
|
3
|
+
import { rem } from "../../../styles/units";
|
|
4
|
+
export const LoadingSpinner = ({ color, className, size = "m", }) => {
|
|
5
|
+
const width = {
|
|
6
|
+
s: rem(16),
|
|
7
|
+
m: rem(32),
|
|
8
|
+
l: rem(64),
|
|
9
|
+
};
|
|
10
|
+
const padding = {
|
|
11
|
+
s: rem(2),
|
|
12
|
+
m: rem(4),
|
|
13
|
+
l: rem(8),
|
|
14
|
+
};
|
|
15
|
+
return (_jsx(Spinner, { className: className, color: color, size: size, width: width, padding: padding }));
|
|
16
|
+
};
|
|
17
|
+
const rotate = keyframes `
|
|
18
|
+
100% {
|
|
19
|
+
transform: rotate(360deg);
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
const Spinner = styled.div `
|
|
23
|
+
width: ${({ width, size }) => width?.[size]};
|
|
24
|
+
padding: ${({ padding, size }) => padding?.[size]};
|
|
25
|
+
aspect-ratio: 1;
|
|
26
|
+
border-radius: 50%;
|
|
27
|
+
background: ${({ color, theme }) => (color ? color : theme?.blueNavy)};
|
|
28
|
+
mask: conic-gradient(#0000 0, #000), linear-gradient(#000 0 0) content-box;
|
|
29
|
+
mask-composite: source-out;
|
|
30
|
+
-webkit-mask-composite: source-out;
|
|
31
|
+
animation: ${rotate} 1s infinite linear;
|
|
32
|
+
`;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { LoadingSpinner } from "./loading-spinner";
|
|
3
|
+
declare const meta: Meta<typeof LoadingSpinner>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof LoadingSpinner>;
|
|
6
|
+
export declare const Default: Story;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { LoadingSpinner } from "./loading-spinner";
|
|
3
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
4
|
+
import { COLORS } from "../../../styles/theme";
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "Icons/LoadingSpinner",
|
|
7
|
+
component: LoadingSpinner,
|
|
8
|
+
decorators: [
|
|
9
|
+
(Story) => (_jsx(Decorator, { children: _jsx(Story, {}) })),
|
|
10
|
+
],
|
|
11
|
+
};
|
|
12
|
+
export default meta;
|
|
13
|
+
export const Default = {
|
|
14
|
+
args: {
|
|
15
|
+
size: "m",
|
|
16
|
+
color: COLORS.red,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { COLORS } from "../../../styles/theme";
|
|
3
|
+
export const SearchIcon = ({ color = COLORS.blackLight, width = 32, height = 32, }) => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: width, height: height, viewBox: `0 0 32 32`, children: _jsx("path", { fill: color, d: "M16 6a9 9 0 0 1 7.032 14.617l3.675 3.676a1 1 0 0 1-1.32 1.497l-.094-.083-3.676-3.675A9 9 0 1 1 16 6zm0 2a7 7 0 1 0 4.865 12.033.732.732 0 0 1 .078-.09l.09-.078A7 7 0 0 0 16 8z" }) }));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { SearchIcon } from "./search-icon";
|
|
3
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Icons/SearchIcon",
|
|
6
|
+
component: SearchIcon,
|
|
7
|
+
decorators: [
|
|
8
|
+
(Story) => (_jsx(Decorator, { children: _jsx(Story, {}) })),
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {
|
|
13
|
+
args: {
|
|
14
|
+
color: "#333",
|
|
15
|
+
width: 32,
|
|
16
|
+
height: 32,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type ToggableChevronProps = {
|
|
2
|
+
toggled?: boolean;
|
|
3
|
+
disableCircle?: boolean;
|
|
4
|
+
className?: string;
|
|
5
|
+
rotation?: number;
|
|
6
|
+
};
|
|
7
|
+
type ChevronDownProps = {
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const ChevronDownIcon: ({ className }: ChevronDownProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const ToggableChevron: ({ toggled, disableCircle, rotation, className, }: ToggableChevronProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styled, { css } from "styled-components";
|
|
3
|
+
export const ChevronDownIcon = ({ className }) => (_jsx("svg", { width: "16px", height: "16px", viewBox: "0 0 16 16", version: "1.1", xmlns: "http://www.w3.org/2000/svg", fill: "#333333", className: className, children: _jsx("path", { d: "M2.29289322,5.29289322 C2.65337718,4.93240926 3.22060824,4.90467972 3.61289944,5.20970461 L3.70710678,5.29289322 L8,9.585 L12.2928932,5.29289322 C12.6533772,4.93240926 13.2206082,4.90467972 13.6128994,5.20970461 L13.7071068,5.29289322 C14.0675907,5.65337718 14.0953203,6.22060824 13.7902954,6.61289944 L13.7071068,6.70710678 L8.70710678,11.7071068 C8.34662282,12.0675907 7.77939176,12.0953203 7.38710056,11.7902954 L7.29289322,11.7071068 L2.29289322,6.70710678 C1.90236893,6.31658249 1.90236893,5.68341751 2.29289322,5.29289322 Z" }) }));
|
|
4
|
+
export const ToggableChevron = ({ toggled, disableCircle = true, rotation, className, }) => (_jsx(Chevron, { toggled: toggled, disableCircle: disableCircle, rotation: rotation, className: className, children: _jsx(ChevronDownIcon, {}) }));
|
|
5
|
+
const Chevron = styled.div `
|
|
6
|
+
width: 22px;
|
|
7
|
+
height: 22px;
|
|
8
|
+
border: 1px solid rgba(19, 20, 21, 0.2);
|
|
9
|
+
border-radius: 50%;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-shrink: 0;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
align-items: center;
|
|
14
|
+
|
|
15
|
+
${({ toggled, disableCircle, rotation }) => css `
|
|
16
|
+
transform: scaleY(${toggled ? -1 : 1})
|
|
17
|
+
${rotation && `rotate(${rotation}deg)`};
|
|
18
|
+
border-width: ${toggled || disableCircle ? 0 : 1};
|
|
19
|
+
`};
|
|
20
|
+
`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { ToggableChevron } from "./toggable-chevron";
|
|
3
|
+
declare const meta: Meta<typeof ToggableChevron>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof ToggableChevron>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Toggled: Story;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ToggableChevron } from "./toggable-chevron";
|
|
3
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Icons/ToggableChevron",
|
|
6
|
+
component: ToggableChevron,
|
|
7
|
+
decorators: [
|
|
8
|
+
(Story) => (_jsx(Decorator, { children: _jsx(Story, {}) })),
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {
|
|
13
|
+
args: {
|
|
14
|
+
toggled: false,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export const Toggled = {
|
|
18
|
+
args: {
|
|
19
|
+
toggled: true,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
export const ToggablePlusMinusIcon = ({ isOpen = false, width = 14, height = 14, className = "", }) => {
|
|
4
|
+
return (_jsxs(Svg, { className: className, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 160 160", width: width, height: height, isOpen: isOpen, children: [_jsx(Rect, { isOpen: isOpen, x: "70", width: "20", height: "160" }), _jsx(Rect, { y: "70", width: "160", height: "20" })] }));
|
|
5
|
+
};
|
|
6
|
+
const Svg = styled.svg `
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
`;
|
|
9
|
+
const Rect = styled.rect `
|
|
10
|
+
transition: transform 250ms ease-in-out;
|
|
11
|
+
transform-origin: 50% 50%;
|
|
12
|
+
transform: ${({ isOpen }) => (!isOpen ? "scaleY(1)" : "scaleY(0)")};
|
|
13
|
+
`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { ToggablePlusMinusIcon } from "./toggable-plus-minus-icon";
|
|
3
|
+
declare const meta: Meta<typeof ToggablePlusMinusIcon>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof ToggablePlusMinusIcon>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Toggled: Story;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ToggablePlusMinusIcon } from "./toggable-plus-minus-icon";
|
|
3
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Icons/ToggablePlusMinusIcon",
|
|
6
|
+
component: ToggablePlusMinusIcon,
|
|
7
|
+
decorators: [
|
|
8
|
+
(Story) => (_jsx(Decorator, { children: _jsx(Story, {}) })),
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {
|
|
13
|
+
args: {
|
|
14
|
+
isOpen: false,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export const Toggled = {
|
|
18
|
+
args: {
|
|
19
|
+
isOpen: true,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { COLORS } from "../../../styles/theme";
|
|
3
|
+
export const WarningIcon = ({ color = COLORS.red }) => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: 32, height: 32, children: _jsx("path", { fill: color, fillRule: "nonzero", d: "M16.447 6c1.049 0 2.021.548 2.568 1.449l8.478 14.154a3 3 0 0 1-2.576 4.5H7.966a3 3 0 0 1-2.557-4.514l8.473-14.145A3 3 0 0 1 16.447 6Zm0 2a.998.998 0 0 0-.852.477L7.133 22.603a1 1 0 0 0 .844 1.5h16.929a1 1 0 0 0 .863-1.486L17.302 8.48A1 1 0 0 0 16.447 8Zm.01 12.103a1 1 0 0 1 .117 1.993l-.127.007a1 1 0 0 1-.117-1.994l.127-.006Zm-.01-8a1 1 0 0 1 .993.883l.007.117v4a1 1 0 0 1-1.993.116l-.007-.116v-4a1 1 0 0 1 1-1Z" }) }));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { WarningIcon } from "./warning-icon";
|
|
3
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Icons/WarningIcon",
|
|
6
|
+
component: WarningIcon,
|
|
7
|
+
decorators: [
|
|
8
|
+
(Story) => (_jsx(Decorator, { children: _jsx(Story, {}) })),
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {
|
|
13
|
+
args: {
|
|
14
|
+
color: "#333",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
import { rem } from "../../../styles/units";
|
|
4
|
+
export const DropdownListItem = ({ label, onClick }) => {
|
|
5
|
+
return (_jsx(ListItem, { children: _jsx(ListElement, { onClick: onClick, children: _jsx(Paragraph, { children: label }) }) }));
|
|
6
|
+
};
|
|
7
|
+
const ListItem = styled.li `
|
|
8
|
+
padding: 0;
|
|
9
|
+
margin: 0;
|
|
10
|
+
margin-bottom: ${rem(1)};
|
|
11
|
+
`;
|
|
12
|
+
const ListElement = styled.button `
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
width: 100%;
|
|
16
|
+
text-align: left;
|
|
17
|
+
margin: 0;
|
|
18
|
+
padding: ${rem(12)} ${rem(6)};
|
|
19
|
+
border: none;
|
|
20
|
+
border-radius: ${rem(4)};
|
|
21
|
+
background: white;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
|
|
24
|
+
&:hover,
|
|
25
|
+
:focus-visible {
|
|
26
|
+
background-color: ${({ theme }) => theme.grayLight};
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
const Paragraph = styled.p `
|
|
30
|
+
font-family: ${({ theme }) => theme.valueRegular};
|
|
31
|
+
font-size: ${rem(16)};
|
|
32
|
+
margin: 0;
|
|
33
|
+
`;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type DropdownItem = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string | boolean;
|
|
4
|
+
};
|
|
5
|
+
export type DropdownProps = {
|
|
6
|
+
prefix?: string;
|
|
7
|
+
id?: string;
|
|
8
|
+
items: DropdownItem[];
|
|
9
|
+
className?: string;
|
|
10
|
+
onItemSelected: (_: DropdownItem) => void;
|
|
11
|
+
initialValue: DropdownItem;
|
|
12
|
+
};
|
|
13
|
+
export declare const Dropdown: ({ prefix, items, id, className, onItemSelected, initialValue, }: DropdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import styled, { css } from "styled-components";
|
|
4
|
+
import { ToggableChevron } from "../../../components/icons/toggable-chevron/toggable-chevron";
|
|
5
|
+
import { DropdownListItem } from "./dropdown-list-item";
|
|
6
|
+
import { media } from "../../../styles/mixins";
|
|
7
|
+
import { rem } from "../../../styles/units";
|
|
8
|
+
export const Dropdown = ({ prefix, items, id, className, onItemSelected, initialValue, }) => {
|
|
9
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
10
|
+
const [selectedItem, setItem] = useState(initialValue || items?.[0] || undefined);
|
|
11
|
+
const ref = useRef(null);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const handleClickOutsideMenu = (e) => {
|
|
14
|
+
if (ref.current && !ref.current.contains(e?.target)) {
|
|
15
|
+
setIsOpen(false);
|
|
16
|
+
document.removeEventListener("click", handleClickOutsideMenu, {
|
|
17
|
+
capture: true,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
if (isOpen) {
|
|
22
|
+
document.addEventListener("click", handleClickOutsideMenu, {
|
|
23
|
+
capture: true,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
document.removeEventListener("click", handleClickOutsideMenu, {
|
|
28
|
+
capture: true,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}, [isOpen]);
|
|
32
|
+
return (_jsxs(Container, { className: className, ref: ref, children: [_jsxs(DropdownButton, { id: id, onClick: () => setIsOpen(!isOpen), "aria-haspopup": "menu", "aria-controls": "dropdown-menu", isOpen: isOpen, children: [_jsxs(TextContainer, { children: [prefix && _jsx(Prefix, { children: `${prefix}:` }), _jsx(Label, { children: selectedItem?.label })] }), _jsx(StyledToggle, { toggled: isOpen })] }), _jsx(Content, { id: "dropdown-menu", "aria-expanded": isOpen, "aria-hidden": !isOpen, role: "menu", children: items.map((item, i) => (_jsx(DropdownListItem, { label: item.label, onClick: () => {
|
|
33
|
+
setIsOpen(false);
|
|
34
|
+
setItem(item);
|
|
35
|
+
onItemSelected(item);
|
|
36
|
+
} }, i))) })] }));
|
|
37
|
+
};
|
|
38
|
+
const Container = styled.div `
|
|
39
|
+
width: 100%;
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
position: relative;
|
|
43
|
+
`;
|
|
44
|
+
const DropdownButton = styled.button `
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
height: ${rem(48)};
|
|
48
|
+
font-size: ${rem(16)};
|
|
49
|
+
background-color: ${({ theme }) => theme.white};
|
|
50
|
+
border: ${rem(1)} solid ${({ theme }) => theme.grayTransparent};
|
|
51
|
+
border-radius: ${({ isOpen }) => isOpen ? `${rem(5)} ${rem(5)} 0 0` : rem(5)};
|
|
52
|
+
border-bottom: ${({ isOpen, theme }) => isOpen ? "none" : `$(${rem(1)}) solid ${theme.grayTransparent}`};
|
|
53
|
+
padding: 0 ${rem(14)};
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
|
|
56
|
+
${({ isOpen, theme }) => {
|
|
57
|
+
return css `
|
|
58
|
+
${media.M `
|
|
59
|
+
&:hover, :focus-visible {
|
|
60
|
+
border: ${rem(1)} solid ${theme.gray};
|
|
61
|
+
border-bottom: ${isOpen ? "none" : `${rem(1)} solid ${theme.gray}`};
|
|
62
|
+
}
|
|
63
|
+
`}
|
|
64
|
+
`;
|
|
65
|
+
}}
|
|
66
|
+
`;
|
|
67
|
+
const TextContainer = styled.div `
|
|
68
|
+
display: flex;
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
white-space: nowrap;
|
|
71
|
+
`;
|
|
72
|
+
const StyledToggle = styled(ToggableChevron).attrs({
|
|
73
|
+
disableCircle: true,
|
|
74
|
+
}) `
|
|
75
|
+
margin-left: auto;
|
|
76
|
+
padding-left: ${rem(8)};
|
|
77
|
+
`;
|
|
78
|
+
const Content = styled.ul `
|
|
79
|
+
position: absolute;
|
|
80
|
+
width: 100%;
|
|
81
|
+
max-height: ${rem(250)};
|
|
82
|
+
top: ${rem(48)};
|
|
83
|
+
list-style: none;
|
|
84
|
+
background-color: ${({ theme }) => theme.white};
|
|
85
|
+
border: ${rem(1)} solid ${({ theme }) => theme.grayTransparent};
|
|
86
|
+
border-radius: ${rem(5)};
|
|
87
|
+
padding: 0 ${rem(6)};
|
|
88
|
+
margin: 0;
|
|
89
|
+
visibility: hidden;
|
|
90
|
+
overflow-y: scroll;
|
|
91
|
+
|
|
92
|
+
&[aria-expanded="true"] {
|
|
93
|
+
visibility: visible;
|
|
94
|
+
border-radius: 0 0 ${rem(5)} ${rem(5)};
|
|
95
|
+
border-top: 0;
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
const Label = styled.p `
|
|
99
|
+
font-family: ${({ theme }) => theme.valueBold};
|
|
100
|
+
font-size: ${rem(16)};
|
|
101
|
+
margin: 0;
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
text-overflow: ellipsis;
|
|
104
|
+
`;
|
|
105
|
+
const Prefix = styled(Label) `
|
|
106
|
+
font-family: ${({ theme }) => theme.valueRegular};
|
|
107
|
+
margin-right: ${rem(6)};
|
|
108
|
+
overflow: unset;
|
|
109
|
+
`;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Dropdown } from "./dropdown";
|
|
3
|
+
declare const meta: Meta<typeof Dropdown>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Dropdown>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const WithPrefix: Story;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
3
|
+
import { Dropdown } from "./dropdown";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Inputs/Dropdown",
|
|
6
|
+
component: Dropdown,
|
|
7
|
+
decorators: [
|
|
8
|
+
(Story) => (_jsx(Decorator, { maxWidth: "250px", children: _jsx(Story, {}) })),
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {
|
|
13
|
+
args: {
|
|
14
|
+
items: [
|
|
15
|
+
{
|
|
16
|
+
label: "2025",
|
|
17
|
+
value: "2025",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
label: "2024",
|
|
21
|
+
value: "2024",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: "2023",
|
|
25
|
+
value: "2023",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: "2022",
|
|
29
|
+
value: "2022",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
label: "2021",
|
|
33
|
+
value: "2021",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: "2020",
|
|
37
|
+
value: "2020",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: "2019",
|
|
41
|
+
value: "2019",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: "2018",
|
|
45
|
+
value: "2018",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
label: "2017",
|
|
49
|
+
value: "2017",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
label: "2016",
|
|
53
|
+
value: "2016",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
label: "2015",
|
|
57
|
+
value: "2015",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
label: "2014",
|
|
61
|
+
value: "2014",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
label: "2013",
|
|
65
|
+
value: "2013",
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
export const WithPrefix = {
|
|
71
|
+
args: {
|
|
72
|
+
prefix: "Sort by",
|
|
73
|
+
items: [
|
|
74
|
+
{
|
|
75
|
+
label: "Latest first",
|
|
76
|
+
value: "newest",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
label: "Oldest first",
|
|
80
|
+
value: "oldest",
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FieldErrors } from "react-hook-form";
|
|
2
|
+
export type FormErrorProps = {
|
|
3
|
+
errors: FieldErrors;
|
|
4
|
+
name: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
alignLeft?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type StyledFormErrorProps = {
|
|
9
|
+
alignLeft?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const FormError: ({ errors, name, className, alignLeft, }: FormErrorProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
import { rem } from "../../../styles/units";
|
|
4
|
+
export const FormError = ({ errors, name, className, alignLeft, }) => {
|
|
5
|
+
const errorMessage = errors[name]?.message;
|
|
6
|
+
if (errorMessage && typeof errorMessage === "string")
|
|
7
|
+
return (_jsx(ErrorMessage, { "data-test": "form-error", className: className, alignLeft: alignLeft, children: errorMessage }));
|
|
8
|
+
return null;
|
|
9
|
+
};
|
|
10
|
+
const ErrorMessage = styled.span `
|
|
11
|
+
display: flex;
|
|
12
|
+
justify-content: ${({ alignLeft }) => alignLeft ? "flex-start" : "flex-end"};
|
|
13
|
+
font-family: ${({ theme }) => theme.valueBold};
|
|
14
|
+
color: ${({ theme }) => theme.red};
|
|
15
|
+
padding: ${rem(8)};
|
|
16
|
+
`;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FormError } from "./form-error";
|
|
3
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Inputs/FormError",
|
|
6
|
+
component: FormError,
|
|
7
|
+
decorators: [
|
|
8
|
+
(Story) => (_jsx(Decorator, { children: _jsx(Story, {}) })),
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {
|
|
13
|
+
args: {
|
|
14
|
+
name: "fieldValue",
|
|
15
|
+
errors: {
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
fieldValue: {
|
|
18
|
+
message: "validation-error-text",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
import { rem } from "../../../styles/units";
|
|
4
|
+
export const FormLabel = ({ htmlFor, className, children }) => (_jsx(Label, { className: className, htmlFor: htmlFor, children: children }));
|
|
5
|
+
const Label = styled.label `
|
|
6
|
+
display: block;
|
|
7
|
+
font-family: ${({ theme }) => theme.valueBold};
|
|
8
|
+
font-weight: 400;
|
|
9
|
+
font-size: ${rem(16)};
|
|
10
|
+
color: ${({ theme }) => theme.blackLight};
|
|
11
|
+
margin: ${rem(8)} 0;
|
|
12
|
+
`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FormLabel } from "./form-label";
|
|
3
|
+
import { Decorator } from "../../../components/decorator/decorator";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Inputs/FormLabel",
|
|
6
|
+
component: FormLabel,
|
|
7
|
+
decorators: [
|
|
8
|
+
(Story) => (_jsx(Decorator, { maxWidth: "250px", children: _jsx(Story, {}) })),
|
|
9
|
+
],
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Default = {
|
|
13
|
+
args: {
|
|
14
|
+
children: "label-text",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ReactNode, InputHTMLAttributes, HTMLInputTypeAttribute } from "react";
|
|
2
|
+
import { UseFormRegisterReturn, FieldErrors } from "react-hook-form";
|
|
3
|
+
export type TextFieldProps = {
|
|
4
|
+
dataTest?: string;
|
|
5
|
+
value?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
type?: HTMLInputTypeAttribute;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
icon?: ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
ariaLabelBtn?: string;
|
|
13
|
+
ariaDescribedBy?: string;
|
|
14
|
+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
15
|
+
onClick?: (e: React.MouseEvent<HTMLElement>) => void;
|
|
16
|
+
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
|
17
|
+
onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
|
18
|
+
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
19
|
+
register?: UseFormRegisterReturn;
|
|
20
|
+
errors?: FieldErrors;
|
|
21
|
+
inputMode?: InputHTMLAttributes<HTMLInputElement>["inputMode"];
|
|
22
|
+
pattern?: InputHTMLAttributes<HTMLInputElement>["pattern"];
|
|
23
|
+
variant?: "default" | "rounded";
|
|
24
|
+
startAdornment?: ReactNode;
|
|
25
|
+
endAdornment?: ReactNode;
|
|
26
|
+
};
|
|
27
|
+
export type StyledTextFieldProps = {
|
|
28
|
+
icon?: string;
|
|
29
|
+
variant?: "default" | "rounded";
|
|
30
|
+
startAdornment?: ReactNode;
|
|
31
|
+
};
|
|
32
|
+
export declare const TextField: import("react").ForwardRefExoticComponent<TextFieldProps & import("react").RefAttributes<HTMLInputElement>>;
|