Skip to main content

shadcn-admin-kit

This skill should be used when building, modifying, or debugging an admin application with shadcn-admin-kit — including creating resources, lists, forms, data fetching, authentication, relationships between entities, custom pages, or any CRUD admin interface built with this kit.

소스 정보

저장소
marmelab/shadcn-admin-kit
최근 소스 활동
2026년 9월 1일 16:13
감지된 SKILL.md 언어
영어
스타
1,129
포크
98

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
shadcn-admin-kit
description
This skill should be used when building, modifying, or debugging an admin application with shadcn-admin-kit — including creating resources, lists, forms, data fetching, authentication, relationships between entities, custom pages, or any CRUD admin interface built with this kit.
# Shadcn Admin Kit Development Guide Shadcn Admin Kit is a component library for building admin/CRUD applications using React, TypeScript, and shadcn/ui. It provides 98+ pre-built components on top of **ra-core** (from react-admin), combining react-admin's proven data layer with modern shadcn/ui components styled via Tailwind CSS. Before writing custom code, always check if shadcn-admin-kit already provides a component or hook for the task. Full documentation: https://marmelab.com/shadcn-admin-kit/docs **Tech Stack**: React Router v7, TanStack Query, React Hook Form, Zod, ra-core, shadcn/ui (Base UI), Lucide icons, Tailwind CSS v4. **Compatible with**: Vite.js, React-router, Next.js, TanStack Start, and more. ## Import Paths Components are imported from `@/components/admin/`, while ra-core hooks and utilities come from `ra-core`: ```jsx // Admin components import { Admin } from "@/components/admin/admin"; import { List } from "@/components/admin/list"; import { DataTable } from "@/components/admin/data-table"; import { TextInput } from "@/components/admin/text-input"; // Ra-core (routing, hooks, utilities) import { Resource, CustomRoutes, useGetList, useRecordContext } from "ra-core"; ``` ## Providers (Backend Abstraction) Shadcn Admin Kit never calls APIs directly. All communication goes through **providers** — adapters that translate standardized calls into API-specific requests. The three main providers are: - **dataProvider**: All CRUD operations (`getList`, `getOne`, `create`, `update`, `delete`, `getMany`, `getManyReference`, `updateMany`, `deleteMany`). See [DataProviders](https://marmelab.com/react-admin/DataProviders.html) and [50+ existing adapters](https://marmelab.com/react-admin/DataProviderList.html). - **authProvider**: Authentication and authorization. See [Authentication](https://marmelab.com/react-admin/Authentication.html). - **i18nProvider**: Translations (`translate`, `changeLocale`, `getLocale`). **Critical rule**: Never use `fetch`, `axios`, or direct HTTP calls in components. Always use data provider hooks. This ensures proper caching, loading states, error handling, authentication, and optimistic rendering. ## Composition (Not God Components) Shadcn Admin Kit uses composition over configuration. Override behavior by passing child components, not by setting dozens of props: ```jsx <Edit actions={<MyCustomActions />}> <SimpleForm> <TextInput source="title" /> </SimpleForm> </Edit> ``` To customize the layout, pass a custom layout component to `<Admin layout={MyLayout}>`. To customize the sidebar, pass it to `<Layout sidebar={MySidebar}>`. This chaining is by design. ## Context: Pull, Don't Push Components expose data to descendants via React contexts. Access data using hooks rather than passing props down: - `useRecordContext()` — current record in Show/Edit/Create views. See [useRecordContext](https://marmelab.com/react-admin/useRecordContext.html). - `useListContext()` — list data, filters, pagination, sort in List views. See [useListContext](https://marmelab.com/react-admin/useListContext.html). - `useShowContext()`, `useEditContext()`, `useCreateContext()` — page-level state for detail views. - `useTranslate()` — translation function from i18nProvider. - `useGetIdentity()` — current user from authProvider. ## Hooks Over Custom Components When a component's UI doesn't fit, use the underlying hook instead of building from scratch. Controller hooks (named `use*Controller`) provide all the logic without the UI: - `useListController()` — list fetching, filtering, pagination logic - `useEditController()` — edit form fetching and submission logic - `useShowController()` — show page data fetching logic ## Routing `<Resource>` declares CRUD routes automatically (`/posts`, `/posts/create`, `/posts/:id/edit`, `/posts/:id/show`). Use `<CustomRoutes>` for non-CRUD pages. Use `useCreatePath()` to build resource URLs and `<Link>` from react-router for navigation. The router is React Router v7. See [Routing](https://marmelab.com/ra-core/routing/). ```jsx import { Resource, CustomRoutes } from "ra-core"; import { Route } from "react-router"; import { Admin } from "@/components/admin/admin"; export const App = () => ( <Admin dataProvider={dataProvider}> <Resource name="posts" list={PostList} edit={PostEdit} /> <CustomRoutes> <Route path="/settings" element={<Settings />} /> </CustomRoutes> </Admin> ); ``` **Note:** Custom routes don't appear in the sidebar automatically. Customize `<AppSidebar>` to add menu items for custom routes. ## Data Fetching ### Query Hooks (Reading Data) ```jsx const { data, total, isPending, error } = useGetList("posts", { pagination: { page: 1, perPage: 25 }, sort: { field: "created_at", order: "DESC" }, filter: { status: "published" }, }); const { data: record, isPending } = useGetOne("posts", { id: 123 }); const { data: records } = useGetMany("posts", { ids: [1, 2, 3] }); const { data, total } = useGetManyReference("comments", { target: "post_id", id: 123, pagination: { page: 1, perPage: 25 }, }); ``` See [useGetList](https://marmelab.com/ra-core/usegetlist/), [useGetOne](https://marmelab.com/ra-core/usegetone/). ### Mutation Hooks (Writing Data) All mutations return `[mutate, state]`. They support three **mutation modes**: - **pessimistic** (default): Wait for server response, then update UI. - **optimistic**: Update UI immediately, revert on server error. - **undoable**: Update UI, show undo notification, commit after delay. ```jsx const [create, { isPending }] = useCreate(); const [update] = useUpdate(); const [deleteOne] = useDelete(); // Call with resource and params create("posts", { data: { title: "Hello" } }); update("posts", { id: 1, data: { title: "Updated" }, previousData: record }); deleteOne("posts", { id: 1, previousData: record }); ``` Pass `mutationMode: 'optimistic'` or `'undoable'` for instant UI feedback. See [useCreate](https://marmelab.com/ra-core/usecreate/), [useUpdate](https://marmelab.com/ra-core/useupdate/). ## Authentication & Authorization ```typescript const authProvider = { login: ({ username, password }) => Promise<void>, logout: () => Promise<void>, checkAuth: () => Promise<void>, // Verify credentials are valid checkError: (error) => Promise<void>, // Detect auth errors from API responses getIdentity: () => Promise<{ id; fullName; avatar }>, getPermissions: () => Promise<any>, canAccess: ({ resource, action, record }) => Promise<boolean>, // RBAC }; ``` Each auth provider method has a corresponding hook (e.g. `useGetIdentity()`, `useCanAccess()`). - **Custom routes are public by default.** Wrap them with `<Authenticated>` or call `useAuthenticated()` to require login. See [Authenticated](https://marmelab.com/ra-core/authenticated/). - Centralize authorization in `authProvider.canAccess()`, not in individual components. Use `useCanAccess()` to check permissions. See [useCanAccess](https://marmelab.com/ra-core/usecanaccess/) and [Access Control]https://marmelab.com/ra-core/permissions/#access-control). - The dataProvider must include credentials (Bearer token, cookies) in requests — authProvider handles login, but dataProvider handles API calls. Configure `httpClient` in data provider setup. ## Relationships Between Entities Fetching all the data (including relationships) upfront for a given page is an anti-pattern. Instead, fetch related records on demand using reference fields and inputs. ### Displaying Related Records (Fields) ```jsx { /* Show the company of the current record based on its company_id */ } <ReferenceField source="company_id" reference="companies" />; { /* Show a list of related records (reverse FK) */ } <ReferenceManyField reference="comments" target="post_id"> <DataTable> <TextField source="body" /> <DateField source="created_at" /> </DataTable> </ReferenceManyField>; { /* Show multiple referenced records (array of IDs) */ } <ReferenceArrayField source="tag_ids" reference="tags"> <SingleFieldList> <ChipField source="name" /> </SingleFieldList> </ReferenceArrayField>; ``` See [ReferenceField](https://marmelab.com/shadcn-admin-kit/docs/referencefield/), [ReferenceManyField](https://marmelab.com/shadcn-admin-kit/docs/referencemanyfield/), [ReferenceArrayField](https://marmelab.com/shadcn-admin-kit/docs/referencearrayfield/). ### Editing Related Records (Inputs) ```jsx { /* Select from another resource (FK) */ } <ReferenceInput source="company_id" reference="companies" />; { /* Multi-select from another resource (array of IDs) */ } <ReferenceArrayInput source="tag_ids" reference="tags" />; ``` See [ReferenceInput](https://marmelab.com/shadcn-admin-kit/docs/referenceinput/), [ReferenceArrayInput](https://marmelab.com/shadcn-admin-kit/docs/referencearrayinput/). ## Forms Forms are built on React Hook Form with Zod validation. Use `<SimpleForm>` for single-column layouts. See [SimpleForm](https://marmelab.com/shadcn-admin-kit/docs/simpleform/). Pass validators to input components: `required()`, `minLength(min)`, `maxLength(max)`, `minValue(min)`, `maxValue(max)`, `number()`, `email()`, `regex(pattern, message)`, or a custom function returning an error string. ```jsx <TextInput source="title" validate={[required(), minLength(3)]} /> ``` Use React Hook Form's `useWatch()` to create dynamic forms that react to field values. ## List Filters Add filters to lists using the `filters` prop with an array of input components: ```jsx import { List } from "@/components/admin/list"; import { TextInput } from "@/components/admin/text-input"; import { ReferenceInput } from "@/components/admin/reference-input"; import { AutocompleteInput } from "@/components/admin/autocomplete-input"; const filters = [ <TextInput source="q" placeholder="Search..." label={false} />, <ReferenceInput source="category_id" reference="categories"> <AutocompleteInput placeholder="Filter by category" label={false} /> </ReferenceInput>, ]; export const ProductList = () => ( <List filters={filters}> <DataTable>{/* columns */}</DataTable> </List> ); ``` ## Resource Definition Encapsulate resource components in index files for clean imports: ```jsx // posts/index.ts export default { list: PostList, create: PostCreate, edit: PostEdit, show: PostShow, icon: FileText, // Lucide icon recordRepresentation: (record) => record.title, // How records appear in references }; ``` See [Resource](https://marmelab.com/shadcn-admin-kit/docs/resource/), [RecordRepresentation](https://marmelab.com/ra-core/recordrepresentation/). ## Key Components ### Page Components - `<List>` — Full list page with breadcrumbs, pagination, filters, create button - `<Create>` — Page wrapper for create forms - `<Edit>` — Page wrapper for edit forms with show/delete buttons - `<Show>` — Read-only detail page ### Data Display - `<DataTable>` — Powerful data table with sorting, selection, column customization, bulk actions - `<TextField>`, `<NumberField>`, `<DateField>`, `<EmailField>` — Display fields - `<ImageField>`, `<FileField>` — Media fields - `<BadgeField>` — Badge/status display - `<RecordField>` — Flexible field with label (inline or stacked) - `<ArrayField>`, `<SingleFieldList>` — Array iteration ### Form Inputs - `<TextInput>`, `<NumberInput>`, `<BooleanInput>` — Basic inputs - `<SelectInput>`, `<RadioButtonGroupInput>` — Choice inputs - `<DateInput>`, `<DateTimeInput>` — Date pickers - `<AutocompleteInput>` — Searchable dropdown with create-on-fly - `<FileInput>` — File upload - `<ArrayInput>`, `<TextArrayInput>` — Array inputs - `<AutocompleteArrayInput>` — Multi-select autocomplete - `<SearchInput>` — Full-text search filter
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기