@realmorg/ui 2.0.0-alpha.2 → 2.0.0-alpha.4

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.
Files changed (65) hide show
  1. package/README.md +6 -6
  2. package/components/accordion.html +40 -1
  3. package/components/alert-dialog.html +40 -0
  4. package/components/alert.html +14 -0
  5. package/components/aspect-ratio.html +6 -0
  6. package/components/attachment.html +14 -0
  7. package/components/avatar.html +22 -0
  8. package/components/badge.html +6 -0
  9. package/components/breadcrumb.html +30 -0
  10. package/components/bubble.html +10 -0
  11. package/components/button-group.html +14 -0
  12. package/components/button.html +41 -22
  13. package/components/calendar.html +6 -0
  14. package/components/card.html +30 -0
  15. package/components/carousel.html +22 -0
  16. package/components/chart.html +6 -0
  17. package/components/checkbox.html +6 -0
  18. package/components/code-block.html +6 -0
  19. package/components/collapsible.html +14 -0
  20. package/components/combobox.html +26 -0
  21. package/components/command.html +12 -0
  22. package/components/context-menu.html +14 -0
  23. package/components/dialog.html +49 -3
  24. package/components/direction.html +6 -0
  25. package/components/drawer.html +46 -3
  26. package/components/dropdown-menu.html +75 -1
  27. package/components/empty.html +26 -0
  28. package/components/field.html +26 -0
  29. package/components/hover-card.html +41 -1
  30. package/components/input-group.html +16 -0
  31. package/components/input-otp.html +12 -0
  32. package/components/input.html +12 -0
  33. package/components/item.html +38 -0
  34. package/components/kbd.html +10 -0
  35. package/components/label.html +6 -0
  36. package/components/marker.html +6 -0
  37. package/components/menubar.html +36 -1
  38. package/components/message-scroller.html +6 -0
  39. package/components/message.html +18 -0
  40. package/components/navigation-menu.html +29 -0
  41. package/components/pagination.html +6 -0
  42. package/components/popover.html +53 -1
  43. package/components/progress.html +6 -0
  44. package/components/radio-group.html +6 -0
  45. package/components/resizable.html +14 -0
  46. package/components/scroll-area.html +6 -0
  47. package/components/select.html +12 -0
  48. package/components/separator.html +6 -0
  49. package/components/sheet.html +30 -0
  50. package/components/sidebar.html +52 -2
  51. package/components/skeleton.html +6 -0
  52. package/components/slider.html +28 -1
  53. package/components/spinner.html +6 -0
  54. package/components/switch.html +6 -0
  55. package/components/table.html +6 -0
  56. package/components/tabs.html +18 -0
  57. package/components/textarea.html +12 -0
  58. package/components/toaster.html +6 -0
  59. package/components/toggle-group.html +6 -0
  60. package/components/toggle.html +6 -0
  61. package/components/tooltip.html +43 -1
  62. package/dist/theme.css +13 -0
  63. package/dist/ui.html +1171 -37
  64. package/package.json +4 -3
  65. package/theme.css +13 -0
@@ -29,6 +29,12 @@
29
29
  </script>
30
30
 
31
31
  <style>
32
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
33
+ touch-action does not reach shadow content in iOS Safari. */
34
+ :host,
35
+ * {
36
+ touch-action: manipulation;
37
+ }
32
38
  :host {
33
39
  position: relative;
34
40
  display: block;
@@ -4,6 +4,12 @@
4
4
  </script>
5
5
 
6
6
  <style>
7
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
8
+ touch-action does not reach shadow content in iOS Safari. */
9
+ :host,
10
+ * {
11
+ touch-action: manipulation;
12
+ }
7
13
  :host {
8
14
  display: flex;
9
15
  gap: calc(var(--spacing) * 2);
@@ -36,6 +42,10 @@
36
42
 
37
43
  <custom-element name="ui-message-avatar" slot="avatar">
38
44
  <style>
45
+ :host,
46
+ * {
47
+ touch-action: manipulation;
48
+ }
39
49
  :host {
40
50
  display: flex;
41
51
  align-self: flex-end;
@@ -48,6 +58,10 @@
48
58
 
49
59
  <custom-element name="ui-message-header" slot="header">
50
60
  <style>
61
+ :host,
62
+ * {
63
+ touch-action: manipulation;
64
+ }
51
65
  :host {
52
66
  display: flex;
53
67
  align-items: center;
@@ -63,6 +77,10 @@
63
77
 
64
78
  <custom-element name="ui-message-footer" slot="footer">
65
79
  <style>
80
+ :host,
81
+ * {
82
+ touch-action: manipulation;
83
+ }
66
84
  :host {
67
85
  display: flex;
68
86
  align-items: center;
@@ -4,6 +4,12 @@
4
4
  </script>
5
5
 
6
6
  <style>
7
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
8
+ touch-action does not reach shadow content in iOS Safari. */
9
+ :host,
10
+ * {
11
+ touch-action: manipulation;
12
+ }
7
13
  :host {
8
14
  display: block;
9
15
  }
@@ -14,6 +20,10 @@
14
20
 
15
21
  <custom-element name="ui-navigation-menu-list">
16
22
  <style>
23
+ :host,
24
+ * {
25
+ touch-action: manipulation;
26
+ }
17
27
  :host {
18
28
  display: block;
19
29
  }
@@ -57,6 +67,10 @@
57
67
  </script>
58
68
 
59
69
  <style>
70
+ :host,
71
+ * {
72
+ touch-action: manipulation;
73
+ }
60
74
  :host {
61
75
  position: relative;
62
76
  display: block;
@@ -77,6 +91,9 @@
77
91
  box-shadow: var(--shadow-md);
78
92
  inset: auto;
79
93
  position-anchor: --navigation-trigger;
94
+ height: fit-content;
95
+ max-height: calc(100svh - calc(var(--spacing) * 8));
96
+ overflow-y: auto;
80
97
  position-area: bottom span-right;
81
98
  }
82
99
  </style>
@@ -87,6 +104,10 @@
87
104
 
88
105
  <custom-element name="ui-navigation-menu-trigger" delegates-focus>
89
106
  <style>
107
+ :host,
108
+ * {
109
+ touch-action: manipulation;
110
+ }
90
111
  :host {
91
112
  display: inline-flex;
92
113
  }
@@ -129,6 +150,10 @@
129
150
 
130
151
  <custom-element name="ui-navigation-menu-content" slot="content">
131
152
  <style>
153
+ :host,
154
+ * {
155
+ touch-action: manipulation;
156
+ }
132
157
  :host {
133
158
  display: grid;
134
159
  gap: calc(var(--spacing) * 1);
@@ -161,6 +186,10 @@
161
186
  </script>
162
187
 
163
188
  <style>
189
+ :host,
190
+ * {
191
+ touch-action: manipulation;
192
+ }
164
193
  :host {
165
194
  display: var(--ui-navigation-link-display, inline-flex);
166
195
  }
@@ -56,6 +56,12 @@
56
56
  </script>
57
57
 
58
58
  <style>
59
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
60
+ touch-action does not reach shadow content in iOS Safari. */
61
+ :host,
62
+ * {
63
+ touch-action: manipulation;
64
+ }
59
65
  :host {
60
66
  display: flex;
61
67
  justify-content: center;
@@ -19,6 +19,12 @@
19
19
  </script>
20
20
 
21
21
  <style>
22
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
23
+ touch-action does not reach shadow content in iOS Safari. */
24
+ :host,
25
+ * {
26
+ touch-action: manipulation;
27
+ }
22
28
  :host {
23
29
  display: contents;
24
30
  }
@@ -29,6 +35,10 @@
29
35
 
30
36
  <custom-element name="ui-popover-trigger">
31
37
  <style>
38
+ :host,
39
+ * {
40
+ touch-action: manipulation;
41
+ }
32
42
  :host {
33
43
  display: inline-block;
34
44
  vertical-align: middle;
@@ -40,14 +50,32 @@
40
50
 
41
51
  <custom-element name="ui-popover-content">
42
52
  <script>
43
- defineProps({
53
+ const props = defineProps({
44
54
  placement: prop.enum(["bottom", "top", "left", "right"]).default("bottom"),
45
55
  });
46
56
 
57
+ const BLOCK_SIDES = new Set(["bottom", "top"]);
58
+
59
+ // Once open, it keeps the side it opened on. Re-deciding while the page scrolls makes it jump,
60
+ // because iOS Safari's toolbar changes the viewport height mid-scroll.
61
+ // Firefox holds a box that does not fit against the screen edge, so touching it counts too.
62
+ function opened(event) {
63
+ internals.states.delete("flipped");
64
+ if (event.newState !== "open" || !BLOCK_SIDES.has(props.placement)) return;
65
+ const box = host.getBoundingClientRect();
66
+ if (box.bottom >= innerHeight || box.top <= 0) internals.states.add("flipped");
67
+ }
68
+
47
69
  attrs.popover ??= "auto";
70
+
71
+ listen("toggle", opened);
48
72
  </script>
49
73
 
50
74
  <style>
75
+ :host,
76
+ * {
77
+ touch-action: manipulation;
78
+ }
51
79
  :host {
52
80
  box-sizing: border-box;
53
81
  width: calc(var(--spacing) * 72);
@@ -59,11 +87,17 @@
59
87
  color: var(--popover-foreground);
60
88
  box-shadow: var(--shadow-md);
61
89
  inset: auto;
90
+ height: fit-content;
91
+ max-height: calc(100svh - calc(var(--spacing) * 8));
92
+ overflow-y: auto;
62
93
  position-area: bottom;
63
94
  position-try-fallbacks: flip-block, flip-inline;
64
95
  }
65
96
  :host(:popover-open) {
97
+ position-try-fallbacks: flip-inline;
66
98
  display: grid;
99
+ /* Safari stretches a grid overlay to its max-height unless the rows are packed at the start. */
100
+ align-content: start;
67
101
  gap: calc(var(--spacing) * 4);
68
102
  }
69
103
  :host(:state(attr-width)) {
@@ -72,6 +106,12 @@
72
106
  :host(:state(attr-placement-is-top)) {
73
107
  position-area: top;
74
108
  }
109
+ :host(:state(flipped)) {
110
+ position-area: top;
111
+ }
112
+ :host(:state(flipped):state(attr-placement-is-top)) {
113
+ position-area: bottom;
114
+ }
75
115
  :host(:state(attr-placement-is-left)) {
76
116
  position-area: left;
77
117
  }
@@ -92,6 +132,10 @@
92
132
 
93
133
  <custom-element name="ui-popover-header">
94
134
  <style>
135
+ :host,
136
+ * {
137
+ touch-action: manipulation;
138
+ }
95
139
  :host {
96
140
  display: grid;
97
141
  gap: calc(var(--spacing) * 1);
@@ -103,6 +147,10 @@
103
147
 
104
148
  <custom-element name="ui-popover-title">
105
149
  <style>
150
+ :host,
151
+ * {
152
+ touch-action: manipulation;
153
+ }
106
154
  :host {
107
155
  display: block;
108
156
  }
@@ -119,6 +167,10 @@
119
167
 
120
168
  <custom-element name="ui-popover-description">
121
169
  <style>
170
+ :host,
171
+ * {
172
+ touch-action: manipulation;
173
+ }
122
174
  :host {
123
175
  display: block;
124
176
  }
@@ -8,6 +8,12 @@
8
8
  </script>
9
9
 
10
10
  <style>
11
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
12
+ touch-action does not reach shadow content in iOS Safari. */
13
+ :host,
14
+ * {
15
+ touch-action: manipulation;
16
+ }
11
17
  :host {
12
18
  display: block;
13
19
  width: 100%;
@@ -37,6 +37,12 @@
37
37
  </script>
38
38
 
39
39
  <style>
40
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
41
+ touch-action does not reach shadow content in iOS Safari. */
42
+ :host,
43
+ * {
44
+ touch-action: manipulation;
45
+ }
40
46
  :host {
41
47
  display: grid;
42
48
  gap: calc(var(--spacing) * 3);
@@ -7,6 +7,12 @@
7
7
  </script>
8
8
 
9
9
  <style>
10
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
11
+ touch-action does not reach shadow content in iOS Safari. */
12
+ :host,
13
+ * {
14
+ touch-action: manipulation;
15
+ }
10
16
  :host {
11
17
  display: flex;
12
18
  width: 100%;
@@ -35,6 +41,10 @@
35
41
  </script>
36
42
 
37
43
  <style>
44
+ :host,
45
+ * {
46
+ touch-action: manipulation;
47
+ }
38
48
  :host {
39
49
  display: block;
40
50
  flex: var(--attr-size) 1 0;
@@ -110,6 +120,10 @@
110
120
  </script>
111
121
 
112
122
  <style>
123
+ :host,
124
+ * {
125
+ touch-action: manipulation;
126
+ }
113
127
  :host {
114
128
  position: relative;
115
129
  display: flex;
@@ -7,6 +7,12 @@
7
7
  </script>
8
8
 
9
9
  <style>
10
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
11
+ touch-action does not reach shadow content in iOS Safari. */
12
+ :host,
13
+ * {
14
+ touch-action: manipulation;
15
+ }
10
16
  :host {
11
17
  display: block;
12
18
  position: relative;
@@ -32,6 +32,12 @@
32
32
  </script>
33
33
 
34
34
  <style>
35
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
36
+ touch-action does not reach shadow content in iOS Safari. */
37
+ :host,
38
+ * {
39
+ touch-action: manipulation;
40
+ }
35
41
  :host {
36
42
  display: block;
37
43
  min-width: calc(var(--spacing) * 32);
@@ -57,6 +63,12 @@
57
63
  outline: none;
58
64
  cursor: pointer;
59
65
  }
66
+ /* iOS Safari zooms in on a focused field whose text is under 16px. */
67
+ @media (pointer: coarse) {
68
+ select {
69
+ font-size: var(--text-base);
70
+ }
71
+ }
60
72
  :host(:state(attr-size-is-sm)) select {
61
73
  height: calc(var(--spacing) * 8);
62
74
  }
@@ -9,6 +9,12 @@
9
9
  </script>
10
10
 
11
11
  <style>
12
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
13
+ touch-action does not reach shadow content in iOS Safari. */
14
+ :host,
15
+ * {
16
+ touch-action: manipulation;
17
+ }
12
18
  :host {
13
19
  display: block;
14
20
  flex-shrink: 0;
@@ -52,6 +52,12 @@
52
52
  </script>
53
53
 
54
54
  <style>
55
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
56
+ touch-action does not reach shadow content in iOS Safari. */
57
+ :host,
58
+ * {
59
+ touch-action: manipulation;
60
+ }
55
61
  :host {
56
62
  display: contents;
57
63
  }
@@ -67,6 +73,10 @@
67
73
 
68
74
  <custom-element name="ui-sheet-trigger" slot="trigger">
69
75
  <style>
76
+ :host,
77
+ * {
78
+ touch-action: manipulation;
79
+ }
70
80
  :host,
71
81
  span {
72
82
  display: contents;
@@ -78,6 +88,10 @@
78
88
 
79
89
  <custom-element name="ui-sheet-close">
80
90
  <style>
91
+ :host,
92
+ * {
93
+ touch-action: manipulation;
94
+ }
81
95
  :host,
82
96
  span {
83
97
  display: contents;
@@ -89,6 +103,10 @@
89
103
 
90
104
  <custom-element name="ui-sheet-header" slot="header">
91
105
  <style>
106
+ :host,
107
+ * {
108
+ touch-action: manipulation;
109
+ }
92
110
  :host {
93
111
  display: grid;
94
112
  gap: calc(var(--spacing) * 2);
@@ -100,6 +118,10 @@
100
118
 
101
119
  <custom-element name="ui-sheet-title">
102
120
  <style>
121
+ :host,
122
+ * {
123
+ touch-action: manipulation;
124
+ }
103
125
  :host {
104
126
  display: block;
105
127
  }
@@ -116,6 +138,10 @@
116
138
 
117
139
  <custom-element name="ui-sheet-description">
118
140
  <style>
141
+ :host,
142
+ * {
143
+ touch-action: manipulation;
144
+ }
119
145
  :host {
120
146
  display: block;
121
147
  }
@@ -131,6 +157,10 @@
131
157
 
132
158
  <custom-element name="ui-sheet-footer" slot="footer">
133
159
  <style>
160
+ :host,
161
+ * {
162
+ touch-action: manipulation;
163
+ }
134
164
  :host {
135
165
  display: flex;
136
166
  flex-wrap: wrap;
@@ -39,11 +39,17 @@
39
39
  </script>
40
40
 
41
41
  <style>
42
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
43
+ touch-action does not reach shadow content in iOS Safari. */
44
+ :host,
45
+ * {
46
+ touch-action: manipulation;
47
+ }
42
48
  :host {
43
49
  --ui-sidebar-width: calc(var(--spacing) * 64);
44
50
  --ui-sidebar-label: block;
45
51
  display: flex;
46
- min-height: 100dvh;
52
+ min-height: 100svh;
47
53
  background: var(--sidebar);
48
54
  }
49
55
  :host(:state(attr-collapsed)) {
@@ -54,7 +60,7 @@
54
60
  position: sticky;
55
61
  top: 0;
56
62
  width: var(--ui-sidebar-width);
57
- height: 100dvh;
63
+ height: 100svh;
58
64
  flex-shrink: 0;
59
65
  transition: width 0.2s ease;
60
66
  }
@@ -93,6 +99,10 @@
93
99
 
94
100
  <custom-element name="ui-sidebar" slot="sidebar">
95
101
  <style>
102
+ :host,
103
+ * {
104
+ touch-action: manipulation;
105
+ }
96
106
  :host {
97
107
  display: flex;
98
108
  flex-direction: column;
@@ -111,6 +121,10 @@
111
121
 
112
122
  <custom-element name="ui-sidebar-header" slot="header">
113
123
  <style>
124
+ :host,
125
+ * {
126
+ touch-action: manipulation;
127
+ }
114
128
  :host {
115
129
  display: flex;
116
130
  flex-direction: column;
@@ -124,6 +138,10 @@
124
138
 
125
139
  <custom-element name="ui-sidebar-footer" slot="footer">
126
140
  <style>
141
+ :host,
142
+ * {
143
+ touch-action: manipulation;
144
+ }
127
145
  :host {
128
146
  display: flex;
129
147
  flex-direction: column;
@@ -137,6 +155,10 @@
137
155
 
138
156
  <custom-element name="ui-sidebar-content">
139
157
  <style>
158
+ :host,
159
+ * {
160
+ touch-action: manipulation;
161
+ }
140
162
  :host {
141
163
  display: block;
142
164
  flex: 1;
@@ -163,6 +185,10 @@
163
185
  </script>
164
186
 
165
187
  <style>
188
+ :host,
189
+ * {
190
+ touch-action: manipulation;
191
+ }
166
192
  :host {
167
193
  display: flex;
168
194
  flex-direction: column;
@@ -175,6 +201,10 @@
175
201
 
176
202
  <custom-element name="ui-sidebar-group-label">
177
203
  <style>
204
+ :host,
205
+ * {
206
+ touch-action: manipulation;
207
+ }
178
208
  :host {
179
209
  display: var(--ui-sidebar-label, block);
180
210
  height: calc(var(--spacing) * 8);
@@ -192,6 +222,10 @@
192
222
 
193
223
  <custom-element name="ui-sidebar-menu">
194
224
  <style>
225
+ :host,
226
+ * {
227
+ touch-action: manipulation;
228
+ }
195
229
  :host {
196
230
  display: block;
197
231
  }
@@ -210,6 +244,10 @@
210
244
 
211
245
  <custom-element name="ui-sidebar-menu-item" role="listitem">
212
246
  <style>
247
+ :host,
248
+ * {
249
+ touch-action: manipulation;
250
+ }
213
251
  :host {
214
252
  position: relative;
215
253
  display: block;
@@ -250,6 +288,10 @@
250
288
  </script>
251
289
 
252
290
  <style>
291
+ :host,
292
+ * {
293
+ touch-action: manipulation;
294
+ }
253
295
  :host {
254
296
  display: block;
255
297
  }
@@ -291,6 +333,10 @@
291
333
 
292
334
  <custom-element name="ui-sidebar-menu-badge">
293
335
  <style>
336
+ :host,
337
+ * {
338
+ touch-action: manipulation;
339
+ }
294
340
  :host {
295
341
  display: var(--ui-sidebar-label, block);
296
342
  position: absolute;
@@ -322,6 +368,10 @@
322
368
 
323
369
  <custom-element name="ui-sidebar-inset">
324
370
  <style>
371
+ :host,
372
+ * {
373
+ touch-action: manipulation;
374
+ }
325
375
  :host {
326
376
  display: flex;
327
377
  flex: 1;
@@ -1,5 +1,11 @@
1
1
  <custom-element name="ui-skeleton">
2
2
  <style>
3
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
4
+ touch-action does not reach shadow content in iOS Safari. */
5
+ :host,
6
+ * {
7
+ touch-action: manipulation;
8
+ }
3
9
  :host {
4
10
  display: block;
5
11
  border-radius: var(--radius-md);
@@ -14,9 +14,21 @@
14
14
  return `${((props.value - props.min) / (props.max - props.min || 1)) * 100}%`;
15
15
  },
16
16
  });
17
+
18
+ // Writing the value Safari just set, during a finger drag, makes the thumb jump.
19
+ observe(() => {
20
+ const value = String(props.value);
21
+ if (refs.control && refs.control.value !== value) refs.control.value = value;
22
+ });
17
23
  </script>
18
24
 
19
25
  <style>
26
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
27
+ touch-action does not reach shadow content in iOS Safari. */
28
+ :host,
29
+ * {
30
+ touch-action: manipulation;
31
+ }
20
32
  :host {
21
33
  display: block;
22
34
  min-width: calc(var(--spacing) * 32);
@@ -30,6 +42,8 @@
30
42
  background: transparent;
31
43
  cursor: pointer;
32
44
  outline: none;
45
+ /* The slider owns the whole gesture, so the browser never turns a drag into a page pan. */
46
+ touch-action: none;
33
47
  }
34
48
  input::-webkit-slider-runnable-track {
35
49
  height: calc(var(--spacing) * 1.5);
@@ -61,6 +75,20 @@
61
75
  input:focus-visible::-webkit-slider-thumb {
62
76
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--ring) 50%, transparent);
63
77
  }
78
+ @media (pointer: coarse) {
79
+ input {
80
+ height: calc(var(--spacing) * 6);
81
+ }
82
+ input::-webkit-slider-thumb {
83
+ width: calc(var(--spacing) * 6);
84
+ height: calc(var(--spacing) * 6);
85
+ margin-top: calc(var(--spacing) * -2.25);
86
+ }
87
+ input::-moz-range-thumb {
88
+ width: calc(var(--spacing) * 6);
89
+ height: calc(var(--spacing) * 6);
90
+ }
91
+ }
64
92
  input:disabled {
65
93
  cursor: not-allowed;
66
94
  opacity: 0.5;
@@ -74,7 +102,6 @@
74
102
  _min="@min"
75
103
  _max="@max"
76
104
  _step="@step"
77
- _value="@value"
78
105
  _disabled="@disabled"
79
106
  _aria-label="@label"
80
107
  >
@@ -12,6 +12,12 @@
12
12
  </script>
13
13
 
14
14
  <style>
15
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
16
+ touch-action does not reach shadow content in iOS Safari. */
17
+ :host,
18
+ * {
19
+ touch-action: manipulation;
20
+ }
15
21
  :host {
16
22
  display: inline-flex;
17
23
  width: calc(var(--attr-size) * 1px);
@@ -10,6 +10,12 @@
10
10
  </script>
11
11
 
12
12
  <style>
13
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
14
+ touch-action does not reach shadow content in iOS Safari. */
15
+ :host,
16
+ * {
17
+ touch-action: manipulation;
18
+ }
13
19
  :host(:state(attr-checked)) label {
14
20
  color: var(--foreground);
15
21
  }