@radishon/lumina 1.0.3 → 1.0.4

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
@@ -181,6 +181,58 @@ export class AppModule {}
181
181
  <lumina-loading type="braille" speed="100"></lumina-loading>
182
182
  ```
183
183
 
184
+ ### 高级自定义
185
+
186
+ #### 自定义字符序列
187
+
188
+ 通过 `chars` 属性传入 JSON 格式的字符数组,完全自定义动画内容:
189
+
190
+ ```html
191
+ <!-- 使用自定义字符 -->
192
+ <lumina-loading chars='["🚀","⭐","🌙","☀️"]' speed="100"></lumina-loading>
193
+
194
+ <!-- 自定义文字动画 -->
195
+ <lumina-loading chars='["L","O","A","D","I","N","G"]' speed="150"></lumina-loading>
196
+
197
+ <!-- 自定义符号 -->
198
+ <lumina-loading chars='["▖","▘","▝","▗"]' speed="120"></lumina-loading>
199
+ ```
200
+
201
+ #### 自定义颜色
202
+
203
+ 通过 `color` 属性传入任意 CSS 颜色值:
204
+
205
+ ```html
206
+ <!-- 自定义预设序列的颜色 -->
207
+ <lumina-loading type="star" color="#ff6b6b"></lumina-loading>
208
+
209
+ <!-- 结合自定义字符和颜色 -->
210
+ <lumina-loading chars='["●","○","★"]' color="#00ff88"></lumina-loading>
211
+
212
+ <!-- 支持所有 CSS 颜色格式 -->
213
+ <lumina-loading type="snow" color="rgb(255, 107, 107)"></lumina-loading>
214
+ <lumina-loading type="snow" color="hsl(330, 80%, 60%)"></lumina-loading>
215
+ <lumina-loading type="snow" color="coral"></lumina-loading>
216
+ ```
217
+
218
+ #### 完整自定义示例
219
+
220
+ ```html
221
+ <!-- 完全自定义:字符 + 颜色 + 速度 -->
222
+ <lumina-loading
223
+ chars='["🔥","✨","💫","🌟"]'
224
+ color="#ffd700"
225
+ speed="80">
226
+ </lumina-loading>
227
+
228
+ <!-- 混合使用:预设序列 + 自定义颜色 -->
229
+ <lumina-loading
230
+ type="flower"
231
+ color="#ff1493"
232
+ speed="200">
233
+ </lumina-loading>
234
+ ```
235
+
184
236
  ### JavaScript 动态控制
185
237
 
186
238
  ```javascript
@@ -195,6 +247,8 @@ el.speed = 200;
195
247
  |------|------|--------|------|
196
248
  | `type` | `SequenceKey` | `'claude'` | 动画序列类型,见下方可用序列列表 |
197
249
  | `speed` | `number` | `180` | 动画帧切换速度(毫秒) |
250
+ | `chars` | `string[]` | `null` | 自定义字符序列(JSON 数组格式),优先级高于 `type` |
251
+ | `color` | `string` | `null` | 自定义颜色值,支持所有 CSS 颜色格式,优先级高于预设颜色 |
198
252
 
199
253
  ## 可用的序列类型
200
254
 
package/dist/index.d.mts CHANGED
@@ -18,6 +18,13 @@ declare class LuminaElement extends HTMLElement {
18
18
  set type(value: SequenceKey);
19
19
  get speed(): number;
20
20
  set speed(value: number);
21
+ get chars(): string[] | null;
22
+ set chars(value: string[] | null);
23
+ get color(): string | null;
24
+ set color(value: string | null);
25
+ private getChars;
26
+ private getConfig;
27
+ private getColor;
21
28
  private render;
22
29
  private startAnimation;
23
30
  }
package/dist/index.d.ts CHANGED
@@ -18,6 +18,13 @@ declare class LuminaElement extends HTMLElement {
18
18
  set type(value: SequenceKey);
19
19
  get speed(): number;
20
20
  set speed(value: number);
21
+ get chars(): string[] | null;
22
+ set chars(value: string[] | null);
23
+ get color(): string | null;
24
+ set color(value: string | null);
25
+ private getChars;
26
+ private getConfig;
27
+ private getColor;
21
28
  private render;
22
29
  private startAnimation;
23
30
  }
package/dist/index.js CHANGED
@@ -112,7 +112,7 @@ var LuminaElement = class extends HTMLElement {
112
112
  this.attachShadow({ mode: "open" });
113
113
  }
114
114
  static get observedAttributes() {
115
- return ["type", "speed"];
115
+ return ["type", "speed", "chars", "color"];
116
116
  }
117
117
  connectedCallback() {
118
118
  this.render();
@@ -128,7 +128,7 @@ var LuminaElement = class extends HTMLElement {
128
128
  if (name === "speed" && this._timer) {
129
129
  this.startAnimation();
130
130
  }
131
- if (name === "type") {
131
+ if (name === "type" || name === "chars" || name === "color") {
132
132
  this.render();
133
133
  this.startAnimation();
134
134
  }
@@ -147,17 +147,67 @@ var LuminaElement = class extends HTMLElement {
147
147
  set speed(value) {
148
148
  this.setAttribute("speed", String(value));
149
149
  }
150
- render() {
150
+ get chars() {
151
+ const charsAttr = this.getAttribute("chars");
152
+ if (charsAttr) {
153
+ try {
154
+ const parsed = JSON.parse(charsAttr);
155
+ if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
156
+ return parsed;
157
+ }
158
+ } catch {
159
+ }
160
+ }
161
+ return null;
162
+ }
163
+ set chars(value) {
164
+ if (value === null) {
165
+ this.removeAttribute("chars");
166
+ } else {
167
+ this.setAttribute("chars", JSON.stringify(value));
168
+ }
169
+ }
170
+ get color() {
171
+ return this.getAttribute("color");
172
+ }
173
+ set color(value) {
174
+ if (value === null) {
175
+ this.removeAttribute("color");
176
+ } else {
177
+ this.setAttribute("color", value);
178
+ }
179
+ }
180
+ getChars() {
181
+ const customChars = this.chars;
182
+ if (customChars) {
183
+ return customChars;
184
+ }
151
185
  const config = SEQUENCES[this.type] || SEQUENCES["claude"];
152
- const currentChar = config.chars[this._index] || config.chars[0];
186
+ return config.chars;
187
+ }
188
+ getConfig() {
189
+ return SEQUENCES[this.type] || SEQUENCES["claude"];
190
+ }
191
+ getColor() {
192
+ const customColor = this.color;
193
+ if (customColor) {
194
+ return customColor;
195
+ }
196
+ const config = this.getConfig();
197
+ return config.color;
198
+ }
199
+ render() {
200
+ const chars = this.getChars();
201
+ const color = this.getColor();
202
+ const currentChar = chars[this._index] || chars[0];
153
203
  this.shadowRoot.innerHTML = `
154
204
  <style>
155
205
  :host {
156
206
  display: inline-block;
157
207
  }
158
208
  .container {
159
- color: ${config.color};
160
- text-shadow: 0 0 20px ${config.color}66;
209
+ color: ${color};
210
+ text-shadow: 0 0 20px ${color}66;
161
211
  font-size: 42px;
162
212
  height: 60px;
163
213
  display: flex;
@@ -175,11 +225,11 @@ var LuminaElement = class extends HTMLElement {
175
225
  if (this._timer) {
176
226
  clearInterval(this._timer);
177
227
  }
178
- const config = SEQUENCES[this.type] || SEQUENCES["claude"];
228
+ const chars = this.getChars();
179
229
  this._timer = setInterval(() => {
180
- this._index = (this._index + 1) % config.chars.length;
230
+ this._index = (this._index + 1) % chars.length;
181
231
  if (this._div) {
182
- this._div.textContent = config.chars[this._index];
232
+ this._div.textContent = chars[this._index];
183
233
  }
184
234
  }, this.speed);
185
235
  }
package/dist/index.mjs CHANGED
@@ -85,7 +85,7 @@ var LuminaElement = class extends HTMLElement {
85
85
  this.attachShadow({ mode: "open" });
86
86
  }
87
87
  static get observedAttributes() {
88
- return ["type", "speed"];
88
+ return ["type", "speed", "chars", "color"];
89
89
  }
90
90
  connectedCallback() {
91
91
  this.render();
@@ -101,7 +101,7 @@ var LuminaElement = class extends HTMLElement {
101
101
  if (name === "speed" && this._timer) {
102
102
  this.startAnimation();
103
103
  }
104
- if (name === "type") {
104
+ if (name === "type" || name === "chars" || name === "color") {
105
105
  this.render();
106
106
  this.startAnimation();
107
107
  }
@@ -120,17 +120,67 @@ var LuminaElement = class extends HTMLElement {
120
120
  set speed(value) {
121
121
  this.setAttribute("speed", String(value));
122
122
  }
123
- render() {
123
+ get chars() {
124
+ const charsAttr = this.getAttribute("chars");
125
+ if (charsAttr) {
126
+ try {
127
+ const parsed = JSON.parse(charsAttr);
128
+ if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
129
+ return parsed;
130
+ }
131
+ } catch {
132
+ }
133
+ }
134
+ return null;
135
+ }
136
+ set chars(value) {
137
+ if (value === null) {
138
+ this.removeAttribute("chars");
139
+ } else {
140
+ this.setAttribute("chars", JSON.stringify(value));
141
+ }
142
+ }
143
+ get color() {
144
+ return this.getAttribute("color");
145
+ }
146
+ set color(value) {
147
+ if (value === null) {
148
+ this.removeAttribute("color");
149
+ } else {
150
+ this.setAttribute("color", value);
151
+ }
152
+ }
153
+ getChars() {
154
+ const customChars = this.chars;
155
+ if (customChars) {
156
+ return customChars;
157
+ }
124
158
  const config = SEQUENCES[this.type] || SEQUENCES["claude"];
125
- const currentChar = config.chars[this._index] || config.chars[0];
159
+ return config.chars;
160
+ }
161
+ getConfig() {
162
+ return SEQUENCES[this.type] || SEQUENCES["claude"];
163
+ }
164
+ getColor() {
165
+ const customColor = this.color;
166
+ if (customColor) {
167
+ return customColor;
168
+ }
169
+ const config = this.getConfig();
170
+ return config.color;
171
+ }
172
+ render() {
173
+ const chars = this.getChars();
174
+ const color = this.getColor();
175
+ const currentChar = chars[this._index] || chars[0];
126
176
  this.shadowRoot.innerHTML = `
127
177
  <style>
128
178
  :host {
129
179
  display: inline-block;
130
180
  }
131
181
  .container {
132
- color: ${config.color};
133
- text-shadow: 0 0 20px ${config.color}66;
182
+ color: ${color};
183
+ text-shadow: 0 0 20px ${color}66;
134
184
  font-size: 42px;
135
185
  height: 60px;
136
186
  display: flex;
@@ -148,11 +198,11 @@ var LuminaElement = class extends HTMLElement {
148
198
  if (this._timer) {
149
199
  clearInterval(this._timer);
150
200
  }
151
- const config = SEQUENCES[this.type] || SEQUENCES["claude"];
201
+ const chars = this.getChars();
152
202
  this._timer = setInterval(() => {
153
- this._index = (this._index + 1) % config.chars.length;
203
+ this._index = (this._index + 1) % chars.length;
154
204
  if (this._div) {
155
- this._div.textContent = config.chars[this._index];
205
+ this._div.textContent = chars[this._index];
156
206
  }
157
207
  }, this.speed);
158
208
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radishon/lumina",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "A beautiful animated loading indicator web component for all frameworks",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",