cherry-styled-components 0.1.0-1

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 (183) hide show
  1. package/.DS_Store +0 -0
  2. package/.eslintrc.json +3 -0
  3. package/.gitignore +43 -0
  4. package/.next/app-build-manifest.json +15 -0
  5. package/.next/build-manifest.json +19 -0
  6. package/.next/cache/.tsbuildinfo +1 -0
  7. package/.next/cache/eslint/.cache_hc9deq +1 -0
  8. package/.next/cache/webpack/client-development/0.pack.gz +0 -0
  9. package/.next/cache/webpack/client-development/1.pack.gz +0 -0
  10. package/.next/cache/webpack/client-development/10.pack.gz +0 -0
  11. package/.next/cache/webpack/client-development/11.pack.gz +0 -0
  12. package/.next/cache/webpack/client-development/12.pack.gz +0 -0
  13. package/.next/cache/webpack/client-development/13.pack.gz +0 -0
  14. package/.next/cache/webpack/client-development/14.pack.gz +0 -0
  15. package/.next/cache/webpack/client-development/15.pack.gz +0 -0
  16. package/.next/cache/webpack/client-development/16.pack.gz +0 -0
  17. package/.next/cache/webpack/client-development/17.pack.gz +0 -0
  18. package/.next/cache/webpack/client-development/18.pack.gz +0 -0
  19. package/.next/cache/webpack/client-development/19.pack.gz +0 -0
  20. package/.next/cache/webpack/client-development/2.pack.gz +0 -0
  21. package/.next/cache/webpack/client-development/20.pack.gz +0 -0
  22. package/.next/cache/webpack/client-development/21.pack.gz +0 -0
  23. package/.next/cache/webpack/client-development/22.pack.gz +0 -0
  24. package/.next/cache/webpack/client-development/23.pack.gz +0 -0
  25. package/.next/cache/webpack/client-development/3.pack.gz +0 -0
  26. package/.next/cache/webpack/client-development/4.pack.gz +0 -0
  27. package/.next/cache/webpack/client-development/5.pack.gz +0 -0
  28. package/.next/cache/webpack/client-development/6.pack.gz +0 -0
  29. package/.next/cache/webpack/client-development/7.pack.gz +0 -0
  30. package/.next/cache/webpack/client-development/8.pack.gz +0 -0
  31. package/.next/cache/webpack/client-development/9.pack.gz +0 -0
  32. package/.next/cache/webpack/client-development/index.pack.gz +0 -0
  33. package/.next/cache/webpack/client-development/index.pack.gz.old +0 -0
  34. package/.next/cache/webpack/client-development-fallback/0.pack.gz +0 -0
  35. package/.next/cache/webpack/client-development-fallback/1.pack.gz +0 -0
  36. package/.next/cache/webpack/client-development-fallback/index.pack.gz +0 -0
  37. package/.next/cache/webpack/client-development-fallback/index.pack.gz.old +0 -0
  38. package/.next/cache/webpack/client-production/0.pack +0 -0
  39. package/.next/cache/webpack/client-production/1.pack +0 -0
  40. package/.next/cache/webpack/client-production/2.pack +0 -0
  41. package/.next/cache/webpack/client-production/index.pack +0 -0
  42. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  43. package/.next/cache/webpack/server-development/0.pack.gz +0 -0
  44. package/.next/cache/webpack/server-development/1.pack.gz +0 -0
  45. package/.next/cache/webpack/server-development/10.pack.gz +0 -0
  46. package/.next/cache/webpack/server-development/11.pack.gz +0 -0
  47. package/.next/cache/webpack/server-development/12.pack.gz +0 -0
  48. package/.next/cache/webpack/server-development/13.pack.gz +0 -0
  49. package/.next/cache/webpack/server-development/14.pack.gz +0 -0
  50. package/.next/cache/webpack/server-development/15.pack.gz +0 -0
  51. package/.next/cache/webpack/server-development/16.pack.gz +0 -0
  52. package/.next/cache/webpack/server-development/17.pack.gz +0 -0
  53. package/.next/cache/webpack/server-development/18.pack.gz +0 -0
  54. package/.next/cache/webpack/server-development/19.pack.gz +0 -0
  55. package/.next/cache/webpack/server-development/2.pack.gz +0 -0
  56. package/.next/cache/webpack/server-development/20.pack.gz +0 -0
  57. package/.next/cache/webpack/server-development/21.pack.gz +0 -0
  58. package/.next/cache/webpack/server-development/22.pack.gz +0 -0
  59. package/.next/cache/webpack/server-development/23.pack.gz +0 -0
  60. package/.next/cache/webpack/server-development/24.pack.gz +0 -0
  61. package/.next/cache/webpack/server-development/25.pack.gz +0 -0
  62. package/.next/cache/webpack/server-development/26.pack.gz +0 -0
  63. package/.next/cache/webpack/server-development/27.pack.gz +0 -0
  64. package/.next/cache/webpack/server-development/28.pack.gz +0 -0
  65. package/.next/cache/webpack/server-development/29.pack.gz +0 -0
  66. package/.next/cache/webpack/server-development/3.pack.gz +0 -0
  67. package/.next/cache/webpack/server-development/30.pack.gz +0 -0
  68. package/.next/cache/webpack/server-development/31.pack.gz +0 -0
  69. package/.next/cache/webpack/server-development/32.pack.gz +0 -0
  70. package/.next/cache/webpack/server-development/4.pack.gz +0 -0
  71. package/.next/cache/webpack/server-development/5.pack.gz +0 -0
  72. package/.next/cache/webpack/server-development/6.pack.gz +0 -0
  73. package/.next/cache/webpack/server-development/7.pack.gz +0 -0
  74. package/.next/cache/webpack/server-development/8.pack.gz +0 -0
  75. package/.next/cache/webpack/server-development/9.pack.gz +0 -0
  76. package/.next/cache/webpack/server-development/index.pack.gz +0 -0
  77. package/.next/cache/webpack/server-development/index.pack.gz.old +0 -0
  78. package/.next/cache/webpack/server-production/0.pack +0 -0
  79. package/.next/cache/webpack/server-production/1.pack +0 -0
  80. package/.next/cache/webpack/server-production/index.pack +0 -0
  81. package/.next/cache/webpack/server-production/index.pack.old +0 -0
  82. package/.next/package.json +1 -0
  83. package/.next/react-loadable-manifest.json +1 -0
  84. package/.next/server/app/page.js +1072 -0
  85. package/.next/server/app/page_client-reference-manifest.js +1 -0
  86. package/.next/server/app-paths-manifest.json +1 -0
  87. package/.next/server/middleware-build-manifest.js +1 -0
  88. package/.next/server/middleware-manifest.json +6 -0
  89. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  90. package/.next/server/next-font-manifest.js +1 -0
  91. package/.next/server/next-font-manifest.json +1 -0
  92. package/.next/server/pages-manifest.json +1 -0
  93. package/.next/server/server-reference-manifest.js +1 -0
  94. package/.next/server/server-reference-manifest.json +5 -0
  95. package/.next/server/vendor-chunks/@emotion.js +45 -0
  96. package/.next/server/vendor-chunks/@swc.js +75 -0
  97. package/.next/server/vendor-chunks/next.js +2197 -0
  98. package/.next/server/vendor-chunks/shallowequal.js +24 -0
  99. package/.next/server/vendor-chunks/styled-components.js +35 -0
  100. package/.next/server/vendor-chunks/stylis.js +85 -0
  101. package/.next/server/webpack-runtime.js +220 -0
  102. package/.next/static/chunks/app/layout.js +695 -0
  103. package/.next/static/chunks/app/page.js +28 -0
  104. package/.next/static/chunks/app-pages-internals.js +105 -0
  105. package/.next/static/chunks/main-app.js +1893 -0
  106. package/.next/static/chunks/polyfills.js +1 -0
  107. package/.next/static/chunks/webpack.js +1416 -0
  108. package/.next/static/css/app/layout.css +69 -0
  109. package/.next/static/development/_buildManifest.js +1 -0
  110. package/.next/static/development/_ssgManifest.js +1 -0
  111. package/.next/static/media/05a31a2ca4975f99-s.woff2 +0 -0
  112. package/.next/static/media/513657b02c5c193f-s.woff2 +0 -0
  113. package/.next/static/media/51ed15f9841b9f9d-s.woff2 +0 -0
  114. package/.next/static/media/c9a5bc6a7c948fb0-s.p.woff2 +0 -0
  115. package/.next/static/media/d6b16ce4a6175f26-s.woff2 +0 -0
  116. package/.next/static/media/ec159349637c90ad-s.woff2 +0 -0
  117. package/.next/static/media/fd4db3eb5472fc27-s.woff2 +0 -0
  118. package/.next/static/webpack/633457081244afec._.hot-update.json +1 -0
  119. package/.next/trace +19 -0
  120. package/.next/types/app/layout.ts +79 -0
  121. package/.next/types/app/page.ts +79 -0
  122. package/.next/types/package.json +1 -0
  123. package/.prettierrc +11 -0
  124. package/.vscode/settings.json +67 -0
  125. package/README.md +15 -0
  126. package/next-env.d.ts +5 -0
  127. package/next.config.mjs +8 -0
  128. package/package.json +51 -0
  129. package/src/app/components/box.tsx +16 -0
  130. package/src/app/components/button.tsx +177 -0
  131. package/src/app/components/col.tsx +39 -0
  132. package/src/app/components/container.tsx +55 -0
  133. package/src/app/components/flex.tsx +90 -0
  134. package/src/app/components/grid.tsx +60 -0
  135. package/src/app/components/index.ts +15 -0
  136. package/src/app/components/input.tsx +254 -0
  137. package/src/app/components/max-width.tsx +43 -0
  138. package/src/app/components/range.tsx +223 -0
  139. package/src/app/components/select.tsx +122 -0
  140. package/src/app/components/space.tsx +54 -0
  141. package/src/app/components/styled-components/index.ts +2 -0
  142. package/src/app/components/styled-components/registry.tsx +26 -0
  143. package/src/app/components/styled-components/theme-provider.tsx +21 -0
  144. package/src/app/components/textarea.tsx +98 -0
  145. package/src/app/components/toggle.tsx +148 -0
  146. package/src/app/components/utils/global.tsx +78 -0
  147. package/src/app/components/utils/icons.tsx +168 -0
  148. package/src/app/components/utils/index.ts +5 -0
  149. package/src/app/components/utils/mixins.tsx +107 -0
  150. package/src/app/components/utils/theme.ts +241 -0
  151. package/src/app/components/utils/typography.tsx +204 -0
  152. package/src/app/layout.tsx +19 -0
  153. package/src/app/page.tsx +14 -0
  154. package/tsconfig.json +29 -0
  155. package/tsconfig.tsbuildinfo +1 -0
  156. package/types/.next/types/app/layout.d.ts +9 -0
  157. package/types/.next/types/app/page.d.ts +9 -0
  158. package/types/src/app/components/box.d.ts +4 -0
  159. package/types/src/app/components/button.d.ts +17 -0
  160. package/types/src/app/components/col.d.ts +16 -0
  161. package/types/src/app/components/container.d.ts +19 -0
  162. package/types/src/app/components/flex.d.ts +27 -0
  163. package/types/src/app/components/grid.d.ts +24 -0
  164. package/types/src/app/components/index.d.ts +15 -0
  165. package/types/src/app/components/input.d.ts +15 -0
  166. package/types/src/app/components/max-width.d.ts +13 -0
  167. package/types/src/app/components/range.d.ts +13 -0
  168. package/types/src/app/components/select.d.ts +14 -0
  169. package/types/src/app/components/space.d.ts +14 -0
  170. package/types/src/app/components/styled-components/index.d.ts +2 -0
  171. package/types/src/app/components/styled-components/registry.d.ts +5 -0
  172. package/types/src/app/components/styled-components/theme-provider.d.ts +6 -0
  173. package/types/src/app/components/textarea.d.ts +13 -0
  174. package/types/src/app/components/toggle.d.ts +14 -0
  175. package/types/src/app/components/utils/global.d.ts +3 -0
  176. package/types/src/app/components/utils/icons.d.ts +9 -0
  177. package/types/src/app/components/utils/index.d.ts +5 -0
  178. package/types/src/app/components/utils/mixins.d.ts +11 -0
  179. package/types/src/app/components/utils/theme.d.ts +227 -0
  180. package/types/src/app/components/utils/typography.d.ts +20 -0
  181. package/types/src/app/layout.d.ts +2 -0
  182. package/types/src/app/page.d.ts +4 -0
  183. package/types/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,122 @@
1
+ "use client";
2
+ import React from "react";
3
+ import styled from "styled-components";
4
+ import {
5
+ Theme,
6
+ IconArrow,
7
+ formElementHeightStyles,
8
+ fullWidthStyles,
9
+ resetButton,
10
+ resetInput,
11
+ statusBorderStyles,
12
+ } from "./utils";
13
+ import { StyledInputWrapper, StyledLabel } from "./input";
14
+
15
+ interface SelectProps extends React.InputHTMLAttributes<HTMLSelectElement> {
16
+ children?: React.ReactNode;
17
+ $label?: string;
18
+ $size?: "default" | "big";
19
+ $error?: boolean;
20
+ $success?: boolean;
21
+ $fullWidth?: boolean;
22
+ theme?: Theme;
23
+ }
24
+
25
+ const StyledSelect = styled.select<SelectProps>`
26
+ ${resetButton};
27
+ ${resetInput};
28
+ font-family: inherit;
29
+ display: inline-block;
30
+ padding: 15px;
31
+ border-radius: ${({ theme }) => theme.spacing.radius.xs};
32
+ font-weight: 400;
33
+ white-space: nowrap;
34
+ hyphens: auto;
35
+ color: ${({ theme }) => theme.colors.dark};
36
+ background: ${({ theme }) => theme.colors.light};
37
+ border: solid 2px ${({ theme }) => theme.colors.grayLight};
38
+ box-shadow: 0 0 0 0px ${({ theme }) => theme.colors.primaryLight};
39
+ transition: all 0.3s ease;
40
+
41
+ &::placeholder {
42
+ color: ${({ theme }) => theme.colors.gray};
43
+ }
44
+
45
+ @media (hover: hover) {
46
+ &:hover:not([disabled]) {
47
+ border-color: ${({ theme }) => theme.colors.primary};
48
+ }
49
+ }
50
+
51
+ &:focus:not([disabled]) {
52
+ box-shadow: 0 0 0 4px ${({ theme }) => theme.colors.primaryLight};
53
+ border-color: ${({ theme }) => theme.colors.primary};
54
+ }
55
+
56
+ &:active:not([disabled]) {
57
+ box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.primaryLight};
58
+ }
59
+
60
+ ${({ $size }) => formElementHeightStyles($size)}
61
+
62
+ ${({ $size, theme }) =>
63
+ $size === "big"
64
+ ? `font-size: ${theme.fontSizes.inputBig.lg};
65
+ line-height: ${theme.lineHeights.inputBig.lg};
66
+ `
67
+ : `font-size: ${theme.fontSizes.input.lg};
68
+ line-height: ${theme.lineHeights.input.lg};`}
69
+
70
+ ${({ $error, $success, theme }) => {
71
+ return statusBorderStyles(
72
+ $error ? true : false,
73
+ $success ? true : false,
74
+ theme,
75
+ );
76
+ }}
77
+
78
+ ${({ disabled, theme }) =>
79
+ disabled &&
80
+ `cursor: not-allowed;
81
+ background: ${theme.colors.grayLight};
82
+ border-color: ${theme.colors.gray};
83
+ color: ${theme.colors.gray};
84
+ `}
85
+
86
+ ${({ $fullWidth }) => fullWidthStyles($fullWidth ? true : false)}
87
+ `;
88
+
89
+ export const StyledIconWrapper = styled.span<SelectProps>`
90
+ position: relative;
91
+ ${({ $fullWidth }) => fullWidthStyles($fullWidth ? true : false)}
92
+
93
+ & svg {
94
+ position: absolute;
95
+ top: 50%;
96
+ right: 15px;
97
+ transform: translateY(-50%) rotate(0);
98
+ transition: all 0.3s ease;
99
+ pointer-events: none;
100
+ }
101
+
102
+ & select:active:not([disabled]) ~ svg,
103
+ & select:focus:not([disabled]) ~ svg {
104
+ transform: translateY(-50%) rotate(180deg);
105
+ }
106
+ `;
107
+
108
+ function Select({ ...props }: SelectProps) {
109
+ return (
110
+ <StyledInputWrapper $fullWidth={props.$fullWidth}>
111
+ {props.$label && (
112
+ <StyledLabel htmlFor={props.id}>{props.$label}</StyledLabel>
113
+ )}
114
+ <StyledIconWrapper $fullWidth={props.$fullWidth}>
115
+ <StyledSelect {...props}>{props.children}</StyledSelect>
116
+ <IconArrow />
117
+ </StyledIconWrapper>
118
+ </StyledInputWrapper>
119
+ );
120
+ }
121
+
122
+ export { Select };
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import React from "react";
3
+ import styled from "styled-components";
4
+ import { Breakpoints, mq } from "./utils";
5
+
6
+ interface SpaceProps {
7
+ $size?: number | "none";
8
+ $xs?: number | "none";
9
+ $sm?: number | "none";
10
+ $md?: number | "none";
11
+ $lg?: number | "none";
12
+ $xl?: number | "none";
13
+ $xxl?: number | "none";
14
+ $xxxl?: number | "none";
15
+ $horizontal?: boolean;
16
+ }
17
+
18
+ const styles = ($size: number | "none", $horizontal: boolean) =>
19
+ $horizontal
20
+ ? `display: inline-block;
21
+ max-height: 0;
22
+ min-width: ${$size}px;
23
+ max-width: ${$size}px;`
24
+ : `display: block;
25
+ min-height: ${$size}px;
26
+ max-height: ${$size}px;`;
27
+
28
+ function responsiveStyles(props: any) {
29
+ return Object.keys(props)
30
+ .filter((key) => key.startsWith("$"))
31
+ .map((key) => {
32
+ const size = key.substring(1) as keyof Breakpoints<number>;
33
+ return (
34
+ props[key] &&
35
+ mq(size) +
36
+ `{ ${styles(props[key], props.$horizontal || false)} }`
37
+ );
38
+ })
39
+ .join("");
40
+ }
41
+
42
+ const StyledSpace = styled.span<SpaceProps>`
43
+ ${({ $horizontal, $size }) => `
44
+ ${$size && $size !== "none" && styles($size, $horizontal || false)};
45
+ ${$size === "none" && `display: none;`};
46
+ `}
47
+ ${(props) => responsiveStyles(props)}
48
+ `;
49
+
50
+ function Space({ ...props }: SpaceProps) {
51
+ return <StyledSpace {...props} />;
52
+ }
53
+
54
+ export { Space };
@@ -0,0 +1,2 @@
1
+ export * from "./registry";
2
+ export * from "./theme-provider";
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import React, { useState } from "react";
3
+ import { useServerInsertedHTML } from "next/navigation";
4
+ import { ServerStyleSheet, StyleSheetManager } from "styled-components";
5
+
6
+ function StyledComponentsRegistry({ children }: { children: React.ReactNode }) {
7
+ // Only create stylesheet once with lazy initial state
8
+ // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
9
+ const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
10
+
11
+ useServerInsertedHTML(() => {
12
+ const styles = styledComponentsStyleSheet.getStyleElement();
13
+ styledComponentsStyleSheet.instance.clearTag();
14
+ return <>{styles}</>;
15
+ });
16
+
17
+ if (typeof window !== "undefined") return <>{children}</>;
18
+
19
+ return (
20
+ <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
21
+ {children}
22
+ </StyleSheetManager>
23
+ );
24
+ }
25
+
26
+ export { StyledComponentsRegistry };
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import React from "react";
3
+ import { ThemeProvider as StyledThemeProvider } from "styled-components";
4
+ import { theme as defaultTheme, GlobalStyles } from "../utils";
5
+
6
+ function CherryThemeProvider({
7
+ children,
8
+ theme,
9
+ }: {
10
+ children: any;
11
+ theme?: any;
12
+ }) {
13
+ return (
14
+ <StyledThemeProvider theme={theme || defaultTheme}>
15
+ <GlobalStyles />
16
+ {children}
17
+ </StyledThemeProvider>
18
+ );
19
+ }
20
+
21
+ export { CherryThemeProvider };
@@ -0,0 +1,98 @@
1
+ "use client";
2
+ import React from "react";
3
+ import styled from "styled-components";
4
+ import {
5
+ Theme,
6
+ fullWidthStyles,
7
+ resetButton,
8
+ resetInput,
9
+ statusBorderStyles,
10
+ } from "./utils";
11
+ import { StyledInputWrapper, StyledLabel } from "./input";
12
+
13
+ interface TextareaProps
14
+ extends Omit<React.InputHTMLAttributes<HTMLTextAreaElement>, "size"> {
15
+ children?: React.ReactNode;
16
+ $label?: string;
17
+ $size?: "default" | "big";
18
+ $error?: boolean;
19
+ $success?: boolean;
20
+ $fullWidth?: boolean;
21
+ theme?: Theme;
22
+ }
23
+
24
+ const StyledTextarea = styled.textarea<TextareaProps>`
25
+ ${resetButton};
26
+ ${resetInput};
27
+ font-family: inherit;
28
+ display: inline-block;
29
+ padding: 15px;
30
+ border-radius: ${({ theme }) => theme.spacing.radius.xs};
31
+ font-weight: 400;
32
+ white-space: nowrap;
33
+ hyphens: auto;
34
+ color: ${({ theme }) => theme.colors.dark};
35
+ background: ${({ theme }) => theme.colors.light};
36
+ border: solid 2px ${({ theme }) => theme.colors.grayLight};
37
+ box-shadow: 0 0 0 0px ${({ theme }) => theme.colors.primaryLight};
38
+ transition: all 0.3s ease;
39
+ min-height: 80px;
40
+
41
+ &::placeholder {
42
+ color: ${({ theme }) => theme.colors.gray};
43
+ }
44
+
45
+ @media (hover: hover) {
46
+ &:hover:not([disabled]) {
47
+ border-color: ${({ theme }) => theme.colors.primary};
48
+ }
49
+ }
50
+
51
+ &:focus:not([disabled]) {
52
+ box-shadow: 0 0 0 4px ${({ theme }) => theme.colors.primaryLight};
53
+ border-color: ${({ theme }) => theme.colors.primary};
54
+ }
55
+
56
+ &:active:not([disabled]) {
57
+ box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.primaryLight};
58
+ }
59
+
60
+ ${({ $size, theme }) =>
61
+ $size === "big"
62
+ ? `font-size: ${theme.fontSizes.inputBig.lg};
63
+ line-height: ${theme.lineHeights.text.lg};
64
+ `
65
+ : `font-size: ${theme.fontSizes.input.lg};
66
+ line-height: ${theme.lineHeights.text.lg};`}
67
+
68
+ ${({ $error, $success, theme }) => {
69
+ return statusBorderStyles(
70
+ $error ? true : false,
71
+ $success ? true : false,
72
+ theme,
73
+ );
74
+ }}
75
+
76
+ ${({ disabled, theme }) =>
77
+ disabled &&
78
+ `cursor: not-allowed;
79
+ background: ${theme.colors.grayLight};
80
+ border-color: ${theme.colors.gray};
81
+ color: ${theme.colors.gray};
82
+ `}
83
+
84
+ ${({ $fullWidth }) => fullWidthStyles($fullWidth ? true : false)}
85
+ `;
86
+
87
+ function Textarea({ ...props }: TextareaProps) {
88
+ return (
89
+ <StyledInputWrapper $fullWidth={props.$fullWidth}>
90
+ {props.$label && (
91
+ <StyledLabel htmlFor={props.id}>{props.$label}</StyledLabel>
92
+ )}
93
+ <StyledTextarea {...props}>{props.children}</StyledTextarea>
94
+ </StyledInputWrapper>
95
+ );
96
+ }
97
+
98
+ export { Textarea };
@@ -0,0 +1,148 @@
1
+ "use client";
2
+ import React from "react";
3
+ import styled from "styled-components";
4
+ import { Theme, resetButton, statusBorderStyles } from "./utils";
5
+ import { StyledInputWrapper, StyledLabel } from "./input";
6
+
7
+ interface ToggleProps extends React.InputHTMLAttributes<HTMLInputElement> {
8
+ children?: React.ReactNode;
9
+ type?: "checkbox" | "radio";
10
+ $label?: string;
11
+ $size?: "default" | "big";
12
+ $error?: boolean;
13
+ $success?: boolean;
14
+ $fullWidth?: boolean;
15
+ theme?: Theme;
16
+ }
17
+
18
+ const StyledToggleWrapper = styled.span<ToggleProps>`
19
+ display: inline-block;
20
+ margin: auto 0;
21
+ position: relative;
22
+ vertical-align: middle;
23
+ `;
24
+
25
+ const StyledFakeToggle = styled.span<ToggleProps>`
26
+ display: block;
27
+ border: solid 2px ${({ theme }) => theme.colors.grayLight};
28
+ background: ${({ theme }) => theme.colors.light};
29
+ border-radius: ${({ theme }) => theme.spacing.radius.xl};
30
+ pointer-events: none;
31
+ transition: all 0.3s ease;
32
+ box-shadow: 0 0 0 0 ${({ theme }) => theme.colors.primaryLight};
33
+ transform: none;
34
+ width: ${({ $size }) => ($size === "big" ? "56px" : "46px")};
35
+ height: ${({ $size }) => ($size === "big" ? "32px" : "22px")};
36
+
37
+ ${({ $error, $success, theme }) => {
38
+ return statusBorderStyles(
39
+ $error ? true : false,
40
+ $success ? true : false,
41
+ theme,
42
+ );
43
+ }}
44
+
45
+ &::before,
46
+ &::after {
47
+ content: "";
48
+ display: block;
49
+ position: absolute;
50
+ }
51
+
52
+ &::before {
53
+ top: 5px;
54
+ left: 5px;
55
+ width: calc(100% - 10px);
56
+ height: calc(100% - 10px);
57
+ max-width: 0;
58
+ border-radius: ${({ theme }) => theme.spacing.radius.xl};
59
+ background: ${({ theme }) => theme.colors.light};
60
+ transition: all 0.3s ease;
61
+ }
62
+
63
+ &::after {
64
+ left: 0;
65
+ top: 0;
66
+ border-radius: 50%;
67
+ transition: all 0.3s ease;
68
+ transform: translateX(0);
69
+ background: ${({ theme }) => theme.colors.primary};
70
+ width: ${({ $size }) => ($size === "big" ? "32px" : "22px")};
71
+ height: ${({ $size }) => ($size === "big" ? "32px" : "22px")};
72
+ }
73
+ `;
74
+
75
+ const StyledToggle = styled.input<ToggleProps>`
76
+ ${resetButton};
77
+ position: absolute;
78
+ left: 0;
79
+ top: 0;
80
+ width: 100%;
81
+ height: 100%;
82
+ outline: none;
83
+ z-index: 10;
84
+
85
+ &:checked ~ .fake-toggle {
86
+ &::before {
87
+ max-width: 46px;
88
+ background: ${({ theme }) => theme.colors.primaryLight};
89
+ }
90
+
91
+ &::after {
92
+ transform: translateX(25px);
93
+ }
94
+ }
95
+
96
+ @media (hover: hover) {
97
+ &:hover:not([disabled]) ~ .fake-toggle {
98
+ border-color: ${({ theme }) => theme.colors.primary};
99
+ }
100
+ }
101
+
102
+ &:focus:not([disabled]) ~ .fake-toggle {
103
+ outline: none;
104
+ border-color: ${({ theme }) => theme.colors.primary};
105
+ box-shadow: 0 0 0 4px ${({ theme }) => theme.colors.primaryLight};
106
+ }
107
+
108
+ &:active:not([disabled]) ~ .fake-toggle {
109
+ box-shadow: 0 0 0 2px ${({ theme }) => theme.colors.primaryLight};
110
+ }
111
+
112
+ ${({ disabled, theme }) =>
113
+ disabled &&
114
+ `cursor: not-allowed;
115
+
116
+ & ~ .fake-toggle {
117
+ border-color: ${theme.colors.gray};
118
+
119
+ &::before {
120
+ background: ${theme.colors.grayLight};
121
+ }
122
+
123
+ &::after {
124
+ background: ${theme.colors.gray};
125
+ }
126
+ }`}
127
+ `;
128
+
129
+ function Toggle({ type = "checkbox", ...props }: ToggleProps) {
130
+ return (
131
+ <StyledInputWrapper $fullWidth={props.$fullWidth}>
132
+ <StyledToggleWrapper>
133
+ <StyledToggle {...props} type={type} />
134
+ <StyledFakeToggle
135
+ $error={props.$error}
136
+ $success={props.$success}
137
+ className="fake-toggle"
138
+ $size={props.$size}
139
+ />
140
+ </StyledToggleWrapper>
141
+ {props.$label && (
142
+ <StyledLabel htmlFor={props.id}>{props.$label}</StyledLabel>
143
+ )}
144
+ </StyledInputWrapper>
145
+ );
146
+ }
147
+
148
+ export { Toggle };
@@ -0,0 +1,78 @@
1
+ "use client";
2
+ import { createGlobalStyle } from "styled-components";
3
+
4
+ const GlobalStyles = createGlobalStyle`
5
+ html,
6
+ body {
7
+ margin: 0;
8
+ padding: 0;
9
+ min-height: 100%;
10
+ scroll-behavior: smooth;
11
+ }
12
+
13
+ body {
14
+ -moz-osx-font-smoothing: grayscale;
15
+ -webkit-text-size-adjust: 100%;
16
+ -webkit-font-smoothing: antialiased;
17
+ }
18
+
19
+ * {
20
+ box-sizing: border-box;
21
+ min-width: 0;
22
+ }
23
+
24
+ pre,
25
+ code,
26
+ kbd,
27
+ samp {
28
+ font-family: monospace, monospace;
29
+ }
30
+
31
+ pre,
32
+ code,
33
+ kbd,
34
+ samp,
35
+ blockquote,
36
+ p,
37
+ a,
38
+ h1,
39
+ h2,
40
+ h3,
41
+ h4,
42
+ h5,
43
+ h6 {
44
+ margin: 0;
45
+ padding: 0;
46
+ }
47
+
48
+ ol,
49
+ ul {
50
+ list-style: none;
51
+ margin: 0;
52
+ padding: 0;
53
+ }
54
+
55
+ figure {
56
+ margin: 0;
57
+ }
58
+
59
+ fieldset {
60
+ appearance: none;
61
+ border: none;
62
+ }
63
+
64
+ button,
65
+ input,
66
+ a,
67
+ img,
68
+ svg,
69
+ svg * {
70
+ transition: all 0.3s ease;
71
+ }
72
+
73
+ strong,
74
+ b {
75
+ font-weight: 700;
76
+ }`;
77
+
78
+ export { GlobalStyles };