bootstrap-time 0.2.0 → 0.2.2-beta

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/README.md CHANGED
@@ -18,7 +18,7 @@ dist/ generated, do not edit
18
18
  examples/ HTML that points at dist
19
19
  ```
20
20
 
21
- `npm run build` compiles `src` into `dist`. Bootstrap 6 is required. The time field uses [form adornments](https://getbootstrap.com/docs/6.0/forms/form-adorn/), which Bootstrap 5.3 does not have. Bootstrap 5.3 can only place an addon beside the input with `input-group`, not inside it. The clock icon comes from bootstrap-icons.
21
+ `npm run build` compiles `src` into `dist`. Bootstrap 5.3.8 or later 5.3 is required. The browser supplies the time field icon. Focus opens the clock and blur closes it.
22
22
 
23
23
  ## Usage
24
24
 
@@ -31,10 +31,9 @@ npm install bootstrap-time
31
31
  Or load the published files from jsDelivr:
32
32
 
33
33
  ```html
34
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@6.0.0-alpha.1/dist/css/bootstrap.min.css">
35
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.2/font/bootstrap-icons.min.css">
36
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-time@0.2.0/dist/css/bootstrap-time.min.css">
37
- <script src="https://cdn.jsdelivr.net/npm/bootstrap-time@0.2.0/dist/js/bootstrap-time.min.js"></script>
34
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
35
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-time@0.2.2-beta/dist/css/bootstrap-time.min.css">
36
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap-time@0.2.2-beta/dist/js/bootstrap-time.min.js"></script>
38
37
  ```
39
38
 
40
39
  Local builds use the same paths under `dist/`:
@@ -55,6 +54,15 @@ Minute selection follows the input `step`, including when `step` changes: `60` a
55
54
 
56
55
  ## Changelog
57
56
 
57
+ ### 0.2.2-beta
58
+
59
+ - The clock overlays the form and no longer stretches a smaller field.
60
+
61
+ ### 0.2.1-beta
62
+
63
+ - Requires Bootstrap 5.3.8 instead of Bootstrap 6.
64
+ - Removed the adorn button. The browser time icon stays, and focus and blur still open and close the clock.
65
+
58
66
  ### 0.2.0
59
67
 
60
68
  - Stable release. Attach the clock to any field with class `bs-time`.
@@ -1,40 +1,15 @@
1
1
  .clock-picker {
2
- position: relative;
3
- }
4
- .clock-picker input[type=time]::-webkit-calendar-picker-indicator {
5
- display: none;
6
- appearance: none;
7
- }
8
-
9
- .clock-toggle {
10
- pointer-events: auto;
11
- width: 2.25rem;
12
- height: 2.25rem;
13
- margin: -0.25rem;
14
- border: 0;
15
- border-radius: 50%;
16
- background: transparent;
17
- color: var(--bs-form-adorn-icon-color, var(--bs-secondary-color));
18
- }
19
- .clock-toggle .bi {
20
- font-size: 1rem;
21
- line-height: 1;
22
- }
23
- .clock-toggle:hover, .clock-toggle:focus-visible {
24
- background-color: var(--bs-bg-3);
25
- color: var(--bs-body-color);
2
+ display: contents;
26
3
  }
27
4
 
28
5
  .clock-widget {
29
- position: absolute;
30
- top: 100%;
31
- left: 0;
32
- z-index: 5;
6
+ position: fixed;
7
+ z-index: 1080;
33
8
  width: 20rem;
34
- margin-top: 0.25rem;
9
+ margin: 0;
35
10
  padding: 0.25rem 0.5rem 1rem;
36
- background-color: var(--bs-secondary-bg-subtle);
37
- color: var(--bs-secondary-fg);
11
+ background-color: var(--bs-secondary-bg);
12
+ color: var(--bs-body-color);
38
13
  }
39
14
 
40
15
  .clock-arrows {
@@ -62,7 +37,7 @@
62
37
  fill: currentColor;
63
38
  }
64
39
  .btn.clock-arrow:hover, .btn.clock-arrow:focus-visible {
65
- background-color: var(--bs-bg-3);
40
+ background-color: var(--bs-tertiary-bg);
66
41
  color: var(--bs-body-color);
67
42
  }
68
43
  .btn.clock-arrow:disabled, .btn.clock-arrow:disabled:hover {
@@ -1 +1 @@
1
- .clock-picker{position:relative}.clock-picker input[type=time]::-webkit-calendar-picker-indicator{display:none;appearance:none}.clock-toggle{pointer-events:auto;width:2.25rem;height:2.25rem;margin:-0.25rem;border:0;border-radius:50%;background:rgba(0,0,0,0);color:var(--bs-form-adorn-icon-color, var(--bs-secondary-color))}.clock-toggle .bi{font-size:1rem;line-height:1}.clock-toggle:hover,.clock-toggle:focus-visible{background-color:var(--bs-bg-3);color:var(--bs-body-color)}.clock-widget{position:absolute;top:100%;left:0;z-index:5;width:20rem;margin-top:.25rem;padding:.25rem .5rem 1rem;background-color:var(--bs-secondary-bg-subtle);color:var(--bs-secondary-fg)}.clock-arrows{display:flex;justify-content:flex-end;gap:.25rem}.btn.clock-arrow{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;min-height:0;padding:0;border-radius:50%;background-color:rgba(0,0,0,0);color:var(--bs-body-color);text-decoration:none}.btn.clock-arrow svg{width:1.5rem;height:1.5rem;fill:currentColor}.btn.clock-arrow:hover,.btn.clock-arrow:focus-visible{background-color:var(--bs-bg-3);color:var(--bs-body-color)}.btn.clock-arrow:disabled,.btn.clock-arrow:disabled:hover{background-color:rgba(0,0,0,0);color:var(--bs-secondary-color);opacity:.45}.clock{width:16rem;height:16rem;border-radius:50%;touch-action:none;cursor:pointer}.clock-hand{position:absolute;left:50%;bottom:50%;width:2px;height:var(--hand);transform-origin:center bottom;transform:translateX(-50%) rotate(var(--angle));transition:transform .3s ease,height .3s ease;border-radius:1px;pointer-events:none}.clock-knob{position:absolute;left:50%;top:0;width:2.25rem;height:2.25rem;border-radius:50%;transform:translate(-50%, -50%)}.clock-number{position:absolute;left:50%;top:50%;z-index:1;width:2.25rem;height:2.25rem;margin:-1.125rem;border:0;border-radius:50%;background:rgba(0,0,0,0);color:inherit;transform:rotate(var(--angle)) translateY(calc(var(--radius) * -1)) rotate(calc(var(--angle) * -1))}.clock-number[aria-pressed=true]{color:var(--bs-white, #fff)}.clock-number:disabled{opacity:.35;cursor:default}
1
+ .clock-picker{display:contents}.clock-widget{position:fixed;z-index:1080;width:20rem;margin:0;padding:.25rem .5rem 1rem;background-color:var(--bs-secondary-bg);color:var(--bs-body-color)}.clock-arrows{display:flex;justify-content:flex-end;gap:.25rem}.btn.clock-arrow{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;min-height:0;padding:0;border-radius:50%;background-color:rgba(0,0,0,0);color:var(--bs-body-color);text-decoration:none}.btn.clock-arrow svg{width:1.5rem;height:1.5rem;fill:currentColor}.btn.clock-arrow:hover,.btn.clock-arrow:focus-visible{background-color:var(--bs-tertiary-bg);color:var(--bs-body-color)}.btn.clock-arrow:disabled,.btn.clock-arrow:disabled:hover{background-color:rgba(0,0,0,0);color:var(--bs-secondary-color);opacity:.45}.clock{width:16rem;height:16rem;border-radius:50%;touch-action:none;cursor:pointer}.clock-hand{position:absolute;left:50%;bottom:50%;width:2px;height:var(--hand);transform-origin:center bottom;transform:translateX(-50%) rotate(var(--angle));transition:transform .3s ease,height .3s ease;border-radius:1px;pointer-events:none}.clock-knob{position:absolute;left:50%;top:0;width:2.25rem;height:2.25rem;border-radius:50%;transform:translate(-50%, -50%)}.clock-number{position:absolute;left:50%;top:50%;z-index:1;width:2.25rem;height:2.25rem;margin:-1.125rem;border:0;border-radius:50%;background:rgba(0,0,0,0);color:inherit;transform:rotate(var(--angle)) translateY(calc(var(--radius) * -1)) rotate(calc(var(--angle) * -1))}.clock-number[aria-pressed=true]{color:var(--bs-white, #fff)}.clock-number:disabled{opacity:.35;cursor:default}
@@ -27,39 +27,28 @@
27
27
  picker.append(host);
28
28
  }
29
29
 
30
- var adorn = field.closest(".form-adorn");
31
- if (!adorn && field.classList.contains("form-control")) {
32
- adorn = document.createElement("div");
33
- adorn.className = "form-control form-adorn form-adorn-end";
34
- field.parentNode.insertBefore(adorn, field);
35
- adorn.append(field);
36
- field.classList.remove("form-control");
37
- field.classList.add("form-ghost");
38
- }
39
-
40
- var toggle = picker.querySelector(".clock-toggle");
41
- if (!toggle && adorn) {
42
- toggle = document.createElement("button");
43
- toggle.type = "button";
44
- toggle.className = "form-adorn-icon clock-toggle";
45
- toggle.setAttribute("aria-label", "Klok");
46
- toggle.setAttribute("aria-pressed", "false");
47
- toggle.innerHTML = '<i class="bi bi-clock" aria-hidden="true"></i>';
48
- adorn.insertBefore(toggle, adorn.firstChild);
49
- }
50
-
51
30
  var widget = picker.querySelector(".clock-widget");
52
31
  if (!widget) {
53
32
  widget = document.createElement("div");
54
- widget.className = "clock-widget card theme-secondary theme-subtle";
33
+ widget.className = "clock-widget card bg-body-secondary";
55
34
  widget.hidden = true;
56
35
  widget.innerHTML =
57
36
  '<div class="clock-arrows">' +
58
37
  '<button class="btn btn-link clock-arrow clock-hour" type="button" aria-label="Uren">' + svg(LEFT) + "</button>" +
59
38
  '<button class="btn btn-link clock-arrow clock-minute" type="button" aria-label="Minuten">' + svg(RIGHT) + "</button>" +
60
39
  "</div>" +
61
- '<div class="clock position-relative mx-auto theme-inverse theme-subtle" role="group" aria-label="Kies een uur"></div>';
40
+ '<div class="clock position-relative mx-auto bg-body-tertiary" role="group" aria-label="Kies een uur"></div>';
62
41
  picker.append(widget);
42
+ document.body.append(widget);
43
+ }
44
+
45
+ function placeWidget() {
46
+ var rect = field.getBoundingClientRect();
47
+ var width = widget.offsetWidth || 320;
48
+ var left = rect.left;
49
+ if (left + width > window.innerWidth - 8) left = Math.max(8, window.innerWidth - width - 8);
50
+ widget.style.top = Math.round(rect.bottom + 4) + "px";
51
+ widget.style.left = Math.round(left) + "px";
63
52
  }
64
53
 
65
54
  var clock = widget.querySelector(".clock");
@@ -181,17 +170,11 @@
181
170
 
182
171
  function showWidget() {
183
172
  widget.hidden = false;
184
- if (toggle) toggle.setAttribute("aria-pressed", "true");
173
+ placeWidget();
185
174
  }
186
175
 
187
176
  function hideWidget() {
188
177
  widget.hidden = true;
189
- if (toggle) toggle.setAttribute("aria-pressed", "false");
190
- }
191
-
192
- function toggleWidget() {
193
- if (widget.hidden) showWidget();
194
- else hideWidget();
195
178
  }
196
179
 
197
180
  function valueFromPoint(event) {
@@ -225,8 +208,17 @@
225
208
  minuteArrow.addEventListener("click", function () {
226
209
  showMode("minute");
227
210
  });
228
- if (toggle) toggle.addEventListener("click", toggleWidget);
229
211
  field.addEventListener("focus", showWidget);
212
+ field.addEventListener("blur", hideWidget);
213
+ widget.addEventListener("mousedown", function (event) {
214
+ event.preventDefault();
215
+ });
216
+ document.addEventListener("mousedown", function (event) {
217
+ if (field === event.target || widget.contains(event.target)) return;
218
+ hideWidget();
219
+ });
220
+ window.addEventListener("resize", placeWidget);
221
+ window.addEventListener("scroll", placeWidget, true);
230
222
  field.addEventListener("input", function () {
231
223
  if (!field.value) return;
232
224
  var parts = field.value.split(":");
@@ -239,15 +231,6 @@
239
231
  updateArrows();
240
232
  renderClock();
241
233
  });
242
- picker.addEventListener("mousedown", function (event) {
243
- if (event.target === field) return;
244
- if (toggle && toggle.contains(event.target)) return;
245
- event.preventDefault();
246
- });
247
- document.addEventListener("mousedown", function (event) {
248
- if (picker.contains(event.target)) return;
249
- hideWidget();
250
- });
251
234
 
252
235
  function applyStep() {
253
236
  minute = snapMinute(minute);
@@ -1 +1 @@
1
- !function(){"use strict";var e="4.6rem",t="6.4rem";function n(e){return'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="'+e+'"></path></svg>'}function r(r){if("ready"!==r.dataset.bsTime){r.dataset.bsTime="ready";var o=r.closest(".form-control")||r,a=o.closest(".clock-picker");a||((a=document.createElement("div")).className="clock-picker",o.parentNode.insertBefore(a,o),a.append(o));var i=r.closest(".form-adorn");!i&&r.classList.contains("form-control")&&((i=document.createElement("div")).className="form-control form-adorn form-adorn-end",r.parentNode.insertBefore(i,r),i.append(r),r.classList.remove("form-control"),r.classList.add("form-ghost"));var c=a.querySelector(".clock-toggle");!c&&i&&((c=document.createElement("button")).type="button",c.className="form-adorn-icon clock-toggle",c.setAttribute("aria-label","Klok"),c.setAttribute("aria-pressed","false"),c.innerHTML='<i class="bi bi-clock" aria-hidden="true"></i>',i.insertBefore(c,i.firstChild));var u=a.querySelector(".clock-widget");u||((u=document.createElement("div")).className="clock-widget card theme-secondary theme-subtle",u.hidden=!0,u.innerHTML='<div class="clock-arrows"><button class="btn btn-link clock-arrow clock-hour" type="button" aria-label="Uren">'+n("M15.41 16.59 10.83 12l4.58-4.59L14 6l-6 6 6 6z")+'</button><button class="btn btn-link clock-arrow clock-minute" type="button" aria-label="Minuten">'+n("M8.59 16.59 13.17 12 8.59 7.41 10 6l6 6-6 6z")+'</button></div><div class="clock position-relative mx-auto theme-inverse theme-subtle" role="group" aria-label="Kies een uur"></div>',a.append(u));var s=u.querySelector(".clock"),l=u.querySelector(".clock-hour"),d=u.querySelector(".clock-minute");if(s&&l&&d){var m=new Date,f=r.value?r.value.split(":"):[m.getHours(),m.getMinutes()],b=Number(f[0])||0,p=M(Number(f[1])||0),v="hour",h=150,g=document.createElement("div"),k=document.createElement("span");g.className="clock-hand bg-primary",k.className="clock-knob bg-primary",k.setAttribute("aria-hidden","true"),g.append(k),s.append(g),s.addEventListener("click",function(e){if(!e.target.closest(".clock-number")){var t=function(e){var t=s.getBoundingClientRect(),n=e.clientX-(t.left+t.width/2),r=e.clientY-(t.top+t.height/2),o=(180*Math.atan2(n,-r)/Math.PI+360)%360;if("minute"===v)return M(Math.round(o/6)%60);var a=Math.round(o/30)%12;return Math.hypot(n,r)<.32*t.width?0===a?0:a+12:0===a?12:a}(e);"minute"===v?p=t:(b=t,v="minute"),S(),w(),q()}}),l.addEventListener("click",function(){A("hour")}),d.addEventListener("click",function(){A("minute")}),c&&c.addEventListener("click",function(){u.hidden?P():B()}),r.addEventListener("focus",P),r.addEventListener("input",function(){if(r.value){var e=r.value.split(":"),t=Number(e[0]),n=Number(e[1]);n!==p?v="minute":t!==b&&(v="hour"),b=t,p=n,w(),q()}}),a.addEventListener("mousedown",function(e){e.target!==r&&(c&&c.contains(e.target)||e.preventDefault())}),document.addEventListener("mousedown",function(e){a.contains(e.target)||B()});var y=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"step");y&&y.set&&Object.defineProperty(r,"step",{configurable:!0,get:function(){return y.get.call(r)},set:function(e){y.set.call(r,e),O()}}),new MutationObserver(O).observe(r,{attributes:!0,attributeFilter:["step"]}),w(),r.value||(r.value=E(b)+":"+E(p)),q(),B()}}function E(e){return String(e).padStart(2,"0")}function L(){var e=Number(r.getAttribute("step")||r.step);return(!e||e<60)&&(e=60),Math.max(1,Math.round(e/60))}function M(e){var t=L();return(Math.round(e/t)*t%60+60)%60}function N(){h+=((("hour"===v?b%12*30:6*p)-h)%360+540)%360-180,g.style.setProperty("--angle",h+"deg"),g.style.setProperty("--hand","hour"===v&&(0===b||b>12)?e:t)}function w(){l.disabled="hour"===v,d.disabled="minute"===v}function S(){r.value=E(b)+":"+E(p)}function A(e){v!==e&&(v=e,w(),q())}function q(){s.querySelectorAll(".clock-number").forEach(function(e){e.remove()}),s.setAttribute("aria-label","hour"===v?"Kies een uur":"Kies de minuten");var n="hour"===v?[12,1,2,3,4,5,6,7,8,9,10,11,0,13,14,15,16,17,18,19,20,21,22,23]:[0,5,10,15,20,25,30,35,40,45,50,55],r="hour"===v?b:p;N(),n.forEach(function(n,o){var a=document.createElement("button"),i="hour"===v&&o>=12,c=30*("hour"===v?o%12:o),u="minute"===v&&!function(e){return e%L()===0}(n);a.type="button",a.className="clock-number",a.textContent=0===n?"00":String(n),a.dataset.value=String(n),a.disabled=u,a.setAttribute("aria-pressed",u||n!==r?"false":"true"),a.style.setProperty("--angle",c+"deg"),a.style.setProperty("--radius",i?e:t),a.addEventListener("click",function(){a.disabled||("hour"===v?(b=n,v="minute"):p=n,S(),w(),q())}),s.append(a)})}function P(){u.hidden=!1,c&&c.setAttribute("aria-pressed","true")}function B(){u.hidden=!0,c&&c.setAttribute("aria-pressed","false")}function O(){p=M(p),r.value=E(b)+":"+E(p),q()}}function o(){document.querySelectorAll(".bs-time").forEach(r)}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",o):o()}();
1
+ !function(){"use strict";var e="4.6rem",t="6.4rem";function n(e){return'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="'+e+'"></path></svg>'}function r(r){if("ready"!==r.dataset.bsTime){r.dataset.bsTime="ready";var o=r.closest(".form-control")||r,a=o.closest(".clock-picker");a||((a=document.createElement("div")).className="clock-picker",o.parentNode.insertBefore(a,o),a.append(o));var i=a.querySelector(".clock-widget");i||((i=document.createElement("div")).className="clock-widget card bg-body-secondary",i.hidden=!0,i.innerHTML='<div class="clock-arrows"><button class="btn btn-link clock-arrow clock-hour" type="button" aria-label="Uren">'+n("M15.41 16.59 10.83 12l4.58-4.59L14 6l-6 6 6 6z")+'</button><button class="btn btn-link clock-arrow clock-minute" type="button" aria-label="Minuten">'+n("M8.59 16.59 13.17 12 8.59 7.41 10 6l6 6-6 6z")+'</button></div><div class="clock position-relative mx-auto bg-body-tertiary" role="group" aria-label="Kies een uur"></div>',a.append(i),document.body.append(i));var u=i.querySelector(".clock"),c=i.querySelector(".clock-hour"),d=i.querySelector(".clock-minute");if(u&&c&&d){var l=new Date,s=r.value?r.value.split(":"):[l.getHours(),l.getMinutes()],m=Number(s[0])||0,b=E(Number(s[1])||0),p="hour",v=150,f=document.createElement("div"),h=document.createElement("span");f.className="clock-hand bg-primary",h.className="clock-knob bg-primary",h.setAttribute("aria-hidden","true"),f.append(h),u.append(f),u.addEventListener("click",function(e){if(!e.target.closest(".clock-number")){var t=function(e){var t=u.getBoundingClientRect(),n=e.clientX-(t.left+t.width/2),r=e.clientY-(t.top+t.height/2),o=(180*Math.atan2(n,-r)/Math.PI+360)%360;if("minute"===p)return E(Math.round(o/6)%60);var a=Math.round(o/30)%12;return Math.hypot(n,r)<.32*t.width?0===a?0:a+12:0===a?12:a}(e);"minute"===p?b=t:(m=t,p="minute"),N(),L(),x()}}),c.addEventListener("click",function(){S("hour")}),d.addEventListener("click",function(){S("minute")}),r.addEventListener("focus",function(){i.hidden=!1,g()}),r.addEventListener("blur",P),i.addEventListener("mousedown",function(e){e.preventDefault()}),document.addEventListener("mousedown",function(e){r===e.target||i.contains(e.target)||P()}),window.addEventListener("resize",g),window.addEventListener("scroll",g,!0),r.addEventListener("input",function(){if(r.value){var e=r.value.split(":"),t=Number(e[0]),n=Number(e[1]);n!==b?p="minute":t!==m&&(p="hour"),m=t,b=n,L(),x()}});var y=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"step");y&&y.set&&Object.defineProperty(r,"step",{configurable:!0,get:function(){return y.get.call(r)},set:function(e){y.set.call(r,e),q()}}),new MutationObserver(q).observe(r,{attributes:!0,attributeFilter:["step"]}),L(),r.value||(r.value=k(m)+":"+k(b)),x(),P()}}function g(){var e=r.getBoundingClientRect(),t=i.offsetWidth||320,n=e.left;n+t>window.innerWidth-8&&(n=Math.max(8,window.innerWidth-t-8)),i.style.top=Math.round(e.bottom+4)+"px",i.style.left=Math.round(n)+"px"}function k(e){return String(e).padStart(2,"0")}function w(){var e=Number(r.getAttribute("step")||r.step);return(!e||e<60)&&(e=60),Math.max(1,Math.round(e/60))}function E(e){var t=w();return(Math.round(e/t)*t%60+60)%60}function M(){v+=((("hour"===p?m%12*30:6*b)-v)%360+540)%360-180,f.style.setProperty("--angle",v+"deg"),f.style.setProperty("--hand","hour"===p&&(0===m||m>12)?e:t)}function L(){c.disabled="hour"===p,d.disabled="minute"===p}function N(){r.value=k(m)+":"+k(b)}function S(e){p!==e&&(p=e,L(),x())}function x(){u.querySelectorAll(".clock-number").forEach(function(e){e.remove()}),u.setAttribute("aria-label","hour"===p?"Kies een uur":"Kies de minuten");var n="hour"===p?[12,1,2,3,4,5,6,7,8,9,10,11,0,13,14,15,16,17,18,19,20,21,22,23]:[0,5,10,15,20,25,30,35,40,45,50,55],r="hour"===p?m:b;M(),n.forEach(function(n,o){var a=document.createElement("button"),i="hour"===p&&o>=12,c=30*("hour"===p?o%12:o),d="minute"===p&&!function(e){return e%w()===0}(n);a.type="button",a.className="clock-number",a.textContent=0===n?"00":String(n),a.dataset.value=String(n),a.disabled=d,a.setAttribute("aria-pressed",d||n!==r?"false":"true"),a.style.setProperty("--angle",c+"deg"),a.style.setProperty("--radius",i?e:t),a.addEventListener("click",function(){a.disabled||("hour"===p?(m=n,p="minute"):b=n,N(),L(),x())}),u.append(a)})}function P(){i.hidden=!0}function q(){b=E(b),r.value=k(m)+":"+k(b),x()}}function o(){document.querySelectorAll(".bs-time").forEach(r)}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",o):o()}();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bootstrap-time",
3
- "version": "0.2.0",
3
+ "version": "0.2.2-beta",
4
4
  "description": "Time picker based on Bootstrap.",
5
5
  "author": "M. de Ridder",
6
6
  "license": "MIT",
@@ -60,7 +60,6 @@
60
60
  "terser": "^5.44.0"
61
61
  },
62
62
  "dependencies": {
63
- "bootstrap": ">=6.0.0-alpha.1 <7",
64
- "bootstrap-icons": "^1.13.2"
63
+ "bootstrap": ">=5.3.8 <6"
65
64
  }
66
65
  }
@@ -27,39 +27,28 @@
27
27
  picker.append(host);
28
28
  }
29
29
 
30
- var adorn = field.closest(".form-adorn");
31
- if (!adorn && field.classList.contains("form-control")) {
32
- adorn = document.createElement("div");
33
- adorn.className = "form-control form-adorn form-adorn-end";
34
- field.parentNode.insertBefore(adorn, field);
35
- adorn.append(field);
36
- field.classList.remove("form-control");
37
- field.classList.add("form-ghost");
38
- }
39
-
40
- var toggle = picker.querySelector(".clock-toggle");
41
- if (!toggle && adorn) {
42
- toggle = document.createElement("button");
43
- toggle.type = "button";
44
- toggle.className = "form-adorn-icon clock-toggle";
45
- toggle.setAttribute("aria-label", "Klok");
46
- toggle.setAttribute("aria-pressed", "false");
47
- toggle.innerHTML = '<i class="bi bi-clock" aria-hidden="true"></i>';
48
- adorn.insertBefore(toggle, adorn.firstChild);
49
- }
50
-
51
30
  var widget = picker.querySelector(".clock-widget");
52
31
  if (!widget) {
53
32
  widget = document.createElement("div");
54
- widget.className = "clock-widget card theme-secondary theme-subtle";
33
+ widget.className = "clock-widget card bg-body-secondary";
55
34
  widget.hidden = true;
56
35
  widget.innerHTML =
57
36
  '<div class="clock-arrows">' +
58
37
  '<button class="btn btn-link clock-arrow clock-hour" type="button" aria-label="Uren">' + svg(LEFT) + "</button>" +
59
38
  '<button class="btn btn-link clock-arrow clock-minute" type="button" aria-label="Minuten">' + svg(RIGHT) + "</button>" +
60
39
  "</div>" +
61
- '<div class="clock position-relative mx-auto theme-inverse theme-subtle" role="group" aria-label="Kies een uur"></div>';
40
+ '<div class="clock position-relative mx-auto bg-body-tertiary" role="group" aria-label="Kies een uur"></div>';
62
41
  picker.append(widget);
42
+ document.body.append(widget);
43
+ }
44
+
45
+ function placeWidget() {
46
+ var rect = field.getBoundingClientRect();
47
+ var width = widget.offsetWidth || 320;
48
+ var left = rect.left;
49
+ if (left + width > window.innerWidth - 8) left = Math.max(8, window.innerWidth - width - 8);
50
+ widget.style.top = Math.round(rect.bottom + 4) + "px";
51
+ widget.style.left = Math.round(left) + "px";
63
52
  }
64
53
 
65
54
  var clock = widget.querySelector(".clock");
@@ -181,17 +170,11 @@
181
170
 
182
171
  function showWidget() {
183
172
  widget.hidden = false;
184
- if (toggle) toggle.setAttribute("aria-pressed", "true");
173
+ placeWidget();
185
174
  }
186
175
 
187
176
  function hideWidget() {
188
177
  widget.hidden = true;
189
- if (toggle) toggle.setAttribute("aria-pressed", "false");
190
- }
191
-
192
- function toggleWidget() {
193
- if (widget.hidden) showWidget();
194
- else hideWidget();
195
178
  }
196
179
 
197
180
  function valueFromPoint(event) {
@@ -225,8 +208,17 @@
225
208
  minuteArrow.addEventListener("click", function () {
226
209
  showMode("minute");
227
210
  });
228
- if (toggle) toggle.addEventListener("click", toggleWidget);
229
211
  field.addEventListener("focus", showWidget);
212
+ field.addEventListener("blur", hideWidget);
213
+ widget.addEventListener("mousedown", function (event) {
214
+ event.preventDefault();
215
+ });
216
+ document.addEventListener("mousedown", function (event) {
217
+ if (field === event.target || widget.contains(event.target)) return;
218
+ hideWidget();
219
+ });
220
+ window.addEventListener("resize", placeWidget);
221
+ window.addEventListener("scroll", placeWidget, true);
230
222
  field.addEventListener("input", function () {
231
223
  if (!field.value) return;
232
224
  var parts = field.value.split(":");
@@ -239,15 +231,6 @@
239
231
  updateArrows();
240
232
  renderClock();
241
233
  });
242
- picker.addEventListener("mousedown", function (event) {
243
- if (event.target === field) return;
244
- if (toggle && toggle.contains(event.target)) return;
245
- event.preventDefault();
246
- });
247
- document.addEventListener("mousedown", function (event) {
248
- if (picker.contains(event.target)) return;
249
- hideWidget();
250
- });
251
234
 
252
235
  function applyStep() {
253
236
  minute = snapMinute(minute);
@@ -3,46 +3,17 @@
3
3
  // and dist/css/bootstrap-time.min.css.
4
4
 
5
5
  .clock-picker {
6
- position: relative;
7
-
8
- input[type="time"]::-webkit-calendar-picker-indicator {
9
- display: none;
10
- appearance: none;
11
- }
12
- }
13
-
14
- .clock-toggle {
15
- pointer-events: auto;
16
- width: 2.25rem;
17
- height: 2.25rem;
18
- margin: -0.25rem;
19
- border: 0;
20
- border-radius: 50%;
21
- background: transparent;
22
- color: var(--bs-form-adorn-icon-color, var(--bs-secondary-color));
23
-
24
- .bi {
25
- font-size: 1rem;
26
- line-height: 1;
27
- }
28
-
29
- &:hover,
30
- &:focus-visible {
31
- background-color: var(--bs-bg-3);
32
- color: var(--bs-body-color);
33
- }
6
+ display: contents;
34
7
  }
35
8
 
36
9
  .clock-widget {
37
- position: absolute;
38
- top: 100%;
39
- left: 0;
40
- z-index: 5;
10
+ position: fixed;
11
+ z-index: 1080;
41
12
  width: 20rem;
42
- margin-top: 0.25rem;
13
+ margin: 0;
43
14
  padding: 0.25rem 0.5rem 1rem;
44
- background-color: var(--bs-secondary-bg-subtle);
45
- color: var(--bs-secondary-fg);
15
+ background-color: var(--bs-secondary-bg);
16
+ color: var(--bs-body-color);
46
17
  }
47
18
 
48
19
  .clock-arrows {
@@ -72,7 +43,7 @@
72
43
 
73
44
  &:hover,
74
45
  &:focus-visible {
75
- background-color: var(--bs-bg-3);
46
+ background-color: var(--bs-tertiary-bg);
76
47
  color: var(--bs-body-color);
77
48
  }
78
49