bootstrap-time 0.1.4-beta → 0.1.6-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 +14 -3
- package/dist/css/bootstrap-time.css +6 -0
- package/dist/css/bootstrap-time.min.css +1 -1
- package/dist/js/bootstrap-time.js +76 -4
- package/dist/js/bootstrap-time.min.js +1 -1
- package/package.json +1 -1
- package/src/js/bootstrap-time.js +76 -4
- package/src/scss/bootstrap-time.scss +7 -0
package/README.md
CHANGED
|
@@ -33,8 +33,8 @@ Or load the published files from jsDelivr:
|
|
|
33
33
|
```html
|
|
34
34
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@6.0.0-alpha.1/dist/css/bootstrap.min.css">
|
|
35
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.1.
|
|
37
|
-
<script src="https://cdn.jsdelivr.net/npm/bootstrap-time@0.1.
|
|
36
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-time@0.1.6-beta/dist/css/bootstrap-time.min.css">
|
|
37
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap-time@0.1.6-beta/dist/js/bootstrap-time.min.js"></script>
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Local builds use the same paths under `dist/`:
|
|
@@ -44,10 +44,21 @@ Local builds use the same paths under `dist/`:
|
|
|
44
44
|
<script src="dist/js/bootstrap-time.min.js"></script>
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
The script initializes the clock when `.clock-picker`, `#clock`, `#time-input`, `#hour-arrow` and `#minute-arrow` are present. The widget overlays the form under the time input. See `examples/bootstrap-time.html`.
|
|
47
|
+
The script initializes the clock when `.clock-picker`, `#clock`, `#time-input`, `#hour-arrow` and `#minute-arrow` are present. The widget overlays the form under the time input. Minute selection follows the input `step`, including when `step` changes: `60` allows every minute by clicking between the numbers, `900` enables only 00, 15, 30 and 45. See `examples/bootstrap-time.html`.
|
|
48
48
|
|
|
49
49
|
## Changelog
|
|
50
50
|
|
|
51
|
+
### 0.1.6-beta
|
|
52
|
+
|
|
53
|
+
- The example starts on the current time.
|
|
54
|
+
- Minute selection follows the input `step`, including when it changes.
|
|
55
|
+
- `step="60"` selects any minute by clicking between the numbers.
|
|
56
|
+
- `step="900"` enables only 00, 15, 30 and 45.
|
|
57
|
+
|
|
58
|
+
### 0.1.5-beta
|
|
59
|
+
|
|
60
|
+
- Release title uses `<version>-beta`.
|
|
61
|
+
|
|
51
62
|
### 0.1.4-beta
|
|
52
63
|
|
|
53
64
|
- Bootstrap 6 is a dependency.
|
|
@@ -76,6 +76,8 @@
|
|
|
76
76
|
width: 16rem;
|
|
77
77
|
height: 16rem;
|
|
78
78
|
border-radius: 50%;
|
|
79
|
+
touch-action: none;
|
|
80
|
+
cursor: pointer;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
.clock-hand {
|
|
@@ -118,3 +120,7 @@
|
|
|
118
120
|
.clock-number[aria-pressed=true] {
|
|
119
121
|
color: var(--bs-white, #fff);
|
|
120
122
|
}
|
|
123
|
+
.clock-number:disabled {
|
|
124
|
+
opacity: 0.35;
|
|
125
|
+
cursor: default;
|
|
126
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.clock-picker{position:relative;width:20rem}.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
|
|
1
|
+
.clock-picker{position:relative;width:20rem}.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}
|
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
var clockToggle = document.querySelector("#clock-toggle");
|
|
19
19
|
if (!clock || !timeInput || !hourArrow || !minuteArrow) return;
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var now = new Date();
|
|
22
|
+
var initial = timeInput.value
|
|
23
|
+
? timeInput.value.split(":")
|
|
24
|
+
: [now.getHours(), now.getMinutes()];
|
|
22
25
|
var hour = Number(initial[0]) || 0;
|
|
23
|
-
var minute = Number(initial[1]) || 0;
|
|
26
|
+
var minute = snapMinute(Number(initial[1]) || 0);
|
|
24
27
|
var mode = "hour";
|
|
25
28
|
var handAngle = 150;
|
|
26
29
|
var hand = document.createElement("div");
|
|
@@ -36,6 +39,22 @@
|
|
|
36
39
|
return String(value).padStart(2, "0");
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
function minuteStep() {
|
|
43
|
+
var step = Number(timeInput.getAttribute("step") || timeInput.step);
|
|
44
|
+
if (!step || step < 60) step = 60;
|
|
45
|
+
return Math.max(1, Math.round(step / 60));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function snapMinute(value) {
|
|
49
|
+
var step = minuteStep();
|
|
50
|
+
var snapped = Math.round(value / step) * step;
|
|
51
|
+
return ((snapped % 60) + 60) % 60;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function allowedMinute(value) {
|
|
55
|
+
return value % minuteStep() === 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
39
58
|
function targetAngle() {
|
|
40
59
|
return mode === "hour" ? (hour % 12) * 30 : minute * 6;
|
|
41
60
|
}
|
|
@@ -85,14 +104,18 @@
|
|
|
85
104
|
var button = document.createElement("button");
|
|
86
105
|
var inner = mode === "hour" && index >= 12;
|
|
87
106
|
var angle = (mode === "hour" ? index % 12 : index) * 30;
|
|
107
|
+
var disabled = mode === "minute" && !allowedMinute(value);
|
|
88
108
|
|
|
89
109
|
button.type = "button";
|
|
90
110
|
button.className = "clock-number";
|
|
91
|
-
button.textContent =
|
|
92
|
-
button.
|
|
111
|
+
button.textContent = value === 0 ? "00" : String(value);
|
|
112
|
+
button.dataset.value = String(value);
|
|
113
|
+
button.disabled = disabled;
|
|
114
|
+
button.setAttribute("aria-pressed", !disabled && value === selected ? "true" : "false");
|
|
93
115
|
button.style.setProperty("--angle", angle + "deg");
|
|
94
116
|
button.style.setProperty("--radius", inner ? INNER_RADIUS : OUTER_RADIUS);
|
|
95
117
|
button.addEventListener("click", function () {
|
|
118
|
+
if (button.disabled) return;
|
|
96
119
|
if (mode === "hour") {
|
|
97
120
|
hour = value;
|
|
98
121
|
mode = "minute";
|
|
@@ -124,6 +147,31 @@
|
|
|
124
147
|
else hideWidget();
|
|
125
148
|
}
|
|
126
149
|
|
|
150
|
+
function valueFromPoint(event) {
|
|
151
|
+
var rect = clock.getBoundingClientRect();
|
|
152
|
+
var dx = event.clientX - (rect.left + rect.width / 2);
|
|
153
|
+
var dy = event.clientY - (rect.top + rect.height / 2);
|
|
154
|
+
var angle = (Math.atan2(dx, -dy) * 180 / Math.PI + 360) % 360;
|
|
155
|
+
if (mode === "minute") return snapMinute(Math.round(angle / 6) % 60);
|
|
156
|
+
var hour12 = Math.round(angle / 30) % 12;
|
|
157
|
+
var inner = Math.hypot(dx, dy) < rect.width * 0.32;
|
|
158
|
+
if (inner) return hour12 === 0 ? 0 : hour12 + 12;
|
|
159
|
+
return hour12 === 0 ? 12 : hour12;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
clock.addEventListener("click", function (event) {
|
|
163
|
+
if (event.target.closest(".clock-number")) return;
|
|
164
|
+
var value = valueFromPoint(event);
|
|
165
|
+
if (mode === "minute") minute = value;
|
|
166
|
+
else {
|
|
167
|
+
hour = value;
|
|
168
|
+
mode = "minute";
|
|
169
|
+
}
|
|
170
|
+
writeInput();
|
|
171
|
+
updateArrows();
|
|
172
|
+
renderClock();
|
|
173
|
+
});
|
|
174
|
+
|
|
127
175
|
hourArrow.addEventListener("click", function () {
|
|
128
176
|
showMode("hour");
|
|
129
177
|
});
|
|
@@ -158,6 +206,30 @@
|
|
|
158
206
|
hideWidget();
|
|
159
207
|
});
|
|
160
208
|
|
|
209
|
+
function applyStep() {
|
|
210
|
+
minute = snapMinute(minute);
|
|
211
|
+
writeInput();
|
|
212
|
+
renderClock();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
var stepDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "step");
|
|
216
|
+
if (stepDescriptor && stepDescriptor.set) {
|
|
217
|
+
Object.defineProperty(timeInput, "step", {
|
|
218
|
+
configurable: true,
|
|
219
|
+
get: function () {
|
|
220
|
+
return stepDescriptor.get.call(timeInput);
|
|
221
|
+
},
|
|
222
|
+
set: function (value) {
|
|
223
|
+
stepDescriptor.set.call(timeInput, value);
|
|
224
|
+
applyStep();
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
new MutationObserver(applyStep).observe(timeInput, {
|
|
229
|
+
attributes: true,
|
|
230
|
+
attributeFilter: ["step"]
|
|
231
|
+
});
|
|
232
|
+
|
|
161
233
|
updateArrows();
|
|
162
234
|
writeInput();
|
|
163
235
|
renderClock();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){"use strict";var e="4.6rem",t="6.4rem";function n(){var n=document.querySelector(".clock-picker"),r=document.querySelector("#clock"),u=document.querySelector("#clock-widget"),o=document.querySelector("#time-input"),
|
|
1
|
+
!function(){"use strict";var e="4.6rem",t="6.4rem";function n(){var n=document.querySelector(".clock-picker"),r=document.querySelector("#clock"),u=document.querySelector("#clock-widget"),o=document.querySelector("#time-input"),i=document.querySelector("#hour-arrow"),a=document.querySelector("#minute-arrow"),c=document.querySelector("#clock-toggle");if(r&&o&&i&&a){var d=new Date,s=o.value?o.value.split(":"):[d.getHours(),d.getMinutes()],l=Number(s[0])||0,m=k(Number(s[1])||0),f="hour",p=150,h=document.createElement("div"),v=document.createElement("span");h.className="clock-hand bg-primary",v.className="clock-knob bg-primary",v.setAttribute("aria-hidden","true"),h.append(v),r.append(h),r.addEventListener("click",function(e){if(!e.target.closest(".clock-number")){var t=function(e){var t=r.getBoundingClientRect(),n=e.clientX-(t.left+t.width/2),u=e.clientY-(t.top+t.height/2),o=(180*Math.atan2(n,-u)/Math.PI+360)%360;if("minute"===f)return k(Math.round(o/6)%60);var i=Math.round(o/30)%12;return Math.hypot(n,u)<.32*t.width?0===i?0:i+12:0===i?12:i}(e);"minute"===f?m=t:(l=t,f="minute"),L(),S(),w()}}),i.addEventListener("click",function(){M("hour")}),a.addEventListener("click",function(){M("minute")}),c&&c.addEventListener("click",function(){u&&u.hidden?q():N()}),o.addEventListener("focus",q),o.addEventListener("input",function(){if(o.value){var e=o.value.split(":"),t=Number(e[0]),n=Number(e[1]);n!==m?f="minute":t!==l&&(f="hour"),l=t,m=n,S(),w()}}),n&&n.addEventListener("mousedown",function(e){e.target!==o&&(c&&c.contains(e.target)||e.preventDefault())}),document.addEventListener("mousedown",function(e){n&&!n.contains(e.target)&&N()});var b=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"step");b&&b.set&&Object.defineProperty(o,"step",{configurable:!0,get:function(){return b.get.call(o)},set:function(e){b.set.call(o,e),A()}}),new MutationObserver(A).observe(o,{attributes:!0,attributeFilter:["step"]}),S(),L(),w(),N()}function g(e){return String(e).padStart(2,"0")}function y(){var e=Number(o.getAttribute("step")||o.step);return(!e||e<60)&&(e=60),Math.max(1,Math.round(e/60))}function k(e){var t=y();return(Math.round(e/t)*t%60+60)%60}function E(){p+=((("hour"===f?l%12*30:6*m)-p)%360+540)%360-180,h.style.setProperty("--angle",p+"deg"),h.style.setProperty("--hand","hour"===f&&(0===l||l>12)?e:t)}function S(){i.disabled="hour"===f,a.disabled="minute"===f}function L(){o.value=g(l)+":"+g(m)}function M(e){f!==e&&(f=e,S(),w())}function w(){r.querySelectorAll(".clock-number").forEach(function(e){e.remove()}),r.setAttribute("aria-label","hour"===f?"Kies een uur":"Kies de minuten");var n="hour"===f?[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],u="hour"===f?l:m;E(),n.forEach(function(n,o){var i=document.createElement("button"),a="hour"===f&&o>=12,c=30*("hour"===f?o%12:o),d="minute"===f&&!function(e){return e%y()===0}(n);i.type="button",i.className="clock-number",i.textContent=0===n?"00":String(n),i.dataset.value=String(n),i.disabled=d,i.setAttribute("aria-pressed",d||n!==u?"false":"true"),i.style.setProperty("--angle",c+"deg"),i.style.setProperty("--radius",a?e:t),i.addEventListener("click",function(){i.disabled||("hour"===f?(l=n,f="minute"):m=n,L(),S(),w())}),r.append(i)})}function q(){u&&(u.hidden=!1,c&&c.setAttribute("aria-pressed","true"))}function N(){u&&(u.hidden=!0,c&&c.setAttribute("aria-pressed","false"))}function A(){m=k(m),L(),w()}}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",n):n()}();
|
package/package.json
CHANGED
package/src/js/bootstrap-time.js
CHANGED
|
@@ -18,9 +18,12 @@
|
|
|
18
18
|
var clockToggle = document.querySelector("#clock-toggle");
|
|
19
19
|
if (!clock || !timeInput || !hourArrow || !minuteArrow) return;
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var now = new Date();
|
|
22
|
+
var initial = timeInput.value
|
|
23
|
+
? timeInput.value.split(":")
|
|
24
|
+
: [now.getHours(), now.getMinutes()];
|
|
22
25
|
var hour = Number(initial[0]) || 0;
|
|
23
|
-
var minute = Number(initial[1]) || 0;
|
|
26
|
+
var minute = snapMinute(Number(initial[1]) || 0);
|
|
24
27
|
var mode = "hour";
|
|
25
28
|
var handAngle = 150;
|
|
26
29
|
var hand = document.createElement("div");
|
|
@@ -36,6 +39,22 @@
|
|
|
36
39
|
return String(value).padStart(2, "0");
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
function minuteStep() {
|
|
43
|
+
var step = Number(timeInput.getAttribute("step") || timeInput.step);
|
|
44
|
+
if (!step || step < 60) step = 60;
|
|
45
|
+
return Math.max(1, Math.round(step / 60));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function snapMinute(value) {
|
|
49
|
+
var step = minuteStep();
|
|
50
|
+
var snapped = Math.round(value / step) * step;
|
|
51
|
+
return ((snapped % 60) + 60) % 60;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function allowedMinute(value) {
|
|
55
|
+
return value % minuteStep() === 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
39
58
|
function targetAngle() {
|
|
40
59
|
return mode === "hour" ? (hour % 12) * 30 : minute * 6;
|
|
41
60
|
}
|
|
@@ -85,14 +104,18 @@
|
|
|
85
104
|
var button = document.createElement("button");
|
|
86
105
|
var inner = mode === "hour" && index >= 12;
|
|
87
106
|
var angle = (mode === "hour" ? index % 12 : index) * 30;
|
|
107
|
+
var disabled = mode === "minute" && !allowedMinute(value);
|
|
88
108
|
|
|
89
109
|
button.type = "button";
|
|
90
110
|
button.className = "clock-number";
|
|
91
|
-
button.textContent =
|
|
92
|
-
button.
|
|
111
|
+
button.textContent = value === 0 ? "00" : String(value);
|
|
112
|
+
button.dataset.value = String(value);
|
|
113
|
+
button.disabled = disabled;
|
|
114
|
+
button.setAttribute("aria-pressed", !disabled && value === selected ? "true" : "false");
|
|
93
115
|
button.style.setProperty("--angle", angle + "deg");
|
|
94
116
|
button.style.setProperty("--radius", inner ? INNER_RADIUS : OUTER_RADIUS);
|
|
95
117
|
button.addEventListener("click", function () {
|
|
118
|
+
if (button.disabled) return;
|
|
96
119
|
if (mode === "hour") {
|
|
97
120
|
hour = value;
|
|
98
121
|
mode = "minute";
|
|
@@ -124,6 +147,31 @@
|
|
|
124
147
|
else hideWidget();
|
|
125
148
|
}
|
|
126
149
|
|
|
150
|
+
function valueFromPoint(event) {
|
|
151
|
+
var rect = clock.getBoundingClientRect();
|
|
152
|
+
var dx = event.clientX - (rect.left + rect.width / 2);
|
|
153
|
+
var dy = event.clientY - (rect.top + rect.height / 2);
|
|
154
|
+
var angle = (Math.atan2(dx, -dy) * 180 / Math.PI + 360) % 360;
|
|
155
|
+
if (mode === "minute") return snapMinute(Math.round(angle / 6) % 60);
|
|
156
|
+
var hour12 = Math.round(angle / 30) % 12;
|
|
157
|
+
var inner = Math.hypot(dx, dy) < rect.width * 0.32;
|
|
158
|
+
if (inner) return hour12 === 0 ? 0 : hour12 + 12;
|
|
159
|
+
return hour12 === 0 ? 12 : hour12;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
clock.addEventListener("click", function (event) {
|
|
163
|
+
if (event.target.closest(".clock-number")) return;
|
|
164
|
+
var value = valueFromPoint(event);
|
|
165
|
+
if (mode === "minute") minute = value;
|
|
166
|
+
else {
|
|
167
|
+
hour = value;
|
|
168
|
+
mode = "minute";
|
|
169
|
+
}
|
|
170
|
+
writeInput();
|
|
171
|
+
updateArrows();
|
|
172
|
+
renderClock();
|
|
173
|
+
});
|
|
174
|
+
|
|
127
175
|
hourArrow.addEventListener("click", function () {
|
|
128
176
|
showMode("hour");
|
|
129
177
|
});
|
|
@@ -158,6 +206,30 @@
|
|
|
158
206
|
hideWidget();
|
|
159
207
|
});
|
|
160
208
|
|
|
209
|
+
function applyStep() {
|
|
210
|
+
minute = snapMinute(minute);
|
|
211
|
+
writeInput();
|
|
212
|
+
renderClock();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
var stepDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "step");
|
|
216
|
+
if (stepDescriptor && stepDescriptor.set) {
|
|
217
|
+
Object.defineProperty(timeInput, "step", {
|
|
218
|
+
configurable: true,
|
|
219
|
+
get: function () {
|
|
220
|
+
return stepDescriptor.get.call(timeInput);
|
|
221
|
+
},
|
|
222
|
+
set: function (value) {
|
|
223
|
+
stepDescriptor.set.call(timeInput, value);
|
|
224
|
+
applyStep();
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
new MutationObserver(applyStep).observe(timeInput, {
|
|
229
|
+
attributes: true,
|
|
230
|
+
attributeFilter: ["step"]
|
|
231
|
+
});
|
|
232
|
+
|
|
161
233
|
updateArrows();
|
|
162
234
|
writeInput();
|
|
163
235
|
renderClock();
|
|
@@ -89,6 +89,8 @@
|
|
|
89
89
|
width: 16rem;
|
|
90
90
|
height: 16rem;
|
|
91
91
|
border-radius: 50%;
|
|
92
|
+
touch-action: none;
|
|
93
|
+
cursor: pointer;
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
.clock-hand {
|
|
@@ -131,4 +133,9 @@
|
|
|
131
133
|
&[aria-pressed="true"] {
|
|
132
134
|
color: var(--bs-white, #fff);
|
|
133
135
|
}
|
|
136
|
+
|
|
137
|
+
&:disabled {
|
|
138
|
+
opacity: 0.35;
|
|
139
|
+
cursor: default;
|
|
140
|
+
}
|
|
134
141
|
}
|