@tuturuuu/ui 0.0.4

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 (104) hide show
  1. package/.checksum +1 -0
  2. package/README.md +46 -0
  3. package/components.json +20 -0
  4. package/eslint.config.mjs +20 -0
  5. package/jsr.json +10 -0
  6. package/package.json +120 -0
  7. package/postcss.config.mjs +8 -0
  8. package/rollup.config.js +40 -0
  9. package/src/components/ui/accordion.tsx +70 -0
  10. package/src/components/ui/alert-dialog.tsx +156 -0
  11. package/src/components/ui/alert.tsx +58 -0
  12. package/src/components/ui/aspect-ratio.tsx +11 -0
  13. package/src/components/ui/avatar.tsx +52 -0
  14. package/src/components/ui/badge.tsx +49 -0
  15. package/src/components/ui/breadcrumb.tsx +108 -0
  16. package/src/components/ui/button.tsx +61 -0
  17. package/src/components/ui/calendar.tsx +212 -0
  18. package/src/components/ui/card.tsx +74 -0
  19. package/src/components/ui/carousel.tsx +240 -0
  20. package/src/components/ui/chart.tsx +365 -0
  21. package/src/components/ui/checkbox.tsx +31 -0
  22. package/src/components/ui/codeblock.tsx +161 -0
  23. package/src/components/ui/collapsible.tsx +33 -0
  24. package/src/components/ui/color-picker.tsx +143 -0
  25. package/src/components/ui/command.tsx +176 -0
  26. package/src/components/ui/context-menu.tsx +251 -0
  27. package/src/components/ui/custom/autosize-textarea.tsx +111 -0
  28. package/src/components/ui/custom/calendar/core.tsx +61 -0
  29. package/src/components/ui/custom/calendar/day-cell.tsx +74 -0
  30. package/src/components/ui/custom/calendar/month-header.tsx +59 -0
  31. package/src/components/ui/custom/calendar/month-view.tsx +110 -0
  32. package/src/components/ui/custom/calendar/utils.ts +76 -0
  33. package/src/components/ui/custom/calendar/year-calendar.tsx +64 -0
  34. package/src/components/ui/custom/calendar/year-view.tsx +58 -0
  35. package/src/components/ui/custom/combobox.tsx +197 -0
  36. package/src/components/ui/custom/common-footer.tsx +215 -0
  37. package/src/components/ui/custom/compared-date-range-picker.tsx +561 -0
  38. package/src/components/ui/custom/date-input.tsx +279 -0
  39. package/src/components/ui/custom/empty-card.tsx +39 -0
  40. package/src/components/ui/custom/feature-summary.tsx +135 -0
  41. package/src/components/ui/custom/file-uploader.tsx +349 -0
  42. package/src/components/ui/custom/input-field.tsx +29 -0
  43. package/src/components/ui/custom/loading-indicator.tsx +28 -0
  44. package/src/components/ui/custom/modifiable-dialog-trigger.tsx +83 -0
  45. package/src/components/ui/custom/month-picker.tsx +157 -0
  46. package/src/components/ui/custom/report-preview.tsx +175 -0
  47. package/src/components/ui/custom/search-bar.tsx +56 -0
  48. package/src/components/ui/custom/select-field.tsx +78 -0
  49. package/src/components/ui/custom/tables/data-table-column-header.tsx +72 -0
  50. package/src/components/ui/custom/tables/data-table-create-button.tsx +31 -0
  51. package/src/components/ui/custom/tables/data-table-faceted-filter.tsx +142 -0
  52. package/src/components/ui/custom/tables/data-table-pagination.tsx +243 -0
  53. package/src/components/ui/custom/tables/data-table-refresh-button.tsx +45 -0
  54. package/src/components/ui/custom/tables/data-table-toolbar.tsx +133 -0
  55. package/src/components/ui/custom/tables/data-table-view-options.tsx +112 -0
  56. package/src/components/ui/custom/tables/data-table.tsx +228 -0
  57. package/src/components/ui/custom/uploaded-files-card.tsx +50 -0
  58. package/src/components/ui/dialog.tsx +137 -0
  59. package/src/components/ui/drawer.tsx +131 -0
  60. package/src/components/ui/dropdown-menu.tsx +256 -0
  61. package/src/components/ui/form.tsx +167 -0
  62. package/src/components/ui/hover-card.tsx +41 -0
  63. package/src/components/ui/icons.tsx +506 -0
  64. package/src/components/ui/input-otp.tsx +78 -0
  65. package/src/components/ui/input.tsx +18 -0
  66. package/src/components/ui/label.tsx +23 -0
  67. package/src/components/ui/markdown.tsx +7 -0
  68. package/src/components/ui/menubar.tsx +275 -0
  69. package/src/components/ui/navigation-menu.tsx +169 -0
  70. package/src/components/ui/pagination.tsx +126 -0
  71. package/src/components/ui/popover.tsx +47 -0
  72. package/src/components/ui/progress.tsx +30 -0
  73. package/src/components/ui/radio-group.tsx +44 -0
  74. package/src/components/ui/resizable.tsx +55 -0
  75. package/src/components/ui/scroll-area.tsx +57 -0
  76. package/src/components/ui/select.tsx +180 -0
  77. package/src/components/ui/separator.tsx +27 -0
  78. package/src/components/ui/sheet.tsx +138 -0
  79. package/src/components/ui/sidebar.tsx +734 -0
  80. package/src/components/ui/skeleton.tsx +13 -0
  81. package/src/components/ui/slider.tsx +62 -0
  82. package/src/components/ui/sonner.tsx +29 -0
  83. package/src/components/ui/switch.tsx +30 -0
  84. package/src/components/ui/table.tsx +112 -0
  85. package/src/components/ui/tabs.tsx +68 -0
  86. package/src/components/ui/tag-input.tsx +141 -0
  87. package/src/components/ui/textarea.tsx +17 -0
  88. package/src/components/ui/time-picker-input.tsx +117 -0
  89. package/src/components/ui/time-picker-utils.tsx +146 -0
  90. package/src/components/ui/toast.tsx +128 -0
  91. package/src/components/ui/toaster.tsx +35 -0
  92. package/src/components/ui/toggle-group.tsx +72 -0
  93. package/src/components/ui/toggle.tsx +46 -0
  94. package/src/components/ui/tooltip.tsx +60 -0
  95. package/src/globals.css +252 -0
  96. package/src/hooks/use-callback-ref.ts +28 -0
  97. package/src/hooks/use-controllable-state.ts +68 -0
  98. package/src/hooks/use-copy-to-clipboard.ts +46 -0
  99. package/src/hooks/use-form.ts +23 -0
  100. package/src/hooks/use-forwarded-ref.ts +17 -0
  101. package/src/hooks/use-mobile.tsx +21 -0
  102. package/src/hooks/use-toast.ts +191 -0
  103. package/src/resolvers.ts +3 -0
  104. package/tsconfig.json +17 -0
package/.checksum ADDED
@@ -0,0 +1 @@
1
+ ce19d96648be5c89455ffc1a3db65def4fe52ac251b18433c1867049b64c9726
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @tuturuuu/ui
2
+
3
+ Shared UI components and design system for Tuturuuu Platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @tuturuuu/ui
9
+ # or
10
+ yarn add @tuturuuu/ui
11
+ # or
12
+ pnpm add @tuturuuu/ui
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { Button, Card } from '@tuturuuu/ui'
19
+
20
+ export default function MyComponent() {
21
+ return (
22
+ <Card>
23
+ <Button variant="primary">Click me</Button>
24
+ </Card>
25
+ )
26
+ }
27
+ ```
28
+
29
+ ## Features
30
+
31
+ - Fully accessible components
32
+ - Type-safe props
33
+ - Tailwind CSS integration
34
+ - Dark mode support
35
+ - Comprehensive theming system
36
+
37
+ ## Development
38
+
39
+ ```bash
40
+ # Install dependencies
41
+ pnpm install
42
+ ```
43
+
44
+ ## License
45
+
46
+ MIT © [Tuturuuu](https://github.com/tutur3u)
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "default",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.ts",
8
+ "css": "src/globals.css",
9
+ "baseColor": "zinc",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "@tuturuuu/ui/components",
15
+ "ui": "@tuturuuu/ui/components/ui",
16
+ "utils": "@tuturuuu/ui/lib/utils",
17
+ "lib": "@tuturuuu/ui/lib",
18
+ "hooks": "@tuturuuu/ui/hooks"
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ import { FlatCompat } from "@eslint/eslintrc";
2
+ import js from "@eslint/js";
3
+ import tsParser from "@typescript-eslint/parser";
4
+
5
+
6
+ const compat = new FlatCompat({
7
+ baseDirectory: import.meta.dirname,
8
+ recommendedConfig: js.configs.recommended,
9
+ allConfig: js.configs.all
10
+ });
11
+
12
+ export default [...compat.extends("@tuturuuu/eslint-config/react-internal.js"), {
13
+ languageOptions: {
14
+ parser: tsParser,
15
+ },
16
+
17
+ rules: {
18
+ "no-redeclare": "off",
19
+ },
20
+ }];
package/jsr.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://jsr.io/schema/config-file.v1.json",
3
+ "name": "@tuturuuu/ui",
4
+ "license": "MIT",
5
+ "version": "0.0.4",
6
+ "exports": {
7
+ "./resolvers": "./src/resolvers.ts",
8
+ "./button": "./src/components/ui/button.tsx"
9
+ }
10
+ }
package/package.json ADDED
@@ -0,0 +1,120 @@
1
+ {
2
+ "name": "@tuturuuu/ui",
3
+ "version": "0.0.4",
4
+ "license": "MIT",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "scripts": {
9
+ "ui": "pnpm dlx shadcn-ui@latest",
10
+ "rollup": "rollup -c --bundleConfigAsCjs",
11
+ "lint": "eslint ."
12
+ },
13
+ "main": "dist/index.js",
14
+ "module": "dist/index.mjs",
15
+ "types": "dist/index.d.ts",
16
+ "packageManager": "pnpm@10.4.1",
17
+ "dependencies": {
18
+ "@hookform/resolvers": "^4.1.1",
19
+ "@radix-ui/react-accordion": "^1.2.3",
20
+ "@radix-ui/react-alert-dialog": "^1.1.6",
21
+ "@radix-ui/react-aspect-ratio": "^1.1.2",
22
+ "@radix-ui/react-avatar": "^1.1.3",
23
+ "@radix-ui/react-checkbox": "^1.1.4",
24
+ "@radix-ui/react-collapsible": "^1.1.3",
25
+ "@radix-ui/react-context-menu": "^2.2.6",
26
+ "@radix-ui/react-dialog": "^1.1.6",
27
+ "@radix-ui/react-dropdown-menu": "^2.1.6",
28
+ "@radix-ui/react-hover-card": "^1.1.6",
29
+ "@radix-ui/react-label": "^2.1.2",
30
+ "@radix-ui/react-menubar": "^1.1.6",
31
+ "@radix-ui/react-navigation-menu": "^1.2.5",
32
+ "@radix-ui/react-popover": "^1.1.6",
33
+ "@radix-ui/react-progress": "^1.1.2",
34
+ "@radix-ui/react-radio-group": "^1.2.3",
35
+ "@radix-ui/react-scroll-area": "^1.2.3",
36
+ "@radix-ui/react-select": "^2.1.6",
37
+ "@radix-ui/react-separator": "^1.1.2",
38
+ "@radix-ui/react-slider": "^1.2.3",
39
+ "@radix-ui/react-slot": "^1.1.2",
40
+ "@radix-ui/react-switch": "^1.1.3",
41
+ "@radix-ui/react-tabs": "^1.1.3",
42
+ "@radix-ui/react-toast": "^1.2.6",
43
+ "@radix-ui/react-toggle": "^1.1.2",
44
+ "@radix-ui/react-toggle-group": "^1.1.2",
45
+ "@radix-ui/react-tooltip": "^1.1.8",
46
+ "@tanstack/react-table": "^8.21.2",
47
+ "@tuturuuu/utils": "workspace:*",
48
+ "class-variance-authority": "^0.7.1",
49
+ "cmdk": "^1.0.4",
50
+ "date-fns": "^4.1.0",
51
+ "date-fns-tz": "^3.2.0",
52
+ "embla-carousel-react": "^8.5.2",
53
+ "eslint": "^9.21.0",
54
+ "input-otp": "^1.4.2",
55
+ "lodash": "^4.17.21",
56
+ "lucide-react": "^0.475.0",
57
+ "next": "^15.1.7",
58
+ "next-themes": "^0.4.4",
59
+ "react": "^19.0.0",
60
+ "react-colorful": "^5.6.1",
61
+ "react-day-picker": "9.5.1",
62
+ "react-dom": "^19.0.0",
63
+ "react-dropzone": "^14.3.5",
64
+ "react-hook-form": "^7.54.2",
65
+ "react-markdown": "^10.0.0",
66
+ "react-resizable": "^3.0.5",
67
+ "react-resizable-panels": "^2.1.7",
68
+ "react-syntax-highlighter": "^15.6.1",
69
+ "recharts": "^2.15.1",
70
+ "rollup": "^4.34.8",
71
+ "rollup-plugin-postcss": "^4.0.2",
72
+ "sonner": "^2.0.1",
73
+ "tailwindcss-animate": "^1.0.7",
74
+ "vaul": "^1.1.2",
75
+ "zod": "^3.24.2"
76
+ },
77
+ "devDependencies": {
78
+ "@eslint/eslintrc": "^3.3.0",
79
+ "@eslint/js": "^9.21.0",
80
+ "@rollup/plugin-commonjs": "^28.0.2",
81
+ "@rollup/plugin-node-resolve": "^16.0.0",
82
+ "@rollup/plugin-terser": "^0.4.4",
83
+ "@rollup/plugin-typescript": "^12.1.2",
84
+ "@tailwindcss/postcss": "^4.0.8",
85
+ "@tailwindcss/typography": "^0.5.16",
86
+ "@tuturuuu/eslint-config": "workspace:*",
87
+ "@tuturuuu/typescript-config": "workspace:*",
88
+ "@types/lodash": "^4.17.15",
89
+ "@types/node": "^22.13.5",
90
+ "@types/react": "^19.0.10",
91
+ "@types/react-resizable": "^3.0.8",
92
+ "@types/react-syntax-highlighter": "^15.5.13",
93
+ "@types/rollup-plugin-peer-deps-external": "^2.2.5",
94
+ "@typescript-eslint/eslint-plugin": "^8.24.1",
95
+ "@typescript-eslint/parser": "^8.24.1",
96
+ "autoprefixer": "^10.4.20",
97
+ "postcss": "^8.5.3",
98
+ "postcss-load-config": "^6.0.1",
99
+ "rollup-plugin-dts": "^6.1.1",
100
+ "rollup-plugin-peer-deps-external": "^2.2.4",
101
+ "tailwindcss": "^4.0.8",
102
+ "typescript": "^5.7.3"
103
+ },
104
+ "overrides": {
105
+ "react-is": "^19.0.0"
106
+ },
107
+ "exports": {
108
+ ".": {
109
+ "types": "./src/index.d.ts",
110
+ "import": "./src/index.ts"
111
+ },
112
+ "./globals.css": "./src/globals.css",
113
+ "./postcss.config": "./postcss.config.mjs",
114
+ "./tailwind.config": "./tailwind.config.ts",
115
+ "./lib/*": "./src/lib/*.ts",
116
+ "./hooks/*": "./src/hooks/*.ts",
117
+ "./resolvers": "./src/resolvers.ts",
118
+ "./*": "./src/components/ui/*.tsx"
119
+ }
120
+ }
@@ -0,0 +1,8 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ "@tailwindcss/postcss": {},
5
+ },
6
+ };
7
+
8
+ export default config;
@@ -0,0 +1,40 @@
1
+ import commonjs from "@rollup/plugin-commonjs";
2
+ import resolve from "@rollup/plugin-node-resolve";
3
+ import terser from "@rollup/plugin-terser";
4
+ import typescript from "@rollup/plugin-typescript";
5
+ import dts from "rollup-plugin-dts";
6
+ import peerDepsExternal from "rollup-plugin-peer-deps-external";
7
+
8
+ const packageJson = require("./package.json");
9
+
10
+ export default [
11
+ {
12
+ input: "src/index.ts",
13
+ output: [
14
+ {
15
+ file: packageJson.main,
16
+ format: "cjs",
17
+ sourcemap: true,
18
+ },
19
+ {
20
+ file: packageJson.module,
21
+ format: "esm",
22
+ sourcemap: true,
23
+ },
24
+ ],
25
+ plugins: [
26
+ peerDepsExternal(),
27
+ resolve(),
28
+ commonjs(),
29
+ typescript({ tsconfig: "./tsconfig.json" }),
30
+ terser(),
31
+ postcss(),
32
+ ],
33
+ external: ["react", "react-dom", /\.css$/],
34
+ },
35
+ {
36
+ input: "src/index.ts",
37
+ output: [{ file: packageJson.types }],
38
+ plugins: [dts.default()],
39
+ },
40
+ ];
@@ -0,0 +1,70 @@
1
+ 'use client';
2
+
3
+ import * as AccordionPrimitive from '@radix-ui/react-accordion';
4
+ import { cn } from '@tuturuuu/utils/format';
5
+ import { ChevronDownIcon } from 'lucide-react';
6
+ import * as React from 'react';
7
+
8
+ function Accordion({
9
+ ...props
10
+ }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
11
+ return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
12
+ }
13
+
14
+ function AccordionItem({
15
+ className,
16
+ ...props
17
+ }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
18
+ return (
19
+ <AccordionPrimitive.Item
20
+ data-slot="accordion-item"
21
+ className={cn('border-b last:border-b-0', className)}
22
+ {...props}
23
+ />
24
+ );
25
+ }
26
+
27
+ function AccordionTrigger({
28
+ className,
29
+ children,
30
+ showChevron = true,
31
+ ...props
32
+ }: React.ComponentProps<typeof AccordionPrimitive.Trigger> & {
33
+ showChevron?: boolean;
34
+ }) {
35
+ return (
36
+ <AccordionPrimitive.Header className="flex">
37
+ <AccordionPrimitive.Trigger
38
+ data-slot="accordion-trigger"
39
+ className={cn(
40
+ 'flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium ring-ring/10 outline-ring/50 transition-all hover:underline focus-visible:ring-4 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 dark:ring-ring/20 dark:outline-ring/40 [&[data-state=open]>svg]:rotate-180',
41
+ className
42
+ )}
43
+ {...props}
44
+ >
45
+ {children}
46
+ {showChevron && (
47
+ <ChevronDownIcon className="pointer-events-none size-4 shrink-0 translate-y-0.5 text-muted-foreground transition-transform duration-200" />
48
+ )}
49
+ </AccordionPrimitive.Trigger>
50
+ </AccordionPrimitive.Header>
51
+ );
52
+ }
53
+
54
+ function AccordionContent({
55
+ className,
56
+ children,
57
+ ...props
58
+ }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
59
+ return (
60
+ <AccordionPrimitive.Content
61
+ data-slot="accordion-content"
62
+ className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
63
+ {...props}
64
+ >
65
+ <div className={cn('pt-0 pb-4', className)}>{children}</div>
66
+ </AccordionPrimitive.Content>
67
+ );
68
+ }
69
+
70
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -0,0 +1,156 @@
1
+ 'use client';
2
+
3
+ import { buttonVariants } from './button';
4
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
5
+ import { cn } from '@tuturuuu/utils/format';
6
+ import * as React from 'react';
7
+
8
+ function AlertDialog({
9
+ ...props
10
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
11
+ return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
12
+ }
13
+
14
+ function AlertDialogTrigger({
15
+ ...props
16
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
17
+ return (
18
+ <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
19
+ );
20
+ }
21
+
22
+ function AlertDialogPortal({
23
+ ...props
24
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
25
+ return (
26
+ <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
27
+ );
28
+ }
29
+
30
+ function AlertDialogOverlay({
31
+ className,
32
+ ...props
33
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
34
+ return (
35
+ <AlertDialogPrimitive.Overlay
36
+ data-slot="alert-dialog-overlay"
37
+ className={cn(
38
+ 'fixed inset-0 z-50 bg-black/80 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0',
39
+ className
40
+ )}
41
+ {...props}
42
+ />
43
+ );
44
+ }
45
+
46
+ function AlertDialogContent({
47
+ className,
48
+ ...props
49
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {
50
+ return (
51
+ <AlertDialogPortal>
52
+ <AlertDialogOverlay />
53
+ <AlertDialogPrimitive.Content
54
+ data-slot="alert-dialog-content"
55
+ className={cn(
56
+ 'fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg',
57
+ className
58
+ )}
59
+ {...props}
60
+ />
61
+ </AlertDialogPortal>
62
+ );
63
+ }
64
+
65
+ function AlertDialogHeader({
66
+ className,
67
+ ...props
68
+ }: React.ComponentProps<'div'>) {
69
+ return (
70
+ <div
71
+ data-slot="alert-dialog-header"
72
+ className={cn('flex flex-col gap-2 text-center sm:text-left', className)}
73
+ {...props}
74
+ />
75
+ );
76
+ }
77
+
78
+ function AlertDialogFooter({
79
+ className,
80
+ ...props
81
+ }: React.ComponentProps<'div'>) {
82
+ return (
83
+ <div
84
+ data-slot="alert-dialog-footer"
85
+ className={cn(
86
+ 'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',
87
+ className
88
+ )}
89
+ {...props}
90
+ />
91
+ );
92
+ }
93
+
94
+ function AlertDialogTitle({
95
+ className,
96
+ ...props
97
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
98
+ return (
99
+ <AlertDialogPrimitive.Title
100
+ data-slot="alert-dialog-title"
101
+ className={cn('text-lg font-semibold', className)}
102
+ {...props}
103
+ />
104
+ );
105
+ }
106
+
107
+ function AlertDialogDescription({
108
+ className,
109
+ ...props
110
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
111
+ return (
112
+ <AlertDialogPrimitive.Description
113
+ data-slot="alert-dialog-description"
114
+ className={cn('text-sm text-muted-foreground', className)}
115
+ {...props}
116
+ />
117
+ );
118
+ }
119
+
120
+ function AlertDialogAction({
121
+ className,
122
+ ...props
123
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
124
+ return (
125
+ <AlertDialogPrimitive.Action
126
+ className={cn(buttonVariants(), className)}
127
+ {...props}
128
+ />
129
+ );
130
+ }
131
+
132
+ function AlertDialogCancel({
133
+ className,
134
+ ...props
135
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
136
+ return (
137
+ <AlertDialogPrimitive.Cancel
138
+ className={cn(buttonVariants({ variant: 'outline' }), className)}
139
+ {...props}
140
+ />
141
+ );
142
+ }
143
+
144
+ export {
145
+ AlertDialog,
146
+ AlertDialogAction,
147
+ AlertDialogCancel,
148
+ AlertDialogContent,
149
+ AlertDialogDescription,
150
+ AlertDialogFooter,
151
+ AlertDialogHeader,
152
+ AlertDialogOverlay,
153
+ AlertDialogPortal,
154
+ AlertDialogTitle,
155
+ AlertDialogTrigger,
156
+ };
@@ -0,0 +1,58 @@
1
+ import { cn } from '@tuturuuu/utils/format';
2
+ import { type VariantProps, cva } from 'class-variance-authority';
3
+ import * as React from 'react';
4
+
5
+ const alertVariants = cva(
6
+ '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',
7
+ {
8
+ variants: {
9
+ variant: {
10
+ default: 'bg-background text-foreground',
11
+ destructive:
12
+ 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
13
+ },
14
+ },
15
+ defaultVariants: {
16
+ variant: 'default',
17
+ },
18
+ }
19
+ );
20
+
21
+ const Alert = React.forwardRef<
22
+ HTMLDivElement,
23
+ React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
24
+ >(({ className, variant, ...props }, ref) => (
25
+ <div
26
+ ref={ref}
27
+ role="alert"
28
+ className={cn(alertVariants({ variant }), className)}
29
+ {...props}
30
+ />
31
+ ));
32
+ Alert.displayName = 'Alert';
33
+
34
+ const AlertTitle = React.forwardRef<
35
+ HTMLParagraphElement,
36
+ React.HTMLAttributes<HTMLHeadingElement>
37
+ >(({ className, ...props }, ref) => (
38
+ <h5
39
+ ref={ref}
40
+ className={cn('mb-1 leading-none font-medium tracking-tight', className)}
41
+ {...props}
42
+ />
43
+ ));
44
+ AlertTitle.displayName = 'AlertTitle';
45
+
46
+ const AlertDescription = React.forwardRef<
47
+ HTMLParagraphElement,
48
+ React.HTMLAttributes<HTMLParagraphElement>
49
+ >(({ className, ...props }, ref) => (
50
+ <div
51
+ ref={ref}
52
+ className={cn('text-sm [&_p]:leading-relaxed', className)}
53
+ {...props}
54
+ />
55
+ ));
56
+ AlertDescription.displayName = 'AlertDescription';
57
+
58
+ export { Alert, AlertDescription, AlertTitle };
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+
3
+ import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
4
+
5
+ function AspectRatio({
6
+ ...props
7
+ }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
8
+ return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />;
9
+ }
10
+
11
+ export { AspectRatio };
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+
3
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
4
+ import { cn } from '@tuturuuu/utils/format';
5
+ import * as React from 'react';
6
+
7
+ function Avatar({
8
+ className,
9
+ ...props
10
+ }: React.ComponentProps<typeof AvatarPrimitive.Root>) {
11
+ return (
12
+ <AvatarPrimitive.Root
13
+ data-slot="avatar"
14
+ className={cn(
15
+ 'relative flex size-8 shrink-0 overflow-hidden rounded-full',
16
+ className
17
+ )}
18
+ {...props}
19
+ />
20
+ );
21
+ }
22
+
23
+ function AvatarImage({
24
+ className,
25
+ ...props
26
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
27
+ return (
28
+ <AvatarPrimitive.Image
29
+ data-slot="avatar-image"
30
+ className={cn('aspect-square size-full', className)}
31
+ {...props}
32
+ />
33
+ );
34
+ }
35
+
36
+ function AvatarFallback({
37
+ className,
38
+ ...props
39
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
40
+ return (
41
+ <AvatarPrimitive.Fallback
42
+ data-slot="avatar-fallback"
43
+ className={cn(
44
+ 'flex size-full items-center justify-center rounded-full bg-muted',
45
+ className
46
+ )}
47
+ {...props}
48
+ />
49
+ );
50
+ }
51
+
52
+ export { Avatar, AvatarFallback, AvatarImage };
@@ -0,0 +1,49 @@
1
+ import { Slot } from '@radix-ui/react-slot';
2
+ import { cn } from '@tuturuuu/utils/format';
3
+ import { type VariantProps, cva } from 'class-variance-authority';
4
+ import * as React from 'react';
5
+
6
+ const badgeVariants = cva(
7
+ 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-semibold w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0 transition-[color,box-shadow]',
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default:
12
+ 'border-transparent bg-primary text-primary-foreground shadow-sm [a&]:hover:bg-primary/90',
13
+ secondary:
14
+ 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
15
+ destructive:
16
+ 'border-transparent bg-destructive text-destructive-foreground shadow-sm [a&]:hover:bg-destructive/90',
17
+ outline:
18
+ 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
19
+ success:
20
+ 'border-transparent bg-green-500 text-white hover:bg-green-600',
21
+ warning:
22
+ 'border-transparent bg-yellow-500 text-white hover:bg-yellow-600',
23
+ },
24
+ },
25
+ defaultVariants: {
26
+ variant: 'default',
27
+ },
28
+ }
29
+ );
30
+
31
+ function Badge({
32
+ className,
33
+ variant,
34
+ asChild = false,
35
+ ...props
36
+ }: React.ComponentProps<'span'> &
37
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
38
+ const Comp = asChild ? Slot : 'span';
39
+
40
+ return (
41
+ <Comp
42
+ data-slot="badge"
43
+ className={cn(badgeVariants({ variant }), className)}
44
+ {...props}
45
+ />
46
+ );
47
+ }
48
+
49
+ export { Badge, badgeVariants };