@nuralyui/icon 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,19 +6,20 @@
6
6
  import { LitElement } from 'lit';
7
7
  import { IconTypes } from './icon.types.js';
8
8
  /**
9
- * Enhanced Icon component with clickable functionality and proper event handling
9
+ * Enhanced Icon component with clickable functionality, custom styling, and comprehensive theming
10
10
  *
11
11
  * @example
12
12
  * ```html
13
- * <hy-icon name="envelope"></hy-icon>
14
- * <hy-icon name="check" clickable @icon-click="${this.handleIconClick}"></hy-icon>
15
- * <hy-icon name="warning" type="regular" disabled></hy-icon>
13
+ * <nr-icon name="envelope"></nr-icon>
14
+ * <nr-icon name="check" clickable @icon-click="${this.handleIconClick}"></nr-icon>
15
+ * <nr-icon name="warning" type="regular" disabled></nr-icon>
16
+ * <nr-icon name="star" color="#ffd700" size="large"></nr-icon>
16
17
  * ```
17
18
  *
18
19
  * @fires icon-click - Dispatched when icon is clicked (contains iconName, iconType, originalEvent, timestamp)
19
20
  * @fires icon-keyboard-activation - Dispatched when icon is activated via keyboard (contains iconName, iconType, key, originalEvent, timestamp)
20
21
  */
21
- declare const IconBaseMixin: (new (...args: any[]) => import("./mixins/clickable-mixin.js").ClickableCapable) & (new (...args: any[]) => import("../../shared/dependency-mixin.js").DependencyAware) & (new (...args: any[]) => import("../../shared/theme-mixin.js").ThemeAware) & (new (...args: any[]) => import("../../shared/event-handler-mixin.js").EventHandlerCapable) & typeof LitElement;
22
+ declare const IconBaseMixin: (new (...args: any[]) => import("./mixins/clickable-mixin.js").ClickableCapable) & (new (...args: any[]) => import("@nuralyui/common/mixins").DependencyAware) & (new (...args: any[]) => import("@nuralyui/common/mixins").ThemeAware) & (new (...args: any[]) => import("@nuralyui/common/mixins").EventHandlerCapable) & typeof LitElement;
22
23
  export declare class HyIconElement extends IconBaseMixin {
23
24
  static readonly styles: import("lit").CSSResult[];
24
25
  /** The FontAwesome icon name */
@@ -27,6 +28,14 @@ export declare class HyIconElement extends IconBaseMixin {
27
28
  type: IconTypes;
28
29
  /** Alternative text for accessibility */
29
30
  alt: string;
31
+ /** Icon size (small, medium, large, xlarge, xxlarge) */
32
+ size?: 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge';
33
+ /** Icon color override */
34
+ color?: string;
35
+ /** Custom width override */
36
+ width?: string;
37
+ /** Custom height override */
38
+ height?: string;
30
39
  /**
31
40
  * Validate component properties on update
32
41
  */
package/icon.component.js CHANGED
@@ -19,16 +19,17 @@ library.add(fas, far);
19
19
  dom.watch();
20
20
  import { styles } from './icon.style.js';
21
21
  import { regularIconPack, solidIconPack } from './icon.types.js';
22
- import { NuralyUIBaseMixin } from '../../shared/base-mixin.js';
22
+ import { NuralyUIBaseMixin } from '@nuralyui/common/mixins';
23
23
  import { ClickableMixin } from './mixins/index.js';
24
24
  /**
25
- * Enhanced Icon component with clickable functionality and proper event handling
25
+ * Enhanced Icon component with clickable functionality, custom styling, and comprehensive theming
26
26
  *
27
27
  * @example
28
28
  * ```html
29
- * <hy-icon name="envelope"></hy-icon>
30
- * <hy-icon name="check" clickable @icon-click="${this.handleIconClick}"></hy-icon>
31
- * <hy-icon name="warning" type="regular" disabled></hy-icon>
29
+ * <nr-icon name="envelope"></nr-icon>
30
+ * <nr-icon name="check" clickable @icon-click="${this.handleIconClick}"></nr-icon>
31
+ * <nr-icon name="warning" type="regular" disabled></nr-icon>
32
+ * <nr-icon name="star" color="#ffd700" size="large"></nr-icon>
32
33
  * ```
33
34
  *
34
35
  * @fires icon-click - Dispatched when icon is clicked (contains iconName, iconType, originalEvent, timestamp)
@@ -56,15 +57,39 @@ let HyIconElement = class HyIconElement extends IconBaseMixin {
56
57
  console.warn(`HyIconElement: Invalid type "${this.type}". Using default "${"solid" /* IconTypes.Solid */}"`);
57
58
  this.type = "solid" /* IconTypes.Solid */;
58
59
  }
60
+ if (changedProperties.has('size') && this.size) {
61
+ const validSizes = ['small', 'medium', 'large', 'xlarge', 'xxlarge'];
62
+ if (!validSizes.includes(this.size)) {
63
+ console.warn(`HyIconElement: Invalid size "${this.size}". Valid sizes are: ${validSizes.join(', ')}`);
64
+ }
65
+ }
59
66
  }
60
67
  render() {
61
68
  const iconPath = this.getIconPath();
62
69
  const role = this.getIconRole();
63
70
  const tabIndex = this.getIconTabIndex();
64
71
  const ariaDisabled = this.getAriaDisabled();
72
+ // Build dynamic styles using CSS custom properties
73
+ let dynamicStyles = '';
74
+ if (this.color) {
75
+ dynamicStyles += `--nuraly-color-icon: ${this.color};`;
76
+ }
77
+ if (this.width) {
78
+ dynamicStyles += `width: ${this.width};`;
79
+ }
80
+ if (this.height) {
81
+ dynamicStyles += `height: ${this.height};`;
82
+ }
83
+ // Build CSS classes
84
+ const cssClasses = [
85
+ 'svg-icon',
86
+ this.clickable ? 'clickable' : '',
87
+ this.disabled ? 'disabled' : ''
88
+ ].filter(Boolean).join(' ');
65
89
  return html `
66
90
  <svg
67
- class="svg-icon ${this.clickable ? 'clickable' : ''} ${this.disabled ? 'disabled' : ''}"
91
+ class="${cssClasses}"
92
+ style="${dynamicStyles}"
68
93
  xmlns="http://www.w3.org/2000/svg"
69
94
  viewBox="0 0 550 550"
70
95
  role="${role}"
@@ -144,8 +169,20 @@ __decorate([
144
169
  __decorate([
145
170
  property({ type: String, attribute: 'alt' })
146
171
  ], HyIconElement.prototype, "alt", void 0);
172
+ __decorate([
173
+ property({ type: String, reflect: true })
174
+ ], HyIconElement.prototype, "size", void 0);
175
+ __decorate([
176
+ property({ type: String })
177
+ ], HyIconElement.prototype, "color", void 0);
178
+ __decorate([
179
+ property({ type: String })
180
+ ], HyIconElement.prototype, "width", void 0);
181
+ __decorate([
182
+ property({ type: String })
183
+ ], HyIconElement.prototype, "height", void 0);
147
184
  HyIconElement = __decorate([
148
- customElement('hy-icon')
185
+ customElement('nr-icon')
149
186
  ], HyIconElement);
150
187
  export { HyIconElement };
151
188
  //# sourceMappingURL=icon.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"icon.component.js","sourceRoot":"","sources":["../../../src/components/icon/icon.component.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * @license\n * Copyright 2023 Nuraly Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { library, dom } from '@fortawesome/fontawesome-svg-core';\nimport { far } from '@fortawesome/free-regular-svg-icons';\nimport { fas } from '@fortawesome/free-solid-svg-icons';\nlibrary.add(fas, far);\ndom.watch();\n\nimport { styles } from './icon.style.js';\nimport { IconTypes, regularIconPack, solidIconPack } from './icon.types.js';\nimport { NuralyUIBaseMixin } from '../../shared/base-mixin.js';\nimport { ClickableMixin } from './mixins/index.js';\n\n/**\n * Enhanced Icon component with clickable functionality and proper event handling\n * \n * @example\n * ```html\n * <hy-icon name=\"envelope\"></hy-icon>\n * <hy-icon name=\"check\" clickable @icon-click=\"${this.handleIconClick}\"></hy-icon>\n * <hy-icon name=\"warning\" type=\"regular\" disabled></hy-icon>\n * ```\n * \n * @fires icon-click - Dispatched when icon is clicked (contains iconName, iconType, originalEvent, timestamp)\n * @fires icon-keyboard-activation - Dispatched when icon is activated via keyboard (contains iconName, iconType, key, originalEvent, timestamp)\n */\n\nconst IconBaseMixin = ClickableMixin(NuralyUIBaseMixin(LitElement));\n@customElement('hy-icon')\nexport class HyIconElement extends IconBaseMixin {\n static override readonly styles = styles;\n\n /** The FontAwesome icon name */\n @property({type: String})\n name!: string;\n\n /** The icon type (solid or regular) */\n @property()\n type = IconTypes.Solid;\n\n /** Alternative text for accessibility */\n @property({type: String, attribute: 'alt'})\n alt = '';\n\n /**\n * Validate component properties on update\n */\n override willUpdate(changedProperties: Map<string, any>) {\n super.willUpdate(changedProperties);\n \n if (changedProperties.has('name') && !this.name) {\n console.error('HyIconElement: \"name\" property is required');\n }\n \n if (changedProperties.has('type') && \n this.type !== IconTypes.Solid && this.type !== IconTypes.Regular) {\n console.warn(`HyIconElement: Invalid type \"${this.type}\". Using default \"${IconTypes.Solid}\"`);\n this.type = IconTypes.Solid;\n }\n }\n override render() {\n const iconPath = this.getIconPath();\n const role = this.getIconRole();\n const tabIndex = this.getIconTabIndex();\n const ariaDisabled = this.getAriaDisabled();\n \n return html`\n <svg \n class=\"svg-icon ${this.clickable ? 'clickable' : ''} ${this.disabled ? 'disabled' : ''}\"\n xmlns=\"http://www.w3.org/2000/svg\" \n viewBox=\"0 0 550 550\"\n role=\"${role}\"\n tabindex=\"${tabIndex}\"\n aria-label=\"${this.alt || this.name}\"\n aria-disabled=\"${ariaDisabled || 'false'}\"\n data-theme=\"${this.currentTheme}\"\n @click=\"${this.clickable ? this.handleIconClick : undefined}\"\n @keydown=\"${this.clickable ? this.handleIconKeydown : undefined}\"\n >\n <path d=\"${iconPath}\" />\n </svg>\n `;\n }\n getIconPath() {\n if (!this.name) {\n console.warn('HyIconElement: Icon name is required');\n return '';\n }\n\n const iconPack = this.type == IconTypes.Solid ? solidIconPack : regularIconPack;\n \n try {\n const definitions = (library as any).definitions;\n if (!definitions || !definitions[iconPack]) {\n console.warn(`HyIconElement: Icon pack \"${iconPack}\" not found`);\n return '';\n }\n\n const iconDefinition = definitions[iconPack][this.name];\n if (!iconDefinition) {\n console.warn(`HyIconElement: Icon \"${this.name}\" not found in ${iconPack} pack`);\n return '';\n }\n\n // Validate that the path data exists\n const pathData = iconDefinition[4];\n if (!pathData || typeof pathData !== 'string') {\n console.warn(`HyIconElement: Invalid path data for icon \"${this.name}\"`);\n return '';\n }\n\n return pathData;\n } catch (error) {\n console.error(`HyIconElement: Error loading icon \"${this.name}\":`, error);\n return '';\n }\n }\n\n /**\n * Get the appropriate ARIA role for the icon\n */\n override getIconRole(): string {\n if (this.clickable) {\n return 'button';\n }\n return this.alt ? 'img' : 'presentation';\n }\n\n /**\n * Get the appropriate tabindex for the icon\n */\n override getIconTabIndex(): string {\n if (this.clickable && !this.disabled) {\n return '0';\n }\n return '-1';\n }\n\n /**\n * Get the appropriate aria-disabled value\n */\n override getAriaDisabled(): string | undefined {\n return this.disabled ? 'true' : undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"icon.component.js","sourceRoot":"","sources":["../../../src/components/icon/icon.component.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * @license\n * Copyright 2023 Nuraly Laabidi Aymen\n * SPDX-License-Identifier: MIT\n */\n\nimport { LitElement, html } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { library, dom } from '@fortawesome/fontawesome-svg-core';\nimport { far } from '@fortawesome/free-regular-svg-icons';\nimport { fas } from '@fortawesome/free-solid-svg-icons';\nlibrary.add(fas, far);\ndom.watch();\n\nimport { styles } from './icon.style.js';\nimport { IconTypes, regularIconPack, solidIconPack } from './icon.types.js';\nimport { NuralyUIBaseMixin } from '@nuralyui/common/mixins';\nimport { ClickableMixin } from './mixins/index.js';\n\n/**\n * Enhanced Icon component with clickable functionality, custom styling, and comprehensive theming\n * \n * @example\n * ```html\n * <nr-icon name=\"envelope\"></nr-icon>\n * <nr-icon name=\"check\" clickable @icon-click=\"${this.handleIconClick}\"></nr-icon>\n * <nr-icon name=\"warning\" type=\"regular\" disabled></nr-icon>\n * <nr-icon name=\"star\" color=\"#ffd700\" size=\"large\"></nr-icon>\n * ```\n * \n * @fires icon-click - Dispatched when icon is clicked (contains iconName, iconType, originalEvent, timestamp)\n * @fires icon-keyboard-activation - Dispatched when icon is activated via keyboard (contains iconName, iconType, key, originalEvent, timestamp)\n */\n\nconst IconBaseMixin = ClickableMixin(NuralyUIBaseMixin(LitElement));\n@customElement('nr-icon')\nexport class HyIconElement extends IconBaseMixin {\n static override readonly styles = styles;\n\n /** The FontAwesome icon name */\n @property({type: String})\n name!: string;\n\n /** The icon type (solid or regular) */\n @property()\n type = IconTypes.Solid;\n\n /** Alternative text for accessibility */\n @property({type: String, attribute: 'alt'})\n alt = '';\n\n /** Icon size (small, medium, large, xlarge, xxlarge) */\n @property({type: String, reflect: true})\n size?: 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge';\n\n /** Icon color override */\n @property({type: String})\n color?: string;\n\n /** Custom width override */\n @property({type: String})\n width?: string;\n\n /** Custom height override */\n @property({type: String})\n height?: string;\n\n /**\n * Validate component properties on update\n */\n override willUpdate(changedProperties: Map<string, any>) {\n super.willUpdate(changedProperties);\n \n if (changedProperties.has('name') && !this.name) {\n console.error('HyIconElement: \"name\" property is required');\n }\n \n if (changedProperties.has('type') && \n this.type !== IconTypes.Solid && this.type !== IconTypes.Regular) {\n console.warn(`HyIconElement: Invalid type \"${this.type}\". Using default \"${IconTypes.Solid}\"`);\n this.type = IconTypes.Solid;\n }\n\n if (changedProperties.has('size') && this.size) {\n const validSizes = ['small', 'medium', 'large', 'xlarge', 'xxlarge'];\n if (!validSizes.includes(this.size)) {\n console.warn(`HyIconElement: Invalid size \"${this.size}\". Valid sizes are: ${validSizes.join(', ')}`);\n }\n }\n }\n override render() {\n const iconPath = this.getIconPath();\n const role = this.getIconRole();\n const tabIndex = this.getIconTabIndex();\n const ariaDisabled = this.getAriaDisabled();\n \n // Build dynamic styles using CSS custom properties\n let dynamicStyles = '';\n if (this.color) {\n dynamicStyles += `--nuraly-color-icon: ${this.color};`;\n }\n if (this.width) {\n dynamicStyles += `width: ${this.width};`;\n }\n if (this.height) {\n dynamicStyles += `height: ${this.height};`;\n }\n \n // Build CSS classes\n const cssClasses = [\n 'svg-icon',\n this.clickable ? 'clickable' : '',\n this.disabled ? 'disabled' : ''\n ].filter(Boolean).join(' ');\n \n return html`\n <svg \n class=\"${cssClasses}\"\n style=\"${dynamicStyles}\"\n xmlns=\"http://www.w3.org/2000/svg\" \n viewBox=\"0 0 550 550\"\n role=\"${role}\"\n tabindex=\"${tabIndex}\"\n aria-label=\"${this.alt || this.name}\"\n aria-disabled=\"${ariaDisabled || 'false'}\"\n data-theme=\"${this.currentTheme}\"\n @click=\"${this.clickable ? this.handleIconClick : undefined}\"\n @keydown=\"${this.clickable ? this.handleIconKeydown : undefined}\"\n >\n <path d=\"${iconPath}\" />\n </svg>\n `;\n }\n getIconPath() {\n if (!this.name) {\n console.warn('HyIconElement: Icon name is required');\n return '';\n }\n\n const iconPack = this.type == IconTypes.Solid ? solidIconPack : regularIconPack;\n \n try {\n const definitions = (library as any).definitions;\n if (!definitions || !definitions[iconPack]) {\n console.warn(`HyIconElement: Icon pack \"${iconPack}\" not found`);\n return '';\n }\n\n const iconDefinition = definitions[iconPack][this.name];\n if (!iconDefinition) {\n console.warn(`HyIconElement: Icon \"${this.name}\" not found in ${iconPack} pack`);\n return '';\n }\n\n // Validate that the path data exists\n const pathData = iconDefinition[4];\n if (!pathData || typeof pathData !== 'string') {\n console.warn(`HyIconElement: Invalid path data for icon \"${this.name}\"`);\n return '';\n }\n\n return pathData;\n } catch (error) {\n console.error(`HyIconElement: Error loading icon \"${this.name}\":`, error);\n return '';\n }\n }\n\n /**\n * Get the appropriate ARIA role for the icon\n */\n override getIconRole(): string {\n if (this.clickable) {\n return 'button';\n }\n return this.alt ? 'img' : 'presentation';\n }\n\n /**\n * Get the appropriate tabindex for the icon\n */\n override getIconTabIndex(): string {\n if (this.clickable && !this.disabled) {\n return '0';\n }\n return '-1';\n }\n\n /**\n * Get the appropriate aria-disabled value\n */\n override getAriaDisabled(): string | undefined {\n return this.disabled ? 'true' : undefined;\n }\n}\n"]}
package/icon.style.js CHANGED
@@ -1,26 +1,53 @@
1
1
  import { css } from 'lit';
2
2
  import { styleVariables } from './icon.variables.js';
3
3
  /**
4
- * Icon component styles with theme support and interactive states
4
+ * Icon component styles for the Hybrid UI Library
5
5
  *
6
- * Uses CSS custom properties for theming with fallbacks for backwards compatibility.
7
- * Supports both light and dark themes via data-theme attribute.
6
+ * This file contains all the styling for the nr-icon component, including:
7
+ * - Base icon styles with CSS custom properties for theming
8
+ * - Multiple icon states (default, hover, active, disabled, focus)
9
+ * - Size variations (small, medium, large, custom)
10
+ * - Interactive states for clickable icons
11
+ * - Theme compatibility (light, dark, carbon, default design systems)
12
+ * - Accessibility features and reduced motion support
13
+ *
14
+ * The styling system uses CSS custom properties with fallbacks to allow
15
+ * for both global and local customization of icon appearance.
8
16
  */
9
- const iconStyles = css `
17
+ const iconStyle = css `
18
+ /*
19
+ * Host element base styles
20
+ * Container for the icon component with flexible positioning
21
+ */
10
22
  :host {
11
- display: inline-block;
12
- line-height: 0;
23
+ display: inline-flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ line-height: 1;
27
+ vertical-align: baseline;
28
+ position: relative;
29
+ font-family: var(--nuraly-font-family-icon, 'IBM Plex Sans', ui-sans-serif, system-ui);
13
30
  }
14
31
 
32
+ /*
33
+ * Base SVG icon styles
34
+ * Uses theme CSS custom properties for comprehensive theming support
35
+ */
15
36
  .svg-icon {
16
- /* Basic properties */
17
- fill: var(--hybrid-icon-local-color, var(--hybrid-icon-color, #000000));
18
- width: var(--hybrid-icon-local-width, var(--hybrid-icon-width, 18px));
19
- height: var(--hybrid-icon-local-height, var(--hybrid-icon-height, 18px));
20
- transition: var(--hybrid-icon-local-transition, opacity 0.2s ease, transform 0.2s ease);
37
+ /* Basic properties with theme support */
38
+ fill: var(--nuraly-color-icon, var(--nuraly-color-icon-fallback, #161616));
39
+ width: var(--nuraly-icon-size, var(--nuraly-icon-size-fallback, 18px));
40
+ height: var(--nuraly-icon-size, var(--nuraly-icon-size-fallback, 18px));
41
+ min-width: var(--nuraly-icon-min-size, var(--nuraly-icon-min-size-fallback, 16px));
42
+ min-height: var(--nuraly-icon-min-size, var(--nuraly-icon-min-size-fallback, 16px));
43
+
44
+ /* Transition and display properties */
45
+ transition: var(--nuraly-icon-transition, var(--nuraly-icon-transition-fallback, opacity 0.2s ease, transform 0.2s ease, fill 0.2s ease));
46
+ display: block;
47
+ flex-shrink: 0;
21
48
 
22
49
  /* Cursor handling */
23
- cursor: default;
50
+ cursor: var(--nuraly-cursor-default, default);
24
51
  }
25
52
 
26
53
  /* ========================================
@@ -28,26 +55,27 @@ const iconStyles = css `
28
55
  * ======================================== */
29
56
 
30
57
  .svg-icon.clickable {
31
- cursor: var(--hybrid-icon-local-cursor, pointer);
58
+ cursor: var(--nuraly-cursor-interactive, pointer);
32
59
  }
33
60
 
34
61
  .svg-icon.clickable:hover {
35
- opacity: var(--hybrid-icon-local-hover-opacity, 0.8);
36
- transform: var(--hybrid-icon-local-hover-transform, scale(1.1));
37
- fill: var(--hybrid-icon-local-hover-color, var(--hybrid-icon-local-color, #0f62fe));
62
+ opacity: var(--nuraly-icon-hover-opacity, var(--nuraly-icon-hover-opacity-fallback, 0.8));
63
+ transform: var(--nuraly-icon-hover-transform, var(--nuraly-icon-hover-transform-fallback, scale(1.05)));
64
+ fill: var(--nuraly-color-icon-hover, var(--nuraly-color-icon-hover-fallback, #0f62fe));
38
65
  }
39
66
 
40
67
  .svg-icon.clickable:active {
41
- opacity: var(--hybrid-icon-local-active-opacity, 0.6);
42
- transform: var(--hybrid-icon-local-active-transform, scale(0.95));
43
- fill: var(--hybrid-icon-local-active-color, var(--hybrid-icon-local-color, #054ada));
68
+ opacity: var(--nuraly-icon-active-opacity, var(--nuraly-icon-active-opacity-fallback, 0.6));
69
+ transform: var(--nuraly-icon-active-transform, var(--nuraly-icon-active-transform-fallback, scale(0.95)));
70
+ fill: var(--nuraly-color-icon-active, var(--nuraly-color-icon-active-fallback, #054ada));
44
71
  }
45
72
 
46
73
  .svg-icon.clickable:focus {
47
- outline: var(--hybrid-icon-local-focus-outline, 2px solid #0f62fe);
48
- outline-offset: var(--hybrid-icon-local-focus-outline-offset, 2px);
49
- background: var(--hybrid-icon-local-focus-background, rgba(15, 98, 254, 0.1));
50
- border-radius: var(--hybrid-icon-local-focus-border-radius, 4px);
74
+ outline: var(--nuraly-icon-focus-outline, var(--nuraly-icon-focus-outline-fallback, 2px solid #0f62fe));
75
+ outline-offset: var(--nuraly-icon-focus-outline-offset, var(--nuraly-icon-focus-outline-offset-fallback, 2px));
76
+ background: var(--nuraly-icon-focus-background, var(--nuraly-icon-focus-background-fallback, rgba(15, 98, 254, 0.1)));
77
+ border-radius: var(--nuraly-icon-focus-border-radius, var(--nuraly-icon-focus-border-radius-fallback, 4px));
78
+ box-shadow: var(--nuraly-icon-focus-shadow, var(--nuraly-icon-focus-shadow-fallback, none));
51
79
  }
52
80
 
53
81
  /* ========================================
@@ -55,22 +83,102 @@ const iconStyles = css `
55
83
  * ======================================== */
56
84
 
57
85
  .svg-icon.disabled {
58
- opacity: var(--hybrid-icon-local-disabled-opacity, 0.4);
59
- fill: var(--hybrid-icon-local-disabled-color, #c6c6c6);
60
- cursor: var(--hybrid-icon-local-disabled-cursor, not-allowed);
86
+ opacity: var(--nuraly-icon-disabled-opacity, var(--nuraly-icon-disabled-opacity-fallback, 0.25));
87
+ fill: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));
88
+ cursor: var(--nuraly-cursor-disabled, not-allowed);
61
89
  }
62
90
 
63
91
  .svg-icon.clickable.disabled:hover,
64
92
  .svg-icon.clickable.disabled:active {
65
- opacity: var(--hybrid-icon-local-disabled-opacity, 0.4);
66
- fill: var(--hybrid-icon-local-disabled-color, #c6c6c6);
93
+ opacity: var(--nuraly-icon-disabled-opacity, var(--nuraly-icon-disabled-opacity-fallback, 0.25));
94
+ fill: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));
67
95
  transform: none;
68
96
  }
69
97
 
70
98
  .svg-icon.clickable.disabled:focus {
71
99
  outline: none;
72
100
  background: none;
101
+ box-shadow: none;
102
+ }
103
+
104
+ /* ========================================
105
+ * ACCESSIBILITY FEATURES
106
+ * ======================================== */
107
+
108
+ /* Screen reader only text for better accessibility */
109
+ .sr-only {
110
+ position: absolute;
111
+ width: 1px;
112
+ height: 1px;
113
+ padding: 0;
114
+ margin: -1px;
115
+ overflow: hidden;
116
+ clip: rect(0, 0, 0, 0);
117
+ white-space: nowrap;
118
+ border: 0;
119
+ }
120
+
121
+ /* High contrast mode support */
122
+ @media (prefers-contrast: high) {
123
+ .svg-icon {
124
+ fill: CanvasText;
125
+ }
126
+
127
+ .svg-icon.disabled {
128
+ opacity: 0.5;
129
+ }
130
+ }
131
+
132
+ /* Reduced motion support */
133
+ @media (prefers-reduced-motion: reduce) {
134
+ .svg-icon {
135
+ transition: none;
136
+ }
137
+
138
+ .svg-icon.clickable:hover,
139
+ .svg-icon.clickable:active {
140
+ transform: none;
141
+ }
142
+ }
143
+ `;
144
+ /**
145
+ * Size variation styles for the icon component
146
+ * Defines size variations for different icon use cases
147
+ */
148
+ const sizeIconStyle = css `
149
+ /* ========================================
150
+ * SIZE VARIATIONS
151
+ * ======================================== */
152
+
153
+ /* Small icon size */
154
+ :host([size='small']) .svg-icon {
155
+ width: var(--nuraly-icon-size-small, var(--nuraly-icon-size-small-fallback, 16px));
156
+ height: var(--nuraly-icon-size-small, var(--nuraly-icon-size-small-fallback, 16px));
157
+ }
158
+
159
+ /* Medium icon size (default) */
160
+ :host([size='medium']) .svg-icon {
161
+ width: var(--nuraly-icon-size-medium, var(--nuraly-icon-size-medium-fallback, 20px));
162
+ height: var(--nuraly-icon-size-medium, var(--nuraly-icon-size-medium-fallback, 20px));
163
+ }
164
+
165
+ /* Large icon size */
166
+ :host([size='large']) .svg-icon {
167
+ width: var(--nuraly-icon-size-large, var(--nuraly-icon-size-large-fallback, 24px));
168
+ height: var(--nuraly-icon-size-large, var(--nuraly-icon-size-large-fallback, 24px));
169
+ }
170
+
171
+ /* Extra large icon size */
172
+ :host([size='xlarge']) .svg-icon {
173
+ width: var(--nuraly-icon-size-xlarge, var(--nuraly-icon-size-xlarge-fallback, 32px));
174
+ height: var(--nuraly-icon-size-xlarge, var(--nuraly-icon-size-xlarge-fallback, 32px));
175
+ }
176
+
177
+ /* 2X large icon size */
178
+ :host([size='xxlarge']) .svg-icon {
179
+ width: var(--nuraly-icon-size-xxlarge, var(--nuraly-icon-size-xxlarge-fallback, 40px));
180
+ height: var(--nuraly-icon-size-xxlarge, var(--nuraly-icon-size-xxlarge-fallback, 40px));
73
181
  }
74
182
  `;
75
- export const styles = [iconStyles, styleVariables];
183
+ export const styles = [iconStyle, sizeIconStyle, styleVariables];
76
184
  //# sourceMappingURL=icon.style.js.map
package/icon.style.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"icon.style.js","sourceRoot":"","sources":["../../../src/components/icon/icon.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,OAAO,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,UAAU,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiErB,CAAC;AACF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC","sourcesContent":["import {css} from 'lit';\nimport {styleVariables} from './icon.variables.js';\n\n/**\n * Icon component styles with theme support and interactive states\n * \n * Uses CSS custom properties for theming with fallbacks for backwards compatibility.\n * Supports both light and dark themes via data-theme attribute.\n */\nconst iconStyles = css`\n :host {\n display: inline-block;\n line-height: 0;\n }\n\n .svg-icon {\n /* Basic properties */\n fill: var(--hybrid-icon-local-color, var(--hybrid-icon-color, #000000));\n width: var(--hybrid-icon-local-width, var(--hybrid-icon-width, 18px));\n height: var(--hybrid-icon-local-height, var(--hybrid-icon-height, 18px));\n transition: var(--hybrid-icon-local-transition, opacity 0.2s ease, transform 0.2s ease);\n \n /* Cursor handling */\n cursor: default;\n }\n\n /* ========================================\n * CLICKABLE STATES\n * ======================================== */\n \n .svg-icon.clickable {\n cursor: var(--hybrid-icon-local-cursor, pointer);\n }\n\n .svg-icon.clickable:hover {\n opacity: var(--hybrid-icon-local-hover-opacity, 0.8);\n transform: var(--hybrid-icon-local-hover-transform, scale(1.1));\n fill: var(--hybrid-icon-local-hover-color, var(--hybrid-icon-local-color, #0f62fe));\n }\n\n .svg-icon.clickable:active {\n opacity: var(--hybrid-icon-local-active-opacity, 0.6);\n transform: var(--hybrid-icon-local-active-transform, scale(0.95));\n fill: var(--hybrid-icon-local-active-color, var(--hybrid-icon-local-color, #054ada));\n }\n\n .svg-icon.clickable:focus {\n outline: var(--hybrid-icon-local-focus-outline, 2px solid #0f62fe);\n outline-offset: var(--hybrid-icon-local-focus-outline-offset, 2px);\n background: var(--hybrid-icon-local-focus-background, rgba(15, 98, 254, 0.1));\n border-radius: var(--hybrid-icon-local-focus-border-radius, 4px);\n }\n\n /* ========================================\n * DISABLED STATE\n * ======================================== */\n \n .svg-icon.disabled {\n opacity: var(--hybrid-icon-local-disabled-opacity, 0.4);\n fill: var(--hybrid-icon-local-disabled-color, #c6c6c6);\n cursor: var(--hybrid-icon-local-disabled-cursor, not-allowed);\n }\n\n .svg-icon.clickable.disabled:hover,\n .svg-icon.clickable.disabled:active {\n opacity: var(--hybrid-icon-local-disabled-opacity, 0.4);\n fill: var(--hybrid-icon-local-disabled-color, #c6c6c6);\n transform: none;\n }\n\n .svg-icon.clickable.disabled:focus {\n outline: none;\n background: none;\n }\n`;\nexport const styles = [iconStyles, styleVariables];\n"]}
1
+ {"version":3,"file":"icon.style.js","sourceRoot":"","sources":["../../../src/components/icon/icon.style.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;;;;;;;;;;GAaG;AAEH,MAAM,SAAS,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8HpB,CAAC;AAEF;;;GAGG;AACH,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCxB,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC","sourcesContent":["import { css } from 'lit';\nimport { styleVariables } from './icon.variables.js';\n\n/**\n * Icon component styles for the Hybrid UI Library\n * \n * This file contains all the styling for the nr-icon component, including:\n * - Base icon styles with CSS custom properties for theming\n * - Multiple icon states (default, hover, active, disabled, focus)\n * - Size variations (small, medium, large, custom)\n * - Interactive states for clickable icons\n * - Theme compatibility (light, dark, carbon, default design systems)\n * - Accessibility features and reduced motion support\n * \n * The styling system uses CSS custom properties with fallbacks to allow\n * for both global and local customization of icon appearance.\n */\n\nconst iconStyle = css`\n /* \n * Host element base styles\n * Container for the icon component with flexible positioning\n */\n :host {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n vertical-align: baseline;\n position: relative;\n font-family: var(--nuraly-font-family-icon, 'IBM Plex Sans', ui-sans-serif, system-ui);\n }\n\n /* \n * Base SVG icon styles\n * Uses theme CSS custom properties for comprehensive theming support\n */\n .svg-icon {\n /* Basic properties with theme support */\n fill: var(--nuraly-color-icon, var(--nuraly-color-icon-fallback, #161616));\n width: var(--nuraly-icon-size, var(--nuraly-icon-size-fallback, 18px));\n height: var(--nuraly-icon-size, var(--nuraly-icon-size-fallback, 18px));\n min-width: var(--nuraly-icon-min-size, var(--nuraly-icon-min-size-fallback, 16px));\n min-height: var(--nuraly-icon-min-size, var(--nuraly-icon-min-size-fallback, 16px));\n \n /* Transition and display properties */\n transition: var(--nuraly-icon-transition, var(--nuraly-icon-transition-fallback, opacity 0.2s ease, transform 0.2s ease, fill 0.2s ease));\n display: block;\n flex-shrink: 0;\n \n /* Cursor handling */\n cursor: var(--nuraly-cursor-default, default);\n }\n\n /* ========================================\n * CLICKABLE STATES\n * ======================================== */\n \n .svg-icon.clickable {\n cursor: var(--nuraly-cursor-interactive, pointer);\n }\n\n .svg-icon.clickable:hover {\n opacity: var(--nuraly-icon-hover-opacity, var(--nuraly-icon-hover-opacity-fallback, 0.8));\n transform: var(--nuraly-icon-hover-transform, var(--nuraly-icon-hover-transform-fallback, scale(1.05)));\n fill: var(--nuraly-color-icon-hover, var(--nuraly-color-icon-hover-fallback, #0f62fe));\n }\n\n .svg-icon.clickable:active {\n opacity: var(--nuraly-icon-active-opacity, var(--nuraly-icon-active-opacity-fallback, 0.6));\n transform: var(--nuraly-icon-active-transform, var(--nuraly-icon-active-transform-fallback, scale(0.95)));\n fill: var(--nuraly-color-icon-active, var(--nuraly-color-icon-active-fallback, #054ada));\n }\n\n .svg-icon.clickable:focus {\n outline: var(--nuraly-icon-focus-outline, var(--nuraly-icon-focus-outline-fallback, 2px solid #0f62fe));\n outline-offset: var(--nuraly-icon-focus-outline-offset, var(--nuraly-icon-focus-outline-offset-fallback, 2px));\n background: var(--nuraly-icon-focus-background, var(--nuraly-icon-focus-background-fallback, rgba(15, 98, 254, 0.1)));\n border-radius: var(--nuraly-icon-focus-border-radius, var(--nuraly-icon-focus-border-radius-fallback, 4px));\n box-shadow: var(--nuraly-icon-focus-shadow, var(--nuraly-icon-focus-shadow-fallback, none));\n }\n\n /* ========================================\n * DISABLED STATE\n * ======================================== */\n \n .svg-icon.disabled {\n opacity: var(--nuraly-icon-disabled-opacity, var(--nuraly-icon-disabled-opacity-fallback, 0.25));\n fill: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));\n cursor: var(--nuraly-cursor-disabled, not-allowed);\n }\n\n .svg-icon.clickable.disabled:hover,\n .svg-icon.clickable.disabled:active {\n opacity: var(--nuraly-icon-disabled-opacity, var(--nuraly-icon-disabled-opacity-fallback, 0.25));\n fill: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));\n transform: none;\n }\n\n .svg-icon.clickable.disabled:focus {\n outline: none;\n background: none;\n box-shadow: none;\n }\n\n /* ========================================\n * ACCESSIBILITY FEATURES\n * ======================================== */\n\n /* Screen reader only text for better accessibility */\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* High contrast mode support */\n @media (prefers-contrast: high) {\n .svg-icon {\n fill: CanvasText;\n }\n \n .svg-icon.disabled {\n opacity: 0.5;\n }\n }\n\n /* Reduced motion support */\n @media (prefers-reduced-motion: reduce) {\n .svg-icon {\n transition: none;\n }\n \n .svg-icon.clickable:hover,\n .svg-icon.clickable:active {\n transform: none;\n }\n }\n`;\n\n/**\n * Size variation styles for the icon component\n * Defines size variations for different icon use cases\n */\nconst sizeIconStyle = css`\n /* ========================================\n * SIZE VARIATIONS\n * ======================================== */\n\n /* Small icon size */\n :host([size='small']) .svg-icon {\n width: var(--nuraly-icon-size-small, var(--nuraly-icon-size-small-fallback, 16px));\n height: var(--nuraly-icon-size-small, var(--nuraly-icon-size-small-fallback, 16px));\n }\n\n /* Medium icon size (default) */\n :host([size='medium']) .svg-icon {\n width: var(--nuraly-icon-size-medium, var(--nuraly-icon-size-medium-fallback, 20px));\n height: var(--nuraly-icon-size-medium, var(--nuraly-icon-size-medium-fallback, 20px));\n }\n\n /* Large icon size */\n :host([size='large']) .svg-icon {\n width: var(--nuraly-icon-size-large, var(--nuraly-icon-size-large-fallback, 24px));\n height: var(--nuraly-icon-size-large, var(--nuraly-icon-size-large-fallback, 24px));\n }\n\n /* Extra large icon size */\n :host([size='xlarge']) .svg-icon {\n width: var(--nuraly-icon-size-xlarge, var(--nuraly-icon-size-xlarge-fallback, 32px));\n height: var(--nuraly-icon-size-xlarge, var(--nuraly-icon-size-xlarge-fallback, 32px));\n }\n\n /* 2X large icon size */\n :host([size='xxlarge']) .svg-icon {\n width: var(--nuraly-icon-size-xxlarge, var(--nuraly-icon-size-xxlarge-fallback, 40px));\n height: var(--nuraly-icon-size-xxlarge, var(--nuraly-icon-size-xxlarge-fallback, 40px));\n }\n`;\n\nexport const styles = [iconStyle, sizeIconStyle, styleVariables];\n"]}
@@ -1,11 +1,17 @@
1
1
  /**
2
2
  * Icon component CSS custom properties (design tokens)
3
3
  *
4
- * This file contains all the CSS custom properties used by the hy-icon component,
5
- * organized by functionality and including both light and dark theme variants.
4
+ * This file contains all the CSS custom properties used by the nr-icon component,
5
+ * organized by functionality and including comprehensive theme support for multiple design systems.
6
6
  *
7
7
  * The styling system uses CSS custom properties with fallbacks to allow
8
- * for both global and local customization of icon appearance.
8
+ * for both global and local customization of icon appearance across different themes:
9
+ * - Light theme (default)
10
+ * - Dark theme
11
+ * - Carbon Design System (light/dark)
12
+ * - Default Design System (light/dark)
13
+ *
14
+ * Design tokens follow the pattern: --nuraly-[component]-[property]-[variant]
9
15
  */
10
16
  export declare const styleVariables: import("lit").CSSResult;
11
17
  //# sourceMappingURL=icon.variables.d.ts.map
package/icon.variables.js CHANGED
@@ -2,80 +2,131 @@ import { css } from 'lit';
2
2
  /**
3
3
  * Icon component CSS custom properties (design tokens)
4
4
  *
5
- * This file contains all the CSS custom properties used by the hy-icon component,
6
- * organized by functionality and including both light and dark theme variants.
5
+ * This file contains all the CSS custom properties used by the nr-icon component,
6
+ * organized by functionality and including comprehensive theme support for multiple design systems.
7
7
  *
8
8
  * The styling system uses CSS custom properties with fallbacks to allow
9
- * for both global and local customization of icon appearance.
9
+ * for both global and local customization of icon appearance across different themes:
10
+ * - Light theme (default)
11
+ * - Dark theme
12
+ * - Carbon Design System (light/dark)
13
+ * - Default Design System (light/dark)
14
+ *
15
+ * Design tokens follow the pattern: --nuraly-[component]-[property]-[variant]
10
16
  */
11
17
  export const styleVariables = css `
12
18
  :host {
13
- /* ----------------------------------------
14
- * BASIC ICON PROPERTIES
15
- * ---------------------------------------- */
16
- --hybrid-icon-local-color: #000000;
17
- --hybrid-icon-local-width: 18px;
18
- --hybrid-icon-local-height: 18px;
19
-
20
- /* ----------------------------------------
21
- * INTERACTIVE STATES
22
- * ---------------------------------------- */
23
- --hybrid-icon-local-transition: opacity 0.2s ease, transform 0.2s ease;
24
- --hybrid-icon-local-hover-opacity: 0.8;
25
- --hybrid-icon-local-hover-transform: scale(1.1);
26
- --hybrid-icon-local-hover-color: #0f62fe;
27
- --hybrid-icon-local-active-opacity: 0.6;
28
- --hybrid-icon-local-active-transform: scale(0.95);
29
- --hybrid-icon-local-active-color: #054ada;
30
- --hybrid-icon-local-disabled-opacity: 0.4;
31
- --hybrid-icon-local-disabled-color: #c6c6c6;
19
+ /* ========================================
20
+ * BASE ICON PROPERTIES
21
+ * ======================================== */
32
22
 
33
- /* ----------------------------------------
34
- * FOCUS STYLES
35
- * ---------------------------------------- */
36
- --hybrid-icon-local-focus-outline: 2px solid #0f62fe;
37
- --hybrid-icon-local-focus-outline-offset: 2px;
38
- --hybrid-icon-local-focus-background: rgba(15, 98, 254, 0.1);
39
- --hybrid-icon-local-focus-border-radius: 4px;
40
-
41
- /* ----------------------------------------
42
- * CURSOR STYLES
43
- * ---------------------------------------- */
44
- --hybrid-icon-local-cursor: pointer;
45
- --hybrid-icon-local-disabled-cursor: not-allowed;
23
+ /* Size properties with fallbacks */
24
+ --nuraly-icon-size-fallback: 18px;
25
+ --nuraly-icon-size-small-fallback: 14px;
26
+ --nuraly-icon-size-medium-fallback: 20px;
27
+ --nuraly-icon-size-large-fallback: 24px;
28
+ --nuraly-icon-size-xlarge-fallback: 32px;
29
+ --nuraly-icon-size-xxlarge-fallback: 40px;
30
+ --nuraly-icon-min-size-fallback: 12px;
31
+
32
+ /* Color properties with theme-aware fallbacks */
33
+ --nuraly-color-icon-fallback: #161616;
34
+
35
+ /* ========================================
36
+ * INTERACTIVE STATE PROPERTIES
37
+ * ======================================== */
38
+
39
+ /* Transition properties */
40
+ --nuraly-icon-transition-fallback: opacity 0.2s ease, transform 0.2s ease, fill 0.2s ease;
41
+
42
+ /* Hover state properties */
43
+ --nuraly-icon-hover-opacity-fallback: 0.8;
44
+ --nuraly-icon-hover-transform-fallback: scale(1.05);
45
+ --nuraly-color-icon-hover-fallback: #0f62fe;
46
+
47
+ /* Active state properties */
48
+ --nuraly-icon-active-opacity-fallback: 0.6;
49
+ --nuraly-icon-active-transform-fallback: scale(0.95);
50
+ --nuraly-color-icon-active-fallback: #054ada;
51
+
52
+ /* Disabled state properties */
53
+ --nuraly-icon-disabled-opacity-fallback: 0.25;
54
+ --nuraly-color-icon-disabled-fallback: #c6c6c6;
55
+
56
+ /* ========================================
57
+ * FOCUS STATE PROPERTIES
58
+ * ======================================== */
59
+
60
+ --nuraly-icon-focus-outline-fallback: 2px solid #0f62fe;
61
+ --nuraly-icon-focus-outline-offset-fallback: 2px;
62
+ --nuraly-icon-focus-background-fallback: rgba(15, 98, 254, 0.1);
63
+ --nuraly-icon-focus-border-radius-fallback: 4px;
64
+ --nuraly-icon-focus-shadow-fallback: none;
65
+
66
+ /* ========================================
67
+ * CURSOR PROPERTIES
68
+ * ======================================== */
69
+
70
+ --nuraly-cursor-default: default;
71
+ --nuraly-cursor-interactive: pointer;
72
+ --nuraly-cursor-disabled: not-allowed;
46
73
  }
47
74
 
48
75
  /* ========================================
49
- * DARK THEME OVERRIDES
76
+ * SIZE-SPECIFIC DESIGN TOKENS
50
77
  * ======================================== */
51
78
 
52
79
  /**
53
- * Dark theme styles using data-theme attribute on the SVG element
54
- * These override the light theme defaults when data-theme="dark" is applied
80
+ * Size-specific customizations that can be overridden in themes
81
+ * These provide defaults that themes can customize for different design systems
55
82
  */
56
- .svg-icon[data-theme="dark"] {
57
- --hybrid-icon-local-color: #ffffff;
58
- --hybrid-icon-local-hover-color: #78a9ff;
59
- --hybrid-icon-local-active-color: #a6c8ff;
60
- --hybrid-icon-local-disabled-color: #6f6f6f;
61
- --hybrid-icon-local-focus-outline: 2px solid #78a9ff;
62
- --hybrid-icon-local-focus-background: rgba(120, 169, 255, 0.1);
83
+
84
+ :host([size="small"]) {
85
+ --nuraly-icon-size: var(--nuraly-icon-size-small, var(--nuraly-icon-size-small-fallback));
86
+ }
87
+
88
+ :host([size="medium"]) {
89
+ --nuraly-icon-size: var(--nuraly-icon-size-medium, var(--nuraly-icon-size-medium-fallback));
90
+ }
91
+
92
+ :host([size="large"]) {
93
+ --nuraly-icon-size: var(--nuraly-icon-size-large, var(--nuraly-icon-size-large-fallback));
94
+ }
95
+
96
+ :host([size="xlarge"]) {
97
+ --nuraly-icon-size: var(--nuraly-icon-size-xlarge, var(--nuraly-icon-size-xlarge-fallback));
98
+ }
99
+
100
+ :host([size="xxlarge"]) {
101
+ --nuraly-icon-size: var(--nuraly-icon-size-xxlarge, var(--nuraly-icon-size-xxlarge-fallback));
63
102
  }
64
103
 
65
104
  /* ========================================
66
- * REDUCED MOTION SUPPORT
105
+ * ACCESSIBILITY DESIGN TOKENS
67
106
  * ======================================== */
68
107
 
69
108
  /**
70
- * Accessibility: Respect user's motion preferences
71
- * Disables animations when user prefers reduced motion
109
+ * Accessibility features that respect user preferences
110
+ * These ensure the component works well for all users
72
111
  */
73
- @media (prefers-reduced-motion: reduce) {
112
+
113
+ /* High contrast mode support */
114
+ @media (prefers-contrast: high) {
74
115
  :host {
75
- --hybrid-icon-local-transition: none;
76
- --hybrid-icon-local-hover-transform: none;
77
- --hybrid-icon-local-active-transform: none;
116
+ --nuraly-color-icon: CanvasText;
117
+ --nuraly-color-icon-hover: CanvasText;
118
+ --nuraly-color-icon-active: CanvasText;
119
+ --nuraly-icon-focus-outline: 3px solid CanvasText;
120
+ --nuraly-icon-focus-background: Canvas;
78
121
  }
79
122
  }
123
+
124
+ /* Reduced motion support */
125
+ @media (prefers-reduced-motion: reduce) {
126
+ :host {
127
+ --nuraly-icon-transition: none;
128
+ --nuraly-icon-hover-transform: none;
129
+ --nuraly-icon-active-transform: none;
130
+ }
80
131
  `;
81
132
  //# sourceMappingURL=icon.variables.js.map