@clickhouse/click-ui 0.0.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/.eslintrc.cjs +32 -0
- package/.github/workflows/deployment.yml +34 -0
- package/.storybook/main.ts +18 -0
- package/.storybook/preview-head.html +4 -0
- package/.storybook/preview.tsx +67 -0
- package/README.md +11 -0
- package/app/.babelrc +27 -0
- package/app/.eslintrc.json +6 -0
- package/app/.storybook/main.ts +17 -0
- package/app/.storybook/preview.tsx +26 -0
- package/app/README.md +38 -0
- package/app/next.config.js +6 -0
- package/app/package-lock.json +28711 -0
- package/app/package.json +44 -0
- package/app/public/favicon.ico +0 -0
- package/app/public/next.svg +1 -0
- package/app/public/vercel.svg +1 -0
- package/app/src/assets/RightArrow/right-arrow.tsx +17 -0
- package/app/src/assets/S3Logo/s3-logo.tsx +31 -0
- package/app/src/assets/amazon_s3.svg +9 -0
- package/app/src/assets/arrow.svg +3 -0
- package/app/src/globals.d.ts +4 -0
- package/app/src/pages/_app.tsx +8 -0
- package/app/src/pages/_document.tsx +17 -0
- package/app/src/pages/api/hello.ts +13 -0
- package/app/src/pages/index.tsx +141 -0
- package/app/src/pages/label.tsx +27 -0
- package/app/src/stories/assets/code-brackets.svg +1 -0
- package/app/src/stories/assets/colors.svg +1 -0
- package/app/src/stories/assets/comments.svg +1 -0
- package/app/src/stories/assets/direction.svg +1 -0
- package/app/src/stories/assets/flow.svg +1 -0
- package/app/src/stories/assets/plugin.svg +1 -0
- package/app/src/stories/assets/repo.svg +1 -0
- package/app/src/stories/assets/stackalt.svg +1 -0
- package/app/src/styles/Home.module.css +235 -0
- package/app/src/styles/globals.css +111 -0
- package/app/src/styles/types.ts +1031 -0
- package/app/src/styles/variables.classic.css +16 -0
- package/app/src/styles/variables.classic.json +31 -0
- package/app/src/styles/variables.css +763 -0
- package/app/src/styles/variables.dark.css +135 -0
- package/app/src/styles/variables.dark.json +339 -0
- package/app/src/styles/variables.json +1029 -0
- package/app/src/styles/variables.light.css +203 -0
- package/app/src/styles/variables.light.json +478 -0
- package/app/tokens/themes/$metadata.json +9 -0
- package/app/tokens/themes/$themes.json +1 -0
- package/app/tokens/themes/classic.json +58 -0
- package/app/tokens/themes/component.json +868 -0
- package/app/tokens/themes/dark.json +937 -0
- package/app/tokens/themes/light.json +1380 -0
- package/app/tokens/themes/primitives.json +859 -0
- package/app/tsconfig.json +23 -0
- package/build-tokens.js +131 -0
- package/index.html +17 -0
- package/jest.config.ts +11 -0
- package/package.json +77 -0
- package/public/vite.svg +1 -0
- package/src/App.css +1 -0
- package/src/App.module.css +235 -0
- package/src/App.tsx +154 -0
- package/src/assets/RightArrow/RightArrow.tsx +17 -0
- package/src/assets/S3Logo/S3Logo.tsx +31 -0
- package/src/assets/react.svg +1 -0
- package/src/components/Accordion/Accordion.stories.tsx +78 -0
- package/src/components/Accordion/Accordion.test.tsx +46 -0
- package/src/components/Accordion/Accordion.tsx +118 -0
- package/src/components/Badge/Badge.stories.ts +14 -0
- package/src/components/Badge/Badge.test.tsx +11 -0
- package/src/components/Badge/Badge.tsx +24 -0
- package/src/components/BigStat/BigStat.stories.ts +15 -0
- package/src/components/BigStat/BigStat.tsx +37 -0
- package/src/components/Button/Button.stories.ts +82 -0
- package/src/components/Button/Button.test.tsx +32 -0
- package/src/components/Button/Button.tsx +97 -0
- package/src/components/ButtonGroup/ButtonGroup.stories.ts +14 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +78 -0
- package/src/components/Card/Card.stories.ts +19 -0
- package/src/components/Card/Card.tsx +107 -0
- package/src/components/FormField/FormField.stories.ts +14 -0
- package/src/components/FormField/FormField.tsx +22 -0
- package/src/components/Icon/Icon.stories.ts +46 -0
- package/src/components/Icon/Icon.tsx +90 -0
- package/src/components/Icon/types.ts +18 -0
- package/src/components/IconButton/IconButton.stories.ts +16 -0
- package/src/components/IconButton/IconButton.tsx +94 -0
- package/src/components/SidebarNavigationItem/SidebarNavigationItem.stories.tsx +28 -0
- package/src/components/SidebarNavigationItem/SidebarNavigationItem.tsx +112 -0
- package/src/components/Switch/Switch.stories.ts +14 -0
- package/src/components/Switch/Switch.tsx +106 -0
- package/src/components/Tabs/Tabs.stories.tsx +71 -0
- package/src/components/Tabs/Tabs.test.tsx +86 -0
- package/src/components/Tabs/Tabs.tsx +82 -0
- package/src/components/icons/ChatIcon.tsx +22 -0
- package/src/components/icons/ChevronDown.tsx +6 -0
- package/src/components/icons/ChevronRight.tsx +20 -0
- package/src/components/icons/DatabaseIcon.tsx +33 -0
- package/src/components/icons/FilterIcon.tsx +24 -0
- package/src/components/icons/Flags/EuropeanUnion.tsx +174 -0
- package/src/components/icons/Flags/Germany.tsx +25 -0
- package/src/components/icons/Flags/India.tsx +48 -0
- package/src/components/icons/Flags/Ireland.tsx +32 -0
- package/src/components/icons/Flags/Netherlands.tsx +29 -0
- package/src/components/icons/Flags/Singapore.tsx +43 -0
- package/src/components/icons/Flags/UnitedKingdom.tsx +32 -0
- package/src/components/icons/Flags/UnitedStates.tsx +26 -0
- package/src/components/icons/Flags/index.tsx +46 -0
- package/src/components/icons/HistoryIcon.tsx +28 -0
- package/src/components/icons/Icons.mdx +36 -0
- package/src/components/icons/InsertRowIcon.tsx +36 -0
- package/src/components/icons/SortAltIcon.tsx +24 -0
- package/src/components/icons/UserIcon.tsx +17 -0
- package/src/components/icons/UsersIcon.tsx +43 -0
- package/src/components/index.ts +14 -0
- package/src/components/types.ts +1 -0
- package/src/index.css +9 -0
- package/src/index.ts +2 -0
- package/src/main.tsx +11 -0
- package/src/stories/assets/code-brackets.svg +1 -0
- package/src/stories/assets/colors.svg +1 -0
- package/src/stories/assets/comments.svg +1 -0
- package/src/stories/assets/direction.svg +1 -0
- package/src/stories/assets/flow.svg +1 -0
- package/src/stories/assets/plugin.svg +1 -0
- package/src/stories/assets/repo.svg +1 -0
- package/src/stories/assets/stackalt.svg +1 -0
- package/src/styles/Home.module.css +235 -0
- package/src/styles/globals.css +111 -0
- package/src/styles/types.ts +1669 -0
- package/src/styles/variables.classic.css +16 -0
- package/src/styles/variables.classic.json +31 -0
- package/src/styles/variables.css +763 -0
- package/src/styles/variables.dark.css +135 -0
- package/src/styles/variables.dark.json +576 -0
- package/src/styles/variables.json +1667 -0
- package/src/styles/variables.light.css +203 -0
- package/src/styles/variables.light.json +789 -0
- package/src/theme/index.ts +22 -0
- package/src/theme/theme.tsx +28 -0
- package/src/vite-env.d.ts +1 -0
- package/tokens/themes/$metadata.json +9 -0
- package/tokens/themes/$themes.json +1 -0
- package/tokens/themes/classic.json +58 -0
- package/tokens/themes/component.json +1567 -0
- package/tokens/themes/dark.json +1450 -0
- package/tokens/themes/light.json +2059 -0
- package/tokens/themes/primitives.json +863 -0
- package/tsconfig.json +27 -0
- package/tsconfig.node.json +10 -0
- package/vite.config.ts +38 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Badge } from "@/components/Badge/Badge";
|
|
3
|
+
import { S3Logo } from "@/assets/S3Logo/S3Logo";
|
|
4
|
+
import { RightArrow } from "@/assets/RightArrow/RightArrow";
|
|
5
|
+
|
|
6
|
+
export type CardState = "active" | "disabled";
|
|
7
|
+
export interface CardProps {
|
|
8
|
+
title: string;
|
|
9
|
+
badgeText: string;
|
|
10
|
+
description: string;
|
|
11
|
+
infoUrl: string;
|
|
12
|
+
infoText: string;
|
|
13
|
+
state?: CardState;
|
|
14
|
+
}
|
|
15
|
+
export const Card = ({
|
|
16
|
+
title,
|
|
17
|
+
badgeText,
|
|
18
|
+
description,
|
|
19
|
+
infoUrl,
|
|
20
|
+
infoText,
|
|
21
|
+
state = "active",
|
|
22
|
+
}: CardProps) => (
|
|
23
|
+
<Wrapper state={state}>
|
|
24
|
+
<Header>
|
|
25
|
+
<HeaderLeft>
|
|
26
|
+
<S3Logo />
|
|
27
|
+
<Title>{title}</Title>
|
|
28
|
+
</HeaderLeft>
|
|
29
|
+
<Badge
|
|
30
|
+
text={badgeText}
|
|
31
|
+
state={state === "disabled" ? "disabled" : "default"}
|
|
32
|
+
></Badge>
|
|
33
|
+
</Header>
|
|
34
|
+
|
|
35
|
+
<Content>
|
|
36
|
+
<Description>{description}</Description>
|
|
37
|
+
</Content>
|
|
38
|
+
|
|
39
|
+
<InfoLink>
|
|
40
|
+
<LinkButton href={infoUrl}>{infoText}</LinkButton>
|
|
41
|
+
<RightArrow />
|
|
42
|
+
</InfoLink>
|
|
43
|
+
</Wrapper>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
interface WrapperProps {
|
|
47
|
+
state: CardState;
|
|
48
|
+
}
|
|
49
|
+
const Wrapper = styled.div<WrapperProps>`
|
|
50
|
+
background-color: ${({ state }) =>
|
|
51
|
+
state === "active"
|
|
52
|
+
? "var(--click-card-color-background-active)"
|
|
53
|
+
: "var(--click-card-color-background-disabled)"};
|
|
54
|
+
border-radius: 4px;
|
|
55
|
+
border: 1px solid #e6e7e9;
|
|
56
|
+
max-width: 420px;
|
|
57
|
+
min-width: 300px;
|
|
58
|
+
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
padding: 16px;
|
|
62
|
+
gap: 16px;
|
|
63
|
+
`;
|
|
64
|
+
|
|
65
|
+
const Header = styled.div`
|
|
66
|
+
margin-top: 8px;
|
|
67
|
+
width: 100%;
|
|
68
|
+
|
|
69
|
+
display: flex;
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
align-items: center;
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
const HeaderLeft = styled.div`
|
|
75
|
+
display: flex;
|
|
76
|
+
align-items: center;
|
|
77
|
+
gap: 16px;
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
const Title = styled.h3`
|
|
81
|
+
font-size: 16px;
|
|
82
|
+
line-height: 24px;
|
|
83
|
+
font-weight: 600;
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
const Content = styled.div`
|
|
87
|
+
/* width: 330px; */
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
const Description = styled.p`
|
|
91
|
+
font-weight: 400;
|
|
92
|
+
font-size: 14px;
|
|
93
|
+
line-height: 150%;
|
|
94
|
+
color: #696e79;
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
const InfoLink = styled.div`
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
`;
|
|
101
|
+
const LinkButton = styled.a`
|
|
102
|
+
width: max-content;
|
|
103
|
+
text-decoration: none;
|
|
104
|
+
color: #161517;
|
|
105
|
+
font-size: 14px;
|
|
106
|
+
font-weight: 600;
|
|
107
|
+
`;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TextFieldLabel } from "./FormField";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
component: TextFieldLabel,
|
|
5
|
+
title: "TextFieldLabel",
|
|
6
|
+
tags: ["form-field", "text-field-label"],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Default = {
|
|
10
|
+
args: {
|
|
11
|
+
text: "text field label",
|
|
12
|
+
state: "active",
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import styled from "styled-components"
|
|
2
|
+
import { States } from "../types"
|
|
3
|
+
|
|
4
|
+
export type LabelProps = {
|
|
5
|
+
state: States
|
|
6
|
+
text: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Label = styled.label<Pick<LabelProps, "state">>`
|
|
10
|
+
font: ${({state}) => (
|
|
11
|
+
`var(--click-field-typography-label-${state})`
|
|
12
|
+
)};
|
|
13
|
+
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
color: var(--click-field-color-label-default);
|
|
17
|
+
`
|
|
18
|
+
|
|
19
|
+
export function TextFieldLabel({ state, text }: LabelProps) {
|
|
20
|
+
return <Label state={state}>{text}</Label>
|
|
21
|
+
}
|
|
22
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Icon } from "./Icon";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
component: Icon,
|
|
5
|
+
title: "Icon",
|
|
6
|
+
tags: ["icon"],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Default = {
|
|
10
|
+
args: {
|
|
11
|
+
name: "users",
|
|
12
|
+
width: "1rem",
|
|
13
|
+
height: "16px",
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const Color = {
|
|
18
|
+
args: {
|
|
19
|
+
name: "users",
|
|
20
|
+
color: "darkturquoise",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const Small = {
|
|
25
|
+
args: {
|
|
26
|
+
name: "users",
|
|
27
|
+
color: "darkturquoise",
|
|
28
|
+
size: "small",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const Medium = {
|
|
33
|
+
args: {
|
|
34
|
+
name: "users",
|
|
35
|
+
color: "darkturquoise",
|
|
36
|
+
size: "medium",
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const Large = {
|
|
41
|
+
args: {
|
|
42
|
+
name: "users",
|
|
43
|
+
color: "darkturquoise",
|
|
44
|
+
size: "large",
|
|
45
|
+
},
|
|
46
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ElementType, ReactElement } from "react";
|
|
2
|
+
import { UsersIcon } from "../icons/UsersIcon";
|
|
3
|
+
import styled from "styled-components";
|
|
4
|
+
import { UserIcon } from "../icons/UserIcon";
|
|
5
|
+
import ChatIcon from "../icons/ChatIcon";
|
|
6
|
+
import DatabaseIcon from "../icons/DatabaseIcon";
|
|
7
|
+
import FilterIcon from "../icons/FilterIcon";
|
|
8
|
+
import HistoryIcon from "../icons/HistoryIcon";
|
|
9
|
+
import InsertRowIcon from "../icons/InsertRowIcon";
|
|
10
|
+
import SortAltIcon from "../icons/SortAltIcon";
|
|
11
|
+
import { IconProps } from "./types";
|
|
12
|
+
import { ChevronRight } from "../icons/ChevronRight";
|
|
13
|
+
import { ChevronDown } from "../icons/ChevronDown";
|
|
14
|
+
|
|
15
|
+
const ICONS_MAP = {
|
|
16
|
+
chat: ChatIcon,
|
|
17
|
+
"chevron-right": ChevronRight,
|
|
18
|
+
"chevron-down": ChevronDown,
|
|
19
|
+
database: DatabaseIcon,
|
|
20
|
+
filter: FilterIcon,
|
|
21
|
+
history: HistoryIcon,
|
|
22
|
+
insertRow: InsertRowIcon,
|
|
23
|
+
sort: SortAltIcon,
|
|
24
|
+
user: UserIcon,
|
|
25
|
+
users: UsersIcon,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const SVGIcon = ({ name, ...delegated }: IconProps) => {
|
|
29
|
+
const Component = ICONS_MAP[name];
|
|
30
|
+
return <Component {...delegated} />;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const withStylesWrapper =
|
|
34
|
+
(IconComponent: ElementType) =>
|
|
35
|
+
({
|
|
36
|
+
color,
|
|
37
|
+
width,
|
|
38
|
+
height,
|
|
39
|
+
className,
|
|
40
|
+
size,
|
|
41
|
+
...props
|
|
42
|
+
}: IconProps): ReactElement =>
|
|
43
|
+
(
|
|
44
|
+
<SvgWrapper
|
|
45
|
+
color={color}
|
|
46
|
+
width={width}
|
|
47
|
+
height={height}
|
|
48
|
+
size={size}
|
|
49
|
+
className={className}
|
|
50
|
+
>
|
|
51
|
+
<IconComponent {...props} />
|
|
52
|
+
</SvgWrapper>
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const SvgWrapper = styled.div<Partial<IconProps>>`
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
|
|
59
|
+
& path[stroke] {
|
|
60
|
+
stroke: ${props => props.color || "currentColor"};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
& path[fill] {
|
|
64
|
+
fill: ${props => props.color || "currentColor"};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
& svg {
|
|
68
|
+
width: ${props =>
|
|
69
|
+
props.width ||
|
|
70
|
+
props.theme.click.image[props.size || "medium"].size.width ||
|
|
71
|
+
"24px"};
|
|
72
|
+
height: ${props =>
|
|
73
|
+
props.height ||
|
|
74
|
+
props.theme.click.image[props.size || "medium"].size.height ||
|
|
75
|
+
"24px"};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
& svg[stroke] {
|
|
79
|
+
stroke: ${props => props.color || "currentColor"};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
& svg[fill]:not([fill="none"]) {
|
|
83
|
+
fill: ${props => props.color || "currentColor"};
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
const Icon = withStylesWrapper(SVGIcon);
|
|
88
|
+
const IconToExport = styled(Icon)``;
|
|
89
|
+
|
|
90
|
+
export { IconToExport as Icon };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SVGAttributes } from "react";
|
|
2
|
+
|
|
3
|
+
export type IconSize = "small" | "medium" | "large";
|
|
4
|
+
export type IconName =
|
|
5
|
+
| "chat"
|
|
6
|
+
| "chevron-down"
|
|
7
|
+
| "chevron-right"
|
|
8
|
+
| "database"
|
|
9
|
+
| "filter"
|
|
10
|
+
| "history"
|
|
11
|
+
| "user"
|
|
12
|
+
| "users";
|
|
13
|
+
|
|
14
|
+
export interface IconProps extends SVGAttributes<HTMLOrSVGElement> {
|
|
15
|
+
name: IconName;
|
|
16
|
+
color?: string;
|
|
17
|
+
size?: IconSize;
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IconButton } from "./IconButton";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
component: IconButton,
|
|
5
|
+
title: "IconButton",
|
|
6
|
+
tags: ["icon-button"],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Default = {
|
|
10
|
+
args: {
|
|
11
|
+
size: "default",
|
|
12
|
+
state: "active",
|
|
13
|
+
disabled: "false",
|
|
14
|
+
display: "fileld",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { HTMLAttributes, forwardRef } from "react";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
|
|
4
|
+
interface IconButtonProps extends HTMLAttributes<HTMLButtonElement> {
|
|
5
|
+
state?: "default" | "active";
|
|
6
|
+
size?: "small" | "default";
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
display?: "empty" | "filled";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
|
|
12
|
+
({ children, display = "filled", ...props }, ref) => {
|
|
13
|
+
return (
|
|
14
|
+
<Button {...props} display={display} ref={ref}>
|
|
15
|
+
{children}
|
|
16
|
+
</Button>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
IconButton.displayName = "IconButton";
|
|
22
|
+
|
|
23
|
+
const Button = styled.button<IconButtonProps>`
|
|
24
|
+
border-radius: var(--click-button-radii-all);
|
|
25
|
+
border-color: transparent;
|
|
26
|
+
|
|
27
|
+
${({ state, disabled, display }: IconButtonProps) => {
|
|
28
|
+
if (disabled) {
|
|
29
|
+
return `
|
|
30
|
+
background-color: var(--click-button-basic-color-disabled-background-default);
|
|
31
|
+
color: var(--click-button-basic-color-disabled-text-default);
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
if (state === "active") {
|
|
35
|
+
return `
|
|
36
|
+
background-color: ${
|
|
37
|
+
display === "filled"
|
|
38
|
+
? "var(--click-button-basic-color-primary-background-active)"
|
|
39
|
+
: "var(--click-button-basic-color-secondary-background-active)"
|
|
40
|
+
};
|
|
41
|
+
color: ${
|
|
42
|
+
display === "filled"
|
|
43
|
+
? "var(--click-button-basic-color-primary-text-default)"
|
|
44
|
+
: "var(--click-button-basic-color-secondary-text-default)"
|
|
45
|
+
};
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return `
|
|
50
|
+
background-color: ${
|
|
51
|
+
display === "filled"
|
|
52
|
+
? "var(--click-button-basic-color-primary-background-default)"
|
|
53
|
+
: "transparent"
|
|
54
|
+
};
|
|
55
|
+
color: ${
|
|
56
|
+
display === "filled"
|
|
57
|
+
? "var(--click-button-basic-color-primary-text-default)"
|
|
58
|
+
: "var(--click-button-basic-color-secondary-text-default)"
|
|
59
|
+
};
|
|
60
|
+
`;
|
|
61
|
+
}};
|
|
62
|
+
${({ size }: IconButtonProps) => {
|
|
63
|
+
if (size === "small") {
|
|
64
|
+
return `
|
|
65
|
+
padding: var(--click-button-icon-button-space-1);
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return `
|
|
70
|
+
padding: var(--click-button-icon-button-space-2);
|
|
71
|
+
`;
|
|
72
|
+
}};
|
|
73
|
+
&:hover {
|
|
74
|
+
${({ disabled, state, display }: IconButtonProps) => {
|
|
75
|
+
if (disabled) {
|
|
76
|
+
return `
|
|
77
|
+
cursor-pointer: not-allowed;
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (state !== "active") {
|
|
82
|
+
return `
|
|
83
|
+
background-color: ${
|
|
84
|
+
display === "filled"
|
|
85
|
+
? "var(--click-button-basic-color-primary-background-hover)"
|
|
86
|
+
: "var(--click-button-basic-color-secondary-background-hover)"
|
|
87
|
+
};
|
|
88
|
+
`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return "";
|
|
92
|
+
}}
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { SidebarNavigationItem } from "@/components";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
component: SidebarNavigationItem,
|
|
5
|
+
title: "SidebarNavigationItem",
|
|
6
|
+
tags: ["sidebar", "navigation-item"],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Default = {
|
|
10
|
+
args: {
|
|
11
|
+
icon: "user",
|
|
12
|
+
children: <a href="/profile">Profile</a>,
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const Collapsible = {
|
|
17
|
+
args: {
|
|
18
|
+
icon: "user",
|
|
19
|
+
collapsible: true,
|
|
20
|
+
label: "Profile",
|
|
21
|
+
children: (
|
|
22
|
+
<>
|
|
23
|
+
<h2>Content</h2>
|
|
24
|
+
<p>SomeText</p>
|
|
25
|
+
</>
|
|
26
|
+
),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Icon } from "@/components";
|
|
2
|
+
import { SidebarAccordion } from "@/components/Accordion/Accordion";
|
|
3
|
+
import { IconName } from "@/components/Icon/types";
|
|
4
|
+
|
|
5
|
+
import styled from "styled-components";
|
|
6
|
+
|
|
7
|
+
interface DefaultSidebarNavigationItemProps
|
|
8
|
+
extends React.HTMLAttributes<HTMLButtonElement> {
|
|
9
|
+
collapsible?: false | undefined | null;
|
|
10
|
+
label?: undefined;
|
|
11
|
+
icon?: IconName;
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface CollapsibleSidebarNavigationItemProps
|
|
16
|
+
extends React.HTMLAttributes<HTMLButtonElement> {
|
|
17
|
+
collapsible: true;
|
|
18
|
+
label: string;
|
|
19
|
+
icon?: IconName;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type SidebarNavigationItemProps =
|
|
24
|
+
| DefaultSidebarNavigationItemProps
|
|
25
|
+
| CollapsibleSidebarNavigationItemProps;
|
|
26
|
+
|
|
27
|
+
const SidebarNavigationItem = ({
|
|
28
|
+
icon,
|
|
29
|
+
collapsible,
|
|
30
|
+
children,
|
|
31
|
+
label,
|
|
32
|
+
}: SidebarNavigationItemProps) => (
|
|
33
|
+
<>
|
|
34
|
+
{collapsible ? (
|
|
35
|
+
<CollapsibleNavigationItem
|
|
36
|
+
collapsible={collapsible}
|
|
37
|
+
label={label}
|
|
38
|
+
icon={icon}
|
|
39
|
+
children={children}
|
|
40
|
+
/>
|
|
41
|
+
) : (
|
|
42
|
+
<Wrapper>
|
|
43
|
+
<IconsWrapper>
|
|
44
|
+
{/* This icon is only used as a place holder */}
|
|
45
|
+
<Icon name="chevron-right" size="small" visibility="hidden" />
|
|
46
|
+
{icon && <Icon name={icon || "user"} size="small" />}
|
|
47
|
+
</IconsWrapper>
|
|
48
|
+
{children}
|
|
49
|
+
</Wrapper>
|
|
50
|
+
)}
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
const Wrapper = styled.div`
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
gap: ${props => props.theme.click.sidebar.navigation.item.default.space.gap};
|
|
57
|
+
|
|
58
|
+
padding: ${props =>
|
|
59
|
+
`${props.theme.click.sidebar.navigation.item.default.space.y} 0`};
|
|
60
|
+
|
|
61
|
+
border-radius: ${props =>
|
|
62
|
+
props.theme.click.sidebar.navigation.item.radii.all};
|
|
63
|
+
font: ${props =>
|
|
64
|
+
props.theme.click.sidebar.navigation.item.typography.default};
|
|
65
|
+
background-color: ${props =>
|
|
66
|
+
props.theme.click.sidebar.navigation.item.color.background.default};
|
|
67
|
+
|
|
68
|
+
&:hover {
|
|
69
|
+
font: ${props =>
|
|
70
|
+
props.theme.click.sidebar.navigation.item.typography.hover};
|
|
71
|
+
background-color: ${props =>
|
|
72
|
+
props.theme.click.sidebar.navigation.item.color.background.hover};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&:active {
|
|
76
|
+
font: ${props =>
|
|
77
|
+
props.theme.click.sidebar.navigation.item.typography.active};
|
|
78
|
+
background-color: ${props =>
|
|
79
|
+
props.theme.click.sidebar.navigation.item.color.background.active};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
a {
|
|
83
|
+
color: inherit;
|
|
84
|
+
text-decoration: none;
|
|
85
|
+
|
|
86
|
+
&:active {
|
|
87
|
+
color: inherit;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
`;
|
|
91
|
+
const IconsWrapper = styled.div`
|
|
92
|
+
display: flex;
|
|
93
|
+
`;
|
|
94
|
+
const CollapsibleNavigationItem = ({
|
|
95
|
+
collapsible,
|
|
96
|
+
icon,
|
|
97
|
+
label,
|
|
98
|
+
children,
|
|
99
|
+
}: CollapsibleSidebarNavigationItemProps) => (
|
|
100
|
+
<CollapsibleWrapper>
|
|
101
|
+
{label && collapsible && (
|
|
102
|
+
<SidebarAccordion title={label} icon={icon} iconSize="small">
|
|
103
|
+
{children}
|
|
104
|
+
</SidebarAccordion>
|
|
105
|
+
)}
|
|
106
|
+
</CollapsibleWrapper>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const CollapsibleWrapper = styled(Wrapper)`
|
|
110
|
+
padding-left: 0;
|
|
111
|
+
`;
|
|
112
|
+
export { SidebarNavigationItem };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as RadixSwitch from "@radix-ui/react-switch";
|
|
2
|
+
import styled, { DefaultTheme } from "styled-components";
|
|
3
|
+
|
|
4
|
+
interface SwitchProps extends RadixSwitch.SwitchProps {
|
|
5
|
+
checked: boolean;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface RootProps {
|
|
10
|
+
checked: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ThumbProps {
|
|
15
|
+
checked: boolean;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function Switch({ checked, disabled, ...props }: SwitchProps) {
|
|
20
|
+
return (
|
|
21
|
+
<SwitchRoot disabled={disabled} checked={checked} {...props}>
|
|
22
|
+
<SwitchThumb checked={checked} />
|
|
23
|
+
</SwitchRoot>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getRootVars(
|
|
28
|
+
theme: any,
|
|
29
|
+
disabled: boolean | undefined,
|
|
30
|
+
checked: boolean
|
|
31
|
+
) {
|
|
32
|
+
const baseVars = {};
|
|
33
|
+
|
|
34
|
+
if (disabled) {
|
|
35
|
+
return {
|
|
36
|
+
...baseVars,
|
|
37
|
+
backgroundColor: theme.click.switch.color.background.disabled,
|
|
38
|
+
border: `1px solid ${theme.click.switch.color.stroke.disabled}`,
|
|
39
|
+
};
|
|
40
|
+
} else if (checked) {
|
|
41
|
+
return {
|
|
42
|
+
...baseVars,
|
|
43
|
+
backgroundColor: theme.click.switch.color.background.active,
|
|
44
|
+
border: `1px solid ${theme.click.switch.color.stroke.active}`,
|
|
45
|
+
};
|
|
46
|
+
} else {
|
|
47
|
+
return {
|
|
48
|
+
...baseVars,
|
|
49
|
+
backgroundColor: theme.click.switch.color.background.default,
|
|
50
|
+
border: `1px solid ${theme.click.switch.color.stroke.default}`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getThumbVars(
|
|
56
|
+
theme: DefaultTheme,
|
|
57
|
+
disabled: boolean | undefined,
|
|
58
|
+
checked: boolean
|
|
59
|
+
) {
|
|
60
|
+
const baseVars = {};
|
|
61
|
+
|
|
62
|
+
if (disabled) {
|
|
63
|
+
return {
|
|
64
|
+
...baseVars,
|
|
65
|
+
backgroundColor: theme.click.switch.color.indicator.disabled,
|
|
66
|
+
};
|
|
67
|
+
} else if (checked) {
|
|
68
|
+
return {
|
|
69
|
+
...baseVars,
|
|
70
|
+
backgroundColor: theme.click.switch.color.indicator.active,
|
|
71
|
+
};
|
|
72
|
+
} else {
|
|
73
|
+
return {
|
|
74
|
+
...baseVars,
|
|
75
|
+
backgroundColor: theme.click.switch.color.indicator.default,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const SwitchRoot = styled(RadixSwitch.Root)<RootProps>(props => {
|
|
81
|
+
const vars = getRootVars(props.theme, props.disabled, props.checked);
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
width: props.theme.click.switch.size.width,
|
|
85
|
+
height: props.theme.click.switch.size.height,
|
|
86
|
+
backgroundColor: vars.backgroundColor,
|
|
87
|
+
border: vars.border,
|
|
88
|
+
borderRadius: props.theme.click.switch.radii.all,
|
|
89
|
+
position: "relative",
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const SwitchThumb = styled(RadixSwitch.Thumb)<ThumbProps>(props => {
|
|
94
|
+
const vars = getThumbVars(props.theme, props.disabled, props.checked);
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
display: "block",
|
|
98
|
+
width: "12px",
|
|
99
|
+
height: "12px",
|
|
100
|
+
backgroundColor: vars.backgroundColor,
|
|
101
|
+
borderRadius: props.theme.click.switch.radii.all,
|
|
102
|
+
transition: "transform 100ms",
|
|
103
|
+
transform: props.checked ? "translateX(15px)" : "translateX(2px)",
|
|
104
|
+
willChange: "transform",
|
|
105
|
+
};
|
|
106
|
+
});
|