mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 05:06:55 +04:00
Import tabler.js in the Confetti and Sparkline demo scripts (#3105)
This commit is contained in:
1 parent
41d9b1b7d2
commit
2b0afd20c6
6 files changed
+85
-47
No files matched your search
@@ -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.
|
||||
@@ -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()
|
||||
})
|
||||
`
|
||||
---
|
||||
|
||||
<DefaultLayout title="Confetti" pageMenu="base.confetti" description="Confetti pours a short shower of colored pieces over the page to celebrate a finished task, a signup or a first success.">
|
||||
<DocsLink slot="page-header-actions" path="/ui/components/confetti" />
|
||||
<CaptureScript>
|
||||
<!-- BEGIN SCRIPT OF CONFETTI ON LOAD -->
|
||||
<script is:inline>
|
||||
/*
|
||||
One burst when the page opens. The instance lives on the body, so no element
|
||||
on the page has to own it.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
tabler.Confetti.getOrCreateInstance(document.body).burst()
|
||||
})
|
||||
</script>
|
||||
<script is:inline type="module" set:html={onLoadScript} />
|
||||
<!-- END SCRIPT OF CONFETTI ON LOAD -->
|
||||
</CaptureScript>
|
||||
<div class="row row-cards">
|
||||
@@ -116,7 +138,7 @@ import Badge from '@ui/Badge.astro'
|
||||
<Card>
|
||||
<CardBody>
|
||||
<CardTitle>From JavaScript</CardTitle>
|
||||
<CardSubtitle>Call <code>burst()</code> on a <code>tabler.Confetti</code> instance when something else finishes, for example a form that was saved.</CardSubtitle>
|
||||
<CardSubtitle>Call <code>burst()</code> on a <code>Confetti</code> instance when something else finishes, for example a form that was saved.</CardSubtitle>
|
||||
<form id="confetti-form" class="d-flex align-items-end gap-2">
|
||||
<div class="flex-fill">
|
||||
<label class="form-label" for="confetti-project">Project name</label>
|
||||
@@ -126,21 +148,7 @@ import Badge from '@ui/Badge.astro'
|
||||
</form>
|
||||
<CaptureScript>
|
||||
<!-- BEGIN SCRIPT OF CONFETTI FORM -->
|
||||
<script is:inline>
|
||||
/*
|
||||
Bursts confetti from code once the form is "saved". The instance lives on
|
||||
the form, so the events fire there.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const form = document.getElementById('confetti-form')
|
||||
const confetti = tabler.Confetti.getOrCreateInstance(form, { count: 150, duration: 1500 })
|
||||
|
||||
form.addEventListener('submit', (event) => {
|
||||
event.preventDefault()
|
||||
confetti.burst()
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script is:inline type="module" set:html={formScript} />
|
||||
<!-- END SCRIPT OF CONFETTI FORM -->
|
||||
</CaptureScript>
|
||||
</CardBody>
|
||||
|
||||
@@ -11,9 +11,33 @@ import Sparkline from '@ui/Sparkline.astro'
|
||||
import type { SparklineType } from '@ui/Sparkline.astro'
|
||||
import site from '@data/site.json'
|
||||
import { ucFirst } from '@shared/lib/string-format'
|
||||
import { tablerJsPath } from '@shared/lib/assets'
|
||||
|
||||
const colors = Object.keys(site.colors)
|
||||
|
||||
// tabler.js is an ES module with no `window.tabler` global, so the script imports
|
||||
// the component it drives. Built as a string because the import path depends on
|
||||
// the build (`.min` outside development) and `define:vars` cannot carry an import.
|
||||
const updateScript = `
|
||||
/*
|
||||
Pushes random data into a sparkline and counts the updated.bs.sparkline events.
|
||||
*/
|
||||
import { Sparkline } from '${tablerJsPath()}'
|
||||
|
||||
const element = document.getElementById('sparkline-orders')
|
||||
const sparkline = Sparkline.getOrCreateInstance(element)
|
||||
let updates = 0
|
||||
|
||||
document.getElementById('sparkline-update').addEventListener('click', () => {
|
||||
sparkline.update(Array.from({ length: 10 }, () => Math.floor(Math.random() * 30)))
|
||||
})
|
||||
|
||||
element.addEventListener('updated.bs.sparkline', () => {
|
||||
updates += 1
|
||||
document.getElementById('sparkline-updates').textContent = updates + (updates === 1 ? ' update' : ' updates')
|
||||
})
|
||||
`
|
||||
|
||||
const metrics: { name: string; value: string; color: string; type: SparklineType; fill?: string; values: string }[] = [
|
||||
{ name: 'Revenue', value: '$12.4k', color: 'success', type: 'line', fill: 'auto', values: '5,6,7,6,8,9,10' },
|
||||
{ name: 'Orders', value: '1,352', color: 'primary', type: 'bar', values: '3,4,2,6,5,8,7' },
|
||||
@@ -200,26 +224,7 @@ const progress = [
|
||||
</div>
|
||||
<CaptureScript>
|
||||
<!-- BEGIN SCRIPT OF SPARKLINE -->
|
||||
<script is:inline>
|
||||
/*
|
||||
Pushes random data into a sparkline and counts the updated.bs.sparkline events.
|
||||
tabler.js is deferred, so the instance is looked up once the DOM is ready.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const element = document.getElementById('sparkline-orders')
|
||||
const sparkline = tabler.Sparkline.getOrCreateInstance(element)
|
||||
let updates = 0
|
||||
|
||||
document.getElementById('sparkline-update').addEventListener('click', () => {
|
||||
sparkline.update(Array.from({ length: 10 }, () => Math.floor(Math.random() * 30)))
|
||||
})
|
||||
|
||||
element.addEventListener('updated.bs.sparkline', () => {
|
||||
updates += 1
|
||||
document.getElementById('sparkline-updates').textContent = `${updates} update${updates === 1 ? '' : 's'}`
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script is:inline type="module" set:html={updateScript} />
|
||||
<!-- END SCRIPT OF SPARKLINE -->
|
||||
</CaptureScript>
|
||||
</CardBody>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import ThemeSettings from '@shared/components/demo/ThemeSettings.astro'
|
||||
import { site } from '@shared/lib/site'
|
||||
import { tablerJsPath } from '@shared/lib/assets'
|
||||
import PageModals from '@shared/components/PageModals.astro'
|
||||
import PageScripts from '@shared/components/PageScripts.astro'
|
||||
import Analytics from '@shared/components/Analytics.astro'
|
||||
@@ -135,7 +136,7 @@ const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean
|
||||
}
|
||||
|
||||
<!-- BEGIN GLOBAL MANDATORY SCRIPTS -->
|
||||
<script is:inline type="module" src={`${base}/dist/js/tabler${min}.js`}></script>
|
||||
<script is:inline type="module" src={tablerJsPath(base)}></script>
|
||||
<!-- END GLOBAL MANDATORY SCRIPTS -->
|
||||
|
||||
<PageScripts />
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
@@ -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`
|
||||
Reference in new issue
Block a user