@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
@@ -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-dropdown-menu-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;
@@ -46,8 +56,15 @@
46
56
 
47
57
  const ITEMS = ":is(ui-menu-item, ui-menu-checkbox-item, ui-menu-radio-item):not([disabled])";
48
58
 
59
+ // Once open, the menu keeps the side it opened on. Re-deciding while the page scrolls makes it
60
+ // jump, 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.
49
62
  function opened(event) {
50
- if (event.newState === "open") host.querySelector(ITEMS)?.focus();
63
+ if (event.newState !== "open") return;
64
+ internals.states.delete("flipped");
65
+ const box = host.getBoundingClientRect();
66
+ if (box.bottom >= innerHeight || box.top <= 0) internals.states.add("flipped");
67
+ host.querySelector(ITEMS)?.focus({ preventScroll: true });
51
68
  }
52
69
 
53
70
  function leave(event) {
@@ -62,6 +79,10 @@
62
79
  </script>
63
80
 
64
81
  <style>
82
+ :host,
83
+ * {
84
+ touch-action: manipulation;
85
+ }
65
86
  :host {
66
87
  box-sizing: border-box;
67
88
  min-width: calc(var(--spacing) * 32);
@@ -73,6 +94,9 @@
73
94
  color: var(--popover-foreground);
74
95
  box-shadow: var(--shadow-md);
75
96
  inset: auto;
97
+ height: fit-content;
98
+ max-height: calc(100svh - calc(var(--spacing) * 8));
99
+ overflow-y: auto;
76
100
  position-area: bottom span-right;
77
101
  position-try-fallbacks: flip-block, flip-inline;
78
102
  }
@@ -87,6 +111,24 @@
87
111
  position-area: top span-left;
88
112
  margin: 0 0 calc(var(--spacing) * 1);
89
113
  }
114
+ :host(:popover-open) {
115
+ position-try-fallbacks: flip-inline;
116
+ }
117
+ :host(:state(flipped)) {
118
+ position-area: top span-right;
119
+ margin: 0 0 calc(var(--spacing) * 1);
120
+ }
121
+ :host(:state(flipped):state(attr-placement-is-bottom-end)) {
122
+ position-area: top span-left;
123
+ }
124
+ :host(:state(flipped):state(attr-placement-is-top-start)) {
125
+ position-area: bottom span-right;
126
+ margin: calc(var(--spacing) * 1) 0 0;
127
+ }
128
+ :host(:state(flipped):state(attr-placement-is-top-end)) {
129
+ position-area: bottom span-left;
130
+ margin: calc(var(--spacing) * 1) 0 0;
131
+ }
90
132
  </style>
91
133
 
92
134
  <div part="menu" focusgroup="menu block wrap"><slot></slot></div>
@@ -123,6 +165,10 @@
123
165
  </script>
124
166
 
125
167
  <style>
168
+ :host,
169
+ * {
170
+ touch-action: manipulation;
171
+ }
126
172
  :host {
127
173
  display: flex;
128
174
  align-items: center;
@@ -190,6 +236,10 @@
190
236
  </script>
191
237
 
192
238
  <style>
239
+ :host,
240
+ * {
241
+ touch-action: manipulation;
242
+ }
193
243
  :host {
194
244
  display: flex;
195
245
  align-items: center;
@@ -245,6 +295,10 @@
245
295
  </script>
246
296
 
247
297
  <style>
298
+ :host,
299
+ * {
300
+ touch-action: manipulation;
301
+ }
248
302
  :host {
249
303
  display: block;
250
304
  }
@@ -285,6 +339,10 @@
285
339
  </script>
286
340
 
287
341
  <style>
342
+ :host,
343
+ * {
344
+ touch-action: manipulation;
345
+ }
288
346
  :host {
289
347
  display: flex;
290
348
  align-items: center;
@@ -326,6 +384,10 @@
326
384
 
327
385
  <custom-element name="ui-menu-label">
328
386
  <style>
387
+ :host,
388
+ * {
389
+ touch-action: manipulation;
390
+ }
329
391
  :host {
330
392
  display: block;
331
393
  padding: calc(var(--spacing) * 1.5) calc(var(--spacing) * 2);
@@ -339,6 +401,10 @@
339
401
 
340
402
  <custom-element name="ui-menu-group" role="group">
341
403
  <style>
404
+ :host,
405
+ * {
406
+ touch-action: manipulation;
407
+ }
342
408
  :host {
343
409
  display: block;
344
410
  }
@@ -349,6 +415,10 @@
349
415
 
350
416
  <custom-element name="ui-menu-separator" role="separator">
351
417
  <style>
418
+ :host,
419
+ * {
420
+ touch-action: manipulation;
421
+ }
352
422
  :host {
353
423
  display: block;
354
424
  height: 1px;
@@ -360,6 +430,10 @@
360
430
 
361
431
  <custom-element name="ui-menu-shortcut">
362
432
  <style>
433
+ :host,
434
+ * {
435
+ touch-action: manipulation;
436
+ }
363
437
  :host {
364
438
  margin-inline-start: auto;
365
439
  font-size: var(--text-xs);
@@ -1,5 +1,11 @@
1
1
  <custom-element name="ui-empty">
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: flex;
5
11
  flex-direction: column;
@@ -20,6 +26,10 @@
20
26
 
21
27
  <custom-element name="ui-empty-header">
22
28
  <style>
29
+ :host,
30
+ * {
31
+ touch-action: manipulation;
32
+ }
23
33
  :host {
24
34
  display: flex;
25
35
  flex-direction: column;
@@ -34,6 +44,10 @@
34
44
 
35
45
  <custom-element name="ui-empty-media">
36
46
  <style>
47
+ :host,
48
+ * {
49
+ touch-action: manipulation;
50
+ }
37
51
  :host {
38
52
  display: flex;
39
53
  flex-shrink: 0;
@@ -63,6 +77,10 @@
63
77
  </script>
64
78
 
65
79
  <style>
80
+ :host,
81
+ * {
82
+ touch-action: manipulation;
83
+ }
66
84
  :host {
67
85
  display: block;
68
86
  }
@@ -79,6 +97,10 @@
79
97
 
80
98
  <custom-element name="ui-empty-description">
81
99
  <style>
100
+ :host,
101
+ * {
102
+ touch-action: manipulation;
103
+ }
82
104
  :host {
83
105
  display: block;
84
106
  font-size: var(--text-sm);
@@ -91,6 +113,10 @@
91
113
 
92
114
  <custom-element name="ui-empty-content">
93
115
  <style>
116
+ :host,
117
+ * {
118
+ touch-action: manipulation;
119
+ }
94
120
  :host {
95
121
  display: flex;
96
122
  flex-direction: column;
@@ -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: flex;
13
19
  flex-direction: column;
@@ -41,6 +47,10 @@
41
47
 
42
48
  <custom-element name="ui-field-content">
43
49
  <style>
50
+ :host,
51
+ * {
52
+ touch-action: manipulation;
53
+ }
44
54
  :host {
45
55
  display: flex;
46
56
  flex: 1;
@@ -55,6 +65,10 @@
55
65
 
56
66
  <custom-element name="ui-field-description">
57
67
  <style>
68
+ :host,
69
+ * {
70
+ touch-action: manipulation;
71
+ }
58
72
  :host {
59
73
  display: block;
60
74
  font-size: var(--text-sm);
@@ -68,6 +82,10 @@
68
82
 
69
83
  <custom-element name="ui-field-group">
70
84
  <style>
85
+ :host,
86
+ * {
87
+ touch-action: manipulation;
88
+ }
71
89
  :host {
72
90
  display: flex;
73
91
  flex-direction: column;
@@ -87,6 +105,10 @@
87
105
  </script>
88
106
 
89
107
  <style>
108
+ :host,
109
+ * {
110
+ touch-action: manipulation;
111
+ }
90
112
  :host {
91
113
  display: flex;
92
114
  flex-direction: column;
@@ -103,6 +125,10 @@
103
125
 
104
126
  <custom-element name="ui-field-legend" slot="legend">
105
127
  <style>
128
+ :host,
129
+ * {
130
+ touch-action: manipulation;
131
+ }
106
132
  :host {
107
133
  display: block;
108
134
  font-size: var(--text-base);
@@ -31,6 +31,12 @@
31
31
  </script>
32
32
 
33
33
  <style>
34
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
35
+ touch-action does not reach shadow content in iOS Safari. */
36
+ :host,
37
+ * {
38
+ touch-action: manipulation;
39
+ }
34
40
  :host {
35
41
  display: contents;
36
42
  }
@@ -41,6 +47,10 @@
41
47
 
42
48
  <custom-element name="ui-hover-card-trigger">
43
49
  <style>
50
+ :host,
51
+ * {
52
+ touch-action: manipulation;
53
+ }
44
54
  :host {
45
55
  display: inline-block;
46
56
  }
@@ -51,14 +61,32 @@
51
61
 
52
62
  <custom-element name="ui-hover-card-content">
53
63
  <script>
54
- defineProps({
64
+ const props = defineProps({
55
65
  placement: prop.enum(["bottom", "top", "left", "right"]).default("bottom"),
56
66
  });
57
67
 
68
+ const BLOCK_SIDES = new Set(["bottom", "top"]);
69
+
70
+ // Once open, it keeps the side it opened on. Re-deciding while the page scrolls makes it jump,
71
+ // because iOS Safari's toolbar changes the viewport height mid-scroll.
72
+ // Firefox holds a box that does not fit against the screen edge, so touching it counts too.
73
+ function opened(event) {
74
+ internals.states.delete("flipped");
75
+ if (event.newState !== "open" || !BLOCK_SIDES.has(props.placement)) return;
76
+ const box = host.getBoundingClientRect();
77
+ if (box.bottom >= innerHeight || box.top <= 0) internals.states.add("flipped");
78
+ }
79
+
58
80
  attrs.popover ??= "manual";
81
+
82
+ listen("toggle", opened);
59
83
  </script>
60
84
 
61
85
  <style>
86
+ :host,
87
+ * {
88
+ touch-action: manipulation;
89
+ }
62
90
  :host {
63
91
  box-sizing: border-box;
64
92
  width: calc(var(--spacing) * 64);
@@ -70,15 +98,27 @@
70
98
  color: var(--popover-foreground);
71
99
  box-shadow: var(--shadow-md);
72
100
  inset: auto;
101
+ height: fit-content;
102
+ max-height: calc(100svh - calc(var(--spacing) * 8));
103
+ overflow-y: auto;
73
104
  position-area: bottom;
74
105
  position-try-fallbacks: flip-block, flip-inline;
75
106
  }
107
+ :host(:popover-open) {
108
+ position-try-fallbacks: flip-inline;
109
+ }
76
110
  :host(:state(attr-width)) {
77
111
  width: calc(var(--spacing) * var(--attr-width));
78
112
  }
79
113
  :host(:state(attr-placement-is-top)) {
80
114
  position-area: top;
81
115
  }
116
+ :host(:state(flipped)) {
117
+ position-area: top;
118
+ }
119
+ :host(:state(flipped):state(attr-placement-is-top)) {
120
+ position-area: bottom;
121
+ }
82
122
  :host(:state(attr-placement-is-left)) {
83
123
  position-area: left;
84
124
  }
@@ -11,6 +11,12 @@
11
11
  </script>
12
12
 
13
13
  <style>
14
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
15
+ touch-action does not reach shadow content in iOS Safari. */
16
+ :host,
17
+ * {
18
+ touch-action: manipulation;
19
+ }
14
20
  :host {
15
21
  display: flex;
16
22
  align-items: center;
@@ -38,6 +44,12 @@
38
44
  font-size: var(--text-sm);
39
45
  outline: none;
40
46
  }
47
+ /* iOS Safari zooms in on a focused field whose text is under 16px. */
48
+ @media (pointer: coarse) {
49
+ input {
50
+ font-size: var(--text-base);
51
+ }
52
+ }
41
53
  input::placeholder {
42
54
  color: var(--muted-foreground);
43
55
  }
@@ -49,6 +61,10 @@
49
61
 
50
62
  <custom-element name="ui-input-group-addon">
51
63
  <style>
64
+ :host,
65
+ * {
66
+ touch-action: manipulation;
67
+ }
52
68
  :host {
53
69
  display: flex;
54
70
  order: -1;
@@ -77,6 +77,12 @@
77
77
  </script>
78
78
 
79
79
  <style>
80
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
81
+ touch-action does not reach shadow content in iOS Safari. */
82
+ :host,
83
+ * {
84
+ touch-action: manipulation;
85
+ }
80
86
  :host {
81
87
  display: inline-flex;
82
88
  }
@@ -97,6 +103,12 @@
97
103
  text-align: center;
98
104
  outline: none;
99
105
  }
106
+ /* iOS Safari zooms in on a focused field whose text is under 16px. */
107
+ @media (pointer: coarse) {
108
+ input {
109
+ font-size: var(--text-base);
110
+ }
111
+ }
100
112
  input:first-child,
101
113
  input[data-gap] {
102
114
  margin-left: 0;
@@ -23,6 +23,12 @@
23
23
  </script>
24
24
 
25
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
+ }
26
32
  :host {
27
33
  display: block;
28
34
  min-width: 0;
@@ -42,6 +48,12 @@
42
48
  outline: none;
43
49
  transition: color var(--default-transition-duration), box-shadow var(--default-transition-duration);
44
50
  }
51
+ /* iOS Safari zooms in on a focused field whose text is under 16px. */
52
+ @media (pointer: coarse) {
53
+ input {
54
+ font-size: var(--text-base);
55
+ }
56
+ }
45
57
  input::placeholder {
46
58
  color: var(--muted-foreground);
47
59
  }
@@ -11,6 +11,12 @@
11
11
  </script>
12
12
 
13
13
  <style>
14
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
15
+ touch-action does not reach shadow content in iOS Safari. */
16
+ :host,
17
+ * {
18
+ touch-action: manipulation;
19
+ }
14
20
  :host {
15
21
  display: flex;
16
22
  flex-wrap: wrap;
@@ -39,6 +45,10 @@
39
45
 
40
46
  <custom-element name="ui-item-group" role="list">
41
47
  <style>
48
+ :host,
49
+ * {
50
+ touch-action: manipulation;
51
+ }
42
52
  :host {
43
53
  display: flex;
44
54
  flex-direction: column;
@@ -50,6 +60,10 @@
50
60
 
51
61
  <custom-element name="ui-item-media">
52
62
  <style>
63
+ :host,
64
+ * {
65
+ touch-action: manipulation;
66
+ }
53
67
  :host {
54
68
  display: flex;
55
69
  flex-shrink: 0;
@@ -87,6 +101,10 @@
87
101
 
88
102
  <custom-element name="ui-item-content">
89
103
  <style>
104
+ :host,
105
+ * {
106
+ touch-action: manipulation;
107
+ }
90
108
  :host {
91
109
  display: flex;
92
110
  flex: 1;
@@ -101,6 +119,10 @@
101
119
 
102
120
  <custom-element name="ui-item-title">
103
121
  <style>
122
+ :host,
123
+ * {
124
+ touch-action: manipulation;
125
+ }
104
126
  :host {
105
127
  display: flex;
106
128
  align-items: center;
@@ -115,6 +137,10 @@
115
137
 
116
138
  <custom-element name="ui-item-description">
117
139
  <style>
140
+ :host,
141
+ * {
142
+ touch-action: manipulation;
143
+ }
118
144
  :host {
119
145
  display: -webkit-box;
120
146
  overflow: hidden;
@@ -131,6 +157,10 @@
131
157
 
132
158
  <custom-element name="ui-item-actions">
133
159
  <style>
160
+ :host,
161
+ * {
162
+ touch-action: manipulation;
163
+ }
134
164
  :host {
135
165
  display: flex;
136
166
  align-items: center;
@@ -143,6 +173,10 @@
143
173
 
144
174
  <custom-element name="ui-item-header">
145
175
  <style>
176
+ :host,
177
+ * {
178
+ touch-action: manipulation;
179
+ }
146
180
  :host {
147
181
  display: flex;
148
182
  flex-basis: 100%;
@@ -157,6 +191,10 @@
157
191
 
158
192
  <custom-element name="ui-item-footer">
159
193
  <style>
194
+ :host,
195
+ * {
196
+ touch-action: manipulation;
197
+ }
160
198
  :host {
161
199
  display: flex;
162
200
  flex-basis: 100%;
@@ -1,5 +1,11 @@
1
1
  <custom-element name="ui-kbd">
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: inline-flex;
5
11
  align-items: center;
@@ -24,6 +30,10 @@
24
30
 
25
31
  <custom-element name="ui-kbd-group">
26
32
  <style>
33
+ :host,
34
+ * {
35
+ touch-action: manipulation;
36
+ }
27
37
  :host {
28
38
  display: inline-flex;
29
39
  align-items: center;
@@ -22,6 +22,12 @@
22
22
  </script>
23
23
 
24
24
  <style>
25
+ /* A double tap must not zoom the page. Set inside the shadow root, because a page-level
26
+ touch-action does not reach shadow content in iOS Safari. */
27
+ :host,
28
+ * {
29
+ touch-action: manipulation;
30
+ }
25
31
  :host {
26
32
  display: inline-flex;
27
33
  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: flex;
9
15
  align-items: center;
@@ -1,5 +1,11 @@
1
1
  <custom-element name="ui-menubar" role="menubar">
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: flex;
5
11
  align-items: center;
@@ -42,6 +48,10 @@
42
48
  </script>
43
49
 
44
50
  <style>
51
+ :host,
52
+ * {
53
+ touch-action: manipulation;
54
+ }
45
55
  :host {
46
56
  display: contents;
47
57
  }
@@ -52,6 +62,10 @@
52
62
 
53
63
  <custom-element name="ui-menubar-trigger">
54
64
  <style>
65
+ :host,
66
+ * {
67
+ touch-action: manipulation;
68
+ }
55
69
  :host {
56
70
  display: inline-flex;
57
71
  }
@@ -80,8 +94,15 @@
80
94
  <script>
81
95
  const ITEMS = ":is(ui-menu-item, ui-menu-checkbox-item, ui-menu-radio-item):not([disabled])";
82
96
 
97
+ // Once open, it keeps the side it opened on. Re-deciding while the page scrolls makes it jump,
98
+ // because iOS Safari's toolbar changes the viewport height mid-scroll.
99
+ // Firefox holds a box that does not fit against the screen edge, so touching it counts too.
83
100
  function opened(event) {
84
- if (event.newState === "open") host.querySelector(ITEMS)?.focus();
101
+ if (event.newState !== "open") return;
102
+ internals.states.delete("flipped");
103
+ const box = host.getBoundingClientRect();
104
+ if (box.bottom >= innerHeight || box.top <= 0) internals.states.add("flipped");
105
+ host.querySelector(ITEMS)?.focus({ preventScroll: true });
85
106
  }
86
107
 
87
108
  function leave(event) {
@@ -96,6 +117,10 @@
96
117
  </script>
97
118
 
98
119
  <style>
120
+ :host,
121
+ * {
122
+ touch-action: manipulation;
123
+ }
99
124
  :host {
100
125
  box-sizing: border-box;
101
126
  min-width: calc(var(--spacing) * 48);
@@ -107,9 +132,19 @@
107
132
  color: var(--popover-foreground);
108
133
  box-shadow: var(--shadow-md);
109
134
  inset: auto;
135
+ height: fit-content;
136
+ max-height: calc(100svh - calc(var(--spacing) * 8));
137
+ overflow-y: auto;
110
138
  position-area: bottom span-right;
111
139
  position-try-fallbacks: flip-block, flip-inline;
112
140
  }
141
+ :host(:popover-open) {
142
+ position-try-fallbacks: flip-inline;
143
+ }
144
+ :host(:state(flipped)) {
145
+ position-area: top span-right;
146
+ margin: 0 0 calc(var(--spacing) * 2) calc(var(--spacing) * -1);
147
+ }
113
148
  </style>
114
149
 
115
150
  <div part="menu" focusgroup="menu block wrap"><slot></slot></div>