@sun-panel/micro-app 1.0.5

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 ADDED
@@ -0,0 +1,298 @@
1
+ # @sun-panel/micro-app
2
+
3
+ Sun Panel 微应用组件 - 基于 LitElement 的微应用开发框架,提供内置事件绑定和验证支持。
4
+
5
+ ## 简介
6
+
7
+ `@sun-panel/micro-app` 是一个用于开发 Sun Panel 微应用的 JavaScript 组件库,提供了:
8
+
9
+ - 基于原生 Web Components 的基础组件类
10
+ - 内置的事件绑定和验证功能
11
+ - TypeScript 类型定义支持
12
+ - 预设的卡片和页面组件基类
13
+ - 与 Lit 框架兼容的开发体验
14
+
15
+ ## 安装
16
+
17
+ ```bash
18
+ npm install @sun-panel/micro-app
19
+ ```
20
+
21
+ ## 快速开始
22
+
23
+ ### 创建卡片组件
24
+
25
+ ```javascript
26
+ import { SunPanelCardElement } from '@sun-panel/micro-app';
27
+
28
+ class MyCard extends SunPanelCardElement {
29
+ constructor() {
30
+ super();
31
+ this.title = 'My Card';
32
+ this.count = 0;
33
+ }
34
+
35
+ render() {
36
+ return `
37
+ <style>
38
+ :host {
39
+ display: block;
40
+ padding: 16px;
41
+ border: 1px solid #ccc;
42
+ }
43
+ </style>
44
+ <h3>${this.title}</h3>
45
+ <p>Count: ${this.count}</p>
46
+ <button onclick="this.increment()">Increment</button>
47
+ `;
48
+ }
49
+
50
+ increment() {
51
+ this.count++;
52
+ this.update();
53
+ }
54
+ }
55
+
56
+ // 定义自定义元素
57
+ customElements.define('my-card', MyCard);
58
+ ```
59
+
60
+ ### 创建页面组件
61
+
62
+ ```javascript
63
+ import { SunPanelPageElement } from '@sun-panel/micro-app';
64
+
65
+ class MyPage extends SunPanelPageElement {
66
+ constructor() {
67
+ super();
68
+ this.message = 'Hello World';
69
+ }
70
+
71
+ render() {
72
+ return `
73
+ <style>
74
+ :host {
75
+ display: block;
76
+ padding: 20px;
77
+ }
78
+ </style>
79
+ <h1>${this.pageTitle}</h1>
80
+ <p>${this.message}</p>
81
+ `;
82
+ }
83
+ }
84
+
85
+ // 定义自定义元素
86
+ customElements.define('my-page', MyPage);
87
+ ```
88
+
89
+ ### 使用验证功能
90
+
91
+ ```typescript
92
+ import { Validator, FormValidator } from '@sun-panel/micro-app';
93
+
94
+ // 验证单个字段
95
+ const rules = {
96
+ required: true,
97
+ type: 'string',
98
+ minLength: 3,
99
+ maxLength: 20
100
+ };
101
+
102
+ const errors = await Validator.validateField('test', rules, 'username');
103
+ if (errors.length > 0) {
104
+ console.log('Validation errors:', errors);
105
+ }
106
+
107
+ // 验证对象
108
+ const formRules = {
109
+ username: {
110
+ required: true,
111
+ type: 'string',
112
+ minLength: 3
113
+ },
114
+ email: {
115
+ required: true,
116
+ type: 'email'
117
+ }
118
+ };
119
+
120
+ const formData = {
121
+ username: 'test',
122
+ email: 'test@example.com'
123
+ };
124
+
125
+ const formValidator = new FormValidator(formRules);
126
+ await formValidator.validateOrThrow(formData); // 抛出验证错误或无错误
127
+ ```
128
+
129
+ ## 核心组件
130
+
131
+ ### SunPanelElement
132
+
133
+ 基础元素类,提供微应用的基本能力:
134
+
135
+ - 基于原生 Web Components 标准
136
+ - 内置影子 DOM 管理
137
+ - 属性和生命周期管理
138
+ - 事件派发机制
139
+
140
+ ### SunPanelCardElement
141
+
142
+ 卡片元素基类,适用于微应用中的卡片组件:
143
+
144
+ - 支持卡片大小配置
145
+ - 支持卡片标题
146
+ - 内置卡片信息处理
147
+ - 预设卡片样式
148
+
149
+ ### SunPanelPageElement
150
+
151
+ 页面元素基类,适用于微应用中的页面组件:
152
+
153
+ - 支持页面标题和描述
154
+ - 内置页面生命周期管理
155
+ - 预设页面布局
156
+
157
+ ## API
158
+
159
+ ### 元素生命周期
160
+
161
+ - `connectedCallback()` - 元素插入 DOM 时调用
162
+ - `disconnectedCallback()` - 元素从 DOM 移除时调用
163
+ - `attributeChangedCallback()` - 属性变化时调用
164
+
165
+ ### 实用工具
166
+
167
+ - `Validator` - 验证工具类
168
+ - `FormValidator` - 表单验证器
169
+ - `ValidationError` - 验证错误类
170
+
171
+ ## 构建
172
+
173
+ ```bash
174
+ # 复制源文件到发布目录
175
+ npm run build
176
+ ```
177
+
178
+ ## 开发
179
+
180
+ ### 开发测试环境
181
+
182
+ ```bash
183
+ # 启动开发服务器(带热重载)
184
+ ✓ Rollup 正在监听文件变化
185
+ ✓ 开发服务器运行在: http://localhost:3000
186
+ ✓ LiveReload 已启用
187
+ ✓ 成功构建: dev/bundle.js (91ms)
188
+
189
+ ```
190
+
191
+ 这将:
192
+ - 启动 Rollup watch 模式监听文件变化
193
+ - 自动启动开发服务器(http://localhost:3000)
194
+ - 自动在浏览器中打开测试页面
195
+ - 支持源码修改后自动重新构建和热重载
196
+
197
+ ### 测试环境功能
198
+
199
+ 开发测试环境包含:
200
+ - **卡片组件测试**:展示不同主题和大小的卡片
201
+ - **页面组件测试**:演示页面组件的功能
202
+ - **验证功能测试**:测试字段和表单验证
203
+ - **实时预览**:修改源代码后自动刷新
204
+
205
+ ### 修改代码后
206
+
207
+ 1. 修改 `src/` 目录下的源代码
208
+ 2. Rollup 会自动重新构建 `dev/bundle.js`
209
+ 3. 浏览器会自动刷新
210
+ 4. 立即查看修改效果
211
+
212
+ ### 构建生产版本
213
+
214
+ ```bash
215
+ # 构建生产版本
216
+ npm run build
217
+ ```
218
+
219
+ ## 开发模式说明
220
+
221
+ 此库采用 TypeScript 定义文件的开发模式:
222
+
223
+ - 使用者可以选择使用 JavaScript 或 TypeScript 方式导入和使用组件
224
+
225
+ ## 开发时链接模块(开发者指南)
226
+
227
+ 如果你正在开发基于 `@sun-panel/micro-app` 的微应用,并且希望在开发时获得最新的类型提示,可以使用 npm link 方式链接到本地的开发版本:
228
+
229
+ ### 在微应用项目中链接开发版本
230
+
231
+ 假设你有以下目录结构:
232
+ ```
233
+ sun-panel-app/
234
+ ├── sun-panel-micro-app/ # 正在开发的模块
235
+ └── sun-panel-micro-app-hslr-demo-app/ # 微应用项目
236
+ ```
237
+
238
+ **步骤 1:在 sun-panel-micro-app 目录创建全局链接**
239
+
240
+ ```bash
241
+ cd sun-panel-micro-app
242
+ npm link
243
+ ```
244
+
245
+ **步骤 2:在微应用项目目录链接到全局包**
246
+
247
+ ```bash
248
+ cd sun-panel-micro-app-hslr-demo-app
249
+ npm link @sun-panel/micro-app
250
+ ```
251
+
252
+ **步骤 3:重新加载 VSCode**
253
+
254
+ 按 `Cmd+Shift+P`,输入 "Developer: Reload Window" 并回车。
255
+
256
+ ### 配置 jsconfig.json
257
+
258
+ 在微应用项目根目录创建 `jsconfig.json` 文件:
259
+
260
+ ```json
261
+ {
262
+ "compilerOptions": {
263
+ "baseUrl": ".",
264
+ "moduleResolution": "node",
265
+ "checkJs": true
266
+ },
267
+ "include": ["src/**/*", "**/*.js"],
268
+ "exclude": ["node_modules", "dist"]
269
+ }
270
+ ```
271
+
272
+ ### 效果
273
+
274
+ - ✅ 编辑器会显示来自 `sun-panel-micro-app/src` 的最新类型定义
275
+ - ✅ 修改类型定义后无需重新发布,编辑器会自动更新提示
276
+ - ✅ 运行时代码通过 vite alias 引用开发目录的代码
277
+ - ✅ 类型提示通过 npm link 引用开发目录的类型定义
278
+
279
+ ### 解除链接
280
+
281
+ 如果要恢复使用 npm 发布的版本:
282
+
283
+ ```bash
284
+ cd sun-panel-micro-app-hslr-demo-app
285
+ npm unlink @sun-panel/micro-app
286
+ ```
287
+
288
+ 然后重新加载 VSCode 即可。
289
+
290
+ ## 类型定义开源
291
+
292
+ 本项目的所有类型定义文件(以 `.d.ts` 结尾的文件)采用 MIT 开源协议发布,允许在任何项目中自由使用。
293
+
294
+ 详细信息请参阅 [TYPES_LICENSE.md](TYPES_LICENSE.md) 文件。
295
+
296
+ ## 许可证
297
+
298
+ MIT
@@ -0,0 +1,48 @@
1
+ # 类型定义开源协议
2
+
3
+ 本项目的所有类型定义文件(以 `.d.ts` 结尾的文件)采用 MIT 开源协议发布,允许在任何项目中自由使用。
4
+
5
+ ## 包含的类型定义文件
6
+
7
+ - `dist/*.d.ts` - 编译后的主类型定义文件
8
+ - `dist/types/*.d.ts` - 详细的类型定义文件
9
+ - `src/types/*.d.ts` - 源码中的类型定义文件
10
+
11
+ ## 使用方法
12
+
13
+ 安装包后,TypeScript 会自动识别类型定义:
14
+
15
+ ```typescript
16
+ import { SunPanelElement, MicroAppAPI, SpContext } from '@sun-panel/micro-app';
17
+
18
+ // 现在你可以使用完整的类型定义
19
+ class MyCustomElement extends SunPanelElement {
20
+ protected override render(): TemplateResult {
21
+ return html`<div>Hello World</div>`;
22
+ }
23
+ }
24
+ ```
25
+
26
+ ## 协议声明
27
+
28
+ MIT License
29
+
30
+ Copyright (c) 2024 Sun Panel Team
31
+
32
+ Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ of this software and associated documentation files (the "Software"), to deal
34
+ in the Software without restriction, including without limitation the rights
35
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ copies of the Software, and to permit persons to whom the Software is
37
+ furnished to do so, subject to the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be included in all
40
+ copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48
+ SOFTWARE.
@@ -0,0 +1,61 @@
1
+ import { LitElement, TemplateResult } from 'lit';
2
+ /**
3
+ * Sun Panel 基础元素抽象类
4
+ * 提供了微应用开发的基础能力
5
+ */
6
+ export declare class SunPanelElement extends LitElement {
7
+ private _initialized;
8
+ private _eventListeners;
9
+ constructor();
10
+ /**
11
+ * 初始化微应用
12
+ */
13
+ initializeMicroApp(): void;
14
+ /**
15
+ * 连接回调
16
+ */
17
+ connectedCallback(): void;
18
+ /**
19
+ * 断开连接回调
20
+ */
21
+ disconnectedCallback(): void;
22
+ /**
23
+ * 属性变化回调
24
+ * 注意:必须先调用 super,否则 LitElement 的响应式属性会失效
25
+ */
26
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
27
+ /**
28
+ * 设置事件监听器
29
+ */
30
+ protected _setupEventListeners(): void;
31
+ /**
32
+ * 清理事件监听器
33
+ */
34
+ protected _cleanupEventListeners(): void;
35
+ /**
36
+ * 添加事件监听器
37
+ */
38
+ addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
39
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
40
+ /**
41
+ * 派发自定义事件
42
+ */
43
+ dispatchCustomEvent<T = any>(eventName: string, detail?: T): void;
44
+ /**
45
+ * 连接时回调
46
+ */
47
+ onConnected(): void;
48
+ /**
49
+ * 断开连接时回调
50
+ */
51
+ onDisconnected(): void;
52
+ /**
53
+ * 属性变化时回调
54
+ */
55
+ onAttributeChanged(_name: string, _oldValue: string | null, _newValue: string | null): void;
56
+ /**
57
+ * 渲染方法(需要子类实现)
58
+ */
59
+ render(): TemplateResult;
60
+ }
61
+ //# sourceMappingURL=SunPanelElement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SunPanelElement.d.ts","sourceRoot":"","sources":["../src/SunPanelElement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAEvD;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,eAAe,CAA+B;;IAQtD;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAO1B;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAMzB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAM5B;;;OAGG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAK9F;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAItC;;OAEG;IACH,SAAS,CAAC,sBAAsB,IAAI,IAAI;IAYxC;;OAEG;IACH,gBAAgB,CAAC,CAAC,SAAS,MAAM,mBAAmB,EAClD,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,GAAG,EAChE,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI;IACP,gBAAgB,CACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,kCAAkC,EAC5C,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI;IASP;;OAEG;IACH,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI;IASjE;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI3F;;OAEG;IACH,MAAM,IAAI,cAAc;CAIzB"}
@@ -0,0 +1,67 @@
1
+ import { SunPanelElement } from './SunPanelElement';
2
+ import { TemplateResult, PropertyValueMap } from 'lit';
3
+ import { SpContextPage, NetworkMode } from './types/common';
4
+ import { PageInitializedParam } from './types/api';
5
+ /**
6
+ * Sun Panel 页面元素基类
7
+ * 用于开发微应用中的页面组件,以窗口的形式加载
8
+ */
9
+ export declare class SunPanelPageElement extends SunPanelElement {
10
+ static properties: {
11
+ spCtx: {
12
+ type: ObjectConstructor;
13
+ attribute: boolean;
14
+ };
15
+ };
16
+ spCtx: SpContextPage;
17
+ constructor();
18
+ /**
19
+ * 精确更新方法(父级调用此方法更新状态)
20
+ * @param partialContext - 需要更新的部分状态
21
+ * @example element.updateContext({ theme: 'dark', itemInfo: {...} })
22
+ */
23
+ updateContext(partialContext: Partial<SpContextPage>): void;
24
+ /**
25
+ * 利用 Lit 生命周期处理状态变化
26
+ */
27
+ /**
28
+ * 首次渲染完成后调用(只执行一次)
29
+ * 适合进行 DOM 查询、初始化第三方库等操作
30
+ */
31
+ firstUpdated(changedProperties: PropertyValueMap<any> | Map<string, any>): void;
32
+ /**
33
+ * 每次更新完成后调用
34
+ */
35
+ updated(changedProperties: PropertyValueMap<any> | Map<string, any>): void;
36
+ onConnected(): void;
37
+ /**
38
+ * 初始化完成回调
39
+ * 子类可重写此方法,用于初始化完成后的逻辑
40
+ */
41
+ onInitialized(_param: PageInitializedParam): void;
42
+ /**
43
+ * 首次渲染完成回调
44
+ * 子类可重写此方法,用于 DOM 查询、第三方库初始化等
45
+ */
46
+ onFirstRendered(): void;
47
+ /**
48
+ * 主题变化回调
49
+ * @param isDark - true | false
50
+ */
51
+ onIsDarkChanged(_isDark: boolean): void;
52
+ /**
53
+ * 语言变化回调
54
+ * @param language - 语言代码,如 'zh-CN' | 'en-US' ....
55
+ */
56
+ onLanguageChanged(_language: string): void;
57
+ /**
58
+ * 网络模式变化回调
59
+ * @param networkMode - 网络模式,如 'wan' | 'lan'
60
+ */
61
+ onNetworkModeChanged(_networkMode: NetworkMode): void;
62
+ /**
63
+ * 渲染方法(需要子类实现)
64
+ */
65
+ render(): TemplateResult;
66
+ }
67
+ //# sourceMappingURL=SunPanelPageElement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SunPanelPageElement.d.ts","sourceRoot":"","sources":["../src/SunPanelPageElement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAQ,cAAc,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAe,MAAM,aAAa,CAAC;AAGhE;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;IAEtD,MAAM,CAAC,UAAU;;;;;MAGf;IAEF,KAAK,EAAE,aAAa,CAAC;;IAmBrB;;;;OAIG;IACH,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAe3D;;OAEG;IACH;;;OAGG;IACH,YAAY,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAK/E;;OAEG;IACH,OAAO,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IA4B1E,WAAW,IAAI,IAAI;IAKnB;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAIjD;;;OAGG;IACH,eAAe,IAAI,IAAI;IAIvB;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIvC;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACH,oBAAoB,CAAC,YAAY,EAAE,WAAW,GAAG,IAAI;IAIrD;;OAEG;IACH,MAAM,IAAI,cAAc;CAIzB"}
@@ -0,0 +1,78 @@
1
+ import { SunPanelElement } from './SunPanelElement';
2
+ import { TemplateResult, PropertyValueMap } from 'lit';
3
+ import { SpContextWidget, GridSizeType, BackgroundType, NetworkMode } from './types/common';
4
+ /**
5
+ * Sun Panel 小部件(卡片)元素基类
6
+ * 用于开发微应用中的卡片组件
7
+ */
8
+ export declare class SunPanelWidgetElement extends SunPanelElement {
9
+ static properties: {
10
+ spCtx: {
11
+ type: ObjectConstructor;
12
+ attribute: boolean;
13
+ };
14
+ };
15
+ spCtx: SpContextWidget;
16
+ constructor();
17
+ /**
18
+ * 精确更新方法(父级调用此方法更新状态)
19
+ * @param partialContext - 需要更新的部分状态
20
+ * @param callback - 可选的初始化完成回调
21
+ * @example element.updateContext({ theme: 'dark', itemInfo: {...} })
22
+ * @example element.updateContext({ api, widgetInfo }, (success, error) => { ... })
23
+ */
24
+ updateContext(partialContext: Partial<SpContextWidget>): void;
25
+ /**
26
+ * 利用 Lit 生命周期处理状态变化
27
+ */
28
+ /**
29
+ * 首次渲染完成后调用(只执行一次)
30
+ * 适合进行 DOM 查询、初始化第三方库等操作
31
+ */
32
+ firstUpdated(changedProperties: PropertyValueMap<any> | Map<string, any>): void;
33
+ /**
34
+ * 每次更新完成后调用
35
+ */
36
+ updated(changedProperties: PropertyValueMap<any> | Map<string, any>): void;
37
+ onConnected(): void;
38
+ /**
39
+ * 初始化完成回调
40
+ * 子类可重写此方法,用于初始化完成后的逻辑
41
+ */
42
+ onInitialized(): void;
43
+ /**
44
+ * 首次渲染完成回调
45
+ * 子类可重写此方法,用于 DOM 查询、第三方库初始化等
46
+ */
47
+ onFirstRendered(): void;
48
+ /**
49
+ * 卡片尺寸变化回调
50
+ * @param cardSize - 卡片尺寸,如 1 | 2 | 3 | 4
51
+ */
52
+ onGridSizeTypeChanged(_cardSize: GridSizeType): void;
53
+ /**
54
+ * 卡片背景颜色变化回调
55
+ * @param background - 背景颜色,如 '#000000' | 'rgb(0,0,0)' | 'rgba(0,0,0,1)' | 'black' ...
56
+ */
57
+ onBackgroundColorChanged(_background: BackgroundType): void;
58
+ /**
59
+ * 主题变化回调
60
+ * @param isDark - true | false
61
+ */
62
+ onIsDarkChanged(_isDark: boolean): void;
63
+ /**
64
+ * 语言变化回调
65
+ * @param language - 语言代码,如 'zh-CN' | 'en-US' ....
66
+ */
67
+ onLanguageChanged(_language: string): void;
68
+ /**
69
+ * 网络模式变化回调
70
+ * @param networkMode - 网络模式,如 'wan' | 'lan'
71
+ */
72
+ onNetworkModeChanged(_networkMode: NetworkMode): void;
73
+ /**
74
+ * 渲染方法(需要子类实现)
75
+ */
76
+ render(): TemplateResult;
77
+ }
78
+ //# sourceMappingURL=SunPanelWidgetElement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SunPanelWidgetElement.d.ts","sourceRoot":"","sources":["../src/SunPanelWidgetElement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAQ,cAAc,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AAGlH;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,eAAe;IAExD,MAAM,CAAC,UAAU;;;;;MAGf;IAEF,KAAK,EAAE,eAAe,CAAC;;IAmBvB;;;;;;OAMG;IACH,aAAa,CAAC,cAAc,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAgB7D;;OAEG;IACH;;;OAGG;IACH,YAAY,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAK/E;;OAEG;IACH,OAAO,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmC1E,WAAW,IAAI,IAAI;IAKnB;;;OAGG;IACH,aAAa,IAAI,IAAI;IAKrB;;;OAGG;IACH,eAAe,IAAI,IAAI;IAIvB;;;OAGG;IACH,qBAAqB,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAIpD;;;OAGG;IACH,wBAAwB,CAAC,WAAW,EAAE,cAAc,GAAG,IAAI;IAI3D;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIvC;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI1C;;;OAGG;IACH,oBAAoB,CAAC,YAAY,EAAE,WAAW,GAAG,IAAI;IAIrD;;OAEG;IACH,MAAM,IAAI,cAAc;CAIzB"}
@@ -0,0 +1,24 @@
1
+ !function(t){
2
+ /**
3
+ * @license
4
+ * Copyright 2019 Google LLC
5
+ * SPDX-License-Identifier: BSD-3-Clause
6
+ */
7
+ const e=globalThis,s=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),n=new WeakMap;let r=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const e=this.t;if(s&&void 0===t){const s=void 0!==e&&1===e.length;s&&(t=n.get(e)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),s&&n.set(e,t))}return t}toString(){return this.cssText}};const o=s?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return(t=>new r("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:a,defineProperty:h,getOwnPropertyDescriptor:l,getOwnPropertyNames:d,getOwnPropertySymbols:c,getPrototypeOf:p}=Object,u=globalThis,g=u.trustedTypes,$=g?g.emptyScript:"",f=u.reactiveElementPolyfillSupport,m=(t,e)=>t,_={toAttribute(t,e){switch(e){case Boolean:t=t?$:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let s=t;switch(e){case Boolean:s=null!==t;break;case Number:s=null===t?null:Number(t);break;case Object:case Array:try{s=JSON.parse(t)}catch(t){s=null}}return s}},y=(t,e)=>!a(t,e),A={attribute:!0,type:String,converter:_,reflect:!1,useDefault:!1,hasChanged:y};
8
+ /**
9
+ * @license
10
+ * Copyright 2017 Google LLC
11
+ * SPDX-License-Identifier: BSD-3-Clause
12
+ */Symbol.metadata??=Symbol("metadata"),u.litPropertyMetadata??=new WeakMap;let v=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=A){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const s=Symbol(),i=this.getPropertyDescriptor(t,s,e);void 0!==i&&h(this.prototype,t,i)}}static getPropertyDescriptor(t,e,s){const{get:i,set:n}=l(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:i,set(e){const r=i?.call(this);n?.call(this,e),this.requestUpdate(t,r,s)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??A}static _$Ei(){if(this.hasOwnProperty(m("elementProperties")))return;const t=p(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(m("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(m("properties"))){const t=this.properties,e=[...d(t),...c(t)];for(const s of e)this.createProperty(s,t[s])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,s]of e)this.elementProperties.set(t,s)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const s=this._$Eu(t,e);void 0!==s&&this._$Eh.set(s,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const s=new Set(t.flat(1/0).reverse());for(const t of s)e.unshift(o(t))}else void 0!==t&&e.push(o(t));return e}static _$Eu(t,e){const s=e.attribute;return!1===s?void 0:"string"==typeof s?s:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const s of e.keys())this.hasOwnProperty(s)&&(t.set(s,this[s]),delete this[s]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((t,i)=>{if(s)t.adoptedStyleSheets=i.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const s of i){const i=document.createElement("style"),n=e.litNonce;void 0!==n&&i.setAttribute("nonce",n),i.textContent=s.cssText,t.appendChild(i)}})(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,s){this._$AK(t,s)}_$ET(t,e){const s=this.constructor.elementProperties.get(t),i=this.constructor._$Eu(t,s);if(void 0!==i&&!0===s.reflect){const n=(void 0!==s.converter?.toAttribute?s.converter:_).toAttribute(e,s.type);this._$Em=t,null==n?this.removeAttribute(i):this.setAttribute(i,n),this._$Em=null}}_$AK(t,e){const s=this.constructor,i=s._$Eh.get(t);if(void 0!==i&&this._$Em!==i){const t=s.getPropertyOptions(i),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:_;this._$Em=i;const r=n.fromAttribute(e,t.type);this[i]=r??this._$Ej?.get(i)??r,this._$Em=null}}requestUpdate(t,e,s,i=!1,n){if(void 0!==t){const r=this.constructor;if(!1===i&&(n=this[t]),s??=r.getPropertyOptions(t),!((s.hasChanged??y)(n,e)||s.useDefault&&s.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(r._$Eu(t,s))))return;this.C(t,e,s)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:s,reflect:i,wrapped:n},r){s&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??e??this[t]),!0!==n||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||s||(e=void 0),this._$AL.set(t,e)),!0===i&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,s]of t){const{wrapped:t}=s,i=this[e];!0!==t||this._$AL.has(e)||void 0===i||this.C(e,void 0,s,i)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};v.elementStyles=[],v.shadowRootOptions={mode:"open"},v[m("elementProperties")]=new Map,v[m("finalized")]=new Map,f?.({ReactiveElement:v}),(u.reactiveElementVersions??=[]).push("2.1.2");
13
+ /**
14
+ * @license
15
+ * Copyright 2017 Google LLC
16
+ * SPDX-License-Identifier: BSD-3-Clause
17
+ */
18
+ const b=globalThis,C=t=>t,E=b.trustedTypes,w=E?E.createPolicy("lit-html",{createHTML:t=>t}):void 0,S="$lit$",x=`lit$${Math.random().toFixed(9).slice(2)}$`,k="?"+x,P=`<${k}>`,M=document,U=()=>M.createComment(""),O=t=>null===t||"object"!=typeof t&&"function"!=typeof t,N=Array.isArray,T="[ \t\n\f\r]",L=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,H=/-->/g,R=/>/g,z=RegExp(`>|${T}(?:([^\\s"'>=/]+)(${T}*=${T}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),D=/'/g,I=/"/g,j=/^(?:script|style|textarea|title)$/i,V=(t=>(e,...s)=>({_$litType$:t,strings:e,values:s}))(1),B=Symbol.for("lit-noChange"),F=Symbol.for("lit-nothing"),W=new WeakMap,q=M.createTreeWalker(M,129);function G(t,e){if(!N(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==w?w.createHTML(e):e}const J=(t,e)=>{const s=t.length-1,i=[];let n,r=2===e?"<svg>":3===e?"<math>":"",o=L;for(let e=0;e<s;e++){const s=t[e];let a,h,l=-1,d=0;for(;d<s.length&&(o.lastIndex=d,h=o.exec(s),null!==h);)d=o.lastIndex,o===L?"!--"===h[1]?o=H:void 0!==h[1]?o=R:void 0!==h[2]?(j.test(h[2])&&(n=RegExp("</"+h[2],"g")),o=z):void 0!==h[3]&&(o=z):o===z?">"===h[0]?(o=n??L,l=-1):void 0===h[1]?l=-2:(l=o.lastIndex-h[2].length,a=h[1],o=void 0===h[3]?z:'"'===h[3]?I:D):o===I||o===D?o=z:o===H||o===R?o=L:(o=z,n=void 0);const c=o===z&&t[e+1].startsWith("/>")?" ":"";r+=o===L?s+P:l>=0?(i.push(a),s.slice(0,l)+S+s.slice(l)+x+c):s+x+(-2===l?e:c)}return[G(t,r+(t[s]||"<?>")+(2===e?"</svg>":3===e?"</math>":"")),i]};class K{constructor({strings:t,_$litType$:e},s){let i;this.parts=[];let n=0,r=0;const o=t.length-1,a=this.parts,[h,l]=J(t,e);if(this.el=K.createElement(h,s),q.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(i=q.nextNode())&&a.length<o;){if(1===i.nodeType){if(i.hasAttributes())for(const t of i.getAttributeNames())if(t.endsWith(S)){const e=l[r++],s=i.getAttribute(t).split(x),o=/([.?@])?(.*)/.exec(e);a.push({type:1,index:n,name:o[2],strings:s,ctor:"."===o[1]?tt:"?"===o[1]?et:"@"===o[1]?st:Y}),i.removeAttribute(t)}else t.startsWith(x)&&(a.push({type:6,index:n}),i.removeAttribute(t));if(j.test(i.tagName)){const t=i.textContent.split(x),e=t.length-1;if(e>0){i.textContent=E?E.emptyScript:"";for(let s=0;s<e;s++)i.append(t[s],U()),q.nextNode(),a.push({type:2,index:++n});i.append(t[e],U())}}}else if(8===i.nodeType)if(i.data===k)a.push({type:2,index:n});else{let t=-1;for(;-1!==(t=i.data.indexOf(x,t+1));)a.push({type:7,index:n}),t+=x.length-1}n++}}static createElement(t,e){const s=M.createElement("template");return s.innerHTML=t,s}}function Z(t,e,s=t,i){if(e===B)return e;let n=void 0!==i?s._$Co?.[i]:s._$Cl;const r=O(e)?void 0:e._$litDirective$;return n?.constructor!==r&&(n?._$AO?.(!1),void 0===r?n=void 0:(n=new r(t),n._$AT(t,s,i)),void 0!==i?(s._$Co??=[])[i]=n:s._$Cl=n),void 0!==n&&(e=Z(t,n._$AS(t,e.values),n,i)),e}class Q{constructor(t,e){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:e},parts:s}=this._$AD,i=(t?.creationScope??M).importNode(e,!0);q.currentNode=i;let n=q.nextNode(),r=0,o=0,a=s[0];for(;void 0!==a;){if(r===a.index){let e;2===a.type?e=new X(n,n.nextSibling,this,t):1===a.type?e=new a.ctor(n,a.name,a.strings,this,t):6===a.type&&(e=new it(n,this,t)),this._$AV.push(e),a=s[++o]}r!==a?.index&&(n=q.nextNode(),r++)}return q.currentNode=M,i}p(t){let e=0;for(const s of this._$AV)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,e),e+=s.strings.length-2):s._$AI(t[e])),e++}}class X{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,s,i){this.type=2,this._$AH=F,this._$AN=void 0,this._$AA=t,this._$AB=e,this._$AM=s,this.options=i,this._$Cv=i?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode;const e=this._$AM;return void 0!==e&&11===t?.nodeType&&(t=e.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,e=this){t=Z(this,t,e),O(t)?t===F||null==t||""===t?(this._$AH!==F&&this._$AR(),this._$AH=F):t!==this._$AH&&t!==B&&this._(t):void 0!==t._$litType$?this.$(t):void 0!==t.nodeType?this.T(t):(t=>N(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==F&&O(this._$AH)?this._$AA.nextSibling.data=t:this.T(M.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:s}=t,i="number"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=K.createElement(G(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===i)this._$AH.p(e);else{const t=new Q(i,this),s=t.u(this.options);t.p(e),this.T(s),this._$AH=t}}_$AC(t){let e=W.get(t.strings);return void 0===e&&W.set(t.strings,e=new K(t)),e}k(t){N(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let s,i=0;for(const n of t)i===e.length?e.push(s=new X(this.O(U()),this.O(U()),this,this.options)):s=e[i],s._$AI(n),i++;i<e.length&&(this._$AR(s&&s._$AB.nextSibling,i),e.length=i)}_$AR(t=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);t!==this._$AB;){const e=C(t).nextSibling;C(t).remove(),t=e}}setConnected(t){void 0===this._$AM&&(this._$Cv=t,this._$AP?.(t))}}class Y{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,e,s,i,n){this.type=1,this._$AH=F,this._$AN=void 0,this.element=t,this.name=e,this._$AM=i,this.options=n,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=F}_$AI(t,e=this,s,i){const n=this.strings;let r=!1;if(void 0===n)t=Z(this,t,e,0),r=!O(t)||t!==this._$AH&&t!==B,r&&(this._$AH=t);else{const i=t;let o,a;for(t=n[0],o=0;o<n.length-1;o++)a=Z(this,i[s+o],e,o),a===B&&(a=this._$AH[o]),r||=!O(a)||a!==this._$AH[o],a===F?t=F:t!==F&&(t+=(a??"")+n[o+1]),this._$AH[o]=a}r&&!i&&this.j(t)}j(t){t===F?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}}class tt extends Y{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===F?void 0:t}}class et extends Y{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==F)}}class st extends Y{constructor(t,e,s,i,n){super(t,e,s,i,n),this.type=5}_$AI(t,e=this){if((t=Z(this,t,e,0)??F)===B)return;const s=this._$AH,i=t===F&&s!==F||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,n=t!==F&&(s===F||i);i&&this.element.removeEventListener(this.name,this,s),n&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}}class it{constructor(t,e,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=e,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){Z(this,t)}}const nt=b.litHtmlPolyfillSupport;nt?.(K,X),(b.litHtmlVersions??=[]).push("3.3.2");const rt=globalThis;
19
+ /**
20
+ * @license
21
+ * Copyright 2017 Google LLC
22
+ * SPDX-License-Identifier: BSD-3-Clause
23
+ */class ot extends v{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=((t,e,s)=>{const i=s?.renderBefore??e;let n=i._$litPart$;if(void 0===n){const t=s?.renderBefore??null;i._$litPart$=n=new X(e.insertBefore(U(),t),t,void 0,s??{})}return n._$AI(t),n})(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return B}}ot._$litElement$=!0,ot.finalized=!0,rt.litElementHydrateSupport?.({LitElement:ot});const at=rt.litElementPolyfillSupport;at?.({LitElement:ot}),(rt.litElementVersions??=[]).push("4.2.2");class ht extends ot{constructor(){super(),this._initialized=!1,this._eventListeners=new Map}initializeMicroApp(){this._initialized||(this._setupEventListeners(),this._initialized=!0)}connectedCallback(){super.connectedCallback(),this.initializeMicroApp(),this.onConnected()}disconnectedCallback(){super.disconnectedCallback(),this._cleanupEventListeners(),this.onDisconnected()}attributeChangedCallback(t,e,s){super.attributeChangedCallback(t,e,s),this.onAttributeChanged(t,e,s)}_setupEventListeners(){}_cleanupEventListeners(){const t=Array.from(this._eventListeners.entries());for(const[e,s]of t)s.forEach(t=>{window.removeEventListener(e,t)});this._eventListeners.clear()}addEventListener(t,e,s){super.addEventListener(t,e,s)}dispatchCustomEvent(t,e){const s=new CustomEvent(t,{bubbles:!0,composed:!0,detail:e});this.dispatchEvent(s)}onConnected(){}onDisconnected(){}onAttributeChanged(t,e,s){}render(){return V``}}class lt extends ht{constructor(){super(),this.spCtx={api:{},isDark:!1,language:"zh-CN",networkMode:"wan",staticPath:"",role:0,background:"",gridSizeType:1,widgetInfo:{}}}updateContext(t){if(!t||"object"!=typeof t)return;const e={};for(const s in t)void 0!==t[s]&&(e[s]=t[s]);this.spCtx={...this.spCtx,...e}}firstUpdated(t){super.firstUpdated?.(t),this.onFirstRendered()}updated(t){if(super.updated(t),t.has("spCtx")){const e=t.get("spCtx")||{},s=this.spCtx;s.widgetInfo&&(this.spCtx.background=s.widgetInfo.background||""),s.isDark!==e.isDark&&this.onIsDarkChanged(s.isDark),s.language!==e.language&&this.onLanguageChanged(s.language),s.networkMode!==e.networkMode&&this.onNetworkModeChanged(s.networkMode),s.gridSizeType&&(this.spCtx.gridSizeType=s.gridSizeType,this.onGridSizeTypeChanged(s.gridSizeType))}}onConnected(){super.onConnected(),this.onInitialized()}onInitialized(){}onFirstRendered(){}onGridSizeTypeChanged(t){}onBackgroundColorChanged(t){}onIsDarkChanged(t){}onLanguageChanged(t){}onNetworkModeChanged(t){}render(){return V``}}lt.properties={spCtx:{type:Object,attribute:!1}};class dt extends ht{constructor(){super(),this.spCtx={api:{},isDark:!1,language:"zh-CN",networkMode:"wan",staticPath:"",role:0,background:"",widgetInfo:{},customParam:{}}}updateContext(t){if(!t||"object"!=typeof t)return;const e={};for(const s in t)void 0!==t[s]&&(e[s]=t[s]);this.spCtx={...this.spCtx,...e}}firstUpdated(t){super.firstUpdated?.(t),this.onFirstRendered()}updated(t){if(super.updated(t),t.has("spCtx")){const e=t.get("spCtx")||{},s=this.spCtx;s.isDark!==e.isDark&&this.onIsDarkChanged(s.isDark),s.language!==e.language&&this.onLanguageChanged(s.language),s.networkMode!==e.networkMode&&this.onNetworkModeChanged(s.networkMode)}}onConnected(){super.onConnected(),this.onInitialized({widgetInfo:this.spCtx.widgetInfo,customParam:this.spCtx.customParam})}onInitialized(t){}onFirstRendered(){}onIsDarkChanged(t){}onLanguageChanged(t){}onNetworkModeChanged(t){}render(){return V``}}dt.properties={spCtx:{type:Object,attribute:!1}};class ct extends Error{constructor(t){super(`Validation failed: ${t.map(t=>t.message).join(", ")}`),this.name="ValidationError",this.errors=t}}class pt{static async validateField(t,e,s="field"){const i=[];if(e.required&&(null==t||""===t))return i.push({field:s,message:e.message||`${s} is required`,value:t}),i;if(null==t||""===t)return i;if(e.type){let n=!1;switch(e.type){case"string":n="string"==typeof t;break;case"number":n="number"==typeof t&&!isNaN(t);break;case"boolean":n="boolean"==typeof t;break;case"object":n="object"==typeof t&&null!==t&&!Array.isArray(t);break;case"array":n=Array.isArray(t);break;case"date":n=t instanceof Date||!isNaN(Date.parse(t));break;case"email":n="string"==typeof t&&/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t);break;case"url":try{new URL(t),n=!0}catch{n=!1}break;default:n=!0}n||i.push({field:s,message:e.message||`${s} must be of type ${e.type}`,value:t})}if(void 0!==e.minLength&&"string"==typeof t&&t.length<e.minLength&&i.push({field:s,message:e.message||`${s} must be at least ${e.minLength} characters`,value:t}),void 0!==e.maxLength&&"string"==typeof t&&t.length>e.maxLength&&i.push({field:s,message:e.message||`${s} must be no more than ${e.maxLength} characters`,value:t}),void 0!==e.min&&"number"==typeof t&&t<e.min&&i.push({field:s,message:e.message||`${s} must be at least ${e.min}`,value:t}),void 0!==e.max&&"number"==typeof t&&t>e.max&&i.push({field:s,message:e.message||`${s} must be no more than ${e.max}`,value:t}),e.pattern&&"string"==typeof t&&!e.pattern.test(t)&&i.push({field:s,message:e.message||`${s} format is invalid`,value:t}),e.validator)try{const n=await Promise.resolve(e.validator(t));"string"==typeof n?i.push({field:s,message:n,value:t}):!1===n&&i.push({field:s,message:e.message||`${s} is invalid`,value:t})}catch(n){i.push({field:s,message:e.message||`Validation failed for ${s}: ${n instanceof Error?n.message:String(n)}`,value:t})}return i}static async validateObject(t,e){const s=[];for(const i of Object.keys(e)){const n=e[i],r=t[i],o=await this.validateField(r,n,i);s.push(...o)}return s}static async validateArray(t,e){if(!Array.isArray(t))return[{field:"array",message:"Value must be an array",value:t}];const s=[];if(void 0!==e.min&&t.length<e.min&&s.push({field:"array",message:e.message||`Array must have at least ${e.min} items`,value:t}),void 0!==e.max&&t.length>e.max&&s.push({field:"array",message:e.message||`Array must have no more than ${e.max} items`,value:t}),e.validator)for(let i=0;i<t.length;i++){const n=t[i],r=await this.validateField(n,e,`array[${i}]`);s.push(...r)}return s}}t.FormValidator=class{constructor(t){this.rules=t}async validate(t){return await pt.validateObject(t,this.rules)}async validateOrThrow(t){const e=await this.validate(t);if(e.length>0)throw new ct(e)}},t.SunPanelElement=ht,t.SunPanelPageElement=dt,t.SunPanelWidgetElement=lt,t.VERSION='"1.0.5"',t.ValidationError=ct,t.Validator=pt}(this.SunPanelMicroApp=this.SunPanelMicroApp||{});
24
+ //# sourceMappingURL=index.bundle.js.map