Compare commits

..

86 commits
shop ... main

Author SHA1 Message Date
Jeremy Thomas
7f4c17bb55 Fix banner overflow 2025-02-05 14:05:26 +00:00
Jeremy Thomas
96a2497155
Merge pull request #3958 from martinkupa/fix-docs
[Docs] Mention required order on form controls' modifiers
2025-01-17 14:32:07 +00:00
Jeremy Thomas
8bf59deadc Fix banner 2025-01-16 13:01:55 +00:00
martinkupa
cce4b20117 Mention required order on form controls' modifiers 2025-01-10 16:44:45 -03:00
Jeremy Thomas
785418143e Build 1.0.3 2024-12-27 21:25:24 +01:00
Jeremy Thomas
e23cfc1262 Fix README 2024-12-05 15:18:44 +00:00
Jeremy Thomas
33eeeab44e Update docs dependencies 2024-12-04 23:24:49 +00:00
Jeremy Thomas
679bef8568 Update dependencies 2024-12-04 23:24:49 +00:00
Jeremy Thomas
2172fa18c9
Merge pull request #3873 from smudja/patch-1
Correct spelling in modular.html
2024-11-27 16:11:42 +00:00
Jeremy Thomas
eb4ff2ad41
Merge pull request #3930 from jnoordsij/fix-branch-references
Update various references from master to main brach
2024-11-27 16:11:11 +00:00
Jeremy Thomas
3b3ef02f29
Merge pull request #3773 from tonprince/main
fixed disabled state for is-outlined button
2024-11-27 16:01:36 +00:00
Jeremy Thomas
4ebf14b538
Merge pull request #3940 from SomethingNew71/sass-deprecation-fix
Updates deprecated round functions in Sass Build
2024-11-27 15:47:28 +00:00
Cole Gentry
125f8f8994 Updates deprecated round functions
Signed-off-by: Cole Gentry <peapod2007@gmail.com>
2024-11-24 11:44:39 -05:00
Jeremy Thomas
6374a8094d Fix #3926 2024-11-11 10:32:08 +00:00
Jeremy Thomas
5531ee1d11 Fix #3920 2024-11-11 10:22:12 +00:00
Jeremy Thomas
4abe784fc4 Rebuild website CSS 2024-11-07 14:48:46 +00:00
Jeremy Thomas
eaab45a2ca Build CSS 2024-11-07 14:40:23 +00:00
Jeremy Thomas
70ecf0771e Merge branch 'masterclass' 2024-11-07 14:32:06 +00:00
Jeremy Thomas
b85d1898c1 Fix #3918 2024-11-07 14:16:51 +00:00
Jeremy Thomas
1c7fa94bf1 Add fallback 2024-11-07 13:08:51 +00:00
Jeremy Thomas
fc52c88009 Add banner 2024-11-07 12:44:39 +00:00
Jeremy Thomas
66b6a46451 Init Masterclass 2024-11-07 12:26:30 +00:00
Jesper Noordsij
4b3654aad7
Update various references from master to main brach 2024-10-30 16:13:17 +01:00
Jeremy Thomas
3b63997ad2 Remove shop link 2024-10-18 13:53:06 +01:00
Jeremy Thomas
acc5fd2d1e
Merge pull request #3913 from thecodechef/patch-1
Update love.json
2024-10-18 13:50:43 +01:00
Jeremy Bolding
82640b0e14
Update love.json
Updated `@db4you` to `@gebsystems` username and fullname also fixed avatar
2024-09-28 03:48:59 -05:00
Jeremy Thomas
4301d4de48
Merge pull request #3900 from thecodechef/main
[Fixed] the twitter link now show up in twitter cards Fixes #3898
2024-09-20 15:33:30 +01:00
Jeremy Thomas
15ff0be367 Add documentation of all CSS variables available 2024-09-18 14:46:10 +01:00
Jeremy Thomas
29aea4dfc4 Fix #3842: restore use of $easing, $radius-rounded and $speed Sass variables 2024-09-18 12:41:28 +01:00
Jeremy Thomas
9e64f5034f Fix #3849: fix Light Mode color swatches in Dark Mode 2024-09-18 12:38:23 +01:00
Jeremy Thomas
1bc01f2676 Fix #3904, #3884: fix website horizontal overflow 2024-09-18 12:28:20 +01:00
Jeremy Bolding
98e7ac3c12
Merge pull request #1 from thecodechef/update-twitter-links
Changed `twitter.com` to `x.com` in `_includes/docs/elements/tw.html` Fixes #3898
2024-09-11 11:53:59 -05:00
Jeremy Bolding
ac4ba07d78
Changed twitter.com to x.com in _includes/docs/elements/tw.html 2024-09-11 11:49:33 -05:00
Corentin Hervaud
9a1b620195 FIx error in example code in with-modular-sass.html 2024-09-04 16:54:14 +01:00
smudja
664f9f14da
Correct spelling
compnents  -> components
2024-08-05 13:21:12 +02:00
Jeremy Thomas
5c09f18f5f Set 1.0.2 as main version 2024-08-02 20:20:00 +01:00
Jeremy Thomas
0ce430fc1a Update docs packages 2024-08-02 20:19:33 +01:00
Sébastien Conejo
dc8fadb764 feat: Update renamed project: CASE becomes Manifest 2024-08-01 00:15:40 +01:00
Jeremy Thomas
230b21f7fb
Merge pull request #3862 from eltociear/patch-3
docs: update modal.html
2024-07-27 15:53:40 +02:00
Ikko Eltociear Ashimine
09411bcbbf
docs: update modal.html
seperate -> separate
2024-07-27 02:14:35 +09:00
Jeremy Thomas
3fd2f65026 Build 1.0.2 2024-07-25 16:58:39 +02:00
Jeremy Thomas
0c05f2874e
Merge pull request #3860 from jgthms/1.0.2
1.0.2
2024-07-25 16:56:55 +02:00
Jeremy Thomas
66eda9537e Merge branch 'main' into 1.0.2 2024-07-25 16:52:23 +02:00
Jeremy Thomas
66336ea4f2 Fix #3757 2024-07-25 16:50:50 +02:00
Jeremy Thomas
3769027216 Fix #3856 2024-07-25 16:29:34 +02:00
Jeremy Thomas
a2b16c2fa7 Update Sidebar 2024-07-11 13:17:08 +01:00
Jeremy Thomas
05f898d4d8 Add more Sass and CSS variables 2024-07-07 21:01:04 +01:00
Jeremy Thomas
ab4a7b7d18 Add fullheight Section, Add more color helpers, Add tablet Container, Add list of checkboxes and radios 2024-07-07 17:59:24 +01:00
Jeremy Thomas
2ed62be159 Fix #3775, Fix #3829 2024-07-06 15:42:36 +01:00
Jeremy Thomas
fc7db1b204 Fix doc urls 2024-07-01 15:37:50 +01:00
Jeremy Thomas
8ed556711b
Merge pull request #3837 from bagedevimo/fix-bulma-color-brightness
Fix bulma color brightness
2024-07-01 15:32:22 +01:00
Jeremy Thomas
bbd8d21bf2
Merge pull request #3848 from jgthms/customizer
Add Bulma Customizer
2024-06-27 04:21:44 +01:00
Jeremy Thomas
7ac0831470 Add box shadow 2024-06-27 04:19:20 +01:00
Jeremy Thomas
ff3ffb12ef Fix styling 2024-06-27 04:03:20 +01:00
Jeremy Thomas
d3e01494db Fix Export 2024-06-27 03:50:54 +01:00
Jeremy Thomas
3c1e19a9ad Add Export toggle 2024-06-27 03:04:40 +01:00
Jeremy Thomas
96de5b2f45 Add Export 2024-06-27 02:00:43 +01:00
Jeremy Thomas
762926d492 Fix styling 2024-06-27 01:26:39 +01:00
Jeremy Thomas
bb62f531e1 Add open state 2024-06-27 01:03:51 +01:00
Jeremy Thomas
068b93a878 Make Customizer a floating window 2024-06-27 00:35:13 +01:00
Jeremy Thomas
493aa56bbb Add Components 2024-06-26 20:00:17 +01:00
Jeremy Thomas
303da19588 Add Control vars 2024-06-26 16:06:52 +01:00
Jeremy Thomas
891e6e3cb7 Add layout elements 2024-06-26 15:29:29 +01:00
Jeremy Thomas
f9a418dd26 Merge branch 'main' into customizer 2024-06-26 15:02:27 +01:00
Jeremy Thomas
fbbb85d40a Fix #3743, Fix #3799, Fix #3846 2024-06-26 14:59:42 +01:00
Jeremy Thomas
a2bd136efa Add Form elements 2024-06-26 14:33:43 +01:00
Jeremy Thomas
7670f4eed9 Add all Elements 2024-06-26 02:36:41 +01:00
Jeremy Thomas
5b9f3a0d2a Add scopes 2024-06-26 01:49:55 +01:00
Jeremy Thomas
fd13432ccc Add Generic vars 2024-06-26 00:49:42 +01:00
Jeremy Thomas
e0477953b3 Add Typography 2024-06-25 23:28:12 +01:00
Jeremy Thomas
c638115ef2 Add Scheme vars 2024-06-25 23:12:07 +01:00
Jeremy Thomas
0014fc4e34 Add Color module 2024-06-25 22:20:37 +01:00
Jeremy Thomas
cb2de3a2a2 Add Hex prompt 2024-06-25 16:20:07 +01:00
Jeremy Thomas
2cc6593269 Add Reset button 2024-06-25 13:48:53 +01:00
Jeremy Thomas
0c9ae61698 Create Context 2024-06-25 03:59:13 +01:00
Jeremy Thomas
34029baa2c Add HSL sliders 2024-06-24 04:10:08 +01:00
Jeremy Thomas
681592e689 Improve Slider 2024-06-24 03:48:38 +01:00
Jeremy Thomas
4a165737df Create Slider 2024-06-24 03:25:58 +01:00
Jeremy Thomas
7d92a2b872 Init Customizer 2024-06-24 01:08:40 +01:00
Jeremy Thomas
74c01f42d1 Fix #3830 2024-06-23 23:35:32 +01:00
Jeremy Thomas
1ad4cb21a2 Fix #3824 2024-06-23 23:09:54 +01:00
Jeremy Thomas
d48e275f43 Fix #3823 2024-06-23 22:56:35 +01:00
Jeremy Thomas
45d70e7e65
Merge pull request #3838 from jgthms/shop
Shop
2024-06-11 15:15:36 +01:00
Ben Anderson
b252b86cfa
Replace deprecated use of division operator wiith call to math.div 2024-06-11 15:35:53 +12:00
Ben Anderson
4236077572
Correct the implementation of bulmaColorBrightness
Instead of using all channels of the colour to approximate brightness,
this function was sublty ignoring the blue channel and over-stating
other channels.
2024-06-11 15:34:34 +12:00
Stefan Sommer
1a84fafd63 fixed disabled state for is-outlined button 2024-04-05 09:17:18 +07:00
229 changed files with 48321 additions and 35960 deletions

View file

@ -22,10 +22,10 @@ This is a **new feature | improvement | bugfix | documentation fix**.
None. None.
<!-- BEFORE SUBMITTING YOUR PR, MAKE SURE TO FOLLOW THESE STEPS: --> <!-- BEFORE SUBMITTING YOUR PR, MAKE SURE TO FOLLOW THESE STEPS: -->
<!-- 1. Pull the latest `master` branch --> <!-- 1. Pull the latest `main` branch -->
<!-- 2. Make sure your Sass code is compliant with the [Bulma Sass styleguide](https://github.com/jgthms/bulma/blob/master/.github/CONTRIBUTING.md#bulma-sass-styleguide) --> <!-- 2. Make sure your Sass code is compliant with the [Bulma Sass styleguide](https://github.com/jgthms/bulma/blob/main/.github/CONTRIBUTING.md#bulma-sass-styleguide) -->
<!-- 3. Make sure your PR only affects `.sass` or documentation files --> <!-- 3. Make sure your PR only affects `.sass` or documentation files -->
<!-- 4. [Try your changes](https://github.com/jgthms/bulma/blob/master/.github/CONTRIBUTING.md#try-your-changes). --> <!-- 4. [Try your changes](https://github.com/jgthms/bulma/blob/main/.github/CONTRIBUTING.md#try-your-changes). -->
<!-- How have you confirmed this feature works? --> <!-- How have you confirmed this feature works? -->
<!-- Please explain more than "Yes". --> <!-- Please explain more than "Yes". -->

3
.gitignore vendored
View file

@ -6,7 +6,9 @@ npm-debug.log
test.css test.css
test.css.map test.css.map
test.html test.html
test*.html
test.sass test.sass
test.scss
test.css test.css
test.css.map test.css.map
@ -17,5 +19,6 @@ test.css.map
_gh_pages _gh_pages
_site _site
dev dev
dist
node_modules node_modules
test/output/ test/output/

View file

@ -1,5 +1,56 @@
# Bulma Changelog # Bulma Changelog
## 1.0.3
### Bug Fixes
- Fix #3842: restore use of `$easing`, `$radius-rounded` and `$speed` Sass variables
- Fix #3920: migrate code to avoid Sass 1.80 deprecation warning of global built-in functions
- Fix #3822: Non-minified version of bulma-prefixed was missing
- Fix #3805: helper classes were missing prefix
### Documentation Fixes
- Fix #3904, #3884: fix website horizontal overflow
- Fix #3849: fix Light Mode color swatches in Dark Mode
- Fix #3918: broken placeholder images
- Fix #3926: broken documentation hero
## 1.0.2
### Improvements
- Smart Grid `is-col-min` now goes up to `32` (Fixes #3829)
- Remove need for `is-variable` modifier for Column gaps
- You can have a list of radio buttons or checkboxes with the `radios` and `checkboxes` classes respectively
- Add `is-max-tablet` modifier to the Container element
- Add `currentColor` and `inherit` as possible values for the color and background helpers
- The Section can now have a minimum height of `100vh` with the `is-fullheight` modifier
- Add more SCSS variables:
- `$input-border-style`
- `$input-border-width`
- `$label-spacing`
- `$field-block-spacing`
- Add more CSS variables:
- `--bulma-input-border-style`
- `--bulma-input-border-width`
- `--bulma-label-color`
- `--bulma-label-spacing`
- `--bulma-label-weight`
- `--bulma-help-size`
- `--bulma-field-block-spacing`
### Bug fixes
- Fix #3824: ability to override `$scheme-h`, `$scheme-s`, `$dark-l` and `$light-l` Sass variables
- Fix #3830: add remaining logical properties
- Fix #3743: make sure 12 columns system take up whole width
- Fix #3799: restore variable columns
- Fix #3846: restore `--bulma-column-gap` CSS variable
- Fix #3775: `has-background` helpers should only affect element it's applied to
- Fix #3856: Sass nested rule deprecation warning
- Fix #3757: restore use of `$navbar-burger-color`
## 1.0.1 ## 1.0.1
### Bug fixes ### Bug fixes

View file

@ -52,7 +52,7 @@ Feel free to raise an issue or submit a pull request.
## CSS only ## CSS only
Bulma is a **CSS** framework. As such, the sole output is a single CSS file: [bulma.css](https://github.com/jgthms/bulma/blob/master/css/bulma.css) Bulma is a **CSS** framework. As such, the sole output is a single CSS file: [bulma.css](https://github.com/jgthms/bulma/blob/main/css/bulma.css)
You can either use that file, "out of the box", or download the Sass source files to customize the [variables](https://bulma.io/documentation/customize/#docsNav). You can either use that file, "out of the box", or download the Sass source files to customize the [variables](https://bulma.io/documentation/customize/#docsNav).
@ -131,12 +131,14 @@ Browse the [online documentation here.](https://bulma.io/documentation/start/ove
| [@angular-bulma](https://quinnjr.github.io/angular-bulma) | [Angular](https://angular.io/) directives and components to use in your Bulma projects | | [@angular-bulma](https://quinnjr.github.io/angular-bulma) | [Angular](https://angular.io/) directives and components to use in your Bulma projects |
| [Bulma CSS Class Completion](https://github.com/eliutdev/bulma-css-class-completion) | CSS class name completion for the HTML class attribute based on Bulma CSS classes. | | [Bulma CSS Class Completion](https://github.com/eliutdev/bulma-css-class-completion) | CSS class name completion for the HTML class attribute based on Bulma CSS classes. |
| [Crispy-Bulma](https://github.com/ckrybus/crispy-bulma) | Bulma template pack for django-crispy-forms | | [Crispy-Bulma](https://github.com/ckrybus/crispy-bulma) | Bulma template pack for django-crispy-forms |
| [CASE](https://case.app) | CASE is Lightweight Backend-as-a-Service with essential features: DB, Admin panel, API, JS SDK | | [Manifest](https://manifest.build) | Manifest is a lightweight Backend-as-a-Service with essential features: DB, Admin panel, API, JS SDK |
| [Reactive Bulma](https://github.com/NicolasOmar/reactive-bulma) | A component library based on React, Bulma, Typescript and Rollup | | [Reactive Bulma](https://github.com/NicolasOmar/reactive-bulma) | A component library based on React, Bulma, Typescript and Rollup |
<p>Browser testing via<br /><a href="https://www.lambdatest.com/" target="_blank"><img src="https://bulma.io/assets/images/amis/lambdatest-logo.png" width="168" height="40" /></a></p>
## Copyright and license ![Github](https://img.shields.io/github/license/jgthms/bulma?logo=Github) ## Copyright and license ![Github](https://img.shields.io/github/license/jgthms/bulma?logo=Github)
Code copyright 2023 Jeremy Thomas. Code released under [the MIT license](https://github.com/jgthms/bulma/blob/master/LICENSE). Code copyright 2023 Jeremy Thomas. Code released under [the MIT license](https://github.com/jgthms/bulma/blob/main/LICENSE).
[npm-link]: https://www.npmjs.com/package/bulma [npm-link]: https://www.npmjs.com/package/bulma
[awesome-link]: https://github.com/awesome-css-group/awesome-css [awesome-link]: https://github.com/awesome-css-group/awesome-css

View file

@ -1,6 +1,6 @@
{ {
"name": "bulma", "name": "bulma",
"version": "1.0.0", "version": "1.0.3",
"homepage": "https://bulma.io", "homepage": "https://bulma.io",
"authors": ["jgthms <bbxdesign@gmail.com>"], "authors": ["jgthms <bbxdesign@gmail.com>"],
"description": "Modern CSS framework based on Flexbox", "description": "Modern CSS framework based on Flexbox",

2
bulma.scss vendored
View file

@ -1,4 +1,4 @@
@charset "utf-8"; @charset "utf-8";
/*! bulma.io v1.0.1 | MIT License | github.com/jgthms/bulma */ /*! bulma.io v1.0.3 | MIT License | github.com/jgthms/bulma */
@use "sass"; @use "sass";

4792
css/bulma.css vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

4
css/bulma.min.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -757,7 +757,7 @@
"path": "/documentation/helpers/other-helpers/" "path": "/documentation/helpers/other-helpers/"
} }
}, },
"navbar": ["docs", "expo", "love", "sponsor", "shop"], "navbar": ["docs", "expo", "love", "sponsor"],
"navbar_icons": ["github", "twitter"], "navbar_icons": ["github", "twitter"],
"navbar_more": ["made-with-bulma", "backers", "brand", "extensions"], "navbar_more": ["made-with-bulma", "backers", "brand", "extensions"],
"category_ids": [ "category_ids": [

View file

@ -1984,9 +1984,9 @@
"id": "1161404522331344896", "id": "1161404522331344896",
"date": "11:29 PM - 13 Aug 2019", "date": "11:29 PM - 13 Aug 2019",
"content": "Bloody hell.... To think that I was using my own simple framework for all of the <a href=\"https://twitter.com/search?q=%23Frontend\">#Frontend</a> <a href=\"https://twitter.com/search?q=%23webdevelopment\">#webdevelopment</a>. Here is a my old login page vs <a href=\"https://twitter.com/search?q=%23bulmaio\">#bulmaio</a> framework... Me so dumb. Why reinvent the wheel? Amazing job <a href=\"https://twitter.com/jgthms\">@jgthms</a> <a href=\"https://twitter.com/search?q=%23CSS\">#CSS</a> <a href=\"https://t.co/X5NnKZxyQq\">pic.twitter.com/X5NnKZxyQq</a>", "content": "Bloody hell.... To think that I was using my own simple framework for all of the <a href=\"https://twitter.com/search?q=%23Frontend\">#Frontend</a> <a href=\"https://twitter.com/search?q=%23webdevelopment\">#webdevelopment</a>. Here is a my old login page vs <a href=\"https://twitter.com/search?q=%23bulmaio\">#bulmaio</a> framework... Me so dumb. Why reinvent the wheel? Amazing job <a href=\"https://twitter.com/jgthms\">@jgthms</a> <a href=\"https://twitter.com/search?q=%23CSS\">#CSS</a> <a href=\"https://t.co/X5NnKZxyQq\">pic.twitter.com/X5NnKZxyQq</a>",
"fullname": "db4you", "fullname": "gebsystems",
"username": "db4you2", "username": "gebsystems",
"avatar": "https://pbs.twimg.com/profile_images/1283183292683038727/wVhp9AQr_normal.jpg", "avatar": "https://pbs.twimg.com/profile_images/1713156593137639424/Wwz0i_rj_400x400.jpg",
"hearts": 22, "hearts": 22,
"retweets": 4 "retweets": 4
}, },

View file

@ -2,11 +2,11 @@
"title": "Bulma: Free, open source, and modern CSS framework based on Flexbox", "title": "Bulma: Free, open source, and modern CSS framework based on Flexbox",
"description": "Bulma is a free, open source CSS framework based on Flexbox and built with Sass. It's 100% responsive, fully modular, and available for free.", "description": "Bulma is a free, open source CSS framework based on Flexbox and built with Sass. It's 100% responsive, fully modular, and available for free.",
"documentation": "/documentation", "documentation": "/documentation",
"download": "https://github.com/jgthms/bulma/releases/download/1.0.0/bulma-1.0.0.zip", "download": "https://github.com/jgthms/bulma/releases/download/1.0.2/bulma-1.0.2.zip",
"release_notes": "https://github.com/jgthms/bulma/releases/tag/1.0.0", "release_notes": "https://github.com/jgthms/bulma/releases/tag/1.0.2",
"github": "https://github.com/jgthms/bulma", "github": "https://github.com/jgthms/bulma",
"twitter": "https://twitter.com/jgthms", "twitter": "https://twitter.com/jgthms",
"version": "1.0.0", "version": "1.0.2",
"book_url": "https://bleedingedgepress.com/creating-interfaces-bulma/", "book_url": "https://bleedingedgepress.com/creating-interfaces-bulma/",
"book_amazon": "https://www.amazon.com/Creating-Interfaces-Bulma-Jeremy-Thomas-ebook/dp/B079M1BJG4/", "book_amazon": "https://www.amazon.com/Creating-Interfaces-Bulma-Jeremy-Thomas-ebook/dp/B079M1BJG4/",
"book_sample": "http://www.bleedingedgepress.com/book_excerpts/01E9D1/creating_interfaces_with_bulma_sample.pdf", "book_sample": "http://www.bleedingedgepress.com/book_excerpts/01E9D1/creating_interfaces_with_bulma_sample.pdf",

View file

@ -37,7 +37,7 @@
}, },
{ {
"name": "card-header-shadow", "name": "card-header-shadow",
"value": "0 0.125em 0.25em\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.1\n )", "value": "0 0.125em 0.25em hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.1\n)",
"css-var": "card-header-shadow" "css-var": "card-header-shadow"
}, },
{ {

View file

@ -99,10 +99,6 @@
"name": "modal-card-body-padding", "name": "modal-card-body-padding",
"value": "2rem", "value": "2rem",
"css-var": "modal-card-body-padding" "css-var": "modal-card-body-padding"
},
{
"name": "modal-breakpoint",
"value": "iv.$tablet"
} }
], ],
"css-vars": [ "css-vars": [

View file

@ -2,14 +2,17 @@
"sass-vars": [ "sass-vars": [
{ {
"name": "navbar-background-color", "name": "navbar-background-color",
"css-var": "navbar-background-color",
"value": "var(--bulma-scheme-main)" "value": "var(--bulma-scheme-main)"
}, },
{ {
"name": "navbar-box-shadow-size", "name": "navbar-box-shadow-size",
"css-var": "navbar-box-shadow-size",
"value": "0 0.125em 0 0" "value": "0 0.125em 0 0"
}, },
{ {
"name": "navbar-box-shadow-color", "name": "navbar-box-shadow-color",
"css-var": "navbar-box-shadow-color",
"value": "var(--bulma-background)" "value": "var(--bulma-background)"
}, },
{ {
@ -19,124 +22,144 @@
}, },
{ {
"name": "navbar-padding-vertical", "name": "navbar-padding-vertical",
"css-var": "navbar-padding-vertical",
"value": "1rem" "value": "1rem"
}, },
{ {
"name": "navbar-padding-horizontal", "name": "navbar-padding-horizontal",
"css-var": "navbar-padding-horizontal",
"value": "2rem" "value": "2rem"
}, },
{ {
"name": "navbar-z", "name": "navbar-z",
"css-var": "navbar-z",
"value": "30" "value": "30"
}, },
{ {
"name": "navbar-fixed-z", "name": "navbar-fixed-z",
"css-var": "navbar-fixed-z",
"value": "30" "value": "30"
}, },
{ {
"name": "navbar-item-img-max-height", "name": "navbar-item-img-max-height",
"css-var": "navbar-item-img-max-height",
"value": "1.75rem" "value": "1.75rem"
}, },
{ {
"name": "navbar-burger-color", "name": "navbar-burger-color",
"css-var": "navbar-burger-color",
"value": "var(--bulma-navbar-item-color)" "value": "var(--bulma-navbar-item-color)"
}, },
{ {
"name": "navbar-tab-hover-background-color", "name": "navbar-tab-hover-background-color",
"css-var": "navbar-tab-hover-background-color",
"value": "transparent" "value": "transparent"
}, },
{ {
"name": "navbar-tab-hover-border-bottom-color", "name": "navbar-tab-hover-border-bottom-color",
"css-var": "navbar-tab-hover-border-bottom-color",
"value": "var(--bulma-link)" "value": "var(--bulma-link)"
}, },
{ {
"name": "navbar-tab-active-color", "name": "navbar-tab-active-color",
"css-var": "navbar-tab-active-color",
"value": "var(--bulma-link)" "value": "var(--bulma-link)"
}, },
{ {
"name": "navbar-tab-active-background-color", "name": "navbar-tab-active-background-color",
"css-var": "navbar-tab-active-background-color",
"value": "transparent" "value": "transparent"
}, },
{ {
"name": "navbar-tab-active-border-bottom-color", "name": "navbar-tab-active-border-bottom-color",
"css-var": "navbar-tab-active-border-bottom-color",
"value": "var(--bulma-link)" "value": "var(--bulma-link)"
}, },
{ {
"name": "navbar-tab-active-border-bottom-style", "name": "navbar-tab-active-border-bottom-style",
"css-var": "navbar-tab-active-border-bottom-style",
"value": "solid" "value": "solid"
}, },
{ {
"name": "navbar-tab-active-border-bottom-width", "name": "navbar-tab-active-border-bottom-width",
"css-var": "navbar-tab-active-border-bottom-width",
"value": "0.1875em" "value": "0.1875em"
}, },
{ {
"name": "navbar-dropdown-background-color", "name": "navbar-dropdown-background-color",
"css-var": "navbar-dropdown-background-color",
"value": "var(--bulma-scheme-main)" "value": "var(--bulma-scheme-main)"
}, },
{ {
"name": "navbar-dropdown-border-l", "name": "navbar-dropdown-border-l",
"css-var": "navbar-dropdown-border-l",
"value": "var(--bulma-border-l)" "value": "var(--bulma-border-l)"
}, },
{ {
"name": "navbar-dropdown-border-color", "name": "navbar-dropdown-border-color",
"css-var": "navbar-dropdown-border-color",
"value": "hsl(\n var(--bulma-navbar-h),\n var(--bulma-navbar-s),\n var(--bulma-navbar-dropdown-border-l)\n)" "value": "hsl(\n var(--bulma-navbar-h),\n var(--bulma-navbar-s),\n var(--bulma-navbar-dropdown-border-l)\n)"
}, },
{ {
"name": "navbar-dropdown-border-style", "name": "navbar-dropdown-border-style",
"css-var": "navbar-dropdown-border-style",
"value": "solid" "value": "solid"
}, },
{ {
"name": "navbar-dropdown-border-width", "name": "navbar-dropdown-border-width",
"css-var": "navbar-dropdown-border-width",
"value": "0.125em" "value": "0.125em"
}, },
{ {
"name": "navbar-dropdown-offset", "name": "navbar-dropdown-offset",
"css-var": "navbar-dropdown-offset",
"value": "-0.25em" "value": "-0.25em"
}, },
{ {
"name": "navbar-dropdown-arrow", "name": "navbar-dropdown-arrow",
"css-var": "navbar-dropdown-arrow",
"value": "var(--bulma-link)" "value": "var(--bulma-link)"
}, },
{ {
"name": "navbar-dropdown-radius", "name": "navbar-dropdown-radius",
"css-var": "navbar-dropdown-radius",
"value": "var(--bulma-radius-large)" "value": "var(--bulma-radius-large)"
}, },
{ {
"name": "navbar-dropdown-z", "name": "navbar-dropdown-z",
"css-var": "navbar-dropdown-z",
"value": "20" "value": "20"
}, },
{ {
"name": "navbar-dropdown-boxed-radius", "name": "navbar-dropdown-boxed-radius",
"css-var": "navbar-dropdown-boxed-radius",
"value": "var(--bulma-radius-large)" "value": "var(--bulma-radius-large)"
}, },
{ {
"name": "navbar-dropdown-boxed-shadow", "name": "navbar-dropdown-boxed-shadow",
"value": "0 0.5em 0.5em\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.1\n ),\n 0 0 0 1px\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.1\n )" "css-var": "navbar-dropdown-boxed-shadow",
"value": "0 0.5em 0.5em hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.1\n),\n0 0 0 1px hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.1\n)"
}, },
{ {
"name": "navbar-divider-background-l", "name": "navbar-divider-background-l",
"css-var": "navbar-divider-background-l",
"value": "var(--bulma-background-l)" "value": "var(--bulma-background-l)"
}, },
{ {
"name": "navbar-divider-height", "name": "navbar-divider-height",
"css-var": "navbar-divider-height",
"value": "0.125em" "value": "0.125em"
}, },
{ {
"name": "navbar-bottom-box-shadow-size", "name": "navbar-bottom-box-shadow-size",
"css-var": "navbar-bottom-box-shadow-size",
"value": "0 -0.125em 0 0" "value": "0 -0.125em 0 0"
},
{
"name": "navbar-breakpoint",
"value": "iv.$desktop"
},
{
"name": "navbar-colors",
"value": "dv.$colors"
} }
], ],
"css-vars": [ "css-vars": [
{ {
"name": "navbar-height", "name": "navbar-height",
"css-var": "navbar-height",
"value": "3.25rem" "value": "3.25rem"
} }
] ]

View file

@ -87,7 +87,7 @@
}, },
{ {
"name": "pagination-shadow-inset", "name": "pagination-shadow-inset",
"value": "inset 0 0.0625em 0.125em\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.2\n )", "value": "inset 0 0.0625em 0.125em hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.2\n)",
"css-var": "pagination-shadow-inset" "css-var": "pagination-shadow-inset"
} }
], ],
@ -226,7 +226,7 @@
}, },
{ {
"name": "pagination-shadow-inset", "name": "pagination-shadow-inset",
"value": "inset 0 0.0625em 0.125em\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.2\n )" "value": "inset 0 0.0625em 0.125em hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.2\n)"
}, },
{ {
"name": "pagination-selected-item-h", "name": "pagination-selected-item-h",

View file

@ -1,4 +1,9 @@
{ {
"sass-vars": [], "sass-vars": [],
"css-vars": [] "css-vars": [
{
"name": "block-spacing",
"value": "1.5rem"
}
]
} }

View file

@ -27,12 +27,12 @@
}, },
{ {
"name": "box-link-hover-shadow", "name": "box-link-hover-shadow",
"value": "0 0.5em 1em -0.125em hsla(var(--bulma-scheme-h), var(--bulma-scheme-s), #{cv.getVar(\n \"scheme-invert-l\"\n )}, 0.1),\n 0 0 0 1px var(--bulma-link)", "value": "0 0.5em 1em -0.125em hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.1\n),\n0 0 0 1px var(--bulma-link)",
"css-var": "box-link-hover-shadow" "css-var": "box-link-hover-shadow"
}, },
{ {
"name": "box-link-active-shadow", "name": "box-link-active-shadow",
"value": "inset 0 1px 2px\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.2\n ),\n 0 0 0 1px var(--bulma-link)", "value": "inset 0 1px 2px hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.2\n),\n0 0 0 1px var(--bulma-link)",
"css-var": "box-link-active-shadow" "css-var": "box-link-active-shadow"
} }
], ],
@ -59,11 +59,11 @@
}, },
{ {
"name": "box-link-hover-shadow", "name": "box-link-hover-shadow",
"value": "0 0.5em 1em -0.125em hsla(var(--bulma-scheme-h), var(--bulma-scheme-s), #{cv.getVar(\n \"scheme-invert-l\"\n )}, 0.1),\n 0 0 0 1px var(--bulma-link)" "value": "0 0.5em 1em -0.125em hsla(\nvar(--bulma-scheme-h),\nvar(--bulma-scheme-s), var(--bulma-scheme-invert-l), 0.1),\n0 0 0 1px var(--bulma-link)"
}, },
{ {
"name": "box-link-active-shadow", "name": "box-link-active-shadow",
"value": "inset 0 1px 2px\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.2\n ),\n 0 0 0 1px var(--bulma-link)" "value": "inset 0 1px 2px hsla( var(--bulma-scheme-h), var(--bulma-scheme-s), var(--bulma-scheme-invert-l), 0.2),\n0 0 0 1px var(--bulma-link)"
} }
] ]
} }

View file

@ -148,10 +148,6 @@
{ {
"name": "button-colors", "name": "button-colors",
"value": "dv.$colors" "value": "dv.$colors"
},
{
"name": "button-responsive-sizes",
"value": "(\n \"mobile\": (\n \"small\": calc(var(--bulma-size-small) * 0.75),\n \"normal\": calc(var(--bulma-size-small) * 0.875),\n \"medium\": var(--bulma-size-small),\n \"large\": var(--bulma-size-normal),\n ),\n \"tablet-only\": (\n \"small\": calc(var(--bulma-size-small) * 0.875),\n \"normal\": var(--bulma-size-small),\n \"medium\": var(--bulma-size-normal),\n \"large\": var(--bulma-size-medium),\n ),\n)"
} }
], ],
"css-vars": [ "css-vars": [

View file

@ -1,4 +1,21 @@
{ {
"sass-vars": [], "sass-vars": [],
"css-vars": [] "css-vars": [
{
"name": "delete-dimensions",
"value": "1.25rem"
},
{
"name": "delete-background-l",
"value": "0%"
},
{
"name": "delete-background-alpha",
"value": "0.5"
},
{
"name": "delete-color",
"value": "var(--bulma-white)"
}
]
} }

View file

@ -97,7 +97,7 @@
}, },
{ {
"name": "table-striped-row-even-hover-background-color", "name": "table-striped-row-even-hover-background-color",
"value": "cv.getVar(\n \"scheme-main-ter\"\n)", "value": "var(--bulma-scheme-main-ter)",
"css-var": "table-striped-row-even-hover-background-color" "css-var": "table-striped-row-even-hover-background-color"
}, },
{ {

View file

@ -36,10 +36,6 @@
"name": "file-name-max-width", "name": "file-name-max-width",
"value": "16em", "value": "16em",
"css-var": "file-name-max-width" "css-var": "file-name-max-width"
},
{
"name": "file-colors",
"value": "shared.$form-colors"
} }
], ],
"css-vars": [ "css-vars": [

View file

@ -0,0 +1,174 @@
{
"sass-vars": [
{
"name": "control-radius",
"value": "var(--bulma-radius)",
"css-var": "control-radius"
},
{
"name": "control-radius-small",
"value": "var(--bulma-radius-small)",
"css-var": "control-radius-small"
},
{
"name": "control-border-width",
"value": "1px",
"css-var": "control-border-width"
},
{
"name": "control-size",
"value": "var(--bulma-size-normal)",
"css-var": "control-size"
},
{
"name": "control-height",
"value": "2.5em",
"css-var": "control-height"
},
{
"name": "control-line-height",
"value": "1.5",
"css-var": "control-line-height"
},
{
"name": "control-padding-vertical",
"value": "calc(0.5em - 1px)",
"css-var": "control-padding-vertical"
},
{
"name": "control-padding-horizontal",
"value": "calc(0.75em - 1px)",
"css-var": "control-padding-horizontal"
},
{
"name": "control-focus-shadow-l",
"value": "50%",
"css-var": "control-focus-shadow-l"
},
{
"name": "label-color",
"css-var": "label-color",
"value": "var(--bulma-text-strong)"
},
{
"name": "label-weight",
"css-var": "label-weight",
"value": "var(--bulma-weight-semibold)"
},
{
"name": "help-size",
"css-var": "help-size",
"value": "var(--bulma-size-small)"
}
],
"css-vars": [
{
"name": "input-h",
"value": "var(--bulma-scheme-h)"
},
{
"name": "input-s",
"value": "var(--bulma-scheme-s)"
},
{
"name": "input-l",
"value": "var(--bulma-scheme-main-l)"
},
{
"name": "input-border-l",
"value": "var(--bulma-border-l)"
},
{
"name": "input-border-l-delta",
"value": "0%"
},
{
"name": "input-hover-border-l-delta",
"value": "var(--bulma-hover-border-l-delta)"
},
{
"name": "input-active-border-l-delta",
"value": "var(--bulma-active-border-l-delta)"
},
{
"name": "input-focus-h",
"value": "var(--bulma-focus-h)"
},
{
"name": "input-focus-s",
"value": "var(--bulma-focus-s)"
},
{
"name": "input-focus-l",
"value": "var(--bulma-focus-l)"
},
{
"name": "input-focus-shadow-size",
"value": "var(--bulma-focus-shadow-size)"
},
{
"name": "input-focus-shadow-alpha",
"value": "var(--bulma-focus-shadow-alpha)"
},
{
"name": "input-color-l",
"value": "var(--bulma-text-strong-l)"
},
{
"name": "input-background-l",
"value": "var(--bulma-scheme-main-l)"
},
{
"name": "input-background-l-delta",
"value": "0%"
},
{
"name": "input-height",
"value": "var(--bulma-control-height)"
},
{
"name": "input-shadow",
"value": "inset 0 0.0625em 0.125em\n hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.05\n )"
},
{
"name": "input-placeholder-color",
"value": "hsla(\n var(--bulma-text-h),\n var(--bulma-text-s),\n var(--bulma-text-strong-l),\n 0.3\n)"
},
{
"name": "input-disabled-color",
"value": "var(--bulma-text-weak)"
},
{
"name": "input-disabled-background-color",
"value": "var(--bulma-background)"
},
{
"name": "input-disabled-border-color",
"value": "var(--bulma-background)"
},
{
"name": "input-disabled-placeholder-color",
"value": "hsla(\n var(--bulma-text-h),\n var(--bulma-text-s),\n var(--bulma-text-weak-l),\n 0.3\n)"
},
{
"name": "input-arrow",
"value": "var(--bulma-link)"
},
{
"name": "input-icon-color",
"value": "var(--bulma-text-light)"
},
{
"name": "input-icon-hover-color",
"value": "var(--bulma-text-weak)"
},
{
"name": "input-icon-focus-color",
"value": "var(--bulma-link)"
},
{
"name": "input-radius",
"value": "var(--bulma-radius)"
}
]
}

View file

@ -0,0 +1,249 @@
{
"sass-vars": [
{
"name": "input-h",
"value": "var(--bulma-scheme-h)",
"css-var": "input-h"
},
{
"name": "input-s",
"value": "var(--bulma-scheme-s)",
"css-var": "input-s"
},
{
"name": "input-l",
"value": "var(--bulma-scheme-main-l)",
"css-var": "input-l"
},
{
"name": "input-border-l",
"value": "var(--bulma-border-l)",
"css-var": "input-border-l"
},
{
"name": "input-border-l-delta",
"value": "0%",
"css-var": "input-border-l-delta"
},
{
"name": "input-hover-border-l-delta",
"value": "var(--bulma-hover-border-l-delta)",
"css-var": "input-hover-border-l-delta"
},
{
"name": "input-active-border-l-delta",
"value": "var(--bulma-active-border-l-delta)",
"css-var": "input-active-border-l-delta"
},
{
"name": "input-color-l",
"value": "var(--bulma-text-strong-l)",
"css-var": "input-color-l"
},
{
"name": "input-background-l",
"value": "var(--bulma-scheme-main-l)",
"css-var": "input-background-l"
},
{
"name": "input-background-l-delta",
"value": "0%",
"css-var": "input-background-l-delta"
},
{
"name": "input-height",
"value": "var(--bulma-control-height)",
"css-var": "input-height"
},
{
"name": "input-shadow",
"value": "inset 0 0.0625em 0.125em hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.05\n)",
"css-var": "input-shadow"
},
{
"name": "input-placeholder-color",
"value": "hsla(\n var(--bulma-text-h),\n var(--bulma-text-s),\n var(--bulma-text-strong-l),\n 0.3\n)",
"css-var": "input-placeholder-color"
},
{
"name": "input-focus-h",
"value": "var(--bulma-focus-h)",
"css-var": "input-focus-h"
},
{
"name": "input-focus-s",
"value": "var(--bulma-focus-s)",
"css-var": "input-focus-s"
},
{
"name": "input-focus-l",
"value": "var(--bulma-focus-l)",
"css-var": "input-focus-l"
},
{
"name": "input-focus-shadow-size",
"value": "var(--bulma-focus-shadow-size)",
"css-var": "input-focus-shadow-size"
},
{
"name": "input-focus-shadow-alpha",
"value": "var(--bulma-focus-shadow-alpha)",
"css-var": "input-focus-shadow-alpha"
},
{
"name": "input-disabled-color",
"value": "var(--bulma-text-weak)",
"css-var": "input-disabled-color"
},
{
"name": "input-disabled-background-color",
"value": "var(--bulma-background)",
"css-var": "input-disabled-background-color"
},
{
"name": "input-disabled-border-color",
"value": "var(--bulma-background)",
"css-var": "input-disabled-border-color"
},
{
"name": "input-disabled-placeholder-color",
"value": "hsla(\n var(--bulma-text-h),\n var(--bulma-text-s),\n var(--bulma-text-weak-l),\n 0.3\n)",
"css-var": "input-disabled-placeholder-color"
},
{
"name": "input-arrow",
"value": "var(--bulma-link)",
"css-var": "input-arrow"
},
{
"name": "input-icon-color",
"value": "var(--bulma-text-light)",
"css-var": "input-icon-color"
},
{
"name": "input-icon-hover-color",
"value": "var(--bulma-text-weak)",
"css-var": "input-icon-hover-color"
},
{
"name": "input-icon-focus-color",
"value": "var(--bulma-link)",
"css-var": "input-icon-focus-color"
},
{
"name": "input-radius",
"value": "var(--bulma-radius)",
"css-var": "input-radius"
}
],
"css-vars": [
{
"name": "input-h",
"value": "var(--bulma-scheme-h)"
},
{
"name": "input-s",
"value": "var(--bulma-scheme-s)"
},
{
"name": "input-l",
"value": "var(--bulma-scheme-main-l)"
},
{
"name": "input-border-l",
"value": "var(--bulma-border-l)"
},
{
"name": "input-border-l-delta",
"value": "0%"
},
{
"name": "input-hover-border-l-delta",
"value": "var(--bulma-hover-border-l-delta)"
},
{
"name": "input-active-border-l-delta",
"value": "var(--bulma-active-border-l-delta)"
},
{
"name": "input-focus-h",
"value": "var(--bulma-focus-h)"
},
{
"name": "input-focus-s",
"value": "var(--bulma-focus-s)"
},
{
"name": "input-focus-l",
"value": "var(--bulma-focus-l)"
},
{
"name": "input-focus-shadow-size",
"value": "var(--bulma-focus-shadow-size)"
},
{
"name": "input-focus-shadow-alpha",
"value": "var(--bulma-focus-shadow-alpha)"
},
{
"name": "input-color-l",
"value": "var(--bulma-text-strong-l)"
},
{
"name": "input-background-l",
"value": "var(--bulma-scheme-main-l)"
},
{
"name": "input-background-l-delta",
"value": "0%"
},
{
"name": "input-height",
"value": "var(--bulma-control-height)"
},
{
"name": "input-shadow",
"value": "inset 0 0.0625em 0.125em hsla(\n var(--bulma-scheme-h),\n var(--bulma-scheme-s),\n var(--bulma-scheme-invert-l),\n 0.05\n)"
},
{
"name": "input-placeholder-color",
"value": "hsla(\n var(--bulma-text-h),\n var(--bulma-text-s),\n var(--bulma-text-strong-l),\n 0.3\n)"
},
{
"name": "input-disabled-color",
"value": "var(--bulma-text-weak)"
},
{
"name": "input-disabled-background-color",
"value": "var(--bulma-background)"
},
{
"name": "input-disabled-border-color",
"value": "var(--bulma-background)"
},
{
"name": "input-disabled-placeholder-color",
"value": "hsla(\n var(--bulma-text-h),\n var(--bulma-text-s),\n var(--bulma-text-weak-l),\n 0.3\n)"
},
{
"name": "input-arrow",
"value": "var(--bulma-link)"
},
{
"name": "input-icon-color",
"value": "var(--bulma-text-light)"
},
{
"name": "input-icon-hover-color",
"value": "var(--bulma-text-weak)"
},
{
"name": "input-icon-focus-color",
"value": "var(--bulma-link)"
},
{
"name": "input-radius",
"value": "var(--bulma-radius)"
}
]
}

View file

@ -0,0 +1,41 @@
{
"sass-vars": [
{
"name": "textarea-padding",
"css-var": "textarea-padding",
"value": "var(--bulma-control-padding-horizontal)"
},
{
"name": "textarea-max-height",
"css-var": "textarea-max-height",
"value": "40em"
},
{
"name": "textarea-min-height",
"css-var": "textarea-min-height",
"value": "8em"
}
],
"css-vars": [
{
"name": "input-h",
"value": "#{cv.getVar(\"scheme-h\")},"
},
{
"name": "input-s",
"value": "#{cv.getVar(\"scheme-s\")},"
},
{
"name": "input-border-style",
"value": "solid,"
},
{
"name": "input-border-width",
"value": "1px,"
},
{
"name": "input-border-l",
"value": "#{cv.getVar(\"border-l\")},"
}
]
}

View file

@ -2,11 +2,13 @@
"sass-vars": [ "sass-vars": [
{ {
"name": "container-offset", "name": "container-offset",
"value": "2 * iv.$gap" "css-var": "container-offset",
"value": "64px"
}, },
{ {
"name": "container-max-width", "name": "container-max-width",
"value": "iv.$fullhd" "css-var": "container-max-width",
"value": "1408px"
} }
], ],
"css-vars": [] "css-vars": []

View file

@ -26,8 +26,19 @@
"css-var": "hero-body-padding-large" "css-var": "hero-body-padding-large"
}, },
{ {
"name": "hero-colors", "name": "hero-gradient-h-offset",
"value": "dv.$colors" "value": "5deg",
"css-var": "hero-gradient-h-offset"
},
{
"name": "hero-gradient-s-offset",
"value": "10%",
"css-var": "hero-gradient-s-offset"
},
{
"name": "hero-gradient-l-offset",
"value": "5%",
"css-var": "hero-gradient-l-offset:"
} }
], ],
"css-vars": [ "css-vars": [

View file

@ -0,0 +1,2 @@
<span class="bd-color" style="background: currentColor"></span>
<code>currentColor</code>

View file

@ -0,0 +1,2 @@
<span class="bd-color" style="background: inherit"></span>
<code>inherit</code>

View file

@ -1,7 +1,7 @@
<div <div
{% if include.unsplash %} {% if include.unsplash %}
class="bd-logos-item" class="bd-logos-item"
style="background-image: url(https://source.unsplash.com/{{ include.unsplash }}/480x480)" style="background-image: url(/assets/images/unsplash/{{ include.unsplash }}.jpg)"
{% else %} {% else %}
class="bd-logos-item is-transparent" class="bd-logos-item is-transparent"
{% endif %} {% endif %}

View file

@ -2,8 +2,14 @@
{% assign subtab = include.subtab | default: page.doc-subtab %} {% assign subtab = include.subtab | default: page.doc-subtab %}
{% assign data = include.data | default: site.data.variables[tab][subtab] %} {% assign data = include.data | default: site.data.variables[tab][subtab] %}
{% assign sass_vars = include.data | default: data["sass-vars"] %} {% assign sass_vars = include.data | default: data["sass-vars"] %}
{% assign sass_vars_size = sass_vars | size %}
{% assign css_vars = include.data | default: data["css-vars"] %} {% assign css_vars = include.data | default: data["css-vars"] %}
{% assign css_vars_size = css_vars | size %}
{% if sass_vars_size > 0 or css_vars_size > 0 %}
{% include docs/elements/anchor.html name="Sass and CSS variables" %}
{% if sass_vars_size > 0 %}
<div class="bd-vars-table block table-container"> <div class="bd-vars-table block table-container">
<table> <table>
<thead> <thead>
@ -14,7 +20,7 @@
<span>Sass Variable</span> <span>Sass Variable</span>
</div> </div>
</th> </th>
{% unless include.hide_css_vars %} {% unless include.hide_css_vars or page.meta.hide_css_vars %}
<th> <th>
<div class="icon-text"> <div class="icon-text">
<span class="icon has-text-link"><i class="fab fa-css3"></i></span> <span class="icon has-text-link"><i class="fab fa-css3"></i></span>
@ -36,7 +42,7 @@
{% unless sass_var["value"] == "dv.$colors" %} {% unless sass_var["value"] == "dv.$colors" %}
<tr> <tr>
<td class="bd-theme-sass">{% highlight sass %}${{ sass_var["name"] }}{% endhighlight %}</td> <td class="bd-theme-sass">{% highlight sass %}${{ sass_var["name"] }}{% endhighlight %}</td>
{% unless include.hide_css_vars %} {% unless include.hide_css_vars or page.meta.hide_css_vars %}
<td class="bd-theme-code">{% highlight css %}var(--bulma-{{ sass_var["css-var"] }}){% endhighlight %}</td> <td class="bd-theme-code">{% highlight css %}var(--bulma-{{ sass_var["css-var"] }}){% endhighlight %}</td>
{% endunless %} {% endunless %}
<td class="bd-theme-docs">{% highlight css %}{{ sass_var["value"] }}{% endhighlight %}</td> <td class="bd-theme-docs">{% highlight css %}{{ sass_var["value"] }}{% endhighlight %}</td>
@ -46,3 +52,35 @@
</tbody> </tbody>
</table> </table>
</div> </div>
{% elsif css_vars_size > 0 %}
<div class="bd-vars-table block table-container">
<table>
<thead>
<tr>
<th>
<div class="icon-text">
<span class="icon has-text-link"><i class="fab fa-css3"></i></span>
<span>CSS Variable</span>
</div>
</th>
<th>
<div class="icon-text">
<span class="icon has-text-success"><i class="fas fa-code"></i></span>
<span>Value</span>
</div>
</th>
</tr>
</thead>
<tbody>
{% for css_var in css_vars %}
<tr>
<td class="bd-theme-sass">{% highlight sass %}var(--bulma-{{ css_var["name"] }}){% endhighlight %}</td>
<td class="bd-theme-docs">{% highlight css %}{{ css_var["value"] }}{% endhighlight %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
{% endif %}

View file

@ -108,4 +108,4 @@
</div> </div>
</div> </div>
<script src="{{ site.url }}/lib/klmn.js"></script> <script src="{{ site.url }}/assets/javascript/klmn.js"></script>

View file

@ -33,13 +33,13 @@
<ul class="bd-tw-actions"> <ul class="bd-tw-actions">
<li class="bd-tw-action is-reply"> <li class="bd-tw-action is-reply">
<a class="bd-tw-action-link" href="https://twitter.com/intent/tweet?in_reply_to={{ tweet.id }}"> <a class="bd-tw-action-link" href="https://x.com/intent/tweet?in_reply_to={{ tweet.id }}">
<div class="bd-tw-icon"></div> <div class="bd-tw-icon"></div>
</a> </a>
</li> </li>
<li class="bd-tw-action is-retweet"> <li class="bd-tw-action is-retweet">
<a class="bd-tw-action-link" href="https://twitter.com/intent/retweet?tweet_id={{ tweet.id }}"> <a class="bd-tw-action-link" href="https://x.com/intent/retweet?tweet_id={{ tweet.id }}">
<div class="bd-tw-icon"></div> <div class="bd-tw-icon"></div>
{% if tweet.retweets != 0 %} {% if tweet.retweets != 0 %}
<span class="bd-tw-action-stat"> <span class="bd-tw-action-stat">
@ -50,7 +50,7 @@
</li> </li>
<li class="bd-tw-action is-heart"> <li class="bd-tw-action is-heart">
<a class="bd-tw-action-link" href="https://twitter.com/intent/like?tweet_id={{ tweet.id }}&amp;ref_src=twsrc%5Etfw&amp;ref_url=http%3A%2F%2Fbulma.io%2F&amp;original_referer=http%3A%2F%2Fbulma.io%2F&amp;tw_i={{ tweet.id }}&amp;tw_p=tweetembed" target="_blank"> <a class="bd-tw-action-link" href="https://x.com/intent/like?tweet_id={{ tweet.id }}&amp;ref_src=twsrc%5Etfw&amp;ref_url=http%3A%2F%2Fbulma.io%2F&amp;original_referer=http%3A%2F%2Fbulma.io%2F&amp;tw_i={{ tweet.id }}&amp;tw_p=tweetembed" target="_blank">
<div class="bd-tw-icon"></div> <div class="bd-tw-icon"></div>
{% if tweet.hearts != 0 %} {% if tweet.hearts != 0 %}
<span class="bd-tw-action-stat"> <span class="bd-tw-action-stat">

View file

@ -13,7 +13,7 @@
{% if include.prints %} {% if include.prints %}
<div class="bd-hero-prints"> <div class="bd-hero-prints">
{% for print in include.prints %} {% for print in include.prints %}
<a class="bd-hero-print icon-text"> <a class="bd-hero-print icon-text" href="{{ print.url }}" target="_blank">
<span class="icon"> <span class="icon">
<i class="{{ print.icon }}"></i> <i class="{{ print.icon }}"></i>
</span> </span>

View file

@ -63,3 +63,5 @@
{% include docs/menu-list.html category_id="helpers" %} {% include docs/menu-list.html category_id="helpers" %}
</div> </div>
</div> </div>
{% include docs/side-sponsr.html %}

View file

@ -1,14 +1,14 @@
<div class="bd-side-sponsrs"> <div class="bd-side-sponsrs">
<p class="bd-side-sponsor-label">Sponsors</p> <p class="bd-side-sponsor-label">Sponsor</p>
<a class="bd-side-sponsor" href="https://password.link/" target="_blank"> <a class="bd-side-sponsor" href="https://www.route4me.com/" target="_blank">
{% {%
include docs/elements/responsive-image.html include docs/elements/responsive-image.html
path="amis/passwordlink" path="amis/route4me"
extension="png" extension="png"
alt="Password.link" alt="Route Planner and Route Optimizer"
width="332" width="224"
height="96" height="57"
%} %}
</a> </a>
</div> </div>

View 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>

View file

@ -1,5 +1,5 @@
{% assign link = site.data.links.by_id[include.link_id] %} {% assign link = site.data.links.by_id[include.link_id] %} {% assign cleanpath =
{% assign cleanpath = link.path | remove: '/' %} link.path | remove: '/' %}
<a <a
class=" class="
@ -17,12 +17,19 @@
{% endif %} {% endif %}
" "
title="{{ link.subtitle | strip_html }}" title="{{ link.subtitle | strip_html }}"
{% if link.href %} {%
if
link.href
%}
href="{{ link.href }}" href="{{ link.href }}"
target="_blank" target="_blank"
{% else %} {%
else
%}
href="{{ site.url }}{{ link.path }}" href="{{ site.url }}{{ link.path }}"
{% endif %} {%
endif
%}
> >
<span class="icon"> <span class="icon">
<i class="{{ link.icon }}"></i> <i class="{{ link.icon }}"></i>
@ -33,12 +40,7 @@
{% if link.long_name %} {% if link.long_name %}
<span class="is-hidden-fullhd">{{ link.name }}</span> <span class="is-hidden-fullhd">{{ link.name }}</span>
<span class="is-hidden is-block-fullhd">{{ link.long_name }}</span> <span class="is-hidden is-block-fullhd">{{ link.long_name }}</span>
{% else %} {% else %} {{ link.name }} {% endif %}
{{ link.name }}
{% endif %}
{% if include.link_id == "shop" %}
<span class="tag is-success ml-1">New!</span>
{% endif %}
</span> </span>
{% endunless %} {% endunless %}
</a> </a>

View file

@ -23,6 +23,14 @@
</div> </div>
</div> </div>
<div class="bd-footer-donation column">
<p class="bd-footer-donation-title"><strong>Browser testing</strong> via</p>
<div class="bd-footer-donation-action">
<a class="bd-hidden-dark" href="https://www.lambdatest.com/" target="_blank"><img src="https://www.lambdatest.com/support/img/logo.svg" style="vertical-align: middle;margin-left:5px" width="147" height="26" /></a>
<a class="bd-hidden-light" href="https://www.lambdatest.com/" target="_blank"><img src="https://www.lambdatest.com/resources/images/logo-white.svg" style="vertical-align: middle;margin-left:5px" width="147" height="26" /></a>
</div>
</div>
{% if site.data.sponsors.footer.size > 0 %} {% if site.data.sponsors.footer.size > 0 %}
<div class="bd-footer-donation column"> <div class="bd-footer-donation column">
<p class="bd-footer-donation-title">Visit our <strong>Sponsors</strong></p> <p class="bd-footer-donation-title">Visit our <strong>Sponsors</strong></p>

View file

@ -2,8 +2,8 @@
<div class="content has-text-centered"> <div class="content has-text-centered">
<p> <p>
<strong>Bulma</strong> by <a href="https://jgthms.com">Jeremy Thomas</a>. The source code is licensed <strong>Bulma</strong> by <a href="https://jgthms.com">Jeremy Thomas</a>. The source code is licensed
<a href="http://opensource.org/licenses/mit-license.php">MIT</a>. The website content is licensed <a href="https://opensource.org/license/mit">MIT</a>. The website content is licensed
<a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY NC SA 4.0</a>. <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY NC SA 4.0</a>.
</p> </p>
</div> </div>
</footer> </footer>

View file

@ -0,0 +1,13 @@
<a href="https://cssmasterclass.io/" target="_blank" class="launch-code is-animated">
<h3><img
src="{{site.url}}/assets/images/masterclass/logo-desktop.png"
height="40"
width="300"
/>
</h3>
<small>
Learn CSS with 🎓 online interactive courses,📺 educational videos, and
🧑🏻💻project-building tutorials.
</small>
</a>

View file

@ -1,5 +1,8 @@
<div id="carboncontainer" class="bd-carbon"> <div id="carboncontainer" class="bd-carbon">
<div id="carbon"> <div id="carbon">
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CWYIE237&placement=bulmaio&format=cover" id="_carbonads_js"></script> <a id="masterclass-carbon" href="https://cssmasterclass.io/" target="_blank" style="display: none; aspect-ratio: 40 / 26; max-width: 400px; max-height: 260px;">
<img src="{{ site.url }}/assets/images/masterclass/masterclass-carbon.png" height="260" width="400" alt="CSS Masterclass">
</a>
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CWYIE237&placement=bulmaio&format=cover" id="_carbonads_js" onerror="this.previousElementSibling.style.display = 'flex'"></script>
</div> </div>
</div> </div>

View file

@ -0,0 +1,43 @@
<div id="masterclass" class="masterclass">
<div id="masterclass-background" class="masterclass-background"></div>
<a class="masterclass-body" href="https://cssmasterclass.io/" target="_blank">
<div class="masterclass-content is-hidden-desktop">
<img
src="{{site.url}}/assets/images/masterclass/logo-mobile.png"
height="68"
width="240"
/>
<img
src="{{site.url}}/assets/images/masterclass/text-mobile.png"
height="99"
width="228"
/>
<div class="shine">
<span>Get started for Free</span>
</div>
</div>
<div class="masterclass-content is-hidden-touch">
<img
src="{{site.url}}/assets/images/masterclass/logo-desktop.png"
height="50"
width="378"
/>
<img
src="{{site.url}}/assets/images/masterclass/text-desktop.png"
height="58"
width="571"
/>
<div class="shine">
<span>Get started for Free</span>
</div>
</div>
</a>
<button
id="masterclass-close"
class="modal-close is-large"
aria-label="close"
></button>
</div>

View file

@ -4,6 +4,8 @@
{% include global/head.html %} {% include global/head.html %}
</head> </head>
<body> <body>
{% include website/banner.html %}
{{ content }} {{ content }}
{% if page.modals %} {% if page.modals %}
@ -29,5 +31,7 @@
}); });
</script> </script>
<script src="{{ site.url }}/assets/javascript/main.js"></script> <script src="{{ site.url }}/assets/javascript/main.js"></script>
{% include global/customizer.html %}
{% include website/masterclass.html %}
</body> </body>
</html> </html>

View file

@ -40,7 +40,6 @@ route: documentation
{% endif %} {% endif %}
{% if page.meta.variables %} {% if page.meta.variables %}
{% include docs/elements/anchor.html name="Sass and CSS variables" %}
{% include docs/components/variables.html %} {% include docs/components/variables.html %}
{% endif %} {% endif %}
</div> </div>

View 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
View 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?

View 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

View 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>

File diff suppressed because it is too large Load diff

View 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"
}
}

View 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"]
*/
}

View 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;

View 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;
}

View 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;

View 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;
}

View 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&apos;s go!
</button>
</div>
</>
)}
</div>
{css && <pre className={cn.pre}>{css.trim()}</pre>}
</div>
);
}
export default Export;

View file

@ -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;
}

View 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;

View 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;

View 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;

View file

@ -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%)
);
}

View file

@ -0,0 +1,3 @@
function VarInput() {}
export default VarInput;

View 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;

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View 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;
}
}

View 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>,
);

View 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;

View 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;

View 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;

View 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;

View 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;

View 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;

View file

@ -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;

View 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;

View file

@ -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;

View 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;

View file

@ -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;

View 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;

View 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;

View file

@ -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;

View 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;

View 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;

View 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;

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