cooterlabs 1.0.2 → 2.1.0

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/README.md CHANGED
@@ -1,80 +1,263 @@
1
1
  # CooterLabs UI Library CLI
2
2
 
3
- A blazingly fast, standalone CLI tool for scaffolding beautiful, accessible, and highly customizable UI components built strictly for React, Vite, and Next.js applications directly into your project via the terminal!
3
+ A standalone CLI for scaffolding the **Aeon Product Design System** — beautiful, accessible, highly customizable React components directly into your React, Vite, or Next.js project.
4
4
 
5
- It brings components directly to you. We do not provide a generic NPM library package to import elements from. Instead, the actual React TS/JS code is scaffolded straight into your `src/components/ui` folder, meaning you completely own the implementation, styles, and markup.
5
+ It brings components directly to you. This is **not** an importable NPM package: the actual React TS/JS source is scaffolded straight into your `src/components/ui` folder, so you completely own the implementation, styles, and markup. Think shadcn/ui, but for the Aeon design system.
6
+
7
+ ```bash
8
+ npx cooterlabs init # set up the theme
9
+ npx cooterlabs add button # scaffold a component
10
+ ```
11
+
12
+ ---
13
+
14
+ ## Table of contents
15
+
16
+ - [Features](#features)
17
+ - [Requirements](#requirements)
18
+ - [Commands](#commands)
19
+ - [`init` — theme setup](#init--theme-setup)
20
+ - [`add` — scaffold components](#add--scaffold-components)
21
+ - [The shared `cn()` utility](#the-shared-cn-utility)
22
+ - [The Aeon theme](#the-aeon-theme)
23
+ - [Semantic colors](#semantic-colors)
24
+ - [Primitive color scales](#primitive-color-scales)
25
+ - [Typography ramp](#typography-ramp)
26
+ - [Radius, elevation & focus ring](#radius-elevation--focus-ring)
27
+ - [Component reference](#component-reference)
28
+ - [How it works under the hood](#how-it-works-under-the-hood)
29
+ - [Changelog](#changelog)
30
+ - [License](#license)
31
+
32
+ ---
6
33
 
7
34
  ## Features
8
35
 
9
- - **✅ Project Detection**: Auto-detects your ecosystem (Next.js App router/Pages router, Vite, Create React App).
10
- - **✅ TypeScript vs. JavaScript**: Installs `.tsx` component files if you use TypeScript, gracefully falling back to stripped `.jsx` components for vanilla JS environments.
11
- - **✅ Tailwind Awareness**: Verifies you have Tailwind appropriately installed.
12
- - **✅ Dependency Auto-Install**: If the component you want needs `framer-motion`, `@radix-ui/react-checkbox` or even just `clsx`, the CLI automatically resolves these dependencies silently for you.
13
- - **✅ Prettier Formatting**: Uses your project's Prettier settings statically against our components before file creation so the component matches your exact code-style.
14
- - **✅ Interactive Interface**: Employs interactive menus to let you visually pick the component you want to build inside your project.
36
+ - **Project detection** — auto-detects your ecosystem: Next.js (App router or Pages router), Vite, or Create React App, plus your package manager (`npm`, `pnpm`, `yarn`, `bun`) from lockfiles.
37
+ - **TypeScript vs. JavaScript** installs `.tsx` component files when TypeScript is detected (via `typescript` dependency or `tsconfig.json`), falling back to `.jsx` otherwise.
38
+ - **Tailwind awareness** — warns if Tailwind CSS isn't detected, since all components are styled with Tailwind utilities.
39
+ - **Dependency auto-install** each component's runtime dependencies (`@radix-ui/*`, `lucide-react`, `clsx`, `tailwind-merge`) are resolved and installed automatically, collectively, in one pass.
40
+ - **Component dependencies** components that build on other components (e.g. `select` reuses `input`'s variant styles) automatically pull in what they need.
41
+ - **Shared `cn()` helper** a single `src/lib/utils.ts` is scaffolded once and shared by every component, with a tailwind-merge config that understands the Aeon type ramp (see [below](#the-shared-cn-utility)).
42
+ - **Prettier formatting** — components are formatted with *your* project's Prettier config before being written, so they match your code style from the first commit.
43
+ - **Interactive interface** — run without arguments to get an autocomplete multi-select of every available component.
15
44
 
16
- ## Installation / Usage
45
+ ## Requirements
17
46
 
18
- 1. Open your terminal at the root of your project directory.
19
- 2. Ensure you have `tailwind-merge` and `clsx` properly configured in a central utility path or installed manually (some components will auto-detect and install these).
47
+ - **React 18+** project (Vite, Next.js, or CRA).
48
+ - **Tailwind CSS v4** for the default `aeon` theme (it's emitted as a v4 `@theme` block). The legacy `zinc` / `slate` themes target Tailwind v3 / shadcn-style HSL variables.
49
+ - Node 18+ (the CLI is an ES module).
20
50
 
21
- ### Initialization (Themes & CSS Base)
51
+ ---
22
52
 
23
- To swiftly set up a cohesive Tailwind theme and properly configure your base CSS file (e.g. `index.css` or `globals.css`), run:
53
+ ## Commands
54
+
55
+ ### `init` — theme setup
56
+
57
+ Sets up the design-system CSS variables in your base stylesheet (`src/index.css`, `app/globals.css`, or `styles/globals.css` — resolved automatically per framework):
24
58
 
25
59
  ```bash
26
- npx cooterlabs init
60
+ npx cooterlabs init # interactive theme picker
61
+ npx cooterlabs init aeon # non-interactive, applies the default theme
27
62
  ```
28
63
 
29
- This will give you a list of carefully curated designer themes (like `zinc`, `slate`) to apply global default variables (background, foreground, primary borders, etc.) out-of-the-box.
64
+ What it does:
65
+
66
+ 1. Locates (or creates) your base CSS file.
67
+ 2. Ensures the Tailwind entry point exists — `@import "tailwindcss";` for v4 themes, the classic `@tailwind base/components/utilities` trio for legacy themes.
68
+ 3. Appends the theme block. For **aeon** this is a Tailwind v4 `@theme static { … }` block plus the `alert-timer` keyframes used by the Alert component's auto-dismiss countdown.
69
+ 4. If theme variables already exist in the file, it prints the block for you to merge manually instead of clobbering your file.
30
70
 
31
- ### Adding Components
71
+ Available themes:
32
72
 
33
- Run the CLI tool without arguments to get an interactive autocomplete prompt:
73
+ | Theme | Format | Description |
74
+ |---|---|---|
75
+ | `aeon` *(default)* | Tailwind v4 `@theme` | The full Aeon Product Design System — colors, type ramp, radii, elevation, focus ring. |
76
+ | `zinc` | v3 / shadcn HSL `:root` vars | Legacy neutral theme. |
77
+ | `slate` | v3 / shadcn HSL `:root` vars | Legacy cool-grey theme. |
78
+
79
+ ### `add` — scaffold components
34
80
 
35
81
  ```bash
36
- npx cooterlabs add
82
+ npx cooterlabs add # interactive multi-select
83
+ npx cooterlabs add button # one component
84
+ npx cooterlabs add card badge # ⚠️ one at a time — run twice, or use the picker
85
+ npx cooterlabs add --all # everything
37
86
  ```
38
87
 
39
- If you know exactly what component you want, bypass the interactive wizard and supply the name:
88
+ What it does, per run:
40
89
 
41
- ```bash
42
- # Example: Adding a Button
43
- npx cooterlabs add button
90
+ 1. Detects framework, TypeScript, Tailwind, and package manager.
91
+ 2. Expands component requirements — e.g. `add select` also scaffolds `input`, because `select.tsx` imports its shared variant styles from `./input`.
92
+ 3. Scaffolds `src/lib/utils.ts` (the shared `cn()` helper) if it doesn't exist yet.
93
+ 4. Copies each component into `src/components/ui/` (or `components/ui/` for Next.js without `src/`), formatted with your Prettier config.
94
+ 5. Installs the union of all required runtime dependencies in a single package-manager invocation.
95
+
96
+ Existing files with the same name are overwritten — re-running `add` is also how you *update* a component to the latest version (diff your local changes first if you've customized it).
44
97
 
45
- # Example: Adding an Avatar
46
- npx cooterlabs add avatar
98
+ ---
99
+
100
+ ## The shared `cn()` utility
101
+
102
+ Every component imports one helper:
103
+
104
+ ```ts
105
+ import { cn } from "../../lib/utils"
47
106
  ```
48
107
 
49
- ### Install All Components At Once
108
+ The CLI scaffolds this file once, at `src/lib/utils.ts` (or `lib/utils.js`). It is **not** the stock shadcn two-liner — it uses `extendTailwindMerge` to teach tailwind-merge the Aeon font-size ramp:
50
109
 
51
- Need a complete starting block? Add the `--all` flag to scaffold the entire library in one go:
110
+ ```ts
111
+ import { clsx, type ClassValue } from "clsx"
112
+ import { extendTailwindMerge } from "tailwind-merge"
52
113
 
53
- ```bash
54
- npx cooterlabs add --all
114
+ const twMerge = extendTailwindMerge({
115
+ extend: {
116
+ classGroups: {
117
+ "font-size": [{ text: ["h1", …, "b4", …, "btn-tiny"] }],
118
+ },
119
+ },
120
+ })
121
+
122
+ export function cn(...inputs: ClassValue[]) {
123
+ return twMerge(clsx(inputs))
124
+ }
125
+ ```
126
+
127
+ **Why this matters:** without it, tailwind-merge treats custom utilities like `text-b4` as text *colors* and silently drops real color classes like `text-white` when they appear together. If you already have your own `lib/utils`, the CLI won't overwrite it — but make sure it includes this classGroups extension or component styles will subtly break.
128
+
129
+ ---
130
+
131
+ ## The Aeon theme
132
+
133
+ Running `npx cooterlabs init aeon` gives you the complete design system as CSS variables, which Tailwind v4 turns into utilities automatically.
134
+
135
+ ### Semantic colors
136
+
137
+ `background`, `foreground`, `card`, `popover`, `primary` (deep teal `#0d3435`), `secondary`, `muted`, `accent`, `destructive`, `border`, `input`, `ring` — plus status colors `success`, `info`, `warning`, `error`, each with a `-foreground` pair. Use them as `bg-primary`, `text-muted-foreground`, `border-border`, etc.
138
+
139
+ ### Primitive color scales
140
+
141
+ Full 50–900 scales for `primary-*`, `grey-*`, `success-*`, `error-*`, `warning-*`, and `info-*` — e.g. `bg-primary-50`, `text-grey-500`, `border-error-200`. Components use these for hover/active/disabled states, so keep them if you retheme.
142
+
143
+ ### Typography ramp
144
+
145
+ The entire Aeon type ramp ships as `--text-*` variables, each with size, line-height, **and weight** baked in:
146
+
147
+ | Utilities | Role |
148
+ |---|---|
149
+ | `text-h1` … `text-h5` | Headings (48px/600 → 24px/600) |
150
+ | `text-s1`, `text-s2` | Subtitles |
151
+ | `text-b1` … `text-b4` | Body (regular & medium, 16px & 14px) |
152
+ | `text-c1` … `text-c3` | Captions (12px & 10px) |
153
+ | `text-label` | Form labels |
154
+ | `text-btn-giant` … `text-btn-tiny` | Button text sizes |
155
+
156
+ Font family: **Inter** (`--font-sans`). Load the font yourself (e.g. via Google Fonts or `@fontsource/inter`) — the theme only declares the stack.
157
+
158
+ ### Radius, elevation & focus ring
159
+
160
+ - **Radius:** `rounded-xxs` (4px) → `rounded-xl` (24px).
161
+ - **Elevation:** `shadow-100` → `shadow-800`.
162
+ - **Focus ring:** `--shadow-focus` (a 3px `#c2f5f6` halo) — every interactive component uses `focus-visible:shadow-focus` for a consistent, accessible focus style.
163
+ - **`@keyframes alert-timer`:** powers the Alert component's auto-dismiss countdown bar; emitted alongside the theme block.
164
+
165
+ ---
166
+
167
+ ## Component reference
168
+
169
+ All components live in `components/ui/`, are fully typed, and follow the Aeon size ramp (`giant / large / medium / small / tiny`) where applicable. Radix-based components keep the full Radix composition API.
170
+
171
+ ### Form controls
172
+
173
+ | Component | Exports | Key props / notes |
174
+ |---|---|---|
175
+ | `button` | `Button` | `variant`: `filled` \| `outline` \| `clear` · `size`: giant→tiny · `iconOnly` · `asChild` (Radix `Slot`). |
176
+ | `button-group` | `ButtonGroup`, `ButtonGroupItem` | Segmented control matching the button size ramp. |
177
+ | `input` | `Input` (+ exported style maps reused by `select`) | `variant`: `outline` \| `filled` · `size`: `large` \| `medium` · `status`: success/info/warning/error · `helperText` · `icon`. |
178
+ | `textarea` | `Textarea` | Multiline input matching `input` styling. |
179
+ | `select` | `Select`, `SelectTrigger`, `SelectContent`, `SelectItem`, `SelectValue`, `SelectGroup`, … | Radix select styled as an Aeon input; **requires `input`** (auto-installed). |
180
+ | `label` | `Label` | Radix label. |
181
+ | `checkbox` | `Checkbox` | Radix checkbox with indeterminate support. |
182
+ | `radio` | `RadioGroup`, `RadioGroupItem` | Radix radio group. |
183
+ | `toggle` | `Toggle` | Radix switch. |
184
+
185
+ ### Feedback
186
+
187
+ | Component | Exports | Key props / notes |
188
+ |---|---|---|
189
+ | `alert` | `Alert`, `AlertTitle`, `AlertDescription`, `AlertActions` | `severity`: default/success/info/warning/error · `variant`: `filled` \| `outline` · `position` (fixed placements) · `duration` (auto-dismiss seconds, pauses on hover, animated countdown) · `onDismiss`. |
190
+ | `badge` | `Badge` | `type`: `badge` \| `chip` (chips are dismissible/selectable) · `variant`: `filled` \| `outline` · `color`: default/success/info/warning/error · `size`: medium/small/tiny · `iconOnly`. |
191
+ | `avatar` | `Avatar`, `AvatarImage`, `AvatarFallback` | Radix avatar, `size`: giant→tiny. |
192
+ | `progress` | `Progress` | Radix progress; `label`: `left` \| `right` percentage label · `disabled`. |
193
+ | `loader` | `Loader` | CSS spinner, `size`: giant→tiny. |
194
+ | `tooltip` | `TooltipProvider`, `Tooltip`, `TooltipTrigger`, `TooltipContent` | Radix dark tooltip. |
195
+
196
+ ### Overlays
197
+
198
+ | Component | Exports | Key props / notes |
199
+ |---|---|---|
200
+ | `dialog` | `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogFooter`, … | Radix dialog (Pop-Up). |
201
+ | `action-sheet` | `ActionSheet`, `ActionSheetTrigger`, `ActionSheetContent`, … | Mobile bottom sheet built on Radix dialog. |
202
+ | `context-menu` | `ContextMenu`, `ContextMenuTrigger`, `ContextMenuContent`, `ContextMenuItem`, checkbox/radio items, … | Radix context menu. |
203
+ | `dropdown` | `DropdownMenu`, `DropdownMenuTrigger`, `DropdownMenuContent`, `DropdownMenuItem`, … | Radix dropdown menu. |
204
+
205
+ ### Navigation
206
+
207
+ | Component | Exports | Key props / notes |
208
+ |---|---|---|
209
+ | `tabs` | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | Radix tabs. |
210
+ | `breadcrumb` | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, … | Accessible breadcrumb trail. |
211
+ | `pagination` | `Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink`, `PaginationPrevious`, `PaginationNext`, … | Page navigation. |
212
+ | `page-control` | `PageControl` | Mobile page-indicator dots. |
213
+ | `stepper` | `Stepper`, `StepperItem`, `StepperSeparator` | Horizontal step indicator. |
214
+ | `navbar-top` | `NavbarTop`, `NavbarTopLeft`, `NavbarTopTitle`, `NavbarTopRight` | Mobile top app bar. |
215
+ | `navbar-bottom` | `NavbarBottom`, `NavbarBottomItem` | Mobile bottom tab bar. |
216
+ | `list` | `List`, `ListHeader`, `ListItem` | Mobile list rows with leading/trailing slots. |
217
+
218
+ ### Layout
219
+
220
+ | Component | Exports | Key props / notes |
221
+ |---|---|---|
222
+ | `card` | `Card`, `CardImage`, `CardHeader`, `CardFooter`, `CardTitle`, `CardDescription`, … | Composable card wrappers. |
223
+
224
+ ### Example
225
+
226
+ ```tsx
227
+ import { Button } from "@/components/ui/button"
228
+ import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"
229
+
230
+ export function Example() {
231
+ return (
232
+ <>
233
+ <Button variant="filled" size="large">Save changes</Button>
234
+ <Alert severity="success" duration={5} onDismiss={() => {}}>
235
+ <AlertTitle>Saved</AlertTitle>
236
+ <AlertDescription>Your changes are live.</AlertDescription>
237
+ </Alert>
238
+ </>
239
+ )
240
+ }
55
241
  ```
56
242
 
57
- ## Available Components
243
+ ---
244
+
245
+ ## How it works under the hood
58
246
 
59
- Currently, the CooterLabs Library ships with the following carefully designed boilerplate components:
247
+ 1. `npx cooterlabs add [component]` inspects your filesystem: lockfiles for the package manager, `package.json` deps for the framework, `tsconfig.json` for TypeScript, and Tailwind config/deps for styling support.
248
+ 2. Component requirements are expanded (`select` → `input`), then the shared `lib/utils` helper is scaffolded if missing.
249
+ 3. Templates are copied from the CLI package into `src/components/ui/` (or `components/ui/`), run through your Prettier config, and written with the right extension.
250
+ 4. The union of every selected component's runtime dependencies is installed in one package-manager call, so you only get libraries the components actually use.
60
251
 
61
- - `avatar` - An accessible React image element holding fallback identifiers.
62
- - `badge` - Tiny status badge elements relying on standard `variant` mappings.
63
- - `button` - A highly stylized native HTML button leveraging Radix UI primitives (`Slot`).
64
- - `card` - Content display wrappers comprising headers, footers, body content, and titles.
65
- - `checkbox` - Robust implementation for accessible `<input type="checkbox"/>` mappings.
66
- - `input` - Your standard customized HTML `<input />`.
67
- - `label` - An accessible Radix-backed `<label />`.
68
- - `textarea` - A matching multiline input variation styling perfectly with standard inputs.
252
+ ## Changelog
69
253
 
70
- ## How it works under-the-hood
254
+ ### 2.1.0
71
255
 
72
- 1. When you run `npx cooterlabs add [component]`, the script analyzes your filesystem looking for `pnpm-lock.yaml`, `bun.lockb`, `yarn.lock`, etc., and detects package managers.
73
- 2. It looks for `tsconfig.json` to see if it should copy the raw `.tsx` component files or use regex parsers to strip types for a standard `.jsx` output.
74
- 3. It recursively creates target folders, usually resolving to `src/components/ui` or `components/ui`.
75
- 4. Formatting is applied.
76
- 5. Child dependencies (e.g., `lucide-react`, Radix UI dependencies) required *exclusively* for that component are installed so the codebase isn't overwhelmed with useless imported libraries.
256
+ - **Synced all 28 component templates** with the latest Aeon implementations (updated button/badge/alert variants, refined focus states using `shadow-focus`, tailwind-merge-safe type-ramp classes).
257
+ - **New component: `select`** Radix select styled as an Aeon input; auto-installs `input`, whose variant styles it reuses.
258
+ - **Shared `cn()` helper** components now import from `lib/utils` instead of inlining `cn` per file; the CLI scaffolds it (with the type-ramp-aware tailwind-merge config) on first `add`.
259
+ - **Theme update** — the `aeon` theme now ships `--shadow-focus` (shared focus ring) and the `alert-timer` keyframes for Alert auto-dismiss.
77
260
 
78
261
  ## License
79
262
 
80
- MIT - Grab it, use it, scale it!
263
+ MIT Grab it, use it, scale it!