From 2b0afd20c6c1f282c10674d5a84e91f78806a85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Kuna?= <1282324+codecalm@users.noreply.github.com> Date: Mon, 21 Sep 2026 18:37:33 +0200 Subject: [PATCH] Import `tabler.js` in the Confetti and Sparkline demo scripts (#3105) --- .changeset/fix-esm-demo-scripts.md | 5 +++ preview/pages/confetti.astro | 58 +++++++++++++++++------------- preview/pages/sparkline.astro | 45 ++++++++++++----------- shared/layouts/BaseLayout.astro | 3 +- shared/lib/assets.test.ts | 12 ++++++- shared/lib/assets.ts | 9 +++++ 6 files changed, 85 insertions(+), 47 deletions(-) create mode 100644 .changeset/fix-esm-demo-scripts.md diff --git a/.changeset/fix-esm-demo-scripts.md b/.changeset/fix-esm-demo-scripts.md new file mode 100644 index 000000000..19b5b4c9f --- /dev/null +++ b/.changeset/fix-esm-demo-scripts.md @@ -0,0 +1,5 @@ +--- +"@tabler/preview": patch +--- + +Fixed the Confetti and Sparkline demo scripts to import from the `tabler.js` ES module instead of a `tabler` global. diff --git a/preview/pages/confetti.astro b/preview/pages/confetti.astro index 8d7e6437e..d51d79905 100644 --- a/preview/pages/confetti.astro +++ b/preview/pages/confetti.astro @@ -9,21 +9,43 @@ import DocsLink from '@ui/DocsLink.astro' import Button from '@ui/Button.astro' import ButtonList from '@ui/ButtonList.astro' import Badge from '@ui/Badge.astro' +import { tablerJsPath } from '@shared/lib/assets' + +// tabler.js is an ES module with no `window.tabler` global, so a script imports +// the component it drives. Built as strings because the import path depends on +// the build (`.min` outside development) and `define:vars` cannot carry an import. +const onLoadScript = ` + /* + One burst when the page opens. The instance lives on the body, so no element + on the page has to own it. + */ + import { Confetti } from '${tablerJsPath()}' + + Confetti.getOrCreateInstance(document.body).burst() + ` + +const formScript = ` + /* + Bursts confetti from code once the form is "saved". The instance lives on + the form, so the events fire there. + */ + import { Confetti } from '${tablerJsPath()}' + + const form = document.getElementById('confetti-form') + const confetti = Confetti.getOrCreateInstance(form, { count: 150, duration: 1500 }) + + form.addEventListener('submit', (event) => { + event.preventDefault() + confetti.burst() + }) + ` --- - + + + + diff --git a/shared/lib/assets.test.ts b/shared/lib/assets.test.ts index d2237cab4..a842d7f61 100644 --- a/shared/lib/assets.test.ts +++ b/shared/lib/assets.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { staticPath, assetRoot } from './assets' +import { staticPath, assetRoot, tablerJsPath } from './assets' // TABLER_STATIC_BASE is not defined in the test environment, so the relative // default ('./static') applies — same as the downloadable preview package. @@ -18,3 +18,13 @@ describe('assetRoot', () => { expect(assetRoot).toBe('.') }) }) + +describe('tablerJsPath', () => { + it('points at the minified module outside development', () => { + expect(tablerJsPath()).toBe('./dist/js/tabler.min.js') + }) + + it('takes the page root for nested pages', () => { + expect(tablerJsPath('..')).toBe('../dist/js/tabler.min.js') + }) +}) diff --git a/shared/lib/assets.ts b/shared/lib/assets.ts index b668731b5..7cb09c2e3 100644 --- a/shared/lib/assets.ts +++ b/shared/lib/assets.ts @@ -15,3 +15,12 @@ export const staticPath = (file: string): string => `${base}/${file.replace(/^\/ * relative default, "" when the base is absolute) — see Avatar's `base` prop. */ export const assetRoot = base.replace(/\/static$/, '') + +const min = (process.env.NODE_ENV || 'production') === 'development' ? '' : '.min' + +/** + * Url of the tabler.js ES module, for a demo script that imports a component + * from it. It has to be the very url the layout loads: a module is cached by + * url, so a different spelling would load and initialise tabler.js twice. + */ +export const tablerJsPath = (root = '.'): string => `${root}/dist/js/tabler${min}.js`