Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6c52a9f
test: add resolved-css baseline characterization test
kevinchappell Sep 24, 2026
fe06eb5
feat: declare formeo color custom properties with current defaults
kevinchappell Sep 24, 2026
fdce0e5
refactor: consume color custom properties in component styles
kevinchappell Sep 24, 2026
0bdfe1b
chore: exclude css baseline fixture from biome
kevinchappell Sep 24, 2026
8ee536e
fix: let icons inherit the formeo icon color
kevinchappell Sep 24, 2026
75ff323
feat: expose theme colors as CSS custom properties
kevinchappell Sep 24, 2026
36e07be
feat: set container text color in the .formeo-dark preset
kevinchappell Sep 24, 2026
ecd0626
fix: let the plus and minus icons follow the icon color
kevinchappell Sep 24, 2026
b04cf08
feat: theme formeo dialogs and raise dark preset contrast
kevinchappell Sep 24, 2026
63677a8
test: make the property resolver reject impure property blocks
kevinchappell Sep 24, 2026
6541b70
test: harden the color literal guard and run it in npm test
kevinchappell Sep 24, 2026
d3c6324
chore: give the demo page a dark theme under formeo-dark
kevinchappell Sep 24, 2026
5493920
docs: rewrite the theming section of the readme
kevinchappell Sep 24, 2026
5e611a2
test: count property blocks nested in at-rules
kevinchappell Sep 24, 2026
4b352e4
fix: scope the dialog surface rule to the dark preset
kevinchappell Sep 24, 2026
68588aa
style: use bg token for editing field background
kevinchappell Sep 24, 2026
362cce0
fix: give the editing field its surface background at zero specificity
kevinchappell Sep 24, 2026
084e1bd
chore: npm audit fix
kevinchappell Sep 24, 2026
51e300a
fix: derive edit pulse midpoint from runtime focus color
Copilot Sep 24, 2026
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
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ A highly configurable drag & drop form building module for creating dynamic, res
- [Installation](#installation)
- [Usage](#usage)
- [Framework Integration](#framework-integration)
- [Theming](#theming)
- [Documentation](#documentation)
- [Development](#development)
- [Contributing](#contributing)
Expand Down Expand Up @@ -161,6 +162,37 @@ Formeo can be integrated with popular frontend frameworks:
- **[React Integration Guide](https://github.com/Draggable/formeo/blob/main/docs/react-integration.md)** - Custom hooks, functional components, and Context API patterns
- **[Angular Integration Guide](https://github.com/Draggable/formeo/blob/main/docs/angular-integration.md)** - Services, components, and standalone patterns

## Theming

Every color formeo uses is a `--formeo-*` CSS custom property, declared on `:root` with zero specificity. Override them on `:root` or `<body>`: formeo appends its dialogs to `document.body`, so a rule scoped to the editor's container misses them. A narrower selector works too if it also covers `.formeo-dialog` and, when you move the controls panel with `controls.container`, `.formeo-controls`. For example, to map your own dark theme:

```css
:root {
color-scheme: dark;
color: #fafafa;
--formeo-bg: #0a0a0a;
--formeo-bg-hover: #1a1a1a;
--formeo-text: #fafafa;
--formeo-border: #262626;
--formeo-icon: #e5e5e5;
}
```

- **Dark preset:** add the `formeo-dark` class to `<body>` (or `:root`). It sets `color-scheme: dark` on that subtree, so your own native controls inside it darken too. Dialogs take the preset's background and text colors as well.
- **Your own dark theme:** set `color-scheme: dark` as well, and make sure your mapping's scope includes `.formeo-dialog`. Outside the preset, formeo leaves the dialog's own background and text color, the text color of inputs and selects, and the checkboxes to the browser, which only switches them to dark-mode colors under a dark `color-scheme`.
- **Text color:** outside the dark preset, the editor and controls containers inherit the page's `color`. Setting `--formeo-text` alone only recolors text formeo colors explicitly, not inherited labels, so set `color` on your container too.
- **Derived properties:** some defaults are computed from another color at build time and don't follow when you override that color. If you change the base, override these too: `--formeo-bg-hover`, `--formeo-overlay`, `--formeo-danger-subtle`, `--formeo-column-outline-soft`, and the `--formeo-*-highlight` / `--formeo-*-highlight-text` properties.

The full list, with defaults, is in [`_properties.scss`](https://github.com/Draggable/formeo/blob/main/src/lib/sass/base/_properties.scss). It isn't included in the npm package. The groups, without the `--formeo-` prefix, are:

- **Surfaces:** `bg`, `bg-hover`, `surface-muted`, `stage-bg`, `stage-shadow`, `overlay`
- **Text and icons:** `text`, `text-strong`, `text-secondary`, `text-muted`, `text-subtle`, `on-accent`, `icon`
- **Borders and focus:** `border`, `border-strong`, `focus`
- **Accents:** `primary`, `success`, `warning` and `danger` (each with a `-dark` variant), `danger-subtle`, `info`, `remove-bg`
- **Component outlines:** `{stage,row,column,field,option}-outline`, `-outline-text`, `-highlight` and `-highlight-text`, plus `column-outline-soft`

**Visual changes from 5.1.3:** icons that hard-coded `#444` (header, paragraph and the triangles) now use `--formeo-icon`, which defaults to `#000`. The column resize-handle triangles now use the column outline color (`--formeo-column-outline-soft`, or the darker `--formeo-column-outline` on hover) instead of `#444`.

## Documentation

Comprehensive documentation is available in the [docs](https://github.com/Draggable/formeo/blob/main/docs/README.md) directory:
Expand Down
3 changes: 2 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"!**/dist",
"!**/test-results",
"!**/playwright-report",
"!**/src/demo/index.html"
"!**/src/demo/index.html",
"!**/src/lib/sass/__fixtures__"
]
},
"assist": { "actions": { "source": { "organizeImports": "on" } } },
Expand Down
78 changes: 39 additions & 39 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"postbuild:demo": "node --no-warnings tools/copy-assets.mjs",
"build:demo:watch": "vite build --mode demo --watch",
"build:icons": "node ./tools/generate-sprite",
"lint": "biome check ./src",
"lint": "biome check ./src && node tools/check-color-literals.mjs",
"lint:fix": "biome check --write ./src",
"format": "biome format --write .",
"test": "node --loader=./tools/svg-loader.mjs --import=./tools/__mocks__/sprite-init.mjs --experimental-test-snapshots --require ./tools/test-setup.cjs --test --no-warnings src/**/*.test.{js,mjs}",
Expand Down
1 change: 1 addition & 0 deletions src/demo/js/actionButtons.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const editorActions = (editor, renderer) => {
editData: () => {
jsonEditor.setValue(JSON.stringify(editor.formData, null, 2), 1)
},
toggleDark: () => document.body.classList.toggle('formeo-dark'),
}
}

Expand Down
32 changes: 32 additions & 0 deletions src/demo/sass/demo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,35 @@ body {
}
}
}

// "Toggle Dark" puts .formeo-dark on <body>, so the demo page itself goes dark too.
body.formeo-dark {
background: linear-gradient(135deg, #18181b 0%, #1e293b 100%);
background-attachment: fixed;
color: var(--formeo-text);

#demo-header,
#demo-header nav,
#demo-footer nav {
background-color: var(--formeo-bg);
}

#demo-header {
border-bottom: 1px solid var(--formeo-border);
}

#demo-footer nav {
border-top: 1px solid var(--formeo-border);
}

#formeo-logo,
#demo-footer img {
filter: invert(1);
}

#formData-popover[popover] {
background-color: var(--formeo-bg);
border-color: var(--formeo-border);
color: var(--formeo-text);
}
}
2 changes: 1 addition & 1 deletion src/lib/icons/formeo-sprite.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 src/lib/icons/icon-email.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 src/lib/icons/icon-hash.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 src/lib/icons/icon-header.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 src/lib/icons/icon-minus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading