minka-ds 0.1.0

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 ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "minka-ds",
3
+ "version": "0.1.0",
4
+ "description": "Minka product design system — tokenized component library",
5
+ "license": "MIT",
6
+ "files": ["src", "tokens"],
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./tokens/*": "./tokens/*"
10
+ },
11
+ "peerDependencies": {
12
+ "react": ">=19",
13
+ "react-dom": ">=19"
14
+ },
15
+ "dependencies": {
16
+ "@base-ui/react": "^1.4.1",
17
+ "@tanstack/react-table": "^8.21.3",
18
+ "class-variance-authority": "^0.7.1",
19
+ "clsx": "^2.1.1",
20
+ "lucide-react": "^1.14.0",
21
+ "radix-ui": "^1.4.3",
22
+ "tailwind-merge": "^3.5.0",
23
+ "tw-animate-css": "^1.4.0"
24
+ }
25
+ }
@@ -0,0 +1,63 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { Slot } from "radix-ui"
4
+
5
+ import { cn } from "../../lib/utils"
6
+
7
+ const badgeVariants = cva(
8
+ "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden [border-radius:var(--radius-badge)] border px-2 py-0.5 text-label-sm whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 [&>svg]:pointer-events-none [&>svg]:size-3",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ "bg-[var(--color-bg-raised)] text-[var(--color-text-default)] border-transparent [a&]:hover:bg-[var(--color-action-secondary-hover)]",
14
+ filled:
15
+ "bg-[var(--color-action-primary-default)] text-[var(--color-action-primary-foreground)] border-transparent [a&]:hover:bg-[var(--color-action-primary-hover)]",
16
+ secondary:
17
+ "bg-[var(--color-bg-disabled)] text-[var(--color-text-default)] border-transparent",
18
+ destructive:
19
+ "bg-[var(--color-action-destructive-default)] text-[var(--color-action-destructive-foreground)] border-transparent focus-visible:ring-destructive/20 [a&]:hover:bg-[var(--color-action-destructive-hover)]",
20
+ success:
21
+ "bg-[var(--color-bg-success)] text-[var(--color-feedback-success)] border-transparent",
22
+ warning:
23
+ "bg-[var(--color-bg-warning)] text-[var(--color-text-default)] border-transparent",
24
+ error:
25
+ "bg-[var(--color-bg-error)] text-[var(--color-feedback-error)] border-transparent",
26
+ info:
27
+ "bg-[var(--color-bg-info)] text-[var(--color-feedback-info)] border-transparent",
28
+ pending:
29
+ "bg-[var(--color-bg-warning)] text-[var(--color-text-default)] border-transparent",
30
+ outline:
31
+ "border-[var(--color-border-default)] text-[var(--color-text-default)] [a&]:hover:bg-[var(--color-action-ghost-hover)]",
32
+ ghost:
33
+ "border-transparent text-[var(--color-text-default)] [a&]:hover:bg-[var(--color-action-ghost-hover)]",
34
+ link:
35
+ "border-transparent text-[var(--color-text-link)] underline-offset-4 [a&]:hover:text-[var(--color-text-link-hover)] [a&]:hover:underline",
36
+ },
37
+ },
38
+ defaultVariants: {
39
+ variant: "default",
40
+ },
41
+ }
42
+ )
43
+
44
+ function Badge({
45
+ className,
46
+ variant = "default",
47
+ asChild = false,
48
+ ...props
49
+ }: React.ComponentProps<"span"> &
50
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
51
+ const Comp = asChild ? Slot.Root : "span"
52
+
53
+ return (
54
+ <Comp
55
+ data-slot="badge"
56
+ data-variant={variant}
57
+ className={cn(badgeVariants({ variant }), className)}
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+
63
+ export { Badge, badgeVariants }
@@ -0,0 +1,109 @@
1
+ import * as React from "react"
2
+ import { ChevronRight, MoreHorizontal } from "lucide-react"
3
+ import { Slot } from "radix-ui"
4
+
5
+ import { cn } from "../../lib/utils"
6
+
7
+ function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
8
+ return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
9
+ }
10
+
11
+ function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
12
+ return (
13
+ <ol
14
+ data-slot="breadcrumb-list"
15
+ className={cn(
16
+ "flex flex-wrap items-center gap-1.5 text-body-sm break-words text-[var(--color-text-muted)] sm:gap-2.5",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ )
22
+ }
23
+
24
+ function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
25
+ return (
26
+ <li
27
+ data-slot="breadcrumb-item"
28
+ className={cn("inline-flex items-center gap-1.5", className)}
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function BreadcrumbLink({
35
+ asChild,
36
+ className,
37
+ ...props
38
+ }: React.ComponentProps<"a"> & {
39
+ asChild?: boolean
40
+ }) {
41
+ const Comp = asChild ? Slot.Root : "a"
42
+
43
+ return (
44
+ <Comp
45
+ data-slot="breadcrumb-link"
46
+ className={cn("transition-colors hover:text-[var(--color-text-default)]", className)}
47
+ {...props}
48
+ />
49
+ )
50
+ }
51
+
52
+ function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
53
+ return (
54
+ <span
55
+ data-slot="breadcrumb-page"
56
+ role="link"
57
+ aria-disabled="true"
58
+ aria-current="page"
59
+ className={cn("text-[var(--color-text-default)]", className)}
60
+ {...props}
61
+ />
62
+ )
63
+ }
64
+
65
+ function BreadcrumbSeparator({
66
+ children,
67
+ className,
68
+ ...props
69
+ }: React.ComponentProps<"li">) {
70
+ return (
71
+ <li
72
+ data-slot="breadcrumb-separator"
73
+ role="presentation"
74
+ aria-hidden="true"
75
+ className={cn("[&>svg]:size-3.5", className)}
76
+ {...props}
77
+ >
78
+ {children ?? <ChevronRight />}
79
+ </li>
80
+ )
81
+ }
82
+
83
+ function BreadcrumbEllipsis({
84
+ className,
85
+ ...props
86
+ }: React.ComponentProps<"span">) {
87
+ return (
88
+ <span
89
+ data-slot="breadcrumb-ellipsis"
90
+ role="presentation"
91
+ aria-hidden="true"
92
+ className={cn("flex size-9 items-center justify-center", className)}
93
+ {...props}
94
+ >
95
+ <MoreHorizontal className="size-4" />
96
+ <span className="sr-only">More</span>
97
+ </span>
98
+ )
99
+ }
100
+
101
+ export {
102
+ Breadcrumb,
103
+ BreadcrumbList,
104
+ BreadcrumbItem,
105
+ BreadcrumbLink,
106
+ BreadcrumbPage,
107
+ BreadcrumbSeparator,
108
+ BreadcrumbEllipsis,
109
+ }
@@ -0,0 +1,89 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+ import { Slot } from "radix-ui"
3
+
4
+ import { cn } from "../../lib/utils"
5
+ import { Separator } from "./separator"
6
+
7
+ const buttonGroupVariants = cva(
8
+ "flex w-fit items-stretch [border-radius:var(--radius-button)] has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
9
+ {
10
+ variants: {
11
+ orientation: {
12
+ horizontal:
13
+ "[&>*:not([data-slot=button-group]):not(:first-child)]:rounded-l-none [&>*:not([data-slot=button-group]):not(:first-child)]:border-l-0 [&>*:not([data-slot=button-group]):not(:last-child)]:rounded-r-none",
14
+ vertical:
15
+ "flex-col [&>*:not([data-slot=button-group]):not(:first-child)]:rounded-t-none [&>*:not([data-slot=button-group]):not(:first-child)]:border-t-0 [&>*:not([data-slot=button-group]):not(:last-child)]:rounded-b-none",
16
+ },
17
+ variant: {
18
+ elevated: "bg-[var(--color-bg-raised)]",
19
+ flat: "bg-transparent",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ orientation: "horizontal",
24
+ variant: "elevated",
25
+ },
26
+ }
27
+ )
28
+
29
+ function ButtonGroup({
30
+ className,
31
+ orientation,
32
+ variant,
33
+ ...props
34
+ }: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>) {
35
+ return (
36
+ <div
37
+ role="group"
38
+ data-slot="button-group"
39
+ data-orientation={orientation}
40
+ className={cn(buttonGroupVariants({ orientation, variant }), className)}
41
+ {...props}
42
+ />
43
+ )
44
+ }
45
+
46
+ function ButtonGroupText({
47
+ className,
48
+ asChild = false,
49
+ ...props
50
+ }: React.ComponentProps<"div"> & {
51
+ asChild?: boolean
52
+ }) {
53
+ const Comp = asChild ? Slot.Root : "div"
54
+
55
+ return (
56
+ <Comp
57
+ className={cn(
58
+ "flex items-center gap-2 [border-radius:var(--radius-button)] border border-[var(--color-border-default)] bg-[var(--color-bg-raised)] px-4 text-label text-[var(--color-text-muted)] [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
59
+ className
60
+ )}
61
+ {...props}
62
+ />
63
+ )
64
+ }
65
+
66
+ function ButtonGroupSeparator({
67
+ className,
68
+ orientation = "vertical",
69
+ ...props
70
+ }: React.ComponentProps<typeof Separator>) {
71
+ return (
72
+ <Separator
73
+ data-slot="button-group-separator"
74
+ orientation={orientation}
75
+ className={cn(
76
+ "relative m-0! self-stretch bg-input data-[orientation=vertical]:h-auto",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ export {
85
+ ButtonGroup,
86
+ ButtonGroupSeparator,
87
+ ButtonGroupText,
88
+ buttonGroupVariants,
89
+ }
@@ -0,0 +1,65 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { Slot } from "radix-ui"
4
+
5
+ import { cn } from "../../lib/utils"
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex shrink-0 items-center justify-center gap-2 [border-radius:var(--radius-button)] text-label whitespace-nowrap transition-all outline-none focus-visible:border-[var(--color-border-focus)] focus-visible:ring-[3px] focus-visible:ring-[var(--color-border-focus)]/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-[var(--color-border-error)] aria-invalid:ring-[3px] aria-invalid:ring-[var(--color-border-error)]/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ "bg-[var(--color-action-primary-default)] text-[var(--color-action-primary-foreground)] hover:bg-[var(--color-action-primary-hover)]",
14
+ destructive:
15
+ "bg-[var(--color-action-destructive-default)] text-[var(--color-action-destructive-foreground)] hover:bg-[var(--color-action-destructive-hover)] focus-visible:ring-[var(--color-border-error)]/20",
16
+ outline:
17
+ "border border-[var(--color-border-default)] bg-[var(--color-bg-raised)] shadow-xs hover:bg-[var(--color-action-ghost-hover)] hover:text-[var(--color-text-default)]",
18
+ secondary:
19
+ "bg-[var(--color-action-secondary-default)] text-[var(--color-action-secondary-foreground)] hover:bg-[var(--color-action-secondary-hover)]",
20
+ ghost:
21
+ "hover:bg-[var(--color-action-ghost-hover)] hover:text-[var(--color-text-default)]",
22
+ link: "text-[var(--color-text-link)] underline-offset-4 hover:underline hover:text-[var(--color-text-link-hover)]",
23
+ },
24
+ size: {
25
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
26
+ xs: "h-6 gap-1 px-2 text-caption has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
27
+ sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
28
+ lg: "h-10 px-6 has-[>svg]:px-4",
29
+ icon: "size-9",
30
+ "icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
31
+ "icon-sm": "size-8",
32
+ "icon-lg": "size-10",
33
+ },
34
+ },
35
+ defaultVariants: {
36
+ variant: "default",
37
+ size: "default",
38
+ },
39
+ }
40
+ )
41
+
42
+ function Button({
43
+ className,
44
+ variant = "default",
45
+ size = "default",
46
+ asChild = false,
47
+ ...props
48
+ }: React.ComponentProps<"button"> &
49
+ VariantProps<typeof buttonVariants> & {
50
+ asChild?: boolean
51
+ }) {
52
+ const Comp = asChild ? Slot.Root : "button"
53
+
54
+ return (
55
+ <Comp
56
+ data-slot="button"
57
+ data-variant={variant}
58
+ data-size={size}
59
+ className={cn(buttonVariants({ variant, size, className }))}
60
+ {...props}
61
+ />
62
+ )
63
+ }
64
+
65
+ export { Button, buttonVariants }
@@ -0,0 +1,92 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "../../lib/utils"
4
+
5
+ function Card({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ data-slot="card"
9
+ className={cn(
10
+ "flex flex-col gap-6 [border-radius:var(--radius-card)] border bg-card py-6 text-card-foreground shadow-[var(--shadow-card)]",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+ return (
20
+ <div
21
+ data-slot="card-header"
22
+ className={cn(
23
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
+ return (
33
+ <div
34
+ data-slot="card-title"
35
+ className={cn("text-heading-4", className)}
36
+ {...props}
37
+ />
38
+ )
39
+ }
40
+
41
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42
+ return (
43
+ <div
44
+ data-slot="card-description"
45
+ className={cn("text-body-sm text-[var(--color-text-muted)]", className)}
46
+ {...props}
47
+ />
48
+ )
49
+ }
50
+
51
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52
+ return (
53
+ <div
54
+ data-slot="card-action"
55
+ className={cn(
56
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57
+ className
58
+ )}
59
+ {...props}
60
+ />
61
+ )
62
+ }
63
+
64
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
+ return (
66
+ <div
67
+ data-slot="card-content"
68
+ className={cn("px-6", className)}
69
+ {...props}
70
+ />
71
+ )
72
+ }
73
+
74
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
+ return (
76
+ <div
77
+ data-slot="card-footer"
78
+ className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ export {
85
+ Card,
86
+ CardHeader,
87
+ CardFooter,
88
+ CardTitle,
89
+ CardAction,
90
+ CardDescription,
91
+ CardContent,
92
+ }
@@ -0,0 +1,104 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "../../lib/utils"
5
+
6
+ // ── TextStack ─────────────────────────────────────────────────────────────────
7
+ // Two-line cell content: a primary label and an optional muted secondary line.
8
+ // Use inside <TableCell> for entity columns (sender, receiver, etc.)
9
+
10
+ interface TextStackProps {
11
+ primary: React.ReactNode
12
+ secondary?: React.ReactNode
13
+ className?: string
14
+ }
15
+
16
+ function TextStack({ primary, secondary, className }: TextStackProps) {
17
+ return (
18
+ <div className={cn("flex flex-col gap-0.5", className)}>
19
+ <span className="text-caption-light text-[var(--color-text-default)]">{primary}</span>
20
+ {secondary && (
21
+ <span className="text-caption-sm-light text-[var(--color-text-muted)]">{secondary}</span>
22
+ )}
23
+ </div>
24
+ )
25
+ }
26
+
27
+ // ── MonoCell ──────────────────────────────────────────────────────────────────
28
+ // Single-line monospace text. Use for IDs, codes, hashes.
29
+
30
+ interface MonoCellProps {
31
+ children: React.ReactNode
32
+ className?: string
33
+ }
34
+
35
+ function MonoCell({ children, className }: MonoCellProps) {
36
+ return (
37
+ <span
38
+ className={cn(
39
+ "text-body-sm-light text-[var(--color-text-default)]",
40
+ className
41
+ )}
42
+ >
43
+ {children}
44
+ </span>
45
+ )
46
+ }
47
+
48
+ // ── AmountCell ────────────────────────────────────────────────────────────────
49
+ // Right-aligned numeric/currency value.
50
+
51
+ interface AmountCellProps {
52
+ children: React.ReactNode
53
+ className?: string
54
+ }
55
+
56
+ function AmountCell({ children, className }: AmountCellProps) {
57
+ return (
58
+ <span
59
+ className={cn(
60
+ "text-body-sm text-[var(--color-text-default)] tabular-nums tracking-tight",
61
+ className
62
+ )}
63
+ >
64
+ {children}
65
+ </span>
66
+ )
67
+ }
68
+
69
+ // ── BadgeCell ─────────────────────────────────────────────────────────────────
70
+ // Centered wrapper for one or more badges inside a table cell.
71
+
72
+ interface BadgeCellProps {
73
+ children: React.ReactNode
74
+ className?: string
75
+ }
76
+
77
+ function BadgeCell({ children, className }: BadgeCellProps) {
78
+ return (
79
+ <div className={cn("flex items-center gap-1", className)}>{children}</div>
80
+ )
81
+ }
82
+
83
+ // ── ActionCell ────────────────────────────────────────────────────────────────
84
+ // Flex row for action buttons inside a table cell.
85
+
86
+ interface ActionCellProps {
87
+ children: React.ReactNode
88
+ className?: string
89
+ }
90
+
91
+ function ActionCell({ children, className }: ActionCellProps) {
92
+ return (
93
+ <div className={cn("flex items-center gap-1", className)}>{children}</div>
94
+ )
95
+ }
96
+
97
+ export { TextStack, MonoCell, AmountCell, BadgeCell, ActionCell }
98
+ export type {
99
+ TextStackProps,
100
+ MonoCellProps,
101
+ AmountCellProps,
102
+ BadgeCellProps,
103
+ ActionCellProps,
104
+ }
@@ -0,0 +1,33 @@
1
+ "use client"
2
+
3
+ import { Collapsible as CollapsiblePrimitive } from "radix-ui"
4
+
5
+ function Collapsible({
6
+ ...props
7
+ }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
8
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
9
+ }
10
+
11
+ function CollapsibleTrigger({
12
+ ...props
13
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
14
+ return (
15
+ <CollapsiblePrimitive.CollapsibleTrigger
16
+ data-slot="collapsible-trigger"
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ function CollapsibleContent({
23
+ ...props
24
+ }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
25
+ return (
26
+ <CollapsiblePrimitive.CollapsibleContent
27
+ data-slot="collapsible-content"
28
+ {...props}
29
+ />
30
+ )
31
+ }
32
+
33
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }