@k2b/ui 0.26.0 → 0.28.0

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 (231) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +147 -2
  3. package/dist/browser/actions/ContextMenu.js +30 -4
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/Dropdown.js +184 -158
  6. package/dist/browser/actions/Dropdown.js.map +1 -1
  7. package/dist/browser/actions/GestureMenu.js +71 -138
  8. package/dist/browser/actions/GestureMenu.js.map +1 -1
  9. package/dist/browser/actions/Toolbar.js +379 -48
  10. package/dist/browser/actions/Toolbar.js.map +1 -1
  11. package/dist/browser/actions/index.js.map +1 -1
  12. package/dist/browser/actions/menu-rows.js +15 -0
  13. package/dist/browser/actions/menu-rows.js.map +1 -0
  14. package/dist/browser/actions/menu-sheet.js +154 -0
  15. package/dist/browser/actions/menu-sheet.js.map +1 -0
  16. package/dist/browser/actions/toolbar-messages.js +20 -0
  17. package/dist/browser/actions/toolbar-messages.js.map +1 -0
  18. package/dist/browser/chart-inspection.js +3 -0
  19. package/dist/browser/chart-inspection.js.map +1 -0
  20. package/dist/browser/chat/ChatComposer.js +1020 -431
  21. package/dist/browser/chat/ChatComposer.js.map +1 -1
  22. package/dist/browser/chat/chat-behavior.js +4 -0
  23. package/dist/browser/chat/chat-behavior.js.map +1 -1
  24. package/dist/browser/chat/chat-messages.js +33 -1
  25. package/dist/browser/chat/chat-messages.js.map +1 -1
  26. package/dist/browser/chat/command-search.js +173 -0
  27. package/dist/browser/chat/command-search.js.map +1 -0
  28. package/dist/browser/chat/composer-document.js +1 -1
  29. package/dist/browser/chat/composer-document.js.map +1 -1
  30. package/dist/browser/chat/index.js +2 -0
  31. package/dist/browser/chat/index.js.map +1 -1
  32. package/dist/browser/chat/reaction-people.js +15 -0
  33. package/dist/browser/chat/reaction-people.js.map +1 -0
  34. package/dist/browser/content/CalendarDayView.js +28 -3
  35. package/dist/browser/content/CalendarDayView.js.map +1 -1
  36. package/dist/browser/content/Chart.js +6 -15
  37. package/dist/browser/content/Chart.js.map +1 -1
  38. package/dist/browser/content/ChartSnapshotView.js +7 -10
  39. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  40. package/dist/browser/content/MessageRow.js +330 -448
  41. package/dist/browser/content/MessageRow.js.map +1 -1
  42. package/dist/browser/content/ReactionBar.js +419 -0
  43. package/dist/browser/content/ReactionBar.js.map +1 -0
  44. package/dist/browser/content/chart-inspection-core.js +557 -0
  45. package/dist/browser/content/chart-inspection-core.js.map +1 -0
  46. package/dist/browser/content/chart-inspection.js +10 -445
  47. package/dist/browser/content/chart-inspection.js.map +1 -1
  48. package/dist/browser/content/chart-line-gaps.js +1 -1
  49. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  50. package/dist/browser/content/chart-snapshot.js +1 -1
  51. package/dist/browser/content/chart-snapshot.js.map +1 -1
  52. package/dist/browser/content/index.js +1 -0
  53. package/dist/browser/content/index.js.map +1 -1
  54. package/dist/browser/feedback/dialog-core.js +135 -23
  55. package/dist/browser/feedback/dialog-core.js.map +1 -1
  56. package/dist/browser/index.js +1 -0
  57. package/dist/browser/index.js.map +1 -1
  58. package/dist/browser/input-mode.js +40 -0
  59. package/dist/browser/input-mode.js.map +1 -0
  60. package/dist/browser/inputs/Combobox.js +4 -2
  61. package/dist/browser/inputs/Combobox.js.map +1 -1
  62. package/dist/browser/inputs/FileDropTarget.js +24 -9
  63. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  64. package/dist/browser/inputs/FileInputs.js +2 -2
  65. package/dist/browser/inputs/FileInputs.js.map +1 -1
  66. package/dist/browser/inputs/SelectChip.js +52 -12
  67. package/dist/browser/inputs/SelectChip.js.map +1 -1
  68. package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
  69. package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
  70. package/dist/browser/inputs/file-drop.js.map +1 -1
  71. package/dist/browser/layout/AppWorkspace.js +708 -515
  72. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  73. package/dist/browser/layout/BottomSheet.js +8 -0
  74. package/dist/browser/layout/BottomSheet.js.map +1 -1
  75. package/dist/browser/layout/DetailPanel.js +283 -197
  76. package/dist/browser/layout/DetailPanel.js.map +1 -1
  77. package/dist/browser/layout/Discussion.js +233 -185
  78. package/dist/browser/layout/Discussion.js.map +1 -1
  79. package/dist/browser/layout/TableOfContents.js +10 -2
  80. package/dist/browser/layout/TableOfContents.js.map +1 -1
  81. package/dist/browser/layout/app-workspace-controller.js +155 -23
  82. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  83. package/dist/browser/layout/app-workspace-state.js +5 -1
  84. package/dist/browser/layout/app-workspace-state.js.map +1 -1
  85. package/dist/browser/layout/detail-panel-messages.js +35 -0
  86. package/dist/browser/layout/detail-panel-messages.js.map +1 -0
  87. package/dist/browser/layout/index.js +1 -1
  88. package/dist/browser/layout/index.js.map +1 -1
  89. package/dist/browser/surfaces/Avatar.js +50 -20
  90. package/dist/browser/surfaces/Avatar.js.map +1 -1
  91. package/dist/browser/surfaces/AvatarStack.js +406 -0
  92. package/dist/browser/surfaces/AvatarStack.js.map +1 -0
  93. package/dist/browser/surfaces/avatar-messages.js +8 -2
  94. package/dist/browser/surfaces/avatar-messages.js.map +1 -1
  95. package/dist/browser/surfaces/index.js +1 -0
  96. package/dist/browser/surfaces/index.js.map +1 -1
  97. package/dist/ssr/actions/ContextMenu.js +21 -3
  98. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  99. package/dist/ssr/actions/Dropdown.js +140 -72
  100. package/dist/ssr/actions/Dropdown.js.map +1 -1
  101. package/dist/ssr/actions/GestureMenu.js +52 -106
  102. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  103. package/dist/ssr/actions/Toolbar.js +294 -14
  104. package/dist/ssr/actions/Toolbar.js.map +1 -1
  105. package/dist/ssr/actions/index.js.map +1 -1
  106. package/dist/ssr/actions/menu-rows.js +15 -0
  107. package/dist/ssr/actions/menu-rows.js.map +1 -0
  108. package/dist/ssr/actions/menu-sheet.js +138 -0
  109. package/dist/ssr/actions/menu-sheet.js.map +1 -0
  110. package/dist/ssr/actions/toolbar-messages.js +20 -0
  111. package/dist/ssr/actions/toolbar-messages.js.map +1 -0
  112. package/dist/ssr/chart-inspection.js +3 -0
  113. package/dist/ssr/chart-inspection.js.map +1 -0
  114. package/dist/ssr/chat/ChatComposer.js +604 -113
  115. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  116. package/dist/ssr/chat/chat-behavior.js +4 -0
  117. package/dist/ssr/chat/chat-behavior.js.map +1 -1
  118. package/dist/ssr/chat/chat-messages.js +33 -1
  119. package/dist/ssr/chat/chat-messages.js.map +1 -1
  120. package/dist/ssr/chat/command-search.js +173 -0
  121. package/dist/ssr/chat/command-search.js.map +1 -0
  122. package/dist/ssr/chat/composer-document.js +1 -1
  123. package/dist/ssr/chat/composer-document.js.map +1 -1
  124. package/dist/ssr/chat/index.js +2 -0
  125. package/dist/ssr/chat/index.js.map +1 -1
  126. package/dist/ssr/chat/reaction-people.js +15 -0
  127. package/dist/ssr/chat/reaction-people.js.map +1 -0
  128. package/dist/ssr/content/CalendarDayView.js +28 -3
  129. package/dist/ssr/content/CalendarDayView.js.map +1 -1
  130. package/dist/ssr/content/Chart.js +6 -15
  131. package/dist/ssr/content/Chart.js.map +1 -1
  132. package/dist/ssr/content/ChartSnapshotView.js +7 -10
  133. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  134. package/dist/ssr/content/MessageRow.js +98 -152
  135. package/dist/ssr/content/MessageRow.js.map +1 -1
  136. package/dist/ssr/content/ReactionBar.js +304 -0
  137. package/dist/ssr/content/ReactionBar.js.map +1 -0
  138. package/dist/ssr/content/chart-inspection-core.js +557 -0
  139. package/dist/ssr/content/chart-inspection-core.js.map +1 -0
  140. package/dist/ssr/content/chart-inspection.js +10 -445
  141. package/dist/ssr/content/chart-inspection.js.map +1 -1
  142. package/dist/ssr/content/chart-line-gaps.js +1 -1
  143. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  144. package/dist/ssr/content/chart-snapshot.js +1 -1
  145. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  146. package/dist/ssr/content/index.js +1 -0
  147. package/dist/ssr/content/index.js.map +1 -1
  148. package/dist/ssr/feedback/dialog-core.js +135 -23
  149. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  150. package/dist/ssr/index.js +1 -0
  151. package/dist/ssr/index.js.map +1 -1
  152. package/dist/ssr/input-mode.js +40 -0
  153. package/dist/ssr/input-mode.js.map +1 -0
  154. package/dist/ssr/inputs/Combobox.js +4 -2
  155. package/dist/ssr/inputs/Combobox.js.map +1 -1
  156. package/dist/ssr/inputs/FileDropTarget.js +17 -5
  157. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  158. package/dist/ssr/inputs/FileInputs.js +2 -2
  159. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  160. package/dist/ssr/inputs/SelectChip.js +44 -11
  161. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  162. package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
  163. package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
  164. package/dist/ssr/inputs/file-drop.js.map +1 -1
  165. package/dist/ssr/layout/AppWorkspace.js +242 -105
  166. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  167. package/dist/ssr/layout/BottomSheet.js +8 -0
  168. package/dist/ssr/layout/BottomSheet.js.map +1 -1
  169. package/dist/ssr/layout/DetailPanel.js +112 -58
  170. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  171. package/dist/ssr/layout/Discussion.js +63 -36
  172. package/dist/ssr/layout/Discussion.js.map +1 -1
  173. package/dist/ssr/layout/TableOfContents.js +10 -2
  174. package/dist/ssr/layout/TableOfContents.js.map +1 -1
  175. package/dist/ssr/layout/app-workspace-controller.js +155 -23
  176. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  177. package/dist/ssr/layout/app-workspace-state.js +5 -1
  178. package/dist/ssr/layout/app-workspace-state.js.map +1 -1
  179. package/dist/ssr/layout/detail-panel-messages.js +35 -0
  180. package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
  181. package/dist/ssr/layout/index.js +1 -1
  182. package/dist/ssr/layout/index.js.map +1 -1
  183. package/dist/ssr/surfaces/Avatar.js +20 -2
  184. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  185. package/dist/ssr/surfaces/AvatarStack.js +286 -0
  186. package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
  187. package/dist/ssr/surfaces/avatar-messages.js +8 -2
  188. package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
  189. package/dist/ssr/surfaces/index.js +1 -0
  190. package/dist/ssr/surfaces/index.js.map +1 -1
  191. package/dist/styles.css +1 -1
  192. package/dist/types/actions/ContextMenu.d.ts +8 -0
  193. package/dist/types/actions/Dropdown.d.ts +12 -5
  194. package/dist/types/actions/GestureMenu.d.ts +6 -4
  195. package/dist/types/actions/Toolbar.d.ts +20 -0
  196. package/dist/types/actions/index.d.ts +1 -1
  197. package/dist/types/actions/menu-rows.d.ts +5 -0
  198. package/dist/types/actions/menu-sheet.d.ts +22 -0
  199. package/dist/types/actions/toolbar-messages.d.ts +8 -0
  200. package/dist/types/chart-inspection.d.ts +2 -0
  201. package/dist/types/chat/ChatComposer.d.ts +51 -2
  202. package/dist/types/chat/chat-behavior.d.ts +4 -0
  203. package/dist/types/chat/chat-messages.d.ts +17 -2
  204. package/dist/types/chat/command-search.d.ts +41 -0
  205. package/dist/types/chat/index.d.ts +3 -1
  206. package/dist/types/chat/reaction-people.d.ts +9 -0
  207. package/dist/types/content/Chart.d.ts +2 -2
  208. package/dist/types/content/MessageRow.d.ts +3 -10
  209. package/dist/types/content/ReactionBar.d.ts +32 -0
  210. package/dist/types/content/chart-inspection-core.d.ts +61 -0
  211. package/dist/types/content/chart-inspection.d.ts +4 -20
  212. package/dist/types/content/chart-snapshot.d.ts +1 -1
  213. package/dist/types/content/index.d.ts +2 -1
  214. package/dist/types/feedback/dialog-core.d.ts +16 -1
  215. package/dist/types/index.d.ts +1 -0
  216. package/dist/types/input-mode.d.ts +7 -0
  217. package/dist/types/inputs/FileDropTarget.d.ts +6 -3
  218. package/dist/types/inputs/SelectChip.d.ts +6 -0
  219. package/dist/types/inputs/file-drop.d.ts +2 -0
  220. package/dist/types/layout/AppWorkspace.d.ts +13 -1
  221. package/dist/types/layout/BottomSheet.d.ts +8 -0
  222. package/dist/types/layout/DetailPanel.d.ts +11 -0
  223. package/dist/types/layout/Discussion.d.ts +8 -0
  224. package/dist/types/layout/TableOfContents.d.ts +2 -0
  225. package/dist/types/layout/detail-panel-messages.d.ts +15 -0
  226. package/dist/types/layout/index.d.ts +1 -1
  227. package/dist/types/surfaces/Avatar.d.ts +12 -0
  228. package/dist/types/surfaces/AvatarStack.d.ts +41 -0
  229. package/dist/types/surfaces/avatar-messages.d.ts +3 -0
  230. package/dist/types/surfaces/index.d.ts +3 -1
  231. package/package.json +9 -4
@@ -24,18 +24,21 @@ var _tmpl$ = /*#__PURE__*/_$template(`<span class=k2b-dropdown__copy><span></spa
24
24
  _tmpl$7 = /*#__PURE__*/_$template(`<i class="ti ti-check">`),
25
25
  _tmpl$8 = /*#__PURE__*/_$template(`<span class=k2b-dropdown__checkbox aria-hidden=true>`),
26
26
  _tmpl$9 = /*#__PURE__*/_$template(`<i class="ti ti-check k2b-dropdown__check"aria-hidden=true>`),
27
- _tmpl$0 = /*#__PURE__*/_$template(`<button type=button tabindex=-1><!$><!/><!$><!/><!$><!/><span class=k2b-dropdown__copy><span></span><!$><!/></span><!$><!/>`),
28
- _tmpl$1 = /*#__PURE__*/_$template(`<span class=k2b-dropdown__color aria-hidden=true>`),
29
- _tmpl$10 = /*#__PURE__*/_$template(`<div class=k2b-dropdown__row>`),
30
- _tmpl$11 = /*#__PURE__*/_$template(`<div class=k2b-dropdown__section role=group><!$><!/><!$><!/>`),
31
- _tmpl$12 = /*#__PURE__*/_$template(`<div class=k2b-dropdown__label>`),
32
- _tmpl$13 = /*#__PURE__*/_$template(`<button>`),
33
- _tmpl$14 = /*#__PURE__*/_$template(`<span><!$><!/><div popover=auto role=menu>`);
27
+ _tmpl$0 = /*#__PURE__*/_$template(`<span class=k2b-dropdown__color aria-hidden=true>`),
28
+ _tmpl$1 = /*#__PURE__*/_$template(`<div class=k2b-dropdown__row>`),
29
+ _tmpl$10 = /*#__PURE__*/_$template(`<div class=k2b-dropdown__section role=group><!$><!/><!$><!/>`),
30
+ _tmpl$11 = /*#__PURE__*/_$template(`<div class=k2b-dropdown__label>`),
31
+ _tmpl$12 = /*#__PURE__*/_$template(`<button>`),
32
+ _tmpl$13 = /*#__PURE__*/_$template(`<span><!$><!/><div popover=auto role=menu>`);
34
33
  import { createContext, createEffect, createSignal, createUniqueId, For, onCleanup, onMount, Show, splitProps, useContext } from "solid-js";
34
+ import { Dynamic } from "solid-js/web";
35
35
  import { Tooltip, useLabelTooltip } from "../feedback/Tooltip";
36
36
  import { returnFocus, ringOnReturn } from "../internal/focus-return";
37
+ import { useLocale } from "../intl/locale";
37
38
  import { useUiMessages } from "../intl/messages";
38
39
  import { Button, iconTitle } from "./Button";
40
+ import { focusRowSegment } from "./menu-rows";
41
+ import { openMenuSheet, prefersMenuSheet } from "./menu-sheet";
39
42
 
40
43
  // Resolved outside JSX: a conditional attribute compiles to a lazy memo, which would be created inside the click handler.
41
44
  const selectAction = item => item.action;
@@ -50,21 +53,6 @@ const focusMenuItem = (menu, index) => {
50
53
  if (items.length === 0) return;
51
54
  items[(index + items.length) % items.length]?.focus();
52
55
  };
53
-
54
- /**
55
- * Left and Right cycle through the segments of a row section; Up and Down leave it like any item. Returns whether
56
- * the key moved focus.
57
- */
58
- export const focusRowSegment = (items, key) => {
59
- if (key !== "ArrowLeft" && key !== "ArrowRight") return false;
60
- const active = document.activeElement;
61
- const row = active?.closest(".k2b-dropdown__row");
62
- if (!active || !row) return false;
63
- const segments = items.filter(item => row.contains(item));
64
- const next = segments.indexOf(active) + (key === "ArrowRight" ? 1 : -1);
65
- segments[(next + segments.length) % segments.length]?.focus();
66
- return true;
67
- };
68
56
  export const dropdownPosition = (trigger, menu, position, viewport, gap = 4) => {
69
57
  let left = trigger.left;
70
58
  let top = trigger.bottom + gap;
@@ -202,34 +190,66 @@ export function DropdownItem(props) {
202
190
  function DropdownChoiceItem(props) {
203
191
  const menu = useContext(MenuContext);
204
192
  const checked = () => typeof props.checked === "function" ? props.checked() : props.checked;
205
- return (// biome-ignore lint/a11y/useAriaPropsSupportedByRole: the runtime role is always menuitemcheckbox or menuitemradio, both of which support aria-checked.
206
- (() => {
207
- var _el$0 = _$getNextElement(_tmpl$0),
208
- _el$16 = _el$0.firstChild,
209
- [_el$17, _co$3] = _$getNextMarker(_el$16.nextSibling),
210
- _el$18 = _el$17.nextSibling,
211
- [_el$19, _co$4] = _$getNextMarker(_el$18.nextSibling),
212
- _el$20 = _el$19.nextSibling,
213
- [_el$21, _co$5] = _$getNextMarker(_el$20.nextSibling),
214
- _el$11 = _el$21.nextSibling,
215
- _el$12 = _el$11.firstChild,
216
- _el$13 = _el$12.nextSibling,
217
- [_el$14, _co$2] = _$getNextMarker(_el$13.nextSibling),
218
- _el$22 = _el$11.nextSibling,
219
- [_el$23, _co$6] = _$getNextMarker(_el$22.nextSibling);
220
- _el$0.$$click = event => {
221
- event.preventDefault();
222
- event.stopPropagation();
223
- if (props.closeOnSelect !== false) menu?.close();
224
- props.action();
225
- };
226
- _$insert(_el$0, _$createComponent(Show, {
193
+ let element;
194
+ return _$createComponent(Dynamic, {
195
+ ref: node => {
196
+ element = node;
197
+ },
198
+ get component() {
199
+ return !props.disabled && props.href ? "a" : "button";
200
+ },
201
+ get href() {
202
+ return _$memo(() => !!!props.disabled)() ? props.href : undefined;
203
+ },
204
+ get type() {
205
+ return !props.disabled && props.href ? undefined : "button";
206
+ },
207
+ get role() {
208
+ return props.choice === "checkbox" ? "menuitemcheckbox" : "menuitemradio";
209
+ },
210
+ get ["aria-label"]() {
211
+ return props.ariaLabel;
212
+ },
213
+ get ["aria-checked"]() {
214
+ return checked();
215
+ },
216
+ get ["aria-disabled"]() {
217
+ return props.disabled ? "true" : undefined;
218
+ },
219
+ tabIndex: -1,
220
+ get ["class"]() {
221
+ return `k2b-dropdown__item ${props.class ?? ""}`;
222
+ },
223
+ get ["data-selected"]() {
224
+ return checked() ? "true" : undefined;
225
+ },
226
+ get disabled() {
227
+ return props.disabled;
228
+ },
229
+ onClick: event => {
230
+ if (props.href && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) {
231
+ menu?.close(false);
232
+ return;
233
+ }
234
+ event.preventDefault();
235
+ event.stopPropagation();
236
+ if (props.closeOnSelect !== false) menu?.close();
237
+ props.action();
238
+ },
239
+ onKeyDown: event => {
240
+ // A link answers only Enter; as a menu choice it also answers Space, like the button form.
241
+ if (event.key !== " " || props.disabled || !props.href) return;
242
+ event.preventDefault();
243
+ element?.click();
244
+ },
245
+ get children() {
246
+ return [_$createComponent(Show, {
227
247
  get when() {
228
248
  return props.choice === "checkbox";
229
249
  },
230
250
  get children() {
231
- var _el$1 = _$getNextElement(_tmpl$8);
232
- _$insert(_el$1, _$createComponent(Show, {
251
+ var _el$0 = _$getNextElement(_tmpl$8);
252
+ _$insert(_el$0, _$createComponent(Show, {
233
253
  get when() {
234
254
  return checked();
235
255
  },
@@ -237,10 +257,9 @@ function DropdownChoiceItem(props) {
237
257
  return _$getNextElement(_tmpl$7);
238
258
  }
239
259
  }));
240
- return _el$1;
260
+ return _el$0;
241
261
  }
242
- }), _el$17, _co$3);
243
- _$insert(_el$0, _$createComponent(Show, {
262
+ }), _$createComponent(Show, {
244
263
  get when() {
245
264
  return props.image;
246
265
  },
@@ -250,78 +269,55 @@ function DropdownChoiceItem(props) {
250
269
  return props.icon;
251
270
  },
252
271
  children: icon => (() => {
253
- var _el$24 = _$getNextElement(_tmpl$2);
254
- _$effect(() => _$className(_el$24, icon()));
255
- return _el$24;
272
+ var _el$15 = _$getNextElement(_tmpl$2);
273
+ _$effect(() => _$className(_el$15, icon()));
274
+ return _el$15;
256
275
  })()
257
276
  });
258
277
  },
259
278
  children: image => (() => {
260
- var _el$25 = _$getNextElement(_tmpl$3);
261
- _$effect(() => _$setAttribute(_el$25, "src", image()));
262
- return _el$25;
279
+ var _el$16 = _$getNextElement(_tmpl$3);
280
+ _$effect(() => _$setAttribute(_el$16, "src", image()));
281
+ return _el$16;
263
282
  })()
264
- }), _el$19, _co$4);
265
- _$insert(_el$0, _$createComponent(Show, {
283
+ }), _$createComponent(Show, {
266
284
  get when() {
267
285
  return props.color;
268
286
  },
269
287
  children: color => (() => {
270
- var _el$26 = _$getNextElement(_tmpl$1);
271
- _$effect(_$p => _$setStyleProperty(_el$26, "--k2b-dropdown-color", color()));
272
- return _el$26;
288
+ var _el$17 = _$getNextElement(_tmpl$0);
289
+ _$effect(_$p => _$setStyleProperty(_el$17, "--k2b-dropdown-color", color()));
290
+ return _el$17;
273
291
  })()
274
- }), _el$21, _co$5);
275
- _$insert(_el$12, () => props.label);
276
- _$insert(_el$11, _$createComponent(Show, {
277
- get when() {
278
- return props.description;
279
- },
280
- children: description => (() => {
281
- var _el$27 = _$getNextElement(_tmpl$4);
282
- _$insert(_el$27, description);
283
- return _el$27;
284
- })()
285
- }), _el$14, _co$2);
286
- _$insert(_el$0, _$createComponent(Show, {
292
+ }), (() => {
293
+ var _el$10 = _$getNextElement(_tmpl$),
294
+ _el$11 = _el$10.firstChild,
295
+ _el$12 = _el$11.nextSibling,
296
+ [_el$13, _co$2] = _$getNextMarker(_el$12.nextSibling);
297
+ _$insert(_el$11, () => props.label);
298
+ _$insert(_el$10, _$createComponent(Show, {
299
+ get when() {
300
+ return props.description;
301
+ },
302
+ children: description => (() => {
303
+ var _el$18 = _$getNextElement(_tmpl$4);
304
+ _$insert(_el$18, description);
305
+ return _el$18;
306
+ })()
307
+ }), _el$13, _co$2);
308
+ return _el$10;
309
+ })(), _$createComponent(Show, {
287
310
  get when() {
288
311
  return props.choice === "radio";
289
312
  },
290
313
  get children() {
291
- var _el$15 = _$getNextElement(_tmpl$9);
292
- _$effect(() => _$setAttribute(_el$15, "data-hidden", checked() ? undefined : "true"));
293
- return _el$15;
314
+ var _el$14 = _$getNextElement(_tmpl$9);
315
+ _$effect(() => _$setAttribute(_el$14, "data-hidden", checked() ? undefined : "true"));
316
+ return _el$14;
294
317
  }
295
- }), _el$23, _co$6);
296
- _$effect(_p$ => {
297
- var _v$10 = props.choice === "checkbox" ? "menuitemcheckbox" : "menuitemradio",
298
- _v$11 = props.ariaLabel,
299
- _v$12 = checked(),
300
- _v$13 = props.disabled ? "true" : undefined,
301
- _v$14 = `k2b-dropdown__item ${props.class ?? ""}`,
302
- _v$15 = checked() ? "true" : undefined,
303
- _v$16 = props.disabled;
304
- _v$10 !== _p$.e && _$setAttribute(_el$0, "role", _p$.e = _v$10);
305
- _v$11 !== _p$.t && _$setAttribute(_el$0, "aria-label", _p$.t = _v$11);
306
- _v$12 !== _p$.a && _$setAttribute(_el$0, "aria-checked", _p$.a = _v$12);
307
- _v$13 !== _p$.o && _$setAttribute(_el$0, "aria-disabled", _p$.o = _v$13);
308
- _v$14 !== _p$.i && _$className(_el$0, _p$.i = _v$14);
309
- _v$15 !== _p$.n && _$setAttribute(_el$0, "data-selected", _p$.n = _v$15);
310
- _v$16 !== _p$.s && _$setProperty(_el$0, "disabled", _p$.s = _v$16);
311
- return _p$;
312
- }, {
313
- e: undefined,
314
- t: undefined,
315
- a: undefined,
316
- o: undefined,
317
- i: undefined,
318
- n: undefined,
319
- s: undefined
320
- });
321
- _$runHydrationEvents();
322
- return _el$0;
323
- })()
324
- );
318
+ })];
319
+ }
320
+ });
325
321
  }
326
322
  export function DropdownItems(props) {
327
323
  const messages = useUiMessages();
@@ -382,22 +378,22 @@ export function DropdownItems(props) {
382
378
  return renderItem(item);
383
379
  },
384
380
  get children() {
385
- var _el$28 = _$getNextElement(_tmpl$11),
386
- _el$30 = _el$28.firstChild,
387
- [_el$31, _co$7] = _$getNextMarker(_el$30.nextSibling),
388
- _el$32 = _el$31.nextSibling,
389
- [_el$33, _co$8] = _$getNextMarker(_el$32.nextSibling);
390
- _$insert(_el$28, _$createComponent(Show, {
381
+ var _el$19 = _$getNextElement(_tmpl$10),
382
+ _el$21 = _el$19.firstChild,
383
+ [_el$22, _co$3] = _$getNextMarker(_el$21.nextSibling),
384
+ _el$23 = _el$22.nextSibling,
385
+ [_el$24, _co$4] = _$getNextMarker(_el$23.nextSibling);
386
+ _$insert(_el$19, _$createComponent(Show, {
391
387
  get when() {
392
388
  return item.sectionLabel;
393
389
  },
394
390
  children: label => (() => {
395
- var _el$34 = _$getNextElement(_tmpl$12);
396
- _$insert(_el$34, label);
397
- return _el$34;
391
+ var _el$25 = _$getNextElement(_tmpl$11);
392
+ _$insert(_el$25, label);
393
+ return _el$25;
398
394
  })()
399
- }), _el$31, _co$7);
400
- _$insert(_el$28, _$createComponent(Show, {
395
+ }), _el$22, _co$3);
396
+ _$insert(_el$19, _$createComponent(Show, {
401
397
  get when() {
402
398
  return item.layout === "row";
403
399
  },
@@ -410,27 +406,27 @@ export function DropdownItems(props) {
410
406
  });
411
407
  },
412
408
  get children() {
413
- var _el$29 = _$getNextElement(_tmpl$10);
414
- _$insert(_el$29, _$createComponent(For, {
409
+ var _el$20 = _$getNextElement(_tmpl$1);
410
+ _$insert(_el$20, _$createComponent(For, {
415
411
  get each() {
416
412
  return item.items;
417
413
  },
418
414
  children: renderItem
419
415
  }));
420
- return _el$29;
416
+ return _el$20;
421
417
  }
422
- }), _el$33, _co$8);
418
+ }), _el$24, _co$4);
423
419
  _$effect(_p$ => {
424
- var _v$17 = index() > 0 ? "true" : undefined,
425
- _v$18 = item.sectionLabel ?? (item.layout === "row" ? undefined : messages().actions);
426
- _v$17 !== _p$.e && _$setAttribute(_el$28, "data-divided", _p$.e = _v$17);
427
- _v$18 !== _p$.t && _$setAttribute(_el$28, "aria-label", _p$.t = _v$18);
420
+ var _v$10 = index() > 0 ? "true" : undefined,
421
+ _v$11 = item.sectionLabel ?? (item.layout === "row" ? undefined : messages().actions);
422
+ _v$10 !== _p$.e && _$setAttribute(_el$19, "data-divided", _p$.e = _v$10);
423
+ _v$11 !== _p$.t && _$setAttribute(_el$19, "aria-label", _p$.t = _v$11);
428
424
  return _p$;
429
425
  }, {
430
426
  e: undefined,
431
427
  t: undefined
432
428
  });
433
- return _el$28;
429
+ return _el$19;
434
430
  }
435
431
  })
436
432
  });
@@ -507,9 +503,9 @@ function DropdownTrigger(props) {
507
503
  }));
508
504
  }
509
505
  return [(() => {
510
- var _el$35 = _$getNextElement(_tmpl$13);
511
- _$use(register, _el$35);
512
- _$spread(_el$35, _$mergeProps(rest, {
506
+ var _el$26 = _$getNextElement(_tmpl$12);
507
+ _$use(register, _el$26);
508
+ _$spread(_el$26, _$mergeProps(rest, {
513
509
  get ["aria-controls"]() {
514
510
  return context.menuId;
515
511
  },
@@ -540,9 +536,9 @@ function DropdownTrigger(props) {
540
536
  return iconTitle(local.title, tooltip());
541
537
  }
542
538
  }), false, true);
543
- _$insert(_el$35, () => local.children);
539
+ _$insert(_el$26, () => local.children);
544
540
  _$runHydrationEvents();
545
- return _el$35;
541
+ return _el$26;
546
542
  })(), _$createComponent(Show, {
547
543
  get when() {
548
544
  return _$memo(() => tooltip() !== false)() && tooltip() !== undefined;
@@ -570,6 +566,9 @@ function DropdownTrigger(props) {
570
566
  /** Accessible top-layer menu with explicit trigger ownership. */
571
567
  function DropdownRoot(props) {
572
568
  const messages = useUiMessages();
569
+ const locale = useLocale();
570
+ /** The open phone sheet's cancel switch: it closes when the menu goes or is disabled, as the popover does. */
571
+ let sheet;
573
572
  const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, "-");
574
573
  const menuId = `k2b-dropdown-${id}`;
575
574
  const [internalOpen, setInternalOpen] = createSignal(false);
@@ -617,6 +616,9 @@ function DropdownRoot(props) {
617
616
  // Before hiding, so the popover does not return focus on its own.
618
617
  if (restoreFocus) returnFocus(triggerRef, triggerRing);
619
618
  if (menuRef?.matches(":popover-open")) menuRef.hidePopover();
619
+ // Like `open`, expose the closed state now: the toggle event can arrive after the next key press, and a trigger
620
+ // that still reads as open would ignore Enter (Escape, then Enter at once, must reopen).
621
+ setInternalOpen(false);
620
622
  detachViewportListeners();
621
623
  };
622
624
  const open = (focus = "first") => {
@@ -637,6 +639,27 @@ function DropdownRoot(props) {
637
639
  props.onOpenChange?.(next);
638
640
  return;
639
641
  }
642
+ if (next && props.phone === "sheet" && prefersMenuSheet()) {
643
+ if (sheet) return;
644
+ const current = new AbortController();
645
+ sheet = current;
646
+ // The sheet is this menu's open state: the trigger reports it and the owner hears both ends.
647
+ setInternalOpen(true);
648
+ props.onOpenChange?.(true);
649
+ void openMenuSheet({
650
+ Items: DropdownItems,
651
+ items: props.items,
652
+ label: props.label ?? messages().dropdownMenu,
653
+ locale: locale(),
654
+ signal: current.signal
655
+ }).finally(() => {
656
+ sheet = undefined;
657
+ setInternalOpen(false);
658
+ props.onOpenChange?.(false);
659
+ props.onClose?.();
660
+ });
661
+ return;
662
+ }
640
663
  if (next) open(focus);else close(false);
641
664
  };
642
665
  const handleMenuKeyDown = event => {
@@ -686,57 +709,60 @@ function DropdownRoot(props) {
686
709
  if (!controlled && menuRef.matches(":popover-open")) close(false);
687
710
  });
688
711
  createEffect(() => {
689
- if (mounted && props.disabled) close(false);
712
+ if (!props.disabled) return;
713
+ sheet?.abort();
714
+ if (mounted) close(false);
690
715
  });
691
716
  onMount(() => {
692
717
  mounted = true;
693
718
  if (props.open) open(false);
694
719
  onCleanup(detachViewportListeners);
695
720
  });
721
+ onCleanup(() => sheet?.abort());
696
722
  return _$createComponent(DropdownContext.Provider, {
697
723
  value: context,
698
724
  get children() {
699
- var _el$36 = _$getNextElement(_tmpl$14),
700
- _el$38 = _el$36.firstChild,
701
- [_el$39, _co$9] = _$getNextMarker(_el$38.nextSibling),
702
- _el$37 = _el$39.nextSibling;
703
- _$insert(_el$36, () => props.children, _el$39, _co$9);
704
- _el$37.addEventListener("toggle", event => {
725
+ var _el$27 = _$getNextElement(_tmpl$13),
726
+ _el$29 = _el$27.firstChild,
727
+ [_el$30, _co$5] = _$getNextMarker(_el$29.nextSibling),
728
+ _el$28 = _el$30.nextSibling;
729
+ _$insert(_el$27, () => props.children, _el$30, _co$5);
730
+ _el$28.addEventListener("toggle", event => {
705
731
  const nextOpen = event.newState === "open";
706
- const wasOpen = internalOpen();
732
+ const wasOpen = event.oldState === "open";
707
733
  setInternalOpen(nextOpen);
708
734
  if (nextOpen) attachViewportListeners();else detachViewportListeners();
709
735
  if (props.open === undefined || props.open !== nextOpen) props.onOpenChange?.(nextOpen);
710
736
  if (wasOpen && !nextOpen) props.onClose?.();
711
737
  if (!nextOpen && props.open === true) queueMicrotask(() => props.open === true && open(false));
712
738
  });
713
- _el$37.$$keydown = handleMenuKeyDown;
739
+ _el$28.$$keydown = handleMenuKeyDown;
714
740
  var _ref$ = menuRef;
715
- typeof _ref$ === "function" ? _$use(_ref$, _el$37) : menuRef = _el$37;
716
- _$setAttribute(_el$37, "id", menuId);
717
- _$insert(_el$37, _$createComponent(DropdownItems, {
741
+ typeof _ref$ === "function" ? _$use(_ref$, _el$28) : menuRef = _el$28;
742
+ _$setAttribute(_el$28, "id", menuId);
743
+ _$insert(_el$28, _$createComponent(DropdownItems, {
718
744
  get items() {
719
745
  return props.items;
720
746
  },
721
747
  close: close
722
748
  }));
723
749
  _$effect(_p$ => {
724
- var _v$19 = `k2b-dropdown ${props.class ?? ""}`,
725
- _v$20 = props.label ?? messages().dropdownMenu,
726
- _v$21 = `k2b-dropdown__menu ${props.menuClass ?? ""}`,
727
- _v$22 = props.width ? {
750
+ var _v$12 = `k2b-dropdown ${props.class ?? ""}`,
751
+ _v$13 = props.label ?? messages().dropdownMenu,
752
+ _v$14 = `k2b-dropdown__menu ${props.menuClass ?? ""}`,
753
+ _v$15 = props.width ? {
728
754
  "--k2b-dropdown-width": props.width
729
755
  } : undefined,
730
- _v$23 = props.width ? "fixed" : undefined,
731
- _v$24 = props.variant ?? "default",
732
- _v$25 = position();
733
- _v$19 !== _p$.e && _$className(_el$36, _p$.e = _v$19);
734
- _v$20 !== _p$.t && _$setAttribute(_el$37, "aria-label", _p$.t = _v$20);
735
- _v$21 !== _p$.a && _$className(_el$37, _p$.a = _v$21);
736
- _p$.o = _$style(_el$37, _v$22, _p$.o);
737
- _v$23 !== _p$.i && _$setAttribute(_el$37, "data-width", _p$.i = _v$23);
738
- _v$24 !== _p$.n && _$setAttribute(_el$37, "data-variant", _p$.n = _v$24);
739
- _v$25 !== _p$.s && _$setAttribute(_el$37, "data-position", _p$.s = _v$25);
756
+ _v$16 = props.width ? "fixed" : undefined,
757
+ _v$17 = props.variant ?? "default",
758
+ _v$18 = position();
759
+ _v$12 !== _p$.e && _$className(_el$27, _p$.e = _v$12);
760
+ _v$13 !== _p$.t && _$setAttribute(_el$28, "aria-label", _p$.t = _v$13);
761
+ _v$14 !== _p$.a && _$className(_el$28, _p$.a = _v$14);
762
+ _p$.o = _$style(_el$28, _v$15, _p$.o);
763
+ _v$16 !== _p$.i && _$setAttribute(_el$28, "data-width", _p$.i = _v$16);
764
+ _v$17 !== _p$.n && _$setAttribute(_el$28, "data-variant", _p$.n = _v$17);
765
+ _v$18 !== _p$.s && _$setAttribute(_el$28, "data-position", _p$.s = _v$18);
740
766
  return _p$;
741
767
  }, {
742
768
  e: undefined,
@@ -748,7 +774,7 @@ function DropdownRoot(props) {
748
774
  s: undefined
749
775
  });
750
776
  _$runHydrationEvents();
751
- return _el$36;
777
+ return _el$27;
752
778
  }
753
779
  });
754
780
  }