Version 3.5.0 #16

Merged
athena merged 12 commits from v3.5.0 into main 5 months ago
  1. 12
      Changelog.md
  2. 3
      Gruntfile.js
  3. 34
      README.md
  4. 240
      dist/jui-bundled.js
  5. 4
      dist/jupiterui.css
  6. 4
      dist/jupiterui.js
  7. 147
      examples/animated.html
  8. 4
      extensions/README.md
  9. 25
      extensions/Vivus/README.md
  10. 15
      extensions/Vivus/package.json
  11. 13
      extensions/Vivus/src/animation/_root.scss
  12. 8
      extensions/Vivus/src/animation/types/_types.scss
  13. 32
      extensions/Vivus/src/animation/types/fade/_fade_in.scss
  14. 32
      extensions/Vivus/src/animation/types/fade/_fade_out.scss
  15. 36
      extensions/Vivus/src/animation/types/scale/_scale_in.scss
  16. 36
      extensions/Vivus/src/animation/types/scale/_scale_out.scss
  17. 2
      extensions/Vivus/src/vivus.scss
  18. 7
      extensions/Vivus/vivus.css
  19. 21
      index.html
  20. 2
      package.json
  21. 2
      project/mightDo.md
  22. 2
      src/assets/header.css
  23. 4
      src/css/components/_components.scss
  24. 32
      src/css/components/_dropdown.scss
  25. 0
      src/css/components/_skeleton.scss
  26. 146
      src/css/components/shell/_nav.scss
  27. 391
      src/css/components/shell/_sidebar.scss
  28. 8
      src/css/interactive/animation/_animation.scss
  29. 18
      src/css/interactive/animation/_motion.scss
  30. 94
      src/css/interactive/animation/entrances/_scale_in.scss
  31. 53
      src/css/interactive/animation/exits/_scale_out.scss
  32. 3
      src/css/styles/colors/_gradients.scss
  33. 6
      src/js/components/accordion.js
  34. 28
      src/js/components/dropdown.js
  35. 7
      src/js/components/dynamic_elements.js
  36. 6
      src/js/components/icons.js
  37. 7
      src/js/components/loader.js
  38. 7
      src/js/components/media.js
  39. 6
      src/js/components/modal.js
  40. 10
      src/js/components/notifications.js
  41. 35
      src/js/components/sidebar.js
  42. 7
      src/js/components/tabs.js
  43. 7
      src/js/core/app.js
  44. 7
      src/js/core/config.js
  45. 6
      src/js/core/data.js
  46. 5
      src/js/etc/anchors.js
  47. 6
      src/js/etc/animation.js
  48. 7
      src/js/etc/color_buttons.js
  49. 5
      src/js/etc/copy.js
  50. 6
      src/js/etc/dynamic_accents.js
  51. 5
      src/js/etc/theme.js
  52. 6
      src/js/etc/utility_functions.js
  53. 5
      src/js/extensions/extensions_config.js
  54. 5
      src/js/extensions/index.js
  55. 13
      src/js/main.js

12
Changelog.md

@ -1,3 +1,15 @@
Version 3.5.0:
- added:
- Vivus extension for animations (default Jupiter animations will be slowly phased out)
- JavaScript files now have explainer comments at the top. (SCSS files are explanatory enough, so those remain unchanged)
- modified:
- Dropdown styling. There is now a `0.25rem` padding on the top and bottom of the menu, with some additional modifications to the link text. This padding is accounted for on `.icon-only` configurations.
- removed:
- `shell/` components.
- Hover dropdown is no longer supported. Use `.dynamic-view` if you need to make one.
Version 3.4.0:
- added:

3
Gruntfile.js

@ -1,6 +1,3 @@
var pjson = require('./package.json');
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),

34
README.md

@ -15,24 +15,15 @@ JupiterUI Docs | [JupiterUI-Docs](https://codeberg.org/JupiterUI/JupiterUI-Docs)
JupiterUI is a front-end UI kit for modern websites. It provides a comprehensive compilation of many useuful CSS rules. Ultimately, it's a design system.
## What does Jupiter do for me?
- High-class, working components right out of the box.
- Support for dynamic theme colors and dark mode right out of the box.
- Styles work the same for React sites as they do for Wordpress websites (allowing you to share styles between projects)
- Exceptional CSS layout coverage. From simple Flex layouts to more complicated Grid layouts, Jupiter has a lot of support.
- many more.
### What do I use?
If you're building a modern website with a **React-based JavaScript framework** (namely Create React App, NextJS, Gatsby, Frontity, etc.), you'll want to use the React Components. If you're building a static website without a framework (namely raw HTML, PHP, Wordpress, etc.), you should use the Source.
## Features
- No dependencies!
- Flexible and easily extendable.
- High-quality websites (or web apps!) right out-of-the-box.
- High-quality components that work out-of-the-box.
- _Zero_ dependencies!
- **Advanced colors** and _themeing_ system (Dark & Light mode)
- Support for _any_ platform. For React projects, you can use [JupiterUI-Components](https://codeberg.org/JupiterUI/JupiterUI-Components)
- Detailed layout system—with lots of support for Flex and Grid layouts.
- Easily extendable, with support for both CSS and JavaScript extensions.
- Vivus extension, a library for smooth, highly customizeable (via classnames) animations. Built by us.
- and much more!
## Get started
@ -56,7 +47,10 @@ Getting to the point, if you have any questions or concerns, please email me at:
## Sites made with JupiterUI
- [Attom](https://attom.space/)
- [FiveAtoms](https://fiveatoms.com/)
- [Kiri](https://kiri.vercel.app)
- [Infinium Earth](https://www.infinium.earth)
- [Attom](https://attom.space/) (entirely)
- [FiveAtoms](https://fiveatoms.com/) (entirely)
- [Kiri](https://kiri.vercel.app) (partly)
- [Infinium Earth](https://www.infinium.earth) (entirely)
- [CypherBook](https://cypherbook.eu) (partly)
Submit a PR to add your site, if applicable.

240
dist/jui-bundled.js

@ -1,4 +1,10 @@
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
/*
* @purpose:
* Attaches event handlers to accordion components.
*
*/
const attach_accordion_triggers = () => {
document.querySelectorAll('.j-acc-trigger').forEach((e) => {
e.addEventListener('click', () => {
@ -14,6 +20,13 @@ module.exports = {
};
},{}],2:[function(require,module,exports){
/*
* @purpose:
* Attaches event handlers to dropdown components,
* handles mouse events on dropdown menus,
* handles click on #root to close menus.
*/
const config = require('../core/config');
const close_all = () => {
@ -50,31 +63,12 @@ const attach_click_event = (e, parent) => {
});
};
const attach_hover_event = (parent) => {
parent.addEventListener('mouseover', () => {
parent.setAttribute('aria-expanded', 'true');
});
parent.addEventListener('mouseout', () => {
parent.setAttribute('aria-expanded', 'false');
});
};
const set_dropdown = () => {
document
.querySelectorAll('.j-dropdown-trigger:not(:only-child)')
.forEach((e) => {
const parent = e.parentNode;
if (parent.getAttribute('j-dropdown') === 'hover') {
if (window.innerWidth > 991) {
attach_hover_event(parent);
} else {
attach_click_event(e, parent);
}
} else {
attach_click_event(e, parent);
}
attach_click_event(e, parent);
});
};
@ -99,8 +93,12 @@ module.exports = {
set_dropdown_inner,
};
},{"../core/config":12}],3:[function(require,module,exports){
// Why the long way? https://stackoverflow.com/a/51140673
},{"../core/config":11}],3:[function(require,module,exports){
/*
* @purpose:
* Automatically inserts modal and notification
* containers into the document, if they aren't found.
*/
const { icons } = require('../core/data');
const config = require('../core/config');
@ -109,6 +107,7 @@ const check_for_dynamic_elements = () => {
const root = document.getElementById('root') || document.querySelector('body');
if (document.getElementsByClassName('j-modal').length === 0) {
// Why the long way? https://stackoverflow.com/a/51140673
let modal = document.createElement('div');
modal.classList.add('j-modal');
modal.setAttribute('aria-expanded', 'false');
@ -208,7 +207,13 @@ module.exports = {
check_for_dynamic_elements,
};
},{"../core/config":12,"../core/data":13}],4:[function(require,module,exports){
},{"../core/config":11,"../core/data":12}],4:[function(require,module,exports){
/*
* @purpose:
* Populates icon SVG content into elements with
* the `data-icon` attribute.
*/
const data = require('../core/data');
const add_icons = () => {
@ -221,7 +226,14 @@ module.exports = {
add_icons,
};
},{"../core/data":13}],5:[function(require,module,exports){
},{"../core/data":12}],5:[function(require,module,exports){
/*
* @purpose:
* Handles the initial loading screen
* via an HTTP request to the document,
* to determine if the page is loaded.
*/
const config = require('../core/config');
const hide_loader = () => {
@ -274,7 +286,14 @@ module.exports = {
start_loader,
};
},{"../core/config":12}],6:[function(require,module,exports){
},{"../core/config":11}],6:[function(require,module,exports){
/*
* @purpose:
* Handles background images and
* relative URLs in the provided
* attribute value therein.
*/
const handle_relative_urls = (url) => {
let parsed_url = url;
@ -314,6 +333,12 @@ module.exports = {
};
},{}],7:[function(require,module,exports){
/*
* @purpose:
* Handles the complex usage of the
* modal component.
*/
const data = require('../core/data');
let active_modal;
@ -460,7 +485,17 @@ module.exports = {
open_modal,
};
},{"../core/data":13}],8:[function(require,module,exports){
},{"../core/data":12}],8:[function(require,module,exports){
/*
* @purpose:
* Handles the notification component.
*
* @note:
* The notifications _are not_ handled
* internally. That is, there is no internal
* object to track the current items.
*/
const utility = require('../etc/utility_functions');
const data = require('../core/data');
const config = require('../core/config');
@ -570,44 +605,14 @@ module.exports = {
push_notification,
};
},{"../core/config":12,"../core/data":13,"../etc/utility_functions":20}],9:[function(require,module,exports){
const close_sidebar = () => {
document.querySelector('.j-sidebar').classList.remove('active');
};
},{"../core/config":11,"../core/data":12,"../etc/utility_functions":19}],9:[function(require,module,exports){
/*
* @purpose:
* Handles the tab component.
*
*/
const set_sidebar = (aside) => {
if (aside.classList.contains('active')) {
aside.classList.remove('active');
document.querySelector('#root').removeEventListener('click', close_sidebar);
} else {
aside.classList.add('active');
document.querySelector('#root').addEventListener('click', close_sidebar);
}
};
const toggle_sidebar = () => {
const aside = document.querySelector('.j-sidebar');
aside.addEventListener('click', (e) => {
e.stopPropagation();
});
set_sidebar(aside);
};
const attach_sidebar_event = () => {
try {
document.querySelector('.j-sidebar-button').addEventListener('click', () => {
toggle_sidebar();
});
} catch {}
};
module.exports = {
attach_sidebar_event,
};
},{}],10:[function(require,module,exports){
const init = () => {
document.querySelectorAll('.j-tab-container').forEach((container) => {
let active_tab = container.getAttribute('data-active-tab');
@ -642,7 +647,14 @@ module.exports = {
init,
};
},{}],11:[function(require,module,exports){
},{}],10:[function(require,module,exports){
/*
* @purpose:
* Handles the app configuration
* detailed in the config.js file.
*/
const config = require('../core/config');
const set_app_config = (v) => {
@ -668,7 +680,14 @@ module.exports = {
init_app,
};
},{"../core/config":12}],12:[function(require,module,exports){
},{"../core/config":11}],11:[function(require,module,exports){
/*
* @purpose:
* Handles the configuration (or setting)
* values for Jupiter. Likewise handles
* custom_config objects.
*/
const util = require('../etc/utility_functions');
let jupiter_config = {
@ -751,7 +770,13 @@ const give_config = () => jupiter_config;
module.exports = give_config();
},{"../etc/utility_functions":20}],13:[function(require,module,exports){
},{"../etc/utility_functions":19}],12:[function(require,module,exports){
/*
* @purpose:
* Handles default icons and modals,
* and handles custom objects for both.
*/
const util = require('../etc/utility_functions');
let icons = {
@ -826,7 +851,12 @@ module.exports = {
icons,
};
},{"../etc/utility_functions":20}],14:[function(require,module,exports){
},{"../etc/utility_functions":19}],13:[function(require,module,exports){
/*
* @purpose:
* Handles `data-anchor` values.
*/
const config = require('../core/config');
const is_intersecting = (a) => {
@ -880,7 +910,13 @@ module.exports = {
init,
};
},{"../core/config":12}],15:[function(require,module,exports){
},{"../core/config":11}],14:[function(require,module,exports){
/*
* @purpose:
* Handles animations via the
* IntersectionObserverAPI.
*/
const config = require('../core/config');
const traverse_elements = (entries) => {
@ -925,7 +961,14 @@ module.exports = {
animate_list,
};
},{"../core/config":12}],16:[function(require,module,exports){
},{"../core/config":11}],15:[function(require,module,exports){
/*
* @purpose:
* Handles the relatively unofficial
* color_buttons component, to change the
* accent color in a more explicit manner.
*/
const dynamic_accents = require('./dynamic_accents');
const setup_color_buttons = () => {
@ -953,7 +996,12 @@ module.exports = {
setup_color_buttons,
};
},{"./dynamic_accents":18}],17:[function(require,module,exports){
},{"./dynamic_accents":17}],16:[function(require,module,exports){
/*
* @purpose:
* Handles `data-copy` attributes on `<a>` tags.
*/
const notifications = require('../components/notifications');
const setup_copy_events = () => {
@ -976,7 +1024,13 @@ module.exports = {
setup_copy_events,
};
},{"../components/notifications":8}],18:[function(require,module,exports){
},{"../components/notifications":8}],17:[function(require,module,exports){
/*
* @purpose:
* Handles dynamic accents by modifying CSS
* variables based on an HTML attribute.
*/
const config = require('../core/config');
const colors = ["red", "magenta", "purple", "indigo", "blue", "cyan", "teal", "green"];
@ -1065,7 +1119,12 @@ module.exports = {
set_dynamic_color,
};
},{"../core/config":12}],19:[function(require,module,exports){
},{"../core/config":11}],18:[function(require,module,exports){
/*
* @purpose:
* Handles the theme feature.
*/
const config = require('../core/config');
const data = require('../core/data');
@ -1168,7 +1227,13 @@ module.exports = {
init_themes,
};
},{"../core/config":12,"../core/data":13}],20:[function(require,module,exports){
},{"../core/config":11,"../core/data":12}],19:[function(require,module,exports){
/*
* @purpose:
* Provides unbiased functions for general
* purpose.
*/
const config = require('../core/config');
const make_id = (length = 10) => {
@ -1218,12 +1283,22 @@ module.exports = {
set_leave_callback
};
},{"../core/config":12}],21:[function(require,module,exports){
},{"../core/config":11}],20:[function(require,module,exports){
/*
* @purpose:
* A place for you to put extension settings
*/
module.exports = {
// Your extension settings can go here
};
},{}],22:[function(require,module,exports){
},{}],21:[function(require,module,exports){
/*
* @purpose:
* Allows an area where extensions can access Jupiter core.
*/
const x_config = require('./extensions_config.js');
const util = require('../etc/utility_functions');
// require() your files here
@ -1238,7 +1313,13 @@ module.exports = {
init_extentions,
};
},{"../etc/utility_functions":20,"./extensions_config.js":21}],23:[function(require,module,exports){
},{"../etc/utility_functions":19,"./extensions_config.js":20}],22:[function(require,module,exports){
/*
* @purpose:
* Entry point for Jupiter. Handles the
* invokation of all files.
*/
// Core
const config = require('./core/config');
const app = require('./core/app');
@ -1254,7 +1335,6 @@ const loader = require('./components/loader');
const media = require('./components/media');
const modal = require('./components/modal');
const notifications = require('./components/notifications');
const sidebar = require('./components/sidebar');
const tabs = require('./components/tabs');
// Etc
@ -1320,11 +1400,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (config.enable_accordions) {
accordion.attach_accordion_triggers();
}
if (document.getElementsByClassName("j-sidebar").length !== 0) {
sidebar.attach_sidebar_event();
}
if (config.enable_extensions) {
extensions.init_extentions();
}
@ -1344,4 +1420,4 @@ document.addEventListener('DOMContentLoaded', () => {
}
});
},{"./components/accordion":1,"./components/dropdown":2,"./components/dynamic_elements":3,"./components/icons":4,"./components/loader":5,"./components/media":6,"./components/modal":7,"./components/notifications":8,"./components/sidebar":9,"./components/tabs":10,"./core/app":11,"./core/config":12,"./etc/anchors":14,"./etc/animation":15,"./etc/color_buttons":16,"./etc/copy":17,"./etc/dynamic_accents":18,"./etc/theme":19,"./extensions/index":22}]},{},[23]);
},{"./components/accordion":1,"./components/dropdown":2,"./components/dynamic_elements":3,"./components/icons":4,"./components/loader":5,"./components/media":6,"./components/modal":7,"./components/notifications":8,"./components/tabs":9,"./core/app":10,"./core/config":11,"./etc/anchors":13,"./etc/animation":14,"./etc/color_buttons":15,"./etc/copy":16,"./etc/dynamic_accents":17,"./etc/theme":18,"./extensions/index":21}]},{},[22]);

4
dist/jupiterui.css

File diff suppressed because one or more lines are too long

4
dist/jupiterui.js

File diff suppressed because one or more lines are too long

147
examples/animated.html

@ -0,0 +1,147 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>JupiterUI - Features</title>
<link rel="stylesheet" href="../dist/jupiterui.css" />
<link rel="stylesheet" href="../extensions/Vivus/vivus.css" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
</head>
<body>
<div class="j-loading">
<div class="j-loader xl mb-16"></div>
</div>
<div id="root">
<section class="section">
<div class="container flex-c">
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-1900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-2900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-3900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-4900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-5900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-6900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-7900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-8900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9000" data-animate="v-fade-in-center"></div>
</div>
<div class="flex flex-row align-c">
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9100" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9200" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9300" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9400" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9500" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9600" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9700" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9800" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-9900" data-animate="v-fade-in-center"></div>
<div class="h-5r w-5r g-accent-50-70 shadow-md delay-10000" data-animate="v-fade-in-center"></div>
</div>
</div>
</section>
</div>
<script src="../dist/jupiterui.js"></script>
</body>
</html>

4
extensions/README.md

@ -8,11 +8,13 @@ Occasionally, extensions will be listed that are not "official," in that Jupiter
## Layout of Extensions
Extensions are folders that consist of:
Extensions are folders that (primarily) consist of:
- a `README.md` file explaining the purpose and use of the extension; and
- either a `.css` file or a `.js` file.
On occasion, like the Vivus extension (introduced in 3.5.0), there will also be source files. These can be ignored, and the README will clarify which files to use.
## Using an extension
### JavaScript extensions

25
extensions/Vivus/README.md

@ -0,0 +1,25 @@
# Vivus
A comprehensive animation extension for JupiterUI.
## Usage
Simply `<link>` the `vivus.css` file in your project.
### Animation name structure
Structure: v-[animationType]-[toDirection]-[expressionSize]
`expressionSize` is not always used. The `fade-[]` animations, for instance, have no expression value. Instead, they use the global CSS variable `--v-translate-distance`.
Examples:
> v-scale-in-left-lg
> v-fade-out-down
## Animations
- `scale-in`
- `scale-out`
- `fade-in`
- `fade-out`

15
extensions/Vivus/package.json

@ -0,0 +1,15 @@
{
"name": "@jupiterui/vivus",
"version": "1.0.0",
"description": "A comprehensive animation extension for JupiterUI",
"main": "_",
"scripts": {
"w": "sass --watch src/vivus.scss:vivus.css --no-source-map --style=compressed"
},
"repository": {
"type": "git",
"url": "https://codeberg.org/JupiterUI/Vivus"
},
"author": "athena",
"license": "MIT"
}

13
extensions/Vivus/src/animation/_root.scss

@ -0,0 +1,13 @@
/*!
* Vivus.css
* Version: 1.0.0
* https://codeberg.org/JupiterUI/Vivus
* License: MIT
* Author: athena
*/
:root {
--v-translate-distance: 10rem;
--v-translate-distance-neg: -10rem;
}

8
extensions/Vivus/src/animation/types/_types.scss

@ -0,0 +1,8 @@
// Scale
@use 'scale/scale_in';
@use 'scale/scale_out';
// Fade
@use 'fade/fade_in';
@use 'fade/fade_out';

32
extensions/Vivus/src/animation/types/fade/_fade_in.scss

@ -0,0 +1,32 @@
$name: 'fade-in';
$directions:
('center' 'center' 0 0)
('up' 'center' 0 var(--v-translate-distance))
('down' 'center' 0 var(--v-translate-distance-neg))
('right' 'right' var(--v-translate-distance) 0)
('left' 'left' var(--v-translate-distance-neg) 0);
@each $direction in $directions {
$animation: 'v-#{$name}#{'-'}#{nth($direction, 1)}';
@keyframes #{$animation} {
0% {
transform: translate(#{nth($direction, 3)}, #{nth($direction, 4)});
opacity: 0;
}
100% {
transform: translate(0);
opacity: 1;
}
}
div[data-animate="#{$animation}"], .#{$animation}#{'-pre'} {
opacity: 0;
transform: translate(#{nth($direction, 3)}, #{nth($direction, 4)});
}
.#{$animation} {
animation: #{$animation} 600ms cubic-bezier(0, 0, 0.38, 0.9) both;
transform-origin: #{nth($direction, 2)};
will-change: transform;
}
}

32
extensions/Vivus/src/animation/types/fade/_fade_out.scss

@ -0,0 +1,32 @@
$name: 'fade-out';
$directions:
('center' 'center' 0 0)
('up' 'center' 0 var(--v-translate-distance-neg))
('down' 'center' 0 var(--v-translate-distance))
('right' 'right' var(--v-translate-distance) 0)
('left' 'left' var(--v-translate-distance-neg) 0);
@each $direction in $directions {
$animation: 'v-#{$name}#{'-'}#{nth($direction, 1)}';
@keyframes #{$animation} {
0% {
transform: translate(0);
opacity: 1;
}
100% {
transform: translate(#{nth($direction, 3)}, #{nth($direction, 4)});
opacity: 0;
}
}
div[data-animate="#{$animation}"], .#{$animation}#{'-pre'} {
opacity: 1;
transform: translate(0);
}
.#{$animation} {
animation: #{$animation} 600ms cubic-bezier(0, 0, 0.38, 0.9) both;
transform-origin: #{nth($direction, 2)};
will-change: transform;
}
}

36
extensions/Vivus/src/animation/types/scale/_scale_in.scss

@ -0,0 +1,36 @@
$name: 'scale-in';
$directions:
('center' 'center' 0 0)
('up' 'center' 0 var(--v-translate-distance))
('down' 'center' 0 var(--v-translate-distance-neg))
('right' 'right' var(--v-translate-distance) 0)
('left' 'left' var(--v-translate-distance-neg) 0);
$expressions: ('sm' 0.98) ('md' 0.95) ('lg' 0.93);
@each $direction in $directions {
@each $tuple in $expressions {
$animation: 'v-#{$name}#{'-'}#{nth($direction, 1)}#{'-'}#{nth($tuple, 1)}';
@keyframes #{$animation} {
0% {
transform: scale(#{nth($tuple, 2)}) translate(#{nth($direction, 3)}, #{nth($direction, 4)});
opacity: 0;
}
100% {
transform: scale(1) translate(0);
opacity: 1;
}
}
div[data-animate="#{$animation}"], .#{$animation}#{'-pre'} {
opacity: 0;
transform: scale(#{nth($tuple, 2)}) translate(#{nth($direction, 3)}, #{nth($direction, 4)});
}
.#{$animation} {
animation: #{$animation} 600ms cubic-bezier(0, 0, 0.38, 0.9) both;
transform-origin: #{nth($direction, 2)};
will-change: transform;
}
}
}

36
extensions/Vivus/src/animation/types/scale/_scale_out.scss

@ -0,0 +1,36 @@
$name: 'scale-out';
$directions:
('center' 'center' 0 0)
('up' 'center' 0 var(--v-translate-distance))
('down' 'center' 0 var(--v-translate-distance-neg))
('right' 'right' var(--v-translate-distance) 0)
('left' 'left' var(--v-translate-distance-neg) 0);
$expressions: ('sm' 0.98) ('md' 0.95) ('lg' 0.93);
@each $direction in $directions {
@each $tuple in $expressions {
$animation: 'v-#{$name}#{'-'}#{nth($direction, 1)}#{'-'}#{nth($tuple, 1)}';
@keyframes #{$animation} {
0% {
transform: scale(1) translate(0);
opacity: 1;
}
100% {
transform: scale(#{nth($tuple, 2)}) translate(#{nth($direction, 3)}, #{nth($direction, 4)});
opacity: 0;
}
}
div[data-animate="#{$animation}"], .#{$animation}#{'-pre'} {
transform: scale(1) translate(0);
opacity: 1;
}
.#{$animation} {
animation: #{$animation} 600ms cubic-bezier(0, 0, 0.38, 0.9) both;
transform-origin: #{nth($direction, 2)};
will-change: transform;
}
}
}

2
extensions/Vivus/src/vivus.scss

@ -0,0 +1,2 @@
@use 'animation/root';
@use 'animation/types/types';

7
extensions/Vivus/vivus.css

File diff suppressed because one or more lines are too long

21
index.html

@ -30,7 +30,7 @@
<a href="/" class="shallow-link text-dynamic py-1r ph-1r flex-c">
<div class="flex flex-row align-s">
<span class="fs-lg fw-600">Jupiter<span class="text-accent">UI</span></span>
<p class="fs-2xs text-dynamic-06 ml-0-25r mb-0 portrait-hide"> (v3.4.0)</p>
<p class="fs-2xs text-dynamic-06 ml-0-25r mb-0 portrait-hide">(v3.5.0)</p>
</div>
</a>
</div>
@ -330,7 +330,7 @@
</div>
<div class="grid-block">
<div class="flex flex-row flex-wrap justify-c align-c">
<div class="j-dropdown items-bordered mr-1r portrait-mb-2r portrait-mr-0" aria-expanded="false">
<div class="j-dropdown mr-1r portrait-mb-2r portrait-mr-0" aria-expanded="false">
<a class="j-button j-dropdown-trigger sm">Normal <i data-icon="down_chevron"></i></a>
<ul class="j-dropdown-menu shadow-md">
<li>
@ -347,23 +347,6 @@
</li>
</ul>
</div>
<div class="j-dropdown items-bordered portrait-mb-1r mr-1r" j-dropdown="hover" aria-expanded="false">
<a class="j-button j-dropdown-trigger sm">Hover <i data-icon="down_chevron"></i></a>
<ul class="j-dropdown-menu shadow-md">
<li>
<a class="j-dropdown-link">Link</a>
</li>
<li>
<a class="j-dropdown-link">Link</a>
</li>
<li>
<a class="j-dropdown-link">Link</a>
</li>
<li>
<a class="j-dropdown-link">Link</a>
</li>
</ul>
</div>
<div class="j-dropdown items-bordered relative-right" aria-expanded="false">
<a class="j-button gray app icon-only j-dropdown-trigger"><i class="j-icon" data-icon="dots_horizontal"></i></a>
<ul class="j-dropdown-menu shadow-md">

2
package.json

@ -1,6 +1,6 @@
{
"name": "jupiterui",
"version": "3.4.0",
"version": "3.5.0",
"description": "A component-first UI Kit that's flexible and extendable.",
"main": "",
"scripts": {

2
project/mightDo.md

@ -3,4 +3,4 @@
> Stuff that might be added in the future
- Layered panels component. In this case, it would appear akin to a slider with the inactive panels being slightly above and behind the current active panel.
- Considering separating Jupiter into different "kits." For example, there'd be a Layout kit, a Gradient kit, and so on. Such that picking and choosing based on needs is easier.
- ~~Considering separating Jupiter into different "kits." For example, there'd be a Layout kit, a Gradient kit, and so on. Such that picking and choosing based on needs is easier.~~ Dropped in favor of Extensions.

2
src/assets/header.css

@ -1,6 +1,6 @@
/*
* JupiterUI.css
* Version: 3.4.0
* Version: 3.5.0
* https://codeberg.org/JupiterUI/JupiterUI
* License: MIT
* Author: athena

4
src/css/components/_components.scss

@ -15,7 +15,5 @@
@use 'list';
@use 'media';
@use 'modal';
@use 'shell/nav';
@use 'notifications';
@use 'shell/sidebar';
@use 'shell/skeleton';
@use 'skeleton';

32
src/css/components/_dropdown.scss

@ -24,13 +24,14 @@
}
}
.j-dropdown-menu {
min-width: 100%;
min-width: 8rem;
list-style: none;
padding-inline-start: 0;
padding: 0.25rem 0;
position: absolute;
top: calc(100% + 0.5rem);
background-color: var(--ui);
border-radius: 0.5rem;
border-radius: 0.25rem;
z-index: 9999;
overflow: hidden;
margin: 0;
@ -47,11 +48,12 @@
}
&.icons-only {
padding: 0;
min-width: 0 !important;
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
border-radius: 0.25rem;
transition: var(--duration-fast-02) var(--productive-entrance);
}
&.icons-only.vertical {
@ -137,16 +139,15 @@
.j-dropdown-menu li a, .j-dropdown-menu li button {
background-color: transparent;
width: 100%;
height: 2.5rem;
padding: 0 1rem;
padding: 0.5rem 1rem;
display: flex;
justify-content: space-between;
align-items: center;
text-decoration: none;
font-size: 1rem;
font-weight: 500;
color: var(--text-color-1);
transition: var(--duration-fast-02) var(--expressive-standard);
color: var(--text-color);
transition: var(--duration-fast-01) var(--expressive-standard);
}
.j-dropdown-menu li a:hover, .j-dropdown-menu li button:hover {
background-color: var(--ui-1);
@ -172,23 +173,6 @@ body.dark .j-dropdown.items-bordered li:not(:last-child) a, body.dark .j-dropdow
border-bottom-color: var(--ui) !important;
}
// j-dropdown='hover'
.j-dropdown.relative-right[j-dropdown="hover"] > .j-button.icon-only + .j-dropdown-menu {
border-top-left-radius: 0.5rem;
border-top-right-radius: 0;
}
.j-dropdown[j-dropdown="hover"][aria-expanded="true"] .j-dropdown-trigger {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.j-dropdown[j-dropdown="hover"] .j-dropdown-menu {
border-top-right-radius: 0;
border-top-left-radius: 0;
top: 100%;
}
.j-dropdown[j-dropdown="hover"] > .j-button.icon-only + .j-dropdown-menu {
border-top-right-radius: 0.5rem;
}
.j-dropdown-trigger {
transition: var(--duration-moderate-01) var(--productive-entrance);

0
src/css/components/shell/_skeleton.scss → src/css/components/_skeleton.scss

146
src/css/components/shell/_nav.scss

@ -1,146 +0,0 @@
@use '../../variables';
.j-nav {
width: 100%;
border-bottom: 1px solid var(--ui-2);
height: 2.75rem;
padding: 0 0.5rem;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
background: var(--ui);
top: 0;
z-index: 99999;
& + .j-sidebar {
top: 2.75rem !important;
height: calc(100vh - 2.75rem);
}
&.round {
padding: 0.25rem 0.5rem;
& .j-nav-link {
border-radius: 0.5rem;
}
}
&.force-dark {
background-color: variables.$force-dark-bg !important;
border-bottom-color: variables.$force-dark-border;
& .j-nav-link {
color: variables.$force-dark-color !important;
&:hover {
background-color: variables.$force-dark-bg-hover;
color: variables.$force-dark-color-hover;
}
& i > svg, & a {
color: variables.$force-dark-color;
}
&.has-border::after {
background: variables.$force-dark-border-2;
}
}
}
& .j-nav-link {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-color);
padding: 0 0.75rem;
position: relative;
z-index: 999;
transition: var(--duration-fast-01) var(--productive-exit);
&:hover {
background-color: var(--ui-1);
}
&,
& p,
& i {
font-size: 1rem;
font-weight: 500;
color: var(--text-color-06);
}
& i {
margin-right: 0.75rem;
}
&.has-border:hover::after {
opacity: 0;
}
&.has-border::after {
content: '';
position: absolute;
right: 0;
height: 1.25rem;
width: 1px;
background: var(--ui-2);
transition: var(--duration-fast-01) var(--productive-exit);
}
&.icon-only {
height: 100%;
width: 2.75rem;
padding: 0;
}
}
& .fellow {
transform: translateX(-1px);
}
&.force-dark .j-dropdown {
color: variables.$force-dark-color !important;
&.items-bordered .j-dropdown-link {
border-color: variables.$force-dark-border !important;
}
& .j-dropdown-menu {
background-color: variables.$force-dark-bg-hover !important;
& .j-dropdown-link {
border-right-color: variables.$force-dark-border;
&:hover {
background-color: variables.$force-dark-border-2;
}
}
}
}
@media only screen and (max-width: 991px) {
& .tablet-fellow {
transform: translateX(-1px);
}
}
@media only screen and (max-width: 767px) {
& .landscaoe-fellow {
transform: translateX(-1px);
}
}
@media only screen and (max-width: 478px) {
& .portrait-fellow {
transform: translateX(-1px);
}
}
}
.j-app {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: flex-start;
overflow-y: scroll;
}

391
src/css/components/shell/_sidebar.scss

@ -1,391 +0,0 @@
@use '../../variables';
.j-sidebar {
width: 100%;
max-width: 14.5rem;
height: 100vh;
border-right: 1px solid var(--ui-2);
position: fixed;
top: 0;
bottom: 0;
left: 0;
overflow-y: scroll;
overflow: visible;
background-color: var(--ui);
z-index: 9999;
transition: var(--duration-moderate-02) ease;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
&.sm {
max-width: 5rem;
}
&.md {
max-width: 12.5rem;
}
&.lg {
max-width: 17rem;
}
&.sm + #root {
margin-left: 5rem;
}
&.md + #root {
margin-left: 12.5rem;
}
&.lg + #root {
margin-left: 17rem;
}
& > div.overscroll {
overflow-x: hidden;
overflow-y: scroll;
max-height: 100%;
}
&.right {
left: auto;
right: 0;
border-left: 1px solid var(--ui-2);
border-right: none;
}
&.right + #root {
margin-right: 14.5rem;
margin-left: 0;
}
&.right.sm + #root {
margin-right: 5rem;
margin-left: 0;
}
&.right.md + #root {
margin-right: 12.5rem;
margin-left: 0;
}
&.right.lg + #root {
margin-right: 17rem;
margin-left: 0;
}
& + #root {
margin-left: 14.5rem;
}
&.sm + #root {
margin-left: 5rem;
}
&.md + #root {
margin-left: 12.5rem;
}
&.lg + #root {
margin-left: 17rem;
}
&.items-sm .j-sidebar-link,
&.items-sm .j-acc-trigger {
padding: 0.5rem 0.75rem;
}
&.items-md .j-sidebar-link,
&.items-sm .j-acc-trigger {
padding: 1rem;
}
&.items-lg .j-sidebar-link,
&.items-sm .j-acc-trigger {
padding: 0.75rem 0.5rem 0.75rem 1.25rem;
}
& > div:nth-child(1) {
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
}
& > div:nth-child(2) {
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
}
& > div:nth-child(3) {
display: flex;
justify-content: flex-end;
align-content: center;
flex-direction: column;
}
&.force-dark {
background-color: variables.$force-dark-bg !important;
border-right-color: variables.$force-dark-border;
}
&.force-dark p,
&.force-dark i,
&.force-dark a {
color: variables.$force-dark-color;
}
& .j-acc-trigger {
// border-top: 1px solid var(--ui-2);
padding-top: 0;
padding-bottom: 0;
margin: 0 !important;
&,
& p {
line-height: 1;
}
}
&.force-dark .j-acc-trigger {
color: variables.$force-dark-color !important;
}
&.force-dark .j-sidebar-link,
&.force-dark .j-acc-trigger {
display: flex;
justify-content: flex-start;
align-items: center;
border-bottom-color: variables.$force-dark-border;
&,
& p {
color: variables.$force-dark-color;
}
&:hover {
background-color: variables.$force-dark-bg-hover;
color: variables.$force-dark-color-hover;
}
& i > svg {
color: variables.$force-dark-color;
}
}
&.force-dark .j-accordion[aria-expanded='true'] .j-acc-trigger {
border-bottom-color: variables.$force-dark-border !important;
<