create-react-scaffold-cli 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.
- package/bin/index.js +34 -0
- package/package.json +15 -0
- package/scripts/createProject.js +30 -0
- package/templates/base/.env +1 -0
- package/templates/base/.husky/pre-commit +1 -0
- package/templates/base/.husky/pre-push +0 -0
- package/templates/base/.prettierrc +8 -0
- package/templates/base/.vscode/extensions.json +8 -0
- package/templates/base/.vscode/settings.json +16 -0
- package/templates/base/eslint.config.js +48 -0
- package/templates/base/index.html +16 -0
- package/templates/base/jsconfig.json +7 -0
- package/templates/base/package.json +64 -0
- package/templates/base/postcss.config.mjs +7 -0
- package/templates/base/readme.md +97 -0
- package/templates/base/src/app/App.jsx +13 -0
- package/templates/base/src/app/Router.jsx +4 -0
- package/templates/base/src/app/app_readme.md +74 -0
- package/templates/base/src/app/index.css +1 -0
- package/templates/base/src/app/main.jsx +10 -0
- package/templates/base/src/app/middlewares/index.js +0 -0
- package/templates/base/src/app/providers/QueryProvider.jsx +75 -0
- package/templates/base/src/app/providers/index.js +1 -0
- package/templates/base/src/features/features_readme.md +102 -0
- package/templates/base/src/features/index.js +0 -0
- package/templates/base/src/features/sample/components/index.js +0 -0
- package/templates/base/src/features/sample/constants/index.js +0 -0
- package/templates/base/src/features/sample/constants/sample.constants.js +0 -0
- package/templates/base/src/features/sample/hooks/index.js +0 -0
- package/templates/base/src/features/sample/pages/index.js +0 -0
- package/templates/base/src/features/sample/sample.assets.js +0 -0
- package/templates/base/src/features/sample/sample.context.js +0 -0
- package/templates/base/src/features/sample/sample.navigations.js +0 -0
- package/templates/base/src/features/sample/sample.queryKeys.js +0 -0
- package/templates/base/src/features/sample/sample.routes.jsx +0 -0
- package/templates/base/src/shared/constants/app.constants.js +4 -0
- package/templates/base/src/shared/constants/assets.constants.js +0 -0
- package/templates/base/src/shared/constants/index.js +0 -0
- package/templates/base/src/shared/contexts/index.js +0 -0
- package/templates/base/src/shared/hooks/index.js +3 -0
- package/templates/base/src/shared/hooks/useBooleanState.js +19 -0
- package/templates/base/src/shared/hooks/useDebounce.js +17 -0
- package/templates/base/src/shared/hooks/useToggleState.js +11 -0
- package/templates/base/src/shared/layouts/index.js +0 -0
- package/templates/base/src/shared/libs/axios.js +6 -0
- package/templates/base/src/shared/libs/cn.js +7 -0
- package/templates/base/src/shared/libs/index.js +2 -0
- package/templates/base/src/shared/shared_readme.md +98 -0
- package/templates/base/src/shared/theme/index.js +1 -0
- package/templates/base/src/shared/theme/theme.js +2138 -0
- package/templates/base/src/shared/ui/Box.jsx +200 -0
- package/templates/base/src/shared/ui/Button.jsx +150 -0
- package/templates/base/src/shared/ui/Checkbox.jsx +112 -0
- package/templates/base/src/shared/ui/DropdownMenu.jsx +152 -0
- package/templates/base/src/shared/ui/Flex.jsx +151 -0
- package/templates/base/src/shared/ui/FlexItem.jsx +96 -0
- package/templates/base/src/shared/ui/FormField.jsx +184 -0
- package/templates/base/src/shared/ui/Grid.jsx +151 -0
- package/templates/base/src/shared/ui/GridItem.jsx +95 -0
- package/templates/base/src/shared/ui/Modal.jsx +43 -0
- package/templates/base/src/shared/ui/Scrollable.jsx +47 -0
- package/templates/base/src/shared/ui/Select.jsx +207 -0
- package/templates/base/src/shared/ui/Sheet.jsx +112 -0
- package/templates/base/src/shared/ui/Text.jsx +122 -0
- package/templates/base/src/shared/ui/Toaster.jsx +31 -0
- package/templates/base/src/shared/ui/index.js +1 -0
- package/templates/base/src/shared/utils/getClassName.js +5 -0
- package/templates/base/src/shared/utils/index.js +4 -0
- package/templates/base/src/shared/utils/memo.js +3 -0
- package/templates/base/src/shared/utils/parser.js +41 -0
- package/templates/base/src/shared/utils/tryCatch.js +13 -0
- package/templates/base/vite.config.js +19 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
marginLookup,
|
|
4
|
+
marginMdLookup,
|
|
5
|
+
marginLgLookup,
|
|
6
|
+
marginXLookup,
|
|
7
|
+
marginXMdLookup,
|
|
8
|
+
marginYLookup,
|
|
9
|
+
marginYMdLookup,
|
|
10
|
+
marginYLgLookup,
|
|
11
|
+
paddingLgLookup,
|
|
12
|
+
paddingLookup,
|
|
13
|
+
paddingMdLookup,
|
|
14
|
+
paddingXLgLookup,
|
|
15
|
+
paddingXLookup,
|
|
16
|
+
paddingXMdLookup,
|
|
17
|
+
paddingYLgLookup,
|
|
18
|
+
paddingYLookup,
|
|
19
|
+
paddingYMdLookup,
|
|
20
|
+
widthLookup,
|
|
21
|
+
widthMdLookup,
|
|
22
|
+
widthLgLookup,
|
|
23
|
+
marginXlLookup,
|
|
24
|
+
marginXXlLookup,
|
|
25
|
+
marginYXlLookup,
|
|
26
|
+
paddingXlLookup,
|
|
27
|
+
paddingXXlLookup,
|
|
28
|
+
paddingYXlLookup,
|
|
29
|
+
marginXlgLookup,
|
|
30
|
+
AnimationLookup,
|
|
31
|
+
AnimationMdLookup,
|
|
32
|
+
AnimationLgLookup,
|
|
33
|
+
AnimationXlLookup,
|
|
34
|
+
radiusLookup,
|
|
35
|
+
radiusMdLookup,
|
|
36
|
+
radiusLgLookup,
|
|
37
|
+
radiusXlLookup,
|
|
38
|
+
paddingY2XlLookup,
|
|
39
|
+
paddingX2XlLookup,
|
|
40
|
+
} from '../theme';
|
|
41
|
+
import { getClassName, memo } from '../utils';
|
|
42
|
+
import { cn } from '../libs';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {'base' | 'md' | 'lg' | 'xl' | '2xl'} Breakpoint
|
|
46
|
+
*
|
|
47
|
+
* @typedef {0
|
|
48
|
+
* | 0.5
|
|
49
|
+
* | 1
|
|
50
|
+
* | 1.5
|
|
51
|
+
* | 2
|
|
52
|
+
* | 2.5
|
|
53
|
+
* | 3
|
|
54
|
+
* | 3.5
|
|
55
|
+
* | 4
|
|
56
|
+
* | 5
|
|
57
|
+
* | 6
|
|
58
|
+
* | 7
|
|
59
|
+
* | 8
|
|
60
|
+
* | 9
|
|
61
|
+
* | 10
|
|
62
|
+
* | 11
|
|
63
|
+
* | 12
|
|
64
|
+
* | 14
|
|
65
|
+
* | 16
|
|
66
|
+
* | 20
|
|
67
|
+
* | 24
|
|
68
|
+
* | 28
|
|
69
|
+
* | 32
|
|
70
|
+
* | 36
|
|
71
|
+
* | 40} Size
|
|
72
|
+
*
|
|
73
|
+
*
|
|
74
|
+
* @typedef {0
|
|
75
|
+
* | 0.5
|
|
76
|
+
* | 1
|
|
77
|
+
* | 1.5
|
|
78
|
+
* | 2
|
|
79
|
+
* | 2.5
|
|
80
|
+
* | 3
|
|
81
|
+
* | 3.5
|
|
82
|
+
* | 4
|
|
83
|
+
* | 5
|
|
84
|
+
* | 6
|
|
85
|
+
* | 7
|
|
86
|
+
* | 8
|
|
87
|
+
* | 9
|
|
88
|
+
* | 10
|
|
89
|
+
* | 11
|
|
90
|
+
* | 12
|
|
91
|
+
* | 14
|
|
92
|
+
* | 16
|
|
93
|
+
* | 20
|
|
94
|
+
* | 24
|
|
95
|
+
* | 28
|
|
96
|
+
* | 32
|
|
97
|
+
* | 36
|
|
98
|
+
* | 40
|
|
99
|
+
* | fit
|
|
100
|
+
* | full
|
|
101
|
+
* | auto} Width
|
|
102
|
+
*
|
|
103
|
+
*
|
|
104
|
+
* @typedef {'sm' | 'rounded' | 'md' | 'lg' | 'xl' | 'full'} Radius
|
|
105
|
+
*
|
|
106
|
+
* @typedef {Size} Margin
|
|
107
|
+
*
|
|
108
|
+
* @typedef {Size} Padding
|
|
109
|
+
*
|
|
110
|
+
* @typedef {'x' | 'y'} Axis
|
|
111
|
+
*
|
|
112
|
+
* @typedef {object} ComponentProps
|
|
113
|
+
* @property {boolean | Record<Breakpoint, boolean>} [hide]
|
|
114
|
+
* @property {boolean | Record<Breakpoint, boolean>} [grow]
|
|
115
|
+
* @property {Margin
|
|
116
|
+
* | Record<Breakpoint, Margin>
|
|
117
|
+
* | Record<Axis, Margin>
|
|
118
|
+
* | Record<Axis, Record<Breakpoint, Margin>>} [margin]
|
|
119
|
+
* @property {Padding
|
|
120
|
+
* | Record<Breakpoint, Padding>
|
|
121
|
+
* | Record<Axis, Padding>
|
|
122
|
+
* | Record<Axis, Record<Breakpoint, Padding>>} [padding]
|
|
123
|
+
* @property {Width | Record<Breakpoint, Width>} [width]
|
|
124
|
+
* @property {Radius} [radius]
|
|
125
|
+
* @property {Animation} [animation]
|
|
126
|
+
* @param {React.ComponentProps<'div'> & ComponentProps} props
|
|
127
|
+
* @returns {JSX.Element}
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
const Component = (
|
|
131
|
+
{ hide, grow, margin, radius, padding, width, animation, className, ...rest },
|
|
132
|
+
ref
|
|
133
|
+
) => {
|
|
134
|
+
return (
|
|
135
|
+
<div
|
|
136
|
+
ref={ref}
|
|
137
|
+
className={cn(
|
|
138
|
+
typeof hide !== 'object' && hide === true ? 'hidden' : hide === false && 'block',
|
|
139
|
+
hide?.base === true ? 'hidden' : hide?.base === false && 'block',
|
|
140
|
+
hide?.md === true ? 'md:hidden' : hide?.md === false && 'md:block',
|
|
141
|
+
hide?.lg === true ? 'lg:hidden' : hide?.lg === false && 'lg:block',
|
|
142
|
+
typeof grow !== 'object' && grow === true ? 'h-full' : grow === false && 'h-auto',
|
|
143
|
+
grow?.base === true ? 'h-full' : grow?.base === false && 'h-auto',
|
|
144
|
+
grow?.md === true ? 'md:h-full' : grow?.md === false && 'md:h-auto',
|
|
145
|
+
grow?.lg === true ? 'lg:h-full' : grow?.lg === false && 'lg:h-auto',
|
|
146
|
+
typeof margin !== 'object' && getClassName(margin, marginLookup),
|
|
147
|
+
getClassName(margin?.base, marginLookup),
|
|
148
|
+
getClassName(margin?.md, marginMdLookup),
|
|
149
|
+
getClassName(margin?.lg, marginLgLookup),
|
|
150
|
+
getClassName(margin?.xl, marginXlLookup),
|
|
151
|
+
typeof margin?.x !== 'object' && getClassName(margin?.x, marginXLookup),
|
|
152
|
+
getClassName(margin?.x?.base, marginXLookup),
|
|
153
|
+
getClassName(margin?.x?.md, marginXMdLookup),
|
|
154
|
+
getClassName(margin?.x?.lg, marginXlgLookup),
|
|
155
|
+
getClassName(margin?.x?.xl, marginXXlLookup),
|
|
156
|
+
typeof margin?.y !== 'object' && getClassName(margin?.y, marginYLookup),
|
|
157
|
+
getClassName(margin?.y?.base, marginYLookup),
|
|
158
|
+
getClassName(margin?.y?.md, marginYMdLookup),
|
|
159
|
+
getClassName(margin?.y?.lg, marginYLgLookup),
|
|
160
|
+
getClassName(margin?.y?.xl, marginYXlLookup),
|
|
161
|
+
typeof padding !== 'object' && getClassName(padding, paddingLookup),
|
|
162
|
+
getClassName(padding?.base, paddingLookup),
|
|
163
|
+
getClassName(padding?.md, paddingMdLookup),
|
|
164
|
+
getClassName(padding?.lg, paddingLgLookup),
|
|
165
|
+
getClassName(padding?.xl, paddingXlLookup),
|
|
166
|
+
getClassName(padding?.['2xl'], paddingXlLookup),
|
|
167
|
+
typeof padding?.x !== 'object' && getClassName(padding?.x, paddingXLookup),
|
|
168
|
+
getClassName(padding?.x?.base, paddingXLookup),
|
|
169
|
+
getClassName(padding?.x?.md, paddingXMdLookup),
|
|
170
|
+
getClassName(padding?.x?.lg, paddingXLgLookup),
|
|
171
|
+
getClassName(padding?.x?.xl, paddingXXlLookup),
|
|
172
|
+
getClassName(padding?.x?.['2xl'], paddingX2XlLookup),
|
|
173
|
+
typeof padding?.y !== 'object' && getClassName(padding?.y, paddingYLookup),
|
|
174
|
+
getClassName(padding?.y?.base, paddingYLookup),
|
|
175
|
+
getClassName(padding?.y?.md, paddingYMdLookup),
|
|
176
|
+
getClassName(padding?.y?.lg, paddingYLgLookup),
|
|
177
|
+
getClassName(padding?.y?.xl, paddingYXlLookup),
|
|
178
|
+
getClassName(padding?.y?.['2xl'], paddingY2XlLookup),
|
|
179
|
+
typeof width !== 'object' && getClassName(width, widthLookup),
|
|
180
|
+
getClassName(width?.base, widthLookup),
|
|
181
|
+
getClassName(width?.md, widthMdLookup),
|
|
182
|
+
getClassName(width?.lg, widthLgLookup),
|
|
183
|
+
typeof font !== 'object' && getClassName(animation, AnimationLookup),
|
|
184
|
+
getClassName(animation?.base, AnimationLookup),
|
|
185
|
+
getClassName(animation?.md, AnimationMdLookup),
|
|
186
|
+
getClassName(animation?.lg, AnimationLgLookup),
|
|
187
|
+
getClassName(animation?.xl, AnimationXlLookup),
|
|
188
|
+
typeof radius !== 'object' && getClassName(radius, radiusLookup),
|
|
189
|
+
getClassName(radius?.base, radiusLookup),
|
|
190
|
+
getClassName(radius?.md, radiusMdLookup),
|
|
191
|
+
getClassName(radius?.lg, radiusLgLookup),
|
|
192
|
+
getClassName(radius?.xl, radiusXlLookup),
|
|
193
|
+
className
|
|
194
|
+
)}
|
|
195
|
+
{...rest}
|
|
196
|
+
/>
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export const Box = memo(React.forwardRef(Component));
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PiSpinnerBold } from 'react-icons/pi';
|
|
3
|
+
import {
|
|
4
|
+
AnimationLookup,
|
|
5
|
+
colorLookup,
|
|
6
|
+
fieldSize2XlLookup,
|
|
7
|
+
fieldSizeLgLookup,
|
|
8
|
+
fieldSizeLookup,
|
|
9
|
+
fieldSizeMdLookup,
|
|
10
|
+
fieldSizeXlLookup,
|
|
11
|
+
fontFamilyLookup,
|
|
12
|
+
fontSize2xlLookup,
|
|
13
|
+
fontSizeLgLookup,
|
|
14
|
+
fontSizeLookup,
|
|
15
|
+
fontSizeMdLookup,
|
|
16
|
+
fontSizeXlLookup,
|
|
17
|
+
fontWeight2xlLookup,
|
|
18
|
+
fontWeightLgLookup,
|
|
19
|
+
fontWeightLookup,
|
|
20
|
+
fontWeightMdLookup,
|
|
21
|
+
fontWeightXlLookup,
|
|
22
|
+
radiusLgLookup,
|
|
23
|
+
radiusLookup,
|
|
24
|
+
radiusMdLookup,
|
|
25
|
+
radiusXlLookup,
|
|
26
|
+
} from '../theme';
|
|
27
|
+
import { getClassName, memo } from '../utils';
|
|
28
|
+
|
|
29
|
+
const variantLookup = {
|
|
30
|
+
primary:
|
|
31
|
+
'text-primary-foreground bg-primary hover:bg-primary/90 disabled:text-primary-foreground/70 disabled:bg-primary/50',
|
|
32
|
+
outline:
|
|
33
|
+
'border text-primary bg-primary-foreground hover:bg-neutral-50 disabled:text-primary/70 disabled:bg-neutral-50/50',
|
|
34
|
+
pill: 'text-primary-foreground bg-primary hover:bg-primary/90 disabled:text-primary-foreground/70 disabled:bg-primary/50 rounded-lg',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @typedef {'base' | 'md' | 'lg' | 'xl' | '2xl'} Breakpoint
|
|
39
|
+
*
|
|
40
|
+
* @typedef {'primary' | 'outline' | 'pill'} Variant
|
|
41
|
+
*
|
|
42
|
+
* @typedef {'xxxs' | 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'} Size
|
|
43
|
+
*
|
|
44
|
+
* @typedef {''} Font
|
|
45
|
+
*
|
|
46
|
+
* @typedef {'primary' | 'secondary' | 'success' | 'danger' | 'white' | 'black'} Color
|
|
47
|
+
*
|
|
48
|
+
* @typedef {'sm' | 'rounded' | 'md' | 'lg' | 'xl' | 'full'} Radius
|
|
49
|
+
*
|
|
50
|
+
* @typedef {'thin'
|
|
51
|
+
* | 'extralight'
|
|
52
|
+
* | 'light'
|
|
53
|
+
* | 'normal'
|
|
54
|
+
* | 'medium'
|
|
55
|
+
* | 'semibold'
|
|
56
|
+
* | 'bold'
|
|
57
|
+
* | 'extrabold'
|
|
58
|
+
* | 'black'} Weight
|
|
59
|
+
*
|
|
60
|
+
*
|
|
61
|
+
* @typedef {'xs'
|
|
62
|
+
* | 'sm'
|
|
63
|
+
* | 'base'
|
|
64
|
+
* | 'lg'
|
|
65
|
+
* | 'xl'
|
|
66
|
+
* | '2xl'
|
|
67
|
+
* | '3xl'
|
|
68
|
+
* | '4xl'
|
|
69
|
+
* | '5xl'
|
|
70
|
+
* | '6xl'
|
|
71
|
+
* | '7xl'
|
|
72
|
+
* | '8xl'
|
|
73
|
+
* | '9xl'} fontSize
|
|
74
|
+
*
|
|
75
|
+
*
|
|
76
|
+
* @typedef {object} ComponentProps
|
|
77
|
+
* @property {Variant} [variant]
|
|
78
|
+
* @property {Radius} [radius]
|
|
79
|
+
* @property {Size} [size]
|
|
80
|
+
* @property {Font} [font]
|
|
81
|
+
* @property {fontSize} [fontSize]
|
|
82
|
+
* @property {Weight} [weight]
|
|
83
|
+
* @property {boolean} [isLoading]
|
|
84
|
+
* @property {Color} [color]
|
|
85
|
+
* @param {React.ComponentProps<'button'> & ComponentProps} props
|
|
86
|
+
* @returns {JSX.Element}
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
const Component = (
|
|
90
|
+
{
|
|
91
|
+
variant = 'primary',
|
|
92
|
+
radius = 'lg',
|
|
93
|
+
size = 'lg',
|
|
94
|
+
font = 'inter',
|
|
95
|
+
fontSize = 'base',
|
|
96
|
+
weight = 'semibold',
|
|
97
|
+
color,
|
|
98
|
+
isLoading,
|
|
99
|
+
className,
|
|
100
|
+
animation,
|
|
101
|
+
type = 'button',
|
|
102
|
+
children,
|
|
103
|
+
...rest
|
|
104
|
+
},
|
|
105
|
+
ref
|
|
106
|
+
) => {
|
|
107
|
+
return (
|
|
108
|
+
<button
|
|
109
|
+
ref={ref}
|
|
110
|
+
className={cn(
|
|
111
|
+
'h-12 px-4 w-full rounded-lg text-base font-inter font-semibold disabled:cursor-not-allowed transition-colors flex justify-center items-center',
|
|
112
|
+
typeof fontSize !== 'object' && getClassName(fontSize, fontSizeLookup),
|
|
113
|
+
getClassName(fontSize?.base, fontSizeLookup),
|
|
114
|
+
getClassName(fontSize?.md, fontSizeMdLookup),
|
|
115
|
+
getClassName(fontSize?.lg, fontSizeLgLookup),
|
|
116
|
+
getClassName(fontSize?.xl, fontSizeXlLookup),
|
|
117
|
+
getClassName(fontSize?.['2xl'], fontSize2xlLookup),
|
|
118
|
+
typeof weight !== 'object' && getClassName(weight, fontWeightLookup),
|
|
119
|
+
getClassName(weight?.base, fontWeightLookup),
|
|
120
|
+
getClassName(weight?.md, fontWeightMdLookup),
|
|
121
|
+
getClassName(weight?.lg, fontWeightLgLookup),
|
|
122
|
+
getClassName(weight?.xl, fontWeightXlLookup),
|
|
123
|
+
getClassName(weight?.['2xl'], fontWeight2xlLookup),
|
|
124
|
+
typeof size !== 'object' && getClassName(size, fieldSizeLookup),
|
|
125
|
+
getClassName(size?.base, fieldSizeLookup),
|
|
126
|
+
getClassName(size?.md, fieldSizeMdLookup),
|
|
127
|
+
getClassName(size?.lg, fieldSizeLgLookup),
|
|
128
|
+
getClassName(size?.xl, fieldSizeXlLookup),
|
|
129
|
+
getClassName(size?.['2xl'], fieldSize2XlLookup),
|
|
130
|
+
typeof radius !== 'object' && getClassName(radius, radiusLookup),
|
|
131
|
+
getClassName(radius?.base, radiusLookup),
|
|
132
|
+
getClassName(radius?.md, radiusMdLookup),
|
|
133
|
+
getClassName(radius?.lg, radiusLgLookup),
|
|
134
|
+
getClassName(radius?.xl, radiusXlLookup),
|
|
135
|
+
variantLookup[variant],
|
|
136
|
+
fontFamilyLookup[font],
|
|
137
|
+
colorLookup[color],
|
|
138
|
+
AnimationLookup[animation],
|
|
139
|
+
className
|
|
140
|
+
)}
|
|
141
|
+
type={type}
|
|
142
|
+
{...(isLoading && { disabled: true })}
|
|
143
|
+
{...rest}
|
|
144
|
+
>
|
|
145
|
+
{isLoading ? <PiSpinnerBold className="animate-spin size-5 m-auto" /> : children}
|
|
146
|
+
</button>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export const Button = memo(React.forwardRef(Component));
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
sizeLookup,
|
|
4
|
+
sizeMdLookup,
|
|
5
|
+
sizeLgLookup,
|
|
6
|
+
fontSizeLookup,
|
|
7
|
+
fontSizeMdLookup,
|
|
8
|
+
fontSizeLgLookup,
|
|
9
|
+
fontWeightLookup,
|
|
10
|
+
fontWeightMdLookup,
|
|
11
|
+
fontWeightLgLookup,
|
|
12
|
+
} from '../theme';
|
|
13
|
+
import { getClassName, memo } from '../utils';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
*
|
|
18
|
+
* @typedef {'base' | 'md' | 'lg'} Breakpoint
|
|
19
|
+
*
|
|
20
|
+
* @typedef {0 | 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 3.5 | 4 | 5 | 6 | 7 | 8} Size
|
|
21
|
+
*
|
|
22
|
+
* @typedef {'xs'
|
|
23
|
+
* | 'sm'
|
|
24
|
+
* | 'base'
|
|
25
|
+
* | 'lg'
|
|
26
|
+
* | 'xl'
|
|
27
|
+
* | '2xl'
|
|
28
|
+
* | '3xl'
|
|
29
|
+
* | '4xl'
|
|
30
|
+
* | '5xl'
|
|
31
|
+
* | '6xl'
|
|
32
|
+
* | '7xl'
|
|
33
|
+
* | '8xl'
|
|
34
|
+
* | '9xl'} LabelFontSize
|
|
35
|
+
*
|
|
36
|
+
*
|
|
37
|
+
* @typedef {'thin'
|
|
38
|
+
* | 'extralight'
|
|
39
|
+
* | 'light'
|
|
40
|
+
* | 'normal'
|
|
41
|
+
* | 'medium'
|
|
42
|
+
* | 'semibold'
|
|
43
|
+
* | 'bold'
|
|
44
|
+
* | 'extrabold'
|
|
45
|
+
* | 'black'} LabelFontWeight
|
|
46
|
+
*
|
|
47
|
+
*
|
|
48
|
+
* @typedef {object} ComponentProps
|
|
49
|
+
* @property {Size | Record<Breakpoint, Size>} [size]
|
|
50
|
+
*
|
|
51
|
+
* - @property {LabelFontSize | Record<Breakpoint, LabelFontSize>} [labelFontSize]
|
|
52
|
+
*
|
|
53
|
+
* @property {LabelFontWeight | Record<Breakpoint, LabelFontWeight>} [labelFontWeight]
|
|
54
|
+
* @param {React.ComponentProps<'input'> & ComponentProps} props
|
|
55
|
+
* @returns {JSX.Element}
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
const Component = ({
|
|
59
|
+
label,
|
|
60
|
+
disabled = false,
|
|
61
|
+
className = '',
|
|
62
|
+
labelClass,
|
|
63
|
+
checkClass,
|
|
64
|
+
onChange,
|
|
65
|
+
size = { base: 4, md: 5 },
|
|
66
|
+
labelFontSize = { base: 'xs', md: 'sm', lg: 'base' },
|
|
67
|
+
labelFontWeight,
|
|
68
|
+
...rest
|
|
69
|
+
}) => {
|
|
70
|
+
const id = React.useId();
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div className={cn('flex items-center gap-2', className)}>
|
|
74
|
+
<input
|
|
75
|
+
type="checkbox"
|
|
76
|
+
disabled={disabled}
|
|
77
|
+
onChange={onChange}
|
|
78
|
+
className={cn(
|
|
79
|
+
' border border-tertiary checked:bg-primary accent-primary transition-colors duration-200',
|
|
80
|
+
typeof size !== 'object' && getClassName(size, sizeLookup),
|
|
81
|
+
disabled && 'cursor-not-allowed bg-opacity-60',
|
|
82
|
+
getClassName(size?.base, sizeLookup),
|
|
83
|
+
getClassName(size?.md, sizeMdLookup),
|
|
84
|
+
getClassName(size?.lg, sizeLgLookup),
|
|
85
|
+
checkClass
|
|
86
|
+
)}
|
|
87
|
+
id={id}
|
|
88
|
+
{...rest}
|
|
89
|
+
/>
|
|
90
|
+
<label
|
|
91
|
+
htmlFor={id}
|
|
92
|
+
className={cn(
|
|
93
|
+
'text-secondary font-inter',
|
|
94
|
+
disabled && 'opacity-50 cursor-not-allowed',
|
|
95
|
+
typeof labelFontSize !== 'object' && getClassName(labelFontSize, fontSizeLookup),
|
|
96
|
+
getClassName(labelFontSize?.base, fontSizeLookup),
|
|
97
|
+
getClassName(labelFontSize?.md, fontSizeMdLookup),
|
|
98
|
+
getClassName(labelFontSize?.lg, fontSizeLgLookup),
|
|
99
|
+
typeof labelFontWeight !== 'object' && getClassName(labelFontWeight, fontWeightLookup),
|
|
100
|
+
getClassName(labelFontWeight?.base, fontWeightLookup),
|
|
101
|
+
getClassName(labelFontWeight?.md, fontWeightMdLookup),
|
|
102
|
+
getClassName(labelFontWeight?.lg, fontWeightLgLookup),
|
|
103
|
+
labelClass
|
|
104
|
+
)}
|
|
105
|
+
>
|
|
106
|
+
{label}
|
|
107
|
+
</label>
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const Checkbox = memo(Component);
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
3
|
+
import { FaChevronRight } from 'react-icons/fa';
|
|
4
|
+
import { memo } from '@/utils';
|
|
5
|
+
import { cn } from '@/libs';
|
|
6
|
+
|
|
7
|
+
const DropdownMenuRoot = DropdownMenuPrimitive.Root;
|
|
8
|
+
|
|
9
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
10
|
+
|
|
11
|
+
const DropdownMenuSubTrigger = React.forwardRef(
|
|
12
|
+
({ className, inset, children, ...props }, ref) => (
|
|
13
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={cn(
|
|
16
|
+
'flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
|
17
|
+
inset && 'pl-8',
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
<FaChevronRight className="ml-auto" />
|
|
24
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
DropdownMenuSubTrigger.displayName =
|
|
28
|
+
DropdownMenuPrimitive.SubTrigger.displayName;
|
|
29
|
+
|
|
30
|
+
const DropdownMenuSubContent = React.forwardRef(
|
|
31
|
+
({ className, ...props }, ref) => (
|
|
32
|
+
<DropdownMenuPrimitive.SubContent
|
|
33
|
+
ref={ref}
|
|
34
|
+
className={cn(
|
|
35
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
36
|
+
className
|
|
37
|
+
)}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
)
|
|
41
|
+
);
|
|
42
|
+
DropdownMenuSubContent.displayName =
|
|
43
|
+
DropdownMenuPrimitive.SubContent.displayName;
|
|
44
|
+
|
|
45
|
+
const DropdownMenuContent = React.forwardRef(
|
|
46
|
+
({ className, sideOffset = 4, contentClassName, ...props }, ref) => (
|
|
47
|
+
<DropdownMenuPrimitive.Portal>
|
|
48
|
+
<DropdownMenuPrimitive.Content
|
|
49
|
+
ref={ref}
|
|
50
|
+
sideOffset={sideOffset}
|
|
51
|
+
className={cn(
|
|
52
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-lg border bg-popover p-1 text-popover-foreground shadow',
|
|
53
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
54
|
+
className,
|
|
55
|
+
contentClassName
|
|
56
|
+
)}
|
|
57
|
+
{...props}
|
|
58
|
+
/>
|
|
59
|
+
</DropdownMenuPrimitive.Portal>
|
|
60
|
+
)
|
|
61
|
+
);
|
|
62
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
63
|
+
|
|
64
|
+
const DropdownMenuItem = React.forwardRef(
|
|
65
|
+
({ className, inset, ...props }, ref) => (
|
|
66
|
+
<DropdownMenuPrimitive.Item
|
|
67
|
+
ref={ref}
|
|
68
|
+
className={cn(
|
|
69
|
+
'relative flex select-none items-center gap-2 font-inter cursor-pointer rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0',
|
|
70
|
+
inset && 'pl-8',
|
|
71
|
+
className
|
|
72
|
+
)}
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
78
|
+
|
|
79
|
+
const DropdownMenuLabel = React.forwardRef(
|
|
80
|
+
({ className, inset, ...props }, ref) => (
|
|
81
|
+
<DropdownMenuPrimitive.Label
|
|
82
|
+
ref={ref}
|
|
83
|
+
className={cn(
|
|
84
|
+
'px-2 py-1.5 text-sm font-semibold font-inter',
|
|
85
|
+
inset && 'pl-8',
|
|
86
|
+
className
|
|
87
|
+
)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
93
|
+
|
|
94
|
+
const DropdownMenuSeparator = React.forwardRef(
|
|
95
|
+
({ className, ...props }, ref) => (
|
|
96
|
+
<DropdownMenuPrimitive.Separator
|
|
97
|
+
ref={ref}
|
|
98
|
+
className={cn('-mx-1 my-1 h-px bg-muted', className)}
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
104
|
+
|
|
105
|
+
const DropdownMenuShortcut = ({ className, ...props }) => {
|
|
106
|
+
return (
|
|
107
|
+
<span
|
|
108
|
+
className={cn('ml-auto text-xs tracking-widest opacity-60', className)}
|
|
109
|
+
{...props}
|
|
110
|
+
/>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
DropdownMenuShortcut.displayName = 'DropdownMenuShortcut';
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @typedef {object} ComponentProps
|
|
117
|
+
* @property {boolean} [open]
|
|
118
|
+
* @property {(open: boolean) => void} [onOpenChange]
|
|
119
|
+
* @property {React.ReactNode} content
|
|
120
|
+
* @param {React.PropsWithChildren<ComponentProps>} props
|
|
121
|
+
* @returns {JSX.Element}
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
const Component = ({
|
|
125
|
+
open,
|
|
126
|
+
onOpenChange,
|
|
127
|
+
content,
|
|
128
|
+
children,
|
|
129
|
+
contentClassName,
|
|
130
|
+
}) => {
|
|
131
|
+
return (
|
|
132
|
+
<DropdownMenuRoot
|
|
133
|
+
className="border w-full "
|
|
134
|
+
open={open}
|
|
135
|
+
onOpenChange={onOpenChange}
|
|
136
|
+
>
|
|
137
|
+
<DropdownMenuTrigger className="w-full">{children}</DropdownMenuTrigger>
|
|
138
|
+
<DropdownMenuContent align="end" contentClassName={contentClassName}>
|
|
139
|
+
{content}
|
|
140
|
+
</DropdownMenuContent>
|
|
141
|
+
</DropdownMenuRoot>
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const DropdownMenu = memo(Component);
|
|
146
|
+
|
|
147
|
+
export {
|
|
148
|
+
DropdownMenu,
|
|
149
|
+
DropdownMenuLabel,
|
|
150
|
+
DropdownMenuSeparator,
|
|
151
|
+
DropdownMenuItem,
|
|
152
|
+
};
|