@giddaa-housing/ui 0.1.0 → 1.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 +18 -6
- package/css/base.css +37 -0
- package/css/components.css +135 -0
- package/css/generated/shared.css +1 -0
- package/css/giddaa.css +402 -0
- package/css/preset.css +77 -0
- package/css/styles.css +2 -0
- package/css/theme.css +255 -0
- package/dist/accordion.d.ts +9 -10
- package/dist/accordion.js +41 -117
- package/dist/activity-timeline.d.ts +29 -0
- package/dist/activity-timeline.js +97 -0
- package/dist/alert.d.ts +8 -9
- package/dist/alert.js +53 -141
- package/dist/auth-layout.d.ts +23 -0
- package/dist/auth-layout.js +153 -0
- package/dist/avatar.d.ts +6 -6
- package/dist/avatar.js +40 -142
- package/dist/badge.d.ts +12 -13
- package/dist/badge.js +66 -114
- package/dist/bar-chart.d.ts +136 -114
- package/dist/bar-chart.js +244 -297
- package/dist/breadcrumb.d.ts +5 -5
- package/dist/breadcrumb.js +56 -148
- package/dist/bullet-chart.d.ts +33 -33
- package/dist/bullet-chart.js +123 -183
- package/dist/button-BZIeyUw6.d.ts +17 -0
- package/dist/button-group.d.ts +13 -16
- package/dist/button-group.js +38 -163
- package/dist/button.d.ts +2 -19
- package/dist/button.js +90 -142
- package/dist/calendar.d.ts +6 -6
- package/dist/calendar.js +134 -288
- package/dist/card.d.ts +14 -16
- package/dist/card.js +58 -174
- package/dist/carousel.d.ts +34 -35
- package/dist/carousel.js +319 -378
- package/dist/chart.d.ts +58 -59
- package/dist/chart.js +350 -466
- package/dist/checkbox.d.ts +10 -12
- package/dist/checkbox.js +84 -84
- package/dist/cn-BI_4DMBf.js +23 -0
- package/dist/collapsible.d.ts +7 -8
- package/dist/collapsible.js +23 -77
- package/dist/combobox.d.ts +10 -10
- package/dist/combobox.js +220 -696
- package/dist/cta.d.ts +64 -0
- package/dist/cta.js +192 -0
- package/dist/currency-selector.d.ts +41 -0
- package/dist/currency-selector.js +114 -0
- package/dist/data-table.d.ts +164 -0
- package/dist/data-table.js +673 -0
- package/dist/date-picker.d.ts +27 -20
- package/dist/date-picker.js +122 -520
- package/dist/details-card.d.ts +19 -0
- package/dist/details-card.js +118 -0
- package/dist/dialog.d.ts +13 -14
- package/dist/dialog.js +117 -320
- package/dist/dropdown-menu.d.ts +14 -14
- package/dist/dropdown-menu.js +170 -365
- package/dist/dropzone.d.ts +55 -55
- package/dist/dropzone.js +328 -467
- package/dist/editorial-card.d.ts +27 -0
- package/dist/editorial-card.js +144 -0
- package/dist/empty-state.d.ts +8 -9
- package/dist/empty-state.js +48 -135
- package/dist/field.d.ts +23 -25
- package/dist/field.js +111 -327
- package/dist/filter.d.ts +118 -0
- package/dist/filter.js +775 -0
- package/dist/footer.d.ts +40 -0
- package/dist/footer.js +227 -0
- package/dist/funnel-chart.d.ts +38 -41
- package/dist/funnel-chart.js +168 -563
- package/dist/gallery-indicator.d.ts +17 -0
- package/dist/gallery-indicator.js +75 -0
- package/dist/heatmap-chart.d.ts +95 -0
- package/dist/heatmap-chart.js +197 -0
- package/dist/infotip.d.ts +10 -0
- package/dist/infotip.js +40 -0
- package/dist/input-CfoEJ8A6.d.ts +12 -0
- package/dist/input-group.d.ts +16 -19
- package/dist/input-group.js +92 -372
- package/dist/input-size-context-C-SFx9sx.d.ts +10 -0
- package/dist/input-size-context.d.ts +2 -11
- package/dist/input-size-context.js +14 -20
- package/dist/input.d.ts +2 -13
- package/dist/input.js +23 -79
- package/dist/item.d.ts +7 -8
- package/dist/item.js +22 -89
- package/dist/kpi-card.d.ts +18 -20
- package/dist/kpi-card.js +84 -232
- package/dist/label.d.ts +6 -6
- package/dist/label.js +39 -66
- package/dist/line-chart.d.ts +88 -89
- package/dist/line-chart.js +143 -262
- package/dist/logo.d.ts +4 -4
- package/dist/logo.js +87 -141
- package/dist/map-indicator.d.ts +13 -0
- package/dist/map-indicator.js +83 -0
- package/dist/match.d.ts +15 -0
- package/dist/match.js +68 -0
- package/dist/media-gallery-hero.d.ts +58 -0
- package/dist/media-gallery-hero.js +201 -0
- package/dist/media-player.d.ts +60 -0
- package/dist/media-player.js +919 -0
- package/dist/multi-step-form.d.ts +56 -0
- package/dist/multi-step-form.js +342 -0
- package/dist/number-input.d.ts +34 -34
- package/dist/number-input.js +62 -413
- package/dist/page-header.d.ts +10 -11
- package/dist/page-header.js +34 -107
- package/dist/pagination.d.ts +17 -20
- package/dist/pagination.js +132 -341
- package/dist/password-input.d.ts +5 -12
- package/dist/password-input.js +32 -354
- package/dist/phone-input.d.ts +19 -19
- package/dist/phone-input.js +232 -561
- package/dist/photo-gallery.d.ts +20 -20
- package/dist/photo-gallery.js +314 -746
- package/dist/picker-lzgmsNfG.js +32 -0
- package/dist/pie-chart.d.ts +60 -60
- package/dist/pie-chart.js +141 -184
- package/dist/popover.d.ts +9 -9
- package/dist/popover.js +60 -156
- package/dist/price-tag.d.ts +34 -0
- package/dist/price-tag.js +118 -0
- package/dist/progress.d.ts +18 -16
- package/dist/progress.js +156 -300
- package/dist/property-listing-card.d.ts +29 -0
- package/dist/property-listing-card.js +117 -0
- package/dist/radar-chart.d.ts +108 -0
- package/dist/radar-chart.js +172 -0
- package/dist/radio-group.d.ts +11 -13
- package/dist/radio-group.js +47 -96
- package/dist/review-block.d.ts +18 -0
- package/dist/review-block.js +154 -0
- package/dist/rich-text-editor.d.ts +30 -14
- package/dist/rich-text-editor.js +594 -979
- package/dist/scatter-chart.d.ts +140 -0
- package/dist/scatter-chart.js +248 -0
- package/dist/search-input.d.ts +8 -15
- package/dist/search-input.js +58 -408
- package/dist/select.d.ts +8 -8
- package/dist/select.js +131 -291
- package/dist/separator.d.ts +8 -9
- package/dist/separator.js +31 -70
- package/dist/sheet.d.ts +11 -11
- package/dist/sheet.js +84 -262
- package/dist/sidebar.d.ts +32 -37
- package/dist/sidebar.js +380 -1055
- package/dist/size-context-D4mYvcg8.d.ts +10 -0
- package/dist/size-context.d.ts +2 -11
- package/dist/size-context.js +14 -18
- package/dist/skeleton.d.ts +4 -5
- package/dist/skeleton.js +9 -45
- package/dist/slider.d.ts +27 -0
- package/dist/slider.js +81 -0
- package/dist/sparkline.d.ts +43 -46
- package/dist/sparkline.js +223 -561
- package/dist/stepper.d.ts +23 -24
- package/dist/stepper.js +149 -276
- package/dist/styles.css +9995 -2
- package/dist/switch.d.ts +10 -12
- package/dist/switch.js +49 -106
- package/dist/table-card.d.ts +35 -0
- package/dist/table-card.js +125 -0
- package/dist/table.d.ts +18 -14
- package/dist/table.js +114 -182
- package/dist/tabs.d.ts +23 -15
- package/dist/tabs.js +62 -149
- package/dist/tag.d.ts +22 -23
- package/dist/tag.js +104 -156
- package/dist/testimonial-block.d.ts +33 -0
- package/dist/testimonial-block.js +208 -0
- package/dist/textarea-IS_D8pXf.d.ts +11 -0
- package/dist/textarea.d.ts +2 -12
- package/dist/textarea.js +20 -74
- package/dist/time-picker.d.ts +11 -11
- package/dist/time-picker.js +247 -464
- package/dist/toast.d.ts +16 -18
- package/dist/toast.js +154 -310
- package/dist/tooltip.d.ts +9 -10
- package/dist/tooltip.js +33 -91
- package/dist/tree-map.d.ts +54 -57
- package/dist/tree-map.js +231 -646
- package/dist/use-uncontrolled-CLfM1XbB.js +21 -0
- package/dist/waterfall-chart.d.ts +126 -0
- package/dist/waterfall-chart.js +480 -0
- package/package.json +123 -34
- package/dist/accordion.js.map +0 -1
- package/dist/alert.js.map +0 -1
- package/dist/avatar.js.map +0 -1
- package/dist/badge.js.map +0 -1
- package/dist/bar-chart.js.map +0 -1
- package/dist/base.css +0 -32
- package/dist/breadcrumb.js.map +0 -1
- package/dist/bullet-chart.js.map +0 -1
- package/dist/button-group.js.map +0 -1
- package/dist/button.js.map +0 -1
- package/dist/calendar.js.map +0 -1
- package/dist/card.js.map +0 -1
- package/dist/carousel.js.map +0 -1
- package/dist/chart.js.map +0 -1
- package/dist/checkbox.js.map +0 -1
- package/dist/collapsible.js.map +0 -1
- package/dist/combobox.js.map +0 -1
- package/dist/date-picker.js.map +0 -1
- package/dist/dialog.js.map +0 -1
- package/dist/dropdown-menu.js.map +0 -1
- package/dist/dropzone.js.map +0 -1
- package/dist/empty-state.js.map +0 -1
- package/dist/field.js.map +0 -1
- 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.js.map +0 -1
- package/dist/index.d.ts +0 -87
- package/dist/index.js +0 -10448
- package/dist/index.js.map +0 -1
- package/dist/input-group.js.map +0 -1
- package/dist/input-size-context.js.map +0 -1
- package/dist/input.js.map +0 -1
- package/dist/item.js.map +0 -1
- package/dist/kpi-card.js.map +0 -1
- package/dist/label.js.map +0 -1
- package/dist/line-chart.js.map +0 -1
- package/dist/logo.js.map +0 -1
- package/dist/number-input.js.map +0 -1
- package/dist/page-header.js.map +0 -1
- package/dist/pagination.js.map +0 -1
- package/dist/password-input.js.map +0 -1
- package/dist/phone-input.js.map +0 -1
- package/dist/photo-gallery.js.map +0 -1
- package/dist/pie-chart.js.map +0 -1
- package/dist/popover.js.map +0 -1
- package/dist/progress.js.map +0 -1
- package/dist/radio-group.js.map +0 -1
- package/dist/red-hat-display.css +0 -2
- package/dist/rich-text-editor.js.map +0 -1
- package/dist/search-input.js.map +0 -1
- package/dist/select.js.map +0 -1
- package/dist/separator.js.map +0 -1
- package/dist/sheet.js.map +0 -1
- package/dist/sidebar.js.map +0 -1
- package/dist/size-context.js.map +0 -1
- package/dist/skeleton.js.map +0 -1
- package/dist/sparkline.js.map +0 -1
- package/dist/stepper.js.map +0 -1
- package/dist/switch.js.map +0 -1
- package/dist/tab-list.d.ts +0 -38
- package/dist/tab-list.js +0 -394
- package/dist/tab-list.js.map +0 -1
- package/dist/table.js.map +0 -1
- package/dist/tabs.js.map +0 -1
- package/dist/tag.js.map +0 -1
- package/dist/textarea.js.map +0 -1
- package/dist/theme/giddaa.css +0 -2
- package/dist/time-picker.js.map +0 -1
- package/dist/toast.js.map +0 -1
- package/dist/tooltip.js.map +0 -1
- package/dist/tree-map.js.map +0 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { t as ComponentSize } from "./size-context-D4mYvcg8.js";
|
|
2
|
+
import { ChartConfig } from "./chart.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { PolarAngleAxis, PolarGrid, PolarRadiusAxis, Radar, RadarChart as RadarChart$1 } from "recharts";
|
|
5
|
+
//#region src/radar-chart.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Radar charts are composable wrappers over the recharts polar primitives.
|
|
8
|
+
* recharts 3 registers graphical items through context when they render, so —
|
|
9
|
+
* unlike the recharts 2 era that shaped `bar-chart`/`line-chart` — the
|
|
10
|
+
* primitives CAN be wrapped in our own components. Each wrapper bakes in the
|
|
11
|
+
* giddaa defaults (tokens, size-scaled type, mark specs) and forwards every
|
|
12
|
+
* recharts prop, so anything can be overridden in place or replaced with the
|
|
13
|
+
* raw recharts element.
|
|
14
|
+
*
|
|
15
|
+
* Anatomy: `RadarChart` is the plot root (frame + responsive box + recharts
|
|
16
|
+
* chart); compose the grid, axes, series, and the shared overlays from
|
|
17
|
+
* `./chart` as children:
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* <ChartCard size="md">
|
|
21
|
+
* <ChartHeader>
|
|
22
|
+
* <ChartTitle>Listing scorecard</ChartTitle>
|
|
23
|
+
* <ChartDescription>How this listing scores per criterion</ChartDescription>
|
|
24
|
+
* </ChartHeader>
|
|
25
|
+
* <RadarChart config={config} data={data}>
|
|
26
|
+
* <RadarChartGrid />
|
|
27
|
+
* <RadarChartAngleAxis dataKey="criterion" />
|
|
28
|
+
* <ChartTooltip content={<ChartTooltipContent />} />
|
|
29
|
+
* <RadarChartSeries dataKey="score" name="This listing" />
|
|
30
|
+
* </RadarChart>
|
|
31
|
+
* </ChartCard>
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Categorical series palette — the theme-aware `chart-1`…`chart-3` tokens
|
|
35
|
+
* (each theme's steps are validated against that theme's chart surface; see
|
|
36
|
+
* `styles/giddaa.css`). Assign colours in this fixed order, never cycled: a
|
|
37
|
+
* fourth series folds into "Other" or becomes a second chart.
|
|
38
|
+
*/
|
|
39
|
+
declare const RADAR_CHART_PALETTE: readonly ["var(--color-chart-1)", "var(--color-chart-2)", "var(--color-chart-3)"];
|
|
40
|
+
type RadarChartLayout = {
|
|
41
|
+
/** Plot height in px. Width stays fluid via the ResponsiveContainer. */
|
|
42
|
+
height: number;
|
|
43
|
+
/** Category (angle) and value (radius) tick label font size. */
|
|
44
|
+
tickFontSize: number;
|
|
45
|
+
/** Series outline stroke width in px. */
|
|
46
|
+
strokeWidth: number;
|
|
47
|
+
/** Radius of the resting data-point dot. */
|
|
48
|
+
dotRadius: number;
|
|
49
|
+
/** Radius of the active (hover) dot. */
|
|
50
|
+
activeDotRadius: number;
|
|
51
|
+
};
|
|
52
|
+
declare const RADAR_CHART_LAYOUT: Record<ComponentSize, RadarChartLayout>;
|
|
53
|
+
type RadarChartProps = Omit<React.ComponentProps<typeof RadarChart$1>, "width" | "height"> & {
|
|
54
|
+
/** Series labels/icons for the shared tooltip and legend (see `ChartConfig`). */
|
|
55
|
+
config?: ChartConfig;
|
|
56
|
+
/** Plot scale; inherited from the nearest `SizeProvider` when omitted. */
|
|
57
|
+
size?: ComponentSize;
|
|
58
|
+
/** Applied to the responsive plot box, e.g. to override its height. */
|
|
59
|
+
className?: string;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Plot root — wraps the shared `ChartContainer` (tooltip/legend theming,
|
|
63
|
+
* responsive box) around the recharts `RadarChart` with a size-scaled height.
|
|
64
|
+
* `size` also flows to the child primitives through `SizeProvider`. Extra
|
|
65
|
+
* props reach the recharts chart (`outerRadius`, `startAngle`, `margin`, …).
|
|
66
|
+
*/
|
|
67
|
+
declare function RadarChart({ config, size, className, children, ...props }: RadarChartProps): React.JSX.Element;
|
|
68
|
+
/**
|
|
69
|
+
* Polygon web behind the series — recharts `PolarGrid` on the recessive
|
|
70
|
+
* `line` token (`line-subtle` matches the ChartCard surface in both themes,
|
|
71
|
+
* so it would vanish). Pass `gridType="circle"` for rings or
|
|
72
|
+
* `radialLines={false}` to keep only the concentric outlines.
|
|
73
|
+
*/
|
|
74
|
+
declare function RadarChartGrid(props: React.ComponentProps<typeof PolarGrid>): React.JSX.Element;
|
|
75
|
+
/**
|
|
76
|
+
* Category labels around the rim — recharts `PolarAngleAxis` with no tick
|
|
77
|
+
* lines and size-scaled secondary-ink labels. Passing your own `tick`
|
|
78
|
+
* replaces the default styling entirely.
|
|
79
|
+
*/
|
|
80
|
+
declare function RadarChartAngleAxis({ size, tick, ...props }: React.ComponentProps<typeof PolarAngleAxis> & {
|
|
81
|
+
size?: ComponentSize;
|
|
82
|
+
}): React.JSX.Element;
|
|
83
|
+
/**
|
|
84
|
+
* Value scale along one spoke — recharts `PolarRadiusAxis`, muted and
|
|
85
|
+
* line-free. Radars are usually read comparatively, so this is opt-in;
|
|
86
|
+
* include it (often with an explicit `domain={[0, max]}`) when the absolute
|
|
87
|
+
* scale matters. If the tick labels collide with a category label, move the
|
|
88
|
+
* scale between two spokes with `angle`.
|
|
89
|
+
*/
|
|
90
|
+
declare function RadarChartValueAxis({ size, tick, ...props }: React.ComponentProps<typeof PolarRadiusAxis> & {
|
|
91
|
+
size?: ComponentSize;
|
|
92
|
+
}): React.JSX.Element;
|
|
93
|
+
type RadarChartSeriesProps = React.ComponentProps<typeof Radar> & {
|
|
94
|
+
/** Series colour for the outline, wash, and dots. Defaults to brand. */
|
|
95
|
+
color?: string;
|
|
96
|
+
/** Explicit mark scale; otherwise inherited from the chart's `size`. */
|
|
97
|
+
size?: ComponentSize;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* One data series — recharts `Radar` with the giddaa mark spec: a 2px outline,
|
|
101
|
+
* the series colour washed to 15% inside the shape (matches the line-chart
|
|
102
|
+
* area wash), solid resting dots, and a hover dot ringed in `surface-raised`
|
|
103
|
+
* so overlapping series stay separable. `color` drives all of them at once;
|
|
104
|
+
* `stroke`/`fill`/`dot` still win when passed directly.
|
|
105
|
+
*/
|
|
106
|
+
declare function RadarChartSeries({ color, size, dot, activeDot, ...props }: RadarChartSeriesProps): React.JSX.Element;
|
|
107
|
+
//#endregion
|
|
108
|
+
export { RADAR_CHART_LAYOUT, RADAR_CHART_PALETTE, RadarChart, RadarChartAngleAxis, RadarChartGrid, type RadarChartLayout, type RadarChartProps, RadarChartSeries, type RadarChartSeriesProps, RadarChartValueAxis };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as cn } from "./cn-BI_4DMBf.js";
|
|
3
|
+
import { SizeProvider, useComponentSize } from "./size-context.js";
|
|
4
|
+
import { ChartContainer } from "./chart.js";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import { PolarAngleAxis, PolarGrid, PolarRadiusAxis, Radar, RadarChart as RadarChart$1 } from "recharts";
|
|
7
|
+
//#region src/radar-chart.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Radar charts are composable wrappers over the recharts polar primitives.
|
|
10
|
+
* recharts 3 registers graphical items through context when they render, so —
|
|
11
|
+
* unlike the recharts 2 era that shaped `bar-chart`/`line-chart` — the
|
|
12
|
+
* primitives CAN be wrapped in our own components. Each wrapper bakes in the
|
|
13
|
+
* giddaa defaults (tokens, size-scaled type, mark specs) and forwards every
|
|
14
|
+
* recharts prop, so anything can be overridden in place or replaced with the
|
|
15
|
+
* raw recharts element.
|
|
16
|
+
*
|
|
17
|
+
* Anatomy: `RadarChart` is the plot root (frame + responsive box + recharts
|
|
18
|
+
* chart); compose the grid, axes, series, and the shared overlays from
|
|
19
|
+
* `./chart` as children:
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* <ChartCard size="md">
|
|
23
|
+
* <ChartHeader>
|
|
24
|
+
* <ChartTitle>Listing scorecard</ChartTitle>
|
|
25
|
+
* <ChartDescription>How this listing scores per criterion</ChartDescription>
|
|
26
|
+
* </ChartHeader>
|
|
27
|
+
* <RadarChart config={config} data={data}>
|
|
28
|
+
* <RadarChartGrid />
|
|
29
|
+
* <RadarChartAngleAxis dataKey="criterion" />
|
|
30
|
+
* <ChartTooltip content={<ChartTooltipContent />} />
|
|
31
|
+
* <RadarChartSeries dataKey="score" name="This listing" />
|
|
32
|
+
* </RadarChart>
|
|
33
|
+
* </ChartCard>
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Categorical series palette — the theme-aware `chart-1`…`chart-3` tokens
|
|
37
|
+
* (each theme's steps are validated against that theme's chart surface; see
|
|
38
|
+
* `styles/giddaa.css`). Assign colours in this fixed order, never cycled: a
|
|
39
|
+
* fourth series folds into "Other" or becomes a second chart.
|
|
40
|
+
*/
|
|
41
|
+
const RADAR_CHART_PALETTE = [
|
|
42
|
+
"var(--color-chart-1)",
|
|
43
|
+
"var(--color-chart-2)",
|
|
44
|
+
"var(--color-chart-3)"
|
|
45
|
+
];
|
|
46
|
+
const DEFAULT_SERIES_COLOR = RADAR_CHART_PALETTE[0];
|
|
47
|
+
const RADAR_CHART_LAYOUT = {
|
|
48
|
+
sm: {
|
|
49
|
+
height: 180,
|
|
50
|
+
tickFontSize: 10,
|
|
51
|
+
strokeWidth: 2,
|
|
52
|
+
dotRadius: 2.5,
|
|
53
|
+
activeDotRadius: 4
|
|
54
|
+
},
|
|
55
|
+
md: {
|
|
56
|
+
height: 240,
|
|
57
|
+
tickFontSize: 11,
|
|
58
|
+
strokeWidth: 2,
|
|
59
|
+
dotRadius: 3,
|
|
60
|
+
activeDotRadius: 4.5
|
|
61
|
+
},
|
|
62
|
+
lg: {
|
|
63
|
+
height: 300,
|
|
64
|
+
tickFontSize: 12,
|
|
65
|
+
strokeWidth: 2,
|
|
66
|
+
dotRadius: 3.5,
|
|
67
|
+
activeDotRadius: 5
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Plot root — wraps the shared `ChartContainer` (tooltip/legend theming,
|
|
72
|
+
* responsive box) around the recharts `RadarChart` with a size-scaled height.
|
|
73
|
+
* `size` also flows to the child primitives through `SizeProvider`. Extra
|
|
74
|
+
* props reach the recharts chart (`outerRadius`, `startAngle`, `margin`, …).
|
|
75
|
+
*/
|
|
76
|
+
function RadarChart({ config = {}, size, className, children, ...props }) {
|
|
77
|
+
const resolvedSize = useComponentSize(size);
|
|
78
|
+
const layout = RADAR_CHART_LAYOUT[resolvedSize];
|
|
79
|
+
return /* @__PURE__ */ jsx(SizeProvider, {
|
|
80
|
+
size: resolvedSize,
|
|
81
|
+
children: /* @__PURE__ */ jsx(ChartContainer, {
|
|
82
|
+
config,
|
|
83
|
+
className: cn("aspect-auto w-full", className),
|
|
84
|
+
style: { height: layout.height },
|
|
85
|
+
children: /* @__PURE__ */ jsx(RadarChart$1, {
|
|
86
|
+
accessibilityLayer: true,
|
|
87
|
+
...props,
|
|
88
|
+
children
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Polygon web behind the series — recharts `PolarGrid` on the recessive
|
|
95
|
+
* `line` token (`line-subtle` matches the ChartCard surface in both themes,
|
|
96
|
+
* so it would vanish). Pass `gridType="circle"` for rings or
|
|
97
|
+
* `radialLines={false}` to keep only the concentric outlines.
|
|
98
|
+
*/
|
|
99
|
+
function RadarChartGrid(props) {
|
|
100
|
+
return /* @__PURE__ */ jsx(PolarGrid, {
|
|
101
|
+
stroke: "var(--color-line)",
|
|
102
|
+
...props
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Category labels around the rim — recharts `PolarAngleAxis` with no tick
|
|
107
|
+
* lines and size-scaled secondary-ink labels. Passing your own `tick`
|
|
108
|
+
* replaces the default styling entirely.
|
|
109
|
+
*/
|
|
110
|
+
function RadarChartAngleAxis({ size, tick, ...props }) {
|
|
111
|
+
const defaultTick = {
|
|
112
|
+
fontSize: RADAR_CHART_LAYOUT[useComponentSize(size)].tickFontSize,
|
|
113
|
+
fill: "var(--color-fg-secondary)"
|
|
114
|
+
};
|
|
115
|
+
return /* @__PURE__ */ jsx(PolarAngleAxis, {
|
|
116
|
+
tickLine: false,
|
|
117
|
+
tick: tick ?? defaultTick,
|
|
118
|
+
...props
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Value scale along one spoke — recharts `PolarRadiusAxis`, muted and
|
|
123
|
+
* line-free. Radars are usually read comparatively, so this is opt-in;
|
|
124
|
+
* include it (often with an explicit `domain={[0, max]}`) when the absolute
|
|
125
|
+
* scale matters. If the tick labels collide with a category label, move the
|
|
126
|
+
* scale between two spokes with `angle`.
|
|
127
|
+
*/
|
|
128
|
+
function RadarChartValueAxis({ size, tick, ...props }) {
|
|
129
|
+
const defaultTick = {
|
|
130
|
+
fontSize: RADAR_CHART_LAYOUT[useComponentSize(size)].tickFontSize,
|
|
131
|
+
fill: "var(--color-fg-caption-placeholder)"
|
|
132
|
+
};
|
|
133
|
+
return /* @__PURE__ */ jsx(PolarRadiusAxis, {
|
|
134
|
+
axisLine: false,
|
|
135
|
+
tickLine: false,
|
|
136
|
+
tick: tick ?? defaultTick,
|
|
137
|
+
...props
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* One data series — recharts `Radar` with the giddaa mark spec: a 2px outline,
|
|
142
|
+
* the series colour washed to 15% inside the shape (matches the line-chart
|
|
143
|
+
* area wash), solid resting dots, and a hover dot ringed in `surface-raised`
|
|
144
|
+
* so overlapping series stay separable. `color` drives all of them at once;
|
|
145
|
+
* `stroke`/`fill`/`dot` still win when passed directly.
|
|
146
|
+
*/
|
|
147
|
+
function RadarChartSeries({ color = DEFAULT_SERIES_COLOR, size, dot, activeDot, ...props }) {
|
|
148
|
+
const layout = RADAR_CHART_LAYOUT[useComponentSize(size)];
|
|
149
|
+
const defaultDot = {
|
|
150
|
+
r: layout.dotRadius,
|
|
151
|
+
fill: color,
|
|
152
|
+
fillOpacity: 1,
|
|
153
|
+
strokeWidth: 0
|
|
154
|
+
};
|
|
155
|
+
const defaultActiveDot = {
|
|
156
|
+
r: layout.activeDotRadius,
|
|
157
|
+
fill: color,
|
|
158
|
+
stroke: "var(--color-surface-raised)",
|
|
159
|
+
strokeWidth: 2
|
|
160
|
+
};
|
|
161
|
+
return /* @__PURE__ */ jsx(Radar, {
|
|
162
|
+
stroke: color,
|
|
163
|
+
fill: color,
|
|
164
|
+
fillOpacity: .15,
|
|
165
|
+
strokeWidth: layout.strokeWidth,
|
|
166
|
+
dot: dot ?? defaultDot,
|
|
167
|
+
activeDot: activeDot ?? defaultActiveDot,
|
|
168
|
+
...props
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
172
|
+
export { RADAR_CHART_LAYOUT, RADAR_CHART_PALETTE, RadarChart, RadarChartAngleAxis, RadarChartGrid, RadarChartSeries, RadarChartValueAxis };
|
package/dist/radio-group.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
declare function RadioGroup({ className, ...props }: RadioGroup$1.Props): React.JSX.Element;
|
|
1
|
+
import { VariantProps } from "class-variance-authority";
|
|
2
|
+
import { Radio } from "@base-ui/react/radio";
|
|
3
|
+
import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
|
|
4
|
+
//#region src/radio-group.d.ts
|
|
5
|
+
declare function RadioGroup({ className, ...props }: RadioGroup$1.Props): import("react").JSX.Element;
|
|
8
6
|
declare const radioVariants: (props?: ({
|
|
9
|
-
|
|
10
|
-
} &
|
|
7
|
+
size?: "lg" | "md" | "sm" | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
9
|
type RadioGroupItemSize = NonNullable<VariantProps<typeof radioVariants>["size"]>;
|
|
12
10
|
type RadioGroupItemProps<Value = unknown> = Radio.Root.Props<Value> & {
|
|
13
|
-
|
|
11
|
+
size?: RadioGroupItemSize;
|
|
14
12
|
};
|
|
15
13
|
/**
|
|
16
14
|
* Compose each radio item with the shared field primitives.
|
|
@@ -27,6 +25,6 @@ type RadioGroupItemProps<Value = unknown> = Radio.Root.Props<Value> & {
|
|
|
27
25
|
* </RadioGroup>
|
|
28
26
|
* ```
|
|
29
27
|
*/
|
|
30
|
-
declare function RadioGroupItem<Value = unknown>({ className, size, ...props }: RadioGroupItemProps<Value>):
|
|
31
|
-
|
|
32
|
-
export { RadioGroup, RadioGroupItem, radioVariants };
|
|
28
|
+
declare function RadioGroupItem<Value = unknown>({ className, size, ...props }: RadioGroupItemProps<Value>): import("react").JSX.Element;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { RadioGroup, RadioGroupItem, radioVariants };
|
package/dist/radio-group.js
CHANGED
|
@@ -1,100 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
"use client";
|
|
2
|
+
import { t as cn } from "./cn-BI_4DMBf.js";
|
|
3
|
+
import { useComponentSize } from "./size-context.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
import { cva } from "class-variance-authority";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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/size-context.tsx
|
|
39
|
-
import { createContext, useContext } from "react";
|
|
40
|
-
import { Fragment, jsx } from "react/jsx-runtime";
|
|
41
|
-
var SizeContext = createContext(void 0);
|
|
42
|
-
function useComponentSize(size, fallback = "md") {
|
|
43
|
-
const inheritedSize = useContext(SizeContext);
|
|
44
|
-
return size ?? inheritedSize ?? fallback;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// src/components/ui/radio-group.tsx
|
|
48
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
6
|
+
import { Radio } from "@base-ui/react/radio";
|
|
7
|
+
import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
|
|
8
|
+
//#region src/radio-group.tsx
|
|
49
9
|
function RadioGroup({ className, ...props }) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
...props
|
|
56
|
-
}
|
|
57
|
-
);
|
|
10
|
+
return /* @__PURE__ */ jsx(RadioGroup$1, {
|
|
11
|
+
"data-slot": "radio-group",
|
|
12
|
+
className: cn("grid w-full gap-2", className),
|
|
13
|
+
...props
|
|
14
|
+
});
|
|
58
15
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
);
|
|
16
|
+
const radioVariants = cva("group/radio-group-item peer relative flex aspect-square shrink-0 rounded-full border-2 bg-transparent text-transparent outline-none transition-[background-color,border-color,box-shadow,color] after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-line-focus focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] aria-invalid:border-line-danger aria-invalid:ring-3 aria-invalid:ring-destructive/20 border-line-strong data-checked:border-action-primary data-checked:text-action-primary data-disabled:cursor-not-allowed data-disabled:border-line-subtle data-disabled:bg-surface data-disabled:text-fg-caption-placeholder size-5 [--radio-dot-size:0.75rem] group-data-[size=sm]/field:size-4 group-data-[size=sm]/field:[--radio-dot-size:0.625rem] group-data-[size=md]/field:size-5 group-data-[size=md]/field:[--radio-dot-size:0.75rem] group-data-[size=lg]/field:size-6 group-data-[size=lg]/field:[--radio-dot-size:0.875rem]", { variants: { size: {
|
|
17
|
+
sm: "size-4 [--radio-dot-size:0.625rem]",
|
|
18
|
+
md: "size-5 [--radio-dot-size:0.75rem]",
|
|
19
|
+
lg: "size-6 [--radio-dot-size:0.875rem]"
|
|
20
|
+
} } });
|
|
21
|
+
/**
|
|
22
|
+
* Compose each radio item with the shared field primitives.
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* <RadioGroup defaultValue="option-1">
|
|
26
|
+
* <Field orientation="horizontal" size="md">
|
|
27
|
+
* <RadioGroupItem id="option-1" value="option-1" />
|
|
28
|
+
* <FieldContent>
|
|
29
|
+
* <FieldLabel htmlFor="option-1">Radio label</FieldLabel>
|
|
30
|
+
* <FieldDescription>Optional helper description for context.</FieldDescription>
|
|
31
|
+
* </FieldContent>
|
|
32
|
+
* </Field>
|
|
33
|
+
* </RadioGroup>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function RadioGroupItem({ className, size, ...props }) {
|
|
37
|
+
const resolvedSize = useComponentSize(size);
|
|
38
|
+
return /* @__PURE__ */ jsx(Radio.Root, {
|
|
39
|
+
"data-slot": "radio-group-item",
|
|
40
|
+
"data-size": resolvedSize,
|
|
41
|
+
className: cn(radioVariants({ size: resolvedSize }), className),
|
|
42
|
+
...props,
|
|
43
|
+
children: /* @__PURE__ */ jsx(Radio.Indicator, {
|
|
44
|
+
"data-slot": "radio-group-indicator",
|
|
45
|
+
className: "flex size-full items-center justify-center",
|
|
46
|
+
children: /* @__PURE__ */ jsx("span", { className: "absolute top-1/2 left-1/2 size-(--radio-dot-size) -translate-x-1/2 -translate-y-1/2 rounded-full bg-current" })
|
|
47
|
+
})
|
|
48
|
+
});
|
|
94
49
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
RadioGroupItem,
|
|
98
|
-
radioVariants
|
|
99
|
-
};
|
|
100
|
-
//# sourceMappingURL=radio-group.js.map
|
|
50
|
+
//#endregion
|
|
51
|
+
export { RadioGroup, RadioGroupItem, radioVariants };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
//#region src/review-block.d.ts
|
|
4
|
+
declare const reviewBlockVariants: (props?: ({
|
|
5
|
+
size?: "lg" | "md" | "sm" | "xs" | null | undefined;
|
|
6
|
+
bordered?: boolean | null | undefined;
|
|
7
|
+
showReviewText?: boolean | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
9
|
+
type ReviewBlockSize = NonNullable<VariantProps<typeof reviewBlockVariants>["size"]>;
|
|
10
|
+
type ReviewBlockProps = Omit<useRender.ComponentProps<"div">, "children"> & VariantProps<typeof reviewBlockVariants> & {
|
|
11
|
+
rating: number;
|
|
12
|
+
reviewCount?: number;
|
|
13
|
+
reviewLabel?: string;
|
|
14
|
+
ratingLabel?: string;
|
|
15
|
+
};
|
|
16
|
+
declare function ReviewBlock({ bordered, className, rating, ratingLabel, render, reviewCount, reviewLabel, size, showReviewText, ...props }: ReviewBlockProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { ReviewBlock, type ReviewBlockProps, type ReviewBlockSize, reviewBlockVariants };
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { t as cn } from "./cn-BI_4DMBf.js";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
//#region src/review-block.tsx
|
|
7
|
+
const STAR_INDEXES = [
|
|
8
|
+
0,
|
|
9
|
+
1,
|
|
10
|
+
2,
|
|
11
|
+
3,
|
|
12
|
+
4
|
|
13
|
+
];
|
|
14
|
+
const reviewBlockVariants = cva("group/review-block inline-flex w-fit min-w-0 flex-col items-center justify-center rounded-full bg-canvas text-fg-primary transition-[background-color,border-color,box-shadow]", {
|
|
15
|
+
variants: {
|
|
16
|
+
size: {
|
|
17
|
+
xs: "gap-[2px] border px-6 py-1.5",
|
|
18
|
+
sm: "gap-[3px] border-[1.5px] px-10 py-1.5",
|
|
19
|
+
md: "gap-1 border-2 px-14 py-2",
|
|
20
|
+
lg: "gap-[5px] border-[2.5px] px-18 py-2.5"
|
|
21
|
+
},
|
|
22
|
+
bordered: {
|
|
23
|
+
true: "border-line-focus",
|
|
24
|
+
false: "border-transparent"
|
|
25
|
+
},
|
|
26
|
+
showReviewText: {
|
|
27
|
+
true: "",
|
|
28
|
+
false: ""
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
defaultVariants: {
|
|
32
|
+
size: "md",
|
|
33
|
+
bordered: true,
|
|
34
|
+
showReviewText: true
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const reviewBlockStarsVariants = cva("inline-flex shrink-0 items-center", {
|
|
38
|
+
variants: { size: {
|
|
39
|
+
xs: "gap-1.5",
|
|
40
|
+
sm: "gap-2",
|
|
41
|
+
md: "gap-2.5",
|
|
42
|
+
lg: "gap-3.5"
|
|
43
|
+
} },
|
|
44
|
+
defaultVariants: { size: "md" }
|
|
45
|
+
});
|
|
46
|
+
const reviewBlockStarVariants = cva("relative inline-flex shrink-0", {
|
|
47
|
+
variants: { size: {
|
|
48
|
+
xs: "size-4",
|
|
49
|
+
sm: "size-6",
|
|
50
|
+
md: "size-9",
|
|
51
|
+
lg: "size-12"
|
|
52
|
+
} },
|
|
53
|
+
defaultVariants: { size: "md" }
|
|
54
|
+
});
|
|
55
|
+
const reviewBlockStarIconVariants = cva("block h-full max-w-none", {
|
|
56
|
+
variants: { size: {
|
|
57
|
+
xs: "w-4",
|
|
58
|
+
sm: "w-6",
|
|
59
|
+
md: "w-9",
|
|
60
|
+
lg: "w-12"
|
|
61
|
+
} },
|
|
62
|
+
defaultVariants: { size: "md" }
|
|
63
|
+
});
|
|
64
|
+
const reviewBlockTextVariants = cva("text-center font-medium text-fg-primary whitespace-nowrap", {
|
|
65
|
+
variants: { size: {
|
|
66
|
+
xs: "text-[0.75rem] leading-[1.125rem]",
|
|
67
|
+
sm: "text-gdt-sm",
|
|
68
|
+
md: "text-[1rem] leading-[1.375rem]",
|
|
69
|
+
lg: "text-[1.125rem] leading-[1.5rem]"
|
|
70
|
+
} },
|
|
71
|
+
defaultVariants: { size: "md" }
|
|
72
|
+
});
|
|
73
|
+
function clampRating(rating) {
|
|
74
|
+
if (!Number.isFinite(rating)) return 0;
|
|
75
|
+
return Math.min(5, Math.max(0, rating));
|
|
76
|
+
}
|
|
77
|
+
function getStarFill(index, rating) {
|
|
78
|
+
return Math.min(1, Math.max(0, rating - index)) * 100;
|
|
79
|
+
}
|
|
80
|
+
function formatRating(rating) {
|
|
81
|
+
return Number.isInteger(rating) ? rating.toString() : rating.toFixed(2).replace(/0+$/, "").replace(/\.$/, "");
|
|
82
|
+
}
|
|
83
|
+
function formatReviewText(reviewCount, reviewLabel = "Review") {
|
|
84
|
+
const normalizedLabel = reviewCount === 1 ? reviewLabel : `${reviewLabel}s`;
|
|
85
|
+
return `${reviewCount.toLocaleString()} ${normalizedLabel}`;
|
|
86
|
+
}
|
|
87
|
+
function ReviewStarIcon(props) {
|
|
88
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
89
|
+
"aria-hidden": "true",
|
|
90
|
+
fill: "none",
|
|
91
|
+
focusable: "false",
|
|
92
|
+
viewBox: "0 0 35 33",
|
|
93
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
94
|
+
...props,
|
|
95
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
96
|
+
d: "m17.119 0 4.042 12.437h13.077l-10.58 7.688L27.7 32.562l-10.58-7.686-10.58 7.686 4.04-12.437L0 12.438h13.077L17.12 0Z",
|
|
97
|
+
fill: "currentColor"
|
|
98
|
+
})
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function ReviewStar({ fillPercent, size }) {
|
|
102
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
103
|
+
className: reviewBlockStarVariants({ size }),
|
|
104
|
+
children: [/* @__PURE__ */ jsx(ReviewStarIcon, {
|
|
105
|
+
"aria-hidden": "true",
|
|
106
|
+
className: cn("text-line-focus", reviewBlockStarIconVariants({ size }))
|
|
107
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
108
|
+
"aria-hidden": "true",
|
|
109
|
+
className: "absolute inset-y-0 left-0 overflow-hidden text-line-focus",
|
|
110
|
+
style: { width: `${fillPercent}%` },
|
|
111
|
+
children: /* @__PURE__ */ jsx(ReviewStarIcon, { className: reviewBlockStarIconVariants({ size }) })
|
|
112
|
+
})]
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function ReviewBlock({ bordered = true, className, rating, ratingLabel, render, reviewCount, reviewLabel, size = "md", showReviewText = true, ...props }) {
|
|
116
|
+
const resolvedSize = size ?? "md";
|
|
117
|
+
const normalizedRating = clampRating(rating);
|
|
118
|
+
const formattedRating = formatRating(normalizedRating);
|
|
119
|
+
const reviewText = showReviewText && typeof reviewCount === "number" ? formatReviewText(reviewCount, reviewLabel) : null;
|
|
120
|
+
return useRender({
|
|
121
|
+
defaultTagName: "div",
|
|
122
|
+
props: mergeProps({
|
|
123
|
+
"aria-label": ratingLabel ?? (reviewText ? `${formattedRating} out of 5 stars, ${reviewText}` : `${formattedRating} out of 5 stars`),
|
|
124
|
+
className: cn(reviewBlockVariants({
|
|
125
|
+
bordered,
|
|
126
|
+
size: resolvedSize,
|
|
127
|
+
showReviewText: Boolean(reviewText)
|
|
128
|
+
}), className),
|
|
129
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
130
|
+
"aria-hidden": "true",
|
|
131
|
+
className: reviewBlockStarsVariants({ size: resolvedSize }),
|
|
132
|
+
children: STAR_INDEXES.map((index) => /* @__PURE__ */ jsx(ReviewStar, {
|
|
133
|
+
fillPercent: getStarFill(index, normalizedRating),
|
|
134
|
+
size: resolvedSize
|
|
135
|
+
}, index))
|
|
136
|
+
}), reviewText ? /* @__PURE__ */ jsx("span", {
|
|
137
|
+
className: reviewBlockTextVariants({ size: resolvedSize }),
|
|
138
|
+
children: reviewText
|
|
139
|
+
}) : null] }),
|
|
140
|
+
role: "img"
|
|
141
|
+
}, props),
|
|
142
|
+
render,
|
|
143
|
+
state: {
|
|
144
|
+
bordered,
|
|
145
|
+
rating: normalizedRating,
|
|
146
|
+
reviewCount,
|
|
147
|
+
size: resolvedSize,
|
|
148
|
+
showReviewText: Boolean(reviewText),
|
|
149
|
+
slot: "review-block"
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
154
|
+
export { ReviewBlock, reviewBlockVariants };
|