mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 13:17:00 +04:00
92 lines
3.9 KiB
Plaintext
92 lines
3.9 KiB
Plaintext
---
|
|
// Example code from the `html` prop or the rendered slot; the copy button carries it in data-bs-text.
|
|
import Icon from '@ui/Icon.astro'
|
|
import { beautifyHtml, highlightCode, removeHref } from '@shared/lib/code-example'
|
|
|
|
/**
|
|
* Demo area background:
|
|
* - surface-secondary — muted solid surface (default)
|
|
* - transparent — checkerboard pattern, for components with their own background
|
|
* - primary — theme-aware white (bg-surface)
|
|
*/
|
|
type ExampleBackground = 'surface-secondary' | 'transparent' | 'primary' | 'dark'
|
|
|
|
interface Props {
|
|
/** raw HTML of the example; when absent — the slot is rendered */
|
|
html?: string
|
|
/** code shown in the panel instead of html */
|
|
code?: string
|
|
raw?: boolean
|
|
overflow?: string
|
|
background?: ExampleBackground
|
|
class?: string
|
|
height?: string
|
|
column?: boolean
|
|
centered?: boolean
|
|
vertical?: boolean
|
|
columnFullWidth?: boolean
|
|
hideCode?: boolean
|
|
codeOnly?: boolean
|
|
/** no padding around the demo, for content that fills the whole area, such as a map */
|
|
flush?: boolean
|
|
}
|
|
|
|
const { html: htmlProp, code, raw, overflow = 'auto', background = 'surface-secondary', class: className, height, column, centered, vertical, columnFullWidth, hideCode, codeOnly, flush } = Astro.props
|
|
|
|
const backgroundClasses: Record<ExampleBackground, string> = {
|
|
'surface-secondary': 'bg-surface-secondary',
|
|
'transparent': 'bg-pattern-rectangles',
|
|
'primary': 'bg-surface',
|
|
'dark': 'bg-dark',
|
|
}
|
|
|
|
// Strip empty lines from the example HTML.
|
|
let html = (htmlProp ?? (await Astro.slots.render('default'))).replace(/^\s*[\r\n]/gm, '')
|
|
|
|
// JSX reserializes the slot markup: empty SVG elements get explicit closing
|
|
// tags, and apostrophes in text are escaped. We restore the source form so the
|
|
// code in the panel looks like hand-written HTML.
|
|
html = html.replace(/<(path|circle|line|polyline|polygon|rect|ellipse)([^>]*?)\s*><\/\1>/g, '<$1$2 />').replace(/'/g, "'")
|
|
|
|
// Demo and its code panel render as one visually joined group: the demo keeps
|
|
// only its top corners rounded when a code panel is attached below it.
|
|
const hasDemo = !codeOnly
|
|
const hasCode = !hideCode
|
|
const exampleClasses = ['example fs-base border', hasCode ? 'rounded-top' : 'rounded', !raw && 'd-flex flex-wrap justify-content-center', `overflow-${overflow}`, 'position-relative', backgroundClasses[background], className]
|
|
|
|
const innerClasses = [flush ? 'p-0' : 'p-6', 'w-full', column && 'd-flex gap-3 flex-column', !column && centered && `d-flex flex-fill flex-wrap gap-2 justify-content-center${vertical ? ' align-items-center flex-column' : ' justify-content-center'}`, columnFullWidth && 'd-flex flex-fill flex-column gap-2']
|
|
|
|
const highlighted = hideCode ? '' : await highlightCode(beautifyHtml(code ?? html), 'html')
|
|
---
|
|
|
|
<!--EXAMPLE-->{/* data-example-markup carries the markup for examples with no code panel, so the .md mirror (docs/lib/llms.ts) still has real html to show */}
|
|
<div class="docs-example my-5" data-example-markup={hideCode ? (code ?? html) : undefined}>
|
|
{
|
|
hasDemo && (
|
|
<div class:list={exampleClasses} style={height ? `height: ${height}` : undefined}>
|
|
{raw ? (
|
|
<Fragment set:html={removeHref(html)} />
|
|
) : (
|
|
<div class:list={innerClasses} style={column ? 'max-width: 25rem;' : undefined}>
|
|
<Fragment set:html={removeHref(html)} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
{
|
|
hasCode && (
|
|
<div class:list={['docs-example-code position-relative', hasDemo && 'docs-example-code-attached']}>
|
|
<button type="button" class="btn btn-icon btn-dark position-absolute m-2 top-0 end-0 z-3" data-bs-toggle="clipboard" data-bs-text={code ?? html} aria-label="Copy code">
|
|
<Icon name="clipboard" class="clipboard-label" />
|
|
<Icon name="check" class="clipboard-feedback" />
|
|
<span class="clipboard-feedback visually-hidden">Copied</span>
|
|
</button>
|
|
<Fragment set:html={highlighted} />
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
<!--/EXAMPLE-->
|