@spatika/react 1.1.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/Card.d.ts +7 -1
- package/dist/composites/Card.d.ts.map +1 -1
- package/dist/composites/Card.js +10 -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/CoverHero.d.ts +1 -1
- package/dist/composites/CoverHero.d.ts.map +1 -1
- package/dist/composites/CoverHero.js +2 -2
- 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/MapChart.d.ts +24 -0
- package/dist/composites/MapChart.d.ts.map +1 -0
- package/dist/composites/MapChart.js +58 -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/ScatterWebGL.d.ts +22 -0
- package/dist/composites/ScatterWebGL.d.ts.map +1 -0
- package/dist/composites/ScatterWebGL.js +45 -0
- package/dist/composites/SiteFooter.d.ts +1 -1
- package/dist/composites/SiteFooter.js +1 -1
- package/dist/composites/SiteNav.d.ts +7 -2
- package/dist/composites/SiteNav.d.ts.map +1 -1
- package/dist/composites/SiteNav.js +9 -5
- package/dist/composites/StatCard.d.ts +2 -1
- package/dist/composites/StatCard.d.ts.map +1 -1
- package/dist/composites/StatCard.js +3 -3
- package/dist/composites/StatusDot.d.ts +1 -1
- package/dist/composites/Wordmark.d.ts +2 -2
- package/dist/composites/Wordmark.d.ts.map +1 -1
- 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 +67 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -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/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 +28 -4
- package/skills/spatika-ui/SKILL.md +96 -0
- package/src/composites/Card.tsx +51 -1
- package/src/composites/ChartDataGrid.test.tsx +57 -0
- package/src/composites/ChartDataGrid.tsx +196 -0
- package/src/composites/CoverHero.test.tsx +38 -0
- package/src/composites/CoverHero.tsx +29 -22
- 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/MapChart.test.tsx +39 -0
- package/src/composites/MapChart.tsx +130 -0
- package/src/composites/ProfileHero.test.tsx +33 -0
- package/src/composites/ProfileHero.tsx +96 -79
- package/src/composites/ScatterWebGL.test.tsx +25 -0
- package/src/composites/ScatterWebGL.tsx +79 -0
- package/src/composites/SiteFooter.test.tsx +37 -0
- package/src/composites/SiteFooter.tsx +1 -1
- package/src/composites/SiteNav.test.tsx +46 -0
- package/src/composites/SiteNav.tsx +14 -4
- package/src/composites/StatCard.test.tsx +30 -0
- package/src/composites/StatCard.tsx +4 -0
- package/src/composites/Wordmark.test.tsx +23 -0
- package/src/composites/Wordmark.tsx +2 -2
- 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 +38 -34
- 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 +277 -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/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,28 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
declare const toggleButtonVariants: (props?: ({
|
|
4
|
+
size?: "sm" | "lg" | "md" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
export type ToggleButtonGroupProps = Omit<React.ComponentPropsWithoutRef<"div">, "onChange" | "value" | "defaultValue"> & {
|
|
7
|
+
exclusive?: boolean;
|
|
8
|
+
value?: string | string[] | null;
|
|
9
|
+
defaultValue?: string | string[] | null;
|
|
10
|
+
onValueChange?: (value: string | string[] | null) => void;
|
|
11
|
+
size?: VariantProps<typeof toggleButtonVariants>["size"];
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
orientation?: "horizontal" | "vertical";
|
|
14
|
+
};
|
|
15
|
+
declare function ToggleButtonGroup({ exclusive, value: valueProp, defaultValue, onValueChange, size, disabled, orientation, className, children, ...props }: ToggleButtonGroupProps): React.JSX.Element;
|
|
16
|
+
declare namespace ToggleButtonGroup {
|
|
17
|
+
var displayName: string;
|
|
18
|
+
}
|
|
19
|
+
export type ToggleButtonProps = Omit<React.ComponentPropsWithoutRef<"button">, "value"> & VariantProps<typeof toggleButtonVariants> & {
|
|
20
|
+
value: string;
|
|
21
|
+
selected?: boolean;
|
|
22
|
+
};
|
|
23
|
+
declare function ToggleButton({ value, selected, size: sizeProp, className, disabled, onClick, children, ...props }: ToggleButtonProps): React.JSX.Element;
|
|
24
|
+
declare namespace ToggleButton {
|
|
25
|
+
var displayName: string;
|
|
26
|
+
}
|
|
27
|
+
export { ToggleButton, ToggleButtonGroup, toggleButtonVariants };
|
|
28
|
+
//# sourceMappingURL=ToggleButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleButton.d.ts","sourceRoot":"","sources":["../../src/primitives/ToggleButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,oBAAoB;;8EAYzB,CAAC;AAYF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EACrC,UAAU,GAAG,OAAO,GAAG,cAAc,CACtC,GAAG;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;IACxC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1D,IAAI,CAAC,EAAE,YAAY,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CACzC,CAAC;AAEF,iBAAS,iBAAiB,CAAC,EACzB,SAAiB,EACjB,KAAK,EAAE,SAAS,EAChB,YAAY,EACZ,aAAa,EACb,IAAW,EACX,QAAgB,EAChB,WAA0B,EAC1B,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,sBAAsB,qBAmCxB;kBA9CQ,iBAAiB;;;AAiD1B,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GACrF,YAAY,CAAC,OAAO,oBAAoB,CAAC,GAAG;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEJ,iBAAS,YAAY,CAAC,EACpB,KAAK,EACL,QAAQ,EACR,IAAI,EAAE,QAAQ,EACd,SAAS,EACT,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAsCnB;kBA/CQ,YAAY;;;AAkDrB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { useControllableState } from "../lib/use-controllable-state";
|
|
5
|
+
import { cn } from "../lib/cn";
|
|
6
|
+
const toggleButtonVariants = cva("inline-flex items-center justify-center gap-1.5 border text-sm font-bold outline-none transition-colors focus-visible:z-10 focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-40 [&_svg]:size-4", {
|
|
7
|
+
variants: {
|
|
8
|
+
size: {
|
|
9
|
+
sm: "h-8 px-2.5 text-xs",
|
|
10
|
+
md: "h-9 px-3",
|
|
11
|
+
lg: "h-10 px-4",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: { size: "md" },
|
|
15
|
+
});
|
|
16
|
+
const ToggleGroupContext = React.createContext(null);
|
|
17
|
+
function ToggleButtonGroup({ exclusive = false, value: valueProp, defaultValue, onValueChange, size = "md", disabled = false, orientation = "horizontal", className, children, ...props }) {
|
|
18
|
+
const [value, setValue] = useControllableState({
|
|
19
|
+
prop: valueProp,
|
|
20
|
+
defaultProp: defaultValue ?? (exclusive ? null : []),
|
|
21
|
+
onChange: onValueChange,
|
|
22
|
+
});
|
|
23
|
+
const setFromChild = (next) => {
|
|
24
|
+
if (disabled)
|
|
25
|
+
return;
|
|
26
|
+
setValue((prev) => {
|
|
27
|
+
if (exclusive)
|
|
28
|
+
return prev === next ? null : next;
|
|
29
|
+
const list = Array.isArray(prev) ? prev : prev ? [prev] : [];
|
|
30
|
+
return list.includes(next) ? list.filter((v) => v !== next) : [...list, next];
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
return (_jsx(ToggleGroupContext.Provider, { value: { exclusive, value: value ?? null, setValue: setFromChild, size: size ?? "md", disabled }, children: _jsx("div", { role: "group", "data-slot": "toggle-button-group", "data-orientation": orientation, className: cn("inline-flex isolate", orientation === "vertical" ? "flex-col" : "flex-row", className), ...props, children: children }) }));
|
|
34
|
+
}
|
|
35
|
+
ToggleButtonGroup.displayName = "ToggleButtonGroup";
|
|
36
|
+
function ToggleButton({ value, selected, size: sizeProp, className, disabled, onClick, children, ...props }) {
|
|
37
|
+
const ctx = React.useContext(ToggleGroupContext);
|
|
38
|
+
const size = sizeProp ?? ctx?.size ?? "md";
|
|
39
|
+
const isSelected = selected ??
|
|
40
|
+
(ctx
|
|
41
|
+
? Array.isArray(ctx.value)
|
|
42
|
+
? ctx.value.includes(value)
|
|
43
|
+
: ctx.value === value
|
|
44
|
+
: false);
|
|
45
|
+
const isDisabled = disabled || ctx?.disabled;
|
|
46
|
+
return (_jsx("button", { type: "button", "data-slot": "toggle-button", "data-state": isSelected ? "on" : "off", "aria-pressed": isSelected, disabled: isDisabled, className: cn(toggleButtonVariants({ size }), isSelected
|
|
47
|
+
? "z-[1] border-primary/50 bg-primary/15 text-primary"
|
|
48
|
+
: "border-border/60 bg-background/80 text-foreground hover:bg-muted/40", ctx && "first:rounded-l-lg last:rounded-r-lg [&:not(:first-child)]:rounded-l-none [&:not(:last-child)]:rounded-r-none [&:not(:first-child)]:-ml-px", !ctx && "rounded-lg", className), onClick: (event) => {
|
|
49
|
+
onClick?.(event);
|
|
50
|
+
if (event.defaultPrevented || isDisabled)
|
|
51
|
+
return;
|
|
52
|
+
ctx?.setValue(value);
|
|
53
|
+
}, ...props, children: children }));
|
|
54
|
+
}
|
|
55
|
+
ToggleButton.displayName = "ToggleButton";
|
|
56
|
+
export { ToggleButton, ToggleButtonGroup, toggleButtonVariants };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type TransferListProps = {
|
|
3
|
+
left: string[];
|
|
4
|
+
right: string[];
|
|
5
|
+
onChange?: (next: {
|
|
6
|
+
left: string[];
|
|
7
|
+
right: string[];
|
|
8
|
+
}) => void;
|
|
9
|
+
leftTitle?: string;
|
|
10
|
+
rightTitle?: string;
|
|
11
|
+
className?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Two-list shuttle for picking items — MUI Transfer List analogue.
|
|
15
|
+
*/
|
|
16
|
+
declare function TransferList({ left, right, onChange, leftTitle, rightTitle, className, }: TransferListProps): React.JSX.Element;
|
|
17
|
+
declare namespace TransferList {
|
|
18
|
+
var displayName: string;
|
|
19
|
+
}
|
|
20
|
+
export { TransferList };
|
|
21
|
+
//# sourceMappingURL=TransferList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TransferList.d.ts","sourceRoot":"","sources":["../../src/primitives/TransferList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAgDF;;GAEG;AACH,iBAAS,YAAY,CAAC,EACpB,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,SAAqB,EACrB,UAAqB,EACrB,SAAS,GACV,EAAE,iBAAiB,qBAkCnB;kBAzCQ,YAAY;;;AA4CrB,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
4
|
+
import { cn } from "../lib/cn";
|
|
5
|
+
import { Button } from "./Button";
|
|
6
|
+
import { List, ListItemButton, ListItemIcon, ListItemText } from "./List";
|
|
7
|
+
import { Paper } from "./Paper";
|
|
8
|
+
function move(source, target, picked) {
|
|
9
|
+
return {
|
|
10
|
+
source: source.filter((item) => !picked.includes(item)),
|
|
11
|
+
target: [...target, ...source.filter((item) => picked.includes(item))],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function Column({ title, items, checked, onToggle, }) {
|
|
15
|
+
return (_jsxs(Paper, { variant: "outlined", className: "min-w-40 flex-1 overflow-hidden", children: [_jsx("div", { className: "border-b border-border/40 px-3 py-2 text-xs font-black uppercase tracking-widest text-muted-foreground", children: title }), _jsx(List, { dense: true, disablePadding: true, className: "max-h-48 overflow-auto", children: items.map((item) => (_jsxs(ListItemButton, { selected: checked.includes(item), onClick: () => onToggle(item), children: [_jsx(ListItemIcon, { children: _jsx("span", { className: cn("size-3.5 rounded-sm border", checked.includes(item) ? "border-primary bg-primary" : "border-border") }) }), _jsx(ListItemText, { primary: item })] }, item))) })] }));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Two-list shuttle for picking items — MUI Transfer List analogue.
|
|
19
|
+
*/
|
|
20
|
+
function TransferList({ left, right, onChange, leftTitle = "Choices", rightTitle = "Chosen", className, }) {
|
|
21
|
+
const [checkedLeft, setCheckedLeft] = React.useState([]);
|
|
22
|
+
const [checkedRight, setCheckedRight] = React.useState([]);
|
|
23
|
+
const toggle = (item, side) => {
|
|
24
|
+
const setter = side === "left" ? setCheckedLeft : setCheckedRight;
|
|
25
|
+
setter((prev) => (prev.includes(item) ? prev.filter((x) => x !== item) : [...prev, item]));
|
|
26
|
+
};
|
|
27
|
+
const toRight = () => {
|
|
28
|
+
const next = move(left, right, checkedLeft);
|
|
29
|
+
onChange?.({ left: next.source, right: next.target });
|
|
30
|
+
setCheckedLeft([]);
|
|
31
|
+
};
|
|
32
|
+
const toLeft = () => {
|
|
33
|
+
const next = move(right, left, checkedRight);
|
|
34
|
+
onChange?.({ left: next.target, right: next.source });
|
|
35
|
+
setCheckedRight([]);
|
|
36
|
+
};
|
|
37
|
+
return (_jsxs("div", { "data-slot": "transfer-list", className: cn("flex items-center gap-3", className), children: [_jsx(Column, { title: leftTitle, items: left, checked: checkedLeft, onToggle: (item) => toggle(item, "left") }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Button, { size: "sm", variant: "outline", disabled: !checkedLeft.length, onClick: toRight, "aria-label": "Move right", children: _jsx(ChevronRight, { className: "size-4" }) }), _jsx(Button, { size: "sm", variant: "outline", disabled: !checkedRight.length, onClick: toLeft, "aria-label": "Move left", children: _jsx(ChevronLeft, { className: "size-4" }) })] }), _jsx(Column, { title: rightTitle, items: right, checked: checkedRight, onToggle: (item) => toggle(item, "right") })] }));
|
|
38
|
+
}
|
|
39
|
+
TransferList.displayName = "TransferList";
|
|
40
|
+
export { TransferList };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type VariantProps } from "class-variance-authority";
|
|
3
|
+
declare const typographyVariants: (props?: ({
|
|
4
|
+
variant?: "overline" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | null | undefined;
|
|
5
|
+
color?: "inherit" | "default" | "primary" | "muted" | null | undefined;
|
|
6
|
+
align?: "inherit" | "center" | "left" | "right" | null | undefined;
|
|
7
|
+
gutterBottom?: boolean | null | undefined;
|
|
8
|
+
noWrap?: boolean | null | undefined;
|
|
9
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
10
|
+
export type TypographyProps = Omit<React.ComponentPropsWithoutRef<"p">, "color"> & VariantProps<typeof typographyVariants> & {
|
|
11
|
+
component?: React.ElementType;
|
|
12
|
+
};
|
|
13
|
+
declare const Typography: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref">, "color"> & VariantProps<(props?: ({
|
|
14
|
+
variant?: "overline" | "caption" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | null | undefined;
|
|
15
|
+
color?: "inherit" | "default" | "primary" | "muted" | null | undefined;
|
|
16
|
+
align?: "inherit" | "center" | "left" | "right" | null | undefined;
|
|
17
|
+
gutterBottom?: boolean | null | undefined;
|
|
18
|
+
noWrap?: boolean | null | undefined;
|
|
19
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & {
|
|
20
|
+
component?: React.ElementType;
|
|
21
|
+
} & React.RefAttributes<HTMLElement>>;
|
|
22
|
+
export { Typography, typographyVariants };
|
|
23
|
+
//# sourceMappingURL=Typography.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Typography.d.ts","sourceRoot":"","sources":["../../src/primitives/Typography.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,QAAA,MAAM,kBAAkB;;;;;;8EA4CtB,CAAC;AAoBH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,GAC9E,YAAY,CAAC,OAAO,kBAAkB,CAAC,GAAG;IACxC,SAAS,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;CAC/B,CAAC;AAEJ,QAAA,MAAM,UAAU;;;;;;;gBAHA,KAAK,CAAC,WAAW;qCAgBhC,CAAC;AAGF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { cn } from "../lib/cn";
|
|
5
|
+
const typographyVariants = cva("text-foreground", {
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
h1: "text-4xl font-black tracking-tight",
|
|
9
|
+
h2: "text-3xl font-black tracking-tight",
|
|
10
|
+
h3: "text-2xl font-bold tracking-tight",
|
|
11
|
+
h4: "text-xl font-bold",
|
|
12
|
+
h5: "text-lg font-bold",
|
|
13
|
+
h6: "text-base font-bold",
|
|
14
|
+
subtitle1: "text-base font-semibold",
|
|
15
|
+
subtitle2: "text-sm font-semibold",
|
|
16
|
+
body1: "text-base font-medium leading-relaxed",
|
|
17
|
+
body2: "text-sm font-medium leading-relaxed",
|
|
18
|
+
caption: "text-xs font-medium text-muted-foreground",
|
|
19
|
+
overline: "text-[10px] font-black uppercase tracking-widest text-muted-foreground",
|
|
20
|
+
},
|
|
21
|
+
color: {
|
|
22
|
+
default: "",
|
|
23
|
+
muted: "text-muted-foreground",
|
|
24
|
+
primary: "text-primary",
|
|
25
|
+
inherit: "text-inherit",
|
|
26
|
+
},
|
|
27
|
+
align: {
|
|
28
|
+
inherit: "",
|
|
29
|
+
left: "text-left",
|
|
30
|
+
center: "text-center",
|
|
31
|
+
right: "text-right",
|
|
32
|
+
},
|
|
33
|
+
gutterBottom: {
|
|
34
|
+
true: "mb-2",
|
|
35
|
+
false: "",
|
|
36
|
+
},
|
|
37
|
+
noWrap: {
|
|
38
|
+
true: "truncate",
|
|
39
|
+
false: "",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
defaultVariants: {
|
|
43
|
+
variant: "body1",
|
|
44
|
+
color: "default",
|
|
45
|
+
align: "inherit",
|
|
46
|
+
gutterBottom: false,
|
|
47
|
+
noWrap: false,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
const variantElement = {
|
|
51
|
+
h1: "h1",
|
|
52
|
+
h2: "h2",
|
|
53
|
+
h3: "h3",
|
|
54
|
+
h4: "h4",
|
|
55
|
+
h5: "h5",
|
|
56
|
+
h6: "h6",
|
|
57
|
+
subtitle1: "h6",
|
|
58
|
+
subtitle2: "h6",
|
|
59
|
+
body1: "p",
|
|
60
|
+
body2: "p",
|
|
61
|
+
caption: "span",
|
|
62
|
+
overline: "span",
|
|
63
|
+
};
|
|
64
|
+
const Typography = React.forwardRef(({ className, variant = "body1", color, align, gutterBottom, noWrap, component, ...props }, ref) => {
|
|
65
|
+
const Comp = (component ?? variantElement[variant ?? "body1"]);
|
|
66
|
+
return (_jsx(Comp, { ref: ref, "data-slot": "typography", "data-variant": variant, className: cn(typographyVariants({ variant, color, align, gutterBottom, noWrap }), className), ...props }));
|
|
67
|
+
});
|
|
68
|
+
Typography.displayName = "Typography";
|
|
69
|
+
export { Typography, typographyVariants };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type TransitionProps = Omit<React.ComponentPropsWithoutRef<"div">, "in"> & {
|
|
3
|
+
in?: boolean;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
unmountOnExit?: boolean;
|
|
6
|
+
appear?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare function Fade({ in: open, unmountOnExit, className, children, ...props }: TransitionProps): React.JSX.Element | null;
|
|
9
|
+
declare namespace Fade {
|
|
10
|
+
var displayName: string;
|
|
11
|
+
}
|
|
12
|
+
declare function Grow({ in: open, unmountOnExit, className, children, ...props }: TransitionProps): React.JSX.Element | null;
|
|
13
|
+
declare namespace Grow {
|
|
14
|
+
var displayName: string;
|
|
15
|
+
}
|
|
16
|
+
export type SlideProps = TransitionProps & {
|
|
17
|
+
direction?: "up" | "down" | "left" | "right";
|
|
18
|
+
};
|
|
19
|
+
declare function Slide({ in: open, direction, unmountOnExit, className, children, ...props }: SlideProps): React.JSX.Element | null;
|
|
20
|
+
declare namespace Slide {
|
|
21
|
+
var displayName: string;
|
|
22
|
+
}
|
|
23
|
+
declare function Zoom({ in: open, unmountOnExit, className, children, ...props }: TransitionProps): React.JSX.Element | null;
|
|
24
|
+
declare namespace Zoom {
|
|
25
|
+
var displayName: string;
|
|
26
|
+
}
|
|
27
|
+
export { Fade, Grow, Slide, Zoom };
|
|
28
|
+
export type { TransitionProps };
|
|
29
|
+
//# sourceMappingURL=transitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transitions.d.ts","sourceRoot":"","sources":["../../src/primitives/transitions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,KAAK,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG;IACzE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAgBF,iBAAS,IAAI,CAAC,EAAE,EAAE,EAAE,IAAY,EAAE,aAAqB,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,4BAgBxG;kBAhBQ,IAAI;;;AAmBb,iBAAS,IAAI,CAAC,EAAE,EAAE,EAAE,IAAY,EAAE,aAAqB,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,4BAgBxG;kBAhBQ,IAAI;;;AAmBb,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG;IACzC,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC9C,CAAC;AASF,iBAAS,KAAK,CAAC,EACb,EAAE,EAAE,IAAY,EAChB,SAAgB,EAChB,aAAqB,EACrB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,UAAU,4BAgBZ;kBAvBQ,KAAK;;;AA0Bd,iBAAS,IAAI,CAAC,EAAE,EAAE,EAAE,IAAY,EAAE,aAAqB,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,4BAgBxG;kBAhBQ,IAAI;;;AAmBb,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACnC,YAAY,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../lib/cn";
|
|
4
|
+
function useTransitionVisible(open, unmountOnExit) {
|
|
5
|
+
const [present, setPresent] = React.useState(open);
|
|
6
|
+
React.useEffect(() => {
|
|
7
|
+
if (open) {
|
|
8
|
+
setPresent(true);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (!unmountOnExit)
|
|
12
|
+
return;
|
|
13
|
+
const id = window.setTimeout(() => setPresent(false), 220);
|
|
14
|
+
return () => window.clearTimeout(id);
|
|
15
|
+
}, [open, unmountOnExit]);
|
|
16
|
+
return present;
|
|
17
|
+
}
|
|
18
|
+
function Fade({ in: open = false, unmountOnExit = false, className, children, ...props }) {
|
|
19
|
+
const present = useTransitionVisible(open, unmountOnExit);
|
|
20
|
+
if (!present)
|
|
21
|
+
return null;
|
|
22
|
+
return (_jsx("div", { "data-slot": "fade", className: cn("transition-opacity duration-200 ease-out", open ? "opacity-100" : "opacity-0", className), ...props, children: children }));
|
|
23
|
+
}
|
|
24
|
+
Fade.displayName = "Fade";
|
|
25
|
+
function Grow({ in: open = false, unmountOnExit = false, className, children, ...props }) {
|
|
26
|
+
const present = useTransitionVisible(open, unmountOnExit);
|
|
27
|
+
if (!present)
|
|
28
|
+
return null;
|
|
29
|
+
return (_jsx("div", { "data-slot": "grow", className: cn("origin-center transition-[opacity,transform] duration-200 ease-out", open ? "scale-100 opacity-100" : "scale-90 opacity-0", className), ...props, children: children }));
|
|
30
|
+
}
|
|
31
|
+
Grow.displayName = "Grow";
|
|
32
|
+
const slideClosed = {
|
|
33
|
+
up: "translate-y-4 opacity-0",
|
|
34
|
+
down: "-translate-y-4 opacity-0",
|
|
35
|
+
left: "translate-x-4 opacity-0",
|
|
36
|
+
right: "-translate-x-4 opacity-0",
|
|
37
|
+
};
|
|
38
|
+
function Slide({ in: open = false, direction = "up", unmountOnExit = false, className, children, ...props }) {
|
|
39
|
+
const present = useTransitionVisible(open, unmountOnExit);
|
|
40
|
+
if (!present)
|
|
41
|
+
return null;
|
|
42
|
+
return (_jsx("div", { "data-slot": "slide", className: cn("transition-[opacity,transform] duration-200 ease-out", open ? "translate-x-0 translate-y-0 opacity-100" : slideClosed[direction], className), ...props, children: children }));
|
|
43
|
+
}
|
|
44
|
+
Slide.displayName = "Slide";
|
|
45
|
+
function Zoom({ in: open = false, unmountOnExit = false, className, children, ...props }) {
|
|
46
|
+
const present = useTransitionVisible(open, unmountOnExit);
|
|
47
|
+
if (!present)
|
|
48
|
+
return null;
|
|
49
|
+
return (_jsx("div", { "data-slot": "zoom", className: cn("origin-center transition-[opacity,transform] duration-200 ease-out", open ? "scale-100 opacity-100" : "scale-75 opacity-0", className), ...props, children: children }));
|
|
50
|
+
}
|
|
51
|
+
Zoom.displayName = "Zoom";
|
|
52
|
+
export { Fade, Grow, Slide, Zoom };
|
package/package.json
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spatika/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"description": "Spatika React primitives and composites",
|
|
5
|
+
"description": "Spatika UI — glass React primitives and composites for production apps",
|
|
6
|
+
"homepage": "https://spatika.sreelal.me",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/SreelalChalil/spatika",
|
|
10
|
+
"directory": "packages/react"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/SreelalChalil/spatika/issues"
|
|
14
|
+
},
|
|
15
|
+
"author": "Sreelal Chalil",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"spatika",
|
|
18
|
+
"spatika-ui",
|
|
19
|
+
"spadik",
|
|
20
|
+
"spadik-ui",
|
|
21
|
+
"react",
|
|
22
|
+
"design-system",
|
|
23
|
+
"component-library",
|
|
24
|
+
"glass",
|
|
25
|
+
"glassmorphism",
|
|
26
|
+
"ui"
|
|
27
|
+
],
|
|
6
28
|
"type": "module",
|
|
7
29
|
"sideEffects": false,
|
|
8
30
|
"main": "./dist/index.js",
|
|
@@ -18,7 +40,9 @@
|
|
|
18
40
|
},
|
|
19
41
|
"files": [
|
|
20
42
|
"dist",
|
|
21
|
-
"src"
|
|
43
|
+
"src",
|
|
44
|
+
"AGENTS.md",
|
|
45
|
+
"skills"
|
|
22
46
|
],
|
|
23
47
|
"scripts": {
|
|
24
48
|
"build": "tsc -p tsconfig.build.json",
|
|
@@ -35,7 +59,7 @@
|
|
|
35
59
|
"react-dom": "^18.2.0 || ^19.0.0"
|
|
36
60
|
},
|
|
37
61
|
"dependencies": {
|
|
38
|
-
"@spatika/tokens": "1.
|
|
62
|
+
"@spatika/tokens": "1.2.0",
|
|
39
63
|
"class-variance-authority": "^0.7.1",
|
|
40
64
|
"clsx": "^2.1.1",
|
|
41
65
|
"cmdk": "^1.1.1",
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spatika-ui
|
|
3
|
+
description: Build UI with Spatika glass React components from @spatika/react. Use when adding pages, forms, app chrome, dialogs, charts, or when the user mentions Spatika, Spadik, @spatika/react, glass UI, or the Spatika design system.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Spatika UI
|
|
7
|
+
|
|
8
|
+
Glass React design system. Never invent Spatika components. Import from `@spatika/react`. Fetch https://spatika.sreelal.me/llms.txt for the live catalog.
|
|
9
|
+
|
|
10
|
+
## Bootstrap
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @spatika/tokens @spatika/react
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import "@spatika/tokens/styles.css";
|
|
18
|
+
import { SpatikaThemeProvider, Button } from "@spatika/react";
|
|
19
|
+
|
|
20
|
+
export function App() {
|
|
21
|
+
return (
|
|
22
|
+
<SpatikaThemeProvider defaultTheme="neelam">
|
|
23
|
+
<Button>Hello Spatika</Button>
|
|
24
|
+
</SpatikaThemeProvider>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Rules
|
|
30
|
+
|
|
31
|
+
- Import `@spatika/tokens/styles.css` before any component
|
|
32
|
+
- Wrap the tree in `SpatikaThemeProvider`
|
|
33
|
+
- Themes: `mukta` | `neelam` | `usha` | `sandhya`
|
|
34
|
+
- Prefer composites over restyling primitives
|
|
35
|
+
- Token CSS variables only — no hardcoded hex
|
|
36
|
+
- `size="touch"` on mobile primary actions
|
|
37
|
+
- Never `transition-all` on glass
|
|
38
|
+
|
|
39
|
+
## Pick a component
|
|
40
|
+
|
|
41
|
+
| Need | Use |
|
|
42
|
+
|---|---|
|
|
43
|
+
| Page frame | `PageShell` |
|
|
44
|
+
| Directory chrome | `FloatingPageChromeBar` + `FloatingPageChromeIdentity` |
|
|
45
|
+
| Safe-area bar | `AppHeader variant="chrome"` |
|
|
46
|
+
| Mobile tabs | `MobileTabBar` |
|
|
47
|
+
| Cover / profile | `CoverHero` / `ProfileHero` + `useCoverChromeBleed` |
|
|
48
|
+
| Glass panel | `GlassCard` |
|
|
49
|
+
| Labeled field | `TextField` |
|
|
50
|
+
| Filters | `FilterSheet` + `ChipGroup` |
|
|
51
|
+
| Empty | `EmptyState` |
|
|
52
|
+
| Modal | `Dialog` |
|
|
53
|
+
| Toasts | `Toaster` + `useToast` |
|
|
54
|
+
| Chart | `BarChart` / `LineChart` / `ChartContainer` |
|
|
55
|
+
| Calendar | `EventCalendar` |
|
|
56
|
+
|
|
57
|
+
## App shell
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import {
|
|
61
|
+
AppHeader,
|
|
62
|
+
Button,
|
|
63
|
+
FloatingPageChromeBar,
|
|
64
|
+
FloatingPageChromeIdentity,
|
|
65
|
+
FloatingPageChromeSearchField,
|
|
66
|
+
MobileTabBar,
|
|
67
|
+
PageShell,
|
|
68
|
+
} from "@spatika/react";
|
|
69
|
+
import { Home, Search, User } from "lucide-react";
|
|
70
|
+
|
|
71
|
+
<PageShell>
|
|
72
|
+
<AppHeader variant="chrome" title="Spatika" />
|
|
73
|
+
<FloatingPageChromeBar
|
|
74
|
+
identity={<FloatingPageChromeIdentity title="Leads" count={128} />}
|
|
75
|
+
search={
|
|
76
|
+
<FloatingPageChromeSearchField value={query} onChange={setQuery} placeholder="Search…" />
|
|
77
|
+
}
|
|
78
|
+
actions={<Button size="sm">New</Button>}
|
|
79
|
+
>
|
|
80
|
+
<main className="app-tabbar-clearance px-4 py-6">{children}</main>
|
|
81
|
+
</FloatingPageChromeBar>
|
|
82
|
+
<MobileTabBar
|
|
83
|
+
items={[
|
|
84
|
+
{ id: "home", label: "Home", icon: Home, active: true },
|
|
85
|
+
{ id: "search", label: "Search", icon: Search },
|
|
86
|
+
{ id: "you", label: "You", icon: User },
|
|
87
|
+
]}
|
|
88
|
+
/>
|
|
89
|
+
</PageShell>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Next
|
|
93
|
+
|
|
94
|
+
1. Fetch the component markdown: `https://spatika.sreelal.me/docs/{slug}.md`
|
|
95
|
+
2. Read prop types from `node_modules/@spatika/react/dist/index.d.ts`
|
|
96
|
+
3. Icons in examples use `lucide-react`
|
package/src/composites/Card.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
2
|
import { cn } from "../lib/cn";
|
|
3
3
|
|
|
4
4
|
export type CardProps = {
|
|
@@ -101,6 +101,56 @@ export function CardContent({
|
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
export function CardActionArea({
|
|
105
|
+
className,
|
|
106
|
+
children,
|
|
107
|
+
...props
|
|
108
|
+
}: ComponentPropsWithoutRef<"button">) {
|
|
109
|
+
return (
|
|
110
|
+
<button
|
|
111
|
+
type="button"
|
|
112
|
+
data-slot="card-action-area"
|
|
113
|
+
className={cn(
|
|
114
|
+
"block w-full text-left outline-none transition-[transform,box-shadow] duration-150",
|
|
115
|
+
"hover:-translate-y-0.5 focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
116
|
+
className,
|
|
117
|
+
)}
|
|
118
|
+
{...props}
|
|
119
|
+
>
|
|
120
|
+
{children}
|
|
121
|
+
</button>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function CardMedia({
|
|
126
|
+
className,
|
|
127
|
+
component = "img",
|
|
128
|
+
image,
|
|
129
|
+
src,
|
|
130
|
+
alt,
|
|
131
|
+
height = 160,
|
|
132
|
+
...props
|
|
133
|
+
}: ComponentPropsWithoutRef<"img"> & {
|
|
134
|
+
component?: "img" | "div";
|
|
135
|
+
image?: string;
|
|
136
|
+
height?: number;
|
|
137
|
+
}) {
|
|
138
|
+
const Comp = component;
|
|
139
|
+
return (
|
|
140
|
+
<Comp
|
|
141
|
+
data-slot="card-media"
|
|
142
|
+
src={component === "img" ? (src ?? image) : undefined}
|
|
143
|
+
alt={alt}
|
|
144
|
+
className={cn("w-full object-cover", component === "div" && "bg-muted", className)}
|
|
145
|
+
style={{
|
|
146
|
+
height,
|
|
147
|
+
...(component === "div" && image ? { backgroundImage: `url(${image})`, backgroundSize: "cover" } : undefined),
|
|
148
|
+
}}
|
|
149
|
+
{...(props as ComponentPropsWithoutRef<"img">)}
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
104
154
|
export function CardFooter({
|
|
105
155
|
className,
|
|
106
156
|
children,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { render, screen } from "@testing-library/react";
|
|
2
|
+
import userEvent from "@testing-library/user-event";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { ChartDataGrid, renderChartCell } from "./ChartDataGrid";
|
|
5
|
+
|
|
6
|
+
describe("ChartDataGrid", () => {
|
|
7
|
+
it("renders a linked table and highlights a selected row", async () => {
|
|
8
|
+
const user = userEvent.setup();
|
|
9
|
+
const { container } = render(
|
|
10
|
+
<ChartDataGrid
|
|
11
|
+
height={140}
|
|
12
|
+
categoryField="name"
|
|
13
|
+
valueField="views"
|
|
14
|
+
rows={[
|
|
15
|
+
{ id: "web", name: "Web", views: 10, trend: [1, 2, 3] },
|
|
16
|
+
{ id: "ios", name: "iOS", views: 6, trend: [2, 2, 1] },
|
|
17
|
+
]}
|
|
18
|
+
columns={[
|
|
19
|
+
{ field: "name", headerName: "Channel" },
|
|
20
|
+
{ field: "views", headerName: "Views", type: "number" },
|
|
21
|
+
{ field: "trend", headerName: "Trend", type: "sparkline" },
|
|
22
|
+
]}
|
|
23
|
+
/>,
|
|
24
|
+
);
|
|
25
|
+
expect(container.querySelector('[data-slot="chart-data-grid"]')).toBeTruthy();
|
|
26
|
+
expect(screen.getByText("Channel")).toBeInTheDocument();
|
|
27
|
+
const row = container.querySelector(
|
|
28
|
+
'[data-slot="chart-data-grid"] tbody [data-slot="table-row"]:nth-child(2)',
|
|
29
|
+
);
|
|
30
|
+
await user.click(row!);
|
|
31
|
+
expect(row).toHaveAttribute("data-state", "selected");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("hides the chart when requested", () => {
|
|
35
|
+
const { container } = render(
|
|
36
|
+
<ChartDataGrid
|
|
37
|
+
hideChart
|
|
38
|
+
categoryField="name"
|
|
39
|
+
valueField="views"
|
|
40
|
+
rows={[{ id: "web", name: "Web", views: 10 }]}
|
|
41
|
+
columns={[{ field: "name", headerName: "Channel" }]}
|
|
42
|
+
/>,
|
|
43
|
+
);
|
|
44
|
+
expect(container.querySelector('[data-slot="chart-container"]')).toBeNull();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("renderChartCell", () => {
|
|
49
|
+
it("returns a dash for non-numeric values", () => {
|
|
50
|
+
expect(renderChartCell("n/a")).toBe("—");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("renders a sparkline for numeric arrays", () => {
|
|
54
|
+
const { container } = render(<>{renderChartCell([1, 4, 2], { variant: "sparkline" })}</>);
|
|
55
|
+
expect(container.querySelector('[data-slot="sparkline"]')).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
});
|