Compare commits

..

No commits in common. "main" and "shop" have entirely different histories.
main ... shop

229 changed files with 35959 additions and 48320 deletions

View file

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

3
.gitignore vendored
View file

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

View file

@ -1,56 +1,5 @@
# 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
### Bug fixes

View file

@ -52,7 +52,7 @@ Feel free to raise an issue or submit a pull request.
## 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/main/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/master/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).
@ -131,14 +131,12 @@ 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 |
| [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 |
| [Manifest](https://manifest.build) | Manifest is a lightweight Backend-as-a-Service with essential features: DB, Admin panel, API, JS SDK |
| [CASE](https://case.app) | CASE is 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 |
<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)
Code copyright 2023 Jeremy Thomas. Code released under [the MIT license](https://github.com/jgthms/bulma/blob/main/LICENSE).
Code copyright 2023 Jeremy Thomas. Code released under [the MIT license](https://github.com/jgthms/bulma/blob/master/LICENSE).
[npm-link]: https://www.npmjs.com/package/bulma
[awesome-link]: https://github.com/awesome-css-group/awesome-css

View file

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

2
bulma.scss vendored
View file

@ -1,4 +1,4 @@
@charset "utf-8";
/*! bulma.io v1.0.3 | MIT License | github.com/jgthms/bulma */
/*! bulma.io v1.0.1 | MIT License | github.com/jgthms/bulma */
@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/"
}
},
"navbar": ["docs", "expo", "love", "sponsor"],
"navbar": ["docs", "expo", "love", "sponsor", "shop"],
"navbar_icons": ["github", "twitter"],
"navbar_more": ["made-with-bulma", "backers", "brand", "extensions"],
"category_ids": [

View file

@ -1984,9 +1984,9 @@
"id": "1161404522331344896",
"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>",
"fullname": "gebsystems",
"username": "gebsystems",
"avatar": "https://pbs.twimg.com/profile_images/1713156593137639424/Wwz0i_rj_400x400.jpg",
"fullname": "db4you",
"username": "db4you2",
"avatar": "https://pbs.twimg.com/profile_images/1283183292683038727/wVhp9AQr_normal.jpg",
"hearts": 22,
"retweets": 4
},

View file

@ -2,11 +2,11 @@
"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.",
"documentation": "/documentation",
"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.2",
"download": "https://github.com/jgthms/bulma/releases/download/1.0.0/bulma-1.0.0.zip",
"release_notes": "https://github.com/jgthms/bulma/releases/tag/1.0.0",
"github": "https://github.com/jgthms/bulma",
"twitter": "https://twitter.com/jgthms",
"version": "1.0.2",
"version": "1.0.0",
"book_url": "https://bleedingedgepress.com/creating-interfaces-bulma/",
"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",

View file

@ -37,7 +37,7 @@
},
{
"name": "card-header-shadow",
"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)",
"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 )",
"css-var": "card-header-shadow"
},
{
@ -138,4 +138,4 @@
"value": "var(--bulma-block-spacing)"
}
]
}
}

View file

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

View file

@ -2,17 +2,14 @@
"sass-vars": [
{
"name": "navbar-background-color",
"css-var": "navbar-background-color",
"value": "var(--bulma-scheme-main)"
},
{
"name": "navbar-box-shadow-size",
"css-var": "navbar-box-shadow-size",
"value": "0 0.125em 0 0"
},
{
"name": "navbar-box-shadow-color",
"css-var": "navbar-box-shadow-color",
"value": "var(--bulma-background)"
},
{
@ -22,145 +19,125 @@
},
{
"name": "navbar-padding-vertical",
"css-var": "navbar-padding-vertical",
"value": "1rem"
},
{
"name": "navbar-padding-horizontal",
"css-var": "navbar-padding-horizontal",
"value": "2rem"
},
{
"name": "navbar-z",
"css-var": "navbar-z",
"value": "30"
},
{
"name": "navbar-fixed-z",
"css-var": "navbar-fixed-z",
"value": "30"
},
{
"name": "navbar-item-img-max-height",
"css-var": "navbar-item-img-max-height",
"value": "1.75rem"
},
{
"name": "navbar-burger-color",
"css-var": "navbar-burger-color",
"value": "var(--bulma-navbar-item-color)"
},
{
"name": "navbar-tab-hover-background-color",
"css-var": "navbar-tab-hover-background-color",
"value": "transparent"
},
{
"name": "navbar-tab-hover-border-bottom-color",
"css-var": "navbar-tab-hover-border-bottom-color",
"value": "var(--bulma-link)"
},
{
"name": "navbar-tab-active-color",
"css-var": "navbar-tab-active-color",
"value": "var(--bulma-link)"
},
{
"name": "navbar-tab-active-background-color",
"css-var": "navbar-tab-active-background-color",
"value": "transparent"
},
{
"name": "navbar-tab-active-border-bottom-color",
"css-var": "navbar-tab-active-border-bottom-color",
"value": "var(--bulma-link)"
},
{
"name": "navbar-tab-active-border-bottom-style",
"css-var": "navbar-tab-active-border-bottom-style",
"value": "solid"
},
{
"name": "navbar-tab-active-border-bottom-width",
"css-var": "navbar-tab-active-border-bottom-width",
"value": "0.1875em"
},
{
"name": "navbar-dropdown-background-color",
"css-var": "navbar-dropdown-background-color",
"value": "var(--bulma-scheme-main)"
},
{
"name": "navbar-dropdown-border-l",
"css-var": "navbar-dropdown-border-l",
"value": "var(--bulma-border-l)"
},
{
"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)"
},
{
"name": "navbar-dropdown-border-style",
"css-var": "navbar-dropdown-border-style",
"value": "solid"
},
{
"name": "navbar-dropdown-border-width",
"css-var": "navbar-dropdown-border-width",
"value": "0.125em"
},
{
"name": "navbar-dropdown-offset",
"css-var": "navbar-dropdown-offset",
"value": "-0.25em"
},
{
"name": "navbar-dropdown-arrow",
"css-var": "navbar-dropdown-arrow",
"value": "var(--bulma-link)"
},
{
"name": "navbar-dropdown-radius",
"css-var": "navbar-dropdown-radius",
"value": "var(--bulma-radius-large)"
},
{
"name": "navbar-dropdown-z",
"css-var": "navbar-dropdown-z",
"value": "20"
},
{
"name": "navbar-dropdown-boxed-radius",
"css-var": "navbar-dropdown-boxed-radius",
"value": "var(--bulma-radius-large)"
},
{
"name": "navbar-dropdown-boxed-shadow",
"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)"
"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 )"
},
{
"name": "navbar-divider-background-l",
"css-var": "navbar-divider-background-l",
"value": "var(--bulma-background-l)"
},
{
"name": "navbar-divider-height",
"css-var": "navbar-divider-height",
"value": "0.125em"
},
{
"name": "navbar-bottom-box-shadow-size",
"css-var": "navbar-bottom-box-shadow-size",
"value": "0 -0.125em 0 0"
},
{
"name": "navbar-breakpoint",
"value": "iv.$desktop"
},
{
"name": "navbar-colors",
"value": "dv.$colors"
}
],
"css-vars": [
{
"name": "navbar-height",
"css-var": "navbar-height",
"value": "3.25rem"
}
]
}
}

View file

@ -87,7 +87,7 @@
},
{
"name": "pagination-shadow-inset",
"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)",
"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 )",
"css-var": "pagination-shadow-inset"
}
],
@ -226,7 +226,7 @@
},
{
"name": "pagination-shadow-inset",
"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)"
"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 )"
},
{
"name": "pagination-selected-item-h",
@ -253,4 +253,4 @@
"value": "#{$pagination-selected-item-color-l},"
}
]
}
}

View file

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

View file

@ -27,12 +27,12 @@
},
{
"name": "box-link-hover-shadow",
"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)",
"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)",
"css-var": "box-link-hover-shadow"
},
{
"name": "box-link-active-shadow",
"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)",
"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)",
"css-var": "box-link-active-shadow"
}
],
@ -59,11 +59,11 @@
},
{
"name": "box-link-hover-shadow",
"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)"
"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)"
},
{
"name": "box-link-active-shadow",
"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)"
"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)"
}
]
}
}

View file

@ -148,6 +148,10 @@
{
"name": "button-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": [
@ -268,4 +272,4 @@
"value": "var(--bulma-border)"
}
]
}
}

View file

@ -1,21 +1,4 @@
{
"sass-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)"
}
]
}
"css-vars": []
}

View file

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

View file

@ -36,6 +36,10 @@
"name": "file-name-max-width",
"value": "16em",
"css-var": "file-name-max-width"
},
{
"name": "file-colors",
"value": "shared.$form-colors"
}
],
"css-vars": [
@ -120,4 +124,4 @@
"value": "#{$file-active-color-l-delta},"
}
]
}
}

View file

@ -1,174 +0,0 @@
{
"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

@ -1,249 +0,0 @@
{
"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

@ -1,41 +0,0 @@
{
"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,14 +2,12 @@
"sass-vars": [
{
"name": "container-offset",
"css-var": "container-offset",
"value": "64px"
"value": "2 * iv.$gap"
},
{
"name": "container-max-width",
"css-var": "container-max-width",
"value": "1408px"
"value": "iv.$fullhd"
}
],
"css-vars": []
}
}

View file

@ -26,19 +26,8 @@
"css-var": "hero-body-padding-large"
},
{
"name": "hero-gradient-h-offset",
"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:"
"name": "hero-colors",
"value": "dv.$colors"
}
],
"css-vars": [
@ -63,4 +52,4 @@
"value": "18rem 6rem"
}
]
}
}

View file

@ -6,4 +6,4 @@
}
],
"css-vars": []
}
}

View file

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

View file

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

View file

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

View file

@ -2,14 +2,8 @@
{% assign subtab = include.subtab | default: page.doc-subtab %}
{% assign data = include.data | default: site.data.variables[tab][subtab] %}
{% 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_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">
<table>
<thead>
@ -20,7 +14,7 @@
<span>Sass Variable</span>
</div>
</th>
{% unless include.hide_css_vars or page.meta.hide_css_vars %}
{% unless include.hide_css_vars %}
<th>
<div class="icon-text">
<span class="icon has-text-link"><i class="fab fa-css3"></i></span>
@ -42,7 +36,7 @@
{% unless sass_var["value"] == "dv.$colors" %}
<tr>
<td class="bd-theme-sass">{% highlight sass %}${{ sass_var["name"] }}{% endhighlight %}</td>
{% unless include.hide_css_vars or page.meta.hide_css_vars %}
{% unless include.hide_css_vars %}
<td class="bd-theme-code">{% highlight css %}var(--bulma-{{ sass_var["css-var"] }}){% endhighlight %}</td>
{% endunless %}
<td class="bd-theme-docs">{% highlight css %}{{ sass_var["value"] }}{% endhighlight %}</td>
@ -52,35 +46,3 @@
</tbody>
</table>
</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>
<script src="{{ site.url }}/assets/javascript/klmn.js"></script>
<script src="{{ site.url }}/lib/klmn.js"></script>

View file

@ -33,13 +33,13 @@
<ul class="bd-tw-actions">
<li class="bd-tw-action is-reply">
<a class="bd-tw-action-link" href="https://x.com/intent/tweet?in_reply_to={{ tweet.id }}">
<a class="bd-tw-action-link" href="https://twitter.com/intent/tweet?in_reply_to={{ tweet.id }}">
<div class="bd-tw-icon"></div>
</a>
</li>
<li class="bd-tw-action is-retweet">
<a class="bd-tw-action-link" href="https://x.com/intent/retweet?tweet_id={{ tweet.id }}">
<a class="bd-tw-action-link" href="https://twitter.com/intent/retweet?tweet_id={{ tweet.id }}">
<div class="bd-tw-icon"></div>
{% if tweet.retweets != 0 %}
<span class="bd-tw-action-stat">
@ -50,7 +50,7 @@
</li>
<li class="bd-tw-action is-heart">
<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">
<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">
<div class="bd-tw-icon"></div>
{% if tweet.hearts != 0 %}
<span class="bd-tw-action-stat">

View file

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

View file

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

View file

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

View file

@ -1,39 +0,0 @@
<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 cleanpath =
link.path | remove: '/' %}
{% assign link = site.data.links.by_id[include.link_id] %}
{% assign cleanpath = link.path | remove: '/' %}
<a
class="
@ -17,30 +17,28 @@ link.path | remove: '/' %}
{% endif %}
"
title="{{ link.subtitle | strip_html }}"
{%
if
link.href
%}
href="{{ link.href }}"
target="_blank"
{%
else
%}
href="{{ site.url }}{{ link.path }}"
{%
endif
%}
{% if link.href %}
href="{{ link.href }}"
target="_blank"
{% else %}
href="{{ site.url }}{{ link.path }}"
{% endif %}
>
<span class="icon">
<i class="{{ link.icon }}"></i>
</span>
{% unless link.icon_only %}
<span class="bd-nav-item-name">
{% if link.long_name %}
<span class="is-hidden-fullhd">{{ link.name }}</span>
<span class="is-hidden is-block-fullhd">{{ link.long_name }}</span>
{% else %} {{ link.name }} {% endif %}
</span>
<span class="bd-nav-item-name">
{% if link.long_name %}
<span class="is-hidden-fullhd">{{ link.name }}</span>
<span class="is-hidden is-block-fullhd">{{ link.long_name }}</span>
{% else %}
{{ link.name }}
{% endif %}
{% if include.link_id == "shop" %}
<span class="tag is-success ml-1">New!</span>
{% endif %}
</span>
{% endunless %}
</a>

View file

@ -23,14 +23,6 @@
</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 %}
<div class="bd-footer-donation column">
<p class="bd-footer-donation-title">Visit our <strong>Sponsors</strong></p>

View file

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

View file

@ -1,13 +0,0 @@
<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,8 +1,5 @@
<div id="carboncontainer" class="bd-carbon">
<div id="carbon">
<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>
<script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CWYIE237&placement=bulmaio&format=cover" id="_carbonads_js"></script>
</div>
</div>

View file

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

View file

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

View file

@ -1,21 +0,0 @@
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 },
],
},
}

View file

@ -1,24 +0,0 @@
# 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

@ -1,8 +0,0 @@
# 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

@ -1,46 +0,0 @@
<!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

@ -1,28 +0,0 @@
{
"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

@ -1,26 +0,0 @@
: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

@ -1,592 +0,0 @@
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

@ -1,55 +0,0 @@
.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

@ -1,264 +0,0 @@
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

@ -1,80 +0,0 @@
.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

@ -1,120 +0,0 @@
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

@ -1,36 +0,0 @@
.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

@ -1,15 +0,0 @@
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

@ -1,80 +0,0 @@
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

@ -1,167 +0,0 @@
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

@ -1,68 +0,0 @@
.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

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

View file

@ -1,102 +0,0 @@
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

@ -1,67 +0,0 @@
.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

@ -1,68 +0,0 @@
: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

@ -1,9 +0,0 @@
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

@ -1,17 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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

@ -1,18 +0,0 @@
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;

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