@canopy-iiif/app 1.12.1 → 1.12.3
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/iiif.js +4 -2
- package/lib/components/navigation.js +49 -9
- package/package.json +1 -1
- package/ui/dist/server.mjs +33 -11
- package/ui/dist/server.mjs.map +2 -2
package/lib/build/iiif.js
CHANGED
|
@@ -1783,8 +1783,10 @@ async function buildIiifCollectionPages(CONFIG) {
|
|
|
1783
1783
|
trimmed.toLowerCase().replace(/[^a-z0-9]+/g, "-") ||
|
|
1784
1784
|
trimmed;
|
|
1785
1785
|
if (!valueSlug) continue;
|
|
1786
|
-
if (
|
|
1787
|
-
valueMap.
|
|
1786
|
+
if (valueMap.has(valueSlug)) {
|
|
1787
|
+
valueMap.get(valueSlug).count += 1;
|
|
1788
|
+
} else {
|
|
1789
|
+
valueMap.set(valueSlug, {value: trimmed, slug: valueSlug, count: 1});
|
|
1788
1790
|
}
|
|
1789
1791
|
}
|
|
1790
1792
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
fs,
|
|
3
|
+
path,
|
|
4
|
+
CONTENT_DIR,
|
|
5
|
+
rootRelativeHref,
|
|
6
|
+
canonicalizeLocaleCode,
|
|
7
|
+
} = require("../common");
|
|
2
8
|
const mdx = require("../build/mdx.js");
|
|
3
9
|
const {getPageContext} = require("../page-context");
|
|
4
10
|
|
|
@@ -38,6 +44,33 @@ function slugFromRelative(relativePath) {
|
|
|
38
44
|
return {slug, segments, isIndex};
|
|
39
45
|
}
|
|
40
46
|
|
|
47
|
+
// Returns true when the segment is a configured (non-default) locale code that
|
|
48
|
+
// prefixes content routes, e.g. "fr" for content/fr/...
|
|
49
|
+
function isLocaleSegment(segment) {
|
|
50
|
+
if (!segment) return false;
|
|
51
|
+
try {
|
|
52
|
+
return !!canonicalizeLocaleCode(segment);
|
|
53
|
+
} catch (_) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Depth (number of leading segments) that identifies a navigation section root
|
|
59
|
+
// for a page. Locale-prefixed routes root at <locale>/<section>; everything else
|
|
60
|
+
// roots at <section>.
|
|
61
|
+
function rootDepthForSegments(segments) {
|
|
62
|
+
if (!Array.isArray(segments) || !segments.length) return 0;
|
|
63
|
+
if (segments.length > 1 && isLocaleSegment(segments[0])) return 2;
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Slug of the section root for a page's segments (locale-aware).
|
|
68
|
+
function rootSegmentForSegments(segments) {
|
|
69
|
+
const depth = rootDepthForSegments(segments);
|
|
70
|
+
if (!depth) return "";
|
|
71
|
+
return segments.slice(0, depth).join("/");
|
|
72
|
+
}
|
|
73
|
+
|
|
41
74
|
function pageSortKey(relativePath) {
|
|
42
75
|
const normalized = normalizeRelativePath(relativePath).toLowerCase();
|
|
43
76
|
if (!normalized) return "";
|
|
@@ -210,7 +243,11 @@ function getNavigationCache() {
|
|
|
210
243
|
|
|
211
244
|
const roots = new Map();
|
|
212
245
|
for (const node of nodes.values()) {
|
|
213
|
-
|
|
246
|
+
// A section root is either a top-level node (<section>) or, for
|
|
247
|
+
// locale-prefixed content, a <locale>/<section> node. Rooting a
|
|
248
|
+
// locale-prefixed sidebar at the locale segment alone would list every
|
|
249
|
+
// section under that locale instead of just the current one.
|
|
250
|
+
if (rootDepthForSegments(node.segments) === node.segments.length) {
|
|
214
251
|
roots.set(node.slug, node);
|
|
215
252
|
}
|
|
216
253
|
}
|
|
@@ -266,7 +303,7 @@ function getPageInfo(relativePath) {
|
|
|
266
303
|
slug: page.slug,
|
|
267
304
|
segments: page.segments.slice(),
|
|
268
305
|
relativePath: page.relativePath,
|
|
269
|
-
rootSegment: page.segments
|
|
306
|
+
rootSegment: rootSegmentForSegments(page.segments),
|
|
270
307
|
isIndex: page.isIndex,
|
|
271
308
|
};
|
|
272
309
|
}
|
|
@@ -278,7 +315,7 @@ function getPageInfo(relativePath) {
|
|
|
278
315
|
slug,
|
|
279
316
|
segments,
|
|
280
317
|
relativePath: normalized,
|
|
281
|
-
rootSegment: segments
|
|
318
|
+
rootSegment: rootSegmentForSegments(segments),
|
|
282
319
|
isIndex: false,
|
|
283
320
|
};
|
|
284
321
|
}
|
|
@@ -289,10 +326,12 @@ function buildNavigationForFile(relativePath) {
|
|
|
289
326
|
const page = cache.pagesByRelative.get(normalized);
|
|
290
327
|
const fallback = slugFromRelative(normalized);
|
|
291
328
|
const slug = page ? page.slug : fallback.slug;
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
329
|
+
const segments = page ? page.segments : fallback.segments;
|
|
330
|
+
const rootSegment = rootSegmentForSegments(segments);
|
|
331
|
+
// The section name is the last segment of the root (the segment after an
|
|
332
|
+
// optional locale prefix), e.g. "works" for both "works" and "fr/works".
|
|
333
|
+
const sectionName = rootSegment.split("/").pop() || "";
|
|
334
|
+
if (!slug || !rootSegment || EXCLUDED_ROOTS.has(sectionName)) {
|
|
296
335
|
return null;
|
|
297
336
|
}
|
|
298
337
|
const rootNode = cache.roots.get(rootSegment);
|
|
@@ -312,7 +351,8 @@ function buildNavigationRoots(currentSlug) {
|
|
|
312
351
|
const result = {};
|
|
313
352
|
const normalizedSlug = typeof currentSlug === "string" ? currentSlug : "";
|
|
314
353
|
for (const [segment, rootNode] of cache.roots.entries()) {
|
|
315
|
-
|
|
354
|
+
const sectionName = segment.split("/").pop() || "";
|
|
355
|
+
if (!segment || EXCLUDED_ROOTS.has(sectionName)) continue;
|
|
316
356
|
const shouldExpand =
|
|
317
357
|
normalizedSlug &&
|
|
318
358
|
(normalizedSlug === segment || normalizedSlug.startsWith(segment + "/"));
|
package/package.json
CHANGED
package/ui/dist/server.mjs
CHANGED
|
@@ -4260,7 +4260,8 @@ function normalizeEntries(entries) {
|
|
|
4260
4260
|
const dedupeKey = `${labelSlug}__${slug}`;
|
|
4261
4261
|
if (seen.has(dedupeKey)) return;
|
|
4262
4262
|
seen.add(dedupeKey);
|
|
4263
|
-
|
|
4263
|
+
const count = valueEntry && typeof valueEntry === "object" && typeof valueEntry.count === "number" ? valueEntry.count : void 0;
|
|
4264
|
+
values.push({ value: trimmed, slug, ...count !== void 0 && { count } });
|
|
4264
4265
|
});
|
|
4265
4266
|
if (!values.length) return;
|
|
4266
4267
|
normalized.push({ label, slug: labelSlug, values });
|
|
@@ -4374,6 +4375,8 @@ function Index({
|
|
|
4374
4375
|
limit = 15,
|
|
4375
4376
|
expandLabel = "Show more",
|
|
4376
4377
|
collapseLabel = "Show less",
|
|
4378
|
+
sortOrder = "alphabetically",
|
|
4379
|
+
showCount = false,
|
|
4377
4380
|
className = "",
|
|
4378
4381
|
...rest
|
|
4379
4382
|
}) {
|
|
@@ -4390,7 +4393,9 @@ function Index({
|
|
|
4390
4393
|
values: entry.values,
|
|
4391
4394
|
limit,
|
|
4392
4395
|
expandLabel,
|
|
4393
|
-
collapseLabel
|
|
4396
|
+
collapseLabel,
|
|
4397
|
+
sortOrder,
|
|
4398
|
+
showCount
|
|
4394
4399
|
}
|
|
4395
4400
|
)), /* @__PURE__ */ React34.createElement(
|
|
4396
4401
|
"script",
|
|
@@ -4400,18 +4405,34 @@ function Index({
|
|
|
4400
4405
|
}
|
|
4401
4406
|
));
|
|
4402
4407
|
}
|
|
4403
|
-
function
|
|
4408
|
+
function sortValues(values, sortOrder) {
|
|
4409
|
+
const copy = [...values];
|
|
4410
|
+
if (sortOrder === "count") {
|
|
4411
|
+
copy.sort((a, b) => {
|
|
4412
|
+
var _a, _b;
|
|
4413
|
+
return ((_a = b.count) != null ? _a : 0) - ((_b = a.count) != null ? _b : 0);
|
|
4414
|
+
});
|
|
4415
|
+
} else {
|
|
4416
|
+
copy.sort(
|
|
4417
|
+
(a, b) => String(a.value).localeCompare(String(b.value), void 0, { sensitivity: "base" })
|
|
4418
|
+
);
|
|
4419
|
+
}
|
|
4420
|
+
return copy;
|
|
4421
|
+
}
|
|
4422
|
+
function IndexGroup({ label, labelSlug, values, limit, expandLabel, collapseLabel, sortOrder, showCount }) {
|
|
4404
4423
|
const parsedLimit = Number(limit);
|
|
4424
|
+
const showAll = Number.isFinite(parsedLimit) && Math.floor(parsedLimit) === 0;
|
|
4405
4425
|
const clampedLimit = Number.isFinite(parsedLimit) ? Math.max(1, Math.floor(parsedLimit)) : 15;
|
|
4406
|
-
const
|
|
4407
|
-
const hasOverflow =
|
|
4408
|
-
const visibleValues = hasOverflow ?
|
|
4409
|
-
const hiddenValues = hasOverflow ?
|
|
4426
|
+
const sorted = sortValues(values, sortOrder);
|
|
4427
|
+
const hasOverflow = !showAll && sorted.length > clampedLimit;
|
|
4428
|
+
const visibleValues = hasOverflow ? sorted.slice(0, clampedLimit) : sorted;
|
|
4429
|
+
const hiddenValues = hasOverflow ? sorted.slice(clampedLimit) : [];
|
|
4410
4430
|
const labelCollapsed = typeof expandLabel === "string" && expandLabel.trim() ? expandLabel.trim() : "Show more";
|
|
4411
4431
|
const labelExpanded = typeof collapseLabel === "string" && collapseLabel.trim() ? collapseLabel.trim() : "Show less";
|
|
4412
4432
|
return /* @__PURE__ */ React34.createElement("dl", { className: "canopy-index__group", "data-canopy-index-group": "", "data-expanded": "0" }, /* @__PURE__ */ React34.createElement("dt", null, label), /* @__PURE__ */ React34.createElement("div", { className: "canopy-index__values" }, visibleValues.map((value) => {
|
|
4413
4433
|
const href = buildSearchHref(labelSlug, value.slug);
|
|
4414
4434
|
const key = `${labelSlug || label}-${value.slug || value.value}`;
|
|
4435
|
+
const displayText = showCount && value.count != null ? `${value.value} (${value.count})` : value.value;
|
|
4415
4436
|
return /* @__PURE__ */ React34.createElement("dd", { key }, href ? /* @__PURE__ */ React34.createElement(
|
|
4416
4437
|
"a",
|
|
4417
4438
|
{
|
|
@@ -4420,11 +4441,12 @@ function IndexGroup({ label, labelSlug, values, limit, expandLabel, collapseLabe
|
|
|
4420
4441
|
"data-index-label": labelSlug,
|
|
4421
4442
|
"data-index-value": value.slug
|
|
4422
4443
|
},
|
|
4423
|
-
|
|
4424
|
-
) :
|
|
4444
|
+
displayText
|
|
4445
|
+
) : displayText);
|
|
4425
4446
|
}), hiddenValues.map((value) => {
|
|
4426
4447
|
const href = buildSearchHref(labelSlug, value.slug);
|
|
4427
4448
|
const key = `${labelSlug || label}-hidden-${value.slug || value.value}`;
|
|
4449
|
+
const displayText = showCount && value.count != null ? `${value.value} (${value.count})` : value.value;
|
|
4428
4450
|
return /* @__PURE__ */ React34.createElement("dd", { key, "data-canopy-index-hidden": "", hidden: true }, href ? /* @__PURE__ */ React34.createElement(
|
|
4429
4451
|
"a",
|
|
4430
4452
|
{
|
|
@@ -4433,8 +4455,8 @@ function IndexGroup({ label, labelSlug, values, limit, expandLabel, collapseLabe
|
|
|
4433
4455
|
"data-index-label": labelSlug,
|
|
4434
4456
|
"data-index-value": value.slug
|
|
4435
4457
|
},
|
|
4436
|
-
|
|
4437
|
-
) :
|
|
4458
|
+
displayText
|
|
4459
|
+
) : displayText);
|
|
4438
4460
|
})), hasOverflow && /* @__PURE__ */ React34.createElement("div", { className: "canopy-index__more-wrapper" }, /* @__PURE__ */ React34.createElement(
|
|
4439
4461
|
"button",
|
|
4440
4462
|
{
|