UNPKG

super-jss

Version:

Super JavaScript Stylesheets for Angular 20 — atomic CSS-in-JS using Signals with responsive breakpoints and theming.

1,192 lines (1,169 loc) 55.7 kB
import * as CSS from 'csstype'; import * as i0 from '@angular/core'; import { OnDestroy, WritableSignal, Injector, RendererFactory2, OnChanges, ViewContainerRef, ElementRef, Renderer2, SimpleChanges, AfterContentInit, OnInit, EventEmitter } from '@angular/core'; import { SafeHtml, DomSanitizer } from '@angular/platform-browser'; type SjThemeColorOption = { main: string; light: string; dark: string; contrast: string; }; type SjColorOption = { 50: string; 100: string; 200: string; 300: string; 400: string; 500: string; 600: string; 700: string; 800: string; 900: string; contrast: string; }; type SjColors = { blue: SjColorOption; indigo: SjColorOption; purple: SjColorOption; pink: SjColorOption; red: SjColorOption; orange: SjColorOption; yellow: SjColorOption; green: SjColorOption; teal: SjColorOption; cyan: SjColorOption; gray: SjColorOption; black: string; white: string; }; type SjPalette = { primary: SjThemeColorOption; secondary: SjThemeColorOption; tertiary: SjThemeColorOption; success: SjThemeColorOption; info: SjThemeColorOption; warning: SjThemeColorOption; error: SjThemeColorOption; dark: SjThemeColorOption; neutral: SjThemeColorOption; light: SjThemeColorOption; }; type SjTypography = { default?: SjStyle; H1?: SjStyle; H2?: SjStyle; H3?: SjStyle; H4?: SjStyle; H5?: SjStyle; H6?: SjStyle; SPAN?: SjStyle; P?: SjStyle; BODY?: SjStyle; STRONG?: SjStyle; CAPTION?: SjStyle; SMALL?: SjStyle; PRE?: SjStyle; }; type SjTheme = { name?: string; breakpoints?: SjBreakPoints; spacing?: (factor: number) => string; typography?: SjTypography; colors?: SjColors; palette?: SjPalette; components?: { surfaces?: { /** * Density-driven padding map. Values can be: * - number or ResponsiveStyle (applies equally to all sides) * - side map to target per-side/axis values */ padding?: Partial<Record<1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12, ResponsiveStyle | number | { all?: ResponsiveStyle | number; x?: ResponsiveStyle | number; y?: ResponsiveStyle | number; top?: ResponsiveStyle | number; right?: ResponsiveStyle | number; bottom?: ResponsiveStyle | number; left?: ResponsiveStyle | number; }>>; gap?: Partial<Record<1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12, ResponsiveStyle | number>>; radius?: Partial<Record<1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12, ResponsiveStyle | number | string>>; border?: Partial<Record<1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12, ResponsiveStyle | number>>; }; /** * Optional design presets expressed as arrays of SjStyle, to be applied * directly via [sj] (e.g., [ ...theme.components.surfacesPresets.padding[5] ]). * Useful for asymmetric or richer density patterns without complicating * the core surfaces maps. */ surfacesPresets?: { padding?: Partial<Record<1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12, SjStyle[]>>; }; }; }; type Primitive = string | number | boolean | bigint | symbol | undefined | null; type DeepPartial<T> = T extends Function ? T : T extends Primitive ? T : T extends Array<infer U> ? Array<DeepPartial<U>> : T extends object ? { [P in keyof T]?: DeepPartial<T[P]>; } : T; type SjResolvedTheme = Omit<SjTheme, 'breakpoints' | 'spacing' | 'typography' | 'colors' | 'palette' | 'components'> & { breakpoints: SjBreakPoints; spacing: (factor: number) => string; typography: SjTypography; colors: SjColors; palette: SjPalette; components: Required<Required<SjTheme>['components']>; }; type SjBreakPoints = { xs: number; sm: number; md: number; lg: number; xl: number; xxl: number; }; type ResponsiveStyle = { xs?: string | number; sm?: string | number; md?: string | number; lg?: string | number; xl?: string | number; xxl?: string | number; }; type WithResponsive<T> = { [P in keyof T]: T[P] | ResponsiveStyle; }; type SjShorthandStyle = { p?: ResponsiveStyle | string | number; pt?: ResponsiveStyle | string | number; pr?: ResponsiveStyle | string | number; pb?: ResponsiveStyle | string | number; pl?: ResponsiveStyle | string | number; m?: ResponsiveStyle | string | number; mt?: ResponsiveStyle | string | number; mr?: ResponsiveStyle | string | number; mb?: ResponsiveStyle | string | number; ml?: ResponsiveStyle | string | number; w?: ResponsiveStyle | string | number; h?: ResponsiveStyle | string | number; minW?: ResponsiveStyle | string | number; minH?: ResponsiveStyle | string | number; maxW?: ResponsiveStyle | string | number; maxH?: ResponsiveStyle | string | number; b?: ResponsiveStyle | string | number; bt?: ResponsiveStyle | string | number; br?: ResponsiveStyle | string | number; bb?: ResponsiveStyle | string | number; bl?: ResponsiveStyle | string | number; bx?: ResponsiveStyle | string | number; by?: ResponsiveStyle | string | number; bs?: ResponsiveStyle | string | number; bw?: ResponsiveStyle | string | number; bc?: ResponsiveStyle | string | number; brad?: ResponsiveStyle | string | number; bg?: ResponsiveStyle | string | number; c?: ResponsiveStyle | string | number; d?: ResponsiveStyle | string | number; fxDir?: ResponsiveStyle | string | number; fxWrap?: ResponsiveStyle | string | number; fxFlow?: ResponsiveStyle | string | number; fxJustify?: ResponsiveStyle | string | number; fxAItems?: ResponsiveStyle | string | number; fxAContent?: ResponsiveStyle | string | number; fxOrder?: ResponsiveStyle | string | number; fxGrow?: ResponsiveStyle | string | number; fxShrink?: ResponsiveStyle | string | number; fxBasis?: ResponsiveStyle | string | number; fxASelf?: ResponsiveStyle | string | number; }; type SjShorthandCustomStyle = { py?: ResponsiveStyle | string | number; px?: ResponsiveStyle | string | number; my?: ResponsiveStyle | string | number; mx?: ResponsiveStyle | string | number; bx?: ResponsiveStyle | string | number; by?: ResponsiveStyle | string | number; }; type SjStyle = WithResponsive<CSS.Properties<string | number>> & SjShorthandStyle & SjShorthandCustomStyle & { [key: string]: ResponsiveStyle | string | number | SjStyle | undefined; }; /** * Global registry for style bundles and hashes. * Phase 1 scaffold: caches bundle keys → className and tracks hit/miss counters. * Injection is still performed by SjCssGeneratorService; this registry centralizes * cache knowledge and enables future cross-service sharing and SSR hydration. */ declare class StyleRegistry { private enabled; private bundleMap; hits: number; misses: number; isEnabled(): boolean; setEnabled(v: boolean): void; getBundleClass(key: string): string | undefined; setBundleClass(key: string, className: string): void; snapshot(): { enabled: boolean; bundles: number; hits: number; misses: number; hitRate: number; }; resetCounters(): void; static ɵfac: i0.ɵɵFactoryDeclaration<StyleRegistry, never>; static ɵprov: i0.ɵɵInjectableDeclaration<StyleRegistry>; } declare let sjActiveThemeService: SjThemeService | undefined; declare class SjThemeService implements OnDestroy { private document; private platformId; private injector; private styleRegistry; theme: WritableSignal<SjResolvedTheme>; sjTheme: i0.Signal<SjResolvedTheme>; currentBreakpoint: WritableSignal<string>; windowWidth: WritableSignal<number>; themeVersion: WritableSignal<number>; private resizeSubscription?; private purgeCssOnBreakpoint; themeName: i0.Signal<string | undefined>; breakpoint: i0.Signal<string>; isMobile: i0.Signal<boolean>; isTablet: i0.Signal<boolean>; isDesktop: i0.Signal<boolean>; private _buildSeq; constructor(document: Document, platformId: Object, injector: Injector, styleRegistry: StyleRegistry); /** Version used for CSS caching: theme version + build sequence (dev). */ cacheVersion(): number; /** * Subscribes to window resize and updates width/breakpoint signals (debounced). * Ensures consumers re-render on any resize, not only breakpoint changes. * Only runs in browser environment. */ initResizeListener(): void; /** * Deep-merges provided theme into the current one, resets CSS cache and bumps version. * @param theme Partial theme overrides. */ setTheme(theme: DeepPartial<SjTheme>): void; setTheme(theme: SjTheme): void; /** * Replace strategy: start from library defaults and apply the provided theme. * Use this when switching between full themes to avoid carry-over. */ setThemeReset(theme: DeepPartial<SjTheme> | SjTheme): void; /** Cleans up window resize subscription when the service is destroyed. */ ngOnDestroy(): void; /** Enable/disable purging generated CSS on breakpoint changes (off by default). */ setPurgeCssOnBreakpoint(enabled: boolean): void; /** Enable/disable the next-gen engine (global style registry + batching). */ enableNextGenEngine(enabled: boolean): void; /** Configure CSS batching (Phase 6): useIdle scheduling and threshold. */ configureCssBatching(options: { useIdle?: boolean; idleThreshold?: number; }): void; /** Phase 7: expose perf stats (registry + generator) for demo dashboards. */ getPerfStats(): any; resetPerfCounters(): void; /** Force-flush pending CSS injection batches immediately. */ flushCssNow(): void; /** Apply current theme variables (typography + app background) to :root/body */ private applyDocumentTypography; static ɵfac: i0.ɵɵFactoryDeclaration<SjThemeService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<SjThemeService>; } declare class SjCssGeneratorService { private document; private platformId; private rendererFactory; private registry; private generatedClasses; private classCache; private renderer; private styleEl?; private isBrowser; private cssQueue; private flushScheduled; private useIdleFlush; private idleThreshold; constructor(document: Document, platformId: Object, rendererFactory: RendererFactory2, registry: StyleRegistry); /** Create atomic CSS map for a given style and theme. */ private generateCssMap; /** Append CSS text to the single managed <style> tag if any. */ private appendCss; /** * Phase 5 (SSR hydration): scan existing <style> tags for class selectors and * pre-populate the generatedClasses set so we don't emit duplicates on startup. */ private seedExistingStyleClasses; private enqueueCss; private flushCssQueue; /** Force an immediate flush of any pending CSS batches (latency-sensitive paths). */ flushNow(): void; /** Schedule a flush using requestIdleCallback (or a timeout fallback). */ private scheduleIdleFlush; /** Configure batching/idle flush behavior (Phase 6). */ configureBatching(opts: { useIdle?: boolean; idleThreshold?: number; }): void; /** * Orders declarations so that shorthands (e.g., padding) are emitted before * corresponding longhands (e.g., padding-top). This ensures that longhands * take precedence within the merged declaration block. */ private orderDeclarations; /** * Returns prefixed class names for styles, appending new CSS to a single <style> tag. * Deduplicates previously generated rules using an in-memory cache. * @param styles Style object to convert. * @param theme Active theme for spacing/colors/breakpoints. * @param version Optional cache/version prefix to bust old CSS. * @returns Array of generated class names (prefixed). */ getOrGenerateClasses(styles: SjStyle, theme: SjResolvedTheme, version?: number): string[]; /** * Generate a single bundled class for the entire style object. * This reduces the number of classes applied per element (1 class vs many atomic classes) * by replacing all generated atomic selectors with a single prefix class. */ getOrGenerateClassBundle(styles: SjStyle, theme: SjResolvedTheme, version?: number): string[]; /** * Clears in-memory cache and resets the <style> host element. * Call when theme structure changes to avoid stale CSS. */ clearCache(): void; /** Perf stats for Phase 7 dashboard. */ getStats(): { readonly generatedClasses: number; readonly cacheEntries: number; readonly pendingCssChunks: number; }; static ɵfac: i0.ɵɵFactoryDeclaration<SjCssGeneratorService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<SjCssGeneratorService>; } /** * [sj] directive applies SJSS styles: responsive classes + inline typography. * Re-renders on theme, breakpoint and window resize changes. * * This directive is the core of SJSS, transforming style objects into atomic CSS classes * that are applied reactively based on theme and responsive breakpoints. It supports * various input formats including static styles, arrays, and producer functions. */ type SjStyleProducer = () => SjStyle; type SjInput = SjStyle | SjStyle[] | SjStyleProducer | Array<SjStyle | SjStyleProducer>; declare class SjDirective implements OnChanges { vcr: ViewContainerRef; protected el: ElementRef<HTMLElement>; private sjt; private cssGenerator; private renderer; /** * The style object or array of style objects to be applied. * Can be a single style object, an array of styles, a producer function, * or a mixed array of styles and producers for dynamic styling. */ sj: SjInput | undefined; /** When false, the directive will not auto-re-render on theme changes. */ reactive: boolean; private lastClasses; private cacheManager; /** * Constructs the SjDirective. * * @param vcr The ViewContainerRef provides access to the host element. * @param el The ElementRef of the host element. * @param sjt The SjThemeService for accessing theme-related functionalities. * @param cssGenerator The SjCssGeneratorService for generating CSS classes. * @param renderer The Renderer2 for manipulating the DOM. */ constructor(vcr: ViewContainerRef, el: ElementRef<HTMLElement>, sjt: SjThemeService, cssGenerator: SjCssGeneratorService, renderer: Renderer2); /** * Triggers a re-render when [sj] input changes. * Clears caches when the input reference changes to ensure fresh resolution. * @param changes Angular input change set containing changed properties. */ ngOnChanges(changes: SimpleChanges): void; /** * Generates/attaches classes and applies inline typography + text overrides. * Executed reactively by signals and on input changes. */ protected renderStyles(): void; /** * Generates CSS classes for the given processed styles and theme. * @param processedStyles The resolved and merged styles object. * @param theme The current theme object. * @returns Array of generated class names or undefined if generation failed. */ private generateClasses; /** * Applies the generated classes to the DOM element. * @param element The native DOM element to apply classes to. * @param classes Array of class names to apply. */ private applyClasses; static ɵfac: i0.ɵɵFactoryDeclaration<SjDirective, never>; static ɵdir: i0.ɵɵDirectiveDeclaration<SjDirective, "[sj]:not(sj-host):not(sj-typography):not(sj-card):not(sj-paper):not(sj-flex):not(sj-button):not(sj-input)", never, { "sj": { "alias": "sj"; "required": false; }; "reactive": { "alias": "reactive"; "required": false; }; }, {}, never, never, true, never>; static ngAcceptInputType_reactive: any; } type SjButtonApi = ((overrides?: Partial<SjStyle>) => SjStyle) & { light: (overrides?: Partial<SjStyle>) => SjStyle; contained: (overrides?: Partial<SjStyle>) => SjStyle; outlined: (overrides?: Partial<SjStyle>) => SjStyle; containedPrimary: (overrides?: Partial<SjStyle>) => SjStyle; containedLight: (overrides?: Partial<SjStyle>) => SjStyle; containedDark: (overrides?: Partial<SjStyle>) => SjStyle; containedSecondary: (overrides?: Partial<SjStyle>) => SjStyle; danger: (overrides?: Partial<SjStyle>) => SjStyle; }; declare const sjButton: SjButtonApi; declare const sjButtonLight: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjButtonContained: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjButtonOutlined: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjButtonContainedPrimary: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjButtonContainedLight: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjButtonContainedDark: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjButtonContainedSecondary: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjButtonDanger: (overrides?: Partial<SjStyle>) => SjStyle; /** Base border style used by card variants. */ declare const sjBorder: SjStyle; /** Light shadow used by card variants. */ declare const sjShadow: SjStyle; declare const sjShadowElevated: SjStyle; /** Convenience mixin combining border and shadow. */ declare const sjBorderShadow: SjStyle; /** Function API for composing card styles with variant helpers. */ type SjCardApi = ((overrides?: Partial<SjStyle>) => SjStyle) & { outlined: (overrides?: Partial<SjStyle>) => SjStyle; flat: (overrides?: Partial<SjStyle>) => SjStyle; elevated: (overrides?: Partial<SjStyle>) => SjStyle; interactive: (overrides?: Partial<SjStyle>) => SjStyle; primary: (overrides?: Partial<SjStyle>) => SjStyle; secondary: (overrides?: Partial<SjStyle>) => SjStyle; info: (overrides?: Partial<SjStyle>) => SjStyle; codeSnippet: (overrides?: Partial<SjStyle>) => SjStyle; }; /** Public card API exposing default and variant builders. */ declare const sjCard: SjCardApi; declare const sjCardOutlined: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjCardFlat: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjCardElevated: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjCardInteractive: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjCardPrimary: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjCardSecondary: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjCardCodeSnippet: (overrides?: Partial<SjStyle>) => SjStyle; declare const sjOutlinedCard: (overrides?: Partial<SjStyle>) => SjStyle; type PaperBuilder = (overrides?: Partial<SjStyle>) => SjStyle; type SjPaperApi = PaperBuilder & { flat: PaperBuilder; outlined: PaperBuilder; filled: PaperBuilder; }; declare const sjPaper: SjPaperApi; declare const sjPaperFlat: PaperBuilder; declare const sjPaperOutlined: PaperBuilder; declare const sjPaperFilled: PaperBuilder; type BoxBuilder = (overrides?: Partial<SjStyle>) => SjStyle; type BoxPartial = Partial<SjStyle> | undefined; type SjBoxApi = BoxBuilder & { row: BoxBuilder; column: BoxBuilder; grid: BoxBuilder; centered: BoxBuilder; middle: BoxBuilder; between: BoxBuilder; around: BoxBuilder; evenly: BoxBuilder; wrap: BoxBuilder; nowrap: BoxBuilder; grow: BoxBuilder; with: (...partials: BoxPartial[]) => BoxBuilder; }; declare const sjBox: SjBoxApi; declare const sjBoxRow: BoxBuilder; declare const sjBoxColumn: BoxBuilder; declare const sjBoxGrid: BoxBuilder; declare const sjBoxCentered: BoxBuilder; declare const sjBoxMiddle: BoxBuilder; declare const sjBoxBetween: BoxBuilder; declare const sjBoxAround: BoxBuilder; declare const sjBoxEvenly: BoxBuilder; declare const sjBoxWrap: BoxBuilder; declare const sjBoxNoWrap: BoxBuilder; declare const sjBoxGrow: BoxBuilder; /** Function API for composing typography styles with variant helpers. */ type SjTypographyApi = ((overrides?: Partial<SjStyle>) => SjStyle) & { h1: (overrides?: Partial<SjStyle>) => SjStyle; h2: (overrides?: Partial<SjStyle>) => SjStyle; h3: (overrides?: Partial<SjStyle>) => SjStyle; h4: (overrides?: Partial<SjStyle>) => SjStyle; h5: (overrides?: Partial<SjStyle>) => SjStyle; h6: (overrides?: Partial<SjStyle>) => SjStyle; p: (overrides?: Partial<SjStyle>) => SjStyle; paragraph: (overrides?: Partial<SjStyle>) => SjStyle; span: (overrides?: Partial<SjStyle>) => SjStyle; strong: (overrides?: Partial<SjStyle>) => SjStyle; body: (overrides?: Partial<SjStyle>) => SjStyle; caption: (overrides?: Partial<SjStyle>) => SjStyle; small: (overrides?: Partial<SjStyle>) => SjStyle; pre: (overrides?: Partial<SjStyle>) => SjStyle; }; declare function createSjTypographyApi(theme: SjResolvedTheme): SjTypographyApi; /** * Lightweight host element that forwards `[sj]` styles to its surrounding parent. * Useful when the consumer is dynamically instantiating a component and needs a * dedicated hook to apply Super JSS styles without introducing extra DOM wrappers. */ declare class SjHostComponent extends SjDirective implements AfterContentInit, OnChanges { constructor(viewContainerRef: ViewContainerRef, elementRef: ElementRef<HTMLElement>, themeService: SjThemeService, cssGenerator: SjCssGeneratorService, renderer: Renderer2); ngOnChanges(changes: SimpleChanges): void; ngAfterContentInit(): void; static ɵfac: i0.ɵɵFactoryDeclaration<SjHostComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjHostComponent, "sj-host", never, {}, {}, never, ["*"], true, never>; } interface SjIconRenderOptions { fill?: string; stroke?: string; fillOpacity?: number; strokeOpacity?: number; } declare const SJ_ICON_RENDERERS: { readonly sun: (options?: SjIconRenderOptions) => string; readonly moon: (options?: SjIconRenderOptions) => string; readonly superJson: (options?: SjIconRenderOptions) => string; readonly plus: (o?: SjIconRenderOptions) => string; readonly minus: (o?: SjIconRenderOptions) => string; readonly x: (o?: SjIconRenderOptions) => string; readonly check: (o?: SjIconRenderOptions) => string; readonly edit: (o?: SjIconRenderOptions) => string; readonly trash: (o?: SjIconRenderOptions) => string; readonly download: (o?: SjIconRenderOptions) => string; readonly upload: (o?: SjIconRenderOptions) => string; readonly refresh: (o?: SjIconRenderOptions) => string; readonly externalLink: (o?: SjIconRenderOptions) => string; readonly link: (o?: SjIconRenderOptions) => string; readonly arrowLeft: (o?: SjIconRenderOptions) => string; readonly arrowRight: (o?: SjIconRenderOptions) => string; readonly arrowUp: (o?: SjIconRenderOptions) => string; readonly arrowDown: (o?: SjIconRenderOptions) => string; readonly chevronLeft: (o?: SjIconRenderOptions) => string; readonly chevronRight: (o?: SjIconRenderOptions) => string; readonly chevronUp: (o?: SjIconRenderOptions) => string; readonly chevronDown: (o?: SjIconRenderOptions) => string; readonly menu: (o?: SjIconRenderOptions) => string; readonly search: (o?: SjIconRenderOptions) => string; readonly filter: (o?: SjIconRenderOptions) => string; readonly list: (o?: SjIconRenderOptions) => string; readonly grid: (o?: SjIconRenderOptions) => string; readonly moreHorizontal: (o?: SjIconRenderOptions) => string; readonly moreVertical: (o?: SjIconRenderOptions) => string; }; type SjIconName = keyof typeof SJ_ICON_RENDERERS; declare const icon: { sun: SjIconName; moon: SjIconName; superJson: SjIconName; plus: SjIconName; minus: SjIconName; x: SjIconName; check: SjIconName; edit: SjIconName; trash: SjIconName; download: SjIconName; upload: SjIconName; refresh: SjIconName; externalLink: SjIconName; link: SjIconName; arrowLeft: SjIconName; arrowRight: SjIconName; arrowUp: SjIconName; arrowDown: SjIconName; chevronLeft: SjIconName; chevronRight: SjIconName; chevronUp: SjIconName; chevronDown: SjIconName; menu: SjIconName; search: SjIconName; filter: SjIconName; list: SjIconName; grid: SjIconName; moreHorizontal: SjIconName; moreVertical: SjIconName; }; declare const SJ_ICON_SVGS: { readonly sun: string; readonly moon: string; readonly superJson: string; readonly plus: string; readonly minus: string; readonly x: string; readonly check: string; readonly edit: string; readonly trash: string; readonly download: string; readonly upload: string; readonly refresh: string; readonly externalLink: string; readonly link: string; readonly arrowLeft: string; readonly arrowRight: string; readonly arrowUp: string; readonly arrowDown: string; readonly chevronLeft: string; readonly chevronRight: string; readonly chevronUp: string; readonly chevronDown: string; readonly menu: string; readonly search: string; readonly filter: string; readonly list: string; readonly grid: string; readonly moreHorizontal: string; readonly moreVertical: string; }; type SjIconOptions = SjIconRenderOptions; declare const renderIcon: (name: SjIconName, options?: SjIconOptions) => string; declare class SjIconComponent implements OnChanges { private readonly sanitizer; private readonly themeService; static icon: { sun: SjIconName; moon: SjIconName; superJson: SjIconName; plus: SjIconName; minus: SjIconName; x: SjIconName; check: SjIconName; edit: SjIconName; trash: SjIconName; download: SjIconName; upload: SjIconName; refresh: SjIconName; externalLink: SjIconName; link: SjIconName; arrowLeft: SjIconName; arrowRight: SjIconName; arrowUp: SjIconName; arrowDown: SjIconName; chevronLeft: SjIconName; chevronRight: SjIconName; chevronUp: SjIconName; chevronDown: SjIconName; menu: SjIconName; search: SjIconName; filter: SjIconName; list: SjIconName; grid: SjIconName; moreHorizontal: SjIconName; moreVertical: SjIconName; }; name: SjIconName; size: string | number; label: string | null; fill?: string; stroke?: string; fillOpacity?: number; strokeOpacity?: number; svg: SafeHtml | null; constructor(sanitizer: DomSanitizer, themeService: SjThemeService); get computedRole(): string | null; get isAriaHidden(): boolean; ngOnChanges(changes: SimpleChanges): void; private updateSvg; private normalizeSize; private getSafeSvg; private normalizeColor; static ɵfac: i0.ɵɵFactoryDeclaration<SjIconComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjIconComponent, "sj-icon", never, { "name": { "alias": "name"; "required": false; }; "size": { "alias": "size"; "required": false; }; "label": { "alias": "label"; "required": false; }; "fill": { "alias": "fill"; "required": false; }; "stroke": { "alias": "stroke"; "required": false; }; "fillOpacity": { "alias": "fillOpacity"; "required": false; }; "strokeOpacity": { "alias": "strokeOpacity"; "required": false; }; }, {}, never, never, true, never>; } declare const SjCardVariants: { readonly default: "default"; readonly outlined: "outlined"; readonly flat: "flat"; readonly elevated: "elevated"; readonly interactive: "interactive"; readonly codeSnippet: "codeSnippet"; }; declare const SjPaperVariants: { readonly default: "default"; readonly flat: "flat"; readonly outlined: "outlined"; readonly filled: "filled"; }; type SjPaperVariant = (typeof SjPaperVariants)[keyof typeof SjPaperVariants]; declare const SjButtonVariants: { readonly default: "default"; readonly light: "light"; readonly contained: "contained"; readonly outlined: "outlined"; readonly containedPrimary: "containedPrimary"; readonly containedLight: "containedLight"; readonly containedDark: "containedDark"; readonly containedSecondary: "containedSecondary"; readonly danger: "danger"; readonly filled: "filled"; readonly flat: "flat"; }; type SjButtonVariant = (typeof SjButtonVariants)[keyof typeof SjButtonVariants]; declare const SjTypographyVariants: { readonly default: "default"; readonly h1: "h1"; readonly h2: "h2"; readonly h3: "h3"; readonly h4: "h4"; readonly h5: "h5"; readonly h6: "h6"; readonly p: "p"; readonly paragraph: "paragraph"; readonly span: "span"; readonly strong: "strong"; readonly body: "body"; readonly caption: "caption"; readonly small: "small"; readonly pre: "pre"; }; type SjTypographyVariant = (typeof SjTypographyVariants)[keyof typeof SjTypographyVariants]; declare abstract class SjBaseComponent implements AfterContentInit, OnChanges { protected hostRef: ElementRef<HTMLElement>; protected renderer: Renderer2; protected themeService: SjThemeService; protected cssGenerator: SjCssGeneratorService; sj: SjInput | undefined; /** When false, this component will not auto-re-render on theme changes. */ reactive: boolean; component: 'div' | 'section' | 'article' | 'span' | 'nav' | 'header' | 'footer' | 'main' | 'aside'; host: boolean; marker: string | undefined; useBg: string | 'none' | undefined; useColor: string | 'auto' | 'none' | undefined; protected parentEl: HTMLElement | null; protected targetEl: HTMLElement | null; protected lastAppliedClass: string | null; private static _instanceCounter; private _instanceId; constructor(hostRef: ElementRef<HTMLElement>, renderer: Renderer2, themeService: SjThemeService, cssGenerator: SjCssGeneratorService); ngAfterContentInit(): void; ngOnChanges(changes: SimpleChanges): void; protected rebuildTargetElement(): void; protected get defaultMarker(): string; private applyMarkerToEl; protected applyExtraMarkers(el: HTMLElement): void; protected composeBaseStyle(): SjStyle; protected abstract composeStyle(): SjStyle; protected applyToTarget(): void; protected applyToParent(): void; static ɵfac: i0.ɵɵFactoryDeclaration<SjBaseComponent, never>; static ɵdir: i0.ɵɵDirectiveDeclaration<SjBaseComponent, never, never, { "sj": { "alias": "sj"; "required": false; }; "reactive": { "alias": "reactive"; "required": false; }; "component": { "alias": "component"; "required": false; }; "host": { "alias": "host"; "required": false; }; "marker": { "alias": "marker"; "required": false; }; "useBg": { "alias": "useBg"; "required": false; }; "useColor": { "alias": "useColor"; "required": false; }; }, {}, never, never, true, never>; static ngAcceptInputType_reactive: any; static ngAcceptInputType_host: any; } declare class SjPaperComponent extends SjBaseComponent { protected get defaultMarker(): string; variant: SjPaperVariant; usePadding: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | true | '' | undefined; usePaint: string | 'auto' | 'none'; useRounded: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | true | '' | undefined; constructor(hostRef: ElementRef<HTMLElement>, renderer: Renderer2, themeService: SjThemeService, cssGenerator: SjCssGeneratorService); protected applyExtraMarkers(el: HTMLElement): void; private getVariantStyles; composeStyle(): SjStyle; static ɵfac: i0.ɵɵFactoryDeclaration<SjPaperComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjPaperComponent, "sj-paper", never, { "variant": { "alias": "variant"; "required": false; }; "usePadding": { "alias": "usePadding"; "required": false; }; "usePaint": { "alias": "usePaint"; "required": false; }; "useRounded": { "alias": "useRounded"; "required": false; }; }, {}, never, ["*"], true, never>; } /** * A card is a container for content. * * If you make a card interactive (e.g., by adding a click handler), * you must make it accessible. * * @example * <!-- For navigation --> * <a href="/details" style="text-decoration: none;"> * <sj-card variant="interactive"> * ... * </sj-card> * </a> * * <!-- For an action --> * <sj-card variant="interactive" role="button" tabindex="0" (click)="doSomething()"> * ... * </sj-card> */ declare class SjCardComponent extends SjBaseComponent { variant: 'flat' | 'outlined' | 'elevated' | 'interactive'; usePaint: string | 'auto' | 'none'; usePadding: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | undefined; useRounded: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | undefined; sj: SjInput | undefined; set useSurface(v: any); protected get defaultMarker(): string; constructor(hostRef: ElementRef<HTMLElement>, renderer: Renderer2, themeService: SjThemeService, cssGenerator: SjCssGeneratorService); protected applyExtraMarkers(el: HTMLElement): void; private getVariantStyles; protected composeStyle(): SjStyle; static ɵfac: i0.ɵɵFactoryDeclaration<SjCardComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjCardComponent, "sj-card", never, { "variant": { "alias": "variant"; "required": false; }; "usePaint": { "alias": "usePaint"; "required": false; }; "usePadding": { "alias": "usePadding"; "required": false; }; "useRounded": { "alias": "useRounded"; "required": false; }; "sj": { "alias": "sj"; "required": false; }; "useSurface": { "alias": "useSurface"; "required": false; }; }, {}, never, ["*"], true, never>; } declare class SjButtonComponent { private themeService; sjButton: SjButtonApi; variant: SjButtonVariant | 'filled' | 'flat'; useDensity: 1 | 2 | 3 | 4; sj: SjInput | undefined; color: keyof SjPalette | undefined; useFullWidth: boolean; usePaint: string | 'auto' | 'none' | undefined; useRounded: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | true | '' | undefined; constructor(themeService: SjThemeService); get selectedSj(): (overrides?: Partial<SjStyle>) => SjStyle; private pickLegacyVariant; private baseButtonStyles; private variantStyles; get hostSj(): SjInput; static ɵfac: i0.ɵɵFactoryDeclaration<SjButtonComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjButtonComponent, "sj-button", never, { "variant": { "alias": "variant"; "required": false; }; "useDensity": { "alias": "useDensity"; "required": false; }; "sj": { "alias": "sj"; "required": false; }; "color": { "alias": "color"; "required": false; }; "useFullWidth": { "alias": "useFullWidth"; "required": false; }; "usePaint": { "alias": "usePaint"; "required": false; }; "useRounded": { "alias": "useRounded"; "required": false; }; }, {}, never, ["*"], true, never>; } /** * To make this component accessible, you should provide a label and associate it with the input. * * @example * <label for="my-input">My Input</label> * <sj-input id="my-input"></sj-input> */ declare class SjInputComponent implements OnInit { private static nextId; ngOnInit(): void; variant: 'flat' | 'outlined' | 'filled'; type: 'text' | 'email' | 'password' | 'search' | 'number' | 'url' | 'color'; usePadding: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | undefined; useRounded: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | undefined; usePaint: 'none' | 'auto' | 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | 'dark' | 'neutral' | 'light'; fullWidth: boolean; disabled: boolean; invalid: boolean; id: string | undefined; ariaDescribedby: string | undefined; placeholder: string | undefined; value: string | undefined; valueChange: EventEmitter<string>; sj: SjInput | undefined; get paperVariant(): 'flat' | 'outlined' | 'filled'; onInput(evt: Event): void; get containerSj(): SjInput; get inputSj(): SjInput; static ɵfac: i0.ɵɵFactoryDeclaration<SjInputComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjInputComponent, "sj-input", never, { "variant": { "alias": "variant"; "required": false; }; "type": { "alias": "type"; "required": false; }; "usePadding": { "alias": "usePadding"; "required": false; }; "useRounded": { "alias": "useRounded"; "required": false; }; "usePaint": { "alias": "usePaint"; "required": false; }; "fullWidth": { "alias": "fullWidth"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "invalid": { "alias": "invalid"; "required": false; }; "id": { "alias": "id"; "required": false; }; "ariaDescribedby": { "alias": "ariaDescribedby"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "value": { "alias": "value"; "required": false; }; "sj": { "alias": "sj"; "required": false; }; }, { "valueChange": "valueChange"; }, never, ["[prefix]", "[suffix]"], true, never>; } declare class SjTypographyComponent implements AfterContentInit, OnChanges { private themeService; private cssGenerator; private hostRef; private renderer; private static _nextId; variant: SjTypographyVariant; component: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'strong' | 'small' | 'pre' | 'code' | 'label' | 'div' | 'blockquote' | 'cite' | undefined; align: 'left' | 'center' | 'right' | 'justify' | undefined; noWrap: boolean; gutterBottom: boolean; paragraph: boolean; useWeight: number | 'thin' | 'extraLight' | 'light' | 'regular' | 'medium' | 'semiBold' | 'bold' | 'extraBold' | 'black' | 'default' | { xs?: number | string; sm?: number | string; md?: number | string; lg?: number | string; xl?: number | string; xxl?: number | string; } | undefined; sj: SjInput | undefined; private sjTypographyApi; private targetEl; private lastAppliedClass; constructor(themeService: SjThemeService, cssGenerator: SjCssGeneratorService, hostRef: ElementRef<HTMLElement>, renderer: Renderer2); ngAfterContentInit(): void; ngOnChanges(changes: SimpleChanges): void; private resolveTag; private rebuildTargetElement; private selectedSj; private composeStyle; private applyToTarget; static ɵfac: i0.ɵɵFactoryDeclaration<SjTypographyComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjTypographyComponent, "sj-typography", never, { "variant": { "alias": "variant"; "required": false; }; "component": { "alias": "component"; "required": false; }; "align": { "alias": "align"; "required": false; }; "noWrap": { "alias": "noWrap"; "required": false; }; "gutterBottom": { "alias": "gutterBottom"; "required": false; }; "paragraph": { "alias": "paragraph"; "required": false; }; "useWeight": { "alias": "useWeight"; "required": false; }; "sj": { "alias": "sj"; "required": false; }; }, {}, never, ["*"], true, never>; } declare class SjFlexComponent extends SjBaseComponent { protected get defaultMarker(): string; useCol: boolean; useWrap: boolean; useInline: boolean; useCenter: boolean; useBetween: boolean; useAround: boolean; useEvenly: boolean; useGap: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | true | '' | undefined; usePadding: 1 | 2 | 3 | 4 | 'compact' | 'default' | 'comfortable' | 'spacious' | 'none' | true | '' | undefined; constructor(hostRef: ElementRef<HTMLElement>, renderer: Renderer2, themeService: SjThemeService, cssGenerator: SjCssGeneratorService); composeStyle(): SjStyle; static ɵfac: i0.ɵɵFactoryDeclaration<SjFlexComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<SjFlexComponent, "sj-flex", never, { "useCol": { "alias": "useCol"; "required": false; }; "useWrap": { "alias": "useWrap"; "required": false; }; "useInline": { "alias": "useInline"; "required": false; }; "useCenter": { "alias": "useCenter"; "required": false; }; "useBetween": { "alias": "useBetween"; "required": false; }; "useAround": { "alias": "useAround"; "required": false; }; "useEvenly": { "alias": "useEvenly"; "required": false; }; "useGap": { "alias": "useGap"; "required": false; }; "usePadding": { "alias": "usePadding"; "required": false; }; }, {}, never, ["*"], true, never>; static ngAcceptInputType_useCol: any; static ngAcceptInputType_useWrap: any; static ngAcceptInputType_useInline: any; static ngAcceptInputType_useCenter: any; static ngAcceptInputType_useBetween: any; static ngAcceptInputType_useAround: any; static ngAcceptInputType_useEvenly: any; } declare const SjPaletteTokens: { readonly primary: { readonly main: "primary.main"; readonly light: "primary.light"; readonly dark: "primary.dark"; readonly contrast: "primary.contrast"; }; readonly secondary: { readonly main: "secondary.main"; readonly light: "secondary.light"; readonly dark: "secondary.dark"; readonly contrast: "secondary.contrast"; }; readonly tertiary: { readonly main: "tertiary.main"; readonly light: "tertiary.light"; readonly dark: "tertiary.dark"; readonly contrast: "tertiary.contrast"; }; readonly success: { readonly main: "success.main"; readonly light: "success.light"; readonly dark: "success.dark"; readonly contrast: "success.contrast"; }; readonly info: { readonly main: "info.main"; readonly light: "info.light"; readonly dark: "info.dark"; readonly contrast: "info.contrast"; }; readonly warning: { readonly main: "warning.main"; readonly light: "warning.light"; readonly dark: "warning.dark"; readonly contrast: "warning.contrast"; }; readonly error: { readonly main: "error.main"; readonly light: "error.light"; readonly dark: "error.dark"; readonly contrast: "error.contrast"; }; readonly dark: { readonly main: "dark.main"; readonly light: "dark.light"; readonly dark: "dark.dark"; readonly contrast: "dark.contrast"; }; readonly neutral: { readonly main: "neutral.main"; readonly light: "neutral.light"; readonly dark: "neutral.dark"; readonly contrast: "neutral.contrast"; }; readonly light: { readonly main: "light.main"; readonly light: "light.light"; readonly dark: "light.dark"; readonly contrast: "light.contrast"; }; }; type Responsive<T> = T | ResponsiveStyle; type RemoveIndex<T> = { [K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: T[K]; }; type CssPropsNoIndex = RemoveIndex<CSS.Properties<string | number>>; type CssFunctionsBase = { [K in keyof CssPropsNoIndex]-?: (value: Responsive<CssPropsNoIndex[K]>) => SjStyle; }; type CssOverrides = { width: (value: Responsive<CSS.Property.Width<string | number>>) => SjStyle; height: (value: Responsive<CSS.Property.Height<string | number>>) => SjStyle; maxWidth: (value: Responsive<CSS.Property.MaxWidth<string | number>>) => SjStyle; minWidth: (value: Responsive<CSS.Property.MinWidth<string | number>>) => SjStyle; maxHeight: (value: Responsive<CSS.Property.MaxHeight<string | number>>) => SjStyle; minHeight: (value: Responsive<CSS.Property.MinHeight<string | number>>) => SjStyle; }; type ReservedRootKeys = 'hover' | 'focus' | 'active' | 'disabled' | 'theme' | 'palette' | 'breakpoints' | 'sjBox' | 'sjPaper' | 'sjCard' | 'sjButton' | 'options'; type CssFunctions = Omit<CssFunctionsBase, keyof CssOverrides | ReservedRootKeys> & CssOverrides; type CssFunctionWithOptions<T> = T & { options: Record<string, any>; }; type CssFunctionsWithOptions = { [K in keyof CssFunctions]: CssFunctionWithOptions<CssFunctions[K]>; }; type SjCssApi = CssFunctionsWithOptions; type SjStyleApi = SjCssApi & SjShApi; type SjApi = { sjBox: SjBoxApi; sjPaper: SjPaperApi & { variants: typeof SjPaperVariants; }; sjCard: SjCardApi & { variants: typeof SjCardVariants; }; sjButton: SjButtonApi & { variants: typeof SjButtonVariants; }; density: { options: { compact: 1; default: 2; comfortable: 3; spacious: 4; }; }; hover: (style: SjStyle | Array<Partial<SjStyle> | undefined | null | false>) => SjStyle; focus: (style: SjStyle | Array<Partial<SjStyle> | undefined | null | false>) => SjStyle; active: (style: SjStyle | Array<Partial<SjStyle> | undefined | null | false>) => SjStyle; disabled: (style: SjStyle | Array<Partial<SjStyle> | undefined | null | false>) => SjStyle; palette: typeof SjPaletteTokens; breakpoints: typeof SjBreakpointTokens; space: (n: number) => number; }; interface SjRootApi extends SjApi, SjCssApiWithOptions, SjShApiWithOptions { } declare const SjBreakpointTokens: { readonly xs: "xs"; readonly sm: "sm"; readonly md: "md"; readonly lg: "lg"; readonly xl: "xl"; readonly xxl: "xxl"; }; declare const SjDisplayTokens: { readonly flex: "flex"; readonly grid: "grid"; readonly block: "block"; readonly inline: "inline"; readonly inlineBlock: "inline-block"; readonly contents: "contents"; readonly none: "none"; }; declare const SjBorderStyleTokens: { readonly none: "none"; readonly hidden: "hidden"; readonly dotted: "dotted"; readonly dashed: "dashed"; readonly solid: "solid"; readonly double: "double"; readonly groove: "groove"; readonly ridge: "ridge"; readonly inset: "inset"; readonly outset: "outset"; }; declare const SjPositionTokens: { readonly static: "static"; readonly relative: "relative"; readonly absolute: "absolute"; readonly fixed: "fixed"; readonly sticky: "sticky"; }; declare const SjSizingTokens: { readonly width: { readonly auto: "auto"; readonly fitContent: "fit-content"; readonly maxContent: "max-content"; readonly minContent: "min-content"; }; readonly height: { readonly auto: "auto"; readonly fitContent: "fit-content"; readonly maxContent: "max-content"; readonly minContent: "min-content"; }; }; declare const SjFlexTokens: { readonly direction: { readonly row: "row"; readonly rowReverse: "row-reverse"; readonly column: "column"; readonly columnReverse: "column-reverse"; }; readonly justify: { readonly start: "flex-start"; readonly end: "flex-end"; readonly center: "center"; readonly between: "space-between"; readonly around: "space-around"; readonly evenly: "space-evenly"; }; readonly align: { readonly start: "flex-start"; readonly end: "flex-end"; readonly center: "center"; readonly stretch: "stretch"; readonly baseline: "baseline"; }; readonly wrap: { readonly wrap: "wrap"; readonly nowrap: "nowrap"; readonly wrapReverse: "wrap-reverse"; }; readonly display: { readonly flex: "flex"; readonly grid: "grid"; readonly block: "block"; readonly inline: "inline"; readonly inlineBlock: "inline-block"; readonly contents: "contents"; readonly none: "none"; }; }; type Fn<T> = (value: T) => SjStyle; type SjShApi = { p: Fn<SjShorthandStyle['p']>; px: Fn<SjShorthandCustomStyle['px']>; py: Fn<SjShorthandCustomStyle['py']>; pt: Fn<SjShorthandStyle['pt']>; pr: Fn<SjShorthandStyle['pr']>; pb: Fn<SjShorthandStyle['pb']>; pl: Fn<SjShorthandStyle['pl']>; m: Fn<SjShorthandStyle['m']>; mx: Fn<SjShorthandCustomStyle['mx']>; my: Fn<SjShorthandCustomStyle['my']>; mt: Fn<SjShorthandStyle['mt']>; mr: Fn<SjShorthandStyle['mr']>; mb: Fn<SjShorthandStyle['mb']>; ml: Fn<SjShorthandStyle['ml']>; gap: Fn<SjStyle['gap']>; bg: Fn<SjShorthandStyle['bg']>; c: Fn<SjShorthandStyle['c']>; w: Fn<SjShorthandStyle['w']>; h: Fn<SjShorthandStyle['h']>; minW: Fn<SjShorthandStyle['minW']>; minH: Fn<SjShorthandStyle['minH']>; maxW: Fn<SjShorthandStyle['maxW']>; maxH: Fn<SjShorthandStyle['maxH']>; brad: Fn<SjShorthandStyle['brad']>; d: Fn<SjShorthandStyle['d']>; fxDir: Fn<SjShorthandStyle['fxDir']>; fxJustify: Fn<SjShorthandStyle['fxJustify']>; fxAItems: Fn<SjShorthandStyle['fxAItems']>; }; declare const FlexJustifyOptions: { readonly flexStart: "flex-start"; readonly flexEnd: "flex-end"; readonly center: "center"; readonly spaceBetween: "space-between"; readonly spaceAround: "space-around"; readonly spaceEvenly: "space-evenly"; }; declare const FlexAlignOptions: { readonly flexStart: "flex-start"; readonly flexEnd: "flex-end"; readonly center: "center"; readonly stretch: "stretch"; readonly baseline: "baseline"; }; type WithOptions<TFn, TOpts> = TFn & { options: TOpts; }; type SjCssApiWithOptions = Omit<SjCssApi, 'color' |