skcr-autechre
v4.0.2
Published
A collection of modern, standalone, signal-based Angular UI components (`input()`, `output()`, `model()`), designed for performant and accessible Angular applications. The library provides form controls, navigation, modals, a virtualized table, selectors,
Readme
skcr-autechre — Angular component library
A collection of modern, standalone, signal-based Angular UI components (input(), output(), model()), designed for performant and accessible Angular applications. The library provides form controls, navigation, modals, a virtualized table, selectors, and a toast system.
This page covers installation, compatibility, the component catalog, exported types/enums, toaster integration, and the required Tailwind configuration.
Contents
- Installation & compatibility
- Peer dependencies
- Required configuration (Animations, NgIcons, design system + Tailwind scan, theme)
- Quick start
- Component catalog
- Services
- Exported types and enums
- Toaster and
ToastService - Accessibility (a11y)
- Theme and Tailwind
- Build and publish
Installation & compatibility
- Supported Angular version: Angular 22.x (standalone by default). Requires Node 22+ and TypeScript 6.
- For applications still on Angular 21, use skcr-autechre 1.x (latest: 1.0.50).
- This library targets Angular applications (no
NgModule, standalone components only).
Upgrading to 4.0.1
No API change, but it requires skcr-design-tokens 1.1.0 or later — and that requirement is not
optional in the way peer ranges usually are. Tailwind only emits a utility when the token behind it
exists, so on 1.0.0 the class bg-hover is never generated and hover states render with no
background at all.
What it fixes: hover and selection were being expressed with zone colours (muted,
primary-subtle) rather than state colours. In the dark theme muted and popover held the same
value, so every hover:bg-muted on a menu was strictly invisible — a contrast ratio of 1.00. Worse,
list options used primary-subtle for both the hovered and the selected option, so the two states
were indistinguishable.
--color-hover is a state colour: it darkens on a light ground and lightens on a dark one, which is
the thing a zone colour cannot do. The three states now read in order in both themes — on a popover,
1.00 at rest, 1.41 hovered, 2.05 selected.
If your own templates use hover:bg-muted for a hover, switch them to hover:bg-hover. Using
bg-muted for an actual muted zone stays correct.
Migrating to 4.0.0
4.0.0 changes no API. Every breaking part of it is about where the colours come from, so the migration is a styles file and a package, not a sweep through templates — orion migrated without touching a single one.
Two required steps. Install skcr-design-tokens and import its three entries, then add the
@source line (see Required configuration). Without the package the components render
unstyled: they no longer carry any colour of their own.
Four rendering changes to look at on screen. They are deliberate, and they are the price of having one design system instead of three drifting copies:
| Change | Who it touches |
| --- | --- |
| The .btn family now follows orion's variant | 79 buttons in gaffer, 2 in skcr-chat — shadow, padding, neutral hover |
| title-three is font-semibold | gaffer |
| .badge follows gaffer's variant | skcr-chat's single badge |
| The Warning button moves from amber-500 to the warning token | all three — a real change of hue |
One thing that gets fixed on its own. Applications showing skcr-date-picker or
skcr-datetime-picker were rendering the Material calendar in azure blue, because none of them
carried the --mat-sys-* redirection. The package carries it now, and it follows the theme.
The safelist is gone. Delete your safelist.txt and keep the single @source line — it is
generated from the installed package, so a new library version brings its classes with it.
Migrating to 3.0.0
3.0.0 is a major release and it breaks a lot: around thirty changes to the public surface — 18 members removed, 2 components deleted, 5 renames, 6 tightened types or changed defaults, plus about ten behaviour changes. It is cheap to adopt, not harmless.
Expect 24 lines of migration, and only three items produce them:
| Change | Lines | Where |
| --- | --- | --- |
| ToastService.newToastEvent$ → the service methods | 14 | error interceptors of all four apps |
| isFooterInvisible → isFooterDisplayed | 7 | 5 in orion, 1 in gaffer, 1 in operation-webapp |
| skcr-loader.isNotAbsolute removed | 3 | 1 in orion, 2 in skcr-chat |
Everything else costs nothing, and that is the point of this release rather than a coincidence: each removal was measured against orion, gaffer, operation-webapp and skcr-chat before being made. What went away was what nobody consumed.
The behaviour changes deserve more attention than the removals, because they compile silently and change what users see. They are listed at the end of this section.
Two components are gone: skcr-multi-select-async and skcr-select-grouped. Neither had a
single usage in six months. Their code remains in git history if the need comes back.
Removed inputs and outputs:
| Component | Removed | Notes |
| --- | --- | --- |
| skcr-loader | isNotAbsolute | Never had any effect: the loader carries no positioning rule and was already static. Delete the binding, nothing changes. |
| skcr-table | title | Was never rendered. |
| skcr-modal, skcr-confirmation-modal | form | Were never read. |
| skcr-table-header-cell | isDisabled, disabledText | isOrderByDisplayed already guards the click and hides the chevrons. disabledText defaulted to an English sentence about a 10,000-result query limit — a business rule that had no place in a generic library. |
| skcr-checkbox | subLabel, isWithFullSpace | |
| skcr-input | maxLength | The field no longer truncates; use the native maxlength attribute if you need it. |
| skcr-input-number | maxFractionDigits, tooltipText | The pattern it fed was ignored by browsers on a number input anyway. |
| skcr-multi-select | searchPlaceholder, tooltipText | |
| skcr-datetime-picker | interval | The step stays at 5 minutes, now hardcoded — mat-timepicker defaults to 30. |
| skcr-dropdown-menu | menuClosed | No application listened to it. |
The icon list shrank from 13 to 11: heroChevronRight and heroQuestionMarkCircle are no longer
needed. See "Required configuration" for the exact list — it is generated from the source, not
maintained by hand.
The nine call sites that relied on the w-fit default, and therefore widen:
- orion —
players-comparison(the view and itstable-bar-chart),watchlist-modal(three),scatter-panel(two) - gaffer —
team-form(two). Review !103 of 2026-08-04 had already reported these two as missing[isFullWidth], so full width is the expected rendering there.
New:
| Component | Addition | Why |
| --- | --- | --- |
| skcr-modal | isSubmitDisabled | The footer could not refuse a submission, so a modal that had to forbid one — an empty watchlist name, no metric ticked — had to give up the library footer and rewrite it for that single button. Two of orion's modals were in that position. |
| skcr-submit-button | The spinner and the check no longer change the button's width | They replaced the label in the flow, so the button shrank to the width of a 20px icon mid-save and sprang back. The label now stays in place, merely hidden, and the indicator sits over it. It carries text-inherit, which is not cosmetic: consumer resets give span an explicit colour — orion's covers 70 elements with text-slate-950 — and that wins over the colour inherited from the button, rendering a white label almost black on the coloured variants. Any element a library component adds inside a coloured background needs it. |
Renamed and realigned:
| Component | Change | What to do |
| --- | --- | --- |
| skcr-modal | isFooterInvisible → isFooterDisplayed, default true | [isFooterInvisible]="true" becomes [isFooterDisplayed]="false". Seven call sites across the consumer apps. The negative form went against the library's four …Displayed precedents. |
| skcr-select, skcr-multi-select, skcr-combobox-multi | isFullWidth default is now true on all three | Check the nine call sites that pass nothing, listed below; every other one is unaffected. The three selects had three different width behaviours: skcr-select and skcr-combobox-multi defaulted to w-fit (the combobox to w-full until 2.0.14), and skcr-multi-select was not steerable at all — a hard-coded w-full on its button until 2.0.14, then a w-fit default that 2.1.0 shipped, shrinking 14 call sites. Measured across the four consumer apps: 74 of the 83 call sites want full width, 60 of the 69 skcr-select already passing [isFullWidth]="true" by hand. A w-fit default made 87% of the calls contradict it and silently shrank the ones that forgot — with no compiler error and no lint rule to name them. Pass [isFullWidth]="false" where a select should hug its content. |
| skcr-combobox-multi | placeholder default 'Search...' → '' | Nothing, unless you relied on the English default. Aligns with every other field in the family. |
| skcr-toast | selector renamed from app-toast | Nothing — no application instantiates it directly; the toaster renders it. It was the last of the historical prefix. |
| EModalCloseCondition | SubmitSuccess value 'SubmitSuccess' → 'submitSuccess' | Nothing, unless you compared against the string literal rather than the enum member. None of the four consumer apps did. |
| ToastService | error(message, key) → error(message, title), and a new info() | The second argument of error() used to land in a key field that nothing displayed or copied, so the same argument position produced a title on success() and nothing at all on error(). All four methods now take (message, title). info() was missing although its variant was fully implemented. |
| skcr-loader | size is now TLoaderSize ('xl' \| 'md' \| 'sm' \| 'xs') instead of string, and md exists at 75px | Any other value stops compiling. Worth checking: two loaders in skcr-chat passed size="md", which no CSS rule handled, so they rendered with no width at all — invisible. The scale had no size between sm (50px) and xl (100px); it does now. |
| skcr-input | type is now TInputType (text, password, email, tel, url, search), and value is string \| undefined \| null | number is deliberately excluded — skcr-input-number holds numbers, and accepting it forced value to claim string \| number when handleChange only ever wrote a string. None of the 97 tags passed a type outside the new union. |
| TToast | variant is required now; key and status removed | Nothing in the library reads either field. Worth a look if you type an API response body as TToast — orion's error interceptor does — but only message is ever used by the 14 call sites across the consumer apps, and the assignment still compiles. |
| skcr-submit-button | handleCLick → handleClick | A casing typo in a public method. Nothing calls it from outside its own template. |
| ToastService | newToastEvent$ is private now; newToastEvents is a read-only Observable | This one needs 14 lines changed across the consumer apps — see below. |
Behaviour changes
These compile without complaint and change what is rendered. Read them before upgrading:
skcr-select,skcr-multi-selectandskcr-combobox-multinow decide per option whether to fall back onidfor a missingvalue. They used to decide from the first option alone, so a partially valued list left the remaining options without a usable value.skcr-radio-buttonandskcr-tabsnow honouroption.isDisabled, which the type had always advertised and neither component read. If you pass options carrying that flag, they will now actually be disabled.skcr-radio-buttonalso falls back onidwhen an option has novalue, and no longer renders an empty<legend>when it has no label.
Pushing toasts
ToastService.newToastEvent$ was public, and applications used it to push notifications
directly — 14 call sites across the four consumer apps, all in HTTP error interceptors, all of the
form newToastEvent$.next({ message }). That subject is private now, and newToastEvents exposes
a read-only Observable for anyone who wants to listen.
The replacement is exact, not approximate. Those calls carried no variant, and the toast falls
back to Danger when a notification has none — so they already rendered as error toasts. Which
means:
// before
toastService.newToastEvent$.next({ message: 'Request failed' });
// after — same rendering, shorter
toastService.error('Request failed');If you were pushing an API response body straight through (orion's interceptor does), pass its
fields: toastService.error(error.message, error.title). Only message and title were ever
read.
skcr-modal's footer looks different. It is now an action bar aligned to the right, separated from the content by a rule, with compact buttons at their natural width — instead of two full-width buttons in a two-column grid. This is the footer seven modals across the apps were already building by hand after hiding this one, orion's player-profile metrics editor being the reference. The 22 modals that use the library footer change appearance, with nothing failing to compile.skcr-confirmation-modalinherits the change, and its submit button now carries its level's colour.skcr-submit-buttongainsisCompact, which the modal footer uses. Its default isfalse, so buttons used directly keepbtn-largeandw-fullexactly as before.skcr-radio-buttonandskcr-tabsnow honouroption.isDisabled. If your options carry that flag, radio buttons and tabs that were clickable will now be disabled. This is the change most likely to surprise you.skcr-confirmation-modaltells all four levels apart.Warningrenders amber andInfocarries an information circle, where both previously rendered as a triangle in the primary colour. ItsDangericon colour moved fromtext-red-500to thedestructivetoken, a deeper red.- Both date pickers format their calendar correctly. The header reads "August 2026" instead of
a full date, because
MAT_DATE_FORMATSnow carriesIntlobjects rather than moment-style strings, whichNativeDateAdaptersilently ignored. - Notification ids are a counter, not
Date.now(). Several toasts emitted in the same tick used to share an id, so the first expiry removed its twins — including one the user was reading. skcr-toastertakes anautoCloseDurationinput; its default is the previous 5000ms.skcr-input,skcr-checkboxandskcr-checkbox-classicgenerate a unique element id whenid(respectivelyname) is not passed. Check this one against your own code:skcr-inputused to fall back on the label for its id — so a field with no id carriedid="Player name", spaces and accents included — while the label'sforstayed empty. 57 of the 97skcr-inputtags across the consumer apps are in that case, as are all 43 checkboxes. Clicking a label did not focus its field. Onskcr-checkboxthe label pointed at nothing, so clicking it did not toggle the box either. If you were styling or querying by those empty ids, they now have values.skcr-input-numberrefuses the point and the comma at the keyboard. It holds integers, and aninput[type=number]returns an empty string as soon as its content is not a complete number — so typing "12." used to wipe the field. For real decimals, atype=textwithinputmode=decimalwould be needed, which is another component.
Install into an existing application:
npm install skcr-autechre \
@angular/common@^22 @angular/core@^22 @angular/animations@^22 @angular/cdk@^22 @angular/material@^22 \
@ng-icons/core@^34.0.0 @ng-icons/heroicons@^34.0.0Import from the library (examples):
import { SelectComponent, MultiSelectComponent, ToasterComponent, ToastService } from 'skcr-autechre';
import { TSelectOption, TToast, ESortDirection } from 'skcr-autechre';Peer dependencies
The library declares the following peer dependencies (target versions):
{
"skcr-design-tokens": "^1.1.0",
"@ng-icons/core": "^34.0.0",
"@ng-icons/heroicons": "^34.0.0",
"@angular/animations": "^22.0.0",
"@angular/cdk": "^22.0.0",
"@angular/common": "^22.0.0",
"@angular/core": "^22.0.0",
"@angular/forms": "^22.0.0",
"@angular/material": "^22.0.0"
}Required configuration
- Enable Angular animations (required by several components):
// main.ts (Angular 16+)
import { bootstrapApplication } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [provideAnimations()],
});- Configure NgIcons (components use
NgIcon). The following icons must be provided in your application configuration:
// app.config.ts (or main.ts)
import { provideIcons } from '@ng-icons/core';
import {
heroCheck,
heroCheckCircle,
heroChevronDown,
heroChevronUp,
heroChevronUpDown,
heroDocumentDuplicate,
heroExclamationTriangle,
heroInformationCircle,
heroMagnifyingGlass,
heroXCircle,
heroXMark
} from '@ng-icons/heroicons/outline';
export const appConfig = {
providers: [
provideIcons({
heroCheck,
heroCheckCircle,
heroChevronDown,
heroChevronUp,
heroChevronUpDown,
heroDocumentDuplicate,
heroExclamationTriangle,
heroInformationCircle,
heroMagnifyingGlass,
heroXCircle,
heroXMark
}),
],
};- Import the design system and let Tailwind scan the library.
The components carry no colours of their own: they write roles — card surface, secondary text,
floating surface — whose values come from skcr-design-tokens. Without it they render unstyled.
/* src/styles.css */
@import 'tailwindcss';
@import 'skcr-design-tokens/tokens.css';
@import 'skcr-design-tokens/utilities.css';
@import 'skcr-design-tokens/components.css';
/* Tailwind does not scan node_modules. Without this line the classes the components
write are never generated: the component behaves correctly, only its style is
missing, and nothing in the console says so. */
@source '../node_modules/skcr-autechre/fesm2022/*.mjs';The @source path targets the built JavaScript, where ng-packagr has inlined the templates —
that is where the classes live in the published package. It replaces the hand-copied safelist that
4.0.0 removes: verified on a real consumer build, it generates 269 of the 269 classes the
library writes, including z-[9999], which the tooltip directive assembles in TypeScript.
- Light and dark theme (optional).
The theme is one attribute on <html>, and it has to be set before the first paint — an Angular
initialiser runs after it, so the page would flash the wrong theme on every load.
<!-- index.html, in the <head> -->
<script>
try {
document.documentElement.dataset.theme = localStorage.getItem('skcr-theme') || 'light';
} catch {
document.documentElement.dataset.theme = 'light';
}
</script>The attribute goes on <html>, never on <body>: a custom property is substituted on the element
where it is declared, and the token block is emitted in :root. Set on the body, the switch would
move hand-written colours but not the ones Tailwind generates.
ThemeService (exported by this package) carries the signal, toggle(), and cross-tab
synchronisation. It does not initialise — the script above already did.
- Only if you use
skcr-date-pickerorskcr-datetime-picker— import a Material theme and the CDK overlay stylesheet, then point Material's system tokens at your design system.
Both files are needed: the prebuilt theme does not carry the overlay container's styles. Without them the floating calendar is unstyled and, more misleading, the selected day has no background at all — so it looks as though the picker never registered your choice.
// angular.json — the application's build target
"styles": [
"node_modules/@angular/material/prebuilt-themes/azure-blue.css",
"node_modules/@angular/cdk/overlay-prebuilt.css",
"src/styles.css"
]Angular Material derives its whole appearance from the --mat-sys-* system tokens, and the prebuilt
theme pins their hue — leave it at that and the calendar comes out azure blue inside a green
interface. Redirect them rather than copying values, so a change of palette follows:
/* styles.css, after your @theme block */
:root {
--mat-sys-primary: var(--color-primary);
--mat-sys-on-primary: #ffffff;
--mat-sys-surface: #ffffff;
--mat-sys-surface-container-high: #ffffff;
--mat-sys-on-surface: var(--color-foreground);
--mat-sys-on-surface-variant: var(--color-muted-foreground);
--mat-sys-outline: var(--color-border-color);
--mat-sys-outline-variant: var(--color-border-color);
--mat-sys-corner-large: 0.5rem;
}Quick start
Minimal example with skcr-select and TSelectOption<T>:
import { Component, signal } from '@angular/core';
import { SelectComponent, TSelectOption } from 'skcr-autechre';
@Component({
selector: 'demo-select',
template: `
<skcr-select [options]="options" [isSearchDisplayed]="true" [(value)]="value" />
`,
imports: [SelectComponent],
})
export class DemoSelectComponent {
options: TSelectOption<number>[] = [
{ id: 1, name: 'One' },
{ id: 2, name: 'Two' },
];
value = signal<unknown>(null);
}Component catalog
All components are standalone. Import them into the imports property of your components/pages.
skcr-input— Text field with label, placeholder, invalid/disabled states.skcr-input-number— Numeric input with keyboard handling. Note it advertises integers without enforcing them: the point and the comma both get through.skcr-checkbox— Custom checkbox (form controlFormCheckboxControl).skcr-checkbox-classic— Simple checkbox variant. Since 2.0.14,isIndeterminaterenders the third state (the dash) for a partially selected set — a parent-driven input, so the parent recomputes it after every change.checkedstays boolean, so[formField]keeps working; when both are true the dash wins and the check stays hidden. Clicking an indeterminate checkbox resolves it to checked.skcr-radio-button— Radio button group (options typed withTSelectOption<T>).skcr-tabs— Pill tab bar / segmented control (options typed withTSelectOption<T>, optionalicon), bindable with[(value)]or[formField].skcr-select— Simple select with optional search, supportsTSelectOption<T>.skcr-multi-select— Multi-select with search and virtual scroll (CDK).skcr-combobox-multi— Multi-select combobox with free-text entry, emitsoptionSelected.skcr-dropdown-menu— Dropdown menu with label/icon, closes on outside click.isNeutralStyled(2.0.7+) renders the trigger as a neutral form-like control instead of a hover-only button. Since 2.0.12 the panel opens upwards on its own when the space under the trigger cannot fit it, measured inside the closest clipping ancestor (a scrollable table body, for instance) rather than the whole window — nothing to declare on the consumer side.skcr-submit-button— Action button with loading/success states and color variants.skcr-dialog— Base modal/dialog component with animations.skcr-modal— Full-featured modal including footer/actions.skcr-confirmation-modal— Confirmation modal with levels (EConfirmLevelVariant) and closing conditions (EModalCloseCondition).skcr-table— Virtualized table (CDK) with sortable headers.skcr-table-header-cell— Header cell with sorting (ESortDirection) and tooltip.skcr-date-picker— Date picker (Angular Material) usingDD/MM/YYYYformat (localefr-FR).skcr-datetime-picker— Date and time picker (Angular Material), 5-minute steps. This component styles the global document, on purpose. It runs withViewEncapsulation.Nonebecause it has to reach Material's own classes (.mat-timepicker-panel), which live outside its view. Two consequences to accept before using it: its rules apply to the whole page, including after you navigate away from the page that hosts it; and if another page starts looking odd right after you visited one with a datetime picker, this is the first place to look. Keeping the styles encapsulated would mean pushing them into each consuming application's global stylesheet instead — the same leak, further from the component that needs it.[skcrTooltip]— Directive attaching a tooltip to any element, positioned through the CDK overlay. Not a component: importTooltipDirective.skcr-toaster— Toast container (place at the app level).skcr-toast— Internal component used by the toaster (not intended for direct use). Renamed fromapp-toastin 3.0.0, the last of the historical prefix.skcr-loader— Loading indicator.
Integration notes:
- Option search (
skcr-select,skcr-multi-select,skcr-combobox-multi) matches each term of the query independently, in any order, ignoring case, diacritics and separators. TypingENG Premier— orpremier eng, orENG-Premier— matches an option namedENG - Premier League. A query without a separator behaves exactly as a plain substring search. skcr-tableandskcr-multi-selectrely on@angular/cdk/scrollingfor virtual scroll.skcr-date-pickerdepends on@angular/material(the component imports required modules internally, but@angular/materialmust be installed in the app).
Services
ToastService— Singleton service (providedIn: 'root') to emit new toasts. All four methods take(message?, title?)in that order since 3.0.0.error(message?, title?)— error toast (destructive red,Xicon,Copybutton). Its second argument used to bekeyand landed in a field nothing displayed.info(message?, title?)— new in 3.0.0 (blue, information circle). Its variant had always been implemented but no method reached it.success(message?, title?)— success toast (primary green, check icon, noCopybutton).warning(message?, title?)— warning toast (amber, triangle icon, noCopybutton).newToastEvents— a read-onlyObservable<TToast>, to listen. The underlyingSubjectis private since 3.0.0: push through the methods above.
import { inject } from '@angular/core';
import { ToastService } from 'skcr-autechre';
export class AnyComponent {
private toast = inject(ToastService);
save() {
this.toast.success('Saved successfully');
}
fail() {
this.toast.error('Something went wrong');
}
}ThemeService— new in 4.0.0. Singleton service (providedIn: 'root') for the light/dark switch. It deliberately does not initialise the theme: it is constructed after Angular boots, so after the first paint, and setting the attribute here would flash the wrong theme on every load. The inline script inindex.htmldoes that; the service reads what it left.theme— read-only signal,'light' | 'dark'. Writing is closed on purpose:set()andtoggle()are the only two entries, so the value can never disagree with what is on screen.isDark— computed convenience.set(theme)— applies the attribute, persists to storage, updates the signal.toggle()— flips between the two.- A
storagelistener keeps other tabs in sync. Storage failures are swallowed: the theme stays applied for the session, only its persistence is lost.
TooltipServicewas removed in 4.0.0. It duplicated[skcrTooltip]in full and no application used it. Use the directive.
Exported types and enums
Types:
TSelectOption<T>—{ name: string; value?: T; id?: number; icon?: string; isDisabled?: boolean }- Used by
skcr-select,skcr-multi-select,skcr-combobox-multi,skcr-radio-button,skcr-tabs. valueis optional and falls back toid, per option since 3.0.0.isDisabledis honoured by every one of those components since 3.0.0 —skcr-radio-buttonandskcr-tabsused to ignore it. Thegroupfield is gone: it existed only for the deletedskcr-select-grouped.
- Used by
TColumnCategory—{ label: string; colspan: number }- The category row above
skcr-table's columns.colspancounts columns, and the first category should cover exactly the fixed columns if you use both features.
- The category row above
TToast—{ id?: number; message?: string; title?: string; variant: EConfirmLevelVariant }- Used by the toast system (
ToastServiceandskcr-toaster). variantis required since 3.0.0, andkey/statusare gone.idstays optional because the toaster is what sets it. Withoutmessageortitle, the toast falls back to its variant's default heading.
- Used by the toast system (
TLoaderSize—'xl' | 'md' | 'sm' | 'xs'(100, 75, 50 and 35 pixels)skcr-loader.size, a freestringuntil 3.0.0.mdis new.
TInputType—'text' | 'password' | 'email' | 'tel' | 'url' | 'search'skcr-input.type, a freestringuntil 3.0.0.numberis deliberately excluded — useskcr-input-number.
Enums:
ESortDirection—Ascending | Descending | None(forskcr-table/skcr-table-header-cell).EButtonColorVariant— four values since 3.0.0:PrimaryandDangername a design-system class (btn-primary,btn-danger), whileWarningandInfocarry composed Tailwind classes, because no application declares abtn-warningor abtn-info. Used byskcr-submit-buttonandskcr-modal.EConfirmLevelVariant—Danger | Info | Success | Warning, values'danger' | 'info' | 'success' | 'warning'. All four are now told apart byskcr-confirmation-modal, which used to renderWarningandInfoidentically.EModalCloseCondition—Close('close') andSubmitSuccess('submitSuccess'since 3.0.0, previously'SubmitSuccess').
Import them directly from the package:
import {
EButtonColorVariant,
EConfirmLevelVariant,
EModalCloseCondition,
ESortDirection,
TColumnCategory,
TInputType,
TLoaderSize,
TSelectOption,
TToast,
} from 'skcr-autechre';Toaster and <skcr-toaster>
To use the toast system:
- Place
<skcr-toaster></skcr-toaster>in yourAppComponent(or a global layout shell), ideally at the end of the template:
<!-- app.component.html -->
<router-outlet />
<skcr-toaster></skcr-toaster>- Inject
ToastServiceand emit toasts via its helpers:
import { Component, inject } from '@angular/core';
import { ToastService } from 'skcr-autechre';
@Component({
selector: 'demo-toasts',
template: `<button (click)="notify()">Notify</button>`,
})
export class DemoToastsComponent {
private toast = inject(ToastService);
notify() {
this.toast.success('Operation completed', 'Done');
// or: this.toast.error('Operation failed');
}
}Behavior:
- A toast is shown for 5s by default, then removed (hovering pauses the timer).
skcr-toastertakes anautoCloseDurationinput in milliseconds if that does not suit your messages. error(...)renders the destructive red with aCopybutton;info(...)(blue),success(...)(primary green) andwarning(...)(amber) render without one.- The default headings are
An error occurred/Information/Success/Warning; passtitleto override one. - There is no way to push a toast without a variant any more, and that is deliberate: such a toast fell back to the error style, so a neutral message rendered as a failure. Use the method matching the level you mean.
Theme and Tailwind
- The components carry no colours of their own. They write roles — card surface, secondary
text, floating surface — and
skcr-design-tokensgives those roles their values. That is what lets a single set of classes render in either theme. - There is nothing to configure and no
tailwind.config.jsto adapt: Tailwind v4 reads the@themeblock the package ships. Importing the three CSS entries is the whole setup. - Overriding a token value in your own
styles.cssis expected — it is how the dark theme works and how a project repaints itself. Redefining a class the package defines is not: that is how.btndrifted five ways across three applications before 4.0.0 pulled it back. - The
@sourceline ensures the classes the library writes are generated in the consumer, and replaces the safelist 3.x asked you to copy by hand.
