284 lines
8.1 KiB
Markdown
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
|