mirror of
https://github.com/picocss/pico.git
synced 2025-04-20 16:46:14 -04:00
JavaScript modularization
This commit is contained in:
parent
366e0a55d6
commit
9575624834
21 changed files with 1629 additions and 1048 deletions
30
docs/js/components/aside.js
Normal file
30
docs/js/components/aside.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Aside adjustment
|
||||
*
|
||||
* Pico.css - https://picocss.com
|
||||
* Copyright 2019-2021 - Licensed under MIT
|
||||
*/
|
||||
|
||||
export const aside = {
|
||||
|
||||
// Config
|
||||
_minWidth: '992px',
|
||||
_targets: {
|
||||
nav: 'aside nav',
|
||||
details: 'aside details',
|
||||
},
|
||||
|
||||
|
||||
// Init
|
||||
init() {
|
||||
if (window.matchMedia('(min-width: ' + this._minWidth + ')').matches) {
|
||||
let nav = document.querySelector(this._targets.nav);
|
||||
let details = document.querySelectorAll(this._targets.details);
|
||||
if (nav.clientHeight < nav.scrollHeight) {
|
||||
details.forEach(function(detail) {
|
||||
detail.removeAttribute("open");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
177
docs/js/components/color-picker.js
Normal file
177
docs/js/components/color-picker.js
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Color Picker
|
||||
*
|
||||
* Pico.css - https://picocss.com
|
||||
* Copyright 2019-2021 - Licensed under MIT
|
||||
*/
|
||||
|
||||
export const colorPicker = {
|
||||
|
||||
// Config
|
||||
_colors: null,
|
||||
_buttonsTarget: '#customization article[data-theme="generated"]',
|
||||
_selectorButton: '#customization button[data-color]',
|
||||
_selectorSection: '#customization',
|
||||
_buttons: null,
|
||||
_generatedStyles: null,
|
||||
|
||||
// Set colors
|
||||
set colors(colors) {
|
||||
this._colors = colors;
|
||||
},
|
||||
|
||||
// Init
|
||||
init() {
|
||||
this.generateButtons();
|
||||
this.setActiveButton('pink');
|
||||
this.generateTheme('pink');
|
||||
},
|
||||
|
||||
// Generate Buttons
|
||||
generateButtons() {
|
||||
|
||||
// Init
|
||||
let innerButtons = '';
|
||||
let innerStyles = '';
|
||||
|
||||
|
||||
// Loop colors
|
||||
for (const color in this._colors) {
|
||||
// Buttons
|
||||
innerButtons += '<button data-color="'+ color +'" aria-label="Activate '+ color +' theme"></button>';
|
||||
|
||||
// Styles
|
||||
innerStyles += `
|
||||
button[data-color="${color}"] {
|
||||
background-color: ${this._colors[color]['600']};
|
||||
}
|
||||
[data-theme="light"] button[data-color="${color}"]:hover,
|
||||
[data-theme="light"] button[data-color="${color}"]:active,
|
||||
[data-theme="light"] button[data-color="${color}"]:focus {
|
||||
background-color: ${this._colors[color]['700']}; '
|
||||
}
|
||||
[data-theme="dark"] button[data-color="${color}"]:hover,
|
||||
[data-theme="dark"] button[data-color="${color}"]:active,
|
||||
[data-theme="dark"] button[data-color="${color}"]:focus {
|
||||
background-color: ${this._colors[color]['500']};
|
||||
}`;
|
||||
}
|
||||
|
||||
|
||||
// Insert buttons
|
||||
let containerButtons = document.createElement('FIGURE');
|
||||
containerButtons.innerHTML = innerButtons;
|
||||
document.querySelector(this._buttonsTarget).before(containerButtons);
|
||||
|
||||
// Buttons listeners
|
||||
this._buttons = document.querySelectorAll(this._selectorButton);
|
||||
this._buttons.forEach(function(button) {
|
||||
button.addEventListener('click', function(event) {
|
||||
let color = event.target.getAttribute('data-color');
|
||||
this.setActiveButton(color);
|
||||
this.generateTheme(color);
|
||||
}.bind(this), false);
|
||||
}.bind(this));
|
||||
|
||||
// Insert CSS Styles
|
||||
let containerStyles = document.createElement('STYLE');
|
||||
containerStyles.setAttribute('title', 'color-picker');
|
||||
this._generatedStyles = this.minifyCSS(innerStyles);
|
||||
containerStyles.innerHTML = this._generatedStyles;
|
||||
document.querySelector('head').appendChild(containerStyles);
|
||||
},
|
||||
|
||||
|
||||
// Set active button
|
||||
setActiveButton(color) {
|
||||
|
||||
// Remove all active states
|
||||
this._buttons.forEach(function(button) {
|
||||
button.removeAttribute('class');
|
||||
}.bind(this));
|
||||
|
||||
// Set active state
|
||||
let buttonPicked = document.querySelector(this._selectorButton + '[data-color="' + color + '"]');
|
||||
buttonPicked.setAttribute('class', 'picked');
|
||||
},
|
||||
|
||||
|
||||
// Set active button
|
||||
generateTheme(color) {
|
||||
let name = color;
|
||||
let data = this._colors[color];
|
||||
|
||||
// 1. Update name and colors in demo code
|
||||
let swaps = {
|
||||
'.name': name.charAt(0).toUpperCase() + name.substring(1) + ' ',
|
||||
'.c500': data[500],
|
||||
'.c600': data[600],
|
||||
'.c700': data[700],
|
||||
'.c600-outline-light': this.hexToRgbA(data[600], .125),
|
||||
'.c600-outline-dark': this.hexToRgbA(data[600], .25),
|
||||
'.inverse': data['inverse'],
|
||||
}
|
||||
|
||||
Object.keys(swaps).forEach(function(swap) {
|
||||
let targets = document.querySelectorAll(this._selectorSection + ' ' + swap);
|
||||
targets.forEach(function(target) {
|
||||
target.innerHTML = swaps[swap];
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
||||
// 2. Update CSS Styles
|
||||
const innerStyles = `
|
||||
[data-theme="generated"] {
|
||||
--h4-color: ${data[700]};
|
||||
--primary: ${data[600]};
|
||||
--primary-hover: ${data[700]};
|
||||
--primary-focus: ${this.hexToRgbA(data[600], .125)};
|
||||
--primary-inverse: ${data['inverse']};
|
||||
}
|
||||
@media only screen and (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme="light"]) [data-theme="generated"] {
|
||||
--h4-color: ${data[400]};
|
||||
--primary: ${data[600]};
|
||||
--primary-hover: ${data[500]};
|
||||
--primary-focus: ${this.hexToRgbA(data[600], .25)};
|
||||
--primary-inverse: ${data['inverse']};
|
||||
}
|
||||
}
|
||||
[data-theme="dark"] [data-theme="generated"] {
|
||||
--h4-color: ${data[500]};
|
||||
--primary: ${data[600]};
|
||||
--primary-hover: ${data[500]};
|
||||
--primary-focus: ${this.hexToRgbA(data[600], .25)};
|
||||
--primary-inverse: ${data['inverse']};
|
||||
}
|
||||
[data-theme="generated"] {
|
||||
--form-element-active-border-color: var(--primary);
|
||||
--form-element-focus-color: var(--primary-focus);
|
||||
--switch-color: var(--primary-inverse);
|
||||
--switch-checked-background-color: var(--primary);
|
||||
}`;
|
||||
|
||||
document.querySelector('style[title="color-picker"]').innerHTML = this._generatedStyles + this.minifyCSS(innerStyles);
|
||||
},
|
||||
|
||||
|
||||
// Minify CSS
|
||||
minifyCSS(css) {
|
||||
return css.replace(/^ +/gm, '')
|
||||
},
|
||||
|
||||
|
||||
// Hexadecimal to Rgba
|
||||
hexToRgbA(hex, alpha) {
|
||||
var c;
|
||||
if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
|
||||
c= hex.substring(1).split('');
|
||||
if(c.length== 3) {
|
||||
c= [c[0], c[0], c[1], c[1], c[2], c[2]];
|
||||
}
|
||||
c= '0x' + c.join('');
|
||||
return 'rgba(' + [(c>>16)&255, (c>>8)&255, c&255].join(', ') + ', ' + alpha + ')';
|
||||
}
|
||||
throw new Error('Bad Hex');
|
||||
}
|
||||
}
|
104
docs/js/components/grid.js
Normal file
104
docs/js/components/grid.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Grid Interaction
|
||||
*
|
||||
* Pico.css - https://picocss.com
|
||||
* Copyright 2019-2021 - Licensed under MIT
|
||||
*/
|
||||
|
||||
export const grid = {
|
||||
|
||||
// Config
|
||||
_buttons: {
|
||||
text: {
|
||||
add: 'Add column',
|
||||
remove: 'Remove column'
|
||||
},
|
||||
target: '#grids article'
|
||||
},
|
||||
_grid: {
|
||||
current: 4,
|
||||
min: 1,
|
||||
max: 12,
|
||||
gridTarget: '#grids .grid',
|
||||
codeTarget: '#grids pre code'
|
||||
},
|
||||
|
||||
|
||||
// Init
|
||||
init() {
|
||||
this.addButtons();
|
||||
this.generateGrid()
|
||||
},
|
||||
|
||||
|
||||
// Add buttons
|
||||
addButtons() {
|
||||
|
||||
// Insert buttons
|
||||
let buttons = document.createElement('P');
|
||||
buttons.innerHTML = `
|
||||
<button class="secondary add">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||||
<line x1="5" y1="12" x2="19" y2="12">'</line>
|
||||
</svg>
|
||||
${this._buttons.text.add}
|
||||
</button>
|
||||
|
||||
<button class="secondary remove">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||||
</svg>
|
||||
${this._buttons.text.remove}
|
||||
</button>`;
|
||||
document.querySelector(this._buttons.target).before(buttons);
|
||||
|
||||
// Add button listener
|
||||
document.querySelector('#grids button.add').addEventListener('click', function() {
|
||||
this.addColumn();
|
||||
}.bind(this), false);
|
||||
|
||||
// Remove button listener
|
||||
document.querySelector('#grids button.remove').addEventListener('click', function() {
|
||||
this.removeColumn();
|
||||
}.bind(this), false);
|
||||
},
|
||||
|
||||
|
||||
// Generate grid
|
||||
generateGrid() {
|
||||
|
||||
// Config
|
||||
let htmlInner = '';
|
||||
let codeInner = '<<b>div</b> <i>class</i>=<u>"grid"</u>>\n';
|
||||
|
||||
// Build
|
||||
for (let col = 0; col < this._grid.current; col++) {
|
||||
htmlInner += '<div>' + (col + 1) + '</div>';
|
||||
codeInner += ' <<b>div</b>>' + (col+1) + '</<b>div</b>>\n';
|
||||
}
|
||||
|
||||
// Display
|
||||
codeInner += '</<b>div</b>>';
|
||||
document.querySelector(this._grid.gridTarget).innerHTML = htmlInner;
|
||||
document.querySelector(this._grid.codeTarget).innerHTML = codeInner;
|
||||
},
|
||||
|
||||
|
||||
// Add column
|
||||
addColumn() {
|
||||
if (this._grid.current < this._grid.max) {
|
||||
this._grid.current++;
|
||||
this.generateGrid();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Remove column
|
||||
removeColumn() {
|
||||
if (this._grid.current > this._grid.min) {
|
||||
this._grid.current--;
|
||||
this.generateGrid();
|
||||
}
|
||||
}
|
||||
};
|
301
docs/js/components/material-design-colors.js
Normal file
301
docs/js/components/material-design-colors.js
Normal file
|
@ -0,0 +1,301 @@
|
|||
// Source: https://material.io/design/color/the-color-system.html
|
||||
export const materialDesignColors = {
|
||||
red: {
|
||||
50: "#ffebee",
|
||||
100: "#ffcdd2",
|
||||
200: "#ef9a9a",
|
||||
300: "#e57373",
|
||||
400: "#ef5350",
|
||||
500: "#f44336",
|
||||
600: "#e53935",
|
||||
700: "#d32f2f",
|
||||
800: "#c62828",
|
||||
900: "#b71c1c",
|
||||
a100: "#ff8a80",
|
||||
a200: "#ff5252",
|
||||
a400: "#ff1744",
|
||||
a700: "#d50000",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
pink: {
|
||||
50: "#fce4ec",
|
||||
100: "#f8bbd0",
|
||||
200: "#f48fb1",
|
||||
300: "#f06292",
|
||||
400: "#ec407a",
|
||||
500: "#e91e63",
|
||||
600: "#d81b60",
|
||||
700: "#c2185b",
|
||||
800: "#ad1457",
|
||||
900: "#880e4f",
|
||||
a100: "#ff80ab",
|
||||
a200: "#ff4081",
|
||||
a400: "#f50057",
|
||||
a700: "#c51162",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
purple: {
|
||||
50: "#f3e5f5",
|
||||
100: "#e1bee7",
|
||||
200: "#ce93d8",
|
||||
300: "#ba68c8",
|
||||
400: "#ab47bc",
|
||||
500: "#9c27b0",
|
||||
600: "#8e24aa",
|
||||
700: "#7b1fa2",
|
||||
800: "#6a1b9a",
|
||||
900: "#4a148c",
|
||||
a100: "#ea80fc",
|
||||
a200: "#e040fb",
|
||||
a400: "#d500f9",
|
||||
a700: "#aa00ff",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
"deep-purple": {
|
||||
50: "#ede7f6",
|
||||
100: "#d1c4e9",
|
||||
200: "#b39ddb",
|
||||
300: "#9575cd",
|
||||
400: "#7e57c2",
|
||||
500: "#673ab7",
|
||||
600: "#5e35b1",
|
||||
700: "#512da8",
|
||||
800: "#4527a0",
|
||||
900: "#311b92",
|
||||
a100: "#b388ff",
|
||||
a200: "#7c4dff",
|
||||
a400: "#651fff",
|
||||
a700: "#6200ea",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
indigo: {
|
||||
50: "#e8eaf6",
|
||||
100: "#c5cae9",
|
||||
200: "#9fa8da",
|
||||
300: "#7986cb",
|
||||
400: "#5c6bc0",
|
||||
500: "#3f51b5",
|
||||
600: "#3949ab",
|
||||
700: "#303f9f",
|
||||
800: "#283593",
|
||||
900: "#1a237e",
|
||||
a100: "#8c9eff",
|
||||
a200: "#536dfe",
|
||||
a400: "#3d5afe",
|
||||
a700: "#304ffe",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
blue: {
|
||||
50: "#e3f2fd",
|
||||
100: "#bbdefb",
|
||||
200: "#90caf9",
|
||||
300: "#64b5f6",
|
||||
400: "#42a5f5",
|
||||
500: "#2196f3",
|
||||
600: "#1e88e5",
|
||||
700: "#1976d2",
|
||||
800: "#1565c0",
|
||||
900: "#0d47a1",
|
||||
a100: "#82b1ff",
|
||||
a200: "#448aff",
|
||||
a400: "#2979ff",
|
||||
a700: "#2962ff",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
"light-blue": {
|
||||
50: "#e1f5fe",
|
||||
100: "#b3e5fc",
|
||||
200: "#81d4fa",
|
||||
300: "#4fc3f7",
|
||||
400: "#29b6f6",
|
||||
500: "#03a9f4",
|
||||
600: "#039be5",
|
||||
700: "#0288d1",
|
||||
800: "#0277bd",
|
||||
900: "#01579b",
|
||||
a100: "#80d8ff",
|
||||
a200: "#40c4ff",
|
||||
a400: "#00b0ff",
|
||||
a700: "#0091ea",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
cyan: {
|
||||
50: "#e0f7fa",
|
||||
100: "#b2ebf2",
|
||||
200: "#80deea",
|
||||
300: "#4dd0e1",
|
||||
400: "#26c6da",
|
||||
500: "#00bcd4",
|
||||
600: "#00acc1",
|
||||
700: "#0097a7",
|
||||
800: "#00838f",
|
||||
900: "#006064",
|
||||
a100: "#84ffff",
|
||||
a200: "#18ffff",
|
||||
a400: "#00e5ff",
|
||||
a700: "#00b8d4",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
teal: {
|
||||
50: "#e0f2f1",
|
||||
100: "#b2dfdb",
|
||||
200: "#80cbc4",
|
||||
300: "#4db6ac",
|
||||
400: "#26a69a",
|
||||
500: "#009688",
|
||||
600: "#00897b",
|
||||
700: "#00796b",
|
||||
800: "#00695c",
|
||||
900: "#004d40",
|
||||
a100: "#a7ffeb",
|
||||
a200: "#64ffda",
|
||||
a400: "#1de9b6",
|
||||
a700: "#00bfa5",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
green: {
|
||||
50: "#e8f5e9",
|
||||
100: "#c8e6c9",
|
||||
200: "#a5d6a7",
|
||||
300: "#81c784",
|
||||
400: "#66bb6a",
|
||||
500: "#4caf50",
|
||||
600: "#43a047",
|
||||
700: "#388e3c",
|
||||
800: "#2e7d32",
|
||||
900: "#1b5e20",
|
||||
a100: "#b9f6ca",
|
||||
a200: "#69f0ae",
|
||||
a400: "#00e676",
|
||||
a700: "#00c853",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
"light-green": {
|
||||
50: "#f1f8e9",
|
||||
100: "#dcedc8",
|
||||
200: "#c5e1a5",
|
||||
300: "#aed581",
|
||||
400: "#9ccc65",
|
||||
500: "#8bc34a",
|
||||
600: "#7cb342",
|
||||
700: "#689f38",
|
||||
800: "#558b2f",
|
||||
900: "#33691e",
|
||||
a100: "#ccff90",
|
||||
a200: "#b2ff59",
|
||||
a400: "#76ff03",
|
||||
a700: "#64dd17",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
lime: {
|
||||
50: "#f9fbe7",
|
||||
100: "#f0f4c3",
|
||||
200: "#e6ee9c",
|
||||
300: "#dce775",
|
||||
400: "#d4e157",
|
||||
500: "#cddc39",
|
||||
600: "#c0ca33",
|
||||
700: "#afb42b",
|
||||
800: "#9e9d24",
|
||||
900: "#827717",
|
||||
a100: "#f4ff81",
|
||||
a200: "#eeff41",
|
||||
a400: "#c6ff00",
|
||||
a700: "#aeea00",
|
||||
inverse: "rgba(0, 0, 0, 0.75)"
|
||||
},
|
||||
yellow: {
|
||||
50: "#fffde7",
|
||||
100: "#fff9c4",
|
||||
200: "#fff59d",
|
||||
300: "#fff176",
|
||||
400: "#ffee58",
|
||||
500: "#ffeb3b",
|
||||
600: "#fdd835",
|
||||
700: "#fbc02d",
|
||||
800: "#f9a825",
|
||||
900: "#f57f17",
|
||||
a100: "#ffff8d",
|
||||
a200: "#ffff00",
|
||||
a400: "#ffea00",
|
||||
a700: "#ffd600",
|
||||
inverse: "rgba(0, 0, 0, 0.75)"
|
||||
},
|
||||
amber: {
|
||||
50: "#fff8e1",
|
||||
100: "#ffecb3",
|
||||
200: "#ffe082",
|
||||
300: "#ffd54f",
|
||||
400: "#ffca28",
|
||||
500: "#ffc107",
|
||||
600: "#ffb300",
|
||||
700: "#ffa000",
|
||||
800: "#ff8f00",
|
||||
900: "#ff6f00",
|
||||
a100: "#ffe57f",
|
||||
a200: "#ffd740",
|
||||
a400: "#ffc400",
|
||||
a700: "#ffab00",
|
||||
inverse: "rgba(0, 0, 0, 0.75)"
|
||||
},
|
||||
orange: {
|
||||
50: "#fff3e0",
|
||||
100: "#ffe0b2",
|
||||
200: "#ffcc80",
|
||||
300: "#ffb74d",
|
||||
400: "#ffa726",
|
||||
500: "#ff9800",
|
||||
600: "#fb8c00",
|
||||
700: "#f57c00",
|
||||
800: "#ef6c00",
|
||||
900: "#e65100",
|
||||
a100: "#ffd180",
|
||||
a200: "#ffab40",
|
||||
a400: "#ff9100",
|
||||
a700: "#ff6d00",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
"deep-orange": {
|
||||
50: "#fbe9e7",
|
||||
100: "#ffccbc",
|
||||
200: "#ffab91",
|
||||
300: "#ff8a65",
|
||||
400: "#ff7043",
|
||||
500: "#ff5722",
|
||||
600: "#f4511e",
|
||||
700: "#e64a19",
|
||||
800: "#d84315",
|
||||
900: "#bf360c",
|
||||
a100: "#ff9e80",
|
||||
a200: "#ff6e40",
|
||||
a400: "#ff3d00",
|
||||
a700: "#dd2c00",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
grey: {
|
||||
50: "#fafafa",
|
||||
100: "#f5f5f5",
|
||||
200: "#eeeeee",
|
||||
300: "#e0e0e0",
|
||||
400: "#bdbdbd",
|
||||
500: "#9e9e9e",
|
||||
600: "#757575",
|
||||
700: "#616161",
|
||||
800: "#424242",
|
||||
900: "#212121",
|
||||
inverse: "#FFF"
|
||||
},
|
||||
"blue-grey": {
|
||||
50: "#eceff1",
|
||||
100: "#cfd8dc",
|
||||
200: "#b0bec5",
|
||||
300: "#90a4ae",
|
||||
400: "#78909c",
|
||||
500: "#607d8b",
|
||||
600: "#546e7a",
|
||||
700: "#455a64",
|
||||
800: "#37474f",
|
||||
900: "#263238",
|
||||
inverse: "#FFF"
|
||||
}
|
||||
};
|
63
docs/js/components/scrollspy.js
Normal file
63
docs/js/components/scrollspy.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Scrollspy
|
||||
* Automatically update nav targets based on scroll position
|
||||
*
|
||||
* Require `most-visible.js` (https://github.com/andyexeter/most-visible)
|
||||
*
|
||||
* Pico.css - https://picocss.com
|
||||
* Copyright 2019-2021 - Licensed under MIT
|
||||
*/
|
||||
|
||||
export const scrollspy = {
|
||||
|
||||
// Config
|
||||
_minWidth: '992px',
|
||||
_interval: 75,
|
||||
_targets: {
|
||||
sections: '[role="document"] > section',
|
||||
nav: 'main aside nav',
|
||||
active: 'active',
|
||||
},
|
||||
|
||||
|
||||
// Init
|
||||
init() {
|
||||
if (window.matchMedia('(min-width: ' + this._minWidth + ')').matches) {
|
||||
this.setActiveNav();
|
||||
this.scrollStop();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Set active section in nav
|
||||
setActiveNav() {
|
||||
|
||||
// Get active section
|
||||
let currentSection = mostVisible(this._targets.sections).getAttribute('id');
|
||||
|
||||
// Remove all active states
|
||||
let links = document.querySelectorAll(this._targets.nav + ' a.' + this._targets.active);
|
||||
links.forEach(function(link) {
|
||||
link.classList.remove(this._targets.active);
|
||||
}.bind(this));
|
||||
|
||||
// Set active state
|
||||
let activeLink = document.querySelector(this._targets.nav + ' a[href="#' + currentSection + '"]');
|
||||
activeLink.classList.add(this._targets.active);
|
||||
|
||||
// Open details parent
|
||||
activeLink.closest('details').setAttribute('open', '');
|
||||
},
|
||||
|
||||
|
||||
// Scroll stop
|
||||
scrollStop() {
|
||||
let isScrolling;
|
||||
window.addEventListener('scroll', function (event) {
|
||||
window.clearTimeout(isScrolling);
|
||||
isScrolling = setTimeout(function() {
|
||||
this.setActiveNav();
|
||||
}.bind(this), this._interval);
|
||||
}.bind(this), false);
|
||||
}
|
||||
}
|
105
docs/js/components/theme-switcher.js
Normal file
105
docs/js/components/theme-switcher.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Theme switcher
|
||||
*
|
||||
* Pico.css - https://picocss.com
|
||||
* Copyright 2019-2021 - Licensed under MIT
|
||||
*/
|
||||
|
||||
export const themeSwitcher = {
|
||||
|
||||
// Config
|
||||
_change: {
|
||||
light: '<i>Turn on dark mode</i>',
|
||||
dark: '<i>Turn off dark mode</i>'
|
||||
},
|
||||
_buttonsTarget: '.theme-switcher',
|
||||
_scheme: 'auto',
|
||||
|
||||
|
||||
// Init
|
||||
init() {
|
||||
this.scheme = this._scheme;
|
||||
this.initSwitchers();
|
||||
},
|
||||
|
||||
|
||||
// Prefered color scheme
|
||||
get preferedColorScheme() {
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
return 'dark';
|
||||
}
|
||||
else {
|
||||
return 'light';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// Init switchers
|
||||
initSwitchers() {
|
||||
const buttons = document.querySelectorAll(this._buttonsTarget);
|
||||
buttons.forEach(function(button) {
|
||||
button.addEventListener('click', function(event) {
|
||||
if (this._scheme == 'dark') {
|
||||
this.scheme = 'light';
|
||||
}
|
||||
else {
|
||||
this.scheme = 'dark';
|
||||
}
|
||||
}.bind(this), false);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
|
||||
// Add new button
|
||||
addButton(config) {
|
||||
|
||||
// Insert Switcher
|
||||
let button = document.createElement(config.tag);
|
||||
button.className = config.class;
|
||||
document.querySelector(config.target).appendChild(button);
|
||||
},
|
||||
|
||||
|
||||
// Set scheme
|
||||
set scheme(scheme) {
|
||||
|
||||
if (scheme == 'auto') {
|
||||
if (this.preferedColorScheme == 'dark') {
|
||||
this._scheme = 'dark';
|
||||
}
|
||||
else {
|
||||
this._scheme = 'light';
|
||||
}
|
||||
}
|
||||
|
||||
// Set to Dark
|
||||
else if (scheme == 'dark' || scheme == 'light') {
|
||||
this._scheme = scheme;
|
||||
}
|
||||
|
||||
// Set to Apply theme
|
||||
this.applyScheme();
|
||||
},
|
||||
|
||||
|
||||
// Apply scheme
|
||||
applyScheme() {
|
||||
|
||||
// Root attribute
|
||||
document.querySelector('html').setAttribute('data-theme', this._scheme);
|
||||
|
||||
// Buttons text
|
||||
const buttons = document.querySelectorAll(this._buttonsTarget);
|
||||
let text;
|
||||
buttons.forEach(function(button) {
|
||||
if (this._scheme == 'dark') {
|
||||
text = this._change.dark;
|
||||
}
|
||||
else {
|
||||
text = this._change.light;
|
||||
}
|
||||
button.innerHTML = text;
|
||||
button.setAttribute('aria-label', text.replace(/<[^>]*>?/gm, ''));
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue