@umituz/web-design-system 1.0.2 → 1.0.3
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 +1 -1
- package/src/domain/tokens/animation.tokens.ts +87 -0
- package/src/domain/tokens/index.ts +11 -0
- package/src/presentation/atoms/Checkbox.tsx +50 -0
- package/src/presentation/atoms/Divider.tsx +34 -0
- package/src/presentation/atoms/Link.tsx +45 -0
- package/src/presentation/atoms/Progress.tsx +48 -0
- package/src/presentation/atoms/Radio.tsx +42 -0
- package/src/presentation/atoms/Skeleton.tsx +38 -0
- package/src/presentation/atoms/Slider.tsx +49 -0
- package/src/presentation/atoms/Tooltip.tsx +76 -0
- package/src/presentation/atoms/index.ts +24 -0
- package/src/presentation/hooks/index.ts +13 -0
- package/src/presentation/hooks/useClickOutside.ts +33 -0
- package/src/presentation/hooks/useClipboard.ts +38 -0
- package/src/presentation/hooks/useDebounce.ts +22 -0
- package/src/presentation/hooks/useKeyboard.ts +89 -0
- package/src/presentation/hooks/useScrollLock.ts +26 -0
- package/src/presentation/hooks/useToggle.ts +16 -0
- package/src/presentation/molecules/CheckboxGroup.tsx +68 -0
- package/src/presentation/molecules/InputGroup.tsx +65 -0
- package/src/presentation/molecules/RadioGroup.tsx +63 -0
- package/src/presentation/molecules/Select.tsx +41 -0
- package/src/presentation/molecules/Textarea.tsx +43 -0
- package/src/presentation/molecules/index.ts +15 -0
- package/src/presentation/organisms/Accordion.tsx +117 -0
- package/src/presentation/organisms/Breadcrumb.tsx +83 -0
- package/src/presentation/organisms/Table.tsx +120 -0
- package/src/presentation/organisms/Tabs.tsx +99 -0
- package/src/presentation/organisms/index.ts +21 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table Component (Organism)
|
|
3
|
+
* @description Data table component
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { forwardRef, type HTMLAttributes } from 'react';
|
|
7
|
+
import { cn } from '../../infrastructure/utils';
|
|
8
|
+
import type { BaseProps, ChildrenProps } from '../../domain/types';
|
|
9
|
+
|
|
10
|
+
export interface TableProps extends HTMLAttributes<HTMLTableElement>, BaseProps, ChildrenProps {}
|
|
11
|
+
|
|
12
|
+
export const Table = forwardRef<HTMLTableElement, TableProps>(
|
|
13
|
+
({ className, children, ...props }, ref) => {
|
|
14
|
+
return (
|
|
15
|
+
<div className="relative w-full overflow-auto">
|
|
16
|
+
<table
|
|
17
|
+
ref={ref}
|
|
18
|
+
className={cn('w-full caption-bottom text-sm', className)}
|
|
19
|
+
{...props}
|
|
20
|
+
>
|
|
21
|
+
{children}
|
|
22
|
+
</table>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
Table.displayName = 'Table';
|
|
29
|
+
|
|
30
|
+
export const TableHeader = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(
|
|
31
|
+
({ className, ...props }, ref) => (
|
|
32
|
+
<thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
TableHeader.displayName = 'TableHeader';
|
|
37
|
+
|
|
38
|
+
export const TableBody = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(
|
|
39
|
+
({ className, ...props }, ref) => (
|
|
40
|
+
<tbody
|
|
41
|
+
ref={ref}
|
|
42
|
+
className={cn('[&_tr:last-child]:border-0', className)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
TableBody.displayName = 'TableBody';
|
|
49
|
+
|
|
50
|
+
export const TableFooter = forwardRef<HTMLTableSectionElement, HTMLAttributes<HTMLTableSectionElement>>(
|
|
51
|
+
({ className, ...props }, ref) => (
|
|
52
|
+
<tfoot
|
|
53
|
+
ref={ref}
|
|
54
|
+
className={cn(
|
|
55
|
+
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
|
|
56
|
+
className
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
TableFooter.displayName = 'TableFooter';
|
|
64
|
+
|
|
65
|
+
export const TableRow = forwardRef<HTMLTableRowElement, HTMLAttributes<HTMLTableRowElement>>(
|
|
66
|
+
({ className, ...props }, ref) => (
|
|
67
|
+
<tr
|
|
68
|
+
ref={ref}
|
|
69
|
+
className={cn(
|
|
70
|
+
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
|
|
71
|
+
className
|
|
72
|
+
)}
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
TableRow.displayName = 'TableRow';
|
|
79
|
+
|
|
80
|
+
export const TableHead = forwardRef<HTMLTableCellElement, HTMLAttributes<HTMLTableCellElement>>(
|
|
81
|
+
({ className, ...props }, ref) => (
|
|
82
|
+
<th
|
|
83
|
+
ref={ref}
|
|
84
|
+
className={cn(
|
|
85
|
+
'h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
|
|
86
|
+
className
|
|
87
|
+
)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
TableHead.displayName = 'TableHead';
|
|
94
|
+
|
|
95
|
+
export const TableCell = forwardRef<HTMLTableCellElement, HTMLAttributes<HTMLTableCellElement>>(
|
|
96
|
+
({ className, ...props }, ref) => (
|
|
97
|
+
<td
|
|
98
|
+
ref={ref}
|
|
99
|
+
className={cn(
|
|
100
|
+
'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
|
|
101
|
+
className
|
|
102
|
+
)}
|
|
103
|
+
{...props}
|
|
104
|
+
/>
|
|
105
|
+
)
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
TableCell.displayName = 'TableCell';
|
|
109
|
+
|
|
110
|
+
export const TableCaption = forwardRef<HTMLTableCaptionElement, HTMLAttributes<HTMLTableCaptionElement>>(
|
|
111
|
+
({ className, ...props }, ref) => (
|
|
112
|
+
<caption
|
|
113
|
+
ref={ref}
|
|
114
|
+
className={cn('mt-4 text-sm text-muted-foreground', className)}
|
|
115
|
+
{...props}
|
|
116
|
+
/>
|
|
117
|
+
)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
TableCaption.displayName = 'TableCaption';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tabs Component (Organism)
|
|
3
|
+
* @description Tabbed interface
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useState, useCallback, type ReactNode, type HTMLAttributes } from 'react';
|
|
7
|
+
import { cn } from '../../infrastructure/utils';
|
|
8
|
+
import type { BaseProps, ChildrenProps } from '../../domain/types';
|
|
9
|
+
|
|
10
|
+
export interface Tab {
|
|
11
|
+
value: string;
|
|
12
|
+
label: string;
|
|
13
|
+
content?: ReactNode;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TabsProps extends HTMLAttributes<HTMLDivElement>, BaseProps {
|
|
18
|
+
tabs: Tab[];
|
|
19
|
+
defaultValue?: string;
|
|
20
|
+
variant?: 'default' | 'pills' | 'underline';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const variantStyles: Record<'default' | 'pills' | 'underline', string> = {
|
|
24
|
+
default: 'bg-muted p-1 rounded-lg gap-1',
|
|
25
|
+
pills: 'bg-transparent gap-2',
|
|
26
|
+
underline: 'bg-transparent border-b gap-6',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const tabVariantStyles: Record<'default' | 'pills' | 'underline', { base: string; active: string }> = {
|
|
30
|
+
default: {
|
|
31
|
+
base: 'px-3 py-1.5 rounded-md text-sm font-medium transition-all',
|
|
32
|
+
active: 'bg-background text-foreground shadow-sm',
|
|
33
|
+
},
|
|
34
|
+
pills: {
|
|
35
|
+
base: 'px-4 py-2 rounded-full text-sm font-medium transition-all',
|
|
36
|
+
active: 'bg-primary text-primary-foreground',
|
|
37
|
+
},
|
|
38
|
+
underline: {
|
|
39
|
+
base: 'px-1 pb-3 text-sm font-medium transition-all border-b-2 border-transparent',
|
|
40
|
+
active: 'text-foreground border-primary',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export function Tabs({ tabs, defaultValue, variant = 'default', className, ...props }: TabsProps) {
|
|
45
|
+
const [activeTab, setActiveTab] = useState(defaultValue || tabs[0]?.value);
|
|
46
|
+
|
|
47
|
+
const handleTabChange = useCallback((value: string) => {
|
|
48
|
+
const tab = tabs.find((t) => t.value === value);
|
|
49
|
+
if (tab && !tab.disabled) {
|
|
50
|
+
setActiveTab(value);
|
|
51
|
+
}
|
|
52
|
+
}, [tabs]);
|
|
53
|
+
|
|
54
|
+
const currentTab = tabs.find((t) => t.value === activeTab);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div className={cn('w-full', className)} {...props}>
|
|
58
|
+
{/* Tab List */}
|
|
59
|
+
<div
|
|
60
|
+
role="tablist"
|
|
61
|
+
className={cn('inline-flex w-full', variantStyles[variant])}
|
|
62
|
+
>
|
|
63
|
+
{tabs.map((tab) => {
|
|
64
|
+
const isActive = activeTab === tab.value;
|
|
65
|
+
const styles = tabVariantStyles[variant];
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<button
|
|
69
|
+
key={tab.value}
|
|
70
|
+
role="tab"
|
|
71
|
+
aria-selected={isActive}
|
|
72
|
+
disabled={tab.disabled}
|
|
73
|
+
onClick={() => handleTabChange(tab.value)}
|
|
74
|
+
className={cn(
|
|
75
|
+
styles.base,
|
|
76
|
+
isActive
|
|
77
|
+
? styles.active
|
|
78
|
+
: 'text-muted-foreground hover:text-foreground',
|
|
79
|
+
tab.disabled && 'opacity-50 cursor-not-allowed'
|
|
80
|
+
)}
|
|
81
|
+
>
|
|
82
|
+
{tab.label}
|
|
83
|
+
</button>
|
|
84
|
+
);
|
|
85
|
+
})}
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
{/* Tab Content */}
|
|
89
|
+
<div
|
|
90
|
+
role="tabpanel"
|
|
91
|
+
className="mt-4"
|
|
92
|
+
>
|
|
93
|
+
{currentTab?.content}
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Tabs.displayName = 'Tabs';
|
|
@@ -15,3 +15,24 @@ export type { ModalProps } from './Modal';
|
|
|
15
15
|
|
|
16
16
|
export { Navbar, NavbarBrand, NavbarLinks, NavbarActions } from './Navbar';
|
|
17
17
|
export type { NavbarProps } from './Navbar';
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
Table,
|
|
21
|
+
TableHeader,
|
|
22
|
+
TableBody,
|
|
23
|
+
TableFooter,
|
|
24
|
+
TableRow,
|
|
25
|
+
TableHead,
|
|
26
|
+
TableCell,
|
|
27
|
+
TableCaption
|
|
28
|
+
} from './Table';
|
|
29
|
+
export type { TableProps } from './Table';
|
|
30
|
+
|
|
31
|
+
export { Tabs } from './Tabs';
|
|
32
|
+
export type { TabsProps, Tab } from './Tabs';
|
|
33
|
+
|
|
34
|
+
export { Accordion } from './Accordion';
|
|
35
|
+
export type { AccordionProps, AccordionItem } from './Accordion';
|
|
36
|
+
|
|
37
|
+
export { Breadcrumbs } from './Breadcrumb';
|
|
38
|
+
export type { BreadcrumbsProps, BreadcrumbItem } from './Breadcrumb';
|