1
0
mirror of https://github.com/tabler/tabler.git synced 2025-12-22 09:54:24 +04:00

Compare commits

..

2 Commits

Author SHA1 Message Date
github-actions[bot]
2d320870f5 chore: update versions 2025-02-05 21:08:32 +00:00
BG-Software
11f4487286 Use the full license agreement for illustrations in docs (#2128)
* Use the full license agreement for illustrations in docs

* Create short-wombats-rhyme.md
2025-02-05 22:07:27 +01:00
2082 changed files with 5689 additions and 1677 deletions

View File

@@ -1,6 +1,11 @@
>= 1%
last 2 versions
Firefox ESR
last 1 major version
not dead
safari >= 15.4
iOS >= 15.4
Chrome >= 60
Firefox >= 60
Edge >= 15.15063
Explorer 11
iOS >= 10
Safari >= 10
Android >= 6
not ExplorerMobile <= 11

57
.build/download-images.js Normal file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env node
'use strict'
const fs = require('node:fs')
const path = require('node:path')
const request = require('request')
const filePath = path.join(__dirname, '../src/pages/_data/photos.json')
const photos = JSON.parse(fs.readFileSync(filePath, 'utf8'))
const urlTitle = (str) => {
str = str
.toLowerCase()
.replaceAll('&', 'and')
.replace(/[^[a-z0-9-]/g, '-')
.replace(/-+/g, '-')
return str
}
const download = function (uri, filename, callback, error) {
request.head(uri, function (err, res, body) {
request(uri).pipe(fs.createWriteStream(filename))
.on('close', callback)
.on('error', error)
})
}
async function downloadPhotos() {
for (const key in photos) {
const photo = photos[key]
let filename, i = 1;
do {
filename = `${urlTitle(photo['title'])}${i > 1 ? `-${i}` : ''}.jpg`
i++
} while (fs.existsSync(path.join(__dirname, `../src/static/photos/${filename}`)))
await new Promise((resolve, reject) => {
download(photo['path'], path.join(__dirname, `../src/static/photos/${filename}`), function () {
resolve()
}, function () {
reject()
});
})
photos[key]['file'] = filename
photos[key]['horizontal'] = photo['width'] > photo['height']
}
fs.writeFileSync(filePath, JSON.stringify(photos))
}
downloadPhotos();

37
.build/import-icons.js Normal file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env node
'use strict'
const fs = require('fs'),
path = require('path');
const iconsTags = require('../node_modules/@tabler/icons/icons.json'),
iconsPkg = require('../node_modules/@tabler/icons/package.json');
const prepareSvgFile = (svg) => {
return svg.replace(/\n/g, '').replace(/>\s+</g, '><').replace(/\s+/g, ' ')
}
let svgList = {}
for (let iconName in iconsTags) {
let iconData = iconsTags[iconName]
svgList[iconName] = {
name: iconName,
svg: {
outline: iconData.styles.outline ? prepareSvgFile(fs.readFileSync(path.join(__dirname, `../node_modules/@tabler/icons/icons/outline/${iconName}.svg`), 'utf8')) : null,
filled: iconData.styles.filled ? prepareSvgFile(fs.readFileSync(path.join(__dirname, `../node_modules/@tabler/icons/icons/filled/${iconName}.svg`), 'utf8')) : null,
}
}
}
fs.writeFileSync(
path.join(__dirname, `../src/pages/_data/icons-info.json`),
JSON.stringify({
version: iconsPkg.version,
count: Object.values(svgList).reduce((acc, icon) => {
return acc + (icon.svg.outline ? 1 : 0) + (icon.svg.filled ? 1 : 0)
}, 0)
})
)
fs.writeFileSync(path.join(__dirname, `../src/pages/_data/icons.json`), JSON.stringify(svgList))

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env node
'use strict'
const fs = require('fs'),
path = require('path'),
glob = require('glob');
const illustrations = glob
.sync(path.join(__dirname, `../src/static/illustrations/light/*.png`))
.map((file) => {
return path.basename(file, '.png')
})
fs.writeFileSync(
path.join(__dirname, `../src/pages/_data/illustrations.json`),
JSON.stringify(illustrations)
)
// let i = {}
// const dirs = ['light', 'dark', 'autodark']
// const ilustrations = ['not-found', 'computer-fix', 'boy-with-key', 'boy-girl']
// for(const dir of dirs) {
// i[dir] = {}
// for(const ilustration of ilustrations) {
// let svg = fs.readFileSync(path.join(__dirname, `../src/pages/_free-illustrations/${dir}/${ilustration}.svg`), 'utf8')
// svg = svg
// .replace(/\n+/g, ' ')
// .replace(/>\s+</g, '><')
// .replace(/\s+/g, ' ')
// .replace(/^[\n\s-]+/, '')
// i[dir][ilustration] = svg
// }
// }
// fs.writeFileSync(
// path.join(__dirname, `../src/pages/_data/free-illustrations.json`),
// JSON.stringify(i)
// )

36
.build/reformat-mdx.js Normal file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env node
'use strict'
const fs = require('fs'),
path = require('path'),
glob = require('glob'),
beautifyHtml = require('js-beautify').html;
const docs = glob
.sync(path.join(__dirname, `../docs/**/*.mdx`))
docs.forEach((file, i) => {
const oldContent = fs.readFileSync(file, 'utf8')
// get codeblocks from markdown
const content = oldContent.replace(/(```([a-z0-9]+).*?\n)(.*?)(```)/gs, (m, m1, m2, m3, m4) => {
if (m2 === 'html') {
let m3m = beautifyHtml(m3, {
"indent_size": 2,
"indent_char": " ",
}).trim();
// remove empty lines
m3m = m3m.replace(/^\s*[\r\n]/gm, '');
return m1 + m3m + "\n" + m4;
}
return m
})
if (content !== oldContent) {
fs.writeFileSync(file, content, 'utf8')
console.log(`Reformatted ${file}`)
}
})

26
.build/unused-files.js Normal file
View File

@@ -0,0 +1,26 @@
const glob = require('glob');
const fs = require('fs')
const path = require('path')
const srcDir = path.join(__dirname, '../src')
let foundFiles = []
glob.sync(`${srcDir}/pages/**/*.{html,md}`).forEach((file) => {
let fileContent = fs.readFileSync(file)
fileContent.toString().replace(/\{% include(_cached)? "([a-z0-9\/_-]+\.html)"/g, (f, c, filename) => {
filename = `${srcDir}/pages/_includes/${filename}`
if (!foundFiles.includes(filename)) {
foundFiles.push(filename)
}
})
})
let includeFiles = glob.sync(`${srcDir}/pages/_includes/**/*.html`)
includeFiles.forEach((file) => {
if (!foundFiles.includes(file)) {
console.log('file', file)
}
})

View File

@@ -1,5 +0,0 @@
---
"@tabler/core": patch
---
Enable `scrollSpy` in `countup` module

View File

@@ -1,4 +0,0 @@
---
---
Refactor bundlewatch workflow to use Turbo

View File

@@ -1,5 +0,0 @@
---
"@tabler/core": patch
---
Fix size of `apexcharts` tooltip marker

View File

@@ -1,5 +0,0 @@
---
"@tabler/core": patch
---
Refactored the project into a monorepo, removed Gulp, and introduced a new, more efficient build process.

View File

@@ -1,5 +0,0 @@
---
"@tabler/core": patch
---
Fix vertical alignment in single page and error layouts

View File

@@ -19,14 +19,6 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Cache turbo build setup
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
- name: Set up Node.js
uses: actions/setup-node@v4
with:
@@ -34,6 +26,8 @@ jobs:
- name: Install PNPM
uses: pnpm/action-setup@v4
with:
version: 8
- name: Set up Bundler
uses: ruby/setup-ruby@v1
@@ -44,7 +38,7 @@ jobs:
- name: Install pnpm dependencies
run: pnpm install --no-frozen-lockfile
- name: Build
- name: Run build
run: pnpm run build
- name: Run bundlewatch

View File

@@ -4,6 +4,7 @@ on:
push:
branches:
- main
- dev
permissions:
contents: read
@@ -30,6 +31,8 @@ jobs:
- name: Install PNPM
uses: pnpm/action-setup@v4
with:
version: 8
- name: Install Dependencies
run: pnpm install

View File

@@ -1,7 +1,8 @@
name: Test build
on:
pull_request: null
pull_request:
types: [ opened, reopened ]
env:
NODE: 20
@@ -16,14 +17,6 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Cache turbo build setup
uses: actions/cache@v4
with:
path: .turbo
key: ${{ runner.os }}-turbo-${{ github.sha }}
restore-keys: |
${{ runner.os }}-turbo-
- name: Set up Node.js
uses: actions/setup-node@v4
with:
@@ -31,6 +24,8 @@ jobs:
- name: Install PNPM
uses: pnpm/action-setup@v4
with:
version: 8
- run: node --version

1
.gitignore vendored
View File

@@ -28,7 +28,6 @@ node_modules/
.yarn
.next
.vercel
.turbo
package-lock.json
demo/

16
.vscode/settings.json vendored
View File

@@ -1,12 +1,14 @@
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"**/.idea/": true
"**/.git": false,
"**/.svn": false,
"**/.hg": false,
"**/CVS": false,
"**/.DS_Store": false,
"**/Thumbs.db": false,
"**/.idea/": false,
"dist": false,
"demo": false
},
"explorerExclude.backup": {}
}

View File

@@ -1,5 +1,11 @@
# Changelog
## 1.0.1
### Patch Changes
- 11f4487: Use the full license agreement for illustrations in docs
## 1.0.0 - 2025-01-28
### Minor Changes

View File

@@ -110,7 +110,7 @@ Once you complete the setup, you'll be able to run the various commands provided
## Build locally
You need to have `pnpm` installed.
You need to have `pnpm` and `bundler` installed.
1. From the root `/tabler` directory, run installation in the command line: `pnpm install`
2. Then execute `pnpm run start` to start up the application stack.

View File

@@ -1,38 +0,0 @@
#!/usr/bin/env node
'use strict'
import { readFileSync, writeFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url'
import { sync } from 'glob';
import beautify from 'js-beautify';
const __dirname = dirname(fileURLToPath(import.meta.url))
const docs = sync(join(__dirname, '..', 'docs', '**', '*.mdx'))
docs.forEach((file, i) => {
const oldContent = readFileSync(file, 'utf8')
// get codeblocks from markdown
const content = oldContent.replace(/(```([a-z0-9]+).*?\n)(.*?)(```)/gs, (m, m1, m2, m3, m4) => {
if (m2 === 'html') {
// m3 = beautify.default.html(m3, {
// "indent_size": 2,
// "indent_char": " ",
// }).trim();
// remove empty lines
m3 = m3.replace(/^\s*[\r\n]/gm, '');
return m1 + m3 + "\n" + m4;
}
return m
})
if (content !== oldContent) {
writeFileSync(file, content, 'utf8')
console.log(`Reformatted ${file}`)
}
})

View File

@@ -1,46 +0,0 @@
#!/usr/bin/env node
'use strict'
import { readFileSync, writeFileSync } from 'node:fs';
import { join, dirname, basename } from 'node:path';
import { fileURLToPath } from 'node:url'
import { sync } from 'glob';
import banner from '@repo/banner';
const __dirname = dirname(fileURLToPath(import.meta.url))
const styles = sync(join(__dirname, '..', 'dist', 'css', '*.css'))
const plugins = {
'tabler-flags': 'Flags',
'tabler-flags.rtl': 'Flags RTL',
'tabler-marketing': 'Marketing',
'tabler-marketing.rtl': 'Marketing RTL',
'tabler-payments': 'Payments',
'tabler-payments.rtl': 'Payments RTL',
'tabler-socials': 'Socials',
'tabler-socials.rtl': 'Socials RTL',
'tabler-vendors': 'Vendors',
'tabler-vendors.rtl': 'Vendors RTL',
}
styles.forEach((file, i) => {
const content = readFileSync(file, 'utf8')
const filename = basename(file)
const pluginKey = Object.keys(plugins).find(plugin => filename.includes(plugin))
const plugin = plugins[pluginKey]
const regex = /^(@charset ['"][a-zA-Z0-9-]+['"];?)\n?/i
let newContent = ''
if (content.match(regex)) {
newContent = content.replace(regex, (m, m1) => {
return `${m1}\n${banner(plugin)}\n`
})
} else {
newContent = `${banner(plugin)}\n${content}`
}
writeFileSync(file, newContent, 'utf8')
})

View File

@@ -1,15 +0,0 @@
export default context => {
return {
map: {
inline: false,
annotation: true,
sourcesContent: true
},
plugins: {
autoprefixer: {
cascade: false
},
rtlcss: context.env === 'RTL'
}
}
}

View File

@@ -1,46 +0,0 @@
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { babel } from '@rollup/plugin-babel'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import replace from '@rollup/plugin-replace'
import banner from '@repo/banner'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const ESM = process.env.ESM === 'true'
let destinationFile = `tabler${ESM ? '.esm' : ''}`
const external = []
const plugins = [
babel({
exclude: 'node_modules/**',
babelHelpers: 'bundled'
})
]
plugins.push(
replace({
'process.env.NODE_ENV': '"production"',
preventAssignment: true
}),
nodeResolve()
)
const rollupConfig = {
input: path.resolve(__dirname, `../js/tabler.${ESM ? 'esm' : 'umd'}.js`),
output: {
banner: banner(),
file: path.resolve(__dirname, `../dist/js/${destinationFile}.js`),
format: ESM ? 'esm' : 'umd',
generatedCode: 'es2015'
},
external,
plugins
}
if (!ESM) {
rollupConfig.output.name = 'tabler'
}
export default rollupConfig

View File

@@ -1,3 +0,0 @@
export * as Popper from '@popperjs/core';
export { Dropdown, Tooltip, Popover, Tab, Toast } from 'bootstrap';

View File

@@ -1,150 +0,0 @@
{
"name": "@tabler/core",
"version": "1.0.0",
"description": "Premium and Open Source dashboard template with responsive and high quality UI.",
"homepage": "https://tabler.io",
"scripts": {
"dev": "pnpm run watch",
"build": "pnpm run clean && pnpm run css && pnpm run js && pnpm run copy",
"clean": "rm -rf dist/* demo",
"css": "pnpm run css-compile && pnpm run css-prefix && pnpm run css-rtl && pnpm run css-minify && pnpm run css-banner",
"css-compile": "sass scss/:dist/css/ --no-source-map --load-path=node_modules",
"css-banner": "node build/add-banner.mjs",
"css-prefix": "postcss --config build/postcss.config.mjs --replace 'dist/css/*.css' '!dist/css/*.rtl*.css' '!dist/css/*.min.css'",
"css-rtl": "cross-env NODE_ENV=RTL postcss --config build/postcss.config.mjs --dir 'dist/css' --ext '.rtl.css' 'dist/css/*.css' '!dist/css/*.min.css' '!dist/css/*.rtl.css'",
"css-minify": "pnpm run css-minify-main && pnpm run css-minify-rtl",
"css-minify-main": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/css/ --batch --batch-suffix '.min' 'dist/css/*.css' '!dist/css/*.min.css' '!dist/css/*rtl*.css'",
"css-minify-rtl": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/css/ --batch --batch-suffix '.min' 'dist/css/*rtl.css' '!dist/css/*.min.css'",
"js": "pnpm run js-compile && pnpm run js-minify",
"js-compile": "pnpm run js-compile-standalone && pnpm run js-compile-standalone-esm",
"js-compile-standalone": "rollup --config build/rollup.config.mjs --sourcemap",
"js-compile-standalone-esm": "rollup --environment ESM:true --config build/rollup.config.mjs --sourcemap",
"js-minify": "pnpm run js-minify-standalone && pnpm run js-minify-standalone-esm",
"js-minify-standalone": "terser --compress passes=2 --mangle --comments '/^!/' --source-map 'content=dist/js/tabler.js.map,includeSources,url=tabler.min.js.map' --output dist/js/tabler.min.js dist/js/tabler.js",
"js-minify-standalone-esm": "terser --compress passes=2 --mangle --comments '/^!/' --source-map 'content=dist/js/tabler.esm.js.map,includeSources,url=tabler.esm.min.js.map' --output dist/js/tabler.esm.min.js dist/js/tabler.esm.js",
"copy": "pnpm run copy-img",
"copy-img": "cp -r img dist/img",
"watch": "pnpm run watch-css & pnpm run watch-js",
"watch-css": "nodemon --watch scss/ --ext scss --exec 'pnpm run css-compile && pnpm run css-prefix'",
"watch-js": "nodemon --watch js/ --ext js --exec 'pnpm run js-compile'",
"bundlewatch": "bundlewatch",
"format:check": "prettier --check src/**/*.{js,scss} --cache",
"format:write": "prettier --write src/**/*.{js,scss} --cache"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tabler/tabler.git"
},
"keywords": [
"css",
"sass",
"mobile-first",
"responsive",
"front-end",
"framework",
"web"
],
"author": "codecalm",
"license": "MIT",
"bugs": {
"url": "https://github.com/tabler/tabler/issues"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/codecalm"
},
"engines": {
"node": ">=20"
},
"files": [
"docs/**/*",
"dist/**/*",
"js/**/*.{js,map}",
"img/**/*.{svg}",
"scss/**/*.scss"
],
"style": "dist/css/tabler.css",
"sass": "scss/tabler.scss",
"unpkg": "dist/js/tabler.min.js",
"umd:main": "dist/js/tabler.min.js",
"module": "dist/js/tabler.esm.js",
"main": "dist/js/tabler.js",
"bundlewatch": {
"files": [
{
"path": "./dist/css/tabler.css",
"maxSize": "75 kB"
},
{
"path": "./dist/css/tabler.min.css",
"maxSize": "70 kB"
},
{
"path": "./dist/css/tabler.rtl.css",
"maxSize": "75 kB"
},
{
"path": "./dist/css/tabler.rtl.min.css",
"maxSize": "70 kB"
},
{
"path": "./dist/css/tabler-flags.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-flags.min.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-payments.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-payments.min.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-socials.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-socials.min.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-vendors.css",
"maxSize": "7.5 kB"
},
{
"path": "./dist/css/tabler-vendors.min.css",
"maxSize": "6.5 kB"
},
{
"path": "./dist/js/tabler.js",
"maxSize": "60 kB"
},
{
"path": "./dist/js/tabler.min.js",
"maxSize": "45 kB"
},
{
"path": "./dist/js/tabler.esm.js",
"maxSize": "60 kB"
},
{
"path": "./dist/js/tabler.esm.min.js",
"maxSize": "45 kB"
}
]
},
"dependencies": {
"@popperjs/core": "^2.11.8",
"bootstrap": "5.3.3"
},
"devDependencies": {
"@repo/banner": "workspace:*"
},
"directories": {
"doc": "docs"
}
}

View File

@@ -2,21 +2,89 @@
title: Tabler Illustrations License
---
Codecalm.net grants you an on-going, non-exclusive license to use the Tabler Illustrations.
### Personal License
By purchasing Tabler Illustrations, you are granted an ongoing, non-exclusive license by codecalm.net to use Tabler Illustrations.
The license grants permission to one individual (the Licensee) to access and use the Tabler Illustrations.
## What You Can Do with Tabler Illustrations
You **can**:
* Use the Tabler Illustrations to create unlimited End Products.
* Modify the Tabler Illustrations to create derivative Tabler Illustrations. Those Tabler Illustrations are subject to this license.
* Use the Tabler Illustrations to create unlimited End Products for unlimited Clients.
* Use the Tabler Illustrations to create End Products where the End Product is sold to End Users.
## What You Cannot Do with Tabler Illustrations
You **cannot**:
* Use the Tabler Illustrations to create End Products that are designed to allow an End User to build their own End Products using the Tabler Illustrations or derivatives of the Tabler Illustrations.
* Re-distribute the Tabler Illustrations or derivatives of the Tabler Illustrations separately from an End Product, neither in code or as design assets.
* Share your access to the Tabler Illustrations with any other individuals.
* Re-distribute the Tabler Illustrations or derivatives of the Tabler Illustrations separately from an End Product, neither in code nor as design assets.
* Share your access to the Tabler Illustrations with any other individuals. You need a Team License for that to be allowed.
* Use the Tabler Illustrations to create End Products that are open source and freely available to End Users.
* Use the Tabler Illustrations to produce anything that may be deemed by Codecalm.net, in their sole and absolute discretion, to be competitive or in conflict with the business of Codecalm.net
* Use the Tabler Illustrations to produce anything that may be deemed by codecalm.net, in their sole and absolute discretion, to be competitive or in conflict with the business of codecalm.net
#### Example usage
Examples of usage **allowed** by the license:* Creating a personal website by yourself.
* Creating a website or web application for a client that will be owned by that client.
* Creating a commercial SaaS application (like an invoicing app for example) where end users have to pay a fee to use the application.
* Creating a commercial self-hosted web application that is sold to end users for a one-time fee.
Examples of usage **not allowed** by the license:
* Creating a repository of your favorite Tabler Illustrations (or derivatives based on Tabler Illustrations) and publishing it publicly.
* Creating a UI library using Tabler Illustrations and making it available either for sale or for free.
* Converting a Tabler Illustrations to another framework and making it available either for sale or for free.
* Creating a Figma or Sketch file based on the Tabler Illustrations.
* Creating a "website builder" project where end users can build their own websites using illustrations included with or derived from Tabler Illustrations.
* Creating a theme, template, or project starter kit using the illustrations and making it available either for sale or for free.
* Creating a web application where the primary purpose is clearly not to simply re-distribute the illustrations (like a conference organization app that uses the illustrations for its UI for example) that is free and open source, where the source code is publicly available.
In simple terms, use Tabler Illustrations for anything you like as long as it doesn't compete with Tabler Illustrations.
### Team License
By purchasing Tabler Illustrations, you are granted an ongoing, non-exclusive license by codecalm.net to use Tabler Illustrations.
The license grants permission for up to 10 Employees and Contractors of the Licensee to access and use the Tabler Illustrations.
You **can**:
* Use the Tabler Illustrations to create unlimited End Products.
* Modify the Tabler Illustrations to create derivative Tabler Illustrations. Those Tabler Illustrations are subject to this license.
* Use the Tabler Illustrations to create unlimited End Products for unlimited Clients.
* Use the Tabler Illustrations to create End Products where the End Product is sold to End Users.
You **cannot**:
* Use the Tabler Illustrations to create End Products that are designed to allow an End User to build their own End Products using the Tabler Illustrations or derivatives of the Tabler Illustrations.
* Re-distribute the Tabler Illustrations or derivatives of the Tabler Illustrations separately from an End Product.
* Use the Tabler Illustrations to create End Products that are the property of any individual or entity other than the Licensee or Clients of the Licensee.
* Grant access to the Tabler Illustrations to individuals who are not an Employee or Contractor of the Licensee.
* Use the Tabler Illustrations to create End Products that are open source and freely available to End Users.
* Use the Tabler Illustrations to produce anything that may be deemed by codecalm.net, in their sole and absolute discretion, to be competitive or in conflict with the business of codecalm.net
#### Example usage
Examples of usage **allowed** by the license:
* Creating a website for your company.
* Creating a website or web application for a client that will be owned by that client.
* Creating a commercial SaaS application (like an invoicing app for example) where end users have to pay a fee to use the application.
* Creating a commercial self-hosted web application that is sold to end users for a one-time fee.
Examples of use **not allowed** by the license:
* Creating a repository of your favorite Tabler Illustrations (or derivatives based on Tabler Illustrations) and publishing it publicly.
* Creating a UI library using Tabler Illustrations and making it available either for sale or for free.
* Converting a Tabler Illustrations to another framework and making it available either for sale or for free.
* Creating a "website builder" project where end users can build their own websites using illustrations included with or derived from Tabler Illustrations.
* Creating a theme or template using the illustrations and making it available either for sale or for free.
* Creating any End Product that is not the sole property of either your company or a client of your company. For example your employees/contractors can't use your company Tabler Illustrations license to build their own websites or side projects.
* Giving someone access to Tabler Illustrations when they purchase a product from you. For example, you can't use a Team License as a way to give someone access to Tabler Illustrations when they purchase an online course from you.
* Selling access to your team account to people who don't work for you company.
---
In case of differences between above license agreements and the license agreements provided with the product, the license agreement provided with the product shall prevail.

View File

@@ -1,58 +1,20 @@
import { readFileSync } from 'node:fs';
import { readFileSync } from 'fs';
import { EleventyRenderPlugin } from "@11ty/eleventy";
import { join, dirname } from 'node:path';
/*
* Copy list
*/
const getCopyList = () => {
let copy = {
"node_modules/@tabler/core/dist": "core",
"pages/favicon.ico": "favicon.ico",
"static": "static",
}
const libs = JSON.parse(readFileSync('./pages/_data/libs.json'));
let files = []
Object.keys(libs.js).forEach((lib) => {
files.push(Array.isArray(libs.js[lib]) ? libs.js[lib] : [libs.js[lib]])
})
Object.keys(libs.css).forEach((lib) => {
files.push(Array.isArray(libs.css[lib]) ? libs.css[lib] : [libs.css[lib]])
})
Object.keys(libs['js-copy']).forEach((lib) => {
files.push(libs['js-copy'][lib])
})
files = files.flat()
files.forEach((file) => {
if (!file.match(/^https?/)) {
copy[`node_modules/${dirname(file)}`] = `libs/${dirname(file) }`;
}
})
return copy;
}
/** @type {import('@11ty/eleventy').LocalConfig} */
export default function (eleventyConfig) {
const env = process.env.NODE_ENV || "development";
const isDevelopment = env === "development";
eleventyConfig.setInputDirectory("pages");
eleventyConfig.setOutputDirectory("dist");
eleventyConfig.setInputDirectory("src/pages");
eleventyConfig.setOutputDirectory(process.env.DIST_DIR || "demo");
eleventyConfig.setLayoutsDirectory("_layouts");
eleventyConfig.setIncludesDirectory("_includes");
eleventyConfig.addWatchTarget("../core/dist/**");
eleventyConfig.setWatchThrottleWaitTime(100);
eleventyConfig.addPassthroughCopy(getCopyList());
eleventyConfig.addPassthroughCopy("src/pages/favicon.ico");
eleventyConfig.addPlugin(EleventyRenderPlugin, {
accessGlobalData: true,
@@ -65,15 +27,19 @@ export default function (eleventyConfig) {
jekyllWhere: true,
});
if (isDevelopment) {
eleventyConfig.addWatchTarget("dist");
}
/**
* Data
*/
eleventyConfig.addGlobalData("environment", env);
eleventyConfig.addGlobalData("package", JSON.parse(readFileSync(join("..", "core", "package.json"), "utf-8")));
eleventyConfig.addGlobalData("readme", readFileSync(join("..", "README.md"), "utf-8"));
eleventyConfig.addGlobalData("license", readFileSync(join("..", "LICENSE"), "utf-8"));
eleventyConfig.addGlobalData("changelog", readFileSync(join("..", "CHANGELOG.md"), "utf-8"));
eleventyConfig.addGlobalData("package", JSON.parse(readFileSync("package.json", "utf-8")));
eleventyConfig.addGlobalData("readme", readFileSync("README.md", "utf-8"));
eleventyConfig.addGlobalData("license", readFileSync("LICENSE", "utf-8"));
eleventyConfig.addGlobalData("changelog", readFileSync("CHANGELOG.md", "utf-8"));
eleventyConfig.addGlobalData("site", {
title: "Tabler",

400
gulpfile.js Normal file
View File

@@ -0,0 +1,400 @@
const gulp = require('gulp'),
debug = require('gulp-debug'),
clean = require('gulp-clean'),
sass = require('gulp-sass')(require('sass')),
postcss = require('gulp-postcss'),
header = require('gulp-header'),
cleanCSS = require('gulp-clean-css'),
rtlcss = require('gulp-rtlcss'),
minifyJS = require('gulp-terser'),
rename = require('gulp-rename'),
purgecss = require('gulp-purgecss'),
rollupStream = require('@rollup/stream'),
rollupBabel = require('rollup-plugin-babel'),
rollupCleanup = require('rollup-plugin-cleanup'),
{ nodeResolve } = require('@rollup/plugin-node-resolve'),
rollupCommonjs = require('@rollup/plugin-commonjs'),
rollupReplace = require('@rollup/plugin-replace'),
vinylSource = require('vinyl-source-stream'),
vinylBuffer = require('vinyl-buffer'),
browserSync = require('browser-sync'),
spawn = require('cross-spawn'),
path = require('path'),
yargs = require('yargs/yargs'),
cp = require('child_process'),
pkg = require('./package.json'),
year = new Date().getFullYear(),
replace = require('gulp-replace'),
argv = yargs(process.argv).argv
let BUILD = false,
distDir = './dist',
demoDir = './demo',
srcDir = './src'
/**
* Enable BUILD mode and set directories
*/
gulp.task('build-on', (cb) => {
BUILD = true
cb()
})
/**
* Return banner added to CSS and JS dist files
*/
const getBanner = () => {
return `/*!
* Tabler v${pkg.version} (${pkg.homepage})
* @version ${pkg.version}
* @link ${pkg.homepage}
* Copyright 2018-${year} The Tabler Authors
* Copyright 2018-${year} codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
`
}
/**
* Clean `dist` folder before build
*/
gulp.task('clean-dirs', () => {
return gulp
.src(`{${distDir}/*,${demoDir}/*}`, { read: false })
.pipe(clean())
})
/**
* Compile SASS to CSS and move it to dist directory
*/
gulp.task('sass', () => {
return gulp
.src(`${srcDir}/scss/!(_)*.scss`)
.pipe(debug())
.pipe(sass({
includePaths: ['node_modules'],
style: 'expanded',
precision: 7,
importer: (url, prev, done) => {
if (url[0] === '~') {
url = path.resolve('node_modules', url.substr(1))
}
return { file: url }
},
}))
.on('error', function (err) {
throw err;
})
.pipe(postcss([
require('autoprefixer'),
]))
.pipe(gulp.dest(`${distDir}/css/`))
.pipe(browserSync.reload({
stream: true,
}));
})
gulp.task('css-rtl', function () {
return gulp.src(`${distDir}/css/*.css`)
.pipe(rtlcss())
.pipe(rename((path) => {
path.basename += '.rtl'
}))
.pipe(gulp.dest(`${distDir}/css/`))
});
/**
* CSS minify
*/
gulp.task('css-minify', function () {
return gulp.src(`${distDir}/css/!(*.min).css`)
.pipe(debug())
.pipe(cleanCSS())
.pipe(rename((path) => {
path.basename += '.min'
}))
.pipe(gulp.dest(`${distDir}/css/`))
})
/**
* Compile JS files to dist directory
*/
let cache = {}
const compileJs = function (name, mjs = false) {
if (!cache[name]) {
cache[name] = null
}
const g = rollupStream({
input: `${srcDir}/js/${name}.js`,
cache: cache[name],
output: {
name: `${name}.js`,
format: mjs ? 'es' : 'umd',
...(mjs ? { exports: 'named' } : {})
},
plugins: [
rollupReplace({
'process.env.NODE_ENV': JSON.stringify(BUILD ? 'production' : 'development'),
preventAssignment: false
}),
rollupBabel({
exclude: 'node_modules/**'
}),
nodeResolve(),
rollupCommonjs(),
rollupCleanup()
]
})
.on('bundle', (bundle) => {
cache[name] = bundle
})
.pipe(vinylSource(`${name}.js`))
.pipe(vinylBuffer())
.pipe(rename((path) => {
path.dirname = ''
}))
.pipe(gulp.dest(`${distDir}/js/`))
.pipe(browserSync.reload({
stream: true,
}))
if (BUILD) {
g.pipe(minifyJS())
.pipe(rename((path) => {
path.extname = '.min.js'
}))
.pipe(gulp.dest(`${distDir}/js/`))
}
return g
}
/**
* Compile JS files to dist directory
*/
gulp.task('js', () => {
return compileJs('tabler')
})
gulp.task('js-demo', () => {
return compileJs('demo')
})
gulp.task('js-demo-theme', () => {
return compileJs('demo-theme')
})
/**
* Compile JS module files to dist directory
*/
gulp.task('mjs', () => {
return compileJs('tabler.esm', true)
})
let cacheEsm
gulp.task('mjs', () => {
const g = rollupStream({
input: `${srcDir}/js/tabler.esm.js`,
cache: cacheEsm,
output: {
name: 'tabler.esm.js',
format: 'es',
exports: 'named'
},
plugins: [
rollupReplace({
'process.env.NODE_ENV': JSON.stringify(BUILD ? 'production' : 'development'),
preventAssignment: false
}),
rollupBabel({
exclude: 'node_modules/**'
}),
nodeResolve(),
rollupCommonjs(),
rollupCleanup()
]
})
.on('bundle', (bundle) => {
cacheEsm = bundle
})
.pipe(vinylSource('tabler.esm.js'))
.pipe(vinylBuffer())
.pipe(rename((path) => {
path.dirname = ''
}))
.pipe(gulp.dest(`${distDir}/js/`))
.pipe(browserSync.reload({
stream: true,
}))
if (BUILD) {
g.pipe(minifyJS())
.pipe(rename((path) => {
path.extname = '.min.js'
}))
.pipe(gulp.dest(`${distDir}/js/`))
}
return g
})
/**
* Watch eleventy files and build it to demo directory
*/
gulp.task('watch-eleventy', (cb) => {
browserSync.notify('Building eleventy')
return spawn('pnpm', ['run', 'watch:html'], { stdio: 'inherit' })
.on('close', cb)
})
/**
* Build eleventy files do demo directory
*/
gulp.task('build-eleventy', (cb) => {
var env = Object.create(process.env)
if (argv.preview) {
env.eleventy_ENV = 'preview'
} else {
env.eleventy_ENV = 'production'
}
return spawn('pnpm', ['run', 'build:html'], {
env: env,
stdio: 'inherit'
})
.on('close', cb)
})
gulp.task('build-cleanup', () => {
return gulp
.src(`${demoDir}/redirects.json`, { read: false, allowEmpty: true })
.pipe(clean())
})
gulp.task('build-purgecss', (cb) => {
if (argv.preview) {
return gulp.src('demo/dist/{libs,css}/**/*.css')
.pipe(purgecss({
content: ['demo/**/*.html']
}))
.pipe(gulp.dest('demo/dist/css'))
}
cb()
})
/**
* Watch JS and SCSS files
*/
gulp.task('watch', (cb) => {
gulp.watch('./src/scss/**/*.scss', gulp.series('sass'))
gulp.watch('./src/js/**/*.js', gulp.parallel('js', 'mjs', gulp.parallel('js-demo', 'js-demo-theme')))
cb()
})
/**
* Create BrowserSync server
*/
gulp.task('browser-sync', () => {
browserSync({
watch: true,
server: {
baseDir: demoDir,
routes: {
'/node_modules': 'node_modules',
'/dist/img': `${srcDir}/img`,
'/static': `${srcDir}/static`,
'/dist': `${distDir}`,
},
},
port: 3000,
open: false,
host: 'localhost',
notify: false,
reloadOnRestart: true
})
})
/**
* Copy libs used in tabler from npm to dist directory
*/
gulp.task('copy-libs', (cb) => {
const allLibs = require(`${srcDir}/pages/_data/libs`)
let files = []
Object.keys(allLibs.js).forEach((lib) => {
files.push(Array.isArray(allLibs.js[lib]) ? allLibs.js[lib] : [allLibs.js[lib]])
})
Object.keys(allLibs.css).forEach((lib) => {
files.push(Array.isArray(allLibs.css[lib]) ? allLibs.css[lib] : [allLibs.css[lib]])
})
Object.keys(allLibs['js-copy']).forEach((lib) => {
files.push(allLibs['js-copy'][lib])
})
files = files.flat()
files.forEach((file) => {
if (!file.match(/^https?/)) {
let dirname = path.dirname(file).replace('@', '')
let cmd = `mkdir -p "${distDir}/libs/${dirname}" && cp -r node_modules/${path.dirname(file)}/* ${distDir}/libs/${dirname}`
cp.exec(cmd)
}
})
cb()
})
/**
* Copy static files (flags, payments images, etc) to dist directory
*/
gulp.task('copy-images', () => {
return gulp
.src(`${srcDir}/img/**/*`)
.pipe(gulp.dest(`${distDir}/img`))
})
/**
* Copy static files (demo images, etc) to demo directory
*/
gulp.task('copy-static', () => {
return gulp
.src(`${srcDir}/static/**/*`)
.pipe(gulp.dest(`${demoDir}/static`))
})
/**
* Copy Tabler dist files to demo directory
*/
gulp.task('copy-dist', () => {
return gulp
.src(`${distDir}/**/*`)
.pipe(gulp.dest(`${demoDir}/dist/`))
})
/**
* Add banner to build JS and CSS files
*/
gulp.task('add-banner', () => {
return gulp.src(`${distDir}/{css,js}/**/*.{js,css}`)
.pipe(header(getBanner()))
.pipe(replace(/^([\s\S]+)(@charset "UTF-8";)\n?/, '$2\n$1'))
.pipe(gulp.dest(`${distDir}`))
})
gulp.task('clean', gulp.series('clean-dirs'))
gulp.task('start', gulp.series('clean', 'sass', 'js', gulp.parallel('js-demo', 'js-demo-theme'), 'mjs', 'build-eleventy', gulp.parallel('watch-eleventy', 'watch', 'browser-sync')))
gulp.task('build-core', gulp.series('build-on', 'clean', 'sass', 'css-rtl', 'css-minify', 'js', gulp.parallel('js-demo', 'js-demo-theme'), 'mjs', 'copy-images', 'copy-libs', 'add-banner'))
gulp.task('build-demo', gulp.series('build-on', 'build-eleventy', 'copy-static', 'copy-dist', 'build-cleanup', 'build-purgecss'))
gulp.task('build', gulp.series('build-core', 'build-demo'))

View File

@@ -1,38 +1,275 @@
{
"private": true,
"name": "@tabler/core",
"version": "1.0.1",
"description": "Premium and Open Source dashboard template with responsive and high quality UI.",
"homepage": "https://tabler.io",
"scripts": {
"build": "turbo build",
"dev": "turbo dev",
"clean": "turbo clean",
"bundlewatch": "turbo bundlewatch",
"dev": "pnpm run start",
"start": "gulp start",
"build": "gulp build",
"build-docs": "mkdir public && touch public/index.html && echo 'ok'",
"preview": "gulp build --preview",
"svg-optimize": "svgo -f svg/brand --pretty",
"unused-files": "node .build/unused-files.js",
"version": "changeset version",
"publish": "changeset publish",
"reformat-mdx": "node build/reformat-mdx.mjs"
"svg-icons": "node .build/import-icons.js",
"bundlewatch": "bundlewatch",
"storybook": "start-storybook -p 6006",
"changelog": "node .build/changelog.js",
"icons": "git checkout dev && BRANCH_NAME=\"dev-tabler-icons-`pnpm info @tabler/icons version`\" && git branch $BRANCH_NAME && git checkout $BRANCH_NAME && ncu -u @tabler/icons && pnpm install && pnpm run svg-icons && git add . && git commit -am \"update icons to v`pnpm info @tabler/icons version`\" && git push origin $BRANCH_NAME && git checkout dev",
"download-images": "node .build/download-images.js",
"optimize-images": "for i in ./src/static/photos/*.jpg; do convert \"$i\" -quality 80% \"${i%.jpg}.jpg\"; done",
"format:check": "prettier --check src/**/*.{js,scss} --cache",
"format:write": "prettier --write src/**/*.{js,scss} --cache",
"illustrations": "node .build/import-illustrations.js",
"build:html": "eleventy",
"watch:html": "eleventy --watch --incremental",
"zip": "mkdir -p packages-zip && zip -r packages-zip/tabler-$(node -p \"require('./package.json').version\").zip demo/*"
},
"repository": {
"type": "git",
"url": "git+https://github.com/tabler/tabler.git"
},
"keywords": [
"css",
"sass",
"mobile-first",
"responsive",
"front-end",
"framework",
"web"
],
"author": "codecalm",
"license": "MIT",
"bugs": {
"url": "https://github.com/tabler/tabler/issues"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/codecalm"
},
"engines": {
"node": ">=20"
},
"files": [
"docs/**/*",
"dist/**/*",
"src/js/**/*.{js,map}",
"src/img/**/*.{svg}",
"src/scss/**/*.scss"
],
"style": "dist/css/tabler.css",
"sass": "src/scss/tabler.scss",
"unpkg": "dist/js/tabler.min.js",
"umd:main": "dist/js/tabler.min.js",
"module": "dist/js/tabler.esm.js",
"main": "dist/js/tabler.js",
"bundlewatch": {
"files": [
{
"path": "./dist/css/tabler.css",
"maxSize": "75 kB"
},
{
"path": "./dist/css/tabler.min.css",
"maxSize": "70 kB"
},
{
"path": "./dist/css/tabler.rtl.css",
"maxSize": "75 kB"
},
{
"path": "./dist/css/tabler.rtl.min.css",
"maxSize": "70 kB"
},
{
"path": "./dist/css/tabler-flags.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-flags.min.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-payments.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-payments.min.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-socials.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-socials.min.css",
"maxSize": "2 kB"
},
{
"path": "./dist/css/tabler-vendors.css",
"maxSize": "7.5 kB"
},
{
"path": "./dist/css/tabler-vendors.min.css",
"maxSize": "6.5 kB"
},
{
"path": "./dist/js/tabler.js",
"maxSize": "60 kB"
},
{
"path": "./dist/js/tabler.min.js",
"maxSize": "45 kB"
},
{
"path": "./dist/js/tabler.esm.js",
"maxSize": "60 kB"
},
{
"path": "./dist/js/tabler.esm.min.js",
"maxSize": "45 kB"
}
]
},
"packageManager": "pnpm@9.15.4",
"devDependencies": {
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.2",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-replace": "^6.0.2",
"autoprefixer": "^10.4.20",
"bundlewatch": "^0.4.0",
"cross-env": "^7.0.3",
"nodemon": "^3.1.9",
"postcss": "^8.5.1",
"postcss-cli": "^11.0.0",
"rollup": "4.34.0",
"rtlcss": "^4.3.0",
"sass": "1.71.0",
"clean-css-cli": "^5.6.3",
"terser": "^5.37.0",
"@11ty/eleventy": "^3.0.0",
"@babel/core": "^7.26.7",
"@babel/preset-env": "^7.26.7",
"@changesets/changelog-github": "^0.5.0",
"@changesets/cli": "^2.27.12",
"glob": "^11.0.1",
"@rollup/plugin-commonjs": "^24.1.0",
"@rollup/plugin-node-resolve": "^15.3.1",
"@rollup/plugin-replace": "^5.0.7",
"@rollup/stream": "^2.0.0",
"apexcharts": "^4.4.0",
"autoprefixer": "^10.4.20",
"autosize": "^6.0.1",
"browser-sync": "^2.29.3",
"bundlewatch": "^0.4.0",
"choices.js": "^11.0.3",
"countup.js": "^2.8.0",
"cross-spawn": "^7.0.6",
"dropzone": "^6.0.0-beta.2",
"flatpickr": "^4.6.13",
"fslightbox": "^3.4.2",
"glob": "^10.4.5",
"gulp": "^4.0.2",
"gulp-clean": "^0.4.0",
"gulp-clean-css": "^4.3.0",
"gulp-debug": "^4.0.0",
"gulp-header": "^2.0.9",
"gulp-postcss": "^9.1.0",
"gulp-purgecss": "^5.0.0",
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.1.4",
"gulp-rtlcss": "^2.0.0",
"gulp-sass": "^5.1.0",
"gulp-terser": "^2.1.0",
"html-minifier": "^4.0.0",
"imageoptim-cli": "^3.1.9",
"imask": "^7.6.1",
"js-beautify": "^1.15.1",
"prettier": "^3.4.2",
"turbo": "^2.4.0"
"jsvectormap": "^1.6.0",
"list.js": "^2.3.1",
"litepicker": "^2.0.12",
"nouislider": "^15.8.1",
"plyr": "^3.7.8",
"postcss": "^8.5.1",
"prettier": "^2.8.8",
"request": "^2.88.2",
"rollup": "2.79.2",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-cleanup": "^3.2.1",
"sass": "1.71.0",
"star-rating.js": "^4.3.1",
"tinymce": "^7.6.0",
"tom-select": "^2.4.1",
"typed.js": "^2.1.0",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"yargs": "^17.7.2"
},
"dependencies": {
"@popperjs/core": "^2.11.8",
"@tabler/icons": "^3.29.0",
"bootstrap": "5.3.3"
},
"peerDependencies": {
"@melloware/coloris": "^0.19.1",
"apexcharts": "^3.40.0",
"autosize": "^6.0.1",
"choices.js": "^10.2.0",
"countup.js": "^2.6.2",
"dropzone": "^6.0.0-beta.2",
"flatpickr": "^4.6.13",
"fslightbox": "^3.4.1",
"imask": "^6.6.1",
"jsvectormap": "^1.5.3",
"list.js": "^2.3.1",
"litepicker": "^2.0.12",
"nouislider": "^15.7.0",
"plyr": "^3.7.8",
"star-rating.js": "^4.3.0",
"tinymce": "^6.4.2 || ^7.0.0",
"tom-select": "^2.2.2",
"typed.js": "^2.1.0"
},
"peerDependenciesMeta": {
"@melloware/coloris": {
"optional": true
},
"apexcharts": {
"optional": true
},
"autosize": {
"optional": true
},
"choices.js": {
"optional": true
},
"countup.js": {
"optional": true
},
"dropzone": {
"optional": true
},
"flatpickr": {
"optional": true
},
"fslightbox": {
"optional": true
},
"imask": {
"optional": true
},
"jsvectormap": {
"optional": true
},
"list.js": {
"optional": true
},
"litepicker": {
"optional": true
},
"nouislider": {
"optional": true
},
"plyr": {
"optional": true
},
"tinymce": {
"optional": true
},
"tom-select": {
"optional": true
},
"star-rating.js": {
"optional": true
}
},
"directories": {
"doc": "docs"
}
}

5202
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +0,0 @@
packages:
- core
- preview
- 'shared/*'

View File

@@ -1,21 +0,0 @@
import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const pkgJson = path.join(__dirname, '../package.json')
const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
const year = new Date().getFullYear()
function getBanner(pluginFilename) {
return `/*!
* Tabler${pluginFilename ? ` ${pluginFilename}` : ''} v${pkg.version} (${pkg.homepage})
* Copyright 2018-${year} The Tabler Authors
* Copyright 2018-${year} codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/`
}
export default getBanner

View File

@@ -1,59 +0,0 @@
// #!/usr/bin/env node
// import { readFileSync, createWriteStream, existsSync, writeFileSync } from 'node:fs'
// import { join, dirname } from 'node:path'
// import request, { head } from 'request'
// import { fileURLToPath } from 'node:url';
// const __dirname = dirname(fileURLToPath(import.meta.url))
// const filePath = join(__dirname, '..', 'preview', 'pages', '_data', 'photos.json')
// const photos = JSON.parse(readFileSync(filePath, 'utf8'))
// const urlTitle = (str) => {
// str = str
// .toLowerCase()
// .replaceAll('&', 'and')
// .replace(/[^[a-z0-9-]/g, '-')
// .replace(/-+/g, '-')
// return str
// }
// const download = function (uri, filename, callback, error) {
// head(uri, function (err, res, body) {
// request(uri).pipe(createWriteStream(filename))
// .on('close', callback)
// .on('error', error)
// })
// }
// async function downloadPhotos() {
// for (const key in photos) {
// const photo = photos[key]
// let filename, i = 1;
// do {
// filename = `${urlTitle(photo['title'])}${i > 1 ? `-${i}` : ''}.jpg`
// i++
// } while (existsSync(join(__dirname, `../preview/static/photos/${filename}`)))
// await new Promise((resolve, reject) => {
// download(photo['path'], join(__dirname, `../preview/static/photos/${filename}`), function () {
// resolve()
// }, function () {
// reject()
// });
// })
// photos[key]['file'] = filename
// photos[key]['horizontal'] = photo['width'] > photo['height']
// }
// writeFileSync(filePath, JSON.stringify(photos))
// }
// downloadPhotos();

View File

@@ -1,38 +0,0 @@
#!/usr/bin/env node
import { readFileSync, writeFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url))
const iconsTags = JSON.parse(readFileSync(join(__dirname, '../node_modules/@tabler/icons/icons.json'), 'utf8'));
const { version } = JSON.parse(readFileSync(join(__dirname, '../node_modules/@tabler/icons/package.json'), 'utf8'))
const prepareSvgFile = (svg) => {
return svg.replace(/\n/g, '').replace(/>\s+</g, '><').replace(/\s+/g, ' ')
}
let svgList = {}
for (let iconName in iconsTags) {
let iconData = iconsTags[iconName]
svgList[iconName] = {
name: iconName,
svg: {
outline: iconData.styles.outline ? prepareSvgFile(readFileSync(join(__dirname, `../node_modules/@tabler/icons/icons/outline/${iconName}.svg`), 'utf8')) : null,
filled: iconData.styles.filled ? prepareSvgFile(readFileSync(join(__dirname, `../node_modules/@tabler/icons/icons/filled/${iconName}.svg`), 'utf8')) : null,
}
}
}
writeFileSync(
join(__dirname, `../pages/_data/icons-info.json`),
JSON.stringify({
version,
count: Object.values(svgList).reduce((acc, icon) => {
return acc + (icon.svg.outline ? 1 : 0) + (icon.svg.filled ? 1 : 0)
}, 0)
})
)
writeFileSync(join(__dirname, `../pages/_data/icons.json`), JSON.stringify(svgList))

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env node
import { writeFileSync } from 'node:fs';
import { join, basename, dirname } from 'node:path';
import { sync } from 'glob';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url))
const illustrations = sync(join(__dirname, `../static/illustrations/light/*.png`))
.map((file) => {
return basename(file, '.png')
})
writeFileSync(
join(__dirname, `../pages/_data/illustrations.json`),
JSON.stringify(illustrations)
)

View File

@@ -1,42 +0,0 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { babel } from '@rollup/plugin-babel'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import replace from '@rollup/plugin-replace'
import banner from '@repo/banner'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const external = []
const plugins = [
babel({
exclude: 'node_modules/**',
babelHelpers: 'bundled'
})
]
plugins.push(
replace({
'process.env.NODE_ENV': '"production"',
preventAssignment: true
}),
nodeResolve()
)
const rollupConfig = {
input: [
path.resolve(__dirname, `../js/demo.js`),
path.resolve(__dirname, `../js/demo-theme.js`)
],
output: {
name: 'demo',
banner: banner('Demo'),
dir: path.resolve(__dirname, `../dist/preview/js`),
format: 'esm',
generatedCode: 'es2015'
},
external,
plugins
}
export default rollupConfig

View File

@@ -1,31 +0,0 @@
#!/usr/bin/env node
import { sync } from 'glob';
import { readFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url))
const srcDir = join(__dirname, '..')
let foundFiles = []
sync(`${srcDir}/pages/**/*.{html,md}`).forEach((file) => {
let fileContent = readFileSync(file)
fileContent.toString().replace(/\{% include(_cached)? "([a-z0-9\/_-]+\.html)"/g, (f, c, filename) => {
filename = `${srcDir}/pages/_includes/${filename}`
if (!foundFiles.includes(filename)) {
foundFiles.push(filename)
}
})
})
let includeFiles = sync(`${srcDir}/pages/_includes/**/*.html`)
includeFiles.forEach((file) => {
if (!foundFiles.includes(file)) {
console.log('file', file)
}
})

View File

@@ -1,59 +0,0 @@
{
"name": "preview",
"private": true,
"scripts": {
"build": "pnpm run clean && pnpm run css && pnpm run js && pnpm run html",
"dev": "pnpm run clean && pnpm run watch",
"watch": "pnpm run watch-html & pnpm run watch-css & pnpm run watch-js",
"watch-html": "eleventy --serve --port=3000",
"watch-js": "nodemon --watch js/ --ext js --exec 'pnpm run js'",
"watch-css": "nodemon --watch scss/ --ext scss --exec 'pnpm run css'",
"css": "pnpm run css-compile && pnpm run css-prefix && pnpm run css-minify",
"css-compile": "sass scss/:dist/preview/css/ --no-source-map --load-path=node_modules",
"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-compile && pnpm run js-minify",
"js-compile": "rollup --config build/rollup.config.mjs --sourcemap",
"js-minify": "pnpm run js-minify-demo && pnpm run js-minify-theme",
"js-minify-demo": "terser --compress passes=2 --mangle --comments '/^!/' --source-map 'content=dist/preview/js/demo.js.map,includeSources,url=demo.min.js.map' --output dist/preview/js/demo.min.js dist/preview/js/demo.js",
"js-minify-theme": "terser --compress passes=2 --mangle --comments '/^!/' --source-map 'content=dist/preview/js/demo-theme.js.map,includeSources,url=demo-theme.min.js.map' --output dist/preview/js/demo-theme.min.js dist/preview/js/demo-theme.js",
"clean": "rm -rf dist demo",
"html": "eleventy",
"svg-optimize": "svgo -f svg/brand --pretty",
"unused-files": "node build/unused-files.mjs",
"download-images": "node build/download-images.mjs",
"optimize-images": "for i in ./src/static/photos/*.jpg; do convert \"$i\" -quality 80% \"${i%.jpg}.jpg\"; done",
"svg-icons": "node build/import-icons.mjs",
"import-illustrations": "node build/import-illustrations.mjs",
"import-icons": "git checkout dev && BRANCH_NAME=\"dev-tabler-icons-`pnpm info @tabler/icons version`\" && git branch $BRANCH_NAME && git checkout $BRANCH_NAME && ncu -u @tabler/icons && pnpm install && pnpm run svg-icons && git add . && git commit -am \"update icons to v`pnpm info @tabler/icons version`\" && git push origin $BRANCH_NAME && git checkout dev",
"zip": "mkdir -p packages-zip && zip -r packages-zip/tabler-$(node -p \"require('./package.json').version\").zip demo/*"
},
"dependencies": {
"@tabler/icons": "^3.29.0",
"@melloware/coloris": "^0.19.1",
"apexcharts": "^4.4.0",
"@tabler/core": "workspace:*",
"star-rating.js": "^4.3.1",
"tinymce": "^7.6.0",
"tom-select": "^2.4.1",
"typed.js": "^2.1.0",
"imask": "^7.6.1",
"jsvectormap": "^1.6.0",
"list.js": "^2.3.1",
"litepicker": "^2.0.12",
"nouislider": "^15.8.1",
"plyr": "^3.7.8",
"dropzone": "^6.0.0-beta.2",
"flatpickr": "^4.6.13",
"fslightbox": "^3.4.2",
"choices.js": "^11.0.3",
"countup.js": "^2.8.0",
"autosize": "^6.0.1"
},
"devDependencies": {
"request": "^2.88.2",
"imageoptim-cli": "^3.1.9",
"@11ty/eleventy": "^3.0.0",
"@repo/banner": "workspace:*"
}
}

View File

@@ -1,153 +0,0 @@
---
layout: default
permalink: playground.html
---
<div class="container-xl">
<div class="page-header d-print-none mb-4">
<div class="row align-items-center">
<div class="col">
<div class="page-pretitle"></div>
<div class="d-flex align-items-center">
<img
src="https://hebbkx1anhila5yf.public.blob.vercel-storage.com/chips-b5dF2YPuqsOD3mhXWZ7cLs6YW8B5QM.png"
alt="Tabler Logo"
class="h-8 me-2"
/>
<h2 class="page-title">tabler</h2>
</div>
</div>
</div>
</div>
<div class="row row-deck row-cards">
<div class="col-sm-6 col-lg-6">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="subheader">Sales</div>
<div class="ms-auto lh-1">
<div class="text-success d-inline-flex align-items-center lh-1">
1%{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon ms-1"
width="24"
height="24"
viewBox="0 0 24 24"
strokeWidth="2"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 17l6 -6l4 4l8 -8" />
<path d="M14 7l7 0l0 7" />
</svg>
</div>
</div>
</div>
<div class="d-flex align-items-baseline">
<div class="h1 mb-0 me-2">132</div>
<div class="me-auto">
<span class="text-muted">12 waiting payments</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-6">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="subheader">Orders</div>
<div class="ms-auto lh-1">
<div class="text-muted d-inline-flex align-items-center lh-1">
0% <span class="ms-1"></span>
</div>
</div>
</div>
<div class="d-flex align-items-baseline">
<div class="h1 mb-0 me-2">78</div>
<div class="me-auto">
<span class="text-muted">32 shipped</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-6">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="subheader">Shares</div>
<div class="ms-auto lh-1">
<div class="text-danger d-inline-flex align-items-center lh-1">
4%{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon ms-1"
width="24"
height="24"
viewBox="0 0 24 24"
strokeWidth="2"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 7l6 6l4 -4l8 8" />
<path d="M14 17l7 0l0 -7" />
</svg>
</div>
</div>
</div>
<div class="d-flex align-items-baseline">
<div class="h1 mb-0 me-2">623</div>
<div class="me-auto">
<span class="text-muted">16 today</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-lg-6">
<div class="card">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="subheader">Likes</div>
<div class="ms-auto lh-1">
<div class="text-success d-inline-flex align-items-center lh-1">
8%{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon ms-1"
width="24"
height="24"
viewBox="0 0 24 24"
strokeWidth="2"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M3 17l6 -6l4 4l8 -8" />
<path d="M14 7l7 0l0 7" />
</svg>
</div>
</div>
</div>
<div class="d-flex align-items-baseline">
<div class="h1 mb-0 me-2">132</div>
<div class="me-auto">
<span class="text-muted">21 today</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,21 +0,0 @@
import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const pkgJson = path.join(__dirname, 'package.json')
const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8'))
const year = new Date().getFullYear()
function getBanner(pluginFilename) {
return `/*!
* Tabler${pluginFilename ? ` ${pluginFilename}` : ''} v${pkg.version} (${pkg.homepage})
* Copyright 2018-${year} The Tabler Authors
* Copyright 2018-${year} codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/`
}
export default getBanner

View File

@@ -1,10 +0,0 @@
{
"name": "@repo/banner",
"version": "1.0.0",
"homepage": "https://tabler.io",
"exports": {
".": {
"default": "./index.mjs"
}
}
}

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 507 B

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 877 B

After

Width:  |  Height:  |  Size: 877 B

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 611 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 584 B

After

Width:  |  Height:  |  Size: 584 B

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 572 B

After

Width:  |  Height:  |  Size: 572 B

View File

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 992 B

View File

Before

Width:  |  Height:  |  Size: 970 B

After

Width:  |  Height:  |  Size: 970 B

View File

Before

Width:  |  Height:  |  Size: 842 B

After

Width:  |  Height:  |  Size: 842 B

View File

Before

Width:  |  Height:  |  Size: 384 B

After

Width:  |  Height:  |  Size: 384 B

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 711 B

After

Width:  |  Height:  |  Size: 711 B

View File

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 611 B

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 426 B

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 577 B

After

Width:  |  Height:  |  Size: 577 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 407 B

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 634 B

After

Width:  |  Height:  |  Size: 634 B

View File

Before

Width:  |  Height:  |  Size: 633 B

After

Width:  |  Height:  |  Size: 633 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 757 B

After

Width:  |  Height:  |  Size: 757 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 849 B

After

Width:  |  Height:  |  Size: 849 B

View File

Before

Width:  |  Height:  |  Size: 633 B

After

Width:  |  Height:  |  Size: 633 B

View File

Before

Width:  |  Height:  |  Size: 437 B

After

Width:  |  Height:  |  Size: 437 B

View File

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 620 B

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 542 B

After

Width:  |  Height:  |  Size: 542 B

View File

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 532 B

View File

Before

Width:  |  Height:  |  Size: 950 B

After

Width:  |  Height:  |  Size: 950 B

View File

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 611 B

View File

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 565 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 817 B

After

Width:  |  Height:  |  Size: 817 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 666 B

After

Width:  |  Height:  |  Size: 666 B

Some files were not shown because too many files have changed in this diff Show More