adnbn-ui 0.0.1 → 0.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.
Files changed (146) hide show
  1. package/.prettierignore +3 -0
  2. package/.prettierrc +28 -0
  3. package/.storybook/main.ts +22 -0
  4. package/.storybook/preview.tsx +100 -0
  5. package/.storybook/styles/custom.scss +59 -0
  6. package/.storybook/styles/preview.css +58 -0
  7. package/.storybook/vitest.setup.ts +9 -0
  8. package/README.md +1057 -0
  9. package/eslint.config.js +39 -0
  10. package/package.json +95 -4
  11. package/src/components/Avatar/Avatar.stories.tsx +118 -0
  12. package/src/components/Avatar/Avatar.tsx +65 -0
  13. package/src/components/Avatar/avatar.module.scss +77 -0
  14. package/src/components/Avatar/index.ts +2 -0
  15. package/src/components/BaseButton/BaseButton.tsx +36 -0
  16. package/src/components/BaseButton/base-button.module.scss +24 -0
  17. package/src/components/BaseButton/index.ts +2 -0
  18. package/src/components/Button/Button.stories.tsx +148 -0
  19. package/src/components/Button/Button.tsx +73 -0
  20. package/src/components/Button/button.module.scss +140 -0
  21. package/src/components/Button/index.ts +2 -0
  22. package/src/components/Checkbox/Checkbox.stories.tsx +180 -0
  23. package/src/components/Checkbox/Checkbox.tsx +71 -0
  24. package/src/components/Checkbox/checkbox.module.scss +82 -0
  25. package/src/components/Checkbox/index.ts +2 -0
  26. package/src/components/Dialog/Dialog.tsx +125 -0
  27. package/src/components/Dialog/dialog.module.scss +55 -0
  28. package/src/components/Dialog/index.ts +2 -0
  29. package/src/components/Drawer/Drawer.stories.tsx +89 -0
  30. package/src/components/Drawer/Drawer.tsx +57 -0
  31. package/src/components/Drawer/drawer.module.scss +170 -0
  32. package/src/components/Drawer/index.ts +2 -0
  33. package/src/components/Footer/Footer.stories.tsx +118 -0
  34. package/src/components/Footer/Footer.tsx +58 -0
  35. package/src/components/Footer/footer.module.scss +44 -0
  36. package/src/components/Footer/index.ts +2 -0
  37. package/src/components/Header/Header.stories.tsx +49 -0
  38. package/src/components/Header/Header.tsx +73 -0
  39. package/src/components/Header/header.module.scss +56 -0
  40. package/src/components/Header/index.ts +2 -0
  41. package/src/components/Highlight/Highlight.stories.tsx +83 -0
  42. package/src/components/Highlight/Highlight.tsx +40 -0
  43. package/src/components/Highlight/highlight.module.scss +47 -0
  44. package/src/components/Highlight/index.ts +2 -0
  45. package/src/components/Icon/Icon.tsx +46 -0
  46. package/src/components/Icon/icon.module.scss +17 -0
  47. package/src/components/Icon/index.ts +2 -0
  48. package/src/components/IconButton/IconButton.stories.tsx +179 -0
  49. package/src/components/IconButton/IconButton.tsx +65 -0
  50. package/src/components/IconButton/icon-button.module.scss +86 -0
  51. package/src/components/IconButton/index.ts +2 -0
  52. package/src/components/Layout/Layout.stories.tsx +88 -0
  53. package/src/components/Layout/Provider.tsx +47 -0
  54. package/src/components/Layout/context.ts +24 -0
  55. package/src/components/Layout/index.ts +2 -0
  56. package/src/components/Layout/layout.module.scss +17 -0
  57. package/src/components/List/List.stories.tsx +81 -0
  58. package/src/components/List/List.tsx +24 -0
  59. package/src/components/List/index.ts +2 -0
  60. package/src/components/List/list.module.scss +8 -0
  61. package/src/components/ListItem/ListItem.tsx +75 -0
  62. package/src/components/ListItem/index.ts +2 -0
  63. package/src/components/ListItem/list-item.module.scss +36 -0
  64. package/src/components/Modal/Modal.stories.tsx +95 -0
  65. package/src/components/Modal/Modal.tsx +94 -0
  66. package/src/components/Modal/index.ts +2 -0
  67. package/src/components/Modal/modal.module.scss +97 -0
  68. package/src/components/Odometer/Odometer.stories.tsx +66 -0
  69. package/src/components/Odometer/Odometer.tsx +45 -0
  70. package/src/components/Odometer/hooks/useOdometer.tsx +24 -0
  71. package/src/components/Odometer/index.ts +3 -0
  72. package/src/components/Odometer/odometer.module.scss +81 -0
  73. package/src/components/Odometer/odometr.d.ts +9 -0
  74. package/src/components/ScrollArea/ScrollArea.stories.tsx +58 -0
  75. package/src/components/ScrollArea/ScrollArea.tsx +63 -0
  76. package/src/components/ScrollArea/index.ts +2 -0
  77. package/src/components/ScrollArea/scroll-area.module.scss +54 -0
  78. package/src/components/SvgSprite/SvgSprite.tsx +21 -0
  79. package/src/components/SvgSprite/index.ts +2 -0
  80. package/src/components/Switch/Switch.stories.tsx +25 -0
  81. package/src/components/Switch/Switch.tsx +23 -0
  82. package/src/components/Switch/index.ts +2 -0
  83. package/src/components/Switch/switch.module.scss +65 -0
  84. package/src/components/Tag/Tag.stories.tsx +157 -0
  85. package/src/components/Tag/Tag.tsx +71 -0
  86. package/src/components/Tag/index.ts +2 -0
  87. package/src/components/Tag/tag.module.scss +118 -0
  88. package/src/components/TextArea/TextArea.stories.tsx +145 -0
  89. package/src/components/TextArea/TextArea.tsx +143 -0
  90. package/src/components/TextArea/index.ts +2 -0
  91. package/src/components/TextArea/text-area.module.scss +88 -0
  92. package/src/components/TextField/TextField.stories.tsx +177 -0
  93. package/src/components/TextField/TextField.tsx +162 -0
  94. package/src/components/TextField/index.ts +2 -0
  95. package/src/components/TextField/text-field.module.scss +129 -0
  96. package/src/components/Toast/Toast.stories.tsx +209 -0
  97. package/src/components/Toast/Toast.tsx +142 -0
  98. package/src/components/Toast/index.ts +2 -0
  99. package/src/components/Toast/toast.module.scss +267 -0
  100. package/src/components/Tooltip/Tooltip.stories.tsx +80 -0
  101. package/src/components/Tooltip/Tooltip.tsx +79 -0
  102. package/src/components/Tooltip/index.ts +2 -0
  103. package/src/components/Tooltip/tooltip.module.scss +93 -0
  104. package/src/components/View/View.stories.tsx +47 -0
  105. package/src/components/View/View.tsx +68 -0
  106. package/src/components/View/index.ts +2 -0
  107. package/src/components/View/view.module.scss +38 -0
  108. package/src/components/ViewDrawer/ViewDrawer.stories.tsx +75 -0
  109. package/src/components/ViewDrawer/ViewDrawer.tsx +24 -0
  110. package/src/components/ViewDrawer/index.ts +2 -0
  111. package/src/components/ViewModal/ViewModal.stories.tsx +68 -0
  112. package/src/components/ViewModal/ViewModal.tsx +24 -0
  113. package/src/components/ViewModal/index.ts +2 -0
  114. package/src/components/index.ts +29 -0
  115. package/src/components/types.ts +65 -0
  116. package/src/config/default.ts +3 -0
  117. package/src/config/index.ts +26 -0
  118. package/src/declaration.d.ts +8 -0
  119. package/src/index.ts +3 -0
  120. package/src/plugin/builder/ConfigBuilder.ts +32 -0
  121. package/src/plugin/builder/StyleBuilder.ts +34 -0
  122. package/src/plugin/builder/virtual.config.ts +7 -0
  123. package/src/plugin/finder/ConfigFinder.ts +26 -0
  124. package/src/plugin/finder/Finder.ts +76 -0
  125. package/src/plugin/finder/StyleFinder.ts +23 -0
  126. package/src/plugin/index.ts +70 -0
  127. package/src/plugin/types.ts +8 -0
  128. package/src/providers/UIProvider.tsx +26 -0
  129. package/src/providers/icons/IconsProvider.tsx +34 -0
  130. package/src/providers/icons/context.ts +22 -0
  131. package/src/providers/icons/index.ts +3 -0
  132. package/src/providers/index.ts +3 -0
  133. package/src/providers/theme/ThemeProvider.tsx +39 -0
  134. package/src/providers/theme/context.ts +30 -0
  135. package/src/providers/theme/index.ts +2 -0
  136. package/src/providers/theme/styles/default.scss +95 -0
  137. package/src/providers/theme/styles/reset.css +111 -0
  138. package/src/styles/mixins.scss +23 -0
  139. package/src/types/theme.ts +4 -0
  140. package/src/utils/index.ts +2 -0
  141. package/src/utils/react.ts +21 -0
  142. package/src/utils/utils.ts +12 -0
  143. package/tsconfig.json +18 -0
  144. package/vite.config.ts +11 -0
  145. package/vitest.workspace.ts +19 -0
  146. package/components/Button/index.ts +0 -0
@@ -0,0 +1,97 @@
1
+ @use "../../styles/mixins" as dir;
2
+
3
+ $root: modal;
4
+
5
+ .#{$root} {
6
+ &-overlay {
7
+ background-color: var(--modal-overlay-bg-color, var(--dialog-overlay-bg-color, #111));
8
+ }
9
+
10
+ &-content {
11
+ top: 50%;
12
+ left: 50%;
13
+ transform: translate(-50%, -50%);
14
+ width: var(--modal-width, 90vw);
15
+ max-width: var(--modal-max-width, 350px);
16
+ max-height: var(--modal-max-height, 85vh);
17
+ padding: var(--modal-padding, 0);
18
+ border-radius: var(--modal-border-radius, 10px);
19
+ box-shadow: var(--modal-box-shadow, 0 0 4px rgba(0, 0, 0, 0.5));
20
+ background-color: var(--modal-bg-color, var(--bg-primary-color));
21
+ transition:
22
+ background-color var(--transition-speed-sm),
23
+ color var(--transition-speed-sm);
24
+
25
+ &[data-state="open"] {
26
+ animation-name: contentShow;
27
+ }
28
+
29
+ &[data-state="closed"] {
30
+ animation-name: contentHide;
31
+ }
32
+
33
+ &--fullscreen {
34
+ max-width: 100%;
35
+ max-height: 100%;
36
+ width: 100%;
37
+ height: 100%;
38
+ border-radius: 0 !important;
39
+ }
40
+
41
+ &--none-radius {
42
+ border-radius: 0;
43
+ }
44
+
45
+ &--small-radius {
46
+ border-radius: var(--modal-border-radius-sm, 5px);
47
+ }
48
+
49
+ &--medium-radius {
50
+ border-radius: var(--modal-border-radius-sm, 15px);
51
+ }
52
+
53
+ &--large-radius {
54
+ border-radius: var(--modal-border-radius-sm, 20px);
55
+ }
56
+ }
57
+
58
+ &-children {
59
+ display: flex;
60
+ flex-direction: column;
61
+ }
62
+
63
+ &-close {
64
+ position: absolute !important;
65
+ top: var(--modal-close-offset, 5px);
66
+
67
+ @include dir.ltr {
68
+ right: var(--modal-close-offset, 5px);
69
+ }
70
+
71
+ @include dir.rtl {
72
+ left: var(--modal-close-offset, 5px);
73
+ }
74
+ }
75
+ }
76
+
77
+ @keyframes contentShow {
78
+ from {
79
+ opacity: 0;
80
+ transform: translate(-50%, -48%) scale(var(--modal-animation-content-scale, 0.96));
81
+ }
82
+ to {
83
+ opacity: 1;
84
+ transform: translate(-50%, -50%) scale(1);
85
+ }
86
+ }
87
+
88
+ @keyframes contentHide {
89
+ from {
90
+ opacity: 1;
91
+ transform: translate(-50%, -50%) scale(1);
92
+ }
93
+ to {
94
+ opacity: 0;
95
+ transform: translate(-50%, -48%) scale(var(--modal-animation-content-scale, 0.96));
96
+ }
97
+ }
@@ -0,0 +1,66 @@
1
+ import {useEffect, useState} from "react";
2
+ import {Meta, StoryObj} from "@storybook/react";
3
+
4
+ import {hideInTable} from "../../utils";
5
+
6
+ import OdometerComponent from "./Odometer";
7
+
8
+ const meta: Meta<typeof OdometerComponent> = {
9
+ title: "Components/Odometer",
10
+ component: OdometerComponent,
11
+ tags: ["autodocs"],
12
+ argTypes: {
13
+ value: {
14
+ description: "The number to display on the odometer.",
15
+ control: {type: "number"},
16
+ },
17
+ format: {
18
+ description: "Formatting string for odometer value.",
19
+ control: {type: "text"},
20
+ },
21
+ duration: {
22
+ description: "Animation duration in milliseconds.",
23
+ control: {type: "number"},
24
+ },
25
+ auto: hideInTable,
26
+ className: hideInTable,
27
+ },
28
+ };
29
+
30
+ export default meta;
31
+
32
+ export const Odometer: StoryObj<typeof OdometerComponent> = {
33
+ args: {
34
+ value: 1234,
35
+ duration: 500,
36
+ format: "d",
37
+ },
38
+ };
39
+
40
+ export const OdometerCount = () => {
41
+ const [value, setValue] = useState(100);
42
+
43
+ useEffect(() => {
44
+ const interval = setInterval(() => {
45
+ setValue(prev => ++prev);
46
+ }, 1000);
47
+
48
+ return () => clearInterval(interval);
49
+ }, []);
50
+
51
+ return <OdometerComponent value={value} />;
52
+ };
53
+
54
+ export const OdometerRandom = () => {
55
+ const [value, setValue] = useState(100);
56
+
57
+ useEffect(() => {
58
+ const interval = setInterval(() => {
59
+ setValue(prev => prev + Math.floor(Math.random() * 10) + 1);
60
+ }, 3000);
61
+
62
+ return () => clearInterval(interval);
63
+ }, []);
64
+
65
+ return <OdometerComponent value={value} duration={1000} />;
66
+ };
@@ -0,0 +1,45 @@
1
+ import React, {FC, memo, useRef} from "react";
2
+
3
+ import classNames from "classnames";
4
+
5
+ import {useComponentProps} from "../../providers";
6
+
7
+ import useOdometer, {OdometerOptions} from "./hooks/useOdometer";
8
+
9
+ import styles from "./odometer.module.scss";
10
+
11
+ export interface OdometerProps extends OdometerOptions {
12
+ value: number;
13
+ className?: string;
14
+ }
15
+
16
+ const Odometer: FC<OdometerProps> = props => {
17
+ const {
18
+ value,
19
+ auto = false,
20
+ format = "d",
21
+ duration = 250,
22
+ className,
23
+ ...other
24
+ } = {...useComponentProps("odometer"), ...props};
25
+
26
+ const targetRef = useRef(null);
27
+
28
+ useOdometer(targetRef, value, {
29
+ ...other,
30
+ auto,
31
+ format,
32
+ duration,
33
+ });
34
+
35
+ return (
36
+ <span
37
+ ref={targetRef}
38
+ dir="ltr"
39
+ style={{"--speed": `${duration}ms`} as React.CSSProperties}
40
+ className={classNames(styles["odometer"], className)}
41
+ />
42
+ );
43
+ };
44
+
45
+ export default memo(Odometer);
@@ -0,0 +1,24 @@
1
+ import {RefObject, useEffect, useRef} from "react";
2
+ import Odometer from "odometer";
3
+
4
+ export interface OdometerOptions {
5
+ auto?: boolean;
6
+ format?: string;
7
+ duration?: number;
8
+ }
9
+
10
+ export default (ref: RefObject<HTMLElement | null>, value: number, options: OdometerOptions = {}) => {
11
+ const od = useRef<Odometer | null>(null);
12
+
13
+ useEffect(() => {
14
+ if (ref.current === null) return;
15
+
16
+ od.current = new Odometer({...options, el: ref.current, value});
17
+ }, [ref, options, value]);
18
+
19
+ useEffect(() => {
20
+ od.current?.update(value);
21
+ }, [value]);
22
+
23
+ return od.current;
24
+ };
@@ -0,0 +1,3 @@
1
+ export {default as Odometer} from "./Odometer";
2
+ export {default as useOdometer} from "./hooks/useOdometer";
3
+ export type {OdometerProps} from "./Odometer";
@@ -0,0 +1,81 @@
1
+ $root: odometer;
2
+
3
+ .#{$root} {
4
+ display: inline-block;
5
+ position: relative;
6
+ color: var(--odometer-color, var(--text-primary-color));
7
+ font-family: var(--odometer-font-family, var(--font-family)), sans-serif;
8
+
9
+ &-digit {
10
+ display: inline-block;
11
+ position: relative;
12
+
13
+ &-spacer {
14
+ display: inline-block;
15
+ visibility: hidden;
16
+ }
17
+
18
+ &-inner {
19
+ text-align: left;
20
+ display: block;
21
+ position: absolute;
22
+ top: 0;
23
+ left: 0;
24
+ right: 0;
25
+ bottom: 0;
26
+ overflow: hidden;
27
+ }
28
+ }
29
+
30
+ &-ribbon {
31
+ display: block;
32
+
33
+ &-inner {
34
+ display: block;
35
+ -webkit-backface-visibility: hidden;
36
+
37
+ .#{$root}-animating-up & {
38
+ transition: transform var(--speed);
39
+ }
40
+
41
+ .#{$root}-animating-up.#{$root}-animating & {
42
+ transform: translateY(-100%);
43
+ }
44
+
45
+ .#{$root}-animating-down & {
46
+ transform: translateY(-100%);
47
+ }
48
+
49
+ .#{$root}-animating-down.#{$root}-animating & {
50
+ transition: transform var(--speed);
51
+ transform: translateY(0);
52
+ }
53
+ }
54
+ }
55
+
56
+ &-value {
57
+ display: block;
58
+ text-align: center;
59
+ transform: translateZ(0);
60
+ }
61
+
62
+ &-last-value {
63
+ position: absolute;
64
+ }
65
+
66
+ &-inside {
67
+ transition:
68
+ all var(--speed),
69
+ color var(--transition-speed-sm);
70
+
71
+ &:before {
72
+ content: "";
73
+ width: 0;
74
+ display: inline-block;
75
+ color: inherit;
76
+ transition:
77
+ all var(--speed),
78
+ color var(--transition-speed-sm);
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,9 @@
1
+ declare module "odometer" {
2
+ class Odometer {
3
+ constructor(options: {el: HTMLElement; auto?: boolean; value?: number; format?: string; duration?: number});
4
+
5
+ update(value: number): void;
6
+ }
7
+
8
+ export default Odometer;
9
+ }
@@ -0,0 +1,58 @@
1
+ import {Meta, StoryObj} from "@storybook/react";
2
+
3
+ import {hideInTable} from "../../utils";
4
+
5
+ import ScrollAreaComponent from "./ScrollArea";
6
+
7
+ const meta: Meta<typeof ScrollAreaComponent> = {
8
+ title: "Components/ScrollArea",
9
+ component: ScrollAreaComponent,
10
+ tags: ["autodocs"],
11
+ argTypes: {
12
+ type: {
13
+ description:
14
+ "Describes the nature of scrollbar visibility, similar to how the scrollbar preferences in MacOS control visibility of native scrollbars.",
15
+ options: ["auto", "always", "scroll", "hover"],
16
+ control: {type: "select"},
17
+ },
18
+ scrollHideDelay: {
19
+ description:
20
+ 'If type is set to either "scroll" or "hover", this prop determines the length of time, in milliseconds, before the scrollbars are hidden after the user stops interacting with scrollbars.',
21
+ },
22
+ dir: {
23
+ description:
24
+ "The reading direction of the scroll area. If omitted, inherits globally from DirectionProvider or assumes LTR (left-to-right) reading mode.",
25
+ options: ["ltr", "rtl"],
26
+ control: {type: "select"},
27
+ },
28
+
29
+ style: hideInTable,
30
+ className: hideInTable,
31
+ thumbClassName: hideInTable,
32
+ cornerClassName: hideInTable,
33
+ viewportClassName: hideInTable,
34
+ scrollbarClassName: hideInTable,
35
+ },
36
+ };
37
+
38
+ export default meta;
39
+
40
+ export const ScrollArea: StoryObj<typeof ScrollAreaComponent> = {
41
+ args: {
42
+ type: "hover",
43
+ dir: "ltr",
44
+ xOffset: 3,
45
+ yOffset: 3,
46
+ scrollHideDelay: 600,
47
+ style: {
48
+ padding: "10px",
49
+ width: "300px",
50
+ height: "150px",
51
+ borderRadius: "10px",
52
+ color: "var(--text-secondary-color)",
53
+ background: "var(--bg-secondary-color)",
54
+ },
55
+ children:
56
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam vehicula, justo at congue malesuada, arcu elit malesuada eros, ut tempor justo libero a est. Donec sit amet tortor nec justo auctor sagittis. Suspendisse potenti. Fusce gravida, libero vel auctor pretium, odio risus vehicula nunc, et ultricies nunc arcu a neque. Aliquam erat volutpat. Morbi vulputate erat nec lectus vestibulum, at ullamcorper risus aliquet",
57
+ },
58
+ };
@@ -0,0 +1,63 @@
1
+ import React, {FC, memo} from "react";
2
+ import classnames from "classnames";
3
+ import {
4
+ Corner,
5
+ Root,
6
+ ScrollAreaProps as ScrollAreaRootProps,
7
+ Scrollbar,
8
+ Thumb,
9
+ Viewport,
10
+ } from "@radix-ui/react-scroll-area";
11
+
12
+ import {useComponentProps} from "../../providers";
13
+
14
+ import styles from "./scroll-area.module.scss";
15
+
16
+ export interface ScrollAreaProps extends ScrollAreaRootProps {
17
+ xOffset?: number;
18
+ yOffset?: number;
19
+ thumbClassName?: string;
20
+ cornerClassName?: string;
21
+ viewportClassName?: string;
22
+ scrollbarClassName?: string;
23
+ }
24
+
25
+ const ScrollArea: FC<ScrollAreaProps> = props => {
26
+ const {
27
+ xOffset,
28
+ yOffset,
29
+ children,
30
+ className,
31
+ thumbClassName,
32
+ cornerClassName,
33
+ viewportClassName,
34
+ scrollbarClassName,
35
+ ...other
36
+ } = {...useComponentProps("scrollArea"), ...props};
37
+
38
+ return (
39
+ <Root className={classnames(styles["scroll-area"], className)} {...other}>
40
+ <Viewport className={classnames(styles["scroll-area__viewport"], viewportClassName)}>{children}</Viewport>
41
+
42
+ <Scrollbar
43
+ orientation="vertical"
44
+ style={{padding: `0 ${xOffset}px`}}
45
+ className={classnames(styles["scroll-area__scrollbar"], scrollbarClassName)}
46
+ >
47
+ <Thumb className={classnames(styles["scroll-area__thumb"], thumbClassName)} />
48
+ </Scrollbar>
49
+
50
+ <Scrollbar
51
+ orientation="horizontal"
52
+ style={{padding: `${yOffset}px 0`}}
53
+ className={classnames(styles["scroll-area__scrollbar"], scrollbarClassName)}
54
+ >
55
+ <Thumb className={classnames(styles["scroll-area__thumb"], thumbClassName)} />
56
+ </Scrollbar>
57
+
58
+ <Corner className={classnames(styles["scroll-area__corner"], cornerClassName)} />
59
+ </Root>
60
+ );
61
+ };
62
+
63
+ export default memo(ScrollArea);
@@ -0,0 +1,2 @@
1
+ export {default as ScrollArea} from "./ScrollArea";
2
+ export type {ScrollAreaProps} from "./ScrollArea";
@@ -0,0 +1,54 @@
1
+ $root: scroll-area;
2
+
3
+ .#{$root} {
4
+ box-sizing: border-box;
5
+ overflow: hidden;
6
+
7
+ &__viewport {
8
+ width: 100%;
9
+ height: 100%;
10
+ }
11
+
12
+ &__scrollbar {
13
+ display: flex;
14
+ user-select: none;
15
+ touch-action: none;
16
+ padding: var(--scroll-area-scrollbar-padding, 3px);
17
+ background: var(--scroll-area-scrollbar-bg-color, transparent);
18
+ transition: background var(--transition-speed-sm) ease-in-out;
19
+
20
+ &:hover {
21
+ background: var(--scroll-area-scrollbar-bg-color-hover, transparent);
22
+ }
23
+
24
+ &[data-orientation="vertical"] {
25
+ width: var(--scroll-area-scrollbar-size, 9px);
26
+ padding: 0 var(--scroll-area-scrollbar-offset, var(--scroll-area-scrollbar-x-offset, 2px));
27
+ }
28
+
29
+ &[data-orientation="horizontal"] {
30
+ flex-direction: column;
31
+ height: var(--scroll-area-scrollbar-size, 9px);
32
+ padding: var(--scroll-area-scrollbar-offset, var(--scroll-area-scrollbar-y-offset, 2px)) 0;
33
+ }
34
+ }
35
+
36
+ &__thumb {
37
+ flex: 1;
38
+ position: relative;
39
+ background: var(--scroll-area-thumb-bg-color);
40
+ border-radius: var(--scroll-area-thumb-border-radius, 100px);
41
+
42
+ &:hover {
43
+ background: var(--scroll-area-thumb-bg-color-hover, var(--scroll-area-thumb-bg-color));
44
+ }
45
+ }
46
+
47
+ &__corner {
48
+ background: var(--scroll-area-scrollbar-bg-color, transparent);
49
+
50
+ &:hover {
51
+ background: var(--scroll-area-scrollbar-bg-color-hover, transparent);
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,21 @@
1
+ import React, {ComponentProps, FC, memo} from "react";
2
+
3
+ export interface SvgSpriteProps {
4
+ icons: Record<string, FC<ComponentProps<"svg">>>;
5
+ }
6
+
7
+ const SvgSprite: FC<SvgSpriteProps> = ({icons}) => {
8
+ return (
9
+ <svg style={{display: "none"}} aria-hidden="true">
10
+ <defs>
11
+ {Object.entries(icons).map(([name, Icon]) => (
12
+ <symbol id={name} key={name} viewBox="0 0 24 24">
13
+ <Icon />
14
+ </symbol>
15
+ ))}
16
+ </defs>
17
+ </svg>
18
+ );
19
+ };
20
+
21
+ export default memo(SvgSprite);
@@ -0,0 +1,2 @@
1
+ export {default as SvgSprite} from "./SvgSprite";
2
+ export type {SvgSpriteProps} from "./SvgSprite";
@@ -0,0 +1,25 @@
1
+ import {Meta, StoryObj} from "@storybook/react";
2
+
3
+ import {hideInTable} from "../../utils";
4
+
5
+ import SwitchComponent from "./Switch";
6
+
7
+ const meta: Meta<typeof SwitchComponent> = {
8
+ title: "Components/Switch",
9
+ component: SwitchComponent,
10
+ tags: ["autodocs"],
11
+ argTypes: {
12
+ children: hideInTable,
13
+ className: hideInTable,
14
+ thumbClassName: hideInTable,
15
+ },
16
+ };
17
+
18
+ export default meta;
19
+
20
+ export const Switch: StoryObj<typeof SwitchComponent> = {
21
+ args: {
22
+ checked: true,
23
+ disabled: false,
24
+ },
25
+ };
@@ -0,0 +1,23 @@
1
+ import React, {FC, memo} from "react";
2
+ import classnames from "classnames";
3
+ import {Root, SwitchProps as SwitchRootProps, Thumb} from "@radix-ui/react-switch";
4
+
5
+ import {useComponentProps} from "../../providers";
6
+
7
+ import styles from "./switch.module.scss";
8
+
9
+ export interface SwitchProps extends SwitchRootProps {
10
+ thumbClassName?: string;
11
+ }
12
+
13
+ const Switch: FC<SwitchProps> = props => {
14
+ const {className, thumbClassName, ...other} = {...useComponentProps("switch"), ...props};
15
+
16
+ return (
17
+ <Root {...other} className={classnames(styles["switch"], className)}>
18
+ <Thumb className={classnames(styles["switch__thumb"], thumbClassName)} />
19
+ </Root>
20
+ );
21
+ };
22
+
23
+ export default memo(Switch);
@@ -0,0 +1,2 @@
1
+ export {default as Switch} from "./Switch";
2
+ export type {SwitchProps} from "./Switch";
@@ -0,0 +1,65 @@
1
+ @use "../../styles/mixins" as dir;
2
+
3
+ @function switch-width() {
4
+ @return var(--switch-width, 36px);
5
+ }
6
+
7
+ @function switch-height() {
8
+ @return var(--switch-height, 22px);
9
+ }
10
+
11
+ @function switch-thumb-width() {
12
+ @return var(--switch-thumb-width, 18px);
13
+ }
14
+
15
+ @function switch-thumb-height() {
16
+ @return var(--switch-thumb-height, 18px);
17
+ }
18
+
19
+ $root: switch;
20
+
21
+ .#{$root} {
22
+ margin: 0;
23
+ padding: 0;
24
+ border: none;
25
+ box-sizing: border-box;
26
+ cursor: pointer;
27
+ position: relative;
28
+ width: switch-width();
29
+ height: switch-height();
30
+ border-radius: var(--switch-border-radius, 9999px);
31
+ background: var(--switch-bg-color, #bbb);
32
+ will-change: background;
33
+ transition: background var(--transition-speed-sm);
34
+
35
+ &[data-state="checked"] {
36
+ background-color: var(--switch-cheked-bg-color, var(--primary-color));
37
+ }
38
+
39
+ &:disabled {
40
+ opacity: var(--switch-disabled-opacity, 0.6);
41
+ cursor: default;
42
+ }
43
+
44
+ &__thumb {
45
+ box-sizing: border-box;
46
+ display: block;
47
+ width: switch-thumb-width();
48
+ height: switch-thumb-height();
49
+ transform: translateX(calc((#{switch-height()} - #{switch-thumb-height()}) / 2));
50
+ background-color: var(--switch-thumb-bg-color, white);
51
+ border-radius: var(--switch-border-radius, 9999px);
52
+ will-change: transform;
53
+ transition: transform var(--transition-speed-sm) ease-in-out;
54
+
55
+ @include dir.rtl {
56
+ margin-right: calc(#{switch-width()} / 2);
57
+ }
58
+
59
+ &[data-state="checked"] {
60
+ transform: translateX(
61
+ calc(#{switch-width()} - #{switch-thumb-width()} - (#{switch-height()} - #{switch-thumb-height()}) / 2)
62
+ );
63
+ }
64
+ }
65
+ }