@museumwnf/viewer-layout 3.3.0 → 3.5.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.
Files changed (34) hide show
  1. package/README.md +191 -12
  2. package/dist/{FeaturedRecord-BJ8LaWGP.js → FeaturedRecord-DJfyvfqt.js} +1 -1
  3. package/dist/GlossaryPopover-DcptyNWI.js +654 -0
  4. package/dist/ItemDetailView-COWC8GDg.js +299 -0
  5. package/dist/{OnDisplayIn-Dv8i7uvH.js → OnDisplayIn-BfJoPonn.js} +38 -38
  6. package/dist/RecordView-C9rP8TyQ.js +263 -0
  7. package/dist/SiteShell-4vV2jIzf.js +192 -0
  8. package/dist/{Theme-Db88mckV.js → Theme-CZ-OVXao.js} +26 -26
  9. package/dist/TimelineEventList-gsoc-SBx.js +841 -0
  10. package/dist/TimelineResultsView-C2-TnM71.js +1386 -0
  11. package/dist/chrome-DPuPeWzV.js +1141 -0
  12. package/dist/components.js +1 -1
  13. package/dist/{content-p0tqKkcD.js → content-CtwBcSjU.js} +2 -2
  14. package/dist/content.js +6 -5
  15. package/dist/data-CJlLA-Mf.js +38 -0
  16. package/dist/data-DTbAYdr2.js +40 -0
  17. package/dist/dxa.js +638 -519
  18. package/dist/index.js +7 -6
  19. package/dist/standalone.js +762 -0
  20. package/dist/{themeSpecs-C_uGarTs.js → themeSpecs-B885l456.js} +3 -2
  21. package/dist/viewer-layout.css +1 -1
  22. package/dist/views.js +5 -4
  23. package/package.json +4 -3
  24. package/src/dxa/testing.js +37 -14
  25. package/src/styles/dxa-exhibition.css +25 -1
  26. package/src/styles/dxa-gallery.css +249 -2
  27. package/src/tokens.reference.css +78 -0
  28. package/dist/ItemDetailView-CfUtRLOV.js +0 -284
  29. package/dist/PageShell-CbJ9lQoQ.js +0 -961
  30. package/dist/SiteShell-C3OgZO8p.js +0 -154
  31. package/dist/TimelineEventList-COjkXEzS.js +0 -1487
  32. package/dist/TimelineResultsView-CmHomvV_.js +0 -1636
  33. package/dist/data-BfyYB8ff.js +0 -33
  34. package/dist/data-G8uXeEfE.js +0 -35
package/README.md CHANGED
@@ -20,6 +20,7 @@ all the packages:
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
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
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 |
23
+ | `@museumwnf/viewer-layout/standalone` | standalone family layer | the chrome, home page, item sheet, text page and blocks of Discover Islamic Art, Discover Baroque Art and Sharing History | the entries above and `@museumwnf/viewer-core` |
23
24
  | `@museumwnf/viewer-layout/style.css` | — | one stylesheet for every entry, the family styles included | — |
24
25
  | `@museumwnf/viewer-layout/tokens.reference.css` | — | every token the package reads, with its fallback | — |
25
26
 
@@ -35,7 +36,8 @@ view does.
35
36
  1. **Into the lowest layer that fits.** A block comes before a composed view,
36
37
  and a composed view before a family page. A block is promoted here when
37
38
  several websites need the same thing; a whole page is shared only inside
38
- the DXA family, under `/dxa`.
39
+ a family: the DXA family under `/dxa`, the standalone family under
40
+ `/standalone`.
39
41
  2. **A generic component never defaults to one family's texts.** A block or a
40
42
  composed view defaults to a shared entry (`core.*`, `record.*`,
41
43
  `partner.*`, …) or takes the entry name as a prop; it never defaults to a
@@ -43,7 +45,8 @@ view does.
43
45
  3. **A component only the DXA family uses belongs under `/dxa`.**
44
46
 
45
47
  **The dependency runs one way.** The root, `/content`, `/views` and
46
- `/components` never import from `/dxa`. `/dxa` imports only what the other
48
+ `/components` never import from `/dxa` or `/standalone`, and the two
49
+ families never import from each other. Each imports only what the other
47
50
  entries publish, and `@museumwnf/viewer-core`. A component that moves
48
51
  between entries keeps its old export as an alias until the websites have
49
52
  moved; a major release then removes the alias.
@@ -138,23 +141,25 @@ section — the mark in the header, the active view — not for rebuilding the
138
141
  section. A website that needs something no prop expresses adds the prop
139
142
  here, so the next website has it too.
140
143
 
141
- 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.
144
+ 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.
142
145
 
143
146
  | Section | Slot | Props (on PageShell) | Events |
144
147
  |---|---|---|---|
145
- | `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` |
148
+ | `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` |
146
149
  | `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` | — |
147
- | `AppNavigation` | `#navigation` | `nav-links`, `notice`, `languages`, `language` | `update:language` |
150
+ | `AppNavigation` | `#navigation` | `nav-links`, `notice`, `languages`, `language`, `navigation-placement` | `update:language` |
148
151
  | `AppContent` | default | — | — |
149
152
  | `AppHyperlinks` | `#hyperlinks` | `hyperlinks-variant`, `hyperlinks-title`, `hyperlinks-title-href`, `hyperlinks-subtitle`, `hyperlinks` | — |
150
153
  | `AppSponsors` | `#sponsors` | `sponsors-title`, `sponsors`, `sponsor-groups` | — |
151
- | `AppFooter` | `#footer` | `footer-text`, `footer-links`, `footer-attribution-label`, `footer-attribution-text`, `footer-terms-href`, `footer-terms-label` | — |
154
+ | `AppFooter` | `#footer` | `footer-text`, `footer-links`, `footer-social`, `footer-attribution-label`, `footer-attribution-text`, `footer-terms-href`, `footer-terms-label` | — |
152
155
 
153
156
  ### The language switcher
154
157
 
155
158
  `languages` is `['en']` or `[{ code, label }]`, `language` the active code.
156
159
  `language-placement` says where the switcher renders: `navigation` (the
157
- default, a select at the end of the navigation bar) or `header`;
160
+ default, a select at the end of the navigation bar), `header`, or `none` (no
161
+ site-language switcher at all: legacy's galleries had only the record's own
162
+ bar);
158
163
  `language-style` says how, `select` or `buttons`. Whichever renders emits
159
164
  `update:language` with the code chosen.
160
165
 
@@ -241,13 +246,122 @@ renders before the routed content, `#after-content` after it (a dismissible
241
246
  sponsor notice next to the router-view, say); `#header`, `#navigation`,
242
247
  `#hyperlinks`, `#sponsors`, `#footer` pass straight through to `PageShell`.
243
248
 
244
- Once the loaded package's `manifest.rights` names a holder (`useSiteRights()`),
245
- the footer also renders the attribution sentence — `rights.attribution`, or
249
+ The footer is legacy's unless the site says otherwise: MWNF's five portal
250
+ links and "© Museum With No Frontiers (MWNF) 2004–<year>" (since 3.4.0). With
251
+ `config.footer.rightsHolder: true`, and once the loaded package's
252
+ `manifest.rights` names a holder (`useSiteRights()`), it also renders the
253
+ attribution sentence — `rights.attribution`, or
246
254
  the holder's name when the package carries no separate attribution text —
247
255
  labelled `record.source.rightsHolder`, with a link labelled
248
- `record.source.termsOfUse` to `rights.termsUrl`. A package built before the
249
- `rights` block existed carries no holder, so the footer renders exactly as
250
- it did before: `footer-text` alone.
256
+ `record.source.termsOfUse` to `rights.termsUrl`. Legacy printed no such line,
257
+ so it is off by default.
258
+
259
+ ### Site chrome: the logo, the chrome pictures, the social links
260
+
261
+ Since 3.4.0 a site supplies its own chrome files (decision D7 of
262
+ inventory-app#2233: logos, banners, tiles and backgrounds belong to their
263
+ website, not to the inventory nor to `images.museumwnf.org`). It keeps them
264
+ in its repository under `theme/assets/` and hands the layout one map of
265
+ them, built by Vite so every file is fingerprinted with the build:
266
+
267
+ ```js
268
+ // src/dataset.config.js
269
+ const chrome = import.meta.glob('../theme/assets/**/*.{jpg,jpeg,png,gif,svg}', {
270
+ eager: true, query: '?url', import: 'default',
271
+ })
272
+
273
+ export default { /* … */ chrome, brand: { logo: 'logo.png', alt: 'MWNF Logo' } }
274
+ // a DXA site: galleryConfig({ …, chrome }) / exhibitionConfig({ …, chrome })
275
+ ```
276
+
277
+ The map's keys are normalised to the path after `theme/assets/`, so
278
+ `'../theme/assets/chrome/thematic_gallery/thg_galleries/9/banner.jpg'` is
279
+ `chrome/thematic_gallery/thg_galleries/9/banner.jpg`. Two kinds of key:
280
+
281
+ | Key | What reads it |
282
+ | --- | --- |
283
+ | a file name at the root (`logo.png`, `dia.jpg`, …) | the part of the layout that names it (`brand.logo`, the DXA keys below) |
284
+ | `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 |
285
+
286
+ A key a site doesn't supply falls back to what the layout drew before:
287
+ the package path on `config.media.legacyHost`, the "MWNF" text mark for the
288
+ logo, nothing for a background. So a site that supplies nothing renders as
289
+ it did on 3.3.
290
+
291
+ | Config | Shape | Notes |
292
+ | --- | --- | --- |
293
+ | `config.chrome` | `{ [path]: url }` | the map above |
294
+ | `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) |
295
+ | `config.navigation.placement` | `'after-banner'` (default) \| `'before-banner'` \| `({ section }) => …` | where the menu goes: PageShell's `navigation-placement` |
296
+ | `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` |
297
+ | `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 |
298
+
299
+ `SocialLinks` (package root, prop `links`) draws the icon links on their own,
300
+ for a site that writes its own `#footer`:
301
+ `<SocialLinks :links="mwnfSocialLinks" />`.
302
+
303
+ The favicon is not the layout's: every site ships `public/favicon.ico` and
304
+ declares it in its own `index.html` (`<link rel="icon" href="%BASE_URL%favicon.ico">`).
305
+
306
+ **DXA families.** `galleryConfig` sets `brand.logo` to `logo.png` (legacy
307
+ dxa-client's white mark), `exhibitionConfig` to `logo_black.png`. Besides
308
+ the logo, the family reads:
309
+
310
+ | Key | Family | Where | Legacy source |
311
+ | --- | --- | --- | --- |
312
+ | `logo.png` | gallery (and the hub) | the header | `dxa-client/src/assets/logo.png` |
313
+ | `logo_black.png` | exhibition | the header | `exhibitions-client/src/assets/logo_black.png` |
314
+ | `dia.jpg`, `dba.jpg`, `sh.jpg` | gallery | the home's Other Virtual Museums banners (flat colour blocks without them) | `dxa-client/src/assets/` |
315
+ | `world.png` | gallery | the glossary entry's header on the item sheet | `dxa-client/src/sites/<site>/world.png` (one per gallery) |
316
+ | `chrome/<gallery.banner_image_path>` | gallery | the banner, every page | `images.museumwnf.org/hi_res/<path>` |
317
+ | `chrome/<sibling_galleries[].image_path>` | gallery | the "Visit MWNF Galleries" tiles | `images.museumwnf.org/zoom/<path>` (legacy's tile size) |
318
+ | `chrome/<exhibition.banner_image_path>` | exhibition | the banner on inner pages | `images.museumwnf.org/hi_res/<path>` |
319
+ | `chrome/<exhibition.homepage_image_path>` | exhibition | the home banner (`home_image.jpg`) | `images.museumwnf.org/full/<path>` |
320
+ | `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>` |
321
+ | `chrome/<homeLogos[].image>` | gallery (Glass) | the home's "Set up on the occasion of" logos | `images.museumwnf.org/gallery_logo/<path>` |
322
+
323
+ **Exhibition sponsors.** The sponsors' logos are the site's, not the
324
+ inventory's. `exhibitionConfig({ sponsorLogos })` takes the site's own list,
325
+ `[{ image, href, alt, category_id, display_order }]` (`image` a chrome key or a
326
+ URL, `alt` an entry name or text), in place of the package's. Without it each
327
+ entry of `exhibition.json`'s `logos` draws `chrome/<legacy_path>`, else legacy's
328
+ media host at that path; never the inventory's `image_url`. A picture in the
329
+ popup notice whose legacy address the site keeps a copy of
330
+ (`chrome/<the path after legacy's size segment>`, e.g. `chrome/upload/toronto.jpg`
331
+ for `…/full/upload/toronto.jpg`) is drawn from that copy.
332
+
333
+ Glass's home logo slot is the one gallery-specific block, declared by the
334
+ site because no package carries it:
335
+
336
+ ```js
337
+ galleryConfig({
338
+ // …
339
+ homeLogos: [
340
+ { image: 'thematic_gallery/thg_logos/dga/1.jpg', href: 'https://iyog2022.org/', alt: 'glass.home.iyogLogo' },
341
+ ],
342
+ })
343
+ ```
344
+
345
+ `image` is a `chrome/` path (the file at
346
+ `theme/assets/chrome/thematic_gallery/thg_logos/dga/1.jpg`), `alt` an entry
347
+ name in the site's own locales; the strip's heading is viewer-i18n's
348
+ `gallery.home.logosLabel` ("Set up on the occasion of").
349
+
350
+ A gallery shell for a site without a gallery package (the galleries hub,
351
+ legacy's gallery 45) takes its chrome from `config.galleryShell` instead,
352
+ each field optional and each winning over the package:
353
+
354
+ | `config.galleryShell` field | Shape |
355
+ | --- | --- |
356
+ | `headerEyebrow`, `headerTitle` | entry name or text: the header's title cell on inner pages |
357
+ | `bannerEyebrow`, `bannerTitle` | entry name or text: the line over the home banner's title ("Welcome to") and the title ("MWNF Galleries") |
358
+ | `bannerImage` | a `chrome` key or a URL |
359
+ | `bannerCaption` | `{ name, partner, location, country }` or a string, after "Detail from" |
360
+ | `notice` | `false` drops the menu's tip about the search bar (a site with no search) |
361
+
362
+ An empty string is "no line" (`bannerEyebrow: ''` drops "Discover MWNF
363
+ Galleries"); a field left out keeps the gallery's own. The header fields
364
+ apply on inner pages only, as the home page's header has no title.
251
365
 
252
366
  ## Sections (standalone use)
253
367
 
@@ -591,6 +705,71 @@ Since 3.3.0 what every site of a family shared by copy is here once:
591
705
  which processes this package (viewer-core's `defineViewerConfig` inlines
592
706
  it).
593
707
 
708
+ ## Standalone family pages
709
+
710
+ `@museumwnf/viewer-layout/standalone` is the family layer of Discover Islamic
711
+ Art, Discover Baroque Art and Sharing History: three sites legacy built from
712
+ one PHP template family, whose layouts match legacy's
713
+ (inventory-app#2233, decision D1). What they share is here once; what
714
+ differs is a config value, a token or a slot.
715
+
716
+ The shell is a `SiteShell`, so everything the site chrome contract above
717
+ reads works as on any site: `chrome` (the site's files under `theme/assets/`),
718
+ `navigation.placement` (legacy's menu sits under the home page's picture and
719
+ above every other page's band) and `navigation.socialLinks`. A site names
720
+ the shell in its `dataset.config.js` and sets `config.standalone` beside its
721
+ `navigation` (every key optional). Every picture is a key of the chrome map,
722
+ or a URL:
723
+
724
+ ```js
725
+ import { mwnfSocialLinks } from '@museumwnf/viewer-layout'
726
+ import { StandaloneShell } from '@museumwnf/viewer-layout/standalone'
727
+
728
+ const chrome = import.meta.glob('../theme/assets/**/*.{jpg,jpeg,png,gif,svg}', {
729
+ eager: true, query: '?url', import: 'default',
730
+ })
731
+
732
+ export default {
733
+ shell: StandaloneShell,
734
+ chrome,
735
+ navigation: {
736
+ languages, links, footerLinks, sectionTitles, // as on every site
737
+ placement: ({ section }) => (section === 'home' ? 'after-banner' : 'before-banner'),
738
+ socialLinks: mwnfSocialLinks,
739
+ },
740
+ standalone: {
741
+ logo: { src: 'legacy/logo_isl_en.png', alt: 'islamicart.identity.title', href: mwnfLinks.portal, print: { en: 'legacy/logo_print.gif', fr: 'legacy/logo_print_fr.gif' } },
742
+ heading: 'islamicart.identity.heading', // the header's title on every page but the home page
743
+ headerLinks: [{ label, href | to, on: 'home' | 'inner' | 'all' }],
744
+ banner: { home: 'legacy/banner.jpg', inner: 'legacy/banner_inside.jpg' },
745
+ languages: true, // false: chrome in one language, no switcher
746
+ copyright: 'islamicart.footer.copyright', // the footer line; the year follows it
747
+ sponsors: { on: 'home' | 'all', columns: [{ lead, text, break, title, logos, links, width }] },
748
+ home: { links: [...], highlight: { list, heading, alsoKnownAs, action, route }, tiles: { caption, items } },
749
+ areas: { [section]: { logo, banner, class } }, // a section with chrome of its own
750
+ },
751
+ }
752
+ ```
753
+
754
+ The shell hands the logo to SiteShell's `brand`. The logo, the print logo and
755
+ the banners may each be given once or per language (`{ en, ar }`).
756
+
757
+ | Export | What it is |
758
+ | --- | --- |
759
+ | `StandaloneShell` | `SiteShell` with legacy's chrome: the logo per language, the inner pages' centred heading and "Portal \| Home" links, the home page's picture banner, the inner pages' titled band (`navigation.sectionTitles`), the menu above or below the banner, the band above the footer on the home page, the copyright line with the year, a print-only logo. The page gets `.mwnf-standalone`, the scope of the family stylesheet |
760
+ | `StandaloneHome` | the home page's content: the side links and the record of the day, or a tile grid |
761
+ | `TodayHighlight` | legacy's "Today's highlight": the record for the day of the year from legacy's own list (`home_items_img.txt`), its picture and legacy's lines |
762
+ | `StandaloneItemSheet` | `RecordView` in legacy's three columns: the way back and the pictures; the sheet with its short-description toggle; the coloured Related Content column (`RelatedContent`), which takes the site's own blocks in its `sidebar` slot |
763
+ | `StandaloneTextPage` | a text page in legacy's centred column: a Markdown entry, an optional drop cap, a "→" link and Print |
764
+ | `StandaloneSponsors` | the band above the footer, in columns of text, logos and links |
765
+ | `StandaloneSubNav`, `StandaloneTileGrid`, `StandaloneSlider` | Sharing History's tab strip, picture tiles and slider |
766
+ | `byLanguage`, `dayOfYear`, `pickForDay`, `legacyHomeItemKey` | the plain functions the chrome reads with |
767
+
768
+ Every rule of the family's stylesheet is scoped to `.mwnf-standalone`, and
769
+ every value is a `--mwnf-standalone-*` token with a neutral fallback
770
+ (`tokens.reference.css`); a site's `theme/tokens.css` sets legacy's. It ships
771
+ in `style.css`, so a site imports nothing more.
772
+
594
773
  ## Theming
595
774
 
596
775
  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.
@@ -1,4 +1,4 @@
1
- import { y as e } from "./TimelineEventList-COjkXEzS.js";
1
+ import { d as e } from "./GlossaryPopover-DcptyNWI.js";
2
2
  import { Fragment as t, computed as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createVNode as o, openBlock as s, renderList as c, renderSlot as l, toDisplayString as u, useSlots as d, withCtx as f } from "vue";
3
3
  //#region src/content/FeaturedRecord.vue
4
4
  var p = {