iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0

概念

Shadcn UI 底層使用 Radix UITailwind CSS,它不是一套元件庫,而是一個元件合集,不用像 dependency 一樣安裝它,直接選擇需要的元件貼到專案裡,或是透過 Shadcn 的 CLI 增加元件。

  • Shadcn UI 負責元件樣式
  • Radix UI 負責元件功能

不適合的對象

  • 每個元件都在專案的程式碼中,開發者必須自己去維護這些元件以及去修復相關的 bug
  • 元件都是開發者自己維護,所以打包的尺寸或是效能必須自己兼顧

而使用 Shadcn UI 可能會需要適應的地方:

  • 每一個元件都要手動安裝或是手動複製,如果過去是使用元件庫的開發者可能會不習慣
  • 元件用得越多,codebase 越大,越需要好好維護管理

範例

內容取自 When NOT to use shadcn/ui?

透過 CLI 將元件 source code 加進專案中,架構如下:

your-project
├── components
│   ├── ui
│   │   ├── button.tsx
│   │   └── card.tsx
│   ├── your-folder
│   │   └── your-component.tsx
│   └── your-another-component.tsx
└── lib
    └── utils.ts

要使用的檔案中做載入

import { Button } from "@/components/ui/button";

開發者可以完全的掌控元件,而 button.tsx 內容如下:

export const buttonVariants = cva(
  'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
  {
    variants: {
      variant: {
        default: 'bg-primary text-primary-foreground hover:bg-primary/90',
        destructive:
          'bg-destructive text-destructive-foreground hover:bg-destructive/90',
        outline:
          'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
        secondary:
          'bg-secondary text-secondary-foreground hover:bg-secondary/80',
        ghost: 'hover:bg-accent hover:text-accent-foreground',
        link: 'text-primary underline-offset-4 hover:underline',
      },
      size: {
        default: 'h-10 px-4 py-2',
        sm: 'h-9 rounded-md px-3',
        lg: 'h-11 rounded-md px-8',
        icon: 'h-10 w-10',
      },
    },
    defaultVariants: {
      variant: 'default',
      size: 'default',
    },
  },
);
 
export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  asChild?: boolean;
}
 
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, asChild = false, ...props }, ref) => {
    const Comp = asChild ? Slot : 'button';
    return (
      <Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    );
  },
);
Button.displayName = 'Button';

要做的是,在 variants 中透過 Tailwind CSS 客製成要的樣式

正如上面提到的,這大段產生的 button source code 會在專案的 source code 裡,造成維護的成本。


參考資源

Shadcn-ui : 美觀、無障礙、又能 100 % 客製化的「元件合集」
Shadcn UI adoption guide: Overview, examples, and alternatives


上一篇
[Hello World] SonarQube & SonarLint
下一篇
[Hello World] htmx & alpine
系列文
那些經過腦海一瞬的關鍵字們13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言