@carbonid1/design-system 5.1.0 → 5.2.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/dist/Badge/Badge.d.ts +6 -0
- package/dist/Badge/Badge.js +23 -0
- package/{src/Badge/Badge.types.ts → dist/Badge/Badge.types.d.ts} +8 -11
- package/dist/Badge/Badge.types.js +1 -0
- package/dist/Button/Button.d.ts +7 -0
- package/dist/Button/Button.js +34 -0
- package/dist/Button/Button.types.d.ts +8 -0
- package/dist/Button/Button.types.js +1 -0
- package/dist/ContextMenu/ContextMenu.d.ts +56 -0
- package/dist/ContextMenu/ContextMenu.js +40 -0
- package/dist/Kbd/Kbd.d.ts +6 -0
- package/dist/Kbd/Kbd.js +38 -0
- package/dist/Kbd/Kbd.types.d.ts +8 -0
- package/dist/Kbd/Kbd.types.js +1 -0
- package/dist/ProgressRing/ProgressRing.consts.d.ts +4 -0
- package/dist/ProgressRing/ProgressRing.consts.js +4 -0
- package/dist/ProgressRing/ProgressRing.d.ts +10 -0
- package/dist/ProgressRing/ProgressRing.js +12 -0
- package/dist/Select/Select.d.ts +2 -0
- package/dist/Select/Select.js +85 -0
- package/dist/Select/Select.types.d.ts +26 -0
- package/dist/Select/Select.types.js +1 -0
- package/dist/Slider/Slider.d.ts +13 -0
- package/dist/Slider/Slider.js +5 -0
- package/dist/ThemeCycler/ThemeCycler.d.ts +1 -0
- package/dist/ThemeCycler/ThemeCycler.js +30 -0
- package/dist/ThemeProvider/ThemeProvider.d.ts +5 -0
- package/dist/ThemeProvider/ThemeProvider.js +4 -0
- package/dist/Toaster/Toaster.d.ts +2 -0
- package/dist/Toaster/Toaster.js +4 -0
- package/dist/Tooltip/Tooltip.d.ts +15 -0
- package/dist/Tooltip/Tooltip.js +59 -0
- package/dist/helpers/cn/cn.d.ts +2 -0
- package/dist/helpers/cn/cn.js +5 -0
- package/dist/helpers/getModKey/getModKey.d.ts +1 -0
- package/dist/helpers/getModKey/getModKey.js +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +16 -0
- package/package.json +17 -35
- package/themes/dashboard.css +4 -2
- package/themes/reader.css +4 -2
- package/src/Badge/Badge.tsx +0 -53
- package/src/Button/Button.tsx +0 -67
- package/src/Button/Button.types.ts +0 -11
- package/src/ContextMenu/ContextMenu.tsx +0 -159
- package/src/Kbd/Kbd.tsx +0 -56
- package/src/Kbd/Kbd.types.ts +0 -10
- package/src/ProgressRing/ProgressRing.consts.ts +0 -4
- package/src/ProgressRing/ProgressRing.tsx +0 -68
- package/src/Select/Select.test.tsx +0 -129
- package/src/Select/Select.tsx +0 -156
- package/src/Select/Select.types.ts +0 -30
- package/src/Slider/Slider.test.tsx +0 -29
- package/src/Slider/Slider.tsx +0 -53
- package/src/ThemeCycler/ThemeCycler.tsx +0 -37
- package/src/ThemeProvider/ThemeProvider.tsx +0 -18
- package/src/Toaster/Toaster.tsx +0 -7
- package/src/Tooltip/Tooltip.tsx +0 -107
- package/src/helpers/cn/cn.ts +0 -6
- package/src/helpers/getModKey/getModKey.test.ts +0 -23
- package/src/helpers/getModKey/getModKey.ts +0 -2
- package/src/index.ts +0 -36
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { Badge, badgeVariants } from './Badge/Badge';
|
|
2
|
+
export type { BadgeProps } from './Badge/Badge.types';
|
|
3
|
+
export { Button, buttonVariants } from './Button/Button';
|
|
4
|
+
export type { ButtonProps } from './Button/Button.types';
|
|
5
|
+
export { Kbd, kbdVariants } from './Kbd/Kbd';
|
|
6
|
+
export type { KbdProps } from './Kbd/Kbd.types';
|
|
7
|
+
export { ProgressRing } from './ProgressRing/ProgressRing';
|
|
8
|
+
export { Slider } from './Slider/Slider';
|
|
9
|
+
export { ContextMenu } from './ContextMenu/ContextMenu';
|
|
10
|
+
export { Select } from './Select/Select';
|
|
11
|
+
export type { SelectOption, SelectGroup, SelectOptionState, SelectProps, } from './Select/Select.types';
|
|
12
|
+
export { Tooltip } from './Tooltip/Tooltip';
|
|
13
|
+
export { ThemeProvider } from './ThemeProvider/ThemeProvider';
|
|
14
|
+
export { ThemeCycler } from './ThemeCycler/ThemeCycler';
|
|
15
|
+
export { Toaster } from './Toaster/Toaster';
|
|
16
|
+
export { toast } from 'sonner';
|
|
17
|
+
export { useTheme } from 'next-themes';
|
|
18
|
+
export { cn } from './helpers/cn/cn';
|
|
19
|
+
export { getModKey } from './helpers/getModKey/getModKey';
|
|
20
|
+
export { cva } from 'class-variance-authority';
|
|
21
|
+
export type { VariantProps } from 'class-variance-authority';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { Badge, badgeVariants } from './Badge/Badge';
|
|
2
|
+
export { Button, buttonVariants } from './Button/Button';
|
|
3
|
+
export { Kbd, kbdVariants } from './Kbd/Kbd';
|
|
4
|
+
export { ProgressRing } from './ProgressRing/ProgressRing';
|
|
5
|
+
export { Slider } from './Slider/Slider';
|
|
6
|
+
export { ContextMenu } from './ContextMenu/ContextMenu';
|
|
7
|
+
export { Select } from './Select/Select';
|
|
8
|
+
export { Tooltip } from './Tooltip/Tooltip';
|
|
9
|
+
export { ThemeProvider } from './ThemeProvider/ThemeProvider';
|
|
10
|
+
export { ThemeCycler } from './ThemeCycler/ThemeCycler';
|
|
11
|
+
export { Toaster } from './Toaster/Toaster';
|
|
12
|
+
export { toast } from 'sonner';
|
|
13
|
+
export { useTheme } from 'next-themes';
|
|
14
|
+
export { cn } from './helpers/cn/cn';
|
|
15
|
+
export { getModKey } from './helpers/getModKey/getModKey';
|
|
16
|
+
export { cva } from 'class-variance-authority';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carbonid1/design-system",
|
|
3
|
-
"version": "5.1
|
|
3
|
+
"version": "5.2.1",
|
|
4
4
|
"description": "Shared React UI primitives + design tokens (themes, postcss config)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
"**/*.css"
|
|
15
15
|
],
|
|
16
16
|
"exports": {
|
|
17
|
-
".":
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
18
21
|
"./themes/reader": "./themes/reader.css",
|
|
19
22
|
"./themes/dashboard": "./themes/dashboard.css",
|
|
20
23
|
"./postcss": "./postcss.mjs"
|
|
21
24
|
},
|
|
22
25
|
"files": [
|
|
23
|
-
"
|
|
26
|
+
"dist",
|
|
24
27
|
"themes",
|
|
25
28
|
"postcss.mjs",
|
|
26
29
|
"skills",
|
|
@@ -28,43 +31,26 @@
|
|
|
28
31
|
],
|
|
29
32
|
"dependencies": {
|
|
30
33
|
"@tailwindcss/postcss": "^4.2.0",
|
|
34
|
+
"class-variance-authority": "^0.7.1",
|
|
35
|
+
"clsx": "^2.1.1",
|
|
36
|
+
"lucide-react": "^1.8.0",
|
|
31
37
|
"next-themes": "^0.4.6",
|
|
38
|
+
"react-hotkeys-hook": "^5.2.4",
|
|
32
39
|
"sonner": "^2.0.7",
|
|
40
|
+
"tailwind-merge": "^3.5.0",
|
|
33
41
|
"tailwindcss": "^4.2.0"
|
|
34
42
|
},
|
|
35
43
|
"peerDependencies": {
|
|
36
|
-
"@base-ui/react": "^1.
|
|
37
|
-
"class-variance-authority": "^0.7.0",
|
|
38
|
-
"clsx": "^2.0.0",
|
|
39
|
-
"lucide-react": ">=0.400.0",
|
|
44
|
+
"@base-ui/react": "^1.4.0",
|
|
40
45
|
"postcss": "^8.0.0",
|
|
41
46
|
"react": "^19.0.0",
|
|
42
|
-
"react-dom": "^19.0.0"
|
|
43
|
-
"react-hotkeys-hook": "^5.0.0",
|
|
44
|
-
"tailwind-merge": "^3.0.0"
|
|
45
|
-
},
|
|
46
|
-
"peerDependenciesMeta": {
|
|
47
|
-
"@base-ui/react": {
|
|
48
|
-
"optional": true
|
|
49
|
-
},
|
|
50
|
-
"class-variance-authority": {
|
|
51
|
-
"optional": true
|
|
52
|
-
},
|
|
53
|
-
"clsx": {
|
|
54
|
-
"optional": true
|
|
55
|
-
},
|
|
56
|
-
"lucide-react": {
|
|
57
|
-
"optional": true
|
|
58
|
-
},
|
|
59
|
-
"tailwind-merge": {
|
|
60
|
-
"optional": true
|
|
61
|
-
}
|
|
47
|
+
"react-dom": "^19.0.0"
|
|
62
48
|
},
|
|
63
49
|
"publishConfig": {
|
|
64
50
|
"access": "public"
|
|
65
51
|
},
|
|
66
52
|
"devDependencies": {
|
|
67
|
-
"@base-ui/react": "^1.4.
|
|
53
|
+
"@base-ui/react": "^1.4.1",
|
|
68
54
|
"@storybook/addon-docs": "^10.3.5",
|
|
69
55
|
"@storybook/addon-themes": "^10.3.5",
|
|
70
56
|
"@storybook/addon-vitest": "^10.3.5",
|
|
@@ -76,24 +62,20 @@
|
|
|
76
62
|
"@types/react-dom": "^19.2.3",
|
|
77
63
|
"@vitejs/plugin-react": "^6.0.1",
|
|
78
64
|
"@vitest/browser-playwright": "^4.1.4",
|
|
79
|
-
"class-variance-authority": "^0.7.1",
|
|
80
|
-
"clsx": "^2.1.1",
|
|
81
65
|
"jsdom": "^29.0.2",
|
|
82
|
-
"lucide-react": "^1.8.0",
|
|
83
66
|
"next-themes": "^0.4.6",
|
|
84
67
|
"playwright": "^1.59.1",
|
|
85
|
-
"react": "^19.2.
|
|
86
|
-
"react-dom": "^19.2.
|
|
87
|
-
"react-hotkeys-hook": "^5.2.4",
|
|
68
|
+
"react": "^19.2.6",
|
|
69
|
+
"react-dom": "^19.2.6",
|
|
88
70
|
"sonner": "^2.0.7",
|
|
89
71
|
"storybook": "^10.3.5",
|
|
90
|
-
"tailwind-merge": "^3.5.0",
|
|
91
72
|
"tailwindcss": "^4.2.2",
|
|
92
73
|
"vite": "^8.0.8",
|
|
93
74
|
"vitest": "^4.1.4",
|
|
94
75
|
"@carbonid1/tsconfig": "0.3.0"
|
|
95
76
|
},
|
|
96
77
|
"scripts": {
|
|
78
|
+
"build": "tsc",
|
|
97
79
|
"storybook": "storybook dev -p 6006",
|
|
98
80
|
"build-storybook": "storybook build",
|
|
99
81
|
"test": "vitest --run",
|
package/themes/dashboard.css
CHANGED
|
@@ -18,8 +18,10 @@
|
|
|
18
18
|
@import 'tailwindcss';
|
|
19
19
|
|
|
20
20
|
/* Scan design-system components so consumers pick up classes used inside
|
|
21
|
-
* Button/Kbd/etc. — Tailwind v4 skips node_modules by default.
|
|
22
|
-
|
|
21
|
+
* Button/Kbd/etc. — Tailwind v4 skips node_modules by default. Point at the
|
|
22
|
+
* shipped `dist/` (the only source that lands in installed `node_modules`),
|
|
23
|
+
* not `src/` which isn't in the published `files`. */
|
|
24
|
+
@source "../dist/**/*.js";
|
|
23
25
|
|
|
24
26
|
@custom-variant dark (&:is(.dark *));
|
|
25
27
|
|
package/themes/reader.css
CHANGED
|
@@ -40,8 +40,10 @@
|
|
|
40
40
|
@import 'tailwindcss';
|
|
41
41
|
|
|
42
42
|
/* Scan design-system components so consumers pick up classes used inside
|
|
43
|
-
* Button/Kbd/etc. — Tailwind v4 skips node_modules by default.
|
|
44
|
-
|
|
43
|
+
* Button/Kbd/etc. — Tailwind v4 skips node_modules by default. Point at the
|
|
44
|
+
* shipped `dist/` (the only source that lands in installed `node_modules`),
|
|
45
|
+
* not `src/` which isn't in the published `files`. */
|
|
46
|
+
@source "../dist/**/*.js";
|
|
45
47
|
|
|
46
48
|
@custom-variant dark (&:is(.dark *));
|
|
47
49
|
|
package/src/Badge/Badge.tsx
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { cn } from '../helpers/cn/cn'
|
|
4
|
-
import { cva } from 'class-variance-authority'
|
|
5
|
-
import { X } from 'lucide-react'
|
|
6
|
-
import type { BadgeProps } from './Badge.types'
|
|
7
|
-
|
|
8
|
-
const badgeVariants = cva(
|
|
9
|
-
'inline-flex max-w-full min-w-0 items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium',
|
|
10
|
-
{
|
|
11
|
-
variants: {
|
|
12
|
-
variant: {
|
|
13
|
-
default: 'bg-muted text-muted-foreground',
|
|
14
|
-
primary: 'bg-primary-border/30 text-primary',
|
|
15
|
-
success: 'bg-success/15 text-success-foreground',
|
|
16
|
-
attention: 'bg-attention-muted text-attention-foreground',
|
|
17
|
-
destructive: 'bg-destructive/15 text-destructive',
|
|
18
|
-
highlight: 'bg-highlight-muted text-highlight-foreground',
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
defaultVariants: { variant: 'default' },
|
|
22
|
-
},
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
const Badge = ({
|
|
26
|
-
className,
|
|
27
|
-
variant,
|
|
28
|
-
onRemove,
|
|
29
|
-
removeLabel,
|
|
30
|
-
children,
|
|
31
|
-
...props
|
|
32
|
-
}: BadgeProps) => {
|
|
33
|
-
const resolvedRemoveLabel =
|
|
34
|
-
removeLabel ?? (typeof children === 'string' ? `Remove ${children}` : 'Remove')
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<span className={cn(badgeVariants({ variant }), className)} {...props}>
|
|
38
|
-
{onRemove ? <span className="truncate">{children}</span> : children}
|
|
39
|
-
{onRemove && (
|
|
40
|
-
<button
|
|
41
|
-
type="button"
|
|
42
|
-
aria-label={resolvedRemoveLabel}
|
|
43
|
-
onClick={onRemove}
|
|
44
|
-
className="-me-0.5 inline-flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-full opacity-70 hover:opacity-100 focus-visible:ring-2 focus-visible:ring-current focus-visible:ring-offset-1 focus-visible:ring-offset-transparent focus-visible:outline-none"
|
|
45
|
-
>
|
|
46
|
-
<X className="size-3" aria-hidden="true" />
|
|
47
|
-
</button>
|
|
48
|
-
)}
|
|
49
|
-
</span>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export { Badge, badgeVariants }
|
package/src/Button/Button.tsx
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { cn } from '../helpers/cn/cn'
|
|
4
|
-
import { Button as ButtonPrimitive } from '@base-ui/react/button'
|
|
5
|
-
import { cva } from 'class-variance-authority'
|
|
6
|
-
import { Loader2 } from 'lucide-react'
|
|
7
|
-
import type { ButtonProps } from './Button.types'
|
|
8
|
-
|
|
9
|
-
const buttonVariants = cva(
|
|
10
|
-
"group/button inline-flex shrink-0 items-center justify-center gap-2 rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-hidden select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
11
|
-
{
|
|
12
|
-
variants: {
|
|
13
|
-
variant: {
|
|
14
|
-
ghost: 'hover:bg-accent aria-expanded:bg-accent dark:hover:bg-accent/50',
|
|
15
|
-
primary: 'bg-primary text-primary-foreground font-medium hover:bg-primary/90',
|
|
16
|
-
outline:
|
|
17
|
-
'border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50',
|
|
18
|
-
destructive:
|
|
19
|
-
'bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40',
|
|
20
|
-
attention: 'text-attention-foreground hover:bg-attention-muted',
|
|
21
|
-
subtle: 'text-muted-foreground hover:text-primary',
|
|
22
|
-
danger: 'text-muted-foreground hover:text-destructive',
|
|
23
|
-
link: 'text-primary underline-offset-4 hover:underline',
|
|
24
|
-
},
|
|
25
|
-
size: {
|
|
26
|
-
small: 'h-7 gap-1 px-2.5 text-[0.8rem]',
|
|
27
|
-
default: 'h-8 gap-1.5 px-2.5',
|
|
28
|
-
large: 'h-9 gap-1.5 px-3',
|
|
29
|
-
icon: 'size-8 rounded-full',
|
|
30
|
-
smallIcon: 'size-6 rounded-full',
|
|
31
|
-
largeIcon: 'size-12 rounded-full',
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
defaultVariants: {
|
|
35
|
-
variant: 'ghost',
|
|
36
|
-
size: 'default',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
const Button = ({
|
|
42
|
-
className,
|
|
43
|
-
variant,
|
|
44
|
-
size,
|
|
45
|
-
fullWidth,
|
|
46
|
-
loading,
|
|
47
|
-
disabled,
|
|
48
|
-
children,
|
|
49
|
-
...props
|
|
50
|
-
}: ButtonProps) => (
|
|
51
|
-
<ButtonPrimitive
|
|
52
|
-
data-slot="button"
|
|
53
|
-
className={cn(
|
|
54
|
-
buttonVariants({ variant, size }),
|
|
55
|
-
fullWidth && 'w-full justify-start',
|
|
56
|
-
className,
|
|
57
|
-
)}
|
|
58
|
-
disabled={disabled ?? loading}
|
|
59
|
-
aria-busy={loading ?? undefined}
|
|
60
|
-
{...props}
|
|
61
|
-
>
|
|
62
|
-
{loading && <Loader2 className="size-4 animate-spin" aria-hidden="true" />}
|
|
63
|
-
{children}
|
|
64
|
-
</ButtonPrimitive>
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
export { Button, buttonVariants }
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Button as ButtonPrimitive } from '@base-ui/react/button'
|
|
2
|
-
import type { VariantProps } from 'class-variance-authority'
|
|
3
|
-
import type { buttonVariants } from './Button'
|
|
4
|
-
|
|
5
|
-
type ButtonProps = ButtonPrimitive.Props &
|
|
6
|
-
VariantProps<typeof buttonVariants> & {
|
|
7
|
-
fullWidth?: boolean
|
|
8
|
-
loading?: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type { ButtonProps }
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { ContextMenu as BaseContextMenu } from '@base-ui/react/context-menu'
|
|
4
|
-
import { ChevronRight } from 'lucide-react'
|
|
5
|
-
import type { ComponentPropsWithoutRef, Ref } from 'react'
|
|
6
|
-
import { cn } from '../helpers/cn/cn'
|
|
7
|
-
|
|
8
|
-
type BasePopupProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Popup>
|
|
9
|
-
type BasePositionerProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Positioner>
|
|
10
|
-
type BaseItemProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Item>
|
|
11
|
-
type BaseSeparatorProps = ComponentPropsWithoutRef<typeof BaseContextMenu.Separator>
|
|
12
|
-
type BaseGroupLabelProps = ComponentPropsWithoutRef<typeof BaseContextMenu.GroupLabel>
|
|
13
|
-
type BaseSubmenuTriggerProps = ComponentPropsWithoutRef<typeof BaseContextMenu.SubmenuTrigger>
|
|
14
|
-
type BaseCheckboxItemProps = ComponentPropsWithoutRef<typeof BaseContextMenu.CheckboxItem>
|
|
15
|
-
type BaseRadioItemProps = ComponentPropsWithoutRef<typeof BaseContextMenu.RadioItem>
|
|
16
|
-
|
|
17
|
-
type ItemVariant = 'default' | 'destructive'
|
|
18
|
-
|
|
19
|
-
type PositionerProps = BasePositionerProps & { ref?: Ref<HTMLDivElement> }
|
|
20
|
-
type PopupProps = BasePopupProps & { ref?: Ref<HTMLDivElement> }
|
|
21
|
-
type SeparatorProps = BaseSeparatorProps & { ref?: Ref<HTMLDivElement> }
|
|
22
|
-
type GroupLabelProps = BaseGroupLabelProps & { ref?: Ref<HTMLDivElement> }
|
|
23
|
-
type ItemProps = BaseItemProps & { ref?: Ref<HTMLDivElement>; variant?: ItemVariant }
|
|
24
|
-
type CheckboxItemProps = BaseCheckboxItemProps & { ref?: Ref<HTMLDivElement> }
|
|
25
|
-
type RadioItemProps = BaseRadioItemProps & { ref?: Ref<HTMLDivElement> }
|
|
26
|
-
type SubmenuTriggerProps = BaseSubmenuTriggerProps & { ref?: Ref<HTMLDivElement> }
|
|
27
|
-
|
|
28
|
-
const popupClasses =
|
|
29
|
-
'bg-popover text-popover-foreground border-border z-50 min-w-45 origin-[var(--transform-origin)] rounded-lg border py-1 shadow-lg outline-hidden transition-[transform,opacity] data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[starting-style]:scale-95 data-[starting-style]:opacity-0'
|
|
30
|
-
|
|
31
|
-
const itemBaseClasses =
|
|
32
|
-
'relative flex h-7 cursor-default items-center gap-1.5 px-2.5 text-[0.8rem] outline-hidden select-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-4 data-[disabled]:pointer-events-none data-[disabled]:opacity-50'
|
|
33
|
-
|
|
34
|
-
const itemVariantClasses: Record<ItemVariant, string> = {
|
|
35
|
-
default:
|
|
36
|
-
'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground',
|
|
37
|
-
destructive:
|
|
38
|
-
'text-destructive data-[highlighted]:bg-destructive/10 data-[highlighted]:text-destructive',
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const Positioner = ({ className, sideOffset = 4, ...props }: PositionerProps) => (
|
|
42
|
-
<BaseContextMenu.Positioner
|
|
43
|
-
sideOffset={sideOffset}
|
|
44
|
-
className={cn('z-50 outline-hidden', className)}
|
|
45
|
-
{...props}
|
|
46
|
-
/>
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
const Popup = ({ className, ...props }: PopupProps) => (
|
|
50
|
-
<BaseContextMenu.Popup className={cn(popupClasses, className)} {...props} />
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
const Item = ({ className, variant = 'default', ...props }: ItemProps) => (
|
|
54
|
-
<BaseContextMenu.Item
|
|
55
|
-
className={cn(itemBaseClasses, itemVariantClasses[variant], className)}
|
|
56
|
-
{...props}
|
|
57
|
-
/>
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
const Separator = ({ className, ...props }: SeparatorProps) => (
|
|
61
|
-
<BaseContextMenu.Separator
|
|
62
|
-
className={cn('bg-border my-1 h-px', className)}
|
|
63
|
-
{...props}
|
|
64
|
-
/>
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
const GroupLabel = ({ className, ...props }: GroupLabelProps) => (
|
|
68
|
-
<BaseContextMenu.GroupLabel
|
|
69
|
-
className={cn('text-muted-foreground px-2.5 py-1 text-xs', className)}
|
|
70
|
-
{...props}
|
|
71
|
-
/>
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
const CheckboxItem = ({ className, children, ...props }: CheckboxItemProps) => (
|
|
75
|
-
<BaseContextMenu.CheckboxItem
|
|
76
|
-
className={cn(itemBaseClasses, itemVariantClasses.default, 'pl-7', className)}
|
|
77
|
-
{...props}
|
|
78
|
-
>
|
|
79
|
-
<span
|
|
80
|
-
aria-hidden
|
|
81
|
-
className="absolute left-2 flex size-3.5 items-center justify-center"
|
|
82
|
-
>
|
|
83
|
-
<BaseContextMenu.CheckboxItemIndicator className="size-3.5">
|
|
84
|
-
<CheckIcon />
|
|
85
|
-
</BaseContextMenu.CheckboxItemIndicator>
|
|
86
|
-
</span>
|
|
87
|
-
{children}
|
|
88
|
-
</BaseContextMenu.CheckboxItem>
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
const RadioItem = ({ className, children, ...props }: RadioItemProps) => (
|
|
92
|
-
<BaseContextMenu.RadioItem
|
|
93
|
-
className={cn(itemBaseClasses, itemVariantClasses.default, 'pl-7', className)}
|
|
94
|
-
{...props}
|
|
95
|
-
>
|
|
96
|
-
<span
|
|
97
|
-
aria-hidden
|
|
98
|
-
className="absolute left-2 flex size-3.5 items-center justify-center"
|
|
99
|
-
>
|
|
100
|
-
<BaseContextMenu.RadioItemIndicator className="size-3.5">
|
|
101
|
-
<DotIcon />
|
|
102
|
-
</BaseContextMenu.RadioItemIndicator>
|
|
103
|
-
</span>
|
|
104
|
-
{children}
|
|
105
|
-
</BaseContextMenu.RadioItem>
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
const SubmenuTrigger = ({ className, children, ...props }: SubmenuTriggerProps) => (
|
|
109
|
-
<BaseContextMenu.SubmenuTrigger
|
|
110
|
-
className={cn(
|
|
111
|
-
itemBaseClasses,
|
|
112
|
-
itemVariantClasses.default,
|
|
113
|
-
'data-popup-open:bg-accent data-popup-open:text-accent-foreground pr-2',
|
|
114
|
-
className,
|
|
115
|
-
)}
|
|
116
|
-
{...props}
|
|
117
|
-
>
|
|
118
|
-
{children}
|
|
119
|
-
<ChevronRight className="ml-auto size-4 opacity-60" aria-hidden />
|
|
120
|
-
</BaseContextMenu.SubmenuTrigger>
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
const CheckIcon = () => (
|
|
124
|
-
<svg viewBox="0 0 14 14" fill="none" className="size-3.5">
|
|
125
|
-
<path
|
|
126
|
-
d="M3 7.5 6 10.5 11 4.5"
|
|
127
|
-
stroke="currentColor"
|
|
128
|
-
strokeWidth="1.75"
|
|
129
|
-
strokeLinecap="round"
|
|
130
|
-
strokeLinejoin="round"
|
|
131
|
-
/>
|
|
132
|
-
</svg>
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
const DotIcon = () => (
|
|
136
|
-
<svg viewBox="0 0 14 14" className="size-3.5">
|
|
137
|
-
<circle cx="7" cy="7" r="3" fill="currentColor" />
|
|
138
|
-
</svg>
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
export const ContextMenu = {
|
|
142
|
-
Root: BaseContextMenu.Root,
|
|
143
|
-
Trigger: BaseContextMenu.Trigger,
|
|
144
|
-
Portal: BaseContextMenu.Portal,
|
|
145
|
-
Backdrop: BaseContextMenu.Backdrop,
|
|
146
|
-
Positioner,
|
|
147
|
-
Popup,
|
|
148
|
-
Arrow: BaseContextMenu.Arrow,
|
|
149
|
-
Group: BaseContextMenu.Group,
|
|
150
|
-
GroupLabel,
|
|
151
|
-
Separator,
|
|
152
|
-
Item,
|
|
153
|
-
LinkItem: BaseContextMenu.LinkItem,
|
|
154
|
-
CheckboxItem,
|
|
155
|
-
RadioGroup: BaseContextMenu.RadioGroup,
|
|
156
|
-
RadioItem,
|
|
157
|
-
SubmenuRoot: BaseContextMenu.SubmenuRoot,
|
|
158
|
-
SubmenuTrigger,
|
|
159
|
-
}
|
package/src/Kbd/Kbd.tsx
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { getModKey } from '../helpers/getModKey/getModKey'
|
|
4
|
-
import { cn } from '../helpers/cn/cn'
|
|
5
|
-
import { cva } from 'class-variance-authority'
|
|
6
|
-
import type { KbdProps } from './Kbd.types'
|
|
7
|
-
|
|
8
|
-
const MOD_SYMBOLS: Record<string, string> = { Cmd: '⌘', Ctrl: 'Ctrl' }
|
|
9
|
-
|
|
10
|
-
const KEY_SYMBOLS: Record<string, string> = {
|
|
11
|
-
shift: '⇧',
|
|
12
|
-
alt: '⌥',
|
|
13
|
-
enter: '↵',
|
|
14
|
-
backspace: '⌫',
|
|
15
|
-
escape: 'Esc',
|
|
16
|
-
space: '␣',
|
|
17
|
-
left: '←',
|
|
18
|
-
right: '→',
|
|
19
|
-
up: '↑',
|
|
20
|
-
down: '↓',
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const resolveKey = (key: string): string => {
|
|
24
|
-
const lower = key.toLowerCase()
|
|
25
|
-
if (lower === 'mod') return MOD_SYMBOLS[getModKey()] ?? 'Ctrl'
|
|
26
|
-
return KEY_SYMBOLS[lower] ?? key
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const kbdVariants = cva(
|
|
30
|
-
'inline-flex items-center justify-center rounded-sm border font-mono leading-none select-none',
|
|
31
|
-
{
|
|
32
|
-
variants: {
|
|
33
|
-
size: {
|
|
34
|
-
sm: 'min-w-4 px-1 py-0.5 text-[10px] border-foreground/10 bg-foreground/10',
|
|
35
|
-
default: 'min-w-5 px-1.5 py-1 text-[11px] border-border bg-muted',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
defaultVariants: { size: 'default' },
|
|
39
|
-
},
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
const Kbd = ({ keys, size, className }: KbdProps) => {
|
|
43
|
-
const keyList = Array.isArray(keys) ? keys : [keys]
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<span className="inline-flex items-center gap-0.5" role="presentation">
|
|
47
|
-
{keyList.map((key, i) => (
|
|
48
|
-
<kbd key={i} className={cn(kbdVariants({ size }), className)}>
|
|
49
|
-
{resolveKey(key)}
|
|
50
|
-
</kbd>
|
|
51
|
-
))}
|
|
52
|
-
</span>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export { Kbd, kbdVariants }
|
package/src/Kbd/Kbd.types.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { VariantProps } from 'class-variance-authority'
|
|
2
|
-
import type { kbdVariants } from './Kbd'
|
|
3
|
-
|
|
4
|
-
type KbdProps = {
|
|
5
|
-
/** Single key or array of keys for combos. 'mod' auto-resolves to Cmd/Ctrl. */
|
|
6
|
-
keys: string | string[]
|
|
7
|
-
className?: string
|
|
8
|
-
} & VariantProps<typeof kbdVariants>
|
|
9
|
-
|
|
10
|
-
export type { KbdProps }
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { CIRCUMFERENCE, RADIUS, RING_SIZE, STROKE_WIDTH } from './ProgressRing.consts'
|
|
2
|
-
|
|
3
|
-
type ProgressRingProps = {
|
|
4
|
-
progress: number
|
|
5
|
-
colorClass: string
|
|
6
|
-
label: string
|
|
7
|
-
animate?: boolean
|
|
8
|
-
pendingStyle?: 'none' | 'dashed'
|
|
9
|
-
testId?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const DASH_SEGMENT = CIRCUMFERENCE / 8
|
|
13
|
-
|
|
14
|
-
export const ProgressRing = ({
|
|
15
|
-
progress,
|
|
16
|
-
colorClass,
|
|
17
|
-
label,
|
|
18
|
-
animate = false,
|
|
19
|
-
pendingStyle = 'none',
|
|
20
|
-
testId,
|
|
21
|
-
}: ProgressRingProps) => {
|
|
22
|
-
const MIN_VISIBLE = 0.08
|
|
23
|
-
const visibleProgress = animate ? Math.max(progress, MIN_VISIBLE) : progress
|
|
24
|
-
const dashoffset = CIRCUMFERENCE * (1 - visibleProgress)
|
|
25
|
-
|
|
26
|
-
const shouldSpin = animate && progress < 0.15
|
|
27
|
-
const isDashed = !animate && pendingStyle === 'dashed'
|
|
28
|
-
const center = RING_SIZE / 2
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<svg
|
|
32
|
-
width={RING_SIZE}
|
|
33
|
-
height={RING_SIZE}
|
|
34
|
-
viewBox={`0 0 ${RING_SIZE} ${RING_SIZE}`}
|
|
35
|
-
role="img"
|
|
36
|
-
aria-label={label}
|
|
37
|
-
className={animate && !shouldSpin ? 'animate-buffer-pulse motion-reduce:animate-none' : ''}
|
|
38
|
-
>
|
|
39
|
-
{/* Track */}
|
|
40
|
-
<circle
|
|
41
|
-
cx={center}
|
|
42
|
-
cy={center}
|
|
43
|
-
r={RADIUS}
|
|
44
|
-
fill="none"
|
|
45
|
-
stroke="currentColor"
|
|
46
|
-
strokeWidth={STROKE_WIDTH}
|
|
47
|
-
className={`text-border ${isDashed ? 'animate-ring-drift motion-reduce:animate-none' : ''}`}
|
|
48
|
-
strokeDasharray={isDashed ? `${DASH_SEGMENT * 0.6} ${DASH_SEGMENT * 0.4}` : undefined}
|
|
49
|
-
style={isDashed ? { transformOrigin: `${center}px ${center}px` } : undefined}
|
|
50
|
-
/>
|
|
51
|
-
{/* Fill */}
|
|
52
|
-
<circle
|
|
53
|
-
data-testid={testId}
|
|
54
|
-
cx={center}
|
|
55
|
-
cy={center}
|
|
56
|
-
r={RADIUS}
|
|
57
|
-
fill="none"
|
|
58
|
-
stroke="currentColor"
|
|
59
|
-
strokeWidth={STROKE_WIDTH}
|
|
60
|
-
strokeDasharray={CIRCUMFERENCE}
|
|
61
|
-
strokeDashoffset={dashoffset}
|
|
62
|
-
strokeLinecap="round"
|
|
63
|
-
className={`${colorClass} transition-[stroke-dashoffset,color] duration-500 ${shouldSpin ? 'animate-ring-spin motion-reduce:animate-none' : ''}`}
|
|
64
|
-
style={{ transformOrigin: `${center}px ${center}px` }}
|
|
65
|
-
/>
|
|
66
|
-
</svg>
|
|
67
|
-
)
|
|
68
|
-
}
|