@endfield-ui/react 1.2.0 → 1.2.1

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 (477) hide show
  1. package/README.md +8 -3
  2. package/dist/components/accordion/Accordion.d.ts +46 -0
  3. package/dist/components/accordion/Accordion.js +2 -0
  4. package/dist/components/accordion/index.d.ts +3 -0
  5. package/dist/components/alert/Alert.d.ts +28 -0
  6. package/dist/components/alert/Alert.js +2 -0
  7. package/dist/components/alert/index.d.ts +3 -0
  8. package/dist/components/avatar/Avatar.d.ts +24 -0
  9. package/dist/components/avatar/Avatar.js +2 -0
  10. package/dist/components/avatar/AvatarSwitcher.d.ts +46 -0
  11. package/dist/components/avatar/AvatarSwitcher.js +2 -0
  12. package/dist/components/avatar/index.d.ts +4 -0
  13. package/dist/components/back-to-top/BackToTop.d.ts +21 -0
  14. package/dist/components/back-to-top/BackToTop.js +2 -0
  15. package/dist/components/back-to-top/index.d.ts +3 -0
  16. package/dist/components/badge/Badge.d.ts +20 -0
  17. package/dist/components/badge/Badge.js +2 -0
  18. package/dist/components/badge/index.d.ts +3 -0
  19. package/dist/components/bracket-title/BracketTitle.d.ts +17 -0
  20. package/dist/components/bracket-title/BracketTitle.js +2 -0
  21. package/dist/components/bracket-title/index.d.ts +3 -0
  22. package/dist/components/breadcrumb/Breadcrumb.d.ts +26 -0
  23. package/dist/components/breadcrumb/Breadcrumb.js +2 -0
  24. package/dist/components/breadcrumb/index.d.ts +3 -0
  25. package/dist/components/button/Button.d.ts +50 -0
  26. package/dist/components/button/Button.js +2 -0
  27. package/dist/components/button/ButtonGroup.d.ts +21 -0
  28. package/dist/components/button/ButtonGroup.js +2 -0
  29. package/dist/components/button/index.d.ts +4 -0
  30. package/dist/components/calendar/Calendar.d.ts +57 -0
  31. package/dist/components/calendar/Calendar.js +2 -0
  32. package/dist/components/calendar/index.d.ts +3 -0
  33. package/dist/components/carousel/Carousel.d.ts +38 -0
  34. package/dist/components/carousel/Carousel.js +2 -0
  35. package/dist/components/carousel/index.d.ts +3 -0
  36. package/dist/components/carousel/snap-track.js +2 -0
  37. package/dist/components/checkbox/Checkbox.d.ts +18 -0
  38. package/dist/components/checkbox/Checkbox.js +2 -0
  39. package/dist/components/checkbox/choice-style.js +2 -0
  40. package/dist/components/checkbox/index.d.ts +3 -0
  41. package/dist/components/chip/FilterChip.d.ts +18 -0
  42. package/dist/components/chip/FilterChip.js +2 -0
  43. package/dist/components/chip/ResourceChip.d.ts +16 -0
  44. package/dist/components/chip/ResourceChip.js +2 -0
  45. package/dist/components/chip/capsule-style.d.ts +4 -0
  46. package/dist/components/chip/capsule-style.js +2 -0
  47. package/dist/components/chip/index.d.ts +4 -0
  48. package/dist/components/combobox/Combobox.d.ts +105 -0
  49. package/dist/components/combobox/Combobox.js +2 -0
  50. package/dist/components/combobox/index.d.ts +3 -0
  51. package/dist/components/completion-banner/CompletionBanner.d.ts +26 -0
  52. package/dist/components/completion-banner/CompletionBanner.js +2 -0
  53. package/dist/components/completion-banner/index.d.ts +3 -0
  54. package/dist/components/context-menu/ContextMenu.d.ts +30 -0
  55. package/dist/components/context-menu/ContextMenu.js +2 -0
  56. package/dist/components/context-menu/index.d.ts +3 -0
  57. package/dist/components/corner-brackets/CornerBrackets.d.ts +20 -0
  58. package/dist/components/corner-brackets/CornerBrackets.js +2 -0
  59. package/dist/components/corner-brackets/index.d.ts +3 -0
  60. package/dist/components/countdown/Countdown.d.ts +26 -0
  61. package/dist/components/countdown/Countdown.js +2 -0
  62. package/dist/components/countdown/index.d.ts +3 -0
  63. package/dist/components/dash-indicator/DashIndicator.d.ts +15 -0
  64. package/dist/components/dash-indicator/DashIndicator.js +2 -0
  65. package/dist/components/dash-indicator/index.d.ts +3 -0
  66. package/dist/components/data-row/DataRow.d.ts +58 -0
  67. package/dist/components/data-row/DataRow.js +2 -0
  68. package/dist/components/data-row/index.d.ts +3 -0
  69. package/dist/components/date-picker/DateField.js +2 -0
  70. package/dist/components/date-picker/DatePicker.d.ts +56 -0
  71. package/dist/components/date-picker/DatePicker.js +2 -0
  72. package/dist/components/date-picker/DateRangePicker.d.ts +57 -0
  73. package/dist/components/date-picker/DateRangePicker.js +2 -0
  74. package/dist/components/date-picker/index.d.ts +4 -0
  75. package/dist/components/dialog/Dialog.d.ts +55 -0
  76. package/dist/components/dialog/Dialog.js +2 -0
  77. package/dist/components/dialog/index.d.ts +3 -0
  78. package/dist/components/dialog/initial-focus.js +2 -0
  79. package/dist/components/dialog/overlay-style.js +2 -0
  80. package/dist/components/drawer/Drawer.d.ts +48 -0
  81. package/dist/components/drawer/Drawer.js +2 -0
  82. package/dist/components/drawer/index.d.ts +3 -0
  83. package/dist/components/dropdown-menu/DropdownMenu.d.ts +115 -0
  84. package/dist/components/dropdown-menu/DropdownMenu.js +2 -0
  85. package/dist/components/dropdown-menu/MenuCheck.js +2 -0
  86. package/dist/components/dropdown-menu/index.d.ts +3 -0
  87. package/dist/components/dropdown-menu/menu-style.d.ts +4 -0
  88. package/dist/components/dropdown-menu/menu-style.js +2 -0
  89. package/dist/components/empty-state/EmptyState.d.ts +22 -0
  90. package/dist/components/empty-state/EmptyState.js +2 -0
  91. package/dist/components/empty-state/index.d.ts +3 -0
  92. package/dist/components/field/Field.d.ts +58 -0
  93. package/dist/components/field/Field.js +2 -0
  94. package/dist/components/field/index.d.ts +3 -0
  95. package/dist/components/file-upload/FileItem.d.ts +50 -0
  96. package/dist/components/file-upload/FileItem.js +2 -0
  97. package/dist/components/file-upload/FileUpload.d.ts +82 -0
  98. package/dist/components/file-upload/FileUpload.js +2 -0
  99. package/dist/components/file-upload/index.d.ts +4 -0
  100. package/dist/components/flyout-bar/FlyoutBar.d.ts +46 -0
  101. package/dist/components/flyout-bar/FlyoutBar.js +2 -0
  102. package/dist/components/flyout-bar/index.d.ts +3 -0
  103. package/dist/components/ghost-text/GhostText.d.ts +21 -0
  104. package/dist/components/ghost-text/GhostText.js +2 -0
  105. package/dist/components/ghost-text/index.d.ts +3 -0
  106. package/dist/components/hatch/Hatch.d.ts +18 -0
  107. package/dist/components/hatch/Hatch.js +2 -0
  108. package/dist/components/hatch/index.d.ts +3 -0
  109. package/dist/components/hazard-stripe/HazardStripe.d.ts +15 -0
  110. package/dist/components/hazard-stripe/HazardStripe.js +2 -0
  111. package/dist/components/hazard-stripe/index.d.ts +3 -0
  112. package/dist/components/hover-card/HoverCard.d.ts +35 -0
  113. package/dist/components/hover-card/HoverCard.js +2 -0
  114. package/dist/components/hover-card/index.d.ts +3 -0
  115. package/dist/components/icon-button/IconButton.d.ts +21 -0
  116. package/dist/components/icon-button/IconButton.js +2 -0
  117. package/dist/components/icon-button/index.d.ts +3 -0
  118. package/dist/components/image-viewer/ImageViewer.d.ts +48 -0
  119. package/dist/components/image-viewer/ImageViewer.js +2 -0
  120. package/dist/components/image-viewer/index.d.ts +3 -0
  121. package/dist/components/input/Input.d.ts +27 -0
  122. package/dist/components/input/Input.js +2 -0
  123. package/dist/components/input/control-box.d.ts +5 -0
  124. package/dist/components/input/control-box.js +2 -0
  125. package/dist/components/input/index.d.ts +3 -0
  126. package/dist/components/input/value-chip.js +2 -0
  127. package/dist/components/item-slot/ItemGrid.d.ts +12 -0
  128. package/dist/components/item-slot/ItemGrid.js +2 -0
  129. package/dist/components/item-slot/ItemSlot.d.ts +54 -0
  130. package/dist/components/item-slot/ItemSlot.js +2 -0
  131. package/dist/components/item-slot/index.d.ts +4 -0
  132. package/dist/components/kbd/Kbd.d.ts +15 -0
  133. package/dist/components/kbd/Kbd.js +2 -0
  134. package/dist/components/kbd/index.d.ts +3 -0
  135. package/dist/components/link-element/LinkElement.d.ts +6 -0
  136. package/dist/components/link-element/LinkElement.js +2 -0
  137. package/dist/components/list/List.d.ts +46 -0
  138. package/dist/components/list/List.js +2 -0
  139. package/dist/components/list/band-style.js +2 -0
  140. package/dist/components/list/index.d.ts +3 -0
  141. package/dist/components/loader/Loader.d.ts +23 -0
  142. package/dist/components/loader/Loader.js +2 -0
  143. package/dist/components/loader/index.d.ts +3 -0
  144. package/dist/components/marquee/Marquee.d.ts +22 -0
  145. package/dist/components/marquee/Marquee.js +2 -0
  146. package/dist/components/marquee/index.d.ts +3 -0
  147. package/dist/components/media-card/MediaCard.d.ts +36 -0
  148. package/dist/components/media-card/MediaCard.js +2 -0
  149. package/dist/components/media-card/index.d.ts +3 -0
  150. package/dist/components/nav-action/NavAction.d.ts +34 -0
  151. package/dist/components/nav-action/NavAction.js +2 -0
  152. package/dist/components/nav-action/index.d.ts +3 -0
  153. package/dist/components/nav-menu/NavMenu.d.ts +57 -0
  154. package/dist/components/nav-menu/NavMenu.js +2 -0
  155. package/dist/components/nav-menu/index.d.ts +3 -0
  156. package/dist/components/navigator/Navigator.d.ts +27 -0
  157. package/dist/components/navigator/Navigator.js +2 -0
  158. package/dist/components/navigator/index.d.ts +3 -0
  159. package/dist/components/otp-input/OtpInput.d.ts +52 -0
  160. package/dist/components/otp-input/OtpInput.js +2 -0
  161. package/dist/components/otp-input/index.d.ts +3 -0
  162. package/dist/components/page-header/PageHeader.d.ts +56 -0
  163. package/dist/components/page-header/PageHeader.js +2 -0
  164. package/dist/components/page-header/index.d.ts +3 -0
  165. package/dist/components/pagination/Pagination.d.ts +29 -0
  166. package/dist/components/pagination/Pagination.js +2 -0
  167. package/dist/components/pagination/index.d.ts +3 -0
  168. package/dist/components/panel/Panel.d.ts +36 -0
  169. package/dist/components/panel/Panel.js +2 -0
  170. package/dist/components/panel/index.d.ts +3 -0
  171. package/dist/components/play-button/PlayButton.d.ts +20 -0
  172. package/dist/components/play-button/PlayButton.js +2 -0
  173. package/dist/components/play-button/index.d.ts +3 -0
  174. package/dist/components/popover/Popover.d.ts +36 -0
  175. package/dist/components/popover/Popover.js +2 -0
  176. package/dist/components/popover/index.d.ts +3 -0
  177. package/dist/components/popover/panel-style.js +2 -0
  178. package/dist/components/progress/Progress.d.ts +27 -0
  179. package/dist/components/progress/Progress.js +2 -0
  180. package/dist/components/progress/ProgressRing.d.ts +23 -0
  181. package/dist/components/progress/ProgressRing.js +2 -0
  182. package/dist/components/progress/index.d.ts +4 -0
  183. package/dist/components/radio/Radio.d.ts +33 -0
  184. package/dist/components/radio/Radio.js +2 -0
  185. package/dist/components/radio/index.d.ts +3 -0
  186. package/dist/components/rec-indicator/RecIndicator.d.ts +16 -0
  187. package/dist/components/rec-indicator/RecIndicator.js +2 -0
  188. package/dist/components/rec-indicator/index.d.ts +3 -0
  189. package/dist/components/registration-strip/RegistrationStrip.d.ts +16 -0
  190. package/dist/components/registration-strip/RegistrationStrip.js +2 -0
  191. package/dist/components/registration-strip/index.d.ts +3 -0
  192. package/dist/components/rolling-number/RollingNumber.d.ts +25 -0
  193. package/dist/components/rolling-number/RollingNumber.js +2 -0
  194. package/dist/components/rolling-number/index.d.ts +3 -0
  195. package/dist/components/schedule/Schedule.d.ts +78 -0
  196. package/dist/components/schedule/Schedule.js +2 -0
  197. package/dist/components/schedule/index.d.ts +3 -0
  198. package/dist/components/scroll-area/ScrollArea.d.ts +26 -0
  199. package/dist/components/scroll-area/ScrollArea.js +2 -0
  200. package/dist/components/scroll-area/index.d.ts +3 -0
  201. package/dist/components/scroll-hint/ScrollHint.d.ts +23 -0
  202. package/dist/components/scroll-hint/ScrollHint.js +2 -0
  203. package/dist/components/scroll-hint/index.d.ts +3 -0
  204. package/dist/components/section-title/SectionTitle.d.ts +33 -0
  205. package/dist/components/section-title/SectionTitle.js +2 -0
  206. package/dist/components/section-title/index.d.ts +3 -0
  207. package/dist/components/segmented-control/SegmentedControl.d.ts +49 -0
  208. package/dist/components/segmented-control/SegmentedControl.js +2 -0
  209. package/dist/components/segmented-control/index.d.ts +3 -0
  210. package/dist/components/select/Select.d.ts +95 -0
  211. package/dist/components/select/Select.js +2 -0
  212. package/dist/components/select/index.d.ts +3 -0
  213. package/dist/components/side-rail/SideRail.d.ts +62 -0
  214. package/dist/components/side-rail/SideRail.js +2 -0
  215. package/dist/components/side-rail/SideRailSub.d.ts +47 -0
  216. package/dist/components/side-rail/SideRailSub.js +2 -0
  217. package/dist/components/side-rail/index.d.ts +4 -0
  218. package/dist/components/skeleton/Skeleton.d.ts +22 -0
  219. package/dist/components/skeleton/Skeleton.js +2 -0
  220. package/dist/components/skeleton/index.d.ts +3 -0
  221. package/dist/components/slider/Slider.d.ts +63 -0
  222. package/dist/components/slider/Slider.js +2 -0
  223. package/dist/components/slider/index.d.ts +3 -0
  224. package/dist/components/sparkline/Sparkline.d.ts +32 -0
  225. package/dist/components/sparkline/Sparkline.js +2 -0
  226. package/dist/components/sparkline/index.d.ts +3 -0
  227. package/dist/components/spinner/Spinner.d.ts +19 -0
  228. package/dist/components/spinner/Spinner.js +2 -0
  229. package/dist/components/spinner/index.d.ts +3 -0
  230. package/dist/components/splash-screen/SplashScreen.d.ts +43 -0
  231. package/dist/components/splash-screen/SplashScreen.js +2 -0
  232. package/dist/components/splash-screen/index.d.ts +3 -0
  233. package/dist/components/stat/Stat.d.ts +22 -0
  234. package/dist/components/stat/Stat.js +2 -0
  235. package/dist/components/stat/index.d.ts +3 -0
  236. package/dist/components/stepper/Stepper.d.ts +29 -0
  237. package/dist/components/stepper/Stepper.js +2 -0
  238. package/dist/components/stepper/index.d.ts +3 -0
  239. package/dist/components/steps/Steps.d.ts +55 -0
  240. package/dist/components/steps/Steps.js +2 -0
  241. package/dist/components/steps/index.d.ts +3 -0
  242. package/dist/components/switch/Switch.d.ts +28 -0
  243. package/dist/components/switch/Switch.js +2 -0
  244. package/dist/components/switch/index.d.ts +3 -0
  245. package/dist/components/table/Table.d.ts +96 -0
  246. package/dist/components/table/Table.js +2 -0
  247. package/dist/components/table/index.d.ts +3 -0
  248. package/dist/components/tabs/Tabs.d.ts +39 -0
  249. package/dist/components/tabs/Tabs.js +2 -0
  250. package/dist/components/tabs/index.d.ts +3 -0
  251. package/dist/components/tag/Tag.d.ts +25 -0
  252. package/dist/components/tag/Tag.js +2 -0
  253. package/dist/components/tag/TagPair.d.ts +16 -0
  254. package/dist/components/tag/TagPair.js +2 -0
  255. package/dist/components/tag/index.d.ts +4 -0
  256. package/dist/components/tag-input/TagInput.d.ts +66 -0
  257. package/dist/components/tag-input/TagInput.js +3 -0
  258. package/dist/components/tag-input/index.d.ts +3 -0
  259. package/dist/components/term/Term.d.ts +19 -0
  260. package/dist/components/term/Term.js +2 -0
  261. package/dist/components/term/index.d.ts +3 -0
  262. package/dist/components/textarea/Textarea.d.ts +17 -0
  263. package/dist/components/textarea/Textarea.js +2 -0
  264. package/dist/components/textarea/index.d.ts +3 -0
  265. package/dist/components/texture/Texture.d.ts +19 -0
  266. package/dist/components/texture/Texture.js +2 -0
  267. package/dist/components/texture/index.d.ts +3 -0
  268. package/dist/components/tick-ring/TickRing.d.ts +22 -0
  269. package/dist/components/tick-ring/TickRing.js +2 -0
  270. package/dist/components/tick-ring/index.d.ts +3 -0
  271. package/dist/components/timeline/Timeline.d.ts +22 -0
  272. package/dist/components/timeline/Timeline.js +2 -0
  273. package/dist/components/timeline/index.d.ts +3 -0
  274. package/dist/components/toast/Toast.d.ts +45 -0
  275. package/dist/components/toast/Toast.js +2 -0
  276. package/dist/components/toast/index.d.ts +3 -0
  277. package/dist/components/toc/Toc.d.ts +46 -0
  278. package/dist/components/toc/Toc.js +2 -0
  279. package/dist/components/toc/index.d.ts +3 -0
  280. package/dist/components/toolbar/Toolbar.d.ts +97 -0
  281. package/dist/components/toolbar/Toolbar.js +2 -0
  282. package/dist/components/toolbar/index.d.ts +3 -0
  283. package/dist/components/tooltip/Tooltip.d.ts +47 -0
  284. package/dist/components/tooltip/Tooltip.js +2 -0
  285. package/dist/components/tooltip/index.d.ts +3 -0
  286. package/dist/components/top-bar/TopBar.d.ts +21 -0
  287. package/dist/components/top-bar/TopBar.js +2 -0
  288. package/dist/components/top-bar/index.d.ts +3 -0
  289. package/dist/components/viewfinder/Viewfinder.d.ts +35 -0
  290. package/dist/components/viewfinder/Viewfinder.js +2 -0
  291. package/dist/components/viewfinder/index.d.ts +3 -0
  292. package/dist/game/animated-dialog/AnimatedDialog.d.ts +53 -0
  293. package/dist/game/animated-dialog/AnimatedDialog.js +2 -0
  294. package/dist/game/animated-dialog/index.d.ts +3 -0
  295. package/dist/game/banner-alert/AlertIcons.js +2 -0
  296. package/dist/game/banner-alert/AlertModal.js +2 -0
  297. package/dist/game/banner-alert/BannerAlert.d.ts +6 -0
  298. package/dist/game/banner-alert/BannerAlert.js +2 -0
  299. package/dist/game/banner-alert/index.d.ts +3 -0
  300. package/dist/game/banner-alert/types.d.ts +48 -0
  301. package/dist/game/banner-alert/types.js +2 -0
  302. package/dist/game/banner-alert/useAlertActions.js +2 -0
  303. package/dist/game/banner-alert/useAlertGlitch.js +2 -0
  304. package/dist/game/full-width-alert/FullWidthAlert.d.ts +7 -0
  305. package/dist/game/full-width-alert/FullWidthAlert.js +2 -0
  306. package/dist/game/full-width-alert/index.d.ts +3 -0
  307. package/dist/game/item-card/ItemCard.d.ts +48 -0
  308. package/dist/game/item-card/ItemCard.js +2 -0
  309. package/dist/game/item-card/index.d.ts +3 -0
  310. package/dist/game/item-hover-card/ItemHoverCard.d.ts +31 -0
  311. package/dist/game/item-hover-card/ItemHoverCard.js +2 -0
  312. package/dist/game/item-hover-card/events.js +2 -0
  313. package/dist/game/item-hover-card/index.d.ts +3 -0
  314. package/dist/game/item-icon/ItemIcon.d.ts +5 -0
  315. package/dist/game/item-icon/ItemIcon.js +2 -0
  316. package/dist/game/item-icon/helpers.d.ts +22 -0
  317. package/dist/game/item-icon/helpers.js +2 -0
  318. package/dist/game/item-icon/index.d.ts +5 -0
  319. package/dist/game/item-icon/types.d.ts +32 -0
  320. package/dist/game/item-tooltip-card/ItemTooltipCard.d.ts +6 -0
  321. package/dist/game/item-tooltip-card/ItemTooltipCard.js +2 -0
  322. package/dist/game/item-tooltip-card/icons.js +2 -0
  323. package/dist/game/item-tooltip-card/index.d.ts +4 -0
  324. package/dist/game/item-tooltip-card/types.d.ts +40 -0
  325. package/dist/game/lib/core.d.ts +8 -0
  326. package/dist/game/lib/first-focusable.js +2 -0
  327. package/dist/game/rounded-button/RoundedButton.d.ts +22 -0
  328. package/dist/game/rounded-button/RoundedButton.js +2 -0
  329. package/dist/game/rounded-button/RoundedIconButton.d.ts +10 -0
  330. package/dist/game/rounded-button/RoundedIconButton.js +2 -0
  331. package/dist/game/rounded-button/index.d.ts +4 -0
  332. package/dist/game/rounded-select/RoundedSelect.d.ts +43 -0
  333. package/dist/game/rounded-select/RoundedSelect.js +2 -0
  334. package/dist/game/rounded-select/index.d.ts +3 -0
  335. package/dist/game/rounded-switch/RoundedSwitch.d.ts +16 -0
  336. package/dist/game/rounded-switch/RoundedSwitch.js +2 -0
  337. package/dist/game/rounded-switch/index.d.ts +3 -0
  338. package/dist/game/rounded-toggle/RoundedToggle.d.ts +23 -0
  339. package/dist/game/rounded-toggle/RoundedToggle.js +2 -0
  340. package/dist/game/rounded-toggle/index.d.ts +3 -0
  341. package/dist/game/rounded-toggle/keyboard.js +2 -0
  342. package/dist/game/rounded-toggle/spring-highlight.js +2 -0
  343. package/dist/game/splash-screen/EndfieldSplashScreen.d.ts +14 -0
  344. package/dist/game/splash-screen/EndfieldSplashScreen.js +2 -0
  345. package/dist/game/splash-screen/index.d.ts +3 -0
  346. package/dist/game.d.ts +29 -383
  347. package/dist/game.js +1 -2068
  348. package/dist/hooks/index.d.ts +7 -0
  349. package/dist/hooks/useAddedKeys.js +2 -0
  350. package/dist/hooks/useControllableState.d.ts +12 -0
  351. package/dist/hooks/useControllableState.js +2 -0
  352. package/dist/hooks/useFlip.js +2 -0
  353. package/dist/hooks/useInView.d.ts +15 -0
  354. package/dist/hooks/useInView.js +2 -0
  355. package/dist/hooks/useIndicator.js +2 -0
  356. package/dist/hooks/useLingering.js +2 -0
  357. package/dist/hooks/useOverflowing.js +2 -0
  358. package/dist/hooks/usePortalScope.d.ts +26 -0
  359. package/dist/hooks/usePortalScope.js +2 -0
  360. package/dist/hooks/usePresence.js +2 -0
  361. package/dist/hooks/useReducedMotion.d.ts +10 -0
  362. package/dist/hooks/useReducedMotion.js +2 -0
  363. package/dist/hooks/useScrollPosition.js +2 -0
  364. package/dist/hooks/useTheme.d.ts +21 -0
  365. package/dist/hooks/useTheme.js +2 -0
  366. package/dist/icons/ArrowCorner.d.ts +9 -0
  367. package/dist/icons/ArrowCorner.js +2 -0
  368. package/dist/icons/ArrowLeft.d.ts +8 -0
  369. package/dist/icons/ArrowLeft.js +2 -0
  370. package/dist/icons/ArrowRight.d.ts +8 -0
  371. package/dist/icons/ArrowRight.js +2 -0
  372. package/dist/icons/CalendarIcon.d.ts +12 -0
  373. package/dist/icons/CalendarIcon.js +2 -0
  374. package/dist/icons/Check.d.ts +9 -0
  375. package/dist/icons/Check.js +2 -0
  376. package/dist/icons/ChevronDown.d.ts +8 -0
  377. package/dist/icons/ChevronDown.js +2 -0
  378. package/dist/icons/ChevronLeft.d.ts +8 -0
  379. package/dist/icons/ChevronLeft.js +2 -0
  380. package/dist/icons/ChevronRight.d.ts +8 -0
  381. package/dist/icons/ChevronRight.js +2 -0
  382. package/dist/icons/Close.d.ts +8 -0
  383. package/dist/icons/Close.js +2 -0
  384. package/dist/icons/Crosshair.d.ts +9 -0
  385. package/dist/icons/Crosshair.js +2 -0
  386. package/dist/icons/Lock.d.ts +8 -0
  387. package/dist/icons/Lock.js +2 -0
  388. package/dist/icons/Menu.d.ts +9 -0
  389. package/dist/icons/Menu.js +2 -0
  390. package/dist/icons/Minus.d.ts +9 -0
  391. package/dist/icons/Minus.js +2 -0
  392. package/dist/icons/Plus.d.ts +8 -0
  393. package/dist/icons/Plus.js +2 -0
  394. package/dist/icons/StatusDanger.d.ts +9 -0
  395. package/dist/icons/StatusDanger.js +2 -0
  396. package/dist/icons/StatusInfo.d.ts +9 -0
  397. package/dist/icons/StatusInfo.js +2 -0
  398. package/dist/icons/StatusSuccess.d.ts +9 -0
  399. package/dist/icons/StatusSuccess.js +2 -0
  400. package/dist/icons/StatusWarning.d.ts +9 -0
  401. package/dist/icons/StatusWarning.js +2 -0
  402. package/dist/icons/TriangleRight.d.ts +9 -0
  403. package/dist/icons/TriangleRight.js +2 -0
  404. package/dist/icons/Upload.d.ts +9 -0
  405. package/dist/icons/Upload.js +2 -0
  406. package/dist/icons/createIcon.d.ts +16 -0
  407. package/dist/icons/createIcon.js +2 -0
  408. package/dist/icons/index.d.ts +23 -0
  409. package/dist/index.d.ts +209 -3546
  410. package/dist/index.js +1 -9848
  411. package/dist/lib/cn.d.ts +5 -0
  412. package/dist/lib/cn.js +2 -0
  413. package/dist/lib/create-lazy-context.js +2 -0
  414. package/dist/lib/date.js +2 -0
  415. package/dist/lib/decor.js +2 -0
  416. package/dist/lib/defined.js +2 -0
  417. package/dist/lib/file.js +2 -0
  418. package/dist/lib/focus-ring.js +2 -0
  419. package/dist/lib/inline-style.js +2 -0
  420. package/dist/lib/merge-refs.js +2 -0
  421. package/dist/lib/motion.js +2 -0
  422. package/package.json +17 -11
  423. package/src/components/accordion/Accordion.tsx +13 -5
  424. package/src/components/avatar/AvatarSwitcher.tsx +7 -5
  425. package/src/components/carousel/Carousel.tsx +6 -5
  426. package/src/components/context-menu/ContextMenu.tsx +5 -2
  427. package/src/components/data-row/DataRow.tsx +10 -4
  428. package/src/components/date-picker/DateField.tsx +1 -1
  429. package/src/components/dropdown-menu/DropdownMenu.tsx +7 -4
  430. package/src/components/dropdown-menu/menu-style.ts +3 -2
  431. package/src/components/field/Field.tsx +10 -6
  432. package/src/components/flyout-bar/FlyoutBar.tsx +1 -1
  433. package/src/components/image-viewer/ImageViewer.tsx +6 -5
  434. package/src/components/list/List.tsx +7 -5
  435. package/src/components/nav-action/NavAction.tsx +4 -3
  436. package/src/components/nav-menu/NavMenu.tsx +13 -7
  437. package/src/components/radio/Radio.tsx +7 -5
  438. package/src/components/schedule/Schedule.tsx +7 -5
  439. package/src/components/segmented-control/SegmentedControl.tsx +7 -5
  440. package/src/components/select/Select.tsx +11 -9
  441. package/src/components/side-rail/SideRail.tsx +15 -9
  442. package/src/components/side-rail/SideRailSub.tsx +12 -7
  443. package/src/components/steps/Steps.tsx +7 -5
  444. package/src/components/table/Table.tsx +23 -17
  445. package/src/components/tabs/Tabs.tsx +7 -5
  446. package/src/components/toast/Toast.tsx +8 -5
  447. package/src/components/toc/Toc.tsx +5 -4
  448. package/src/components/toolbar/Toolbar.tsx +7 -6
  449. package/src/components/tooltip/Tooltip.tsx +7 -4
  450. package/src/components/top-bar/TopBar.tsx +7 -2
  451. package/src/icons/ArrowCorner.tsx +1 -1
  452. package/src/icons/ArrowLeft.tsx +1 -1
  453. package/src/icons/ArrowRight.tsx +1 -1
  454. package/src/icons/CalendarIcon.tsx +1 -1
  455. package/src/icons/Check.tsx +4 -1
  456. package/src/icons/ChevronDown.tsx +4 -1
  457. package/src/icons/ChevronLeft.tsx +1 -1
  458. package/src/icons/ChevronRight.tsx +1 -1
  459. package/src/icons/Close.tsx +4 -1
  460. package/src/icons/Crosshair.tsx +1 -1
  461. package/src/icons/Lock.tsx +1 -1
  462. package/src/icons/Menu.tsx +4 -1
  463. package/src/icons/Minus.tsx +1 -1
  464. package/src/icons/Plus.tsx +4 -1
  465. package/src/icons/StatusDanger.tsx +1 -1
  466. package/src/icons/StatusInfo.tsx +1 -1
  467. package/src/icons/StatusSuccess.tsx +1 -1
  468. package/src/icons/StatusWarning.tsx +1 -1
  469. package/src/icons/TriangleRight.tsx +1 -1
  470. package/src/icons/Upload.tsx +1 -1
  471. package/src/lib/cn.ts +1 -1
  472. package/src/lib/create-lazy-context.ts +6 -0
  473. package/src/components/README.md +0 -191
  474. package/src/hooks/README.md +0 -20
  475. package/src/icons/README.md +0 -31
  476. package/src/lib/README.md +0 -19
  477. package/src/styles/README.md +0 -77
package/dist/game.js CHANGED
@@ -1,2069 +1,2 @@
1
1
  "use client";
2
- import { Dialog } from "@base-ui/react/dialog";
3
- import { Fragment, memo, useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
4
- import { SplashScreen, cn, useControllableState, useFieldContext, useFieldControl, usePortalScope, useReducedMotion } from "./index.js";
5
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
- import { ScrollArea } from "@base-ui/react/scroll-area";
7
- import { Popover } from "@base-ui/react/popover";
8
- import { flushSync } from "react-dom";
9
- import { Select } from "@base-ui/react/select";
10
- import { Radio } from "@base-ui/react/radio";
11
- import { RadioGroup } from "@base-ui/react/radio-group";
12
- //#region src/game/lib/first-focusable.ts
13
- const FOCUSABLE = [
14
- "a[href]",
15
- "button:not([disabled])",
16
- "input:not([disabled]):not([type=\"hidden\"])",
17
- "select:not([disabled])",
18
- "textarea:not([disabled])",
19
- "[tabindex]:not([tabindex=\"-1\"])"
20
- ].join(",");
21
- /**
22
- * 弹窗打开时焦点落在哪:内容区里第一个能聚焦的元素;没有时返回 `true`,交还给默认行为。
23
- *
24
- * 和主库 `components/dialog/initial-focus.ts` 是同一条规则。那边不是公开导出,
25
- * 这一类又只经主入口用主库(见 `core.ts`),所以这里自己留一份。
26
- */
27
- function firstFocusableIn(content) {
28
- return () => content.current?.querySelector(FOCUSABLE) ?? true;
29
- }
30
- //#endregion
31
- //#region src/game/animated-dialog/AnimatedDialog.tsx
32
- function slotClass(value, open) {
33
- return typeof value === "function" ? value(open) : value;
34
- }
35
- function AnimatedDialog({ trigger, open: controlledOpen, defaultOpen = false, onOpenChange, title, description, icon, width, height, className, classNames, dismissible = true, keyboardCloseable, onClose, onDismiss, closeLabel = "关闭", initialFocus, finalFocus, keepMounted = false, modal, container, children, ...popupProps }) {
36
- const [internalOpen, setInternalOpen] = useState(defaultOpen);
37
- const open = controlledOpen ?? internalOpen;
38
- const [pending, setPending] = useState(false);
39
- const lifecycle = useRef({
40
- open,
41
- session: 0,
42
- locked: false,
43
- mounted: true
44
- });
45
- const contentRef = useRef(null);
46
- const { anchorRef, portalRef } = usePortalScope();
47
- const focusContent = useCallback(() => firstFocusableIn(contentRef)(), []);
48
- useLayoutEffect(() => {
49
- const current = lifecycle.current;
50
- current.mounted = true;
51
- return () => {
52
- current.mounted = false;
53
- current.session += 1;
54
- current.locked = false;
55
- };
56
- }, []);
57
- useLayoutEffect(() => {
58
- if (lifecycle.current.open === open) return;
59
- lifecycle.current.open = open;
60
- lifecycle.current.session += 1;
61
- lifecycle.current.locked = false;
62
- setPending(false);
63
- }, [open]);
64
- const updateOpen = useCallback((next) => {
65
- if (controlledOpen === void 0) setInternalOpen(next);
66
- onOpenChange?.(next);
67
- }, [controlledOpen, onOpenChange]);
68
- const requestClose = useCallback(async (dismiss) => {
69
- const current = lifecycle.current;
70
- if (!current.open || current.locked || !current.mounted) return;
71
- current.locked = true;
72
- const session = current.session;
73
- setPending(true);
74
- const active = () => lifecycle.current.mounted && lifecycle.current.open && lifecycle.current.session === session;
75
- try {
76
- if (dismiss) {
77
- if (await onDismiss?.() === false || !active()) return;
78
- }
79
- if (await onClose?.() !== false && active()) updateOpen(false);
80
- } catch {} finally {
81
- if (active()) {
82
- lifecycle.current.locked = false;
83
- setPending(false);
84
- }
85
- }
86
- }, [
87
- onClose,
88
- onDismiss,
89
- updateOpen
90
- ]);
91
- const handleOpenChange = (next, details) => {
92
- if (next) {
93
- updateOpen(true);
94
- return;
95
- }
96
- details.cancel();
97
- if (details.reason === "escape-key" && !(keyboardCloseable ?? dismissible)) return;
98
- const dismiss = details.reason === "escape-key" || details.reason === "outside-press" || details.reason === "focus-out";
99
- if (dismiss && details.reason !== "escape-key" && !dismissible) return;
100
- requestClose(dismiss);
101
- };
102
- return /* @__PURE__ */ jsxs(Dialog.Root, {
103
- open,
104
- onOpenChange: handleOpenChange,
105
- disablePointerDismissal: !dismissible,
106
- modal,
107
- children: [trigger && /* @__PURE__ */ jsx(Dialog.Trigger, {
108
- ref: anchorRef,
109
- render: trigger
110
- }), /* @__PURE__ */ jsxs(Dialog.Portal, {
111
- ref: portalRef,
112
- keepMounted,
113
- container,
114
- children: [/* @__PURE__ */ jsx(Dialog.Backdrop, { className: cn("ef-animated-dialog-backdrop", slotClass(classNames?.backdrop, open)) }), /* @__PURE__ */ jsx(Dialog.Viewport, {
115
- className: "ef-animated-dialog-viewport",
116
- children: /* @__PURE__ */ jsxs(Dialog.Popup, {
117
- ...popupProps,
118
- "aria-busy": pending || void 0,
119
- initialFocus: initialFocus ?? focusContent,
120
- finalFocus,
121
- style: {
122
- width,
123
- height
124
- },
125
- className: cn("ef-animated-dialog", className, slotClass(classNames?.alert, open)),
126
- children: [
127
- /* @__PURE__ */ jsxs("header", {
128
- className: cn("ef-animated-dialog__header", slotClass(classNames?.header, open)),
129
- children: [
130
- /* @__PURE__ */ jsxs("div", {
131
- "aria-hidden": "true",
132
- className: "ef-animated-dialog__top-strip",
133
- children: [/* @__PURE__ */ jsx("span", { className: "ef-animated-dialog__yellow-block" }), /* @__PURE__ */ jsxs("span", {
134
- className: "ef-animated-dialog__top-deco",
135
- children: [/* @__PURE__ */ jsxs("svg", {
136
- viewBox: "0 0 120 10",
137
- children: [
138
- /* @__PURE__ */ jsx("polygon", {
139
- points: "0,2 7,2 3.5,8",
140
- fill: "currentColor"
141
- }),
142
- /* @__PURE__ */ jsx("text", {
143
- x: "7",
144
- y: "7",
145
- fontSize: "7",
146
- fontStyle: "italic",
147
- children: "//"
148
- }),
149
- /* @__PURE__ */ jsx("text", {
150
- x: "16",
151
- y: "7",
152
- fontSize: "7",
153
- children: "ARKNIGHTS:ENDFIELD"
154
- })
155
- ]
156
- }), /* @__PURE__ */ jsxs("svg", {
157
- viewBox: "0 0 10 10",
158
- className: "ef-animated-dialog__plus",
159
- children: [/* @__PURE__ */ jsx("rect", {
160
- x: "0.5",
161
- y: "0.5",
162
- width: "9",
163
- height: "9",
164
- fill: "none",
165
- stroke: "currentColor"
166
- }), /* @__PURE__ */ jsx("path", {
167
- d: "M5 2.5v5M2.5 5h5",
168
- stroke: "currentColor"
169
- })]
170
- })]
171
- })]
172
- }),
173
- /* @__PURE__ */ jsxs("div", {
174
- className: "ef-animated-dialog__title-band",
175
- children: [
176
- /* @__PURE__ */ jsx("div", {
177
- "aria-hidden": "true",
178
- className: "ef-animated-dialog__icon-slot",
179
- children: /* @__PURE__ */ jsx("span", {
180
- className: "ef-animated-dialog__icon",
181
- children: icon
182
- })
183
- }),
184
- /* @__PURE__ */ jsx(Dialog.Title, {
185
- className: cn("ef-animated-dialog__title", slotClass(classNames?.title, open)),
186
- children: /* @__PURE__ */ jsx("span", { children: title })
187
- }),
188
- /* @__PURE__ */ jsx("span", {
189
- "aria-hidden": "true",
190
- className: "ef-animated-dialog__title-deco",
191
- children: "ENDFIELD"
192
- })
193
- ]
194
- }),
195
- /* @__PURE__ */ jsx("div", {
196
- className: "ef-animated-dialog__close-motion",
197
- children: /* @__PURE__ */ jsx(Dialog.Close, {
198
- "aria-label": closeLabel,
199
- "aria-disabled": pending || void 0,
200
- className: cn("ef-animated-dialog__close", slotClass(classNames?.close, open)),
201
- children: /* @__PURE__ */ jsx("svg", {
202
- "aria-hidden": "true",
203
- viewBox: "0 0 205 205",
204
- fill: "currentColor",
205
- fillRule: "evenodd",
206
- children: /* @__PURE__ */ jsx("path", { d: "M0 25L25 0L205 180L180 205ZM25 205L0 180L180 0L205 25Z" })
207
- })
208
- })
209
- }),
210
- /* @__PURE__ */ jsx("div", {
211
- "aria-hidden": "true",
212
- className: "ef-animated-dialog__separator"
213
- })
214
- ]
215
- }),
216
- /* @__PURE__ */ jsxs("div", {
217
- "data-theme": "light",
218
- className: cn("ef-animated-dialog__content", slotClass(classNames?.contentContainer, open)),
219
- children: [/* @__PURE__ */ jsxs("div", {
220
- ref: contentRef,
221
- className: "ef-animated-dialog__body",
222
- children: [description && /* @__PURE__ */ jsx(Dialog.Description, {
223
- className: "ef-animated-dialog__description",
224
- children: description
225
- }), children]
226
- }), /* @__PURE__ */ jsx("span", {
227
- "aria-hidden": "true",
228
- className: "ef-animated-dialog__registration"
229
- })]
230
- }),
231
- /* @__PURE__ */ jsxs("footer", {
232
- "aria-hidden": "true",
233
- className: cn("ef-animated-dialog__footer", slotClass(classNames?.footer, open)),
234
- children: [
235
- /* @__PURE__ */ jsx("span", { className: "ef-animated-dialog__footer-square" }),
236
- /* @__PURE__ */ jsx("span", { className: "ef-animated-dialog__footer-outline" }),
237
- /* @__PURE__ */ jsx("span", { className: "ef-animated-dialog__footer-hatch" })
238
- ]
239
- })
240
- ]
241
- })
242
- })]
243
- })]
244
- });
245
- }
246
- //#endregion
247
- //#region src/game/rounded-button/RoundedButton.tsx
248
- const hoverColors = {
249
- primary: {
250
- enter: [
251
- "#2a272877",
252
- "#2a2728b5",
253
- "#2a272877",
254
- "#2a2728b5"
255
- ],
256
- leave: [
257
- "#2a2728b5",
258
- "#2a2728",
259
- "#2a2728b5",
260
- "#2a2728"
261
- ],
262
- enterBorder: [
263
- "#81807f",
264
- "#81807f",
265
- "#81807f",
266
- "#81807f"
267
- ],
268
- leaveBorder: [
269
- "#81807f",
270
- "#81807f",
271
- "#81807f",
272
- "#81807f"
273
- ]
274
- },
275
- default: {
276
- enter: [
277
- "#ececec77",
278
- "#e8e8e8b5",
279
- "#ececec77",
280
- "#e8e8e8b5"
281
- ],
282
- leave: [
283
- "#e8e8e8b5",
284
- "#f2f1ef",
285
- "#e8e8e8b5",
286
- "#f2f1ef"
287
- ],
288
- enterBorder: [
289
- "#a5a5a5",
290
- "#a5a5a5",
291
- "#a5a5a5",
292
- "#a5a5a5"
293
- ],
294
- leaveBorder: [
295
- "#a5a5a5",
296
- "#a0a2a3",
297
- "#a5a5a5",
298
- "#a0a2a3"
299
- ]
300
- }
301
- };
302
- /** 原灰色圆角按钮;悬停闪动由浏览器动画执行。 */
303
- function RoundedButton({ variant = "primary", type = "button", text = "", children, icon, showIcon = true, iconPosition = "right", loading = false, disabled = false, className, classNames, onClick, onPointerEnter, onPointerLeave, ...props }) {
304
- const reducedMotion = useReducedMotion();
305
- const animationRef = useRef(null);
306
- const isPrimary = variant === "primary";
307
- const slotClass = (slot) => typeof slot === "function" ? slot(isPrimary) : slot;
308
- useEffect(() => {
309
- if (disabled || loading || reducedMotion) animationRef.current?.cancel();
310
- return () => animationRef.current?.cancel();
311
- }, [
312
- disabled,
313
- loading,
314
- reducedMotion,
315
- variant
316
- ]);
317
- const animateHover = (event, entering) => {
318
- const button = event.currentTarget;
319
- if (disabled || loading || reducedMotion || event.defaultPrevented || event.pointerType !== "mouse" || typeof window.matchMedia !== "function" || !window.matchMedia("(hover: hover) and (pointer: fine)").matches || typeof button.animate !== "function") return;
320
- animationRef.current?.cancel();
321
- const colors = hoverColors[variant];
322
- const backgrounds = entering ? colors.enter : colors.leave;
323
- const borders = entering ? colors.enterBorder : colors.leaveBorder;
324
- animationRef.current = button.animate(backgrounds.map((backgroundColor, index) => ({
325
- backgroundColor,
326
- boxShadow: `0 0 0 0.1em ${backgroundColor}, 0 0 0 0.1em ${borders[index]} inset`
327
- })), {
328
- duration: 200,
329
- easing: "ease-out"
330
- });
331
- };
332
- const iconElement = showIcon && /* @__PURE__ */ jsx("span", {
333
- "aria-hidden": "true",
334
- className: cn("ef-rounded-button-icon", slotClass(classNames?.icon)),
335
- children: loading ? /* @__PURE__ */ jsx("span", { className: "ef-rounded-button-spinner" }) : icon
336
- });
337
- return /* @__PURE__ */ jsxs("button", {
338
- ...props,
339
- type,
340
- disabled,
341
- "aria-busy": loading || props["aria-busy"] || void 0,
342
- "aria-disabled": loading || props["aria-disabled"] || void 0,
343
- "data-variant": variant,
344
- "data-icon-position": iconPosition,
345
- "data-loading": loading ? "" : void 0,
346
- className: cn("ef-rounded-button", className, slotClass(classNames?.button)),
347
- onClick: (event) => {
348
- if (disabled || loading) {
349
- event.preventDefault();
350
- return;
351
- }
352
- onClick?.(event);
353
- },
354
- onPointerEnter: (event) => {
355
- onPointerEnter?.(event);
356
- animateHover(event, true);
357
- },
358
- onPointerLeave: (event) => {
359
- onPointerLeave?.(event);
360
- animateHover(event, false);
361
- },
362
- children: [
363
- iconPosition === "left" && iconElement,
364
- /* @__PURE__ */ jsx("span", {
365
- className: cn("ef-rounded-button-text", slotClass(classNames?.text)),
366
- children: children ?? text
367
- }),
368
- iconPosition === "right" && iconElement
369
- ]
370
- });
371
- }
372
- //#endregion
373
- //#region src/game/banner-alert/AlertIcons.tsx
374
- function AlertTickIcon() {
375
- return /* @__PURE__ */ jsx("svg", {
376
- viewBox: "0 0 24 24",
377
- fill: "none",
378
- width: "1em",
379
- height: "1em",
380
- "aria-hidden": "true",
381
- children: /* @__PURE__ */ jsx("path", {
382
- d: "M4.89163 13.2687L9.16582 17.5427L18.7085 8",
383
- stroke: "currentColor",
384
- strokeWidth: "3",
385
- strokeLinecap: "round",
386
- strokeLinejoin: "round"
387
- })
388
- });
389
- }
390
- function AlertCloseIcon() {
391
- return /* @__PURE__ */ jsx("svg", {
392
- viewBox: "0 0 1024 1024",
393
- width: "1em",
394
- height: "1em",
395
- "aria-hidden": "true",
396
- children: /* @__PURE__ */ jsx("path", {
397
- fill: "currentColor",
398
- d: "M195.2 195.2a64 64 0 0 1 90.496 0L512 421.504 738.304 195.2a64 64 0 0 1 90.496 90.496L602.496 512 828.8 738.304a64 64 0 0 1-90.496 90.496L512 602.496 285.696 828.8a64 64 0 0 1-90.496-90.496L421.504 512 195.2 285.696a64 64 0 0 1 0-90.496z"
399
- })
400
- });
401
- }
402
- //#endregion
403
- //#region src/game/banner-alert/types.ts
404
- function alertSlotClass(value, open) {
405
- return typeof value === "function" ? value(open) : value;
406
- }
407
- //#endregion
408
- //#region src/game/banner-alert/useAlertActions.ts
409
- function useAlertActions({ open: controlledOpen, defaultOpen = false, onOpenChange, loading = false, onConfirm, onCancel, onDismiss, onClose }) {
410
- const [internalOpen, setInternalOpen] = useState(defaultOpen);
411
- const [pending, setPending] = useState(false);
412
- const open = controlledOpen ?? internalOpen;
413
- const lifecycle = useRef({
414
- open,
415
- loading,
416
- mounted: true,
417
- locked: false,
418
- session: 0
419
- });
420
- useLayoutEffect(() => {
421
- const current = lifecycle.current;
422
- current.mounted = true;
423
- return () => {
424
- current.mounted = false;
425
- current.locked = false;
426
- current.session += 1;
427
- };
428
- }, []);
429
- useLayoutEffect(() => {
430
- lifecycle.current.loading = loading;
431
- if (lifecycle.current.open === open) return;
432
- lifecycle.current.open = open;
433
- lifecycle.current.session += 1;
434
- lifecycle.current.locked = false;
435
- setPending(false);
436
- }, [open, loading]);
437
- const updateOpen = useCallback((next) => {
438
- if (controlledOpen === void 0) setInternalOpen(next);
439
- onOpenChange?.(next);
440
- }, [controlledOpen, onOpenChange]);
441
- const run = useCallback(async (kind) => {
442
- const current = lifecycle.current;
443
- if (!current.open || !current.mounted || current.loading || current.locked) return;
444
- current.locked = true;
445
- setPending(true);
446
- const session = current.session;
447
- const active = () => lifecycle.current.mounted && lifecycle.current.open && lifecycle.current.session === session;
448
- try {
449
- const action = {
450
- confirm: onConfirm,
451
- cancel: onCancel,
452
- dismiss: onDismiss,
453
- close: void 0
454
- }[kind];
455
- if (await action?.() === false || !active()) return;
456
- if (await onClose?.() !== false && active()) updateOpen(false);
457
- } catch {} finally {
458
- if (active()) {
459
- lifecycle.current.locked = false;
460
- setPending(false);
461
- }
462
- }
463
- }, [
464
- onConfirm,
465
- onCancel,
466
- onDismiss,
467
- onClose,
468
- updateOpen
469
- ]);
470
- return {
471
- open,
472
- busy: loading || pending,
473
- updateOpen,
474
- run
475
- };
476
- }
477
- //#endregion
478
- //#region src/game/banner-alert/AlertModal.tsx
479
- function hasTabbableContent(popup) {
480
- const candidates = popup.querySelectorAll("a[href],button,input:not([type=\"hidden\"]),select,textarea,[tabindex],[contenteditable=\"true\"]");
481
- return Array.from(candidates).some((node) => {
482
- if (node.matches(":disabled") || node.hasAttribute("tabindex") && node.tabIndex < 0 || node.closest("[hidden],[inert],[aria-hidden=\"true\"]")) return false;
483
- const style = getComputedStyle(node);
484
- return style.display !== "none" && style.visibility !== "hidden";
485
- });
486
- }
487
- function AlertModal({ trigger, open: controlledOpen, defaultOpen, onOpenChange, title, description, dismissible = true, keyboardCloseable, loading, hideCancel = false, cancelText: _cancelText, confirmText: _confirmText, showIcon: _showIcon, width, height, className, classNames, onConfirm, onCancel, onDismiss, onClose, initialFocus, finalFocus, keepMounted = false, modal, container, popupClassName, backdropClassName, viewportClassName, children, ref: forwardedRef, ...popupProps }) {
488
- const { open, busy, updateOpen, run } = useAlertActions({
489
- open: controlledOpen,
490
- defaultOpen,
491
- onOpenChange,
492
- loading,
493
- onConfirm,
494
- onCancel,
495
- onDismiss,
496
- onClose
497
- });
498
- const { anchorRef, portalRef } = usePortalScope();
499
- const popupRef = useRef(null);
500
- const cancelRef = useRef(null);
501
- const confirmRef = useRef(null);
502
- const lastFocus = useRef(null);
503
- const wasBusy = useRef(false);
504
- const focusAction = useCallback(() => {
505
- const button = hideCancel ? confirmRef.current : cancelRef.current;
506
- return button && !button.disabled ? button : popupRef.current ?? true;
507
- }, [hideCancel]);
508
- const assignRef = useCallback((node) => {
509
- popupRef.current = node;
510
- if (typeof forwardedRef === "function") return forwardedRef(node);
511
- if (forwardedRef) forwardedRef.current = node;
512
- }, [forwardedRef]);
513
- useLayoutEffect(() => {
514
- const popup = popupRef.current;
515
- const previousBusy = wasBusy.current;
516
- wasBusy.current = busy;
517
- if (!open || !popup) return;
518
- const focused = popup.ownerDocument.activeElement;
519
- if (busy) {
520
- if (focused === popup.ownerDocument.body || focused instanceof HTMLElement && popup.contains(focused) && focused.matches(":disabled")) popup.focus({ preventScroll: true });
521
- } else if (previousBusy && focused === popup) {
522
- const previousFocus = lastFocus.current;
523
- if (previousFocus && popup.contains(previousFocus) && !previousFocus.matches(":disabled")) previousFocus.focus({ preventScroll: true });
524
- }
525
- }, [busy, open]);
526
- const changeOpen = (next, details) => {
527
- if (next) {
528
- updateOpen(true);
529
- return;
530
- }
531
- details.cancel();
532
- if (details.reason === "escape-key" && !(keyboardCloseable ?? dismissible)) return;
533
- const dismiss = details.reason === "escape-key" || details.reason === "outside-press" || details.reason === "focus-out";
534
- if (dismiss && details.reason !== "escape-key" && !dismissible) return;
535
- run(dismiss ? "dismiss" : "close");
536
- };
537
- return /* @__PURE__ */ jsxs(Dialog.Root, {
538
- open,
539
- onOpenChange: changeOpen,
540
- disablePointerDismissal: !dismissible || busy,
541
- modal,
542
- children: [trigger && /* @__PURE__ */ jsx(Dialog.Trigger, {
543
- ref: anchorRef,
544
- render: trigger
545
- }), /* @__PURE__ */ jsxs(Dialog.Portal, {
546
- ref: portalRef,
547
- keepMounted,
548
- container,
549
- children: [/* @__PURE__ */ jsx(Dialog.Backdrop, { className: cn(backdropClassName, alertSlotClass(classNames?.backdrop, open)) }), /* @__PURE__ */ jsx(Dialog.Viewport, {
550
- className: cn("ef-alert-modal-viewport", viewportClassName),
551
- children: /* @__PURE__ */ jsxs(Dialog.Popup, {
552
- ...popupProps,
553
- onFocusCapture: (event) => {
554
- popupProps.onFocusCapture?.(event);
555
- if (event.target instanceof HTMLElement && event.target !== event.currentTarget && event.currentTarget.contains(event.target)) lastFocus.current = event.target;
556
- },
557
- onKeyDownCapture: (event) => {
558
- popupProps.onKeyDownCapture?.(event);
559
- if (open && busy && event.key === "Tab" && event.target instanceof Node && event.currentTarget.contains(event.target) && !hasTabbableContent(event.currentTarget)) {
560
- event.preventDefault();
561
- event.currentTarget.focus({ preventScroll: true });
562
- }
563
- },
564
- ref: assignRef,
565
- role: "alertdialog",
566
- "aria-busy": busy || void 0,
567
- "data-theme": "light",
568
- initialFocus: initialFocus ?? focusAction,
569
- finalFocus,
570
- style: {
571
- width,
572
- height
573
- },
574
- className: cn(popupClassName, className, alertSlotClass(classNames?.alert, open)),
575
- children: [
576
- /* @__PURE__ */ jsx(Dialog.Title, {
577
- className: "ef-alert-modal-sr-only",
578
- children: title
579
- }),
580
- description && /* @__PURE__ */ jsx(Dialog.Description, {
581
- className: "ef-alert-modal-sr-only",
582
- children: description
583
- }),
584
- children({
585
- open,
586
- busy,
587
- cancelRef,
588
- confirmRef,
589
- confirm: () => {
590
- run("confirm");
591
- },
592
- cancel: () => {
593
- run("cancel");
594
- }
595
- })
596
- ]
597
- })
598
- })]
599
- })]
600
- });
601
- }
602
- //#endregion
603
- //#region src/game/banner-alert/useAlertGlitch.ts
604
- const OPACITY = [
605
- 0,
606
- 1,
607
- 1,
608
- 0,
609
- 0,
610
- 1,
611
- 1,
612
- 0,
613
- 0,
614
- 1
615
- ];
616
- const OFFSETS = [
617
- 0,
618
- .48,
619
- .82,
620
- .85,
621
- .87,
622
- .9,
623
- .92,
624
- .95,
625
- .97,
626
- 1
627
- ];
628
- const frames = OPACITY.map((opacity, index) => ({
629
- opacity,
630
- offset: OFFSETS[index]
631
- }));
632
- function useAlertGlitch(open) {
633
- const contentRef = useRef(null);
634
- const actionsRef = useRef(null);
635
- useLayoutEffect(() => {
636
- if (!open) return;
637
- const nodes = [contentRef.current, actionsRef.current].filter((node) => node !== null);
638
- const media = window.matchMedia?.("(prefers-reduced-motion: reduce)");
639
- const animations = nodes.flatMap((node) => {
640
- node.style.removeProperty("--ef-game-alert-exit-opacity");
641
- node.style.opacity = "1";
642
- if (media?.matches || typeof node.animate !== "function") return [];
643
- node.style.opacity = "0";
644
- const animation = node.animate(frames, {
645
- duration: 205,
646
- easing: "ease-out",
647
- fill: "both"
648
- });
649
- animation.onfinish = () => {
650
- node.style.opacity = "1";
651
- animation.cancel();
652
- };
653
- return [{
654
- node,
655
- animation
656
- }];
657
- });
658
- const settle = () => {
659
- for (const { node, animation } of animations) {
660
- node.style.opacity = "1";
661
- animation.cancel();
662
- }
663
- };
664
- const reduced = () => {
665
- if (media?.matches) settle();
666
- };
667
- media?.addEventListener("change", reduced);
668
- return () => {
669
- media?.removeEventListener("change", reduced);
670
- for (const { node, animation } of animations) {
671
- node.style.setProperty("--ef-game-alert-exit-opacity", getComputedStyle(node).opacity);
672
- animation.cancel();
673
- node.style.opacity = "1";
674
- }
675
- };
676
- }, [open]);
677
- return {
678
- contentRef,
679
- actionsRef
680
- };
681
- }
682
- //#endregion
683
- //#region src/game/banner-alert/BannerAlert.tsx
684
- function BannerAlert({ children, width = "30em", hideCancel = false, cancelText = "取消", confirmText = "确认", showIcon = true, classNames, ...props }) {
685
- return /* @__PURE__ */ jsx(AlertModal, {
686
- ...props,
687
- width,
688
- hideCancel,
689
- classNames,
690
- popupClassName: "ef-banner-alert",
691
- backdropClassName: "ef-banner-alert-backdrop",
692
- children: (state) => /* @__PURE__ */ jsx(BannerAlertContent, {
693
- ...state,
694
- hideCancel,
695
- cancelText,
696
- confirmText,
697
- showIcon,
698
- classNames,
699
- children
700
- })
701
- });
702
- }
703
- function BannerAlertContent({ open, busy, cancelRef, confirmRef, cancel, confirm, hideCancel, cancelText, confirmText, showIcon, classNames, children }) {
704
- const { contentRef, actionsRef } = useAlertGlitch(open);
705
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
706
- /* @__PURE__ */ jsxs("div", {
707
- "aria-hidden": "true",
708
- className: "ef-banner-alert__banner",
709
- children: [/* @__PURE__ */ jsx("span", {}), /* @__PURE__ */ jsx("span", {})]
710
- }),
711
- /* @__PURE__ */ jsx("div", {
712
- ref: contentRef,
713
- className: cn("ef-banner-alert__content", alertSlotClass(classNames?.content, open)),
714
- children: /* @__PURE__ */ jsx("div", {
715
- className: "ef-banner-alert__body",
716
- children
717
- })
718
- }),
719
- /* @__PURE__ */ jsxs("div", {
720
- ref: actionsRef,
721
- className: "ef-banner-alert__actions",
722
- "data-hide-cancel": hideCancel ? "" : void 0,
723
- children: [!hideCancel && /* @__PURE__ */ jsx(RoundedButton, {
724
- ref: cancelRef,
725
- variant: "default",
726
- text: cancelText,
727
- showIcon,
728
- disabled: busy,
729
- onClick: cancel,
730
- icon: /* @__PURE__ */ jsx(AlertCloseIcon, {}),
731
- className: "ef-banner-alert__button"
732
- }), /* @__PURE__ */ jsx(RoundedButton, {
733
- ref: confirmRef,
734
- variant: "primary",
735
- text: confirmText,
736
- showIcon,
737
- disabled: busy,
738
- loading: busy,
739
- onClick: confirm,
740
- icon: /* @__PURE__ */ jsx(AlertTickIcon, {}),
741
- className: "ef-banner-alert__button"
742
- })]
743
- })
744
- ] });
745
- }
746
- //#endregion
747
- //#region src/game/full-width-alert/FullWidthAlert.tsx
748
- /** 横贯视口的确认面板,底部按钮突出于面板下沿。 */
749
- function FullWidthAlert({ hideCancel = false, cancelText = "取消", confirmText = "确认", showIcon = true, height = "auto", classNames, children, ...props }) {
750
- return /* @__PURE__ */ jsx(AlertModal, {
751
- ...props,
752
- hideCancel,
753
- height,
754
- classNames,
755
- popupClassName: "ef-full-width-alert",
756
- backdropClassName: "ef-full-width-alert-backdrop",
757
- viewportClassName: "ef-full-width-alert-viewport",
758
- children: ({ open, busy, cancelRef, confirmRef, cancel, confirm }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
759
- /* @__PURE__ */ jsxs("div", {
760
- "aria-hidden": "true",
761
- className: "ef-full-width-alert-decoration",
762
- children: [
763
- /* @__PURE__ */ jsx("span", { className: "ef-full-width-alert-logo" }),
764
- /* @__PURE__ */ jsx("span", { className: "ef-full-width-alert-color-bar" }),
765
- /* @__PURE__ */ jsxs("div", {
766
- className: "ef-full-width-alert-banner",
767
- children: [/* @__PURE__ */ jsx("span", { className: "ef-full-width-alert-banner-left" }), /* @__PURE__ */ jsx("span", { className: "ef-full-width-alert-banner-right" })]
768
- })
769
- ]
770
- }),
771
- /* @__PURE__ */ jsx("div", {
772
- className: cn("ef-full-width-alert-content", alertSlotClass(classNames?.content, open)),
773
- children: /* @__PURE__ */ jsxs(ScrollArea.Root, {
774
- className: "ef-full-width-alert-scroll-area",
775
- children: [/* @__PURE__ */ jsx(ScrollArea.Viewport, {
776
- className: "ef-full-width-alert-viewport-content",
777
- style: { overflowX: "hidden" },
778
- render: (viewportProps, state) => /* @__PURE__ */ jsx("div", {
779
- ...viewportProps,
780
- role: state.hasOverflowY ? "region" : "presentation",
781
- "aria-label": state.hasOverflowY ? "内容" : void 0,
782
- tabIndex: state.hasOverflowY ? 0 : -1
783
- }),
784
- children: /* @__PURE__ */ jsx(ScrollArea.Content, {
785
- className: "ef-full-width-alert-body",
786
- children
787
- })
788
- }), /* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
789
- orientation: "vertical",
790
- className: "ef-full-width-alert-scrollbar",
791
- children: /* @__PURE__ */ jsx(ScrollArea.Thumb, { className: "ef-full-width-alert-thumb" })
792
- })]
793
- })
794
- }),
795
- /* @__PURE__ */ jsxs("div", {
796
- className: "ef-full-width-alert-actions",
797
- children: [!hideCancel && /* @__PURE__ */ jsxs("div", {
798
- className: "ef-full-width-alert-action",
799
- children: [/* @__PURE__ */ jsx("span", {
800
- "aria-hidden": "true",
801
- className: "ef-full-width-alert-action-backing"
802
- }), /* @__PURE__ */ jsx(RoundedButton, {
803
- ref: cancelRef,
804
- variant: "default",
805
- text: cancelText,
806
- showIcon,
807
- disabled: busy,
808
- onClick: cancel,
809
- icon: /* @__PURE__ */ jsx(AlertCloseIcon, {}),
810
- className: "ef-full-width-alert-button"
811
- })]
812
- }), /* @__PURE__ */ jsxs("div", {
813
- className: "ef-full-width-alert-action",
814
- children: [/* @__PURE__ */ jsx("span", {
815
- "aria-hidden": "true",
816
- className: "ef-full-width-alert-action-backing"
817
- }), /* @__PURE__ */ jsx(RoundedButton, {
818
- ref: confirmRef,
819
- variant: "primary",
820
- text: confirmText,
821
- showIcon,
822
- loading: busy,
823
- disabled: busy,
824
- onClick: confirm,
825
- icon: /* @__PURE__ */ jsx(AlertTickIcon, {}),
826
- className: "ef-full-width-alert-button"
827
- })]
828
- })]
829
- })
830
- ] })
831
- });
832
- }
833
- //#endregion
834
- //#region src/game/item-icon/helpers.ts
835
- const EMPTY_ITEM_ICON_LAYERS = {
836
- iconUrl: "",
837
- iconBgUrl: "",
838
- iconMarkUrl: "",
839
- iconOverlayUrl: "",
840
- iconContentUrl: "",
841
- iconTrans: "",
842
- iconShowRarity: true
843
- };
844
- const ITEM_ICON_TRANSFORMS = {
845
- formula: {
846
- scale: .72,
847
- pivotX: 1,
848
- pivotY: .5
849
- },
850
- bigGem: {
851
- scale: 1,
852
- offsetX: 3,
853
- offsetY: 4
854
- }
855
- };
856
- function itemIconTransformStyle(key) {
857
- const variable = (part, fallback) => `var(--ef-game-iicon-${key}-${part}, ${fallback})`;
858
- if (key === "formula") {
859
- const values = ITEM_ICON_TRANSFORMS.formula;
860
- return {
861
- transform: `scale(${variable("scale", values.scale)})`,
862
- transformOrigin: `calc(${variable("pivot-x", values.pivotX)} * 100%) calc((1 - ${variable("pivot-y", values.pivotY)}) * 100%)`
863
- };
864
- }
865
- const values = ITEM_ICON_TRANSFORMS.bigGem;
866
- return {
867
- transform: `translate(calc(${variable("offset-x", values.offsetX)} * 1%), calc(${variable("offset-y", values.offsetY)} * -1%)) scale(${variable("scale", values.scale)})`,
868
- transformOrigin: "50% 50%"
869
- };
870
- }
871
- function coerceItemIconTrans(value) {
872
- return value === "formula" || value === "bigGem" ? value : "";
873
- }
874
- function pickItemIconLayers(source, prefix = "icon") {
875
- const values = source ?? {};
876
- const key = (name) => prefix === "icon" ? name : `${prefix}${name.slice(0, 1).toUpperCase()}${name.slice(1)}`;
877
- const stringValue = (name) => {
878
- const value = values[key(name)];
879
- return typeof value === "string" ? value : "";
880
- };
881
- const showRarity = values[key("iconShowRarity")];
882
- return {
883
- iconUrl: stringValue("iconUrl"),
884
- iconBgUrl: stringValue("iconBgUrl"),
885
- iconMarkUrl: stringValue("iconMarkUrl"),
886
- iconOverlayUrl: stringValue("iconOverlayUrl"),
887
- iconContentUrl: stringValue("iconContentUrl"),
888
- iconTrans: coerceItemIconTrans(values[key("iconTrans")]),
889
- iconShowRarity: typeof showRarity === "boolean" ? showRarity : true
890
- };
891
- }
892
- //#endregion
893
- //#region src/game/item-icon/ItemIcon.tsx
894
- function ItemImage({ src, alt, className, style, loading = "lazy", fallback = null }) {
895
- const [failed, setFailed] = useState(false);
896
- if (!src.trim() || failed) return /* @__PURE__ */ jsx(Fragment$1, { children: fallback });
897
- return /* @__PURE__ */ jsx("img", {
898
- src,
899
- alt,
900
- className,
901
- style,
902
- loading,
903
- decoding: "async",
904
- draggable: false,
905
- onError: () => setFailed(true)
906
- });
907
- }
908
- function ItemIcon({ layers, alt, className, style, fallback = null, loading, renderImage }) {
909
- const trans = coerceItemIconTrans(layers.iconTrans);
910
- const hasOverlay = Boolean(layers.iconOverlayUrl);
911
- const iconStyle = trans === "formula" ? itemIconTransformStyle("formula") : trans === "bigGem" && !hasOverlay ? itemIconTransformStyle("bigGem") : void 0;
912
- const overlayStyle = trans === "bigGem" ? itemIconTransformStyle("bigGem") : void 0;
913
- const renderLayer = (role, props) => /* @__PURE__ */ jsx(Fragment, { children: renderImage ? renderImage(props) : /* @__PURE__ */ jsx(ItemImage, { ...props }) }, `${role}:${props.src}`);
914
- return /* @__PURE__ */ jsxs("span", {
915
- className: cn("ef-composite-item-icon", className),
916
- style,
917
- children: [
918
- layers.iconBgUrl && renderLayer("background", {
919
- src: layers.iconBgUrl,
920
- alt: "",
921
- className: "ef-composite-item-icon__layer",
922
- loading
923
- }),
924
- renderLayer("art", {
925
- src: layers.iconUrl,
926
- alt,
927
- className: "ef-composite-item-icon__layer ef-composite-item-icon__art",
928
- style: iconStyle,
929
- loading,
930
- fallback
931
- }),
932
- hasOverlay && renderLayer("overlay", {
933
- src: layers.iconOverlayUrl ?? "",
934
- alt: "",
935
- className: "ef-composite-item-icon__layer ef-composite-item-icon__overlay",
936
- style: overlayStyle,
937
- loading
938
- }),
939
- layers.iconContentUrl && renderLayer("content", {
940
- src: layers.iconContentUrl,
941
- alt: "",
942
- className: "ef-composite-item-icon__layer",
943
- style: {
944
- transform: `scale(${80 / 180})`,
945
- transformOrigin: "50% 50%"
946
- },
947
- loading
948
- }),
949
- layers.iconMarkUrl && renderLayer("mark", {
950
- src: layers.iconMarkUrl,
951
- alt: "",
952
- className: "ef-composite-item-icon__layer",
953
- loading
954
- })
955
- ]
956
- });
957
- }
958
- //#endregion
959
- //#region src/game/item-card/ItemCard.tsx
960
- const KIND_LABEL = {
961
- weapon: "武器",
962
- item: "物品",
963
- enemy: "敌人"
964
- };
965
- function isItemKind(kind) {
966
- return kind === "weapon" || kind === "item" || kind === "enemy";
967
- }
968
- function clampRarity(rarity) {
969
- return Math.min(Math.max(Math.trunc(rarity), 1), 6);
970
- }
971
- function nameFontSize(name) {
972
- let em = 0;
973
- for (const character of name) em += (character.codePointAt(0) ?? 0) < 11904 ? .5 : 1;
974
- return em > 0 ? `clamp(9px, calc(100cqw / ${em}), 14px)` : void 0;
975
- }
976
- /** Wiki 物品卡片:名称横条或库存数量横条,共用完整图层图标。 */
977
- const ItemCard = memo(function ItemCard({ kind, name, imageUrl, rarity, itemId, href, variant = "banner", count = 0, showName = true, className, style, icon, action, badges, ariaLabel, fallback, renderImage, renderLink, renderName, renderCount }) {
978
- if (!isItemKind(kind)) return null;
979
- const hasRarity = Number.isFinite(rarity) && rarity > 0 && (icon?.iconShowRarity ?? true);
980
- const inventory = variant === "inventory";
981
- const layers = {
982
- ...EMPTY_ITEM_ICON_LAYERS,
983
- ...icon,
984
- iconUrl: imageUrl
985
- };
986
- const label = ariaLabel || name || KIND_LABEL[kind];
987
- const renderedName = renderName ? renderName(name) : name || "—";
988
- const tile = /* @__PURE__ */ jsxs("div", {
989
- className: "ef-item-card-tile",
990
- children: [
991
- /* @__PURE__ */ jsx("span", {
992
- "aria-hidden": "true",
993
- className: "ef-item-card-background"
994
- }),
995
- /* @__PURE__ */ jsx("div", {
996
- className: "ef-item-card-art",
997
- children: /* @__PURE__ */ jsx(ItemIcon, {
998
- layers,
999
- alt: name,
1000
- className: "ef-item-card-icon",
1001
- renderImage,
1002
- fallback: fallback === void 0 ? /* @__PURE__ */ jsx("span", {
1003
- className: "ef-item-card-fallback",
1004
- children: "NO IMAGE"
1005
- }) : fallback
1006
- })
1007
- }),
1008
- badges ? /* @__PURE__ */ jsx("div", {
1009
- className: "ef-item-card-badges",
1010
- children: badges
1011
- }) : null,
1012
- /* @__PURE__ */ jsxs("div", {
1013
- className: "ef-item-card-strip",
1014
- children: [/* @__PURE__ */ jsx("span", {
1015
- "aria-hidden": "true",
1016
- className: "ef-item-card-edge"
1017
- }), /* @__PURE__ */ jsx("div", {
1018
- className: "ef-item-card-strip-content",
1019
- children: inventory ? /* @__PURE__ */ jsx("span", {
1020
- className: "ef-item-card-count",
1021
- children: renderCount ? renderCount(count) : count > 0 ? count : "\xA0"
1022
- }) : /* @__PURE__ */ jsx("span", {
1023
- className: "ef-item-card-name",
1024
- style: { fontSize: nameFontSize(name) },
1025
- title: name,
1026
- children: showName ? renderedName : "\xA0"
1027
- })
1028
- })]
1029
- })
1030
- ]
1031
- });
1032
- const inner = /* @__PURE__ */ jsxs("div", {
1033
- className: cn("ef-item-card", className),
1034
- style,
1035
- "data-kind": kind,
1036
- "data-variant": variant,
1037
- "data-rarity": hasRarity ? clampRarity(rarity) : void 0,
1038
- "data-item-tooltip-id": !action && !href && kind === "item" ? itemId : void 0,
1039
- children: [tile, inventory && showName && /* @__PURE__ */ jsx("span", {
1040
- className: "ef-item-card-caption",
1041
- title: name,
1042
- children: renderedName
1043
- })]
1044
- });
1045
- if (action) return /* @__PURE__ */ jsxs("button", {
1046
- type: "button",
1047
- onClick: action.onSelect,
1048
- disabled: action.disabled,
1049
- "aria-pressed": action.selected,
1050
- "aria-label": [action.ariaLabel || label, action.disabledReason].filter(Boolean).join(" · "),
1051
- className: "ef-item-card-action",
1052
- "data-selected": action.selected ? "" : void 0,
1053
- children: [inner, action.disabledReason && /* @__PURE__ */ jsx("span", {
1054
- className: "ef-item-card-disabled-reason",
1055
- children: action.disabledReason
1056
- })]
1057
- });
1058
- if (href) {
1059
- const linkProps = {
1060
- href,
1061
- children: inner,
1062
- className: "ef-item-card-link",
1063
- "aria-label": label,
1064
- "data-item-tooltip-id": kind === "item" ? itemId : void 0
1065
- };
1066
- return renderLink ? renderLink(linkProps) : /* @__PURE__ */ jsx("a", { ...linkProps });
1067
- }
1068
- return inner;
1069
- });
1070
- //#endregion
1071
- //#region src/game/item-tooltip-card/icons.tsx
1072
- function ObtainFallbackIcon() {
1073
- return /* @__PURE__ */ jsxs("svg", {
1074
- "aria-hidden": "true",
1075
- viewBox: "0 0 24 24",
1076
- fill: "none",
1077
- stroke: "currentColor",
1078
- strokeWidth: "2",
1079
- strokeLinecap: "round",
1080
- strokeLinejoin: "round",
1081
- children: [
1082
- /* @__PURE__ */ jsx("path", { d: "M12 22V12M20.27 18.27 22 20" }),
1083
- /* @__PURE__ */ jsx("path", { d: "M21 10.498V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.729l7 4a2 2 0 0 0 2 .001l.98-.559" }),
1084
- /* @__PURE__ */ jsx("path", { d: "M3.29 7 12 12l8.71-5M7.5 4.27l8.997 5.148" }),
1085
- /* @__PURE__ */ jsx("circle", {
1086
- cx: "18.5",
1087
- cy: "16.5",
1088
- r: "2.5"
1089
- })
1090
- ]
1091
- });
1092
- }
1093
- function ObtainLinkIcon() {
1094
- return /* @__PURE__ */ jsx("svg", {
1095
- "aria-hidden": "true",
1096
- className: "ef-item-tooltip-card__chevrons",
1097
- viewBox: "0 0 24 24",
1098
- fill: "none",
1099
- stroke: "currentColor",
1100
- strokeWidth: "3",
1101
- strokeLinecap: "round",
1102
- strokeLinejoin: "round",
1103
- children: /* @__PURE__ */ jsx("path", { d: "m6 17 5-5-5-5m7 10 5-5-5-5" })
1104
- });
1105
- }
1106
- //#endregion
1107
- //#region src/game/item-tooltip-card/ItemTooltipCard.tsx
1108
- const plainText = (text) => text;
1109
- const defaultLink = (props) => /* @__PURE__ */ jsx("a", { ...props });
1110
- /** 固定灰色游戏皮肤的物品详情;文章路由与富文本由使用方接入。 */
1111
- function ItemTooltipCard({ item, className, style, fontFamily, obtainLabel = "获取途径", renderText = plainText, renderImage, renderLink = defaultLink }) {
1112
- const rarity = Number.isFinite(item.rarity) ? Math.min(6, Math.max(1, Math.trunc(item.rarity))) : 1;
1113
- const obtainWays = item.obtainWays ?? [];
1114
- return /* @__PURE__ */ jsxs("article", {
1115
- className: cn("ef-item-tooltip-card", className),
1116
- style: {
1117
- fontFamily,
1118
- ...style
1119
- },
1120
- "data-rarity": rarity,
1121
- children: [
1122
- /* @__PURE__ */ jsxs("header", {
1123
- className: "ef-item-tooltip-card__header",
1124
- children: [
1125
- /* @__PURE__ */ jsx("span", {
1126
- "aria-hidden": "true",
1127
- className: "ef-item-tooltip-card__header-texture"
1128
- }),
1129
- /* @__PURE__ */ jsx("h2", { children: item.name }),
1130
- item.href && renderLink({
1131
- href: item.href,
1132
- className: "ef-item-tooltip-card__detail-link",
1133
- "aria-label": item.name,
1134
- children: /* @__PURE__ */ jsx("span", {
1135
- "aria-hidden": "true",
1136
- className: "ef-item-tooltip-card__detail-link-icon"
1137
- })
1138
- })
1139
- ]
1140
- }),
1141
- /* @__PURE__ */ jsxs("div", {
1142
- className: "ef-item-tooltip-card__body",
1143
- children: [
1144
- /* @__PURE__ */ jsx("span", {
1145
- "aria-hidden": "true",
1146
- className: "ef-item-tooltip-card__detail-texture"
1147
- }),
1148
- /* @__PURE__ */ jsxs("div", {
1149
- className: "ef-item-tooltip-card__hero",
1150
- children: [
1151
- /* @__PURE__ */ jsx("p", {
1152
- className: "ef-item-tooltip-card__category",
1153
- children: item.category
1154
- }),
1155
- /* @__PURE__ */ jsx("span", {
1156
- "aria-hidden": "true",
1157
- className: "ef-item-tooltip-card__marker"
1158
- }),
1159
- /* @__PURE__ */ jsx("span", {
1160
- "aria-hidden": "true",
1161
- className: "ef-item-tooltip-card__barcode"
1162
- }),
1163
- /* @__PURE__ */ jsx(ItemIcon, {
1164
- layers: {
1165
- ...pickItemIconLayers(item),
1166
- iconBgUrl: "",
1167
- iconMarkUrl: ""
1168
- },
1169
- alt: item.name,
1170
- loading: "eager",
1171
- className: "ef-item-tooltip-card__icon",
1172
- renderImage
1173
- })
1174
- ]
1175
- }),
1176
- /* @__PURE__ */ jsx("span", {
1177
- "aria-hidden": "true",
1178
- className: "ef-item-tooltip-card__color-strip"
1179
- }),
1180
- (item.usage || item.description) && /* @__PURE__ */ jsxs("div", {
1181
- className: "ef-item-tooltip-card__text",
1182
- children: [item.usage && /* @__PURE__ */ jsx("p", { children: renderText(item.usage) }), item.description && /* @__PURE__ */ jsx("p", {
1183
- className: "ef-item-tooltip-card__description",
1184
- children: renderText(item.description)
1185
- })]
1186
- })
1187
- ]
1188
- }),
1189
- (obtainWays.length > 0 || item.noObtainWayHint) && /* @__PURE__ */ jsxs("section", {
1190
- "aria-label": obtainLabel,
1191
- children: [
1192
- /* @__PURE__ */ jsx("h3", {
1193
- className: "ef-item-tooltip-card__obtain-title",
1194
- children: obtainLabel
1195
- }),
1196
- /* @__PURE__ */ jsx("ul", {
1197
- className: "ef-item-tooltip-card__obtain-list",
1198
- children: obtainWays.map((way, index) => {
1199
- const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
1200
- /* @__PURE__ */ jsx(ItemIcon, {
1201
- layers: { iconUrl: way.iconUrl ?? "" },
1202
- alt: "",
1203
- loading: "eager",
1204
- className: "ef-item-tooltip-card__obtain-icon",
1205
- renderImage,
1206
- fallback: /* @__PURE__ */ jsx(ObtainFallbackIcon, {})
1207
- }),
1208
- /* @__PURE__ */ jsx("span", {
1209
- className: "ef-item-tooltip-card__obtain-name",
1210
- children: renderText(way.name)
1211
- }),
1212
- way.href && /* @__PURE__ */ jsx(ObtainLinkIcon, {})
1213
- ] });
1214
- return /* @__PURE__ */ jsx("li", { children: way.href ? renderLink({
1215
- href: way.href,
1216
- className: "ef-item-tooltip-card__obtain-row",
1217
- children: content
1218
- }) : /* @__PURE__ */ jsx("div", {
1219
- className: "ef-item-tooltip-card__obtain-row",
1220
- children: content
1221
- }) }, `${way.id ?? index}-${index}`);
1222
- })
1223
- }),
1224
- item.noObtainWayHint && /* @__PURE__ */ jsx("p", {
1225
- className: "ef-item-tooltip-card__obtain-hint",
1226
- children: renderText(item.noObtainWayHint)
1227
- })
1228
- ]
1229
- })
1230
- ]
1231
- });
1232
- }
1233
- //#endregion
1234
- //#region src/game/item-hover-card/events.ts
1235
- function bindItemHoverEvents(options, select, panel) {
1236
- const doc = options.root.ownerDocument ?? options.root;
1237
- const win = doc.defaultView;
1238
- let active = null;
1239
- let dismissed = null;
1240
- let focusedTrigger = null;
1241
- let pointerTarget = null;
1242
- let openTimer;
1243
- let closeTimer;
1244
- let shown = false;
1245
- let activeId;
1246
- let activeTarget = null;
1247
- const cancel = () => {
1248
- win.clearTimeout(openTimer);
1249
- win.clearTimeout(closeTimer);
1250
- openTimer = closeTimer = void 0;
1251
- };
1252
- const close = () => {
1253
- cancel();
1254
- active = null;
1255
- activeId = void 0;
1256
- activeTarget = null;
1257
- shown = false;
1258
- unwatch();
1259
- select(null);
1260
- };
1261
- const inPanel = (node) => node instanceof Node && Boolean(panel()?.contains(node));
1262
- const inside = (node) => inPanel(node) || node instanceof Node && Boolean(active?.contains(node));
1263
- const hostOf = (node) => {
1264
- if (!(node instanceof Element) || inPanel(node)) return null;
1265
- if (node.closest("[inert], [aria-disabled='true'], :disabled")) return null;
1266
- const host = node.closest("[data-item-tooltip-id]");
1267
- const scope = options.rootOf ? options.rootOf() : options.root;
1268
- if (!host || !scope?.contains(host)) return null;
1269
- if (host.closest("[inert], [aria-disabled='true'], :disabled")) return null;
1270
- return options.anchorOf(host) ? host : null;
1271
- };
1272
- const open = (host, delay, target) => {
1273
- if (host === dismissed) return;
1274
- dismissed = null;
1275
- win.clearTimeout(closeTimer);
1276
- closeTimer = void 0;
1277
- if (host === active && shown) {
1278
- activeTarget = target;
1279
- if (activeId !== host.dataset.itemTooltipId) {
1280
- activeId = host.dataset.itemTooltipId;
1281
- select(options.anchorOf(host));
1282
- }
1283
- return;
1284
- }
1285
- if (host === active && openTimer !== void 0 && delay > 0) return;
1286
- cancel();
1287
- active = host;
1288
- activeId = host.dataset.itemTooltipId;
1289
- activeTarget = target;
1290
- shown = false;
1291
- watch();
1292
- select(null);
1293
- openTimer = win.setTimeout(() => {
1294
- openTimer = void 0;
1295
- const anchor = host.isConnected && hostOf(target) === host ? options.anchorOf(host) : null;
1296
- if (active !== host) return;
1297
- if (!anchor) return close();
1298
- shown = true;
1299
- activeId = host.dataset.itemTooltipId;
1300
- select(anchor);
1301
- }, Math.max(0, delay));
1302
- };
1303
- const leave = () => {
1304
- if (inside(pointerTarget) || inside(doc.activeElement)) {
1305
- win.clearTimeout(closeTimer);
1306
- closeTimer = void 0;
1307
- return;
1308
- }
1309
- cancel();
1310
- closeTimer = win.setTimeout(close, Math.max(0, options.closeDelay));
1311
- };
1312
- const clearDismissed = (target, next) => {
1313
- if (target instanceof Node && dismissed?.contains(target) && !(next instanceof Node && dismissed.contains(next))) dismissed = null;
1314
- };
1315
- const pointerOver = (event) => {
1316
- if (event.pointerType === "touch") return;
1317
- pointerTarget = event.target;
1318
- if (inPanel(event.target)) return cancel();
1319
- const host = hostOf(event.target);
1320
- if (host) open(host, options.openDelay, event.target);
1321
- };
1322
- const pointerOut = (event) => {
1323
- if (event.pointerType === "touch") return;
1324
- pointerTarget = event.relatedTarget;
1325
- clearDismissed(event.target, event.relatedTarget);
1326
- if (active && inside(event.target) && !inside(event.relatedTarget)) leave();
1327
- };
1328
- const focusIn = (event) => {
1329
- if (inPanel(event.target)) return cancel();
1330
- const host = hostOf(event.target);
1331
- if (host) {
1332
- focusedTrigger = event.target instanceof HTMLElement ? event.target : host;
1333
- open(host, 0, event.target);
1334
- }
1335
- };
1336
- const focusOut = (event) => {
1337
- clearDismissed(event.target, event.relatedTarget);
1338
- if (active && inside(event.target) && !inside(event.relatedTarget)) leave();
1339
- };
1340
- const scroll = (event) => {
1341
- if (active && !inPanel(event.target)) close();
1342
- };
1343
- const dismiss = (restoreFocus = false) => {
1344
- const available = (node) => Boolean(node?.isConnected && !node.closest("[hidden],[inert],[aria-disabled='true'],:disabled"));
1345
- const restore = restoreFocus && inPanel(doc.activeElement) && active ? focusedTrigger && available(focusedTrigger) && active.contains(focusedTrigger) ? focusedTrigger : Array.from(active.querySelectorAll("a[href],button:not(:disabled),[tabindex='0']")).find(available) ?? (available(active) && active.matches("a[href],button,[tabindex]") ? active : null) ?? (available(active.closest("[role='dialog']")) ? active.closest("[role='dialog']") : null) : null;
1346
- dismissed = active;
1347
- close();
1348
- if (restore?.isConnected) restore.focus({ preventScroll: true });
1349
- };
1350
- const listeners = [
1351
- ["pointerover", pointerOver],
1352
- ["pointerout", pointerOut],
1353
- ["focusin", focusIn],
1354
- ["focusout", focusOut]
1355
- ];
1356
- for (const [type, listener] of listeners) doc.addEventListener(type, listener);
1357
- const mutation = new MutationObserver(() => {
1358
- if (!active) return;
1359
- if (hostOf(activeTarget) !== active || !active.isConnected) return dismiss(true);
1360
- if (shown && activeId !== active.dataset.itemTooltipId) {
1361
- activeId = active.dataset.itemTooltipId;
1362
- const anchor = options.anchorOf(active);
1363
- if (anchor) select(anchor);
1364
- else dismiss(true);
1365
- }
1366
- });
1367
- let watching = false;
1368
- function watch() {
1369
- if (watching) return;
1370
- watching = true;
1371
- mutation.observe(doc, {
1372
- subtree: true,
1373
- childList: true,
1374
- attributes: true,
1375
- attributeFilter: [
1376
- "data-item-tooltip-id",
1377
- "disabled",
1378
- "inert",
1379
- "aria-disabled"
1380
- ]
1381
- });
1382
- win.addEventListener("scroll", scroll, true);
1383
- win.addEventListener("resize", close);
1384
- }
1385
- function unwatch() {
1386
- if (!watching) return;
1387
- watching = false;
1388
- mutation.disconnect();
1389
- win.removeEventListener("scroll", scroll, true);
1390
- win.removeEventListener("resize", close);
1391
- }
1392
- return {
1393
- close,
1394
- dismiss,
1395
- dispose() {
1396
- cancel();
1397
- unwatch();
1398
- for (const [type, listener] of listeners) doc.removeEventListener(type, listener);
1399
- }
1400
- };
1401
- }
1402
- //#endregion
1403
- //#region src/game/item-hover-card/ItemHoverCard.tsx
1404
- /** 一个监听层为网格内所有 data-item-tooltip-id 提供物品预览。 */
1405
- function ItemHoverCardLayer({ resolveItem, root, rootRef, disabled = false, disableOnMobile = true, openDelay = 180, closeDelay = 160, gap = 8, width = 320, className, style, cardProps, onOpenChange }) {
1406
- const [anchor, setAnchor] = useState(null);
1407
- const panelRef = useRef(null);
1408
- const controls = useRef(null);
1409
- const binding = useRef(null);
1410
- const resolveRef = useRef(resolveItem);
1411
- const scopeRef = useRef({
1412
- root,
1413
- rootRef
1414
- });
1415
- const changeRef = useRef(onOpenChange);
1416
- useLayoutEffect(() => {
1417
- resolveRef.current = resolveItem;
1418
- scopeRef.current = {
1419
- root,
1420
- rootRef
1421
- };
1422
- changeRef.current = onOpenChange;
1423
- });
1424
- const close = useCallback(() => controls.current?.close(), []);
1425
- useEffect(() => {
1426
- const delegateRoot = disabled ? null : rootRef?.current ?? root ?? document;
1427
- const previous = binding.current;
1428
- const delegateDocument = delegateRoot ? delegateRoot.ownerDocument ?? delegateRoot : null;
1429
- const scope = rootRef ? rootRef.current : root ?? delegateRoot;
1430
- if (anchor && !scope?.contains(anchor.host)) controls.current?.close();
1431
- if (previous && previous.root === delegateDocument && previous.disableOnMobile === disableOnMobile && previous.openDelay === openDelay && previous.closeDelay === closeDelay) return;
1432
- previous?.dispose();
1433
- binding.current = null;
1434
- if (!delegateRoot) return;
1435
- const media = (delegateRoot.ownerDocument ?? delegateRoot).defaultView.matchMedia("(min-width: 768px) and (hover: hover) and (pointer: fine)");
1436
- const bind = () => {
1437
- controls.current?.close();
1438
- controls.current?.dispose();
1439
- controls.current = null;
1440
- if (disableOnMobile && !media.matches) return;
1441
- controls.current = bindItemHoverEvents({
1442
- root: delegateRoot,
1443
- rootOf: () => {
1444
- const scope = scopeRef.current;
1445
- return scope.rootRef ? scope.rootRef.current : scope.root ?? delegateDocument;
1446
- },
1447
- anchorOf: (host) => {
1448
- const itemId = host.dataset.itemTooltipId;
1449
- return itemId && resolveRef.current(itemId, host) ? {
1450
- host,
1451
- itemId
1452
- } : null;
1453
- },
1454
- openDelay,
1455
- closeDelay
1456
- }, setAnchor, () => panelRef.current);
1457
- };
1458
- bind();
1459
- media.addEventListener("change", bind);
1460
- binding.current = {
1461
- root: delegateDocument,
1462
- disableOnMobile,
1463
- openDelay,
1464
- closeDelay,
1465
- dispose: () => {
1466
- media.removeEventListener("change", bind);
1467
- controls.current?.close();
1468
- controls.current?.dispose();
1469
- controls.current = null;
1470
- }
1471
- };
1472
- });
1473
- useEffect(() => () => {
1474
- binding.current?.dispose();
1475
- binding.current = null;
1476
- }, []);
1477
- const currentId = anchor?.host.dataset.itemTooltipId;
1478
- const item = !disabled && anchor && currentId ? resolveItem(currentId, anchor.host) : null;
1479
- const activeId = item ? currentId ?? null : null;
1480
- useEffect(() => {
1481
- changeRef.current?.(Boolean(activeId), activeId);
1482
- }, [activeId]);
1483
- if (!anchor || !item) return null;
1484
- return /* @__PURE__ */ jsx(ItemHoverPanel, {
1485
- anchor,
1486
- item,
1487
- panelRef,
1488
- close,
1489
- dismiss: (restore) => controls.current?.dismiss(restore),
1490
- gap,
1491
- width,
1492
- className,
1493
- style,
1494
- cardProps
1495
- });
1496
- }
1497
- function ItemHoverPanel({ anchor, item, panelRef, close, dismiss, gap, width, className, style, cardProps }) {
1498
- const id = useId();
1499
- const { anchorRef, portalRef } = usePortalScope();
1500
- useLayoutEffect(() => {
1501
- const doc = anchor.host.ownerDocument;
1502
- const attributes = [
1503
- "aria-controls",
1504
- "aria-expanded",
1505
- "aria-haspopup"
1506
- ];
1507
- let trigger = null;
1508
- let previous = [];
1509
- const restoreAria = () => {
1510
- if (!trigger) return;
1511
- attributes.forEach((name, index) => {
1512
- const value = previous[index];
1513
- if (value == null) trigger?.removeAttribute(name);
1514
- else trigger?.setAttribute(name, value);
1515
- });
1516
- };
1517
- const syncAria = () => {
1518
- const next = anchor.host.contains(doc.activeElement) ? doc.activeElement : anchor.host;
1519
- if (next === trigger) return;
1520
- restoreAria();
1521
- trigger = next;
1522
- previous = attributes.map((name) => trigger.getAttribute(name));
1523
- trigger.setAttribute("aria-controls", id);
1524
- trigger.setAttribute("aria-expanded", "true");
1525
- trigger.setAttribute("aria-haspopup", "dialog");
1526
- };
1527
- syncAria();
1528
- const focusPanel = (event) => {
1529
- if (event.defaultPrevented) return;
1530
- const first = panelRef.current?.querySelector("a[href],button:not(:disabled),[tabindex='0']");
1531
- if (event.key === "Tab" && !first) {
1532
- flushSync(close);
1533
- return;
1534
- }
1535
- if (event.key === "ArrowDown" && first) {
1536
- event.preventDefault();
1537
- first.focus({ preventScroll: true });
1538
- }
1539
- };
1540
- anchor.host.addEventListener("keydown", focusPanel);
1541
- anchor.host.addEventListener("focusin", syncAria);
1542
- return () => {
1543
- anchor.host.removeEventListener("keydown", focusPanel);
1544
- anchor.host.removeEventListener("focusin", syncAria);
1545
- restoreAria();
1546
- };
1547
- }, [
1548
- anchor.host,
1549
- close,
1550
- id,
1551
- panelRef
1552
- ]);
1553
- useEffect(() => {
1554
- const observer = typeof IntersectionObserver === "undefined" ? null : new IntersectionObserver((entries) => {
1555
- if (entries.some((entry) => !entry.isIntersecting)) close();
1556
- });
1557
- observer?.observe(anchor.host);
1558
- return () => observer?.disconnect();
1559
- }, [anchor.host, close]);
1560
- return /* @__PURE__ */ jsx(Popover.Root, {
1561
- open: true,
1562
- onOpenChange: (open, details) => {
1563
- if (open) return;
1564
- if (details.reason === "focus-out") details.cancel();
1565
- else dismiss(details.reason === "escape-key");
1566
- },
1567
- children: /* @__PURE__ */ jsx(Popover.Portal, {
1568
- ref: (node) => {
1569
- anchorRef(anchor.host);
1570
- portalRef(node);
1571
- },
1572
- container: anchor.host.closest("dialog,[role='dialog'],[role='alertdialog']") ?? void 0,
1573
- children: /* @__PURE__ */ jsx(Popover.Positioner, {
1574
- anchor: anchor.host,
1575
- positionMethod: "fixed",
1576
- side: "right",
1577
- align: "start",
1578
- sideOffset: gap,
1579
- collisionBoundary: [],
1580
- collisionPadding: 8,
1581
- collisionAvoidance: {
1582
- side: "flip",
1583
- align: "shift"
1584
- },
1585
- className: "ef-item-hover-positioner",
1586
- style: {
1587
- width,
1588
- ...style
1589
- },
1590
- children: /* @__PURE__ */ jsx(Popover.Popup, {
1591
- ref: panelRef,
1592
- id,
1593
- "aria-label": item.name,
1594
- initialFocus: false,
1595
- finalFocus: false,
1596
- "data-item-tooltip-panel": "",
1597
- className: cn("ef-item-hover-panel", className),
1598
- children: /* @__PURE__ */ jsx(ItemTooltipCard, {
1599
- ...cardProps,
1600
- item
1601
- })
1602
- })
1603
- })
1604
- })
1605
- });
1606
- }
1607
- function ItemHoverCard({ item, children, triggerProps, ...layerProps }) {
1608
- const rootRef = useRef(null);
1609
- const itemId = useId();
1610
- return /* @__PURE__ */ jsxs("span", {
1611
- ...triggerProps,
1612
- className: cn("ef-item-hover-trigger", triggerProps?.className),
1613
- ref: rootRef,
1614
- "data-item-tooltip-id": itemId,
1615
- children: [children, /* @__PURE__ */ jsx(ItemHoverCardLayer, {
1616
- ...layerProps,
1617
- rootRef,
1618
- resolveItem: () => item
1619
- })]
1620
- });
1621
- }
1622
- //#endregion
1623
- //#region src/game/rounded-button/RoundedIconButton.tsx
1624
- /** 24px 圆形图标按钮;纹理与双边线只作装饰。 */
1625
- function RoundedIconButton({ type = "button", disabled = false, children, className, ...props }) {
1626
- return /* @__PURE__ */ jsxs("button", {
1627
- ...props,
1628
- type,
1629
- disabled,
1630
- className: cn("ef-rounded-icon-button", className),
1631
- children: [
1632
- /* @__PURE__ */ jsx("span", {
1633
- "aria-hidden": "true",
1634
- className: "ef-rounded-icon-button-texture"
1635
- }),
1636
- /* @__PURE__ */ jsx("span", {
1637
- "aria-hidden": "true",
1638
- className: "ef-rounded-icon-button-border"
1639
- }),
1640
- /* @__PURE__ */ jsx("span", {
1641
- "aria-hidden": "true",
1642
- className: "ef-rounded-icon-button-content",
1643
- children
1644
- })
1645
- ]
1646
- });
1647
- }
1648
- //#endregion
1649
- //#region src/game/rounded-select/RoundedSelect.tsx
1650
- /** 圆角触发器与半覆盖面板;隐藏项不进入列表,禁用项不能选择。 */
1651
- function RoundedSelect({ options, value, defaultValue, onValueChange, placeholder, name, form, required: requiredProp, disabled: disabledProp, invalid: invalidProp, open, defaultOpen = false, onOpenChange, id: idProp, "aria-label": ariaLabel, "aria-describedby": describedByProp, className, classNames, ref }) {
1652
- const { id, disabled, required, invalid, ...field } = useFieldControl({
1653
- id: idProp,
1654
- disabled: disabledProp,
1655
- required: requiredProp,
1656
- invalid: invalidProp,
1657
- "aria-describedby": describedByProp
1658
- });
1659
- const [expanded, setExpanded] = useControllableState({
1660
- value: open,
1661
- defaultValue: defaultOpen
1662
- });
1663
- const [currentValue, setCurrentValue] = useControllableState({
1664
- value,
1665
- defaultValue: defaultValue ?? null,
1666
- onChange: (next) => {
1667
- if (next !== null) onValueChange?.(next);
1668
- }
1669
- });
1670
- if (disabled && expanded && open === void 0) setExpanded(false);
1671
- const popupOpen = expanded && !disabled;
1672
- const [hovered, setHovered] = useState(false);
1673
- const [pressed, setPressed] = useState(false);
1674
- const boxRef = useRef(null);
1675
- const { anchorRef, portalRef } = usePortalScope();
1676
- return /* @__PURE__ */ jsxs(Select.Root, {
1677
- items: options,
1678
- value: currentValue,
1679
- onValueChange: setCurrentValue,
1680
- name,
1681
- form,
1682
- required,
1683
- disabled,
1684
- modal: false,
1685
- open: popupOpen,
1686
- onOpenChange: (next) => {
1687
- setExpanded(next);
1688
- if (next !== expanded) onOpenChange?.(next);
1689
- },
1690
- children: [/* @__PURE__ */ jsx("div", {
1691
- ref: (node) => {
1692
- boxRef.current = node;
1693
- anchorRef(node);
1694
- },
1695
- className: cn("ef-rounded-select", className, classNames?.container),
1696
- "data-invalid": invalid ? "" : void 0,
1697
- children: /* @__PURE__ */ jsx(Select.Trigger, {
1698
- ref,
1699
- id,
1700
- "aria-label": ariaLabel,
1701
- "aria-invalid": invalid || void 0,
1702
- "aria-describedby": field["aria-describedby"],
1703
- className: cn("ef-rounded-select-trigger", classNames?.trigger),
1704
- onPointerEnter: (event) => setHovered(event.pointerType !== "touch"),
1705
- onPointerLeave: () => {
1706
- setHovered(false);
1707
- setPressed(false);
1708
- },
1709
- onPointerDown: (event) => setPressed(event.button === 0),
1710
- onPointerUp: () => setPressed(false),
1711
- onPointerCancel: () => setPressed(false),
1712
- children: /* @__PURE__ */ jsx(RoundedTriggerContent, { placeholder })
1713
- })
1714
- }), /* @__PURE__ */ jsx(Select.Portal, {
1715
- ref: portalRef,
1716
- children: /* @__PURE__ */ jsxs(Select.Positioner, {
1717
- anchor: boxRef,
1718
- alignItemWithTrigger: false,
1719
- side: "bottom",
1720
- align: "start",
1721
- sideOffset: -16,
1722
- className: "ef-rounded-select-positioner",
1723
- children: [/* @__PURE__ */ jsx("div", {
1724
- "aria-hidden": "true",
1725
- className: cn("ef-rounded-select-trigger ef-rounded-select-mirror", classNames?.trigger),
1726
- "data-invalid": invalid ? "" : void 0,
1727
- "data-hovered": hovered ? "" : void 0,
1728
- "data-pressed": pressed ? "" : void 0,
1729
- children: /* @__PURE__ */ jsx(RoundedTriggerContent, { placeholder })
1730
- }), /* @__PURE__ */ jsx(Select.Popup, {
1731
- className: cn("ef-rounded-select-popup", classNames?.optionContainer),
1732
- children: /* @__PURE__ */ jsxs(ScrollArea.Root, {
1733
- className: cn("ef-rounded-select-scroll-area", classNames?.optionScrollArea),
1734
- children: [/* @__PURE__ */ jsx(ScrollArea.Viewport, {
1735
- className: "ef-rounded-select-viewport",
1736
- style: { overflowX: "hidden" },
1737
- render: /* @__PURE__ */ jsx(Select.List, { role: "listbox" }),
1738
- children: /* @__PURE__ */ jsx(ScrollArea.Content, { children: options.filter((option) => !option.hidden).map((option) => /* @__PURE__ */ jsx(Select.Item, {
1739
- value: option.value,
1740
- label: option.textValue,
1741
- disabled: disabled || option.disabled,
1742
- className: cn("ef-rounded-select-option", classNames?.option),
1743
- render: (itemProps, state) => {
1744
- const left = typeof option.left === "function" ? option.left(state.selected) : option.left;
1745
- const right = typeof option.right === "function" ? option.right(state.selected) : option.right;
1746
- return /* @__PURE__ */ jsxs("div", {
1747
- ...itemProps,
1748
- children: [
1749
- left != null && /* @__PURE__ */ jsx("span", {
1750
- className: "ef-rounded-select-left",
1751
- children: left
1752
- }),
1753
- /* @__PURE__ */ jsx(Select.ItemText, {
1754
- className: "ef-rounded-select-option-label",
1755
- children: option.label
1756
- }),
1757
- right != null && /* @__PURE__ */ jsx("span", {
1758
- className: "ef-rounded-select-right",
1759
- children: right
1760
- }),
1761
- /* @__PURE__ */ jsx(RoundedOptionIndicator, {})
1762
- ]
1763
- });
1764
- }
1765
- }, option.value)) })
1766
- }), /* @__PURE__ */ jsx(ScrollArea.Scrollbar, {
1767
- orientation: "vertical",
1768
- className: "ef-rounded-select-scrollbar",
1769
- children: /* @__PURE__ */ jsx(ScrollArea.Thumb, { className: "ef-rounded-select-thumb" })
1770
- })]
1771
- })
1772
- })]
1773
- })
1774
- })]
1775
- });
1776
- }
1777
- function RoundedTriggerContent({ placeholder }) {
1778
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Select.Value, {
1779
- placeholder,
1780
- className: "ef-rounded-select-value"
1781
- }), /* @__PURE__ */ jsx(Select.Icon, {
1782
- className: "ef-rounded-select-chevron",
1783
- children: /* @__PURE__ */ jsx("svg", {
1784
- "aria-hidden": "true",
1785
- viewBox: "0 0 1024 1024",
1786
- width: "0.6em",
1787
- height: "0.6em",
1788
- fill: "currentColor",
1789
- children: /* @__PURE__ */ jsx("path", { d: "M957.056 338.624C951.84 327.296 940.512 320 928 320H96c-12.512 0-23.84 7.296-29.088 18.624-5.216 11.36-3.328 24.704 4.768 34.208l416 485.344c6.08 7.104 14.944 11.2 24.288 11.2s18.208-4.096 24.288-11.2l416-485.344c8.096-9.472 9.952-22.88 4.768-34.208Z" })
1790
- })
1791
- })] });
1792
- }
1793
- function RoundedOptionIndicator() {
1794
- return /* @__PURE__ */ jsx("span", {
1795
- className: "ef-rounded-select-check",
1796
- children: /* @__PURE__ */ jsx(Select.ItemIndicator, { children: /* @__PURE__ */ jsx("svg", {
1797
- "aria-hidden": "true",
1798
- width: "0.85em",
1799
- height: "0.85em",
1800
- viewBox: "0 0 24 24",
1801
- fill: "none",
1802
- stroke: "currentColor",
1803
- strokeWidth: "3",
1804
- children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
1805
- }) })
1806
- });
1807
- }
1808
- //#endregion
1809
- //#region src/game/rounded-toggle/keyboard.ts
1810
- function roundedGroupBoundary(event) {
1811
- if (event.defaultPrevented || event.key !== "Home" && event.key !== "End") return;
1812
- const options = event.currentTarget.querySelectorAll("[data-rounded-option]:not([disabled]):not([aria-disabled=\"true\"])");
1813
- const target = event.key === "Home" ? options[0] : options[options.length - 1];
1814
- if (!target) return;
1815
- event.preventDefault();
1816
- target.focus();
1817
- target.click();
1818
- }
1819
- //#endregion
1820
- //#region src/game/rounded-toggle/spring-highlight.ts
1821
- const DURATION = 650;
1822
- const SAMPLES = 65;
1823
- /** stiffness 300、damping 30、mass 1 的位移响应。 */
1824
- function roundedSpringProgress(milliseconds) {
1825
- const time = Math.max(0, milliseconds) / 1e3;
1826
- const frequency = Math.sqrt(75);
1827
- return 1 - Math.exp(-15 * time) * (Math.cos(frequency * time) + 15 / frequency * Math.sin(frequency * time));
1828
- }
1829
- const offsets = Array.from({ length: 66 }, (_, index) => ({
1830
- offset: index / SAMPLES,
1831
- time: index / SAMPLES * DURATION
1832
- }));
1833
- function springPosition(time, start, end, velocity) {
1834
- const seconds = time / 1e3;
1835
- const frequency = Math.sqrt(75);
1836
- return start + (end - start) * roundedSpringProgress(time) + velocity * Math.exp(-15 * seconds) * Math.sin(frequency * seconds) / frequency;
1837
- }
1838
- function springVelocity(time, start, end, velocity) {
1839
- const seconds = time / 1e3;
1840
- const frequency = Math.sqrt(75);
1841
- return Math.exp(-15 * seconds) * (velocity * Math.cos(frequency * seconds) + (300 * (end - start) - 15 * velocity) / frequency * Math.sin(frequency * seconds));
1842
- }
1843
- function translation(transform) {
1844
- if (transform === "none") return 0;
1845
- const values = transform.match(/^matrix\((.+)\)$/)?.[1]?.split(",");
1846
- return values ? Number.parseFloat(values[4] ?? "0") : 0;
1847
- }
1848
- function useSpringHighlight(target) {
1849
- const ref = useRef(null);
1850
- const previous = useRef(null);
1851
- const animation = useRef(null);
1852
- const movement = useRef({
1853
- start: 0,
1854
- end: 0,
1855
- velocity: 0
1856
- });
1857
- useLayoutEffect(() => {
1858
- const node = ref.current;
1859
- if (!node) return;
1860
- const before = previous.current;
1861
- previous.current = target;
1862
- if (!target) {
1863
- animation.current?.cancel();
1864
- animation.current = null;
1865
- return;
1866
- }
1867
- const from = animation.current ? getComputedStyle(node).transform : (() => {
1868
- node.style.transform = before ?? target;
1869
- return getComputedStyle(node).transform;
1870
- })();
1871
- const active = animation.current;
1872
- const velocity = active?.playState === "running" && typeof active.currentTime === "number" ? springVelocity(active.currentTime, movement.current.start, movement.current.end, movement.current.velocity) : 0;
1873
- animation.current?.cancel();
1874
- animation.current = null;
1875
- node.style.transform = target;
1876
- const media = window.matchMedia?.("(prefers-reduced-motion: reduce)");
1877
- if (!before || media?.matches || typeof node.animate !== "function") return;
1878
- const start = translation(from);
1879
- const end = translation(getComputedStyle(node).transform);
1880
- if (Math.abs(end - start) < .01 && Math.abs(velocity) < .01) return;
1881
- movement.current = {
1882
- start,
1883
- end,
1884
- velocity
1885
- };
1886
- const running = node.animate(offsets.map(({ offset, time }) => ({
1887
- offset,
1888
- transform: `translateX(${offset === 1 ? end : springPosition(time, start, end, velocity)}px)`
1889
- })), {
1890
- duration: DURATION,
1891
- easing: "linear"
1892
- });
1893
- animation.current = running;
1894
- running.onfinish = () => {
1895
- if (animation.current === running) animation.current = null;
1896
- };
1897
- }, [target]);
1898
- useLayoutEffect(() => {
1899
- const node = ref.current;
1900
- if (!node) return;
1901
- const media = window.matchMedia?.("(prefers-reduced-motion: reduce)");
1902
- const settle = () => {
1903
- animation.current?.cancel();
1904
- animation.current = null;
1905
- };
1906
- const reduced = () => {
1907
- if (media?.matches) settle();
1908
- };
1909
- media?.addEventListener("change", reduced);
1910
- const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(settle) : null;
1911
- observer?.observe(node);
1912
- return () => {
1913
- observer?.disconnect();
1914
- media?.removeEventListener("change", reduced);
1915
- settle();
1916
- };
1917
- }, []);
1918
- return ref;
1919
- }
1920
- //#endregion
1921
- //#region src/game/rounded-switch/RoundedSwitch.tsx
1922
- function RoundedSwitch({ checked, defaultChecked = false, onCheckedChange, onText = "ON", offText = "OFF", name, form, disabled: disabledProp, required: requiredProp, className, onKeyDown, ...props }) {
1923
- const field = useFieldContext();
1924
- const disabled = disabledProp ?? field?.disabled ?? false;
1925
- const required = requiredProp ?? field?.required ?? false;
1926
- const [current, setCurrent] = useControllableState({
1927
- value: checked,
1928
- defaultValue: defaultChecked,
1929
- onChange: onCheckedChange
1930
- });
1931
- const target = current ? "translateX(0%)" : "translateX(calc(100% - 1em))";
1932
- const highlightRef = useSpringHighlight(target);
1933
- return /* @__PURE__ */ jsxs(RadioGroup, {
1934
- ...props,
1935
- "aria-labelledby": props["aria-labelledby"] ?? (field && !field.group ? field.labelId : void 0),
1936
- "aria-describedby": props["aria-describedby"] ?? field?.describedBy,
1937
- "aria-invalid": field?.invalid || void 0,
1938
- value: current,
1939
- name,
1940
- form,
1941
- disabled,
1942
- required,
1943
- className: cn("ef-rounded-switch", className),
1944
- onValueChange: (next) => {
1945
- if (!disabled) setCurrent(next);
1946
- },
1947
- onKeyDown: (event) => {
1948
- onKeyDown?.(event);
1949
- roundedGroupBoundary(event);
1950
- },
1951
- children: [
1952
- /* @__PURE__ */ jsx("div", {
1953
- ref: highlightRef,
1954
- "aria-hidden": "true",
1955
- className: "ef-rounded-switch__highlight",
1956
- style: { transform: target }
1957
- }),
1958
- /* @__PURE__ */ jsx(Radio.Root, {
1959
- value: true,
1960
- nativeButton: true,
1961
- render: /* @__PURE__ */ jsx("button", { type: "button" }),
1962
- "data-rounded-option": "",
1963
- className: "ef-rounded-switch__option",
1964
- children: /* @__PURE__ */ jsx("span", { children: onText })
1965
- }),
1966
- /* @__PURE__ */ jsx(Radio.Root, {
1967
- value: false,
1968
- nativeButton: true,
1969
- render: /* @__PURE__ */ jsx("button", { type: "button" }),
1970
- "data-rounded-option": "",
1971
- className: "ef-rounded-switch__option",
1972
- children: /* @__PURE__ */ jsx("span", { children: offText })
1973
- })
1974
- ]
1975
- });
1976
- }
1977
- //#endregion
1978
- //#region src/game/rounded-toggle/RoundedToggle.tsx
1979
- function RoundedToggle({ options, value, defaultValue, onValueChange, label, name, form, required: requiredProp, disabled: disabledProp, className, onKeyDown, "aria-label": ariaLabel, ...props }) {
1980
- const field = useFieldContext();
1981
- const disabled = disabledProp ?? field?.disabled ?? false;
1982
- const required = requiredProp ?? field?.required ?? false;
1983
- const [current, setCurrent] = useControllableState({
1984
- value,
1985
- defaultValue,
1986
- onChange: (next) => {
1987
- if (next !== void 0) onValueChange?.(next);
1988
- }
1989
- });
1990
- const index = options.findIndex((option) => option.value === current);
1991
- const target = index >= 0 ? `translateX(${index * 100}%)` : null;
1992
- const highlightRef = useSpringHighlight(target);
1993
- return /* @__PURE__ */ jsxs(RadioGroup, {
1994
- ...props,
1995
- "aria-label": ariaLabel ?? label,
1996
- "aria-labelledby": props["aria-labelledby"] ?? (field && !field.group ? field.labelId : void 0),
1997
- "aria-describedby": props["aria-describedby"] ?? field?.describedBy,
1998
- "aria-invalid": field?.invalid || void 0,
1999
- value: index >= 0 ? current : null,
2000
- name,
2001
- form,
2002
- disabled,
2003
- required,
2004
- className: cn("ef-rounded-toggle", className),
2005
- onValueChange: (next) => {
2006
- if (disabled || next === null || !options.some((option) => option.value === next && !option.disabled)) return;
2007
- setCurrent(next);
2008
- },
2009
- onKeyDown: (event) => {
2010
- onKeyDown?.(event);
2011
- roundedGroupBoundary(event);
2012
- },
2013
- children: [/* @__PURE__ */ jsx("div", {
2014
- ref: highlightRef,
2015
- "aria-hidden": "true",
2016
- hidden: index < 0,
2017
- className: "ef-rounded-toggle__highlight",
2018
- style: options.length > 0 ? {
2019
- width: `${100 / options.length}%`,
2020
- transform: target ?? void 0
2021
- } : void 0
2022
- }), options.map((option) => /* @__PURE__ */ jsxs(Radio.Root, {
2023
- value: option.value,
2024
- disabled: option.disabled,
2025
- "aria-label": option["aria-label"],
2026
- nativeButton: true,
2027
- render: /* @__PURE__ */ jsx("button", { type: "button" }),
2028
- "data-rounded-option": "",
2029
- className: "ef-rounded-toggle__option",
2030
- children: [option.icon && /* @__PURE__ */ jsx("span", {
2031
- "aria-hidden": "true",
2032
- className: "ef-rounded-toggle__icon",
2033
- children: option.icon
2034
- }), /* @__PURE__ */ jsx("span", {
2035
- className: "ef-rounded-toggle__label",
2036
- children: option.label
2037
- })]
2038
- }, option.value))]
2039
- });
2040
- }
2041
- //#endregion
2042
- //#region src/game/splash-screen/EndfieldSplashScreen.tsx
2043
- /**
2044
- * 官网的开屏页:主入口的 `SplashScreen` 填上官方的标志、底图和微标。
2045
- * 排法、动画、属性都是 `SplashScreen` 的,这里只管把图放进它的插槽。
2046
- *
2047
- * 标志、标语、状态字可以换(`logo`、`tagline`、`status`);底图和微标经变量换,
2048
- * 或者用 `data-ef-game-images="off"` 整类关掉,见 docs/design/game/splash-screen.md
2049
- */
2050
- function EndfieldSplashScreen({ logo = /* @__PURE__ */ jsx("span", {
2051
- role: "img",
2052
- "aria-label": "明日方舟:终末地",
2053
- className: "ef-splash-logo"
2054
- }), tagline = "OVER THE FRONTIER / INTO THE FRONT", status = "Updating...", className, ...props }) {
2055
- return /* @__PURE__ */ jsx(SplashScreen, {
2056
- ...props,
2057
- logo,
2058
- tagline,
2059
- status,
2060
- backdrop: /* @__PURE__ */ jsx("span", { className: "ef-splash-backdrop" }),
2061
- decor: /* @__PURE__ */ jsxs("span", {
2062
- className: "ef-splash-deco",
2063
- children: [/* @__PURE__ */ jsx("span", { className: "ef-splash-deco__text" }), /* @__PURE__ */ jsx("span", { className: "ef-splash-deco__mark" })]
2064
- }),
2065
- className: cn("ef-splash", className)
2066
- });
2067
- }
2068
- //#endregion
2069
- export { AnimatedDialog, BannerAlert, EMPTY_ITEM_ICON_LAYERS, EndfieldSplashScreen, FullWidthAlert, ITEM_ICON_TRANSFORMS, ItemCard, ItemHoverCard, ItemHoverCardLayer, ItemIcon, ItemTooltipCard, RoundedButton, RoundedIconButton, RoundedSelect, RoundedSwitch, RoundedToggle, coerceItemIconTrans, itemIconTransformStyle, pickItemIconLayers };
2
+ import{AnimatedDialog as e}from"./game/animated-dialog/AnimatedDialog.js";import{RoundedButton as t}from"./game/rounded-button/RoundedButton.js";import{BannerAlert as n}from"./game/banner-alert/BannerAlert.js";import{FullWidthAlert as r}from"./game/full-width-alert/FullWidthAlert.js";import{EMPTY_ITEM_ICON_LAYERS as i,ITEM_ICON_TRANSFORMS as a,coerceItemIconTrans as o,itemIconTransformStyle as s,pickItemIconLayers as c}from"./game/item-icon/helpers.js";import{ItemIcon as l}from"./game/item-icon/ItemIcon.js";import{ItemCard as u}from"./game/item-card/ItemCard.js";import{ItemTooltipCard as d}from"./game/item-tooltip-card/ItemTooltipCard.js";import{ItemHoverCard as f,ItemHoverCardLayer as p}from"./game/item-hover-card/ItemHoverCard.js";import{RoundedIconButton as m}from"./game/rounded-button/RoundedIconButton.js";import{RoundedSelect as h}from"./game/rounded-select/RoundedSelect.js";import{RoundedSwitch as g}from"./game/rounded-switch/RoundedSwitch.js";import{RoundedToggle as _}from"./game/rounded-toggle/RoundedToggle.js";import{EndfieldSplashScreen as v}from"./game/splash-screen/EndfieldSplashScreen.js";export{e as AnimatedDialog,n as BannerAlert,i as EMPTY_ITEM_ICON_LAYERS,v as EndfieldSplashScreen,r as FullWidthAlert,a as ITEM_ICON_TRANSFORMS,u as ItemCard,f as ItemHoverCard,p as ItemHoverCardLayer,l as ItemIcon,d as ItemTooltipCard,t as RoundedButton,m as RoundedIconButton,h as RoundedSelect,g as RoundedSwitch,_ as RoundedToggle,o as coerceItemIconTrans,s as itemIconTransformStyle,c as pickItemIconLayers};