radiant-docs 0.1.46 → 0.1.48

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.46",
3
+ "version": "0.1.48",
4
4
  "description": "CLI tool for previewing Radiant documentation locally",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,6 +17,7 @@
17
17
  "@astrojs/sitemap": "^3.7.2",
18
18
  "@aws-sdk/client-s3": "^3.964.0",
19
19
  "@fontsource/google-sans-flex": "^5.2.2",
20
+ "@iconify-json/fluent": "^1.2.47",
20
21
  "@iconify-json/lucide": "^1.2.79",
21
22
  "@iconify-json/simple-icons": "^1.2.69",
22
23
  "@iconify/react": "^6.0.2",
@@ -1995,6 +1996,15 @@
1995
1996
  "node": ">=10.10.0"
1996
1997
  }
1997
1998
  },
1999
+ "node_modules/@iconify-json/fluent": {
2000
+ "version": "1.2.47",
2001
+ "resolved": "https://registry.npmjs.org/@iconify-json/fluent/-/fluent-1.2.47.tgz",
2002
+ "integrity": "sha512-YA9pCYNW3bqXMD1rMIkK0vqLK90UyE63hfI1cB2sQwGAbEFhi+VUz5mvcXYfb7bl5R8N5sLZNI2Kr0Q3Yo9M4A==",
2003
+ "license": "MIT",
2004
+ "dependencies": {
2005
+ "@iconify/types": "*"
2006
+ }
2007
+ },
1998
2008
  "node_modules/@iconify-json/lucide": {
1999
2009
  "version": "1.2.79",
2000
2010
  "resolved": "https://registry.npmjs.org/@iconify-json/lucide/-/lucide-1.2.79.tgz",
@@ -21,6 +21,7 @@
21
21
  "@astrojs/sitemap": "^3.7.2",
22
22
  "@aws-sdk/client-s3": "^3.964.0",
23
23
  "@fontsource/google-sans-flex": "^5.2.2",
24
+ "@iconify-json/fluent": "^1.2.47",
24
25
  "@iconify-json/lucide": "^1.2.79",
25
26
  "@iconify-json/simple-icons": "^1.2.69",
26
27
  "@iconify/react": "^6.0.2",
@@ -869,7 +869,10 @@ const formattedBodyDescription = bodyDescription
869
869
  data-snippet-stack
870
870
  class="relative flex min-h-0 w-full min-w-0 flex-col gap-6 overflow-hidden"
871
871
  >
872
- <div data-snippet-slot class="min-h-0 min-w-0 overflow-hidden">
872
+ <div
873
+ data-snippet-slot
874
+ class="min-h-0 min-w-0 overflow-hidden transition-[height,max-height] duration-[360ms] ease-[cubic-bezier(0.22,1,0.36,1)]"
875
+ >
873
876
  <RequestSnippets
874
877
  api={api}
875
878
  method={route.openApiMethod}
@@ -878,7 +881,10 @@ const formattedBodyDescription = bodyDescription
878
881
  </div>
879
882
  {
880
883
  responses && (
881
- <div data-snippet-slot class="min-h-0 min-w-0 overflow-hidden">
884
+ <div
885
+ data-snippet-slot
886
+ class="min-h-0 min-w-0 overflow-hidden transition-[height,max-height] duration-[360ms] ease-[cubic-bezier(0.22,1,0.36,1)]"
887
+ >
882
888
  <ResponseSnippets responses={responses} />
883
889
  </div>
884
890
  )
@@ -1087,14 +1093,37 @@ const formattedBodyDescription = bodyDescription
1087
1093
  stack.querySelectorAll("[data-snippet-slot]"),
1088
1094
  ).filter((slot) => slot instanceof HTMLElement);
1089
1095
 
1090
- const applySlotHeights = () => {
1096
+ const prefersReducedMotion =
1097
+ typeof window.matchMedia === "function" &&
1098
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches;
1099
+
1100
+ const slotHeightTransitionMs = 360;
1101
+ let isAnimatingSlotHeights = false;
1102
+ let slotHeightAnimationTimeoutId = null;
1103
+
1104
+ const applySlotHeights = ({ animate = false } = {}) => {
1091
1105
  if (!slots.length) return;
1106
+ if (isAnimatingSlotHeights && !animate) return;
1107
+
1108
+ const shouldAnimate = animate && !prefersReducedMotion;
1109
+ const previousHeights = shouldAnimate
1110
+ ? slots.map((slot) => Math.ceil(slot.getBoundingClientRect().height))
1111
+ : [];
1112
+ const previousTransitions = shouldAnimate
1113
+ ? slots.map((slot) => slot.style.transition)
1114
+ : [];
1092
1115
 
1093
1116
  const viewportBudget = getViewportBudget();
1094
1117
  if (host instanceof HTMLElement && viewportBudget > 0) {
1095
1118
  host.style.maxHeight = `${viewportBudget}px`;
1096
1119
  }
1097
1120
 
1121
+ if (shouldAnimate) {
1122
+ for (const slot of slots) {
1123
+ slot.style.transition = "none";
1124
+ }
1125
+ }
1126
+
1098
1127
  for (const slot of slots) {
1099
1128
  slot.style.height = "auto";
1100
1129
  slot.style.maxHeight = "none";
@@ -1132,89 +1161,117 @@ const formattedBodyDescription = bodyDescription
1132
1161
  0,
1133
1162
  );
1134
1163
 
1135
- if (naturalTotal <= available) {
1136
- for (let i = 0; i < slots.length; i += 1) {
1137
- const height = naturalHeights[i];
1138
- slots[i].style.height = `${height}px`;
1139
- slots[i].style.maxHeight = `${height}px`;
1140
- }
1141
- return;
1142
- }
1164
+ let targetHeights = naturalHeights;
1143
1165
 
1144
- const roundedHeights = new Array(slots.length).fill(0);
1145
- let remainingHeight = available;
1146
- let remainingIndexes = slots
1147
- .map((_, index) => index)
1148
- .sort((a, b) => naturalHeights[a] - naturalHeights[b]);
1149
-
1150
- while (remainingIndexes.length > 0) {
1151
- const evenShare = remainingHeight / remainingIndexes.length;
1152
- const smallestIndex = remainingIndexes[0];
1153
- const smallestNatural = naturalHeights[smallestIndex];
1154
-
1155
- if (smallestNatural <= evenShare) {
1156
- const fixedHeight = Math.min(smallestNatural, remainingHeight);
1157
- roundedHeights[smallestIndex] = Math.floor(fixedHeight);
1158
- remainingHeight -= roundedHeights[smallestIndex];
1159
- remainingIndexes = remainingIndexes.slice(1);
1160
- continue;
1161
- }
1166
+ if (naturalTotal > available) {
1167
+ targetHeights = new Array(slots.length).fill(0);
1168
+ let remainingHeight = available;
1169
+ let remainingIndexes = slots
1170
+ .map((_, index) => index)
1171
+ .sort((a, b) => naturalHeights[a] - naturalHeights[b]);
1172
+
1173
+ while (remainingIndexes.length > 0) {
1174
+ const evenShare = remainingHeight / remainingIndexes.length;
1175
+ const smallestIndex = remainingIndexes[0];
1176
+ const smallestNatural = naturalHeights[smallestIndex];
1177
+
1178
+ if (smallestNatural <= evenShare) {
1179
+ const fixedHeight = Math.min(smallestNatural, remainingHeight);
1180
+ targetHeights[smallestIndex] = Math.floor(fixedHeight);
1181
+ remainingHeight -= targetHeights[smallestIndex];
1182
+ remainingIndexes = remainingIndexes.slice(1);
1183
+ continue;
1184
+ }
1162
1185
 
1163
- const base = Math.floor(evenShare);
1164
- const remainder = remainingHeight - base * remainingIndexes.length;
1165
- for (let i = 0; i < remainingIndexes.length; i += 1) {
1166
- const index = remainingIndexes[i];
1167
- roundedHeights[index] = base + (i < remainder ? 1 : 0);
1186
+ const base = Math.floor(evenShare);
1187
+ const remainder = remainingHeight - base * remainingIndexes.length;
1188
+ for (let i = 0; i < remainingIndexes.length; i += 1) {
1189
+ const index = remainingIndexes[i];
1190
+ targetHeights[index] = base + (i < remainder ? 1 : 0);
1191
+ }
1192
+ remainingHeight = 0;
1193
+ remainingIndexes = [];
1168
1194
  }
1169
- remainingHeight = 0;
1170
- remainingIndexes = [];
1171
- }
1172
1195
 
1173
- let roundedTotal = roundedHeights.reduce((sum, value) => sum + value, 0);
1174
- let delta = available - roundedTotal;
1196
+ let roundedTotal = targetHeights.reduce((sum, value) => sum + value, 0);
1197
+ let delta = available - roundedTotal;
1175
1198
 
1176
- if (delta !== 0) {
1177
- const adjustOrder = slots
1178
- .map((_, index) => index)
1179
- .sort((a, b) => roundedHeights[b] - roundedHeights[a]);
1199
+ if (delta !== 0) {
1200
+ const adjustOrder = slots
1201
+ .map((_, index) => index)
1202
+ .sort((a, b) => targetHeights[b] - targetHeights[a]);
1180
1203
 
1181
- while (delta !== 0) {
1182
- let changed = false;
1204
+ while (delta !== 0) {
1205
+ let changed = false;
1183
1206
 
1184
- for (const index of adjustOrder) {
1185
- if (delta === 0) break;
1207
+ for (const index of adjustOrder) {
1208
+ if (delta === 0) break;
1186
1209
 
1187
- if (delta > 0) {
1188
- roundedHeights[index] += 1;
1189
- delta -= 1;
1190
- changed = true;
1191
- continue;
1192
- }
1210
+ if (delta > 0) {
1211
+ targetHeights[index] += 1;
1212
+ delta -= 1;
1213
+ changed = true;
1214
+ continue;
1215
+ }
1193
1216
 
1194
- if (roundedHeights[index] > 0) {
1195
- roundedHeights[index] -= 1;
1196
- delta += 1;
1197
- changed = true;
1217
+ if (targetHeights[index] > 0) {
1218
+ targetHeights[index] -= 1;
1219
+ delta += 1;
1220
+ changed = true;
1221
+ }
1198
1222
  }
1223
+
1224
+ if (!changed) break;
1199
1225
  }
1226
+ }
1227
+ }
1200
1228
 
1201
- if (!changed) break;
1229
+ const setSlotHeights = () => {
1230
+ for (let i = 0; i < slots.length; i += 1) {
1231
+ const height = targetHeights[i];
1232
+ slots[i].style.height = `${height}px`;
1233
+ slots[i].style.maxHeight = `${height}px`;
1202
1234
  }
1235
+ };
1236
+
1237
+ if (!shouldAnimate) {
1238
+ setSlotHeights();
1239
+ return;
1240
+ }
1241
+
1242
+ isAnimatingSlotHeights = true;
1243
+ if (slotHeightAnimationTimeoutId) {
1244
+ window.clearTimeout(slotHeightAnimationTimeoutId);
1203
1245
  }
1204
1246
 
1205
1247
  for (let i = 0; i < slots.length; i += 1) {
1206
- slots[i].style.height = `${roundedHeights[i]}px`;
1207
- slots[i].style.maxHeight = `${roundedHeights[i]}px`;
1248
+ const height = previousHeights[i];
1249
+ slots[i].style.height = `${height}px`;
1250
+ slots[i].style.maxHeight = `${height}px`;
1208
1251
  }
1252
+
1253
+ void stack.offsetHeight;
1254
+
1255
+ for (let i = 0; i < slots.length; i += 1) {
1256
+ slots[i].style.transition = previousTransitions[i];
1257
+ }
1258
+
1259
+ window.requestAnimationFrame(setSlotHeights);
1260
+
1261
+ slotHeightAnimationTimeoutId = window.setTimeout(() => {
1262
+ isAnimatingSlotHeights = false;
1263
+ slotHeightAnimationTimeoutId = null;
1264
+ applySlotHeights();
1265
+ }, slotHeightTransitionMs + 80);
1209
1266
  };
1210
1267
 
1211
- const scheduleApplySlotHeights = () => {
1268
+ const scheduleApplySlotHeights = (options = {}) => {
1212
1269
  window.requestAnimationFrame(() => {
1213
- window.requestAnimationFrame(applySlotHeights);
1270
+ window.requestAnimationFrame(() => applySlotHeights(options));
1214
1271
  });
1215
1272
  };
1216
1273
 
1217
- const resizeObserver = new ResizeObserver(applySlotHeights);
1274
+ const resizeObserver = new ResizeObserver(() => applySlotHeights());
1218
1275
  resizeObserver.observe(stack);
1219
1276
  if (host instanceof HTMLElement) {
1220
1277
  resizeObserver.observe(host);
@@ -1230,7 +1287,7 @@ const formattedBodyDescription = bodyDescription
1230
1287
  });
1231
1288
  window.addEventListener(
1232
1289
  "rd:snippet-content-change",
1233
- scheduleApplySlotHeights,
1290
+ () => scheduleApplySlotHeights({ animate: true }),
1234
1291
  );
1235
1292
  applySlotHeights();
1236
1293
  }
@@ -24,7 +24,7 @@ function buildHref(route: Route): string {
24
24
  {
25
25
  (previousRoute || nextRoute) && (
26
26
  <nav class="w-full pt-16" aria-label="Page pagination">
27
- <div class="flex gap-4 xs:grid-cols-2">
27
+ <div class="flex gap-4 flex-col sm:flex-row">
28
28
  {previousRoute && (
29
29
  <a
30
30
  href={buildHref(previousRoute)}
@@ -106,7 +106,7 @@ const containsActivePage = item.pages.some((child) => {
106
106
  x-show="expanded"
107
107
  x-collapse
108
108
  x-cloak
109
- class="border-l border-neutral-300/80 ml-[15.5px] pl-2"
109
+ class="border-l border-neutral-900/12 dark:border-neutral-100/12 ml-[15.5px] pl-2"
110
110
  >
111
111
  {
112
112
  item.pages.map((child) => (
@@ -321,14 +321,37 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
321
321
  pillLeft: 0,
322
322
  pillWidth: 0,
323
323
  pillVisible: false,
324
+ previousSelected: null,
325
+ isTransitioning: false,
326
+ isManagedSlot: false,
327
+ transitionDirection: 1,
328
+ transitionDurationMs: 360,
329
+ transitionEasing: "cubic-bezier(0.22, 1, 0.36, 1)",
324
330
  tabSyncHandler: null,
331
+ transitionTimeoutId: null,
325
332
  copyTimeoutId: null,
326
333
  init() {
327
- if (!this.hasMultiple) return;
328
- const sync = () => this.syncPill();
334
+ this.isManagedSlot = !!this.$root?.closest("[data-snippet-slot]");
335
+ if (
336
+ typeof window.matchMedia === "function" &&
337
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches
338
+ ) {
339
+ this.transitionDurationMs = 0;
340
+ }
341
+
342
+ const sync = () => {
343
+ this.syncPill();
344
+ this.syncSnippetHeight();
345
+ };
329
346
  this.tabSyncHandler = sync;
330
347
  this.$nextTick(() => {
348
+ if (this.$refs.snippetPanels) {
349
+ this.$refs.snippetPanels.style.transitionDuration =
350
+ this.transitionDurationMs + "ms";
351
+ }
331
352
  this.syncPill();
353
+ this.syncSnippetHeight();
354
+ if (!this.hasMultiple) return;
332
355
  this.$refs.tabList?.addEventListener("scroll", sync, {
333
356
  passive: true,
334
357
  });
@@ -352,13 +375,96 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
352
375
  this.pillWidth = activeRect.width;
353
376
  this.pillVisible = true;
354
377
  },
378
+ getPanelHeight(panel) {
379
+ if (!panel) return 0;
380
+ const child = panel.firstElementChild;
381
+ const childHeight =
382
+ child instanceof HTMLElement ? child.scrollHeight : 0;
383
+ return Math.ceil(
384
+ Math.max(panel.scrollHeight, childHeight, panel.getBoundingClientRect().height),
385
+ );
386
+ },
387
+ syncSnippetHeight() {
388
+ const panels = this.$refs.snippetPanels;
389
+ if (!panels) return;
390
+ if (this.isManagedSlot) {
391
+ panels.style.height = "";
392
+ return;
393
+ }
394
+ const activePanel = panels.querySelector(
395
+ '[data-snippet-index="' + this.selected + '"]',
396
+ );
397
+ const activeHeight = this.getPanelHeight(activePanel);
398
+ if (activeHeight > 0) {
399
+ panels.style.height = activeHeight + "px";
400
+ }
401
+ },
402
+ finishTransition() {
403
+ this.isTransitioning = false;
404
+ this.previousSelected = null;
405
+ this.transitionTimeoutId = null;
406
+ this.$nextTick(() => {
407
+ this.syncSnippetHeight();
408
+ window.dispatchEvent(new CustomEvent("rd:snippet-content-change"));
409
+ });
410
+ },
355
411
  select(index) {
412
+ if (index === this.selected) return;
413
+
414
+ if (this.transitionTimeoutId) {
415
+ window.clearTimeout(this.transitionTimeoutId);
416
+ this.transitionTimeoutId = null;
417
+ this.isTransitioning = false;
418
+ this.previousSelected = null;
419
+ }
420
+
421
+ const previousIndex = this.selected;
422
+ this.previousSelected = previousIndex;
423
+ this.transitionDirection = index > previousIndex ? 1 : -1;
356
424
  this.selected = index;
425
+ this.isTransitioning = true;
357
426
  this.$nextTick(() => {
358
427
  this.syncPill();
428
+ this.syncSnippetHeight();
359
429
  window.dispatchEvent(new CustomEvent("rd:snippet-content-change"));
430
+
431
+ if (this.transitionDurationMs === 0) {
432
+ this.finishTransition();
433
+ return;
434
+ }
435
+
436
+ this.transitionTimeoutId = window.setTimeout(() => {
437
+ this.finishTransition();
438
+ }, this.transitionDurationMs);
360
439
  });
361
440
  },
441
+ getPanelStyle(index) {
442
+ const base = "position: absolute; top: 0; right: 0; left: 0;";
443
+ const isActive = index === this.selected;
444
+ const isPrevious = this.isTransitioning && index === this.previousSelected;
445
+
446
+ if (!isActive && !isPrevious) {
447
+ return "display: none; opacity: 0; pointer-events: none; visibility: hidden; z-index: 0;";
448
+ }
449
+
450
+ if (!this.isTransitioning) {
451
+ return "position: relative; transform: translateX(0); opacity: 1; pointer-events: auto; visibility: visible; z-index: 1;";
452
+ }
453
+
454
+ if (isActive) {
455
+ const animationName =
456
+ this.transitionDirection === 1
457
+ ? "rd-snippet-slide-in-from-right"
458
+ : "rd-snippet-slide-in-from-left";
459
+ return "position: relative; opacity: 1; pointer-events: auto; visibility: visible; z-index: 2; animation: " + animationName + " " + this.transitionDurationMs + "ms " + this.transitionEasing + " both;";
460
+ }
461
+
462
+ const animationName =
463
+ this.transitionDirection === 1
464
+ ? "rd-snippet-slide-out-to-left"
465
+ : "rd-snippet-slide-out-to-right";
466
+ return base + " opacity: 1; pointer-events: none; visibility: visible; z-index: 1; animation: " + animationName + " " + this.transitionDurationMs + "ms " + this.transitionEasing + " both;";
467
+ },
362
468
  async copySelected() {
363
469
  const snippet = this.snippets[this.selected];
364
470
  if (!snippet) return;
@@ -383,10 +489,10 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
383
489
  >
384
490
  <div class="group/prose-code not-prose relative h-full min-h-0 w-full max-w-full min-w-0">
385
491
  <div
386
- class="flex h-full min-h-0 w-full max-w-full min-w-0 flex-col overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-xs dark:border-neutral-800 dark:bg-(--rd-code-surface)"
492
+ class="flex h-full min-h-0 w-full max-w-full min-w-0 flex-col rounded-xl"
387
493
  >
388
494
  <div
389
- class="flex items-center justify-between gap-2 border-b border-neutral-200 bg-neutral-50 rounded-t-xl inset-shadow-sm inset-shadow-neutral-100/80 dark:border-neutral-800 dark:bg-neutral-900/60 dark:inset-shadow-neutral-900/80"
495
+ class="flex items-center justify-between gap-2 bg-(--rd-code-header-surface)"
390
496
  >
391
497
  {
392
498
  hasMultipleRequests ? (
@@ -397,7 +503,7 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
397
503
  >
398
504
  <div
399
505
  aria-hidden="true"
400
- class="pointer-events-none absolute top-1/2 z-0 h-[28px] -translate-y-1/2 rounded-lg border-[0.5px] border-neutral-200 bg-white shadow-xs transition-[left,width,opacity] duration-200 ease-out dark:border-neutral-700/70 dark:bg-(--rd-code-surface)"
506
+ class="pointer-events-none absolute top-1/2 z-0 h-[28px] -translate-y-1/2 rounded-[9px] border-[0.5px] border-(--rd-code-tab-edge-border) bg-(--rd-code-surface) transition-[left,width,opacity] duration-200 ease-out"
401
507
  x-bind:class="pillVisible ? 'opacity-100' : 'opacity-0'"
402
508
  x-bind:style="'left:' + pillLeft + 'px;width:' + pillWidth + 'px;'"
403
509
  />
@@ -425,13 +531,13 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
425
531
  </div>
426
532
  ) : (
427
533
  <div class="min-w-0 flex-1">
428
- <div class="relative h-9 w-fit max-w-full rounded-tl-xl bg-white dark:bg-(--rd-code-surface)">
429
- <div class="absolute inset-x-0 -bottom-px h-px bg-white dark:bg-(--rd-code-surface)"></div>
534
+ <div class="relative h-9 w-fit max-w-full rounded-tl-xl bg-(--rd-code-surface)">
535
+ <div class="absolute inset-x-0 -bottom-px h-px bg-(--rd-code-surface)"></div>
430
536
  <CodeTabEdge
431
- className="pointer-events-none absolute -top-px left-full z-10 h-[calc(100%+2px)]"
537
+ className="pointer-events-none absolute -top-[0.5px] left-full z-10 h-[calc(100%+1.5px)]"
432
538
  />
433
539
 
434
- <div class="relative z-20 inline-flex h-9 max-w-full items-center gap-2 pl-5 pr-3 py-1.5 text-xs font-medium text-neutral-700 dark:text-neutral-300">
540
+ <div class="relative z-20 inline-flex h-9 max-w-full items-center gap-2 rounded-tl-xl border-t-[0.5px] border-l-[0.5px] border-(--rd-code-tab-edge-border) pl-5 pr-3 py-1.5 text-xs font-medium text-neutral-700 dark:text-neutral-300">
435
541
  <span
436
542
  class="size-3.5 shrink-0 self-center rounded-[4px]"
437
543
  set:html={firstSnippet.iconSvg}
@@ -443,8 +549,8 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
443
549
  )
444
550
  }
445
551
 
446
- <div class="relative h-9 w-5 shrink-0 rounded-tr-xl bg-white dark:bg-(--rd-code-surface)">
447
- <div class="absolute inset-x-0 -bottom-px h-px bg-white dark:bg-(--rd-code-surface)"></div>
552
+ <div class="relative h-9 w-5 shrink-0 rounded-tr-xl bg-(--rd-code-surface) border-t-[0.5px] border-r-[0.5px] border-(--rd-code-tab-edge-border)">
553
+ <div class="absolute inset-x-0 -bottom-px h-px bg-(--rd-code-surface)"></div>
448
554
  <CodeTabEdge
449
555
  className="pointer-events-none absolute -top-px right-full z-10 h-[calc(100%+2px)] rotate-y-180"
450
556
  />
@@ -470,14 +576,21 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
470
576
  </div>
471
577
  </div>
472
578
 
473
- <div class="relative min-h-0 min-w-0 flex-1 overflow-hidden rounded-b-xl">
474
- <div class="relative h-full overflow-auto [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90 dark:[scrollbar-color:var(--color-neutral-700)_transparent] dark:[&::-webkit-scrollbar-thumb]:bg-neutral-700/70 dark:hover:[&::-webkit-scrollbar-thumb]:bg-neutral-700/90">
475
- <div class="pointer-events-none sticky top-0 z-10 -mb-4 h-4 w-full bg-linear-to-b from-white to-transparent dark:from-(--rd-code-surface)"></div>
579
+ <div class="relative min-h-0 min-w-0 flex-1 overflow-hidden rounded-b-xl rounded-tl-xl border-[0.5px] border-(--rd-code-tab-edge-border) bg-(--rd-code-surface)">
580
+ <div
581
+ x-ref="snippetPanels"
582
+ class="relative h-full overflow-auto transition-[height] duration-[360ms] ease-[cubic-bezier(0.22,1,0.36,1)] [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90 dark:[scrollbar-color:var(--color-neutral-700)_transparent] dark:[&::-webkit-scrollbar-thumb]:bg-neutral-700/70 dark:hover:[&::-webkit-scrollbar-thumb]:bg-neutral-700/90"
583
+ >
476
584
  {
477
585
  requestSnippetItems.map((snippet, index) => (
478
586
  <pre
479
- class="relative m-0 min-w-full bg-white p-0 text-[13px] leading-6 dark:bg-(--rd-code-surface)"
480
- x-show={`selected === ${index}`}
587
+ class="relative m-0 min-w-full p-0 text-[13px] leading-6"
588
+ x-bind:style={`getPanelStyle(${index})`}
589
+ style={
590
+ index === 0
591
+ ? "position: relative;"
592
+ : "display: none; position: absolute; top: 0; right: 0; left: 0; opacity: 0; visibility: hidden; pointer-events: none;"
593
+ }
481
594
  {...(index !== 0 ? { "x-cloak": true } : {})}
482
595
  data-snippet-index={index}
483
596
  ><code data-rd-code-theme class="block min-w-full py-2.5 font-mono text-neutral-800 dark:text-neutral-200"><Fragment set:html={snippet.renderedCodeLinesHtml} /></code></pre>
@@ -488,3 +601,49 @@ const hasMultipleRequests = requestSnippetItems.length > 1;
488
601
  </div>
489
602
  </div>
490
603
  </div>
604
+
605
+ <style>
606
+ @keyframes rd-snippet-slide-in-from-right {
607
+ from {
608
+ transform: translateX(100%);
609
+ opacity: 0;
610
+ }
611
+ to {
612
+ transform: translateX(0);
613
+ opacity: 1;
614
+ }
615
+ }
616
+
617
+ @keyframes rd-snippet-slide-in-from-left {
618
+ from {
619
+ transform: translateX(-100%);
620
+ opacity: 0;
621
+ }
622
+ to {
623
+ transform: translateX(0);
624
+ opacity: 1;
625
+ }
626
+ }
627
+
628
+ @keyframes rd-snippet-slide-out-to-left {
629
+ from {
630
+ transform: translateX(0);
631
+ opacity: 1;
632
+ }
633
+ to {
634
+ transform: translateX(-100%);
635
+ opacity: 0;
636
+ }
637
+ }
638
+
639
+ @keyframes rd-snippet-slide-out-to-right {
640
+ from {
641
+ transform: translateX(0);
642
+ opacity: 1;
643
+ }
644
+ to {
645
+ transform: translateX(100%);
646
+ opacity: 0;
647
+ }
648
+ }
649
+ </style>