Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
69 changes: 69 additions & 0 deletions docs/guides/migration.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ New versions include improvements but also contain **breaking changes**; they mu
11. **20.3.0**: the button-toggle review — ARIA semantics, keyboard navigation and signal inputs.
12. **20.3.0**: the form-field review — signals, accessibility and the removal of `mixinColor`.
13. **20.3.0**: the theme service review — signals, `auto` mode and built-in persistence.
14. **20.3.0**: explicit prefix and suffix slots for tag content.

### 1. Upgrade to 18.5.3

Expand Down Expand Up @@ -766,6 +767,74 @@ themeService.currentTheme(); // read directly, or wrap with toObservable() if yo

**Custom themes and DI-based setup.** `setThemes()` still accepts any array of `{ name, className, colorScheme? }` objects — `colorScheme` (`'light' | 'dark'`) is optional: when set, it's each theme's own polarity, independent of its `name`, and is what `colorScheme()` (and `toggle()`) key off; when omitted, `colorScheme()` falls back to the OS preference for that theme. New: `kbqThemeProvider({ themes, mode, storageKey, autoLight, autoDark })` configures the service through DI instead of calling `setThemes()`/`setTheme()` imperatively. The active theme is always applied as a CSS class on `<body>` — the design tokens' `.kbq-light`/`.kbq-dark` styles depend on it, so there's no attribute-based alternative. `auto` resolves to the theme named `autoLight`/`autoDark` (`'light'`/`'dark'` by default) — set these if your custom theme set doesn't use those names, otherwise `auto` won't match any registered theme.

### 14. Explicit tag content slots (20.3.0)

Until 20.3.0 every directly projected element with `kbq-icon` was placed before the tag text, regardless of its position in the template. This implicit rule made icon placement depend on the component's projection selector and made the markup easy to break. Tag content now has explicit `kbqTagPrefix` and `kbqTagSuffix` slots:

```html
<kbq-tag>
<i kbqTagPrefix kbq-icon="kbq-circle-info_16"></i>
Tag
<i kbqTagSuffix kbq-icon="kbq-chevron-down-s_16"></i>
</kbq-tag>
```

`kbqTagRemove` and `kbqTagEditSubmit` are suffix controls already: `KbqTagSuffix` is attached to them through `hostDirectives`. Do not add `kbqTagSuffix` to the same element explicitly, because that applies the directive twice.

#### Running the migration

The `tag-slots` schematic runs automatically:

```bash
ng update @koobiq/components@20
```

Or manually — for example, if you have already upgraded to 20.3.0:

```bash
ng g @koobiq/components:tag-slots --project <your project>
```

To preview the changes without writing them, use `--fix=false`:

```bash
ng g @koobiq/components:tag-slots --project <your project> --fix=false
```

#### What is fixed automatically

The schematic adds `kbqTagPrefix` to every legacy, directly projected `kbq-icon` that is not already assigned to a slot and is not a remove or edit-submit control:

```html
<!-- Before: the info icon rendered before the text despite its source position. -->
<kbq-tag>
Tag
<i kbq-icon="kbq-circle-info_16"></i>
<i kbqTagRemove kbq-icon="kbq-xmark-s_16"></i>
</kbq-tag>

<!-- After: rendering is preserved by an explicit slot. -->
<kbq-tag>
Tag
<i kbqTagPrefix kbq-icon="kbq-circle-info_16"></i>
<i kbqTagRemove kbq-icon="kbq-xmark-s_16"></i>
</kbq-tag>
```

Source order is not used to infer a suffix: under the old projection rule all such icons were prefixes. Existing `kbqTagPrefix`, `kbqTagSuffix`, `kbqTagRemove` and `kbqTagEditSubmit` attributes are left unchanged, so the migration is idempotent.

#### What you need to fix manually

**Intentional trailing content.** Add `kbqTagSuffix` yourself when an icon or another element should follow the label. The schematic cannot infer a new visual intent from markup whose old rendering always placed `kbq-icon` before the label.

**Content outside the legacy icon selector.** Elements with only `kbq-icon-button` or `kbq-icon-item`, nested consumer wrappers and nodes with `ngProjectAs` are left unchanged because they were not directly matched by the old `kbq-icon` slot. Review them only if you want to move them to one of the new slots.

**Standalone imports.** `KbqTagsModule` exports both slot directives. If a standalone component imports `KbqTag` directly instead of the module, also import `KbqTagPrefix` and/or `KbqTagSuffix` when using them; otherwise their host classes and slot spacing are not applied.

<!-- cspell:ignore addClassModificatorForIcons -->

**Deprecated imperative placement and styles.** Replace calls to `addClassModificatorForIcons()` with explicit slot directives, and migrate custom selectors from `.kbq-icon_left` to `.kbq-tag-prefix`. The method and the old selector are deprecated and will be removed in the next major version.

### After the migration

The migration is regex-based and does not rewrite aliased imports, local variables, or re-exports — **review the diff before committing**, rebuild the project and run your tests. The full list of breaking changes is on the [Angular 20 breaking changes](https://github.com/koobiq/angular-components/blob/main/docs/guides/angular-20-breaking-changes.en.md) page.
69 changes: 69 additions & 0 deletions docs/guides/migration.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
11. **20.3.0**: ревью группы кнопок — ARIA-семантика, навигация с клавиатуры и сигнальные входы.
12. **20.3.0**: ревью поля формы — сигналы, доступность и удаление `mixinColor`.
13. **20.3.0**: ревью сервиса темизации — сигналы, режим `auto` и сохранение выбора из коробки.
14. **20.3.0**: явные prefix- и suffix-слоты для содержимого тегов.

### 1. Обновление до 18.5.3

Expand Down Expand Up @@ -766,6 +767,74 @@ themeService.currentTheme(); // читайте напрямую, либо обе

**Кастомные темы и настройка через DI.** `setThemes()` по-прежнему принимает любой массив объектов `{ name, className, colorScheme? }` — `colorScheme` (`'light' | 'dark'`) необязателен: если задан, это собственная «полярность» темы, независимая от её `name`, и именно на неё опирается `colorScheme()` (а также `toggle()`); если не задан, `colorScheme()` для этой темы откатывается на предпочтение ОС. Новое: `kbqThemeProvider({ themes, mode, storageKey, autoLight, autoDark })` настраивает сервис через DI вместо императивных вызовов `setThemes()`/`setTheme()`. Активная тема всегда применяется как CSS-класс на `<body>` — от этого зависят стили `.kbq-light`/`.kbq-dark` дизайн-токенов, поэтому альтернативы через атрибут нет. `auto` разрешается в тему с именем `autoLight`/`autoDark` (по умолчанию `'light'`/`'dark'`) — задайте их, если ваш набор кастомных тем использует другие имена, иначе `auto` не совпадёт ни с одной зарегистрированной темой.

### 14. Явные слоты содержимого тегов (20.3.0)

До 20.3.0 каждый непосредственно спроецированный элемент с `kbq-icon` размещался перед текстом тега независимо от своего положения в шаблоне. Это неявное правило привязывало расположение иконок к селектору проекции компонента, поэтому разметку было легко сломать. Теперь у содержимого тега есть явные слоты `kbqTagPrefix` и `kbqTagSuffix`:

```html
<kbq-tag>
<i kbqTagPrefix kbq-icon="kbq-circle-info_16"></i>
Тег
<i kbqTagSuffix kbq-icon="kbq-chevron-down-s_16"></i>
</kbq-tag>
```

`kbqTagRemove` и `kbqTagEditSubmit` уже являются suffix-контролами: `KbqTagSuffix` подключается к ним через `hostDirectives`. Не добавляйте `kbqTagSuffix` на тот же элемент явно, иначе директива будет применена дважды.

#### Запуск миграции

Схематик `tag-slots` запускается автоматически:

```bash
ng update @koobiq/components@20
```

Или вручную — например, если вы уже обновились до 20.3.0:

```bash
ng g @koobiq/components:tag-slots --project <your project>
```

Посмотреть изменения без записи можно с помощью `--fix=false`:

```bash
ng g @koobiq/components:tag-slots --project <your project> --fix=false
```

#### Что исправляется автоматически

Схематик добавляет `kbqTagPrefix` каждой непосредственно спроецированной legacy-иконке с `kbq-icon`, которая ещё не помещена в слот и не является контролом удаления или подтверждения редактирования:

```html
<!-- Было: иконка info отображалась перед текстом, несмотря на своё положение в исходном коде. -->
<kbq-tag>
Тег
<i kbq-icon="kbq-circle-info_16"></i>
<i kbqTagRemove kbq-icon="kbq-xmark-s_16"></i>
</kbq-tag>

<!-- Стало: внешний вид сохраняется благодаря явному слоту. -->
<kbq-tag>
Тег
<i kbqTagPrefix kbq-icon="kbq-circle-info_16"></i>
<i kbqTagRemove kbq-icon="kbq-xmark-s_16"></i>
</kbq-tag>
```

Положение в исходном коде не используется для определения suffix-слота: по старому правилу проекции все такие иконки были префиксами. Существующие атрибуты `kbqTagPrefix`, `kbqTagSuffix`, `kbqTagRemove` и `kbqTagEditSubmit` не изменяются, поэтому миграция идемпотентна.

#### Что нужно исправить вручную

**Намеренно замыкающий контент.** Добавьте `kbqTagSuffix` самостоятельно, если иконка или другой элемент должны располагаться после текста. Схематик не может определить новое визуальное намерение по разметке, в которой старое правило всегда размещало `kbq-icon` перед текстом.

**Контент вне старого селектора иконок.** Элементы только с `kbq-icon-button` или `kbq-icon-item`, вложенные пользовательские обёртки и узлы с `ngProjectAs` остаются без изменений, поскольку старый слот `kbq-icon` не находил их напрямую. Проверьте их только в том случае, если хотите перенести их в один из новых слотов.

**Standalone-импорты.** `KbqTagsModule` экспортирует обе slot-директивы. Если standalone-компонент импортирует `KbqTag` напрямую вместо модуля, при использовании слотов также импортируйте `KbqTagPrefix` и/или `KbqTagSuffix` — иначе их host-классы и отступы слотов не применятся.

<!-- cspell:ignore addClassModificatorForIcons -->

**Устаревшее императивное расположение и стили.** Замените вызовы `addClassModificatorForIcons()` явными slot-директивами, а пользовательские селекторы `.kbq-icon_left` — на `.kbq-tag-prefix`. Метод и старый селектор устарели и будут удалены в следующей мажорной версии.

### После миграции

Миграция работает на регулярных выражениях и не переписывает алиасные импорты, локальные переменные и ре-экспорты — **проверьте диф перед коммитом**, пересоберите проект и прогоните тесты. Полный список ломающих изменений — на странице [Ломающие изменения — Angular 20](https://github.com/koobiq/angular-components/blob/main/docs/guides/angular-20-breaking-changes.ru.md).
Loading