Hier finden sich alle Komponenten für das System inkl. benötigtem Code.
Nach dem Import von bootstrap-setup.scss bzw. vor dem Import der Komponenten, muss der erste Import
components/site/site.scss sein. Hier sind globale Sass-Variablen definiert.
Die Reihenfolge sollte also in etwa wie folgt aussehen.
[…]
bootstrap-setup.scss
components/site/site.scss
components/**/*.scss
[…]
components/site/site.scss kann natürlich auch aus den Komponenten entfernt und von anderer Stelle
importiert werden. Dass hier eine Komponente verwendet wurde, dient nur der Dokumentation.
Da neue Farben für das Farbsystem definiert wurde und das momentan eher schlecht als recht geht, ist kein weiterer Import des Bootstrap-Hauptmoduls nötig, da in unserem Setup alle Untermodule bereits importiert werden. Siehe Dokumentation.
~bootstrap ist ein in vite.config.js definierter Alias und muss dementsprechend
ersetzt oder definiert werden.
@use 'sass:color';
@use "sass:map";
@import "~bootstrap/scss/functions";
////// Colors
//////
$gray-100: #f6f6f6;
$gray-300: #ececec;
$gray-400: #cfcfcf;
$gray-500: #aaa;
$gray-600: #888;
$green: #11BF22;
$orange: #f29200;
$red: #c80707;
$primary: #0b2e53;
$secondary: #888;
$warning: $orange;
$accent: #f29200;
$gray: $gray-600;
$material: #cbb491;
$not-material: #888;
$open-material: #c80707;
$border-color: $gray-400;
$focus-ring-color: rgba($accent, .2);
$component-active-bg: $accent;
////// Base
//////
$body-color: $primary;
////// Typographie
//////
$font-family-sans-serif: Roboto, sans-serif;
$font-size-base: .875rem;
$font-size-xs: $font-size-base * .78571429;
$font-size-sm: $font-size-base * 0.85714286;
$font-size-lg: $font-size-base * 1.14285714;
$font-size-xl: $font-size-base * 1.42857143;
$font-size-xxl: $font-size-base * 1.71428571;
$line-height-base: 1.3;
$link-color: $primary;
$link-hover-color: $secondary;
//// Headings
$h1-font-size: $font-size-base * 2;
$h2-font-size: $font-size-base * 1.5;
$h3-font-size: $font-size-base * 1.25;
$headings-font-weight: 700;
////// Forms
//////
////// Buttons
$input-btn-padding-y: .5rem;
$input-btn-padding-x: 1rem;
$btn-border-radius: 0;
$btn-border-radius-sm: 0;
$btn-border-radius-lg: 0;
$btn-font-weight: 500;
$btn-padding-y: .5rem;
$btn-padding-x: 1rem;
$input-btn-padding-y-sm: .25rem;
$input-btn-padding-x-sm: .5rem;
$input-btn-padding-y-lg: 1rem;
$input-btn-padding-x-lg: 1.25rem;
$input-font-size-lg: $font-size-lg;
///// Labels
$form-label-color: $secondary;
$form-label-font-size: $font-size-xs;
///// Inputs
$input-bg: $gray-100;
$input-border-color: $gray-100;
$input-border-radius: 0;
$input-border-radius-sm: 0;
$input-border-radius-lg: 0;
$input-padding-y: $input-btn-padding-y;
$input-padding-x: $input-btn-padding-x;
$input-padding-y-sm: $input-btn-padding-y-sm;
$input-padding-x-sm: $input-btn-padding-x-sm;
$input-placeholder-color: $gray-400;
$input-disabled-bg: darken($gray-300, 5%);
$input-disabled-border-color: darken($gray-300, 5%);
$input-disabled-color: rgba($primary, 0.6);
///// Selects
$form-select-bg: $gray-100;
$form-select-border-color: $gray-100;
$form-select-border-radius: 0;
$form-select-padding-y: $input-padding-y;
$form-select-padding-x: $input-padding-x;
$form-select-bg-position: right ($form-select-padding-x * 0.5) center;
$form-select-indicator-padding: $form-select-padding-x * 2;
$form-select-disabled-color: rgba($primary, 0.7);
$form-select-padding-y-sm: $input-padding-y-sm;
$form-select-padding-x-sm: $input-padding-x-sm;
///// Checkboxes + radios
$form-check-input-border-radius: 0;
$form-check-input-checked-bg-color: $primary;
///// Breadcrumbs
/////
$breadcrumb-active-color: $gray-600;
$breadcrumb-divider: quote('|');
$breadcrumb-divider-color: $gray-600;
///// Navs
/////
$nav-link-padding-y: 0.5rem;
$nav-underline-gap: 2.5rem;
$nav-underline-border-width: 1px;
$nav-underline-link-active-color: $orange;
///// Tables
/////
$table-cell-padding-y: .5rem;
$table-cell-padding-x: 1rem;
$table-cell-padding-y-sm: .375rem;
$table-cell-padding-x-sm: .75rem;
$table-color: $primary;
$table-hover-color: #fff;
$table-hover-bg: $accent;
$table-striped-bg: $gray-100;
$table-striped-order: even;
///// Progress bars
/////
$progress-height: 01.25rem;
$progress-border-radius: 0;
///// Modals
/////
$modal-content-border-radius: 0;
$modal-sm: 400px;
$modal-md: 700px;
///// Accordions
/////
$accordion-icon-color: $accent;
$accordion-icon-active-color: $accent;
////// Custom maps + utilities
//////
///// Bootstrap variables + maps
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/variables-dark";
///// Custom maps
// Custom colors
$theme-colors: map.merge($theme-colors, (
"accent": $accent,
"gray": $gray,
"medium-light-gray": $gray-300,
"light-gray": $gray-100,
"material": $material,
"not-material": $not-material,
"open-material": $open-material,
));
///// Bootstrap maps, mixins + utilities
@import "~bootstrap/scss/maps";
@import "~bootstrap/scss/mixins";
@import "~bootstrap/scss/utilities";
///// Add accent color to more maps …
// Light mode
$custom-colors-text: (
"accent": $accent,
"material": $material,
"not-material": $not-material,
"open-material": $open-material,
);
$custom-colors-bg-subtle: (
"accent": $accent,
"material": $material,
"not-material": $not-material,
"open-material": $open-material,
);
$custom-colors-border-subtle: (
"accent": $accent,
"material": $material,
"not-material": $not-material,
"open-material": $open-material,
);
$theme-colors-text: map.merge($theme-colors-text, $custom-colors-text);
$theme-colors-bg-subtle: map.merge($theme-colors-bg-subtle, $custom-colors-bg-subtle);
$theme-colors-border-subtle: map.merge($theme-colors-border-subtle, $custom-colors-border-subtle);
// Dark mode
$custom-colors-text-dark: (
"accent": $accent,
"material": $material,
"not-material": $not-material,
"open-material": $open-material,
);
$custom-colors-bg-subtle-dark: (
"accent": $accent,
"material": $material,
"not-material": $not-material,
"open-material": $open-material,
);
$custom-colors-border-subtle-dark: (
"accent": $accent,
"material": $material,
"not-material": $not-material,
"open-material": $open-material,
);
$theme-colors-text-dark: map.merge($theme-colors-text-dark, $custom-colors-text-dark);
$theme-colors-bg-subtle-dark: map.merge($theme-colors-bg-subtle-dark, $custom-colors-bg-subtle-dark);
$theme-colors-border-subtle-dark: map.merge($theme-colors-border-subtle-dark, $custom-colors-border-subtle-dark);
///// Utilities
$utilities: map-merge(
$utilities,
(
"white-space": (
property: white-space,
class: text,
values: (
wrap: normal,
nowrap: nowrap,
break-spaces: break-spaces
)
),
"viewport-height": (
property: height,
class: vh,
values: (
25: 25vh,
50: 50vh,
75: 75vh,
100: 100vh
)
)
)
);
///// Remainder of Bootstrap imports
@import "~bootstrap/scss/root";
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/type";
@import "~bootstrap/scss/images";
@import "~bootstrap/scss/containers";
@import "~bootstrap/scss/grid";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/transitions";
@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/nav";
@import "~bootstrap/scss/navbar";
@import "~bootstrap/scss/card";
@import "~bootstrap/scss/accordion";
@import "~bootstrap/scss/breadcrumb";
@import "~bootstrap/scss/pagination";
@import "~bootstrap/scss/badge";
@import "~bootstrap/scss/alert";
@import "~bootstrap/scss/progress";
@import "~bootstrap/scss/list-group";
@import "~bootstrap/scss/close";
@import "~bootstrap/scss/toasts";
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/tooltip";
@import "~bootstrap/scss/popover";
@import "~bootstrap/scss/carousel";
@import "~bootstrap/scss/spinners";
@import "~bootstrap/scss/offcanvas";
@import "~bootstrap/scss/placeholders";
@import "~bootstrap/scss/helpers";
@import "~bootstrap/scss/utilities/api";
Verwendet werden die Schriften Roboto (400, 500, 700) und Roboto Condensed (400, 500).
Die benötigten Dateien befinden sich in /resources/fonts. Die Definitionen finden sich in
/components/site/fonts.scss und werden in diesem Setup über
/components/site/site.scss eingebunden.
Momentan wird TomSelect verwendet. Anforderung ist, dass die Darstellung im Standard einzeilig bleibt, auch wenn sehr viele Optionen ausgewählt worden sind. Siehe auch das Beispiel bei den Formularen.
Folgend der Setup-Code:
import 'tom-select/dist/js/tom-select.complete.min.js';
import TomSelect from 'tom-select';
const tomSelectSettings = {
onInitialize: function() {
this.dropdownWatch = null;
this.dropdownWatchCb = () => {
if (this.isOpen) {
const controlRect = this.control.getBoundingClientRect();
const dropdownRect = this.dropdown.getBoundingClientRect();
const spaceAbove = controlRect.top;
const spaceBelow = window.innerHeight - controlRect.bottom;
if (spaceBelow < dropdownRect.height && spaceAbove > spaceBelow) {
this.wrapper.classList.add('dropdown-top');
} else {
this.wrapper.classList.remove('dropdown-top');
}
}
}
},
onDropdownOpen: function() {
this.dropdownWatchCb();
this.dropdownWatch = setInterval(this.dropdownWatchCb, 250);
},
onDropdownClose: function() {
clearInterval(this.dropdownWatch)
},
plugins: {
remove_button:{
title: 'Auswahl entfernen',
},
'checkbox_options': {
'checkedClassNames': ['form-check-input', 'ts-checked'],
'uncheckedClassNames': ['form-check-input', 'ts-unchecked'],
}
},
};
for (const select of document.querySelectorAll('.multi-select')) {
const tomSelect = new TomSelect(select, tomSelectSettings);
// Make sure the dropdown triggers when just clicking inside the control.
// Our "one-liner select" CSS actually hides the real trigger input from
// TomSelect and remedy that a bit here.
tomSelect.on('focus', event => {
tomSelect.refreshOptions();
tomSelect.open();
});
}
Wir verwenden die Outline-Variante der Tabler Icons. Eine Integration mit Vue ist verfügbar.
Es wird Apache ECharts verwendet. Hier scheint es ebenfalls eine aktuelle Vue-Integration zu geben.
Es wird GLightbox verwendet.
Die Bibliothek kann über npm eingebunden werden. Wir verwenden als Selektor [data-toggle="lightbox"].
Ein Beispiel findet sich hier.
import GLightbox from 'glightbox';
import 'glightbox/dist/css/glightbox.min.css';
const lightbox= GLightbox({
selector: '[data-toggle="lightbox"]'
});