Files
shadcn-ui/apps/v4/lib/registry.ts
shadcn 5f966a282a Merge branch 'main' into shadcn/base-docs
# Conflicts:
#	apps/v4/lib/llm.ts
#	apps/v4/lib/registry.ts
#	apps/v4/public/r/styles/base-lyra/accordion-example.json
#	apps/v4/public/r/styles/base-lyra/accordion.json
#	apps/v4/public/r/styles/base-lyra/alert-dialog-example.json
#	apps/v4/public/r/styles/base-lyra/alert-example.json
#	apps/v4/public/r/styles/base-lyra/avatar-example.json
#	apps/v4/public/r/styles/base-lyra/badge-example.json
#	apps/v4/public/r/styles/base-lyra/breadcrumb.json
#	apps/v4/public/r/styles/base-lyra/button-example.json
#	apps/v4/public/r/styles/base-lyra/button-group-example.json
#	apps/v4/public/r/styles/base-lyra/calendar-example.json
#	apps/v4/public/r/styles/base-lyra/calendar.json
#	apps/v4/public/r/styles/base-lyra/card-example.json
#	apps/v4/public/r/styles/base-lyra/carousel.json
#	apps/v4/public/r/styles/base-lyra/chart-example.json
#	apps/v4/public/r/styles/base-lyra/chatgpt.json
#	apps/v4/public/r/styles/base-lyra/checkbox.json
#	apps/v4/public/r/styles/base-lyra/collapsible-example.json
#	apps/v4/public/r/styles/base-lyra/combobox-example.json
#	apps/v4/public/r/styles/base-lyra/combobox.json
#	apps/v4/public/r/styles/base-lyra/command-example.json
#	apps/v4/public/r/styles/base-lyra/command.json
#	apps/v4/public/r/styles/base-lyra/component-example.json
#	apps/v4/public/r/styles/base-lyra/context-menu-example.json
#	apps/v4/public/r/styles/base-lyra/context-menu.json
#	apps/v4/public/r/styles/base-lyra/dialog-example.json
#	apps/v4/public/r/styles/base-lyra/dialog.json
#	apps/v4/public/r/styles/base-lyra/dropdown-menu-example.json
#	apps/v4/public/r/styles/base-lyra/dropdown-menu.json
#	apps/v4/public/r/styles/base-lyra/empty-example.json
#	apps/v4/public/r/styles/base-lyra/github.json
#	apps/v4/public/r/styles/base-lyra/input-group-example.json
#	apps/v4/public/r/styles/base-lyra/input-otp-example.json
#	apps/v4/public/r/styles/base-lyra/input-otp.json
#	apps/v4/public/r/styles/base-lyra/item-example.json
#	apps/v4/public/r/styles/base-lyra/kbd-example.json
#	apps/v4/public/r/styles/base-lyra/menubar-example.json
#	apps/v4/public/r/styles/base-lyra/menubar.json
#	apps/v4/public/r/styles/base-lyra/native-select.json
#	apps/v4/public/r/styles/base-lyra/navigation-menu-example.json
#	apps/v4/public/r/styles/base-lyra/navigation-menu.json
#	apps/v4/public/r/styles/base-lyra/pagination.json
#	apps/v4/public/r/styles/base-lyra/preview.json
#	apps/v4/public/r/styles/base-lyra/progress-example.json
#	apps/v4/public/r/styles/base-lyra/radio-group.json
#	apps/v4/public/r/styles/base-lyra/select-example.json
#	apps/v4/public/r/styles/base-lyra/select.json
#	apps/v4/public/r/styles/base-lyra/sheet.json
#	apps/v4/public/r/styles/base-lyra/sidebar-example.json
#	apps/v4/public/r/styles/base-lyra/sidebar-floating-example.json
#	apps/v4/public/r/styles/base-lyra/sidebar-icon-example.json
#	apps/v4/public/r/styles/base-lyra/sidebar-inset-example.json
#	apps/v4/public/r/styles/base-lyra/sidebar.json
#	apps/v4/public/r/styles/base-lyra/spinner-example.json
#	apps/v4/public/r/styles/base-lyra/spinner.json
#	apps/v4/public/r/styles/base-lyra/table-example.json
#	apps/v4/public/r/styles/base-lyra/tabs-example.json
#	apps/v4/public/r/styles/base-lyra/toggle-example.json
#	apps/v4/public/r/styles/base-lyra/toggle-group-example.json
#	apps/v4/public/r/styles/base-lyra/tooltip-example.json
#	apps/v4/public/r/styles/base-lyra/vercel.json
#	apps/v4/public/r/styles/base-maia/accordion-example.json
#	apps/v4/public/r/styles/base-maia/accordion.json
#	apps/v4/public/r/styles/base-maia/alert-dialog-example.json
#	apps/v4/public/r/styles/base-maia/alert-example.json
#	apps/v4/public/r/styles/base-maia/avatar-example.json
#	apps/v4/public/r/styles/base-maia/badge-example.json
#	apps/v4/public/r/styles/base-maia/breadcrumb.json
#	apps/v4/public/r/styles/base-maia/button-example.json
#	apps/v4/public/r/styles/base-maia/button-group-example.json
#	apps/v4/public/r/styles/base-maia/calendar-example.json
#	apps/v4/public/r/styles/base-maia/calendar.json
#	apps/v4/public/r/styles/base-maia/card-example.json
#	apps/v4/public/r/styles/base-maia/carousel.json
#	apps/v4/public/r/styles/base-maia/chart-example.json
#	apps/v4/public/r/styles/base-maia/chatgpt.json
#	apps/v4/public/r/styles/base-maia/checkbox.json
#	apps/v4/public/r/styles/base-maia/collapsible-example.json
#	apps/v4/public/r/styles/base-maia/combobox-example.json
#	apps/v4/public/r/styles/base-maia/combobox.json
#	apps/v4/public/r/styles/base-maia/command-example.json
#	apps/v4/public/r/styles/base-maia/command.json
#	apps/v4/public/r/styles/base-maia/component-example.json
#	apps/v4/public/r/styles/base-maia/context-menu-example.json
#	apps/v4/public/r/styles/base-maia/context-menu.json
#	apps/v4/public/r/styles/base-maia/dialog-example.json
#	apps/v4/public/r/styles/base-maia/dialog.json
#	apps/v4/public/r/styles/base-maia/dropdown-menu-example.json
#	apps/v4/public/r/styles/base-maia/dropdown-menu.json
#	apps/v4/public/r/styles/base-maia/empty-example.json
#	apps/v4/public/r/styles/base-maia/github.json
#	apps/v4/public/r/styles/base-maia/input-group-example.json
#	apps/v4/public/r/styles/base-maia/input-otp-example.json
#	apps/v4/public/r/styles/base-maia/input-otp.json
#	apps/v4/public/r/styles/base-maia/item-example.json
#	apps/v4/public/r/styles/base-maia/kbd-example.json
#	apps/v4/public/r/styles/base-maia/menubar-example.json
#	apps/v4/public/r/styles/base-maia/menubar.json
#	apps/v4/public/r/styles/base-maia/native-select.json
#	apps/v4/public/r/styles/base-maia/navigation-menu-example.json
#	apps/v4/public/r/styles/base-maia/navigation-menu.json
#	apps/v4/public/r/styles/base-maia/pagination.json
#	apps/v4/public/r/styles/base-maia/preview.json
#	apps/v4/public/r/styles/base-maia/progress-example.json
#	apps/v4/public/r/styles/base-maia/radio-group.json
#	apps/v4/public/r/styles/base-maia/select-example.json
#	apps/v4/public/r/styles/base-maia/select.json
#	apps/v4/public/r/styles/base-maia/sheet.json
#	apps/v4/public/r/styles/base-maia/sidebar-example.json
#	apps/v4/public/r/styles/base-maia/sidebar-floating-example.json
#	apps/v4/public/r/styles/base-maia/sidebar-icon-example.json
#	apps/v4/public/r/styles/base-maia/sidebar-inset-example.json
#	apps/v4/public/r/styles/base-maia/sidebar.json
#	apps/v4/public/r/styles/base-maia/spinner-example.json
#	apps/v4/public/r/styles/base-maia/spinner.json
#	apps/v4/public/r/styles/base-maia/table-example.json
#	apps/v4/public/r/styles/base-maia/tabs-example.json
#	apps/v4/public/r/styles/base-maia/toggle-example.json
#	apps/v4/public/r/styles/base-maia/toggle-group-example.json
#	apps/v4/public/r/styles/base-maia/tooltip-example.json
#	apps/v4/public/r/styles/base-maia/vercel.json
#	apps/v4/public/r/styles/base-mira/accordion-example.json
#	apps/v4/public/r/styles/base-mira/accordion.json
#	apps/v4/public/r/styles/base-mira/alert-dialog-example.json
#	apps/v4/public/r/styles/base-mira/alert-example.json
#	apps/v4/public/r/styles/base-mira/avatar-example.json
#	apps/v4/public/r/styles/base-mira/badge-example.json
#	apps/v4/public/r/styles/base-mira/breadcrumb.json
#	apps/v4/public/r/styles/base-mira/button-example.json
#	apps/v4/public/r/styles/base-mira/button-group-example.json
#	apps/v4/public/r/styles/base-mira/calendar-example.json
#	apps/v4/public/r/styles/base-mira/calendar.json
#	apps/v4/public/r/styles/base-mira/card-example.json
#	apps/v4/public/r/styles/base-mira/carousel.json
#	apps/v4/public/r/styles/base-mira/chart-example.json
#	apps/v4/public/r/styles/base-mira/chatgpt.json
#	apps/v4/public/r/styles/base-mira/checkbox.json
#	apps/v4/public/r/styles/base-mira/collapsible-example.json
#	apps/v4/public/r/styles/base-mira/combobox-example.json
#	apps/v4/public/r/styles/base-mira/combobox.json
#	apps/v4/public/r/styles/base-mira/command-example.json
#	apps/v4/public/r/styles/base-mira/command.json
#	apps/v4/public/r/styles/base-mira/component-example.json
#	apps/v4/public/r/styles/base-mira/context-menu-example.json
#	apps/v4/public/r/styles/base-mira/context-menu.json
#	apps/v4/public/r/styles/base-mira/dialog-example.json
#	apps/v4/public/r/styles/base-mira/dialog.json
#	apps/v4/public/r/styles/base-mira/dropdown-menu-example.json
#	apps/v4/public/r/styles/base-mira/dropdown-menu.json
#	apps/v4/public/r/styles/base-mira/empty-example.json
#	apps/v4/public/r/styles/base-mira/github.json
#	apps/v4/public/r/styles/base-mira/input-group-example.json
#	apps/v4/public/r/styles/base-mira/input-otp-example.json
#	apps/v4/public/r/styles/base-mira/input-otp.json
#	apps/v4/public/r/styles/base-mira/item-example.json
#	apps/v4/public/r/styles/base-mira/kbd-example.json
#	apps/v4/public/r/styles/base-mira/menubar-example.json
#	apps/v4/public/r/styles/base-mira/menubar.json
#	apps/v4/public/r/styles/base-mira/native-select.json
#	apps/v4/public/r/styles/base-mira/navigation-menu-example.json
#	apps/v4/public/r/styles/base-mira/navigation-menu.json
#	apps/v4/public/r/styles/base-mira/pagination.json
#	apps/v4/public/r/styles/base-mira/preview.json
#	apps/v4/public/r/styles/base-mira/progress-example.json
#	apps/v4/public/r/styles/base-mira/radio-group.json
#	apps/v4/public/r/styles/base-mira/select-example.json
#	apps/v4/public/r/styles/base-mira/select.json
#	apps/v4/public/r/styles/base-mira/sheet.json
#	apps/v4/public/r/styles/base-mira/sidebar-example.json
#	apps/v4/public/r/styles/base-mira/sidebar-floating-example.json
#	apps/v4/public/r/styles/base-mira/sidebar-icon-example.json
#	apps/v4/public/r/styles/base-mira/sidebar-inset-example.json
#	apps/v4/public/r/styles/base-mira/sidebar.json
#	apps/v4/public/r/styles/base-mira/spinner-example.json
#	apps/v4/public/r/styles/base-mira/spinner.json
#	apps/v4/public/r/styles/base-mira/table-example.json
#	apps/v4/public/r/styles/base-mira/tabs-example.json
#	apps/v4/public/r/styles/base-mira/toggle-example.json
#	apps/v4/public/r/styles/base-mira/toggle-group-example.json
#	apps/v4/public/r/styles/base-mira/tooltip-example.json
#	apps/v4/public/r/styles/base-mira/vercel.json
#	apps/v4/public/r/styles/base-nova/accordion-example.json
#	apps/v4/public/r/styles/base-nova/accordion.json
#	apps/v4/public/r/styles/base-nova/alert-dialog-example.json
#	apps/v4/public/r/styles/base-nova/alert-example.json
#	apps/v4/public/r/styles/base-nova/avatar-example.json
#	apps/v4/public/r/styles/base-nova/badge-example.json
#	apps/v4/public/r/styles/base-nova/breadcrumb.json
#	apps/v4/public/r/styles/base-nova/button-example.json
#	apps/v4/public/r/styles/base-nova/button-group-example.json
#	apps/v4/public/r/styles/base-nova/calendar-example.json
#	apps/v4/public/r/styles/base-nova/calendar.json
#	apps/v4/public/r/styles/base-nova/card-example.json
#	apps/v4/public/r/styles/base-nova/carousel.json
#	apps/v4/public/r/styles/base-nova/chart-example.json
#	apps/v4/public/r/styles/base-nova/chatgpt.json
#	apps/v4/public/r/styles/base-nova/checkbox.json
#	apps/v4/public/r/styles/base-nova/collapsible-example.json
#	apps/v4/public/r/styles/base-nova/combobox-example.json
#	apps/v4/public/r/styles/base-nova/combobox.json
#	apps/v4/public/r/styles/base-nova/command-example.json
#	apps/v4/public/r/styles/base-nova/command.json
#	apps/v4/public/r/styles/base-nova/component-example.json
#	apps/v4/public/r/styles/base-nova/context-menu-example.json
#	apps/v4/public/r/styles/base-nova/context-menu.json
#	apps/v4/public/r/styles/base-nova/dialog-example.json
#	apps/v4/public/r/styles/base-nova/dialog.json
#	apps/v4/public/r/styles/base-nova/dropdown-menu-example.json
#	apps/v4/public/r/styles/base-nova/dropdown-menu.json
#	apps/v4/public/r/styles/base-nova/empty-example.json
#	apps/v4/public/r/styles/base-nova/github.json
#	apps/v4/public/r/styles/base-nova/input-group-example.json
#	apps/v4/public/r/styles/base-nova/input-otp-example.json
#	apps/v4/public/r/styles/base-nova/input-otp.json
#	apps/v4/public/r/styles/base-nova/item-example.json
#	apps/v4/public/r/styles/base-nova/kbd-example.json
#	apps/v4/public/r/styles/base-nova/menubar-example.json
#	apps/v4/public/r/styles/base-nova/menubar.json
#	apps/v4/public/r/styles/base-nova/native-select.json
#	apps/v4/public/r/styles/base-nova/navigation-menu-example.json
#	apps/v4/public/r/styles/base-nova/navigation-menu.json
#	apps/v4/public/r/styles/base-nova/pagination.json
#	apps/v4/public/r/styles/base-nova/preview.json
#	apps/v4/public/r/styles/base-nova/progress-example.json
#	apps/v4/public/r/styles/base-nova/radio-group.json
#	apps/v4/public/r/styles/base-nova/select-example.json
#	apps/v4/public/r/styles/base-nova/select.json
#	apps/v4/public/r/styles/base-nova/sheet.json
#	apps/v4/public/r/styles/base-nova/sidebar-example.json
#	apps/v4/public/r/styles/base-nova/sidebar-floating-example.json
#	apps/v4/public/r/styles/base-nova/sidebar-icon-example.json
#	apps/v4/public/r/styles/base-nova/sidebar-inset-example.json
#	apps/v4/public/r/styles/base-nova/sidebar.json
#	apps/v4/public/r/styles/base-nova/spinner-example.json
#	apps/v4/public/r/styles/base-nova/spinner.json
#	apps/v4/public/r/styles/base-nova/table-example.json
#	apps/v4/public/r/styles/base-nova/tabs-example.json
#	apps/v4/public/r/styles/base-nova/toggle-example.json
#	apps/v4/public/r/styles/base-nova/toggle-group-example.json
#	apps/v4/public/r/styles/base-nova/tooltip-example.json
#	apps/v4/public/r/styles/base-nova/vercel.json
#	apps/v4/public/r/styles/base-vega/accordion-example.json
#	apps/v4/public/r/styles/base-vega/accordion.json
#	apps/v4/public/r/styles/base-vega/alert-dialog-example.json
#	apps/v4/public/r/styles/base-vega/alert-example.json
#	apps/v4/public/r/styles/base-vega/avatar-example.json
#	apps/v4/public/r/styles/base-vega/badge-example.json
#	apps/v4/public/r/styles/base-vega/breadcrumb.json
#	apps/v4/public/r/styles/base-vega/button-example.json
#	apps/v4/public/r/styles/base-vega/button-group-example.json
#	apps/v4/public/r/styles/base-vega/calendar-example.json
#	apps/v4/public/r/styles/base-vega/calendar.json
#	apps/v4/public/r/styles/base-vega/card-example.json
#	apps/v4/public/r/styles/base-vega/carousel.json
#	apps/v4/public/r/styles/base-vega/chart-example.json
#	apps/v4/public/r/styles/base-vega/chatgpt.json
#	apps/v4/public/r/styles/base-vega/checkbox.json
#	apps/v4/public/r/styles/base-vega/collapsible-example.json
#	apps/v4/public/r/styles/base-vega/combobox-example.json
#	apps/v4/public/r/styles/base-vega/combobox.json
#	apps/v4/public/r/styles/base-vega/command-example.json
#	apps/v4/public/r/styles/base-vega/command.json
#	apps/v4/public/r/styles/base-vega/component-example.json
#	apps/v4/public/r/styles/base-vega/context-menu-example.json
#	apps/v4/public/r/styles/base-vega/context-menu.json
#	apps/v4/public/r/styles/base-vega/dialog-example.json
#	apps/v4/public/r/styles/base-vega/dialog.json
#	apps/v4/public/r/styles/base-vega/dropdown-menu-example.json
#	apps/v4/public/r/styles/base-vega/dropdown-menu.json
#	apps/v4/public/r/styles/base-vega/empty-example.json
#	apps/v4/public/r/styles/base-vega/github.json
#	apps/v4/public/r/styles/base-vega/input-group-example.json
#	apps/v4/public/r/styles/base-vega/input-otp-example.json
#	apps/v4/public/r/styles/base-vega/input-otp.json
#	apps/v4/public/r/styles/base-vega/item-example.json
#	apps/v4/public/r/styles/base-vega/kbd-example.json
#	apps/v4/public/r/styles/base-vega/menubar-example.json
#	apps/v4/public/r/styles/base-vega/menubar.json
#	apps/v4/public/r/styles/base-vega/native-select.json
#	apps/v4/public/r/styles/base-vega/navigation-menu-example.json
#	apps/v4/public/r/styles/base-vega/navigation-menu.json
#	apps/v4/public/r/styles/base-vega/pagination.json
#	apps/v4/public/r/styles/base-vega/preview.json
#	apps/v4/public/r/styles/base-vega/progress-example.json
#	apps/v4/public/r/styles/base-vega/radio-group.json
#	apps/v4/public/r/styles/base-vega/select-example.json
#	apps/v4/public/r/styles/base-vega/select.json
#	apps/v4/public/r/styles/base-vega/sheet.json
#	apps/v4/public/r/styles/base-vega/sidebar-example.json
#	apps/v4/public/r/styles/base-vega/sidebar-floating-example.json
#	apps/v4/public/r/styles/base-vega/sidebar-icon-example.json
#	apps/v4/public/r/styles/base-vega/sidebar-inset-example.json
#	apps/v4/public/r/styles/base-vega/sidebar.json
#	apps/v4/public/r/styles/base-vega/spinner-example.json
#	apps/v4/public/r/styles/base-vega/spinner.json
#	apps/v4/public/r/styles/base-vega/table-example.json
#	apps/v4/public/r/styles/base-vega/tabs-example.json
#	apps/v4/public/r/styles/base-vega/toggle-example.json
#	apps/v4/public/r/styles/base-vega/toggle-group-example.json
#	apps/v4/public/r/styles/base-vega/tooltip-example.json
#	apps/v4/public/r/styles/base-vega/vercel.json
#	apps/v4/public/r/styles/radix-lyra/accordion-example.json
#	apps/v4/public/r/styles/radix-lyra/accordion.json
#	apps/v4/public/r/styles/radix-lyra/alert-dialog-example.json
#	apps/v4/public/r/styles/radix-lyra/alert-example.json
#	apps/v4/public/r/styles/radix-lyra/avatar-example.json
#	apps/v4/public/r/styles/radix-lyra/badge-example.json
#	apps/v4/public/r/styles/radix-lyra/breadcrumb.json
#	apps/v4/public/r/styles/radix-lyra/button-example.json
#	apps/v4/public/r/styles/radix-lyra/button-group-example.json
#	apps/v4/public/r/styles/radix-lyra/calendar-example.json
#	apps/v4/public/r/styles/radix-lyra/calendar.json
#	apps/v4/public/r/styles/radix-lyra/card-example.json
#	apps/v4/public/r/styles/radix-lyra/carousel.json
#	apps/v4/public/r/styles/radix-lyra/chart-example.json
#	apps/v4/public/r/styles/radix-lyra/chatgpt.json
#	apps/v4/public/r/styles/radix-lyra/checkbox.json
#	apps/v4/public/r/styles/radix-lyra/collapsible-example.json
#	apps/v4/public/r/styles/radix-lyra/combobox-example.json
#	apps/v4/public/r/styles/radix-lyra/combobox.json
#	apps/v4/public/r/styles/radix-lyra/command-example.json
#	apps/v4/public/r/styles/radix-lyra/command.json
#	apps/v4/public/r/styles/radix-lyra/component-example.json
#	apps/v4/public/r/styles/radix-lyra/context-menu-example.json
#	apps/v4/public/r/styles/radix-lyra/context-menu.json
#	apps/v4/public/r/styles/radix-lyra/dialog-example.json
#	apps/v4/public/r/styles/radix-lyra/dialog.json
#	apps/v4/public/r/styles/radix-lyra/dropdown-menu-example.json
#	apps/v4/public/r/styles/radix-lyra/dropdown-menu.json
#	apps/v4/public/r/styles/radix-lyra/empty-example.json
#	apps/v4/public/r/styles/radix-lyra/github.json
#	apps/v4/public/r/styles/radix-lyra/input-group-example.json
#	apps/v4/public/r/styles/radix-lyra/input-otp-example.json
#	apps/v4/public/r/styles/radix-lyra/input-otp.json
#	apps/v4/public/r/styles/radix-lyra/item-example.json
#	apps/v4/public/r/styles/radix-lyra/kbd-example.json
#	apps/v4/public/r/styles/radix-lyra/menubar-example.json
#	apps/v4/public/r/styles/radix-lyra/menubar.json
#	apps/v4/public/r/styles/radix-lyra/native-select.json
#	apps/v4/public/r/styles/radix-lyra/navigation-menu-example.json
#	apps/v4/public/r/styles/radix-lyra/navigation-menu.json
#	apps/v4/public/r/styles/radix-lyra/pagination.json
#	apps/v4/public/r/styles/radix-lyra/preview.json
#	apps/v4/public/r/styles/radix-lyra/progress-example.json
#	apps/v4/public/r/styles/radix-lyra/radio-group.json
#	apps/v4/public/r/styles/radix-lyra/select-example.json
#	apps/v4/public/r/styles/radix-lyra/select.json
#	apps/v4/public/r/styles/radix-lyra/sheet.json
#	apps/v4/public/r/styles/radix-lyra/sidebar-example.json
#	apps/v4/public/r/styles/radix-lyra/sidebar-floating-example.json
#	apps/v4/public/r/styles/radix-lyra/sidebar-icon-example.json
#	apps/v4/public/r/styles/radix-lyra/sidebar-inset-example.json
#	apps/v4/public/r/styles/radix-lyra/sidebar.json
#	apps/v4/public/r/styles/radix-lyra/spinner-example.json
#	apps/v4/public/r/styles/radix-lyra/spinner.json
#	apps/v4/public/r/styles/radix-lyra/table-example.json
#	apps/v4/public/r/styles/radix-lyra/tabs-example.json
#	apps/v4/public/r/styles/radix-lyra/toggle-example.json
#	apps/v4/public/r/styles/radix-lyra/toggle-group-example.json
#	apps/v4/public/r/styles/radix-lyra/tooltip-example.json
#	apps/v4/public/r/styles/radix-lyra/vercel.json
#	apps/v4/public/r/styles/radix-maia/accordion-example.json
#	apps/v4/public/r/styles/radix-maia/accordion.json
#	apps/v4/public/r/styles/radix-maia/alert-dialog-example.json
#	apps/v4/public/r/styles/radix-maia/alert-example.json
#	apps/v4/public/r/styles/radix-maia/avatar-example.json
#	apps/v4/public/r/styles/radix-maia/badge-example.json
#	apps/v4/public/r/styles/radix-maia/breadcrumb.json
#	apps/v4/public/r/styles/radix-maia/button-example.json
#	apps/v4/public/r/styles/radix-maia/button-group-example.json
#	apps/v4/public/r/styles/radix-maia/calendar-example.json
#	apps/v4/public/r/styles/radix-maia/calendar.json
#	apps/v4/public/r/styles/radix-maia/card-example.json
#	apps/v4/public/r/styles/radix-maia/carousel.json
#	apps/v4/public/r/styles/radix-maia/chart-example.json
#	apps/v4/public/r/styles/radix-maia/chatgpt.json
#	apps/v4/public/r/styles/radix-maia/checkbox.json
#	apps/v4/public/r/styles/radix-maia/collapsible-example.json
#	apps/v4/public/r/styles/radix-maia/combobox-example.json
#	apps/v4/public/r/styles/radix-maia/combobox.json
#	apps/v4/public/r/styles/radix-maia/command-example.json
#	apps/v4/public/r/styles/radix-maia/command.json
#	apps/v4/public/r/styles/radix-maia/component-example.json
#	apps/v4/public/r/styles/radix-maia/context-menu-example.json
#	apps/v4/public/r/styles/radix-maia/context-menu.json
#	apps/v4/public/r/styles/radix-maia/dialog-example.json
#	apps/v4/public/r/styles/radix-maia/dialog.json
#	apps/v4/public/r/styles/radix-maia/dropdown-menu-example.json
#	apps/v4/public/r/styles/radix-maia/dropdown-menu.json
#	apps/v4/public/r/styles/radix-maia/empty-example.json
#	apps/v4/public/r/styles/radix-maia/github.json
#	apps/v4/public/r/styles/radix-maia/input-group-example.json
#	apps/v4/public/r/styles/radix-maia/input-otp-example.json
#	apps/v4/public/r/styles/radix-maia/input-otp.json
#	apps/v4/public/r/styles/radix-maia/item-example.json
#	apps/v4/public/r/styles/radix-maia/kbd-example.json
#	apps/v4/public/r/styles/radix-maia/menubar-example.json
#	apps/v4/public/r/styles/radix-maia/menubar.json
#	apps/v4/public/r/styles/radix-maia/native-select.json
#	apps/v4/public/r/styles/radix-maia/navigation-menu-example.json
#	apps/v4/public/r/styles/radix-maia/navigation-menu.json
#	apps/v4/public/r/styles/radix-maia/pagination.json
#	apps/v4/public/r/styles/radix-maia/preview.json
#	apps/v4/public/r/styles/radix-maia/progress-example.json
#	apps/v4/public/r/styles/radix-maia/radio-group.json
#	apps/v4/public/r/styles/radix-maia/select-example.json
#	apps/v4/public/r/styles/radix-maia/select.json
#	apps/v4/public/r/styles/radix-maia/sheet.json
#	apps/v4/public/r/styles/radix-maia/sidebar-example.json
#	apps/v4/public/r/styles/radix-maia/sidebar-floating-example.json
#	apps/v4/public/r/styles/radix-maia/sidebar-icon-example.json
#	apps/v4/public/r/styles/radix-maia/sidebar-inset-example.json
#	apps/v4/public/r/styles/radix-maia/sidebar.json
#	apps/v4/public/r/styles/radix-maia/spinner-example.json
#	apps/v4/public/r/styles/radix-maia/spinner.json
#	apps/v4/public/r/styles/radix-maia/table-example.json
#	apps/v4/public/r/styles/radix-maia/tabs-example.json
#	apps/v4/public/r/styles/radix-maia/toggle-example.json
#	apps/v4/public/r/styles/radix-maia/toggle-group-example.json
#	apps/v4/public/r/styles/radix-maia/tooltip-example.json
#	apps/v4/public/r/styles/radix-maia/vercel.json
#	apps/v4/public/r/styles/radix-mira/accordion-example.json
#	apps/v4/public/r/styles/radix-mira/accordion.json
#	apps/v4/public/r/styles/radix-mira/alert-dialog-example.json
#	apps/v4/public/r/styles/radix-mira/alert-example.json
#	apps/v4/public/r/styles/radix-mira/avatar-example.json
#	apps/v4/public/r/styles/radix-mira/badge-example.json
#	apps/v4/public/r/styles/radix-mira/breadcrumb.json
#	apps/v4/public/r/styles/radix-mira/button-example.json
#	apps/v4/public/r/styles/radix-mira/button-group-example.json
#	apps/v4/public/r/styles/radix-mira/calendar-example.json
#	apps/v4/public/r/styles/radix-mira/calendar.json
#	apps/v4/public/r/styles/radix-mira/card-example.json
#	apps/v4/public/r/styles/radix-mira/carousel.json
#	apps/v4/public/r/styles/radix-mira/chart-example.json
#	apps/v4/public/r/styles/radix-mira/chatgpt.json
#	apps/v4/public/r/styles/radix-mira/checkbox.json
#	apps/v4/public/r/styles/radix-mira/collapsible-example.json
#	apps/v4/public/r/styles/radix-mira/combobox-example.json
#	apps/v4/public/r/styles/radix-mira/combobox.json
#	apps/v4/public/r/styles/radix-mira/command-example.json
#	apps/v4/public/r/styles/radix-mira/command.json
#	apps/v4/public/r/styles/radix-mira/component-example.json
#	apps/v4/public/r/styles/radix-mira/context-menu-example.json
#	apps/v4/public/r/styles/radix-mira/context-menu.json
#	apps/v4/public/r/styles/radix-mira/dialog-example.json
#	apps/v4/public/r/styles/radix-mira/dialog.json
#	apps/v4/public/r/styles/radix-mira/dropdown-menu-example.json
#	apps/v4/public/r/styles/radix-mira/dropdown-menu.json
#	apps/v4/public/r/styles/radix-mira/empty-example.json
#	apps/v4/public/r/styles/radix-mira/github.json
#	apps/v4/public/r/styles/radix-mira/input-group-example.json
#	apps/v4/public/r/styles/radix-mira/input-otp-example.json
#	apps/v4/public/r/styles/radix-mira/input-otp.json
#	apps/v4/public/r/styles/radix-mira/item-example.json
#	apps/v4/public/r/styles/radix-mira/kbd-example.json
#	apps/v4/public/r/styles/radix-mira/menubar-example.json
#	apps/v4/public/r/styles/radix-mira/menubar.json
#	apps/v4/public/r/styles/radix-mira/native-select.json
#	apps/v4/public/r/styles/radix-mira/navigation-menu-example.json
#	apps/v4/public/r/styles/radix-mira/navigation-menu.json
#	apps/v4/public/r/styles/radix-mira/pagination.json
#	apps/v4/public/r/styles/radix-mira/preview.json
#	apps/v4/public/r/styles/radix-mira/progress-example.json
#	apps/v4/public/r/styles/radix-mira/radio-group.json
#	apps/v4/public/r/styles/radix-mira/select-example.json
#	apps/v4/public/r/styles/radix-mira/select.json
#	apps/v4/public/r/styles/radix-mira/sheet.json
#	apps/v4/public/r/styles/radix-mira/sidebar-example.json
#	apps/v4/public/r/styles/radix-mira/sidebar-floating-example.json
#	apps/v4/public/r/styles/radix-mira/sidebar-icon-example.json
#	apps/v4/public/r/styles/radix-mira/sidebar-inset-example.json
#	apps/v4/public/r/styles/radix-mira/sidebar.json
#	apps/v4/public/r/styles/radix-mira/spinner-example.json
#	apps/v4/public/r/styles/radix-mira/spinner.json
#	apps/v4/public/r/styles/radix-mira/table-example.json
#	apps/v4/public/r/styles/radix-mira/tabs-example.json
#	apps/v4/public/r/styles/radix-mira/toggle-example.json
#	apps/v4/public/r/styles/radix-mira/toggle-group-example.json
#	apps/v4/public/r/styles/radix-mira/tooltip-example.json
#	apps/v4/public/r/styles/radix-mira/vercel.json
#	apps/v4/public/r/styles/radix-nova/accordion-example.json
#	apps/v4/public/r/styles/radix-nova/accordion.json
#	apps/v4/public/r/styles/radix-nova/alert-dialog-example.json
#	apps/v4/public/r/styles/radix-nova/alert-example.json
#	apps/v4/public/r/styles/radix-nova/avatar-example.json
#	apps/v4/public/r/styles/radix-nova/badge-example.json
#	apps/v4/public/r/styles/radix-nova/breadcrumb.json
#	apps/v4/public/r/styles/radix-nova/button-example.json
#	apps/v4/public/r/styles/radix-nova/button-group-example.json
#	apps/v4/public/r/styles/radix-nova/calendar-example.json
#	apps/v4/public/r/styles/radix-nova/calendar.json
#	apps/v4/public/r/styles/radix-nova/card-example.json
#	apps/v4/public/r/styles/radix-nova/carousel.json
#	apps/v4/public/r/styles/radix-nova/chart-example.json
#	apps/v4/public/r/styles/radix-nova/chatgpt.json
#	apps/v4/public/r/styles/radix-nova/checkbox.json
#	apps/v4/public/r/styles/radix-nova/collapsible-example.json
#	apps/v4/public/r/styles/radix-nova/combobox-example.json
#	apps/v4/public/r/styles/radix-nova/combobox.json
#	apps/v4/public/r/styles/radix-nova/command-example.json
#	apps/v4/public/r/styles/radix-nova/command.json
#	apps/v4/public/r/styles/radix-nova/component-example.json
#	apps/v4/public/r/styles/radix-nova/context-menu-example.json
#	apps/v4/public/r/styles/radix-nova/context-menu.json
#	apps/v4/public/r/styles/radix-nova/dialog-example.json
#	apps/v4/public/r/styles/radix-nova/dialog.json
#	apps/v4/public/r/styles/radix-nova/dropdown-menu-example.json
#	apps/v4/public/r/styles/radix-nova/dropdown-menu.json
#	apps/v4/public/r/styles/radix-nova/empty-example.json
#	apps/v4/public/r/styles/radix-nova/github.json
#	apps/v4/public/r/styles/radix-nova/input-group-example.json
#	apps/v4/public/r/styles/radix-nova/input-otp-example.json
#	apps/v4/public/r/styles/radix-nova/input-otp.json
#	apps/v4/public/r/styles/radix-nova/item-example.json
#	apps/v4/public/r/styles/radix-nova/kbd-example.json
#	apps/v4/public/r/styles/radix-nova/menubar-example.json
#	apps/v4/public/r/styles/radix-nova/menubar.json
#	apps/v4/public/r/styles/radix-nova/native-select.json
#	apps/v4/public/r/styles/radix-nova/navigation-menu-example.json
#	apps/v4/public/r/styles/radix-nova/navigation-menu.json
#	apps/v4/public/r/styles/radix-nova/pagination.json
#	apps/v4/public/r/styles/radix-nova/preview.json
#	apps/v4/public/r/styles/radix-nova/progress-example.json
#	apps/v4/public/r/styles/radix-nova/radio-group.json
#	apps/v4/public/r/styles/radix-nova/select-example.json
#	apps/v4/public/r/styles/radix-nova/select.json
#	apps/v4/public/r/styles/radix-nova/sheet.json
#	apps/v4/public/r/styles/radix-nova/sidebar-example.json
#	apps/v4/public/r/styles/radix-nova/sidebar-floating-example.json
#	apps/v4/public/r/styles/radix-nova/sidebar-icon-example.json
#	apps/v4/public/r/styles/radix-nova/sidebar-inset-example.json
#	apps/v4/public/r/styles/radix-nova/sidebar.json
#	apps/v4/public/r/styles/radix-nova/spinner-example.json
#	apps/v4/public/r/styles/radix-nova/spinner.json
#	apps/v4/public/r/styles/radix-nova/table-example.json
#	apps/v4/public/r/styles/radix-nova/tabs-example.json
#	apps/v4/public/r/styles/radix-nova/toggle-example.json
#	apps/v4/public/r/styles/radix-nova/toggle-group-example.json
#	apps/v4/public/r/styles/radix-nova/tooltip-example.json
#	apps/v4/public/r/styles/radix-nova/vercel.json
#	apps/v4/public/r/styles/radix-vega/accordion-example.json
#	apps/v4/public/r/styles/radix-vega/accordion.json
#	apps/v4/public/r/styles/radix-vega/alert-dialog-example.json
#	apps/v4/public/r/styles/radix-vega/alert-example.json
#	apps/v4/public/r/styles/radix-vega/avatar-example.json
#	apps/v4/public/r/styles/radix-vega/badge-example.json
#	apps/v4/public/r/styles/radix-vega/breadcrumb.json
#	apps/v4/public/r/styles/radix-vega/button-example.json
#	apps/v4/public/r/styles/radix-vega/button-group-example.json
#	apps/v4/public/r/styles/radix-vega/calendar-example.json
#	apps/v4/public/r/styles/radix-vega/calendar.json
#	apps/v4/public/r/styles/radix-vega/card-example.json
#	apps/v4/public/r/styles/radix-vega/carousel.json
#	apps/v4/public/r/styles/radix-vega/chart-example.json
#	apps/v4/public/r/styles/radix-vega/chatgpt.json
#	apps/v4/public/r/styles/radix-vega/checkbox.json
#	apps/v4/public/r/styles/radix-vega/collapsible-example.json
#	apps/v4/public/r/styles/radix-vega/combobox-example.json
#	apps/v4/public/r/styles/radix-vega/combobox.json
#	apps/v4/public/r/styles/radix-vega/command-example.json
#	apps/v4/public/r/styles/radix-vega/command.json
#	apps/v4/public/r/styles/radix-vega/component-example.json
#	apps/v4/public/r/styles/radix-vega/context-menu-example.json
#	apps/v4/public/r/styles/radix-vega/context-menu.json
#	apps/v4/public/r/styles/radix-vega/dialog-example.json
#	apps/v4/public/r/styles/radix-vega/dialog.json
#	apps/v4/public/r/styles/radix-vega/dropdown-menu-example.json
#	apps/v4/public/r/styles/radix-vega/dropdown-menu.json
#	apps/v4/public/r/styles/radix-vega/empty-example.json
#	apps/v4/public/r/styles/radix-vega/github.json
#	apps/v4/public/r/styles/radix-vega/input-group-example.json
#	apps/v4/public/r/styles/radix-vega/input-otp-example.json
#	apps/v4/public/r/styles/radix-vega/input-otp.json
#	apps/v4/public/r/styles/radix-vega/item-example.json
#	apps/v4/public/r/styles/radix-vega/kbd-example.json
#	apps/v4/public/r/styles/radix-vega/menubar-example.json
#	apps/v4/public/r/styles/radix-vega/menubar.json
#	apps/v4/public/r/styles/radix-vega/native-select.json
#	apps/v4/public/r/styles/radix-vega/navigation-menu-example.json
#	apps/v4/public/r/styles/radix-vega/navigation-menu.json
#	apps/v4/public/r/styles/radix-vega/pagination.json
#	apps/v4/public/r/styles/radix-vega/preview.json
#	apps/v4/public/r/styles/radix-vega/progress-example.json
#	apps/v4/public/r/styles/radix-vega/radio-group.json
#	apps/v4/public/r/styles/radix-vega/select-example.json
#	apps/v4/public/r/styles/radix-vega/select.json
#	apps/v4/public/r/styles/radix-vega/sheet.json
#	apps/v4/public/r/styles/radix-vega/sidebar-example.json
#	apps/v4/public/r/styles/radix-vega/sidebar-floating-example.json
#	apps/v4/public/r/styles/radix-vega/sidebar-icon-example.json
#	apps/v4/public/r/styles/radix-vega/sidebar-inset-example.json
#	apps/v4/public/r/styles/radix-vega/sidebar.json
#	apps/v4/public/r/styles/radix-vega/spinner-example.json
#	apps/v4/public/r/styles/radix-vega/spinner.json
#	apps/v4/public/r/styles/radix-vega/table-example.json
#	apps/v4/public/r/styles/radix-vega/tabs-example.json
#	apps/v4/public/r/styles/radix-vega/toggle-example.json
#	apps/v4/public/r/styles/radix-vega/toggle-group-example.json
#	apps/v4/public/r/styles/radix-vega/tooltip-example.json
#	apps/v4/public/r/styles/radix-vega/vercel.json
#	apps/v4/scripts/build-registry.mts
2026-01-19 11:39:57 +04:00

303 lines
7.4 KiB
TypeScript

import { promises as fs } from "fs"
import path from "path"
import { ExamplesIndex } from "@/examples/__index__"
import { LRUCache } from "lru-cache"
import { registryItemSchema, type registryItemFileSchema } from "shadcn/schema"
import { type z } from "zod"
import { Index as StylesIndex } from "@/registry/__index__"
import { BASES } from "@/registry/bases"
import { Index as BasesIndex } from "@/registry/bases/__index__"
const INDEXED_STYLES = ["new-york-v4"]
// LRU cache for cross-request caching of registry items.
// File reads are I/O-bound, so caching improves dev server performance.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const registryCache = new LRUCache<string, any>({
max: 500,
ttl: 1000 * 60 * 5, // 5 minutes (shorter for dev to pick up changes).
})
function getBaseForStyle(styleName: string) {
for (const base of BASES) {
if (styleName.startsWith(`${base.name}-`)) {
return base.name
}
}
return null
}
export function getDemoComponent(name: string, styleName: string) {
const base = getBaseForStyle(styleName)
if (!base) return undefined
return ExamplesIndex[base]?.[name]?.component
}
export async function getDemoItem(name: string, styleName: string) {
const base = getBaseForStyle(styleName)
if (!base) return null
const demo = ExamplesIndex[base]?.[name]
if (!demo) {
return null
}
const filePath = path.join(process.cwd(), demo.filePath)
const content = await fs.readFile(filePath, "utf-8")
return {
name: demo.name,
type: "registry:internal" as const,
files: [
{
path: demo.filePath,
content,
type: "registry:internal" as const,
},
],
}
}
function getIndexForStyle(styleName: string) {
if (INDEXED_STYLES.includes(styleName)) {
return { index: StylesIndex, key: styleName }
}
const base = getBaseForStyle(styleName)
if (base) {
return { index: BasesIndex, key: base }
}
return { index: StylesIndex, key: styleName }
}
export function getRegistryComponent(name: string, styleName: string) {
const demoComponent = getDemoComponent(name, styleName)
if (demoComponent) {
return demoComponent
}
const { index, key } = getIndexForStyle(styleName)
return index[key]?.[name]?.component
}
export async function getRegistryItems(
styleName: string,
filter?: (item: z.infer<typeof registryItemSchema>) => boolean
) {
const { index, key } = getIndexForStyle(styleName)
const styleIndex = index[key]
if (!styleIndex) {
return []
}
const entries = Object.values(styleIndex)
const filteredEntries = filter ? entries.filter(filter) : entries
return await Promise.all(
filteredEntries.map(async (entry) => {
const item = await getRegistryItem(entry.name, styleName)
return item
})
).then((results) => results.filter(Boolean))
}
export async function getRegistryItem(name: string, styleName: string) {
const cacheKey = `${styleName}:${name}`
// Check cache first.
if (registryCache.has(cacheKey)) {
return registryCache.get(cacheKey)
}
const { index, key } = getIndexForStyle(styleName)
const item = index[key]?.[name]
if (!item) {
registryCache.set(cacheKey, null)
return null
}
// Convert all file paths to object.
// TODO: remove when we migrate to new registry.
item.files = item.files.map((file: unknown) =>
typeof file === "string" ? { path: file } : file
)
// Fail early before doing expensive file operations.
const result = registryItemSchema.safeParse(item)
if (!result.success) {
registryCache.set(cacheKey, null)
return null
}
// Read all files in parallel.
let files: typeof result.data.files = await Promise.all(
item.files.map(async (file: z.infer<typeof registryItemFileSchema>) => {
const content = await getFileContent(file)
const relativePath = path.relative(process.cwd(), file.path)
return {
...file,
path: relativePath,
content,
}
})
)
// Fix file paths.
files = fixFilePaths(files)
const parsed = registryItemSchema.safeParse({
...result.data,
files,
})
if (!parsed.success) {
console.error(parsed.error.message)
registryCache.set(cacheKey, null)
return null
}
// Cache the result.
registryCache.set(cacheKey, parsed.data)
return parsed.data
}
async function getFileContent(file: z.infer<typeof registryItemFileSchema>) {
let code = await fs.readFile(file.path, "utf-8")
// Some registry items uses default export.
// We want to use named export instead.
if (file.type !== "registry:page") {
code = code.replaceAll("export default", "export")
}
// Fix imports.
code = fixImport(code)
return code
}
function getFileTarget(file: z.infer<typeof registryItemFileSchema>) {
let target = file.target
if (!target || target === "") {
const fileName = file.path.split("/").pop()
if (
file.type === "registry:block" ||
file.type === "registry:component" ||
file.type === "registry:example"
) {
target = `components/${fileName}`
}
if (file.type === "registry:ui") {
target = `components/ui/${fileName}`
}
if (file.type === "registry:hook") {
target = `hooks/${fileName}`
}
if (file.type === "registry:lib") {
target = `lib/${fileName}`
}
}
return target ?? ""
}
function fixFilePaths(files: z.infer<typeof registryItemSchema>["files"]) {
if (!files) {
return []
}
// Resolve all paths relative to the first file's directory.
const firstFilePath = files[0].path
const firstFilePathDir = path.dirname(firstFilePath)
return files.map((file) => {
return {
...file,
path: path.relative(firstFilePathDir, file.path),
target: getFileTarget(file),
}
})
}
export function fixImport(content: string) {
const regex = /@\/(.+?)\/((?:.*?\/)?(?:components|ui|hooks|lib))\/([\w-]+)/g
const replacement = (
match: string,
path: string,
type: string,
component: string
) => {
if (type.endsWith("components")) {
return `@/components/${component}`
} else if (type.endsWith("ui")) {
return `@/components/ui/${component}`
} else if (type.endsWith("hooks")) {
return `@/hooks/${component}`
} else if (type.endsWith("lib")) {
return `@/lib/${component}`
}
return match
}
return content.replace(regex, replacement)
}
export type FileTree = {
name: string
path?: string
children?: FileTree[]
}
export function createFileTreeForRegistryItemFiles(
files: Array<{ path: string; target?: string }>
) {
const root: FileTree[] = []
for (const file of files) {
const path = file.target ?? file.path
const parts = path.split("/")
let currentLevel = root
for (let i = 0; i < parts.length; i++) {
const part = parts[i]
const isFile = i === parts.length - 1
const existingNode = currentLevel.find((node) => node.name === part)
if (existingNode) {
if (isFile) {
// Update existing file node with full path
existingNode.path = path
} else {
// Move to next level in the tree
currentLevel = existingNode.children!
}
} else {
const newNode: FileTree = isFile
? { name: part, path }
: { name: part, children: [] }
currentLevel.push(newNode)
if (!isFile) {
currentLevel = newNode.children!
}
}
}
}
return root
}