@mayor_grd/centry-ui 0.1.0 → 0.1.2
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.
- package/CLAUDE.md +241 -0
- package/dist/tokens/generated/primitives.css +2 -2
- package/package.json +3 -2
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# @mayor_grd/centry-ui — AI Agent Reference
|
|
2
|
+
|
|
3
|
+
This is the **Basis DS** React UI component library for GRDFI projects.
|
|
4
|
+
When building UI in any project that uses `@mayor_grd/centry-ui`, follow this guide.
|
|
5
|
+
|
|
6
|
+
## Package
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
@mayor_grd/centry-ui
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Available Components
|
|
13
|
+
|
|
14
|
+
All components are imported from the package root:
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { Button, Input, Card, ... } from '@mayor_grd/centry-ui';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Component List
|
|
21
|
+
|
|
22
|
+
| Component | Description | Key Props |
|
|
23
|
+
|-----------|-------------|-----------|
|
|
24
|
+
| `Button` | Primary action element | `variant`: default/destructive/outline/secondary/ghost/link · `size`: default/sm/lg/icon/iconSm/iconLg · `loading?: boolean` (spinner + disable) · `asChild` · Pill-shaped (`rounded-full`) |
|
|
25
|
+
| `Input` | Text input field | `state`: default/error. Standard HTML input props |
|
|
26
|
+
| `Card` | Container with sections | Sub-components: `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` |
|
|
27
|
+
| `Accordion` | Collapsible panels | `type`: single/multiple, `collapsible`. Sub: `AccordionItem`, `AccordionTrigger`, `AccordionContent` |
|
|
28
|
+
| `Alert` | Feedback banner | `variant`: default/info/success/warning/error. Sub: `AlertTitle`, `AlertDescription` |
|
|
29
|
+
| `AlertDialog` | Confirmation modal | Sub: `AlertDialogTrigger`, `AlertDialogContent`, `AlertDialogHeader`, `AlertDialogFooter`, `AlertDialogTitle`, `AlertDialogDescription`, `AlertDialogAction`, `AlertDialogCancel` |
|
|
30
|
+
| `Sidebar` | App navigation | `side`: left/right, `collapsible`: offcanvas/icon/none, `variant`: sidebar/floating/inset |
|
|
31
|
+
| `SidebarProvider` | Sidebar state context | `defaultOpen`, `open`, `onOpenChange`. Hook: `useSidebar()` |
|
|
32
|
+
| `Sheet` | Slide-over panel | Sub: `SheetTrigger`, `SheetContent` (side: top/right/bottom/left), `SheetHeader`, `SheetTitle`, `SheetDescription`, `SheetFooter`, `SheetClose` |
|
|
33
|
+
| `Tooltip` | Hover popup | Wrap with `TooltipProvider`. Sub: `TooltipTrigger`, `TooltipContent` (`variant`: dark/light) |
|
|
34
|
+
| `Separator` | Divider line | `orientation`: horizontal/vertical |
|
|
35
|
+
| `AspectRatio` | Constrain content to a ratio | `ratio`: number (default 1). Re-exports Radix primitive |
|
|
36
|
+
| `Avatar` | User avatar with image + fallback | `size`: 2xs/xs/sm/md/lg/xl. Sub: `AvatarImage`, `AvatarFallback` |
|
|
37
|
+
| `Badge` | Compact status/labeling pill | `variant`: default/secondary/outline/destructive/info/success/warning/error/verified |
|
|
38
|
+
| `Skeleton` | Loading placeholder | Plain div with pulse animation; size via `className` |
|
|
39
|
+
| `Tag` | Rectangular label, optional dismiss | `variant`: default/outline/brand/info/success/warning/error. `onRemove?: () => void` shows close button |
|
|
40
|
+
| `Dialog` | Modal dialog | Sub: `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter`, `DialogTitle`, `DialogDescription`, `DialogClose` |
|
|
41
|
+
| `Drawer` | Bottom-sheet overlay (vaul) | `shouldScaleBackground`. Sub: `DrawerTrigger`, `DrawerContent`, `DrawerHeader`, `DrawerFooter`, `DrawerTitle`, `DrawerDescription`, `DrawerClose` |
|
|
42
|
+
| `Popover` | Floating panel | Sub: `PopoverTrigger`, `PopoverContent`, `PopoverAnchor` |
|
|
43
|
+
| `HoverCard` | Hover-triggered popup | Sub: `HoverCardTrigger`, `HoverCardContent` |
|
|
44
|
+
| `Toaster` / `toast` | Sonner toast notifications | Mount `<Toaster />` once; call `toast()` / `toast.success()` / `toast.error()` anywhere |
|
|
45
|
+
| `Label` | Form field label (Radix) | Pair with `htmlFor` / form control id |
|
|
46
|
+
| `Checkbox` | Boolean checkbox | Standard Radix `checked` (true/false/"indeterminate")/`defaultChecked`/`onCheckedChange`/`disabled`. Renders inline check + dash SVG indicators |
|
|
47
|
+
| `Switch` | On/off toggle | Standard Radix props. Boxed-card layout via parent `<Label>` with `has-[[data-state=checked]]:` selector — see Storybook `BoxedCard` story. |
|
|
48
|
+
| `RadioGroup` | Radio set | Sub: `RadioGroupItem`. `value`/`defaultValue`/`onValueChange`. Boxed-card layout via parent `<Label>` with `has-[:checked]:` — see Storybook `BoxedCards` story. |
|
|
49
|
+
| `Toggle` | Single press-toggle button | `variant`: default/outline. `size`: default/sm/lg. `pressed`/`defaultPressed` |
|
|
50
|
+
| `ToggleGroup` | Group of toggles | `type`: single/multiple. `variant`: default/outline/outline-fill/outline-icon/outline-text (bordered group). Sub: `ToggleGroupItem`. |
|
|
51
|
+
| `Slider` | Range slider | `defaultValue` (number[]), `min`/`max`/`step`. Supports single or multi-thumb |
|
|
52
|
+
| `Textarea` | Multi-line text input | `state`: default/error. Standard HTML textarea props |
|
|
53
|
+
| `Select` | Single-select dropdown (Radix) | Sub: `SelectTrigger`, `SelectValue`, `SelectContent`, `SelectItem`, `SelectGroup`, `SelectLabel`, `SelectSeparator`, `SelectScrollUpButton`, `SelectScrollDownButton` |
|
|
54
|
+
| `DropdownMenu` | Menu triggered by a button | Sub: `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem` (`variant`: default/error), `DropdownMenuCheckboxItem`, `DropdownMenuRadioItem`, `DropdownMenuLabel`, `DropdownMenuSeparator`, `DropdownMenuShortcut`, `DropdownMenuGroup`, `DropdownMenuSub`, `DropdownMenuSubTrigger`, `DropdownMenuSubContent`, `DropdownMenuRadioGroup` |
|
|
55
|
+
| `NavigationMenu` | Top-level nav menu | Sub: `NavigationMenuList`, `NavigationMenuItem`, `NavigationMenuTrigger`, `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuIndicator`, `NavigationMenuViewport`. Helper: `navigationMenuTriggerStyle()` |
|
|
56
|
+
| `Breadcrumb` | Path-style nav trail | Sub: `BreadcrumbList` (`size`: sm/md), `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` |
|
|
57
|
+
| `Pagination` | Page navigator | Sub: `PaginationContent`, `PaginationItem`, `PaginationLink` (`isActive`), `PaginationPrevious`, `PaginationNext`, `PaginationEllipsis` |
|
|
58
|
+
| `Collapsible` | Show/hide content (Radix) | Sub: `CollapsibleTrigger`, `CollapsibleContent` |
|
|
59
|
+
| `Progress` | Determinate progress bar | `value`: 0–100 |
|
|
60
|
+
| `Command` | Command palette (cmdk) | Sub: `CommandInput`, `CommandList`, `CommandEmpty`, `CommandGroup`, `CommandItem`, `CommandShortcut`, `CommandSeparator`, `CommandDialog` |
|
|
61
|
+
| `Combobox` | Searchable single-select | `options: { value, label, disabled? }[]`, `value`/`defaultValue`/`onValueChange`, `placeholder`, `searchPlaceholder`, `emptyText` |
|
|
62
|
+
| `Calendar` | Date picker grid (react-day-picker) | Passes through all `DayPicker` props (`mode`, `selected`, `onSelect`, etc.) |
|
|
63
|
+
| `DatePicker` | Single-date input | `value`/`defaultValue`/`onValueChange` (Date), `placeholder`, `iconPosition`: left/right |
|
|
64
|
+
| `InputOTP` | OTP code input | `maxLength`. Sub: `InputOTPGroup`, `InputOTPSlot` (`index`), `InputOTPSeparator` |
|
|
65
|
+
| `Carousel` | Slide carousel (embla) | `orientation`: horizontal/vertical, `opts` (Embla options), `plugins`, `setApi`. Sub: `CarouselContent`, `CarouselItem`, `CarouselPrevious`, `CarouselNext` |
|
|
66
|
+
| `Table` | Semantic table primitives | `size`: sm/md/lg. Sub: `TableHeader`, `TableBody`, `TableFooter`, `TableHead`, `TableRow`, `TableCell`, `TableCaption` |
|
|
67
|
+
| `DataTable` | Headless data grid (@tanstack/react-table) | `columns: ColumnDef[]`, `data`, `emptyMessage`, `onTableReady` |
|
|
68
|
+
| `Form` | RHF + zod form helpers | Sub: `FormField`, `FormItem`, `FormLabel`, `FormControl`, `FormDescription`, `FormMessage`. Hook: `useFormField()`. Wraps `FormProvider` |
|
|
69
|
+
|
|
70
|
+
## Color System — Tailwind Classes
|
|
71
|
+
|
|
72
|
+
Use these Tailwind utility classes. They auto-switch between light and dark mode.
|
|
73
|
+
|
|
74
|
+
### Backgrounds
|
|
75
|
+
- `bg-bg-canvas` — page background
|
|
76
|
+
- `bg-bg-surface` — card/panel background
|
|
77
|
+
- `bg-bg-popover` — dropdown/popover background
|
|
78
|
+
- `bg-bg-sidebar` — sidebar background
|
|
79
|
+
- `bg-bg-sidebar-accent` — active sidebar item
|
|
80
|
+
- `bg-bg-navbar` — top navbar
|
|
81
|
+
- `bg-bg-brand` — brand/accent background
|
|
82
|
+
- `bg-bg-input` — input field background
|
|
83
|
+
- `bg-bg-secondary` — secondary surfaces
|
|
84
|
+
- `bg-bg-muted` — subtle/muted background
|
|
85
|
+
- `bg-bg-accent` — accent/highlight
|
|
86
|
+
- `bg-bg-strong` — strong emphasis
|
|
87
|
+
- `bg-bg-inverse` — inverse (dark on light, light on dark)
|
|
88
|
+
- `bg-bg-scrim` — overlay/backdrop
|
|
89
|
+
- `bg-bg-transparent` — transparent
|
|
90
|
+
|
|
91
|
+
### Text
|
|
92
|
+
- `text-text-primary` — primary body text
|
|
93
|
+
- `text-text-secondary` — secondary/supporting text
|
|
94
|
+
- `text-text-muted` — de-emphasized text
|
|
95
|
+
- `text-text-disabled` — disabled state
|
|
96
|
+
- `text-text-inverse` — text on inverse background
|
|
97
|
+
- `text-text-link` — link text
|
|
98
|
+
- `text-text-link-hover` — link hover
|
|
99
|
+
- `text-text-sidebar` — sidebar text
|
|
100
|
+
- `text-text-dialog` — dialog text
|
|
101
|
+
|
|
102
|
+
### Icons
|
|
103
|
+
- `text-icon-primary`, `text-icon-secondary`, `text-icon-muted`, `text-icon-disabled`
|
|
104
|
+
- `text-icon-inverse`, `text-icon-link`, `text-icon-sidebar`
|
|
105
|
+
|
|
106
|
+
### Borders
|
|
107
|
+
- `border-border-default` — standard border
|
|
108
|
+
- `border-border-muted` — subtle border
|
|
109
|
+
- `border-border-strong` — emphasis border
|
|
110
|
+
- `border-border-disabled`, `border-border-input`, `border-border-brand`, `border-border-inverse`
|
|
111
|
+
|
|
112
|
+
### Actions (Buttons)
|
|
113
|
+
| Variant | Background | Hover | Text |
|
|
114
|
+
|---------|-----------|-------|------|
|
|
115
|
+
| Primary | `bg-action-primary-bg` | `hover:bg-action-primary-bg-hover` | `text-action-primary-text` |
|
|
116
|
+
| Secondary | `bg-action-secondary-bg` | `hover:bg-action-secondary-bg-hover` | `text-action-secondary-text` |
|
|
117
|
+
| Ghost | `bg-action-ghost-bg` | `hover:bg-action-ghost-bg-hover` | `text-action-ghost-text` |
|
|
118
|
+
| Outline | `bg-action-outline-bg` | `hover:bg-action-outline-bg-hover` | `text-action-outline-text` |
|
|
119
|
+
| Destructive | `bg-action-destructive-bg` | `hover:bg-action-destructive-bg-hover` | `text-action-destructive-text` |
|
|
120
|
+
| Link | — | — | `text-action-link-text` |
|
|
121
|
+
|
|
122
|
+
### Status
|
|
123
|
+
| Status | Background | Border | Text | Icon |
|
|
124
|
+
|--------|-----------|--------|------|------|
|
|
125
|
+
| Info | `bg-status-info-bg` | `border-status-info-border` | `text-status-info-text` | `text-status-info-icon` |
|
|
126
|
+
| Success | `bg-status-success-bg` | `border-status-success-border` | `text-status-success-text` | `text-status-success-icon` |
|
|
127
|
+
| Warning | `bg-status-warning-bg` | `border-status-warning-border` | `text-status-warning-text` | `text-status-warning-icon` |
|
|
128
|
+
| Error | `bg-status-error-bg` | `border-status-error-border` | `text-status-error-text` | `text-status-error-icon` |
|
|
129
|
+
|
|
130
|
+
### Field (Input) Colors
|
|
131
|
+
- `bg-field-bg`, `text-field-text`, `text-field-placeholder`
|
|
132
|
+
- `border-field-border`, `hover:border-field-border-hover`, `focus:border-field-border-focus`
|
|
133
|
+
- `border-field-border-error`, `border-field-border-disabled`
|
|
134
|
+
- `text-field-label`, `text-field-helptext`, `text-field-errortext`
|
|
135
|
+
|
|
136
|
+
### Focus
|
|
137
|
+
- `ring-focus-ring` — focus ring color
|
|
138
|
+
- `ring-offset-focus-offset` — focus ring offset
|
|
139
|
+
|
|
140
|
+
### Shadows
|
|
141
|
+
- `shadow-input` — input field shadow
|
|
142
|
+
- `shadow-card` — card elevation
|
|
143
|
+
- `shadow-popover` — dropdown/popover
|
|
144
|
+
- `shadow-modal` — modal dialog
|
|
145
|
+
- `shadow-focus-ring` — focus ring shadow
|
|
146
|
+
|
|
147
|
+
### Border Radius
|
|
148
|
+
- `rounded-sm` (4px), `rounded-md` (8px), `rounded-lg` (12px), `rounded-xl` (14px), `rounded-full` (9999px)
|
|
149
|
+
|
|
150
|
+
## Typography CSS Variables
|
|
151
|
+
|
|
152
|
+
Typography is defined via CSS variables, not Tailwind classes. Use inline styles or custom classes:
|
|
153
|
+
|
|
154
|
+
| Token | Variables |
|
|
155
|
+
|-------|----------|
|
|
156
|
+
| Display | `--display-font`, `--display-size`, `--display-weight`, `--display-line-height`, `--display-letter-spacing` |
|
|
157
|
+
| H1 | `--h1-font`, `--h1-size`, `--h1-weight`, `--h1-line-height`, `--h1-letter-spacing` |
|
|
158
|
+
| H2 | `--h2-font`, `--h2-size`, `--h2-weight`, `--h2-line-height`, `--h2-letter-spacing` |
|
|
159
|
+
| H3 | `--h3-font`, `--h3-size`, `--h3-weight`, `--h3-line-height`, `--h3-letter-spacing` |
|
|
160
|
+
| H4 | `--h4-font`, `--h4-size`, `--h4-weight`, `--h4-line-height`, `--h4-letter-spacing` |
|
|
161
|
+
| Body SM | `--body-sm-font`, `--body-sm-size`, `--body-sm-weight`, `--body-sm-line-height`, `--body-sm-letter-spacing` |
|
|
162
|
+
| Body MD | `--body-md-font`, `--body-md-size`, `--body-md-weight`, `--body-md-line-height`, `--body-md-letter-spacing` |
|
|
163
|
+
| Label | `--label-font`, `--label-size`, `--label-weight`, `--label-line-height`, `--label-letter-spacing` |
|
|
164
|
+
| Caption | `--caption-font`, `--caption-size`, `--caption-weight`, `--caption-line-height`, `--caption-letter-spacing` |
|
|
165
|
+
|
|
166
|
+
## Dark Mode
|
|
167
|
+
|
|
168
|
+
Activate dark mode by adding `dark` class or `data-theme="dark"` to the root element:
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<html className="dark"> {/* or data-theme="dark" */}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
All color tokens automatically switch values. No code changes needed in components.
|
|
175
|
+
|
|
176
|
+
## Icon Library
|
|
177
|
+
|
|
178
|
+
This library uses **iconsax-react** for icons. Import icons like:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import { Home2, Setting2, ArrowDown2 } from 'iconsax-react';
|
|
182
|
+
<Home2 size={16} />
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Component Architecture Pattern
|
|
186
|
+
|
|
187
|
+
When creating new components for this library, follow this pattern:
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
import * as React from 'react';
|
|
191
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
192
|
+
import { cn } from '@/lib/utils';
|
|
193
|
+
|
|
194
|
+
const myVariants = cva('base-classes', {
|
|
195
|
+
variants: { variant: { default: '...', secondary: '...' } },
|
|
196
|
+
defaultVariants: { variant: 'default' },
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
interface MyComponentProps
|
|
200
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
201
|
+
VariantProps<typeof myVariants> {}
|
|
202
|
+
|
|
203
|
+
const MyComponent = React.forwardRef<HTMLDivElement, MyComponentProps>(
|
|
204
|
+
({ className, variant, ...props }, ref) => (
|
|
205
|
+
<div ref={ref} className={cn(myVariants({ variant }), className)} {...props} />
|
|
206
|
+
)
|
|
207
|
+
);
|
|
208
|
+
MyComponent.displayName = 'MyComponent';
|
|
209
|
+
|
|
210
|
+
export { MyComponent, myVariants };
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Key conventions:
|
|
214
|
+
- Always use `React.forwardRef`
|
|
215
|
+
- Use `cn()` from `@/lib/utils` for className merging (clsx + tailwind-merge)
|
|
216
|
+
- Use `cva()` for variant definitions
|
|
217
|
+
- Use Radix UI primitives for complex behaviors (dialogs, tooltips, etc.)
|
|
218
|
+
- All colors must use design token Tailwind classes, never hardcoded values
|
|
219
|
+
- Set `displayName` on forwardRef components
|
|
220
|
+
- Support `asChild` prop via Radix `Slot` for composition
|
|
221
|
+
|
|
222
|
+
## File Structure
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
src/
|
|
226
|
+
components/ui/ — All UI components
|
|
227
|
+
lib/utils.ts — cn() utility
|
|
228
|
+
styles/globals.css — Tailwind config + @theme token mappings
|
|
229
|
+
tokens/generated/ — Auto-generated from Figma tokens
|
|
230
|
+
docs/ — Storybook documentation pages
|
|
231
|
+
index.ts — Library entry point
|
|
232
|
+
scripts/
|
|
233
|
+
transform-tokens.ts — Token generator (reads design-tokens/ folder)
|
|
234
|
+
design-tokens/ — DTCG token files from Figma
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Token Regeneration
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
pnpm tokens:generate # Reads design-tokens/ folder → generates CSS, TS, Tailwind theme
|
|
241
|
+
```
|
|
@@ -488,8 +488,8 @@
|
|
|
488
488
|
--letter-spacing-none: 0.15px;
|
|
489
489
|
--letter-spacing-tight: -0.2px;
|
|
490
490
|
--letter-spacing-wide: 0.2px;
|
|
491
|
-
--letter-spacing-tight-
|
|
492
|
-
--letter-spacing-wide-
|
|
491
|
+
--letter-spacing-tight-em: -0.01em;
|
|
492
|
+
--letter-spacing-wide-em: 0.02em;
|
|
493
493
|
|
|
494
494
|
/* ── Unit Primitives ── */
|
|
495
495
|
--space-0: 0px;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mayor_grd/centry-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "React UI component library built from Basis DS design tokens",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
],
|
|
40
40
|
"files": [
|
|
41
41
|
"dist",
|
|
42
|
-
"README.md"
|
|
42
|
+
"README.md",
|
|
43
|
+
"CLAUDE.md"
|
|
43
44
|
],
|
|
44
45
|
"peerDependencies": {
|
|
45
46
|
"react": "^18.0.0 || ^19.0.0",
|