mirror of
https://github.com/a2nt/webpack-bootstrap-ui-kit.git
synced 2024-10-22 11:05:45 +02:00
UI: captcha on window load and on AJAX
This commit is contained in:
parent
5f54ca9d6a
commit
35bd02ac50
74
src/js/ui/captcha.js
Normal file
74
src/js/ui/captcha.js
Normal file
@ -0,0 +1,74 @@
|
||||
import Events from '../_events'
|
||||
|
||||
const CaptchaUI = ((window) => {
|
||||
const NAME = 'js-captcha'
|
||||
|
||||
const init = () => {
|
||||
console.log(`${NAME}: init`)
|
||||
|
||||
const submitListener = (e) => {
|
||||
console.log(`${NAME}: Validating Captcha ...`)
|
||||
const field = e.currentTarget.querySelectorAll(`.${NAME}, .g-recaptcha`).forEach((el) => {
|
||||
grecaptcha.execute(el.dataset.widgetid)
|
||||
})
|
||||
}
|
||||
|
||||
const attachCaptcha = () => {
|
||||
console.log(`${NAME}: Rendering Captcha ...`)
|
||||
|
||||
const fields = document.querySelectorAll(`.${NAME}, .g-recaptcha`)
|
||||
const grecaptcha = window.grecaptcha
|
||||
|
||||
fields.forEach((el, i) => {
|
||||
if (el.dataset.widgetid || el.innerHTML !== '') {
|
||||
// already initialized
|
||||
return
|
||||
}
|
||||
|
||||
const form = el.closest(form)
|
||||
const widgetid = grecaptcha.render(el, el.dataset)
|
||||
el.dataset.widgetid = widgetid
|
||||
|
||||
if(el.dataset.size === 'invisible' && !el.dataset.callback){
|
||||
grecaptcha.execute(widgetid)
|
||||
form.addEventListener('submit', submitListener)
|
||||
}
|
||||
|
||||
el.classList.add(`${NAME}-active`)
|
||||
el.dispatchEvent(new Event(`${NAME}-ready`))
|
||||
})
|
||||
}
|
||||
|
||||
const loadScript = (callback) => {
|
||||
if(typeof window.grecaptcha !== 'undefined'){
|
||||
callback()
|
||||
}
|
||||
|
||||
console.log(`${NAME}: Loading Captcha API ...`)
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.id = 'captchaAPI';
|
||||
script.src = 'https://www.google.com/recaptcha/api.js?render=explicit&hl=' + document.querySelector('html').getAttribute('lang').substr(0,2)
|
||||
script.async = true
|
||||
script.onload = function() {
|
||||
console.log(`${NAME}: Captcha API is loaded.`)
|
||||
callback()
|
||||
}
|
||||
|
||||
document.body.append(script)
|
||||
}
|
||||
|
||||
if(document.querySelectorAll('.g-recaptcha').length){
|
||||
loadScript(attachCaptcha);
|
||||
}else{
|
||||
console.log(`${NAME}: No Captcha fields.`)
|
||||
}
|
||||
|
||||
window.noCaptchaFieldRender = attachCaptcha
|
||||
}
|
||||
|
||||
window.addEventListener(`${Events.LODEDANDREADY}`, init)
|
||||
window.addEventListener(`${Events.AJAX}`, init)
|
||||
})(window)
|
||||
|
||||
export default CaptchaUI
|
@ -187,6 +187,7 @@ const CarouselUI = ((window) => {
|
||||
|
||||
el.dataset.ui = el.ui
|
||||
el.classList.add(`${NAME}-active`)
|
||||
el.dispatchEvent(new Event(`${NAME}-ready`))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -22,22 +22,22 @@ const DropdownHoverUI = ((window) => {
|
||||
const Toggle = (el) => {
|
||||
HideAll()
|
||||
|
||||
if (el.querySelector('.dropdown-menu').classList.contains('show')) {
|
||||
Hide(el)
|
||||
} else {
|
||||
Show(el)
|
||||
}
|
||||
el.querySelector('.dropdown-menu').classList.toggle('show')
|
||||
}
|
||||
|
||||
const Show = (el) => {
|
||||
const Show = (e) => {
|
||||
e.stopPropagation()
|
||||
const el = e.currentTarget
|
||||
|
||||
el.classList.add(...ACTIVECLS)
|
||||
el.closest('.dropdown').classList.add(...ACTIVECLS)
|
||||
el.querySelector('.dropdown-menu').classList.add('show')
|
||||
}
|
||||
|
||||
const Hide = (el) => {
|
||||
const Hide = (e) => {
|
||||
e.stopPropagation()
|
||||
const el = e.currentTarget
|
||||
|
||||
el.classList.remove(...ACTIVECLS)
|
||||
el.closest('.dropdown').classList.remove(...ACTIVECLS)
|
||||
el.querySelector('.dropdown-menu').classList.remove('show')
|
||||
}
|
||||
|
||||
@ -48,14 +48,8 @@ const DropdownHoverUI = ((window) => {
|
||||
const hoverableEls = document.querySelectorAll('[data-bs-toggle="hover"]')
|
||||
|
||||
const attachHoverEvents = (el) => {
|
||||
el.addEventListener('mouseover', (e) => {
|
||||
e.stopPropagation()
|
||||
Show(e.currentTarget)
|
||||
}, false)
|
||||
el.addEventListener('mouseleave', (e) => {
|
||||
e.stopPropagation()
|
||||
Hide(e.currentTarget)
|
||||
}, false)
|
||||
el.addEventListener('mouseover', Show, false)
|
||||
el.addEventListener('mouseleave', Hide, false)
|
||||
|
||||
el.classList.add(`${NAME}-active`)
|
||||
}
|
||||
|
@ -2,226 +2,246 @@
|
||||
|
||||
@import "~bootstrap/scss/mixins";
|
||||
|
||||
@mixin hover-disabled() {
|
||||
&:not(.disabled) {
|
||||
&.active,
|
||||
&:active,
|
||||
&:hover,
|
||||
&:focus {
|
||||
@content;
|
||||
}
|
||||
/// Remove the unit of a length
|
||||
/// @param {Number} $number - Number to remove unit from
|
||||
/// @return {Number} - Unitless number
|
||||
@function strip-unit($number) {
|
||||
@if type-of($number) == 'number' and not unitless($number) {
|
||||
@return $number / ($number * 0 + 1);
|
||||
}
|
||||
|
||||
@return $number;
|
||||
}
|
||||
|
||||
@function rem($pxValue) {
|
||||
@return #{strip-unit($pxValue) / strip-unit($html-font-size)}rem;
|
||||
}
|
||||
|
||||
/*.component {
|
||||
font-size: rem(14px); // or rem(14)
|
||||
}*/
|
||||
|
||||
@mixin hover-disabled() {
|
||||
&:not(.disabled) {
|
||||
&.active,
|
||||
&:active,
|
||||
&:hover,
|
||||
&:focus {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin pseudo($display: block, $pos: absolute, $content: "") {
|
||||
content: $content;
|
||||
display: $display;
|
||||
position: $pos;
|
||||
position: $pos;
|
||||
display: $display;
|
||||
content: $content;
|
||||
}
|
||||
|
||||
@mixin responsive-ratio($x, $y, $pseudo: false) {
|
||||
$padding: unquote(math.div($y, $x) * 100 + "%");
|
||||
$padding: unquote(math.div($y, $x) * 100 + "%");
|
||||
|
||||
@if $pseudo {
|
||||
&:before {
|
||||
@include pseudo($pos: relative);
|
||||
padding-top: $padding;
|
||||
width: 100%;
|
||||
@if $pseudo {
|
||||
&:before {
|
||||
width: 100%;
|
||||
padding-top: $padding;
|
||||
|
||||
@include pseudo($pos: relative);
|
||||
}
|
||||
} @else {
|
||||
padding-top: $padding;
|
||||
}
|
||||
} @else {
|
||||
padding-top: $padding;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin input-placeholder {
|
||||
&.placeholder {
|
||||
@content;
|
||||
}
|
||||
&.placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&:-moz-placeholder {
|
||||
@content;
|
||||
}
|
||||
&:-moz-placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&::-moz-placeholder {
|
||||
@content;
|
||||
}
|
||||
&::-moz-placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&:-ms-input-placeholder {
|
||||
@content;
|
||||
}
|
||||
&:-ms-input-placeholder {
|
||||
@content;
|
||||
}
|
||||
|
||||
&::-webkit-input-placeholder {
|
||||
@content;
|
||||
}
|
||||
&::-webkit-input-placeholder {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin truncate($truncation-boundary) {
|
||||
max-width: $truncation-boundary;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
max-width: $truncation-boundary;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@mixin fix-bold() {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
|
||||
&:before {
|
||||
content: attr(data-text);
|
||||
content: attr(data-text) / "";
|
||||
font-weight: bold;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
&:before {
|
||||
font-weight: bold;
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
content: attr(data-text);
|
||||
content: attr(data-text) / "";
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin dropdowns-dark() {
|
||||
.navbar-dark {
|
||||
.nav-link {
|
||||
@include hover-focus {
|
||||
background: $navbar-dark-hover-background;
|
||||
}
|
||||
.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 {
|
||||
color: $navbar-dark-show-color;
|
||||
background: $navbar-dark-show-background;
|
||||
}
|
||||
}
|
||||
|
||||
.active > .nav-link,
|
||||
.nav-link.active {
|
||||
background: $navbar-dark-active-background;
|
||||
.dropdown-menu.bg-dark {
|
||||
border-color: $dark;
|
||||
|
||||
.nav-link {
|
||||
color: $navbar-dark-color;
|
||||
|
||||
@include hover-focus {
|
||||
color: $navbar-dark-hover-color;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: default;
|
||||
color: $navbar-dark-disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
.show > .nav-link,
|
||||
.active > .nav-link,
|
||||
.nav-link.show,
|
||||
.nav-link.active {
|
||||
color: $navbar-dark-active-color;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
@include hover-focus {
|
||||
color: $navbar-dark-hover-color;
|
||||
background: $navbar-dark-hover-background;
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
background: $navbar-dark-active-background;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
|
||||
.nav-link {
|
||||
color: $navbar-dark-color;
|
||||
|
||||
@include hover-focus {
|
||||
color: $navbar-dark-hover-color;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: $navbar-dark-disabled-color;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.show > .nav-link,
|
||||
.active > .nav-link,
|
||||
.nav-link.show,
|
||||
.nav-link.active {
|
||||
color: $navbar-dark-active-color;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
@include hover-focus {
|
||||
background: $navbar-dark-hover-background;
|
||||
color: $navbar-dark-hover-color;
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
background: $navbar-dark-active-background;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin dropdown-hovers() {
|
||||
.dropdown.show {
|
||||
.dropdown {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
> .dropdown-menu {
|
||||
display: block;
|
||||
.dropdown.show {
|
||||
.dropdown {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
> .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: map-get($grid-breakpoints, "md")) {
|
||||
.dropdown-hover ul li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-hover ul li {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
> .dropdown-toggle::after {
|
||||
transform: rotate(-90deg);
|
||||
@media only screen and (min-width: map-get($grid-breakpoints, "md")) {
|
||||
.dropdown-hover ul li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
> ul {
|
||||
display: block;
|
||||
.dropdown-hover ul li {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
> .dropdown-toggle::after {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
> ul {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul {
|
||||
display: none;
|
||||
left: 0;
|
||||
min-width: 250px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul li {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
> ul {
|
||||
display: block;
|
||||
.dropdown-hover ul ul {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
display: none;
|
||||
min-width: 250px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul {
|
||||
display: none;
|
||||
left: 100%;
|
||||
min-width: 250px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul li {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
ul {
|
||||
display: block;
|
||||
.dropdown-hover ul ul li {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul ul {
|
||||
display: none;
|
||||
left: -100%;
|
||||
min-width: 250px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
.dropdown-hover ul ul li {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
> ul {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
display: none;
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul li {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul li {
|
||||
&:hover,
|
||||
&.active,
|
||||
&:focus {
|
||||
ul {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-hover ul ul ul ul {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
display: none;
|
||||
min-width: 250px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,108 +27,78 @@ $container-max-widths: (
|
||||
xxxl: 1536px,
|
||||
xxxxl: 1836px,
|
||||
) !default;
|
||||
|
||||
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
|
||||
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
|
||||
|
||||
$font-family-base: "Roboto", $font-family-sans-serif !default;
|
||||
|
||||
$html-font-size: 14px!default;
|
||||
$spacer: 1rem !default;
|
||||
$headings-margin-bottom: $spacer !default;
|
||||
|
||||
$enable-rounded: false !default;
|
||||
$enable-shadows: true !default;
|
||||
|
||||
$enable-gradients: false !default;
|
||||
|
||||
$enable-transitions: true !default;
|
||||
$enable-reduced-motion: true !default;
|
||||
|
||||
$enable-caret: false !default;
|
||||
|
||||
$enable-grid-classes: true !default;
|
||||
$enable-button-pointers: true !default;
|
||||
$enable-rfs: true !default;
|
||||
|
||||
$enable-validation-icons: true !default;
|
||||
$enable-negative-margins: true !default;
|
||||
|
||||
$enable-deprecation-messages: true !default;
|
||||
|
||||
$enable-important-utilities: true !default;
|
||||
$breadcrumb-divider: quote("/") !default;
|
||||
|
||||
// ui framework settings
|
||||
$body-gutter-x: $spacer !default;
|
||||
$body-gutter-y: $spacer !default;
|
||||
|
||||
$body-double-gutter-x: $body-gutter-x * 2 !default;
|
||||
$body-double-gutter-y: $body-gutter-y * 2 !default;
|
||||
|
||||
$body-gutter-reduced-x: $body-gutter-x * 0.5 !default;
|
||||
$body-gutter-reduced-y: $body-gutter-y * 0.5 !default;
|
||||
|
||||
$body-gutter-reduced-d-x: $body-gutter-x * 0.25 !default;
|
||||
$body-gutter-reduced-d-y: $body-gutter-y * 0.25 !default;
|
||||
|
||||
$body-gutter-reduced-x: $body-gutter-x * .5 !default;
|
||||
$body-gutter-reduced-y: $body-gutter-y * .5 !default;
|
||||
$body-gutter-reduced-d-x: $body-gutter-x * .25 !default;
|
||||
$body-gutter-reduced-d-y: $body-gutter-y * .25 !default;
|
||||
$form-spacer-x: $spacer !default;
|
||||
$form-spacer-y: $spacer !default;
|
||||
|
||||
$element-spacer-x: map.get($spacers, 3) !default;
|
||||
$element-spacer-y: map.get($spacers, 3) !default;
|
||||
|
||||
$element-reduced-spacer-x: map.get($spacers, 2) !default;
|
||||
$element-reduced-spacer-y: map.get($spacers, 2) !default;
|
||||
|
||||
$element-reduced-d-spacer-x: map.get($spacers, 1) !default;
|
||||
$element-reduced-d-spacer-y: map.get($spacers, 1) !default;
|
||||
|
||||
$body-bg: #fff !default;
|
||||
$body-color: #212529 !default;
|
||||
|
||||
// site specific variables
|
||||
$extra-large-screen: 2000px !default;
|
||||
|
||||
$full-body-min-width: map-get($grid-breakpoints, "lg") !default;
|
||||
$typography-breakpoint: map-get($grid-breakpoints, "sm") - 1 !default;
|
||||
|
||||
$header-bg: var(--bs-dark) !default;
|
||||
$header-color: var(--bs-light) !default;
|
||||
$header-link: var(--bs-white) !default;
|
||||
|
||||
$main-nav-link-color: var(--bs-white) !default;
|
||||
$main-nav-link-bg: none !default;
|
||||
|
||||
$main-nav-toggler-size: 2rem !default;
|
||||
|
||||
$main-nav-link-hover-bg: none !default;
|
||||
$main-nav-link-hover-color: var(--bs-cyan) !default;
|
||||
|
||||
$main-nav-dropdown-bg: $header-bg !default;
|
||||
$main-nav-dropdown-color: $header-link !default;
|
||||
$main-nav-dropdown-hover-bg: var(--bs-black) !default;
|
||||
$main-nav-dropdown-hover-color: $main-nav-link-hover-color !default;
|
||||
|
||||
$sidebar-nav-link-hover-color: var(--bs-indigo) !default;
|
||||
|
||||
$footer-bg: $header-bg !default;
|
||||
$footer-color: $header-color !default;
|
||||
$footer-link: $header-link !default;
|
||||
|
||||
$footer-footer-bg: $main-nav-dropdown-hover-bg !default;
|
||||
|
||||
$sliderelement-carousel-slide-max-y: 70vh !default;
|
||||
$sliderelement-carousel-slide-bg: $header-bg !default;
|
||||
$sliderelement-carousel-slide-ratio-x: 16 !default;
|
||||
$sliderelement-carousel-slide-ratio-y: 9 !default;
|
||||
|
||||
$carousel-title-color: $white !default;
|
||||
$carousel-slide-min-height: 4rem !default;
|
||||
$carousel-text-shadow: 1px 1px $black !default;
|
||||
$carousel-controls-font-size: 3rem;
|
||||
$carousel-controls-zindex: 11 !default;
|
||||
$carousel-controls-shadow: 1px 1px $black !default;
|
||||
$carousel-controls-hover-bg: transparentize($black, 0.4) !default;
|
||||
$carousel-controls-hover-bg: transparentize($black, .4) !default;
|
||||
$carousel-slide-img-loading-max-height: 70vh !default;
|
||||
|
||||
$breadcrumb-active-color: $sidebar-nav-link-hover-color;
|
||||
$breadcrumb-active-color: $sidebar-nav-link-hover-color;
|
||||
|
Loading…
Reference in New Issue
Block a user