nexus-shared 1.1.21 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/CHANGELOG.md +262 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1000 -0
  4. package/dist/Client.Index.d.ts +55 -0
  5. package/dist/Client.Index.js +60 -0
  6. package/dist/Components/Chats/Chat.d.ts +28 -0
  7. package/dist/Components/Chats/Chat.js +19 -0
  8. package/dist/Components/Chats/ChatButton.d.ts +26 -0
  9. package/dist/Components/Chats/ChatButton.js +41 -0
  10. package/dist/Components/Chats/ChatComposer.d.ts +41 -0
  11. package/dist/Components/Chats/ChatComposer.js +177 -0
  12. package/dist/Components/Chats/ChatConversations.d.ts +35 -0
  13. package/dist/Components/Chats/ChatConversations.js +38 -0
  14. package/dist/Components/Chats/ChatPanel.d.ts +66 -0
  15. package/dist/Components/Chats/ChatPanel.js +94 -0
  16. package/dist/Components/Chats/ChatParts.d.ts +87 -0
  17. package/dist/Components/Chats/ChatParts.js +100 -0
  18. package/dist/Components/Chats/ChatThread.d.ts +22 -0
  19. package/dist/Components/Chats/ChatThread.js +96 -0
  20. package/dist/Components/Documents/Button.d.ts +29 -0
  21. package/dist/Components/Documents/Button.js +11 -0
  22. package/dist/Components/Documents/Menu.d.ts +102 -0
  23. package/dist/Components/Documents/Menu.js +242 -0
  24. package/dist/Components/Documents/SplitButton.d.ts +64 -0
  25. package/dist/Components/Documents/SplitButton.js +129 -0
  26. package/dist/Components/Documents/TabButtons.d.ts +80 -0
  27. package/dist/Components/Documents/TabButtons.js +38 -0
  28. package/dist/Components/Forms/ApiForm.d.ts +23 -0
  29. package/dist/Components/Forms/ApiForm.js +100 -0
  30. package/dist/Components/Forms/Crud.d.ts +17 -0
  31. package/dist/Components/Forms/Crud.js +708 -0
  32. package/dist/Components/Forms/CrudParts.d.ts +15 -0
  33. package/dist/Components/Forms/CrudParts.js +36 -0
  34. package/dist/Components/Forms/ExcelImport.d.ts +42 -0
  35. package/dist/Components/Forms/ExcelImport.js +190 -0
  36. package/dist/Components/Forms/Form.d.ts +52 -0
  37. package/dist/Components/Forms/Form.js +323 -0
  38. package/dist/Components/Forms/SubmitForm.d.ts +65 -0
  39. package/dist/Components/Forms/SubmitForm.js +198 -0
  40. package/dist/Components/Inputs/Calendar.d.ts +69 -0
  41. package/dist/Components/Inputs/Calendar.js +258 -0
  42. package/dist/Components/Inputs/CheckBox.d.ts +53 -0
  43. package/dist/Components/Inputs/CheckBox.js +87 -0
  44. package/dist/Components/Inputs/CheckBoxGroup.d.ts +20 -0
  45. package/dist/Components/Inputs/CheckBoxGroup.js +80 -0
  46. package/dist/Components/Inputs/ChoiceField.d.ts +122 -0
  47. package/dist/Components/Inputs/ChoiceField.js +169 -0
  48. package/dist/Components/Inputs/DatePicker.d.ts +54 -0
  49. package/dist/Components/Inputs/DatePicker.js +246 -0
  50. package/dist/Components/Inputs/DateRangePicker.d.ts +62 -0
  51. package/dist/Components/Inputs/DateRangePicker.js +283 -0
  52. package/dist/Components/Inputs/DateTimePicker.d.ts +75 -0
  53. package/dist/Components/Inputs/DateTimePicker.js +400 -0
  54. package/dist/Components/Inputs/Dropdown.d.ts +117 -0
  55. package/dist/Components/Inputs/Dropdown.js +839 -0
  56. package/dist/Components/Inputs/DropdownParts.d.ts +84 -0
  57. package/dist/Components/Inputs/DropdownParts.js +102 -0
  58. package/dist/Components/Inputs/EditorShell.d.ts +45 -0
  59. package/dist/Components/Inputs/EditorShell.js +214 -0
  60. package/dist/Components/Inputs/Field.d.ts +53 -0
  61. package/dist/Components/Inputs/Field.js +16 -0
  62. package/dist/Components/Inputs/GroupForm.d.ts +20 -0
  63. package/dist/Components/Inputs/GroupForm.js +172 -0
  64. package/dist/Components/Inputs/InputField.d.ts +59 -0
  65. package/dist/Components/Inputs/InputField.js +169 -0
  66. package/dist/Components/Inputs/InputRenderer.d.ts +37 -0
  67. package/dist/Components/Inputs/InputRenderer.js +99 -0
  68. package/dist/Components/Inputs/MarkdownEditor.d.ts +67 -0
  69. package/dist/Components/Inputs/MarkdownEditor.js +289 -0
  70. package/dist/Components/Inputs/NumberBox.d.ts +53 -0
  71. package/dist/Components/Inputs/NumberBox.js +228 -0
  72. package/dist/Components/Inputs/RadioGroup.d.ts +20 -0
  73. package/dist/Components/Inputs/RadioGroup.js +43 -0
  74. package/dist/Components/Inputs/ReadOnlyNotice.d.ts +36 -0
  75. package/dist/Components/Inputs/ReadOnlyNotice.js +117 -0
  76. package/dist/Components/Inputs/RichTextEditor.d.ts +103 -0
  77. package/dist/Components/Inputs/RichTextEditor.js +1170 -0
  78. package/dist/Components/Inputs/RichTextParts.d.ts +63 -0
  79. package/dist/Components/Inputs/RichTextParts.js +157 -0
  80. package/dist/Components/Inputs/RowsInput.d.ts +115 -0
  81. package/dist/Components/Inputs/RowsInput.js +308 -0
  82. package/dist/Components/Inputs/Slider.d.ts +87 -0
  83. package/dist/Components/Inputs/Slider.js +216 -0
  84. package/dist/Components/Inputs/TabularForm.d.ts +27 -0
  85. package/dist/Components/Inputs/TabularForm.js +348 -0
  86. package/dist/Components/Inputs/TextArea.d.ts +43 -0
  87. package/dist/Components/Inputs/TextArea.js +31 -0
  88. package/dist/Components/Inputs/TextBox.d.ts +52 -0
  89. package/dist/Components/Inputs/TextBox.js +58 -0
  90. package/dist/Components/Inputs/TextField.d.ts +31 -0
  91. package/dist/Components/Inputs/TextField.js +35 -0
  92. package/dist/Components/Inputs/TimePanel.d.ts +34 -0
  93. package/dist/Components/Inputs/TimePanel.js +288 -0
  94. package/dist/Components/Inputs/TimePicker.d.ts +54 -0
  95. package/dist/Components/Inputs/TimePicker.js +240 -0
  96. package/dist/Components/Inputs/TreeView.d.ts +160 -0
  97. package/dist/Components/Inputs/TreeView.js +947 -0
  98. package/dist/Components/Layouts/MessageBox.d.ts +71 -0
  99. package/dist/Components/Layouts/MessageBox.js +104 -0
  100. package/dist/Components/Layouts/Popup.d.ts +92 -0
  101. package/dist/Components/Layouts/Popup.js +376 -0
  102. package/dist/Components/Layouts/PopupContext.d.ts +2 -0
  103. package/dist/Components/Layouts/PopupContext.js +4 -0
  104. package/dist/Components/Layouts/PopupDock.d.ts +22 -0
  105. package/dist/Components/Layouts/PopupDock.js +121 -0
  106. package/dist/Components/Layouts/PopupHost.d.ts +56 -0
  107. package/dist/Components/Layouts/PopupHost.js +163 -0
  108. package/dist/Components/Layouts/PopupRules.d.ts +30 -0
  109. package/dist/Components/Layouts/PopupRules.js +63 -0
  110. package/dist/Components/Layouts/ThemePicker.d.ts +13 -0
  111. package/dist/Components/Layouts/ThemePicker.js +22 -0
  112. package/dist/Components/Layouts/ThemeScript.d.ts +14 -0
  113. package/dist/Components/Layouts/ThemeScript.js +13 -0
  114. package/dist/Components/Layouts/ThemeSwitcher.d.ts +13 -0
  115. package/dist/Components/Layouts/ThemeSwitcher.js +49 -0
  116. package/dist/Components/Layouts/Toaster.d.ts +76 -0
  117. package/dist/Components/Layouts/Toaster.js +172 -0
  118. package/dist/Components/Viewers/DataTable.d.ts +25 -0
  119. package/dist/Components/Viewers/DataTable.js +596 -0
  120. package/dist/Components/Viewers/DataTableColumns.d.ts +28 -0
  121. package/dist/Components/Viewers/DataTableColumns.js +243 -0
  122. package/dist/Components/Viewers/DataTableParts.d.ts +138 -0
  123. package/dist/Components/Viewers/DataTableParts.js +157 -0
  124. package/dist/Components/Viewers/MarkdownView.d.ts +26 -0
  125. package/dist/Components/Viewers/MarkdownView.js +79 -0
  126. package/dist/Components/Viewers/RichTextView.d.ts +18 -0
  127. package/dist/Components/Viewers/RichTextView.js +17 -0
  128. package/dist/Helpers/AnimationHelpers.d.ts +6 -0
  129. package/dist/Helpers/AnimationHelpers.js +35 -0
  130. package/dist/Helpers/ApiClient.d.ts +96 -0
  131. package/dist/Helpers/ApiClient.js +200 -0
  132. package/dist/Helpers/ApiFormHelpers.d.ts +49 -0
  133. package/dist/Helpers/ApiFormHelpers.js +120 -0
  134. package/dist/Helpers/ApiModules.d.ts +131 -0
  135. package/dist/Helpers/ApiModules.js +195 -0
  136. package/dist/Helpers/ApiResponses.d.ts +51 -0
  137. package/dist/Helpers/ApiResponses.js +250 -0
  138. package/dist/Helpers/ApiRoutes.d.ts +140 -0
  139. package/dist/Helpers/ApiRoutes.js +183 -0
  140. package/dist/Helpers/ApiToasts.d.ts +21 -0
  141. package/dist/Helpers/ApiToasts.js +22 -0
  142. package/dist/Helpers/ChatBackend.d.ts +134 -0
  143. package/dist/Helpers/ChatBackend.js +332 -0
  144. package/dist/Helpers/ChatHelpers.d.ts +189 -0
  145. package/dist/Helpers/ChatHelpers.js +486 -0
  146. package/dist/Helpers/ChatHooks.d.ts +81 -0
  147. package/dist/Helpers/ChatHooks.js +175 -0
  148. package/dist/Helpers/ChatStore.d.ts +132 -0
  149. package/dist/Helpers/ChatStore.js +394 -0
  150. package/dist/Helpers/ChatSummaries.d.ts +39 -0
  151. package/dist/Helpers/ChatSummaries.js +118 -0
  152. package/dist/Helpers/ClassHelpers.d.ts +3 -0
  153. package/dist/Helpers/ClassHelpers.js +4 -0
  154. package/dist/Helpers/CrudBackend.d.ts +98 -0
  155. package/dist/Helpers/CrudBackend.js +214 -0
  156. package/dist/Helpers/CrudHelpers.d.ts +111 -0
  157. package/dist/Helpers/CrudHelpers.js +267 -0
  158. package/dist/Helpers/DateHelpers.d.ts +88 -0
  159. package/dist/Helpers/DateHelpers.js +363 -0
  160. package/dist/Helpers/DatePreferences.d.ts +14 -0
  161. package/dist/Helpers/DatePreferences.js +94 -0
  162. package/dist/Helpers/DateTimeHelpers.d.ts +87 -0
  163. package/dist/Helpers/DateTimeHelpers.js +286 -0
  164. package/dist/Helpers/DragHelpers.d.ts +129 -0
  165. package/dist/Helpers/DragHelpers.js +281 -0
  166. package/dist/Helpers/DropdownHelpers.d.ts +56 -0
  167. package/dist/Helpers/DropdownHelpers.js +180 -0
  168. package/dist/Helpers/ExcelBackend.d.ts +106 -0
  169. package/dist/Helpers/ExcelBackend.js +290 -0
  170. package/dist/Helpers/ExcelHelpers.d.ts +98 -0
  171. package/dist/Helpers/ExcelHelpers.js +302 -0
  172. package/dist/Helpers/FormDrafts.d.ts +18 -0
  173. package/dist/Helpers/FormDrafts.js +76 -0
  174. package/dist/Helpers/FormStore.d.ts +233 -0
  175. package/dist/Helpers/FormStore.js +752 -0
  176. package/dist/Helpers/InputParamsHelpers.d.ts +79 -0
  177. package/dist/Helpers/InputParamsHelpers.js +388 -0
  178. package/dist/Helpers/MarkdownEditing.d.ts +27 -0
  179. package/dist/Helpers/MarkdownEditing.js +250 -0
  180. package/dist/Helpers/MarkdownHelpers.d.ts +82 -0
  181. package/dist/Helpers/MarkdownHelpers.js +775 -0
  182. package/dist/Helpers/MessageBuilder.d.ts +74 -0
  183. package/dist/Helpers/MessageBuilder.js +252 -0
  184. package/dist/Helpers/NepaliCalendar.d.ts +25 -0
  185. package/dist/Helpers/NepaliCalendar.js +107 -0
  186. package/dist/Helpers/NumberHelpers.d.ts +71 -0
  187. package/dist/Helpers/NumberHelpers.js +202 -0
  188. package/dist/Helpers/Permissions.d.ts +62 -0
  189. package/dist/Helpers/Permissions.js +133 -0
  190. package/dist/Helpers/PopoverHelpers.d.ts +68 -0
  191. package/dist/Helpers/PopoverHelpers.js +195 -0
  192. package/dist/Helpers/RichTextHelpers.d.ts +77 -0
  193. package/dist/Helpers/RichTextHelpers.js +1072 -0
  194. package/dist/Helpers/RowsStore.d.ts +166 -0
  195. package/dist/Helpers/RowsStore.js +606 -0
  196. package/dist/Helpers/TableColumns.d.ts +47 -0
  197. package/dist/Helpers/TableColumns.js +282 -0
  198. package/dist/Helpers/TableExport.d.ts +30 -0
  199. package/dist/Helpers/TableExport.js +97 -0
  200. package/dist/Helpers/TableHelpers.d.ts +110 -0
  201. package/dist/Helpers/TableHelpers.js +301 -0
  202. package/dist/Helpers/TableStore.d.ts +142 -0
  203. package/dist/Helpers/TableStore.js +530 -0
  204. package/dist/Helpers/ThemeHelpers.d.ts +15 -0
  205. package/dist/Helpers/ThemeHelpers.js +16 -0
  206. package/dist/Helpers/TimeHelpers.d.ts +73 -0
  207. package/dist/Helpers/TimeHelpers.js +253 -0
  208. package/dist/Helpers/TreeStore.d.ts +188 -0
  209. package/dist/Helpers/TreeStore.js +577 -0
  210. package/dist/Helpers/ValidationHelpers.d.ts +124 -0
  211. package/dist/Helpers/ValidationHelpers.js +301 -0
  212. package/dist/Interfaces/ApiInterfaces.d.ts +174 -0
  213. package/dist/Interfaces/ApiInterfaces.js +30 -0
  214. package/dist/Interfaces/ChatInterfaces.d.ts +240 -0
  215. package/{src/sso-client.tsx → dist/Interfaces/ChatInterfaces.js} +1 -1
  216. package/dist/Interfaces/CrudInterfaces.d.ts +232 -0
  217. package/dist/Interfaces/CrudInterfaces.js +1 -0
  218. package/dist/Interfaces/DateInterfaces.d.ts +154 -0
  219. package/dist/Interfaces/DateInterfaces.js +29 -0
  220. package/dist/Interfaces/ExcelInterfaces.d.ts +215 -0
  221. package/dist/Interfaces/ExcelInterfaces.js +45 -0
  222. package/dist/Interfaces/FormInterfaces.d.ts +402 -0
  223. package/dist/Interfaces/FormInterfaces.js +1 -0
  224. package/dist/Interfaces/InputInterfaces.d.ts +141 -0
  225. package/dist/Interfaces/InputInterfaces.js +1 -0
  226. package/dist/Interfaces/MessageInterfaces.d.ts +111 -0
  227. package/dist/Interfaces/MessageInterfaces.js +5 -0
  228. package/dist/Interfaces/TableInterfaces.d.ts +351 -0
  229. package/dist/Interfaces/TableInterfaces.js +1 -0
  230. package/dist/Interfaces/ThemeInterfaces.d.ts +17 -0
  231. package/dist/Interfaces/ThemeInterfaces.js +17 -0
  232. package/dist/Interfaces/TypeInterfaces.d.ts +4 -0
  233. package/dist/Interfaces/TypeInterfaces.js +1 -0
  234. package/dist/Server.Index.d.ts +2 -0
  235. package/dist/Server.Index.js +5 -0
  236. package/dist/Services/ApiProxy.d.ts +32 -0
  237. package/dist/Services/ApiProxy.js +111 -0
  238. package/dist/Services/BrowserApi.d.ts +95 -0
  239. package/dist/Services/BrowserApi.js +129 -0
  240. package/dist/Services/ChatApi.d.ts +37 -0
  241. package/dist/Services/ChatApi.js +98 -0
  242. package/dist/Services/ExcelApi.d.ts +46 -0
  243. package/dist/Services/ExcelApi.js +196 -0
  244. package/dist/Services/ServerApi.d.ts +54 -0
  245. package/dist/Services/ServerApi.js +78 -0
  246. package/dist/Services/ThemeService.d.ts +17 -0
  247. package/dist/Services/ThemeService.js +83 -0
  248. package/dist/Shared.Index.d.ts +51 -0
  249. package/dist/Shared.Index.js +55 -0
  250. package/package.json +85 -33
  251. package/src/Styles/Nexus.Base.css +70 -0
  252. package/src/Styles/Nexus.Button.css +153 -0
  253. package/src/Styles/Nexus.Calendar.css +275 -0
  254. package/src/Styles/Nexus.Chat.css +1489 -0
  255. package/src/Styles/Nexus.Choice.css +345 -0
  256. package/src/Styles/Nexus.Crud.css +161 -0
  257. package/src/Styles/Nexus.DateTime.css +81 -0
  258. package/src/Styles/Nexus.Dropdown.css +774 -0
  259. package/src/Styles/Nexus.Editor.css +297 -0
  260. package/src/Styles/Nexus.Excel.css +370 -0
  261. package/src/Styles/Nexus.Form.css +321 -0
  262. package/src/Styles/Nexus.Index.css +36 -0
  263. package/src/Styles/Nexus.Input.css +637 -0
  264. package/src/Styles/Nexus.Markdown.css +265 -0
  265. package/src/Styles/Nexus.Menu.css +259 -0
  266. package/src/Styles/Nexus.Popup.css +731 -0
  267. package/src/Styles/Nexus.RichText.css +463 -0
  268. package/src/Styles/Nexus.Rows.css +596 -0
  269. package/src/Styles/Nexus.Slider.css +278 -0
  270. package/src/Styles/Nexus.Tab.Buttons.css +419 -0
  271. package/src/Styles/Nexus.Table.css +1296 -0
  272. package/src/Styles/Nexus.Theme.Picker.css +232 -0
  273. package/src/Styles/Nexus.Themes.css +194 -0
  274. package/src/Styles/Nexus.Time.css +147 -0
  275. package/src/Styles/Nexus.Toast.css +265 -0
  276. package/src/Styles/Nexus.Tokens.css +72 -0
  277. package/src/Styles/Nexus.Tree.css +435 -0
  278. package/src/api-services/authentication-service.tsx +0 -23
  279. package/src/api-services/preference-service.tsx +0 -5
  280. package/src/api-services/system-service.tsx +0 -29
  281. package/src/client.ts +0 -31
  282. package/src/components/documents/button.tsx +0 -133
  283. package/src/components/documents/icon-box.tsx +0 -93
  284. package/src/components/documents/page-title.tsx +0 -7
  285. package/src/components/documents/tab-button.tsx +0 -172
  286. package/src/components/documents/tag.tsx +0 -30
  287. package/src/components/index.js +0 -0
  288. package/src/components/inputs/checkbox-input.tsx +0 -66
  289. package/src/components/inputs/input-box.tsx +0 -48
  290. package/src/components/inputs/input-element.tsx +0 -65
  291. package/src/components/inputs/input-form.tsx +0 -164
  292. package/src/components/inputs/input.tsx +0 -181
  293. package/src/components/inputs/number-input.tsx +0 -108
  294. package/src/components/inputs/radiobox-input.tsx +0 -53
  295. package/src/components/inputs/textarea-input.tsx +0 -47
  296. package/src/components/inputs/textbox-input.tsx +0 -45
  297. package/src/components/layouts/global-dialogbox.tsx +0 -431
  298. package/src/components/layouts/global-layout.tsx +0 -64
  299. package/src/components/layouts/layout-helpers.tsx +0 -20
  300. package/src/components/layouts/panels/user-panel.tsx +0 -112
  301. package/src/components/layouts/utility-menu.tsx +0 -49
  302. package/src/components/panels/theme-panel.tsx +0 -46
  303. package/src/helpers/bitwise-helpers.tsx +0 -11
  304. package/src/helpers/browser-helpers.tsx +0 -156
  305. package/src/helpers/datasource-helpers.tsx +0 -99
  306. package/src/helpers/element-helpers.tsx +0 -123
  307. package/src/helpers/input-helpers.tsx +0 -74
  308. package/src/helpers/string-helpers.tsx +0 -28
  309. package/src/helpers/utility-helpers.tsx +0 -45
  310. package/src/helpers/validation-helpers.tsx +0 -302
  311. package/src/index.ts +0 -26
  312. package/src/interface.ts +0 -19
  313. package/src/interfaces/auth-token-interfaces.tsx +0 -6
  314. package/src/interfaces/browser-interfaces.tsx +0 -36
  315. package/src/interfaces/button-interfaces.tsx +0 -63
  316. package/src/interfaces/datasource-interfaces.tsx +0 -22
  317. package/src/interfaces/datatable-interfaces.tsx +0 -25
  318. package/src/interfaces/dialogbox-interfaces.tsx +0 -5
  319. package/src/interfaces/exception-interfaces.tsx +0 -99
  320. package/src/interfaces/http-interfaces.tsx +0 -129
  321. package/src/interfaces/icon-interfaces.tsx +0 -129
  322. package/src/interfaces/input-interfaces.tsx +0 -410
  323. package/src/interfaces/layout-interfaces.tsx +0 -191
  324. package/src/interfaces/menu-interfaces.tsx +0 -53
  325. package/src/interfaces/message-interfaces.tsx +0 -32
  326. package/src/interfaces/permission-interfaces.tsx +0 -9
  327. package/src/interfaces/storage-interfaces.tsx +0 -5
  328. package/src/interfaces/system-interfaces.tsx +0 -22
  329. package/src/interfaces/theme-interfaces.tsx +0 -123
  330. package/src/interfaces/type-interfaces.tsx +0 -28
  331. package/src/interfaces/user-interfaces.tsx +0 -47
  332. package/src/nexus-client.tsx +0 -21
  333. package/src/nexus.environments.tsx +0 -66
  334. package/src/proxy-api/proxy-backend.tsx +0 -60
  335. package/src/proxy-api/proxy-constants.tsx +0 -28
  336. package/src/proxy-api/proxy-helpers.tsx +0 -91
  337. package/src/proxy-api-client.tsx +0 -1
  338. package/src/proxy-api-server.tsx +0 -2
  339. package/src/services/http-client-services.tsx +0 -75
  340. package/src/services/http-services.tsx +0 -158
  341. package/src/services/loader-service.tsx +0 -185
  342. package/src/services/localstorage-service.tsx +0 -119
  343. package/src/services/message-services.tsx +0 -383
  344. package/src/services/theme-service.tsx +0 -163
  345. package/src/services/user-services.tsx +0 -10
  346. package/src/sso-config/auth-token-validation.ts +0 -16
  347. package/src/sso-config/callback-route.tsx +0 -35
  348. package/src/sso-config/cookie-encryption.ts +0 -51
  349. package/src/sso-config/cookie-helpers.tsx +0 -102
  350. package/src/sso-config/forgot-password-route.tsx +0 -36
  351. package/src/sso-config/oauth-callback-state.ts +0 -61
  352. package/src/sso-config/pkce-helpers.ts +0 -9
  353. package/src/sso-config/provider-complete-route.tsx +0 -18
  354. package/src/sso-config/redirect-context-actions.tsx +0 -45
  355. package/src/sso-config/redirect-context-helpers.tsx +0 -159
  356. package/src/sso-config/redirect-context-persist.tsx +0 -18
  357. package/src/sso-config/redirect-context-route.tsx +0 -45
  358. package/src/sso-config/refresh-route.tsx +0 -23
  359. package/src/sso-config/sign-in-route.tsx +0 -74
  360. package/src/sso-config/sign-out-route.tsx +0 -57
  361. package/src/sso-config/sign-up-route.tsx +0 -57
  362. package/src/sso-config/sso-backend-flow.ts +0 -38
  363. package/src/sso-config/sso-complete-route.tsx +0 -50
  364. package/src/sso-config/sso-config.ts +0 -59
  365. package/src/sso-config/sso-interfaces.tsx +0 -99
  366. package/src/sso-config/sso-response-helpers.tsx +0 -20
  367. package/src/sso-server.tsx +0 -21
  368. package/src/styles/nexus.animation.css +0 -269
  369. package/src/styles/nexus.core.css +0 -119
  370. package/src/styles/nexus.dialog.css +0 -144
  371. package/src/styles/nexus.grid-view.css +0 -42
  372. package/src/styles/nexus.icon.css +0 -51
  373. package/src/styles/nexus.input.css +0 -207
  374. package/src/styles/nexus.loader.css +0 -11
  375. package/src/styles/nexus.logic.css +0 -47
  376. package/src/styles/nexus.utility.css +0 -347
@@ -0,0 +1,258 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { InlineIcon, iconChevronLeft, iconChevronRight } from "nexus-icons";
4
+ import { useEffect, useId, useRef, useState } from "react";
5
+ import { cx } from "../../Helpers/ClassHelpers.js";
6
+ import { addDays, addMonths, CALENDAR_RANGE, daysInMonth, formatDateParts, fromCalendar, getMonthNames, getWeekdayNames, toCalendar, toDevanagariDigits, todayIsoDate, toIsoDate, usesDevanagari, weekdayOf, } from "../../Helpers/DateHelpers.js";
7
+ import { useDatePreferences } from "../../Helpers/DatePreferences.js";
8
+ import { BS_FIRST_YEAR, BS_LAST_YEAR } from "../../Helpers/NepaliCalendar.js";
9
+ import { Button } from "../Documents/Button.js";
10
+ const ROWS = 6;
11
+ const LABEL_FORMAT = "dddd, MMMM D, YYYY";
12
+ const yearsWindow = (calendar, today, min, max) => {
13
+ const first = calendar === "bs" ? BS_FIRST_YEAR : today.year - 100;
14
+ const last = calendar === "bs" ? BS_LAST_YEAR : today.year + 50;
15
+ return { first: min ? Math.max(min.year, first) : first, last: max ? Math.min(max.year, last) : last };
16
+ };
17
+ /**
18
+ * A month of days to pick from, in the English (AD) or Nepali (BS) calendar, with month and year menus, arrow-key
19
+ * navigation, a range mode with a live preview, two months side by side with `months`, and a `renderDay` slot for
20
+ * event markers. Values are ISO dates in the Gregorian calendar whatever calendar is shown. It is the panel of
21
+ * `DatePicker` and `DateRangePicker`, and works on its own in a page.
22
+ *
23
+ * @example <Calendar value={date} onValueChange={setDate} min={todayIsoDate()} />
24
+ */
25
+ export function Calendar(props) {
26
+ const { mode = "single", value, defaultValue, onValueChange, range, defaultRange, onRangeChange, onSelect, min, max, isDateDisabled, month, defaultMonth, onMonthChange, months = 1, weekStart = 0, weekendDays, showOutsideDays = true, renderDay, footer = true, size = "md", readOnly = false, disabled = false, autoFocus = false, id, className, style, } = props;
27
+ const preferences = useDatePreferences();
28
+ const calendar = props.calendar ?? preferences.calendar;
29
+ const script = props.script ?? preferences.script;
30
+ const devanagari = usesDevanagari(calendar, script);
31
+ const lang = devanagari ? "ne" : undefined;
32
+ const isRange = mode === "range";
33
+ const inert = readOnly || disabled;
34
+ const monthCount = Math.max(1, Math.floor(months));
35
+ // Two months share their edges, so the days of a neighbour are drawn once, in their own month.
36
+ const outsideDays = showOutsideDays && monthCount === 1;
37
+ const generatedId = useId();
38
+ const rootId = id ?? generatedId;
39
+ const gridRef = useRef(null);
40
+ const focusPendingRef = useRef(false);
41
+ // The value: one day, or a start and an end.
42
+ const [ownValue, setOwnValue] = useState(() => toIsoDate(defaultValue));
43
+ const [ownRange, setOwnRange] = useState(() => [toIsoDate(defaultRange?.[0]), toIsoDate(defaultRange?.[1])]);
44
+ const selected = value !== undefined ? toIsoDate(value) : ownValue;
45
+ const [rangeStart, rangeEnd] = range !== undefined ? [toIsoDate(range[0]), toIsoDate(range[1])] : ownRange;
46
+ const picking = isRange && rangeStart !== null && rangeEnd === null;
47
+ const [hoverEnd, setHoverEnd] = useState(null);
48
+ // Limits, as ISO dates, kept inside the days the calendar covers.
49
+ const today = toIsoDate(props.today) ?? todayIsoDate();
50
+ const minIso = toIsoDate(min) ?? CALENDAR_RANGE[calendar].min;
51
+ const maxIso = toIsoDate(max) ?? CALENDAR_RANGE[calendar].max;
52
+ const clampView = (iso) => (iso < CALENDAR_RANGE[calendar].min ? CALENDAR_RANGE[calendar].min : iso > CALENDAR_RANGE[calendar].max ? CALENDAR_RANGE[calendar].max : iso);
53
+ // The month shown is remembered as a day in it, so a change of calendar keeps showing the month of that day.
54
+ const [ownView, setOwnView] = useState(() => toIsoDate(defaultMonth) ?? (isRange ? rangeStart : selected) ?? today);
55
+ const viewIso = clampView((month !== undefined ? toIsoDate(month) : null) ?? ownView);
56
+ const view = toCalendar(viewIso, calendar) ?? toCalendar(CALENDAR_RANGE[calendar].min, calendar);
57
+ const viewStart = { year: view.year, month: view.month, day: 1 };
58
+ const firstOfMonth = fromCalendar(viewStart, calendar);
59
+ // The first day after the last month shown. At the end of the Nepali table, the day after its last day.
60
+ const afterShown = fromCalendar(addMonths(viewStart, monthCount, calendar), calendar);
61
+ const shownEnd = afterShown && afterShown > firstOfMonth ? afterShown : addDays(CALENDAR_RANGE[calendar].max, 1);
62
+ // The day that takes focus, in the roving tab order of the grid: the chosen day when it is on screen, else today,
63
+ // else the first day of the month shown.
64
+ const inShown = (iso) => iso !== null && iso >= firstOfMonth && iso < shownEnd;
65
+ const [focused, setFocused] = useState(() => {
66
+ const chosen = isRange ? rangeStart : selected;
67
+ return inShown(chosen) ? chosen : inShown(today) ? today : firstOfMonth;
68
+ });
69
+ const isDisabled = (iso) => iso < minIso || iso > maxIso || (isDateDisabled?.(iso) ?? false);
70
+ function showMonth(iso) {
71
+ const next = clampView(iso);
72
+ if (month === undefined)
73
+ setOwnView(next);
74
+ const parts = toCalendar(next, calendar);
75
+ if (parts && (parts.year !== view.year || parts.month !== view.month))
76
+ onMonthChange?.(fromCalendar({ year: parts.year, month: parts.month, day: 1 }, calendar));
77
+ }
78
+ /** Shows a month picked in the menus of the month at `index`, so that month keeps its place. */
79
+ function showMonthAt(parts, index) {
80
+ showMonth(fromCalendar(addMonths({ year: parts.year, month: parts.month, day: 1 }, -index, calendar), calendar) ?? firstOfMonth);
81
+ }
82
+ function moveFocus(iso) {
83
+ if (iso < CALENDAR_RANGE[calendar].min || iso > CALENDAR_RANGE[calendar].max)
84
+ return;
85
+ setFocused(iso);
86
+ focusPendingRef.current = true;
87
+ if (iso < firstOfMonth) {
88
+ showMonth(iso);
89
+ }
90
+ else if (iso >= shownEnd) {
91
+ // Moving forward, the day lands in the last month shown.
92
+ const parts = toCalendar(iso, calendar);
93
+ if (parts)
94
+ showMonth(fromCalendar(addMonths({ year: parts.year, month: parts.month, day: 1 }, 1 - monthCount, calendar), calendar) ?? iso);
95
+ }
96
+ if (picking)
97
+ setHoverEnd(iso);
98
+ }
99
+ function pick(iso) {
100
+ if (inert || isDisabled(iso))
101
+ return;
102
+ setFocused(iso);
103
+ if (!isRange) {
104
+ if (value === undefined)
105
+ setOwnValue(iso);
106
+ onValueChange?.(iso);
107
+ onSelect?.(iso);
108
+ return;
109
+ }
110
+ if (!picking) {
111
+ if (range === undefined)
112
+ setOwnRange([iso, null]);
113
+ setHoverEnd(null);
114
+ onRangeChange?.([iso, null]);
115
+ return;
116
+ }
117
+ const next = iso < rangeStart ? [iso, rangeStart] : [rangeStart, iso];
118
+ if (range === undefined)
119
+ setOwnRange(next);
120
+ setHoverEnd(null);
121
+ onRangeChange?.(next);
122
+ onSelect?.(next[1]);
123
+ }
124
+ function clear() {
125
+ if (inert)
126
+ return;
127
+ if (isRange) {
128
+ if (range === undefined)
129
+ setOwnRange([null, null]);
130
+ setHoverEnd(null);
131
+ onRangeChange?.([null, null]);
132
+ }
133
+ else {
134
+ if (value === undefined)
135
+ setOwnValue(null);
136
+ onValueChange?.(null);
137
+ }
138
+ }
139
+ function goToday() {
140
+ showMonth(today);
141
+ moveFocus(today);
142
+ if (!isRange)
143
+ pick(today);
144
+ }
145
+ // Focus follows the roving day after the grid renders it, e.g. after an arrow key moved to another month.
146
+ useEffect(() => {
147
+ if (!focusPendingRef.current || !focused)
148
+ return;
149
+ focusPendingRef.current = false;
150
+ gridRef.current?.querySelector(`[data-iso="${focused}"]`)?.focus();
151
+ });
152
+ useEffect(() => {
153
+ if (autoFocus)
154
+ gridRef.current?.querySelector('[role="gridcell"][tabindex="0"]')?.focus();
155
+ // eslint-disable-next-line react-hooks/exhaustive-deps
156
+ }, []);
157
+ function onKeyDown(event) {
158
+ const target = event.target;
159
+ const current = target.dataset.iso;
160
+ if (!current)
161
+ return;
162
+ const { key } = event;
163
+ let next = null;
164
+ if (key === "ArrowLeft")
165
+ next = addDays(current, -1);
166
+ else if (key === "ArrowRight")
167
+ next = addDays(current, 1);
168
+ else if (key === "ArrowUp")
169
+ next = addDays(current, -7);
170
+ else if (key === "ArrowDown")
171
+ next = addDays(current, 7);
172
+ else if (key === "Home")
173
+ next = addDays(current, -((weekdayOf(current) - weekStart + 7) % 7));
174
+ else if (key === "End")
175
+ next = addDays(current, 6 - ((weekdayOf(current) - weekStart + 7) % 7));
176
+ else if (key === "PageUp" || key === "PageDown") {
177
+ const parts = toCalendar(current, calendar);
178
+ if (parts)
179
+ next = fromCalendar(addMonths(parts, (key === "PageUp" ? -1 : 1) * (event.shiftKey ? 12 : 1), calendar), calendar);
180
+ }
181
+ else if (key === "Enter" || key === " ") {
182
+ event.preventDefault();
183
+ pick(current);
184
+ return;
185
+ }
186
+ if (next) {
187
+ event.preventDefault();
188
+ moveFocus(next);
189
+ }
190
+ }
191
+ function onPointerOver(event) {
192
+ if (!picking)
193
+ return;
194
+ const iso = event.target.closest("[data-iso]")?.dataset.iso ?? null;
195
+ if (iso !== hoverEnd)
196
+ setHoverEnd(iso);
197
+ }
198
+ // The range band: between the two ends, or between the start and the day under the pointer while picking.
199
+ const bandEnd = rangeEnd ?? (picking ? hoverEnd : null);
200
+ const [bandStart, bandStop] = rangeStart && bandEnd ? (bandEnd < rangeStart ? [bandEnd, rangeStart] : [rangeStart, bandEnd]) : [null, null];
201
+ const holidays = weekendDays ?? (calendar === "bs" ? [6] : []);
202
+ const monthNames = getMonthNames(calendar, script);
203
+ const digits = (n) => (devanagari ? toDevanagariDigits(String(n)) : String(n));
204
+ const monthLabel = (m) => monthNames[m - 1] ?? "";
205
+ // The grids: always six rows each, so the panel keeps its height from month to month.
206
+ const monthViews = [];
207
+ for (let index = 0; index < monthCount; index++) {
208
+ const parts = addMonths(viewStart, index, calendar);
209
+ const first = fromCalendar(parts, calendar);
210
+ if (!first || (index > 0 && first <= monthViews[index - 1].first))
211
+ break;
212
+ const monthLength = daysInMonth(parts.year, parts.month, calendar);
213
+ const lead = (weekdayOf(first) - weekStart + 7) % 7;
214
+ const cells = [];
215
+ for (let cell = 0; cell < ROWS * 7; cell++) {
216
+ const iso = addDays(first, cell - lead);
217
+ const outside = cell < lead || cell >= lead + monthLength;
218
+ const dayParts = toCalendar(iso, calendar);
219
+ if (!dayParts || (outside && !outsideDays)) {
220
+ cells.push(null);
221
+ continue;
222
+ }
223
+ const weekday = weekdayOf(iso);
224
+ cells.push({
225
+ iso,
226
+ parts: dayParts,
227
+ weekday,
228
+ outside,
229
+ today: iso === today,
230
+ selected: isRange ? iso === rangeStart || iso === rangeEnd : iso === selected,
231
+ inRange: bandStart !== null && iso > bandStart && iso < bandStop,
232
+ disabled: inert || isDisabled(iso),
233
+ rangeStart: isRange && iso === bandStart && bandStop !== bandStart,
234
+ rangeEnd: isRange && iso === bandStop && bandStop !== bandStart,
235
+ });
236
+ }
237
+ monthViews.push({ first, parts, title: `${monthLabel(parts.month)} ${digits(parts.year)}`, cells });
238
+ }
239
+ const focusIso = focused && monthViews.some(view => view.cells.some(cell => cell?.iso === focused)) ? focused : (monthViews[0]?.cells.find(cell => cell && !cell.outside)?.iso ?? null);
240
+ // Header menus and arrows
241
+ const todayParts = toCalendar(today, calendar) ?? view;
242
+ const years = yearsWindow(calendar, todayParts, toIsoDate(min) ? toCalendar(minIso, calendar) : null, toIsoDate(max) ? toCalendar(maxIso, calendar) : null);
243
+ const lastShownYear = monthViews[monthViews.length - 1]?.parts.year ?? view.year;
244
+ const yearOptions = [];
245
+ for (let year = Math.min(years.first, view.year); year <= Math.max(years.last, lastShownYear); year++)
246
+ yearOptions.push(year);
247
+ const prevMonth = fromCalendar(addMonths(viewStart, -1, calendar), calendar) ?? firstOfMonth;
248
+ const nextMonth = fromCalendar(addMonths(viewStart, 1, calendar), calendar) ?? firstOfMonth;
249
+ const canGoPrev = prevMonth < firstOfMonth && addDays(firstOfMonth, -1) >= minIso;
250
+ const canGoNext = nextMonth > firstOfMonth && shownEnd <= maxIso;
251
+ const title = monthViews.map(view => view.title).join(" – ");
252
+ const weekdayNames = getWeekdayNames(calendar, script);
253
+ const weekdayMinNames = getWeekdayNames(calendar, script, "min");
254
+ return (_jsxs("div", { id: rootId, className: cx("nx-cal", `nx-cal--${size}`, isRange && "nx-cal--range", monthViews.length > 1 && "nx-cal--months", className), style: style, "data-disabled": disabled || undefined, "data-readonly": readOnly || undefined, "aria-label": props["aria-label"], "aria-labelledby": props["aria-labelledby"], children: [_jsx("div", { ref: gridRef, className: "nx-cal__months", children: monthViews.map((monthView, index) => (_jsxs("div", { className: "nx-cal__month", children: [_jsxs("div", { className: "nx-cal__head", children: [index === 0 ? (_jsx("button", { type: "button", className: "nx-cal__nav", "aria-label": "Previous month", disabled: disabled || !canGoPrev, onClick: () => showMonth(prevMonth), children: _jsx(InlineIcon, { icon: iconChevronLeft }) })) : (_jsx("span", { className: "nx-cal__nav nx-cal__nav--space", "aria-hidden": "true" })), _jsxs("div", { className: "nx-cal__menus", children: [_jsx("select", { className: "nx-cal__select", "aria-label": "Month", lang: lang, value: monthView.parts.month, disabled: disabled, onChange: event => showMonthAt({ year: monthView.parts.year, month: Number(event.target.value), day: 1 }, index), children: monthNames.map((name, monthIndex) => (_jsx("option", { value: monthIndex + 1, children: name }, name))) }), _jsx("select", { className: "nx-cal__select", "aria-label": "Year", lang: lang, value: monthView.parts.year, disabled: disabled, onChange: event => showMonthAt({ year: Number(event.target.value), month: monthView.parts.month, day: 1 }, index), children: yearOptions.map(year => (_jsx("option", { value: year, children: digits(year) }, year))) })] }), index === monthViews.length - 1 ? (_jsx("button", { type: "button", className: "nx-cal__nav", "aria-label": "Next month", disabled: disabled || !canGoNext, onClick: () => showMonth(nextMonth), children: _jsx(InlineIcon, { icon: iconChevronRight }) })) : (_jsx("span", { className: "nx-cal__nav nx-cal__nav--space", "aria-hidden": "true" }))] }), _jsxs("div", { className: "nx-cal__grid", role: "grid", "aria-label": monthView.title, "aria-multiselectable": isRange || undefined, onKeyDown: onKeyDown, onPointerOver: onPointerOver, onPointerLeave: () => picking && setHoverEnd(null), children: [_jsx("div", { className: "nx-cal__row", role: "row", children: Array.from({ length: 7 }, (_, column) => {
255
+ const weekday = (weekStart + column) % 7;
256
+ return (_jsx("div", { className: "nx-cal__weekday", role: "columnheader", lang: lang, "data-weekend": holidays.includes(weekday) || undefined, "aria-label": weekdayNames[weekday], title: weekdayNames[weekday], children: weekdayMinNames[weekday] }, weekday));
257
+ }) }), Array.from({ length: ROWS }, (_, row) => (_jsx("div", { className: "nx-cal__row", role: "row", children: monthView.cells.slice(row * 7, row * 7 + 7).map((cell, column) => cell ? (_jsx("button", { type: "button", role: "gridcell", className: "nx-cal__day", lang: lang, "data-iso": cell.iso, "data-outside": cell.outside || undefined, "data-today": cell.today || undefined, "data-weekend": holidays.includes(cell.weekday) || undefined, "data-in-range": cell.inRange || undefined, "data-range-start": cell.rangeStart || undefined, "data-range-end": cell.rangeEnd || undefined, "aria-selected": cell.selected, "aria-disabled": cell.disabled || undefined, "aria-current": cell.today ? "date" : undefined, "aria-label": formatDateParts(cell.parts, calendar, LABEL_FORMAT, script, cell.weekday), tabIndex: cell.iso === focusIso ? 0 : -1, onClick: () => pick(cell.iso), onFocus: () => setFocused(cell.iso), children: renderDay ? renderDay(cell) : _jsx("span", { className: "nx-cal__num", children: digits(cell.parts.day) }) }, cell.iso)) : (_jsx("div", { className: "nx-cal__day nx-cal__day--empty", role: "gridcell", "aria-hidden": "true" }, `empty-${row}-${column}`))) }, row)))] })] }, monthView.first))) }), _jsx("p", { className: "nx-visually-hidden", "aria-live": "polite", lang: lang, children: title }), footer && (_jsxs("div", { className: "nx-cal__foot", children: [_jsx(Button, { size: "sm", variant: "ghost", hoverTone: "primary", disabled: inert || isDisabled(today), onClick: goToday, children: "Today" }), _jsx(Button, { size: "sm", variant: "ghost", disabled: inert || (isRange ? rangeStart === null : selected === null), onClick: clear, children: "Clear" })] }))] }));
258
+ }
@@ -0,0 +1,53 @@
1
+ import { type ChangeEvent, type ComponentPropsWithRef, type ReactNode } from "react";
2
+ import type { CheckRules, ValidateOn } from "../../Interfaces/InputInterfaces.ts";
3
+ import type { Size } from "../../Interfaces/TypeInterfaces.ts";
4
+ type NativeInputProps = Omit<ComponentPropsWithRef<"input">, "type" | "size" | "children" | keyof CheckRules>;
5
+ export interface CheckBoxProps extends NativeInputProps, CheckRules {
6
+ label?: ReactNode;
7
+ /** A second, muted line under the label. */
8
+ description?: ReactNode;
9
+ /** An error from outside, such as a server message. */
10
+ error?: string | null;
11
+ /** Default `md`. */
12
+ size?: Size;
13
+ /** `end` (default) puts the label after the box. `start` puts it first and fills the width, as in a settings list. */
14
+ labelPosition?: "end" | "start";
15
+ /** Can be clicked and focused but not changed; still sent with a form when checked. A lock follows the label, and a click shows a note. */
16
+ readOnly?: boolean;
17
+ /** What a read-only box says when someone tries to change it. Default "Read-only: this option cannot be changed." ("this setting" for a switch). */
18
+ readOnlyMessage?: string;
19
+ /** Name used in messages: "Terms must be checked." Without it: "Check this box to continue." */
20
+ fieldName?: string;
21
+ /** When the message shows. Default `blur`; submitting a form always shows it. */
22
+ validateOn?: ValidateOn;
23
+ /** The new state after each change. */
24
+ onValueChange?: (checked: boolean, event: ChangeEvent<HTMLInputElement>) => void;
25
+ /** Class of the outer field. `inputClassName` goes on the input. */
26
+ className?: string;
27
+ inputClassName?: string;
28
+ }
29
+ export interface CheckBoxOnlyProps {
30
+ /** Shows a dash for "some chosen", e.g. a select-all box. A click clears it. */
31
+ indeterminate?: boolean;
32
+ }
33
+ /**
34
+ * A checkbox with a label. Uncontrolled by default (`defaultChecked`); `checked` with `onValueChange` also works.
35
+ * `required` means it must be checked. Drawn from the native input, so it stays one element and works in any form.
36
+ *
37
+ * @example <CheckBox name="terms" label="I accept the booking terms" required />
38
+ */
39
+ export declare function CheckBox({ indeterminate, ...props }: CheckBoxProps & CheckBoxOnlyProps): import("react").JSX.Element;
40
+ /**
41
+ * An on/off switch for a setting that takes effect at once. The same props as `CheckBox`, announced as a switch.
42
+ *
43
+ * @example <Switch name="breakfast" label="Breakfast included" labelPosition="start" defaultChecked />
44
+ */
45
+ export declare function Switch(props: CheckBoxProps): import("react").JSX.Element;
46
+ /**
47
+ * One radio button that is on or off, with the same props as `CheckBox`. A click only turns it on. Tabular and group
48
+ * forms use it for a value one row has at a time, such as the primary address; for a choice from a list, use `RadioGroup`.
49
+ *
50
+ * @example <RadioButton label="Primary" defaultChecked onValueChange={on => on && makePrimary(row)} />
51
+ */
52
+ export declare function RadioButton(props: CheckBoxProps): import("react").JSX.Element;
53
+ export {};
@@ -0,0 +1,87 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useLayoutEffect, useRef } from "react";
4
+ import { cx } from "../../Helpers/ClassHelpers.js";
5
+ import { validateCheck } from "../../Helpers/ValidationHelpers.js";
6
+ import { assignRef, GroupFooter, leavesField, OPTION_ATTRIBUTE, optionAnchor, preventChange, useChoiceField } from "./ChoiceField.js";
7
+ import { hasContent } from "./Field.js";
8
+ import { useReadOnlyNotice } from "./ReadOnlyNotice.js";
9
+ /**
10
+ * A checkbox with a label. Uncontrolled by default (`defaultChecked`); `checked` with `onValueChange` also works.
11
+ * `required` means it must be checked. Drawn from the native input, so it stays one element and works in any form.
12
+ *
13
+ * @example <CheckBox name="terms" label="I accept the booking terms" required />
14
+ */
15
+ export function CheckBox({ indeterminate, ...props }) {
16
+ return _jsx(Toggle, { ...props, kind: "checkbox", indeterminate: indeterminate });
17
+ }
18
+ /**
19
+ * An on/off switch for a setting that takes effect at once. The same props as `CheckBox`, announced as a switch.
20
+ *
21
+ * @example <Switch name="breakfast" label="Breakfast included" labelPosition="start" defaultChecked />
22
+ */
23
+ export function Switch(props) {
24
+ return _jsx(Toggle, { ...props, kind: "switch" });
25
+ }
26
+ /**
27
+ * One radio button that is on or off, with the same props as `CheckBox`. A click only turns it on. Tabular and group
28
+ * forms use it for a value one row has at a time, such as the primary address; for a choice from a list, use `RadioGroup`.
29
+ *
30
+ * @example <RadioButton label="Primary" defaultChecked onValueChange={on => on && makePrimary(row)} />
31
+ */
32
+ export function RadioButton(props) {
33
+ return _jsx(Toggle, { ...props, kind: "radio" });
34
+ }
35
+ function Toggle(props) {
36
+ const { kind, label, description, error, size = "md", labelPosition = "end", indeterminate, readOnly = false, readOnlyMessage = kind === "switch" ? "Read-only: this setting cannot be changed." : kind === "radio" ? "Read-only: this choice cannot be changed." : "Read-only: this option cannot be changed.", required, validate, fieldName, validateOn, onValueChange, className, inputClassName, style, id, checked, disabled, ref, onChange, onClick, onKeyDown, ...inputProps } = props;
37
+ const inputRef = useRef(null);
38
+ const field = useChoiceField({ id, label, fieldName, error, validateOn, nameFromLabel: false }, {
39
+ check: ([input], name) => (input ? validateCheck(input.checked, { required, validate }, name) : null),
40
+ checkKeys: [checked, required, validate],
41
+ });
42
+ const setRef = useCallback((node) => {
43
+ inputRef.current = node;
44
+ assignRef(ref, node);
45
+ }, [ref]);
46
+ useLayoutEffect(() => {
47
+ if (inputRef.current && kind === "checkbox")
48
+ inputRef.current.indeterminate = Boolean(indeterminate);
49
+ }, [indeterminate, kind]);
50
+ // A lock after the label, and a note under the row when someone tries to change it. With the label first, the
51
+ // control sits at the end of the row, so the note lines up with that end.
52
+ const readOnlyNotice = useReadOnlyNotice(readOnly && !disabled, inputRef, readOnlyMessage, {
53
+ anchor: optionAnchor,
54
+ align: labelPosition === "start" ? "end" : "start",
55
+ typing: false,
56
+ lock: "label",
57
+ });
58
+ function handleClick(event) {
59
+ if (!readOnly) {
60
+ onClick?.(event);
61
+ return;
62
+ }
63
+ preventChange(event);
64
+ readOnlyNotice.onClick(event);
65
+ }
66
+ function handleKeyDown(event) {
67
+ readOnlyNotice.onKeyDown(event);
68
+ onKeyDown?.(event);
69
+ }
70
+ function handleBlur(event) {
71
+ if (leavesField(event))
72
+ readOnlyNotice.hide();
73
+ field.onBlur(event);
74
+ }
75
+ function handleChange(event) {
76
+ if (readOnly)
77
+ return;
78
+ field.onChange();
79
+ onChange?.(event);
80
+ onValueChange?.(event.currentTarget.checked, event);
81
+ }
82
+ const descriptionId = hasContent(description) ? `${field.fieldId}-description` : undefined;
83
+ // With a description, the name comes from the label text alone; the description is read as a description.
84
+ const labelId = descriptionId && hasContent(label) && !inputProps["aria-label"] ? `${field.fieldId}-label` : undefined;
85
+ const describedBy = [inputProps["aria-describedby"], descriptionId, field.error && field.messageId].filter(Boolean).join(" ") || undefined;
86
+ return (_jsxs("div", { ref: field.containerRef, className: cx("nx-choice-field", className), style: style, "data-invalid": field.error ? true : undefined, "data-readonly": readOnly || undefined, onBlur: handleBlur, children: [_jsxs("label", { className: cx("nx-choice", `nx-choice--${size}`, labelPosition === "start" && "nx-choice--start"), children: [_jsx("input", { ...inputProps, [OPTION_ATTRIBUTE]: 0, ref: setRef, id: field.fieldId, type: kind === "radio" ? "radio" : "checkbox", role: kind === "switch" ? "switch" : undefined, className: cx("nx-choice__control", `nx-choice__control--${kind}`, inputClassName), checked: checked, disabled: disabled, "aria-invalid": field.error ? true : undefined, "aria-required": required || undefined, "aria-readonly": readOnly || undefined, "aria-labelledby": inputProps["aria-labelledby"] ?? labelId, "aria-describedby": describedBy, onClick: handleClick, onKeyDown: handleKeyDown, onChange: handleChange, onInvalid: field.onInvalid }), (hasContent(label) || descriptionId) && (_jsxs("span", { className: "nx-choice__text", children: [hasContent(label) && (_jsxs("span", { id: labelId, className: "nx-choice__label", children: [label, readOnlyNotice.lock] })), descriptionId && (_jsx("span", { id: descriptionId, className: "nx-choice__description", children: description }))] }))] }), _jsx(GroupFooter, { id: field.messageId, error: field.error }), readOnlyNotice.notice] }));
87
+ }
@@ -0,0 +1,20 @@
1
+ import { type ChangeEvent, type ReactNode } from "react";
2
+ import type { OptionValue, SelectionRules } from "../../Interfaces/InputInterfaces.ts";
3
+ import { type ChoiceGroupProps } from "./ChoiceField.tsx";
4
+ export interface CheckBoxGroupProps<T extends OptionValue = string> extends ChoiceGroupProps<T>, Omit<SelectionRules<T>, "required"> {
5
+ /** The chosen values. With `value`, the group is controlled; pair it with `onValueChange`. */
6
+ value?: readonly T[];
7
+ defaultValue?: readonly T[];
8
+ /** Adds a "Select all" box above the options (`true`), or one with this label. Not shown with `max`. */
9
+ selectAll?: boolean | ReactNode;
10
+ /** The chosen values, in option order, after each change. */
11
+ onValueChange?: (values: T[], event: ChangeEvent<HTMLElement>) => void;
12
+ }
13
+ /**
14
+ * Several choices from a list of options, such as amenities or permissions. `min` and `max` limit the count; at `max`,
15
+ * the other options are disabled and a count shows under the group. Clicking an option re-renders nothing. Read-only
16
+ * (default note "Read-only: these options cannot be changed.") shows a lock after the label and a note under a clicked option.
17
+ *
18
+ * @example <CheckBoxGroup name="amenities" label="Amenities" columns={3} options={[{ value: "wifi", label: "Wi-Fi" }]} />
19
+ */
20
+ export declare function CheckBoxGroup<T extends OptionValue = string>(props: CheckBoxGroupProps<T>): import("react").JSX.Element;
@@ -0,0 +1,80 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useRef } from "react";
4
+ import { validateSelection } from "../../Helpers/ValidationHelpers.js";
5
+ import { ChoiceItem, ChoiceLegend, GroupFooter, groupLayout, leavesField, OPTION_ATTRIBUTE, optionAnchor, useChoiceField } from "./ChoiceField.js";
6
+ import { useReadOnlyNotice } from "./ReadOnlyNotice.js";
7
+ /**
8
+ * Several choices from a list of options, such as amenities or permissions. `min` and `max` limit the count; at `max`,
9
+ * the other options are disabled and a count shows under the group. Clicking an option re-renders nothing. Read-only
10
+ * (default note "Read-only: these options cannot be changed.") shows a lock after the label and a note under a clicked option.
11
+ *
12
+ * @example <CheckBoxGroup name="amenities" label="Amenities" columns={3} options={[{ value: "wifi", label: "Wi-Fi" }]} />
13
+ */
14
+ export function CheckBoxGroup(props) {
15
+ const { options, name, label, hint, required, min, max, validate, value, defaultValue, selectAll, readOnly = false, disabled, onValueChange } = props;
16
+ const { readOnlyMessage = "Read-only: these options cannot be changed." } = props;
17
+ const { size = "md" } = props;
18
+ const allRef = useRef(null);
19
+ const countRef = useRef(null);
20
+ const chosen = (inputs) => inputs.filter(input => input.checked).map(input => options[Number(input.getAttribute(OPTION_ATTRIBUTE))].value);
21
+ const field = useChoiceField(props, {
22
+ check: (inputs, fieldName) => validateSelection(chosen(inputs), { required, min, max, validate }, fieldName),
23
+ checkKeys: [value, required, min, max, validate, options],
24
+ sync,
25
+ });
26
+ /** Writes the count, the select-all state, and the limit straight to the DOM. */
27
+ function sync(inputs) {
28
+ const count = inputs.filter(input => input.checked).length;
29
+ if (countRef.current)
30
+ countRef.current.textContent = String(count);
31
+ if (max !== undefined) {
32
+ for (const input of inputs) {
33
+ const limited = count >= max && !input.checked;
34
+ if (limited && !input.disabled) {
35
+ input.disabled = true;
36
+ input.dataset.nxLimit = "";
37
+ }
38
+ else if (!limited && input.dataset.nxLimit !== undefined) {
39
+ input.disabled = false;
40
+ delete input.dataset.nxLimit;
41
+ }
42
+ }
43
+ }
44
+ const all = allRef.current;
45
+ if (all) {
46
+ const available = inputs.filter(input => !input.disabled);
47
+ const availableChosen = available.filter(input => input.checked).length;
48
+ all.checked = available.length > 0 && availableChosen === available.length;
49
+ all.indeterminate = availableChosen > 0 && availableChosen < available.length;
50
+ all.disabled = available.length === 0;
51
+ }
52
+ }
53
+ function toggleAll(event) {
54
+ if (readOnly)
55
+ return;
56
+ const checked = event.currentTarget.checked;
57
+ for (const input of field.inputs())
58
+ if (!input.disabled)
59
+ input.checked = checked;
60
+ }
61
+ function handleChange(event) {
62
+ if (readOnly)
63
+ return;
64
+ field.onChange();
65
+ onValueChange?.(chosen(field.inputs()), event);
66
+ }
67
+ // Clicks and focus bubble to the fieldset, so one handler covers every option.
68
+ const readOnlyNotice = useReadOnlyNotice(readOnly && !disabled, field.containerRef, readOnlyMessage, { anchor: optionAnchor, typing: false, lock: "label" });
69
+ function handleBlur(event) {
70
+ if (leavesField(event))
71
+ readOnlyNotice.hide();
72
+ field.onBlur(event);
73
+ }
74
+ const invalid = Boolean(field.error);
75
+ const layout = groupLayout(props);
76
+ const groupName = name ?? field.fieldId;
77
+ const selected = value ?? defaultValue ?? [];
78
+ const showAll = Boolean(selectAll) && max === undefined;
79
+ return (_jsxs("fieldset", { ref: field.containerRef, id: field.fieldId, className: layout.className, style: props.style, disabled: disabled, "data-invalid": invalid || undefined, "data-readonly": readOnly || undefined, "aria-label": props["aria-label"], "aria-labelledby": props["aria-labelledby"], "aria-describedby": field.error || hint ? field.messageId : undefined, onChange: handleChange, onClick: readOnlyNotice.onClick, onKeyDown: readOnlyNotice.onKeyDown, onBlur: handleBlur, children: [_jsx(ChoiceLegend, { label: label, required: required, lock: readOnlyNotice.lock }), showAll && (_jsxs("label", { className: `nx-choice nx-choice--${size} nx-choices__all`, children: [_jsx("input", { ref: allRef, type: "checkbox", className: "nx-choice__control nx-choice__control--checkbox", "aria-controls": options.map((_, index) => `${field.fieldId}-${index}`).join(" "), onClick: readOnly ? event => event.preventDefault() : undefined, onChange: toggleAll }), _jsx("span", { className: "nx-choice__text", children: _jsx("span", { className: "nx-choice__label", children: selectAll === true ? "Select all" : selectAll }) })] })), _jsx("div", { className: "nx-choices__options", style: layout.optionsStyle, children: options.map((option, index) => (_jsx(ChoiceItem, { type: "checkbox", groupId: field.fieldId, name: groupName, option: option, index: index, size: size, checked: value ? value.includes(option.value) : undefined, defaultChecked: defaultValue?.includes(option.value), invalid: invalid, readOnly: readOnly, onInvalid: field.onInvalid }, String(option.value)))) }), _jsx(GroupFooter, { id: field.messageId, hint: hint, error: field.error, aside: max !== undefined && (_jsxs(_Fragment, { children: [_jsx("span", { ref: countRef, children: options.filter(option => selected.includes(option.value)).length }), "/", max] })) }), readOnlyNotice.notice] }));
80
+ }
@@ -0,0 +1,122 @@
1
+ import { type CSSProperties, type FocusEvent, type FormEvent, type MouseEvent, type ReactNode, type Ref } from "react";
2
+ import type { ChoiceDesign, ChoiceOption, OptionValue, ValidateOn } from "../../Interfaces/InputInterfaces.ts";
3
+ import type { Size } from "../../Interfaces/TypeInterfaces.ts";
4
+ /** Marks the inputs that are options of a choice field, so a "select all" box beside them is not counted. */
5
+ export declare const OPTION_ATTRIBUTE = "data-nx-option";
6
+ export interface ChoiceFieldOptions {
7
+ id?: string;
8
+ label?: ReactNode;
9
+ fieldName?: string;
10
+ error?: string | null;
11
+ validateOn?: ValidateOn;
12
+ /** Uses a text label as the field name in messages. Off for a single checkbox, whose label is usually a sentence. */
13
+ nameFromLabel?: boolean;
14
+ }
15
+ export interface ChoiceFieldRules {
16
+ /** The field's message for its option inputs, or `null` when valid. */
17
+ check: (inputs: HTMLInputElement[], name: string | undefined) => string | null;
18
+ /** Everything `check` depends on (rules, a controlled value). The field is checked again when one changes. */
19
+ checkKeys: readonly unknown[];
20
+ /** Writes what follows from the choices straight to the DOM (a count, limits, a select-all box), after every change and reset. */
21
+ sync?: (inputs: HTMLInputElement[]) => void;
22
+ }
23
+ /**
24
+ * Behavior shared by checkboxes, switches, radio groups, and sliders (fields made of native inputs in a container): ids, validation messages, and form integration, with the
25
+ * same timing as a text box. A message shows once focus leaves a field that was changed, or on submit, and then follows
26
+ * every change. Validity is set on the first option with `setCustomValidity`, so a plain `<form>` blocks submit and
27
+ * focuses it. Clicking an option re-renders nothing unless its message changes.
28
+ */
29
+ export declare function useChoiceField<E extends HTMLElement>(options: ChoiceFieldOptions, rules: ChoiceFieldRules): {
30
+ fieldId: string;
31
+ messageId: string;
32
+ containerRef: import("react").RefObject<E | null>;
33
+ error: string | null;
34
+ inputs: () => HTMLInputElement[];
35
+ onChange: () => void;
36
+ onBlur: (event: FocusEvent<E>) => void;
37
+ onInvalid: (event: FormEvent<HTMLInputElement>) => void;
38
+ };
39
+ /** Stops a click from changing a read-only option. The value stays in the form. */
40
+ export declare function preventChange(event: MouseEvent<HTMLInputElement>): void;
41
+ /**
42
+ * Where a read-only choice shows its note: under the option whose input was clicked (a click on its label text
43
+ * reaches the input too), or pressed with Space or an arrow key, which browsers turn into a click.
44
+ */
45
+ export declare function optionAnchor(target: Element): Element | null;
46
+ /** Hides a field's read-only note when focus leaves the field, not when it moves between its options. */
47
+ export declare function leavesField(event: FocusEvent<HTMLElement>): boolean;
48
+ /** Points a ref given by the caller at the same node as our own. */
49
+ export declare function assignRef<T>(ref: Ref<T> | undefined, node: T | null): void;
50
+ export interface ChoiceItemProps<T extends OptionValue> {
51
+ type: "checkbox" | "radio";
52
+ groupId: string;
53
+ name: string;
54
+ option: ChoiceOption<T>;
55
+ index: number;
56
+ size: Size;
57
+ /** Controlled state; `undefined` leaves the option uncontrolled with `defaultChecked`. */
58
+ checked?: boolean;
59
+ defaultChecked?: boolean;
60
+ invalid: boolean;
61
+ readOnly: boolean;
62
+ onInvalid: (event: FormEvent<HTMLInputElement>) => void;
63
+ }
64
+ /** One option of a group: a native input and its label, icon, and description, all inside one clickable label. */
65
+ export declare function ChoiceItem<T extends OptionValue>({ type, groupId, name, option, index, size, checked, defaultChecked, invalid, readOnly, onInvalid }: ChoiceItemProps<T>): import("react").JSX.Element;
66
+ /** The legend of a choice group, with the required mark and, when read-only, a lock. */
67
+ export declare function ChoiceLegend({ label, required, lock }: {
68
+ label: ReactNode;
69
+ required?: boolean;
70
+ lock?: ReactNode;
71
+ }): import("react").JSX.Element | null;
72
+ /** Props shared by `CheckBoxGroup` and `RadioGroup`. */
73
+ export interface ChoiceGroupProps<T extends OptionValue> {
74
+ options: readonly ChoiceOption<T>[];
75
+ /** Form field name. Default: a unique id. */
76
+ name?: string;
77
+ /** The group's legend. Without one, pass `aria-label` or `aria-labelledby`. */
78
+ label?: ReactNode;
79
+ /** Help text under the options. An error takes its place. */
80
+ hint?: ReactNode;
81
+ /** An error from outside, such as a server message. */
82
+ error?: string | null;
83
+ /** Default `md`. */
84
+ size?: Size;
85
+ /** `default`: a box or circle beside each label. `cards`: each option is a card. */
86
+ design?: ChoiceDesign;
87
+ /** `vertical` (default) stacks options, in `columns` when set; `horizontal` puts them in a wrapping row. */
88
+ orientation?: "vertical" | "horizontal";
89
+ /** Columns for vertical options. They drop to fewer columns when each would be narrower than 160px. */
90
+ columns?: number;
91
+ required?: boolean;
92
+ disabled?: boolean;
93
+ /** Options can be focused but not changed; the value is still sent with a form. A lock follows the label, and a click shows a note. */
94
+ readOnly?: boolean;
95
+ /** What a read-only group says when someone tries to change it. */
96
+ readOnlyMessage?: string;
97
+ /** Name used in messages. Default: the label, when it is text. */
98
+ fieldName?: string;
99
+ /** When the message shows. Default `blur` (when focus leaves the group); submitting a form always shows it. */
100
+ validateOn?: ValidateOn;
101
+ id?: string;
102
+ className?: string;
103
+ style?: CSSProperties;
104
+ "aria-label"?: string;
105
+ "aria-labelledby"?: string;
106
+ }
107
+ type GroupStyle = CSSProperties & {
108
+ "--nx-choices-columns"?: number;
109
+ };
110
+ /** Class names and inline style of a group's fieldset and options list. */
111
+ export declare function groupLayout(props: ChoiceGroupProps<OptionValue>): {
112
+ className: string;
113
+ optionsStyle: GroupStyle | undefined;
114
+ };
115
+ /** The hint or error line under a group. */
116
+ export declare function GroupFooter({ id, hint, error, aside }: {
117
+ id: string;
118
+ hint?: ReactNode;
119
+ error?: ReactNode;
120
+ aside?: ReactNode;
121
+ }): import("react").JSX.Element | null;
122
+ export {};