mirror of
https://github.com/jgthms/bulma.git
synced 2024-11-14 11:14:24 +00:00
commit
bbd8d21bf2
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,5 +17,6 @@ test.css.map
|
||||
_gh_pages
|
||||
_site
|
||||
dev
|
||||
dist
|
||||
node_modules
|
||||
test/output/
|
||||
|
39
docs/_includes/global/customizer.html
Normal file
39
docs/_includes/global/customizer.html
Normal file
@ -0,0 +1,39 @@
|
||||
<div id="bulma-customizer-app" class="is-hidden-mobile"></div>
|
||||
<div id="scope" class="is-hidden">
|
||||
<div class="breadcrumb"></div>
|
||||
<div class="card"></div>
|
||||
<div class="dropdown"></div>
|
||||
<div class="menu"></div>
|
||||
<div class="message"></div>
|
||||
<div class="modal"></div>
|
||||
<div class="navbar"></div>
|
||||
<div class="pagination"></div>
|
||||
<div class="panel"></div>
|
||||
<div class="tabs"></div>
|
||||
<div class="box"></div>
|
||||
<div class="content"></div>
|
||||
<div class="delete"></div>
|
||||
<div class="icon"></div>
|
||||
<div class="notification"></div>
|
||||
<div class="progress"></div>
|
||||
<div class="table"></div>
|
||||
<div class="tag"></div>
|
||||
<div class="title"></div>
|
||||
<input class="input" />
|
||||
<div class="file"></div>
|
||||
<div class="columns"></div>
|
||||
<div class="grid"></div>
|
||||
<div class="footer"></div>
|
||||
<div class="hero"></div>
|
||||
<div class="media"></div>
|
||||
<div class="section"></div>
|
||||
</div>
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="{{ site.url }}/assets/javascript/bulma-customizer/index.css"
|
||||
/>
|
||||
<script
|
||||
defer
|
||||
src="{{ site.url }}/assets/javascript/bulma-customizer/index.js"
|
||||
></script>
|
@ -29,5 +29,6 @@
|
||||
});
|
||||
</script>
|
||||
<script src="{{ site.url }}/assets/javascript/main.js"></script>
|
||||
{% include global/customizer.html %}
|
||||
</body>
|
||||
</html>
|
||||
|
21
docs/_react/bulma-customizer/.eslintrc.cjs
Normal file
21
docs/_react/bulma-customizer/.eslintrc.cjs
Normal file
@ -0,0 +1,21 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: { browser: true, es2020: true },
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
||||
settings: { react: { version: '18.2' } },
|
||||
plugins: ['react-refresh'],
|
||||
rules: {
|
||||
'react/jsx-no-target-blank': 'off',
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
},
|
||||
}
|
24
docs/_react/bulma-customizer/.gitignore
vendored
Normal file
24
docs/_react/bulma-customizer/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
8
docs/_react/bulma-customizer/README.md
Normal file
8
docs/_react/bulma-customizer/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# React + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
46
docs/_react/bulma-customizer/index.html
Normal file
46
docs/_react/bulma-customizer/index.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React</title>
|
||||
<style type="text/css">
|
||||
#bulma-customizer-app {
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="bulma-customizer-app"></div>
|
||||
<div id="scope" class="is-hidden">
|
||||
<div class="breadcrumb"></div>
|
||||
<div class="card"></div>
|
||||
<div class="dropdown"></div>
|
||||
<div class="menu"></div>
|
||||
<div class="message"></div>
|
||||
<div class="modal"></div>
|
||||
<div class="navbar"></div>
|
||||
<div class="pagination"></div>
|
||||
<div class="panel"></div>
|
||||
<div class="tabs"></div>
|
||||
<div class="box"></div>
|
||||
<div class="content"></div>
|
||||
<div class="delete"></div>
|
||||
<div class="icon"></div>
|
||||
<div class="notification"></div>
|
||||
<div class="progress"></div>
|
||||
<table class="table"></table>
|
||||
<div class="tag"></div>
|
||||
<div class="title"></div>
|
||||
<input class="input" />
|
||||
<div class="file"></div>
|
||||
<div class="columns"></div>
|
||||
<div class="grid"></div>
|
||||
<div class="footer"></div>
|
||||
<div class="hero"></div>
|
||||
<div class="media"></div>
|
||||
<div class="section"></div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
4578
docs/_react/bulma-customizer/package-lock.json
generated
Normal file
4578
docs/_react/bulma-customizer/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
28
docs/_react/bulma-customizer/package.json
Normal file
28
docs/_react/bulma-customizer/package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "bulma-customizer",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "^2.5.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-syntax-highlighter": "^15.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-react": "^7.34.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"eslint-plugin-react-refresh": "^0.4.7",
|
||||
"vite": "^5.3.1"
|
||||
}
|
||||
}
|
26
docs/_react/bulma-customizer/src/App.css
Normal file
26
docs/_react/bulma-customizer/src/App.css
Normal file
@ -0,0 +1,26 @@
|
||||
:root {
|
||||
--gh-dark: #25292e;
|
||||
--gh-dimmed: #6a737d;
|
||||
--gh-text: #e1e4e8;
|
||||
--gh-red: #f97583;
|
||||
--gh-orange: #ffab70;
|
||||
--gh-yellow: #ffea7f;
|
||||
--gh-green: #85e89d;
|
||||
--gh-blue: #79b8ff;
|
||||
--gh-blue-light: #9ecbff;
|
||||
--gh-purple: #b392f0;
|
||||
--gh-pink: #f692ce;
|
||||
|
||||
/*
|
||||
"black": "#1b1f23",
|
||||
"white": "#fff",
|
||||
"gray": ["#fafbfc", "#f6f8fa", "#e1e4e8", "#d1d5da", "#959da5", "#6a737d", "#586069", "#444d56", "#2f363d", "#24292e"],
|
||||
"blue": ["#f1f8ff", "#dbedff", "#c8e1ff", "#79b8ff", "#2188ff", "#0366d6", "#005cc5", "#044289", "#032f62", "#05264c"],
|
||||
"green": ["#f0fff4", "#dcffe4", "#bef5cb", "#85e89d", "#34d058", "#28a745", "#22863a", "#176f2c", "#165c26", "#144620"],
|
||||
"yellow": ["#fffdef", "#fffbdd", "#fff5b1", "#ffea7f", "#ffdf5d", "#ffd33d", "#f9c513", "#dbab09", "#b08800", "#735c0f"],
|
||||
"orange": ["#fff8f2", "#ffebda", "#ffd1ac", "#ffab70", "#fb8532", "#f66a0a", "#e36209", "#d15704", "#c24e00", "#a04100"],
|
||||
"red": ["#ffeef0", "#ffdce0", "#fdaeb7", "#f97583", "#ea4a5a", "#d73a49", "#cb2431", "#b31d28", "#9e1c23", "#86181d"],
|
||||
"purple": ["#f5f0ff", "#e6dcfd", "#d1bcf9", "#b392f0", "#8a63d2", "#6f42c1", "#5a32a3", "#4c2889", "#3a1d6e", "#29134e"],
|
||||
"pink": ["#ffeef8", "#fedbf0", "#f9b3dd", "#f692ce", "#ec6cb9", "#ea4aaa", "#d03592", "#b93a86", "#99306f", "#6d224f"]
|
||||
*/
|
||||
}
|
592
docs/_react/bulma-customizer/src/App.jsx
Normal file
592
docs/_react/bulma-customizer/src/App.jsx
Normal file
@ -0,0 +1,592 @@
|
||||
import { createContext, useEffect, useRef, useState } from "react";
|
||||
import classNames from "classnames";
|
||||
// import "../../../../css/bulma.css";
|
||||
import "./App.css";
|
||||
import cn from "./App.module.css";
|
||||
|
||||
import { CSSVAR_KEYS } from "./constants";
|
||||
import { unslug } from "./utils";
|
||||
|
||||
import Colors from "./pages/Colors";
|
||||
import Scheme from "./pages/Scheme";
|
||||
import Typography from "./pages/Typography";
|
||||
import Other from "./pages/Other";
|
||||
import Generic from "./pages/Generic";
|
||||
import Skeleton from "./pages/Skeleton";
|
||||
|
||||
import Breadcrumb from "./pages/components/Breadcrumb";
|
||||
import Card from "./pages/components/Card";
|
||||
import Dropdown from "./pages/components/Dropdown";
|
||||
import Menu from "./pages/components/Menu";
|
||||
import Message from "./pages/components/Message";
|
||||
import Modal from "./pages/components/Modal";
|
||||
import Navbar from "./pages/components/Navbar";
|
||||
import Pagination from "./pages/components/Pagination";
|
||||
import Panel from "./pages/components/Panel";
|
||||
import Tabs from "./pages/components/Tabs";
|
||||
|
||||
import Box from "./pages/elements/Box";
|
||||
import Content from "./pages/elements/Content";
|
||||
import Delete from "./pages/elements/Delete";
|
||||
import Icon from "./pages/elements/Icon";
|
||||
import Notification from "./pages/elements/Notification";
|
||||
import Progress from "./pages/elements/Progress";
|
||||
import Table from "./pages/elements/Table";
|
||||
import Tag from "./pages/elements/Tag";
|
||||
import Title from "./pages/elements/Title";
|
||||
import Control from "./pages/form/Control";
|
||||
import Input from "./pages/form/Input";
|
||||
import File from "./pages/form/File";
|
||||
import Columns from "./pages/grid/Columns";
|
||||
import Grid from "./pages/grid/Grid";
|
||||
import Footer from "./pages/layout/Footer";
|
||||
import Hero from "./pages/layout/Hero";
|
||||
import Media from "./pages/layout/Media";
|
||||
import Section from "./pages/layout/Section";
|
||||
import Export from "./components/Export";
|
||||
|
||||
const SUFFIX_TO_KIND = {
|
||||
"-h": "hue",
|
||||
"-s": "saturation",
|
||||
"-l": "lightness",
|
||||
"-delta": "delta",
|
||||
"-color": "color",
|
||||
};
|
||||
const UNITS = ["deg", "%"];
|
||||
const PAGE_TO_COMPONENT = {
|
||||
colors: <Colors />,
|
||||
scheme: <Scheme />,
|
||||
typography: <Typography />,
|
||||
other: <Other />,
|
||||
generic: <Generic />,
|
||||
skeleton: <Skeleton />,
|
||||
// Components
|
||||
breadcrumb: <Breadcrumb />,
|
||||
card: <Card />,
|
||||
dropdown: <Dropdown />,
|
||||
menu: <Menu />,
|
||||
message: <Message />,
|
||||
modal: <Modal />,
|
||||
navbar: <Navbar />,
|
||||
pagination: <Pagination />,
|
||||
panel: <Panel />,
|
||||
tabs: <Tabs />,
|
||||
// Elements
|
||||
box: <Box />,
|
||||
content: <Content />,
|
||||
delete: <Delete />,
|
||||
icon: <Icon />,
|
||||
notification: <Notification />,
|
||||
progress: <Progress />,
|
||||
table: <Table />,
|
||||
tag: <Tag />,
|
||||
title: <Title />,
|
||||
// Form
|
||||
control: <Control />,
|
||||
input: <Input />,
|
||||
file: <File />,
|
||||
// Grid
|
||||
columns: <Columns />,
|
||||
grid: <Grid />,
|
||||
// Layout
|
||||
footer: <Footer />,
|
||||
hero: <Hero />,
|
||||
media: <Media />,
|
||||
section: <Section />,
|
||||
// Export
|
||||
export: <Export />,
|
||||
};
|
||||
const TAB_IDS = [
|
||||
"Global Variables",
|
||||
"Components",
|
||||
"Elements",
|
||||
"Form",
|
||||
"Grid",
|
||||
"Layout",
|
||||
"Export",
|
||||
];
|
||||
const PAGE_IDS = {
|
||||
"Global Variables": [
|
||||
"colors",
|
||||
"scheme",
|
||||
"typography",
|
||||
"other",
|
||||
"generic",
|
||||
"skeleton",
|
||||
],
|
||||
Components: [
|
||||
"breadcrumb",
|
||||
"card",
|
||||
"dropdown",
|
||||
"menu",
|
||||
"message",
|
||||
"modal",
|
||||
"navbar",
|
||||
"pagination",
|
||||
"panel",
|
||||
"tabs",
|
||||
],
|
||||
Elements: [
|
||||
"box",
|
||||
"content",
|
||||
"delete",
|
||||
"icon",
|
||||
"notification",
|
||||
"progress",
|
||||
"table",
|
||||
"tag",
|
||||
"title",
|
||||
],
|
||||
Form: ["control", "input", "file"],
|
||||
Grid: ["columns", "grid"],
|
||||
Layout: ["footer", "hero", "media", "section"],
|
||||
Export: ["export"],
|
||||
};
|
||||
const LOCAL_STORAGE_KEY = "bulma-customizer-vars";
|
||||
|
||||
export const CustomizerContext = createContext({
|
||||
isOpen: false,
|
||||
showExport: false,
|
||||
cssvars: {},
|
||||
saved: {},
|
||||
currentTab: "",
|
||||
currentPage: "",
|
||||
getVar: () => {},
|
||||
changeTab: () => {},
|
||||
changePage: () => {},
|
||||
updateVar: () => {},
|
||||
hideExport: () => {},
|
||||
});
|
||||
|
||||
function App() {
|
||||
const styleRef = useRef();
|
||||
const initialContext = {
|
||||
isOpen: false,
|
||||
showExport: false,
|
||||
cssvars: {},
|
||||
saved: {},
|
||||
currentTab: "Global Variables",
|
||||
currentPage: "colors",
|
||||
getVar: (id) => {
|
||||
return context.cssvars[id];
|
||||
},
|
||||
changeTab: (tabId) => {
|
||||
setContext((context) => {
|
||||
return {
|
||||
...context,
|
||||
currentTab: tabId,
|
||||
};
|
||||
});
|
||||
},
|
||||
changePage: (pageId) => {
|
||||
setContext((context) => {
|
||||
return {
|
||||
...context,
|
||||
currentPage: pageId,
|
||||
};
|
||||
});
|
||||
},
|
||||
updateVar: (id, newValue) => {
|
||||
setContext((context) => {
|
||||
return {
|
||||
...context,
|
||||
cssvars: {
|
||||
...context.cssvars,
|
||||
[id]: {
|
||||
...context.cssvars[id],
|
||||
current: newValue,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
resetVars: () => {
|
||||
setContext((context) => {
|
||||
const cssvars = {};
|
||||
|
||||
for (const [key, value] of Object.entries(context.cssvars)) {
|
||||
const item = { ...value, current: value.start };
|
||||
cssvars[key] = item;
|
||||
}
|
||||
|
||||
return {
|
||||
...context,
|
||||
cssvars,
|
||||
};
|
||||
});
|
||||
},
|
||||
hideExport: () => {
|
||||
setContext((context) => {
|
||||
return {
|
||||
...context,
|
||||
showExport: false,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
const [context, setContext] = useState(() => {
|
||||
const saved = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
|
||||
if (saved) {
|
||||
const initialValue = JSON.parse(saved);
|
||||
initialContext.cssvars = initialValue;
|
||||
initialContext.saved = initialValue;
|
||||
}
|
||||
|
||||
return initialContext;
|
||||
});
|
||||
|
||||
const handleTabChange = (event) => {
|
||||
event.preventDefault();
|
||||
const tabId = event.target.value;
|
||||
context.changeTab(tabId);
|
||||
context.changePage(PAGE_IDS[tabId][0]);
|
||||
};
|
||||
|
||||
const handlePageChange = (event, pageId) => {
|
||||
event.preventDefault();
|
||||
context.changePage(pageId);
|
||||
};
|
||||
|
||||
const handleOpening = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
setContext((context) => {
|
||||
return {
|
||||
...context,
|
||||
isOpen: !context.isOpen,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const handleExport = (event) => {
|
||||
event.preventDefault();
|
||||
setContext((context) => {
|
||||
return {
|
||||
...context,
|
||||
showExport: !context.showExport,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Get the computed styles of all cssvars
|
||||
useEffect(() => {
|
||||
const styles = {
|
||||
root: window.getComputedStyle(document.documentElement),
|
||||
breadcrumb: window.getComputedStyle(
|
||||
document.querySelector(".breadcrumb"),
|
||||
),
|
||||
card: window.getComputedStyle(document.querySelector(".card")),
|
||||
dropdown: window.getComputedStyle(document.querySelector(".dropdown")),
|
||||
menu: window.getComputedStyle(document.querySelector(".menu")),
|
||||
message: window.getComputedStyle(document.querySelector(".message")),
|
||||
modal: window.getComputedStyle(document.querySelector(".modal")),
|
||||
navbar: window.getComputedStyle(document.querySelector(".navbar")),
|
||||
pagination: window.getComputedStyle(
|
||||
document.querySelector(".pagination"),
|
||||
),
|
||||
panel: window.getComputedStyle(document.querySelector(".panel")),
|
||||
tabs: window.getComputedStyle(document.querySelector(".tabs")),
|
||||
box: window.getComputedStyle(document.querySelector(".box")),
|
||||
content: window.getComputedStyle(document.querySelector(".content")),
|
||||
delete: window.getComputedStyle(document.querySelector(".delete")),
|
||||
icon: window.getComputedStyle(document.querySelector(".icon")),
|
||||
notification: window.getComputedStyle(
|
||||
document.querySelector(".notification"),
|
||||
),
|
||||
progress: window.getComputedStyle(document.querySelector(".progress")),
|
||||
table: window.getComputedStyle(document.querySelector(".table")),
|
||||
tag: window.getComputedStyle(document.querySelector(".tag")),
|
||||
title: window.getComputedStyle(document.querySelector(".title")),
|
||||
file: window.getComputedStyle(document.querySelector(".file")),
|
||||
input: window.getComputedStyle(document.querySelector(".input")),
|
||||
columns: window.getComputedStyle(document.querySelector(".columns")),
|
||||
grid: window.getComputedStyle(document.querySelector(".grid")),
|
||||
footer: window.getComputedStyle(document.querySelector(".footer")),
|
||||
hero: window.getComputedStyle(document.querySelector(".hero")),
|
||||
media: window.getComputedStyle(document.querySelector(".media")),
|
||||
section: window.getComputedStyle(document.querySelector(".section")),
|
||||
};
|
||||
|
||||
const cssvars = {};
|
||||
const allKeys = Object.values(PAGE_IDS)
|
||||
.flat()
|
||||
.map((pageId) => {
|
||||
if (!(pageId in CSSVAR_KEYS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return CSSVAR_KEYS[pageId];
|
||||
})
|
||||
.flat();
|
||||
const allKeyIds = allKeys.map((i) => {
|
||||
if (!i) {
|
||||
return;
|
||||
}
|
||||
|
||||
return i.id;
|
||||
});
|
||||
|
||||
allKeyIds.map((key) => {
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep the value saved in localStorage
|
||||
if (key in context.saved) {
|
||||
cssvars[key] = context.saved[key];
|
||||
return;
|
||||
}
|
||||
|
||||
let original;
|
||||
let scope = ":root";
|
||||
|
||||
if (key.startsWith("breadcrumb")) {
|
||||
scope = ".breadcrumb";
|
||||
original = styles.breadcrumb.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("card")) {
|
||||
scope = ".card";
|
||||
original = styles.card.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("dropdown")) {
|
||||
scope = ".dropdown";
|
||||
original = styles.dropdown.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("menu")) {
|
||||
scope = ".menu";
|
||||
original = styles.menu.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("message")) {
|
||||
scope = ".message";
|
||||
original = styles.message.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("modal")) {
|
||||
scope = ".modal";
|
||||
original = styles.modal.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("navbar")) {
|
||||
scope = ".navbar";
|
||||
original = styles.navbar.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("pagination")) {
|
||||
scope = ".pagination";
|
||||
original = styles.pagination.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("panel")) {
|
||||
scope = ".panel";
|
||||
original = styles.panel.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("tabs")) {
|
||||
scope = ".tabs";
|
||||
original = styles.tabs.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("box")) {
|
||||
scope = ".box";
|
||||
original = styles.box.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("content")) {
|
||||
scope = ".content";
|
||||
original = styles.content.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("delete")) {
|
||||
scope = ".delete";
|
||||
original = styles.delete.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("icon")) {
|
||||
scope = ".icon";
|
||||
original = styles.icon.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("notification")) {
|
||||
scope = ".notification";
|
||||
original = styles.notification.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("progress")) {
|
||||
scope = ".progress";
|
||||
original = styles.progress.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("table")) {
|
||||
scope = ".table";
|
||||
original = styles.table.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("tag")) {
|
||||
scope = ".tag";
|
||||
original = styles.tag.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("title")) {
|
||||
scope = ".title";
|
||||
original = styles.title.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("file")) {
|
||||
scope = ".file";
|
||||
original = styles.file.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("input")) {
|
||||
scope = ".input";
|
||||
original = styles.input.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("columns")) {
|
||||
scope = ".columns";
|
||||
original = styles.columns.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("grid")) {
|
||||
scope = ".grid";
|
||||
original = styles.grid.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("footer")) {
|
||||
scope = ".footer";
|
||||
original = styles.footer.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("hero")) {
|
||||
scope = ".hero";
|
||||
original = styles.hero.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("media")) {
|
||||
scope = ".media";
|
||||
original = styles.media.getPropertyValue(`--bulma-${key}`);
|
||||
} else if (key.startsWith("section")) {
|
||||
scope = ".section";
|
||||
original = styles.section.getPropertyValue(`--bulma-${key}`);
|
||||
} else {
|
||||
original = styles.root.getPropertyValue(`--bulma-${key}`);
|
||||
}
|
||||
|
||||
const suffix = Object.keys(SUFFIX_TO_KIND).find((kind) =>
|
||||
key.endsWith(kind),
|
||||
);
|
||||
const unit = UNITS.find((unit) => original.endsWith(unit)) || "";
|
||||
const value = unit !== "" ? original.split(unit)[0] : original;
|
||||
const description =
|
||||
allKeys.find((el) => el.id === key)?.description || "None";
|
||||
|
||||
cssvars[key] = {
|
||||
id: key,
|
||||
kind: SUFFIX_TO_KIND[suffix] || "any",
|
||||
original,
|
||||
unit,
|
||||
current: value,
|
||||
start: value,
|
||||
description,
|
||||
scope,
|
||||
};
|
||||
});
|
||||
|
||||
setContext((context) => {
|
||||
return {
|
||||
...context,
|
||||
cssvars,
|
||||
};
|
||||
});
|
||||
}, [context.saved]);
|
||||
|
||||
// Update the styling when the cssvars change
|
||||
useEffect(() => {
|
||||
const rules = {};
|
||||
const storedVars = {};
|
||||
|
||||
Object.values(context.cssvars).forEach((cssvar) => {
|
||||
const { id, current, start, scope, unit } = cssvar;
|
||||
|
||||
if (current == start) {
|
||||
return;
|
||||
}
|
||||
|
||||
storedVars[id] = cssvar;
|
||||
|
||||
const computedValue = `${current}${unit}`;
|
||||
const declaration = `--bulma-${id}: ${computedValue} !important;`;
|
||||
|
||||
if (scope in rules) {
|
||||
rules[scope].push(declaration);
|
||||
} else {
|
||||
rules[scope] = [declaration];
|
||||
}
|
||||
});
|
||||
|
||||
let content = "";
|
||||
|
||||
for (const [key, arr] of Object.entries(rules)) {
|
||||
content += `${key} {`;
|
||||
arr.forEach((item) => (content += item));
|
||||
content += `}`;
|
||||
}
|
||||
|
||||
if (styleRef) {
|
||||
styleRef.current.innerHTML = content;
|
||||
}
|
||||
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(storedVars));
|
||||
}, [context.cssvars]);
|
||||
|
||||
// Computed values
|
||||
// const isExportAvailable = Object.values(context.cssvars).some(
|
||||
// (item) => item.current != item.start,
|
||||
// );
|
||||
|
||||
// Styles
|
||||
const tabsStyle = {
|
||||
"--bulma-tabs-link-active-color": "var(--bulma-primary)",
|
||||
};
|
||||
|
||||
const customizerClass = classNames({
|
||||
[cn.customizer]: true,
|
||||
[cn.open]: context.isOpen,
|
||||
});
|
||||
|
||||
const controlsClass = classNames({
|
||||
[cn.controls]: true,
|
||||
});
|
||||
|
||||
const exportClass = classNames({
|
||||
[cn.button]: true,
|
||||
"is-hidden": !context.isOpen,
|
||||
button: !context.showExport,
|
||||
"button is-primary": context.showExport,
|
||||
});
|
||||
|
||||
const buttonClass = classNames({
|
||||
[cn.button]: true,
|
||||
"button is-primary": !context.isOpen,
|
||||
button: context.isOpen,
|
||||
});
|
||||
|
||||
return (
|
||||
<CustomizerContext.Provider value={context}>
|
||||
<div className={cn.app}>
|
||||
<style ref={styleRef} />
|
||||
|
||||
<div className={customizerClass}>
|
||||
{context.showExport ? (
|
||||
PAGE_TO_COMPONENT.export
|
||||
) : (
|
||||
<>
|
||||
{" "}
|
||||
<div className={controlsClass}>
|
||||
<div className="select" style={tabsStyle}>
|
||||
<select onChange={handleTabChange} value={context.currentTab}>
|
||||
{TAB_IDS.map((tabId) => {
|
||||
return (
|
||||
<option key={tabId} value={tabId}>
|
||||
{unslug(tabId)}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{PAGE_IDS[context.currentTab].map((pageId) => {
|
||||
const buttonClass = classNames({
|
||||
button: true,
|
||||
"is-primary": pageId === context.currentPage,
|
||||
});
|
||||
|
||||
return (
|
||||
<button
|
||||
className={buttonClass}
|
||||
key={pageId}
|
||||
onClick={(e) => handlePageChange(e, pageId)}
|
||||
>
|
||||
{unslug(pageId)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{PAGE_TO_COMPONENT[context.currentPage]}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={cn.buttons}>
|
||||
<button className={exportClass} onClick={handleExport}>
|
||||
<i className="fa-solid fa-code"></i>
|
||||
<span>Export</span>
|
||||
</button>
|
||||
|
||||
<button className={buttonClass} onClick={handleOpening}>
|
||||
<i className="fa-solid fa-palette"></i>
|
||||
<span>
|
||||
{context.isOpen ? "Close Customizer" : "Open Customizer"}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</CustomizerContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
55
docs/_react/bulma-customizer/src/App.module.css
Normal file
55
docs/_react/bulma-customizer/src/App.module.css
Normal file
@ -0,0 +1,55 @@
|
||||
.app {
|
||||
background-color: red;
|
||||
--var-item-side-width: 12rem;
|
||||
--var-item-slider-width: 30rem;
|
||||
--var-item-padding: 1rem;
|
||||
--var-item-gap: 1rem;
|
||||
bottom: 1rem;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.customizer {
|
||||
background: var(--bulma-scheme-main);
|
||||
box-shadow: var(--bulma-shadow);
|
||||
border-radius: 0.5rem;
|
||||
transform-origin: bottom right;
|
||||
transition-duration: 300ms;
|
||||
transition-property: opacity, transform;
|
||||
transform: scale(0.98) translate(2px, 2px);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
width: 33rem;
|
||||
top: 1rem;
|
||||
position: fixed;
|
||||
bottom: 4.5rem;
|
||||
right: 1rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.open {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.button {
|
||||
gap: 0.5rem;
|
||||
}
|
264
docs/_react/bulma-customizer/src/components/Color.jsx
Normal file
264
docs/_react/bulma-customizer/src/components/Color.jsx
Normal file
@ -0,0 +1,264 @@
|
||||
import { useContext } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import Slider from "./Slider";
|
||||
|
||||
import cn from "./Color.module.css";
|
||||
import { CustomizerContext } from "../App";
|
||||
import classNames from "classnames";
|
||||
|
||||
export function hslToHex(h, s, l) {
|
||||
s /= 100;
|
||||
l /= 100;
|
||||
|
||||
let c = (1 - Math.abs(2 * l - 1)) * s;
|
||||
let x = c * (1 - Math.abs(((h / 60) % 2) - 1));
|
||||
let m = l - c / 2;
|
||||
let r = 0,
|
||||
g = 0,
|
||||
b = 0;
|
||||
|
||||
if (0 <= h && h < 60) {
|
||||
r = c;
|
||||
g = x;
|
||||
b = 0;
|
||||
} else if (60 <= h && h < 120) {
|
||||
r = x;
|
||||
g = c;
|
||||
b = 0;
|
||||
} else if (120 <= h && h < 180) {
|
||||
r = 0;
|
||||
g = c;
|
||||
b = x;
|
||||
} else if (180 <= h && h < 240) {
|
||||
r = 0;
|
||||
g = x;
|
||||
b = c;
|
||||
} else if (240 <= h && h < 300) {
|
||||
r = x;
|
||||
g = 0;
|
||||
b = c;
|
||||
} else if (300 <= h && h < 360) {
|
||||
r = c;
|
||||
g = 0;
|
||||
b = x;
|
||||
}
|
||||
|
||||
r = Math.round((r + m) * 255);
|
||||
g = Math.round((g + m) * 255);
|
||||
b = Math.round((b + m) * 255);
|
||||
|
||||
return `${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()}`;
|
||||
}
|
||||
|
||||
function hexToHsl(hex) {
|
||||
// Remove the hash at the start if it's there
|
||||
hex = hex.replace(/^#/, "");
|
||||
|
||||
// Parse the hex values
|
||||
let r = parseInt(hex.slice(0, 2), 16);
|
||||
let g = parseInt(hex.slice(2, 4), 16);
|
||||
let b = parseInt(hex.slice(4, 6), 16);
|
||||
|
||||
// Convert the RGB values to the range [0, 1]
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
|
||||
// Find the maximum and minimum values to get the lightness
|
||||
let max = Math.max(r, g, b);
|
||||
let min = Math.min(r, g, b);
|
||||
let h,
|
||||
s,
|
||||
l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // Achromatic
|
||||
} else {
|
||||
let d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
|
||||
switch (max) {
|
||||
case r:
|
||||
h = (g - b) / d + (g < b ? 6 : 0);
|
||||
break;
|
||||
case g:
|
||||
h = (b - r) / d + 2;
|
||||
break;
|
||||
case b:
|
||||
h = (r - g) / d + 4;
|
||||
break;
|
||||
}
|
||||
|
||||
h *= 60;
|
||||
}
|
||||
|
||||
return {
|
||||
hue: Math.round(h),
|
||||
saturation: Math.round(s * 100),
|
||||
lightness: Math.round(l * 100),
|
||||
};
|
||||
}
|
||||
|
||||
function Color({ color }) {
|
||||
const { cssvars, updateVar } = useContext(CustomizerContext);
|
||||
|
||||
const hName = `${color}-h`;
|
||||
const sName = `${color}-s`;
|
||||
const lName = `${color}-l`;
|
||||
const h = cssvars[hName];
|
||||
const s = cssvars[sName];
|
||||
const l = cssvars[lName];
|
||||
|
||||
const mainStyle = {
|
||||
"--h": `var(--bulma-${hName})`,
|
||||
"--s": `var(--bulma-${sName})`,
|
||||
"--l": `var(--bulma-${lName})`,
|
||||
};
|
||||
const name = color.charAt(0).toUpperCase() + color.slice(1);
|
||||
|
||||
const handleReset = (event) => {
|
||||
event.preventDefault();
|
||||
updateVar(h.id, h.start);
|
||||
updateVar(s.id, s.start);
|
||||
updateVar(l.id, l.start);
|
||||
};
|
||||
|
||||
const handleHexInput = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
let value = window.prompt("Enter a Hexadecimal value (e.g. 00d1b2)");
|
||||
|
||||
if (value.startsWith("#")) {
|
||||
value = value.replace(/^#/, "");
|
||||
}
|
||||
|
||||
const hexPattern = /^([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/;
|
||||
|
||||
if (!hexPattern.test(value) || value.length > 6) {
|
||||
window.prompt("That is not a valid Hexadecimal value. Please try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.length === 3) {
|
||||
value = value[0] + value[0] + value[1] + value[1] + value[2] + value[2];
|
||||
}
|
||||
|
||||
const { hue, saturation, lightness } = hexToHsl(value);
|
||||
|
||||
updateVar(h.id, hue);
|
||||
updateVar(s.id, saturation);
|
||||
updateVar(l.id, lightness);
|
||||
};
|
||||
|
||||
const handleInputChange = (event, cssvar) => {
|
||||
let value = event.target.value;
|
||||
updateVar(cssvar.id, value);
|
||||
};
|
||||
|
||||
if (!h || !s || !l) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isDisabled =
|
||||
Number(h.current) === Number(h.start) &&
|
||||
Number(s.current) === Number(s.start) &&
|
||||
Number(l.current) === Number(l.start);
|
||||
const resetClass = classNames({
|
||||
button: true,
|
||||
"is-danger is-outlined": !isDisabled,
|
||||
});
|
||||
const resetStyle = isDisabled ? { opacity: 0.1 } : {};
|
||||
|
||||
return (
|
||||
<div className={cn.main} style={mainStyle}>
|
||||
<div className={cn.side}>
|
||||
<div className="buttons are-small is-float-right ml-2">
|
||||
<button className="button" onClick={handleHexInput}>
|
||||
Enter a Hex code
|
||||
</button>
|
||||
|
||||
<button
|
||||
className={resetClass}
|
||||
style={resetStyle}
|
||||
onClick={handleReset}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className={cn.name}>
|
||||
<div className={cn.swatch} />
|
||||
<p>{name}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cn.lines}>
|
||||
<div className={cn.line}>
|
||||
<p className={cn.label}>Hue</p>
|
||||
<div className={cn.slider}>
|
||||
<Slider id={hName} kind="hue" color={color} />
|
||||
<p className={cn.form}>
|
||||
<input
|
||||
type="text"
|
||||
className="input"
|
||||
value={Number(h.current)}
|
||||
onChange={(e) => handleInputChange(e, h)}
|
||||
size="3"
|
||||
/>
|
||||
<span>{h.unit}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cn.line}>
|
||||
<p className={cn.label}>Saturation</p>
|
||||
<div className={cn.slider}>
|
||||
<Slider id={sName} kind="saturation" color={color} />
|
||||
<p className={cn.form}>
|
||||
<input
|
||||
type="text"
|
||||
className="input"
|
||||
value={Number(s.current)}
|
||||
onChange={(e) => handleInputChange(e, s)}
|
||||
size="3"
|
||||
/>
|
||||
<span>{s.unit}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cn.line}>
|
||||
<p className={cn.label}>Lightness</p>
|
||||
<div className={cn.slider}>
|
||||
<Slider id={lName} kind="lightness" color={color} />
|
||||
<p className={cn.form}>
|
||||
<input
|
||||
type="text"
|
||||
className="input"
|
||||
value={Number(l.current)}
|
||||
onChange={(e) => handleInputChange(e, l)}
|
||||
size="3"
|
||||
/>
|
||||
<span>{l.unit}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cn.example}>
|
||||
<button className={`button is-${color}`}>{name}</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Color.propTypes = {
|
||||
color: PropTypes.string,
|
||||
h: PropTypes.string,
|
||||
s: PropTypes.string,
|
||||
l: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Color;
|
80
docs/_react/bulma-customizer/src/components/Color.module.css
Normal file
80
docs/_react/bulma-customizer/src/components/Color.module.css
Normal file
@ -0,0 +1,80 @@
|
||||
.main {
|
||||
border-top: 1px solid var(--bulma-border);
|
||||
padding: var(--var-item-padding);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.swatch {
|
||||
background-color: hsl(var(--h) var(--s) var(--l));
|
||||
height: 1.25rem;
|
||||
width: 1.25rem;
|
||||
border-radius: 0.25rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: var(--bulma-primary);
|
||||
gap: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.name p {
|
||||
color: var(--bulma-text-strong);
|
||||
font-size: 1.25em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.lines {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.line {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0 1.5rem;
|
||||
}
|
||||
|
||||
.line p {
|
||||
color: var(--bulma-text-strong);
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.slider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 1.5rem;
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: var(--bulma-family-code);
|
||||
gap: 0.25em;
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
.form input {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
padding: 0.25em;
|
||||
height: auto;
|
||||
border-radius: 0.25em;
|
||||
width: 3em;
|
||||
padding: 0 0.25em;
|
||||
}
|
||||
|
||||
.form span {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.example {
|
||||
margin-top: 0.5rem;
|
||||
}
|
120
docs/_react/bulma-customizer/src/components/Export.jsx
Normal file
120
docs/_react/bulma-customizer/src/components/Export.jsx
Normal file
@ -0,0 +1,120 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { CustomizerContext } from "../App";
|
||||
|
||||
import cn from "./Export.module.css";
|
||||
|
||||
function Export() {
|
||||
const { cssvars, resetVars, hideExport } = useContext(CustomizerContext);
|
||||
|
||||
const [css, setCSS] = useState("");
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
const handleReset = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (window.confirm("Are you sure?")) {
|
||||
resetVars();
|
||||
}
|
||||
};
|
||||
|
||||
const handleGo = (event) => {
|
||||
event.preventDefault();
|
||||
hideExport();
|
||||
};
|
||||
|
||||
const copyToClipboard = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(css);
|
||||
setCopied(true);
|
||||
window.setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 500);
|
||||
} catch (err) {
|
||||
console.error("Failed to copy!", err);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const rules = {};
|
||||
|
||||
Object.values(cssvars).forEach((cssvar) => {
|
||||
const { id, current, start, scope, unit } = cssvar;
|
||||
|
||||
if (current == start) {
|
||||
return;
|
||||
}
|
||||
|
||||
const computedValue = `${current}${unit}`;
|
||||
const declaration = `--bulma-${id}: ${computedValue};\n`;
|
||||
|
||||
if (scope in rules) {
|
||||
rules[scope].push(declaration);
|
||||
} else {
|
||||
rules[scope] = [declaration];
|
||||
}
|
||||
});
|
||||
|
||||
let content = "";
|
||||
|
||||
for (const [key, arr] of Object.entries(rules)) {
|
||||
content += `${key} {\n`;
|
||||
arr.forEach((item) => (content += ` ${item}`));
|
||||
content += `}\n\n`;
|
||||
}
|
||||
|
||||
setCSS(content);
|
||||
}, [cssvars]);
|
||||
|
||||
return (
|
||||
<div className={cn.main}>
|
||||
<div className={cn.body}>
|
||||
<p className="title is-5">Export</p>
|
||||
|
||||
{css ? (
|
||||
<div className={cn.explanation}>
|
||||
<p>
|
||||
Insert this CSS <em>after</em> importing Bulma.
|
||||
</p>
|
||||
|
||||
<div className="buttons are-small">
|
||||
{copied ? (
|
||||
<span className="button is-success">Copied!</span>
|
||||
) : (
|
||||
<button onClick={copyToClipboard} className="button is-primary">
|
||||
Copy
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={handleReset}
|
||||
className="button is-danger is-outlined"
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className={cn.explanation}>
|
||||
<p>
|
||||
Customize CSS variables in the other pages and come back here to
|
||||
find the generated CSS.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={cn.go}>
|
||||
<button className="button is-primary" onClick={handleGo}>
|
||||
Let's go!
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{css && <pre className={cn.pre}>{css.trim()}</pre>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Export;
|
@ -0,0 +1,36 @@
|
||||
.main {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.body {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.body :global(.title) {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.explanation {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
p {
|
||||
padding: 3px 0;
|
||||
}
|
||||
|
||||
div {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.go {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.pre {
|
||||
background-color: var(--gh-dark);
|
||||
margin: 0.5rem -0.5rem;
|
||||
color: var(--gh-text);
|
||||
font-size: 1rem;
|
||||
}
|
15
docs/_react/bulma-customizer/src/components/Highlighter.jsx
Normal file
15
docs/_react/bulma-customizer/src/components/Highlighter.jsx
Normal file
@ -0,0 +1,15 @@
|
||||
import PropTypes from "prop-types";
|
||||
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
||||
|
||||
const Highlighter = ({ ...rest }) => {
|
||||
return (
|
||||
<SyntaxHighlighter style={atomOneDark} useInlineStyles={false} {...rest} />
|
||||
);
|
||||
};
|
||||
|
||||
Highlighter.propTypes = {
|
||||
code: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Highlighter;
|
80
docs/_react/bulma-customizer/src/components/Picker.jsx
Normal file
80
docs/_react/bulma-customizer/src/components/Picker.jsx
Normal file
@ -0,0 +1,80 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import classNames from "classnames";
|
||||
|
||||
import cn from "./Slider.module.css";
|
||||
|
||||
const RANGES = {
|
||||
deg: [0, 360, 1],
|
||||
"%": [0, 100, 1],
|
||||
};
|
||||
|
||||
function Picker({ id, kind, start, unit }) {
|
||||
const [value, setValue] = useState(start);
|
||||
|
||||
let min = 0;
|
||||
let max = 360;
|
||||
let step = 1;
|
||||
|
||||
if (unit in RANGES) {
|
||||
[min, max, step] = RANGES[unit];
|
||||
}
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValue(event.target.value);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setValue(start);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const computedValue = `${value}${unit}`;
|
||||
|
||||
if (value === start) {
|
||||
document.documentElement.style.removeProperty(`--bulma-${id}`);
|
||||
} else {
|
||||
document.documentElement.style.setProperty(
|
||||
`--bulma-${id}`,
|
||||
computedValue,
|
||||
);
|
||||
}
|
||||
}, [id, start, unit, value]);
|
||||
|
||||
const mainCN = classNames({
|
||||
[cn.main]: true,
|
||||
[cn[kind]]: kind,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={mainCN}>
|
||||
<code>{id}</code>
|
||||
|
||||
<input
|
||||
type="range"
|
||||
min={min}
|
||||
max={max}
|
||||
step={step}
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<code>
|
||||
{value}
|
||||
{unit}
|
||||
</code>
|
||||
<button className="button is-small" onClick={handleReset}>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Picker.propTypes = {
|
||||
id: PropTypes.string,
|
||||
kind: PropTypes.string,
|
||||
original: PropTypes.string,
|
||||
start: PropTypes.number,
|
||||
unit: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Picker;
|
167
docs/_react/bulma-customizer/src/components/Slider.jsx
Normal file
167
docs/_react/bulma-customizer/src/components/Slider.jsx
Normal file
@ -0,0 +1,167 @@
|
||||
import { useContext, useEffect, useRef, useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import classNames from "classnames";
|
||||
|
||||
import cn from "./Slider.module.css";
|
||||
import { CustomizerContext } from "../App";
|
||||
|
||||
const RANGES = {
|
||||
hue: [0, 360, 1],
|
||||
saturation: [0, 100, 1],
|
||||
lightness: [0, 100, 1],
|
||||
gap: [0, 100, 1],
|
||||
delta: [0, 100, 1],
|
||||
any: [0, 100, 1],
|
||||
};
|
||||
|
||||
const xToValue = (x, width, min, max) => {
|
||||
const decimal = x / width;
|
||||
const newValue = decimal * (max - min);
|
||||
return Math.round(newValue);
|
||||
};
|
||||
|
||||
const valueToX = (value, width, min, max) => {
|
||||
const decimal = Number(value) / (max - min);
|
||||
const newValue = decimal * width;
|
||||
return Math.round(newValue);
|
||||
};
|
||||
|
||||
function Slider({ id, color }) {
|
||||
const { cssvars, updateVar } = useContext(CustomizerContext);
|
||||
const { start, current, kind } = cssvars[id];
|
||||
const [min, max] = kind ? RANGES[kind] : RANGES.any;
|
||||
|
||||
const sliderRef = useRef(null);
|
||||
const handleRef = useRef(null);
|
||||
|
||||
const [isMoving, setMoving] = useState(false);
|
||||
const [x, setX] = useState(valueToX(start, 360, min, max));
|
||||
|
||||
const handleMouseDown = (event) => {
|
||||
setMoving(true);
|
||||
const slider = sliderRef.current;
|
||||
const sliderRect = slider.getBoundingClientRect();
|
||||
const target = event.clientX - sliderRect.left;
|
||||
setX(Math.round(target));
|
||||
};
|
||||
|
||||
const docMouseLeave = () => {
|
||||
setMoving(false);
|
||||
};
|
||||
|
||||
const docMouseUp = () => {
|
||||
setMoving(false);
|
||||
};
|
||||
|
||||
// useEffect(() => {
|
||||
// const computedValue = `${current}${unit}`;
|
||||
|
||||
// if (current === start) {
|
||||
// document.documentElement.style.removeProperty(`--bulma-${id}`);
|
||||
// } else {
|
||||
// document.documentElement.style.setProperty(
|
||||
// `--bulma-${id}`,
|
||||
// computedValue,
|
||||
// );
|
||||
// }
|
||||
// }, [current, id, start, unit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMoving) {
|
||||
return;
|
||||
}
|
||||
const slider = sliderRef.current;
|
||||
const sliderRect = slider.getBoundingClientRect();
|
||||
const final = xToValue(x, sliderRect.width, min, max);
|
||||
updateVar(id, final);
|
||||
}, [id, isMoving, min, max, updateVar, x]);
|
||||
|
||||
useEffect(() => {
|
||||
const newX = valueToX(current, 360, min, max);
|
||||
setX(Math.round(newX));
|
||||
}, [min, max, current]);
|
||||
|
||||
useEffect(() => {
|
||||
const docMouseMove = (event) => {
|
||||
if (!isMoving || !sliderRef.current || !handleRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
const slider = sliderRef.current;
|
||||
const sliderRect = slider.getBoundingClientRect();
|
||||
let target = event.clientX - sliderRect.left;
|
||||
|
||||
if (target < 0) {
|
||||
target = 0;
|
||||
} else if (target > sliderRect.width) {
|
||||
target = sliderRect.width;
|
||||
}
|
||||
|
||||
setX(Math.round(target));
|
||||
};
|
||||
|
||||
window.addEventListener("mousemove", docMouseMove);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("mousemove", docMouseMove);
|
||||
};
|
||||
}, [isMoving, min, max, x]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("mouseleave", docMouseLeave);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("mouseleave", docMouseLeave);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("mouseup", docMouseUp);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("mouseup", docMouseUp);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const mainCN = classNames({
|
||||
[cn.main]: true,
|
||||
[cn.moving]: isMoving,
|
||||
});
|
||||
|
||||
const backgroundCN = classNames({
|
||||
[cn.background]: true,
|
||||
[cn[kind]]: true,
|
||||
});
|
||||
|
||||
const mainStyle = color
|
||||
? {
|
||||
"--h": `var(--bulma-${color}-h)`,
|
||||
"--s": `var(--bulma-${color}-s)`,
|
||||
"--l": `var(--bulma-${color}-l)`,
|
||||
}
|
||||
: {};
|
||||
|
||||
const handleStyle = {
|
||||
transform: `translateX(${x}px)`,
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={mainCN}
|
||||
ref={sliderRef}
|
||||
style={mainStyle}
|
||||
onMouseDown={handleMouseDown}
|
||||
>
|
||||
<div className={backgroundCN}>
|
||||
<span ref={handleRef} className={cn.handle} style={handleStyle} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Slider.propTypes = {
|
||||
id: PropTypes.string,
|
||||
color: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Slider;
|
@ -0,0 +1,68 @@
|
||||
.main {
|
||||
position: relative;
|
||||
width: 360px;
|
||||
flex-shrink: 0;
|
||||
padding: 0.375rem 0;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.moving {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.handle {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
box-shadow:
|
||||
rgba(0, 0, 0, 0.15) 0 0 0 1px,
|
||||
rgba(0, 0, 0, 0.05) 0 10px 10px -5px;
|
||||
height: 1.25rem;
|
||||
width: 1.25rem;
|
||||
border-radius: 9999px;
|
||||
position: absolute;
|
||||
top: 0rem;
|
||||
cursor: grab;
|
||||
border: 0.25rem solid white;
|
||||
left: -0.625rem;
|
||||
}
|
||||
|
||||
.moving .handle,
|
||||
.handle:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.background {
|
||||
border-radius: 0.25rem;
|
||||
background-color: var(--bulma-border);
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
.hue {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
rgb(255, 0, 0),
|
||||
rgb(255, 255, 0),
|
||||
rgb(0, 255, 0),
|
||||
rgb(0, 255, 255),
|
||||
rgb(0, 0, 255),
|
||||
rgb(255, 0, 255),
|
||||
rgb(255, 0, 0)
|
||||
);
|
||||
}
|
||||
|
||||
.saturation {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
hsl(var(--h), 0%, var(--l)),
|
||||
hsl(var(--h), var(--s), var(--l)),
|
||||
hsl(var(--h), 100%, var(--l))
|
||||
);
|
||||
}
|
||||
|
||||
.lightness {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
hsl(var(--h), var(--s), 0%),
|
||||
hsl(var(--h), var(--s), 50%),
|
||||
hsl(var(--h), var(--s), 100%)
|
||||
);
|
||||
}
|
3
docs/_react/bulma-customizer/src/components/VarInput.jsx
Normal file
3
docs/_react/bulma-customizer/src/components/VarInput.jsx
Normal file
@ -0,0 +1,3 @@
|
||||
function VarInput() {}
|
||||
|
||||
export default VarInput;
|
102
docs/_react/bulma-customizer/src/components/VarItem.jsx
Normal file
102
docs/_react/bulma-customizer/src/components/VarItem.jsx
Normal file
@ -0,0 +1,102 @@
|
||||
import { useContext } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import Slider from "./Slider";
|
||||
import { CustomizerContext } from "../App";
|
||||
|
||||
import cn from "./VarItem.module.css";
|
||||
import classNames from "classnames";
|
||||
|
||||
function VarItem({ id }) {
|
||||
const { cssvars, updateVar } = useContext(CustomizerContext);
|
||||
|
||||
const cssvar = cssvars[id];
|
||||
|
||||
if (!cssvar) {
|
||||
return;
|
||||
}
|
||||
|
||||
const handleReset = (event) => {
|
||||
event.preventDefault();
|
||||
updateVar(cssvar.id, cssvar.start);
|
||||
};
|
||||
|
||||
const handleInputChange = (event, cssvar) => {
|
||||
let value = event.target.value;
|
||||
updateVar(cssvar.id, value);
|
||||
};
|
||||
|
||||
const isDisabled = cssvar.current == cssvar.start;
|
||||
const resetClass = classNames({
|
||||
"button is-small": true,
|
||||
"is-float-right": true,
|
||||
"ml-2": true,
|
||||
"is-danger is-outlined": !isDisabled,
|
||||
});
|
||||
const resetStyle = isDisabled ? { opacity: 0.1 } : {};
|
||||
|
||||
let control;
|
||||
|
||||
switch (cssvar.kind) {
|
||||
case "hue":
|
||||
case "saturation":
|
||||
case "lightness":
|
||||
case "delta":
|
||||
control = (
|
||||
<>
|
||||
<Slider id={cssvar.id} />
|
||||
|
||||
<p className={cn.form}>
|
||||
<input
|
||||
type="text"
|
||||
className="input"
|
||||
value={cssvar.current}
|
||||
onChange={(e) => handleInputChange(e, cssvar)}
|
||||
size="3"
|
||||
/>
|
||||
<span>{cssvar.unit}</span>
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
control = (
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={cssvar.current}
|
||||
onChange={(e) => handleInputChange(e, cssvar)}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn.main}>
|
||||
<div className={cn.side}>
|
||||
<button
|
||||
className={resetClass}
|
||||
onClick={handleReset}
|
||||
disabled={isDisabled}
|
||||
style={resetStyle}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
|
||||
<div className={cn.name}>
|
||||
<code>{cssvar.id}</code>
|
||||
</div>
|
||||
|
||||
<div className={cn.description}>{cssvar.description}</div>
|
||||
</div>
|
||||
|
||||
<div className={cn.slider}>{control}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
VarItem.propTypes = {
|
||||
id: PropTypes.string,
|
||||
};
|
||||
|
||||
export default VarItem;
|
@ -0,0 +1,67 @@
|
||||
.main {
|
||||
gap: var(--var-item-gap);
|
||||
border-top: 1px solid var(--bulma-border);
|
||||
padding: var(--var-item-padding);
|
||||
transition-property: background-color;
|
||||
transition-duration: var(--bulma-duration);
|
||||
}
|
||||
|
||||
.main:hover {
|
||||
background-color: var(--bulma-background);
|
||||
}
|
||||
|
||||
.side {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.name {
|
||||
gap: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.name code {
|
||||
color: var(--bulma-primary);
|
||||
font-size: 1em;
|
||||
font-weight: 400;
|
||||
padding: 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.slider {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
/* padding: 2px 0; */
|
||||
flex-shrink: 0;
|
||||
width: var(--var-item-slider-width);
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: var(--bulma-family-code);
|
||||
gap: 0.25em;
|
||||
}
|
||||
|
||||
.form input {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
padding: 0.25em;
|
||||
height: auto;
|
||||
border-radius: 0.25em;
|
||||
width: 3em;
|
||||
padding: 0 0.25em;
|
||||
}
|
||||
|
||||
.form span {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.description {
|
||||
flex-shrink: 1;
|
||||
flex-grow: 1;
|
||||
margin: -0.25rem 0 0.5rem;
|
||||
font-size: 0.875em;
|
||||
}
|
1576
docs/_react/bulma-customizer/src/constants.js
Normal file
1576
docs/_react/bulma-customizer/src/constants.js
Normal file
File diff suppressed because it is too large
Load Diff
68
docs/_react/bulma-customizer/src/index.css
Normal file
68
docs/_react/bulma-customizer/src/index.css
Normal file
@ -0,0 +1,68 @@
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
9
docs/_react/bulma-customizer/src/main.jsx
Normal file
9
docs/_react/bulma-customizer/src/main.jsx
Normal file
@ -0,0 +1,9 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("bulma-customizer-app")).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
);
|
17
docs/_react/bulma-customizer/src/pages/Colors.jsx
Normal file
17
docs/_react/bulma-customizer/src/pages/Colors.jsx
Normal file
@ -0,0 +1,17 @@
|
||||
import Color from "../components/Color";
|
||||
|
||||
const COLORS = ["primary", "link", "info", "success", "warning", "danger"];
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Colors() {
|
||||
return (
|
||||
<div className={cn.colors}>
|
||||
{COLORS.map((color) => {
|
||||
return <Color key={color} color={color} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Colors;
|
18
docs/_react/bulma-customizer/src/pages/Generic.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/Generic.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "../components/VarItem";
|
||||
import { CSSVAR_KEYS } from "../constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Generic() {
|
||||
const ids = CSSVAR_KEYS.generic.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Generic;
|
18
docs/_react/bulma-customizer/src/pages/Other.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/Other.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "../components/VarItem";
|
||||
import { CSSVAR_KEYS } from "../constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Other() {
|
||||
const ids = CSSVAR_KEYS.other.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Other;
|
18
docs/_react/bulma-customizer/src/pages/Scheme.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/Scheme.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "../components/VarItem";
|
||||
import { CSSVAR_KEYS } from "../constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Scheme() {
|
||||
const schemeIds = CSSVAR_KEYS.scheme.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{schemeIds.map((schemeId) => {
|
||||
return <VarItem key={schemeId} id={schemeId} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Scheme;
|
18
docs/_react/bulma-customizer/src/pages/Skeleton.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/Skeleton.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "../components/VarItem";
|
||||
import { CSSVAR_KEYS } from "../constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Skeleton() {
|
||||
const ids = CSSVAR_KEYS.skeleton.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Skeleton;
|
18
docs/_react/bulma-customizer/src/pages/Typography.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/Typography.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "../components/VarItem";
|
||||
import { CSSVAR_KEYS } from "../constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Typography() {
|
||||
const ids = CSSVAR_KEYS.typography.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Typography;
|
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Breadcrumb() {
|
||||
const ids = CSSVAR_KEYS.breadcrumb.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Breadcrumb;
|
18
docs/_react/bulma-customizer/src/pages/components/Card.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/components/Card.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Card() {
|
||||
const ids = CSSVAR_KEYS.card.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Card;
|
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Dropdown() {
|
||||
const ids = CSSVAR_KEYS.dropdown.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Dropdown;
|
18
docs/_react/bulma-customizer/src/pages/components/Menu.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/components/Menu.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Menu() {
|
||||
const ids = CSSVAR_KEYS.menu.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Menu;
|
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Message() {
|
||||
const ids = CSSVAR_KEYS.message.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Message;
|
18
docs/_react/bulma-customizer/src/pages/components/Modal.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/components/Modal.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Modal() {
|
||||
const ids = CSSVAR_KEYS.modal.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Modal;
|
18
docs/_react/bulma-customizer/src/pages/components/Navbar.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/components/Navbar.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Navbar() {
|
||||
const ids = CSSVAR_KEYS.navbar.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Navbar;
|
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Pagination() {
|
||||
const ids = CSSVAR_KEYS.pagination.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Pagination;
|
18
docs/_react/bulma-customizer/src/pages/components/Panel.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/components/Panel.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Panel() {
|
||||
const ids = CSSVAR_KEYS.panel.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Panel;
|
18
docs/_react/bulma-customizer/src/pages/components/Tabs.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/components/Tabs.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Tabs() {
|
||||
const ids = CSSVAR_KEYS.tabs.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Tabs;
|
18
docs/_react/bulma-customizer/src/pages/elements/Box.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Box.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Box() {
|
||||
const ids = CSSVAR_KEYS.box.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Box;
|
18
docs/_react/bulma-customizer/src/pages/elements/Content.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Content.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Content() {
|
||||
const ids = CSSVAR_KEYS.content.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Content;
|
18
docs/_react/bulma-customizer/src/pages/elements/Delete.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Delete.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Delete() {
|
||||
const ids = CSSVAR_KEYS.delete.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Delete;
|
18
docs/_react/bulma-customizer/src/pages/elements/Icon.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Icon.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Icon() {
|
||||
const ids = CSSVAR_KEYS.icon.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Icon;
|
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Notification() {
|
||||
const ids = CSSVAR_KEYS.notification.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Notification;
|
18
docs/_react/bulma-customizer/src/pages/elements/Progress.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Progress.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Progress() {
|
||||
const ids = CSSVAR_KEYS.progress.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Progress;
|
18
docs/_react/bulma-customizer/src/pages/elements/Table.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Table.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Table() {
|
||||
const ids = CSSVAR_KEYS.table.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Table;
|
18
docs/_react/bulma-customizer/src/pages/elements/Tag.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Tag.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Tag() {
|
||||
const ids = CSSVAR_KEYS.tag.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Tag;
|
18
docs/_react/bulma-customizer/src/pages/elements/Title.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/elements/Title.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Title() {
|
||||
const ids = CSSVAR_KEYS.title.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Title;
|
18
docs/_react/bulma-customizer/src/pages/form/Control.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/form/Control.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Control() {
|
||||
const ids = CSSVAR_KEYS.control.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Control;
|
18
docs/_react/bulma-customizer/src/pages/form/File.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/form/File.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function File() {
|
||||
const ids = CSSVAR_KEYS.file.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default File;
|
18
docs/_react/bulma-customizer/src/pages/form/Input.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/form/Input.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Input() {
|
||||
const ids = CSSVAR_KEYS.input.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Input;
|
18
docs/_react/bulma-customizer/src/pages/grid/Columns.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/grid/Columns.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Columns() {
|
||||
const ids = CSSVAR_KEYS.columns.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Columns;
|
18
docs/_react/bulma-customizer/src/pages/grid/Grid.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/grid/Grid.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Grid() {
|
||||
const ids = CSSVAR_KEYS.grid.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Grid;
|
18
docs/_react/bulma-customizer/src/pages/layout/Footer.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/layout/Footer.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Footer() {
|
||||
const ids = CSSVAR_KEYS.footer.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
18
docs/_react/bulma-customizer/src/pages/layout/Hero.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/layout/Hero.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Hero() {
|
||||
const ids = CSSVAR_KEYS.hero.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Hero;
|
18
docs/_react/bulma-customizer/src/pages/layout/Media.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/layout/Media.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Media() {
|
||||
const ids = CSSVAR_KEYS.media.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Media;
|
18
docs/_react/bulma-customizer/src/pages/layout/Section.jsx
Normal file
18
docs/_react/bulma-customizer/src/pages/layout/Section.jsx
Normal file
@ -0,0 +1,18 @@
|
||||
import VarItem from "components/VarItem";
|
||||
import { CSSVAR_KEYS } from "root/constants";
|
||||
|
||||
import cn from "root/App.module.css";
|
||||
|
||||
function Section() {
|
||||
const ids = CSSVAR_KEYS.section.map((i) => i.id);
|
||||
|
||||
return (
|
||||
<div className={cn.items}>
|
||||
{ids.map((id) => {
|
||||
return <VarItem key={id} id={id} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Section;
|
9
docs/_react/bulma-customizer/src/utils.js
Normal file
9
docs/_react/bulma-customizer/src/utils.js
Normal file
@ -0,0 +1,9 @@
|
||||
export function unslug(slug) {
|
||||
// Replace hyphens and underscores with spaces
|
||||
let result = slug.replace(/[-_]/g, " ");
|
||||
|
||||
// Capitalize the first letter of each word
|
||||
return result.replace(/\b\w/g, function (char) {
|
||||
return char.toUpperCase();
|
||||
});
|
||||
}
|
23
docs/_react/bulma-customizer/vite.config.js
Normal file
23
docs/_react/bulma-customizer/vite.config.js
Normal file
@ -0,0 +1,23 @@
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
build: {
|
||||
emptyOutDir: true,
|
||||
outDir: "../../assets/javascript/bulma-customizer",
|
||||
rollupOptions: {
|
||||
output: {
|
||||
assetFileNames: "[name].css",
|
||||
entryFileNames: "[name].js",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
root: "/src",
|
||||
components: "/src/components",
|
||||
},
|
||||
},
|
||||
});
|
@ -10,6 +10,7 @@
|
||||
padding: calc(var(--scale) * 3rem);
|
||||
text-align: center;
|
||||
|
||||
&.is-horizontal,
|
||||
&.is-docs {
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
@ -30,6 +31,10 @@
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-horizontal {
|
||||
padding: calc(var(--scale) * 3rem);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1000px) {
|
||||
|
@ -36819,23 +36819,26 @@ has-background-moon.is-hoverable:active {
|
||||
padding: calc(var(--scale) * 3rem);
|
||||
text-align: center;
|
||||
}
|
||||
.bd-hero.is-docs {
|
||||
.bd-hero.is-horizontal, .bd-hero.is-docs {
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.bd-hero.is-docs .bd-hero-body {
|
||||
.bd-hero.is-horizontal .bd-hero-body, .bd-hero.is-docs .bd-hero-body {
|
||||
flex-basis: 20em;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.bd-hero.is-docs .bd-hr {
|
||||
.bd-hero.is-horizontal .bd-hr, .bd-hero.is-docs .bd-hr {
|
||||
margin-left: 0;
|
||||
}
|
||||
.bd-hero.is-docs .bd-hero-prints {
|
||||
.bd-hero.is-horizontal .bd-hero-prints, .bd-hero.is-docs .bd-hero-prints {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.bd-hero.is-horizontal {
|
||||
padding: calc(var(--scale) * 3rem);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1000px) {
|
||||
.bd-hero.is-docs {
|
||||
|
2
docs/assets/css/website.min.css
vendored
2
docs/assets/css/website.min.css
vendored
File diff suppressed because one or more lines are too long
1
docs/assets/javascript/bulma-customizer/index.css
Normal file
1
docs/assets/javascript/bulma-customizer/index.css
Normal file
@ -0,0 +1 @@
|
||||
:root{--gh-dark: #25292e;--gh-dimmed: #6a737d;--gh-text: #e1e4e8;--gh-red: #f97583;--gh-orange: #ffab70;--gh-yellow: #ffea7f;--gh-green: #85e89d;--gh-blue: #79b8ff;--gh-blue-light: #9ecbff;--gh-purple: #b392f0;--gh-pink: #f692ce}._app_1oamh_1{background-color:red;--var-item-side-width: 12rem;--var-item-slider-width: 30rem;--var-item-padding: 1rem;--var-item-gap: 1rem;bottom:1rem;overflow:hidden;position:fixed;right:1rem;z-index:100}._customizer_1oamh_14{background:var(--bulma-scheme-main);box-shadow:var(--bulma-shadow);border-radius:.5rem;transform-origin:bottom right;transition-duration:.3s;transition-property:opacity,transform;transform:scale(.98) translate(2px,2px);opacity:0;pointer-events:none;width:33rem;top:1rem;position:fixed;bottom:4.5rem;right:1rem;overflow-y:auto}._open_1oamh_32{opacity:1;pointer-events:auto;transform:none}._controls_1oamh_38{display:flex;flex-wrap:wrap;gap:.5rem;padding:.5rem}._buttons_1oamh_45{display:flex;gap:.5rem;bottom:1rem;right:1rem;position:fixed}._button_1oamh_45{gap:.5rem}._main_1gut5_1{position:relative;width:360px;flex-shrink:0;padding:.375rem 0;cursor:grab}._moving_1gut5_9{cursor:grabbing}._handle_1gut5_13{background-color:#ffffff0d;box-shadow:#00000026 0 0 0 1px,#0000000d 0 10px 10px -5px;height:1.25rem;width:1.25rem;border-radius:9999px;position:absolute;top:0rem;cursor:grab;border:.25rem solid white;left:-.625rem}._moving_1gut5_9 ._handle_1gut5_13,._handle_1gut5_13:active{cursor:grabbing}._background_1gut5_33{border-radius:.25rem;background-color:var(--bulma-border);height:.5rem}._hue_1gut5_39{background-image:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}._saturation_1gut5_52{background-image:linear-gradient(to right,hsl(var(--h),0%,var(--l)),hsl(var(--h),var(--s),var(--l)),hsl(var(--h),100%,var(--l)))}._lightness_1gut5_61{background-image:linear-gradient(to right,hsl(var(--h),var(--s),0%),hsl(var(--h),var(--s),50%),hsl(var(--h),var(--s),100%))}._main_17ce3_1{border-top:1px solid var(--bulma-border);padding:var(--var-item-padding);justify-content:center}._swatch_17ce3_7{background-color:hsl(var(--h) var(--s) var(--l));height:1.25rem;width:1.25rem;border-radius:.25rem;flex-shrink:0}._name_17ce3_15{color:var(--bulma-primary);gap:1rem;display:flex;align-items:center;margin-bottom:.5rem}._name_17ce3_15 p{color:var(--bulma-text-strong);font-size:1.25em;font-weight:600}._lines_17ce3_29{display:flex;flex-direction:column;gap:.25rem}._line_17ce3_29{display:flex;flex-wrap:wrap;align-items:center;gap:0 1.5rem}._line_17ce3_29 p{color:var(--bulma-text-strong)}._label_17ce3_46{width:100%}._slider_17ce3_50{display:flex;align-items:center;gap:0 1.5rem}._form_17ce3_56{display:flex;align-items:center;font-family:var(--bulma-family-code);gap:.25em;width:6rem}._form_17ce3_56 input{font-family:inherit;font-size:inherit;height:auto;border-radius:.25em;width:3em;padding:0 .25em}._form_17ce3_56 span{opacity:.5}._example_17ce3_78{margin-top:.5rem}._main_1itpo_1{gap:var(--var-item-gap);border-top:1px solid var(--bulma-border);padding:var(--var-item-padding);transition-property:background-color;transition-duration:var(--bulma-duration)}._main_1itpo_1:hover{background-color:var(--bulma-background)}._side_1itpo_13{flex-shrink:0}._name_1itpo_17{gap:1rem;display:flex;align-items:center;margin-bottom:.5rem}._name_1itpo_17 code{color:var(--bulma-primary);font-size:1em;font-weight:400;padding:0;background:none}._slider_1itpo_32{align-items:center;display:flex;gap:1.5rem;flex-shrink:0;width:var(--var-item-slider-width)}._form_1itpo_41{display:flex;align-items:center;font-family:var(--bulma-family-code);gap:.25em}._form_1itpo_41 input{font-family:inherit;font-size:inherit;height:auto;border-radius:.25em;width:3em;padding:0 .25em}._form_1itpo_41 span{opacity:.5}._description_1itpo_62{flex-shrink:1;flex-grow:1;margin:-.25rem 0 .5rem;font-size:.875em}._main_uds4w_1{padding:.5rem}._body_uds4w_5{padding:.5rem 1rem}._body_uds4w_5 .title{margin-bottom:.25rem}._explanation_uds4w_13{display:flex;align-items:center;justify-content:space-between}._explanation_uds4w_13 p{padding:3px 0}._explanation_uds4w_13 div{flex-wrap:nowrap}._go_uds4w_27{margin-top:.5rem}._pre_uds4w_31{background-color:var(--gh-dark);margin:.5rem -.5rem;color:var(--gh-text);font-size:1rem}
|
47
docs/assets/javascript/bulma-customizer/index.html
Normal file
47
docs/assets/javascript/bulma-customizer/index.html
Normal file
@ -0,0 +1,47 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React</title>
|
||||
<style type="text/css">
|
||||
#bulma-customizer-app {
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/index.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="bulma-customizer-app"></div>
|
||||
<div id="scope" class="is-hidden">
|
||||
<div class="breadcrumb"></div>
|
||||
<div class="card"></div>
|
||||
<div class="dropdown"></div>
|
||||
<div class="menu"></div>
|
||||
<div class="message"></div>
|
||||
<div class="modal"></div>
|
||||
<div class="navbar"></div>
|
||||
<div class="pagination"></div>
|
||||
<div class="panel"></div>
|
||||
<div class="tabs"></div>
|
||||
<div class="box"></div>
|
||||
<div class="content"></div>
|
||||
<div class="delete"></div>
|
||||
<div class="icon"></div>
|
||||
<div class="notification"></div>
|
||||
<div class="progress"></div>
|
||||
<table class="table"></table>
|
||||
<div class="tag"></div>
|
||||
<div class="title"></div>
|
||||
<input class="input" />
|
||||
<div class="file"></div>
|
||||
<div class="columns"></div>
|
||||
<div class="grid"></div>
|
||||
<div class="footer"></div>
|
||||
<div class="hero"></div>
|
||||
<div class="media"></div>
|
||||
<div class="section"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
48
docs/assets/javascript/bulma-customizer/index.js
Normal file
48
docs/assets/javascript/bulma-customizer/index.js
Normal file
File diff suppressed because one or more lines are too long
@ -155,6 +155,10 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
if ($clickableDropdowns.length > 0) {
|
||||
$clickableDropdowns.forEach(($dropdown) => {
|
||||
if (!$dropdown.querySelector("button")) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dropdown.querySelector("button").addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
$dropdown.classList.toggle("is-active");
|
||||
|
9
docs/customizer.html
Normal file
9
docs/customizer.html
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
layout: default
|
||||
theme: customizer
|
||||
route: customizer
|
||||
---
|
||||
|
||||
{% include global/header.html %} {% include docs/hero.html variant="horizontal"
|
||||
title="The Bulma Customizer" subtitle="Easily customize Bulma with your own CSS
|
||||
variables." %}
|
@ -31,9 +31,9 @@ breadcrumb:
|
||||
</div>
|
||||
<div class="media-content">
|
||||
<p class="title is-5">Use the <strong>HTML5 doctype</strong></p>
|
||||
{% highlight html %}
|
||||
<!doctype html>
|
||||
{% endhighlight %}
|
||||
{%- highlight html -%}
|
||||
<!DOCTYPE html>
|
||||
{%- endhighlight -%}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
|
44
docs/package-lock.json
generated
44
docs/package-lock.json
generated
@ -1,19 +1,17 @@
|
||||
{
|
||||
"name": "bulma-docs",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bulma-docs",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sass": "^1.71.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@shopify/prettier-plugin-liquid": "^1.4.4",
|
||||
"prettier": "^3.2.4"
|
||||
"prettier": "^3.2.4",
|
||||
"sass": "^1.71.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@shopify/liquid-html-parser": {
|
||||
@ -43,6 +41,7 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
@ -55,6 +54,7 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
@ -63,11 +63,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@ -77,6 +78,7 @@
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
@ -97,9 +99,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@ -111,6 +114,7 @@
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
@ -124,6 +128,7 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
@ -140,12 +145,14 @@
|
||||
"node_modules/immutable": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
|
||||
"integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw=="
|
||||
"integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
@ -157,6 +164,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -165,6 +173,7 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
@ -176,6 +185,7 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@ -212,6 +222,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -229,6 +240,7 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
@ -255,6 +267,7 @@
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
@ -266,6 +279,7 @@
|
||||
"version": "1.72.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz",
|
||||
"integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
@ -282,6 +296,7 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -290,6 +305,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user