@rettangoli/ui 1.0.17 → 1.0.19

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rettangoli/ui",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "A UI component library for building web interfaces.",
5
5
  "main": "dist/rettangoli-esm.min.js",
6
6
  "type": "module",
@@ -37,7 +37,7 @@
37
37
  "build": "rtgl fe build -o ./.generated/fe-entry.js && bun run esbuild.js && bun run esbuild-dev.js && npm run copy:css",
38
38
  "prepack": "npm run build",
39
39
  "vt:generate": "bun run build:dev && rtgl vt generate",
40
- "vt:docker": "bun run build:dev && bash -lc 'IMAGE=\"han4wluc/rtgl:playwright-v1.57.0-rtgl-v1.0.10\"; docker pull \"$IMAGE\" >/dev/null 2>&1; docker run --rm --user $(id -u):$(id -g) -v \"$PWD:/app\" -w /app \"$IMAGE\" rtgl vt screenshot'",
40
+ "vt:docker": "bun run build:dev && bash -lc 'IMAGE=\"han4wluc/rtgl:playwright-v1.57.0-rtgl-v1.1.0\"; docker pull \"$IMAGE\" >/dev/null 2>&1; docker run --rm --user $(id -u):$(id -g) -v \"$PWD:/app\" -w /app \"$IMAGE\" rtgl vt screenshot'",
41
41
  "vt:report": "bun run vt:docker && rtgl vt report",
42
42
  "vt:accept": "rtgl vt accept",
43
43
  "serve": "bunx serve .rettangoli/vt/_site"
@@ -62,7 +62,7 @@
62
62
  },
63
63
  "homepage": "https://github.com/yuusoft-org/rettangoli#readme",
64
64
  "dependencies": {
65
- "@rettangoli/fe": "1.1.0",
65
+ "@rettangoli/fe": "1.1.1",
66
66
  "jempl": "1.0.1"
67
67
  }
68
68
  }
@@ -1,11 +1,32 @@
1
+ const getHeadingElements = (contentContainer) => {
2
+ const headings = contentContainer.querySelectorAll(
3
+ "h1[id], h2[id], h3[id], h4[id], rtgl-text[id]"
4
+ );
5
+ return Array.from(headings);
6
+ };
7
+
8
+ const buildItems = (headingElements) => {
9
+ return headingElements.map((heading) => {
10
+ let level = 1;
11
+ const tagName = heading.tagName.toLowerCase();
1
12
 
13
+ if (tagName === "h1") level = 1;
14
+ else if (tagName === "h2") level = 2;
15
+ else if (tagName === "h3") level = 3;
16
+ else if (tagName === "h4") level = 4;
17
+ else if (tagName === "rtgl-text") {
18
+ level = parseInt(heading.getAttribute("data-level") || "1", 10);
19
+ }
20
+
21
+ return {
22
+ id: heading.id,
23
+ href: `#${heading.id}`,
24
+ title: heading.textContent,
25
+ level
26
+ };
27
+ });
28
+ };
2
29
 
3
- /**
4
- *
5
- * @param {*} headingElements
6
- * @param {*} offsetTop
7
- * @param {*} deps
8
- */
9
30
  const updateToLatestCurrentId = (headingElements, offsetTop, deps) => {
10
31
  const { store, render } = deps;
11
32
 
@@ -45,45 +66,51 @@ const updateToLatestCurrentId = (headingElements, offsetTop, deps) => {
45
66
 
46
67
  const startListening = (contentContainer, scrollContainer, offsetTop, deps) => {
47
68
  const { store, render } = deps;
48
-
49
- // Extract headings
50
- const headings = contentContainer.querySelectorAll("h1[id], h2[id], h3[id], h4[id], rtgl-text[id]");
51
- const headingElements = Array.from(headings);
52
-
53
- const items = headingElements.map((heading) => {
54
- let level = 1;
55
- const tagName = heading.tagName.toLowerCase();
56
-
57
- if (tagName === 'h1') level = 1;
58
- else if (tagName === 'h2') level = 2;
59
- else if (tagName === 'h3') level = 3;
60
- else if (tagName === 'h4') level = 4;
61
- else if (tagName === 'rtgl-text') {
62
- // For rtgl-text, check if it has a data-level attribute or default to 1
63
- level = parseInt(heading.getAttribute('data-level') || '1', 10);
69
+ let rafId = null;
70
+
71
+ const syncOutline = () => {
72
+ rafId = null;
73
+ const headingElements = getHeadingElements(contentContainer);
74
+ store.setItems({ items: buildItems(headingElements) });
75
+ updateToLatestCurrentId(headingElements, offsetTop, deps);
76
+ render();
77
+ };
78
+
79
+ const scheduleSyncOutline = () => {
80
+ if (rafId !== null) {
81
+ return;
64
82
  }
65
-
66
- return {
67
- id: heading.id,
68
- href: `#${heading.id}`,
69
- title: heading.textContent,
70
- level: level
71
- };
72
- });
73
-
74
- store.setItems({ items });
75
- updateToLatestCurrentId(headingElements, offsetTop, deps);
76
- render();
83
+ rafId = requestAnimationFrame(syncOutline);
84
+ };
77
85
 
78
- const boundCheckCurrentHeading = updateToLatestCurrentId.bind(this, headingElements, offsetTop, deps);
79
-
80
- // Add scroll listener to the scroll container
81
- scrollContainer.addEventListener("scroll", boundCheckCurrentHeading, {
86
+ const handleScroll = () => {
87
+ updateToLatestCurrentId(getHeadingElements(contentContainer), offsetTop, deps);
88
+ };
89
+
90
+ scheduleSyncOutline();
91
+
92
+ scrollContainer.addEventListener("scroll", handleScroll, {
82
93
  passive: true,
83
94
  });
84
95
 
96
+ const observer = new MutationObserver(() => {
97
+ scheduleSyncOutline();
98
+ });
99
+
100
+ observer.observe(contentContainer, {
101
+ childList: true,
102
+ subtree: true,
103
+ characterData: true,
104
+ attributes: true,
105
+ attributeFilter: ["id", "data-level"]
106
+ });
107
+
85
108
  return () => {
86
- scrollContainer.removeEventListener("scroll", boundCheckCurrentHeading);
109
+ if (rafId !== null) {
110
+ cancelAnimationFrame(rafId);
111
+ }
112
+ observer.disconnect();
113
+ scrollContainer.removeEventListener("scroll", handleScroll);
87
114
  }
88
115
  };
89
116
 
@@ -104,7 +104,8 @@ class RettangoliViewElement extends HTMLElement {
104
104
  "av",
105
105
  "wrap",
106
106
  "no-wrap",
107
- "overflow"
107
+ "overflow",
108
+ "stretch"
108
109
  ]),
109
110
  ];
110
111
  }
@@ -300,6 +301,11 @@ class RettangoliViewElement extends HTMLElement {
300
301
  this._styles[size]["flex-wrap"] = "nowrap";
301
302
  }
302
303
 
304
+ // Handle stretch
305
+ if (this.hasAttribute(addSizePrefix("stretch"))) {
306
+ this._styles[size]["align-self"] = "stretch";
307
+ }
308
+
303
309
  // Handle scroll properties
304
310
  const scrollHorizontal = this.hasAttribute(addSizePrefix("sh"));
305
311
  const scrollVertical = this.hasAttribute(addSizePrefix("sv"));