mirror of
https://github.com/tabler/tabler.git
synced 2026-01-25 12:26:30 +00:00
Compare commits
32 Commits
dev-layout
...
refactor/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38ab83908f | ||
|
|
6c2c233d0f | ||
|
|
82e3c39585 | ||
|
|
eac69eb35b | ||
|
|
684f40e7c1 | ||
|
|
f6414b3c94 | ||
|
|
c3e6aa1bd3 | ||
|
|
8e3cddb70f | ||
|
|
857988dd44 | ||
|
|
a24d5cab13 | ||
|
|
0c654c61f0 | ||
|
|
8e73f57140 | ||
|
|
f0fb9c66c0 | ||
|
|
29d9d4b5df | ||
|
|
84c31d1383 | ||
|
|
41fd82b388 | ||
|
|
abac36c580 | ||
|
|
301e77898c | ||
|
|
a14425792b | ||
|
|
48dbd1ed1b | ||
|
|
ee8875deb6 | ||
|
|
c0a93b8611 | ||
|
|
42081245b4 | ||
|
|
d56e1a2bac | ||
|
|
c6e8879bb6 | ||
|
|
a811fdb662 | ||
|
|
63a35a849c | ||
|
|
94e1a95ffb | ||
|
|
83ec6f8bcc | ||
|
|
e3d86c519b | ||
|
|
f9d6076014 | ||
|
|
f264470d8f |
@@ -1,6 +1,10 @@
|
||||
>= 1%
|
||||
last 2 versions
|
||||
Firefox ESR
|
||||
>= 0.5%
|
||||
last 2 major versions
|
||||
not dead
|
||||
safari >= 15.4
|
||||
iOS >= 15.4
|
||||
Chrome >= 120
|
||||
Firefox >= 121
|
||||
iOS >= 15.6
|
||||
Safari >= 15.6
|
||||
not Explorer <= 11
|
||||
Samsung >= 23
|
||||
not kaios <= 2.5
|
||||
@@ -1,63 +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 * as prettier from "prettier";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const docs = sync(join(__dirname, '..', 'docs', '**', '*.md'))
|
||||
|
||||
async function formatHTML(htmlString) {
|
||||
try {
|
||||
const formattedHtml = await prettier.format(htmlString, {
|
||||
parser: "html",
|
||||
printWidth: 100,
|
||||
});
|
||||
return formattedHtml;
|
||||
} catch (error) {
|
||||
console.error("Error formatting HTML:", error);
|
||||
return htmlString; // Return original in case of an error
|
||||
}
|
||||
}
|
||||
|
||||
async function replaceAsync(str, regex, asyncFn) {
|
||||
const matches = [...str.matchAll(regex)];
|
||||
|
||||
const replacements = await Promise.all(
|
||||
matches.map(async (match) => asyncFn(...match))
|
||||
);
|
||||
|
||||
let result = str;
|
||||
matches.forEach((match, i) => {
|
||||
result = result.replace(match[0], replacements[i]);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
for (const file of docs) {
|
||||
const oldContent = readFileSync(file, 'utf8')
|
||||
|
||||
// get codeblocks from markdown
|
||||
const content = await replaceAsync(oldContent, /(```([a-z0-9]+).*?\n)(.*?)(```)/gs, async (m, m1, m2, m3, m4) => {
|
||||
if (m2 === 'html') {
|
||||
m3 = await formatHTML(m3);
|
||||
|
||||
// remove empty lines
|
||||
m3 = m3.replace(/^\s*[\r\n]/gm, '');
|
||||
|
||||
return m1 + m3.trim() + "\n" + m4;
|
||||
}
|
||||
return m.trim();
|
||||
})
|
||||
|
||||
if (content !== oldContent) {
|
||||
writeFileSync(file, content, 'utf8')
|
||||
console.log(`Reformatted ${file}`)
|
||||
}
|
||||
}
|
||||
79
.build/reformat-mdx.ts
Normal file
79
.build/reformat-mdx.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { readFileSync, writeFileSync } from 'node:fs'
|
||||
import { join, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { sync } from 'glob'
|
||||
import * as prettier from 'prettier'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const docs: string[] = sync(join(__dirname, '..', 'docs', '**', '*.md'))
|
||||
|
||||
async function formatHTML(htmlString: string): Promise<string> {
|
||||
try {
|
||||
const formattedHtml = await prettier.format(htmlString, {
|
||||
parser: 'html',
|
||||
printWidth: 100,
|
||||
})
|
||||
return formattedHtml
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
console.error('Error formatting HTML:', errorMessage)
|
||||
return htmlString // Return original in case of an error
|
||||
}
|
||||
}
|
||||
|
||||
async function replaceAsync(
|
||||
str: string,
|
||||
regex: RegExp,
|
||||
asyncFn: (...args: string[]) => Promise<string>
|
||||
): Promise<string> {
|
||||
const matches = [...str.matchAll(regex)]
|
||||
|
||||
const replacements = await Promise.all(
|
||||
matches.map(async (match: RegExpMatchArray) => asyncFn(...match))
|
||||
)
|
||||
|
||||
let result = str
|
||||
matches.forEach((match: RegExpMatchArray, i: number) => {
|
||||
result = result.replace(match[0], replacements[i])
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
async function processFiles(): Promise<void> {
|
||||
for (const file of docs) {
|
||||
const oldContent = readFileSync(file, 'utf8')
|
||||
|
||||
// get codeblocks from markdown
|
||||
const content = await replaceAsync(
|
||||
oldContent,
|
||||
/(```([a-z0-9]+).*?\n)(.*?)(```)/gs,
|
||||
async (m: string, m1: string, m2: string, m3: string, m4: string) => {
|
||||
if (m2 === 'html') {
|
||||
let formattedHtml = await formatHTML(m3)
|
||||
|
||||
// remove empty lines
|
||||
formattedHtml = formattedHtml.replace(/^\s*[\r\n]/gm, '')
|
||||
|
||||
return m1 + formattedHtml.trim() + '\n' + m4
|
||||
}
|
||||
return m.trim()
|
||||
}
|
||||
)
|
||||
|
||||
if (content !== oldContent) {
|
||||
writeFileSync(file, content, 'utf8')
|
||||
console.log(`Reformatted ${file}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processFiles().catch((error) => {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
console.error('Error processing files:', errorMessage)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
76
.build/vite.config.helper.ts
Normal file
76
.build/vite.config.helper.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { defineConfig, type UserConfig } from 'vite'
|
||||
|
||||
interface CreateViteConfigOptions {
|
||||
entry: string
|
||||
name?: string
|
||||
fileName: string | ((format: string) => string)
|
||||
formats: ('es' | 'umd' | 'iife' | 'cjs')[]
|
||||
outDir: string
|
||||
banner?: string
|
||||
minify?: boolean | 'esbuild'
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Vite configuration for building libraries
|
||||
*/
|
||||
export function createViteConfig({
|
||||
entry,
|
||||
name,
|
||||
fileName,
|
||||
formats,
|
||||
outDir,
|
||||
banner,
|
||||
minify = false
|
||||
}: CreateViteConfigOptions): UserConfig {
|
||||
const rollupOutput: {
|
||||
generatedCode: {
|
||||
constBindings: boolean
|
||||
}
|
||||
banner?: string
|
||||
} = {
|
||||
generatedCode: {
|
||||
constBindings: true
|
||||
}
|
||||
}
|
||||
|
||||
// Add banner if provided
|
||||
if (banner) {
|
||||
rollupOutput.banner = banner
|
||||
}
|
||||
|
||||
const config: UserConfig = {
|
||||
build: {
|
||||
lib: {
|
||||
entry: path.resolve(entry),
|
||||
name: name,
|
||||
fileName: typeof fileName === 'function' ? fileName : () => fileName,
|
||||
formats: formats
|
||||
},
|
||||
outDir: path.resolve(outDir),
|
||||
emptyOutDir: false,
|
||||
sourcemap: true,
|
||||
rollupOptions: {
|
||||
output: rollupOutput
|
||||
},
|
||||
target: 'es2015',
|
||||
minify: minify
|
||||
},
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"'
|
||||
},
|
||||
esbuild: {
|
||||
target: 'es2015',
|
||||
tsconfigRaw: {
|
||||
compilerOptions: {
|
||||
module: 'ES2020',
|
||||
target: 'ES2015'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return defineConfig(config)
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import AdmZip from 'adm-zip';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
// Get __dirname in ESM
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const pkg = JSON.parse(
|
||||
readFileSync(path.join(__dirname, '../core', 'package.json'), 'utf8')
|
||||
)
|
||||
|
||||
// Create zip instance and add folder
|
||||
const zip = new AdmZip();
|
||||
zip.addLocalFolder(path.join(__dirname, '../preview/dist'), 'dashboard');
|
||||
|
||||
zip.addLocalFile(path.join(__dirname, '../preview/static', 'og.png'), '.', 'preview.png');
|
||||
|
||||
zip.addFile("documentation.url", Buffer.from("[InternetShortcut]\nURL = https://tabler.io/docs"));
|
||||
|
||||
|
||||
// Folder to zip and output path
|
||||
const outputZipPath = path.join(__dirname, '../packages-zip', `tabler-${pkg.version}.zip`);
|
||||
|
||||
// Write the zip file
|
||||
zip.writeZip(outputZipPath);
|
||||
|
||||
console.log(`Zipped folder to ${outputZipPath}`);
|
||||
46
.build/zip-package.ts
Normal file
46
.build/zip-package.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import AdmZip from 'adm-zip'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { readFileSync } from 'node:fs'
|
||||
|
||||
// Get __dirname in ESM
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
interface PackageJson {
|
||||
version: string
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
const pkg: PackageJson = JSON.parse(
|
||||
readFileSync(path.join(__dirname, '../core', 'package.json'), 'utf8')
|
||||
)
|
||||
|
||||
// Create zip instance and add folder
|
||||
const zip = new AdmZip()
|
||||
zip.addLocalFolder(path.join(__dirname, '../preview/dist'), 'dashboard')
|
||||
|
||||
zip.addLocalFile(
|
||||
path.join(__dirname, '../preview/static', 'og.png'),
|
||||
'.',
|
||||
'preview.png'
|
||||
)
|
||||
|
||||
zip.addFile(
|
||||
'documentation.url',
|
||||
Buffer.from('[InternetShortcut]\nURL = https://tabler.io/docs')
|
||||
)
|
||||
|
||||
// Folder to zip and output path
|
||||
const outputZipPath = path.join(
|
||||
__dirname,
|
||||
'../packages-zip',
|
||||
`tabler-${pkg.version}.zip`
|
||||
)
|
||||
|
||||
// Write the zip file
|
||||
zip.writeZip(outputZipPath)
|
||||
|
||||
console.log(`Zipped folder to ${outputZipPath}`)
|
||||
|
||||
5
.changeset/docs-css-variables-font-sizes.md
Normal file
5
.changeset/docs-css-variables-font-sizes.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tabler/docs": patch
|
||||
---
|
||||
|
||||
Updated documentation to explain font sizing and system color CSS variables (`--tblr-primary-rgb`, `--tblr-secondary`, `--tblr-tertiary`, `--tblr-link-color`, `--tblr-gray-*`).
|
||||
6
.changeset/migrate-rgba-to-color-mix.md
Normal file
6
.changeset/migrate-rgba-to-color-mix.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tabler/core": patch
|
||||
---
|
||||
|
||||
Migrated `rgba()` functions to modern CSS color functions (`color-mix()` and `color-transparent()`) for better browser support and cleaner code. Replaced `rgba(var(--#{$prefix}*-rgb), ...)` with `color-mix(in srgb, var(--#{$prefix}*) ..., transparent)`, static percentage `color-mix()` with `color-transparent()`, and `rgba($variable, ...)` with `color-transparent($variable, ...)`.
|
||||
|
||||
8
.changeset/migrate-rollup-to-vite.md
Normal file
8
.changeset/migrate-rollup-to-vite.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
"@tabler/preview": minor
|
||||
"@tabler/docs": minor
|
||||
---
|
||||
|
||||
Migrated build system from Rollup to Vite across all packages. Replaced `rollup.config.mjs` with `vite.config.mjs` and updated build scripts to use `vite build` instead of `rollup`. Build outputs remain identical (UMD and ESM formats) with no breaking changes for end users.
|
||||
|
||||
6
.changeset/scss-layers-other-bundles.md
Normal file
6
.changeset/scss-layers-other-bundles.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tabler/core": patch
|
||||
---
|
||||
|
||||
Updated `tabler-vendors.css`, `tabler-themes.css`, and `tabler-marketing.css` to use CSS Cascade Layers (`@layer`) for predictable cascade ordering.
|
||||
|
||||
7
.changeset/silly-crabs-walk.md
Normal file
7
.changeset/silly-crabs-walk.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@tabler/core": patch
|
||||
"@tabler/preview": patch
|
||||
---
|
||||
|
||||
Added Driver.js library integration and Tour demo page for interactive product tours and onboarding guides.
|
||||
|
||||
6
.changeset/update-icons-3.36.1.md
Normal file
6
.changeset/update-icons-3.36.1.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tabler/preview": patch
|
||||
---
|
||||
|
||||
Updated `@tabler/icons` to v3.36.1.
|
||||
|
||||
7
.changeset/upgrade-apexcharts.md
Normal file
7
.changeset/upgrade-apexcharts.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
"@tabler/preview": minor
|
||||
---
|
||||
|
||||
Upgraded `apexcharts` from `3.54.1` to `5.3.6` and added CSS variables (`--chart-{id}-color-{index}`) for dynamic chart colors to fix compatibility with the new version.
|
||||
|
||||
38
.cursor/rules/branch-naming.mdc
Normal file
38
.cursor/rules/branch-naming.mdc
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
description: Git Branch Naming Rules
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
## Branch naming
|
||||
|
||||
- Use lowercase branch names.
|
||||
- Use a type prefix and a short description in kebab-case.
|
||||
- Format: `<type>/<short-description>` or `<type>/<issue-id>-<short-description>`
|
||||
- Use `gh-123` as the issue id format (avoid `#` in branch names).
|
||||
|
||||
### Allowed types
|
||||
|
||||
- `feat` - new features
|
||||
- `fix` - bug fixes
|
||||
- `docs` - documentation changes
|
||||
- `chore` - maintenance / tooling
|
||||
- `refactor` - code refactoring (no behavior change)
|
||||
- `test` - tests only
|
||||
- `build` - build system changes
|
||||
- `ci` - CI changes
|
||||
- `perf` - performance improvements
|
||||
- `style` - formatting / lint-only changes
|
||||
- `revert` - reverting prior changes
|
||||
|
||||
### Examples
|
||||
|
||||
- `feat/gh-123-add-stepper-component`
|
||||
- `fix/markdown-table-overflow`
|
||||
- `docs/gh-45-update-contributing`
|
||||
- `chore/update-pnpm-lock`
|
||||
|
||||
### Notes
|
||||
|
||||
- Branch off `dev` by default (unless maintainers request otherwise).
|
||||
- Avoid spaces, uppercase letters, and special characters other than `/` and `-`.
|
||||
39
.cursor/rules/pull-request.mdc
Normal file
39
.cursor/rules/pull-request.mdc
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
description: Pull Request Title & Description Rules
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
## Pull request title
|
||||
|
||||
- Write PR titles in **English**.
|
||||
- Start the title with a **capital letter**.
|
||||
- Use **present tense** and keep it concise (ideally <= 72 chars).
|
||||
- Avoid a trailing period.
|
||||
|
||||
### Examples
|
||||
|
||||
- `Improve markdown table overflow handling`
|
||||
- `Clarify contributing branch naming`
|
||||
- `Add onboarding stepper page`
|
||||
|
||||
## Pull request description
|
||||
|
||||
- Write PR descriptions in **English**.
|
||||
- Focus on **why** the change is needed and what user-visible effect it has.
|
||||
- Keep it skimmable: bullets, short paragraphs, clear headings.
|
||||
|
||||
### Recommended template
|
||||
|
||||
```md
|
||||
## Summary
|
||||
- <1–3 bullets describing the change and why>
|
||||
|
||||
## Changes
|
||||
- <key implementation notes, non-obvious decisions>
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- If you changed SCSS or any package behavior, add a **changeset** describing it (one sentence, with backticks for code elements).
|
||||
- If a PR is WIP, mark it as draft and prefix the title with `WIP:` only while it is not ready for review.
|
||||
140
.cursor/rules/scss-layers.mdc
Normal file
140
.cursor/rules/scss-layers.mdc
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
## SCSS Cascade Layers Guidelines
|
||||
|
||||
Use CSS Cascade Layers (`@layer`) to make the cascade predictable across modules (reboot/layout/forms/components/helpers/utilities), without relying on import order or widespread `!important`.
|
||||
|
||||
### 0. Inventory: SCSS entrypoints → CSS bundles → consumers
|
||||
|
||||
This repo produces multiple CSS bundles from multiple SCSS entrypoints. Before moving rules into layers, keep this mapping handy so you can reason about bundle-level ordering and who consumes what.
|
||||
|
||||
#### `@tabler/core` (published bundles)
|
||||
|
||||
- **Build tool**: Sass CLI (not Vite) compiles `core/scss/` → `core/dist/css/` via `sass scss/:dist/css/`
|
||||
- **Entrypoints (non-partials)**:
|
||||
- `core/scss/tabler.scss` → `core/dist/css/tabler.css` (+ `tabler.min.css`, `tabler.rtl.css`, `tabler.rtl.min.css`)
|
||||
- **Consumers**:
|
||||
- `shared/includes/layout/css.html` (preview pages, mandatory styles)
|
||||
- `shared/layouts/docs/default.html` (docs site)
|
||||
- `core/package.json` exposes it via `style: dist/css/tabler.css` and `sass: scss/tabler.scss`
|
||||
- `core/scss/tabler-flags.scss` → `core/dist/css/tabler-flags.css` (+ `.min`, `.rtl`, `.rtl.min`)
|
||||
- `core/scss/tabler-socials.scss` → `core/dist/css/tabler-socials.css` (+ `.min`, `.rtl`, `.rtl.min`)
|
||||
- `core/scss/tabler-payments.scss` → `core/dist/css/tabler-payments.css` (+ `.min`, `.rtl`, `.rtl.min`)
|
||||
- `core/scss/tabler-vendors.scss` → `core/dist/css/tabler-vendors.css` (+ `.min`, `.rtl`, `.rtl.min`)
|
||||
- `core/scss/tabler-marketing.scss` → `core/dist/css/tabler-marketing.css` (+ `.min`, `.rtl`, `.rtl.min`)
|
||||
- `core/scss/tabler-themes.scss` → `core/dist/css/tabler-themes.css` (+ `.min`, `.rtl`, `.rtl.min`)
|
||||
- `core/scss/tabler-props.scss` → `core/dist/css/tabler-props.css` (+ `.min`, `.rtl`, `.rtl.min`)
|
||||
- **Note**: currently not included by default layouts (it exists as a separate bundle and is covered by SRI generation).
|
||||
- **Plugin consumers**:
|
||||
- Preview pages: `shared/includes/layout/css.html` loads `tabler-{{ plugin }}` for each plugin in `shared/data/site.json` (`cssPlugins`).
|
||||
- Docs site: `shared/layouts/docs/default.html` loads the same plugin list.
|
||||
- **Copying into static sites**:
|
||||
- `preview/eleventy.config.mjs` and `docs/eleventy.config.mjs` both `addPassthroughCopy({ "node_modules/@tabler/core/dist": "dist" })`, so core bundles are available at `/dist/css/...` in those sites.
|
||||
|
||||
#### `@tabler/preview` (preview-only bundle)
|
||||
|
||||
- **Build tool**: Sass CLI compiles `preview/scss/` → `preview/dist/preview/css/` via `sass scss/:dist/preview/css/`
|
||||
- **Entrypoints**:
|
||||
- `preview/scss/demo.scss` → `preview/dist/preview/css/demo.css` (+ `.min`)
|
||||
- **Consumer**: `shared/includes/layout/css.html` loads it as `/preview/css/demo...`
|
||||
|
||||
#### `@tabler/docs` (docs-only bundle)
|
||||
|
||||
- **Build tool**: Sass CLI compiles `docs/scss/` → `docs/dist/css/` via `sass scss/:dist/css/`
|
||||
- **Entrypoints**:
|
||||
- `docs/scss/docs.scss` → `docs/dist/css/docs.css` (+ `.min`)
|
||||
- **Consumer**: `shared/layouts/docs/default.html` loads it as `/css/docs...`
|
||||
|
||||
### 1. Canonical layer order (single source of truth)
|
||||
|
||||
- Define the layer order exactly once in the main entrypoint (e.g. the file that builds the final CSS bundle).
|
||||
- Do not redefine the global ordering in multiple places.
|
||||
- Keep the names stable (typos create new layers and break the intended cascade).
|
||||
|
||||
**Recommended order (based on Bootstrap v6 CSS layers work):**
|
||||
|
||||
```scss
|
||||
@layer colors, theme, config, root, reboot, layout, content, forms, components, helpers, custom, utilities;
|
||||
```
|
||||
|
||||
### 2. Naming rules
|
||||
|
||||
- Use lowercase, ASCII names.
|
||||
- Use the canonical names only:
|
||||
- `colors`, `theme`, `config`, `root`, `reboot`, `layout`, `content`, `forms`, `components`, `helpers`, `custom`, `utilities`
|
||||
- Never introduce new layer names without updating the canonical ordering and documenting the reasoning.
|
||||
- Treat any misspelling (e.g. `componenents`) as a **blocker**: it creates a separate layer and changes cascade behavior.
|
||||
|
||||
### 3. File-to-layer mapping (convention)
|
||||
|
||||
Use one layer per partial whenever the file outputs CSS rules.
|
||||
|
||||
- **Reboot/reset**: `scss/content/_reboot.scss` → `@layer reboot`
|
||||
- **Content styles**: `scss/content/*` → `@layer content`
|
||||
- **Form styles**: `scss/forms/*` → `@layer forms`
|
||||
- **Helpers**: `scss/helpers/*` → `@layer helpers`
|
||||
- **Layout**: `scss/layout/*` → `@layer layout`
|
||||
- **Components**: component partials (e.g. `scss/_buttons.scss`, `scss/_modal.scss`) → `@layer components`
|
||||
- **Utilities**: utility output → `@layer utilities` (should be last/highest layer)
|
||||
- **Project overrides/adapters**: local overrides → `@layer custom`
|
||||
|
||||
### 4. How to refactor a partial
|
||||
|
||||
- Wrap the file’s CSS output in a single `@layer <name> { ... }` block.
|
||||
- Keep Sass-only constructs (e.g. `@use`, variables, functions, mixins) outside the layer when it improves clarity.
|
||||
- Keep `@keyframes` inside the same layer as the rules that use them.
|
||||
|
||||
**Good example**
|
||||
|
||||
```scss
|
||||
@use "mixins/foo" as *;
|
||||
|
||||
@layer components {
|
||||
.component {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@keyframes component-spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Bad example (creates an unintended layer due to typo)**
|
||||
|
||||
```scss
|
||||
@layer componenents {
|
||||
.component { display: block; }
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Strategy for `:root` and CSS variables
|
||||
|
||||
Choose one strategy and apply it consistently:
|
||||
|
||||
- **Layered root (recommended for predictability)**: put `:root { ... }` in `@layer root { ... }`.
|
||||
- **Unlayered root (explicit exception)**: keep `:root` outside layers and document why (it will participate in the unlayered cascade).
|
||||
|
||||
Do not mix both approaches within the same codebase.
|
||||
|
||||
### 6. Utilities and `!important`
|
||||
|
||||
- Prefer putting utility output in the `utilities` layer (highest) instead of adding `!important`.
|
||||
- If `!important` is still needed, keep it limited and document the exception (utilities are expected to win via layer order).
|
||||
|
||||
### 7. Review checklist (must-pass)
|
||||
|
||||
- **Layer order** is declared once and uses the canonical names.
|
||||
- **No typos** in layer names (any unknown layer name is a blocker).
|
||||
- Each refactored partial that emits CSS rules is wrapped in the correct `@layer`.
|
||||
- No accidental unlayered rules were introduced (unless explicitly documented as an exception).
|
||||
- Bundle size budgets are updated if `@layer` increases output size (e.g. bundlewatch thresholds).
|
||||
|
||||
### 8. Anti-patterns
|
||||
|
||||
- Mixing multiple layers inside one partial without a clear need.
|
||||
- Adding new layer names ad-hoc.
|
||||
- Relying on import order to “fix” layer behavior.
|
||||
- Adding `!important` broadly instead of using the `utilities` layer strategy.
|
||||
68
.github/workflows/argos.yml
vendored
68
.github/workflows/argos.yml
vendored
@@ -1,68 +0,0 @@
|
||||
name: Argos Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
pull_request:
|
||||
paths:
|
||||
- 'preview/**/*.js'
|
||||
- 'preview/**/*.html'
|
||||
- 'preview/**/*.scss'
|
||||
- 'core/**/*.js'
|
||||
- 'core/**/*.scss'
|
||||
|
||||
env:
|
||||
NODE: 20
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
# if: github.event.pull_request.draft == false
|
||||
if: false
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-
|
||||
|
||||
- name: Install PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Get installed Playwright version
|
||||
id: playwright-version
|
||||
run: echo "PLAYWRIGHT_VERSION=$(node -e "console.log(require('./package.json').devDependencies['@playwright/test'])")" >> $GITHUB_ENV
|
||||
|
||||
- name: Cache playwright binaries
|
||||
uses: actions/cache@v4
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
|
||||
|
||||
- name: Install pnpm dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm exec playwright install --with-deps
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: pnpm run playwright
|
||||
6
.github/workflows/bundlewatch.yml
vendored
6
.github/workflows/bundlewatch.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 2
|
||||
NODE: 20
|
||||
NODE: 22
|
||||
|
||||
jobs:
|
||||
bundlewatch:
|
||||
@@ -17,10 +17,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
32
.github/workflows/lint.yml
vendored
Normal file
32
.github/workflows/lint.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
pull_request: null
|
||||
|
||||
env:
|
||||
NODE: 22
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install pnpm dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Lint Markdown
|
||||
run: pnpm run lint
|
||||
2
.github/workflows/lockfiles.yaml
vendored
2
.github/workflows/lockfiles.yaml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
name: Verify lock file integrity
|
||||
steps:
|
||||
- name: Clone Tabler
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
- name: Prevent lock file change
|
||||
uses: xalvarez/prevent-file-change-action@v3
|
||||
with:
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
pull-requests: write # to create pull request
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
pull_request: null
|
||||
|
||||
env:
|
||||
NODE: 20
|
||||
NODE: 22
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -14,10 +14,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||
|
||||
45
.github/workflows/type-check.yml
vendored
Normal file
45
.github/workflows/type-check.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: Type Check
|
||||
|
||||
on:
|
||||
pull_request: null
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
|
||||
env:
|
||||
NODE: 20
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
type-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Cache turbo build setup
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .turbo
|
||||
key: ${{ runner.os }}-turbo-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-turbo-
|
||||
|
||||
- name: Install PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install pnpm dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Run type-check
|
||||
run: pnpm run type-check
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -36,4 +36,9 @@ package-lock.json
|
||||
demo/
|
||||
dist/
|
||||
packages-zip/
|
||||
.env
|
||||
.env
|
||||
sri.json
|
||||
|
||||
# TypeScript
|
||||
*.tsbuildinfo
|
||||
.tsbuildinfo
|
||||
61
.markdownlint.json
Normal file
61
.markdownlint.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD001": {
|
||||
"level": 2
|
||||
},
|
||||
"MD003": {
|
||||
"style": "atx"
|
||||
},
|
||||
"MD004": {
|
||||
"style": "dash"
|
||||
},
|
||||
"MD007": {
|
||||
"indent": 2
|
||||
},
|
||||
"MD009": {
|
||||
"br_spaces": 2
|
||||
},
|
||||
"MD010": false,
|
||||
"MD012": {
|
||||
"maximum": 2
|
||||
},
|
||||
"MD013": {
|
||||
"line_length": 120,
|
||||
"code_blocks": false,
|
||||
"tables": false,
|
||||
"headings": false,
|
||||
"headings_line_length": 120
|
||||
},
|
||||
"MD022": true,
|
||||
"MD025": {
|
||||
"front_matter_title": ""
|
||||
},
|
||||
"MD026": {
|
||||
"punctuation": ".,;:!"
|
||||
},
|
||||
"MD030": {
|
||||
"ul_single": 1,
|
||||
"ul_multi": 1,
|
||||
"ol_single": 1,
|
||||
"ol_multi": 1
|
||||
},
|
||||
"MD031": true,
|
||||
"MD032": true,
|
||||
"MD033": false,
|
||||
"MD034": false,
|
||||
"MD035": {
|
||||
"style": "---"
|
||||
},
|
||||
"MD036": false,
|
||||
"MD037": true,
|
||||
"MD038": true,
|
||||
"MD039": true,
|
||||
"MD040": true,
|
||||
"MD041": {
|
||||
"front_matter_title": ""
|
||||
},
|
||||
"MD046": {
|
||||
"style": "fenced"
|
||||
},
|
||||
"MD047": true
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018-2025 The Tabler Authors
|
||||
Copyright (c) 2018-2026 The Tabler Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict'
|
||||
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
import { join, dirname, basename } from 'node:path';
|
||||
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 '../../shared/banner/index.mjs';
|
||||
import { sync } from 'glob'
|
||||
import banner from '../../shared/banner/index.mjs'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const styles = sync(join(__dirname, '..', 'dist', 'css', '*.css'))
|
||||
const styles: string[] = sync(join(__dirname, '..', 'dist', 'css', '*.css'))
|
||||
|
||||
const plugins = {
|
||||
interface Plugins {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
const plugins: Plugins = {
|
||||
'tabler-flags': 'Flags',
|
||||
'tabler-flags.rtl': 'Flags RTL',
|
||||
'tabler-marketing': 'Marketing',
|
||||
@@ -25,22 +27,24 @@ const plugins = {
|
||||
'tabler-vendors.rtl': 'Vendors RTL',
|
||||
}
|
||||
|
||||
styles.forEach((file, i) => {
|
||||
styles.forEach((file: string) => {
|
||||
const content = readFileSync(file, 'utf8')
|
||||
const filename = basename(file)
|
||||
const pluginKey = Object.keys(plugins).find(plugin => filename.includes(plugin))
|
||||
const plugin = plugins[pluginKey]
|
||||
const pluginKey = Object.keys(plugins).find((plugin: string) => filename.includes(plugin))
|
||||
const plugin = pluginKey ? plugins[pluginKey] : undefined
|
||||
const regex = /^(@charset ['"][a-zA-Z0-9-]+['"];?)\n?/i
|
||||
|
||||
let newContent = ''
|
||||
const bannerText = banner(plugin)
|
||||
|
||||
if (content.match(regex)) {
|
||||
newContent = content.replace(regex, (m, m1) => {
|
||||
return `${m1}\n${banner(plugin)}\n`
|
||||
newContent = content.replace(regex, (m: string, m1: string) => {
|
||||
return `${m1}\n${bannerText}\n`
|
||||
})
|
||||
} else {
|
||||
newContent = `${banner(plugin)}\n${content}`
|
||||
newContent = `${bannerText}\n${content}`
|
||||
}
|
||||
|
||||
writeFileSync(file, newContent, 'utf8')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
// Get __dirname in ES modules
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// File paths (relative to core/.build directory)
|
||||
const bootstrapPath = path.join(__dirname, '../node_modules/bootstrap/scss/_variables.scss');
|
||||
const tablerPath = path.join(__dirname, '../scss/_variables.scss');
|
||||
|
||||
// Function to extract variable names from SCSS file
|
||||
function extractVariables(filePath) {
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const variables = new Set();
|
||||
|
||||
// Regex to find SCSS variables
|
||||
// Looks for patterns like: $variable-name: value
|
||||
// Includes variables in maps and lists
|
||||
const variableRegex = /\$([a-zA-Z0-9_-]+)\s*[:=]/g;
|
||||
|
||||
let match;
|
||||
while ((match = variableRegex.exec(content)) !== null) {
|
||||
const varName = match[1];
|
||||
variables.add(varName);
|
||||
}
|
||||
|
||||
return variables;
|
||||
}
|
||||
|
||||
// Main function
|
||||
function compareVariables() {
|
||||
console.log('Analyzing Bootstrap variables...');
|
||||
const bootstrapVars = extractVariables(bootstrapPath);
|
||||
console.log(`Found ${bootstrapVars.size} variables in Bootstrap\n`);
|
||||
|
||||
console.log('Analyzing Tabler variables...');
|
||||
const tablerVars = extractVariables(tablerPath);
|
||||
console.log(`Found ${tablerVars.size} variables in Tabler\n`);
|
||||
|
||||
// Find variables that are in Bootstrap but not in Tabler
|
||||
const missingInTabler = [];
|
||||
for (const varName of bootstrapVars) {
|
||||
if (!tablerVars.has(varName)) {
|
||||
missingInTabler.push(varName);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort alphabetically
|
||||
missingInTabler.sort();
|
||||
|
||||
console.log('='.repeat(60));
|
||||
console.log(`Variables in Bootstrap that are missing in Tabler: ${missingInTabler.length}`);
|
||||
console.log('='.repeat(60));
|
||||
|
||||
if (missingInTabler.length === 0) {
|
||||
console.log('All Bootstrap variables are present in Tabler!');
|
||||
} else {
|
||||
console.log('\nList of missing variables:\n');
|
||||
missingInTabler.forEach((varName, index) => {
|
||||
console.log(`${(index + 1).toString().padStart(4)}. $${varName}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Optionally: show statistics
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('Statistics:');
|
||||
console.log(` Bootstrap: ${bootstrapVars.size} variables`);
|
||||
console.log(` Tabler: ${tablerVars.size} variables`);
|
||||
console.log(` Missing: ${missingInTabler.length} variables`);
|
||||
console.log(` Coverage: ${((1 - missingInTabler.length / bootstrapVars.size) * 100).toFixed(1)}%`);
|
||||
console.log('='.repeat(60));
|
||||
}
|
||||
|
||||
// Run analysis
|
||||
try {
|
||||
compareVariables();
|
||||
} catch (error) {
|
||||
console.error('Error during analysis:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
84
core/.build/compare-variables.ts
Normal file
84
core/.build/compare-variables.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
// Get __dirname in ES modules
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = path.dirname(__filename)
|
||||
|
||||
// File paths (relative to core/.build directory)
|
||||
const bootstrapPath = path.join(__dirname, '../node_modules/bootstrap/scss/_variables.scss')
|
||||
const tablerPath = path.join(__dirname, '../scss/_variables.scss')
|
||||
|
||||
// Function to extract variable names from SCSS file
|
||||
function extractVariables(filePath: string): Set<string> {
|
||||
const content = readFileSync(filePath, 'utf8')
|
||||
const variables = new Set<string>()
|
||||
|
||||
// Regex to find SCSS variables
|
||||
// Looks for patterns like: $variable-name: value
|
||||
// Includes variables in maps and lists
|
||||
const variableRegex = /\$([a-zA-Z0-9_-]+)\s*[:=]/g
|
||||
|
||||
let match: RegExpExecArray | null
|
||||
while ((match = variableRegex.exec(content)) !== null) {
|
||||
const varName = match[1]
|
||||
variables.add(varName)
|
||||
}
|
||||
|
||||
return variables
|
||||
}
|
||||
|
||||
// Main function
|
||||
function compareVariables(): void {
|
||||
console.log('Analyzing Bootstrap variables...')
|
||||
const bootstrapVars = extractVariables(bootstrapPath)
|
||||
console.log(`Found ${bootstrapVars.size} variables in Bootstrap\n`)
|
||||
|
||||
console.log('Analyzing Tabler variables...')
|
||||
const tablerVars = extractVariables(tablerPath)
|
||||
console.log(`Found ${tablerVars.size} variables in Tabler\n`)
|
||||
|
||||
// Find variables that are in Bootstrap but not in Tabler
|
||||
const missingInTabler: string[] = []
|
||||
for (const varName of bootstrapVars) {
|
||||
if (!tablerVars.has(varName)) {
|
||||
missingInTabler.push(varName)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort alphabetically
|
||||
missingInTabler.sort()
|
||||
|
||||
console.log('='.repeat(60))
|
||||
console.log(`Variables in Bootstrap that are missing in Tabler: ${missingInTabler.length}`)
|
||||
console.log('='.repeat(60))
|
||||
|
||||
if (missingInTabler.length === 0) {
|
||||
console.log('All Bootstrap variables are present in Tabler!')
|
||||
} else {
|
||||
console.log('\nList of missing variables:\n')
|
||||
missingInTabler.forEach((varName: string, index: number) => {
|
||||
console.log(`${(index + 1).toString().padStart(4)}. $${varName}`)
|
||||
})
|
||||
}
|
||||
|
||||
// Optionally: show statistics
|
||||
console.log('\n' + '='.repeat(60))
|
||||
console.log('Statistics:')
|
||||
console.log(` Bootstrap: ${bootstrapVars.size} variables`)
|
||||
console.log(` Tabler: ${tablerVars.size} variables`)
|
||||
console.log(` Missing: ${missingInTabler.length} variables`)
|
||||
console.log(` Coverage: ${((1 - missingInTabler.length / bootstrapVars.size) * 100).toFixed(1)}%`)
|
||||
console.log('='.repeat(60))
|
||||
}
|
||||
|
||||
// Run analysis
|
||||
try {
|
||||
compareVariables()
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
console.error('Error during analysis:', errorMessage)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,30 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict'
|
||||
|
||||
import { existsSync, mkdirSync, lstatSync } from 'fs'
|
||||
import { existsSync, mkdirSync } from 'node:fs'
|
||||
import { emptyDirSync, copySync } from 'fs-extra/esm'
|
||||
import libs from '../libs.json' with { type: 'json' }
|
||||
import { fileURLToPath } from 'url'
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { join, dirname } from 'node:path'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
interface LibConfig {
|
||||
npm?: string
|
||||
js?: string[]
|
||||
css?: string[]
|
||||
head?: boolean
|
||||
}
|
||||
|
||||
interface Libs {
|
||||
[key: string]: LibConfig
|
||||
}
|
||||
|
||||
const libsData = libs as Libs
|
||||
|
||||
emptyDirSync(join(__dirname, '..', 'dist/libs'))
|
||||
|
||||
for(const name in libs) {
|
||||
const { npm } = libs[name]
|
||||
for (const name in libsData) {
|
||||
const { npm } = libsData[name]
|
||||
|
||||
if (npm) {
|
||||
const from = join(__dirname, '..', `node_modules/${npm}`)
|
||||
@@ -23,11 +34,12 @@ for(const name in libs) {
|
||||
if (!existsSync(to)) {
|
||||
mkdirSync(to, { recursive: true })
|
||||
}
|
||||
|
||||
|
||||
copySync(from, to, {
|
||||
dereference: true,
|
||||
})
|
||||
|
||||
|
||||
console.log(`Successfully copied ${npm}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
const crypto = require('node:crypto');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const sh = require('shelljs');
|
||||
import * as crypto from 'node:crypto'
|
||||
import { readFileSync, writeFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
sh.config.fatal = true
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const configFile = path.join(__dirname, '../../shared/data/sri.json')
|
||||
|
||||
const files = [
|
||||
interface FileConfig {
|
||||
file: string
|
||||
configPropertyName: string
|
||||
}
|
||||
|
||||
const files: FileConfig[] = [
|
||||
{
|
||||
file: 'dist/css/tabler.min.css',
|
||||
configPropertyName: 'css'
|
||||
@@ -80,28 +85,37 @@ const files = [
|
||||
file: 'dist/js/tabler-theme.min.js',
|
||||
configPropertyName: 'js-theme'
|
||||
},
|
||||
// {
|
||||
// file: 'dist/preview/css/demo.min.css',
|
||||
// configPropertyName: 'demo-css'
|
||||
// },
|
||||
// {
|
||||
// file: 'dist/preview/js/demo.min.js',
|
||||
// configPropertyName: 'demo-js'
|
||||
// },
|
||||
]
|
||||
|
||||
for (const { file, configPropertyName } of files) {
|
||||
fs.readFile(path.join(__dirname, '..', file), 'utf8', (error, data) => {
|
||||
if (error) {
|
||||
function generateSRI(): void {
|
||||
const sriData: Record<string, string> = {}
|
||||
|
||||
for (const { file, configPropertyName } of files) {
|
||||
try {
|
||||
const filePath = path.join(__dirname, '..', file)
|
||||
const data = readFileSync(filePath, 'utf8')
|
||||
|
||||
const algorithm = 'sha384'
|
||||
const hash = crypto.createHash(algorithm).update(data, 'utf8').digest('base64')
|
||||
const integrity = `${algorithm}-${hash}`
|
||||
|
||||
console.log(`${configPropertyName}: ${integrity}`)
|
||||
|
||||
sriData[configPropertyName] = integrity
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
console.error(`Error processing ${file}:`, errorMessage)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
const algorithm = 'sha384'
|
||||
const hash = crypto.createHash(algorithm).update(data, 'utf8').digest('base64')
|
||||
const integrity = `${algorithm}-${hash}`
|
||||
writeFileSync(configFile, JSON.stringify(sriData, null, 2) + '\n', 'utf8')
|
||||
}
|
||||
|
||||
console.log(`${configPropertyName}: ${integrity}`)
|
||||
try {
|
||||
generateSRI()
|
||||
} catch (error) {
|
||||
console.error('Failed to generate SRI:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
sh.sed('-i', new RegExp(`^(\\s+"${configPropertyName}":\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile)
|
||||
})
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict'
|
||||
|
||||
import { existsSync, mkdirSync } from 'fs'
|
||||
import { existsSync, mkdirSync } from 'node:fs'
|
||||
import { copySync } from 'fs-extra/esm'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { join, dirname } from 'node:path'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
@@ -25,11 +23,11 @@ if (existsSync(monoFrom)) {
|
||||
if (!existsSync(monoTo)) {
|
||||
mkdirSync(monoTo, { recursive: true })
|
||||
}
|
||||
|
||||
|
||||
copySync(monoFrom, monoTo, {
|
||||
dereference: true,
|
||||
})
|
||||
|
||||
|
||||
console.log(`Successfully copied geist-mono fonts`)
|
||||
} else {
|
||||
console.warn(`Warning: geist-mono fonts not found at ${monoFrom}`)
|
||||
@@ -43,11 +41,11 @@ if (existsSync(sansFrom)) {
|
||||
if (!existsSync(sansTo)) {
|
||||
mkdirSync(sansTo, { recursive: true })
|
||||
}
|
||||
|
||||
|
||||
copySync(sansFrom, sansTo, {
|
||||
dereference: true,
|
||||
})
|
||||
|
||||
|
||||
console.log(`Successfully copied geist-sans fonts`)
|
||||
} else {
|
||||
console.warn(`Warning: geist-sans fonts not found at ${sansFrom}`)
|
||||
@@ -1,47 +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 '../../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 external = []
|
||||
const plugins = [
|
||||
babel({
|
||||
exclude: 'node_modules/**',
|
||||
babelHelpers: 'bundled'
|
||||
})
|
||||
]
|
||||
|
||||
plugins.push(
|
||||
replace({
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
preventAssignment: true
|
||||
}),
|
||||
nodeResolve()
|
||||
)
|
||||
|
||||
const destinationFile = `tabler${THEME ? '-theme' : ''}${ESM ? '.esm' : ''}`
|
||||
const rollupConfig = {
|
||||
input: path.resolve(__dirname, `../js/tabler${THEME ? '-theme' : ''}.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${THEME ? '-theme' : ''}`
|
||||
}
|
||||
|
||||
export default rollupConfig
|
||||
33
core/.build/vite.config.ts
Normal file
33
core/.build/vite.config.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
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
|
||||
})
|
||||
|
||||
@@ -106,7 +106,6 @@
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- a2640e2: Add Playwright configuration and visual regression tests
|
||||
- d3ae77c: Enable `scrollSpy` in `countup` module
|
||||
- bd3d959: Refactor SCSS files to replace divide function with calc
|
||||
- cb278c7: Add Segmented Control component
|
||||
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="16" fill="none"><mask id="a" width="21" height="16" x="0" y="0" mask-type="alpha" maskUnits="userSpaceOnUse"><path fill="#fff" d="M.001.927h20v15h-20z"/></mask><g mask="url(#a)"><path fill="#F7FCFF" fill-rule="evenodd" d="M.001.927v15h20v-15h-20Z" clip-rule="evenodd"/><mask id="b" width="21" height="16" x="0" y="0" mask-type="alpha" maskUnits="userSpaceOnUse"><path fill="#fff" fill-rule="evenodd" d="M.001.927v15h20v-15h-20Z" clip-rule="evenodd"/></mask><g fill-rule="evenodd" clip-rule="evenodd" mask="url(#b)"><path fill="#3D58DB" d="M.001.927v15h20v-15h-20Z"/><path fill="#FFD018" d="m9.407 3.137-.14.818L10 3.57l.735.386-.14-.818.594-.64h-.821L10 1.695l-.367.804h-.822l.595.639Zm0 10.855-.14.819.734-.387.735.387-.14-.819.594-.639h-.821L10 12.55l-.367.804h-.822l.595.64ZM3.484 9.438l.14-.818-.594-.64h.822l.367-.803.367.804h.822l-.595.639.14.818-.734-.386-.735.386Zm1.352 1.77-.14.818.734-.386.735.386-.14-.818.594-.64h-.821l-.368-.803-.367.804H4.24l.595.639Zm9.009.818.14-.818-.595-.64h.822l.367-.803.368.804h.821l-.594.639.14.818-.735-.386-.734.386Zm-9.01-6.062-.14.818.735-.386.735.386-.14-.818.594-.639h-.821l-.368-.804-.367.804H4.24l.595.64Zm9.01.818.14-.818-.595-.639h.822l.367-.804.368.804h.821l-.594.64.14.817-.735-.386-.734.386ZM6.66 13.29l-.14.819.735-.387.734.386-.14-.818.595-.639h-.822l-.367-.804-.368.804h-.821l.594.64Zm5.418.819.14-.819-.594-.639h.821l.367-.804.368.804h.821l-.594.64.14.817-.735-.386-.734.386ZM6.52 4.666l.735-.387.734.387-.14-.818.595-.64h-.822l-.367-.804-.368.804h-.821l.594.64-.14.818Zm5.558 0 .14-.818-.594-.64h.821l.367-.804.368.804h.821l-.594.64.14.818-.735-.387-.734.387Zm3.062 3.879-.14.818.735-.386.735.386-.14-.818.593-.64h-.82l-.368-.803-.368.804h-.821l.594.639Z"/></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="15" fill="none" viewBox="0 0 20 15"><path fill="#3d58db" fill-rule="evenodd" d="M0 0v15h20V0z" clip-rule="evenodd"/><path fill="#ffd018" fill-rule="evenodd" d="m9.407 2.442-.14.818.733-.385.735.386-.14-.818.594-.64h-.821L10 1l-.367.804h-.822zm0 10.855-.14.819.734-.387.735.387-.14-.819.594-.639h-.821L10 11.855l-.367.804h-.822l.595.64zM3.484 8.743l.14-.818-.594-.64h.822l.367-.803.367.804h.822l-.595.639.14.818-.734-.386zm1.352 1.77-.14.818.734-.386.735.386-.14-.818.594-.64h-.821L5.43 9.07l-.367.804H4.24zm9.009.818.14-.818-.595-.64h.822l.367-.803.368.804h.821l-.594.639.14.818-.735-.386zm-9.01-6.062-.14.818.735-.386.735.386-.14-.818.594-.639h-.821l-.368-.804-.367.804H4.24zm9.01.818.14-.818-.595-.639h.822l.367-.804.368.804h.821l-.594.64.14.817-.735-.386zM6.66 12.595l-.14.819.735-.387.734.386-.14-.818.595-.639h-.822l-.367-.804-.368.804h-.821zm5.418.819.14-.819-.594-.639h.821l.367-.804.368.804h.821l-.594.64.14.817-.735-.386zM6.52 3.971l.735-.387.734.387-.14-.818.595-.64h-.822l-.367-.804-.368.804h-.821l.594.64zm5.558 0 .14-.818-.594-.64h.821l.367-.804.368.804h.821l-.594.64.14.818-.735-.387zM15.14 7.85l-.14.818.735-.386.735.386-.14-.818.593-.64h-.82l-.368-.803-.368.804h-.821z" clip-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1,8 +0,0 @@
|
||||
// Autosize plugin
|
||||
const elements = document.querySelectorAll('[data-bs-toggle="autosize"]')
|
||||
|
||||
if (elements.length) {
|
||||
elements.forEach(function (element) {
|
||||
window.autosize && window.autosize(element)
|
||||
})
|
||||
}
|
||||
10
core/js/src/autosize.ts
Normal file
10
core/js/src/autosize.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
// Autosize plugin
|
||||
const autosizeElements: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>('[data-bs-toggle="autosize"]')
|
||||
|
||||
if (autosizeElements.length) {
|
||||
autosizeElements.forEach(function (element: HTMLElement) {
|
||||
if (window.autosize) {
|
||||
window.autosize(element)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1,20 +1,7 @@
|
||||
export * as Popper from '@popperjs/core'
|
||||
|
||||
// Export all Bootstrap components directly for consistent usage
|
||||
export {
|
||||
Alert,
|
||||
Button,
|
||||
Carousel,
|
||||
Collapse,
|
||||
Dropdown,
|
||||
Modal,
|
||||
Offcanvas,
|
||||
Popover,
|
||||
ScrollSpy,
|
||||
Tab,
|
||||
Toast,
|
||||
Tooltip
|
||||
} from 'bootstrap'
|
||||
export { Alert, Button, Carousel, Collapse, Dropdown, Modal, Offcanvas, Popover, ScrollSpy, Tab, Toast, Tooltip } from 'bootstrap'
|
||||
|
||||
// Re-export everything as namespace for backward compatibility
|
||||
export * as bootstrap from 'bootstrap'
|
||||
@@ -1,17 +1,19 @@
|
||||
const elements = document.querySelectorAll('[data-countup]')
|
||||
const countupElements: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>('[data-countup]')
|
||||
|
||||
if (elements.length) {
|
||||
elements.forEach(function (element) {
|
||||
let options = {}
|
||||
if (countupElements.length) {
|
||||
countupElements.forEach(function (element: HTMLElement) {
|
||||
let options: Record<string, any> = {}
|
||||
try {
|
||||
const dataOptions = element.getAttribute('data-countup') ? JSON.parse(element.getAttribute('data-countup')) : {}
|
||||
const dataOptions = element.getAttribute('data-countup') ? JSON.parse(element.getAttribute('data-countup')!) : {}
|
||||
options = Object.assign(
|
||||
{
|
||||
enableScrollSpy: true,
|
||||
},
|
||||
dataOptions,
|
||||
)
|
||||
} catch (error) {}
|
||||
} catch (error) {
|
||||
// ignore invalid JSON
|
||||
}
|
||||
|
||||
const value = parseInt(element.innerHTML, 10)
|
||||
|
||||
@@ -3,9 +3,9 @@ import { Dropdown } from './bootstrap'
|
||||
/*
|
||||
Core dropdowns
|
||||
*/
|
||||
let dropdownTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="dropdown"]'))
|
||||
dropdownTriggerList.map(function (dropdownTriggerEl) {
|
||||
let options = {
|
||||
const dropdownTriggerList: HTMLElement[] = [].slice.call(document.querySelectorAll<HTMLElement>('[data-bs-toggle="dropdown"]'))
|
||||
dropdownTriggerList.map(function (dropdownTriggerEl: HTMLElement) {
|
||||
const options = {
|
||||
boundary: dropdownTriggerEl.getAttribute('data-bs-boundary') === 'viewport' ? document.querySelector('.btn') : 'clippingParents',
|
||||
}
|
||||
return new Dropdown(dropdownTriggerEl, options)
|
||||
14
core/js/src/global.d.ts
vendored
Normal file
14
core/js/src/global.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Global type declarations for window properties
|
||||
|
||||
interface Window {
|
||||
autosize?: (element: HTMLElement | HTMLTextAreaElement) => void
|
||||
countUp?: {
|
||||
CountUp: new (target: HTMLElement, endVal: number, options?: any) => {
|
||||
error: boolean
|
||||
start: () => void
|
||||
}
|
||||
}
|
||||
IMask?: new (element: HTMLElement, options: { mask: string; lazy?: boolean }) => any
|
||||
Sortable?: new (element: HTMLElement, options?: any) => any
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Input mask plugin
|
||||
|
||||
var maskElementList = [].slice.call(document.querySelectorAll('[data-mask]'))
|
||||
maskElementList.map(function (maskEl) {
|
||||
const maskElementList: HTMLElement[] = [].slice.call(document.querySelectorAll<HTMLElement>('[data-mask]'))
|
||||
maskElementList.map(function (maskEl: HTMLElement) {
|
||||
window.IMask &&
|
||||
new window.IMask(maskEl, {
|
||||
mask: maskEl.dataset.mask,
|
||||
@@ -3,9 +3,9 @@ import { Popover } from './bootstrap'
|
||||
/*
|
||||
Core popovers
|
||||
*/
|
||||
let popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
|
||||
popoverTriggerList.map(function (popoverTriggerEl) {
|
||||
let options = {
|
||||
const popoverTriggerList: HTMLElement[] = [].slice.call(document.querySelectorAll<HTMLElement>('[data-bs-toggle="popover"]'))
|
||||
popoverTriggerList.map(function (popoverTriggerEl: HTMLElement) {
|
||||
const options = {
|
||||
delay: { show: 50, hide: 50 },
|
||||
html: popoverTriggerEl.getAttribute('data-bs-html') === 'true',
|
||||
placement: popoverTriggerEl.getAttribute('data-bs-placement') ?? 'auto',
|
||||
@@ -2,11 +2,11 @@
|
||||
// Initializes Sortable on elements marked with [data-sortable]
|
||||
// Allows options via JSON in data attribute: data-sortable='{"animation":150}'
|
||||
|
||||
const sortableElements = document.querySelectorAll('[data-sortable]')
|
||||
const sortableElements: NodeListOf<HTMLElement> = document.querySelectorAll<HTMLElement>('[data-sortable]')
|
||||
|
||||
if (sortableElements.length) {
|
||||
sortableElements.forEach(function (element) {
|
||||
let options = {}
|
||||
sortableElements.forEach(function (element: HTMLElement) {
|
||||
let options: Record<string, any> = {}
|
||||
|
||||
try {
|
||||
const rawOptions = element.getAttribute('data-sortable')
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
Switch icons
|
||||
*/
|
||||
let switchesTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="switch-icon"]'))
|
||||
switchesTriggerList.map(function (switchTriggerEl) {
|
||||
switchTriggerEl.addEventListener('click', (e) => {
|
||||
e.stopPropagation()
|
||||
|
||||
switchTriggerEl.classList.toggle('active')
|
||||
})
|
||||
})
|
||||
11
core/js/src/switch-icon.ts
Normal file
11
core/js/src/switch-icon.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
Switch icons
|
||||
*/
|
||||
const switchesTriggerList: HTMLElement[] = [].slice.call(document.querySelectorAll<HTMLElement>('[data-bs-toggle="switch-icon"]'))
|
||||
switchesTriggerList.map(function (switchTriggerEl: HTMLElement) {
|
||||
switchTriggerEl.addEventListener('click', (e: MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
|
||||
switchTriggerEl.classList.toggle('active')
|
||||
})
|
||||
})
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Tab } from './bootstrap'
|
||||
|
||||
export const EnableActivationTabsFromLocationHash = () => {
|
||||
const locationHash = window.location.hash
|
||||
|
||||
if (locationHash) {
|
||||
const tabsList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tab"]'))
|
||||
const matchedTabs = tabsList.filter((tab) => tab.hash === locationHash)
|
||||
|
||||
matchedTabs.map((tab) => {
|
||||
new Tab(tab).show()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
EnableActivationTabsFromLocationHash()
|
||||
16
core/js/src/tab.ts
Normal file
16
core/js/src/tab.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { Tab } from './bootstrap'
|
||||
|
||||
export const EnableActivationTabsFromLocationHash = (): void => {
|
||||
const locationHash: string = window.location.hash
|
||||
|
||||
if (locationHash) {
|
||||
const tabsList: HTMLAnchorElement[] = [].slice.call(document.querySelectorAll<HTMLAnchorElement>('[data-bs-toggle="tab"]'))
|
||||
const matchedTabs = tabsList.filter((tab: HTMLAnchorElement) => tab.hash === locationHash)
|
||||
|
||||
matchedTabs.map((tab: HTMLAnchorElement) => {
|
||||
new Tab(tab).show()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
EnableActivationTabsFromLocationHash()
|
||||
@@ -1,12 +1,12 @@
|
||||
export const prefix = 'tblr-'
|
||||
export const prefix: string = 'tblr-'
|
||||
|
||||
export const hexToRgba = (hex, opacity) => {
|
||||
export const hexToRgba = (hex: string, opacity: number): string | null => {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
||||
|
||||
return result ? `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}, ${opacity})` : null
|
||||
}
|
||||
|
||||
export const getColor = (color, opacity = 1) => {
|
||||
export const getColor = (color: string, opacity: number = 1): string | null => {
|
||||
const c = getComputedStyle(document.body).getPropertyValue(`--${prefix}${color}`).trim()
|
||||
|
||||
if (opacity !== 1) {
|
||||
@@ -1,17 +0,0 @@
|
||||
import { Toast } from './bootstrap'
|
||||
|
||||
/*
|
||||
Toasts
|
||||
*/
|
||||
let toastsTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="toast"]'))
|
||||
toastsTriggerList.map(function (toastTriggerEl) {
|
||||
if (!toastTriggerEl.hasAttribute('data-bs-target')) {
|
||||
return
|
||||
}
|
||||
|
||||
const toastEl = new Toast(toastTriggerEl.getAttribute('data-bs-target'))
|
||||
|
||||
toastTriggerEl.addEventListener('click', () => {
|
||||
toastEl.show()
|
||||
})
|
||||
})
|
||||
18
core/js/src/toast.ts
Normal file
18
core/js/src/toast.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Toast } from './bootstrap'
|
||||
|
||||
/*
|
||||
Toasts
|
||||
*/
|
||||
const toastsTriggerList: HTMLElement[] = [].slice.call(document.querySelectorAll<HTMLElement>('[data-bs-toggle="toast"]'))
|
||||
toastsTriggerList.map(function (toastTriggerEl: HTMLElement) {
|
||||
const target = toastTriggerEl.getAttribute('data-bs-target')
|
||||
if (target === null) {
|
||||
return
|
||||
}
|
||||
|
||||
const toastEl = new Toast(target)
|
||||
|
||||
toastTriggerEl.addEventListener('click', () => {
|
||||
toastEl.show()
|
||||
})
|
||||
})
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Tooltip } from './bootstrap'
|
||||
|
||||
let tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
let options = {
|
||||
const tooltipTriggerList: HTMLElement[] = [].slice.call(document.querySelectorAll<HTMLElement>('[data-bs-toggle="tooltip"]'))
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl: HTMLElement) {
|
||||
const options = {
|
||||
delay: { show: 50, hide: 50 },
|
||||
html: tooltipTriggerEl.getAttribute('data-bs-html') === 'true',
|
||||
placement: tooltipTriggerEl.getAttribute('data-bs-placement') ?? 'auto',
|
||||
@@ -3,7 +3,15 @@
|
||||
* to ensure we switch to the chosen dark/light theme as fast as possible.
|
||||
* This will prevent any flashes of the light theme (default) before switching.
|
||||
*/
|
||||
const themeConfig = {
|
||||
interface ThemeConfig {
|
||||
'theme': string
|
||||
'theme-base': string
|
||||
'theme-font': string
|
||||
'theme-primary': string
|
||||
'theme-radius': string
|
||||
}
|
||||
|
||||
const themeConfig: ThemeConfig = {
|
||||
'theme': 'light',
|
||||
'theme-base': 'gray',
|
||||
'theme-font': 'sans-serif',
|
||||
@@ -12,22 +20,22 @@ const themeConfig = {
|
||||
}
|
||||
|
||||
const params = new Proxy(new URLSearchParams(window.location.search), {
|
||||
get: (searchParams, prop) => searchParams.get(prop),
|
||||
get: (searchParams: URLSearchParams, prop: string): string | null => searchParams.get(prop),
|
||||
})
|
||||
|
||||
for (const key in themeConfig) {
|
||||
const param = params[key]
|
||||
let selectedValue
|
||||
let selectedValue: string
|
||||
|
||||
if (!!param) {
|
||||
localStorage.setItem('tabler-' + key, param)
|
||||
selectedValue = param
|
||||
} else {
|
||||
const storedTheme = localStorage.getItem('tabler-' + key)
|
||||
selectedValue = storedTheme ? storedTheme : themeConfig[key]
|
||||
selectedValue = storedTheme ? storedTheme : themeConfig[key as keyof ThemeConfig]
|
||||
}
|
||||
|
||||
if (selectedValue !== themeConfig[key]) {
|
||||
if (selectedValue !== themeConfig[key as keyof ThemeConfig]) {
|
||||
document.documentElement.setAttribute('data-bs-' + key, selectedValue)
|
||||
} else {
|
||||
document.documentElement.removeAttribute('data-bs-' + key)
|
||||
@@ -9,7 +9,7 @@ import './src/tab'
|
||||
import './src/toast'
|
||||
import './src/sortable'
|
||||
|
||||
// Re-export everything from bootstrap.js (single source of truth)
|
||||
// Re-export everything from bootstrap.ts (single source of truth)
|
||||
export * from './src/bootstrap'
|
||||
|
||||
// Re-export tabler namespace
|
||||
@@ -166,5 +166,14 @@
|
||||
"dist/turbo.es2017-umd.js"
|
||||
],
|
||||
"head": true
|
||||
},
|
||||
"driver.js": {
|
||||
"npm": "driver.js",
|
||||
"js": [
|
||||
"dist/driver.js.iife.js"
|
||||
],
|
||||
"css": [
|
||||
"dist/driver.css"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,41 +5,43 @@
|
||||
"homepage": "https://tabler.io",
|
||||
"scripts": {
|
||||
"dev": "pnpm run clean && pnpm run copy && pnpm run watch",
|
||||
"build": "pnpm run clean && pnpm run css && pnpm run js && pnpm run copy && pnpm run generate-sri",
|
||||
"build": "pnpm run clean && pnpm run build-assets && pnpm run copy && pnpm run generate-sri",
|
||||
"build-assets": "concurrently \"pnpm run css\" \"pnpm run js\"",
|
||||
"clean": "shx 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 --no-source-map --load-path=node_modules --style expanded scss/:dist/css/",
|
||||
"css-banner": "node .build/add-banner.mjs",
|
||||
"css": "pnpm run css-build && pnpm run css-prefix && pnpm run css-rtl && pnpm run css-minify && pnpm run css-banner",
|
||||
"css-build": "sass --no-source-map --load-path=node_modules --style expanded scss/:dist/css/",
|
||||
"css-banner": "tsx .build/add-banner.ts",
|
||||
"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": "concurrently \"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\"",
|
||||
"css-lint": "pnpm run css-lint-variables",
|
||||
"css-lint-variables": "find-unused-sass-variables scss/ node_modules/bootstrap/scss/",
|
||||
"js": "pnpm run js-compile && pnpm run js-minify",
|
||||
"js-compile": "pnpm run js-compile-standalone && pnpm run js-compile-standalone-esm && pnpm run js-compile-theme && pnpm run js-compile-theme-esm",
|
||||
"js-compile-theme-esm": "rollup --environment THEME:true --environment ESM:true --config .build/rollup.config.mjs --sourcemap",
|
||||
"js-compile-theme": "rollup --environment THEME:true --config .build/rollup.config.mjs --sourcemap",
|
||||
"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 && pnpm run js-minify-theme && pnpm run js-minify-theme-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",
|
||||
"js-minify-theme": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/tabler-theme.js.map,includeSources,url=tabler-theme.min.js.map\" --output dist/js/tabler-theme.min.js dist/js/tabler-theme.js",
|
||||
"js-minify-theme-esm": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/tabler-theme.esm.js.map,includeSources,url=tabler-theme.esm.min.js.map\" --output dist/js/tabler-theme.esm.min.js dist/js/tabler-theme.esm.js",
|
||||
"copy": "pnpm run copy-img && pnpm run copy-libs && pnpm run copy-fonts",
|
||||
"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",
|
||||
"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": "node .build/copy-libs.mjs",
|
||||
"copy-libs": "tsx .build/copy-libs.ts",
|
||||
"copy-fonts": "shx mkdir -p dist/fonts && shx cp -rf fonts/* dist/fonts",
|
||||
"import-fonts": "node .build/import-fonts.mjs",
|
||||
"import-fonts": "tsx .build/import-fonts.ts",
|
||||
"watch": "concurrently \"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\"",
|
||||
"watch-css": "nodemon --watch scss/ --ext scss --exec \"pnpm run css-build && pnpm run css-prefix\"",
|
||||
"watch-js": "nodemon --watch js/ --ext ts,js --exec \"pnpm run js-build\"",
|
||||
"bundlewatch": "bundlewatch",
|
||||
"generate-sri": "node .build/generate-sri.js",
|
||||
"format:check": "prettier --check \"scss/**/*.scss\" \"js/**/*.js\" --cache",
|
||||
"format:write": "prettier --write \"scss/**/*.scss\" \"js/**/*.js\" --cache"
|
||||
"generate-sri": "tsx .build/generate-sri.ts",
|
||||
"format:check": "prettier --check \"scss/**/*.scss\" \"js/**/*.{js,ts}\" --cache",
|
||||
"format:write": "prettier --write \"scss/**/*.scss\" \"js/**/*.{js,ts}\" --cache",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -69,7 +71,7 @@
|
||||
"files": [
|
||||
"docs/**/*",
|
||||
"dist/**/*",
|
||||
"js/**/*.{js,map}",
|
||||
"js/**/*.{ts,js,map}",
|
||||
"img/**/*.{svg}",
|
||||
"scss/**/*.scss",
|
||||
"libs.json"
|
||||
@@ -155,7 +157,8 @@
|
||||
"devDependencies": {
|
||||
"@hotwired/turbo": "^8.0.18",
|
||||
"@melloware/coloris": "^0.25.0",
|
||||
"apexcharts": "3.54.1",
|
||||
"@types/node": "^22.0.0",
|
||||
"apexcharts": "^5.3.6",
|
||||
"autosize": "^6.0.1",
|
||||
"choices.js": "^11.1.0",
|
||||
"clipboard": "^2.0.11",
|
||||
@@ -177,7 +180,9 @@
|
||||
"sortablejs": "^1.15.6",
|
||||
"star-rating.js": "^4.3.1",
|
||||
"tom-select": "^2.4.3",
|
||||
"typed.js": "^2.1.0"
|
||||
"typed.js": "^2.1.0",
|
||||
"typescript": "^5.9.3",
|
||||
"driver.js": "^1.0.0"
|
||||
},
|
||||
"directories": {
|
||||
"doc": "docs"
|
||||
|
||||
@@ -1,30 +1,48 @@
|
||||
// Layout & components
|
||||
@import 'bootstrap/scss/root';
|
||||
@import 'bootstrap/scss/reboot';
|
||||
@import 'bootstrap/scss/type';
|
||||
@import 'bootstrap/scss/images';
|
||||
@import 'bootstrap/scss/containers';
|
||||
@import 'bootstrap/scss/grid';
|
||||
@import 'bootstrap/scss/tables';
|
||||
@import 'bootstrap/scss/forms';
|
||||
@import 'bootstrap/scss/buttons';
|
||||
@import 'bootstrap/scss/transitions';
|
||||
@import 'bootstrap/scss/dropdown';
|
||||
@import 'bootstrap/scss/button-group';
|
||||
@import 'bootstrap/scss/nav';
|
||||
@import 'bootstrap/scss/navbar';
|
||||
@import 'bootstrap/scss/card';
|
||||
@import 'bootstrap/scss/pagination';
|
||||
@import 'bootstrap/scss/progress';
|
||||
@import 'bootstrap/scss/list-group';
|
||||
@import 'bootstrap/scss/toasts';
|
||||
@import 'bootstrap/scss/modal';
|
||||
@import 'bootstrap/scss/tooltip';
|
||||
@import 'bootstrap/scss/popover';
|
||||
@import 'bootstrap/scss/carousel';
|
||||
@import 'bootstrap/scss/spinners';
|
||||
@import 'bootstrap/scss/offcanvas';
|
||||
@import 'bootstrap/scss/placeholders';
|
||||
// Bootstrap (CSS Cascade Layers)
|
||||
@layer root {
|
||||
@import 'bootstrap/scss/root';
|
||||
}
|
||||
|
||||
// Utilities
|
||||
@import 'bootstrap/scss/utilities/api';
|
||||
@layer reboot {
|
||||
@import 'bootstrap/scss/reboot';
|
||||
}
|
||||
|
||||
@layer content {
|
||||
@import 'bootstrap/scss/type';
|
||||
@import 'bootstrap/scss/images';
|
||||
@import 'bootstrap/scss/tables';
|
||||
}
|
||||
|
||||
@layer layout {
|
||||
@import 'bootstrap/scss/containers';
|
||||
@import 'bootstrap/scss/grid';
|
||||
@import 'bootstrap/scss/nav';
|
||||
@import 'bootstrap/scss/navbar';
|
||||
}
|
||||
|
||||
@layer forms {
|
||||
@import 'bootstrap/scss/forms';
|
||||
}
|
||||
|
||||
@layer components {
|
||||
@import 'bootstrap/scss/buttons';
|
||||
@import 'bootstrap/scss/transitions';
|
||||
@import 'bootstrap/scss/dropdown';
|
||||
@import 'bootstrap/scss/button-group';
|
||||
@import 'bootstrap/scss/card';
|
||||
@import 'bootstrap/scss/pagination';
|
||||
@import 'bootstrap/scss/progress';
|
||||
@import 'bootstrap/scss/list-group';
|
||||
@import 'bootstrap/scss/toasts';
|
||||
@import 'bootstrap/scss/modal';
|
||||
@import 'bootstrap/scss/tooltip';
|
||||
@import 'bootstrap/scss/popover';
|
||||
@import 'bootstrap/scss/carousel';
|
||||
@import 'bootstrap/scss/spinners';
|
||||
@import 'bootstrap/scss/offcanvas';
|
||||
@import 'bootstrap/scss/placeholders';
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
@import 'bootstrap/scss/utilities/api';
|
||||
}
|
||||
|
||||
3
core/scss/_layers.scss
Normal file
3
core/scss/_layers.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
// Canonical CSS Cascade Layers order.
|
||||
// Keep in sync with `.cursor/rules/scss-layers.mdc`.
|
||||
@layer colors, theme, config, root, reboot, layout, content, forms, components, helpers, custom, utilities;
|
||||
@@ -1,6 +1,7 @@
|
||||
@use 'sass:map';
|
||||
@import 'config';
|
||||
|
||||
@layer root {
|
||||
:root,
|
||||
:host {
|
||||
/** Fonts */
|
||||
@@ -91,3 +92,4 @@
|
||||
--#{$prefix}backdrop-blur: #{$backdrop-blur};
|
||||
--#{$prefix}backdrop-filter: blur(var(--#{$prefix}backdrop-blur));
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,12 +33,7 @@ $enable-deprecation-messages: true !default;
|
||||
$enable-important-utilities: true !default;
|
||||
|
||||
// Escaped Characters
|
||||
$escaped-characters: (
|
||||
('<', '%3c'),
|
||||
('>', '%3e'),
|
||||
('#', '%23'),
|
||||
('(', '%28'),
|
||||
(')', '%29')) !default;
|
||||
$escaped-characters: (('<', '%3c'), ('>', '%3e'), ('#', '%23'), ('(', '%28'), (')', '%29')) !default;
|
||||
|
||||
// Dark Mode
|
||||
$color-mode-type: data !default;
|
||||
@@ -500,6 +495,11 @@ $line-heights: (
|
||||
h4: $h4-line-height,
|
||||
h5: $h5-line-height,
|
||||
h6: $h6-line-height,
|
||||
|
||||
base: $line-height-base,
|
||||
sm: $line-height-sm,
|
||||
lg: $line-height-lg,
|
||||
xl: $line-height-xl,
|
||||
) !default;
|
||||
|
||||
$display-font-sizes: (
|
||||
@@ -560,11 +560,6 @@ $text-secondary-opacity: 0.7 !default;
|
||||
$text-secondary-light-opacity: 0.4 !default;
|
||||
$text-secondary-dark-opacity: 0.8 !default;
|
||||
|
||||
$border-opacity: 0.16 !default;
|
||||
$border-light-opacity: 0.08 !default;
|
||||
$border-dark-opacity: 0.24 !default;
|
||||
$border-active-opacity: 0.58 !default;
|
||||
|
||||
$bg-surface: var(--#{$prefix}white) !default;
|
||||
$bg-surface-secondary: var(--#{$prefix}gray-100) !default;
|
||||
$bg-surface-tertiary: var(--#{$prefix}gray-50) !default;
|
||||
@@ -572,12 +567,8 @@ $bg-surface-dark: var(--#{$prefix}dark) !default;
|
||||
|
||||
$body-text-align: null !default;
|
||||
$body-bg: $gray-50 !default;
|
||||
$body-color: $dark !default;
|
||||
$body-color: $gray-800 !default;
|
||||
$body-emphasis-color: $gray-700 !default;
|
||||
$body-secondary-color: rgba($body-color, 0.75) !default;
|
||||
$body-secondary-bg: $gray-200 !default;
|
||||
$body-tertiary-color: rgba($body-color, 0.5) !default;
|
||||
$body-tertiary-bg: $gray-100 !default;
|
||||
|
||||
$color-contrast-dark: $body-color !default;
|
||||
$color-contrast-light: $light !default;
|
||||
@@ -587,20 +578,27 @@ $text-secondary: $gray-500 !default;
|
||||
$text-secondary-light: $gray-400 !default;
|
||||
$text-secondary-dark: $gray-600 !default;
|
||||
|
||||
$border-color: $gray-200 !default;
|
||||
$border-color-translucent: rgba(4, 32, 69, 0.1);
|
||||
$border-light-color: var(--#{$prefix}gray-200) !default;
|
||||
$border-light-opacity: 4.7% !default;
|
||||
$border-light-color-translucent: color-mix(in srgb, var(--#{$prefix}gray-800) #{$border-light-opacity}, transparent) !default;
|
||||
|
||||
$border-dark-color: $gray-400 !default;
|
||||
$border-dark-color-translucent: rgba(4, 32, 69, 0.27);
|
||||
$border-color: var(--#{$prefix}gray-200) !default;
|
||||
$border-opacity: 11.9% !default;
|
||||
$border-color-translucent: color-mix(in srgb, var(--#{$prefix}gray-800) #{$border-opacity}, transparent) !default;
|
||||
|
||||
$border-active-color: color.mix($text-secondary, #ffffff, math.percentage($border-active-opacity)) !default;
|
||||
$border-active-color-translucent: rgba($text-secondary, $border-active-opacity) !default;
|
||||
$border-dark-color: var(--#{$prefix}gray-300) !default;
|
||||
$border-dark-opacity: 20.7% !default;
|
||||
$border-dark-color-translucent: color-mix(in srgb, var(--#{$prefix}gray-800) #{$border-dark-opacity}, transparent) !default;
|
||||
|
||||
$active-bg: rgba(var(--#{$prefix}primary-rgb), 0.04) !default;
|
||||
$border-active-color: var(--#{$prefix}gray-400) !default;
|
||||
$border-active-opacity: 44.8% !default;
|
||||
$border-active-color-translucent: color-mix(in srgb, var(--#{$prefix}gray-800) #{$border-active-opacity}, transparent) !default;
|
||||
|
||||
$active-bg: color-transparent(var(--#{$prefix}primary), 0.04) !default;
|
||||
$active-color: var(--#{$prefix}primary) !default;
|
||||
$active-border-color: var(--#{$prefix}primary) !default;
|
||||
|
||||
$hover-bg: rgba(var(--#{$prefix}secondary-rgb), 0.08) !default;
|
||||
$hover-bg: color-transparent(var(--#{$prefix}secondary), 0.08) !default;
|
||||
|
||||
$disabled-bg: var(--#{$prefix}bg-surface-secondary) !default;
|
||||
$disabled-color: color-transparent(var(--#{$prefix}body-color), 0.4) !default;
|
||||
@@ -880,7 +878,7 @@ $avatar-sizes: (
|
||||
brand-size: 2rem,
|
||||
),
|
||||
) !default;
|
||||
$avatar-border-radius: var(--#{$prefix}border-radius) !default;
|
||||
$avatar-border-radius: var(--#{$prefix}border-radius-pill) !default;
|
||||
$avatar-font-size: $h4-font-size !default;
|
||||
$avatar-box-shadow: var(--#{$prefix}shadow-border) !default;
|
||||
$avatar-list-spacing: -0.5;
|
||||
@@ -988,14 +986,14 @@ $aspect-ratios: (
|
||||
) !default;
|
||||
|
||||
// Shadows
|
||||
$box-shadow: rgba(var(--#{$prefix}body-color-rgb), 0.04) 0 2px 4px 0 !default;
|
||||
$box-shadow: color-transparent(var(--#{$prefix}body-color), 0.04) 0 2px 4px 0 !default;
|
||||
$box-shadow-sm: 0 0.125rem 0.25rem rgba($black, 0.075) !default;
|
||||
$box-shadow-lg: 0 1rem 3rem rgba($black, 0.175) !default;
|
||||
$box-shadow-transparent: 0 0 0 0 transparent !default;
|
||||
$box-shadow-border: inset 0 0 0 1px var(--#{$prefix}border-color-translucent) !default;
|
||||
$box-shadow-input: 0 1px 1px rgba(var(--#{$prefix}body-color-rgb), 0.06) !default;
|
||||
$box-shadow-card: 0 0 4px rgba(var(--#{$prefix}body-color-rgb), 0.04) !default;
|
||||
$box-shadow-card-hover: rgba(var(--#{$prefix}body-color-rgb), 0.16) 0 2px 16px 0 !default;
|
||||
$box-shadow-input: 0 1px 1px color-transparent(var(--#{$prefix}body-color), 0.06) !default;
|
||||
$box-shadow-card: 0px 1px 3px rgba(0, 0, 0, 0.08) !default;
|
||||
$box-shadow-card-hover: color-transparent(var(--#{$prefix}body-color), 0.16) 0 2px 16px 0 !default;
|
||||
$box-shadow-dropdown:
|
||||
0 16px 24px 2px rgba(0, 0, 0, 0.07),
|
||||
0 6px 30px 5px rgba(0, 0, 0, 0.06),
|
||||
@@ -1020,7 +1018,7 @@ $component-active-bg: $primary !default;
|
||||
// Focus
|
||||
$focus-ring-width: 0.25rem !default;
|
||||
$focus-ring-opacity: 0.25 !default;
|
||||
$focus-ring-color: rgba(var(--#{$prefix}primary-rgb), $focus-ring-opacity) !default;
|
||||
$focus-ring-color: color-mix(in srgb, var(--#{$prefix}primary) #{percentage($focus-ring-opacity)}, transparent) !default;
|
||||
$focus-ring-blur: 0 !default;
|
||||
$focus-ring-box-shadow: 0 0 $focus-ring-blur $focus-ring-width $focus-ring-color !default;
|
||||
|
||||
@@ -1166,9 +1164,9 @@ $btn-padding-y-lg: $input-btn-padding-y-lg !default;
|
||||
$btn-padding-x-lg: $input-btn-padding-x-lg !default;
|
||||
|
||||
// Inputs
|
||||
$input-bg: var(--#{$prefix}body-bg) !default;
|
||||
$input-bg: var(--#{$prefix}bg-forms) !default;
|
||||
$input-disabled-color: null !default;
|
||||
$input-disabled-bg: var(--#{$prefix}secondary-bg) !default;
|
||||
$input-disabled-bg: var(--#{$prefix}bg-surface-secondary) !default;
|
||||
$input-disabled-border-color: null !default;
|
||||
|
||||
$input-height: null !default;
|
||||
@@ -1517,9 +1515,9 @@ $navbar-light-active-color: var(--#{$prefix}body-color) !default;
|
||||
$navbar-light-hover-color: var(--#{$prefix}body-color) !default;
|
||||
$navbar-light-disabled-color: var(--#{$prefix}disabled-color) !default;
|
||||
$navbar-light-active-bg: rgba(0, 0, 0, 0.2) !default;
|
||||
$navbar-light-icon-color: rgba($body-color, 0.75) !default;
|
||||
$navbar-light-icon-color: color-transparent(var(--#{$prefix}body-color), 0.75) !default;
|
||||
$navbar-light-toggler-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'><path stroke='#{$navbar-light-icon-color}' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/></svg>") !default;
|
||||
$navbar-light-toggler-border-color: rgba(var(--#{$prefix}emphasis-color-rgb), 0.15) !default;
|
||||
$navbar-light-toggler-border-color: color-transparent(var(--#{$prefix}emphasis-color), 0.15) !default;
|
||||
$navbar-light-brand-hover-color: $navbar-light-active-color !default;
|
||||
|
||||
$navbar-dark-color: rgba($white, $text-secondary-opacity) !default;
|
||||
@@ -1694,7 +1692,7 @@ $table-active-bg: var(--#{$prefix}active-bg) !default;
|
||||
|
||||
$table-hover-color: $table-color !default;
|
||||
$table-hover-bg-factor: 0.075 !default;
|
||||
$table-hover-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-hover-bg-factor) !default;
|
||||
$table-hover-bg: color-mix(in srgb, var(--#{$prefix}emphasis-color) #{percentage($table-hover-bg-factor)}, transparent) !default;
|
||||
|
||||
$table-caption-color: var(--#{$prefix}secondary-color) !default;
|
||||
|
||||
@@ -1729,7 +1727,7 @@ $toast-box-shadow: var(--#{$prefix}box-shadow) !default;
|
||||
$toast-spacing: $container-padding-x !default;
|
||||
|
||||
$toast-header-color: var(--#{$prefix}gray-500) !default;
|
||||
$toast-header-background-color: rgba(var(--#{$prefix}body-bg-rgb), 0.85) !default;
|
||||
$toast-header-background-color: color-transparent(var(--#{$prefix}body-bg), 0.85) !default;
|
||||
$toast-header-border-color: $toast-border-color !default;
|
||||
|
||||
// Tracking
|
||||
@@ -1774,8 +1772,6 @@ $list-group-action-active-color: var(--#{$prefix}body-color) !default;
|
||||
$list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default;
|
||||
|
||||
// Forms
|
||||
|
||||
$input-bg: var(--#{$prefix}bg-forms) !default;
|
||||
$input-disabled-bg: $disabled-bg !default;
|
||||
$input-border-color: var(--#{$prefix}border-color) !default;
|
||||
$input-border-color-translucent: var(--#{$prefix}border-color-translucent) !default;
|
||||
@@ -1865,16 +1861,16 @@ $form-select-font-size-lg: $input-font-size-lg !default;
|
||||
$form-select-border-radius-lg: $input-border-radius-lg !default;
|
||||
$form-select-transition: $input-transition !default;
|
||||
|
||||
$form-switch-color: rgba($black, 0.25) !default;
|
||||
$form-switch-color: white !default;
|
||||
$form-switch-width: 2rem !default;
|
||||
$form-switch-height: 1.25rem !default;
|
||||
$form-switch-padding-start: $form-switch-width + 0.5rem !default;
|
||||
$form-switch-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$border-color}'/></svg>") !default;
|
||||
$form-switch-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color}'/></svg>") !default;
|
||||
$form-switch-border-radius: $form-switch-width !default;
|
||||
$form-switch-transition: background-position 0.15s ease-in-out !default;
|
||||
$form-switch-focus-color: $input-focus-border-color !default;
|
||||
$form-switch-focus-color: white !default;
|
||||
$form-switch-focus-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-focus-color}'/></svg>") !default;
|
||||
$form-switch-checked-color: $component-active-color !default;
|
||||
$form-switch-checked-color: white !default;
|
||||
$form-switch-checked-bg-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-checked-color}'/></svg>") !default;
|
||||
$form-switch-checked-bg-position: right center !default;
|
||||
$form-switch-bg-size: auto !default;
|
||||
@@ -1960,7 +1956,7 @@ $form-validation-states: (
|
||||
'icon': $form-feedback-icon-valid,
|
||||
'tooltip-color': #fff,
|
||||
'tooltip-bg-color': var(--#{$prefix}success),
|
||||
'focus-box-shadow': 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}success-rgb), $input-btn-focus-color-opacity),
|
||||
'focus-box-shadow': 0 0 $input-btn-focus-blur $input-focus-width color-mix(in srgb, var(--#{$prefix}success) #{percentage($input-btn-focus-color-opacity)}, transparent),
|
||||
'border-color': var(--#{$prefix}form-valid-border-color),
|
||||
),
|
||||
'invalid': (
|
||||
@@ -1968,7 +1964,7 @@ $form-validation-states: (
|
||||
'icon': $form-feedback-icon-invalid,
|
||||
'tooltip-color': #fff,
|
||||
'tooltip-bg-color': var(--#{$prefix}danger),
|
||||
'focus-box-shadow': 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}danger-rgb), $input-btn-focus-color-opacity),
|
||||
'focus-box-shadow': 0 0 $input-btn-focus-blur $input-focus-width color-mix(in srgb, var(--#{$prefix}danger) #{percentage($input-btn-focus-color-opacity)}, transparent),
|
||||
'border-color': var(--#{$prefix}form-invalid-border-color),
|
||||
),
|
||||
) !default;
|
||||
|
||||
@@ -1,184 +1,206 @@
|
||||
@layer root {
|
||||
// Geist Sans Font Family
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-Thin.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Thin.ttf') format('truetype');
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Thin.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Thin.ttf') format('truetype');
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-UltraLight.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-UltraLight.ttf') format('truetype');
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-UltraLight.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-UltraLight.ttf') format('truetype');
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-Light.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Light.ttf') format('truetype');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Light.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Light.ttf') format('truetype');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-Regular.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Regular.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-Medium.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Medium.ttf') format('truetype');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Medium.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Medium.ttf') format('truetype');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-SemiBold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-SemiBold.ttf') format('truetype');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-SemiBold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-SemiBold.ttf') format('truetype');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-Bold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Bold.ttf') format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Bold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Bold.ttf') format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-Black.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Black.ttf') format('truetype');
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Black.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Black.ttf') format('truetype');
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-UltraBlack.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-UltraBlack.ttf') format('truetype');
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-UltraBlack.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-UltraBlack.ttf') format('truetype');
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
// Geist Sans Variable Font
|
||||
@font-face {
|
||||
font-family: 'Geist';
|
||||
src: url('#{$assets-base}/fonts/geist-sans/Geist-Variable.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Variable.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Variable.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-sans/Geist-Variable.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
// Geist Mono Font Family
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-Thin.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Thin.ttf') format('truetype');
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Thin.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Thin.ttf') format('truetype');
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraLight.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraLight.ttf') format('truetype');
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraLight.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraLight.ttf') format('truetype');
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-Light.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Light.ttf') format('truetype');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Light.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Light.ttf') format('truetype');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-Regular.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Regular.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-Medium.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Medium.ttf') format('truetype');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Medium.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Medium.ttf') format('truetype');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-SemiBold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-SemiBold.ttf') format('truetype');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-SemiBold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-SemiBold.ttf') format('truetype');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-Bold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Bold.ttf') format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Bold.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Bold.ttf') format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-Black.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Black.ttf') format('truetype');
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Black.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Black.ttf') format('truetype');
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraBlack.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraBlack.ttf') format('truetype');
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraBlack.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-UltraBlack.ttf') format('truetype');
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
// Geist Mono Variable Font
|
||||
@font-face {
|
||||
font-family: 'Geist Mono';
|
||||
src: url('#{$assets-base}/fonts/geist-mono/GeistMono-Variable.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Variable.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-family: 'Geist Mono';
|
||||
src:
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Variable.woff2') format('woff2'),
|
||||
url('#{$assets-base}/fonts/geist-mono/GeistMono-Variable.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@use 'sass:map';
|
||||
|
||||
@layer helpers {
|
||||
//
|
||||
// Clearfix
|
||||
//
|
||||
@@ -119,7 +120,7 @@
|
||||
content: '';
|
||||
}
|
||||
|
||||
>* {
|
||||
> * {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
@@ -141,4 +142,5 @@
|
||||
outline: 0;
|
||||
// By default, there is no `--bs-focus-ring-x`, `--bs-focus-ring-y`, or `--bs-focus-ring-blur`, but we provide CSS variables with fallbacks to initial `0` values
|
||||
box-shadow: var(--#{$prefix}focus-ring-x, 0) var(--#{$prefix}focus-ring-y, 0) var(--#{$prefix}focus-ring-blur, 0) var(--#{$prefix}focus-ring-width) var(--#{$prefix}focus-ring-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer layout {
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
@@ -96,3 +97,4 @@
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@use 'sass:map';
|
||||
|
||||
@layer layout {
|
||||
html {
|
||||
scrollbar-gutter: stable;
|
||||
|
||||
@@ -74,3 +75,4 @@ body {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
// stylelint-disable declaration-no-important
|
||||
|
||||
@layer layout {
|
||||
@if $enable-dark-mode {
|
||||
:root {
|
||||
&:not(.theme-dark):not([data-bs-theme='dark']) {
|
||||
@@ -67,3 +68,4 @@
|
||||
@extend [data-bs-theme='dark'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer layout {
|
||||
.footer {
|
||||
border-top: var(--#{$prefix}border-width) var(--#{$prefix}border-style) $footer-border-color;
|
||||
background-color: $footer-bg;
|
||||
@@ -14,3 +15,4 @@
|
||||
background-color: transparent;
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,13 +69,14 @@
|
||||
.nav-item.active:after {
|
||||
border-bottom-width: 0;
|
||||
border-inline-start-width: 3px;
|
||||
inset-inline-end: auto;
|
||||
inset-inline-end: auto;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@layer layout {
|
||||
/**
|
||||
Navbar
|
||||
*/
|
||||
@@ -118,7 +119,7 @@ Navbar
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
inset-inline-end: 0.5rem;
|
||||
inset-inline-end: 0.5rem;
|
||||
transform: translate(50%, -50%);
|
||||
}
|
||||
}
|
||||
@@ -151,8 +152,8 @@ Navbar
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
bottom: -0.25rem;
|
||||
border: 0 var(--#{$prefix}border-style) var(--#{$prefix}navbar-active-border-color);
|
||||
border-bottom-width: 2px;
|
||||
@@ -235,7 +236,7 @@ Navbar toggler
|
||||
border-radius: inherit;
|
||||
background: inherit;
|
||||
position: absolute;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-start: 0;
|
||||
@include transition(inherit);
|
||||
}
|
||||
|
||||
@@ -313,7 +314,7 @@ Navbar vertical
|
||||
width: $sidebar-width;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-start: 0;
|
||||
bottom: 0;
|
||||
z-index: $zindex-fixed;
|
||||
align-items: start;
|
||||
@@ -323,8 +324,8 @@ Navbar vertical
|
||||
|
||||
&.navbar-right,
|
||||
&.navbar-end {
|
||||
inset-inline-start: auto;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: auto;
|
||||
inset-inline-end: 0;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
@@ -384,10 +385,11 @@ Navbar vertical
|
||||
height: $navbar-overlap-height;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
background: inherit;
|
||||
z-index: -1;
|
||||
box-shadow: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer layout {
|
||||
.page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -67,8 +68,8 @@
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
bottom: 0;
|
||||
background-image: $overlay-gradient;
|
||||
}
|
||||
@@ -167,3 +168,4 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer root {
|
||||
:root,
|
||||
:host {
|
||||
font-size: 16px;
|
||||
@@ -33,7 +34,10 @@
|
||||
--#{$prefix}border-color-translucent: #{$border-color-translucent};
|
||||
--#{$prefix}border-dark-color: #{$border-dark-color};
|
||||
--#{$prefix}border-dark-color-translucent: #{$border-dark-color-translucent};
|
||||
--#{$prefix}border-light-color: #{$border-light-color};
|
||||
--#{$prefix}border-light-color-translucent: #{$border-light-color-translucent};
|
||||
--#{$prefix}border-active-color: #{$border-active-color};
|
||||
--#{$prefix}border-active-color-translucent: #{$border-active-color-translucent};
|
||||
|
||||
--#{$prefix}icon-color: #{$icon-color};
|
||||
|
||||
@@ -57,3 +61,4 @@
|
||||
--#{$prefix}page-padding: #{$page-padding-sm};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,71 @@
|
||||
//
|
||||
// Browser
|
||||
//
|
||||
.browser {
|
||||
border-radius: var(--#{$prefix}border-radius-lg);
|
||||
box-shadow: 0 0 0 1px var(--#{$prefix}border-color);
|
||||
background: var(--#{$prefix}bg-surface-secondary);
|
||||
overflow: hidden;
|
||||
}
|
||||
@layer components {
|
||||
.browser {
|
||||
border-radius: var(--#{$prefix}border-radius-lg);
|
||||
box-shadow: 0 0 0 1px var(--#{$prefix}border-color);
|
||||
background: var(--#{$prefix}bg-surface-secondary);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.browser-header {
|
||||
padding: 0.25rem 1rem;
|
||||
background: var(--#{$prefix}border-color-light) linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.03));
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||
border-radius: calc(var(--#{$prefix}border-radius-lg) - 1px) calc(var(--#{$prefix}border-radius-lg) - 1px) 0 0;
|
||||
}
|
||||
.browser-header {
|
||||
padding: 0.25rem 1rem;
|
||||
background: var(--#{$prefix}border-color-light) linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.03));
|
||||
border-bottom: 1px solid var(--#{$prefix}border-color);
|
||||
border-radius: calc(var(--#{$prefix}border-radius-lg) - 1px) calc(var(--#{$prefix}border-radius-lg) - 1px) 0 0;
|
||||
}
|
||||
|
||||
.browser-dots {
|
||||
margin-inline-end: 3rem;
|
||||
display: flex;
|
||||
}
|
||||
.browser-dots {
|
||||
margin-inline-end: 3rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.browser-dots-colored {
|
||||
.browser-dot {
|
||||
&:nth-child(1) {
|
||||
background: #fb6058;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
background: #fcbe3b;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
background: #2ccb4c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.browser-dots-colored {
|
||||
.browser-dot {
|
||||
&:nth-child(1) {
|
||||
background: #fb6058;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
background: #fcbe3b;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
background: #2ccb4c;
|
||||
}
|
||||
margin-inline-end: 0.5rem;
|
||||
width: 0.75rem;
|
||||
min-width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
background: var(--#{$prefix}border-color);
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--#{$prefix}border-color-dark);
|
||||
}
|
||||
}
|
||||
|
||||
.browser-dot {
|
||||
margin-inline-end: 0.5rem;
|
||||
width: 0.75rem;
|
||||
min-width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
background: var(--#{$prefix}border-color);
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--#{$prefix}border-color-dark);
|
||||
}
|
||||
|
||||
.browser-input {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
padding: 0.25rem;
|
||||
color: var(--#{$prefix}secondary);
|
||||
font-size: var(--#{$prefix}font-size-h5);
|
||||
border-radius: var(--#{$prefix}border-radius);
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(0, 0, 0, 0.05),
|
||||
0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
background-image: linear-gradient(to bottom, var(--#{$prefix}bg-surface), var(--#{$prefix}bg-surface-secondary));
|
||||
|
||||
&:hover {
|
||||
.browser-input {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
padding: 0.25rem;
|
||||
color: var(--#{$prefix}secondary);
|
||||
font-size: var(--#{$prefix}font-size-h5);
|
||||
border-radius: var(--#{$prefix}border-radius);
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(0, 0, 0, 0.05),
|
||||
0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
background-image: linear-gradient(to bottom, var(--#{$prefix}bg-surface), var(--#{$prefix}bg-surface-secondary));
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
.body-marketing {
|
||||
--#{$prefix}body-font-size: 1rem;
|
||||
--#{$prefix}body-line-height: 1.75;
|
||||
}
|
||||
@layer components {
|
||||
.body-marketing {
|
||||
--#{$prefix}body-font-size: 1rem;
|
||||
--#{$prefix}body-line-height: 1.75;
|
||||
}
|
||||
|
||||
.body-gradient {
|
||||
background: var(--#{$prefix}bg-surface) linear-gradient(to bottom, var(--#{$prefix}bg-surface-secondary) 12%, var(--#{$prefix}bg-surface) 99%) repeat-x top center/100% 100vh;
|
||||
.body-gradient {
|
||||
background: var(--#{$prefix}bg-surface) linear-gradient(to bottom, var(--#{$prefix}bg-surface-secondary) 12%, var(--#{$prefix}bg-surface) 99%) repeat-x top center/100% 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,71 @@
|
||||
//
|
||||
// Hero
|
||||
//
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 6.5rem 0;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 3rem;
|
||||
font-weight: var(--#{$prefix}font-weight-black);
|
||||
letter-spacing: $spacing-tight;
|
||||
line-height: $headings-line-height;
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
font-size: 2rem;
|
||||
@layer components {
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 6.5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-description {
|
||||
color: var(--#{$prefix}secondary);
|
||||
font-size: var(--#{$prefix}font-size-h2);
|
||||
line-height: 1.5;
|
||||
margin: 0 auto;
|
||||
max-width: 45rem;
|
||||
.hero-title {
|
||||
font-size: 3rem;
|
||||
font-weight: var(--#{$prefix}font-weight-black);
|
||||
letter-spacing: $spacing-tight;
|
||||
line-height: $headings-line-height;
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
font-size: var(--#{$prefix}font-size-h3);
|
||||
@include media-breakpoint-down(md) {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hero-description-wide {
|
||||
max-width: 61.875rem;
|
||||
}
|
||||
.hero-description {
|
||||
color: var(--#{$prefix}secondary);
|
||||
font-size: var(--#{$prefix}font-size-h2);
|
||||
line-height: 1.5;
|
||||
margin: 0 auto;
|
||||
max-width: 45rem;
|
||||
|
||||
//
|
||||
// Hero subheader
|
||||
//
|
||||
.hero-subheader {
|
||||
@include subheader;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
@include media-breakpoint-down(sm) {
|
||||
font-size: var(--#{$prefix}font-size-h3);
|
||||
}
|
||||
}
|
||||
|
||||
.hero-img {
|
||||
margin: 4rem auto;
|
||||
max-width: 65rem;
|
||||
border-radius: $border-radius-lg;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
//box-shadow: 0 10px 15px -3px rgba($color-text, 0.1),
|
||||
// 0 4px 6px -2px rgba($color-text, 0.05);
|
||||
.hero-description-wide {
|
||||
max-width: 61.875rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
//
|
||||
// Hero subheader
|
||||
//
|
||||
.hero-subheader {
|
||||
@include subheader;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.hero-img {
|
||||
margin: 4rem auto;
|
||||
max-width: 65rem;
|
||||
border-radius: $border-radius-lg;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
//box-shadow: 0 10px 15px -3px rgba($color-text, 0.1),
|
||||
// 0 4px 6px -2px rgba($color-text, 0.05);
|
||||
|
||||
img,
|
||||
svg {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
//
|
||||
//.hero-img-side {
|
||||
// img,
|
||||
// svg {
|
||||
// max-width: 100%;
|
||||
// height: auto;
|
||||
// display: block;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
//
|
||||
//.hero-img-side {
|
||||
// img,
|
||||
// svg {
|
||||
// max-width: 100%;
|
||||
// height: auto;
|
||||
// display: block;
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -1,111 +1,113 @@
|
||||
$pricing-card-width: 22rem;
|
||||
|
||||
.pricing {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
justify-content: center;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.pricing-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--#{$prefix}bg-surface);
|
||||
border: 1px solid $border-color;
|
||||
padding: 2rem;
|
||||
margin: 0 0 1rem;
|
||||
position: relative;
|
||||
box-shadow: $box-shadow-card;
|
||||
text-align: center;
|
||||
border-radius: $border-radius-lg;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
margin: 1rem -1px;
|
||||
max-width: $pricing-card-width;
|
||||
|
||||
&:first-child {
|
||||
border-radius: $border-radius-lg 0 0 $border-radius-lg;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 $border-radius-lg $border-radius-lg 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.featured {
|
||||
z-index: 1;
|
||||
border: 2px solid var(--#{$prefix}primary);
|
||||
order: -1;
|
||||
@layer components {
|
||||
.pricing {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
justify-content: center;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
order: unset;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
box-shadow: $box-shadow-card;
|
||||
border-radius: $border-radius-lg;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.pricing-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--#{$prefix}bg-surface);
|
||||
border: 1px solid $border-color;
|
||||
padding: 2rem;
|
||||
margin: 0 0 1rem;
|
||||
position: relative;
|
||||
box-shadow: $box-shadow-card;
|
||||
text-align: center;
|
||||
border-radius: $border-radius-lg;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
margin: 1rem -1px;
|
||||
max-width: $pricing-card-width;
|
||||
|
||||
&:first-child {
|
||||
border-radius: $border-radius-lg 0 0 $border-radius-lg;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 $border-radius-lg $border-radius-lg 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.featured {
|
||||
z-index: 1;
|
||||
border: 2px solid var(--#{$prefix}primary);
|
||||
order: -1;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
order: unset;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
box-shadow: $box-shadow-card;
|
||||
border-radius: $border-radius-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pricing-title {
|
||||
font-size: $h2-font-size;
|
||||
line-height: $h2-line-height;
|
||||
}
|
||||
|
||||
.pricing-label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
transform: translateY(-50%);
|
||||
vertical-align: bottom;
|
||||
inset-inline-end: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pricing-btn {
|
||||
margin-top: auto;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
.pricing-price {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 2.5rem;
|
||||
line-height: 1;
|
||||
font-weight: $font-weight-semibold;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
|
||||
.pricing-price-currency {
|
||||
font-size: $h2-font-size;
|
||||
line-height: 1.5;
|
||||
margin-inline-end: 0.25rem;
|
||||
font-weight: $font-weight-semibold;
|
||||
}
|
||||
|
||||
.pricing-price-description {
|
||||
font-size: $h4-font-size;
|
||||
line-height: $h4-line-height;
|
||||
font-weight: $font-weight-normal;
|
||||
color: $text-secondary;
|
||||
align-self: center;
|
||||
margin-inline-start: 0.5rem;
|
||||
}
|
||||
|
||||
.pricing-features {
|
||||
margin: 1rem 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
text-align: start;
|
||||
|
||||
> li:not(:first-child) {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pricing-title {
|
||||
font-size: $h2-font-size;
|
||||
line-height: $h2-line-height;
|
||||
}
|
||||
|
||||
.pricing-label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-start: 0;
|
||||
transform: translateY(-50%);
|
||||
vertical-align: bottom;
|
||||
inset-inline-end: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pricing-btn {
|
||||
margin-top: auto;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
.pricing-price {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 2.5rem;
|
||||
line-height: 1;
|
||||
font-weight: $font-weight-semibold;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
|
||||
.pricing-price-currency {
|
||||
font-size: $h2-font-size;
|
||||
line-height: 1.5;
|
||||
margin-inline-end: 0.25rem;
|
||||
font-weight: $font-weight-semibold;
|
||||
}
|
||||
|
||||
.pricing-price-description {
|
||||
font-size: $h4-font-size;
|
||||
line-height: $h4-line-height;
|
||||
font-weight: $font-weight-normal;
|
||||
color: $text-secondary;
|
||||
align-self: center;
|
||||
margin-inline-start: 0.5rem;
|
||||
}
|
||||
|
||||
.pricing-features {
|
||||
margin: 1rem 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
text-align: start;
|
||||
|
||||
> li:not(:first-child) {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,124 +1,126 @@
|
||||
@keyframes move-forever1 {
|
||||
0% {
|
||||
transform: translate(85px, 0%);
|
||||
@layer components {
|
||||
@keyframes move-forever1 {
|
||||
0% {
|
||||
transform: translate(85px, 0%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(-90px, 0%);
|
||||
}
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(-90px, 0%);
|
||||
}
|
||||
}
|
||||
@keyframes move-forever2 {
|
||||
0% {
|
||||
transform: translate(-90px, 0%);
|
||||
}
|
||||
|
||||
@keyframes move-forever2 {
|
||||
0% {
|
||||
transform: translate(-90px, 0%);
|
||||
100% {
|
||||
transform: translate(85px, 0%);
|
||||
}
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(85px, 0%);
|
||||
}
|
||||
}
|
||||
@keyframes move-forever3 {
|
||||
0% {
|
||||
transform: translate(-90px, 0%);
|
||||
}
|
||||
|
||||
@keyframes move-forever3 {
|
||||
0% {
|
||||
transform: translate(-90px, 0%);
|
||||
100% {
|
||||
transform: translate(85px, 0%);
|
||||
}
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(85px, 0%);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Sections
|
||||
//
|
||||
.section {
|
||||
--section-bg: transparent;
|
||||
background: var(--section-bg);
|
||||
position: relative;
|
||||
padding: 5rem 0;
|
||||
}
|
||||
|
||||
.section-sm {
|
||||
padding: 4rem 0;
|
||||
}
|
||||
|
||||
.section-white {
|
||||
--section-bg: var(--#{$prefix}bg-surface);
|
||||
}
|
||||
|
||||
.section-light {
|
||||
--section-bg: var(--#{$prefix}bg-surface-secondary);
|
||||
}
|
||||
|
||||
.section-primary {
|
||||
--section-bg: var(--#{$prefix}primary);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.section-dark {
|
||||
--section-bg: var(--#{$prefix}dark);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
text-align: center;
|
||||
max-width: 45rem;
|
||||
margin: 0 auto 5rem;
|
||||
|
||||
@at-root .section-sm & {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: var(--#{$prefix}font-size-h1);
|
||||
font-weight: var(--#{$prefix}font-weight-semibold);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.section-title-lg {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.section-description {
|
||||
color: var(--#{$prefix}secondary);
|
||||
font-size: var(--#{$prefix}font-size-h3);
|
||||
line-height: var(--#{$prefix}line-height-h3);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
//
|
||||
// Section divider
|
||||
//
|
||||
.section-divider {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
pointer-events: none;
|
||||
height: 5rem;
|
||||
width: 100%;
|
||||
|
||||
path {
|
||||
fill: var(--section-bg);
|
||||
//
|
||||
// Sections
|
||||
//
|
||||
.section {
|
||||
--section-bg: transparent;
|
||||
background: var(--section-bg);
|
||||
position: relative;
|
||||
padding: 5rem 0;
|
||||
}
|
||||
|
||||
.wave-1 {
|
||||
animation: move-forever1 30s linear infinite;
|
||||
animation-delay: -2s;
|
||||
.section-sm {
|
||||
padding: 4rem 0;
|
||||
}
|
||||
|
||||
.wave-2 {
|
||||
animation: move-forever2 24s linear infinite;
|
||||
opacity: 0.5;
|
||||
animation-delay: -2s;
|
||||
.section-white {
|
||||
--section-bg: var(--#{$prefix}bg-surface);
|
||||
}
|
||||
|
||||
.wave-3 {
|
||||
animation: move-forever3 18s linear infinite;
|
||||
opacity: 0.3;
|
||||
animation-delay: -2s;
|
||||
.section-light {
|
||||
--section-bg: var(--#{$prefix}bg-surface-secondary);
|
||||
}
|
||||
|
||||
.section-primary {
|
||||
--section-bg: var(--#{$prefix}primary);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.section-dark {
|
||||
--section-bg: var(--#{$prefix}dark);
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
text-align: center;
|
||||
max-width: 45rem;
|
||||
margin: 0 auto 5rem;
|
||||
|
||||
@at-root .section-sm & {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: var(--#{$prefix}font-size-h1);
|
||||
font-weight: var(--#{$prefix}font-weight-semibold);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.section-title-lg {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.section-description {
|
||||
color: var(--#{$prefix}secondary);
|
||||
font-size: var(--#{$prefix}font-size-h3);
|
||||
line-height: var(--#{$prefix}line-height-h3);
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
//
|
||||
// Section divider
|
||||
//
|
||||
.section-divider {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
pointer-events: none;
|
||||
height: 5rem;
|
||||
width: 100%;
|
||||
|
||||
path {
|
||||
fill: var(--section-bg);
|
||||
}
|
||||
|
||||
.wave-1 {
|
||||
animation: move-forever1 30s linear infinite;
|
||||
animation-delay: -2s;
|
||||
}
|
||||
|
||||
.wave-2 {
|
||||
animation: move-forever2 24s linear infinite;
|
||||
opacity: 0.5;
|
||||
animation-delay: -2s;
|
||||
}
|
||||
|
||||
.wave-3 {
|
||||
animation: move-forever3 18s linear infinite;
|
||||
opacity: 0.3;
|
||||
animation-delay: -2s;
|
||||
}
|
||||
}
|
||||
|
||||
.section-divider-auto {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.section-divider-auto {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,35 @@
|
||||
@use 'sass:map';
|
||||
|
||||
.shape {
|
||||
--#{$prefix}shape-size: #{$avatar-size};
|
||||
--#{$prefix}shape-icon-size: #{$avatar-icon-size};
|
||||
background-color: var(--#{$prefix}primary-lt);
|
||||
color: var(--#{$prefix}primary);
|
||||
border-radius: 35%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: var(--#{$prefix}shape-size);
|
||||
width: var(--#{$prefix}shape-size);
|
||||
@layer components {
|
||||
.shape {
|
||||
--#{$prefix}shape-size: #{$avatar-size};
|
||||
--#{$prefix}shape-icon-size: #{$avatar-icon-size};
|
||||
background-color: var(--#{$prefix}primary-lt);
|
||||
color: var(--#{$prefix}primary);
|
||||
border-radius: 35%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: var(--#{$prefix}shape-size);
|
||||
width: var(--#{$prefix}shape-size);
|
||||
|
||||
.icon {
|
||||
width: var(--#{$prefix}shape-icon-size);
|
||||
height: var(--#{$prefix}shape-icon-size);
|
||||
}
|
||||
}
|
||||
|
||||
@each $avatar-size, $size in $avatar-sizes {
|
||||
.shape-#{$avatar-size} {
|
||||
--#{$prefix}shape-size: #{map.get($size, size)};
|
||||
--#{$prefix}shape-icon-size: #{map.get($size, icon-size)};
|
||||
}
|
||||
}
|
||||
|
||||
@each $name, $color in $colors {
|
||||
.shape-#{$name} {
|
||||
background: var(--#{$prefix}#{$name}-lt);
|
||||
color: var(--#{$prefix}#{$name});
|
||||
.icon {
|
||||
width: var(--#{$prefix}shape-icon-size);
|
||||
height: var(--#{$prefix}shape-icon-size);
|
||||
}
|
||||
}
|
||||
|
||||
@each $avatar-size, $size in $avatar-sizes {
|
||||
.shape-#{$avatar-size} {
|
||||
--#{$prefix}shape-size: #{map.get($size, size)};
|
||||
--#{$prefix}shape-icon-size: #{map.get($size, icon-size)};
|
||||
}
|
||||
}
|
||||
|
||||
@each $name, $color in $colors {
|
||||
.shape-#{$name} {
|
||||
background: var(--#{$prefix}#{$name}-lt);
|
||||
color: var(--#{$prefix}#{$name});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,18 +138,20 @@
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// stylelint-disable scss/dollar-variable-pattern
|
||||
@function rgba-css-var($identifier, $target) {
|
||||
@if $identifier == 'body' and $target == 'bg' {
|
||||
@return rgba(var(--#{$prefix}#{$identifier}-bg-rgb), var(--#{$prefix}#{$target}-opacity));
|
||||
@return color-mix(in srgb, var(--#{$prefix}#{$identifier}-bg) calc(var(--#{$prefix}#{$target}-opacity) * 100%), transparent);
|
||||
}
|
||||
@if $identifier == 'body' and $target == 'text' {
|
||||
@return rgba(var(--#{$prefix}#{$identifier}-color-rgb), var(--#{$prefix}#{$target}-opacity));
|
||||
@return color-mix(in srgb, var(--#{$prefix}#{$identifier}-color) calc(var(--#{$prefix}#{$target}-opacity) * 100%), transparent);
|
||||
} @else {
|
||||
@return rgba(var(--#{$prefix}#{$identifier}-rgb), var(--#{$prefix}#{$target}-opacity));
|
||||
@return color-mix(in srgb, var(--#{$prefix}#{$identifier}) calc(var(--#{$prefix}#{$target}-opacity) * 100%), transparent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +59,10 @@
|
||||
|
||||
@mixin focus-ring($show-border: false) {
|
||||
outline: 0;
|
||||
box-shadow: 0 0 $focus-ring-blur $focus-ring-width rgba(var(--#{$prefix}primary-rgb), 0.25);
|
||||
box-shadow: 0 0 $focus-ring-blur $focus-ring-width color-transparent(var(--#{$prefix}primary), 0.25);
|
||||
|
||||
@if ($show-border) {
|
||||
border-color: rgba(var(--#{$prefix}primary-rgb), 0.25);
|
||||
border-color: color-transparent(var(--#{$prefix}primary), 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
@use 'layers';
|
||||
|
||||
@import 'ui/flags';
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use 'layers';
|
||||
|
||||
@import 'config';
|
||||
@import 'variables';
|
||||
@import 'utilities-marketing';
|
||||
@@ -10,4 +12,6 @@
|
||||
@import 'marketing/pricing';
|
||||
@import 'marketing/shape';
|
||||
|
||||
@import 'bootstrap/scss/utilities/api';
|
||||
@layer utilities {
|
||||
@import 'bootstrap/scss/utilities/api';
|
||||
}
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
@use 'layers';
|
||||
|
||||
@forward 'ui/payments';
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
@use 'layers';
|
||||
|
||||
@import 'props';
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
@use 'layers';
|
||||
|
||||
@import 'ui/social';
|
||||
|
||||
@@ -1,121 +1,125 @@
|
||||
@use 'layers';
|
||||
|
||||
@import 'config';
|
||||
|
||||
[data-bs-theme-base='slate'] {
|
||||
--#{$prefix}gray-50: #f8fafc;
|
||||
--#{$prefix}gray-100: #f1f5f9;
|
||||
--#{$prefix}gray-200: #e2e8f0;
|
||||
--#{$prefix}gray-300: #cbd5e1;
|
||||
--#{$prefix}gray-400: #94a3b8;
|
||||
--#{$prefix}gray-500: #64748b;
|
||||
--#{$prefix}gray-600: #475569;
|
||||
--#{$prefix}gray-700: #334155;
|
||||
--#{$prefix}gray-800: #1e293b;
|
||||
--#{$prefix}gray-900: #0f172a;
|
||||
--#{$prefix}gray-950: #020617;
|
||||
}
|
||||
|
||||
[data-bs-theme-base='gray'] {
|
||||
--#{$prefix}gray-50: #f9fafb;
|
||||
--#{$prefix}gray-100: #f3f4f6;
|
||||
--#{$prefix}gray-200: #e5e7eb;
|
||||
--#{$prefix}gray-300: #d1d5db;
|
||||
--#{$prefix}gray-400: #9ca3af;
|
||||
--#{$prefix}gray-500: #6b7280;
|
||||
--#{$prefix}gray-600: #4b5563;
|
||||
--#{$prefix}gray-700: #374151;
|
||||
--#{$prefix}gray-800: #1f2937;
|
||||
--#{$prefix}gray-900: #111827;
|
||||
--#{$prefix}gray-950: #030712;
|
||||
}
|
||||
|
||||
[data-bs-theme-base='zinc'] {
|
||||
--#{$prefix}gray-50: #fafafa;
|
||||
--#{$prefix}gray-100: #f4f4f5;
|
||||
--#{$prefix}gray-200: #e4e4e7;
|
||||
--#{$prefix}gray-300: #d4d4d8;
|
||||
--#{$prefix}gray-400: #a1a1aa;
|
||||
--#{$prefix}gray-500: #71717a;
|
||||
--#{$prefix}gray-600: #52525b;
|
||||
--#{$prefix}gray-700: #3f3f46;
|
||||
--#{$prefix}gray-800: #27272a;
|
||||
--#{$prefix}gray-900: #18181b;
|
||||
--#{$prefix}gray-950: #09090b;
|
||||
}
|
||||
|
||||
[data-bs-theme-base='neutral'] {
|
||||
--#{$prefix}gray-50: #fafafa;
|
||||
--#{$prefix}gray-100: #f5f5f5;
|
||||
--#{$prefix}gray-200: #e5e5e5;
|
||||
--#{$prefix}gray-300: #d4d4d4;
|
||||
--#{$prefix}gray-400: #a3a3a3;
|
||||
--#{$prefix}gray-500: #737373;
|
||||
--#{$prefix}gray-600: #525252;
|
||||
--#{$prefix}gray-700: #404040;
|
||||
--#{$prefix}gray-800: #262626;
|
||||
--#{$prefix}gray-900: #171717;
|
||||
--#{$prefix}gray-950: #0a0a0a;
|
||||
}
|
||||
|
||||
[data-bs-theme-base='stone'] {
|
||||
--#{$prefix}gray-50: #fafaf9;
|
||||
--#{$prefix}gray-100: #f5f5f4;
|
||||
--#{$prefix}gray-200: #e7e5e4;
|
||||
--#{$prefix}gray-300: #d6d3d1;
|
||||
--#{$prefix}gray-400: #a8a29e;
|
||||
--#{$prefix}gray-500: #78716c;
|
||||
--#{$prefix}gray-600: #57534e;
|
||||
--#{$prefix}gray-700: #44403c;
|
||||
--#{$prefix}gray-800: #292524;
|
||||
--#{$prefix}gray-900: #1c1917;
|
||||
--#{$prefix}gray-950: #0c0a09;
|
||||
}
|
||||
|
||||
[data-bs-theme-base='pink'] {
|
||||
--#{$prefix}gray-50: #fdf2f8;
|
||||
--#{$prefix}gray-100: #fce7f3;
|
||||
--#{$prefix}gray-200: #fbcfe8;
|
||||
--#{$prefix}gray-300: #f9a8d4;
|
||||
--#{$prefix}gray-400: #f472b6;
|
||||
--#{$prefix}gray-500: #ec4899;
|
||||
--#{$prefix}gray-600: #db2777;
|
||||
--#{$prefix}gray-700: #be185d;
|
||||
--#{$prefix}gray-800: #9d174d;
|
||||
--#{$prefix}gray-900: #831843;
|
||||
--#{$prefix}gray-950: #500724;
|
||||
}
|
||||
|
||||
@each $name, $value in $extra-colors {
|
||||
[data-bs-theme-primary='#{$name}'] {
|
||||
--#{$prefix}primary: #{$value};
|
||||
--#{$prefix}primary-rgb: #{to-rgb($value)};
|
||||
@layer theme {
|
||||
[data-bs-theme-base='slate'] {
|
||||
--#{$prefix}gray-50: #f8fafc;
|
||||
--#{$prefix}gray-100: #f1f5f9;
|
||||
--#{$prefix}gray-200: #e2e8f0;
|
||||
--#{$prefix}gray-300: #cbd5e1;
|
||||
--#{$prefix}gray-400: #94a3b8;
|
||||
--#{$prefix}gray-500: #64748b;
|
||||
--#{$prefix}gray-600: #475569;
|
||||
--#{$prefix}gray-700: #334155;
|
||||
--#{$prefix}gray-800: #1e293b;
|
||||
--#{$prefix}gray-900: #0f172a;
|
||||
--#{$prefix}gray-950: #020617;
|
||||
}
|
||||
}
|
||||
|
||||
@each $value in (0, 0.5, 1, 1.5, 2) {
|
||||
[data-bs-theme-radius='#{$value}'] {
|
||||
--#{$prefix}border-radius-scale: #{$value};
|
||||
[data-bs-theme-base='gray'] {
|
||||
--#{$prefix}gray-50: $gray-50;
|
||||
--#{$prefix}gray-100: $gray-100;
|
||||
--#{$prefix}gray-200: $gray-200;
|
||||
--#{$prefix}gray-300: $gray-300;
|
||||
--#{$prefix}gray-400: $gray-400;
|
||||
--#{$prefix}gray-500: $gray-500;
|
||||
--#{$prefix}gray-600: $gray-600;
|
||||
--#{$prefix}gray-700: $gray-700;
|
||||
--#{$prefix}gray-800: $gray-800;
|
||||
--#{$prefix}gray-900: $gray-900;
|
||||
--#{$prefix}gray-950: $gray-950;
|
||||
}
|
||||
}
|
||||
|
||||
[data-bs-theme-primary='inverted'] {
|
||||
--#{$prefix}primary: var(--#{$prefix}gray-800);
|
||||
--#{$prefix}primary-fg: var(--#{$prefix}light);
|
||||
--#{$prefix}primary-rgb: #{to-rgb($dark)};
|
||||
|
||||
&[data-bs-theme='dark'],
|
||||
[data-bs-theme='dark'] {
|
||||
--#{$prefix}primary: #{$light};
|
||||
--#{$prefix}primary-fg: var(--#{$prefix}dark);
|
||||
--#{$prefix}primary-rgb: #{to-rgb($light)};
|
||||
[data-bs-theme-base='zinc'] {
|
||||
--#{$prefix}gray-50: #fafafa;
|
||||
--#{$prefix}gray-100: #f4f4f5;
|
||||
--#{$prefix}gray-200: #e4e4e7;
|
||||
--#{$prefix}gray-300: #d4d4d8;
|
||||
--#{$prefix}gray-400: #a1a1aa;
|
||||
--#{$prefix}gray-500: #71717a;
|
||||
--#{$prefix}gray-600: #52525b;
|
||||
--#{$prefix}gray-700: #3f3f46;
|
||||
--#{$prefix}gray-800: #27272a;
|
||||
--#{$prefix}gray-900: #18181b;
|
||||
--#{$prefix}gray-950: #09090b;
|
||||
}
|
||||
}
|
||||
|
||||
@each $name, $value in (monospace: $font-family-monospace, sans-serif: $font-family-sans-serif, serif: $font-family-serif, comic: $font-family-comic) {
|
||||
[data-bs-theme-font='#{$name}'] {
|
||||
--#{$prefix}body-font-family: var(--#{$prefix}font-#{$name});
|
||||
[data-bs-theme-base='neutral'] {
|
||||
--#{$prefix}gray-50: #fafafa;
|
||||
--#{$prefix}gray-100: #f5f5f5;
|
||||
--#{$prefix}gray-200: #e5e5e5;
|
||||
--#{$prefix}gray-300: #d4d4d4;
|
||||
--#{$prefix}gray-400: #a3a3a3;
|
||||
--#{$prefix}gray-500: #737373;
|
||||
--#{$prefix}gray-600: #525252;
|
||||
--#{$prefix}gray-700: #404040;
|
||||
--#{$prefix}gray-800: #262626;
|
||||
--#{$prefix}gray-900: #171717;
|
||||
--#{$prefix}gray-950: #0a0a0a;
|
||||
}
|
||||
|
||||
@if $name == 'monospace' {
|
||||
--#{$prefix}body-font-size: 80%;
|
||||
[data-bs-theme-base='stone'] {
|
||||
--#{$prefix}gray-50: #fafaf9;
|
||||
--#{$prefix}gray-100: #f5f5f4;
|
||||
--#{$prefix}gray-200: #e7e5e4;
|
||||
--#{$prefix}gray-300: #d6d3d1;
|
||||
--#{$prefix}gray-400: #a8a29e;
|
||||
--#{$prefix}gray-500: #78716c;
|
||||
--#{$prefix}gray-600: #57534e;
|
||||
--#{$prefix}gray-700: #44403c;
|
||||
--#{$prefix}gray-800: #292524;
|
||||
--#{$prefix}gray-900: #1c1917;
|
||||
--#{$prefix}gray-950: #0c0a09;
|
||||
}
|
||||
|
||||
[data-bs-theme-base='pink'] {
|
||||
--#{$prefix}gray-50: #fdf2f8;
|
||||
--#{$prefix}gray-100: #fce7f3;
|
||||
--#{$prefix}gray-200: #fbcfe8;
|
||||
--#{$prefix}gray-300: #f9a8d4;
|
||||
--#{$prefix}gray-400: #f472b6;
|
||||
--#{$prefix}gray-500: #ec4899;
|
||||
--#{$prefix}gray-600: #db2777;
|
||||
--#{$prefix}gray-700: #be185d;
|
||||
--#{$prefix}gray-800: #9d174d;
|
||||
--#{$prefix}gray-900: #831843;
|
||||
--#{$prefix}gray-950: #500724;
|
||||
}
|
||||
|
||||
@each $name, $value in $extra-colors {
|
||||
[data-bs-theme-primary='#{$name}'] {
|
||||
--#{$prefix}primary: #{$value};
|
||||
--#{$prefix}primary-rgb: #{to-rgb($value)};
|
||||
}
|
||||
}
|
||||
|
||||
@each $value in (0, 0.5, 1, 1.5, 2) {
|
||||
[data-bs-theme-radius='#{$value}'] {
|
||||
--#{$prefix}border-radius-scale: #{$value};
|
||||
}
|
||||
}
|
||||
|
||||
[data-bs-theme-primary='inverted'] {
|
||||
--#{$prefix}primary: var(--#{$prefix}gray-800);
|
||||
--#{$prefix}primary-fg: var(--#{$prefix}light);
|
||||
--#{$prefix}primary-rgb: #{to-rgb($dark)};
|
||||
|
||||
&[data-bs-theme='dark'],
|
||||
[data-bs-theme='dark'] {
|
||||
--#{$prefix}primary: #{$light};
|
||||
--#{$prefix}primary-fg: var(--#{$prefix}dark);
|
||||
--#{$prefix}primary-rgb: #{to-rgb($light)};
|
||||
}
|
||||
}
|
||||
|
||||
@each $name, $value in (monospace: $font-family-monospace, sans-serif: $font-family-sans-serif, serif: $font-family-serif, comic: $font-family-comic) {
|
||||
[data-bs-theme-font='#{$name}'] {
|
||||
--#{$prefix}body-font-family: var(--#{$prefix}font-#{$name});
|
||||
|
||||
@if $name == 'monospace' {
|
||||
--#{$prefix}body-font-size: 80%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
@use 'layers';
|
||||
|
||||
@import 'config';
|
||||
|
||||
@import 'vendor/nouislider';
|
||||
@import 'vendor/litepicker';
|
||||
@import 'vendor/tom-select';
|
||||
@import 'vendor/apexcharts';
|
||||
@import 'vendor/jsvectormap';
|
||||
@import 'vendor/dropzone';
|
||||
@import 'vendor/fslightbox';
|
||||
@import 'vendor/plyr';
|
||||
@import 'vendor/wysiwyg';
|
||||
@import 'vendor/stars-rating';
|
||||
@import 'vendor/coloris';
|
||||
@import 'vendor/typed';
|
||||
@import 'vendor/turbo';
|
||||
@import 'vendor/fullcalendar';
|
||||
@layer components {
|
||||
@import 'vendor/nouislider';
|
||||
@import 'vendor/litepicker';
|
||||
@import 'vendor/tom-select';
|
||||
@import 'vendor/apexcharts';
|
||||
@import 'vendor/jsvectormap';
|
||||
@import 'vendor/dropzone';
|
||||
@import 'vendor/fslightbox';
|
||||
@import 'vendor/plyr';
|
||||
@import 'vendor/wysiwyg';
|
||||
@import 'vendor/stars-rating';
|
||||
@import 'vendor/coloris';
|
||||
@import 'vendor/typed';
|
||||
@import 'vendor/turbo';
|
||||
@import 'vendor/fullcalendar';
|
||||
}
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
@use 'layers';
|
||||
|
||||
@import 'core';
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer components {
|
||||
.accordion {
|
||||
--#{$prefix}accordion-color: var(--#{$prefix}body-color);
|
||||
--#{$prefix}accordion-border-color: var(--#{$prefix}border-color);
|
||||
@@ -175,3 +176,4 @@
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
@layer components {
|
||||
.alert {
|
||||
--#{$prefix}alert-color: var(--#{$prefix}body-color);
|
||||
--#{$prefix}alert-bg: #{color-transparent(var(--#{$prefix}alert-color), 0.1)};
|
||||
--#{$prefix}alert-variant-color: var(--#{$prefix}body-color);
|
||||
--#{$prefix}alert-color: var(--#{$prefix}alert-variant-color);
|
||||
--#{$prefix}alert-bg: #{color-transparent(var(--#{$prefix}alert-variant-color), 0.16, var(--#{$prefix}bg-surface))};
|
||||
--#{$prefix}alert-padding-x: #{$alert-padding-x};
|
||||
--#{$prefix}alert-padding-y: #{$alert-padding-y};
|
||||
--#{$prefix}alert-margin-bottom: #{$alert-margin-bottom};
|
||||
--#{$prefix}alert-border-color: #{color-transparent(var(--#{$prefix}alert-color), 0.2)};
|
||||
--#{$prefix}alert-border-color: #{color-transparent(var(--#{$prefix}alert-variant-color), 0.2, var(--#{$prefix}bg-surface))};
|
||||
--#{$prefix}alert-border-color: var(--#{$prefix}border-color);
|
||||
--#{$prefix}alert-border: var(--#{$prefix}border-width) solid var(--#{$prefix}alert-border-color);
|
||||
--#{$prefix}alert-border-radius: var(--#{$prefix}border-radius);
|
||||
--#{$prefix}alert-link-color: inherit;
|
||||
@@ -16,6 +19,8 @@
|
||||
background-color: color-mix(in srgb, var(--#{$prefix}alert-bg), var(--#{$prefix}bg-surface));
|
||||
border-radius: var(--#{$prefix}alert-border-radius);
|
||||
border: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}alert-border-color);
|
||||
box-shadow: var(--#{$prefix}box-shadow);
|
||||
color: var(--#{$prefix}alert-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
@@ -66,15 +71,14 @@
|
||||
.btn-close {
|
||||
position: absolute;
|
||||
top: calc(var(--#{$prefix}alert-padding-x) / 2 - 1px);
|
||||
inset-inline-end: calc(var(--#{$prefix}alert-padding-y) / 2 - 1px);
|
||||
inset-inline-end: calc(var(--#{$prefix}alert-padding-y) / 2 - 1px);
|
||||
z-index: 1;
|
||||
padding: calc(var(--#{$prefix}alert-padding-y) * 1.25) var(--#{$prefix}alert-padding-x);
|
||||
}
|
||||
}
|
||||
|
||||
.alert-important {
|
||||
border-color: var(--#{$prefix}alert-color);
|
||||
background-color: var(--#{$prefix}alert-color);
|
||||
background-color: var(--#{$prefix}alert-variant-color);
|
||||
color: var(--#{$prefix}white);
|
||||
|
||||
.alert-description {
|
||||
@@ -93,6 +97,7 @@
|
||||
|
||||
@each $name, $color in $theme-colors {
|
||||
.alert-#{$name} {
|
||||
--#{$prefix}alert-color: var(--#{$prefix}#{$name});
|
||||
--#{$prefix}alert-variant-color: var(--#{$prefix}#{$name});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@use 'sass:map';
|
||||
|
||||
@layer components {
|
||||
.avatar {
|
||||
--#{$prefix}avatar-size: var(--#{$prefix}avatar-list-size, #{$avatar-size});
|
||||
--#{$prefix}avatar-status-size: #{$avatar-status-size};
|
||||
@@ -9,6 +10,7 @@
|
||||
--#{$prefix}avatar-font-size: #{$avatar-font-size};
|
||||
--#{$prefix}avatar-icon-size: #{$avatar-icon-size};
|
||||
--#{$prefix}avatar-brand-size: #{$avatar-brand-size};
|
||||
--#{$prefix}avatar-border-radius: #{$avatar-border-radius};
|
||||
position: relative;
|
||||
width: var(--#{$prefix}avatar-size);
|
||||
height: var(--#{$prefix}avatar-size);
|
||||
@@ -24,7 +26,7 @@
|
||||
vertical-align: bottom;
|
||||
user-select: none;
|
||||
background: var(--#{$prefix}avatar-bg) no-repeat center/cover;
|
||||
border-radius: $avatar-border-radius;
|
||||
border-radius: var(--#{$prefix}avatar-border-radius);
|
||||
box-shadow: var(--#{$prefix}avatar-box-shadow);
|
||||
transition:
|
||||
color $transition-time,
|
||||
@@ -38,7 +40,7 @@
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-end: 0;
|
||||
bottom: 0;
|
||||
border-radius: $border-radius-pill;
|
||||
box-shadow: 0 0 0 calc(var(--#{$prefix}avatar-status-size) / 4) $card-bg;
|
||||
@@ -58,6 +60,10 @@
|
||||
border-radius: $border-radius-pill;
|
||||
}
|
||||
|
||||
.avatar-square {
|
||||
border-radius: var(--#{$prefix}border-radius);
|
||||
}
|
||||
|
||||
@each $avatar-size, $size in $avatar-sizes {
|
||||
.avatar-#{$avatar-size} {
|
||||
--#{$prefix}avatar-size: #{map.get($size, size)};
|
||||
@@ -66,14 +72,14 @@
|
||||
--#{$prefix}avatar-icon-size: #{map.get($size, icon-size)};
|
||||
--#{$prefix}avatar-brand-size: #{map.get($size, brand-size)};
|
||||
|
||||
@if map.has-key($size, border-radius) {
|
||||
border-radius: map.get($size, border-radius);
|
||||
}
|
||||
|
||||
.badge:empty {
|
||||
width: map.get($size, status-size);
|
||||
height: map.get($size, status-size);
|
||||
}
|
||||
|
||||
&.avatar-square {
|
||||
--#{$prefix}avatar-border-radius: #{map.get($size, border-radius)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,10 +102,13 @@
|
||||
--#{$prefix}list-gap: 0;
|
||||
|
||||
.avatar {
|
||||
margin-inline-end: calc(#{$avatar-list-spacing} * var(--#{$prefix}avatar-size)) !important;
|
||||
box-shadow:
|
||||
var(--#{$prefix}avatar-box-shadow),
|
||||
0 0 0 2px var(--#{$prefix}card-bg, var(--#{$prefix}bg-surface));
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-inline-start: calc(#{$avatar-list-spacing} * var(--#{$prefix}avatar-size)) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,3 +163,4 @@
|
||||
border-radius: var(--#{$prefix}border-radius);
|
||||
border: 1px solid var(--#{$prefix}border-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer components {
|
||||
.badge {
|
||||
--#{$prefix}badge-padding-x: #{$badge-padding-x};
|
||||
--#{$prefix}badge-padding-y: #{$badge-padding-y};
|
||||
@@ -111,3 +112,4 @@
|
||||
.badge-icononly {
|
||||
--#{$prefix}badge-padding-x: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer components {
|
||||
.breadcrumb {
|
||||
--#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x};
|
||||
--#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y};
|
||||
@@ -79,3 +80,4 @@
|
||||
--#{$prefix}breadcrumb-divider: '#{quote($symbol)}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer components {
|
||||
.btn-group,
|
||||
.btn-group-vertical {
|
||||
box-shadow: $input-box-shadow;
|
||||
@@ -14,3 +15,4 @@
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@use 'sass:color';
|
||||
@use 'sass:map';
|
||||
|
||||
@layer components {
|
||||
//
|
||||
// Button
|
||||
//
|
||||
@@ -76,6 +77,15 @@
|
||||
//
|
||||
// Button color variations
|
||||
//
|
||||
.btn-ghost {
|
||||
--#{$prefix}btn-bg: transparent;
|
||||
--#{$prefix}btn-border-color: transparent;
|
||||
--#{$prefix}btn-box-shadow: none;
|
||||
--#{$prefix}btn-hover-bg: var(--#{$prefix}bg-surface-secondary);
|
||||
--#{$prefix}btn-hover-border-color: transparent;
|
||||
--#{$prefix}btn-hover-color: var(--#{$prefix}body-color);
|
||||
}
|
||||
|
||||
@each $color, $value in map.merge($theme-colors, $social-colors) {
|
||||
.btn-#{$color} {
|
||||
@if $color == 'dark' {
|
||||
@@ -114,15 +124,6 @@
|
||||
--#{$prefix}btn-disabled-border-color: var(--#{$prefix}#{$color});
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
--#{$prefix}btn-bg: transparent;
|
||||
--#{$prefix}btn-border-color: transparent;
|
||||
--#{$prefix}btn-box-shadow: none;
|
||||
--#{$prefix}btn-hover-bg: var(--#{$prefix}bg-surface-secondary);
|
||||
--#{$prefix}btn-hover-border-color: transparent;
|
||||
--#{$prefix}btn-hover-color: var(--#{$prefix}body-color);
|
||||
}
|
||||
|
||||
.btn-ghost-#{$color},
|
||||
.btn-ghost.btn-#{$color} {
|
||||
--#{$prefix}btn-color: var(--#{$prefix}#{$color});
|
||||
@@ -250,7 +251,7 @@
|
||||
position: absolute;
|
||||
width: var(--#{$prefix}btn-icon-size);
|
||||
height: var(--#{$prefix}btn-icon-size);
|
||||
inset-inline-start: calc(50% - var(--#{$prefix}btn-icon-size) / 2);
|
||||
inset-inline-start: calc(50% - var(--#{$prefix}btn-icon-size) / 2);
|
||||
top: calc(50% - var(--#{$prefix}btn-icon-size) / 2);
|
||||
animation: spinner-border 0.75s linear infinite;
|
||||
}
|
||||
@@ -359,3 +360,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer components {
|
||||
.calendar {
|
||||
display: block;
|
||||
font-size: $font-size-sm;
|
||||
@@ -77,11 +78,11 @@
|
||||
&:before {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: 0;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-start: 0;
|
||||
height: 1.4rem;
|
||||
content: '';
|
||||
background: rgba(var(--#{$prefix}primary-rgb), 0.1);
|
||||
background: color-transparent(var(--#{$prefix}primary), 0.1);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
@@ -95,10 +96,11 @@
|
||||
}
|
||||
|
||||
&.range-start:before {
|
||||
inset-inline-start: 50%;
|
||||
inset-inline-start: 50%;
|
||||
}
|
||||
|
||||
&.range-end:before {
|
||||
inset-inline-end: 50%;
|
||||
inset-inline-end: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@use 'sass:map';
|
||||
|
||||
@layer components {
|
||||
@property --tblr-card-gradient-direction {
|
||||
syntax: '<angle>';
|
||||
inherits: true;
|
||||
@@ -40,7 +41,6 @@
|
||||
|
||||
// Card borderless
|
||||
.card-borderless {
|
||||
|
||||
&,
|
||||
.card-header,
|
||||
.card-footer {
|
||||
@@ -48,6 +48,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Card dashed
|
||||
.card-dashed {
|
||||
border: var(--#{$prefix}border-width) dashed var(--#{$prefix}border-color);
|
||||
}
|
||||
|
||||
// Card transparent
|
||||
.card-transparent {
|
||||
background: transparent;
|
||||
border: var(--#{$prefix}border-width) dashed var(--#{$prefix}border-color);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
// Card stamp
|
||||
.card-stamp {
|
||||
--#{$prefix}stamp-size: 7rem;
|
||||
@@ -141,7 +153,7 @@
|
||||
background: $active-bg;
|
||||
}
|
||||
|
||||
&+& {
|
||||
& + & {
|
||||
border-inline-start: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color);
|
||||
}
|
||||
}
|
||||
@@ -340,17 +352,17 @@ Stacked card
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-sm>& {
|
||||
.card-sm > & {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.card-md>& {
|
||||
.card-md > & {
|
||||
@include media-breakpoint-up(md) {
|
||||
padding: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card-lg>& {
|
||||
.card-lg > & {
|
||||
@include media-breakpoint-up(md) {
|
||||
padding: 2rem;
|
||||
}
|
||||
@@ -364,7 +376,7 @@ Stacked card
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&+& {
|
||||
& + & {
|
||||
border-top: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color);
|
||||
}
|
||||
}
|
||||
@@ -427,7 +439,6 @@ Card table
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
tr {
|
||||
|
||||
td,
|
||||
th {
|
||||
&:first-child {
|
||||
@@ -456,11 +467,11 @@ Card table
|
||||
tfoot {
|
||||
&:last-child {
|
||||
tr:last-child {
|
||||
>*:last-child {
|
||||
> *:last-child {
|
||||
border-end-end-radius: calc(var(--#{$prefix}card-border-radius) - var(--#{$prefix}card-border-width));
|
||||
}
|
||||
|
||||
>*:first-child {
|
||||
> *:first-child {
|
||||
border-end-start-radius: calc(var(--#{$prefix}card-border-radius) - var(--#{$prefix}card-border-width));
|
||||
}
|
||||
}
|
||||
@@ -496,7 +507,7 @@ Card table
|
||||
}
|
||||
}
|
||||
|
||||
.card-body+& {
|
||||
.card-body + & {
|
||||
border-top: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}table-border-color);
|
||||
}
|
||||
}
|
||||
@@ -541,7 +552,7 @@ Card avatar
|
||||
Card list group
|
||||
*/
|
||||
.card-list-group {
|
||||
.card-body+& {
|
||||
.card-body + & {
|
||||
border-top: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color);
|
||||
}
|
||||
|
||||
@@ -600,7 +611,7 @@ Card list group
|
||||
}
|
||||
}
|
||||
|
||||
+.nav-item {
|
||||
+ .nav-item {
|
||||
margin-inline-start: calc(-1 * #{$card-border-width});
|
||||
}
|
||||
}
|
||||
@@ -640,7 +651,7 @@ Card list group
|
||||
border-end-start-radius: 0;
|
||||
}
|
||||
|
||||
.nav-tabs+.tab-content .card {
|
||||
.nav-tabs + .tab-content .card {
|
||||
border-end-start-radius: var(--#{$prefix}card-border-radius);
|
||||
border-start-start-radius: 0;
|
||||
}
|
||||
@@ -654,7 +665,6 @@ Card note
|
||||
--#{$prefix}card-border-color: #fff1c9;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Card gradient
|
||||
*/
|
||||
@@ -663,10 +673,10 @@ Card gradient
|
||||
--#{$prefix}card-gradient-opacity: 86%;
|
||||
--#{$prefix}card-gradient: var(--tblr-primary), var(--tblr-primary);
|
||||
|
||||
background: radial-gradient(ellipse at center, var(--#{$prefix}card-bg) 0%, color-mix(in srgb, var(--#{$prefix}card-bg) 0%, transparent) 80%) border-box,
|
||||
linear-gradient(var(--#{$prefix}card-gradient-direction), color-mix(in srgb, var(--#{$prefix}card-bg) var(--#{$prefix}card-gradient-opacity), transparent) 0%, var(--#{$prefix}card-bg) 40%) border-box,
|
||||
linear-gradient(calc(270deg + var(--#{$prefix}card-gradient-direction)), var(--#{$prefix}card-gradient)) border-box;
|
||||
|
||||
background:
|
||||
radial-gradient(ellipse at center, var(--#{$prefix}card-bg) 0%, color-mix(in srgb, var(--#{$prefix}card-bg) 0%, transparent) 80%) border-box,
|
||||
linear-gradient(var(--#{$prefix}card-gradient-direction), color-mix(in srgb, var(--#{$prefix}card-bg) var(--#{$prefix}card-gradient-opacity), transparent) 0%, var(--#{$prefix}card-bg) 40%) border-box,
|
||||
linear-gradient(calc(270deg + var(--#{$prefix}card-gradient-direction)), var(--#{$prefix}card-gradient)) border-box;
|
||||
}
|
||||
|
||||
@each $name, $color in map.merge($colors, $theme-colors) {
|
||||
@@ -676,14 +686,7 @@ Card gradient
|
||||
}
|
||||
|
||||
.card-gradient-rainbow {
|
||||
--#{$prefix}card-gradient: #78C5D6,
|
||||
#459BA8,
|
||||
#79C267,
|
||||
#C5D647,
|
||||
#F5D63D,
|
||||
#F08B33,
|
||||
#E868A2,
|
||||
#BE61A5;
|
||||
--#{$prefix}card-gradient: #78c5d6, #459ba8, #79c267, #c5d647, #f5d63d, #f08b33, #e868a2, #be61a5;
|
||||
}
|
||||
|
||||
.card-gradient-sun {
|
||||
@@ -695,7 +698,7 @@ Card gradient
|
||||
}
|
||||
|
||||
.card-gradient-ocean {
|
||||
--#{$prefix}card-gradient: #1CB5E0, #000851;
|
||||
--#{$prefix}card-gradient: #1cb5e0, #000851;
|
||||
}
|
||||
|
||||
.card-gradient-mellow {
|
||||
@@ -703,7 +706,7 @@ Card gradient
|
||||
}
|
||||
|
||||
.card-gradient-disco {
|
||||
--#{$prefix}card-gradient: #FC466B, #3F5EFB;
|
||||
--#{$prefix}card-gradient: #fc466b, #3f5efb;
|
||||
}
|
||||
|
||||
.card-gradient-psychedelic {
|
||||
@@ -715,7 +718,7 @@ Card gradient
|
||||
}
|
||||
|
||||
.card-gradient-gold {
|
||||
--#{$prefix}card-gradient: #9d4100, #bf7122, #f59f00, #FFD700;
|
||||
--#{$prefix}card-gradient: #9d4100, #bf7122, #f59f00, #ffd700;
|
||||
}
|
||||
|
||||
.card-gradient-animated {
|
||||
@@ -732,4 +735,5 @@ Card gradient
|
||||
|
||||
.card-gradient-start {
|
||||
--#{$prefix}card-gradient-direction: 90deg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer components {
|
||||
.carousel {
|
||||
}
|
||||
|
||||
@@ -65,3 +66,4 @@
|
||||
height: 90%;
|
||||
background: linear-gradient(0deg, rgba($dark, 0.9), rgba($dark, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@layer components {
|
||||
.chart {
|
||||
display: block;
|
||||
min-height: 10rem;
|
||||
@@ -59,3 +60,4 @@ Chart sparkline
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user