@threadlabs/looma 0.2.8 → 0.2.9

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.
@@ -139,8 +139,8 @@ function toInitials(value) {
139
139
  function controller3(host) {
140
140
  const img = host.element.querySelector("img");
141
141
  const fallback = host.element.querySelector(".fallback");
142
- let hasImage = false;
143
142
  const apply = () => {
143
+ const hasImage = host.state.hasImage;
144
144
  const label = host.state.alt || host.state.name || "Avatar";
145
145
  host.element.setAttribute("role", "img");
146
146
  host.element.setAttribute("aria-label", label);
@@ -159,12 +159,10 @@ function controller3(host) {
159
159
  else host.element.removeAttribute("data-has-image");
160
160
  };
161
161
  const onLoad = () => {
162
- hasImage = true;
163
- apply();
162
+ host.state.hasImage = true;
164
163
  };
165
164
  const onError = () => {
166
- hasImage = false;
167
- apply();
165
+ host.state.hasImage = false;
168
166
  };
169
167
  img?.addEventListener("load", onLoad);
170
168
  img?.addEventListener("error", onError);
@@ -2020,13 +2018,18 @@ function controller19(host) {
2020
2018
  const status = host.element.querySelector(".search-shell__status");
2021
2019
  const footer = host.element.querySelector(".search-shell__footer");
2022
2020
  const syncSlots = () => {
2023
- if (status) status.hidden = !hasContent2(status);
2024
- if (footer) footer.hidden = !hasContent2(footer);
2021
+ const hasStatus = Boolean(status && hasContent2(status));
2022
+ const hasFooter = Boolean(footer && hasContent2(footer));
2023
+ host.state.hasStatus = hasStatus;
2024
+ host.state.hasFooter = hasFooter;
2025
+ if (status) status.hidden = !hasStatus;
2026
+ if (footer) footer.hidden = !hasFooter;
2025
2027
  };
2026
2028
  const observer = new MutationObserver(syncSlots);
2027
2029
  if (status) observer.observe(status, { childList: true, subtree: true });
2028
2030
  if (footer) observer.observe(footer, { childList: true, subtree: true });
2029
2031
  syncSlots();
2032
+ queueMicrotask(syncSlots);
2030
2033
  return () => observer.disconnect();
2031
2034
  }
2032
2035
 
@@ -2467,13 +2470,24 @@ function hasContent3(region) {
2467
2470
  return [...region.childNodes].some((node) => node.nodeType !== 3 || Boolean(node.textContent?.trim()));
2468
2471
  }
2469
2472
  function controller26(host) {
2470
- const regions = ["leading", "search", "actions"].map((name) => host.element.querySelector(`.top-bar__${name}`)).filter(Boolean);
2473
+ const regions = {
2474
+ hasLeading: host.element.querySelector(".top-bar__leading"),
2475
+ hasSearch: host.element.querySelector(".top-bar__search"),
2476
+ hasActions: host.element.querySelector(".top-bar__actions")
2477
+ };
2471
2478
  const syncSlots = () => {
2472
- for (const region of regions) region.hidden = !hasContent3(region);
2479
+ for (const [state, region] of Object.entries(regions)) {
2480
+ const present = Boolean(region && hasContent3(region));
2481
+ host.state[state] = present;
2482
+ if (region) region.hidden = !present;
2483
+ }
2473
2484
  };
2474
2485
  const observer = new MutationObserver(syncSlots);
2475
- for (const region of regions) observer.observe(region, { childList: true, subtree: true });
2486
+ for (const region of Object.values(regions)) {
2487
+ if (region) observer.observe(region, { childList: true, subtree: true });
2488
+ }
2476
2489
  syncSlots();
2490
+ queueMicrotask(syncSlots);
2477
2491
  return () => observer.disconnect();
2478
2492
  }
2479
2493
 
package/dist/index.cjs CHANGED
@@ -184,8 +184,8 @@ function toInitials(value) {
184
184
  function controller3(host) {
185
185
  const img = host.element.querySelector("img");
186
186
  const fallback = host.element.querySelector(".fallback");
187
- let hasImage = false;
188
187
  const apply = () => {
188
+ const hasImage = host.state.hasImage;
189
189
  const label = host.state.alt || host.state.name || "Avatar";
190
190
  host.element.setAttribute("role", "img");
191
191
  host.element.setAttribute("aria-label", label);
@@ -204,12 +204,10 @@ function controller3(host) {
204
204
  else host.element.removeAttribute("data-has-image");
205
205
  };
206
206
  const onLoad = () => {
207
- hasImage = true;
208
- apply();
207
+ host.state.hasImage = true;
209
208
  };
210
209
  const onError = () => {
211
- hasImage = false;
212
- apply();
210
+ host.state.hasImage = false;
213
211
  };
214
212
  img?.addEventListener("load", onLoad);
215
213
  img?.addEventListener("error", onError);
@@ -2065,13 +2063,18 @@ function controller19(host) {
2065
2063
  const status = host.element.querySelector(".search-shell__status");
2066
2064
  const footer = host.element.querySelector(".search-shell__footer");
2067
2065
  const syncSlots = () => {
2068
- if (status) status.hidden = !hasContent2(status);
2069
- if (footer) footer.hidden = !hasContent2(footer);
2066
+ const hasStatus = Boolean(status && hasContent2(status));
2067
+ const hasFooter = Boolean(footer && hasContent2(footer));
2068
+ host.state.hasStatus = hasStatus;
2069
+ host.state.hasFooter = hasFooter;
2070
+ if (status) status.hidden = !hasStatus;
2071
+ if (footer) footer.hidden = !hasFooter;
2070
2072
  };
2071
2073
  const observer = new MutationObserver(syncSlots);
2072
2074
  if (status) observer.observe(status, { childList: true, subtree: true });
2073
2075
  if (footer) observer.observe(footer, { childList: true, subtree: true });
2074
2076
  syncSlots();
2077
+ queueMicrotask(syncSlots);
2075
2078
  return () => observer.disconnect();
2076
2079
  }
2077
2080
 
@@ -2512,13 +2515,24 @@ function hasContent3(region) {
2512
2515
  return [...region.childNodes].some((node) => node.nodeType !== 3 || Boolean(node.textContent?.trim()));
2513
2516
  }
2514
2517
  function controller26(host) {
2515
- const regions = ["leading", "search", "actions"].map((name) => host.element.querySelector(`.top-bar__${name}`)).filter(Boolean);
2518
+ const regions = {
2519
+ hasLeading: host.element.querySelector(".top-bar__leading"),
2520
+ hasSearch: host.element.querySelector(".top-bar__search"),
2521
+ hasActions: host.element.querySelector(".top-bar__actions")
2522
+ };
2516
2523
  const syncSlots = () => {
2517
- for (const region of regions) region.hidden = !hasContent3(region);
2524
+ for (const [state2, region] of Object.entries(regions)) {
2525
+ const present = Boolean(region && hasContent3(region));
2526
+ host.state[state2] = present;
2527
+ if (region) region.hidden = !present;
2528
+ }
2518
2529
  };
2519
2530
  const observer = new MutationObserver(syncSlots);
2520
- for (const region of regions) observer.observe(region, { childList: true, subtree: true });
2531
+ for (const region of Object.values(regions)) {
2532
+ if (region) observer.observe(region, { childList: true, subtree: true });
2533
+ }
2521
2534
  syncSlots();
2535
+ queueMicrotask(syncSlots);
2522
2536
  return () => observer.disconnect();
2523
2537
  }
2524
2538
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  records,
3
3
  styles
4
- } from "./chunk-3K45IWIJ.js";
4
+ } from "./chunk-FAEZV4LT.js";
5
5
  import {
6
6
  attachLoomaComponent,
7
7
  controllerFor,
package/dist/loader.cjs CHANGED
@@ -160,8 +160,8 @@ function toInitials(value) {
160
160
  function controller3(host) {
161
161
  const img = host.element.querySelector("img");
162
162
  const fallback = host.element.querySelector(".fallback");
163
- let hasImage = false;
164
163
  const apply = () => {
164
+ const hasImage = host.state.hasImage;
165
165
  const label = host.state.alt || host.state.name || "Avatar";
166
166
  host.element.setAttribute("role", "img");
167
167
  host.element.setAttribute("aria-label", label);
@@ -180,12 +180,10 @@ function controller3(host) {
180
180
  else host.element.removeAttribute("data-has-image");
181
181
  };
182
182
  const onLoad = () => {
183
- hasImage = true;
184
- apply();
183
+ host.state.hasImage = true;
185
184
  };
186
185
  const onError = () => {
187
- hasImage = false;
188
- apply();
186
+ host.state.hasImage = false;
189
187
  };
190
188
  img?.addEventListener("load", onLoad);
191
189
  img?.addEventListener("error", onError);
@@ -2041,13 +2039,18 @@ function controller19(host) {
2041
2039
  const status = host.element.querySelector(".search-shell__status");
2042
2040
  const footer = host.element.querySelector(".search-shell__footer");
2043
2041
  const syncSlots = () => {
2044
- if (status) status.hidden = !hasContent2(status);
2045
- if (footer) footer.hidden = !hasContent2(footer);
2042
+ const hasStatus = Boolean(status && hasContent2(status));
2043
+ const hasFooter = Boolean(footer && hasContent2(footer));
2044
+ host.state.hasStatus = hasStatus;
2045
+ host.state.hasFooter = hasFooter;
2046
+ if (status) status.hidden = !hasStatus;
2047
+ if (footer) footer.hidden = !hasFooter;
2046
2048
  };
2047
2049
  const observer = new MutationObserver(syncSlots);
2048
2050
  if (status) observer.observe(status, { childList: true, subtree: true });
2049
2051
  if (footer) observer.observe(footer, { childList: true, subtree: true });
2050
2052
  syncSlots();
2053
+ queueMicrotask(syncSlots);
2051
2054
  return () => observer.disconnect();
2052
2055
  }
2053
2056
 
@@ -2488,13 +2491,24 @@ function hasContent3(region) {
2488
2491
  return [...region.childNodes].some((node) => node.nodeType !== 3 || Boolean(node.textContent?.trim()));
2489
2492
  }
2490
2493
  function controller26(host) {
2491
- const regions = ["leading", "search", "actions"].map((name) => host.element.querySelector(`.top-bar__${name}`)).filter(Boolean);
2494
+ const regions = {
2495
+ hasLeading: host.element.querySelector(".top-bar__leading"),
2496
+ hasSearch: host.element.querySelector(".top-bar__search"),
2497
+ hasActions: host.element.querySelector(".top-bar__actions")
2498
+ };
2492
2499
  const syncSlots = () => {
2493
- for (const region of regions) region.hidden = !hasContent3(region);
2500
+ for (const [state2, region] of Object.entries(regions)) {
2501
+ const present = Boolean(region && hasContent3(region));
2502
+ host.state[state2] = present;
2503
+ if (region) region.hidden = !present;
2504
+ }
2494
2505
  };
2495
2506
  const observer = new MutationObserver(syncSlots);
2496
- for (const region of regions) observer.observe(region, { childList: true, subtree: true });
2507
+ for (const region of Object.values(regions)) {
2508
+ if (region) observer.observe(region, { childList: true, subtree: true });
2509
+ }
2497
2510
  syncSlots();
2511
+ queueMicrotask(syncSlots);
2498
2512
  return () => observer.disconnect();
2499
2513
  }
2500
2514
 
package/dist/loader.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  records,
3
3
  styles
4
- } from "./chunk-3K45IWIJ.js";
4
+ } from "./chunk-FAEZV4LT.js";
5
5
  import {
6
6
  registerLoomaPackage
7
7
  } from "./chunk-3HMMDK27.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "type": "module",
5
5
  "description": "Looma declarative components, responsive layout primitives, a complete editor, and supported Vue adapters.",
6
6
  "license": "MIT",
@@ -4,11 +4,24 @@ import "@threadlabs/looma/core";
4
4
 
5
5
  // src/adapter.ts
6
6
  import {
7
+ cloneVNode,
7
8
  defineComponent,
9
+ Fragment,
8
10
  h,
11
+ isVNode,
9
12
  shallowRef,
10
13
  watchEffect
11
14
  } from "vue";
15
+ function assignNamedSlot(value, slotName) {
16
+ if (Array.isArray(value)) return value.map((child) => assignNamedSlot(child, slotName));
17
+ if (!isVNode(value)) return value;
18
+ if (value.type === Fragment && Array.isArray(value.children)) {
19
+ const fragment = cloneVNode(value);
20
+ fragment.children = value.children.map((child) => assignNamedSlot(child, slotName));
21
+ return fragment;
22
+ }
23
+ return cloneVNode(value, { slot: slotName });
24
+ }
12
25
  var BASE_EVENT_BINDINGS = [
13
26
  ["open", "onOpen"],
14
27
  ["close", "onClose"],
@@ -68,7 +81,10 @@ function createAdapterComponent(component, displayName, additionalEventBindings
68
81
  )
69
82
  );
70
83
  const componentSlots = Object.fromEntries(
71
- Object.entries(slots).filter((entry) => Boolean(entry[1])).map(([slotName, slotFn]) => [slotName, () => slotFn()])
84
+ Object.entries(slots).filter((entry) => Boolean(entry[1])).map(([slotName, slotFn]) => [
85
+ slotName,
86
+ () => slotName === "default" ? slotFn() : assignNamedSlot(slotFn(), slotName)
87
+ ])
72
88
  );
73
89
  return h(
74
90
  component,
@@ -10,7 +10,7 @@ import {
10
10
  UiEditorToolbar_default,
11
11
  createAdapterComponent,
12
12
  toHTMLElement
13
- } from "../chunk-5OS45GWE.js";
13
+ } from "../chunk-KQTGO5WQ.js";
14
14
 
15
15
  // src/editor/index.ts
16
16
  import "@threadlabs/looma/editor";
package/vue/index.js CHANGED
@@ -43,7 +43,7 @@ import {
43
43
  Tree,
44
44
  TreeItem,
45
45
  VUE_ADAPTER_NOTE
46
- } from "./chunk-5OS45GWE.js";
46
+ } from "./chunk-KQTGO5WQ.js";
47
47
  export {
48
48
  ADAPTER_COMPONENT_TAG_MAP,
49
49
  AffordanceScope,