吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7|回复: 0
收起左侧

[其他原创] 【前端组件】用solidjs移植了shadcn

[复制链接]
thepoy 发表于 2026-4-23 12:57
本帖最后由 thepoy 于 2026-4-23 12:58 编辑

shadcn是用React框架开发,但它使用的底层组件库不是由其开发者完全控制,因此虽然很好用,但也存在着许多大大小小的bug,只能通过上游来修复。
所以我用solidjs重写了这个组件库,重写时主要参考shadcn的样式而不是其实现方式。
除了图标库外没有使用任何第三方组件库,一些shadcn依赖的上游组件库(比如sonner)也直接移植。
目前开发的主要目标是样式移植,功能缺陷和bug没有完全修复,准备在全部组件完全移植后再修复其中的bug(比如sonner本身存在着严重的bug),不支持服务端渲染
与shadcn类似,也可以直接复制组件源码到你自己的前端项目中使用,但同时也支持通过npm安装组件库在你的项目中导入本组件库的组件。
已经将移植完成的组件制成成了简单的示例,已静态部署:

Button组件的示例页:

屏幕截图 2026-04-23 125218.png

组件库名称为@neut/ui,已经上传到npm:https://www.npmjs.com/package/@neut/ui

组件库源码:https://github.com/thep0y/neut

下面是组件库结构,出于可维护性其于单一职责原则设计:

src
└── components
    └── accordion
        └── Accordion
            └── Accordion.context.tsx
            └── Accordion.styles.ts
            └── Accordion.tsx
            └── Accordion.types.ts
            └── index.ts
            └── useAccordion.ts
        └── AccordionContent
            └── AccordionContent.styles.ts
            └── AccordionContent.tsx
            └── AccordionContent.types.ts
            └── index.ts
        └── AccordionItem
            └── AccordionItem.context.tsx
            └── AccordionItem.styles.ts
            └── AccordionItem.tsx
            └── AccordionItem.types.ts
            └── index.ts
        └── AccordionTrigger
            └── AccordionTrigger.styles.ts
            └── AccordionTrigger.tsx
            └── AccordionTrigger.types.ts
            └── index.ts
        └── index.ts
    └── aspect-ratio
        └── AspectRatio.styles.ts
        └── AspectRatio.tsx
        └── AspectRatio.types.ts
        └── index.ts
    └── avatar
        └── Avatar
            └── Avatar.context.ts
            └── Avatar.tsx
            └── Avatar.types.ts
            └── index.ts
        └── AvatarBadge
            └── AvatarBadge.tsx
            └── AvatarBadge.types.ts
            └── index.ts
        └── AvatarFallback
            └── AvatarFallback.tsx
            └── AvatarFallback.types.ts
            └── index.ts
        └── AvatarGroup
            └── AvatarGroup.tsx
            └── AvatarGroup.types.ts
            └── index.ts
        └── AvatarGroupCount
            └── AvatarGroupCount.tsx
            └── AvatarGroupCount.types.ts
            └── index.ts
        └── AvatarImage
            └── AvatarImage.tsx
            └── AvatarImage.types.ts
            └── index.ts
        └── index.ts
    └── badge
        └── Badge.styles.ts
        └── Badge.tsx
        └── Badge.types.ts
        └── index.ts
    └── button
        └── Button.styles.ts
        └── Button.tsx
        └── Button.types.ts
        └── index.ts
    └── button-group
        └── ButtonGroup
            └── ButtonGroup.styles.ts
            └── ButtonGroup.tsx
            └── ButtonGroup.types.ts
            └── index.ts
        └── ButtonGroupSeparator
            └── ButtonGroupSeparator.styles.ts
            └── ButtonGroupSeparator.tsx
            └── ButtonGroupSeparator.types.ts
            └── index.ts
        └── ButtonGroupText
            └── ButtonGroupText.styles.ts
            └── ButtonGroupText.tsx
            └── ButtonGroupText.types.ts
            └── index.ts
        └── index.ts
    └── card
        └── Card
            └── Card.styles.ts
            └── Card.tsx
            └── Card.types.ts
            └── index.ts
        └── CardAction
            └── CardAction.styles.ts
            └── CardAction.tsx
            └── CardAction.types.ts
            └── index.ts
        └── CardContent
            └── CardContent.styles.ts
            └── CardContent.tsx
            └── CardContent.types.ts
            └── index.ts
        └── CardDescription
            └── CardDescription.styles.ts
            └── CardDescription.tsx
            └── CardDescription.types.ts
            └── index.ts
        └── CardFooter
            └── CardFooter.styles.ts
            └── CardFooter.tsx
            └── CardFooter.types.ts
            └── index.ts
        └── CardHeader
            └── CardHeader.styles.ts
            └── CardHeader.tsx
            └── CardHeader.types.ts
            └── index.ts
        └── CardTitle
            └── CardTitle.styles.ts
            └── CardTitle.tsx
            └── CardTitle.types.ts
            └── index.ts
        └── index.ts
    └── carousel
        └── Carousel
            └── Carousel.context.tsx
            └── Carousel.styles.ts
            └── Carousel.tsx
            └── Carousel.types.ts
            └── Carousel.utils.ts
            └── index.ts
            └── useAutoPlay.ts
            └── useCarousel.ts
            └── useKeyboardNavigation.ts
        └── CarouselContent
            └── CarouselContent.styles.ts
            └── CarouselContent.tsx
            └── CarouselContent.types.ts
            └── index.ts
            └── useItemSizeMeasure.ts
        └── CarouselDots
            └── CarouselDots.tsx
            └── CarouselDots.types.ts
            └── index.ts
        └── CarouselItem
            └── CarouselItem.tsx
            └── CarouselItem.types.ts
            └── index.ts
        └── CarouselNext
            └── CarouselNext.tsx
            └── CarouselNext.types.ts
            └── index.ts
        └── CarouselPrevious
            └── CarouselPrevious.tsx
            └── CarouselPrevious.types.ts
            └── index.ts
        └── index.ts
    └── field
        └── Field
            └── Field.styles.ts
            └── Field.tsx
            └── Field.types.ts
            └── index.ts
        └── FieldContent
            └── FieldContent.tsx
            └── FieldContent.types.ts
            └── index.ts
        └── FieldDescription
            └── FieldDescription.tsx
            └── FieldDescription.types.ts
            └── index.ts
        └── FieldError
            └── FieldError.tsx
            └── FieldError.types.ts
            └── index.ts
            └── useFieldError.ts
        └── FieldGroup
            └── FieldGroup.tsx
            └── FieldGroup.types.ts
            └── index.ts
        └── FieldLabel
            └── FieldLabel.tsx
            └── FieldLabel.types.ts
            └── index.ts
        └── FieldLegend
            └── FieldLegend.tsx
            └── FieldLegend.types.ts
            └── index.ts
        └── FieldSeparator
            └── FieldSeparator.tsx
            └── FieldSeparator.types.ts
            └── index.ts
        └── FieldSet
            └── FieldSet.tsx
            └── FieldSet.types.ts
            └── index.ts
        └── FieldTitle
            └── FieldTitle.tsx
            └── FieldTitle.types.ts
            └── index.ts
        └── index.ts
    └── image
        └── Image.config.ts
        └── Image.styles.ts
        └── Image.tsx
        └── Image.types.ts
        └── Image.utils.ts
        └── ImageElement.tsx
        └── ImagePreload.tsx
        └── index.ts
        └── useImage.ts
    └── input
        └── index.ts
        └── Input.tsx
        └── Input.types.ts
    └── input-group
        └── index.ts
        └── InputGroup
            └── index.ts
            └── InputGroup.styles.ts
            └── InputGroup.tsx
            └── InputGroup.types.ts
        └── InputGroupAddon
            └── index.ts
            └── InputGroupAddon.styles.ts
            └── InputGroupAddon.tsx
            └── InputGroupAddon.types.ts
        └── InputGroupButton
            └── index.ts
            └── InputGroupButton.styles.ts
            └── InputGroupButton.tsx
            └── InputGroupButton.types.ts
        └── InputGroupInput
            └── index.ts
            └── InputGroupInput.styles.ts
            └── InputGroupInput.tsx
            └── InputGroupInput.types.ts
        └── InputGroupText
            └── index.ts
            └── InputGroupText.styles.ts
            └── InputGroupText.tsx
            └── InputGroupText.types.ts
        └── InputGroupTextarea
            └── index.ts
            └── InputGroupTextarea.tsx
            └── InputGroupTextarea.types.ts
    └── item
        └── index.ts
        └── Item
            └── index.ts
            └── Item.styles.ts
            └── Item.tsx
            └── Item.types.ts
        └── ItemActions
            └── index.ts
            └── ItemActions.tsx
            └── ItemActions.types.ts
        └── ItemContent
            └── index.ts
            └── ItemContent.tsx
            └── ItemContent.types.ts
        └── ItemDescription
            └── index.ts
            └── ItemDescription.tsx
            └── ItemDescription.types.ts
        └── ItemFooter
            └── index.ts
            └── ItemFooter.tsx
            └── ItemFooter.types.ts
        └── ItemGroup
            └── index.ts
            └── ItemGroup.tsx
            └── ItemGroup.types.ts
        └── ItemHeader
            └── index.ts
            └── ItemHeader.tsx
            └── ItemHeader.types.ts
        └── ItemMedia
            └── index.ts
            └── ItemMedia.styles.ts
            └── ItemMedia.tsx
            └── ItemMedia.types.ts
        └── ItemSeparator
            └── index.ts
            └── ItemSeparator.tsx
            └── ItemSeparator.types.ts
        └── ItemTitle
            └── index.ts
            └── ItemTitle.tsx
            └── ItemTitle.types.ts
    └── kbd
        └── index.ts
        └── Kbd.tsx
        └── Kbd.types.ts
    └── label
        └── index.ts
        └── Label.tsx
        └── Label.types.ts
    └── pagination
        └── index.ts
        └── Pagination
            └── index.ts
            └── Pagination.tsx
            └── Pagination.types.ts
        └── PaginationContent
            └── index.ts
            └── PaginationContent.tsx
            └── PaginationContent.types.ts
        └── PaginationEllipsis
            └── index.ts
            └── PaginationEllipsis.tsx
            └── PaginationEllipsis.types.ts
        └── PaginationItem
            └── index.ts
            └── PaginationItem.tsx
            └── PaginationItem.types.ts
        └── PaginationLink
            └── index.ts
            └── PaginationLink.tsx
            └── PaginationLink.types.ts
        └── PaginationNext
            └── index.ts
            └── PaginationNext.tsx
            └── PaginationNext.types.ts
        └── PaginationPrevious
            └── index.ts
            └── PaginationPrevious.tsx
            └── PaginationPrevious.types.ts
    └── progress
        └── index.ts
        └── Progress
            └── index.ts
            └── Progress.context.ts
            └── Progress.styles.ts
            └── Progress.tsx
            └── Progress.types.ts
        └── ProgressIndicator
            └── index.ts
            └── ProgressIndicator.styles.ts
            └── ProgressIndicator.tsx
            └── ProgressIndicator.types.ts
        └── ProgressLabel
            └── index.ts
            └── ProgressLabel.styles.ts
            └── ProgressLabel.tsx
            └── ProgressLabel.types.ts
        └── ProgressTrack
            └── index.ts
            └── ProgressTrack.styles.ts
            └── ProgressTrack.tsx
            └── ProgressTrack.types.ts
        └── ProgressValue
            └── index.ts
            └── ProgressValue.styles.ts
            └── ProgressValue.tsx
            └── ProgressValue.types.ts
    └── scroll-area
        └── index.ts
        └── ScrollArea
            └── index.ts
            └── ScrollArea.context.ts
            └── ScrollArea.tsx
            └── ScrollArea.types.ts
            └── ScrollArea.utils.ts
        └── ScrollBar
            └── index.ts
            └── ScrollBar.tsx
            └── ScrollBar.types.ts
    └── separator
        └── index.ts
        └── Separator.styles.ts
        └── Separator.tsx
        └── Separator.types.ts
    └── sidebar
        └── index.ts
        └── Sidebar
            └── index.ts
            └── Sidebar.tsx
            └── Sidebar.types.ts
        └── SidebarContent
            └── index.ts
            └── SidebarContent.tsx
            └── SidebarContent.types.ts
        └── SidebarFooter
            └── index.ts
            └── SidebarFooter.tsx
            └── SidebarFooter.types.ts
        └── SidebarGroup
            └── index.ts
            └── SidebarGroup.tsx
            └── SidebarGroup.types.ts
        └── SidebarGroupAction
            └── index.ts
            └── SidebarGroupAction.tsx
            └── SidebarGroupAction.types.ts
        └── SidebarGroupContent
            └── index.ts
            └── SidebarGroupContent.tsx
            └── SidebarGroupContent.types.ts
        └── SidebarGroupLabel
            └── index.ts
            └── SidebarGroupLabel.tsx
            └── SidebarGroupLabel.types.ts
        └── SidebarHeader
            └── index.ts
            └── SidebarHeader.tsx
            └── SidebarHeader.types.ts
        └── SidebarInput
            └── index.ts
            └── SidebarInput.tsx
            └── SidebarInput.types.ts
        └── SidebarInset
            └── index.ts
            └── SidebarInset.tsx
            └── SidebarInset.types.ts
        └── SidebarMenu
            └── index.ts
            └── SidebarMenu.tsx
            └── SidebarMenu.types.ts
        └── SidebarMenuBadge
            └── index.ts
            └── SidebarMenuBadge.tsx
            └── SidebarMenuBadge.types.ts
        └── SidebarMenuButton
            └── index.ts
            └── SidebarMenuButton.styles.ts
            └── SidebarMenuButton.tsx
            └── SidebarMenuButton.types.ts
        └── SidebarMenuItem
            └── index.ts
            └── SidebarMenuItem.tsx
            └── SidebarMenuItem.types.ts
        └── SidebarMenuSkeleton
            └── index.ts
            └── SidebarMenuSkeleton.tsx
            └── SidebarMenuSkeleton.types.ts
        └── SidebarMenuSub
            └── index.ts
            └── SidebarMenuSub.tsx
            └── SidebarMenuSub.types.ts
        └── SidebarMenuSubButton
            └── index.ts
            └── SidebarMenuSubButton.tsx
            └── SidebarMenuSubButton.types.ts
        └── SidebarMenuSubItem
            └── index.ts
            └── SidebarMenuSubItem.tsx
            └── SidebarMenuSubItem.types.ts
        └── SidebarProvider
            └── index.ts
            └── SidebarProvider.consts.ts
            └── SidebarProvider.context.ts
            └── SidebarProvider.tsx
            └── SidebarProvider.types.ts
        └── SidebarRail
            └── index.ts
            └── SidebarRail.tsx
            └── SidebarRail.types.ts
        └── SidebarSeparator
            └── index.ts
            └── SidebarSeparator.tsx
            └── SidebarSeparator.types.ts
        └── SidebarTrigger
            └── index.ts
            └── SidebarTrigger.tsx
            └── SidebarTrigger.types.ts
    └── skeleton
        └── index.ts
        └── Skeleton.tsx
        └── Skeleton.types.ts
    └── slider
        └── index.ts
        └── Slider
            └── index.ts
            └── Slider.context.ts
            └── Slider.styles.ts
            └── Slider.tsx
            └── Slider.types.ts
            └── useSlider.ts
        └── SliderControl
            └── index.ts
            └── SliderControl.styles.ts
            └── SliderControl.tsx
            └── SliderControl.types.ts
            └── useSliderControl.ts
        └── SliderIndicator
            └── index.ts
            └── SliderIndicator.styles.ts
            └── SliderIndicator.tsx
            └── SliderIndicator.types.ts
            └── useSliderIndicator.ts
        └── SliderThumb
            └── index.ts
            └── SliderThumb.styles.ts
            └── SliderThumb.tsx
            └── SliderThumb.types.ts
            └── useSliderThumb.tsx
        └── SliderTrack
            └── index.ts
            └── SliderTrack.styles.ts
            └── SliderTrack.tsx
            └── SliderTrack.types.ts
    └── spinner
        └── index.ts
        └── Spinner.styles.ts
        └── Spinner.tsx
        └── Spinner.types.ts
    └── switch
        └── index.ts
        └── Switch.styles.ts
        └── Switch.tsx
        └── Switch.types.ts
    └── textarea
        └── index.ts
        └── Textarea.tsx
        └── Textarea.types.ts
    └── toast
        └── components
            └── Assets.tsx
            └── Toast.tsx
            └── ToastActions.tsx
            └── ToastContent.tsx
            └── Toaster.tsx
            └── ToastIcon.tsx
        └── constants.ts
        └── hooks
            └── useSwipe.ts
            └── useTheme.ts
            └── useToasterKeyboard.ts
            └── useToastHeight.ts
            └── useToastSubscription.ts
            └── useToastTimer.ts
        └── hooks.ts
        └── index.ts
        └── state.ts
        └── types.ts
        └── utils.ts
    └── tooltip
        └── index.ts
        └── Tooltip
            └── index.ts
            └── Tooltip.context.ts
            └── Tooltip.tsx
            └── Tooltip.types.ts
        └── TooltipArrow
            └── index.ts
            └── TooltipArrow.tsx
        └── TooltipContent
            └── index.ts
            └── TooltipContent.context.ts
            └── TooltipContent.tsx
            └── TooltipContent.types.ts
            └── TooltipContent.utils.ts
            └── useTooltipContent.ts
        └── TooltipTrigger
            └── index.ts
            └── TooltipTrigger.tsx
            └── TooltipTrigger.types.ts
            └── useTooltipTrigger.ts
└── hooks
    └── index.ts
    └── useFontLoader.ts
└── index.ts
└── styles
    └── animate.css
    └── i18n-font.css
    └── index.css
    └── toast.css
└── types
    └── index.ts
    └── props.types.ts
└── utils
    └── clsx.ts
    └── get-style.ts
    └── index.ts
    └── warn-once.ts

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-4-23 13:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表