@canopy-iiif/app 0.7.17 → 0.7.18

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": "@canopy-iiif/app",
3
- "version": "0.7.17",
3
+ "version": "0.7.18",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "author": "Mat Jordan <mat@northwestern.edu>",
@@ -15,14 +15,20 @@
15
15
  "./ui/canopy-iiif-plugin": "./ui/tailwind-canopy-iiif-plugin.js",
16
16
  "./ui/canopy-iiif-preset": "./ui/tailwind-canopy-iiif-preset.js",
17
17
  "./lib/components/*": "./lib/components/*",
18
- "./head": "./lib/head.js"
18
+ "./head": "./lib/head.js",
19
+ "./orchestrator": {
20
+ "types": "./types/orchestrator.d.ts",
21
+ "require": "./lib/orchestrator.js",
22
+ "default": "./lib/orchestrator.js"
23
+ }
19
24
  },
20
25
  "files": [
21
26
  "lib/**",
22
27
  "ui/dist/**",
23
28
  "ui/styles/**",
24
29
  "ui/tailwind-canopy-iiif-plugin.js",
25
- "ui/tailwind-canopy-iiif-preset.js"
30
+ "ui/tailwind-canopy-iiif-preset.js",
31
+ "types/**"
26
32
  ],
27
33
  "publishConfig": {
28
34
  "access": "public"
@@ -0,0 +1,18 @@
1
+ import type { ChildProcess } from 'node:child_process';
2
+
3
+ export type Mode = 'build' | 'dev';
4
+
5
+ export interface LibraryApi {
6
+ build?: () => Promise<void> | void;
7
+ dev?: () => Promise<void> | void;
8
+ }
9
+
10
+ export type NullableChildProcess = ChildProcess | null;
11
+
12
+ export interface OrchestratorOptions {
13
+ argv?: string[];
14
+ env?: NodeJS.ProcessEnv;
15
+ }
16
+
17
+ export declare function orchestrate(options?: OrchestratorOptions): Promise<void>;
18
+ export declare function verifyBuildOutput(outDir?: string): void;
package/ui/dist/index.mjs CHANGED
@@ -377,40 +377,233 @@ function SearchResults({
377
377
 
378
378
  // ui/src/search/SearchTabs.jsx
379
379
  import React11 from "react";
380
- function SearchTabs({ type = "all", onTypeChange, types = [], counts = {} }) {
380
+ function SearchTabs({
381
+ type = "all",
382
+ onTypeChange,
383
+ types = [],
384
+ counts = {},
385
+ onOpenFilters,
386
+ activeFilterCount = 0,
387
+ filtersLabel = "Filters",
388
+ filtersOpen = false
389
+ }) {
381
390
  const orderedTypes = Array.isArray(types) ? types : [];
382
391
  const toLabel = (t) => t && t.length ? t.charAt(0).toUpperCase() + t.slice(1) : "";
383
- return /* @__PURE__ */ React11.createElement("div", { role: "tablist", "aria-label": "Search types", className: "flex items-center gap-2 border-b border-slate-200" }, orderedTypes.map((t) => {
384
- const active = String(type).toLowerCase() === String(t).toLowerCase();
385
- const cRaw = counts && Object.prototype.hasOwnProperty.call(counts, t) ? counts[t] : void 0;
386
- const c = Number.isFinite(Number(cRaw)) ? Number(cRaw) : 0;
387
- return /* @__PURE__ */ React11.createElement(
392
+ const hasFilters = typeof onOpenFilters === "function";
393
+ const filterBadge = activeFilterCount > 0 ? ` (${activeFilterCount})` : "";
394
+ return /* @__PURE__ */ React11.createElement("div", { className: "flex flex-wrap items-center justify-between gap-3 border-b border-slate-200 pb-1" }, /* @__PURE__ */ React11.createElement(
395
+ "div",
396
+ {
397
+ role: "tablist",
398
+ "aria-label": "Search types",
399
+ className: "flex items-center gap-2"
400
+ },
401
+ orderedTypes.map((t) => {
402
+ const active = String(type).toLowerCase() === String(t).toLowerCase();
403
+ const cRaw = counts && Object.prototype.hasOwnProperty.call(counts, t) ? counts[t] : void 0;
404
+ const c = Number.isFinite(Number(cRaw)) ? Number(cRaw) : 0;
405
+ return /* @__PURE__ */ React11.createElement(
406
+ "button",
407
+ {
408
+ key: t,
409
+ role: "tab",
410
+ "aria-selected": active,
411
+ type: "button",
412
+ onClick: () => onTypeChange && onTypeChange(t),
413
+ className: "px-3 py-2 text-sm rounded-t-md border-b-2 -mb-px transition-colors " + (active ? "border-brand-600 text-brand-700" : "border-transparent text-slate-600 hover:text-slate-900 hover:border-slate-300")
414
+ },
415
+ toLabel(t),
416
+ " (",
417
+ c,
418
+ ")"
419
+ );
420
+ })
421
+ ), hasFilters ? /* @__PURE__ */ React11.createElement(
422
+ "button",
423
+ {
424
+ type: "button",
425
+ onClick: () => onOpenFilters && onOpenFilters(),
426
+ "aria-expanded": filtersOpen ? "true" : "false",
427
+ className: "inline-flex items-center gap-2 rounded-md border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium text-slate-700 shadow-sm transition hover:border-brand-200 hover:bg-brand-50 hover:text-brand-700"
428
+ },
429
+ /* @__PURE__ */ React11.createElement("span", null, filtersLabel, filterBadge)
430
+ ) : null);
431
+ }
432
+
433
+ // ui/src/search/SearchFiltersDialog.jsx
434
+ import React12 from "react";
435
+ function toArray(input) {
436
+ if (!input) return [];
437
+ if (Array.isArray(input)) return input;
438
+ return [input];
439
+ }
440
+ function normalizeSelected(selected = {}) {
441
+ const map = /* @__PURE__ */ new Map();
442
+ if (selected && typeof selected === "object") {
443
+ Object.keys(selected).forEach((key) => {
444
+ const vals = new Set(toArray(selected[key]).map((v) => String(v)));
445
+ if (vals.size) map.set(String(key), vals);
446
+ });
447
+ }
448
+ return map;
449
+ }
450
+ function facetMatches(values = [], query) {
451
+ const q = String(query || "").trim().toLowerCase();
452
+ if (!q) return values;
453
+ const starts = [];
454
+ const contains = [];
455
+ values.forEach((entry) => {
456
+ if (!entry || !entry.value) return;
457
+ const value = String(entry.value);
458
+ const slug = String(entry.slug || entry.value || "");
459
+ const match = value.toLowerCase();
460
+ if (match.startsWith(q))
461
+ starts.push({ value, slug, doc_count: entry.doc_count });
462
+ else if (match.includes(q))
463
+ contains.push({ value, slug, doc_count: entry.doc_count });
464
+ });
465
+ return [...starts, ...contains].slice(0, 10);
466
+ }
467
+ function FacetSection({ facet, selected, onToggle }) {
468
+ if (!facet || !facet.label || !Array.isArray(facet.values)) return null;
469
+ const { label, slug, values } = facet;
470
+ const selectedValues = selected.get(String(slug)) || /* @__PURE__ */ new Set();
471
+ const checkboxId = (valueSlug) => `filter-${slug}-${valueSlug}`;
472
+ const hasSelection = selectedValues.size > 0;
473
+ const [quickQuery, setQuickQuery] = React12.useState("");
474
+ const hasQuery = quickQuery.trim().length > 0;
475
+ const filteredValues = React12.useMemo(
476
+ () => facetMatches(values, quickQuery),
477
+ [values, quickQuery]
478
+ );
479
+ return /* @__PURE__ */ React12.createElement(
480
+ "details",
481
+ {
482
+ className: "rounded-lg border border-slate-200 bg-slate-50",
483
+ open: hasSelection
484
+ },
485
+ /* @__PURE__ */ React12.createElement("summary", { className: "flex cursor-pointer items-center justify-between gap-3 px-4 py-3 text-sm font-medium text-slate-900" }, /* @__PURE__ */ React12.createElement("span", null, label), /* @__PURE__ */ React12.createElement("span", { className: "text-xs font-normal text-slate-500" }, values.length)),
486
+ /* @__PURE__ */ React12.createElement("div", { className: "max-h-60 overflow-y-auto border-t border-slate-200 bg-white px-4 py-3 text-sm text-slate-700" }, /* @__PURE__ */ React12.createElement("div", { className: "mb-3 flex items-center gap-2" }, /* @__PURE__ */ React12.createElement(
487
+ "input",
488
+ {
489
+ type: "search",
490
+ value: quickQuery,
491
+ onChange: (event) => setQuickQuery(event.target.value),
492
+ placeholder: "Search values",
493
+ className: "flex-1 rounded-md border border-slate-300 px-2 py-1 text-sm text-slate-700 focus:border-brand focus:outline-none focus:ring-1 focus:ring-brand",
494
+ "aria-label": `Filter ${label} values`
495
+ }
496
+ ), quickQuery ? /* @__PURE__ */ React12.createElement(
388
497
  "button",
389
498
  {
390
- key: t,
391
- role: "tab",
392
- "aria-selected": active,
393
499
  type: "button",
394
- onClick: () => onTypeChange && onTypeChange(t),
395
- className: "px-3 py-2 text-sm rounded-t-md border-b-2 -mb-px transition-colors " + (active ? "border-brand-600 text-brand-700" : "border-transparent text-slate-600 hover:text-slate-900 hover:border-slate-300")
500
+ onClick: () => setQuickQuery(""),
501
+ className: "rounded-md border border-slate-200 px-2 py-1 text-xs text-slate-600 transition hover:bg-slate-100"
396
502
  },
397
- toLabel(t),
398
- " (",
399
- c,
400
- ")"
401
- );
402
- }));
503
+ "Clear"
504
+ ) : null), hasQuery && !filteredValues.length ? /* @__PURE__ */ React12.createElement("p", { className: "mb-3 text-xs text-slate-400" }, "No matches found.") : null, /* @__PURE__ */ React12.createElement("ul", { className: "space-y-2", style: { padding: 0 } }, filteredValues.map((entry) => {
505
+ const valueSlug = String(entry.slug || entry.value || "");
506
+ const isChecked = selectedValues.has(valueSlug);
507
+ const inputId = checkboxId(valueSlug);
508
+ return /* @__PURE__ */ React12.createElement("li", { key: valueSlug, className: "flex items-start gap-2" }, /* @__PURE__ */ React12.createElement(
509
+ "input",
510
+ {
511
+ id: inputId,
512
+ type: "checkbox",
513
+ className: "mt-1 h-4 w-4 rounded border-slate-300 text-brand focus:ring-brand",
514
+ checked: isChecked,
515
+ onChange: (event) => {
516
+ const nextChecked = !!event.target.checked;
517
+ if (onToggle) onToggle(slug, valueSlug, nextChecked);
518
+ }
519
+ }
520
+ ), /* @__PURE__ */ React12.createElement(
521
+ "label",
522
+ {
523
+ htmlFor: inputId,
524
+ className: "flex flex-1 flex-col gap-0.5"
525
+ },
526
+ /* @__PURE__ */ React12.createElement("span", null, entry.value, " ", Number.isFinite(entry.doc_count) ? /* @__PURE__ */ React12.createElement("span", { className: "text-xs text-slate-500" }, "(", entry.doc_count, ")") : null)
527
+ ));
528
+ }), !filteredValues.length && !hasQuery ? /* @__PURE__ */ React12.createElement("li", { className: "text-xs text-slate-400" }, "No values available.") : null))
529
+ );
530
+ }
531
+ function SearchFiltersDialog(props = {}) {
532
+ const {
533
+ open = false,
534
+ onOpenChange,
535
+ facets = [],
536
+ selected = {},
537
+ onToggle,
538
+ onClear,
539
+ title = "Filters",
540
+ subtitle = "Refine results by metadata"
541
+ } = props;
542
+ const selectedMap = normalizeSelected(selected);
543
+ const activeCount = Array.from(selectedMap.values()).reduce(
544
+ (total, set) => total + set.size,
545
+ 0
546
+ );
547
+ if (!open) return null;
548
+ return /* @__PURE__ */ React12.createElement(
549
+ "div",
550
+ {
551
+ role: "dialog",
552
+ "aria-modal": "true",
553
+ className: "fixed inset-0 z-50 flex items-start justify-center bg-slate-900/50 px-4 py-8",
554
+ onClick: (event) => {
555
+ if (event.target === event.currentTarget && onOpenChange)
556
+ onOpenChange(false);
557
+ }
558
+ },
559
+ /* @__PURE__ */ React12.createElement("div", { className: "w-full max-w-3xl overflow-hidden rounded-xl bg-white shadow-2xl" }, /* @__PURE__ */ React12.createElement("header", { className: "flex items-start justify-between gap-4 border-b border-slate-200 px-6 py-4" }, /* @__PURE__ */ React12.createElement("div", null, /* @__PURE__ */ React12.createElement("h2", { className: "text-lg font-semibold text-slate-900" }, title), /* @__PURE__ */ React12.createElement("p", { className: "text-sm text-slate-500" }, subtitle)), /* @__PURE__ */ React12.createElement(
560
+ "button",
561
+ {
562
+ type: "button",
563
+ onClick: () => onOpenChange && onOpenChange(false),
564
+ className: "rounded-md border border-transparent px-2 py-1 text-sm text-slate-600 transition hover:bg-slate-100 hover:text-slate-900"
565
+ },
566
+ "Close"
567
+ )), /* @__PURE__ */ React12.createElement("div", { className: "grid gap-4 px-6 py-6" }, Array.isArray(facets) && facets.length ? /* @__PURE__ */ React12.createElement("div", { className: "space-y-3" }, facets.map((facet) => /* @__PURE__ */ React12.createElement(
568
+ FacetSection,
569
+ {
570
+ key: facet.slug || facet.label,
571
+ facet,
572
+ selected: selectedMap,
573
+ onToggle
574
+ }
575
+ ))) : /* @__PURE__ */ React12.createElement("p", { className: "text-sm text-slate-500" }, "No filters are available for this collection.")), /* @__PURE__ */ React12.createElement("footer", { className: "flex items-center justify-between gap-4 border-t border-slate-200 px-6 py-4" }, /* @__PURE__ */ React12.createElement("div", { className: "text-sm text-slate-500" }, activeCount ? `${activeCount} filter${activeCount === 1 ? "" : "s"} applied` : "No filters applied"), /* @__PURE__ */ React12.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React12.createElement(
576
+ "button",
577
+ {
578
+ type: "button",
579
+ onClick: () => {
580
+ if (onClear) onClear();
581
+ },
582
+ disabled: !activeCount,
583
+ className: "rounded-md border border-slate-200 px-3 py-1.5 text-sm text-slate-600 transition disabled:cursor-not-allowed disabled:text-slate-400 hover:bg-slate-100"
584
+ },
585
+ "Clear all"
586
+ ), /* @__PURE__ */ React12.createElement(
587
+ "button",
588
+ {
589
+ type: "button",
590
+ onClick: () => onOpenChange && onOpenChange(false),
591
+ className: "rounded-md bg-brand px-4 py-1.5 text-sm font-semibold text-white shadow-sm transition hover:bg-brand-700"
592
+ },
593
+ "Done"
594
+ ))))
595
+ );
403
596
  }
404
597
 
405
598
  // ui/src/command/MdxCommandPalette.jsx
406
- import React15 from "react";
599
+ import React16 from "react";
407
600
 
408
601
  // ui/src/Icons.jsx
409
- import React12 from "react";
410
- var MagnifyingGlassIcon = (props) => /* @__PURE__ */ React12.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", ...props }, /* @__PURE__ */ React12.createElement("path", { d: "M456.69 421.39L362.6 327.3a173.81 173.81 0 0034.84-104.58C397.44 126.38 319.06 48 222.72 48S48 126.38 48 222.72s78.38 174.72 174.72 174.72A173.81 173.81 0 00327.3 362.6l94.09 94.09a25 25 0 0035.3-35.3zM97.92 222.72a124.8 124.8 0 11124.8 124.8 124.95 124.95 0 01-124.8-124.8z" }));
602
+ import React13 from "react";
603
+ var MagnifyingGlassIcon = (props) => /* @__PURE__ */ React13.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", ...props }, /* @__PURE__ */ React13.createElement("path", { d: "M456.69 421.39L362.6 327.3a173.81 173.81 0 0034.84-104.58C397.44 126.38 319.06 48 222.72 48S48 126.38 48 222.72s78.38 174.72 174.72 174.72A173.81 173.81 0 00327.3 362.6l94.09 94.09a25 25 0 0035.3-35.3zM97.92 222.72a124.8 124.8 0 11124.8 124.8 124.95 124.95 0 01-124.8-124.8z" }));
411
604
 
412
605
  // ui/src/search/SearchPanelForm.jsx
413
- import React13 from "react";
606
+ import React14 from "react";
414
607
  function readBasePath() {
415
608
  const normalize = (val) => {
416
609
  const raw = typeof val === "string" ? val.trim() : "";
@@ -472,17 +665,17 @@ function SearchPanelForm(props = {}) {
472
665
  inputId: inputIdProp
473
666
  } = props || {};
474
667
  const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
475
- const action = React13.useMemo(
668
+ const action = React14.useMemo(
476
669
  () => resolveSearchPath(searchPath),
477
670
  [searchPath]
478
671
  );
479
- const autoId = typeof React13.useId === "function" ? React13.useId() : void 0;
480
- const [fallbackId] = React13.useState(
672
+ const autoId = typeof React14.useId === "function" ? React14.useId() : void 0;
673
+ const [fallbackId] = React14.useState(
481
674
  () => `canopy-cmdk-${Math.random().toString(36).slice(2, 10)}`
482
675
  );
483
676
  const inputId = inputIdProp || autoId || fallbackId;
484
- const inputRef = React13.useRef(null);
485
- const focusInput = React13.useCallback(() => {
677
+ const inputRef = React14.useRef(null);
678
+ const focusInput = React14.useCallback(() => {
486
679
  const el = inputRef.current;
487
680
  if (!el) return;
488
681
  if (document.activeElement === el) return;
@@ -495,7 +688,7 @@ function SearchPanelForm(props = {}) {
495
688
  }
496
689
  }
497
690
  }, []);
498
- const handlePointerDown = React13.useCallback((event) => {
691
+ const handlePointerDown = React14.useCallback((event) => {
499
692
  const target = event.target;
500
693
  if (target && typeof target.closest === "function") {
501
694
  if (target.closest("[data-canopy-command-trigger]")) return;
@@ -503,7 +696,7 @@ function SearchPanelForm(props = {}) {
503
696
  event.preventDefault();
504
697
  focusInput();
505
698
  }, [focusInput]);
506
- return /* @__PURE__ */ React13.createElement(
699
+ return /* @__PURE__ */ React14.createElement(
507
700
  "form",
508
701
  {
509
702
  action,
@@ -511,18 +704,18 @@ function SearchPanelForm(props = {}) {
511
704
  role: "search",
512
705
  autoComplete: "off",
513
706
  spellCheck: "false",
514
- className: "group flex items-center gap-2 rounded-lg border border-slate-300 text-slate-700 shadow-sm transition w-full focus-within:ring-2 focus-within:ring-brand-500 canopy-cmdk-form",
707
+ className: "group flex items-center gap-2 rounded-lg border border-slate-300 text-slate-700 shadow-sm transition focus-within:ring-2 focus-within:ring-brand-500 canopy-cmdk-form",
515
708
  onPointerDown: handlePointerDown,
516
709
  "data-placeholder": placeholder || ""
517
710
  },
518
- /* @__PURE__ */ React13.createElement(
711
+ /* @__PURE__ */ React14.createElement(
519
712
  "label",
520
713
  {
521
714
  htmlFor: inputId,
522
715
  className: "flex items-center gap-2 flex-1 min-w-0 cursor-text canopy-cmdk-label"
523
716
  },
524
- /* @__PURE__ */ React13.createElement(MagnifyingGlassIcon, { className: "w-5 h-5 text-slate-400 group-focus-within:text-brand-500 pointer-events-none" }),
525
- /* @__PURE__ */ React13.createElement(
717
+ /* @__PURE__ */ React14.createElement(MagnifyingGlassIcon, { className: "w-5 h-5 text-slate-400 group-focus-within:text-brand-500 pointer-events-none" }),
718
+ /* @__PURE__ */ React14.createElement(
526
719
  "input",
527
720
  {
528
721
  id: inputId,
@@ -537,21 +730,21 @@ function SearchPanelForm(props = {}) {
537
730
  }
538
731
  )
539
732
  ),
540
- /* @__PURE__ */ React13.createElement(
733
+ /* @__PURE__ */ React14.createElement(
541
734
  "button",
542
735
  {
543
- type: "button",
544
- "data-canopy-command-trigger": true,
736
+ type: "submit",
737
+ "data-canopy-command-trigger": "submit",
545
738
  className: "inline-flex items-center gap-2 rounded-md border border-transparent bg-brand px-2 py-1 text-sm font-medium text-white shadow-sm transition hover:bg-brand-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-brand focus-visible:ring-offset-2"
546
739
  },
547
- /* @__PURE__ */ React13.createElement("span", null, text),
548
- /* @__PURE__ */ React13.createElement("span", { "aria-hidden": true, className: "hidden sm:inline-flex items-center gap-1 text-xs font-semibold canopy-cmdk-shortcut" }, /* @__PURE__ */ React13.createElement("span", null, "\u2318"), /* @__PURE__ */ React13.createElement("span", null, "K"))
740
+ /* @__PURE__ */ React14.createElement("span", null, text),
741
+ /* @__PURE__ */ React14.createElement("span", { "aria-hidden": true, className: "hidden sm:inline-flex items-center gap-1 text-xs font-semibold canopy-cmdk-shortcut" }, /* @__PURE__ */ React14.createElement("span", null, "\u2318"), /* @__PURE__ */ React14.createElement("span", null, "K"))
549
742
  )
550
743
  );
551
744
  }
552
745
 
553
746
  // ui/src/search/SearchPanelTeaserResults.jsx
554
- import React14 from "react";
747
+ import React15 from "react";
555
748
  function SearchPanelTeaserResults(props = {}) {
556
749
  const { style } = props || {};
557
750
  const baseStyle = {
@@ -568,7 +761,7 @@ function SearchPanelTeaserResults(props = {}) {
568
761
  overflow: "auto",
569
762
  maxHeight: "60vh"
570
763
  };
571
- return /* @__PURE__ */ React14.createElement("div", { "data-canopy-command-panel": true, style: { ...baseStyle, ...style || {} } }, /* @__PURE__ */ React14.createElement("div", { id: "cplist" }));
764
+ return /* @__PURE__ */ React15.createElement("div", { "data-canopy-command-panel": true, style: { ...baseStyle, ...style || {} } }, /* @__PURE__ */ React15.createElement("div", { id: "cplist" }));
572
765
  }
573
766
 
574
767
  // ui/src/command/MdxCommandPalette.jsx
@@ -587,11 +780,11 @@ function MdxCommandPalette(props = {}) {
587
780
  const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
588
781
  const resolvedSearchPath = resolveSearchPath(searchPath);
589
782
  const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
590
- return /* @__PURE__ */ React15.createElement("div", { "data-canopy-command": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React15.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React15.createElement("style", null, `.relative[data-canopy-panel-auto='1']:focus-within [data-canopy-command-panel]{display:block}`), /* @__PURE__ */ React15.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React15.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React15.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
783
+ return /* @__PURE__ */ React16.createElement("div", { "data-canopy-command": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React16.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React16.createElement("style", null, `.relative[data-canopy-panel-auto='1']:focus-within [data-canopy-command-panel]{display:block}`), /* @__PURE__ */ React16.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React16.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React16.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
591
784
  }
592
785
 
593
786
  // ui/src/search/SearchPanel.jsx
594
- import React16 from "react";
787
+ import React17 from "react";
595
788
  function SearchPanel(props = {}) {
596
789
  const {
597
790
  placeholder = "Search\u2026",
@@ -608,7 +801,7 @@ function SearchPanel(props = {}) {
608
801
  const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
609
802
  const resolvedSearchPath = resolveSearchPath(searchPath);
610
803
  const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
611
- return /* @__PURE__ */ React16.createElement("div", { "data-canopy-command": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React16.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React16.createElement("style", null, `.relative[data-canopy-panel-auto='1']:focus-within [data-canopy-command-panel]{display:block}`), /* @__PURE__ */ React16.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React16.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React16.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
804
+ return /* @__PURE__ */ React17.createElement("div", { "data-canopy-command": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React17.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React17.createElement("style", null, `.relative[data-canopy-panel-auto='1']:focus-within [data-canopy-command-panel]{display:block}`), /* @__PURE__ */ React17.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React17.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React17.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
612
805
  }
613
806
  export {
614
807
  Card,
@@ -617,6 +810,7 @@ export {
617
810
  GridItem,
618
811
  HelloWorld,
619
812
  MdxRelatedItems as RelatedItems,
813
+ SearchFiltersDialog,
620
814
  SearchPanel,
621
815
  SearchPanelForm,
622
816
  SearchPanelTeaserResults,