@threadlabs/looma 0.2.7 → 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.7",
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,
@@ -2194,7 +2210,7 @@ var UiTopBar_default = /* @__PURE__ */ _defineComponent31({
2194
2210
 
2195
2211
  // src/generated/UiTreeItem.ts
2196
2212
  import { defineComponent as _defineComponent32 } from "vue";
2197
- import { createElementVNode as _createElementVNode19, renderSlot as _renderSlot31, mergeProps as _mergeProps32, openBlock as _openBlock32, createElementBlock as _createElementBlock32 } from "vue";
2213
+ import { createElementVNode as _createElementVNode19, createCommentVNode as _createCommentVNode, renderSlot as _renderSlot31, mergeProps as _mergeProps32, openBlock as _openBlock32, createElementBlock as _createElementBlock32 } from "vue";
2198
2214
  import { onMounted as onMounted32, onUnmounted as onUnmounted32, ref as ref32, watchEffect as watchEffect33 } from "vue";
2199
2215
  import { attachLoomaComponent as attachLoomaComponent27 } from "@threadlabs/looma/core/declarative";
2200
2216
  var _hoisted_129 = ["aria-label", "data-container", "data-selected", "data-disabled", "data-drop-scope", "data-accepts"];
@@ -2279,7 +2295,7 @@ var UiTreeItem_default = /* @__PURE__ */ _defineComponent32({
2279
2295
  ref: root
2280
2296
  }), [
2281
2297
  _createElementVNode19("div", _hoisted_214, [
2282
- _cache[0] || (_cache[0] = _createElementVNode19(
2298
+ props.sortable && !props.disabled ? _cache[0] || (_cache[0] = _createElementVNode19(
2283
2299
  "button",
2284
2300
  {
2285
2301
  class: "drag-handle",
@@ -2292,27 +2308,30 @@ var UiTreeItem_default = /* @__PURE__ */ _defineComponent32({
2292
2308
  ],
2293
2309
  -1
2294
2310
  /* CACHED */
2295
- )),
2296
- _cache[1] || (_cache[1] = _createElementVNode19(
2297
- "template",
2298
- { "data-component": "ui-tree-item" },
2311
+ )) : _createCommentVNode("v-if", true),
2312
+ props.container ? _cache[1] || (_cache[1] = _createElementVNode19(
2313
+ "button",
2314
+ {
2315
+ class: "disclosure",
2316
+ part: "disclosure",
2317
+ type: "button",
2318
+ "data-component": "ui-tree-item"
2319
+ },
2299
2320
  [
2300
- _createElementVNode19("button", {
2301
- class: "disclosure",
2302
- part: "disclosure",
2303
- type: "button",
2304
- "data-component": "ui-tree-item"
2305
- }, [
2306
- _createElementVNode19("span", { "data-component": "ui-tree-item" })
2307
- ]),
2308
- _createElementVNode19("span", {
2309
- class: "disclosure-spacer",
2310
- "aria-hidden": "true",
2311
- "data-component": "ui-tree-item"
2312
- })
2321
+ _createElementVNode19("span", { "data-component": "ui-tree-item" })
2313
2322
  ],
2314
2323
  -1
2315
2324
  /* CACHED */
2325
+ )) : _cache[4] || (_cache[4] = _createElementVNode19(
2326
+ "span",
2327
+ {
2328
+ class: "disclosure-spacer",
2329
+ "aria-hidden": "true",
2330
+ "data-component": "ui-tree-item"
2331
+ },
2332
+ null,
2333
+ -1
2334
+ /* CACHED */
2316
2335
  )),
2317
2336
  _createElementVNode19("span", _hoisted_38, [
2318
2337
  _renderSlot31(_ctx.$slots, "leading")
@@ -2336,9 +2355,9 @@ var UiTreeItem_default = /* @__PURE__ */ _defineComponent32({
2336
2355
  /* CACHED */
2337
2356
  ))
2338
2357
  ]),
2339
- _createElementVNode19("div", _hoisted_63, [
2358
+ props.container ? _createElementVNode19("div", _hoisted_63, [
2340
2359
  _renderSlot31(_ctx.$slots, "children")
2341
- ]),
2360
+ ]) : _createCommentVNode("v-if", true),
2342
2361
  _cache[3] || (_cache[3] = _createElementVNode19(
2343
2362
  "span",
2344
2363
  {
@@ -10,7 +10,7 @@ import {
10
10
  UiEditorToolbar_default,
11
11
  createAdapterComponent,
12
12
  toHTMLElement
13
- } from "../chunk-4DPYH3IT.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-4DPYH3IT.js";
46
+ } from "./chunk-KQTGO5WQ.js";
47
47
  export {
48
48
  ADAPTER_COMPONENT_TAG_MAP,
49
49
  AffordanceScope,