UNPKG

igniteui-theming

Version:

A set of Sass variables, mixins, and functions for generating palettes, typography, and elevations used by Ignite UI components.

751 lines (750 loc) 21.8 kB
//#region src/knowledge/component-metadata.ts var GRID_COMPOUND_INFO = { description: "The grid is a complex compound component with many themeable parts including filtering, editing, pagination, toolbar and more.", relatedThemes: [ "action-strip", "grid-summary", "grid-toolbar", "column-actions", "paginator", "checkbox", "chip", "list", "input-group", "flat-button", "outlined-button", "flat-icon-button", "outlined-icon-button" ], composed: true, guidance: `The grid's theme will automatically derive the related themes for all related child components.` }; var COMPONENT_METADATA = { accordion: { selectors: { angular: "igx-accordion", webcomponents: "igc-accordion" } }, "accordion-body": { childOf: "accordion" }, "accordion-header": { childOf: "accordion" }, "action-strip": { selectors: { angular: "igx-action-strip", webcomponents: null } }, avatar: { selectors: { angular: "igx-avatar", webcomponents: "igc-avatar" } }, badge: { selectors: { angular: "igx-badge", webcomponents: "igc-badge" } }, banner: { selectors: { angular: "igx-banner", webcomponents: "igc-banner" }, compound: { description: "The banner component uses flat-buttons for the actions", relatedThemes: ["flat-button"], guidance: `The banner action buttons should visually coordinate with the banner background. \ If customizing the banner background, ensure flat-button foreground contrasts against it.` } }, "bottom-nav": { selectors: { angular: "igx-bottom-nav", webcomponents: null } }, button: { selectors: { angular: ".igx-button", webcomponents: "igc-button" }, variants: [ "flat-button", "contained-button", "outlined-button", "fab-button" ] }, "flat-button": { selectors: { angular: ".igx-button--flat", webcomponents: "igc-button[variant=\"flat\"]" } }, "contained-button": { selectors: { angular: [".igx-button--contained"], webcomponents: "igc-button[variant=\"contained\"]" } }, "outlined-button": { selectors: { angular: [".igx-button--outlined"], webcomponents: "igc-button[variant=\"outlined\"]" } }, "fab-button": { selectors: { angular: [".igx-button--fab"], webcomponents: "igc-button[variant=\"fab\"]" } }, "icon-button": { selectors: { angular: [".igx-icon-button"], webcomponents: "igc-icon-button" }, variants: [ "flat-icon-button", "contained-icon-button", "outlined-icon-button" ] }, "flat-icon-button": { selectors: { angular: [".igx-icon-button--flat"], webcomponents: "igc-icon-button[variant=\"flat\"]" } }, "contained-icon-button": { selectors: { angular: [".igx-icon-button--contained"], webcomponents: "igc-icon-button[variant=\"contained\"]" } }, "outlined-icon-button": { selectors: { angular: [".igx-icon-button--outlined"], webcomponents: "igc-icon-button[variant=\"outlined\"]" } }, "button-group": { selectors: { angular: "igx-buttongroup", webcomponents: "igc-button-group" } }, calendar: { selectors: { angular: "igx-calendar", webcomponents: "igc-calendar" } }, card: { selectors: { angular: "igx-card", webcomponents: "igc-card" }, compound: { description: "The card component can contain various child components like avatars, buttons, chips, and icons.", relatedThemes: [ "flat-button", "flat-icon-button", "chip", "icon" ], guidance: `The card component can contain flat-button(s), flat-icon-button(s), and icon(s) that should harmonize visually well with the background of the card component. \ For the flat-button and flat-icon-button themes, ensure the foreground color contrasts well with the card background. \ For the icon theme, the color should also coordinate with the card background while maintaining sufficient contrast.` } }, "card-actions": { childOf: "card" }, "card-content": { childOf: "card" }, "card-header": { childOf: "card" }, carousel: { selectors: { angular: "igx-carousel", webcomponents: "igc-carousel" } }, chat: { selectors: { angular: "igc-chat", webcomponents: "igc-chat" }, compound: { description: "The chat component uses a flat-icon-button, contained-icon-button, and a textarea internally.", relatedThemes: [ "flat-icon-button", "contained-icon-button", "input-group" ], guidance: "Make sure the textarea, the flat-icon-button, and the contained-icon-button themes visually coordinate with each other and the overall chat background." } }, checkbox: { selectors: { angular: "igx-checkbox", webcomponents: "igc-checkbox" } }, chip: { selectors: { angular: "igx-chip", webcomponents: "igc-chip" } }, "column-actions": { selectors: { angular: "igx-column-actions", webcomponents: null }, compound: { description: "The column actions component uses checkboxes for selection and flat-buttons for the action items.", relatedThemes: ["checkbox", "flat-button"], tokenDerivations: { "flat-button.foreground": { from: "column-actions.background", transform: "adaptive-contrast" } }, guidance: "Make sure to theme these child components to visually coordinate with each other and the overall column actions background." } }, combo: { selectors: { angular: "igx-combo", webcomponents: "igc-combo" }, aliases: ["combobox", "autocomplete"], compound: { description: "The combo component combines input, drop-down, and checkbox components.", relatedThemes: [ "input-group", "drop-down", "checkbox" ], tokenDerivations: { "input-group.focused-border-color": { from: "combo.toggle-button-background", transform: "identity" }, "combo.empty-list-background": { from: "combo.toggle-button-background", transform: "identity" }, "drop-down.background-color": { from: "combo.toggle-button-background", transform: "identity" }, "checkbox.fill-color": { from: "combo.toggle-button-background", transform: "identity" } }, guidance: "The combo's input-group, drop-down, and checkbox should share a consistent color scheme." } }, "simple-combo": { selectors: { angular: "igx-simple-combo", webcomponents: "igc-combo[single-select]" }, compound: { description: "The simple combo component combines input and drop-down components.", relatedThemes: ["input-group", "drop-down"], tokenDerivations: { "combo.empty-list-background": { from: "combo.toggle-button-background", transform: "identity" }, "input-group.focused-border-color": { from: "combo.toggle-button-background", transform: "identity" } }, guidance: "The simple-combo's input-group and drop-down should share a consistent color scheme." } }, "date-picker": { selectors: { angular: "igx-date-picker", webcomponents: "igc-date-picker" }, compound: { description: "The date-picker combines input, calendar, and flat-button components.", relatedThemes: [ "flat-button", "input-group", "calendar" ], tokenDerivations: { "flat-button.foreground": { from: "calendar.content-background", transform: "adaptive-contrast" } }, guidance: "The flat-button foreground inside the calendar should contrast with the calendar content background." } }, "date-range-picker": { selectors: { angular: "igx-date-range-picker", webcomponents: "igc-date-range-picker" }, compound: { description: "The date-range-picker combines input, calendar, and flat-button components.", relatedThemes: [ "flat-button", "input-group", "calendar" ], tokenDerivations: { "flat-button.foreground": { from: "calendar.content-background", transform: "adaptive-contrast" } }, guidance: "The flat-button foreground inside the calendar should contrast with the calendar content background." } }, "date-range-start": { selectors: { angular: "igx-date-range-start", webcomponents: null }, theme: "input-group" }, "date-range-end": { selectors: { angular: "igx-date-range-end", webcomponents: null }, theme: "input-group" }, "date-time-input": { selectors: { angular: null, webcomponents: "igc-date-time-input" }, aliases: ["datetime input", "date time input"] }, dialog: { selectors: { angular: ".igx-dialog", webcomponents: "igc-dialog" }, aliases: ["modal", "popup"], compound: { description: "The dialog component uses flat-buttons for the actions", relatedThemes: ["flat-button"], tokenDerivations: { "flat-button.foreground": { from: "dialog.background", transform: "adaptive-contrast" } }, guidance: `The dialog action buttons should visually coordinate with the dialog background. \ If customizing the dialog background, ensure flat-button foreground contrasts against it.` } }, divider: { selectors: { angular: "igx-divider", webcomponents: "igc-divider" } }, "dock-manager": { selectors: { angular: "igc-dockmanager", webcomponents: "igc-dockmanager" } }, "drop-down": { selectors: { angular: ".igx-drop-down__list", webcomponents: "igc-dropdown" }, aliases: ["dropdown menu"] }, "drop-down-item": { childOf: "drop-down" }, "expansion-panel": { selectors: { angular: "igx-expansion-panel", webcomponents: "igc-expansion-panel" } }, "expansion-panel-body": { childOf: "expansion-panel" }, "expansion-panel-header": { childOf: "expansion-panel" }, "file-input": { selectors: { angular: "igx-input-group[class~=\"igx-input-group--file\"]", webcomponents: "igc-file-input" }, compound: { description: "The file-input uses an input-group for the input field.", relatedThemes: ["input-group", "file-input"], guidance: `The file input is composed of an input-group and a browse button. \ Both themes should share the same visual treatment as the file-input wrapper.` } }, grid: { selectors: { angular: "igx-grid", webcomponents: "igc-grid" }, compound: GRID_COMPOUND_INFO }, "tree-grid": { selectors: { angular: "igx-tree-grid", webcomponents: "igc-tree-grid" }, theme: "grid", compound: GRID_COMPOUND_INFO }, "hierarchical-grid": { selectors: { angular: "igx-hierarchical-grid", webcomponents: "igc-hierarchical-grid" }, theme: "grid", compound: GRID_COMPOUND_INFO }, "pivot-grid": { selectors: { angular: "igx-pivot-grid", webcomponents: "igc-pivot-grid" }, theme: "grid", compound: GRID_COMPOUND_INFO }, "grid-lite": { selectors: { angular: "igx-grid-lite", webcomponents: "igc-grid-lite" }, theme: "grid", compound: { description: "The grid lite component is a compound component some themeable parts including chips and checkboxes.", relatedThemes: ["checkbox", "chip"] } }, "grid-excel-style-filtering": { selectors: { angular: "igx-grid-excel-style-filtering", webcomponents: "igc-grid-excel-style-filtering" }, theme: "grid", compound: GRID_COMPOUND_INFO }, "grid-summary": { selectors: { angular: ".igx-grid-summary", webcomponents: "igc-grid-summary" } }, "grid-toolbar": { selectors: { angular: "igx-grid-toolbar", webcomponents: "igc-grid-toolbar" } }, highlight: { selectors: { angular: "igx-highlight", webcomponents: "igc-highlight" } }, icon: { selectors: { angular: "igx-icon", webcomponents: "igc-icon" } }, "input-group": { selectors: { angular: "igx-input-group", webcomponents: "igc-input" } }, label: { selectors: { angular: "[igxLabel]", webcomponents: "igc-label" } }, list: { selectors: { angular: "igx-list", webcomponents: "igc-list" } }, "list-header": { childOf: "list" }, "list-item": { childOf: "list" }, navbar: { selectors: { angular: "igx-navbar", webcomponents: "igc-navbar" }, compound: { description: "The navbar contains buttons and icons-buttons for navigation.", relatedThemes: [ "flat-button", "outlined-button", "contained-button", "flat-icon-button", "outlined-icon-button", "contained-icon-button" ], guidance: "Make sure to theme all button and icon-button variants in the navbar to visually coordinate with the navbar background." } }, navdrawer: { selectors: { angular: "igx-nav-drawer", webcomponents: "igc-nav-drawer" }, aliases: [ "drawer", "side drawer", "side nav", "sidenav", "navigation drawer", "navigation panel" ] }, "nav-drawer-item": { childOf: "navdrawer" }, overlay: { selectors: { angular: ".igx-overlay__content", webcomponents: null } }, paginator: { selectors: { angular: "igx-paginator", webcomponents: "igc-paginator" }, aliases: ["pagination", "pager"], compound: { description: "The paginator uses combo and flat-icon-buttons for the page controls.", relatedThemes: ["combo", "flat-icon-button"], guidance: "The combo and flat-icon-button themes should visually coordinate with each other and the overall paginator background." } }, "pivot-data-selector": { selectors: { angular: "igx-pivot-data-selector", webcomponents: "igc-pivot-data-selector" }, compound: { description: "The pivot data selector uses checkboxes, expansion panels, lists, and chips.", relatedThemes: [ "checkbox", "expansion-panel", "chip", "list" ], guidance: `The pivot data selector uses checkboxes for field selection, expansion panels for grouping, \ chips for displaying selected fields, and lists for field ordering. \ Detailed token derivation rules are not yet available — use the token names \ and descriptions from get_component_design_tokens for each child to guide value selection.` } }, "progress-circular": { selectors: { angular: "igx-circular-bar", webcomponents: "igc-circular-progress" }, aliases: [ "spinner", "circular loader", "loading spinner" ] }, "progress-linear": { selectors: { angular: "igx-linear-bar", webcomponents: "igc-linear-progress" }, aliases: [ "progress-bar", "loading bar", "linear loader" ] }, "query-builder": { selectors: { angular: "igx-query-builder", webcomponents: null }, aliases: ["filter builder"], compound: { description: "The query builder uses inputs, dropdowns, chips, buttons and button-groups for building query expressions.", relatedThemes: [ "input-group", "select", "chip", "flat-button", "outlined-button", "button-group", "flat-icon-button", "outlined-icon-button" ], guidance: `The query builder uses input-groups and selects for expression values and operator/field selection, \ chips for displaying conditions, and buttons/button-groups for adding and grouping expressions.` } }, radio: { selectors: { angular: "igx-radio", webcomponents: "igc-radio" } }, rating: { selectors: { angular: "igc-rating", webcomponents: "igc-rating" }, aliases: ["star rating"] }, ripple: { selectors: { angular: "igx-ripple", webcomponents: "igc-ripple" } }, scrollbar: { selectors: { angular: ".ig-scrollbar", webcomponents: ".ig-scrollbar" } }, select: { selectors: { angular: "igx-select", webcomponents: "igc-select" }, aliases: ["select box"], compound: { description: "The select component combines input-group and drop-down components.", relatedThemes: ["input-group", "drop-down"], tokenDerivations: { "input-group.focused-border-color": { from: "select.toggle-button-background", transform: "identity" }, "drop-down.background-color": { from: "select.toggle-button-background", transform: "identity" } }, guidance: `The select input-group and drop-down should share a consistent color scheme. \ The drop-down background should match the select surface intent.` } }, slider: { selectors: { angular: "igx-slider", webcomponents: "igc-slider" } }, snackbar: { selectors: { angular: "igx-snackbar", webcomponents: "igc-snackbar" } }, splitter: { selectors: { angular: "igx-splitter", webcomponents: "igc-splitter" } }, step: { childOf: "stepper" }, stepper: { selectors: { angular: "igx-stepper", webcomponents: "igc-stepper" } }, switch: { selectors: { angular: "igx-switch", webcomponents: "igc-switch" }, aliases: ["toggle"] }, tabs: { selectors: { angular: "igx-tabs", webcomponents: "igc-tabs" } }, "tab-item": { childOf: "tabs" }, "time-picker": { selectors: { angular: "igx-time-picker", webcomponents: null }, compound: { description: "The time picker uses an input-group for the input field.", relatedThemes: [ "input-group", "time-picker", "flat-button" ], guidance: `The time-picker input-group and the time-picker dial should share a consistent color scheme. \ The input-group text color should coordinate with the time-picker header.` } }, textarea: { selectors: { angular: ".igx-input-group--textarea-group", webcomponents: "igc-textarea" }, theme: "input-group" }, toast: { selectors: { angular: "igx-toast", webcomponents: "igc-toast" } }, tooltip: { selectors: { angular: ".igx-tooltip", webcomponents: "igc-tooltip" } }, tree: { selectors: { angular: "igx-tree-node", webcomponents: "igc-tree" } }, watermark: { selectors: { angular: "igc-trial-watermark", webcomponents: "igc-trial-watermark" } } }; new Set(Object.values(COMPONENT_METADATA).filter((m) => m.variants).flatMap((m) => m.variants)); /** * Get the selector(s) for a component on a specific platform. * @param componentName - The component name * @param platform - The target platform * @returns Array of selectors (normalized to always return array), empty array if component not found or not available on platform */ function getComponentSelector(componentName, platform) { const metadata = COMPONENT_METADATA[componentName]; if (!metadata) return []; if (!metadata.selectors) return []; const platformSelectors = platform === "angular" ? metadata.selectors.angular : metadata.selectors.webcomponents; if (platformSelectors === null) return []; return Array.isArray(platformSelectors) ? platformSelectors : [platformSelectors]; } /** * Get the selector(s) to use for theming scope. * For child components (with `childOf`), returns the parent's selectors. * For all other components, returns the component's own selectors. * @param componentName - The component name * @param platform - The target platform * @returns Array of selectors for theming scope, empty array if not found */ function getThemingSelector(componentName, platform) { const metadata = COMPONENT_METADATA[componentName]; if (!metadata) return []; if (metadata.childOf) return getComponentSelector(metadata.childOf, platform); return getComponentSelector(componentName, platform); } /** * Check if a component is available on a specific platform. * @param componentName - The component name * @param platform - The target platform ('angular' or 'webcomponents') * @returns True if the component is available on the platform, false otherwise */ function isComponentAvailable(componentName, platform) { const metadata = COMPONENT_METADATA[componentName]; if (!metadata?.selectors) return false; return (platform === "angular" ? metadata.selectors.angular : metadata.selectors.webcomponents) !== null; } /** * Get platform availability for a component. * @param componentName - The component name * @returns Object indicating availability on each platform, or undefined if component not found */ function getComponentPlatformAvailability(componentName) { const metadata = COMPONENT_METADATA[componentName]; if (!metadata?.selectors) return; return { angular: metadata.selectors.angular !== null, webcomponents: metadata.selectors.webcomponents !== null }; } /** * Check if a component has variants. * @param componentName - The component name (e.g., 'button') * @returns True if the component has variant-specific themes */ function hasVariants(componentName) { return !!COMPONENT_METADATA[componentName]?.variants; } /** * Get variants for a component. * @param componentName - The component name (e.g., 'button') * @returns Array of variant names or empty array */ function getVariants(componentName) { return COMPONENT_METADATA[componentName]?.variants ?? []; } /** * Get compound component info if applicable. * @param componentName - The component name * @returns CompoundInfo or undefined */ function getCompoundComponentInfo(componentName) { return COMPONENT_METADATA[componentName]?.compound; } /** * Check if a component is a compound component. * @param componentName - The component name * @returns True if this is a compound component */ function isCompoundComponent(componentName) { return !!COMPONENT_METADATA[componentName]?.compound; } /** * Get token derivations for a specific child theme within a compound component. * @param compoundName - The compound component name * @param childThemeName - The child theme name (e.g., 'flat-button') * @returns Record of 'childToken' -> TokenDerivation, or empty record if none exist */ function getTokenDerivationsForChild(compoundName, childThemeName) { const compound = COMPONENT_METADATA[compoundName]?.compound; if (!compound?.tokenDerivations) return {}; const prefix = `${childThemeName}.`; const result = {}; for (const [key, derivation] of Object.entries(compound.tokenDerivations)) if (key.startsWith(prefix)) { const childToken = key.slice(prefix.length); result[childToken] = derivation; } return result; } //#endregion export { COMPONENT_METADATA, getComponentPlatformAvailability, getComponentSelector, getCompoundComponentInfo, getThemingSelector, getTokenDerivationsForChild, getVariants, hasVariants, isComponentAvailable, isCompoundComponent };