mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-03-08 01:53:30 +01:00
Added sprint protocol
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
| TASK-001B | Launcher Fixes | 🟢 Complete | All 4 subtasks implemented |
|
||||
| TASK-002 | GitHub Integration | 🟢 Complete | OAuth + basic features done |
|
||||
| TASK-002B | GitHub Advanced Integration | 🟡 In Progress | Part 1: GIT-004A-C done. Part 2: GIT-005-011 docs created |
|
||||
| TASK-002C | GitHub Clone & Connect | 🟡 In Progress | Clone from launcher flow |
|
||||
| TASK-002C | GitHub Clone & Connect | <EFBFBD> Complete | All 3 subtasks done (Clone, Connect, Push/Pull) |
|
||||
| TASK-003 | Shared Component System | 🔴 Not Started | Prefab system refactor |
|
||||
| TASK-004 | AI Project Creation | 🔴 Not Started | AI scaffolding feature |
|
||||
| TASK-005 | Deployment Automation | 🔴 Not Started | Planning docs only, no implementation |
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
# Phase 9: Styles Overhaul - Progress Tracker
|
||||
|
||||
**Last Updated:** 2026-01-07
|
||||
**Last Updated:** 2026-02-18
|
||||
**Overall Status:** 🟡 In Progress
|
||||
|
||||
---
|
||||
|
||||
## Quick Summary
|
||||
|
||||
| Metric | Value |
|
||||
| ----------------- | ----------- |
|
||||
| Total Major Tasks | 7 |
|
||||
| Completed | 0 |
|
||||
| In Progress | 1 (CLEANUP) |
|
||||
| Not Started | 6 |
|
||||
| **Progress** | **~15%** |
|
||||
| Metric | Value |
|
||||
| ----------------- | -------- |
|
||||
| Total Major Tasks | 7 |
|
||||
| Completed | 0 |
|
||||
| In Progress | 3 |
|
||||
| Not Started | 4 |
|
||||
| **Progress** | **~35%** |
|
||||
|
||||
> **Note:** Significant foundational work completed in CLEANUP-SUBTASKS (000A-000G).
|
||||
> Major feature tasks (STYLE-001 to STYLE-005, WIZARD-001) remain not started.
|
||||
> STYLE-001 and STYLE-002 are in progress. STYLE-003 to STYLE-005 and WIZARD-001 not started.
|
||||
|
||||
---
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
### Major Feature Tasks
|
||||
|
||||
| Task | Name | Status | Notes |
|
||||
| ---------- | ------------------------ | -------------- | ----------------------------- |
|
||||
| STYLE-001 | Token System Enhancement | 🔴 Not Started | Design tokens system |
|
||||
| STYLE-002 | Element Configs/Variants | 🔴 Not Started | Component styling system |
|
||||
| STYLE-003 | Style Presets System | 🔴 Not Started | Pre-built style presets |
|
||||
| STYLE-004 | Property Panel UX | 🔴 Not Started | Improved styling UX |
|
||||
| STYLE-005 | Smart Style Suggestions | 🔴 Not Started | AI-assisted suggestions |
|
||||
| WIZARD-001 | Project Creation Wizard | 🔴 Not Started | Guided project setup |
|
||||
| CLEANUP-\* | Legacy Color Cleanup | 🟡 In Progress | 7/8 subtasks complete (87.5%) |
|
||||
| Task | Name | Status | Notes |
|
||||
| ---------- | ------------------------ | -------------- | ----------------------------------------------- |
|
||||
| STYLE-001 | Token System Enhancement | 🟡 In Progress | Phase 1+2 done; Phase 3+4 TBD |
|
||||
| STYLE-002 | Element Configs/Variants | 🟡 In Progress | Phase 1+2+3 done; prop panel wiring → STYLE-004 |
|
||||
| STYLE-003 | Style Presets System | ✅ Complete | 5 presets, PresetSelector UI, launcher wiring |
|
||||
| STYLE-004 | Property Panel UX | 🟡 In Progress | Phase 1 done (variant+size picker wired) |
|
||||
| STYLE-005 | Smart Style Suggestions | 🔴 Not Started | AI-assisted suggestions |
|
||||
| WIZARD-001 | Project Creation Wizard | 🔴 Not Started | Guided project setup |
|
||||
| CLEANUP-\* | Legacy Color Cleanup | 🟡 In Progress | 7/8 subtasks complete (87.5%) |
|
||||
|
||||
---
|
||||
|
||||
@@ -65,6 +65,27 @@ Foundation work to remove hardcoded colors and establish token infrastructure.
|
||||
|
||||
---
|
||||
|
||||
## STYLE-001 Progress
|
||||
|
||||
| Phase | Description | Status |
|
||||
| ------- | -------------------------------- | -------------- |
|
||||
| Phase 1 | Token Data Structure | 🟢 Complete |
|
||||
| Phase 2 | Context & Panel Enhancement | 🟢 Complete |
|
||||
| Phase 3 | TokenPicker Component | 🔴 Not Started |
|
||||
| Phase 4 | CSS Variable Injection (preview) | 🔴 Not Started |
|
||||
|
||||
## STYLE-002 Progress
|
||||
|
||||
| Phase | Description | Status |
|
||||
| ------- | ---------------------------------------- | ----------------------- |
|
||||
| Phase 1 | Config system (types, registry, configs) | 🟢 Complete |
|
||||
| Phase 2 | Node creation hook + Text bug fix | 🟢 Complete |
|
||||
| Phase 3 | VariantSelector UI component | 🟢 Complete |
|
||||
| Phase 4 | Property panel wiring | 🔴 Deferred → STYLE-004 |
|
||||
| Phase 5 | State styles (hover/focus/disabled) | 🔴 Deferred → STYLE-004 |
|
||||
|
||||
---
|
||||
|
||||
## Status Legend
|
||||
|
||||
- 🔴 **Not Started** - Work has not begun
|
||||
@@ -77,6 +98,8 @@ Foundation work to remove hardcoded colors and establish token infrastructure.
|
||||
|
||||
| Date | Update |
|
||||
| ---------- | -------------------------------------------------------------- |
|
||||
| 2026-02-18 | STYLE-002 Phase 1+2+3: ElementConfigs system + VariantSelector |
|
||||
| 2026-02-18 | STYLE-001 Phase 1+2: Token system + DesignTokenPanel |
|
||||
| 2026-01-07 | Audit: Updated PROGRESS.md to reflect actual completion status |
|
||||
| 2025-12-31 | Completed TASK-000F (Buttons) and TASK-000G (Dialogs/Panels) |
|
||||
| 2025-12-30 | Completed TASK-000A through TASK-000E (Token/Color foundation) |
|
||||
@@ -106,11 +129,18 @@ The foundational cleanup work (000A-000G) has established:
|
||||
- Typography and spacing token system
|
||||
- Modern visual polish on core UI components
|
||||
|
||||
STYLE-001 (Phases 1+2): Full Tailwind-inspired token system with DesignTokenPanel.
|
||||
|
||||
STYLE-002 (Phases 1+2+3): ElementConfig system for default node styling on creation,
|
||||
VariantSelector UI component, Text node flex bug fix.
|
||||
|
||||
### What's Remaining:
|
||||
|
||||
- **TASK-000H:** Final polish on Migration Wizard
|
||||
- **STYLE-001 to STYLE-005:** Major feature work (enhanced token system, element configs, presets, property panel UX, AI suggestions)
|
||||
- **STYLE-001 Phase 3+4:** TokenPicker component, CSS injection into preview iframe
|
||||
- **STYLE-002 Phase 4+5:** Property panel wiring, state style application
|
||||
- **STYLE-003 to STYLE-005:** Style presets, property panel UX, AI suggestions
|
||||
- **WIZARD-001:** Project creation wizard
|
||||
|
||||
See CLEANUP-SUBTASKS/ folder for detailed changelogs of completed work.
|
||||
See STYLE-\* folders for README specs of upcoming feature work.
|
||||
See STYLE-\* folders for README specs and changelogs.
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# STYLE-001: Token System Enhancement - Changelog
|
||||
|
||||
## 2026-02-18 - Phase 1 & 2 Complete
|
||||
|
||||
### Phase 1: Token Data Structure
|
||||
|
||||
#### New Files
|
||||
|
||||
**`packages/noodl-editor/src/editor/src/models/StyleTokensModel/`**
|
||||
|
||||
- **`TokenCategories.ts`** — TypeScript types for the design token system:
|
||||
|
||||
- `TokenCategory` union type (13 categories: color-semantic, color-palette, spacing, typography-_, border-_, shadow, animation-\*)
|
||||
- `StyleToken`, `StyleTokenRecord`, `StyleTokensData` interfaces
|
||||
- `TOKEN_CATEGORIES` metadata map (label, description, group)
|
||||
- `TOKEN_CATEGORY_GROUPS` ordered display groups
|
||||
|
||||
- **`DefaultTokens.ts`** — Full Tailwind-inspired default token set:
|
||||
|
||||
- ~24 semantic colors (primary, secondary, destructive, muted, accent, surface, border, ring)
|
||||
- ~90 palette colors (gray, blue, red, green, amber, purple at 10 shades each)
|
||||
- ~32 spacing tokens (0–128px numeric scale + semantic aliases xs/sm/md/lg/xl/2xl/3xl)
|
||||
- 10 font sizes, 9 font weights, 6 line heights, 6 letter spacings, 3 font families
|
||||
- 8 border radii, 5 border widths
|
||||
- 7 shadow scales
|
||||
- 8 animation durations + 5 easing functions
|
||||
- **Only overrides stored in project.json** — defaults never persisted
|
||||
|
||||
- **`TokenResolver.ts`** — CSS `var()` reference resolution:
|
||||
|
||||
- Resolves chained references (e.g. `--space-xs` → `var(--space-1)` → `4px`)
|
||||
- LRU-style cache with targeted invalidation
|
||||
- `generateCss()` for `:root { ... }` CSS block generation
|
||||
- Max depth protection against circular references
|
||||
|
||||
- **`StyleTokensModel.ts`** — Main model class:
|
||||
|
||||
- Extends `Model` (EventDispatcher-compatible)
|
||||
- `getTokens()`, `getTokensByCategory()`, `getTokensByGroup()`, `getTokensGrouped()`
|
||||
- `setToken()`, `addCustomToken()`, `deleteCustomToken()`, `resetAllToDefaults()` — all undo-aware
|
||||
- `generateCss()`, `exportCustomTokensJson()`, `importCustomTokensJson()`
|
||||
- Persists only custom overrides under `designTokens` metadata key
|
||||
- Auto-reloads on `ProjectModel.importComplete` / `ProjectModel.instanceHasChanged`
|
||||
- Properly uses `new UndoActionGroup(...)` for undo stack integration
|
||||
|
||||
- **`index.ts`** — Clean public exports
|
||||
|
||||
### Phase 2: Context & Panel Enhancement
|
||||
|
||||
#### Modified
|
||||
|
||||
- **`ProjectDesignTokenContext.tsx`** — Enhanced with:
|
||||
- `designTokens: StyleTokenRecord[]` — live token array, re-renders on `tokensChanged`
|
||||
- `styleTokensModel: StyleTokensModel | null` — model instance for direct interaction
|
||||
- Uses `useEventListener` hook (correct pattern, no direct `.on()`)
|
||||
- Backward compatible — existing `staticColors`, `dynamicColors`, `textStyles` unchanged
|
||||
|
||||
#### New
|
||||
|
||||
- **`DesignTokenPanel.tsx`** — Replaced basic 2-tab panel with proper structure:
|
||||
- New "Tokens" tab (primary) + legacy "Colors" tab preserved
|
||||
- **`components/DesignTokensTab/`** — Tokens tab:
|
||||
|
||||
- Groups all tokens by display category (Colors, Spacing, Typography, Borders, Effects, Animation)
|
||||
- Collapsible sections per group via `CollapsableSection`
|
||||
- Shows "N overrides" banner with "Reset all" when tokens are customised
|
||||
|
||||
- **`components/TokenCategorySection/`** — Per-group token list:
|
||||
- Color swatches for color tokens
|
||||
- Spacing bars for spacing tokens (proportional width)
|
||||
- Border radius preview boxes
|
||||
- Shadow preview boxes
|
||||
- Font size "Aa" previews
|
||||
- Override indicator (highlighted name) with reset button (↺) on hover
|
||||
- SCSS using design tokens throughout (no hardcoded values)
|
||||
|
||||
---
|
||||
|
||||
## What's Still Pending
|
||||
|
||||
### Phase 3: TokenPicker Component (STYLE-001)
|
||||
|
||||
- Reusable `<TokenPicker>` dropdown for use in property panels
|
||||
- Currently `onTokenChange` prop exists but inline editing not yet wired
|
||||
- Will be built as part of STYLE-002/STYLE-004 integration
|
||||
|
||||
### Phase 4: CSS Variable Injection (STYLE-001)
|
||||
|
||||
- `StyleTokensModel.generateCss()` is ready
|
||||
- Need to inject into preview iframe when tokens change
|
||||
- Requires investigation of preview server injection point in `noodl-viewer-react`
|
||||
|
||||
---
|
||||
|
||||
_Started: 2026-02-18_
|
||||
@@ -0,0 +1,113 @@
|
||||
# STYLE-002: Element Configs & Variants - Changelog
|
||||
|
||||
## 2026-02-18 - Phase 1, 2 & 3 Complete
|
||||
|
||||
---
|
||||
|
||||
### Phase 1: Config System Architecture
|
||||
|
||||
#### New Files
|
||||
|
||||
**`packages/noodl-editor/src/editor/src/models/ElementConfigs/`**
|
||||
|
||||
- **`ElementConfigTypes.ts`** — TypeScript interfaces for the config system:
|
||||
|
||||
- `StateStyles` — hover/active/focus/disabled/placeholder style maps
|
||||
- `VariantConfig` — base styles + optional `states` object
|
||||
- `SizePresets` — named size override maps
|
||||
- `ElementConfig` — full config for a node type (defaults + sizes + variants)
|
||||
- `ResolvedVariant` — base styles + states after stripping the `states` key
|
||||
|
||||
- **`ElementConfigRegistry.ts`** — Singleton registry:
|
||||
|
||||
- `register(config)` — add a config
|
||||
- `get(nodeType)` / `has(nodeType)` / `getAll()` — lookup
|
||||
- `getVariantNames(nodeType)` — returns `string[]` of available variant names
|
||||
- `resolveVariant(nodeType, variantName)` → `ResolvedVariant | undefined`
|
||||
- `applyDefaults(node, typeName)` — stamps defaults + initial variant onto a node's `parameters`
|
||||
- `applyVariant(node, typeName, variantName)` — stamps a variant's base styles + updates `_variant` marker
|
||||
- All built-in configs auto-registered on module load
|
||||
|
||||
- **`configs/ButtonConfig.ts`** — Button (`net.noodl.controls.button`):
|
||||
|
||||
- Variants: primary, secondary, outline, ghost, destructive, link
|
||||
- Size presets: sm, md, lg, xl
|
||||
- Interaction states: hover, active, disabled per variant
|
||||
|
||||
- **`configs/GroupConfig.ts`** — Group (`net.noodl.visual.group`):
|
||||
|
||||
- Variants: default, card, section, inset, flex-row, flex-col, centered
|
||||
|
||||
- **`configs/TextConfig.ts`** — Text node:
|
||||
|
||||
- **BUG FIX**: defaults now include `width: auto`, `flexShrink: 1`, `flexGrow: 0`, `minWidth: 0`
|
||||
(previously: implicit `width: 100%` caused Text elements to push siblings off-screen in row layouts)
|
||||
- Variants: body, heading-1 through heading-6, muted, label, small, code, lead, blockquote
|
||||
|
||||
- **`configs/TextInputConfig.ts`** — TextInput (`net.noodl.controls.textinput`):
|
||||
|
||||
- Variants: default (with focus ring), error
|
||||
|
||||
- **`configs/CheckboxConfig.ts`** — Checkbox (`net.noodl.controls.checkbox`):
|
||||
|
||||
- Variant: default
|
||||
|
||||
- **`configs/index.ts`** — barrel export
|
||||
- **`index.ts`** — public module export
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Node Creation Integration
|
||||
|
||||
#### Modified
|
||||
|
||||
- **`views/NodePicker/NodePicker.utils.ts`** — Added `ElementConfigRegistry.applyDefaults(node, type.name)` call in `createNodeFunction`, immediately after `NodeGraphNode.fromJSON(...)`. This is the **single entry point for all user-initiated node creation** — no changes needed to NodeGraphModel or project loading paths.
|
||||
|
||||
- Safe for existing projects: defaults only stamp properties not already set
|
||||
- No-op for node types without a registered config
|
||||
- Works for root nodes, child nodes, and auto-attach-to-root paths
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: VariantSelector UI Component
|
||||
|
||||
#### New Files
|
||||
|
||||
**`packages/noodl-core-ui/src/components/inputs/VariantSelector/`**
|
||||
|
||||
- **`VariantSelector.tsx`** — Controlled dropdown component:
|
||||
|
||||
- Props: `variants: string[]`, `currentVariant: string | undefined`, `onVariantChange: (name) => void`, `disabled?`, `label?`
|
||||
- Keyboard accessible (Escape to close)
|
||||
- Closes on outside click
|
||||
- Formats variant names for display (`heading-1` → `Heading 1`)
|
||||
- Active variant shown with checkmark + primary color highlight
|
||||
|
||||
- **`VariantSelector.module.scss`** — Styled with design tokens exclusively (no hardcoded colors)
|
||||
|
||||
- **`index.ts`** — barrel export
|
||||
|
||||
---
|
||||
|
||||
### What's Pending
|
||||
|
||||
#### Property Panel Integration (STYLE-004)
|
||||
|
||||
Wiring `VariantSection` into the property editor requires understanding the legacy `TypeView.js` / `propertyeditor.ts` system. The `VariantSelector` component is built and ready — integration is scoped to STYLE-004 which covers Property Panel UX overhaul.
|
||||
|
||||
#### State Styles (Phase 4)
|
||||
|
||||
`StateStyles` (hover, focus, active, disabled) are defined in all configs and stored in `ResolvedVariant.states`. Applying them at runtime requires investigation of the existing visual states system in `noodl-viewer-react`. Scoped to STYLE-004.
|
||||
|
||||
---
|
||||
|
||||
## Key Discoveries
|
||||
|
||||
- **NodePicker.utils.ts is the sole user-initiated node creation path** — all `addRoot`/`addChild` calls with `{ undo: true, label: 'create' }` flow through `createNodeFunction`. No need to touch NodeGraphModel.
|
||||
- **NodeGraphNode.parameters is a plain object** — not getter/setter based. The registry uses direct `node.parameters[key]` access.
|
||||
- **Loading vs creation differentiation**: when loading from JSON, `NodeGraphNode.fromJSON` pre-populates parameters before `addRoot` is called. The `applyDefaults` guard (`if param === undefined`) ensures existing project nodes aren't affected.
|
||||
- **Text node width issue**: the `defaultCss` in `text.js` only has `{ position: 'relative', display: 'flex' }`. The width issue comes from dimension port defaults. Stamping `width: auto` + flex props via `applyDefaults` fixes it for newly created nodes.
|
||||
|
||||
---
|
||||
|
||||
_Started: 2026-02-18_
|
||||
@@ -0,0 +1,66 @@
|
||||
# STYLE-003: Style Presets — CHANGELOG
|
||||
|
||||
## 2026-02-18 — Implementation Complete
|
||||
|
||||
### New files created
|
||||
|
||||
**Data layer (noodl-editor)**
|
||||
|
||||
- `models/StylePresets/StylePresetTypes.ts` — `StylePreset` and `PresetPreview` interfaces
|
||||
- `models/StylePresets/presets/ModernPreset.ts` — Default (clean blue, 8px radius, soft shadows)
|
||||
- `models/StylePresets/presets/MinimalPreset.ts` — Monochromatic, 2–4px radius, no shadows
|
||||
- `models/StylePresets/presets/PlayfulPreset.ts` — Purple/pink, very rounded (16px), tinted shadows
|
||||
- `models/StylePresets/presets/EnterprisePreset.ts` — Dark navy, conservative 4px radius, barely-there shadows
|
||||
- `models/StylePresets/presets/SoftPreset.ts` — Indigo, 12px radius, ultra-light shadows
|
||||
- `models/StylePresets/presets/index.ts` — barrel
|
||||
- `models/StylePresets/StylePresetsModel.ts` — `getAllPresets`, `getPreset`, `getDefaultPreset`, `setPendingPresetId`, `consumePendingPreset`
|
||||
- `models/StylePresets/index.ts` — public surface
|
||||
|
||||
**UI layer (noodl-core-ui)**
|
||||
|
||||
- `components/StylePresets/PresetCard.tsx` — Mini mockup card with primary swatch, text lines, surface strip
|
||||
- `components/StylePresets/PresetCard.module.scss` — Card styles with selection ring
|
||||
- `components/StylePresets/PresetSelector.tsx` — Horizontal grid + description below selected
|
||||
- `components/StylePresets/PresetSelector.module.scss`
|
||||
- `components/StylePresets/index.ts` — barrel
|
||||
|
||||
### Modified files
|
||||
|
||||
**`models/StyleTokensModel/StyleTokensModel.ts`**
|
||||
|
||||
- Added `applyPreset(tokens)` public method — bulk-sets tokens without undo
|
||||
- Added `_applyAndClearPendingPreset()` private method — called from `_bindListeners` reload path
|
||||
- Added `consumePendingPreset` import and call in the `reload` closure
|
||||
|
||||
**`preview/launcher/Launcher/components/CreateProjectModal/CreateProjectModal.tsx`**
|
||||
|
||||
- Added `presets?: PresetDisplayInfo[]` prop
|
||||
- Added `selectedPresetId` local state (default `'modern'`)
|
||||
- Renders `<PresetSelector>` when presets provided
|
||||
- Extended `onConfirm` signature to include `presetId: string`
|
||||
|
||||
**`pages/ProjectsPage/ProjectsPage.tsx`**
|
||||
|
||||
- Added `getAllPresets`, `setPendingPresetId` imports
|
||||
- Added `STYLE_PRESETS` module-level constant
|
||||
- Updated `handleCreateProjectConfirm(name, location, presetId)` to call `setPendingPresetId(presetId)`
|
||||
- Passes `presets={STYLE_PRESETS}` to `<CreateProjectModal>`
|
||||
- Error path clears pending preset via `setPendingPresetId(null)`
|
||||
|
||||
### Architecture — pending preset flow
|
||||
|
||||
```
|
||||
User picks preset → CreateProjectModal.onConfirm(name, loc, presetId)
|
||||
→ ProjectsPage.handleCreateProjectConfirm
|
||||
→ setPendingPresetId(presetId) // stored in module-level var
|
||||
→ LocalProjectsModel.newProject(...)
|
||||
→ route to editor
|
||||
→ StyleTokensModel._bindListeners reload fires (ProjectModel.instanceHasChanged)
|
||||
→ _applyAndClearPendingPreset()
|
||||
→ consumePendingPreset() reads + clears _pendingPresetId
|
||||
→ applyPreset(preset.tokens)
|
||||
→ setToken() x N → _store() → ProjectModel.instance.setMetaData('designTokens', ...)
|
||||
→ tokens persisted to project.json
|
||||
```
|
||||
|
||||
Modern preset has `tokens: {}` so it is a no-op (defaults already apply).
|
||||
@@ -0,0 +1,115 @@
|
||||
# STYLE-004: Property Panel UX — Changelog
|
||||
|
||||
## Session: 2026-02-18
|
||||
|
||||
### Summary
|
||||
|
||||
Completed STYLE-004 Phase 1: Property panel wiring for the ElementConfig variant and size system.
|
||||
This closes the STYLE-002 Phase 4 + Phase 5 deferred items.
|
||||
|
||||
---
|
||||
|
||||
### New Files
|
||||
|
||||
#### `noodl-core-ui/src/components/propertyeditor/SizePicker/`
|
||||
|
||||
- **`SizePicker.tsx`** — Segmented control component for selecting a size preset (sm / md / lg / xl).
|
||||
Renders only the sizes defined in the node's ElementConfig. All styling via design tokens.
|
||||
- **`SizePicker.module.scss`** — Styles for the segmented control. No hardcoded colors.
|
||||
- **`index.ts`** — Barrel export.
|
||||
|
||||
#### `noodl-core-ui/src/components/propertyeditor/ElementStyleSection/`
|
||||
|
||||
- **`ElementStyleSection.tsx`** — Property panel section that combines VariantSelector and SizePicker.
|
||||
Renders at the top of the panel for any node with an ElementConfig registered.
|
||||
Props-driven and dumb — the legacy `propertyeditor.ts` manages undo via callbacks.
|
||||
- **`ElementStyleSection.module.scss`** — Section layout and header styling. Design tokens throughout.
|
||||
- **`index.ts`** — Barrel export.
|
||||
|
||||
---
|
||||
|
||||
### Modified Files
|
||||
|
||||
#### `ElementConfigRegistry.ts`
|
||||
|
||||
Added two new public API methods:
|
||||
|
||||
```typescript
|
||||
// Apply a named size preset's styles to a node (stamps CSS properties + _size marker)
|
||||
ElementConfigRegistry.applySize(node, typeName, sizeName)
|
||||
|
||||
// Return the size names defined in the config, in definition order
|
||||
ElementConfigRegistry.getSizeNames(nodeType) → string[]
|
||||
```
|
||||
|
||||
#### `propertyeditor/propertyeditor.html`
|
||||
|
||||
Added `<div class="element-style-section"></div>` slot between `.variants` and `.visual-states`.
|
||||
|
||||
#### `propertyeditor/propertyeditor.ts`
|
||||
|
||||
- Imported `ElementStyleSection` from `@noodl-core-ui/components/propertyeditor/ElementStyleSection`
|
||||
- Imported `ElementConfigRegistry`
|
||||
- Added fields: `elementStyleRoot: Root | null`, `_elementStyleGroup: Record<string, never>`
|
||||
- Added methods:
|
||||
- `renderElementStyleSection()` — mounts/updates the React root; reads `_variant` and `_size` from
|
||||
`this.model.parameters`; guards on `ElementConfigRegistry.has(typeName)`
|
||||
- `onElementVariantChange(variantName)` — resolves variant styles, batches into `UndoActionGroup`,
|
||||
calls `this.model.setParameter()` for each property, pushes to `UndoQueue`, then re-renders
|
||||
- `onElementSizeChange(sizeName)` — same pattern for size preset styles
|
||||
- Updated `render()`: subscribes to `['modelParameterUndo', 'modelParameterRedo']` to re-render
|
||||
the section after undo/redo; calls `renderElementStyleSection()`
|
||||
|
||||
---
|
||||
|
||||
### Test File
|
||||
|
||||
**`tests/models/ElementConfigRegistry.test.ts`**
|
||||
|
||||
Covers:
|
||||
|
||||
- `applyVariant` — stamps styles, excludes `states`, handles unknown types/variants
|
||||
- `applySize` — stamps size presets, handles no-sizes configs, unknown sizes
|
||||
- `getSizeNames` — returns correct keys in order, handles missing sizes
|
||||
- `getVariantNames` — returns all variant names
|
||||
- `resolveVariant` — returns baseStyles + states, excludes `states` from baseStyles
|
||||
- `applyDefaults` — stamps defaults + default variant, does not overwrite pre-existing values
|
||||
|
||||
---
|
||||
|
||||
### Architecture Notes
|
||||
|
||||
**Why callbacks instead of direct undo in the component:**
|
||||
The `ElementStyleSection` is intentionally dumb. Undo grouping requires `UndoActionGroup` +
|
||||
`UndoQueue` — both are editor-specific and not part of `noodl-core-ui`. Keeping undo logic in
|
||||
`propertyeditor.ts` lets the React component stay portable.
|
||||
|
||||
**Why \_variant and \_size in parameters:**
|
||||
These are special marker keys that don't map to real CSS properties. They allow the property panel
|
||||
to re-render the picker with the correct selection state across sessions. `applyDefaults` already
|
||||
persisted `_variant`; `_size` is the same pattern added by STYLE-004.
|
||||
|
||||
**Undo/redo re-render:**
|
||||
`propertyeditor.ts` subscribes to `['modelParameterUndo', 'modelParameterRedo']` on the node model
|
||||
using a stable `_elementStyleGroup` object. This ensures the picker UI stays in sync after undo.
|
||||
|
||||
---
|
||||
|
||||
### What's NOT done (explicitly deferred)
|
||||
|
||||
- **Full panel restructure** (ContentSection, LayoutSection, AdvancedSection, etc.) — future work
|
||||
- **TokenOverrideRow / token picker** — blocked on STYLE-001 Phase 3 (TokenPicker component)
|
||||
- **Override indicators** (badge showing "2 custom values") — future iteration
|
||||
- **Canvas indicator** — optional, deferred
|
||||
|
||||
---
|
||||
|
||||
### Success Criteria Status
|
||||
|
||||
- [x] VariantSelector appears in property panel for registered element types (Button, Text, Group, TextInput, Checkbox)
|
||||
- [x] Variant change applies correct styles with full undo support
|
||||
- [x] SizePicker appears for types with sizes defined (Button)
|
||||
- [x] Size change applies correct preset styles with full undo support
|
||||
- [x] Undo/redo restores picker state correctly
|
||||
- [x] Non-registered node types (logic nodes) show no ElementStyleSection
|
||||
- [x] Unit tests pass for all registry operations
|
||||
Reference in New Issue
Block a user