From e7a1fd0509991099c4479b06e34682cbc0b3ed15 Mon Sep 17 00:00:00 2001 From: hngngn Date: Fri, 9 Feb 2024 18:33:08 +0700 Subject: [PATCH] feat: new components --- .eslintrc | 3 +- apps/www/package.json | 2 + apps/www/public/registry/index.json | 20 ++ .../registry/styles/default/carousel.json | 13 + .../registry/styles/default/pagination.json | 13 + apps/www/src/__registry__/index.js | 63 ++++ apps/www/src/components/mdx-components.tsx | 6 +- apps/www/src/config/docs.ts | 17 ++ .../default/example/carousel-api-demo.tsx | 60 ++++ .../default/example/carousel-demo.tsx | 37 +++ .../default/example/carousel-orientation.tsx | 43 +++ .../default/example/carousel-plugin.tsx | 45 +++ .../default/example/carousel-size.tsx | 42 +++ .../default/example/carousel-spacing.tsx | 36 +++ .../default/example/pagination-demo.tsx | 27 ++ apps/www/src/registry/default/ui/carousel.tsx | 257 ++++++++++++++++ .../src/registry/default/ui/pagination.tsx | 128 ++++++++ apps/www/src/registry/registry.js | 54 ++++ apps/www/src/routes/docs.tsx | 43 +-- apps/www/src/routes/docs/changelog.mdx | 61 ++++ .../src/routes/docs/components/accordion.mdx | 106 +++---- .../routes/docs/components/alert-dialog.mdx | 56 ++-- apps/www/src/routes/docs/components/alert.mdx | 22 +- .../www/src/routes/docs/components/button.mdx | 4 +- .../src/routes/docs/components/carousel.mdx | 282 ++++++++++++++++++ .../src/routes/docs/components/checkbox.mdx | 10 +- .../routes/docs/components/collapsible.mdx | 100 +++---- .../src/routes/docs/components/combobox.mdx | 40 +-- .../routes/docs/components/context-menu.mdx | 32 +- .../www/src/routes/docs/components/dialog.mdx | 42 +-- .../routes/docs/components/dropdown-menu.mdx | 4 +- .../src/routes/docs/components/hover-card.mdx | 24 +- apps/www/src/routes/docs/components/image.mdx | 14 +- .../src/routes/docs/components/pagination.mdx | 70 +++++ .../src/routes/docs/components/popover.mdx | 20 +- .../src/routes/docs/components/progress.mdx | 10 +- .../routes/docs/components/radio-group.mdx | 14 +- .../www/src/routes/docs/components/select.mdx | 36 +-- .../src/routes/docs/components/separator.mdx | 10 +- apps/www/src/routes/docs/components/sheet.mdx | 62 ++-- .../www/src/routes/docs/components/switch.mdx | 16 +- apps/www/src/routes/docs/components/tabs.mdx | 26 +- .../src/routes/docs/components/textarea.mdx | 12 +- .../src/routes/docs/components/textfield.mdx | 12 +- .../www/src/routes/docs/components/toggle.mdx | 10 +- .../src/routes/docs/components/tooltip.mdx | 24 +- pnpm-lock.yaml | 36 +++ 47 files changed, 1686 insertions(+), 378 deletions(-) create mode 100644 apps/www/public/registry/styles/default/carousel.json create mode 100644 apps/www/public/registry/styles/default/pagination.json create mode 100644 apps/www/src/registry/default/example/carousel-api-demo.tsx create mode 100644 apps/www/src/registry/default/example/carousel-demo.tsx create mode 100644 apps/www/src/registry/default/example/carousel-orientation.tsx create mode 100644 apps/www/src/registry/default/example/carousel-plugin.tsx create mode 100644 apps/www/src/registry/default/example/carousel-size.tsx create mode 100644 apps/www/src/registry/default/example/carousel-spacing.tsx create mode 100644 apps/www/src/registry/default/example/pagination-demo.tsx create mode 100644 apps/www/src/registry/default/ui/carousel.tsx create mode 100644 apps/www/src/registry/default/ui/pagination.tsx create mode 100644 apps/www/src/routes/docs/changelog.mdx create mode 100644 apps/www/src/routes/docs/components/carousel.mdx create mode 100644 apps/www/src/routes/docs/components/pagination.mdx diff --git a/.eslintrc b/.eslintrc index 46853d79..18772577 100644 --- a/.eslintrc +++ b/.eslintrc @@ -6,7 +6,8 @@ "rules": { "@typescript-eslint/consistent-type-imports": "error", "no-undef": "off", - "no-redeclare": "off" + "no-redeclare": "off", + "no-unused-vars": "off" }, "parser": "@typescript-eslint/parser" } diff --git a/apps/www/package.json b/apps/www/package.json index 6220ece2..1d50ea36 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -17,6 +17,8 @@ "@vinxi/plugin-mdx": "^3.6.7", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", + "embla-carousel-autoplay": "8.0.0-rc22", + "embla-carousel-solid": "8.0.0-rc22", "solid-js": "^1.8.14", "solid-mdx": "^0.0.7", "solid-wrap-balancer": "^0.0.5", diff --git a/apps/www/public/registry/index.json b/apps/www/public/registry/index.json index 83750048..8b2e2b92 100644 --- a/apps/www/public/registry/index.json +++ b/apps/www/public/registry/index.json @@ -56,6 +56,16 @@ ], "type": "components:ui" }, + { + "name": "carousel", + "dependencies": [ + "embla-carousel-solid" + ], + "files": [ + "ui/carousel.tsx" + ], + "type": "components:ui" + }, { "name": "checkbox", "dependencies": [ @@ -146,6 +156,16 @@ ], "type": "components:ui" }, + { + "name": "pagination", + "dependencies": [ + "@kobalte/core" + ], + "files": [ + "ui/pagination.tsx" + ], + "type": "components:ui" + }, { "name": "progress", "dependencies": [ diff --git a/apps/www/public/registry/styles/default/carousel.json b/apps/www/public/registry/styles/default/carousel.json new file mode 100644 index 00000000..9b30e907 --- /dev/null +++ b/apps/www/public/registry/styles/default/carousel.json @@ -0,0 +1,13 @@ +{ + "name": "carousel", + "dependencies": [ + "embla-carousel-solid" + ], + "files": [ + { + "name": "carousel.tsx", + "content": "import { cn } from \"@/lib/cn\"\r\nimport type { CreateEmblaCarouselType } from \"embla-carousel-solid\"\r\nimport createEmblaCarousel from \"embla-carousel-solid\"\r\n\r\nimport type {\r\n\tAccessor,\r\n\tComponentProps,\r\n\tParentComponent,\r\n\tVoidComponent,\r\n} from \"solid-js\"\r\nimport {\r\n\tcreateContext,\r\n\tcreateEffect,\r\n\tcreateMemo,\r\n\tcreateSignal,\r\n\tmergeProps,\r\n\tsplitProps,\r\n\tuseContext,\r\n} from \"solid-js\"\r\nimport { Button } from \"./button\"\r\n\r\nexport type CarouselApi = CreateEmblaCarouselType[1]\r\ntype UseCarouselParameters = Parameters\r\ntype CarouselOptions = NonNullable\r\ntype CarouselPlugin = NonNullable\r\n\r\ntype CarouselProps = {\r\n\topts?: ReturnType\r\n\tplugins?: ReturnType\r\n\torientation?: \"horizontal\" | \"vertical\"\r\n\tsetApi?: (api: CarouselApi) => void\r\n}\r\n\r\ntype CarouselContextProps = {\r\n\tcarouselRef: ReturnType[0]\r\n\tapi: ReturnType[1]\r\n\tscrollPrev: () => void\r\n\tscrollNext: () => void\r\n\tcanScrollPrev: Accessor\r\n\tcanScrollNext: Accessor\r\n} & CarouselProps\r\n\r\nconst CarouselContext = createContext | null>(\r\n\tnull\r\n)\r\n\r\nconst useCarousel = () => {\r\n\tconst context = useContext(CarouselContext)\r\n\r\n\tif (!context) {\r\n\t\tthrow new Error(\"useCarousel must be used within a \")\r\n\t}\r\n\r\n\treturn context()\r\n}\r\n\r\nexport const Carousel: ParentComponent<\r\n\tComponentProps<\"div\"> & CarouselProps\r\n> = (props) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ orientation: \"horizontal\" } as CarouselProps,\r\n\t\tprops\r\n\t)\r\n\tconst [local, rest] = splitProps(merge, [\r\n\t\t\"orientation\",\r\n\t\t\"opts\",\r\n\t\t\"setApi\",\r\n\t\t\"plugins\",\r\n\t\t\"class\",\r\n\t\t\"children\",\r\n\t])\r\n\r\n\tconst [carouselRef, api] = createEmblaCarousel(\r\n\t\t() => ({\r\n\t\t\t...local.opts,\r\n\t\t\taxis: local.orientation === \"horizontal\" ? \"x\" : \"y\",\r\n\t\t}),\r\n\t\t() => (local.plugins === undefined ? [] : local.plugins)\r\n\t)\r\n\tconst [canScrollPrev, setCanScrollPrev] = createSignal(false)\r\n\tconst [canScrollNext, setCanScrollNext] = createSignal(false)\r\n\r\n\tconst onSelect = (api: NonNullable>) => {\r\n\t\tsetCanScrollPrev(api.canScrollPrev())\r\n\t\tsetCanScrollNext(api.canScrollNext())\r\n\t}\r\n\r\n\tconst scrollPrev = () => {\r\n\t\tapi()?.scrollPrev()\r\n\t}\r\n\r\n\tconst scrollNext = () => {\r\n\t\tapi()?.scrollNext()\r\n\t}\r\n\r\n\tconst handleKeyDown = (event: KeyboardEvent) => {\r\n\t\tif (event.key === \"ArrowLeft\") {\r\n\t\t\tevent.preventDefault()\r\n\t\t\tscrollPrev()\r\n\t\t} else if (event.key === \"ArrowRight\") {\r\n\t\t\tevent.preventDefault()\r\n\t\t\tscrollNext()\r\n\t\t}\r\n\t}\r\n\r\n\tcreateEffect(() => {\r\n\t\tif (!api() || !local.setApi) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tlocal.setApi(api)\r\n\t})\r\n\r\n\tcreateEffect(() => {\r\n\t\tif (!api()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tonSelect(api()!)\r\n\t\tapi()!.on(\"reInit\", onSelect)\r\n\t\tapi()!.on(\"select\", onSelect)\r\n\r\n\t\treturn () => {\r\n\t\t\tapi()?.off(\"select\", onSelect)\r\n\t\t}\r\n\t})\r\n\r\n\tconst value = createMemo(\r\n\t\t() =>\r\n\t\t\t({\r\n\t\t\t\tcarouselRef,\r\n\t\t\t\tapi,\r\n\t\t\t\topts: local.opts,\r\n\t\t\t\torientation:\r\n\t\t\t\t\tlocal.orientation ||\r\n\t\t\t\t\t(local.opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\r\n\t\t\t\tscrollPrev,\r\n\t\t\t\tscrollNext,\r\n\t\t\t\tcanScrollPrev,\r\n\t\t\t\tcanScrollNext,\r\n\t\t\t}) satisfies CarouselContextProps\r\n\t)\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\t\t{local.children}\r\n\t\t\t\r\n\t\t\r\n\t)\r\n}\r\n\r\nexport const CarouselContent: ParentComponent> = (\r\n\tprops\r\n) => {\r\n\tconst [local, rest] = splitProps(props, [\"class\"])\r\n\tconst { carouselRef, orientation } = useCarousel()\r\n\r\n\treturn (\r\n\t\t
\r\n\t\t\t\r\n\t\t
\r\n\t)\r\n}\r\n\r\nexport const CarouselItem: ParentComponent> = (props) => {\r\n\tconst [local, rest] = splitProps(props, [\"class\"])\r\n\tconst { orientation } = useCarousel()\r\n\r\n\treturn (\r\n\t\t\r\n\t)\r\n}\r\n\r\nexport const CarouselPrevious: VoidComponent> = (\r\n\tprops\r\n) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ variant: \"outline\", size: \"icon\" } as ComponentProps,\r\n\t\tprops\r\n\t)\r\n\tconst [local, rest] = splitProps(merge, [\"class\", \"variant\", \"size\"])\r\n\tconst { orientation, scrollPrev, canScrollPrev } = useCarousel()\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\tPrevious slide\r\n\t\t\r\n\t)\r\n}\r\n\r\nexport const CarouselNext: VoidComponent> = (\r\n\tprops\r\n) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ variant: \"outline\", size: \"icon\" } as ComponentProps,\r\n\t\tprops\r\n\t)\r\n\tconst [local, rest] = splitProps(merge, [\"class\", \"variant\", \"size\"])\r\n\tconst { orientation, scrollNext, canScrollNext } = useCarousel()\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\tNext slide\r\n\t\t\r\n\t)\r\n}\r\n" + } + ], + "type": "components:ui" +} \ No newline at end of file diff --git a/apps/www/public/registry/styles/default/pagination.json b/apps/www/public/registry/styles/default/pagination.json new file mode 100644 index 00000000..d817c902 --- /dev/null +++ b/apps/www/public/registry/styles/default/pagination.json @@ -0,0 +1,13 @@ +{ + "name": "pagination", + "dependencies": [ + "@kobalte/core" + ], + "files": [ + { + "name": "pagination.tsx", + "content": "import { cn } from \"@/lib/cn\"\r\nimport { Pagination as PaginationPrimitive } from \"@kobalte/core\"\r\nimport type { VariantProps } from \"class-variance-authority\"\r\nimport type { VoidComponent } from \"solid-js\"\r\nimport { mergeProps, splitProps, type ParentComponent } from \"solid-js\"\r\nimport { buttonVariants } from \"./button\"\r\n\r\nexport const PaginationItems = PaginationPrimitive.Items\r\n\r\nexport const Pagination: ParentComponent<\r\n\tPaginationPrimitive.PaginationRootProps\r\n> = (props) => {\r\n\tconst [local, rest] = splitProps(props, [\"class\"])\r\n\r\n\treturn (\r\n\t\tul]:flex [&>ul]:flex-row [&>ul]:items-center [&>ul]:gap-1\",\r\n\t\t\t\tlocal.class\r\n\t\t\t)}\r\n\t\t\t{...rest}\r\n\t\t/>\r\n\t)\r\n}\r\n\r\nexport const PaginationItem: ParentComponent<\r\n\tPaginationPrimitive.PaginationItemProps &\r\n\t\tPick, \"size\">\r\n> = (props) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ size: \"icon\" } satisfies Pick<\r\n\t\t\tVariantProps,\r\n\t\t\t\"size\"\r\n\t\t>,\r\n\t\tprops\r\n\t)\r\n\tconst [local, rest] = splitProps(merge, [\"class\", \"size\"])\r\n\r\n\treturn (\r\n\t\t\r\n\t)\r\n}\r\n\r\nexport const PaginationEllipsis: VoidComponent<\r\n\tPaginationPrimitive.PaginationEllipsisProps\r\n> = (props) => {\r\n\tconst [local, rest] = splitProps(props, [\"class\"])\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\tMore pages\r\n\t\t\r\n\t)\r\n}\r\n\r\nexport const PaginationPrevious: VoidComponent<\r\n\tPaginationPrimitive.PaginationPreviousProps &\r\n\t\tPick, \"size\">\r\n> = (props) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ size: \"icon\" } satisfies Pick<\r\n\t\t\tVariantProps,\r\n\t\t\t\"size\"\r\n\t\t>,\r\n\t\tprops\r\n\t)\r\n\tconst [local, rest] = splitProps(merge, [\"class\", \"size\"])\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t)\r\n}\r\n\r\nexport const PaginationNext: VoidComponent<\r\n\tPaginationPrimitive.PaginationNextProps &\r\n\t\tPick, \"size\">\r\n> = (props) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ size: \"icon\" } satisfies Pick<\r\n\t\t\tVariantProps,\r\n\t\t\t\"size\"\r\n\t\t>,\r\n\t\tprops\r\n\t)\r\n\tconst [local, rest] = splitProps(merge, [\"class\", \"size\"])\r\n\r\n\treturn (\r\n\t\t\r\n\t\t\t\r\n\t\t\r\n\t)\r\n}\r\n" + } + ], + "type": "components:ui" +} \ No newline at end of file diff --git a/apps/www/src/__registry__/index.js b/apps/www/src/__registry__/index.js index baf6ce6b..6fae2440 100644 --- a/apps/www/src/__registry__/index.js +++ b/apps/www/src/__registry__/index.js @@ -46,6 +46,13 @@ export const Index = { component: lazy(() => import("@/registry/default/ui/card")), files: ["registry/default/ui/card.tsx"], }, + "carousel": { + name: "carousel", + type: "components:ui", + registryDependencies: undefined, + component: lazy(() => import("@/registry/default/ui/carousel")), + files: ["registry/default/ui/carousel.tsx"], + }, "checkbox": { name: "checkbox", type: "components:ui", @@ -109,6 +116,13 @@ export const Index = { component: lazy(() => import("@/registry/default/ui/popover")), files: ["registry/default/ui/popover.tsx"], }, + "pagination": { + name: "pagination", + type: "components:ui", + registryDependencies: undefined, + component: lazy(() => import("@/registry/default/ui/pagination")), + files: ["registry/default/ui/pagination.tsx"], + }, "progress": { name: "progress", type: "components:ui", @@ -333,6 +347,48 @@ export const Index = { component: lazy(() => import("@/registry/default/example/card-demo")), files: ["registry/default/example/card-demo.tsx"], }, + "carousel-demo": { + name: "carousel-demo", + type: "components:example", + registryDependencies: ["carousel","card"], + component: lazy(() => import("@/registry/default/example/carousel-demo")), + files: ["registry/default/example/carousel-demo.tsx"], + }, + "carousel-size": { + name: "carousel-size", + type: "components:example", + registryDependencies: ["carousel","card"], + component: lazy(() => import("@/registry/default/example/carousel-size")), + files: ["registry/default/example/carousel-size.tsx"], + }, + "carousel-api-demo": { + name: "carousel-api-demo", + type: "components:example", + registryDependencies: ["carousel","card"], + component: lazy(() => import("@/registry/default/example/carousel-api-demo")), + files: ["registry/default/example/carousel-api-demo.tsx"], + }, + "carousel-orientation": { + name: "carousel-orientation", + type: "components:example", + registryDependencies: ["carousel","card"], + component: lazy(() => import("@/registry/default/example/carousel-orientation")), + files: ["registry/default/example/carousel-orientation.tsx"], + }, + "carousel-plugin": { + name: "carousel-plugin", + type: "components:example", + registryDependencies: ["carousel","card"], + component: lazy(() => import("@/registry/default/example/carousel-plugin")), + files: ["registry/default/example/carousel-plugin.tsx"], + }, + "carousel-spacing": { + name: "carousel-spacing", + type: "components:example", + registryDependencies: ["carousel","card"], + component: lazy(() => import("@/registry/default/example/carousel-spacing")), + files: ["registry/default/example/carousel-spacing.tsx"], + }, "checkbox-demo": { name: "checkbox-demo", type: "components:example", @@ -431,6 +487,13 @@ export const Index = { component: lazy(() => import("@/registry/default/example/popover-demo")), files: ["registry/default/example/popover-demo.tsx"], }, + "pagination-demo": { + name: "pagination-demo", + type: "components:example", + registryDependencies: ["pagination"], + component: lazy(() => import("@/registry/default/example/pagination-demo")), + files: ["registry/default/example/pagination-demo.tsx"], + }, "progress-demo": { name: "progress-demo", type: "components:example", diff --git a/apps/www/src/components/mdx-components.tsx b/apps/www/src/components/mdx-components.tsx index 64558021..1c857247 100644 --- a/apps/www/src/components/mdx-components.tsx +++ b/apps/www/src/components/mdx-components.tsx @@ -49,7 +49,7 @@ export const MDXComponent = { h4: (props: ComponentProps<"h4">) => { return (

) @@ -57,7 +57,7 @@ export const MDXComponent = { h5: (props: ComponentProps<"h5">) => { return (

) @@ -65,7 +65,7 @@ export const MDXComponent = { h6: (props: ComponentProps<"h6">) => { return (
) diff --git a/apps/www/src/config/docs.ts b/apps/www/src/config/docs.ts index ca96a481..57a28cfd 100644 --- a/apps/www/src/config/docs.ts +++ b/apps/www/src/config/docs.ts @@ -77,6 +77,11 @@ export const docsConfig: TDocsConfig = { href: "/docs/figma", items: [], }, + { + title: "Changelog", + href: "/docs/changelog", + items: [], + }, ], }, { @@ -112,6 +117,12 @@ export const docsConfig: TDocsConfig = { href: "/docs/components/card", items: [], }, + { + title: "Carousel", + href: "/docs/components/carousel", + items: [], + label: "New", + }, { title: "Checkbox", href: "/docs/components/checkbox", @@ -152,6 +163,12 @@ export const docsConfig: TDocsConfig = { href: "/docs/components/image", items: [], }, + { + title: "Pagination", + href: "/docs/components/pagination", + items: [], + label: "New", + }, { title: "Popover", href: "/docs/components/popover", diff --git a/apps/www/src/registry/default/example/carousel-api-demo.tsx b/apps/www/src/registry/default/example/carousel-api-demo.tsx new file mode 100644 index 00000000..040bb293 --- /dev/null +++ b/apps/www/src/registry/default/example/carousel-api-demo.tsx @@ -0,0 +1,60 @@ +import { Index, createEffect, createSignal } from "solid-js" +import { Card, CardContent } from "../ui/card" +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, + type CarouselApi, +} from "../ui/carousel" + +const CarouselApiDemo = () => { + const [api, setApi] = createSignal>() + const [current, setCurrent] = createSignal(0) + const [count, setCount] = createSignal(0) + + const onSelect = () => { + setCurrent(api()!.selectedScrollSnap() + 1) + } + + createEffect(() => { + if (!api()) { + return + } + + setCount(api()!.scrollSnapList().length) + setCurrent(api()!.selectedScrollSnap() + 1) + + api()!.on("select", onSelect) + }) + + return ( +
+ + + + {(_, index) => ( + + + + + {index + 1} + + + + + )} + + + + + +
+ Slide {current()} of {count()} +
+
+ ) +} + +export default CarouselApiDemo diff --git a/apps/www/src/registry/default/example/carousel-demo.tsx b/apps/www/src/registry/default/example/carousel-demo.tsx new file mode 100644 index 00000000..4dd79d5e --- /dev/null +++ b/apps/www/src/registry/default/example/carousel-demo.tsx @@ -0,0 +1,37 @@ +import { Index } from "solid-js" +import { Card, CardContent } from "../ui/card" +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "../ui/carousel" + +const CarouselDemo = () => { + return ( + + + + {(_, index) => ( + +
+ + + + {index + 1} + + + +
+
+ )} +
+
+ + +
+ ) +} + +export default CarouselDemo diff --git a/apps/www/src/registry/default/example/carousel-orientation.tsx b/apps/www/src/registry/default/example/carousel-orientation.tsx new file mode 100644 index 00000000..4c4646c4 --- /dev/null +++ b/apps/www/src/registry/default/example/carousel-orientation.tsx @@ -0,0 +1,43 @@ +import { Index } from "solid-js" +import { Card, CardContent } from "../ui/card" +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "../ui/carousel" + +const CarouselOrientation = () => { + return ( + + + + {(_, index) => ( + +
+ + + + {index + 1} + + + +
+
+ )} +
+
+ + +
+ ) +} + +export default CarouselOrientation diff --git a/apps/www/src/registry/default/example/carousel-plugin.tsx b/apps/www/src/registry/default/example/carousel-plugin.tsx new file mode 100644 index 00000000..8b1b0b52 --- /dev/null +++ b/apps/www/src/registry/default/example/carousel-plugin.tsx @@ -0,0 +1,45 @@ +import Autoplay from "embla-carousel-autoplay" +import { Index } from "solid-js" +import { Card, CardContent } from "../ui/card" +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "../ui/carousel" + +const CarouselPlugin = () => { + let plugin = Autoplay({ delay: 2000, stopOnInteraction: true }) + + return ( + plugin.play(false)} + > + + + {(_, index) => ( + +
+ + + + {index + 1} + + + +
+
+ )} +
+
+ + +
+ ) +} + +export default CarouselPlugin diff --git a/apps/www/src/registry/default/example/carousel-size.tsx b/apps/www/src/registry/default/example/carousel-size.tsx new file mode 100644 index 00000000..110b0c67 --- /dev/null +++ b/apps/www/src/registry/default/example/carousel-size.tsx @@ -0,0 +1,42 @@ +import { Index } from "solid-js" +import { Card, CardContent } from "../ui/card" +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "../ui/carousel" + +const CarouselSize = () => { + return ( + + + + {(_, index) => ( + +
+ + + + {index + 1} + + + +
+
+ )} +
+
+ + +
+ ) +} + +export default CarouselSize diff --git a/apps/www/src/registry/default/example/carousel-spacing.tsx b/apps/www/src/registry/default/example/carousel-spacing.tsx new file mode 100644 index 00000000..0abb4b30 --- /dev/null +++ b/apps/www/src/registry/default/example/carousel-spacing.tsx @@ -0,0 +1,36 @@ +import { Index } from "solid-js" +import { Card, CardContent } from "../ui/card" +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "../ui/carousel" +const CarouselSpacing = () => { + return ( + + + + {(_, index) => ( + +
+ + + + {index + 1} + + + +
+
+ )} +
+
+ + +
+ ) +} + +export default CarouselSpacing diff --git a/apps/www/src/registry/default/example/pagination-demo.tsx b/apps/www/src/registry/default/example/pagination-demo.tsx new file mode 100644 index 00000000..2f85a796 --- /dev/null +++ b/apps/www/src/registry/default/example/pagination-demo.tsx @@ -0,0 +1,27 @@ +import { + Pagination, + PaginationEllipsis, + PaginationItem, + PaginationItems, + PaginationNext, + PaginationPrevious, +} from "../ui/pagination" + +const PaginationDemo = () => { + return ( + ( + {props.page} + )} + ellipsisComponent={() => } + > + + + + + ) +} + +export default PaginationDemo diff --git a/apps/www/src/registry/default/ui/carousel.tsx b/apps/www/src/registry/default/ui/carousel.tsx new file mode 100644 index 00000000..818844b9 --- /dev/null +++ b/apps/www/src/registry/default/ui/carousel.tsx @@ -0,0 +1,257 @@ +import { cn } from "@/lib/cn" +import type { CreateEmblaCarouselType } from "embla-carousel-solid" +import createEmblaCarousel from "embla-carousel-solid" + +import type { + Accessor, + ComponentProps, + ParentComponent, + VoidComponent, +} from "solid-js" +import { + createContext, + createEffect, + createMemo, + createSignal, + mergeProps, + splitProps, + useContext, +} from "solid-js" +import { Button } from "./button" + +export type CarouselApi = CreateEmblaCarouselType[1] +type UseCarouselParameters = Parameters +type CarouselOptions = NonNullable +type CarouselPlugin = NonNullable + +type CarouselProps = { + opts?: ReturnType + plugins?: ReturnType + orientation?: "horizontal" | "vertical" + setApi?: (api: CarouselApi) => void +} + +type CarouselContextProps = { + carouselRef: ReturnType[0] + api: ReturnType[1] + scrollPrev: () => void + scrollNext: () => void + canScrollPrev: Accessor + canScrollNext: Accessor +} & CarouselProps + +const CarouselContext = createContext | null>( + null +) + +const useCarousel = () => { + const context = useContext(CarouselContext) + + if (!context) { + throw new Error("useCarousel must be used within a ") + } + + return context() +} + +export const Carousel: ParentComponent< + ComponentProps<"div"> & CarouselProps +> = (props) => { + const merge = mergeProps( + { orientation: "horizontal" } as CarouselProps, + props + ) + const [local, rest] = splitProps(merge, [ + "orientation", + "opts", + "setApi", + "plugins", + "class", + "children", + ]) + + const [carouselRef, api] = createEmblaCarousel( + () => ({ + ...local.opts, + axis: local.orientation === "horizontal" ? "x" : "y", + }), + () => (local.plugins === undefined ? [] : local.plugins) + ) + const [canScrollPrev, setCanScrollPrev] = createSignal(false) + const [canScrollNext, setCanScrollNext] = createSignal(false) + + const onSelect = (api: NonNullable>) => { + setCanScrollPrev(api.canScrollPrev()) + setCanScrollNext(api.canScrollNext()) + } + + const scrollPrev = () => { + api()?.scrollPrev() + } + + const scrollNext = () => { + api()?.scrollNext() + } + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === "ArrowLeft") { + event.preventDefault() + scrollPrev() + } else if (event.key === "ArrowRight") { + event.preventDefault() + scrollNext() + } + } + + createEffect(() => { + if (!api() || !local.setApi) { + return + } + + local.setApi(api) + }) + + createEffect(() => { + if (!api()) { + return + } + + onSelect(api()!) + api()!.on("reInit", onSelect) + api()!.on("select", onSelect) + + return () => { + api()?.off("select", onSelect) + } + }) + + const value = createMemo( + () => + ({ + carouselRef, + api, + opts: local.opts, + orientation: + local.orientation || + (local.opts?.axis === "y" ? "vertical" : "horizontal"), + scrollPrev, + scrollNext, + canScrollPrev, + canScrollNext, + }) satisfies CarouselContextProps + ) + + return ( + +
+ {local.children} +
+
+ ) +} + +export const CarouselContent: ParentComponent> = ( + props +) => { + const [local, rest] = splitProps(props, ["class"]) + const { carouselRef, orientation } = useCarousel() + + return ( +
+
+
+ ) +} + +export const CarouselItem: ParentComponent> = (props) => { + const [local, rest] = splitProps(props, ["class"]) + const { orientation } = useCarousel() + + return ( +
+ ) +} + +export const CarouselPrevious: VoidComponent> = ( + props +) => { + const merge = mergeProps( + { variant: "outline", size: "icon" } as ComponentProps, + props + ) + const [local, rest] = splitProps(merge, ["class", "variant", "size"]) + const { orientation, scrollPrev, canScrollPrev } = useCarousel() + + return ( + + ) +} + +export const CarouselNext: VoidComponent> = ( + props +) => { + const merge = mergeProps( + { variant: "outline", size: "icon" } as ComponentProps, + props + ) + const [local, rest] = splitProps(merge, ["class", "variant", "size"]) + const { orientation, scrollNext, canScrollNext } = useCarousel() + + return ( + + ) +} diff --git a/apps/www/src/registry/default/ui/pagination.tsx b/apps/www/src/registry/default/ui/pagination.tsx new file mode 100644 index 00000000..f73d9c0a --- /dev/null +++ b/apps/www/src/registry/default/ui/pagination.tsx @@ -0,0 +1,128 @@ +import { cn } from "@/lib/cn" +import { Pagination as PaginationPrimitive } from "@kobalte/core" +import type { VariantProps } from "class-variance-authority" +import type { VoidComponent } from "solid-js" +import { mergeProps, splitProps, type ParentComponent } from "solid-js" +import { buttonVariants } from "./button" + +export const PaginationItems = PaginationPrimitive.Items + +export const Pagination: ParentComponent< + PaginationPrimitive.PaginationRootProps +> = (props) => { + const [local, rest] = splitProps(props, ["class"]) + + return ( + ul]:flex [&>ul]:flex-row [&>ul]:items-center [&>ul]:gap-1", + local.class + )} + {...rest} + /> + ) +} + +export const PaginationItem: ParentComponent< + PaginationPrimitive.PaginationItemProps & + Pick, "size"> +> = (props) => { + const merge = mergeProps( + { size: "icon" } satisfies Pick< + VariantProps, + "size" + >, + props + ) + const [local, rest] = splitProps(merge, ["class", "size"]) + + return ( + + ) +} + +export const PaginationEllipsis: VoidComponent< + PaginationPrimitive.PaginationEllipsisProps +> = (props) => { + const [local, rest] = splitProps(props, ["class"]) + + return ( + + + More pages + + ) +} + +export const PaginationPrevious: VoidComponent< + PaginationPrimitive.PaginationPreviousProps & + Pick, "size"> +> = (props) => { + const merge = mergeProps( + { size: "icon" } satisfies Pick< + VariantProps, + "size" + >, + props + ) + const [local, rest] = splitProps(merge, ["class", "size"]) + + return ( + + + + ) +} + +export const PaginationNext: VoidComponent< + PaginationPrimitive.PaginationNextProps & + Pick, "size"> +> = (props) => { + const merge = mergeProps( + { size: "icon" } satisfies Pick< + VariantProps, + "size" + >, + props + ) + const [local, rest] = splitProps(merge, ["class", "size"]) + + return ( + + + + ) +} diff --git a/apps/www/src/registry/registry.js b/apps/www/src/registry/registry.js index 52479943..1c219b21 100644 --- a/apps/www/src/registry/registry.js +++ b/apps/www/src/registry/registry.js @@ -34,6 +34,12 @@ const ui = [ type: "components:ui", files: ["ui/card.tsx"], }, + { + name: "carousel", + type: "components:ui", + dependencies: ["embla-carousel-solid"], + files: ["ui/carousel.tsx"], + }, { name: "checkbox", type: "components:ui", @@ -88,6 +94,12 @@ const ui = [ dependencies: ["@kobalte/core"], files: ["ui/popover.tsx"], }, + { + name: "pagination", + type: "components:ui", + dependencies: ["@kobalte/core"], + files: ["ui/pagination.tsx"], + }, { name: "progress", type: "components:ui", @@ -282,6 +294,42 @@ const example = [ registryDependencies: ["card", "button", "switch"], files: ["example/card-demo.tsx"], }, + { + name: "carousel-demo", + type: "components:example", + registryDependencies: ["carousel", "card"], + files: ["example/carousel-demo.tsx"], + }, + { + name: "carousel-size", + type: "components:example", + registryDependencies: ["carousel", "card"], + files: ["example/carousel-size.tsx"], + }, + { + name: "carousel-api-demo", + type: "components:example", + registryDependencies: ["carousel", "card"], + files: ["example/carousel-api-demo.tsx"], + }, + { + name: "carousel-orientation", + type: "components:example", + registryDependencies: ["carousel", "card"], + files: ["example/carousel-orientation.tsx"], + }, + { + name: "carousel-plugin", + type: "components:example", + registryDependencies: ["carousel", "card"], + files: ["example/carousel-plugin.tsx"], + }, + { + name: "carousel-spacing", + type: "components:example", + registryDependencies: ["carousel", "card"], + files: ["example/carousel-spacing.tsx"], + }, { name: "checkbox-demo", type: "components:example", @@ -365,6 +413,12 @@ const example = [ registryDependencies: ["popover"], files: ["example/popover-demo.tsx"], }, + { + name: "pagination-demo", + type: "components:example", + registryDependencies: ["pagination"], + files: ["example/pagination-demo.tsx"], + }, { name: "progress-demo", type: "components:example", diff --git a/apps/www/src/routes/docs.tsx b/apps/www/src/routes/docs.tsx index 5d2bccb7..e6cb10a9 100644 --- a/apps/www/src/routes/docs.tsx +++ b/apps/www/src/routes/docs.tsx @@ -11,16 +11,15 @@ import { Balancer } from "solid-wrap-balancer" type Heading = { depth: number; text: string; slug: string } -type Kolbate = { - link: string - api: string -} - type Frontmatter = { title: string description: string component?: boolean - kobalte?: Kolbate + link?: { + doc: string + api: string + } + toc: boolean } const contents = /*#__PURE__*/ import.meta.glob< @@ -102,18 +101,17 @@ const Documents = (props: RouteSectionProps) => {

- +
- diff --git a/apps/www/src/routes/docs/changelog.mdx b/apps/www/src/routes/docs/changelog.mdx new file mode 100644 index 00000000..2bf4e738 --- /dev/null +++ b/apps/www/src/routes/docs/changelog.mdx @@ -0,0 +1,61 @@ +--- +title: Changelog +description: Latest updates and announcements. +toc: false +--- + +## February 2024 - New components, CLI and more + +We've added new components to shadcn-solid and made a improvements to the CLI. + +Here's a quick overview of what's new: + +- [**Carousel**](#carousel) - A carousel component with motion, swipe gestures and keyboard support. +- [**Pagination**](#pagination) - A pagination component allows the user to select a specific page from a range of pages. +- [**CLI updates**](#cli-updates) - Support for custom **Tailwind prefix**, remove `style` and add support for **custom ui dir**. + +### Carousel + +We've added a fully featured carousel component with motion, swipe gestures and keyboard support. Built on top of [Embla Carousel](https://www.embla-carousel.com). + +It has support for infinite looping, autoplay, vertical orientation, and more. + + + +### Pagination + +We've added a pagination component with page navigation, previous and next buttons. Simple and flexible. + + + +### CLI updates + +- Remove `style` property + + In this update, the `style` property has been removed, but there's a possibility of its return if additional styling features are introduced in future updates. + +- Support **custom ui dir** + + You can use this config to customize the installation directory for your `ui` components. + + ```json title="components.json" + { + "aliases": { + "ui": "@/ui" + } + } + ``` + +- Support custom **Tailwind prefix** + + You can now configure a custom Tailwind prefix and the cli will automatically prefix your utility classes when adding components. + + A drop-in for your existing design system with no conflict. 🔥 + + ```tsx /tw-/ + + ``` + + It works with `cn`, `cva` and CSS variables. + +That's it. Happy Lunar New Year. diff --git a/apps/www/src/routes/docs/components/accordion.mdx b/apps/www/src/routes/docs/components/accordion.mdx index c39f490c..3892182d 100644 --- a/apps/www/src/routes/docs/components/accordion.mdx +++ b/apps/www/src/routes/docs/components/accordion.mdx @@ -2,14 +2,14 @@ title: Accordion description: A vertically stacked set of interactive headings that each reveal a section of content. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/accordion +link: + doc: https://kobalte.dev/docs/core/components/accordion api: https://kobalte.dev/docs/core/components/accordion#api-reference --- ## Installation @@ -17,9 +17,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -39,24 +39,24 @@ Add the following animations to your `tailwind.config.js` file: ```js title="tailwind.config.cjs" {5-18} /** @type {import('tailwindcss').Config} */ module.exports = { - theme: { - extend: { - keyframes: { - "accordion-down": { - from: { height: 0 }, - to: { height: "var(--kb-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--kb-accordion-content-height)" }, - to: { height: 0 }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - }, + theme: { + extend: { + keyframes: { + "accordion-down": { + from: { height: 0 }, + to: { height: "var(--kb-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--kb-accordion-content-height)" }, + to: { height: 0 }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, + }, } ``` @@ -87,24 +87,24 @@ Add the following animations to your `tailwind.config.cjs` file: ```js title="tailwind.config.cjs" {5-18} /** @type {import('tailwindcss').Config} */ module.exports = { - theme: { - extend: { - keyframes: { - "accordion-down": { - from: { height: 0 }, - to: { height: "var(--kb-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--kb-accordion-content-height)" }, - to: { height: 0 }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - }, + theme: { + extend: { + keyframes: { + "accordion-down": { + from: { height: 0 }, + to: { height: "var(--kb-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--kb-accordion-content-height)" }, + to: { height: 0 }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, + }, } ``` @@ -118,20 +118,20 @@ module.exports = { ```tsx import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, } from "@/components/ui/accordion" ``` ```tsx - - Is it accessible? - - Yes. It adheres to the WAI-ARIA design pattern. - - + + Is it accessible? + + Yes. It adheres to the WAI-ARIA design pattern. + + ``` diff --git a/apps/www/src/routes/docs/components/alert-dialog.mdx b/apps/www/src/routes/docs/components/alert-dialog.mdx index dcfe2c05..a8e003d5 100644 --- a/apps/www/src/routes/docs/components/alert-dialog.mdx +++ b/apps/www/src/routes/docs/components/alert-dialog.mdx @@ -2,8 +2,8 @@ title: Alert Dialog description: A modal dialog that interrupts the user with important content and expects a response. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/alert-dialog +link: + doc: https://kobalte.dev/docs/core/components/alert-dialog api: https://kobalte.dev/docs/core/components/alert-dialog#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,33 +53,33 @@ npm install @kobalte/core ```tsx import { - AlertDialog, - AlertDialogClose, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger, - AlertDialogAction, + AlertDialog, + AlertDialogClose, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, + AlertDialogAction, } from "@/components/ui/alert-dialog" ``` ```tsx - Open - - - Are you absolutely sure? - - This action cannot be undone. This will permanently delete your - account and remove your data from our servers. - - - - Cancel - Continue - - + Open + + + Are you absolutely sure? + + This action cannot be undone. This will permanently delete your + account and remove your data from our servers. + + + + Cancel + Continue + + ``` diff --git a/apps/www/src/routes/docs/components/alert.mdx b/apps/www/src/routes/docs/components/alert.mdx index e01005fe..ca8a5219 100644 --- a/apps/www/src/routes/docs/components/alert.mdx +++ b/apps/www/src/routes/docs/components/alert.mdx @@ -2,8 +2,8 @@ title: Alert description: Displays a callout for user attention. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/alert +link: + doc: https://kobalte.dev/docs/core/components/alert api: https://kobalte.dev/docs/core/components/alert#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -57,12 +57,12 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" ```tsx - - Heads up! - - You can not add components and dependencies to your app using the cli, - yet. - + + Heads up! + + You can not add components and dependencies to your app using the cli, + yet. + ``` diff --git a/apps/www/src/routes/docs/components/button.mdx b/apps/www/src/routes/docs/components/button.mdx index 1cde711b..c224b089 100644 --- a/apps/www/src/routes/docs/components/button.mdx +++ b/apps/www/src/routes/docs/components/button.mdx @@ -2,8 +2,8 @@ title: Button description: Displays a button or a component that looks like a button. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/button +link: + doc: https://kobalte.dev/docs/core/components/button api: https://kobalte.dev/docs/core/components/button#api-reference --- diff --git a/apps/www/src/routes/docs/components/carousel.mdx b/apps/www/src/routes/docs/components/carousel.mdx new file mode 100644 index 00000000..46714ad6 --- /dev/null +++ b/apps/www/src/routes/docs/components/carousel.mdx @@ -0,0 +1,282 @@ +--- +title: Carousel +description: A carousel with motion and swipe built using Embla. +component: true +link: + doc: https://www.embla-carousel.com/get-started/solid + api: https://www.embla-carousel.com/api +--- + + + +## About + +The carousel component is built using the [Embla Carousel](https://www.embla-carousel.com/) library. + +## Installation + + + + + CLI + Manual + + + + + +```bash +npx shadcn-solid@latest add carousel +``` + + + + + + + +Install the following dependencies: + +```bash +npm install embla-carousel-solid +``` + +Copy and paste the following code into your project. + + + +Update the import paths to match your project setup. + + + + + + + +## Usage + +```tsx +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@/components/ui/carousel" +``` + +```tsx + + + ... + ... + ... + + + + +``` + +## Examples + +### Sizes + +To set the size of the items, you can use the `basis` utility class on the ``. + + + +```tsx title="Example" showLineNumbers {4-6} +// 33% of the carousel width. + + + ... + ... + ... + + +``` + +```tsx title="Responsive" showLineNumbers {4-6} +// 50% on small screens and 33% on larger screens. + + + ... + ... + ... + + +``` + +### Spacing + +To set the spacing between the items, we use a `pl-[VALUE]` utility on the `` and a negative `-ml-[VALUE]` on the ``. + + + + **Why:** I tried to use the `gap` property or a `grid` layout on the ` + ` but it required a lot of math and mental effort to get the + spacing right. I found `pl-[VALUE]` and `-ml-[VALUE]` utilities much easier to + use. + +You can always adjust this in your own project if you need to. + + + + + + +```tsx title="Example" showLineNumbers /-ml-4/ /pl-4/ + + + ... + ... + ... + + +``` + +```tsx title="Responsive" showLineNumbers /-ml-2/ /pl-2/ /md:-ml-4/ /md:pl-4/ + + + ... + ... + ... + + +``` + +### Orientation + +Use the `orientation` prop to set the orientation of the carousel. + + + +```tsx showLineNumbers /vertical | horizontal/ + + + ... + ... + ... + + +``` + +## Options + +You can pass options to the carousel using the `opts` prop. See the [Embla Carousel docs](https://www.embla-carousel.com/api/options/) for more information. + +```tsx showLineNumbers {2-5} + + + ... + ... + ... + + +``` + +## API + +Use a state and the `setApi` props to get an instance of the carousel API. + + + +```tsx showLineNumbers {1,4,22} +import type { CarouselApi } from "@/components/ui/carousel" + +export function Example() { + const [api, setApi] = createSignal() + const [current, setCurrent] = createSignal(0) + const [count, setCount] = createSignal(0) + + createEffect(() => { + if (!api()) { + return + } + + setCount(api().scrollSnapList().length) + setCurrent(api().selectedScrollSnap() + 1) + + api().on("select", () => { + setCurrent(api().selectedScrollSnap() + 1) + }) + }) + + return ( + + + ... + ... + ... + + + ) +} +``` + +## Events + +You can listen to events using the api instance from `setApi`. + +```tsx showLineNumbers {1,4-16} +import type { CarouselApi } from "@/components/ui/carousel" + +export function Example() { + const [api, setApi] = createSignal>() + + const onSelect = () => { + // Do something on select. + } + + createEffect(() => { + if (!api()) { + return + } + + api().on("select", onSelect) + }) + + return ( + + + ... + ... + ... + + + ) +} +``` + +See the [Embla Carousel docs](https://www.embla-carousel.com/api/events/) for more information on using events. + +## Plugins + +You can use the `plugins` prop to add plugins to the carousel. + +```ts showLineNumbers {1,6-10} +import Autoplay from "embla-carousel-autoplay" + +export function Example() { + return ( + + // ... + + ) +} +``` + + + +See the [Embla Carousel docs](https://www.embla-carousel.com/api/plugins/) for more information on using plugins. diff --git a/apps/www/src/routes/docs/components/checkbox.mdx b/apps/www/src/routes/docs/components/checkbox.mdx index 0ca1ff63..c25741da 100644 --- a/apps/www/src/routes/docs/components/checkbox.mdx +++ b/apps/www/src/routes/docs/components/checkbox.mdx @@ -2,8 +2,8 @@ title: Checkbox description: A control that allows the user to toggle between checked and not checked. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/checkbox +link: + doc: https://kobalte.dev/docs/core/components/checkbox api: https://kobalte.dev/docs/core/components/checkbox#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + diff --git a/apps/www/src/routes/docs/components/collapsible.mdx b/apps/www/src/routes/docs/components/collapsible.mdx index 1b09969d..3c52597e 100644 --- a/apps/www/src/routes/docs/components/collapsible.mdx +++ b/apps/www/src/routes/docs/components/collapsible.mdx @@ -2,8 +2,8 @@ title: Collapsible description: An interactive component which expands/collapses a panel. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/collapsible +link: + doc: https://kobalte.dev/docs/core/components/collapsible api: https://kobalte.dev/docs/core/components/collapsible#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -36,24 +36,24 @@ Add the following animations to your `tailwind.config.cjs` file: ```js title="tailwind.config.cjs" {5-18} /** @type {import('tailwindcss').Config} */ module.exports = { - theme: { - extend: { - keyframes: { - "collapsible-down": { - from: { height: 0 }, - to: { height: "var(--kb-collapsible-content-height)" }, - }, - "collapsible-up": { - from: { height: "var(--kb-collapsible-content-height)" }, - to: { height: 0 }, - }, - }, - animation: { - "collapsible-down": "collapsible-down 0.2s ease-out", - "collapsible-up": "collapsible-up 0.2s ease-out", - }, - }, - }, + theme: { + extend: { + keyframes: { + "collapsible-down": { + from: { height: 0 }, + to: { height: "var(--kb-collapsible-content-height)" }, + }, + "collapsible-up": { + from: { height: "var(--kb-collapsible-content-height)" }, + to: { height: 0 }, + }, + }, + animation: { + "collapsible-down": "collapsible-down 0.2s ease-out", + "collapsible-up": "collapsible-up 0.2s ease-out", + }, + }, + }, } ``` @@ -84,24 +84,24 @@ Add the following animations to your `tailwind.config.cjs` file: ```js title="tailwind.config.cjs" {5-18} /** @type {import('tailwindcss').Config} */ module.exports = { - theme: { - extend: { - keyframes: { - "collapsible-down": { - from: { height: 0 }, - to: { height: "var(--kb-collapsible-content-height)" }, - }, - "collapsible-up": { - from: { height: "var(--kb-collapsible-content-height)" }, - to: { height: 0 }, - }, - }, - animation: { - "collapsible-down": "collapsible-down 0.2s ease-out", - "collapsible-up": "collapsible-up 0.2s ease-out", - }, - }, - }, + theme: { + extend: { + keyframes: { + "collapsible-down": { + from: { height: 0 }, + to: { height: "var(--kb-collapsible-content-height)" }, + }, + "collapsible-up": { + from: { height: "var(--kb-collapsible-content-height)" }, + to: { height: 0 }, + }, + }, + animation: { + "collapsible-down": "collapsible-down 0.2s ease-out", + "collapsible-up": "collapsible-up 0.2s ease-out", + }, + }, + }, } ``` @@ -115,19 +115,19 @@ module.exports = { ```tsx import { - Button, - Collapsible, - CollapsibleContent, - CollapsibleTrigger, + Button, + Collapsible, + CollapsibleContent, + CollapsibleTrigger, } from "@/components/ui/collapsible" ``` ```tsx - Can I use this in my project? - - Yes. Free to use for personal and commercial projects. No attribution - required. - + Can I use this in my project? + + Yes. Free to use for personal and commercial projects. No attribution + required. + ``` diff --git a/apps/www/src/routes/docs/components/combobox.mdx b/apps/www/src/routes/docs/components/combobox.mdx index 764379be..ef90c60b 100644 --- a/apps/www/src/routes/docs/components/combobox.mdx +++ b/apps/www/src/routes/docs/components/combobox.mdx @@ -2,8 +2,8 @@ title: Combobox description: Combines a text input with a listbox, allowing users to filter a list of options to items matching a query. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/combobox +link: + doc: https://kobalte.dev/docs/core/components/combobox api: https://kobalte.dev/docs/core/components/combobox#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,11 +53,11 @@ npm install @kobalte/core ```tsx import { - Combobox, - ComboboxControl, - ComboboxItem, - ComboboxTrigger, - ComboboxContent, + Combobox, + ComboboxControl, + ComboboxItem, + ComboboxTrigger, + ComboboxContent, } from "@/components/ui/combobox" import { createFilter } from "@kobalte/core" import { createSignal } from "solid-js" @@ -69,21 +69,21 @@ const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"] const filter = createFilter({ sensitivity: "base" }) const [options, setOptions] = createSignal(ALL_OPTIONS) const onInputChange = (value: string) => { - setOptions(ALL_OPTIONS.filter((option) => filter.contains(option, value))) + setOptions(ALL_OPTIONS.filter((option) => filter.contains(option, value))) } ``` ```tsx ( - {props.item.rawValue} - )} + options={options()} + onInputChange={onInputChange} + itemComponent={(props) => ( + {props.item.rawValue} + )} > - - - - + + + + ``` diff --git a/apps/www/src/routes/docs/components/context-menu.mdx b/apps/www/src/routes/docs/components/context-menu.mdx index 387fdce2..89cc2deb 100644 --- a/apps/www/src/routes/docs/components/context-menu.mdx +++ b/apps/www/src/routes/docs/components/context-menu.mdx @@ -2,8 +2,8 @@ title: Context Menu description: Displays a menu to the user — such as a set of actions or functions — triggered by a button. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/context-menu +link: + doc: https://kobalte.dev/docs/core/components/context-menu api: https://kobalte.dev/docs/core/components/context-menu#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,21 +53,21 @@ npm install @kobalte/core ```tsx import { - ContextMenu, - ContextMenuContent, - ContextMenuItem, - ContextMenuTrigger, + ContextMenu, + ContextMenuContent, + ContextMenuItem, + ContextMenuTrigger, } from "@/components/ui/context-menu" ``` ```tsx - Right click - - Profile - Billing - Team - Subscription - + Right click + + Profile + Billing + Team + Subscription + ``` diff --git a/apps/www/src/routes/docs/components/dialog.mdx b/apps/www/src/routes/docs/components/dialog.mdx index ba43c7f5..52cbd2fb 100644 --- a/apps/www/src/routes/docs/components/dialog.mdx +++ b/apps/www/src/routes/docs/components/dialog.mdx @@ -2,8 +2,8 @@ title: Dialog description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/dialog +link: + doc: https://kobalte.dev/docs/core/components/dialog api: https://kobalte.dev/docs/core/components/dialog#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,26 +53,26 @@ npm install @kobalte/core ```tsx import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, - DialogTrigger, + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, } from "@/components/ui/dialog" ``` ```tsx - Open - - - Are you sure absolutely sure? - - This action cannot be undone. This will permanently delete your - account and remove your data from our servers. - - - + Open + + + Are you sure absolutely sure? + + This action cannot be undone. This will permanently delete your + account and remove your data from our servers. + + + ``` diff --git a/apps/www/src/routes/docs/components/dropdown-menu.mdx b/apps/www/src/routes/docs/components/dropdown-menu.mdx index 773e66b5..2179ba65 100644 --- a/apps/www/src/routes/docs/components/dropdown-menu.mdx +++ b/apps/www/src/routes/docs/components/dropdown-menu.mdx @@ -2,8 +2,8 @@ title: Dropdown Menu description: Displays a menu to the user — such as a set of actions or functions — triggered by a button. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/dropdown-menu +link: + doc: https://kobalte.dev/docs/core/components/dropdown-menu api: https://kobalte.dev/docs/core/components/dropdown-menu#api-reference --- diff --git a/apps/www/src/routes/docs/components/hover-card.mdx b/apps/www/src/routes/docs/components/hover-card.mdx index b16753bd..49a45f13 100644 --- a/apps/www/src/routes/docs/components/hover-card.mdx +++ b/apps/www/src/routes/docs/components/hover-card.mdx @@ -2,8 +2,8 @@ title: Hover Card description: For sighted users to preview content available behind a link. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/hover-card +link: + doc: https://kobalte.dev/docs/core/components/hover-card api: https://kobalte.dev/docs/core/components/hover-card#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,17 +53,17 @@ npm install @kobalte/core ```tsx import { - HoverCard, - HoverCardContent, - HoverCardTrigger, + HoverCard, + HoverCardContent, + HoverCardTrigger, } from "@/components/ui/hover-card" ``` ```tsx - Hover - - SolidJS - Simple and performant reactivity for building user interfaces. - + Hover + + SolidJS - Simple and performant reactivity for building user interfaces. + ``` diff --git a/apps/www/src/routes/docs/components/image.mdx b/apps/www/src/routes/docs/components/image.mdx index 6facb40d..9d4f026f 100644 --- a/apps/www/src/routes/docs/components/image.mdx +++ b/apps/www/src/routes/docs/components/image.mdx @@ -2,8 +2,8 @@ title: Image description: An image element with an optional fallback for loading and error status. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/image +link: + doc: https://kobalte.dev/docs/core/components/image api: https://kobalte.dev/docs/core/components/image#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -57,7 +57,7 @@ import { ImageRoot, ImageFallback, ImageImage } from "@/components/ui/image" ```tsx - - HN + + HN ``` diff --git a/apps/www/src/routes/docs/components/pagination.mdx b/apps/www/src/routes/docs/components/pagination.mdx new file mode 100644 index 00000000..d969892f --- /dev/null +++ b/apps/www/src/routes/docs/components/pagination.mdx @@ -0,0 +1,70 @@ +--- +title: Pagination +description: Pagination with page navigation, next and previous links. +component: true +link: + doc: https://kobalte.dev/docs/core/components/pagination + api: https://kobalte.dev/docs/core/components/pagination#api-reference +--- + + + +## Installation + + + + + CLI + Manual + + + + +```bash +npx shadcn-solid@latest add pagination +``` + + + + + + + +Copy and paste the following code into your project. + + + +Update the import paths to match your project setup. + + + + + + + +## Usage + +```tsx +import { + Pagination, + PaginationEllipsis, + PaginationItem, + PaginationItems, + PaginationNext, + PaginationPrevious, +} from "@/components/ui/pagination" +``` + +```tsx + ( + {props.page} + )} + ellipsisComponent={() => } +> + + + + +``` diff --git a/apps/www/src/routes/docs/components/popover.mdx b/apps/www/src/routes/docs/components/popover.mdx index 11da1a35..249a868b 100644 --- a/apps/www/src/routes/docs/components/popover.mdx +++ b/apps/www/src/routes/docs/components/popover.mdx @@ -2,8 +2,8 @@ title: Popover description: Displays rich content in a portal, triggered by a button. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/popover +link: + doc: https://kobalte.dev/docs/core/components/popover api: https://kobalte.dev/docs/core/components/popover#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,15 +53,15 @@ npm install @kobalte/core ```tsx import { - Popover, - PopoverContent, - PopoverTrigger, + Popover, + PopoverContent, + PopoverTrigger, } from "@/components/ui/popover" ``` ```tsx - Open - Place content for the popover here. + Open + Place content for the popover here. ``` diff --git a/apps/www/src/routes/docs/components/progress.mdx b/apps/www/src/routes/docs/components/progress.mdx index a442f1d8..b6247f49 100644 --- a/apps/www/src/routes/docs/components/progress.mdx +++ b/apps/www/src/routes/docs/components/progress.mdx @@ -2,8 +2,8 @@ title: Progress description: Displays an indicator showing the completion progress of a task, typically displayed as a progress bar. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/progress +link: + doc: https://kobalte.dev/docs/core/components/progress api: https://kobalte.dev/docs/core/components/progress#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + diff --git a/apps/www/src/routes/docs/components/radio-group.mdx b/apps/www/src/routes/docs/components/radio-group.mdx index 43d716d2..ebd51779 100644 --- a/apps/www/src/routes/docs/components/radio-group.mdx +++ b/apps/www/src/routes/docs/components/radio-group.mdx @@ -2,8 +2,8 @@ title: Radio Group description: A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/radio-group +link: + doc: https://kobalte.dev/docs/core/components/radio-group api: https://kobalte.dev/docs/core/components/radio-group#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -57,7 +57,7 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group" ```tsx - - + + ``` diff --git a/apps/www/src/routes/docs/components/select.mdx b/apps/www/src/routes/docs/components/select.mdx index 1cebd7d0..7a41e196 100644 --- a/apps/www/src/routes/docs/components/select.mdx +++ b/apps/www/src/routes/docs/components/select.mdx @@ -2,8 +2,8 @@ title: Select description: Displays a list of options for the user to pick from—triggered by a button. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/select +link: + doc: https://kobalte.dev/docs/core/components/select api: https://kobalte.dev/docs/core/components/select#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,24 +53,24 @@ npm install @kobalte/core ```tsx import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, } from "@/components/ui/select" ``` ```tsx ``` diff --git a/apps/www/src/routes/docs/components/separator.mdx b/apps/www/src/routes/docs/components/separator.mdx index 375b2eb1..0f3db0b5 100644 --- a/apps/www/src/routes/docs/components/separator.mdx +++ b/apps/www/src/routes/docs/components/separator.mdx @@ -2,8 +2,8 @@ title: Separator description: Visually or semantically separates content. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/separator +link: + doc: https://kobalte.dev/docs/core/components/separator api: https://kobalte.dev/docs/core/components/separator#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + diff --git a/apps/www/src/routes/docs/components/sheet.mdx b/apps/www/src/routes/docs/components/sheet.mdx index f5f2ae4c..2c95c10c 100644 --- a/apps/www/src/routes/docs/components/sheet.mdx +++ b/apps/www/src/routes/docs/components/sheet.mdx @@ -2,8 +2,8 @@ title: Sheet description: Extends the Dialog component to display content that complements the main content of the screen. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/dialog +link: + doc: https://kobalte.dev/docs/core/components/dialog api: https://kobalte.dev/docs/core/components/dialog#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,27 +53,27 @@ npm install @kobalte/core ```tsx import { - Sheet, - SheetContent, - SheetDescription, - SheetHeader, - SheetTitle, - SheetTrigger, + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, + SheetTrigger, } from "@/components/ui/sheet" ``` ```tsx - Open - - - Are you sure absolutely sure? - - This action cannot be undone. This will permanently delete your - account and remove your data from our servers. - - - + Open + + + Are you sure absolutely sure? + + This action cannot be undone. This will permanently delete your + account and remove your data from our servers. + + + ``` @@ -91,15 +91,15 @@ You can adjust the size of the sheet using CSS classes: ```tsx {3} - Open - - - Are you sure absolutely sure? - - This action cannot be undone. This will permanently delete your - account and remove your data from our servers. - - - + Open + + + Are you sure absolutely sure? + + This action cannot be undone. This will permanently delete your + account and remove your data from our servers. + + + ``` diff --git a/apps/www/src/routes/docs/components/switch.mdx b/apps/www/src/routes/docs/components/switch.mdx index 4f945e2a..ef11b137 100644 --- a/apps/www/src/routes/docs/components/switch.mdx +++ b/apps/www/src/routes/docs/components/switch.mdx @@ -2,8 +2,8 @@ title: Switch description: A control that allows the user to toggle between checked and not checked. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/switch +link: + doc: https://kobalte.dev/docs/core/components/switch api: https://kobalte.dev/docs/core/components/switch#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -57,8 +57,8 @@ import { Switch, SwitchControl, SwitchThumb } from "@/components/ui/switch" ```tsx - - - + + + ``` diff --git a/apps/www/src/routes/docs/components/tabs.mdx b/apps/www/src/routes/docs/components/tabs.mdx index 3f081c91..d2697bf1 100644 --- a/apps/www/src/routes/docs/components/tabs.mdx +++ b/apps/www/src/routes/docs/components/tabs.mdx @@ -2,8 +2,8 @@ title: Tabs description: A set of layered sections of content—known as tab panels—that are displayed one at a time. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/tabs +link: + doc: https://kobalte.dev/docs/core/components/tabs api: https://kobalte.dev/docs/core/components/tabs#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -57,13 +57,13 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" ```tsx - - Account - Password - - - Make changes to your account here. - - Change your password here. + + Account + Password + + + Make changes to your account here. + + Change your password here. ``` diff --git a/apps/www/src/routes/docs/components/textarea.mdx b/apps/www/src/routes/docs/components/textarea.mdx index 99e3d12f..432ecd6e 100644 --- a/apps/www/src/routes/docs/components/textarea.mdx +++ b/apps/www/src/routes/docs/components/textarea.mdx @@ -2,8 +2,8 @@ title: Textarea description: A textarea that allow users to input custom text entries with a keyboard. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/text-field +link: + doc: https://kobalte.dev/docs/core/components/text-field api: https://kobalte.dev/docs/core/components/text-field#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -58,7 +58,7 @@ import { TextField } from "@/components/ui/textfield" ```tsx - + ``` diff --git a/apps/www/src/routes/docs/components/textfield.mdx b/apps/www/src/routes/docs/components/textfield.mdx index 51158b14..17debb1a 100644 --- a/apps/www/src/routes/docs/components/textfield.mdx +++ b/apps/www/src/routes/docs/components/textfield.mdx @@ -2,8 +2,8 @@ title: TextField description: A text input that allow users to input custom text entries with a keyboard. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/text-field +link: + doc: https://kobalte.dev/docs/core/components/text-field api: https://kobalte.dev/docs/core/components/text-field#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -57,7 +57,7 @@ import { TextField, TextFieldInput } from "@/components/ui/textfield" ```tsx - + ``` diff --git a/apps/www/src/routes/docs/components/toggle.mdx b/apps/www/src/routes/docs/components/toggle.mdx index fd2f60e3..dcc934e5 100644 --- a/apps/www/src/routes/docs/components/toggle.mdx +++ b/apps/www/src/routes/docs/components/toggle.mdx @@ -2,8 +2,8 @@ title: Toggle description: A two-state button that can be either on or off. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/toggle-button +link: + doc: https://kobalte.dev/docs/core/components/toggle-button api: https://kobalte.dev/docs/core/components/toggle-button#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + diff --git a/apps/www/src/routes/docs/components/tooltip.mdx b/apps/www/src/routes/docs/components/tooltip.mdx index acf9bd8c..05c10de4 100644 --- a/apps/www/src/routes/docs/components/tooltip.mdx +++ b/apps/www/src/routes/docs/components/tooltip.mdx @@ -2,8 +2,8 @@ title: Tooltip description: A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it. component: true -kobalte: - link: https://kobalte.dev/docs/core/components/tooltip +link: + doc: https://kobalte.dev/docs/core/components/tooltip api: https://kobalte.dev/docs/core/components/tooltip#api-reference --- @@ -14,9 +14,9 @@ kobalte: - CLI - Manual - + CLI + Manual + @@ -53,17 +53,17 @@ npm install @kobalte/core ```tsx import { - Tooltip, - TooltipContent, - TooltipTrigger, + Tooltip, + TooltipContent, + TooltipTrigger, } from "@/components/ui/tooltip" ``` ```tsx - Hover - -

Add to library

-
+ Hover + +

Add to library

+
``` diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85842bb7..d90a40cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,6 +68,12 @@ importers: clsx: specifier: ^2.1.0 version: 2.1.0 + embla-carousel-autoplay: + specifier: 8.0.0-rc22 + version: 8.0.0-rc22(embla-carousel@8.0.0-rc22) + embla-carousel-solid: + specifier: 8.0.0-rc22 + version: 8.0.0-rc22(solid-js@1.8.14) solid-js: specifier: ^1.8.14 version: 1.8.14 @@ -3894,6 +3900,36 @@ packages: /electron-to-chromium@1.4.657: resolution: {integrity: sha512-On2ymeleg6QbRuDk7wNgDdXtNqlJLM2w4Agx1D/RiTmItiL+a9oq5p7HUa2ZtkAtGBe/kil2dq/7rPfkbe0r5w==} + /embla-carousel-autoplay@8.0.0-rc22(embla-carousel@8.0.0-rc22): + resolution: {integrity: sha512-UFR9ocKapxuYwcAOv8mb6Rmy7TENpzzHTymKADzB1L5dAJJxjUtOci/OpE3KrZedQaniLMz3HIO9hHqgj1h/3w==} + peerDependencies: + embla-carousel: 8.0.0-rc22 + dependencies: + embla-carousel: 8.0.0-rc22 + dev: false + + /embla-carousel-reactive-utils@8.0.0-rc22(embla-carousel@8.0.0-rc22): + resolution: {integrity: sha512-K4b8QhQGXYW5wr4l+U6XryhafsFV5c/IyohDnZN3MGoYIB9xY7qpjUWAcs5bTDjAD+qCZPOuXre0D3IVa28mqw==} + peerDependencies: + embla-carousel: 8.0.0-rc22 + dependencies: + embla-carousel: 8.0.0-rc22 + dev: false + + /embla-carousel-solid@8.0.0-rc22(solid-js@1.8.14): + resolution: {integrity: sha512-WBL0Hh1gnyuHaAqtbQggbQrX0F/RbCbthgsQq68Q15jgohVvSPrUCDFF6HlYrfUWHx3+TcRVgKH+BIkwXTQGAg==} + peerDependencies: + solid-js: ^1.0.0 + dependencies: + embla-carousel: 8.0.0-rc22 + embla-carousel-reactive-utils: 8.0.0-rc22(embla-carousel@8.0.0-rc22) + solid-js: 1.8.14 + dev: false + + /embla-carousel@8.0.0-rc22: + resolution: {integrity: sha512-MeXnPT1LShfgAu8qXj3CskayV0R6OkHx7w3cPTx+Q5ZWKyShKpIuu7qVQJ5BoFegalE4n6yxqoQaRuGFbK9pYw==} + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}