@unlk/keymaster 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/css/keymaster.css +314 -34
- package/dist/css/keymaster.css.map +1 -1
- package/dist/css/keymaster.min.css +2 -2
- package/dist/css/keymaster.min.css.map +1 -1
- package/dist/js/keymaster.js +327 -4594
- package/dist/js/keymaster.js.map +1 -1
- package/dist/js/keymaster.min.js +28 -34
- package/dist/js/keymaster.min.js.map +1 -1
- package/js/carousel-caption.js +48 -21
- package/js/video-modal.js +76 -53
- package/package.json +1 -1
- package/scss/theme/_accordion.scss +2 -1
- package/scss/theme/_alert.scss +7 -1
- package/scss/theme/_forms.scss +2 -0
- package/scss/theme/_utilities-overrides.scss +5 -5
- package/scss/theme/_variables-overrides.scss +251 -212
- package/scss/theme/_variables.scss +22 -22
- package/scss/theme/forms/_floating-labels.scss +12 -0
- package/scss/theme/forms/_form-check.scss +89 -0
package/js/carousel-caption.js
CHANGED
@@ -1,39 +1,66 @@
|
|
1
|
-
import
|
1
|
+
import BaseComponent from 'bootstrap/js/src/base-component.js';
|
2
|
+
import EventHandler from 'bootstrap/js/src/dom/event-handler.js';
|
3
|
+
import SelectorEngine from 'bootstrap/js/src/dom/selector-engine.js';
|
4
|
+
import { defineJQueryPlugin } from 'bootstrap/js/src/util/index.js';
|
2
5
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
+
const NAME = 'carouselCaption';
|
7
|
+
const DATA_KEY = 'bs.carouselCaption';
|
8
|
+
const EVENT_SLID = 'slid.bs.carousel';
|
9
|
+
const SELECTOR_CAROUSEL = '.carousel';
|
10
|
+
const SELECTOR_CAPTION = '.carousel-caption-container p';
|
11
|
+
|
12
|
+
class CarouselCaption extends BaseComponent {
|
13
|
+
constructor(element) {
|
14
|
+
super(element);
|
15
|
+
|
16
|
+
this._captionEl = this._findCaptionEl();
|
17
|
+
if (!this._captionEl) {
|
6
18
|
return;
|
7
19
|
}
|
8
20
|
|
9
|
-
this.
|
10
|
-
this.carousel = Carousel.getOrCreateInstance(carouselEl);
|
11
|
-
this.captionEl = carouselEl
|
12
|
-
.closest('.carousel-wrapper')
|
13
|
-
?.previousElementSibling?.querySelector('.carousel-caption-container');
|
14
|
-
|
21
|
+
this._updateCaption(); // Initialize
|
15
22
|
this._bindEvents();
|
16
|
-
|
23
|
+
}
|
24
|
+
|
25
|
+
dispose() {
|
26
|
+
EventHandler.off(this._element, EVENT_SLID);
|
27
|
+
super.dispose();
|
17
28
|
}
|
18
29
|
|
19
30
|
_bindEvents() {
|
20
|
-
|
31
|
+
EventHandler.on(this._element, EVENT_SLID, () => this._updateCaption());
|
21
32
|
}
|
22
33
|
|
23
34
|
_updateCaption() {
|
24
|
-
const
|
25
|
-
const
|
26
|
-
if (this.
|
27
|
-
this.
|
35
|
+
const activeItem = SelectorEngine.findOne('.carousel-item.active', this._element);
|
36
|
+
const newCaption = activeItem?.getAttribute('data-caption');
|
37
|
+
if (this._captionEl && newCaption) {
|
38
|
+
this._captionEl.textContent = newCaption;
|
28
39
|
}
|
29
40
|
}
|
30
41
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
42
|
+
_findCaptionEl() {
|
43
|
+
return this._element.querySelector(SELECTOR_CAPTION) || null;
|
44
|
+
}
|
45
|
+
|
46
|
+
static get NAME() {
|
47
|
+
return NAME;
|
48
|
+
}
|
49
|
+
|
50
|
+
static jQueryInterface(config) {
|
51
|
+
return this.each(function () {
|
52
|
+
CarouselCaption.getOrCreateInstance(this, config);
|
53
|
+
});
|
36
54
|
}
|
37
55
|
}
|
38
56
|
|
57
|
+
// Auto-init on DOMContentLoaded
|
58
|
+
document.addEventListener('DOMContentLoaded', () => {
|
59
|
+
for (const el of SelectorEngine.find(SELECTOR_CAROUSEL)) {
|
60
|
+
CarouselCaption.getOrCreateInstance(el);
|
61
|
+
}
|
62
|
+
});
|
63
|
+
|
64
|
+
defineJQueryPlugin(CarouselCaption);
|
65
|
+
|
39
66
|
export default CarouselCaption;
|
package/js/video-modal.js
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
|
1
|
+
import BaseComponent from 'bootstrap/js/src/base-component.js';
|
2
|
+
import EventHandler from 'bootstrap/js/src/dom/event-handler.js';
|
3
|
+
import SelectorEngine from 'bootstrap/js/src/dom/selector-engine.js';
|
4
|
+
import { defineJQueryPlugin } from 'bootstrap/js/src/util/index.js';
|
5
|
+
|
6
|
+
const NAME = 'videoModal';
|
7
|
+
const DATA_KEY = 'bs.videoModal';
|
8
|
+
const EVENT_SHOW = 'show.bs.modal';
|
9
|
+
const EVENT_HIDDEN = 'hidden.bs.modal';
|
10
|
+
const SELECTOR_DIALOG = '.modal-dialog-media';
|
11
|
+
const SELECTOR_RATIO = '.ratio';
|
12
|
+
|
2
13
|
// eslint-disable-next-line no-unused-vars
|
3
14
|
let youTubeAPIReady = false;
|
4
15
|
const youTubeAPIInitPromise = new Promise((resolve) => {
|
@@ -11,13 +22,12 @@ const youTubeAPIInitPromise = new Promise((resolve) => {
|
|
11
22
|
resolve();
|
12
23
|
};
|
13
24
|
|
14
|
-
const
|
15
|
-
|
16
|
-
document.head.append(
|
25
|
+
const script = document.createElement('script');
|
26
|
+
script.src = 'https://www.youtube.com/iframe_api';
|
27
|
+
document.head.append(script);
|
17
28
|
}
|
18
29
|
});
|
19
30
|
|
20
|
-
// Load Vimeo API
|
21
31
|
// eslint-disable-next-line no-unused-vars
|
22
32
|
let vimeoAPIReady = false;
|
23
33
|
const vimeoAPIInitPromise = new Promise((resolve) => {
|
@@ -25,99 +35,112 @@ const vimeoAPIInitPromise = new Promise((resolve) => {
|
|
25
35
|
vimeoAPIReady = true;
|
26
36
|
resolve();
|
27
37
|
} else {
|
28
|
-
const
|
29
|
-
|
30
|
-
|
38
|
+
const script = document.createElement('script');
|
39
|
+
script.src = 'https://player.vimeo.com/api/player.js';
|
40
|
+
script.addEventListener('load', () => {
|
31
41
|
vimeoAPIReady = true;
|
32
42
|
resolve();
|
33
43
|
});
|
34
44
|
|
35
|
-
document.head.append(
|
45
|
+
document.head.append(script);
|
36
46
|
}
|
37
47
|
});
|
38
48
|
|
39
|
-
class VideoModal {
|
40
|
-
constructor(
|
41
|
-
|
42
|
-
|
43
|
-
this.
|
44
|
-
|
49
|
+
class VideoModal extends BaseComponent {
|
50
|
+
constructor(element) {
|
51
|
+
super(element);
|
52
|
+
|
53
|
+
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
|
54
|
+
this._container = SelectorEngine.findOne(SELECTOR_RATIO, this._element);
|
55
|
+
|
56
|
+
if (!this._dialog || !this._container) {
|
45
57
|
return;
|
46
58
|
}
|
47
59
|
|
48
|
-
this.
|
49
|
-
this.
|
50
|
-
this.
|
51
|
-
this.
|
52
|
-
|
60
|
+
this._youtubeSrc = this._container.getAttribute('data-src');
|
61
|
+
this._vimeoUrl = this._container.getAttribute('data-vimeo-url');
|
62
|
+
this._youtubePlayer = null;
|
63
|
+
this._vimeoPlayer = null;
|
64
|
+
|
65
|
+
EventHandler.on(this._element, EVENT_SHOW, () => this._onShow());
|
66
|
+
EventHandler.on(this._element, EVENT_HIDDEN, () => this._onHide());
|
67
|
+
}
|
53
68
|
|
54
|
-
|
55
|
-
|
69
|
+
dispose() {
|
70
|
+
this._onHide();
|
71
|
+
super.dispose();
|
56
72
|
}
|
57
73
|
|
58
|
-
async
|
59
|
-
const
|
74
|
+
async _onShow() {
|
75
|
+
const { id } = this._element;
|
76
|
+
const playerClass = `${id}-youtube-player`;
|
60
77
|
|
61
|
-
if (this.
|
62
|
-
const vimeoId = this.getVimeoId(this.vimeoUrl);
|
78
|
+
if (this._vimeoUrl) {
|
63
79
|
await vimeoAPIInitPromise;
|
64
|
-
|
65
|
-
this.
|
80
|
+
const vimeoId = this._getVimeoId(this._vimeoUrl);
|
81
|
+
this._vimeoPlayer = new window.Vimeo.Player(this._container, {
|
66
82
|
id: vimeoId,
|
67
83
|
autoplay: true
|
68
84
|
});
|
69
85
|
}
|
70
86
|
|
71
|
-
if (this.
|
72
|
-
const youtubeId = this.getYouTubeId(this.youtubeSrc);
|
87
|
+
if (this._youtubeSrc) {
|
73
88
|
await youTubeAPIInitPromise;
|
74
|
-
|
75
|
-
|
76
|
-
this.
|
77
|
-
|
78
|
-
|
79
|
-
// eslint-disable-next-line no-undef
|
80
|
-
this.youtubePlayer = new YT.Player(playerDiv, {
|
89
|
+
const youtubeId = this._getYouTubeId(this._youtubeSrc);
|
90
|
+
this._container.innerHTML = `<div class="${playerClass} w-100 h-100"></div>`;
|
91
|
+
const playerDiv = this._container.querySelector(`.${playerClass}`);
|
92
|
+
this._youtubePlayer = new window.YT.Player(playerDiv, {
|
81
93
|
videoId: youtubeId,
|
82
94
|
playerVars: { autoplay: 1, rel: 0 }
|
83
95
|
});
|
84
96
|
}
|
85
97
|
}
|
86
98
|
|
87
|
-
|
88
|
-
if (this.
|
89
|
-
this.
|
90
|
-
this.
|
99
|
+
_onHide() {
|
100
|
+
if (this._vimeoPlayer) {
|
101
|
+
this._vimeoPlayer.unload().catch(() => {});
|
102
|
+
this._vimeoPlayer = null;
|
91
103
|
}
|
92
104
|
|
93
|
-
if (this.
|
94
|
-
this.
|
95
|
-
this.
|
105
|
+
if (this._youtubePlayer) {
|
106
|
+
this._youtubePlayer.destroy();
|
107
|
+
this._youtubePlayer = null;
|
96
108
|
}
|
97
109
|
}
|
98
110
|
|
99
|
-
|
111
|
+
_getYouTubeId(url) {
|
100
112
|
const match = url.match(/(?:v=|youtu\.be\/)([\w-]{11})/);
|
101
113
|
return match ? match[1] : '';
|
102
114
|
}
|
103
115
|
|
104
|
-
|
116
|
+
_getVimeoId(url) {
|
105
117
|
const match = url.match(/vimeo\.com\/(\d+)/);
|
106
118
|
return match ? match[1] : '';
|
107
119
|
}
|
120
|
+
|
121
|
+
static get NAME() {
|
122
|
+
return NAME;
|
123
|
+
}
|
124
|
+
|
125
|
+
static jQueryInterface(config) {
|
126
|
+
return this.each(function () {
|
127
|
+
VideoModal.getOrCreateInstance(this, config);
|
128
|
+
});
|
129
|
+
}
|
108
130
|
}
|
109
131
|
|
110
|
-
// Auto-init
|
132
|
+
// Auto-init
|
111
133
|
document.addEventListener('DOMContentLoaded', () => {
|
112
|
-
|
113
|
-
|
134
|
+
const modals = SelectorEngine.find('[data-bs-toggle="modal"][data-bs-target]');
|
135
|
+
for (const btn of modals) {
|
136
|
+
const targetSelector = btn.getAttribute('data-bs-target');
|
114
137
|
const modal = document.querySelector(targetSelector);
|
115
|
-
|
116
|
-
|
117
|
-
// eslint-disable-next-line no-new
|
118
|
-
new VideoModal(modal);
|
138
|
+
if (modal?.querySelector(SELECTOR_DIALOG)) {
|
139
|
+
VideoModal.getOrCreateInstance(modal);
|
119
140
|
}
|
120
141
|
}
|
121
142
|
});
|
122
143
|
|
144
|
+
defineJQueryPlugin(VideoModal);
|
145
|
+
|
123
146
|
export default VideoModal;
|
package/package.json
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
.accordion-button {
|
15
15
|
margin-bottom: 0;
|
16
16
|
background-color: var(--#{$prefix}accordion-alt-btn-bg);
|
17
|
+
@include box-shadow(none);
|
17
18
|
|
18
19
|
i {
|
19
20
|
width: var(--#{$prefix}accordion-alt-btn-icon-width);
|
@@ -22,8 +23,8 @@
|
|
22
23
|
}
|
23
24
|
|
24
25
|
&:not(.collapsed) {
|
25
|
-
color: var(--#{$prefix}accordion-alt-active-color);
|
26
26
|
@include box-shadow(none);
|
27
|
+
color: var(--#{$prefix}accordion-alt-active-color);
|
27
28
|
|
28
29
|
&::after {
|
29
30
|
background-image: var(--#{$prefix}accordion-alt-btn-active-icon);
|
package/scss/theme/_alert.scss
CHANGED
@@ -12,14 +12,20 @@
|
|
12
12
|
@each $state, $value in $theme-colors {
|
13
13
|
$alert-border: var(--#{$prefix}#{$state}-border-subtle);
|
14
14
|
$alert-color: var(--#{$prefix}#{$state}-text-emphasis);
|
15
|
+
$alert-bg: var(--#{$prefix}#{$state}-bg-subtle);
|
15
16
|
@if $state == "tertiary" {
|
16
17
|
$alert-border: $gray-400;
|
17
18
|
$alert-color: $foundation-500;
|
18
19
|
}
|
20
|
+
@else if $state == "danger" {
|
21
|
+
$alert-bg: $danger-25;
|
22
|
+
} @else if $state == "success" {
|
23
|
+
$alert-bg: $success-50;
|
24
|
+
}
|
19
25
|
|
20
26
|
.alert-#{$state} {
|
21
27
|
--#{$prefix}alert-color: #{$alert-color};
|
22
|
-
--#{$prefix}alert-bg:
|
28
|
+
--#{$prefix}alert-bg: #{$alert-bg};
|
23
29
|
--#{$prefix}alert-border-color: #{$alert-border};
|
24
30
|
--#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis);
|
25
31
|
}
|
package/scss/theme/_forms.scss
CHANGED
@@ -4,12 +4,12 @@
|
|
4
4
|
@import "../assets/bootstrap5/utilities";
|
5
5
|
@import "../assets/bootstrap5/vendor/rfs";
|
6
6
|
|
7
|
-
$box-shadow-sm: 0 rfs-value(1px) rfs-value(4px) rgba($foundation-500, .1);
|
8
|
-
$box-shadow: 0 rfs-value(4px) rfs-value(10px) rgba($foundation-500, .12);
|
9
|
-
$box-shadow-lg: 0 rfs-value(8px) rfs-value(35px) rgba($foundation-500, .16);
|
10
|
-
$box-shadow-inset: 0 rfs-value(1px) rfs-value(2px) rgba($foundation-500, .1) inset;
|
7
|
+
$box-shadow-sm: 0 rfs-value(1px) rfs-value(4px) rgba($foundation-500, .1) !default;
|
8
|
+
$box-shadow: 0 rfs-value(4px) rfs-value(10px) rgba($foundation-500, .12) !default;
|
9
|
+
$box-shadow-lg: 0 rfs-value(8px) rfs-value(35px) rgba($foundation-500, .16) !default;
|
10
|
+
$box-shadow-inset: 0 rfs-value(1px) rfs-value(2px) rgba($foundation-500, .1) inset !default;
|
11
11
|
|
12
|
-
$all-colors: map-merge-multiple($foundations, $blueprints, $entryways, $turnkeys, $sunglows, $warnings, $grays, $successs, $dangers);
|
12
|
+
$all-colors: map-merge-multiple($foundations, $blueprints, $entryways, $turnkeys, $sunglows, $warnings, $grays, $successs, $dangers) !default;
|
13
13
|
|
14
14
|
$utilities: map-merge(
|
15
15
|
$utilities,
|