From cc5e75354fc9c4f02bf2a5adcceef3f46b981c89 Mon Sep 17 00:00:00 2001 From: Tony Air Date: Sat, 7 Sep 2019 08:42:29 +0700 Subject: [PATCH] Mapbox integration, Bootstrap4 menu hover, Example of PageType.js --- src/js/_components/_ui.hover.js | 141 ++++++++++++++ src/js/_components/_ui.map.api.js | 184 +++++++++++++----- src/js/_components/_ui.menu.js | 32 +-- src/js/_events.js | 3 + src/js/_main.js | 22 ++- src/js/_pageType_and_component_template.js | 92 --------- src/js/app.js | 13 +- ...ce_it_to_types_folder_PageTypeClassName.js | 64 ++++++ src/scss/_components/_ui.main.scss | 112 +++++++++-- src/scss/_components/_ui.map.scss | 20 ++ src/scss/_layout.scss | 7 +- src/scss/_typography.scss | 14 +- 12 files changed, 503 insertions(+), 201 deletions(-) create mode 100755 src/js/_components/_ui.hover.js delete mode 100755 src/js/_pageType_and_component_template.js create mode 100755 src/js/place_it_to_types_folder_PageTypeClassName.js diff --git a/src/js/_components/_ui.hover.js b/src/js/_components/_ui.hover.js new file mode 100755 index 0000000..c24417f --- /dev/null +++ b/src/js/_components/_ui.hover.js @@ -0,0 +1,141 @@ +"use strict"; + +import $ from 'jquery'; +import Events from '../_events'; +import 'jquery-hoverintent/jquery.hoverIntent.js'; + +const HoverUI = (($) => { + // Constants + const W = window; + const D = document; + const $Html = $('html'); + const $Body = $('body'); + + const NAME = 'jsHoverUI'; + const DATA_KEY = NAME; + + class HoverUI { + // Constructor + constructor(el) { + const ui = this; + const $el = $(el); + ui.$el = $el; + + // find parent + let $parent = $el.parents('.nav-item, .dropdown'); + $parent = $parent && $parent.length ? $parent.first() : null; + //$parent = $parent ? $parent : $el.parent(); + ui.$parent = $parent; + + // find target + let $target = $el.data('target'); + $target = $target && $target.length ? $target : null; + $target = $target ? $target : ($parent ? $parent.find('.dropdown-menu') : null); + + if (!$target || !$target.length) { + console.warn(`${NAME}: Missing target for:`); + console.warn($el); + return; + } + + ui.$target = $target; + + const $triger = $parent ? $parent : $el; + ui.$triger = $triger; + + // integrate with dropdown-toggle + $('[data-toggle="dropdown"]').on('click touch', (e) => { + ui.hide(); + }); + + if (!W.isTouch) { + $triger.hoverIntent({ + sensitivity: 10, + interval: 50, + over: () => { + ui.show(); + }, + out: () => { + ui.hide(); + }, + }); + } + + $el.on('click touch', (e) => { + e.preventDefault(); + + if (ui.isShown()) { + ui.hide(); + } else { + ui.show(); + } + }); + + $triger.addClass(`${NAME}-active`); + } + + isShown() { + return this.$target.hasClass('show'); + } + + show() { + const ui = this; + ui.$el.parents('.dropdown, .dropdown-menu').each((i, el) => { + const $el = $(el); + $el.siblings('.dropdown, .dropdown-menu').removeClass('show'); + $el.addClass('show'); + }); + + ui.$target.addClass('show'); + } + + hide() { + const ui = this; + ui.$target.removeClass('show'); + ui.$target.parent('.dropdown').removeClass('show'); + } + + dispose() { + const ui = this; + const $el = ui.$el; + + ui.$triger.removeClass(`${NAME}-active`); + $.removeData($el, DATA_KEY); + + ui.$el = null; + ui.$parent = null; + ui.$target = null; + ui.$triger = null; + } + + static _jQueryInterface() { + return this.each(function() { + // attach functionality to el + const $el = $(this); + let data = $el.data(DATA_KEY); + + if (!data) { + data = new HoverUI(this); + $el.data(DATA_KEY, data); + } + }); + } + } + + // jQuery interface + $.fn[NAME] = HoverUI._jQueryInterface; + $.fn[NAME].Constructor = HoverUI; + $.fn[NAME].noConflict = function() { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return HoverUI._jQueryInterface; + }; + + // auto-apply + $('[data-toggle="hover"]').ready(() => { + $('[data-toggle="hover"]').jsHoverUI(); + }); + + return HoverUI; +})($); + +export default HoverUI; diff --git a/src/js/_components/_ui.map.api.js b/src/js/_components/_ui.map.api.js index f789bf2..1517692 100755 --- a/src/js/_components/_ui.map.api.js +++ b/src/js/_components/_ui.map.api.js @@ -1,11 +1,11 @@ 'use strict'; import $ from 'jquery'; -import Events from "../_events"; -import mapBoxGL from "mapbox-gl"; +import Events from '../_events'; +import mapBoxGL from 'mapbox-gl'; //import "./mapStorage"; -import "../../scss/_components/_ui.map.scss"; +import '../../scss/_components/_ui.map.scss'; const W = window; @@ -21,41 +21,45 @@ const MapAPI = (($) => { class MapAPI { // Constructor - constructor(element) { - this._element = element; - const $element = $(this._element); - const geojson = $element.data('geojson'); + constructor(el) { + this._el = el; + const $el = $(this._el); + const config = $el.data(); const center = [ - ($element.data('lng') ? $element.data('lng') : $BODY.data('default-lng')), - ($element.data('lat') ? $element.data('lat') : $BODY.data('default-lat')), + (config['lng'] ? config['lng'] : $BODY.data('default-lng')), + (config['lat'] ? config['lat'] : $BODY.data('default-lat')), ]; - const popup = new mapboxgl.Popup({ + const popup = new mapBoxGL.Popup({ closeOnClick: false, className: 'popup', }); - currentStyle = this.getStyle(); - mapBoxGL.accessToken = $element.data('key'); + currentStyle = this.getStyle(); + mapBoxGL.accessToken = $el.data('key'); Map = new mapBoxGL.Map({ - 'container': $element.find('.mapAPI-map')[0], - center, - //hash: true, - 'style': currentStyle, - //localIdeographFontFamily: $BODY.css('font-family'), - 'zoom': ($element.data('map-zoom') ? $element.data('map-zoom') : 10), - 'attributionControl': false, - /*transformRequest: (url, resourceType)=> { - if(resourceType === 'Source' && url.startsWith('http://myHost')) { - return { - url: url.replace('http', 'https'), - headers: { 'my-custom-header': true}, - credentials: 'include' // Include cookies for cross-origin requests - } - } - }*/ - }) + 'container': $el.find('.mapAPI-map')[0], + 'center': center, + //hash: true, + 'style': currentStyle, + 'localIdeographFontFamily': $BODY.css('font-family'), + 'zoom': (config['mapZoom'] ? config['mapZoom'] : 10), + 'attributionControl': false, + 'antialias': true, + /*'pitch': 45, + 'bearing': -17.6*/ + + /*transformRequest: (url, resourceType)=> { + if(resourceType === 'Source' && url.startsWith('http://myHost')) { + return { + url: url.replace('http', 'https'), + headers: { 'my-custom-header': true}, + credentials: 'include' // Include cookies for cross-origin requests + } + } + }*/ + }) .addControl(new mapBoxGL.AttributionControl({ compact: true, })) @@ -66,34 +70,107 @@ const MapAPI = (($) => { }, trackUserLocation: true, }), 'bottom-right') - .addControl(new mapboxgl.ScaleControl({ + .addControl(new mapBoxGL.ScaleControl({ maxWidth: 80, unit: 'metric', - }), 'top-left'); + }), 'top-left') + .addControl(new mapboxgl.FullscreenControl()); + + $el.data('Map', Map); + $el.data('Popup', popup); // event.target Map.on('load', (e) => { + // Insert the layer beneath any symbol layer. + if (config['3d']) { + const layers = Map.getStyle().layers; + let labelLayerId; + for (let i = 0; i < layers.length; i++) { + if (layers[i].type === 'symbol' && layers[i].layout['text-field']) { + labelLayerId = layers[i].id; + break; + } + } + + Map.addLayer({ + 'id': '3d-buildings', + 'source': 'composite', + 'source-layer': 'building', + 'filter': ['==', 'extrude', 'true'], + 'type': 'fill-extrusion', + 'minzoom': 15, + 'paint': { + 'fill-extrusion-color': '#aaa', + + // use an 'interpolate' expression to add a smooth transition effect to the + // buildings as the user zooms in + 'fill-extrusion-height': [ + "interpolate", ["linear"], + ["zoom"], + 15, 0, + 15.05, ["get", "height"] + ], + 'fill-extrusion-base': [ + "interpolate", ["linear"], + ["zoom"], + 15, 0, + 15.05, ["get", "min_height"] + ], + 'fill-extrusion-opacity': .6 + } + }, labelLayerId); + } + + const firstMarker = config['geojson'].features[0].geometry.coordinates; + //Map.setCenter(firstMarker); + const bounds = new mapBoxGL.LngLatBounds(firstMarker, firstMarker); + // add markers to map - geojson.features.forEach((marker) => { - // create a DOM element for the marker - const $el = $(`
${ marker.icon }
`); + config['geojson'].features.forEach((marker) => { + const id = marker.id; + const crds = marker.geometry.coordinates; + const content = marker.properties.content; + + // create a DOM el for the marker + const $el = $(`
${ marker.icon }
`); $el.on('click', () => { - console.log('Marker click'); - const coordinates = marker.geometry.coordinates; - const content = marker.properties.content; - console.log(popup); - popup.setLngLat(coordinates) + popup.setLngLat(crds) .setHTML(content) .addTo(Map); + + if (config['flyToMarker']) { + Map.flyTo({ + center: crds, + zoom: 17, + }); + } + + $el.trigger(Events.MAPMARKERCLICK); }); // add marker to map - new mapboxgl.Marker($el[0]) - .setLngLat(marker.geometry.coordinates) + new mapBoxGL.Marker($el[0]) + .setLngLat(crds) .addTo(Map); + bounds.extend(crds); }); + Map.fitBounds(bounds, { + padding: 30, + }); + + popup.on('close', (e) => { + if (config['flyToBounds']) { + Map.fitBounds(bounds, { + padding: 30, + }); + } + $el.trigger(Events.MAPPOPUPCLOSE); + }); + + $el.trigger(Events.MAPLOADED); + $(W).trigger(Events.MAPLOADED); console.log('Map is loaded'); }); @@ -124,7 +201,7 @@ const MapAPI = (($) => { }, 36000); - $element.addClass(`${NAME}-active`); + $el.addClass(`${NAME}-active`); } // Public methods @@ -133,36 +210,37 @@ const MapAPI = (($) => { } getStyle() { + const $el = $(this._el); + return $el.data('map-style'); return 'mapbox://styles/mapbox/streets-v9'; const hour = new Date().getHours(); if (hour < 6 || hour > 18) { // night //return 'mapbox://styles/mapbox/streets-v7'; return 'mapbox://styles/tony-air/cjeacwih92iu42rpd8tcmuyb2'; - } else { - // day - return 'mapbox://styles/mapbox/streets-v9'; } + // day + return 'mapbox://styles/mapbox/streets-v9'; } dispose() { - const $element = $(this._element); + const $el = $(this._el); - $element.removeClass(`${NAME}-active`); - $.removeData(this._element, DATA_KEY); - this._element = null; + $el.removeClass(`${NAME}-active`); + $.removeData(this._el, DATA_KEY); + this._el = null; } static _jQueryInterface() { if (typeof W.localStorage !== 'undefined') { return this.each(function() { - // attach functionality to element - const $element = $(this); - let data = $element.data(DATA_KEY); + // attach functionality to el + const $el = $(this); + let data = $el.data(DATA_KEY); if (!data) { data = new MapAPI(this); - $element.data(DATA_KEY, data); + $el.data(DATA_KEY, data); } }); } diff --git a/src/js/_components/_ui.menu.js b/src/js/_components/_ui.menu.js index 44c6c88..8e52cea 100755 --- a/src/js/_components/_ui.menu.js +++ b/src/js/_components/_ui.menu.js @@ -7,37 +7,37 @@ const SlidingMenu = (($) => { class SlidingMenu { // Constructor - constructor(element) { - this._element = element; - const $element = $(this._element); - $element.addClass(`${NAME}-active`); + constructor(el) { + const $el = $(this._el); + this.$el = $el; + $el.addClass(`${NAME}-active`); // esc button - $(window).on('keyup',((e) => { + $(window).on('keyup', ((e) => { if (e.which === 27) { - $element.find('.is-open[data-toggle="offcanvas"]').click(); + $el.find('.is-open[data-toggle="offcanvas"]').click(); } })); } // Public methods dispose() { - console.log(`Disposing: ${NAME} elements`); + console.log(`Disposing: ${NAME} els`); - $(this._element).removeClass(`${NAME}-active`); - $.removeData(this._element, DATA_KEY); - this._element = null; + this.$el.removeClass(`${NAME}-active`); + $.removeData(this.$el, DATA_KEY); + this.$el = null; } static _jQueryInterface() { - return this.each(function () { - // attach functionality to element - const $element = $(this); - let data = $element.data(DATA_KEY); + return this.each(function() { + // attach functionality to el + const $el = $(this); + let data = $el.data(DATA_KEY); if (!data) { data = new SlidingMenu(this); - $element.data(DATA_KEY, data); + $el.data(DATA_KEY, data); } }); } @@ -46,7 +46,7 @@ const SlidingMenu = (($) => { // jQuery interface $.fn[NAME] = SlidingMenu._jQueryInterface; $.fn[NAME].Constructor = SlidingMenu; - $.fn[NAME].noConflict = function () { + $.fn[NAME].noConflict = function() { $.fn[NAME] = JQUERY_NO_CONFLICT; return SlidingMenu._jQueryInterface; }; diff --git a/src/js/_events.js b/src/js/_events.js index 5c0ed2e..c962402 100755 --- a/src/js/_events.js +++ b/src/js/_events.js @@ -5,6 +5,9 @@ module.exports = { AJAX: 'ajax-load', LOADED: 'load', + MAPLOADED: 'map-loaded', + MAPMARKERCLICK: 'map-marker-click', + MAPPOPUPCLOSE: 'map-popup-close', SET_TARGET_UPDATE: 'set-target-update', RESTORE_FIELD: 'restore-field', FORM_INIT_BASICS: 'form-basics', diff --git a/src/js/_main.js b/src/js/_main.js index 57f424f..c0ccb8f 100755 --- a/src/js/_main.js +++ b/src/js/_main.js @@ -15,20 +15,40 @@ import './_components/routes/index'; import Events from './_events'; import Spinner from './_components/_ui.spinner'; +// youtube video preview image import './_components/_ui.video.preview'; + import './_components/_ui.carousel'; import './_components/_ui.menu'; +// Bootstrap hover menu +import './_components/_ui.hover'; + import FormBasics from './_components/_ui.form.basics'; + +// Toggle bootstrap form fields //import FormToggleUI from './_components/_ui.form.fields.toggle'; + +// Bootstrap Date & Time fields //import FormDatetime from './_components/_ui.form.datetime'; -import FormStepped from './_components/_ui.form.stepped'; + +// Stepped forms functionality +//import FormStepped from './_components/_ui.form.stepped'; + +// Forms validation functionality import FormValidate from './_components/_ui.form.validate'; + +// Store forms data into localStorage import FormStorage from './_components/_ui.form.storage'; + +// client-side images cropping //import FormCroppie from './_components/_ui.form.croppie'; +// AJAX functionality import AjaxUI from './_components/_ui.ajax'; + +// Google NoCaptcha fields import NoCaptcha from './_components/_ui.nocaptcha'; import SmoothScroll from 'smooth-scroll'; diff --git a/src/js/_pageType_and_component_template.js b/src/js/_pageType_and_component_template.js deleted file mode 100755 index d43863e..0000000 --- a/src/js/_pageType_and_component_template.js +++ /dev/null @@ -1,92 +0,0 @@ -import $ from 'jquery'; - -const TypePage = (($) => { - // Constants - const NAME = 'TypePage'; - // const DATA_KEY = "pageUI." + NAME; - - const Events = require('./_events'); - - class TypePage { - // Static methods - static init() { - console.log(`Initializing: ${NAME}`); - } - - static destroy() { - console.log(`Destroying: ${NAME}`); - } - - /** - * jQuery extension functions - // Constructor - constructor(element) { - console.log("Constructing: " + NAME + " elements"); - - this._element = element; - } - - // Public methods - dispose() { - console.log("Disposing: " + NAME + " elements"); - - $.removeData(this._element, DATA_KEY); - this._element = null; - } - - static _jQueryInterface() { - return this.each(function () { - // attach functionality to element - const $element = $(this); - let data = $element.data(DATA_KEY); - - if (!data) { - data = new TypePage(this); - $element.data(DATA_KEY, data); - } - }) - } - */ - } - - $(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { - TypePage.init(); - }); - - // JQuery extension functions - /* - $.fn[NAME] = TypePage._jQueryInterface; - $.fn[NAME].Constructor = TypePage; - $.fn[NAME].noConflict = function () { - $.fn[NAME] = JQUERY_NO_CONFLICT; - return TypePage._jQueryInterface; - }; - // auto-apply - $(".ui." + NAME).ready(function(){ - $(".ui." + NAME).TypePage(); - }); */ - - return TypePage; -})($); - -export default TypePage; - - -/* -import $ from 'jquery'; - -(function (G) { - G.initPulsePage = function () { - G.destroyPulsePage(); - }; - - G.destroyPulsePage = function () {}; - - $(window).on("ajax-content-loaded", function () { - G.initPulsePage(); - }); - - $(document).ready(function () { - G.initPulsePage(); - }); -}(this)); */ diff --git a/src/js/app.js b/src/js/app.js index f23e37b..3f9ed37 100755 --- a/src/js/app.js +++ b/src/js/app.js @@ -7,10 +7,7 @@ import 'bootstrap/js/dist/alert'; import 'bootstrap/js/dist/button'; import 'bootstrap/js/dist/carousel'; import 'bootstrap/js/dist/collapse'; - -// conflicting with bootstrap-select/dist/js/bootstrap-select import 'bootstrap/js/dist/dropdown'; - import 'bootstrap/js/dist/modal'; import 'bootstrap/js/dist/tooltip'; import 'bootstrap/js/dist/popover'; @@ -18,14 +15,12 @@ import 'bootstrap/js/dist/scrollspy'; import 'bootstrap/js/dist/tab'; // -//import Vue from 'vue/dist/vue.esm.js'; - -// import Bootstrap-Vue -/*import { Carousel } from 'bootstrap-vue/es/components'; -Vue.use(Carousel);*/ +// Offcanvas menu import 'offcanvas-bootstrap/dist/js/bootstrap.offcanvas'; -import 'jquery-zoom/jquery.zoom'; + +// Uncomment it to enable meta-lightbox zooming on hover +//import 'jquery-zoom/jquery.zoom'; import 'meta-lightbox/meta-lightbox'; import './_main'; diff --git a/src/js/place_it_to_types_folder_PageTypeClassName.js b/src/js/place_it_to_types_folder_PageTypeClassName.js new file mode 100755 index 0000000..0072927 --- /dev/null +++ b/src/js/place_it_to_types_folder_PageTypeClassName.js @@ -0,0 +1,64 @@ +/* + *************************************************************** + * *** PAGE SPECIFIC CODDING *** + * Place it into app/client/src/js/types + * Require page specific css as mentioned bellow + * + * If you don't need page specific JS (only CSS) + * you can create SCSS file at app/client/src/scss/types + * !!! BUT NOT BOTH at "types" folder !!! + *************************************************************** + * + * An example of Page specific JS and Mapbox functionality + * Take a look to app/templates/Objects/Map.ss for HTML + * Take a look to https://github.com/a2nt/silverstripe-mapboxfield/blob/master/README.md for Data Structure + */ +"use strict"; + +// your page specific css +import '../scss/_types/PageTypeClassName.scss'; + +import $ from 'jquery'; +import Events from '../_events'; + +// Mapbox API +import '../_components/_ui.map.api'; + +const PageTypeUI = (($) => { + // Constants + const W = window; + const D = document; + const $Body = $('body'); + + const NAME = 'PageTypeUI'; + class PageTypeUI { + // Static methods + + static init() { + this.dispose(); + console.log(`Initializing: ${NAME}`); + // custom page specific functionality + } + + static initMap() { + // custom map functionality + } + + static dispose() { + console.log(`Destroying: ${NAME}`); + } + } + + $(W).on(`${Events.AJAX} ${Events.LOADED}`, () => { + PageTypeUI.init(); + }); + + $(W).on(Events.MAPLOADED, () => { + PageTypeUI.initMap(); + }); + + return PageTypeUI; + +})($); + +export default PageTypeUI; diff --git a/src/scss/_components/_ui.main.scss b/src/scss/_components/_ui.main.scss index 21582e6..9582a87 100755 --- a/src/scss/_components/_ui.main.scss +++ b/src/scss/_components/_ui.main.scss @@ -146,22 +146,36 @@ button, input, optgroup, select, textarea, } // dropdown hover +/* +.dropdown.show { + .dropdown { + &:hover, + &:focus { + .dropdown-menu { + display: block; + } + } + } +} @media only screen and (min-width: map-get($grid-breakpoints, "md")) { - .dropdown-hover .collapse ul li { + .dropdown-hover ul li { position: relative; } - .dropdown-hover .collapse ul li:hover { - > .dropdown-toggle::after { - transform: rotate(-90deg); - } + .dropdown-hover ul li { + &:hover, + &:focus { + > .dropdown-toggle::after { + transform: rotate(-90deg); + } - > ul { - display: block; + > ul { + display: block; + } } } - .dropdown-hover .collapse ul ul { + .dropdown-hover ul ul { position: absolute; top: 100%; left: 0; @@ -169,16 +183,20 @@ button, input, optgroup, select, textarea, display: none; } - /*******/ - .dropdown-hover .collapse ul ul li { + .dropdown-hover ul ul li { position: relative; } - .dropdown-hover .collapse ul ul li:hover > ul { - display: block; + .dropdown-hover ul ul li { + &:hover, + &:focus { + > ul { + display: block; + } + } } - .dropdown-hover .collapse ul ul ul { + .dropdown-hover ul ul ul { position: absolute; top: 0; left: 100%; @@ -186,16 +204,20 @@ button, input, optgroup, select, textarea, display: none; } - /*******/ - .dropdown-hover .collapse ul ul ul li { + .dropdown-hover ul ul ul li { position: relative; } - .dropdown-hover .collapse ul ul ul li:hover ul { - display: block; + .dropdown-hover ul ul ul li { + &:hover, + &:focus { + ul { + display: block; + } + } } - .dropdown-hover .collapse ul ul ul ul { + .dropdown-hover ul ul ul ul { position: absolute; top: 0; left: -100%; @@ -203,9 +225,28 @@ button, input, optgroup, select, textarea, display: none; z-index: 1; } -} +}*/ // dark dropdowns +.navbar-dark { + .nav-link { + @include hover-focus { + background: $navbar-dark-hover-background; + } + } + + .active > .nav-link, + .nav-link.active { + background: $navbar-dark-active-background; + } + + .nav-link.show, + .navbar-nav .show > .nav-link { + background: $navbar-dark-show-background; + color: $navbar-dark-show-color; + } +} + .dropdown-menu.bg-dark { border-color: $dark; @@ -231,8 +272,37 @@ button, input, optgroup, select, textarea, .dropdown-item { @include hover-focus { - color: $navbar-dark-brand-hover-color; - background: $dark; + color: $navbar-dark-hover-color; + background: $navbar-dark-hover-background; + } + + + &.active, + &:active { + background: $navbar-dark-active-background; + } + + .nav-link { + background: none; } } } + +// pulse +.pulse { + animation: pulse 0.8s linear infinite; +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + + 50% { + transform: scale(0.8); + } + + 100% { + transform: scale(1); + } +} diff --git a/src/scss/_components/_ui.map.scss b/src/scss/_components/_ui.map.scss index 8b24d61..abf817e 100755 --- a/src/scss/_components/_ui.map.scss +++ b/src/scss/_components/_ui.map.scss @@ -6,10 +6,30 @@ margin-bottom: 1rem; } +.mapboxgl-popup-content { + box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.4); + + .mapboxgl-popup-close-button { + font-size: 2rem; + padding: .5rem; + + &:hover, + &:focus { + background: $primary; + color: $white; + } + } +} + .mapboxgl-marker { width: 30px; height: 30px; font-size: 30px; cursor: pointer; text-align: center; + color: $primary; + + .fas { + animation: pulse 0.8s linear infinite; + } } diff --git a/src/scss/_layout.scss b/src/scss/_layout.scss index af74152..2642bb6 100755 --- a/src/scss/_layout.scss +++ b/src/scss/_layout.scss @@ -1,6 +1,3 @@ -@import "~bootstrap-datepicker/dist/css/bootstrap-datepicker.css"; -@import "~bootstrap-timepicker/css/bootstrap-timepicker.css"; - /** * Your custom style */ @@ -55,6 +52,10 @@ body.shrink {} } } + &.dynamic__elements__image__elements__elementimage { + text-align: center; + } + &.site__elements__accordion { .card { padding-left: 0; diff --git a/src/scss/_typography.scss b/src/scss/_typography.scss index 91df2db..0f0fd4e 100755 --- a/src/scss/_typography.scss +++ b/src/scss/_typography.scss @@ -4,14 +4,16 @@ h1, h2, h3, h4, h5, h6, } .bg-dark { - h1, h2, h3, h4, h5, h6, - .h1, .h2, .h3, .h4, .h5, .h6, - .typography, - a { - color: $white; - } + h1, h2, h3, h4, h5, h6, + .h1, .h2, .h3, .h4, .h5, .h6, + .typography, + a { + color: $white; + } } .typography { + @include clearfix; + @import "./types/editor"; }