@5even7/dlc-ui 0.2.3 → 0.2.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/dist/vue2.mjs CHANGED
@@ -175,9 +175,13 @@ function getPreset(kind, ref) {
175
175
  const list = kind === 'capsule' ? CAPSULE_PRESETS : kind === 'progress' ? PROGRESS_PRESETS : null;
176
176
  if (!list) throw new Error(`Unknown preset kind: ${kind} (use "capsule" or "progress")`);
177
177
  const key = String(ref).trim().toLowerCase();
178
- const found = list.find(
179
- (preset) => preset.name.toLowerCase() === key
180
- );
178
+ let found = null;
179
+ for (let index = 0; index < list.length; index += 1) {
180
+ if (list[index].name.toLowerCase() === key) {
181
+ found = list[index];
182
+ break;
183
+ }
184
+ }
181
185
  if (!found) throw new Error(`Unknown ${kind} preset: ${ref}`);
182
186
  return found;
183
187
  }
@@ -196,9 +200,8 @@ const DEFAULTS = {
196
200
  width: 454,
197
201
  height: 104,
198
202
  min: 0,
199
- max: 100,
203
+ max: 100,
200
204
  draggable: true,
201
- keyboard: true,
202
205
  disabled: false,
203
206
  readonly: false,
204
207
  valueSuffix: '%',
@@ -391,7 +394,7 @@ function normalizeRgbArgs(args) {
391
394
  if (parts.length < 3) return null;
392
395
  const to255 = (value) => {
393
396
  if (typeof value !== 'string' || !value) return null;
394
- if (value.endsWith('%')) return clampChannel((parseFloat(value) / 100) * 255);
397
+ if (value.charAt(value.length - 1) === '%') return clampChannel((parseFloat(value) / 100) * 255);
395
398
  const number = Number(value);
396
399
  return Number.isFinite(number) ? clampChannel(number) : null;
397
400
  };
@@ -399,7 +402,11 @@ function normalizeRgbArgs(args) {
399
402
  const green = to255(parts[1]);
400
403
  const blue = to255(parts[2]);
401
404
  if (red === null || green === null || blue === null) return null;
402
- return `#${[red, green, blue].map((n) => n.toString(16).padStart(2, '0')).join('')}`;
405
+ const hex = (n) => {
406
+ const text = n.toString(16);
407
+ return text.length === 1 ? `0${text}` : text;
408
+ };
409
+ return `#${hex(red)}${hex(green)}${hex(blue)}`;
403
410
  }
404
411
 
405
412
  /**
@@ -756,12 +763,13 @@ function rgb(color, alpha = 1) {
756
763
  }
757
764
 
758
765
  class FallbackRenderer {
759
- constructor(canvas, preset) {
760
- this.canvas = canvas;
761
- this.preset = preset;
762
- this.context = canvas.getContext('2d');
763
- this.visible = true;
764
- }
766
+ constructor(canvas, preset) {
767
+ this.canvas = canvas;
768
+ this.preset = preset;
769
+ this.context = canvas.getContext('2d');
770
+ this.visible = true;
771
+ this.timePhase = 0;
772
+ }
765
773
 
766
774
  resize() {
767
775
  const rect = this.canvas.getBoundingClientRect();
@@ -777,7 +785,7 @@ class FallbackRenderer {
777
785
  drawNebula(time) {
778
786
  const ctx = this.context;
779
787
  const { width, height } = this.canvas;
780
- const t = time * (this.preset.speed || 1);
788
+ const t = (time + this.timePhase) * (this.preset.speed || 1);
781
789
  const phase = (this.preset.seed || 0) * 0.7;
782
790
  const gradient = ctx.createLinearGradient(0, 0, width, height);
783
791
  gradient.addColorStop(0, this.preset.colors[0]);
@@ -812,7 +820,10 @@ class FallbackRenderer {
812
820
  }
813
821
 
814
822
  randomize() {
815
- if (this.preset) this.preset.seed = Math.random() * 100;
823
+ if (this.preset) {
824
+ this.preset.seed = Math.random() * 100;
825
+ this.timePhase = Math.random() * Math.PI * 2;
826
+ }
816
827
  }
817
828
  setMouseColor() {}
818
829
  dispose() {}
@@ -1038,10 +1049,9 @@ function createCapsule(container, options = {}) {
1038
1049
  for (const name of Object.keys(vars)) root.style.setProperty(name, vars[name]);
1039
1050
  if (merged.textRatio !== undefined) {
1040
1051
  root.style.setProperty('--hj-text-width', `${merged.textRatio}%`);
1041
- const userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1042
- if (merged.textRatio === 0) root.style.setProperty('--hj-text-min-width', '0');
1043
- else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);
1044
- else root.style.removeProperty('--hj-text-min-width');
1052
+ // textRatio 是文字区宽度的唯一权威值:min-width 会阻止其缩小到
1053
+ // 164px 以下(--hj-copy-min-width 的历史默认),这里强制归零。
1054
+ root.style.setProperty('--hj-text-min-width', '0');
1045
1055
  }
1046
1056
  renderer.resize();
1047
1057
  };
@@ -1140,10 +1150,7 @@ function createCapsule(container, options = {}) {
1140
1150
  dirty.textRatio = true;
1141
1151
  merged.textRatio = value;
1142
1152
  root.style.setProperty('--hj-text-width', `${value}%`);
1143
- const userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1144
- if (value === 0) root.style.setProperty('--hj-text-min-width', '0');
1145
- else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);
1146
- else root.style.removeProperty('--hj-text-min-width');
1153
+ root.style.setProperty('--hj-text-min-width', '0');
1147
1154
  return this;
1148
1155
  },
1149
1156
  setCssVars(vars) {
@@ -1159,11 +1166,17 @@ function createCapsule(container, options = {}) {
1159
1166
  return this;
1160
1167
  },
1161
1168
  setSize(width, height) {
1162
- if (width !== undefined) merged.width = width;
1163
- if (height !== undefined) merged.height = height;
1164
- applySize();
1165
- return this;
1166
- },
1169
+ if (width !== undefined) {
1170
+ parseSize(width); // 非法尺寸直接抛错前先校验,避免污染内部状态
1171
+ merged.width = width;
1172
+ }
1173
+ if (height !== undefined) {
1174
+ parseSize(height);
1175
+ merged.height = height;
1176
+ }
1177
+ applySize();
1178
+ return this;
1179
+ },
1167
1180
  randomize() {
1168
1181
  this.setSeed(Math.random() * 100);
1169
1182
  return this;
@@ -1190,8 +1203,8 @@ function createCapsule(container, options = {}) {
1190
1203
  renderer.dispose();
1191
1204
  root.remove();
1192
1205
  },
1193
- textRatio: merged.textRatio,
1194
- cssVars: merged.cssVars,
1206
+ get textRatio() { return merged.textRatio; },
1207
+ get cssVars() { return merged.cssVars; },
1195
1208
  dirty
1196
1209
  };
1197
1210
  }
@@ -1676,13 +1689,17 @@ const PALETTES = {
1676
1689
  'tide': ['#0a2239', '#2e9bff', '#7fe3ff', '#eaf9ff']
1677
1690
  };
1678
1691
 
1679
- function drawCloud(context, x, y, radiusX, radiusY, color, alpha) {
1680
- context.save();
1681
- context.translate(x, y);
1682
- context.scale(1, radiusY / radiusX);
1683
- const gradient = context.createRadialGradient(0, 0, 0, 0, 0, radiusX);
1684
- gradient.addColorStop(0, `${color}${Math.round(alpha * 255).toString(16).padStart(2, '0')}`);
1685
- gradient.addColorStop(0.46, `${color}${Math.round(alpha * 0.42 * 255).toString(16).padStart(2, '0')}`);
1692
+ function drawCloud(context, x, y, radiusX, radiusY, color, alpha) {
1693
+ context.save();
1694
+ context.translate(x, y);
1695
+ context.scale(1, radiusY / radiusX);
1696
+ const gradient = context.createRadialGradient(0, 0, 0, 0, 0, radiusX);
1697
+ const alphaHex = (value) => {
1698
+ const text = Math.round(value).toString(16);
1699
+ return text.length === 1 ? `0${text}` : text;
1700
+ };
1701
+ gradient.addColorStop(0, `${color}${alphaHex(alpha * 255)}`);
1702
+ gradient.addColorStop(0.46, `${color}${alphaHex(alpha * 0.42 * 255)}`);
1686
1703
  gradient.addColorStop(1, `${color}00`);
1687
1704
  context.fillStyle = gradient;
1688
1705
  context.fillRect(-radiusX, -radiusX, radiusX * 2, radiusX * 2);
@@ -2112,9 +2129,14 @@ class ProgressCapsuleController {
2112
2129
  ctx.restore();
2113
2130
  }
2114
2131
 
2115
- setRange(min, max) {
2116
- this.min = min;
2117
- this.max = max;
2132
+ setRange(min, max) {
2133
+ if (min > max) {
2134
+ const swap = min;
2135
+ min = max;
2136
+ max = swap;
2137
+ }
2138
+ this.min = min;
2139
+ this.max = max;
2118
2140
  const clamped = clamp(this.value, this.min, this.max);
2119
2141
  if (clamped !== this.value) this.setProgress(clamped, 'prop');
2120
2142
  }
@@ -2309,33 +2331,7 @@ class ProgressCapsuleController {
2309
2331
  this.root.addEventListener('pointercancel', this.handlers.pointercancel);
2310
2332
  }
2311
2333
 
2312
- if (this.options.keyboard !== false) {
2313
- this.handlers.keydown = (event) => {
2314
- const step = (this.max - this.min) * 0.02;
2315
- const actions = {
2316
- ArrowLeft: -step,
2317
- ArrowDown: -step,
2318
- ArrowRight: step,
2319
- ArrowUp: step,
2320
- PageDown: -step * 5,
2321
- PageUp: step * 5
2322
- };
2323
- if (event.key === 'Home') {
2324
- event.preventDefault();
2325
- this.setProgress(this.min, 'keyboard');
2326
- } else if (event.key === 'End') {
2327
- event.preventDefault();
2328
- this.setProgress(this.max, 'keyboard');
2329
- } else if (actions[event.key]) {
2330
- event.preventDefault();
2331
- this.setProgress(this.value + actions[event.key], 'keyboard');
2332
- } else {
2333
- return;
2334
- }
2335
- };
2336
- this.root.addEventListener('keydown', this.handlers.keydown);
2337
- }
2338
- }
2334
+ }
2339
2335
 
2340
2336
  update(delta, paused) {
2341
2337
  if (!paused) this.flowTime += delta;
@@ -2373,7 +2369,7 @@ class ProgressCapsuleController {
2373
2369
  * Mount a fluid progress capsule into `container`.
2374
2370
  *
2375
2371
  * Options: preset (id/code/name or object), width, height, value, min, max,
2376
- * draggable, keyboard, colors, edgeStyle, textRatio (0-100, text region
2372
+ * draggable, colors, edgeStyle, textRatio (0-100, text region
2377
2373
  * width in percent), text (HTML string or DOM nodes for the text slot),
2378
2374
  * colorContent (HTML string or DOM nodes for the color slot),
2379
2375
  * showValue (show/hide the right-side percentage), quality,
@@ -2386,6 +2382,11 @@ function createProgressCapsule(container, options = {}) {
2386
2382
 
2387
2383
  const preset = { ...getPreset('progress', options.preset ?? '星火') };
2388
2384
  const merged = normalizeOptions(DEFAULTS.progress, preset, options);
2385
+ if (merged.min > merged.max) {
2386
+ const swap = merged.min;
2387
+ merged.min = merged.max;
2388
+ merged.max = swap;
2389
+ }
2389
2390
  const normalizedColors = merged.colors.map(normalizeColor);
2390
2391
  if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
2391
2392
  preset.edgeStyle = merged.edgeStyle;
@@ -2397,7 +2398,6 @@ function createProgressCapsule(container, options = {}) {
2397
2398
  const readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
2398
2399
  const locked = disabled || readonly;
2399
2400
  const effectiveDraggable = locked ? false : merged.draggable !== false;
2400
- const effectiveKeyboard = locked ? false : merged.keyboard !== false;
2401
2401
  const dirty = {
2402
2402
  preset: false,
2403
2403
  colors: false,
@@ -2410,7 +2410,6 @@ function createProgressCapsule(container, options = {}) {
2410
2410
  const root = document.createElement('div');
2411
2411
  root.className = 'hj-capsule-root hj-progress-root';
2412
2412
  root.setAttribute('role', 'slider');
2413
- root.setAttribute('tabindex', '0');
2414
2413
  root.setAttribute('data-draggable', String(effectiveDraggable));
2415
2414
  if (disabled) {
2416
2415
  root.setAttribute('aria-disabled', 'true');
@@ -2420,6 +2419,7 @@ function createProgressCapsule(container, options = {}) {
2420
2419
  root.setAttribute('aria-readonly', 'true');
2421
2420
  root.classList.add('is-readonly');
2422
2421
  }
2422
+ if (locked) root.setAttribute('tabindex', '-1');
2423
2423
  root.setAttribute('aria-valuemin', String(merged.min ?? 0));
2424
2424
  root.setAttribute('aria-valuemax', String(merged.max ?? 100));
2425
2425
  root.setAttribute('aria-valuenow', String(preset.initialProgress));
@@ -2430,8 +2430,6 @@ function createProgressCapsule(container, options = {}) {
2430
2430
  );
2431
2431
  };
2432
2432
  updateAria();
2433
- if (!effectiveKeyboard) root.setAttribute('tabindex', '-1');
2434
-
2435
2433
  const canvas = document.createElement('canvas');
2436
2434
  canvas.className = 'hj-progress-canvas';
2437
2435
  canvas.setAttribute('aria-hidden', 'true');
@@ -2493,7 +2491,7 @@ function createProgressCapsule(container, options = {}) {
2493
2491
  valueElement,
2494
2492
  preset,
2495
2493
  emitter,
2496
- options: { ...merged, draggable: effectiveDraggable, keyboard: effectiveKeyboard },
2494
+ options: { ...merged, draggable: effectiveDraggable },
2497
2495
  copy,
2498
2496
  dirty
2499
2497
  });
@@ -2634,10 +2632,16 @@ function createProgressCapsule(container, options = {}) {
2634
2632
  controller.resizeCanvas();
2635
2633
  return this;
2636
2634
  },
2637
- setSize(width, height) {
2638
- if (width !== undefined) merged.width = width;
2639
- if (height !== undefined) merged.height = height;
2640
- applySize();
2635
+ setSize(width, height) {
2636
+ if (width !== undefined) {
2637
+ parseSize(width);
2638
+ merged.width = width;
2639
+ }
2640
+ if (height !== undefined) {
2641
+ parseSize(height);
2642
+ merged.height = height;
2643
+ }
2644
+ applySize();
2641
2645
  controller.resizeCanvas();
2642
2646
  return this;
2643
2647
  },
@@ -2667,8 +2671,8 @@ function createProgressCapsule(container, options = {}) {
2667
2671
  controller.dispose();
2668
2672
  root.remove();
2669
2673
  },
2670
- textRatio: merged.textRatio,
2671
- cssVars: merged.cssVars,
2674
+ get textRatio() { return merged.textRatio; },
2675
+ get cssVars() { return merged.cssVars; },
2672
2676
  dirty
2673
2677
  };
2674
2678
  }
@@ -2888,9 +2892,9 @@ function createColorBackground(host, options = {}) {
2888
2892
  renderer.dispose();
2889
2893
  layer.remove();
2890
2894
  },
2891
- opacity: merged.opacity,
2892
- fallbackColor: merged.fallbackColor,
2893
- mouseColor: merged.mouseColor,
2895
+ get opacity() { return merged.opacity; },
2896
+ get fallbackColor() { return merged.fallbackColor; },
2897
+ get mouseColor() { return merged.mouseColor; },
2894
2898
  dirty
2895
2899
  };
2896
2900
  }
@@ -2926,6 +2930,9 @@ function makeWrapper({ name, props, events, create, render, methods, watch }) {
2926
2930
  const extraState = this.runtimeState();
2927
2931
  if (this.controller) this.controller.dispose();
2928
2932
  this.mountController(extraState);
2933
+ // 结构属性连续变化时,插槽内容可能在重建后才被 Vue 写入容器,
2934
+ // 补一次搬运确保不丢。
2935
+ this.$nextTick(() => this.moveSlots());
2929
2936
  },
2930
2937
  scheduleRecreate() {
2931
2938
  if (this._recreateQueued) return;
@@ -3075,7 +3082,7 @@ function makeProgressWrapper(createProgressCapsule, render) {
3075
3082
  name: 'ProgressCapsule',
3076
3083
  props: [
3077
3084
  'preset', 'width', 'height', 'value', 'min', 'max',
3078
- 'draggable', 'keyboard', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix',
3085
+ 'draggable', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix',
3079
3086
  'quality', 'renderer', 'respectReducedMotion', 'cssVars'
3080
3087
  ],
3081
3088
  events: PROGRESS_EVENTS,
@@ -3118,9 +3125,6 @@ function makeProgressWrapper(createProgressCapsule, render) {
3118
3125
  draggable() {
3119
3126
  this.scheduleRecreate();
3120
3127
  },
3121
- keyboard() {
3122
- this.scheduleRecreate();
3123
- },
3124
3128
  renderer() {
3125
3129
  this.scheduleRecreate();
3126
3130
  }