mirror of
https://github.com/tabler/tabler.git
synced 2026-01-25 12:26:30 +00:00
Compare commits
3 Commits
style/upda
...
dev-shiki
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6126649bcd | ||
|
|
e4e1ff40c1 | ||
|
|
938e9d35cc |
5
.changeset/add-shiki-highlight.md
Normal file
5
.changeset/add-shiki-highlight.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
---
|
||||
|
||||
Added Shiki code highlighting for `pre code` blocks with `language-*` classes.
|
||||
5
.changeset/highlight-component.md
Normal file
5
.changeset/highlight-component.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tabler/preview": minor
|
||||
---
|
||||
|
||||
Added Highlight page with examples using the `ui/highlight` component.
|
||||
14
README.md
14
README.md
@@ -28,13 +28,13 @@ A premium and open source dashboard template with a responsive and high-quality
|
||||
<p align="center">Browser testing via:</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.lambdatest.com/" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/14dd2a0a-bafe-436e-a6cb-29636278c781">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://github.com/user-attachments/assets/d3dede5a-d702-47c3-bb66-4d887948ed83">
|
||||
<img src="https://github.com/user-attachments/assets/d3dede5a-d702-47c3-bb66-4d887948ed83" alt="labmdatest" width="296">
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.testmu.ai" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/f0967860-31ad-4078-850b-40b0abc95582" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://github.com/user-attachments/assets/55ac290a-6729-44aa-bbc3-4c5e909facbf" />
|
||||
<img src="https://github.com/user-attachments/assets/86bcbe29-eb8d-4273-a381-5ce17d4ca92d" alt="TestMu AI" width="296">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## 🔎 Preview
|
||||
|
||||
30
core/.build/vite.config.mts
Normal file
30
core/.build/vite.config.mts
Normal file
@@ -0,0 +1,30 @@
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { createViteConfig } from '../../.build/vite.config.helper'
|
||||
import getBanner from '../../shared/banner/index.mjs'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const baseName = process.env.BASE_NAME || 'tabler'
|
||||
const entryFile = baseName
|
||||
const libraryName = baseName
|
||||
|
||||
const bannerText = getBanner()
|
||||
|
||||
const entryPath = path.resolve(__dirname, `../js/${entryFile}`)
|
||||
const entry = `${entryPath}.ts`
|
||||
|
||||
export default createViteConfig({
|
||||
entry: entry,
|
||||
name: libraryName,
|
||||
fileName: (format) => {
|
||||
const esmSuffix = format === 'es' ? '.esm' : ''
|
||||
return `${baseName}${esmSuffix}.js`
|
||||
},
|
||||
formats: ['es', 'umd'],
|
||||
outDir: path.resolve(__dirname, '../dist/js'),
|
||||
banner: bannerText,
|
||||
minify: false
|
||||
})
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { createViteConfig } from '../../.build/vite.config.helper'
|
||||
import getBanner from '../../shared/banner/index.mjs'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const ESM = process.env.ESM === 'true'
|
||||
const THEME = process.env.THEME === 'true'
|
||||
|
||||
const MINIFY = process.env.MINIFY === 'true'
|
||||
const destinationFile = `tabler${THEME ? '-theme' : ''}${ESM ? '.esm' : ''}`
|
||||
const entryFile = `tabler${THEME ? '-theme' : ''}`
|
||||
const libraryName = `tabler${THEME ? '-theme' : ''}`
|
||||
|
||||
const bannerText = getBanner()
|
||||
|
||||
// Try .ts first, fallback to .js for gradual migration
|
||||
const entryPath = path.resolve(__dirname, `../js/${entryFile}`)
|
||||
const entry = existsSync(`${entryPath}.ts`) ? `${entryPath}.ts` : `${entryPath}.js`
|
||||
|
||||
export default createViteConfig({
|
||||
entry: entry,
|
||||
name: ESM ? undefined : libraryName,
|
||||
fileName: () => MINIFY ? `${destinationFile}.min.js` : `${destinationFile}.js`,
|
||||
formats: [ESM ? 'es' : 'umd'],
|
||||
outDir: path.resolve(__dirname, '../dist/js'),
|
||||
banner: bannerText,
|
||||
minify: MINIFY ? true : false
|
||||
})
|
||||
|
||||
9
core/js/src/global.d.ts
vendored
9
core/js/src/global.d.ts
vendored
@@ -12,3 +12,12 @@ interface Window {
|
||||
Sortable?: new (element: HTMLElement, options?: any) => any
|
||||
}
|
||||
|
||||
declare module 'shiki/bundle/web' {
|
||||
export const createHighlighter: (options: {
|
||||
langs: string[]
|
||||
themes: string[]
|
||||
}) => Promise<{
|
||||
codeToHtml: (code: string, options: { lang: string; theme: string }) => string
|
||||
}>
|
||||
}
|
||||
|
||||
|
||||
84
core/js/src/shiki.ts
Normal file
84
core/js/src/shiki.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
type ShikiHighlighter = {
|
||||
codeToHtml: (code: string, options: { lang: string; theme: string }) => string
|
||||
}
|
||||
|
||||
const shikiSelector = 'pre code[class*="language-"], pre code[data-language]'
|
||||
const shikiCodeBlocks = Array.from(document.querySelectorAll<HTMLElement>(shikiSelector))
|
||||
|
||||
const getShikiLanguage = (codeBlock: HTMLElement): string => {
|
||||
const dataLanguage = codeBlock.dataset.language
|
||||
if (dataLanguage) {
|
||||
return dataLanguage
|
||||
}
|
||||
|
||||
const languageClass = Array.from(codeBlock.classList).find((className) => className.startsWith('language-'))
|
||||
return languageClass ? languageClass.replace('language-', '') : 'text'
|
||||
}
|
||||
|
||||
const getShikiTheme = (codeBlock: HTMLElement): string => {
|
||||
return codeBlock.dataset.shikiTheme || codeBlock.closest<HTMLElement>('[data-shiki-theme]')?.dataset.shikiTheme || 'github-dark'
|
||||
}
|
||||
|
||||
const getShikiBlocksToHighlight = (codeBlocks: HTMLElement[]): HTMLElement[] => {
|
||||
return codeBlocks.filter((codeBlock) => {
|
||||
const pre = codeBlock.closest('pre')
|
||||
return pre && !pre.classList.contains('shiki') && pre.dataset.shikiProcessed !== 'true'
|
||||
})
|
||||
}
|
||||
|
||||
const highlightShikiBlocks = async (codeBlocks: HTMLElement[]) => {
|
||||
if (!codeBlocks.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const languages = new Set<string>(['text'])
|
||||
|
||||
codeBlocks.forEach((codeBlock) => {
|
||||
languages.add(getShikiLanguage(codeBlock))
|
||||
})
|
||||
|
||||
const { createHighlighter, createCssVariablesTheme } = await import('shiki')
|
||||
|
||||
const theme = createCssVariablesTheme({
|
||||
name: 'css-variables',
|
||||
variablePrefix: '--shiki-',
|
||||
variableDefaults: {},
|
||||
fontStyle: true
|
||||
})
|
||||
|
||||
const highlighter = (await createHighlighter({
|
||||
langs: Array.from(languages).filter(Boolean),
|
||||
themes: [theme],
|
||||
})) as ShikiHighlighter
|
||||
|
||||
codeBlocks.forEach((codeBlock) => {
|
||||
const pre = codeBlock.closest('pre')
|
||||
if (!pre || pre.dataset.shikiProcessed === 'true') {
|
||||
return
|
||||
}
|
||||
|
||||
const language = getShikiLanguage(codeBlock)
|
||||
const code = codeBlock.textContent || ''
|
||||
|
||||
let highlightedHtml = ''
|
||||
try {
|
||||
highlightedHtml = highlighter.codeToHtml(code, { lang: language, theme: 'css-variables' })
|
||||
} catch (error) {
|
||||
highlightedHtml = highlighter.codeToHtml(code, { lang: 'text', theme: 'css-variables' })
|
||||
}
|
||||
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.innerHTML = highlightedHtml
|
||||
const highlightedPre = wrapper.firstElementChild
|
||||
|
||||
if (highlightedPre) {
|
||||
pre.dataset.shikiProcessed = 'true'
|
||||
pre.replaceWith(highlightedPre)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const shikiBlocksToHighlight = getShikiBlocksToHighlight(shikiCodeBlocks)
|
||||
if (shikiBlocksToHighlight.length) {
|
||||
void highlightShikiBlocks(shikiBlocksToHighlight)
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import './src/switch-icon'
|
||||
import './src/tab'
|
||||
import './src/toast'
|
||||
import './src/sortable'
|
||||
import './src/shiki'
|
||||
|
||||
// Re-export everything from bootstrap.ts (single source of truth)
|
||||
export * from './src/bootstrap'
|
||||
|
||||
@@ -19,16 +19,12 @@
|
||||
"css-lint": "pnpm run css-lint-variables",
|
||||
"css-lint-variables": "find-unused-sass-variables scss/ node_modules/bootstrap/scss/",
|
||||
"js": "pnpm run js-build && pnpm run js-build-min",
|
||||
"js-build": "concurrently \"pnpm run js-build-standalone\" \"pnpm run js-build-standalone-esm\" \"pnpm run js-build-theme\" \"pnpm run js-build-theme-esm\"",
|
||||
"js-build-theme-esm": "cross-env THEME=true ESM=true vite build --config .build/vite.config.ts",
|
||||
"js-build-theme": "cross-env THEME=true vite build --config .build/vite.config.ts",
|
||||
"js-build-standalone": "vite build --config .build/vite.config.ts",
|
||||
"js-build-standalone-esm": "cross-env ESM=true vite build --config .build/vite.config.ts",
|
||||
"js-build-min": "concurrently \"pnpm run js-build-min-standalone\" \"pnpm run js-build-min-standalone-esm\" \"pnpm run js-build-min-theme\" \"pnpm run js-build-min-theme-esm\"",
|
||||
"js-build-min-standalone": "cross-env MINIFY=true vite build --config .build/vite.config.ts",
|
||||
"js-build-min-standalone-esm": "cross-env MINIFY=true ESM=true vite build --config .build/vite.config.ts",
|
||||
"js-build-min-theme": "cross-env MINIFY=true THEME=true vite build --config .build/vite.config.ts",
|
||||
"js-build-min-theme-esm": "cross-env MINIFY=true THEME=true ESM=true vite build --config .build/vite.config.ts",
|
||||
"js-build": "concurrently \"pnpm run js-build-standalone\" \"pnpm run js-build-theme\"",
|
||||
"js-build-theme": "cross-env BASE_NAME=tabler-theme vite build --config .build/vite.config.mts",
|
||||
"js-build-standalone": "cross-env BASE_NAME=tabler vite build --config .build/vite.config.mts",
|
||||
"js-build-min": "concurrently \"pnpm run js-build-min-standalone\" \"pnpm run js-build-min-theme\"",
|
||||
"js-build-min-standalone": "concurrently \"terser dist/js/tabler.js --compress --mangle --comments '/@license|@preserve|^!/' --source-map \\\"content=dist/js/tabler.js.map,filename=dist/js/tabler.min.js.map,url=tabler.min.js.map\\\" -o dist/js/tabler.min.js\" \"terser dist/js/tabler.esm.js --module --compress --mangle --comments '/@license|@preserve|^!/' --source-map \\\"content=dist/js/tabler.esm.js.map,filename=dist/js/tabler.esm.min.js.map,url=tabler.esm.min.js.map\\\" -o dist/js/tabler.esm.min.js\"",
|
||||
"js-build-min-theme": "concurrently \"terser dist/js/tabler-theme.js --compress --mangle --comments '/@license|@preserve|^!/' --source-map \\\"content=dist/js/tabler-theme.js.map,filename=dist/js/tabler-theme.min.js.map,url=tabler-theme.min.js.map\\\" -o dist/js/tabler-theme.min.js\" \"terser dist/js/tabler-theme.esm.js --module --compress --mangle --comments '/@license|@preserve|^!/' --source-map \\\"content=dist/js/tabler-theme.esm.js.map,filename=dist/js/tabler-theme.esm.min.js.map,url=tabler-theme.esm.min.js.map\\\" -o dist/js/tabler-theme.esm.min.js\"",
|
||||
"copy": "concurrently \"pnpm run copy-img\" \"pnpm run copy-libs\" \"pnpm run copy-fonts\"",
|
||||
"copy-img": "shx mkdir -p dist/img && shx cp -rf img/* dist/img",
|
||||
"copy-libs": "tsx .build/copy-libs.ts",
|
||||
@@ -181,6 +177,7 @@
|
||||
"star-rating.js": "^4.3.1",
|
||||
"tom-select": "^2.4.3",
|
||||
"typed.js": "^2.1.0",
|
||||
"shiki": "^3.13.0",
|
||||
"typescript": "^5.9.3",
|
||||
"driver.js": "^1.0.0"
|
||||
},
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
/** Theme colors */
|
||||
@each $name, $color in map.merge($theme-colors, $social-colors) {
|
||||
@debug contrast-ratio($color, white), $name, $min-contrast-ratio;
|
||||
--#{$prefix}#{$name}: #{$color};
|
||||
--#{$prefix}#{$name}-rgb: #{to-rgb($color)};
|
||||
--#{$prefix}#{$name}-fg: #{if(contrast-ratio($color) > $min-contrast-ratio, var(--#{$prefix}light), var(--#{$prefix}dark))};
|
||||
|
||||
@@ -138,8 +138,6 @@
|
||||
|
||||
// Colors
|
||||
@function to-rgb($value) {
|
||||
@debug $value;
|
||||
|
||||
@return color.channel($value, 'red', $space: rgb), color.channel($value, 'green', $space: rgb), color.channel($value, 'blue', $space: rgb);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,3 +14,4 @@
|
||||
@import 'vendor/typed';
|
||||
@import 'vendor/turbo';
|
||||
@import 'vendor/fullcalendar';
|
||||
@import 'vendor/shiki';
|
||||
|
||||
47
core/scss/vendor/_shiki.scss
vendored
Normal file
47
core/scss/vendor/_shiki.scss
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
:root {
|
||||
--shiki-foreground: var(--#{$prefix}light);
|
||||
--shiki-background: var(--#{$prefix}bg-surface-dark);
|
||||
|
||||
--shiki-token-constant: #79b8ff;
|
||||
--shiki-token-string: #9ecbff;
|
||||
--shiki-token-comment: #6a737d;
|
||||
--shiki-token-keyword: #f97583;
|
||||
--shiki-token-parameter: #e1e4e8;
|
||||
--shiki-token-function: #b392f0;
|
||||
--shiki-token-string-expression: #79b8ff;
|
||||
--shiki-token-punctuation: #9ecbff;
|
||||
--shiki-token-link: #79b8ff;
|
||||
|
||||
--shiki-ansi-black: #000000;
|
||||
--shiki-ansi-black-dim: #00000080;
|
||||
--shiki-ansi-red: #bb0000;
|
||||
--shiki-ansi-red-dim: #bb000080;
|
||||
--shiki-ansi-green: #00bb00;
|
||||
--shiki-ansi-green-dim: #00bb0080;
|
||||
--shiki-ansi-yellow: #bbbb00;
|
||||
--shiki-ansi-yellow-dim: #bbbb0080;
|
||||
--shiki-ansi-blue: #0000bb;
|
||||
--shiki-ansi-blue-dim: #0000bb80;
|
||||
--shiki-ansi-magenta: #ff00ff;
|
||||
--shiki-ansi-magenta-dim: #ff00ff80;
|
||||
--shiki-ansi-cyan: #00bbbb;
|
||||
--shiki-ansi-cyan-dim: #00bbbb80;
|
||||
--shiki-ansi-white: #eeeeee;
|
||||
--shiki-ansi-white-dim: #eeeeee80;
|
||||
--shiki-ansi-bright-black: #555555;
|
||||
--shiki-ansi-bright-black-dim: #55555580;
|
||||
--shiki-ansi-bright-red: #ff5555;
|
||||
--shiki-ansi-bright-red-dim: #ff555580;
|
||||
--shiki-ansi-bright-green: #00ff00;
|
||||
--shiki-ansi-bright-green-dim: #00ff0080;
|
||||
--shiki-ansi-bright-yellow: #ffff55;
|
||||
--shiki-ansi-bright-yellow-dim: #ffff5580;
|
||||
--shiki-ansi-bright-blue: #5555ff;
|
||||
--shiki-ansi-bright-blue-dim: #5555ff80;
|
||||
--shiki-ansi-bright-magenta: #ff55ff;
|
||||
--shiki-ansi-bright-magenta-dim: #ff55ff80;
|
||||
--shiki-ansi-bright-cyan: #55ffff;
|
||||
--shiki-ansi-bright-cyan-dim: #55ffff80;
|
||||
--shiki-ansi-bright-white: #ffffff;
|
||||
--shiki-ansi-bright-white-dim: #ffffff80;
|
||||
}
|
||||
@@ -1,25 +1,20 @@
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { createViteConfig } from '../../.build/vite.config.helper'
|
||||
import getBanner from '../../shared/banner/index.mjs'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const MINIFY = process.env.MINIFY === 'true'
|
||||
|
||||
// Try .ts first, fallback to .js for gradual migration
|
||||
const entryPath = path.resolve(__dirname, '../js/docs')
|
||||
const entry = existsSync(`${entryPath}.ts`) ? `${entryPath}.ts` : `${entryPath}.js`
|
||||
const entry = `${entryPath}.ts`
|
||||
|
||||
export default createViteConfig({
|
||||
entry: entry,
|
||||
name: 'docs',
|
||||
fileName: () => MINIFY ? 'docs.min.js' : 'docs.js',
|
||||
fileName: () => 'docs.js',
|
||||
formats: ['es'],
|
||||
outDir: path.resolve(__dirname, '../dist/js'),
|
||||
banner: undefined,
|
||||
minify: MINIFY
|
||||
minify: false
|
||||
})
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
"build-assets": "concurrently \"pnpm run js\" \"pnpm run css\"",
|
||||
"html": "eleventy",
|
||||
"js": "pnpm run js-build && pnpm run js-build-min",
|
||||
"js-build": "vite build --config .build/vite.config.ts",
|
||||
"js-build": "vite build --config .build/vite.config.mts",
|
||||
"js-build-min": "pnpm run js-build-min-docs",
|
||||
"js-build-min-docs": "cross-env MINIFY=true vite build --config .build/vite.config.ts",
|
||||
"js-build-min-docs": "terser dist/js/docs.js --module --compress --mangle --comments '/@license|@preserve|^!/' --source-map \"content=dist/js/docs.js.map,filename=dist/js/docs.min.js.map,url=docs.min.js.map\" -o dist/js/docs.min.js",
|
||||
"css": "pnpm run css-build && pnpm run css-prefix && pnpm run css-minify",
|
||||
"css-build": "sass scss/:dist/css/ --no-source-map --load-path=./node_modules",
|
||||
"css-prefix": "postcss --config .build/postcss.config.mjs --replace \"dist/css/*.css\" \"!dist/css/*.rtl*.css\" \"!dist/css/*.min.css\"",
|
||||
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -160,6 +160,9 @@ importers:
|
||||
plyr:
|
||||
specifier: ^3.8.3
|
||||
version: 3.8.3
|
||||
shiki:
|
||||
specifier: ^3.13.0
|
||||
version: 3.13.0
|
||||
signature_pad:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { createViteConfig } from '../../.build/vite.config.helper'
|
||||
import getBanner from '../../shared/banner/index.mjs'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const MINIFY = process.env.MINIFY === 'true'
|
||||
const bannerText = getBanner('Demo')
|
||||
|
||||
// Try .ts first, fallback to .js for gradual migration
|
||||
const entryPath = path.resolve(__dirname, '../js/demo')
|
||||
const entry = existsSync(`${entryPath}.ts`) ? `${entryPath}.ts` : `${entryPath}.js`
|
||||
const entry = `${entryPath}.ts`
|
||||
|
||||
export default createViteConfig({
|
||||
entry: entry,
|
||||
name: 'demo',
|
||||
fileName: () => MINIFY ? 'demo.min.js' : 'demo.js',
|
||||
fileName: () => 'demo.js',
|
||||
formats: ['es'],
|
||||
outDir: path.resolve(__dirname, '../dist/preview/js'),
|
||||
banner: bannerText,
|
||||
minify: MINIFY
|
||||
minify: false
|
||||
})
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
"css-prefix": "postcss --config .build/postcss.config.mjs --replace \"dist/preview/css/*.css\" \"!dist/preview/css/*.rtl*.css\" \"!dist/preview/css/*.min.css\"",
|
||||
"css-minify": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/preview/css/ --batch --batch-suffix \".min\" \"dist/preview/css/*.css\" \"!dist/preview/css/*.min.css\" \"!dist/preview/css/*rtl*.css\"",
|
||||
"js": "pnpm run js-build && pnpm run js-build-min",
|
||||
"js-build": "vite build --config .build/vite.config.ts",
|
||||
"js-build": "vite build --config .build/vite.config.mts",
|
||||
"js-build-min": "pnpm run js-build-min-demo",
|
||||
"js-build-min-demo": "cross-env MINIFY=true vite build --config .build/vite.config.ts",
|
||||
"js-build-min-demo": "terser dist/preview/js/demo.js --module --compress --mangle --comments '/@license|@preserve|^!/' --source-map \"content=dist/preview/js/demo.js.map,filename=dist/preview/js/demo.min.js.map,url=demo.min.js.map\" -o dist/preview/js/demo.min.js",
|
||||
"clean": "shx rm -rf dist demo",
|
||||
"html": "pnpm run html-build && pnpm run html-prettify && pnpm run html-remove-prettier-ignore",
|
||||
"html-build": "eleventy",
|
||||
|
||||
91
preview/pages/highlight.html
Normal file
91
preview/pages/highlight.html
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
title: Highlight
|
||||
page-header: Highlight
|
||||
page-menu: base.highlight
|
||||
permalink: highlight.html
|
||||
layout: default
|
||||
---
|
||||
|
||||
{% capture example_html -%}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">Hello, Tabler!</h3>
|
||||
<p class="text-secondary">This is a simple card example.</p>
|
||||
</div>
|
||||
</div>
|
||||
{%- endcapture %}
|
||||
|
||||
{% capture example_js -%}
|
||||
const greet = (name) => {
|
||||
console.log(`Hello, ${name}!`)
|
||||
}
|
||||
|
||||
greet('Tabler')
|
||||
{%- endcapture %}
|
||||
|
||||
{% capture example_json -%}
|
||||
{
|
||||
"name": "tabler",
|
||||
"version": "1.4.0",
|
||||
"private": false
|
||||
}
|
||||
{%- endcapture %}
|
||||
|
||||
{% capture example_scss -%}
|
||||
$highlight-colors: (
|
||||
"primary": $primary,
|
||||
"secondary": $secondary
|
||||
);
|
||||
|
||||
.highlight-demo {
|
||||
color: map-get($highlight-colors, "primary");
|
||||
}
|
||||
{%- endcapture %}
|
||||
|
||||
{% capture example_shell -%}
|
||||
pnpm install
|
||||
pnpm -C core build
|
||||
{%- endcapture %}
|
||||
|
||||
<div class="row row-cols-1 row-cols-lg-2 g-3">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">HTML</h3>
|
||||
{% include "ui/highlight.html" lang="html" code=example_html %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">JavaScript</h3>
|
||||
{% include "ui/highlight.html" lang="js" code=example_js %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">JSON</h3>
|
||||
{% include "ui/highlight.html" lang="json" code=example_json %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">SCSS</h3>
|
||||
{% include "ui/highlight.html" lang="scss" code=example_scss %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">Shell</h3>
|
||||
{% include "ui/highlight.html" lang="shell" code=example_shell %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -161,6 +161,11 @@
|
||||
"title": "Markdown",
|
||||
"url": "markdown.html"
|
||||
},
|
||||
"highlight": {
|
||||
"title": "Highlight",
|
||||
"url": "highlight.html",
|
||||
"badge": "New"
|
||||
},
|
||||
"navigation": {
|
||||
"url": "navigation.html",
|
||||
"title": "Navigation"
|
||||
|
||||
4
shared/includes/ui/highlight.html
Normal file
4
shared/includes/ui/highlight.html
Normal file
@@ -0,0 +1,4 @@
|
||||
{% assign language = include.lang | default: 'text' %}
|
||||
{% assign class = include.class | default: '' %}
|
||||
{% assign code = include.code | default: '' %}
|
||||
<pre{% if class != '' %} class="{{ class }}"{% endif %}><code class="language-{{ language }}">{{ code | escape }}</code></pre>
|
||||
Reference in New Issue
Block a user