openadmin 0.3.0__tar.gz → 0.7.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/format/action.yml +3 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/lint/action.yml +3 -0
- openadmin-0.7.11/Makefile +51 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/PKG-INFO +48 -21
- {openadmin-0.3.0 → openadmin-0.7.11}/README.md +46 -20
- {openadmin-0.3.0 → openadmin-0.7.11}/REUSE.toml +1 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/SKILL.md +231 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/cli.md +225 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/customization.md +205 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/mcp.md +92 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/rules/composition.md +197 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/rules/forms.md +207 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/rules/icons.md +111 -0
- openadmin-0.7.11/client/.claude/skills/shadcn-vue/rules/styling.md +166 -0
- openadmin-0.7.11/client/.gitignore +24 -0
- openadmin-0.7.11/client/DESIGN.md +498 -0
- openadmin-0.7.11/client/README.md +5 -0
- openadmin-0.7.11/client/biome.json +70 -0
- openadmin-0.7.11/client/bun.lock +717 -0
- openadmin-0.7.11/client/components.json +24 -0
- openadmin-0.7.11/client/index.html +13 -0
- openadmin-0.7.11/client/package.json +42 -0
- openadmin-0.7.11/client/public/favicon.svg +1 -0
- openadmin-0.7.11/client/public/icons.svg +24 -0
- openadmin-0.7.11/client/skills-lock.json +11 -0
- openadmin-0.7.11/client/src/App.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/avatar/Avatar.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/avatar/AvatarFallback.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/avatar/AvatarImage.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/avatar/index.ts +7 -0
- openadmin-0.7.11/client/src/components/ui/badge/Badge.vue +34 -0
- openadmin-0.7.11/client/src/components/ui/badge/index.ts +27 -0
- openadmin-0.7.11/client/src/components/ui/button/Button.vue +37 -0
- openadmin-0.7.11/client/src/components/ui/button/index.ts +41 -0
- openadmin-0.7.11/client/src/components/ui/card/Card.vue +28 -0
- openadmin-0.7.11/client/src/components/ui/card/CardAction.vue +23 -0
- openadmin-0.7.11/client/src/components/ui/card/CardContent.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/card/CardDescription.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/card/CardFooter.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/card/CardHeader.vue +23 -0
- openadmin-0.7.11/client/src/components/ui/card/CardTitle.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/card/index.ts +11 -0
- openadmin-0.7.11/client/src/components/ui/chart/ChartContainer.vue +65 -0
- openadmin-0.7.11/client/src/components/ui/chart/ChartLegendContent.vue +71 -0
- openadmin-0.7.11/client/src/components/ui/chart/ChartStyle.vue +43 -0
- openadmin-0.7.11/client/src/components/ui/chart/ChartTooltipContent.vue +121 -0
- openadmin-0.7.11/client/src/components/ui/chart/index.ts +33 -0
- openadmin-0.7.11/client/src/components/ui/chart/utils.ts +48 -0
- openadmin-0.7.11/client/src/components/ui/dialog/Dialog.vue +21 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogClose.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogContent.vue +59 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogDescription.vue +29 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogFooter.vue +34 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogHeader.vue +23 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogOverlay.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogScrollContent.vue +65 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogTitle.vue +29 -0
- openadmin-0.7.11/client/src/components/ui/dialog/DialogTrigger.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/dialog/index.ts +14 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenu.vue +21 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +41 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuContent.vue +41 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuItem.vue +42 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +31 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +42 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +29 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +23 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuSub.vue +21 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +30 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +36 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/dropdown-menu/index.ts +20 -0
- openadmin-0.7.11/client/src/components/ui/field/Field.vue +31 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldContent.vue +26 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldDescription.vue +28 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldError.vue +56 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldGroup.vue +26 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldLabel.vue +29 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldLegend.vue +30 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldSeparator.vue +35 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldSet.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/field/FieldTitle.vue +26 -0
- openadmin-0.7.11/client/src/components/ui/field/index.ts +43 -0
- openadmin-0.7.11/client/src/components/ui/input/Input.vue +39 -0
- openadmin-0.7.11/client/src/components/ui/input/index.ts +5 -0
- openadmin-0.7.11/client/src/components/ui/label/Label.vue +32 -0
- openadmin-0.7.11/client/src/components/ui/label/index.ts +5 -0
- openadmin-0.7.11/client/src/components/ui/pagination/Pagination.vue +34 -0
- openadmin-0.7.11/client/src/components/ui/pagination/PaginationContent.vue +28 -0
- openadmin-0.7.11/client/src/components/ui/pagination/PaginationEllipsis.vue +31 -0
- openadmin-0.7.11/client/src/components/ui/pagination/PaginationFirst.vue +44 -0
- openadmin-0.7.11/client/src/components/ui/pagination/PaginationItem.vue +45 -0
- openadmin-0.7.11/client/src/components/ui/pagination/PaginationLast.vue +44 -0
- openadmin-0.7.11/client/src/components/ui/pagination/PaginationNext.vue +44 -0
- openadmin-0.7.11/client/src/components/ui/pagination/PaginationPrevious.vue +44 -0
- openadmin-0.7.11/client/src/components/ui/pagination/index.ts +12 -0
- openadmin-0.7.11/client/src/components/ui/separator/Separator.vue +33 -0
- openadmin-0.7.11/client/src/components/ui/separator/index.ts +5 -0
- openadmin-0.7.11/client/src/components/ui/sheet/Sheet.vue +21 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetClose.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetContent.vue +63 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetDescription.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetFooter.vue +22 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetHeader.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetOverlay.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetTitle.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/sheet/SheetTrigger.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/sheet/index.ts +12 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/Sidebar.vue +102 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarContent.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarFooter.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarGroup.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarGroupAction.vue +35 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarGroupContent.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarGroupLabel.vue +33 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarHeader.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarInput.vue +28 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarInset.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenu.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuAction.vue +46 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuBadge.vue +32 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuButton.vue +55 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuButtonChild.vue +42 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuItem.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuSkeleton.vue +37 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuSub.vue +28 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuSubButton.vue +47 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarMenuSubItem.vue +24 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarProvider.vue +98 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarRail.vue +39 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarSeparator.vue +25 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/SidebarTrigger.vue +33 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/index.ts +64 -0
- openadmin-0.7.11/client/src/components/ui/sidebar/utils.ts +23 -0
- openadmin-0.7.11/client/src/components/ui/skeleton/Skeleton.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/skeleton/index.ts +5 -0
- openadmin-0.7.11/client/src/components/ui/sonner/Sonner.vue +55 -0
- openadmin-0.7.11/client/src/components/ui/sonner/index.ts +5 -0
- openadmin-0.7.11/client/src/components/ui/table/Table.vue +22 -0
- openadmin-0.7.11/client/src/components/ui/table/TableBody.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/table/TableCaption.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/table/TableCell.vue +28 -0
- openadmin-0.7.11/client/src/components/ui/table/TableEmpty.vue +43 -0
- openadmin-0.7.11/client/src/components/ui/table/TableFooter.vue +23 -0
- openadmin-0.7.11/client/src/components/ui/table/TableHead.vue +23 -0
- openadmin-0.7.11/client/src/components/ui/table/TableHeader.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/table/TableRow.vue +23 -0
- openadmin-0.7.11/client/src/components/ui/table/index.ts +13 -0
- openadmin-0.7.11/client/src/components/ui/tabs/Tabs.vue +30 -0
- openadmin-0.7.11/client/src/components/ui/tabs/TabsContent.vue +27 -0
- openadmin-0.7.11/client/src/components/ui/tabs/TabsList.vue +30 -0
- openadmin-0.7.11/client/src/components/ui/tabs/TabsTrigger.vue +32 -0
- openadmin-0.7.11/client/src/components/ui/tabs/index.ts +8 -0
- openadmin-0.7.11/client/src/components/ui/textarea/Textarea.vue +34 -0
- openadmin-0.7.11/client/src/components/ui/textarea/index.ts +5 -0
- openadmin-0.7.11/client/src/components/ui/tooltip/Tooltip.vue +21 -0
- openadmin-0.7.11/client/src/components/ui/tooltip/TooltipContent.vue +45 -0
- openadmin-0.7.11/client/src/components/ui/tooltip/TooltipProvider.vue +20 -0
- openadmin-0.7.11/client/src/components/ui/tooltip/TooltipTrigger.vue +18 -0
- openadmin-0.7.11/client/src/components/ui/tooltip/index.ts +8 -0
- openadmin-0.7.11/client/src/composables/openadmin-spec.ts +43 -0
- openadmin-0.7.11/client/src/lib/utils.ts +11 -0
- openadmin-0.7.11/client/src/main.ts +10 -0
- openadmin-0.7.11/client/src/schemas/action.ts +39 -0
- openadmin-0.7.11/client/src/schemas/area-chart.ts +24 -0
- openadmin-0.7.11/client/src/schemas/bar-chart.ts +58 -0
- openadmin-0.7.11/client/src/schemas/color.ts +36 -0
- openadmin-0.7.11/client/src/schemas/component.ts +28 -0
- openadmin-0.7.11/client/src/schemas/error.ts +11 -0
- openadmin-0.7.11/client/src/schemas/form.ts +49 -0
- openadmin-0.7.11/client/src/schemas/http-method.ts +11 -0
- openadmin-0.7.11/client/src/schemas/icon.ts +2007 -0
- openadmin-0.7.11/client/src/schemas/json-schema.ts +73 -0
- openadmin-0.7.11/client/src/schemas/line-chart.ts +24 -0
- openadmin-0.7.11/client/src/schemas/markdown.ts +40 -0
- openadmin-0.7.11/client/src/schemas/page.ts +17 -0
- openadmin-0.7.11/client/src/schemas/pie-chart.ts +59 -0
- openadmin-0.7.11/client/src/schemas/section.ts +17 -0
- openadmin-0.7.11/client/src/schemas/spec.ts +16 -0
- openadmin-0.7.11/client/src/schemas/stat.ts +40 -0
- openadmin-0.7.11/client/src/schemas/table.ts +45 -0
- openadmin-0.7.11/client/src/style.css +162 -0
- openadmin-0.7.11/client/tsconfig.app.json +18 -0
- openadmin-0.7.11/client/tsconfig.json +10 -0
- openadmin-0.7.11/client/tsconfig.node.json +23 -0
- openadmin-0.7.11/client/vite.config.ts +14 -0
- openadmin-0.7.11/examples/admin/__init__.py +0 -0
- openadmin-0.7.11/examples/admin/analytics.py +96 -0
- openadmin-0.7.11/examples/admin/authors.py +138 -0
- openadmin-0.7.11/examples/admin/books.py +130 -0
- openadmin-0.7.11/examples/admin/control_panel.py +213 -0
- openadmin-0.7.11/examples/admin/docs.py +39 -0
- openadmin-0.7.11/examples/admin/genres.py +114 -0
- openadmin-0.7.11/examples/admin/health.py +56 -0
- openadmin-0.7.11/examples/admin/overview.py +108 -0
- openadmin-0.7.11/examples/admin/publishers.py +99 -0
- openadmin-0.7.11/examples/admin/reports.py +112 -0
- openadmin-0.7.11/examples/admin/tags.py +100 -0
- openadmin-0.7.11/examples/admin/weekdays.py +131 -0
- openadmin-0.7.11/examples/lib/__init__.py +0 -0
- openadmin-0.7.11/examples/lib/database.py +55 -0
- openadmin-0.7.11/examples/lib/lifespan.py +15 -0
- openadmin-0.7.11/examples/lib/models.py +91 -0
- openadmin-0.7.11/examples/lib/seed.py +118 -0
- openadmin-0.7.11/examples/main.py +61 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/openadmin/fastapi/__init__.py +2 -4
- openadmin-0.7.11/openadmin/fastapi/admin_page.py +572 -0
- openadmin-0.7.11/openadmin/fastapi/admin_panel.py +73 -0
- openadmin-0.7.11/openadmin/fastapi/counter.py +19 -0
- openadmin-0.7.11/openadmin/fastapi/deps.py +26 -0
- openadmin-0.7.11/openadmin/fastapi/exc_handler.py +29 -0
- openadmin-0.7.11/openadmin/fastapi/field_config.py +15 -0
- openadmin-0.7.11/openadmin/fastapi/req.py +10 -0
- openadmin-0.7.11/openadmin/fastapi/utils.py +102 -0
- openadmin-0.7.11/openadmin/spec/__init__.py +80 -0
- openadmin-0.7.11/openadmin/spec/action.py +35 -0
- openadmin-0.7.11/openadmin/spec/area_chart.py +22 -0
- openadmin-0.7.11/openadmin/spec/bar_chart.py +51 -0
- openadmin-0.7.11/openadmin/spec/colors.py +59 -0
- openadmin-0.7.11/openadmin/spec/component.py +26 -0
- openadmin-0.7.11/openadmin/spec/error.py +9 -0
- openadmin-0.7.11/openadmin/spec/form.py +43 -0
- openadmin-0.7.11/openadmin/spec/icons.py +2003 -0
- openadmin-0.7.11/openadmin/spec/json_schema.py +49 -0
- openadmin-0.7.11/openadmin/spec/line_chart.py +22 -0
- openadmin-0.7.11/openadmin/spec/markdown.py +35 -0
- openadmin-0.7.11/openadmin/spec/page.py +17 -0
- openadmin-0.7.11/openadmin/spec/pie_chart.py +52 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/openadmin/spec/section.py +6 -4
- {openadmin-0.3.0 → openadmin-0.7.11}/openadmin/spec/spec.py +5 -5
- openadmin-0.7.11/openadmin/spec/stat.py +35 -0
- openadmin-0.7.11/openadmin/spec/table.py +48 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/pyproject.toml +15 -3
- {openadmin-0.3.0 → openadmin-0.7.11}/uv.lock +264 -2
- openadmin-0.3.0/Makefile +0 -45
- openadmin-0.3.0/examples/health.py +0 -17
- openadmin-0.3.0/examples/main.py +0 -31
- openadmin-0.3.0/examples/users.py +0 -46
- openadmin-0.3.0/openadmin/fastapi/admin_page.py +0 -526
- openadmin-0.3.0/openadmin/fastapi/admin_panel.py +0 -89
- openadmin-0.3.0/openadmin/fastapi/types/__init__.py +0 -36
- openadmin-0.3.0/openadmin/fastapi/types/action.py +0 -20
- openadmin-0.3.0/openadmin/fastapi/types/area_chart.py +0 -19
- openadmin-0.3.0/openadmin/fastapi/types/bar_chart.py +0 -19
- openadmin-0.3.0/openadmin/fastapi/types/form.py +0 -20
- openadmin-0.3.0/openadmin/fastapi/types/line_chart.py +0 -19
- openadmin-0.3.0/openadmin/fastapi/types/markdown.py +0 -19
- openadmin-0.3.0/openadmin/fastapi/types/page_protocol.py +0 -12
- openadmin-0.3.0/openadmin/fastapi/types/pie_chart.py +0 -19
- openadmin-0.3.0/openadmin/fastapi/types/section.py +0 -15
- openadmin-0.3.0/openadmin/fastapi/types/stat.py +0 -19
- openadmin-0.3.0/openadmin/fastapi/types/table.py +0 -19
- openadmin-0.3.0/openadmin/fastapi/utils.py +0 -167
- openadmin-0.3.0/openadmin/spec/__init__.py +0 -41
- openadmin-0.3.0/openadmin/spec/components/__init__.py +0 -35
- openadmin-0.3.0/openadmin/spec/components/action.py +0 -22
- openadmin-0.3.0/openadmin/spec/components/area_chart.py +0 -19
- openadmin-0.3.0/openadmin/spec/components/bar_chart.py +0 -19
- openadmin-0.3.0/openadmin/spec/components/form.py +0 -22
- openadmin-0.3.0/openadmin/spec/components/line_chart.py +0 -19
- openadmin-0.3.0/openadmin/spec/components/markdown.py +0 -19
- openadmin-0.3.0/openadmin/spec/components/pie_chart.py +0 -19
- openadmin-0.3.0/openadmin/spec/components/property.py +0 -17
- openadmin-0.3.0/openadmin/spec/components/property_type.py +0 -18
- openadmin-0.3.0/openadmin/spec/components/stat.py +0 -19
- openadmin-0.3.0/openadmin/spec/components/table.py +0 -21
- openadmin-0.3.0/openadmin/spec/page.py +0 -15
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/ISSUE_TEMPLATE/bug.md +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/ISSUE_TEMPLATE/chore.md +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/ISSUE_TEMPLATE/feature.md +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/branch-name/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/dependency-cves/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/license/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/security/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/spell-check/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/test/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/typecheck/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/actions/unused-code/action.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/workflows/ci.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.github/workflows/publish.yml +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.gitignore +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/.python-version +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/LICENSE +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/LICENSES/AGPL-3.0-or-later.txt +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/docs/assets/logo.png +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/examples/__init__.py +0 -0
- {openadmin-0.3.0/openadmin/spec/components → openadmin-0.7.11/openadmin/spec}/http_methods.py +0 -0
- {openadmin-0.3.0 → openadmin-0.7.11}/tests/test_hello.py +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
fix/license:
|
|
2
|
+
@ uv run reuse download --all
|
|
3
|
+
@ uv run reuse annotate --license AGPL-3.0-or-later --copyright "OpenAdmin" --recursive --skip-unrecognised openadmin/
|
|
4
|
+
@ uv run reuse annotate --license AGPL-3.0-or-later --copyright "OpenAdmin" --recursive --skip-unrecognised tests/
|
|
5
|
+
@ uv run reuse annotate --license AGPL-3.0-or-later --copyright "OpenAdmin" --recursive --skip-unrecognised examples/
|
|
6
|
+
@ uv run reuse annotate --license AGPL-3.0-or-later --copyright "OpenAdmin" --recursive --skip-unrecognised $$(find client/src -mindepth 1 -maxdepth 1 ! -name assets)
|
|
7
|
+
|
|
8
|
+
fix/format:
|
|
9
|
+
@ cd client && bun run fix:format
|
|
10
|
+
@ uv run ruff format .
|
|
11
|
+
|
|
12
|
+
fix/lint:
|
|
13
|
+
@ cd client && bun run fix:lint
|
|
14
|
+
@ uv run ruff check --fix .
|
|
15
|
+
|
|
16
|
+
fix: fix/license fix/format fix/lint
|
|
17
|
+
|
|
18
|
+
check/format:
|
|
19
|
+
@ cd client && bun run check:format
|
|
20
|
+
@ uv run ruff format --check .
|
|
21
|
+
|
|
22
|
+
check/lint:
|
|
23
|
+
@ cd client && bun run check:lint
|
|
24
|
+
@ uv run ruff check .
|
|
25
|
+
|
|
26
|
+
check/typing:
|
|
27
|
+
@ uv run pyright .
|
|
28
|
+
|
|
29
|
+
check/cves:
|
|
30
|
+
@ uv audit --preview-features audit
|
|
31
|
+
|
|
32
|
+
check/security:
|
|
33
|
+
@ uv run bandit -r openadmin -q
|
|
34
|
+
|
|
35
|
+
check/unused:
|
|
36
|
+
@ uv run vulture openadmin --min-confidence 80
|
|
37
|
+
|
|
38
|
+
check/spell:
|
|
39
|
+
@ uv run codespell .
|
|
40
|
+
|
|
41
|
+
check/license:
|
|
42
|
+
@ uv run reuse lint
|
|
43
|
+
|
|
44
|
+
check/test:
|
|
45
|
+
@ uv run pytest
|
|
46
|
+
|
|
47
|
+
check: check/format check/lint check/typing check/cves check/security check/unused check/spell check/license check/test
|
|
48
|
+
|
|
49
|
+
dev/run:
|
|
50
|
+
@ cd client && bun run build
|
|
51
|
+
@ PYTHONPATH=. uv run fastapi dev examples/main.py --host 0.0.0.0 --port $${PORT:-8000} --reload
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openadmin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.11
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Project-URL: Homepage, https://github.com/openadmin-team/openadmin-py
|
|
6
6
|
Project-URL: Issues, https://github.com/openadmin-team/openadmin-py/issues
|
|
@@ -11,6 +11,7 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Requires-Python: >=3.14
|
|
13
13
|
Requires-Dist: fastapi[standard]>=0.136.3
|
|
14
|
+
Requires-Dist: typing-extensions>=4.12.0
|
|
14
15
|
Description-Content-Type: text/markdown
|
|
15
16
|
|
|
16
17
|
<!-- <div align="center">
|
|
@@ -60,16 +61,21 @@ admin = AdminPanel()
|
|
|
60
61
|
# Define a page
|
|
61
62
|
page = AdminPage("Dashboard")
|
|
62
63
|
|
|
64
|
+
|
|
63
65
|
@page.stat("Total Users")
|
|
64
66
|
async def total_users() -> Stat:
|
|
65
67
|
return Stat(value=1_024)
|
|
66
68
|
|
|
69
|
+
|
|
67
70
|
@page.table("Recent Users")
|
|
68
71
|
async def recent_users() -> Table:
|
|
69
|
-
return Table(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
return Table(
|
|
73
|
+
data=[
|
|
74
|
+
{"id": 1, "name": "Alice", "role": "admin"},
|
|
75
|
+
{"id": 2, "name": "Bob", "role": "viewer"},
|
|
76
|
+
]
|
|
77
|
+
)
|
|
78
|
+
|
|
73
79
|
|
|
74
80
|
# Register the page and mount the panel
|
|
75
81
|
admin.include_page(page)
|
|
@@ -87,6 +93,7 @@ Display a single numeric or boolean value.
|
|
|
87
93
|
```python
|
|
88
94
|
from openadmin.types import Stat
|
|
89
95
|
|
|
96
|
+
|
|
90
97
|
@page.stat("Active Sessions")
|
|
91
98
|
async def active_sessions() -> Stat:
|
|
92
99
|
return Stat(value=42)
|
|
@@ -100,6 +107,7 @@ Paginated tables with optional search. Use the built-in dependency types to rece
|
|
|
100
107
|
from openadmin.fastapi import PaginationParamsDep, SearchQueryDep
|
|
101
108
|
from openadmin.types import Table
|
|
102
109
|
|
|
110
|
+
|
|
103
111
|
@page.table("Users")
|
|
104
112
|
async def users_table(
|
|
105
113
|
pagination: PaginationParamsDep,
|
|
@@ -117,18 +125,23 @@ Attach per-row action buttons by including `__actions__` in each row:
|
|
|
117
125
|
```python
|
|
118
126
|
from openadmin.types import Action, Table, TableRow
|
|
119
127
|
|
|
128
|
+
|
|
120
129
|
@page.table("Users")
|
|
121
130
|
async def users_table() -> Table:
|
|
122
|
-
return Table(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
return Table(
|
|
132
|
+
data=[
|
|
133
|
+
TableRow(
|
|
134
|
+
id=1,
|
|
135
|
+
name="Alice",
|
|
136
|
+
__actions__=[
|
|
137
|
+
Action(color="danger", method="DELETE", url="/users/1", body=None),
|
|
138
|
+
Action(
|
|
139
|
+
color="info", method="POST", url="/users/1/reset", body=None
|
|
140
|
+
),
|
|
141
|
+
],
|
|
142
|
+
)
|
|
143
|
+
]
|
|
144
|
+
)
|
|
132
145
|
```
|
|
133
146
|
|
|
134
147
|
### Charts
|
|
@@ -138,6 +151,7 @@ All chart types share the same structure: a `data` list of dicts and a `config`
|
|
|
138
151
|
```python
|
|
139
152
|
from openadmin.types import BarChart, PieChart
|
|
140
153
|
|
|
154
|
+
|
|
141
155
|
@page.bar_chart("Sales by Region", "Total sales per region this quarter")
|
|
142
156
|
async def sales_chart() -> BarChart:
|
|
143
157
|
return BarChart(
|
|
@@ -148,11 +162,12 @@ async def sales_chart() -> BarChart:
|
|
|
148
162
|
config={"sales": {"label": "Sales", "color": "#6366f1"}},
|
|
149
163
|
)
|
|
150
164
|
|
|
165
|
+
|
|
151
166
|
@page.pie_chart("User Roles", "Breakdown of user roles")
|
|
152
167
|
async def roles_chart() -> PieChart:
|
|
153
168
|
return PieChart(
|
|
154
169
|
data=[
|
|
155
|
-
{"segment": "Admin",
|
|
170
|
+
{"segment": "Admin", "count": 5},
|
|
156
171
|
{"segment": "Editor", "count": 20},
|
|
157
172
|
{"segment": "Viewer", "count": 75},
|
|
158
173
|
],
|
|
@@ -178,10 +193,12 @@ Forms collect user input and submit it to your endpoint. Mark a form hidden if i
|
|
|
178
193
|
```python
|
|
179
194
|
from pydantic import BaseModel
|
|
180
195
|
|
|
196
|
+
|
|
181
197
|
class InvitePayload(BaseModel):
|
|
182
198
|
email: str
|
|
183
199
|
role: str
|
|
184
200
|
|
|
201
|
+
|
|
185
202
|
@page.form_post("Invite User", "Send an invitation email to a new user")
|
|
186
203
|
async def invite_user(payload: InvitePayload):
|
|
187
204
|
# send invite...
|
|
@@ -209,27 +226,37 @@ from openadmin.types import Stat, Table, BarChart
|
|
|
209
226
|
|
|
210
227
|
page = AdminPage("Library")
|
|
211
228
|
|
|
229
|
+
|
|
212
230
|
@page.stat("Total Books")
|
|
213
231
|
async def total_books(session: AsyncSessionDep) -> Stat:
|
|
214
232
|
result = await session.execute(select(func.count()).select_from(Book))
|
|
215
233
|
return Stat(value=result.scalar_one())
|
|
216
234
|
|
|
235
|
+
|
|
217
236
|
@page.table("Books")
|
|
218
237
|
async def books_table(
|
|
219
238
|
session: AsyncSessionDep,
|
|
220
239
|
pagination: PaginationParamsDep,
|
|
221
240
|
search: SearchQueryDep,
|
|
222
241
|
) -> Table:
|
|
223
|
-
stmt =
|
|
242
|
+
stmt = (
|
|
243
|
+
select(Book)
|
|
244
|
+
.offset(pagination.page * pagination.per_page)
|
|
245
|
+
.limit(pagination.per_page)
|
|
246
|
+
)
|
|
224
247
|
books = (await session.execute(stmt)).scalars().all()
|
|
225
248
|
return Table(data=[{"title": b.title, "year": b.published_year} for b in books])
|
|
226
249
|
|
|
250
|
+
|
|
227
251
|
@page.bar_chart("Books per Genre", "Number of books in each genre")
|
|
228
252
|
async def books_per_genre(session: AsyncSessionDep) -> BarChart:
|
|
229
|
-
rows = (
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
253
|
+
rows = (
|
|
254
|
+
await session.execute(
|
|
255
|
+
select(Genre.name, func.count().label("books"))
|
|
256
|
+
.join(BookToGenre)
|
|
257
|
+
.group_by(Genre.id)
|
|
258
|
+
)
|
|
259
|
+
).all()
|
|
233
260
|
return BarChart(
|
|
234
261
|
data=[{"genre": name, "books": count} for name, count in rows],
|
|
235
262
|
config={"books": {"label": "Books", "color": "#6366f1"}},
|
|
@@ -45,16 +45,21 @@ admin = AdminPanel()
|
|
|
45
45
|
# Define a page
|
|
46
46
|
page = AdminPage("Dashboard")
|
|
47
47
|
|
|
48
|
+
|
|
48
49
|
@page.stat("Total Users")
|
|
49
50
|
async def total_users() -> Stat:
|
|
50
51
|
return Stat(value=1_024)
|
|
51
52
|
|
|
53
|
+
|
|
52
54
|
@page.table("Recent Users")
|
|
53
55
|
async def recent_users() -> Table:
|
|
54
|
-
return Table(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
return Table(
|
|
57
|
+
data=[
|
|
58
|
+
{"id": 1, "name": "Alice", "role": "admin"},
|
|
59
|
+
{"id": 2, "name": "Bob", "role": "viewer"},
|
|
60
|
+
]
|
|
61
|
+
)
|
|
62
|
+
|
|
58
63
|
|
|
59
64
|
# Register the page and mount the panel
|
|
60
65
|
admin.include_page(page)
|
|
@@ -72,6 +77,7 @@ Display a single numeric or boolean value.
|
|
|
72
77
|
```python
|
|
73
78
|
from openadmin.types import Stat
|
|
74
79
|
|
|
80
|
+
|
|
75
81
|
@page.stat("Active Sessions")
|
|
76
82
|
async def active_sessions() -> Stat:
|
|
77
83
|
return Stat(value=42)
|
|
@@ -85,6 +91,7 @@ Paginated tables with optional search. Use the built-in dependency types to rece
|
|
|
85
91
|
from openadmin.fastapi import PaginationParamsDep, SearchQueryDep
|
|
86
92
|
from openadmin.types import Table
|
|
87
93
|
|
|
94
|
+
|
|
88
95
|
@page.table("Users")
|
|
89
96
|
async def users_table(
|
|
90
97
|
pagination: PaginationParamsDep,
|
|
@@ -102,18 +109,23 @@ Attach per-row action buttons by including `__actions__` in each row:
|
|
|
102
109
|
```python
|
|
103
110
|
from openadmin.types import Action, Table, TableRow
|
|
104
111
|
|
|
112
|
+
|
|
105
113
|
@page.table("Users")
|
|
106
114
|
async def users_table() -> Table:
|
|
107
|
-
return Table(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
return Table(
|
|
116
|
+
data=[
|
|
117
|
+
TableRow(
|
|
118
|
+
id=1,
|
|
119
|
+
name="Alice",
|
|
120
|
+
__actions__=[
|
|
121
|
+
Action(color="danger", method="DELETE", url="/users/1", body=None),
|
|
122
|
+
Action(
|
|
123
|
+
color="info", method="POST", url="/users/1/reset", body=None
|
|
124
|
+
),
|
|
125
|
+
],
|
|
126
|
+
)
|
|
127
|
+
]
|
|
128
|
+
)
|
|
117
129
|
```
|
|
118
130
|
|
|
119
131
|
### Charts
|
|
@@ -123,6 +135,7 @@ All chart types share the same structure: a `data` list of dicts and a `config`
|
|
|
123
135
|
```python
|
|
124
136
|
from openadmin.types import BarChart, PieChart
|
|
125
137
|
|
|
138
|
+
|
|
126
139
|
@page.bar_chart("Sales by Region", "Total sales per region this quarter")
|
|
127
140
|
async def sales_chart() -> BarChart:
|
|
128
141
|
return BarChart(
|
|
@@ -133,11 +146,12 @@ async def sales_chart() -> BarChart:
|
|
|
133
146
|
config={"sales": {"label": "Sales", "color": "#6366f1"}},
|
|
134
147
|
)
|
|
135
148
|
|
|
149
|
+
|
|
136
150
|
@page.pie_chart("User Roles", "Breakdown of user roles")
|
|
137
151
|
async def roles_chart() -> PieChart:
|
|
138
152
|
return PieChart(
|
|
139
153
|
data=[
|
|
140
|
-
{"segment": "Admin",
|
|
154
|
+
{"segment": "Admin", "count": 5},
|
|
141
155
|
{"segment": "Editor", "count": 20},
|
|
142
156
|
{"segment": "Viewer", "count": 75},
|
|
143
157
|
],
|
|
@@ -163,10 +177,12 @@ Forms collect user input and submit it to your endpoint. Mark a form hidden if i
|
|
|
163
177
|
```python
|
|
164
178
|
from pydantic import BaseModel
|
|
165
179
|
|
|
180
|
+
|
|
166
181
|
class InvitePayload(BaseModel):
|
|
167
182
|
email: str
|
|
168
183
|
role: str
|
|
169
184
|
|
|
185
|
+
|
|
170
186
|
@page.form_post("Invite User", "Send an invitation email to a new user")
|
|
171
187
|
async def invite_user(payload: InvitePayload):
|
|
172
188
|
# send invite...
|
|
@@ -194,27 +210,37 @@ from openadmin.types import Stat, Table, BarChart
|
|
|
194
210
|
|
|
195
211
|
page = AdminPage("Library")
|
|
196
212
|
|
|
213
|
+
|
|
197
214
|
@page.stat("Total Books")
|
|
198
215
|
async def total_books(session: AsyncSessionDep) -> Stat:
|
|
199
216
|
result = await session.execute(select(func.count()).select_from(Book))
|
|
200
217
|
return Stat(value=result.scalar_one())
|
|
201
218
|
|
|
219
|
+
|
|
202
220
|
@page.table("Books")
|
|
203
221
|
async def books_table(
|
|
204
222
|
session: AsyncSessionDep,
|
|
205
223
|
pagination: PaginationParamsDep,
|
|
206
224
|
search: SearchQueryDep,
|
|
207
225
|
) -> Table:
|
|
208
|
-
stmt =
|
|
226
|
+
stmt = (
|
|
227
|
+
select(Book)
|
|
228
|
+
.offset(pagination.page * pagination.per_page)
|
|
229
|
+
.limit(pagination.per_page)
|
|
230
|
+
)
|
|
209
231
|
books = (await session.execute(stmt)).scalars().all()
|
|
210
232
|
return Table(data=[{"title": b.title, "year": b.published_year} for b in books])
|
|
211
233
|
|
|
234
|
+
|
|
212
235
|
@page.bar_chart("Books per Genre", "Number of books in each genre")
|
|
213
236
|
async def books_per_genre(session: AsyncSessionDep) -> BarChart:
|
|
214
|
-
rows = (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
237
|
+
rows = (
|
|
238
|
+
await session.execute(
|
|
239
|
+
select(Genre.name, func.count().label("books"))
|
|
240
|
+
.join(BookToGenre)
|
|
241
|
+
.group_by(Genre.id)
|
|
242
|
+
)
|
|
243
|
+
).all()
|
|
218
244
|
return BarChart(
|
|
219
245
|
data=[{"genre": name, "books": count} for name, count in rows],
|
|
220
246
|
config={"books": {"label": "Books", "color": "#6366f1"}},
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shadcn-vue
|
|
3
|
+
description: Manages shadcn-vue components and projects — adding, searching, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn-vue, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for "shadcn-vue init", "create an app with --preset", or "switch to --preset".
|
|
4
|
+
user-invocable: false
|
|
5
|
+
allowed-tools: Bash(npx shadcn-vue@latest *), Bash(pnpm dlx shadcn-vue@latest *), Bash(bunx --bun shadcn-vue@latest *)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# shadcn-vue
|
|
9
|
+
|
|
10
|
+
A framework for building ui, components and design systems. Components are added as source code to the user's project via the CLI.
|
|
11
|
+
|
|
12
|
+
> **IMPORTANT:** Run all CLI commands using the project's package runner: `npx shadcn-vue@latest`, `pnpm dlx shadcn-vue@latest`, or `bunx --bun shadcn-vue@latest` — based on the project's `packageManager`. Examples below use `npx shadcn-vue@latest` but substitute the correct runner for the project.
|
|
13
|
+
|
|
14
|
+
## Current Project Context
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
!`npx shadcn-vue@latest info --json`
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The JSON above contains the project config and installed components. Use `npx shadcn-vue@latest docs <component>` to get documentation and example URLs for any component.
|
|
21
|
+
|
|
22
|
+
## Principles
|
|
23
|
+
|
|
24
|
+
1. **Use existing components first.** Use `npx shadcn-vue@latest search` to check registries before writing custom UI. Check community registries too.
|
|
25
|
+
2. **Compose, don't reinvent.** Settings page = Tabs + Card + form controls. Dashboard = Sidebar + Card + Chart + Table.
|
|
26
|
+
3. **Use built-in variants before custom styles.** `variant="outline"`, `size="sm"`, etc.
|
|
27
|
+
4. **Use semantic colors.** `bg-primary`, `text-muted-foreground` — never raw values like `bg-blue-500`.
|
|
28
|
+
|
|
29
|
+
## Critical Rules
|
|
30
|
+
|
|
31
|
+
These rules are **always enforced**. Each links to a file with Incorrect/Correct code pairs.
|
|
32
|
+
|
|
33
|
+
### Styling & Tailwind → [styling.md](./rules/styling.md)
|
|
34
|
+
|
|
35
|
+
- **`class` for layout, not styling.** Never override component colors or typography.
|
|
36
|
+
- **No `space-x-*` or `space-y-*`.** Use `flex` with `gap-*`. For vertical stacks, `flex flex-col gap-*`.
|
|
37
|
+
- **Use `size-*` when width and height are equal.** `size-10` not `w-10 h-10`.
|
|
38
|
+
- **Use `truncate` shorthand.** Not `overflow-hidden text-ellipsis whitespace-nowrap`.
|
|
39
|
+
- **No manual `dark:` color overrides.** Use semantic tokens (`bg-background`, `text-muted-foreground`).
|
|
40
|
+
- **Use `cn()` for conditional classes.** Don't write manual template literal ternaries.
|
|
41
|
+
- **No manual `z-index` on overlay components.** Dialog, Sheet, Popover, etc. handle their own stacking.
|
|
42
|
+
|
|
43
|
+
### Forms & Inputs → [forms.md](./rules/forms.md)
|
|
44
|
+
|
|
45
|
+
- **Forms use `FieldGroup` + `Field`.** Never use raw `div` with `space-y-*` or `grid gap-*` for form layout.
|
|
46
|
+
- **`InputGroup` uses `InputGroupInput`/`InputGroupTextarea`.** Never raw `Input`/`Textarea` inside `InputGroup`.
|
|
47
|
+
- **Buttons inside inputs use `InputGroup` + `InputGroupAddon`.**
|
|
48
|
+
- **Option sets (2–7 choices) use `ToggleGroup`.** Don't loop `Button` with manual active state.
|
|
49
|
+
- **`FieldSet` + `FieldLegend` for grouping related checkboxes/radios.** Don't use a `div` with a heading.
|
|
50
|
+
- **Field validation uses `data-invalid` + `aria-invalid`.** `data-invalid` on `Field`, `aria-invalid` on the control. For disabled: `data-disabled` on `Field`, `disabled` on the control.
|
|
51
|
+
|
|
52
|
+
### Component Structure → [composition.md](./rules/composition.md)
|
|
53
|
+
|
|
54
|
+
- **Items always inside their Group.** `SelectItem` → `SelectGroup`. `DropdownMenuItem` → `DropdownMenuGroup`. `CommandItem` → `CommandGroup`.
|
|
55
|
+
- **Dialog, Sheet, and Drawer always need a Title.** `DialogTitle`, `SheetTitle`, `DrawerTitle` required for accessibility. Use `class="sr-only"` if visually hidden.
|
|
56
|
+
- **Use full Card composition.** `CardHeader`/`CardTitle`/`CardDescription`/`CardContent`/`CardFooter`. Don't dump everything in `CardContent`.
|
|
57
|
+
- **Button has no `isPending`/`isLoading`.** Compose with `Spinner` + `data-icon` + `disabled`.
|
|
58
|
+
- **`TabsTrigger` must be inside `TabsList`.** Never render triggers directly in `Tabs`.
|
|
59
|
+
- **`Avatar` always needs `AvatarFallback`.** For when the image fails to load.
|
|
60
|
+
|
|
61
|
+
### Use Components, Not Custom Markup → [composition.md](./rules/composition.md)
|
|
62
|
+
|
|
63
|
+
- **Use existing components before custom markup.** Check if a component exists before writing a styled `div`.
|
|
64
|
+
- **Callouts use `Alert`.** Don't build custom styled divs.
|
|
65
|
+
- **Empty states use `Empty`.** Don't build custom empty state markup.
|
|
66
|
+
- **Toast via `vue-sonner`.** Use `toast()` from `vue-sonner`.
|
|
67
|
+
- **Use `Separator`** instead of `<hr>` or `<div class="border-t">`.
|
|
68
|
+
- **Use `Skeleton`** for loading placeholders. No custom `animate-pulse` divs.
|
|
69
|
+
- **Use `Badge`** instead of custom styled spans.
|
|
70
|
+
|
|
71
|
+
### Icons → [icons.md](./rules/icons.md)
|
|
72
|
+
|
|
73
|
+
- **Icons in `Button` use `data-icon`.** `data-icon="inline-start"` or `data-icon="inline-end"` on the icon.
|
|
74
|
+
- **No sizing classes on icons inside components.** Components handle icon sizing via CSS. No `size-4` or `w-4 h-4`.
|
|
75
|
+
- **Pass icons as objects, not string keys.** `:icon="CheckIcon"`, not a string lookup.
|
|
76
|
+
|
|
77
|
+
### CLI
|
|
78
|
+
|
|
79
|
+
- **Apply preset codes directly with the CLI.** Use `npx shadcn-vue@latest apply <code>` for existing projects, or `npx shadcn-vue@latest init --preset <code>` when initializing.
|
|
80
|
+
|
|
81
|
+
## Key Patterns
|
|
82
|
+
|
|
83
|
+
These are the most common patterns that differentiate correct shadcn-vue code. For edge cases, see the linked rule files above.
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<!-- Form layout: FieldGroup + Field, not div + Label. -->
|
|
87
|
+
<FieldGroup>
|
|
88
|
+
<Field>
|
|
89
|
+
<FieldLabel for="email">Email</FieldLabel>
|
|
90
|
+
<Input id="email" />
|
|
91
|
+
</Field>
|
|
92
|
+
</FieldGroup>
|
|
93
|
+
|
|
94
|
+
<!-- Validation: data-invalid on Field, aria-invalid on the control. -->
|
|
95
|
+
<Field data-invalid>
|
|
96
|
+
<FieldLabel>Email</FieldLabel>
|
|
97
|
+
<Input aria-invalid />
|
|
98
|
+
<FieldDescription>Invalid email.</FieldDescription>
|
|
99
|
+
</Field>
|
|
100
|
+
|
|
101
|
+
<!-- Icons in buttons: data-icon, no sizing classes. -->
|
|
102
|
+
<Button>
|
|
103
|
+
<SearchIcon data-icon="inline-start" />
|
|
104
|
+
Search
|
|
105
|
+
</Button>
|
|
106
|
+
|
|
107
|
+
<!-- Spacing: gap-*, not space-y-*. -->
|
|
108
|
+
<div class="flex flex-col gap-4"> <!-- correct -->
|
|
109
|
+
<div class="space-y-4"> <!-- wrong -->
|
|
110
|
+
|
|
111
|
+
<!-- Equal dimensions: size-*, not w-* h-*. -->
|
|
112
|
+
<Avatar class="size-10"> <!-- correct -->
|
|
113
|
+
<Avatar class="w-10 h-10"> <!-- wrong -->
|
|
114
|
+
|
|
115
|
+
<!-- Status colors: Badge variants or semantic tokens, not raw colors. -->
|
|
116
|
+
<Badge variant="secondary">+20.1%</Badge> <!-- correct -->
|
|
117
|
+
<span class="text-emerald-600">+20.1%</span> <!-- wrong -->
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Component Selection
|
|
121
|
+
|
|
122
|
+
| Need | Use |
|
|
123
|
+
| -------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
124
|
+
| Button/action | `Button` with appropriate variant |
|
|
125
|
+
| Form inputs | `Input`, `Select`, `Combobox`, `Switch`, `Checkbox`, `RadioGroup`, `Textarea`, `InputOTP`, `Slider` |
|
|
126
|
+
| Toggle between 2–7 options | `ToggleGroup` + `ToggleGroupItem` |
|
|
127
|
+
| Data display | `Table`, `Card`, `Badge`, `Avatar` |
|
|
128
|
+
| Navigation | `Sidebar`, `NavigationMenu`, `Breadcrumb`, `Tabs`, `Pagination` |
|
|
129
|
+
| Overlays | `Dialog` (modal), `Sheet` (side panel), `Drawer` (bottom sheet), `AlertDialog` (confirmation) |
|
|
130
|
+
| Feedback | `vue-sonner` (toast), `Alert`, `Progress`, `Skeleton`, `Spinner` |
|
|
131
|
+
| Command palette | `Command` inside `Dialog` |
|
|
132
|
+
| Charts | `Chart` (wraps Unovis) |
|
|
133
|
+
| Layout | `Card`, `Separator`, `Resizable`, `ScrollArea`, `Accordion`, `Collapsible` |
|
|
134
|
+
| Empty states | `Empty` |
|
|
135
|
+
| Menus | `DropdownMenu`, `ContextMenu`, `Menubar` |
|
|
136
|
+
| Tooltips/info | `Tooltip`, `HoverCard`, `Popover` |
|
|
137
|
+
|
|
138
|
+
## Key Fields
|
|
139
|
+
|
|
140
|
+
The injected project context contains these key fields:
|
|
141
|
+
|
|
142
|
+
- **`aliases`** → use the actual alias prefix for imports (e.g. `@/`, `~/`), never hardcode.
|
|
143
|
+
- **`tailwindVersion`** → `"v4"` uses `@theme inline` blocks; `"v3"` uses `tailwind.config.js`.
|
|
144
|
+
- **`tailwindCssFile`** → the global CSS file where custom CSS variables are defined. Always edit this file, never create a new one.
|
|
145
|
+
- **`style`** → component visual treatment (e.g. `nova`, `vega`).
|
|
146
|
+
- **`base`** → primitive library (`reka`). Affects component APIs and available props.
|
|
147
|
+
- **`iconLibrary`** → determines icon imports. Use `@lucide/vue` for `lucide`, `@tabler/icons-vue` for `tabler`, etc. Never assume `@lucide/vue`.
|
|
148
|
+
- **`resolvedPaths`** → exact file-system destinations for components, utils, hooks, etc.
|
|
149
|
+
- **`framework`** → routing and file conventions (e.g. Nuxt vs Vite SPA).
|
|
150
|
+
- **`packageManager`** → use this for any non-shadcn-vue dependency installs (e.g. `pnpm add date-fns` vs `npm install date-fns`).
|
|
151
|
+
|
|
152
|
+
See [cli.md — `info` command](./cli.md) for the full field reference.
|
|
153
|
+
|
|
154
|
+
## Component Docs, Examples, and Usage
|
|
155
|
+
|
|
156
|
+
Run `npx shadcn-vue@latest docs <component>` to get the URLs for a component's documentation, examples, and API reference. Fetch these URLs to get the actual content.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx shadcn-vue@latest docs button dialog select
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**When creating, fixing, debugging, or using a component, always run `npx shadcn-vue@latest docs` and fetch the URLs first.** This ensures you're working with the correct API and usage patterns rather than guessing.
|
|
163
|
+
|
|
164
|
+
## Workflow
|
|
165
|
+
|
|
166
|
+
1. **Get project context** — already injected above. Run `npx shadcn-vue@latest info` again if you need to refresh.
|
|
167
|
+
2. **Check installed components first** — before running `add`, always check the `components` list from project context or list the `resolvedPaths.ui` directory. Don't import components that haven't been added, and don't re-add ones already installed.
|
|
168
|
+
3. **Find components** — `npx shadcn-vue@latest search`.
|
|
169
|
+
4. **Get docs and examples** — run `npx shadcn-vue@latest docs <component>` to get URLs, then fetch them. Use `npx shadcn-vue@latest view` to browse registry items you haven't installed. To preview changes to installed components, use `npx shadcn-vue@latest add --diff`.
|
|
170
|
+
5. **Install or update** — `npx shadcn-vue@latest add`. When updating existing components, use `--dry-run` and `--diff` to preview changes first (see [Updating Components](#updating-components) below).
|
|
171
|
+
6. **Fix imports in third-party components** — After adding components from community registries, check the added non-UI files for hardcoded import paths like `@/components/ui/...`. These won't match the project's actual aliases. Use `npx shadcn-vue@latest info` to get the correct `ui` alias (e.g. `@workspace/ui/components`) and rewrite the imports accordingly. The CLI rewrites imports for its own UI files, but third-party registry components may use default paths that don't match the project.
|
|
172
|
+
7. **Review added components** — After adding a component or block from any registry, **always read the added files and verify they are correct**. Check for missing sub-components (e.g. `SelectItem` without `SelectGroup`), missing imports, incorrect composition, or violations of the [Critical Rules](#critical-rules). Also replace any icon imports with the project's `iconLibrary` from the project context (e.g. if the registry item uses `@lucide/vue` but the project uses `hugeicons`, swap the imports and icon names accordingly). Fix all issues before moving on.
|
|
173
|
+
8. **Registry must be explicit** — When the user asks to add a block or component, **do not guess the registry**. If no registry is specified (e.g. user says "add a login block" without specifying `@shadcn`, etc.), ask which registry to use. Never default to a registry on behalf of the user.
|
|
174
|
+
9. **Switching presets** — Ask the user first: **overwrite**, **merge**, or **skip**?
|
|
175
|
+
- **Overwrite**: `npx shadcn-vue@latest apply <code>`. Overwrites detected components, fonts, and CSS variables.
|
|
176
|
+
- **Merge**: `npx shadcn-vue@latest init --preset <code> --force --no-reinstall`, then run `npx shadcn-vue@latest info` to list installed components, then for each installed component use `--dry-run` and `--diff` to [smart merge](#updating-components) it individually.
|
|
177
|
+
- **Skip**: `npx shadcn-vue@latest init --preset <code> --force --no-reinstall`. Only updates config and CSS, leaves components as-is.
|
|
178
|
+
- **Important**: Always run preset commands inside the user's project directory. `apply` only works in an existing project with a `components.json` file. The CLI automatically preserves the current base (`reka`) from `components.json`. If you must use a scratch/temp directory (e.g. for `--dry-run` comparisons), pass `--base <current-base>` explicitly — preset codes do not encode the base.
|
|
179
|
+
|
|
180
|
+
## Updating Components
|
|
181
|
+
|
|
182
|
+
When the user asks to update a component from upstream while keeping their local changes, use `--dry-run` and `--diff` to intelligently merge. **NEVER fetch raw files from GitHub manually — always use the CLI.**
|
|
183
|
+
|
|
184
|
+
1. Run `npx shadcn-vue@latest add <component> --dry-run` to see all files that would be affected.
|
|
185
|
+
2. For each file, run `npx shadcn-vue@latest add <component> --diff <file>` to see what changed upstream vs local.
|
|
186
|
+
3. Decide per file based on the diff:
|
|
187
|
+
- No local changes → safe to overwrite.
|
|
188
|
+
- Has local changes → read the local file, analyze the diff, and apply upstream updates while preserving local modifications.
|
|
189
|
+
- User says "just update everything" → use `--overwrite`, but confirm first.
|
|
190
|
+
4. **Never use `--overwrite` without the user's explicit approval.**
|
|
191
|
+
|
|
192
|
+
## Quick Reference
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Create a new project.
|
|
196
|
+
npx shadcn-vue@latest init --name my-app --preset nova
|
|
197
|
+
npx shadcn-vue@latest init --name my-app --preset a2r6bw --template vite
|
|
198
|
+
|
|
199
|
+
# Initialize existing project.
|
|
200
|
+
npx shadcn-vue@latest init --preset nova
|
|
201
|
+
npx shadcn-vue@latest init --defaults # shortcut: --template=nuxt --preset=nova (base style implied)
|
|
202
|
+
|
|
203
|
+
# Apply a preset to an existing project.
|
|
204
|
+
npx shadcn-vue@latest apply a2r6bw
|
|
205
|
+
|
|
206
|
+
# Add components.
|
|
207
|
+
npx shadcn-vue@latest add button card dialog
|
|
208
|
+
npx shadcn-vue@latest add --all
|
|
209
|
+
|
|
210
|
+
# Search registries.
|
|
211
|
+
npx shadcn-vue@latest search @shadcn -q "sidebar"
|
|
212
|
+
|
|
213
|
+
# Get component docs and example URLs.
|
|
214
|
+
npx shadcn-vue@latest docs button dialog select
|
|
215
|
+
|
|
216
|
+
# View registry item details (for items not yet installed).
|
|
217
|
+
npx shadcn-vue@latest view @shadcn/button
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Named presets:** `nova`, `vega`, `maia`, `lyra`, `mira`, `luma`
|
|
221
|
+
**Templates:** `nuxt`, `vite`, `astro` and `laravel`
|
|
222
|
+
**Preset codes:** Version-prefixed base62 strings (e.g. `a2r6bw`), from [shadcn-vue.com](https://shadcn-vue.com).
|
|
223
|
+
|
|
224
|
+
## Detailed References
|
|
225
|
+
|
|
226
|
+
- [rules/forms.md](./rules/forms.md) — FieldGroup, Field, InputGroup, ToggleGroup, FieldSet, validation states
|
|
227
|
+
- [rules/composition.md](./rules/composition.md) — Groups, overlays, Card, Tabs, Avatar, Alert, Empty, Toast, Separator, Skeleton, Badge, Button loading
|
|
228
|
+
- [rules/icons.md](./rules/icons.md) — data-icon, icon sizing, passing icons as objects
|
|
229
|
+
- [rules/styling.md](./rules/styling.md) — Semantic colors, variants, class, spacing, size, truncate, dark mode, cn(), z-index
|
|
230
|
+
- [cli.md](./cli.md) — Commands, flags, presets, templates
|
|
231
|
+
- [customization.md](./customization.md) — Theming, CSS variables, extending components
|