banhaten 0.1.2 → 0.2.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/CHANGELOG.md +45 -0
- package/CONTRIBUTING.md +44 -0
- package/README.md +145 -328
- package/SECURITY.md +15 -0
- package/banhaten.config.example.json +1 -3
- package/docs/design-system/README.md +20 -0
- package/docs/design-system/adoption-quality-remediation.md +87 -0
- package/docs/design-system/agent-usage.md +13 -0
- package/docs/design-system/appearance-presets.md +189 -0
- package/docs/design-system/appearances/default.md +94 -0
- package/docs/design-system/appearances/rounded.md +95 -0
- package/docs/design-system/appearances/sharp.md +95 -0
- package/docs/design-system/component-docs-pattern.md +81 -0
- package/docs/design-system/component-showcase-consistency-report.md +217 -0
- package/docs/design-system/component-token-consistency-audit.md +173 -0
- package/docs/design-system/components/README.md +75 -0
- package/docs/design-system/components/accordion.md +67 -0
- package/docs/design-system/components/activity-feed.md +106 -0
- package/docs/design-system/components/alert-dialog.md +87 -0
- package/docs/design-system/components/alert.md +111 -0
- package/docs/design-system/components/aspect-ratio.md +59 -0
- package/docs/design-system/components/attribute.md +103 -0
- package/docs/design-system/components/autocomplete.md +93 -0
- package/docs/design-system/components/avatar.md +70 -0
- package/docs/design-system/components/badge.md +72 -0
- package/docs/design-system/components/banner.md +99 -0
- package/docs/design-system/components/breadcrumbs.md +188 -0
- package/docs/design-system/components/button-group.md +117 -0
- package/docs/design-system/components/button.md +95 -0
- package/docs/design-system/components/card.md +95 -0
- package/docs/design-system/components/carousel.md +61 -0
- package/docs/design-system/components/catalog-components.md +59 -0
- package/docs/design-system/components/chart.md +58 -0
- package/docs/design-system/components/checkbox.md +68 -0
- package/docs/design-system/components/collapsible.md +63 -0
- package/docs/design-system/components/command.md +75 -0
- package/docs/design-system/components/context-menu.md +59 -0
- package/docs/design-system/components/date-picker.md +97 -0
- package/docs/design-system/components/divider.md +117 -0
- package/docs/design-system/components/empty-state.md +72 -0
- package/docs/design-system/components/field.md +86 -0
- package/docs/design-system/components/file-upload.md +199 -0
- package/docs/design-system/components/hover-card.md +61 -0
- package/docs/design-system/components/icons.md +48 -0
- package/docs/design-system/components/input-group.md +73 -0
- package/docs/design-system/components/input-otp.md +73 -0
- package/docs/design-system/components/input.md +84 -0
- package/docs/design-system/components/item.md +72 -0
- package/docs/design-system/components/kbd.md +62 -0
- package/docs/design-system/components/label.md +64 -0
- package/docs/design-system/components/menu.md +76 -0
- package/docs/design-system/components/menubar.md +60 -0
- package/docs/design-system/components/modal.md +119 -0
- package/docs/design-system/components/native-select.md +70 -0
- package/docs/design-system/components/navigation-menu.md +63 -0
- package/docs/design-system/components/onboarding-step-list-item.md +94 -0
- package/docs/design-system/components/page-header.md +98 -0
- package/docs/design-system/components/pagination.md +71 -0
- package/docs/design-system/components/popover.md +77 -0
- package/docs/design-system/components/progress-slider.md +66 -0
- package/docs/design-system/components/progress.md +92 -0
- package/docs/design-system/components/radio-card.md +65 -0
- package/docs/design-system/components/radio-group.md +72 -0
- package/docs/design-system/components/resizable.md +57 -0
- package/docs/design-system/components/scroll-area.md +60 -0
- package/docs/design-system/components/segmented-control.md +71 -0
- package/docs/design-system/components/select.md +87 -0
- package/docs/design-system/components/sheet.md +82 -0
- package/docs/design-system/components/sidebar.md +83 -0
- package/docs/design-system/components/skeleton.md +91 -0
- package/docs/design-system/components/slideout.md +77 -0
- package/docs/design-system/components/slider.md +81 -0
- package/docs/design-system/components/social-button.md +65 -0
- package/docs/design-system/components/spinner.md +77 -0
- package/docs/design-system/components/steps.md +77 -0
- package/docs/design-system/components/table.md +411 -0
- package/docs/design-system/components/tabs.md +69 -0
- package/docs/design-system/components/tag.md +95 -0
- package/docs/design-system/components/textarea.md +64 -0
- package/docs/design-system/components/timeline.md +95 -0
- package/docs/design-system/components/toast.md +73 -0
- package/docs/design-system/components/toggle.md +96 -0
- package/docs/design-system/components/toolbar.md +105 -0
- package/docs/design-system/components/tooltip.md +107 -0
- package/docs/design-system/components/typography.md +18 -0
- package/docs/design-system/density-and-elevation.md +44 -0
- package/docs/design-system/design-system-test-missing-items.md +368 -0
- package/docs/design-system/direction-and-localization.md +23 -0
- package/docs/design-system/form-recipes.md +73 -0
- package/docs/design-system/gap-promotion-policy.md +21 -0
- package/docs/design-system/gap-promotion-report.md +166 -0
- package/docs/design-system/icons.md +69 -0
- package/docs/design-system/installation.md +68 -0
- package/docs/design-system/launch-comparison-shadcn.md +98 -0
- package/docs/design-system/registry-and-cli.md +64 -0
- package/docs/design-system/release-policy.md +30 -0
- package/docs/design-system/roadmap.md +14 -0
- package/docs/design-system/support-matrix.md +23 -0
- package/docs/design-system/tabs.md +53 -0
- package/docs/design-system/token-governance.md +60 -0
- package/package.json +97 -65
- package/registry/component-contract.json +40 -0
- package/registry/components/alert-dialog.tsx +297 -0
- package/registry/components/alert.tsx +86 -65
- package/registry/components/aspect-ratio.tsx +30 -0
- package/registry/components/autocomplete.tsx +23 -9
- package/registry/components/avatar.tsx +7 -7
- package/registry/components/badge.tsx +1 -1
- package/registry/components/button-group.tsx +321 -4
- package/registry/components/button.tsx +38 -17
- package/registry/components/card.tsx +68 -59
- package/registry/components/carousel.tsx +282 -0
- package/registry/components/chart.tsx +203 -0
- package/registry/components/checkbox.tsx +3 -3
- package/registry/components/collapsible.tsx +69 -0
- package/registry/components/command.tsx +174 -0
- package/registry/components/context-menu.tsx +236 -0
- package/registry/components/date-picker.tsx +246 -105
- package/registry/components/expanded/ActivityFeed.tsx +6 -15
- package/registry/components/expanded/Banner.tsx +3 -3
- package/registry/components/expanded/Breadcrumbs.tsx +5 -5
- package/registry/components/expanded/CatalogComponentsShowcase.tsx +13 -13
- package/registry/components/expanded/CatalogDivider.tsx +1 -1
- package/registry/components/expanded/EmptyState.tsx +1 -1
- package/registry/components/expanded/FileUpload.tsx +9 -2
- package/registry/components/expanded/OnboardingStepListItem.tsx +2 -4
- package/registry/components/expanded/PageHeader.tsx +14 -14
- package/registry/components/expanded/Slideout.tsx +15 -415
- package/registry/components/expanded/Steps.tsx +4 -4
- package/registry/components/expanded/Table.tsx +116 -69
- package/registry/components/expanded/Timeline.tsx +3 -3
- package/registry/components/expanded/activityFeed.css +1 -1
- package/registry/components/expanded/breadcrumbs.css +139 -139
- package/registry/components/expanded/catalogComponentsShowcase.css +83 -83
- package/registry/components/expanded/divider.css +1 -1
- package/registry/components/expanded/emptyState.css +1 -1
- package/registry/components/expanded/fileUpload.css +6 -6
- package/registry/components/expanded/slideout.css +9 -685
- package/registry/components/expanded/steps.css +274 -274
- package/registry/components/expanded/table.css +2 -2
- package/registry/components/expanded/timeline.css +264 -264
- package/registry/components/field.tsx +230 -0
- package/registry/components/hover-card.tsx +48 -0
- package/registry/components/input-content.ts +1 -0
- package/registry/components/input-group.tsx +130 -0
- package/registry/components/input-otp.tsx +13 -3
- package/registry/components/input.tsx +70 -45
- package/registry/components/item.tsx +189 -0
- package/registry/components/kbd.tsx +151 -0
- package/registry/components/label.tsx +78 -0
- package/registry/components/menu.tsx +34 -246
- package/registry/components/menubar.tsx +226 -0
- package/registry/components/modal.tsx +216 -143
- package/registry/components/native-select.tsx +205 -0
- package/registry/components/navigation-menu.tsx +171 -0
- package/registry/components/pagination.tsx +80 -58
- package/registry/components/popover.tsx +162 -664
- package/registry/components/radio-card.tsx +116 -87
- package/registry/components/radio-group.tsx +1 -1
- package/registry/components/resizable.tsx +74 -0
- package/registry/components/scroll-area.tsx +67 -0
- package/registry/components/segmented-control.tsx +87 -0
- package/registry/components/select-content.tsx +2 -2
- package/registry/components/select.tsx +54 -20
- package/registry/components/sheet.tsx +305 -0
- package/registry/components/sidebar.tsx +352 -0
- package/registry/components/skeleton.css +0 -3
- package/registry/components/social-button.tsx +116 -30
- package/registry/components/spinner.tsx +18 -55
- package/registry/components/{expanded/tabs.css → tabs.css} +127 -106
- package/registry/components/tabs.tsx +246 -0
- package/registry/components/tag.tsx +2 -2
- package/registry/components/textarea.tsx +4 -4
- package/registry/components/toast.tsx +136 -0
- package/registry/components/toggle.tsx +2 -2
- package/registry/components/toolbar.tsx +89 -17
- package/registry/components/tooltip.tsx +1 -1
- package/registry/examples/alert-demo.tsx +25 -5
- package/registry/examples/alert-dialog-demo.tsx +42 -0
- package/registry/examples/aspect-ratio-demo.tsx +11 -0
- package/registry/examples/attribute-demo.tsx +1 -1
- package/registry/examples/autocomplete-demo.tsx +3 -3
- package/registry/examples/avatar-demo.tsx +7 -7
- package/registry/examples/badge-demo.tsx +1 -1
- package/registry/examples/button-demo.tsx +6 -6
- package/registry/examples/button-group-demo.tsx +23 -2
- package/registry/examples/card-demo.tsx +46 -8
- package/registry/examples/carousel-demo.tsx +43 -0
- package/registry/examples/chart-demo.tsx +33 -0
- package/registry/examples/checkbox-demo.tsx +5 -5
- package/registry/examples/collapsible-demo.tsx +16 -0
- package/registry/examples/collection-filter-bar-demo.tsx +135 -0
- package/registry/examples/command-demo.tsx +42 -0
- package/registry/examples/{expanded/command-bar-demo.tsx → command-palette-demo.tsx} +5 -15
- package/registry/examples/context-menu-demo.tsx +29 -0
- package/registry/examples/control-density-contract-demo.tsx +61 -0
- package/registry/examples/date-picker-demo.tsx +12 -12
- package/registry/examples/divider-demo.tsx +3 -3
- package/registry/examples/expanded/banner-demo.tsx +1 -1
- package/registry/examples/expanded/breadcrumbs-demo.tsx +1 -1
- package/registry/examples/expanded/empty-state-demo.tsx +1 -1
- package/registry/examples/expanded/file-upload-demo.tsx +1 -1
- package/registry/examples/expanded/onboarding-step-demo.tsx +1 -1
- package/registry/examples/expanded/slideout-demo.tsx +2 -2
- package/registry/examples/expanded/steps-demo.tsx +1 -1
- package/registry/examples/expanded/tabs-demo.tsx +2 -2
- package/registry/examples/expanded/timeline-demo.tsx +1 -1
- package/registry/examples/field-demo.tsx +51 -0
- package/registry/examples/hover-card-demo.tsx +23 -0
- package/registry/examples/input-demo.tsx +6 -6
- package/registry/examples/input-group-demo.tsx +16 -0
- package/registry/examples/input-otp-demo.tsx +4 -4
- package/registry/examples/item-demo.tsx +46 -0
- package/registry/examples/kbd-demo.tsx +11 -0
- package/registry/examples/label-demo.tsx +20 -0
- package/registry/examples/menu-demo.tsx +1 -1
- package/registry/examples/menubar-demo.tsx +34 -0
- package/registry/examples/modal-demo.tsx +67 -9
- package/registry/examples/native-select-demo.tsx +16 -0
- package/registry/examples/navigation-menu-demo.tsx +29 -0
- package/registry/examples/pagination-demo.tsx +6 -3
- package/registry/examples/popover-demo.tsx +19 -19
- package/registry/examples/progress-demo.tsx +1 -1
- package/registry/examples/progress-slider-demo.tsx +1 -1
- package/registry/examples/radio-card-demo.tsx +4 -4
- package/registry/examples/radio-group-demo.tsx +2 -2
- package/registry/examples/resizable-demo.tsx +22 -0
- package/registry/examples/results-toolbar-demo.tsx +44 -0
- package/registry/examples/scroll-area-demo.tsx +15 -0
- package/registry/examples/segmented-control-demo.tsx +39 -0
- package/registry/examples/select-demo.tsx +1 -1
- package/registry/examples/sheet-demo.tsx +47 -0
- package/registry/examples/sidebar-demo.tsx +55 -0
- package/registry/examples/slider-demo.tsx +3 -3
- package/registry/examples/social-button-demo.tsx +18 -8
- package/registry/examples/spinner-demo.tsx +13 -13
- package/registry/examples/tabs-demo.tsx +13 -0
- package/registry/examples/tag-demo.tsx +1 -1
- package/registry/examples/textarea-demo.tsx +4 -4
- package/registry/examples/toast-demo.tsx +35 -0
- package/registry/examples/toggle-demo.tsx +6 -6
- package/registry/examples/tooltip-demo.tsx +4 -4
- package/registry/guidance/USAGE.md +27 -0
- package/registry/hooks/use-direction.ts +193 -13
- package/registry/index.json +6010 -432
- package/registry/styles/globals.css +3112 -4690
- package/registry.json +1582 -0
- package/schema/config.schema.json +51 -0
- package/schema/registry.schema.json +190 -0
- package/schema/tokens.schema.json +163 -0
- package/src/cli/command-line.js +194 -0
- package/src/cli/config-editors.js +9 -0
- package/src/cli/doctor.js +399 -0
- package/src/cli/file-transaction.js +295 -0
- package/src/cli/global-css.js +153 -0
- package/src/cli/index.js +639 -1391
- package/src/cli/install-plan.js +592 -0
- package/src/cli/install-receipt.js +171 -0
- package/src/cli/jsonc.js +203 -0
- package/src/cli/package-install-state.js +254 -0
- package/src/cli/package-manager.js +238 -0
- package/src/cli/package-plan.js +185 -0
- package/src/cli/package-version.js +97 -0
- package/src/cli/registry-query.js +207 -0
- package/src/cli/reporting.js +55 -0
- package/src/cli/schema-validation.js +19 -0
- package/src/cli/source-scanner.js +686 -0
- package/src/cli/vite-config.js +478 -0
- package/tokens/banhaten.tokens.json +4313 -310
- package/registry/assets/avatars/avatar-02.jpg +0 -0
- package/registry/assets/avatars/avatar-03.jpg +0 -0
- package/registry/assets/avatars/avatar-04.jpg +0 -0
- package/registry/assets/avatars/avatar-05.jpg +0 -0
- package/registry/assets/avatars/avatar-06.jpg +0 -0
- package/registry/assets/avatars/avatar-07.jpg +0 -0
- package/registry/assets/avatars/avatar-08.jpg +0 -0
- package/registry/assets/avatars/avatar-09.jpg +0 -0
- package/registry/assets/avatars/avatar-10.jpg +0 -0
- package/registry/assets/avatars/avatar-11.jpg +0 -0
- package/registry/assets/avatars/avatar-12.jpg +0 -0
- package/registry/assets/avatars/avatar-13.jpg +0 -0
- package/registry/assets/avatars/avatar-14.jpg +0 -0
- package/registry/assets/avatars/avatar-15.jpg +0 -0
- package/registry/assets/avatars/avatar-16.jpg +0 -0
- package/registry/assets/avatars/avatar-17.jpg +0 -0
- package/registry/assets/avatars/avatar-18.jpg +0 -0
- package/registry/assets/avatars/avatar-19.jpg +0 -0
- package/registry/assets/avatars/avatar-20.jpg +0 -0
- package/registry/assets/avatars/avatar-21.jpg +0 -0
- package/registry/assets/avatars/avatar-22.jpg +0 -0
- package/registry/assets/avatars/avatar-23.jpg +0 -0
- package/registry/assets/avatars/avatar-24.jpg +0 -0
- package/registry/assets/avatars/avatar-25.jpg +0 -0
- package/registry/assets/avatars/avatar-26.jpg +0 -0
- package/registry/assets/avatars/avatar-27.jpg +0 -0
- package/registry/assets/avatars/avatar-28.jpg +0 -0
- package/registry/assets/avatars/avatar-29.jpg +0 -0
- package/registry/assets/avatars/avatar-30.jpg +0 -0
- package/registry/assets/avatars/avatar-31.jpg +0 -0
- package/registry/assets/avatars/avatar-32.jpg +0 -0
- package/registry/assets/avatars/avatar-33.jpg +0 -0
- package/registry/assets/avatars/avatar-34.jpg +0 -0
- package/registry/assets/avatars/avatar-35.jpg +0 -0
- package/registry/assets/image-assets.json +0 -744
- package/registry/assets/images/art-02.jpg +0 -0
- package/registry/assets/images/art-03.jpg +0 -0
- package/registry/assets/images/art-04.jpg +0 -0
- package/registry/assets/images/art-05.jpg +0 -0
- package/registry/assets/images/art-06.jpg +0 -0
- package/registry/assets/images/art-07.jpg +0 -0
- package/registry/assets/images/art-08.jpg +0 -0
- package/registry/assets/images/art-09.jpg +0 -0
- package/registry/assets/images/art-10.jpg +0 -0
- package/registry/assets/images/art-11.jpg +0 -0
- package/registry/assets/images/art-12.jpg +0 -0
- package/registry/assets/images/art-13.jpg +0 -0
- package/registry/assets/images/art-14.jpg +0 -0
- package/registry/assets/images/art-15.jpg +0 -0
- package/registry/assets/images/art-16.jpg +0 -0
- package/registry/assets/images/art-17.jpg +0 -0
- package/registry/assets/images/art-18.jpg +0 -0
- package/registry/assets/images/art-19.jpg +0 -0
- package/registry/assets/images/art-20.jpg +0 -0
- package/registry/assets/images/art-21.jpg +0 -0
- package/registry/assets/images/art-22.jpg +0 -0
- package/registry/assets/images/art-23.jpg +0 -0
- package/registry/assets/images/art-24.jpg +0 -0
- package/registry/assets/images/art-25.jpg +0 -0
- package/registry/assets/images/art-26.jpg +0 -0
- package/registry/assets/images/art-27.jpg +0 -0
- package/registry/assets/images/nature-01.jpg +0 -0
- package/registry/assets/images/nature-02.jpg +0 -0
- package/registry/assets/images/nature-03.jpg +0 -0
- package/registry/assets/images/nature-04.jpg +0 -0
- package/registry/assets/images/nature-05.jpg +0 -0
- package/registry/assets/images/nature-06.jpg +0 -0
- package/registry/assets/images/nature-07.jpg +0 -0
- package/registry/assets/images/nature-08.jpg +0 -0
- package/registry/assets/images/nature-09.jpg +0 -0
- package/registry/assets/images/nature-10.jpg +0 -0
- package/registry/assets/images/nature-11.jpg +0 -0
- package/registry/assets/images/nature-12.jpg +0 -0
- package/registry/assets/images/nature-13.jpg +0 -0
- package/registry/assets/images/nature-14.jpg +0 -0
- package/registry/assets/images/nature-15.jpg +0 -0
- package/registry/assets/images/nature-16.jpg +0 -0
- package/registry/assets/images/nature-17.jpg +0 -0
- package/registry/assets/images/nature-18.jpg +0 -0
- package/registry/assets/images/nature-19.jpg +0 -0
- package/registry/assets/images/nature-20.jpg +0 -0
- package/registry/components/expanded/BannerBoard.tsx +0 -225
- package/registry/components/expanded/CatalogTag.tsx +0 -85
- package/registry/components/expanded/CommandBar.tsx +0 -386
- package/registry/components/expanded/IconExplorer.tsx +0 -612
- package/registry/components/expanded/Tabs.tsx +0 -86
- package/registry/components/expanded/TimelineShowcase.tsx +0 -158
- package/registry/components/expanded/commandBar.css +0 -470
- package/registry/components/expanded/iconExplorer.css +0 -764
- package/registry/components/expanded/iconPacks.ts +0 -866
- package/registry/components/expanded/tag.css +0 -148
- package/registry/examples/expanded/icons-demo.tsx +0 -5
- package/tokens/Color mode.zip +0 -0
- package/tokens/Numbers.zip +0 -0
- package/tokens/Radius.zip +0 -0
- package/tokens/Theme.zip +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import {
|
|
5
|
+
Toaster as SonnerToaster,
|
|
6
|
+
toast as sonnerToast,
|
|
7
|
+
type ExternalToast,
|
|
8
|
+
type ToasterProps as SonnerToasterProps,
|
|
9
|
+
} from "sonner"
|
|
10
|
+
|
|
11
|
+
import { cn } from "@/lib/utils"
|
|
12
|
+
import { useResolvedDirection } from "@/hooks/use-direction"
|
|
13
|
+
|
|
14
|
+
type ToastIntent = "default" | "success" | "danger" | "warning" | "info"
|
|
15
|
+
type ToastSide = "start" | "end"
|
|
16
|
+
type ToastOptions = ExternalToast & {
|
|
17
|
+
intent?: ToastIntent
|
|
18
|
+
}
|
|
19
|
+
type ToasterProps = Omit<SonnerToasterProps, "position"> & {
|
|
20
|
+
dir?: "ltr" | "rtl"
|
|
21
|
+
position?: SonnerToasterProps["position"]
|
|
22
|
+
side?: ToastSide
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const intentClassNames: Record<ToastIntent, string> = {
|
|
26
|
+
danger:
|
|
27
|
+
"[--bh-toast-accent:var(--bh-content-danger-default)] [--bh-toast-accent-bg:var(--bh-bg-danger-subtle)]",
|
|
28
|
+
default:
|
|
29
|
+
"[--bh-toast-accent:var(--bh-content-brand-default)] [--bh-toast-accent-bg:var(--bh-bg-brand-subtle)]",
|
|
30
|
+
info:
|
|
31
|
+
"[--bh-toast-accent:var(--bh-content-brand-default)] [--bh-toast-accent-bg:var(--bh-bg-info-subtle)]",
|
|
32
|
+
success:
|
|
33
|
+
"[--bh-toast-accent:var(--bh-content-success-default)] [--bh-toast-accent-bg:var(--bh-bg-success-subtle)]",
|
|
34
|
+
warning:
|
|
35
|
+
"[--bh-toast-accent:var(--bh-content-warning-default)] [--bh-toast-accent-bg:var(--bh-bg-warning-subtle)]",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const toastClassName = [
|
|
39
|
+
"border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-raised)] text-[var(--bh-content-default)] shadow-[var(--shadow-component-default)]",
|
|
40
|
+
"rounded-[var(--bh-radius-xl-10)] font-[var(--bh-font-family)]",
|
|
41
|
+
"[--normal-bg:var(--bh-bg-raised)] [--normal-border:var(--bh-border-subtle)] [--normal-text:var(--bh-content-default)]",
|
|
42
|
+
"[--success-bg:var(--bh-bg-raised)] [--success-border:var(--bh-border-success-subtle)] [--success-text:var(--bh-content-default)]",
|
|
43
|
+
"[--error-bg:var(--bh-bg-raised)] [--error-border:var(--bh-border-danger-subtle)] [--error-text:var(--bh-content-default)]",
|
|
44
|
+
"[--warning-bg:var(--bh-bg-raised)] [--warning-border:var(--bh-border-warning-subtle)] [--warning-text:var(--bh-content-default)]",
|
|
45
|
+
"[--info-bg:var(--bh-bg-raised)] [--info-border:var(--bh-border-info-subtle)] [--info-text:var(--bh-content-default)]",
|
|
46
|
+
].join(" ")
|
|
47
|
+
|
|
48
|
+
function Toaster({
|
|
49
|
+
className,
|
|
50
|
+
closeButton = true,
|
|
51
|
+
dir,
|
|
52
|
+
position,
|
|
53
|
+
richColors = false,
|
|
54
|
+
side = "end",
|
|
55
|
+
toastOptions,
|
|
56
|
+
...props
|
|
57
|
+
}: ToasterProps) {
|
|
58
|
+
const directionBoundaryRef = React.useRef<HTMLSpanElement | null>(null)
|
|
59
|
+
const resolvedDirection = useResolvedDirection(dir, directionBoundaryRef)
|
|
60
|
+
const resolvedPosition = position ?? getToastPosition(resolvedDirection, side)
|
|
61
|
+
const mergedToastOptions: ToasterProps["toastOptions"] = {
|
|
62
|
+
...toastOptions,
|
|
63
|
+
classNames: {
|
|
64
|
+
...toastOptions?.classNames,
|
|
65
|
+
toast: cn(toastClassName, toastOptions?.classNames?.toast),
|
|
66
|
+
title: cn(
|
|
67
|
+
"text-[length:var(--bh-text-body-sm-semibold-font-size)] font-[var(--bh-text-body-sm-semibold-font-weight)] leading-[var(--bh-text-body-sm-semibold-line-height)] tracking-[var(--bh-text-body-sm-semibold-letter-spacing)]",
|
|
68
|
+
toastOptions?.classNames?.title
|
|
69
|
+
),
|
|
70
|
+
description: cn(
|
|
71
|
+
"text-[length:var(--bh-text-body-xs-regular-font-size)] font-[var(--bh-text-body-xs-regular-font-weight)] leading-[var(--bh-text-body-xs-regular-line-height)] tracking-[var(--bh-text-body-xs-regular-letter-spacing)] text-[var(--bh-content-subtle)]",
|
|
72
|
+
toastOptions?.classNames?.description
|
|
73
|
+
),
|
|
74
|
+
actionButton: cn(
|
|
75
|
+
"rounded-[var(--bh-control-default)] bg-[var(--bh-interactive-brand-default)] px-[var(--bh-space-lg-10)] py-[var(--bh-space-xs-4)] text-[var(--bh-content-on-brand)]",
|
|
76
|
+
toastOptions?.classNames?.actionButton
|
|
77
|
+
),
|
|
78
|
+
cancelButton: cn(
|
|
79
|
+
"rounded-[var(--bh-control-default)] bg-[var(--bh-bg-neutral-soft)] px-[var(--bh-space-lg-10)] py-[var(--bh-space-xs-4)] text-[var(--bh-content-default)]",
|
|
80
|
+
toastOptions?.classNames?.cancelButton
|
|
81
|
+
),
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<span className="contents" data-slot="toaster-direction-boundary" ref={directionBoundaryRef}>
|
|
87
|
+
<SonnerToaster
|
|
88
|
+
className={cn("toaster group", className)}
|
|
89
|
+
closeButton={closeButton}
|
|
90
|
+
dir={resolvedDirection}
|
|
91
|
+
position={resolvedPosition}
|
|
92
|
+
richColors={richColors}
|
|
93
|
+
toastOptions={mergedToastOptions}
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
</span>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function showToast(message: React.ReactNode, options: ToastOptions = {}) {
|
|
101
|
+
const { intent = "default", className, ...rest } = options
|
|
102
|
+
return sonnerToast(message, {
|
|
103
|
+
className: cn(intentClassNames[intent], className),
|
|
104
|
+
...rest,
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const toast = Object.assign(showToast, {
|
|
109
|
+
danger: (message: React.ReactNode, options?: Omit<ToastOptions, "intent">) =>
|
|
110
|
+
showToast(message, { ...options, intent: "danger" }),
|
|
111
|
+
dismiss: sonnerToast.dismiss,
|
|
112
|
+
error: (message: React.ReactNode, options?: Omit<ToastOptions, "intent">) =>
|
|
113
|
+
showToast(message, { ...options, intent: "danger" }),
|
|
114
|
+
info: (message: React.ReactNode, options?: Omit<ToastOptions, "intent">) =>
|
|
115
|
+
showToast(message, { ...options, intent: "info" }),
|
|
116
|
+
loading: sonnerToast.loading,
|
|
117
|
+
promise: sonnerToast.promise,
|
|
118
|
+
success: (message: React.ReactNode, options?: Omit<ToastOptions, "intent">) =>
|
|
119
|
+
showToast(message, { ...options, intent: "success" }),
|
|
120
|
+
warning: (message: React.ReactNode, options?: Omit<ToastOptions, "intent">) =>
|
|
121
|
+
showToast(message, { ...options, intent: "warning" }),
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
function getToastPosition(
|
|
125
|
+
dir: ToasterProps["dir"],
|
|
126
|
+
side: ToastSide
|
|
127
|
+
): SonnerToasterProps["position"] {
|
|
128
|
+
if (side === "start") {
|
|
129
|
+
return dir === "rtl" ? "top-right" : "top-left"
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return dir === "rtl" ? "top-left" : "top-right"
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { Toaster, toast }
|
|
136
|
+
export type { ToastIntent, ToastOptions, ToasterProps }
|
|
@@ -231,7 +231,7 @@ function ToggleCheckIcon({ className }: { className?: string }) {
|
|
|
231
231
|
aria-hidden="true"
|
|
232
232
|
className={className}
|
|
233
233
|
focusable="false"
|
|
234
|
-
strokeWidth=
|
|
234
|
+
strokeWidth="var(--bh-icon-stroke-250)"
|
|
235
235
|
/>
|
|
236
236
|
)
|
|
237
237
|
}
|
|
@@ -242,7 +242,7 @@ function ToggleCloseIcon({ className }: { className?: string }) {
|
|
|
242
242
|
aria-hidden="true"
|
|
243
243
|
className={className}
|
|
244
244
|
focusable="false"
|
|
245
|
-
strokeWidth=
|
|
245
|
+
strokeWidth="var(--bh-icon-stroke-250)"
|
|
246
246
|
/>
|
|
247
247
|
)
|
|
248
248
|
}
|
|
@@ -9,6 +9,12 @@ import {
|
|
|
9
9
|
} from "lucide-react"
|
|
10
10
|
|
|
11
11
|
import { cn } from "@/lib/utils"
|
|
12
|
+
import {
|
|
13
|
+
KbdShortcut,
|
|
14
|
+
type ShortcutPlatform,
|
|
15
|
+
} from "@/components/ui/kbd"
|
|
16
|
+
|
|
17
|
+
type ControlDensity = "compact" | "default" | "comfortable"
|
|
12
18
|
|
|
13
19
|
const toolbarVariants = cva(
|
|
14
20
|
"flex w-full max-w-full min-w-0 gap-[var(--bh-space-3xl-16)] text-[var(--bh-content-default)]",
|
|
@@ -65,37 +71,44 @@ const toolbarSectionVariants = cva(
|
|
|
65
71
|
)
|
|
66
72
|
|
|
67
73
|
const toolbarButtonVariants = cva(
|
|
68
|
-
"group/toolbar-button inline-flex min-w-0 items-center justify-center whitespace-nowrap rounded-[var(--bh-control-default)] text-[length:var(--bh-text-button-font-size)] font-[var(--bh-text-button-font-weight)] leading-[var(--bh-text-button-line-height)] tracking-[var(--bh-text-button-letter-spacing)] outline-none transition-[background-color,border-color,color,box-shadow] focus-visible:shadow-[var(--shadow-button-focus)] disabled:pointer-events-none disabled:shadow-none aria-invalid:border aria-invalid:border-
|
|
74
|
+
"group/toolbar-button inline-flex min-w-0 items-center justify-center whitespace-nowrap rounded-[var(--bh-control-default)] text-[length:var(--bh-text-button-font-size)] font-[var(--bh-text-button-font-weight)] leading-[var(--bh-text-button-line-height)] tracking-[var(--bh-text-button-letter-spacing)] outline-none transition-[background-color,border-color,color,box-shadow] focus-visible:shadow-[var(--shadow-button-focus)] disabled:pointer-events-none disabled:shadow-none aria-invalid:border-[length:var(--bh-border-width-default)] aria-invalid:border-[var(--bh-border-danger-strong)] aria-invalid:shadow-[var(--shadow-button-danger-focus)] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-[var(--bh-button-icon-size)] [&_svg[data-icon='inline-start']]:ms-[var(--bh-button-icon-offset)] [&_svg[data-icon='inline-end']]:me-[var(--bh-button-icon-offset)] rtl:[&_svg[data-rtl-flip='true']]:-scale-x-100",
|
|
69
75
|
{
|
|
70
76
|
variants: {
|
|
71
77
|
variant: {
|
|
72
78
|
default:
|
|
73
|
-
"bg-
|
|
74
|
-
soft: "border border-transparent bg-[var(--soft)] text-
|
|
79
|
+
"bg-[var(--bh-interactive-brand-default)] text-[var(--bh-content-on-brand)] shadow-[var(--shadow-button-raised)] hover:bg-[var(--bh-interactive-brand-hover)] active:bg-[var(--bh-interactive-brand-pressed)] disabled:bg-[var(--bh-interactive-brand-disabled)] disabled:text-[var(--bh-content-disabled)]",
|
|
80
|
+
soft: "border-[length:var(--bh-border-width-default)] border-transparent bg-[var(--bh-interactive-soft-default)] text-[var(--bh-content-default)] shadow-[var(--shadow-button-soft)] hover:bg-[var(--bh-interactive-soft-hover)] active:bg-[var(--bh-interactive-soft-pressed)] focus-visible:border-[var(--bh-border-brand-strong)] disabled:bg-[var(--bh-interactive-soft-disabled)] disabled:text-[var(--bh-content-disabled)]",
|
|
75
81
|
outline:
|
|
76
|
-
"border border-[var(--bh-border-default)] bg-[var(--
|
|
82
|
+
"border-[length:var(--bh-border-width-default)] border-[var(--bh-border-default)] bg-[var(--bh-interactive-outlined-default)] text-[var(--bh-content-default)] hover:bg-[var(--bh-interactive-outlined-hover)] active:bg-[var(--bh-interactive-outlined-pressed)] focus-visible:border-[var(--bh-border-brand-strong)] disabled:border-[var(--bh-border-disabled)] disabled:bg-[var(--bh-interactive-outlined-disabled)] disabled:text-[var(--bh-content-disabled)]",
|
|
77
83
|
ghost:
|
|
78
|
-
"border border-transparent bg-[var(--ghost)] text-
|
|
79
|
-
link: "border border-transparent bg-[var(--ghost)] text-[var(--bh-content-brand-default)] hover:bg-[var(--ghost-hover)] active:bg-[var(--ghost-pressed)] focus-visible:border-[var(--bh-border-brand-strong)] disabled:bg-[var(--bh-interactive-ghost-disabled)] disabled:text-[var(--bh-content-disabled)]",
|
|
84
|
+
"border-[length:var(--bh-border-width-default)] border-transparent bg-[var(--bh-interactive-ghost-default)] text-[var(--bh-content-default)] hover:bg-[var(--bh-interactive-ghost-hover)] active:bg-[var(--bh-interactive-ghost-pressed)] focus-visible:border-[var(--bh-border-brand-strong)] disabled:bg-[var(--bh-interactive-ghost-disabled)] disabled:text-[var(--bh-content-disabled)]",
|
|
85
|
+
link: "border-[length:var(--bh-border-width-default)] border-transparent bg-[var(--bh-interactive-ghost-default)] text-[var(--bh-content-brand-default)] hover:bg-[var(--bh-interactive-ghost-hover)] active:bg-[var(--bh-interactive-ghost-pressed)] focus-visible:border-[var(--bh-border-brand-strong)] disabled:bg-[var(--bh-interactive-ghost-disabled)] disabled:text-[var(--bh-content-disabled)]",
|
|
80
86
|
},
|
|
81
87
|
size: {
|
|
88
|
+
xs: "h-[var(--bh-button-xs-height)] gap-[var(--bh-button-gap-xs)] px-[var(--bh-button-xs-padding-x)] py-[var(--bh-button-sm-padding-y)] has-[>svg]:px-[var(--bh-button-xs-padding-x)]",
|
|
82
89
|
sm: "h-[var(--bh-button-sm-height)] gap-[var(--bh-button-gap)] px-[var(--bh-button-sm-padding-x)] py-[var(--bh-button-sm-padding-y)] has-[>svg]:px-[var(--bh-button-sm-padding-x)]",
|
|
83
90
|
default: "h-[var(--bh-button-md-height)] gap-[var(--bh-button-gap)] px-[var(--bh-button-md-padding-x)] py-[var(--bh-button-sm-padding-y)] has-[>svg]:px-[var(--bh-button-md-padding-x)]",
|
|
91
|
+
"icon-xs": "size-[var(--bh-button-xs-height)] gap-[var(--bh-space-none)] p-[var(--bh-space-none)]",
|
|
84
92
|
"icon-sm": "size-[var(--bh-button-sm-height)] gap-[var(--bh-space-none)] p-[var(--bh-space-none)]",
|
|
85
93
|
icon: "size-[var(--bh-button-md-height)] gap-[var(--bh-space-none)] p-[var(--bh-space-none)]",
|
|
86
94
|
},
|
|
87
95
|
},
|
|
88
96
|
defaultVariants: {
|
|
89
97
|
variant: "soft",
|
|
90
|
-
size: "
|
|
98
|
+
size: "sm",
|
|
91
99
|
},
|
|
92
100
|
}
|
|
93
101
|
)
|
|
94
102
|
|
|
95
103
|
const toolbarSearchVariants = cva(
|
|
96
|
-
"flex
|
|
104
|
+
"flex max-w-full min-w-0 items-center gap-[var(--bh-input-content-gap)] rounded-[var(--bh-input-radius)] bg-[var(--bh-interactive-input-default)] text-[var(--bh-content-default)] shadow-[var(--shadow-input)] transition-[background-color,box-shadow] focus-within:shadow-[var(--shadow-input-focus-ring)] data-[disabled=true]:pointer-events-none data-[disabled=true]:bg-[var(--bh-interactive-input-disabled)] data-[disabled=true]:text-[var(--bh-content-disabled)]",
|
|
97
105
|
{
|
|
98
106
|
variants: {
|
|
107
|
+
density: {
|
|
108
|
+
compact: "h-[var(--bh-input-md-height)] px-[var(--bh-input-md-padding-x)]",
|
|
109
|
+
default: "h-[var(--bh-input-lg-height)] px-[var(--bh-input-lg-padding-x)]",
|
|
110
|
+
comfortable: "h-[var(--bh-input-comfortable-height)] px-[var(--bh-input-comfortable-padding-x)]",
|
|
111
|
+
},
|
|
99
112
|
width: {
|
|
100
113
|
compact: "w-[calc(var(--bh-input-width)/2)]",
|
|
101
114
|
default: "w-[var(--bh-input-width)]",
|
|
@@ -104,15 +117,21 @@ const toolbarSearchVariants = cva(
|
|
|
104
117
|
},
|
|
105
118
|
},
|
|
106
119
|
defaultVariants: {
|
|
120
|
+
density: "default",
|
|
107
121
|
width: "default",
|
|
108
122
|
},
|
|
109
123
|
}
|
|
110
124
|
)
|
|
111
125
|
|
|
112
126
|
const toolbarSelectVariants = cva(
|
|
113
|
-
"inline-flex
|
|
127
|
+
"inline-flex max-w-full min-w-0 items-center justify-between gap-[var(--bh-space-md-8)] rounded-[var(--bh-input-radius)] bg-[var(--bh-interactive-input-default)] px-[var(--bh-select-trigger-padding-x)] text-start text-[length:var(--bh-text-body-md-regular-font-size)] font-[var(--bh-text-body-md-regular-font-weight)] leading-[var(--bh-text-body-md-regular-line-height)] tracking-[var(--bh-text-body-md-regular-letter-spacing)] text-[var(--bh-content-default)] shadow-[var(--shadow-select-trigger)] outline-none transition-[background-color,box-shadow] hover:bg-[var(--bh-bg-default-hover)] focus-visible:shadow-[var(--shadow-input-focus-ring)] disabled:pointer-events-none disabled:bg-[var(--bh-interactive-input-disabled)] disabled:text-[var(--bh-content-disabled)]",
|
|
114
128
|
{
|
|
115
129
|
variants: {
|
|
130
|
+
density: {
|
|
131
|
+
compact: "h-[var(--bh-input-md-height)]",
|
|
132
|
+
default: "h-[var(--bh-input-lg-height)]",
|
|
133
|
+
comfortable: "h-[var(--bh-input-comfortable-height)]",
|
|
134
|
+
},
|
|
116
135
|
width: {
|
|
117
136
|
compact: "w-[calc(var(--bh-select-width)/2)]",
|
|
118
137
|
default: "w-[var(--bh-select-width)]",
|
|
@@ -121,6 +140,7 @@ const toolbarSelectVariants = cva(
|
|
|
121
140
|
},
|
|
122
141
|
},
|
|
123
142
|
defaultVariants: {
|
|
143
|
+
density: "default",
|
|
124
144
|
width: "compact",
|
|
125
145
|
},
|
|
126
146
|
}
|
|
@@ -201,20 +221,39 @@ const ToolbarSpacer = React.forwardRef<HTMLDivElement, ToolbarSpacerProps>(
|
|
|
201
221
|
type ToolbarButtonProps = React.ComponentProps<"button"> &
|
|
202
222
|
VariantProps<typeof toolbarButtonVariants> & {
|
|
203
223
|
asChild?: boolean
|
|
224
|
+
density?: ControlDensity
|
|
204
225
|
}
|
|
205
226
|
|
|
227
|
+
type ToolbarButtonSize = NonNullable<
|
|
228
|
+
VariantProps<typeof toolbarButtonVariants>["size"]
|
|
229
|
+
>
|
|
230
|
+
|
|
206
231
|
const ToolbarButton = React.forwardRef<HTMLButtonElement, ToolbarButtonProps>(
|
|
207
232
|
function ToolbarButton(
|
|
208
|
-
{
|
|
233
|
+
{
|
|
234
|
+
asChild = false,
|
|
235
|
+
children,
|
|
236
|
+
className,
|
|
237
|
+
density,
|
|
238
|
+
size,
|
|
239
|
+
type = "button",
|
|
240
|
+
variant,
|
|
241
|
+
...props
|
|
242
|
+
},
|
|
209
243
|
ref
|
|
210
244
|
) {
|
|
211
245
|
const Comp = asChild ? Slot : "button"
|
|
246
|
+
const resolvedSize = resolveToolbarButtonSize(density, size)
|
|
212
247
|
|
|
213
248
|
return (
|
|
214
249
|
<Comp
|
|
250
|
+
data-density={density}
|
|
251
|
+
data-size={resolvedSize}
|
|
215
252
|
data-slot="toolbar-button"
|
|
216
253
|
ref={ref}
|
|
217
|
-
className={cn(
|
|
254
|
+
className={cn(
|
|
255
|
+
toolbarButtonVariants({ variant, size: resolvedSize, className })
|
|
256
|
+
)}
|
|
218
257
|
{...(!asChild ? { type } : {})}
|
|
219
258
|
{...props}
|
|
220
259
|
>
|
|
@@ -271,7 +310,7 @@ const ToolbarMoreButton = React.forwardRef<
|
|
|
271
310
|
HTMLButtonElement,
|
|
272
311
|
ToolbarMoreButtonProps
|
|
273
312
|
>(function ToolbarMoreButton(
|
|
274
|
-
{ label = "More actions", size = "icon", ...props },
|
|
313
|
+
{ label = "More actions", size = "icon-sm", ...props },
|
|
275
314
|
ref
|
|
276
315
|
) {
|
|
277
316
|
return (
|
|
@@ -289,6 +328,8 @@ type ToolbarSearchProps = Omit<
|
|
|
289
328
|
className?: string
|
|
290
329
|
inputClassName?: string
|
|
291
330
|
icon?: React.ReactNode
|
|
331
|
+
shortcutKeys?: readonly string[]
|
|
332
|
+
shortcutPlatform?: ShortcutPlatform
|
|
292
333
|
}
|
|
293
334
|
|
|
294
335
|
const ToolbarSearch = React.forwardRef<HTMLInputElement, ToolbarSearchProps>(
|
|
@@ -299,7 +340,10 @@ const ToolbarSearch = React.forwardRef<HTMLInputElement, ToolbarSearchProps>(
|
|
|
299
340
|
icon,
|
|
300
341
|
inputClassName,
|
|
301
342
|
placeholder = "Search...",
|
|
343
|
+
shortcutKeys,
|
|
344
|
+
shortcutPlatform,
|
|
302
345
|
type = "search",
|
|
346
|
+
density,
|
|
303
347
|
width,
|
|
304
348
|
...props
|
|
305
349
|
},
|
|
@@ -308,8 +352,9 @@ const ToolbarSearch = React.forwardRef<HTMLInputElement, ToolbarSearchProps>(
|
|
|
308
352
|
return (
|
|
309
353
|
<div
|
|
310
354
|
data-disabled={disabled ? "true" : undefined}
|
|
355
|
+
data-density={density ?? "default"}
|
|
311
356
|
data-slot="toolbar-search"
|
|
312
|
-
className={cn(toolbarSearchVariants({ width, className }))}
|
|
357
|
+
className={cn(toolbarSearchVariants({ density, width, className }))}
|
|
313
358
|
>
|
|
314
359
|
<span
|
|
315
360
|
aria-hidden="true"
|
|
@@ -329,6 +374,13 @@ const ToolbarSearch = React.forwardRef<HTMLInputElement, ToolbarSearchProps>(
|
|
|
329
374
|
type={type}
|
|
330
375
|
{...props}
|
|
331
376
|
/>
|
|
377
|
+
{shortcutKeys?.length ? (
|
|
378
|
+
<KbdShortcut
|
|
379
|
+
disabled={disabled}
|
|
380
|
+
keys={shortcutKeys}
|
|
381
|
+
platform={shortcutPlatform}
|
|
382
|
+
/>
|
|
383
|
+
) : null}
|
|
332
384
|
</div>
|
|
333
385
|
)
|
|
334
386
|
}
|
|
@@ -349,6 +401,7 @@ const ToolbarSelect = React.forwardRef<HTMLButtonElement, ToolbarSelectProps>(
|
|
|
349
401
|
placeholder = "Select",
|
|
350
402
|
type = "button",
|
|
351
403
|
value,
|
|
404
|
+
density,
|
|
352
405
|
width,
|
|
353
406
|
...props
|
|
354
407
|
},
|
|
@@ -357,10 +410,11 @@ const ToolbarSelect = React.forwardRef<HTMLButtonElement, ToolbarSelectProps>(
|
|
|
357
410
|
return (
|
|
358
411
|
<button
|
|
359
412
|
aria-haspopup="listbox"
|
|
413
|
+
data-density={density ?? "default"}
|
|
360
414
|
data-slot="toolbar-select"
|
|
361
415
|
ref={ref}
|
|
362
416
|
type={type}
|
|
363
|
-
className={cn(toolbarSelectVariants({ width, className }))}
|
|
417
|
+
className={cn(toolbarSelectVariants({ density, width, className }))}
|
|
364
418
|
{...props}
|
|
365
419
|
>
|
|
366
420
|
<span
|
|
@@ -415,16 +469,22 @@ const ToolbarBadge = React.forwardRef<HTMLSpanElement, ToolbarBadgeProps>(
|
|
|
415
469
|
}
|
|
416
470
|
)
|
|
417
471
|
|
|
418
|
-
type ToolbarTextProps = React.ComponentProps<"span">
|
|
472
|
+
type ToolbarTextProps = React.ComponentProps<"span"> & {
|
|
473
|
+
density?: ControlDensity
|
|
474
|
+
}
|
|
419
475
|
|
|
420
476
|
const ToolbarText = React.forwardRef<HTMLSpanElement, ToolbarTextProps>(
|
|
421
|
-
function ToolbarText({ className, ...props }, ref) {
|
|
477
|
+
function ToolbarText({ className, density = "default", ...props }, ref) {
|
|
422
478
|
return (
|
|
423
479
|
<span
|
|
424
480
|
data-slot="toolbar-text"
|
|
481
|
+
data-density={density}
|
|
425
482
|
ref={ref}
|
|
426
483
|
className={cn(
|
|
427
|
-
"inline-flex
|
|
484
|
+
"inline-flex min-w-0 items-center text-[length:var(--bh-text-body-md-regular-font-size)] font-[var(--bh-text-body-md-regular-font-weight)] leading-[var(--bh-text-body-md-regular-line-height)] tracking-[var(--bh-text-body-md-regular-letter-spacing)] text-[var(--bh-content-subtle)]",
|
|
485
|
+
density === "compact" && "h-[var(--bh-input-md-height)]",
|
|
486
|
+
density === "default" && "h-[var(--bh-input-lg-height)]",
|
|
487
|
+
density === "comfortable" && "h-[var(--bh-input-comfortable-height)]",
|
|
428
488
|
className
|
|
429
489
|
)}
|
|
430
490
|
{...props}
|
|
@@ -433,6 +493,17 @@ const ToolbarText = React.forwardRef<HTMLSpanElement, ToolbarTextProps>(
|
|
|
433
493
|
}
|
|
434
494
|
)
|
|
435
495
|
|
|
496
|
+
function resolveToolbarButtonSize(
|
|
497
|
+
density: ControlDensity | undefined,
|
|
498
|
+
size: ToolbarButtonSize | null | undefined
|
|
499
|
+
): ToolbarButtonSize | null | undefined {
|
|
500
|
+
if (!density) return size
|
|
501
|
+
const iconOnly = size?.startsWith("icon") ?? false
|
|
502
|
+
if (density === "compact") return iconOnly ? "icon-xs" : "xs"
|
|
503
|
+
if (density === "default") return iconOnly ? "icon-sm" : "sm"
|
|
504
|
+
return iconOnly ? "icon" : "default"
|
|
505
|
+
}
|
|
506
|
+
|
|
436
507
|
export {
|
|
437
508
|
Toolbar,
|
|
438
509
|
ToolbarBadge,
|
|
@@ -453,6 +524,7 @@ export {
|
|
|
453
524
|
toolbarVariants,
|
|
454
525
|
}
|
|
455
526
|
export type {
|
|
527
|
+
ControlDensity,
|
|
456
528
|
ToolbarBadgeProps,
|
|
457
529
|
ToolbarButtonProps,
|
|
458
530
|
ToolbarFilterButtonProps,
|
|
@@ -2,13 +2,33 @@ import { Alert } from "@/components/ui/alert"
|
|
|
2
2
|
|
|
3
3
|
export function AlertDemo() {
|
|
4
4
|
return (
|
|
5
|
-
<div className="grid gap-
|
|
6
|
-
<Alert status="danger" />
|
|
7
|
-
<Alert status="success" />
|
|
8
|
-
<Alert
|
|
5
|
+
<div className="grid gap-[var(--bh-space-3xl-16)]">
|
|
6
|
+
<Alert status="danger" title="Payment failed" />
|
|
7
|
+
<Alert status="success" title="Changes saved" />
|
|
8
|
+
<Alert
|
|
9
|
+
actions={[
|
|
10
|
+
{ label: "Review details", onClick: noop },
|
|
11
|
+
{ label: "Dismiss", onClick: noop },
|
|
12
|
+
]}
|
|
13
|
+
description="Update the payment method before the next billing attempt."
|
|
14
|
+
isExpandable
|
|
15
|
+
status="warning"
|
|
16
|
+
title="Payment method expires soon"
|
|
17
|
+
/>
|
|
9
18
|
<div dir="rtl">
|
|
10
|
-
<Alert
|
|
19
|
+
<Alert
|
|
20
|
+
actions={[
|
|
21
|
+
{ label: "عرض التفاصيل", onClick: noop },
|
|
22
|
+
{ label: "متابعة", onClick: noop },
|
|
23
|
+
]}
|
|
24
|
+
description="يمكنك مراجعة التفاصيل أو المتابعة من لوحة التحكم."
|
|
25
|
+
isExpandable
|
|
26
|
+
status="info"
|
|
27
|
+
title="تم تحديث حسابك"
|
|
28
|
+
/>
|
|
11
29
|
</div>
|
|
12
30
|
</div>
|
|
13
31
|
)
|
|
14
32
|
}
|
|
33
|
+
|
|
34
|
+
function noop() {}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Button } from "@/components/ui/button"
|
|
2
|
+
import {
|
|
3
|
+
AlertDialog,
|
|
4
|
+
AlertDialogAction,
|
|
5
|
+
AlertDialogBody,
|
|
6
|
+
AlertDialogCancel,
|
|
7
|
+
AlertDialogContent,
|
|
8
|
+
AlertDialogDescription,
|
|
9
|
+
AlertDialogFooter,
|
|
10
|
+
AlertDialogHeader,
|
|
11
|
+
AlertDialogIcon,
|
|
12
|
+
AlertDialogTitle,
|
|
13
|
+
AlertDialogTrigger,
|
|
14
|
+
} from "@/components/ui/alert-dialog"
|
|
15
|
+
|
|
16
|
+
export function AlertDialogDemo() {
|
|
17
|
+
return (
|
|
18
|
+
<AlertDialog>
|
|
19
|
+
<AlertDialogTrigger asChild>
|
|
20
|
+
<Button size="sm" variant="danger">
|
|
21
|
+
Delete project
|
|
22
|
+
</Button>
|
|
23
|
+
</AlertDialogTrigger>
|
|
24
|
+
<AlertDialogContent>
|
|
25
|
+
<AlertDialogHeader>
|
|
26
|
+
<AlertDialogIcon intent="danger" />
|
|
27
|
+
<AlertDialogTitle>Delete project?</AlertDialogTitle>
|
|
28
|
+
</AlertDialogHeader>
|
|
29
|
+
<AlertDialogBody>
|
|
30
|
+
<AlertDialogDescription>
|
|
31
|
+
This action cannot be undone. All environments, deployments, and
|
|
32
|
+
saved settings will be permanently removed.
|
|
33
|
+
</AlertDialogDescription>
|
|
34
|
+
</AlertDialogBody>
|
|
35
|
+
<AlertDialogFooter>
|
|
36
|
+
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
37
|
+
<AlertDialogAction>Delete project</AlertDialogAction>
|
|
38
|
+
</AlertDialogFooter>
|
|
39
|
+
</AlertDialogContent>
|
|
40
|
+
</AlertDialog>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AspectRatio } from "@/components/ui/aspect-ratio"
|
|
2
|
+
|
|
3
|
+
export function AspectRatioDemo() {
|
|
4
|
+
return (
|
|
5
|
+
<AspectRatio ratio={16 / 9} className="max-w-xl">
|
|
6
|
+
<div className="flex size-full items-center justify-center bg-[var(--bh-bg-neutral-subtle)] text-[var(--bh-content-subtle)]">
|
|
7
|
+
16:9
|
|
8
|
+
</div>
|
|
9
|
+
</AspectRatio>
|
|
10
|
+
)
|
|
11
|
+
}
|
|
@@ -11,7 +11,7 @@ import { Button } from "@/components/ui/button"
|
|
|
11
11
|
|
|
12
12
|
export function AttributeDemo() {
|
|
13
13
|
return (
|
|
14
|
-
<div className="grid max-w-5xl gap-
|
|
14
|
+
<div className="grid max-w-5xl gap-[var(--bh-space-3xl-16)] lg:grid-cols-2">
|
|
15
15
|
<AttributeCard>
|
|
16
16
|
<AttributeHeader
|
|
17
17
|
title="Company profile"
|
|
@@ -61,8 +61,8 @@ const rtlOptions = [
|
|
|
61
61
|
|
|
62
62
|
export function AutocompleteDemo() {
|
|
63
63
|
return (
|
|
64
|
-
<div className="grid w-full gap-
|
|
65
|
-
<div className="grid min-w-0 content-start gap-
|
|
64
|
+
<div className="grid w-full gap-[var(--bh-space-4xl-20)] lg:grid-cols-2">
|
|
65
|
+
<div className="grid min-w-0 content-start gap-[var(--bh-space-4xl-20)]">
|
|
66
66
|
<Autocomplete
|
|
67
67
|
className="mb-[var(--bh-space-13xl-160)]"
|
|
68
68
|
defaultOpen
|
|
@@ -83,7 +83,7 @@ export function AutocompleteDemo() {
|
|
|
83
83
|
/>
|
|
84
84
|
</div>
|
|
85
85
|
|
|
86
|
-
<div className="grid min-w-0 content-start gap-
|
|
86
|
+
<div className="grid min-w-0 content-start gap-[var(--bh-space-4xl-20)]">
|
|
87
87
|
<Autocomplete
|
|
88
88
|
label="Project"
|
|
89
89
|
options={projectOptions}
|
|
@@ -30,8 +30,8 @@ const secondaryStatusColumns = [
|
|
|
30
30
|
|
|
31
31
|
export function AvatarDemo() {
|
|
32
32
|
return (
|
|
33
|
-
<div className="flex flex-col gap-
|
|
34
|
-
<div className="grid w-fit grid-cols-5 gap-x-
|
|
33
|
+
<div className="flex flex-col gap-[calc(var(--bh-space-5xl-24)_+_var(--bh-space-xs-4))]">
|
|
34
|
+
<div className="grid w-fit grid-cols-5 gap-x-[var(--bh-space-3xl-16)] gap-y-[var(--bh-space-3xl-16)]">
|
|
35
35
|
{statusColumns.map((status, index) => (
|
|
36
36
|
<Avatar key={`icon-${status}-${index}`} size="2xl">
|
|
37
37
|
<AvatarIcon />
|
|
@@ -56,7 +56,7 @@ export function AvatarDemo() {
|
|
|
56
56
|
))}
|
|
57
57
|
</div>
|
|
58
58
|
|
|
59
|
-
<div className="flex flex-wrap items-center gap-
|
|
59
|
+
<div className="flex flex-wrap items-center gap-[var(--bh-space-4xl-20)] ps-[calc(var(--bh-space-5xl-24)_+_var(--bh-space-xs-4))]">
|
|
60
60
|
<Avatar size="2xl">
|
|
61
61
|
<AvatarImage src={avatarUrl} alt="Profile portrait" />
|
|
62
62
|
<AvatarFallback>AG</AvatarFallback>
|
|
@@ -74,7 +74,7 @@ export function AvatarDemo() {
|
|
|
74
74
|
</Avatar>
|
|
75
75
|
</div>
|
|
76
76
|
|
|
77
|
-
<div className="flex items-center gap-
|
|
77
|
+
<div className="flex items-center gap-[var(--bh-space-xl-12)]">
|
|
78
78
|
<AvatarGroup>
|
|
79
79
|
{Array.from({ length: 7 }).map((_, index) => (
|
|
80
80
|
<Avatar key={index} size="md">
|
|
@@ -89,11 +89,11 @@ export function AvatarDemo() {
|
|
|
89
89
|
className="border border-dashed border-[var(--bh-border-subtle)] bg-[var(--bh-bg-default)] text-[var(--bh-content-subtle)]"
|
|
90
90
|
size="md"
|
|
91
91
|
>
|
|
92
|
-
<PlusIcon aria-hidden="true" className="size-
|
|
92
|
+
<PlusIcon aria-hidden="true" className="size-[var(--bh-space-3xl-16)]" />
|
|
93
93
|
</Avatar>
|
|
94
94
|
</div>
|
|
95
95
|
|
|
96
|
-
<div className="flex items-center gap-
|
|
96
|
+
<div className="flex items-center gap-[var(--bh-space-xl-12)]">
|
|
97
97
|
<Avatar size="xl">
|
|
98
98
|
<AvatarImage src={avatarUrl} alt="John Doe" />
|
|
99
99
|
<AvatarFallback>JD</AvatarFallback>
|
|
@@ -109,7 +109,7 @@ export function AvatarDemo() {
|
|
|
109
109
|
</div>
|
|
110
110
|
</div>
|
|
111
111
|
|
|
112
|
-
<div className="flex items-center gap-
|
|
112
|
+
<div className="flex items-center gap-[var(--bh-space-xl-12)]">
|
|
113
113
|
<Avatar size="md">
|
|
114
114
|
<AvatarImage src={avatarUrl} alt="John Doe" />
|
|
115
115
|
<AvatarFallback>JD</AvatarFallback>
|
|
@@ -10,7 +10,7 @@ import { Spinner } from "@/components/ui/spinner"
|
|
|
10
10
|
|
|
11
11
|
export function BadgeDemo() {
|
|
12
12
|
return (
|
|
13
|
-
<div className="flex flex-wrap items-center gap-
|
|
13
|
+
<div className="flex flex-wrap items-center gap-[var(--bh-space-md-8)]">
|
|
14
14
|
<Badge>Badge</Badge>
|
|
15
15
|
<Badge badgeStyle="outline">Outline</Badge>
|
|
16
16
|
<Badge badgeStyle="solid" color="blue">
|