From a2aaa838c086563e79c647dc4de5962c8b96b044 Mon Sep 17 00:00:00 2001 From: George Cushen Date: Mon, 22 Sep 2025 22:18:00 +0100 Subject: [PATCH] feat(preact+landing): enable Preact block rendering + reusable landing page content system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Preact Block Integration - Enable Preact component detection for data-driven pages: - Fix init.html to resolve sections_source + per-section ref before Preact detection - Correct resource paths: blox/* → js/hbx/blocks/* (Hugo module mounts) - Update libraries.html to load Preact core + compiled block scripts - Add dynamic icon rendering for Preact components: - Create Icon.jsx component with SVG decoding - Add get_icon_data.html partial for passing icon strings to Preact props - Update preact-wrapper.html to fetch icon data and inject into props - Wire hero component to render dynamic icons via - Centralized logging system: - Add functions/logger.html to wrap warnf/errorf safely - Degrade to HTML comments in constrained contexts (content adapters) ## Reusable Landing Page Content System - Add sections_source support: - Page front matter: sections_source: pages/ loads base from data/pages/.yaml - Inline sections deep-merge over base by position; extras appended - Add per-section ref system: - Any section: ref: blocks/ loads from data/blocks/.yaml - Inline section properties deep-merge over ref (content/design submaps) - Enable content reuse across multiple landing pages - Create reusable block library: - Add test/data/blocks/: hero_basic.yaml, features_basic.yaml - Add test/content/linked/index.md demo using refs with overrides - Add pragmatic deep merge for content/design override handling ## Infrastructure & Schemas - Update base-block.json schema: - Fix gradient structure: flat → nested (gradient.start/end/direction) - Fix color structure: string|{light,dark} (matches parse_block_v3.html) - Update hero schema to properly extend base via $ref - Fix Tailwind source path generation: - Add tailwind_sources.html with test vs starter site logic - scripts/view-test.sh: export HUGO_BLOX_TEST_SITE=true - Update block directory structure: - blox//config.html (was blox/--CONFIG.html) - Apply to init.html + parse_block_v2.html - Code quality improvements: - Biome config: match Prettier rules ## Content Adapters (Removed) - Investigated Hugo content adapters for landing pages - Found execution context limitations (early build phase, limited site methods) - Archived to backups/content-adapters-*.zip and removed from test site - Decision: use standard pages + data linking instead of adapters This enables dynamic Preact rendering with proper icon support while providing a flexible, reusable content system for landing pages that maintains the "single file = page" mental model with optional advanced linking. --- .gitignore | 1 + .prettierignore | 15 + .prettierrc.js | 21 + biome.json | 22 +- hugo-blox-builder.code-workspace | 11 +- modules/blox-tailwind/README.md | 22 + .../assets/css/config/safelist.css | 1 + modules/blox-tailwind/assets/css/main.css | 3 + .../assets/dist/lib/alpinejs/cdn.min.js | 4 +- .../assets/dist/lib/katex/auto-render.min.js | 2 +- .../assets/dist/lib/katex/katex.min.css | 2 +- .../assets/dist/lib/katex/katex.min.js | 2 +- .../assets/dist/lib/markmap/index.js | 863 ++-- .../assets/dist/lib/mermaid/mermaid.min.js | 4217 +++++++++++------ .../assets/dist/lib/plotly/plotly.min.js | 3882 ++++++++++++++- .../assets/dist/lib/preact/hooks.min.js | 2 + .../assets/dist/lib/preact/preact.min.js | 2 + .../assets/dist/lib/preact/preact.min.js.map | 1 + .../assets/dist/lib/vendor-libs.mjs | 4 + .../blox-tailwind/assets/js/vendor-libs.js | 11 +- modules/blox-tailwind/blox/hero/client.jsx | 38 + modules/blox-tailwind/blox/hero/component.jsx | 138 + modules/blox-tailwind/blox/hero/schema.json | 24 +- .../blox/shared/js/components/Icon.jsx | 55 + .../blox/shared/schemas/base-block.json | 57 +- .../layouts/_partials/blox/hero/wrapper.html | 32 + .../_partials/blox/preact-wrapper.html | 46 + .../blox-tailwind/layouts/_partials/css.html | 7 +- .../_partials/functions/deep_merge.html | 21 + .../layouts/_partials/functions/get_icon.html | 2 +- .../_partials/functions/get_icon_data.html | 63 + .../layouts/_partials/functions/logger.html | 38 + .../_partials/functions/parse_block_v2.html | 2 +- .../_partials/functions/parse_block_v3.html | 125 + .../layouts/_partials/hbx/sections.html | 108 +- .../blox-tailwind/layouts/_partials/init.html | 88 +- .../layouts/_partials/landing_page.html | 2 +- .../layouts/_partials/libraries.html | 45 +- .../layouts/_partials/site_head.html | 1 - .../layouts/_partials/tailwind_sources.html | 54 + modules/blox-tailwind/package.json | 45 +- modules/blox-tailwind/pnpm-lock.yaml | 3612 ++------------ package.json | 16 +- pnpm-lock.yaml | 1536 +++--- scripts/view-starter-dev.sh | 1 + scripts/view-test.sh | 100 + test/content/_index.md | 19 +- test/content/linked/index.md | 14 + test/data/blocks/features_basic.yaml | 17 + test/data/blocks/hero_basic.yaml | 21 + test/data/pages/home.yaml | 61 + test/go.mod | 3 +- vite.config.js | 15 + 53 files changed, 9341 insertions(+), 6153 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc.js create mode 100644 modules/blox-tailwind/assets/dist/lib/preact/hooks.min.js create mode 100644 modules/blox-tailwind/assets/dist/lib/preact/preact.min.js create mode 100644 modules/blox-tailwind/assets/dist/lib/preact/preact.min.js.map create mode 100644 modules/blox-tailwind/assets/dist/lib/vendor-libs.mjs create mode 100644 modules/blox-tailwind/blox/hero/client.jsx create mode 100644 modules/blox-tailwind/blox/hero/component.jsx create mode 100644 modules/blox-tailwind/blox/shared/js/components/Icon.jsx create mode 100644 modules/blox-tailwind/layouts/_partials/blox/hero/wrapper.html create mode 100644 modules/blox-tailwind/layouts/_partials/blox/preact-wrapper.html create mode 100644 modules/blox-tailwind/layouts/_partials/functions/deep_merge.html create mode 100644 modules/blox-tailwind/layouts/_partials/functions/get_icon_data.html create mode 100644 modules/blox-tailwind/layouts/_partials/functions/logger.html create mode 100644 modules/blox-tailwind/layouts/_partials/functions/parse_block_v3.html create mode 100644 modules/blox-tailwind/layouts/_partials/tailwind_sources.html create mode 100755 scripts/view-test.sh create mode 100644 test/content/linked/index.md create mode 100644 test/data/blocks/features_basic.yaml create mode 100644 test/data/blocks/hero_basic.yaml create mode 100644 test/data/pages/home.yaml diff --git a/.gitignore b/.gitignore index 564a1041..d23ae1db 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,4 @@ pids tmp/ temp/ .tmp/ +backups/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..74159a84 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,15 @@ +# Vendor directories +_vendor/ +vendor/ + +# Generated directories +public/ +resources/ +node_modules/ + +# We use go-template parser for HTML, but still ignore some specific files +modules/blox-tailwind/assets/dist/ + +# JSON files with specific formats (although typically Biome now processes JSON) +modules/blox-tailwind/layouts/index.json +modules/blox-tailwind/layouts/index.webmanifest diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..18e12d7a --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,21 @@ +module.exports = { + bracketSpacing: false, + singleQuote: false, + jsxBracketSameLine: true, + trailingComma: "all", + printWidth: 150, + overrides: [ + { + files: ["*.html"], + options: { + parser: "go-template", + }, + }, + { + files: ["*.md"], + options: { + proseWrap: "preserve", + }, + }, + ], +}; diff --git a/biome.json b/biome.json index 04b3a62a..fbfbdeb0 100644 --- a/biome.json +++ b/biome.json @@ -12,6 +12,8 @@ "**/_vendor/**", "**/vendor/**", "**/*.html", + "**/layouts/**/*.html", + "**/layouts/**/*.htm", "**/*.webmanifest", "**/*.backlinks.json", "**/hugo_stats.json", @@ -25,7 +27,22 @@ }, "formatter": { "enabled": true, - "indentStyle": "space" + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 150 + }, + "javascript": { + "formatter": { + "quoteStyle": "double", + "trailingCommas": "all", + "bracketSpacing": false + }, + "globals": ["PagefindUI"] + }, + "json": { + "formatter": { + "trailingCommas": "none" + } }, "linter": { "enabled": true, @@ -40,8 +57,5 @@ }, "organizeImports": { "enabled": true - }, - "javascript": { - "globals": ["PagefindUI"] } } diff --git a/hugo-blox-builder.code-workspace b/hugo-blox-builder.code-workspace index c8628d7a..c49fbd8f 100644 --- a/hugo-blox-builder.code-workspace +++ b/hugo-blox-builder.code-workspace @@ -38,7 +38,10 @@ "[typescript]": { "editor.defaultFormatter": "biomejs.biome" }, "[json]": { "editor.defaultFormatter": "biomejs.biome" }, "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, - "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[html]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "files.trimTrailingWhitespace": false @@ -47,6 +50,12 @@ "editor.tabSize": 4, "editor.insertSpaces": true }, + "[yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[toml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, "eslint.workingDirectories": [{ "mode": "auto" }], "eslint.validate": [ diff --git a/modules/blox-tailwind/README.md b/modules/blox-tailwind/README.md index 217ca59c..2f99b37a 100644 --- a/modules/blox-tailwind/README.md +++ b/modules/blox-tailwind/README.md @@ -65,3 +65,25 @@ hugo server --disableFastRender # Build for production hugo --minify ``` + +## Vendor Libraries + +The module includes several third-party vendor libraries that are distributed with the module. These are copied from node_modules to the assets/dist/lib directory during the build process. + +To update the vendor libraries: + +```bash +# Update vendor libraries to the latest versions and rebuild +pnpm vendor:update-and-build + +# Just rebuild vendor libraries without updating versions +pnpm vendor:libs +``` + +The following libraries are included: +- mermaid (diagrams) +- plotly.js (interactive charts) +- katex (math rendering) +- markmap-autoloader (mind maps) +- alpinejs (interactivity) +- preact (interactive components) diff --git a/modules/blox-tailwind/assets/css/config/safelist.css b/modules/blox-tailwind/assets/css/config/safelist.css index 6b7bdd7d..971a8707 100644 --- a/modules/blox-tailwind/assets/css/config/safelist.css +++ b/modules/blox-tailwind/assets/css/config/safelist.css @@ -2,6 +2,7 @@ /* Note: In v4, we use @source inline to ensure these are included */ /* This ensures Tailwind generates these classes even if not found in templates */ +/* Inline safelist for classes used in dynamic content and YAML configuration */ @source inline("
"); /* Force generation of all CSS custom properties for dynamic usage in YAML front matter */ diff --git a/modules/blox-tailwind/assets/css/main.css b/modules/blox-tailwind/assets/css/main.css index 6fdcd56e..77dbcaf6 100644 --- a/modules/blox-tailwind/assets/css/main.css +++ b/modules/blox-tailwind/assets/css/main.css @@ -13,6 +13,9 @@ /* Tailwind CSS v4 Base */ @import "tailwindcss"; +/* Dynamic sources are injected by the css.html partial */ +/* This handles both monorepo dev and end-user environments */ + /* Configuration */ @import "config/tailwind.css"; @import "config/theme.css"; diff --git a/modules/blox-tailwind/assets/dist/lib/alpinejs/cdn.min.js b/modules/blox-tailwind/assets/dist/lib/alpinejs/cdn.min.js index fd09b496..0acdcefe 100644 --- a/modules/blox-tailwind/assets/dist/lib/alpinejs/cdn.min.js +++ b/modules/blox-tailwind/assets/dist/lib/alpinejs/cdn.min.js @@ -1,5 +1,5 @@ -(()=>{var rt=!1,nt=!1,U=[],it=-1;function qt(e){On(e)}function On(e){U.includes(e)||U.push(e),Cn()}function Ee(e){let t=U.indexOf(e);t!==-1&&t>it&&U.splice(t,1)}function Cn(){!nt&&!rt&&(rt=!0,queueMicrotask(Tn))}function Tn(){rt=!1,nt=!0;for(let e=0;ee.effect(t,{scheduler:r=>{ot?qt(r):r()}}),st=e.raw}function at(e){D=e}function Gt(e){let t=()=>{};return[n=>{let i=D(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),L(i))},i},()=>{t()}]}function Se(e,t){let r=!0,n,i=D(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>L(i)}var Jt=[],Yt=[],Xt=[];function Zt(e){Xt.push(e)}function ee(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Yt.push(t))}function Ae(e){Jt.push(e)}function Oe(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function ct(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function Qt(e){if(e._x_cleanups)for(;e._x_cleanups.length;)e._x_cleanups.pop()()}var lt=new MutationObserver(pt),ut=!1;function le(){lt.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ut=!0}function ft(){Rn(),lt.disconnect(),ut=!1}var ce=[];function Rn(){let e=lt.takeRecords();ce.push(()=>e.length>0&&pt(e));let t=ce.length;queueMicrotask(()=>{if(ce.length===t)for(;ce.length>0;)ce.shift()()})}function _(e){if(!ut)return e();ft();let t=e();return le(),t}var dt=!1,ve=[];function er(){dt=!0}function tr(){dt=!1,pt(ve),ve=[]}function pt(e){if(dt){ve=ve.concat(e);return}let t=new Set,r=new Set,n=new Map,i=new Map;for(let o=0;os.nodeType===1&&t.add(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.add(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{ct(s,o)}),n.forEach((o,s)=>{Jt.forEach(a=>a(s,o))});for(let o of r)t.has(o)||Yt.forEach(s=>s(o));t.forEach(o=>{o._x_ignoreSelf=!0,o._x_ignore=!0});for(let o of t)r.has(o)||o.isConnected&&(delete o._x_ignoreSelf,delete o._x_ignore,Xt.forEach(s=>s(o)),o._x_ignore=!0,o._x_ignoreSelf=!0);t.forEach(o=>{delete o._x_ignoreSelf,delete o._x_ignore}),t=null,r=null,n=null,i=null}function Ce(e){return F(j(e))}function P(e,t,r){return e._x_dataStack=[t,...j(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function j(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?j(e.host):e.parentNode?j(e.parentNode):[]}function F(e){return new Proxy({objects:e},Mn)}var Mn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Nn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?Reflect.set(i,t,r,n):Reflect.set(i,t,r)}};function Nn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function Te(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Re(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>Dn(n,i),s=>mt(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function Dn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function mt(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),mt(e[t[0]],t.slice(1),r)}}var rr={};function y(e,t){rr[e]=t}function ue(e,t){return Object.entries(rr).forEach(([r,n])=>{let i=null;function o(){if(i)return i;{let[s,a]=_t(t);return i={interceptor:Re,...s},ee(t,a),i}}Object.defineProperty(e,`$${r}`,{get(){return n(t,o())},enumerable:!1})}),e}function nr(e,t,r,...n){try{return r(...n)}catch(i){te(i,e,t)}}function te(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} +(()=>{var nt=!1,it=!1,W=[],ot=-1;function Ut(e){Rn(e)}function Rn(e){W.includes(e)||W.push(e),Mn()}function Wt(e){let t=W.indexOf(e);t!==-1&&t>ot&&W.splice(t,1)}function Mn(){!it&&!nt&&(nt=!0,queueMicrotask(Nn))}function Nn(){nt=!1,it=!0;for(let e=0;ee.effect(t,{scheduler:r=>{st?Ut(r):r()}}),at=e.raw}function ct(e){N=e}function Yt(e){let t=()=>{};return[n=>{let i=N(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}function ve(e,t){let r=!0,n,i=N(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>$(i)}var Xt=[],Zt=[],Qt=[];function er(e){Qt.push(e)}function te(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Zt.push(t))}function Ae(e){Xt.push(e)}function Oe(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function lt(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function tr(e){for(e._x_effects?.forEach(Wt);e._x_cleanups?.length;)e._x_cleanups.pop()()}var ut=new MutationObserver(mt),ft=!1;function ue(){ut.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ft=!0}function dt(){kn(),ut.disconnect(),ft=!1}var le=[];function kn(){let e=ut.takeRecords();le.push(()=>e.length>0&&mt(e));let t=le.length;queueMicrotask(()=>{if(le.length===t)for(;le.length>0;)le.shift()()})}function m(e){if(!ft)return e();dt();let t=e();return ue(),t}var pt=!1,Se=[];function rr(){pt=!0}function nr(){pt=!1,mt(Se),Se=[]}function mt(e){if(pt){Se=Se.concat(e);return}let t=[],r=new Set,n=new Map,i=new Map;for(let o=0;o{s.nodeType===1&&s._x_marker&&r.add(s)}),e[o].addedNodes.forEach(s=>{if(s.nodeType===1){if(r.has(s)){r.delete(s);return}s._x_marker||t.push(s)}})),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{lt(s,o)}),n.forEach((o,s)=>{Xt.forEach(a=>a(s,o))});for(let o of r)t.some(s=>s.contains(o))||Zt.forEach(s=>s(o));for(let o of t)o.isConnected&&Qt.forEach(s=>s(o));t=null,r=null,n=null,i=null}function Ce(e){return z(B(e))}function k(e,t,r){return e._x_dataStack=[t,...B(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function B(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?B(e.host):e.parentNode?B(e.parentNode):[]}function z(e){return new Proxy({objects:e},Dn)}var Dn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Pn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,t,r)}};function Pn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function Te(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Re(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>In(n,i),s=>ht(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function In(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function ht(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),ht(e[t[0]],t.slice(1),r)}}var ir={};function y(e,t){ir[e]=t}function fe(e,t){let r=Ln(t);return Object.entries(ir).forEach(([n,i])=>{Object.defineProperty(e,`$${n}`,{get(){return i(t,r)},enumerable:!1})}),e}function Ln(e){let[t,r]=_t(e),n={interceptor:Re,...t};return te(e,r),n}function or(e,t,r,...n){try{return r(...n)}catch(i){re(i,e,t)}}function re(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} ${r?'Expression: "'+r+`" -`:""}`,t),setTimeout(()=>{throw e},0)}var Me=!0;function De(e){let t=Me;Me=!1;let r=e();return Me=t,r}function M(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return ir(...e)}var ir=gt;function or(e){ir=e}function gt(e,t){let r={};ue(r,e);let n=[r,...j(e)],i=typeof t=="function"?Pn(n,t):kn(n,t,e);return nr.bind(null,e,t,i)}function Pn(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(F([n,...e]),i);Ne(r,o)}}var ht={};function In(e,t){if(ht[e])return ht[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(async()=>{ ${e} })()`:e,o=(()=>{try{let s=new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,"name",{value:`[Alpine] ${e}`}),s}catch(s){return te(s,t,e),Promise.resolve()}})();return ht[e]=o,o}function kn(e,t,r){let n=In(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=F([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>te(l,r,t));n.finished?(Ne(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Ne(i,l,a,s,r)}).catch(l=>te(l,r,t)).finally(()=>n.result=void 0)}}}function Ne(e,t,r,n,i){if(Me&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Ne(e,s,r,n)).catch(s=>te(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var bt="x-";function C(e=""){return bt+e}function sr(e){bt=e}var Pe={};function d(e,t){return Pe[e]=t,{before(r){if(!Pe[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${e}\` will use the default order of execution`);return}let n=W.indexOf(r);W.splice(n>=0?n:W.indexOf("DEFAULT"),0,e)}}}function ar(e){return Object.keys(Pe).includes(e)}function de(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=wt(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(ur((o,s)=>n[o]=s)).filter(dr).map($n(n,r)).sort(jn).map(o=>Ln(e,o))}function wt(e){return Array.from(e).map(ur()).filter(t=>!dr(t))}var xt=!1,fe=new Map,cr=Symbol();function lr(e){xt=!0;let t=Symbol();cr=t,fe.set(t,[]);let r=()=>{for(;fe.get(t).length;)fe.get(t).shift()();fe.delete(t)},n=()=>{xt=!1,r()};e(r),n()}function _t(e){let t=[],r=a=>t.push(a),[n,i]=Gt(e);return t.push(i),[{Alpine:B,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:M.bind(M,e)},()=>t.forEach(a=>a())]}function Ln(e,t){let r=()=>{},n=Pe[t.type]||r,[i,o]=_t(e);Oe(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),xt?fe.get(cr).push(n):n())};return s.runCleanups=o,s}var Ie=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),ke=e=>e;function ur(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=fr.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var fr=[];function re(e){fr.push(e)}function dr({name:e}){return pr().test(e)}var pr=()=>new RegExp(`^${bt}([^:^.]+)\\b`);function $n(e,t){return({name:r,value:n})=>{let i=r.match(pr()),o=r.match(/:([a-zA-Z0-9\-_:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var yt="DEFAULT",W=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",yt,"teleport"];function jn(e,t){let r=W.indexOf(e.type)===-1?yt:e.type,n=W.indexOf(t.type)===-1?yt:t.type;return W.indexOf(r)-W.indexOf(n)}function G(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function T(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>T(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)T(n,t,!1),n=n.nextElementSibling}function E(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var mr=!1;function _r(){mr&&E("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),mr=!0,document.body||E("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + + {{/* Publish the source map so the browser can load it at the expected path */}} + {{ $preact_map := resources.Get "dist/lib/preact/preact.min.js.map" }} + {{ if $preact_map }} + {{ $preact_map.Publish }} + {{ end }} + + {{ end }} + + {{/* Build and load each Preact block's client script */}} + {{ range $block_type := $preact_blocks }} + {{ $client_path := printf "js/hbx/blocks/%s/client.jsx" $block_type }} + {{ $client_jsx := resources.Get $client_path }} + + {{ if $client_jsx }} + {{/* Build the client-side JSX using Hugo's official integration */}} + {{ $jsx_opts := dict + "targetPath" (printf "js/%s-preact.js" $block_type) + "JSX" "automatic" + "JSXImportSource" "preact" + "format" "iife" + "minify" hugo.IsProduction + "sourceMap" (cond hugo.IsDevelopment "external" "") + }} + {{ $built_jsx := $client_jsx | js.Build $jsx_opts }} + {{ if hugo.IsProduction }} + {{ $built_jsx = $built_jsx | fingerprint "sha256" }} + {{ end }} + + {{ end }} + {{ end }} +{{ end }} + {{/* Load Alpine JS extension? */}} {{ if (.Page.Store.Get "has_alpine") }} @@ -100,4 +143,4 @@ {{ $plotly_js := resources.Get "dist/lib/plotly/plotly.min.js" }} {{ $plotly_js = $plotly_js | resources.Fingerprint "sha256" }} -{{ end }} +{{ end }} \ No newline at end of file diff --git a/modules/blox-tailwind/layouts/_partials/site_head.html b/modules/blox-tailwind/layouts/_partials/site_head.html index 3c151ee6..a6306af0 100644 --- a/modules/blox-tailwind/layouts/_partials/site_head.html +++ b/modules/blox-tailwind/layouts/_partials/site_head.html @@ -176,7 +176,6 @@ {{ $font_type = "woff2" }} {{end}} {{ $font := resources.Get (printf "dist/font/%s" $font_file) }} -