Migrating to 2.0
Every breaking change of @kikita-labs/ui 2.0: renamed exports, provider defaults, locale and messages, icons, tokens, component behaviour and the charts.
Update the package and run the migration that ships with it. It renames identifiers only and never touches strings, comments or templates.
ng update @kikita-labs/uing updaterunsrename-symbols-v2for every workspace that moves from 1.x to 2.x. It reads every TypeScript file that imports from@kikita-labs/ui.- It renames named imports (including
import typeandimport { Old as Local }), every use of the renamed binding,export { Old }of such a binding, re-exports, namespace members andimport(...)types. - It skips
node_modules,distand.angular, and a second run changes nothing. When the new name is already declared in the same file the symbol is left alone and a warning names the file; rename it by hand. - Names used through a dynamic import (
const { KuiButtonDirective } = await import(...)) are not seen; search for them with thegit grepcommand above. - Selectors, inputs, outputs,
exportAsnames, CSS custom properties and CSS class names do not change, so templates and styles need no edit.
An Angular class is named for what it is, not for the construct that declares it. There are no compatibility aliases: the old names no longer exist in 2.0.
KuiSeparatorDirectiveis nowKuiSeparator,KuiTabsComponentisKuiTabsandKuiToastServiceisKuiToast, as in Angular 20+, Angular Material and the CDK.- A class name is the PascalCase of its selector:
button[kuiButton]isKuiButtonandkui-tabsisKuiTabs. A pipe keeps its suffix (KuiComboboxHighlightPipe). - Providers follow the
provideXconvention:kuiProvideLocaleisprovideKuiLocale.kuiToast(),kuiDialog(),kuiDrawer(),kuiConfirm()andkuiMediaViewer()are unchanged. - The migration also maps names that only existed in 2.0 prereleases. The chart legend data type
KuiChartLegendItembecameKuiChartLegendEntry, and the template directiveKuiChartLegendItemDirectivetook the plain nameKuiChartLegendItem.
| Name | Type | Default | Description |
|---|---|---|---|
| KuiButtonDirective | KuiButton | — | A directive loses its suffix. |
| KuiTabsComponent | KuiTabs | — | A component loses its suffix. |
| KuiToastService | KuiToast | — | A service loses its suffix; kuiToast() still returns it. |
| KuiSelectCellComponent | KuiSelectCell | — | Table selection parts are renamed the same way. |
| kuiProvideLocale | provideKuiLocale | — | Returns Provider[] and accepts a Signal. |
The full table of the 74 renamed names in the library migration guide
Component defaults moved from six injection tokens to one mechanism, KuiDefaults. A nested provider now merges with its parent per property.
| Name | Type | Default | Description |
|---|---|---|---|
| KUI_BUTTON_OPTIONS, KUI_FIELD_OPTIONS, KUI_SELECT_OPTIONS | provideKuiDefaults({ button, field, select }) | — | The injection tokens are removed. |
| KUI_COMBOBOX_OPTIONS, KUI_TOOLTIP_OPTIONS, KUI_TOAST_OPTIONS | provideKuiDefaults({ combobox, tooltip, toast }) | — | The injection tokens are removed. |
| kuiProvideButtonOptions, kuiProvideFieldOptions, kuiProvideSelectOptions | provideKuiDefaults | — | Deprecated, forward to provideKuiDefaults, removed in 3.0. |
| kuiProvideComboboxOptions, kuiProvideTooltipOptions, provideKuiToastOptions | provideKuiDefaults | — | Deprecated, forward to provideKuiDefaults, removed in 3.0. |
| provideKikitaUi({ tooltip }) | provideKikitaUi({ defaults: { tooltip } }) | — | Deprecated. |
| KikitaUiDefaults | KuiComponentDefaults | — | Deprecated alias, removed in 3.0. |
| KuiButtonOptions as { button, iconButton } | KuiButtonProviderOptions | — | KuiButtonOptions now describes one button. |
- In 1.x the field, select, combobox and button helpers replaced the whole parent object, so a subtree that set one property dropped the rest. In 2.0 each property resolves on its own.
- The global control size is reactive: changing
defaults.sizeupdates components that are already rendered. ProvidingKIKITA_UI_OPTIONSdirectly no longer sets the default size; useprovideKuiDefaults({ size })for a subtree. - Inputs that now resolve through the defaults (Popover, Menu, Dropdown, Calendar, Carousel, Pagination and others) are
undefinedwhen omitted. Their rendered default is unchanged, but code that reads such an input back must read the resolved value. KuiStepperContext.lineariseffectiveLinear,KuiTreeContext.modeiseffectiveModeandKuiSplitterContext.orientationiseffectiveOrientation.
All text the library owns is a typed message with an English default.
provideKuiLocalereturnsProvider[](it returned oneProvider), so spread it where you used it as a single entry. It accepts aSignaland works for a subtree.- A requested locale is checked against the runtime
Intland falls back toen-US.LOCALE_IDis not read implicitly; useprovideKikitaUi({ locale: () => inject(LOCALE_ID) }). - On the server
KUI_LOCALEfollows the requestAccept-Languageand the browser reuses it throughTransferState. A cache in front of the server must sendVary: Accept-Language, or the application can pin a locale withprovideKuiLocale. - The library ships English only. Translate with
provideKikitaUi({ messages }),provideKuiMessagesor themessagesinput of the components that have one. Inputs that carried an English default (ariaLabelof Pagination, Carousel, Menu, Popover, Tree and OTP Input,closeLabelof Alert,labelof Avatar Group and Loader,placeholderof Command Palette and Date Picker,errorLabelof Tab) areundefinedwhen omitted; the rendered text is unchanged. - Date Picker formats and parses the numeric layout of the locale (
10/03/2026inen-US,03.10.2026inru-RU). Setformat="dd.MM.yyyy"ordefaults.datePicker.formatto keep the old layout. - Time Picker defaults to the hour cycle of the locale (
12hinen-US). Setformat="24h"ordefaults.timePicker.formatto keep the old default. - Calendar and Calendar Range name each day button with its full localized date and take the first day and the weekend from the locale. Tests that look up a day button by its bare number must use the full date as the accessible name.
- The default chart
valueFormatis the compact notation of the locale, File Upload sizes useIntlunits (2.5 MB) and Pagination, Carousel, Media Viewer and OTP positions are formatted with the locale. - Removed internals:
KUI_CALENDAR_NAVIGATION_LABELSand the Date PickerformatDisplayDateandparseDisplayDatehelpers.
Structural icons are replaceable data, and the Lucide set is read at a pinned version.
- Structural icons (close, clear, chevrons, status marks and similar) are drawn by one renderer and can be replaced through
defaults.iconsand per-component slots. Default shapes, sizes and weights are unchanged. - The default Lucide set is read at a pinned
lucide-staticversion (1.51.0, it was the floating@1) and converted to glyph data instead of being inserted as trusted HTML. Allowconnect-src https://cdn.jsdelivr.netin a Content Security Policy, or serve the files yourself withcreateKuiLucideResolver({ baseUrl }). - A name that is not a Lucide kebab-case name resolves to nothing without a request.
KuiIconSourceis still the markup string type; resolvers and registries may also returnKuiIconGlyph. - The internal
kui-chrome-icon-paths.utilmodule is removed.
Behaviour that differs from 1.x. Each item names the component, so search this list for the ones you use.
- OTP Input: the
readOnlyinput isreadonly, the name the Signal Forms contract binds. Rename it in templates; there is no alias. - Toast: the region is a manual popover in the browser top layer and sits above open dialogs and drawers.
defaults.toast.positionandmaxVisiblefollow runtime changes, and apersistentsignal that turnsfalseresumes the time left. - Select: an
input[kuiSelect]bound with[formField]showsaria-invalidonly after the field is touched, and a multiple Select keeps its panel open when an option is chosen with Enter or Space. - Required state:
kui-fieldexposes its required state asaria-requiredon the controls that support it, so snapshot tests of the rendered markup change. - Calendar and Calendar Range: the markup is a full ARIA grid with
role="gridcell"elements insiderole="row"weeks, andaria-selectedis on the gridcell. CSS that targets.kui-calendar-grid > .kui-calendar-daymust target.kui-calendar-dayor the new.kui-calendar-weekand.kui-calendar-cellwrappers. - Splitter: the
role="separator"is an inner element ofkui-splitter-gutterand the collapse button is its sibling. The gutter host carries no role,aria-*ortabindex; style it throughdata-kui-orientation,data-kui-disabledanddata-kui-dragging. Each pane renders its generatedid. - File Upload: the "Choose file" label and the native file input are
aria-hidden; the dropzone is the only interactive element. Carousel: the slide track is a tab stop whiledraggableistrue. - Focus and disabled: every focusable part draws a solid 2px
outlinein--kui-color-focus, a ring drawn only withbox-shadowis gone and--kui-input-focus-ringdefaults tonone. Every disabled control dims to--kui-opacity-disabled(0.5). - Dropdown: closing a panel after a selection returns focus to the control, and Escape returns it to the field control.
KuiDropdown.setAnchortakes an optional third argument naming the focus-return element. - Coercion: static numeric attributes of Progress, Avatar, Avatar Group, Time Picker, Pagination, OTP Input, Splitter Pane, Carousel, Dropdown, Menu and Popover are coerced, and an invalid value falls back to a safe default instead of reaching ARIA or CSS.
- Inputs:
type="number"fields built withkuiInputno longer show the browser arrows (usekuiNumberInputfor step buttons) andtype="search"fields no longer show the browser clear cross. - Command Palette: command ids must be stable, unique and non-empty; development builds report empty, whitespace-containing and duplicate ids. It focuses its search input after render instead of in a microtask.
kuiAutoFocusis new, and OTP InputautoFocusfocuses the first cell that can take focus.
Style delivery changed, and field and icon now need the shared stylesheet like every other component.
- Each primitive stylesheet lives beside its component.
@kikita-labs/ui/stylesandkikita-ui.cssare still the only public style paths. kui-fieldandkui-iconstyles moved from component-scoped files into thekui.componentslayer, so both needkikita-ui.css(ng addinstalls it). An unlayered application rule overrides them without raising specificity.- Controls no longer import
kui-field; they inject the internalKUI_FIELDtoken.KuiField.getDropdown(),getCalendar()andgetTimePickerPanel()now find the part anywhere inside the field. theme-default.cssis part of@kikita-labs/ui/styles, so the default theme works from CSS alone. The generated theme sheet sits in thekui.tokenslayer, declared beforekui.baseandkui.components, so a variable you write outside any layer wins regardless of source order.provideKikitaUi()setsdata-kui-densityon<html>fromseeds.density, on the server too, unless the page already set it. Right-to-left layouts are not supported in 2.0.
Token names are kept with the exceptions below. Colour tokens have their own table on the Theming page.
- 322 component tokens that only mapped a role onto a semantic or base token (for example
--kui-card-bg,--kui-btn-solid-bg,--kui-input-height) are no longer defined by the generated stylesheet or returned increateKuiTheme().component. Each component states the default as a fallback chain in its own CSS, so an override on any ancestor reaches it. Reading one withgetComputedStylenow returns an empty string unless it is set. - Components no longer declare 123 of their public tokens on their element (such as
--kui-alert-radius,--kui-badge-height,--kui-carousel-dot-bg); per-variant defaults live in private--_kui-*variables and the public token wins at any level. - The Button aliases
--kui-btn-bg,--kui-btn-color,--kui-btn-focus-ringand related, and the legacy Select tokens--kui-select-bg,--kui-select-borderand related, are removed. Button and Icon Button read the canonical--kui-btn-solid-*and--kui-btn-soft-*tokens, so a token set on an ancestor restyles Button in that scope. - Hooks that used to be defined on
:rootas literals (--kui-btn-focus-ring-w,--kui-btn-disabled-opacity,--kui-dialog-backdropand others) are not generated any more. Set the shared token instead:--kui-focus-ring-width,--kui-focus-ring-offset,--kui-opacity-disabled,--kui-color-scrim,--kui-font-weight-semibold. seeds.neutralnow drives the surface, border, text, skeleton and scrollbar roles;--kui-neutral-1to-12are two scales, one per mode, andtheme.palettes.neutralis the light scale. The defaultwarningseed isoklch(0.56 0.15 65)and the defaultinfoseed isoklch(0.53 0.14 215); pass your own seeds to keep other colours.- Text on solid fills is white on every default accent in both modes and interactive control borders are stronger at rest. Use
--kui-color-<role>-on-fill,-textand-indicatorin your own CSS.--kui-color-on-filland--kui-color-primary-focus-ringstill exist but are deprecated and removed in 3.0. - Hover and pressed fills of list options, menu items, calendar days, tabs and ghost buttons read
--kui-color-state-hoverand--kui-color-state-active. Line heights follow the type roles and--kui-line-height-control. - Windows High Contrast:
forced-colors.css, imported last bykikita-ui.css, states checked controls, Slider, Progress, selected cells, Tabs, Segmented, pressed Chip and Stepper with system colours.
The four charts changed their keyboard model, tooltip data and sizing.
- Arrow keys move DOM focus, and Up and Down move between series while Left and Right move along a series; before, every arrow moved along one flat list.
KuiChartPoint.xandypassed to atooltipformatter are data units (they were SVG pixels), andris passed. The default scatter text is{series}: ({x}, {y}). Bubbleris in CSS pixels and the consumer owns clamping.- Line and bar charts measure their container, so axis text keeps a fixed pixel size (13px by default, it was 11px scaled with the viewBox). Set
--kui-chart-axis-text-font-sizeto change it. - Every tooltip closes on
Escape;[kuiTooltip]tooltips also stay open while the pointer is on them.--kui-chart-legend-swatch-radiusis gone (the swatch is a marker shape); use--kui-chart-legend-swatch-size.
Work through these checks in order after the automatic migration.
- Run
ng update @kikita-labs/ui, then thegit grepcommand from the first section; it must return nothing. - Replace every
KUI_*_OPTIONStoken andkuiProvide*Optionscall withprovideKuiDefaults. - Rename
readOnlytoreadonlyonkui-otp-input. - Search your styles for removed tokens and for selectors that depend on the old Calendar or Splitter markup.
- If you render on the server, check that your cache sends
Vary: Accept-Language. - Rebuild, run your unit and browser tests and review screenshot diffs before accepting new baselines: disabled opacity, focus outlines, warning and info colours, line heights and tooltip timing changed on purpose.