@radishon/lumina 1.0.0 → 1.0.2

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.
package/README.md CHANGED
@@ -1,64 +1,133 @@
1
1
  # Lumina
2
2
 
3
- 一个优雅的 React 动画加载指示器组件,提供多种预设动画序列,为你的应用增添独特的视觉体验。
3
+ 一个优雅的动画加载指示器 **Web Component**,提供多种预设动画序列,为你的应用增添独特的视觉体验。**适用于所有前端框架**。
4
4
 
5
5
  ## 简介
6
6
 
7
- Lumina 是一个轻量级的 React Loading 组件,通过精心设计的 Unicode 字符序列和颜色配置,呈现出流畅的动画效果。无论是科技感的赛博朋克风格,还是自然的月相变化,都能为你的应用加载状态提供独特的视觉表达。
7
+ Lumina 是一个轻量级的 Loading 组件,通过精心设计的 Unicode 字符序列和颜色配置,呈现出流畅的动画效果。无论是科技感的赛博朋克风格,还是自然的月相变化,都能为你的应用加载状态提供独特的视觉表达。
8
+
9
+ **框架无关** - 可在 React、Vue、Angular、Svelte 或任何 HTML 页面中使用。
8
10
 
9
11
  ## 安装
10
12
 
11
13
  ```bash
12
- npm install lumina
14
+ npm install @radishon/lumina
13
15
  ```
14
16
 
15
17
 
16
18
 
17
19
  ```bash
18
- yarn add lumina
20
+ yarn add @radishon/lumina
19
21
  ```
20
22
 
21
23
 
22
24
 
23
25
  ```bash
24
- pnpm add lumina
26
+ pnpm add @radishon/lumina
25
27
  ```
26
28
 
27
29
  ## 使用示例
28
30
 
29
- ### 基本用法
31
+ ### 基本用法 (所有框架)
32
+
33
+ ```html
34
+ <lumina-loading></lumina-loading>
35
+ ```
36
+
37
+ ### React
30
38
 
31
39
  ```tsx
32
- import { Lumina } from 'lumina';
40
+ import '@radishon/lumina';
33
41
 
34
42
  function App() {
35
43
  return (
36
44
  <div className="loading-container">
37
- <Lumina />
45
+ <lumina-loading />
38
46
  </div>
39
47
  );
40
48
  }
41
49
  ```
42
50
 
43
- ### 自定义序列类型
51
+ ### Vue 3
44
52
 
45
- ```tsx
46
- import { Lumina } from 'lumina';
53
+ ```vue
54
+ <template>
55
+ <div class="loading-container">
56
+ <lumina-loading />
57
+ </div>
58
+ </template>
47
59
 
48
- function App() {
49
- return (
50
- <div>
51
- {/* 使用菱形脉冲效果 */}
52
- <Lumina type="diamond" />
53
-
54
- {/* 使用月相变化效果,调整动画速度 */}
55
- <Lumina type="moon" speed={300} />
56
-
57
- {/* 使用赛博朋克风格 */}
58
- <Lumina type="braille" speed={100} />
59
- </div>
60
- );
60
+ <script setup>
61
+ import '@radishon/lumina'
62
+ </script>
63
+ ```
64
+
65
+ ### Vue 2
66
+
67
+ ```vue
68
+ <template>
69
+ <div class="loading-container">
70
+ <lumina-loading />
71
+ </div>
72
+ </template>
73
+
74
+ <script>
75
+ import '@radishon/lumina'
76
+
77
+ export default {
78
+ mounted() {
79
+ // Web Component 自动注册,无需额外操作
80
+ }
61
81
  }
82
+ </script>
83
+ ```
84
+
85
+ ### Angular
86
+
87
+ ```typescript
88
+ // app.module.ts
89
+ import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
90
+
91
+ @NgModule({
92
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
93
+ })
94
+ export class AppModule {}
95
+ ```
96
+
97
+ ```html
98
+ <!-- app.component.html -->
99
+ <lumina-loading></lumina-loading>
100
+ ```
101
+
102
+ ### Svelte
103
+
104
+ ```svelte
105
+ <script>
106
+ import '@radishon/lumina'
107
+ </script>
108
+
109
+ <lumina-loading />
110
+ ```
111
+
112
+ ### 自定义序列类型
113
+
114
+ ```html
115
+ <!-- 使用菱形脉冲效果 -->
116
+ <lumina-loading type="diamond"></lumina-loading>
117
+
118
+ <!-- 使用月相变化效果,调整动画速度 -->
119
+ <lumina-loading type="moon" speed="300"></lumina-loading>
120
+
121
+ <!-- 使用赛博朋克风格 -->
122
+ <lumina-loading type="braille" speed="100"></lumina-loading>
123
+ ```
124
+
125
+ ### JavaScript 动态控制
126
+
127
+ ```javascript
128
+ const el = document.querySelector('lumina-loading');
129
+ el.type = 'star';
130
+ el.speed = 200;
62
131
  ```
63
132
 
64
133
  ## Props API
@@ -67,7 +136,6 @@ function App() {
67
136
  |------|------|--------|------|
68
137
  | `type` | `SequenceKey` | `'claude'` | 动画序列类型,见下方可用序列列表 |
69
138
  | `speed` | `number` | `180` | 动画帧切换速度(毫秒) |
70
- | `showBar` | `boolean` | `true` | 是否显示进度条(目前未实现) |
71
139
 
72
140
  ## 可用的序列类型
73
141
 
@@ -82,7 +150,7 @@ Lumina 提供了 16 种精心设计的动画序列:
82
150
  | `flower` | 开花绽放 | 花朵绽放动画 | 粉色 `#ffadd2` |
83
151
  | `star` | 星辰回环 | 星星旋转变化 | 白色 `#ffffff` |
84
152
  | `snow` | 雪花晶格 | 雪花飘落效果 | 冰蓝 `#e6f7ff` |
85
- | `spiral` | 螰旋回声 | 螰旋圆环变化 | 金黄色 `#fadb14` |
153
+ | `spiral` | 螺旋回声 | 螺旋圆环变化 | 金黄色 `#fadb14` |
86
154
  | `braille` | 布莱叶码 | 赛博朋克风格的布莱叶点码动画 | 荧光绿 `#00ff00` |
87
155
  | `cypher` | 密码矩阵 | 赛博朋克几何方块变换 | 霓虹蓝 `#00d8ff` |
88
156
  | `moon` | 月相变化 | 自然风格的月相周期动画 | 月光白 `#fffae6` |
@@ -131,7 +199,7 @@ npm link
131
199
  然后在目标项目中:
132
200
 
133
201
  ```bash
134
- npm link lumina
202
+ npm link @radishon/lumina
135
203
  ```
136
204
 
137
205
  ## 许可证
@@ -140,4 +208,4 @@ MIT
140
208
 
141
209
  ## 贡献
142
210
 
143
- 欢迎提交 Issue 和 Pull Request!
211
+ 欢迎提交 Issue 和 Pull Request!
package/dist/index.d.mts CHANGED
@@ -1,81 +1,25 @@
1
- import React from 'react';
2
-
3
- declare const SEQUENCES: {
4
- claude: {
5
- name: string;
6
- chars: string[];
7
- color: string;
8
- };
9
- diamond: {
10
- name: string;
11
- chars: string[];
12
- color: string;
13
- };
14
- circle: {
15
- name: string;
16
- chars: string[];
17
- color: string;
18
- };
19
- step: {
20
- name: string;
21
- chars: string[];
22
- color: string;
23
- };
24
- flower: {
25
- name: string;
26
- chars: string[];
27
- color: string;
28
- };
29
- star: {
30
- name: string;
31
- chars: string[];
32
- color: string;
33
- };
34
- snow: {
35
- name: string;
36
- chars: string[];
37
- color: string;
38
- };
39
- spiral: {
40
- name: string;
41
- chars: string[];
42
- color: string;
43
- };
44
- braille: {
45
- chars: string[];
46
- color: string;
47
- };
48
- cypher: {
49
- chars: string[];
50
- color: string;
51
- };
52
- moon: {
53
- chars: string[];
54
- color: string;
55
- };
56
- wave: {
57
- chars: string[];
58
- color: string;
59
- };
60
- compass: {
61
- chars: string[];
62
- color: string;
63
- };
64
- pixel: {
65
- chars: string[];
66
- color: string;
67
- };
68
- clock: {
69
- chars: string[];
70
- color: string;
71
- };
72
- };
1
+ interface SequenceConfig {
2
+ name: string;
3
+ chars: string[];
4
+ color: string;
5
+ }
6
+ declare const SEQUENCES: Record<string, SequenceConfig>;
73
7
  type SequenceKey = keyof typeof SEQUENCES;
74
- interface LuminaProps {
75
- type?: SequenceKey;
76
- speed?: number;
77
- showBar?: boolean;
8
+ declare class LuminaElement extends HTMLElement {
9
+ private _index;
10
+ private _timer;
11
+ private _div;
12
+ static get observedAttributes(): string[];
13
+ constructor();
14
+ connectedCallback(): void;
15
+ disconnectedCallback(): void;
16
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
17
+ get type(): SequenceKey;
18
+ set type(value: SequenceKey);
19
+ get speed(): number;
20
+ set speed(value: number);
21
+ private render;
22
+ private startAnimation;
78
23
  }
79
- declare const Lumina: React.FC<LuminaProps>;
80
24
 
81
- export { Lumina, type SequenceKey };
25
+ export { LuminaElement as Lumina, LuminaElement, type SequenceKey };
package/dist/index.d.ts CHANGED
@@ -1,81 +1,25 @@
1
- import React from 'react';
2
-
3
- declare const SEQUENCES: {
4
- claude: {
5
- name: string;
6
- chars: string[];
7
- color: string;
8
- };
9
- diamond: {
10
- name: string;
11
- chars: string[];
12
- color: string;
13
- };
14
- circle: {
15
- name: string;
16
- chars: string[];
17
- color: string;
18
- };
19
- step: {
20
- name: string;
21
- chars: string[];
22
- color: string;
23
- };
24
- flower: {
25
- name: string;
26
- chars: string[];
27
- color: string;
28
- };
29
- star: {
30
- name: string;
31
- chars: string[];
32
- color: string;
33
- };
34
- snow: {
35
- name: string;
36
- chars: string[];
37
- color: string;
38
- };
39
- spiral: {
40
- name: string;
41
- chars: string[];
42
- color: string;
43
- };
44
- braille: {
45
- chars: string[];
46
- color: string;
47
- };
48
- cypher: {
49
- chars: string[];
50
- color: string;
51
- };
52
- moon: {
53
- chars: string[];
54
- color: string;
55
- };
56
- wave: {
57
- chars: string[];
58
- color: string;
59
- };
60
- compass: {
61
- chars: string[];
62
- color: string;
63
- };
64
- pixel: {
65
- chars: string[];
66
- color: string;
67
- };
68
- clock: {
69
- chars: string[];
70
- color: string;
71
- };
72
- };
1
+ interface SequenceConfig {
2
+ name: string;
3
+ chars: string[];
4
+ color: string;
5
+ }
6
+ declare const SEQUENCES: Record<string, SequenceConfig>;
73
7
  type SequenceKey = keyof typeof SEQUENCES;
74
- interface LuminaProps {
75
- type?: SequenceKey;
76
- speed?: number;
77
- showBar?: boolean;
8
+ declare class LuminaElement extends HTMLElement {
9
+ private _index;
10
+ private _timer;
11
+ private _div;
12
+ static get observedAttributes(): string[];
13
+ constructor();
14
+ connectedCallback(): void;
15
+ disconnectedCallback(): void;
16
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
17
+ get type(): SequenceKey;
18
+ set type(value: SequenceKey);
19
+ get speed(): number;
20
+ set speed(value: number);
21
+ private render;
22
+ private startAnimation;
78
23
  }
79
- declare const Lumina: React.FC<LuminaProps>;
80
24
 
81
- export { Lumina, type SequenceKey };
25
+ export { LuminaElement as Lumina, LuminaElement, type SequenceKey };
package/dist/index.js CHANGED
@@ -20,13 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- Lumina: () => Lumina_default
23
+ Lumina: () => Lumina_default,
24
+ LuminaElement: () => Lumina_default
24
25
  });
25
26
  module.exports = __toCommonJS(index_exports);
26
27
 
27
- // src/Lumina.tsx
28
- var import_react = require("react");
29
- var import_jsx_runtime = require("react/jsx-runtime");
28
+ // src/Lumina.ts
30
29
  var SEQUENCES = {
31
30
  claude: {
32
31
  name: "CLAUDE \u8F68\u8FF9",
@@ -68,71 +67,129 @@ var SEQUENCES = {
68
67
  chars: ["\u25C9", "\u25CE", "\u25CB", "\u25CC", "\u25CD", "\u25CF", "\u25D0", "\u25D1"],
69
68
  color: "#fadb14"
70
69
  },
71
- // 1. Cyberpunk
72
70
  braille: {
71
+ name: "\u5E03\u83B1\u53F6\u7801",
73
72
  chars: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"],
74
73
  color: "#00ff00"
75
74
  },
76
- cypher: { chars: ["\u259E", "\u259A", "\u259C", "\u2599", "\u259F", "\u259B"], color: "#00d8ff" },
77
- // 2. Nature
75
+ cypher: {
76
+ name: "\u5BC6\u7801\u77E9\u9635",
77
+ chars: ["\u259E", "\u259A", "\u259C", "\u2599", "\u259F", "\u259B"],
78
+ color: "#00d8ff"
79
+ },
78
80
  moon: {
81
+ name: "\u6708\u76F8\u53D8\u5316",
79
82
  chars: ["\u{1F311}", "\u{1F312}", "\u{1F313}", "\u{1F314}", "\u{1F315}", "\u{1F316}", "\u{1F317}", "\u{1F318}"],
80
83
  color: "#fffae6"
81
84
  },
82
- wave: { chars: ["_", "\u23BD", "\u23BC", "\u23BB", "\u23BA", "\u23BB", "\u23BC", "\u23BD"], color: "#ff4d4f" },
83
- // 3. Logic
85
+ wave: {
86
+ name: "\u6CE2\u6D6A\u8D77\u4F0F",
87
+ chars: ["_", "\u23BD", "\u23BC", "\u23BB", "\u23BA", "\u23BB", "\u23BC", "\u23BD"],
88
+ color: "#ff4d4f"
89
+ },
84
90
  compass: {
91
+ name: "\u65B9\u5411\u7F57\u76D8",
85
92
  chars: ["\u2191", "\u2197", "\u2192", "\u2198", "\u2193", "\u2199", "\u2190", "\u2196"],
86
93
  color: "#ff4500"
87
94
  },
88
- // 4. Retro
89
- pixel: { chars: ["\u25A3", "\u25A4", "\u25A5", "\u25A6", "\u25A7", "\u25A8", "\u25A9"], color: "#722ed1" },
95
+ pixel: {
96
+ name: "\u50CF\u7D20\u65B9\u5757",
97
+ chars: ["\u25A3", "\u25A4", "\u25A5", "\u25A6", "\u25A7", "\u25A8", "\u25A9"],
98
+ color: "#722ed1"
99
+ },
90
100
  clock: {
91
- chars: [
92
- "\u{1F550}",
93
- "\u{1F551}",
94
- "\u{1F552}",
95
- "\u{1F553}",
96
- "\u{1F554}",
97
- "\u{1F555}",
98
- "\u{1F556}",
99
- "\u{1F557}",
100
- "\u{1F558}",
101
- "\u{1F559}",
102
- "\u{1F55A}",
103
- "\u{1F55B}"
104
- ],
101
+ name: "\u65F6\u949F\u6307\u9488",
102
+ chars: ["\u{1F550}", "\u{1F551}", "\u{1F552}", "\u{1F553}", "\u{1F554}", "\u{1F555}", "\u{1F556}", "\u{1F557}", "\u{1F558}", "\u{1F559}", "\u{1F55A}", "\u{1F55B}"],
105
103
  color: "#ffbb96"
106
104
  }
107
105
  };
108
- var Lumina = ({
109
- type = "claude",
110
- speed = 180,
111
- showBar = true
112
- }) => {
113
- const [index, setIndex] = (0, import_react.useState)(0);
114
- const config = SEQUENCES[type];
115
- (0, import_react.useEffect)(() => {
116
- const timer = setInterval(() => {
117
- setIndex((prevIndex) => (prevIndex + 1) % config.chars.length);
118
- }, speed);
119
- return () => clearInterval(timer);
120
- }, [config.chars.length, speed]);
121
- const glowStyle = {
122
- color: config.color,
123
- textShadow: `0 0 20px ${config.color}66`,
124
- fontSize: "42px",
125
- height: "60px",
126
- display: "flex",
127
- alignItems: "center",
128
- justifyContent: "center",
129
- transition: "all 0.2s ease",
130
- fontFamily: "monospace"
131
- };
132
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: glowStyle, children: config.chars[index] });
106
+ var LuminaElement = class extends HTMLElement {
107
+ constructor() {
108
+ super();
109
+ this._index = 0;
110
+ this._timer = null;
111
+ this._div = null;
112
+ this.attachShadow({ mode: "open" });
113
+ }
114
+ static get observedAttributes() {
115
+ return ["type", "speed"];
116
+ }
117
+ connectedCallback() {
118
+ this.render();
119
+ this.startAnimation();
120
+ }
121
+ disconnectedCallback() {
122
+ if (this._timer) {
123
+ clearInterval(this._timer);
124
+ }
125
+ }
126
+ attributeChangedCallback(name, oldValue, newValue) {
127
+ if (oldValue !== newValue) {
128
+ if (name === "speed" && this._timer) {
129
+ this.startAnimation();
130
+ }
131
+ if (name === "type") {
132
+ this.render();
133
+ this.startAnimation();
134
+ }
135
+ }
136
+ }
137
+ get type() {
138
+ return this.getAttribute("type") || "claude";
139
+ }
140
+ set type(value) {
141
+ this.setAttribute("type", value);
142
+ }
143
+ get speed() {
144
+ const speed = this.getAttribute("speed");
145
+ return speed !== null ? parseInt(speed, 10) : 180;
146
+ }
147
+ set speed(value) {
148
+ this.setAttribute("speed", String(value));
149
+ }
150
+ render() {
151
+ const config = SEQUENCES[this.type] || SEQUENCES["claude"];
152
+ const currentChar = config.chars[this._index] || config.chars[0];
153
+ this.shadowRoot.innerHTML = `
154
+ <style>
155
+ :host {
156
+ display: inline-block;
157
+ }
158
+ .container {
159
+ color: ${config.color};
160
+ text-shadow: 0 0 20px ${config.color}66;
161
+ font-size: 42px;
162
+ height: 60px;
163
+ display: flex;
164
+ align-items: center;
165
+ justify-content: center;
166
+ transition: all 0.2s ease;
167
+ font-family: monospace;
168
+ }
169
+ </style>
170
+ <div class="container">${currentChar}</div>
171
+ `;
172
+ this._div = this.shadowRoot.querySelector(".container");
173
+ }
174
+ startAnimation() {
175
+ if (this._timer) {
176
+ clearInterval(this._timer);
177
+ }
178
+ const config = SEQUENCES[this.type] || SEQUENCES["claude"];
179
+ this._timer = setInterval(() => {
180
+ this._index = (this._index + 1) % config.chars.length;
181
+ if (this._div) {
182
+ this._div.textContent = config.chars[this._index];
183
+ }
184
+ }, this.speed);
185
+ }
133
186
  };
134
- var Lumina_default = Lumina;
187
+ if (typeof customElements !== "undefined" && !customElements.get("lumina-loading")) {
188
+ customElements.define("lumina-loading", LuminaElement);
189
+ }
190
+ var Lumina_default = LuminaElement;
135
191
  // Annotate the CommonJS export names for ESM import in node:
136
192
  0 && (module.exports = {
137
- Lumina
193
+ Lumina,
194
+ LuminaElement
138
195
  });
package/dist/index.mjs CHANGED
@@ -1,6 +1,4 @@
1
- // src/Lumina.tsx
2
- import { useState, useEffect } from "react";
3
- import { jsx } from "react/jsx-runtime";
1
+ // src/Lumina.ts
4
2
  var SEQUENCES = {
5
3
  claude: {
6
4
  name: "CLAUDE \u8F68\u8FF9",
@@ -42,70 +40,128 @@ var SEQUENCES = {
42
40
  chars: ["\u25C9", "\u25CE", "\u25CB", "\u25CC", "\u25CD", "\u25CF", "\u25D0", "\u25D1"],
43
41
  color: "#fadb14"
44
42
  },
45
- // 1. Cyberpunk
46
43
  braille: {
44
+ name: "\u5E03\u83B1\u53F6\u7801",
47
45
  chars: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"],
48
46
  color: "#00ff00"
49
47
  },
50
- cypher: { chars: ["\u259E", "\u259A", "\u259C", "\u2599", "\u259F", "\u259B"], color: "#00d8ff" },
51
- // 2. Nature
48
+ cypher: {
49
+ name: "\u5BC6\u7801\u77E9\u9635",
50
+ chars: ["\u259E", "\u259A", "\u259C", "\u2599", "\u259F", "\u259B"],
51
+ color: "#00d8ff"
52
+ },
52
53
  moon: {
54
+ name: "\u6708\u76F8\u53D8\u5316",
53
55
  chars: ["\u{1F311}", "\u{1F312}", "\u{1F313}", "\u{1F314}", "\u{1F315}", "\u{1F316}", "\u{1F317}", "\u{1F318}"],
54
56
  color: "#fffae6"
55
57
  },
56
- wave: { chars: ["_", "\u23BD", "\u23BC", "\u23BB", "\u23BA", "\u23BB", "\u23BC", "\u23BD"], color: "#ff4d4f" },
57
- // 3. Logic
58
+ wave: {
59
+ name: "\u6CE2\u6D6A\u8D77\u4F0F",
60
+ chars: ["_", "\u23BD", "\u23BC", "\u23BB", "\u23BA", "\u23BB", "\u23BC", "\u23BD"],
61
+ color: "#ff4d4f"
62
+ },
58
63
  compass: {
64
+ name: "\u65B9\u5411\u7F57\u76D8",
59
65
  chars: ["\u2191", "\u2197", "\u2192", "\u2198", "\u2193", "\u2199", "\u2190", "\u2196"],
60
66
  color: "#ff4500"
61
67
  },
62
- // 4. Retro
63
- pixel: { chars: ["\u25A3", "\u25A4", "\u25A5", "\u25A6", "\u25A7", "\u25A8", "\u25A9"], color: "#722ed1" },
68
+ pixel: {
69
+ name: "\u50CF\u7D20\u65B9\u5757",
70
+ chars: ["\u25A3", "\u25A4", "\u25A5", "\u25A6", "\u25A7", "\u25A8", "\u25A9"],
71
+ color: "#722ed1"
72
+ },
64
73
  clock: {
65
- chars: [
66
- "\u{1F550}",
67
- "\u{1F551}",
68
- "\u{1F552}",
69
- "\u{1F553}",
70
- "\u{1F554}",
71
- "\u{1F555}",
72
- "\u{1F556}",
73
- "\u{1F557}",
74
- "\u{1F558}",
75
- "\u{1F559}",
76
- "\u{1F55A}",
77
- "\u{1F55B}"
78
- ],
74
+ name: "\u65F6\u949F\u6307\u9488",
75
+ chars: ["\u{1F550}", "\u{1F551}", "\u{1F552}", "\u{1F553}", "\u{1F554}", "\u{1F555}", "\u{1F556}", "\u{1F557}", "\u{1F558}", "\u{1F559}", "\u{1F55A}", "\u{1F55B}"],
79
76
  color: "#ffbb96"
80
77
  }
81
78
  };
82
- var Lumina = ({
83
- type = "claude",
84
- speed = 180,
85
- showBar = true
86
- }) => {
87
- const [index, setIndex] = useState(0);
88
- const config = SEQUENCES[type];
89
- useEffect(() => {
90
- const timer = setInterval(() => {
91
- setIndex((prevIndex) => (prevIndex + 1) % config.chars.length);
92
- }, speed);
93
- return () => clearInterval(timer);
94
- }, [config.chars.length, speed]);
95
- const glowStyle = {
96
- color: config.color,
97
- textShadow: `0 0 20px ${config.color}66`,
98
- fontSize: "42px",
99
- height: "60px",
100
- display: "flex",
101
- alignItems: "center",
102
- justifyContent: "center",
103
- transition: "all 0.2s ease",
104
- fontFamily: "monospace"
105
- };
106
- return /* @__PURE__ */ jsx("div", { style: glowStyle, children: config.chars[index] });
79
+ var LuminaElement = class extends HTMLElement {
80
+ constructor() {
81
+ super();
82
+ this._index = 0;
83
+ this._timer = null;
84
+ this._div = null;
85
+ this.attachShadow({ mode: "open" });
86
+ }
87
+ static get observedAttributes() {
88
+ return ["type", "speed"];
89
+ }
90
+ connectedCallback() {
91
+ this.render();
92
+ this.startAnimation();
93
+ }
94
+ disconnectedCallback() {
95
+ if (this._timer) {
96
+ clearInterval(this._timer);
97
+ }
98
+ }
99
+ attributeChangedCallback(name, oldValue, newValue) {
100
+ if (oldValue !== newValue) {
101
+ if (name === "speed" && this._timer) {
102
+ this.startAnimation();
103
+ }
104
+ if (name === "type") {
105
+ this.render();
106
+ this.startAnimation();
107
+ }
108
+ }
109
+ }
110
+ get type() {
111
+ return this.getAttribute("type") || "claude";
112
+ }
113
+ set type(value) {
114
+ this.setAttribute("type", value);
115
+ }
116
+ get speed() {
117
+ const speed = this.getAttribute("speed");
118
+ return speed !== null ? parseInt(speed, 10) : 180;
119
+ }
120
+ set speed(value) {
121
+ this.setAttribute("speed", String(value));
122
+ }
123
+ render() {
124
+ const config = SEQUENCES[this.type] || SEQUENCES["claude"];
125
+ const currentChar = config.chars[this._index] || config.chars[0];
126
+ this.shadowRoot.innerHTML = `
127
+ <style>
128
+ :host {
129
+ display: inline-block;
130
+ }
131
+ .container {
132
+ color: ${config.color};
133
+ text-shadow: 0 0 20px ${config.color}66;
134
+ font-size: 42px;
135
+ height: 60px;
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: center;
139
+ transition: all 0.2s ease;
140
+ font-family: monospace;
141
+ }
142
+ </style>
143
+ <div class="container">${currentChar}</div>
144
+ `;
145
+ this._div = this.shadowRoot.querySelector(".container");
146
+ }
147
+ startAnimation() {
148
+ if (this._timer) {
149
+ clearInterval(this._timer);
150
+ }
151
+ const config = SEQUENCES[this.type] || SEQUENCES["claude"];
152
+ this._timer = setInterval(() => {
153
+ this._index = (this._index + 1) % config.chars.length;
154
+ if (this._div) {
155
+ this._div.textContent = config.chars[this._index];
156
+ }
157
+ }, this.speed);
158
+ }
107
159
  };
108
- var Lumina_default = Lumina;
160
+ if (typeof customElements !== "undefined" && !customElements.get("lumina-loading")) {
161
+ customElements.define("lumina-loading", LuminaElement);
162
+ }
163
+ var Lumina_default = LuminaElement;
109
164
  export {
110
- Lumina_default as Lumina
165
+ Lumina_default as Lumina,
166
+ Lumina_default as LuminaElement
111
167
  };
package/package.json CHANGED
@@ -1,31 +1,36 @@
1
1
  {
2
2
  "name": "@radishon/lumina",
3
- "version": "1.0.0",
4
- "description": "A beautiful animated loading indicator component for React with multiple preset sequences",
3
+ "version": "1.0.2",
4
+ "description": "A beautiful animated loading indicator web component for all frameworks",
5
5
  "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
6
+ "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
- "files": ["dist"],
8
+ "files": [
9
+ "dist"
10
+ ],
9
11
  "scripts": {
10
12
  "build": "tsup src/index.ts --format cjs,esm --dts",
11
13
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
12
14
  "prepublishOnly": "npm run build"
13
15
  },
14
- "keywords": ["react", "loading", "spinner", "animation", "lumina", "component"],
16
+ "keywords": [
17
+ "loading",
18
+ "spinner",
19
+ "animation",
20
+ "lumina",
21
+ "web-component",
22
+ "react",
23
+ "vue",
24
+ "angular",
25
+ "svelte"
26
+ ],
15
27
  "author": "",
16
28
  "license": "MIT",
17
29
  "publishConfig": {
18
30
  "access": "public"
19
31
  },
20
- "peerDependencies": {
21
- "react": ">=16.8.0",
22
- "react-dom": ">=16.8.0"
23
- },
32
+ "peerDependencies": {},
24
33
  "devDependencies": {
25
- "@types/react": "^18.0.0",
26
- "@types/react-dom": "^18.0.0",
27
- "react": "^18.0.0",
28
- "react-dom": "^18.0.0",
29
34
  "tsup": "^8.0.0",
30
35
  "typescript": "^5.0.0"
31
36
  }