astro-md-editor 0.0.3 → 0.0.5

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.
Files changed (25) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/index-UQt6zCrS.js +334 -0
  3. package/.output/public/assets/{main-_miJG8oz.js → main-DzXOjsqg.js} +1 -1
  4. package/.output/public/assets/styles-CezfLgHY.css +1 -0
  5. package/.output/server/{__root-C4T8UKZy.mjs → __root-CL_tq3ov.mjs} +1 -1
  6. package/.output/server/_libs/mixmark-io__domino.mjs +16632 -0
  7. package/.output/server/_libs/turndown.mjs +687 -675
  8. package/.output/server/_ssr/IconPickerPopover-fNUx2jAc.mjs +125 -0
  9. package/.output/server/_ssr/{ImageAssetBrowser-DWEdNK_g.mjs → ImageAssetBrowser-DNDdTqtf.mjs} +2 -2
  10. package/.output/server/_ssr/{collections.server-DyZEpKg6.mjs → collections.server-s12asITg.mjs} +24 -1
  11. package/.output/server/_ssr/{file-history.api-BLrUovD8.mjs → file-history.api-oydnxFVV.mjs} +8 -2
  12. package/.output/server/_ssr/{image-assets.server-Dn044pdj.mjs → image-assets.server-Ci2E1_Tm.mjs} +4 -2
  13. package/.output/server/_ssr/{image-preview.api-bqd1erIP.mjs → image-preview.api-pcN5PQhH.mjs} +2 -2
  14. package/.output/server/_ssr/{index-wJDNoCM2.mjs → index-BjQuGIib.mjs} +7 -2
  15. package/.output/server/_ssr/{index-2cOxFkCu.mjs → index-Bn1uKwTu.mjs} +527 -97
  16. package/.output/server/_ssr/index.mjs +17 -11
  17. package/.output/server/_ssr/{router-sxRLAh5a.mjs → router-dPC3iVPs.mjs} +2 -2
  18. package/.output/server/{_tanstack-start-manifest_v-CWdBk-ge.mjs → _tanstack-start-manifest_v-Da8tuNDH.mjs} +1 -1
  19. package/.output/server/index.mjs +50 -50
  20. package/LICENSE.md +21 -0
  21. package/README.md +71 -69
  22. package/package.json +3 -2
  23. package/scripts/bootstrap-collections.mjs +59 -13
  24. package/.output/public/assets/index-DVVq2QjK.js +0 -334
  25. package/.output/public/assets/styles-yeMm8TG7.css +0 -1
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { u as useCollectionsData, R as Route, c as createSsrRpc } from "./router-sxRLAh5a.mjs";
2
+ import { u as useCollectionsData, R as Route, c as createSsrRpc } from "./router-dPC3iVPs.mjs";
3
3
  import { t as toast } from "../_libs/sonner.mjs";
4
4
  import { c as cva } from "../_libs/class-variance-authority.mjs";
5
5
  import { c as clsx } from "../_libs/clsx.mjs";
@@ -85,6 +85,7 @@ import "../_libs/prosemirror-gapcursor.mjs";
85
85
  import "../_libs/prosemirror-history.mjs";
86
86
  import "../_libs/rope-sequence.mjs";
87
87
  import "../_libs/linkifyjs.mjs";
88
+ import "../_libs/mixmark-io__domino.mjs";
88
89
  import "../_libs/fast-deep-equal.mjs";
89
90
  import "../_libs/json-schema-traverse.mjs";
90
91
  import "../_libs/fast-uri.mjs";
@@ -227,10 +228,10 @@ function TabsTrigger({ className, ...props }) {
227
228
  {
228
229
  "data-slot": "tabs-trigger",
229
230
  className: cn(
230
- "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
231
+ "text-foreground/60 hover:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
231
232
  "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
232
233
  "data-active:bg-background data-active:text-foreground dark:data-active:bg-input/30 dark:data-active:text-foreground",
233
- "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
234
+ "after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
234
235
  className
235
236
  ),
236
237
  ...props
@@ -262,7 +263,7 @@ function AlertDialogOverlay({
262
263
  {
263
264
  "data-slot": "alert-dialog-overlay",
264
265
  className: cn(
265
- "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
266
+ "data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs",
266
267
  className
267
268
  ),
268
269
  ...props
@@ -282,7 +283,7 @@ function AlertDialogContent({
282
283
  "data-slot": "alert-dialog-content",
283
284
  "data-size": size,
284
285
  className: cn(
285
- "group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-background p-4 ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
286
+ "group/alert-dialog-content bg-background ring-foreground/10 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl p-4 ring-1 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm",
286
287
  className
287
288
  ),
288
289
  ...props
@@ -315,7 +316,7 @@ function AlertDialogFooter({
315
316
  {
316
317
  "data-slot": "alert-dialog-footer",
317
318
  className: cn(
318
- "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
319
+ "bg-muted/50 -mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
319
320
  className
320
321
  ),
321
322
  ...props
@@ -347,7 +348,7 @@ function AlertDialogDescription({
347
348
  {
348
349
  "data-slot": "alert-dialog-description",
349
350
  className: cn(
350
- "text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
351
+ "text-muted-foreground *:[a]:hover:text-foreground text-sm text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3",
351
352
  className
352
353
  ),
353
354
  ...props
@@ -859,13 +860,13 @@ function PopoverContent({
859
860
  ) });
860
861
  }
861
862
  const MAX_ASSET_RESULTS = 120;
862
- function isObjectRecord$3(value) {
863
+ function isObjectRecord$4(value) {
863
864
  return typeof value === "object" && value !== null && !Array.isArray(value);
864
865
  }
865
866
  const listImageAssets = createServerFn({
866
867
  method: "POST"
867
868
  }).inputValidator((payload) => {
868
- if (!isObjectRecord$3(payload)) {
869
+ if (!isObjectRecord$4(payload)) {
869
870
  throw new Error("Invalid asset list payload.");
870
871
  }
871
872
  const currentFilePath = payload.currentFilePath;
@@ -884,7 +885,7 @@ const listImageAssets = createServerFn({
884
885
  const getImageAssetPreview = createServerFn({
885
886
  method: "POST"
886
887
  }).inputValidator((payload) => {
887
- if (!isObjectRecord$3(payload)) {
888
+ if (!isObjectRecord$4(payload)) {
888
889
  throw new Error("Invalid asset preview payload.");
889
890
  }
890
891
  const assetId = payload.assetId;
@@ -1060,13 +1061,13 @@ function ImageAssetPickerPopover({
1060
1061
  } }) })
1061
1062
  ] });
1062
1063
  }
1063
- function isObjectRecord$2(value) {
1064
+ function isObjectRecord$3(value) {
1064
1065
  return typeof value === "object" && value !== null && !Array.isArray(value);
1065
1066
  }
1066
1067
  const getLocalImagePreviewServerFn = createServerFn({
1067
1068
  method: "POST"
1068
1069
  }).inputValidator((payload) => {
1069
- if (!isObjectRecord$2(payload)) {
1070
+ if (!isObjectRecord$3(payload)) {
1070
1071
  throw new Error("Invalid local image preview payload.");
1071
1072
  }
1072
1073
  const currentFilePath = payload.currentFilePath;
@@ -2383,6 +2384,319 @@ function Switch({
2383
2384
  }
2384
2385
  );
2385
2386
  }
2387
+ const ICON_ROW_HEIGHT = 36;
2388
+ const ICON_VIEWPORT_HEIGHT = 288;
2389
+ const OVERSCAN_ROWS = 8;
2390
+ function isObjectRecord$2(value) {
2391
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2392
+ }
2393
+ function normalizeLibraryPrefixes(value) {
2394
+ if (!Array.isArray(value)) {
2395
+ return void 0;
2396
+ }
2397
+ const normalized = [...new Set(value.filter((item) => typeof item === "string").map((item) => item.trim().toLowerCase()).filter((item) => item.length > 0))];
2398
+ return normalized.length > 0 ? normalized : void 0;
2399
+ }
2400
+ function parseIconifyValue(value) {
2401
+ if (!value) {
2402
+ return {};
2403
+ }
2404
+ const normalized = value.trim();
2405
+ const separatorIndex = normalized.indexOf(":");
2406
+ if (separatorIndex <= 0 || separatorIndex === normalized.length - 1) {
2407
+ return {};
2408
+ }
2409
+ const prefix = normalized.slice(0, separatorIndex).toLowerCase();
2410
+ const name = normalized.slice(separatorIndex + 1);
2411
+ return {
2412
+ prefix,
2413
+ name
2414
+ };
2415
+ }
2416
+ function buildIconSvgUrl(prefix, name) {
2417
+ return `https://api.iconify.design/${encodeURIComponent(prefix)}/${encodeURIComponent(name)}.svg?width=20&height=20`;
2418
+ }
2419
+ function getIconMaskStyle$1(iconUrl) {
2420
+ return {
2421
+ maskImage: `url("${iconUrl}")`,
2422
+ maskRepeat: "no-repeat",
2423
+ maskPosition: "center",
2424
+ maskSize: "contain",
2425
+ WebkitMaskImage: `url("${iconUrl}")`,
2426
+ WebkitMaskRepeat: "no-repeat",
2427
+ WebkitMaskPosition: "center",
2428
+ WebkitMaskSize: "contain"
2429
+ };
2430
+ }
2431
+ const listIconifyCollectionsServerFn = createServerFn({
2432
+ method: "GET"
2433
+ }).handler(createSsrRpc("3ba1a566c82090c8422dd6ca7258b2e1aed644206364441faf1bd80942f21745"));
2434
+ const listCollectionIconsServerFn = createServerFn({
2435
+ method: "POST"
2436
+ }).inputValidator((payload) => {
2437
+ if (!isObjectRecord$2(payload)) {
2438
+ throw new Error("Invalid icon collection payload.");
2439
+ }
2440
+ const prefix = payload.prefix;
2441
+ if (typeof prefix !== "string" || prefix.trim().length === 0) {
2442
+ throw new Error("Missing icon collection prefix.");
2443
+ }
2444
+ return {
2445
+ prefix: prefix.trim().toLowerCase()
2446
+ };
2447
+ }).handler(createSsrRpc("c9dff6ed7373b505d6aeeb84c63f87a0d0c205051d9d817929a5b500e5e79e03"));
2448
+ const collectionsCache = {};
2449
+ const collectionIconsCache = /* @__PURE__ */ new Map();
2450
+ function readCollections() {
2451
+ if (collectionsCache.data) {
2452
+ return Promise.resolve(collectionsCache.data);
2453
+ }
2454
+ if (collectionsCache.promise) {
2455
+ return collectionsCache.promise;
2456
+ }
2457
+ collectionsCache.promise = listIconifyCollectionsServerFn().then((collections) => {
2458
+ collectionsCache.data = collections;
2459
+ return collections;
2460
+ }).finally(() => {
2461
+ collectionsCache.promise = void 0;
2462
+ });
2463
+ return collectionsCache.promise;
2464
+ }
2465
+ function readCollectionIcons(prefix) {
2466
+ const cacheKey = prefix.trim().toLowerCase();
2467
+ const cached = collectionIconsCache.get(cacheKey);
2468
+ if (cached?.data) {
2469
+ return Promise.resolve(cached.data);
2470
+ }
2471
+ if (cached?.promise) {
2472
+ return cached.promise;
2473
+ }
2474
+ const promise = listCollectionIconsServerFn({
2475
+ data: {
2476
+ prefix: cacheKey
2477
+ }
2478
+ }).then((icons) => {
2479
+ collectionIconsCache.set(cacheKey, {
2480
+ data: icons
2481
+ });
2482
+ return icons;
2483
+ }).finally(() => {
2484
+ const nextCached = collectionIconsCache.get(cacheKey);
2485
+ if (nextCached) {
2486
+ delete nextCached.promise;
2487
+ }
2488
+ });
2489
+ collectionIconsCache.set(cacheKey, {
2490
+ data: cached?.data,
2491
+ promise
2492
+ });
2493
+ return promise;
2494
+ }
2495
+ function getVirtualWindow(params) {
2496
+ const startIndex = Math.max(0, Math.floor(params.scrollTop / params.rowHeight) - params.overscan);
2497
+ const visibleCount = Math.ceil(params.viewportHeight / params.rowHeight);
2498
+ const endIndex = Math.min(params.itemCount, startIndex + visibleCount + params.overscan * 2);
2499
+ return {
2500
+ startIndex,
2501
+ endIndex,
2502
+ offsetY: startIndex * params.rowHeight,
2503
+ totalHeight: params.itemCount * params.rowHeight
2504
+ };
2505
+ }
2506
+ function IconPickerPopover({
2507
+ triggerLabel,
2508
+ triggerClassName,
2509
+ triggerAriaLabel,
2510
+ triggerContent,
2511
+ selectedIcon,
2512
+ allowedLibraries,
2513
+ onSelectIcon
2514
+ }) {
2515
+ const [open, setOpen] = reactExports.useState(false);
2516
+ const [collections, setCollections] = reactExports.useState([]);
2517
+ const [collectionsLoading, setCollectionsLoading] = reactExports.useState(false);
2518
+ const [collectionsError, setCollectionsError] = reactExports.useState();
2519
+ const [selectedPrefix, setSelectedPrefix] = reactExports.useState();
2520
+ const [iconNames, setIconNames] = reactExports.useState([]);
2521
+ const [iconsLoading, setIconsLoading] = reactExports.useState(false);
2522
+ const [iconsError, setIconsError] = reactExports.useState();
2523
+ const [iconQuery, setIconQuery] = reactExports.useState("");
2524
+ const [iconScrollTop, setIconScrollTop] = reactExports.useState(0);
2525
+ const parsedSelected = reactExports.useMemo(() => {
2526
+ return parseIconifyValue(selectedIcon);
2527
+ }, [selectedIcon]);
2528
+ const normalizedAllowedLibraries = reactExports.useMemo(() => {
2529
+ return normalizeLibraryPrefixes(allowedLibraries);
2530
+ }, [allowedLibraries]);
2531
+ reactExports.useEffect(() => {
2532
+ if (!open) {
2533
+ return;
2534
+ }
2535
+ let cancelled = false;
2536
+ setCollectionsLoading(true);
2537
+ setCollectionsError(void 0);
2538
+ void readCollections().then((nextCollections) => {
2539
+ if (cancelled) {
2540
+ return;
2541
+ }
2542
+ setCollections(nextCollections);
2543
+ }).catch((error) => {
2544
+ if (cancelled) {
2545
+ return;
2546
+ }
2547
+ const message = error instanceof Error ? error.message : String(error);
2548
+ setCollectionsError(message);
2549
+ toast.error(`Unable to load Iconify collections: ${message}`);
2550
+ }).finally(() => {
2551
+ if (!cancelled) {
2552
+ setCollectionsLoading(false);
2553
+ }
2554
+ });
2555
+ return () => {
2556
+ cancelled = true;
2557
+ };
2558
+ }, [open]);
2559
+ const filteredCollections = reactExports.useMemo(() => {
2560
+ const allowed = normalizedAllowedLibraries ? new Set(normalizedAllowedLibraries) : void 0;
2561
+ return collections.filter((collection) => {
2562
+ return allowed ? allowed.has(collection.prefix) : true;
2563
+ });
2564
+ }, [collections, normalizedAllowedLibraries]);
2565
+ reactExports.useEffect(() => {
2566
+ if (filteredCollections.length === 0) {
2567
+ setSelectedPrefix(void 0);
2568
+ return;
2569
+ }
2570
+ if (selectedPrefix && filteredCollections.some((collection) => collection.prefix === selectedPrefix)) {
2571
+ return;
2572
+ }
2573
+ const preferredByValue = parsedSelected.prefix ? filteredCollections.find((collection) => collection.prefix === parsedSelected.prefix) : void 0;
2574
+ setSelectedPrefix(preferredByValue?.prefix ?? filteredCollections[0].prefix);
2575
+ }, [filteredCollections, parsedSelected.prefix, selectedPrefix]);
2576
+ reactExports.useEffect(() => {
2577
+ if (!open || !selectedPrefix) {
2578
+ setIconNames([]);
2579
+ return;
2580
+ }
2581
+ let cancelled = false;
2582
+ setIconsLoading(true);
2583
+ setIconsError(void 0);
2584
+ setIconNames([]);
2585
+ void readCollectionIcons(selectedPrefix).then((nextIcons) => {
2586
+ if (cancelled) {
2587
+ return;
2588
+ }
2589
+ setIconNames(nextIcons);
2590
+ }).catch((error) => {
2591
+ if (cancelled) {
2592
+ return;
2593
+ }
2594
+ const message = error instanceof Error ? error.message : String(error);
2595
+ setIconsError(message);
2596
+ toast.error(`Unable to load icons for ${selectedPrefix}: ${message}`);
2597
+ }).finally(() => {
2598
+ if (!cancelled) {
2599
+ setIconsLoading(false);
2600
+ }
2601
+ });
2602
+ return () => {
2603
+ cancelled = true;
2604
+ };
2605
+ }, [open, selectedPrefix]);
2606
+ const filteredIcons = reactExports.useMemo(() => {
2607
+ const query = iconQuery.trim().toLowerCase();
2608
+ if (query.length === 0) {
2609
+ return iconNames;
2610
+ }
2611
+ return iconNames.filter((iconName) => iconName.toLowerCase().includes(query));
2612
+ }, [iconNames, iconQuery]);
2613
+ reactExports.useEffect(() => {
2614
+ setIconScrollTop(0);
2615
+ }, [iconQuery, selectedPrefix]);
2616
+ const iconVirtualWindow = reactExports.useMemo(() => {
2617
+ return getVirtualWindow({
2618
+ scrollTop: iconScrollTop,
2619
+ viewportHeight: ICON_VIEWPORT_HEIGHT,
2620
+ rowHeight: ICON_ROW_HEIGHT,
2621
+ itemCount: filteredIcons.length,
2622
+ overscan: OVERSCAN_ROWS
2623
+ });
2624
+ }, [filteredIcons.length, iconScrollTop]);
2625
+ const selectedIconifyName = parsedSelected.prefix && parsedSelected.name ? `${parsedSelected.prefix}:${parsedSelected.name}` : void 0;
2626
+ const selectedCollection = reactExports.useMemo(() => {
2627
+ if (!selectedPrefix) {
2628
+ return void 0;
2629
+ }
2630
+ return filteredCollections.find((collection) => {
2631
+ return collection.prefix === selectedPrefix;
2632
+ });
2633
+ }, [filteredCollections, selectedPrefix]);
2634
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(Popover, { open, onOpenChange: setOpen, children: [
2635
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverTrigger, { className: cn(buttonVariants({
2636
+ variant: "outline"
2637
+ }), "h-8 border-dashed text-xs", triggerClassName), "aria-label": triggerAriaLabel, children: triggerContent ?? triggerLabel ?? "Pick icon" }),
2638
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverContent, { className: "w-96 max-w-[calc(100vw-2rem)] p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
2639
+ collectionsLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-muted-foreground flex items-center gap-2 px-1 text-xs", children: [
2640
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
2641
+ "Loading libraries..."
2642
+ ] }) : null,
2643
+ !collectionsLoading && collectionsError ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-destructive/90 rounded-md px-1 text-xs", children: collectionsError }) : null,
2644
+ !collectionsLoading && !collectionsError && filteredCollections.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground px-1 text-xs", children: "No icon libraries found." }) : null,
2645
+ !collectionsLoading && !collectionsError && filteredCollections.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-x-auto pb-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex w-max min-w-full gap-1", children: filteredCollections.map((collection) => {
2646
+ const isSelected = collection.prefix === selectedPrefix;
2647
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: cn("rounded-md px-2 py-1 text-xs whitespace-nowrap transition-colors", isSelected ? "bg-foreground text-background" : "bg-muted/55 text-muted-foreground hover:bg-muted/75 hover:text-foreground"), onClick: () => {
2648
+ setSelectedPrefix(collection.prefix);
2649
+ }, children: collection.prefix }, collection.prefix);
2650
+ }) }) }) : null,
2651
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground px-1 text-[11px]", children: selectedCollection ? `${selectedCollection.name} (${selectedCollection.prefix}) · ${selectedCollection.total} icons` : "Select a library to browse icons." }),
2652
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
2653
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
2654
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2" }),
2655
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Input, { value: iconQuery, onChange: (event) => {
2656
+ setIconQuery(event.target.value);
2657
+ }, className: "bg-muted/50 focus-visible:ring-ring/35 h-8 border-transparent pl-8 text-xs shadow-none focus-visible:border-transparent focus-visible:ring-2", placeholder: "Search icons...", "aria-label": "Search icons", disabled: !selectedPrefix })
2658
+ ] }),
2659
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-border/50 rounded-md border", children: [
2660
+ !selectedPrefix ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground flex items-center justify-center px-2 text-xs", style: {
2661
+ height: ICON_VIEWPORT_HEIGHT
2662
+ }, children: "Select a library to browse icons." }) : null,
2663
+ selectedPrefix && iconsLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-muted-foreground flex items-center justify-center gap-2 text-xs", style: {
2664
+ height: ICON_VIEWPORT_HEIGHT
2665
+ }, children: [
2666
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
2667
+ "Loading icons..."
2668
+ ] }) : null,
2669
+ selectedPrefix && !iconsLoading && iconsError ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-destructive/90 px-2 py-2 text-xs", style: {
2670
+ height: ICON_VIEWPORT_HEIGHT
2671
+ }, children: iconsError }) : null,
2672
+ selectedPrefix && !iconsLoading && !iconsError && filteredIcons.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground flex items-center justify-center px-2 text-xs", style: {
2673
+ height: ICON_VIEWPORT_HEIGHT
2674
+ }, children: "No icons found." }) : null,
2675
+ selectedPrefix && !iconsLoading && !iconsError && filteredIcons.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: {
2676
+ height: ICON_VIEWPORT_HEIGHT
2677
+ }, onScroll: (event) => {
2678
+ setIconScrollTop(event.currentTarget.scrollTop);
2679
+ }, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: {
2680
+ height: iconVirtualWindow.totalHeight
2681
+ }, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: {
2682
+ transform: `translateY(${iconVirtualWindow.offsetY}px)`
2683
+ }, children: filteredIcons.slice(iconVirtualWindow.startIndex, iconVirtualWindow.endIndex).map((iconName) => {
2684
+ const iconifyName = `${selectedPrefix}:${iconName}`;
2685
+ const isSelected = iconifyName === selectedIconifyName;
2686
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: cn("hover:bg-muted/65 flex h-9 w-full items-center gap-2 px-2 text-left text-xs transition-colors", isSelected ? "bg-muted/70" : ""), onClick: () => {
2687
+ onSelectIcon(iconifyName);
2688
+ setOpen(false);
2689
+ }, children: [
2690
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "text-foreground size-4 shrink-0 bg-current", style: getIconMaskStyle$1(buildIconSvgUrl(selectedPrefix, iconName)) }),
2691
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-foreground/90 flex-1 truncate", children: iconName }),
2692
+ isSelected ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5 shrink-0" }) : null
2693
+ ] }, iconName);
2694
+ }) }) }) }) : null
2695
+ ] })
2696
+ ] })
2697
+ ] }) })
2698
+ ] });
2699
+ }
2386
2700
  function padTwo$1(value) {
2387
2701
  return value.toString().padStart(2, "0");
2388
2702
  }
@@ -2572,6 +2886,14 @@ function resolveCustomFieldKind(params) {
2572
2886
  required: params.required
2573
2887
  };
2574
2888
  }
2889
+ if (customKind.kind === "icon" && params.property.type === "string") {
2890
+ return {
2891
+ kind: "icon",
2892
+ key: params.key,
2893
+ required: params.required,
2894
+ iconLibraries: customKind.iconLibraries
2895
+ };
2896
+ }
2575
2897
  return void 0;
2576
2898
  }
2577
2899
  function resolveAstroObjectSchema(schema) {
@@ -2686,6 +3008,7 @@ function isCompatibleValue(field, value) {
2686
3008
  case "string":
2687
3009
  case "image":
2688
3010
  case "color":
3011
+ case "icon":
2689
3012
  return typeof value === "string";
2690
3013
  case "number":
2691
3014
  return typeof value === "number" && Number.isFinite(value);
@@ -2890,6 +3213,36 @@ function normalizeHexColor(value) {
2890
3213
  function isHexColor(value) {
2891
3214
  return HEX_COLOR_REGEX.test(value);
2892
3215
  }
3216
+ function parseIconifyName(value) {
3217
+ const normalized = value.trim();
3218
+ const separatorIndex = normalized.indexOf(":");
3219
+ if (separatorIndex <= 0 || separatorIndex === normalized.length - 1) {
3220
+ return void 0;
3221
+ }
3222
+ return {
3223
+ prefix: normalized.slice(0, separatorIndex).toLowerCase(),
3224
+ name: normalized.slice(separatorIndex + 1)
3225
+ };
3226
+ }
3227
+ function buildIconPreviewUrl(iconifyName) {
3228
+ const parsed = parseIconifyName(iconifyName);
3229
+ if (!parsed) {
3230
+ return void 0;
3231
+ }
3232
+ return `https://api.iconify.design/${encodeURIComponent(parsed.prefix)}/${encodeURIComponent(parsed.name)}.svg?width=24&height=24`;
3233
+ }
3234
+ function getIconMaskStyle(iconUrl) {
3235
+ return {
3236
+ maskImage: `url("${iconUrl}")`,
3237
+ maskRepeat: "no-repeat",
3238
+ maskPosition: "center",
3239
+ maskSize: "contain",
3240
+ WebkitMaskImage: `url("${iconUrl}")`,
3241
+ WebkitMaskRepeat: "no-repeat",
3242
+ WebkitMaskPosition: "center",
3243
+ WebkitMaskSize: "contain"
3244
+ };
3245
+ }
2893
3246
  const HOUR_OPTIONS = Array.from({ length: 24 }, (_, index) => padTwo(index));
2894
3247
  const MINUTE_OPTIONS = Array.from({ length: 60 }, (_, index) => padTwo(index));
2895
3248
  function isDirectImagePreviewSourcePath(sourcePath) {
@@ -2987,7 +3340,10 @@ function FrontmatterImagePreviewGrid({
2987
3340
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
2988
3341
  "div",
2989
3342
  {
2990
- className: cn("grid gap-2", columns === 1 ? "grid-cols-1" : "grid-cols-2"),
3343
+ className: cn(
3344
+ "grid gap-2",
3345
+ columns === 1 ? "grid-cols-1" : "grid-cols-2"
3346
+ ),
2991
3347
  children: items.map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
2992
3348
  "div",
2993
3349
  {
@@ -2998,7 +3354,10 @@ function FrontmatterImagePreviewGrid({
2998
3354
  {
2999
3355
  src: item.previewUrl,
3000
3356
  alt: item.sourcePath,
3001
- className: cn("w-full object-cover", columns === 1 ? "h-44" : "h-28")
3357
+ className: cn(
3358
+ "w-full object-cover",
3359
+ columns === 1 ? "h-44" : "h-28"
3360
+ )
3002
3361
  }
3003
3362
  ) : item.loading ? /* @__PURE__ */ jsxRuntimeExports.jsx(
3004
3363
  "div",
@@ -3023,7 +3382,7 @@ function FrontmatterImagePreviewGrid({
3023
3382
  "button",
3024
3383
  {
3025
3384
  type: "button",
3026
- className: "bg-background/85 text-foreground absolute top-2 right-2 inline-flex size-6 items-center justify-center rounded-full opacity-0 shadow-sm transition-opacity hover:opacity-100 group-hover:opacity-100",
3385
+ className: "bg-background/85 text-foreground absolute top-2 right-2 inline-flex size-6 items-center justify-center rounded-full opacity-0 shadow-sm transition-opacity group-hover:opacity-100 hover:opacity-100",
3027
3386
  onClick: () => onRemoveAt(index),
3028
3387
  "aria-label": `Remove image ${item.sourcePath}`,
3029
3388
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" })
@@ -3422,6 +3781,53 @@ function ColorField({
3422
3781
  hasValue && !hasValidValue ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-destructive/85 text-xs", children: "Use a hex color in #RRGGBB format." }) : null
3423
3782
  ] });
3424
3783
  }
3784
+ function IconField({
3785
+ fieldKey,
3786
+ value,
3787
+ iconLibraries,
3788
+ onChange,
3789
+ onBlur
3790
+ }) {
3791
+ const stringValue = typeof value === "string" ? value : "";
3792
+ const previewUrl = buildIconPreviewUrl(stringValue);
3793
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
3794
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
3795
+ Input,
3796
+ {
3797
+ id: fieldKey,
3798
+ className: SUBTLE_FIELD_CLASS,
3799
+ value: stringValue,
3800
+ onChange: (event) => {
3801
+ const nextRaw = event.target.value;
3802
+ onChange(nextRaw.length > 0 ? nextRaw : void 0);
3803
+ },
3804
+ onBlur,
3805
+ placeholder: "lucide:messages-square"
3806
+ }
3807
+ ),
3808
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
3809
+ IconPickerPopover,
3810
+ {
3811
+ triggerClassName: "border-border/50 bg-muted/45 hover:bg-muted/60 focus-visible:ring-ring/35 size-8 shrink-0 rounded-md border p-0 shadow-none focus-visible:ring-2",
3812
+ triggerAriaLabel: `${fieldKey} icon picker`,
3813
+ triggerContent: previewUrl ? /* @__PURE__ */ jsxRuntimeExports.jsx(
3814
+ "span",
3815
+ {
3816
+ "aria-hidden": "true",
3817
+ className: "text-foreground size-3 shrink-0 bg-current",
3818
+ style: getIconMaskStyle(previewUrl)
3819
+ }
3820
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground text-[10px] font-medium", children: "icon" }),
3821
+ selectedIcon: stringValue,
3822
+ allowedLibraries: iconLibraries,
3823
+ onSelectIcon: (nextIcon) => {
3824
+ onChange(nextIcon);
3825
+ onBlur();
3826
+ }
3827
+ }
3828
+ )
3829
+ ] });
3830
+ }
3425
3831
  function FieldErrorList({
3426
3832
  fieldKey,
3427
3833
  errors
@@ -3688,7 +4094,7 @@ function RightSidebar({
3688
4094
  setActiveTab(value);
3689
4095
  }
3690
4096
  },
3691
- className: "h-full min-h-0 gap-3 w-full",
4097
+ className: "h-full min-h-0 w-full gap-3",
3692
4098
  children: [
3693
4099
  /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsList, { className: "w-full", children: [
3694
4100
  /* @__PURE__ */ jsxRuntimeExports.jsx(TabsTrigger, { value: "frontmatter", className: "text-xs", children: "Frontmatter" }),
@@ -3752,6 +4158,18 @@ function RightSidebar({
3752
4158
  onBlur: () => handleFieldBlur(field.key)
3753
4159
  }
3754
4160
  ),
4161
+ field.kind === "icon" && /* @__PURE__ */ jsxRuntimeExports.jsx(
4162
+ IconField,
4163
+ {
4164
+ fieldKey: field.key,
4165
+ value,
4166
+ iconLibraries: field.iconLibraries,
4167
+ onChange: (nextValue) => {
4168
+ setFieldValue(field.key, nextValue);
4169
+ },
4170
+ onBlur: () => handleFieldBlur(field.key)
4171
+ }
4172
+ ),
3755
4173
  field.kind === "number" && /* @__PURE__ */ jsxRuntimeExports.jsx(
3756
4174
  NumberField,
3757
4175
  {
@@ -3865,96 +4283,108 @@ function RightSidebar({
3865
4283
  }
3866
4284
  ) : null
3867
4285
  ] }),
3868
- /* @__PURE__ */ jsxRuntimeExports.jsxs(TabsContent, { value: "history", className: "min-h-0 space-y-2 overflow-auto pr-1", children: [
3869
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
3870
- Button,
3871
- {
3872
- type: "button",
3873
- size: "sm",
3874
- variant: "ghost",
3875
- className: "h-7 px-2 text-xs",
3876
- disabled: historyLoading || historyLoadingMore || !selectedFilePath,
3877
- onClick: () => {
3878
- void loadHistory(void 0, false);
3879
- },
3880
- children: "Refresh"
3881
- }
3882
- ) }),
3883
- historyUnavailableReason ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "bg-muted/40 text-muted-foreground rounded-md px-3 py-2 text-xs", children: historyUnavailableReason }) : null,
3884
- !historyUnavailableReason && historyError ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-destructive/90 rounded-md px-1 py-1 text-xs", children: historyError }) : null,
3885
- !historyUnavailableReason && !historyError && historyLoading && historyCommits.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-muted-foreground flex items-center gap-1.5 px-1 py-1 text-xs", children: [
3886
- /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
3887
- "Loading history..."
3888
- ] }) : null,
3889
- !historyUnavailableReason && !historyError && !historyLoading && historyCommits.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground rounded-md px-1 py-1 text-xs", children: "No Git history found for this file." }) : null,
3890
- !historyUnavailableReason && historyCommits.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "divide-border/40 divide-y rounded-md border", children: historyCommits.map((commit) => {
3891
- const isExpanded = selectedCommitSha === commit.sha;
3892
- const commitTitle = commit.message.trim().length > 0 ? commit.message : "No commit message";
3893
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-2.5 py-2", children: [
3894
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
3895
- "button",
4286
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
4287
+ TabsContent,
4288
+ {
4289
+ value: "history",
4290
+ className: "min-h-0 space-y-2 overflow-auto pr-1",
4291
+ children: [
4292
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4293
+ Button,
3896
4294
  {
3897
4295
  type: "button",
3898
- className: "w-full text-left",
4296
+ size: "sm",
4297
+ variant: "ghost",
4298
+ className: "h-7 px-2 text-xs",
4299
+ disabled: historyLoading || historyLoadingMore || !selectedFilePath,
3899
4300
  onClick: () => {
3900
- setApplySummary(void 0);
3901
- setSelectedCommitSha(
3902
- (current) => current === commit.sha ? void 0 : commit.sha
3903
- );
4301
+ void loadHistory(void 0, false);
3904
4302
  },
3905
- children: [
3906
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-foreground/90 text-xs font-medium", children: commitTitle }),
3907
- /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-muted-foreground mt-0.5 text-[11px]", children: [
3908
- commit.author,
3909
- " · ",
3910
- formatHistoryDateTime(commit.dateIso)
3911
- ] })
3912
- ]
4303
+ children: "Refresh"
3913
4304
  }
3914
- ),
3915
- isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 space-y-2", children: [
3916
- revisionLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-muted-foreground flex items-center gap-1.5 text-xs", children: [
3917
- /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
3918
- "Loading frontmatter..."
3919
- ] }) : null,
3920
- revisionError ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-destructive/90 text-xs", children: revisionError }) : null,
3921
- !revisionLoading && !revisionError && selectedRevision ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
3922
- selectedRevision.parseWarnings.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-amber-100/70 text-amber-900 dark:bg-amber-900/30 dark:text-amber-200 rounded-md px-2 py-1.5 text-[11px]", children: selectedRevision.parseWarnings[0] }) : null,
3923
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "bg-muted/55 max-h-40 overflow-auto rounded-md px-2 py-1.5 text-[11px] leading-relaxed whitespace-pre-wrap", children: Object.keys(selectedRevision.frontmatter).length > 0 ? JSON.stringify(selectedRevision.frontmatter, null, 2) : "[No frontmatter]" }),
3924
- /* @__PURE__ */ jsxRuntimeExports.jsx(
3925
- Button,
4305
+ ) }),
4306
+ historyUnavailableReason ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "bg-muted/40 text-muted-foreground rounded-md px-3 py-2 text-xs", children: historyUnavailableReason }) : null,
4307
+ !historyUnavailableReason && historyError ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-destructive/90 rounded-md px-1 py-1 text-xs", children: historyError }) : null,
4308
+ !historyUnavailableReason && !historyError && historyLoading && historyCommits.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-muted-foreground flex items-center gap-1.5 px-1 py-1 text-xs", children: [
4309
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
4310
+ "Loading history..."
4311
+ ] }) : null,
4312
+ !historyUnavailableReason && !historyError && !historyLoading && historyCommits.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground rounded-md px-1 py-1 text-xs", children: "No Git history found for this file." }) : null,
4313
+ !historyUnavailableReason && historyCommits.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "divide-border/40 divide-y rounded-md border", children: historyCommits.map((commit) => {
4314
+ const isExpanded = selectedCommitSha === commit.sha;
4315
+ const commitTitle = commit.message.trim().length > 0 ? commit.message : "No commit message";
4316
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-2.5 py-2", children: [
4317
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
4318
+ "button",
3926
4319
  {
3927
4320
  type: "button",
3928
- size: "sm",
3929
- variant: "outline",
3930
- className: "h-7 w-full text-xs",
3931
- onClick: handleApplyHistoryRevision,
3932
- children: "Apply"
4321
+ className: "w-full text-left",
4322
+ onClick: () => {
4323
+ setApplySummary(void 0);
4324
+ setSelectedCommitSha(
4325
+ (current) => current === commit.sha ? void 0 : commit.sha
4326
+ );
4327
+ },
4328
+ children: [
4329
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-foreground/90 text-xs font-medium", children: commitTitle }),
4330
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-muted-foreground mt-0.5 text-[11px]", children: [
4331
+ commit.author,
4332
+ " ·",
4333
+ " ",
4334
+ formatHistoryDateTime(commit.dateIso)
4335
+ ] })
4336
+ ]
3933
4337
  }
3934
4338
  ),
3935
- applySummary ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-[11px]", children: applySummary }) : null
3936
- ] }) : null
3937
- ] }) : null
3938
- ] }, commit.sha);
3939
- }) }) : null,
3940
- historyNextCursor ? /* @__PURE__ */ jsxRuntimeExports.jsx(
3941
- Button,
3942
- {
3943
- type: "button",
3944
- size: "sm",
3945
- variant: "outline",
3946
- className: "h-7 w-full text-xs",
3947
- disabled: historyLoadingMore || historyLoading,
3948
- onClick: () => {
3949
- void loadHistory(historyNextCursor, true);
3950
- },
3951
- children: historyLoadingMore ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
3952
- /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
3953
- "Loading..."
3954
- ] }) : "Load older revisions"
3955
- }
3956
- ) : null
3957
- ] })
4339
+ isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 space-y-2", children: [
4340
+ revisionLoading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-muted-foreground flex items-center gap-1.5 text-xs", children: [
4341
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
4342
+ "Loading frontmatter..."
4343
+ ] }) : null,
4344
+ revisionError ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-destructive/90 text-xs", children: revisionError }) : null,
4345
+ !revisionLoading && !revisionError && selectedRevision ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
4346
+ selectedRevision.parseWarnings.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md bg-amber-100/70 px-2 py-1.5 text-[11px] text-amber-900 dark:bg-amber-900/30 dark:text-amber-200", children: selectedRevision.parseWarnings[0] }) : null,
4347
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "bg-muted/55 max-h-40 overflow-auto rounded-md px-2 py-1.5 text-[11px] leading-relaxed whitespace-pre-wrap", children: Object.keys(selectedRevision.frontmatter).length > 0 ? JSON.stringify(
4348
+ selectedRevision.frontmatter,
4349
+ null,
4350
+ 2
4351
+ ) : "[No frontmatter]" }),
4352
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
4353
+ Button,
4354
+ {
4355
+ type: "button",
4356
+ size: "sm",
4357
+ variant: "outline",
4358
+ className: "h-7 w-full text-xs",
4359
+ onClick: handleApplyHistoryRevision,
4360
+ children: "Apply"
4361
+ }
4362
+ ),
4363
+ applySummary ? /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-muted-foreground text-[11px]", children: applySummary }) : null
4364
+ ] }) : null
4365
+ ] }) : null
4366
+ ] }, commit.sha);
4367
+ }) }) : null,
4368
+ historyNextCursor ? /* @__PURE__ */ jsxRuntimeExports.jsx(
4369
+ Button,
4370
+ {
4371
+ type: "button",
4372
+ size: "sm",
4373
+ variant: "outline",
4374
+ className: "h-7 w-full text-xs",
4375
+ disabled: historyLoadingMore || historyLoading,
4376
+ onClick: () => {
4377
+ void loadHistory(historyNextCursor, true);
4378
+ },
4379
+ children: historyLoadingMore ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
4380
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }),
4381
+ "Loading..."
4382
+ ] }) : "Load older revisions"
4383
+ }
4384
+ ) : null
4385
+ ]
4386
+ }
4387
+ )
3958
4388
  ]
3959
4389
  }
3960
4390
  ) });