Skip to content

feat: sizes tokens editor and ds-service size token operations - #128

Merged
vkaltyrin merged 30 commits into
devfrom
feat/sizes-tokens-editor
Oct 28, 2026
Merged

vkaltyrin merged 30 commits into
devfrom
feat/sizes-tokens-editor

Conversation

@vkaltyrin

@vkaltyrin vkaltyrin commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Что это

OpenSpec change add-sizes-tokens-editor и его реализация.

Радиусы, отступы и тени темы переводятся на прототип SDDS Portal и на предметные операции ds-service, как «Палитра», «Цвета» и «Типографика» (#121). Прежний экран «Формы» убирается.

ds-service

  • GET /api/ds/tenants/{tenantId}/size-tokens отдаёт радиусы, отступы и тени в px с versionId. У каждого токена:
    • свои значения платформ;
    • использование компонентами и вычисляемые радиусы — по редакциям конфигураций на той же границе.
  • PUT …/size-tokens/{tokenId}/value, POST …/size-tokens и DELETE …/size-tokens/{tokenId} работают на предметных редакциях feat(ds): версии, журнал изменений и версионная палитра #109:
    • базовые редакции значений, X-DS-Mutation-Metadata;
    • Idempotency-Key на создании, логическое удаление, 400 historical_version_read_only.
  • Своей миграции нет. Признак своего значения платформы — колонка token_value_revisions.overridden из feat(ds): градиент как вид значения цветового токена #122 (V15__color_token_value_kind.sql).
  • Цвет слоя тени — HEX или ссылка на ступень палитры [type.shade.step][opacity].
    • Ссылка проверяется по палитре темы, хранится как у стопов градиента.
    • При чтении раскрывается в HEX: color и colorRef в size-tokens, sourceValue в token-values — через общую публикацию значений TokenValuePublisher из feat(ds): градиент как вид значения цветового токена #122.
    • Связи и удаление растяжки и проверка отката учитывают слои теней.
  • Журнал и откат для shape, spacing и shadow покрыты общими обработчиками feat(ds): версии, журнал изменений и версионная палитра #109.

Клиент

  • Модуль modules/sizeTokens и экран pages/shapes по экрану «Отступы и радиусы» прототипа:
    • дерево «Радиусы / Отступы / Тени»;
    • борд радиусов с группой «Вычисляемые», шкала отступов, список теней на отдельных плашках;
    • инспектор со своими значениями платформ «↳ iOS / ↳ Android», слоями тени и полем цвета Custom / Library.
  • Создание — строкой внизу раздела по «+», как в группах «Цветов»: значение по умолчанию раздела, правится в инспекторе. У тени создаётся размер целиком, четыре варианта.
  • Удаление — с подтверждением, если удаляемые токены используют компоненты. У тени подтверждение считается по четырём вариантам размера.
  • Автосохранение по модели feat(ds): версии, журнал изменений и версионная палитра #109. Очередь с автоповтором. Неподтверждённые команды size-tokens повторяются при открытии темы, с platforms и прежним ключом. Перечитывание по SSE.
  • Опубликованная версия (?versionId) открывается только для чтения, переход из журнала — по ?tokenId.

Проверки

  • ./gradlew build в ds-service — PASS: detekt, spotless, тесты, включая Testcontainers.
  • Клиент: npm run build, npm test (941) — PASS. Изменённые файлы чистые по eslint.
  • tools/verify fast --change add-sizes-tokens-editor — PASS.
  • Заодно исправлен манифест маршрутов после feat(ds-service): Add component editor model API #123: группа appearance-editor реализована только в ds-service, но была без origin: "ds-service", и route-manifest.test.ts db-service искал её роутер в db-service.
  • openspec validate add-sizes-tokens-editor --strict — PASS на 1.6.0 и 1.4.1.
  • На локальном контуре с копией рабочей базы (до слияния с feat: typography tokens editor and ds-service typography style operations #121 и feat(ds): градиент как вид значения цветового токена #122) проверено:
    • правка радиуса, её запись в журнале и переход к источнику;
    • своё значение Android;
    • вычисляемый round.l −2;
    • ссылка цвета слоя на палитру с HEX у потребителей;
    • создание и удаление токенов, подтверждение удаления тени.

Не выполнено

  • tools/verify full, сверка вёрстки с прототипом.
  • Внешние проверки:
    • откат в журнале и вторая вкладка по SSE (6.5);
    • опубликованная версия (6.9);
    • dsbuilder theme fetch (6.11).

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a3a01192-6981-4e98-9082-634b5f40fcd9
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vkaltyrin vkaltyrin self-assigned this Oct 22, 2026
val stored = token.copy(values = written.associate { it.platform to SizeStoredValue(it.value, it.overridden) })
val resolve = colors.resolver(context.projectId, tenantId)
val view = usage.views(designSystemId, listOf(stored), resolve).single()
return DsResult.Success(UpdatedSizeToken(view, written))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] После сохранения Library-цвета превью получает сырую ссылку

При сохранении тени с цветом [general.gray.900][0.16] поле token содержит раскрытый HEX, а values — исходную ссылку. Клиентский applyToTheme (modules/sizeTokens/application/themeModel.ts) отдаёт приоритет values: через themeValuesFromWritten ссылка попадает напрямую в WebShadow. Затем getShadowsTokens передаёт это значение в CSS box-shadow, где ссылка на палитру невалидна. В результате превью тени в редакторе компонентов ломается до перезагрузки темы.

Нужно использовать раскрытые цвета при обновлении модели темы, сохранив исходные ссылки для редактирования; например, обновлять модель тени по разрешённому token.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Исправлено

c.name AS component, c.platform::text AS platform
FROM variation_values v
JOIN live_appearances a ON a.id = v.appearance_id
JOIN components c ON c.id = a.component_id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Использование включает удалённые из ДС компоненты

Запрос соединяет конфигурации с общим каталогом components, но не проверяет действующую связь компонента с дизайн-системой. Если компонент ссылается на round.m, а затем его удаляют из ДС, ExposedDesignSystemComponentRepository.deleteOwned записывает только надгробие design-system-component, оставляя appearances и значения свойств. Поэтому этот запрос продолжает возвращать удалённый компонент в components и вычисляемых радиусах.

Нужно фильтровать использование по действующей редакции design_system_component на той же границе версии, что и конфигурации.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Исправлено

@malilex
malilex force-pushed the feature/ds-versions branch from 74386d7 to d143d81 Compare October 22, 2026 12:26
…isions

Add token_value_revisions.overridden and token_value_creation_baselines.overridden
(V8). The flag is a subject field of a value revision: the token-value journal
handler shows it, the creation baseline and the field reverter restore it, new
themes start with false, and every shared value write (token-values PUT, color
tokens, palette rewrites, token value API, theme initializer) keeps the flag of
the latest revision instead of resetting it.
Read radii, spacing and shadows from token_revisions and token_value_revisions
on the transaction boundary with versionId (canEdit is false on a published
version) and component usage and derived radii from the latest revisions of
component configurations on the same boundary. A value change locks the design
system and the token values, rereads them and writes draft revisions of the
changed values only with the /value and /overridden paths and a per-platform
base revision. Creation writes definitions and values in every theme under the
name key lock with Idempotency-Key support; deletion writes tombstones in every
theme and clears component references. The theme edit revision, its lock and
TENANT_EDIT_CONFLICT are removed; mutations return X-DS-Mutation-Metadata.

A shadow layer color may be a palette step reference [type.shade.step][opacity]:
it is validated against the theme palette, stored in every platform value and
resolved to #RRGGBBAA with colorRef on read.
Shadow layer colors that reference a palette step take part in the theme
palette like color token references: the palette snapshot carries shadow tokens
and the references of their layers, ramp links and linked counts include them
(group by the name rule, not in color token assignments), ramp removal rewrites
the layer color in place, and the revert dependency check rejects restoring a
layer reference to a removed ramp. GET token-values returns the resolved
sourceValue.
…ting model

The size-tokens read refers to VersionId; value change, creation and deletion
refer to OptionalBaseRevision (creation also to OptionalIdempotencyKey) and
describe the X-DS-Mutation-Metadata headers. Bodies and responses drop
editRevision and TENANT_EDIT_CONFLICT, deletion takes no body, value changes
take per-platform baseRevisions, shadow layers carry colorRef and accept a
palette step reference, and tenant token values document sourceValue.
…visions

Read the base theme with the derived round.l -2 and a published version with
versionId, edit radii and shadows with and without own platform values, edit
one value concurrently (warning in the mutation metadata) and different tokens
independently, keep the own flag through the shared token-values save, revert
an own platform value from the journal, repeat a creation with the same
Idempotency-Key, delete with component references reset while the published
version keeps the token, delete a token created in the draft without a journal
entry, and link a shadow layer color to the palette: validation, resolution in
size-tokens and token-values with sourceValue, ramp links, ramp removal and the
revert dependency conflict.
Size token operations follow contract v2: no editRevision, base revisions
of the web, iOS and Android values from subjectRevisions taken when the
command is sent, an Idempotency-Key on creation, mutations through
subjectMutation with X-DS-Mutation-Metadata and errors with details.field.
The queue keeps the 400 ms quiet window and generations, retries network
and 5xx errors after 1 s doubling up to 30 s and reports its state as the
size-tokens autosave source.

Every unconfirmed operation is kept in the theme localStorage as the
original size-tokens command (method, path, body with platforms, base
revisions, idempotency key) and is replayed by the same command when the
theme editor session starts, even if the section is not open; it is never
turned into a ds_draft TokenChange.

The section reads with versionId and is read-only for a published version,
selects ?tokenId through useAddressedToken and reports an unavailable
source, rereads after local queues when the theme model is replaced, and
size-tokens truncated metadata refreshes theme tokens. Shadow size deletion
is confirmed by the union of usage of its four variants with the new dialog
texts. The legacy draft banner and legacyDraft are removed.
The swatch inside the layer color field opens the ColorPickerPopover of the
colors section with Custom and Library tabs. A Library step is sent as the
[type.shade.step][opacity] reference, and the field shows the step name
(Gray 900) by colorRef with the reference opacity; HEX input or a Custom
color replaces the reference. The picker rules move into size-tokens.css
under the section root, the popover opens left of the inspector.
The + of a tree section appears on hover and focus of the section heading
row, as for groups in the colors section, instead of anywhere over the
section.
@vkaltyrin
vkaltyrin force-pushed the feat/sizes-tokens-editor branch from 6d1aeec to 5a63bf5 Compare October 22, 2026 14:00
@vkaltyrin
vkaltyrin changed the base branch from feature/ds-versions to dev October 22, 2026 14:01
@angirb

angirb commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

тут при вводе в радиусах и отступах белые рамки появились
image

в тенях они полные, но синей рамки нет
image
image
синяя рамка есть при вводе цвета хекса
image

Наверно везде должна быть синяя рамка?

# Conflicts:
#	js/apps/client/src/pages/shapes/Shapes.tsx
@vkaltyrin

Copy link
Copy Markdown
Contributor Author

Исправлено, теперь при вводе везде синяя рамка

@vkaltyrin
vkaltyrin merged commit c8de288 into dev Oct 28, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants