@kupola/kupola 1.4.9 → 1.5.1

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/js/depends.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ref } from './data-bind.js';
2
+ import { getConfig } from './kupola-config.js';
2
3
 
3
4
  // ============================================================
4
5
  // Scheduler - 批量更新、去重、微任务调度
@@ -273,6 +274,11 @@ class FetchedSource extends DependsSource {
273
274
 
274
275
  async fetch(params) {
275
276
  let url = this.config.source;
277
+ const httpConfig = getConfig('http');
278
+
279
+ if (httpConfig?.baseURL && !url.startsWith('http://') && !url.startsWith('https://')) {
280
+ url = httpConfig.baseURL + url.replace(/^\//, '');
281
+ }
276
282
 
277
283
  // Replace path params (:id -> value)
278
284
  for (const key in params) {
package/js/i18n.js CHANGED
@@ -1,8 +1,11 @@
1
+ import { getConfig } from './kupola-config.js';
2
+
1
3
  class KupolaI18n {
2
4
  constructor(options = {}) {
5
+ const config = getConfig();
3
6
  this.locales = options.locales || {};
4
- this.currentLocale = options.defaultLocale || 'zh-CN';
5
- this.fallbackLocale = options.fallbackLocale || 'zh-CN';
7
+ this.currentLocale = options.defaultLocale || config.i18n?.locale || 'zh-CN';
8
+ this.fallbackLocale = options.fallbackLocale || config.i18n?.fallbackLocale || 'en-US';
6
9
  this.delimiter = options.delimiter || '.';
7
10
  this.missingHandler = options.missingHandler || ((key) => {
8
11
  console.warn(`Missing translation: ${key}`);
@@ -0,0 +1,69 @@
1
+ const config = {
2
+ paths: {
3
+ icons: '/icons/',
4
+ base: '/'
5
+ },
6
+ theme: {
7
+ default: 'dark',
8
+ brand: 'zengqing'
9
+ },
10
+ i18n: {
11
+ locale: 'zh-CN',
12
+ fallbackLocale: 'en-US'
13
+ },
14
+ http: {
15
+ baseURL: '',
16
+ timeout: 10000
17
+ },
18
+ components: {
19
+ autoInit: true,
20
+ silentErrors: false
21
+ },
22
+ store: {
23
+ persist: true,
24
+ prefix: 'kupola-'
25
+ },
26
+ events: {
27
+ global: true
28
+ }
29
+ };
30
+
31
+ export function setConfig(options) {
32
+ mergeDeep(config, options);
33
+ }
34
+
35
+ export function getConfig(key) {
36
+ if (!key) return config;
37
+ return getNestedValue(config, key);
38
+ }
39
+
40
+ export function getIconsPath() {
41
+ return config.paths.base + config.paths.icons.replace(/^\//, '');
42
+ }
43
+
44
+ export function getBasePath() {
45
+ return config.paths.base;
46
+ }
47
+
48
+ export function getDefaultTheme() {
49
+ return config.theme.default;
50
+ }
51
+
52
+ export function getDefaultBrand() {
53
+ return config.theme.brand;
54
+ }
55
+
56
+ function mergeDeep(target, source) {
57
+ for (const key in source) {
58
+ if (source[key] instanceof Object && key in target && target[key] instanceof Object) {
59
+ mergeDeep(target[key], source[key]);
60
+ } else {
61
+ target[key] = source[key];
62
+ }
63
+ }
64
+ return target;
65
+ }
66
+
67
+ function getNestedValue(obj, key) {
68
+ return key.split('.').reduce((o, k) => (o && o[k]) !== undefined ? o[k] : undefined, obj);
69
+ }
package/js/kupola-core.js CHANGED
@@ -9,6 +9,7 @@ import { KupolaLifecycle } from './kupola-lifecycle.js';
9
9
  import { kupolaInitializer } from './initializer.js';
10
10
  import { kupolaData } from './data-bind.js';
11
11
  import { initTheme } from './theme.js';
12
+ import { getConfig } from './kupola-config.js';
12
13
 
13
14
  let kupolaRegistry = null;
14
15
 
@@ -19,16 +20,20 @@ if (typeof window !== 'undefined') {
19
20
  /** Bootstrap the Kupola component system (data binding, theme, component discovery). */
20
21
  async function kupolaBootstrap() {
21
22
  if (typeof window !== 'undefined') {
23
+ const config = getConfig();
22
24
  // Load persisted data and bind data-bind elements
23
25
  kupolaData.loadPersisted();
24
26
  kupolaData.bind();
25
27
  // Initialize theme
26
28
  initTheme();
27
- // Initialize function-based components first
28
- await kupolaInitializer.initializeAll();
29
- // Then bootstrap class-based components
30
- if (kupolaRegistry) {
31
- await kupolaRegistry.bootstrap();
29
+
30
+ if (config.components?.autoInit !== false) {
31
+ // Initialize function-based components first
32
+ await kupolaInitializer.initializeAll();
33
+ // Then bootstrap class-based components
34
+ if (kupolaRegistry) {
35
+ await kupolaRegistry.bootstrap();
36
+ }
32
37
  }
33
38
  }
34
39
  }
package/js/theme.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { getIconsPath, getDefaultTheme, getDefaultBrand } from './kupola-config.js';
2
+
1
3
  const THEME_KEY = 'kupola-theme';
2
4
  const BRAND_KEY = 'kupola-brand';
3
5
 
@@ -16,7 +18,7 @@ const BRAND_OPTIONS = [
16
18
  ];
17
19
 
18
20
  function getTheme() {
19
- return localStorage.getItem(THEME_KEY) || 'dark';
21
+ return localStorage.getItem(THEME_KEY) || getDefaultTheme();
20
22
  }
21
23
 
22
24
  function setTheme(theme) {
@@ -39,7 +41,7 @@ function setTheme(theme) {
39
41
  }
40
42
 
41
43
  function getBrand() {
42
- return localStorage.getItem(BRAND_KEY) || 'zengqing';
44
+ return localStorage.getItem(BRAND_KEY) || getDefaultBrand();
43
45
  }
44
46
 
45
47
  function setBrand(brandId) {
@@ -76,7 +78,8 @@ function updateThemeIcon(toggleBtn) {
76
78
  const iconEl = toggleBtn.querySelector('.theme-icon');
77
79
  if (iconEl) {
78
80
  const currentTheme = getTheme();
79
- iconEl.src = currentTheme === 'dark' ? '/icons/sun.svg' : '/icons/moon.svg';
81
+ const iconsPath = getIconsPath();
82
+ iconEl.src = currentTheme === 'dark' ? iconsPath + 'sun.svg' : iconsPath + 'moon.svg';
80
83
  }
81
84
  }
82
85
 
@@ -203,12 +206,10 @@ function createThemeToggle() {
203
206
 
204
207
  const icon = document.createElement('img');
205
208
  icon.className = 'theme-icon';
206
- const scripts = document.getElementsByTagName('script');
207
- const currentScript = scripts[scripts.length - 1];
208
- const scriptPath = currentScript.src.substring(0, currentScript.src.lastIndexOf('/') + 1);
209
+ const iconsPath = getIconsPath();
209
210
  icon.src = getTheme() === 'dark'
210
- ? scriptPath + '../icons/sun.svg'
211
- : scriptPath + '../icons/moon.svg';
211
+ ? iconsPath + 'sun.svg'
212
+ : iconsPath + 'moon.svg';
212
213
  icon.width = 14;
213
214
  icon.height = 14;
214
215
  icon.alt = 'Toggle theme';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kupola/kupola",
3
- "version": "1.4.9",
3
+ "version": "1.5.1",
4
4
  "description": "A lightweight UI toolkit for any web project. No heavy frontend frameworks required.",
5
5
  "main": "dist/kupola.cjs.js",
6
6
  "module": "dist/kupola.esm.js",