@genarou/blazir-icons 1.2.20 → 1.3.3

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.
Files changed (128) hide show
  1. package/LICENSE +146 -0
  2. package/README.md +1206 -0
  3. package/dist/CustomIcon.svelte +30 -0
  4. package/dist/CustomIcon.svelte.d.ts +14 -0
  5. package/dist/Icon.svelte +282 -102
  6. package/dist/Icon.svelte.d.ts +12 -5
  7. package/dist/IconBadge.svelte +75 -0
  8. package/dist/IconBadge.svelte.d.ts +16 -0
  9. package/dist/IconBase.svelte +89 -57
  10. package/dist/effects.js +1 -3
  11. package/dist/icons/Ai.svelte +34 -6
  12. package/dist/icons/Alternate.svelte +15 -8
  13. package/dist/icons/Alternate.svelte.d.ts +5 -2
  14. package/dist/icons/AnimatedArrowLeft.svelte +29 -11
  15. package/dist/icons/AnimatedArrowLeft.svelte.d.ts +5 -2
  16. package/dist/icons/Archive.svelte +21 -0
  17. package/dist/icons/Archive.svelte.d.ts +7 -0
  18. package/dist/icons/Attachment.svelte +10 -10
  19. package/dist/icons/Attachment.svelte.d.ts +5 -2
  20. package/dist/icons/Bank.svelte +16 -8
  21. package/dist/icons/Bank.svelte.d.ts +5 -2
  22. package/dist/icons/Bell.svelte +11 -8
  23. package/dist/icons/Bell.svelte.d.ts +5 -2
  24. package/dist/icons/Box.svelte +12 -10
  25. package/dist/icons/Box.svelte.d.ts +5 -2
  26. package/dist/icons/BoxAdd.svelte +11 -8
  27. package/dist/icons/BoxAdd.svelte.d.ts +5 -2
  28. package/dist/icons/Buy.svelte +11 -10
  29. package/dist/icons/Buy.svelte.d.ts +5 -2
  30. package/dist/icons/Calendar.svelte +12 -9
  31. package/dist/icons/Calendar.svelte.d.ts +5 -2
  32. package/dist/icons/CalendarEdit.svelte +5 -5
  33. package/dist/icons/CalendarPlus.svelte +11 -9
  34. package/dist/icons/CalendarPlus.svelte.d.ts +5 -2
  35. package/dist/icons/Camera.svelte +19 -0
  36. package/dist/icons/Camera.svelte.d.ts +4 -0
  37. package/dist/icons/Cards.svelte +19 -0
  38. package/dist/icons/Cards.svelte.d.ts +4 -0
  39. package/dist/icons/Cart.svelte +13 -10
  40. package/dist/icons/CloudAlert.svelte +19 -0
  41. package/dist/icons/CloudAlert.svelte.d.ts +4 -0
  42. package/dist/icons/CloudCheck.svelte +19 -0
  43. package/dist/icons/CloudCheck.svelte.d.ts +4 -0
  44. package/dist/icons/CloudDownload.svelte +19 -0
  45. package/dist/icons/CloudDownload.svelte.d.ts +4 -0
  46. package/dist/icons/Connect.svelte +21 -0
  47. package/dist/icons/Connect.svelte.d.ts +7 -0
  48. package/dist/icons/CreditCard.svelte +19 -0
  49. package/dist/icons/CreditCard.svelte.d.ts +4 -0
  50. package/dist/icons/Dashboard.svelte +10 -7
  51. package/dist/icons/Dashboard.svelte.d.ts +5 -2
  52. package/dist/icons/DashboardOutlined.svelte +14 -12
  53. package/dist/icons/DashboardOutlined.svelte.d.ts +5 -2
  54. package/dist/icons/Desktop.svelte +19 -0
  55. package/dist/icons/Desktop.svelte.d.ts +4 -0
  56. package/dist/icons/DoughnutChart.svelte +19 -0
  57. package/dist/icons/DoughnutChart.svelte.d.ts +4 -0
  58. package/dist/icons/Earth.svelte +19 -0
  59. package/dist/icons/Earth.svelte.d.ts +4 -0
  60. package/dist/icons/Eye.svelte +42 -29
  61. package/dist/icons/Eye.svelte.d.ts +5 -2
  62. package/dist/icons/EyeOff.svelte +51 -51
  63. package/dist/icons/EyeOff.svelte.d.ts +5 -2
  64. package/dist/icons/Filter.svelte +10 -7
  65. package/dist/icons/Filter.svelte.d.ts +5 -2
  66. package/dist/icons/FilterOutline.svelte +8 -7
  67. package/dist/icons/FilterOutline.svelte.d.ts +5 -2
  68. package/dist/icons/Globe.svelte +19 -0
  69. package/dist/icons/Globe.svelte.d.ts +4 -0
  70. package/dist/icons/HardDrive.svelte +21 -0
  71. package/dist/icons/HardDrive.svelte.d.ts +7 -0
  72. package/dist/icons/Historic.svelte +21 -0
  73. package/dist/icons/Historic.svelte.d.ts +7 -0
  74. package/dist/icons/Home.svelte +11 -7
  75. package/dist/icons/Home.svelte.d.ts +5 -2
  76. package/dist/icons/LightHub.svelte +19 -0
  77. package/dist/icons/LightHub.svelte.d.ts +4 -0
  78. package/dist/icons/Link.svelte +19 -0
  79. package/dist/icons/Link.svelte.d.ts +4 -0
  80. package/dist/icons/MagnifiyingGlass.svelte +12 -8
  81. package/dist/icons/MagnifiyingGlass.svelte.d.ts +5 -2
  82. package/dist/icons/Pause.svelte +21 -0
  83. package/dist/icons/Pause.svelte.d.ts +7 -0
  84. package/dist/icons/Play.svelte +21 -0
  85. package/dist/icons/Play.svelte.d.ts +7 -0
  86. package/dist/icons/Power.svelte +19 -0
  87. package/dist/icons/Power.svelte.d.ts +4 -0
  88. package/dist/icons/Process.svelte +21 -0
  89. package/dist/icons/Process.svelte.d.ts +7 -0
  90. package/dist/icons/Receipt.svelte +19 -0
  91. package/dist/icons/Receipt.svelte.d.ts +4 -0
  92. package/dist/icons/Settings.svelte +16 -8
  93. package/dist/icons/Settings.svelte.d.ts +5 -2
  94. package/dist/icons/Sync.svelte +19 -0
  95. package/dist/icons/Sync.svelte.d.ts +4 -0
  96. package/dist/icons/SyncPhoto.svelte +21 -0
  97. package/dist/icons/SyncPhoto.svelte.d.ts +7 -0
  98. package/dist/icons/Upload.svelte +12 -57
  99. package/dist/icons/Wifi.svelte +19 -0
  100. package/dist/icons/Wifi.svelte.d.ts +4 -0
  101. package/dist/icons/Work.svelte +21 -0
  102. package/dist/icons/Work.svelte.d.ts +7 -0
  103. package/dist/icons/lazy-registry.d.ts +21 -0
  104. package/dist/icons/lazy-registry.js +251 -0
  105. package/dist/icons/registry.d.ts +211 -135
  106. package/dist/icons/registry.js +195 -137
  107. package/dist/icons-api.d.ts +74 -267
  108. package/dist/icons-api.js +91 -465
  109. package/dist/index.d.ts +5 -5
  110. package/dist/index.js +14 -11
  111. package/dist/plugin/index.d.ts +46 -0
  112. package/dist/plugin/index.js +327 -0
  113. package/dist/smart-cache.d.ts +35 -0
  114. package/dist/smart-cache.js +192 -0
  115. package/dist/types.d.ts +19 -2
  116. package/dist/utils/sanitize.d.ts +25 -0
  117. package/dist/utils/sanitize.js +109 -0
  118. package/package.json +12 -1
  119. package/dist/icons/Aws.svelte +0 -19
  120. package/dist/icons/Aws.svelte.d.ts +0 -4
  121. package/dist/icons/Facebook.svelte +0 -18
  122. package/dist/icons/Facebook.svelte.d.ts +0 -4
  123. package/dist/icons/Golang.svelte +0 -17
  124. package/dist/icons/Golang.svelte.d.ts +0 -4
  125. package/dist/icons/Google.svelte +0 -18
  126. package/dist/icons/Google.svelte.d.ts +0 -4
  127. package/dist/icons/Paypal.svelte +0 -21
  128. package/dist/icons/Paypal.svelte.d.ts +0 -4
@@ -0,0 +1,16 @@
1
+ import type { DynamicIconProps } from "./types";
2
+ interface BadgeProps extends DynamicIconProps {
3
+ /** true = punto rojo | number = conteo | string = texto */
4
+ badge?: boolean | number | string;
5
+ /** Color de fondo del badge. Default: rojo */
6
+ badgeColor?: string;
7
+ /** Color del texto del badge. Default: blanco */
8
+ badgeTextColor?: string;
9
+ /** Tamaño del badge en px. Default: 8 (dot) o 16 (con texto) */
10
+ badgeSize?: number;
11
+ /** Posición del badge. Default: top-right */
12
+ badgePosition?: "top-right" | "top-left" | "bottom-right" | "bottom-left";
13
+ }
14
+ declare const IconBadge: import("svelte").Component<BadgeProps, {}, "">;
15
+ type IconBadge = ReturnType<typeof IconBadge>;
16
+ export default IconBadge;
@@ -10,77 +10,102 @@
10
10
  } from "./utils/defaults.js";
11
11
 
12
12
  // Constantes
13
- const DEFAULT_MS = 180;
14
- const DEFAULT_EASING = "cubic-bezier(.2,.8,.2,1)";
13
+ const DEFAULT_MS = 250;
14
+ const DEFAULT_EASING = "ease";
15
15
  const DEFAULT_ICON_COLOR = "var(--icon-fg, var(--ui-muted-fg, currentColor))";
16
16
 
17
17
  const MS_REGEX = /ms$/;
18
18
  const S_REGEX = /s$/;
19
19
 
20
+ // Presets semánticos de velocidad hover
21
+ const HOVER_SPEED_MAP: Record<string, number> = {
22
+ instant: 0,
23
+ fast: 120,
24
+ normal: 250,
25
+ slow: 400,
26
+ sluggish: 600,
27
+ };
28
+
20
29
  function normalizeMs(v?: number | string): number {
21
30
  if (v == null) return DEFAULT_MS;
22
31
  if (typeof v === "number") return v;
23
32
  const s = String(v).trim();
33
+ if (s in HOVER_SPEED_MAP) return HOVER_SPEED_MAP[s];
24
34
  if (MS_REGEX.test(s)) return parseFloat(s);
25
35
  if (S_REGEX.test(s)) return parseFloat(s) * 1000;
26
36
  const n = parseFloat(s);
27
37
  return Number.isFinite(n) ? n : DEFAULT_MS;
28
38
  }
29
39
 
30
- let uidCounter = 0;
31
- function uid(): string {
32
- return `bz-${Date.now().toString(36)}-${(uidCounter++).toString(36)}`;
33
- }
40
+ // UID por instancia — generado UNA SOLA VEZ por componente, nunca en $derived.
41
+ // Antes se generaba dentro de $derived, lo que causaba un UID nuevo cada vez
42
+ // que props.title cambiaba, produciendo IDs inconsistentes en aria-labelledby.
43
+ let _uidCounter = 0;
44
+ const _instanceUid = `bz-${Date.now().toString(36)}-${(_uidCounter++).toString(36)}`;
34
45
 
35
46
  // Props
36
47
  const props: IconProps & { mode?: IconMode } = $props();
37
48
 
38
49
  // Hover (nativo + heredado)
39
50
  let internalHovered = $state(false);
51
+ let internalPressed = $state(false);
40
52
  const isHovered = $derived(
41
- internalHovered || (props.parentHoverContext?.hovered ?? false)
53
+ !props.disabled &&
54
+ !props.loading &&
55
+ (internalHovered || (props.parentHoverContext?.hovered ?? false))
42
56
  );
57
+ const isPressed = $derived(!props.disabled && internalPressed);
43
58
 
44
- // Color
59
+ // Color — prioridad: activeColor (pressed) > hoverColor (hover) > color > default
45
60
  const effectiveColor = $derived(
46
- (isHovered && props.hoverColor ? props.hoverColor : props.color) ??
47
- DEFAULT_ICON_COLOR
61
+ (isPressed && props.activeColor
62
+ ? props.activeColor
63
+ : isHovered && props.hoverColor
64
+ ? props.hoverColor
65
+ : props.color) ?? DEFAULT_ICON_COLOR
48
66
  );
49
67
 
50
68
  // Mode
51
69
  const mode = $derived(props.mode ?? "solid");
52
70
 
53
- // Derivados base
71
+ // Derivados base — usando $derived.by donde el cuerpo es complejo
54
72
  const klass = $derived(normalizeClass(props));
55
73
  const common = $derived(commonDefaults(props));
56
- const propsWithEffectiveColor = $derived({ ...props, color: effectiveColor });
74
+
75
+ // propsWithEffectiveColor: evitar reconstruir si color no cambió.
76
+ // $derived.by garantiza que solo re-ejecuta cuando sus deps cambian.
77
+ const propsWithEffectiveColor = $derived.by(() => ({
78
+ ...props,
79
+ color: effectiveColor,
80
+ }));
81
+
57
82
  const visual = $derived(modeDefaults(mode, propsWithEffectiveColor));
58
83
  const timingStyle = $derived(getAnimationStyle(props));
59
84
 
60
- // Transiciones
85
+ // Transiciones — hoverSpeed > transitionMs > default
61
86
  const hoverMs = $derived(
62
- normalizeMs(props.transitionMs ?? props.animationDuration)
63
- );
64
- const hoverEase = $derived(
65
- props.transitionEasing ?? props.animationEasing ?? DEFAULT_EASING
87
+ normalizeMs(props.transitionMs ?? props.hoverSpeed)
66
88
  );
89
+ const hoverEase = $derived(props.transitionEasing ?? DEFAULT_EASING);
67
90
 
68
- // Animaciones continuas
69
- const spinDuration = $derived(() => {
91
+ // Animaciones continuas — $derived.by idiomático (Svelte 5)
92
+ const spinDuration = $derived.by(() => {
93
+ if (props.loading) return "0.75s"; // loading siempre gira
70
94
  if (!props.spin) return null;
71
95
  if (props.spin === true) return "1s";
72
96
  return typeof props.spin === "number"
73
97
  ? `${props.spin}ms`
74
98
  : String(props.spin);
75
99
  });
100
+
76
101
  const wantsPulse = $derived(!!props.pulse);
77
102
  const wantsBounce = $derived(!!props.bounce);
78
103
  const wantsWiggle = $derived(!!props.wiggle);
79
104
  const wantsHeartbeat = $derived(!!props.heartbeat);
80
105
  const wantsElastic = $derived(!!props.elastic);
81
106
 
82
- // ===== Chevron state ⇒ grados (se animará por CSS) =====
83
- const effectiveChevronState = $derived(() => {
107
+ // ===== Chevron state ⇒ grados =====
108
+ const effectiveChevronState = $derived.by(() => {
84
109
  if (props.chevronState) return props.chevronState;
85
110
  if (props.chevronOpen !== undefined) {
86
111
  return props.chevronOpen ? "open" : "closed";
@@ -88,8 +113,8 @@
88
113
  return undefined;
89
114
  });
90
115
 
91
- const chevronDeg = $derived((): number | null => {
92
- switch (effectiveChevronState()) {
116
+ const chevronDeg = $derived.by((): number | null => {
117
+ switch (effectiveChevronState) {
93
118
  case "open":
94
119
  case "down":
95
120
  return 90;
@@ -107,11 +132,10 @@
107
132
 
108
133
  // Clase final
109
134
  const finalClass = $derived(
110
- `bz-icon ${klass}${effectiveChevronState() ? " bz-icon-chevron" : ""}`.trim()
135
+ `bz-icon ${klass}${effectiveChevronState ? " bz-icon-chevron" : ""}`.trim()
111
136
  );
112
137
 
113
138
  // ===== SVG transform (solo rotate/flip declarativos) =====
114
- // Rot/flip en <g> para no interferir con la transición del <svg>
115
139
  function getViewBoxCenter(vb: string) {
116
140
  const parts = vb.trim().split(/\s+/);
117
141
  const minX = Number(parts[0]);
@@ -120,12 +144,12 @@
120
144
  const h = Number(parts[3]);
121
145
  return { cx: minX + w / 2, cy: minY + h / 2 };
122
146
  }
147
+
123
148
  const center = $derived(getViewBoxCenter(common.viewBox));
124
149
 
125
- const svgTransform = $derived(() => {
150
+ const svgTransform = $derived.by(() => {
126
151
  const cmds: string[] = [];
127
152
 
128
- // Rotate (prop)
129
153
  if (props.rotate != null) {
130
154
  const r =
131
155
  typeof props.rotate === "number"
@@ -134,7 +158,6 @@
134
158
  if (!isNaN(r)) cmds.push(`rotate(${r} ${center.cx} ${center.cy})`);
135
159
  }
136
160
 
137
- // Flip (prop)
138
161
  if (props.flipH || props.flipV) {
139
162
  const sx = props.flipH ? -1 : 1;
140
163
  const sy = props.flipV ? -1 : 1;
@@ -143,48 +166,39 @@
143
166
  );
144
167
  }
145
168
 
146
- // ⛔️ OJO: chevron NO va aquí (aquí no hay transición CSS)
147
169
  return cmds.length ? cmds.join(" ") : "";
148
170
  });
149
171
 
150
- // ===== Style inline del <svg> (incluye transición y chevron por CSS) =====
151
- const style = $derived(() => {
172
+ // ===== Style inline del <svg> =====
173
+ const style = $derived.by(() => {
152
174
  const parts: string[] = [];
153
175
 
154
- // estilo previo del usuario
155
176
  if (props.style) {
156
177
  parts.push(props.style.endsWith(";") ? props.style : `${props.style};`);
157
178
  }
158
179
 
159
- // color
180
+ if (props.disabled) parts.push("opacity:0.4;pointer-events:none;");
160
181
  parts.push(`color:${effectiveColor};`);
161
182
 
162
- // Vars de timing (si las hay)
163
183
  const tstyle = timingStyle;
164
184
  if (tstyle) parts.push(tstyle);
165
185
 
166
- // transición para transform/opacidad/stroke/fill
167
186
  parts.push(
168
187
  `transition:color ${hoverMs}ms ${hoverEase},fill ${hoverMs}ms ${hoverEase},` +
169
188
  `stroke ${hoverMs}ms ${hoverEase},transform ${hoverMs}ms ${hoverEase},opacity ${hoverMs}ms ${hoverEase};`
170
189
  );
171
190
 
172
- // Var CSS para chevron (si hay estado). Usamos rotate(Xdeg)
173
- const deg = chevronDeg();
191
+ const deg = chevronDeg;
174
192
  if (deg != null) {
175
193
  parts.push(`--bz-chevron-rot: rotate(${deg}deg);`);
176
194
  } else {
177
- // mantener consistente
178
195
  parts.push(`--bz-chevron-rot: rotate(0deg);`);
179
196
  }
180
197
 
181
- // Transform del SVG: incluir SIEMPRE la var del chevron al final
182
- // (puedes añadir más términos aquí si usas CSS-only transforms)
183
198
  parts.push(`transform-origin:center;`);
184
199
  parts.push(`transform: var(--bz-chevron-rot);`);
185
200
 
186
- // Animaciones declarativas (spin/pulse/etc) se apilan con transform
187
- const spin = spinDuration();
201
+ const spin = spinDuration;
188
202
  if (
189
203
  spin ||
190
204
  wantsPulse ||
@@ -212,10 +226,10 @@
212
226
  return parts.join(" ");
213
227
  });
214
228
 
215
- // A11y
229
+ // A11y — computedTitleId usa el UID de instancia (estable durante todo el ciclo de vida)
216
230
  const ariaHidden = $derived(props.decorative ? "true" : undefined);
217
231
  const computedTitleId = $derived(
218
- props.title ? (props.titleId ?? `bz-icon-title-${uid()}`) : undefined
232
+ props.title ? (props.titleId ?? `bz-icon-title-${_instanceUid}`) : undefined
219
233
  );
220
234
  const ariaLabel = $derived(
221
235
  props.decorative ? undefined : props.ariaLabel || undefined
@@ -228,7 +242,8 @@
228
242
  const finalSize = $derived(
229
243
  typeof common.size === "number" ? `${common.size}px` : common.size
230
244
  );
231
- const safeAttrs = $derived(() => {
245
+
246
+ const safeAttrs = $derived.by(() => {
232
247
  if (!props.attrs) return {};
233
248
  const { width, height, ...rest } = props.attrs as any;
234
249
  return rest;
@@ -238,9 +253,11 @@
238
253
  let svgRef: SVGSVGElement | null = $state(null);
239
254
  let fxLayer: SVGGElement | null = $state(null);
240
255
 
241
- // Efectos (incluye heartbeatOnHover si viene en attrs/effects)
256
+ // Efectos el $effect solo se re-ejecuta cuando fxLayer o las opciones de
257
+ // efectos cambian. Devuelve la función de cleanup para destroy automático.
242
258
  $effect(() => {
243
259
  if (!fxLayer) return;
260
+
244
261
  const effectsOpts: IconEffectOptions = { ...(props.effects ?? {}) };
245
262
  const a = props.attrs;
246
263
  if (a) {
@@ -255,22 +272,22 @@
255
272
  if (a.hoverScale) effectsOpts.hoverScale = a.hoverScale;
256
273
  if (a.pressScale) effectsOpts.pressScale = a.pressScale;
257
274
  }
275
+
276
+ if (props.tooltip) effectsOpts.tooltip = props.tooltip;
258
277
  const controller = iconEffects(fxLayer, effectsOpts);
259
278
  return () => controller.destroy();
260
279
  });
261
280
 
262
- function handleMouseEnter() {
263
- internalHovered = true;
264
- }
265
- function handleMouseLeave() {
266
- internalHovered = false;
267
- }
281
+ function handleMouseEnter() { internalHovered = true; }
282
+ function handleMouseLeave() { internalHovered = false; internalPressed = false; }
283
+ function handleMouseDown() { internalPressed = true; }
284
+ function handleMouseUp() { internalPressed = false; }
268
285
  </script>
269
286
 
270
287
  <svg
271
288
  bind:this={svgRef}
272
289
  xmlns="http://www.w3.org/2000/svg"
273
- {...safeAttrs()}
290
+ {...safeAttrs}
274
291
  width={finalSize}
275
292
  height={finalSize}
276
293
  viewBox={common.viewBox}
@@ -281,7 +298,7 @@
281
298
  aria-label={ariaLabel}
282
299
  aria-labelledby={ariaLabelledby}
283
300
  focusable="false"
284
- style={style()}
301
+ style={style}
285
302
  fill={visual.fill}
286
303
  stroke={visual.stroke}
287
304
  stroke-width={visual.strokeWidth}
@@ -291,10 +308,20 @@
291
308
  data-testid={props.testId}
292
309
  onmouseenter={handleMouseEnter}
293
310
  onmouseleave={handleMouseLeave}
311
+ onmousedown={handleMouseDown}
312
+ onmouseup={handleMouseUp}
294
313
  >
295
- {#if props.title}<title id={computedTitleId}>{props.title}</title>{/if}
296
- <g bind:this={fxLayer} transform={svgTransform()}>
297
- {@render props.children?.()}
314
+ {#if props.title}
315
+ <title id={computedTitleId}>{props.title}</title>
316
+ {:else if props.tooltip}
317
+ <title>{props.tooltip}</title>
318
+ {/if}
319
+ <g bind:this={fxLayer} transform={svgTransform}>
320
+ {#if props.loading}
321
+ <circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" stroke-width="2.5" stroke-dasharray="42 15" stroke-linecap="round" />
322
+ {:else}
323
+ {@render props.children?.()}
324
+ {/if}
298
325
  </g>
299
326
  </svg>
300
327
 
@@ -321,6 +348,7 @@
321
348
  transform: rotate(360deg);
322
349
  }
323
350
  }
351
+
324
352
  @keyframes bz-icon-bounce {
325
353
  0% {
326
354
  transform: translateY(0);
@@ -332,6 +360,7 @@
332
360
  transform: translateY(0);
333
361
  }
334
362
  }
363
+
335
364
  @keyframes bz-icon-pulse {
336
365
  0%,
337
366
  100% {
@@ -343,6 +372,7 @@
343
372
  opacity: 0.92;
344
373
  }
345
374
  }
375
+
346
376
  @keyframes bz-icon-wiggle {
347
377
  0% {
348
378
  transform: rotate(0deg);
@@ -357,6 +387,7 @@
357
387
  transform: rotate(0deg);
358
388
  }
359
389
  }
390
+
360
391
  @keyframes bz-icon-elastic {
361
392
  0% {
362
393
  transform: scale(1);
@@ -371,6 +402,7 @@
371
402
  transform: scale(1);
372
403
  }
373
404
  }
405
+
374
406
  @keyframes bz-icon-heartbeat {
375
407
  0%,
376
408
  100% {
package/dist/effects.js CHANGED
@@ -62,9 +62,7 @@ export function iconEffects(node, opts = {}) {
62
62
  if (target instanceof SVGSVGElement) {
63
63
  target.style.pointerEvents = "bounding-box";
64
64
  }
65
- // Setup inicial
66
- if (opts.tooltip)
67
- target.setAttribute("title", opts.tooltip);
65
+ // Setup inicial — tooltip lo maneja Icon.svelte via data-bz-tooltip + CSS
68
66
  if (opts.cursor && isHTML)
69
67
  node.style.cursor = opts.cursor;
70
68
  const ms = opts.transitionMs ?? DEFAULTS.transitionMs;
@@ -2,17 +2,45 @@
2
2
  import IconBase from "../IconBase.svelte";
3
3
  import type { IconProps } from "../types";
4
4
 
5
+ // Usamos el patrón de Svelte 5 que espera tu IconBase
5
6
  const props: IconProps = $props();
6
7
  </script>
7
8
 
8
9
  <IconBase
9
10
  {...props}
10
- mode="solid"
11
+ mode="outline"
11
12
  viewBox="0 0 24 24"
12
- ariaLabel={props.ariaLabel ?? "File settings icon"}
13
- title={props.title ?? ""}
13
+ ariaLabel={props.ariaLabel ?? "Inteligencia Artificial"}
14
+ title={props.title ?? "IA Core"}
14
15
  >
15
- <path
16
- d="m20.467 8.694l.246-.566a4.36 4.36 0 0 1 2.22-2.25l.759-.339a.53.53 0 0 0 0-.963l-.717-.319a4.37 4.37 0 0 1-2.251-2.326l-.253-.611a.506.506 0 0 0-.942 0l-.253.61a4.37 4.37 0 0 1-2.25 2.327l-.718.32a.53.53 0 0 0 0 .962l.76.338a4.36 4.36 0 0 1 2.219 2.251l.246.566c.18.414.753.414.934 0M5.8 16h2.154l.6-1.5h2.892l.6 1.5H14.2L11 8H9zm4.2-5.115l.646 1.615H9.354zM15 16V8h2v8zM3 3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1v-9h-2v8H4V5h10V3z"
17
- />
16
+ {#snippet children()}
17
+ <rect
18
+ x="4"
19
+ y="4"
20
+ width="16"
21
+ height="16"
22
+ rx="2"
23
+ fill="none"
24
+ stroke="currentColor"
25
+ stroke-width="1.8"
26
+ />
27
+
28
+ <path
29
+ fill="none"
30
+ stroke="currentColor"
31
+ stroke-width="1.8"
32
+ stroke-linecap="round"
33
+ d="M9 2v2m6-2v2M9 20v2m6-2v2M2 9h2m-2 6h2M20 9h2m-2 6h2"
34
+ />
35
+
36
+ <path
37
+ fill="none"
38
+ stroke="currentColor"
39
+ stroke-width="1.5"
40
+ stroke-linejoin="round"
41
+ d="M12 8l3 4-3 4-3-4z"
42
+ />
43
+
44
+ <circle cx="12" cy="12" r="1" fill="currentColor" />
45
+ {/snippet}
18
46
  </IconBase>
@@ -1,19 +1,26 @@
1
- <!-- src/lib/icons/TextHeading.svelte -->
2
1
  <script lang="ts">
3
2
  import IconBase from "../IconBase.svelte";
4
- import type { IconProps } from "../types";
3
+ import type { IconMode, IconProps } from "../types.js";
5
4
 
6
- const props: IconProps = $props();
5
+ const props: IconProps & { mode?: IconMode } = $props();
7
6
  </script>
8
7
 
9
8
  <IconBase
10
9
  {...props}
11
10
  mode="solid"
12
11
  viewBox="0 0 24 24"
13
- ariaLabel={props.ariaLabel ?? "Text Heading"}
14
- title={props.title ?? ""}
12
+ ariaLabel={props.ariaLabel ?? "Encabezado de texto"}
13
+ title={props.title ?? "Text Heading"}
15
14
  >
16
- <path
17
- d="M9 5.5c0 .83.67 1.5 1.5 1.5H14v10.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V7h3.5c.83 0 1.5-.67 1.5-1.5S21.33 4 20.5 4h-10C9.67 4 9 4.67 9 5.5M4.5 12H6v5.5c0 .83.67 1.5 1.5 1.5S9 18.33 9 17.5V12h1.5c.83 0 1.5-.67 1.5-1.5S11.33 9 10.5 9h-6C3.67 9 3 9.67 3 10.5S3.67 12 4.5 12"
18
- />
15
+ {#snippet children()}
16
+ <path
17
+ fill="currentColor"
18
+ d="M21 5c0-.55-.45-1-1-1H9c-.55 0-1 .45-1 1s.45 1 1 1h5v12c0 .55.45 1 1 1s1-.45 1-1V6h4c.55 0 1-.45 1-1z"
19
+ />
20
+
21
+ <path
22
+ fill="currentColor"
23
+ d="M11 11c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1h3v6c0 .55.45 1 1 1s1-.45 1-1v-6h1c.55 0 1-.45 1-1z"
24
+ />
25
+ {/snippet}
19
26
  </IconBase>
@@ -1,4 +1,7 @@
1
- import type { IconProps } from "../types";
2
- declare const Alternate: import("svelte").Component<IconProps, {}, "">;
1
+ import type { IconMode, IconProps } from "../types.js";
2
+ type $$ComponentProps = IconProps & {
3
+ mode?: IconMode;
4
+ };
5
+ declare const Alternate: import("svelte").Component<$$ComponentProps, {}, "">;
3
6
  type Alternate = ReturnType<typeof Alternate>;
4
7
  export default Alternate;
@@ -1,23 +1,41 @@
1
1
  <script lang="ts">
2
2
  import IconBase from "../IconBase.svelte";
3
- import type { IconProps } from "../types";
3
+ import type { IconMode, IconProps } from "../types.js";
4
4
 
5
- const props: IconProps = $props();
5
+ const props: IconProps & { mode?: IconMode } = $props();
6
6
  </script>
7
7
 
8
8
  <IconBase
9
9
  {...props}
10
10
  mode="outline"
11
11
  viewBox="0 0 24 24"
12
- ariaLabel={props.ariaLabel ?? "Arrow Right Animated"}
13
- title={props.title ?? ""}
12
+ ariaLabel={props.ariaLabel ?? "Flecha derecha"}
13
+ title={props.title ?? "Arrow Right"}
14
14
  >
15
- <path d="M9 12l5 -5M9 12l5 5" stroke-dasharray="10" stroke-dashoffset="10">
16
- <animate
17
- attributeName="stroke-dashoffset"
18
- dur="0.3s"
19
- values="10;0"
20
- fill="freeze"
15
+ {#snippet children()}
16
+ <path
17
+ fill="none"
18
+ stroke="currentColor"
19
+ stroke-width="1.8"
20
+ stroke-linecap="round"
21
+ stroke-linejoin="round"
22
+ class="bz-arrow-path"
23
+ d="M9 6l6 6-6 6"
21
24
  />
22
- </path>
25
+ {/snippet}
23
26
  </IconBase>
27
+
28
+ <style>
29
+ /* Animación delegada a la GPU mediante transformaciones simples.
30
+ Es mucho más eficiente que animar stroke-dashoffset con JS o <animate>.
31
+ */
32
+ :global(.bz-icon:hover .bz-arrow-path) {
33
+ transform: translateX(2px);
34
+ transition: transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1);
35
+ }
36
+
37
+ .bz-arrow-path {
38
+ transition: transform 0.2s ease;
39
+ will-change: transform;
40
+ }
41
+ </style>
@@ -1,4 +1,7 @@
1
- import type { IconProps } from "../types";
2
- declare const AnimatedArrowLeft: import("svelte").Component<IconProps, {}, "">;
1
+ import type { IconMode, IconProps } from "../types.js";
2
+ type $$ComponentProps = IconProps & {
3
+ mode?: IconMode;
4
+ };
5
+ declare const AnimatedArrowLeft: import("svelte").Component<$$ComponentProps, {}, "">;
3
6
  type AnimatedArrowLeft = ReturnType<typeof AnimatedArrowLeft>;
4
7
  export default AnimatedArrowLeft;
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import IconBase from "../IconBase.svelte";
3
+ import type { IconMode, IconProps } from "../types.js";
4
+
5
+ const props: IconProps & { mode?: IconMode } = $props();
6
+ </script>
7
+
8
+ <IconBase
9
+ {...props}
10
+ mode="solid"
11
+ viewBox="0 0 24 24"
12
+ ariaLabel={props.ariaLabel ?? "Copiar o duplicar"}
13
+ title={props.title ?? "Copy / Duplicate"}
14
+ >
15
+ {#snippet children()}
16
+ <path
17
+ fill="currentColor"
18
+ d="M14 13q.85 0 1.425-.587T16 11h4V4H8v7h4q0 .825.588 1.413T14 13m-6 5q-.825 0-1.412-.587T6 16V4q0-.825.588-1.412T8 2h12q.825 0 1.413.588T22 4v12q0 .825-.587 1.413T20 18zm-4 4q-.825 0-1.412-.587T2 20V6h2v14h14v2z"
19
+ />
20
+ {/snippet}
21
+ </IconBase>
@@ -0,0 +1,7 @@
1
+ import type { IconMode, IconProps } from "../types.js";
2
+ type $$ComponentProps = IconProps & {
3
+ mode?: IconMode;
4
+ };
5
+ declare const Archive: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type Archive = ReturnType<typeof Archive>;
7
+ export default Archive;
@@ -1,21 +1,21 @@
1
- <!-- src/lib/icons/AttachmentClip.svelte -->
2
1
  <script lang="ts">
3
2
  import IconBase from "../IconBase.svelte";
4
- import type { IconProps } from "../types";
3
+ import type { IconMode, IconProps } from "../types.js";
5
4
 
6
- const props: IconProps = $props();
5
+ const props: IconProps & { mode?: IconMode } = $props();
7
6
  </script>
8
7
 
9
8
  <IconBase
10
9
  {...props}
11
10
  mode="solid"
12
11
  viewBox="0 0 24 24"
13
- ariaLabel={props.ariaLabel ?? "Attachment Clip"}
14
- title={props.title ?? ""}
15
- strokeWidth={props.strokeWidth ?? 0}
12
+ ariaLabel={props.ariaLabel ?? "Adjuntar archivo"}
13
+ title={props.title ?? "Attachment"}
16
14
  >
17
- <path
18
- fill="currentColor"
19
- d="M12 19q1.675 0 2.838-1.175T16 15v-3q0-.425-.288-.712T15 11t-.712.288T14 12v3q0 .825-.575 1.413T12 17q-.825 0-1.412-.587T10 15V9.5q0-.225.15-.363T10.5 9q.225 0 .363.138T11 9.5V14q0 .425.288.713T12 15t.713-.288T13 14V9.5q0-1.05-.725-1.775T10.5 7t-1.775.725T8 9.5V15q0 1.65 1.175 2.825T12 19m-6 3q-.825 0-1.412-.587T4 20V4q0-.825.588-1.412T6 2h9l5 5v13q0 .825-.587 1.413T18 22zm8-18v3q0 .425.288.713T15 8h3z"
20
- />
15
+ {#snippet children()}
16
+ <path
17
+ fill="currentColor"
18
+ d="M16.5 6v11.5c0 2.48-2.02 4.5-4.5 4.5s-4.5-2.02-4.5-4.5V5c0-1.66 1.34-3 3-3s3 1.34 3 3v11.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5V6h-2v10.5c0 1.93 1.57 3.5 3.5 3.5s3.5-1.57 3.5-3.5V5c0-2.76-2.24-5-5-5S5 2.24 5 5v12.5C5 20.54 8.46 24 12.75 24S20.5 20.54 20.5 16.25V6h-4z"
19
+ />
20
+ {/snippet}
21
21
  </IconBase>
@@ -1,4 +1,7 @@
1
- import type { IconProps } from "../types";
2
- declare const Attachment: import("svelte").Component<IconProps, {}, "">;
1
+ import type { IconMode, IconProps } from "../types.js";
2
+ type $$ComponentProps = IconProps & {
3
+ mode?: IconMode;
4
+ };
5
+ declare const Attachment: import("svelte").Component<$$ComponentProps, {}, "">;
3
6
  type Attachment = ReturnType<typeof Attachment>;
4
7
  export default Attachment;
@@ -1,13 +1,21 @@
1
- <!-- src/lib/icons/Bank.svelte -->
2
1
  <script lang="ts">
3
2
  import IconBase from "../IconBase.svelte";
4
- import type { IconProps } from "../types";
5
- const props: IconProps = $props();
3
+ import type { IconMode, IconProps } from "../types.js";
4
+
5
+ const props: IconProps & { mode?: IconMode } = $props();
6
6
  </script>
7
7
 
8
- <IconBase {...props} mode="solid" viewBox="0 0 24 24">
9
- <path
10
- fill="currentColor"
11
- d="M5 16v-5q0-.425.288-.712T6 10t.713.288T7 11v5q0 .425-.288.713T6 17t-.712-.288T5 16m6 0v-5q0-.425.288-.712T12 10t.713.288T13 11v5q0 .425-.288.713T12 17t-.712-.288T11 16m10-8H2.9q-.375 0-.638-.262T2 7.1v-.55q0-.275.138-.475T2.5 5.75l8.6-4.3q.425-.2.9-.2t.9.2l8.55 4.275q.275.125.413.375t.137.525V7q0 .425-.287.713T21 8M3 21q-.425 0-.712-.288T2 20t.288-.712T3 19h10.05q.425 0 .713.288t.287.712t-.288.713t-.712.287zm15-8.25q-.425 0-.712-.288T17 11.75V11q0-.425.288-.712T18 10t.713.288T19 11v.75q0 .425-.288.713T18 12.75m-2 5.8v-1.925q0-.275.138-.525t.412-.375l3-1.5q.2-.125.45-.125t.45.125l3 1.5q.275.125.413.375t.137.525v1.925q0 1.875-.975 3.238t-2.65 2.062q-.05.025-.375.075q-.05 0-.375-.075q-1.675-.7-2.65-2.062T16 18.55m3.275.325l-.45-.45q-.225-.225-.525-.213t-.525.238t-.225.525t.225.525l.8.8q.3.3.7.3t.7-.3l2.25-2.225q.225-.225.225-.525t-.225-.525t-.525-.212t-.525.212z"
12
- />
8
+ <IconBase
9
+ {...props}
10
+ mode="solid"
11
+ viewBox="0 0 24 24"
12
+ ariaLabel={props.ariaLabel ?? "Entidad Bancaria"}
13
+ title={props.title ?? "Bank Premium"}
14
+ >
15
+ {#snippet children()}
16
+ <path
17
+ fill="currentColor"
18
+ d="M12 1.5L2 6v14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6L12 1.5zM4 8h3v12H4V8zm5 0h6v12H9V8zm8 0h3v12h-3V8zm-5-3.5L19.5 7H4.5L12 4.5zM10 10v8h1v-8h-1zm3 0v8h1v-8h-1z"
19
+ />
20
+ {/snippet}
13
21
  </IconBase>
@@ -1,4 +1,7 @@
1
- import type { IconProps } from "../types";
2
- declare const Bank: import("svelte").Component<IconProps, {}, "">;
1
+ import type { IconMode, IconProps } from "../types.js";
2
+ type $$ComponentProps = IconProps & {
3
+ mode?: IconMode;
4
+ };
5
+ declare const Bank: import("svelte").Component<$$ComponentProps, {}, "">;
3
6
  type Bank = ReturnType<typeof Bank>;
4
7
  export default Bank;