Initial commit

This commit is contained in:
Eduardo Silva 2024-02-14 16:36:01 -03:00
commit ed55724808
2505 changed files with 1136655 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/.venv
/.vscode
*.pyc
*__pycache__/
*.pyo
*.pyd

37
Dockerfile Normal file
View File

@ -0,0 +1,37 @@
# Usar uma imagem base do Python
FROM python:3.10
# Definir o diretório de trabalho no container
WORKDIR /app
RUN apt-get update && apt-get install -y \
wireguard \
iptables \
iproute2 \
net-tools \
inetutils-ping \
inetutils-traceroute \
nano \
vim-nox \
&& rm -rf /var/lib/apt/lists/*
# those are the really necessary packages
#RUN apt-get update && apt-get install -y \
# wireguard \
# iptables \
# && rm -rf /var/lib/apt/lists/*
# Copiar o arquivo requirements.txt para o container
COPY requirements.txt /app/
# Instalar as dependências do Python
RUN pip install --no-cache-dir -r requirements.txt
# Copiar o restante do código-fonte do projeto para o container
COPY . /app/
# Dar permissão de execução para o script init.sh
RUN chmod +x /app/init.sh
# Comando para executar o script init.sh
CMD ["/app/init.sh"]

1
README.md Normal file
View File

@ -0,0 +1 @@
# wireguard_webadmin

0
accounts/__init__.py Normal file
View File

3
accounts/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
accounts/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class AccountsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'accounts'

41
accounts/forms.py Normal file
View File

@ -0,0 +1,41 @@
from typing import Any
from django import forms
from django.core.exceptions import ValidationError
from django.contrib.auth import authenticate
class CreateUserForm(forms.Form):
username = forms.CharField(label='Username')
password = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput) # Adicione este campo para a confirmação da senha
def clean(self):
cleaned_data = super().clean()
username = cleaned_data.get("username")
if username and ' ' in username:
self.add_error('username', ValidationError("Username cannot contain spaces."))
cleaned_data['username'] = username.lower()
password = cleaned_data.get("password")
password2 = cleaned_data.get("password2")
if password and password2 and password != password2:
self.add_error('password2', ValidationError("The two password fields didn't match."))
return cleaned_data
class LoginForm(forms.Form):
username = forms.CharField(label='Username')
password = forms.CharField(label='Password', widget=forms.PasswordInput)
def clean(self):
cleaned_data = super().clean()
username = cleaned_data.get("username")
password = cleaned_data.get("password")
if username and password:
user = authenticate(username=username, password=password)
if not user:
self.add_error(None, ValidationError("Invalid username or password."))
else:
self.add_error(None, ValidationError("Both fields are required."))
return cleaned_data

View File

3
accounts/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
accounts/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

40
accounts/views.py Normal file
View File

@ -0,0 +1,40 @@
from django.shortcuts import render, Http404, redirect
from django.contrib.auth.models import User
from django.contrib import auth
from .forms import CreateUserForm, LoginForm
from django.http import HttpResponse
def view_create_first_user(request):
if User.objects.filter().all():
raise Http404('Superuser already exists')
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
User.objects.create_superuser(username=username, password=password)
return render(request, 'accounts/superuser_created.html')
else:
form = CreateUserForm()
return render(request, 'accounts/create_first_user.html', {'form': form})
def view_login(request):
if not User.objects.filter().all():
return redirect('/accounts/create_first_user/')
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
user = User.objects.get(username=username)
auth.login(request, user)
return redirect('/')
else:
form = LoginForm()
return render(request, 'accounts/login.html', {'form': form})
def view_logout(request):
auth.logout(request)
return render(request, 'accounts/logout.html')

0
console/__init__.py Normal file
View File

3
console/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
console/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class ConsoleConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'console'

View File

3
console/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
console/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

63
console/views.py Normal file
View File

@ -0,0 +1,63 @@
from wgwadmlibrary.tools import is_valid_ip_or_hostname
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
import subprocess
@login_required
def view_console(request):
page_title = 'Console'
requested_command = request.GET.get('command')
command_target = request.GET.get('target', '')
if command_target:
if not is_valid_ip_or_hostname(command_target):
command_target = ''
if requested_command == 'iptables':
page_title = 'Console: iptables list'
bash_command = ['bash', '-c', 'iptables -L -nv ; iptables -t nat -L -nv']
elif requested_command == 'ifconfig':
page_title = 'Console: ifconfig'
bash_command = ['bash', '-c', 'ifconfig']
elif requested_command == 'ps':
page_title = 'Console: running processes'
bash_command = ['bash', '-c', 'ps faux']
elif requested_command == 'wgshow':
page_title = 'Console: WireGuard show'
bash_command = ['bash', '-c', 'wg show']
elif requested_command == 'freem':
page_title = 'Console: Memory usage'
bash_command = ['bash', '-c', 'free -m']
elif requested_command == 'route':
page_title = 'Console: top'
bash_command = ['bash', '-c', 'route -n']
elif requested_command == 'top':
page_title = 'Console: top'
bash_command = ['bash', '-c', 'top -b -n 1']
elif requested_command == 'ping':
page_title = 'Console: ping ' + command_target
bash_command = ['bash', '-c', 'ping -c 4 ' + command_target]
elif requested_command == 'traceroute':
page_title = 'Console: traceroute ' + command_target
bash_command = ['bash', '-c', 'traceroute ' + command_target]
else:
bash_command = None
command_output = ''
command_success = False
if requested_command == 'ping' or requested_command == 'traceroute':
if not command_target:
command_output = requested_command + ': Invalid target'
bash_command = None
command_success = False
if bash_command:
try:
command_output = subprocess.check_output(bash_command, stderr=subprocess.STDOUT).decode('utf-8')
command_success = True
except subprocess.CalledProcessError as e:
command_output = e.output.decode('utf-8')
command_success = False
context = {'page_title': page_title, 'command_output': command_output, 'command_success': command_success}
return render(request, 'console/console.html', context)

38
docker-compose.yml Normal file
View File

@ -0,0 +1,38 @@
version: '3'
services:
wireguard-webadmin:
image: ubuntu:latest
container_name: wireguard-webadmin
build:
context: .
volumes:
- wireguard:/etc/wireguard
- static_volume:/app_static_files/
- .:/app
ports:
- "127.0.0.1:8000:8000"
- "51820-51839:51820-51839/udp"
# dont go crazy adding ports. Docker will have a hard time handling with a large range of ports
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv4.ip_forward=1
command: /bin/bash /app/init.sh
nginx:
container_name: wireguard-webadmin-nginx
image: nginx:alpine
volumes:
- ./virtualhost.conf:/etc/nginx/conf.d/wireguard-webadmin.conf
- static_volume:/static
- https_cert:/certificate
ports:
- "80:80"
- "443:443"
volumes:
static_volume:
https_cert:
wireguard:

16
init.sh Normal file
View File

@ -0,0 +1,16 @@
#!/bin/bash
set -e
# Starts each WireGuard configuration file found in /etc/wireguard
shopt -s nullglob
config_files=(/etc/wireguard/*.conf)
if [ ${#config_files[@]} -gt 0 ]; then
for f in "${config_files[@]}"; do
wg-quick up "$(basename "${f}" .conf)"
done
fi
# Django startup
python manage.py migrate --noinput
python manage.py collectstatic --noinput
exec python manage.py runserver 0.0.0.0:8000

22
manage.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wireguard_webadmin.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
asgiref==3.7.2
Django==5.0.1
sqlparse==0.4.4
typing_extensions==4.9.0

View File

@ -0,0 +1,13 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
loose: true,
bugfixes: true,
modules: false,
exclude: ['transform-typeof-symbol']
}
]
]
};

View File

@ -0,0 +1,10 @@
# https://github.com/browserslist/browserslist#readme
>= 0.2%
last 2 major versions
not dead
Firefox ESR
Edge >= 16
Explorer >= 10
iOS >= 9
Safari >= 9

View File

@ -0,0 +1,68 @@
{
"files": [
{
"path": "./dist/css/adminlte.css",
"maxSize": "128.3 kB"
},
{
"path": "./dist/css/adminlte.min.css",
"maxSize": "121.5 kB"
},
{
"path": "./dist/css/alt/adminlte.components.css",
"maxSize": "28.6 kB"
},
{
"path": "./dist/css/alt/adminlte.components.min.css",
"maxSize": "27.8 kB"
},
{
"path": "./dist/css/alt/adminlte.core.css",
"maxSize": "72.2 kB"
},
{
"path": "./dist/css/alt/adminlte.core.min.css",
"maxSize": "69.4 kB"
},
{
"path": "./dist/css/alt/adminlte.extra-components.css",
"maxSize": "4.6 kB"
},
{
"path": "./dist/css/alt/adminlte.extra-components.min.css",
"maxSize": "4.5 kB"
},
{
"path": "./dist/css/alt/adminlte.light.css",
"maxSize": "94 kB"
},
{
"path": "./dist/css/alt/adminlte.light.min.css",
"maxSize": "89 kB"
},
{
"path": "./dist/css/alt/adminlte.pages.css",
"maxSize": "3.5 kB"
},
{
"path": "./dist/css/alt/adminlte.pages.min.css",
"maxSize": "3.1 kB"
},
{
"path": "./dist/css/alt/adminlte.plugins.css",
"maxSize": "22.2 kB"
},
{
"path": "./dist/css/alt/adminlte.plugins.min.css",
"maxSize": "21.5 kB"
},
{
"path": "./dist/js/adminlte.js",
"maxSize": "16.4 kB"
},
{
"path": "./dist/js/adminlte.min.js",
"maxSize": "10.9 kB"
}
]
}

View File

@ -0,0 +1,4 @@
.git
*Dockerfile*
*docker-compose*
node_modules

View File

@ -0,0 +1,14 @@
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false

View File

@ -0,0 +1,5 @@
**/*.min.js
**/plugins/
/dist/js/adminlte.js
/docs/
/docs_html/

View File

@ -0,0 +1,76 @@
{
"root": true,
"extends": [
"plugin:compat/recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:unicorn/recommended",
"xo",
"xo/browser"
],
"env": {
"jquery": true
},
"rules": {
"arrow-body-style": "off",
"capitalized-comments": "off",
"comma-dangle": [
"error",
"never"
],
"eqeqeq": "off",
"indent": [
"error",
2,
{
"MemberExpression": "off",
"SwitchCase": 1
}
],
"multiline-ternary": [
"error",
"always-multiline"
],
"new-cap": [
"error",
{
"properties": false
}
],
"no-eq-null": "off",
"no-negated-condition": "off",
"no-console": "error",
"object-curly-spacing": [
"error",
"always"
],
"operator-linebreak": [
"error",
"after"
],
"prefer-template": "error",
"prefer-named-capture-group": "off",
"semi": [
"error",
"never"
],
"unicorn/filename-case": "off",
"unicorn/consistent-destructuring": "off",
"unicorn/no-array-callback-reference": "off",
"unicorn/no-array-for-each": "off",
"unicorn/no-for-loop": "off",
"unicorn/no-null": "off",
"unicorn/no-unused-properties": "error",
"unicorn/prefer-dom-node-append": "off",
"unicorn/prefer-dom-node-dataset": "off",
"unicorn/prefer-dom-node-remove": "off",
"unicorn/prefer-export-from": "off",
"unicorn/prefer-includes": "off",
"unicorn/prefer-number-properties": "off",
"unicorn/prefer-optional-catch-binding": "off",
"unicorn/prefer-query-selector": "off",
"unicorn/prefer-set-has": "off",
"unicorn/prevent-abbreviations": "off"
}
}

View File

@ -0,0 +1,6 @@
# Enforce Unix newlines
* text=auto eol=lf
# Ignores for analysis is used to produce the language stats bar which displays the languages percentages
plugins/* linguist-vendored=true
docs/* linguist-vendored=true

View File

@ -0,0 +1,37 @@
# Contributing to AdminLTE
Contributions are always **welcome and recommended**! Here is how for beginner's: [Get started with open source click here](https://youtu.be/GbqSvJs-6W4)
1. Contribution Requirements :
* When you contribute, you agree to give a non-exclusive license to AdminLTE.io to use that contribution in any context as we (AdminLTE.io) see appropriate.
* If you use content provided by another party, it must be appropriately licensed using an [open source](https://opensource.org/licenses) license.
* Contributions are only accepted through GitHub pull requests.
* Finally, contributed code must work in all supported browsers (see above for browser support).
2. Installation :
* Fork the repository ([here is the guide](https://help.github.com/articles/fork-a-repo/)).
* Clone to your machine
```bash
git clone https://github.com/YOUR_USERNAME/AdminLTE.git
```
* Create a new branch
3. Compile dist files (Development) :
* To compile the dist files you need Node.js 14 or higher/npm (node package manager)
* Delete ./package-lock.json file
* `npm install` (install npm deps)
* `npm run dev` (developer mode, autocompile with browsersync support for live demo)
* Make your changes only in ./build Folder OR package.json OR ./dist/js/demo.js OR package-lock.json OR ./dist/js/pages/ OR ./docs OR in any html files which are necessary for contribution
* Do not make changes in ./dist/css/ AND ./dist/js/ AND ./plugins Because it contains compiled files and do not include in PR (Pull Request)
* `npm run production` (compile css/js files and test all pages are perfectly working fine, before creating a pull request)
4. Create a pull request
## Online one-click setup for contributing
You can use Gitpod(an online IDE which is free for Open Source) for working on issues or making PRs (Pull Requests). With a single click it will launch a workspace and automatically:
- clone the `AdminLTE` repo.
- install the dependencies.
- run `npm run dev` to start the server.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/)

View File

@ -0,0 +1,32 @@
---
name: Bug report for AdminLTE v3.x
about: Create a report to help us improve AdminLTE v3.x
title: "[BUG]"
labels: type:bug, version:3.1.x
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- AdminLTE Version: [e.g. v3.0.0]
- Operating System: [e.g. macOS Catalina]
- Browser (Version): [e.g. Chrome (Latest)]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request for AdminLTE v4.x
about: Suggest an idea for this project
title: "[FEATURE]"
labels: type:enhancement, version:4.x
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,5 @@
name: "CodeQL config"
paths-ignore:
- docs/assets/plugins/
- plugins/

View File

@ -0,0 +1,40 @@
version: 2
updates:
# for master branch
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
day: monday
time: "03:00"
open-pull-requests-limit: 10
target-branch: "master"
labels:
- dependencies
- version:3.1.x
versioning-strategy: increase
rebase-strategy: disabled
- package-ecosystem: bundler
directory: "/docs/"
schedule:
interval: weekly
day: monday
time: "03:00"
open-pull-requests-limit: 10
versioning-strategy: increase
rebase-strategy: disabled
# for v4-dev branch
- package-ecosystem: npm
directory: "/"
schedule:
interval: weekly
day: tuesday
time: "03:00"
open-pull-requests-limit: 10
target-branch: "v4-dev"
labels:
- dependencies
- version:4.x
versioning-strategy: increase
rebase-strategy: disabled

View File

@ -0,0 +1,63 @@
name: CI
on:
push:
branches:
- master
- v4-dev
pull_request:
branches:
- "**"
env:
FORCE_COLOR: 2
jobs:
run:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
node:
- "14.x"
- "16.x"
os:
- "ubuntu-latest"
- "macos-latest"
- "windows-latest"
steps:
- name: Clone repository
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}
- name: Get npm cache directory
id: npm-cache
run: |
echo "::set-output name=dir::$(npm config get cache)"
- name: Set up npm cache
uses: actions/cache@v2
with:
path: ${{ steps.npm-cache.outputs.dir }}
key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}}
restore-keys: |
${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ matrix.node }}-
- name: Install npm dependencies
run: npm ci
- name: Build files
run: npm run compile
- name: Run bundlewatch
run: npm run bundlewatch
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.node, '16')
env:
BUNDLEWATCH_GITHUB_TOKEN: "${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}"

View File

@ -0,0 +1,36 @@
name: "CodeQL"
on:
push:
branches:
- master
- v4-dev
- "!dependabot/**"
pull_request:
# The branches below must be a subset of the branches above
branches:
- master
schedule:
- cron: "0 0 * * 0"
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: "javascript"
config-file: ./.github/codeql/codeql-config.yml
- name: Autobuild
uses: github/codeql-action/autobuild@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@ -0,0 +1,60 @@
name: Docs
on:
push:
branches:
- master
- v4-dev
pull_request:
branches:
- "**"
env:
FORCE_COLOR: 2
NODE: 16.x
RUBY: 2.7
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: "${{ env.NODE }}"
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "${{ env.RUBY }}"
bundler-cache: true
working-directory: docs
- name: Version info
run: |
ruby --version
gem --version
bundle --version
java -version
- name: Set up npm cache
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}}
restore-keys: |
${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ env.NODE }}-
- name: Install npm dependencies
run: npm ci
- name: Build docs
run: npm run docs-compile
- name: Run HTML validator
run: npm run docs-lint

View File

@ -0,0 +1,42 @@
name: Lint
on:
push:
branches:
- master
- v4-dev
pull_request:
branches:
- "**"
env:
FORCE_COLOR: 2
NODE: 16.x
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: "${{ env.NODE }}"
- name: Set up npm cache
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}}
restore-keys: |
${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ env.NODE }}-
- name: Install npm dependencies
run: npm ci
- name: Run lint
run: npm run lint

71
static_files/AdminLTE-3.2.0/.gitignore vendored Normal file
View File

@ -0,0 +1,71 @@
# System / Log files
*.DS_Store
*.log
# Archives
*.zip
# Sass Cache
.sass-cache
# Project files
.idea
nbproject
nbproject/private
.vscode/
.vs/
# Node / Bower
node_modules/
bower_components/
# Plugins
/plugins/**/*.html
/plugins/**/*.less
/plugins/**/*.md
/plugins/**/*.scss
/plugins/**/*.ts
/plugins/**/bower.json
/plugins/**/package.json
/plugins/**/webpack.config.js
/plugins/**/demo/
/plugins/**/demos/
/plugins/**/dev/
/plugins/**/example/
/plugins/**/examples/
/plugins/**/less/
/plugins/**/test/
/plugins/**/tests/
/plugins/daterangepicker/website/
/plugins/daterangepicker/drp.png
/plugins/daterangepicker/moment.min.js
/plugins/daterangepicker/package.js
/plugins/daterangepicker/website.css
/plugins/daterangepicker/website.js
/plugins/jquery-ui/AUTHORS.txt
/plugins/jquery-ui/external/jquery/jquery.js
/plugins/inputmask/bindings/
/plugins/flot/plugins/jquery*.js
!/plugins/flot/plugins/jquery.flot.*.js
!/plugins/**/LICENSE.md
!/plugins/**/LICENSE.txt
!/plugins/**/license.md
!/plugins/**/license.txt
!/plugins/**/LICENSE
!/plugins/**/license
!/plugins/**/COPYING
# Docs
/docs/_site/
/docs/vendor/
/docs/.bundle/
/docs_html/
.jekyll-cache/
.jekyll-metadata
# ETC
TODO
test.html
ad.js
/.cache/

View File

@ -0,0 +1,6 @@
tasks:
- init: npm install
command: npm run dev
ports:
- port: 3000
onOpen: open-preview

View File

@ -0,0 +1,15 @@
# https://lgtm.com/help/lgtm/customizing-file-classification
path_classifiers:
plugins:
- plugins/
extraction:
javascript:
# https://lgtm.com/help/lgtm/javascript-extraction#customizing-index
# The `index` step extracts information from the files in the codebase.
index:
# Specify a list of files and folders to exclude from extraction.
exclude:
- bower_components/
- docs/assets/js/plugins/
- plugins/

View File

@ -0,0 +1,6 @@
/docs/
/docs_html/
/plugins/*
!/plugins/flot-old/
/.github/
/.lgtm.yml

View File

@ -0,0 +1,6 @@
**/*.html
**/*.md
**/*.min.css
**/dist/
**/docs_html/
**/plugins/

View File

@ -0,0 +1,16 @@
{
"extends": [
"stylelint-config-twbs-bootstrap/scss"
],
"rules": {
"declaration-no-important": null,
"order/properties-order": null,
"selector-max-class": null,
"selector-max-combinators": null,
"selector-max-compound-selectors": null,
"selector-max-id": null,
"selector-max-specificity": null,
"selector-max-type": null,
"selector-no-qualifying-type": null
}
}

View File

@ -0,0 +1,43 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at https://colorlib.com/wp/contact-us/. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct/>

View File

@ -0,0 +1,12 @@
FROM node:14
WORKDIR /code
COPY package.json /code/package.json
COPY package-lock.json /code/package-lock.json
RUN npm install
COPY . /code
CMD ["npm", "run", "dev"]

View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014-2021 ColorlibHQ
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,105 @@
# [AdminLTE - Bootstrap 4 Admin Dashboard](https://adminlte.io)
[![npm version](https://img.shields.io/npm/v/admin-lte/latest.svg)](https://www.npmjs.com/package/admin-lte)
[![Packagist](https://img.shields.io/packagist/v/almasaeed2010/adminlte.svg)](https://packagist.org/packages/almasaeed2010/adminlte)
[![cdn version](https://data.jsdelivr.com/v1/package/npm/admin-lte/badge)](https://www.jsdelivr.com/package/npm/admin-lte)
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/from-referrer/)
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/ColorlibHQ/AdminLTE)
[![Discord Invite](https://img.shields.io/badge/discord-join%20now-green)](https://discord.gg/jfdvjwFqfz)
**AdminLTE** is a fully responsive administration template. Based on **[Bootstrap 4.6](https://getbootstrap.com/)** framework and also the JS/jQuery plugin.
Highly customizable and easy to use. Fits many screen resolutions from small mobile devices to large desktops.
**Preview on [AdminLTE.io](https://adminlte.io/themes/v3)**
## Looking for Premium Templates?
AdminLTE.io just opened a new premium templates page. Hand picked to ensure the best quality and the most affordable
prices. Visit <https://adminlte.io/premium> for more information.
!["AdminLTE Presentation"](https://adminlte.io/AdminLTE3.png "AdminLTE Presentation")
**AdminLTE** has been carefully coded with clear comments in all of its JS, SCSS and HTML files.
SCSS has been used to increase code customizability.
## Quick start
There are multiple ways to install AdminLTE.
### Download & Changelog:
Always Recommended to download from GitHub latest release [AdminLTE 3](https://github.com/ColorlibHQ/AdminLTE/releases/latest) for bug free and latest features.\
Visit the [releases](https://github.com/ColorlibHQ/AdminLTE/releases) page to view the changelog.\
Legacy Releases are [AdminLTE 2](https://github.com/ColorlibHQ/AdminLTE/releases/tag/v2.4.18) / [AdminLTE 1](https://github.com/ColorlibHQ/AdminLTE/releases/tag/1.3.1).
## Stable release
### Grab from [jsdelivr](https://www.jsdelivr.com/package/npm/admin-lte) CDN:
_**Important Note**: You needed to add separately cdn links for plugins in your project._
```html
<script src="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/js/adminlte.min.js"></script>
```
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/admin-lte@3.2/dist/css/adminlte.min.css">
```
### Using The Command Line:
_**Important Note**: To install it via npm/Yarn, you need at least Node.js 14 or higher._
#### Via npm
```bash
npm install admin-lte@^3.2 --save
```
#### Via Yarn
```bash
yarn add admin-lte@^3.2
```
#### Via Composer
```bash
composer require "almasaeed2010/adminlte=~3.2"
```
#### Via Git
```bash
git clone https://github.com/ColorlibHQ/AdminLTE.git
```
## Documentation
Visit the [online documentation](https://adminlte.io/docs/3.2/) for the most
updated guide. Information will be added on a weekly basis.
## Browsers support
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari-ios/safari-ios_48x48.png" alt="iOS Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>iOS Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/samsung-internet/samsung-internet_48x48.png" alt="Samsung" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Samsung | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/vivaldi/vivaldi_48x48.png" alt="Vivaldi" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Vivaldi | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Electron |
| --------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions| last 2 versions| last 2 versions| last 2 versions| last 2 versions
## Light Mode (Only Dark Mode Removed)
You can use light-mode-only version, if you are not using dark mode and also file size less without dark-mode.
File Location `./dist/css/alt/adminlte.light.css`
## Compile dist files
To compile the dist files you need Node.js/npm, clone/download the repo then:
1. `npm install` (install npm deps)
2. _Optional:_ `npm run dev` (developer mode, autocompile with browsersync support for live demo)
3. `npm run production` (compile css/js files)
## Contributing
Please read through our [contributing guidelines](https://github.com/ColorlibHQ/AdminLTE/tree/master/.github/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development.
Editor preferences are available in the [editor config](https://github.com/twbs/bootstrap/blob/main/.editorconfig) for easy use in common text editors. Read more and download plugins at <https://editorconfig.org/>.
## License
AdminLTE is an open source project by [AdminLTE.io](https://adminlte.io) that is licensed under [MIT](https://opensource.org/licenses/MIT).
AdminLTE.io reserves the right to change the license of future releases.
## Image Credits
- [Pixeden](http://www.pixeden.com/psd-web-elements/flat-responsive-showcase-psd)
- [Graphicsfuel](https://www.graphicsfuel.com/2013/02/13-high-resolution-blur-backgrounds/)
- [Pickaface](https://pickaface.net/)
- [Unsplash](https://unsplash.com/)
- [Uifaces](http://uifaces.com/)

View File

@ -0,0 +1,15 @@
{
"env": {
"browser": false,
"node": true
},
"parserOptions": {
"sourceType": "script"
},
"extends": "../../.eslintrc.json",
"rules": {
"no-console": "off",
"strict": "error",
"unicorn/prefer-module": "off"
}
}

View File

@ -0,0 +1,14 @@
'use strict'
module.exports = {
map: {
inline: false,
annotation: true,
sourcesContent: true
},
plugins: [
require('autoprefixer')({
cascade: false
})
]
}

View File

@ -0,0 +1,32 @@
'use strict'
const { babel } = require('@rollup/plugin-babel')
const pkg = require('../../package')
const year = new Date().getFullYear()
const banner = `/*!
* AdminLTE v${pkg.version} (${pkg.homepage})
* Copyright 2014-${year} ${pkg.author}
* Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
*/`
module.exports = {
input: 'build/js/AdminLTE.js',
output: {
banner,
file: 'dist/js/adminlte.js',
format: 'umd',
globals: {
jquery: 'jQuery'
},
name: 'adminlte'
},
external: ['jquery'],
plugins: [
babel({
exclude: 'node_modules/**',
// Include the helpers in the bundle, at most one copy of each
babelHelpers: 'bundled'
})
]
}

View File

@ -0,0 +1,33 @@
import CardRefresh from './CardRefresh'
import CardWidget from './CardWidget'
import ControlSidebar from './ControlSidebar'
import DirectChat from './DirectChat'
import Dropdown from './Dropdown'
import ExpandableTable from './ExpandableTable'
import Fullscreen from './Fullscreen'
import IFrame from './IFrame'
import Layout from './Layout'
import PushMenu from './PushMenu'
import SidebarSearch from './SidebarSearch'
import NavbarSearch from './NavbarSearch'
import Toasts from './Toasts'
import TodoList from './TodoList'
import Treeview from './Treeview'
export {
CardRefresh,
CardWidget,
ControlSidebar,
DirectChat,
Dropdown,
ExpandableTable,
Fullscreen,
IFrame,
Layout,
PushMenu,
SidebarSearch,
NavbarSearch,
Toasts,
TodoList,
Treeview
}

View File

@ -0,0 +1,166 @@
/**
* --------------------------------------------
* AdminLTE CardRefresh.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'CardRefresh'
const DATA_KEY = 'lte.cardrefresh'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_LOADED = `loaded${EVENT_KEY}`
const EVENT_OVERLAY_ADDED = `overlay.added${EVENT_KEY}`
const EVENT_OVERLAY_REMOVED = `overlay.removed${EVENT_KEY}`
const CLASS_NAME_CARD = 'card'
const SELECTOR_CARD = `.${CLASS_NAME_CARD}`
const SELECTOR_DATA_REFRESH = '[data-card-widget="card-refresh"]'
const Default = {
source: '',
sourceSelector: '',
params: {},
trigger: SELECTOR_DATA_REFRESH,
content: '.card-body',
loadInContent: true,
loadOnInit: true,
loadErrorTemplate: true,
responseType: '',
overlayTemplate: '<div class="overlay"><i class="fas fa-2x fa-sync-alt fa-spin"></i></div>',
errorTemplate: '<span class="text-danger"></span>',
onLoadStart() {},
onLoadDone(response) {
return response
},
onLoadFail(_jqXHR, _textStatus, _errorThrown) {}
}
class CardRefresh {
constructor(element, settings) {
this._element = element
this._parent = element.parents(SELECTOR_CARD).first()
this._settings = $.extend({}, Default, settings)
this._overlay = $(this._settings.overlayTemplate)
if (element.hasClass(CLASS_NAME_CARD)) {
this._parent = element
}
if (this._settings.source === '') {
throw new Error('Source url was not defined. Please specify a url in your CardRefresh source option.')
}
}
load() {
this._addOverlay()
this._settings.onLoadStart.call($(this))
$.get(this._settings.source, this._settings.params, response => {
if (this._settings.loadInContent) {
if (this._settings.sourceSelector !== '') {
response = $(response).find(this._settings.sourceSelector).html()
}
this._parent.find(this._settings.content).html(response)
}
this._settings.onLoadDone.call($(this), response)
this._removeOverlay()
}, this._settings.responseType !== '' && this._settings.responseType)
.fail((jqXHR, textStatus, errorThrown) => {
this._removeOverlay()
if (this._settings.loadErrorTemplate) {
const msg = $(this._settings.errorTemplate).text(errorThrown)
this._parent.find(this._settings.content).empty().append(msg)
}
this._settings.onLoadFail.call($(this), jqXHR, textStatus, errorThrown)
})
$(this._element).trigger($.Event(EVENT_LOADED))
}
_addOverlay() {
this._parent.append(this._overlay)
$(this._element).trigger($.Event(EVENT_OVERLAY_ADDED))
}
_removeOverlay() {
this._parent.find(this._overlay).remove()
$(this._element).trigger($.Event(EVENT_OVERLAY_REMOVED))
}
// Private
_init() {
$(this).find(this._settings.trigger).on('click', () => {
this.load()
})
if (this._settings.loadOnInit) {
this.load()
}
}
// Static
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (!data) {
data = new CardRefresh($(this), _options)
$(this).data(DATA_KEY, typeof config === 'string' ? data : config)
}
if (typeof config === 'string' && /load/.test(config)) {
data[config]()
} else {
data._init($(this))
}
}
}
/**
* Data API
* ====================================================
*/
$(document).on('click', SELECTOR_DATA_REFRESH, function (event) {
if (event) {
event.preventDefault()
}
CardRefresh._jQueryInterface.call($(this), 'load')
})
$(() => {
$(SELECTOR_DATA_REFRESH).each(function () {
CardRefresh._jQueryInterface.call($(this))
})
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = CardRefresh._jQueryInterface
$.fn[NAME].Constructor = CardRefresh
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return CardRefresh._jQueryInterface
}
export default CardRefresh

View File

@ -0,0 +1,238 @@
/**
* --------------------------------------------
* AdminLTE CardWidget.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'CardWidget'
const DATA_KEY = 'lte.cardwidget'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_EXPANDED = `expanded${EVENT_KEY}`
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
const EVENT_MAXIMIZED = `maximized${EVENT_KEY}`
const EVENT_MINIMIZED = `minimized${EVENT_KEY}`
const EVENT_REMOVED = `removed${EVENT_KEY}`
const CLASS_NAME_CARD = 'card'
const CLASS_NAME_COLLAPSED = 'collapsed-card'
const CLASS_NAME_COLLAPSING = 'collapsing-card'
const CLASS_NAME_EXPANDING = 'expanding-card'
const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed'
const CLASS_NAME_MAXIMIZED = 'maximized-card'
const SELECTOR_DATA_REMOVE = '[data-card-widget="remove"]'
const SELECTOR_DATA_COLLAPSE = '[data-card-widget="collapse"]'
const SELECTOR_DATA_MAXIMIZE = '[data-card-widget="maximize"]'
const SELECTOR_CARD = `.${CLASS_NAME_CARD}`
const SELECTOR_CARD_HEADER = '.card-header'
const SELECTOR_CARD_BODY = '.card-body'
const SELECTOR_CARD_FOOTER = '.card-footer'
const Default = {
animationSpeed: 'normal',
collapseTrigger: SELECTOR_DATA_COLLAPSE,
removeTrigger: SELECTOR_DATA_REMOVE,
maximizeTrigger: SELECTOR_DATA_MAXIMIZE,
collapseIcon: 'fa-minus',
expandIcon: 'fa-plus',
maximizeIcon: 'fa-expand',
minimizeIcon: 'fa-compress'
}
class CardWidget {
constructor(element, settings) {
this._element = element
this._parent = element.parents(SELECTOR_CARD).first()
if (element.hasClass(CLASS_NAME_CARD)) {
this._parent = element
}
this._settings = $.extend({}, Default, settings)
}
collapse() {
this._parent.addClass(CLASS_NAME_COLLAPSING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
.slideUp(this._settings.animationSpeed, () => {
this._parent.addClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_COLLAPSING)
})
this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.collapseIcon}`)
.addClass(this._settings.expandIcon)
.removeClass(this._settings.collapseIcon)
this._element.trigger($.Event(EVENT_COLLAPSED), this._parent)
}
expand() {
this._parent.addClass(CLASS_NAME_EXPANDING).children(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
.slideDown(this._settings.animationSpeed, () => {
this._parent.removeClass(CLASS_NAME_COLLAPSED).removeClass(CLASS_NAME_EXPANDING)
})
this._parent.find(`> ${SELECTOR_CARD_HEADER} ${this._settings.collapseTrigger} .${this._settings.expandIcon}`)
.addClass(this._settings.collapseIcon)
.removeClass(this._settings.expandIcon)
this._element.trigger($.Event(EVENT_EXPANDED), this._parent)
}
remove() {
this._parent.slideUp()
this._element.trigger($.Event(EVENT_REMOVED), this._parent)
}
toggle() {
if (this._parent.hasClass(CLASS_NAME_COLLAPSED)) {
this.expand()
return
}
this.collapse()
}
maximize() {
this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.maximizeIcon}`)
.addClass(this._settings.minimizeIcon)
.removeClass(this._settings.maximizeIcon)
this._parent.css({
height: this._parent.height(),
width: this._parent.width(),
transition: 'all .15s'
}).delay(150).queue(function () {
const $element = $(this)
$element.addClass(CLASS_NAME_MAXIMIZED)
$('html').addClass(CLASS_NAME_MAXIMIZED)
if ($element.hasClass(CLASS_NAME_COLLAPSED)) {
$element.addClass(CLASS_NAME_WAS_COLLAPSED)
}
$element.dequeue()
})
this._element.trigger($.Event(EVENT_MAXIMIZED), this._parent)
}
minimize() {
this._parent.find(`${this._settings.maximizeTrigger} .${this._settings.minimizeIcon}`)
.addClass(this._settings.maximizeIcon)
.removeClass(this._settings.minimizeIcon)
this._parent.css('cssText', `height: ${this._parent[0].style.height} !important; width: ${this._parent[0].style.width} !important; transition: all .15s;`
).delay(10).queue(function () {
const $element = $(this)
$element.removeClass(CLASS_NAME_MAXIMIZED)
$('html').removeClass(CLASS_NAME_MAXIMIZED)
$element.css({
height: 'inherit',
width: 'inherit'
})
if ($element.hasClass(CLASS_NAME_WAS_COLLAPSED)) {
$element.removeClass(CLASS_NAME_WAS_COLLAPSED)
}
$element.dequeue()
})
this._element.trigger($.Event(EVENT_MINIMIZED), this._parent)
}
toggleMaximize() {
if (this._parent.hasClass(CLASS_NAME_MAXIMIZED)) {
this.minimize()
return
}
this.maximize()
}
// Private
_init(card) {
this._parent = card
$(this).find(this._settings.collapseTrigger).click(() => {
this.toggle()
})
$(this).find(this._settings.maximizeTrigger).click(() => {
this.toggleMaximize()
})
$(this).find(this._settings.removeTrigger).click(() => {
this.remove()
})
}
// Static
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (!data) {
data = new CardWidget($(this), _options)
$(this).data(DATA_KEY, typeof config === 'string' ? data : config)
}
if (typeof config === 'string' && /collapse|expand|remove|toggle|maximize|minimize|toggleMaximize/.test(config)) {
data[config]()
} else if (typeof config === 'object') {
data._init($(this))
}
}
}
/**
* Data API
* ====================================================
*/
$(document).on('click', SELECTOR_DATA_COLLAPSE, function (event) {
if (event) {
event.preventDefault()
}
CardWidget._jQueryInterface.call($(this), 'toggle')
})
$(document).on('click', SELECTOR_DATA_REMOVE, function (event) {
if (event) {
event.preventDefault()
}
CardWidget._jQueryInterface.call($(this), 'remove')
})
$(document).on('click', SELECTOR_DATA_MAXIMIZE, function (event) {
if (event) {
event.preventDefault()
}
CardWidget._jQueryInterface.call($(this), 'toggleMaximize')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = CardWidget._jQueryInterface
$.fn[NAME].Constructor = CardWidget
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return CardWidget._jQueryInterface
}
export default CardWidget

View File

@ -0,0 +1,336 @@
/**
* --------------------------------------------
* AdminLTE ControlSidebar.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'ControlSidebar'
const DATA_KEY = 'lte.controlsidebar'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
const EVENT_COLLAPSED_DONE = `collapsed-done${EVENT_KEY}`
const EVENT_EXPANDED = `expanded${EVENT_KEY}`
const SELECTOR_CONTROL_SIDEBAR = '.control-sidebar'
const SELECTOR_CONTROL_SIDEBAR_CONTENT = '.control-sidebar-content'
const SELECTOR_DATA_TOGGLE = '[data-widget="control-sidebar"]'
const SELECTOR_HEADER = '.main-header'
const SELECTOR_FOOTER = '.main-footer'
const CLASS_NAME_CONTROL_SIDEBAR_ANIMATE = 'control-sidebar-animate'
const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open'
const CLASS_NAME_CONTROL_SIDEBAR_SLIDE = 'control-sidebar-slide-open'
const CLASS_NAME_LAYOUT_FIXED = 'layout-fixed'
const CLASS_NAME_NAVBAR_FIXED = 'layout-navbar-fixed'
const CLASS_NAME_NAVBAR_SM_FIXED = 'layout-sm-navbar-fixed'
const CLASS_NAME_NAVBAR_MD_FIXED = 'layout-md-navbar-fixed'
const CLASS_NAME_NAVBAR_LG_FIXED = 'layout-lg-navbar-fixed'
const CLASS_NAME_NAVBAR_XL_FIXED = 'layout-xl-navbar-fixed'
const CLASS_NAME_FOOTER_FIXED = 'layout-footer-fixed'
const CLASS_NAME_FOOTER_SM_FIXED = 'layout-sm-footer-fixed'
const CLASS_NAME_FOOTER_MD_FIXED = 'layout-md-footer-fixed'
const CLASS_NAME_FOOTER_LG_FIXED = 'layout-lg-footer-fixed'
const CLASS_NAME_FOOTER_XL_FIXED = 'layout-xl-footer-fixed'
const Default = {
controlsidebarSlide: true,
scrollbarTheme: 'os-theme-light',
scrollbarAutoHide: 'l',
target: SELECTOR_CONTROL_SIDEBAR,
animationSpeed: 300
}
/**
* Class Definition
* ====================================================
*/
class ControlSidebar {
constructor(element, config) {
this._element = element
this._config = config
}
// Public
collapse() {
const $body = $('body')
const $html = $('html')
// Show the control sidebar
if (this._config.controlsidebarSlide) {
$html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
$(SELECTOR_CONTROL_SIDEBAR).hide()
$html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
})
} else {
$body.removeClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
}
$(this._element).trigger($.Event(EVENT_COLLAPSED))
setTimeout(() => {
$(this._element).trigger($.Event(EVENT_COLLAPSED_DONE))
}, this._config.animationSpeed)
}
show(toggle = false) {
const $body = $('body')
const $html = $('html')
if (toggle) {
$(SELECTOR_CONTROL_SIDEBAR).hide()
}
// Collapse the control sidebar
if (this._config.controlsidebarSlide) {
$html.addClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this._config.target).show().delay(10).queue(function () {
$body.addClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE).delay(300).queue(function () {
$html.removeClass(CLASS_NAME_CONTROL_SIDEBAR_ANIMATE)
$(this).dequeue()
})
$(this).dequeue()
})
} else {
$body.addClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN)
}
this._fixHeight()
this._fixScrollHeight()
$(this._element).trigger($.Event(EVENT_EXPANDED))
}
toggle() {
const $body = $('body')
const { target } = this._config
const notVisible = !$(target).is(':visible')
const shouldClose = ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE))
const shouldToggle = notVisible && ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE))
if (notVisible || shouldToggle) {
// Open the control sidebar
this.show(notVisible)
} else if (shouldClose) {
// Close the control sidebar
this.collapse()
}
}
// Private
_init() {
const $body = $('body')
const shouldNotHideAll = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
if (shouldNotHideAll) {
$(SELECTOR_CONTROL_SIDEBAR).not(this._config.target).hide()
$(this._config.target).css('display', 'block')
} else {
$(SELECTOR_CONTROL_SIDEBAR).hide()
}
this._fixHeight()
this._fixScrollHeight()
$(window).resize(() => {
this._fixHeight()
this._fixScrollHeight()
})
$(window).scroll(() => {
const $body = $('body')
const shouldFixHeight = $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) ||
$body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE)
if (shouldFixHeight) {
this._fixScrollHeight()
}
})
}
_isNavbarFixed() {
const $body = $('body')
return (
$body.hasClass(CLASS_NAME_NAVBAR_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_SM_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_MD_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_LG_FIXED) ||
$body.hasClass(CLASS_NAME_NAVBAR_XL_FIXED)
)
}
_isFooterFixed() {
const $body = $('body')
return (
$body.hasClass(CLASS_NAME_FOOTER_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_SM_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_MD_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_LG_FIXED) ||
$body.hasClass(CLASS_NAME_FOOTER_XL_FIXED)
)
}
_fixScrollHeight() {
const $body = $('body')
const $controlSidebar = $(this._config.target)
if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
return
}
const heights = {
scroll: $(document).height(),
window: $(window).height(),
header: $(SELECTOR_HEADER).outerHeight(),
footer: $(SELECTOR_FOOTER).outerHeight()
}
const positions = {
bottom: Math.abs((heights.window + $(window).scrollTop()) - heights.scroll),
top: $(window).scrollTop()
}
const navbarFixed = this._isNavbarFixed() && $(SELECTOR_HEADER).css('position') === 'fixed'
const footerFixed = this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed'
const $controlsidebarContent = $(`${this._config.target}, ${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)
if (positions.top === 0 && positions.bottom === 0) {
$controlSidebar.css({
bottom: heights.footer,
top: heights.header
})
$controlsidebarContent.css('height', heights.window - (heights.header + heights.footer))
} else if (positions.bottom <= heights.footer) {
if (footerFixed === false) {
const top = heights.header - positions.top
$controlSidebar.css('bottom', heights.footer - positions.bottom).css('top', top >= 0 ? top : 0)
$controlsidebarContent.css('height', heights.window - (heights.footer - positions.bottom))
} else {
$controlSidebar.css('bottom', heights.footer)
}
} else if (positions.top <= heights.header) {
if (navbarFixed === false) {
$controlSidebar.css('top', heights.header - positions.top)
$controlsidebarContent.css('height', heights.window - (heights.header - positions.top))
} else {
$controlSidebar.css('top', heights.header)
}
} else if (navbarFixed === false) {
$controlSidebar.css('top', 0)
$controlsidebarContent.css('height', heights.window)
} else {
$controlSidebar.css('top', heights.header)
}
if (footerFixed && navbarFixed) {
$controlsidebarContent.css('height', '100%')
$controlSidebar.css('height', '')
} else if (footerFixed || navbarFixed) {
$controlsidebarContent.css('height', '100%')
$controlsidebarContent.css('height', '')
}
}
_fixHeight() {
const $body = $('body')
const $controlSidebar = $(`${this._config.target} ${SELECTOR_CONTROL_SIDEBAR_CONTENT}`)
if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
$controlSidebar.attr('style', '')
return
}
const heights = {
window: $(window).height(),
header: $(SELECTOR_HEADER).outerHeight(),
footer: $(SELECTOR_FOOTER).outerHeight()
}
let sidebarHeight = heights.window - heights.header
if (this._isFooterFixed() && $(SELECTOR_FOOTER).css('position') === 'fixed') {
sidebarHeight = heights.window - heights.header - heights.footer
}
$controlSidebar.css('height', sidebarHeight)
if (typeof $.fn.overlayScrollbars !== 'undefined') {
$controlSidebar.overlayScrollbars({
className: this._config.scrollbarTheme,
sizeAutoCapable: true,
scrollbars: {
autoHide: this._config.scrollbarAutoHide,
clickScrolling: true
}
})
}
}
// Static
static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (!data) {
data = new ControlSidebar(this, _options)
$(this).data(DATA_KEY, data)
}
if (data[operation] === 'undefined') {
throw new Error(`${operation} is not a function`)
}
data[operation]()
})
}
}
/**
*
* Data Api implementation
* ====================================================
*/
$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault()
ControlSidebar._jQueryInterface.call($(this), 'toggle')
})
$(document).ready(() => {
ControlSidebar._jQueryInterface.call($(SELECTOR_DATA_TOGGLE), '_init')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = ControlSidebar._jQueryInterface
$.fn[NAME].Constructor = ControlSidebar
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return ControlSidebar._jQueryInterface
}
export default ControlSidebar

View File

@ -0,0 +1,84 @@
/**
* --------------------------------------------
* AdminLTE DirectChat.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'DirectChat'
const DATA_KEY = 'lte.directchat'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_TOGGLED = `toggled${EVENT_KEY}`
const SELECTOR_DATA_TOGGLE = '[data-widget="chat-pane-toggle"]'
const SELECTOR_DIRECT_CHAT = '.direct-chat'
const CLASS_NAME_DIRECT_CHAT_OPEN = 'direct-chat-contacts-open'
/**
* Class Definition
* ====================================================
*/
class DirectChat {
constructor(element) {
this._element = element
}
toggle() {
$(this._element).parents(SELECTOR_DIRECT_CHAT).first().toggleClass(CLASS_NAME_DIRECT_CHAT_OPEN)
$(this._element).trigger($.Event(EVENT_TOGGLED))
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
if (!data) {
data = new DirectChat($(this))
$(this).data(DATA_KEY, data)
}
data[config]()
})
}
}
/**
*
* Data Api implementation
* ====================================================
*/
$(document).on('click', SELECTOR_DATA_TOGGLE, function (event) {
if (event) {
event.preventDefault()
}
DirectChat._jQueryInterface.call($(this), 'toggle')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = DirectChat._jQueryInterface
$.fn[NAME].Constructor = DirectChat
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return DirectChat._jQueryInterface
}
export default DirectChat

View File

@ -0,0 +1,146 @@
/**
* --------------------------------------------
* AdminLTE Dropdown.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'Dropdown'
const DATA_KEY = 'lte.dropdown'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const SELECTOR_NAVBAR = '.navbar'
const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'
const SELECTOR_DROPDOWN_MENU_ACTIVE = '.dropdown-menu.show'
const SELECTOR_DROPDOWN_TOGGLE = '[data-toggle="dropdown"]'
const CLASS_NAME_DROPDOWN_RIGHT = 'dropdown-menu-right'
const CLASS_NAME_DROPDOWN_SUBMENU = 'dropdown-submenu'
// TODO: this is unused; should be removed along with the extend?
const Default = {}
/**
* Class Definition
* ====================================================
*/
class Dropdown {
constructor(element, config) {
this._config = config
this._element = element
}
// Public
toggleSubmenu() {
this._element.siblings().show().toggleClass('show')
if (!this._element.next().hasClass('show')) {
this._element.parents(SELECTOR_DROPDOWN_MENU).first().find('.show').removeClass('show').hide()
}
this._element.parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', () => {
$('.dropdown-submenu .show').removeClass('show').hide()
})
}
fixPosition() {
const $element = $(SELECTOR_DROPDOWN_MENU_ACTIVE)
if ($element.length === 0) {
return
}
if ($element.hasClass(CLASS_NAME_DROPDOWN_RIGHT)) {
$element.css({
left: 'inherit',
right: 0
})
} else {
$element.css({
left: 0,
right: 'inherit'
})
}
const offset = $element.offset()
const width = $element.width()
const visiblePart = $(window).width() - offset.left
if (offset.left < 0) {
$element.css({
left: 'inherit',
right: offset.left - 5
})
} else if (visiblePart < width) {
$element.css({
left: 'inherit',
right: 0
})
}
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _config = $.extend({}, Default, $(this).data())
if (!data) {
data = new Dropdown($(this), _config)
$(this).data(DATA_KEY, data)
}
if (config === 'toggleSubmenu' || config === 'fixPosition') {
data[config]()
}
})
}
}
/**
* Data API
* ====================================================
*/
$(`${SELECTOR_DROPDOWN_MENU} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', function (event) {
event.preventDefault()
event.stopPropagation()
Dropdown._jQueryInterface.call($(this), 'toggleSubmenu')
})
$(`${SELECTOR_NAVBAR} ${SELECTOR_DROPDOWN_TOGGLE}`).on('click', event => {
event.preventDefault()
if ($(event.target).parent().hasClass(CLASS_NAME_DROPDOWN_SUBMENU)) {
return
}
setTimeout(function () {
Dropdown._jQueryInterface.call($(this), 'fixPosition')
}, 1)
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = Dropdown._jQueryInterface
$.fn[NAME].Constructor = Dropdown
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Dropdown._jQueryInterface
}
export default Dropdown

View File

@ -0,0 +1,124 @@
/**
* --------------------------------------------
* AdminLTE ExpandableTable.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'ExpandableTable'
const DATA_KEY = 'lte.expandableTable'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_EXPANDED = `expanded${EVENT_KEY}`
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
const SELECTOR_TABLE = '.expandable-table'
const SELECTOR_EXPANDABLE_BODY = '.expandable-body'
const SELECTOR_DATA_TOGGLE = '[data-widget="expandable-table"]'
const SELECTOR_ARIA_ATTR = 'aria-expanded'
/**
* Class Definition
* ====================================================
*/
class ExpandableTable {
constructor(element, options) {
this._options = options
this._element = element
}
// Public
init() {
$(SELECTOR_DATA_TOGGLE).each((_, $header) => {
const $type = $($header).attr(SELECTOR_ARIA_ATTR)
const $body = $($header).next(SELECTOR_EXPANDABLE_BODY).children().first().children()
if ($type === 'true') {
$body.show()
} else if ($type === 'false') {
$body.hide()
$body.parent().parent().addClass('d-none')
}
})
}
toggleRow() {
let $element = this._element
if ($element[0].nodeName !== 'TR') {
$element = $element.parent()
if ($element[0].nodeName !== 'TR') {
$element = $element.parent()
}
}
const time = 500
const $type = $element.attr(SELECTOR_ARIA_ATTR)
const $body = $element.next(SELECTOR_EXPANDABLE_BODY).children().first().children()
$body.stop()
if ($type === 'true') {
$body.slideUp(time, () => {
$element.next(SELECTOR_EXPANDABLE_BODY).addClass('d-none')
})
$element.attr(SELECTOR_ARIA_ATTR, 'false')
$element.trigger($.Event(EVENT_COLLAPSED))
} else if ($type === 'false') {
$element.next(SELECTOR_EXPANDABLE_BODY).removeClass('d-none')
$body.slideDown(time)
$element.attr(SELECTOR_ARIA_ATTR, 'true')
$element.trigger($.Event(EVENT_EXPANDED))
}
}
// Static
static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
if (!data) {
data = new ExpandableTable($(this))
$(this).data(DATA_KEY, data)
}
if (typeof operation === 'string' && /init|toggleRow/.test(operation)) {
data[operation]()
}
})
}
}
/**
* Data API
* ====================================================
*/
$(SELECTOR_TABLE).ready(function () {
ExpandableTable._jQueryInterface.call($(this), 'init')
})
$(document).on('click', SELECTOR_DATA_TOGGLE, function () {
ExpandableTable._jQueryInterface.call($(this), 'toggleRow')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = ExpandableTable._jQueryInterface
$.fn[NAME].Constructor = ExpandableTable
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return ExpandableTable._jQueryInterface
}
export default ExpandableTable

View File

@ -0,0 +1,130 @@
/**
* --------------------------------------------
* AdminLTE Fullscreen.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'Fullscreen'
const DATA_KEY = 'lte.fullscreen'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const SELECTOR_DATA_WIDGET = '[data-widget="fullscreen"]'
const SELECTOR_ICON = `${SELECTOR_DATA_WIDGET} i`
const EVENT_FULLSCREEN_CHANGE = 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange'
const Default = {
minimizeIcon: 'fa-compress-arrows-alt',
maximizeIcon: 'fa-expand-arrows-alt'
}
/**
* Class Definition
* ====================================================
*/
class Fullscreen {
constructor(_element, _options) {
this.element = _element
this.options = $.extend({}, Default, _options)
}
// Public
toggle() {
if (document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement) {
this.windowed()
} else {
this.fullscreen()
}
}
toggleIcon() {
if (document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement) {
$(SELECTOR_ICON).removeClass(this.options.maximizeIcon).addClass(this.options.minimizeIcon)
} else {
$(SELECTOR_ICON).removeClass(this.options.minimizeIcon).addClass(this.options.maximizeIcon)
}
}
fullscreen() {
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen()
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen()
} else if (document.documentElement.msRequestFullscreen) {
document.documentElement.msRequestFullscreen()
}
}
windowed() {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
}
// Static
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
if (!data) {
data = $(this).data()
}
const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new Fullscreen($(this), _options)
$(this).data(DATA_KEY, typeof config === 'object' ? config : data)
if (typeof config === 'string' && /toggle|toggleIcon|fullscreen|windowed/.test(config)) {
plugin[config]()
} else {
plugin.init()
}
}
}
/**
* Data API
* ====================================================
*/
$(document).on('click', SELECTOR_DATA_WIDGET, function () {
Fullscreen._jQueryInterface.call($(this), 'toggle')
})
$(document).on(EVENT_FULLSCREEN_CHANGE, () => {
Fullscreen._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggleIcon')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = Fullscreen._jQueryInterface
$.fn[NAME].Constructor = Fullscreen
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Fullscreen._jQueryInterface
}
export default Fullscreen

View File

@ -0,0 +1,460 @@
/**
* --------------------------------------------
* AdminLTE IFrame.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'IFrame'
const DATA_KEY = 'lte.iframe'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const SELECTOR_DATA_TOGGLE = '[data-widget="iframe"]'
const SELECTOR_DATA_TOGGLE_CLOSE = '[data-widget="iframe-close"]'
const SELECTOR_DATA_TOGGLE_SCROLL_LEFT = '[data-widget="iframe-scrollleft"]'
const SELECTOR_DATA_TOGGLE_SCROLL_RIGHT = '[data-widget="iframe-scrollright"]'
const SELECTOR_DATA_TOGGLE_FULLSCREEN = '[data-widget="iframe-fullscreen"]'
const SELECTOR_CONTENT_WRAPPER = '.content-wrapper'
const SELECTOR_CONTENT_IFRAME = `${SELECTOR_CONTENT_WRAPPER} iframe`
const SELECTOR_TAB_NAV = `${SELECTOR_CONTENT_WRAPPER}.iframe-mode .nav`
const SELECTOR_TAB_NAVBAR_NAV = `${SELECTOR_CONTENT_WRAPPER}.iframe-mode .navbar-nav`
const SELECTOR_TAB_NAVBAR_NAV_ITEM = `${SELECTOR_TAB_NAVBAR_NAV} .nav-item`
const SELECTOR_TAB_NAVBAR_NAV_LINK = `${SELECTOR_TAB_NAVBAR_NAV} .nav-link`
const SELECTOR_TAB_CONTENT = `${SELECTOR_CONTENT_WRAPPER}.iframe-mode .tab-content`
const SELECTOR_TAB_EMPTY = `${SELECTOR_TAB_CONTENT} .tab-empty`
const SELECTOR_TAB_LOADING = `${SELECTOR_TAB_CONTENT} .tab-loading`
const SELECTOR_TAB_PANE = `${SELECTOR_TAB_CONTENT} .tab-pane`
const SELECTOR_SIDEBAR_MENU_ITEM = '.main-sidebar .nav-item > a.nav-link'
const SELECTOR_SIDEBAR_SEARCH_ITEM = '.sidebar-search-results .list-group-item'
const SELECTOR_HEADER_MENU_ITEM = '.main-header .nav-item a.nav-link'
const SELECTOR_HEADER_DROPDOWN_ITEM = '.main-header a.dropdown-item'
const CLASS_NAME_IFRAME_MODE = 'iframe-mode'
const CLASS_NAME_FULLSCREEN_MODE = 'iframe-mode-fullscreen'
const Default = {
onTabClick(item) {
return item
},
onTabChanged(item) {
return item
},
onTabCreated(item) {
return item
},
autoIframeMode: true,
autoItemActive: true,
autoShowNewTab: true,
autoDarkMode: false,
allowDuplicates: false,
allowReload: true,
loadingScreen: true,
useNavbarItems: true,
scrollOffset: 40,
scrollBehaviorSwap: false,
iconMaximize: 'fa-expand',
iconMinimize: 'fa-compress'
}
/**
* Class Definition
* ====================================================
*/
class IFrame {
constructor(element, config) {
this._config = config
this._element = element
this._init()
}
// Public
onTabClick(item) {
this._config.onTabClick(item)
}
onTabChanged(item) {
this._config.onTabChanged(item)
}
onTabCreated(item) {
this._config.onTabCreated(item)
}
createTab(title, link, uniqueName, autoOpen) {
let tabId = `panel-${uniqueName}`
let navId = `tab-${uniqueName}`
if (this._config.allowDuplicates) {
tabId += `-${Math.floor(Math.random() * 1000)}`
navId += `-${Math.floor(Math.random() * 1000)}`
}
const newNavItem = `<li class="nav-item" role="presentation"><a href="#" class="btn-iframe-close" data-widget="iframe-close" data-type="only-this"><i class="fas fa-times"></i></a><a class="nav-link" data-toggle="row" id="${navId}" href="#${tabId}" role="tab" aria-controls="${tabId}" aria-selected="false">${title}</a></li>`
$(SELECTOR_TAB_NAVBAR_NAV).append(unescape(escape(newNavItem)))
const newTabItem = `<div class="tab-pane fade" id="${tabId}" role="tabpanel" aria-labelledby="${navId}"><iframe src="${link}"></iframe></div>`
$(SELECTOR_TAB_CONTENT).append(unescape(escape(newTabItem)))
if (autoOpen) {
if (this._config.loadingScreen) {
const $loadingScreen = $(SELECTOR_TAB_LOADING)
$loadingScreen.fadeIn()
$(`${tabId} iframe`).ready(() => {
if (typeof this._config.loadingScreen === 'number') {
this.switchTab(`#${navId}`)
setTimeout(() => {
$loadingScreen.fadeOut()
}, this._config.loadingScreen)
} else {
this.switchTab(`#${navId}`)
$loadingScreen.fadeOut()
}
})
} else {
this.switchTab(`#${navId}`)
}
}
this.onTabCreated($(`#${navId}`))
}
openTabSidebar(item, autoOpen = this._config.autoShowNewTab) {
let $item = $(item).clone()
if ($item.attr('href') === undefined) {
$item = $(item).parent('a').clone()
}
$item.find('.right, .search-path').remove()
let title = $item.find('p').text()
if (title === '') {
title = $item.text()
}
const link = $item.attr('href')
if (link === '#' || link === '' || link === undefined) {
return
}
const uniqueName = unescape(link).replace('./', '').replace(/["#&'./:=?[\]]/gi, '-').replace(/(--)/gi, '')
const navId = `tab-${uniqueName}`
if (!this._config.allowDuplicates && $(`#${navId}`).length > 0) {
return this.switchTab(`#${navId}`, this._config.allowReload)
}
if ((!this._config.allowDuplicates && $(`#${navId}`).length === 0) || this._config.allowDuplicates) {
this.createTab(title, link, uniqueName, autoOpen)
}
}
switchTab(item, reload = false) {
const $item = $(item)
const tabId = $item.attr('href')
$(SELECTOR_TAB_EMPTY).hide()
if (reload) {
const $loadingScreen = $(SELECTOR_TAB_LOADING)
if (this._config.loadingScreen) {
$loadingScreen.show(0, () => {
$(`${tabId} iframe`).attr('src', $(`${tabId} iframe`).attr('src')).ready(() => {
if (this._config.loadingScreen) {
if (typeof this._config.loadingScreen === 'number') {
setTimeout(() => {
$loadingScreen.fadeOut()
}, this._config.loadingScreen)
} else {
$loadingScreen.fadeOut()
}
}
})
})
} else {
$(`${tabId} iframe`).attr('src', $(`${tabId} iframe`).attr('src'))
}
}
$(`${SELECTOR_TAB_NAVBAR_NAV} .active`).tab('dispose').removeClass('active')
this._fixHeight()
$item.tab('show')
$item.parents('li').addClass('active')
this.onTabChanged($item)
if (this._config.autoItemActive) {
this._setItemActive($(`${tabId} iframe`).attr('src'))
}
}
removeActiveTab(type, element) {
if (type == 'all') {
$(SELECTOR_TAB_NAVBAR_NAV_ITEM).remove()
$(SELECTOR_TAB_PANE).remove()
$(SELECTOR_TAB_EMPTY).show()
} else if (type == 'all-other') {
$(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}:not(.active)`).remove()
$(`${SELECTOR_TAB_PANE}:not(.active)`).remove()
} else if (type == 'only-this') {
const $navClose = $(element)
const $navItem = $navClose.parent('.nav-item')
const $navItemParent = $navItem.parent()
const navItemIndex = $navItem.index()
const tabId = $navClose.siblings('.nav-link').attr('aria-controls')
$navItem.remove()
$(`#${tabId}`).remove()
if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) {
$(SELECTOR_TAB_EMPTY).show()
} else {
const prevNavItemIndex = navItemIndex - 1
this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link'))
}
} else {
const $navItem = $(`${SELECTOR_TAB_NAVBAR_NAV_ITEM}.active`)
const $navItemParent = $navItem.parent()
const navItemIndex = $navItem.index()
$navItem.remove()
$(`${SELECTOR_TAB_PANE}.active`).remove()
if ($(SELECTOR_TAB_CONTENT).children().length == $(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).length) {
$(SELECTOR_TAB_EMPTY).show()
} else {
const prevNavItemIndex = navItemIndex - 1
this.switchTab($navItemParent.children().eq(prevNavItemIndex).find('a.nav-link'))
}
}
}
toggleFullscreen() {
if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) {
$(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMinimize).addClass(this._config.iconMaximize)
$('body').removeClass(CLASS_NAME_FULLSCREEN_MODE)
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height('100%')
$(SELECTOR_CONTENT_WRAPPER).height('100%')
$(SELECTOR_CONTENT_IFRAME).height('100%')
} else {
$(`${SELECTOR_DATA_TOGGLE_FULLSCREEN} i`).removeClass(this._config.iconMaximize).addClass(this._config.iconMinimize)
$('body').addClass(CLASS_NAME_FULLSCREEN_MODE)
}
$(window).trigger('resize')
this._fixHeight(true)
}
// Private
_init() {
const usingDefTab = ($(SELECTOR_TAB_CONTENT).children().length > 2)
this._setupListeners()
this._fixHeight(true)
if (usingDefTab) {
const $el = $(`${SELECTOR_TAB_PANE}`).first()
// eslint-disable-next-line no-console
console.log($el)
const uniqueName = $el.attr('id').replace('panel-', '')
const navId = `#tab-${uniqueName}`
this.switchTab(navId, true)
}
}
_initFrameElement() {
if (window.frameElement && this._config.autoIframeMode) {
const $body = $('body')
$body.addClass(CLASS_NAME_IFRAME_MODE)
if (this._config.autoDarkMode) {
$body.addClass('dark-mode')
}
}
}
_navScroll(offset) {
const leftPos = $(SELECTOR_TAB_NAVBAR_NAV).scrollLeft()
$(SELECTOR_TAB_NAVBAR_NAV).animate({ scrollLeft: (leftPos + offset) }, 250, 'linear')
}
_setupListeners() {
$(window).on('resize', () => {
setTimeout(() => {
this._fixHeight()
}, 1)
})
if ($(SELECTOR_CONTENT_WRAPPER).hasClass(CLASS_NAME_IFRAME_MODE)) {
$(document).on('click', `${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_SIDEBAR_SEARCH_ITEM}`, e => {
e.preventDefault()
this.openTabSidebar(e.target)
})
if (this._config.useNavbarItems) {
$(document).on('click', `${SELECTOR_HEADER_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`, e => {
e.preventDefault()
this.openTabSidebar(e.target)
})
}
}
$(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => {
e.preventDefault()
this.onTabClick(e.target)
this.switchTab(e.target)
})
$(document).on('click', SELECTOR_TAB_NAVBAR_NAV_LINK, e => {
e.preventDefault()
this.onTabClick(e.target)
this.switchTab(e.target)
})
$(document).on('click', SELECTOR_DATA_TOGGLE_CLOSE, e => {
e.preventDefault()
let { target } = e
if (target.nodeName == 'I') {
target = e.target.offsetParent
}
this.removeActiveTab(target.attributes['data-type'] ? target.attributes['data-type'].nodeValue : null, target)
})
$(document).on('click', SELECTOR_DATA_TOGGLE_FULLSCREEN, e => {
e.preventDefault()
this.toggleFullscreen()
})
let mousedown = false
let mousedownInterval = null
$(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_LEFT, e => {
e.preventDefault()
clearInterval(mousedownInterval)
let { scrollOffset } = this._config
if (!this._config.scrollBehaviorSwap) {
scrollOffset = -scrollOffset
}
mousedown = true
this._navScroll(scrollOffset)
mousedownInterval = setInterval(() => {
this._navScroll(scrollOffset)
}, 250)
})
$(document).on('mousedown', SELECTOR_DATA_TOGGLE_SCROLL_RIGHT, e => {
e.preventDefault()
clearInterval(mousedownInterval)
let { scrollOffset } = this._config
if (this._config.scrollBehaviorSwap) {
scrollOffset = -scrollOffset
}
mousedown = true
this._navScroll(scrollOffset)
mousedownInterval = setInterval(() => {
this._navScroll(scrollOffset)
}, 250)
})
$(document).on('mouseup', () => {
if (mousedown) {
mousedown = false
clearInterval(mousedownInterval)
mousedownInterval = null
}
})
}
_setItemActive(href) {
$(`${SELECTOR_SIDEBAR_MENU_ITEM}, ${SELECTOR_HEADER_DROPDOWN_ITEM}`).removeClass('active')
$(SELECTOR_HEADER_MENU_ITEM).parent().removeClass('active')
const $headerMenuItem = $(`${SELECTOR_HEADER_MENU_ITEM}[href$="${href}"]`)
const $headerDropdownItem = $(`${SELECTOR_HEADER_DROPDOWN_ITEM}[href$="${href}"]`)
const $sidebarMenuItem = $(`${SELECTOR_SIDEBAR_MENU_ITEM}[href$="${href}"]`)
$headerMenuItem.each((i, e) => {
$(e).parent().addClass('active')
})
$headerDropdownItem.each((i, e) => {
$(e).addClass('active')
})
$sidebarMenuItem.each((i, e) => {
$(e).addClass('active')
$(e).parents('.nav-treeview').prevAll('.nav-link').addClass('active')
})
}
_fixHeight(tabEmpty = false) {
if ($('body').hasClass(CLASS_NAME_FULLSCREEN_MODE)) {
const windowHeight = $(window).height()
const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight()
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}, ${SELECTOR_CONTENT_IFRAME}`).height(windowHeight - navbarHeight)
$(SELECTOR_CONTENT_WRAPPER).height(windowHeight)
} else {
const contentWrapperHeight = parseFloat($(SELECTOR_CONTENT_WRAPPER).css('height'))
const navbarHeight = $(SELECTOR_TAB_NAV).outerHeight()
if (tabEmpty == true) {
setTimeout(() => {
$(`${SELECTOR_TAB_EMPTY}, ${SELECTOR_TAB_LOADING}`).height(contentWrapperHeight - navbarHeight)
}, 50)
} else {
$(SELECTOR_CONTENT_IFRAME).height(contentWrapperHeight - navbarHeight)
}
}
}
// Static
static _jQueryInterface(config) {
if ($(SELECTOR_DATA_TOGGLE).length > 0) {
let data = $(this).data(DATA_KEY)
if (!data) {
data = $(this).data()
}
const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
localStorage.setItem('AdminLTE:IFrame:Options', JSON.stringify(_options))
const plugin = new IFrame($(this), _options)
$(this).data(DATA_KEY, typeof config === 'object' ? config : data)
if (typeof config === 'string' && /createTab|openTabSidebar|switchTab|removeActiveTab/.test(config)) {
plugin[config]()
}
} else {
new IFrame($(this), JSON.parse(localStorage.getItem('AdminLTE:IFrame:Options')))._initFrameElement()
}
}
}
/**
* Data API
* ====================================================
*/
$(window).on('load', () => {
IFrame._jQueryInterface.call($(SELECTOR_DATA_TOGGLE))
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = IFrame._jQueryInterface
$.fn[NAME].Constructor = IFrame
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return IFrame._jQueryInterface
}
export default IFrame

View File

@ -0,0 +1,262 @@
/**
* --------------------------------------------
* AdminLTE Layout.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'Layout'
const DATA_KEY = 'lte.layout'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const SELECTOR_HEADER = '.main-header'
const SELECTOR_MAIN_SIDEBAR = '.main-sidebar'
const SELECTOR_SIDEBAR = '.main-sidebar .sidebar'
const SELECTOR_CONTENT = '.content-wrapper'
const SELECTOR_CONTROL_SIDEBAR_CONTENT = '.control-sidebar-content'
const SELECTOR_CONTROL_SIDEBAR_BTN = '[data-widget="control-sidebar"]'
const SELECTOR_FOOTER = '.main-footer'
const SELECTOR_PUSHMENU_BTN = '[data-widget="pushmenu"]'
const SELECTOR_LOGIN_BOX = '.login-box'
const SELECTOR_REGISTER_BOX = '.register-box'
const SELECTOR_PRELOADER = '.preloader'
const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse'
const CLASS_NAME_SIDEBAR_FOCUSED = 'sidebar-focused'
const CLASS_NAME_LAYOUT_FIXED = 'layout-fixed'
const CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN = 'control-sidebar-slide-open'
const CLASS_NAME_CONTROL_SIDEBAR_OPEN = 'control-sidebar-open'
const CLASS_NAME_IFRAME_MODE = 'iframe-mode'
const Default = {
scrollbarTheme: 'os-theme-light',
scrollbarAutoHide: 'l',
panelAutoHeight: true,
panelAutoHeightMode: 'min-height',
preloadDuration: 200,
loginRegisterAutoHeight: true
}
/**
* Class Definition
* ====================================================
*/
class Layout {
constructor(element, config) {
this._config = config
this._element = element
}
// Public
fixLayoutHeight(extra = null) {
const $body = $('body')
let controlSidebar = 0
if ($body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_SLIDE_OPEN) || $body.hasClass(CLASS_NAME_CONTROL_SIDEBAR_OPEN) || extra === 'control_sidebar') {
controlSidebar = $(SELECTOR_CONTROL_SIDEBAR_CONTENT).outerHeight()
}
const heights = {
window: $(window).height(),
header: $(SELECTOR_HEADER).length > 0 ? $(SELECTOR_HEADER).outerHeight() : 0,
footer: $(SELECTOR_FOOTER).length > 0 ? $(SELECTOR_FOOTER).outerHeight() : 0,
sidebar: $(SELECTOR_SIDEBAR).length > 0 ? $(SELECTOR_SIDEBAR).height() : 0,
controlSidebar
}
const max = this._max(heights)
let offset = this._config.panelAutoHeight
if (offset === true) {
offset = 0
}
const $contentSelector = $(SELECTOR_CONTENT)
if (offset !== false) {
if (max === heights.controlSidebar) {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset))
} else if (max === heights.window) {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header - heights.footer)
} else {
$contentSelector.css(this._config.panelAutoHeightMode, (max + offset) - heights.header)
}
if (this._isFooterFixed()) {
$contentSelector.css(this._config.panelAutoHeightMode, parseFloat($contentSelector.css(this._config.panelAutoHeightMode)) + heights.footer)
}
}
if (!$body.hasClass(CLASS_NAME_LAYOUT_FIXED)) {
return
}
if (typeof $.fn.overlayScrollbars !== 'undefined') {
$(SELECTOR_SIDEBAR).overlayScrollbars({
className: this._config.scrollbarTheme,
sizeAutoCapable: true,
scrollbars: {
autoHide: this._config.scrollbarAutoHide,
clickScrolling: true
}
})
} else {
$(SELECTOR_SIDEBAR).css('overflow-y', 'auto')
}
}
fixLoginRegisterHeight() {
const $body = $('body')
const $selector = $(`${SELECTOR_LOGIN_BOX}, ${SELECTOR_REGISTER_BOX}`)
if ($body.hasClass(CLASS_NAME_IFRAME_MODE)) {
$body.css('height', '100%')
$('.wrapper').css('height', '100%')
$('html').css('height', '100%')
} else if ($selector.length === 0) {
$body.css('height', 'auto')
$('html').css('height', 'auto')
} else {
const boxHeight = $selector.height()
if ($body.css(this._config.panelAutoHeightMode) !== boxHeight) {
$body.css(this._config.panelAutoHeightMode, boxHeight)
}
}
}
// Private
_init() {
// Activate layout height watcher
this.fixLayoutHeight()
if (this._config.loginRegisterAutoHeight === true) {
this.fixLoginRegisterHeight()
} else if (this._config.loginRegisterAutoHeight === parseInt(this._config.loginRegisterAutoHeight, 10)) {
setInterval(this.fixLoginRegisterHeight, this._config.loginRegisterAutoHeight)
}
$(SELECTOR_SIDEBAR)
.on('collapsed.lte.treeview expanded.lte.treeview', () => {
this.fixLayoutHeight()
})
$(SELECTOR_MAIN_SIDEBAR)
.on('mouseenter mouseleave', () => {
if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
this.fixLayoutHeight()
}
})
$(SELECTOR_PUSHMENU_BTN)
.on('collapsed.lte.pushmenu shown.lte.pushmenu', () => {
setTimeout(() => {
this.fixLayoutHeight()
}, 300)
})
$(SELECTOR_CONTROL_SIDEBAR_BTN)
.on('collapsed.lte.controlsidebar', () => {
this.fixLayoutHeight()
})
.on('expanded.lte.controlsidebar', () => {
this.fixLayoutHeight('control_sidebar')
})
$(window).resize(() => {
this.fixLayoutHeight()
})
setTimeout(() => {
$('body.hold-transition').removeClass('hold-transition')
}, 50)
setTimeout(() => {
const $preloader = $(SELECTOR_PRELOADER)
if ($preloader) {
$preloader.css('height', 0)
setTimeout(() => {
$preloader.children().hide()
}, 200)
}
}, this._config.preloadDuration)
}
_max(numbers) {
// Calculate the maximum number in a list
let max = 0
Object.keys(numbers).forEach(key => {
if (numbers[key] > max) {
max = numbers[key]
}
})
return max
}
_isFooterFixed() {
return $(SELECTOR_FOOTER).css('position') === 'fixed'
}
// Static
static _jQueryInterface(config = '') {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (!data) {
data = new Layout($(this), _options)
$(this).data(DATA_KEY, data)
}
if (config === 'init' || config === '') {
data._init()
} else if (config === 'fixLayoutHeight' || config === 'fixLoginRegisterHeight') {
data[config]()
}
})
}
}
/**
* Data API
* ====================================================
*/
$(window).on('load', () => {
Layout._jQueryInterface.call($('body'))
})
$(`${SELECTOR_SIDEBAR} a`)
.on('focusin', () => {
$(SELECTOR_MAIN_SIDEBAR).addClass(CLASS_NAME_SIDEBAR_FOCUSED)
})
.on('focusout', () => {
$(SELECTOR_MAIN_SIDEBAR).removeClass(CLASS_NAME_SIDEBAR_FOCUSED)
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = Layout._jQueryInterface
$.fn[NAME].Constructor = Layout
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Layout._jQueryInterface
}
export default Layout

View File

@ -0,0 +1,113 @@
/**
* --------------------------------------------
* AdminLTE NavbarSearch.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'NavbarSearch'
const DATA_KEY = 'lte.navbar-search'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const SELECTOR_TOGGLE_BUTTON = '[data-widget="navbar-search"]'
const SELECTOR_SEARCH_BLOCK = '.navbar-search-block'
const SELECTOR_SEARCH_INPUT = '.form-control'
const CLASS_NAME_OPEN = 'navbar-search-open'
const Default = {
resetOnClose: true,
target: SELECTOR_SEARCH_BLOCK
}
/**
* Class Definition
* ====================================================
*/
class NavbarSearch {
constructor(_element, _options) {
this._element = _element
this._config = $.extend({}, Default, _options)
}
// Public
open() {
$(this._config.target).css('display', 'flex').hide().fadeIn().addClass(CLASS_NAME_OPEN)
$(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).focus()
}
close() {
$(this._config.target).fadeOut().removeClass(CLASS_NAME_OPEN)
if (this._config.resetOnClose) {
$(`${this._config.target} ${SELECTOR_SEARCH_INPUT}`).val('')
}
}
toggle() {
if ($(this._config.target).hasClass(CLASS_NAME_OPEN)) {
this.close()
} else {
this.open()
}
}
// Static
static _jQueryInterface(options) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (!data) {
data = new NavbarSearch(this, _options)
$(this).data(DATA_KEY, data)
}
if (!/toggle|close|open/.test(options)) {
throw new Error(`Undefined method ${options}`)
}
data[options]()
})
}
}
/**
* Data API
* ====================================================
*/
$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
event.preventDefault()
let button = $(event.currentTarget)
if (button.data('widget') !== 'navbar-search') {
button = button.closest(SELECTOR_TOGGLE_BUTTON)
}
NavbarSearch._jQueryInterface.call(button, 'toggle')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = NavbarSearch._jQueryInterface
$.fn[NAME].Constructor = NavbarSearch
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return NavbarSearch._jQueryInterface
}
export default NavbarSearch

View File

@ -0,0 +1,229 @@
/**
* --------------------------------------------
* AdminLTE PushMenu.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'PushMenu'
const DATA_KEY = 'lte.pushmenu'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
const EVENT_COLLAPSED_DONE = `collapsed-done${EVENT_KEY}`
const EVENT_SHOWN = `shown${EVENT_KEY}`
const SELECTOR_TOGGLE_BUTTON = '[data-widget="pushmenu"]'
const SELECTOR_BODY = 'body'
const SELECTOR_OVERLAY = '#sidebar-overlay'
const SELECTOR_WRAPPER = '.wrapper'
const CLASS_NAME_COLLAPSED = 'sidebar-collapse'
const CLASS_NAME_OPEN = 'sidebar-open'
const CLASS_NAME_IS_OPENING = 'sidebar-is-opening'
const CLASS_NAME_CLOSED = 'sidebar-closed'
const Default = {
autoCollapseSize: 992,
enableRemember: false,
noTransitionAfterReload: true,
animationSpeed: 300
}
/**
* Class Definition
* ====================================================
*/
class PushMenu {
constructor(element, options) {
this._element = element
this._options = $.extend({}, Default, options)
if ($(SELECTOR_OVERLAY).length === 0) {
this._addOverlay()
}
this._init()
}
// Public
expand() {
const $bodySelector = $(SELECTOR_BODY)
if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
$bodySelector.addClass(CLASS_NAME_OPEN)
}
$bodySelector.addClass(CLASS_NAME_IS_OPENING).removeClass(`${CLASS_NAME_COLLAPSED} ${CLASS_NAME_CLOSED}`).delay(50).queue(function () {
$bodySelector.removeClass(CLASS_NAME_IS_OPENING)
$(this).dequeue()
})
if (this._options.enableRemember) {
localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_OPEN)
}
$(this._element).trigger($.Event(EVENT_SHOWN))
}
collapse() {
const $bodySelector = $(SELECTOR_BODY)
if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
$bodySelector.removeClass(CLASS_NAME_OPEN).addClass(CLASS_NAME_CLOSED)
}
$bodySelector.addClass(CLASS_NAME_COLLAPSED)
if (this._options.enableRemember) {
localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_COLLAPSED)
}
$(this._element).trigger($.Event(EVENT_COLLAPSED))
setTimeout(() => {
$(this._element).trigger($.Event(EVENT_COLLAPSED_DONE))
}, this._options.animationSpeed)
}
toggle() {
if ($(SELECTOR_BODY).hasClass(CLASS_NAME_COLLAPSED)) {
this.expand()
} else {
this.collapse()
}
}
autoCollapse(resize = false) {
if (!this._options.autoCollapseSize) {
return
}
const $bodySelector = $(SELECTOR_BODY)
if ($(window).width() <= this._options.autoCollapseSize) {
if (!$bodySelector.hasClass(CLASS_NAME_OPEN)) {
this.collapse()
}
} else if (resize === true) {
if ($bodySelector.hasClass(CLASS_NAME_OPEN)) {
$bodySelector.removeClass(CLASS_NAME_OPEN)
} else if ($bodySelector.hasClass(CLASS_NAME_CLOSED)) {
this.expand()
}
}
}
remember() {
if (!this._options.enableRemember) {
return
}
const $body = $('body')
const toggleState = localStorage.getItem(`remember${EVENT_KEY}`)
if (toggleState === CLASS_NAME_COLLAPSED) {
if (this._options.noTransitionAfterReload) {
$body.addClass('hold-transition').addClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
$(this).removeClass('hold-transition')
$(this).dequeue()
})
} else {
$body.addClass(CLASS_NAME_COLLAPSED)
}
} else if (this._options.noTransitionAfterReload) {
$body.addClass('hold-transition').removeClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
$(this).removeClass('hold-transition')
$(this).dequeue()
})
} else {
$body.removeClass(CLASS_NAME_COLLAPSED)
}
}
// Private
_init() {
this.remember()
this.autoCollapse()
$(window).resize(() => {
this.autoCollapse(true)
})
}
_addOverlay() {
const overlay = $('<div />', {
id: 'sidebar-overlay'
})
overlay.on('click', () => {
this.collapse()
})
$(SELECTOR_WRAPPER).append(overlay)
}
// Static
static _jQueryInterface(operation) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (!data) {
data = new PushMenu(this, _options)
$(this).data(DATA_KEY, data)
}
if (typeof operation === 'string' && /collapse|expand|toggle/.test(operation)) {
data[operation]()
}
})
}
}
/**
* Data API
* ====================================================
*/
$(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
event.preventDefault()
let button = event.currentTarget
if ($(button).data('widget') !== 'pushmenu') {
button = $(button).closest(SELECTOR_TOGGLE_BUTTON)
}
PushMenu._jQueryInterface.call($(button), 'toggle')
})
$(window).on('load', () => {
PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON))
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = PushMenu._jQueryInterface
$.fn[NAME].Constructor = PushMenu
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return PushMenu._jQueryInterface
}
export default PushMenu

View File

@ -0,0 +1,299 @@
/**
* --------------------------------------------
* AdminLTE SidebarSearch.js
* License MIT
* --------------------------------------------
*/
import $, { trim } from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'SidebarSearch'
const DATA_KEY = 'lte.sidebar-search'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const CLASS_NAME_OPEN = 'sidebar-search-open'
const CLASS_NAME_ICON_SEARCH = 'fa-search'
const CLASS_NAME_ICON_CLOSE = 'fa-times'
const CLASS_NAME_HEADER = 'nav-header'
const CLASS_NAME_SEARCH_RESULTS = 'sidebar-search-results'
const CLASS_NAME_LIST_GROUP = 'list-group'
const SELECTOR_DATA_WIDGET = '[data-widget="sidebar-search"]'
const SELECTOR_SIDEBAR = '.main-sidebar .nav-sidebar'
const SELECTOR_NAV_LINK = '.nav-link'
const SELECTOR_NAV_TREEVIEW = '.nav-treeview'
const SELECTOR_SEARCH_INPUT = `${SELECTOR_DATA_WIDGET} .form-control`
const SELECTOR_SEARCH_BUTTON = `${SELECTOR_DATA_WIDGET} .btn`
const SELECTOR_SEARCH_ICON = `${SELECTOR_SEARCH_BUTTON} i`
const SELECTOR_SEARCH_LIST_GROUP = `.${CLASS_NAME_LIST_GROUP}`
const SELECTOR_SEARCH_RESULTS = `.${CLASS_NAME_SEARCH_RESULTS}`
const SELECTOR_SEARCH_RESULTS_GROUP = `${SELECTOR_SEARCH_RESULTS} .${CLASS_NAME_LIST_GROUP}`
const Default = {
arrowSign: '->',
minLength: 3,
maxResults: 7,
highlightName: true,
highlightPath: false,
highlightClass: 'text-light',
notFoundText: 'No element found!'
}
const SearchItems = []
/**
* Class Definition
* ====================================================
*/
class SidebarSearch {
constructor(_element, _options) {
this.element = _element
this.options = $.extend({}, Default, _options)
this.items = []
}
// Public
init() {
if ($(SELECTOR_DATA_WIDGET).length === 0) {
return
}
if ($(SELECTOR_DATA_WIDGET).next(SELECTOR_SEARCH_RESULTS).length === 0) {
$(SELECTOR_DATA_WIDGET).after(
$('<div />', { class: CLASS_NAME_SEARCH_RESULTS })
)
}
if ($(SELECTOR_SEARCH_RESULTS).children(SELECTOR_SEARCH_LIST_GROUP).length === 0) {
$(SELECTOR_SEARCH_RESULTS).append(
$('<div />', { class: CLASS_NAME_LIST_GROUP })
)
}
this._addNotFound()
$(SELECTOR_SIDEBAR).children().each((i, child) => {
this._parseItem(child)
})
}
search() {
const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
if (searchValue.length < this.options.minLength) {
$(SELECTOR_SEARCH_RESULTS_GROUP).empty()
this._addNotFound()
this.close()
return
}
const searchResults = SearchItems.filter(item => (item.name).toLowerCase().includes(searchValue))
const endResults = $(searchResults.slice(0, this.options.maxResults))
$(SELECTOR_SEARCH_RESULTS_GROUP).empty()
if (endResults.length === 0) {
this._addNotFound()
} else {
endResults.each((i, result) => {
$(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(escape(result.name), encodeURI(result.link), result.path))
})
}
this.open()
}
open() {
$(SELECTOR_DATA_WIDGET).parent().addClass(CLASS_NAME_OPEN)
$(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_SEARCH).addClass(CLASS_NAME_ICON_CLOSE)
}
close() {
$(SELECTOR_DATA_WIDGET).parent().removeClass(CLASS_NAME_OPEN)
$(SELECTOR_SEARCH_ICON).removeClass(CLASS_NAME_ICON_CLOSE).addClass(CLASS_NAME_ICON_SEARCH)
}
toggle() {
if ($(SELECTOR_DATA_WIDGET).parent().hasClass(CLASS_NAME_OPEN)) {
this.close()
} else {
this.open()
}
}
// Private
_parseItem(item, path = []) {
if ($(item).hasClass(CLASS_NAME_HEADER)) {
return
}
const itemObject = {}
const navLink = $(item).clone().find(`> ${SELECTOR_NAV_LINK}`)
const navTreeview = $(item).clone().find(`> ${SELECTOR_NAV_TREEVIEW}`)
const link = navLink.attr('href')
const name = navLink.find('p').children().remove().end().text()
itemObject.name = this._trimText(name)
itemObject.link = link
itemObject.path = path
if (navTreeview.length === 0) {
SearchItems.push(itemObject)
} else {
const newPath = itemObject.path.concat([itemObject.name])
navTreeview.children().each((i, child) => {
this._parseItem(child, newPath)
})
}
}
_trimText(text) {
return trim(text.replace(/(\r\n|\n|\r)/gm, ' '))
}
_renderItem(name, link, path) {
path = path.join(` ${this.options.arrowSign} `)
name = unescape(name)
link = decodeURI(link)
if (this.options.highlightName || this.options.highlightPath) {
const searchValue = $(SELECTOR_SEARCH_INPUT).val().toLowerCase()
const regExp = new RegExp(searchValue, 'gi')
if (this.options.highlightName) {
name = name.replace(
regExp,
str => {
return `<strong class="${this.options.highlightClass}">${str}</strong>`
}
)
}
if (this.options.highlightPath) {
path = path.replace(
regExp,
str => {
return `<strong class="${this.options.highlightClass}">${str}</strong>`
}
)
}
}
const groupItemElement = $('<a/>', {
href: decodeURIComponent(link),
class: 'list-group-item'
})
const searchTitleElement = $('<div/>', {
class: 'search-title'
}).html(name)
const searchPathElement = $('<div/>', {
class: 'search-path'
}).html(path)
groupItemElement.append(searchTitleElement).append(searchPathElement)
return groupItemElement
}
_addNotFound() {
$(SELECTOR_SEARCH_RESULTS_GROUP).append(this._renderItem(this.options.notFoundText, '#', []))
}
// Static
static _jQueryInterface(config) {
let data = $(this).data(DATA_KEY)
if (!data) {
data = $(this).data()
}
const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new SidebarSearch($(this), _options)
$(this).data(DATA_KEY, typeof config === 'object' ? config : data)
if (typeof config === 'string' && /init|toggle|close|open|search/.test(config)) {
plugin[config]()
} else {
plugin.init()
}
}
}
/**
* Data API
* ====================================================
*/
$(document).on('click', SELECTOR_SEARCH_BUTTON, event => {
event.preventDefault()
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'toggle')
})
$(document).on('keyup', SELECTOR_SEARCH_INPUT, event => {
if (event.keyCode == 38) {
event.preventDefault()
$(SELECTOR_SEARCH_RESULTS_GROUP).children().last().focus()
return
}
if (event.keyCode == 40) {
event.preventDefault()
$(SELECTOR_SEARCH_RESULTS_GROUP).children().first().focus()
return
}
setTimeout(() => {
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'search')
}, 100)
})
$(document).on('keydown', SELECTOR_SEARCH_RESULTS_GROUP, event => {
const $focused = $(':focus')
if (event.keyCode == 38) {
event.preventDefault()
if ($focused.is(':first-child')) {
$focused.siblings().last().focus()
} else {
$focused.prev().focus()
}
}
if (event.keyCode == 40) {
event.preventDefault()
if ($focused.is(':last-child')) {
$focused.siblings().first().focus()
} else {
$focused.next().focus()
}
}
})
$(window).on('load', () => {
SidebarSearch._jQueryInterface.call($(SELECTOR_DATA_WIDGET), 'init')
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = SidebarSearch._jQueryInterface
$.fn[NAME].Constructor = SidebarSearch
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return SidebarSearch._jQueryInterface
}
export default SidebarSearch

View File

@ -0,0 +1,209 @@
/**
* --------------------------------------------
* AdminLTE Toasts.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'Toasts'
const DATA_KEY = 'lte.toasts'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_INIT = `init${EVENT_KEY}`
const EVENT_CREATED = `created${EVENT_KEY}`
const EVENT_REMOVED = `removed${EVENT_KEY}`
const SELECTOR_CONTAINER_TOP_RIGHT = '#toastsContainerTopRight'
const SELECTOR_CONTAINER_TOP_LEFT = '#toastsContainerTopLeft'
const SELECTOR_CONTAINER_BOTTOM_RIGHT = '#toastsContainerBottomRight'
const SELECTOR_CONTAINER_BOTTOM_LEFT = '#toastsContainerBottomLeft'
const CLASS_NAME_TOP_RIGHT = 'toasts-top-right'
const CLASS_NAME_TOP_LEFT = 'toasts-top-left'
const CLASS_NAME_BOTTOM_RIGHT = 'toasts-bottom-right'
const CLASS_NAME_BOTTOM_LEFT = 'toasts-bottom-left'
const POSITION_TOP_RIGHT = 'topRight'
const POSITION_TOP_LEFT = 'topLeft'
const POSITION_BOTTOM_RIGHT = 'bottomRight'
const POSITION_BOTTOM_LEFT = 'bottomLeft'
const Default = {
position: POSITION_TOP_RIGHT,
fixed: true,
autohide: false,
autoremove: true,
delay: 1000,
fade: true,
icon: null,
image: null,
imageAlt: null,
imageHeight: '25px',
title: null,
subtitle: null,
close: true,
body: null,
class: null
}
/**
* Class Definition
* ====================================================
*/
class Toasts {
constructor(element, config) {
this._config = config
this._prepareContainer()
$('body').trigger($.Event(EVENT_INIT))
}
// Public
create() {
const toast = $('<div class="toast" role="alert" aria-live="assertive" aria-atomic="true"/>')
toast.data('autohide', this._config.autohide)
toast.data('animation', this._config.fade)
if (this._config.class) {
toast.addClass(this._config.class)
}
if (this._config.delay && this._config.delay != 500) {
toast.data('delay', this._config.delay)
}
const toastHeader = $('<div class="toast-header">')
if (this._config.image != null) {
const toastImage = $('<img />').addClass('rounded mr-2').attr('src', this._config.image).attr('alt', this._config.imageAlt)
if (this._config.imageHeight != null) {
toastImage.height(this._config.imageHeight).width('auto')
}
toastHeader.append(toastImage)
}
if (this._config.icon != null) {
toastHeader.append($('<i />').addClass('mr-2').addClass(this._config.icon))
}
if (this._config.title != null) {
toastHeader.append($('<strong />').addClass('mr-auto').html(this._config.title))
}
if (this._config.subtitle != null) {
toastHeader.append($('<small />').html(this._config.subtitle))
}
if (this._config.close == true) {
const toastClose = $('<button data-dismiss="toast" />').attr('type', 'button').addClass('ml-2 mb-1 close').attr('aria-label', 'Close').append('<span aria-hidden="true">&times;</span>')
if (this._config.title == null) {
toastClose.toggleClass('ml-2 ml-auto')
}
toastHeader.append(toastClose)
}
toast.append(toastHeader)
if (this._config.body != null) {
toast.append($('<div class="toast-body" />').html(this._config.body))
}
$(this._getContainerId()).prepend(toast)
const $body = $('body')
$body.trigger($.Event(EVENT_CREATED))
toast.toast('show')
if (this._config.autoremove) {
toast.on('hidden.bs.toast', function () {
$(this).delay(200).remove()
$body.trigger($.Event(EVENT_REMOVED))
})
}
}
// Static
_getContainerId() {
if (this._config.position == POSITION_TOP_RIGHT) {
return SELECTOR_CONTAINER_TOP_RIGHT
}
if (this._config.position == POSITION_TOP_LEFT) {
return SELECTOR_CONTAINER_TOP_LEFT
}
if (this._config.position == POSITION_BOTTOM_RIGHT) {
return SELECTOR_CONTAINER_BOTTOM_RIGHT
}
if (this._config.position == POSITION_BOTTOM_LEFT) {
return SELECTOR_CONTAINER_BOTTOM_LEFT
}
}
_prepareContainer() {
if ($(this._getContainerId()).length === 0) {
const container = $('<div />').attr('id', this._getContainerId().replace('#', ''))
if (this._config.position == POSITION_TOP_RIGHT) {
container.addClass(CLASS_NAME_TOP_RIGHT)
} else if (this._config.position == POSITION_TOP_LEFT) {
container.addClass(CLASS_NAME_TOP_LEFT)
} else if (this._config.position == POSITION_BOTTOM_RIGHT) {
container.addClass(CLASS_NAME_BOTTOM_RIGHT)
} else if (this._config.position == POSITION_BOTTOM_LEFT) {
container.addClass(CLASS_NAME_BOTTOM_LEFT)
}
$('body').append(container)
}
if (this._config.fixed) {
$(this._getContainerId()).addClass('fixed')
} else {
$(this._getContainerId()).removeClass('fixed')
}
}
// Static
static _jQueryInterface(option, config) {
return this.each(function () {
const _options = $.extend({}, Default, config)
const toast = new Toasts($(this), _options)
if (option === 'create') {
toast[option]()
}
})
}
}
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = Toasts._jQueryInterface
$.fn[NAME].Constructor = Toasts
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Toasts._jQueryInterface
}
export default Toasts

View File

@ -0,0 +1,118 @@
/**
* --------------------------------------------
* AdminLTE TodoList.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'TodoList'
const DATA_KEY = 'lte.todolist'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const SELECTOR_DATA_TOGGLE = '[data-widget="todo-list"]'
const CLASS_NAME_TODO_LIST_DONE = 'done'
const Default = {
onCheck(item) {
return item
},
onUnCheck(item) {
return item
}
}
/**
* Class Definition
* ====================================================
*/
class TodoList {
constructor(element, config) {
this._config = config
this._element = element
this._init()
}
// Public
toggle(item) {
item.parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
if (!$(item).prop('checked')) {
this.unCheck($(item))
return
}
this.check(item)
}
check(item) {
this._config.onCheck.call(item)
}
unCheck(item) {
this._config.onUnCheck.call(item)
}
// Private
_init() {
const $toggleSelector = this._element
$toggleSelector.find('input:checkbox:checked').parents('li').toggleClass(CLASS_NAME_TODO_LIST_DONE)
$toggleSelector.on('change', 'input:checkbox', event => {
this.toggle($(event.target))
})
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
if (!data) {
data = $(this).data()
}
const _options = $.extend({}, Default, typeof config === 'object' ? config : data)
const plugin = new TodoList($(this), _options)
$(this).data(DATA_KEY, typeof config === 'object' ? config : data)
if (config === 'init') {
plugin[config]()
}
})
}
}
/**
* Data API
* ====================================================
*/
$(window).on('load', () => {
TodoList._jQueryInterface.call($(SELECTOR_DATA_TOGGLE))
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = TodoList._jQueryInterface
$.fn[NAME].Constructor = TodoList
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return TodoList._jQueryInterface
}
export default TodoList

View File

@ -0,0 +1,175 @@
/**
* --------------------------------------------
* AdminLTE Treeview.js
* License MIT
* --------------------------------------------
*/
import $ from 'jquery'
/**
* Constants
* ====================================================
*/
const NAME = 'Treeview'
const DATA_KEY = 'lte.treeview'
const EVENT_KEY = `.${DATA_KEY}`
const JQUERY_NO_CONFLICT = $.fn[NAME]
const EVENT_EXPANDED = `expanded${EVENT_KEY}`
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`
const SELECTOR_LI = '.nav-item'
const SELECTOR_LINK = '.nav-link'
const SELECTOR_TREEVIEW_MENU = '.nav-treeview'
const SELECTOR_OPEN = '.menu-open'
const SELECTOR_DATA_WIDGET = '[data-widget="treeview"]'
const CLASS_NAME_OPEN = 'menu-open'
const CLASS_NAME_IS_OPENING = 'menu-is-opening'
const CLASS_NAME_SIDEBAR_COLLAPSED = 'sidebar-collapse'
const Default = {
trigger: `${SELECTOR_DATA_WIDGET} ${SELECTOR_LINK}`,
animationSpeed: 300,
accordion: true,
expandSidebar: false,
sidebarButtonSelector: '[data-widget="pushmenu"]'
}
/**
* Class Definition
* ====================================================
*/
class Treeview {
constructor(element, config) {
this._config = config
this._element = element
}
// Public
init() {
$(`${SELECTOR_LI}${SELECTOR_OPEN} ${SELECTOR_TREEVIEW_MENU}${SELECTOR_OPEN}`).css('display', 'block')
this._setupListeners()
}
expand(treeviewMenu, parentLi) {
const expandedEvent = $.Event(EVENT_EXPANDED)
if (this._config.accordion) {
const openMenuLi = parentLi.siblings(SELECTOR_OPEN).first()
const openTreeview = openMenuLi.find(SELECTOR_TREEVIEW_MENU).first()
this.collapse(openTreeview, openMenuLi)
}
parentLi.addClass(CLASS_NAME_IS_OPENING)
treeviewMenu.stop().slideDown(this._config.animationSpeed, () => {
parentLi.addClass(CLASS_NAME_OPEN)
$(this._element).trigger(expandedEvent)
})
if (this._config.expandSidebar) {
this._expandSidebar()
}
}
collapse(treeviewMenu, parentLi) {
const collapsedEvent = $.Event(EVENT_COLLAPSED)
parentLi.removeClass(`${CLASS_NAME_IS_OPENING} ${CLASS_NAME_OPEN}`)
treeviewMenu.stop().slideUp(this._config.animationSpeed, () => {
$(this._element).trigger(collapsedEvent)
treeviewMenu.find(`${SELECTOR_OPEN} > ${SELECTOR_TREEVIEW_MENU}`).slideUp()
treeviewMenu.find(SELECTOR_OPEN).removeClass(`${CLASS_NAME_IS_OPENING} ${CLASS_NAME_OPEN}`)
})
}
toggle(event) {
const $relativeTarget = $(event.currentTarget)
const $parent = $relativeTarget.parent()
let treeviewMenu = $parent.find(`> ${SELECTOR_TREEVIEW_MENU}`)
if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
if (!$parent.is(SELECTOR_LI)) {
treeviewMenu = $parent.parent().find(`> ${SELECTOR_TREEVIEW_MENU}`)
}
if (!treeviewMenu.is(SELECTOR_TREEVIEW_MENU)) {
return
}
}
event.preventDefault()
const parentLi = $relativeTarget.parents(SELECTOR_LI).first()
const isOpen = parentLi.hasClass(CLASS_NAME_OPEN)
if (isOpen) {
this.collapse($(treeviewMenu), parentLi)
} else {
this.expand($(treeviewMenu), parentLi)
}
}
// Private
_setupListeners() {
const elementId = this._element.attr('id') !== undefined ? `#${this._element.attr('id')}` : ''
$(document).on('click', `${elementId}${this._config.trigger}`, event => {
this.toggle(event)
})
}
_expandSidebar() {
if ($('body').hasClass(CLASS_NAME_SIDEBAR_COLLAPSED)) {
$(this._config.sidebarButtonSelector).PushMenu('expand')
}
}
// Static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
const _options = $.extend({}, Default, $(this).data())
if (!data) {
data = new Treeview($(this), _options)
$(this).data(DATA_KEY, data)
}
if (config === 'init') {
data[config]()
}
})
}
}
/**
* Data API
* ====================================================
*/
$(window).on(EVENT_LOAD_DATA_API, () => {
$(SELECTOR_DATA_WIDGET).each(function () {
Treeview._jQueryInterface.call($(this), 'init')
})
})
/**
* jQuery API
* ====================================================
*/
$.fn[NAME] = Treeview._jQueryInterface
$.fn[NAME].Constructor = Treeview
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Treeview._jQueryInterface
}
export default Treeview

View File

@ -0,0 +1,15 @@
{
"env": {
"browser": false,
"node": true
},
"parserOptions": {
"sourceType": "script"
},
"extends": "../../.eslintrc.json",
"rules": {
"no-console": "off",
"strict": "error",
"unicorn/prefer-module": "off"
}
}

View File

@ -0,0 +1,48 @@
'use strict'
const Plugins = [
// AdminLTE Dist
{
from: 'dist/css/',
to: 'docs/assets/css/'
},
{
from: 'dist/js/',
to: 'docs/assets/js/'
},
// jQuery
{
from: 'node_modules/jquery/dist/',
to: 'docs/assets/plugins/jquery/'
},
// Popper
{
from: 'node_modules/popper.js/dist/',
to: 'docs/assets/plugins/popper/'
},
// Bootstrap
{
from: 'node_modules/bootstrap/dist/js/',
to: 'docs/assets/plugins/bootstrap/js/'
},
// Font Awesome
{
from: 'node_modules/@fortawesome/fontawesome-free/css/',
to: 'docs/assets/plugins/fontawesome-free/css/'
},
{
from: 'node_modules/@fortawesome/fontawesome-free/webfonts/',
to: 'docs/assets/plugins/fontawesome-free/webfonts/'
},
// overlayScrollbars
{
from: 'node_modules/overlayscrollbars/js/',
to: 'docs/assets/plugins/overlayScrollbars/js/'
},
{
from: 'node_modules/overlayscrollbars/css/',
to: 'docs/assets/plugins/overlayScrollbars/css/'
}
]
module.exports = Plugins

View File

@ -0,0 +1,58 @@
#!/usr/bin/env node
'use strict'
const path = require('path')
const fse = require('fs-extra')
const fs = require('fs')
const Plugins = require('./DocsPlugins')
class Publish {
constructor() {
this.options = {
verbose: false
}
this.getArguments()
}
getArguments() {
if (process.argv.length > 2) {
const arg = process.argv[2]
switch (arg) {
case '-v':
case '--verbose':
this.options.verbose = true
break
default:
throw new Error(`Unknown option ${arg}`)
}
}
}
run() {
// Publish files
Plugins.forEach(module => {
try {
fse.copySync(module.from, module.to, {
// Skip copying dot files
filter(src) {
return !path.basename(src).startsWith('.')
}
})
if (this.options.verbose) {
console.log(`Copied ${module.from} to ${module.to}`)
}
} catch (error) {
console.error(`Error: ${error}`)
}
})
const insertText = '---\r\nlayout: page\r\ntitle: \r\n---\r\n'
fs.writeFileSync('docs/how-to-contribute.md', insertText + fs.readFileSync('.github/CONTRIBUTING.md', 'utf8'))
}
}
(new Publish()).run()

View File

@ -0,0 +1,449 @@
'use strict'
const Plugins = [
// jQuery
{
from: 'node_modules/jquery/dist',
to: 'plugins/jquery'
},
// Popper
{
from: 'node_modules/popper.js/dist',
to: 'plugins/popper'
},
// Bootstrap
{
from: 'node_modules/bootstrap/dist/js',
to: 'plugins/bootstrap/js'
},
// Font Awesome
{
from: 'node_modules/@fortawesome/fontawesome-free/css',
to: 'plugins/fontawesome-free/css'
},
{
from: 'node_modules/@fortawesome/fontawesome-free/webfonts',
to: 'plugins/fontawesome-free/webfonts'
},
// overlayScrollbars
{
from: 'node_modules/overlayscrollbars/js',
to: 'plugins/overlayScrollbars/js'
},
{
from: 'node_modules/overlayscrollbars/css',
to: 'plugins/overlayScrollbars/css'
},
// Chart.js
{
from: 'node_modules/chart.js/dist/',
to: 'plugins/chart.js'
},
// jQuery UI
{
from: 'node_modules/jquery-ui-dist/',
to: 'plugins/jquery-ui'
},
// Flot
{
from: 'node_modules/flot/dist/es5/',
to: 'plugins/flot'
},
{
from: 'node_modules/flot/source/',
to: 'plugins/flot/plugins'
},
// Summernote
{
from: 'node_modules/summernote/dist/',
to: 'plugins/summernote'
},
// Bootstrap Slider
{
from: 'node_modules/bootstrap-slider/dist/',
to: 'plugins/bootstrap-slider'
},
{
from: 'node_modules/bootstrap-slider/dist/css',
to: 'plugins/bootstrap-slider/css'
},
// Bootstrap Colorpicker
{
from: 'node_modules/bootstrap-colorpicker/dist/js',
to: 'plugins/bootstrap-colorpicker/js'
},
{
from: 'node_modules/bootstrap-colorpicker/dist/css',
to: 'plugins/bootstrap-colorpicker/css'
},
// Tempusdominus Bootstrap 4
{
from: 'node_modules/tempusdominus-bootstrap-4/build/js',
to: 'plugins/tempusdominus-bootstrap-4/js'
},
{
from: 'node_modules/tempusdominus-bootstrap-4/build/css',
to: 'plugins/tempusdominus-bootstrap-4/css'
},
// Moment
{
from: 'node_modules/moment/min',
to: 'plugins/moment'
},
{
from: 'node_modules/moment/locale',
to: 'plugins/moment/locale'
},
// FastClick
{
from: 'node_modules/fastclick/lib',
to: 'plugins/fastclick'
},
// Date Range Picker
{
from: 'node_modules/daterangepicker/',
to: 'plugins/daterangepicker'
},
// DataTables
{
from: 'node_modules/pdfmake/build',
to: 'plugins/pdfmake'
},
{
from: 'node_modules/jszip/dist',
to: 'plugins/jszip'
},
{
from: 'node_modules/datatables.net/js',
to: 'plugins/datatables'
},
{
from: 'node_modules/datatables.net-bs4/js',
to: 'plugins/datatables-bs4/js'
},
{
from: 'node_modules/datatables.net-bs4/css',
to: 'plugins/datatables-bs4/css'
},
{
from: 'node_modules/datatables.net-autofill/js',
to: 'plugins/datatables-autofill/js'
},
{
from: 'node_modules/datatables.net-autofill-bs4/js',
to: 'plugins/datatables-autofill/js'
},
{
from: 'node_modules/datatables.net-autofill-bs4/css',
to: 'plugins/datatables-autofill/css'
},
{
from: 'node_modules/datatables.net-buttons/js',
to: 'plugins/datatables-buttons/js'
},
{
from: 'node_modules/datatables.net-buttons-bs4/js',
to: 'plugins/datatables-buttons/js'
},
{
from: 'node_modules/datatables.net-buttons-bs4/css',
to: 'plugins/datatables-buttons/css'
},
{
from: 'node_modules/datatables.net-colreorder/js',
to: 'plugins/datatables-colreorder/js'
},
{
from: 'node_modules/datatables.net-colreorder-bs4/js',
to: 'plugins/datatables-colreorder/js'
},
{
from: 'node_modules/datatables.net-colreorder-bs4/css',
to: 'plugins/datatables-colreorder/css'
},
{
from: 'node_modules/datatables.net-fixedcolumns/js',
to: 'plugins/datatables-fixedcolumns/js'
},
{
from: 'node_modules/datatables.net-fixedcolumns-bs4/js',
to: 'plugins/datatables-fixedcolumns/js'
},
{
from: 'node_modules/datatables.net-fixedcolumns-bs4/css',
to: 'plugins/datatables-fixedcolumns/css'
},
{
from: 'node_modules/datatables.net-fixedheader/js',
to: 'plugins/datatables-fixedheader/js'
},
{
from: 'node_modules/datatables.net-fixedheader-bs4/js',
to: 'plugins/datatables-fixedheader/js'
},
{
from: 'node_modules/datatables.net-fixedheader-bs4/css',
to: 'plugins/datatables-fixedheader/css'
},
{
from: 'node_modules/datatables.net-keytable/js',
to: 'plugins/datatables-keytable/js'
},
{
from: 'node_modules/datatables.net-keytable-bs4/js',
to: 'plugins/datatables-keytable/js'
},
{
from: 'node_modules/datatables.net-keytable-bs4/css',
to: 'plugins/datatables-keytable/css'
},
{
from: 'node_modules/datatables.net-responsive/js',
to: 'plugins/datatables-responsive/js'
},
{
from: 'node_modules/datatables.net-responsive-bs4/js',
to: 'plugins/datatables-responsive/js'
},
{
from: 'node_modules/datatables.net-responsive-bs4/css',
to: 'plugins/datatables-responsive/css'
},
{
from: 'node_modules/datatables.net-rowgroup/js',
to: 'plugins/datatables-rowgroup/js'
},
{
from: 'node_modules/datatables.net-rowgroup-bs4/js',
to: 'plugins/datatables-rowgroup/js'
},
{
from: 'node_modules/datatables.net-rowgroup-bs4/css',
to: 'plugins/datatables-rowgroup/css'
},
{
from: 'node_modules/datatables.net-rowreorder/js',
to: 'plugins/datatables-rowreorder/js'
},
{
from: 'node_modules/datatables.net-rowreorder-bs4/js',
to: 'plugins/datatables-rowreorder/js'
},
{
from: 'node_modules/datatables.net-rowreorder-bs4/css',
to: 'plugins/datatables-rowreorder/css'
},
{
from: 'node_modules/datatables.net-scroller/js',
to: 'plugins/datatables-scroller/js'
},
{
from: 'node_modules/datatables.net-scroller-bs4/js',
to: 'plugins/datatables-scroller/js'
},
{
from: 'node_modules/datatables.net-scroller-bs4/css',
to: 'plugins/datatables-scroller/css'
},
{
from: 'node_modules/datatables.net-searchbuilder/js',
to: 'plugins/datatables-searchbuilder/js'
},
{
from: 'node_modules/datatables.net-searchbuilder-bs4/js',
to: 'plugins/datatables-searchbuilder/js'
},
{
from: 'node_modules/datatables.net-searchbuilder-bs4/css',
to: 'plugins/datatables-searchbuilder/css'
},
{
from: 'node_modules/datatables.net-searchpanes/js',
to: 'plugins/datatables-searchpanes/js'
},
{
from: 'node_modules/datatables.net-searchpanes-bs4/js',
to: 'plugins/datatables-searchpanes/js'
},
{
from: 'node_modules/datatables.net-searchpanes-bs4/css',
to: 'plugins/datatables-searchpanes/css'
},
{
from: 'node_modules/datatables.net-select/js',
to: 'plugins/datatables-select/js'
},
{
from: 'node_modules/datatables.net-select-bs4/js',
to: 'plugins/datatables-select/js'
},
{
from: 'node_modules/datatables.net-select-bs4/css',
to: 'plugins/datatables-select/css'
},
// Fullcalendar
{
from: 'node_modules/fullcalendar/',
to: 'plugins/fullcalendar'
},
// icheck bootstrap
{
from: 'node_modules/icheck-bootstrap/',
to: 'plugins/icheck-bootstrap'
},
// inputmask
{
from: 'node_modules/inputmask/dist/',
to: 'plugins/inputmask'
},
// ion-rangeslider
{
from: 'node_modules/ion-rangeslider/',
to: 'plugins/ion-rangeslider'
},
// JQVMap (jqvmap-novulnerability)
{
from: 'node_modules/jqvmap-novulnerability/dist/',
to: 'plugins/jqvmap'
},
// jQuery Mapael
{
from: 'node_modules/jquery-mapael/js/',
to: 'plugins/jquery-mapael'
},
// Raphael
{
from: 'node_modules/raphael/',
to: 'plugins/raphael'
},
// jQuery Mousewheel
{
from: 'node_modules/jquery-mousewheel/',
to: 'plugins/jquery-mousewheel'
},
// jQuery Knob
{
from: 'node_modules/jquery-knob-chif/dist/',
to: 'plugins/jquery-knob'
},
// pace-progress
{
from: 'node_modules/@lgaitan/pace-progress/dist/',
to: 'plugins/pace-progress'
},
// Select2
{
from: 'node_modules/select2/dist/',
to: 'plugins/select2'
},
{
from: 'node_modules/@ttskch/select2-bootstrap4-theme/dist/',
to: 'plugins/select2-bootstrap4-theme'
},
// Sparklines
{
from: 'node_modules/sparklines/source/',
to: 'plugins/sparklines'
},
// SweetAlert2
{
from: 'node_modules/sweetalert2/dist/',
to: 'plugins/sweetalert2'
},
{
from: 'node_modules/@sweetalert2/theme-bootstrap-4/',
to: 'plugins/sweetalert2-theme-bootstrap-4'
},
// Toastr
{
from: 'node_modules/toastr/build/',
to: 'plugins/toastr'
},
// jsGrid
{
from: 'node_modules/jsgrid/dist',
to: 'plugins/jsgrid'
},
{
from: 'node_modules/jsgrid/demos/db.js',
to: 'plugins/jsgrid/demos/db.js'
},
// flag-icon-css
{
from: 'node_modules/flag-icon-css/css',
to: 'plugins/flag-icon-css/css'
},
{
from: 'node_modules/flag-icon-css/flags',
to: 'plugins/flag-icon-css/flags'
},
// bootstrap4-duallistbox
{
from: 'node_modules/bootstrap4-duallistbox/dist',
to: 'plugins/bootstrap4-duallistbox/'
},
// filterizr
{
from: 'node_modules/filterizr/dist',
to: 'plugins/filterizr/'
},
// ekko-lightbox
{
from: 'node_modules/ekko-lightbox/dist',
to: 'plugins/ekko-lightbox/'
},
// bootstrap-switch
{
from: 'node_modules/bootstrap-switch/dist',
to: 'plugins/bootstrap-switch/'
},
// jQuery Validate
{
from: 'node_modules/jquery-validation/dist/',
to: 'plugins/jquery-validation'
},
// bs-custom-file-input
{
from: 'node_modules/bs-custom-file-input/dist/',
to: 'plugins/bs-custom-file-input'
},
// bs-stepper
{
from: 'node_modules/bs-stepper/dist/',
to: 'plugins/bs-stepper'
},
// CodeMirror
{
from: 'node_modules/codemirror/lib/',
to: 'plugins/codemirror'
},
{
from: 'node_modules/codemirror/addon/',
to: 'plugins/codemirror/addon'
},
{
from: 'node_modules/codemirror/keymap/',
to: 'plugins/codemirror/keymap'
},
{
from: 'node_modules/codemirror/mode/',
to: 'plugins/codemirror/mode'
},
{
from: 'node_modules/codemirror/theme/',
to: 'plugins/codemirror/theme'
},
// dropzonejs
{
from: 'node_modules/dropzone/dist/',
to: 'plugins/dropzone'
},
// uPlot
{
from: 'node_modules/uplot/dist/',
to: 'plugins/uplot'
}
]
module.exports = Plugins

View File

@ -0,0 +1,59 @@
#!/usr/bin/env node
'use strict'
const path = require('path')
const fse = require('fs-extra')
const Plugins = require('./Plugins')
class Publish {
constructor() {
this.options = {
verbose: false
}
this.getArguments()
}
getArguments() {
if (process.argv.length > 2) {
const arg = process.argv[2]
switch (arg) {
case '-v':
case '--verbose':
this.options.verbose = true
break
default:
throw new Error(`Unknown option ${arg}`)
}
}
}
run() {
// Publish files
Plugins.forEach(module => {
const fseOptions = {
// Skip copying dot files
filter(src) {
return !path.basename(src).startsWith('.')
}
}
try {
if (fse.existsSync(module.from)) {
fse.copySync(module.from, module.to, fseOptions)
} else {
fse.copySync(module.from.replace('node_modules/', '../'), module.to, fseOptions)
}
if (this.options.verbose) {
console.log(`Copied ${module.from} to ${module.to}`)
}
} catch (error) {
console.error(`Error: ${error}`)
}
})
}
}
(new Publish()).run()

View File

@ -0,0 +1,55 @@
#!/usr/bin/env node
/*!
* Script to run vnu-jar if Java is available.
* Copyright 2017-2021 The Bootstrap Authors
* Copyright 2017-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
'use strict'
const childProcess = require('child_process')
const vnu = require('vnu-jar')
childProcess.exec('java -version', (error, stdout, stderr) => {
if (error) {
console.error('Skipping vnu-jar test; Java is missing.')
return
}
const is32bitJava = !/64-Bit/.test(stderr)
// vnu-jar accepts multiple ignores joined with a `|`.
// Also note that the ignores are regular expressions.
const ignores = [
// "autocomplete" is included in <button> and checkboxes and radio <input>s due to
// Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072
'Attribute “autocomplete” is only allowed when the input type is.*'
].join('|')
const args = [
'-jar',
vnu,
'--asciiquotes',
'--skip-non-html',
// Ignore the language code warnings
'--no-langdetect',
'--Werror',
`--filterpattern "${ignores}"`,
'./*.html',
'docs_html/',
'pages/'
]
// For the 32-bit Java we need to pass `-Xss512k`
if (is32bitJava) {
args.splice(0, 0, '-Xss512k')
}
return childProcess.spawn('java', args, {
shell: true,
stdio: 'inherit'
})
.on('exit', process.exit)
})

View File

@ -0,0 +1,30 @@
/*!
* AdminLTE v3.2.0
* Author: Colorlib
* Website: AdminLTE.io <https://adminlte.io>
* License: Open source - MIT <https://opensource.org/licenses/MIT>
*/
//
// ------------------------------------------------------------------
// This file is to be included in your custom SCSS. Before importing
// this file, you should include your custom AdminLTE and Bootstrap
// variables followed by bootstrap.scss and then this file. It's
// ok to import this file without custom variables too!
// NOTE: be sure to keep the license notice in the generated css.
// ------------------------------------------------------------------
//
// Variables and Mixins
// ---------------------------------------------------
@import "bootstrap-variables";
@import "variables";
@import "variables-alt";
@import "mixins";
@import "parts/core";
@import "parts/components";
@import "parts/extra-components";
@import "parts/pages";
@import "parts/plugins";
@import "parts/miscellaneous";

View File

@ -0,0 +1,52 @@
//
// Component: Alert
//
.alert {
.icon {
margin-right: 10px;
}
.close {
color: $black;
opacity: .2;
&:hover {
opacity: .5;
}
}
a {
color: $white;
text-decoration: underline;
}
}
//Alert Variants
@each $color, $value in $theme-colors {
.alert-#{$color} {
color: color-yiq($value);
background-color: $value;
border-color: darken($value, 5%);
}
.alert-default-#{$color} {
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
}
}
@include dark-mode () {
@each $color, $value in $theme-colors-alt {
.alert-#{$color} {
color: color-yiq($value);
background-color: $value;
border-color: darken($value, 5%);
}
.alert-default-#{$color} {
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
}
}
}
//

View File

@ -0,0 +1,14 @@
//
// Component: Animation
//
.animation {
&__shake {
animation: shake 1500ms;
}
&__wobble {
animation: wobble 1500ms;
}
}
//

View File

@ -0,0 +1,922 @@
// Variables
//
// Variables should follow the `$component-state-property-size` formula for
// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.
//
// Color system
//
// stylelint-disable
$white: #fff !default;
$gray-100: #f8f9fa !default;
$gray-200: #e9ecef !default;
$gray-300: #dee2e6 !default;
$gray-400: #ced4da !default;
$gray-500: #adb5bd !default;
$gray-600: #6c757d !default;
$gray-700: #495057 !default;
$gray-800: #343a40 !default;
$gray-900: #212529 !default;
$black: #000 !default;
$grays: () !default;
$grays: map-merge((
"100": $gray-100,
"200": $gray-200,
"300": $gray-300,
"400": $gray-400,
"500": $gray-500,
"600": $gray-600,
"700": $gray-700,
"800": $gray-800,
"900": $gray-900
), $grays);
$blue: #007bff !default;
$indigo: #6610f2 !default;
$purple: #6f42c1 !default;
$pink: #e83e8c !default;
$red: #dc3545 !default;
$orange: #fd7e14 !default;
$yellow: #ffc107 !default;
$green: #28a745 !default;
$teal: #20c997 !default;
$cyan: #17a2b8 !default;
$colors: () !default;
$colors: map-merge((
"blue": $blue,
"indigo": $indigo,
"purple": $purple,
"pink": $pink,
"red": $red,
"orange": $orange,
"yellow": $yellow,
"green": $green,
"teal": $teal,
"cyan": $cyan,
"white": $white,
"gray": $gray-600,
"gray-dark": $gray-800
), $colors);
$primary: $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-800 !default;
$theme-colors: () !default;
$theme-colors: map-merge((
"primary": $primary,
"secondary": $secondary,
"success": $success,
"info": $info,
"warning": $warning,
"danger": $danger,
"light": $light,
"dark": $dark
), $theme-colors);
// stylelint-enable
// Set a specific jump point for requesting color jumps
$theme-color-interval: 8% !default;
// The yiq lightness value that determines when the lightness of color changes from "dark" to "light". Acceptable values are between 0 and 255.
$yiq-contrasted-threshold: 150 !default;
// Customize the light and dark text colors for use in our YIQ color contrast function.
$yiq-text-dark: #1f2d3d !default;
$yiq-text-light: $white !default;
// Options
//
// Quickly modify global styling by enabling or disabling optional features.
$enable-caret: true !default;
$enable-rounded: true !default;
$enable-shadows: true !default;
$enable-gradients: false !default;
$enable-transitions: true !default;
$enable-prefers-reduced-motion-media-query: true !default;
$enable-hover-media-query: false !default; // Deprecated, no longer affects any compiled CSS
$enable-grid-classes: true !default;
$enable-pointer-cursor-for-buttons: true !default;
$enable-print-styles: true !default;
$enable-responsive-font-sizes: false !default;
$enable-validation-icons: true !default;
$enable-deprecation-messages: true !default;
// Characters which are escaped by the escape-svg function
$escaped-characters: (
("<", "%3c"),
(">", "%3e"),
("#", "%23"),
("(", "%28"),
(")", "%29"),
) !default;
// Spacing
//
// Control the default styling of most Bootstrap elements by modifying these
// variables. Mostly focused on spacing.
// You can add more entries to the $spacers map, should you need more variation.
// stylelint-disable
$spacer: 1rem !default;
$spacers: () !default;
$spacers: map-merge((
0: 0,
1: ($spacer * .25),
2: ($spacer * .5),
3: $spacer,
4: ($spacer * 1.5),
5: ($spacer * 3)
), $spacers);
// This variable affects the `.h-*` and `.w-*` classes.
$sizes: () !default;
$sizes: map-merge((
25: 25%,
50: 50%,
75: 75%,
100: 100%
), $sizes);
// stylelint-enable
// Body
//
// Settings for the `<body>` element.
$body-bg: $white !default;
$body-color: $gray-900 !default;
// Links
//
// Style anchor elements.
$link-color: theme-color("primary") !default;
$link-decoration: none !default;
$link-hover-color: darken($link-color, 15%) !default;
$link-hover-decoration: none !default;
// Paragraphs
//
// Style p element.
$paragraph-margin-bottom: 1rem !default;
// Grid breakpoints
//
// Define the minimum dimensions at which your layout will change,
// adapting to different screen sizes, for use in media queries.
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
) !default;
@include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
@include _assert-starts-at-zero($grid-breakpoints);
// Grid containers
//
// Define the maximum width of `.container` for different screen sizes.
$container-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1140px
) !default;
@include _assert-ascending($container-max-widths, "$container-max-widths");
// Grid columns
//
// Set the number of columns and specify the width of the gutters.
$grid-columns: 12 !default;
$grid-gutter-width: 15px !default;
// Components
//
// Define common padding and border radius sizes and more.
$line-height-lg: 1.5 !default;
$line-height-sm: 1.5 !default;
$border-width: 1px !default;
$border-color: $gray-300 !default;
$border-radius: .25rem !default;
$border-radius-lg: .3rem !default;
$border-radius-sm: .2rem !default;
$component-active-color: $white !default;
$component-active-bg: theme-color("primary") !default;
$caret-width: .3em !default;
$transition-base: all .2s ease-in-out !default;
$transition-fade: opacity .15s linear !default;
$transition-collapse: height .35s ease !default;
// Fonts
//
// Font, line-height, and color for body text, headings, and more.
// stylelint-disable value-keyword-case
$font-family-sans-serif: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
$font-family-base: $font-family-sans-serif !default;
// stylelint-enable value-keyword-case
$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`
$font-size-lg: ($font-size-base * 1.25) !default;
$font-size-sm: ($font-size-base * .875) !default;
$font-weight-light: 300 !default;
$font-weight-normal: 400 !default;
$font-weight-bold: 700 !default;
$font-weight-base: $font-weight-normal !default;
$line-height-base: 1.5 !default;
$h1-font-size: $font-size-base * 2.5 !default;
$h2-font-size: $font-size-base * 2 !default;
$h3-font-size: $font-size-base * 1.75 !default;
$h4-font-size: $font-size-base * 1.5 !default;
$h5-font-size: $font-size-base * 1.25 !default;
$h6-font-size: $font-size-base !default;
$headings-margin-bottom: ($spacer * .5) !default;
$headings-font-family: inherit !default;
$headings-font-weight: 500 !default;
$headings-line-height: 1.2 !default;
$headings-color: inherit !default;
$display1-size: 6rem !default;
$display2-size: 5.5rem !default;
$display3-size: 4.5rem !default;
$display4-size: 3.5rem !default;
$display1-weight: 300 !default;
$display2-weight: 300 !default;
$display3-weight: 300 !default;
$display4-weight: 300 !default;
$display-line-height: $headings-line-height !default;
$lead-font-size: ($font-size-base * 1.25) !default;
$lead-font-weight: 300 !default;
$small-font-size: 80% !default;
$text-muted: $gray-600 !default;
$blockquote-small-color: $gray-600 !default;
$blockquote-font-size: ($font-size-base * 1.25) !default;
$hr-border-color: rgba($black, .1) !default;
$hr-border-width: $border-width !default;
$mark-padding: .2em !default;
$dt-font-weight: $font-weight-bold !default;
$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;
$nested-kbd-font-weight: $font-weight-bold !default;
$list-inline-padding: .5rem !default;
$mark-bg: #fcf8e3 !default;
$hr-margin-y: $spacer !default;
// Tables
//
// Customizes the `.table` component with basic values, each used across all table variations.
$table-cell-padding: .75rem !default;
$table-cell-padding-sm: .3rem !default;
$table-bg: transparent !default;
$table-accent-bg: rgba($black, .05) !default;
$table-hover-bg: rgba($black, .075) !default;
$table-active-bg: $table-hover-bg !default;
$table-border-width: $border-width !default;
$table-border-color: $gray-300 !default;
$table-head-bg: $gray-200 !default;
$table-head-color: $gray-700 !default;
$table-dark-bg: $gray-900 !default;
$table-dark-accent-bg: rgba($white, .05) !default;
$table-dark-hover-bg: rgba($white, .075) !default;
$table-dark-border-color: lighten($gray-900, 10%) !default;
$table-dark-color: $body-bg !default;
// Buttons + Forms
//
// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.
$input-btn-padding-y: .375rem !default;
$input-btn-padding-x: .75rem !default;
$input-btn-line-height: $line-height-base !default;
$input-btn-focus-width: .2rem !default;
$input-btn-focus-color: rgba($component-active-bg, .25) !default;
$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;
$input-btn-padding-y-sm: .25rem !default;
$input-btn-padding-x-sm: .5rem !default;
$input-btn-line-height-sm: $line-height-sm !default;
$input-btn-padding-y-lg: .5rem !default;
$input-btn-padding-x-lg: 1rem !default;
$input-btn-line-height-lg: $line-height-lg !default;
$input-btn-border-width: $border-width !default;
// Buttons
//
// For each of Bootstrap's buttons, define text, background, and border color.
$btn-padding-y: $input-btn-padding-y !default;
$btn-padding-x: $input-btn-padding-x !default;
$btn-line-height: $input-btn-line-height !default;
$btn-padding-y-sm: $input-btn-padding-y-sm !default;
$btn-padding-x-sm: $input-btn-padding-x-sm !default;
$btn-line-height-sm: $input-btn-line-height-sm !default;
$btn-padding-y-lg: $input-btn-padding-y-lg !default;
$btn-padding-x-lg: $input-btn-padding-x-lg !default;
$btn-line-height-lg: $input-btn-line-height-lg !default;
$btn-border-width: $input-btn-border-width !default;
$btn-font-weight: $font-weight-normal !default;
$btn-box-shadow: none !default;
$btn-focus-width: 0 !default;
$btn-focus-box-shadow: none !default;
$btn-disabled-opacity: .65 !default;
$btn-active-box-shadow: none !default;
$btn-link-disabled-color: $gray-600 !default;
$btn-block-spacing-y: .5rem !default;
// Allows for customizing button radius independently from global border radius
$btn-border-radius: $border-radius !default;
$btn-border-radius-lg: $border-radius-lg !default;
$btn-border-radius-sm: $border-radius-sm !default;
$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
// Forms
$input-padding-y: $input-btn-padding-y !default;
$input-padding-x: $input-btn-padding-x !default;
$input-line-height: $input-btn-line-height !default;
$input-padding-y-sm: $input-btn-padding-y-sm !default;
$input-padding-x-sm: $input-btn-padding-x-sm !default;
$input-line-height-sm: $input-btn-line-height-sm !default;
$input-padding-y-lg: $input-btn-padding-y-lg !default;
$input-padding-x-lg: $input-btn-padding-x-lg !default;
$input-line-height-lg: $input-btn-line-height-lg !default;
$input-bg: $white !default;
$input-disabled-bg: $gray-200 !default;
$input-color: $gray-700 !default;
$input-border-color: $gray-400 !default;
$input-border-width: $input-btn-border-width !default;
$input-box-shadow: inset 0 0 0 rgba($black, 0) !default;
$input-border-radius: $border-radius !default;
$input-border-radius-lg: $border-radius-lg !default;
$input-border-radius-sm: $border-radius-sm !default;
$input-focus-bg: $input-bg !default;
$input-focus-border-color: lighten($component-active-bg, 25%) !default;
$input-focus-color: $input-color !default;
$input-focus-width: 0 !default;
$input-focus-box-shadow: none !default;
$input-placeholder-color: lighten($gray-600, 15%) !default;
$input-height-border: $input-border-width * 2 !default;
$input-height-inner: ($font-size-base * $input-btn-line-height) + ($input-btn-padding-y * 2) !default;
$input-height-inner-half: calc(#{$input-line-height * .5em} + #{$input-padding-y}) !default;
$input-height-inner-quarter: calc(#{$input-line-height * .25em} + #{$input-padding-y * .5}) !default;
$input-height: calc(#{$input-height-inner} + #{$input-height-border}) !default;
$input-height-inner-sm: ($font-size-sm * $input-btn-line-height-sm) + ($input-btn-padding-y-sm * 2) !default;
$input-height-sm: calc(#{$input-height-inner-sm} + #{$input-height-border}) !default;
$input-height-inner-lg: ($font-size-lg * $input-btn-line-height-lg) + ($input-btn-padding-y-lg * 2) !default;
$input-height-lg: calc(#{$input-height-inner-lg} + #{$input-height-border}) !default;
$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
$form-text-margin-top: .25rem !default;
$form-check-input-gutter: 1.25rem !default;
$form-check-input-margin-y: .3rem !default;
$form-check-input-margin-x: .25rem !default;
$form-check-inline-margin-x: .75rem !default;
$form-check-inline-input-margin-x: .3125rem !default;
$form-group-margin-bottom: 1rem !default;
$input-group-addon-color: $input-color !default;
$input-group-addon-bg: $gray-200 !default;
$input-group-addon-border-color: $input-border-color !default;
$custom-control-gutter: .5rem !default;
$custom-control-spacer-x: 1rem !default;
$custom-control-indicator-size: 1rem !default;
$custom-control-indicator-bg: $gray-300 !default;
$custom-control-indicator-bg-size: 50% 50% !default;
$custom-control-indicator-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;
$custom-control-indicator-disabled-bg: $gray-200 !default;
$custom-control-label-disabled-color: $gray-600 !default;
$custom-control-indicator-checked-color: $component-active-color !default;
$custom-control-indicator-checked-bg: $component-active-bg !default;
$custom-control-indicator-checked-disabled-bg: rgba(theme-color("primary"), .5) !default;
$custom-control-indicator-checked-box-shadow: none !default;
$custom-control-indicator-focus-box-shadow: 0 0 0 1px $body-bg, $input-btn-focus-box-shadow !default;
$custom-control-indicator-active-color: $component-active-color !default;
$custom-control-indicator-active-bg: lighten($component-active-bg, 35%) !default;
$custom-control-indicator-active-box-shadow: none !default;
$custom-checkbox-indicator-border-radius: $border-radius !default;
$custom-checkbox-indicator-icon-checked: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"), "#", "%23") !default;
$custom-checkbox-indicator-indeterminate-bg: $component-active-bg !default;
$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;
$custom-checkbox-indicator-icon-indeterminate: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3E%3C/svg%3E"), "#", "%23") !default;
$custom-checkbox-indicator-indeterminate-box-shadow: none !default;
$custom-radio-indicator-border-radius: 50% !default;
$custom-radio-indicator-icon-checked: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3E%3C/svg%3E"), "#", "%23") !default;
$custom-select-padding-y: .375rem !default;
$custom-select-padding-x: .75rem !default;
$custom-select-height: $input-height !default;
$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator
$custom-select-line-height: $input-btn-line-height !default;
$custom-select-color: $input-color !default;
$custom-select-disabled-color: $gray-600 !default;
$custom-select-bg: $white !default;
$custom-select-disabled-bg: $gray-200 !default;
$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions
$custom-select-indicator-color: $gray-800 !default;
$custom-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>") !default;
$custom-select-background: escape-svg($custom-select-indicator) right $custom-select-padding-x center / $custom-select-bg-size no-repeat !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
$custom-select-border-width: $input-btn-border-width !default;
$custom-select-border-color: $input-border-color !default;
$custom-select-border-radius: $border-radius !default;
$custom-select-focus-border-color: $input-focus-border-color !default;
$custom-select-focus-box-shadow: none !default;
$custom-select-font-size-sm: 75% !default;
$custom-select-height-sm: $input-height-sm !default;
$custom-select-font-size-lg: 125% !default;
$custom-select-height-lg: $input-height-lg !default;
$custom-file-height: $input-height !default;
$custom-file-focus-border-color: $input-focus-border-color !default;
$custom-file-focus-box-shadow: $custom-select-focus-box-shadow !default;
$custom-file-padding-y: $input-btn-padding-y !default;
$custom-file-padding-x: $input-btn-padding-x !default;
$custom-file-line-height: $input-btn-line-height !default;
$custom-file-color: $input-color !default;
$custom-file-bg: $input-bg !default;
$custom-file-border-width: $input-btn-border-width !default;
$custom-file-border-color: $input-border-color !default;
$custom-file-border-radius: $input-border-radius !default;
$custom-file-box-shadow: $custom-select-focus-box-shadow !default;
$custom-file-button-color: $custom-file-color !default;
$custom-file-button-bg: $input-group-addon-bg !default;
$custom-file-text: (
en: "Browse"
) !default;
$custom-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-btn-focus-box-shadow !default;
// Form validation
$form-feedback-margin-top: $form-text-margin-top !default;
$form-feedback-font-size: $small-font-size !default;
$form-feedback-valid-color: theme-color("success") !default;
$form-feedback-invalid-color: theme-color("danger") !default;
// Dropdowns
//
// Dropdown menu container and contents.
$dropdown-min-width: 10rem !default;
$dropdown-padding-y: .5rem !default;
$dropdown-spacer: .125rem !default;
$dropdown-bg: $white !default;
$dropdown-border-color: rgba($black, .15) !default;
$dropdown-border-radius: $border-radius !default;
$dropdown-border-width: $border-width !default;
$dropdown-divider-bg: $gray-200 !default;
$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;
$dropdown-link-color: $gray-900 !default;
$dropdown-link-hover-color: darken($gray-900, 5%) !default;
$dropdown-link-hover-bg: $gray-100 !default;
$dropdown-link-active-color: $component-active-color !default;
$dropdown-link-active-bg: $component-active-bg !default;
$dropdown-link-disabled-color: $gray-600 !default;
$dropdown-item-padding-y: .25rem !default;
$dropdown-item-padding-x: 1rem !default;
$dropdown-header-color: $gray-600 !default;
// Z-index master list
//
// Warning: Avoid customizing these values. They're used for a bird's eye view
// of components dependent on the z-axis and are designed to all work together.
$zindex-dropdown: 1000 !default;
$zindex-sticky: 1020 !default;
$zindex-fixed: 1030 !default;
$zindex-modal-backdrop: 1040 !default;
$zindex-modal: 1050 !default;
$zindex-popover: 1060 !default;
$zindex-tooltip: 1070 !default;
// Navs
$nav-link-padding-y: .5rem !default;
$nav-link-padding-x: 1rem !default;
$nav-link-disabled-color: $gray-600 !default;
$nav-tabs-border-color: $gray-300 !default;
$nav-tabs-border-width: $border-width !default;
$nav-tabs-border-radius: $border-radius !default;
$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;
$nav-tabs-link-active-color: $gray-700 !default;
$nav-tabs-link-active-bg: $body-bg !default;
$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;
$nav-pills-border-radius: $border-radius !default;
$nav-pills-link-active-color: $component-active-color !default;
$nav-pills-link-active-bg: $component-active-bg !default;
// Navbar
$navbar-padding-y: ($spacer * .5) !default;
$navbar-padding-x: ($spacer * .5) !default;
$navbar-nav-link-padding-x: 1rem !default;
$navbar-brand-font-size: $font-size-lg !default;
// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link
$nav-link-height: ($font-size-base * $line-height-base + $nav-link-padding-y * 2) !default;
$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;
$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) * .5 !default;
$navbar-toggler-padding-y: .25rem !default;
$navbar-toggler-padding-x: .75rem !default;
$navbar-toggler-font-size: $font-size-lg !default;
$navbar-toggler-border-radius: $btn-border-radius !default;
$navbar-dark-color: rgba($white, .75) !default;
$navbar-dark-hover-color: rgba($white, 1) !default;
$navbar-dark-active-color: $white !default;
$navbar-dark-disabled-color: rgba($white, .25) !default;
$navbar-dark-toggler-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default;
$navbar-dark-toggler-border-color: rgba($white, .1) !default;
$navbar-light-color: rgba($black, .5) !default;
$navbar-light-hover-color: rgba($black, .7) !default;
$navbar-light-active-color: rgba($black, .9) !default;
$navbar-light-disabled-color: rgba($black, .3) !default;
$navbar-light-toggler-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default;
$navbar-light-toggler-border-color: rgba($black, .1) !default;
// Pagination
$pagination-padding-y: .5rem !default;
$pagination-padding-x: .75rem !default;
$pagination-padding-y-sm: .25rem !default;
$pagination-padding-x-sm: .5rem !default;
$pagination-padding-y-lg: .75rem !default;
$pagination-padding-x-lg: 1.5rem !default;
$pagination-line-height: 1.25 !default;
$pagination-color: $link-color !default;
$pagination-bg: $white !default;
$pagination-border-width: $border-width !default;
$pagination-border-color: $gray-300 !default;
$pagination-focus-box-shadow: $input-btn-focus-box-shadow !default;
$pagination-hover-color: $link-hover-color !default;
$pagination-hover-bg: $gray-200 !default;
$pagination-hover-border-color: $gray-300 !default;
$pagination-active-color: $component-active-color !default;
$pagination-active-bg: $component-active-bg !default;
$pagination-active-border-color: $pagination-active-bg !default;
$pagination-disabled-color: $gray-600 !default;
$pagination-disabled-bg: $white !default;
$pagination-disabled-border-color: $gray-300 !default;
// Jumbotron
$jumbotron-padding: 2rem !default;
$jumbotron-bg: $gray-200 !default;
// Cards
$card-spacer-y: .75rem !default;
$card-spacer-x: 1.25rem !default;
$card-border-width: 0 !default; //$border-width !default;
$card-border-radius: $border-radius !default;
$card-border-color: rgba($black, .125) !default;
$card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width}) !default;
$card-cap-bg: rgba($black, .03) !default;
$card-bg: $white !default;
$card-img-overlay-padding: 1.25rem !default;
$card-group-margin: ($grid-gutter-width * .5) !default;
$card-deck-margin: $card-group-margin !default;
$card-columns-count: 3 !default;
$card-columns-gap: 1.25rem !default;
$card-columns-margin: $card-spacer-y !default;
// Tooltips
$tooltip-font-size: $font-size-sm !default;
$tooltip-max-width: 200px !default;
$tooltip-color: $white !default;
$tooltip-bg: $black !default;
$tooltip-border-radius: $border-radius !default;
$tooltip-opacity: .9 !default;
$tooltip-padding-y: .25rem !default;
$tooltip-padding-x: .5rem !default;
$tooltip-margin: 0 !default;
$tooltip-arrow-width: .8rem !default;
$tooltip-arrow-height: .4rem !default;
$tooltip-arrow-color: $tooltip-bg !default;
// Form tooltips must come after regular tooltips
$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;
$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;
$form-feedback-tooltip-font-size: $tooltip-font-size !default;
$form-feedback-tooltip-line-height: $line-height-base !default;
$form-feedback-tooltip-opacity: $tooltip-opacity !default;
$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;
// Popovers
$popover-font-size: $font-size-sm !default;
$popover-bg: $white !default;
$popover-max-width: 276px !default;
$popover-border-width: $border-width !default;
$popover-border-color: rgba($black, .2) !default;
$popover-border-radius: $border-radius-lg !default;
$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;
$popover-header-bg: darken($popover-bg, 3%) !default;
$popover-header-color: $headings-color !default;
$popover-header-padding-y: .5rem !default;
$popover-header-padding-x: .75rem !default;
$popover-body-color: $body-color !default;
$popover-body-padding-y: $popover-header-padding-y !default;
$popover-body-padding-x: $popover-header-padding-x !default;
$popover-arrow-width: 1rem !default;
$popover-arrow-height: .5rem !default;
$popover-arrow-color: $popover-bg !default;
$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;
// Badges
$badge-font-size: 75% !default;
$badge-font-weight: $font-weight-bold !default;
$badge-padding-y: .25em !default;
$badge-padding-x: .4em !default;
$badge-border-radius: $border-radius !default;
$badge-pill-padding-x: .6em !default;
// Use a higher than normal value to ensure completely rounded edges when
// customizing padding or font-size on labels.
$badge-pill-border-radius: 10rem !default;
// Modals
// Padding applied to the modal body
$modal-inner-padding: 1rem !default;
$modal-dialog-margin: .5rem !default;
$modal-dialog-margin-y-sm-up: 1.75rem !default;
$modal-title-line-height: $line-height-base !default;
$modal-content-bg: $white !default;
$modal-content-border-color: rgba($black, .2) !default;
$modal-content-border-width: $border-width !default;
$modal-content-border-radius: $border-radius-lg !default;
$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;
$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;
$modal-backdrop-bg: $black !default;
$modal-backdrop-opacity: .5 !default;
$modal-header-border-color: $gray-200 !default;
$modal-footer-border-color: $modal-header-border-color !default;
$modal-header-border-width: $modal-content-border-width !default;
$modal-footer-border-width: $modal-header-border-width !default;
$modal-header-padding: 1rem !default;
$modal-lg: 800px !default;
$modal-md: 500px !default;
$modal-sm: 300px !default;
$modal-transition: transform .3s ease-out !default;
// Alerts
//
// Define alert colors, border radius, and padding.
$alert-padding-y: .75rem !default;
$alert-padding-x: 1.25rem !default;
$alert-margin-bottom: 1rem !default;
$alert-border-radius: $border-radius !default;
$alert-link-font-weight: $font-weight-bold !default;
$alert-border-width: $border-width !default;
$alert-bg-level: -10 !default;
$alert-border-level: -9 !default;
$alert-color-level: 6 !default;
// Progress bars
$progress-height: 1rem !default;
$progress-font-size: ($font-size-base * .75) !default;
$progress-bg: $gray-200 !default;
$progress-border-radius: $border-radius !default;
$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;
$progress-bar-color: $white !default;
$progress-bar-bg: theme-color("primary") !default;
$progress-bar-animation-timing: 1s linear infinite !default;
$progress-bar-transition: width .6s ease !default;
// List group
$list-group-bg: $white !default;
$list-group-border-color: rgba($black, .125) !default;
$list-group-border-width: $border-width !default;
$list-group-border-radius: $border-radius !default;
$list-group-item-padding-y: .75rem !default;
$list-group-item-padding-x: 1.25rem !default;
$list-group-hover-bg: $gray-100 !default;
$list-group-active-color: $component-active-color !default;
$list-group-active-bg: $component-active-bg !default;
$list-group-active-border-color: $list-group-active-bg !default;
$list-group-disabled-color: $gray-600 !default;
$list-group-disabled-bg: $list-group-bg !default;
$list-group-action-color: $gray-700 !default;
$list-group-action-hover-color: $list-group-action-color !default;
$list-group-action-active-color: $body-color !default;
$list-group-action-active-bg: $gray-200 !default;
// Image thumbnails
$thumbnail-padding: .25rem !default;
$thumbnail-bg: $body-bg !default;
$thumbnail-border-width: $border-width !default;
$thumbnail-border-color: $gray-300 !default;
$thumbnail-border-radius: $border-radius !default;
$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;
// Figures
$figure-caption-font-size: 90% !default;
$figure-caption-color: $gray-600 !default;
// Breadcrumbs
$breadcrumb-padding-y: .75rem !default;
$breadcrumb-padding-x: 1rem !default;
$breadcrumb-item-padding: .5rem !default;
$breadcrumb-margin-bottom: 1rem !default;
$breadcrumb-bg: $gray-200 !default;
$breadcrumb-divider-color: $gray-600 !default;
$breadcrumb-active-color: $gray-600 !default;
$breadcrumb-divider: "/" !default;
// Carousel
$carousel-control-color: $white !default;
$carousel-control-width: 15% !default;
$carousel-control-opacity: .5 !default;
$carousel-indicator-width: 30px !default;
$carousel-indicator-height: 3px !default;
$carousel-indicator-spacer: 3px !default;
$carousel-indicator-active-bg: $white !default;
$carousel-caption-width: 70% !default;
$carousel-caption-color: $white !default;
$carousel-control-icon-width: 20px !default;
$carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"), "#", "%23") !default;
$carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"), "#", "%23") !default;
$carousel-transition: transform .6s ease !default;
// Close
$close-font-size: $font-size-base * 1.5 !default;
$close-font-weight: $font-weight-bold !default;
$close-color: $black !default;
$close-text-shadow: 0 1px 0 $white !default;
// Code
$code-font-size: 87.5% !default;
$code-color: $pink !default;
$kbd-padding-y: .2rem !default;
$kbd-padding-x: .4rem !default;
$kbd-font-size: $code-font-size !default;
$kbd-color: $white !default;
$kbd-bg: $gray-900 !default;
$pre-color: $gray-900 !default;
$pre-scrollable-max-height: 340px !default;
// Printing
$print-page-size: a3 !default;
$print-body-min-width: map-get($grid-breakpoints, "lg") !default;

View File

@ -0,0 +1,106 @@
//
// Component: Brand
//
.brand-link {
$brand-link-padding-y: $navbar-brand-padding-y + $navbar-padding-y;
display: block;
font-size: $navbar-brand-font-size;
line-height: $line-height-lg;
padding: $brand-link-padding-y $sidebar-padding-x;
transition: width $transition-speed $transition-fn;
white-space: nowrap;
&:hover {
color: $white;
text-decoration: none;
}
.text-sm & {
font-size: inherit;
}
[class*="sidebar-dark"] & {
border-bottom: 1px solid lighten($dark, 10%);
&,
.pushmenu {
color: rgba($white, .8);
&:hover {
color: $white;
}
}
}
[class*="sidebar-light"] & {
border-bottom: 1px solid $gray-300;
&,
.pushmenu {
color: rgba($black, .8);
&:hover {
color: $black;
}
}
}
.pushmenu {
margin-right: $sidebar-padding-x;
font-size: $font-size-base;
}
.brand-link {
padding: 0;
border-bottom: none;
}
.brand-image {
float: left;
line-height: .8;
margin-left: .8rem;
margin-right: .5rem;
margin-top: -3px;
max-height: 33px;
width: auto;
}
.brand-image-xs {
float: left;
line-height: .8;
margin-top: -.1rem;
max-height: 33px;
width: auto;
}
.brand-image-xl {
line-height: .8;
max-height: 40px;
width: auto;
&.single {
margin-top: -.3rem;
}
}
&.text-sm,
.text-sm & {
.brand-image {
height: 29px;
margin-bottom: -.25rem;
margin-left: .95rem;
margin-top: -.25rem;
}
.brand-image-xs {
margin-top: -.2rem;
max-height: 29px;
}
.brand-image-xl {
margin-top: -.225rem;
max-height: 38px;
}
}
}

View File

@ -0,0 +1,179 @@
//
// Component: Button
//
.btn {
&.disabled,
&:disabled {
cursor: not-allowed;
}
// Flat buttons
&.btn-flat {
@include border-radius(0);
border-width: 1px;
box-shadow: none;
}
// input file btn
&.btn-file {
overflow: hidden;
position: relative;
> input[type="file"] {
background-color: $white;
cursor: inherit;
display: block;
font-size: 100px;
min-height: 100%;
min-width: 100%;
opacity: 0;
outline: none;
position: absolute;
right: 0;
text-align: right;
top: 0;
}
}
.text-sm & {
font-size: $font-size-sm !important;
}
}
// Button color variations
.btn-default {
background-color: $button-default-background-color;
border-color: $button-default-border-color;
color: $button-default-color;
&:hover,
&:active,
&.hover {
background-color: darken($button-default-background-color, 5%);
color: darken($button-default-color, 10%);
}
&.disabled,
&:disabled {
color: $button-default-color;
background-color: $button-default-background-color;
}
}
.btn-outline-light {
color: darken($light, 20%);
border-color: darken($light, 20%);
&.disabled,
&:disabled {
color: darken($light, 20%);
border-color: darken($light, 20%);
}
}
// Application buttons
.btn-app {
@include border-radius(3px);
background-color: $button-default-background-color;
border: 1px solid $button-default-border-color;
color: $gray-600;
font-size: 12px;
height: 60px;
margin: 0 0 10px 10px;
min-width: 80px;
padding: 15px 5px;
position: relative;
text-align: center;
// Icons within the btn
> .fa,
> .fas,
> .far,
> .fab,
> .fal,
> .fad,
> .svg-inline--fa,
> .ion {
display: block;
font-size: 20px;
}
> .svg-inline--fa {
margin: 0 auto;
}
&:hover {
background-color: $button-default-background-color;
border-color: darken($button-default-border-color, 20%);
color: $button-default-color;
}
&:active,
&:focus {
@include box-shadow(inset 0 3px 5px rgba($black, .125));
}
// The badge
> .badge {
font-size: 10px;
font-weight: 400;
position: absolute;
right: -10px;
top: -3px;
}
}
// Extra Button Size
.btn-xs {
@include button-size($button-padding-y-xs, $button-padding-x-xs, $button-font-size-xs, $button-line-height-xs, $button-border-radius-xs);
}
@include dark-mode () {
.btn-default,
.btn-app {
background-color: lighten($dark, 2.5%);
color: $white;
border-color: $gray-600;
&:hover,
&:focus {
background-color: lighten($dark, 5%);
color: $gray-300;
border-color: lighten($gray-600, 2.5%);
}
}
.btn-light {
background-color: lighten($dark, 7.5%);
color: $white;
border-color: $gray-600;
&:hover,
&:focus {
background-color: lighten($dark, 10%);
color: $gray-300;
border-color: lighten($gray-600, 5%);
}
}
@each $color, $value in $theme-colors-alt {
.btn-#{$color} {
@if $color == dark {
@include button-variant(darken($value, 5%), lighten($value, 10%));
} @else {
@include button-variant($value, $value);
}
}
}
@each $color, $value in $theme-colors-alt {
.btn-outline-#{$color} {
@if $color == dark {
@include button-outline-variant(darken($value, 20%));
} @else {
@include button-outline-variant($value);
}
}
}
}

View File

@ -0,0 +1,73 @@
//
// Component: Callout
//
// Base styles (regardless of theme)
.callout {
@if $enable-rounded {
@include border-radius($border-radius);
}
@if $enable-shadows {
box-shadow: map-get($elevations, 1);
} @else {
border: 1px solid $gray-300;
}
background-color: $white;
border-left: 5px solid $gray-200;
margin-bottom: map-get($spacers, 3);
padding: 1rem;
a {
color: $gray-700;
text-decoration: underline;
&:hover {
color: $gray-200;
}
}
p:last-child {
margin-bottom: 0;
}
// Themes for different contexts
&.callout-danger {
border-left-color: darken(theme-color("danger"), 10%);
}
&.callout-warning {
border-left-color: darken(theme-color("warning"), 10%);
}
&.callout-info {
border-left-color: darken(theme-color("info"), 10%);
}
&.callout-success {
border-left-color: darken(theme-color("success"), 10%);
}
}
@include dark-mode () {
.callout {
background-color: lighten($dark, 5%);
&.callout-danger {
border-left-color: lighten($danger-alt, 10%);
}
&.callout-warning {
border-left-color: lighten($warning-alt, 10%);
}
&.callout-info {
border-left-color: lighten($info-alt, 10%);
}
&.callout-success {
border-left-color: lighten($success-alt, 10%);
}
}
}

View File

@ -0,0 +1,548 @@
//
// Component: Cards
//
// Color variants
@each $name, $color in $theme-colors {
@include cards-variant($name, $color);
}
@each $name, $color in $colors {
@include cards-variant($name, $color);
}
.card {
@include box-shadow($card-shadow);
margin-bottom: map-get($spacers, 3);
&.bg-dark {
.card-header {
border-color: $card-dark-border-color;
}
&,
.card-body {
color: $white;
}
}
&.maximized-card {
height: 100% !important;
left: 0;
max-height: 100% !important;
max-width: 100% !important;
position: fixed;
top: 0;
width: 100% !important;
z-index: $zindex-modal-backdrop;
&.was-collapsed .card-body {
display: block !important;
}
.card-body {
overflow: auto;
}
[data-card-widgett="collapse"] {
display: none;
}
.card-header,
.card-footer {
@include border-radius(0 !important);
}
}
// collapsed mode
&.collapsed-card {
.card-body,
.card-footer {
display: none;
}
}
.nav.flex-column:not(.nav-sidebar) {
> li {
border-bottom: 1px solid $card-border-color;
margin: 0;
&:last-of-type {
border-bottom: 0;
}
}
}
// fixed height to 300px
&.height-control {
.card-body {
max-height: 300px;
overflow: auto;
}
}
.border-right {
border-right: 1px solid $card-border-color;
}
.border-left {
border-left: 1px solid $card-border-color;
}
&.card-tabs {
&:not(.card-outline) {
> .card-header {
border-bottom: 0;
.nav-item {
&:first-child .nav-link {
border-left-color: transparent;
}
}
}
}
&.card-outline {
.nav-item {
border-bottom: 0;
&:first-child .nav-link {
border-left: 0;
margin-left: 0;
}
}
}
.card-tools {
margin: .3rem .5rem;
}
&:not(.expanding-card).collapsed-card {
.card-header {
border-bottom: 0;
.nav-tabs {
border-bottom: 0;
.nav-item {
margin-bottom: 0;
}
}
}
}
&.expanding-card {
.card-header {
.nav-tabs {
.nav-item {
margin-bottom: -1px;
}
}
}
}
}
&.card-outline-tabs {
border-top: 0;
.card-header {
.nav-item {
&:first-child .nav-link {
border-left: 0;
margin-left: 0;
}
}
a {
border-top: 3px solid transparent;
&:hover {
border-top: 3px solid $nav-tabs-border-color;
}
&.active {
&:hover {
margin-top: 0;
}
}
}
}
.card-tools {
margin: .5rem .5rem .3rem;
}
&:not(.expanding-card).collapsed-card .card-header {
border-bottom: 0;
.nav-tabs {
border-bottom: 0;
.nav-item {
margin-bottom: 0;
}
}
}
&.expanding-card {
.card-header {
.nav-tabs {
.nav-item {
margin-bottom: -1px;
}
}
}
}
}
}
// Maximized Card Body Scroll fix
html.maximized-card {
overflow: hidden;
}
// Add clearfix to header, body and footer
.card-header,
.card-body,
.card-footer {
@include clearfix ();
}
// Box header
.card-header {
background-color: transparent;
border-bottom: 1px solid $card-border-color;
padding: (($card-spacer-y * .5) * 2) $card-spacer-x;
position: relative;
@if $enable-rounded {
@include border-top-radius($border-radius);
}
.collapsed-card & {
border-bottom: 0;
}
> .card-tools {
float: right;
margin-right: -$card-spacer-x * .5;
.input-group,
.nav,
.pagination {
margin-bottom: -$card-spacer-y * .4;
margin-top: -$card-spacer-y * .4;
}
[data-toggle="tooltip"] {
position: relative;
}
}
}
.card-title {
float: left;
font-size: $card-title-font-size;
font-weight: $card-title-font-weight;
margin: 0;
}
.card-text {
clear: both;
}
// Box Tools Buttons
.btn-tool {
background-color: transparent;
color: $gray-500;
font-size: $font-size-sm;
margin: -(($card-spacer-y * .5) * 2) 0;
padding: .25rem .5rem;
.btn-group.show &,
&:hover {
color: $gray-700;
}
.show &,
&:focus {
box-shadow: none !important;
}
}
.text-sm {
.card-title {
font-size: $card-title-font-size-sm;
}
.nav-link {
padding: $card-nav-link-padding-sm-y $card-nav-link-padding-sm-x;
}
}
// Box Body
.card-body {
// @include border-radius-sides(0, 0, $border-radius, $border-radius);
// .no-header & {
// @include border-top-radius($border-radius);
// }
// Tables within the box body
> .table {
margin-bottom: 0;
> thead > tr > th,
> thead > tr > td {
border-top-width: 0;
}
}
// Calendar within the box body
.fc {
margin-top: 5px;
}
.full-width-chart {
margin: -19px;
}
&.p-0 .full-width-chart {
margin: -9px;
}
}
.chart-legend {
@include list-unstyled ();
margin: 10px 0;
> li {
@media (max-width: map-get($grid-breakpoints, sm)) {
float: left;
margin-right: 10px;
}
}
}
// Comment Box
.card-comments {
background-color: $gray-100;
.card-comment {
@include clearfix ();
border-bottom: 1px solid $gray-200;
padding: 8px 0;
&:last-of-type {
border-bottom: 0;
}
&:first-of-type {
padding-top: 0;
}
img {
height: $card-img-size;
width: $card-img-size;
float: left;
}
}
.comment-text {
color: lighten($gray-700, 20%);
margin-left: 40px;
}
.username {
color: $gray-700;
display: block;
font-weight: 600;
}
.text-muted {
font-size: 12px;
font-weight: 400;
}
}
// Widgets
//-----------
// Widget: TODO LIST
.todo-list {
list-style: none;
margin: 0;
overflow: auto;
padding: 0;
// Todo list element
> li {
@include border-radius(2px);
background-color: $gray-100;
border-left: 2px solid $gray-200;
color: $gray-700;
margin-bottom: 2px;
padding: 10px;
&:last-of-type {
margin-bottom: 0;
}
> input[type="checkbox"] {
margin: 0 10px 0 5px;
}
.text {
display: inline-block;
font-weight: 600;
margin-left: 5px;
}
// Time labels
.badge {
font-size: .7rem;
margin-left: 10px;
}
// Tools and options box
.tools {
color: theme-color("danger");
display: none;
float: right;
// icons
> .fa,
> .fas,
> .far,
> .fab,
> .fal,
> .fad,
> .svg-inline--fa,
> .ion {
cursor: pointer;
margin-right: 5px;
}
}
&:hover .tools {
display: inline-block;
}
&.done {
color: darken($gray-500, 25%);
.text {
font-weight: 500;
text-decoration: line-through;
}
.badge {
background-color: $gray-500 !important;
}
}
}
// Color variants
@each $name, $color in $theme-colors {
.#{$name} {
border-left-color: $color;
}
}
@each $name, $color in $colors {
.#{$name} {
border-left-color: $color;
}
}
.handle {
cursor: move;
display: inline-block;
margin: 0 5px;
}
}
// END TODO WIDGET
// Input in box
.card-input {
max-width: 200px;
}
// Nav Tabs override
.card-default {
.nav-item {
&:first-child .nav-link {
border-left: 0;
}
}
}
@include dark-mode () {
// Color variants
@each $name, $color in $theme-colors-alt {
@include cards-variant($name, $color);
}
@each $name, $color in $colors-alt {
@include cards-variant($name, $color);
}
.card {
background-color: $dark;
color: $white;
.card {
background-color: lighten($dark, 5%);
color: $white;
}
.nav.flex-column > li {
border-bottom-color: $gray-600;
}
.card-footer {
background-color: rgba($black, .1);
}
&.card-outline-tabs {
border-top: 0;
}
&.card-outline-tabs .card-header a:hover {
border-top-color: $gray-600;
border-bottom-color: transparent;
}
&:not(.card-outline) > .card-header a.active {
color: $white;
}
}
.card-comments {
background-color: lighten($dark, 1.25%);
.username {
color: $gray-400;
}
.card-comment {
border-bottom-color: lighten($dark, 7.5%);
}
}
.todo-list > li {
background-color: lighten($dark, 5%);
border-color: lighten($dark, 7.5%);
color: $white;
}
.todo-list {
@each $name, $color in $theme-colors-alt {
.#{$name} {
border-left-color: $color;
}
}
@each $name, $color in $colors-alt {
.#{$name} {
border-left-color: $color;
}
}
}
}

View File

@ -0,0 +1,28 @@
//
// Component: Carousel
//
.carousel-control-custom-icon {
.carousel-control-prev & {
margin-left: -20px;
}
.carousel-control-next & {
margin-right: 20px;
}
> .fa,
> .fas,
> .far,
> .fab,
> .fal,
> .fad,
> .svg-inline--fa,
> .ion {
display: inline-block;
font-size: 40px;
margin-top: -20px;
position: absolute;
top: 50%;
z-index: 5;
}
}

View File

@ -0,0 +1,44 @@
.close {
float: right;
@include font-size($close-font-size);
font-weight: $close-font-weight;
line-height: 1;
color: $close-color;
text-shadow: $close-text-shadow;
opacity: .5;
// Override <a>'s hover style
@include hover() {
color: $close-color;
text-decoration: none;
}
&:not(:disabled):not(.disabled) {
@include hover-focus() {
opacity: .75;
}
}
&:focus {
outline: none;
}
}
// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
// stylelint-disable-next-line selector-no-qualifying-type
button.close {
padding: 0;
background-color: transparent;
border: 0;
}
// Future-proof disabling of clicks on `<a>` elements
// stylelint-disable-next-line selector-no-qualifying-type
a.close.disabled {
pointer-events: none;
}

View File

@ -0,0 +1,163 @@
//
// Misc: Colors
//
// Background colors (theme colors)
@each $name, $color in $theme-colors {
@include background-variant($name, $color);
}
// Background colors (colors)
@each $name, $color in $colors {
@include background-variant($name, $color);
}
@media print {
.table td,
.table th {
// Background colors (theme colors)
@each $name, $color in $theme-colors {
@include background-variant($name, $color);
}
// Background colors (colors)
@each $name, $color in $colors {
@include background-variant($name, $color);
}
}
}
.bg-gray {
background-color: $gray-500;
color: color-yiq($gray-500);
}
.bg-gray-light {
background-color: lighten($gray-200, 3%);
color: color-yiq(lighten($gray-200, 3%)) !important;
}
.bg-black {
background-color: $black;
color: color-yiq($black) !important;
}
.bg-white {
background-color: $white;
color: color-yiq($white) !important;
}
// Gradient Background colors (theme colors)
@each $name, $color in $theme-colors {
@include background-gradient-variant($name, $color);
}
// Gradient Background colors (colors)
@each $name, $color in $colors {
@include background-gradient-variant($name, $color);
}
// Backgrund Color Disabled
[class^="bg-"].disabled {
opacity: .65;
}
// Text muted hover
a.text-muted:hover {
color: theme-color(primary) !important;
}
// Link Styles
.link-muted {
color: darken($gray-500, 30%);
&:hover,
&:focus {
color: darken($gray-500, 40%);
}
}
.link-black {
color: $gray-600;
&:hover,
&:focus {
color: lighten($gray-500, 20%);
}
}
// Accent colors (theme colors)
@each $name, $color in $theme-colors {
@include accent-variant($name, $color);
}
// Accent colors (colors)
@each $name, $color in $colors {
@include accent-variant($name, $color);
}
// Accent button override fix
[class*="accent-"] {
@each $name, $color in $theme-colors {
a.btn-#{$name} {
color: color-yiq($color);
}
}
}
@include dark-mode () {
.bg-light {
background-color: lighten($dark, 7.5%) !important;
color: $white !important;
}
.text-black,
.text-dark,
.link-black,
.link-dark {
color: $gray-400 !important;
}
// Background colors (theme colors)
@each $name, $color in $theme-colors-alt {
@include background-variant($name, $color);
}
// Background colors (colors)
@each $name, $color in $colors-alt {
@include background-variant($name, $color);
}
// Gradient Background colors (theme colors)
@each $name, $color in $theme-colors-alt {
@include background-gradient-variant($name, $color);
}
// Gradient Background colors (colors)
@each $name, $color in $colors-alt {
@include background-gradient-variant($name, $color);
}
// Accent colors (theme colors)
@each $name, $color in $theme-colors-alt {
@include accent-variant($name, $color);
}
[class*="accent-"] {
@each $name, $color in $theme-colors-alt {
a.btn-#{$name} {
color: color-yiq($color);
}
}
}
// Accent colors (colors)
@each $name, $color in $colors-alt {
@include accent-variant($name, $color);
}
.border-dark {
border-color: lighten($dark, 10%) !important;
}
}
//

View File

@ -0,0 +1,179 @@
//
// Component: Control Sidebar
//
html.control-sidebar-animate {
overflow-x: hidden;
}
.control-sidebar {
bottom: $main-footer-height;
position: absolute;
top: $main-header-height;
z-index: $zindex-control-sidebar;
&,
&::before {
bottom: $main-footer-height;
display: none;
right: -$control-sidebar-width;
width: $control-sidebar-width;
@include transition(
right $transition-speed $transition-fn,
display $transition-speed $transition-fn
);
}
&::before {
content: "";
display: block;
position: fixed;
top: 0;
z-index: -1;
}
}
body.text-sm {
.control-sidebar {
bottom: $main-footer-height-sm;
top: $main-header-height-sm;
}
}
.main-header.text-sm ~ .control-sidebar {
top: $main-header-height-sm;
}
.main-footer.text-sm ~ .control-sidebar {
bottom: $main-footer-height-sm;
}
.control-sidebar-push-slide {
.content-wrapper,
.main-footer {
@include transition(margin-right $transition-speed $transition-fn);
}
}
// Control sidebar open state
.control-sidebar-open {
.control-sidebar {
display: block !important;
&,
&::before {
right: 0;
}
}
&.control-sidebar-push,
&.control-sidebar-push-slide {
.content-wrapper,
.main-footer {
margin-right: $control-sidebar-width;
}
}
}
// Control sidebar slide over content state
.control-sidebar-slide-open {
.control-sidebar {
display: block;
&,
&::before {
right: 0;
@include transition(
right $transition-speed $transition-fn,
display $transition-speed $transition-fn
);
}
}
&.control-sidebar-push,
&.control-sidebar-push-slide {
.content-wrapper,
.main-footer {
margin-right: $control-sidebar-width;
}
}
}
// Dark skin
.control-sidebar-dark {
background-color: $sidebar-dark-bg;
&,
a,
.nav-link {
color: $sidebar-dark-color;
}
a:hover {
color: $sidebar-dark-hover-color;
}
// Headers and labels
h1,
h2,
h3,
h4,
h5,
h6,
label {
color: $sidebar-dark-hover-color;
}
// Tabs
.nav-tabs {
background-color: $sidebar-dark-hover-bg;
border-bottom: 0;
margin-bottom: 5px;
.nav-item {
margin: 0;
}
.nav-link {
border-radius: 0;
padding: 10px 20px;
position: relative;
text-align: center;
&,
&:hover,
&:active,
&:focus,
&.active {
border: 0;
}
&:hover,
&:active,
&:focus,
&.active {
border-bottom-color: transparent;
border-left-color: transparent;
border-top-color: transparent;
color: $sidebar-dark-hover-color;
}
&.active {
background-color: $sidebar-dark-bg;
}
}
}
.tab-pane {
padding: 10px 15px;
}
}
// Light skin
.control-sidebar-light {
color: lighten($sidebar-light-color, 10%);
// Background
background-color: $sidebar-light-bg;
border-left: $main-header-bottom-border;
}

View File

@ -0,0 +1,259 @@
//
// Component: Direct Chat
//
.direct-chat {
.card-body {
overflow-x: hidden;
padding: 0;
position: relative;
}
&.chat-pane-open {
.direct-chat-contacts {
@include translate(0, 0);
}
}
&.timestamp-light {
.direct-chat-timestamp {
color: lighten(color-yiq($yiq-text-light), 10%);
}
}
&.timestamp-dark {
.direct-chat-timestamp {
color: darken(color-yiq($yiq-text-dark), 20%);
}
}
}
.direct-chat-messages {
@include translate(0, 0);
height: 250px;
overflow: auto;
padding: 10px;
}
.direct-chat-msg,
.direct-chat-text {
display: block;
}
.direct-chat-msg {
@include clearfix ();
margin-bottom: 10px;
}
.direct-chat-messages,
.direct-chat-contacts {
transition: transform .5s ease-in-out;
}
.direct-chat-text {
@if $enable-rounded {
@include border-radius($border-radius-lg);
}
background-color: $direct-chat-default-msg-bg;
border: 1px solid $direct-chat-default-msg-border-color;
color: $direct-chat-default-font-color;
margin: 5px 0 0 50px;
padding: 5px 10px;
position: relative;
//Create the arrow
&::after,
&::before {
border: solid transparent;
border-right-color: $direct-chat-default-msg-border-color;
content: " ";
height: 0;
pointer-events: none;
position: absolute;
right: 100%;
top: 15px;
width: 0;
}
&::after {
border-width: 5px;
margin-top: -5px;
}
&::before {
border-width: 6px;
margin-top: -6px;
}
.right & {
margin-left: 0;
margin-right: 50px;
&::after,
&::before {
border-left-color: $direct-chat-default-msg-border-color;
border-right-color: transparent;
left: 100%;
right: auto;
}
}
}
.direct-chat-img {
@include border-radius(50%);
float: left;
height: 40px;
width: 40px;
.right & {
float: right;
}
}
.direct-chat-infos {
display: block;
font-size: $font-size-sm;
margin-bottom: 2px;
}
.direct-chat-name {
font-weight: 600;
}
.direct-chat-timestamp {
color: darken($gray-500, 25%);
}
//Direct chat contacts pane
.direct-chat-contacts-open {
.direct-chat-contacts {
@include translate(0, 0);
}
}
.direct-chat-contacts {
@include translate(101%, 0);
background-color: $dark;
bottom: 0;
color: $white;
height: 250px;
overflow: auto;
position: absolute;
top: 0;
width: 100%;
}
.direct-chat-contacts-light {
background-color: $light;
.contacts-list-name {
color: $gray-700;
}
.contacts-list-date {
color: $gray-600;
}
.contacts-list-msg {
color: darken($gray-600, 10%);
}
}
//Contacts list -- for displaying contacts in direct chat contacts pane
.contacts-list {
@include list-unstyled ();
> li {
@include clearfix ();
border-bottom: 1px solid rgba($black, .2);
margin: 0;
padding: 10px;
&:last-of-type {
border-bottom: 0;
}
}
}
.contacts-list-img {
@include border-radius(50%);
float: left;
width: 40px;
}
.contacts-list-info {
color: $white;
margin-left: 45px;
}
.contacts-list-name,
.contacts-list-status {
display: block;
}
.contacts-list-name {
font-weight: 600;
}
.contacts-list-status {
font-size: $font-size-sm;
}
.contacts-list-date {
color: $gray-400;
font-weight: 400;
}
.contacts-list-msg {
color: darken($gray-400, 10%);
}
// Color variants
@each $name, $color in $theme-colors {
.direct-chat-#{$name} {
@include direct-chat-variant($color);
}
}
@each $name, $color in $colors {
.direct-chat-#{$name} {
@include direct-chat-variant($color);
}
}
@include dark-mode () {
.direct-chat-text {
background-color: lighten($dark, 7.5%);
border-color: lighten($dark, 10%);
color: $white;
&::after,
&::before {
border-right-color: lighten($dark, 10%);
}
}
.direct-chat-timestamp {
color: $gray-500;
}
.right > .direct-chat-text {
&::after,
&::before {
border-right-color: transparent;
}
}
// Color variants
@each $name, $color in $theme-colors-alt {
.direct-chat-#{$name} {
@include direct-chat-variant($color);
}
}
@each $name, $color in $colors-alt {
.direct-chat-#{$name} {
@include direct-chat-variant($color);
}
}
}

View File

@ -0,0 +1,295 @@
//
// Component: Dropdown
//
// General Dropdown Rules
//.dropdown-item {
// &:first-of-type {
// @include border-top-radius($border-radius);
// }
// &:last-of-type {
// @include border-bottom-radius($border-radius);
// }
//}
.text-sm {
.dropdown-menu {
font-size: $font-size-sm !important;
}
.dropdown-toggle::after {
vertical-align: .2rem;
}
}
.dropdown-item-title {
font-size: $font-size-base;
margin: 0;
}
.dropdown-icon {
&::after {
margin-left: 0;
}
}
// Dropdown Sizes
.dropdown-menu-lg {
max-width: 300px;
min-width: 280px;
padding: 0;
.dropdown-divider {
margin: 0;
}
.dropdown-item {
padding: $dropdown-padding-y $dropdown-item-padding-x;
}
p {
margin: 0;
white-space: normal;
}
}
// Dropdown Submenu
.dropdown-submenu {
position: relative;
> a::after {
@include caret-right ();
float: right;
margin-left: .5rem;
margin-top: .5rem;
}
> .dropdown-menu {
left: 100%;
margin-left: 0;
margin-top: 0;
top: 0;
}
}
// Dropdown Hover
.dropdown-hover {
&:hover,
&.nav-item.dropdown:hover,
.dropdown-submenu:hover,
&.dropdown-submenu:hover {
> .dropdown-menu {
display: block;
}
}
}
// Dropdown Sizes
.dropdown-menu-xl {
max-width: 420px;
min-width: 360px;
padding: 0;
.dropdown-divider {
margin: 0;
}
.dropdown-item {
padding: $dropdown-padding-y $dropdown-item-padding-x;
}
p {
margin: 0;
white-space: normal;
}
}
// Dropdown header and footer
.dropdown-footer,
.dropdown-header {
display: block;
font-size: $font-size-sm;
padding: .5rem $dropdown-item-padding-x;
text-align: center;
}
// Add fade animation to dropdown menus by appending
// the class .animated-dropdown-menu to the .dropdown-menu ul (or ol)
.open:not(.dropup) > .animated-dropdown-menu {
@include animation(flipInX .7s both);
backface-visibility: visible !important;
}
// Fix dropdown menu in navbars
.navbar-custom-menu > .navbar-nav {
> li {
position: relative;
> .dropdown-menu {
position: absolute;
right: 0;
left: auto;
}
}
}
@include media-breakpoint-down(sm) {
.navbar-custom-menu > .navbar-nav {
float: right;
> li {
position: static;
> .dropdown-menu {
position: absolute;
right: 5%;
left: auto;
border: 1px solid #ddd;
background-color: $white;
}
}
}
}
// User Menu
.navbar-nav > .user-menu {
> .nav-link::after {
content: none;
}
> .dropdown-menu {
@include border-top-radius(0);
padding: 0;
width: 280px;
&,
> .user-body {
@include border-bottom-radius(4px);
}
// Header menu
> li.user-header {
height: 175px;
padding: 10px;
text-align: center;
// User image
> img {
z-index: 5;
height: 90px;
width: 90px;
border: 3px solid;
border-color: transparent;
border-color: rgba(255, 255, 255, .2);
}
> p {
z-index: 5;
font-size: 17px;
//text-shadow: 2px 2px 3px #333333;
margin-top: 10px;
> small {
display: block;
font-size: 12px;
}
}
}
// Menu Body
> .user-body {
@include clearfix ();
border-bottom: 1px solid $gray-700;
border-top: 1px solid $gray-300;
padding: 15px;
a {
@include media-breakpoint-up(sm) {
background-color: $white !important;
color: $gray-700 !important;
}
}
}
// Menu Footer
> .user-footer {
@include clearfix ();
background-color: $gray-100;
padding: 10px;
.btn-default {
color: $gray-600;
&:hover {
@include media-breakpoint-up(sm) {
background-color: $gray-100;
}
}
}
}
}
.user-image {
@include media-breakpoint-up(sm) {
float: none;
line-height: 10px;
margin-right: .4rem;
margin-top: -8px;
}
border-radius: 50%;
float: left;
height: $sidebar-user-image-width;
margin-right: 10px;
margin-top: -2px;
width: $sidebar-user-image-width;
}
}
@include dark-mode () {
.dropdown-menu {
background-color: $dark;
color: $white;
}
.dropdown-item {
color: $white;
&:focus,
&:hover {
background-color: lighten($dark, 5%);
}
}
.dropdown-divider {
border-color: $gray-600;
}
.navbar-nav > .user-menu > .dropdown-menu {
> .user-footer {
background-color: lighten($dark, 2.5%);
color: $white;
.btn-default {
color: $white;
&:hover,
&:focus {
background-color: lighten($dark, 5%);
color: $gray-300;
}
&:focus {
background-color: lighten($dark, 7.5%);
}
}
}
> .user-body {
border-color: $gray-600;
}
> .user-body a {
background-color: transparent !important;
color: $white !important;
&:hover,
&:focus {
color: $gray-400 !important;
}
}
}
}

View File

@ -0,0 +1,14 @@
//
// Component: Elevation
//
.elevation-0 {
box-shadow: none !important;
}
// Background colors (colors)
@each $name, $value in $elevations {
.elevation-#{$name} {
box-shadow: $value !important;
}
}

View File

@ -0,0 +1,451 @@
//
// Component: Forms
//
.form-group {
&.has-icon {
position: relative;
.form-control {
padding-right: 35px;
}
.form-icon {
background-color: transparent;
border: 0;
cursor: pointer;
font-size: 1rem;
// margin-top: -3px;
padding: $input-btn-padding-y $input-btn-padding-x;
position: absolute;
right: 3px;
top: 0;
}
}
}
// Button groups
.btn-group-vertical {
.btn {
&.btn-flat:first-of-type,
&.btn-flat:last-of-type {
@include border-radius(0);
}
}
}
// Support icons in form-control
.form-control-feedback {
&.fa,
&.fas,
&.far,
&.fab,
&.fal,
&.fad,
&.svg-inline--fa,
&.ion {
line-height: $input-height;
}
}
.input-lg + .form-control-feedback,
.input-group-lg + .form-control-feedback {
&.fa,
&.fas,
&.far,
&.fab,
&.fal,
&.fad,
&.svg-inline--fa,
&.ion {
line-height: $input-height-lg;
}
}
.form-group-lg {
.form-control + .form-control-feedback {
&.fa,
&.fas,
&.far,
&.fab,
&.fal,
&.fad,
&.svg-inline--fa,
&.ion {
line-height: $input-height-lg;
}
}
}
.input-sm + .form-control-feedback,
.input-group-sm + .form-control-feedback {
&.fa,
&.fas,
&.far,
&.fab,
&.fal,
&.fad,
&.svg-inline--fa,
&.ion {
line-height: $input-height-sm;
}
}
.form-group-sm {
.form-control + .form-control-feedback {
&.fa,
&.fas,
&.far,
&.fab,
&.fal,
&.fad,
&.svg-inline--fa,
&.ion {
line-height: $input-height-sm;
}
}
}
label:not(.form-check-label):not(.custom-file-label) {
font-weight: $font-weight-bold;
}
.warning-feedback {
@include font-size($form-feedback-font-size);
color: theme-color("warning");
display: none;
margin-top: $form-feedback-margin-top;
width: 100%;
}
.warning-tooltip {
@include border-radius($form-feedback-tooltip-border-radius);
@include font-size($form-feedback-tooltip-font-size);
background-color: rgba(theme-color("warning"), $form-feedback-tooltip-opacity);
color: color-yiq(theme-color("warning"));
display: none;
line-height: $form-feedback-tooltip-line-height;
margin-top: .1rem;
max-width: 100%; // Contain to parent when possible
padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
position: absolute;
top: 100%;
z-index: 5;
}
.form-control {
&.is-warning {
border-color: theme-color("warning");
@if $enable-validation-icons {
// padding-right: $input-height-inner;
// background-image: none;
// background-repeat: no-repeat;
// background-position: center right $input-height-inner-quarter;
// background-size: $input-height-inner-half $input-height-inner-half;
}
&:focus {
border-color: theme-color("warning");
box-shadow: 0 0 0 $input-focus-width rgba(theme-color("warning"), .25);
}
~ .warning-feedback,
~ .warning-tooltip {
display: block;
}
}
}
// stylelint-disable-next-line selector-no-qualifying-type
textarea.form-control {
&.is-warning {
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
}
}
}
.custom-select {
&.is-warning {
border-color: theme-color("warning");
@if $enable-validation-icons {
// padding-right: $custom-select-feedback-icon-padding-right;
// background: $custom-select-background, none $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;
}
&:focus {
border-color: theme-color("warning");
box-shadow: 0 0 0 $input-focus-width rgba(theme-color("warning"), .25);
}
~ .warning-feedback,
~ .warning-tooltip {
display: block;
}
}
}
.form-control-file {
&.is-warning {
~ .warning-feedback,
~ .warning-tooltip {
display: block;
}
}
}
.form-check-input {
&.is-warning {
~ .form-check-label {
color: theme-color("warning");
}
~ .warning-feedback,
~ .warning-tooltip {
display: block;
}
}
}
.custom-control-input.is-warning {
~ .custom-control-label {
color: theme-color("warning");
&::before {
border-color: theme-color("warning");
}
}
~ .warning-feedback,
~ .warning-tooltip {
display: block;
}
&:checked {
~ .custom-control-label::before {
@include gradient-bg(lighten(theme-color("warning"), 10%));
border-color: lighten(theme-color("warning"), 10%);
}
}
&:focus {
~ .custom-control-label::before {
box-shadow: 0 0 0 $input-focus-width rgba(theme-color("warning"), .25);
}
&:not(:checked) ~ .custom-control-label::before {
border-color: theme-color("warning");
}
}
}
// custom file
.custom-file-input {
&.is-warning {
~ .custom-file-label {
border-color: theme-color("warning");
}
~ .warning-feedback,
~ .warning-tooltip {
display: block;
}
&:focus {
~ .custom-file-label {
border-color: theme-color("warning");
box-shadow: 0 0 0 $input-focus-width rgba(theme-color("warning"), .25);
}
}
}
}
// body.text-sm support
body.text-sm {
.input-group-text {
font-size: $font-size-sm;
}
}
// custom .form-control styles
.form-control,
.custom-select {
&.form-control-border {
border-top: 0;
border-left: 0;
border-right: 0;
border-radius: 0;
box-shadow: inherit;
&.border-width-2 {
border-bottom-width: 2px;
}
&.border-width-3 {
border-bottom-width: 3px;
}
}
}
// custom switch color variations
.custom-switch {
@each $name, $color in $theme-colors {
@include custom-switch-variant($name, $color);
}
@each $name, $color in $colors {
@include custom-switch-variant($name, $color);
}
}
// custom range color variations
.custom-range {
@each $name, $color in $theme-colors {
@include custom-range-variant($name, $color);
}
@each $name, $color in $colors {
@include custom-range-variant($name, $color);
}
}
// custom control input variations
@each $name, $color in $theme-colors {
@include custom-control-input-variant($name, $color);
}
@each $name, $color in $colors {
@include custom-control-input-variant($name, $color);
}
.custom-control-input-outline {
~ .custom-control-label::before {
background-color: transparent !important;
box-shadow: none;
}
&:checked ~ .custom-control-label::before {
@include gradient-bg(transparent);
}
}
.navbar-dark {
.btn-navbar,
.form-control-navbar {
background-color: lighten($sidebar-dark-bg, 5%);
border: 1px solid lighten($sidebar-dark-bg, 15%);
color: lighten(color-yiq(lighten($sidebar-dark-bg, 5%)), 15%);
}
.btn-navbar {
&:hover {
background-color: lighten($sidebar-dark-bg, 7.5%);
}
&:focus {
background-color: lighten($sidebar-dark-bg, 10%);
}
}
.form-control-navbar + .input-group-prepend,
.form-control-navbar + .input-group-append {
> .btn-navbar {
background-color: lighten($sidebar-dark-bg, 5%);
color: $white;
border: 1px solid lighten($sidebar-dark-bg, 15%);
border-left: none;
}
}
}
@include dark-mode () {
.form-control:not(.form-control-navbar):not(.form-control-sidebar),
.custom-select,
.custom-file-label,
.custom-file-label::after,
.custom-control-label::before,
.input-group-text {
background-color: $dark;
color: $white;
}
.form-control:not(.form-control-navbar):not(.form-control-sidebar):not(.is-invalid):not(:focus),
.custom-file-label,
.custom-file-label::after {
border-color: $gray-600;
}
select {
background-color: $dark;
color: $white;
border-color: $gray-600;
}
.custom-select {
background: $dark $custom-select-dark-background;
&[multiple]{
background: $dark;
}
}
.input-group-text {
border-color: $gray-600;
}
.custom-control-input:disabled ~ .custom-control-label::before,
.custom-control-input[disabled] ~ .custom-control-label::before {
background-color: lighten($dark, 5%);
border-color: $gray-600;
color: $white;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
-webkit-text-fill-color: $white;
}
.custom-range {
&::-webkit-slider-runnable-track {
background-color: lighten($dark, 7.5%);
}
&::-moz-range-track {
background-color: lighten($dark, 7.5%);
}
&::-ms-track {
background-color: lighten($dark, 7.5%);
}
@each $name, $color in $theme-colors-alt {
@include custom-range-variant($name, $color);
}
@each $name, $color in $colors-alt {
@include custom-range-variant($name, $color);
}
}
// custom switch color variations
.custom-switch {
@each $name, $color in $theme-colors-alt {
@include custom-switch-variant($name, $color);
}
@each $name, $color in $colors-alt {
@include custom-switch-variant($name, $color);
}
}
@each $name, $color in $theme-colors-alt {
@include custom-control-input-variant($name, $color);
}
@each $name, $color in $colors-alt {
@include custom-control-input-variant($name, $color);
}
}

View File

@ -0,0 +1,166 @@
//
// Component: Info Box
//
.info-box {
@include box-shadow($card-shadow);
@include border-radius($border-radius);
background-color: $white;
display: flex;
margin-bottom: map-get($spacers, 3);
min-height: 80px;
padding: .5rem;
position: relative;
width: 100%;
.progress {
background-color: rgba($black, .125);
height: 2px;
margin: 5px 0;
.progress-bar {
background-color: $white;
}
}
.info-box-icon {
@if $enable-rounded {
border-radius: $border-radius;
}
align-items: center;
display: flex;
font-size: 1.875rem;
justify-content: center;
text-align: center;
width: 70px;
> img {
max-width: 100%;
}
}
.info-box-content {
display: flex;
flex-direction: column;
justify-content: center;
line-height: 1.8;
flex: 1;
padding: 0 10px;
overflow: hidden;
}
.info-box-number {
display: block;
margin-top: .25rem;
font-weight: $font-weight-bold;
}
.progress-description,
.info-box-text {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@each $name, $color in $theme-colors {
.info-box {
.bg-#{$name},
.bg-gradient-#{$name} {
color: color-yiq($color);
.progress-bar {
background-color: color-yiq($color);
}
}
}
}
.info-box-more {
display: block;
}
.progress-description {
margin: 0;
}
@include media-breakpoint-up(md) {
.col-xl-2 &,
.col-lg-2 &,
.col-md-2 & {
.progress-description {
display: none;
}
}
.col-xl-3 &,
.col-lg-3 &,
.col-md-3 & {
.progress-description {
display: none;
}
}
}
@include media-breakpoint-up(lg) {
.col-xl-2 &,
.col-lg-2 &,
.col-md-2 & {
.progress-description {
@include font-size(.75rem);
display: block;
}
}
.col-xl-3 &,
.col-lg-3 &,
.col-md-3 & {
.progress-description {
@include font-size(.75rem);
display: block;
}
}
}
@include media-breakpoint-up(xl) {
.col-xl-2 &,
.col-lg-2 &,
.col-md-2 & {
.progress-description {
@include font-size(1rem);
display: block;
}
}
.col-xl-3 &,
.col-lg-3 &,
.col-md-3 & {
.progress-description {
@include font-size(1rem);
display: block;
}
}
}
}
@include dark-mode () {
.info-box {
background-color: $dark;
color: $white;
@each $name, $color in $theme-colors-alt {
.info-box {
.bg-#{$name},
.bg-gradient-#{$name} {
color: color-yiq($color);
.progress-bar {
background-color: color-yiq($color);
}
}
}
}
}
}

View File

@ -0,0 +1,708 @@
//
// Core: Layout
//
html.scroll-smooth {
scroll-behavior: smooth;
}
html,
body,
.wrapper {
min-height: 100%;
}
.wrapper {
position: relative;
.content-wrapper {
min-height: calc(100vh - #{$main-header-height} - #{$main-footer-height});
}
.layout-boxed & {
@include box-shadow(0 0 10 rgba($black, .3));
&,
&::before {
margin: 0 auto;
max-width: $boxed-layout-max-width;
overflow: hidden;
}
.main-sidebar {
left: inherit;
}
}
@supports not (-webkit-touch-callout: none) {
.layout-fixed & .sidebar {
height: calc(100vh - (#{$main-header-height-inner} + #{$main-header-bottom-border-width}));
}
.layout-fixed.text-sm & .sidebar {
height: calc(100vh - (#{$main-header-height-sm-inner} + #{$main-header-bottom-border-width}));
}
}
.layout-navbar-fixed.layout-fixed & {
.control-sidebar {
top: $main-header-height;
}
.main-header.text-sm ~ .control-sidebar {
top: $main-header-height-sm;
}
.sidebar {
margin-top: $main-header-height;
}
.brand-link.text-sm ~ .sidebar {
margin-top: $main-header-height-sm;
}
}
.layout-navbar-fixed.layout-fixed.text-sm & {
.control-sidebar {
top: $main-header-height-sm;
}
.sidebar {
margin-top: $main-header-height-sm;
}
}
.layout-navbar-fixed.sidebar-mini.sidebar-collapse &,
.layout-navbar-fixed.sidebar-mini-md.sidebar-collapse &,
.layout-navbar-fixed.sidebar-mini-xs.sidebar-collapse & {
.brand-link {
height: $main-header-height;
width: $sidebar-mini-width;
&.text-sm {
height: $main-header-height-sm;
}
}
}
.layout-navbar-fixed.sidebar-mini.sidebar-collapse.text-sm &,
.layout-navbar-fixed.sidebar-mini-md.sidebar-collapse.text-sm &,
.layout-navbar-fixed.sidebar-mini-xs.sidebar-collapse.text-sm & {
.brand-link {
height: $main-header-height-sm;
}
}
body:not(.layout-fixed).layout-navbar-fixed & {
.main-sidebar {
// margin-top: calc(#{$main-header-height} / -1);
// .sidebar {
// margin-top: $main-header-height;
// }
}
}
body:not(.layout-fixed).layout-navbar-fixed.text-sm & {
.main-sidebar {
margin-top: calc(#{$main-header-height-sm} / -1);
.sidebar {
margin-top: $main-header-height-sm;
}
}
}
.layout-navbar-fixed & {
.control-sidebar {
top: 0;
}
a.anchor {
display: block;
position: relative;
top: calc((#{$main-header-height-inner} + #{$main-header-bottom-border-width} + (#{$main-header-link-padding-y} * 2)) / -1);
}
.main-sidebar:hover {
.brand-link {
transition: width $transition-speed $transition-fn;
width: $sidebar-width;
}
}
.brand-link {
overflow: hidden;
position: fixed;
top: 0;
transition: width $transition-speed $transition-fn;
width: $sidebar-width;
z-index: $zindex-main-header + 1;
}
// Sidebar variants brand-link fix
@each $name, $color in $theme-colors {
.sidebar-dark-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-dark-bg;
}
.sidebar-light-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-light-bg;
}
}
@each $name, $color in $colors {
.sidebar-dark-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-dark-bg;
}
.sidebar-light-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-light-bg;
}
}
.main-header.border-bottom-0 ~ .content-wrapper {
margin-top: $main-header-height-inner;
}
.content-wrapper {
margin-top: $main-header-height;
}
.main-header.text-sm ~ .content-wrapper {
margin-top: $main-header-height-sm;
}
.main-header {
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: $zindex-main-header - 1;
}
}
.layout-navbar-fixed.text-sm & {
.content-wrapper {
margin-top: $main-header-height-sm;
}
}
.layout-navbar-not-fixed & {
.brand-link {
position: static;
}
.sidebar,
.content-wrapper {
margin-top: 0;
}
.main-header {
position: static;
}
}
.layout-navbar-not-fixed.layout-fixed & {
.sidebar {
margin-top: 0;
}
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.layout#{$infix}-navbar-fixed.layout-fixed & {
.control-sidebar {
top: $main-header-height;
}
.text-sm & .main-header ~ .control-sidebar,
.main-header.text-sm ~ .control-sidebar {
top: $main-header-height-sm;
}
.sidebar {
margin-top: $main-header-height;
}
.text-sm & .brand-link ~ .sidebar,
.brand-link.text-sm ~ .sidebar {
margin-top: $main-header-height-sm;
}
}
.layout#{$infix}-navbar-fixed.layout-fixed.text-sm & {
.control-sidebar {
top: $main-header-height-sm;
}
.sidebar {
margin-top: $main-header-height-sm;
}
}
.layout#{$infix}-navbar-fixed & {
.control-sidebar {
top: 0;
}
a.anchor {
display: block;
position: relative;
top: calc((#{$main-header-height-inner} + #{$main-header-bottom-border-width} + (#{$main-header-link-padding-y} * 2)) / -1);
}
&.sidebar-collapse {
.brand-link {
height: $main-header-height;
transition: width $transition-speed $transition-fn;
width: $sidebar-mini-width;
.text-sm &,
&.text-sm {
height: $main-header-height-sm;
}
}
.main-sidebar:hover {
.brand-link {
transition: width $transition-speed $transition-fn;
width: $sidebar-width;
}
}
}
.brand-link {
overflow: hidden;
position: fixed;
top: 0;
transition: width $transition-speed $transition-fn;
width: $sidebar-width;
z-index: $zindex-main-header + 1;
}
.content-wrapper {
margin-top: $main-header-height;
}
.text-sm & .main-header ~ .content-wrapper,
.main-header.text-sm ~ .content-wrapper {
margin-top: $main-header-height-sm;
}
.main-header {
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: $zindex-main-sidebar - 1;
}
}
.layout#{$infix}-navbar-fixed.text-sm & {
.content-wrapper {
margin-top: $main-header-height-sm;
}
}
body:not(.layout-fixed).layout#{$infix}-navbar-fixed & {
// .main-sidebar {
// margin-top: calc(#{$main-header-height} / -1);
// .sidebar {
// margin-top: $main-header-height;
// }
// }
}
body:not(.layout-fixed).layout#{$infix}-navbar-fixed.text-sm & {
.main-sidebar {
margin-top: calc(#{$main-header-height-sm} / -1);
.sidebar {
margin-top: $main-header-height-sm;
}
}
}
.layout#{$infix}-navbar-not-fixed & {
.brand-link {
position: static;
}
.sidebar,
.content-wrapper {
margin-top: 0;
}
.main-header {
position: static;
}
}
.layout#{$infix}-navbar-not-fixed.layout-fixed & {
.sidebar {
margin-top: 0;
}
}
}
}
.layout-footer-fixed & {
.control-sidebar {
bottom: 0;
}
.main-footer {
bottom: 0;
left: 0;
position: fixed;
right: 0;
z-index: $zindex-main-footer;
}
}
.layout-footer-not-fixed & {
.main-footer {
position: static;
}
.content-wrapper {
margin-bottom: 0;
}
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.layout#{$infix}-footer-fixed & {
.control-sidebar {
bottom: 0;
}
.main-footer {
bottom: 0;
left: 0;
position: fixed;
right: 0;
z-index: $zindex-main-footer;
}
.content-wrapper {
padding-bottom: $main-footer-height;
}
}
.layout#{$infix}-footer-not-fixed & {
.main-footer {
position: static;
}
}
}
}
.layout-top-nav & {
margin-left: 0;
.main-header {
.brand-image {
margin-top: -.5rem;
margin-right: .2rem;
height: 33px;
}
}
.main-sidebar {
bottom: inherit;
height: inherit;
}
.content-wrapper,
.main-header,
.main-footer {
margin-left: 0;
}
}
}
body.sidebar-collapse:not(.sidebar-mini-xs):not(.sidebar-mini-md):not(.sidebar-mini) {
.content-wrapper,
.main-footer,
.main-header {
&,
&::before {
margin-left: 0;
}
}
}
body:not(.sidebar-mini-md):not(.sidebar-mini-xs):not(.layout-top-nav) {
.content-wrapper,
.main-footer,
.main-header {
@include media-breakpoint-up(md) {
@include transition(margin-left $transition-speed $transition-fn);
margin-left: $sidebar-width;
.sidebar-collapse & {
margin-left: 0;
}
}
@include media-breakpoint-down(md) {
margin-left: 0;
}
}
}
.sidebar-mini-md {
.content-wrapper,
.main-footer,
.main-header {
@include media-breakpoint-up(md) {
@include transition(margin-left $transition-speed $transition-fn);
margin-left: $sidebar-width;
.sidebar-collapse & {
margin-left: $sidebar-mini-width;
}
}
@include media-breakpoint-down(md) {
margin-left: $sidebar-mini-width;
}
@include media-breakpoint-down(sm) {
margin-left: 0;
}
}
}
.sidebar-mini-xs {
.content-wrapper,
.main-footer,
.main-header {
@include media-breakpoint-up(md) {
@include transition(margin-left $transition-speed $transition-fn);
margin-left: $sidebar-width;
.sidebar-collapse & {
margin-left: $sidebar-mini-width;
}
}
@include media-breakpoint-down(md) {
margin-left: $sidebar-mini-width;
}
}
}
.content-wrapper {
background-color: $main-bg;
> .content {
padding: $content-padding-y $content-padding-x;
}
}
.main-sidebar {
&,
&::before {
$local-sidebar-transition: margin-left $transition-speed $transition-fn, width $transition-speed $transition-fn;
@include transition($local-sidebar-transition);
width: $sidebar-width;
}
.sidebar-collapse:not(.sidebar-mini):not(.sidebar-mini-md):not(.sidebar-mini-xs) & {
&,
&::before {
box-shadow: none !important;
}
}
.sidebar-collapse & {
&,
&::before {
margin-left: -$sidebar-width;
}
.nav-sidebar.nav-child-indent .nav-treeview {
padding: 0;
}
}
@include media-breakpoint-down(sm) {
&,
&::before {
box-shadow: none !important;
margin-left: -$sidebar-width;
}
.sidebar-open & {
&,
&::before {
margin-left: 0;
}
}
}
}
body:not(.layout-fixed) {
.main-sidebar {
height: inherit;
min-height: 100%;
position: absolute;
top: 0;
.sidebar {
overflow-y: auto;
}
}
}
.layout-fixed {
.brand-link {
width: $sidebar-width;
}
.main-sidebar {
bottom: 0;
float: none;
left: 0;
position: fixed;
top: 0;
}
.control-sidebar {
bottom: 0;
float: none;
position: fixed;
top: 0;
.control-sidebar-content {
height: calc(100vh - #{$main-header-height});
overflow-y: auto;
@include scrollbar-width-thin();
@include scrollbar-color-gray();
}
}
}
@supports (-webkit-touch-callout: none) {
.layout-fixed {
.main-sidebar {
height: inherit;
}
}
}
.main-footer {
background-color: $main-footer-bg;
border-top: $main-footer-border-top;
color: lighten($gray-700, 25%);
padding: $main-footer-padding;
.text-sm &,
&.text-sm {
padding: $main-footer-padding-sm;
}
}
.content-header {
padding: 15px $content-padding-x;
.text-sm & {
padding: 10px $content-padding-x;
}
h1 {
font-size: 1.8rem;
margin: 0;
.text-sm & {
font-size: 1.5rem;
}
}
.breadcrumb {
background-color: transparent;
line-height: 1.8rem;
margin-bottom: 0;
padding: 0;
.text-sm & {
line-height: 1.5rem;
}
}
}
.hold-transition {
.content-wrapper,
.main-header,
.main-sidebar,
.main-sidebar *,
.control-sidebar,
.control-sidebar *,
.main-footer {
transition: none !important;
animation-duration: 0s !important;
}
}
@include dark-mode () {
background-color: $dark-main-bg;
color: $white;
.wrapper {
.layout-navbar-fixed & {
@each $name, $color in $theme-colors-alt {
.sidebar-dark-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-dark-bg;
}
.sidebar-light-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-light-bg;
}
}
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.layout#{$infix}-navbar-fixed & {
@each $name, $color in $theme-colors-alt {
.sidebar-dark-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-dark-bg;
}
.sidebar-light-#{$name} .brand-link:not([class*="navbar"]) {
background-color: $sidebar-light-bg;
}
}
}
}
}
}
.breadcrumb-item {
&.active,
+ .breadcrumb-item::before {
color: $gray-500;
}
}
.main-footer {
background-color: $dark;
border-color: lighten($dark, 10%);
}
.content-wrapper {
background-color: lighten($dark, 7.5%);
color: $white;
.content-header {
color: $white;
}
}
}

View File

@ -0,0 +1,179 @@
//
// Component: Main Header
//
.main-header {
border-bottom: $main-header-bottom-border;
z-index: $zindex-main-header;
.nav-link {
height: $nav-link-height;
position: relative;
}
.text-sm &,
&.text-sm {
.nav-link {
height: $nav-link-sm-height;
padding: $nav-link-sm-padding-y $nav-link-padding-x;
> .fa,
> .fas,
> .far,
> .fab,
> .fal,
> .fad,
> .svg-inline--fa,
> .ion {
font-size: $font-size-sm;
}
}
}
.navbar-nav {
.nav-item {
margin: 0;
}
&[class*="-right"] {
.dropdown-menu {
left: auto;
margin-top: -3px;
right: 0;
@media (max-width: breakpoint-max(xs)) {
left: 0;
right: auto;
}
}
}
}
&.dropdown-legacy .dropdown-menu {
top: $nav-link-height + $navbar-padding-y;
margin-top: 0;
}
}
// Add this class to images within a nav-link
.navbar-img {
height: calc(#{$main-header-height} * .5);
width: auto;
}
// Navbar badge
.navbar-badge {
font-size: .6rem;
font-weight: 300;
padding: 2px 4px;
position: absolute;
right: 5px;
top: 9px;
}
.btn-navbar {
background-color: transparent;
border-left-width: 0;
}
.form-control-navbar {
border-right-width: 0;
+ .input-group-append {
margin-left: 0;
}
}
.form-control-navbar,
.btn-navbar {
transition: none;
}
.navbar-dark {
.form-control-navbar,
.btn-navbar {
background-color: $main-header-dark-form-control-bg;
border-color: $main-header-dark-form-control-border-color;
}
.form-control-navbar {
&::placeholder {
color: $main-header-dark-placeholder-color;
}
+ .input-group-append > .btn-navbar {
color: $main-header-dark-placeholder-color;
}
&:focus {
&,
+ .input-group-append .btn-navbar {
background-color: $main-header-dark-form-control-focused-bg;
border-color: $main-header-dark-form-control-focused-border-color !important;
color: $main-header-dark-form-control-focused-color;
}
}
}
}
.navbar-light {
.form-control-navbar,
.btn-navbar {
background-color: $main-header-light-form-control-bg;
border-color: $main-header-light-form-control-border-color;
}
.form-control-navbar {
&::placeholder {
color: $main-header-light-placeholder-color;
}
+ .input-group-append > .btn-navbar {
color: $main-header-light-placeholder-color;
}
&:focus {
&,
+ .input-group-append .btn-navbar {
background-color: $main-header-light-form-control-focused-bg;
border-color: $main-header-light-form-control-focused-border-color !important;
color: $main-header-light-form-control-focused-color;
}
}
}
.navbar-search-block {
.form-control-navbar {
&:focus {
&,
+ .input-group-append .btn-navbar {
color: $main-header-light-placeholder-color;
}
}
}
}
}
// Navbar Search
.navbar-search-block {
position: absolute;
padding: 0 $nav-link-padding-x;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 10;
display: none;
justify-content: center;
flex-direction: column;
background-color: initial;
&.navbar-search-open {
display: flex;
}
.input-group {
width: 100%;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,541 @@
//
// Misc: Miscellaneous
//
.border-transparent {
border-color: transparent !important;
}
// Description Blocks
.description-block {
display: block;
margin: 10px 0;
text-align: center;
&.margin-bottom {
margin-bottom: 25px;
}
> .description-header {
font-size: 16px;
font-weight: 600;
margin: 0;
padding: 0;
}
> .description-text {
text-transform: uppercase;
}
// Description Block Extension
.description-icon {
font-size: 16px;
}
}
// List utility classes
.list-group-unbordered {
> .list-group-item {
border-left: 0;
border-radius: 0;
border-right: 0;
padding-left: 0;
padding-right: 0;
}
}
.list-header {
color: $gray-600;
font-size: 15px;
font-weight: 700;
padding: 10px 4px;
}
.list-seperator {
background-color: $card-border-color;
height: 1px;
margin: 15px 0 9px;
}
.list-link {
> a {
color: $gray-600;
padding: 4px;
&:hover {
color: $gray-900;
}
}
}
// User block
.user-block {
float: left;
img {
float: left;
height: 40px;
width: 40px;
}
.username,
.description,
.comment {
display: block;
margin-left: 50px;
}
.username {
font-size: 16px;
font-weight: 600;
margin-top: -1px;
}
.description {
color: $gray-600;
font-size: 13px;
margin-top: -3px;
}
&.user-block-sm {
img {
width: $img-size-sm;
height: $img-size-sm;
}
.username,
.description,
.comment {
margin-left: 40px;
}
.username {
font-size: 14px;
}
}
}
// Image sizes
.img-sm,
.img-md,
.img-lg {
float: left;
}
.img-sm {
height: $img-size-sm;
width: $img-size-sm;
+ .img-push {
margin-left: $img-size-sm + $img-size-push;
}
}
.img-md {
width: $img-size-md;
height: $img-size-md;
+ .img-push {
margin-left: $img-size-md + $img-size-push;
}
}
.img-lg {
width: $img-size-lg;
height: $img-size-lg;
+ .img-push {
margin-left: $img-size-lg + $img-size-push;
}
}
// Image bordered
.img-bordered {
border: 3px solid $gray-500;
padding: 3px;
}
.img-bordered-sm {
border: 2px solid $gray-500;
padding: 2px;
}
// Rounded and Circle Images
.img-rounded {
@include border-radius($border-radius);
}
.img-circle {
@include border-radius(50%);
}
// Image sizes
.img-size-64,
.img-size-50,
.img-size-32 {
height: auto;
}
.img-size-64 {
width: 64px;
}
.img-size-50 {
width: 50px;
}
.img-size-32 {
width: 32px;
}
// Block sizes
.size-32,
.size-40,
.size-50 {
display: block;
text-align: center;
}
.size-32 {
height: 32px;
line-height: 32px;
width: 32px;
}
.size-40 {
height: 40px;
line-height: 40px;
width: 40px;
}
.size-50 {
height: 50px;
line-height: 50px;
width: 50px;
}
// General attachemnt block
.attachment-block {
background-color: $gray-100;
border: 1px solid $card-border-color;
margin-bottom: 10px;
padding: 5px;
.attachment-img {
float: left;
height: auto;
max-height: 100px;
max-width: 100px;
}
.attachment-pushed {
margin-left: 110px;
}
.attachment-heading {
margin: 0;
}
.attachment-text {
color: $gray-700;
}
}
// Overlays for Card, InfoBox & SmallBox
.card,
.overlay-wrapper,
.info-box,
.small-box {
// Box overlay for LOADING STATE effect
> .overlay,
> .loading-img {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.overlay {
@include border-radius($border-radius);
align-items: center;
background-color: rgba($white, .7);
display: flex;
justify-content: center;
z-index: 50;
> .fa,
> .fas,
> .far,
> .fab,
> .fal,
> .fad,
> .svg-inline--fa,
> .ion {
color: $gray-800;
}
&.dark {
background-color: rgba($black, .5);
> .fa,
> .fas,
> .far,
> .fab,
> .fal,
> .fad,
> .svg-inline--fa,
> .ion {
color: $gray-400;
}
}
}
}
.tab-pane {
// Box overlay for LOADING STATE effect on Tab Panels
> .overlay-wrapper {
position: relative;
> .overlay {
border-top-left-radius: 0;
border-top-right-radius: 0;
flex-direction: column;
margin-top: -$card-spacer-x;
margin-left: -$card-spacer-x;
height: calc(100% + 2 * #{$card-spacer-x});
width: calc(100% + 2 * #{$card-spacer-x});
&.dark {
color: $white;
}
}
}
}
// Ribbon
.ribbon-wrapper {
height: $ribbon-wrapper-size;
overflow: hidden;
position: absolute;
right: -2px;
top: -2px;
width: $ribbon-wrapper-size;
z-index: 10;
&.ribbon-lg {
height: $ribbon-lg-wrapper-size;
width: $ribbon-lg-wrapper-size;
.ribbon {
right: $ribbon-lg-right;
top: $ribbon-lg-top;
width: $ribbon-lg-width;
}
}
&.ribbon-xl {
height: $ribbon-xl-wrapper-size;
width: $ribbon-xl-wrapper-size;
.ribbon {
right: $ribbon-xl-right;
top: $ribbon-xl-top;
width: $ribbon-xl-width;
}
}
.ribbon {
box-shadow: 0 0 $ribbon-border-size rgba($black, .3);
font-size: $ribbon-font-size;
line-height: $ribbon-line-height;
padding: $ribbon-padding;
position: relative;
right: $ribbon-right;
text-align: center;
text-shadow: 0 -1px 0 rgba($black, .4);
text-transform: uppercase;
top: $ribbon-top;
transform: rotate(45deg);
width: $ribbon-width;
&::before,
&::after {
border-left: $ribbon-border-size solid transparent;
border-right: $ribbon-border-size solid transparent;
border-top: $ribbon-border-size solid #9e9e9e;
bottom: -$ribbon-border-size;
content: "";
position: absolute;
}
&::before {
left: 0;
}
&::after {
right: 0;
}
}
}
// Scroll To Top
.back-to-top {
bottom: 1.25rem;
position: fixed;
right: 1.25rem;
z-index: $zindex-control-sidebar + 1;
&:focus {
box-shadow: none;
}
}
// Pre
pre {
padding: .75rem;
}
// Blockquotes styles
blockquote {
background-color: $white;
border-left: .7rem solid $primary;
margin: 1.5em .7rem;
padding: .5em .7rem;
.box & {
background-color: $gray-200;
}
p:last-child {
margin-bottom: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: $primary;
font-size: 1.25rem;
font-weight: 600;
}
@each $color, $value in $theme-colors {
&.quote-#{$color} {
border-color: $value;
h1,
h2,
h3,
h4,
h5,
h6 {
color: $value;
}
}
}
@each $color, $value in $colors {
&.quote-#{$color} {
border-color: $value;
h1,
h2,
h3,
h4,
h5,
h6 {
color: $value;
}
}
}
}
// Tab Custom Content
.tab-custom-content {
border-top: $nav-tabs-border-width solid $nav-tabs-border-color;
margin-top: .5rem;
padding-top: .5rem;
}
.nav + .tab-custom-content {
border-top: none;
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
margin-top: 0;
margin-bottom: .5rem;
padding-bottom: .5rem;
}
// Badge BTN Style
.badge-btn {
border-radius: $button-border-radius-xs;
font-size: $button-font-size-xs;
font-weight: 400;
padding: $button-padding-y-xs * 2 $button-padding-x-xs * 2;
}
.badge-btn.badge-pill {
padding: .375rem .6rem;
}
@include dark-mode () {
a:not(.btn):hover {
color: lighten($link-color, 10%);
}
.attachment-block {
background-color: lighten($dark, 3.75%);
.attachment-text {
color: $gray-400;
}
}
blockquote {
background-color: lighten($dark, 5%);
@each $color, $value in $theme-colors {
&.quote-#{$color} {
border-color: $value;
h1,
h2,
h3,
h4,
h5,
h6 {
color: $value;
}
}
}
@each $color, $value in $colors {
&.quote-#{$color} {
border-color: $value;
h1,
h2,
h3,
h4,
h5,
h6 {
color: $value;
}
}
}
}
.close,
.mailbox-attachment-close {
color: $gray-500;
text-shadow: 0 1px 0 $gray-700;
}
.tab-custom-content {
border-color: $gray-600;
}
.list-group-item {
background-color: $dark;
border-color: $gray-600;
}
}

View File

@ -0,0 +1,17 @@
//
// General: Mixins
//
@import "mixins/animations";
@import "mixins/scrollbar";
@import "mixins/cards";
@import "mixins/sidebar";
@import "mixins/navbar";
@import "mixins/accent";
@import "mixins/custom-forms";
@import "mixins/backgrounds";
@import "mixins/dark-mode";
@import "mixins/direct-chat";
@import "mixins/toasts";
@import "mixins/touch-support";
@import "mixins/miscellaneous";

View File

@ -0,0 +1,76 @@
//
// Component: Modals
//
// Overlay
.modal-dialog {
.overlay {
display: flex;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: -$modal-content-border-width;
z-index: ($zindex-modal + 2);
justify-content: center;
align-items: center;
background-color: rgba($black, .7);
color: darken($gray-600, 2.5%);
@include border-radius($modal-content-border-radius);
}
}
// BG Color Variations Fixes
.modal-content {
&.bg-warning {
.modal-header,
.modal-footer {
border-color: $gray-800;
}
}
&.bg-primary,
&.bg-secondary,
&.bg-info,
&.bg-danger,
&.bg-success, {
.close {
color: $white;
text-shadow: 0 1px 0 $black;
}
}
}
@include dark-mode () {
.modal-header,
.modal-footer {
border-color: $gray-600;
}
.modal-content {
background-color: $dark;
&.bg-warning {
.modal-header,
.modal-footer {
border-color: $gray-600;
}
.close {
color: $dark !important;
text-shadow: 0 1px 0 $gray-700 !important;
}
}
&.bg-primary,
&.bg-secondary,
&.bg-info,
&.bg-danger,
&.bg-success {
.modal-header,
.modal-footer {
border-color: $white;
}
}
}
}

View File

@ -0,0 +1,182 @@
//
// Component: Nav
//
.nav-pills {
.nav-link {
color: $gray-600;
&:not(.active):hover {
color: theme-color("primary");
}
}
.nav-item {
&.dropdown.show {
.nav-link:hover {
color: $dropdown-link-active-color;
}
}
}
}
// Vertical Tabs
.nav-tabs.flex-column {
border-bottom: 0;
border-right: $nav-tabs-border-width solid $nav-tabs-border-color;
.nav-link {
border-bottom-left-radius: $nav-tabs-border-radius;
border-top-right-radius: 0;
margin-right: -$nav-tabs-border-width;
@include hover-focus () {
border-color: $gray-200 transparent $gray-200 $gray-200;
}
}
.nav-link.active,
.nav-item.show .nav-link {
border-color: $gray-300 transparent $gray-300 $gray-300;
}
&.nav-tabs-right {
border-left: $nav-tabs-border-width solid $nav-tabs-border-color;
border-right: 0;
.nav-link {
border-bottom-left-radius: 0;
border-bottom-right-radius: $nav-tabs-border-radius;
border-top-left-radius: 0;
border-top-right-radius: $nav-tabs-border-radius;
margin-left: -$nav-tabs-border-width;
@include hover-focus () {
border-color: $gray-200 $gray-200 $gray-200 transparent;
}
}
.nav-link.active,
.nav-item.show .nav-link {
border-color: $gray-300 $gray-300 $gray-300 transparent;
}
}
}
.navbar-no-expand {
flex-direction: row;
.nav-link {
padding-left: $navbar-nav-link-padding-x;
padding-right: $navbar-nav-link-padding-x;
}
.dropdown-menu {
position: absolute;
}
}
// Color variants
@each $color, $value in $theme-colors {
@if $color == dark or $color == light {
.navbar-#{$color} {
background-color: $value;
@if $color == dark {
border-color: lighten($dark, 10%);
}
}
}
}
@each $color, $value in $theme-colors {
@if $color != dark and $color != light {
@include navbar-variant($color, $value);
}
}
@each $color, $value in $colors {
@include navbar-variant($color, $value);
}
.navbar-nav-not-expanded {
flex-direction: row;
.dropdown-menu {
position: absolute;
}
.nav-link {
padding-right: $navbar-nav-link-padding-x;
padding-left: $navbar-nav-link-padding-x;
}
}
@include dark-mode () {
.nav-pills .nav-link {
color: $gray-400;
}
.nav-tabs {
border-color: lighten($dark, 15%);
.nav-link:focus,
.nav-link:hover {
border-color: lighten($dark, 15%);
}
.nav-item.show .nav-link,
.nav-link.active {
background-color: $dark;
border-color: lighten($dark, 15%) lighten($dark, 15%) transparent lighten($dark, 15%);
color: $white;
}
&.flex-column {
.nav-item.show .nav-link,
.nav-link {
&.active,
&:focus,
&:hover {
border-color: lighten($dark, 15%) transparent lighten($dark, 15%) lighten($dark, 15%);
}
&:focus,
&:hover {
background-color: lighten($dark, 5%);
}
}
&.nav-tabs-right {
border-color: lighten($dark, 15%);
.nav-link {
&.active,
&:focus,
&:hover {
border-color: lighten($dark, 15%) lighten($dark, 15%) lighten($dark, 15%) transparent;
}
}
}
}
}
// Color variants
@each $color, $value in $theme-colors-alt {
@if $color == dark or $color == light {
.navbar-#{$color} {
background-color: $value;
@if $color == dark {
border-color: lighten($dark, 10%);
}
}
}
}
@each $color, $value in $theme-colors-alt {
@if $color != dark and $color != light {
@include navbar-variant($color, $value);
}
}
@each $color, $value in $colors-alt {
@include navbar-variant($color, $value);
}
}

View File

@ -0,0 +1,83 @@
//
// Component: Pagination
//
.pagination-month {
.page-item {
justify-self: stretch;
.page-link {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
box-shadow: none;
}
&:first-child,
&:last-child {
.page-link {
height: 100%;
font-size: $font-size-lg;
}
}
.page-month {
margin-bottom: 0;
font-size: $font-size-lg;
font-weight: $font-weight-bold;
}
.page-year {
margin-bottom: 0;
}
}
&.pagination-lg {
.page-month {
font-size: ($font-size-lg * 1.25);
}
}
&.pagination-sm {
.page-month {
font-size: ($font-size-base);
}
}
}
@include dark-mode () {
.page-item {
&.disabled a,
&.disabled .page-link {
background-color: lighten($dark, 2.5%) !important;
border-color: $gray-600 !important;
color: $gray-600;
}
.page-link {
color: $primary-alt;
}
&.active {
.page-link {
background-color: $primary-alt;
border-color: $primary-alt;
color: $white;
&:hover,
&:focus {
color: $gray-400 !important;
}
}
}
&:not(.active) {
.page-link {
background-color: $dark;
border-color: $gray-600;
&:hover,
&:focus {
color: lighten($primary-alt, 5%);
background-color: lighten($dark, 5%);
}
}
}
}
}

View File

@ -0,0 +1,24 @@
//
// Core: Preloader
//
.preloader {
display: flex;
background-color: $main-bg;
height: 100vh;
width: 100%;
transition: height 200ms linear;
position: fixed;
left: 0;
top: 0;
z-index: $zindex-preloader;
}
@include dark-mode () {
.preloader {
background-color: $dark-main-bg;
color: $white;
}
}
//

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