banhaten 0.1.0 → 0.1.2

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 (81) hide show
  1. package/README.md +21 -9
  2. package/package.json +8 -2
  3. package/registry/components/accordion.tsx +37 -1
  4. package/registry/components/alert.tsx +14 -28
  5. package/registry/components/attribute.tsx +6 -10
  6. package/registry/components/autocomplete.tsx +637 -0
  7. package/registry/components/avatar.tsx +259 -24
  8. package/registry/components/badge.tsx +97 -35
  9. package/registry/components/button-group.tsx +1 -1
  10. package/registry/components/card.tsx +1 -1
  11. package/registry/components/checkbox.tsx +19 -16
  12. package/registry/components/date-picker-state.ts +253 -0
  13. package/registry/components/date-picker.tsx +115 -158
  14. package/registry/components/expanded/ActivityFeed.tsx +37 -23
  15. package/registry/components/expanded/Banner.tsx +54 -19
  16. package/registry/components/expanded/Breadcrumbs.tsx +10 -38
  17. package/registry/components/expanded/CatalogComponentsShowcase.tsx +11 -16
  18. package/registry/components/expanded/CatalogTag.tsx +4 -11
  19. package/registry/components/expanded/CommandBar.tsx +33 -53
  20. package/registry/components/expanded/EmptyState.tsx +155 -0
  21. package/registry/components/expanded/FileUpload.tsx +362 -59
  22. package/registry/components/expanded/OnboardingStepListItem.tsx +6 -10
  23. package/registry/components/expanded/PageHeader.tsx +2 -11
  24. package/registry/components/expanded/Slideout.tsx +12 -23
  25. package/registry/components/expanded/Steps.tsx +6 -8
  26. package/registry/components/expanded/Table.tsx +18 -40
  27. package/registry/components/expanded/Timeline.tsx +5 -24
  28. package/registry/components/expanded/activityFeed.css +10 -54
  29. package/registry/components/expanded/banner.css +8 -75
  30. package/registry/components/expanded/breadcrumbs.css +1 -1
  31. package/registry/components/expanded/commandBar.css +23 -26
  32. package/registry/components/expanded/divider.css +1 -1
  33. package/registry/components/expanded/emptyState.css +111 -0
  34. package/registry/components/expanded/fileUpload.css +304 -75
  35. package/registry/components/expanded/pageHeader.css +1 -1
  36. package/registry/components/expanded/slideout.css +1 -0
  37. package/registry/components/expanded/steps.css +15 -51
  38. package/registry/components/expanded/table.css +6 -1
  39. package/registry/components/expanded/timeline.css +18 -15
  40. package/registry/components/input-otp.tsx +574 -0
  41. package/registry/components/input.tsx +140 -59
  42. package/registry/components/menu.tsx +470 -80
  43. package/registry/components/pagination.tsx +6 -18
  44. package/registry/components/popover.tsx +840 -0
  45. package/registry/components/radio-card.tsx +25 -31
  46. package/registry/components/select-content.tsx +28 -123
  47. package/registry/components/select.tsx +13 -9
  48. package/registry/components/skeleton.css +57 -0
  49. package/registry/components/skeleton.tsx +482 -0
  50. package/registry/components/social-button.tsx +24 -90
  51. package/registry/components/spinner.tsx +91 -7
  52. package/registry/components/textarea.tsx +21 -36
  53. package/registry/components/toggle.tsx +7 -23
  54. package/registry/components/tooltip.tsx +8 -4
  55. package/registry/examples/attribute-demo.tsx +2 -2
  56. package/registry/examples/autocomplete-demo.tsx +109 -0
  57. package/registry/examples/avatar-demo.tsx +102 -47
  58. package/registry/examples/badge-demo.tsx +16 -0
  59. package/registry/examples/checkbox-demo.tsx +3 -8
  60. package/registry/examples/date-picker-demo.tsx +75 -22
  61. package/registry/examples/expanded/banner-demo.tsx +31 -6
  62. package/registry/examples/expanded/breadcrumbs-demo.tsx +59 -0
  63. package/registry/examples/expanded/command-bar-demo.tsx +236 -0
  64. package/registry/examples/expanded/empty-state-demo.tsx +39 -0
  65. package/registry/examples/expanded/file-upload-demo.tsx +60 -0
  66. package/registry/examples/expanded/steps-demo.tsx +11 -0
  67. package/registry/examples/expanded/table-demo.tsx +142 -0
  68. package/registry/examples/input-demo.tsx +1 -1
  69. package/registry/examples/input-otp-demo.tsx +72 -0
  70. package/registry/examples/menu-demo.tsx +101 -88
  71. package/registry/examples/popover-demo.tsx +546 -0
  72. package/registry/examples/progress-demo.tsx +2 -2
  73. package/registry/examples/select-demo.tsx +32 -18
  74. package/registry/examples/skeleton-demo.tsx +56 -0
  75. package/registry/examples/social-button-demo.tsx +33 -33
  76. package/registry/examples/spinner-demo.tsx +59 -0
  77. package/registry/examples/tag-demo.tsx +1 -1
  78. package/registry/examples/textarea-demo.tsx +1 -1
  79. package/registry/index.json +266 -20
  80. package/registry/styles/globals.css +93 -3
  81. package/src/cli/index.js +997 -62
@@ -71,7 +71,7 @@ const badgeVariants = cva(
71
71
  "transition-[background-color,border-color,color,box-shadow]",
72
72
  "focus-visible:border-[var(--bh-border-focus)] focus-visible:ring-[length:var(--bh-badge-focus-ring-width)] focus-visible:ring-[var(--ring)]",
73
73
  "aria-invalid:border-[var(--bh-border-focus-danger)] aria-invalid:ring-[var(--danger-ring)]",
74
- "[&_svg]:pointer-events-none [&_svg]:size-[var(--bh-space-3xl-16)] [&_svg]:shrink-0",
74
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0",
75
75
  "rtl:[&_svg[data-rtl-flip='true']]:-scale-x-100",
76
76
  ],
77
77
  {
@@ -134,6 +134,11 @@ const badgeVariants = cva(
134
134
  true: "gap-[var(--bh-space-none)] px-[var(--bh-space-xs-4)] text-center",
135
135
  false: "",
136
136
  },
137
+ splitAction: {
138
+ true:
139
+ "overflow-hidden border-[var(--badge-split-border-color,currentColor)] pe-[var(--bh-space-none)]",
140
+ false: "[&_svg]:size-[var(--bh-space-3xl-16)]",
141
+ },
137
142
  },
138
143
  compoundVariants: [
139
144
  {
@@ -151,8 +156,15 @@ const badgeVariants = cva(
151
156
  {
152
157
  type: ["leading-icon", "trailing-icon", "dot"],
153
158
  showNumber: false,
159
+ splitAction: false,
154
160
  class: "px-[var(--bh-space-md-8)]",
155
161
  },
162
+ {
163
+ type: "trailing-icon",
164
+ showNumber: false,
165
+ splitAction: true,
166
+ class: "ps-[var(--bh-space-md-8)]",
167
+ },
156
168
  {
157
169
  type: "flag",
158
170
  showNumber: false,
@@ -174,181 +186,181 @@ const badgeVariants = cva(
174
186
  badgeStyle: "light",
175
187
  color: "neutral",
176
188
  class:
177
- "bg-[var(--bh-bg-neutral-subtle)] text-[var(--bh-content-default)] [--badge-dot-color:var(--bh-content-muted)]",
189
+ "bg-[var(--bh-bg-neutral-subtle)] text-[var(--bh-content-default)] [--badge-dot-color:var(--bh-content-muted)] [--badge-split-border-color:var(--bh-border-default)]",
178
190
  },
179
191
  {
180
192
  badgeStyle: "outline",
181
193
  color: "neutral",
182
194
  class:
183
- "border-[var(--bh-border-strong)] text-[var(--bh-content-subtle)] [--badge-dot-color:var(--bh-content-subtle)]",
195
+ "border-[var(--bh-border-strong)] text-[var(--bh-content-subtle)] [--badge-dot-color:var(--bh-content-subtle)] [--badge-split-border-color:var(--bh-border-default)]",
184
196
  },
185
197
  {
186
198
  badgeStyle: "solid",
187
199
  color: "neutral",
188
200
  class:
189
- "bg-[var(--bh-bg-neutral-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
201
+ "bg-[var(--bh-bg-neutral-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-subtle)]",
190
202
  },
191
203
  {
192
204
  badgeStyle: "light",
193
205
  color: "blue",
194
206
  class:
195
- "bg-[var(--bh-bg-accent-blue-subtle)] text-[var(--bh-content-accent-blue-strong)] [--badge-dot-color:var(--bh-content-accent-blue-default)]",
207
+ "bg-[var(--bh-bg-accent-blue-subtle)] text-[var(--bh-content-accent-blue-strong)] [--badge-dot-color:var(--bh-content-accent-blue-default)] [--badge-split-border-color:var(--bh-border-accent-blue-subtle)]",
196
208
  },
197
209
  {
198
210
  badgeStyle: "outline",
199
211
  color: "blue",
200
212
  class:
201
- "border-[var(--bh-border-accent-blue-strong)] text-[var(--bh-content-accent-blue-default)] [--badge-dot-color:var(--bh-content-accent-blue-default)]",
213
+ "border-[var(--bh-border-accent-blue-strong)] text-[var(--bh-content-accent-blue-default)] [--badge-dot-color:var(--bh-content-accent-blue-default)] [--badge-split-border-color:var(--bh-border-accent-blue-subtle)]",
202
214
  },
203
215
  {
204
216
  badgeStyle: "solid",
205
217
  color: "blue",
206
218
  class:
207
- "bg-[var(--bh-bg-accent-blue-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
219
+ "bg-[var(--bh-bg-accent-blue-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-blue-subtle)]",
208
220
  },
209
221
  {
210
222
  badgeStyle: "light",
211
223
  color: "green",
212
224
  class:
213
- "bg-[var(--bh-bg-accent-green-subtle)] text-[var(--bh-content-accent-green-strong)] [--badge-dot-color:var(--bh-content-accent-green-default)]",
225
+ "bg-[var(--bh-bg-accent-green-subtle)] text-[var(--bh-content-accent-green-strong)] [--badge-dot-color:var(--bh-content-accent-green-default)] [--badge-split-border-color:var(--bh-border-accent-green-subtle)]",
214
226
  },
215
227
  {
216
228
  badgeStyle: "outline",
217
229
  color: "green",
218
230
  class:
219
- "border-[var(--bh-border-accent-green-strong)] text-[var(--bh-content-accent-green-default)] [--badge-dot-color:var(--bh-content-accent-green-default)]",
231
+ "border-[var(--bh-border-accent-green-strong)] text-[var(--bh-content-accent-green-default)] [--badge-dot-color:var(--bh-content-accent-green-default)] [--badge-split-border-color:var(--bh-border-accent-green-subtle)]",
220
232
  },
221
233
  {
222
234
  badgeStyle: "solid",
223
235
  color: "green",
224
236
  class:
225
- "bg-[var(--bh-bg-accent-green-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
237
+ "bg-[var(--bh-bg-accent-green-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-green-subtle)]",
226
238
  },
227
239
  {
228
240
  badgeStyle: "light",
229
241
  color: "amber",
230
242
  class:
231
- "bg-[var(--bh-bg-accent-amber-subtle)] text-[var(--bh-content-accent-amber-strong)] [--badge-dot-color:var(--bh-content-accent-amber-default)]",
243
+ "bg-[var(--bh-bg-accent-amber-subtle)] text-[var(--bh-content-accent-amber-strong)] [--badge-dot-color:var(--bh-content-accent-amber-default)] [--badge-split-border-color:var(--bh-border-accent-amber-subtle)]",
232
244
  },
233
245
  {
234
246
  badgeStyle: "outline",
235
247
  color: "amber",
236
248
  class:
237
- "border-[var(--bh-border-accent-amber-strong)] text-[var(--bh-content-accent-amber-default)] [--badge-dot-color:var(--bh-content-accent-amber-default)]",
249
+ "border-[var(--bh-border-accent-amber-strong)] text-[var(--bh-content-accent-amber-default)] [--badge-dot-color:var(--bh-content-accent-amber-default)] [--badge-split-border-color:var(--bh-border-accent-amber-subtle)]",
238
250
  },
239
251
  {
240
252
  badgeStyle: "solid",
241
253
  color: "amber",
242
254
  class:
243
- "bg-[var(--bh-bg-accent-amber-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
255
+ "bg-[var(--bh-bg-accent-amber-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-amber-subtle)]",
244
256
  },
245
257
  {
246
258
  badgeStyle: "light",
247
259
  color: "danger",
248
260
  class:
249
- "bg-[var(--bh-bg-accent-red-subtle)] text-[var(--bh-content-accent-red-strong)] [--badge-dot-color:var(--bh-content-accent-red-default)]",
261
+ "bg-[var(--bh-bg-accent-red-subtle)] text-[var(--bh-content-accent-red-strong)] [--badge-dot-color:var(--bh-content-accent-red-default)] [--badge-split-border-color:var(--bh-border-accent-red-subtle)]",
250
262
  },
251
263
  {
252
264
  badgeStyle: "outline",
253
265
  color: "danger",
254
266
  class:
255
- "border-[var(--bh-border-accent-red-strong)] text-[var(--bh-content-accent-red-default)] [--badge-dot-color:var(--bh-content-accent-red-default)]",
267
+ "border-[var(--bh-border-accent-red-strong)] text-[var(--bh-content-accent-red-default)] [--badge-dot-color:var(--bh-content-accent-red-default)] [--badge-split-border-color:var(--bh-border-accent-red-subtle)]",
256
268
  },
257
269
  {
258
270
  badgeStyle: "solid",
259
271
  color: "danger",
260
272
  class:
261
- "bg-[var(--bh-bg-accent-red-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
273
+ "bg-[var(--bh-bg-accent-red-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-red-subtle)]",
262
274
  },
263
275
  {
264
276
  badgeStyle: "light",
265
277
  color: "purple",
266
278
  class:
267
- "bg-[var(--bh-bg-accent-purple-subtle)] text-[var(--bh-content-accent-purple-strong)] [--badge-dot-color:var(--bh-content-accent-purple-default)]",
279
+ "bg-[var(--bh-bg-accent-purple-subtle)] text-[var(--bh-content-accent-purple-strong)] [--badge-dot-color:var(--bh-content-accent-purple-default)] [--badge-split-border-color:var(--bh-border-accent-purple-subtle)]",
268
280
  },
269
281
  {
270
282
  badgeStyle: "outline",
271
283
  color: "purple",
272
284
  class:
273
- "border-[var(--bh-border-accent-purple-strong)] text-[var(--bh-content-accent-purple-default)] [--badge-dot-color:var(--bh-content-accent-purple-default)]",
285
+ "border-[var(--bh-border-accent-purple-strong)] text-[var(--bh-content-accent-purple-default)] [--badge-dot-color:var(--bh-content-accent-purple-default)] [--badge-split-border-color:var(--bh-border-accent-purple-subtle)]",
274
286
  },
275
287
  {
276
288
  badgeStyle: "solid",
277
289
  color: "purple",
278
290
  class:
279
- "bg-[var(--bh-bg-accent-purple-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
291
+ "bg-[var(--bh-bg-accent-purple-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-purple-subtle)]",
280
292
  },
281
293
  {
282
294
  badgeStyle: "light",
283
295
  color: "fuchsia",
284
296
  class:
285
- "bg-[var(--bh-bg-accent-fuchsia-subtle)] text-[var(--bh-content-accent-fuchsia-strong)] [--badge-dot-color:var(--bh-content-accent-fuchsia-default)]",
297
+ "bg-[var(--bh-bg-accent-fuchsia-subtle)] text-[var(--bh-content-accent-fuchsia-strong)] [--badge-dot-color:var(--bh-content-accent-fuchsia-default)] [--badge-split-border-color:var(--bh-border-accent-fuchsia-subtle)]",
286
298
  },
287
299
  {
288
300
  badgeStyle: "outline",
289
301
  color: "fuchsia",
290
302
  class:
291
- "border-[var(--bh-border-accent-fuchsia-strong)] text-[var(--bh-content-accent-fuchsia-default)] [--badge-dot-color:var(--bh-content-accent-fuchsia-default)]",
303
+ "border-[var(--bh-border-accent-fuchsia-strong)] text-[var(--bh-content-accent-fuchsia-default)] [--badge-dot-color:var(--bh-content-accent-fuchsia-default)] [--badge-split-border-color:var(--bh-border-accent-fuchsia-subtle)]",
292
304
  },
293
305
  {
294
306
  badgeStyle: "solid",
295
307
  color: "fuchsia",
296
308
  class:
297
- "bg-[var(--bh-bg-accent-fuchsia-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
309
+ "bg-[var(--bh-bg-accent-fuchsia-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-fuchsia-subtle)]",
298
310
  },
299
311
  {
300
312
  badgeStyle: "light",
301
313
  color: "rose",
302
314
  class:
303
- "bg-[var(--bh-bg-accent-rose-subtle)] text-[var(--bh-content-accent-rose-strong)] [--badge-dot-color:var(--bh-content-accent-rose-default)]",
315
+ "bg-[var(--bh-bg-accent-rose-subtle)] text-[var(--bh-content-accent-rose-strong)] [--badge-dot-color:var(--bh-content-accent-rose-default)] [--badge-split-border-color:var(--bh-border-accent-rose-subtle)]",
304
316
  },
305
317
  {
306
318
  badgeStyle: "outline",
307
319
  color: "rose",
308
320
  class:
309
- "border-[var(--bh-border-accent-rose-strong)] text-[var(--bh-content-accent-rose-default)] [--badge-dot-color:var(--bh-content-accent-rose-default)]",
321
+ "border-[var(--bh-border-accent-rose-strong)] text-[var(--bh-content-accent-rose-default)] [--badge-dot-color:var(--bh-content-accent-rose-default)] [--badge-split-border-color:var(--bh-border-accent-rose-subtle)]",
310
322
  },
311
323
  {
312
324
  badgeStyle: "solid",
313
325
  color: "rose",
314
326
  class:
315
- "bg-[var(--bh-bg-accent-rose-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
327
+ "bg-[var(--bh-bg-accent-rose-default)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-rose-subtle)]",
316
328
  },
317
329
  {
318
330
  badgeStyle: "light",
319
331
  color: "sky",
320
332
  class:
321
- "bg-[var(--bh-bg-accent-sky-subtle)] text-[var(--bh-content-accent-sky-strong)] [--badge-dot-color:var(--bh-content-accent-sky-default)]",
333
+ "bg-[var(--bh-bg-accent-sky-subtle)] text-[var(--bh-content-accent-sky-strong)] [--badge-dot-color:var(--bh-content-accent-sky-default)] [--badge-split-border-color:var(--bh-border-accent-sky-subtle)]",
322
334
  },
323
335
  {
324
336
  badgeStyle: "outline",
325
337
  color: "sky",
326
338
  class:
327
- "border-[var(--bh-border-accent-sky-strong)] text-[var(--bh-content-accent-sky-default)] [--badge-dot-color:var(--bh-content-accent-sky-default)]",
339
+ "border-[var(--bh-border-accent-sky-strong)] text-[var(--bh-content-accent-sky-default)] [--badge-dot-color:var(--bh-content-accent-sky-default)] [--badge-split-border-color:var(--bh-border-accent-sky-subtle)]",
328
340
  },
329
341
  {
330
342
  badgeStyle: "solid",
331
343
  color: "sky",
332
344
  class:
333
- "bg-[var(--bh-bg-accent-sky-base)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)]",
345
+ "bg-[var(--bh-bg-accent-sky-base)] text-[var(--bh-content-on-color)] [--badge-dot-color:var(--bh-content-on-color)] [--badge-split-border-color:var(--bh-border-accent-sky-subtle)]",
334
346
  },
335
347
  {
336
348
  badgeStyle: "light",
337
349
  color: "golden",
338
350
  class:
339
- "bg-[var(--bh-bg-accent-golden-subtle)] text-[var(--bh-content-accent-golden-strong)] [--badge-dot-color:var(--bh-content-accent-golden-default)]",
351
+ "bg-[var(--bh-bg-accent-golden-subtle)] text-[var(--bh-content-accent-golden-strong)] [--badge-dot-color:var(--bh-content-accent-golden-default)] [--badge-split-border-color:var(--bh-border-accent-golden-subtle)]",
340
352
  },
341
353
  {
342
354
  badgeStyle: "outline",
343
355
  color: "golden",
344
356
  class:
345
- "border-[var(--bh-border-accent-golden-strong)] text-[var(--bh-content-accent-golden-default)] [--badge-dot-color:var(--bh-content-accent-golden-default)]",
357
+ "border-[var(--bh-border-accent-golden-strong)] text-[var(--bh-content-accent-golden-default)] [--badge-dot-color:var(--bh-content-accent-golden-default)] [--badge-split-border-color:var(--bh-border-accent-golden-subtle)]",
346
358
  },
347
359
  {
348
360
  badgeStyle: "solid",
349
361
  color: "golden",
350
362
  class:
351
- "bg-[var(--bh-bg-accent-golden-default)] text-[var(--bh-content-on-light)] [--badge-dot-color:var(--bh-content-on-light)]",
363
+ "bg-[var(--bh-bg-accent-golden-default)] text-[var(--bh-content-on-light)] [--badge-dot-color:var(--bh-content-on-light)] [--badge-split-border-color:var(--bh-border-accent-golden-subtle)]",
352
364
  },
353
365
  ],
354
366
  defaultVariants: {
@@ -357,6 +369,7 @@ const badgeVariants = cva(
357
369
  type: "default",
358
370
  size: "sm",
359
371
  showNumber: false,
372
+ splitAction: false,
360
373
  },
361
374
  }
362
375
  )
@@ -373,7 +386,9 @@ type BadgeContentProps = {
373
386
  children: React.ReactNode
374
387
  flag?: React.ReactNode
375
388
  number?: React.ReactNode
389
+ size: BadgeSize
376
390
  showNumber: boolean
391
+ splitAction: boolean
377
392
  type: BadgeType
378
393
  }
379
394
 
@@ -385,6 +400,7 @@ const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(function Badge({
385
400
  type,
386
401
  size,
387
402
  showNumber = false,
403
+ splitAction = false,
388
404
  number,
389
405
  flag,
390
406
  asChild = false,
@@ -398,11 +414,15 @@ const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(function Badge({
398
414
  const resolvedBadgeStyle = badgeStyle ?? legacyVariant?.badgeStyle ?? "light"
399
415
  const resolvedColor = color ?? legacyVariant?.color ?? "neutral"
400
416
  const resolvedType = isNumber ? "default" : type ?? "default"
401
- const resolvedSize = size ?? "sm"
417
+ const resolvedSize = (size ?? "sm") as BadgeSize
418
+ const resolvedSplitAction =
419
+ !isNumber && resolvedType === "trailing-icon" && Boolean(splitAction)
402
420
  const contentProps = {
403
421
  flag,
404
422
  number,
423
+ size: resolvedSize,
405
424
  showNumber: isNumber,
425
+ splitAction: resolvedSplitAction,
406
426
  type: resolvedType,
407
427
  }
408
428
 
@@ -417,6 +437,7 @@ const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(function Badge({
417
437
  data-type={resolvedType}
418
438
  data-size={resolvedSize}
419
439
  data-show-number={isNumber ? "true" : "false"}
440
+ data-split-action={resolvedSplitAction ? "true" : "false"}
420
441
  dir={dir}
421
442
  ref={ref}
422
443
  className={cn(
@@ -426,6 +447,7 @@ const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(function Badge({
426
447
  type: resolvedType,
427
448
  size: resolvedSize,
428
449
  showNumber: isNumber,
450
+ splitAction: resolvedSplitAction,
429
451
  }),
430
452
  legacyVariant?.className,
431
453
  className
@@ -462,7 +484,9 @@ function BadgeContent({
462
484
  children,
463
485
  flag,
464
486
  number,
487
+ size,
465
488
  showNumber,
489
+ splitAction,
466
490
  type,
467
491
  }: BadgeContentProps) {
468
492
  const content = showNumber ? number ?? children : children
@@ -471,7 +495,7 @@ function BadgeContent({
471
495
  <>
472
496
  {!showNumber && type === "dot" ? <BadgeDot /> : null}
473
497
  {!showNumber && type === "flag" ? <BadgeFlag>{flag}</BadgeFlag> : null}
474
- {renderBadgeChildren(content, type)}
498
+ {renderBadgeChildren(content, type, splitAction, size)}
475
499
  </>
476
500
  )
477
501
  }
@@ -479,12 +503,17 @@ function BadgeContent({
479
503
  function renderBadgeChildren(
480
504
  children: React.ReactNode,
481
505
  type: BadgeType,
506
+ splitAction: boolean,
507
+ size: BadgeSize,
482
508
  keyPrefix = "badge-label"
483
509
  ): React.ReactNode[] {
510
+ const hasSplitTrailingAction = splitAction && type === "trailing-icon"
484
511
  const labelClassName = cn(
485
512
  "min-w-0",
486
513
  (type === "leading-icon" || type === "trailing-icon") &&
487
- "px-[var(--bh-space-xs-4)]"
514
+ "px-[var(--bh-space-xs-4)]",
515
+ hasSplitTrailingAction &&
516
+ "ps-[var(--bh-space-xs-4)] pe-[var(--bh-space-md-8)]"
488
517
  )
489
518
  const renderedChildren: React.ReactNode[] = []
490
519
 
@@ -516,6 +545,8 @@ function renderBadgeChildren(
516
545
  ...renderBadgeChildren(
517
546
  child.props.children,
518
547
  type,
548
+ false,
549
+ size,
519
550
  `${keyPrefix}-${index}`
520
551
  )
521
552
  )
@@ -526,7 +557,38 @@ function renderBadgeChildren(
526
557
  renderedChildren.push(child)
527
558
  })
528
559
 
529
- return renderedChildren
560
+ if (!hasSplitTrailingAction || renderedChildren.length < 2) {
561
+ return renderedChildren
562
+ }
563
+
564
+ return [
565
+ ...renderedChildren.slice(0, -1),
566
+ <BadgeSplitAction key={`${keyPrefix}-split-action`} size={size}>
567
+ {renderedChildren.at(-1)}
568
+ </BadgeSplitAction>,
569
+ ]
570
+ }
571
+
572
+ function BadgeSplitAction({
573
+ children,
574
+ size,
575
+ }: {
576
+ children: React.ReactNode
577
+ size: BadgeSize
578
+ }) {
579
+ return (
580
+ <span
581
+ data-slot="badge-split-action"
582
+ className={cn(
583
+ "flex h-full shrink-0 items-center justify-center border-s border-[var(--badge-split-border-color,currentColor)] text-current",
584
+ size === "lg"
585
+ ? "w-[calc(var(--bh-space-5xl-24)+var(--bh-space-xs-4))] [&_svg]:size-[var(--bh-space-2xl-14)]"
586
+ : "w-[var(--bh-space-5xl-24)] [&_svg]:size-[var(--bh-space-xl-12)]"
587
+ )}
588
+ >
589
+ {children}
590
+ </span>
591
+ )
530
592
  }
531
593
 
532
594
  function BadgeDot() {
@@ -18,7 +18,7 @@ const buttonGroupContext = React.createContext<ButtonGroupContextValue>({
18
18
  })
19
19
 
20
20
  const buttonGroupVariants = cva(
21
- "inline-flex items-center overflow-hidden rounded-[var(--bh-button-group-radius)] bg-[var(--bh-button-group-bg)] text-[var(--bh-button-group-content)] shadow-[var(--shadow-button-group)] [--shadow-button-group:inset_0px_0px_0px_var(--bh-border-width-default)_var(--bh-button-group-border),var(--shadow-component-default)]",
21
+ "inline-flex w-fit items-center overflow-hidden rounded-[var(--bh-button-group-radius)] bg-[var(--bh-button-group-bg)] text-[var(--bh-button-group-content)] shadow-[var(--shadow-button-group)] [--shadow-button-group:inset_0px_0px_0px_var(--bh-border-width-default)_var(--bh-button-group-border),var(--shadow-component-default)]",
22
22
  {
23
23
  variants: {
24
24
  size: {
@@ -393,7 +393,7 @@ function CardBody({
393
393
  </div>
394
394
 
395
395
  {showFooter ? (
396
- <CardFooter>
396
+ <CardFooter className={horizontal ? "mt-auto" : undefined}>
397
397
  {footer ??
398
398
  actions ?? (
399
399
  <CardActions
@@ -3,6 +3,7 @@
3
3
  import * as React from "react"
4
4
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
5
5
  import { cva, type VariantProps } from "class-variance-authority"
6
+ import { CheckIcon, MinusIcon } from "lucide-react"
6
7
 
7
8
  import { cn } from "@/lib/utils"
8
9
 
@@ -58,8 +59,18 @@ const Checkbox = React.forwardRef<
58
59
  data-slot="checkbox-indicator"
59
60
  className="pointer-events-none absolute top-1/2 left-1/2 flex size-[var(--bh-checkbox-icon-size)] -translate-x-1/2 -translate-y-1/2 items-center justify-center text-[var(--bh-content-on-color)] group-data-[disabled]/checkbox:text-[var(--bh-content-disabled)]"
60
61
  >
61
- <CheckFillIcon className="size-[var(--bh-checkbox-icon-size)] fill-current group-data-[state=indeterminate]/checkbox:hidden" />
62
- <span className="hidden h-[var(--bh-checkbox-indeterminate-height)] w-[var(--bh-checkbox-indeterminate-width)] rounded-full bg-current group-data-[state=indeterminate]/checkbox:block" />
62
+ <CheckIcon
63
+ aria-hidden="true"
64
+ className="size-[var(--bh-checkbox-icon-size)] group-data-[state=indeterminate]/checkbox:hidden"
65
+ focusable="false"
66
+ strokeWidth={3}
67
+ />
68
+ <MinusIcon
69
+ aria-hidden="true"
70
+ className="hidden size-[var(--bh-checkbox-icon-size)] group-data-[state=indeterminate]/checkbox:block"
71
+ focusable="false"
72
+ strokeWidth={3}
73
+ />
63
74
  </CheckboxPrimitive.Indicator>
64
75
  </CheckboxPrimitive.Root>
65
76
  )
@@ -216,25 +227,17 @@ function CheckboxCardIndicator({
216
227
  className="pointer-events-none absolute top-1/2 left-1/2 size-[var(--bh-checkbox-control-size)] -translate-x-1/2 -translate-y-1/2 rounded-[var(--bh-checkbox-control-radius)] bg-[var(--bh-bg-default)] shadow-[var(--shadow-checkbox-control)] [--bh-checkbox-control-border:var(--bh-border-input)] [--shadow-checkbox-control:inset_0px_0px_0px_var(--bh-border-width-default)_var(--bh-checkbox-control-border,var(--bh-border-input)),var(--shadow-component-default)] data-[state=checked]:[--bh-checkbox-control-border:transparent] data-[state=checked]:bg-[var(--bh-interactive-checkbox-default)] data-[disabled=true]:bg-[var(--bh-bg-disabled)] data-[disabled=true]:shadow-[inset_0px_0px_0px_var(--bh-border-width-default)_var(--bh-border-disabled)]"
217
228
  />
218
229
  {checked ? (
219
- <CheckFillIcon className="absolute top-1/2 left-1/2 size-[var(--bh-checkbox-icon-size)] -translate-x-1/2 -translate-y-1/2 fill-current text-[var(--bh-content-on-color)]" />
230
+ <CheckIcon
231
+ aria-hidden="true"
232
+ className="absolute top-1/2 left-1/2 size-[var(--bh-checkbox-icon-size)] -translate-x-1/2 -translate-y-1/2 text-[var(--bh-content-on-color)]"
233
+ focusable="false"
234
+ strokeWidth={3}
235
+ />
220
236
  ) : null}
221
237
  </span>
222
238
  )
223
239
  }
224
240
 
225
- function CheckFillIcon({ className }: { className?: string }) {
226
- return (
227
- <svg
228
- aria-hidden="true"
229
- className={className}
230
- focusable="false"
231
- viewBox="0 0 24 24"
232
- >
233
- <path d="M9.9997 15.1709L19.1921 5.97852L20.6063 7.39273L9.9997 17.9993L3.63574 11.6354L5.04996 10.2212L9.9997 15.1709Z" />
234
- </svg>
235
- )
236
- }
237
-
238
241
  export { Checkbox, CheckboxCard, checkboxCardVariants, checkboxVariants }
239
242
  export type {
240
243
  CheckboxCardControlPosition,