@refraction-ui/react 0.19.1 → 0.20.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/dist/chunk-533MCMSU.js +2355 -0
- package/dist/chunk-533MCMSU.js.map +7 -0
- package/dist/chunk-AMK4VCBG.js +250 -0
- package/dist/chunk-AMK4VCBG.js.map +7 -0
- package/dist/chunk-BOLFYVI6.js +90 -0
- package/dist/chunk-BOLFYVI6.js.map +7 -0
- package/dist/chunk-F7B64KT3.js +187 -0
- package/dist/chunk-F7B64KT3.js.map +7 -0
- package/dist/chunk-FD37DFCC.js +77 -0
- package/dist/chunk-FD37DFCC.js.map +7 -0
- package/dist/chunk-H54FLNAF.js +132 -0
- package/dist/chunk-H54FLNAF.js.map +7 -0
- package/dist/chunk-INP46354.js +664 -0
- package/dist/chunk-INP46354.js.map +7 -0
- package/dist/chunk-ONACRMG4.js +116 -0
- package/dist/chunk-ONACRMG4.js.map +7 -0
- package/dist/chunk-SDZ3LROZ.js +7 -0
- package/dist/chunk-SDZ3LROZ.js.map +7 -0
- package/dist/chunk-TOZBR4GL.js +154 -0
- package/dist/chunk-TOZBR4GL.js.map +7 -0
- package/dist/chunk-UNEM2TRI.js +225 -0
- package/dist/chunk-UNEM2TRI.js.map +7 -0
- package/dist/chunk-VK3EQ34F.js +92 -0
- package/dist/chunk-VK3EQ34F.js.map +7 -0
- package/dist/chunk-WK2IIUFO.js +316 -0
- package/dist/chunk-WK2IIUFO.js.map +7 -0
- package/dist/chunk-WSPJTQAV.js +59 -0
- package/dist/chunk-WSPJTQAV.js.map +7 -0
- package/dist/chunk-XWP763SH.js +3 -2
- package/dist/chunk-XWP763SH.js.map +7 -1
- package/dist/chunk-Y2FNNAIL.js +80 -0
- package/dist/chunk-Y2FNNAIL.js.map +1 -0
- package/dist/{chunk-4A4BW3GR.js → chunk-ZF3OHCGV.js} +28 -5
- package/dist/chunk-ZF3OHCGV.js.map +7 -0
- package/dist/form.cjs +5 -11
- package/dist/form.cjs.map +1 -1
- package/dist/form.js +6 -12
- package/dist/form.js.map +1 -1
- package/dist/index.cjs +2879 -33936
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +126 -28780
- package/dist/internal/react-app-shell/index.d.cts +2 -22
- package/dist/internal/react-app-shell/index.d.ts +2 -22
- package/dist/internal/react-badge/index.d.cts +5 -0
- package/dist/internal/react-badge/index.d.ts +5 -0
- package/dist/internal/react-callout/index.d.cts +4 -0
- package/dist/internal/react-callout/index.d.ts +4 -0
- package/dist/internal/react-card/index.d.cts +8 -1
- package/dist/internal/react-card/index.d.ts +8 -1
- package/dist/internal/react-collapsible/index.d.cts +0 -3
- package/dist/internal/react-collapsible/index.d.ts +0 -3
- package/dist/internal/react-combobox/index.d.cts +0 -3
- package/dist/internal/react-combobox/index.d.ts +0 -3
- package/dist/internal/react-command/index.d.cts +0 -3
- package/dist/internal/react-command/index.d.ts +0 -3
- package/dist/internal/react-data-table/index.d.cts +0 -3
- package/dist/internal/react-data-table/index.d.ts +0 -3
- package/dist/internal/react-dialog/index.d.cts +0 -3
- package/dist/internal/react-dialog/index.d.ts +0 -3
- package/dist/internal/react-dropdown-menu/index.d.cts +0 -3
- package/dist/internal/react-dropdown-menu/index.d.ts +0 -3
- package/dist/internal/react-feedback-dialog/index.d.cts +0 -3
- package/dist/internal/react-feedback-dialog/index.d.ts +0 -3
- package/dist/internal/react-form/index.d.cts +2 -21
- package/dist/internal/react-form/index.d.ts +2 -21
- package/dist/internal/react-keyboard-shortcut/index.d.cts +0 -6
- package/dist/internal/react-keyboard-shortcut/index.d.ts +0 -6
- package/dist/internal/react-link-card/index.d.cts +8 -2
- package/dist/internal/react-link-card/index.d.ts +8 -2
- package/dist/internal/react-popover/index.d.cts +0 -3
- package/dist/internal/react-popover/index.d.ts +0 -3
- package/dist/internal/react-sheet/index.d.cts +0 -3
- package/dist/internal/react-sheet/index.d.ts +0 -3
- package/dist/internal/react-slot/index.d.cts +23 -0
- package/dist/internal/react-slot/index.d.ts +23 -0
- package/dist/internal/react-toast/index.d.cts +0 -3
- package/dist/internal/react-toast/index.d.ts +0 -3
- package/dist/internal/react-tooltip/index.d.cts +0 -3
- package/dist/internal/react-tooltip/index.d.ts +0 -3
- package/dist/react-accordion.js +125 -0
- package/dist/react-accordion.js.map +7 -0
- package/dist/react-ai.js +257 -0
- package/dist/react-ai.js.map +7 -0
- package/dist/react-analytics.js +1698 -0
- package/dist/react-analytics.js.map +7 -0
- package/dist/react-animated-text.js +164 -0
- package/dist/react-animated-text.js.map +7 -0
- package/dist/react-app-shell.js +631 -0
- package/dist/react-app-shell.js.map +7 -0
- package/dist/react-audience-feature-card.js +53 -0
- package/dist/react-audience-feature-card.js.map +7 -0
- package/dist/react-audio-room.js +166 -0
- package/dist/react-audio-room.js.map +7 -0
- package/dist/react-auth.js +211 -0
- package/dist/react-auth.js.map +7 -0
- package/dist/react-avatar-group.js +154 -0
- package/dist/react-avatar-group.js.map +7 -0
- package/dist/react-avatar.js +168 -0
- package/dist/react-avatar.js.map +7 -0
- package/dist/react-badge.js +86 -0
- package/dist/react-badge.js.map +7 -0
- package/dist/react-bottom-nav.js +67 -0
- package/dist/react-bottom-nav.js.map +7 -0
- package/dist/react-brand-network-cell.js +92 -0
- package/dist/react-brand-network-cell.js.map +7 -0
- package/dist/react-breadcrumbs.js +104 -0
- package/dist/react-breadcrumbs.js.map +7 -0
- package/dist/react-browser-chrome-mock.js +89 -0
- package/dist/react-browser-chrome-mock.js.map +7 -0
- package/dist/react-button.js +13 -0
- package/dist/react-button.js.map +7 -0
- package/dist/react-calendar.js +301 -0
- package/dist/react-calendar.js.map +7 -0
- package/dist/react-call-controls.js +113 -0
- package/dist/react-call-controls.js.map +7 -0
- package/dist/react-callout.js +152 -0
- package/dist/react-callout.js.map +7 -0
- package/dist/react-card-grid.js +34 -0
- package/dist/react-card-grid.js.map +7 -0
- package/dist/react-card.js +200 -0
- package/dist/react-card.js.map +7 -0
- package/dist/react-carousel.js +132 -0
- package/dist/react-carousel.js.map +7 -0
- package/dist/react-charts.js +509 -0
- package/dist/react-charts.js.map +7 -0
- package/dist/react-checkbox.js +156 -0
- package/dist/react-checkbox.js.map +7 -0
- package/dist/react-checklist.js +168 -0
- package/dist/react-checklist.js.map +7 -0
- package/dist/react-code-block.js +78 -0
- package/dist/react-code-block.js.map +7 -0
- package/dist/react-code-editor.js +184 -0
- package/dist/react-code-editor.js.map +7 -0
- package/dist/react-collapsible.js +192 -0
- package/dist/react-collapsible.js.map +7 -0
- package/dist/react-combobox.js +609 -0
- package/dist/react-combobox.js.map +7 -0
- package/dist/react-command-input.js +202 -0
- package/dist/react-command-input.js.map +7 -0
- package/dist/react-command.js +364 -0
- package/dist/react-command.js.map +7 -0
- package/dist/react-composer.js +2036 -0
- package/dist/react-composer.js.map +7 -0
- package/dist/react-content-protection.js +133 -0
- package/dist/react-content-protection.js.map +7 -0
- package/dist/react-conversation.js +1226 -0
- package/dist/react-conversation.js.map +7 -0
- package/dist/react-cookie-consent.js +291 -0
- package/dist/react-cookie-consent.js.map +7 -0
- package/dist/react-data-table.js +310 -0
- package/dist/react-data-table.js.map +7 -0
- package/dist/react-date-picker.js +95 -0
- package/dist/react-date-picker.js.map +7 -0
- package/dist/react-device-frame.js +137 -0
- package/dist/react-device-frame.js.map +7 -0
- package/dist/react-dialog.js +218 -0
- package/dist/react-dialog.js.map +7 -0
- package/dist/react-diff-viewer.js +460 -0
- package/dist/react-diff-viewer.js.map +7 -0
- package/dist/react-dropdown-menu.js +292 -0
- package/dist/react-dropdown-menu.js.map +7 -0
- package/dist/react-editor-status-bar.js +148 -0
- package/dist/react-editor-status-bar.js.map +7 -0
- package/dist/react-editor-tabs.js +159 -0
- package/dist/react-editor-tabs.js.map +7 -0
- package/dist/react-emoji-picker.js +238 -0
- package/dist/react-emoji-picker.js.map +7 -0
- package/dist/react-empty-state.js +90 -0
- package/dist/react-empty-state.js.map +7 -0
- package/dist/react-feedback-dialog.js +275 -0
- package/dist/react-feedback-dialog.js.map +7 -0
- package/dist/react-file-tree.js +376 -0
- package/dist/react-file-tree.js.map +7 -0
- package/dist/react-file-upload.js +360 -0
- package/dist/react-file-upload.js.map +7 -0
- package/dist/react-floating-reactions.js +124 -0
- package/dist/react-floating-reactions.js.map +7 -0
- package/dist/react-flow-editor.js +198 -0
- package/dist/react-flow-editor.js.map +7 -0
- package/dist/react-footer.js +67 -0
- package/dist/react-footer.js.map +7 -0
- package/dist/react-graph-view.js +197 -0
- package/dist/react-graph-view.js.map +7 -0
- package/dist/react-icon-system.js +9 -0
- package/dist/react-icon-system.js.map +7 -0
- package/dist/react-infinite-canvas.js +8 -0
- package/dist/react-infinite-canvas.js.map +7 -0
- package/dist/react-inline-editor.js +216 -0
- package/dist/react-inline-editor.js.map +7 -0
- package/dist/react-input-group.js +150 -0
- package/dist/react-input-group.js.map +7 -0
- package/dist/react-input.js +10 -0
- package/dist/react-input.js.map +7 -0
- package/dist/react-install-prompt.js +132 -0
- package/dist/react-install-prompt.js.map +7 -0
- package/dist/react-kanban-board.js +198 -0
- package/dist/react-kanban-board.js.map +7 -0
- package/dist/react-keyboard-shortcut.js +36 -0
- package/dist/react-keyboard-shortcut.js.map +7 -0
- package/dist/react-language-selector.js +311 -0
- package/dist/react-language-selector.js.map +7 -0
- package/dist/react-link-card.js +48 -0
- package/dist/react-link-card.js.map +7 -0
- package/dist/react-live-captions.js +92 -0
- package/dist/react-live-captions.js.map +7 -0
- package/dist/react-live-cursors.js +145 -0
- package/dist/react-live-cursors.js.map +7 -0
- package/dist/react-live-transcript.js +117 -0
- package/dist/react-live-transcript.js.map +7 -0
- package/dist/react-location-selector.js +252 -0
- package/dist/react-location-selector.js.map +7 -0
- package/dist/react-logger.js +415 -0
- package/dist/react-logger.js.map +7 -0
- package/dist/react-markdown-renderer.js +12 -0
- package/dist/react-markdown-renderer.js.map +7 -0
- package/dist/react-marquee-strip.js +62 -0
- package/dist/react-marquee-strip.js.map +7 -0
- package/dist/react-mascot.js +367 -0
- package/dist/react-mascot.js.map +7 -0
- package/dist/react-mastery-bar.js +97 -0
- package/dist/react-mastery-bar.js.map +7 -0
- package/dist/react-mini-map.js +207 -0
- package/dist/react-mini-map.js.map +7 -0
- package/dist/react-mobile-nav.js +216 -0
- package/dist/react-mobile-nav.js.map +7 -0
- package/dist/react-navbar.js +96 -0
- package/dist/react-navbar.js.map +7 -0
- package/dist/react-numbered-steps.js +67 -0
- package/dist/react-numbered-steps.js.map +7 -0
- package/dist/react-otp-input.js +318 -0
- package/dist/react-otp-input.js.map +7 -0
- package/dist/react-pagination.js +199 -0
- package/dist/react-pagination.js.map +7 -0
- package/dist/react-password-input.js +104 -0
- package/dist/react-password-input.js.map +7 -0
- package/dist/react-payment.js +81 -0
- package/dist/react-payment.js.map +7 -0
- package/dist/react-popover.js +176 -0
- package/dist/react-popover.js.map +7 -0
- package/dist/react-pre-call-lobby.js +309 -0
- package/dist/react-pre-call-lobby.js.map +7 -0
- package/dist/react-presence-indicator.js +86 -0
- package/dist/react-presence-indicator.js.map +7 -0
- package/dist/react-pricing-card.js +142 -0
- package/dist/react-pricing-card.js.map +7 -0
- package/dist/react-progress-display.js +188 -0
- package/dist/react-progress-display.js.map +7 -0
- package/dist/react-radial-gauge.js +193 -0
- package/dist/react-radial-gauge.js.map +7 -0
- package/dist/react-radio.js +169 -0
- package/dist/react-radio.js.map +7 -0
- package/dist/react-rating-scale.js +171 -0
- package/dist/react-rating-scale.js.map +7 -0
- package/dist/react-reaction-bar.js +111 -0
- package/dist/react-reaction-bar.js.map +7 -0
- package/dist/react-resizable-layout.js +298 -0
- package/dist/react-resizable-layout.js.map +7 -0
- package/dist/react-rich-editor.js +1 -0
- package/dist/react-rich-editor.js.map +7 -0
- package/dist/react-search-bar.js +285 -0
- package/dist/react-search-bar.js.map +7 -0
- package/dist/react-section-head.js +65 -0
- package/dist/react-section-head.js.map +7 -0
- package/dist/react-segmented-control.js +215 -0
- package/dist/react-segmented-control.js.map +7 -0
- package/dist/react-select.js +389 -0
- package/dist/react-select.js.map +7 -0
- package/dist/react-separator.js +86 -0
- package/dist/react-separator.js.map +7 -0
- package/dist/react-sheet.js +310 -0
- package/dist/react-sheet.js.map +7 -0
- package/dist/react-sidebar.js +100 -0
- package/dist/react-sidebar.js.map +7 -0
- package/dist/react-skeleton.js +91 -0
- package/dist/react-skeleton.js.map +7 -0
- package/dist/react-skip-to-content.js +38 -0
- package/dist/react-skip-to-content.js.map +7 -0
- package/dist/react-slide-viewer.js +264 -0
- package/dist/react-slide-viewer.js.map +7 -0
- package/dist/react-slider.js +105 -0
- package/dist/react-slider.js.map +7 -0
- package/dist/react-slot-picker.js +184 -0
- package/dist/react-slot-picker.js.map +7 -0
- package/dist/react-slot.js +7 -0
- package/dist/react-slot.js.map +7 -0
- package/dist/react-social-auth-button.js +169 -0
- package/dist/react-social-auth-button.js.map +7 -0
- package/dist/react-sortable-list.js +204 -0
- package/dist/react-sortable-list.js.map +7 -0
- package/dist/react-stat-grid.js +69 -0
- package/dist/react-stat-grid.js.map +7 -0
- package/dist/react-status-indicator.js +117 -0
- package/dist/react-status-indicator.js.map +7 -0
- package/dist/react-steps.js +167 -0
- package/dist/react-steps.js.map +7 -0
- package/dist/react-sticky-note.js +131 -0
- package/dist/react-sticky-note.js.map +7 -0
- package/dist/react-switch.js +139 -0
- package/dist/react-switch.js.map +7 -0
- package/dist/react-table-of-contents.js +80 -0
- package/dist/react-table-of-contents.js.map +7 -0
- package/dist/react-tabs.js +230 -0
- package/dist/react-tabs.js.map +7 -0
- package/dist/react-terminal.js +101 -0
- package/dist/react-terminal.js.map +7 -0
- package/dist/react-test-results.js +158 -0
- package/dist/react-test-results.js.map +7 -0
- package/dist/react-textarea.js +89 -0
- package/dist/react-textarea.js.map +7 -0
- package/dist/react-thread-view.js +139 -0
- package/dist/react-thread-view.js.map +7 -0
- package/dist/react-timeline.js +153 -0
- package/dist/react-timeline.js.map +7 -0
- package/dist/react-toast.js +253 -0
- package/dist/react-toast.js.map +7 -0
- package/dist/react-tooltip.js +221 -0
- package/dist/react-tooltip.js.map +7 -0
- package/dist/react-version-selector.js +270 -0
- package/dist/react-version-selector.js.map +7 -0
- package/dist/react-video-grid.js +129 -0
- package/dist/react-video-grid.js.map +7 -0
- package/dist/react-video-player.js +206 -0
- package/dist/react-video-player.js.map +7 -0
- package/dist/react-video-tile.js +8 -0
- package/dist/react-video-tile.js.map +7 -0
- package/dist/react-voice-pill.js +314 -0
- package/dist/react-voice-pill.js.map +7 -0
- package/dist/react-waveform.js +558 -0
- package/dist/react-waveform.js.map +7 -0
- package/dist/react-wizard.js +337 -0
- package/dist/react-wizard.js.map +7 -0
- package/dist/styles.css +7 -0
- package/dist/theme.js +1 -1
- package/package.json +3 -2
- package/dist/applicationinsights-web-H7OBLIVJ.js +0 -23393
- package/dist/applicationinsights-web-H7OBLIVJ.js.map +0 -1
- package/dist/chunk-4A4BW3GR.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/module-X3HTTRQK.js +0 -6438
- package/dist/module-X3HTTRQK.js.map +0 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn,
|
|
3
|
+
cva
|
|
4
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
5
|
+
|
|
6
|
+
// ../react-progress-display/dist/index.js
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
|
|
9
|
+
// ../progress-display/dist/index.js
|
|
10
|
+
function createProgressDisplay(props) {
|
|
11
|
+
const { stats, badges } = props;
|
|
12
|
+
const ariaProps = {
|
|
13
|
+
role: "region",
|
|
14
|
+
"aria-label": "Progress statistics"
|
|
15
|
+
};
|
|
16
|
+
function getBadgeAriaProps(badge) {
|
|
17
|
+
const label = badge.isUnlocked ? `${badge.name}: ${badge.description}` : `${badge.name}: ${badge.description} (locked)`;
|
|
18
|
+
return {
|
|
19
|
+
"aria-label": label
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
stats,
|
|
24
|
+
badges,
|
|
25
|
+
ariaProps,
|
|
26
|
+
getBadgeAriaProps
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
var statsGridVariants = cva({
|
|
30
|
+
base: "grid gap-4",
|
|
31
|
+
variants: {
|
|
32
|
+
columns: {
|
|
33
|
+
"2": "grid-cols-2",
|
|
34
|
+
"3": "grid-cols-3",
|
|
35
|
+
"4": "grid-cols-4"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
defaultVariants: {
|
|
39
|
+
columns: "3"
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
var statCardVariants = cva({
|
|
43
|
+
base: "rounded-lg border p-4 text-center shadow-sm",
|
|
44
|
+
variants: {
|
|
45
|
+
color: {
|
|
46
|
+
default: "bg-card text-card-foreground",
|
|
47
|
+
primary: "bg-primary/10 text-primary border-primary/20",
|
|
48
|
+
success: "bg-success/10 text-success border-success/20",
|
|
49
|
+
warning: "bg-warning/10 text-warning border-warning/20",
|
|
50
|
+
destructive: "bg-destructive/10 text-destructive border-destructive/20"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
defaultVariants: {
|
|
54
|
+
color: "default"
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
var badgeGridVariants = cva({
|
|
58
|
+
base: "grid gap-4",
|
|
59
|
+
variants: {
|
|
60
|
+
columns: {
|
|
61
|
+
"3": "grid-cols-3",
|
|
62
|
+
"4": "grid-cols-4",
|
|
63
|
+
"5": "grid-cols-5"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
defaultVariants: {
|
|
67
|
+
columns: "4"
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
var badgeItemVariants = cva({
|
|
71
|
+
base: "flex flex-col items-center gap-2 rounded-lg border p-4 text-center transition-opacity",
|
|
72
|
+
variants: {
|
|
73
|
+
state: {
|
|
74
|
+
unlocked: "opacity-100 bg-card",
|
|
75
|
+
locked: "opacity-50 bg-muted grayscale"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
defaultVariants: {
|
|
79
|
+
state: "locked"
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
var progressBarVariants = cva({
|
|
83
|
+
base: "h-2 w-full overflow-hidden rounded-full bg-secondary",
|
|
84
|
+
variants: {
|
|
85
|
+
size: {
|
|
86
|
+
sm: "h-1",
|
|
87
|
+
md: "h-2",
|
|
88
|
+
lg: "h-3"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
defaultVariants: {
|
|
92
|
+
size: "md"
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ../react-progress-display/dist/index.js
|
|
97
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
98
|
+
var StatsGrid = React.forwardRef(
|
|
99
|
+
function StatsGrid2({ stats, badges = [], className, ...props }, ref) {
|
|
100
|
+
const api = createProgressDisplay({ stats, badges });
|
|
101
|
+
return /* @__PURE__ */ jsx(
|
|
102
|
+
"div",
|
|
103
|
+
{
|
|
104
|
+
ref,
|
|
105
|
+
className: cn(statsGridVariants(), className),
|
|
106
|
+
...api.ariaProps,
|
|
107
|
+
...props,
|
|
108
|
+
children: api.stats.map((stat) => /* @__PURE__ */ jsxs(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
className: statCardVariants({
|
|
112
|
+
color: stat.color ?? "default"
|
|
113
|
+
}),
|
|
114
|
+
children: [
|
|
115
|
+
stat.icon && /* @__PURE__ */ jsx("span", { className: "text-2xl", children: stat.icon }),
|
|
116
|
+
/* @__PURE__ */ jsx("div", { className: "text-2xl font-bold", children: stat.value }),
|
|
117
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: stat.label })
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
stat.label
|
|
121
|
+
))
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
var ProgressBar = React.forwardRef(
|
|
127
|
+
function ProgressBar2({ value, max = 100, size, className, ...props }, ref) {
|
|
128
|
+
const percent = Math.min(100, Math.max(0, value / max * 100));
|
|
129
|
+
return /* @__PURE__ */ jsx(
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
ref,
|
|
133
|
+
className: cn(progressBarVariants({ size }), className),
|
|
134
|
+
role: "progressbar",
|
|
135
|
+
"aria-valuenow": value,
|
|
136
|
+
"aria-valuemin": 0,
|
|
137
|
+
"aria-valuemax": max,
|
|
138
|
+
...props,
|
|
139
|
+
children: /* @__PURE__ */ jsx(
|
|
140
|
+
"div",
|
|
141
|
+
{
|
|
142
|
+
className: "h-full rounded-full bg-primary transition-all",
|
|
143
|
+
style: { width: `${percent}%` }
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
var BadgeDisplay = React.forwardRef(
|
|
151
|
+
function BadgeDisplay2({ badges, className, ...props }, ref) {
|
|
152
|
+
const api = createProgressDisplay({ stats: [], badges });
|
|
153
|
+
return /* @__PURE__ */ jsx(
|
|
154
|
+
"div",
|
|
155
|
+
{
|
|
156
|
+
ref,
|
|
157
|
+
className: cn(badgeGridVariants(), className),
|
|
158
|
+
...props,
|
|
159
|
+
children: api.badges.map((badge) => /* @__PURE__ */ jsxs(
|
|
160
|
+
"div",
|
|
161
|
+
{
|
|
162
|
+
className: badgeItemVariants({
|
|
163
|
+
state: badge.isUnlocked ? "unlocked" : "locked"
|
|
164
|
+
}),
|
|
165
|
+
...api.getBadgeAriaProps(badge),
|
|
166
|
+
children: [
|
|
167
|
+
/* @__PURE__ */ jsx("span", { className: "text-3xl", children: badge.icon }),
|
|
168
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: badge.name }),
|
|
169
|
+
!badge.isUnlocked && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Locked" })
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
badge.name
|
|
173
|
+
))
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
export {
|
|
179
|
+
BadgeDisplay,
|
|
180
|
+
ProgressBar,
|
|
181
|
+
StatsGrid,
|
|
182
|
+
badgeGridVariants,
|
|
183
|
+
badgeItemVariants,
|
|
184
|
+
progressBarVariants,
|
|
185
|
+
statCardVariants,
|
|
186
|
+
statsGridVariants
|
|
187
|
+
};
|
|
188
|
+
//# sourceMappingURL=react-progress-display.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../progress-display/src/progress-display.ts", "../../progress-display/src/progress-display.styles.ts", "../../react-progress-display/src/progress-display.tsx"],
|
|
4
|
+
"sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\n\nexport interface StatCardData {\n label: string\n value: number\n icon?: string\n color?: string\n}\n\nexport interface BadgeData {\n name: string\n description: string\n icon: string\n unlockedAt?: string\n isUnlocked: boolean\n}\n\nexport interface ProgressDisplayProps {\n stats: StatCardData[]\n badges: BadgeData[]\n level?: number\n accuracy?: number\n}\n\nexport interface ProgressDisplayAPI {\n /** The computed stats array */\n stats: StatCardData[]\n /** The badges array */\n badges: BadgeData[]\n /** ARIA props for the stats region */\n ariaProps: Partial<AccessibilityProps>\n /** Get ARIA props for a specific badge */\n getBadgeAriaProps: (badge: BadgeData) => Partial<AccessibilityProps>\n}\n\nexport function createProgressDisplay(props: ProgressDisplayProps): ProgressDisplayAPI {\n const { stats, badges } = props\n\n const ariaProps: Partial<AccessibilityProps> = {\n role: 'region',\n 'aria-label': 'Progress statistics',\n }\n\n function getBadgeAriaProps(badge: BadgeData): Partial<AccessibilityProps> {\n const label = badge.isUnlocked\n ? `${badge.name}: ${badge.description}`\n : `${badge.name}: ${badge.description} (locked)`\n\n return {\n 'aria-label': label,\n }\n }\n\n return {\n stats,\n badges,\n ariaProps,\n getBadgeAriaProps,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const statsGridVariants = cva({\n base: 'grid gap-4',\n variants: {\n columns: {\n '2': 'grid-cols-2',\n '3': 'grid-cols-3',\n '4': 'grid-cols-4',\n },\n },\n defaultVariants: {\n columns: '3',\n },\n})\n\nexport const statCardVariants = cva({\n base: 'rounded-lg border p-4 text-center shadow-sm',\n variants: {\n color: {\n default: 'bg-card text-card-foreground',\n primary: 'bg-primary/10 text-primary border-primary/20',\n success: 'bg-success/10 text-success border-success/20',\n warning: 'bg-warning/10 text-warning border-warning/20',\n destructive: 'bg-destructive/10 text-destructive border-destructive/20',\n },\n },\n defaultVariants: {\n color: 'default',\n },\n})\n\nexport const badgeGridVariants = cva({\n base: 'grid gap-4',\n variants: {\n columns: {\n '3': 'grid-cols-3',\n '4': 'grid-cols-4',\n '5': 'grid-cols-5',\n },\n },\n defaultVariants: {\n columns: '4',\n },\n})\n\nexport const badgeItemVariants = cva({\n base: 'flex flex-col items-center gap-2 rounded-lg border p-4 text-center transition-opacity',\n variants: {\n state: {\n unlocked: 'opacity-100 bg-card',\n locked: 'opacity-50 bg-muted grayscale',\n },\n },\n defaultVariants: {\n state: 'locked',\n },\n})\n\nexport const progressBarVariants = cva({\n base: 'h-2 w-full overflow-hidden rounded-full bg-secondary',\n variants: {\n size: {\n sm: 'h-1',\n md: 'h-2',\n lg: 'h-3',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n", "import * as React from 'react'\nimport {\n createProgressDisplay,\n statsGridVariants,\n statCardVariants,\n badgeGridVariants,\n badgeItemVariants,\n progressBarVariants,\n type StatCardData,\n type BadgeData,\n} from '@refraction-ui/progress-display'\nimport { cn } from '@refraction-ui/shared'\n\n/* ------------------------------------------------------------------ */\n/* StatsGrid */\n/* ------------------------------------------------------------------ */\n\nexport interface StatsGridProps extends React.HTMLAttributes<HTMLDivElement> {\n stats: StatCardData[]\n badges?: BadgeData[]\n}\n\nexport const StatsGrid = React.forwardRef<HTMLDivElement, StatsGridProps>(\n function StatsGrid({ stats, badges = [], className, ...props }, ref) {\n const api = createProgressDisplay({ stats, badges })\n\n return (\n <div\n ref={ref}\n className={cn(statsGridVariants(), className)}\n {...api.ariaProps}\n {...props}\n >\n {api.stats.map((stat) => (\n <div\n key={stat.label}\n className={statCardVariants({\n color: (stat.color as 'default' | 'primary' | 'success' | 'warning' | 'destructive') ?? 'default',\n })}\n >\n {stat.icon && <span className=\"text-2xl\">{stat.icon}</span>}\n <div className=\"text-2xl font-bold\">{stat.value}</div>\n <div className=\"text-sm text-muted-foreground\">{stat.label}</div>\n </div>\n ))}\n </div>\n )\n },\n)\n\n/* ------------------------------------------------------------------ */\n/* ProgressBar */\n/* ------------------------------------------------------------------ */\n\nexport interface ProgressBarProps extends React.HTMLAttributes<HTMLDivElement> {\n value: number\n max?: number\n size?: 'sm' | 'md' | 'lg'\n}\n\nexport const ProgressBar = React.forwardRef<HTMLDivElement, ProgressBarProps>(\n function ProgressBar({ value, max = 100, size, className, ...props }, ref) {\n const percent = Math.min(100, Math.max(0, (value / max) * 100))\n\n return (\n <div\n ref={ref}\n className={cn(progressBarVariants({ size }), className)}\n role=\"progressbar\"\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n {...props}\n >\n <div\n className=\"h-full rounded-full bg-primary transition-all\"\n style={{ width: `${percent}%` }}\n />\n </div>\n )\n },\n)\n\n/* ------------------------------------------------------------------ */\n/* BadgeDisplay */\n/* ------------------------------------------------------------------ */\n\nexport interface BadgeDisplayProps extends React.HTMLAttributes<HTMLDivElement> {\n badges: BadgeData[]\n}\n\nexport const BadgeDisplay = React.forwardRef<HTMLDivElement, BadgeDisplayProps>(\n function BadgeDisplay({ badges, className, ...props }, ref) {\n const api = createProgressDisplay({ stats: [], badges })\n\n return (\n <div\n ref={ref}\n className={cn(badgeGridVariants(), className)}\n {...props}\n >\n {api.badges.map((badge) => (\n <div\n key={badge.name}\n className={badgeItemVariants({\n state: badge.isUnlocked ? 'unlocked' : 'locked',\n })}\n {...api.getBadgeAriaProps(badge)}\n >\n <span className=\"text-3xl\">{badge.icon}</span>\n <span className=\"font-medium\">{badge.name}</span>\n {!badge.isUnlocked && (\n <span className=\"text-xs text-muted-foreground\">Locked</span>\n )}\n </div>\n ))}\n </div>\n )\n },\n)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["StatsGrid", "ProgressBar", "BadgeDisplay"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn,
|
|
3
|
+
cva
|
|
4
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
5
|
+
|
|
6
|
+
// ../react-radial-gauge/dist/index.js
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
|
|
9
|
+
// ../radial-gauge/dist/index.js
|
|
10
|
+
var GAUGE_SIZE_PX = {
|
|
11
|
+
sm: 80,
|
|
12
|
+
md: 120,
|
|
13
|
+
lg: 160
|
|
14
|
+
};
|
|
15
|
+
function clampValue(value, min, max) {
|
|
16
|
+
return Math.min(Math.max(value, min), max);
|
|
17
|
+
}
|
|
18
|
+
function valueToFraction(value, min, max) {
|
|
19
|
+
if (max === min) return 0;
|
|
20
|
+
return clampValue((value - min) / (max - min), 0, 1);
|
|
21
|
+
}
|
|
22
|
+
function gaugeStrokeDashoffset(fraction, circumference) {
|
|
23
|
+
return circumference * (1 - fraction);
|
|
24
|
+
}
|
|
25
|
+
function resolveZoneTone(value, zones, _max) {
|
|
26
|
+
if (!zones || zones.length === 0) return "default";
|
|
27
|
+
const sorted = [...zones].sort((a, b) => a.upTo - b.upTo);
|
|
28
|
+
for (const zone of sorted) {
|
|
29
|
+
if (value <= zone.upTo) return zone.tone;
|
|
30
|
+
}
|
|
31
|
+
return sorted[sorted.length - 1].tone;
|
|
32
|
+
}
|
|
33
|
+
function createRadialGauge(props) {
|
|
34
|
+
const { value, min = 0, max = 100, size = "md" } = props;
|
|
35
|
+
const clamped = clampValue(value, min, max);
|
|
36
|
+
const ariaProps = {
|
|
37
|
+
role: "meter",
|
|
38
|
+
"aria-valuenow": clamped,
|
|
39
|
+
"aria-valuemin": min,
|
|
40
|
+
"aria-valuemax": max
|
|
41
|
+
};
|
|
42
|
+
const dataAttributes = {
|
|
43
|
+
"data-size": size,
|
|
44
|
+
"data-value": String(clamped)
|
|
45
|
+
};
|
|
46
|
+
return { ariaProps, dataAttributes };
|
|
47
|
+
}
|
|
48
|
+
var radialGaugeRootVariants = cva({
|
|
49
|
+
base: "inline-block shrink-0",
|
|
50
|
+
variants: {
|
|
51
|
+
size: {
|
|
52
|
+
sm: "",
|
|
53
|
+
md: "",
|
|
54
|
+
lg: ""
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
defaultVariants: {
|
|
58
|
+
size: "md"
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
var gaugeTrackClass = "fill-none stroke-muted-foreground/20";
|
|
62
|
+
var gaugeArcClass = "fill-none stroke-current transition-[stroke-dashoffset] duration-300 ease-out";
|
|
63
|
+
var gaugeArcToneVariants = cva({
|
|
64
|
+
base: "",
|
|
65
|
+
variants: {
|
|
66
|
+
tone: {
|
|
67
|
+
default: "text-foreground",
|
|
68
|
+
success: "text-emerald-500",
|
|
69
|
+
warning: "text-amber-500",
|
|
70
|
+
danger: "text-destructive"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
defaultVariants: {
|
|
74
|
+
tone: "default"
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
var gaugeLabelClass = "fill-foreground text-center font-semibold";
|
|
78
|
+
var gaugeSublabelClass = "fill-muted-foreground";
|
|
79
|
+
var GAUGE_LABEL_FONT_SIZE = {
|
|
80
|
+
sm: 14,
|
|
81
|
+
md: 20,
|
|
82
|
+
lg: 26
|
|
83
|
+
};
|
|
84
|
+
var GAUGE_SUBLABEL_FONT_SIZE = {
|
|
85
|
+
sm: 9,
|
|
86
|
+
md: 11,
|
|
87
|
+
lg: 13
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// ../react-radial-gauge/dist/index.js
|
|
91
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
92
|
+
var RadialGauge = React.forwardRef(
|
|
93
|
+
function RadialGauge2({
|
|
94
|
+
value,
|
|
95
|
+
min = 0,
|
|
96
|
+
max = 100,
|
|
97
|
+
size = "md",
|
|
98
|
+
thickness = 8,
|
|
99
|
+
label,
|
|
100
|
+
sublabel,
|
|
101
|
+
zones,
|
|
102
|
+
showValue = true,
|
|
103
|
+
className,
|
|
104
|
+
...props
|
|
105
|
+
}, ref) {
|
|
106
|
+
const diameter = GAUGE_SIZE_PX[size];
|
|
107
|
+
const cx = diameter / 2;
|
|
108
|
+
const cy = diameter / 2;
|
|
109
|
+
const r = cx - thickness / 2;
|
|
110
|
+
const clamped = clampValue(value, min, max);
|
|
111
|
+
const fraction = valueToFraction(clamped, min, max);
|
|
112
|
+
const circumference = 2 * Math.PI * r;
|
|
113
|
+
const dashoffset = gaugeStrokeDashoffset(fraction, circumference);
|
|
114
|
+
const tone = zones && zones.length > 0 ? resolveZoneTone(clamped, zones, max) : "default";
|
|
115
|
+
const api = createRadialGauge({ value, min, max, size });
|
|
116
|
+
const centerLabel = label ?? (showValue ? String(clamped) : null);
|
|
117
|
+
const labelFontSize = GAUGE_LABEL_FONT_SIZE[size];
|
|
118
|
+
const sublabelFontSize = GAUGE_SUBLABEL_FONT_SIZE[size];
|
|
119
|
+
const labelDy = sublabel ? -sublabelFontSize * 0.8 : 0;
|
|
120
|
+
return /* @__PURE__ */ jsxs(
|
|
121
|
+
"svg",
|
|
122
|
+
{
|
|
123
|
+
ref,
|
|
124
|
+
width: diameter,
|
|
125
|
+
height: diameter,
|
|
126
|
+
viewBox: `0 0 ${diameter} ${diameter}`,
|
|
127
|
+
role: "meter",
|
|
128
|
+
"aria-valuenow": Number(api.ariaProps["aria-valuenow"]),
|
|
129
|
+
"aria-valuemin": Number(api.ariaProps["aria-valuemin"]),
|
|
130
|
+
"aria-valuemax": Number(api.ariaProps["aria-valuemax"]),
|
|
131
|
+
className: cn(radialGaugeRootVariants({ size }), className),
|
|
132
|
+
...api.dataAttributes,
|
|
133
|
+
...props,
|
|
134
|
+
children: [
|
|
135
|
+
/* @__PURE__ */ jsx(
|
|
136
|
+
"circle",
|
|
137
|
+
{
|
|
138
|
+
cx,
|
|
139
|
+
cy,
|
|
140
|
+
r,
|
|
141
|
+
strokeWidth: thickness,
|
|
142
|
+
className: gaugeTrackClass
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
"circle",
|
|
147
|
+
{
|
|
148
|
+
cx,
|
|
149
|
+
cy,
|
|
150
|
+
r,
|
|
151
|
+
strokeWidth: thickness,
|
|
152
|
+
strokeDasharray: `${circumference} ${circumference}`,
|
|
153
|
+
strokeDashoffset: dashoffset,
|
|
154
|
+
strokeLinecap: "round",
|
|
155
|
+
transform: `rotate(-90 ${cx} ${cy})`,
|
|
156
|
+
className: cn(gaugeArcClass, gaugeArcToneVariants({ tone }))
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
centerLabel != null && /* @__PURE__ */ jsx(
|
|
160
|
+
"text",
|
|
161
|
+
{
|
|
162
|
+
x: cx,
|
|
163
|
+
y: cy,
|
|
164
|
+
textAnchor: "middle",
|
|
165
|
+
dominantBaseline: "central",
|
|
166
|
+
fontSize: labelFontSize,
|
|
167
|
+
dy: labelDy,
|
|
168
|
+
className: gaugeLabelClass,
|
|
169
|
+
children: centerLabel
|
|
170
|
+
}
|
|
171
|
+
),
|
|
172
|
+
sublabel != null && /* @__PURE__ */ jsx(
|
|
173
|
+
"text",
|
|
174
|
+
{
|
|
175
|
+
x: cx,
|
|
176
|
+
y: cy,
|
|
177
|
+
textAnchor: "middle",
|
|
178
|
+
dominantBaseline: "central",
|
|
179
|
+
fontSize: sublabelFontSize,
|
|
180
|
+
dy: labelDy + labelFontSize * 1.1,
|
|
181
|
+
className: gaugeSublabelClass,
|
|
182
|
+
children: sublabel
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
export {
|
|
191
|
+
RadialGauge
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=react-radial-gauge.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../radial-gauge/src/radial-gauge.ts", "../../radial-gauge/src/radial-gauge.styles.ts", "../../react-radial-gauge/src/radial-gauge.tsx"],
|
|
4
|
+
"sourcesContent": ["\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** The visual size of the gauge. */\nexport type GaugeSize = 'sm' | 'md' | 'lg'\n\n/** Tone mapped to a zone range. */\nexport type GaugeTone = 'default' | 'success' | 'warning' | 'danger'\n\n/**\n * A threshold zone that applies a semantic tone when the gauge value falls\n * at or below `upTo`. Zones should be listed in ascending `upTo` order; the\n * first zone whose `upTo >= value` wins.\n */\nexport interface GaugeZone {\n /** Value up to (and including) which this zone applies. */\n upTo: number\n /** Semantic tone for the arc while the value is in this zone. */\n tone: GaugeTone\n}\n\nexport interface RadialGaugeProps {\n /** Current gauge value. */\n value: number\n /** Minimum possible value. */\n min?: number\n /** Maximum possible value. */\n max?: number\n /** Visual size. */\n size?: GaugeSize\n}\n\nexport interface RadialGaugeAPI {\n /** ARIA attributes to spread on the SVG element (`role=\"meter\"`). */\n ariaProps: Record<string, string | number>\n /** Data attributes for styling hooks. */\n dataAttributes: Record<string, string>\n}\n\n// ---------------------------------------------------------------------------\n// Pixel diameters for each size variant (exported for use in adapters)\n// ---------------------------------------------------------------------------\nexport const GAUGE_SIZE_PX: Record<GaugeSize, number> = {\n sm: 80,\n md: 120,\n lg: 160,\n}\n\n// ---------------------------------------------------------------------------\n// Pure geometry helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Clamp `value` to the inclusive range `[min, max]`.\n */\nexport function clampValue(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max)\n}\n\n/**\n * Map a `value` within `[min, max]` to a fraction in `[0, 1]`.\n * Returns 0 when `min === max` to avoid division by zero.\n */\nexport function valueToFraction(value: number, min: number, max: number): number {\n if (max === min) return 0\n return clampValue((value - min) / (max - min), 0, 1)\n}\n\n/**\n * Convert polar coordinates to Cartesian.\n * `angleDeg` is measured clockwise from the positive x-axis (SVG convention).\n */\nexport function polarToCartesian(\n cx: number,\n cy: number,\n r: number,\n angleDeg: number,\n): { x: number; y: number } {\n const rad = ((angleDeg - 90) * Math.PI) / 180\n return {\n x: cx + r * Math.cos(rad),\n y: cy + r * Math.sin(rad),\n }\n}\n\n/**\n * Build an SVG arc path `d` string from `startAngleDeg` to `endAngleDeg`\n * (both measured clockwise from the top / 12-o'clock position).\n *\n * Returns an empty string when the arc span is zero.\n */\nexport function describeArc(\n cx: number,\n cy: number,\n r: number,\n startAngleDeg: number,\n endAngleDeg: number,\n): string {\n const span = endAngleDeg - startAngleDeg\n if (span === 0) return ''\n\n // For a full circle we need two arcs to avoid SVG treating start === end as\n // a no-op. Shift the end by 0.001° so the path stays valid.\n const clampedEnd = span >= 360 ? startAngleDeg + 359.999 : endAngleDeg\n\n const start = polarToCartesian(cx, cy, r, startAngleDeg)\n const end = polarToCartesian(cx, cy, r, clampedEnd)\n const largeArc = clampedEnd - startAngleDeg > 180 ? 1 : 0\n\n return [\n `M ${start.x} ${start.y}`,\n `A ${r} ${r} 0 ${largeArc} 1 ${end.x} ${end.y}`,\n ].join(' ')\n}\n\n/**\n * Compute the `stroke-dashoffset` for a full-circle ring gauge.\n *\n * With `stroke-dasharray=\"circumference circumference\"` and this offset, the\n * visible portion of the stroke equals `fraction × circumference`.\n */\nexport function gaugeStrokeDashoffset(fraction: number, circumference: number): number {\n return circumference * (1 - fraction)\n}\n\n// ---------------------------------------------------------------------------\n// Zone resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Find the active zone tone for the current `value`.\n * Zones are tested in ascending `upTo` order; the first zone whose\n * `upTo >= value` wins. Falls back to `'default'` when no zone matches.\n */\nexport function resolveZoneTone(\n value: number,\n zones: GaugeZone[],\n _max: number,\n): GaugeTone {\n if (!zones || zones.length === 0) return 'default'\n\n // Sort a copy ascending by upTo so callers don't have to pre-sort.\n const sorted = [...zones].sort((a, b) => a.upTo - b.upTo)\n\n for (const zone of sorted) {\n if (value <= zone.upTo) return zone.tone\n }\n\n // Value is above all zone thresholds — use the last zone's tone.\n return sorted[sorted.length - 1].tone\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Build the framework-agnostic props for a radial gauge element.\n *\n * Returns `role=\"meter\"` plus ARIA value attributes and data attributes;\n * adapters spread these onto their `<svg>` element.\n */\nexport function createRadialGauge(props: RadialGaugeProps): RadialGaugeAPI {\n const { value, min = 0, max = 100, size = 'md' } = props\n\n const clamped = clampValue(value, min, max)\n\n const ariaProps: Record<string, string | number> = {\n role: 'meter',\n 'aria-valuenow': clamped,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n }\n\n const dataAttributes: Record<string, string> = {\n 'data-size': size,\n 'data-value': String(clamped),\n }\n\n return { ariaProps, dataAttributes }\n}\n", "import { cva } from '@refraction-ui/shared'\n\n/**\n * Root SVG element variants — controls the rendered size via an inline\n * width/height (adapters use GAUGE_SIZE_PX) and sets up the color context.\n */\nexport const radialGaugeRootVariants = cva({\n base: 'inline-block shrink-0',\n variants: {\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n})\n\n/**\n * Track (background) circle stroke class.\n * Uses a muted foreground so it sits behind the value arc without competing.\n */\nexport const gaugeTrackClass = 'fill-none stroke-muted-foreground/20'\n\n/**\n * Value arc stroke class — resolved per tone via {@link gaugeArcToneVariants}.\n * `currentColor` stroke picks up the Tailwind text-* class applied by the\n * tone variant so we only need one class-generating helper.\n */\nexport const gaugeArcClass = 'fill-none stroke-current transition-[stroke-dashoffset] duration-300 ease-out'\n\n/**\n * Tone variants for the value arc. Adapters combine this with `gaugeArcClass`.\n */\nexport const gaugeArcToneVariants = cva({\n base: '',\n variants: {\n tone: {\n default: 'text-foreground',\n success: 'text-emerald-500',\n warning: 'text-amber-500',\n danger: 'text-destructive',\n },\n },\n defaultVariants: {\n tone: 'default',\n },\n})\n\n/** Center label (primary text) classes. */\nexport const gaugeLabelClass = 'fill-foreground text-center font-semibold'\n\n/** Center sub-label (secondary text) classes. */\nexport const gaugeSublabelClass = 'fill-muted-foreground'\n\n/**\n * Font size for the primary label by size variant.\n * Expressed as SVG `font-size` values (px) for use in the `<text>` element.\n */\nexport const GAUGE_LABEL_FONT_SIZE: Record<'sm' | 'md' | 'lg', number> = {\n sm: 14,\n md: 20,\n lg: 26,\n}\n\n/**\n * Font size for the sub-label by size variant.\n */\nexport const GAUGE_SUBLABEL_FONT_SIZE: Record<'sm' | 'md' | 'lg', number> = {\n sm: 9,\n md: 11,\n lg: 13,\n}\n", "import * as React from 'react'\nimport {\n clampValue,\n valueToFraction,\n gaugeStrokeDashoffset,\n resolveZoneTone,\n createRadialGauge,\n radialGaugeRootVariants,\n gaugeTrackClass,\n gaugeArcClass,\n gaugeArcToneVariants,\n gaugeLabelClass,\n gaugeSublabelClass,\n GAUGE_SIZE_PX,\n GAUGE_LABEL_FONT_SIZE,\n GAUGE_SUBLABEL_FONT_SIZE,\n type GaugeSize,\n type GaugeTone,\n type GaugeZone,\n} from '@refraction-ui/radial-gauge'\nimport { cn } from '@refraction-ui/shared'\n\nexport type { GaugeSize, GaugeTone, GaugeZone }\n\nexport interface RadialGaugeProps extends React.SVGAttributes<SVGSVGElement> {\n /** Current value. */\n value: number\n /** Minimum value. Defaults to 0. */\n min?: number\n /** Maximum value. Defaults to 100. */\n max?: number\n /** Visual size of the gauge. Defaults to 'md'. */\n size?: GaugeSize\n /** Stroke thickness in px. Defaults to 8. */\n thickness?: number\n /** Primary center label. When omitted and `showValue` is true, the numeric value is shown. */\n label?: React.ReactNode\n /** Secondary label shown below the primary label. */\n sublabel?: React.ReactNode\n /**\n * Threshold zones that colour the arc based on the current value.\n * List in ascending `upTo` order for clarity (internally sorted).\n */\n zones?: GaugeZone[]\n /** Show the numeric value in the center when no explicit label is given. Defaults to true. */\n showValue?: boolean\n /** Accessible name for the gauge. */\n 'aria-label'?: string\n}\n\n/**\n * RadialGauge — a circular progress / gauge component.\n *\n * Renders an SVG with a background track ring and a value arc whose length is\n * proportional to the current value fraction. Center text shows the value or a\n * custom label. Supports semantic zone colouring (success / warning / danger)\n * so the arc hue communicates health at a glance — ideal for score cards,\n * interview report rings, and dashboard KPIs.\n *\n * Accessibility: `role=\"meter\"` with `aria-valuenow/min/max` on the SVG.\n */\nexport const RadialGauge = React.forwardRef<SVGSVGElement, RadialGaugeProps>(\n function RadialGauge(\n {\n value,\n min = 0,\n max = 100,\n size = 'md',\n thickness = 8,\n label,\n sublabel,\n zones,\n showValue = true,\n className,\n ...props\n },\n ref,\n ) {\n const diameter = GAUGE_SIZE_PX[size]\n const cx = diameter / 2\n const cy = diameter / 2\n // Radius inset by half the stroke width so it stays within the viewBox.\n const r = cx - thickness / 2\n\n const clamped = clampValue(value, min, max)\n const fraction = valueToFraction(clamped, min, max)\n\n const circumference = 2 * Math.PI * r\n const dashoffset = gaugeStrokeDashoffset(fraction, circumference)\n\n const tone = zones && zones.length > 0 ? resolveZoneTone(clamped, zones, max) : 'default'\n\n const api = createRadialGauge({ value, min, max, size })\n\n // Primary center content: explicit label wins; else show numeric value if requested.\n const centerLabel = label ?? (showValue ? String(clamped) : null)\n const labelFontSize = GAUGE_LABEL_FONT_SIZE[size]\n const sublabelFontSize = GAUGE_SUBLABEL_FONT_SIZE[size]\n\n // Vertical offset for the label. When a sublabel is present, nudge up slightly.\n const labelDy = sublabel ? -sublabelFontSize * 0.8 : 0\n\n return (\n <svg\n ref={ref}\n width={diameter}\n height={diameter}\n viewBox={`0 0 ${diameter} ${diameter}`}\n role=\"meter\"\n aria-valuenow={Number(api.ariaProps['aria-valuenow'])}\n aria-valuemin={Number(api.ariaProps['aria-valuemin'])}\n aria-valuemax={Number(api.ariaProps['aria-valuemax'])}\n className={cn(radialGaugeRootVariants({ size }), className)}\n {...api.dataAttributes}\n {...props}\n >\n {/* Background track */}\n <circle\n cx={cx}\n cy={cy}\n r={r}\n strokeWidth={thickness}\n className={gaugeTrackClass}\n />\n\n {/* Value arc — ring style: rotate -90° to start at 12-o'clock */}\n <circle\n cx={cx}\n cy={cy}\n r={r}\n strokeWidth={thickness}\n strokeDasharray={`${circumference} ${circumference}`}\n strokeDashoffset={dashoffset}\n strokeLinecap=\"round\"\n transform={`rotate(-90 ${cx} ${cy})`}\n className={cn(gaugeArcClass, gaugeArcToneVariants({ tone }))}\n />\n\n {/* Center label */}\n {centerLabel != null && (\n <text\n x={cx}\n y={cy}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fontSize={labelFontSize}\n dy={labelDy}\n className={gaugeLabelClass}\n >\n {centerLabel}\n </text>\n )}\n\n {/* Sub-label */}\n {sublabel != null && (\n <text\n x={cx}\n y={cy}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n fontSize={sublabelFontSize}\n dy={labelDy + labelFontSize * 1.1}\n className={gaugeSublabelClass}\n >\n {sublabel}\n </text>\n )}\n </svg>\n )\n },\n)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RadialGauge"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn,
|
|
3
|
+
cva,
|
|
4
|
+
devWarn
|
|
5
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
6
|
+
|
|
7
|
+
// ../react-radio/dist/index.js
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
|
|
10
|
+
// ../radio/dist/index.js
|
|
11
|
+
function createRadioGroup(props = {}) {
|
|
12
|
+
const { value: controlled, defaultValue, onValueChange, name, disabled = false, orientation = "vertical" } = props;
|
|
13
|
+
let selected = controlled ?? defaultValue;
|
|
14
|
+
function select(value) {
|
|
15
|
+
if (disabled) return;
|
|
16
|
+
selected = value;
|
|
17
|
+
onValueChange?.(value);
|
|
18
|
+
}
|
|
19
|
+
const groupProps = {
|
|
20
|
+
role: "radiogroup",
|
|
21
|
+
"aria-orientation": orientation,
|
|
22
|
+
...disabled ? { "aria-disabled": true } : {}
|
|
23
|
+
};
|
|
24
|
+
function getItemProps(value, itemDisabled) {
|
|
25
|
+
const isSelected = selected === value;
|
|
26
|
+
const isDisabled = disabled || itemDisabled;
|
|
27
|
+
return {
|
|
28
|
+
role: "radio",
|
|
29
|
+
"aria-checked": isSelected,
|
|
30
|
+
"aria-disabled": isDisabled || void 0,
|
|
31
|
+
tabIndex: isSelected ? 0 : -1,
|
|
32
|
+
"data-state": isSelected ? "checked" : "unchecked",
|
|
33
|
+
...isDisabled ? { "data-disabled": "" } : {},
|
|
34
|
+
...name ? { name } : {}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const keyboardHandlers = {
|
|
38
|
+
ArrowDown(e) {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
},
|
|
41
|
+
ArrowUp(e) {
|
|
42
|
+
e.preventDefault();
|
|
43
|
+
},
|
|
44
|
+
ArrowRight(e) {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
},
|
|
47
|
+
ArrowLeft(e) {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
state: { get selectedValue() {
|
|
53
|
+
return selected;
|
|
54
|
+
} },
|
|
55
|
+
groupProps,
|
|
56
|
+
getItemProps,
|
|
57
|
+
select,
|
|
58
|
+
keyboardHandlers
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
var radioGroupVariants = cva({
|
|
62
|
+
base: "flex gap-3",
|
|
63
|
+
variants: {
|
|
64
|
+
orientation: {
|
|
65
|
+
vertical: "flex-col",
|
|
66
|
+
horizontal: "flex-row"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
defaultVariants: { orientation: "vertical" }
|
|
70
|
+
});
|
|
71
|
+
var radioItemVariants = cva({
|
|
72
|
+
base: "flex items-center gap-2 cursor-pointer",
|
|
73
|
+
variants: {
|
|
74
|
+
disabled: {
|
|
75
|
+
true: "opacity-50 cursor-not-allowed",
|
|
76
|
+
false: ""
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
defaultVariants: { disabled: "false" }
|
|
80
|
+
});
|
|
81
|
+
var radioCircleVariants = cva({
|
|
82
|
+
base: "h-4 w-4 rounded-full border border-primary transition-colors",
|
|
83
|
+
variants: {
|
|
84
|
+
checked: {
|
|
85
|
+
true: "border-primary bg-primary",
|
|
86
|
+
false: "border-input"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
defaultVariants: { checked: "false" }
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// ../react-radio/dist/index.js
|
|
93
|
+
var RadioContext = React.createContext(null);
|
|
94
|
+
var RadioGroup = React.forwardRef(
|
|
95
|
+
function RadioGroup2({ children, className, value: controlledValue, defaultValue, onValueChange, name, disabled = false, orientation = "vertical" }, ref) {
|
|
96
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
97
|
+
const isControlled = controlledValue !== void 0;
|
|
98
|
+
const currentValue = isControlled ? controlledValue : internalValue;
|
|
99
|
+
const api = createRadioGroup({ value: currentValue, name, disabled, orientation });
|
|
100
|
+
const handleChange = React.useCallback(
|
|
101
|
+
(val) => {
|
|
102
|
+
if (!isControlled) setInternalValue(val);
|
|
103
|
+
onValueChange?.(val);
|
|
104
|
+
},
|
|
105
|
+
[isControlled, onValueChange]
|
|
106
|
+
);
|
|
107
|
+
const ctx = React.useMemo(
|
|
108
|
+
() => ({ value: currentValue, onValueChange: handleChange, name, disabled }),
|
|
109
|
+
[currentValue, handleChange, name, disabled]
|
|
110
|
+
);
|
|
111
|
+
return React.createElement(
|
|
112
|
+
RadioContext.Provider,
|
|
113
|
+
{ value: ctx },
|
|
114
|
+
React.createElement(
|
|
115
|
+
"div",
|
|
116
|
+
{ ref, ...api.groupProps, className: cn(radioGroupVariants({ orientation }), className) },
|
|
117
|
+
children
|
|
118
|
+
)
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
var RadioItem = React.forwardRef(
|
|
123
|
+
function RadioItem2({ value, children, disabled = false, className }, ref) {
|
|
124
|
+
const ctx = React.useContext(RadioContext);
|
|
125
|
+
if (!ctx) {
|
|
126
|
+
devWarn(
|
|
127
|
+
"react-radio/radio-item-outside-group",
|
|
128
|
+
"RadioItem was rendered outside of <RadioGroup>. Wrap it in <RadioGroup>."
|
|
129
|
+
);
|
|
130
|
+
throw new Error("RadioItem must be used within RadioGroup");
|
|
131
|
+
}
|
|
132
|
+
const isChecked = ctx.value === value;
|
|
133
|
+
const isDisabled = ctx.disabled || disabled;
|
|
134
|
+
return React.createElement(
|
|
135
|
+
"label",
|
|
136
|
+
{
|
|
137
|
+
ref,
|
|
138
|
+
className: cn(radioItemVariants({ disabled: isDisabled ? "true" : "false" }), className),
|
|
139
|
+
"data-state": isChecked ? "checked" : "unchecked"
|
|
140
|
+
},
|
|
141
|
+
React.createElement(
|
|
142
|
+
"button",
|
|
143
|
+
{
|
|
144
|
+
type: "button",
|
|
145
|
+
role: "radio",
|
|
146
|
+
"aria-checked": isChecked,
|
|
147
|
+
"aria-disabled": isDisabled || void 0,
|
|
148
|
+
tabIndex: isChecked ? 0 : -1,
|
|
149
|
+
disabled: isDisabled,
|
|
150
|
+
className: cn(radioCircleVariants({ checked: isChecked ? "true" : "false" })),
|
|
151
|
+
onClick: () => !isDisabled && ctx.onValueChange(value)
|
|
152
|
+
},
|
|
153
|
+
isChecked && React.createElement(
|
|
154
|
+
"span",
|
|
155
|
+
{ className: "block h-2 w-2 rounded-full bg-primary-foreground mx-auto" }
|
|
156
|
+
)
|
|
157
|
+
),
|
|
158
|
+
children && React.createElement("span", { className: "text-sm" }, children)
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
export {
|
|
163
|
+
RadioGroup,
|
|
164
|
+
RadioItem,
|
|
165
|
+
radioCircleVariants,
|
|
166
|
+
radioGroupVariants,
|
|
167
|
+
radioItemVariants
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=react-radio.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../radio/src/radio.ts", "../../radio/src/radio.styles.ts", "../../react-radio/src/radio.tsx"],
|
|
4
|
+
"sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\n\nexport interface RadioOption {\n value: string\n label: string\n disabled?: boolean\n}\n\nexport interface RadioGroupProps {\n value?: string\n defaultValue?: string\n onValueChange?: (value: string) => void\n name?: string\n disabled?: boolean\n orientation?: 'horizontal' | 'vertical'\n}\n\nexport interface RadioGroupAPI {\n state: { selectedValue: string | undefined }\n groupProps: Partial<AccessibilityProps> & Record<string, unknown>\n getItemProps(value: string, disabled?: boolean): Partial<AccessibilityProps> & Record<string, unknown>\n select(value: string): void\n keyboardHandlers: Record<string, (e: KeyboardEvent) => void>\n}\n\nexport function createRadioGroup(props: RadioGroupProps = {}): RadioGroupAPI {\n const { value: controlled, defaultValue, onValueChange, name, disabled = false, orientation = 'vertical' } = props\n let selected = controlled ?? defaultValue\n\n function select(value: string) {\n if (disabled) return\n selected = value\n onValueChange?.(value)\n }\n\n const groupProps = {\n role: 'radiogroup' as const,\n 'aria-orientation': orientation,\n ...(disabled ? { 'aria-disabled': true } : {}),\n }\n\n function getItemProps(value: string, itemDisabled?: boolean) {\n const isSelected = selected === value\n const isDisabled = disabled || itemDisabled\n return {\n role: 'radio' as const,\n 'aria-checked': isSelected,\n 'aria-disabled': isDisabled || undefined,\n tabIndex: isSelected ? 0 : -1,\n 'data-state': isSelected ? 'checked' : 'unchecked',\n ...(isDisabled ? { 'data-disabled': '' } : {}),\n ...(name ? { name } : {}),\n }\n }\n\n const keyboardHandlers: Record<string, (e: KeyboardEvent) => void> = {\n ArrowDown(e) { e.preventDefault() },\n ArrowUp(e) { e.preventDefault() },\n ArrowRight(e) { e.preventDefault() },\n ArrowLeft(e) { e.preventDefault() },\n }\n\n return {\n state: { get selectedValue() { return selected } },\n groupProps,\n getItemProps,\n select,\n keyboardHandlers,\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const radioGroupVariants = cva({\n base: 'flex gap-3',\n variants: {\n orientation: {\n vertical: 'flex-col',\n horizontal: 'flex-row',\n },\n },\n defaultVariants: { orientation: 'vertical' },\n})\n\nexport const radioItemVariants = cva({\n base: 'flex items-center gap-2 cursor-pointer',\n variants: {\n disabled: {\n true: 'opacity-50 cursor-not-allowed',\n false: '',\n },\n },\n defaultVariants: { disabled: 'false' },\n})\n\nexport const radioCircleVariants = cva({\n base: 'h-4 w-4 rounded-full border border-primary transition-colors',\n variants: {\n checked: {\n true: 'border-primary bg-primary',\n false: 'border-input',\n },\n },\n defaultVariants: { checked: 'false' },\n})\n", "import * as React from 'react'\nimport {\n createRadioGroup,\n radioGroupVariants,\n radioItemVariants,\n radioCircleVariants,\n type RadioGroupProps as CoreRadioGroupProps,\n} from '@refraction-ui/radio'\nimport { cn, devWarn } from '@refraction-ui/shared'\n\ninterface RadioContextValue {\n value: string | undefined\n onValueChange: (value: string) => void\n name?: string\n disabled: boolean\n}\n\nconst RadioContext = React.createContext<RadioContextValue | null>(null)\n\nexport interface RadioGroupProps extends CoreRadioGroupProps {\n children: React.ReactNode\n className?: string\n}\n\nexport const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>(\n function RadioGroup({ children, className, value: controlledValue, defaultValue, onValueChange, name, disabled = false, orientation = 'vertical' }: RadioGroupProps, ref) {\n const [internalValue, setInternalValue] = React.useState(defaultValue)\n const isControlled = controlledValue !== undefined\n const currentValue = isControlled ? controlledValue : internalValue\n\n const api = createRadioGroup({ value: currentValue, name, disabled, orientation })\n\n const handleChange = React.useCallback(\n (val: string) => {\n if (!isControlled) setInternalValue(val)\n onValueChange?.(val)\n },\n [isControlled, onValueChange],\n )\n\n const ctx = React.useMemo<RadioContextValue>(\n () => ({ value: currentValue, onValueChange: handleChange, name, disabled }),\n [currentValue, handleChange, name, disabled],\n )\n\n return React.createElement(\n RadioContext.Provider,\n { value: ctx },\n React.createElement(\n 'div',\n { ref, ...api.groupProps, className: cn(radioGroupVariants({ orientation }), className) },\n children,\n ),\n )\n },\n)\n\nexport interface RadioItemProps {\n value: string\n children?: React.ReactNode\n disabled?: boolean\n className?: string\n}\n\nexport const RadioItem = React.forwardRef<HTMLLabelElement, RadioItemProps>(\n function RadioItem({ value, children, disabled = false, className }, ref) {\n const ctx = React.useContext(RadioContext)\n if (!ctx) {\n devWarn(\n 'react-radio/radio-item-outside-group',\n 'RadioItem was rendered outside of <RadioGroup>. Wrap it in <RadioGroup>.',\n )\n throw new Error('RadioItem must be used within RadioGroup')\n }\n\n const isChecked = ctx.value === value\n const isDisabled = ctx.disabled || disabled\n\n return React.createElement(\n 'label',\n {\n ref,\n className: cn(radioItemVariants({ disabled: isDisabled ? 'true' : 'false' }), className),\n 'data-state': isChecked ? 'checked' : 'unchecked',\n },\n React.createElement(\n 'button',\n {\n type: 'button',\n role: 'radio',\n 'aria-checked': isChecked,\n 'aria-disabled': isDisabled || undefined,\n tabIndex: isChecked ? 0 : -1,\n disabled: isDisabled,\n className: cn(radioCircleVariants({ checked: isChecked ? 'true' : 'false' })),\n onClick: () => !isDisabled && ctx.onValueChange(value),\n },\n isChecked &&\n React.createElement(\n 'span',\n { className: 'block h-2 w-2 rounded-full bg-primary-foreground mx-auto' },\n ),\n ),\n children && React.createElement('span', { className: 'text-sm' }, children),\n )\n },\n)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["RadioGroup", "RadioItem"]
|
|
7
|
+
}
|