Skip to content
Draft
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
102 changes: 68 additions & 34 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,78 +5,112 @@ repository.

## Project Overview

SIX UI Library is a Stencil-based web component library with framework wrappers for Angular, React,
and Vue. The monorepo uses npm workspaces.
SIX UI Library is a Stencil-based web component library providing 60+ components with framework
wrappers for Angular, React, and Vue. The monorepo uses npm workspaces. Originally forked from
[Shoelace](https://shoelace.style/).

## Common Commands
## Prerequisites

Node.js >= 24

## Commands

```bash
# Install dependencies (from root)
# Install dependencies (run from root)
npm install

# Start dev server with hot reload (serves component demos at localhost:3333)
# Dev server with hot reload (localhost:3333)
npm start

# Build all packages
# Build all packages (core + wrappers + docs)
npm run build

# Build only the core library and framework wrappers
# Build core library + framework wrappers only
npm run build:lib

# Run unit tests
# Unit tests (Jest, runs with TZ='Etc/GMT-2')
npm run test

# Run E2E tests (Playwright)
# E2E tests (Playwright, from root)
npm run test:e2e

# Run specific E2E test (from libraries/ui-library)
# Single component E2E test (from libraries/ui-library)
cd libraries/ui-library && npx playwright test six-button

# Run E2E tests with UI
# E2E with UI mode
cd libraries/ui-library && npx playwright test --ui

# Update E2E screenshots after visual changes
cd libraries/ui-library && npx playwright test six-button --update-snapshots

# Lint
npm run lint:lib

# Format
Always run prettier before committing changes.
# Format β€” IMPORTANT: always run before committing
npm run prettier:write
```

## Architecture

**Monorepo structure:**
**Monorepo:**

- `libraries/ui-library` - Core Stencil components (source of truth)
- `libraries/ui-library-angular` - Angular wrappers (auto-generated)
- `libraries/ui-library-react` - React wrappers (auto-generated)
- `libraries/ui-library-vue` - Vue wrappers (auto-generated)
- `examples/` - Demo apps (Angular, React, Vue, Nuxt, vanilla JS)
- `docs/` - VitePress documentation site
- `libraries/ui-library` β€” Core Stencil components (source of truth)
- `libraries/ui-library-angular` β€” Angular wrappers (auto-generated via stencil.config.ts)
- `libraries/ui-library-react` β€” React wrappers (auto-generated)
- `libraries/ui-library-vue` β€” Vue wrappers (auto-generated)
- `examples/` β€” Demo apps (Angular, React, Vue, Nuxt, vanilla JS)
- `docs/` β€” VitePress documentation site

**Component structure** (in `libraries/ui-library/src/components/{name}/`):
**Component file structure** (in `libraries/ui-library/src/components/six-{name}/`):

- `{name}.tsx` - Stencil component
- `{name}.scss` - Styles
- `{name}.e2e.ts` - E2E tests (Playwright)
- `index.html` - Demo page
- `test/{name}.spec.tsx` - Unit tests (Jest)
- `six-{name}.tsx` β€” Stencil component (TypeScript + JSX)
- `six-{name}.scss` β€” Styles (SCSS, shadow DOM)
- `six-{name}.e2e.ts` β€” E2E tests (Playwright)
- `index.html` β€” Demo/dev page for `npm start`
- `readme.md` β€” Auto-generated by Stencil, do NOT edit

**Build outputs:** Stencil generates framework wrappers via output targets in `stencil.config.ts`.
Building ui-library automatically updates the wrapper libraries.
**Key source directories:**

## Code Formatting
- `src/utils/` β€” Shared utilities (23 modules β€” popover, form, event-listeners, etc.)
- `src/global/` β€” Global styles, CSS variables, SCSS mixins
- `src/functional-components/` β€” Stencil functional components
- `src/test-utils/fixtures.ts` β€” Playwright test fixture (CSS injection + coverage)

Use Prettier to format code: `npm run prettier:write`
## Important Rules

- **Do NOT edit auto-generated files:** `readme.md` in component dirs, `components.d.ts`, and all
files in `stencil-generated/` directories of wrapper libraries
- **Do NOT add `Co-Authored-By` lines** to commits
- **Update the changelog** at `docs/changelog.md` under the "Upcoming" section for any user-facing
change. Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format
- **Shadow DOM:** All components use shadow DOM β€” styles are encapsulated, use CSS custom properties
(`--six-*`) for theming
- **CI verifies clean git state** after build (`git diff --exit-code`), so all auto-generated output
from `npm run build` must be committed

## Commit Convention

Format: `type(scope): subject`

Types: `feat`, `fix`, `docs`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`
- Types: `feat`, `fix`, `docs`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`
- Scope: component name (e.g., `six-button`) or area (e.g., `core`, `docs`)
- Example: `fix(six-dropdown): handle events on blur`

## PR Guidelines

- Branch from `main`, merge back to `main`
- New features require tests and a changelog entry
- Bug fixes: include `(fix #xxxx)` in PR title
- Enable "Allow edits from maintainers"
- CI runs: prettier check, lint, unit tests, E2E tests, and build verification

Scope: component name (e.g., `six-button`) or area (e.g., `core`, `docs`)
## Testing

Example: `fix(six-dropdown): handle events on blur`
E2E tests (Playwright) are the primary test approach β€” 46+ test files covering functional behavior,
visual regression (screenshots), and accessibility (axe-core). Unit tests (Jest) exist only for a
few utility modules.

Do not add `Co-Authored-By` lines to commits.
- Import `test` from `../../test-utils/fixtures` β€” the fixture injects the CSS stylesheet and
collects coverage automatically
- Never use `page.waitForTimeout()` in tests
- See `.claude/skills/playwright-tests/` for detailed testing patterns and examples
53 changes: 53 additions & 0 deletions .claude/rules/component-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
paths:
- 'libraries/ui-library/src/components/**/*'
---

# Stencil Component Development

## Component Pattern

Components use Stencil decorators with shadow DOM and SCSS:

```tsx
@Component({
tag: 'six-{name}',
styleUrl: 'six-{name}.scss',
shadow: true,
})
export class Six{Name} {
@Element() host!: HTMLSix{Name}Element;

@Prop({ reflect: true }) propName: string;
@State() internalState = false;
@Event() sixComponentEvent!: EventEmitter<DetailType>;
@Method() async methodName() { }
}
```

## Conventions

- Tag names always start with `six-` prefix
- Class names use PascalCase: `SixButton`, `SixDatepicker`
- Events are prefixed: `six-button-focus`, `six-dropdown-change`
- Use `@Prop({ reflect: true })` for props that should appear as HTML attributes
- Use `hasSlot()` from `../../utils/slot` to check slot content
- Use `submitForm()` from `../../utils/form` for form-participating components
- Expose CSS parts with `part="base"`, `part="label"`, etc. for external styling
- Use JSDoc comments with `@since`, `@status`, `@slot`, `@part` annotations

## Styling

- SCSS files use variables from `src/global/` (e.g., `--six-spacing-medium`, `--six-color-*`)
- Use `:host` for component-level styles
- Use `::slotted()` for slotted content styles
- Expose `--six-*` CSS custom properties for theming

## Adding a New Component

1. Run `npm run generate` from `libraries/ui-library` to scaffold
2. Implement component in `.tsx` with SCSS styles
3. Add `index.html` demo page
4. Write E2E tests (see `.claude/skills/playwright-tests/`)
5. Build (`npm run build:lib`) to generate wrapper code
6. Update changelog
27 changes: 27 additions & 0 deletions .claude/rules/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
paths:
- 'docs/**/*'
---

# Documentation (VitePress)

## Setup

- Documentation is built with VitePress and lives in `docs/`
- Component API docs are auto-generated from Stencil JSDoc annotations
- Start docs dev server: `npm run start:doc` (from root)
- Build docs: `npm run build:doc`
- Fresh start with rebuilt library: `npm run start:doc:fresh:full`

## Changelog

- Located at `docs/changelog.md`
- Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format
- All user-facing changes MUST be added under the "Upcoming" section
- Categories: Added, Changed, Fixed, Removed
- Prefix breaking changes with **⚠️Breaking**

## Docs base path

The docs site is deployed to `/six-webcomponents/v5/` β€” this is configured in
`docs/.vitepress/config.mts` and must match the `target-folder` in the release workflow.
33 changes: 33 additions & 0 deletions .claude/rules/wrapper-libraries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
paths:
- 'libraries/ui-library-angular/**/*'
- 'libraries/ui-library-react/**/*'
- 'libraries/ui-library-vue/**/*'
---

# Framework Wrapper Libraries

## IMPORTANT: Auto-generated code

The `src/lib/stencil-generated/` directories in each wrapper library are **auto-generated** by
Stencil output targets configured in `libraries/ui-library/stencil.config.ts`. Do NOT edit these
files manually β€” they are overwritten on every build.

## How wrappers work

- `@stencil/angular-output-target` generates Angular component wrappers
- `@stencil/react-output-target` generates React component wrappers
- `@stencil/vue-output-target` generates Vue component wrappers with v-model support

## Vue v-model bindings

Vue wrappers have component models configured in `stencil.config.ts`:

- `six-checkbox`, `six-switch` β†’ `checked` prop via `change` event
- `six-input`, `six-textarea`, `six-range` β†’ `value` prop via `input` event
- `six-select`, `six-datepicker`, `six-date` β†’ `value` prop via `change` event

## Modifying wrapper behavior

To change wrapper generation, edit the output target config in
`libraries/ui-library/stencil.config.ts`, then run `npm run build:lib`.
2 changes: 1 addition & 1 deletion .devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "Node.js & TypeScript",
"image": "mcr.microsoft.com/devcontainers/typescript-node:0-18",
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-18",
"portsAttributes": {
"3000": {
"label": "Application",
Expand Down
18 changes: 8 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
- run: npm ci
Expand All @@ -24,8 +24,8 @@ jobs:
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
- run: npm ci
Expand All @@ -35,15 +35,15 @@ jobs:
run: npm run test:e2e

- name: upload playwright report
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: playwright-report
path: libraries/ui-library/playwright-report
retention-days: 30

- name: upload playwright test coverage
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: playwright-coverage-html
Expand All @@ -60,12 +60,10 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: npm ci
- run: npm run build
- name: verify clean build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
4 changes: 2 additions & 2 deletions .github/workflows/pkg.pr.new.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions/setup-node@v4
uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
- run: npm ci
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ jobs:
if: ${{ inputs.release_type == 'insider' || github.event_name == 'push' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
registry-url: 'https://registry.npmjs.org'
Expand Down Expand Up @@ -79,14 +79,12 @@ jobs:
if: ${{ inputs.release_type == 'regular' && inputs.version != '' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 24
registry-url: 'https://registry.npmjs.org'
cache: 'npm'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- run: npm ci

- name: 'Set version in package.json files to ${{ inputs.version }}'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
display-variables:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: 'Display variables'
run: |
echo "github.ref_name: ${{ github.ref_name }}"
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ dist
docs/.vitepress/cache
docs/.vitepress/dist
test-results
/libraries/ui-library-react/dist/

1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
registry=https://registry.npmjs.org/
min-release-age=5
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ docs/.vitepress/cache
playwright-report/
test-results/
coverage
renovate.json
Loading
Loading