@5even7/dlc-ui 0.2.1 → 0.2.3

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.cjs CHANGED
@@ -148,9 +148,6 @@ function _objectSpread2(e) {
148
148
  }
149
149
  return e;
150
150
  }
151
- function _readOnlyError(r) {
152
- throw new TypeError('"' + r + '" is read-only');
153
- }
154
151
  function _slicedToArray(r, e) {
155
152
  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
156
153
  }
@@ -444,6 +441,7 @@ var DEFAULTS = {
444
441
  draggable: true,
445
442
  keyboard: true,
446
443
  disabled: false,
444
+ readonly: false,
447
445
  valueSuffix: '%',
448
446
  edgeStyle: 'flow',
449
447
  quality: 'auto',
@@ -1210,6 +1208,8 @@ function createCapsule(container) {
1210
1208
  }
1211
1209
  if (merged.textRatio !== undefined) {
1212
1210
  root.style.setProperty('--hj-text-width', "".concat(merged.textRatio, "%"));
1211
+ var userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1212
+ if (merged.textRatio === 0) root.style.setProperty('--hj-text-min-width', '0');else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);else root.style.removeProperty('--hj-text-min-width');
1213
1213
  }
1214
1214
  renderer.resize();
1215
1215
  };
@@ -1333,6 +1333,8 @@ function createCapsule(container) {
1333
1333
  dirty.textRatio = true;
1334
1334
  merged.textRatio = value;
1335
1335
  root.style.setProperty('--hj-text-width', "".concat(value, "%"));
1336
+ var userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1337
+ if (value === 0) root.style.setProperty('--hj-text-min-width', '0');else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);else root.style.removeProperty('--hj-text-min-width');
1336
1338
  return this;
1337
1339
  },
1338
1340
  setCssVars: function setCssVars(vars) {
@@ -2264,6 +2266,14 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2264
2266
  value: function beginDrag(event) {
2265
2267
  if (event.button !== undefined && event.button !== 0) return;
2266
2268
  event.preventDefault();
2269
+ // preventDefault 会吞掉点击聚焦,主动聚焦让键盘方向键立即可用。
2270
+ try {
2271
+ this.root.focus({
2272
+ preventScroll: true
2273
+ });
2274
+ } catch (_unused) {
2275
+ this.root.focus();
2276
+ }
2267
2277
  this.dragging = true;
2268
2278
  this.pendingPointer = null;
2269
2279
  this._dragRaf = 0;
@@ -2271,7 +2281,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2271
2281
  try {
2272
2282
  var _this$root$setPointer, _this$root;
2273
2283
  (_this$root$setPointer = (_this$root = this.root).setPointerCapture) === null || _this$root$setPointer === void 0 || _this$root$setPointer.call(_this$root, event.pointerId);
2274
- } catch (_unused) {}
2284
+ } catch (_unused2) {}
2275
2285
  this.emitter.emit('dragstart', {
2276
2286
  value: this.value
2277
2287
  });
@@ -2311,7 +2321,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2311
2321
  if ((event === null || event === void 0 ? void 0 : event.pointerId) !== undefined && (_this$root$hasPointer = (_this$root2 = this.root).hasPointerCapture) !== null && _this$root$hasPointer !== void 0 && _this$root$hasPointer.call(_this$root2, event.pointerId)) {
2312
2322
  this.root.releasePointerCapture(event.pointerId);
2313
2323
  }
2314
- } catch (_unused2) {}
2324
+ } catch (_unused3) {}
2315
2325
  this.emitter.emit('dragend', {
2316
2326
  value: this.value
2317
2327
  });
@@ -2432,8 +2442,10 @@ function createProgressCapsule(container) {
2432
2442
  // Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
2433
2443
  // 这里统一按 true 处理。
2434
2444
  var disabled = merged.disabled === true || merged.disabled === '' || merged.disabled === 'true';
2435
- var effectiveDraggable = disabled ? false : merged.draggable !== false;
2436
- var effectiveKeyboard = disabled ? false : merged.keyboard !== false;
2445
+ var readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
2446
+ var locked = disabled || readonly;
2447
+ var effectiveDraggable = locked ? false : merged.draggable !== false;
2448
+ var effectiveKeyboard = locked ? false : merged.keyboard !== false;
2437
2449
  var dirty = {
2438
2450
  preset: false,
2439
2451
  colors: false,
@@ -2451,6 +2463,10 @@ function createProgressCapsule(container) {
2451
2463
  root.setAttribute('aria-disabled', 'true');
2452
2464
  root.classList.add('is-disabled');
2453
2465
  }
2466
+ if (readonly) {
2467
+ root.setAttribute('aria-readonly', 'true');
2468
+ root.classList.add('is-readonly');
2469
+ }
2454
2470
  root.setAttribute('aria-valuemin', String((_merged$min = merged.min) !== null && _merged$min !== void 0 ? _merged$min : 0));
2455
2471
  root.setAttribute('aria-valuemax', String((_merged$max = merged.max) !== null && _merged$max !== void 0 ? _merged$max : 100));
2456
2472
  root.setAttribute('aria-valuenow', String(preset.initialProgress));
@@ -2670,7 +2686,7 @@ function createProgressCapsule(container) {
2670
2686
  return this;
2671
2687
  },
2672
2688
  setLabel: function setLabel(label) {
2673
- _readOnlyError("customLabel");
2689
+ customLabel = typeof label === 'string' && label ? label : null;
2674
2690
  updateAria();
2675
2691
  return this;
2676
2692
  },
@@ -3001,22 +3017,21 @@ function makeWrapper(_ref) {
3001
3017
  var root = this.controller.element;
3002
3018
  var textLayer = root.querySelector('.hj-capsule-text, .hj-progress-text');
3003
3019
  var visualLayer = root.querySelector('.hj-capsule-visual, .hj-progress-visual');
3004
- var move = function move(wrapper, layer) {
3005
- if (!wrapper || !layer) return;
3006
- for (var _i = 0, _Array$from = Array.from(wrapper.childNodes); _i < _Array$from.length; _i++) {
3007
- var node = _Array$from[_i];
3008
- layer.appendChild(node);
3009
- }
3010
- };
3011
3020
  var refs = this.$refs || {};
3012
- move(refs.slotText, textLayer);
3013
- move(refs.slotColor, visualLayer);
3021
+ // 把插槽容器整体搬进对应区域,而不是搬子节点:Vue 重渲染/重建组件时
3022
+ // 内容始终留在区域内,不会丢(子节点搬运会在 recreate 时序下丢失)。
3023
+ if (refs.slotText && textLayer && refs.slotText.parentElement !== textLayer) {
3024
+ textLayer.appendChild(refs.slotText);
3025
+ }
3026
+ if (refs.slotColor && visualLayer && refs.slotColor.parentElement !== visualLayer) {
3027
+ visualLayer.appendChild(refs.slotColor);
3028
+ }
3014
3029
  },
3015
3030
  applyAttrs: function applyAttrs() {
3016
3031
  if (!this.controller || !this.controller.element || !this.$attrs) return;
3017
3032
  var root = this.controller.element;
3018
- for (var _i2 = 0, _Object$keys = Object.keys(this.$attrs); _i2 < _Object$keys.length; _i2++) {
3019
- var key = _Object$keys[_i2];
3033
+ for (var _i = 0, _Object$keys = Object.keys(this.$attrs); _i < _Object$keys.length; _i++) {
3034
+ var key = _Object$keys[_i];
3020
3035
  if (key === 'class' || key === 'style') continue;
3021
3036
  var value = this.$attrs[key];
3022
3037
  if (value == null || value === false) root.removeAttribute(key);else root.setAttribute(key, String(value));
@@ -3164,7 +3179,7 @@ function makeCapsuleWrapper(createCapsule, render) {
3164
3179
  function makeProgressWrapper(createProgressCapsule, render) {
3165
3180
  return makeWrapper({
3166
3181
  name: 'ProgressCapsule',
3167
- props: ['preset', 'width', 'height', 'value', 'min', 'max', 'draggable', 'keyboard', 'disabled', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix', 'quality', 'renderer', 'respectReducedMotion', 'cssVars'],
3182
+ props: ['preset', 'width', 'height', 'value', 'min', 'max', 'draggable', 'keyboard', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix', 'quality', 'renderer', 'respectReducedMotion', 'cssVars'],
3168
3183
  events: PROGRESS_EVENTS,
3169
3184
  create: createProgressCapsule,
3170
3185
  render: render,
@@ -3199,6 +3214,9 @@ function makeProgressWrapper(createProgressCapsule, render) {
3199
3214
  disabled: function disabled() {
3200
3215
  this.scheduleRecreate();
3201
3216
  },
3217
+ readonly: function readonly() {
3218
+ this.scheduleRecreate();
3219
+ },
3202
3220
  draggable: function draggable() {
3203
3221
  this.scheduleRecreate();
3204
3222
  },
package/dist/vue2.mjs CHANGED
@@ -200,6 +200,7 @@ const DEFAULTS = {
200
200
  draggable: true,
201
201
  keyboard: true,
202
202
  disabled: false,
203
+ readonly: false,
203
204
  valueSuffix: '%',
204
205
  edgeStyle: 'flow',
205
206
  quality: 'auto',
@@ -1037,6 +1038,10 @@ function createCapsule(container, options = {}) {
1037
1038
  for (const name of Object.keys(vars)) root.style.setProperty(name, vars[name]);
1038
1039
  if (merged.textRatio !== undefined) {
1039
1040
  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');
1040
1045
  }
1041
1046
  renderer.resize();
1042
1047
  };
@@ -1135,6 +1140,10 @@ function createCapsule(container, options = {}) {
1135
1140
  dirty.textRatio = true;
1136
1141
  merged.textRatio = value;
1137
1142
  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');
1138
1147
  return this;
1139
1148
  },
1140
1149
  setCssVars(vars) {
@@ -2244,6 +2253,8 @@ class ProgressCapsuleController {
2244
2253
  beginDrag(event) {
2245
2254
  if (event.button !== undefined && event.button !== 0) return;
2246
2255
  event.preventDefault();
2256
+ // preventDefault 会吞掉点击聚焦,主动聚焦让键盘方向键立即可用。
2257
+ try { this.root.focus({ preventScroll: true }); } catch { this.root.focus(); }
2247
2258
  this.dragging = true;
2248
2259
  this.pendingPointer = null;
2249
2260
  this._dragRaf = 0;
@@ -2379,12 +2390,14 @@ function createProgressCapsule(container, options = {}) {
2379
2390
  if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
2380
2391
  preset.edgeStyle = merged.edgeStyle;
2381
2392
  const copy = COPY;
2382
- const customLabel = typeof options.label === 'string' && options.label ? options.label : null;
2393
+ let customLabel = typeof options.label === 'string' && options.label ? options.label : null;
2383
2394
  // Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
2384
2395
  // 这里统一按 true 处理。
2385
2396
  const disabled = merged.disabled === true || merged.disabled === '' || merged.disabled === 'true';
2386
- const effectiveDraggable = disabled ? false : merged.draggable !== false;
2387
- const effectiveKeyboard = disabled ? false : merged.keyboard !== false;
2397
+ const readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
2398
+ const locked = disabled || readonly;
2399
+ const effectiveDraggable = locked ? false : merged.draggable !== false;
2400
+ const effectiveKeyboard = locked ? false : merged.keyboard !== false;
2388
2401
  const dirty = {
2389
2402
  preset: false,
2390
2403
  colors: false,
@@ -2403,6 +2416,10 @@ function createProgressCapsule(container, options = {}) {
2403
2416
  root.setAttribute('aria-disabled', 'true');
2404
2417
  root.classList.add('is-disabled');
2405
2418
  }
2419
+ if (readonly) {
2420
+ root.setAttribute('aria-readonly', 'true');
2421
+ root.classList.add('is-readonly');
2422
+ }
2406
2423
  root.setAttribute('aria-valuemin', String(merged.min ?? 0));
2407
2424
  root.setAttribute('aria-valuemax', String(merged.max ?? 100));
2408
2425
  root.setAttribute('aria-valuenow', String(preset.initialProgress));
@@ -2923,13 +2940,15 @@ function makeWrapper({ name, props, events, create, render, methods, watch }) {
2923
2940
  const root = this.controller.element;
2924
2941
  const textLayer = root.querySelector('.hj-capsule-text, .hj-progress-text');
2925
2942
  const visualLayer = root.querySelector('.hj-capsule-visual, .hj-progress-visual');
2926
- const move = (wrapper, layer) => {
2927
- if (!wrapper || !layer) return;
2928
- for (const node of Array.from(wrapper.childNodes)) layer.appendChild(node);
2929
- };
2930
2943
  const refs = this.$refs || {};
2931
- move(refs.slotText, textLayer);
2932
- move(refs.slotColor, visualLayer);
2944
+ // 把插槽容器整体搬进对应区域,而不是搬子节点:Vue 重渲染/重建组件时
2945
+ // 内容始终留在区域内,不会丢(子节点搬运会在 recreate 时序下丢失)。
2946
+ if (refs.slotText && textLayer && refs.slotText.parentElement !== textLayer) {
2947
+ textLayer.appendChild(refs.slotText);
2948
+ }
2949
+ if (refs.slotColor && visualLayer && refs.slotColor.parentElement !== visualLayer) {
2950
+ visualLayer.appendChild(refs.slotColor);
2951
+ }
2933
2952
  },
2934
2953
  applyAttrs() {
2935
2954
  if (!this.controller || !this.controller.element || !this.$attrs) return;
@@ -3056,7 +3075,7 @@ function makeProgressWrapper(createProgressCapsule, render) {
3056
3075
  name: 'ProgressCapsule',
3057
3076
  props: [
3058
3077
  'preset', 'width', 'height', 'value', 'min', 'max',
3059
- 'draggable', 'keyboard', 'disabled', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix',
3078
+ 'draggable', 'keyboard', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix',
3060
3079
  'quality', 'renderer', 'respectReducedMotion', 'cssVars'
3061
3080
  ],
3062
3081
  events: PROGRESS_EVENTS,
@@ -3093,6 +3112,9 @@ function makeProgressWrapper(createProgressCapsule, render) {
3093
3112
  disabled() {
3094
3113
  this.scheduleRecreate();
3095
3114
  },
3115
+ readonly() {
3116
+ this.scheduleRecreate();
3117
+ },
3096
3118
  draggable() {
3097
3119
  this.scheduleRecreate();
3098
3120
  },
package/dist/vue3.cjs CHANGED
@@ -150,9 +150,6 @@ function _objectSpread2(e) {
150
150
  }
151
151
  return e;
152
152
  }
153
- function _readOnlyError(r) {
154
- throw new TypeError('"' + r + '" is read-only');
155
- }
156
153
  function _slicedToArray(r, e) {
157
154
  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
158
155
  }
@@ -446,6 +443,7 @@ var DEFAULTS = {
446
443
  draggable: true,
447
444
  keyboard: true,
448
445
  disabled: false,
446
+ readonly: false,
449
447
  valueSuffix: '%',
450
448
  edgeStyle: 'flow',
451
449
  quality: 'auto',
@@ -1212,6 +1210,8 @@ function createCapsule(container) {
1212
1210
  }
1213
1211
  if (merged.textRatio !== undefined) {
1214
1212
  root.style.setProperty('--hj-text-width', "".concat(merged.textRatio, "%"));
1213
+ var userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1214
+ if (merged.textRatio === 0) root.style.setProperty('--hj-text-min-width', '0');else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);else root.style.removeProperty('--hj-text-min-width');
1215
1215
  }
1216
1216
  renderer.resize();
1217
1217
  };
@@ -1335,6 +1335,8 @@ function createCapsule(container) {
1335
1335
  dirty.textRatio = true;
1336
1336
  merged.textRatio = value;
1337
1337
  root.style.setProperty('--hj-text-width', "".concat(value, "%"));
1338
+ var userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1339
+ if (value === 0) root.style.setProperty('--hj-text-min-width', '0');else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);else root.style.removeProperty('--hj-text-min-width');
1338
1340
  return this;
1339
1341
  },
1340
1342
  setCssVars: function setCssVars(vars) {
@@ -2266,6 +2268,14 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2266
2268
  value: function beginDrag(event) {
2267
2269
  if (event.button !== undefined && event.button !== 0) return;
2268
2270
  event.preventDefault();
2271
+ // preventDefault 会吞掉点击聚焦,主动聚焦让键盘方向键立即可用。
2272
+ try {
2273
+ this.root.focus({
2274
+ preventScroll: true
2275
+ });
2276
+ } catch (_unused) {
2277
+ this.root.focus();
2278
+ }
2269
2279
  this.dragging = true;
2270
2280
  this.pendingPointer = null;
2271
2281
  this._dragRaf = 0;
@@ -2273,7 +2283,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2273
2283
  try {
2274
2284
  var _this$root$setPointer, _this$root;
2275
2285
  (_this$root$setPointer = (_this$root = this.root).setPointerCapture) === null || _this$root$setPointer === void 0 || _this$root$setPointer.call(_this$root, event.pointerId);
2276
- } catch (_unused) {}
2286
+ } catch (_unused2) {}
2277
2287
  this.emitter.emit('dragstart', {
2278
2288
  value: this.value
2279
2289
  });
@@ -2313,7 +2323,7 @@ var ProgressCapsuleController = /*#__PURE__*/function () {
2313
2323
  if ((event === null || event === void 0 ? void 0 : event.pointerId) !== undefined && (_this$root$hasPointer = (_this$root2 = this.root).hasPointerCapture) !== null && _this$root$hasPointer !== void 0 && _this$root$hasPointer.call(_this$root2, event.pointerId)) {
2314
2324
  this.root.releasePointerCapture(event.pointerId);
2315
2325
  }
2316
- } catch (_unused2) {}
2326
+ } catch (_unused3) {}
2317
2327
  this.emitter.emit('dragend', {
2318
2328
  value: this.value
2319
2329
  });
@@ -2434,8 +2444,10 @@ function createProgressCapsule(container) {
2434
2444
  // Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
2435
2445
  // 这里统一按 true 处理。
2436
2446
  var disabled = merged.disabled === true || merged.disabled === '' || merged.disabled === 'true';
2437
- var effectiveDraggable = disabled ? false : merged.draggable !== false;
2438
- var effectiveKeyboard = disabled ? false : merged.keyboard !== false;
2447
+ var readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
2448
+ var locked = disabled || readonly;
2449
+ var effectiveDraggable = locked ? false : merged.draggable !== false;
2450
+ var effectiveKeyboard = locked ? false : merged.keyboard !== false;
2439
2451
  var dirty = {
2440
2452
  preset: false,
2441
2453
  colors: false,
@@ -2453,6 +2465,10 @@ function createProgressCapsule(container) {
2453
2465
  root.setAttribute('aria-disabled', 'true');
2454
2466
  root.classList.add('is-disabled');
2455
2467
  }
2468
+ if (readonly) {
2469
+ root.setAttribute('aria-readonly', 'true');
2470
+ root.classList.add('is-readonly');
2471
+ }
2456
2472
  root.setAttribute('aria-valuemin', String((_merged$min = merged.min) !== null && _merged$min !== void 0 ? _merged$min : 0));
2457
2473
  root.setAttribute('aria-valuemax', String((_merged$max = merged.max) !== null && _merged$max !== void 0 ? _merged$max : 100));
2458
2474
  root.setAttribute('aria-valuenow', String(preset.initialProgress));
@@ -2672,7 +2688,7 @@ function createProgressCapsule(container) {
2672
2688
  return this;
2673
2689
  },
2674
2690
  setLabel: function setLabel(label) {
2675
- _readOnlyError("customLabel");
2691
+ customLabel = typeof label === 'string' && label ? label : null;
2676
2692
  updateAria();
2677
2693
  return this;
2678
2694
  },
@@ -3003,22 +3019,21 @@ function makeWrapper(_ref) {
3003
3019
  var root = this.controller.element;
3004
3020
  var textLayer = root.querySelector('.hj-capsule-text, .hj-progress-text');
3005
3021
  var visualLayer = root.querySelector('.hj-capsule-visual, .hj-progress-visual');
3006
- var move = function move(wrapper, layer) {
3007
- if (!wrapper || !layer) return;
3008
- for (var _i = 0, _Array$from = Array.from(wrapper.childNodes); _i < _Array$from.length; _i++) {
3009
- var node = _Array$from[_i];
3010
- layer.appendChild(node);
3011
- }
3012
- };
3013
3022
  var refs = this.$refs || {};
3014
- move(refs.slotText, textLayer);
3015
- move(refs.slotColor, visualLayer);
3023
+ // 把插槽容器整体搬进对应区域,而不是搬子节点:Vue 重渲染/重建组件时
3024
+ // 内容始终留在区域内,不会丢(子节点搬运会在 recreate 时序下丢失)。
3025
+ if (refs.slotText && textLayer && refs.slotText.parentElement !== textLayer) {
3026
+ textLayer.appendChild(refs.slotText);
3027
+ }
3028
+ if (refs.slotColor && visualLayer && refs.slotColor.parentElement !== visualLayer) {
3029
+ visualLayer.appendChild(refs.slotColor);
3030
+ }
3016
3031
  },
3017
3032
  applyAttrs: function applyAttrs() {
3018
3033
  if (!this.controller || !this.controller.element || !this.$attrs) return;
3019
3034
  var root = this.controller.element;
3020
- for (var _i2 = 0, _Object$keys = Object.keys(this.$attrs); _i2 < _Object$keys.length; _i2++) {
3021
- var key = _Object$keys[_i2];
3035
+ for (var _i = 0, _Object$keys = Object.keys(this.$attrs); _i < _Object$keys.length; _i++) {
3036
+ var key = _Object$keys[_i];
3022
3037
  if (key === 'class' || key === 'style') continue;
3023
3038
  var value = this.$attrs[key];
3024
3039
  if (value == null || value === false) root.removeAttribute(key);else root.setAttribute(key, String(value));
@@ -3166,7 +3181,7 @@ function makeCapsuleWrapper(createCapsule, render) {
3166
3181
  function makeProgressWrapper(createProgressCapsule, render) {
3167
3182
  return makeWrapper({
3168
3183
  name: 'ProgressCapsule',
3169
- props: ['preset', 'width', 'height', 'value', 'min', 'max', 'draggable', 'keyboard', 'disabled', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix', 'quality', 'renderer', 'respectReducedMotion', 'cssVars'],
3184
+ props: ['preset', 'width', 'height', 'value', 'min', 'max', 'draggable', 'keyboard', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix', 'quality', 'renderer', 'respectReducedMotion', 'cssVars'],
3170
3185
  events: PROGRESS_EVENTS,
3171
3186
  create: createProgressCapsule,
3172
3187
  render: render,
@@ -3201,6 +3216,9 @@ function makeProgressWrapper(createProgressCapsule, render) {
3201
3216
  disabled: function disabled() {
3202
3217
  this.scheduleRecreate();
3203
3218
  },
3219
+ readonly: function readonly() {
3220
+ this.scheduleRecreate();
3221
+ },
3204
3222
  draggable: function draggable() {
3205
3223
  this.scheduleRecreate();
3206
3224
  },
package/dist/vue3.mjs CHANGED
@@ -202,6 +202,7 @@ const DEFAULTS = {
202
202
  draggable: true,
203
203
  keyboard: true,
204
204
  disabled: false,
205
+ readonly: false,
205
206
  valueSuffix: '%',
206
207
  edgeStyle: 'flow',
207
208
  quality: 'auto',
@@ -1039,6 +1040,10 @@ function createCapsule(container, options = {}) {
1039
1040
  for (const name of Object.keys(vars)) root.style.setProperty(name, vars[name]);
1040
1041
  if (merged.textRatio !== undefined) {
1041
1042
  root.style.setProperty('--hj-text-width', `${merged.textRatio}%`);
1043
+ const userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1044
+ if (merged.textRatio === 0) root.style.setProperty('--hj-text-min-width', '0');
1045
+ else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);
1046
+ else root.style.removeProperty('--hj-text-min-width');
1042
1047
  }
1043
1048
  renderer.resize();
1044
1049
  };
@@ -1137,6 +1142,10 @@ function createCapsule(container, options = {}) {
1137
1142
  dirty.textRatio = true;
1138
1143
  merged.textRatio = value;
1139
1144
  root.style.setProperty('--hj-text-width', `${value}%`);
1145
+ const userMinWidth = merged.cssVars && merged.cssVars['--hj-text-min-width'];
1146
+ if (value === 0) root.style.setProperty('--hj-text-min-width', '0');
1147
+ else if (userMinWidth) root.style.setProperty('--hj-text-min-width', userMinWidth);
1148
+ else root.style.removeProperty('--hj-text-min-width');
1140
1149
  return this;
1141
1150
  },
1142
1151
  setCssVars(vars) {
@@ -2246,6 +2255,8 @@ class ProgressCapsuleController {
2246
2255
  beginDrag(event) {
2247
2256
  if (event.button !== undefined && event.button !== 0) return;
2248
2257
  event.preventDefault();
2258
+ // preventDefault 会吞掉点击聚焦,主动聚焦让键盘方向键立即可用。
2259
+ try { this.root.focus({ preventScroll: true }); } catch { this.root.focus(); }
2249
2260
  this.dragging = true;
2250
2261
  this.pendingPointer = null;
2251
2262
  this._dragRaf = 0;
@@ -2381,12 +2392,14 @@ function createProgressCapsule(container, options = {}) {
2381
2392
  if (normalizedColors.every(Boolean)) preset.colors = normalizedColors;
2382
2393
  preset.edgeStyle = merged.edgeStyle;
2383
2394
  const copy = COPY;
2384
- const customLabel = typeof options.label === 'string' && options.label ? options.label : null;
2395
+ let customLabel = typeof options.label === 'string' && options.label ? options.label : null;
2385
2396
  // Vue 的裸布尔属性(<ProgressCapsule disabled />)会传成空字符串,
2386
2397
  // 这里统一按 true 处理。
2387
2398
  const disabled = merged.disabled === true || merged.disabled === '' || merged.disabled === 'true';
2388
- const effectiveDraggable = disabled ? false : merged.draggable !== false;
2389
- const effectiveKeyboard = disabled ? false : merged.keyboard !== false;
2399
+ const readonly = merged.readonly === true || merged.readonly === '' || merged.readonly === 'true';
2400
+ const locked = disabled || readonly;
2401
+ const effectiveDraggable = locked ? false : merged.draggable !== false;
2402
+ const effectiveKeyboard = locked ? false : merged.keyboard !== false;
2390
2403
  const dirty = {
2391
2404
  preset: false,
2392
2405
  colors: false,
@@ -2405,6 +2418,10 @@ function createProgressCapsule(container, options = {}) {
2405
2418
  root.setAttribute('aria-disabled', 'true');
2406
2419
  root.classList.add('is-disabled');
2407
2420
  }
2421
+ if (readonly) {
2422
+ root.setAttribute('aria-readonly', 'true');
2423
+ root.classList.add('is-readonly');
2424
+ }
2408
2425
  root.setAttribute('aria-valuemin', String(merged.min ?? 0));
2409
2426
  root.setAttribute('aria-valuemax', String(merged.max ?? 100));
2410
2427
  root.setAttribute('aria-valuenow', String(preset.initialProgress));
@@ -2925,13 +2942,15 @@ function makeWrapper({ name, props, events, create, render, methods, watch }) {
2925
2942
  const root = this.controller.element;
2926
2943
  const textLayer = root.querySelector('.hj-capsule-text, .hj-progress-text');
2927
2944
  const visualLayer = root.querySelector('.hj-capsule-visual, .hj-progress-visual');
2928
- const move = (wrapper, layer) => {
2929
- if (!wrapper || !layer) return;
2930
- for (const node of Array.from(wrapper.childNodes)) layer.appendChild(node);
2931
- };
2932
2945
  const refs = this.$refs || {};
2933
- move(refs.slotText, textLayer);
2934
- move(refs.slotColor, visualLayer);
2946
+ // 把插槽容器整体搬进对应区域,而不是搬子节点:Vue 重渲染/重建组件时
2947
+ // 内容始终留在区域内,不会丢(子节点搬运会在 recreate 时序下丢失)。
2948
+ if (refs.slotText && textLayer && refs.slotText.parentElement !== textLayer) {
2949
+ textLayer.appendChild(refs.slotText);
2950
+ }
2951
+ if (refs.slotColor && visualLayer && refs.slotColor.parentElement !== visualLayer) {
2952
+ visualLayer.appendChild(refs.slotColor);
2953
+ }
2935
2954
  },
2936
2955
  applyAttrs() {
2937
2956
  if (!this.controller || !this.controller.element || !this.$attrs) return;
@@ -3058,7 +3077,7 @@ function makeProgressWrapper(createProgressCapsule, render) {
3058
3077
  name: 'ProgressCapsule',
3059
3078
  props: [
3060
3079
  'preset', 'width', 'height', 'value', 'min', 'max',
3061
- 'draggable', 'keyboard', 'disabled', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix',
3080
+ 'draggable', 'keyboard', 'disabled', 'readonly', 'edgeStyle', 'colors', 'textRatio', 'label', 'showValue', 'valueSuffix',
3062
3081
  'quality', 'renderer', 'respectReducedMotion', 'cssVars'
3063
3082
  ],
3064
3083
  events: PROGRESS_EVENTS,
@@ -3095,6 +3114,9 @@ function makeProgressWrapper(createProgressCapsule, render) {
3095
3114
  disabled() {
3096
3115
  this.scheduleRecreate();
3097
3116
  },
3117
+ readonly() {
3118
+ this.scheduleRecreate();
3119
+ },
3098
3120
  draggable() {
3099
3121
  this.scheduleRecreate();
3100
3122
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@5even7/dlc-ui",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/styles/base.css CHANGED
@@ -35,8 +35,8 @@
35
35
  box-sizing: border-box;
36
36
  }
37
37
 
38
- .hj-capsule-canvas,
39
- .hj-progress-canvas {
38
+ .hj-capsule-canvas,
39
+ .hj-progress-canvas {
40
40
  position: absolute;
41
41
  inset: 0;
42
42
  z-index: 1;
@@ -44,5 +44,13 @@
44
44
  width: 100%;
45
45
  height: 100%;
46
46
  border-radius: inherit;
47
- pointer-events: none;
48
- }
47
+ pointer-events: none;
48
+ }
49
+
50
+ /* Vue wrapper 的插槽容器会被搬到文字区/颜色区里,撑满区域以便内容正常布局。 */
51
+ .hj-vue-slot-text,
52
+ .hj-vue-slot-color {
53
+ display: block;
54
+ width: 100%;
55
+ height: 100%;
56
+ }
@@ -23,6 +23,10 @@
23
23
  outline: none;
24
24
  }
25
25
 
26
+ .hj-progress-root.is-readonly {
27
+ cursor: default;
28
+ }
29
+
26
30
  .hj-progress-root:focus-visible {
27
31
  outline: 2px solid rgba(255, 255, 255, 0.8);
28
32
  outline-offset: 4px;
package/types/index.d.ts CHANGED
@@ -61,6 +61,7 @@ export interface ProgressOptions {
61
61
  draggable?: boolean;
62
62
  keyboard?: boolean;
63
63
  disabled?: boolean;
64
+ readonly?: boolean;
64
65
  valueSuffix?: string;
65
66
  edgeStyle?: 'flow' | 'tide';
66
67
  colors?: string[];
@@ -180,7 +181,7 @@ export declare function getPreset(kind: 'capsule' | 'progress', ref: string): Ca
180
181
 
181
182
  export declare const DEFAULTS: {
182
183
  capsule: Required<Pick<CapsuleOptions, 'width' | 'height' | 'quality' | 'respectReducedMotion' | 'mouseColor' | 'renderer' | 'textRatio'>>;
183
- progress: Required<Pick<ProgressOptions, 'width' | 'height' | 'min' | 'max' | 'draggable' | 'keyboard' | 'disabled' | 'valueSuffix' | 'edgeStyle' | 'quality' | 'respectReducedMotion' | 'renderer' | 'textRatio' | 'showValue'>>;
184
+ progress: Required<Pick<ProgressOptions, 'width' | 'height' | 'min' | 'max' | 'draggable' | 'keyboard' | 'disabled' | 'readonly' | 'valueSuffix' | 'edgeStyle' | 'quality' | 'respectReducedMotion' | 'renderer' | 'textRatio' | 'showValue'>>;
184
185
  };
185
186
 
186
187
  export declare const COPY: Copy;