@publier/shell 4.2.2 → 4.3.1

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 CHANGED
@@ -39,14 +39,30 @@ nav:
39
39
  href: /contact
40
40
  ```
41
41
 
42
- The default variant serves both marketing and documentation pages. Keep one
43
- canonical configuration; if named variants are needed, reuse the same YAML anchor
44
- instead of copying the items. Only one level is supported. Empty groups, malformed
42
+ Configure marketing navigation in `default` or a named marketing variant, and
43
+ documentation navigation in `docs`. Without a `docs` variant, documentation routes
44
+ derive section links from `docs.tabSections`. Reuse YAML anchors for shared destinations. Only one level is supported. Empty groups, malformed
45
45
  children, and nested groups are omitted. Descriptions are plain text and are
46
46
  escaped along with labels and destinations. Children support local paths,
47
47
  fragments, HTTP(S), mail and telephone links; executable URL schemes are omitted.
48
48
  `external: true` opens a new tab with `noopener noreferrer`.
49
49
 
50
+ Documentation selectors open on click or keyboard activation. Their labels stay
51
+ stationary while the disclosure arrow rotates smoothly. The menu itself opens
52
+ without an entrance animation.
53
+
54
+ Outside the `docs` variant, desktop groups also open on hover for fine pointers.
55
+ Their panels span the header width and arrange destinations in two columns, with
56
+ a brief Motion entrance. Corners and shadow follow the theme’s `--radius-box`,
57
+ `--radius-selector` and `--shadow-lg` tokens; `--publier-page-max-width` aligns
58
+ the inner content with the page. Reduced motion disables panel and arrow
59
+ animation. Touch uses tap;
60
+ keyboard opening, selection and Escape remain owned by details-menu. Pointer
61
+ opening informs that element's mouse-modality listener so hover does not steal
62
+ focus. Moving into the panel keeps it open; leaving dismisses after a short grace
63
+ period unless a panel link retains keyboard focus. Astro swaps clear timers and
64
+ animations before wiring the new header. Plain-link variants need no groups.
65
+
50
66
  Desktop menus appear at `lg` (1024px). Each group is a native `<details>` with
51
67
  `data-publier-nav-group` set to its label. Its direct `<details-menu>` child has
52
68
  `data-publier-nav-menu`, `role="menu"`, and links with `role="menuitem"`. The
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{a as e,i as t,t as n}from"./integration-DgDVMttc.mjs";export{t as HASHED_ASSET_RE,n as docsShell,e as publierCacheControl};
1
+ import{a as e,i as t,t as n}from"./integration-B__TDsKV.mjs";export{t as HASHED_ASSET_RE,n as docsShell,e as publierCacheControl};
@@ -11,7 +11,7 @@ if (import.meta.hot) {
11
11
  `),i+=t.join(`
12
12
  `),i.endsWith(`
13
13
  `)||(i+=`
14
- `)),i}function we(){return{name:`publier-cascade-hoist`,enforce:`post`,transform(e,t){if(!t.endsWith(`.css`)&&!t.includes(`.css?`))return null;let n=Z(e);return n===e?null:{code:n,map:null}},generateBundle(e,t){for(let e of Object.keys(t)){if(!e.endsWith(`.css`))continue;let n=t[e];if(!n||n.type!==`asset`)continue;let r=typeof n.source==`string`?n.source:new TextDecoder().decode(n.source),i=Z(r);i!==r&&(n.source=i)}}}}function Q(e,t,n){let r=`\0${e}`,i=`export const ${t} = ${JSON.stringify(n)};`;return{name:`publier-${e.replace(/^virtual:publier-/,``)}`,resolveId(t){if(t===e)return r},load(e){if(e===r)return i}}}function Te(e,t=6){return e.length===0?`[]`:e.length<=t?`[${e.join(`, `)}]`:`[${e.slice(0,t).join(`, `)}, +${e.length-t} more]`}function Ee(e){let t=[ve,a,i,f(),v(),C()];return e.searchEnabled&&t.push(S(),x()),t.join(`
14
+ `)),i}function we(){return{name:`publier-cascade-hoist`,enforce:`post`,transform(e,t){if(!t.endsWith(`.css`)&&!t.includes(`.css?`))return null;let n=Z(e);return n===e?null:{code:n,map:null}},generateBundle(e,t){for(let e of Object.keys(t)){if(!e.endsWith(`.css`))continue;let n=t[e];if(!n||n.type!==`asset`)continue;let r=typeof n.source==`string`?n.source:new TextDecoder().decode(n.source),i=Z(r);i!==r&&(n.source=i)}}}}function Q(e,t,n){let r=`\0${e}`,i=`export const ${t} = ${JSON.stringify(n)};`;return{name:`publier-${e.replace(/^virtual:publier-/,``)}`,resolveId(t){if(t===e)return r},load(e){if(e===r)return i}}}function Te(e,t=6){return e.length===0?`[]`:e.length<=t?`[${e.join(`, `)}]`:`[${e.slice(0,t).join(`, `)}, +${e.length-t} more]`}function Ee(e){let t=[`import '@publier/shell/runtime/marketing-nav';`,ve,a,i,f(),v(),C()];return e.searchEnabled&&t.push(S(),x()),t.join(`
15
15
  `)}function De(e,t){let n=[],r=[],i=[];for(let a of[`heading`,`body`,`mono`]){let o=e[a];if(!o?.family)continue;let s=`--publier-font-${a}`,c=a===`mono`?[`monospace`]:[`system-ui`,`sans-serif`],l=[o.weight??`400`],u=[o.style??`normal`];if(o.googleFontsUrl)n.push({name:o.family,cssVariable:s,provider:M.google(),fallbacks:c,weights:l,styles:u,subsets:[`latin`]}),r.push(a);else if(o.src){let e=A.isAbsolute(o.src)&&w(o.src)?o.src:A.join(t,`public`,o.src.replace(/^\/+/,``));n.push({name:o.family,cssVariable:s,provider:M.local(),fallbacks:c,weights:l,styles:u,subsets:[`latin`],options:{variants:[{weight:l[0],style:u[0],src:[e]}]}}),r.push(a)}else i.push(`${s}:"${o.family}",${c.join(`,`)};`)}return{entries:n,familyOnlyCss:i.length?`:root{${i.join(``)}}`:``,slots:r}}const Oe=[{pkg:`astro-expressive-code`,aliases:[`astro-expressive-code`]},{pkg:`@astrojs/mdx`,aliases:[`@astrojs/mdx`]},{pkg:`@astrojs/sitemap`,aliases:[`@astrojs/sitemap`]},{pkg:`astro-pagefind`,aliases:[`astro-pagefind`,`pagefind`]},{pkg:`@qwik.dev/astro`,aliases:[`@qwik.dev/astro`]}];function $(e,t){let n=A.join(e,`src`,`content`,t);if(!w(n))return!1;try{return D(n,{recursive:!0}).some(e=>typeof e==`string`&&/\.mdx?$/.test(e))}catch{return!1}}function ke(e={}){let t=null;return{name:`@publier/shell`,hooks:{"astro:config:setup":async({config:n,updateConfig:r,injectScript:i,injectRoute:a,logger:l})=>{let u=n.root?j(n.root):process.cwd();try{oe()}catch(e){let t=e instanceof Error?e.message:String(e),n=ee(t);throw n?Error(n):e}let f=c(A.join(u,`package.json`)),p=JSON.stringify(e),m=de(fe(u)??``),h=m.site;t={llms:m.llms,siteName:h.name,siteDescription:h.description??void 0};let g=m.vars,_=m.fonts,v=m.nav,y=m.announcement,b=m.docs,x=typeof h.url==`string`&&h.url.length>0;x&&!n.site&&r({site:h.url});let S=new Set(n.integrations.map(e=>e.name)),C=Oe.filter(({aliases:e})=>!e.some(e=>S.has(e)));C.length>0&&l.warn(`[@publier/shell] Required framework integrations are not registered in
16
16
  astro.config.ts. As of @publier/shell@2.0.0, docsShell() no longer
17
17
  auto-wires these. Add the following to your integrations[] array
@@ -1 +1 @@
1
- import{n as e,r as t,t as n}from"./integration-DgDVMttc.mjs";export{n as docsShell,e as hoistMediaOutOfUtilitiesLayer,t as publierCascadeHoistPlugin};
1
+ import{n as e,r as t,t as n}from"./integration-B__TDsKV.mjs";export{n as docsShell,e as hoistMediaOutOfUtilitiesLayer,t as publierCascadeHoistPlugin};
@@ -0,0 +1 @@
1
+ import "@github/details-menu-element";
@@ -0,0 +1 @@
1
+ import"@github/details-menu-element";const e=matchMedia(`(min-width: 1024px)`),t=matchMedia(`(hover: hover) and (pointer: fine)`),n=matchMedia(`(prefers-reduced-motion: reduce)`);let r,i,a;function o(){return i||=import(`motion/mini`).then(e=>{r=e.animate}).catch(()=>{i=void 0}),i}function s(){a?.();let i=Array.from(document.querySelectorAll(`[data-publier-top-nav]:not([data-publier-docs-header]) details.dropdown[data-publier-nav-group]:not([data-publier-docs-selector])`));if(!i.length)return;let s=new AbortController,c={signal:s.signal},l=new Set;e.matches&&!n.matches&&o();for(let a of i){let i=a.querySelector(`:scope > summary`),u=a.querySelector(`:scope > details-menu`);if(!i||!u)continue;let d,f,p=0,m=!1,h=()=>{clearTimeout(d),d=void 0},g=()=>{p+=1,f?.cancel(),f=void 0},_=()=>{h(),g(),m=!1,a.open=!1};l.add(_),a.addEventListener(`pointerenter`,n=>{n.pointerType===`touch`||!e.matches||!t.matches||(h(),!a.open&&(a.dispatchEvent(new MouseEvent(`mousedown`)),m=!0,a.open=!0))},c),a.addEventListener(`pointerleave`,e=>{e.pointerType!==`touch`&&(h(),d=setTimeout(()=>{u.contains(document.activeElement)||_()},160))},c),i.addEventListener(`click`,e=>{e.detail>0&&m&&a.open&&e.preventDefault(),m=!1},c),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&!e.defaultPrevented&&a.open&&!a.contains(document.activeElement)&&(_(),e.preventDefault())},c),a.addEventListener(`focusout`,()=>{queueMicrotask(()=>{!a.contains(document.activeElement)&&!a.matches(`:hover`)&&_()})},c),a.addEventListener(`toggle`,()=>{if(g(),!a.open){m=!1;return}if(n.matches||!e.matches)return;let t=p;o().then(()=>{t!==p||s.signal.aborted||!a.isConnected||!a.open||n.matches||!e.matches||(f=r?.(u,{opacity:[0,1],transform:[`translateY(6px)`,`translateY(0)`]},{duration:.18,ease:[.16,1,.3,1]}))})},c),n.addEventListener(`change`,g,c)}e.addEventListener(`change`,()=>{for(let e of l)e()},c),t.addEventListener(`change`,()=>{for(let e of l)e()},c),a=()=>{s.abort();for(let e of l)e();a=void 0}}s(),document.addEventListener(`astro:before-swap`,()=>a?.()),document.addEventListener(`astro:after-swap`,s);export{};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@publier/shell",
3
- "version": "4.2.2",
3
+ "version": "4.3.1",
4
4
  "license": "UNLICENSED",
5
5
  "description": "Qwik + Astro docs layout for Publier sites.",
6
6
  "type": "module",
@@ -101,7 +101,11 @@
101
101
  "import": "./dist/tailwind/loader.mjs"
102
102
  },
103
103
  "./tailwind/preset.css": "./src/tailwind/preset.css",
104
- "./tailwind/themes/*": "./dist/themes/*"
104
+ "./tailwind/themes/*": "./dist/themes/*",
105
+ "./runtime/marketing-nav": {
106
+ "types": "./dist/runtime/marketing-nav.d.mts",
107
+ "import": "./dist/runtime/marketing-nav.mjs"
108
+ }
105
109
  },
106
110
  "publishConfig": {
107
111
  "access": "public"
@@ -133,7 +137,8 @@
133
137
  "remark-gfm": "^4.0.1",
134
138
  "remark-math": "^6.0.0",
135
139
  "unist-util-visit": "^5.1.0",
136
- "yaml": "^2.9.0"
140
+ "yaml": "^2.9.0",
141
+ "motion": "^14.0.0"
137
142
  },
138
143
  "peerDependencies": {
139
144
  "@astrojs/markdown-remark": ">=7.0.0",
@@ -172,6 +172,7 @@ h6 {
172
172
  border-right: 1.5px solid currentColor;
173
173
  border-bottom: 1.5px solid currentColor;
174
174
  transform: translateY(-0.1rem) rotate(45deg);
175
+ transition: transform 150ms ease;
175
176
  }
176
177
 
177
178
  [data-publier-top-nav] details[data-publier-nav-group].dropdown[open] > summary::after {
@@ -707,3 +708,98 @@ aside[aria-label="Table of contents"] {
707
708
  body:has([data-publier-docs-header]) :is(h2, h3, h4)[id] {
708
709
  scroll-margin-top: calc(var(--publier-header-height, 4rem) + 1rem);
709
710
  }
711
+
712
+ /* Header controls remain stationary while the disclosure indicator changes. */
713
+ [data-publier-docs-header] .btn,
714
+ [data-publier-docs-selector] > summary,
715
+ [data-publier-top-nav] details[data-publier-nav-group] > summary {
716
+ translate: none;
717
+ scale: none;
718
+ }
719
+ [data-publier-docs-selector] > summary {
720
+ color: var(--color-base-content);
721
+ transform: none;
722
+ transition: none;
723
+ background-color: transparent;
724
+ box-shadow: none;
725
+ }
726
+ [data-publier-docs-selector] > summary > span[aria-hidden="true"] {
727
+ display: inline-block;
728
+ width: 0.4rem;
729
+ height: 0.4rem;
730
+ font-size: 0;
731
+ border-right: 1.5px solid currentColor;
732
+ border-bottom: 1.5px solid currentColor;
733
+ transform: rotate(45deg);
734
+ transition: transform 150ms ease;
735
+ }
736
+ [data-publier-docs-selector][open] > summary > span[aria-hidden="true"] {
737
+ transform: rotate(225deg);
738
+ }
739
+ [data-publier-docs-header] .dropdown-content {
740
+ animation: none;
741
+ transition: none;
742
+ scale: 1;
743
+ }
744
+
745
+ /* Marketing uses the existing menu surface, expanded across the header into an airy link grid.
746
+ * Native disclosure still works without JavaScript; Motion enhances entrance. */
747
+ @media (width >= 64rem) {
748
+ [data-publier-top-nav]:not([data-publier-docs-header]) > .navbar {
749
+ position: static;
750
+ }
751
+ [data-publier-top-nav]:not([data-publier-docs-header])
752
+ details.dropdown[data-publier-nav-group]:not([data-publier-docs-selector]) {
753
+ position: static;
754
+ }
755
+ [data-publier-top-nav]:not([data-publier-docs-header])
756
+ details.dropdown[data-publier-nav-group]:not([data-publier-docs-selector])
757
+ > summary {
758
+ transform: none;
759
+ background-color: transparent;
760
+ box-shadow: none;
761
+ transition: color 150ms ease;
762
+ }
763
+ [data-publier-top-nav]:not([data-publier-docs-header])
764
+ details.dropdown[data-publier-nav-group]:not([data-publier-docs-selector])
765
+ > [data-publier-nav-menu] {
766
+ inset-inline: 0;
767
+ top: 100%;
768
+ width: 100%;
769
+ max-width: none;
770
+ max-height: calc(100dvh - 6rem);
771
+ margin-inline: auto;
772
+ padding-block: 2.5rem;
773
+ padding-inline: max(2rem, calc((100% - var(--publier-page-max-width, 80rem)) / 2));
774
+ overflow-y: auto;
775
+ border-radius: 0 0 var(--radius-box) var(--radius-box);
776
+ box-shadow: var(--shadow-lg);
777
+ scale: 1;
778
+ animation: none;
779
+ transition: none;
780
+ transform-origin: top center;
781
+ }
782
+ [data-publier-top-nav]:not([data-publier-docs-header]) [data-publier-nav-menu] > ul {
783
+ display: grid;
784
+ grid-template-columns: repeat(2, minmax(0, 1fr));
785
+ gap: 1rem 3rem;
786
+ }
787
+ [data-publier-top-nav]:not([data-publier-docs-header]) [data-publier-nav-menu] > ul > li > a {
788
+ height: 100%;
789
+ padding: 1rem;
790
+ border-radius: var(--radius-selector);
791
+ font-size: 1.25rem;
792
+ line-height: 1.4;
793
+ }
794
+ [data-publier-top-nav]:not([data-publier-docs-header]) [data-publier-nav-description] {
795
+ margin-top: 0.375rem;
796
+ color: color-mix(in oklab, var(--color-base-content) 70%, transparent);
797
+ line-height: 1.5;
798
+ }
799
+ }
800
+ @media (prefers-reduced-motion: reduce) {
801
+ [data-publier-top-nav] details[data-publier-nav-group] > summary::after,
802
+ [data-publier-docs-selector] > summary > span[aria-hidden="true"] {
803
+ transition: none;
804
+ }
805
+ }