Skip to main content

ui4

Manually invoked skill for reskinning Payload UI components. Requires Figma URL. Usage: /ui4

Source facts

Repository
payloadcms/payload
Last source activity
September 22, 2026 at 17:53
Detected SKILL.md language
English
Stars
45,097
Forks
4,256

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
ui4
description
Manually invoked skill for reskinning Payload UI components. Requires Figma URL. Usage: /ui4
# Payload UI Reskin (ui4) **Figma URL is REQUIRED.** If not provided, ask before proceeding. --- ## Process ### Step 0: Icon Scan **Goal:** Identify icon dependencies before starting work. 1. **Scan component files** for icon imports: ``` grep -E "from.*icons|import.*Icon" packages/ui/src/elements/ComponentName/ ``` 2. **List existing icons** in `packages/ui/src/icons/`: - Each icon has its own folder with `index.tsx` + `index.css` 3. **Compare Figma design** to available icons: - Does the design use icons not currently in the component? - Does the design use icons that don't exist yet? 4. **Document findings:** - **Existing & used:** No action needed - **Existing but not imported:** Will need to add import - **Missing from codebase:** Flag for user — need to source/create icon **Figma Icons Source:** When updating or creating icons, reference the Figma icon library at: ``` ~/figma/figma/fpl/icons/src/icons/ ``` Icon naming convention: `icon-{size}-{name}.tsx` (e.g., `icon-16-close.tsx`, `icon-24-chevron-down.tsx`) To find the correct icon: 1. Note the icon name from Figma design (e.g., "close", "chevron-down") 2. Check both 16px and 24px variants if they exist 3. Read the corresponding files and extract the SVG paths for each size **Icon implementation rules:** 1. **Props:** Icon components MUST accept these props (keep existing props when updating): ```typescript type IconProps = { readonly className?: string readonly size?: 16 | 24 // Add more sizes as needed // ... keep any existing component-specific props } ``` 2. **Multi-size support:** Store path data keyed by size: ```typescript const paths = { 16: 'M4.854 4.146...', // from icon-16-{name}.tsx 24: 'M6.854 6.146...', // from icon-24-{name}.tsx } ``` 3. **SVG rendering:** Use the size prop to select path and viewBox: ```tsx <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} fill="none"> <path d={paths[size]} fill="currentColor" /> </svg> ``` 4. **Payload conventions:** - Use `fill="currentColor"` instead of `fill="var(--color-icon)"` - Use `fillRule` and `clipRule` (React camelCase) instead of kebab-case - Default size should match most common usage (typically 24) 5. **Reference implementation:** See `packages/ui/src/icons/Chevron/index.tsx` for the pattern. **If icons are missing from Figma source:** Ask user how to proceed before continuing. --- ### Step 1: SCSS → CSS Migration **Goal:** Syntax conversion only. Component must look IDENTICAL after. 1. Read component files: `packages/ui/src/elements/ComponentName/` or `packages/ui/src/fields/ComponentName/` 2. Create `index.css` with converted styles: - `$var` → `var(--token)` - Keep CSS nesting with `&` (preferred) - Remove `@use`/`@import` (tokens are global) - Inline any mixins 3. Update import: `import './index.scss'` → `import './index.css'` 4. Delete `index.scss` 5. Wrap in `@layer payload-default {}` 6. **Convert legacy `var(--base)` to `--spacer` tokens** (see below) 7. **Check for SCSS-only variables** (see below) --- #### SCSS Variable Dependencies **CRITICAL:** The `packages/ui/src/scss/` folder has been removed. All global tokens now live in `packages/ui/src/css/`. Any CSS variable you use must exist there. **Before using a variable, verify it exists in the CSS folder:** ```bash grep -r "variable-name" packages/ui/src/css/ ``` **If a variable is only in SCSS:** 1. Check if there's an equivalent in the CSS folder 2. If not, add it to the appropriate CSS file: - `spacing.css` — spacers, gutters, layout spacing, breakpoints - `colors.css` — color tokens - `typography.css` — font tokens - `radius.css` — border-radius tokens - `utilities.css` — accessibility, misc utilities **Common SCSS-only variables to watch for:** | SCSS Variable | CSS Equivalent / Action | | ----------------------- | ------------------------------------------------ | | `--spacing-view-bottom` | Defined in `spacing.css` | | `--breakpoint-m-width` | Defined in `spacing.css` (1024px) | | `--breakpoint-s-width` | Defined in `spacing.css` (768px) | | `--gutter-h` | Defined in `spacing.css` | | `$breakpoint-m-width` | Use `var(--breakpoint-m-width)` in media queries | | `@include mid-break` | Use `@media (max-width: 1024px)` | | `@include small-break` | Use `@media (max-width: 768px)` | --- #### Legacy Token Migration: `var(--base)` → `--spacer` **What is `--base`?** A legacy spacing token equal to `20px` (1.25rem). It must be replaced with `--spacer-*` tokens. **Spacer token values:** | Token | Value | Pixels | | -------------- | ----- | ------ | | `--spacer-0` | 0 | 0px | | `--spacer-1` | 4px | 4px | | `--spacer-2` | 8px | 8px | | `--spacer-2-5` | 12px | 12px | | `--spacer-3` | 16px | 16px | | `--spacer-4` | 24px | 24px | | `--spacer-5` | 32px | 32px | | `--spacer-6` | 40px | 40px | **Conversion strategy:** 1. **Direct match:** If the result equals a spacer token, use it directly: ```css /* Before: var(--base) = 20px → closest is --spacer-3 (16px) or --spacer-4 (24px) */ padding: var(--base); /* After: Choose semantically correct size */ padding: var(--spacer-4); /* if 24px is acceptable */ ``` 2. **Calculated values:** When exact pixel value is important, use `calc()`: ```css /* Before: calc(var(--base) * 0.5) = 10px */ gap: calc(var(--base) * 0.5); /* After: calc(var(--spacer-1) * 2.5) = 10px */ gap: calc(var(--spacer-1) * 2.5); ``` 3. **ALWAYS round to nearest spacer token.** Never use `calc()` to preserve non-standard pixel values. Round all calculated values to the nearest token: | Pixel Range | Token | Notes | | ----------- | --------------------- | ----------------------------- | | 0-2px | `--spacer-0` | Use 0 | | 3-6px | `--spacer-1` (4px) | 5-6px rounds to 4px | | 7-10px | `--spacer-2` (8px) | 10px rounds DOWN to 8px | | 11-14px | `--spacer-2-5` (12px) | 13.33px rounds to 12px | | 15-20px | `--spacer-3` (16px) | 15px, 20px both round to 16px | | 21-28px | `--spacer-4` (24px) | | | 29-36px | `--spacer-5` (32px) | 30px rounds to 32px | | 37-48px | `--spacer-6` (40px) | | 4. **Common `var(--base)` conversions** (base = 20px): | Original | Pixels | Rounded Token | | -------------------- | ------ | --------------------------------------------------------------- | | `var(--base) * 0.25` | 5px | `--spacer-1` (4px) | | `var(--base) * 0.3` | 6px | `--spacer-1` (4px) | | `var(--base) * 0.4` | 8px | `--spacer-2` | | `var(--base) * 0.5` | 10px | `--spacer-2` (8px) | | `var(--base) * 0.6` | 12px | `--spacer-2-5` | | `var(--base) / 1.5` | 13.3px | `--spacer-2-5` (12px) | | `var(--base) * 0.75` | 15px | `--spacer-3` (16px) | | `var(--base) * 0.8` | 16px | `--spacer-3` | | `var(--base)` | 20px | `--spacer-3` (16px) or `--spacer-4` (24px) | | `var(--base) * 1.2` | 24px | `--spacer-4` | | `var(--base) * 1.5` | 30px | `--spacer-5` (32px) | | `var(--base) * 2` | 40px | `--spacer-6` | | `var(--base) * 3` | 60px | `calc(var(--spacer-4) * 2.5)` — only use calc for values > 40px | **Rule:** For values ≤ 40px, ALWAYS use a single token. For values > 40px, use `calc()` with a spacer token. 5. **Check Figma design:** The best approach is to check the Figma design for the intended spacing value and use the matching `--spacer-*` token directly. --- **CRITICAL: SCSS nesting patterns that DON'T work in CSS:** **1. BEM element concatenation (`&__element`):** ```scss // SCSS - WORKS (produces .block__element) .block { &__element { color: red; } &__other { color: blue; } } ``` ```css /* CSS - DOES NOT WORK! &__element is invalid */ /* You must use flat selectors: */ .block { ... } .block__element { color: red; } .block__other { color: blue; } ``` **2. BEM modifier concatenation (`&--modifier`):** ```scss // SCSS - WORKS (produces .block--active) .block { &--active { background: blue; } } ``` ```css /* CSS - DOES NOT WORK! Use flat selector: */ .block { ... } .block--active { background: blue; } ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub