@lateralus-ai/shipping-ui 2.0.0-dev.19 → 2.0.0-dev.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/dist/components/Entry.d.ts +7 -27
- package/dist/components/Tabs.d.ts +5 -5
- package/dist/components/index.d.ts +2 -4
- package/dist/index.cjs +25 -25
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +4628 -4857
- package/dist/patterns/Search/ResultRow.d.ts +5 -11
- package/dist/patterns/Sidebar/sidebar-styles.d.ts +1 -2
- package/dist/primitives/Badge.d.ts +4 -7
- package/dist/primitives/index.d.ts +1 -1
- package/dist/tailwind-theme.d.ts +4 -8
- package/dist/{theme-entry-tLBc6zGT.mjs → theme-entry-CxDa1D0_.mjs} +8 -12
- package/dist/theme-entry-D2X3Ptjf.js +1 -0
- package/dist/theme.cjs +1 -1
- package/dist/theme.esm.js +1 -1
- package/package.json +2 -2
- package/src/components/Entry.tsx +45 -119
- package/src/components/Tabs.tsx +139 -146
- package/src/components/index.ts +42 -56
- package/src/index.ts +74 -85
- package/src/patterns/Search/ResultRow.tsx +58 -44
- package/src/patterns/Search/SearchModal.tsx +292 -310
- package/src/patterns/Search/index.ts +31 -31
- package/src/patterns/Sidebar/CollapsibleNavGroup.tsx +1 -1
- package/src/patterns/Sidebar/SidebarAction.tsx +17 -26
- package/src/patterns/Sidebar/SidebarEntry.tsx +39 -54
- package/src/patterns/Sidebar/SidebarLink.tsx +20 -30
- package/src/patterns/Sidebar/sidebar-styles.ts +1 -2
- package/src/patterns/Skeleton/Skeleton.tsx +56 -56
- package/src/primitives/Badge.tsx +10 -20
- package/src/primitives/Button.tsx +11 -16
- package/src/primitives/index.ts +1 -1
- package/src/stories/canvases/ContentCanvas.tsx +114 -353
- package/src/stories/canvases/SearchCanvas.tsx +150 -150
- package/src/tailwind-theme.ts +182 -186
- package/src/utils/cn.ts +1 -28
- package/dist/components/PageHeader.d.ts +0 -41
- package/dist/components/ScrollableList.d.ts +0 -22
- package/dist/theme-entry-Dwr2mV7_.js +0 -1
- package/src/components/PageHeader.tsx +0 -132
- package/src/components/ScrollableList.tsx +0 -61
|
@@ -45,6 +45,7 @@ export const CollapsibleNavGroup = ({
|
|
|
45
45
|
href={href}
|
|
46
46
|
label={label}
|
|
47
47
|
icon={icon}
|
|
48
|
+
tall
|
|
48
49
|
onNavigate={onNavigate}
|
|
49
50
|
trailing={
|
|
50
51
|
<IconButton
|
|
@@ -92,7 +93,6 @@ export const CollapsibleNavGroup = ({
|
|
|
92
93
|
) : undefined
|
|
93
94
|
}
|
|
94
95
|
menuItems={entryMenuItems}
|
|
95
|
-
onNavigate={onNavigate}
|
|
96
96
|
/>
|
|
97
97
|
))}
|
|
98
98
|
</div>
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { Tooltip } from "../../primitives";
|
|
3
3
|
import { cn } from "../../utils/cn";
|
|
4
|
-
import {
|
|
5
|
-
sidebarLinkActive,
|
|
6
|
-
sidebarLinkIdle,
|
|
7
|
-
sidebarRowInteractiveHover,
|
|
8
|
-
sidebarSectionIconClass,
|
|
9
|
-
sidebarSectionShell,
|
|
10
|
-
sidebarSectionShellCollapsed,
|
|
11
|
-
} from "./sidebar-styles";
|
|
4
|
+
import { sidebarLinkActive, sidebarLinkIdle, sidebarRowClass, sidebarRowInteractiveHover, sidebarSectionAnchorClass } from "./sidebar-styles";
|
|
12
5
|
|
|
13
6
|
export type SidebarActionProps = {
|
|
14
7
|
label: string;
|
|
@@ -30,28 +23,26 @@ export const SidebarAction = ({
|
|
|
30
23
|
className,
|
|
31
24
|
}: SidebarActionProps) => {
|
|
32
25
|
const row = (
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
active ? sidebarLinkActive : sidebarLinkIdle,
|
|
41
|
-
!active && sidebarRowInteractiveHover,
|
|
42
|
-
!collapsed && "gap-2",
|
|
43
|
-
className,
|
|
26
|
+
<div
|
|
27
|
+
className={sidebarRowClass(
|
|
28
|
+
cn(
|
|
29
|
+
active ? sidebarLinkActive : sidebarLinkIdle,
|
|
30
|
+
!active && sidebarRowInteractiveHover,
|
|
31
|
+
className,
|
|
32
|
+
),
|
|
44
33
|
)}
|
|
45
34
|
data-active={active}
|
|
46
35
|
data-collapsed={collapsed}
|
|
47
36
|
>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
37
|
+
<button
|
|
38
|
+
type="button"
|
|
39
|
+
className={sidebarSectionAnchorClass(collapsed ? "justify-center" : undefined)}
|
|
40
|
+
onClick={onClick}
|
|
41
|
+
>
|
|
42
|
+
{icon && <span className="shrink-0 [&>svg]:size-5">{icon}</span>}
|
|
43
|
+
{!collapsed && <span className="truncate">{label}</span>}
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
55
46
|
);
|
|
56
47
|
|
|
57
48
|
if (!collapsed || !tooltip) return row;
|
|
@@ -3,6 +3,7 @@ import { DropdownMenu, DropdownMenuItem, IconButton } from "../../primitives";
|
|
|
3
3
|
import { MoreIcon } from "../../icons";
|
|
4
4
|
import { cn } from "../../utils/cn";
|
|
5
5
|
import {
|
|
6
|
+
sidebarAnchorClass,
|
|
6
7
|
sidebarEntryHover,
|
|
7
8
|
sidebarEntryIdle,
|
|
8
9
|
sidebarEntrySelected,
|
|
@@ -65,74 +66,58 @@ export const SidebarEntry = ({
|
|
|
65
66
|
)}
|
|
66
67
|
data-state={state}
|
|
67
68
|
>
|
|
68
|
-
{/* Stretch hit target over shell padding (hover was on the shell, link was content-only). */}
|
|
69
69
|
<a
|
|
70
70
|
href={href}
|
|
71
|
-
className="
|
|
72
|
-
aria-label={label}
|
|
71
|
+
className={sidebarAnchorClass("gap-1")}
|
|
73
72
|
aria-current={state === "selected" ? "true" : undefined}
|
|
74
73
|
onClick={onNavigate}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<div className="pointer-events-none relative z-10 flex min-w-0 flex-1 items-center gap-2 text-caption-2">
|
|
78
|
-
{icon && <span className="shrink-0 [&>svg]:size-4">{icon}</span>}
|
|
74
|
+
>
|
|
75
|
+
{icon && <span className="shrink-0 px-1 py-0.5 [&>svg]:size-4">{icon}</span>}
|
|
79
76
|
<span className="truncate">{label}</span>
|
|
80
|
-
</
|
|
77
|
+
</a>
|
|
81
78
|
|
|
82
79
|
{badge && !(showMenu && menuVisible) && (
|
|
83
80
|
<span
|
|
84
|
-
className={cn(
|
|
85
|
-
"pointer-events-none relative z-10 shrink-0",
|
|
86
|
-
showMenu && !forceMenuVisible && "group-hover/row:hidden",
|
|
87
|
-
)}
|
|
81
|
+
className={cn("shrink-0", showMenu && !forceMenuVisible && "group-hover/row:hidden")}
|
|
88
82
|
>
|
|
89
83
|
{badge}
|
|
90
84
|
</span>
|
|
91
85
|
)}
|
|
92
86
|
|
|
93
87
|
{showMenu && (
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
>
|
|
128
|
-
{item.icon && (
|
|
129
|
-
<span className="shrink-0 [&>svg]:size-4">{item.icon}</span>
|
|
130
|
-
)}
|
|
131
|
-
{item.label}
|
|
132
|
-
</DropdownMenuItem>
|
|
133
|
-
))}
|
|
134
|
-
</DropdownMenu>
|
|
135
|
-
</div>
|
|
88
|
+
<DropdownMenu
|
|
89
|
+
open={menuOpen}
|
|
90
|
+
onOpenChange={setMenuOpen}
|
|
91
|
+
align="end"
|
|
92
|
+
trigger={
|
|
93
|
+
<IconButton
|
|
94
|
+
hierarchy="quaternary"
|
|
95
|
+
size="small"
|
|
96
|
+
aria-label={`Actions for ${label}`}
|
|
97
|
+
aria-haspopup="menu"
|
|
98
|
+
aria-expanded={menuOpen}
|
|
99
|
+
className={cn(
|
|
100
|
+
"size-6 min-h-6 shrink-0 p-1",
|
|
101
|
+
sidebarQuaternaryIconButton,
|
|
102
|
+
!forceMenuVisible && !menuOpen && "hidden group-hover/row:inline-flex",
|
|
103
|
+
(forceMenuVisible || menuOpen) && "inline-flex",
|
|
104
|
+
)}
|
|
105
|
+
>
|
|
106
|
+
<MoreIcon size="small" />
|
|
107
|
+
</IconButton>
|
|
108
|
+
}
|
|
109
|
+
>
|
|
110
|
+
{menuItems?.map((item) => (
|
|
111
|
+
<DropdownMenuItem
|
|
112
|
+
key={item.id}
|
|
113
|
+
className={cn(item.destructive && "text-red-500 hover:bg-red-50 hover:text-red-700")}
|
|
114
|
+
onSelect={() => item.onSelect()}
|
|
115
|
+
>
|
|
116
|
+
{item.icon && <span className="shrink-0 [&>svg]:size-4">{item.icon}</span>}
|
|
117
|
+
{item.label}
|
|
118
|
+
</DropdownMenuItem>
|
|
119
|
+
))}
|
|
120
|
+
</DropdownMenu>
|
|
136
121
|
)}
|
|
137
122
|
</div>
|
|
138
123
|
);
|
|
@@ -58,7 +58,6 @@ export const SidebarLink = ({
|
|
|
58
58
|
const row = collapsed ? (
|
|
59
59
|
<div
|
|
60
60
|
className={cn(
|
|
61
|
-
"relative",
|
|
62
61
|
sidebarSectionShellCollapsed,
|
|
63
62
|
stateStyles[state],
|
|
64
63
|
state === "idle" && sidebarRowInteractiveHover,
|
|
@@ -69,24 +68,24 @@ export const SidebarLink = ({
|
|
|
69
68
|
>
|
|
70
69
|
<a
|
|
71
70
|
href={href}
|
|
72
|
-
className="
|
|
71
|
+
className="flex w-full items-center justify-center"
|
|
73
72
|
aria-current={state === "active" ? "page" : undefined}
|
|
74
73
|
aria-label={label}
|
|
75
74
|
onClick={onNavigate}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
75
|
+
>
|
|
76
|
+
<span className="relative inline-flex shrink-0 items-center">
|
|
77
|
+
{icon && <span className={sidebarSectionIconClass}>{icon}</span>}
|
|
78
|
+
{unread && (
|
|
79
|
+
<span aria-hidden className={sidebarUnreadOverlay}>
|
|
80
|
+
<span className={sidebarUnreadDot} />
|
|
81
|
+
</span>
|
|
82
|
+
)}
|
|
83
|
+
</span>
|
|
84
|
+
</a>
|
|
85
85
|
</div>
|
|
86
86
|
) : (
|
|
87
87
|
<div
|
|
88
88
|
className={cn(
|
|
89
|
-
"relative",
|
|
90
89
|
tall ? sidebarSectionShellTall : sidebarSectionShell,
|
|
91
90
|
stateStyles[state],
|
|
92
91
|
state === "idle" && sidebarRowInteractiveHover,
|
|
@@ -95,27 +94,18 @@ export const SidebarLink = ({
|
|
|
95
94
|
data-state={state}
|
|
96
95
|
data-collapsed={collapsed}
|
|
97
96
|
>
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<div
|
|
106
|
-
className={cn(
|
|
107
|
-
sidebarSectionContent,
|
|
108
|
-
"pointer-events-none relative z-10",
|
|
109
|
-
)}
|
|
110
|
-
>
|
|
111
|
-
<span className="flex min-w-0 flex-1 items-center gap-2 truncate text-left">
|
|
97
|
+
<div className={sidebarSectionContent}>
|
|
98
|
+
<a
|
|
99
|
+
href={href}
|
|
100
|
+
className="flex min-w-0 flex-1 items-center gap-2 truncate text-left"
|
|
101
|
+
aria-current={state === "active" ? "page" : undefined}
|
|
102
|
+
onClick={onNavigate}
|
|
103
|
+
>
|
|
112
104
|
{icon && <span className={sidebarSectionIconClass}>{icon}</span>}
|
|
113
105
|
<span className={sidebarSectionLabelClass}>{label}</span>
|
|
114
106
|
{badge}
|
|
115
|
-
</
|
|
116
|
-
{trailing
|
|
117
|
-
<span className="pointer-events-auto shrink-0">{trailing}</span>
|
|
118
|
-
)}
|
|
107
|
+
</a>
|
|
108
|
+
{trailing}
|
|
119
109
|
</div>
|
|
120
110
|
</div>
|
|
121
111
|
);
|
|
@@ -30,8 +30,7 @@ export const sidebarUnreadOverlay =
|
|
|
30
30
|
export const sidebarUnreadDot =
|
|
31
31
|
"absolute right-0 top-0 size-1.5 rounded-full bg-[#802c20]";
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
export const sidebarSectionContent = "flex w-full min-w-0 items-center gap-2";
|
|
33
|
+
export const sidebarSectionContent = "flex w-full min-w-0 items-center gap-2 pl-1";
|
|
35
34
|
|
|
36
35
|
export const sidebarSectionIconClass = "shrink-0 [&>svg]:size-4";
|
|
37
36
|
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { cn } from "../../utils/cn";
|
|
2
|
-
|
|
3
|
-
export type SkeletonVariant = "content" | "search";
|
|
4
|
-
|
|
5
|
-
export type SkeletonProps = {
|
|
6
|
-
variant?: SkeletonVariant;
|
|
7
|
-
className?: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const ContentSkeleton = () => (
|
|
11
|
-
<div className="flex flex-col gap-4 p-4" aria-hidden>
|
|
12
|
-
<div className="flex items-center gap-3">
|
|
13
|
-
<div className="size-8 animate-pulse rounded-full bg-grey-200" />
|
|
14
|
-
<div className="flex flex-1 flex-col gap-2">
|
|
15
|
-
<div className="h-4 w-1/3 animate-pulse rounded bg-grey-200" />
|
|
16
|
-
<div className="h-3 w-1/4 animate-pulse rounded bg-grey-100" />
|
|
17
|
-
</div>
|
|
18
|
-
</div>
|
|
19
|
-
<div className="flex flex-col gap-2">
|
|
20
|
-
<div className="h-4 w-full animate-pulse rounded bg-grey-200" />
|
|
21
|
-
<div className="h-4 w-5/6 animate-pulse rounded bg-grey-200" />
|
|
22
|
-
<div className="h-4 w-2/3 animate-pulse rounded bg-grey-100" />
|
|
23
|
-
</div>
|
|
24
|
-
<div className="h-24 animate-pulse rounded-control bg-grey-100" />
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
/** Figma Search loading — 8 rows of icon + bar (no input/pills). */
|
|
29
|
-
const SearchSkeleton = () => {
|
|
30
|
-
const widths = [250, 300, 220, 255, 250, 300, 220, 255];
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<div className="flex flex-col gap-1.5 p-4" aria-hidden>
|
|
34
|
-
{widths.map((width, index) => (
|
|
35
|
-
<div key={index} className="flex items-start gap-2 py-2">
|
|
36
|
-
<div className="size-3 shrink-0 animate-pulse rounded-md bg-grey-200" />
|
|
37
|
-
<div
|
|
38
|
-
className="h-3 animate-pulse rounded-md bg-grey-200"
|
|
39
|
-
style={{ width }}
|
|
40
|
-
/>
|
|
41
|
-
</div>
|
|
42
|
-
))}
|
|
43
|
-
</div>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export const Skeleton = ({ variant = "content", className }: SkeletonProps) => (
|
|
48
|
-
<div
|
|
49
|
-
className={cn("rounded-control bg-background-primary", className)}
|
|
50
|
-
role="status"
|
|
51
|
-
aria-label="Loading"
|
|
52
|
-
data-variant={variant}
|
|
53
|
-
>
|
|
54
|
-
{variant === "content" ? <ContentSkeleton /> : <SearchSkeleton />}
|
|
55
|
-
</div>
|
|
56
|
-
);
|
|
1
|
+
import { cn } from "../../utils/cn";
|
|
2
|
+
|
|
3
|
+
export type SkeletonVariant = "content" | "search";
|
|
4
|
+
|
|
5
|
+
export type SkeletonProps = {
|
|
6
|
+
variant?: SkeletonVariant;
|
|
7
|
+
className?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const ContentSkeleton = () => (
|
|
11
|
+
<div className="flex flex-col gap-4 p-4" aria-hidden>
|
|
12
|
+
<div className="flex items-center gap-3">
|
|
13
|
+
<div className="size-8 animate-pulse rounded-full bg-grey-200" />
|
|
14
|
+
<div className="flex flex-1 flex-col gap-2">
|
|
15
|
+
<div className="h-4 w-1/3 animate-pulse rounded bg-grey-200" />
|
|
16
|
+
<div className="h-3 w-1/4 animate-pulse rounded bg-grey-100" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="flex flex-col gap-2">
|
|
20
|
+
<div className="h-4 w-full animate-pulse rounded bg-grey-200" />
|
|
21
|
+
<div className="h-4 w-5/6 animate-pulse rounded bg-grey-200" />
|
|
22
|
+
<div className="h-4 w-2/3 animate-pulse rounded bg-grey-100" />
|
|
23
|
+
</div>
|
|
24
|
+
<div className="h-24 animate-pulse rounded-control bg-grey-100" />
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
/** Figma Search loading — 8 rows of icon + bar (no input/pills). */
|
|
29
|
+
const SearchSkeleton = () => {
|
|
30
|
+
const widths = [250, 300, 220, 255, 250, 300, 220, 255];
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className="flex flex-col gap-1.5 p-4" aria-hidden>
|
|
34
|
+
{widths.map((width, index) => (
|
|
35
|
+
<div key={index} className="flex items-start gap-2 py-2">
|
|
36
|
+
<div className="size-3 shrink-0 animate-pulse rounded-md bg-grey-200" />
|
|
37
|
+
<div
|
|
38
|
+
className="h-3 animate-pulse rounded-md bg-grey-200"
|
|
39
|
+
style={{ width }}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
))}
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const Skeleton = ({ variant = "content", className }: SkeletonProps) => (
|
|
48
|
+
<div
|
|
49
|
+
className={cn("rounded-control bg-background-primary", className)}
|
|
50
|
+
role="status"
|
|
51
|
+
aria-label="Loading"
|
|
52
|
+
data-variant={variant}
|
|
53
|
+
>
|
|
54
|
+
{variant === "content" ? <ContentSkeleton /> : <SearchSkeleton />}
|
|
55
|
+
</div>
|
|
56
|
+
);
|
package/src/primitives/Badge.tsx
CHANGED
|
@@ -1,40 +1,30 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { cn } from "../utils/cn";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
type BadgeColor = "blue" | "green" | "red" | "orange" | "purple" | "grey";
|
|
5
|
+
type BadgeType = "label" | "icon";
|
|
6
6
|
|
|
7
7
|
export type BadgeProps = {
|
|
8
8
|
color: BadgeColor;
|
|
9
|
-
/** `label` grows with content (pill). `icon` is a compact circle for a glyph/digit. */
|
|
10
9
|
type?: BadgeType;
|
|
11
10
|
children: ReactNode;
|
|
12
11
|
className?: string;
|
|
13
12
|
};
|
|
14
13
|
|
|
15
14
|
const colorStyles: Record<BadgeColor, string> = {
|
|
16
|
-
blue: "bg-meta-blue text-meta-
|
|
17
|
-
green: "bg-meta-green text-meta-
|
|
18
|
-
red: "bg-meta-red text-meta-
|
|
19
|
-
orange: "bg-meta-orange text-meta-
|
|
20
|
-
purple: "bg-meta-purple text-meta-
|
|
15
|
+
blue: "bg-meta-blue text-meta-on-blue",
|
|
16
|
+
green: "bg-meta-green text-meta-on-green",
|
|
17
|
+
red: "bg-meta-red text-meta-on-red",
|
|
18
|
+
orange: "bg-meta-orange text-meta-on-orange",
|
|
19
|
+
purple: "bg-meta-purple text-meta-on-purple",
|
|
21
20
|
grey: "bg-grey-100 text-display-on-light-secondary",
|
|
22
21
|
};
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
* Figma Badge (4365:74363) — padding + rounded-full; no fixed width on labels.
|
|
26
|
-
*/
|
|
27
|
-
export const Badge = ({
|
|
28
|
-
color,
|
|
29
|
-
type = "label",
|
|
30
|
-
children,
|
|
31
|
-
className,
|
|
32
|
-
}: BadgeProps) => (
|
|
23
|
+
export const Badge = ({ color, type = "label", children, className }: BadgeProps) => (
|
|
33
24
|
<span
|
|
34
25
|
className={cn(
|
|
35
|
-
"inline-flex shrink-0 items-center justify-center text-footnote-em
|
|
36
|
-
type === "label"
|
|
37
|
-
type === "icon" && "size-5 rounded-full [&>svg]:size-3",
|
|
26
|
+
"inline-flex shrink-0 items-center justify-center text-footnote-em",
|
|
27
|
+
type === "label" ? "rounded-control px-2 py-0.5" : "size-6 rounded-full",
|
|
38
28
|
colorStyles[color],
|
|
39
29
|
className,
|
|
40
30
|
)}
|
|
@@ -121,8 +121,6 @@ export const Button = ({
|
|
|
121
121
|
...props
|
|
122
122
|
}: ButtonProps) => {
|
|
123
123
|
const resolvedIcon = icon ?? startIcon;
|
|
124
|
-
const renderedIcon = renderIcon(resolvedIcon);
|
|
125
|
-
const hasIcon = renderedIcon != null;
|
|
126
124
|
const hasDropdown = Boolean(dropdownOptions?.length);
|
|
127
125
|
const dropdownDisabled = !dropdownOptions?.some((option) => !option.disabled);
|
|
128
126
|
const mainAppearance = getAppearance(disabled, forcedState);
|
|
@@ -137,18 +135,11 @@ export const Button = ({
|
|
|
137
135
|
dropdownAppearance,
|
|
138
136
|
forcedState,
|
|
139
137
|
);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
"flex min-h-6 items-center justify-center",
|
|
146
|
-
hasIcon && "gap-2",
|
|
147
|
-
)}
|
|
148
|
-
>
|
|
149
|
-
{renderedIcon}
|
|
150
|
-
<span>{children}</span>
|
|
151
|
-
</span>
|
|
138
|
+
const label = (
|
|
139
|
+
<>
|
|
140
|
+
{renderIcon(resolvedIcon)}
|
|
141
|
+
<span className="px-2">{children}</span>
|
|
142
|
+
</>
|
|
152
143
|
);
|
|
153
144
|
|
|
154
145
|
if (!hasDropdown) {
|
|
@@ -165,7 +156,9 @@ export const Button = ({
|
|
|
165
156
|
)}
|
|
166
157
|
{...props}
|
|
167
158
|
>
|
|
168
|
-
|
|
159
|
+
<span className="flex min-h-6 items-center [&>*:first-child]:-mr-1 [&>*:last-child]:-mr-1">
|
|
160
|
+
{label}
|
|
161
|
+
</span>
|
|
169
162
|
</button>
|
|
170
163
|
);
|
|
171
164
|
}
|
|
@@ -182,7 +175,9 @@ export const Button = ({
|
|
|
182
175
|
)}
|
|
183
176
|
{...props}
|
|
184
177
|
>
|
|
185
|
-
|
|
178
|
+
<span className="flex min-h-6 items-center [&>*:first-child]:-mr-1 [&>*:last-child]:-mr-1">
|
|
179
|
+
{label}
|
|
180
|
+
</span>
|
|
186
181
|
</button>
|
|
187
182
|
);
|
|
188
183
|
|
package/src/primitives/index.ts
CHANGED
|
@@ -14,5 +14,5 @@ export { Tooltip, TooltipProvider, type TooltipProps, type TooltipSide } from ".
|
|
|
14
14
|
export { ThinkingDot, type ThinkingDotProps } from "./ThinkingDot";
|
|
15
15
|
export { Count, type CountProps } from "./Count";
|
|
16
16
|
export { Switch, type SwitchProps } from "./Switch";
|
|
17
|
-
export { Badge, type BadgeProps
|
|
17
|
+
export { Badge, type BadgeProps } from "./Badge";
|
|
18
18
|
export { Callout, type CalloutProps } from "./Callout";
|