@nuralyui/icon 0.0.10 → 0.0.12

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.
@@ -10,9 +10,9 @@ import { IconTypes } from './icon.types.js';
10
10
  *
11
11
  * @example
12
12
  * ```html
13
- * <nr-icon name="envelope"></nr-icon>
13
+ * <nr-icon name="mail"></nr-icon>
14
14
  * <nr-icon name="check" clickable @icon-click="${this.handleIconClick}"></nr-icon>
15
- * <nr-icon name="warning" type="regular" disabled></nr-icon>
15
+ * <nr-icon name="alert-triangle" type="regular" disabled></nr-icon>
16
16
  * <nr-icon name="star" color="#ffd700" size="large"></nr-icon>
17
17
  * ```
18
18
  *
@@ -22,7 +22,7 @@ import { IconTypes } from './icon.types.js';
22
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;
23
23
  export declare class HyIconElement extends IconBaseMixin {
24
24
  static readonly styles: import("lit").CSSResult[];
25
- /** The FontAwesome icon name */
25
+ /** The Lucide icon name */
26
26
  name: string;
27
27
  /** The icon type (solid or regular) */
28
28
  type: IconTypes;
@@ -40,8 +40,13 @@ export declare class HyIconElement extends IconBaseMixin {
40
40
  * Validate component properties on update
41
41
  */
42
42
  willUpdate(changedProperties: Map<string, any>): void;
43
- render(): import("lit").TemplateResult<1>;
44
- getIconPath(): string;
43
+ render(): import("lit-html").TemplateResult<1>;
44
+ /**
45
+ * Create and mount the Lucide SVG icon using createElement
46
+ */
47
+ private mountIcon;
48
+ firstUpdated(changedProperties: Map<string, any>): void;
49
+ updated(changedProperties: Map<string, any>): void;
45
50
  /**
46
51
  * Get the appropriate ARIA role for the icon
47
52
  */
package/icon.component.js CHANGED
@@ -12,13 +12,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
12
12
  };
13
13
  import { LitElement, html } from 'lit';
14
14
  import { customElement, property } from 'lit/decorators.js';
15
- import { library, dom } from '@fortawesome/fontawesome-svg-core';
16
- import { far } from '@fortawesome/free-regular-svg-icons';
17
- import { fas } from '@fortawesome/free-solid-svg-icons';
18
- library.add(fas, far);
19
- dom.watch();
15
+ import { icons, createElement } from 'lucide';
20
16
  import { styles } from './icon.style.js';
21
- import { regularIconPack, solidIconPack } from './icon.types.js';
22
17
  import { NuralyUIBaseMixin } from '@nuralyui/common/mixins';
23
18
  import { ClickableMixin } from './mixins/index.js';
24
19
  /**
@@ -26,9 +21,9 @@ import { ClickableMixin } from './mixins/index.js';
26
21
  *
27
22
  * @example
28
23
  * ```html
29
- * <nr-icon name="envelope"></nr-icon>
24
+ * <nr-icon name="mail"></nr-icon>
30
25
  * <nr-icon name="check" clickable @icon-click="${this.handleIconClick}"></nr-icon>
31
- * <nr-icon name="warning" type="regular" disabled></nr-icon>
26
+ * <nr-icon name="alert-triangle" type="regular" disabled></nr-icon>
32
27
  * <nr-icon name="star" color="#ffd700" size="large"></nr-icon>
33
28
  * ```
34
29
  *
@@ -40,7 +35,7 @@ let HyIconElement = class HyIconElement extends IconBaseMixin {
40
35
  constructor() {
41
36
  super(...arguments);
42
37
  /** The icon type (solid or regular) */
43
- this.type = "solid" /* IconTypes.Solid */;
38
+ this.type = "regular" /* IconTypes.Regular */;
44
39
  /** Alternative text for accessibility */
45
40
  this.alt = '';
46
41
  }
@@ -65,14 +60,10 @@ let HyIconElement = class HyIconElement extends IconBaseMixin {
65
60
  }
66
61
  }
67
62
  render() {
68
- const iconPath = this.getIconPath();
69
- const role = this.getIconRole();
70
- const tabIndex = this.getIconTabIndex();
71
- const ariaDisabled = this.getAriaDisabled();
72
63
  // Build dynamic styles using CSS custom properties
73
64
  let dynamicStyles = '';
74
65
  if (this.color) {
75
- dynamicStyles += `--nuraly-color-icon: ${this.color};`;
66
+ dynamicStyles += `color: ${this.color};`;
76
67
  }
77
68
  if (this.width) {
78
69
  dynamicStyles += `width: ${this.width};`;
@@ -80,58 +71,86 @@ let HyIconElement = class HyIconElement extends IconBaseMixin {
80
71
  if (this.height) {
81
72
  dynamicStyles += `height: ${this.height};`;
82
73
  }
83
- // Build CSS classes
84
- const cssClasses = [
85
- 'svg-icon',
86
- this.clickable ? 'clickable' : '',
87
- this.disabled ? 'disabled' : ''
88
- ].filter(Boolean).join(' ');
89
74
  return html `
90
- <svg
91
- class="${cssClasses}"
75
+ <div
76
+ id="icon-slot"
77
+ class="icon-container ${this.clickable ? 'clickable' : ''} ${this.disabled ? 'disabled' : ''}"
92
78
  style="${dynamicStyles}"
93
- xmlns="http://www.w3.org/2000/svg"
94
- viewBox="0 0 550 550"
95
- role="${role}"
96
- tabindex="${tabIndex}"
97
- aria-label="${this.alt || this.name}"
98
- aria-disabled="${ariaDisabled || 'false'}"
99
79
  data-theme="${this.currentTheme}"
100
- @click="${this.clickable ? this.handleIconClick : undefined}"
101
- @keydown="${this.clickable ? this.handleIconKeydown : undefined}"
102
- >
103
- <path d="${iconPath}" />
104
- </svg>
80
+ ></div>
105
81
  `;
106
82
  }
107
- getIconPath() {
83
+ /**
84
+ * Create and mount the Lucide SVG icon using createElement
85
+ */
86
+ mountIcon() {
87
+ var _a;
88
+ const slot = (_a = this.renderRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#icon-slot');
89
+ if (!slot)
90
+ return;
91
+ // Clear previous content
92
+ while (slot.firstChild) {
93
+ slot.removeChild(slot.firstChild);
94
+ }
108
95
  if (!this.name) {
109
96
  console.warn('HyIconElement: Icon name is required');
110
- return '';
97
+ return;
111
98
  }
112
- const iconPack = this.type == "solid" /* IconTypes.Solid */ ? solidIconPack : regularIconPack;
113
99
  try {
114
- const definitions = library.definitions;
115
- if (!definitions || !definitions[iconPack]) {
116
- console.warn(`HyIconElement: Icon pack "${iconPack}" not found`);
117
- return '';
100
+ // Convert kebab-case to PascalCase for Lucide icon names
101
+ const pascalCaseName = this.name
102
+ .split('-')
103
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
104
+ .join('');
105
+ // Get the icon data from Lucide
106
+ const iconData = icons[pascalCaseName];
107
+ if (!iconData) {
108
+ console.warn(`HyIconElement: Icon "${this.name}" (${pascalCaseName}) not found in Lucide icons`);
109
+ return;
118
110
  }
119
- const iconDefinition = definitions[iconPack][this.name];
120
- if (!iconDefinition) {
121
- console.warn(`HyIconElement: Icon "${this.name}" not found in ${iconPack} pack`);
122
- return '';
111
+ // Use Lucide's createElement to generate the SVG element
112
+ const svgClasses = [
113
+ 'svg-icon',
114
+ this.clickable ? 'clickable' : '',
115
+ this.disabled ? 'disabled' : ''
116
+ ].filter(Boolean);
117
+ const svgElement = createElement(iconData, {
118
+ class: svgClasses,
119
+ 'stroke-width': 2,
120
+ });
121
+ // Set accessibility attributes
122
+ svgElement.setAttribute('role', this.getIconRole());
123
+ svgElement.setAttribute('tabindex', this.getIconTabIndex());
124
+ svgElement.setAttribute('aria-label', this.alt || this.name);
125
+ if (this.disabled) {
126
+ svgElement.setAttribute('aria-disabled', 'true');
123
127
  }
124
- // Validate that the path data exists
125
- const pathData = iconDefinition[4];
126
- if (!pathData || typeof pathData !== 'string') {
127
- console.warn(`HyIconElement: Invalid path data for icon "${this.name}"`);
128
- return '';
128
+ // Add event listeners for clickable icons
129
+ if (this.clickable) {
130
+ svgElement.addEventListener('click', (e) => this.handleIconClick(e));
131
+ svgElement.addEventListener('keydown', (e) => this.handleIconKeydown(e));
129
132
  }
130
- return pathData;
133
+ // Append to slot
134
+ slot.appendChild(svgElement);
131
135
  }
132
136
  catch (error) {
133
137
  console.error(`HyIconElement: Error loading icon "${this.name}":`, error);
134
- return '';
138
+ }
139
+ }
140
+ firstUpdated(changedProperties) {
141
+ var _a;
142
+ (_a = super.firstUpdated) === null || _a === void 0 ? void 0 : _a.call(this, changedProperties);
143
+ this.mountIcon();
144
+ }
145
+ updated(changedProperties) {
146
+ var _a;
147
+ (_a = super.updated) === null || _a === void 0 ? void 0 : _a.call(this, changedProperties);
148
+ // Re-mount icon if any relevant property changed
149
+ if (changedProperties.has('name') ||
150
+ changedProperties.has('color') ||
151
+ changedProperties.has('clickable') ||
152
+ changedProperties.has('disabled')) {
153
+ this.mountIcon();
135
154
  }
136
155
  }
137
156
  /**
@@ -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 '@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"]}
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 { icons, createElement } from 'lucide';\n\nimport { styles } from './icon.style.js';\nimport { IconTypes } 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=\"mail\"></nr-icon>\n * <nr-icon name=\"check\" clickable @icon-click=\"${this.handleIconClick}\"></nr-icon>\n * <nr-icon name=\"alert-triangle\" 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 Lucide icon name */\n @property({type: String})\n name!: string;\n\n /** The icon type (solid or regular) */\n @property()\n type = IconTypes.Regular;\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 // Build dynamic styles using CSS custom properties\n let dynamicStyles = '';\n if (this.color) {\n dynamicStyles += `color: ${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 return html`\n <div \n id=\"icon-slot\" \n class=\"icon-container ${this.clickable ? 'clickable' : ''} ${this.disabled ? 'disabled' : ''}\"\n style=\"${dynamicStyles}\"\n data-theme=\"${this.currentTheme}\"\n ></div>\n `;\n }\n\n /**\n * Create and mount the Lucide SVG icon using createElement\n */\n private mountIcon() {\n const slot = this.renderRoot?.querySelector('#icon-slot') as HTMLElement | null;\n if (!slot) return;\n \n // Clear previous content\n while (slot.firstChild) {\n slot.removeChild(slot.firstChild);\n }\n\n if (!this.name) {\n console.warn('HyIconElement: Icon name is required');\n return;\n }\n\n try {\n // Convert kebab-case to PascalCase for Lucide icon names\n const pascalCaseName = this.name\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n \n // Get the icon data from Lucide\n const iconData = (icons as any)[pascalCaseName];\n \n if (!iconData) {\n console.warn(`HyIconElement: Icon \"${this.name}\" (${pascalCaseName}) not found in Lucide icons`);\n return;\n }\n\n // Use Lucide's createElement to generate the SVG element\n const svgClasses = [\n 'svg-icon',\n this.clickable ? 'clickable' : '',\n this.disabled ? 'disabled' : ''\n ].filter(Boolean);\n\n const svgElement = (createElement as any)(iconData, {\n class: svgClasses,\n 'stroke-width': 2,\n });\n\n // Set accessibility attributes\n svgElement.setAttribute('role', this.getIconRole());\n svgElement.setAttribute('tabindex', this.getIconTabIndex());\n svgElement.setAttribute('aria-label', this.alt || this.name);\n if (this.disabled) {\n svgElement.setAttribute('aria-disabled', 'true');\n }\n\n // Add event listeners for clickable icons\n if (this.clickable) {\n svgElement.addEventListener('click', (e: MouseEvent) => this.handleIconClick(e));\n svgElement.addEventListener('keydown', (e: KeyboardEvent) => this.handleIconKeydown(e));\n }\n\n // Append to slot\n slot.appendChild(svgElement);\n } catch (error) {\n console.error(`HyIconElement: Error loading icon \"${this.name}\":`, error);\n }\n }\n\n override firstUpdated(changedProperties: Map<string, any>): void {\n super.firstUpdated?.(changedProperties);\n this.mountIcon();\n }\n\n override updated(changedProperties: Map<string, any>): void {\n super.updated?.(changedProperties);\n \n // Re-mount icon if any relevant property changed\n if (changedProperties.has('name') || \n changedProperties.has('color') || \n changedProperties.has('clickable') || \n changedProperties.has('disabled')) {\n this.mountIcon();\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
@@ -27,22 +27,32 @@ const iconStyle = css `
27
27
  vertical-align: baseline;
28
28
  position: relative;
29
29
  font-family: var(--nuraly-font-family-icon, 'IBM Plex Sans', ui-sans-serif, system-ui);
30
+ /* Ensure currentColor has a sensible default for Lucide stroke inheritance */
31
+ color: var(--nuraly-color-icon, var(--nuraly-color-icon-fallback, #161616));
32
+ }
33
+
34
+ /* Icon container that holds the dynamically created SVG */
35
+ .icon-container {
36
+ display: inline-flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ line-height: 1;
30
40
  }
31
41
 
32
42
  /*
33
- * Base SVG icon styles
34
- * Uses theme CSS custom properties for comprehensive theming support
43
+ * Base SVG icon styles - targets the SVG element created by Lucide's createElement
44
+ * Uses stroke-based rendering for Lucide icons
35
45
  */
36
46
  .svg-icon {
37
- /* Basic properties with theme support */
38
- fill: var(--nuraly-color-icon, var(--nuraly-color-icon-fallback, #161616));
47
+ stroke: currentColor;
48
+ fill: none;
39
49
  width: var(--nuraly-icon-size, var(--nuraly-icon-size-fallback, 18px));
40
50
  height: var(--nuraly-icon-size, var(--nuraly-icon-size-fallback, 18px));
41
51
  min-width: var(--nuraly-icon-min-size, var(--nuraly-icon-min-size-fallback, 16px));
42
52
  min-height: var(--nuraly-icon-min-size, var(--nuraly-icon-min-size-fallback, 16px));
43
53
 
44
54
  /* 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));
55
+ transition: var(--nuraly-icon-transition, var(--nuraly-icon-transition-fallback, opacity 0.2s ease, transform 0.2s ease, stroke 0.2s ease));
46
56
  display: block;
47
57
  flex-shrink: 0;
48
58
 
@@ -50,6 +60,18 @@ const iconStyle = css `
50
60
  cursor: var(--nuraly-cursor-default, default);
51
61
  }
52
62
 
63
+ /* Ensure all SVG primitives inherit stroke and have no fill */
64
+ .svg-icon path,
65
+ .svg-icon line,
66
+ .svg-icon polyline,
67
+ .svg-icon polygon,
68
+ .svg-icon circle,
69
+ .svg-icon rect,
70
+ .svg-icon ellipse {
71
+ stroke: currentColor;
72
+ fill: none;
73
+ }
74
+
53
75
  /* ========================================
54
76
  * CLICKABLE STATES
55
77
  * ======================================== */
@@ -61,13 +83,15 @@ const iconStyle = css `
61
83
  .svg-icon.clickable:hover {
62
84
  opacity: var(--nuraly-icon-hover-opacity, var(--nuraly-icon-hover-opacity-fallback, 0.8));
63
85
  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));
86
+ stroke: var(--nuraly-color-icon-hover, var(--nuraly-color-icon-hover-fallback, #0f62fe));
87
+ color: var(--nuraly-color-icon-hover, var(--nuraly-color-icon-hover-fallback, #0f62fe));
65
88
  }
66
89
 
67
90
  .svg-icon.clickable:active {
68
91
  opacity: var(--nuraly-icon-active-opacity, var(--nuraly-icon-active-opacity-fallback, 0.6));
69
92
  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));
93
+ stroke: var(--nuraly-color-icon-active, var(--nuraly-color-icon-active-fallback, #054ada));
94
+ color: var(--nuraly-color-icon-active, var(--nuraly-color-icon-active-fallback, #054ada));
71
95
  }
72
96
 
73
97
  .svg-icon.clickable:focus {
@@ -84,14 +108,16 @@ const iconStyle = css `
84
108
 
85
109
  .svg-icon.disabled {
86
110
  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));
111
+ stroke: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));
112
+ color: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));
88
113
  cursor: var(--nuraly-cursor-disabled, not-allowed);
89
114
  }
90
115
 
91
116
  .svg-icon.clickable.disabled:hover,
92
117
  .svg-icon.clickable.disabled:active {
93
118
  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));
119
+ stroke: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));
120
+ color: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));
95
121
  transform: none;
96
122
  }
97
123
 
@@ -121,7 +147,8 @@ const iconStyle = css `
121
147
  /* High contrast mode support */
122
148
  @media (prefers-contrast: high) {
123
149
  .svg-icon {
124
- fill: CanvasText;
150
+ stroke: CanvasText;
151
+ color: CanvasText;
125
152
  }
126
153
 
127
154
  .svg-icon.disabled {
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,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
+ {"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyJpB,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 /* Ensure currentColor has a sensible default for Lucide stroke inheritance */\n color: var(--nuraly-color-icon, var(--nuraly-color-icon-fallback, #161616));\n }\n\n /* Icon container that holds the dynamically created SVG */\n .icon-container {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n }\n\n /* \n * Base SVG icon styles - targets the SVG element created by Lucide's createElement\n * Uses stroke-based rendering for Lucide icons\n */\n .svg-icon {\n stroke: currentColor;\n fill: none;\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, stroke 0.2s ease));\n display: block;\n flex-shrink: 0;\n \n /* Cursor handling */\n cursor: var(--nuraly-cursor-default, default);\n }\n\n /* Ensure all SVG primitives inherit stroke and have no fill */\n .svg-icon path,\n .svg-icon line,\n .svg-icon polyline,\n .svg-icon polygon,\n .svg-icon circle,\n .svg-icon rect,\n .svg-icon ellipse {\n stroke: currentColor;\n fill: none;\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 stroke: var(--nuraly-color-icon-hover, var(--nuraly-color-icon-hover-fallback, #0f62fe));\n color: 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 stroke: var(--nuraly-color-icon-active, var(--nuraly-color-icon-active-fallback, #054ada));\n color: 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 stroke: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));\n color: 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 stroke: var(--nuraly-color-icon-disabled, var(--nuraly-color-icon-disabled-fallback, #c6c6c6));\n color: 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 stroke: CanvasText;\n color: 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"]}
package/icon.types.d.ts CHANGED
@@ -2,6 +2,4 @@ export declare const enum IconTypes {
2
2
  Solid = "solid",
3
3
  Regular = "regular"
4
4
  }
5
- export declare const solidIconPack = "fas";
6
- export declare const regularIconPack = "far";
7
5
  //# sourceMappingURL=icon.types.d.ts.map
package/icon.types.js CHANGED
@@ -1,3 +1,2 @@
1
- export const solidIconPack = 'fas';
2
- export const regularIconPack = 'far';
1
+ export {};
3
2
  //# sourceMappingURL=icon.types.js.map
package/icon.types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"icon.types.js","sourceRoot":"","sources":["../../../src/components/icon/icon.types.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC;AACnC,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC","sourcesContent":["export const enum IconTypes {\n Solid = 'solid',\n Regular = 'regular',\n}\nexport const solidIconPack = 'fas';\nexport const regularIconPack = 'far';\n"]}
1
+ {"version":3,"file":"icon.types.js","sourceRoot":"","sources":["../../../../src/components/icon/icon.types.ts"],"names":[],"mappings":"","sourcesContent":["export const enum IconTypes {\n Solid = 'solid',\n Regular = 'regular',\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"icon.variables.js","sourceRoot":"","sources":["../../../src/components/icon/icon.variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkHhC,CAAC","sourcesContent":["import { css } from 'lit';\n\n/**\n * Icon component CSS custom properties (design tokens)\n * \n * This file contains all the CSS custom properties used by the nr-icon component,\n * organized by functionality and including comprehensive theme support for multiple design systems.\n * \n * The styling system uses CSS custom properties with fallbacks to allow\n * for both global and local customization of icon appearance across different themes:\n * - Light theme (default)\n * - Dark theme\n * - Carbon Design System (light/dark)\n * - Default Design System (light/dark)\n * \n * Design tokens follow the pattern: --nuraly-[component]-[property]-[variant]\n */\nexport const styleVariables = css`\n :host {\n /* ========================================\n * BASE ICON PROPERTIES\n * ======================================== */\n \n /* Size properties with fallbacks */\n --nuraly-icon-size-fallback: 18px;\n --nuraly-icon-size-small-fallback: 14px;\n --nuraly-icon-size-medium-fallback: 20px;\n --nuraly-icon-size-large-fallback: 24px;\n --nuraly-icon-size-xlarge-fallback: 32px;\n --nuraly-icon-size-xxlarge-fallback: 40px;\n --nuraly-icon-min-size-fallback: 12px;\n \n /* Color properties with theme-aware fallbacks */\n --nuraly-color-icon-fallback: #161616;\n \n /* ========================================\n * INTERACTIVE STATE PROPERTIES\n * ======================================== */\n \n /* Transition properties */\n --nuraly-icon-transition-fallback: opacity 0.2s ease, transform 0.2s ease, fill 0.2s ease;\n \n /* Hover state properties */\n --nuraly-icon-hover-opacity-fallback: 0.8;\n --nuraly-icon-hover-transform-fallback: scale(1.05);\n --nuraly-color-icon-hover-fallback: #0f62fe;\n \n /* Active state properties */\n --nuraly-icon-active-opacity-fallback: 0.6;\n --nuraly-icon-active-transform-fallback: scale(0.95);\n --nuraly-color-icon-active-fallback: #054ada;\n \n /* Disabled state properties */\n --nuraly-icon-disabled-opacity-fallback: 0.25;\n --nuraly-color-icon-disabled-fallback: #c6c6c6;\n \n /* ========================================\n * FOCUS STATE PROPERTIES\n * ======================================== */\n \n --nuraly-icon-focus-outline-fallback: 2px solid #0f62fe;\n --nuraly-icon-focus-outline-offset-fallback: 2px;\n --nuraly-icon-focus-background-fallback: rgba(15, 98, 254, 0.1);\n --nuraly-icon-focus-border-radius-fallback: 4px;\n --nuraly-icon-focus-shadow-fallback: none;\n \n /* ========================================\n * CURSOR PROPERTIES\n * ======================================== */\n \n --nuraly-cursor-default: default;\n --nuraly-cursor-interactive: pointer;\n --nuraly-cursor-disabled: not-allowed;\n }\n\n /* ========================================\n * SIZE-SPECIFIC DESIGN TOKENS\n * ======================================== */\n \n /**\n * Size-specific customizations that can be overridden in themes\n * These provide defaults that themes can customize for different design systems\n */\n \n :host([size=\"small\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-small, var(--nuraly-icon-size-small-fallback));\n }\n \n :host([size=\"medium\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-medium, var(--nuraly-icon-size-medium-fallback));\n }\n \n :host([size=\"large\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-large, var(--nuraly-icon-size-large-fallback));\n }\n \n :host([size=\"xlarge\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-xlarge, var(--nuraly-icon-size-xlarge-fallback));\n }\n \n :host([size=\"xxlarge\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-xxlarge, var(--nuraly-icon-size-xxlarge-fallback));\n }\n\n /* ========================================\n * ACCESSIBILITY DESIGN TOKENS\n * ======================================== */\n \n /**\n * Accessibility features that respect user preferences\n * These ensure the component works well for all users\n */\n \n /* High contrast mode support */\n @media (prefers-contrast: high) {\n :host {\n --nuraly-color-icon: CanvasText;\n --nuraly-color-icon-hover: CanvasText;\n --nuraly-color-icon-active: CanvasText;\n --nuraly-icon-focus-outline: 3px solid CanvasText;\n --nuraly-icon-focus-background: Canvas;\n }\n }\n \n /* Reduced motion support */\n @media (prefers-reduced-motion: reduce) {\n :host {\n --nuraly-icon-transition: none;\n --nuraly-icon-hover-transform: none;\n --nuraly-icon-active-transform: none;\n }\n`;\n"]}
1
+ {"version":3,"file":"icon.variables.js","sourceRoot":"","sources":["../../../../src/components/icon/icon.variables.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkHhC,CAAC","sourcesContent":["import { css } from 'lit';\n\n/**\n * Icon component CSS custom properties (design tokens)\n * \n * This file contains all the CSS custom properties used by the nr-icon component,\n * organized by functionality and including comprehensive theme support for multiple design systems.\n * \n * The styling system uses CSS custom properties with fallbacks to allow\n * for both global and local customization of icon appearance across different themes:\n * - Light theme (default)\n * - Dark theme\n * - Carbon Design System (light/dark)\n * - Default Design System (light/dark)\n * \n * Design tokens follow the pattern: --nuraly-[component]-[property]-[variant]\n */\nexport const styleVariables = css`\n :host {\n /* ========================================\n * BASE ICON PROPERTIES\n * ======================================== */\n \n /* Size properties with fallbacks */\n --nuraly-icon-size-fallback: 18px;\n --nuraly-icon-size-small-fallback: 14px;\n --nuraly-icon-size-medium-fallback: 20px;\n --nuraly-icon-size-large-fallback: 24px;\n --nuraly-icon-size-xlarge-fallback: 32px;\n --nuraly-icon-size-xxlarge-fallback: 40px;\n --nuraly-icon-min-size-fallback: 12px;\n \n /* Color properties with theme-aware fallbacks */\n --nuraly-color-icon-fallback: #161616;\n \n /* ========================================\n * INTERACTIVE STATE PROPERTIES\n * ======================================== */\n \n /* Transition properties */\n --nuraly-icon-transition-fallback: opacity 0.2s ease, transform 0.2s ease, fill 0.2s ease;\n \n /* Hover state properties */\n --nuraly-icon-hover-opacity-fallback: 0.8;\n --nuraly-icon-hover-transform-fallback: scale(1.05);\n --nuraly-color-icon-hover-fallback: #0f62fe;\n \n /* Active state properties */\n --nuraly-icon-active-opacity-fallback: 0.6;\n --nuraly-icon-active-transform-fallback: scale(0.95);\n --nuraly-color-icon-active-fallback: #054ada;\n \n /* Disabled state properties */\n --nuraly-icon-disabled-opacity-fallback: 0.25;\n --nuraly-color-icon-disabled-fallback: #c6c6c6;\n \n /* ========================================\n * FOCUS STATE PROPERTIES\n * ======================================== */\n \n --nuraly-icon-focus-outline-fallback: 2px solid #0f62fe;\n --nuraly-icon-focus-outline-offset-fallback: 2px;\n --nuraly-icon-focus-background-fallback: rgba(15, 98, 254, 0.1);\n --nuraly-icon-focus-border-radius-fallback: 4px;\n --nuraly-icon-focus-shadow-fallback: none;\n \n /* ========================================\n * CURSOR PROPERTIES\n * ======================================== */\n \n --nuraly-cursor-default: default;\n --nuraly-cursor-interactive: pointer;\n --nuraly-cursor-disabled: not-allowed;\n }\n\n /* ========================================\n * SIZE-SPECIFIC DESIGN TOKENS\n * ======================================== */\n \n /**\n * Size-specific customizations that can be overridden in themes\n * These provide defaults that themes can customize for different design systems\n */\n \n :host([size=\"small\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-small, var(--nuraly-icon-size-small-fallback));\n }\n \n :host([size=\"medium\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-medium, var(--nuraly-icon-size-medium-fallback));\n }\n \n :host([size=\"large\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-large, var(--nuraly-icon-size-large-fallback));\n }\n \n :host([size=\"xlarge\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-xlarge, var(--nuraly-icon-size-xlarge-fallback));\n }\n \n :host([size=\"xxlarge\"]) {\n --nuraly-icon-size: var(--nuraly-icon-size-xxlarge, var(--nuraly-icon-size-xxlarge-fallback));\n }\n\n /* ========================================\n * ACCESSIBILITY DESIGN TOKENS\n * ======================================== */\n \n /**\n * Accessibility features that respect user preferences\n * These ensure the component works well for all users\n */\n \n /* High contrast mode support */\n @media (prefers-contrast: high) {\n :host {\n --nuraly-color-icon: CanvasText;\n --nuraly-color-icon-hover: CanvasText;\n --nuraly-color-icon-active: CanvasText;\n --nuraly-icon-focus-outline: 3px solid CanvasText;\n --nuraly-icon-focus-background: Canvas;\n }\n }\n \n /* Reduced motion support */\n @media (prefers-reduced-motion: reduce) {\n :host {\n --nuraly-icon-transition: none;\n --nuraly-icon-hover-transform: none;\n --nuraly-icon-active-transform: none;\n }\n`;\n"]}
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/icon/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './icon.component.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/icon/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './icon.component.js';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuralyui/icon",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sourceRoot":"","sources":["../../../src/components/icon/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC;IACpC,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,aAAa;IAC3B,KAAK,EAAE,KAAK;CACb,CAAC,CAAC","sourcesContent":["import { createComponent } from '@lit-labs/react';\nimport * as React from 'react';\nimport { HyIconElement } from './icon.component.js';\nexport const HyIcon = createComponent({\n tagName: 'nr-icon',\n elementClass: HyIconElement,\n react: React,\n});\n"]}
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../../../src/components/icon/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC;IACpC,OAAO,EAAE,SAAS;IAClB,YAAY,EAAE,aAAa;IAC3B,KAAK,EAAE,KAAK;CACb,CAAC,CAAC","sourcesContent":["import { createComponent } from '@lit-labs/react';\nimport * as React from 'react';\nimport { HyIconElement } from './icon.component.js';\nexport const HyIcon = createComponent({\n tagName: 'nr-icon',\n elementClass: HyIconElement,\n react: React,\n});\n"]}