@umituz/web-design-system 1.3.1 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -2
- package/src/presentation/molecules/Avatar.tsx +47 -19
- package/src/presentation/molecules/Select.tsx +152 -33
- package/src/presentation/molecules/index.ts +3 -3
- package/src/presentation/organisms/Accordion.tsx +53 -111
- package/src/presentation/organisms/Alert.tsx +52 -85
- package/src/presentation/organisms/index.ts +3 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/web-design-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Web Design System - Atomic Design components (Atoms, Molecules, Organisms, Templates) for React applications",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -52,15 +52,20 @@
|
|
|
52
52
|
"url": "git+https://github.com/umituz/web-design-system.git"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
+
"@radix-ui/react-accordion": ">=1.0.0",
|
|
56
|
+
"@radix-ui/react-select": ">=2.0.0",
|
|
57
|
+
"clsx": ">=2.0.0",
|
|
55
58
|
"react": ">=18.0.0",
|
|
56
59
|
"react-dom": ">=18.0.0",
|
|
57
|
-
"clsx": ">=2.0.0",
|
|
58
60
|
"tailwind-merge": ">=2.0.0"
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
63
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
64
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
61
65
|
"@types/react": "^18.0.0",
|
|
62
66
|
"@types/react-dom": "^18.0.0",
|
|
63
67
|
"clsx": "^2.1.1",
|
|
68
|
+
"lucide-react": "^0.577.0",
|
|
64
69
|
"react": "^18.0.0",
|
|
65
70
|
"react-dom": "^18.0.0",
|
|
66
71
|
"tailwind-merge": "^3.5.0",
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Avatar Component (Molecule)
|
|
3
|
-
* @description User avatar with fallback
|
|
3
|
+
* @description User avatar with image and fallback (shadcn/ui compatible)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { forwardRef, type HTMLAttributes } from 'react';
|
|
6
|
+
import { forwardRef, type HTMLAttributes, type ElementType, type ComponentPropsWithoutRef } from 'react';
|
|
7
7
|
import { cn } from '../../infrastructure/utils';
|
|
8
8
|
import type { BaseProps, SizeVariant } from '../../domain/types';
|
|
9
9
|
|
|
10
10
|
export interface AvatarProps extends HTMLAttributes<HTMLDivElement>, BaseProps {
|
|
11
|
-
src?: string;
|
|
12
|
-
alt?: string;
|
|
13
|
-
fallback?: string;
|
|
14
11
|
size?: Extract<SizeVariant, 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'>;
|
|
15
12
|
}
|
|
16
13
|
|
|
@@ -23,30 +20,61 @@ const sizeStyles: Record<'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl', string> = {
|
|
|
23
20
|
'2xl': 'h-20 w-20 text-2xl',
|
|
24
21
|
};
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
({ className,
|
|
28
|
-
const hasError = !src;
|
|
29
|
-
|
|
23
|
+
const Avatar = forwardRef<HTMLDivElement, AvatarProps>(
|
|
24
|
+
({ className, size = 'md', ...props }, ref) => {
|
|
30
25
|
return (
|
|
31
26
|
<div
|
|
32
27
|
ref={ref}
|
|
33
28
|
className={cn(
|
|
34
|
-
'relative
|
|
29
|
+
'relative flex shrink-0 overflow-hidden rounded-full',
|
|
35
30
|
sizeStyles[size],
|
|
36
31
|
className
|
|
37
32
|
)}
|
|
38
33
|
{...props}
|
|
39
|
-
|
|
40
|
-
{hasError ? (
|
|
41
|
-
<span className="font-medium text-muted-foreground">
|
|
42
|
-
{fallback || '?'}
|
|
43
|
-
</span>
|
|
44
|
-
) : (
|
|
45
|
-
<img src={src} alt={alt || 'Avatar'} className="h-full w-full object-cover" />
|
|
46
|
-
)}
|
|
47
|
-
</div>
|
|
34
|
+
/>
|
|
48
35
|
);
|
|
49
36
|
}
|
|
50
37
|
);
|
|
51
38
|
|
|
52
39
|
Avatar.displayName = 'Avatar';
|
|
40
|
+
|
|
41
|
+
export interface AvatarImageProps extends ComponentPropsWithoutRef<'img'> {
|
|
42
|
+
asChild?: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const AvatarImage = forwardRef<HTMLImageElement, AvatarImageProps>(
|
|
46
|
+
({ className, src, alt, ...props }, ref) => {
|
|
47
|
+
return (
|
|
48
|
+
<img
|
|
49
|
+
ref={ref}
|
|
50
|
+
src={src}
|
|
51
|
+
alt={alt}
|
|
52
|
+
className={cn('aspect-square h-full w-full object-cover', className)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
AvatarImage.displayName = 'AvatarImage';
|
|
60
|
+
|
|
61
|
+
export interface AvatarFallbackProps extends HTMLAttributes<HTMLDivElement> {}
|
|
62
|
+
|
|
63
|
+
const AvatarFallback = forwardRef<HTMLDivElement, AvatarFallbackProps>(
|
|
64
|
+
({ className, ...props }, ref) => {
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
ref={ref}
|
|
68
|
+
className={cn(
|
|
69
|
+
'flex h-full w-full items-center justify-center rounded-full bg-muted',
|
|
70
|
+
className
|
|
71
|
+
)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
AvatarFallback.displayName = 'AvatarFallback';
|
|
79
|
+
|
|
80
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
@@ -1,41 +1,160 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Select Component (Molecule)
|
|
3
|
-
* @description Dropdown select
|
|
3
|
+
* @description Dropdown select (Shadcn/Radix UI compatible)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
8
|
+
import { Check, ChevronDown, ChevronUp } from 'lucide-react';
|
|
7
9
|
import { cn } from '../../infrastructure/utils';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
|
|
11
|
+
const Select = SelectPrimitive.Root;
|
|
12
|
+
|
|
13
|
+
const SelectGroup = SelectPrimitive.Group;
|
|
14
|
+
|
|
15
|
+
const SelectValue = SelectPrimitive.Value;
|
|
16
|
+
|
|
17
|
+
const SelectTrigger = React.forwardRef<
|
|
18
|
+
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
|
19
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
|
20
|
+
>(({ className, children, ...props }, ref) => (
|
|
21
|
+
<SelectPrimitive.Trigger
|
|
22
|
+
ref={ref}
|
|
23
|
+
className={cn(
|
|
24
|
+
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
|
25
|
+
className
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
{children}
|
|
30
|
+
<SelectPrimitive.Icon asChild>
|
|
31
|
+
<ChevronDown className="h-4 w-4 opacity-50" />
|
|
32
|
+
</SelectPrimitive.Icon>
|
|
33
|
+
</SelectPrimitive.Trigger>
|
|
34
|
+
));
|
|
35
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
36
|
+
|
|
37
|
+
const SelectScrollUpButton = React.forwardRef<
|
|
38
|
+
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
|
|
39
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
|
|
40
|
+
>(({ className, ...props }, ref) => (
|
|
41
|
+
<SelectPrimitive.ScrollUpButton
|
|
42
|
+
ref={ref}
|
|
43
|
+
className={cn(
|
|
44
|
+
'flex cursor-default items-center justify-center py-1',
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
<ChevronUp className="h-4 w-4" />
|
|
50
|
+
</SelectPrimitive.ScrollUpButton>
|
|
51
|
+
));
|
|
52
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
53
|
+
|
|
54
|
+
const SelectScrollDownButton = React.forwardRef<
|
|
55
|
+
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
|
|
56
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
|
|
57
|
+
>(({ className, ...props }, ref) => (
|
|
58
|
+
<SelectPrimitive.ScrollDownButton
|
|
59
|
+
ref={ref}
|
|
60
|
+
className={cn(
|
|
61
|
+
'flex cursor-default items-center justify-center py-1',
|
|
62
|
+
className
|
|
63
|
+
)}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
<ChevronDown className="h-4 w-4" />
|
|
67
|
+
</SelectPrimitive.ScrollDownButton>
|
|
68
|
+
));
|
|
69
|
+
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
70
|
+
|
|
71
|
+
const SelectContent = React.forwardRef<
|
|
72
|
+
React.ElementRef<typeof SelectPrimitive.Content>,
|
|
73
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
|
74
|
+
>(({ className, children, position = 'popper', ...props }, ref) => (
|
|
75
|
+
<SelectPrimitive.Portal>
|
|
76
|
+
<SelectPrimitive.Content
|
|
77
|
+
ref={ref}
|
|
78
|
+
className={cn(
|
|
79
|
+
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md 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',
|
|
80
|
+
position === 'popper' &&
|
|
81
|
+
'data-[side=bottom]:translate-y-1 data-[side=left]:translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:translate-y-1',
|
|
82
|
+
className
|
|
83
|
+
)}
|
|
84
|
+
position={position}
|
|
85
|
+
{...props}
|
|
86
|
+
>
|
|
87
|
+
<SelectScrollUpButton />
|
|
88
|
+
<SelectPrimitive.Viewport
|
|
21
89
|
className={cn(
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
|
|
25
|
-
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
26
|
-
error && 'border-destructive',
|
|
27
|
-
className
|
|
90
|
+
'p-1',
|
|
91
|
+
position === 'popper' &&
|
|
92
|
+
'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'
|
|
28
93
|
)}
|
|
29
|
-
{...props}
|
|
30
94
|
>
|
|
31
|
-
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
95
|
+
{children}
|
|
96
|
+
</SelectPrimitive.Viewport>
|
|
97
|
+
<SelectScrollDownButton />
|
|
98
|
+
</SelectPrimitive.Content>
|
|
99
|
+
</SelectPrimitive.Portal>
|
|
100
|
+
));
|
|
101
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
102
|
+
|
|
103
|
+
const SelectLabel = React.forwardRef<
|
|
104
|
+
React.ElementRef<typeof SelectPrimitive.Label>,
|
|
105
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
|
106
|
+
>(({ className, ...props }, ref) => (
|
|
107
|
+
<SelectPrimitive.Label
|
|
108
|
+
ref={ref}
|
|
109
|
+
className={cn('py-1.5 pl-8 pr-2 text-sm font-semibold', className)}
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
));
|
|
113
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
114
|
+
|
|
115
|
+
const SelectItem = React.forwardRef<
|
|
116
|
+
React.ElementRef<typeof SelectPrimitive.Item>,
|
|
117
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
|
118
|
+
>(({ className, children, ...props }, ref) => (
|
|
119
|
+
<SelectPrimitive.Item
|
|
120
|
+
ref={ref}
|
|
121
|
+
className={cn(
|
|
122
|
+
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
123
|
+
className
|
|
124
|
+
)}
|
|
125
|
+
{...props}
|
|
126
|
+
>
|
|
127
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
128
|
+
<SelectPrimitive.ItemIndicator>
|
|
129
|
+
<Check className="h-4 w-4" />
|
|
130
|
+
</SelectPrimitive.ItemIndicator>
|
|
131
|
+
</span>
|
|
132
|
+
{children}
|
|
133
|
+
</SelectPrimitive.Item>
|
|
134
|
+
));
|
|
135
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
136
|
+
|
|
137
|
+
const SelectSeparator = React.forwardRef<
|
|
138
|
+
React.ElementRef<typeof SelectPrimitive.Separator>,
|
|
139
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
|
140
|
+
>(({ className, ...props }, ref) => (
|
|
141
|
+
<SelectPrimitive.Separator
|
|
142
|
+
ref={ref}
|
|
143
|
+
className={cn('-mx-1 my-1 h-px bg-muted', className)}
|
|
144
|
+
{...props}
|
|
145
|
+
/>
|
|
146
|
+
));
|
|
147
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
148
|
+
|
|
149
|
+
export {
|
|
150
|
+
Select,
|
|
151
|
+
SelectGroup,
|
|
152
|
+
SelectValue,
|
|
153
|
+
SelectTrigger,
|
|
154
|
+
SelectContent,
|
|
155
|
+
SelectLabel,
|
|
156
|
+
SelectItem,
|
|
157
|
+
SelectSeparator,
|
|
158
|
+
SelectScrollUpButton,
|
|
159
|
+
SelectScrollDownButton,
|
|
160
|
+
};
|
|
@@ -10,8 +10,8 @@ export type { FormFieldProps } from './FormField';
|
|
|
10
10
|
export { SearchBox } from './SearchBox';
|
|
11
11
|
export type { SearchBoxProps } from './SearchBox';
|
|
12
12
|
|
|
13
|
-
export { Avatar } from './Avatar';
|
|
14
|
-
export type { AvatarProps } from './Avatar';
|
|
13
|
+
export { Avatar, AvatarImage, AvatarFallback } from './Avatar';
|
|
14
|
+
export type { AvatarProps, AvatarImageProps, AvatarFallbackProps } from './Avatar';
|
|
15
15
|
|
|
16
16
|
export { Chip } from './Chip';
|
|
17
17
|
export type { ChipProps } from './Chip';
|
|
@@ -19,7 +19,7 @@ export type { ChipProps } from './Chip';
|
|
|
19
19
|
export { Toggle } from './Toggle';
|
|
20
20
|
export type { ToggleProps } from './Toggle';
|
|
21
21
|
|
|
22
|
-
export { Select } from './Select';
|
|
22
|
+
export { Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton } from './Select';
|
|
23
23
|
export type { SelectProps } from './Select';
|
|
24
24
|
|
|
25
25
|
export { Textarea } from './Textarea';
|
|
@@ -1,117 +1,59 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Accordion Component (Organism)
|
|
3
|
-
* @description Collapsible content sections
|
|
3
|
+
* @description Collapsible content sections (Shadcn/ui compatible)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
8
|
+
import { ChevronDown } from 'lucide-react';
|
|
7
9
|
import { cn } from '../../infrastructure/utils';
|
|
8
|
-
import type { BaseProps } from '../../domain/types';
|
|
9
|
-
import { Icon } from '../atoms/Icon';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<div
|
|
62
|
-
key={item.value}
|
|
63
|
-
className={cn(
|
|
64
|
-
'group',
|
|
65
|
-
variantStyles[variant],
|
|
66
|
-
variant === 'bordered' && isOpen && 'ring-1 ring-ring'
|
|
67
|
-
)}
|
|
68
|
-
>
|
|
69
|
-
{/* Header */}
|
|
70
|
-
<button
|
|
71
|
-
onClick={() => toggleItem(item.value)}
|
|
72
|
-
disabled={item.disabled}
|
|
73
|
-
className={cn(
|
|
74
|
-
'flex w-full items-center justify-between py-4 font-medium transition-all',
|
|
75
|
-
'hover:text-foreground',
|
|
76
|
-
item.disabled && 'opacity-50 cursor-not-allowed',
|
|
77
|
-
variant === 'bordered' && 'px-4'
|
|
78
|
-
)}
|
|
79
|
-
>
|
|
80
|
-
<span>{item.title}</span>
|
|
81
|
-
<Icon
|
|
82
|
-
className={cn(
|
|
83
|
-
'transition-transform duration-200',
|
|
84
|
-
isOpen && 'rotate-180'
|
|
85
|
-
)}
|
|
86
|
-
size="sm"
|
|
87
|
-
>
|
|
88
|
-
<path
|
|
89
|
-
strokeLinecap="round"
|
|
90
|
-
strokeLinejoin="round"
|
|
91
|
-
d="M19.5 8.25l-7.5 7.5-7.5-7.5"
|
|
92
|
-
/>
|
|
93
|
-
</Icon>
|
|
94
|
-
</button>
|
|
95
|
-
|
|
96
|
-
{/* Content */}
|
|
97
|
-
{isOpen && (
|
|
98
|
-
<div
|
|
99
|
-
className={cn(
|
|
100
|
-
'overflow-hidden',
|
|
101
|
-
'animate-accordion-down',
|
|
102
|
-
variant === 'bordered' && 'px-4 pb-4'
|
|
103
|
-
)}
|
|
104
|
-
>
|
|
105
|
-
<div className="pb-4 text-sm text-muted-foreground">
|
|
106
|
-
{item.content}
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
)}
|
|
110
|
-
</div>
|
|
111
|
-
);
|
|
112
|
-
})}
|
|
113
|
-
</div>
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
Accordion.displayName = 'Accordion';
|
|
11
|
+
const Accordion = AccordionPrimitive.Root;
|
|
12
|
+
|
|
13
|
+
const AccordionItem = React.forwardRef<
|
|
14
|
+
React.ElementRef<typeof AccordionPrimitive.Item>,
|
|
15
|
+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
|
16
|
+
>(({ className, ...props }, ref) => (
|
|
17
|
+
<AccordionPrimitive.Item
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn('border-b', className)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
));
|
|
23
|
+
AccordionItem.displayName = 'AccordionItem';
|
|
24
|
+
|
|
25
|
+
const AccordionTrigger = React.forwardRef<
|
|
26
|
+
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
|
27
|
+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
|
|
28
|
+
>(({ className, children, ...props }, ref) => (
|
|
29
|
+
<AccordionPrimitive.Header className="flex">
|
|
30
|
+
<AccordionPrimitive.Trigger
|
|
31
|
+
ref={ref}
|
|
32
|
+
className={cn(
|
|
33
|
+
'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
|
|
34
|
+
className
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
>
|
|
38
|
+
{children}
|
|
39
|
+
<ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
|
|
40
|
+
</AccordionPrimitive.Trigger>
|
|
41
|
+
</AccordionPrimitive.Header>
|
|
42
|
+
));
|
|
43
|
+
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
|
|
44
|
+
|
|
45
|
+
const AccordionContent = React.forwardRef<
|
|
46
|
+
React.ElementRef<typeof AccordionPrimitive.Content>,
|
|
47
|
+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
|
48
|
+
>(({ className, children, ...props }, ref) => (
|
|
49
|
+
<AccordionPrimitive.Content
|
|
50
|
+
ref={ref}
|
|
51
|
+
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
|
52
|
+
{...props}
|
|
53
|
+
>
|
|
54
|
+
<div className={cn('pb-4 pt-0', className)}>{children}</div>
|
|
55
|
+
</AccordionPrimitive.Content>
|
|
56
|
+
));
|
|
57
|
+
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
|
|
58
|
+
|
|
59
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
|
|
@@ -1,96 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Alert Component (Organism)
|
|
3
|
-
* @description Feedback message
|
|
3
|
+
* @description Feedback message (Shadcn/ui compatible)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
7
8
|
import { cn } from '../../infrastructure/utils';
|
|
8
|
-
import type { BaseProps, ChildrenProps, ColorVariant } from '../../domain/types';
|
|
9
|
-
import { Icon } from '../atoms/Icon';
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
const alertVariants = cva(
|
|
11
|
+
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
|
|
12
|
+
{
|
|
13
|
+
variants: {
|
|
14
|
+
variant: {
|
|
15
|
+
default: 'bg-background text-foreground',
|
|
16
|
+
destructive: 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: {
|
|
20
|
+
variant: 'default',
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
);
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
success: {
|
|
20
|
-
container: 'border-success bg-success/10 text-success',
|
|
21
|
-
iconColor: 'text-success',
|
|
22
|
-
},
|
|
23
|
-
warning: {
|
|
24
|
-
container: 'border-warning bg-warning/10 text-warning',
|
|
25
|
-
iconColor: 'text-warning',
|
|
26
|
-
},
|
|
27
|
-
destructive: {
|
|
28
|
-
container: 'border-destructive bg-destructive/10 text-destructive',
|
|
29
|
-
iconColor: 'text-destructive',
|
|
30
|
-
},
|
|
31
|
-
info: {
|
|
32
|
-
container: 'border-primary bg-primary/10 text-primary',
|
|
33
|
-
iconColor: 'text-primary',
|
|
34
|
-
},
|
|
35
|
-
};
|
|
25
|
+
export interface AlertProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof alertVariants> {}
|
|
36
26
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
),
|
|
45
|
-
warning: (
|
|
46
|
-
<path
|
|
47
|
-
strokeLinecap="round"
|
|
48
|
-
strokeLinejoin="round"
|
|
49
|
-
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
|
|
50
|
-
/>
|
|
51
|
-
),
|
|
52
|
-
destructive: (
|
|
53
|
-
<path
|
|
54
|
-
strokeLinecap="round"
|
|
55
|
-
strokeLinejoin="round"
|
|
56
|
-
d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"
|
|
57
|
-
/>
|
|
58
|
-
),
|
|
59
|
-
info: (
|
|
60
|
-
<path
|
|
61
|
-
strokeLinecap="round"
|
|
62
|
-
strokeLinejoin="round"
|
|
63
|
-
d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"
|
|
27
|
+
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
|
|
28
|
+
({ className, variant, ...props }, ref) => (
|
|
29
|
+
<div
|
|
30
|
+
ref={ref}
|
|
31
|
+
role="alert"
|
|
32
|
+
className={cn(alertVariants({ variant }), className)}
|
|
33
|
+
{...props}
|
|
64
34
|
/>
|
|
65
|
-
)
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const Alert = forwardRef<HTMLDivElement, AlertProps>(
|
|
69
|
-
({ className, variant = 'info', showIcon = true, children, ...props }, ref) => {
|
|
70
|
-
const styles = variantStyles[variant];
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<div
|
|
74
|
-
ref={ref}
|
|
75
|
-
role="alert"
|
|
76
|
-
className={cn(
|
|
77
|
-
'relative w-full rounded-lg border p-4',
|
|
78
|
-
styles.container,
|
|
79
|
-
className
|
|
80
|
-
)}
|
|
81
|
-
{...props}
|
|
82
|
-
>
|
|
83
|
-
<div className="flex items-start gap-3">
|
|
84
|
-
{showIcon && (
|
|
85
|
-
<Icon className={cn('shrink-0 mt-0.5', styles.iconColor)} size="sm">
|
|
86
|
-
{icons[variant]}
|
|
87
|
-
</Icon>
|
|
88
|
-
)}
|
|
89
|
-
<div className="flex-1">{children}</div>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
35
|
+
)
|
|
94
36
|
);
|
|
95
|
-
|
|
96
37
|
Alert.displayName = 'Alert';
|
|
38
|
+
|
|
39
|
+
const AlertTitle = React.forwardRef<
|
|
40
|
+
HTMLParagraphElement,
|
|
41
|
+
React.HTMLAttributes<HTMLHeadingElement>
|
|
42
|
+
>(({ className, ...props }, ref) => (
|
|
43
|
+
<h5
|
|
44
|
+
ref={ref}
|
|
45
|
+
className={cn('mb-1 font-medium leading-none tracking-tight', className)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
));
|
|
49
|
+
AlertTitle.displayName = 'AlertTitle';
|
|
50
|
+
|
|
51
|
+
const AlertDescription = React.forwardRef<
|
|
52
|
+
HTMLParagraphElement,
|
|
53
|
+
React.HTMLAttributes<HTMLParagraphElement>
|
|
54
|
+
>(({ className, ...props }, ref) => (
|
|
55
|
+
<div
|
|
56
|
+
ref={ref}
|
|
57
|
+
className={cn('text-sm [&_p]:leading-relaxed', className)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
));
|
|
61
|
+
AlertDescription.displayName = 'AlertDescription';
|
|
62
|
+
|
|
63
|
+
export { Alert, AlertTitle, AlertDescription };
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './Card';
|
|
8
8
|
export type { CardProps } from './Card';
|
|
9
9
|
|
|
10
|
-
export { Alert } from './Alert';
|
|
11
|
-
export type { AlertProps
|
|
10
|
+
export { Alert, AlertTitle, AlertDescription } from './Alert';
|
|
11
|
+
export type { AlertProps } from './Alert';
|
|
12
12
|
|
|
13
13
|
export { Modal, ModalHeader, ModalTitle, ModalDescription, ModalContent, ModalFooter } from './Modal';
|
|
14
14
|
export type { ModalProps } from './Modal';
|
|
@@ -31,8 +31,7 @@ export type { TableProps } from './Table';
|
|
|
31
31
|
export { Tabs } from './Tabs';
|
|
32
32
|
export type { TabsProps, Tab } from './Tabs';
|
|
33
33
|
|
|
34
|
-
export { Accordion } from './Accordion';
|
|
35
|
-
export type { AccordionProps, AccordionItem } from './Accordion';
|
|
34
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from './Accordion';
|
|
36
35
|
|
|
37
36
|
export { Breadcrumbs } from './Breadcrumb';
|
|
38
37
|
export type { BreadcrumbsProps, BreadcrumbItem } from './Breadcrumb';
|