addon-ui 0.3.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 (129) hide show
  1. package/README.md +1197 -0
  2. package/package.json +113 -0
  3. package/src/components/Avatar/Avatar.tsx +56 -0
  4. package/src/components/Avatar/avatar.module.scss +78 -0
  5. package/src/components/Avatar/index.ts +2 -0
  6. package/src/components/Avatar/types.ts +11 -0
  7. package/src/components/BaseButton/BaseButton.tsx +36 -0
  8. package/src/components/BaseButton/base-button.module.scss +24 -0
  9. package/src/components/BaseButton/index.ts +1 -0
  10. package/src/components/Button/Button.tsx +51 -0
  11. package/src/components/Button/button.module.scss +140 -0
  12. package/src/components/Button/index.ts +2 -0
  13. package/src/components/Button/types.ts +24 -0
  14. package/src/components/Checkbox/Checkbox.tsx +58 -0
  15. package/src/components/Checkbox/checkbox.module.scss +82 -0
  16. package/src/components/Checkbox/index.ts +2 -0
  17. package/src/components/Checkbox/types.ts +15 -0
  18. package/src/components/Dialog/Dialog.tsx +126 -0
  19. package/src/components/Dialog/dialog.module.scss +55 -0
  20. package/src/components/Dialog/index.ts +1 -0
  21. package/src/components/Drawer/Drawer.tsx +53 -0
  22. package/src/components/Drawer/drawer.module.scss +170 -0
  23. package/src/components/Drawer/index.ts +2 -0
  24. package/src/components/Drawer/types.ts +6 -0
  25. package/src/components/Footer/Footer.tsx +59 -0
  26. package/src/components/Footer/footer.module.scss +45 -0
  27. package/src/components/Footer/index.ts +1 -0
  28. package/src/components/Header/Header.tsx +74 -0
  29. package/src/components/Header/header.module.scss +56 -0
  30. package/src/components/Header/index.ts +1 -0
  31. package/src/components/Highlight/Highlight.tsx +36 -0
  32. package/src/components/Highlight/highlight.module.scss +48 -0
  33. package/src/components/Highlight/index.ts +2 -0
  34. package/src/components/Highlight/types.ts +5 -0
  35. package/src/components/Icon/Icon.tsx +46 -0
  36. package/src/components/Icon/icon.module.scss +17 -0
  37. package/src/components/Icon/index.ts +1 -0
  38. package/src/components/IconButton/IconButton.tsx +50 -0
  39. package/src/components/IconButton/icon-button.module.scss +86 -0
  40. package/src/components/IconButton/index.ts +2 -0
  41. package/src/components/IconButton/types.ts +17 -0
  42. package/src/components/Layout/Provider.tsx +60 -0
  43. package/src/components/Layout/context.ts +24 -0
  44. package/src/components/Layout/index.ts +2 -0
  45. package/src/components/Layout/layout.module.scss +17 -0
  46. package/src/components/List/List.tsx +24 -0
  47. package/src/components/List/index.ts +1 -0
  48. package/src/components/List/list.module.scss +8 -0
  49. package/src/components/ListItem/ListItem.tsx +75 -0
  50. package/src/components/ListItem/index.ts +1 -0
  51. package/src/components/ListItem/list-item.module.scss +37 -0
  52. package/src/components/Modal/Modal.tsx +90 -0
  53. package/src/components/Modal/index.ts +2 -0
  54. package/src/components/Modal/modal.module.scss +97 -0
  55. package/src/components/Modal/types.ts +6 -0
  56. package/src/components/Odometer/Odometer.tsx +45 -0
  57. package/src/components/Odometer/hooks/useOdometer.tsx +24 -0
  58. package/src/components/Odometer/index.ts +2 -0
  59. package/src/components/Odometer/odometer.module.scss +81 -0
  60. package/src/components/Odometer/odometr.d.ts +9 -0
  61. package/src/components/ScrollArea/ScrollArea.tsx +75 -0
  62. package/src/components/ScrollArea/index.ts +1 -0
  63. package/src/components/ScrollArea/scroll-area.module.scss +58 -0
  64. package/src/components/SvgSprite/SvgSprite.tsx +21 -0
  65. package/src/components/SvgSprite/index.ts +1 -0
  66. package/src/components/Switch/Switch.tsx +24 -0
  67. package/src/components/Switch/index.ts +1 -0
  68. package/src/components/Switch/switch.module.scss +65 -0
  69. package/src/components/Tag/Tag.tsx +50 -0
  70. package/src/components/Tag/index.ts +2 -0
  71. package/src/components/Tag/tag.module.scss +118 -0
  72. package/src/components/Tag/types.ts +23 -0
  73. package/src/components/TextArea/TextArea.tsx +126 -0
  74. package/src/components/TextArea/index.ts +2 -0
  75. package/src/components/TextArea/text-area.module.scss +88 -0
  76. package/src/components/TextArea/types.ts +18 -0
  77. package/src/components/TextField/TextField.tsx +139 -0
  78. package/src/components/TextField/index.ts +2 -0
  79. package/src/components/TextField/text-field.module.scss +129 -0
  80. package/src/components/TextField/types.ts +24 -0
  81. package/src/components/Toast/Toast.tsx +124 -0
  82. package/src/components/Toast/index.ts +2 -0
  83. package/src/components/Toast/toast.module.scss +267 -0
  84. package/src/components/Toast/types.ts +20 -0
  85. package/src/components/Tooltip/Tooltip.tsx +82 -0
  86. package/src/components/Tooltip/index.ts +1 -0
  87. package/src/components/Tooltip/tooltip.module.scss +123 -0
  88. package/src/components/View/View.tsx +68 -0
  89. package/src/components/View/index.ts +1 -0
  90. package/src/components/View/view.module.scss +38 -0
  91. package/src/components/ViewDrawer/ViewDrawer.tsx +24 -0
  92. package/src/components/ViewDrawer/index.ts +1 -0
  93. package/src/components/ViewModal/ViewModal.tsx +24 -0
  94. package/src/components/ViewModal/index.ts +1 -0
  95. package/src/components/index.ts +27 -0
  96. package/src/components/types.ts +65 -0
  97. package/src/config/default.ts +3 -0
  98. package/src/config/index.ts +8 -0
  99. package/src/declaration.d.ts +8 -0
  100. package/src/index.ts +3 -0
  101. package/src/plugin/builder/ConfigBuilder.ts +32 -0
  102. package/src/plugin/builder/StyleBuilder.ts +35 -0
  103. package/src/plugin/builder/virtual.config.ts +5 -0
  104. package/src/plugin/finder/ConfigFinder.ts +26 -0
  105. package/src/plugin/finder/Finder.ts +76 -0
  106. package/src/plugin/finder/StyleFinder.ts +23 -0
  107. package/src/plugin/index.ts +73 -0
  108. package/src/plugin/types.ts +8 -0
  109. package/src/providers/extra/ExtraProvider.tsx +13 -0
  110. package/src/providers/extra/context.ts +14 -0
  111. package/src/providers/extra/index.ts +2 -0
  112. package/src/providers/icons/IconsProvider.tsx +35 -0
  113. package/src/providers/icons/context.ts +20 -0
  114. package/src/providers/icons/index.ts +2 -0
  115. package/src/providers/index.ts +4 -0
  116. package/src/providers/theme/ThemeProvider.tsx +60 -0
  117. package/src/providers/theme/ThemeStorage.tsx +36 -0
  118. package/src/providers/theme/context.ts +30 -0
  119. package/src/providers/theme/index.ts +3 -0
  120. package/src/providers/ui/UIProvider.tsx +41 -0
  121. package/src/providers/ui/index.ts +1 -0
  122. package/src/providers/ui/styles/default.scss +95 -0
  123. package/src/providers/ui/styles/reset.scss +127 -0
  124. package/src/styles/mixins.scss +23 -0
  125. package/src/types/config.ts +15 -0
  126. package/src/types/theme.ts +11 -0
  127. package/src/utils/index.ts +2 -0
  128. package/src/utils/react.ts +21 -0
  129. package/src/utils/utils.ts +12 -0
package/package.json ADDED
@@ -0,0 +1,113 @@
1
+ {
2
+ "name": "addon-ui",
3
+ "type": "module",
4
+ "version": "0.3.0",
5
+ "description": "A comprehensive React UI component library designed exclusively for the AddonBone browser extension framework with customizable theming and consistent design patterns",
6
+ "keywords": [
7
+ "react",
8
+ "ui",
9
+ "components",
10
+ "adnbn",
11
+ "addonbone",
12
+ "browser-extension",
13
+ "theme",
14
+ "customizable",
15
+ "typescript",
16
+ "design-system"
17
+ ],
18
+ "author": "Addon Stack",
19
+ "contributors": [
20
+ "Anjey Tsibylskij <addonbonedev@gmail.com> (https://github.com/atldays)"
21
+ ],
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/addon-stack/addon-ui.git"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/addon-stack/addon-ui/issues"
29
+ },
30
+ "types": "./src/index.ts",
31
+ "typesVersions": {
32
+ "*": {
33
+ ".": [
34
+ "./src/index.ts"
35
+ ],
36
+ "config": [
37
+ "./src/config/index.ts"
38
+ ],
39
+ "plugin": [
40
+ "./src/plugin/index.ts"
41
+ ]
42
+ }
43
+ },
44
+ "exports": {
45
+ ".": "./src/index.ts",
46
+ "./config": "./src/config/index.ts",
47
+ "./plugin": "./src/plugin/index.ts",
48
+ "./theme": "./src/styles/mixins.scss"
49
+ },
50
+ "sideEffects": [
51
+ "*.css",
52
+ "*.scss"
53
+ ],
54
+ "scripts": {
55
+ "lint": "eslint .",
56
+ "format": "prettier --write .",
57
+ "storybook": "storybook dev -p 6006",
58
+ "build-storybook": "storybook build"
59
+ },
60
+ "dependencies": {
61
+ "autosize": "^6.0.1",
62
+ "classnames": "^2.5.1",
63
+ "odometer": "^0.4.8",
64
+ "radix-ui": "^1.1.3",
65
+ "react-highlight-words": "^0.21.0",
66
+ "sass": "^1.85.1",
67
+ "storybook-react-rsbuild": "^2.1.0",
68
+ "ts-deepmerge": "^7.0.3"
69
+ },
70
+ "devDependencies": {
71
+ "adnbn": "^0.2.9",
72
+ "@eslint/js": "^9.21.0",
73
+ "@rsbuild/plugin-sass": "^1.4.0",
74
+ "@storybook/react": "^9.1.3",
75
+ "@types/autosize": "^4.0.3",
76
+ "@types/node": "^22.13.10",
77
+ "@types/react": "^19.0.10",
78
+ "@types/react-dom": "^19.0.4",
79
+ "@types/react-highlight-words": "^0.20.0",
80
+ "depcheck": "^1.4.7",
81
+ "eslint": "^9.21.0",
82
+ "eslint-plugin-react-hooks": "^5.1.0",
83
+ "eslint-plugin-react-refresh": "^0.4.19",
84
+ "globals": "^15.15.0",
85
+ "prettier": "^3.5.3",
86
+ "react": "^19.1.0",
87
+ "react-dom": "^19.1.0",
88
+ "rspack-plugin-virtual-module": "^1.0.0",
89
+ "storybook": "^9.1.3",
90
+ "typescript": "~5.7.2",
91
+ "typescript-eslint": "^8.24.1"
92
+ },
93
+ "peerDependencies": {
94
+ "@types/react": "*",
95
+ "@types/react-dom": "*",
96
+ "adnbn": ">=0.2.7",
97
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
98
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
99
+ },
100
+ "peerDependenciesMeta": {
101
+ "@types/react": {
102
+ "optional": true
103
+ },
104
+ "@types/react-dom": {
105
+ "optional": true
106
+ }
107
+ },
108
+ "eslintConfig": {
109
+ "extends": [
110
+ "plugin:storybook/recommended"
111
+ ]
112
+ }
113
+ }
@@ -0,0 +1,56 @@
1
+ import React, {memo, ReactNode, forwardRef, ForwardRefRenderFunction} from "react";
2
+ import classnames from "classnames";
3
+ import {AvatarFallbackProps, AvatarImageProps, Fallback, Image, Root} from "@radix-ui/react-avatar";
4
+
5
+ import {useComponentProps} from "../../providers";
6
+
7
+ import {AvatarRadius, AvatarSize} from "./types";
8
+
9
+ import styles from "./avatar.module.scss";
10
+
11
+ export interface AvatarProps extends AvatarImageProps, Pick<AvatarFallbackProps, "delayMs"> {
12
+ imageClassName?: string;
13
+ size?: AvatarSize;
14
+ radius?: AvatarRadius;
15
+ fallback?: ReactNode;
16
+ fallbackClassName?: string;
17
+ cursorPointer?: boolean;
18
+ }
19
+
20
+ const Avatar: ForwardRefRenderFunction<HTMLSpanElement, AvatarProps> = (props, ref) => {
21
+ const {
22
+ size,
23
+ radius,
24
+ fallback,
25
+ fallbackClassName,
26
+ delayMs = 600,
27
+ cursorPointer,
28
+ imageClassName,
29
+ className,
30
+ ...other
31
+ } = {...useComponentProps("avatar"), ...props};
32
+
33
+ return (
34
+ <Root
35
+ ref={ref}
36
+ className={classnames(
37
+ styles["avatar"],
38
+ {
39
+ [styles[`avatar--${size}-size`]]: size,
40
+ [styles[`avatar--${radius}-radius`]]: radius,
41
+ [styles[`avatar--cursor-pointer`]]: cursorPointer,
42
+ },
43
+ className
44
+ )}
45
+ >
46
+ <Image className={classnames(styles["avatar-image"], imageClassName)} {...other} />
47
+ {fallback && (
48
+ <Fallback className={classnames(styles["avatar-fallback"], fallbackClassName)} delayMs={delayMs}>
49
+ {fallback}
50
+ </Fallback>
51
+ )}
52
+ </Root>
53
+ );
54
+ };
55
+
56
+ export default memo(forwardRef(Avatar));
@@ -0,0 +1,78 @@
1
+ $root: avatar;
2
+
3
+ .#{$root} {
4
+ box-sizing: border-box;
5
+ display: inline-flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ vertical-align: middle;
9
+ overflow: hidden;
10
+ cursor: default;
11
+ width: var(--avatar-size, 45px);
12
+ height: var(--avatar-size, 45px);
13
+ background-color: var(--avatar-bg-color, transparent);
14
+ border-radius: var(--avatar-border-radius, 100%);
15
+ border-width: var(--avatar-border-width);
16
+ border-color: var(--avatar-border-color);
17
+ border-style: var(--avatar-border-style);
18
+ font-size: var(--avatar-font-size, 18px);
19
+ font-weight: var(--avatar-font-weight, 500);
20
+
21
+ &--cursor-pointer {
22
+ cursor: pointer;
23
+ }
24
+
25
+ // Size
26
+ &--small-size {
27
+ width: var(--avatar-size-sm, 35px);
28
+ height: var(--avatar-size-sm, 35px);
29
+ font-size: var(--avatar-font-size-sm, 14px);
30
+ }
31
+
32
+ &--medium-size {
33
+ width: var(--avatar-size-md, 55px);
34
+ height: var(--avatar-size-md, 55px);
35
+ font-size: var(--avatar-font-size-md, 22px);
36
+ }
37
+
38
+ &--large-size {
39
+ width: var(--avatar-size-lg, 65px);
40
+ height: var(--avatar-size-lg, 65px);
41
+ font-size: var(--avatar-font-size-lg, 26px);
42
+ }
43
+
44
+ // Radius
45
+ &--small-radius {
46
+ border-radius: var(--avatar-border-radius-sm, 20%);
47
+ }
48
+
49
+ &--medium-radius {
50
+ border-radius: var(--avatar-border-radius-md, 30%);
51
+ }
52
+
53
+ &--large-radius {
54
+ border-radius: var(--avatar-border-radius-lg, 40%);
55
+ }
56
+
57
+ &-image {
58
+ width: 100%;
59
+ height: 100%;
60
+ object-fit: cover;
61
+ border-radius: inherit;
62
+ }
63
+
64
+ &-fallback {
65
+ width: 100%;
66
+ height: 100%;
67
+ cursor: inherit;
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ color: var(--avatar-fallback-color);
72
+ line-height: var(--fallback-line-height, var(--line-height, 1 rem));
73
+ background-color: var(--avatar-fallback-bg-color, var(--avatar-bg-color));
74
+ border-width: var(--avatar-fallback-border-width, var(--avatar-border-width));
75
+ border-color: var(--avatar-fallback-border-color, var(--avatar-border-color));
76
+ border-style: var(--avatar-fallback-border-style, var(--avatar-border-style));
77
+ }
78
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export {default as Avatar, type AvatarProps} from "./Avatar";
@@ -0,0 +1,11 @@
1
+ export enum AvatarSize {
2
+ Small = "small",
3
+ Medium = "medium",
4
+ Large = "large",
5
+ }
6
+
7
+ export enum AvatarRadius {
8
+ Small = "small",
9
+ Medium = "medium",
10
+ Large = "large",
11
+ }
@@ -0,0 +1,36 @@
1
+ import React, {ComponentProps, memo, ReactNode, forwardRef, ForwardRefRenderFunction} from "react";
2
+ import classnames from "classnames";
3
+
4
+ import {cloneOrCreateElement} from "../../utils";
5
+
6
+ import styles from "./base-button.module.scss";
7
+
8
+ export interface BaseButtonProps extends ComponentProps<"button"> {
9
+ after?: ReactNode;
10
+ before?: ReactNode;
11
+ afterClassName?: string;
12
+ beforeClassName?: string;
13
+ childrenClassName?: string;
14
+ }
15
+
16
+ const BaseButton: ForwardRefRenderFunction<HTMLButtonElement, BaseButtonProps> = (props, ref) => {
17
+ const {after, before, children, className, afterClassName, beforeClassName, childrenClassName, ...other} = props;
18
+
19
+ return (
20
+ <button ref={ref} className={classnames(styles["base-button"], className)} {...other}>
21
+ {cloneOrCreateElement(before, {
22
+ className: classnames(styles["base-button__before"], beforeClassName),
23
+ })}
24
+
25
+ {cloneOrCreateElement(children, {
26
+ className: classnames(styles["base-button__children"], childrenClassName),
27
+ })}
28
+
29
+ {cloneOrCreateElement(after, {
30
+ className: classnames(styles["base-button__after"], afterClassName),
31
+ })}
32
+ </button>
33
+ );
34
+ };
35
+
36
+ export default memo(forwardRef(BaseButton));
@@ -0,0 +1,24 @@
1
+ .base-button {
2
+ box-sizing: border-box;
3
+ border: none;
4
+ cursor: pointer;
5
+ position: relative;
6
+ display: inline-flex;
7
+ flex-direction: row;
8
+ align-items: center;
9
+ vertical-align: middle;
10
+ justify-content: center;
11
+ gap: var(--base-button-gap, 8px);
12
+ will-change: background, color, transform;
13
+ transition:
14
+ background var(--transition-speed-sm),
15
+ color var(--transition-speed-sm),
16
+ transform var(--transition-speed-sm);
17
+
18
+ &__after,
19
+ &__before,
20
+ &__children {
21
+ position: relative;
22
+ display: inline;
23
+ }
24
+ }
@@ -0,0 +1 @@
1
+ export {default as BaseButton, type BaseButtonProps} from "./BaseButton";
@@ -0,0 +1,51 @@
1
+ import React, {memo, forwardRef, ForwardRefRenderFunction} from "react";
2
+ import classnames from "classnames";
3
+ import {BaseButton, BaseButtonProps} from "../BaseButton";
4
+
5
+ import {useComponentProps} from "../../providers";
6
+
7
+ import {ButtonColor, ButtonRadius, ButtonSize, ButtonVariant} from "./types";
8
+
9
+ import styles from "./button.module.scss";
10
+
11
+ export interface ButtonProps extends BaseButtonProps {
12
+ variant?: ButtonVariant;
13
+ color?: ButtonColor;
14
+ size?: ButtonSize;
15
+ radius?: ButtonRadius;
16
+ }
17
+
18
+ const Button: ForwardRefRenderFunction<HTMLButtonElement, ButtonProps> = (props, ref) => {
19
+ const {
20
+ variant = ButtonVariant.Contained,
21
+ color,
22
+ size,
23
+ radius,
24
+ childrenClassName,
25
+ className,
26
+ children,
27
+ ...other
28
+ } = {...useComponentProps("button"), ...props};
29
+
30
+ return (
31
+ <BaseButton
32
+ ref={ref}
33
+ {...other}
34
+ className={classnames(
35
+ styles["button"],
36
+ {
37
+ [styles[`button--${variant}`]]: variant,
38
+ [styles[`button--${radius}-radius`]]: radius,
39
+ [styles[`button--${color}-color`]]: color,
40
+ [styles[`button--${size}-size`]]: size,
41
+ },
42
+ className
43
+ )}
44
+ childrenClassName={classnames(styles["button__text"], childrenClassName)}
45
+ >
46
+ {children}
47
+ </BaseButton>
48
+ );
49
+ };
50
+
51
+ export default memo(forwardRef(Button));
@@ -0,0 +1,140 @@
1
+ $root: button;
2
+
3
+ .#{$root} {
4
+ font-family: var(--button-font-family, var(--font-family)), sans-serif;
5
+ font-weight: var(--button-font-weight, 500);
6
+ font-size: var(--button-font-size, var(--font-size, 14px));
7
+ letter-spacing: var(--button-letter-spacing, 0.5px);
8
+ line-height: var(--button-line-height, var(--line-height, 1 rem));
9
+ height: var(--button-height, 34px);
10
+ border-radius: var(--button-border-radius, 10px);
11
+ padding: var(--button-padding, 0 16px);
12
+
13
+ &:active:not(:disabled) {
14
+ transform: scale(var(--button-scale, 0.98));
15
+ }
16
+
17
+ &:disabled {
18
+ opacity: var(--button-disabled-opacity, 0.75);
19
+ cursor: default;
20
+ }
21
+
22
+ // Variants
23
+ &--contained {
24
+ color: var(--button-contained-text-color, var(--bg-primary-color));
25
+ background: var(--button-contained-bg-color, var(--text-primary-color));
26
+
27
+ &.#{$root}--primary-color {
28
+ color: #fff;
29
+ background: var(--primary-color);
30
+ }
31
+
32
+ &.#{$root}--secondary-color {
33
+ color: #fff;
34
+ background: var(--secondary-color);
35
+ }
36
+
37
+ &.#{$root}--accent-color {
38
+ color: #fff;
39
+ background: var(--accent-color);
40
+ }
41
+ }
42
+
43
+ &--outlined {
44
+ color: var(--button-outlined-text-color, var(--text-primary-color));
45
+ border: 1px solid var(--button-outlined-border-color, var(--button-outlined-text-color, var(--text-primary-color)));
46
+ background: none;
47
+
48
+ &:hover {
49
+ background-color: var(--button-outlined-bg-color-hover);
50
+ }
51
+
52
+ &:active {
53
+ background-color: var(--button-outlined-bg-color-active);
54
+ }
55
+
56
+ &.#{$root}--primary-color {
57
+ color: var(--primary-color);
58
+ border-color: var(--button-outlined-border-primary-color);
59
+ }
60
+
61
+ &.#{$root}--secondary-color {
62
+ color: var(--secondary-color);
63
+ border-color: var(--button-outlined-border-secondary-color);
64
+ }
65
+
66
+ &.#{$root}--accent-color {
67
+ color: var(--accent-color);
68
+ border-color: var(--button-outlined-border-accent-color);
69
+ }
70
+ }
71
+
72
+ &--text {
73
+ color: var(--button-text-text-color, var(--text-primary-color));
74
+ background-color: transparent;
75
+
76
+ &:hover {
77
+ color: var(--button-text-text-color-hover, var(--text-secondary-color));
78
+ }
79
+
80
+ &:active {
81
+ color: var(--button-text-text-color-active, var(--text-secondary-color));
82
+ }
83
+
84
+ &.#{$root}--primary-color {
85
+ color: var(--primary-color);
86
+ }
87
+
88
+ &.#{$root}--secondary-color {
89
+ color: var(--secondary-color);
90
+ }
91
+
92
+ &.#{$root}--accent-color {
93
+ color: var(--accent-color);
94
+ }
95
+ }
96
+
97
+ // Sizes
98
+ &--small-size {
99
+ height: var(--button-height-sm, 24px);
100
+ font-size: var(--button-font-size-sm, 12px);
101
+ }
102
+
103
+ &--medium-size {
104
+ height: var(--button-height-md, 44px);
105
+ font-size: var(--button-font-size-sm, 16px);
106
+ }
107
+
108
+ &--large-size {
109
+ height: var(--button-height-lg, 54px);
110
+ min-width: 95px;
111
+ font-size: var(--button-font-size-sm, 18px);
112
+ }
113
+
114
+ //Radius
115
+ &--small-radius {
116
+ border-radius: var(--button-border-radius-sm, 5px);
117
+ }
118
+
119
+ &--medium-radius {
120
+ border-radius: var(--button-border-radius-md, 12px);
121
+ }
122
+
123
+ &--large-radius {
124
+ border-radius: var(--button-border-radius-lg, 15px);
125
+ }
126
+
127
+ &--full-radius {
128
+ border-radius: var(--button-height, 999px);
129
+ }
130
+
131
+ &__text {
132
+ position: relative;
133
+ z-index: 3;
134
+ white-space: nowrap;
135
+ text-overflow: ellipsis;
136
+ overflow: hidden;
137
+ max-width: var(--button-max-width, 160px);
138
+ line-height: initial;
139
+ }
140
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export {default as Button, type ButtonProps} from "./Button";
@@ -0,0 +1,24 @@
1
+ export enum ButtonVariant {
2
+ Contained = "contained",
3
+ Outlined = "outlined",
4
+ Text = "text",
5
+ }
6
+
7
+ export enum ButtonColor {
8
+ Primary = "primary",
9
+ Secondary = "secondary",
10
+ Accent = "accent",
11
+ }
12
+
13
+ export enum ButtonSize {
14
+ Small = "small",
15
+ Medium = "medium",
16
+ Large = "large",
17
+ }
18
+
19
+ export enum ButtonRadius {
20
+ Small = "small",
21
+ Medium = "medium",
22
+ Large = "large",
23
+ Full = "full",
24
+ }
@@ -0,0 +1,58 @@
1
+ import React, {memo, ReactElement, forwardRef, ForwardRefRenderFunction} from "react";
2
+ import classnames from "classnames";
3
+ import {CheckboxProps as CheckboxRootProps, Indicator, Root} from "@radix-ui/react-checkbox";
4
+
5
+ import {useComponentProps} from "../../providers";
6
+
7
+ import {CheckboxVariant, CheckboxSize, CheckboxRadius} from "./types";
8
+
9
+ import styles from "./checkbox.module.scss";
10
+
11
+ export type {CheckedState} from "@radix-ui/react-checkbox";
12
+
13
+ export interface CheckboxProps extends CheckboxRootProps {
14
+ indicatorClassName?: string;
15
+ size?: CheckboxSize;
16
+ radius?: CheckboxRadius;
17
+ variant?: CheckboxVariant;
18
+ checkedIcon?: ReactElement;
19
+ indeterminateIcon?: ReactElement;
20
+ }
21
+
22
+ const Checkbox: ForwardRefRenderFunction<HTMLButtonElement, CheckboxProps> = (props, ref) => {
23
+ const {
24
+ checked,
25
+ size,
26
+ radius,
27
+ variant,
28
+ className,
29
+ indicatorClassName,
30
+ checkedIcon = "✔",
31
+ indeterminateIcon = "―",
32
+ ...other
33
+ } = {...useComponentProps("checkbox"), ...props};
34
+
35
+ return (
36
+ <Root
37
+ ref={ref}
38
+ {...other}
39
+ checked={checked}
40
+ className={classnames(
41
+ styles["checkbox"],
42
+ {
43
+ [styles[`checkbox--${variant}`]]: variant,
44
+ [styles[`checkbox--${radius}-radius`]]: radius,
45
+ [styles[`checkbox--${size}-size`]]: size,
46
+ },
47
+ className
48
+ )}
49
+ >
50
+ <Indicator className={classnames(styles["checkbox__indicator"], indicatorClassName)}>
51
+ {checked === "indeterminate" && indeterminateIcon}
52
+ {checked === true && checkedIcon}
53
+ </Indicator>
54
+ </Root>
55
+ );
56
+ };
57
+
58
+ export default memo(forwardRef(Checkbox));
@@ -0,0 +1,82 @@
1
+ $root: checkbox;
2
+
3
+ .#{$root} {
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ cursor: pointer;
8
+ padding: 2px;
9
+ width: var(--checkbox-size, 18px);
10
+ height: var(--checkbox-size, 18px);
11
+ border-radius: var(--checkbox-border-radius, 4px);
12
+ color: var(--checkbox-color, #333);
13
+ border: var(--checkbox-border-width, 1px) solid var(--checkbox-border-color, #999);
14
+ will-change: background, color;
15
+ transition:
16
+ background var(--transition-speed-sm),
17
+ color var(--transition-speed-sm);
18
+
19
+ &:disabled {
20
+ opacity: var(--checkbox-disabled-opacity, 0.6);
21
+ cursor: default;
22
+ }
23
+
24
+ &:active:not(:disabled) {
25
+ transform: scale(var(--checkbox-scale, 0.98));
26
+ }
27
+
28
+ //Variants
29
+ &--classic {
30
+ color: var(--checkbox-classic-color, white);
31
+ background: var(--checkbox-classic-bg-color);
32
+ border: var(--checkbox-classic-border-width, 1px) solid var(--checkbox-classic-border-color, #999);
33
+
34
+ &[data-state="checked"],
35
+ &[data-state="indeterminate"] {
36
+ background: var(--checkbox-checked-bg-color, var(--primary-color));
37
+ border: none;
38
+ }
39
+ }
40
+
41
+ &--soft {
42
+ color: var(--checkbox-soft-color, white);
43
+ background: var(--checkbox-soft-bg-color, var(--secondary-color));
44
+ border: none;
45
+ }
46
+
47
+ //sizes
48
+ &--small-size {
49
+ width: var(--checkbox-size-sm, 16px);
50
+ height: var(--checkbox-size-sm, 16px);
51
+ }
52
+
53
+ &--medium-size {
54
+ width: var(--checkbox-size-md, 20px);
55
+ height: var(--checkbox-size-md, 20px);
56
+ }
57
+
58
+ &--large-size {
59
+ width: var(--checkbox-size-lg, 22px);
60
+ height: var(--checkbox-size-lg, 22px);
61
+ }
62
+
63
+ //Radius
64
+ &--small-radius {
65
+ border-radius: var(--checkbox-border-radius-sm, 2px);
66
+ }
67
+
68
+ &--large-radius {
69
+ border-radius: var(--checkbox-border-radius-lg, 6px);
70
+ }
71
+
72
+ &__indicator {
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+
77
+ & svg {
78
+ width: 100%;
79
+ height: 100%;
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export {default as Checkbox, type CheckboxProps, type CheckedState} from "./Checkbox";