Files
Oleg Isonen d4b1994a6a fix: Improve editor selection and project tag contrast (#6302)
Closes #6301

## Summary

- Restore Dashboard project tags to the pre-color-refactor treatment:
fixed white text over a 30% black scrim in both application themes.
- Use one high-contrast text-selection treatment across native inputs,
textareas, contenteditable fields, and every shared CodeMirror editor.
- Preserve the existing subtle selection treatment for Navigator,
Project Settings, command menus, Dashboard navigation, and other
selected controls.
- Add direct Storybook coverage for the CSS fragment editor.
- Simplify chromatic color derivation from 571 to 329 lines without
changing computed colors.

## Technical choices

- Keep project tags independent from application-theme polarity because
they overlay arbitrary thumbnail artwork.
- Keep the existing `selectionBackground` control-state export unchanged
at its original 12% light / 20% dark accent blend.
- Define separate `--background-text-selection` and
`--foreground-on-text-selection` tokens exclusively for selected text.
- Use the bounded accent in light mode and a luminance-lifted accent in
dark mode so selected text remains distinct even with extreme custom
theme colors.
- Style CodeMirror through its existing selection layer and
`::selection` CSS hooks; no selection tracking or editor-state logic is
added.
- Leave canvas rich-text selection independent: authored canvas
documents do not load the Builder UI theme stylesheet.
- Replace five duplicated XYZ clamp formulas with the exact
upper-luminance cap they reduce to. The removed lower-bound and
white-mixing branches were unreachable because the minimum was fixed at
zero.

## Todo

- [x] Restore the original project-tag scrim and foreground in both
themes.
- [x] Inventory native, CodeMirror, and canvas rich-text selection
paths.
- [x] Unify native and shared CodeMirror text-selection colors.
- [x] Keep text selection independent from selected control and
navigation states.
- [x] Add the missing CSS fragment editor story.
- [x] Add light- and dark-mode browser regressions and confirm they fail
before the fix.
- [x] Enforce 4.5:1 selected-text contrast and 3:1 highlight-to-surface
contrast across supported theme inputs.
- [x] Remove duplicated and unreachable chromatic color derivation while
preserving outputs.
- [x] Review documentation impact; the design-system color-token
reference is updated, with no user-facing product documentation change
required.
- [x] Verify fixture impact; no fixture inputs or generated outputs are
affected.

## Verification

- `pnpm --filter @webstudio-is/design-system test` — 227 tests passed,
including the control/text separation regression, Navigator tree
interaction, default-palette comparisons, and the full supported-theme
contrast sweep
- `pnpm --filter @webstudio-is/design-system typecheck`
- `pnpm --filter @webstudio-is/builder exec vitest run
app/shared/code-editor-base.browser.test.tsx --project
app-browser-shared`
- `pnpm --filter @webstudio-is/builder exec vitest run
app/dashboard/projects/project-card.browser.test.tsx --project
app-browser-canvas-dashboard`
- `pnpm --filter @webstudio-is/builder typecheck`
- Targeted `oxlint`, formatting, and `git diff --check`
- Live dark-mode Dashboard verification of the restored subtle
navigation selection
- Storybook visual checks for the full color system and input/CodeMirror
selection in light and dark modes
2026-09-01 17:05:14 +02:00

93 lines
3.1 KiB
JSON

{
"name": "@webstudio-is/design-system",
"version": "0.0.0",
"description": "Webstudio Design System",
"author": "Webstudio <github@webstudio.is>",
"homepage": "https://webstudio.is",
"type": "module",
"scripts": {
"generate:color-types": "tsx src/colors/generate-color-types.ts",
"typecheck": "tsx src/colors/generate-color-types.ts --check && tsc --noEmit -p tsconfig.typecheck.json",
"test": "vitest run"
},
"devDependencies": {
"@types/react": "^18.2.70",
"@types/react-dom": "^18.2.25",
"@vitest/browser": "3.1.1",
"@webstudio-is/image": "workspace:*",
"@webstudio-is/tsconfig": "workspace:*",
"css-tree": "^3.2.1",
"playwright": "1.50.1",
"react": "18.3.0-canary-14898b6a9-20240318",
"react-dom": "18.3.0-canary-14898b6a9-20240318",
"vitest": "3.1.1",
"zod": "^4.4.3"
},
"peerDependencies": {
"react": "18.3.0-canary-14898b6a9-20240318",
"react-dom": "18.3.0-canary-14898b6a9-20240318"
},
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.7.4",
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.0",
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
"@floating-ui/dom": "^1.6.13",
"@fontsource-variable/inter": "^5.0.20",
"@fontsource-variable/manrope": "^5.0.20",
"@fontsource/roboto-mono": "^5.0.18",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/react-accessible-icon": "^1.1.4",
"@radix-ui/react-avatar": "^1.1.7",
"@radix-ui/react-checkbox": "^1.2.3",
"@radix-ui/react-collapsible": "^1.1.8",
"@radix-ui/react-context-menu": "^2.2.12",
"@radix-ui/react-dialog": "^1.1.11",
"@radix-ui/react-dropdown-menu": "^2.1.12",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-popover": "^1.1.11",
"@radix-ui/react-progress": "^1.1.4",
"@radix-ui/react-radio-group": "^1.3.4",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.2.2",
"@radix-ui/react-separator": "^1.1.4",
"@radix-ui/react-slot": "^1.2.0",
"@radix-ui/react-switch": "^1.2.2",
"@radix-ui/react-tabs": "^1.1.9",
"@radix-ui/react-toast": "^1.2.11",
"@radix-ui/react-toggle": "^1.1.6",
"@radix-ui/react-toggle-group": "^1.1.7",
"@radix-ui/react-toolbar": "^1.1.7",
"@radix-ui/react-tooltip": "^1.2.4",
"@radix-ui/react-use-controllable-state": "^1.2.2",
"@radix-ui/react-visually-hidden": "^1.2.0",
"@react-aria/focus": "^3.19.1",
"@react-aria/interactions": "^3.23.0",
"@react-aria/utils": "^3.27.0",
"@stitches/react": "1.3.1-1",
"@webstudio-is/css-data": "workspace:*",
"@webstudio-is/css-engine": "workspace:*",
"@webstudio-is/icons": "workspace:*",
"change-case": "^5.4.4",
"cmdk": "^1.1.1",
"downshift": "^6.1.7",
"hdr-color-input": "^0.4.0",
"match-sorter": "^8.0.0",
"react-colorful": "^5.6.1",
"react-hot-toast": "^2.5.1",
"type-fest": "^4.37.0",
"use-debounce": "^10.0.4",
"warn-once": "^0.1.1"
},
"exports": {
".": {
"webstudio": "./src/index.ts"
},
"./global.css": "./src/global.css"
},
"license": "AGPL-3.0-or-later",
"private": true,
"sideEffects": [
"**/*.css"
]
}