Nychthemeron/docs/superpowers/specs/2026-05-11-library-with-playground-design.md
Matthew L McPeak 8b54df80ab
Some checks failed
ci / build (push) Failing after 27s
ci / publish (push) Has been skipped
ci / publish-docs (push) Has been skipped
Inital Commit
2026-07-15 19:32:31 -04:00

284 lines
8.1 KiB
Markdown

# Library with Playground Design
**Date:** 2026-05-11
**Project:** nychthemeron
**Status:** Approved
## Overview
Transform nychthemeron from a single Vue app into a monorepo containing a Vue component library built on PrimeVue with Tailwind CSS styling, accompanied by a Storybook playground for interactive documentation and development.
## Goals
- Build a reusable Vue component library with custom Tailwind-based styling on PrimeVue
- Provide interactive documentation via Storybook for developers and stakeholders
- Enable fast, hot-reload development workflow
- Support both components and composables (e.g., date utilities for DatePicker)
- Keep internal/private — no npm publishing required
## Architecture
### Monorepo Structure
```
nychthemeron/
├── packages/
│ ├── library/ # Vue component library
│ │ ├── src/
│ │ │ ├── components/ # Vue components (DatePicker, Button, etc.)
│ │ │ ├── composables/ # Reusable logic (useDate, etc.)
│ │ │ └── index.ts # Barrel export for all exports
│ │ ├── __tests__/ # Unit tests
│ │ ├── package.json # Library metadata
│ │ ├── tsconfig.json # Library TS config
│ │ └── vite.config.ts # Library build config
│ │
│ └── playground/ # Storybook playground
│ ├── .storybook/
│ │ ├── main.ts # Storybook configuration
│ │ └── preview.ts # Global setup (Tailwind, PrimeVue)
│ ├── stories/ # Component stories (.stories.ts)
│ ├── package.json # Playground metadata
│ ├── tsconfig.json # Storybook TS config
│ └── tailwind.config.ts # Shared Tailwind config
├── package.json # Root workspace config (bun workspaces)
├── tsconfig.json # Shared base TS config
├── eslint.config.ts # Shared ESLint config
├── prettier.config.json # Shared Prettier config
└── docs/ # Documentation
```
### Dependency Model
- **Root:** Shared dev dependencies (TypeScript, ESLint, Prettier, bun workspace config)
- **Library:** Declares PrimeVue, Vue 3 as peer dependencies; exports components + composables
- **Playground:** Imports `@nychthemeron/library` and PrimeVue; bundles Storybook
### Technology Stack
| Layer | Technology |
|-------|-----------|
| Framework | Vue 3 |
| Component Base | PrimeVue |
| Styling | Tailwind CSS + custom CSS layer |
| Build (Library) | Vite (library mode) |
| Build (Playground) | Vite + Storybook |
| Testing | Vitest + Vue Test Utils |
| Package Manager | Bun (with workspaces) |
| Type Checking | TypeScript + vue-tsc |
## Library Package Details
### Export Model
**index.ts** exports all components and composables:
```typescript
export * from './components'
export * from './composables'
```
Consumers import as:
```typescript
import { DatePicker, Button } from '@nychthemeron/library'
import { useDate } from '@nychthemeron/library'
```
### Component Structure
Each component lives in its own folder:
```
src/components/
├── DatePicker/
│ ├── DatePicker.vue
│ └── DatePicker.spec.ts
├── Button/
│ ├── Button.vue
│ └── Button.spec.ts
└── index.ts
```
### Composables Structure
Reusable logic in `src/composables/`:
```
src/composables/
├── useDate.ts # Date utilities (parsing, formatting, etc.)
├── index.ts
```
Components use composables internally; consumers can also import them directly.
### Tailwind Integration
- `tailwind.config.ts` extends PrimeVue theme with custom utilities
- Library does NOT bundle Tailwind — consumers must include it in their setup
- Supports portability: teams can apply custom Tailwind themes independently
### Build Output
- ESM modules (primary) + optional CommonJS
- TypeScript declarations (`.d.ts`)
- Sourcemaps for debugging
- No dependency bundling (peer deps only)
## Playground Package Details
### Storybook Configuration
- **Addon:** Vue 3 builder
- **Global Setup:** `preview.ts` configures:
- Tailwind CSS
- PrimeVue theme setup
- Global styles
- **Stories Location:** `stories/` directory
### Story Structure
Each component gets a `.stories.ts` file:
```typescript
// stories/DatePicker.stories.ts
import DatePicker from '../components/DatePicker.vue'
export default {
component: DatePicker,
tags: ['autodocs'],
}
export const Default = {}
export const WithCustomTheme = { args: { /* ... */ } }
```
Stories serve triple duty:
1. Interactive documentation for developers
2. Visual regression baseline
3. Live testing environment during dev
### Preview Configuration
`preview.ts` sets up:
- Tailwind CSS
- PrimeVue initialization
- Global CSS imports
- Example theme configuration
## Development Workflow
### Scripts
**Root-level (`bun` commands):**
```json
{
"dev": "bun -r --cwd packages/playground dev",
"build": "bun -r --cwd packages/library build && bun -r --cwd packages/playground build",
"lint": "eslint packages/*/src",
"type-check": "vue-tsc --build",
"test": "bun -r --cwd packages/library test:unit"
}
```
**Library scripts:**
- `bun dev` — (unused for lib, optional for local testing)
- `bun build` — Vite library build
- `bun test:unit` — Vitest
**Playground scripts:**
- `bun dev` — Start Storybook dev server (port 6006)
- `bun build` — Build static Storybook site
### Developer Experience
1. **Start playground:** `bun dev` (root) → Storybook on `localhost:6006`
2. **Edit component:** Modify `packages/library/src/components/DatePicker/DatePicker.vue`
3. **See update:** Playground hot-reloads via Storybook
4. **View story:** Open `stories/DatePicker.stories.ts` to add/update examples
5. **Test:** Run `bun test` in library package
### Hot Reload
- Library changes trigger Storybook rebuild
- Playground imports `@nychthemeron/library` from source (no build step during dev)
## Testing Strategy
### Unit Tests
- **Location:** `packages/library/__tests__/`
- **Framework:** Vitest + Vue Test Utils
- **Coverage:** Component logic, composables, edge cases
- **Command:** `bun test` (from library or root)
### Visual Documentation
- Storybook stories serve as visual baseline
- Can be extended with snapshot testing if needed
### Type Safety
- `vue-tsc --build` runs across monorepo
- CI/local checks ensure no type errors
## Build & Deployment
### Library Build
- **Output:** `packages/library/dist/`
- **Formats:** ESM (primary) + optional CommonJS
- **Declarations:** Full TypeScript support
- **Size:** Optimized with tree-shaking enabled
### Playground Build
- **Output:** `packages/playground/storybook-static/`
- **Deploy:** Can be served on internal server, wiki, or documentation site
- **Audience:** Internal team, stakeholders, designers
### Internal Distribution
No npm publishing. Teams use library by:
- Cloning/pulling monorepo
- Installing dependencies: `bun install`
- Importing components from `@nychthemeron/library`
## Dependencies
### Library Package
**Peer Dependencies:**
- `vue@^3.5.0`
- `primevue@^18.0.0` (or latest)
**Dev Dependencies:** (shared from root)
- TypeScript, Vite, ESLint, Prettier
### Playground Package
**Dependencies:**
- `@nychthemeron/library` (local workspace package)
- `primevue`
- `vue`
**Dev Dependencies:**
- Storybook (@storybook/vue3)
- Vite, TypeScript
## Success Criteria
- ✅ Monorepo structure set up with bun workspaces
- ✅ Library builds to `dist/` with exports
- ✅ Storybook starts with `bun dev` and hot-reloads on library changes
- ✅ Components use PrimeVue + Tailwind CSS
- ✅ Composables (e.g., `useDate`) are accessible
- ✅ TypeScript declarations present and correct
- ✅ Unit tests run and pass
- ✅ Shared config (ESLint, Prettier, tsconfig) enforced across packages
## Next Steps
1. Restructure project into monorepo layout
2. Set up bun workspaces in root `package.json`
3. Create library package with Vite lib config
4. Create playground package with Storybook
5. Add shared configurations
6. Implement first component (e.g., Button or DatePicker)
7. Create corresponding Storybook stories
8. Test hot-reload workflow