@vielzeug/refine 1.5.4 → 1.7.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 (329) hide show
  1. package/dist/accordion.cjs +1 -1
  2. package/dist/accordion.cjs.map +1 -1
  3. package/dist/accordion.js +30 -28
  4. package/dist/accordion.js.map +1 -1
  5. package/dist/button-group.cjs.map +1 -1
  6. package/dist/button-group.js.map +1 -1
  7. package/dist/button.cjs +1 -1
  8. package/dist/button.cjs.map +1 -1
  9. package/dist/button.js +1 -0
  10. package/dist/button.js.map +1 -1
  11. package/dist/checkbox-group.cjs +3 -3
  12. package/dist/checkbox-group.cjs.map +1 -1
  13. package/dist/checkbox-group.js +51 -58
  14. package/dist/checkbox-group.js.map +1 -1
  15. package/dist/combobox.cjs +29 -28
  16. package/dist/combobox.cjs.map +1 -1
  17. package/dist/combobox.js +201 -195
  18. package/dist/combobox.js.map +1 -1
  19. package/dist/content/card/card.css.cjs +1 -1
  20. package/dist/content/card/card.css.cjs.map +1 -1
  21. package/dist/content/card/card.css.js +1 -1
  22. package/dist/content/card/card.css.js.map +1 -1
  23. package/dist/content/chat-message/chat-message.css.cjs +1 -1
  24. package/dist/content/chat-message/chat-message.css.cjs.map +1 -1
  25. package/dist/content/chat-message/chat-message.css.js +1 -1
  26. package/dist/content/chat-message/chat-message.css.js.map +1 -1
  27. package/dist/content/icon/icon.d.ts.map +1 -1
  28. package/dist/content/index.d.ts +4 -0
  29. package/dist/content/index.d.ts.map +1 -1
  30. package/dist/content/list/_list-item-reveal.cjs +2 -0
  31. package/dist/content/list/_list-item-reveal.cjs.map +1 -0
  32. package/dist/content/list/_list-item-reveal.d.ts +25 -0
  33. package/dist/content/list/_list-item-reveal.d.ts.map +1 -0
  34. package/dist/content/list/_list-item-reveal.js +33 -0
  35. package/dist/content/list/_list-item-reveal.js.map +1 -0
  36. package/dist/content/list/list-item.css.cjs +2 -0
  37. package/dist/content/list/list-item.css.cjs.map +1 -0
  38. package/dist/content/list/list-item.css.js +6 -0
  39. package/dist/content/list/list-item.css.js.map +1 -0
  40. package/dist/content/list/list-item.d.ts +111 -0
  41. package/dist/content/list/list-item.d.ts.map +1 -0
  42. package/dist/content/list/list.css.cjs +2 -0
  43. package/dist/content/list/list.css.cjs.map +1 -0
  44. package/dist/content/list/list.css.js +6 -0
  45. package/dist/content/list/list.css.js.map +1 -0
  46. package/dist/content/list/list.d.ts +93 -0
  47. package/dist/content/list/list.d.ts.map +1 -0
  48. package/dist/custom-elements.json +6052 -5449
  49. package/dist/date-picker.cjs +2 -1
  50. package/dist/date-picker.cjs.map +1 -1
  51. package/dist/date-picker.js +2 -0
  52. package/dist/date-picker.js.map +1 -1
  53. package/dist/disclosure/tab-item/tab-item.d.ts.map +1 -1
  54. package/dist/disclosure/tab-panel/tab-panel.d.ts.map +1 -1
  55. package/dist/disclosure/tabs/tabs.d.ts.map +1 -1
  56. package/dist/drawer.cjs +1 -1
  57. package/dist/drawer.cjs.map +1 -1
  58. package/dist/drawer.js +47 -48
  59. package/dist/drawer.js.map +1 -1
  60. package/dist/file-input.cjs +111 -45
  61. package/dist/file-input.cjs.map +1 -1
  62. package/dist/file-input.js +216 -156
  63. package/dist/file-input.js.map +1 -1
  64. package/dist/headless/aria-reflection.cjs +2 -0
  65. package/dist/headless/aria-reflection.cjs.map +1 -0
  66. package/dist/headless/aria-reflection.d.ts +27 -0
  67. package/dist/headless/aria-reflection.d.ts.map +1 -0
  68. package/dist/headless/aria-reflection.js +18 -0
  69. package/dist/headless/aria-reflection.js.map +1 -0
  70. package/dist/headless/checkable.cjs +1 -1
  71. package/dist/headless/checkable.cjs.map +1 -1
  72. package/dist/headless/checkable.d.ts +2 -10
  73. package/dist/headless/checkable.d.ts.map +1 -1
  74. package/dist/headless/checkable.js +29 -29
  75. package/dist/headless/checkable.js.map +1 -1
  76. package/dist/headless/choice-field.cjs +1 -1
  77. package/dist/headless/choice-field.cjs.map +1 -1
  78. package/dist/headless/choice-field.d.ts +2 -7
  79. package/dist/headless/choice-field.d.ts.map +1 -1
  80. package/dist/headless/choice-field.js +37 -37
  81. package/dist/headless/choice-field.js.map +1 -1
  82. package/dist/headless/field-base.cjs +1 -1
  83. package/dist/headless/field-base.cjs.map +1 -1
  84. package/dist/headless/field-base.d.ts +17 -0
  85. package/dist/headless/field-base.d.ts.map +1 -1
  86. package/dist/headless/field-base.js +21 -6
  87. package/dist/headless/field-base.js.map +1 -1
  88. package/dist/headless/focus.cjs +1 -1
  89. package/dist/headless/focus.cjs.map +1 -1
  90. package/dist/headless/focus.d.ts +7 -0
  91. package/dist/headless/focus.d.ts.map +1 -1
  92. package/dist/headless/focus.js +6 -6
  93. package/dist/headless/focus.js.map +1 -1
  94. package/dist/headless/index.d.ts +4 -2
  95. package/dist/headless/index.d.ts.map +1 -1
  96. package/dist/headless/nav.cjs +1 -1
  97. package/dist/headless/nav.cjs.map +1 -1
  98. package/dist/headless/nav.d.ts +12 -0
  99. package/dist/headless/nav.d.ts.map +1 -1
  100. package/dist/headless/nav.js +68 -50
  101. package/dist/headless/nav.js.map +1 -1
  102. package/dist/headless/overlay.cjs +1 -1
  103. package/dist/headless/overlay.cjs.map +1 -1
  104. package/dist/headless/overlay.d.ts +2 -0
  105. package/dist/headless/overlay.d.ts.map +1 -1
  106. package/dist/headless/overlay.js +8 -5
  107. package/dist/headless/overlay.js.map +1 -1
  108. package/dist/headless/ref-callback.cjs +2 -0
  109. package/dist/headless/ref-callback.cjs.map +1 -0
  110. package/dist/headless/ref-callback.d.ts +26 -0
  111. package/dist/headless/ref-callback.d.ts.map +1 -0
  112. package/dist/headless/ref-callback.js +13 -0
  113. package/dist/headless/ref-callback.js.map +1 -0
  114. package/dist/headless/swipe.cjs +1 -1
  115. package/dist/headless/swipe.cjs.map +1 -1
  116. package/dist/headless/swipe.d.ts +2 -0
  117. package/dist/headless/swipe.d.ts.map +1 -1
  118. package/dist/headless/swipe.js +26 -21
  119. package/dist/headless/swipe.js.map +1 -1
  120. package/dist/headless.cjs +1 -1
  121. package/dist/headless.js +28 -26
  122. package/dist/icon.cjs +1 -1
  123. package/dist/icon.cjs.map +1 -1
  124. package/dist/icon.js +36 -38
  125. package/dist/icon.js.map +1 -1
  126. package/dist/index.cjs +1 -1
  127. package/dist/index.js +63 -61
  128. package/dist/input.cjs +29 -26
  129. package/dist/input.cjs.map +1 -1
  130. package/dist/input.js +91 -79
  131. package/dist/input.js.map +1 -1
  132. package/dist/inputs/button/button.css.cjs +1 -1
  133. package/dist/inputs/button/button.css.cjs.map +1 -1
  134. package/dist/inputs/button/button.css.js +1 -1
  135. package/dist/inputs/button/button.css.js.map +1 -1
  136. package/dist/inputs/button/button.d.ts +8 -0
  137. package/dist/inputs/button/button.d.ts.map +1 -1
  138. package/dist/inputs/checkbox/checkbox.css.cjs +1 -1
  139. package/dist/inputs/checkbox/checkbox.css.cjs.map +1 -1
  140. package/dist/inputs/checkbox/checkbox.css.js +1 -1
  141. package/dist/inputs/checkbox/checkbox.css.js.map +1 -1
  142. package/dist/inputs/combobox/combobox.d.ts +1 -0
  143. package/dist/inputs/combobox/combobox.d.ts.map +1 -1
  144. package/dist/inputs/date-picker/date-picker.css.cjs +1 -1
  145. package/dist/inputs/date-picker/date-picker.css.cjs.map +1 -1
  146. package/dist/inputs/date-picker/date-picker.css.js +1 -1
  147. package/dist/inputs/date-picker/date-picker.css.js.map +1 -1
  148. package/dist/inputs/date-picker/date-picker.d.ts +6 -0
  149. package/dist/inputs/date-picker/date-picker.d.ts.map +1 -1
  150. package/dist/inputs/file-input/file-input-upload.cjs +2 -0
  151. package/dist/inputs/file-input/file-input-upload.cjs.map +1 -0
  152. package/dist/inputs/file-input/file-input-upload.d.ts +76 -0
  153. package/dist/inputs/file-input/file-input-upload.d.ts.map +1 -0
  154. package/dist/inputs/file-input/file-input-upload.js +145 -0
  155. package/dist/inputs/file-input/file-input-upload.js.map +1 -0
  156. package/dist/inputs/file-input/file-input.css.cjs +1 -1
  157. package/dist/inputs/file-input/file-input.css.cjs.map +1 -1
  158. package/dist/inputs/file-input/file-input.css.js +1 -1
  159. package/dist/inputs/file-input/file-input.css.js.map +1 -1
  160. package/dist/inputs/file-input/file-input.d.ts +54 -1
  161. package/dist/inputs/file-input/file-input.d.ts.map +1 -1
  162. package/dist/inputs/input/input.css.cjs +1 -1
  163. package/dist/inputs/input/input.css.cjs.map +1 -1
  164. package/dist/inputs/input/input.css.js +1 -1
  165. package/dist/inputs/input/input.css.js.map +1 -1
  166. package/dist/inputs/input/input.d.ts +13 -0
  167. package/dist/inputs/input/input.d.ts.map +1 -1
  168. package/dist/inputs/message-composer/message-composer.css.cjs +1 -1
  169. package/dist/inputs/message-composer/message-composer.css.cjs.map +1 -1
  170. package/dist/inputs/message-composer/message-composer.css.js +1 -1
  171. package/dist/inputs/message-composer/message-composer.css.js.map +1 -1
  172. package/dist/inputs/message-composer/message-composer.d.ts +7 -0
  173. package/dist/inputs/message-composer/message-composer.d.ts.map +1 -1
  174. package/dist/inputs/number-input/number-input.css.cjs +1 -1
  175. package/dist/inputs/number-input/number-input.css.cjs.map +1 -1
  176. package/dist/inputs/number-input/number-input.css.js +1 -1
  177. package/dist/inputs/number-input/number-input.css.js.map +1 -1
  178. package/dist/inputs/number-input/number-input.d.ts +15 -0
  179. package/dist/inputs/number-input/number-input.d.ts.map +1 -1
  180. package/dist/inputs/otp-input/otp-input.css.cjs +1 -1
  181. package/dist/inputs/otp-input/otp-input.css.cjs.map +1 -1
  182. package/dist/inputs/otp-input/otp-input.css.js +1 -1
  183. package/dist/inputs/otp-input/otp-input.css.js.map +1 -1
  184. package/dist/inputs/radio/radio.d.ts.map +1 -1
  185. package/dist/inputs/select/select.d.ts +1 -0
  186. package/dist/inputs/select/select.d.ts.map +1 -1
  187. package/dist/inputs/shared/index.d.ts +1 -1
  188. package/dist/inputs/shared/index.d.ts.map +1 -1
  189. package/dist/inputs/shared/templates.cjs +26 -3
  190. package/dist/inputs/shared/templates.cjs.map +1 -1
  191. package/dist/inputs/shared/templates.d.ts +20 -0
  192. package/dist/inputs/shared/templates.d.ts.map +1 -1
  193. package/dist/inputs/shared/templates.js +29 -5
  194. package/dist/inputs/shared/templates.js.map +1 -1
  195. package/dist/inputs/switch/switch.css.cjs +1 -1
  196. package/dist/inputs/switch/switch.css.cjs.map +1 -1
  197. package/dist/inputs/switch/switch.css.js +1 -1
  198. package/dist/inputs/switch/switch.css.js.map +1 -1
  199. package/dist/inputs/switch/switch.d.ts.map +1 -1
  200. package/dist/inputs/textarea/textarea.css.cjs +1 -1
  201. package/dist/inputs/textarea/textarea.css.cjs.map +1 -1
  202. package/dist/inputs/textarea/textarea.css.js +1 -1
  203. package/dist/inputs/textarea/textarea.css.js.map +1 -1
  204. package/dist/inputs/textarea/textarea.d.ts +14 -0
  205. package/dist/inputs/textarea/textarea.d.ts.map +1 -1
  206. package/dist/inputs/time-picker/time-picker.css.cjs +1 -1
  207. package/dist/inputs/time-picker/time-picker.css.cjs.map +1 -1
  208. package/dist/inputs/time-picker/time-picker.css.js +1 -1
  209. package/dist/inputs/time-picker/time-picker.css.js.map +1 -1
  210. package/dist/inputs/time-picker/time-picker.d.ts +6 -0
  211. package/dist/inputs/time-picker/time-picker.d.ts.map +1 -1
  212. package/dist/list-item.cjs +22 -0
  213. package/dist/list-item.cjs.map +1 -0
  214. package/dist/list-item.js +91 -0
  215. package/dist/list-item.js.map +1 -0
  216. package/dist/list.cjs +2 -0
  217. package/dist/list.cjs.map +1 -0
  218. package/dist/list.js +64 -0
  219. package/dist/list.js.map +1 -0
  220. package/dist/menu.cjs +4 -4
  221. package/dist/menu.cjs.map +1 -1
  222. package/dist/menu.js +60 -59
  223. package/dist/menu.js.map +1 -1
  224. package/dist/message-composer.cjs +14 -20
  225. package/dist/message-composer.cjs.map +1 -1
  226. package/dist/message-composer.js +63 -64
  227. package/dist/message-composer.js.map +1 -1
  228. package/dist/number-input.cjs +5 -3
  229. package/dist/number-input.cjs.map +1 -1
  230. package/dist/number-input.js +8 -4
  231. package/dist/number-input.js.map +1 -1
  232. package/dist/otp-input.cjs +9 -9
  233. package/dist/otp-input.cjs.map +1 -1
  234. package/dist/otp-input.js +70 -62
  235. package/dist/otp-input.js.map +1 -1
  236. package/dist/overlay/menu/menu-item.css.cjs +1 -1
  237. package/dist/overlay/menu/menu-item.css.cjs.map +1 -1
  238. package/dist/overlay/menu/menu-item.css.js +1 -1
  239. package/dist/overlay/menu/menu-item.css.js.map +1 -1
  240. package/dist/overlay/menu/menu-separator.css.cjs +1 -1
  241. package/dist/overlay/menu/menu-separator.css.cjs.map +1 -1
  242. package/dist/overlay/menu/menu-separator.css.js +1 -1
  243. package/dist/overlay/menu/menu-separator.css.js.map +1 -1
  244. package/dist/overlay/menu/menu.css.cjs +1 -1
  245. package/dist/overlay/menu/menu.css.cjs.map +1 -1
  246. package/dist/overlay/menu/menu.css.js +1 -1
  247. package/dist/overlay/menu/menu.css.js.map +1 -1
  248. package/dist/overlay/shared/use-dialog.cjs +1 -1
  249. package/dist/overlay/shared/use-dialog.cjs.map +1 -1
  250. package/dist/overlay/shared/use-dialog.d.ts.map +1 -1
  251. package/dist/overlay/shared/use-dialog.js +7 -6
  252. package/dist/overlay/shared/use-dialog.js.map +1 -1
  253. package/dist/radio-group.cjs +3 -3
  254. package/dist/radio-group.cjs.map +1 -1
  255. package/dist/radio-group.js +64 -70
  256. package/dist/radio-group.js.map +1 -1
  257. package/dist/radio.cjs +4 -4
  258. package/dist/radio.cjs.map +1 -1
  259. package/dist/radio.js +58 -58
  260. package/dist/radio.js.map +1 -1
  261. package/dist/rating.cjs.map +1 -1
  262. package/dist/rating.js.map +1 -1
  263. package/dist/refine.cjs +426 -233
  264. package/dist/refine.cjs.map +1 -1
  265. package/dist/refine.iife.js +431 -238
  266. package/dist/refine.iife.js.map +1 -1
  267. package/dist/refine.js +452 -259
  268. package/dist/refine.js.map +1 -1
  269. package/dist/select.cjs +21 -21
  270. package/dist/select.cjs.map +1 -1
  271. package/dist/select.js +135 -127
  272. package/dist/select.js.map +1 -1
  273. package/dist/shared/size-presets.cjs +1 -1
  274. package/dist/shared/size-presets.cjs.map +1 -1
  275. package/dist/shared/size-presets.d.ts +74 -0
  276. package/dist/shared/size-presets.d.ts.map +1 -1
  277. package/dist/shared/size-presets.js +48 -1
  278. package/dist/shared/size-presets.js.map +1 -1
  279. package/dist/shared/types.d.ts +5 -0
  280. package/dist/shared/types.d.ts.map +1 -1
  281. package/dist/styles/index.cjs +1 -1
  282. package/dist/styles/index.cjs.map +1 -1
  283. package/dist/styles/index.d.ts +1 -0
  284. package/dist/styles/index.d.ts.map +1 -1
  285. package/dist/styles/index.js +5 -4
  286. package/dist/styles/index.js.map +1 -1
  287. package/dist/styles/mixins/field-variants.css.cjs +85 -0
  288. package/dist/styles/mixins/field-variants.css.cjs.map +1 -0
  289. package/dist/styles/mixins/field-variants.css.d.ts +66 -0
  290. package/dist/styles/mixins/field-variants.css.d.ts.map +1 -0
  291. package/dist/styles/mixins/field-variants.css.js +90 -0
  292. package/dist/styles/mixins/field-variants.css.js.map +1 -0
  293. package/dist/switch.cjs +3 -3
  294. package/dist/switch.cjs.map +1 -1
  295. package/dist/switch.js +38 -36
  296. package/dist/switch.js.map +1 -1
  297. package/dist/tab-item.cjs +8 -8
  298. package/dist/tab-item.cjs.map +1 -1
  299. package/dist/tab-item.js +38 -28
  300. package/dist/tab-item.js.map +1 -1
  301. package/dist/tab-panel.cjs +7 -7
  302. package/dist/tab-panel.cjs.map +1 -1
  303. package/dist/tab-panel.js +34 -26
  304. package/dist/tab-panel.js.map +1 -1
  305. package/dist/tabs.cjs +4 -4
  306. package/dist/tabs.cjs.map +1 -1
  307. package/dist/tabs.js +64 -60
  308. package/dist/tabs.js.map +1 -1
  309. package/dist/textarea.cjs +15 -18
  310. package/dist/textarea.cjs.map +1 -1
  311. package/dist/textarea.js +83 -74
  312. package/dist/textarea.js.map +1 -1
  313. package/dist/time-picker.cjs +34 -31
  314. package/dist/time-picker.cjs.map +1 -1
  315. package/dist/time-picker.js +121 -109
  316. package/dist/time-picker.js.map +1 -1
  317. package/package.json +21 -9
  318. package/dist/headless/dialog-focus.cjs +0 -2
  319. package/dist/headless/dialog-focus.cjs.map +0 -1
  320. package/dist/headless/dialog-focus.d.ts +0 -40
  321. package/dist/headless/dialog-focus.d.ts.map +0 -1
  322. package/dist/headless/dialog-focus.js +0 -22
  323. package/dist/headless/dialog-focus.js.map +0 -1
  324. package/dist/headless/focus-trap.cjs +0 -2
  325. package/dist/headless/focus-trap.cjs.map +0 -1
  326. package/dist/headless/focus-trap.d.ts +0 -45
  327. package/dist/headless/focus-trap.d.ts.map +0 -1
  328. package/dist/headless/focus-trap.js +0 -51
  329. package/dist/headless/focus-trap.js.map +0 -1
package/dist/drawer.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { coarsePointerMixin as e, reducedMotionMixin as t } from "./styles/mixins/accessibility.css.js";
2
- import { elevationMixin as n, forcedColorsMixin as r } from "./styles/mixins/theme.css.js";
3
- import { createSwipeControl as i } from "./headless/swipe.js";
4
- import { useDialogControl as a } from "./overlay/shared/use-dialog.js";
5
- import o from "./overlay/drawer/drawer.css.js";
6
- import { createStableId as s, define as c, getHost as l, html as u, onCleanup as d, onEvent as f, onMounted as p, prop as m, ref as h, useEmit as g, useSlots as _ } from "@vielzeug/ore";
7
- import { signal as v } from "@vielzeug/ripple";
2
+ import { forcedColorsMixin as n } from "./styles/mixins/theme.css.js";
3
+ import { createSwipeControl as r } from "./headless/swipe.js";
4
+ import { useDialogControl as i } from "./overlay/shared/use-dialog.js";
5
+ import a from "./overlay/drawer/drawer.css.js";
6
+ import { createStableId as o, define as s, getHost as c, html as l, onCleanup as u, onEvent as d, onMounted as f, prop as p, ref as m, useEmit as h, useSlots as g } from "@vielzeug/ore";
7
+ import { signal as _ } from "@vielzeug/ripple";
8
8
  //#region src/overlay/drawer/drawer.ts
9
- var y = {
9
+ var v = {
10
10
  bottom: {
11
11
  axis: "y",
12
12
  closingDistance: (e) => Math.max(0, e),
@@ -27,34 +27,34 @@ var y = {
27
27
  closingDistance: (e) => Math.max(0, -e),
28
28
  translate: (e) => `translateY(${e}px)`
29
29
  }
30
- }, b = "ore-drawer";
31
- c(b, {
30
+ }, y = "ore-drawer";
31
+ s(y, {
32
32
  props: {
33
- backdrop: m.string(),
34
- dismissible: m.bool(!0),
35
- "drag-handle-placement": m.oneOf(["outside", "inset"], "outside"),
36
- "initial-focus": m.string(),
37
- label: m.string(),
38
- open: m.bool(!1),
39
- persistent: m.bool(!1),
40
- placement: m.oneOf([
33
+ backdrop: p.string(),
34
+ dismissible: p.bool(!0),
35
+ "drag-handle-placement": p.oneOf(["outside", "inset"], "outside"),
36
+ "initial-focus": p.string(),
37
+ label: p.string(),
38
+ open: p.bool(!1),
39
+ persistent: p.bool(!1),
40
+ placement: p.oneOf([
41
41
  "left",
42
42
  "right",
43
43
  "top",
44
44
  "bottom"
45
45
  ], "right"),
46
- "return-focus": m.bool(!0),
47
- size: m.string(),
48
- title: m.string()
46
+ "return-focus": p.bool(!0),
47
+ size: p.string(),
48
+ title: p.string()
49
49
  },
50
50
  setup(e) {
51
- let t = l(), n = g(), r = _(), o = s("drawer-label"), c = h(), m = h(), b = v(!1), x, S = () => e.label.value ?? e.title.value ?? "", C = () => r.has("header").value || !!S(), w = () => C() || e.dismissible.value, T = () => r.has("footer").value, E = () => e.placement.value || "right", D = () => y[E()], O = (e, t) => {
51
+ let t = c(), n = h(), a = g(), s = o("drawer-label"), p = m(), y = m(), b = _(!1), x, S = () => e.label.value ?? e.title.value ?? "", C = () => a.has("header").value || !!S(), w = () => C() || e.dismissible.value, T = () => a.has("footer").value, E = () => e.placement.value || "right", D = () => v[E()], O = (e, t) => {
52
52
  let n = t === "x" ? e.offsetWidth : e.offsetHeight;
53
53
  return Math.min(96, Math.max(36, n * .18));
54
54
  }, k = (e, t) => D().closingDistance(e) >= t, A = (e) => {
55
55
  if (!b.value) return;
56
56
  x &&= (clearTimeout(x), void 0);
57
- let t = c.value;
57
+ let t = p.value;
58
58
  if (!t) {
59
59
  b.value = !1;
60
60
  return;
@@ -76,7 +76,7 @@ c(b, {
76
76
  }, M = (e) => {
77
77
  x &&= (clearTimeout(x), void 0), e.style.transition = "", e.style.transform = "", e.style.opacity = "", e.style.visibility = "", b.value = !1;
78
78
  }, N = ({ distance: e, threshold: t }) => {
79
- let n = m.value;
79
+ let n = y.value;
80
80
  if (n) {
81
81
  if (k(e, t)) {
82
82
  j(n, D(), e);
@@ -84,16 +84,16 @@ c(b, {
84
84
  }
85
85
  M(n);
86
86
  }
87
- }, P = i({
87
+ }, P = r({
88
88
  axis: () => D().axis,
89
89
  disabled: b,
90
90
  onCancel: N,
91
91
  onCommit: ({ distance: e }) => {
92
- let t = m.value;
92
+ let t = y.value;
93
93
  t && j(t, D(), e);
94
94
  },
95
95
  onMove: ({ distance: e, threshold: t }) => {
96
- let n = m.value;
96
+ let n = y.value;
97
97
  if (!n) return;
98
98
  let r = D(), i = r.closingDistance(e), a = Math.min(i / t, 1);
99
99
  n.style.transition = "none", n.style.transform = r.translate(e), n.style.opacity = String(1 - a * .4);
@@ -101,26 +101,26 @@ c(b, {
101
101
  onRelease: N,
102
102
  shouldCommit: ({ distance: e, threshold: t }) => k(e, t),
103
103
  threshold: () => {
104
- let e = m.value;
104
+ let e = y.value;
105
105
  return e ? O(e, D().axis) : 48;
106
106
  }
107
- }), { closeWithAnimation: F, handleCancel: I, overlay: L, requestClose: R, watchOpenProp: z } = a({
107
+ }), { closeWithAnimation: F, handleCancel: I, overlay: L, requestClose: R, watchOpenProp: z } = i({
108
108
  beforeOpen: (e) => {
109
- let t = m.value;
109
+ let t = y.value;
110
110
  t && M(t);
111
111
  },
112
112
  closeRequestDetail: (t) => ({ placement: e.placement.value ?? "right" }),
113
- dialogRef: c,
114
- getPanelEl: () => m.value,
113
+ dialogRef: p,
114
+ getPanelEl: () => y.value,
115
115
  host: t,
116
116
  initialFocus: e["initial-focus"],
117
117
  isPersistent: () => !!e.persistent.value,
118
- onCleanup: d,
119
- onEvent: f,
118
+ onCleanup: u,
119
+ onEvent: d,
120
120
  onNativeClose: (t) => {
121
- let r = m.value;
121
+ let r = y.value;
122
122
  r && t !== "swipe" && M(r);
123
- let i = c.value;
123
+ let i = p.value;
124
124
  i && (i.style.transition = ""), n("close", {
125
125
  placement: e.placement.value ?? "right",
126
126
  reason: t
@@ -136,31 +136,31 @@ c(b, {
136
136
  },
137
137
  returnFocus: e["return-focus"]
138
138
  });
139
- return p(() => {
140
- let n = c.value;
139
+ return f(() => {
140
+ let n = p.value;
141
141
  if (!n) return;
142
142
  let r = t;
143
143
  r.show = () => {
144
144
  L.open("programmatic");
145
145
  }, r.hide = () => {
146
146
  L.close("programmatic", !1);
147
- }, z(), f(n, "cancel", I), f(n, "click", (t) => {
147
+ }, z(), d(n, "cancel", I), d(n, "click", (t) => {
148
148
  e.persistent.value || P.isActive() || b.value || t.target === n && R("outsideClick");
149
149
  });
150
- let i = m.value?.querySelector("[part=\"drag-handle\"]");
151
- return i && (f(i, "pointerdown", P.handlePointerDown), f(i, "pointermove", P.handlePointerMove), f(i, "pointerup", P.handlePointerUp), f(i, "pointercancel", P.handlePointerCancel)), () => {
150
+ let i = y.value?.querySelector("[part=\"drag-handle\"]");
151
+ return i && (d(i, "pointerdown", P.handlePointerDown), d(i, "pointermove", P.handlePointerMove), d(i, "pointerup", P.handlePointerUp), d(i, "pointercancel", P.handlePointerCancel)), () => {
152
152
  L.dispose();
153
153
  };
154
- }), u`
154
+ }), l`
155
155
  <dialog
156
- ref=${c}
156
+ ref=${p}
157
157
  aria-modal="true"
158
158
  :aria-label="${() => e.label.value ?? null}"
159
- :aria-labelledby="${() => e.label.value ? null : o}">
160
- <div class="panel" part="panel" ref=${m}>
159
+ :aria-labelledby="${() => e.label.value ? null : s}">
160
+ <div class="panel" part="panel" ref=${y}>
161
161
  <div class="drag-handle" part="drag-handle" aria-label="Drag to close" role="button"></div>
162
162
  <div class="header" part="header" ?hidden=${() => !w()}>
163
- <span class="header-title" id="${o}" ?hidden=${() => !C()}>
163
+ <span class="header-title" id="${s}" ?hidden=${() => !C()}>
164
164
  <slot name="header">${() => S()}</slot>
165
165
  </span>
166
166
  <button
@@ -187,13 +187,12 @@ c(b, {
187
187
  },
188
188
  styles: [
189
189
  n,
190
- r,
191
190
  e,
192
191
  t,
193
- o
192
+ a
194
193
  ]
195
194
  });
196
195
  //#endregion
197
- export { b as DRAWER_TAG };
196
+ export { y as DRAWER_TAG };
198
197
 
199
198
  //# sourceMappingURL=drawer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drawer.js","names":[],"sources":["../src/overlay/drawer/drawer.ts"],"sourcesContent":["import {\n createStableId,\n define,\n html,\n prop,\n ref,\n getHost,\n onCleanup,\n onEvent,\n onMounted,\n useEmit,\n useSlots,\n} from '@vielzeug/ore';\nimport { signal } from '@vielzeug/ripple';\n\nimport type { OverlayCloseDetail, OverlayOpenDetail, SwipeAxis } from '../../headless';\n\nimport { createSwipeControl } from '../../headless';\nimport '../../content/icon/icon';\nimport { coarsePointerMixin, elevationMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport { useDialogControl } from '../shared/use-dialog';\nimport styles from './drawer.css?inline';\n\ntype DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';\ntype DrawerSize = 'sm' | 'lg' | 'full';\ntype DrawerBackdrop = 'opaque' | 'blur' | 'transparent';\ntype DrawerDragHandlePlacement = 'outside' | 'inset';\ntype DrawerSwipeConfig = {\n axis: SwipeAxis;\n closingDistance: (distance: number) => number;\n translate: (distance: number) => string;\n};\n\nconst drawerSwipeConfig: Record<DrawerPlacement, DrawerSwipeConfig> = {\n bottom: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n left: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n right: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n top: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n};\n\n/** Element interface exposing the imperative API for `ore-drawer`. */\nexport interface DrawerElement extends HTMLElement, Omit<OreDrawerProps, 'title'> {\n /** Programmatically open the drawer. Equivalent to setting `open`. */\n show(): void;\n /** Programmatically close the drawer with the exit animation. */\n hide(): void;\n}\n\n/** Drawer component properties */\n\nexport type OreDrawerEvents = {\n close: OverlayCloseDetail & { placement: DrawerPlacement };\n open: OverlayOpenDetail & { placement: DrawerPlacement };\n};\n\nexport type OreDrawerProps = {\n /** Backdrop style — 'opaque' (default), 'blur', or 'transparent' */\n backdrop?: DrawerBackdrop;\n /** Show the close (×) button in the header (default: true) */\n dismissible?: boolean;\n /** Drag handle position used for swipe-to-close gestures */\n 'drag-handle-placement'?: DrawerDragHandlePlacement;\n /**\n * CSS selector for the element inside the drawer that should receive focus on open.\n * Defaults to native dialog focus management (first focusable element).\n * @example '#submit-btn' | 'input[name=\"email\"]'\n */\n 'initial-focus'?: string;\n /**\n * Invisible accessible label for the dialog (`aria-label`).\n * Use when the drawer has no visible title (e.g. image-only content).\n * When omitted, `aria-labelledby` points to the visible header title instead.\n */\n label?: string;\n /** Controlled open state */\n open?: boolean;\n /** When true, backdrop clicks do not close the drawer (default: false) */\n persistent?: boolean;\n /** Side from which the drawer slides in */\n placement?: DrawerPlacement;\n /**\n * When true (default), focus returns to the triggering element after the drawer closes.\n * Set to false to manage focus manually.\n */\n 'return-focus'?: boolean;\n /** Drawer width/height preset */\n size?: DrawerSize;\n /**\n * Visible title text rendered inside the header.\n * Used as the dialog's accessible label via `aria-labelledby` when `label` is not set.\n */\n title?: string;\n};\n\n/**\n * A panel that slides in from any edge of the screen, built on the native `<dialog>` element.\n *\n * @element ore-drawer\n *\n * @attr {boolean} open - Controlled open/close state\n * @attr {string} placement - 'left' | 'right' (default) | 'top' | 'bottom'\n * @attr {string} size - 'sm' | 'lg' | 'full'\n * @attr {string} title - Visible header title text\n * @attr {string} label - Invisible aria-label (for drawers without a visible title)\n * @attr {boolean} dismissible - Show the close (×) button (default: true)\n * @attr {string} drag-handle-placement - 'outside' (default) | 'inset'\n * @attr {string} backdrop - Backdrop style: 'opaque' (default) | 'blur' | 'transparent'\n * @attr {boolean} persistent - Prevent backdrop-click from closing (default: false)\n *\n * @fires open - When the drawer opens with detail: { placement, reason }\n * @fires close - When the drawer closes with detail: { placement, reason }\n *\n * @slot header - Drawer header content\n * @slot - Main body content\n * @slot footer - Drawer footer content\n *\n * @cssprop --drawer-backdrop-bg - Backdrop background color\n * @cssprop --drawer-bg - Panel background color\n * @cssprop --drawer-size - Panel width (horizontal) or height (vertical)\n * @cssprop --drawer-shadow - Panel box-shadow\n * @cssprop --drawer-panel-blur - Panel backdrop blur amount\n *\n * @part drag-handle - Drawer drag handle.\n * @part panel - Panel container.\n * @part header - Header container.\n * @part close-btn - Close button.\n * @part body - Body content container.\n * @part footer - Footer container.\n * @example\n * ```html\n * <!-- With visible title -->\n * <ore-drawer open title=\"Settings\" placement=\"right\">\n * <p>Settings content here.</p>\n * </ore-drawer>\n *\n * <!-- With custom header slot -->\n * <ore-drawer open placement=\"right\">\n * <span slot=\"header\">Settings</span>\n * <p>Settings content here.</p>\n * </ore-drawer>\n * ```\n */\n\nexport const DRAWER_TAG = 'ore-drawer' as const;\ndefine<OreDrawerProps>(DRAWER_TAG, {\n props: {\n backdrop: prop.string<DrawerBackdrop>(),\n dismissible: prop.bool(true),\n 'drag-handle-placement': prop.oneOf(['outside', 'inset'] as const, 'outside'),\n 'initial-focus': prop.string(),\n label: prop.string(),\n open: prop.bool(false),\n persistent: prop.bool(false),\n placement: prop.oneOf(['left', 'right', 'top', 'bottom'] as const, 'right'),\n 'return-focus': prop.bool(true),\n size: prop.string<DrawerSize>(),\n title: prop.string(),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreDrawerEvents>();\n const slots = useSlots();\n\n const drawerLabelId = createStableId('drawer-label');\n const dialogRef = ref<HTMLDialogElement>();\n const panelRef = ref<HTMLDivElement>();\n\n // Drag-to-close state\n const isSwipeClosing = signal(false);\n let swipeCloseTimer: ReturnType<typeof setTimeout> | undefined;\n\n const getHeaderText = () => props.label.value ?? props.title.value ?? '';\n const hasHeaderTitle = () => slots.has('header').value || !!getHeaderText();\n\n // Header is visible when there is slot content, a text label, or a close button.\n const hasHeader = () => hasHeaderTitle() || props.dismissible.value;\n const hasFooter = () => slots.has('footer').value;\n\n const getPlacement = (): DrawerPlacement => props.placement.value || 'right';\n\n const getSwipeConfig = (): DrawerSwipeConfig => drawerSwipeConfig[getPlacement()];\n\n const getSnapThreshold = (panel: HTMLElement, axis: SwipeAxis) => {\n const panelSize = axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n\n return Math.min(96, Math.max(36, panelSize * 0.18));\n };\n\n const shouldCommitSwipeClose = (distance: number, threshold: number) => {\n return getSwipeConfig().closingDistance(distance) >= threshold;\n };\n\n const finalizeSwipeClose = (panel: HTMLElement) => {\n if (!isSwipeClosing.value) return;\n\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n const dialog = dialogRef.value;\n\n if (!dialog) {\n isSwipeClosing.value = false;\n\n return;\n }\n\n dialog.style.transition = 'none';\n panel.style.opacity = '0';\n panel.style.visibility = 'hidden';\n void dialog.offsetWidth;\n\n requestClose('swipe');\n };\n\n const startSwipeClose = (panel: HTMLElement, swipe: DrawerSwipeConfig, committedDistance: number) => {\n if (isSwipeClosing.value) return;\n\n isSwipeClosing.value = true;\n\n const panelSize = swipe.axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n // Preserve overshoot so closing continues from the dragged position instead of snapping back.\n const exitDistance =\n committedDistance >= 0 ? Math.max(committedDistance, panelSize) : Math.min(committedDistance, -panelSize);\n const exitTransform = swipe.translate(exitDistance);\n\n // Commit the current drag position first so the magnetic snap continues\n // from the finger instead of jumping back to rest.\n panel.style.transition = 'transform 180ms cubic-bezier(0.2, 0.9, 0.2, 1), opacity 180ms ease-out';\n void panel.offsetWidth;\n\n const onExitTransitionEnd = (ev: TransitionEvent) => {\n if (ev.target !== panel || ev.propertyName !== 'transform') return;\n\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n };\n\n panel.addEventListener('transitionend', onExitTransitionEnd);\n\n const durationMs = parseFloat(getComputedStyle(panel).transitionDuration) * 1000;\n\n swipeCloseTimer = setTimeout(() => {\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n }, durationMs + 50);\n\n panel.style.transform = exitTransform;\n panel.style.opacity = '0.2';\n };\n\n const resetPanelDragStyles = (panel: HTMLElement) => {\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n // Re-enable transitions so the snap-back or exit animates.\n panel.style.transition = '';\n panel.style.transform = '';\n panel.style.opacity = '';\n panel.style.visibility = '';\n isSwipeClosing.value = false;\n };\n\n // Same \"snap back or commit close\" decision whether the swipe was\n // interrupted by the platform (onCancel) or simply released without an\n // intervening move event crossing the threshold (onRelease).\n const handleSwipeRelease = ({ distance, threshold }: { distance: number; threshold: number }): void => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n // If the release event crosses the threshold (without an intervening\n // move event), commit close instead of snapping back to rest first.\n if (shouldCommitSwipeClose(distance, threshold)) {\n startSwipeClose(panel, getSwipeConfig(), distance);\n\n return;\n }\n\n resetPanelDragStyles(panel);\n };\n\n const swipe = createSwipeControl({\n axis: () => getSwipeConfig().axis,\n disabled: isSwipeClosing,\n onCancel: handleSwipeRelease,\n onCommit: ({ distance }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n startSwipeClose(panel, getSwipeConfig(), distance);\n },\n onMove: ({ distance, threshold }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n const swipeConfig = getSwipeConfig();\n const closingDistance = swipeConfig.closingDistance(distance);\n const progress = Math.min(closingDistance / threshold, 1);\n\n // Kill CSS transitions so the panel tracks the finger instantly.\n panel.style.transition = 'none';\n panel.style.transform = swipeConfig.translate(distance);\n panel.style.opacity = String(1 - progress * 0.4);\n },\n onRelease: handleSwipeRelease,\n shouldCommit: ({ distance, threshold }) => shouldCommitSwipeClose(distance, threshold),\n threshold: () => {\n const panel = panelRef.value;\n\n if (!panel) return 48;\n\n return getSnapThreshold(panel, getSwipeConfig().axis);\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Overlay State Management\n // ────────────────────────────────────────────────────────────────\n\n const { closeWithAnimation, handleCancel, overlay, requestClose, watchOpenProp } = useDialogControl({\n beforeOpen: (dialog) => {\n // Clear any inline drag styles from a previous swipe-close so the CSS\n // entry animation starts from the correct base state.\n const panel = panelRef.value;\n\n if (panel) resetPanelDragStyles(panel);\n\n void dialog;\n },\n closeRequestDetail: (_reason) => ({ placement: props.placement.value ?? 'right' }),\n dialogRef,\n getPanelEl: () => panelRef.value,\n host: el,\n initialFocus: props['initial-focus'],\n isPersistent: () => Boolean(props.persistent.value),\n onCleanup,\n onEvent,\n onNativeClose: (reason) => {\n const panelEl = panelRef.value;\n\n // For swipe-close, keep the panel hidden and off-screen until the next\n // open cycle — resetting inline styles during native close can produce\n // a visible frame at the rest position on some browsers.\n if (panelEl && reason !== 'swipe') resetPanelDragStyles(panelEl);\n\n const dialog = dialogRef.value;\n\n if (dialog) dialog.style.transition = '';\n\n emit('close', { placement: props.placement.value ?? 'right', reason });\n },\n onOpen: (reason) => emit('open', { placement: props.placement.value ?? 'right', reason }),\n openProp: props.open,\n performClose: (dialog, reason) => {\n if (reason === 'swipe') {\n dialog.close();\n } else {\n closeWithAnimation();\n }\n },\n returnFocus: props['return-focus'],\n });\n\n const handleCloseButtonClick = () => {\n requestClose('trigger');\n };\n\n // ────────────────────────────────────────────────────────────────\n // Lifecycle: Setup Drawer Integration\n // ────────────────────────────────────────────────────────────────\n\n onMounted(() => {\n const dialog = dialogRef.value;\n\n if (!dialog) return;\n\n // Expose imperative API\n const drawerEl = el as DrawerElement;\n\n drawerEl.show = () => {\n overlay.open('programmatic');\n };\n\n drawerEl.hide = () => {\n overlay.close('programmatic', false);\n };\n\n // ────────────────────────────────────────────────────────────\n // Event Handlers: Cancel, Backdrop Click\n // ────────────────────────────────────────────────────────────\n // `handleCancel` (Escape via the native `cancel` event) is provided by\n // `useDialogControl` above — drawer only needs its own backdrop-click\n // handler since it has swipe-to-dismiss logic the shared dialog helper\n // doesn't know about.\n\n const handleBackdropClick = (e: MouseEvent) => {\n if (props.persistent.value) return;\n\n if (swipe.isActive() || isSwipeClosing.value) return;\n\n if (e.target !== dialog) return; // Click inside panel\n\n requestClose('outsideClick');\n };\n\n watchOpenProp();\n\n onEvent(dialog, 'cancel', handleCancel);\n onEvent(dialog, 'click', handleBackdropClick);\n\n // Drag-to-close handlers — scoped to the handle element only so interactions\n // with panel content don't accidentally start a drag.\n const panel = panelRef.value;\n const dragHandleEl = panel?.querySelector<HTMLElement>('[part=\"drag-handle\"]');\n\n if (dragHandleEl) {\n onEvent(dragHandleEl, 'pointerdown', swipe.handlePointerDown);\n onEvent(dragHandleEl, 'pointermove', swipe.handlePointerMove);\n onEvent(dragHandleEl, 'pointerup', swipe.handlePointerUp);\n onEvent(dragHandleEl, 'pointercancel', swipe.handlePointerCancel);\n }\n\n return () => {\n overlay.dispose();\n };\n });\n\n return html`\n <dialog\n ref=${dialogRef}\n aria-modal=\"true\"\n :aria-label=\"${() => props.label.value ?? null}\"\n :aria-labelledby=\"${() => (!props.label.value ? drawerLabelId : null)}\">\n <div class=\"panel\" part=\"panel\" ref=${panelRef}>\n <div class=\"drag-handle\" part=\"drag-handle\" aria-label=\"Drag to close\" role=\"button\"></div>\n <div class=\"header\" part=\"header\" ?hidden=${() => !hasHeader()}>\n <span class=\"header-title\" id=\"${drawerLabelId}\" ?hidden=${() => !hasHeaderTitle()}>\n <slot name=\"header\">${() => getHeaderText()}</slot>\n </span>\n <button\n class=\"close-btn\"\n part=\"close-btn\"\n type=\"button\"\n aria-label=\"Close\"\n ?hidden=${() => !props.dismissible.value}\n @click=${handleCloseButtonClick}>\n <ore-icon name=\"x\" size=\"16\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </button>\n </div>\n <div class=\"body\" part=\"body\">\n <slot></slot>\n </div>\n <div class=\"footer\" part=\"footer\" ?hidden=${() => !hasFooter()}>\n <slot name=\"footer\"></slot>\n </div>\n </div>\n </dialog>\n `;\n },\n styles: [elevationMixin, forcedColorsMixin, coarsePointerMixin, reducedMotionMixin, styles],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"drawer.js","names":[],"sources":["../src/overlay/drawer/drawer.ts"],"sourcesContent":["import {\n createStableId,\n define,\n html,\n prop,\n ref,\n getHost,\n onCleanup,\n onEvent,\n onMounted,\n useEmit,\n useSlots,\n} from '@vielzeug/ore';\nimport { signal } from '@vielzeug/ripple';\n\nimport type { OverlayCloseDetail, OverlayOpenDetail, SwipeAxis } from '../../headless';\n\nimport { createSwipeControl } from '../../headless';\nimport '../../content/icon/icon';\nimport { coarsePointerMixin, forcedColorsMixin, reducedMotionMixin } from '../../styles';\nimport { useDialogControl } from '../shared/use-dialog';\nimport styles from './drawer.css?inline';\n\ntype DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';\ntype DrawerSize = 'sm' | 'lg' | 'full';\ntype DrawerBackdrop = 'opaque' | 'blur' | 'transparent';\ntype DrawerDragHandlePlacement = 'outside' | 'inset';\ntype DrawerSwipeConfig = {\n axis: SwipeAxis;\n closingDistance: (distance: number) => number;\n translate: (distance: number) => string;\n};\n\nconst drawerSwipeConfig: Record<DrawerPlacement, DrawerSwipeConfig> = {\n bottom: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n left: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n right: {\n axis: 'x',\n closingDistance: (distance) => Math.max(0, distance),\n translate: (distance) => `translateX(${distance}px)`,\n },\n top: {\n axis: 'y',\n closingDistance: (distance) => Math.max(0, -distance),\n translate: (distance) => `translateY(${distance}px)`,\n },\n};\n\n/** Element interface exposing the imperative API for `ore-drawer`. */\nexport interface DrawerElement extends HTMLElement, Omit<OreDrawerProps, 'title'> {\n /** Programmatically open the drawer. Equivalent to setting `open`. */\n show(): void;\n /** Programmatically close the drawer with the exit animation. */\n hide(): void;\n}\n\n/** Drawer component properties */\n\nexport type OreDrawerEvents = {\n close: OverlayCloseDetail & { placement: DrawerPlacement };\n open: OverlayOpenDetail & { placement: DrawerPlacement };\n};\n\nexport type OreDrawerProps = {\n /** Backdrop style — 'opaque' (default), 'blur', or 'transparent' */\n backdrop?: DrawerBackdrop;\n /** Show the close (×) button in the header (default: true) */\n dismissible?: boolean;\n /** Drag handle position used for swipe-to-close gestures */\n 'drag-handle-placement'?: DrawerDragHandlePlacement;\n /**\n * CSS selector for the element inside the drawer that should receive focus on open.\n * Defaults to native dialog focus management (first focusable element).\n * @example '#submit-btn' | 'input[name=\"email\"]'\n */\n 'initial-focus'?: string;\n /**\n * Invisible accessible label for the dialog (`aria-label`).\n * Use when the drawer has no visible title (e.g. image-only content).\n * When omitted, `aria-labelledby` points to the visible header title instead.\n */\n label?: string;\n /** Controlled open state */\n open?: boolean;\n /** When true, backdrop clicks do not close the drawer (default: false) */\n persistent?: boolean;\n /** Side from which the drawer slides in */\n placement?: DrawerPlacement;\n /**\n * When true (default), focus returns to the triggering element after the drawer closes.\n * Set to false to manage focus manually.\n */\n 'return-focus'?: boolean;\n /** Drawer width/height preset */\n size?: DrawerSize;\n /**\n * Visible title text rendered inside the header.\n * Used as the dialog's accessible label via `aria-labelledby` when `label` is not set.\n */\n title?: string;\n};\n\n/**\n * A panel that slides in from any edge of the screen, built on the native `<dialog>` element.\n *\n * @element ore-drawer\n *\n * @attr {boolean} open - Controlled open/close state\n * @attr {string} placement - 'left' | 'right' (default) | 'top' | 'bottom'\n * @attr {string} size - 'sm' | 'lg' | 'full'\n * @attr {string} title - Visible header title text\n * @attr {string} label - Invisible aria-label (for drawers without a visible title)\n * @attr {boolean} dismissible - Show the close (×) button (default: true)\n * @attr {string} drag-handle-placement - 'outside' (default) | 'inset'\n * @attr {string} backdrop - Backdrop style: 'opaque' (default) | 'blur' | 'transparent'\n * @attr {boolean} persistent - Prevent backdrop-click from closing (default: false)\n *\n * @fires open - When the drawer opens with detail: { placement, reason }\n * @fires close - When the drawer closes with detail: { placement, reason }\n *\n * @slot header - Drawer header content\n * @slot - Main body content\n * @slot footer - Drawer footer content\n *\n * @cssprop --drawer-backdrop-bg - Backdrop background color\n * @cssprop --drawer-bg - Panel background color\n * @cssprop --drawer-size - Panel width (horizontal) or height (vertical)\n * @cssprop --drawer-shadow - Panel box-shadow\n * @cssprop --drawer-panel-blur - Panel backdrop blur amount\n *\n * @part drag-handle - Drawer drag handle.\n * @part panel - Panel container.\n * @part header - Header container.\n * @part close-btn - Close button.\n * @part body - Body content container.\n * @part footer - Footer container.\n * @example\n * ```html\n * <!-- With visible title -->\n * <ore-drawer open title=\"Settings\" placement=\"right\">\n * <p>Settings content here.</p>\n * </ore-drawer>\n *\n * <!-- With custom header slot -->\n * <ore-drawer open placement=\"right\">\n * <span slot=\"header\">Settings</span>\n * <p>Settings content here.</p>\n * </ore-drawer>\n * ```\n */\n\nexport const DRAWER_TAG = 'ore-drawer' as const;\ndefine<OreDrawerProps>(DRAWER_TAG, {\n props: {\n backdrop: prop.string<DrawerBackdrop>(),\n dismissible: prop.bool(true),\n 'drag-handle-placement': prop.oneOf(['outside', 'inset'] as const, 'outside'),\n 'initial-focus': prop.string(),\n label: prop.string(),\n open: prop.bool(false),\n persistent: prop.bool(false),\n placement: prop.oneOf(['left', 'right', 'top', 'bottom'] as const, 'right'),\n 'return-focus': prop.bool(true),\n size: prop.string<DrawerSize>(),\n title: prop.string(),\n },\n setup(props) {\n const el = getHost();\n const emit = useEmit<OreDrawerEvents>();\n const slots = useSlots();\n\n const drawerLabelId = createStableId('drawer-label');\n const dialogRef = ref<HTMLDialogElement>();\n const panelRef = ref<HTMLDivElement>();\n\n // Drag-to-close state\n const isSwipeClosing = signal(false);\n let swipeCloseTimer: ReturnType<typeof setTimeout> | undefined;\n\n const getHeaderText = () => props.label.value ?? props.title.value ?? '';\n const hasHeaderTitle = () => slots.has('header').value || !!getHeaderText();\n\n // Header is visible when there is slot content, a text label, or a close button.\n const hasHeader = () => hasHeaderTitle() || props.dismissible.value;\n const hasFooter = () => slots.has('footer').value;\n\n const getPlacement = (): DrawerPlacement => props.placement.value || 'right';\n\n const getSwipeConfig = (): DrawerSwipeConfig => drawerSwipeConfig[getPlacement()];\n\n const getSnapThreshold = (panel: HTMLElement, axis: SwipeAxis) => {\n const panelSize = axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n\n return Math.min(96, Math.max(36, panelSize * 0.18));\n };\n\n const shouldCommitSwipeClose = (distance: number, threshold: number) => {\n return getSwipeConfig().closingDistance(distance) >= threshold;\n };\n\n const finalizeSwipeClose = (panel: HTMLElement) => {\n if (!isSwipeClosing.value) return;\n\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n const dialog = dialogRef.value;\n\n if (!dialog) {\n isSwipeClosing.value = false;\n\n return;\n }\n\n dialog.style.transition = 'none';\n panel.style.opacity = '0';\n panel.style.visibility = 'hidden';\n void dialog.offsetWidth;\n\n requestClose('swipe');\n };\n\n const startSwipeClose = (panel: HTMLElement, swipe: DrawerSwipeConfig, committedDistance: number) => {\n if (isSwipeClosing.value) return;\n\n isSwipeClosing.value = true;\n\n const panelSize = swipe.axis === 'x' ? panel.offsetWidth : panel.offsetHeight;\n // Preserve overshoot so closing continues from the dragged position instead of snapping back.\n const exitDistance =\n committedDistance >= 0 ? Math.max(committedDistance, panelSize) : Math.min(committedDistance, -panelSize);\n const exitTransform = swipe.translate(exitDistance);\n\n // Commit the current drag position first so the magnetic snap continues\n // from the finger instead of jumping back to rest.\n panel.style.transition = 'transform 180ms cubic-bezier(0.2, 0.9, 0.2, 1), opacity 180ms ease-out';\n void panel.offsetWidth;\n\n const onExitTransitionEnd = (ev: TransitionEvent) => {\n if (ev.target !== panel || ev.propertyName !== 'transform') return;\n\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n };\n\n panel.addEventListener('transitionend', onExitTransitionEnd);\n\n const durationMs = parseFloat(getComputedStyle(panel).transitionDuration) * 1000;\n\n swipeCloseTimer = setTimeout(() => {\n panel.removeEventListener('transitionend', onExitTransitionEnd);\n finalizeSwipeClose(panel);\n }, durationMs + 50);\n\n panel.style.transform = exitTransform;\n panel.style.opacity = '0.2';\n };\n\n const resetPanelDragStyles = (panel: HTMLElement) => {\n if (swipeCloseTimer) {\n clearTimeout(swipeCloseTimer);\n swipeCloseTimer = undefined;\n }\n\n // Re-enable transitions so the snap-back or exit animates.\n panel.style.transition = '';\n panel.style.transform = '';\n panel.style.opacity = '';\n panel.style.visibility = '';\n isSwipeClosing.value = false;\n };\n\n // Same \"snap back or commit close\" decision whether the swipe was\n // interrupted by the platform (onCancel) or simply released without an\n // intervening move event crossing the threshold (onRelease).\n const handleSwipeRelease = ({ distance, threshold }: { distance: number; threshold: number }): void => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n // If the release event crosses the threshold (without an intervening\n // move event), commit close instead of snapping back to rest first.\n if (shouldCommitSwipeClose(distance, threshold)) {\n startSwipeClose(panel, getSwipeConfig(), distance);\n\n return;\n }\n\n resetPanelDragStyles(panel);\n };\n\n const swipe = createSwipeControl({\n axis: () => getSwipeConfig().axis,\n disabled: isSwipeClosing,\n onCancel: handleSwipeRelease,\n onCommit: ({ distance }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n startSwipeClose(panel, getSwipeConfig(), distance);\n },\n onMove: ({ distance, threshold }) => {\n const panel = panelRef.value;\n\n if (!panel) return;\n\n const swipeConfig = getSwipeConfig();\n const closingDistance = swipeConfig.closingDistance(distance);\n const progress = Math.min(closingDistance / threshold, 1);\n\n // Kill CSS transitions so the panel tracks the finger instantly.\n panel.style.transition = 'none';\n panel.style.transform = swipeConfig.translate(distance);\n panel.style.opacity = String(1 - progress * 0.4);\n },\n onRelease: handleSwipeRelease,\n shouldCommit: ({ distance, threshold }) => shouldCommitSwipeClose(distance, threshold),\n threshold: () => {\n const panel = panelRef.value;\n\n if (!panel) return 48;\n\n return getSnapThreshold(panel, getSwipeConfig().axis);\n },\n });\n\n // ────────────────────────────────────────────────────────────────\n // Overlay State Management\n // ────────────────────────────────────────────────────────────────\n\n const { closeWithAnimation, handleCancel, overlay, requestClose, watchOpenProp } = useDialogControl({\n beforeOpen: (dialog) => {\n // Clear any inline drag styles from a previous swipe-close so the CSS\n // entry animation starts from the correct base state.\n const panel = panelRef.value;\n\n if (panel) resetPanelDragStyles(panel);\n\n void dialog;\n },\n closeRequestDetail: (_reason) => ({ placement: props.placement.value ?? 'right' }),\n dialogRef,\n getPanelEl: () => panelRef.value,\n host: el,\n initialFocus: props['initial-focus'],\n isPersistent: () => Boolean(props.persistent.value),\n onCleanup,\n onEvent,\n onNativeClose: (reason) => {\n const panelEl = panelRef.value;\n\n // For swipe-close, keep the panel hidden and off-screen until the next\n // open cycle — resetting inline styles during native close can produce\n // a visible frame at the rest position on some browsers.\n if (panelEl && reason !== 'swipe') resetPanelDragStyles(panelEl);\n\n const dialog = dialogRef.value;\n\n if (dialog) dialog.style.transition = '';\n\n emit('close', { placement: props.placement.value ?? 'right', reason });\n },\n onOpen: (reason) => emit('open', { placement: props.placement.value ?? 'right', reason }),\n openProp: props.open,\n performClose: (dialog, reason) => {\n if (reason === 'swipe') {\n dialog.close();\n } else {\n closeWithAnimation();\n }\n },\n returnFocus: props['return-focus'],\n });\n\n const handleCloseButtonClick = () => {\n requestClose('trigger');\n };\n\n // ────────────────────────────────────────────────────────────────\n // Lifecycle: Setup Drawer Integration\n // ────────────────────────────────────────────────────────────────\n\n onMounted(() => {\n const dialog = dialogRef.value;\n\n if (!dialog) return;\n\n // Expose imperative API\n const drawerEl = el as DrawerElement;\n\n drawerEl.show = () => {\n overlay.open('programmatic');\n };\n\n drawerEl.hide = () => {\n overlay.close('programmatic', false);\n };\n\n // ────────────────────────────────────────────────────────────\n // Event Handlers: Cancel, Backdrop Click\n // ────────────────────────────────────────────────────────────\n // `handleCancel` (Escape via the native `cancel` event) is provided by\n // `useDialogControl` above — drawer only needs its own backdrop-click\n // handler since it has swipe-to-dismiss logic the shared dialog helper\n // doesn't know about.\n\n const handleBackdropClick = (e: MouseEvent) => {\n if (props.persistent.value) return;\n\n if (swipe.isActive() || isSwipeClosing.value) return;\n\n if (e.target !== dialog) return; // Click inside panel\n\n requestClose('outsideClick');\n };\n\n watchOpenProp();\n\n onEvent(dialog, 'cancel', handleCancel);\n onEvent(dialog, 'click', handleBackdropClick);\n\n // Drag-to-close handlers — scoped to the handle element only so interactions\n // with panel content don't accidentally start a drag.\n const panel = panelRef.value;\n const dragHandleEl = panel?.querySelector<HTMLElement>('[part=\"drag-handle\"]');\n\n if (dragHandleEl) {\n onEvent(dragHandleEl, 'pointerdown', swipe.handlePointerDown);\n onEvent(dragHandleEl, 'pointermove', swipe.handlePointerMove);\n onEvent(dragHandleEl, 'pointerup', swipe.handlePointerUp);\n onEvent(dragHandleEl, 'pointercancel', swipe.handlePointerCancel);\n }\n\n return () => {\n overlay.dispose();\n };\n });\n\n return html`\n <dialog\n ref=${dialogRef}\n aria-modal=\"true\"\n :aria-label=\"${() => props.label.value ?? null}\"\n :aria-labelledby=\"${() => (!props.label.value ? drawerLabelId : null)}\">\n <div class=\"panel\" part=\"panel\" ref=${panelRef}>\n <div class=\"drag-handle\" part=\"drag-handle\" aria-label=\"Drag to close\" role=\"button\"></div>\n <div class=\"header\" part=\"header\" ?hidden=${() => !hasHeader()}>\n <span class=\"header-title\" id=\"${drawerLabelId}\" ?hidden=${() => !hasHeaderTitle()}>\n <slot name=\"header\">${() => getHeaderText()}</slot>\n </span>\n <button\n class=\"close-btn\"\n part=\"close-btn\"\n type=\"button\"\n aria-label=\"Close\"\n ?hidden=${() => !props.dismissible.value}\n @click=${handleCloseButtonClick}>\n <ore-icon name=\"x\" size=\"16\" stroke-width=\"2.5\" aria-hidden=\"true\"></ore-icon>\n </button>\n </div>\n <div class=\"body\" part=\"body\">\n <slot></slot>\n </div>\n <div class=\"footer\" part=\"footer\" ?hidden=${() => !hasFooter()}>\n <slot name=\"footer\"></slot>\n </div>\n </div>\n </dialog>\n `;\n },\n styles: [forcedColorsMixin, coarsePointerMixin, reducedMotionMixin, styles],\n});\n"],"mappings":"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"}
@@ -1,37 +1,41 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./styles/index.cjs"),r=require("./shared/size-presets.cjs"),i=require("./headless/keyboard.cjs"),a=require("./inputs/shared/form-context.cjs"),o=require("./inputs/file-input/file-input.css.cjs");let s=require("@vielzeug/ore"),c=require("@vielzeug/ripple"),l=require("@vielzeug/ore/forms"),u=require("@vielzeug/dnd");var d=e=>{if(e===0)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`,`TB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**r).toFixed(1))+` `+n[r]},f=(e,t)=>!t||e.size<=t,p=e=>e.type.startsWith(`image/`),m=`ore-file-input`;(0,s.define)(m,{formAssociated:!0,props:{accept:s.prop.string(),color:s.prop.string(),disabled:s.prop.bool(!1),error:s.prop.string(),gallery:s.prop.bool(!1),helper:s.prop.string(),label:s.prop.string(),"max-files":s.prop.number(0),"max-size":s.prop.number(0),multiple:s.prop.bool(!1),name:s.prop.string(),ref:s.prop.json(void 0),required:s.prop.bool(!1),size:s.prop.string()},setup(e){let t=(0,s.useEmit)(),n=(0,c.signal)([]),r=(0,c.signal)(!1),o=a.useFormContext(e,(0,s.inject)(a.FORM_CTX)),m=o.disabled,h=(0,c.computed)(()=>e[`max-files`].value??0),g=(0,c.computed)(()=>e[`max-size`].value??0);(0,l.useField)({disabled:m,toFormValue:t=>{if(t.length===0)return null;let n=e.name.value||`file`,r=new FormData;for(let e of t)r.append(n,e);return r},value:n});let _=(0,c.computed)(()=>!!e.error.value);(0,s.bind)({attr:{"drag-over":()=>r.value?!0:void 0,invalid:()=>_.value?!0:void 0,size:o.size}});let v=(0,s.createStableId)(`file-input`),y=`label-${v}`,b=`helper-${v}`,x=`error-${v}`,S=(0,s.ref)(),C=(0,s.ref)(),w=(0,c.computed)(()=>{let t=[];e.accept.value&&t.push(e.accept.value.split(`,`).map(e=>e.trim()).join(`, `));let n=g.value;n>0&&t.push(`max ${d(n)}`);let r=h.value;return r>0&&t.push(`up to ${r} file${r===1?``:`s`}`),t.join(` · `)});function T(r,i){if(m.value)return;let a=e.accept.value,o=!!e.multiple.value,s=Array.from(r);o||(s=s.slice(0,1)),s=s.filter(e=>(0,u.matchesAccept)(e,a?a.split(`,`).map(e=>e.trim()):[])&&f(e,g.value));let c=o?[...n.value]:[];for(let e of s)c.includes(e)||c.push(e);h.value>0&&c.length>h.value&&(c=c.slice(0,h.value)),n.value=c,t(`change`,{files:n.value,originalEvent:i,value:n.value})}function E(e,r){n.value=n.value.filter(t=>t!==e),t(`remove`,{file:e,files:n.value,originalEvent:r,value:n.value}),t(`change`,{files:n.value,originalEvent:r,value:n.value})}let D=new Map;function O(e){let t=D.get(e);return t||(t=URL.createObjectURL(e),D.set(e,t)),t}function k(e){let t=new Set(e);for(let[e,n]of D)t.has(e)||(URL.revokeObjectURL(n),D.delete(e))}return(0,c.watch)(n,k),(0,s.onCleanup)(()=>{for(let e of D.values())URL.revokeObjectURL(e);D.clear()}),(0,s.onElement)(C,t=>{e.ref.value?.(t);let n=(0,c.watch)(e.ref,e=>{e?.(t)});return()=>{n.dispose(),e.ref.value?.(null)}}),(0,s.onMounted)(()=>{let e=C.value,t=S.value,n=!1,a=i.createInteraction({disabled:m,onPress:()=>{e.click()}});(0,s.onEvent)(e,`change`,e=>{let t=e.target;t.files?.length&&T(Array.from(t.files),e),t.value=``}),(0,s.onEvent)(t,`click`,t=>{if(t.target!==e){if(n){n=!1;return}m.value||e.click()}}),(0,s.onEvent)(t,`keydown`,e=>{n=a.handleKeydown(e)&&e.key===`Enter`});let o=(0,u.createDropZone)({disabled:m.value,element:t,onDrop:e=>T(e),onHoverChange:e=>{r.value=e}});(0,s.onCleanup)(()=>o.dispose())}),s.html`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/theme.css.cjs"),n=require("./styles/index.cjs"),r=require("./shared/size-presets.cjs"),i=require("./headless/ref-callback.cjs"),a=require("./headless/keyboard.cjs"),o=require("./inputs/shared/form-context.cjs"),s=require("./inputs/file-input/file-input-upload.cjs"),c=require("./inputs/file-input/file-input.css.cjs");let l=require("@vielzeug/ore"),u=require("@vielzeug/ore/directives"),d=require("@vielzeug/ripple"),f=require("@vielzeug/ore/forms"),p=require("@vielzeug/dnd");var m=e=>e.type.startsWith(`image/`),h=`ore-file-input`;(0,l.define)(h,{formAssociated:!0,props:{accept:l.prop.string(),color:l.prop.string(),disabled:l.prop.bool(!1),error:l.prop.string(),gallery:l.prop.bool(!1),helper:l.prop.string(),label:l.prop.string(),"max-files":l.prop.number(0),"max-size":l.prop.number(0),multiple:l.prop.bool(!1),name:l.prop.string(),ref:l.prop.data(),required:l.prop.bool(!1),size:l.prop.string(),upload:l.prop.data()},setup(e){let t=(0,l.useEmit)(),n=(0,d.signal)(!1),r=(0,d.signal)(null),c=o.useFormContext(e,(0,l.inject)(o.FORM_CTX)),h=c.disabled,g=(0,d.computed)(()=>e[`max-files`].value??0),_=(0,d.computed)(()=>e[`max-size`].value??0),v=s.createFileQueue({accept:e.accept,disabled:h,maxFiles:g,maxSize:_,multiple:(0,d.computed)(()=>!!e.multiple.value),onChange:(e,n)=>t(`change`,{files:e,originalEvent:n,value:e}),onRemove:(e,n,r)=>t(`remove`,{file:e,files:n,originalEvent:r,value:n}),onUploadError:(e,n)=>t(`upload-error`,{error:n,file:e}),onUploadProgress:(e,n,r)=>t(`upload-progress`,{file:e,loaded:n,total:r}),onUploadSuccess:e=>t(`upload-success`,{file:e}),upload:(0,d.computed)(()=>e.upload.value??void 0)});(0,l.onCleanup)(()=>v.dispose()),(0,f.useField)({disabled:h,toFormValue:t=>{if(t.length===0)return null;let n=e.name.value||`file`,r=new FormData;for(let e of t)r.append(n,e);return r},value:v.files});let y=(0,d.computed)(()=>!!e.error.value);(0,l.bind)({attr:{"drag-over":()=>n.value?!0:void 0,invalid:()=>y.value?!0:void 0,size:c.size}});let b=(0,l.createStableId)(`file-input`),x=`label-${b}`,S=`helper-${b}`,C=`error-${b}`,w=(0,l.ref)(),T=(0,l.ref)(),E=(0,d.computed)(()=>{let t=[];e.accept.value&&t.push(e.accept.value.split(`,`).map(e=>e.trim()).join(`, `));let n=_.value;n>0&&t.push(`max ${s.formatBytes(n)}`);let r=g.value;return r>0&&t.push(`up to ${r} file${r===1?``:`s`}`),t.join(` · `)});function D(e){r.value=e,T.value?.click()}let O=new Map;function k(e){let t=O.get(e);return t||(t=URL.createObjectURL(e),O.set(e,t)),t}function A(e){let t=new Set(e);for(let[e,n]of O)t.has(e)||(URL.revokeObjectURL(n),O.delete(e))}return(0,d.watch)(v.files,A),(0,l.onCleanup)(()=>{for(let e of O.values())URL.revokeObjectURL(e);O.clear()}),(0,l.onElement)(T,t=>i.bindRefCallback(e.ref,t)),(0,l.onMounted)(()=>{let e=T.value,t=w.value,i=!1,o=a.createInteraction({disabled:h,onPress:()=>{e.click()}});(0,l.onEvent)(e,`change`,e=>{let t=e.target,n=r.value;r.value=null,n&&t.files?.[0]?v.replaceFile(n,t.files[0],e):t.files?.length&&v.addFiles(Array.from(t.files),e),t.value=``}),(0,l.onEvent)(t,`click`,t=>{if(t.target!==e){if(i){i=!1;return}h.value||e.click()}}),(0,l.onEvent)(t,`keydown`,e=>{i=o.handleKeydown(e)&&e.key===`Enter`}),(0,d.watch)(h,e=>{let r=(0,p.createDropZone)({disabled:e,element:t,onDrop:e=>v.addFiles(e),onHoverChange:e=>{n.value=e}});return()=>r.dispose()},{immediate:!0})}),l.html`
2
2
  <div class="file-input-wrapper" part="wrapper">
3
- <label class="label-outside" id="${y}" part="label" ?hidden=${()=>!e.label.value}
3
+ <label class="label-outside" id="${x}" part="label" ?hidden=${()=>!e.label.value}
4
4
  >${e.label}</label
5
5
  >
6
6
  <div
7
7
  class="dropzone"
8
8
  part="dropzone"
9
- ref=${S}
9
+ ref=${w}
10
10
  role="button"
11
- :tabindex="${()=>m.value?`-1`:`0`}"
12
- :aria-disabled="${()=>String(m.value)}"
11
+ :tabindex="${()=>h.value?`-1`:`0`}"
12
+ :aria-disabled="${()=>String(h.value)}"
13
13
  :aria-label="${()=>e.label.value?null:`File upload drop zone`}"
14
- :aria-labelledby="${()=>e.label.value?y:null}"
15
- aria-describedby="${b}">
14
+ :aria-labelledby="${()=>e.label.value?x:null}"
15
+ aria-describedby="${S}">
16
16
  <input
17
17
  type="file"
18
- ref=${C}
18
+ ref=${T}
19
19
  part="input"
20
- id="${v}"
20
+ id="${b}"
21
21
  :accept="${e.accept}"
22
22
  ?multiple="${e.multiple}"
23
23
  ?required="${e.required}"
24
- ?disabled="${m}"
24
+ ?disabled="${h}"
25
25
  :name="${e.name}"
26
26
  hidden
27
27
  inert
28
28
  tabindex="-1" />
29
29
  <div class="dropzone-content">
30
- <span class="dropzone-icon" aria-hidden="true">
31
- <ore-icon name="upload" size="36" stroke-width="1.5" aria-hidden="true"></ore-icon>
30
+ <span class="dropzone-icon" aria-hidden="true" :data-status="${()=>y.value?`error`:null}">
31
+ ${()=>y.value?l.html`<ore-icon name="alert-circle" size="36" stroke-width="1.5" aria-hidden="true"></ore-icon>`:l.html`<ore-icon name="upload" size="36" stroke-width="1.5" aria-hidden="true"></ore-icon>`}
32
32
  </span>
33
- <span class="dropzone-title">Drop files here or <u>click to browse</u></span>
34
- <span class="dropzone-hint" ?hidden=${()=>!w.value}>${w}</span>
33
+ <!-- Signal 01: the copy itself shifts on drag-entry (not just border/glow) — a
34
+ static "Drop files here" during an active drag reads as if the drop target
35
+ hasn't noticed the file yet. -->
36
+ ${(0,u.when)(()=>n.value,()=>l.html`<span class="dropzone-title dropzone-title-active">Release to upload</span>`)}
37
+ ${(0,u.when)(()=>!n.value,()=>l.html`<span class="dropzone-title">Drop files here or <u>click to browse</u></span>`)}
38
+ <span class="dropzone-hint" ?hidden=${()=>!E.value}>${E}</span>
35
39
  </div>
36
40
  </div>
37
41
  <ul
@@ -39,54 +43,116 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
39
43
  part="${()=>e.gallery.value?`gallery`:null}"
40
44
  role="list"
41
45
  aria-label="Selected files"
42
- ?hidden=${()=>n.value.length===0}>
43
- ${()=>n.value.map(t=>e.gallery.value?s.html`
44
- <li class="file-card">
45
- ${p(t)?s.html`<img
46
- class="file-thumb"
47
- alt=""
48
- ref="${e=>{e&&(e.src=O(t))}}" />`:s.html`<span class="file-thumb file-thumb-generic" aria-hidden="true">
49
- <ore-icon name="file" size="28" stroke-width="1.5" aria-hidden="true"></ore-icon>
50
- </span>`}
46
+ ?hidden=${()=>v.files.value.length===0}>
47
+ ${()=>v.files.value.map(t=>e.gallery.value?l.html`
48
+ <li class="file-card" data-status=${()=>v.fileState(t).status}>
49
+ <span class="file-thumb-frame">
50
+ ${m(t)?l.html`<img
51
+ class="file-thumb"
52
+ alt=""
53
+ ref="${e=>{e&&(e.src=k(t))}}" />`:l.html`<span class="file-thumb file-thumb-generic" aria-hidden="true">
54
+ <ore-icon name="file" size="28" stroke-width="1.5" aria-hidden="true"></ore-icon>
55
+ </span>`}
56
+ ${(0,u.when)(()=>v.fileState(t).status===`success`,()=>l.html`<span class="file-status-badge file-status-badge-success" aria-hidden="true">
57
+ <ore-icon name="check" size="11" stroke-width="3" aria-hidden="true"></ore-icon>
58
+ </span>`)}
59
+ ${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<span class="file-status-badge file-status-badge-error" aria-hidden="true">
60
+ <ore-icon name="alert-circle" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
61
+ </span>`)}
62
+ <span class="file-card-actions">
63
+ ${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<button
64
+ class="file-card-action"
65
+ type="button"
66
+ aria-label="${`Retry uploading ${t.name}`}"
67
+ @click=${()=>v.retryUpload(t)}>
68
+ <ore-icon name="refresh-cw" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
69
+ </button>`)}
70
+ ${(0,u.when)(()=>v.fileState(t).status===`success`&&!!e.multiple.value&&!!e.upload.value,()=>l.html`<button
71
+ class="file-card-action"
72
+ type="button"
73
+ aria-label="${`Replace ${t.name}`}"
74
+ @click=${()=>D(t)}>
75
+ <ore-icon name="upload" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
76
+ </button>`)}
77
+ <button
78
+ class="file-card-action file-card-remove"
79
+ type="button"
80
+ aria-label="${`Remove ${t.name}`}"
81
+ @click=${e=>v.removeFile(t,e)}>
82
+ <ore-icon name="x" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
83
+ </button>
84
+ </span>
85
+ </span>
51
86
  <span class="file-card-name" title="${t.name}">${t.name}</span>
52
- <button
53
- class="file-card-remove"
54
- type="button"
55
- aria-label="${`Remove ${t.name}`}"
56
- @click=${e=>E(t,e)}>
57
- <ore-icon name="x" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
58
- </button>
87
+ ${(0,u.when)(()=>v.fileState(t).status===`uploading`,()=>l.html`
88
+ <ore-progress
89
+ type="linear"
90
+ size="sm"
91
+ :value=${()=>v.uploadPercent(t)}
92
+ label=${()=>`${v.uploadPercent(t)}%`}></ore-progress>
93
+ <span class="file-progress-meta">${()=>v.uploadMetaText(t)}</span>
94
+ `)}
95
+ ${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<span class="file-error-text">${()=>v.fileState(t).error}</span>`)}
59
96
  </li>
60
- `:s.html`
61
- <li class="file-item">
97
+ `:l.html`
98
+ <li class="file-item" data-status=${()=>v.fileState(t).status}>
62
99
  <span class="file-icon" aria-hidden="true">
63
- <ore-icon name="file" size="18" stroke-width="1.75" aria-hidden="true"></ore-icon>
100
+ <ore-icon
101
+ name=${()=>v.statusIconName(t)}
102
+ size="18"
103
+ stroke-width="1.75"
104
+ aria-hidden="true"></ore-icon>
64
105
  </span>
65
106
  <span class="file-meta">
66
107
  <span class="file-name" title="${t.name}">${t.name}</span>
67
- <span class="file-size">${d(t.size)}</span>
108
+ ${(0,u.when)(()=>v.fileState(t).status===`uploading`,()=>l.html`
109
+ <ore-progress
110
+ type="linear"
111
+ size="sm"
112
+ :value=${()=>v.uploadPercent(t)}
113
+ label=${()=>`${v.uploadPercent(t)}%`}></ore-progress>
114
+ <span class="file-progress-meta">${()=>v.uploadMetaText(t)}</span>
115
+ `)}
116
+ ${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<span class="file-error-text">${()=>v.fileState(t).error}</span>`)}
117
+ ${(0,u.when)(()=>v.fileState(t).status===`idle`||v.fileState(t).status===`success`,()=>l.html`<span class="file-size">${s.formatBytes(t.size)}</span>`)}
118
+ </span>
119
+ <span class="file-actions">
120
+ ${(0,u.when)(()=>v.fileState(t).status===`error`,()=>l.html`<button
121
+ class="file-action"
122
+ type="button"
123
+ aria-label="${`Retry uploading ${t.name}`}"
124
+ @click=${()=>v.retryUpload(t)}>
125
+ <ore-icon name="refresh-cw" size="14" stroke-width="2" aria-hidden="true"></ore-icon>
126
+ </button>`)}
127
+ ${(0,u.when)(()=>v.fileState(t).status===`success`&&!!e.multiple.value&&!!e.upload.value,()=>l.html`<button
128
+ class="file-action"
129
+ type="button"
130
+ aria-label="${`Replace ${t.name}`}"
131
+ @click=${()=>D(t)}>
132
+ <ore-icon name="upload" size="14" stroke-width="2" aria-hidden="true"></ore-icon>
133
+ </button>`)}
134
+ <button
135
+ class="file-remove"
136
+ type="button"
137
+ aria-label="${`Remove ${t.name}`}"
138
+ @click=${e=>v.removeFile(t,e)}>
139
+ <ore-icon name="x" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
140
+ </button>
68
141
  </span>
69
- <button
70
- class="file-remove"
71
- type="button"
72
- aria-label="${`Remove ${t.name}`}"
73
- @click=${e=>E(t,e)}>
74
- <ore-icon name="x" size="12" stroke-width="2.5" aria-hidden="true"></ore-icon>
75
- </button>
76
142
  </li>
77
143
  `)}
78
144
  </ul>
79
- <div class="helper-text" id="${b}" part="helper" ?hidden=${()=>_.value||!e.helper.value}>
145
+ <div class="helper-text" id="${S}" part="helper" ?hidden=${()=>y.value||!e.helper.value}>
80
146
  ${e.helper}
81
147
  </div>
82
148
  <div
83
149
  class="helper-text helper-text-error"
84
- id="${x}"
150
+ id="${C}"
85
151
  role="alert"
86
152
  part="error"
87
- ?hidden=${()=>!_.value}>
153
+ ?hidden=${()=>!y.value}>
88
154
  ${()=>e.error.value??``}
89
155
  </div>
90
156
  </div>
91
- `},shadow:{delegatesFocus:!0},styles:[...n.fieldMixins,e.sizeVariantMixin(r.FILE_INPUT_SIZE_PRESET),t.forcedColorsFocusMixin(`.dropzone`),o.default]}),exports.FILE_INPUT_TAG=m;
157
+ `},shadow:{delegatesFocus:!0},styles:[...n.fieldMixins,e.sizeVariantMixin(r.FILE_INPUT_SIZE_PRESET),t.forcedColorsFocusMixin(`.dropzone`),c.default]}),exports.FILE_INPUT_TAG=h;
92
158
  //# sourceMappingURL=file-input.cjs.map