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,89 @@
1
+ import {useState} from "react";
2
+ import {Meta} from "@storybook/react";
3
+
4
+ import {capitalizeFirstLetter, hideInTable} from "../../utils";
5
+
6
+ import {Button, List, ListItem} from "../index";
7
+
8
+ import DrawerComponent, {DrawerProps, DrawerSide} from "./Drawer";
9
+
10
+ const sides: DrawerSide[] = [DrawerSide.Left, DrawerSide.Top, DrawerSide.Bottom, DrawerSide.Right];
11
+ const items = [
12
+ {title: "Profile", icon: "👤"},
13
+ {title: "Messages", icon: "✉️"},
14
+ {title: "Notifications", icon: "🔔"},
15
+ {title: "Setting", icon: "⚙️"},
16
+ {title: "Help", icon: "❓"},
17
+ {title: "Logout", icon: "🚪"},
18
+ ];
19
+
20
+ const meta: Meta<typeof DrawerComponent> = {
21
+ title: "Components/Drawer",
22
+ component: DrawerComponent,
23
+ tags: ["autodocs"],
24
+ argTypes: {
25
+ side: {
26
+ options: sides,
27
+ control: {type: "select"},
28
+ },
29
+ modal: {
30
+ description:
31
+ "The modality of the dialog. When set to true, interaction with outside elements will be disabled and only dialog content will be visible to screen readers.",
32
+ control: {type: "boolean"},
33
+ type: "boolean",
34
+ },
35
+ speed: {
36
+ type: "number",
37
+ },
38
+ className: hideInTable,
39
+ description: hideInTable,
40
+ overlayClassName: hideInTable,
41
+ childrenClassName: hideInTable,
42
+ },
43
+ };
44
+
45
+ export default meta;
46
+
47
+ export const Drawer = (props: DrawerProps & {label?: string}) => {
48
+ const [open, setOpen] = useState(false);
49
+ const {label = "Open Drawer", ...other} = props;
50
+ return (
51
+ <div>
52
+ <Button onClick={() => setOpen(true)}>{label}</Button>
53
+ <DrawerComponent open={open} onOpenChange={setOpen} {...other}>
54
+ <div
55
+ style={{
56
+ boxSizing: "border-box",
57
+ display: "flex",
58
+ flexDirection: "column",
59
+ justifyContent: "space-between",
60
+ height: "100%",
61
+ gap: "30px",
62
+ padding: "20px",
63
+ }}
64
+ >
65
+ <List style={{display: "flex", flexDirection: "column", gap: "15px", overflow: "auto"}}>
66
+ {items.map(({icon, title}) => (
67
+ <ListItem left={icon} primary={title} />
68
+ ))}
69
+ </List>
70
+ <Button onClick={() => setOpen(false)} style={{width: "auto"}}>
71
+ Close
72
+ </Button>
73
+ </div>
74
+ </DrawerComponent>
75
+ </div>
76
+ );
77
+ };
78
+
79
+ export const Side = () => {
80
+ return (
81
+ <div className="grid-wrapper" style={{gridTemplateColumns: "repeat(4, auto)"}}>
82
+ {sides.map(side => (
83
+ <div key={side} className="item-card">
84
+ <Drawer side={side} label={`${capitalizeFirstLetter(side)} side`} />
85
+ </div>
86
+ ))}
87
+ </div>
88
+ );
89
+ };
@@ -0,0 +1,57 @@
1
+ import React, {FC, memo} from "react";
2
+ import classnames from "classnames";
3
+
4
+ import {useComponentProps} from "../../providers";
5
+ import {cloneOrCreateElement} from "../../utils";
6
+
7
+ import {Dialog, DialogProps, dialogPropsKeys} from "../Dialog";
8
+
9
+ import styles from "./drawer.module.scss";
10
+
11
+ export enum DrawerSide {
12
+ Left = "left",
13
+ Right = "right",
14
+ Top = "top",
15
+ Bottom = "bottom",
16
+ }
17
+
18
+ export interface DrawerProps extends DialogProps {
19
+ side?: DrawerSide;
20
+ }
21
+
22
+ export const drawerPropsKeys = new Set<keyof DrawerProps>(["side", ...dialogPropsKeys]);
23
+
24
+ const Drawer: FC<DrawerProps> = props => {
25
+ const {
26
+ side = DrawerSide.Left,
27
+ fullscreen,
28
+ children,
29
+ className,
30
+ overlayClassName,
31
+ childrenClassName,
32
+ ...other
33
+ } = {...useComponentProps("drawer"), ...props};
34
+
35
+ return (
36
+ <Dialog
37
+ {...other}
38
+ overlayClassName={classnames(styles["drawer-overlay"], overlayClassName)}
39
+ className={classnames(
40
+ styles["drawer-content"],
41
+ {
42
+ [styles["drawer-content--fullscreen"]]: fullscreen,
43
+ [styles[`drawer-content--${side}-side`]]: side,
44
+ },
45
+ className
46
+ )}
47
+ >
48
+ {cloneOrCreateElement(
49
+ children,
50
+ {className: classnames(styles["drawer-children"], childrenClassName)},
51
+ "div"
52
+ )}
53
+ </Dialog>
54
+ );
55
+ };
56
+
57
+ export default memo(Drawer);
@@ -0,0 +1,170 @@
1
+ $root: drawer;
2
+
3
+ .#{$root} {
4
+ &-overlay {
5
+ background-color: var(--drawer-overlay-bg-color, var(--dialog-overlay-bg-color, #111));
6
+ }
7
+
8
+ &-content {
9
+ padding: var(--drawer-padding, 0);
10
+ box-shadow: var(--drawer-box-shadow, 0 0 4px rgba(0, 0, 0, 0.5));
11
+ background-color: var(--drawer-bg-color, var(--bg-secondary-color));
12
+
13
+ &[data-state="open"] {
14
+ &.#{$root}-content--left-side {
15
+ animation-name: slideInLeft;
16
+ }
17
+
18
+ &.#{$root}-content--right-side {
19
+ animation-name: slideInRight;
20
+ }
21
+
22
+ &.#{$root}-content--top-side {
23
+ animation-name: slideInTop;
24
+ }
25
+
26
+ &.#{$root}-content--bottom-side {
27
+ animation-name: slideInBottom;
28
+ }
29
+ }
30
+
31
+ &[data-state="closed"] {
32
+ &.#{$root}-content--left-side {
33
+ animation-name: slideOutLeft;
34
+ }
35
+
36
+ &.#{$root}-content--right-side {
37
+ animation-name: slideOutRight;
38
+ }
39
+
40
+ &.#{$root}-content--top-side {
41
+ animation-name: slideOutTop;
42
+ }
43
+
44
+ &.#{$root}-content--bottom-side {
45
+ animation-name: slideOutBottom;
46
+ }
47
+ }
48
+
49
+ &--left-side {
50
+ left: 0;
51
+ top: 0;
52
+ bottom: 0;
53
+ width: var(--drawer-width, 90vw);
54
+
55
+ &.#{$root}-content--fullscreen {
56
+ width: 100%;
57
+ }
58
+ }
59
+
60
+ &--right-side {
61
+ right: 0;
62
+ top: 0;
63
+ bottom: 0;
64
+ width: var(--drawer-width, 90vw);
65
+
66
+ &.#{$root}-content--fullscreen {
67
+ width: 100%;
68
+ }
69
+ }
70
+
71
+ &--top-side {
72
+ top: 0;
73
+ left: 0;
74
+ right: 0;
75
+ height: var(--drawer-height, 90vh);
76
+
77
+ &.#{$root}-content--fullscreen {
78
+ height: 100%;
79
+ }
80
+ }
81
+
82
+ &--bottom-side {
83
+ bottom: 0;
84
+ left: 0;
85
+ right: 0;
86
+ height: var(--drawer-height, 90vh);
87
+
88
+ &.#{$root}-content--fullscreen {
89
+ height: 100%;
90
+ }
91
+ }
92
+ }
93
+
94
+ &-children {
95
+ display: flex;
96
+ flex-direction: column;
97
+ }
98
+ }
99
+
100
+ @keyframes slideInRight {
101
+ from {
102
+ transform: translateX(100%);
103
+ }
104
+ to {
105
+ transform: translateX(0);
106
+ }
107
+ }
108
+
109
+ @keyframes slideInLeft {
110
+ from {
111
+ transform: translateX(-100%);
112
+ }
113
+ to {
114
+ transform: translateX(0);
115
+ }
116
+ }
117
+
118
+ @keyframes slideInTop {
119
+ from {
120
+ transform: translateY(-100%);
121
+ }
122
+ to {
123
+ transform: translateY(0);
124
+ }
125
+ }
126
+
127
+ @keyframes slideInBottom {
128
+ from {
129
+ transform: translateY(100%);
130
+ }
131
+ to {
132
+ transform: translateY(0);
133
+ }
134
+ }
135
+
136
+ @keyframes slideOutRight {
137
+ from {
138
+ transform: translateX(0);
139
+ }
140
+ to {
141
+ transform: translateX(100%);
142
+ }
143
+ }
144
+
145
+ @keyframes slideOutLeft {
146
+ from {
147
+ transform: translateX(0);
148
+ }
149
+ to {
150
+ transform: translateX(-100%);
151
+ }
152
+ }
153
+
154
+ @keyframes slideOutTop {
155
+ from {
156
+ transform: translateY(0);
157
+ }
158
+ to {
159
+ transform: translateY(-100%);
160
+ }
161
+ }
162
+
163
+ @keyframes slideOutBottom {
164
+ from {
165
+ transform: translateY(0);
166
+ }
167
+ to {
168
+ transform: translateY(100%);
169
+ }
170
+ }
@@ -0,0 +1,2 @@
1
+ export {default as Drawer, DrawerSide, drawerPropsKeys} from "./Drawer";
2
+ export type {DrawerProps} from "./Drawer";
@@ -0,0 +1,118 @@
1
+ import {Meta, StoryObj} from "@storybook/react";
2
+
3
+ import {hideInTable} from "../../utils";
4
+
5
+ import {IconButton, IconButtonSize, IconButtonVariant} from "../index";
6
+
7
+ import FooterComponent from "./Footer";
8
+
9
+ const meta: Meta<typeof FooterComponent> = {
10
+ title: "Components/Footer",
11
+ component: FooterComponent,
12
+ tags: ["autodocs"],
13
+ argTypes: {
14
+ left: hideInTable,
15
+ right: hideInTable,
16
+ style: hideInTable,
17
+ children: hideInTable,
18
+ className: hideInTable,
19
+ leftClassName: hideInTable,
20
+ rightClassName: hideInTable,
21
+ childrenClassName: hideInTable,
22
+ },
23
+ decorators: [
24
+ Story => (
25
+ <div
26
+ style={{
27
+ display: "flex",
28
+ flexDirection: "column",
29
+ background: "var(--bg-secondary-color",
30
+ width: "380px",
31
+ height: "300px",
32
+ borderRadius: "10px",
33
+ }}
34
+ >
35
+ <span style={{flexGrow: 1}} />
36
+ <Story />
37
+ </div>
38
+ ),
39
+ ],
40
+ };
41
+
42
+ export default meta;
43
+
44
+ export const Footer: StoryObj<typeof FooterComponent> = {
45
+ args: {
46
+ shadow: true,
47
+ reverse: false,
48
+ style: {paddingTop: "20px"},
49
+ children: (
50
+ <div>
51
+ <div style={{display: "flex", gap: "20px"}}>
52
+ <IconButton style={{fontSize: "20px"}} tooltip={{content: "Change theme"}}>
53
+ 🌓
54
+ </IconButton>
55
+ <IconButton style={{fontSize: "20px"}} tooltip={{content: "Rate Us"}}>
56
+ ❤️
57
+ </IconButton>
58
+ </div>
59
+ <div style={{display: "flex", gap: "20px"}}>
60
+ <IconButton style={{fontSize: "20px"}} tooltip={{content: "Support Us"}}>
61
+ 💲
62
+ </IconButton>
63
+ <IconButton style={{fontSize: "20px"}} tooltip={{content: "FAQ"}}>
64
+
65
+ </IconButton>
66
+ </div>
67
+ </div>
68
+ ),
69
+ },
70
+ };
71
+
72
+ export const FooterWithoutChildren: StoryObj<typeof FooterComponent> = {
73
+ args: {
74
+ shadow: true,
75
+ reverse: false,
76
+ style: {paddingTop: "20px"},
77
+ left: (
78
+ <div>
79
+ <IconButton
80
+ variant={IconButtonVariant.Contained}
81
+ size={IconButtonSize.Medium}
82
+ style={{fontSize: "20px"}}
83
+ tooltip={{content: "Change theme"}}
84
+ >
85
+ 🌓
86
+ </IconButton>
87
+ <IconButton
88
+ variant={IconButtonVariant.Contained}
89
+ size={IconButtonSize.Medium}
90
+ style={{fontSize: "20px"}}
91
+ tooltip={{content: "Rate Us"}}
92
+ >
93
+ ❤️
94
+ </IconButton>
95
+ </div>
96
+ ),
97
+ right: (
98
+ <div>
99
+ <IconButton
100
+ variant={IconButtonVariant.Ghost}
101
+ size={IconButtonSize.Medium}
102
+ style={{fontSize: "20px"}}
103
+ tooltip={{content: "Support Us"}}
104
+ >
105
+ 💲
106
+ </IconButton>
107
+ <IconButton
108
+ variant={IconButtonVariant.Ghost}
109
+ size={IconButtonSize.Medium}
110
+ style={{fontSize: "20px"}}
111
+ tooltip={{content: "FAQ"}}
112
+ >
113
+
114
+ </IconButton>
115
+ </div>
116
+ ),
117
+ },
118
+ };
@@ -0,0 +1,58 @@
1
+ import React, {ComponentProps, FC, memo, ReactNode} from "react";
2
+ import classnames from "classnames";
3
+
4
+ import {cloneOrCreateElement} from "../../utils";
5
+ import {useComponentProps} from "../../providers";
6
+
7
+ import styles from "./footer.module.scss";
8
+
9
+ export interface FooterProps extends ComponentProps<"footer"> {
10
+ left?: ReactNode;
11
+ right?: ReactNode;
12
+ shadow?: boolean;
13
+ reverse?: boolean;
14
+ leftClassName?: string;
15
+ rightClassName?: string;
16
+ childrenClassName?: string;
17
+ }
18
+
19
+ const Footer: FC<FooterProps> = props => {
20
+ const {
21
+ left,
22
+ right,
23
+ shadow,
24
+ reverse,
25
+ children,
26
+ className,
27
+ leftClassName,
28
+ rightClassName,
29
+ childrenClassName,
30
+ ...other
31
+ } = {...useComponentProps("footer"), ...props};
32
+
33
+ return (
34
+ <footer
35
+ {...other}
36
+ className={classnames(
37
+ styles["footer"],
38
+ {
39
+ [styles["footer--shadow"]]: shadow,
40
+ [styles["footer--reverse"]]: reverse,
41
+ },
42
+ className
43
+ )}
44
+ >
45
+ {cloneOrCreateElement(
46
+ children,
47
+ {className: classnames(styles["footer-children"], childrenClassName)},
48
+ "div"
49
+ )}
50
+ {!children &&
51
+ cloneOrCreateElement(left, {className: classnames(styles["footer-left"], leftClassName)}, "div")}
52
+ {!children &&
53
+ cloneOrCreateElement(right, {className: classnames(styles["footer-right"], rightClassName)}, "div")}
54
+ </footer>
55
+ );
56
+ };
57
+
58
+ export default memo(Footer);
@@ -0,0 +1,44 @@
1
+ $root: footer;
2
+
3
+ .#{$root} {
4
+ box-sizing: border-box;
5
+ display: flex;
6
+ justify-content: space-between;
7
+ width: 100%;
8
+ padding: var(--footer-padding, var(--side-padding-sm));
9
+ padding-top: 0;
10
+ background-color: var(--footer-background-color, transparent);
11
+ transition:
12
+ background-color var(--transition-speed-sm),
13
+ box-shadow var(--transition-speed-sm);
14
+
15
+ &--shadow {
16
+ box-shadow: var(--footer-box-shadow, 0px -4px 4px 0px rgba(0, 0, 0, 0.03));
17
+ }
18
+
19
+ &--reverse {
20
+ flex-direction: row-reverse;
21
+ }
22
+
23
+ &-children {
24
+ width: 100%;
25
+ display: flex;
26
+ justify-content: space-between;
27
+
28
+ .#{$root}--reverse & {
29
+ flex-direction: row-reverse;
30
+ }
31
+ }
32
+
33
+ &-left {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: var(--footer-left-gap, var(--footer-gap, 15px));
37
+ }
38
+
39
+ &-right {
40
+ display: flex;
41
+ align-items: center;
42
+ gap: var(--footer-right-gap, var(--footer-gap, 15px));
43
+ }
44
+ }
@@ -0,0 +1,2 @@
1
+ export {default as Footer} from "./Footer";
2
+ export type {FooterProps} from "./Footer";
@@ -0,0 +1,49 @@
1
+ import {Meta, StoryObj} from "@storybook/react";
2
+
3
+ import {hideInTable} from "../../utils";
4
+
5
+ import HeaderComponent from "./Header";
6
+
7
+ const meta: Meta<typeof HeaderComponent> = {
8
+ title: "Components/Header",
9
+ component: HeaderComponent,
10
+ tags: ["autodocs"],
11
+ argTypes: {
12
+ before: hideInTable,
13
+ after: hideInTable,
14
+ children: hideInTable,
15
+ className: hideInTable,
16
+ wrapClassName: hideInTable,
17
+ titleClassName: hideInTable,
18
+ beforeClassName: hideInTable,
19
+ afterClassName: hideInTable,
20
+ subtitleClassName: hideInTable,
21
+ childrenClassName: hideInTable,
22
+ },
23
+ decorators: [
24
+ Story => (
25
+ <div
26
+ style={{background: "var(--bg-secondary-color", width: "380px", height: "300px", borderRadius: "10px"}}
27
+ >
28
+ <Story />
29
+ </div>
30
+ ),
31
+ ],
32
+ };
33
+
34
+ export default meta;
35
+
36
+ export const Header: StoryObj<typeof HeaderComponent> = {
37
+ args: {
38
+ title: "Volume Up Plus",
39
+ subtitle: "Adjust the current tab's volume with the slider. Switch to any audio tab in one click.",
40
+ },
41
+ };
42
+
43
+ export const WithLogo: StoryObj<typeof HeaderComponent> = {
44
+ args: {
45
+ title: "Volume Up Plus",
46
+ subtitle: "Adjust the current tab's volume with the slider. Switch to any audio tab in one click.",
47
+ before: "❤️",
48
+ },
49
+ };
@@ -0,0 +1,73 @@
1
+ import React, {ComponentProps, FC, memo, ReactNode} from "react";
2
+ import classnames from "classnames";
3
+
4
+ import {cloneOrCreateElement} from "../../utils";
5
+ import {useComponentProps} from "../../providers";
6
+
7
+ import styles from "./header.module.scss";
8
+
9
+ export interface HeaderProps extends Omit<ComponentProps<"header">, "title"> {
10
+ title?: ReactNode;
11
+ before?: ReactNode;
12
+ after?: ReactNode;
13
+ subtitle?: ReactNode;
14
+ wrapClassName?: string;
15
+ titleClassName?: string;
16
+ beforeClassName?: string;
17
+ afterClassName?: string;
18
+ subtitleClassName?: string;
19
+ childrenClassName?: string;
20
+ alignCenter?: boolean;
21
+ }
22
+
23
+ const Header: FC<HeaderProps> = props => {
24
+ const {
25
+ title,
26
+ before,
27
+ after,
28
+ subtitle,
29
+ className,
30
+ wrapClassName,
31
+ titleClassName,
32
+ beforeClassName,
33
+ afterClassName,
34
+ subtitleClassName,
35
+ childrenClassName,
36
+ alignCenter = true,
37
+ children,
38
+ ...other
39
+ } = {...useComponentProps("header"), ...props};
40
+
41
+ return (
42
+ <header
43
+ {...other}
44
+ className={classnames(
45
+ styles["header"],
46
+ {
47
+ [styles["header--center"]]: alignCenter,
48
+ },
49
+ className
50
+ )}
51
+ >
52
+ {(title || subtitle) && (
53
+ <div className={classnames(styles["header__wrap"], wrapClassName)}>
54
+ <h1 className={classnames(styles["header__title"], titleClassName)}>
55
+ {cloneOrCreateElement(before, {className: beforeClassName})}
56
+ {title}
57
+ {cloneOrCreateElement(after, {className: afterClassName})}
58
+ </h1>
59
+
60
+ {cloneOrCreateElement(
61
+ subtitle,
62
+ {className: classnames(styles["header__subtitle"], subtitleClassName)},
63
+ "h2"
64
+ )}
65
+ </div>
66
+ )}
67
+
68
+ {cloneOrCreateElement(children, {className: childrenClassName}, "div")}
69
+ </header>
70
+ );
71
+ };
72
+
73
+ export default memo(Header);