@giddaa-housing/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/accordion.d.ts +11 -0
- package/dist/accordion.js +124 -0
- package/dist/accordion.js.map +1 -0
- package/dist/alert.d.ts +18 -0
- package/dist/alert.js +152 -0
- package/dist/alert.js.map +1 -0
- package/dist/avatar.d.ts +14 -0
- package/dist/avatar.js +152 -0
- package/dist/avatar.js.map +1 -0
- package/dist/badge.d.ts +14 -0
- package/dist/badge.js +119 -0
- package/dist/badge.js.map +1 -0
- package/dist/bar-chart.d.ts +136 -0
- package/dist/bar-chart.js +302 -0
- package/dist/bar-chart.js.map +1 -0
- package/dist/base.css +32 -0
- package/dist/breadcrumb.d.ts +12 -0
- package/dist/breadcrumb.js +161 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/bullet-chart.d.ts +98 -0
- package/dist/bullet-chart.js +189 -0
- package/dist/bullet-chart.js.map +1 -0
- package/dist/button-group.d.ts +18 -0
- package/dist/button-group.js +170 -0
- package/dist/button-group.js.map +1 -0
- package/dist/button.d.ts +19 -0
- package/dist/button.js +146 -0
- package/dist/button.js.map +1 -0
- package/dist/calendar.d.ts +9 -0
- package/dist/calendar.js +293 -0
- package/dist/calendar.js.map +1 -0
- package/dist/card.d.ts +18 -0
- package/dist/card.js +186 -0
- package/dist/card.js.map +1 -0
- package/dist/carousel.d.ts +53 -0
- package/dist/carousel.js +396 -0
- package/dist/carousel.js.map +1 -0
- package/dist/chart.d.ts +122 -0
- package/dist/chart.js +494 -0
- package/dist/chart.js.map +1 -0
- package/dist/checkbox.d.ts +73 -0
- package/dist/checkbox.js +87 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/collapsible.d.ts +8 -0
- package/dist/collapsible.js +82 -0
- package/dist/collapsible.js.map +1 -0
- package/dist/combobox.d.ts +30 -0
- package/dist/combobox.js +713 -0
- package/dist/combobox.js.map +1 -0
- package/dist/date-picker.d.ts +22 -0
- package/dist/date-picker.js +528 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/dialog.d.ts +30 -0
- package/dist/dialog.js +339 -0
- package/dist/dialog.js.map +1 -0
- package/dist/dropdown-menu.d.ts +35 -0
- package/dist/dropdown-menu.js +376 -0
- package/dist/dropdown-menu.js.map +1 -0
- package/dist/dropzone.d.ts +128 -0
- package/dist/dropzone.js +490 -0
- package/dist/dropzone.js.map +1 -0
- package/dist/empty-state.d.ts +17 -0
- package/dist/empty-state.js +146 -0
- package/dist/empty-state.js.map +1 -0
- package/dist/field.d.ts +29 -0
- package/dist/field.js +345 -0
- package/dist/field.js.map +1 -0
- package/dist/files/red-hat-display-latin-300-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-300-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-300-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-300-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-400-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-400-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-400-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-400-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-500-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-500-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-500-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-500-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-600-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-600-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-600-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-600-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-700-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-700-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-700-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-700-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-800-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-800-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-800-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-800-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-900-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-900-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-900-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-900-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-300-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-300-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-300-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-300-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-400-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-400-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-400-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-400-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-500-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-500-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-500-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-500-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-600-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-600-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-600-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-600-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-700-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-700-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-700-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-700-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-800-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-800-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-800-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-800-normal.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-900-italic.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-900-italic.woff2 +0 -0
- package/dist/files/red-hat-display-latin-ext-900-normal.woff +0 -0
- package/dist/files/red-hat-display-latin-ext-900-normal.woff2 +0 -0
- package/dist/funnel-chart.d.ts +84 -0
- package/dist/funnel-chart.js +569 -0
- package/dist/funnel-chart.js.map +1 -0
- package/dist/index.d.ts +87 -0
- package/dist/index.js +10448 -0
- package/dist/index.js.map +1 -0
- package/dist/input-group.d.ts +31 -0
- package/dist/input-group.js +380 -0
- package/dist/input-group.js.map +1 -0
- package/dist/input-size-context.d.ts +11 -0
- package/dist/input-size-context.js +24 -0
- package/dist/input-size-context.js.map +1 -0
- package/dist/input.d.ts +13 -0
- package/dist/input.js +83 -0
- package/dist/input.js.map +1 -0
- package/dist/item.d.ts +8 -0
- package/dist/item.js +93 -0
- package/dist/item.js.map +1 -0
- package/dist/kpi-card.d.ts +24 -0
- package/dist/kpi-card.js +243 -0
- package/dist/kpi-card.js.map +1 -0
- package/dist/label.d.ts +8 -0
- package/dist/label.js +68 -0
- package/dist/label.js.map +1 -0
- package/dist/line-chart.d.ts +155 -0
- package/dist/line-chart.js +269 -0
- package/dist/line-chart.js.map +1 -0
- package/dist/logo.d.ts +6 -0
- package/dist/logo.js +146 -0
- package/dist/logo.js.map +1 -0
- package/dist/number-input.d.ts +41 -0
- package/dist/number-input.js +418 -0
- package/dist/number-input.js.map +1 -0
- package/dist/page-header.d.ts +13 -0
- package/dist/page-header.js +113 -0
- package/dist/page-header.js.map +1 -0
- package/dist/pagination.d.ts +35 -0
- package/dist/pagination.js +352 -0
- package/dist/pagination.js.map +1 -0
- package/dist/password-input.d.ts +13 -0
- package/dist/password-input.js +356 -0
- package/dist/password-input.js.map +1 -0
- package/dist/phone-input.d.ts +21 -0
- package/dist/phone-input.js +573 -0
- package/dist/phone-input.js.map +1 -0
- package/dist/photo-gallery.d.ts +42 -0
- package/dist/photo-gallery.js +756 -0
- package/dist/photo-gallery.js.map +1 -0
- package/dist/pie-chart.d.ts +125 -0
- package/dist/pie-chart.js +192 -0
- package/dist/pie-chart.js.map +1 -0
- package/dist/popover.d.ts +20 -0
- package/dist/popover.js +169 -0
- package/dist/popover.js.map +1 -0
- package/dist/progress.d.ts +28 -0
- package/dist/progress.js +315 -0
- package/dist/progress.js.map +1 -0
- package/dist/radio-group.d.ts +32 -0
- package/dist/radio-group.js +100 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/red-hat-display.css +2 -0
- package/dist/rich-text-editor.d.ts +16 -0
- package/dist/rich-text-editor.js +1000 -0
- package/dist/rich-text-editor.js.map +1 -0
- package/dist/search-input.d.ts +19 -0
- package/dist/search-input.js +411 -0
- package/dist/search-input.js.map +1 -0
- package/dist/select.d.ts +21 -0
- package/dist/select.js +305 -0
- package/dist/select.js.map +1 -0
- package/dist/separator.d.ts +10 -0
- package/dist/separator.js +72 -0
- package/dist/separator.js.map +1 -0
- package/dist/sheet.d.ts +24 -0
- package/dist/sheet.js +282 -0
- package/dist/sheet.js.map +1 -0
- package/dist/sidebar.d.ts +70 -0
- package/dist/sidebar.js +1078 -0
- package/dist/sidebar.js.map +1 -0
- package/dist/size-context.d.ts +11 -0
- package/dist/size-context.js +22 -0
- package/dist/size-context.js.map +1 -0
- package/dist/skeleton.d.ts +5 -0
- package/dist/skeleton.js +48 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/sparkline.d.ts +94 -0
- package/dist/sparkline.js +568 -0
- package/dist/sparkline.js.map +1 -0
- package/dist/stepper.d.ts +43 -0
- package/dist/stepper.js +296 -0
- package/dist/stepper.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/switch.d.ts +29 -0
- package/dist/switch.js +108 -0
- package/dist/switch.js.map +1 -0
- package/dist/tab-list.d.ts +38 -0
- package/dist/tab-list.js +394 -0
- package/dist/tab-list.js.map +1 -0
- package/dist/table.d.ts +69 -0
- package/dist/table.js +197 -0
- package/dist/table.js.map +1 -0
- package/dist/tabs.d.ts +18 -0
- package/dist/tabs.js +159 -0
- package/dist/tabs.js.map +1 -0
- package/dist/tag.d.ts +25 -0
- package/dist/tag.js +160 -0
- package/dist/tag.js.map +1 -0
- package/dist/textarea.d.ts +12 -0
- package/dist/textarea.js +78 -0
- package/dist/textarea.js.map +1 -0
- package/dist/theme/giddaa.css +2 -0
- package/dist/time-picker.d.ts +13 -0
- package/dist/time-picker.js +472 -0
- package/dist/time-picker.js.map +1 -0
- package/dist/toast.d.ts +23 -0
- package/dist/toast.js +330 -0
- package/dist/toast.js.map +1 -0
- package/dist/tooltip.d.ts +11 -0
- package/dist/tooltip.js +96 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/tree-map.d.ts +127 -0
- package/dist/tree-map.js +652 -0
- package/dist/tree-map.js.map +1 -0
- package/package.json +328 -0
package/dist/base.css
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
body {
|
|
2
|
+
background-color: var(--color-canvas);
|
|
3
|
+
color: var(--color-fg-primary);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
button:not(:disabled),
|
|
7
|
+
[role="button"]:not(:disabled) {
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
html {
|
|
12
|
+
font-family: var(--font-sans);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
* {
|
|
16
|
+
border-color: var(--color-line);
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
outline-color: rgb(from var(--color-line-focus) r g b / 0.5);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
::-webkit-scrollbar {
|
|
22
|
+
display: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.no-scrollbar::-webkit-scrollbar {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.no-scrollbar {
|
|
30
|
+
-ms-overflow-style: none;
|
|
31
|
+
scrollbar-width: none;
|
|
32
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
declare function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">): React.JSX.Element;
|
|
5
|
+
declare function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">): React.JSX.Element;
|
|
6
|
+
declare function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
|
|
7
|
+
declare function BreadcrumbLink({ className, render, ...props }: useRender.ComponentProps<"a">): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
8
|
+
declare function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
|
|
9
|
+
declare function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<"li">): React.JSX.Element;
|
|
10
|
+
declare function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
|
|
11
|
+
|
|
12
|
+
export { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// src/components/ui/breadcrumb.tsx
|
|
2
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
|
+
import { ChevronRightIcon, MoreHorizontalIcon } from "lucide-react";
|
|
5
|
+
|
|
6
|
+
// src/lib/cn.ts
|
|
7
|
+
import { clsx } from "clsx";
|
|
8
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
9
|
+
var twMerge = extendTailwindMerge({
|
|
10
|
+
extend: {
|
|
11
|
+
classGroups: {
|
|
12
|
+
"font-size": [
|
|
13
|
+
{
|
|
14
|
+
text: [
|
|
15
|
+
"gdt-display",
|
|
16
|
+
"gdt-h1",
|
|
17
|
+
"gdt-h2",
|
|
18
|
+
"gdt-h3",
|
|
19
|
+
"gdt-h4",
|
|
20
|
+
"gdt-h5",
|
|
21
|
+
"gdt-xl",
|
|
22
|
+
"gdt-lg",
|
|
23
|
+
"gdt-md",
|
|
24
|
+
"gdt-sm",
|
|
25
|
+
"gdt-xs",
|
|
26
|
+
"gdt-subtext",
|
|
27
|
+
"gdt-capitalized"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
function cn(...inputs) {
|
|
35
|
+
return twMerge(clsx(inputs));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/components/ui/breadcrumb.tsx
|
|
39
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
40
|
+
function Breadcrumb({ className, ...props }) {
|
|
41
|
+
return /* @__PURE__ */ jsx(
|
|
42
|
+
"nav",
|
|
43
|
+
{
|
|
44
|
+
"aria-label": "breadcrumb",
|
|
45
|
+
"data-slot": "breadcrumb",
|
|
46
|
+
className: cn("min-w-0", className),
|
|
47
|
+
...props
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
function BreadcrumbList({ className, ...props }) {
|
|
52
|
+
return /* @__PURE__ */ jsx(
|
|
53
|
+
"ol",
|
|
54
|
+
{
|
|
55
|
+
"data-slot": "breadcrumb-list",
|
|
56
|
+
className: cn(
|
|
57
|
+
"flex flex-wrap items-center gap-2 wrap-break-word text-gdt-sm text-fg-secondary",
|
|
58
|
+
className
|
|
59
|
+
),
|
|
60
|
+
...props
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
function BreadcrumbItem({ className, ...props }) {
|
|
65
|
+
return /* @__PURE__ */ jsx(
|
|
66
|
+
"li",
|
|
67
|
+
{
|
|
68
|
+
"data-slot": "breadcrumb-item",
|
|
69
|
+
className: cn("inline-flex min-w-0 items-center gap-2", className),
|
|
70
|
+
...props
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
function BreadcrumbLink({
|
|
75
|
+
className,
|
|
76
|
+
render,
|
|
77
|
+
...props
|
|
78
|
+
}) {
|
|
79
|
+
return useRender({
|
|
80
|
+
defaultTagName: "a",
|
|
81
|
+
props: mergeProps(
|
|
82
|
+
{
|
|
83
|
+
className: cn(
|
|
84
|
+
"inline-flex min-w-0 items-center rounded-sm text-gdt-sm font-normal text-fg-secondary transition-colors hover:text-fg-primary focus-visible:outline-none focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)]",
|
|
85
|
+
className
|
|
86
|
+
)
|
|
87
|
+
},
|
|
88
|
+
props
|
|
89
|
+
),
|
|
90
|
+
render,
|
|
91
|
+
state: {
|
|
92
|
+
slot: "breadcrumb-link"
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function BreadcrumbPage({ className, ...props }) {
|
|
97
|
+
return /* @__PURE__ */ jsx(
|
|
98
|
+
"span",
|
|
99
|
+
{
|
|
100
|
+
"data-slot": "breadcrumb-page",
|
|
101
|
+
"aria-current": "page",
|
|
102
|
+
className: cn(
|
|
103
|
+
"inline-flex min-w-0 items-center text-gdt-sm font-semibold text-fg-brand",
|
|
104
|
+
className
|
|
105
|
+
),
|
|
106
|
+
...props
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
function BreadcrumbSeparator({
|
|
111
|
+
children,
|
|
112
|
+
className,
|
|
113
|
+
...props
|
|
114
|
+
}) {
|
|
115
|
+
return /* @__PURE__ */ jsx(
|
|
116
|
+
"li",
|
|
117
|
+
{
|
|
118
|
+
"data-slot": "breadcrumb-separator",
|
|
119
|
+
role: "presentation",
|
|
120
|
+
"aria-hidden": "true",
|
|
121
|
+
className: cn(
|
|
122
|
+
"inline-flex shrink-0 items-center text-fg-caption-placeholder [&>svg]:size-4 [&>svg]:shrink-0",
|
|
123
|
+
className
|
|
124
|
+
),
|
|
125
|
+
...props,
|
|
126
|
+
children: children ?? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "cn-rtl-flip" })
|
|
127
|
+
}
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
function BreadcrumbEllipsis({
|
|
131
|
+
className,
|
|
132
|
+
...props
|
|
133
|
+
}) {
|
|
134
|
+
return /* @__PURE__ */ jsxs(
|
|
135
|
+
"span",
|
|
136
|
+
{
|
|
137
|
+
"data-slot": "breadcrumb-ellipsis",
|
|
138
|
+
role: "presentation",
|
|
139
|
+
"aria-hidden": "true",
|
|
140
|
+
className: cn(
|
|
141
|
+
"inline-flex items-center justify-center text-fg-caption-placeholder [&>svg]:size-4 [&>svg]:shrink-0",
|
|
142
|
+
className
|
|
143
|
+
),
|
|
144
|
+
...props,
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ jsx(MoreHorizontalIcon, {}),
|
|
147
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "More" })
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
export {
|
|
153
|
+
Breadcrumb,
|
|
154
|
+
BreadcrumbEllipsis,
|
|
155
|
+
BreadcrumbItem,
|
|
156
|
+
BreadcrumbLink,
|
|
157
|
+
BreadcrumbList,
|
|
158
|
+
BreadcrumbPage,
|
|
159
|
+
BreadcrumbSeparator
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=breadcrumb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/breadcrumb.tsx","../src/lib/cn.ts"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { ChevronRightIcon, MoreHorizontalIcon } from \"lucide-react\";\nimport type * as React from \"react\";\n\nimport { cn } from \"../../lib/cn\";\n\nfunction Breadcrumb({ className, ...props }: React.ComponentProps<\"nav\">) {\n\treturn (\n\t\t<nav\n\t\t\taria-label=\"breadcrumb\"\n\t\t\tdata-slot=\"breadcrumb\"\n\t\t\tclassName={cn(\"min-w-0\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<\"ol\">) {\n\treturn (\n\t\t<ol\n\t\t\tdata-slot=\"breadcrumb-list\"\n\t\t\tclassName={cn(\n\t\t\t\t\"flex flex-wrap items-center gap-2 wrap-break-word text-gdt-sm text-fg-secondary\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<\"li\">) {\n\treturn (\n\t\t<li\n\t\t\tdata-slot=\"breadcrumb-item\"\n\t\t\tclassName={cn(\"inline-flex min-w-0 items-center gap-2\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction BreadcrumbLink({\n\tclassName,\n\trender,\n\t...props\n}: useRender.ComponentProps<\"a\">) {\n\treturn useRender({\n\t\tdefaultTagName: \"a\",\n\t\tprops: mergeProps<\"a\">(\n\t\t\t{\n\t\t\t\tclassName: cn(\n\t\t\t\t\t\"inline-flex min-w-0 items-center rounded-sm text-gdt-sm font-normal text-fg-secondary transition-colors hover:text-fg-primary focus-visible:outline-none focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)]\",\n\t\t\t\t\tclassName,\n\t\t\t\t),\n\t\t\t},\n\t\t\tprops,\n\t\t),\n\t\trender,\n\t\tstate: {\n\t\t\tslot: \"breadcrumb-link\",\n\t\t},\n\t});\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<\"span\">) {\n\treturn (\n\t\t<span\n\t\t\tdata-slot=\"breadcrumb-page\"\n\t\t\taria-current=\"page\"\n\t\t\tclassName={cn(\n\t\t\t\t\"inline-flex min-w-0 items-center text-gdt-sm font-semibold text-fg-brand\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction BreadcrumbSeparator({\n\tchildren,\n\tclassName,\n\t...props\n}: React.ComponentProps<\"li\">) {\n\treturn (\n\t\t<li\n\t\t\tdata-slot=\"breadcrumb-separator\"\n\t\t\trole=\"presentation\"\n\t\t\taria-hidden=\"true\"\n\t\t\tclassName={cn(\n\t\t\t\t\"inline-flex shrink-0 items-center text-fg-caption-placeholder [&>svg]:size-4 [&>svg]:shrink-0\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children ?? <ChevronRightIcon className=\"cn-rtl-flip\" />}\n\t\t</li>\n\t);\n}\n\nfunction BreadcrumbEllipsis({\n\tclassName,\n\t...props\n}: React.ComponentProps<\"span\">) {\n\treturn (\n\t\t<span\n\t\t\tdata-slot=\"breadcrumb-ellipsis\"\n\t\t\trole=\"presentation\"\n\t\t\taria-hidden=\"true\"\n\t\t\tclassName={cn(\n\t\t\t\t\"inline-flex items-center justify-center text-fg-caption-placeholder [&>svg]:size-4 [&>svg]:shrink-0\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<MoreHorizontalIcon />\n\t\t\t<span className=\"sr-only\">More</span>\n\t\t</span>\n\t);\n}\n\nexport {\n\tBreadcrumb,\n\tBreadcrumbList,\n\tBreadcrumbItem,\n\tBreadcrumbLink,\n\tBreadcrumbPage,\n\tBreadcrumbSeparator,\n\tBreadcrumbEllipsis,\n};\n","import { type ClassValue, clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n\textend: {\n\t\tclassGroups: {\n\t\t\t\"font-size\": [\n\t\t\t\t{\n\t\t\t\t\ttext: [\n\t\t\t\t\t\t\"gdt-display\",\n\t\t\t\t\t\t\"gdt-h1\",\n\t\t\t\t\t\t\"gdt-h2\",\n\t\t\t\t\t\t\"gdt-h3\",\n\t\t\t\t\t\t\"gdt-h4\",\n\t\t\t\t\t\t\"gdt-h5\",\n\t\t\t\t\t\t\"gdt-xl\",\n\t\t\t\t\t\t\"gdt-lg\",\n\t\t\t\t\t\t\"gdt-md\",\n\t\t\t\t\t\t\"gdt-sm\",\n\t\t\t\t\t\t\"gdt-xs\",\n\t\t\t\t\t\t\"gdt-subtext\",\n\t\t\t\t\t\t\"gdt-capitalized\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n});\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB,0BAA0B;;;ACFrD,SAA0B,YAAY;AACtC,SAAS,2BAA2B;AAEpC,IAAM,UAAU,oBAAoB;AAAA,EACnC,QAAQ;AAAA,IACP,aAAa;AAAA,MACZ,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD,CAAC;AAEM,SAAS,MAAM,QAAsB;AAC3C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC5B;;;ADtBE,cA+FA,YA/FA;AAFF,SAAS,WAAW,EAAE,WAAW,GAAG,MAAM,GAAgC;AACzE,SACC;AAAA,IAAC;AAAA;AAAA,MACA,cAAW;AAAA,MACX,aAAU;AAAA,MACV,WAAW,GAAG,WAAW,SAAS;AAAA,MACjC,GAAG;AAAA;AAAA,EACL;AAEF;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC5E,SACC;AAAA,IAAC;AAAA;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACV;AAAA,QACA;AAAA,MACD;AAAA,MACC,GAAG;AAAA;AAAA,EACL;AAEF;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAA+B;AAC5E,SACC;AAAA,IAAC;AAAA;AAAA,MACA,aAAU;AAAA,MACV,WAAW,GAAG,0CAA0C,SAAS;AAAA,MAChE,GAAG;AAAA;AAAA,EACL;AAEF;AAEA,SAAS,eAAe;AAAA,EACvB;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAAkC;AACjC,SAAO,UAAU;AAAA,IAChB,gBAAgB;AAAA,IAChB,OAAO;AAAA,MACN;AAAA,QACC,WAAW;AAAA,UACV;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACN,MAAM;AAAA,IACP;AAAA,EACD,CAAC;AACF;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAiC;AAC9E,SACC;AAAA,IAAC;AAAA;AAAA,MACA,aAAU;AAAA,MACV,gBAAa;AAAA,MACb,WAAW;AAAA,QACV;AAAA,QACA;AAAA,MACD;AAAA,MACC,GAAG;AAAA;AAAA,EACL;AAEF;AAEA,SAAS,oBAAoB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,GAAG;AACJ,GAA+B;AAC9B,SACC;AAAA,IAAC;AAAA;AAAA,MACA,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW;AAAA,QACV;AAAA,QACA;AAAA,MACD;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY,oBAAC,oBAAiB,WAAU,eAAc;AAAA;AAAA,EACxD;AAEF;AAEA,SAAS,mBAAmB;AAAA,EAC3B;AAAA,EACA,GAAG;AACJ,GAAiC;AAChC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,aAAU;AAAA,MACV,MAAK;AAAA,MACL,eAAY;AAAA,MACZ,WAAW;AAAA,QACV;AAAA,QACA;AAAA,MACD;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,4BAAC,sBAAmB;AAAA,QACpB,oBAAC,UAAK,WAAU,WAAU,kBAAI;AAAA;AAAA;AAAA,EAC/B;AAEF;","names":[]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ComponentSize } from './size-context.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A bullet chart — a compact linear gauge for KPI-vs-goal reporting where a full
|
|
6
|
+
* bar chart would be excessive. It encodes three things on one horizontal track:
|
|
7
|
+
* a **measure** bar (the actualized value), a **target** marker (the forecast to
|
|
8
|
+
* beat), and qualitative **range** bands (poor · satisfactory · good context
|
|
9
|
+
* zones) along a quantitative axis.
|
|
10
|
+
*
|
|
11
|
+
* This is just the gauge — no card, title, or value display — so it composes
|
|
12
|
+
* into whatever surrounds it (a `ChartCard`, a `KpiCard`, a table cell). Unlike
|
|
13
|
+
* the other charts in this folder it is not built on recharts (recharts has no
|
|
14
|
+
* bullet/linear-gauge primitive); it is a few positioned bands, a centered bar,
|
|
15
|
+
* and a tick. It stays size-aware via the shared `SizeProvider` and reuses the
|
|
16
|
+
* brand colour tokens.
|
|
17
|
+
*
|
|
18
|
+
* Status colour signals whether the actual cleared the forecast: `auto` paints
|
|
19
|
+
* the measure bar `status-success` when `value >= target` (OnTrack) and
|
|
20
|
+
* `status-warning` when it falls short (Behind); pass `status` to override.
|
|
21
|
+
*
|
|
22
|
+
* Tokens:
|
|
23
|
+
* - Measure bar — OnTrack `var(--color-status-success)`, Behind
|
|
24
|
+
* `var(--color-status-warning)`
|
|
25
|
+
* - Target marker — `var(--color-fg-primary)`
|
|
26
|
+
* - Range bands — progressively darker `stone` shades (poor → good); the base
|
|
27
|
+
* track is the lightest shade
|
|
28
|
+
* - Axis ticks — `var(--color-fg-caption-placeholder)`
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* <BulletChart
|
|
32
|
+
* value={108}
|
|
33
|
+
* target={100}
|
|
34
|
+
* max={120}
|
|
35
|
+
* ranges={[60, 90]}
|
|
36
|
+
* ticks={[0, 60, 120]}
|
|
37
|
+
* valueFormatter={(v) => `₦${v}M`}
|
|
38
|
+
* />
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* // Composed under a heading the consumer owns
|
|
42
|
+
* <div className="flex flex-col gap-4">
|
|
43
|
+
* <div className="flex items-start justify-between">
|
|
44
|
+
* <div>
|
|
45
|
+
* <h3 className="font-bold">Revenue</h3>
|
|
46
|
+
* <p className="text-fg-secondary">Actual vs ₦100M forecast</p>
|
|
47
|
+
* </div>
|
|
48
|
+
* <span className="text-gdt-h3 font-extrabold">₦108M</span>
|
|
49
|
+
* </div>
|
|
50
|
+
* <BulletChart value={108} target={100} max={120} ranges={[60, 90]} />
|
|
51
|
+
* </div>
|
|
52
|
+
*/
|
|
53
|
+
/** Bullet sizes line up with the three shared `ComponentSize` values. */
|
|
54
|
+
type BulletChartSize = ComponentSize;
|
|
55
|
+
/** Measure-bar sentiment — `auto` derives it from `value` vs `target`. */
|
|
56
|
+
type BulletChartStatus = "auto" | "success" | "warning";
|
|
57
|
+
type BulletChartLayout = {
|
|
58
|
+
/** Thickness of the range-band track (the pill) in px. */
|
|
59
|
+
trackHeight: number;
|
|
60
|
+
/** Thickness of the centered measure bar in px. */
|
|
61
|
+
measureHeight: number;
|
|
62
|
+
/** Height of the target marker in px — taller than the bar, inside the track. */
|
|
63
|
+
markerHeight: number;
|
|
64
|
+
/** Target marker thickness in px. */
|
|
65
|
+
markerWidth: number;
|
|
66
|
+
/** Axis tick label class. */
|
|
67
|
+
tickClass: string;
|
|
68
|
+
};
|
|
69
|
+
declare const BULLET_CHART_LAYOUT: Record<BulletChartSize, BulletChartLayout>;
|
|
70
|
+
/**
|
|
71
|
+
* Range-band shades, ordered poor → good. The base track is the lightest shade,
|
|
72
|
+
* so the first (poorest) zone blends into it and each higher zone darkens —
|
|
73
|
+
* giving the gauge its qualitative context without competing with the bar.
|
|
74
|
+
*/
|
|
75
|
+
declare const BULLET_RANGE_PALETTE: readonly ["var(--color-stone-200)", "var(--color-stone-300)", "var(--color-stone-400)"];
|
|
76
|
+
type BulletChartProps = Omit<React.ComponentProps<"div">, "children"> & {
|
|
77
|
+
/** The realized (actualized) value — drives the measure bar length. */
|
|
78
|
+
value: number;
|
|
79
|
+
/** The goal to beat — drives the target marker and the auto status colour. */
|
|
80
|
+
target: number;
|
|
81
|
+
/** Axis start. Default 0. */
|
|
82
|
+
min?: number;
|
|
83
|
+
/** Axis end. Default the largest of `value`, `target`, and the top range. */
|
|
84
|
+
max?: number;
|
|
85
|
+
/** Internal thresholds dividing [min, max] into qualitative zones, ascending. */
|
|
86
|
+
ranges?: number[];
|
|
87
|
+
/** Axis tick values. Default `[min, midpoint, max]`. Pass `[]` to hide. */
|
|
88
|
+
ticks?: number[];
|
|
89
|
+
/** Measure-bar sentiment. Default `auto` (success when `value >= target`). */
|
|
90
|
+
status?: BulletChartStatus;
|
|
91
|
+
/** Explicit size; otherwise inherited from the nearest `SizeProvider`. */
|
|
92
|
+
size?: BulletChartSize;
|
|
93
|
+
/** Format the tick labels (and the aria summary). Default grouped integer. */
|
|
94
|
+
valueFormatter?: (value: number) => string;
|
|
95
|
+
};
|
|
96
|
+
declare function BulletChart({ value, target, min, max, ranges, ticks, status, size, valueFormatter, className, ...props }: BulletChartProps): React.JSX.Element;
|
|
97
|
+
|
|
98
|
+
export { BULLET_CHART_LAYOUT, BULLET_RANGE_PALETTE, BulletChart, type BulletChartLayout, type BulletChartProps, type BulletChartSize, type BulletChartStatus };
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// src/lib/cn.ts
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
4
|
+
var twMerge = extendTailwindMerge({
|
|
5
|
+
extend: {
|
|
6
|
+
classGroups: {
|
|
7
|
+
"font-size": [
|
|
8
|
+
{
|
|
9
|
+
text: [
|
|
10
|
+
"gdt-display",
|
|
11
|
+
"gdt-h1",
|
|
12
|
+
"gdt-h2",
|
|
13
|
+
"gdt-h3",
|
|
14
|
+
"gdt-h4",
|
|
15
|
+
"gdt-h5",
|
|
16
|
+
"gdt-xl",
|
|
17
|
+
"gdt-lg",
|
|
18
|
+
"gdt-md",
|
|
19
|
+
"gdt-sm",
|
|
20
|
+
"gdt-xs",
|
|
21
|
+
"gdt-subtext",
|
|
22
|
+
"gdt-capitalized"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
function cn(...inputs) {
|
|
30
|
+
return twMerge(clsx(inputs));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/components/ui/size-context.tsx
|
|
34
|
+
import { createContext, useContext } from "react";
|
|
35
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
36
|
+
var SizeContext = createContext(void 0);
|
|
37
|
+
function useComponentSize(size, fallback = "md") {
|
|
38
|
+
const inheritedSize = useContext(SizeContext);
|
|
39
|
+
return size ?? inheritedSize ?? fallback;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/components/ui/bullet-chart.tsx
|
|
43
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
44
|
+
var BULLET_CHART_LAYOUT = {
|
|
45
|
+
sm: {
|
|
46
|
+
trackHeight: 26,
|
|
47
|
+
measureHeight: 11,
|
|
48
|
+
markerHeight: 20,
|
|
49
|
+
markerWidth: 3,
|
|
50
|
+
tickClass: "text-gdt-xs"
|
|
51
|
+
},
|
|
52
|
+
md: {
|
|
53
|
+
trackHeight: 34,
|
|
54
|
+
measureHeight: 15,
|
|
55
|
+
markerHeight: 26,
|
|
56
|
+
markerWidth: 4,
|
|
57
|
+
tickClass: "text-gdt-sm"
|
|
58
|
+
},
|
|
59
|
+
lg: {
|
|
60
|
+
trackHeight: 44,
|
|
61
|
+
measureHeight: 19,
|
|
62
|
+
markerHeight: 34,
|
|
63
|
+
markerWidth: 5,
|
|
64
|
+
tickClass: "text-gdt-sm"
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var BULLET_RANGE_PALETTE = [
|
|
68
|
+
"var(--color-stone-200)",
|
|
69
|
+
"var(--color-stone-300)",
|
|
70
|
+
"var(--color-stone-400)"
|
|
71
|
+
];
|
|
72
|
+
var STATUS_COLOR = {
|
|
73
|
+
success: "var(--color-status-success)",
|
|
74
|
+
warning: "var(--color-status-warning)"
|
|
75
|
+
};
|
|
76
|
+
function toPercent(value, min, max) {
|
|
77
|
+
if (max <= min) return 0;
|
|
78
|
+
const ratio = (value - min) / (max - min);
|
|
79
|
+
return Math.min(Math.max(ratio, 0), 1) * 100;
|
|
80
|
+
}
|
|
81
|
+
function BulletChart({
|
|
82
|
+
value,
|
|
83
|
+
target,
|
|
84
|
+
min = 0,
|
|
85
|
+
max,
|
|
86
|
+
ranges,
|
|
87
|
+
ticks,
|
|
88
|
+
status = "auto",
|
|
89
|
+
size,
|
|
90
|
+
valueFormatter = (v) => v.toLocaleString("en-NG"),
|
|
91
|
+
className,
|
|
92
|
+
...props
|
|
93
|
+
}) {
|
|
94
|
+
const layout = BULLET_CHART_LAYOUT[useComponentSize(size)];
|
|
95
|
+
const topRange = ranges?.length ? Math.max(...ranges) : 0;
|
|
96
|
+
const resolvedMax = max ?? (Math.max(value, target, topRange) || 1);
|
|
97
|
+
const resolvedTicks = ticks ?? [min, (min + resolvedMax) / 2, resolvedMax];
|
|
98
|
+
const resolvedStatus = status === "auto" ? value >= target ? "success" : "warning" : status;
|
|
99
|
+
const measureColor = STATUS_COLOR[resolvedStatus];
|
|
100
|
+
const thresholds = [
|
|
101
|
+
min,
|
|
102
|
+
...(ranges ?? []).filter((r) => r > min && r < resolvedMax).sort((a, b) => a - b),
|
|
103
|
+
resolvedMax
|
|
104
|
+
];
|
|
105
|
+
const zones = thresholds.slice(0, -1).map((from, i) => ({
|
|
106
|
+
from,
|
|
107
|
+
to: thresholds[i + 1],
|
|
108
|
+
color: BULLET_RANGE_PALETTE[Math.min(i, BULLET_RANGE_PALETTE.length - 1)]
|
|
109
|
+
}));
|
|
110
|
+
const ariaLabel = props["aria-label"] ?? `${valueFormatter(value)} of ${valueFormatter(target)} target \u2014 ${resolvedStatus === "success" ? "on track" : "behind"}`;
|
|
111
|
+
return /* @__PURE__ */ jsxs(
|
|
112
|
+
"div",
|
|
113
|
+
{
|
|
114
|
+
...props,
|
|
115
|
+
role: "img",
|
|
116
|
+
"aria-label": ariaLabel,
|
|
117
|
+
className: cn("flex w-full flex-col gap-2", className),
|
|
118
|
+
children: [
|
|
119
|
+
/* @__PURE__ */ jsxs("div", { className: "relative w-full", style: { height: layout.trackHeight }, children: [
|
|
120
|
+
/* @__PURE__ */ jsx2(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
className: "absolute inset-0 overflow-hidden rounded-full",
|
|
124
|
+
style: { backgroundColor: BULLET_RANGE_PALETTE[0] },
|
|
125
|
+
children: zones.map((zone) => /* @__PURE__ */ jsx2(
|
|
126
|
+
"div",
|
|
127
|
+
{
|
|
128
|
+
className: "absolute inset-y-0",
|
|
129
|
+
style: {
|
|
130
|
+
left: `${toPercent(zone.from, min, resolvedMax)}%`,
|
|
131
|
+
width: `${toPercent(zone.to, min, resolvedMax) - toPercent(zone.from, min, resolvedMax)}%`,
|
|
132
|
+
backgroundColor: zone.color
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
zone.from
|
|
136
|
+
))
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
/* @__PURE__ */ jsx2(
|
|
140
|
+
"div",
|
|
141
|
+
{
|
|
142
|
+
className: "absolute left-0 top-1/2 rounded-full",
|
|
143
|
+
style: {
|
|
144
|
+
height: layout.measureHeight,
|
|
145
|
+
width: `${toPercent(value, min, resolvedMax)}%`,
|
|
146
|
+
backgroundColor: measureColor,
|
|
147
|
+
transform: "translateY(-50%)"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
/* @__PURE__ */ jsx2(
|
|
152
|
+
"div",
|
|
153
|
+
{
|
|
154
|
+
className: "absolute top-1/2 rounded-full bg-fg-primary",
|
|
155
|
+
style: {
|
|
156
|
+
height: layout.markerHeight,
|
|
157
|
+
width: layout.markerWidth,
|
|
158
|
+
left: `${toPercent(target, min, resolvedMax)}%`,
|
|
159
|
+
transform: "translate(-50%, -50%)"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
] }),
|
|
164
|
+
resolvedTicks.length > 0 && /* @__PURE__ */ jsx2("div", { className: "relative h-4 w-full", children: resolvedTicks.map((tick) => {
|
|
165
|
+
const pct = toPercent(tick, min, resolvedMax);
|
|
166
|
+
const transform = pct <= 0 ? "translateX(0)" : pct >= 100 ? "translateX(-100%)" : "translateX(-50%)";
|
|
167
|
+
return /* @__PURE__ */ jsx2(
|
|
168
|
+
"span",
|
|
169
|
+
{
|
|
170
|
+
className: cn(
|
|
171
|
+
"absolute top-0 whitespace-nowrap tabular-nums text-fg-caption-placeholder",
|
|
172
|
+
layout.tickClass
|
|
173
|
+
),
|
|
174
|
+
style: { left: `${pct}%`, transform },
|
|
175
|
+
children: valueFormatter(tick)
|
|
176
|
+
},
|
|
177
|
+
tick
|
|
178
|
+
);
|
|
179
|
+
}) })
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
export {
|
|
185
|
+
BULLET_CHART_LAYOUT,
|
|
186
|
+
BULLET_RANGE_PALETTE,
|
|
187
|
+
BulletChart
|
|
188
|
+
};
|
|
189
|
+
//# sourceMappingURL=bullet-chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/cn.ts","../src/components/ui/size-context.tsx","../src/components/ui/bullet-chart.tsx"],"sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n\textend: {\n\t\tclassGroups: {\n\t\t\t\"font-size\": [\n\t\t\t\t{\n\t\t\t\t\ttext: [\n\t\t\t\t\t\t\"gdt-display\",\n\t\t\t\t\t\t\"gdt-h1\",\n\t\t\t\t\t\t\"gdt-h2\",\n\t\t\t\t\t\t\"gdt-h3\",\n\t\t\t\t\t\t\"gdt-h4\",\n\t\t\t\t\t\t\"gdt-h5\",\n\t\t\t\t\t\t\"gdt-xl\",\n\t\t\t\t\t\t\"gdt-lg\",\n\t\t\t\t\t\t\"gdt-md\",\n\t\t\t\t\t\t\"gdt-sm\",\n\t\t\t\t\t\t\"gdt-xs\",\n\t\t\t\t\t\t\"gdt-subtext\",\n\t\t\t\t\t\t\"gdt-capitalized\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n});\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { createContext, type ReactNode, useContext } from \"react\";\n\ntype ComponentSize = \"sm\" | \"md\" | \"lg\";\n\nconst SizeContext = createContext<ComponentSize | undefined>(undefined);\n\nfunction SizeProvider({\n\tchildren,\n\tsize,\n}: {\n\tchildren: ReactNode;\n\tsize?: ComponentSize | null;\n}) {\n\tif (!size) {\n\t\treturn <>{children}</>;\n\t}\n\n\treturn <SizeContext.Provider value={size}>{children}</SizeContext.Provider>;\n}\n\nfunction useComponentSize(\n\tsize?: ComponentSize | null,\n\tfallback: ComponentSize = \"md\",\n) {\n\tconst inheritedSize = useContext(SizeContext);\n\treturn size ?? inheritedSize ?? fallback;\n}\n\nexport { SizeProvider, useComponentSize, type ComponentSize };\n","\"use client\";\n\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn\";\nimport { type ComponentSize, useComponentSize } from \"./size-context\";\n\n/**\n * A bullet chart — a compact linear gauge for KPI-vs-goal reporting where a full\n * bar chart would be excessive. It encodes three things on one horizontal track:\n * a **measure** bar (the actualized value), a **target** marker (the forecast to\n * beat), and qualitative **range** bands (poor · satisfactory · good context\n * zones) along a quantitative axis.\n *\n * This is just the gauge — no card, title, or value display — so it composes\n * into whatever surrounds it (a `ChartCard`, a `KpiCard`, a table cell). Unlike\n * the other charts in this folder it is not built on recharts (recharts has no\n * bullet/linear-gauge primitive); it is a few positioned bands, a centered bar,\n * and a tick. It stays size-aware via the shared `SizeProvider` and reuses the\n * brand colour tokens.\n *\n * Status colour signals whether the actual cleared the forecast: `auto` paints\n * the measure bar `status-success` when `value >= target` (OnTrack) and\n * `status-warning` when it falls short (Behind); pass `status` to override.\n *\n * Tokens:\n * - Measure bar — OnTrack `var(--color-status-success)`, Behind\n * `var(--color-status-warning)`\n * - Target marker — `var(--color-fg-primary)`\n * - Range bands — progressively darker `stone` shades (poor → good); the base\n * track is the lightest shade\n * - Axis ticks — `var(--color-fg-caption-placeholder)`\n *\n * @example\n * <BulletChart\n * value={108}\n * target={100}\n * max={120}\n * ranges={[60, 90]}\n * ticks={[0, 60, 120]}\n * valueFormatter={(v) => `₦${v}M`}\n * />\n *\n * @example\n * // Composed under a heading the consumer owns\n * <div className=\"flex flex-col gap-4\">\n * <div className=\"flex items-start justify-between\">\n * <div>\n * <h3 className=\"font-bold\">Revenue</h3>\n * <p className=\"text-fg-secondary\">Actual vs ₦100M forecast</p>\n * </div>\n * <span className=\"text-gdt-h3 font-extrabold\">₦108M</span>\n * </div>\n * <BulletChart value={108} target={100} max={120} ranges={[60, 90]} />\n * </div>\n */\n\n/** Bullet sizes line up with the three shared `ComponentSize` values. */\ntype BulletChartSize = ComponentSize;\n\n/** Measure-bar sentiment — `auto` derives it from `value` vs `target`. */\ntype BulletChartStatus = \"auto\" | \"success\" | \"warning\";\n\ntype BulletChartLayout = {\n\t/** Thickness of the range-band track (the pill) in px. */\n\ttrackHeight: number;\n\t/** Thickness of the centered measure bar in px. */\n\tmeasureHeight: number;\n\t/** Height of the target marker in px — taller than the bar, inside the track. */\n\tmarkerHeight: number;\n\t/** Target marker thickness in px. */\n\tmarkerWidth: number;\n\t/** Axis tick label class. */\n\ttickClass: string;\n};\n\nconst BULLET_CHART_LAYOUT: Record<BulletChartSize, BulletChartLayout> = {\n\tsm: {\n\t\ttrackHeight: 26,\n\t\tmeasureHeight: 11,\n\t\tmarkerHeight: 20,\n\t\tmarkerWidth: 3,\n\t\ttickClass: \"text-gdt-xs\",\n\t},\n\tmd: {\n\t\ttrackHeight: 34,\n\t\tmeasureHeight: 15,\n\t\tmarkerHeight: 26,\n\t\tmarkerWidth: 4,\n\t\ttickClass: \"text-gdt-sm\",\n\t},\n\tlg: {\n\t\ttrackHeight: 44,\n\t\tmeasureHeight: 19,\n\t\tmarkerHeight: 34,\n\t\tmarkerWidth: 5,\n\t\ttickClass: \"text-gdt-sm\",\n\t},\n};\n\n/**\n * Range-band shades, ordered poor → good. The base track is the lightest shade,\n * so the first (poorest) zone blends into it and each higher zone darkens —\n * giving the gauge its qualitative context without competing with the bar.\n */\nconst BULLET_RANGE_PALETTE = [\n\t\"var(--color-stone-200)\",\n\t\"var(--color-stone-300)\",\n\t\"var(--color-stone-400)\",\n] as const;\n\nconst STATUS_COLOR: Record<Exclude<BulletChartStatus, \"auto\">, string> = {\n\tsuccess: \"var(--color-status-success)\",\n\twarning: \"var(--color-status-warning)\",\n};\n\n/** Clamp a value into [min, max] and express it as a 0–100 track percentage. */\nfunction toPercent(value: number, min: number, max: number) {\n\tif (max <= min) return 0;\n\tconst ratio = (value - min) / (max - min);\n\treturn Math.min(Math.max(ratio, 0), 1) * 100;\n}\n\ntype BulletChartProps = Omit<React.ComponentProps<\"div\">, \"children\"> & {\n\t/** The realized (actualized) value — drives the measure bar length. */\n\tvalue: number;\n\t/** The goal to beat — drives the target marker and the auto status colour. */\n\ttarget: number;\n\t/** Axis start. Default 0. */\n\tmin?: number;\n\t/** Axis end. Default the largest of `value`, `target`, and the top range. */\n\tmax?: number;\n\t/** Internal thresholds dividing [min, max] into qualitative zones, ascending. */\n\tranges?: number[];\n\t/** Axis tick values. Default `[min, midpoint, max]`. Pass `[]` to hide. */\n\tticks?: number[];\n\t/** Measure-bar sentiment. Default `auto` (success when `value >= target`). */\n\tstatus?: BulletChartStatus;\n\t/** Explicit size; otherwise inherited from the nearest `SizeProvider`. */\n\tsize?: BulletChartSize;\n\t/** Format the tick labels (and the aria summary). Default grouped integer. */\n\tvalueFormatter?: (value: number) => string;\n};\n\nfunction BulletChart({\n\tvalue,\n\ttarget,\n\tmin = 0,\n\tmax,\n\tranges,\n\tticks,\n\tstatus = \"auto\",\n\tsize,\n\tvalueFormatter = (v) => v.toLocaleString(\"en-NG\"),\n\tclassName,\n\t...props\n}: BulletChartProps) {\n\tconst layout = BULLET_CHART_LAYOUT[useComponentSize(size)];\n\n\tconst topRange = ranges?.length ? Math.max(...ranges) : 0;\n\tconst resolvedMax = max ?? (Math.max(value, target, topRange) || 1);\n\tconst resolvedTicks = ticks ?? [min, (min + resolvedMax) / 2, resolvedMax];\n\n\tconst resolvedStatus =\n\t\tstatus === \"auto\" ? (value >= target ? \"success\" : \"warning\") : status;\n\tconst measureColor = STATUS_COLOR[resolvedStatus];\n\n\t// Zones are the spans between consecutive thresholds (and the axis bounds).\n\tconst thresholds = [\n\t\tmin,\n\t\t...(ranges ?? [])\n\t\t\t.filter((r) => r > min && r < resolvedMax)\n\t\t\t.sort((a, b) => a - b),\n\t\tresolvedMax,\n\t];\n\tconst zones = thresholds.slice(0, -1).map((from, i) => ({\n\t\tfrom,\n\t\tto: thresholds[i + 1],\n\t\tcolor: BULLET_RANGE_PALETTE[Math.min(i, BULLET_RANGE_PALETTE.length - 1)],\n\t}));\n\n\tconst ariaLabel =\n\t\t(props[\"aria-label\"] as string | undefined) ??\n\t\t`${valueFormatter(value)} of ${valueFormatter(target)} target — ${\n\t\t\tresolvedStatus === \"success\" ? \"on track\" : \"behind\"\n\t\t}`;\n\n\treturn (\n\t\t<div\n\t\t\t{...props}\n\t\t\trole=\"img\"\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName={cn(\"flex w-full flex-col gap-2\", className)}\n\t\t>\n\t\t\t<div className=\"relative w-full\" style={{ height: layout.trackHeight }}>\n\t\t\t\t{/* Range bands — the lightest shade is the full-width base track,\n\t\t\t\t darker zones layer on top, all clipped to the pill. */}\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"absolute inset-0 overflow-hidden rounded-full\"\n\t\t\t\t\tstyle={{ backgroundColor: BULLET_RANGE_PALETTE[0] }}\n\t\t\t\t>\n\t\t\t\t\t{zones.map((zone) => (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={zone.from}\n\t\t\t\t\t\t\tclassName=\"absolute inset-y-0\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tleft: `${toPercent(zone.from, min, resolvedMax)}%`,\n\t\t\t\t\t\t\t\twidth: `${\n\t\t\t\t\t\t\t\t\ttoPercent(zone.to, min, resolvedMax) -\n\t\t\t\t\t\t\t\t\ttoPercent(zone.from, min, resolvedMax)\n\t\t\t\t\t\t\t\t}%`,\n\t\t\t\t\t\t\t\tbackgroundColor: zone.color,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\n\t\t\t\t{/* Measure / actual bar — centered, thinner than the track. */}\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"absolute left-0 top-1/2 rounded-full\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\theight: layout.measureHeight,\n\t\t\t\t\t\twidth: `${toPercent(value, min, resolvedMax)}%`,\n\t\t\t\t\t\tbackgroundColor: measureColor,\n\t\t\t\t\t\ttransform: \"translateY(-50%)\",\n\t\t\t\t\t}}\n\t\t\t\t/>\n\n\t\t\t\t{/* Target / forecast marker — taller than the bar, inside the track. */}\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"absolute top-1/2 rounded-full bg-fg-primary\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\theight: layout.markerHeight,\n\t\t\t\t\t\twidth: layout.markerWidth,\n\t\t\t\t\t\tleft: `${toPercent(target, min, resolvedMax)}%`,\n\t\t\t\t\t\ttransform: \"translate(-50%, -50%)\",\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t{resolvedTicks.length > 0 && (\n\t\t\t\t<div className=\"relative h-4 w-full\">\n\t\t\t\t\t{resolvedTicks.map((tick) => {\n\t\t\t\t\t\tconst pct = toPercent(tick, min, resolvedMax);\n\t\t\t\t\t\tconst transform =\n\t\t\t\t\t\t\tpct <= 0\n\t\t\t\t\t\t\t\t? \"translateX(0)\"\n\t\t\t\t\t\t\t\t: pct >= 100\n\t\t\t\t\t\t\t\t\t? \"translateX(-100%)\"\n\t\t\t\t\t\t\t\t\t: \"translateX(-50%)\";\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={tick}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"absolute top-0 whitespace-nowrap tabular-nums text-fg-caption-placeholder\",\n\t\t\t\t\t\t\t\t\tlayout.tickClass,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstyle={{ left: `${pct}%`, transform }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{valueFormatter(tick)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nexport { BULLET_CHART_LAYOUT, BULLET_RANGE_PALETTE, BulletChart };\nexport type {\n\tBulletChartLayout,\n\tBulletChartProps,\n\tBulletChartSize,\n\tBulletChartStatus,\n};\n"],"mappings":"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","names":["jsx"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React$1 from 'react';
|
|
2
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
3
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
import { Separator } from './separator.js';
|
|
6
|
+
import { ComponentSize } from './size-context.js';
|
|
7
|
+
import '@base-ui/react/separator';
|
|
8
|
+
|
|
9
|
+
declare const buttonGroupVariants: (props?: ({
|
|
10
|
+
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
11
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
12
|
+
declare function ButtonGroup({ className, orientation, ...props }: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants> & {
|
|
13
|
+
size?: ComponentSize;
|
|
14
|
+
}): React$1.JSX.Element;
|
|
15
|
+
declare function ButtonGroupText({ className, render, ...props }: useRender.ComponentProps<"div">): React$1.ReactElement<unknown, string | React$1.JSXElementConstructor<any>>;
|
|
16
|
+
declare function ButtonGroupSeparator({ className, orientation, ...props }: React.ComponentProps<typeof Separator>): React$1.JSX.Element;
|
|
17
|
+
|
|
18
|
+
export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants };
|