initial bootstrap/navbar setup akin to bones73k implementation
This commit is contained in:
parent
dfe805b811
commit
0a83f8f317
32 changed files with 6856 additions and 7865 deletions
35
assets/css/_bs-colors.scss
Normal file
35
assets/css/_bs-colors.scss
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Colors
|
||||
// $primary: #662c91;
|
||||
// $secondary: #ee6c4d;
|
||||
// $success: #3f784c;
|
||||
// $info: #3f84e5;
|
||||
// $warning: #ffec51;
|
||||
$light: $gray-200;
|
||||
$dark: $gray-800;
|
||||
|
||||
// Create your own map
|
||||
$custom-colors: (
|
||||
"primary": $primary,
|
||||
"secondary": $secondary,
|
||||
"success": $success,
|
||||
"info": $info,
|
||||
"warning": $warning,
|
||||
"danger": $danger,
|
||||
"light": $light,
|
||||
"dark": $dark,
|
||||
"gray": $gray-500,
|
||||
);
|
||||
|
||||
// $custom-colors: (
|
||||
// "custom-color": #900
|
||||
// );
|
||||
|
||||
// Merge the maps
|
||||
$theme-colors: map-merge($theme-colors, $custom-colors);
|
||||
|
||||
// misc
|
||||
$navbar-dark-color: rgba($white, 0.75);
|
||||
$navbar-dark-hover-color: rgba($white, 0.9);
|
||||
$navbar-dark-active-color: $white;
|
||||
$navbar-dark-disabled-color: rgba($white, 0.45);
|
||||
$navbar-dark-toggler-border-color: rgba($white, 0.3);
|
21
assets/css/_bs-custom.scss
Normal file
21
assets/css/_bs-custom.scss
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Bootstrap custom variable overrides */
|
||||
|
||||
// Typography
|
||||
//
|
||||
// Font, line-height, and color for body text, headings, and more.
|
||||
|
||||
// stylelint-disable value-keyword-case
|
||||
$font-family-sans-serif: Lato, system-ui, -apple-system, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
|
||||
$font-family-secondary: Righteous, system-ui, -apple-system, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important;
|
||||
$font-family-monospace: "Fira Mono", SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
"Liberation Mono", "Courier New", monospace !important;
|
||||
$font-family-code: "Fira Code", "Fira Mono", SFMono-Regular, Menlo, Monaco,
|
||||
Consolas, "Liberation Mono", "Courier New", monospace !important;
|
||||
|
||||
// Features
|
||||
$enable-shadows: true;
|
||||
$enable-negative-margins: true;
|
50
assets/css/_bs-load.scss
Normal file
50
assets/css/_bs-load.scss
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* Bootstrap custom variable overrides */
|
||||
@import "bs-custom";
|
||||
|
||||
// Required || Configuration
|
||||
@import "../node_modules/bootstrap/scss/functions";
|
||||
@import "../node_modules/bootstrap/scss/variables";
|
||||
|
||||
/* Bootstrap custom variable overrides */
|
||||
@import "bs-colors";
|
||||
|
||||
// Required || Configuration -- CONTINUED
|
||||
@import "../node_modules/bootstrap/scss/mixins";
|
||||
@import "../node_modules/bootstrap/scss/utilities";
|
||||
|
||||
// Optional || Layout & components
|
||||
@import "../node_modules/bootstrap/scss/root";
|
||||
@import "../node_modules/bootstrap/scss/reboot";
|
||||
@import "../node_modules/bootstrap/scss/type";
|
||||
@import "../node_modules/bootstrap/scss/images";
|
||||
@import "../node_modules/bootstrap/scss/containers";
|
||||
@import "../node_modules/bootstrap/scss/grid";
|
||||
// @import "../node_modules/bootstrap/scss/tables";
|
||||
@import "../node_modules/bootstrap/scss/forms";
|
||||
@import "../node_modules/bootstrap/scss/buttons";
|
||||
@import "../node_modules/bootstrap/scss/transitions";
|
||||
// @import "../node_modules/bootstrap/scss/dropdown";
|
||||
// @import "../node_modules/bootstrap/scss/button-group";
|
||||
@import "../node_modules/bootstrap/scss/nav";
|
||||
@import "../node_modules/bootstrap/scss/navbar";
|
||||
@import "../node_modules/bootstrap/scss/card";
|
||||
// @import "../node_modules/bootstrap/scss/accordion";
|
||||
// @import "../node_modules/bootstrap/scss/breadcrumb";
|
||||
// @import "../node_modules/bootstrap/scss/pagination";
|
||||
// @import "../node_modules/bootstrap/scss/badge";
|
||||
// @import "../node_modules/bootstrap/scss/alert";
|
||||
// @import "../node_modules/bootstrap/scss/progress";
|
||||
// @import "../node_modules/bootstrap/scss/list-group";
|
||||
// @import "../node_modules/bootstrap/scss/close";
|
||||
// @import "../node_modules/bootstrap/scss/toasts";
|
||||
// @import "../node_modules/bootstrap/scss/modal";
|
||||
// @import "../node_modules/bootstrap/scss/tooltip";
|
||||
// @import "../node_modules/bootstrap/scss/popover";
|
||||
// @import "../node_modules/bootstrap/scss/carousel";
|
||||
// @import "../node_modules/bootstrap/scss/spinners";
|
||||
|
||||
// Helpers
|
||||
@import "../node_modules/bootstrap/scss/helpers";
|
||||
|
||||
// Utilities
|
||||
@import "../node_modules/bootstrap/scss/utilities/api";
|
26
assets/css/_fonts.scss
Normal file
26
assets/css/_fonts.scss
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Fontsource Lato */
|
||||
// @import "../node_modules/@fontsource/lato/100.css"; /* thin | normal */
|
||||
// @import "../node_modules/@fontsource/lato/100-italic.css"; /* thin | italic */
|
||||
@import "../node_modules/@fontsource/lato/300.css"; /* light | normal */
|
||||
// @import "../node_modules/@fontsource/lato/300-italic.css"; /* light | italic */
|
||||
@import "../node_modules/@fontsource/lato/400.css"; /* normal | normal */
|
||||
// @import "../node_modules/@fontsource/lato/400-italic.css"; /* normal | italic */
|
||||
@import "../node_modules/@fontsource/lato/700.css"; /* bold | normal */
|
||||
// @import "../node_modules/@fontsource/lato/700-italic.css"; /* bold | italic */
|
||||
// @import "../node_modules/@fontsource/lato/900.css"; /* black | normal */
|
||||
// @import "../node_modules/@fontsource/lato/900-italic.css"; /* black | italic */
|
||||
|
||||
/* Fontsource Righteous */
|
||||
@import "../node_modules/@fontsource/righteous/400.css"; /* normal | normal */
|
||||
|
||||
/* Fontsource Fira Mono */
|
||||
@import "../node_modules/@fontsource/fira-mono/400.css"; /* normal | normal */
|
||||
// @import "../node_modules/@fontsource/fira-mono/500.css"; /* heavier normal? */
|
||||
@import "../node_modules/@fontsource/fira-mono/700.css"; /* bold | normal */
|
||||
|
||||
/* Fontsource Fira Code */
|
||||
@import "../node_modules/@fontsource/fira-code/300.css"; /* light | normal */
|
||||
@import "../node_modules/@fontsource/fira-code/400.css"; /* normal | normal */
|
||||
// @import "../node_modules/@fontsource/fira-code/500.css"; /* heavier normal? */
|
||||
// @import "../node_modules/@fontsource/fira-code/600.css"; /* heavier normal? */
|
||||
@import "../node_modules/@fontsource/fira-code/700.css"; /* bold | normal */
|
56
assets/css/_nav-burger.scss
Normal file
56
assets/css/_nav-burger.scss
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* Hamburger settings overrides */
|
||||
$hamburger-padding-x: 0.95rem !default;
|
||||
$hamburger-padding-y: 0.625rem !default;
|
||||
$hamburger-layer-width: 1.5rem !default;
|
||||
$hamburger-layer-height: 2px !default;
|
||||
$hamburger-layer-spacing: 6px !default;
|
||||
// * skipping default color, using color from bootstrap instead, below
|
||||
// $hamburger-layer-color: rgba(0, 0, 0, 0.55) !default;
|
||||
$hamburger-layer-border-radius: 0.25rem !default;
|
||||
$hamburger-hover-opacity: 0.7 !default;
|
||||
// * skipping default color, using color from bootstrap instead, below
|
||||
// $hamburger-active-layer-color: $hamburger-layer-color !default;
|
||||
$hamburger-active-hover-opacity: $hamburger-hover-opacity !default;
|
||||
|
||||
/* import hamburgers sass */
|
||||
@import "../node_modules/hamburgers/_sass/hamburgers/hamburgers.scss";
|
||||
|
||||
/* correct colors to match bootstrap defaults */
|
||||
.navbar-light {
|
||||
.hamburger {
|
||||
&.navbar-toggler {
|
||||
border: 1px $navbar-light-toggler-border-color solid !important;
|
||||
.hamburger-inner {
|
||||
&,
|
||||
&::before,
|
||||
&::after {
|
||||
background-color: $navbar-light-color;
|
||||
}
|
||||
}
|
||||
&.is-active {
|
||||
.hamburger-inner::after {
|
||||
background-color: $navbar-light-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navbar-dark {
|
||||
.hamburger {
|
||||
&.navbar-toggler {
|
||||
border: 1px $navbar-dark-toggler-border-color solid !important;
|
||||
.hamburger-inner {
|
||||
&,
|
||||
&::before,
|
||||
&::after {
|
||||
background-color: $navbar-dark-color;
|
||||
}
|
||||
}
|
||||
&.is-active {
|
||||
.hamburger-inner::after {
|
||||
background-color: $navbar-dark-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
43
assets/css/_phx-liveview.scss
Normal file
43
assets/css/_phx-liveview.scss
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* LiveView specific classes for your customizations */
|
||||
|
||||
/* hides the feedback field help if liveview indicates field not touched yet */
|
||||
.phx-no-feedback.invalid-feedback,
|
||||
.phx-no-feedback .invalid-feedback,
|
||||
.phx-orphaned-feedback.phx-no-feedback .invalid-feedback {
|
||||
display: none;
|
||||
}
|
||||
.phx-orphaned-feedback .invalid-feedback {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* sets default bootstrap form-control styles if field not touched yet */
|
||||
.phx-no-feedback .form-control.is-valid,
|
||||
.phx-no-feedback .form-control.is-invalid {
|
||||
border: $input-border-width solid $input-border-color;
|
||||
background-image: none;
|
||||
|
||||
&:focus {
|
||||
color: $input-focus-color;
|
||||
background-color: $input-focus-bg;
|
||||
border-color: $input-focus-border-color;
|
||||
outline: 0;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: $input-focus-box-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.phx-click-loading {
|
||||
opacity: 0.5;
|
||||
transition: opacity 1s ease-out;
|
||||
}
|
||||
|
||||
.phx-disconnected {
|
||||
cursor: wait;
|
||||
}
|
||||
.phx-disconnected * {
|
||||
pointer-events: none;
|
||||
}
|
21
assets/css/_svg-icons.scss
Normal file
21
assets/css/_svg-icons.scss
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
SVG ICON SYSTEM
|
||||
per https://blog.prototypr.io/align-svg-icons-to-text-and-say-goodbye-to-font-icons-d44b3d7b26b4
|
||||
*/
|
||||
.icon {
|
||||
display: inline-flex;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.icon svg,
|
||||
.icon img {
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.icon.baseline svg,
|
||||
.icon img {
|
||||
top: 0.125em;
|
||||
position: relative;
|
||||
}
|
|
@ -1,90 +1,63 @@
|
|||
/* This file is for your main application css. */
|
||||
@import "./phoenix.css";
|
||||
/* Fonts */
|
||||
@import "fonts";
|
||||
|
||||
/* LiveView specific classes for your customizations */
|
||||
.phx-no-feedback.invalid-feedback,
|
||||
.phx-no-feedback .invalid-feedback {
|
||||
display: none;
|
||||
/* Load Bootstrap v5 and customizations */
|
||||
@import "bs-load";
|
||||
|
||||
/*SVG ICON SYSTEM*/
|
||||
@import "svg-icons";
|
||||
|
||||
/* LiveView specific CSS */
|
||||
@import "phx-liveview";
|
||||
|
||||
/* Navbar toggler icon override */
|
||||
@import "nav-burger";
|
||||
|
||||
/* extra */
|
||||
.was-validated .no-valid-style .form-check-input:valid,
|
||||
.form-check-input.is-valid {
|
||||
border-color: inherit !important;
|
||||
}
|
||||
.was-validated .no-valid-style .form-check-input:valid ~ .form-check-label,
|
||||
.no-valid-style .form-check-input.is-valid ~ .form-check-label {
|
||||
color: inherit !important;
|
||||
}
|
||||
.table-nonfluid {
|
||||
width: auto !important;
|
||||
}
|
||||
.cursor-pointer {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.phx-click-loading {
|
||||
opacity: 0.5;
|
||||
transition: opacity 1s ease-out;
|
||||
/*
|
||||
icons in input fields
|
||||
*/
|
||||
/* enable absolute positioning */
|
||||
.inner-addon {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.phx-disconnected{
|
||||
cursor: wait;
|
||||
}
|
||||
.phx-disconnected *{
|
||||
/* style icon */
|
||||
.inner-addon > .icon {
|
||||
position: absolute;
|
||||
padding: 0.5625rem 0.5rem;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.phx-modal {
|
||||
opacity: 1!important;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgb(0,0,0);
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
/* align icon */
|
||||
.inner-addon > .icon.is-left {
|
||||
left: 0px;
|
||||
}
|
||||
.inner-addon > .icon.is-right {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.phx-modal-content {
|
||||
background-color: #fefefe;
|
||||
margin: 15% auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
/* add padding */
|
||||
.left-addon input,
|
||||
.left-addon select {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.phx-modal-close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.phx-modal-close:hover,
|
||||
.phx-modal-close:focus {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
/* Alerts and form errors */
|
||||
.alert {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.alert-info {
|
||||
color: #31708f;
|
||||
background-color: #d9edf7;
|
||||
border-color: #bce8f1;
|
||||
}
|
||||
.alert-warning {
|
||||
color: #8a6d3b;
|
||||
background-color: #fcf8e3;
|
||||
border-color: #faebcc;
|
||||
}
|
||||
.alert-danger {
|
||||
color: #a94442;
|
||||
background-color: #f2dede;
|
||||
border-color: #ebccd1;
|
||||
}
|
||||
.alert p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.alert:empty {
|
||||
display: none;
|
||||
}
|
||||
.invalid-feedback {
|
||||
color: #a94442;
|
||||
display: block;
|
||||
margin: -1rem 0 2rem;
|
||||
.right-addon input,
|
||||
.right-addon select {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
12
assets/js/_hamburger-helper.js
Normal file
12
assets/js/_hamburger-helper.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
const togglerBtn = document.getElementById("navbarSupportedContentToggler");
|
||||
const navbarContent = document.getElementById("navbarSupportedContent");
|
||||
|
||||
navbarContent.addEventListener("show.bs.collapse", () => {
|
||||
console.log("opening navbar content");
|
||||
togglerBtn.classList.toggle("is-active");
|
||||
});
|
||||
|
||||
navbarContent.addEventListener("hide.bs.collapse", () => {
|
||||
console.log("closing navbar content");
|
||||
togglerBtn.classList.toggle("is-active");
|
||||
});
|
|
@ -1,7 +1,12 @@
|
|||
// We need to import the CSS so that webpack will load it.
|
||||
// The MiniCssExtractPlugin is used to separate it out into
|
||||
// its own CSS file.
|
||||
import "../css/app.scss"
|
||||
import "../css/app.scss";
|
||||
|
||||
// Import icons for sprite-loader
|
||||
// navbar brand icon
|
||||
import "../node_modules/@mdi/svg/svg/desktop-classic.svg"; // brand
|
||||
// other:///
|
||||
|
||||
// webpack automatically bundles all modules in your
|
||||
// entry points. Those entry points can be configured
|
||||
|
@ -12,25 +17,34 @@ import "../css/app.scss"
|
|||
// import {Socket} from "phoenix"
|
||||
// import socket from "./socket"
|
||||
//
|
||||
import "phoenix_html"
|
||||
import {Socket} from "phoenix"
|
||||
import topbar from "topbar"
|
||||
import {LiveSocket} from "phoenix_live_view"
|
||||
import "phoenix_html";
|
||||
import { Socket } from "phoenix";
|
||||
import topbar from "topbar";
|
||||
import { LiveSocket } from "phoenix_live_view";
|
||||
|
||||
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
|
||||
// // Bootstrap v5 js imports
|
||||
import "bootstrap/js/dist/collapse";
|
||||
// import "bootstrap/js/dist/dropdown";
|
||||
// Bootstrap helpers
|
||||
import "./_hamburger-helper";
|
||||
|
||||
let csrfToken = document
|
||||
.querySelector("meta[name='csrf-token']")
|
||||
.getAttribute("content");
|
||||
let liveSocket = new LiveSocket("/live", Socket, {
|
||||
params: { _csrf_token: csrfToken },
|
||||
});
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
||||
window.addEventListener("phx:page-loading-start", info => topbar.show())
|
||||
window.addEventListener("phx:page-loading-stop", info => topbar.hide())
|
||||
topbar.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" });
|
||||
window.addEventListener("phx:page-loading-start", (info) => topbar.show());
|
||||
window.addEventListener("phx:page-loading-stop", (info) => topbar.hide());
|
||||
|
||||
// connect if there are any LiveViews on the page
|
||||
liveSocket.connect()
|
||||
liveSocket.connect();
|
||||
|
||||
// expose liveSocket on window for web console debug logs and latency simulation:
|
||||
// >> liveSocket.enableDebug()
|
||||
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
|
||||
// >> liveSocket.disableLatencySim()
|
||||
window.liveSocket = liveSocket
|
||||
|
||||
window.liveSocket = liveSocket;
|
||||
|
|
13754
assets/package-lock.json
generated
13754
assets/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -3,28 +3,43 @@
|
|||
"description": " ",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"deploy": "webpack --mode production",
|
||||
"deploy": "NODE_ENV=production webpack --mode production",
|
||||
"watch": "webpack --mode development --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/fira-code": "^4.x",
|
||||
"@fontsource/fira-mono": "^4.x",
|
||||
"@fontsource/lato": "^4.x",
|
||||
"@fontsource/righteous": "^4.x",
|
||||
"@mdi/svg": "^5.9.55",
|
||||
"@popperjs/core": "^2.8.4",
|
||||
"bootstrap": "^5.0.0-beta3",
|
||||
"bootstrap-icons": "^1.4.0",
|
||||
"hamburgers": "^1.1.3",
|
||||
"phoenix": "file:../deps/phoenix",
|
||||
"phoenix_html": "file:../deps/phoenix_html",
|
||||
"phoenix_live_view": "file:../deps/phoenix_live_view",
|
||||
"topbar": "^0.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"babel-loader": "^8.0.0",
|
||||
"copy-webpack-plugin": "^5.1.1",
|
||||
"css-loader": "^3.4.2",
|
||||
"hard-source-webpack-plugin": "^0.13.1",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"terser-webpack-plugin": "^2.3.2",
|
||||
"webpack": "^4.41.5",
|
||||
"webpack-cli": "^3.3.2"
|
||||
"@babel/core": "^7.x",
|
||||
"@babel/preset-env": "^7.x",
|
||||
"autoprefixer": "^10.2.4",
|
||||
"babel-loader": "^8.x",
|
||||
"copy-webpack-plugin": "^8.x",
|
||||
"css-loader": "^5.x",
|
||||
"css-minimizer-webpack-plugin": "^1.x",
|
||||
"file-loader": "^6.2.0",
|
||||
"glob-all": "^3.2.1",
|
||||
"mini-css-extract-plugin": "^1.x",
|
||||
"postcss": "^8.2.6",
|
||||
"postcss-loader": "^5.0.0",
|
||||
"postcss-scss": "^3.0.4",
|
||||
"purgecss-webpack-plugin": "^4.0.2",
|
||||
"sass": "^1.x",
|
||||
"sass-loader": "^11.x",
|
||||
"svg-sprite-loader": "^6.x",
|
||||
"webpack": "^5.x",
|
||||
"webpack-cli": "^4.x"
|
||||
}
|
||||
}
|
||||
|
|
4
assets/postcss.config.js
Normal file
4
assets/postcss.config.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
parser: require("postcss-scss"),
|
||||
plugins: [require("autoprefixer")],
|
||||
};
|
|
@ -1,53 +1,105 @@
|
|||
const path = require('path');
|
||||
const glob = require('glob');
|
||||
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const path = require("path");
|
||||
const glob = require("glob-all");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
|
||||
const PurgecssPlugin = require("purgecss-webpack-plugin");
|
||||
|
||||
module.exports = (env, options) => {
|
||||
const devMode = options.mode !== 'production';
|
||||
const devMode = options.mode !== "production";
|
||||
|
||||
return {
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({ cache: true, parallel: true, sourceMap: devMode }),
|
||||
new OptimizeCSSAssetsPlugin({})
|
||||
]
|
||||
},
|
||||
entry: {
|
||||
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
|
||||
app: glob.sync("./vendor/**/*.js").concat(["./js/app.js"]),
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
path: path.resolve(__dirname, '../priv/static/js'),
|
||||
publicPath: '/js/'
|
||||
path: path.resolve(__dirname, "../priv/static/js"),
|
||||
filename: "[name].js",
|
||||
publicPath: "/js/",
|
||||
},
|
||||
devtool: devMode ? 'eval-cheap-module-source-map' : undefined,
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
loader: "babel-loader",
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.[s]?css$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
'sass-loader',
|
||||
"css-loader",
|
||||
"sass-loader",
|
||||
"postcss-loader",
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [
|
||||
{
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
esModule: false,
|
||||
name: "[name].[ext]",
|
||||
outputPath: "../fonts",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
loader: "svg-sprite-loader",
|
||||
options: {
|
||||
extract: true,
|
||||
spriteFilename: "icons.svg",
|
||||
publicPath: "../images/",
|
||||
symbolId: (filePath) => {
|
||||
if (filePath.includes("bootstrap-icons")) {
|
||||
return `bi-${path.basename(filePath).slice(0, -4)}`;
|
||||
} else if (filePath.includes("@mdi")) {
|
||||
return `mdi-${path.basename(filePath).slice(0, -4)}`;
|
||||
} else if (filePath.includes("heroicons")) {
|
||||
if (filePath.includes("outline")) {
|
||||
return `hio-${path.basename(filePath).slice(0, -4)}`;
|
||||
} else {
|
||||
return `his-${path.basename(filePath).slice(0, -4)}`;
|
||||
}
|
||||
} else {
|
||||
return `${path.basename(filePath).slice(0, -4)}`;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({ filename: '../css/app.css' }),
|
||||
new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
|
||||
]
|
||||
.concat(devMode ? [new HardSourceWebpackPlugin()] : [])
|
||||
}
|
||||
new MiniCssExtractPlugin({ filename: "../css/app.css" }),
|
||||
new SpriteLoaderPlugin({ plainSprite: true }),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [{ from: "static/", to: "../" }],
|
||||
}),
|
||||
].concat(
|
||||
devMode
|
||||
? []
|
||||
: [
|
||||
new PurgecssPlugin({
|
||||
paths: glob.sync([
|
||||
"../**/*.html.leex",
|
||||
"../**/*.html.eex",
|
||||
"../**/views/**/*.ex",
|
||||
"../**/live/**/*.ex",
|
||||
"./js/**/*.js",
|
||||
]),
|
||||
safelist: [/phx/, /topbar/],
|
||||
}),
|
||||
]
|
||||
),
|
||||
optimization: {
|
||||
minimizer: ["...", new CssMinimizerPlugin()],
|
||||
},
|
||||
devtool: devMode ? "source-map" : undefined,
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue