bootstrap-time 0.2.1-beta → 0.2.3-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
@@ -32,8 +32,8 @@ Or load the published files from jsDelivr:
32
32
 
33
33
  ```html
34
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.1-beta/dist/css/bootstrap-time.min.css">
36
- <script src="https://cdn.jsdelivr.net/npm/bootstrap-time@0.2.1-beta/dist/js/bootstrap-time.min.js"></script>
35
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-time@0.2.3-beta/dist/css/bootstrap-time.min.css">
36
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap-time@0.2.3-beta/dist/js/bootstrap-time.min.js"></script>
37
37
  ```
38
38
 
39
39
  Local builds use the same paths under `dist/`:
@@ -54,6 +54,14 @@ Minute selection follows the input `step`, including when `step` changes: `60` a
54
54
 
55
55
  ## Changelog
56
56
 
57
+ ### 0.2.3-beta
58
+
59
+ - The native time picker no longer opens. The browser icon stays.
60
+
61
+ ### 0.2.2-beta
62
+
63
+ - The clock overlays the form and no longer stretches a smaller field.
64
+
57
65
  ### 0.2.1-beta
58
66
 
59
67
  - Requires Bootstrap 5.3.8 instead of Bootstrap 6.
@@ -1,14 +1,16 @@
1
1
  .clock-picker {
2
- position: relative;
2
+ display: contents;
3
+ }
4
+
5
+ .bs-time::-webkit-calendar-picker-indicator {
6
+ pointer-events: none;
3
7
  }
4
8
 
5
9
  .clock-widget {
6
- position: absolute;
7
- top: 100%;
8
- left: 0;
9
- z-index: 5;
10
+ position: fixed;
11
+ z-index: 1080;
10
12
  width: 20rem;
11
- margin-top: 0.25rem;
13
+ margin: 0;
12
14
  padding: 0.25rem 0.5rem 1rem;
13
15
  background-color: var(--bs-secondary-bg);
14
16
  color: var(--bs-body-color);
@@ -1 +1 @@
1
- .clock-picker{position:relative}.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);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}
1
+ .clock-picker{display:contents}.bs-time::-webkit-calendar-picker-indicator{pointer-events:none}.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}
@@ -39,6 +39,16 @@
39
39
  "</div>" +
40
40
  '<div class="clock position-relative mx-auto bg-body-tertiary" role="group" aria-label="Kies een uur"></div>';
41
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";
42
52
  }
43
53
 
44
54
  var clock = widget.querySelector(".clock");
@@ -160,6 +170,7 @@
160
170
 
161
171
  function showWidget() {
162
172
  widget.hidden = false;
173
+ placeWidget();
163
174
  }
164
175
 
165
176
  function hideWidget() {
@@ -197,8 +208,31 @@
197
208
  minuteArrow.addEventListener("click", function () {
198
209
  showMode("minute");
199
210
  });
211
+ field.addEventListener("mousedown", function (event) {
212
+ event.preventDefault();
213
+ field.focus();
214
+ });
215
+ field.addEventListener("click", function (event) {
216
+ event.preventDefault();
217
+ showWidget();
218
+ });
219
+ field.addEventListener("keydown", function (event) {
220
+ if (event.key === " " || event.key === "Enter" || (event.altKey && event.key === "ArrowDown")) {
221
+ event.preventDefault();
222
+ showWidget();
223
+ }
224
+ });
200
225
  field.addEventListener("focus", showWidget);
201
226
  field.addEventListener("blur", hideWidget);
227
+ widget.addEventListener("mousedown", function (event) {
228
+ event.preventDefault();
229
+ });
230
+ document.addEventListener("mousedown", function (event) {
231
+ if (field === event.target || widget.contains(event.target)) return;
232
+ hideWidget();
233
+ });
234
+ window.addEventListener("resize", placeWidget);
235
+ window.addEventListener("scroll", placeWidget, true);
202
236
  field.addEventListener("input", function () {
203
237
  if (!field.value) return;
204
238
  var parts = field.value.split(":");
@@ -211,14 +245,6 @@
211
245
  updateArrows();
212
246
  renderClock();
213
247
  });
214
- picker.addEventListener("mousedown", function (event) {
215
- if (event.target === field) return;
216
- event.preventDefault();
217
- });
218
- document.addEventListener("mousedown", function (event) {
219
- if (picker.contains(event.target)) return;
220
- hideWidget();
221
- });
222
248
 
223
249
  function applyStep() {
224
250
  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 a=r.closest(".form-control")||r,o=a.closest(".clock-picker");o||((o=document.createElement("div")).className="clock-picker",a.parentNode.insertBefore(o,a),o.append(a));var u=o.querySelector(".clock-widget");u||((u=document.createElement("div")).className="clock-widget card bg-body-secondary",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 bg-body-tertiary" role="group" aria-label="Kies een uur"></div>',o.append(u));var i=u.querySelector(".clock"),c=u.querySelector(".clock-hour"),l=u.querySelector(".clock-minute");if(i&&c&&l){var d=new Date,s=r.value?r.value.split(":"):[d.getHours(),d.getMinutes()],m=Number(s[0])||0,b=E(Number(s[1])||0),v="hour",p=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),i.append(f),i.addEventListener("click",function(e){if(!e.target.closest(".clock-number")){var t=function(e){var t=i.getBoundingClientRect(),n=e.clientX-(t.left+t.width/2),r=e.clientY-(t.top+t.height/2),a=(180*Math.atan2(n,-r)/Math.PI+360)%360;if("minute"===v)return E(Math.round(a/6)%60);var o=Math.round(a/30)%12;return Math.hypot(n,r)<.32*t.width?0===o?0:o+12:0===o?12:o}(e);"minute"===v?b=t:(m=t,v="minute"),w(),L(),S()}}),c.addEventListener("click",function(){N("hour")}),l.addEventListener("click",function(){N("minute")}),r.addEventListener("focus",function(){u.hidden=!1}),r.addEventListener("blur",P),r.addEventListener("input",function(){if(r.value){var e=r.value.split(":"),t=Number(e[0]),n=Number(e[1]);n!==b?v="minute":t!==m&&(v="hour"),m=t,b=n,L(),S()}}),o.addEventListener("mousedown",function(e){e.target!==r&&e.preventDefault()}),document.addEventListener("mousedown",function(e){o.contains(e.target)||P()});var g=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"step");g&&g.set&&Object.defineProperty(r,"step",{configurable:!0,get:function(){return g.get.call(r)},set:function(e){g.set.call(r,e),q()}}),new MutationObserver(q).observe(r,{attributes:!0,attributeFilter:["step"]}),L(),r.value||(r.value=y(m)+":"+y(b)),S(),P()}}function y(e){return String(e).padStart(2,"0")}function k(){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=k();return(Math.round(e/t)*t%60+60)%60}function M(){p+=((("hour"===v?m%12*30:6*b)-p)%360+540)%360-180,f.style.setProperty("--angle",p+"deg"),f.style.setProperty("--hand","hour"===v&&(0===m||m>12)?e:t)}function L(){c.disabled="hour"===v,l.disabled="minute"===v}function w(){r.value=y(m)+":"+y(b)}function N(e){v!==e&&(v=e,L(),S())}function S(){i.querySelectorAll(".clock-number").forEach(function(e){e.remove()}),i.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?m:b;M(),n.forEach(function(n,a){var o=document.createElement("button"),u="hour"===v&&a>=12,c=30*("hour"===v?a%12:a),l="minute"===v&&!function(e){return e%k()===0}(n);o.type="button",o.className="clock-number",o.textContent=0===n?"00":String(n),o.dataset.value=String(n),o.disabled=l,o.setAttribute("aria-pressed",l||n!==r?"false":"true"),o.style.setProperty("--angle",c+"deg"),o.style.setProperty("--radius",u?e:t),o.addEventListener("click",function(){o.disabled||("hour"===v?(m=n,v="minute"):b=n,w(),L(),S())}),i.append(o)})}function P(){u.hidden=!0}function q(){b=E(b),r.value=y(m)+":"+y(b),S()}}function a(){document.querySelectorAll(".bs-time").forEach(r)}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",a):a()}();
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()],v=Number(s[0])||0,f=E(Number(s[1])||0),m="hour",p=150,b=document.createElement("div"),h=document.createElement("span");b.className="clock-hand bg-primary",h.className="clock-knob bg-primary",h.setAttribute("aria-hidden","true"),b.append(h),u.append(b),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"===m)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"===m?f=t:(v=t,m="minute"),N(),M(),D()}}),c.addEventListener("click",function(){S("hour")}),d.addEventListener("click",function(){S("minute")}),r.addEventListener("mousedown",function(e){e.preventDefault(),r.focus()}),r.addEventListener("click",function(e){e.preventDefault(),x()}),r.addEventListener("keydown",function(e){(" "===e.key||"Enter"===e.key||e.altKey&&"ArrowDown"===e.key)&&(e.preventDefault(),x())}),r.addEventListener("focus",x),r.addEventListener("blur",A),i.addEventListener("mousedown",function(e){e.preventDefault()}),document.addEventListener("mousedown",function(e){r===e.target||i.contains(e.target)||A()}),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!==f?m="minute":t!==v&&(m="hour"),v=t,f=n,M(),D()}});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),P()}}),new MutationObserver(P).observe(r,{attributes:!0,attributeFilter:["step"]}),M(),r.value||(r.value=k(v)+":"+k(f)),D(),A()}}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 L(){p+=((("hour"===m?v%12*30:6*f)-p)%360+540)%360-180,b.style.setProperty("--angle",p+"deg"),b.style.setProperty("--hand","hour"===m&&(0===v||v>12)?e:t)}function M(){c.disabled="hour"===m,d.disabled="minute"===m}function N(){r.value=k(v)+":"+k(f)}function S(e){m!==e&&(m=e,M(),D())}function D(){u.querySelectorAll(".clock-number").forEach(function(e){e.remove()}),u.setAttribute("aria-label","hour"===m?"Kies een uur":"Kies de minuten");var n="hour"===m?[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"===m?v:f;L(),n.forEach(function(n,o){var a=document.createElement("button"),i="hour"===m&&o>=12,c=30*("hour"===m?o%12:o),d="minute"===m&&!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"===m?(v=n,m="minute"):f=n,N(),M(),D())}),u.append(a)})}function x(){i.hidden=!1,g()}function A(){i.hidden=!0}function P(){f=E(f),r.value=k(v)+":"+k(f),D()}}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.1-beta",
3
+ "version": "0.2.3-beta",
4
4
  "description": "Time picker based on Bootstrap.",
5
5
  "author": "M. de Ridder",
6
6
  "license": "MIT",
@@ -39,6 +39,16 @@
39
39
  "</div>" +
40
40
  '<div class="clock position-relative mx-auto bg-body-tertiary" role="group" aria-label="Kies een uur"></div>';
41
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";
42
52
  }
43
53
 
44
54
  var clock = widget.querySelector(".clock");
@@ -160,6 +170,7 @@
160
170
 
161
171
  function showWidget() {
162
172
  widget.hidden = false;
173
+ placeWidget();
163
174
  }
164
175
 
165
176
  function hideWidget() {
@@ -197,8 +208,31 @@
197
208
  minuteArrow.addEventListener("click", function () {
198
209
  showMode("minute");
199
210
  });
211
+ field.addEventListener("mousedown", function (event) {
212
+ event.preventDefault();
213
+ field.focus();
214
+ });
215
+ field.addEventListener("click", function (event) {
216
+ event.preventDefault();
217
+ showWidget();
218
+ });
219
+ field.addEventListener("keydown", function (event) {
220
+ if (event.key === " " || event.key === "Enter" || (event.altKey && event.key === "ArrowDown")) {
221
+ event.preventDefault();
222
+ showWidget();
223
+ }
224
+ });
200
225
  field.addEventListener("focus", showWidget);
201
226
  field.addEventListener("blur", hideWidget);
227
+ widget.addEventListener("mousedown", function (event) {
228
+ event.preventDefault();
229
+ });
230
+ document.addEventListener("mousedown", function (event) {
231
+ if (field === event.target || widget.contains(event.target)) return;
232
+ hideWidget();
233
+ });
234
+ window.addEventListener("resize", placeWidget);
235
+ window.addEventListener("scroll", placeWidget, true);
202
236
  field.addEventListener("input", function () {
203
237
  if (!field.value) return;
204
238
  var parts = field.value.split(":");
@@ -211,14 +245,6 @@
211
245
  updateArrows();
212
246
  renderClock();
213
247
  });
214
- picker.addEventListener("mousedown", function (event) {
215
- if (event.target === field) return;
216
- event.preventDefault();
217
- });
218
- document.addEventListener("mousedown", function (event) {
219
- if (picker.contains(event.target)) return;
220
- hideWidget();
221
- });
222
248
 
223
249
  function applyStep() {
224
250
  minute = snapMinute(minute);
@@ -3,16 +3,18 @@
3
3
  // and dist/css/bootstrap-time.min.css.
4
4
 
5
5
  .clock-picker {
6
- position: relative;
6
+ display: contents;
7
+ }
8
+
9
+ .bs-time::-webkit-calendar-picker-indicator {
10
+ pointer-events: none;
7
11
  }
8
12
 
9
13
  .clock-widget {
10
- position: absolute;
11
- top: 100%;
12
- left: 0;
13
- z-index: 5;
14
+ position: fixed;
15
+ z-index: 1080;
14
16
  width: 20rem;
15
- margin-top: 0.25rem;
17
+ margin: 0;
16
18
  padding: 0.25rem 0.5rem 1rem;
17
19
  background-color: var(--bs-secondary-bg);
18
20
  color: var(--bs-body-color);