@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.
Files changed (151) hide show
  1. package/.eslintrc.cjs +32 -0
  2. package/.github/workflows/deployment.yml +34 -0
  3. package/.storybook/main.ts +18 -0
  4. package/.storybook/preview-head.html +4 -0
  5. package/.storybook/preview.tsx +67 -0
  6. package/README.md +11 -0
  7. package/app/.babelrc +27 -0
  8. package/app/.eslintrc.json +6 -0
  9. package/app/.storybook/main.ts +17 -0
  10. package/app/.storybook/preview.tsx +26 -0
  11. package/app/README.md +38 -0
  12. package/app/next.config.js +6 -0
  13. package/app/package-lock.json +28711 -0
  14. package/app/package.json +44 -0
  15. package/app/public/favicon.ico +0 -0
  16. package/app/public/next.svg +1 -0
  17. package/app/public/vercel.svg +1 -0
  18. package/app/src/assets/RightArrow/right-arrow.tsx +17 -0
  19. package/app/src/assets/S3Logo/s3-logo.tsx +31 -0
  20. package/app/src/assets/amazon_s3.svg +9 -0
  21. package/app/src/assets/arrow.svg +3 -0
  22. package/app/src/globals.d.ts +4 -0
  23. package/app/src/pages/_app.tsx +8 -0
  24. package/app/src/pages/_document.tsx +17 -0
  25. package/app/src/pages/api/hello.ts +13 -0
  26. package/app/src/pages/index.tsx +141 -0
  27. package/app/src/pages/label.tsx +27 -0
  28. package/app/src/stories/assets/code-brackets.svg +1 -0
  29. package/app/src/stories/assets/colors.svg +1 -0
  30. package/app/src/stories/assets/comments.svg +1 -0
  31. package/app/src/stories/assets/direction.svg +1 -0
  32. package/app/src/stories/assets/flow.svg +1 -0
  33. package/app/src/stories/assets/plugin.svg +1 -0
  34. package/app/src/stories/assets/repo.svg +1 -0
  35. package/app/src/stories/assets/stackalt.svg +1 -0
  36. package/app/src/styles/Home.module.css +235 -0
  37. package/app/src/styles/globals.css +111 -0
  38. package/app/src/styles/types.ts +1031 -0
  39. package/app/src/styles/variables.classic.css +16 -0
  40. package/app/src/styles/variables.classic.json +31 -0
  41. package/app/src/styles/variables.css +763 -0
  42. package/app/src/styles/variables.dark.css +135 -0
  43. package/app/src/styles/variables.dark.json +339 -0
  44. package/app/src/styles/variables.json +1029 -0
  45. package/app/src/styles/variables.light.css +203 -0
  46. package/app/src/styles/variables.light.json +478 -0
  47. package/app/tokens/themes/$metadata.json +9 -0
  48. package/app/tokens/themes/$themes.json +1 -0
  49. package/app/tokens/themes/classic.json +58 -0
  50. package/app/tokens/themes/component.json +868 -0
  51. package/app/tokens/themes/dark.json +937 -0
  52. package/app/tokens/themes/light.json +1380 -0
  53. package/app/tokens/themes/primitives.json +859 -0
  54. package/app/tsconfig.json +23 -0
  55. package/build-tokens.js +131 -0
  56. package/index.html +17 -0
  57. package/jest.config.ts +11 -0
  58. package/package.json +77 -0
  59. package/public/vite.svg +1 -0
  60. package/src/App.css +1 -0
  61. package/src/App.module.css +235 -0
  62. package/src/App.tsx +154 -0
  63. package/src/assets/RightArrow/RightArrow.tsx +17 -0
  64. package/src/assets/S3Logo/S3Logo.tsx +31 -0
  65. package/src/assets/react.svg +1 -0
  66. package/src/components/Accordion/Accordion.stories.tsx +78 -0
  67. package/src/components/Accordion/Accordion.test.tsx +46 -0
  68. package/src/components/Accordion/Accordion.tsx +118 -0
  69. package/src/components/Badge/Badge.stories.ts +14 -0
  70. package/src/components/Badge/Badge.test.tsx +11 -0
  71. package/src/components/Badge/Badge.tsx +24 -0
  72. package/src/components/BigStat/BigStat.stories.ts +15 -0
  73. package/src/components/BigStat/BigStat.tsx +37 -0
  74. package/src/components/Button/Button.stories.ts +82 -0
  75. package/src/components/Button/Button.test.tsx +32 -0
  76. package/src/components/Button/Button.tsx +97 -0
  77. package/src/components/ButtonGroup/ButtonGroup.stories.ts +14 -0
  78. package/src/components/ButtonGroup/ButtonGroup.tsx +78 -0
  79. package/src/components/Card/Card.stories.ts +19 -0
  80. package/src/components/Card/Card.tsx +107 -0
  81. package/src/components/FormField/FormField.stories.ts +14 -0
  82. package/src/components/FormField/FormField.tsx +22 -0
  83. package/src/components/Icon/Icon.stories.ts +46 -0
  84. package/src/components/Icon/Icon.tsx +90 -0
  85. package/src/components/Icon/types.ts +18 -0
  86. package/src/components/IconButton/IconButton.stories.ts +16 -0
  87. package/src/components/IconButton/IconButton.tsx +94 -0
  88. package/src/components/SidebarNavigationItem/SidebarNavigationItem.stories.tsx +28 -0
  89. package/src/components/SidebarNavigationItem/SidebarNavigationItem.tsx +112 -0
  90. package/src/components/Switch/Switch.stories.ts +14 -0
  91. package/src/components/Switch/Switch.tsx +106 -0
  92. package/src/components/Tabs/Tabs.stories.tsx +71 -0
  93. package/src/components/Tabs/Tabs.test.tsx +86 -0
  94. package/src/components/Tabs/Tabs.tsx +82 -0
  95. package/src/components/icons/ChatIcon.tsx +22 -0
  96. package/src/components/icons/ChevronDown.tsx +6 -0
  97. package/src/components/icons/ChevronRight.tsx +20 -0
  98. package/src/components/icons/DatabaseIcon.tsx +33 -0
  99. package/src/components/icons/FilterIcon.tsx +24 -0
  100. package/src/components/icons/Flags/EuropeanUnion.tsx +174 -0
  101. package/src/components/icons/Flags/Germany.tsx +25 -0
  102. package/src/components/icons/Flags/India.tsx +48 -0
  103. package/src/components/icons/Flags/Ireland.tsx +32 -0
  104. package/src/components/icons/Flags/Netherlands.tsx +29 -0
  105. package/src/components/icons/Flags/Singapore.tsx +43 -0
  106. package/src/components/icons/Flags/UnitedKingdom.tsx +32 -0
  107. package/src/components/icons/Flags/UnitedStates.tsx +26 -0
  108. package/src/components/icons/Flags/index.tsx +46 -0
  109. package/src/components/icons/HistoryIcon.tsx +28 -0
  110. package/src/components/icons/Icons.mdx +36 -0
  111. package/src/components/icons/InsertRowIcon.tsx +36 -0
  112. package/src/components/icons/SortAltIcon.tsx +24 -0
  113. package/src/components/icons/UserIcon.tsx +17 -0
  114. package/src/components/icons/UsersIcon.tsx +43 -0
  115. package/src/components/index.ts +14 -0
  116. package/src/components/types.ts +1 -0
  117. package/src/index.css +9 -0
  118. package/src/index.ts +2 -0
  119. package/src/main.tsx +11 -0
  120. package/src/stories/assets/code-brackets.svg +1 -0
  121. package/src/stories/assets/colors.svg +1 -0
  122. package/src/stories/assets/comments.svg +1 -0
  123. package/src/stories/assets/direction.svg +1 -0
  124. package/src/stories/assets/flow.svg +1 -0
  125. package/src/stories/assets/plugin.svg +1 -0
  126. package/src/stories/assets/repo.svg +1 -0
  127. package/src/stories/assets/stackalt.svg +1 -0
  128. package/src/styles/Home.module.css +235 -0
  129. package/src/styles/globals.css +111 -0
  130. package/src/styles/types.ts +1669 -0
  131. package/src/styles/variables.classic.css +16 -0
  132. package/src/styles/variables.classic.json +31 -0
  133. package/src/styles/variables.css +763 -0
  134. package/src/styles/variables.dark.css +135 -0
  135. package/src/styles/variables.dark.json +576 -0
  136. package/src/styles/variables.json +1667 -0
  137. package/src/styles/variables.light.css +203 -0
  138. package/src/styles/variables.light.json +789 -0
  139. package/src/theme/index.ts +22 -0
  140. package/src/theme/theme.tsx +28 -0
  141. package/src/vite-env.d.ts +1 -0
  142. package/tokens/themes/$metadata.json +9 -0
  143. package/tokens/themes/$themes.json +1 -0
  144. package/tokens/themes/classic.json +58 -0
  145. package/tokens/themes/component.json +1567 -0
  146. package/tokens/themes/dark.json +1450 -0
  147. package/tokens/themes/light.json +2059 -0
  148. package/tokens/themes/primitives.json +863 -0
  149. package/tsconfig.json +27 -0
  150. package/tsconfig.node.json +10 -0
  151. 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,14 @@
1
+ import { Switch } from "./Switch";
2
+
3
+ export default {
4
+ component: Switch,
5
+ title: "Switch",
6
+ tags: ["switch"],
7
+ };
8
+
9
+ export const Default = {
10
+ args: {
11
+ checked: true,
12
+ disabled: false,
13
+ },
14
+ };
@@ -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
+ });