Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions docs/plans/ui-package-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
# UI Package Migration Plan

Extract Zag components from `packages/web` into a shared `packages/ui` package for reuse across web and landing.

## Package Structure

```
packages/
ui/
package.json
jsconfig.json
src/
index.js # Barrel export
zag/
index.js # Zag barrel export
Accordion.jsx
Avatar.jsx
Checkbox.jsx
Clipboard.jsx
Collapsible.jsx
Combobox.jsx
Dialog.jsx
Editable.jsx
FileUpload.jsx
FloatingPanel.jsx
Menu.jsx
NumberInput.jsx
PasswordInput.jsx
PinInput.jsx
Popover.jsx
Progress.jsx
QRCode.jsx
RadioGroup.jsx
Select.jsx
Splitter.jsx
Switch.jsx
Tabs.jsx
TagsInput.jsx
Toast.jsx
ToggleGroup.jsx
Tooltip.jsx
Tour.jsx
README.md
```

## Tasks

### 1. Create Package Infrastructure

- [ ] Create `packages/ui/` directory
- [ ] Create `package.json` with name `@corates/ui`
- [ ] Create `jsconfig.json` for path aliases
- [ ] Add to `pnpm-workspace.yaml` (already includes `packages/*`)

### 2. Move Dependencies

Move these from `packages/web/package.json` to `packages/ui/package.json`:

**Zag.js packages:**

- @zag-js/accordion
- @zag-js/avatar
- @zag-js/checkbox
- @zag-js/clipboard
- @zag-js/collapsible
- @zag-js/combobox
- @zag-js/dialog
- @zag-js/editable
- @zag-js/file-upload
- @zag-js/floating-panel
- @zag-js/menu
- @zag-js/number-input
- @zag-js/pin-input
- @zag-js/popover
- @zag-js/progress
- @zag-js/qr-code
- @zag-js/radio-group
- @zag-js/select
- @zag-js/solid
- @zag-js/splitter
- @zag-js/switch
- @zag-js/tabs
- @zag-js/tags-input
- @zag-js/toast
- @zag-js/toggle-group
- @zag-js/tooltip
- @zag-js/tour

**Peer dependencies:**

- solid-js (peerDependency)
- solid-icons (or move icons to consuming packages)

### 3. Move Component Files

- [ ] Copy all files from `packages/web/src/components/zag/` to `packages/ui/src/zag/`
- [ ] Create barrel exports (`index.js` files)
- [ ] Delete original files from web package

### 4. Create Barrel Exports

`packages/ui/src/zag/index.js`:

```js
export { Accordion } from './Accordion';
export { Avatar } from './Avatar';
export { Checkbox } from './Checkbox';
export { Clipboard, CopyButton } from './Clipboard';
// ... all components
```

`packages/ui/src/index.js`:

```js
export * from './zag';
```

### 5. Update Consumer Packages

**packages/web/package.json:**

```json
{
"dependencies": {
"@corates/ui": "workspace:*"
}
}
```

**packages/landing/package.json:**

```json
{
"dependencies": {
"@corates/ui": "workspace:*"
}
}
```

### 6. Update Imports in Web Package

Find and replace all imports:

```js
// Before
import { Dialog } from '@components/zag/Dialog';
import { Select } from '@components/zag/Select';

// After
import { Dialog, Select } from '@corates/ui';
```

### 7. Tailwind Configuration

The UI package uses Tailwind classes. Options:

**Option A: Classes only (recommended)**

- UI package outputs JSX with Tailwind classes
- Each consuming app (web, landing) has its own Tailwind config
- Tailwind config must include `'./node_modules/@corates/ui/**/*.{js,jsx}'` in content paths

**Option B: Shared Tailwind config**

- Create base config in UI package
- Extend in web/landing

### 8. Update Tailwind Configs

`packages/web/tailwind.config.js` - add:

```js
content: ['./src/**/*.{js,jsx}', './node_modules/@corates/ui/**/*.{js,jsx}'];
```

`packages/landing/tailwind.config.js` - add:

```js
content: ['./src/**/*.{js,jsx}', './node_modules/@corates/ui/**/*.{js,jsx}'];
```

### 9. Handle Toast Primitive

The Toast component uses `@primitives/useToast`. Options:

- Move `useToast` primitive to UI package
- Or keep Toast in web, only share components that don't need primitives

### 10. Testing

- [ ] Run `pnpm install` to link workspace packages
- [ ] Run `pnpm lint` to check for errors
- [ ] Start dev servers for web and landing
- [ ] Verify components render correctly
- [ ] Test a component import in landing page

## Migration Order

1. Create package infrastructure (package.json, jsconfig.json)
2. Move dependencies
3. Move component files
4. Create barrel exports
5. Update web package imports
6. Update Tailwind configs
7. Test web package still works
8. Add dependency to landing
9. Test landing can use components

## Rollback Plan

If issues arise:

1. Revert package.json changes
2. Copy components back to web
3. Remove ui package directory

## Open Questions

1. Should solid-icons be a peer dependency or bundled?
2. Move useToast to UI package or keep Toast separate?
3. Any other primitives/utilities needed by components?

## Estimated Effort

- Package setup: 15 min
- Move files & dependencies: 20 min
- Update imports in web: 30 min (many files to update)
- Tailwind config updates: 10 min
- Testing: 15 min

**Total: ~1.5 hours**
75 changes: 75 additions & 0 deletions packages/ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# @corates/ui

Shared UI component library for Corates built with [Zag.js](https://zagjs.com/) and [SolidJS](https://solidjs.com/).

## Installation

This package is meant to be used within the Corates monorepo. Add it as a dependency:

```bash
pnpm add @corates/ui --workspace
```

## Usage

Import components from the package:

```jsx
import { Dialog, Select, Toast, toaster } from '@corates/ui/zag';
```

Or import from the main entry point:

```jsx
import { Dialog, Select, Toast, toaster } from '@corates/ui';
```

## Components

The following Zag.js components are available:

| Component | Description |
| ------------- | ---------------------------------------------------- |
| Accordion | Expandable/collapsible content sections |
| Avatar | User avatar with fallback support |
| Checkbox | Checkbox input with label support |
| Clipboard | Copy to clipboard functionality |
| Collapsible | Single collapsible content section |
| Combobox | Searchable select with autocomplete |
| Dialog | Modal dialog with backdrop |
| Editable | Inline editable text |
| FileUpload | File upload with drag and drop |
| FloatingPanel | Draggable/resizable floating panel |
| Menu | Dropdown menu with keyboard navigation |
| NumberInput | Numeric input with increment/decrement |
| PasswordInput | Password input with visibility toggle |
| PinInput | OTP/PIN code input |
| Popover | Floating content panel |
| Progress | Progress bar indicator |
| QRCode | QR code generator |
| RadioGroup | Radio button group |
| Select | Dropdown select |
| Splitter | Resizable split panels |
| Switch | Toggle switch |
| Tabs | Tabbed content panels |
| TagsInput | Tag/chip input |
| Toast/Toaster | Toast notifications (use `toaster` to create toasts) |
| ToggleGroup | Group of toggle buttons |
| Tooltip | Hover tooltips |
| Tour | Guided tour/onboarding |

## Styling

Components use Tailwind CSS classes. Make sure your Tailwind config includes the UI package in its content paths:

```js
// In your app's CSS or Tailwind config
@source "../../packages/ui/src/**/*.{js,jsx}";
```

## Peer Dependencies

This package requires the following peer dependencies:

- `solid-js` (^1.9.0)
- `solid-icons` (^1.1.0)
10 changes: 10 additions & 0 deletions packages/ui/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@zag/*": ["src/zag/*"]
}
},
"exclude": ["node_modules"]
}
51 changes: 51 additions & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@corates/ui",
"version": "0.0.1",
"private": true,
"description": "Shared UI components for Corates built with Zag.js and SolidJS",
"type": "module",
"main": "./src/index.js",
"exports": {
".": "./src/index.js",
"./zag": "./src/zag/index.js",
"./zag/*": "./src/zag/*.jsx"
},
"dependencies": {
"@zag-js/accordion": "^1.31.1",
"@zag-js/avatar": "^1.31.1",
"@zag-js/checkbox": "^1.31.1",
"@zag-js/clipboard": "^1.31.1",
"@zag-js/collapsible": "^1.31.1",
"@zag-js/combobox": "^1.31.1",
"@zag-js/dialog": "^1.31.1",
"@zag-js/editable": "^1.31.1",
"@zag-js/file-upload": "^1.31.1",
"@zag-js/floating-panel": "^1.31.1",
"@zag-js/menu": "^1.31.1",
"@zag-js/number-input": "^1.31.1",
"@zag-js/password-input": "^1.31.1",
"@zag-js/pin-input": "^1.31.1",
"@zag-js/popover": "^1.31.1",
"@zag-js/progress": "^1.31.1",
"@zag-js/qr-code": "^1.31.1",
"@zag-js/radio-group": "^1.31.1",
"@zag-js/select": "^1.31.1",
"@zag-js/solid": "^1.31.1",
"@zag-js/splitter": "^1.31.1",
"@zag-js/switch": "^1.31.1",
"@zag-js/tabs": "^1.31.1",
"@zag-js/tags-input": "^1.31.1",
"@zag-js/toast": "^1.31.1",
"@zag-js/toggle-group": "^1.31.1",
"@zag-js/tooltip": "^1.31.1",
"@zag-js/tour": "^1.31.1"
},
"peerDependencies": {
"solid-icons": "^1.1.0",
"solid-js": "^1.9.0"
},
"devDependencies": {
"solid-icons": "^1.1.0",
"solid-js": "^1.9.10"
}
}
7 changes: 7 additions & 0 deletions packages/ui/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// @corates/ui - Shared UI Components

// Re-export all Zag components
export * from './zag/index.js';

// Re-export primitives
export { useWindowDrag } from './primitives/useWindowDrag.js';
Loading