@museumwnf/viewer-layout 3.2.2 → 3.4.0
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/README.md +167 -12
- package/dist/ItemDetailView-I__hm63H.js +298 -0
- package/dist/SiteShell-4vV2jIzf.js +192 -0
- package/dist/{Theme-Dd8G1RA3.js → Theme-B5J0XRe1.js} +3 -3
- package/dist/{TimelineResultsView-5Cy-OkZY.js → TimelineResultsView-ChkBn27W.js} +489 -485
- package/dist/chrome-DPuPeWzV.js +1141 -0
- package/dist/components.js +1 -1
- package/dist/data-CJlLA-Mf.js +38 -0
- package/dist/data-DTbAYdr2.js +40 -0
- package/dist/dxa.js +619 -502
- package/dist/index.js +6 -6
- package/dist/{themeSpecs-C_uGarTs.js → themeSpecs-B885l456.js} +3 -2
- package/dist/viewer-layout.css +1 -1
- package/dist/views.js +1 -1
- package/package.json +8 -2
- package/src/dxa/testing.js +857 -0
- package/src/styles/dxa-exhibition.css +389 -0
- package/src/styles/dxa-gallery.css +589 -0
- package/src/tokens.reference.css +25 -7
- package/dist/ItemDetailView-C-X-LgJU.js +0 -284
- package/dist/PageShell-CbJ9lQoQ.js +0 -961
- package/dist/SiteShell-C3OgZO8p.js +0 -154
- package/dist/data-BfyYB8ff.js +0 -33
- package/dist/data-G8uXeEfE.js +0 -35
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ all the packages:
|
|
|
18
18
|
| `@museumwnf/viewer-layout/views` | composed views | whole pages driven by a spec the website declares, with slots it fills | viewer-core's data layer, the site config and the router |
|
|
19
19
|
| `@museumwnf/viewer-layout/components` | composed views | `SiteShell`, the frame composed from `dataset.config.js` | the site config and the current route |
|
|
20
20
|
| `@museumwnf/viewer-layout/dxa` | DXA family layer | the gallery and exhibition pages and shells, the family-only blocks, `standardRoutes`, `galleryConfig` / `exhibitionConfig` | the entries above, `@museumwnf/viewer-core` and `@museumwnf/viewer-core/dxa` |
|
|
21
|
+
| `@museumwnf/viewer-layout/dxa/gallery.css`, `/dxa/exhibition.css` | DXA family layer | each family's stylesheet: its fonts, page reset and page column, and its theme as a function of the palette | the palette a site's `theme/tokens.css` sets |
|
|
22
|
+
| `@museumwnf/viewer-layout/dxa/testing` | DXA family layer | each family's smoke test, `describeGallerySmoke` / `describeExhibitionSmoke` | the site's config, texts and package, in the site's own Vitest |
|
|
21
23
|
| `@museumwnf/viewer-layout/style.css` | — | one stylesheet for every entry, the family styles included | — |
|
|
22
24
|
| `@museumwnf/viewer-layout/tokens.reference.css` | — | every token the package reads, with its fallback | — |
|
|
23
25
|
|
|
@@ -136,23 +138,25 @@ section — the mark in the header, the active view — not for rebuilding the
|
|
|
136
138
|
section. A website that needs something no prop expresses adds the prop
|
|
137
139
|
here, so the next website has it too.
|
|
138
140
|
|
|
139
|
-
Sections render top to bottom in this fixed order. Every section is optional: it renders nothing unless its slot or driving props are set. The default slot (→ `AppContent`) is where the router-view goes.
|
|
141
|
+
Sections render top to bottom in this fixed order, except that `navigation-placement="before-banner"` puts the navigation above the banner. Every section is optional: it renders nothing unless its slot or driving props are set. The default slot (→ `AppContent`) is where the router-view goes.
|
|
140
142
|
|
|
141
143
|
| Section | Slot | Props (on PageShell) | Events |
|
|
142
144
|
|---|---|---|---|
|
|
143
|
-
| `AppHeader` | `#header`, `#header-brand` | `header-home`, `header-brand`, `header-eyebrow`, `header-title`, `header-title-href`, `header-subtitle`, `header-logos`, `header-logos-title`, `header-links`, `search`, `languages`, `language`, `language-placement`, `language-style` | `search`, `update:language` |
|
|
145
|
+
| `AppHeader` | `#header`, `#header-brand` | `header-home`, `header-brand`, `header-brand-logo`, `header-eyebrow`, `header-title`, `header-title-href`, `header-subtitle`, `header-logos`, `header-logos-title`, `header-links`, `search`, `languages`, `language`, `language-placement`, `language-style` | `search`, `update:language` |
|
|
144
146
|
| `AppBanner` | `#banner` | `banner-variant`, `banner-image`, `banner-image-alt`, `banner-text`, `banner-caption`, `banner-caption-label`, `banner-eyebrow`, `banner-title`, `banner-title-href`, `banner-subtitle`, `banner-headline`, `banner-enter`, `banner-strapline` | — |
|
|
145
|
-
| `AppNavigation` | `#navigation` | `nav-links`, `notice`, `languages`, `language` | `update:language` |
|
|
147
|
+
| `AppNavigation` | `#navigation` | `nav-links`, `notice`, `languages`, `language`, `navigation-placement` | `update:language` |
|
|
146
148
|
| `AppContent` | default | — | — |
|
|
147
149
|
| `AppHyperlinks` | `#hyperlinks` | `hyperlinks-variant`, `hyperlinks-title`, `hyperlinks-title-href`, `hyperlinks-subtitle`, `hyperlinks` | — |
|
|
148
150
|
| `AppSponsors` | `#sponsors` | `sponsors-title`, `sponsors`, `sponsor-groups` | — |
|
|
149
|
-
| `AppFooter` | `#footer` | `footer-text`, `footer-links`, `footer-attribution-label`, `footer-attribution-text`, `footer-terms-href`, `footer-terms-label` | — |
|
|
151
|
+
| `AppFooter` | `#footer` | `footer-text`, `footer-links`, `footer-social`, `footer-attribution-label`, `footer-attribution-text`, `footer-terms-href`, `footer-terms-label` | — |
|
|
150
152
|
|
|
151
153
|
### The language switcher
|
|
152
154
|
|
|
153
155
|
`languages` is `['en']` or `[{ code, label }]`, `language` the active code.
|
|
154
156
|
`language-placement` says where the switcher renders: `navigation` (the
|
|
155
|
-
default, a select at the end of the navigation bar) or `
|
|
157
|
+
default, a select at the end of the navigation bar), `header`, or `none` (no
|
|
158
|
+
site-language switcher at all: legacy's galleries had only the record's own
|
|
159
|
+
bar);
|
|
156
160
|
`language-style` says how, `select` or `buttons`. Whichever renders emits
|
|
157
161
|
`update:language` with the code chosen.
|
|
158
162
|
|
|
@@ -239,13 +243,122 @@ renders before the routed content, `#after-content` after it (a dismissible
|
|
|
239
243
|
sponsor notice next to the router-view, say); `#header`, `#navigation`,
|
|
240
244
|
`#hyperlinks`, `#sponsors`, `#footer` pass straight through to `PageShell`.
|
|
241
245
|
|
|
242
|
-
|
|
243
|
-
|
|
246
|
+
The footer is legacy's unless the site says otherwise: MWNF's five portal
|
|
247
|
+
links and "© Museum With No Frontiers (MWNF) 2004–<year>" (since 3.4.0). With
|
|
248
|
+
`config.footer.rightsHolder: true`, and once the loaded package's
|
|
249
|
+
`manifest.rights` names a holder (`useSiteRights()`), it also renders the
|
|
250
|
+
attribution sentence — `rights.attribution`, or
|
|
244
251
|
the holder's name when the package carries no separate attribution text —
|
|
245
252
|
labelled `record.source.rightsHolder`, with a link labelled
|
|
246
|
-
`record.source.termsOfUse` to `rights.termsUrl`.
|
|
247
|
-
|
|
248
|
-
|
|
253
|
+
`record.source.termsOfUse` to `rights.termsUrl`. Legacy printed no such line,
|
|
254
|
+
so it is off by default.
|
|
255
|
+
|
|
256
|
+
### Site chrome: the logo, the chrome pictures, the social links
|
|
257
|
+
|
|
258
|
+
Since 3.4.0 a site supplies its own chrome files (decision D7 of
|
|
259
|
+
inventory-app#2233: logos, banners, tiles and backgrounds belong to their
|
|
260
|
+
website, not to the inventory nor to `images.museumwnf.org`). It keeps them
|
|
261
|
+
in its repository under `theme/assets/` and hands the layout one map of
|
|
262
|
+
them, built by Vite so every file is fingerprinted with the build:
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
// src/dataset.config.js
|
|
266
|
+
const chrome = import.meta.glob('../theme/assets/**/*.{jpg,jpeg,png,gif,svg}', {
|
|
267
|
+
eager: true, query: '?url', import: 'default',
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
export default { /* … */ chrome, brand: { logo: 'logo.png', alt: 'MWNF Logo' } }
|
|
271
|
+
// a DXA site: galleryConfig({ …, chrome }) / exhibitionConfig({ …, chrome })
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The map's keys are normalised to the path after `theme/assets/`, so
|
|
275
|
+
`'../theme/assets/chrome/thematic_gallery/thg_galleries/9/banner.jpg'` is
|
|
276
|
+
`chrome/thematic_gallery/thg_galleries/9/banner.jpg`. Two kinds of key:
|
|
277
|
+
|
|
278
|
+
| Key | What reads it |
|
|
279
|
+
| --- | --- |
|
|
280
|
+
| a file name at the root (`logo.png`, `dia.jpg`, …) | the part of the layout that names it (`brand.logo`, the DXA keys below) |
|
|
281
|
+
| `chrome/<path>` | an image the data package names by its legacy path (`banner_image_path`, `image_path`, `homepage_image_path`, a sibling gallery's `image_path`): the file is the package's path under `theme/assets/chrome/`. One file per path, whatever size the layout asks for |
|
|
282
|
+
|
|
283
|
+
A key a site doesn't supply falls back to what the layout drew before:
|
|
284
|
+
the package path on `config.media.legacyHost`, the "MWNF" text mark for the
|
|
285
|
+
logo, nothing for a background. So a site that supplies nothing renders as
|
|
286
|
+
it did on 3.3.
|
|
287
|
+
|
|
288
|
+
| Config | Shape | Notes |
|
|
289
|
+
| --- | --- | --- |
|
|
290
|
+
| `config.chrome` | `{ [path]: url }` | the map above |
|
|
291
|
+
| `config.brand` | `{ logo, alt }` | `logo` a key of `chrome` (or a URL), drawn in the header's brand cell; `alt` an entry name or text. The DXA configs set it (below) |
|
|
292
|
+
| `config.navigation.placement` | `'after-banner'` (default) \| `'before-banner'` \| `({ section }) => …` | where the menu goes: PageShell's `navigation-placement` |
|
|
293
|
+
| `config.navigation.socialLinks` | `[{ label, href, icon }]` | the footer's social-network icons, opt-in for any site; `mwnfSocialLinks` (package root) is legacy's six. `icon` is one of `youtube`, `x`, `facebook`, `instagram`, `weibo`, `linkedin` |
|
|
294
|
+
| `config.footer` | `{ rightsHolder }` | the footer is legacy's by default on every site: MWNF's five portal links (`config.navigation.footerLinks` replaces them) and "© Museum With No Frontiers (MWNF) 2004–<year>" (a `footer-text` the caller passes replaces it). `rightsHolder: true` adds the package's rights-holder attribution, which legacy never printed |
|
|
295
|
+
|
|
296
|
+
`SocialLinks` (package root, prop `links`) draws the icon links on their own,
|
|
297
|
+
for a site that writes its own `#footer`:
|
|
298
|
+
`<SocialLinks :links="mwnfSocialLinks" />`.
|
|
299
|
+
|
|
300
|
+
The favicon is not the layout's: every site ships `public/favicon.ico` and
|
|
301
|
+
declares it in its own `index.html` (`<link rel="icon" href="%BASE_URL%favicon.ico">`).
|
|
302
|
+
|
|
303
|
+
**DXA families.** `galleryConfig` sets `brand.logo` to `logo.png` (legacy
|
|
304
|
+
dxa-client's white mark), `exhibitionConfig` to `logo_black.png`. Besides
|
|
305
|
+
the logo, the family reads:
|
|
306
|
+
|
|
307
|
+
| Key | Family | Where | Legacy source |
|
|
308
|
+
| --- | --- | --- | --- |
|
|
309
|
+
| `logo.png` | gallery (and the hub) | the header | `dxa-client/src/assets/logo.png` |
|
|
310
|
+
| `logo_black.png` | exhibition | the header | `exhibitions-client/src/assets/logo_black.png` |
|
|
311
|
+
| `dia.jpg`, `dba.jpg`, `sh.jpg` | gallery | the home's Other Virtual Museums banners (flat colour blocks without them) | `dxa-client/src/assets/` |
|
|
312
|
+
| `world.png` | gallery | the glossary entry's header on the item sheet | `dxa-client/src/sites/<site>/world.png` (one per gallery) |
|
|
313
|
+
| `chrome/<gallery.banner_image_path>` | gallery | the banner, every page | `images.museumwnf.org/hi_res/<path>` |
|
|
314
|
+
| `chrome/<sibling_galleries[].image_path>` | gallery | the "Visit MWNF Galleries" tiles | `images.museumwnf.org/zoom/<path>` (legacy's tile size) |
|
|
315
|
+
| `chrome/<exhibition.banner_image_path>` | exhibition | the banner on inner pages | `images.museumwnf.org/hi_res/<path>` |
|
|
316
|
+
| `chrome/<exhibition.homepage_image_path>` | exhibition | the home banner (`home_image.jpg`) | `images.museumwnf.org/full/<path>` |
|
|
317
|
+
| `chrome/<exhibition.logos[].legacy_path>` | exhibition | the sponsors' logos (header and footer strip), unless `sponsorLogos` lists the site's own | `images.museumwnf.org/full/<path>` |
|
|
318
|
+
| `chrome/<homeLogos[].image>` | gallery (Glass) | the home's "Set up on the occasion of" logos | `images.museumwnf.org/gallery_logo/<path>` |
|
|
319
|
+
|
|
320
|
+
**Exhibition sponsors.** The sponsors' logos are the site's, not the
|
|
321
|
+
inventory's. `exhibitionConfig({ sponsorLogos })` takes the site's own list,
|
|
322
|
+
`[{ image, href, alt, category_id, display_order }]` (`image` a chrome key or a
|
|
323
|
+
URL, `alt` an entry name or text), in place of the package's. Without it each
|
|
324
|
+
entry of `exhibition.json`'s `logos` draws `chrome/<legacy_path>`, else legacy's
|
|
325
|
+
media host at that path; never the inventory's `image_url`. A picture in the
|
|
326
|
+
popup notice whose legacy address the site keeps a copy of
|
|
327
|
+
(`chrome/<the path after legacy's size segment>`, e.g. `chrome/upload/toronto.jpg`
|
|
328
|
+
for `…/full/upload/toronto.jpg`) is drawn from that copy.
|
|
329
|
+
|
|
330
|
+
Glass's home logo slot is the one gallery-specific block, declared by the
|
|
331
|
+
site because no package carries it:
|
|
332
|
+
|
|
333
|
+
```js
|
|
334
|
+
galleryConfig({
|
|
335
|
+
// …
|
|
336
|
+
homeLogos: [
|
|
337
|
+
{ image: 'thematic_gallery/thg_logos/dga/1.jpg', href: 'https://iyog2022.org/', alt: 'glass.home.iyogLogo' },
|
|
338
|
+
],
|
|
339
|
+
})
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
`image` is a `chrome/` path (the file at
|
|
343
|
+
`theme/assets/chrome/thematic_gallery/thg_logos/dga/1.jpg`), `alt` an entry
|
|
344
|
+
name in the site's own locales; the strip's heading is viewer-i18n's
|
|
345
|
+
`gallery.home.logosLabel` ("Set up on the occasion of").
|
|
346
|
+
|
|
347
|
+
A gallery shell for a site without a gallery package (the galleries hub,
|
|
348
|
+
legacy's gallery 45) takes its chrome from `config.galleryShell` instead,
|
|
349
|
+
each field optional and each winning over the package:
|
|
350
|
+
|
|
351
|
+
| `config.galleryShell` field | Shape |
|
|
352
|
+
| --- | --- |
|
|
353
|
+
| `headerEyebrow`, `headerTitle` | entry name or text: the header's title cell on inner pages |
|
|
354
|
+
| `bannerEyebrow`, `bannerTitle` | entry name or text: the line over the home banner's title ("Welcome to") and the title ("MWNF Galleries") |
|
|
355
|
+
| `bannerImage` | a `chrome` key or a URL |
|
|
356
|
+
| `bannerCaption` | `{ name, partner, location, country }` or a string, after "Detail from" |
|
|
357
|
+
| `notice` | `false` drops the menu's tip about the search bar (a site with no search) |
|
|
358
|
+
|
|
359
|
+
An empty string is "no line" (`bannerEyebrow: ''` drops "Discover MWNF
|
|
360
|
+
Galleries"); a field left out keeps the gallery's own. The header fields
|
|
361
|
+
apply on inner pages only, as the home page's header has no title.
|
|
249
362
|
|
|
250
363
|
## Sections (standalone use)
|
|
251
364
|
|
|
@@ -432,8 +545,8 @@ export default {
|
|
|
432
545
|
| View | Declaration | Slots |
|
|
433
546
|
|---|---|---|
|
|
434
547
|
| `HomeView` | `config.home` or the same as props: `title`, `intro` (Markdown), `cards: [{ title, description, action, to \| href }]`, `featured: { entity, heading, action, route, eyebrow, meta, seed, filter }` — the pick is `useFeaturedRecord`, among the records `filter` keeps (viewer-core 2.2.0) — `panels` (the welcome and the record as `.mwnf-panel` boxes) | `before`, default, `after` |
|
|
435
|
-
| `CatalogueResultsView` | `spec`: `entity`, `keys`, `facets` (viewer-core's facet spec), `facetScope: 'all' \| 'matching'`, `controls: [{ key, type: 'select' \| 'year' \| 'query' \| 'checkbox', label, placeholder, anyLabel, hideEmpty }]`, `filterMode: 'apply' \| 'immediate'`, `scope(record, filters)`, `match(record, filters)`, `narrow(list, filters, helpers)` (a rule over the whole list — a keyword index, say), `dates: { mode, begin, end }`, `sort`, `pageSize`, `variant: 'list' \| 'grid'`, `record(record, helpers)`, `recordRoute`, `summary(context)`, `title`, `filterTitle`, `empty`, `actionLabel`, `pagination` | `before`, `filters`, `actions`, `aside`, `empty`, `after` — each given `{ filters, active, apply, reset, goToPage, matching, pageInfo, options }`, enough to compose the panel in the aside or a second pagination |
|
|
436
|
-
| `RecordView` | `spec` and `id`: `entity`, `translations`, `attribution`, `fields` (viewer-core's `sheetRows` spec, or a function of the context), `sections`, `layout`, `shortDescription`, `media(record, ctx)`, `mediaVariant`, `credits`, `workingNumber`, `citation: { project, permalink: true \| false \| string, heading } \| false` (the permalink is `sourceUrl(currentRoute)` — null, so no address, until the website declares `site.origin` — unless the spec disables it with `false` or overrides it with a string), `related: { variant, heading, record, route } \| false`, `back: { label, to \| href }`, `title(ctx)` | `header`, `before-sheet`, `after-sheet`, `aside`, `source` (under the citation; default `SourceCredit`), `related`, `after`, and one named after every `custom` or `link` row — each given `{ record, text, language, languages, select, dir, glossary, ready, attribution, t, tr }`; `related` also `records` (the rows) and `outside` (the related records the package does not carry) |
|
|
548
|
+
| `CatalogueResultsView` | `spec`: `entity`, `keys`, `facets` (viewer-core's facet spec), `facetScope: 'all' \| 'matching'`, `controls: [{ key, type: 'select' \| 'year' \| 'query' \| 'checkbox', label, placeholder, anyLabel, hideEmpty }]`, `filterMode: 'apply' \| 'immediate'`, `scope(record, filters)`, `match(record, filters)`, `narrow(list, filters, helpers)` (a rule over the whole list — a keyword index, say), `dates: { mode, begin, end }`, `sort`, `pageSize`, `variant: 'list' \| 'grid'`, `boxed: true` (the results in the site's content box: framed by the `.mwnf-panel` tokens, a gap under the filters, narrow year fields), `record(record, helpers)`, `recordRoute`, `summary(context)`, `title`, `filterTitle`, `empty`, `actionLabel`, `pagination` | `before`, `filters`, `actions`, `aside`, `empty`, `after` — each given `{ filters, active, apply, reset, goToPage, matching, pageInfo, options }`, enough to compose the panel in the aside or a second pagination |
|
|
549
|
+
| `RecordView` | `spec` and `id`: `entity`, `translations`, `attribution`, `fields` (viewer-core's `sheetRows` spec, or a function of the context), `sections`, `layout`, `shortDescription`, `media(record, ctx)`, `mediaVariant`, `spaced: true` (a gap under every block of pictures and under the sheet), `credits`, `workingNumber`, `citation: { project, permalink: true \| false \| string, heading } \| false` (the permalink is `sourceUrl(currentRoute)` — null, so no address, until the website declares `site.origin` — unless the spec disables it with `false` or overrides it with a string), `related: { variant, heading, record, route } \| false`, `back: { label, to \| href }`, `title(ctx)` | `header`, `before-sheet`, `after-sheet`, `aside`, `source` (under the citation; default `SourceCredit`), `related`, `after`, and one named after every `custom` or `link` row — each given `{ record, text, language, languages, select, dir, glossary, ready, attribution, t, tr }`; `related` also `records` (the rows) and `outside` (the related records the package does not carry) |
|
|
437
550
|
| `ItemDetailView` (`/dxa`) | Every `RecordView` prop (`spec`, `id`, `entity`) plus `dataGetter(id) => record \| null \| undefined` — a website's own language-subset record lookup (an exhibition's per-build `itemById.get`); omitted, every `id` `RecordView` itself finds is treated as present (the gallery shape); supplied and it reports `id` missing, `NotFoundView` renders before `RecordView` ever mounts (the exhibition shape's per-language-build 404), and it also narrows the related block's `records`/outside-reference split the same way. The DXA gallery/exhibition item sheet's own blocks, on top of `spec`: `sourceDatabase: { label?, chipClass(record, ctx), addToCollection: { label? } \| false } \| false` (the source-database line + `backward_compatibility` code + "add to my collection" link — `chipClass` is a site's own project→colour map, the name comes from `useProjects()`), `notice: { show(record, ctx), label } \| false` (the Explore-partner notice), `museum: { route(partnerId, ctx) } \| false` (the holding-museum row: the item's holder text, then the partner as `PartnerPanel`'s `summary` — "About {name}, {city}, {country}" — linked through `route`; `route` returning null keeps the name without a link, for a hidden partner; `false` keeps the holder text alone; decision D3), and on `spec.related`: `title`, `description` (entries, above the block), `notInPackageLabel`, `outsideChip(ref, ctx)` (an outside reference's chip — `TODO(#1727)`, no `project_id` on a stub yet), `artisticIntroductionLabel` (with `useProjects().links(record.project_id).artisticIntroductionUrl`), `databaseLabel` (ditto, `.relatedDatabaseUrl`), `overallDatabase: { label, linkLabel } \| false` (`mwnfLinks.overallDatabase`), `onDisplayIn: { linkPendingLabel } \| false` (`record.gallery_references`, by `kind`), `download: false` (default on, `record.action.download`/`.downloadPdf`, prints), `glossary: false` (default on, `GlossaryTool`), `dynasties(record, language, ctx) => { records, tr } \| null` (`DynastyList`), `media: false` (default on, `record.media`, a `SheetSection`), `timeline(record, ctx) => TimelineInfo \| null` (`TimelineLookup` — see `docs/slot-catalogue.md`) | Every `RecordView` slot, forwarded straight through by name, unmodified, **except** `before-sheet`/`museum`/`related`: each always has this view's own default content (above), which a website's own slot still replaces entirely — "a slot fills, the default content renders otherwise" |
|
|
438
551
|
| `EssayView` | `spec` and `id`: `tree` (a `useCollectionTree` result, or `{ purpose \| rootId, childType?, entity?, order? }` / `{ themes: true \| 'themes', childType? }` for the view to build one), `entity` (the tree's items — also the tree's own translations entity when `tree` carries none of its own, a pre-built tree or a declarative form with no `entity`/`themes`; falls back to `'collections'`), `route` (a node's own page: a route name or `(node, ctx) => to \| href`), `heading(ctx)`, `placeholder` (a regex a synthesized title matches, falling back to the English title, then the internal name), `quote` / `body` (a field of the node's translation, a dotted path into it such as `'extra.intro_text'`, or a function `(ctx) => Markdown`; default `'quote'`/`'description'`, `false` to drop), `glossary`, `items: { of(node) => ids, caption(item, node, ctx) => override, meta(item, ctx) => [string] (the grid's caption lines), badge(item, ctx) => string, route }`, `panel: { variants(item, ctx) => [{ id, image, alt, caption: { title, justification, fields: [{ label (entry name), value }] } }], fields(item, node, ctx) => [{ label, value }] (the fallback when a variant carries no fields of its own) } \| false`, `navigation: 'tree' \| 'siblings' \| false` (`tree` crosses a branch boundary, `siblings` stays inside the parent), `breadcrumb`, `tabs: true \| 'siblings' \| 'children'` (the strip: `true`/`'siblings'` — the node's own siblings, the default; `'children'` — the node's own children, e.g. a theme's chapters), `about(node) => boolean \| { panel?, navigation? }` (essay only; a plain boolean drops both the picture panel and the navigation, an object keeps the named piece instead), `aboutKeeps: ['panel' \| 'navigation']` (the spec-wide equivalent, when every about page in this spec keeps the same piece), `numbering: 'roman' \| 'decimal' \| false` (counts a node among its true siblings — for a themes-package tree, whose `root` is `null`, that's every node whose own `tree.parents(id)` is also empty, so a themes tree numbers its top-level themes I, II, III); `previous`, `next`, `backTo`, `inThisTheme` (the strip's label), `seeAll` (the panel's link to the selected record) — entry names, defaulting to shared entries every bundle carries: `core.pagination.previous`/`.next`, `record.action.backToResults`, `core.nav.inThisSection`, `catalogue.results.seeDatabaseEntry` | `header`, `before-body`, `after-body`, `panel`, `thumbnails`, `aside`, `justifications`, `navigation`, `after` (default `SourceCredit` — nothing until the website declares `site.origin`) — each given `{ node, text, language, tree, items, selected, select, selectedVariant, selectVariant, breadcrumb, previous, next, t, tr }` |
|
|
439
552
|
| `LinkListView` | `spec`: `title` (entry), `groups: [{ heading (entry), links: [{ label, href \| to, note? }] }] \| (ctx) => groups` (`label`/`note` are Markdown, rendered inline through `mdInline`), `back: { label, to \| href } \| false`, `empty` (entry) | `before`, `group` (given `{ group }`; the default renders the heading and its links — replace it for a citation list that is not link-shaped), `after` |
|
|
@@ -557,10 +670,52 @@ every `legacyRoutes` resolver targeting those names) working unmodified.
|
|
|
557
670
|
Full page-by-page prop/slot/entry table in
|
|
558
671
|
[`docs/slot-catalogue.md`](docs/slot-catalogue.md#dxa-family-pages-museumwnfviewer-layoutdxa).
|
|
559
672
|
|
|
673
|
+
### The family's stylesheet, theme and smoke test
|
|
674
|
+
|
|
675
|
+
Since 3.3.0 what every site of a family shared by copy is here once:
|
|
676
|
+
|
|
677
|
+
- **`@museumwnf/viewer-layout/dxa/gallery.css`** and **`/dxa/exhibition.css`**:
|
|
678
|
+
the fonts, the page reset, the 1350px page column with its sticky header
|
|
679
|
+
and menu grid, and the family's theme — every `--mwnf-*` token the family
|
|
680
|
+
sets, read from the palette. A site imports its family's stylesheet after
|
|
681
|
+
`style.css` and before its own theme, so that its own values win:
|
|
682
|
+
|
|
683
|
+
```js
|
|
684
|
+
import '@museumwnf/viewer-layout/style.css'
|
|
685
|
+
import '@museumwnf/viewer-layout/dxa/gallery.css'
|
|
686
|
+
import '../theme/tokens.css'
|
|
687
|
+
import '../theme/overrides.css'
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
The site's `theme/tokens.css` then holds its palette — legacy's five
|
|
691
|
+
colours for a gallery (`--theme-dark`, `--theme-medium-dark`,
|
|
692
|
+
`--theme-medium`, `--theme-light`, `--background-color`), legacy's six for
|
|
693
|
+
an exhibition (`--main-color`, `--secondary-color`, `--contrast-color` and
|
|
694
|
+
their `-text-color`s) — and any token that differs from the family's.
|
|
695
|
+
`theme/overrides.css` stays the escape hatch.
|
|
696
|
+
- **`@museumwnf/viewer-layout/dxa/testing`**: `describeGallerySmoke` and
|
|
697
|
+
`describeExhibitionSmoke`, the smoke test every site of the family runs.
|
|
698
|
+
A site's `tests/smoke.test.js` calls its family's with its config, its
|
|
699
|
+
texts, its package and — for a gallery — the records of its own dataset the
|
|
700
|
+
tests look for (the function's documentation names each), and may add
|
|
701
|
+
tests of its own after the call. The suite runs in the site's own Vitest,
|
|
702
|
+
which processes this package (viewer-core's `defineViewerConfig` inlines
|
|
703
|
+
it).
|
|
704
|
+
|
|
560
705
|
## Theming
|
|
561
706
|
|
|
562
707
|
Every color, font, spacing, radius comes from a `--mwnf-*` CSS custom property with a neutral fallback. Full list: [`tokens.reference.css`](src/tokens.reference.css) (also exported as `@museumwnf/viewer-layout/tokens.reference.css`) — copy it into your website as `theme/tokens.css` and set values.
|
|
563
708
|
|
|
709
|
+
**Links read one colour.** Every link takes `--mwnf-link-text`, and
|
|
710
|
+
`--mwnf-link-hover-text` where it changes colour under the pointer. A
|
|
711
|
+
component whose links a site may want different has a token of its own that
|
|
712
|
+
falls back to them — `--mwnf-back-link-color`, `--mwnf-link-list-link-color`,
|
|
713
|
+
`--mwnf-partner-link-color`, `--mwnf-dxa-item-link`,
|
|
714
|
+
`--mwnf-related-media-link-color`, `--mwnf-on-display-link-color`,
|
|
715
|
+
`--mwnf-card-accordion-child-hover-color`. **`--mwnf-color-accent` is a
|
|
716
|
+
surface colour** (active backgrounds, rules, bands) and colours no text: a
|
|
717
|
+
theme can paint its menu or its bands in it without hiding a link.
|
|
718
|
+
|
|
564
719
|
Below `48rem` the navigation folds its links behind a menu button, the
|
|
565
720
|
`split` banner stacks its two columns, and the banner captions are hidden.
|
|
566
721
|
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { t as e } from "./chrome-DPuPeWzV.js";
|
|
2
|
+
import { n as t, o as n } from "./TimelineEventList-COjkXEzS.js";
|
|
3
|
+
import { i as r, n as i, o as a, r as o, t as s } from "./OnDisplayIn-Dv8i7uvH.js";
|
|
4
|
+
import { s as c } from "./TimelineResultsView-ChkBn27W.js";
|
|
5
|
+
import { Fragment as l, computed as u, createBlock as d, createCommentVNode as f, createElementBlock as p, createElementVNode as m, createSlots as ee, createTextVNode as h, createVNode as g, guardReactiveProps as _, normalizeClass as v, normalizeProps as y, normalizeStyle as te, openBlock as b, renderList as x, renderSlot as S, toDisplayString as C, unref as w, useSlots as ne, withCtx as T } from "vue";
|
|
6
|
+
import { NotFoundView as re, byId as E, loadEntities as ie, mdInline as D, mdStrip as ae, mwnfLinks as O, partnerView as oe, useDataPackage as se, useI18n as ce, useProjects as le, useSiteConfig as ue } from "@museumwnf/viewer-core";
|
|
7
|
+
//#region src/dxa/ItemDetailView.vue
|
|
8
|
+
var k = {
|
|
9
|
+
key: 0,
|
|
10
|
+
class: "mwnf-sheet-source"
|
|
11
|
+
}, A = {
|
|
12
|
+
key: 0,
|
|
13
|
+
class: "mwnf-sheet-source__line"
|
|
14
|
+
}, j = {
|
|
15
|
+
key: 1,
|
|
16
|
+
class: "mwnf-sheet-source__collection"
|
|
17
|
+
}, M = ["href"], N = {
|
|
18
|
+
key: 1,
|
|
19
|
+
class: "mwnf-sheet-notice"
|
|
20
|
+
}, P = {
|
|
21
|
+
key: "museum",
|
|
22
|
+
class: "mwnf-sheet-museum"
|
|
23
|
+
}, F = ["innerHTML"], I = {
|
|
24
|
+
key: 0,
|
|
25
|
+
class: "mwnf-sheet-related"
|
|
26
|
+
}, L = {
|
|
27
|
+
key: 0,
|
|
28
|
+
class: "mwnf-sheet-related__heading mwnf-sheet-related__heading--caps"
|
|
29
|
+
}, R = {
|
|
30
|
+
key: 1,
|
|
31
|
+
class: "mwnf-sheet-related__description"
|
|
32
|
+
}, z = {
|
|
33
|
+
key: 0,
|
|
34
|
+
class: "mwnf-sheet-related__references"
|
|
35
|
+
}, B = {
|
|
36
|
+
key: 2,
|
|
37
|
+
class: "mwnf-sheet-related__unresolved"
|
|
38
|
+
}, V = {
|
|
39
|
+
key: 3,
|
|
40
|
+
class: "mwnf-sheet-related__line"
|
|
41
|
+
}, H = ["href"], U = { key: 7 }, de = { class: "mwnf-sheet-related__heading" }, fe = { key: 8 }, pe = { class: "mwnf-sheet-related__heading" }, me = { class: "mwnf-sheet-related__line" }, he = ["href"], ge = { key: 9 }, _e = { class: "mwnf-sheet-related__heading" }, ve = { class: "mwnf-sheet-related__line" }, ye = ["href"], be = { key: 10 }, xe = { class: "mwnf-sheet-related__heading" }, Se = "sheet.field.", W = {
|
|
42
|
+
__name: "ItemDetailView",
|
|
43
|
+
props: {
|
|
44
|
+
spec: {
|
|
45
|
+
type: Object,
|
|
46
|
+
required: !0
|
|
47
|
+
},
|
|
48
|
+
id: {
|
|
49
|
+
type: String,
|
|
50
|
+
required: !0
|
|
51
|
+
},
|
|
52
|
+
entity: {
|
|
53
|
+
type: String,
|
|
54
|
+
default: ""
|
|
55
|
+
},
|
|
56
|
+
dataGetter: {
|
|
57
|
+
type: Function,
|
|
58
|
+
default: null
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
setup(W) {
|
|
62
|
+
let G = W, Ce = ne(), we = /* @__PURE__ */ new Set([
|
|
63
|
+
"before-sheet",
|
|
64
|
+
"museum",
|
|
65
|
+
"related",
|
|
66
|
+
"aside"
|
|
67
|
+
]), Te = u(() => Object.keys(Ce).filter((e) => !we.has(e))), Ee = u(() => !G.dataGetter || G.dataGetter(G.id) != null), { t: K } = ce();
|
|
68
|
+
function De(e) {
|
|
69
|
+
if (typeof e != "string" || !e.startsWith(Se)) return e;
|
|
70
|
+
let t = `sheet.dxa.${e.slice(12)}`;
|
|
71
|
+
return K(t) === t ? e : t;
|
|
72
|
+
}
|
|
73
|
+
let q = u(() => Array.isArray(G.spec.fields) ? {
|
|
74
|
+
...G.spec,
|
|
75
|
+
fields: G.spec.fields.map((e) => ({
|
|
76
|
+
...e,
|
|
77
|
+
label: De(e.label)
|
|
78
|
+
}))
|
|
79
|
+
} : G.spec), J = le(), Y = (e, t) => (e.name ?? "").localeCompare(t.name ?? ""), Oe = (e) => (e.gallery_references ?? []).filter((e) => e.kind === "gallery").sort(Y), X = (e) => (e.gallery_references ?? []).filter((e) => e.kind === "exhibition").sort(Y), Z = (e) => J.links(e.project_id)?.artisticIntroductionUrl ?? null, Q = (e) => J.links(e.project_id)?.relatedDatabaseUrl ?? null;
|
|
80
|
+
function ke(e, t) {
|
|
81
|
+
if (!e) return null;
|
|
82
|
+
let n = q.value.sourceDatabase === !1 ? null : q.value.sourceDatabase ?? null, r = null;
|
|
83
|
+
if (n) {
|
|
84
|
+
let i = n.chipClass ? n.chipClass(e, t) : null, a = J.label(e.project_id);
|
|
85
|
+
(i || a) && (r = {
|
|
86
|
+
chipClass: i,
|
|
87
|
+
name: a,
|
|
88
|
+
label: K(n.label ?? "record.sheet.sourceDatabase")
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
let i = n && n.addToCollection !== !1 ? K(n.addToCollection?.label ?? "record.action.addToCollection") : null, a = q.value.notice === !1 ? null : q.value.notice ?? null, o = a && a.show(e, t) ? K(a.label) : null;
|
|
92
|
+
return {
|
|
93
|
+
source: r,
|
|
94
|
+
addToCollectionLabel: i,
|
|
95
|
+
notice: o
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
let $ = se(), Ae = E("partners"), je = E("countries");
|
|
99
|
+
ie(["partners", "countries"]), $.loadTranslations("countries", "en");
|
|
100
|
+
function Me(e, t) {
|
|
101
|
+
let n = $.tr("countries", e, t, "en");
|
|
102
|
+
return ae(n.name ?? je.value?.get(e)?.internal_name ?? "");
|
|
103
|
+
}
|
|
104
|
+
function Ne(e) {
|
|
105
|
+
let t = e.text?.holder ? D(String(e.text.holder)) : "", n = q.value.museum === !1 ? null : q.value.museum ?? null, r = n ? Ae.value?.get(e.record?.partner_id) : null;
|
|
106
|
+
return {
|
|
107
|
+
holder: t,
|
|
108
|
+
view: r ? oe(r, $.tr("partners", r.id, e.language, "en"), {
|
|
109
|
+
countryLabel: (t) => Me(t, e.language),
|
|
110
|
+
route: (t) => n.route ? n.route(t.id, e) : null
|
|
111
|
+
}) : null
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function Pe(e, t) {
|
|
115
|
+
if (!e) return null;
|
|
116
|
+
let n = q.value.related ?? {}, r = t.records ?? [], i = t.outside ?? [], a = G.dataGetter ? r.filter((e) => G.dataGetter(e.id) != null) : r, o = G.dataGetter ? r.filter((e) => G.dataGetter(e.id) == null).map((t) => (e.related_items ?? []).find((e) => e.id === t.id)).filter(Boolean) : [], s = [...i, ...o].map((e) => ({
|
|
117
|
+
...e,
|
|
118
|
+
name: e.project_id ? J.label(e.project_id) : null,
|
|
119
|
+
chipClass: n.outsideChip ? n.outsideChip(e, t) : null
|
|
120
|
+
})), c = (e) => ({
|
|
121
|
+
id: e.id,
|
|
122
|
+
label: D(e.name ?? ""),
|
|
123
|
+
href: e.legacy_host || "",
|
|
124
|
+
external: !!e.legacy_host
|
|
125
|
+
}), l = n.onDisplayIn && n.onDisplayIn !== !1 ? {
|
|
126
|
+
pendingLabel: n.onDisplayIn.linkPendingLabel ?? "",
|
|
127
|
+
groups: [{
|
|
128
|
+
heading: "record.related.exhibitions",
|
|
129
|
+
links: X(e).map(c)
|
|
130
|
+
}, {
|
|
131
|
+
heading: "record.related.galleries",
|
|
132
|
+
links: Oe(e).map(c)
|
|
133
|
+
}].filter((e) => e.links.length)
|
|
134
|
+
} : null, u = n.databaseLabel && Q(e) ? {
|
|
135
|
+
url: Q(e),
|
|
136
|
+
label: K(n.databaseLabel),
|
|
137
|
+
name: J.label(e.project_id)
|
|
138
|
+
} : null, d = n.overallDatabase && n.overallDatabase !== !1 ? {
|
|
139
|
+
label: K(n.overallDatabase.label),
|
|
140
|
+
linkLabel: K(n.overallDatabase.linkLabel)
|
|
141
|
+
} : null;
|
|
142
|
+
return {
|
|
143
|
+
title: n.title ? K(n.title) : "",
|
|
144
|
+
description: n.description ? K(n.description) : "",
|
|
145
|
+
heading: K(n.heading ?? "record.related.items"),
|
|
146
|
+
variant: n.variant ?? "grid",
|
|
147
|
+
actionLabel: n.actionLabel ? K(n.actionLabel) : "",
|
|
148
|
+
inPackage: a,
|
|
149
|
+
references: s,
|
|
150
|
+
notInPackageLabel: n.notInPackageLabel ? K(n.notInPackageLabel) : "",
|
|
151
|
+
artisticIntroduction: n.artisticIntroductionLabel && Z(e) ? {
|
|
152
|
+
url: Z(e),
|
|
153
|
+
label: K(n.artisticIntroductionLabel)
|
|
154
|
+
} : null,
|
|
155
|
+
timeline: n.timeline ? n.timeline(e, t) : null,
|
|
156
|
+
glossary: n.glossary !== !1,
|
|
157
|
+
dynasties: n.dynasties ? n.dynasties(e, t.language, t) : null,
|
|
158
|
+
media: n.media === !1 ? [] : e.media ?? [],
|
|
159
|
+
onDisplayIn: l,
|
|
160
|
+
database: u,
|
|
161
|
+
overallDatabase: d,
|
|
162
|
+
download: n.download === !1 ? null : {
|
|
163
|
+
label: K("record.action.download"),
|
|
164
|
+
pdfLabel: K("record.action.downloadPdf")
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
let Fe = ue(), Ie = u(() => {
|
|
169
|
+
let t = e(Fe.chrome, "world.png");
|
|
170
|
+
return t ? { "--mwnf-dxa-glossary-image": `url("${t}")` } : null;
|
|
171
|
+
});
|
|
172
|
+
function Le() {
|
|
173
|
+
window.print();
|
|
174
|
+
}
|
|
175
|
+
return (e, u) => Ee.value ? (b(), d(c, {
|
|
176
|
+
key: 0,
|
|
177
|
+
spec: q.value,
|
|
178
|
+
id: W.id,
|
|
179
|
+
entity: W.entity,
|
|
180
|
+
style: te(Ie.value)
|
|
181
|
+
}, ee({
|
|
182
|
+
"before-sheet": T((t) => [S(e.$slots, "before-sheet", y(_(t)), () => [(b(!0), p(l, null, x([ke(t.record, t)], (e) => (b(), p(l, { key: "before-sheet" }, [e?.source || e?.addToCollectionLabel ? (b(), p("div", k, [e.source ? (b(), p("p", A, [e.source.chipClass ? (b(), p("span", {
|
|
183
|
+
key: 0,
|
|
184
|
+
class: v(["mwnf-chip", e.source.chipClass]),
|
|
185
|
+
"aria-hidden": "true"
|
|
186
|
+
}, null, 2)) : f("", !0), e.source.name ? (b(), p(l, { key: 1 }, [h(C(e.source.label) + ": " + C(e.source.name), 1)], 64)) : f("", !0)])) : f("", !0), e.addToCollectionLabel ? (b(), p("p", j, [m("a", {
|
|
187
|
+
href: w(O).myCollection,
|
|
188
|
+
target: "_blank",
|
|
189
|
+
rel: "noopener"
|
|
190
|
+
}, "↗ " + C(e.addToCollectionLabel), 9, M)])) : f("", !0)])) : f("", !0), e?.notice ? (b(), p("div", N, [h(C(e.notice) + " ", 1), m("strong", null, [m("em", null, C(t.languages.map((e) => e.label).join(", ")), 1)])])) : f("", !0)], 64))), 128))])]),
|
|
191
|
+
museum: T((n) => [S(e.$slots, "museum", y(_(n)), () => [(b(!0), p(l, null, x([Ne(n)], (e) => (b(), p("div", P, [e.holder ? (b(), p("p", {
|
|
192
|
+
key: 0,
|
|
193
|
+
class: "mwnf-sheet-museum__holder",
|
|
194
|
+
innerHTML: e.holder
|
|
195
|
+
}, null, 8, F)) : f("", !0), e.view ? (b(), d(t, {
|
|
196
|
+
key: 1,
|
|
197
|
+
variant: "summary",
|
|
198
|
+
partner: e.view,
|
|
199
|
+
label: "partner.info.about",
|
|
200
|
+
dir: n.dir
|
|
201
|
+
}, null, 8, ["partner", "dir"])) : f("", !0)]))), 128))])]),
|
|
202
|
+
related: T(() => []),
|
|
203
|
+
aside: T((t) => [S(e.$slots, "related", y(_(t)), () => [(b(!0), p(l, null, x([Pe(t.record, t)], (e) => (b(), p(l, { key: t.record?.id ?? "related" }, [e ? (b(), p("div", I, [
|
|
204
|
+
e.title ? (b(), p("p", L, C(e.title), 1)) : f("", !0),
|
|
205
|
+
e.description ? (b(), p("p", R, C(e.description), 1)) : f("", !0),
|
|
206
|
+
e.inPackage.length || e.references.length ? (b(), d(n, {
|
|
207
|
+
key: 2,
|
|
208
|
+
heading: e.heading,
|
|
209
|
+
records: e.inPackage,
|
|
210
|
+
variant: e.variant,
|
|
211
|
+
"action-label": e.actionLabel
|
|
212
|
+
}, {
|
|
213
|
+
default: T(() => [e.references.length ? (b(), p("ul", z, [(b(!0), p(l, null, x(e.references, (t) => (b(), p("li", { key: t.id }, [
|
|
214
|
+
t.chipClass ? (b(), p("span", {
|
|
215
|
+
key: 0,
|
|
216
|
+
class: v(["mwnf-chip", t.chipClass]),
|
|
217
|
+
"aria-hidden": "true"
|
|
218
|
+
}, null, 2)) : f("", !0),
|
|
219
|
+
t.name ? (b(), p(l, { key: 1 }, [h(C(t.name), 1)], 64)) : f("", !0),
|
|
220
|
+
e.notInPackageLabel ? (b(), p("span", B, C(e.notInPackageLabel), 1)) : f("", !0)
|
|
221
|
+
]))), 128))])) : f("", !0)]),
|
|
222
|
+
_: 2
|
|
223
|
+
}, 1032, [
|
|
224
|
+
"heading",
|
|
225
|
+
"records",
|
|
226
|
+
"variant",
|
|
227
|
+
"action-label"
|
|
228
|
+
])) : f("", !0),
|
|
229
|
+
e.artisticIntroduction ? (b(), p("p", V, [m("a", {
|
|
230
|
+
href: e.artisticIntroduction.url,
|
|
231
|
+
target: "_blank",
|
|
232
|
+
rel: "noopener"
|
|
233
|
+
}, "↗ " + C(e.artisticIntroduction.label), 9, H)])) : f("", !0),
|
|
234
|
+
e.timeline ? (b(), d(o, {
|
|
235
|
+
key: t.record.id,
|
|
236
|
+
info: e.timeline
|
|
237
|
+
}, null, 8, ["info"])) : f("", !0),
|
|
238
|
+
e.glossary ? (b(), d(a, {
|
|
239
|
+
key: 5,
|
|
240
|
+
language: t.language,
|
|
241
|
+
dir: t.dir
|
|
242
|
+
}, null, 8, ["language", "dir"])) : f("", !0),
|
|
243
|
+
e.dynasties?.records?.length ? (b(), d(r, {
|
|
244
|
+
key: 6,
|
|
245
|
+
heading: w(K)("record.dynasty.list"),
|
|
246
|
+
dynasties: e.dynasties.records,
|
|
247
|
+
tr: e.dynasties.tr,
|
|
248
|
+
dir: t.dir
|
|
249
|
+
}, null, 8, [
|
|
250
|
+
"heading",
|
|
251
|
+
"dynasties",
|
|
252
|
+
"tr",
|
|
253
|
+
"dir"
|
|
254
|
+
])) : f("", !0),
|
|
255
|
+
g(i, {
|
|
256
|
+
media: e.media,
|
|
257
|
+
descriptions: !1,
|
|
258
|
+
dir: t.dir
|
|
259
|
+
}, null, 8, ["media", "dir"]),
|
|
260
|
+
e.onDisplayIn?.groups.length ? (b(), p("div", U, [m("p", de, C(w(K)("record.related.onDisplayIn")), 1), g(s, {
|
|
261
|
+
heading: "",
|
|
262
|
+
groups: e.onDisplayIn.groups,
|
|
263
|
+
"pending-label": e.onDisplayIn.pendingLabel,
|
|
264
|
+
dir: t.dir
|
|
265
|
+
}, null, 8, [
|
|
266
|
+
"groups",
|
|
267
|
+
"pending-label",
|
|
268
|
+
"dir"
|
|
269
|
+
])])) : f("", !0),
|
|
270
|
+
e.database ? (b(), p("div", fe, [m("p", pe, C(e.database.label), 1), m("p", me, [m("a", {
|
|
271
|
+
href: e.database.url,
|
|
272
|
+
target: "_blank",
|
|
273
|
+
rel: "noopener"
|
|
274
|
+
}, "↗ " + C(e.database.name), 9, he)])])) : f("", !0),
|
|
275
|
+
e.overallDatabase ? (b(), p("div", ge, [m("p", _e, C(e.overallDatabase.label), 1), m("p", ve, [m("a", {
|
|
276
|
+
href: w(O).overallDatabase,
|
|
277
|
+
target: "_blank",
|
|
278
|
+
rel: "noopener"
|
|
279
|
+
}, "↗ " + C(e.overallDatabase.linkLabel), 9, ye)])])) : f("", !0),
|
|
280
|
+
e.download ? (b(), p("div", be, [m("p", xe, C(e.download.label), 1), m("p", {
|
|
281
|
+
class: "mwnf-sheet-related__line mwnf-sheet-related__line--action",
|
|
282
|
+
onClick: Le
|
|
283
|
+
}, "➤ " + C(e.download.pdfLabel), 1)])) : f("", !0)
|
|
284
|
+
])) : f("", !0)], 64))), 128))])]),
|
|
285
|
+
_: 2
|
|
286
|
+
}, [x(Te.value, (t) => ({
|
|
287
|
+
name: t,
|
|
288
|
+
fn: T((n) => [S(e.$slots, t, y(_(n)))])
|
|
289
|
+
}))]), 1032, [
|
|
290
|
+
"spec",
|
|
291
|
+
"id",
|
|
292
|
+
"entity",
|
|
293
|
+
"style"
|
|
294
|
+
])) : (b(), d(w(re), { key: 1 }));
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
//#endregion
|
|
298
|
+
export { W as t };
|