radiant-docs 0.1.20 → 0.1.21

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": "radiant-docs",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "CLI tool for previewing Radiant documentation locally",
5
5
  "type": "module",
6
6
  "bin": {
@@ -56,170 +56,169 @@ import CodeTabEdge from "../ui/CodeTabEdge.astro";
56
56
  <div data-rd-code-group-content class="min-w-0">
57
57
  <slot />
58
58
  </div>
59
- </div>
60
-
61
- <script is:inline>
62
- (() => {
63
- const script = document.currentScript;
64
- if (!(script instanceof HTMLScriptElement)) return;
59
+ <script is:inline>
60
+ (() => {
61
+ const script = document.currentScript;
62
+ if (!(script instanceof HTMLScriptElement)) return;
65
63
 
66
- const root = script.previousElementSibling;
67
- if (!(root instanceof HTMLElement)) return;
64
+ const root = script.closest("[data-rd-code-group-root='true']");
65
+ if (!(root instanceof HTMLElement)) return;
68
66
 
69
- const contentElement = root.querySelector("[data-rd-code-group-content]");
70
- const tabsElement = root.querySelector("[data-rd-code-group-tabs]");
71
- const pillElement = root.querySelector("[data-rd-code-group-pill]");
72
- const copyButton = root.querySelector("[data-rd-copy-trigger='true']");
67
+ const contentElement = root.querySelector("[data-rd-code-group-content]");
68
+ const tabsElement = root.querySelector("[data-rd-code-group-tabs]");
69
+ const pillElement = root.querySelector("[data-rd-code-group-pill]");
70
+ const copyButton = root.querySelector("[data-rd-copy-trigger='true']");
73
71
 
74
- if (!contentElement || !tabsElement || !pillElement) return;
72
+ if (!contentElement || !tabsElement || !pillElement) return;
75
73
 
76
- const codeItems = Array.from(
77
- contentElement.querySelectorAll("[data-rd-code-group-item='true']"),
78
- );
79
- if (codeItems.length === 0) return;
74
+ const codeItems = Array.from(
75
+ contentElement.querySelectorAll("[data-rd-code-group-item='true']"),
76
+ );
77
+ if (codeItems.length === 0) return;
80
78
 
81
- let activeIndex = 0;
79
+ let activeIndex = 0;
82
80
 
83
- const setCopiedState = (button, copied) => {
84
- const copyIcon = button.querySelector("[data-rd-copy-icon]");
85
- const checkIcon = button.querySelector("[data-rd-copy-check]");
86
- if (!copyIcon || !checkIcon) return;
81
+ const setCopiedState = (button, copied) => {
82
+ const copyIcon = button.querySelector("[data-rd-copy-icon]");
83
+ const checkIcon = button.querySelector("[data-rd-copy-check]");
84
+ if (!copyIcon || !checkIcon) return;
87
85
 
88
- if (copied) {
89
- copyIcon.classList.add("scale-50", "opacity-0", "-rotate-6");
90
- copyIcon.classList.remove("scale-100", "opacity-100", "rotate-0");
86
+ if (copied) {
87
+ copyIcon.classList.add("scale-50", "opacity-0", "-rotate-6");
88
+ copyIcon.classList.remove("scale-100", "opacity-100", "rotate-0");
91
89
 
92
- checkIcon.classList.remove("scale-50", "opacity-0", "rotate-6");
93
- checkIcon.classList.add("scale-110", "opacity-100", "rotate-0");
94
- return;
95
- }
90
+ checkIcon.classList.remove("scale-50", "opacity-0", "rotate-6");
91
+ checkIcon.classList.add("scale-110", "opacity-100", "rotate-0");
92
+ return;
93
+ }
96
94
 
97
- copyIcon.classList.remove("scale-50", "opacity-0", "-rotate-6");
98
- copyIcon.classList.add("scale-100", "opacity-100", "rotate-0");
95
+ copyIcon.classList.remove("scale-50", "opacity-0", "-rotate-6");
96
+ copyIcon.classList.add("scale-100", "opacity-100", "rotate-0");
99
97
 
100
- checkIcon.classList.remove("scale-110", "opacity-100", "rotate-0");
101
- checkIcon.classList.add("scale-50", "opacity-0", "rotate-6");
102
- };
98
+ checkIcon.classList.remove("scale-110", "opacity-100", "rotate-0");
99
+ checkIcon.classList.add("scale-50", "opacity-0", "rotate-6");
100
+ };
103
101
 
104
- const tabs = codeItems.map((itemElement, index) => {
105
- const filename =
106
- itemElement.getAttribute("data-rd-tab-filename") ??
107
- `file-name-${index + 1}.txt`;
108
- const tabIconTemplate = itemElement.querySelector(
109
- "template[data-rd-code-group-tab-icon]",
110
- );
102
+ const tabs = codeItems.map((itemElement, index) => {
103
+ const filename =
104
+ itemElement.getAttribute("data-rd-tab-filename") ??
105
+ `file-name-${index + 1}.txt`;
106
+ const tabIconTemplate = itemElement.querySelector(
107
+ "template[data-rd-code-group-tab-icon]",
108
+ );
109
+
110
+ const tabWrapper = document.createElement("div");
111
+ tabWrapper.className = "relative z-10 text-xs font-medium";
112
+
113
+ const tabButton = document.createElement("button");
114
+ tabButton.type = "button";
115
+ tabButton.className =
116
+ "relative inline-flex h-9 items-center gap-2 border-0 bg-transparent px-3 py-1.5 text-xs font-medium text-neutral-600 transition-colors duration-150 focus:outline-none focus-visible:outline-none cursor-pointer";
117
+ tabButton.setAttribute("aria-label", filename);
118
+ tabButton.setAttribute("data-rd-code-group-tab", String(index));
119
+
120
+ const iconContainer = document.createElement("span");
121
+ iconContainer.className =
122
+ "pointer-events-none inline-flex shrink-0 items-center rounded-[4px] transition-opacity duration-150";
123
+
124
+ if (tabIconTemplate && tabIconTemplate.innerHTML.trim().length > 0) {
125
+ iconContainer.innerHTML = tabIconTemplate.innerHTML;
126
+ } else {
127
+ iconContainer.classList.add("hidden");
128
+ }
111
129
 
112
- const tabWrapper = document.createElement("div");
113
- tabWrapper.className = "relative z-10 text-xs font-medium";
130
+ const labelElement = document.createElement("span");
131
+ labelElement.className = "whitespace-pre leading-none";
132
+ labelElement.textContent = filename;
133
+
134
+ tabButton.appendChild(iconContainer);
135
+ tabButton.appendChild(labelElement);
136
+ tabWrapper.appendChild(tabButton);
137
+ tabsElement.appendChild(tabWrapper);
138
+
139
+ return {
140
+ itemElement,
141
+ tabWrapper,
142
+ tabButton,
143
+ iconContainer,
144
+ };
145
+ });
114
146
 
115
- const tabButton = document.createElement("button");
116
- tabButton.type = "button";
117
- tabButton.className =
118
- "relative inline-flex h-9 items-center gap-2 border-0 bg-transparent px-3 py-1.5 text-xs font-medium text-neutral-600 transition-colors duration-150 focus:outline-none focus-visible:outline-none cursor-pointer";
119
- tabButton.setAttribute("aria-label", filename);
120
- tabButton.setAttribute("data-rd-code-group-tab", String(index));
147
+ const syncPill = () => {
148
+ const activeTab = tabs[activeIndex]?.tabWrapper;
149
+ if (!activeTab) {
150
+ pillElement.classList.add("opacity-0");
151
+ pillElement.classList.remove("opacity-100");
152
+ return;
153
+ }
121
154
 
122
- const iconContainer = document.createElement("span");
123
- iconContainer.className =
124
- "pointer-events-none inline-flex shrink-0 items-center rounded-[4px] transition-opacity duration-150";
155
+ const activeRect = activeTab.getBoundingClientRect();
156
+ const tabsRect = tabsElement.getBoundingClientRect();
157
+ const left = activeRect.left - tabsRect.left + tabsElement.scrollLeft;
158
+ const width = activeRect.width;
159
+ pillElement.style.left = `${left}px`;
160
+ pillElement.style.width = `${width}px`;
161
+ pillElement.classList.remove("opacity-0");
162
+ pillElement.classList.add("opacity-100");
163
+ };
125
164
 
126
- if (tabIconTemplate && tabIconTemplate.innerHTML.trim().length > 0) {
127
- iconContainer.innerHTML = tabIconTemplate.innerHTML;
128
- } else {
129
- iconContainer.classList.add("hidden");
130
- }
165
+ const syncActiveTab = () => {
166
+ tabs.forEach(({ itemElement, tabButton, iconContainer }, index) => {
167
+ const isActive = index === activeIndex;
168
+ itemElement.style.display = isActive ? "" : "none";
169
+ tabButton.classList.toggle("text-neutral-900", isActive);
170
+ tabButton.classList.toggle("text-neutral-600", !isActive);
171
+
172
+ if (iconContainer.classList.contains("hidden")) return;
173
+ iconContainer.classList.toggle("opacity-100", isActive);
174
+ iconContainer.classList.toggle("opacity-80", !isActive);
175
+ });
176
+ syncPill();
177
+ };
131
178
 
132
- const labelElement = document.createElement("span");
133
- labelElement.className = "whitespace-pre leading-none";
134
- labelElement.textContent = filename;
179
+ tabs.forEach(({ tabButton }, index) => {
180
+ tabButton.addEventListener("click", () => {
181
+ if (activeIndex === index) return;
182
+ activeIndex = index;
183
+ syncActiveTab();
184
+ });
185
+ });
135
186
 
136
- tabButton.appendChild(iconContainer);
137
- tabButton.appendChild(labelElement);
138
- tabWrapper.appendChild(tabButton);
139
- tabsElement.appendChild(tabWrapper);
187
+ if (copyButton) {
188
+ let timeoutId = null;
189
+ copyButton.addEventListener("click", async () => {
190
+ const activeItem = tabs[activeIndex]?.itemElement;
191
+ const encodedCopyValue =
192
+ activeItem?.getAttribute("data-rd-copy-content") ?? "";
193
+ const copyValue = decodeURIComponent(encodedCopyValue);
194
+
195
+ try {
196
+ await navigator.clipboard.writeText(copyValue);
197
+ setCopiedState(copyButton, true);
198
+
199
+ if (timeoutId) window.clearTimeout(timeoutId);
200
+ timeoutId = window.setTimeout(() => {
201
+ setCopiedState(copyButton, false);
202
+ timeoutId = null;
203
+ }, 1200);
204
+ } catch {
205
+ setCopiedState(copyButton, false);
206
+ }
207
+ });
208
+ }
140
209
 
141
- return {
142
- itemElement,
143
- tabWrapper,
144
- tabButton,
145
- iconContainer,
146
- };
147
- });
148
-
149
- const syncPill = () => {
150
- const activeTab = tabs[activeIndex]?.tabWrapper;
151
- if (!activeTab) {
152
- pillElement.classList.add("opacity-0");
153
- pillElement.classList.remove("opacity-100");
154
- return;
210
+ const resizeObserver =
211
+ typeof ResizeObserver !== "undefined"
212
+ ? new ResizeObserver(() => syncPill())
213
+ : null;
214
+ if (resizeObserver) {
215
+ resizeObserver.observe(tabsElement);
155
216
  }
156
217
 
157
- const activeRect = activeTab.getBoundingClientRect();
158
- const tabsRect = tabsElement.getBoundingClientRect();
159
- const left = activeRect.left - tabsRect.left + tabsElement.scrollLeft;
160
- const width = activeRect.width;
161
- pillElement.style.left = `${left}px`;
162
- pillElement.style.width = `${width}px`;
163
- pillElement.classList.remove("opacity-0");
164
- pillElement.classList.add("opacity-100");
165
- };
166
-
167
- const syncActiveTab = () => {
168
- tabs.forEach(({ itemElement, tabButton, iconContainer }, index) => {
169
- const isActive = index === activeIndex;
170
- itemElement.style.display = isActive ? "" : "none";
171
- tabButton.classList.toggle("text-neutral-900", isActive);
172
- tabButton.classList.toggle("text-neutral-600", !isActive);
173
-
174
- if (iconContainer.classList.contains("hidden")) return;
175
- iconContainer.classList.toggle("opacity-100", isActive);
176
- iconContainer.classList.toggle("opacity-80", !isActive);
177
- });
178
- syncPill();
179
- };
180
-
181
- tabs.forEach(({ tabButton }, index) => {
182
- tabButton.addEventListener("click", () => {
183
- if (activeIndex === index) return;
184
- activeIndex = index;
185
- syncActiveTab();
186
- });
187
- });
188
-
189
- if (copyButton) {
190
- let timeoutId = null;
191
- copyButton.addEventListener("click", async () => {
192
- const activeItem = tabs[activeIndex]?.itemElement;
193
- const encodedCopyValue =
194
- activeItem?.getAttribute("data-rd-copy-content") ?? "";
195
- const copyValue = decodeURIComponent(encodedCopyValue);
196
-
197
- try {
198
- await navigator.clipboard.writeText(copyValue);
199
- setCopiedState(copyButton, true);
200
-
201
- if (timeoutId) window.clearTimeout(timeoutId);
202
- timeoutId = window.setTimeout(() => {
203
- setCopiedState(copyButton, false);
204
- timeoutId = null;
205
- }, 1200);
206
- } catch {
207
- setCopiedState(copyButton, false);
208
- }
209
- });
210
- }
211
-
212
- const resizeObserver =
213
- typeof ResizeObserver !== "undefined"
214
- ? new ResizeObserver(() => syncPill())
215
- : null;
216
- if (resizeObserver) {
217
- resizeObserver.observe(tabsElement);
218
- }
219
-
220
- tabsElement.addEventListener("scroll", syncPill, { passive: true });
221
- window.addEventListener("resize", syncPill);
222
- syncActiveTab();
223
- requestAnimationFrame(syncPill);
224
- })();
225
- </script>
218
+ tabsElement.addEventListener("scroll", syncPill, { passive: true });
219
+ window.addEventListener("resize", syncPill);
220
+ syncActiveTab();
221
+ requestAnimationFrame(syncPill);
222
+ })();
223
+ </script>
224
+ </div>