@spatika/react 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +71 -0
- package/README.md +4 -3
- package/dist/composites/AccentRule.d.ts +6 -0
- package/dist/composites/AccentRule.d.ts.map +1 -0
- package/dist/composites/AccentRule.js +6 -0
- package/dist/composites/AvailabilityBadge.d.ts +9 -0
- package/dist/composites/AvailabilityBadge.d.ts.map +1 -0
- package/dist/composites/AvailabilityBadge.js +9 -0
- package/dist/composites/Card.d.ts +7 -1
- package/dist/composites/Card.d.ts.map +1 -1
- package/dist/composites/Card.js +10 -0
- package/dist/composites/CareerCard.d.ts +20 -0
- package/dist/composites/CareerCard.d.ts.map +1 -0
- package/dist/composites/CareerCard.js +17 -0
- package/dist/composites/ChartDataGrid.d.ts +33 -0
- package/dist/composites/ChartDataGrid.d.ts.map +1 -0
- package/dist/composites/ChartDataGrid.js +77 -0
- package/dist/composites/ContactLink.d.ts +15 -0
- package/dist/composites/ContactLink.d.ts.map +1 -0
- package/dist/composites/ContactLink.js +8 -0
- package/dist/composites/CoverHero.d.ts +1 -1
- package/dist/composites/CoverHero.d.ts.map +1 -1
- package/dist/composites/CoverHero.js +2 -2
- package/dist/composites/DisplayHeading.d.ts +9 -0
- package/dist/composites/DisplayHeading.d.ts.map +1 -0
- package/dist/composites/DisplayHeading.js +6 -0
- package/dist/composites/EntityMediaCard.d.ts +1 -1
- package/dist/composites/EntityMediaCard.d.ts.map +1 -1
- package/dist/composites/EntityMediaCard.js +12 -4
- package/dist/composites/EventCalendar.d.ts +35 -0
- package/dist/composites/EventCalendar.d.ts.map +1 -0
- package/dist/composites/EventCalendar.js +339 -0
- package/dist/composites/EventEditor.d.ts +22 -0
- package/dist/composites/EventEditor.d.ts.map +1 -0
- package/dist/composites/EventEditor.js +86 -0
- package/dist/composites/EventTimeline.d.ts +24 -0
- package/dist/composites/EventTimeline.d.ts.map +1 -0
- package/dist/composites/EventTimeline.js +184 -0
- package/dist/composites/FloatChip.d.ts +15 -0
- package/dist/composites/FloatChip.d.ts.map +1 -0
- package/dist/composites/FloatChip.js +7 -0
- package/dist/composites/GradientText.d.ts +11 -0
- package/dist/composites/GradientText.d.ts.map +1 -0
- package/dist/composites/GradientText.js +6 -0
- package/dist/composites/IconTile.d.ts +10 -0
- package/dist/composites/IconTile.d.ts.map +1 -0
- package/dist/composites/IconTile.js +7 -0
- package/dist/composites/MapChart.d.ts +24 -0
- package/dist/composites/MapChart.d.ts.map +1 -0
- package/dist/composites/MapChart.js +58 -0
- package/dist/composites/MetaChip.d.ts +9 -0
- package/dist/composites/MetaChip.d.ts.map +1 -0
- package/dist/composites/MetaChip.js +6 -0
- package/dist/composites/PresenceDot.d.ts +10 -0
- package/dist/composites/PresenceDot.d.ts.map +1 -0
- package/dist/composites/PresenceDot.js +10 -0
- package/dist/composites/ProfileHero.d.ts +6 -4
- package/dist/composites/ProfileHero.d.ts.map +1 -1
- package/dist/composites/ProfileHero.js +8 -8
- package/dist/composites/ProjectCard.d.ts +12 -0
- package/dist/composites/ProjectCard.d.ts.map +1 -0
- package/dist/composites/ProjectCard.js +9 -0
- package/dist/composites/ScatterWebGL.d.ts +22 -0
- package/dist/composites/ScatterWebGL.d.ts.map +1 -0
- package/dist/composites/ScatterWebGL.js +45 -0
- package/dist/composites/SectionHeading.d.ts +16 -0
- package/dist/composites/SectionHeading.d.ts.map +1 -0
- package/dist/composites/SectionHeading.js +12 -0
- package/dist/composites/SiteFooter.d.ts +18 -0
- package/dist/composites/SiteFooter.d.ts.map +1 -0
- package/dist/composites/SiteFooter.js +15 -0
- package/dist/composites/SiteNav.d.ts +25 -0
- package/dist/composites/SiteNav.d.ts.map +1 -0
- package/dist/composites/SiteNav.js +44 -0
- package/dist/composites/StatCard.d.ts +7 -1
- package/dist/composites/StatCard.d.ts.map +1 -1
- package/dist/composites/StatCard.js +5 -2
- package/dist/composites/StatusDot.d.ts +1 -1
- package/dist/composites/Tag.d.ts +11 -0
- package/dist/composites/Tag.d.ts.map +1 -0
- package/dist/composites/Tag.js +33 -0
- package/dist/composites/Wordmark.d.ts +19 -0
- package/dist/composites/Wordmark.d.ts.map +1 -0
- package/dist/composites/Wordmark.js +15 -0
- package/dist/composites/cartesian-charts.d.ts +138 -0
- package/dist/composites/cartesian-charts.d.ts.map +1 -0
- package/dist/composites/cartesian-charts.js +401 -0
- package/dist/composites/chart-composition.d.ts +139 -0
- package/dist/composites/chart-composition.d.ts.map +1 -0
- package/dist/composites/chart-composition.js +486 -0
- package/dist/composites/chart-ui.d.ts +83 -0
- package/dist/composites/chart-ui.d.ts.map +1 -0
- package/dist/composites/chart-ui.js +108 -0
- package/dist/composites/charts-3d.d.ts +37 -0
- package/dist/composites/charts-3d.d.ts.map +1 -0
- package/dist/composites/charts-3d.js +121 -0
- package/dist/composites/flow-charts.d.ts +89 -0
- package/dist/composites/flow-charts.d.ts.map +1 -0
- package/dist/composites/flow-charts.js +186 -0
- package/dist/composites/radial-charts.d.ts +109 -0
- package/dist/composites/radial-charts.d.ts.map +1 -0
- package/dist/composites/radial-charts.js +176 -0
- package/dist/composites/scheduler-ui.d.ts +43 -0
- package/dist/composites/scheduler-ui.d.ts.map +1 -0
- package/dist/composites/scheduler-ui.js +71 -0
- package/dist/index.d.ts +83 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -7
- package/dist/lib/chart-export.d.ts +10 -0
- package/dist/lib/chart-export.d.ts.map +1 -0
- package/dist/lib/chart-export.js +102 -0
- package/dist/lib/charts.d.ts +235 -0
- package/dist/lib/charts.d.ts.map +1 -0
- package/dist/lib/charts.js +744 -0
- package/dist/lib/geo.d.ts +39 -0
- package/dist/lib/geo.d.ts.map +1 -0
- package/dist/lib/geo.js +101 -0
- package/dist/lib/iso.d.ts +21 -0
- package/dist/lib/iso.d.ts.map +1 -0
- package/dist/lib/iso.js +56 -0
- package/dist/lib/rrule.d.ts +20 -0
- package/dist/lib/rrule.d.ts.map +1 -0
- package/dist/lib/rrule.js +236 -0
- package/dist/lib/scheduler.d.ts +152 -0
- package/dist/lib/scheduler.d.ts.map +1 -0
- package/dist/lib/scheduler.js +501 -0
- package/dist/lib/webgl-scatter.d.ts +44 -0
- package/dist/lib/webgl-scatter.d.ts.map +1 -0
- package/dist/lib/webgl-scatter.js +185 -0
- package/dist/primitives/Accordion.d.ts +44 -20
- package/dist/primitives/Accordion.d.ts.map +1 -1
- package/dist/primitives/Accordion.js +82 -22
- package/dist/primitives/AppBar.d.ts +13 -0
- package/dist/primitives/AppBar.d.ts.map +1 -0
- package/dist/primitives/AppBar.js +27 -0
- package/dist/primitives/Autocomplete.d.ts +28 -0
- package/dist/primitives/Autocomplete.d.ts.map +1 -0
- package/dist/primitives/Autocomplete.js +118 -0
- package/dist/primitives/Avatar.d.ts +13 -1
- package/dist/primitives/Avatar.d.ts.map +1 -1
- package/dist/primitives/Avatar.js +17 -2
- package/dist/primitives/Backdrop.d.ts +17 -0
- package/dist/primitives/Backdrop.d.ts.map +1 -0
- package/dist/primitives/Backdrop.js +17 -0
- package/dist/primitives/BottomNavigation.d.ts +23 -0
- package/dist/primitives/BottomNavigation.d.ts.map +1 -0
- package/dist/primitives/BottomNavigation.js +30 -0
- package/dist/primitives/Button.d.ts +4 -4
- package/dist/primitives/Button.d.ts.map +1 -1
- package/dist/primitives/Button.js +2 -0
- package/dist/primitives/ButtonBase.d.ts +14 -0
- package/dist/primitives/ButtonBase.d.ts.map +1 -0
- package/dist/primitives/ButtonBase.js +13 -0
- package/dist/primitives/ButtonGroup.d.ts +25 -0
- package/dist/primitives/ButtonGroup.d.ts.map +1 -0
- package/dist/primitives/ButtonGroup.js +44 -0
- package/dist/primitives/CircularProgress.d.ts +16 -0
- package/dist/primitives/CircularProgress.d.ts.map +1 -0
- package/dist/primitives/CircularProgress.js +17 -0
- package/dist/primitives/ClickAwayListener.d.ts +16 -0
- package/dist/primitives/ClickAwayListener.d.ts.map +1 -0
- package/dist/primitives/ClickAwayListener.js +33 -0
- package/dist/primitives/Collapse.d.ts +19 -0
- package/dist/primitives/Collapse.d.ts.map +1 -0
- package/dist/primitives/Collapse.js +14 -0
- package/dist/primitives/Container.d.ts +13 -0
- package/dist/primitives/Container.d.ts.map +1 -0
- package/dist/primitives/Container.js +26 -0
- package/dist/primitives/Fab.d.ts +22 -0
- package/dist/primitives/Fab.d.ts.map +1 -0
- package/dist/primitives/Fab.js +42 -0
- package/dist/primitives/FormControl.d.ts +27 -0
- package/dist/primitives/FormControl.d.ts.map +1 -0
- package/dist/primitives/FormControl.js +24 -0
- package/dist/primitives/FormControlLabel.d.ts +18 -0
- package/dist/primitives/FormControlLabel.d.ts.map +1 -0
- package/dist/primitives/FormControlLabel.js +19 -0
- package/dist/primitives/Grid.d.ts +32 -0
- package/dist/primitives/Grid.d.ts.map +1 -0
- package/dist/primitives/Grid.js +50 -0
- package/dist/primitives/IconButton.d.ts +22 -0
- package/dist/primitives/IconButton.d.ts.map +1 -0
- package/dist/primitives/IconButton.js +39 -0
- package/dist/primitives/ImageList.d.ts +31 -0
- package/dist/primitives/ImageList.d.ts.map +1 -0
- package/dist/primitives/ImageList.js +33 -0
- package/dist/primitives/InputAdornment.d.ts +28 -0
- package/dist/primitives/InputAdornment.d.ts.map +1 -0
- package/dist/primitives/InputAdornment.js +13 -0
- package/dist/primitives/Link.d.ts +17 -0
- package/dist/primitives/Link.d.ts.map +1 -0
- package/dist/primitives/Link.js +29 -0
- package/dist/primitives/List.d.ts +41 -0
- package/dist/primitives/List.d.ts.map +1 -0
- package/dist/primitives/List.js +22 -0
- package/dist/primitives/Masonry.d.ts +14 -0
- package/dist/primitives/Masonry.d.ts.map +1 -0
- package/dist/primitives/Masonry.js +15 -0
- package/dist/primitives/Menu.d.ts +28 -0
- package/dist/primitives/Menu.d.ts.map +1 -0
- package/dist/primitives/Menu.js +54 -0
- package/dist/primitives/MobileStepper.d.ts +15 -0
- package/dist/primitives/MobileStepper.d.ts.map +1 -0
- package/dist/primitives/MobileStepper.js +8 -0
- package/dist/primitives/Modal.d.ts +18 -0
- package/dist/primitives/Modal.d.ts.map +1 -0
- package/dist/primitives/Modal.js +29 -0
- package/dist/primitives/NoSsr.d.ts +15 -0
- package/dist/primitives/NoSsr.d.ts.map +1 -0
- package/dist/primitives/NoSsr.js +19 -0
- package/dist/primitives/Paper.d.ts +22 -0
- package/dist/primitives/Paper.d.ts.map +1 -0
- package/dist/primitives/Paper.js +33 -0
- package/dist/primitives/Progress.d.ts +6 -2
- package/dist/primitives/Progress.d.ts.map +1 -1
- package/dist/primitives/Progress.js +8 -3
- package/dist/primitives/Snackbar.d.ts +23 -0
- package/dist/primitives/Snackbar.d.ts.map +1 -0
- package/dist/primitives/Snackbar.js +33 -0
- package/dist/primitives/SpeedDial.d.ts +26 -0
- package/dist/primitives/SpeedDial.d.ts.map +1 -0
- package/dist/primitives/SpeedDial.js +26 -0
- package/dist/primitives/Stack.d.ts +15 -0
- package/dist/primitives/Stack.d.ts.map +1 -0
- package/dist/primitives/Stack.js +45 -0
- package/dist/primitives/StarRating.d.ts +19 -1
- package/dist/primitives/StarRating.d.ts.map +1 -1
- package/dist/primitives/StarRating.js +36 -6
- package/dist/primitives/Stepper.d.ts +36 -0
- package/dist/primitives/Stepper.d.ts.map +1 -0
- package/dist/primitives/Stepper.js +53 -0
- package/dist/primitives/TablePagination.d.ts +16 -0
- package/dist/primitives/TablePagination.d.ts.map +1 -0
- package/dist/primitives/TablePagination.js +12 -0
- package/dist/primitives/TextField.d.ts +24 -0
- package/dist/primitives/TextField.d.ts.map +1 -0
- package/dist/primitives/TextField.js +19 -0
- package/dist/primitives/TextareaAutosize.d.ts +11 -0
- package/dist/primitives/TextareaAutosize.d.ts.map +1 -0
- package/dist/primitives/TextareaAutosize.js +26 -0
- package/dist/primitives/ToggleButton.d.ts +28 -0
- package/dist/primitives/ToggleButton.d.ts.map +1 -0
- package/dist/primitives/ToggleButton.js +56 -0
- package/dist/primitives/TransferList.d.ts +21 -0
- package/dist/primitives/TransferList.d.ts.map +1 -0
- package/dist/primitives/TransferList.js +40 -0
- package/dist/primitives/Typography.d.ts +23 -0
- package/dist/primitives/Typography.d.ts.map +1 -0
- package/dist/primitives/Typography.js +69 -0
- package/dist/primitives/transitions.d.ts +29 -0
- package/dist/primitives/transitions.d.ts.map +1 -0
- package/dist/primitives/transitions.js +52 -0
- package/package.json +30 -5
- package/skills/spatika-ui/SKILL.md +96 -0
- package/src/composites/AccentRule.tsx +12 -0
- package/src/composites/AvailabilityBadge.tsx +32 -0
- package/src/composites/Card.tsx +51 -1
- package/src/composites/CareerCard.tsx +111 -0
- package/src/composites/ChartDataGrid.test.tsx +57 -0
- package/src/composites/ChartDataGrid.tsx +196 -0
- package/src/composites/ContactLink.tsx +66 -0
- package/src/composites/CoverHero.test.tsx +38 -0
- package/src/composites/CoverHero.tsx +29 -22
- package/src/composites/DisplayHeading.tsx +27 -0
- package/src/composites/EntityMediaCard.test.tsx +58 -0
- package/src/composites/EntityMediaCard.tsx +31 -13
- package/src/composites/EventCalendar.tsx +928 -0
- package/src/composites/EventEditor.tsx +268 -0
- package/src/composites/EventTimeline.tsx +357 -0
- package/src/composites/FloatChip.tsx +63 -0
- package/src/composites/GradientText.tsx +31 -0
- package/src/composites/IconTile.tsx +33 -0
- package/src/composites/MapChart.test.tsx +39 -0
- package/src/composites/MapChart.tsx +130 -0
- package/src/composites/MetaChip.tsx +24 -0
- package/src/composites/PresenceDot.tsx +42 -0
- package/src/composites/ProfileHero.test.tsx +33 -0
- package/src/composites/ProfileHero.tsx +96 -79
- package/src/composites/ProjectCard.tsx +65 -0
- package/src/composites/ScatterWebGL.test.tsx +25 -0
- package/src/composites/ScatterWebGL.tsx +79 -0
- package/src/composites/SectionHeading.tsx +61 -0
- package/src/composites/SiteFooter.test.tsx +37 -0
- package/src/composites/SiteFooter.tsx +79 -0
- package/src/composites/SiteNav.test.tsx +46 -0
- package/src/composites/SiteNav.tsx +150 -0
- package/src/composites/StatCard.test.tsx +30 -0
- package/src/composites/StatCard.tsx +36 -1
- package/src/composites/Tag.tsx +50 -0
- package/src/composites/Wordmark.test.tsx +23 -0
- package/src/composites/Wordmark.tsx +46 -0
- package/src/composites/cartesian-charts.test.tsx +52 -0
- package/src/composites/cartesian-charts.tsx +1287 -0
- package/src/composites/chart-composition.test.tsx +53 -0
- package/src/composites/chart-composition.tsx +898 -0
- package/src/composites/chart-ui.tsx +328 -0
- package/src/composites/charts-3d.test.tsx +25 -0
- package/src/composites/charts-3d.tsx +318 -0
- package/src/composites/charts.test.tsx +254 -0
- package/src/composites/chrome.test.tsx +29 -0
- package/src/composites/flow-charts.test.tsx +79 -0
- package/src/composites/flow-charts.tsx +607 -0
- package/src/composites/marketing.test.tsx +192 -0
- package/src/composites/radial-charts.test.tsx +74 -0
- package/src/composites/radial-charts.tsx +617 -0
- package/src/composites/scheduler-ui.tsx +304 -0
- package/src/composites/scheduler.test.tsx +194 -0
- package/src/index.test.ts +22 -0
- package/src/index.ts +300 -5
- package/src/lib/chart-export.test.ts +20 -0
- package/src/lib/chart-export.ts +99 -0
- package/src/lib/charts-platform.test.ts +93 -0
- package/src/lib/charts.test.ts +132 -0
- package/src/lib/charts.ts +1021 -0
- package/src/lib/geo.test.ts +42 -0
- package/src/lib/geo.ts +138 -0
- package/src/lib/iso.test.ts +22 -0
- package/src/lib/iso.ts +102 -0
- package/src/lib/rrule.test.ts +53 -0
- package/src/lib/rrule.ts +281 -0
- package/src/lib/scheduler.test.ts +186 -0
- package/src/lib/scheduler.ts +688 -0
- package/src/lib/tokens.test.ts +2 -2
- package/src/lib/webgl-scatter.test.ts +36 -0
- package/src/lib/webgl-scatter.ts +230 -0
- package/src/primitives/Accordion.tsx +218 -63
- package/src/primitives/AppBar.tsx +39 -0
- package/src/primitives/Autocomplete.tsx +236 -0
- package/src/primitives/Avatar.tsx +52 -1
- package/src/primitives/Backdrop.tsx +48 -0
- package/src/primitives/BottomNavigation.tsx +102 -0
- package/src/primitives/Button.tsx +3 -0
- package/src/primitives/ButtonBase.tsx +34 -0
- package/src/primitives/ButtonGroup.tsx +90 -0
- package/src/primitives/CircularProgress.tsx +104 -0
- package/src/primitives/ClickAwayListener.tsx +46 -0
- package/src/primitives/Collapse.tsx +39 -0
- package/src/primitives/Container.tsx +40 -0
- package/src/primitives/Fab.tsx +62 -0
- package/src/primitives/FormControl.tsx +90 -0
- package/src/primitives/FormControlLabel.tsx +51 -0
- package/src/primitives/Grid.tsx +101 -0
- package/src/primitives/IconButton.tsx +59 -0
- package/src/primitives/ImageList.test.tsx +48 -0
- package/src/primitives/ImageList.tsx +112 -0
- package/src/primitives/InputAdornment.tsx +86 -0
- package/src/primitives/Link.tsx +48 -0
- package/src/primitives/List.tsx +121 -0
- package/src/primitives/Masonry.tsx +32 -0
- package/src/primitives/Menu.tsx +112 -0
- package/src/primitives/MobileStepper.tsx +64 -0
- package/src/primitives/Modal.tsx +70 -0
- package/src/primitives/NoSsr.tsx +28 -0
- package/src/primitives/Paper.tsx +55 -0
- package/src/primitives/Progress.tsx +25 -7
- package/src/primitives/Snackbar.tsx +83 -0
- package/src/primitives/SpeedDial.tsx +110 -0
- package/src/primitives/Stack.tsx +88 -0
- package/src/primitives/StarRating.tsx +87 -28
- package/src/primitives/Stepper.tsx +184 -0
- package/src/primitives/TablePagination.tsx +58 -0
- package/src/primitives/TextField.tsx +105 -0
- package/src/primitives/TextareaAutosize.tsx +49 -0
- package/src/primitives/ToggleButton.tsx +148 -0
- package/src/primitives/TransferList.tsx +110 -0
- package/src/primitives/Typography.tsx +90 -0
- package/src/primitives/mui-more.test.tsx +76 -0
- package/src/primitives/mui.test.tsx +134 -0
- package/src/primitives/transitions.tsx +120 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw WebGL scatter renderer — no three.js.
|
|
3
|
+
* Canvas sits behind SVG axes; hit-testing stays on the CPU.
|
|
4
|
+
*/
|
|
5
|
+
export const WEBGL_AUTO_THRESHOLD = 2000;
|
|
6
|
+
export function shouldUseWebGL(renderer, pointCount) {
|
|
7
|
+
if (renderer === "webgl")
|
|
8
|
+
return true;
|
|
9
|
+
if (renderer === "auto")
|
|
10
|
+
return pointCount >= WEBGL_AUTO_THRESHOLD;
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
export function parseCssColor(css) {
|
|
14
|
+
const hex = css.trim();
|
|
15
|
+
const hexMatch = /^#([0-9a-f]{3,8})$/i.exec(hex);
|
|
16
|
+
if (hexMatch) {
|
|
17
|
+
let h = hexMatch[1];
|
|
18
|
+
if (h.length === 3 || h.length === 4)
|
|
19
|
+
h = [...h].map((c) => c + c).join("");
|
|
20
|
+
const n = Number.parseInt(h.slice(0, 6), 16);
|
|
21
|
+
const a = h.length === 8 ? Number.parseInt(h.slice(6, 8), 16) / 255 : 1;
|
|
22
|
+
return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255, a];
|
|
23
|
+
}
|
|
24
|
+
const rgb = /^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)$/i.exec(hex);
|
|
25
|
+
if (rgb) {
|
|
26
|
+
return [
|
|
27
|
+
Number(rgb[1]) / 255,
|
|
28
|
+
Number(rgb[2]) / 255,
|
|
29
|
+
Number(rgb[3]) / 255,
|
|
30
|
+
rgb[4] != null ? Number(rgb[4]) : 1,
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
export function resolveCssColor(color, el) {
|
|
36
|
+
const parsed = parseCssColor(color);
|
|
37
|
+
if (parsed)
|
|
38
|
+
return parsed;
|
|
39
|
+
if (typeof document === "undefined" || !el)
|
|
40
|
+
return [0.35, 0.55, 0.95, 1];
|
|
41
|
+
const probe = document.createElement("span");
|
|
42
|
+
probe.style.color = color;
|
|
43
|
+
probe.style.position = "absolute";
|
|
44
|
+
probe.style.pointerEvents = "none";
|
|
45
|
+
probe.style.opacity = "0";
|
|
46
|
+
el.appendChild(probe);
|
|
47
|
+
const computed = getComputedStyle(probe).color;
|
|
48
|
+
probe.remove();
|
|
49
|
+
return parseCssColor(computed) ?? [0.35, 0.55, 0.95, 1];
|
|
50
|
+
}
|
|
51
|
+
export function nearestScatterHit(candidates, px, py, pad = 4) {
|
|
52
|
+
let best = null;
|
|
53
|
+
let bestDist = Infinity;
|
|
54
|
+
for (const item of candidates) {
|
|
55
|
+
const dx = item.x - px;
|
|
56
|
+
const dy = item.y - py;
|
|
57
|
+
const dist = Math.hypot(dx, dy);
|
|
58
|
+
if (dist <= item.r + pad && dist < bestDist) {
|
|
59
|
+
best = item;
|
|
60
|
+
bestDist = dist;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return best;
|
|
64
|
+
}
|
|
65
|
+
export function svgPointerPosition(svg, clientX, clientY, width, height) {
|
|
66
|
+
const bounds = svg.getBoundingClientRect();
|
|
67
|
+
const w = bounds.width || width;
|
|
68
|
+
const h = bounds.height || height;
|
|
69
|
+
return {
|
|
70
|
+
x: ((clientX - bounds.left) / w) * width,
|
|
71
|
+
y: ((clientY - bounds.top) / h) * height,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const VS = `
|
|
75
|
+
attribute vec2 a_position;
|
|
76
|
+
attribute float a_size;
|
|
77
|
+
uniform vec2 u_resolution;
|
|
78
|
+
uniform float u_dpr;
|
|
79
|
+
void main() {
|
|
80
|
+
vec2 zeroToOne = a_position / u_resolution;
|
|
81
|
+
vec2 clip = zeroToOne * 2.0 - 1.0;
|
|
82
|
+
gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);
|
|
83
|
+
gl_PointSize = max(1.0, a_size * u_dpr);
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
const FS = `
|
|
87
|
+
precision mediump float;
|
|
88
|
+
uniform vec4 u_color;
|
|
89
|
+
void main() {
|
|
90
|
+
vec2 c = gl_PointCoord - vec2(0.5);
|
|
91
|
+
if (dot(c, c) > 0.25) discard;
|
|
92
|
+
gl_FragColor = u_color;
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
function compile(gl, type, source) {
|
|
96
|
+
const shader = gl.createShader(type);
|
|
97
|
+
if (!shader)
|
|
98
|
+
return null;
|
|
99
|
+
gl.shaderSource(shader, source);
|
|
100
|
+
gl.compileShader(shader);
|
|
101
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
102
|
+
gl.deleteShader(shader);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return shader;
|
|
106
|
+
}
|
|
107
|
+
export function createScatterGL(canvas) {
|
|
108
|
+
const gl = canvas.getContext("webgl", {
|
|
109
|
+
alpha: true,
|
|
110
|
+
antialias: true,
|
|
111
|
+
premultipliedAlpha: true,
|
|
112
|
+
});
|
|
113
|
+
if (!gl)
|
|
114
|
+
return null;
|
|
115
|
+
const vs = compile(gl, gl.VERTEX_SHADER, VS);
|
|
116
|
+
const fs = compile(gl, gl.FRAGMENT_SHADER, FS);
|
|
117
|
+
if (!vs || !fs)
|
|
118
|
+
return null;
|
|
119
|
+
const program = gl.createProgram();
|
|
120
|
+
if (!program)
|
|
121
|
+
return null;
|
|
122
|
+
gl.attachShader(program, vs);
|
|
123
|
+
gl.attachShader(program, fs);
|
|
124
|
+
gl.linkProgram(program);
|
|
125
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
|
|
126
|
+
return null;
|
|
127
|
+
const buffer = gl.createBuffer();
|
|
128
|
+
if (!buffer)
|
|
129
|
+
return null;
|
|
130
|
+
gl.enable(gl.BLEND);
|
|
131
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
132
|
+
return {
|
|
133
|
+
gl,
|
|
134
|
+
program,
|
|
135
|
+
buffer,
|
|
136
|
+
aPosition: gl.getAttribLocation(program, "a_position"),
|
|
137
|
+
aSize: gl.getAttribLocation(program, "a_size"),
|
|
138
|
+
uResolution: gl.getUniformLocation(program, "u_resolution"),
|
|
139
|
+
uDpr: gl.getUniformLocation(program, "u_dpr"),
|
|
140
|
+
uColor: gl.getUniformLocation(program, "u_color"),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export function drawScatterGL(gpu, canvas, width, height, series) {
|
|
144
|
+
const dpr = typeof window !== "undefined" ? Math.min(window.devicePixelRatio || 1, 2) : 1;
|
|
145
|
+
const pixelW = Math.max(1, Math.round(width * dpr));
|
|
146
|
+
const pixelH = Math.max(1, Math.round(height * dpr));
|
|
147
|
+
if (canvas.width !== pixelW)
|
|
148
|
+
canvas.width = pixelW;
|
|
149
|
+
if (canvas.height !== pixelH)
|
|
150
|
+
canvas.height = pixelH;
|
|
151
|
+
canvas.style.width = `${width}px`;
|
|
152
|
+
canvas.style.height = `${height}px`;
|
|
153
|
+
const { gl } = gpu;
|
|
154
|
+
gl.viewport(0, 0, pixelW, pixelH);
|
|
155
|
+
gl.clearColor(0, 0, 0, 0);
|
|
156
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
157
|
+
gl.useProgram(gpu.program);
|
|
158
|
+
gl.uniform2f(gpu.uResolution, width, height);
|
|
159
|
+
gl.uniform1f(gpu.uDpr, dpr);
|
|
160
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, gpu.buffer);
|
|
161
|
+
const stride = 3 * 4;
|
|
162
|
+
for (const item of series) {
|
|
163
|
+
if (!item.positions.length)
|
|
164
|
+
continue;
|
|
165
|
+
const data = new Float32Array(item.positions.length * 3);
|
|
166
|
+
item.positions.forEach((point, i) => {
|
|
167
|
+
data[i * 3] = point.x;
|
|
168
|
+
data[i * 3 + 1] = point.y;
|
|
169
|
+
data[i * 3 + 2] = point.size;
|
|
170
|
+
});
|
|
171
|
+
gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
|
|
172
|
+
gl.enableVertexAttribArray(gpu.aPosition);
|
|
173
|
+
gl.vertexAttribPointer(gpu.aPosition, 2, gl.FLOAT, false, stride, 0);
|
|
174
|
+
gl.enableVertexAttribArray(gpu.aSize);
|
|
175
|
+
gl.vertexAttribPointer(gpu.aSize, 1, gl.FLOAT, false, stride, 8);
|
|
176
|
+
const [r, g, b, a] = resolveCssColor(item.color, canvas.parentElement ?? canvas);
|
|
177
|
+
gl.uniform4f(gpu.uColor, r, g, b, a);
|
|
178
|
+
gl.drawArrays(gl.POINTS, 0, item.positions.length);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
export function destroyScatterGL(gpu) {
|
|
182
|
+
const { gl } = gpu;
|
|
183
|
+
gl.deleteBuffer(gpu.buffer);
|
|
184
|
+
gl.deleteProgram(gpu.program);
|
|
185
|
+
}
|
|
@@ -1,24 +1,48 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
type AccordionType = "single" | "multiple";
|
|
3
|
+
export type AccordionProps = Omit<React.ComponentPropsWithoutRef<"div">, "onChange"> & {
|
|
4
|
+
type?: AccordionType;
|
|
5
|
+
value?: string | string[];
|
|
4
6
|
defaultValue?: string | string[];
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
onValueChange?: (value: string | string[]) => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
/** Remove the gap between items and stack them as a single surface. */
|
|
10
|
+
disableGutters?: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare function Accordion({ type, value: valueProp, defaultValue, onValueChange, disabled, disableGutters, className, children, ...props }: AccordionProps): React.JSX.Element;
|
|
13
|
+
declare namespace Accordion {
|
|
14
|
+
var displayName: string;
|
|
15
|
+
}
|
|
16
|
+
export type AccordionItemProps = React.ComponentPropsWithoutRef<"div"> & {
|
|
9
17
|
value: string;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}): React.JSX.Element;
|
|
13
|
-
declare
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
};
|
|
20
|
+
declare function AccordionItem({ value, disabled, className, children, ...props }: AccordionItemProps): React.JSX.Element;
|
|
21
|
+
declare namespace AccordionItem {
|
|
22
|
+
var displayName: string;
|
|
23
|
+
}
|
|
24
|
+
export type AccordionTriggerProps = React.ComponentPropsWithoutRef<"button"> & {
|
|
25
|
+
/** @deprecated Prefer wrapping with AccordionItem — value is inherited. */
|
|
26
|
+
value?: string;
|
|
27
|
+
};
|
|
28
|
+
declare function AccordionTrigger({ value: valueProp, className, children, onClick, ...props }: AccordionTriggerProps): React.JSX.Element;
|
|
29
|
+
declare namespace AccordionTrigger {
|
|
30
|
+
var displayName: string;
|
|
31
|
+
}
|
|
32
|
+
export type AccordionContentProps = React.ComponentPropsWithoutRef<"div"> & {
|
|
33
|
+
/** @deprecated Prefer wrapping with AccordionItem — value is inherited. */
|
|
34
|
+
value?: string;
|
|
35
|
+
};
|
|
36
|
+
declare function AccordionContent({ value: valueProp, className, children, ...props }: AccordionContentProps): React.JSX.Element;
|
|
37
|
+
declare namespace AccordionContent {
|
|
38
|
+
var displayName: string;
|
|
39
|
+
}
|
|
40
|
+
declare function AccordionActions({ className, ...props }: React.ComponentPropsWithoutRef<"div">): React.JSX.Element;
|
|
41
|
+
declare namespace AccordionActions {
|
|
42
|
+
var displayName: string;
|
|
43
|
+
}
|
|
44
|
+
/** MUI-compatible aliases. */
|
|
45
|
+
declare const AccordionSummary: typeof AccordionTrigger;
|
|
46
|
+
declare const AccordionDetails: typeof AccordionContent;
|
|
47
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent, AccordionActions, AccordionSummary, AccordionDetails, };
|
|
24
48
|
//# sourceMappingURL=Accordion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../src/primitives/Accordion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../src/primitives/Accordion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,KAAK,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;AAiC3C,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG;IACrF,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,CAAC;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAOF,iBAAS,SAAS,CAAC,EACjB,IAAe,EACf,KAAK,EAAE,SAAS,EAChB,YAAY,EACZ,aAAa,EACb,QAAgB,EAChB,cAAsB,EACtB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,qBAkChB;kBA5CQ,SAAS;;;AA+ClB,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,GAAG;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,iBAAS,aAAa,CAAC,EACrB,KAAK,EACL,QAAgB,EAChB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,qBAmCpB;kBAzCQ,aAAa;;;AA4CtB,MAAM,MAAM,qBAAqB,GAAG,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC,GAAG;IAC7E,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EAAE,SAAS,EAChB,SAAS,EACT,QAAQ,EACR,OAAO,EACP,GAAG,KAAK,EACT,EAAE,qBAAqB,qBA2CvB;kBAjDQ,gBAAgB;;;AAoDzB,MAAM,MAAM,qBAAqB,GAAG,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,GAAG;IAC1E,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EAAE,SAAS,EAChB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,qBAAqB,qBAsBvB;kBA3BQ,gBAAgB;;;AA8BzB,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,qBAWvF;kBAXQ,gBAAgB;;;AAczB,8BAA8B;AAC9B,QAAA,MAAM,gBAAgB,yBAAmB,CAAC;AAC1C,QAAA,MAAM,gBAAgB,yBAAmB,CAAC;AAE1C,OAAO,EACL,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,CAAC"}
|
|
@@ -1,37 +1,97 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { ChevronDown } from "lucide-react";
|
|
4
|
+
import { useControllableState } from "../lib/use-controllable-state";
|
|
4
5
|
import { cn } from "../lib/cn";
|
|
6
|
+
import { Collapse } from "./Collapse";
|
|
5
7
|
const AccordionContext = React.createContext(null);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const AccordionItemContext = React.createContext(null);
|
|
9
|
+
function useAccordion(component) {
|
|
10
|
+
const ctx = React.useContext(AccordionContext);
|
|
11
|
+
if (!ctx)
|
|
12
|
+
throw new Error(`${component} must be used within <Accordion>`);
|
|
13
|
+
return ctx;
|
|
14
|
+
}
|
|
15
|
+
function useAccordionItem(component) {
|
|
16
|
+
const ctx = React.useContext(AccordionItemContext);
|
|
17
|
+
if (!ctx)
|
|
18
|
+
throw new Error(`${component} must be used within <AccordionItem>`);
|
|
19
|
+
return ctx;
|
|
20
|
+
}
|
|
21
|
+
function toArray(value) {
|
|
22
|
+
if (value == null || value === "")
|
|
23
|
+
return [];
|
|
24
|
+
return Array.isArray(value) ? value : [value];
|
|
25
|
+
}
|
|
26
|
+
function Accordion({ type = "single", value: valueProp, defaultValue, onValueChange, disabled = false, disableGutters = false, className, children, ...props }) {
|
|
27
|
+
const [open = [], setOpen] = useControllableState({
|
|
28
|
+
prop: valueProp === undefined ? undefined : toArray(valueProp),
|
|
29
|
+
defaultProp: toArray(defaultValue),
|
|
30
|
+
onChange: (next) => {
|
|
31
|
+
onValueChange?.(type === "single" ? (next[0] ?? "") : next);
|
|
32
|
+
},
|
|
33
|
+
});
|
|
13
34
|
const toggle = (id) => {
|
|
35
|
+
if (disabled)
|
|
36
|
+
return;
|
|
14
37
|
setOpen((prev) => {
|
|
15
|
-
const
|
|
38
|
+
const current = prev ?? [];
|
|
39
|
+
const isOpen = current.includes(id);
|
|
16
40
|
if (type === "single")
|
|
17
41
|
return isOpen ? [] : [id];
|
|
18
|
-
return isOpen ?
|
|
42
|
+
return isOpen ? current.filter((x) => x !== id) : [...current, id];
|
|
19
43
|
});
|
|
20
44
|
};
|
|
21
|
-
return (_jsx(AccordionContext.Provider, { value: { open, toggle, type }, children: _jsx("div", { "data-slot": "accordion", className: cn("space-y-2", className), children: children }) }));
|
|
45
|
+
return (_jsx(AccordionContext.Provider, { value: { open: open ?? [], toggle, type, disabled, disableGutters }, children: _jsx("div", { "data-slot": "accordion", "data-disabled": disabled ? "" : undefined, "data-gutters": disableGutters ? "false" : "true", className: cn(disableGutters ? "overflow-hidden rounded-xl" : "space-y-2", className), ...props, children: children }) }));
|
|
22
46
|
}
|
|
23
|
-
|
|
24
|
-
|
|
47
|
+
Accordion.displayName = "Accordion";
|
|
48
|
+
function AccordionItem({ value, disabled = false, className, children, ...props }) {
|
|
49
|
+
const accordion = useAccordion("AccordionItem");
|
|
50
|
+
const reactId = React.useId();
|
|
51
|
+
const expanded = accordion.open.includes(value);
|
|
52
|
+
const isDisabled = disabled || accordion.disabled;
|
|
53
|
+
return (_jsx(AccordionItemContext.Provider, { value: {
|
|
54
|
+
value,
|
|
55
|
+
disabled: isDisabled,
|
|
56
|
+
expanded,
|
|
57
|
+
triggerId: `${reactId}-trigger`,
|
|
58
|
+
contentId: `${reactId}-content`,
|
|
59
|
+
}, children: _jsx("div", { "data-slot": "accordion-item", "data-value": value, "data-state": expanded ? "open" : "closed", "data-disabled": isDisabled ? "" : undefined, className: cn("overflow-hidden border-border/40 bg-card/40", accordion.disableGutters
|
|
60
|
+
? "border-x border-b first:rounded-t-xl first:border-t last:rounded-b-xl"
|
|
61
|
+
: "rounded-xl border", isDisabled && "pointer-events-none opacity-50", className), ...props, children: children }) }));
|
|
25
62
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
|
|
63
|
+
AccordionItem.displayName = "AccordionItem";
|
|
64
|
+
function AccordionTrigger({ value: valueProp, className, children, onClick, ...props }) {
|
|
65
|
+
const accordion = useAccordion("AccordionTrigger");
|
|
66
|
+
const item = React.useContext(AccordionItemContext);
|
|
67
|
+
const value = valueProp ?? item?.value;
|
|
68
|
+
if (!value)
|
|
69
|
+
throw new Error("AccordionTrigger requires AccordionItem or a value prop");
|
|
70
|
+
const expanded = item?.expanded ?? accordion.open.includes(value);
|
|
71
|
+
const disabled = item?.disabled ?? accordion.disabled;
|
|
72
|
+
return (_jsx("h3", { className: "m-0", children: _jsxs("button", { type: "button", id: item?.triggerId, "data-slot": "accordion-trigger", "data-state": expanded ? "open" : "closed", "aria-expanded": expanded, "aria-controls": item?.contentId, disabled: disabled, className: cn("flex w-full items-center justify-between gap-2 px-4 py-3 text-left text-sm font-bold outline-none transition-colors", "hover:bg-muted/30 focus-visible:ring-ring/50 focus-visible:ring-[3px]", "disabled:cursor-not-allowed", className), onClick: (event) => {
|
|
73
|
+
onClick?.(event);
|
|
74
|
+
if (event.defaultPrevented || disabled)
|
|
75
|
+
return;
|
|
76
|
+
accordion.toggle(value);
|
|
77
|
+
}, ...props, children: [children, _jsx(ChevronDown, { "aria-hidden": true, className: cn("size-4 shrink-0 text-muted-foreground transition-transform duration-300", expanded && "rotate-180") })] }) }));
|
|
30
78
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
79
|
+
AccordionTrigger.displayName = "AccordionTrigger";
|
|
80
|
+
function AccordionContent({ value: valueProp, className, children, ...props }) {
|
|
81
|
+
const accordion = useAccordion("AccordionContent");
|
|
82
|
+
const item = React.useContext(AccordionItemContext);
|
|
83
|
+
const value = valueProp ?? item?.value;
|
|
84
|
+
if (!value)
|
|
85
|
+
throw new Error("AccordionContent requires AccordionItem or a value prop");
|
|
86
|
+
const expanded = item?.expanded ?? accordion.open.includes(value);
|
|
87
|
+
return (_jsx(Collapse, { in: expanded, children: _jsx("div", { id: item?.contentId, role: "region", "aria-labelledby": item?.triggerId, "data-slot": "accordion-content", className: cn("border-t border-border/30 px-4 py-3 text-sm", className), ...props, children: children }) }));
|
|
88
|
+
}
|
|
89
|
+
AccordionContent.displayName = "AccordionContent";
|
|
90
|
+
function AccordionActions({ className, ...props }) {
|
|
91
|
+
return (_jsx("div", { "data-slot": "accordion-actions", className: cn("flex flex-wrap items-center justify-end gap-2 border-t border-border/30 px-4 py-2.5", className), ...props }));
|
|
36
92
|
}
|
|
37
|
-
|
|
93
|
+
AccordionActions.displayName = "AccordionActions";
|
|
94
|
+
/** MUI-compatible aliases. */
|
|
95
|
+
const AccordionSummary = AccordionTrigger;
|
|
96
|
+
const AccordionDetails = AccordionContent;
|
|
97
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent, AccordionActions, AccordionSummary, AccordionDetails, };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
declare const appBarVariants: (props?: ({
|
|
4
|
+
position?: "fixed" | "relative" | "static" | "sticky" | null | undefined;
|
|
5
|
+
color?: "transparent" | "default" | "primary" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export type AppBarProps = Omit<React.ComponentPropsWithoutRef<"header">, "color"> & VariantProps<typeof appBarVariants>;
|
|
8
|
+
declare function AppBar({ className, position, color, ...props }: AppBarProps): React.JSX.Element;
|
|
9
|
+
declare namespace AppBar {
|
|
10
|
+
var displayName: string;
|
|
11
|
+
}
|
|
12
|
+
export { AppBar, appBarVariants };
|
|
13
|
+
//# sourceMappingURL=AppBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppBar.d.ts","sourceRoot":"","sources":["../../src/primitives/AppBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,QAAA,MAAM,cAAc;;;8EAkBlB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GAC/E,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtC,iBAAS,MAAM,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,qBAQpE;kBARQ,MAAM;;;AAWf,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
import { cn } from "../lib/cn";
|
|
4
|
+
const appBarVariants = cva("z-40 flex w-full items-center border-b border-border/50", {
|
|
5
|
+
variants: {
|
|
6
|
+
position: {
|
|
7
|
+
static: "relative",
|
|
8
|
+
sticky: "sticky top-0",
|
|
9
|
+
fixed: "fixed inset-x-0 top-0",
|
|
10
|
+
relative: "relative",
|
|
11
|
+
},
|
|
12
|
+
color: {
|
|
13
|
+
default: "glass-header text-foreground",
|
|
14
|
+
primary: "bg-primary text-primary-foreground border-transparent",
|
|
15
|
+
transparent: "border-transparent bg-transparent",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
position: "sticky",
|
|
20
|
+
color: "default",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
function AppBar({ className, position, color, ...props }) {
|
|
24
|
+
return (_jsx("header", { "data-slot": "app-bar", className: cn(appBarVariants({ position, color }), className), ...props }));
|
|
25
|
+
}
|
|
26
|
+
AppBar.displayName = "AppBar";
|
|
27
|
+
export { AppBar, appBarVariants };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type AutocompleteOption = {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type AutocompleteProps = Omit<React.ComponentPropsWithoutRef<"div">, "onChange" | "defaultValue"> & {
|
|
8
|
+
options: Array<string | AutocompleteOption>;
|
|
9
|
+
value?: string | string[] | null;
|
|
10
|
+
defaultValue?: string | string[] | null;
|
|
11
|
+
onChange?: (value: string | string[] | null, option?: AutocompleteOption | AutocompleteOption[] | null) => void;
|
|
12
|
+
multiple?: boolean;
|
|
13
|
+
freeSolo?: boolean;
|
|
14
|
+
label?: React.ReactNode;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
fullWidth?: boolean;
|
|
18
|
+
noOptionsText?: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Filterable combobox. Supports single, multiple, and free-solo entry.
|
|
22
|
+
*/
|
|
23
|
+
declare function Autocomplete({ options: optionsProp, value: valueProp, defaultValue, onChange, multiple, freeSolo, label, placeholder, disabled, fullWidth, noOptionsText, className, id, ...props }: AutocompleteProps): React.JSX.Element;
|
|
24
|
+
declare namespace Autocomplete {
|
|
25
|
+
var displayName: string;
|
|
26
|
+
}
|
|
27
|
+
export { Autocomplete };
|
|
28
|
+
//# sourceMappingURL=Autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Autocomplete.d.ts","sourceRoot":"","sources":["../../src/primitives/Autocomplete.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAQF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAClC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EACrC,UAAU,GAAG,cAAc,CAC5B,GAAG;IACF,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,kBAAkB,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAChH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAOF;;GAEG;AACH,iBAAS,YAAY,CAAC,EACpB,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,SAAS,EAChB,YAAY,EACZ,QAAQ,EACR,QAAgB,EAChB,QAAgB,EAChB,KAAK,EACL,WAAuB,EACvB,QAAQ,EACR,SAAS,EACT,aAA4B,EAC5B,SAAS,EACT,EAAE,EACF,GAAG,KAAK,EACT,EAAE,iBAAiB,qBA4KnB;kBA3LQ,YAAY;;;AA8LrB,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Check, ChevronsUpDown, X } from "lucide-react";
|
|
4
|
+
import { useControllableState } from "../lib/use-controllable-state";
|
|
5
|
+
import { useDismissable } from "../lib/use-dismissable";
|
|
6
|
+
import { cn } from "../lib/cn";
|
|
7
|
+
import { Input } from "./Input";
|
|
8
|
+
import { Label } from "./Label";
|
|
9
|
+
function normalizeOptions(options) {
|
|
10
|
+
return options.map((option) => typeof option === "string" ? { label: option, value: option } : option);
|
|
11
|
+
}
|
|
12
|
+
function asList(value) {
|
|
13
|
+
if (value == null || value === "")
|
|
14
|
+
return [];
|
|
15
|
+
return Array.isArray(value) ? value : [value];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Filterable combobox. Supports single, multiple, and free-solo entry.
|
|
19
|
+
*/
|
|
20
|
+
function Autocomplete({ options: optionsProp, value: valueProp, defaultValue, onChange, multiple = false, freeSolo = false, label, placeholder = "Search…", disabled, fullWidth, noOptionsText = "No options", className, id, ...props }) {
|
|
21
|
+
const autoId = React.useId();
|
|
22
|
+
const fieldId = id ?? autoId;
|
|
23
|
+
const options = React.useMemo(() => normalizeOptions(optionsProp), [optionsProp]);
|
|
24
|
+
const [value, setValue] = useControllableState({
|
|
25
|
+
prop: valueProp,
|
|
26
|
+
defaultProp: defaultValue ?? (multiple ? [] : null),
|
|
27
|
+
onChange: (next) => {
|
|
28
|
+
const list = asList(next);
|
|
29
|
+
const matched = options.filter((opt) => list.includes(opt.value));
|
|
30
|
+
onChange?.(next, multiple ? matched : (matched[0] ?? null));
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
const selected = asList(value);
|
|
34
|
+
const [query, setQuery] = React.useState("");
|
|
35
|
+
const [open, setOpen] = React.useState(false);
|
|
36
|
+
const [highlight, setHighlight] = React.useState(0);
|
|
37
|
+
const rootRef = React.useRef(null);
|
|
38
|
+
const listRef = React.useRef(null);
|
|
39
|
+
const filtered = options.filter((opt) => {
|
|
40
|
+
if (multiple && selected.includes(opt.value) && !query)
|
|
41
|
+
return true;
|
|
42
|
+
return opt.label.toLowerCase().includes(query.toLowerCase());
|
|
43
|
+
});
|
|
44
|
+
useDismissable({
|
|
45
|
+
enabled: open,
|
|
46
|
+
onDismiss: () => setOpen(false),
|
|
47
|
+
refs: [rootRef, listRef],
|
|
48
|
+
});
|
|
49
|
+
const commit = (next) => {
|
|
50
|
+
if (disabled)
|
|
51
|
+
return;
|
|
52
|
+
if (multiple) {
|
|
53
|
+
const list = selected.includes(next)
|
|
54
|
+
? selected.filter((item) => item !== next)
|
|
55
|
+
: [...selected, next];
|
|
56
|
+
setValue(list);
|
|
57
|
+
setQuery("");
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
setValue(next);
|
|
61
|
+
setQuery("");
|
|
62
|
+
setOpen(false);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const display = multiple
|
|
66
|
+
? query
|
|
67
|
+
: open
|
|
68
|
+
? query
|
|
69
|
+
: (options.find((opt) => opt.value === selected[0])?.label ?? selected[0] ?? "");
|
|
70
|
+
return (_jsxs("div", { ref: rootRef, "data-slot": "autocomplete", className: cn("relative", fullWidth && "w-full", className), ...props, children: [label ? _jsx(Label, { htmlFor: fieldId, children: label }) : null, _jsxs("div", { className: cn("mt-1.5 flex min-h-9 flex-wrap items-center gap-1 rounded-md border border-input bg-input-background px-2 py-1", "focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]", disabled && "opacity-50"), children: [multiple
|
|
71
|
+
? selected.map((item) => {
|
|
72
|
+
const opt = options.find((option) => option.value === item);
|
|
73
|
+
return (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border border-border/50 bg-muted/50 px-2 py-0.5 text-xs font-bold", children: [opt?.label ?? item, _jsx("button", { type: "button", "aria-label": `Remove ${opt?.label ?? item}`, className: "text-muted-foreground hover:text-foreground", onClick: () => commit(item), children: _jsx(X, { className: "size-3" }) })] }, item));
|
|
74
|
+
})
|
|
75
|
+
: null, _jsx(Input, { id: fieldId, disabled: disabled, role: "combobox", "aria-expanded": open, "aria-autocomplete": "list", placeholder: selected.length && multiple ? undefined : placeholder, value: multiple ? query : display, className: "h-7 min-w-16 flex-1 border-0 bg-transparent px-1 shadow-none focus-visible:ring-0", onFocus: () => {
|
|
76
|
+
setOpen(true);
|
|
77
|
+
if (!multiple) {
|
|
78
|
+
const current = options.find((opt) => opt.value === selected[0])?.label ?? selected[0] ?? "";
|
|
79
|
+
setQuery(current);
|
|
80
|
+
}
|
|
81
|
+
}, onChange: (event) => {
|
|
82
|
+
setQuery(event.target.value);
|
|
83
|
+
setOpen(true);
|
|
84
|
+
setHighlight(0);
|
|
85
|
+
if (!multiple && !freeSolo) {
|
|
86
|
+
/* keep typing local until a selection is committed */
|
|
87
|
+
}
|
|
88
|
+
}, onKeyDown: (event) => {
|
|
89
|
+
if (event.key === "ArrowDown") {
|
|
90
|
+
event.preventDefault();
|
|
91
|
+
setOpen(true);
|
|
92
|
+
setHighlight((index) => Math.min(filtered.length - 1, index + 1));
|
|
93
|
+
}
|
|
94
|
+
else if (event.key === "ArrowUp") {
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
setHighlight((index) => Math.max(0, index - 1));
|
|
97
|
+
}
|
|
98
|
+
else if (event.key === "Enter") {
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
const hit = filtered[highlight];
|
|
101
|
+
if (hit)
|
|
102
|
+
commit(hit.value);
|
|
103
|
+
else if (freeSolo && query.trim())
|
|
104
|
+
commit(query.trim());
|
|
105
|
+
}
|
|
106
|
+
else if (event.key === "Escape") {
|
|
107
|
+
setOpen(false);
|
|
108
|
+
}
|
|
109
|
+
else if (event.key === "Backspace" && multiple && !query && selected.length) {
|
|
110
|
+
commit(selected[selected.length - 1]);
|
|
111
|
+
}
|
|
112
|
+
} }), _jsx(ChevronsUpDown, { className: "size-3.5 shrink-0 text-muted-foreground" })] }), open ? (_jsx("div", { ref: listRef, role: "listbox", "data-slot": "autocomplete-list", className: "glass-menu absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-xl border border-border/50 p-1 shadow-xl", children: filtered.length === 0 ? (_jsx("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: noOptionsText })) : (filtered.map((opt, index) => {
|
|
113
|
+
const active = selected.includes(opt.value);
|
|
114
|
+
return (_jsxs("button", { type: "button", role: "option", "aria-selected": active, disabled: opt.disabled, className: cn("flex w-full items-center justify-between rounded-lg px-3 py-2 text-left text-sm font-medium", index === highlight ? "bg-muted/60" : "hover:bg-muted/40", opt.disabled && "opacity-40"), onMouseEnter: () => setHighlight(index), onClick: () => commit(opt.value), children: [opt.label, active ? _jsx(Check, { className: "size-3.5 text-primary" }) : null] }, opt.value));
|
|
115
|
+
})) })) : null] }));
|
|
116
|
+
}
|
|
117
|
+
Autocomplete.displayName = "Autocomplete";
|
|
118
|
+
export { Autocomplete };
|
|
@@ -11,5 +11,17 @@ declare function InitialsAvatar({ name, className, textClassName, }: {
|
|
|
11
11
|
className?: string;
|
|
12
12
|
textClassName?: string;
|
|
13
13
|
}): React.JSX.Element;
|
|
14
|
-
export
|
|
14
|
+
export type AvatarGroupProps = React.ComponentPropsWithoutRef<"div"> & {
|
|
15
|
+
max?: number;
|
|
16
|
+
total?: number;
|
|
17
|
+
spacing?: "sm" | "md" | "lg";
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Overlapping avatar stack with an overflow count.
|
|
21
|
+
*/
|
|
22
|
+
declare function AvatarGroup({ max, total, spacing, className, children, ...props }: AvatarGroupProps): React.JSX.Element;
|
|
23
|
+
declare namespace AvatarGroup {
|
|
24
|
+
var displayName: string;
|
|
25
|
+
}
|
|
26
|
+
export { Avatar, AvatarImage, AvatarFallback, InitialsAvatar, AvatarGroup };
|
|
15
27
|
//# sourceMappingURL=Avatar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/primitives/Avatar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAc/B,QAAA,MAAM,MAAM,sKA6BV,CAAC;AAGH,QAAA,MAAM,WAAW,4KAsCf,CAAC;AAGH,QAAA,MAAM,cAAc,sKAoBlB,CAAC;AAGH;;;GAGG;AACH,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,SAAS,EACT,aAAa,GACd,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,qBAcA;AAED,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/primitives/Avatar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAc/B,QAAA,MAAM,MAAM,sKA6BV,CAAC;AAGH,QAAA,MAAM,WAAW,4KAsCf,CAAC;AAGH,QAAA,MAAM,cAAc,sKAoBlB,CAAC;AAGH;;;GAGG;AACH,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,SAAS,EACT,aAAa,GACd,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,qBAcA;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,GAAG;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC9B,CAAC;AAQF;;GAEG;AACH,iBAAS,WAAW,CAAC,EACnB,GAAO,EACP,KAAK,EACL,OAAc,EACd,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,gBAAgB,qBA0BlB;kBAjCQ,WAAW;;;AAoCpB,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { getAvatarColor, getInitials } from "../lib/avatar-utils";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
@@ -49,4 +49,19 @@ function InitialsAvatar({ name, className, textClassName, }) {
|
|
|
49
49
|
const initials = getInitials(n) || "?";
|
|
50
50
|
return (_jsx("div", { className: cn("relative flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full text-white", getAvatarColor(n), className), children: _jsx("span", { className: cn("leading-none", textClassName), children: initials }) }));
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
const spacingClass = {
|
|
53
|
+
sm: "-space-x-1",
|
|
54
|
+
md: "-space-x-2",
|
|
55
|
+
lg: "-space-x-3",
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Overlapping avatar stack with an overflow count.
|
|
59
|
+
*/
|
|
60
|
+
function AvatarGroup({ max = 5, total, spacing = "md", className, children, ...props }) {
|
|
61
|
+
const avatars = React.Children.toArray(children);
|
|
62
|
+
const extra = Math.max(0, (total ?? avatars.length) - max);
|
|
63
|
+
const shown = extra > 0 ? avatars.slice(0, max) : avatars;
|
|
64
|
+
return (_jsxs("div", { "data-slot": "avatar-group", className: cn("flex items-center [&_[data-slot=avatar]]:ring-2 [&_[data-slot=avatar]]:ring-background", spacingClass[spacing], className), ...props, children: [shown, extra > 0 ? (_jsxs("span", { "data-slot": "avatar-group-surplus", className: "relative z-[1] flex size-10 shrink-0 items-center justify-center rounded-full border-2 border-background bg-muted text-xs font-bold text-muted-foreground", children: ["+", extra] })) : null] }));
|
|
65
|
+
}
|
|
66
|
+
AvatarGroup.displayName = "AvatarGroup";
|
|
67
|
+
export { Avatar, AvatarImage, AvatarFallback, InitialsAvatar, AvatarGroup };
|