Skip to content

Commit

Permalink
feat: new components
Browse files Browse the repository at this point in the history
  • Loading branch information
hngngn committed Feb 9, 2024
1 parent 6696395 commit e7a1fd0
Show file tree
Hide file tree
Showing 47 changed files with 1,686 additions and 378 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
2 changes: 2 additions & 0 deletions apps/www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
20 changes: 20 additions & 0 deletions apps/www/public/registry/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@
],
"type": "components:ui"
},
{
"name": "carousel",
"dependencies": [
"embla-carousel-solid"
],
"files": [
"ui/carousel.tsx"
],
"type": "components:ui"
},
{
"name": "checkbox",
"dependencies": [
Expand Down Expand Up @@ -146,6 +156,16 @@
],
"type": "components:ui"
},
{
"name": "pagination",
"dependencies": [
"@kobalte/core"
],
"files": [
"ui/pagination.tsx"
],
"type": "components:ui"
},
{
"name": "progress",
"dependencies": [
Expand Down
13 changes: 13 additions & 0 deletions apps/www/public/registry/styles/default/carousel.json
Original file line number Diff line number Diff line change
@@ -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<typeof createEmblaCarousel>\r\ntype CarouselOptions = NonNullable<UseCarouselParameters[0]>\r\ntype CarouselPlugin = NonNullable<UseCarouselParameters[1]>\r\n\r\ntype CarouselProps = {\r\n\topts?: ReturnType<CarouselOptions>\r\n\tplugins?: ReturnType<CarouselPlugin>\r\n\torientation?: \"horizontal\" | \"vertical\"\r\n\tsetApi?: (api: CarouselApi) => void\r\n}\r\n\r\ntype CarouselContextProps = {\r\n\tcarouselRef: ReturnType<typeof createEmblaCarousel>[0]\r\n\tapi: ReturnType<typeof createEmblaCarousel>[1]\r\n\tscrollPrev: () => void\r\n\tscrollNext: () => void\r\n\tcanScrollPrev: Accessor<boolean>\r\n\tcanScrollNext: Accessor<boolean>\r\n} & CarouselProps\r\n\r\nconst CarouselContext = createContext<Accessor<CarouselContextProps> | 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 <Carousel />\")\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<ReturnType<CarouselApi>>) => {\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<CarouselContext.Provider value={value}>\r\n\t\t\t<div\r\n\t\t\t\tonKeyDown={handleKeyDown}\r\n\t\t\t\tclass={cn(\"relative\", local.class)}\r\n\t\t\t\trole=\"region\"\r\n\t\t\t\taria-roledescription=\"carousel\"\r\n\t\t\t\t{...rest}\r\n\t\t\t>\r\n\t\t\t\t{local.children}\r\n\t\t\t</div>\r\n\t\t</CarouselContext.Provider>\r\n\t)\r\n}\r\n\r\nexport const CarouselContent: ParentComponent<ComponentProps<\"div\">> = (\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<div ref={carouselRef} class=\"overflow-hidden\">\r\n\t\t\t<div\r\n\t\t\t\tclass={cn(\r\n\t\t\t\t\t\"flex\",\r\n\t\t\t\t\torientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\r\n\t\t\t\t\tlocal.class\r\n\t\t\t\t)}\r\n\t\t\t\t{...rest}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t)\r\n}\r\n\r\nexport const CarouselItem: ParentComponent<ComponentProps<\"div\">> = (props) => {\r\n\tconst [local, rest] = splitProps(props, [\"class\"])\r\n\tconst { orientation } = useCarousel()\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\trole=\"group\"\r\n\t\t\taria-roledescription=\"slide\"\r\n\t\t\tclass={cn(\r\n\t\t\t\t\"min-w-0 shrink-0 grow-0 basis-full\",\r\n\t\t\t\torientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\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 CarouselPrevious: VoidComponent<ComponentProps<typeof Button>> = (\r\n\tprops\r\n) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ variant: \"outline\", size: \"icon\" } as ComponentProps<typeof Button>,\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<Button\r\n\t\t\tvariant={local.variant}\r\n\t\t\tsize={local.size}\r\n\t\t\tclass={cn(\r\n\t\t\t\t\"absolute h-8 w-8 rounded-full\",\r\n\t\t\t\torientation === \"horizontal\"\r\n\t\t\t\t\t? \"-left-12 top-1/2 -translate-y-1/2\"\r\n\t\t\t\t\t: \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\r\n\t\t\t\tlocal.class\r\n\t\t\t)}\r\n\t\t\tdisabled={!canScrollPrev()}\r\n\t\t\tonClick={scrollPrev}\r\n\t\t\t{...rest}\r\n\t\t>\r\n\t\t\t<span class=\"icon-[tabler--arrow-left] h-4 w-4\" />\r\n\t\t\t<span class=\"sr-only\">Previous slide</span>\r\n\t\t</Button>\r\n\t)\r\n}\r\n\r\nexport const CarouselNext: VoidComponent<ComponentProps<typeof Button>> = (\r\n\tprops\r\n) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ variant: \"outline\", size: \"icon\" } as ComponentProps<typeof Button>,\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<Button\r\n\t\t\tvariant={local.variant}\r\n\t\t\tsize={local.size}\r\n\t\t\tclass={cn(\r\n\t\t\t\t\"absolute h-8 w-8 rounded-full\",\r\n\t\t\t\torientation === \"horizontal\"\r\n\t\t\t\t\t? \"-right-12 top-1/2 -translate-y-1/2\"\r\n\t\t\t\t\t: \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\r\n\t\t\t\tlocal.class\r\n\t\t\t)}\r\n\t\t\tdisabled={!canScrollNext()}\r\n\t\t\tonClick={scrollNext}\r\n\t\t\t{...rest}\r\n\t\t>\r\n\t\t\t<span class=\"icon-[tabler--arrow-right] h-4 w-4\" />\r\n\t\t\t<span class=\"sr-only\">Next slide</span>\r\n\t\t</Button>\r\n\t)\r\n}\r\n"
}
],
"type": "components:ui"
}
13 changes: 13 additions & 0 deletions apps/www/public/registry/styles/default/pagination.json
Original file line number Diff line number Diff line change
@@ -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\t<PaginationPrimitive.Root\r\n\t\t\tclass={cn(\r\n\t\t\t\t\"mx-auto flex w-full justify-center [&>ul]: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<VariantProps<typeof buttonVariants>, \"size\">\r\n> = (props) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ size: \"icon\" } satisfies Pick<\r\n\t\t\tVariantProps<typeof buttonVariants>,\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<PaginationPrimitive.Item\r\n\t\t\tclass={cn(\r\n\t\t\t\tbuttonVariants({\r\n\t\t\t\t\tvariant: \"ghost\",\r\n\t\t\t\t\tsize: local.size,\r\n\t\t\t\t}),\r\n\t\t\t\t\"aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-sm aria-[current=page]:hover:bg-accent aria-[current=page]:hover:text-accent-foreground\",\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 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<PaginationPrimitive.Ellipsis\r\n\t\t\tclass={cn(\"flex h-9 w-9 items-center justify-center\", local.class)}\r\n\t\t\t{...rest}\r\n\t\t>\r\n\t\t\t<span class=\"icon-[tabler--dots] h-4 w-4\" />\r\n\t\t\t<span class=\"sr-only\">More pages</span>\r\n\t\t</PaginationPrimitive.Ellipsis>\r\n\t)\r\n}\r\n\r\nexport const PaginationPrevious: VoidComponent<\r\n\tPaginationPrimitive.PaginationPreviousProps &\r\n\t\tPick<VariantProps<typeof buttonVariants>, \"size\">\r\n> = (props) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ size: \"icon\" } satisfies Pick<\r\n\t\t\tVariantProps<typeof buttonVariants>,\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<PaginationPrimitive.Previous\r\n\t\t\tclass={cn(\r\n\t\t\t\tbuttonVariants({\r\n\t\t\t\t\tvariant: \"ghost\",\r\n\t\t\t\t\tsize: local.size,\r\n\t\t\t\t}),\r\n\t\t\t\t\"aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-sm aria-[current=page]:hover:bg-accent aria-[current=page]:hover:text-accent-foreground\",\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\t\t<span class=\"icon-[tabler--chevron-left] h-4 w-4\" />\r\n\t\t</PaginationPrimitive.Previous>\r\n\t)\r\n}\r\n\r\nexport const PaginationNext: VoidComponent<\r\n\tPaginationPrimitive.PaginationNextProps &\r\n\t\tPick<VariantProps<typeof buttonVariants>, \"size\">\r\n> = (props) => {\r\n\tconst merge = mergeProps(\r\n\t\t{ size: \"icon\" } satisfies Pick<\r\n\t\t\tVariantProps<typeof buttonVariants>,\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<PaginationPrimitive.Next\r\n\t\t\tclass={cn(\r\n\t\t\t\tbuttonVariants({\r\n\t\t\t\t\tvariant: \"ghost\",\r\n\t\t\t\t\tsize: local.size,\r\n\t\t\t\t}),\r\n\t\t\t\t\"aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-sm aria-[current=page]:hover:bg-accent aria-[current=page]:hover:text-accent-foreground\",\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\t\t<span class=\"icon-[tabler--chevron-right] h-4 w-4\" />\r\n\t\t</PaginationPrimitive.Next>\r\n\t)\r\n}\r\n"
}
],
"type": "components:ui"
}
63 changes: 63 additions & 0 deletions apps/www/src/__registry__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
6 changes: 3 additions & 3 deletions apps/www/src/components/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,23 @@ export const MDXComponent = {
h4: (props: ComponentProps<"h4">) => {
return (
<h4
class="font-heading mt-8 scroll-m-20 text-xl font-semibold tracking-tight"
class="font-heading mt-8 scroll-m-20 text-lg font-semibold tracking-tight"
{...props}
/>
)
},
h5: (props: ComponentProps<"h5">) => {
return (
<h5
class="font-heading mt-8 scroll-m-20 text-xl font-semibold tracking-tight"
class="font-heading mt-8 scroll-m-20 text-base font-semibold tracking-tight"
{...props}
/>
)
},
h6: (props: ComponentProps<"h6">) => {
return (
<h6
class="font-heading mt-8 scroll-m-20 text-xl font-semibold tracking-tight"
class="font-heading mt-8 scroll-m-20 text-sm font-semibold tracking-tight"
{...props}
/>
)
Expand Down
17 changes: 17 additions & 0 deletions apps/www/src/config/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ export const docsConfig: TDocsConfig = {
href: "/docs/figma",
items: [],
},
{
title: "Changelog",
href: "/docs/changelog",
items: [],
},
],
},
{
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
60 changes: 60 additions & 0 deletions apps/www/src/registry/default/example/carousel-api-demo.tsx
Original file line number Diff line number Diff line change
@@ -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<ReturnType<CarouselApi>>()
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 (
<div>
<Carousel setApi={setApi} class="w-full max-w-xs">
<CarouselContent>
<Index each={Array.from({ length: 5 })}>
{(_, index) => (
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">
{index + 1}
</span>
</CardContent>
</Card>
</CarouselItem>
)}
</Index>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
<div class="py-2 text-center text-sm text-muted-foreground">
Slide {current()} of {count()}
</div>
</div>
)
}

export default CarouselApiDemo
Loading

0 comments on commit e7a1fd0

Please sign in to comment.