@tetherto/dev-websites-core 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -9
- package/dist/cms/index.d.mts +2 -2
- package/dist/cms/index.mjs +2 -2
- package/dist/{cms-5bS91IRZ.mjs → cms.mjs} +2 -2
- package/dist/cms.mjs.map +1 -0
- package/dist/i18n/index.d.mts +1 -1
- package/dist/i18n/index.mjs +1 -1
- package/dist/{i18n-Dy3VrbBw.mjs → i18n.mjs} +1 -1
- package/dist/i18n.mjs.map +1 -0
- package/dist/index.d.mts +214 -6
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +6 -6
- package/dist/{index-D36IEwUg.d.mts → index2.d.mts} +1 -1
- package/dist/index2.d.mts.map +1 -0
- package/dist/{index-tTs9h9BS.d.mts → index3.d.mts} +2 -2
- package/dist/index3.d.mts.map +1 -0
- package/dist/{index-Dyi7DDoO.d.mts → index4.d.mts} +1 -1
- package/dist/index4.d.mts.map +1 -0
- package/dist/index5.d.mts +6 -0
- package/dist/{logger-BPURnavq.mjs → logger.mjs} +1 -1
- package/dist/logger.mjs.map +1 -0
- package/dist/{readMediaBuffer-1C3QTpkO.d.mts → readMediaBuffer.d.mts} +1 -1
- package/dist/readMediaBuffer.d.mts.map +1 -0
- package/dist/{readMediaBuffer-DWkTbYVn.mjs → readMediaBuffer.mjs} +2 -2
- package/dist/readMediaBuffer.mjs.map +1 -0
- package/dist/seo/index.d.mts +1 -1
- package/dist/seo/index.mjs +1 -1
- package/dist/{seo-e5XjgQ7l.mjs → seo.mjs} +3 -3
- package/dist/seo.mjs.map +1 -0
- package/dist/ui/a11y/focus.d.mts +6 -0
- package/dist/ui/a11y/focus.d.mts.map +1 -0
- package/dist/ui/a11y/focus.mjs +7 -0
- package/dist/ui/a11y/focus.mjs.map +1 -0
- package/dist/ui/a11y/index.d.mts +4 -0
- package/dist/ui/a11y/index.mjs +4 -0
- package/dist/ui/carousel/index.d.mts +3 -0
- package/dist/ui/carousel/index.mjs +3 -0
- package/dist/ui/components/Accordion/Accordion.d.mts +16 -0
- package/dist/ui/components/Accordion/Accordion.d.mts.map +1 -0
- package/dist/ui/components/Accordion/Accordion.mjs +51 -0
- package/dist/ui/components/Accordion/Accordion.mjs.map +1 -0
- package/dist/ui/components/Accordion/index.d.mts +2 -0
- package/dist/ui/components/Accordion/index.mjs +2 -0
- package/dist/ui/components/Avatar/Avatar.d.mts +9 -0
- package/dist/ui/components/Avatar/Avatar.d.mts.map +1 -0
- package/dist/ui/components/Avatar/Avatar.mjs +15 -0
- package/dist/ui/components/Avatar/Avatar.mjs.map +1 -0
- package/dist/ui/components/Avatar/index.d.mts +2 -0
- package/dist/ui/components/Avatar/index.mjs +2 -0
- package/dist/ui/components/Badge/Badge.d.mts +14 -0
- package/dist/ui/components/Badge/Badge.d.mts.map +1 -0
- package/dist/ui/components/Badge/Badge.mjs +30 -0
- package/dist/ui/components/Badge/Badge.mjs.map +1 -0
- package/dist/ui/components/Badge/index.d.mts +2 -0
- package/dist/ui/components/Badge/index.mjs +2 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.d.mts +24 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.d.mts.map +1 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.mjs +66 -0
- package/dist/ui/components/BadgeVersion/BadgeVersion.mjs.map +1 -0
- package/dist/ui/components/BadgeVersion/index.d.mts +2 -0
- package/dist/ui/components/BadgeVersion/index.mjs +2 -0
- package/dist/ui/components/Button/Button.d.mts +14 -0
- package/dist/ui/components/Button/Button.d.mts.map +1 -0
- package/dist/ui/components/Button/Button.mjs +48 -0
- package/dist/ui/components/Button/Button.mjs.map +1 -0
- package/dist/ui/components/Button/index.d.mts +2 -0
- package/dist/ui/components/Button/index.mjs +2 -0
- package/dist/ui/components/Card/Card.d.mts +14 -0
- package/dist/ui/components/Card/Card.d.mts.map +1 -0
- package/dist/ui/components/Card/Card.mjs +40 -0
- package/dist/ui/components/Card/Card.mjs.map +1 -0
- package/dist/ui/components/Card/index.d.mts +2 -0
- package/dist/ui/components/Card/index.mjs +2 -0
- package/dist/ui/components/Carousel/Carousel.d.mts +42 -0
- package/dist/ui/components/Carousel/Carousel.d.mts.map +1 -0
- package/dist/ui/components/Carousel/Carousel.mjs +164 -0
- package/dist/ui/components/Carousel/Carousel.mjs.map +1 -0
- package/dist/ui/components/Carousel/index.d.mts +2 -0
- package/dist/ui/components/Carousel/index.mjs +2 -0
- package/dist/ui/components/Checkbox/Checkbox.d.mts +8 -0
- package/dist/ui/components/Checkbox/Checkbox.d.mts.map +1 -0
- package/dist/ui/components/Checkbox/Checkbox.mjs +39 -0
- package/dist/ui/components/Checkbox/Checkbox.mjs.map +1 -0
- package/dist/ui/components/Checkbox/index.d.mts +2 -0
- package/dist/ui/components/Checkbox/index.mjs +2 -0
- package/dist/ui/components/CodeBlock/CodeBlock.d.mts +22 -0
- package/dist/ui/components/CodeBlock/CodeBlock.d.mts.map +1 -0
- package/dist/ui/components/CodeBlock/CodeBlock.mjs +66 -0
- package/dist/ui/components/CodeBlock/CodeBlock.mjs.map +1 -0
- package/dist/ui/components/CodeBlock/index.d.mts +2 -0
- package/dist/ui/components/CodeBlock/index.mjs +2 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.d.mts +19 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.d.mts.map +1 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.mjs +59 -0
- package/dist/ui/components/CodeBlockTabs/CodeBlockTabs.mjs.map +1 -0
- package/dist/ui/components/CodeBlockTabs/index.d.mts +2 -0
- package/dist/ui/components/CodeBlockTabs/index.mjs +2 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.d.mts +13 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.d.mts.map +1 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.mjs +55 -0
- package/dist/ui/components/CollapsibleSection/CollapsibleSection.mjs.map +1 -0
- package/dist/ui/components/CollapsibleSection/index.d.mts +2 -0
- package/dist/ui/components/CollapsibleSection/index.mjs +2 -0
- package/dist/ui/components/CopyButton/CopyButton.d.mts +12 -0
- package/dist/ui/components/CopyButton/CopyButton.d.mts.map +1 -0
- package/dist/ui/components/CopyButton/CopyButton.mjs +45 -0
- package/dist/ui/components/CopyButton/CopyButton.mjs.map +1 -0
- package/dist/ui/components/CopyButton/index.d.mts +2 -0
- package/dist/ui/components/CopyButton/index.mjs +2 -0
- package/dist/ui/components/Dialog/Dialog.d.mts +26 -0
- package/dist/ui/components/Dialog/Dialog.d.mts.map +1 -0
- package/dist/ui/components/Dialog/Dialog.mjs +79 -0
- package/dist/ui/components/Dialog/Dialog.mjs.map +1 -0
- package/dist/ui/components/Dialog/index.d.mts +2 -0
- package/dist/ui/components/Dialog/index.mjs +2 -0
- package/dist/ui/components/EmptyState/EmptyState.d.mts +18 -0
- package/dist/ui/components/EmptyState/EmptyState.d.mts.map +1 -0
- package/dist/ui/components/EmptyState/EmptyState.mjs +36 -0
- package/dist/ui/components/EmptyState/EmptyState.mjs.map +1 -0
- package/dist/ui/components/EmptyState/index.d.mts +2 -0
- package/dist/ui/components/EmptyState/index.mjs +2 -0
- package/dist/ui/components/FieldError/FieldError.d.mts +14 -0
- package/dist/ui/components/FieldError/FieldError.d.mts.map +1 -0
- package/dist/ui/components/FieldError/FieldError.mjs +19 -0
- package/dist/ui/components/FieldError/FieldError.mjs.map +1 -0
- package/dist/ui/components/FieldError/index.d.mts +2 -0
- package/dist/ui/components/FieldError/index.mjs +2 -0
- package/dist/ui/components/FormattedDate/FormattedDate.d.mts +15 -0
- package/dist/ui/components/FormattedDate/FormattedDate.d.mts.map +1 -0
- package/dist/ui/components/FormattedDate/FormattedDate.mjs +23 -0
- package/dist/ui/components/FormattedDate/FormattedDate.mjs.map +1 -0
- package/dist/ui/components/FormattedDate/index.d.mts +2 -0
- package/dist/ui/components/FormattedDate/index.mjs +2 -0
- package/dist/ui/components/IconButton/IconButton.d.mts +10 -0
- package/dist/ui/components/IconButton/IconButton.d.mts.map +1 -0
- package/dist/ui/components/IconButton/IconButton.mjs +19 -0
- package/dist/ui/components/IconButton/IconButton.mjs.map +1 -0
- package/dist/ui/components/IconButton/index.d.mts +2 -0
- package/dist/ui/components/IconButton/index.mjs +2 -0
- package/dist/ui/components/Input/Input.d.mts +12 -0
- package/dist/ui/components/Input/Input.d.mts.map +1 -0
- package/dist/ui/components/Input/Input.mjs +43 -0
- package/dist/ui/components/Input/Input.mjs.map +1 -0
- package/dist/ui/components/Input/index.d.mts +2 -0
- package/dist/ui/components/Input/index.mjs +2 -0
- package/dist/ui/components/Label/Label.d.mts +11 -0
- package/dist/ui/components/Label/Label.d.mts.map +1 -0
- package/dist/ui/components/Label/Label.mjs +18 -0
- package/dist/ui/components/Label/Label.mjs.map +1 -0
- package/dist/ui/components/Label/index.d.mts +2 -0
- package/dist/ui/components/Label/index.mjs +2 -0
- package/dist/ui/components/LazyVideo/LazyVideo.d.mts +23 -0
- package/dist/ui/components/LazyVideo/LazyVideo.d.mts.map +1 -0
- package/dist/ui/components/LazyVideo/LazyVideo.mjs +57 -0
- package/dist/ui/components/LazyVideo/LazyVideo.mjs.map +1 -0
- package/dist/ui/components/LazyVideo/index.d.mts +2 -0
- package/dist/ui/components/LazyVideo/index.mjs +2 -0
- package/dist/ui/components/Pagination/Pagination.d.mts +38 -0
- package/dist/ui/components/Pagination/Pagination.d.mts.map +1 -0
- package/dist/ui/components/Pagination/Pagination.mjs +110 -0
- package/dist/ui/components/Pagination/Pagination.mjs.map +1 -0
- package/dist/ui/components/Pagination/index.d.mts +2 -0
- package/dist/ui/components/Pagination/index.mjs +2 -0
- package/dist/ui/components/PaginationItem/PaginationItem.d.mts +15 -0
- package/dist/ui/components/PaginationItem/PaginationItem.d.mts.map +1 -0
- package/dist/ui/components/PaginationItem/PaginationItem.mjs +34 -0
- package/dist/ui/components/PaginationItem/PaginationItem.mjs.map +1 -0
- package/dist/ui/components/PaginationItem/index.d.mts +2 -0
- package/dist/ui/components/PaginationItem/index.mjs +2 -0
- package/dist/ui/components/PasswordInput/PasswordInput.d.mts +10 -0
- package/dist/ui/components/PasswordInput/PasswordInput.d.mts.map +1 -0
- package/dist/ui/components/PasswordInput/PasswordInput.mjs +39 -0
- package/dist/ui/components/PasswordInput/PasswordInput.mjs.map +1 -0
- package/dist/ui/components/PasswordInput/index.d.mts +2 -0
- package/dist/ui/components/PasswordInput/index.mjs +2 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.d.mts +20 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.d.mts.map +1 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.mjs +39 -0
- package/dist/ui/components/ProgressStepper/ProgressStepper.mjs.map +1 -0
- package/dist/ui/components/ProgressStepper/index.d.mts +2 -0
- package/dist/ui/components/ProgressStepper/index.mjs +2 -0
- package/dist/ui/components/Prose/Prose.d.mts +10 -0
- package/dist/ui/components/Prose/Prose.d.mts.map +1 -0
- package/dist/ui/components/Prose/Prose.mjs +19 -0
- package/dist/ui/components/Prose/Prose.mjs.map +1 -0
- package/dist/ui/components/Prose/index.d.mts +2 -0
- package/dist/ui/components/Prose/index.mjs +2 -0
- package/dist/ui/components/Radio/Radio.d.mts +8 -0
- package/dist/ui/components/Radio/Radio.d.mts.map +1 -0
- package/dist/ui/components/Radio/Radio.mjs +25 -0
- package/dist/ui/components/Radio/Radio.mjs.map +1 -0
- package/dist/ui/components/Radio/index.d.mts +2 -0
- package/dist/ui/components/Radio/index.mjs +2 -0
- package/dist/ui/components/Reveal/Reveal.d.mts +10 -0
- package/dist/ui/components/Reveal/Reveal.d.mts.map +1 -0
- package/dist/ui/components/Reveal/Reveal.mjs +18 -0
- package/dist/ui/components/Reveal/Reveal.mjs.map +1 -0
- package/dist/ui/components/Reveal/index.d.mts +2 -0
- package/dist/ui/components/Reveal/index.mjs +2 -0
- package/dist/ui/components/SearchInput/SearchInput.d.mts +15 -0
- package/dist/ui/components/SearchInput/SearchInput.d.mts.map +1 -0
- package/dist/ui/components/SearchInput/SearchInput.mjs +28 -0
- package/dist/ui/components/SearchInput/SearchInput.mjs.map +1 -0
- package/dist/ui/components/SearchInput/index.d.mts +2 -0
- package/dist/ui/components/SearchInput/index.mjs +2 -0
- package/dist/ui/components/Select/Select.d.mts +34 -0
- package/dist/ui/components/Select/Select.d.mts.map +1 -0
- package/dist/ui/components/Select/Select.mjs +167 -0
- package/dist/ui/components/Select/Select.mjs.map +1 -0
- package/dist/ui/components/Select/index.d.mts +2 -0
- package/dist/ui/components/Select/index.mjs +2 -0
- package/dist/ui/components/Sheet/Sheet.d.mts +19 -0
- package/dist/ui/components/Sheet/Sheet.d.mts.map +1 -0
- package/dist/ui/components/Sheet/Sheet.mjs +59 -0
- package/dist/ui/components/Sheet/Sheet.mjs.map +1 -0
- package/dist/ui/components/Sheet/index.d.mts +2 -0
- package/dist/ui/components/Sheet/index.mjs +2 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.d.mts +10 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.d.mts.map +1 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.mjs +31 -0
- package/dist/ui/components/StaggerReveal/StaggerReveal.mjs.map +1 -0
- package/dist/ui/components/StaggerReveal/index.d.mts +2 -0
- package/dist/ui/components/StaggerReveal/index.mjs +2 -0
- package/dist/ui/components/Stepper/Stepper.d.mts +15 -0
- package/dist/ui/components/Stepper/Stepper.d.mts.map +1 -0
- package/dist/ui/components/Stepper/Stepper.mjs +38 -0
- package/dist/ui/components/Stepper/Stepper.mjs.map +1 -0
- package/dist/ui/components/Stepper/index.d.mts +2 -0
- package/dist/ui/components/Stepper/index.mjs +2 -0
- package/dist/ui/components/Switch/Switch.d.mts +12 -0
- package/dist/ui/components/Switch/Switch.d.mts.map +1 -0
- package/dist/ui/components/Switch/Switch.mjs +34 -0
- package/dist/ui/components/Switch/Switch.mjs.map +1 -0
- package/dist/ui/components/Switch/index.d.mts +2 -0
- package/dist/ui/components/Switch/index.mjs +2 -0
- package/dist/ui/components/TextButton/TextButton.d.mts +9 -0
- package/dist/ui/components/TextButton/TextButton.d.mts.map +1 -0
- package/dist/ui/components/TextButton/TextButton.mjs +16 -0
- package/dist/ui/components/TextButton/TextButton.mjs.map +1 -0
- package/dist/ui/components/TextButton/index.d.mts +2 -0
- package/dist/ui/components/TextButton/index.mjs +2 -0
- package/dist/ui/components/Textarea/Textarea.d.mts +9 -0
- package/dist/ui/components/Textarea/Textarea.d.mts.map +1 -0
- package/dist/ui/components/Textarea/Textarea.mjs +27 -0
- package/dist/ui/components/Textarea/Textarea.mjs.map +1 -0
- package/dist/ui/components/Textarea/index.d.mts +2 -0
- package/dist/ui/components/Textarea/index.mjs +2 -0
- package/dist/ui/components/Toast/Toast.d.mts +20 -0
- package/dist/ui/components/Toast/Toast.d.mts.map +1 -0
- package/dist/ui/components/Toast/Toast.mjs +128 -0
- package/dist/ui/components/Toast/Toast.mjs.map +1 -0
- package/dist/ui/components/Toast/index.d.mts +2 -0
- package/dist/ui/components/Toast/index.mjs +2 -0
- package/dist/ui/components/Tooltip/Tooltip.d.mts +11 -0
- package/dist/ui/components/Tooltip/Tooltip.d.mts.map +1 -0
- package/dist/ui/components/Tooltip/Tooltip.mjs +20 -0
- package/dist/ui/components/Tooltip/Tooltip.mjs.map +1 -0
- package/dist/ui/components/Tooltip/index.d.mts +2 -0
- package/dist/ui/components/Tooltip/index.mjs +2 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.d.mts +7 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.d.mts.map +1 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.mjs +13 -0
- package/dist/ui/components/VisuallyHidden/VisuallyHidden.mjs.map +1 -0
- package/dist/ui/components/VisuallyHidden/index.d.mts +2 -0
- package/dist/ui/components/VisuallyHidden/index.mjs +2 -0
- package/dist/ui/hooks/index.d.mts +2 -0
- package/dist/ui/hooks/index.mjs +2 -0
- package/dist/ui/hooks/useInView.d.mts +13 -0
- package/dist/ui/hooks/useInView.d.mts.map +1 -0
- package/dist/ui/hooks/useInView.mjs +37 -0
- package/dist/ui/hooks/useInView.mjs.map +1 -0
- package/dist/ui/index.d.mts +81 -0
- package/dist/ui/index.mjs +40 -0
- package/dist/ui/theme/preset.d.mts +170 -0
- package/dist/ui/theme/preset.d.mts.map +1 -0
- package/dist/ui/theme/preset.mjs +143 -0
- package/dist/ui/theme/preset.mjs.map +1 -0
- package/dist/ui/utils/cn.d.mts +6 -0
- package/dist/ui/utils/cn.d.mts.map +1 -0
- package/dist/ui/utils/cn.mjs +42 -0
- package/dist/ui/utils/cn.mjs.map +1 -0
- package/dist/ui/utils/index.d.mts +2 -0
- package/dist/ui/utils/index.mjs +2 -0
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/index.mjs +2 -2
- package/dist/{utils-CVVQQltg.mjs → utils.mjs} +1 -1
- package/dist/utils.mjs.map +1 -0
- package/package.json +66 -7
- package/src/ui/theme/preset.css +53 -0
- package/src/ui/theme/preset.ts +131 -0
- package/src/ui/theme/theme.css +12 -0
- package/src/ui/theme/tokens.css +57 -0
- package/dist/cms-5bS91IRZ.mjs.map +0 -1
- package/dist/i18n-Dy3VrbBw.mjs.map +0 -1
- package/dist/index-9B8SfwdR.d.mts +0 -214
- package/dist/index-9B8SfwdR.d.mts.map +0 -1
- package/dist/index-D36IEwUg.d.mts.map +0 -1
- package/dist/index-Dyi7DDoO.d.mts.map +0 -1
- package/dist/index-tTs9h9BS.d.mts.map +0 -1
- package/dist/logger-BPURnavq.mjs.map +0 -1
- package/dist/readMediaBuffer-1C3QTpkO.d.mts.map +0 -1
- package/dist/readMediaBuffer-DWkTbYVn.mjs.map +0 -1
- package/dist/seo-e5XjgQ7l.mjs.map +0 -1
- package/dist/utils-CVVQQltg.mjs.map +0 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.mjs";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
//#region src/ui/components/Card/Card.tsx
|
|
7
|
+
const cardVariants = cva("rounded-card border", {
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
surface: "border-border bg-surface",
|
|
11
|
+
card: "border-border-subtle bg-card",
|
|
12
|
+
elevated: "border-border bg-card-elevated"
|
|
13
|
+
},
|
|
14
|
+
padding: {
|
|
15
|
+
none: "",
|
|
16
|
+
sm: "p-5",
|
|
17
|
+
md: "p-6",
|
|
18
|
+
lg: "p-6 sm:p-8"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
variant: "surface",
|
|
23
|
+
padding: "md"
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
function Card({ className, variant, padding, asChild = false, ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
|
|
28
|
+
"data-slot": "card",
|
|
29
|
+
"data-variant": variant,
|
|
30
|
+
className: cn(cardVariants({
|
|
31
|
+
variant,
|
|
32
|
+
padding
|
|
33
|
+
}), className),
|
|
34
|
+
...props
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Card, cardVariants };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=Card.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.mjs","names":[],"sources":["../../../../src/ui/components/Card/Card.tsx"],"sourcesContent":["'use client'\n\nimport { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '../../utils/cn.js'\n\nimport type { HTMLAttributes } from 'react'\n\nconst cardVariants = cva('rounded-card border', {\n variants: {\n variant: {\n surface: 'border-border bg-surface',\n card: 'border-border-subtle bg-card',\n elevated: 'border-border bg-card-elevated',\n },\n padding: {\n none: '',\n sm: 'p-5',\n md: 'p-6',\n lg: 'p-6 sm:p-8',\n },\n },\n defaultVariants: {\n variant: 'surface',\n padding: 'md',\n },\n})\n\nexport type CardProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof cardVariants> & {\n asChild?: boolean\n }\n\nfunction Card({ className, variant, padding, asChild = false, ...props }: CardProps) {\n const Comp = asChild ? Slot : 'div'\n return (\n <Comp\n data-slot=\"card\"\n data-variant={variant}\n className={cn(cardVariants({ variant, padding }), className)}\n {...props}\n />\n )\n}\n\nexport { Card, cardVariants }\n"],"mappings":";;;;;;AASA,MAAM,eAAe,IAAI,uBAAuB;CAC9C,UAAU;EACR,SAAS;GACP,SAAS;GACT,MAAM;GACN,UAAU;EACZ;EACA,SAAS;GACP,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;CACF;CACA,iBAAiB;EACf,SAAS;EACT,SAAS;CACX;AACF,CAAC;AAOD,SAAS,KAAK,EAAE,WAAW,SAAS,SAAS,UAAU,OAAO,GAAG,SAAoB;CAEnF,OACE,oBAFW,UAAU,OAAO,OAE5B;EACE,aAAU;EACV,gBAAc;EACd,WAAW,GAAG,aAAa;GAAE;GAAS;EAAQ,CAAC,GAAG,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
import { UseEmblaCarouselType } from "embla-carousel-react";
|
|
3
|
+
import { EmblaOptionsType } from "embla-carousel";
|
|
4
|
+
//#region src/ui/components/Carousel/Carousel.d.ts
|
|
5
|
+
type EmblaCarouselType = UseEmblaCarouselType[1];
|
|
6
|
+
type CarouselApi = {
|
|
7
|
+
selectedIndex: number;
|
|
8
|
+
scrollSnaps: number[];
|
|
9
|
+
canScrollPrev: boolean;
|
|
10
|
+
canScrollNext: boolean;
|
|
11
|
+
scrollTo: (index: number) => void;
|
|
12
|
+
scrollPrev: () => void;
|
|
13
|
+
scrollNext: () => void;
|
|
14
|
+
viewportRef: (node: HTMLElement | null) => void;
|
|
15
|
+
emblaApi: EmblaCarouselType | undefined;
|
|
16
|
+
};
|
|
17
|
+
declare function useCarousel(): CarouselApi;
|
|
18
|
+
type CarouselProps = HTMLAttributes<HTMLDivElement> & {
|
|
19
|
+
options?: EmblaOptionsType;
|
|
20
|
+
/** Accessible name for the carousel region. Apps own i18n. */
|
|
21
|
+
label: string;
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
};
|
|
24
|
+
declare function Carousel({ options, label, className, children, ...props }: CarouselProps): import("react").JSX.Element;
|
|
25
|
+
declare function CarouselViewport({ className, children, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
|
|
26
|
+
declare function CarouselContainer({ className, children, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
|
|
27
|
+
declare function CarouselSlide({ className, children, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
|
|
28
|
+
type CarouselControlsProps = {
|
|
29
|
+
className?: string;
|
|
30
|
+
prevLabel: string;
|
|
31
|
+
nextLabel: string;
|
|
32
|
+
};
|
|
33
|
+
declare function CarouselControls({ className, prevLabel, nextLabel }: CarouselControlsProps): import("react").JSX.Element;
|
|
34
|
+
type CarouselPaginationProps = {
|
|
35
|
+
className?: string;
|
|
36
|
+
paginationLabel: string;
|
|
37
|
+
slideLabel: (slide: number) => string;
|
|
38
|
+
};
|
|
39
|
+
declare function CarouselPagination({ className, paginationLabel, slideLabel }: CarouselPaginationProps): import("react").JSX.Element | null;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { Carousel, CarouselApi, CarouselContainer, CarouselControls, CarouselControlsProps, CarouselPagination, CarouselPaginationProps, CarouselProps, CarouselSlide, CarouselViewport, useCarousel };
|
|
42
|
+
//# sourceMappingURL=Carousel.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.d.mts","names":[],"sources":["../../../../src/ui/components/Carousel/Carousel.tsx"],"mappings":";;;;KAkBK,oBAAoB;KAEb;EACV;EACA;EACA;EACA;EACA,WAAW;EACX;EACA;EACA,cAAc,MAAM;EACpB,UAAU;;iBAKI,eAAW;KAQf,gBAAgB,eAAe;EACzC,UAAU;;EAEV;EACA,UAAU;;iBAGH,WAAW,SAAS,OAAO,WAAW,aAAa,SAAS,gCAAa,IAAA;iBAkDzE,mBAAmB,WAAW,aAAa,SAAS,eAAe,kCAAe,IAAA;iBASlF,oBAAoB,WAAW,aAAa,SAAS,eAAe,kCAAe,IAAA;iBAQnF,gBAAgB,WAAW,aAAa,SAAS,eAAe,kCAAe,IAAA;KAa5E;EACV;EACA;EACA;;iBA+BO,mBAAmB,WAAW,WAAW,aAAa,wCAAqB,IAAA;KA6BxE;EACV;EACA;EACA,aAAa;;iBAGN,qBAAqB,WAAW,iBAAiB,cAAc,0CAAuB,IAAA"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.mjs";
|
|
3
|
+
import { focusRingClassName } from "../../a11y/focus.mjs";
|
|
4
|
+
import { Button } from "../Button/Button.mjs";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
7
|
+
import useEmblaCarousel from "embla-carousel-react";
|
|
8
|
+
//#region src/ui/components/Carousel/Carousel.tsx
|
|
9
|
+
const CarouselContext = createContext(null);
|
|
10
|
+
function useCarousel() {
|
|
11
|
+
const context = useContext(CarouselContext);
|
|
12
|
+
if (!context) throw new Error("Carousel components must be used within <Carousel>");
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
function Carousel({ options, label, className, children, ...props }) {
|
|
16
|
+
const [viewportRef, emblaApi] = useEmblaCarousel(options);
|
|
17
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
18
|
+
const [scrollSnaps, setScrollSnaps] = useState([]);
|
|
19
|
+
const [canScrollPrev, setCanScrollPrev] = useState(false);
|
|
20
|
+
const [canScrollNext, setCanScrollNext] = useState(false);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!emblaApi) return;
|
|
23
|
+
function onSelect(api) {
|
|
24
|
+
setSelectedIndex(api.selectedScrollSnap());
|
|
25
|
+
setCanScrollPrev(api.canScrollPrev());
|
|
26
|
+
setCanScrollNext(api.canScrollNext());
|
|
27
|
+
}
|
|
28
|
+
setScrollSnaps(emblaApi.scrollSnapList());
|
|
29
|
+
onSelect(emblaApi);
|
|
30
|
+
emblaApi.on("reInit", onSelect);
|
|
31
|
+
emblaApi.on("select", onSelect);
|
|
32
|
+
return () => {
|
|
33
|
+
emblaApi.off("reInit", onSelect);
|
|
34
|
+
emblaApi.off("select", onSelect);
|
|
35
|
+
};
|
|
36
|
+
}, [emblaApi]);
|
|
37
|
+
const value = {
|
|
38
|
+
viewportRef,
|
|
39
|
+
emblaApi,
|
|
40
|
+
selectedIndex,
|
|
41
|
+
scrollSnaps,
|
|
42
|
+
canScrollPrev,
|
|
43
|
+
canScrollNext,
|
|
44
|
+
scrollTo: (index) => emblaApi?.scrollTo(index),
|
|
45
|
+
scrollPrev: () => emblaApi?.scrollPrev(),
|
|
46
|
+
scrollNext: () => emblaApi?.scrollNext()
|
|
47
|
+
};
|
|
48
|
+
return /* @__PURE__ */ jsx(CarouselContext.Provider, {
|
|
49
|
+
value,
|
|
50
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
51
|
+
className: cn("flex flex-col", className),
|
|
52
|
+
...props,
|
|
53
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
54
|
+
"aria-label": label,
|
|
55
|
+
"aria-roledescription": "carousel",
|
|
56
|
+
children
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function CarouselViewport({ className, children, ...props }) {
|
|
62
|
+
const { viewportRef } = useCarousel();
|
|
63
|
+
return /* @__PURE__ */ jsx("div", {
|
|
64
|
+
ref: viewportRef,
|
|
65
|
+
className: cn("overflow-hidden", className),
|
|
66
|
+
...props,
|
|
67
|
+
children
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function CarouselContainer({ className, children, ...props }) {
|
|
71
|
+
return /* @__PURE__ */ jsx("div", {
|
|
72
|
+
className: cn("flex", className),
|
|
73
|
+
...props,
|
|
74
|
+
children
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function CarouselSlide({ className, children, ...props }) {
|
|
78
|
+
return /* @__PURE__ */ jsx("div", {
|
|
79
|
+
role: "group",
|
|
80
|
+
"aria-roledescription": "slide",
|
|
81
|
+
className: cn("min-w-0 shrink-0 grow-0 basis-full", className),
|
|
82
|
+
...props,
|
|
83
|
+
children
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function ChevronLeft() {
|
|
87
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
88
|
+
"aria-hidden": "true",
|
|
89
|
+
viewBox: "0 0 20 20",
|
|
90
|
+
width: "20",
|
|
91
|
+
height: "20",
|
|
92
|
+
fill: "none",
|
|
93
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
94
|
+
d: "M12.5 4.5 7 10l5.5 5.5",
|
|
95
|
+
stroke: "currentColor",
|
|
96
|
+
strokeWidth: "1.5",
|
|
97
|
+
strokeLinecap: "round",
|
|
98
|
+
strokeLinejoin: "round"
|
|
99
|
+
})
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function ChevronRight() {
|
|
103
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
104
|
+
"aria-hidden": "true",
|
|
105
|
+
viewBox: "0 0 20 20",
|
|
106
|
+
width: "20",
|
|
107
|
+
height: "20",
|
|
108
|
+
fill: "none",
|
|
109
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
110
|
+
d: "M7.5 4.5 13 10l-5.5 5.5",
|
|
111
|
+
stroke: "currentColor",
|
|
112
|
+
strokeWidth: "1.5",
|
|
113
|
+
strokeLinecap: "round",
|
|
114
|
+
strokeLinejoin: "round"
|
|
115
|
+
})
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function CarouselControls({ className, prevLabel, nextLabel }) {
|
|
119
|
+
const { canScrollPrev, canScrollNext, scrollPrev, scrollNext } = useCarousel();
|
|
120
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
121
|
+
className: cn("flex items-center gap-2", className),
|
|
122
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
123
|
+
type: "button",
|
|
124
|
+
variant: "secondary",
|
|
125
|
+
size: "icon",
|
|
126
|
+
"aria-label": prevLabel,
|
|
127
|
+
disabled: !canScrollPrev,
|
|
128
|
+
onClick: scrollPrev,
|
|
129
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, {})
|
|
130
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
131
|
+
type: "button",
|
|
132
|
+
variant: "secondary",
|
|
133
|
+
size: "icon",
|
|
134
|
+
"aria-label": nextLabel,
|
|
135
|
+
disabled: !canScrollNext,
|
|
136
|
+
onClick: scrollNext,
|
|
137
|
+
children: /* @__PURE__ */ jsx(ChevronRight, {})
|
|
138
|
+
})]
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function CarouselPagination({ className, paginationLabel, slideLabel }) {
|
|
142
|
+
const { scrollSnaps, selectedIndex, scrollTo } = useCarousel();
|
|
143
|
+
if (scrollSnaps.length <= 1) return null;
|
|
144
|
+
return /* @__PURE__ */ jsx("div", {
|
|
145
|
+
role: "tablist",
|
|
146
|
+
"aria-label": paginationLabel,
|
|
147
|
+
className: cn("flex items-center justify-center gap-2", className),
|
|
148
|
+
children: scrollSnaps.map((_, index) => {
|
|
149
|
+
const isActive = index === selectedIndex;
|
|
150
|
+
return /* @__PURE__ */ jsx("button", {
|
|
151
|
+
type: "button",
|
|
152
|
+
role: "tab",
|
|
153
|
+
"aria-label": slideLabel(index + 1),
|
|
154
|
+
"aria-selected": isActive,
|
|
155
|
+
onClick: () => scrollTo(index),
|
|
156
|
+
className: cn("size-2 cursor-pointer rounded-full transition-colors", focusRingClassName, isActive ? "bg-accent" : "bg-foreground/25 hover:bg-foreground/40")
|
|
157
|
+
}, index);
|
|
158
|
+
})
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
//#endregion
|
|
162
|
+
export { Carousel, CarouselContainer, CarouselControls, CarouselPagination, CarouselSlide, CarouselViewport, useCarousel };
|
|
163
|
+
|
|
164
|
+
//# sourceMappingURL=Carousel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.mjs","names":[],"sources":["../../../../src/ui/components/Carousel/Carousel.tsx"],"sourcesContent":["'use client'\n\nimport useEmblaCarousel, { type UseEmblaCarouselType } from 'embla-carousel-react'\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react'\n\nimport { Button } from '../Button/Button.js'\nimport { focusRingClassName } from '../../a11y/focus.js'\nimport { cn } from '../../utils/cn.js'\n\nimport type { EmblaOptionsType } from 'embla-carousel'\n\ntype EmblaCarouselType = UseEmblaCarouselType[1]\n\nexport type CarouselApi = {\n selectedIndex: number\n scrollSnaps: number[]\n canScrollPrev: boolean\n canScrollNext: boolean\n scrollTo: (index: number) => void\n scrollPrev: () => void\n scrollNext: () => void\n viewportRef: (node: HTMLElement | null) => void\n emblaApi: EmblaCarouselType | undefined\n}\n\nconst CarouselContext = createContext<CarouselApi | null>(null)\n\nexport function useCarousel() {\n const context = useContext(CarouselContext)\n if (!context) {\n throw new Error('Carousel components must be used within <Carousel>')\n }\n return context\n}\n\nexport type CarouselProps = HTMLAttributes<HTMLDivElement> & {\n options?: EmblaOptionsType\n /** Accessible name for the carousel region. Apps own i18n. */\n label: string\n children: ReactNode\n}\n\nfunction Carousel({ options, label, className, children, ...props }: CarouselProps) {\n const [viewportRef, emblaApi] = useEmblaCarousel(options)\n const [selectedIndex, setSelectedIndex] = useState(0)\n const [scrollSnaps, setScrollSnaps] = useState<number[]>([])\n const [canScrollPrev, setCanScrollPrev] = useState(false)\n const [canScrollNext, setCanScrollNext] = useState(false)\n\n useEffect(() => {\n if (!emblaApi) return\n\n function onSelect(api: NonNullable<typeof emblaApi>) {\n setSelectedIndex(api.selectedScrollSnap())\n setCanScrollPrev(api.canScrollPrev())\n setCanScrollNext(api.canScrollNext())\n }\n\n setScrollSnaps(emblaApi.scrollSnapList())\n onSelect(emblaApi)\n emblaApi.on('reInit', onSelect)\n emblaApi.on('select', onSelect)\n\n return () => {\n emblaApi.off('reInit', onSelect)\n emblaApi.off('select', onSelect)\n }\n }, [emblaApi])\n\n const value: CarouselApi = {\n viewportRef,\n emblaApi,\n selectedIndex,\n scrollSnaps,\n canScrollPrev,\n canScrollNext,\n scrollTo: (index) => emblaApi?.scrollTo(index),\n scrollPrev: () => emblaApi?.scrollPrev(),\n scrollNext: () => emblaApi?.scrollNext(),\n }\n\n return (\n <CarouselContext.Provider value={value}>\n <div className={cn('flex flex-col', className)} {...props}>\n <div aria-label={label} aria-roledescription=\"carousel\">\n {children}\n </div>\n </div>\n </CarouselContext.Provider>\n )\n}\n\nfunction CarouselViewport({ className, children, ...props }: HTMLAttributes<HTMLDivElement>) {\n const { viewportRef } = useCarousel()\n return (\n <div ref={viewportRef} className={cn('overflow-hidden', className)} {...props}>\n {children}\n </div>\n )\n}\n\nfunction CarouselContainer({ className, children, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div className={cn('flex', className)} {...props}>\n {children}\n </div>\n )\n}\n\nfunction CarouselSlide({ className, children, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n className={cn('min-w-0 shrink-0 grow-0 basis-full', className)}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nexport type CarouselControlsProps = {\n className?: string\n prevLabel: string\n nextLabel: string\n}\n\nfunction ChevronLeft() {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 20 20\" width=\"20\" height=\"20\" fill=\"none\">\n <path\n d=\"M12.5 4.5 7 10l5.5 5.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nfunction ChevronRight() {\n return (\n <svg aria-hidden=\"true\" viewBox=\"0 0 20 20\" width=\"20\" height=\"20\" fill=\"none\">\n <path\n d=\"M7.5 4.5 13 10l-5.5 5.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nfunction CarouselControls({ className, prevLabel, nextLabel }: CarouselControlsProps) {\n const { canScrollPrev, canScrollNext, scrollPrev, scrollNext } = useCarousel()\n\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"icon\"\n aria-label={prevLabel}\n disabled={!canScrollPrev}\n onClick={scrollPrev}\n >\n <ChevronLeft />\n </Button>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"icon\"\n aria-label={nextLabel}\n disabled={!canScrollNext}\n onClick={scrollNext}\n >\n <ChevronRight />\n </Button>\n </div>\n )\n}\n\nexport type CarouselPaginationProps = {\n className?: string\n paginationLabel: string\n slideLabel: (slide: number) => string\n}\n\nfunction CarouselPagination({ className, paginationLabel, slideLabel }: CarouselPaginationProps) {\n const { scrollSnaps, selectedIndex, scrollTo } = useCarousel()\n\n if (scrollSnaps.length <= 1) return null\n\n return (\n <div\n role=\"tablist\"\n aria-label={paginationLabel}\n className={cn('flex items-center justify-center gap-2', className)}\n >\n {scrollSnaps.map((_, index) => {\n const isActive = index === selectedIndex\n return (\n <button\n key={index}\n type=\"button\"\n role=\"tab\"\n aria-label={slideLabel(index + 1)}\n aria-selected={isActive}\n onClick={() => scrollTo(index)}\n className={cn(\n 'size-2 cursor-pointer rounded-full transition-colors',\n focusRingClassName,\n isActive ? 'bg-accent' : 'bg-foreground/25 hover:bg-foreground/40'\n )}\n />\n )\n })}\n </div>\n )\n}\n\nexport {\n Carousel,\n CarouselViewport,\n CarouselContainer,\n CarouselSlide,\n CarouselControls,\n CarouselPagination,\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Carousel, CarouselApi, CarouselContainer, CarouselControls, CarouselControlsProps, CarouselPagination, CarouselPaginationProps, CarouselProps, CarouselSlide, CarouselViewport, useCarousel } from "./Carousel.mjs";
|
|
2
|
+
export { Carousel, type CarouselApi, CarouselContainer, CarouselControls, type CarouselControlsProps, CarouselPagination, type CarouselPaginationProps, type CarouselProps, CarouselSlide, CarouselViewport, useCarousel };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ComponentProps } from "react";
|
|
2
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
3
|
+
//#region src/ui/components/Checkbox/Checkbox.d.ts
|
|
4
|
+
type CheckboxProps = Omit<ComponentProps<typeof Primitive.input>, 'type'>;
|
|
5
|
+
declare function Checkbox({ className, ref, ...props }: CheckboxProps): import("react").JSX.Element;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { Checkbox, CheckboxProps };
|
|
8
|
+
//# sourceMappingURL=Checkbox.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.d.mts","names":[],"sources":["../../../../src/ui/components/Checkbox/Checkbox.tsx"],"mappings":";;;KASY,gBAAgB,KAAK,sBAAsB,UAAU;iBAuBxD,WAAW,WAAW,QAAQ,SAAS,gCAAa,IAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.mjs";
|
|
3
|
+
import { focusRingClassName } from "../../a11y/focus.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
6
|
+
//#region src/ui/components/Checkbox/Checkbox.tsx
|
|
7
|
+
function CheckIcon({ className }) {
|
|
8
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
9
|
+
"aria-hidden": "true",
|
|
10
|
+
viewBox: "0 0 14 14",
|
|
11
|
+
width: "14",
|
|
12
|
+
height: "14",
|
|
13
|
+
fill: "none",
|
|
14
|
+
className,
|
|
15
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
16
|
+
d: "M2.5 7.2 5.4 10l6.1-6.5",
|
|
17
|
+
stroke: "currentColor",
|
|
18
|
+
strokeWidth: "1.75",
|
|
19
|
+
strokeLinecap: "round",
|
|
20
|
+
strokeLinejoin: "round"
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function Checkbox({ className, ref, ...props }) {
|
|
25
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
26
|
+
className: "relative inline-flex shrink-0 items-center justify-center",
|
|
27
|
+
children: [/* @__PURE__ */ jsx(Primitive.input, {
|
|
28
|
+
type: "checkbox",
|
|
29
|
+
ref,
|
|
30
|
+
"data-slot": "checkbox",
|
|
31
|
+
className: cn("peer size-5 shrink-0 appearance-none rounded-sm border border-border bg-surface", "cursor-pointer transition-colors", "hover:border-accent", "checked:border-accent checked:bg-accent", "disabled:cursor-not-allowed disabled:opacity-50", focusRingClassName, className),
|
|
32
|
+
...props
|
|
33
|
+
}), /* @__PURE__ */ jsx(CheckIcon, { className: "pointer-events-none absolute text-accent-foreground opacity-0 transition-opacity peer-checked:opacity-100" })]
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { Checkbox };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=Checkbox.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.mjs","names":[],"sources":["../../../../src/ui/components/Checkbox/Checkbox.tsx"],"sourcesContent":["'use client'\n\nimport { Primitive } from '@radix-ui/react-primitive'\n\nimport { focusRingClassName } from '../../a11y/focus.js'\nimport { cn } from '../../utils/cn.js'\n\nimport type { ComponentProps } from 'react'\n\nexport type CheckboxProps = Omit<ComponentProps<typeof Primitive.input>, 'type'>\n\nfunction CheckIcon({ className }: { className?: string }) {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 14 14\"\n width=\"14\"\n height=\"14\"\n fill=\"none\"\n className={className}\n >\n <path\n d=\"M2.5 7.2 5.4 10l6.1-6.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nfunction Checkbox({ className, ref, ...props }: CheckboxProps) {\n return (\n <span className=\"relative inline-flex shrink-0 items-center justify-center\">\n <Primitive.input\n type=\"checkbox\"\n ref={ref}\n data-slot=\"checkbox\"\n className={cn(\n 'peer size-5 shrink-0 appearance-none rounded-sm border border-border bg-surface',\n 'cursor-pointer transition-colors',\n 'hover:border-accent',\n 'checked:border-accent checked:bg-accent',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n focusRingClassName,\n className\n )}\n {...props}\n />\n <CheckIcon className=\"pointer-events-none absolute text-accent-foreground opacity-0 transition-opacity peer-checked:opacity-100\" />\n </span>\n )\n}\n\nexport { Checkbox }\n"],"mappings":";;;;;;AAWA,SAAS,UAAU,EAAE,aAAqC;CACxD,OACE,oBAAC,OAAD;EACE,eAAY;EACZ,SAAQ;EACR,OAAM;EACN,QAAO;EACP,MAAK;EACM;EAEX,UAAA,oBAAC,QAAD;GACE,GAAE;GACF,QAAO;GACP,aAAY;GACZ,eAAc;GACd,gBAAe;EAChB,CAAA;CACE,CAAA;AAET;AAEA,SAAS,SAAS,EAAE,WAAW,KAAK,GAAG,SAAwB;CAC7D,OACE,qBAAC,QAAD;EAAM,WAAU;EAAhB,UAAA,CACE,oBAAC,UAAU,OAAX;GACE,MAAK;GACA;GACL,aAAU;GACV,WAAW,GACT,mFACA,oCACA,uBACA,2CACA,mDACA,oBACA,SACF;GACA,GAAI;EACL,CAAA,GACD,oBAAC,WAAD,EAAW,WAAU,4GAA6G,CAAA,CAC9H;;AAEV"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/ui/components/CodeBlock/CodeBlock.d.ts
|
|
2
|
+
type CodeBlockTheme = 'light' | 'dark';
|
|
3
|
+
type CodeBlockProps = {
|
|
4
|
+
code: string;
|
|
5
|
+
/** Pre-highlighted HTML (e.g. from shiki). When omitted, `code` is plain text. */
|
|
6
|
+
html?: string;
|
|
7
|
+
filename?: string | null;
|
|
8
|
+
theme?: CodeBlockTheme;
|
|
9
|
+
copyable?: boolean;
|
|
10
|
+
collapsible?: boolean;
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Apps own i18n — pass translated aria labels. */
|
|
13
|
+
copyLabel: string;
|
|
14
|
+
copiedLabel: string;
|
|
15
|
+
expandLabel?: string;
|
|
16
|
+
collapseLabel?: string;
|
|
17
|
+
onCopied?: () => void;
|
|
18
|
+
};
|
|
19
|
+
declare function CodeBlock({ code, html, filename, theme, copyable, collapsible, className, copyLabel, copiedLabel, expandLabel, collapseLabel, onCopied }: CodeBlockProps): import("react").JSX.Element;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { CodeBlock, CodeBlockProps, CodeBlockTheme };
|
|
22
|
+
//# sourceMappingURL=CodeBlock.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlock.d.mts","names":[],"sources":["../../../../src/ui/components/CodeBlock/CodeBlock.tsx"],"mappings":";KAOY;KAEA;EACV;;EAEA;EACA;EACA,QAAQ;EACR;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;;iBAqBO,YACP,MACA,MACA,UACA,OACA,UACA,aACA,WACA,WACA,aACA,aACA,eACA,YACC,iCAAc,IAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.mjs";
|
|
3
|
+
import { CopyButton } from "../CopyButton/CopyButton.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
//#region src/ui/components/CodeBlock/CodeBlock.tsx
|
|
7
|
+
const CONTAINER_CLASS = {
|
|
8
|
+
light: "border-border bg-foreground/5 text-foreground",
|
|
9
|
+
dark: "border-border bg-card text-secondary"
|
|
10
|
+
};
|
|
11
|
+
const COPY_BUTTON_CLASS = {
|
|
12
|
+
light: "border-border bg-foreground/5 hover:bg-foreground/10",
|
|
13
|
+
dark: "border-border bg-card-elevated hover:bg-card-elevated/80"
|
|
14
|
+
};
|
|
15
|
+
const GRADIENT_CLASS = {
|
|
16
|
+
light: "from-transparent to-background",
|
|
17
|
+
dark: "from-transparent to-card"
|
|
18
|
+
};
|
|
19
|
+
const COLLAPSED_MAX_HEIGHT = "max-h-40";
|
|
20
|
+
const PRE_STYLE = "m-0 whitespace-pre-wrap break-words font-mono text-sm leading-relaxed";
|
|
21
|
+
function CodeBlock({ code, html, filename, theme = "dark", copyable = true, collapsible = false, className, copyLabel, copiedLabel, expandLabel = "Show more", collapseLabel = "Show less", onCopied }) {
|
|
22
|
+
const [expanded, setExpanded] = useState(false);
|
|
23
|
+
const isCollapsed = collapsible && !expanded;
|
|
24
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
25
|
+
className: cn("my-3 overflow-hidden rounded-card border", CONTAINER_CLASS[theme], className),
|
|
26
|
+
children: [filename ? /* @__PURE__ */ jsx("div", {
|
|
27
|
+
className: "border-b border-border-subtle px-4 py-2 font-mono text-sm text-secondary sm:px-5",
|
|
28
|
+
children: filename
|
|
29
|
+
}) : null, /* @__PURE__ */ jsxs("div", {
|
|
30
|
+
className: "relative",
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ jsx("div", {
|
|
33
|
+
className: cn("p-5 sm:p-6", isCollapsed && COLLAPSED_MAX_HEIGHT, isCollapsed && "overflow-hidden", collapsible && "pb-16"),
|
|
34
|
+
children: html !== void 0 ? /* @__PURE__ */ jsx("div", {
|
|
35
|
+
className: PRE_STYLE,
|
|
36
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
37
|
+
}) : /* @__PURE__ */ jsx("pre", {
|
|
38
|
+
className: PRE_STYLE,
|
|
39
|
+
children: /* @__PURE__ */ jsx("code", { children: code })
|
|
40
|
+
})
|
|
41
|
+
}),
|
|
42
|
+
isCollapsed ? /* @__PURE__ */ jsx("div", {
|
|
43
|
+
"aria-hidden": true,
|
|
44
|
+
className: cn("pointer-events-none absolute inset-x-0 bottom-12 h-16 bg-gradient-to-b", GRADIENT_CLASS[theme])
|
|
45
|
+
}) : null,
|
|
46
|
+
copyable ? /* @__PURE__ */ jsx(CopyButton, {
|
|
47
|
+
text: code,
|
|
48
|
+
"aria-label": copyLabel,
|
|
49
|
+
copiedAriaLabel: copiedLabel,
|
|
50
|
+
onCopied,
|
|
51
|
+
className: cn("absolute top-3 right-3 border", COPY_BUTTON_CLASS[theme])
|
|
52
|
+
}) : null,
|
|
53
|
+
collapsible ? /* @__PURE__ */ jsx("button", {
|
|
54
|
+
type: "button",
|
|
55
|
+
className: "absolute bottom-3 left-1/2 -translate-x-1/2 cursor-pointer rounded-btn border border-border bg-surface px-3 py-1.5 text-xs font-semibold text-foreground",
|
|
56
|
+
onClick: () => setExpanded((v) => !v),
|
|
57
|
+
children: expanded ? collapseLabel : expandLabel
|
|
58
|
+
}) : null
|
|
59
|
+
]
|
|
60
|
+
})]
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { CodeBlock };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=CodeBlock.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlock.mjs","names":[],"sources":["../../../../src/ui/components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\n\nimport { CopyButton } from '../CopyButton/CopyButton.js'\nimport { cn } from '../../utils/cn.js'\n\nexport type CodeBlockTheme = 'light' | 'dark'\n\nexport type CodeBlockProps = {\n code: string\n /** Pre-highlighted HTML (e.g. from shiki). When omitted, `code` is plain text. */\n html?: string\n filename?: string | null\n theme?: CodeBlockTheme\n copyable?: boolean\n collapsible?: boolean\n className?: string\n /** Apps own i18n — pass translated aria labels. */\n copyLabel: string\n copiedLabel: string\n expandLabel?: string\n collapseLabel?: string\n onCopied?: () => void\n}\n\nconst CONTAINER_CLASS: Record<CodeBlockTheme, string> = {\n light: 'border-border bg-foreground/5 text-foreground',\n dark: 'border-border bg-card text-secondary',\n}\n\nconst COPY_BUTTON_CLASS: Record<CodeBlockTheme, string> = {\n light: 'border-border bg-foreground/5 hover:bg-foreground/10',\n dark: 'border-border bg-card-elevated hover:bg-card-elevated/80',\n}\n\nconst GRADIENT_CLASS: Record<CodeBlockTheme, string> = {\n light: 'from-transparent to-background',\n dark: 'from-transparent to-card',\n}\n\nconst COLLAPSED_MAX_HEIGHT = 'max-h-40'\nconst PRE_STYLE = 'm-0 whitespace-pre-wrap break-words font-mono text-sm leading-relaxed'\n\nfunction CodeBlock({\n code,\n html,\n filename,\n theme = 'dark',\n copyable = true,\n collapsible = false,\n className,\n copyLabel,\n copiedLabel,\n expandLabel = 'Show more',\n collapseLabel = 'Show less',\n onCopied,\n}: CodeBlockProps) {\n const [expanded, setExpanded] = useState(false)\n const isCollapsed = collapsible && !expanded\n\n return (\n <div\n className={cn('my-3 overflow-hidden rounded-card border', CONTAINER_CLASS[theme], className)}\n >\n {filename ? (\n <div className=\"border-b border-border-subtle px-4 py-2 font-mono text-sm text-secondary sm:px-5\">\n {filename}\n </div>\n ) : null}\n <div className=\"relative\">\n <div\n className={cn(\n 'p-5 sm:p-6',\n isCollapsed && COLLAPSED_MAX_HEIGHT,\n isCollapsed && 'overflow-hidden',\n collapsible && 'pb-16'\n )}\n >\n {html !== undefined ? (\n <div className={PRE_STYLE} dangerouslySetInnerHTML={{ __html: html }} />\n ) : (\n <pre className={PRE_STYLE}>\n <code>{code}</code>\n </pre>\n )}\n </div>\n\n {isCollapsed ? (\n <div\n aria-hidden\n className={cn(\n 'pointer-events-none absolute inset-x-0 bottom-12 h-16 bg-gradient-to-b',\n GRADIENT_CLASS[theme]\n )}\n />\n ) : null}\n\n {copyable ? (\n <CopyButton\n text={code}\n aria-label={copyLabel}\n copiedAriaLabel={copiedLabel}\n onCopied={onCopied}\n className={cn('absolute top-3 right-3 border', COPY_BUTTON_CLASS[theme])}\n />\n ) : null}\n\n {collapsible ? (\n <button\n type=\"button\"\n className=\"absolute bottom-3 left-1/2 -translate-x-1/2 cursor-pointer rounded-btn border border-border bg-surface px-3 py-1.5 text-xs font-semibold text-foreground\"\n onClick={() => setExpanded((v) => !v)}\n >\n {expanded ? collapseLabel : expandLabel}\n </button>\n ) : null}\n </div>\n </div>\n )\n}\n\nexport { CodeBlock }\n"],"mappings":";;;;;;AA0BA,MAAM,kBAAkD;CACtD,OAAO;CACP,MAAM;AACR;AAEA,MAAM,oBAAoD;CACxD,OAAO;CACP,MAAM;AACR;AAEA,MAAM,iBAAiD;CACrD,OAAO;CACP,MAAM;AACR;AAEA,MAAM,uBAAuB;AAC7B,MAAM,YAAY;AAElB,SAAS,UAAU,EACjB,MACA,MACA,UACA,QAAQ,QACR,WAAW,MACX,cAAc,OACd,WACA,WACA,aACA,cAAc,aACd,gBAAgB,aAChB,YACiB;CACjB,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,cAAc,eAAe,CAAC;CAEpC,OACE,qBAAC,OAAD;EACE,WAAW,GAAG,4CAA4C,gBAAgB,QAAQ,SAAS;EAD7F,UAAA,CAGG,WACC,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA;EACE,CAAA,IACH,MACJ,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,oBAAC,OAAD;KACE,WAAW,GACT,cACA,eAAe,sBACf,eAAe,mBACf,eAAe,OACjB;KAEC,UAAA,SAAS,SACR,oBAAC,OAAD;MAAK,WAAW;MAAW,yBAAyB,EAAE,QAAQ,KAAK;KAAI,CAAA,IAEvE,oBAAC,OAAD;MAAK,WAAW;MACd,UAAA,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA;KACf,CAAA;IAEJ,CAAA;IAEJ,cACC,oBAAC,OAAD;KACE,eAAA;KACA,WAAW,GACT,0EACA,eAAe,MACjB;IACD,CAAA,IACC;IAEH,WACC,oBAAC,YAAD;KACE,MAAM;KACN,cAAY;KACZ,iBAAiB;KACP;KACV,WAAW,GAAG,iCAAiC,kBAAkB,MAAM;IACxE,CAAA,IACC;IAEH,cACC,oBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,eAAe,aAAa,MAAM,CAAC,CAAC;KAEnC,UAAA,WAAW,gBAAgB;IACtB,CAAA,IACN;GACD;EACF,CAAA,CAAA;;AAET"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/ui/components/CodeBlockTabs/CodeBlockTabs.d.ts
|
|
2
|
+
type CodeBlockTabsTheme = 'light' | 'dark';
|
|
3
|
+
type CodeBlockTab = {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
/** Pre-highlighted HTML (e.g. from shiki). */
|
|
7
|
+
html: string;
|
|
8
|
+
};
|
|
9
|
+
type CodeBlockTabsProps = {
|
|
10
|
+
tabs: CodeBlockTab[];
|
|
11
|
+
className?: string;
|
|
12
|
+
theme?: CodeBlockTabsTheme;
|
|
13
|
+
/** Apps own i18n — aria-label for the tablist. */
|
|
14
|
+
tabsAriaLabel: string;
|
|
15
|
+
};
|
|
16
|
+
declare function CodeBlockTabs({ tabs, className, theme, tabsAriaLabel }: CodeBlockTabsProps): import("react").JSX.Element | null;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { CodeBlockTab, CodeBlockTabs, CodeBlockTabsProps, CodeBlockTabsTheme };
|
|
19
|
+
//# sourceMappingURL=CodeBlockTabs.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlockTabs.d.mts","names":[],"sources":["../../../../src/ui/components/CodeBlockTabs/CodeBlockTabs.tsx"],"mappings":";KAMY;KAEA;EACV;EACA;;EAEA;;KAGU;EACV,MAAM;EACN;EACA,QAAQ;;EAER;;iBAgBO,gBAAgB,MAAM,WAAW,OAAiB,iBAAiB,qCAAkB,IAAA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils/cn.mjs";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
//#region src/ui/components/CodeBlockTabs/CodeBlockTabs.tsx
|
|
6
|
+
const PRE_CLASS = "[&>pre]:m-0 [&>pre]:font-mono [&>pre]:text-[13px] [&>pre]:leading-[22px] [&>pre]:wrap-break-word [&>pre]:whitespace-pre-wrap";
|
|
7
|
+
const SHELL = {
|
|
8
|
+
light: "border-border bg-foreground/5",
|
|
9
|
+
dark: "border-border bg-surface-elevated"
|
|
10
|
+
};
|
|
11
|
+
const TAB_IDLE = {
|
|
12
|
+
light: "border-border text-muted hover:text-foreground",
|
|
13
|
+
dark: "border-border bg-card text-muted hover:text-foreground"
|
|
14
|
+
};
|
|
15
|
+
function CodeBlockTabs({ tabs, className, theme = "light", tabsAriaLabel }) {
|
|
16
|
+
const [active, setActive] = useState(0);
|
|
17
|
+
if (tabs.length === 0) return null;
|
|
18
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
19
|
+
className: cn("flex flex-col gap-4 overflow-hidden rounded-card border p-5", SHELL[theme], className),
|
|
20
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
21
|
+
role: "tablist",
|
|
22
|
+
"aria-label": tabsAriaLabel,
|
|
23
|
+
className: "flex flex-wrap gap-2 print:hidden",
|
|
24
|
+
children: tabs.map((tab, idx) => {
|
|
25
|
+
const isActive = idx === active;
|
|
26
|
+
return /* @__PURE__ */ jsx("button", {
|
|
27
|
+
type: "button",
|
|
28
|
+
role: "tab",
|
|
29
|
+
id: `code-tab-${tab.id}`,
|
|
30
|
+
"aria-selected": isActive,
|
|
31
|
+
"aria-controls": `code-tab-panel-${tab.id}`,
|
|
32
|
+
onClick: () => setActive(idx),
|
|
33
|
+
className: cn("rounded-full border px-4 py-2 text-btn font-medium transition-colors", isActive ? "border-accent/30 bg-accent/12 text-accent" : TAB_IDLE[theme]),
|
|
34
|
+
children: tab.label
|
|
35
|
+
}, tab.id);
|
|
36
|
+
})
|
|
37
|
+
}), tabs.map((tab, idx) => {
|
|
38
|
+
const isActive = idx === active;
|
|
39
|
+
return /* @__PURE__ */ jsx("div", {
|
|
40
|
+
id: `code-tab-panel-${tab.id}`,
|
|
41
|
+
role: "tabpanel",
|
|
42
|
+
"aria-labelledby": `code-tab-${tab.id}`,
|
|
43
|
+
hidden: !isActive,
|
|
44
|
+
className: cn("overflow-hidden rounded-card border text-foreground", SHELL[theme], isActive ? "block" : "hidden print:block"),
|
|
45
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
46
|
+
className: "overflow-x-auto px-[18px] py-4",
|
|
47
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
48
|
+
className: PRE_CLASS,
|
|
49
|
+
dangerouslySetInnerHTML: { __html: tab.html }
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
}, tab.id);
|
|
53
|
+
})]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { CodeBlockTabs };
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=CodeBlockTabs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodeBlockTabs.mjs","names":[],"sources":["../../../../src/ui/components/CodeBlockTabs/CodeBlockTabs.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\n\nimport { cn } from '../../utils/cn.js'\n\nexport type CodeBlockTabsTheme = 'light' | 'dark'\n\nexport type CodeBlockTab = {\n id: string\n label: string\n /** Pre-highlighted HTML (e.g. from shiki). */\n html: string\n}\n\nexport type CodeBlockTabsProps = {\n tabs: CodeBlockTab[]\n className?: string\n theme?: CodeBlockTabsTheme\n /** Apps own i18n — aria-label for the tablist. */\n tabsAriaLabel: string\n}\n\nconst PRE_CLASS =\n '[&>pre]:m-0 [&>pre]:font-mono [&>pre]:text-[13px] [&>pre]:leading-[22px] [&>pre]:wrap-break-word [&>pre]:whitespace-pre-wrap'\n\nconst SHELL: Record<CodeBlockTabsTheme, string> = {\n light: 'border-border bg-foreground/5',\n dark: 'border-border bg-surface-elevated',\n}\n\nconst TAB_IDLE: Record<CodeBlockTabsTheme, string> = {\n light: 'border-border text-muted hover:text-foreground',\n dark: 'border-border bg-card text-muted hover:text-foreground',\n}\n\nfunction CodeBlockTabs({ tabs, className, theme = 'light', tabsAriaLabel }: CodeBlockTabsProps) {\n const [active, setActive] = useState(0)\n\n if (tabs.length === 0) return null\n\n return (\n <div\n className={cn(\n 'flex flex-col gap-4 overflow-hidden rounded-card border p-5',\n SHELL[theme],\n className\n )}\n >\n <div role=\"tablist\" aria-label={tabsAriaLabel} className=\"flex flex-wrap gap-2 print:hidden\">\n {tabs.map((tab, idx) => {\n const isActive = idx === active\n return (\n <button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n id={`code-tab-${tab.id}`}\n aria-selected={isActive}\n aria-controls={`code-tab-panel-${tab.id}`}\n onClick={() => setActive(idx)}\n className={cn(\n 'rounded-full border px-4 py-2 text-btn font-medium transition-colors',\n isActive ? 'border-accent/30 bg-accent/12 text-accent' : TAB_IDLE[theme]\n )}\n >\n {tab.label}\n </button>\n )\n })}\n </div>\n\n {tabs.map((tab, idx) => {\n const isActive = idx === active\n return (\n <div\n key={tab.id}\n id={`code-tab-panel-${tab.id}`}\n role=\"tabpanel\"\n aria-labelledby={`code-tab-${tab.id}`}\n hidden={!isActive}\n className={cn(\n 'overflow-hidden rounded-card border text-foreground',\n SHELL[theme],\n isActive ? 'block' : 'hidden print:block'\n )}\n >\n <div className=\"overflow-x-auto px-[18px] py-4\">\n <div className={PRE_CLASS} dangerouslySetInnerHTML={{ __html: tab.html }} />\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n\nexport { CodeBlockTabs }\n"],"mappings":";;;;;AAuBA,MAAM,YACJ;AAEF,MAAM,QAA4C;CAChD,OAAO;CACP,MAAM;AACR;AAEA,MAAM,WAA+C;CACnD,OAAO;CACP,MAAM;AACR;AAEA,SAAS,cAAc,EAAE,MAAM,WAAW,QAAQ,SAAS,iBAAqC;CAC9F,MAAM,CAAC,QAAQ,aAAa,SAAS,CAAC;CAEtC,IAAI,KAAK,WAAW,GAAG,OAAO;CAE9B,OACE,qBAAC,OAAD;EACE,WAAW,GACT,+DACA,MAAM,QACN,SACF;EALF,UAAA,CAOE,oBAAC,OAAD;GAAK,MAAK;GAAU,cAAY;GAAe,WAAU;GACtD,UAAA,KAAK,KAAK,KAAK,QAAQ;IACtB,MAAM,WAAW,QAAQ;IACzB,OACE,oBAAC,UAAD;KAEE,MAAK;KACL,MAAK;KACL,IAAI,YAAY,IAAI;KACpB,iBAAe;KACf,iBAAe,kBAAkB,IAAI;KACrC,eAAe,UAAU,GAAG;KAC5B,WAAW,GACT,wEACA,WAAW,8CAA8C,SAAS,MACpE;KAEC,UAAA,IAAI;IACC,GAbD,IAAI,EAaH;GAEZ,CAAC;EACE,CAAA,GAEJ,KAAK,KAAK,KAAK,QAAQ;GACtB,MAAM,WAAW,QAAQ;GACzB,OACE,oBAAC,OAAD;IAEE,IAAI,kBAAkB,IAAI;IAC1B,MAAK;IACL,mBAAiB,YAAY,IAAI;IACjC,QAAQ,CAAC;IACT,WAAW,GACT,uDACA,MAAM,QACN,WAAW,UAAU,oBACvB;IAEA,UAAA,oBAAC,OAAD;KAAK,WAAU;KACb,UAAA,oBAAC,OAAD;MAAK,WAAW;MAAW,yBAAyB,EAAE,QAAQ,IAAI,KAAK;KAAI,CAAA;IACxE,CAAA;GACF,GAdE,IAAI,EAcN;EAET,CAAC,CACE;;AAET"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/ui/components/CollapsibleSection/CollapsibleSection.d.ts
|
|
3
|
+
type CollapsibleSectionProps = {
|
|
4
|
+
collapsedHeight: number;
|
|
5
|
+
toggleLabel: string;
|
|
6
|
+
defaultOpen?: boolean;
|
|
7
|
+
className?: string;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
};
|
|
10
|
+
declare function CollapsibleSection({ collapsedHeight, toggleLabel, defaultOpen, className, children }: CollapsibleSectionProps): import("react").JSX.Element;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { CollapsibleSection, CollapsibleSectionProps };
|
|
13
|
+
//# sourceMappingURL=CollapsibleSection.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollapsibleSection.d.mts","names":[],"sources":["../../../../src/ui/components/CollapsibleSection/CollapsibleSection.tsx"],"mappings":";;KASY;EACV;EACA;EACA;EACA;EACA,UAAU;;iBAwBH,qBACP,iBACA,aACA,aACA,WACA,YACC,0CAAuB,IAAA"}
|