banhaten 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.
Files changed (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +361 -0
  3. package/banhaten.config.example.json +13 -0
  4. package/package.json +59 -0
  5. package/registry/assets/activity-feed-avatar.png +0 -0
  6. package/registry/assets/avatars/avatar-01.jpg +0 -0
  7. package/registry/assets/avatars/avatar-02.jpg +0 -0
  8. package/registry/assets/avatars/avatar-03.jpg +0 -0
  9. package/registry/assets/avatars/avatar-04.jpg +0 -0
  10. package/registry/assets/avatars/avatar-05.jpg +0 -0
  11. package/registry/assets/avatars/avatar-06.jpg +0 -0
  12. package/registry/assets/avatars/avatar-07.jpg +0 -0
  13. package/registry/assets/avatars/avatar-08.jpg +0 -0
  14. package/registry/assets/avatars/avatar-09.jpg +0 -0
  15. package/registry/assets/avatars/avatar-10.jpg +0 -0
  16. package/registry/assets/avatars/avatar-11.jpg +0 -0
  17. package/registry/assets/avatars/avatar-12.jpg +0 -0
  18. package/registry/assets/avatars/avatar-13.jpg +0 -0
  19. package/registry/assets/avatars/avatar-14.jpg +0 -0
  20. package/registry/assets/avatars/avatar-15.jpg +0 -0
  21. package/registry/assets/avatars/avatar-16.jpg +0 -0
  22. package/registry/assets/avatars/avatar-17.jpg +0 -0
  23. package/registry/assets/avatars/avatar-18.jpg +0 -0
  24. package/registry/assets/avatars/avatar-19.jpg +0 -0
  25. package/registry/assets/avatars/avatar-20.jpg +0 -0
  26. package/registry/assets/avatars/avatar-21.jpg +0 -0
  27. package/registry/assets/avatars/avatar-22.jpg +0 -0
  28. package/registry/assets/avatars/avatar-23.jpg +0 -0
  29. package/registry/assets/avatars/avatar-24.jpg +0 -0
  30. package/registry/assets/avatars/avatar-25.jpg +0 -0
  31. package/registry/assets/avatars/avatar-26.jpg +0 -0
  32. package/registry/assets/avatars/avatar-27.jpg +0 -0
  33. package/registry/assets/avatars/avatar-28.jpg +0 -0
  34. package/registry/assets/avatars/avatar-29.jpg +0 -0
  35. package/registry/assets/avatars/avatar-30.jpg +0 -0
  36. package/registry/assets/avatars/avatar-31.jpg +0 -0
  37. package/registry/assets/avatars/avatar-32.jpg +0 -0
  38. package/registry/assets/avatars/avatar-33.jpg +0 -0
  39. package/registry/assets/avatars/avatar-34.jpg +0 -0
  40. package/registry/assets/avatars/avatar-35.jpg +0 -0
  41. package/registry/assets/image-assets.json +744 -0
  42. package/registry/assets/images/art-01.jpg +0 -0
  43. package/registry/assets/images/art-02.jpg +0 -0
  44. package/registry/assets/images/art-03.jpg +0 -0
  45. package/registry/assets/images/art-04.jpg +0 -0
  46. package/registry/assets/images/art-05.jpg +0 -0
  47. package/registry/assets/images/art-06.jpg +0 -0
  48. package/registry/assets/images/art-07.jpg +0 -0
  49. package/registry/assets/images/art-08.jpg +0 -0
  50. package/registry/assets/images/art-09.jpg +0 -0
  51. package/registry/assets/images/art-10.jpg +0 -0
  52. package/registry/assets/images/art-11.jpg +0 -0
  53. package/registry/assets/images/art-12.jpg +0 -0
  54. package/registry/assets/images/art-13.jpg +0 -0
  55. package/registry/assets/images/art-14.jpg +0 -0
  56. package/registry/assets/images/art-15.jpg +0 -0
  57. package/registry/assets/images/art-16.jpg +0 -0
  58. package/registry/assets/images/art-17.jpg +0 -0
  59. package/registry/assets/images/art-18.jpg +0 -0
  60. package/registry/assets/images/art-19.jpg +0 -0
  61. package/registry/assets/images/art-20.jpg +0 -0
  62. package/registry/assets/images/art-21.jpg +0 -0
  63. package/registry/assets/images/art-22.jpg +0 -0
  64. package/registry/assets/images/art-23.jpg +0 -0
  65. package/registry/assets/images/art-24.jpg +0 -0
  66. package/registry/assets/images/art-25.jpg +0 -0
  67. package/registry/assets/images/art-26.jpg +0 -0
  68. package/registry/assets/images/art-27.jpg +0 -0
  69. package/registry/assets/images/nature-01.jpg +0 -0
  70. package/registry/assets/images/nature-02.jpg +0 -0
  71. package/registry/assets/images/nature-03.jpg +0 -0
  72. package/registry/assets/images/nature-04.jpg +0 -0
  73. package/registry/assets/images/nature-05.jpg +0 -0
  74. package/registry/assets/images/nature-06.jpg +0 -0
  75. package/registry/assets/images/nature-07.jpg +0 -0
  76. package/registry/assets/images/nature-08.jpg +0 -0
  77. package/registry/assets/images/nature-09.jpg +0 -0
  78. package/registry/assets/images/nature-10.jpg +0 -0
  79. package/registry/assets/images/nature-11.jpg +0 -0
  80. package/registry/assets/images/nature-12.jpg +0 -0
  81. package/registry/assets/images/nature-13.jpg +0 -0
  82. package/registry/assets/images/nature-14.jpg +0 -0
  83. package/registry/assets/images/nature-15.jpg +0 -0
  84. package/registry/assets/images/nature-16.jpg +0 -0
  85. package/registry/assets/images/nature-17.jpg +0 -0
  86. package/registry/assets/images/nature-18.jpg +0 -0
  87. package/registry/assets/images/nature-19.jpg +0 -0
  88. package/registry/assets/images/nature-20.jpg +0 -0
  89. package/registry/components/accordion.tsx +119 -0
  90. package/registry/components/alert.tsx +282 -0
  91. package/registry/components/attribute.tsx +452 -0
  92. package/registry/components/avatar.tsx +142 -0
  93. package/registry/components/badge.tsx +567 -0
  94. package/registry/components/button-group.tsx +246 -0
  95. package/registry/components/button.tsx +102 -0
  96. package/registry/components/card.tsx +613 -0
  97. package/registry/components/checkbox.tsx +244 -0
  98. package/registry/components/date-picker.tsx +1143 -0
  99. package/registry/components/divider.tsx +82 -0
  100. package/registry/components/expanded/ActivityFeed.tsx +226 -0
  101. package/registry/components/expanded/Banner.tsx +145 -0
  102. package/registry/components/expanded/BannerBoard.tsx +225 -0
  103. package/registry/components/expanded/Breadcrumbs.tsx +156 -0
  104. package/registry/components/expanded/CatalogComponentsShowcase.tsx +211 -0
  105. package/registry/components/expanded/CatalogDivider.tsx +48 -0
  106. package/registry/components/expanded/CatalogTag.tsx +92 -0
  107. package/registry/components/expanded/CommandBar.tsx +406 -0
  108. package/registry/components/expanded/FileUpload.tsx +231 -0
  109. package/registry/components/expanded/IconExplorer.tsx +612 -0
  110. package/registry/components/expanded/OnboardingStepListItem.tsx +67 -0
  111. package/registry/components/expanded/PageHeader.tsx +184 -0
  112. package/registry/components/expanded/Slideout.tsx +514 -0
  113. package/registry/components/expanded/Steps.tsx +266 -0
  114. package/registry/components/expanded/Table.tsx +1014 -0
  115. package/registry/components/expanded/Tabs.tsx +86 -0
  116. package/registry/components/expanded/Timeline.tsx +235 -0
  117. package/registry/components/expanded/TimelineShowcase.tsx +158 -0
  118. package/registry/components/expanded/activityFeed.css +292 -0
  119. package/registry/components/expanded/banner.css +312 -0
  120. package/registry/components/expanded/breadcrumbs.css +140 -0
  121. package/registry/components/expanded/catalogComponentsShowcase.css +87 -0
  122. package/registry/components/expanded/commandBar.css +473 -0
  123. package/registry/components/expanded/divider.css +75 -0
  124. package/registry/components/expanded/fileUpload.css +228 -0
  125. package/registry/components/expanded/iconExplorer.css +764 -0
  126. package/registry/components/expanded/iconPacks.ts +866 -0
  127. package/registry/components/expanded/onboardingStepListItem.css +126 -0
  128. package/registry/components/expanded/pageHeader.css +287 -0
  129. package/registry/components/expanded/slideout.css +955 -0
  130. package/registry/components/expanded/steps.css +329 -0
  131. package/registry/components/expanded/table.css +607 -0
  132. package/registry/components/expanded/tabs.css +197 -0
  133. package/registry/components/expanded/tag.css +148 -0
  134. package/registry/components/expanded/timeline.css +282 -0
  135. package/registry/components/input-content.ts +106 -0
  136. package/registry/components/input.tsx +866 -0
  137. package/registry/components/menu.tsx +758 -0
  138. package/registry/components/modal.tsx +799 -0
  139. package/registry/components/pagination.tsx +543 -0
  140. package/registry/components/progress-slider.tsx +216 -0
  141. package/registry/components/progress.tsx +367 -0
  142. package/registry/components/radio-card.tsx +654 -0
  143. package/registry/components/radio-group.tsx +570 -0
  144. package/registry/components/select-content.tsx +313 -0
  145. package/registry/components/select.tsx +871 -0
  146. package/registry/components/slider.tsx +380 -0
  147. package/registry/components/social-button.tsx +360 -0
  148. package/registry/components/spinner.tsx +31 -0
  149. package/registry/components/tag.tsx +423 -0
  150. package/registry/components/textarea.tsx +625 -0
  151. package/registry/components/toggle.tsx +272 -0
  152. package/registry/components/toolbar.tsx +467 -0
  153. package/registry/components/tooltip.tsx +427 -0
  154. package/registry/examples/accordion-demo.tsx +34 -0
  155. package/registry/examples/alert-demo.tsx +14 -0
  156. package/registry/examples/attribute-demo.tsx +65 -0
  157. package/registry/examples/avatar-demo.tsx +74 -0
  158. package/registry/examples/badge-demo.tsx +53 -0
  159. package/registry/examples/button-demo.tsx +83 -0
  160. package/registry/examples/button-group-demo.tsx +42 -0
  161. package/registry/examples/card-demo.tsx +48 -0
  162. package/registry/examples/checkbox-demo.tsx +67 -0
  163. package/registry/examples/date-picker-demo.tsx +74 -0
  164. package/registry/examples/divider-demo.tsx +17 -0
  165. package/registry/examples/expanded/activity-feed-demo.tsx +22 -0
  166. package/registry/examples/expanded/banner-demo.tsx +23 -0
  167. package/registry/examples/expanded/catalog-components-demo.tsx +5 -0
  168. package/registry/examples/expanded/command-bar-demo.tsx +10 -0
  169. package/registry/examples/expanded/icons-demo.tsx +5 -0
  170. package/registry/examples/expanded/onboarding-step-demo.tsx +11 -0
  171. package/registry/examples/expanded/page-header-demo.tsx +19 -0
  172. package/registry/examples/expanded/slideout-demo.tsx +15 -0
  173. package/registry/examples/expanded/steps-demo.tsx +18 -0
  174. package/registry/examples/expanded/tabs-demo.tsx +13 -0
  175. package/registry/examples/expanded/timeline-demo.tsx +18 -0
  176. package/registry/examples/input-demo.tsx +87 -0
  177. package/registry/examples/menu-demo.tsx +109 -0
  178. package/registry/examples/modal-demo.tsx +16 -0
  179. package/registry/examples/pagination-demo.tsx +17 -0
  180. package/registry/examples/progress-demo.tsx +37 -0
  181. package/registry/examples/progress-slider-demo.tsx +29 -0
  182. package/registry/examples/radio-card-demo.tsx +51 -0
  183. package/registry/examples/radio-group-demo.tsx +62 -0
  184. package/registry/examples/select-demo.tsx +73 -0
  185. package/registry/examples/slider-demo.tsx +31 -0
  186. package/registry/examples/social-button-demo.tsx +51 -0
  187. package/registry/examples/tag-demo.tsx +29 -0
  188. package/registry/examples/textarea-demo.tsx +79 -0
  189. package/registry/examples/toggle-demo.tsx +59 -0
  190. package/registry/examples/toolbar-demo.tsx +80 -0
  191. package/registry/examples/tooltip-demo.tsx +115 -0
  192. package/registry/hooks/use-direction.ts +27 -0
  193. package/registry/index.json +1213 -0
  194. package/registry/styles/globals.css +4600 -0
  195. package/registry/utils/cn.ts +6 -0
  196. package/src/cli/index.js +826 -0
  197. package/tokens/Color mode.zip +0 -0
  198. package/tokens/Numbers.zip +0 -0
  199. package/tokens/Radius.zip +0 -0
  200. package/tokens/Theme.zip +0 -0
  201. package/tokens/banhaten.tokens.json +5525 -0
@@ -0,0 +1,423 @@
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { PlusIcon, XIcon } from "lucide-react"
4
+ import { cva, type VariantProps } from "class-variance-authority"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ type TagType = "simple" | "dot" | "flag" | "avatar" | "icon"
9
+ type TagSize = "xs" | "md" | "lg"
10
+ type TagState = "default" | "active" | "disabled"
11
+
12
+ const tagVariants = cva(
13
+ [
14
+ "relative inline-flex min-w-0 shrink-0 items-center whitespace-nowrap border outline-none",
15
+ "rounded-[var(--bh-control-default)] text-[var(--bh-content-default)]",
16
+ "transition-[background-color,border-color,color,box-shadow]",
17
+ "after:pointer-events-none after:absolute after:inset-[var(--bh-tag-focus-ring-inset)] after:rounded-[inherit] after:border-[length:var(--bh-tag-focus-ring-width)] after:border-transparent after:content-['']",
18
+ "focus-visible:border-[var(--bh-border-brand-strong)] focus-visible:after:border-[var(--bh-border-focus)] focus-visible:after:opacity-[var(--bh-opacity-30)]",
19
+ "rtl:[&_svg[data-rtl-flip='true']]:-scale-x-100",
20
+ ],
21
+ {
22
+ variants: {
23
+ type: {
24
+ simple: "justify-center gap-[var(--bh-space-none)]",
25
+ dot: "justify-start gap-[var(--bh-space-none)]",
26
+ flag: "justify-start gap-[var(--bh-space-xs-4)]",
27
+ avatar: "justify-start gap-[var(--bh-space-xs-4)]",
28
+ icon: "justify-start gap-[var(--bh-space-xs-4)]",
29
+ },
30
+ size: {
31
+ xs: [
32
+ "h-[var(--bh-space-5xl-24)] rounded-[var(--bh-control-md)]",
33
+ "text-[length:var(--bh-text-body-xs-medium-font-size)]",
34
+ "font-[var(--bh-text-body-xs-medium-font-weight)]",
35
+ "leading-[var(--bh-text-body-xs-medium-line-height)]",
36
+ "tracking-[var(--bh-text-body-xs-medium-letter-spacing)]",
37
+ ],
38
+ md: [
39
+ "h-[calc(var(--bh-space-5xl-24)+var(--bh-space-xs-4))]",
40
+ "text-[length:var(--bh-text-body-sm-medium-font-size)]",
41
+ "font-[var(--bh-text-body-sm-medium-font-weight)]",
42
+ "leading-[var(--bh-text-body-sm-medium-line-height)]",
43
+ "tracking-[var(--bh-text-body-sm-medium-letter-spacing)]",
44
+ ],
45
+ lg: [
46
+ "h-[calc(var(--bh-space-5xl-24)+var(--bh-space-xl-12))]",
47
+ "text-[length:var(--bh-text-body-md-medium-font-size)]",
48
+ "font-[var(--bh-text-body-md-medium-font-weight)]",
49
+ "leading-[var(--bh-text-body-md-medium-line-height)]",
50
+ "tracking-[var(--bh-text-body-md-medium-letter-spacing)]",
51
+ ],
52
+ },
53
+ state: {
54
+ default:
55
+ "border-[var(--bh-border-default)] bg-[var(--bh-interactive-secondary-default)] hover:border-transparent hover:bg-[var(--bh-interactive-secondary-hover)]",
56
+ active:
57
+ "border-[length:var(--bh-tag-active-border-width)] border-[var(--bh-border-brand-strong)] bg-[var(--bh-bg-brand-subtle)] text-[var(--bh-content-brand-default)]",
58
+ disabled:
59
+ "pointer-events-none border-[var(--bh-border-disabled)] bg-[var(--bh-interactive-secondary-disabled)] text-[var(--bh-content-disabled)]",
60
+ },
61
+ showCloseButton: {
62
+ true: "",
63
+ false: "",
64
+ },
65
+ },
66
+ compoundVariants: [
67
+ {
68
+ type: "simple",
69
+ showCloseButton: false,
70
+ size: "xs",
71
+ class: "px-[var(--bh-space-md-8)]",
72
+ },
73
+ {
74
+ type: "simple",
75
+ showCloseButton: false,
76
+ size: ["md", "lg"],
77
+ class: "px-[var(--bh-space-xl-12)]",
78
+ },
79
+ {
80
+ type: "simple",
81
+ showCloseButton: true,
82
+ size: "xs",
83
+ class:
84
+ "gap-[var(--bh-space-xs-4)] ps-[var(--bh-space-md-8)] pe-[var(--bh-space-xs-4)]",
85
+ },
86
+ {
87
+ type: "simple",
88
+ showCloseButton: true,
89
+ size: "md",
90
+ class:
91
+ "gap-[var(--bh-space-xs-4)] ps-[var(--bh-space-lg-10)] pe-[var(--bh-space-md-8)]",
92
+ },
93
+ {
94
+ type: "simple",
95
+ showCloseButton: true,
96
+ size: "lg",
97
+ class:
98
+ "gap-[var(--bh-space-xs-4)] ps-[var(--bh-space-xl-12)] pe-[var(--bh-space-md-8)]",
99
+ },
100
+ {
101
+ type: ["dot", "flag", "avatar", "icon"],
102
+ showCloseButton: false,
103
+ size: "xs",
104
+ class: "ps-[var(--bh-space-sm-6)] pe-[var(--bh-space-md-8)]",
105
+ },
106
+ {
107
+ type: ["dot", "flag", "avatar", "icon"],
108
+ showCloseButton: false,
109
+ size: "md",
110
+ class: "ps-[var(--bh-space-sm-6)] pe-[var(--bh-space-xl-12)]",
111
+ },
112
+ {
113
+ type: ["dot", "flag", "avatar", "icon"],
114
+ showCloseButton: false,
115
+ size: "lg",
116
+ class: "ps-[var(--bh-space-md-8)] pe-[var(--bh-space-xl-12)]",
117
+ },
118
+ {
119
+ type: ["dot", "flag", "avatar", "icon"],
120
+ showCloseButton: true,
121
+ size: ["xs", "md"],
122
+ class: "px-[var(--bh-space-sm-6)]",
123
+ },
124
+ {
125
+ type: ["dot", "flag", "avatar", "icon"],
126
+ showCloseButton: true,
127
+ size: "lg",
128
+ class: "px-[var(--bh-space-md-8)]",
129
+ },
130
+ ],
131
+ defaultVariants: {
132
+ type: "simple",
133
+ size: "md",
134
+ state: "default",
135
+ showCloseButton: false,
136
+ },
137
+ }
138
+ )
139
+
140
+ type TagProps = Omit<React.ComponentProps<"span">, "children"> &
141
+ VariantProps<typeof tagVariants> & {
142
+ asChild?: boolean
143
+ avatar?: React.ReactNode
144
+ children?: React.ReactNode
145
+ closeLabel?: string
146
+ disabled?: boolean
147
+ flag?: React.ReactNode
148
+ icon?: React.ReactNode
149
+ onClose?: React.MouseEventHandler<HTMLButtonElement>
150
+ }
151
+
152
+ type TagContentProps = {
153
+ avatar?: React.ReactNode
154
+ children: React.ReactNode
155
+ closeLabel?: string
156
+ disabled: boolean
157
+ flag?: React.ReactNode
158
+ icon?: React.ReactNode
159
+ onClose?: React.MouseEventHandler<HTMLButtonElement>
160
+ showCloseButton: boolean
161
+ type: TagType
162
+ }
163
+
164
+ const Tag = React.forwardRef<HTMLSpanElement, TagProps>(function Tag({
165
+ asChild = false,
166
+ avatar,
167
+ children,
168
+ className,
169
+ closeLabel,
170
+ dir = "auto",
171
+ disabled = false,
172
+ flag,
173
+ icon,
174
+ onClose,
175
+ showCloseButton = false,
176
+ size = "md",
177
+ state = "default",
178
+ type = "simple",
179
+ ...props
180
+ }, ref) {
181
+ const Comp = asChild ? Slot : "span"
182
+ const resolvedType = (type || "simple") as TagType
183
+ const isDisabled = disabled || state === "disabled"
184
+ const resolvedState = isDisabled ? "disabled" : ((state || "default") as TagState)
185
+
186
+ return (
187
+ <Comp
188
+ aria-disabled={isDisabled || undefined}
189
+ data-disabled={isDisabled ? "true" : undefined}
190
+ data-size={size}
191
+ data-slot="tag"
192
+ data-state={resolvedState}
193
+ data-type={resolvedType}
194
+ dir={dir}
195
+ ref={ref}
196
+ className={cn(
197
+ tagVariants({
198
+ type: resolvedType,
199
+ size,
200
+ state: resolvedState,
201
+ showCloseButton,
202
+ }),
203
+ className
204
+ )}
205
+ {...props}
206
+ >
207
+ {asChild ? (
208
+ children
209
+ ) : (
210
+ <TagContent
211
+ avatar={avatar}
212
+ closeLabel={closeLabel}
213
+ disabled={isDisabled}
214
+ flag={flag}
215
+ icon={icon}
216
+ onClose={onClose}
217
+ showCloseButton={Boolean(showCloseButton)}
218
+ type={resolvedType}
219
+ >
220
+ {children}
221
+ </TagContent>
222
+ )}
223
+ </Comp>
224
+ )
225
+ })
226
+
227
+ function TagContent({
228
+ avatar,
229
+ children,
230
+ closeLabel,
231
+ disabled,
232
+ flag,
233
+ icon,
234
+ onClose,
235
+ showCloseButton,
236
+ type,
237
+ }: TagContentProps) {
238
+ return (
239
+ <>
240
+ {type === "dot" ? <TagDot /> : null}
241
+ {type === "flag" ? <TagFlag>{flag}</TagFlag> : null}
242
+ {type === "avatar" ? <TagAvatar>{avatar}</TagAvatar> : null}
243
+ {type === "icon" ? <TagIcon>{icon}</TagIcon> : null}
244
+ {renderTagChildren(children)}
245
+ {showCloseButton ? (
246
+ <TagCloseButton
247
+ disabled={disabled}
248
+ label={closeLabel}
249
+ offset={type === "dot"}
250
+ onClick={onClose}
251
+ />
252
+ ) : null}
253
+ </>
254
+ )
255
+ }
256
+
257
+ function renderTagChildren(
258
+ children: React.ReactNode,
259
+ keyPrefix = "tag-label"
260
+ ): React.ReactNode[] {
261
+ const renderedChildren: React.ReactNode[] = []
262
+
263
+ React.Children.toArray(children).forEach((child, index) => {
264
+ if (
265
+ typeof child === "string" ||
266
+ typeof child === "number" ||
267
+ typeof child === "bigint"
268
+ ) {
269
+ renderedChildren.push(
270
+ <span
271
+ key={`${keyPrefix}-${index}`}
272
+ data-slot="tag-label"
273
+ dir="auto"
274
+ className="min-w-0 truncate"
275
+ >
276
+ {child}
277
+ </span>
278
+ )
279
+
280
+ return
281
+ }
282
+
283
+ if (
284
+ React.isValidElement<{ children?: React.ReactNode }>(child) &&
285
+ child.type === React.Fragment
286
+ ) {
287
+ renderedChildren.push(
288
+ ...renderTagChildren(child.props.children, `${keyPrefix}-${index}`)
289
+ )
290
+
291
+ return
292
+ }
293
+
294
+ renderedChildren.push(child)
295
+ })
296
+
297
+ return renderedChildren
298
+ }
299
+
300
+ function TagDot({ className, ...props }: React.ComponentProps<"span">) {
301
+ return (
302
+ <span
303
+ aria-hidden="true"
304
+ data-slot="tag-dot"
305
+ className={cn(
306
+ "flex size-[var(--bh-space-4xl-20)] shrink-0 items-center justify-center",
307
+ className
308
+ )}
309
+ {...props}
310
+ >
311
+ <span className="size-[var(--bh-space-md-8)] rounded-[var(--bh-radius-full)] bg-[var(--bh-bg-accent-green-default)]" />
312
+ </span>
313
+ )
314
+ }
315
+
316
+ function TagFlag({
317
+ children,
318
+ className,
319
+ ...props
320
+ }: React.ComponentProps<"span">) {
321
+ return (
322
+ <span
323
+ data-slot="tag-flag"
324
+ aria-hidden={children ? undefined : "true"}
325
+ className={cn(
326
+ "flex size-[var(--bh-space-4xl-20)] shrink-0 items-center justify-center overflow-hidden rounded-[var(--bh-radius-xs-2)] bg-[var(--bh-bg-neutral-subtle)] text-[var(--bh-content-muted)]",
327
+ className
328
+ )}
329
+ {...props}
330
+ >
331
+ {children ?? (
332
+ <span className="grid size-full grid-rows-3">
333
+ <span className="bg-[var(--bh-bg-danger-default)]" />
334
+ <span className="bg-[var(--bh-bg-always-white)]" />
335
+ <span className="bg-[var(--bh-bg-always-dark)]" />
336
+ </span>
337
+ )}
338
+ </span>
339
+ )
340
+ }
341
+
342
+ function TagAvatar({
343
+ children,
344
+ className,
345
+ ...props
346
+ }: React.ComponentProps<"span">) {
347
+ return (
348
+ <span
349
+ data-slot="tag-avatar"
350
+ className={cn(
351
+ "flex size-[var(--bh-space-4xl-20)] shrink-0 items-center justify-center overflow-hidden rounded-[var(--bh-radius-full)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-neutral-default)] text-[length:var(--bh-text-body-3xs-semibold-font-size)] font-[var(--bh-text-body-3xs-semibold-font-weight)] leading-[var(--bh-text-body-3xs-semibold-line-height)] text-[var(--bh-content-on-color)]",
352
+ className
353
+ )}
354
+ {...props}
355
+ >
356
+ {children}
357
+ </span>
358
+ )
359
+ }
360
+
361
+ function TagIcon({
362
+ children,
363
+ className,
364
+ ...props
365
+ }: React.ComponentProps<"span">) {
366
+ return (
367
+ <span
368
+ data-slot="tag-icon"
369
+ className={cn(
370
+ "flex size-[var(--bh-space-4xl-20)] shrink-0 items-center justify-center text-current [&_svg]:size-[var(--bh-space-4xl-20)] [&_svg]:shrink-0",
371
+ className
372
+ )}
373
+ {...props}
374
+ >
375
+ {children ?? <PlusIcon aria-hidden="true" strokeWidth={2.25} />}
376
+ </span>
377
+ )
378
+ }
379
+
380
+ function TagCloseButton({
381
+ className,
382
+ disabled,
383
+ label,
384
+ offset,
385
+ type,
386
+ ...props
387
+ }: React.ComponentProps<"button"> & {
388
+ label?: string
389
+ offset?: boolean
390
+ }) {
391
+ return (
392
+ <button
393
+ aria-label={label}
394
+ data-slot="tag-close"
395
+ disabled={disabled}
396
+ type={type || "button"}
397
+ className={cn(
398
+ "relative z-[var(--bh-z-raised)] inline-flex size-[var(--bh-space-3xl-16)] shrink-0 items-center justify-center rounded-[var(--bh-radius-full)] text-current outline-none transition-[background-color,box-shadow]",
399
+ "hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:shadow-[var(--shadow-button-focus)] disabled:pointer-events-none",
400
+ offset && "ms-[var(--bh-space-xs-4)]",
401
+ className
402
+ )}
403
+ {...props}
404
+ >
405
+ <XIcon
406
+ aria-hidden="true"
407
+ className="size-[var(--bh-space-xl-12)]"
408
+ strokeWidth={2}
409
+ />
410
+ </button>
411
+ )
412
+ }
413
+
414
+ export {
415
+ Tag,
416
+ TagAvatar,
417
+ TagCloseButton,
418
+ TagDot,
419
+ TagFlag,
420
+ TagIcon,
421
+ tagVariants,
422
+ }
423
+ export type { TagProps, TagSize, TagState, TagType }