voodoojs 0.11.2 → 0.12.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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-H2ZUEQWV.js → chunk-4M4ZXHNY.js} +84 -19
  3. package/dist/{chunk-UV5PMS7P.js → chunk-72PMUUMT.js} +4 -4
  4. package/dist/{chunk-KQYSJHZR.js → chunk-AFMCDNYS.js} +5 -5
  5. package/dist/{chunk-DJJB35SR.js → chunk-D7675IJG.js} +6 -6
  6. package/dist/{chunk-IS3DR2KY.js → chunk-GXPNWCGE.js} +3 -3
  7. package/dist/{chunk-DCE5WIGA.js → chunk-HNM3CTBD.js} +5 -5
  8. package/dist/{chunk-IGZSDZKU.js → chunk-KN7NAKBL.js} +4 -4
  9. package/dist/{chunk-WJP3YGUI.js → chunk-LLNDLLKV.js} +4 -4
  10. package/dist/{chunk-V3O3WOZH.js → chunk-NP66JM2P.js} +4 -4
  11. package/dist/{chunk-AH2VXDZD.js → chunk-RDHYPGH6.js} +187 -18
  12. package/dist/{chunk-NFDXVIII.js → chunk-T5ION5NG.js} +3 -3
  13. package/dist/essential.cjs +263 -25
  14. package/dist/essential.d.cts +1 -1
  15. package/dist/essential.d.ts +1 -1
  16. package/dist/essential.js +10 -10
  17. package/dist/gpu.cjs +1 -1
  18. package/dist/gpu.js +10 -10
  19. package/dist/http.cjs +1 -1
  20. package/dist/http.js +5 -5
  21. package/dist/index.cjs +273 -27
  22. package/dist/index.d.cts +88 -4
  23. package/dist/index.d.ts +88 -4
  24. package/dist/index.js +20 -20
  25. package/dist/{query-Cf-7iibE.d.ts → query-DzHfm8Kg.d.ts} +40 -29
  26. package/dist/{query-DiQAS73Q.d.cts → query-XooOh4vB.d.cts} +40 -29
  27. package/dist/reactivity.cjs +1 -1
  28. package/dist/reactivity.js +2 -2
  29. package/dist/socket.cjs +1 -1
  30. package/dist/socket.js +9 -9
  31. package/dist/style-GR4X6O7I.js +5 -0
  32. package/dist/utils.cjs +1 -1
  33. package/dist/utils.js +2 -2
  34. package/dist/voodoo.core.js +242 -24
  35. package/dist/voodoo.core.min.js +17 -17
  36. package/dist/voodoo.full.js +266 -27
  37. package/dist/voodoo.full.min.js +57 -53
  38. package/dist/voodoo.js +264 -25
  39. package/dist/voodoo.min.js +29 -25
  40. package/package.json +1 -1
  41. package/dist/style-4X62SABN.js +0 -5
package/dist/voodoo.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Voodoo.js v0.11.2
2
+ * Voodoo.js v0.12.1
3
3
  * JavaScript feels like magic.
4
4
  * (c) 2026 Voodoo.js contributors. MIT License.
5
5
  */
@@ -2263,6 +2263,10 @@ Expression: ${expression}` : message);
2263
2263
  function magic(name, getter) {
2264
2264
  magics.set(name.startsWith("$") ? name : `$${name}`, getter);
2265
2265
  }
2266
+ var hooks = /* @__PURE__ */ new Map();
2267
+ function hook(name, getter) {
2268
+ hooks.set(name, getter);
2269
+ }
2266
2270
  var Scope = class _Scope {
2267
2271
  // Assignment order matches the order the fields were declared in before, so
2268
2272
  // the properties are created in the same sequence they always were.
@@ -2318,7 +2322,10 @@ Expression: ${expression}` : message);
2318
2322
  s = s.parent;
2319
2323
  }
2320
2324
  if (name.charCodeAt(0) === 36 && magics.has(name)) {
2321
- return this.magicContainer(name);
2325
+ return this.magicContainer(name, magics);
2326
+ }
2327
+ if (hooks.has(name)) {
2328
+ return this.magicContainer(name, hooks);
2322
2329
  }
2323
2330
  return void 0;
2324
2331
  }
@@ -2347,11 +2354,11 @@ Expression: ${expression}` : message);
2347
2354
  reactiveChild(vars, el = null) {
2348
2355
  return new _Scope(reactive(vars), this, el != null ? el : this.el);
2349
2356
  }
2350
- magicContainer(name) {
2357
+ magicContainer(name, registry) {
2351
2358
  if (!this.magicCache) this.magicCache = /* @__PURE__ */ new Map();
2352
2359
  const cached = this.magicCache.get(name);
2353
2360
  if (cached) return cached;
2354
- const getter = magics.get(name);
2361
+ const getter = registry.get(name);
2355
2362
  const scope = this;
2356
2363
  const container2 = {};
2357
2364
  Object.defineProperty(container2, name, {
@@ -2744,7 +2751,16 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
2744
2751
  },
2745
2752
  effect(fn) {
2746
2753
  const owner = ownerScope();
2747
- owner.run(() => effect(fn, { scope: owner }));
2754
+ const hosted = () => {
2755
+ const previous = hookHost;
2756
+ hookHost = el;
2757
+ try {
2758
+ fn();
2759
+ } finally {
2760
+ hookHost = previous;
2761
+ }
2762
+ };
2763
+ owner.run(() => effect(hosted, { scope: owner }));
2748
2764
  },
2749
2765
  cleanup(fn) {
2750
2766
  addCleanup(el, fn);
@@ -2792,6 +2808,56 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
2792
2808
  return;
2793
2809
  }
2794
2810
  initialized.add(el);
2811
+ const previousHost = hookHost;
2812
+ hookHost = el;
2813
+ try {
2814
+ walkElementDirectives(el, attrs, tagComponent, current2);
2815
+ } finally {
2816
+ hookHost = previousHost;
2817
+ }
2818
+ }
2819
+ var hookHost = null;
2820
+ function currentHookHost() {
2821
+ return hookHost;
2822
+ }
2823
+ function createDataScope(expression, parent, el) {
2824
+ let ast = null;
2825
+ try {
2826
+ ast = parse(expression);
2827
+ } catch (e) {
2828
+ ast = null;
2829
+ }
2830
+ const plain = ast && ast.t === "obj" && ast.props.every(
2831
+ (p2) => !p2.spread && !p2.keyExpr
2832
+ );
2833
+ if (!plain) {
2834
+ const raw = evaluateIn(expression, parent, "v-data");
2835
+ return parent.reactiveChild(raw && typeof raw === "object" ? raw : {}, el);
2836
+ }
2837
+ const scope = parent.reactiveChild({}, el);
2838
+ const props = ast.props;
2839
+ for (const prop of props) {
2840
+ if (prop.key === null) continue;
2841
+ try {
2842
+ if (prop.getter) {
2843
+ const compute = evaluate(prop.value, scope);
2844
+ Object.defineProperty(scope.data, prop.key, {
2845
+ enumerable: true,
2846
+ configurable: true,
2847
+ get: () => compute.call(scope.data)
2848
+ });
2849
+ } else {
2850
+ scope.data[prop.key] = evaluate(prop.value, scope);
2851
+ }
2852
+ } catch (err) {
2853
+ if (inDevelopment()) warnInvalidExpression(el, expression, expression, err);
2854
+ else handleError(err, "v-data");
2855
+ }
2856
+ }
2857
+ return scope;
2858
+ }
2859
+ function walkElementDirectives(el, attrs, tagComponent, scope) {
2860
+ let current2 = scope;
2795
2861
  for (const attr2 of attrs) {
2796
2862
  const def = directives.get(attr2.name);
2797
2863
  if (def == null ? void 0 : def.terminal) {
@@ -2811,11 +2877,10 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
2811
2877
  nodeScopes.set(el, current2);
2812
2878
  }
2813
2879
  } else if (dataAttr || componentAttr) {
2814
- const raw = dataAttr ? evaluateIn(dataAttr.expression || "{}", current2, "v-data") : {};
2815
- current2 = current2.reactiveChild(raw && typeof raw === "object" ? raw : {}, el);
2880
+ current2 = createDataScope(dataAttr ? dataAttr.expression || "{}" : "{}", current2, el);
2816
2881
  nodeScopes.set(el, current2);
2817
2882
  }
2818
- const attributeScope = mountedComponent ? activeScope2 : current2;
2883
+ const attributeScope = mountedComponent ? scope : current2;
2819
2884
  for (const attr2 of attrs) {
2820
2885
  if (attr2.name === "data" || attr2.name === "component") continue;
2821
2886
  runDirective(el, attr2, attributeScope);
@@ -2972,9 +3037,9 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
2972
3037
  var observer = null;
2973
3038
  var startHooks = [];
2974
3039
  function runPhase(target, after) {
2975
- for (const hook of startHooks) {
3040
+ for (const hook2 of startHooks) {
2976
3041
  try {
2977
- hook(target, after);
3042
+ hook2(target, after);
2978
3043
  } catch (error) {
2979
3044
  console.error("[Voodoo] a start hook failed", error);
2980
3045
  }
@@ -3358,10 +3423,10 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
3358
3423
  "destroyed"
3359
3424
  ]);
3360
3425
  function callHook(def, instance, name) {
3361
- const hook = def[name];
3362
- if (typeof hook !== "function") return;
3426
+ const hook2 = def[name];
3427
+ if (typeof hook2 !== "function") return;
3363
3428
  try {
3364
- hook.call(instance);
3429
+ hook2.call(instance);
3365
3430
  } catch (err) {
3366
3431
  handleError(err, `hook ${name}`);
3367
3432
  }
@@ -4820,6 +4885,7 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
4820
4885
  );
4821
4886
 
4822
4887
  // src/storage/index.ts
4888
+ init_reactivity();
4823
4889
  function createStorage(getStore, prefix = "") {
4824
4890
  const full = (key) => prefix + key;
4825
4891
  return {
@@ -4995,22 +5061,29 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
4995
5061
  };
4996
5062
  var THEME_KEY = "voodoo:theme";
4997
5063
  var picked = null;
5064
+ var revision = ref(0);
4998
5065
  var theme = {
4999
5066
  /** Theme chosen by the user, or `system` when never set. */
5000
5067
  get current() {
5001
5068
  var _a2, _b;
5069
+ void revision.value;
5002
5070
  return (_b = (_a2 = storage.get(THEME_KEY)) != null ? _a2 : picked) != null ? _b : "system";
5003
5071
  },
5004
5072
  /** Theme effectively applied, resolving `system`. */
5005
5073
  get resolved() {
5006
5074
  const value = this.current;
5007
5075
  if (value !== "system") return value;
5076
+ if (typeof document !== "undefined") {
5077
+ const authored = document.documentElement.getAttribute("data-theme");
5078
+ if (authored === "light" || authored === "dark") return authored;
5079
+ }
5008
5080
  if (typeof matchMedia === "undefined") return "light";
5009
5081
  return matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
5010
5082
  },
5011
5083
  set(value) {
5012
5084
  picked = value;
5013
5085
  storage.set(THEME_KEY, value);
5086
+ revision.value++;
5014
5087
  this.apply();
5015
5088
  },
5016
5089
  toggle() {
@@ -5044,8 +5117,17 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
5044
5117
  init() {
5045
5118
  if (typeof document === "undefined") return;
5046
5119
  this.apply();
5120
+ if (typeof MutationObserver !== "undefined") {
5121
+ new MutationObserver(() => {
5122
+ revision.value++;
5123
+ }).observe(document.documentElement, {
5124
+ attributes: true,
5125
+ attributeFilter: ["data-theme"]
5126
+ });
5127
+ }
5047
5128
  if (typeof matchMedia === "undefined") return;
5048
5129
  matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
5130
+ revision.value++;
5049
5131
  if (this.current === "system") this.apply();
5050
5132
  });
5051
5133
  }
@@ -5189,6 +5271,141 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
5189
5271
  );
5190
5272
  }
5191
5273
 
5274
+ // src/hooks/index.ts
5275
+ init_reactivity();
5276
+ var tables = /* @__PURE__ */ new WeakMap();
5277
+ function tableFor(scope) {
5278
+ var _a2, _b, _c;
5279
+ const host = (_b = (_a2 = currentHookHost()) != null ? _a2 : scope.el) != null ? _b : scope;
5280
+ let table = tables.get(host);
5281
+ if (!table) {
5282
+ table = { slots: [], index: 0, scheduled: false, bound: false };
5283
+ tables.set(host, table);
5284
+ }
5285
+ const el = (_c = currentHookHost()) != null ? _c : scope.el;
5286
+ if (!table.bound && el) {
5287
+ table.bound = true;
5288
+ const owned = table;
5289
+ addCleanup(el, () => {
5290
+ for (const slot of owned.slots) {
5291
+ if (slot.dispose) slot.dispose();
5292
+ if (slot.runner) stop(slot.runner);
5293
+ }
5294
+ owned.slots.length = 0;
5295
+ });
5296
+ }
5297
+ if (!table.scheduled) {
5298
+ table.scheduled = true;
5299
+ const pending = table;
5300
+ queueMicrotask(() => {
5301
+ pending.index = 0;
5302
+ pending.scheduled = false;
5303
+ });
5304
+ }
5305
+ return table;
5306
+ }
5307
+ function nextSlot(scope, kind) {
5308
+ const table = tableFor(scope);
5309
+ const at = table.index++;
5310
+ let slot = table.slots[at];
5311
+ if (!slot || slot.kind !== kind) {
5312
+ if (slot) {
5313
+ if (slot.dispose) slot.dispose();
5314
+ if (slot.runner) stop(slot.runner);
5315
+ }
5316
+ slot = { kind, deps: null, value: void 0 };
5317
+ table.slots[at] = slot;
5318
+ }
5319
+ return slot;
5320
+ }
5321
+ function depsChanged(previous, next) {
5322
+ if (!previous || !next) return true;
5323
+ if (previous.length !== next.length) return true;
5324
+ for (let i = 0; i < next.length; i++) {
5325
+ if (!Object.is(previous[i], next[i])) return true;
5326
+ }
5327
+ return false;
5328
+ }
5329
+ function normalizeDeps(deps) {
5330
+ return Array.isArray(deps) ? deps.slice() : null;
5331
+ }
5332
+ function useState(scope, initial) {
5333
+ const slot = nextSlot(scope, "state");
5334
+ if (slot.value === void 0) slot.value = ref(initial);
5335
+ return slot.value;
5336
+ }
5337
+ function useEffect(scope, fn, deps) {
5338
+ const slot = nextSlot(scope, "effect");
5339
+ const next = normalizeDeps(deps);
5340
+ const runCleanup = () => {
5341
+ if (slot.dispose) {
5342
+ const dispose = slot.dispose;
5343
+ slot.dispose = void 0;
5344
+ dispose();
5345
+ }
5346
+ };
5347
+ if (next) {
5348
+ const first = slot.deps === null && !slot.runner;
5349
+ if (first || depsChanged(slot.deps, next)) {
5350
+ slot.deps = next;
5351
+ runCleanup();
5352
+ const result = fn();
5353
+ if (typeof result === "function") slot.dispose = result;
5354
+ }
5355
+ return;
5356
+ }
5357
+ if (slot.runner) return;
5358
+ slot.deps = null;
5359
+ slot.runner = effect(() => {
5360
+ runCleanup();
5361
+ const result = fn();
5362
+ if (typeof result === "function") slot.dispose = result;
5363
+ });
5364
+ }
5365
+ function useMemo(scope, fn, deps) {
5366
+ const slot = nextSlot(scope, "memo");
5367
+ const next = normalizeDeps(deps);
5368
+ if (!next) {
5369
+ if (!slot.value) slot.value = computed(fn);
5370
+ return slot.value;
5371
+ }
5372
+ if (!slot.value) {
5373
+ slot.value = ref(fn());
5374
+ slot.deps = next;
5375
+ } else if (depsChanged(slot.deps, next)) {
5376
+ slot.deps = next;
5377
+ slot.value.value = fn();
5378
+ }
5379
+ return slot.value;
5380
+ }
5381
+ function useRef(scope, initial) {
5382
+ const slot = nextSlot(scope, "ref");
5383
+ if (!slot.value) slot.value = markRaw({ current: initial });
5384
+ return slot.value;
5385
+ }
5386
+ function useContext(name, initial) {
5387
+ if (initial !== void 0 && !(name in allStores)) {
5388
+ store(name, initial);
5389
+ }
5390
+ return allStores[name];
5391
+ }
5392
+ function installHooks() {
5393
+ hook("useState", (scope) => (initial) => useState(scope, initial));
5394
+ hook(
5395
+ "useEffect",
5396
+ (scope) => (fn, deps) => useEffect(scope, fn, deps)
5397
+ );
5398
+ hook(
5399
+ "useMemo",
5400
+ (scope) => (fn, deps) => useMemo(scope, fn, deps)
5401
+ );
5402
+ hook("useRef", (scope) => (initial) => useRef(scope, initial));
5403
+ hook(
5404
+ "useContext",
5405
+ () => (name, initial) => useContext(name, initial)
5406
+ );
5407
+ }
5408
+
5192
5409
  // src/http/resource.ts
5193
5410
  init_reactivity();
5194
5411
  function pick(value, path) {
@@ -6793,6 +7010,7 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
6793
7010
  setScopeMarker(markNodeScope);
6794
7011
  setDirectiveRegistrar(directive);
6795
7012
  installMagics();
7013
+ installHooks();
6796
7014
  var eventBus = /* @__PURE__ */ new Map();
6797
7015
  function on(name, handler) {
6798
7016
  let set2 = eventBus.get(name);
@@ -6828,7 +7046,7 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
6828
7046
  }
6829
7047
  function directive(name, definition) {
6830
7048
  var _a2, _b;
6831
- const hooks = typeof definition === "function" ? { mounted: definition, updated: definition } : definition;
7049
+ const hooks2 = typeof definition === "function" ? { mounted: definition, updated: definition } : definition;
6832
7050
  defineDirective(
6833
7051
  name,
6834
7052
  (ctx) => {
@@ -6848,38 +7066,38 @@ Suggestion: attribute expressions accept a single value. If the logic spans more
6848
7066
  instance: (_b3 = (_a4 = ctx.scope.owner) == null ? void 0 : _a4.component) != null ? _b3 : null
6849
7067
  };
6850
7068
  };
6851
- const initial = hooks.raw ? ctx.expression : ctx.evaluate();
6852
- (_a3 = hooks.created) == null ? void 0 : _a3.call(hooks, ctx.el, makeBinding(initial));
6853
- (_b2 = hooks.beforeMount) == null ? void 0 : _b2.call(hooks, ctx.el, makeBinding(initial));
7069
+ const initial = hooks2.raw ? ctx.expression : ctx.evaluate();
7070
+ (_a3 = hooks2.created) == null ? void 0 : _a3.call(hooks2, ctx.el, makeBinding(initial));
7071
+ (_b2 = hooks2.beforeMount) == null ? void 0 : _b2.call(hooks2, ctx.el, makeBinding(initial));
6854
7072
  ctx.effect(() => {
6855
7073
  var _a4, _b3;
6856
- const value = hooks.raw ? ctx.expression : ctx.evaluate();
7074
+ const value = hooks2.raw ? ctx.expression : ctx.evaluate();
6857
7075
  if (!mounted) {
6858
7076
  mounted = true;
6859
7077
  oldValue = value;
6860
- (_a4 = hooks.mounted) == null ? void 0 : _a4.call(hooks, ctx.el, makeBinding(value));
7078
+ (_a4 = hooks2.mounted) == null ? void 0 : _a4.call(hooks2, ctx.el, makeBinding(value));
6861
7079
  return;
6862
7080
  }
6863
7081
  if (value === oldValue) return;
6864
7082
  const binding = makeBinding(value);
6865
- (_b3 = hooks.updated) == null ? void 0 : _b3.call(hooks, ctx.el, binding);
7083
+ (_b3 = hooks2.updated) == null ? void 0 : _b3.call(hooks2, ctx.el, binding);
6866
7084
  oldValue = value;
6867
7085
  });
6868
7086
  ctx.cleanup(() => {
6869
7087
  var _a4, _b3;
6870
7088
  const binding = makeBinding(oldValue);
6871
- (_a4 = hooks.beforeUnmount) == null ? void 0 : _a4.call(hooks, ctx.el, binding);
6872
- (_b3 = hooks.unmounted) == null ? void 0 : _b3.call(hooks, ctx.el, binding);
7089
+ (_a4 = hooks2.beforeUnmount) == null ? void 0 : _a4.call(hooks2, ctx.el, binding);
7090
+ (_b3 = hooks2.unmounted) == null ? void 0 : _b3.call(hooks2, ctx.el, binding);
6873
7091
  });
6874
7092
  },
6875
- { priority: (_a2 = hooks.priority) != null ? _a2 : PRIORITY.DEFAULT, terminal: (_b = hooks.terminal) != null ? _b : false }
7093
+ { priority: (_a2 = hooks2.priority) != null ? _a2 : PRIORITY.DEFAULT, terminal: (_b = hooks2.terminal) != null ? _b : false }
6876
7094
  );
6877
7095
  }
6878
7096
  function data(values) {
6879
7097
  Object.defineProperties(rootScope.data, Object.getOwnPropertyDescriptors(values));
6880
7098
  return rootScope.data;
6881
7099
  }
6882
- var version2 = "0.11.2";
7100
+ var version2 = "0.12.1";
6883
7101
  var core = {
6884
7102
  // Utilities first: Voodoo's own names can override.
6885
7103
  ...utils_exports,
@@ -12401,12 +12619,15 @@ form.v-loading [type="submit"],form.v-loading button[disabled]{opacity:.6}
12401
12619
 
12402
12620
  // src/sound/index.ts
12403
12621
  init_registry();
12622
+ init_reactivity();
12623
+ init_style();
12404
12624
  var audioContext = null;
12405
12625
  var masterVolume = 0.35;
12406
12626
  var isMuted = false;
12407
12627
  var hasLoadedPreference = false;
12408
12628
  var VOLUME_KEY = "voodoo:sound:volume";
12409
12629
  var MUTE_KEY = "voodoo:sound:muted";
12630
+ var muteRevision = ref(0);
12410
12631
  function loadPreference() {
12411
12632
  if (hasLoadedPreference) return;
12412
12633
  hasLoadedPreference = true;
@@ -12722,6 +12943,7 @@ form.v-loading [type="submit"],form.v-loading button[disabled]{opacity:.6}
12722
12943
  loadPreference();
12723
12944
  isMuted = value;
12724
12945
  storage.set(MUTE_KEY, isMuted);
12946
+ muteRevision.value++;
12725
12947
  },
12726
12948
  /** Unmutes sound. */
12727
12949
  unmute() {
@@ -12733,8 +12955,18 @@ form.v-loading [type="submit"],form.v-loading button[disabled]{opacity:.6}
12733
12955
  this.mute(!isMuted);
12734
12956
  return isMuted;
12735
12957
  },
12736
- /** `true` when muted. */
12958
+ /**
12959
+ * `true` when muted.
12960
+ *
12961
+ * Reads a revision ref first, so that an expression asking whether sound is
12962
+ * muted actually re-runs when it changes. The state lives in a module
12963
+ * variable and in localStorage, both invisible to the Proxy, so
12964
+ * `v-show="$sound.muted"` used to render once and then never move: a page had
12965
+ * no way to show whether it was muted, which made the mute button look like
12966
+ * it did nothing at all.
12967
+ */
12737
12968
  get muted() {
12969
+ void muteRevision.value;
12738
12970
  loadPreference();
12739
12971
  return isMuted;
12740
12972
  },
@@ -12785,11 +13017,18 @@ form.v-loading [type="submit"],form.v-loading button[disabled]{opacity:.6}
12785
13017
  cleanup(() => el.removeEventListener(event, play));
12786
13018
  void scope;
12787
13019
  });
13020
+ var MUTE_CSS = `
13021
+ .v-muted{opacity:.55}
13022
+ .v-muted::after{content:" \\1F507";font-size:.9em}
13023
+ .v-mute-on::after{content:" \\1F50A";font-size:.9em}
13024
+ `;
12788
13025
  defineDirective("mute", ({ el, cleanup }) => {
13026
+ injectStyle("mute", MUTE_CSS);
12789
13027
  const sync = () => {
12790
13028
  const isMuted2 = sound.muted;
12791
13029
  el.setAttribute("aria-pressed", String(isMuted2));
12792
13030
  el.classList.toggle("v-muted", isMuted2);
13031
+ el.classList.toggle("v-mute-on", !isMuted2);
12793
13032
  };
12794
13033
  const toggle = () => {
12795
13034
  sound.toggle();