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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 3 additions & 3 deletions .github/instructions/a11y.instructions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: "Guidance for creating more accessible code"
applyTo: "resources/js/**,resources/css/**,resources/templates/**,packages/craftcms-cp/src/**"
applyTo: "resources/js/**,resources/css/**,resources/templates/**,packages/craftcms-ui/src/**"
---

# Accessibility instructions
Expand All @@ -11,11 +11,11 @@ You are an expert in accessibility with deep software engineering expertise.

- Conform to [WCAG 2.2 Level AA](https://www.w3.org/TR/WCAG22/).
- Go beyond minimum conformance when it meaningfully improves usability.
- UI components are defined as Lit Web Components in the component library (`@craftcms/cp`) or as Vue components in `./resources/js/`. You SHOULD use the component patterns as defined. Do not recreate patterns.
- UI components are defined as Lit Web Components in the component library (`@craftcms/ui`) or as Vue components in `./resources/js/`. You SHOULD use the component patterns as defined. Do not recreate patterns.
- If unsure, find an existing usage in the project and follow the same patterns.
- Ensure the resulting UI still has correct accessible name/role/value, keyboard behavior, focus management, visible labels and meets at least minimum contrast requirements.
- If a needed component does not exist, prefer native HTML elements/attributes over ARIA.
- The `@craftcms/cp` component library should include components that can be reused by plugin developers, or outside the context of this application. Vue components should be used for application-specific UI.
- The `@craftcms/ui` component library should include components that can be reused by plugin developers, or outside the context of this application. Vue components should be used for application-specific UI.
- Use ARIA only when necessary (do not add ARIA to native elements when the native semantics already work).
- Ensure correct accessible **name, role, value, states, and properties**.
- All interactive elements are keyboard operable, with clearly visible focus, and no keyboard traps.
Expand Down
6 changes: 3 additions & 3 deletions .github/scripts/storybook-preview-comment.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ async function sectionFor(preview, changed) {
// Scope the changed-file matching to the relevant subtree so similarly-named
// directories elsewhere in the repo don't create false positives.
const baseDir =
preview.name === '@craftcms/cp'
? 'packages/craftcms-cp'
preview.name === '@craftcms/ui'
? 'packages/craftcms-ui'
: preview.name === 'resources/js'
? 'resources/js'
: null;
Expand Down Expand Up @@ -87,7 +87,7 @@ async function sectionFor(preview, changed) {

module.exports = async ({github, context}) => {
const previews = [
{name: '@craftcms/cp', result: process.env.CP_RESULT, url: process.env.CP_URL},
{name: '@craftcms/ui', result: process.env.CP_RESULT, url: process.env.CP_URL},
{name: 'resources/js', result: process.env.RESOURCES_RESULT, url: process.env.RESOURCES_URL},
];

Expand Down
49 changes: 43 additions & 6 deletions .github/workflows/js-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
# `testbench typescript:transform` and `testbench wayfinder:generate`
# derive their output from controllers, DTOs, and routes in src/.
run: |
echo "value=js-ci-v3-${{ runner.os }}-${{ hashFiles('package-lock.json', 'composer.lock', 'package.json', 'packages/*/package.json', 'packages/craftcms-cp/src/**', 'packages/craftcms-cp/tsconfig*.json', 'packages/craftcms-cp/vite.config.*', 'packages/craftcms-cp/tsdown.config.*', 'packages/craftcms-garnish/src/**', 'packages/craftcms-garnish/tsconfig*.json', 'packages/craftcms-garnish/tsdown.config.*', 'src/**/*.php', 'workbench/**/*.php') }}" >> "$GITHUB_OUTPUT"
echo "value=js-ci-v3-${{ runner.os }}-${{ hashFiles('package-lock.json', 'composer.lock', 'package.json', 'packages/*/package.json', 'packages/craftcms-ui/src/**', 'packages/craftcms-ui/tsconfig*.json', 'packages/craftcms-ui/vite.config.*', 'packages/craftcms-ui/tsdown.config.*', 'packages/craftcms-garnish/src/**', 'packages/craftcms-garnish/tsconfig*.json', 'packages/craftcms-garnish/tsdown.config.*', 'src/**/*.php', 'workbench/**/*.php') }}" >> "$GITHUB_OUTPUT"

- name: Restore install + build + generated cache
id: cache
Expand All @@ -56,7 +56,7 @@ jobs:
path: |
node_modules
packages/*/node_modules
packages/craftcms-cp/dist
packages/craftcms-ui/dist
packages/craftcms-garnish/dist
vendor
resources/js/actions
Expand All @@ -82,9 +82,9 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
run: npm run build:garnish

- name: Build @craftcms/cp
- name: Build @craftcms/ui
if: steps.cache.outputs.cache-hit != 'true'
run: npm run build:cp
run: npm run build:ui

- name: Generate TypeScript types
if: steps.cache.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -115,7 +115,7 @@ jobs:
path: |
node_modules
packages/*/node_modules
packages/craftcms-cp/dist
packages/craftcms-ui/dist
packages/craftcms-garnish/dist
vendor
resources/js/actions
Expand Down Expand Up @@ -148,7 +148,7 @@ jobs:
path: |
node_modules
packages/*/node_modules
packages/craftcms-cp/dist
packages/craftcms-ui/dist
packages/craftcms-garnish/dist
vendor
resources/js/actions
Expand All @@ -162,3 +162,40 @@ jobs:
# up — the setup job already produced and cached the output).
- name: Run TypeScript type check
run: npm run typecheck

test-ui:
name: 'Tests / @craftcms/ui'
runs-on: ubuntu-latest
timeout-minutes: 10
needs: setup
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'

- name: Restore install + build + generated cache
uses: actions/cache@v4
with:
path: |
node_modules
packages/*/node_modules
packages/craftcms-ui/dist
packages/craftcms-garnish/dist
vendor
resources/js/actions
resources/js/routes
resources/js/wayfinder
resources/js/generated
key: ${{ needs.setup.outputs.cache-key }}

# The storybook tests run in real Chromium via @vitest/browser-playwright.
- name: Install Playwright Chromium
run: npx playwright install --with-deps chromium

- name: Run @craftcms/ui tests
run: npm run test:ui
22 changes: 11 additions & 11 deletions .github/workflows/storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ on:
branches:
- 6.x
paths:
- 'packages/craftcms-cp/**'
- 'packages/craftcms-ui/**'
- 'packages/craftcms-garnish/**'
- 'resources/js/**'
- 'src/**/*.php'
pull_request:
paths:
- 'packages/craftcms-cp/**'
- 'packages/craftcms-ui/**'
- 'packages/craftcms-garnish/**'
- 'resources/js/**'
- 'src/**/*.php'
Expand Down Expand Up @@ -59,7 +59,7 @@ jobs:
# Keep this in sync with .github/workflows/js-ci.yml so the built assets
# and generated files are shared between the two workflows.
run: |
echo "value=js-ci-v3-${{ runner.os }}-${{ hashFiles('package-lock.json', 'composer.lock', 'package.json', 'packages/*/package.json', 'packages/craftcms-cp/src/**', 'packages/craftcms-cp/tsconfig*.json', 'packages/craftcms-cp/vite.config.*', 'packages/craftcms-cp/tsdown.config.*', 'packages/craftcms-garnish/src/**', 'packages/craftcms-garnish/tsconfig*.json', 'packages/craftcms-garnish/tsdown.config.*', 'src/**/*.php', 'workbench/**/*.php') }}" >> "$GITHUB_OUTPUT"
echo "value=js-ci-v3-${{ runner.os }}-${{ hashFiles('package-lock.json', 'composer.lock', 'package.json', 'packages/*/package.json', 'packages/craftcms-ui/src/**', 'packages/craftcms-ui/tsconfig*.json', 'packages/craftcms-ui/vite.config.*', 'packages/craftcms-ui/tsdown.config.*', 'packages/craftcms-garnish/src/**', 'packages/craftcms-garnish/tsconfig*.json', 'packages/craftcms-garnish/tsdown.config.*', 'src/**/*.php', 'workbench/**/*.php') }}" >> "$GITHUB_OUTPUT"

- name: Restore install + build + generated cache
id: cache
Expand All @@ -68,7 +68,7 @@ jobs:
path: |
node_modules
packages/*/node_modules
packages/craftcms-cp/dist
packages/craftcms-ui/dist
packages/craftcms-garnish/dist
vendor
resources/js/actions
Expand All @@ -93,9 +93,9 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
run: npm run build:garnish

- name: Build @craftcms/cp
- name: Build @craftcms/ui
if: steps.cache.outputs.cache-hit != 'true'
run: npm run build:cp
run: npm run build:ui

- name: Generate TypeScript types
if: steps.cache.outputs.cache-hit != 'true'
Expand All @@ -115,7 +115,7 @@ jobs:
fi

deploy-cp:
name: 'Deploy / craftcms-cp'
name: 'Deploy / craftcms-ui'
runs-on: ubuntu-latest
timeout-minutes: 10
needs: build-assets
Expand All @@ -137,7 +137,7 @@ jobs:
path: |
node_modules
packages/*/node_modules
packages/craftcms-cp/dist
packages/craftcms-ui/dist
packages/craftcms-garnish/dist
vendor
resources/js/actions
Expand All @@ -147,15 +147,15 @@ jobs:
key: ${{ needs.build-assets.outputs.cache-key }}

- name: Build Storybook
run: npm run build:storybook --workspace=@craftcms/cp
run: npm run build:storybook --workspace=@craftcms/ui

- name: Deploy to Cloudflare Pages
id: deploy
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy packages/craftcms-cp/storybook-static --project-name=craftcms-ui-storybook --branch=${{ needs.build-assets.outputs.deploy-branch }}
command: pages deploy packages/craftcms-ui/storybook-static --project-name=craftcms-ui-storybook --branch=${{ needs.build-assets.outputs.deploy-branch }}

deploy-resources:
name: 'Deploy / resources'
Expand All @@ -180,7 +180,7 @@ jobs:
path: |
node_modules
packages/*/node_modules
packages/craftcms-cp/dist
packages/craftcms-ui/dist
packages/craftcms-garnish/dist
vendor
resources/js/actions
Expand Down
2 changes: 1 addition & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const config: StorybookConfig = {
viteFinal(config) {
// Storybook's vue3-vite framework adds its own Vue plugin with default options.
// We need to configure `isCustomElement` so Vue treats `craft-*` tags as web
// components (from @craftcms/cp) rather than trying to resolve them as Vue
// components (from @craftcms/ui) rather than trying to resolve them as Vue
// components. Since Vite's mergeConfig doesn't deep-merge plugin options,
// we remove Storybook's Vue plugin and add our own with the correct config.
const filteredPlugins = (config.plugins || []).flat().filter((plugin) => {
Expand Down
2 changes: 1 addition & 1 deletion .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {Preview} from '@storybook/vue3';
import {setup} from '@storybook/vue3';
import {withThemeByDataAttribute} from '@storybook/addon-themes';
import '@craftcms/cp';
import '@craftcms/ui';
import '../resources/css/cp.css';
import './preview.css';
import {installInertiaMock, setPageProps} from './inertia-mock';
Expand Down
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ npm run dev # Vite dev server (HMR) for the Inertia/Vue CP
npm run build # Production Vite build (cp.ts + legacy.ts + cp.css)
npm run build:all # Build legacy bundles + CP component package + Vite
npm run dev:bundles # Webpack dev watch for legacy jQuery bundles
npm run dev:cp # Dev build for the @craftcms/cp component package
npm run build:cp # Production build for the @craftcms/cp component package
npm run dev:ui # Dev build for the @craftcms/ui component package
npm run build:ui # Production build for the @craftcms/ui component package
npm run lint # ESLint + Stylelint + TypeScript type-check
npm run typecheck # TypeScript type-check only (vue-tsc)
npm run test:cp # Vitest tests for the @craftcms/cp package
npm run test:ui # Vitest tests for the @craftcms/ui package
```

> **Note:** `@craftcms/cp` must be built (`npm run build:cp`) before building or running the main Vite app if you've
> **Note:** `@craftcms/ui` must be built (`npm run build:ui`) before building or running the main Vite app if you've
> made changes to it.

## Testing
Expand Down Expand Up @@ -79,8 +79,8 @@ partially migrated; full migration means converting the inner form to a Vue comp

**Packages:**

- `packages/craftcms-cp` — the `@craftcms/cp` component library (Web Components built on Lit/WebAwesome). Imported as
`@craftcms/cp` in Vue pages. Has its own build (`npm run build:cp`) and Vitest tests (`npm run test:cp`).
- `packages/craftcms-ui` — the `@craftcms/ui` component library (Web Components built on Lit/WebAwesome). Imported as
`@craftcms/ui` in Vue pages. Has its own build (`npm run build:ui`) and Vitest tests (`npm run test:ui`).
- `packages/craftcms-legacy` — webpack-bundled jQuery modules used by legacy CP surfaces.

**TypeScript types** for PHP classes are auto-generated via `spatie/laravel-typescript-transformer` and written to
Expand Down
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ If you would like to work on a new core feature or improvement, first create a [

## Control Panel Front End

In order to work on the control panel front end, run `npm run dev`. On first run, this ensures the build artifacts the dev server depends on exist (building them if they don't), then starts the Vite development server together with the `@craftcms/cp` watcher, with output from each prefixed so you can tell them apart.
In order to work on the control panel front end, run `npm run dev`. On first run, this ensures the build artifacts the dev server depends on exist (building them if they don't), then starts the Vite development server together with the `@craftcms/ui` watcher, with output from each prefixed so you can tell them apart.

That covers most control panel work. If you also need to edit files under `packages/craftcms-legacy`, run `npm run dev:legacy` instead, which additionally starts the legacy webpack watcher.

Expand All @@ -86,15 +86,15 @@ npm run dev
npm run build
```

### `@craftcms/cp` package
### `@craftcms/ui` package

The control panel is largely backed by web components that live in the `@craftcms/cp` package within the `packages/craftcms-cp` directory. Like other packages, it has its own build process that can be run independently of the control panel.
The control panel is largely backed by web components that live in the `@craftcms/ui` package within the `packages/craftcms-ui` directory. Like other packages, it has its own build process that can be run independently of the control panel.
```shell
# Run the build in watch mode. Assets will be rebuilt on every change
npm run dev:cp
npm run dev:ui

# Run the build for production
npm run build:cp
npm run build:ui
```

In practice, you rarely work on one without the other, which is why `npm run dev` runs both together.
Expand Down
1 change: 1 addition & 0 deletions cms-assets/resources/icons/custom-icons/grip-dots.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/admin-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The `AdminTable` component renders data tables in the Craft CMS Control Panel. I
import {getCoreRowModel, useVueTable} from '@tanstack/vue-table';
import AdminTable from '@/components/AdminTable/AdminTable.vue';
import {createCraftColumnHelper} from '@/components/AdminTable/createCraftColumnHelper';
import {t} from '@craftcms/cp';
import {t} from '@craftcms/ui';
interface RowData {
id: number;
Expand Down
Loading
Loading