@umituz/web-design-system 1.3.1 → 1.7.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 +20 -2
- package/src/presentation/atoms/Label.tsx +25 -0
- package/src/presentation/atoms/index.ts +2 -0
- package/src/presentation/molecules/Avatar.tsx +47 -19
- package/src/presentation/molecules/ListItem.tsx +128 -0
- package/src/presentation/molecules/ScrollArea.tsx +50 -0
- package/src/presentation/molecules/Select.tsx +152 -33
- package/src/presentation/molecules/index.ts +8 -3
- package/src/presentation/organisms/Accordion.tsx +53 -111
- package/src/presentation/organisms/Alert.tsx +43 -85
- package/src/presentation/organisms/Collapsible.tsx +14 -0
- package/src/presentation/organisms/ConfirmDialog.tsx +97 -0
- package/src/presentation/organisms/DataTable.tsx +233 -0
- package/src/presentation/organisms/Dialog.tsx +124 -0
- package/src/presentation/organisms/EmptyState.tsx +103 -0
- package/src/presentation/organisms/FormModal.tsx +126 -0
- package/src/presentation/organisms/HoverCard.tsx +31 -0
- package/src/presentation/organisms/LoadingState.tsx +87 -0
- package/src/presentation/organisms/MetricCard.tsx +126 -0
- package/src/presentation/organisms/Popover.tsx +33 -0
- package/src/presentation/organisms/QuickActionCard.tsx +110 -0
- package/src/presentation/organisms/Sheet.tsx +135 -0
- package/src/presentation/organisms/StatCard.tsx +161 -0
- package/src/presentation/organisms/index.ts +57 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/web-design-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.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,33 @@
|
|
|
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-collapsible": ">=1.0.0",
|
|
57
|
+
"@radix-ui/react-dialog": ">=1.0.0",
|
|
58
|
+
"@radix-ui/react-hover-card": ">=1.0.0",
|
|
59
|
+
"@radix-ui/react-label": ">=2.0.0",
|
|
60
|
+
"@radix-ui/react-popover": ">=1.0.0",
|
|
61
|
+
"@radix-ui/react-scroll-area": ">=1.0.0",
|
|
62
|
+
"@radix-ui/react-select": ">=2.0.0",
|
|
63
|
+
"clsx": ">=2.0.0",
|
|
64
|
+
"lucide-react": ">=0.400.0",
|
|
55
65
|
"react": ">=18.0.0",
|
|
56
66
|
"react-dom": ">=18.0.0",
|
|
57
|
-
"clsx": ">=2.0.0",
|
|
58
67
|
"tailwind-merge": ">=2.0.0"
|
|
59
68
|
},
|
|
60
69
|
"devDependencies": {
|
|
70
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
71
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
72
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
73
|
+
"@radix-ui/react-hover-card": "^1.1.8",
|
|
74
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
75
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
76
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
77
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
61
78
|
"@types/react": "^18.0.0",
|
|
62
79
|
"@types/react-dom": "^18.0.0",
|
|
63
80
|
"clsx": "^2.1.1",
|
|
81
|
+
"lucide-react": "^0.577.0",
|
|
64
82
|
"react": "^18.0.0",
|
|
65
83
|
"react-dom": "^18.0.0",
|
|
66
84
|
"tailwind-merge": "^3.5.0",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Label Component (Atom)
|
|
3
|
+
* @description Form label (Shadcn/ui compatible)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
8
|
+
import { cn } from '../../infrastructure/utils';
|
|
9
|
+
|
|
10
|
+
const Label = React.forwardRef<
|
|
11
|
+
React.ElementRef<typeof LabelPrimitive.Root>,
|
|
12
|
+
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
|
|
13
|
+
>(({ className, ...props }, ref) => (
|
|
14
|
+
<LabelPrimitive.Root
|
|
15
|
+
ref={ref}
|
|
16
|
+
className={cn(
|
|
17
|
+
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
));
|
|
23
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
24
|
+
|
|
25
|
+
export { Label };
|
|
@@ -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 };
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ListItem Component (Molecule)
|
|
3
|
+
* @description Reusable list item with icon, content, and actions
|
|
4
|
+
* Reduces boilerplate in list components throughout the app
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { forwardRef, type ReactNode, type MouseEvent } from 'react';
|
|
8
|
+
import { cn } from '../../infrastructure/utils';
|
|
9
|
+
import { Button } from '../atoms';
|
|
10
|
+
import type { BaseProps } from '../../domain/types';
|
|
11
|
+
|
|
12
|
+
export interface ListItemProps extends BaseProps {
|
|
13
|
+
title: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
icon?: ReactNode;
|
|
16
|
+
actions?: ReactNode;
|
|
17
|
+
leftContent?: ReactNode;
|
|
18
|
+
rightContent?: ReactNode;
|
|
19
|
+
onClick?: () => void;
|
|
20
|
+
href?: string;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
selected?: boolean;
|
|
23
|
+
size?: 'sm' | 'md' | 'lg';
|
|
24
|
+
variant?: 'default' | 'bordered' | 'ghost';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const sizeStyles = {
|
|
28
|
+
sm: 'p-3 gap-3',
|
|
29
|
+
md: 'p-4 gap-4',
|
|
30
|
+
lg: 'p-5 gap-5',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const titleSizeStyles = {
|
|
34
|
+
sm: 'text-sm',
|
|
35
|
+
md: 'text-base',
|
|
36
|
+
lg: 'text-lg',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const descriptionSizeStyles = {
|
|
40
|
+
sm: 'text-xs',
|
|
41
|
+
md: 'text-sm',
|
|
42
|
+
lg: 'text-base',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const iconSizeStyles = {
|
|
46
|
+
sm: 'h-4 w-4',
|
|
47
|
+
md: 'h-5 w-5',
|
|
48
|
+
lg: 'h-6 w-6',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const ListItem = forwardRef<HTMLDivElement, ListItemProps>(
|
|
52
|
+
(
|
|
53
|
+
{
|
|
54
|
+
className,
|
|
55
|
+
title,
|
|
56
|
+
description,
|
|
57
|
+
icon,
|
|
58
|
+
actions,
|
|
59
|
+
leftContent,
|
|
60
|
+
rightContent,
|
|
61
|
+
onClick,
|
|
62
|
+
href,
|
|
63
|
+
disabled = false,
|
|
64
|
+
selected = false,
|
|
65
|
+
size = 'md',
|
|
66
|
+
variant = 'default',
|
|
67
|
+
...props
|
|
68
|
+
},
|
|
69
|
+
ref
|
|
70
|
+
) => {
|
|
71
|
+
const baseClasses = cn(
|
|
72
|
+
'flex items-center justify-between w-full transition-all duration-200',
|
|
73
|
+
sizeStyles[size],
|
|
74
|
+
!disabled && onClick && 'cursor-pointer hover:bg-muted/50 active:scale-[0.98]',
|
|
75
|
+
selected && 'bg-muted/50 border-primary',
|
|
76
|
+
variant === 'bordered' && 'border border-border rounded-lg',
|
|
77
|
+
variant === 'ghost' && 'hover:bg-muted/30',
|
|
78
|
+
disabled && 'opacity-50 cursor-not-allowed',
|
|
79
|
+
className
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const content = (
|
|
83
|
+
<>
|
|
84
|
+
{leftContent || icon ? (
|
|
85
|
+
<div className="flex items-center gap-3 flex-shrink-0">
|
|
86
|
+
{icon && <div className={cn(iconSizeStyles[size], 'text-muted-foreground')}>{icon}</div>}
|
|
87
|
+
{!icon && leftContent}
|
|
88
|
+
</div>
|
|
89
|
+
) : null}
|
|
90
|
+
|
|
91
|
+
<div className="flex-1 min-w-0">
|
|
92
|
+
<p className={cn('font-medium text-foreground truncate', titleSizeStyles[size])}>{title}</p>
|
|
93
|
+
{description && (
|
|
94
|
+
<p className={cn('text-muted-foreground truncate', descriptionSizeStyles[size])}>{description}</p>
|
|
95
|
+
)}
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
{rightContent || actions ? (
|
|
99
|
+
<div className="flex items-center gap-2 flex-shrink-0">
|
|
100
|
+
{rightContent}
|
|
101
|
+
{actions}
|
|
102
|
+
</div>
|
|
103
|
+
) : null}
|
|
104
|
+
</>
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (href && !disabled) {
|
|
108
|
+
return (
|
|
109
|
+
<a href={href} ref={ref as any} className={baseClasses} {...(props as any)}>
|
|
110
|
+
{content}
|
|
111
|
+
</a>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<div
|
|
117
|
+
ref={ref}
|
|
118
|
+
className={baseClasses}
|
|
119
|
+
onClick={disabled ? undefined : onClick}
|
|
120
|
+
{...props}
|
|
121
|
+
>
|
|
122
|
+
{content}
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
ListItem.displayName = 'ListItem';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScrollArea Component (Molecule)
|
|
3
|
+
* @description Custom scrollable area (Shadcn/ui compatible)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
8
|
+
import { cn } from '../../infrastructure/utils';
|
|
9
|
+
|
|
10
|
+
const ScrollArea = React.forwardRef<
|
|
11
|
+
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
|
12
|
+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
|
13
|
+
>(({ className, children, ...props }, ref) => (
|
|
14
|
+
<ScrollAreaPrimitive.Root
|
|
15
|
+
ref={ref}
|
|
16
|
+
className={cn('relative overflow-hidden', className)}
|
|
17
|
+
{...props}
|
|
18
|
+
>
|
|
19
|
+
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
|
20
|
+
{children}
|
|
21
|
+
</ScrollAreaPrimitive.Viewport>
|
|
22
|
+
<ScrollBar />
|
|
23
|
+
<ScrollAreaPrimitive.Corner />
|
|
24
|
+
</ScrollAreaPrimitive.Root>
|
|
25
|
+
));
|
|
26
|
+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
27
|
+
|
|
28
|
+
const ScrollBar = React.forwardRef<
|
|
29
|
+
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
|
30
|
+
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
31
|
+
>(({ className, orientation = 'vertical', ...props }, ref) => (
|
|
32
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
33
|
+
ref={ref}
|
|
34
|
+
orientation={orientation}
|
|
35
|
+
className={cn(
|
|
36
|
+
'flex touch-none select-none transition-colors',
|
|
37
|
+
orientation === 'vertical' &&
|
|
38
|
+
'h-full w-2.5 border-l border-l-transparent p-[1px]',
|
|
39
|
+
orientation === 'horizontal' &&
|
|
40
|
+
'h-2.5 flex-col border-t border-t-transparent p-[1px]',
|
|
41
|
+
className
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
|
46
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
47
|
+
));
|
|
48
|
+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
49
|
+
|
|
50
|
+
export { ScrollArea, ScrollBar };
|
|
@@ -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';
|
|
@@ -33,3 +33,8 @@ export type { CheckboxGroupProps, CheckboxOption } from './CheckboxGroup';
|
|
|
33
33
|
|
|
34
34
|
export { InputGroup, GroupedInput } from './InputGroup';
|
|
35
35
|
export type { InputGroupProps } from './InputGroup';
|
|
36
|
+
|
|
37
|
+
export { ScrollArea, ScrollBar } from './ScrollArea';
|
|
38
|
+
|
|
39
|
+
export { ListItem } from './ListItem';
|
|
40
|
+
export type { ListItemProps } from './ListItem';
|