radiant-docs 0.1.48 → 0.1.50
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 +1 -1
- package/template/src/components/LogoLink.astro +2 -2
- package/template/src/components/SidebarGroup.astro +1 -1
- package/template/src/components/SidebarLink.astro +3 -3
- package/template/src/components/SidebarSubgroup.astro +1 -1
- package/template/src/components/endpoint/RequestSnippets.astro +30 -12
- package/template/src/components/endpoint/ResponseDisplay.astro +8 -9
- package/template/src/components/endpoint/ResponseSnippets.astro +27 -9
- package/template/src/components/sidebar/SidebarEndpointLink.astro +3 -2
- package/template/src/components/ui/Tag.astro +64 -2
- package/template/src/components/user/Accordion.astro +18 -4
- package/template/src/components/user/CodeBlock.astro +15 -5
- package/template/src/components/user/CodeGroup.astro +28 -11
- package/template/src/components/user/ComponentPreviewBlock.astro +32 -24
- package/template/src/components/user/Image.astro +119 -38
- package/template/src/components/user/Step.astro +2 -2
- package/template/src/components/user/Tabs.astro +59 -27
- package/template/src/lib/validation.ts +120 -8
- package/template/src/styles/global.css +3 -6
|
@@ -60,16 +60,20 @@ const isInitiallyExpanded = shouldShowAllCode || totalLineCount <= visibleLines;
|
|
|
60
60
|
---
|
|
61
61
|
|
|
62
62
|
<div
|
|
63
|
-
class="rd-prose-block rd-component-preview flex w-full max-w-full min-w-0 flex-col"
|
|
63
|
+
class="rd-prose-block rd-component-preview isolate flex w-full max-w-full min-w-0 flex-col"
|
|
64
64
|
data-rd-component-preview-root="true"
|
|
65
65
|
>
|
|
66
66
|
<div
|
|
67
|
-
class="w-full max-w-full min-w-0
|
|
67
|
+
class="relative z-10 w-full max-w-full min-w-0 rounded-t-xl border-[0.5px] border-b-0 border-(--rd-code-tab-edge-border) bg-(--rd-code-surface) p-2"
|
|
68
68
|
>
|
|
69
|
-
<
|
|
69
|
+
<div
|
|
70
|
+
class="bg-white dark:bg-neutral-900/70 rounded-xl border-[0.5px] border-neutral-900/10 dark:border-white/8 p-4 xs:p-6 sm:p-9 sm:px-12 *:first:mt-0! *:last:mb-0! shadow-[0_.5px_1px_rgba(0,0,0,0.15),0_5px_12px_-8px_rgba(0,0,0,0.08)] dark:shadow-[0_-0.5px_1px_rgba(255,255,255,0.1),0_5px_12px_-4px_rgba(0,0,0,0.15)] overflow-x-auto"
|
|
71
|
+
>
|
|
72
|
+
<slot />
|
|
73
|
+
</div>
|
|
70
74
|
</div>
|
|
71
75
|
<div
|
|
72
|
-
class="rd-component-preview__code not-prose relative overflow-hidden rounded-b-xl
|
|
76
|
+
class="rd-component-preview__code not-prose relative z-0 overflow-hidden rounded-b-xl"
|
|
73
77
|
data-rd-preview-expanded={isInitiallyExpanded ? "true" : "false"}
|
|
74
78
|
style={{ "--rd-preview-visible-lines": String(visibleLines) }}
|
|
75
79
|
>
|
|
@@ -82,16 +86,19 @@ const isInitiallyExpanded = shouldShowAllCode || totalLineCount <= visibleLines;
|
|
|
82
86
|
hideLanguageIcon={hideLanguageIcon}
|
|
83
87
|
highlightedLines={highlightedLines}
|
|
84
88
|
collapsedLines={collapsedLines}
|
|
89
|
+
flushTop
|
|
85
90
|
/>
|
|
86
91
|
<div
|
|
87
|
-
class="rd-component-preview__overlay pointer-events-none absolute inset-
|
|
92
|
+
class="rd-component-preview__overlay pointer-events-none absolute inset-0 hidden items-end justify-center rounded-b-xl pb-4"
|
|
88
93
|
data-rd-preview-overlay
|
|
89
94
|
aria-hidden="true"
|
|
90
95
|
>
|
|
91
|
-
<div
|
|
96
|
+
<div
|
|
97
|
+
class="bg-white dark:bg-neutral-800 rounded-xl [corner-shape:superellipse(1.2)]"
|
|
98
|
+
>
|
|
92
99
|
<button
|
|
93
100
|
type="button"
|
|
94
|
-
class="pointer-events-auto inline-flex h-8 items-center justify-center rounded-
|
|
101
|
+
class="pointer-events-auto inline-flex h-8 items-center justify-center rounded-xl [corner-shape:superellipse(1.2)] border-[0.5px] border-neutral-900/10 dark:border-white/8 bg-linear-to-br from-white via-white/10 to-neutral-900/5 dark:from-white/7 dark:via-white/6 dark:to-white/2 px-3 text-sm font-medium text-neutral-600 hover:text-neutral-900 dark:text-neutral-300/90 hover:dark:text-neutral-200 transition-colors duration-200 hover:bg-neutral-50/80 cursor-pointer dark:hover:bg-neutral-700/30 shadow-[0_.5px_1px_rgba(0,0,0,0.15),0_5px_12px_-4px_rgba(0,0,0,0.08)] dark:shadow-[0_-0.5px_0px_rgba(255,255,255,0.15),0_5px_12px_-4px_rgba(0,0,0,0.18)]"
|
|
95
102
|
data-rd-preview-expand
|
|
96
103
|
>
|
|
97
104
|
View code
|
|
@@ -174,36 +181,37 @@ const isInitiallyExpanded = shouldShowAllCode || totalLineCount <= visibleLines;
|
|
|
174
181
|
.rd-component-preview__code[data-rd-preview-expanded="false"]
|
|
175
182
|
.rd-component-preview__overlay {
|
|
176
183
|
display: flex;
|
|
177
|
-
background: linear-gradient(
|
|
178
|
-
to top,
|
|
179
|
-
rgb(250 250 250 / 90%),
|
|
180
|
-
rgb(250 250 250 / 30%)
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
:global(.dark)
|
|
185
|
-
.rd-component-preview__code[data-rd-preview-expanded="false"]
|
|
186
|
-
.rd-component-preview__overlay {
|
|
187
|
-
background: linear-gradient(
|
|
188
|
-
to top,
|
|
189
|
-
color-mix(in srgb, var(--rd-code-surface) 90%, transparent),
|
|
190
|
-
color-mix(in srgb, var(--rd-code-surface) 35%, transparent)
|
|
191
|
-
);
|
|
192
184
|
}
|
|
193
185
|
|
|
194
186
|
.rd-component-preview__code :global([data-rd-code-scroll-area]) {
|
|
195
187
|
overflow-y: hidden;
|
|
196
|
-
transition:
|
|
188
|
+
transition:
|
|
189
|
+
max-height 280ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
190
|
+
mask-image 180ms ease-out;
|
|
197
191
|
}
|
|
198
192
|
|
|
199
193
|
.rd-component-preview__code[data-rd-preview-expanded="false"]
|
|
200
194
|
:global([data-rd-code-scroll-area]) {
|
|
201
|
-
max-height: calc(var(--rd-preview-visible-lines, 5) * 1.5rem +
|
|
195
|
+
max-height: calc(var(--rd-preview-visible-lines, 5) * 1.5rem + 0.75rem);
|
|
196
|
+
-webkit-mask-image: linear-gradient(
|
|
197
|
+
to bottom,
|
|
198
|
+
rgb(0 0 0 / 80%) 0%,
|
|
199
|
+
rgb(0 0 0 / 32%) 82%,
|
|
200
|
+
transparent 110%
|
|
201
|
+
);
|
|
202
|
+
mask-image: linear-gradient(
|
|
203
|
+
to bottom,
|
|
204
|
+
rgb(0 0 0 / 80%) 0%,
|
|
205
|
+
rgb(0 0 0 / 32%) 82%,
|
|
206
|
+
transparent 110%
|
|
207
|
+
);
|
|
202
208
|
}
|
|
203
209
|
|
|
204
210
|
.rd-component-preview__code[data-rd-preview-expanded="true"]
|
|
205
211
|
:global([data-rd-code-scroll-area]) {
|
|
206
212
|
max-height: var(--rd-preview-expanded-height, 200rem);
|
|
213
|
+
-webkit-mask-image: none;
|
|
214
|
+
mask-image: none;
|
|
207
215
|
}
|
|
208
216
|
</style>
|
|
209
217
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { validateNoUnknownProps, validateProps } from "../../lib/component-error";
|
|
3
|
-
import { renderMarkdown } from "../../lib/utils";
|
|
4
3
|
import { resolveStaticAssetUrl } from "../../lib/static-asset-url";
|
|
5
4
|
|
|
6
5
|
interface Props {
|
|
7
|
-
src: string;
|
|
6
|
+
src: string | { light?: string; dark?: string };
|
|
8
7
|
alt?: string;
|
|
9
8
|
title?: string;
|
|
10
9
|
width?: number | string;
|
|
@@ -24,7 +23,7 @@ validateProps(
|
|
|
24
23
|
"Image",
|
|
25
24
|
imageProps,
|
|
26
25
|
{
|
|
27
|
-
src: { required: true, type: "string" },
|
|
26
|
+
src: { required: true, type: ["string", "object"] },
|
|
28
27
|
alt: { type: "string" },
|
|
29
28
|
title: { type: "string" },
|
|
30
29
|
width: { type: ["number", "string"] },
|
|
@@ -35,17 +34,51 @@ validateProps(
|
|
|
35
34
|
|
|
36
35
|
const { src, alt, title, width, zoom = true } = imageProps as Props;
|
|
37
36
|
const zoomEnabled = zoom !== false;
|
|
38
|
-
const resolvedSrc = resolveStaticAssetUrl(src);
|
|
39
37
|
const rawWidth = width;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
|
|
39
|
+
function normalizeImageSource(value: Props["src"]): {
|
|
40
|
+
light: string;
|
|
41
|
+
dark?: string;
|
|
42
|
+
} {
|
|
43
|
+
if (typeof value === "string") {
|
|
44
|
+
return { light: value };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const light = typeof value.light === "string" ? value.light : "";
|
|
48
|
+
const dark = typeof value.dark === "string" ? value.dark : undefined;
|
|
49
|
+
|
|
50
|
+
return { light, dark };
|
|
43
51
|
}
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
|
|
53
|
+
const normalizedSource = normalizeImageSource(src);
|
|
54
|
+
if (!normalizedSource.light.trim()) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
`[USER_ERROR]: <Image>: Invalid prop "src": object form requires a non-empty "light" string (in ${Astro.url.pathname})`,
|
|
57
|
+
);
|
|
46
58
|
}
|
|
47
59
|
|
|
48
|
-
const
|
|
60
|
+
const resolvedLightSrc = resolveStaticAssetUrl(normalizedSource.light);
|
|
61
|
+
const resolvedDarkSrc =
|
|
62
|
+
typeof normalizedSource.dark === "string" && normalizedSource.dark.trim()
|
|
63
|
+
? resolveStaticAssetUrl(normalizedSource.dark)
|
|
64
|
+
: undefined;
|
|
65
|
+
const hasDarkSource =
|
|
66
|
+
typeof resolvedDarkSrc === "string" && resolvedDarkSrc !== resolvedLightSrc;
|
|
67
|
+
|
|
68
|
+
function createImageAttrs(source: string): Record<string, unknown> {
|
|
69
|
+
const attrs: Record<string, unknown> = { src: source };
|
|
70
|
+
if (typeof alt === "string") {
|
|
71
|
+
attrs.alt = alt;
|
|
72
|
+
}
|
|
73
|
+
if (width !== undefined) {
|
|
74
|
+
attrs.width = width;
|
|
75
|
+
}
|
|
76
|
+
return attrs;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const lightImageAttrs = createImageAttrs(resolvedLightSrc);
|
|
80
|
+
const darkImageAttrs = hasDarkSource ? createImageAttrs(resolvedDarkSrc!) : null;
|
|
81
|
+
const zoomAttrs: Record<string, unknown> = { src: resolvedLightSrc };
|
|
49
82
|
if (typeof alt === "string") {
|
|
50
83
|
zoomAttrs.alt = alt;
|
|
51
84
|
}
|
|
@@ -81,17 +114,33 @@ function isConstrainedWidthValue(value: unknown): boolean {
|
|
|
81
114
|
return true;
|
|
82
115
|
}
|
|
83
116
|
|
|
117
|
+
function toCssWidthValue(value: unknown): string | undefined {
|
|
118
|
+
if (typeof value === "number") {
|
|
119
|
+
if (!Number.isFinite(value) || value <= 0) return undefined;
|
|
120
|
+
return `${value}px`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (typeof value !== "string") return undefined;
|
|
124
|
+
const normalized = value.trim();
|
|
125
|
+
if (!normalized) return undefined;
|
|
126
|
+
|
|
127
|
+
return /^-?\d*\.?\d+$/.test(normalized) ? `${normalized}px` : normalized;
|
|
128
|
+
}
|
|
129
|
+
|
|
84
130
|
const hasCustomImageWidth = isConstrainedWidthValue(rawWidth);
|
|
131
|
+
const contentWidthStyle = hasCustomImageWidth
|
|
132
|
+
? `width: ${toCssWidthValue(rawWidth) ?? "auto"};`
|
|
133
|
+
: undefined;
|
|
85
134
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
135
|
+
const slotCaptionHtml = Astro.slots.has("default")
|
|
136
|
+
? (await Astro.slots.render("default")).trim()
|
|
137
|
+
: "";
|
|
138
|
+
const hasCaption = slotCaptionHtml.length > 0;
|
|
90
139
|
---
|
|
91
140
|
|
|
92
141
|
<figure
|
|
93
142
|
class:list={[
|
|
94
|
-
"rd-prose-block p-1.5 pb-1 xs:pb-1.5 group border border-neutral-
|
|
143
|
+
"rd-prose-block p-1.5 pb-1 xs:pb-1.5 group border-[0.5px] border-neutral-900/8 dark:border-white/6 bg-(--rd-code-surface) rounded-2xl shadow-[0_.5px_1px_rgba(0,0,0,0.15),0_5px_12px_-8px_rgba(0,0,0,0.08)] dark:shadow-[0_-.5px_1px_rgba(255,255,255,0.15),0_5px_12px_-8px_rgba(0,0,0,0.2)]",
|
|
95
144
|
hasCustomImageWidth ? "w-fit max-w-full mx-auto" : "w-full",
|
|
96
145
|
]}
|
|
97
146
|
x-data="{
|
|
@@ -102,8 +151,16 @@ const captionHtml =
|
|
|
102
151
|
style: 'visibility: hidden;',
|
|
103
152
|
fullShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
|
104
153
|
noShadow: '0 0 0 rgba(0, 0, 0, 0)',
|
|
154
|
+
zoomSrc: '',
|
|
155
|
+
activeImage() {
|
|
156
|
+
const darkImg = this.$refs.darkImg;
|
|
157
|
+
if (darkImg && window.getComputedStyle(darkImg).display !== 'none') {
|
|
158
|
+
return darkImg;
|
|
159
|
+
}
|
|
160
|
+
return this.$refs.lightImg;
|
|
161
|
+
},
|
|
105
162
|
computeZoomSize() {
|
|
106
|
-
const img = this
|
|
163
|
+
const img = this.activeImage();
|
|
107
164
|
const zoomContainer = this.$refs.zoomViewport;
|
|
108
165
|
if (!img || !zoomContainer) {
|
|
109
166
|
this.zoomSize = `width: min(92vw, ${this.zoomMaxWidth}px);`;
|
|
@@ -138,9 +195,12 @@ const captionHtml =
|
|
|
138
195
|
return this.zoomSize;
|
|
139
196
|
},
|
|
140
197
|
async zoom() {
|
|
198
|
+
const img = this.activeImage();
|
|
199
|
+
if (!img) return;
|
|
141
200
|
// 1. Lock scroll and measure
|
|
142
201
|
document.body.style.overflow = 'hidden';
|
|
143
|
-
|
|
202
|
+
this.zoomSrc = img.currentSrc || img.src;
|
|
203
|
+
const rect = img.getBoundingClientRect();
|
|
144
204
|
|
|
145
205
|
// 2. Prepare the zoomed image (hidden but in DOM)
|
|
146
206
|
this.style = 'opacity: 0; transition: none;';
|
|
@@ -176,7 +236,9 @@ const captionHtml =
|
|
|
176
236
|
},
|
|
177
237
|
close() {
|
|
178
238
|
document.body.style.overflow = 'auto';
|
|
179
|
-
const
|
|
239
|
+
const img = this.activeImage();
|
|
240
|
+
if (!img) return;
|
|
241
|
+
const rect = img.getBoundingClientRect();
|
|
180
242
|
const zRect = this.$refs.zoomedImg.getBoundingClientRect();
|
|
181
243
|
|
|
182
244
|
const scale = rect.width / zRect.width;
|
|
@@ -194,28 +256,46 @@ const captionHtml =
|
|
|
194
256
|
}"
|
|
195
257
|
>
|
|
196
258
|
<div
|
|
197
|
-
class="
|
|
259
|
+
class:list={["max-w-full", !hasCustomImageWidth && "w-full"]}
|
|
260
|
+
style={contentWidthStyle}
|
|
198
261
|
>
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
262
|
+
<div class="overflow-hidden rounded-[11px]">
|
|
263
|
+
<img
|
|
264
|
+
{...lightImageAttrs}
|
|
265
|
+
x-ref="lightImg"
|
|
266
|
+
title={title}
|
|
267
|
+
class:list={[
|
|
268
|
+
"h-auto my-0! block w-full transition-opacity",
|
|
269
|
+
hasDarkSource && "dark:hidden",
|
|
270
|
+
zoomEnabled && "cursor-zoom-in",
|
|
271
|
+
]}
|
|
272
|
+
:class="showZoomed ? 'opacity-0 duration-0' : 'opacity-100 duration-300'"
|
|
273
|
+
@click={zoomEnabled ? "zoom()" : undefined}
|
|
274
|
+
/>
|
|
275
|
+
{
|
|
276
|
+
darkImageAttrs && (
|
|
277
|
+
<img
|
|
278
|
+
{...darkImageAttrs}
|
|
279
|
+
x-ref="darkImg"
|
|
280
|
+
title={title}
|
|
281
|
+
class:list={[
|
|
282
|
+
"h-auto my-0! hidden w-full transition-opacity dark:block",
|
|
283
|
+
zoomEnabled && "cursor-zoom-in",
|
|
284
|
+
]}
|
|
285
|
+
:class="showZoomed ? 'opacity-0 duration-0' : 'opacity-100 duration-300'"
|
|
286
|
+
@click={zoomEnabled ? "zoom()" : undefined}
|
|
287
|
+
/>
|
|
288
|
+
)
|
|
289
|
+
}
|
|
290
|
+
</div>
|
|
291
|
+
{
|
|
292
|
+
hasCaption && (
|
|
293
|
+
<figcaption class="prose-rules mt-1! xs:mt-1.5! max-w-none! *:max-w-none! text-center text-xs! xs:text-sm! text-neutral-500 dark:text-neutral-400 leading-relaxed px-2">
|
|
294
|
+
<Fragment set:html={slotCaptionHtml} />
|
|
295
|
+
</figcaption>
|
|
296
|
+
)
|
|
297
|
+
}
|
|
211
298
|
</div>
|
|
212
|
-
{
|
|
213
|
-
title && (
|
|
214
|
-
<figcaption class="mt-1! xs:mt-1.5! text-center text-xs! xs:text-sm! text-neutral-500 dark:text-neutral-400 font-medium whitespace-pre-line leading-relaxed px-2">
|
|
215
|
-
<span set:html={captionHtml} />
|
|
216
|
-
</figcaption>
|
|
217
|
-
)
|
|
218
|
-
}
|
|
219
299
|
|
|
220
300
|
{
|
|
221
301
|
zoomEnabled && (
|
|
@@ -243,6 +323,7 @@ const captionHtml =
|
|
|
243
323
|
<img
|
|
244
324
|
{...zoomAttrs}
|
|
245
325
|
x-ref="zoomedImg"
|
|
326
|
+
:src="zoomSrc || $el.getAttribute('src')"
|
|
246
327
|
class="relative z-10 max-w-full max-h-full object-contain rounded-2xl shadow-none will-change-transform pointer-events-none"
|
|
247
328
|
:style="style"
|
|
248
329
|
/>
|
|
@@ -21,14 +21,14 @@ validateProps(
|
|
|
21
21
|
<div
|
|
22
22
|
class:list={[
|
|
23
23
|
"relative pl-10 step-item pb-4 last:pb-0 space-y-4",
|
|
24
|
-
"before:absolute before:left-[
|
|
24
|
+
"before:mask-b-from-90% before:absolute before:left-[13.25px] before:top-[28px] before:bottom-0 before:w-[1.5px] before:bg-neutral-900/8 dark:before:bg-neutral-50/8",
|
|
25
25
|
]}
|
|
26
26
|
data-step-panel
|
|
27
27
|
>
|
|
28
28
|
<div
|
|
29
29
|
class:list={[
|
|
30
30
|
"flex items-center gap-1.5 not-prose",
|
|
31
|
-
"step-number before:
|
|
31
|
+
"step-number before:leading-none before:size-7 before:bg-neutral-900/6 dark:before:bg-neutral-50/6 before:rounded-full before:text-neutral-700 dark:before:text-neutral-100 before:flex before:items-center before:justify-center before:text-[13px] before:font-medium before:absolute before:left-0 before:top-0",
|
|
32
32
|
]}
|
|
33
33
|
>
|
|
34
34
|
<h3 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100">
|
|
@@ -30,12 +30,33 @@ if (labels.length === 0) {
|
|
|
30
30
|
previousTab: null,
|
|
31
31
|
transitionDirection: 1,
|
|
32
32
|
isTransitioning: false,
|
|
33
|
-
transitionDurationMs:
|
|
33
|
+
transitionDurationMs: 400,
|
|
34
|
+
transitionEasing: 'cubic-bezier(0.22, 1, 0.36, 1)',
|
|
34
35
|
transitionTimeout: null,
|
|
35
36
|
containerHeight: 'auto',
|
|
36
37
|
markerStyle: { left: null, width: null },
|
|
37
38
|
resizeHandler: null,
|
|
39
|
+
readMotionTokens() {
|
|
40
|
+
const styles = window.getComputedStyle(document.documentElement);
|
|
41
|
+
const configuredDurationMs = Number.parseFloat(
|
|
42
|
+
styles.getPropertyValue('--rd-panel-transition-duration-ms'),
|
|
43
|
+
);
|
|
44
|
+
this.transitionDurationMs = Number.isFinite(configuredDurationMs)
|
|
45
|
+
? configuredDurationMs
|
|
46
|
+
: this.transitionDurationMs;
|
|
47
|
+
this.transitionEasing =
|
|
48
|
+
styles.getPropertyValue('--rd-panel-transition-easing').trim() ||
|
|
49
|
+
this.transitionEasing;
|
|
50
|
+
|
|
51
|
+
if (
|
|
52
|
+
typeof window.matchMedia === 'function' &&
|
|
53
|
+
window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
54
|
+
) {
|
|
55
|
+
this.transitionDurationMs = 0;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
38
58
|
init() {
|
|
59
|
+
this.readMotionTokens();
|
|
39
60
|
this.resizeHandler = () => {
|
|
40
61
|
this.updateMarker(this.activeTab);
|
|
41
62
|
this.updateHeight(this.isTransitioning);
|
|
@@ -68,7 +89,7 @@ if (labels.length === 0) {
|
|
|
68
89
|
this.isTransitioning = true;
|
|
69
90
|
this.activeTab = index;
|
|
70
91
|
this.updateMarker(this.activeTab);
|
|
71
|
-
this.updateHeight(
|
|
92
|
+
this.updateHeight();
|
|
72
93
|
|
|
73
94
|
this.transitionTimeout = window.setTimeout(() => {
|
|
74
95
|
this.isTransitioning = false;
|
|
@@ -87,7 +108,7 @@ if (labels.length === 0) {
|
|
|
87
108
|
}
|
|
88
109
|
},
|
|
89
110
|
getPanelStyle(index) {
|
|
90
|
-
const base = 'position: absolute;
|
|
111
|
+
const base = 'position: absolute; top: 0; left: 0; right: 0; width: 100%;';
|
|
91
112
|
|
|
92
113
|
const isActive = index === this.activeTab;
|
|
93
114
|
const isPrevious = this.isTransitioning && index === this.previousTab;
|
|
@@ -105,29 +126,23 @@ if (labels.length === 0) {
|
|
|
105
126
|
this.transitionDirection === 1
|
|
106
127
|
? 'rd-tabs-slide-in-from-right'
|
|
107
128
|
: 'rd-tabs-slide-in-from-left';
|
|
108
|
-
return `${base} opacity: 1; pointer-events: auto; visibility: visible; z-index: 2; animation: ${animationName} ${this.transitionDurationMs}ms
|
|
129
|
+
return `${base} opacity: 1; pointer-events: auto; visibility: visible; z-index: 2; animation: ${animationName} ${this.transitionDurationMs}ms ${this.transitionEasing} both;`;
|
|
109
130
|
}
|
|
110
131
|
|
|
111
132
|
const animationName =
|
|
112
133
|
this.transitionDirection === 1
|
|
113
134
|
? 'rd-tabs-slide-out-to-left'
|
|
114
135
|
: 'rd-tabs-slide-out-to-right';
|
|
115
|
-
return `${base} opacity: 1; pointer-events: none; visibility: visible; z-index: 1; animation: ${animationName} ${this.transitionDurationMs}ms
|
|
136
|
+
return `${base} opacity: 1; pointer-events: none; visibility: visible; z-index: 1; animation: ${animationName} ${this.transitionDurationMs}ms ${this.transitionEasing} both;`;
|
|
116
137
|
},
|
|
117
|
-
updateHeight(
|
|
138
|
+
updateHeight() {
|
|
118
139
|
this.$nextTick(() => {
|
|
119
140
|
const activeSlide = this.$refs['content-' + this.activeTab];
|
|
120
141
|
if (!activeSlide) return;
|
|
142
|
+
const activeContent = activeSlide.querySelector('[data-rd-tabs-panel-content]');
|
|
143
|
+
const measuredElement = activeContent || activeSlide;
|
|
121
144
|
|
|
122
|
-
|
|
123
|
-
if (includePrevious && this.previousTab !== null) {
|
|
124
|
-
const previousSlide = this.$refs['content-' + this.previousTab];
|
|
125
|
-
if (previousSlide) {
|
|
126
|
-
nextHeight = Math.max(nextHeight, previousSlide.scrollHeight);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
this.containerHeight = nextHeight + 'px';
|
|
145
|
+
this.containerHeight = measuredElement.scrollHeight + 'px';
|
|
131
146
|
});
|
|
132
147
|
}
|
|
133
148
|
}"
|
|
@@ -167,19 +182,28 @@ class="rd-prose-block">
|
|
|
167
182
|
</ul>
|
|
168
183
|
|
|
169
184
|
<div
|
|
170
|
-
class="relative mt-4 overflow-
|
|
171
|
-
:style="'height: ' + containerHeight"
|
|
185
|
+
class="relative mt-4 overflow-visible transition-[height] motion-reduce:transition-none"
|
|
186
|
+
:style="'height: ' + containerHeight + '; transition-duration: ' + transitionDurationMs + 'ms; transition-timing-function: ' + transitionEasing + ';'"
|
|
172
187
|
>
|
|
173
|
-
|
|
174
|
-
<div
|
|
175
|
-
{
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
188
|
+
<div class="relative -mx-4 h-full overflow-x-clip overflow-y-visible">
|
|
189
|
+
<div class="relative mx-4 h-full">
|
|
190
|
+
{ tabContents.map((content, index) => (
|
|
191
|
+
<div
|
|
192
|
+
{...(index !== 0 ? { "x-cloak": true } : {})}
|
|
193
|
+
x-ref={`content-${index}`}
|
|
194
|
+
class="w-full"
|
|
195
|
+
:style={`getPanelStyle(${index})`}
|
|
196
|
+
style={index === 0 ? 'position: relative;' : ''}
|
|
197
|
+
>
|
|
198
|
+
<div
|
|
199
|
+
data-rd-tabs-panel-content
|
|
200
|
+
class="prose-rules w-full max-w-none! *:max-w-none!"
|
|
201
|
+
set:html={content}
|
|
202
|
+
/>
|
|
203
|
+
</div>
|
|
204
|
+
)) }
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
183
207
|
</div>
|
|
184
208
|
</div>
|
|
185
209
|
|
|
@@ -187,36 +211,44 @@ class="rd-prose-block">
|
|
|
187
211
|
@keyframes rd-tabs-slide-in-from-right {
|
|
188
212
|
from {
|
|
189
213
|
transform: translateX(100%);
|
|
214
|
+
opacity: 0;
|
|
190
215
|
}
|
|
191
216
|
to {
|
|
192
217
|
transform: translateX(0);
|
|
218
|
+
opacity: 1;
|
|
193
219
|
}
|
|
194
220
|
}
|
|
195
221
|
|
|
196
222
|
@keyframes rd-tabs-slide-in-from-left {
|
|
197
223
|
from {
|
|
198
224
|
transform: translateX(-100%);
|
|
225
|
+
opacity: 0;
|
|
199
226
|
}
|
|
200
227
|
to {
|
|
201
228
|
transform: translateX(0);
|
|
229
|
+
opacity: 1;
|
|
202
230
|
}
|
|
203
231
|
}
|
|
204
232
|
|
|
205
233
|
@keyframes rd-tabs-slide-out-to-left {
|
|
206
234
|
from {
|
|
207
235
|
transform: translateX(0);
|
|
236
|
+
opacity: 1;
|
|
208
237
|
}
|
|
209
238
|
to {
|
|
210
239
|
transform: translateX(-100%);
|
|
240
|
+
opacity: 0;
|
|
211
241
|
}
|
|
212
242
|
}
|
|
213
243
|
|
|
214
244
|
@keyframes rd-tabs-slide-out-to-right {
|
|
215
245
|
from {
|
|
216
246
|
transform: translateX(0);
|
|
247
|
+
opacity: 1;
|
|
217
248
|
}
|
|
218
249
|
to {
|
|
219
250
|
transform: translateX(100%);
|
|
251
|
+
opacity: 0;
|
|
220
252
|
}
|
|
221
253
|
}
|
|
222
254
|
</style>
|