@canopy-iiif/app 0.8.3 → 0.8.4
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/lib/build/build.js +2 -0
- package/lib/build/dev.js +38 -22
- package/lib/build/mdx.js +12 -2
- package/lib/build/pages.js +15 -1
- package/lib/components/navigation.js +308 -0
- package/lib/page-context.js +14 -0
- package/package.json +1 -1
- package/ui/dist/index.mjs +4 -5
- package/ui/dist/index.mjs.map +2 -2
- package/ui/dist/server.mjs +126 -37
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/components/_sub-navigation.scss +76 -0
- package/ui/styles/components/index.scss +1 -0
- package/ui/styles/components/search/_results.scss +41 -4
- package/ui/styles/index.css +110 -0
package/ui/dist/index.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/HelloWorld.jsx", "../src/layout/Card.jsx", "../src/layout/Grid.jsx", "../src/iiif/Viewer.jsx", "../src/iiif/Slider.jsx", "../src/iiif/MdxRelatedItems.jsx", "../src/search/MdxSearchResults.jsx", "../src/search/SearchSummary.jsx", "../src/search/MdxSearchTabs.jsx", "../src/search/SearchResults.jsx", "../src/search/SearchTabs.jsx", "../src/search/SearchFiltersDialog.jsx", "../src/search-form/MdxSearchFormModal.jsx", "../src/Icons.jsx", "../src/search/SearchPanelForm.jsx", "../src/search/SearchPanelTeaserResults.jsx", "../src/search/SearchPanel.jsx"],
|
|
4
|
-
"sourcesContent": ["import React from \"react\";\n\nexport const HelloWorld = () => {\n return <div>Hello, World!</div>;\n};\n", "import React, { useEffect, useRef, useState } from \"react\";\n\n/**\n * Card\n *\n * Renders an anchor wrapping a figure with an image and caption.\n * Minimal styling; consumers can override via className/style.\n *\n * Props:\n * - href: string (required) \u2014 link target\n * - src: string (optional) \u2014 image source\n * - alt: string (optional) \u2014 image alt text (falls back to title)\n * - title: string (optional) \u2014 primary caption text\n * - subtitle: string (optional) \u2014 secondary caption text\n * - className: string (optional)\n * - style: object (optional)\n * - children: ReactNode (optional) \u2014 appended inside figcaption\n */\nexport default function Card({\n href,\n src,\n alt,\n title,\n subtitle,\n // Optional intrinsic dimensions or aspect ratio to compute a responsive height\n imgWidth,\n imgHeight,\n aspectRatio,\n className,\n style,\n children,\n ...rest\n}) {\n const containerRef = useRef(null);\n const [inView, setInView] = useState(false);\n const [imageLoaded, setImageLoaded] = useState(false);\n\n /**\n * Use IntersectionObserver to detect when the card enters the viewport.\n * When in view, setInView(true) to trigger image loading.\n * If IntersectionObserver is not supported, default to inView=true.\n */\n useEffect(() => {\n if (!containerRef.current) return;\n if (typeof IntersectionObserver !== \"function\") {\n setInView(true);\n return;\n }\n const el = containerRef.current;\n const obs = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n setInView(true);\n try {\n obs.unobserve(el);\n } catch (_) {}\n break;\n }\n }\n },\n { root: null, rootMargin: \"100px\", threshold: 0.1 }\n );\n try {\n obs.observe(el);\n } catch (_) {}\n return () => {\n try {\n obs.disconnect();\n } catch (_) {}\n };\n }, []);\n\n /**\n * Calculate aspect ratio and padding percent for responsive image container.\n */\n const w = Number(imgWidth);\n const h = Number(imgHeight);\n const ratio =\n Number.isFinite(Number(aspectRatio)) && Number(aspectRatio) > 0\n ? Number(aspectRatio)\n : Number.isFinite(w) && w > 0 && Number.isFinite(h) && h > 0\n ? w / h\n : undefined;\n const paddingPercent = ratio ? 100 / ratio : 100;\n\n /**\n * Caption element (figcaption), rendered if title, subtitle, or children are provided.\n */\n const caption = (\n <figcaption>\n {title && <span>{title}</span>}\n {subtitle && <span>{subtitle}</span>}\n {children}\n </figcaption>\n );\n\n return (\n <a\n href={href}\n className={[\"canopy-card\", className].filter(Boolean).join(\" \")}\n style={style}\n ref={containerRef}\n data-aspect-ratio={ratio}\n data-in-view={inView ? \"true\" : \"false\"}\n data-image-loaded={imageLoaded ? \"true\" : \"false\"}\n {...rest}\n >\n <figure>\n {src ? (\n ratio ? (\n <div\n className=\"canopy-card-media\"\n style={{ \"--canopy-card-padding\": `${paddingPercent}%` }}\n >\n {inView ? (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n />\n ) : null}\n </div>\n ) : (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n className=\"canopy-card-image\"\n />\n )\n ) : null}\n {caption}\n </figure>\n </a>\n );\n}\n", "import Masonry from \"react-masonry-css\";\nimport React from \"react\";\n\n// Simple item wrapper to provide consistent spacing between items.\nexport function GridItem({ children, className = \"\", style = {}, ...rest }) {\n return (\n <div\n className={`canopy-grid-item ${className}`.trim()}\n style={style}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Grid (Masonry)\n *\n * Lightweight wrapper around `react-masonry-css` with sensible defaults\n * and inline styles so it works without a global CSS pipeline.\n *\n * Props:\n * - breakpointCols: number | object \u2014 columns per breakpoint (react-masonry-css prop)\n * - gap: CSS length string \u2014 spacing between items/columns (default '1rem')\n * - paddingY: CSS length string \u2014 vertical padding for the grid (default '0')\n * - className, style \u2014 forwarded to container\n * - columnClassName \u2014 forwarded to Masonry (defaults to 'canopy-grid-column')\n * - children \u2014 usually a list of <GridItem> elements\n */\nexport default function Grid({\n breakpointCols,\n gap = \"2rem\",\n paddingY = \"0\",\n className = \"\",\n style = {},\n columnClassName = \"canopy-grid-column\",\n children,\n ...rest\n}) {\n const cols = breakpointCols || {\n default: 6,\n 1280: 5,\n 1024: 4,\n 768: 3,\n 640: 2,\n };\n const vars = { \"--grid-gap\": gap, \"--grid-padding-y\": paddingY };\n\n return (\n <div className=\"canopy-grid-wrap\">\n {/* Scoped styles so the component works standalone */}\n <style\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html: `\n .canopy-grid { display: flex; width: auto; position: relative; padding: var(--grid-padding-y, 0) 0; z-index: 1; }\n .canopy-grid .${columnClassName} { margin-left: var(--grid-gap, 1rem); }\n .canopy-grid .${columnClassName}:first-child { margin-left: 0; }\n .canopy-grid-item { margin-bottom: var(--grid-gap, 1rem); }\n `,\n }}\n />\n <Masonry\n breakpointCols={cols}\n className={`canopy-grid ${className}`.trim()}\n columnClassName={columnClassName}\n style={{ ...vars, ...style }}\n {...rest}\n >\n {children}\n </Masonry>\n </div>\n );\n}\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's viewer. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\n\n// Default Clover viewer options; can be overridden per-usage via props.options\nconst DEFAULT_VIEWER_OPTIONS = {\n showDownload: false,\n showIIIFBadge: false,\n showTitle: false,\n informationPanel: {\n open: false,\n renderAbout: false,\n renderToggle: false,\n },\n};\n\nfunction isPlainObject(val) {\n return val && typeof val === \"object\" && !Array.isArray(val);\n}\n\nfunction deepMerge(base, override) {\n if (!isPlainObject(base)) return override;\n const out = { ...base };\n if (!isPlainObject(override)) return out;\n for (const key of Object.keys(override)) {\n const a = base[key];\n const b = override[key];\n if (isPlainObject(a) && isPlainObject(b)) out[key] = deepMerge(a, b);\n else out[key] = b;\n }\n return out;\n}\n\nexport const Viewer = (props) => {\n const [CloverViewer, setCloverViewer] = useState(null);\n const mergedOptions = deepMerge(\n DEFAULT_VIEWER_OPTIONS,\n props && props.options\n );\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/viewer\")\n .then((mod) => {\n if (!mounted) return;\n // Loaded Clover viewer dynamically in the browser\n const Comp = mod && (mod.default || mod.Viewer || mod);\n setCloverViewer(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverViewer) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n const p = { ...(props || {}) };\n if (mergedOptions) p.options = mergedOptions;\n json = JSON.stringify(p);\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-viewer=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverViewer {...props} options={mergedOptions} />;\n};\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's slider. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\nexport const Slider = (props) => {\n const [CloverSlider, setCloverSlider] = useState(null);\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/slider\")\n .then((mod) => {\n if (!mounted) return;\n console.log(mod);\n const Comp = mod && (mod.default || mod.Slider || mod);\n setCloverSlider(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverSlider) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-slider=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverSlider {...props} />;\n};\n", "import React from 'react';\n\n// SSR-safe placeholder for RelatedItems. Hydrated by canopy-related-items.js + canopy-slider.js\nexport default function MdxRelatedItems(props) {\n let json = '{}';\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = '{}';\n }\n return (\n <div data-canopy-related-items=\"1\" className=\"not-prose\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n", "import React from 'react';\n\nexport default function MdxSearchResults(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-results=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function SearchSummary(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-summary=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function MdxSearchTabs(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-tabs=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import Grid, { GridItem } from \"../layout/Grid.jsx\";\n\nimport Card from \"../layout/Card.jsx\";\nimport React from \"react\";\n\nexport default function SearchResults({\n results = [],\n type = \"all\",\n layout = \"grid\",\n}) {\n if (!results.length) {\n return (\n <div className=\"text-slate-600\">\n <em>No results</em>\n </div>\n );\n }\n\n if (layout === \"list\") {\n return (\n <ul id=\"search-results\" className=\"space-y-3\">\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <li\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </li>\n );\n })}\n </ul>\n );\n }\n\n // Default: grid (masonry)\n return (\n <div id=\"search-results\">\n <Grid>\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <GridItem\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </GridItem>\n );\n })}\n </Grid>\n </div>\n );\n}\n", "import React from \"react\";\n\nexport default function SearchTabs({\n type = \"all\",\n onTypeChange,\n types = [],\n counts = {},\n onOpenFilters,\n activeFilterCount = 0,\n filtersLabel = \"Filters\",\n filtersOpen = false,\n}) {\n const orderedTypes = Array.isArray(types) ? types : [];\n const toLabel = (t) =>\n t && t.length ? t.charAt(0).toUpperCase() + t.slice(1) : \"\";\n const hasFilters = typeof onOpenFilters === \"function\";\n const filterBadge = activeFilterCount > 0 ? ` (${activeFilterCount})` : \"\";\n return (\n <div className=\"flex flex-wrap items-center justify-between gap-3 border-b border-slate-200 pb-1\">\n <div\n role=\"tablist\"\n aria-label=\"Search types\"\n className=\"flex items-center gap-2\"\n >\n {orderedTypes.map((t) => {\n const active = String(type).toLowerCase() === String(t).toLowerCase();\n const cRaw =\n counts && Object.prototype.hasOwnProperty.call(counts, t)\n ? counts[t]\n : undefined;\n const c = Number.isFinite(Number(cRaw)) ? Number(cRaw) : 0;\n return (\n <button\n key={t}\n role=\"tab\"\n aria-selected={active}\n type=\"button\"\n onClick={() => onTypeChange && onTypeChange(t)}\n className={\n \"px-3 py-2 text-sm rounded-t-md border-b-2 -mb-px transition-colors \" +\n (active\n ? \"border-brand-600 text-brand-700\"\n : \"border-transparent text-slate-600 hover:text-slate-900 hover:border-slate-300\")\n }\n >\n {toLabel(t)} ({c})\n </button>\n );\n })}\n </div>\n {hasFilters ? (\n <button\n type=\"button\"\n onClick={() => onOpenFilters && onOpenFilters()}\n aria-expanded={filtersOpen ? \"true\" : \"false\"}\n 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\"\n >\n <span>\n {filtersLabel}\n {filterBadge}\n </span>\n </button>\n ) : null}\n </div>\n );\n}\n", "import React from \"react\";\n\nfunction toArray(input) {\n if (!input) return [];\n if (Array.isArray(input)) return input;\n return [input];\n}\n\nfunction normalizeSelected(selected = {}) {\n const map = new Map();\n if (selected && typeof selected === \"object\") {\n Object.keys(selected).forEach((key) => {\n const vals = new Set(toArray(selected[key]).map((v) => String(v)));\n if (vals.size) map.set(String(key), vals);\n });\n }\n return map;\n}\n\nfunction facetMatches(values = [], query) {\n const q = String(query || \"\")\n .trim()\n .toLowerCase();\n if (!q) return values;\n const starts = [];\n const contains = [];\n values.forEach((entry) => {\n if (!entry || !entry.value) return;\n const value = String(entry.value);\n const slug = String(entry.slug || entry.value || \"\");\n const match = value.toLowerCase();\n if (match.startsWith(q))\n starts.push({value, slug, doc_count: entry.doc_count});\n else if (match.includes(q))\n contains.push({value, slug, doc_count: entry.doc_count});\n });\n return [...starts, ...contains].slice(0, 10);\n}\n\nfunction FacetSection({facet, selected, onToggle}) {\n if (!facet || !facet.label || !Array.isArray(facet.values)) return null;\n const {label, slug, values} = facet;\n const selectedValues = selected.get(String(slug)) || new Set();\n const checkboxId = (valueSlug) => `filter-${slug}-${valueSlug}`;\n const hasSelection = selectedValues.size > 0;\n const [quickQuery, setQuickQuery] = React.useState(\"\");\n const hasQuery = quickQuery.trim().length > 0;\n const filteredValues = React.useMemo(\n () => facetMatches(values, quickQuery),\n [values, quickQuery]\n );\n\n return (\n <details\n className=\"canopy-search-filters__facet\"\n open={hasSelection}\n >\n <summary className=\"canopy-search-filters__facet-summary\">\n <span>{label}</span>\n <span className=\"canopy-search-filters__facet-count\">\n {values.length}\n </span>\n </summary>\n <div className=\"canopy-search-filters__facet-content\">\n <div className=\"canopy-search-filters__quick\">\n <input\n type=\"search\"\n value={quickQuery}\n onChange={(event) => setQuickQuery(event.target.value)}\n placeholder=\"Search values\"\n className=\"canopy-search-filters__quick-input\"\n aria-label={`Filter ${label} values`}\n />\n {quickQuery ? (\n <button\n type=\"button\"\n onClick={() => setQuickQuery(\"\")}\n className=\"canopy-search-filters__quick-clear\"\n >\n Clear\n </button>\n ) : null}\n </div>\n {hasQuery && !filteredValues.length ? (\n <p className=\"canopy-search-filters__facet-notice\">No matches found.</p>\n ) : null}\n <ul className=\"canopy-search-filters__facet-list\">\n {filteredValues.map((entry) => {\n const valueSlug = String(entry.slug || entry.value || \"\");\n const isChecked = selectedValues.has(valueSlug);\n const inputId = checkboxId(valueSlug);\n return (\n <li key={valueSlug} className=\"canopy-search-filters__facet-item\">\n <input\n id={inputId}\n type=\"checkbox\"\n className=\"canopy-search-filters__facet-checkbox\"\n checked={isChecked}\n onChange={(event) => {\n const nextChecked = !!event.target.checked;\n if (onToggle) onToggle(slug, valueSlug, nextChecked);\n }}\n />\n <label\n htmlFor={inputId}\n className=\"canopy-search-filters__facet-label\"\n >\n <span>\n {entry.value}{\" \"}\n {Number.isFinite(entry.doc_count) ? (\n <span className=\"canopy-search-filters__facet-count\">\n ({entry.doc_count})\n </span>\n ) : null}\n </span>\n </label>\n </li>\n );\n })}\n {!filteredValues.length && !hasQuery ? (\n <li className=\"canopy-search-filters__facet-empty\">No values available.</li>\n ) : null}\n </ul>\n </div>\n </details>\n );\n}\n\nexport default function SearchFiltersDialog(props = {}) {\n const {\n open = false,\n onOpenChange,\n facets = [],\n selected = {},\n onToggle,\n onClear,\n title = \"Filters\",\n subtitle = \"Refine results by metadata\",\n } = props;\n\n const selectedMap = normalizeSelected(selected);\n const activeCount = Array.from(selectedMap.values()).reduce(\n (total, set) => total + set.size,\n 0\n );\n\n if (!open) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"canopy-search-filters-overlay\"\n onClick={(event) => {\n if (event.target === event.currentTarget && onOpenChange)\n onOpenChange(false);\n }}\n >\n <div className=\"canopy-search-filters\">\n <header className=\"canopy-search-filters__header\">\n <div>\n <h2 className=\"canopy-search-filters__title\">{title}</h2>\n <p className=\"canopy-search-filters__subtitle\">{subtitle}</p>\n </div>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"canopy-search-filters__close\"\n >\n Close\n </button>\n </header>\n <div className=\"canopy-search-filters__body\">\n {Array.isArray(facets) && facets.length ? (\n <div className=\"canopy-search-filters__facets\">\n {facets.map((facet) => (\n <FacetSection\n key={facet.slug || facet.label}\n facet={facet}\n selected={selectedMap}\n onToggle={onToggle}\n />\n ))}\n </div>\n ) : (\n <p className=\"canopy-search-filters__empty\">\n No filters are available for this collection.\n </p>\n )}\n </div>\n <footer className=\"canopy-search-filters__footer\">\n <div>\n {activeCount\n ? `${activeCount} filter${activeCount === 1 ? \"\" : \"s\"} applied`\n : \"No filters applied\"}\n </div>\n <div className=\"canopy-search-filters__footer-actions\">\n <button\n type=\"button\"\n onClick={() => {\n if (onClear) onClear();\n }}\n disabled={!activeCount}\n className=\"canopy-search-filters__button canopy-search-filters__button--secondary\"\n >\n Clear all\n </button>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"canopy-search-filters__button canopy-search-filters__button--primary\"\n >\n Done\n </button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from '../search/SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from '../search/SearchPanelTeaserResults.jsx';\n\n// SSR-safe placeholder for the search form modal, composed from SearchPanel parts.\n// This ensures a single JSX source of truth for form/panel markup.\nexport default function MdxSearchFormModal(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'page'],\n button = true, // kept for backward compat; ignored by teaser form\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n return (\n <div data-canopy-search-form className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n", "import React from \"react\";\n\nexport const MagnifyingGlassIcon = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" {...props}>\n <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\" />\n </svg>\n);\n", "import {MagnifyingGlassIcon} from \"../Icons\";\nimport React from \"react\";\n\nfunction readBasePath() {\n const normalize = (val) => {\n const raw = typeof val === \"string\" ? val.trim() : \"\";\n if (!raw) return \"\";\n return raw.replace(/\\/+$/, \"\");\n };\n try {\n if (typeof window !== \"undefined\" && window.CANOPY_BASE_PATH != null) {\n const fromWindow = normalize(window.CANOPY_BASE_PATH);\n if (fromWindow) return fromWindow;\n }\n } catch (_) {}\n try {\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.CANOPY_BASE_PATH != null\n ) {\n const fromGlobal = normalize(globalThis.CANOPY_BASE_PATH);\n if (fromGlobal) return fromGlobal;\n }\n } catch (_) {}\n try {\n if (\n typeof process !== \"undefined\" &&\n process.env &&\n process.env.CANOPY_BASE_PATH\n ) {\n const fromEnv = normalize(process.env.CANOPY_BASE_PATH);\n if (fromEnv) return fromEnv;\n }\n } catch (_) {}\n return \"\";\n}\n\nfunction isAbsoluteUrl(href) {\n try {\n return /^https?:/i.test(String(href || \"\"));\n } catch (_) {\n return false;\n }\n}\n\nexport function resolveSearchPath(pathValue) {\n let raw = typeof pathValue === \"string\" ? pathValue.trim() : \"\";\n if (!raw) raw = \"/search\";\n if (isAbsoluteUrl(raw)) return raw;\n const normalizedPath = raw.startsWith(\"/\") ? raw : `/${raw}`;\n const base = readBasePath();\n if (!base) return normalizedPath;\n const baseWithLead = base.startsWith(\"/\") ? base : `/${base}`;\n const baseTrimmed = baseWithLead.replace(/\\/+$/, \"\");\n if (!baseTrimmed) return normalizedPath;\n if (\n normalizedPath === baseTrimmed ||\n normalizedPath.startsWith(`${baseTrimmed}/`)\n ) {\n return normalizedPath;\n }\n const pathTrimmed = normalizedPath.replace(/^\\/+/, \"\");\n return `${baseTrimmed}/${pathTrimmed}`;\n}\n\nexport default function SearchPanelForm(props = {}) {\n const {\n placeholder = \"Search\u2026\",\n buttonLabel = \"Search\",\n label,\n searchPath = \"/search\",\n inputId: inputIdProp,\n } = props || {};\n\n const text =\n typeof label === \"string\" && label.trim() ? label.trim() : buttonLabel;\n const action = React.useMemo(\n () => resolveSearchPath(searchPath),\n [searchPath]\n );\n const autoId = typeof React.useId === \"function\" ? React.useId() : undefined;\n const [fallbackId] = React.useState(\n () => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`\n );\n const inputId = inputIdProp || autoId || fallbackId;\n const inputRef = React.useRef(null);\n const [hasValue, setHasValue] = React.useState(false);\n\n const focusInput = React.useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (document.activeElement === el) return;\n try {\n el.focus({preventScroll: true});\n } catch (_) {\n try {\n el.focus();\n } catch (_) {}\n }\n }, []);\n\n const handlePointerDown = React.useCallback(\n (event) => {\n const target = event.target;\n if (target && typeof target.closest === \"function\") {\n if (target.closest(\"[data-canopy-search-form-trigger]\")) return;\n }\n event.preventDefault();\n focusInput();\n },\n [focusInput]\n );\n\n React.useEffect(() => {\n const el = inputRef.current;\n if (!el) return;\n if (el.value && el.value.trim()) {\n setHasValue(true);\n }\n }, []);\n\n const handleInputChange = React.useCallback((event) => {\n const nextHasValue = Boolean(event?.target?.value && event.target.value.trim());\n setHasValue(nextHasValue);\n }, []);\n\n return (\n <form\n action={action}\n method=\"get\"\n role=\"search\"\n autoComplete=\"off\"\n spellCheck=\"false\"\n className=\"canopy-search-form canopy-search-form-shell\"\n onPointerDown={handlePointerDown}\n data-placeholder={placeholder || \"\"}\n data-has-value={hasValue ? \"1\" : \"0\"}\n >\n <label\n htmlFor={inputId}\n className=\"canopy-search-form__label\"\n >\n <MagnifyingGlassIcon className=\"canopy-search-form__icon\" />\n <input\n id={inputId}\n type=\"search\"\n name=\"q\"\n inputMode=\"search\"\n data-canopy-search-form-input\n placeholder={placeholder}\n className=\"canopy-search-form__input\"\n aria-label=\"Search\"\n ref={inputRef}\n onChange={handleInputChange}\n onInput={handleInputChange}\n />\n </label>\n <button\n type=\"submit\"\n data-canopy-search-form-trigger=\"submit\"\n className=\"canopy-search-form__submit\"\n >\n <span>{text}</span>\n <span aria-hidden className=\"canopy-search-form__shortcut\">\n <span>\u2318</span>\n <span>K</span>\n </span>\n </button>\n </form>\n );\n}\n", "import React from \"react\";\n\n// SSR placeholder for teaser results panel; the runtime controls visibility and content.\nexport default function SearchPanelTeaserResults(props = {}) {\n const { style, className } = props || {};\n const classes = [\"canopy-search-teaser\", className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n data-canopy-search-form-panel\n className={classes || undefined}\n style={style}\n >\n <div id=\"cplist\" />\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from './SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from './SearchPanelTeaserResults.jsx';\n\n// High-level SearchPanel composed of a teaser form and teaser results panel.\n// Encodes configuration as JSON for the client runtime.\nexport default function SearchPanel(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'docs', 'page'],\n // Kept for backward compat; form always renders submit\n button = true, // eslint-disable-line no-unused-vars\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n\n return (\n <div data-canopy-search-form className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import React from \"react\";\n\nexport const HelloWorld = () => {\n return <div>Hello, World!</div>;\n};\n", "import React, { useEffect, useRef, useState } from \"react\";\n\n/**\n * Card\n *\n * Renders an anchor wrapping a figure with an image and caption.\n * Minimal styling; consumers can override via className/style.\n *\n * Props:\n * - href: string (required) \u2014 link target\n * - src: string (optional) \u2014 image source\n * - alt: string (optional) \u2014 image alt text (falls back to title)\n * - title: string (optional) \u2014 primary caption text\n * - subtitle: string (optional) \u2014 secondary caption text\n * - className: string (optional)\n * - style: object (optional)\n * - children: ReactNode (optional) \u2014 appended inside figcaption\n */\nexport default function Card({\n href,\n src,\n alt,\n title,\n subtitle,\n // Optional intrinsic dimensions or aspect ratio to compute a responsive height\n imgWidth,\n imgHeight,\n aspectRatio,\n className,\n style,\n children,\n ...rest\n}) {\n const containerRef = useRef(null);\n const [inView, setInView] = useState(false);\n const [imageLoaded, setImageLoaded] = useState(false);\n\n /**\n * Use IntersectionObserver to detect when the card enters the viewport.\n * When in view, setInView(true) to trigger image loading.\n * If IntersectionObserver is not supported, default to inView=true.\n */\n useEffect(() => {\n if (!containerRef.current) return;\n if (typeof IntersectionObserver !== \"function\") {\n setInView(true);\n return;\n }\n const el = containerRef.current;\n const obs = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n setInView(true);\n try {\n obs.unobserve(el);\n } catch (_) {}\n break;\n }\n }\n },\n { root: null, rootMargin: \"100px\", threshold: 0.1 }\n );\n try {\n obs.observe(el);\n } catch (_) {}\n return () => {\n try {\n obs.disconnect();\n } catch (_) {}\n };\n }, []);\n\n /**\n * Calculate aspect ratio and padding percent for responsive image container.\n */\n const w = Number(imgWidth);\n const h = Number(imgHeight);\n const ratio =\n Number.isFinite(Number(aspectRatio)) && Number(aspectRatio) > 0\n ? Number(aspectRatio)\n : Number.isFinite(w) && w > 0 && Number.isFinite(h) && h > 0\n ? w / h\n : undefined;\n const paddingPercent = ratio ? 100 / ratio : 100;\n\n /**\n * Caption element (figcaption), rendered if title, subtitle, or children are provided.\n */\n const caption = (\n <figcaption>\n {title && <span>{title}</span>}\n {subtitle && <span>{subtitle}</span>}\n {children}\n </figcaption>\n );\n\n return (\n <a\n href={href}\n className={[\"canopy-card\", className].filter(Boolean).join(\" \")}\n style={style}\n ref={containerRef}\n data-aspect-ratio={ratio}\n data-in-view={inView ? \"true\" : \"false\"}\n data-image-loaded={imageLoaded ? \"true\" : \"false\"}\n {...rest}\n >\n <figure>\n {src ? (\n ratio ? (\n <div\n className=\"canopy-card-media\"\n style={{ \"--canopy-card-padding\": `${paddingPercent}%` }}\n >\n {inView ? (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n />\n ) : null}\n </div>\n ) : (\n <img\n src={src}\n alt={alt || title || \"\"}\n loading=\"lazy\"\n onLoad={() => setImageLoaded(true)}\n onError={() => setImageLoaded(true)}\n className=\"canopy-card-image\"\n />\n )\n ) : null}\n {caption}\n </figure>\n </a>\n );\n}\n", "import Masonry from \"react-masonry-css\";\nimport React from \"react\";\n\n// Simple item wrapper to provide consistent spacing between items.\nexport function GridItem({children, className = \"\", style = {}, ...rest}) {\n return (\n <div\n className={`canopy-grid-item ${className}`.trim()}\n style={style}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Grid (Masonry)\n *\n * Lightweight wrapper around `react-masonry-css` with sensible defaults\n * and inline styles so it works without a global CSS pipeline.\n *\n * Props:\n * - breakpointCols: number | object \u2014 columns per breakpoint (react-masonry-css prop)\n * - gap: CSS length string \u2014 spacing between items/columns (default '1rem')\n * - paddingY: CSS length string \u2014 vertical padding for the grid (default '0')\n * - className, style \u2014 forwarded to container\n * - columnClassName \u2014 forwarded to Masonry (defaults to 'canopy-grid-column')\n * - children \u2014 usually a list of <GridItem> elements\n */\nexport default function Grid({\n breakpointCols,\n gap = \"1.618rem\",\n paddingY = \"0\",\n className = \"\",\n style = {},\n columnClassName = \"canopy-grid-column\",\n children,\n ...rest\n}) {\n const cols = breakpointCols || {\n default: 6,\n 1280: 5,\n 1024: 4,\n 768: 3,\n 640: 2,\n };\n const vars = {\"--grid-gap\": gap, \"--grid-padding-y\": paddingY};\n\n return (\n <div className=\"canopy-grid-wrap\">\n {/* Scoped styles so the component works standalone */}\n <style\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html: `\n .canopy-grid { display: flex; width: auto; position: relative; padding: var(--grid-padding-y, 0) 0; z-index: 1; }\n .canopy-grid .${columnClassName} { margin-left: var(--grid-gap, 1rem); }\n .canopy-grid .${columnClassName}:first-child { margin-left: 0; }\n .canopy-grid-item { margin-bottom: var(--grid-gap, 1rem); }\n `,\n }}\n />\n <Masonry\n breakpointCols={cols}\n className={`canopy-grid ${className}`.trim()}\n columnClassName={columnClassName}\n style={{...vars, ...style}}\n {...rest}\n >\n {children}\n </Masonry>\n </div>\n );\n}\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's viewer. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\n\n// Default Clover viewer options; can be overridden per-usage via props.options\nconst DEFAULT_VIEWER_OPTIONS = {\n showDownload: false,\n showIIIFBadge: false,\n showTitle: false,\n informationPanel: {\n open: false,\n renderAbout: false,\n renderToggle: false,\n },\n};\n\nfunction isPlainObject(val) {\n return val && typeof val === \"object\" && !Array.isArray(val);\n}\n\nfunction deepMerge(base, override) {\n if (!isPlainObject(base)) return override;\n const out = { ...base };\n if (!isPlainObject(override)) return out;\n for (const key of Object.keys(override)) {\n const a = base[key];\n const b = override[key];\n if (isPlainObject(a) && isPlainObject(b)) out[key] = deepMerge(a, b);\n else out[key] = b;\n }\n return out;\n}\n\nexport const Viewer = (props) => {\n const [CloverViewer, setCloverViewer] = useState(null);\n const mergedOptions = deepMerge(\n DEFAULT_VIEWER_OPTIONS,\n props && props.options\n );\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/viewer\")\n .then((mod) => {\n if (!mounted) return;\n // Loaded Clover viewer dynamically in the browser\n const Comp = mod && (mod.default || mod.Viewer || mod);\n setCloverViewer(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverViewer) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n const p = { ...(props || {}) };\n if (mergedOptions) p.options = mergedOptions;\n json = JSON.stringify(p);\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-viewer=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverViewer {...props} options={mergedOptions} />;\n};\n", "import React, { useEffect, useState } from \"react\";\n\n// SSR-safe wrapper around Clover's slider. Clover touches the DOM at import time,\n// so we dynamically import it only in the browser.\nexport const Slider = (props) => {\n const [CloverSlider, setCloverSlider] = useState(null);\n\n useEffect(() => {\n let mounted = true;\n const canUseDom =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n if (canUseDom) {\n import(\"@samvera/clover-iiif/slider\")\n .then((mod) => {\n if (!mounted) return;\n console.log(mod);\n const Comp = mod && (mod.default || mod.Slider || mod);\n setCloverSlider(() => Comp);\n })\n .catch(() => {\n // Silently ignore load errors on the server or if Clover is unavailable\n });\n }\n return () => {\n mounted = false;\n };\n }, []);\n\n if (!CloverSlider) {\n // SSR placeholder for client hydration; props provided as JSON\n let json = \"{}\";\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = \"{}\";\n }\n return (\n <div data-canopy-slider=\"1\" className=\"not-prose\">\n <script\n type=\"application/json\"\n dangerouslySetInnerHTML={{ __html: json }}\n />\n </div>\n );\n }\n return <CloverSlider {...props} />;\n};\n", "import React from 'react';\n\n// SSR-safe placeholder for RelatedItems. Hydrated by canopy-related-items.js + canopy-slider.js\nexport default function MdxRelatedItems(props) {\n let json = '{}';\n try {\n json = JSON.stringify(props || {});\n } catch (_) {\n json = '{}';\n }\n return (\n <div data-canopy-related-items=\"1\" className=\"not-prose\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n", "import React from 'react';\n\nexport default function MdxSearchResults(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-results=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function SearchSummary(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-summary=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import React from 'react';\n\nexport default function MdxSearchTabs(props) {\n let json = '{}';\n try { json = JSON.stringify(props || {}); } catch (_) { json = '{}'; }\n return (\n <div data-canopy-search-tabs=\"1\">\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: json }} />\n </div>\n );\n}\n\n", "import Grid, { GridItem } from \"../layout/Grid.jsx\";\n\nimport Card from \"../layout/Card.jsx\";\nimport React from \"react\";\n\nexport default function SearchResults({\n results = [],\n type = \"all\",\n layout = \"grid\",\n}) {\n if (!results.length) {\n return (\n <div className=\"text-slate-600\">\n <em>No results</em>\n </div>\n );\n }\n\n if (layout === \"list\") {\n return (\n <ul id=\"search-results\" className=\"space-y-3\">\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <li\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </li>\n );\n })}\n </ul>\n );\n }\n\n // Default: grid (masonry)\n return (\n <div id=\"search-results\">\n <Grid>\n {results.map((r, i) => {\n const hasDims =\n Number.isFinite(Number(r.thumbnailWidth)) &&\n Number(r.thumbnailWidth) > 0 &&\n Number.isFinite(Number(r.thumbnailHeight)) &&\n Number(r.thumbnailHeight) > 0;\n const aspect = hasDims\n ? Number(r.thumbnailWidth) / Number(r.thumbnailHeight)\n : undefined;\n return (\n <GridItem\n key={i}\n className={`search-result ${r.type}`}\n data-thumbnail-aspect-ratio={aspect}\n >\n <Card\n href={r.href}\n title={r.title || r.href}\n src={r.type === \"work\" ? r.thumbnail : undefined}\n imgWidth={r.thumbnailWidth}\n imgHeight={r.thumbnailHeight}\n aspectRatio={aspect}\n />\n </GridItem>\n );\n })}\n </Grid>\n </div>\n );\n}\n", "import React from \"react\";\n\nexport default function SearchTabs({\n type = \"all\",\n onTypeChange,\n types = [],\n counts = {},\n onOpenFilters,\n activeFilterCount = 0,\n filtersLabel = \"Filters\",\n filtersOpen = false,\n}) {\n const orderedTypes = Array.isArray(types) ? types : [];\n const toLabel = (t) =>\n t && t.length ? t.charAt(0).toUpperCase() + t.slice(1) : \"\";\n const hasFilters = typeof onOpenFilters === \"function\";\n const filterBadge = activeFilterCount > 0 ? ` (${activeFilterCount})` : \"\";\n return (\n <div className=\"canopy-search-tabs-wrapper\">\n <div\n role=\"tablist\"\n aria-label=\"Search types\"\n className=\"canopy-search-tabs\"\n >\n {orderedTypes.map((t) => {\n const active = String(type).toLowerCase() === String(t).toLowerCase();\n const cRaw =\n counts && Object.prototype.hasOwnProperty.call(counts, t)\n ? counts[t]\n : undefined;\n const c = Number.isFinite(Number(cRaw)) ? Number(cRaw) : 0;\n return (\n <button\n key={t}\n role=\"tab\"\n aria-selected={active}\n type=\"button\"\n onClick={() => onTypeChange && onTypeChange(t)}\n >\n {toLabel(t)} ({c})\n </button>\n );\n })}\n </div>\n {hasFilters ? (\n <button\n type=\"button\"\n onClick={() => onOpenFilters && onOpenFilters()}\n aria-expanded={filtersOpen ? \"true\" : \"false\"}\n 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\"\n >\n <span>\n {filtersLabel}\n {filterBadge}\n </span>\n </button>\n ) : null}\n </div>\n );\n}\n", "import React from \"react\";\n\nfunction toArray(input) {\n if (!input) return [];\n if (Array.isArray(input)) return input;\n return [input];\n}\n\nfunction normalizeSelected(selected = {}) {\n const map = new Map();\n if (selected && typeof selected === \"object\") {\n Object.keys(selected).forEach((key) => {\n const vals = new Set(toArray(selected[key]).map((v) => String(v)));\n if (vals.size) map.set(String(key), vals);\n });\n }\n return map;\n}\n\nfunction facetMatches(values = [], query) {\n const q = String(query || \"\")\n .trim()\n .toLowerCase();\n if (!q) return values;\n const starts = [];\n const contains = [];\n values.forEach((entry) => {\n if (!entry || !entry.value) return;\n const value = String(entry.value);\n const slug = String(entry.slug || entry.value || \"\");\n const match = value.toLowerCase();\n if (match.startsWith(q))\n starts.push({value, slug, doc_count: entry.doc_count});\n else if (match.includes(q))\n contains.push({value, slug, doc_count: entry.doc_count});\n });\n return [...starts, ...contains].slice(0, 10);\n}\n\nfunction FacetSection({facet, selected, onToggle}) {\n if (!facet || !facet.label || !Array.isArray(facet.values)) return null;\n const {label, slug, values} = facet;\n const selectedValues = selected.get(String(slug)) || new Set();\n const checkboxId = (valueSlug) => `filter-${slug}-${valueSlug}`;\n const hasSelection = selectedValues.size > 0;\n const [quickQuery, setQuickQuery] = React.useState(\"\");\n const hasQuery = quickQuery.trim().length > 0;\n const filteredValues = React.useMemo(\n () => facetMatches(values, quickQuery),\n [values, quickQuery]\n );\n\n return (\n <details\n className=\"canopy-search-filters__facet\"\n open={hasSelection}\n >\n <summary className=\"canopy-search-filters__facet-summary\">\n <span>{label}</span>\n <span className=\"canopy-search-filters__facet-count\">\n {values.length}\n </span>\n </summary>\n <div className=\"canopy-search-filters__facet-content\">\n <div className=\"canopy-search-filters__quick\">\n <input\n type=\"search\"\n value={quickQuery}\n onChange={(event) => setQuickQuery(event.target.value)}\n placeholder=\"Search values\"\n className=\"canopy-search-filters__quick-input\"\n aria-label={`Filter ${label} values`}\n />\n {quickQuery ? (\n <button\n type=\"button\"\n onClick={() => setQuickQuery(\"\")}\n className=\"canopy-search-filters__quick-clear\"\n >\n Clear\n </button>\n ) : null}\n </div>\n {hasQuery && !filteredValues.length ? (\n <p className=\"canopy-search-filters__facet-notice\">No matches found.</p>\n ) : null}\n <ul className=\"canopy-search-filters__facet-list\">\n {filteredValues.map((entry) => {\n const valueSlug = String(entry.slug || entry.value || \"\");\n const isChecked = selectedValues.has(valueSlug);\n const inputId = checkboxId(valueSlug);\n return (\n <li key={valueSlug} className=\"canopy-search-filters__facet-item\">\n <input\n id={inputId}\n type=\"checkbox\"\n className=\"canopy-search-filters__facet-checkbox\"\n checked={isChecked}\n onChange={(event) => {\n const nextChecked = !!event.target.checked;\n if (onToggle) onToggle(slug, valueSlug, nextChecked);\n }}\n />\n <label\n htmlFor={inputId}\n className=\"canopy-search-filters__facet-label\"\n >\n <span>\n {entry.value}{\" \"}\n {Number.isFinite(entry.doc_count) ? (\n <span className=\"canopy-search-filters__facet-count\">\n ({entry.doc_count})\n </span>\n ) : null}\n </span>\n </label>\n </li>\n );\n })}\n {!filteredValues.length && !hasQuery ? (\n <li className=\"canopy-search-filters__facet-empty\">No values available.</li>\n ) : null}\n </ul>\n </div>\n </details>\n );\n}\n\nexport default function SearchFiltersDialog(props = {}) {\n const {\n open = false,\n onOpenChange,\n facets = [],\n selected = {},\n onToggle,\n onClear,\n title = \"Filters\",\n subtitle = \"Refine results by metadata\",\n } = props;\n\n const selectedMap = normalizeSelected(selected);\n const activeCount = Array.from(selectedMap.values()).reduce(\n (total, set) => total + set.size,\n 0\n );\n\n if (!open) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"canopy-search-filters-overlay\"\n onClick={(event) => {\n if (event.target === event.currentTarget && onOpenChange)\n onOpenChange(false);\n }}\n >\n <div className=\"canopy-search-filters\">\n <header className=\"canopy-search-filters__header\">\n <div>\n <h2 className=\"canopy-search-filters__title\">{title}</h2>\n <p className=\"canopy-search-filters__subtitle\">{subtitle}</p>\n </div>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"canopy-search-filters__close\"\n >\n Close\n </button>\n </header>\n <div className=\"canopy-search-filters__body\">\n {Array.isArray(facets) && facets.length ? (\n <div className=\"canopy-search-filters__facets\">\n {facets.map((facet) => (\n <FacetSection\n key={facet.slug || facet.label}\n facet={facet}\n selected={selectedMap}\n onToggle={onToggle}\n />\n ))}\n </div>\n ) : (\n <p className=\"canopy-search-filters__empty\">\n No filters are available for this collection.\n </p>\n )}\n </div>\n <footer className=\"canopy-search-filters__footer\">\n <div>\n {activeCount\n ? `${activeCount} filter${activeCount === 1 ? \"\" : \"s\"} applied`\n : \"No filters applied\"}\n </div>\n <div className=\"canopy-search-filters__footer-actions\">\n <button\n type=\"button\"\n onClick={() => {\n if (onClear) onClear();\n }}\n disabled={!activeCount}\n className=\"canopy-search-filters__button canopy-search-filters__button--secondary\"\n >\n Clear all\n </button>\n <button\n type=\"button\"\n onClick={() => onOpenChange && onOpenChange(false)}\n className=\"canopy-search-filters__button canopy-search-filters__button--primary\"\n >\n Done\n </button>\n </div>\n </footer>\n </div>\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from '../search/SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from '../search/SearchPanelTeaserResults.jsx';\n\n// SSR-safe placeholder for the search form modal, composed from SearchPanel parts.\n// This ensures a single JSX source of truth for form/panel markup.\nexport default function MdxSearchFormModal(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'page'],\n button = true, // kept for backward compat; ignored by teaser form\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n return (\n <div data-canopy-search-form className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n", "import React from \"react\";\n\nexport const MagnifyingGlassIcon = (props) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" {...props}>\n <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\" />\n </svg>\n);\n", "import {MagnifyingGlassIcon} from \"../Icons\";\nimport React from \"react\";\n\nfunction readBasePath() {\n const normalize = (val) => {\n const raw = typeof val === \"string\" ? val.trim() : \"\";\n if (!raw) return \"\";\n return raw.replace(/\\/+$/, \"\");\n };\n try {\n if (typeof window !== \"undefined\" && window.CANOPY_BASE_PATH != null) {\n const fromWindow = normalize(window.CANOPY_BASE_PATH);\n if (fromWindow) return fromWindow;\n }\n } catch (_) {}\n try {\n if (\n typeof globalThis !== \"undefined\" &&\n globalThis.CANOPY_BASE_PATH != null\n ) {\n const fromGlobal = normalize(globalThis.CANOPY_BASE_PATH);\n if (fromGlobal) return fromGlobal;\n }\n } catch (_) {}\n try {\n if (\n typeof process !== \"undefined\" &&\n process.env &&\n process.env.CANOPY_BASE_PATH\n ) {\n const fromEnv = normalize(process.env.CANOPY_BASE_PATH);\n if (fromEnv) return fromEnv;\n }\n } catch (_) {}\n return \"\";\n}\n\nfunction isAbsoluteUrl(href) {\n try {\n return /^https?:/i.test(String(href || \"\"));\n } catch (_) {\n return false;\n }\n}\n\nexport function resolveSearchPath(pathValue) {\n let raw = typeof pathValue === \"string\" ? pathValue.trim() : \"\";\n if (!raw) raw = \"/search\";\n if (isAbsoluteUrl(raw)) return raw;\n const normalizedPath = raw.startsWith(\"/\") ? raw : `/${raw}`;\n const base = readBasePath();\n if (!base) return normalizedPath;\n const baseWithLead = base.startsWith(\"/\") ? base : `/${base}`;\n const baseTrimmed = baseWithLead.replace(/\\/+$/, \"\");\n if (!baseTrimmed) return normalizedPath;\n if (\n normalizedPath === baseTrimmed ||\n normalizedPath.startsWith(`${baseTrimmed}/`)\n ) {\n return normalizedPath;\n }\n const pathTrimmed = normalizedPath.replace(/^\\/+/, \"\");\n return `${baseTrimmed}/${pathTrimmed}`;\n}\n\nexport default function SearchPanelForm(props = {}) {\n const {\n placeholder = \"Search\u2026\",\n buttonLabel = \"Search\",\n label,\n searchPath = \"/search\",\n inputId: inputIdProp,\n } = props || {};\n\n const text =\n typeof label === \"string\" && label.trim() ? label.trim() : buttonLabel;\n const action = React.useMemo(\n () => resolveSearchPath(searchPath),\n [searchPath]\n );\n const autoId = typeof React.useId === \"function\" ? React.useId() : undefined;\n const [fallbackId] = React.useState(\n () => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`\n );\n const inputId = inputIdProp || autoId || fallbackId;\n const inputRef = React.useRef(null);\n const [hasValue, setHasValue] = React.useState(false);\n\n const focusInput = React.useCallback(() => {\n const el = inputRef.current;\n if (!el) return;\n if (document.activeElement === el) return;\n try {\n el.focus({preventScroll: true});\n } catch (_) {\n try {\n el.focus();\n } catch (_) {}\n }\n }, []);\n\n const handlePointerDown = React.useCallback(\n (event) => {\n const target = event.target;\n if (target && typeof target.closest === \"function\") {\n if (target.closest(\"[data-canopy-search-form-trigger]\")) return;\n }\n event.preventDefault();\n focusInput();\n },\n [focusInput]\n );\n\n React.useEffect(() => {\n const el = inputRef.current;\n if (!el) return;\n if (el.value && el.value.trim()) {\n setHasValue(true);\n }\n }, []);\n\n const handleInputChange = React.useCallback((event) => {\n const nextHasValue = Boolean(event?.target?.value && event.target.value.trim());\n setHasValue(nextHasValue);\n }, []);\n\n return (\n <form\n action={action}\n method=\"get\"\n role=\"search\"\n autoComplete=\"off\"\n spellCheck=\"false\"\n className=\"canopy-search-form canopy-search-form-shell\"\n onPointerDown={handlePointerDown}\n data-placeholder={placeholder || \"\"}\n data-has-value={hasValue ? \"1\" : \"0\"}\n >\n <label\n htmlFor={inputId}\n className=\"canopy-search-form__label\"\n >\n <MagnifyingGlassIcon className=\"canopy-search-form__icon\" />\n <input\n id={inputId}\n type=\"search\"\n name=\"q\"\n inputMode=\"search\"\n data-canopy-search-form-input\n placeholder={placeholder}\n className=\"canopy-search-form__input\"\n aria-label=\"Search\"\n ref={inputRef}\n onChange={handleInputChange}\n onInput={handleInputChange}\n />\n </label>\n <button\n type=\"submit\"\n data-canopy-search-form-trigger=\"submit\"\n className=\"canopy-search-form__submit\"\n >\n <span>{text}</span>\n <span aria-hidden className=\"canopy-search-form__shortcut\">\n <span>\u2318</span>\n <span>K</span>\n </span>\n </button>\n </form>\n );\n}\n", "import React from \"react\";\n\n// SSR placeholder for teaser results panel; the runtime controls visibility and content.\nexport default function SearchPanelTeaserResults(props = {}) {\n const { style, className } = props || {};\n const classes = [\"canopy-search-teaser\", className]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n data-canopy-search-form-panel\n className={classes || undefined}\n style={style}\n >\n <div id=\"cplist\" />\n </div>\n );\n}\n", "import React from 'react';\nimport SearchPanelForm, { resolveSearchPath } from './SearchPanelForm.jsx';\nimport SearchPanelTeaserResults from './SearchPanelTeaserResults.jsx';\n\n// High-level SearchPanel composed of a teaser form and teaser results panel.\n// Encodes configuration as JSON for the client runtime.\nexport default function SearchPanel(props = {}) {\n const {\n placeholder = 'Search\u2026',\n hotkey = 'mod+k',\n maxResults = 8,\n groupOrder = ['work', 'docs', 'page'],\n // Kept for backward compat; form always renders submit\n button = true, // eslint-disable-line no-unused-vars\n buttonLabel = 'Search',\n label,\n searchPath = '/search',\n } = props || {};\n\n const text = typeof label === 'string' && label.trim() ? label.trim() : buttonLabel;\n const resolvedSearchPath = resolveSearchPath(searchPath);\n const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };\n\n return (\n <div data-canopy-search-form className=\"flex-1 min-w-0\">\n <div className=\"relative w-full\">\n <SearchPanelForm placeholder={placeholder} buttonLabel={buttonLabel} label={label} searchPath={resolvedSearchPath} />\n <SearchPanelTeaserResults />\n </div>\n <script type=\"application/json\" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />\n </div>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["React", "React", "React", "useEffect", "useState", "React", "useEffect", "useState", "React", "React", "React", "React", "React", "React", "React", "React", "React", "React", "_", "React", "React", "React", "React"]
|
|
7
7
|
}
|
package/ui/dist/server.mjs
CHANGED
|
@@ -244,8 +244,96 @@ function FeaturedHero(props = {}) {
|
|
|
244
244
|
return /* @__PURE__ */ React6.createElement(Hero, { ...props });
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
// ui/src/
|
|
247
|
+
// ui/src/layout/SubNavigation.jsx
|
|
248
248
|
import React7 from "react";
|
|
249
|
+
import navigationHelpers from "@canopy-iiif/app/lib/components/navigation.js";
|
|
250
|
+
function resolveRelativeCandidate(page, current) {
|
|
251
|
+
if (page && typeof page.relativePath === "string" && page.relativePath) return page.relativePath;
|
|
252
|
+
if (page && typeof page.slug === "string" && page.slug) return page.slug;
|
|
253
|
+
if (typeof current === "string" && current) return current;
|
|
254
|
+
return "";
|
|
255
|
+
}
|
|
256
|
+
function renderNodes(nodes, parentKey = "node") {
|
|
257
|
+
if (!Array.isArray(nodes) || !nodes.length) return null;
|
|
258
|
+
return nodes.map((node, index) => {
|
|
259
|
+
if (!node) return null;
|
|
260
|
+
const key = node.slug || node.relativePath || `${parentKey}-${index}`;
|
|
261
|
+
const hasChildren = Array.isArray(node.children) && node.children.length > 0;
|
|
262
|
+
const showChildren = hasChildren && (node.isExpanded || node.depth === 0);
|
|
263
|
+
const depth = typeof node.depth === "number" ? Math.max(0, node.depth) : 0;
|
|
264
|
+
const depthClass = `depth-${Math.min(depth, 5)}`;
|
|
265
|
+
const classes = [
|
|
266
|
+
"canopy-sub-navigation__link",
|
|
267
|
+
depthClass
|
|
268
|
+
];
|
|
269
|
+
if (!node.href) classes.push("is-label");
|
|
270
|
+
if (node.isActive) classes.push("is-active");
|
|
271
|
+
const linkClass = classes.join(" ");
|
|
272
|
+
const Tag = node.href ? "a" : "span";
|
|
273
|
+
return /* @__PURE__ */ React7.createElement(
|
|
274
|
+
"li",
|
|
275
|
+
{
|
|
276
|
+
key,
|
|
277
|
+
className: "canopy-sub-navigation__item",
|
|
278
|
+
"data-depth": depth
|
|
279
|
+
},
|
|
280
|
+
/* @__PURE__ */ React7.createElement(
|
|
281
|
+
Tag,
|
|
282
|
+
{
|
|
283
|
+
className: linkClass,
|
|
284
|
+
href: node.href || void 0,
|
|
285
|
+
"aria-current": node.isActive ? "page" : void 0
|
|
286
|
+
},
|
|
287
|
+
node.title || node.slug
|
|
288
|
+
),
|
|
289
|
+
showChildren ? /* @__PURE__ */ React7.createElement("ul", { className: "canopy-sub-navigation__list canopy-sub-navigation__list--nested", role: "list" }, renderNodes(node.children, key)) : null
|
|
290
|
+
);
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
function SubNavigation({
|
|
294
|
+
navigation: navigationProp,
|
|
295
|
+
page,
|
|
296
|
+
current,
|
|
297
|
+
className = "",
|
|
298
|
+
style = {},
|
|
299
|
+
heading,
|
|
300
|
+
ariaLabel
|
|
301
|
+
}) {
|
|
302
|
+
const PageContext = navigationHelpers && navigationHelpers.getPageContext ? navigationHelpers.getPageContext() : null;
|
|
303
|
+
const context = PageContext ? React7.useContext(PageContext) : null;
|
|
304
|
+
const contextNavigation = context && context.navigation ? context.navigation : null;
|
|
305
|
+
const contextPage = context && context.page ? context.page : null;
|
|
306
|
+
const effectiveNavigation = navigationProp || contextNavigation;
|
|
307
|
+
const effectivePage = page || contextPage;
|
|
308
|
+
const resolvedNavigation = React7.useMemo(() => {
|
|
309
|
+
if (effectiveNavigation && effectiveNavigation.root) return effectiveNavigation;
|
|
310
|
+
const candidate = resolveRelativeCandidate(effectivePage, current);
|
|
311
|
+
if (!candidate) return effectiveNavigation || null;
|
|
312
|
+
const helpers2 = navigationHelpers && navigationHelpers.buildNavigationForFile ? navigationHelpers : null;
|
|
313
|
+
if (!helpers2) return effectiveNavigation || null;
|
|
314
|
+
try {
|
|
315
|
+
const normalized = navigationHelpers.normalizeRelativePath ? navigationHelpers.normalizeRelativePath(candidate) : candidate;
|
|
316
|
+
const built = helpers2.buildNavigationForFile(normalized);
|
|
317
|
+
if (built) return built;
|
|
318
|
+
} catch (_) {
|
|
319
|
+
}
|
|
320
|
+
return effectiveNavigation || null;
|
|
321
|
+
}, [effectiveNavigation, effectivePage, current]);
|
|
322
|
+
if (!resolvedNavigation || !resolvedNavigation.root) return null;
|
|
323
|
+
const rootNode = resolvedNavigation.root;
|
|
324
|
+
const finalHeading = heading || null;
|
|
325
|
+
const labelSource = finalHeading || resolvedNavigation.title;
|
|
326
|
+
const navLabel = ariaLabel || (labelSource ? `${labelSource} navigation` : "Section navigation");
|
|
327
|
+
const combinedClassName = ["canopy-sub-navigation", className].filter(Boolean).join(" ");
|
|
328
|
+
const inlineStyle = { ...style };
|
|
329
|
+
if (!Object.prototype.hasOwnProperty.call(inlineStyle, "--sub-nav-indent")) {
|
|
330
|
+
inlineStyle["--sub-nav-indent"] = "0.85rem";
|
|
331
|
+
}
|
|
332
|
+
return /* @__PURE__ */ React7.createElement("nav", { className: combinedClassName, style: inlineStyle, "aria-label": navLabel }, finalHeading ? /* @__PURE__ */ React7.createElement("div", { className: "canopy-sub-navigation__heading" }, finalHeading) : null, /* @__PURE__ */ React7.createElement("ul", { className: "canopy-sub-navigation__list", role: "list" }, renderNodes([rootNode], rootNode.slug || "root")));
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ui/src/search/MdxSearchResults.jsx
|
|
336
|
+
import React8 from "react";
|
|
249
337
|
function MdxSearchResults(props) {
|
|
250
338
|
let json = "{}";
|
|
251
339
|
try {
|
|
@@ -253,11 +341,11 @@ function MdxSearchResults(props) {
|
|
|
253
341
|
} catch (_) {
|
|
254
342
|
json = "{}";
|
|
255
343
|
}
|
|
256
|
-
return /* @__PURE__ */
|
|
344
|
+
return /* @__PURE__ */ React8.createElement("div", { "data-canopy-search-results": "1" }, /* @__PURE__ */ React8.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
257
345
|
}
|
|
258
346
|
|
|
259
347
|
// ui/src/search/SearchSummary.jsx
|
|
260
|
-
import
|
|
348
|
+
import React9 from "react";
|
|
261
349
|
function SearchSummary(props) {
|
|
262
350
|
let json = "{}";
|
|
263
351
|
try {
|
|
@@ -265,11 +353,11 @@ function SearchSummary(props) {
|
|
|
265
353
|
} catch (_) {
|
|
266
354
|
json = "{}";
|
|
267
355
|
}
|
|
268
|
-
return /* @__PURE__ */
|
|
356
|
+
return /* @__PURE__ */ React9.createElement("div", { "data-canopy-search-summary": "1" }, /* @__PURE__ */ React9.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
269
357
|
}
|
|
270
358
|
|
|
271
359
|
// ui/src/search/MdxSearchTabs.jsx
|
|
272
|
-
import
|
|
360
|
+
import React10 from "react";
|
|
273
361
|
function MdxSearchTabs(props) {
|
|
274
362
|
let json = "{}";
|
|
275
363
|
try {
|
|
@@ -277,18 +365,18 @@ function MdxSearchTabs(props) {
|
|
|
277
365
|
} catch (_) {
|
|
278
366
|
json = "{}";
|
|
279
367
|
}
|
|
280
|
-
return /* @__PURE__ */
|
|
368
|
+
return /* @__PURE__ */ React10.createElement("div", { "data-canopy-search-tabs": "1" }, /* @__PURE__ */ React10.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: json } }));
|
|
281
369
|
}
|
|
282
370
|
|
|
283
371
|
// ui/src/search-form/MdxSearchFormModal.jsx
|
|
284
|
-
import
|
|
372
|
+
import React14 from "react";
|
|
285
373
|
|
|
286
374
|
// ui/src/Icons.jsx
|
|
287
|
-
import
|
|
288
|
-
var MagnifyingGlassIcon = (props) => /* @__PURE__ */
|
|
375
|
+
import React11 from "react";
|
|
376
|
+
var MagnifyingGlassIcon = (props) => /* @__PURE__ */ React11.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 512 512", ...props }, /* @__PURE__ */ React11.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" }));
|
|
289
377
|
|
|
290
378
|
// ui/src/search/SearchPanelForm.jsx
|
|
291
|
-
import
|
|
379
|
+
import React12 from "react";
|
|
292
380
|
function readBasePath() {
|
|
293
381
|
const normalize = (val) => {
|
|
294
382
|
const raw = typeof val === "string" ? val.trim() : "";
|
|
@@ -350,18 +438,18 @@ function SearchPanelForm(props = {}) {
|
|
|
350
438
|
inputId: inputIdProp
|
|
351
439
|
} = props || {};
|
|
352
440
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
353
|
-
const action =
|
|
441
|
+
const action = React12.useMemo(
|
|
354
442
|
() => resolveSearchPath(searchPath),
|
|
355
443
|
[searchPath]
|
|
356
444
|
);
|
|
357
|
-
const autoId = typeof
|
|
358
|
-
const [fallbackId] =
|
|
445
|
+
const autoId = typeof React12.useId === "function" ? React12.useId() : void 0;
|
|
446
|
+
const [fallbackId] = React12.useState(
|
|
359
447
|
() => `canopy-search-form-${Math.random().toString(36).slice(2, 10)}`
|
|
360
448
|
);
|
|
361
449
|
const inputId = inputIdProp || autoId || fallbackId;
|
|
362
|
-
const inputRef =
|
|
363
|
-
const [hasValue, setHasValue] =
|
|
364
|
-
const focusInput =
|
|
450
|
+
const inputRef = React12.useRef(null);
|
|
451
|
+
const [hasValue, setHasValue] = React12.useState(false);
|
|
452
|
+
const focusInput = React12.useCallback(() => {
|
|
365
453
|
const el = inputRef.current;
|
|
366
454
|
if (!el) return;
|
|
367
455
|
if (document.activeElement === el) return;
|
|
@@ -374,7 +462,7 @@ function SearchPanelForm(props = {}) {
|
|
|
374
462
|
}
|
|
375
463
|
}
|
|
376
464
|
}, []);
|
|
377
|
-
const handlePointerDown =
|
|
465
|
+
const handlePointerDown = React12.useCallback(
|
|
378
466
|
(event) => {
|
|
379
467
|
const target = event.target;
|
|
380
468
|
if (target && typeof target.closest === "function") {
|
|
@@ -385,19 +473,19 @@ function SearchPanelForm(props = {}) {
|
|
|
385
473
|
},
|
|
386
474
|
[focusInput]
|
|
387
475
|
);
|
|
388
|
-
|
|
476
|
+
React12.useEffect(() => {
|
|
389
477
|
const el = inputRef.current;
|
|
390
478
|
if (!el) return;
|
|
391
479
|
if (el.value && el.value.trim()) {
|
|
392
480
|
setHasValue(true);
|
|
393
481
|
}
|
|
394
482
|
}, []);
|
|
395
|
-
const handleInputChange =
|
|
483
|
+
const handleInputChange = React12.useCallback((event) => {
|
|
396
484
|
var _a;
|
|
397
485
|
const nextHasValue = Boolean(((_a = event == null ? void 0 : event.target) == null ? void 0 : _a.value) && event.target.value.trim());
|
|
398
486
|
setHasValue(nextHasValue);
|
|
399
487
|
}, []);
|
|
400
|
-
return /* @__PURE__ */
|
|
488
|
+
return /* @__PURE__ */ React12.createElement(
|
|
401
489
|
"form",
|
|
402
490
|
{
|
|
403
491
|
action,
|
|
@@ -410,14 +498,14 @@ function SearchPanelForm(props = {}) {
|
|
|
410
498
|
"data-placeholder": placeholder || "",
|
|
411
499
|
"data-has-value": hasValue ? "1" : "0"
|
|
412
500
|
},
|
|
413
|
-
/* @__PURE__ */
|
|
501
|
+
/* @__PURE__ */ React12.createElement(
|
|
414
502
|
"label",
|
|
415
503
|
{
|
|
416
504
|
htmlFor: inputId,
|
|
417
505
|
className: "canopy-search-form__label"
|
|
418
506
|
},
|
|
419
|
-
/* @__PURE__ */
|
|
420
|
-
/* @__PURE__ */
|
|
507
|
+
/* @__PURE__ */ React12.createElement(MagnifyingGlassIcon, { className: "canopy-search-form__icon" }),
|
|
508
|
+
/* @__PURE__ */ React12.createElement(
|
|
421
509
|
"input",
|
|
422
510
|
{
|
|
423
511
|
id: inputId,
|
|
@@ -434,32 +522,32 @@ function SearchPanelForm(props = {}) {
|
|
|
434
522
|
}
|
|
435
523
|
)
|
|
436
524
|
),
|
|
437
|
-
/* @__PURE__ */
|
|
525
|
+
/* @__PURE__ */ React12.createElement(
|
|
438
526
|
"button",
|
|
439
527
|
{
|
|
440
528
|
type: "submit",
|
|
441
529
|
"data-canopy-search-form-trigger": "submit",
|
|
442
530
|
className: "canopy-search-form__submit"
|
|
443
531
|
},
|
|
444
|
-
/* @__PURE__ */
|
|
445
|
-
/* @__PURE__ */
|
|
532
|
+
/* @__PURE__ */ React12.createElement("span", null, text),
|
|
533
|
+
/* @__PURE__ */ React12.createElement("span", { "aria-hidden": true, className: "canopy-search-form__shortcut" }, /* @__PURE__ */ React12.createElement("span", null, "\u2318"), /* @__PURE__ */ React12.createElement("span", null, "K"))
|
|
446
534
|
)
|
|
447
535
|
);
|
|
448
536
|
}
|
|
449
537
|
|
|
450
538
|
// ui/src/search/SearchPanelTeaserResults.jsx
|
|
451
|
-
import
|
|
539
|
+
import React13 from "react";
|
|
452
540
|
function SearchPanelTeaserResults(props = {}) {
|
|
453
541
|
const { style, className } = props || {};
|
|
454
542
|
const classes = ["canopy-search-teaser", className].filter(Boolean).join(" ");
|
|
455
|
-
return /* @__PURE__ */
|
|
543
|
+
return /* @__PURE__ */ React13.createElement(
|
|
456
544
|
"div",
|
|
457
545
|
{
|
|
458
546
|
"data-canopy-search-form-panel": true,
|
|
459
547
|
className: classes || void 0,
|
|
460
548
|
style
|
|
461
549
|
},
|
|
462
|
-
/* @__PURE__ */
|
|
550
|
+
/* @__PURE__ */ React13.createElement("div", { id: "cplist" })
|
|
463
551
|
);
|
|
464
552
|
}
|
|
465
553
|
|
|
@@ -479,11 +567,11 @@ function MdxSearchFormModal(props = {}) {
|
|
|
479
567
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
480
568
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
481
569
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
482
|
-
return /* @__PURE__ */
|
|
570
|
+
return /* @__PURE__ */ React14.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React14.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React14.createElement(SearchPanelForm, { placeholder, buttonLabel, label, searchPath: resolvedSearchPath }), /* @__PURE__ */ React14.createElement(SearchPanelTeaserResults, null)), /* @__PURE__ */ React14.createElement("script", { type: "application/json", dangerouslySetInnerHTML: { __html: JSON.stringify(data) } }));
|
|
483
571
|
}
|
|
484
572
|
|
|
485
573
|
// ui/src/search/SearchPanel.jsx
|
|
486
|
-
import
|
|
574
|
+
import React15 from "react";
|
|
487
575
|
function SearchPanel(props = {}) {
|
|
488
576
|
const {
|
|
489
577
|
placeholder = "Search\u2026",
|
|
@@ -500,11 +588,11 @@ function SearchPanel(props = {}) {
|
|
|
500
588
|
const text = typeof label === "string" && label.trim() ? label.trim() : buttonLabel;
|
|
501
589
|
const resolvedSearchPath = resolveSearchPath(searchPath);
|
|
502
590
|
const data = { placeholder, hotkey, maxResults, groupOrder, label: text, searchPath: resolvedSearchPath };
|
|
503
|
-
return /* @__PURE__ */
|
|
591
|
+
return /* @__PURE__ */ React15.createElement("div", { "data-canopy-search-form": true, className: "flex-1 min-w-0" }, /* @__PURE__ */ React15.createElement("div", { className: "relative w-full" }, /* @__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) } }));
|
|
504
592
|
}
|
|
505
593
|
|
|
506
594
|
// ui/src/iiif/ManifestPrimitives.jsx
|
|
507
|
-
import
|
|
595
|
+
import React16 from "react";
|
|
508
596
|
import {
|
|
509
597
|
Label as CloverLabel,
|
|
510
598
|
Metadata as CloverMetadata,
|
|
@@ -529,24 +617,24 @@ function ensureMetadata(items) {
|
|
|
529
617
|
function Label({ manifest, label, ...rest }) {
|
|
530
618
|
const intl = label || manifest && manifest.label;
|
|
531
619
|
if (!hasInternationalValue(intl)) return null;
|
|
532
|
-
return /* @__PURE__ */
|
|
620
|
+
return /* @__PURE__ */ React16.createElement(CloverLabel, { label: intl, ...rest });
|
|
533
621
|
}
|
|
534
622
|
function Summary({ manifest, summary, ...rest }) {
|
|
535
623
|
const intl = summary || manifest && manifest.summary;
|
|
536
624
|
if (!hasInternationalValue(intl)) return null;
|
|
537
|
-
return /* @__PURE__ */
|
|
625
|
+
return /* @__PURE__ */ React16.createElement(CloverSummary, { summary: intl, ...rest });
|
|
538
626
|
}
|
|
539
627
|
function Metadata({ manifest, metadata, ...rest }) {
|
|
540
628
|
const items = ensureMetadata(metadata || manifest && manifest.metadata);
|
|
541
629
|
if (!items.length) return null;
|
|
542
|
-
return /* @__PURE__ */
|
|
630
|
+
return /* @__PURE__ */ React16.createElement(CloverMetadata, { metadata: items, ...rest });
|
|
543
631
|
}
|
|
544
632
|
function RequiredStatement({ manifest, requiredStatement, ...rest }) {
|
|
545
633
|
const stmt = requiredStatement || manifest && manifest.requiredStatement;
|
|
546
634
|
if (!stmt || !hasInternationalValue(stmt.label) || !hasInternationalValue(stmt.value)) {
|
|
547
635
|
return null;
|
|
548
636
|
}
|
|
549
|
-
return /* @__PURE__ */
|
|
637
|
+
return /* @__PURE__ */ React16.createElement(CloverRequiredStatement, { requiredStatement: stmt, ...rest });
|
|
550
638
|
}
|
|
551
639
|
export {
|
|
552
640
|
FeaturedHero,
|
|
@@ -564,6 +652,7 @@ export {
|
|
|
564
652
|
SearchSummary,
|
|
565
653
|
MdxSearchTabs as SearchTabs,
|
|
566
654
|
Slider,
|
|
655
|
+
SubNavigation,
|
|
567
656
|
Summary,
|
|
568
657
|
Viewer
|
|
569
658
|
};
|