nexus-shared 1.1.20 → 2.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 (332) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +903 -0
  3. package/dist/Client.Index.d.ts +44 -0
  4. package/dist/Client.Index.js +49 -0
  5. package/dist/Components/Documents/Button.d.ts +29 -0
  6. package/dist/Components/Documents/Button.js +11 -0
  7. package/dist/Components/Documents/Menu.d.ts +102 -0
  8. package/dist/Components/Documents/Menu.js +238 -0
  9. package/dist/Components/Documents/SplitButton.d.ts +64 -0
  10. package/dist/Components/Documents/SplitButton.js +127 -0
  11. package/dist/Components/Documents/TabButtons.d.ts +62 -0
  12. package/dist/Components/Documents/TabButtons.js +19 -0
  13. package/dist/Components/Forms/ApiForm.d.ts +21 -0
  14. package/dist/Components/Forms/ApiForm.js +99 -0
  15. package/dist/Components/Forms/Crud.d.ts +17 -0
  16. package/dist/Components/Forms/Crud.js +556 -0
  17. package/dist/Components/Forms/CrudParts.d.ts +15 -0
  18. package/dist/Components/Forms/CrudParts.js +36 -0
  19. package/dist/Components/Forms/Form.d.ts +52 -0
  20. package/dist/Components/Forms/Form.js +319 -0
  21. package/dist/Components/Forms/SubmitForm.d.ts +65 -0
  22. package/dist/Components/Forms/SubmitForm.js +198 -0
  23. package/dist/Components/Inputs/Calendar.d.ts +69 -0
  24. package/dist/Components/Inputs/Calendar.js +258 -0
  25. package/dist/Components/Inputs/CheckBox.d.ts +53 -0
  26. package/dist/Components/Inputs/CheckBox.js +87 -0
  27. package/dist/Components/Inputs/CheckBoxGroup.d.ts +20 -0
  28. package/dist/Components/Inputs/CheckBoxGroup.js +80 -0
  29. package/dist/Components/Inputs/ChoiceField.d.ts +122 -0
  30. package/dist/Components/Inputs/ChoiceField.js +169 -0
  31. package/dist/Components/Inputs/DatePicker.d.ts +54 -0
  32. package/dist/Components/Inputs/DatePicker.js +246 -0
  33. package/dist/Components/Inputs/DateRangePicker.d.ts +62 -0
  34. package/dist/Components/Inputs/DateRangePicker.js +283 -0
  35. package/dist/Components/Inputs/DateTimePicker.d.ts +75 -0
  36. package/dist/Components/Inputs/DateTimePicker.js +399 -0
  37. package/dist/Components/Inputs/Dropdown.d.ts +117 -0
  38. package/dist/Components/Inputs/Dropdown.js +839 -0
  39. package/dist/Components/Inputs/DropdownParts.d.ts +84 -0
  40. package/dist/Components/Inputs/DropdownParts.js +102 -0
  41. package/dist/Components/Inputs/EditorShell.d.ts +45 -0
  42. package/dist/Components/Inputs/EditorShell.js +214 -0
  43. package/dist/Components/Inputs/Field.d.ts +53 -0
  44. package/dist/Components/Inputs/Field.js +16 -0
  45. package/dist/Components/Inputs/GroupForm.d.ts +20 -0
  46. package/dist/Components/Inputs/GroupForm.js +170 -0
  47. package/dist/Components/Inputs/InputField.d.ts +59 -0
  48. package/dist/Components/Inputs/InputField.js +169 -0
  49. package/dist/Components/Inputs/InputRenderer.d.ts +35 -0
  50. package/dist/Components/Inputs/InputRenderer.js +99 -0
  51. package/dist/Components/Inputs/MarkdownEditor.d.ts +67 -0
  52. package/dist/Components/Inputs/MarkdownEditor.js +289 -0
  53. package/dist/Components/Inputs/NumberBox.d.ts +53 -0
  54. package/dist/Components/Inputs/NumberBox.js +228 -0
  55. package/dist/Components/Inputs/RadioGroup.d.ts +20 -0
  56. package/dist/Components/Inputs/RadioGroup.js +43 -0
  57. package/dist/Components/Inputs/ReadOnlyNotice.d.ts +36 -0
  58. package/dist/Components/Inputs/ReadOnlyNotice.js +116 -0
  59. package/dist/Components/Inputs/RichTextEditor.d.ts +103 -0
  60. package/dist/Components/Inputs/RichTextEditor.js +1170 -0
  61. package/dist/Components/Inputs/RichTextParts.d.ts +63 -0
  62. package/dist/Components/Inputs/RichTextParts.js +157 -0
  63. package/dist/Components/Inputs/RowsInput.d.ts +104 -0
  64. package/dist/Components/Inputs/RowsInput.js +259 -0
  65. package/dist/Components/Inputs/Slider.d.ts +87 -0
  66. package/dist/Components/Inputs/Slider.js +216 -0
  67. package/dist/Components/Inputs/TabularForm.d.ts +23 -0
  68. package/dist/Components/Inputs/TabularForm.js +283 -0
  69. package/dist/Components/Inputs/TextArea.d.ts +43 -0
  70. package/dist/Components/Inputs/TextArea.js +31 -0
  71. package/dist/Components/Inputs/TextBox.d.ts +52 -0
  72. package/dist/Components/Inputs/TextBox.js +58 -0
  73. package/dist/Components/Inputs/TextField.d.ts +31 -0
  74. package/dist/Components/Inputs/TextField.js +35 -0
  75. package/dist/Components/Inputs/TimePanel.d.ts +34 -0
  76. package/dist/Components/Inputs/TimePanel.js +288 -0
  77. package/dist/Components/Inputs/TimePicker.d.ts +54 -0
  78. package/dist/Components/Inputs/TimePicker.js +239 -0
  79. package/dist/Components/Inputs/TreeView.d.ts +160 -0
  80. package/dist/Components/Inputs/TreeView.js +947 -0
  81. package/dist/Components/Layouts/MessageBox.d.ts +71 -0
  82. package/dist/Components/Layouts/MessageBox.js +104 -0
  83. package/dist/Components/Layouts/Popup.d.ts +92 -0
  84. package/dist/Components/Layouts/Popup.js +376 -0
  85. package/dist/Components/Layouts/PopupContext.d.ts +2 -0
  86. package/dist/Components/Layouts/PopupContext.js +4 -0
  87. package/dist/Components/Layouts/PopupDock.d.ts +22 -0
  88. package/dist/Components/Layouts/PopupDock.js +121 -0
  89. package/dist/Components/Layouts/PopupHost.d.ts +56 -0
  90. package/dist/Components/Layouts/PopupHost.js +163 -0
  91. package/dist/Components/Layouts/PopupRules.d.ts +30 -0
  92. package/dist/Components/Layouts/PopupRules.js +63 -0
  93. package/dist/Components/Layouts/ThemePicker.d.ts +13 -0
  94. package/dist/Components/Layouts/ThemePicker.js +22 -0
  95. package/dist/Components/Layouts/ThemeScript.d.ts +14 -0
  96. package/dist/Components/Layouts/ThemeScript.js +13 -0
  97. package/dist/Components/Layouts/ThemeSwitcher.d.ts +13 -0
  98. package/dist/Components/Layouts/ThemeSwitcher.js +29 -0
  99. package/dist/Components/Layouts/Toaster.d.ts +76 -0
  100. package/dist/Components/Layouts/Toaster.js +172 -0
  101. package/dist/Components/Viewers/DataTable.d.ts +25 -0
  102. package/dist/Components/Viewers/DataTable.js +542 -0
  103. package/dist/Components/Viewers/DataTableParts.d.ts +134 -0
  104. package/dist/Components/Viewers/DataTableParts.js +145 -0
  105. package/dist/Components/Viewers/MarkdownView.d.ts +26 -0
  106. package/dist/Components/Viewers/MarkdownView.js +79 -0
  107. package/dist/Components/Viewers/RichTextView.d.ts +18 -0
  108. package/dist/Components/Viewers/RichTextView.js +17 -0
  109. package/dist/Helpers/AnimationHelpers.d.ts +6 -0
  110. package/dist/Helpers/AnimationHelpers.js +35 -0
  111. package/dist/Helpers/ApiClient.d.ts +74 -0
  112. package/dist/Helpers/ApiClient.js +197 -0
  113. package/dist/Helpers/ApiFormHelpers.d.ts +26 -0
  114. package/dist/Helpers/ApiFormHelpers.js +56 -0
  115. package/dist/Helpers/ApiModules.d.ts +135 -0
  116. package/dist/Helpers/ApiModules.js +194 -0
  117. package/dist/Helpers/ApiResponses.d.ts +41 -0
  118. package/dist/Helpers/ApiResponses.js +159 -0
  119. package/dist/Helpers/ApiRoutes.d.ts +150 -0
  120. package/dist/Helpers/ApiRoutes.js +191 -0
  121. package/dist/Helpers/ApiToasts.d.ts +21 -0
  122. package/dist/Helpers/ApiToasts.js +22 -0
  123. package/dist/Helpers/ClassHelpers.d.ts +3 -0
  124. package/dist/Helpers/ClassHelpers.js +4 -0
  125. package/dist/Helpers/CrudBackend.d.ts +56 -0
  126. package/dist/Helpers/CrudBackend.js +119 -0
  127. package/dist/Helpers/CrudHelpers.d.ts +76 -0
  128. package/dist/Helpers/CrudHelpers.js +202 -0
  129. package/dist/Helpers/DateHelpers.d.ts +88 -0
  130. package/dist/Helpers/DateHelpers.js +363 -0
  131. package/dist/Helpers/DatePreferences.d.ts +14 -0
  132. package/dist/Helpers/DatePreferences.js +94 -0
  133. package/dist/Helpers/DateTimeHelpers.d.ts +87 -0
  134. package/dist/Helpers/DateTimeHelpers.js +286 -0
  135. package/dist/Helpers/DragHelpers.d.ts +129 -0
  136. package/dist/Helpers/DragHelpers.js +281 -0
  137. package/dist/Helpers/DropdownHelpers.d.ts +56 -0
  138. package/dist/Helpers/DropdownHelpers.js +180 -0
  139. package/dist/Helpers/FormDrafts.d.ts +18 -0
  140. package/dist/Helpers/FormDrafts.js +76 -0
  141. package/dist/Helpers/FormStore.d.ts +231 -0
  142. package/dist/Helpers/FormStore.js +734 -0
  143. package/dist/Helpers/InputParamsHelpers.d.ts +79 -0
  144. package/dist/Helpers/InputParamsHelpers.js +388 -0
  145. package/dist/Helpers/MarkdownEditing.d.ts +27 -0
  146. package/dist/Helpers/MarkdownEditing.js +250 -0
  147. package/dist/Helpers/MarkdownHelpers.d.ts +82 -0
  148. package/dist/Helpers/MarkdownHelpers.js +775 -0
  149. package/dist/Helpers/MessageBuilder.d.ts +74 -0
  150. package/dist/Helpers/MessageBuilder.js +254 -0
  151. package/dist/Helpers/NepaliCalendar.d.ts +25 -0
  152. package/dist/Helpers/NepaliCalendar.js +107 -0
  153. package/dist/Helpers/NumberHelpers.d.ts +71 -0
  154. package/dist/Helpers/NumberHelpers.js +202 -0
  155. package/dist/Helpers/Permissions.d.ts +62 -0
  156. package/dist/Helpers/Permissions.js +133 -0
  157. package/dist/Helpers/PopoverHelpers.d.ts +43 -0
  158. package/dist/Helpers/PopoverHelpers.js +91 -0
  159. package/dist/Helpers/RichTextHelpers.d.ts +77 -0
  160. package/dist/Helpers/RichTextHelpers.js +1072 -0
  161. package/dist/Helpers/RowsStore.d.ts +160 -0
  162. package/dist/Helpers/RowsStore.js +584 -0
  163. package/dist/Helpers/TableColumns.d.ts +40 -0
  164. package/dist/Helpers/TableColumns.js +254 -0
  165. package/dist/Helpers/TableExport.d.ts +30 -0
  166. package/dist/Helpers/TableExport.js +97 -0
  167. package/dist/Helpers/TableHelpers.d.ts +102 -0
  168. package/dist/Helpers/TableHelpers.js +281 -0
  169. package/dist/Helpers/TableStore.d.ts +142 -0
  170. package/dist/Helpers/TableStore.js +530 -0
  171. package/dist/Helpers/ThemeHelpers.d.ts +15 -0
  172. package/dist/Helpers/ThemeHelpers.js +16 -0
  173. package/dist/Helpers/TimeHelpers.d.ts +73 -0
  174. package/dist/Helpers/TimeHelpers.js +253 -0
  175. package/dist/Helpers/TreeStore.d.ts +188 -0
  176. package/dist/Helpers/TreeStore.js +577 -0
  177. package/dist/Helpers/ValidationHelpers.d.ts +124 -0
  178. package/dist/Helpers/ValidationHelpers.js +301 -0
  179. package/dist/Interfaces/ApiInterfaces.d.ts +149 -0
  180. package/dist/Interfaces/ApiInterfaces.js +24 -0
  181. package/dist/Interfaces/CrudInterfaces.d.ts +171 -0
  182. package/{src/sso-client.tsx → dist/Interfaces/CrudInterfaces.js} +1 -1
  183. package/dist/Interfaces/DateInterfaces.d.ts +154 -0
  184. package/dist/Interfaces/DateInterfaces.js +29 -0
  185. package/dist/Interfaces/FormInterfaces.d.ts +352 -0
  186. package/dist/Interfaces/FormInterfaces.js +1 -0
  187. package/dist/Interfaces/InputInterfaces.d.ts +141 -0
  188. package/dist/Interfaces/InputInterfaces.js +1 -0
  189. package/dist/Interfaces/MessageInterfaces.d.ts +111 -0
  190. package/dist/Interfaces/MessageInterfaces.js +5 -0
  191. package/dist/Interfaces/TableInterfaces.d.ts +291 -0
  192. package/dist/Interfaces/TableInterfaces.js +1 -0
  193. package/dist/Interfaces/ThemeInterfaces.d.ts +17 -0
  194. package/dist/Interfaces/ThemeInterfaces.js +17 -0
  195. package/dist/Interfaces/TypeInterfaces.d.ts +4 -0
  196. package/dist/Interfaces/TypeInterfaces.js +1 -0
  197. package/dist/Server.Index.d.ts +2 -0
  198. package/dist/Server.Index.js +5 -0
  199. package/dist/Services/ApiProxy.d.ts +32 -0
  200. package/dist/Services/ApiProxy.js +111 -0
  201. package/dist/Services/BrowserApi.d.ts +78 -0
  202. package/dist/Services/BrowserApi.js +111 -0
  203. package/dist/Services/ServerApi.d.ts +49 -0
  204. package/dist/Services/ServerApi.js +75 -0
  205. package/dist/Services/ThemeService.d.ts +17 -0
  206. package/dist/Services/ThemeService.js +83 -0
  207. package/dist/Shared.Index.d.ts +43 -0
  208. package/dist/Shared.Index.js +47 -0
  209. package/package.json +82 -33
  210. package/src/Styles/Nexus.Base.css +70 -0
  211. package/src/Styles/Nexus.Button.css +151 -0
  212. package/src/Styles/Nexus.Calendar.css +275 -0
  213. package/src/Styles/Nexus.Choice.css +345 -0
  214. package/src/Styles/Nexus.Crud.css +84 -0
  215. package/src/Styles/Nexus.DateTime.css +81 -0
  216. package/src/Styles/Nexus.Dropdown.css +774 -0
  217. package/src/Styles/Nexus.Editor.css +297 -0
  218. package/src/Styles/Nexus.Form.css +298 -0
  219. package/src/Styles/Nexus.Index.css +34 -0
  220. package/src/Styles/Nexus.Input.css +637 -0
  221. package/src/Styles/Nexus.Markdown.css +265 -0
  222. package/src/Styles/Nexus.Menu.css +249 -0
  223. package/src/Styles/Nexus.Popup.css +731 -0
  224. package/src/Styles/Nexus.RichText.css +463 -0
  225. package/src/Styles/Nexus.Rows.css +566 -0
  226. package/src/Styles/Nexus.Slider.css +278 -0
  227. package/src/Styles/Nexus.Tab.Buttons.css +364 -0
  228. package/src/Styles/Nexus.Table.css +1014 -0
  229. package/src/Styles/Nexus.Theme.Picker.css +159 -0
  230. package/src/Styles/Nexus.Themes.css +194 -0
  231. package/src/Styles/Nexus.Time.css +147 -0
  232. package/src/Styles/Nexus.Toast.css +265 -0
  233. package/src/Styles/Nexus.Tokens.css +72 -0
  234. package/src/Styles/Nexus.Tree.css +435 -0
  235. package/src/api-services/authentication-service.tsx +0 -23
  236. package/src/api-services/preference-service.tsx +0 -5
  237. package/src/api-services/system-service.tsx +0 -34
  238. package/src/client.ts +0 -31
  239. package/src/components/documents/button.tsx +0 -142
  240. package/src/components/documents/icon-box.tsx +0 -93
  241. package/src/components/documents/page-title.tsx +0 -7
  242. package/src/components/documents/tab-button.tsx +0 -172
  243. package/src/components/documents/tag.tsx +0 -30
  244. package/src/components/index.js +0 -0
  245. package/src/components/inputs/checkbox-input.tsx +0 -66
  246. package/src/components/inputs/input-box.tsx +0 -48
  247. package/src/components/inputs/input-element.tsx +0 -65
  248. package/src/components/inputs/input-form.tsx +0 -164
  249. package/src/components/inputs/input.tsx +0 -181
  250. package/src/components/inputs/number-input.tsx +0 -108
  251. package/src/components/inputs/radiobox-input.tsx +0 -53
  252. package/src/components/inputs/textarea-input.tsx +0 -47
  253. package/src/components/inputs/textbox-input.tsx +0 -45
  254. package/src/components/layouts/global-dialogbox.tsx +0 -431
  255. package/src/components/layouts/global-layout.tsx +0 -59
  256. package/src/components/layouts/layout-helpers.tsx +0 -20
  257. package/src/components/layouts/panels/user-panel.tsx +0 -112
  258. package/src/components/layouts/utility-menu.tsx +0 -49
  259. package/src/components/panels/theme-panel.tsx +0 -46
  260. package/src/helpers/bitwise-helpers.tsx +0 -11
  261. package/src/helpers/browser-helpers.tsx +0 -156
  262. package/src/helpers/datasource-helpers.tsx +0 -99
  263. package/src/helpers/element-helpers.tsx +0 -57
  264. package/src/helpers/input-helpers.tsx +0 -74
  265. package/src/helpers/string-helpers.tsx +0 -28
  266. package/src/helpers/utility-helpers.tsx +0 -45
  267. package/src/helpers/validation-helpers.tsx +0 -302
  268. package/src/index.ts +0 -26
  269. package/src/interface.ts +0 -19
  270. package/src/interfaces/auth-token-interfaces.tsx +0 -6
  271. package/src/interfaces/browser-interfaces.tsx +0 -36
  272. package/src/interfaces/button-interfaces.tsx +0 -63
  273. package/src/interfaces/datasource-interfaces.tsx +0 -22
  274. package/src/interfaces/datatable-interfaces.tsx +0 -25
  275. package/src/interfaces/dialogbox-interfaces.tsx +0 -5
  276. package/src/interfaces/exception-interfaces.tsx +0 -99
  277. package/src/interfaces/http-interfaces.tsx +0 -129
  278. package/src/interfaces/icon-interfaces.tsx +0 -129
  279. package/src/interfaces/input-interfaces.tsx +0 -410
  280. package/src/interfaces/layout-interfaces.tsx +0 -191
  281. package/src/interfaces/menu-interfaces.tsx +0 -49
  282. package/src/interfaces/message-interfaces.tsx +0 -32
  283. package/src/interfaces/permission-interfaces.tsx +0 -9
  284. package/src/interfaces/storage-interfaces.tsx +0 -5
  285. package/src/interfaces/system-interfaces.tsx +0 -22
  286. package/src/interfaces/theme-interfaces.tsx +0 -123
  287. package/src/interfaces/type-interfaces.tsx +0 -28
  288. package/src/interfaces/user-interfaces.tsx +0 -47
  289. package/src/nexus-client.tsx +0 -21
  290. package/src/nexus.environments.tsx +0 -66
  291. package/src/proxy-api/proxy-backend.tsx +0 -60
  292. package/src/proxy-api/proxy-constants.tsx +0 -28
  293. package/src/proxy-api/proxy-helpers.tsx +0 -91
  294. package/src/proxy-api-client.tsx +0 -1
  295. package/src/proxy-api-server.tsx +0 -2
  296. package/src/services/http-client-services.tsx +0 -75
  297. package/src/services/http-services.tsx +0 -158
  298. package/src/services/loader-service.tsx +0 -185
  299. package/src/services/localstorage-service.tsx +0 -119
  300. package/src/services/message-services.tsx +0 -383
  301. package/src/services/theme-service.tsx +0 -161
  302. package/src/services/user-services.tsx +0 -10
  303. package/src/sso-config/auth-token-validation.ts +0 -16
  304. package/src/sso-config/callback-route.tsx +0 -35
  305. package/src/sso-config/cookie-encryption.ts +0 -51
  306. package/src/sso-config/cookie-helpers.tsx +0 -102
  307. package/src/sso-config/forgot-password-route.tsx +0 -36
  308. package/src/sso-config/oauth-callback-state.ts +0 -61
  309. package/src/sso-config/pkce-helpers.ts +0 -9
  310. package/src/sso-config/provider-complete-route.tsx +0 -18
  311. package/src/sso-config/redirect-context-actions.tsx +0 -45
  312. package/src/sso-config/redirect-context-helpers.tsx +0 -159
  313. package/src/sso-config/redirect-context-persist.tsx +0 -18
  314. package/src/sso-config/redirect-context-route.tsx +0 -45
  315. package/src/sso-config/refresh-route.tsx +0 -23
  316. package/src/sso-config/sign-in-route.tsx +0 -74
  317. package/src/sso-config/sign-out-route.tsx +0 -57
  318. package/src/sso-config/sign-up-route.tsx +0 -57
  319. package/src/sso-config/sso-backend-flow.ts +0 -38
  320. package/src/sso-config/sso-complete-route.tsx +0 -50
  321. package/src/sso-config/sso-config.ts +0 -59
  322. package/src/sso-config/sso-interfaces.tsx +0 -99
  323. package/src/sso-config/sso-response-helpers.tsx +0 -20
  324. package/src/sso-server.tsx +0 -21
  325. package/src/styles/nexus.animation.css +0 -269
  326. package/src/styles/nexus.core.css +0 -119
  327. package/src/styles/nexus.dialog.css +0 -144
  328. package/src/styles/nexus.icon.css +0 -51
  329. package/src/styles/nexus.input.css +0 -207
  330. package/src/styles/nexus.loader.css +0 -11
  331. package/src/styles/nexus.logic.css +0 -47
  332. package/src/styles/nexus.utility.css +0 -347
@@ -0,0 +1,74 @@
1
+ import type { ApiResult } from "../Interfaces/ApiInterfaces.ts";
2
+ import type { ActionWords, BuiltMessage, MessageAction, MessageActionName, MessageContext, MessageKind, MessageReasons, MessageTexts } from "../Interfaces/MessageInterfaces.ts";
3
+ /** Every action the builder knows by name, for pickers and permission screens. */
4
+ export declare const MESSAGE_ACTION_NAMES: MessageActionName[];
5
+ export interface MessageChanges {
6
+ /** Texts to replace. `reasons` and `confirmDetails` merge with the current ones. */
7
+ texts?: Partial<Omit<MessageTexts, "reasons" | "confirmDetails">> & {
8
+ reasons?: Partial<MessageReasons>;
9
+ confirmDetails?: MessageTexts["confirmDetails"];
10
+ };
11
+ /** Action words to replace, merged per action. */
12
+ words?: Partial<Record<MessageActionName, Partial<ActionWords>>>;
13
+ }
14
+ /**
15
+ * Rewords every message at once, such as for another language or a product's tone. Call it once when the app starts;
16
+ * `configureMessages(null)` goes back to the defaults.
17
+ *
18
+ * @example
19
+ * configureMessages({ texts: { reasons: { signedOut: "Please sign in again." } }, words: { delete: { done: "removed" } } });
20
+ */
21
+ export declare function configureMessages(changes: MessageChanges | null): void;
22
+ /** The words of an action: a name's from the table, or the words given. Unknown names read as `save`. */
23
+ export declare function actionWords(action: MessageAction | undefined): ActionWords;
24
+ /** An English plural: address → addresses, city → cities, row → rows. */
25
+ export declare function pluralize(word: string): string;
26
+ /** Fills `{name}` from the values; `{Name}` capitalizes. Unknown names stay as they are. */
27
+ export declare function fillMessage(template: string, values: Record<string, string | number | undefined>): string;
28
+ /**
29
+ * Builds a message of any kind from what it is about. Every helper in `messages` calls this.
30
+ *
31
+ * @example
32
+ * buildMessage("success", { action: "delete", subject: "room", count: 3 }) // "3 rooms deleted."
33
+ * buildMessage("failure", { action: "save", subject: "Room 204" }) // "Could not save Room 204."
34
+ * buildMessage("reason", { action: "delete", status: 403 }) // "You do not have permission to delete the record."
35
+ */
36
+ export declare function buildMessage(kind: MessageKind, context?: MessageContext): string;
37
+ /** The message for a module whose API root is not set: "The Reservation API address is not set (API_RESERVATION)." */
38
+ export declare function notConfiguredMessage(module: string, env: string): string;
39
+ /** Why a call failed: by its status, or because nothing reached the server or no answer came in time. */
40
+ type Failure = number | undefined | Pick<ApiResult, "status" | "network" | "timeout">;
41
+ /**
42
+ * What to show for a call's answer: a success with the server's message (or one built for the action), or a failure
43
+ * titled with what failed and, under it, the server's message or the reason by status. `null` for an aborted call.
44
+ */
45
+ export declare function describeResult(result: ApiResult, context?: MessageContext): BuiltMessage | null;
46
+ /**
47
+ * Short ways to build messages. Each calls `buildMessage`, so the wording lives in one table.
48
+ *
49
+ * @example
50
+ * messages.success("save", "Room 204") // "Room 204 saved."
51
+ * messages.success("delete", "room", 3) // "3 rooms deleted."
52
+ * messages.success("save") // "Saved."
53
+ * messages.failure("load", "rooms") // "Could not load rooms."
54
+ * messages.reason(403, "delete", "Room 204") // "You do not have permission to delete Room 204."
55
+ * messages.loading("upload", "photo.jpg") // "Uploading photo.jpg…"
56
+ * messages.confirm("trash", "room", 3) // "Move 3 rooms to the trash?"
57
+ * messages.label("trash") // "Move to the trash"
58
+ * messages.forResult(result, { action: "save", subject: "Room 204" }) // { tone, title, message } for a toast
59
+ */
60
+ export declare const messages: {
61
+ build: typeof buildMessage;
62
+ success: (action?: MessageAction, subject?: string, count?: number) => string;
63
+ failure: (action?: MessageAction, subject?: string, count?: number) => string;
64
+ loading: (action?: MessageAction, subject?: string, count?: number) => string;
65
+ confirm: (action?: MessageAction, subject?: string, count?: number) => string;
66
+ /** The action on a button: "Delete", "Move to the trash". */
67
+ label: (action?: MessageAction) => string;
68
+ /** The line under a question: "This cannot be undone." for delete; empty for most actions. */
69
+ confirmDetail: (action?: MessageAction, subject?: string, count?: number) => string;
70
+ reason: (failure: Failure, action?: MessageAction, subject?: string, count?: number) => string;
71
+ forResult: typeof describeResult;
72
+ words: typeof actionWords;
73
+ };
74
+ export {};
@@ -0,0 +1,254 @@
1
+ /*
2
+ * Every success, failure, loading, and confirm message comes from here: one table of texts, one table of action words,
3
+ * and one generic `buildMessage(kind, context)`. The helpers in `messages` are short ways to call it. An app changes
4
+ * the wording of every message at once with `configureMessages` (to reword or translate), never message by message.
5
+ */
6
+ /** The words of each action. A `verb` or `doing` with `{object}` places the object inside: "move Room 204 to the trash". */
7
+ const DEFAULT_WORDS = {
8
+ load: { verb: "load", done: "loaded", doing: "Loading", object: "the data" },
9
+ save: { verb: "save", done: "saved", doing: "Saving", object: "the changes", sendsValues: true },
10
+ create: { verb: "create", done: "created", doing: "Creating", object: "the record", sendsValues: true },
11
+ update: { verb: "update", done: "updated", doing: "Updating", object: "the record", sendsValues: true },
12
+ delete: { verb: "delete", done: "deleted", doing: "Deleting", object: "the record" },
13
+ trash: { verb: "move {object} to the trash", done: "moved to the trash", doing: "Moving {object} to the trash", object: "the record" },
14
+ archive: { verb: "archive", done: "archived", doing: "Archiving", object: "the record" },
15
+ restore: { verb: "restore", done: "restored", doing: "Restoring", object: "the record" },
16
+ recover: { verb: "recover", done: "recovered", doing: "Recovering", object: "the record" },
17
+ flag: { verb: "flag", done: "flagged", doing: "Flagging", object: "the record" },
18
+ unflag: { verb: "unflag", done: "unflagged", doing: "Unflagging", object: "the record" },
19
+ pin: { verb: "pin", done: "pinned", doing: "Pinning", object: "the record" },
20
+ unpin: { verb: "unpin", done: "unpinned", doing: "Unpinning", object: "the record" },
21
+ send: { verb: "send", done: "sent", doing: "Sending", object: "the message", sendsValues: true },
22
+ submit: { verb: "submit", done: "submitted", doing: "Submitting", object: "the form", sendsValues: true },
23
+ upload: { verb: "upload", done: "uploaded", doing: "Uploading", object: "the file", sendsValues: true },
24
+ download: { verb: "download", done: "downloaded", doing: "Downloading", object: "the file" },
25
+ import: { verb: "import", done: "imported", doing: "Importing", object: "the file", sendsValues: true },
26
+ export: { verb: "export", done: "exported", doing: "Exporting", object: "the data" },
27
+ copy: { verb: "copy", done: "copied", doing: "Copying", object: "the record" },
28
+ approve: { verb: "approve", done: "approved", doing: "Approving", object: "the request" },
29
+ reject: { verb: "reject", done: "rejected", doing: "Rejecting", object: "the request" },
30
+ cancel: { verb: "cancel", done: "cancelled", doing: "Cancelling", object: "the request" },
31
+ };
32
+ /**
33
+ * The texts. `{act}` is the verb with its object ("save Room 204", "move 3 rooms to the trash"), `{acting}` the same
34
+ * in progress, `{object}` what is named ("Room 204", "3 rooms", or the action's object), `{target}` what is named or
35
+ * "this record". A capital first letter capitalizes the value.
36
+ */
37
+ const DEFAULT_TEXTS = {
38
+ success: "{Object} {done}.",
39
+ successPlain: "{Done}.",
40
+ failure: "Could not {act}.",
41
+ loading: "{Acting}…",
42
+ confirm: "{Act}?",
43
+ label: "{Verb}",
44
+ confirmDetails: {
45
+ delete: "This cannot be undone.",
46
+ trash: "It can be restored from the trash.",
47
+ archive: "It can be restored from the archive.",
48
+ },
49
+ reasons: {
50
+ network: "The server cannot be reached. Check your internet connection and try again.",
51
+ timeout: "The server took too long to answer. Try again in a moment.",
52
+ rejectedValues: "The server did not accept the values. Check them and try again.",
53
+ rejected: "The server did not accept the request.",
54
+ signedOut: "Your session has ended. Sign in again to {act}.",
55
+ forbidden: "You do not have permission to {act}.",
56
+ notFound: "The server could not find {target}. It may have been deleted.",
57
+ notAllowed: "The server does not allow this request.",
58
+ conflict: "Someone else changed this record since it was opened. Reload it, then try again.",
59
+ tooLarge: "The request is too large for the server.",
60
+ tooMany: "Too many requests. Wait a moment and try again.",
61
+ unavailable: "The server is not available right now. Try again in a moment.",
62
+ serverError: "Something went wrong on the server. Try again in a moment.",
63
+ other: "Could not {act} (error {status}).",
64
+ notConfigured: "The {module} API address is not set ({env}).",
65
+ },
66
+ };
67
+ /** Every action the builder knows by name, for pickers and permission screens. */
68
+ export const MESSAGE_ACTION_NAMES = Object.keys(DEFAULT_WORDS);
69
+ let words = DEFAULT_WORDS;
70
+ let texts = DEFAULT_TEXTS;
71
+ /**
72
+ * Rewords every message at once, such as for another language or a product's tone. Call it once when the app starts;
73
+ * `configureMessages(null)` goes back to the defaults.
74
+ *
75
+ * @example
76
+ * configureMessages({ texts: { reasons: { signedOut: "Please sign in again." } }, words: { delete: { done: "removed" } } });
77
+ */
78
+ export function configureMessages(changes) {
79
+ if (!changes) {
80
+ words = DEFAULT_WORDS;
81
+ texts = DEFAULT_TEXTS;
82
+ return;
83
+ }
84
+ const { reasons, confirmDetails, ...rest } = changes.texts ?? {};
85
+ texts = { ...texts, ...rest, reasons: { ...texts.reasons, ...reasons }, confirmDetails: { ...texts.confirmDetails, ...confirmDetails } };
86
+ const next = { ...words };
87
+ for (const [name, change] of Object.entries(changes.words ?? {}))
88
+ next[name] = { ...next[name], ...change };
89
+ words = next;
90
+ }
91
+ /** The words of an action: a name's from the table, or the words given. Unknown names read as `save`. */
92
+ export function actionWords(action) {
93
+ if (!action)
94
+ return words.save;
95
+ if (typeof action === "string")
96
+ return words[action] ?? words.save;
97
+ return action;
98
+ }
99
+ const countFormat = new Intl.NumberFormat("en-US");
100
+ /** An English plural: address → addresses, city → cities, row → rows. */
101
+ export function pluralize(word) {
102
+ if (/[^aeiou]y$/i.test(word))
103
+ return word.slice(0, -1) + (word.endsWith("Y") ? "IES" : "ies");
104
+ if (/(s|x|z|ch|sh)$/i.test(word))
105
+ return word + (/[A-Z]$/.test(word) ? "ES" : "es");
106
+ return word + (/[A-Z]$/.test(word) && word.length > 1 ? "S" : "s");
107
+ }
108
+ /** What a message names: "Room 204", "3 rooms", "3 items", or nothing. */
109
+ function named(context) {
110
+ const { subject, count, plural } = context;
111
+ const many = count !== undefined && count !== 1;
112
+ if (subject)
113
+ return many ? `${countFormat.format(count)} ${plural ?? pluralize(subject)}` : subject;
114
+ return many ? `${countFormat.format(count)} items` : undefined;
115
+ }
116
+ const capitalize = (text) => (text ? text[0].toUpperCase() + text.slice(1) : text);
117
+ /** A verb phrase with its object: the object goes where the phrase says `{object}`, else after it. */
118
+ function phrase(verb, object) {
119
+ return verb.includes("{object}") ? verb.replace("{object}", object) : `${verb} ${object}`;
120
+ }
121
+ /** Fills `{name}` from the values; `{Name}` capitalizes. Unknown names stay as they are. */
122
+ export function fillMessage(template, values) {
123
+ return template.replace(/\{(\w+)\}/g, (whole, key) => {
124
+ const value = values[key[0].toLowerCase() + key.slice(1)];
125
+ if (value === undefined)
126
+ return whole;
127
+ const text = String(value);
128
+ return key[0] === key[0].toUpperCase() && key[0] !== key[0].toLowerCase() ? capitalize(text) : text;
129
+ });
130
+ }
131
+ function reasonTemplate(context, action) {
132
+ const { reasons } = texts;
133
+ if (context.network)
134
+ return reasons.network;
135
+ if (context.timeout)
136
+ return reasons.timeout;
137
+ const status = context.status;
138
+ if (status === undefined || status < 400)
139
+ return texts.failure;
140
+ switch (status) {
141
+ case 400:
142
+ case 422:
143
+ return action.sendsValues ? reasons.rejectedValues : reasons.rejected;
144
+ case 401:
145
+ return reasons.signedOut;
146
+ case 403:
147
+ return reasons.forbidden;
148
+ case 404:
149
+ case 410:
150
+ return reasons.notFound;
151
+ case 405:
152
+ return reasons.notAllowed;
153
+ case 408:
154
+ return reasons.timeout;
155
+ case 409:
156
+ return reasons.conflict;
157
+ case 413:
158
+ return reasons.tooLarge;
159
+ case 429:
160
+ return reasons.tooMany;
161
+ case 502:
162
+ case 503:
163
+ case 504:
164
+ return reasons.unavailable;
165
+ default:
166
+ return status >= 500 ? reasons.serverError : reasons.other;
167
+ }
168
+ }
169
+ /**
170
+ * Builds a message of any kind from what it is about. Every helper in `messages` calls this.
171
+ *
172
+ * @example
173
+ * buildMessage("success", { action: "delete", subject: "room", count: 3 }) // "3 rooms deleted."
174
+ * buildMessage("failure", { action: "save", subject: "Room 204" }) // "Could not save Room 204."
175
+ * buildMessage("reason", { action: "delete", status: 403 }) // "You do not have permission to delete the record."
176
+ */
177
+ export function buildMessage(kind, context = {}) {
178
+ const action = actionWords(context.action);
179
+ const name = named(context);
180
+ const object = name ?? action.object;
181
+ const values = {
182
+ verb: action.verb.replace(" {object}", "").replace("{object} ", ""),
183
+ done: action.done,
184
+ doing: action.doing.replace(" {object}", "").replace("{object} ", ""),
185
+ object,
186
+ target: name ?? "this record",
187
+ act: phrase(action.verb, object),
188
+ acting: phrase(action.doing, object),
189
+ status: context.status,
190
+ };
191
+ switch (kind) {
192
+ case "success":
193
+ return fillMessage(name ? texts.success : texts.successPlain, values);
194
+ case "failure":
195
+ return fillMessage(texts.failure, values);
196
+ case "loading":
197
+ return fillMessage(texts.loading, values);
198
+ case "confirm":
199
+ return fillMessage(texts.confirm, values);
200
+ case "label":
201
+ return fillMessage(texts.label, values);
202
+ case "confirmDetail": {
203
+ const detail = typeof context.action === "string" ? texts.confirmDetails[context.action] : undefined;
204
+ return detail ? fillMessage(detail, values) : "";
205
+ }
206
+ case "reason":
207
+ return fillMessage(reasonTemplate(context, action), values);
208
+ }
209
+ }
210
+ /** The message for a module whose API root is not set: "The Reservation API address is not set (API_RESERVATION)." */
211
+ export function notConfiguredMessage(module, env) {
212
+ return fillMessage(texts.reasons.notConfigured, { module, env });
213
+ }
214
+ /**
215
+ * What to show for a call's answer: a success with the server's message (or one built for the action), or a failure
216
+ * titled with what failed and, under it, the server's message or the reason by status. `null` for an aborted call.
217
+ */
218
+ export function describeResult(result, context = {}) {
219
+ if (result.aborted)
220
+ return null;
221
+ if (result.ok)
222
+ return { tone: "success", title: result.message ?? buildMessage("success", context) };
223
+ const title = buildMessage("failure", context);
224
+ const message = result.message ?? buildMessage("reason", { ...context, status: result.status, network: result.network, timeout: result.timeout });
225
+ return message && message !== title ? { tone: "danger", title, message } : { tone: "danger", title };
226
+ }
227
+ /**
228
+ * Short ways to build messages. Each calls `buildMessage`, so the wording lives in one table.
229
+ *
230
+ * @example
231
+ * messages.success("save", "Room 204") // "Room 204 saved."
232
+ * messages.success("delete", "room", 3) // "3 rooms deleted."
233
+ * messages.success("save") // "Saved."
234
+ * messages.failure("load", "rooms") // "Could not load rooms."
235
+ * messages.reason(403, "delete", "Room 204") // "You do not have permission to delete Room 204."
236
+ * messages.loading("upload", "photo.jpg") // "Uploading photo.jpg…"
237
+ * messages.confirm("trash", "room", 3) // "Move 3 rooms to the trash?"
238
+ * messages.label("trash") // "Move to the trash"
239
+ * messages.forResult(result, { action: "save", subject: "Room 204" }) // { tone, title, message } for a toast
240
+ */
241
+ export const messages = {
242
+ build: buildMessage,
243
+ success: (action, subject, count) => buildMessage("success", { action, subject, count }),
244
+ failure: (action, subject, count) => buildMessage("failure", { action, subject, count }),
245
+ loading: (action, subject, count) => buildMessage("loading", { action, subject, count }),
246
+ confirm: (action, subject, count) => buildMessage("confirm", { action, subject, count }),
247
+ /** The action on a button: "Delete", "Move to the trash". */
248
+ label: (action) => buildMessage("label", { action }),
249
+ /** The line under a question: "This cannot be undone." for delete; empty for most actions. */
250
+ confirmDetail: (action, subject, count) => buildMessage("confirmDetail", { action, subject, count }),
251
+ reason: (failure, action, subject, count) => buildMessage("reason", { action, subject, count, ...(typeof failure === "object" ? failure : { status: failure }) }),
252
+ forResult: describeResult,
253
+ words: actionWords,
254
+ };
@@ -0,0 +1,25 @@
1
+ import type { DateParts } from "../Interfaces/DateInterfaces.ts";
2
+ /**
3
+ * The Bikram Sambat (Nepali) calendar, as the lengths of its months from BS 1975 to 2100 (AD 1918 to 2044).
4
+ * Year and month lengths are not computed; they follow the calendar Nepal publishes each year. The table is the
5
+ * majority of five published tables (nepali-datetime for Python, nepali-date-converter, the Python and Node
6
+ * libraries of opensource-nepal, and the previous Nexus project); years after 2083 are those libraries' predictions,
7
+ * and 2096 has one day added (the sources give it 364 days, which no Bikram Sambat year has).
8
+ * `npm run test:dates` checks the table against known dates and round-trips every day in it.
9
+ *
10
+ * Dates are converted through day numbers (days since 1970-01-01 in the proleptic Gregorian calendar), with no
11
+ * `Date` objects and no time zone, so a conversion gives the same answer on every machine.
12
+ */
13
+ export declare const BS_FIRST_YEAR = 1975;
14
+ export declare const BS_LAST_YEAR = 2100;
15
+ /** Days in a Bikram Sambat month (1 to 12), or 0 for a year outside the table. */
16
+ export declare function bsMonthLength(year: number, month: number): number;
17
+ /** Days in a Bikram Sambat year, or 0 for a year outside the table. */
18
+ export declare function bsYearLength(year: number): number;
19
+ /** Day number of a Bikram Sambat date, or `null` when the date does not exist or falls outside the table. */
20
+ export declare function bsToDayNumber(year: number, month: number, day: number): number | null;
21
+ /** The Bikram Sambat date of a day number, or `null` outside the table. */
22
+ export declare function dayNumberToBs(dayNumber: number): DateParts | null;
23
+ /** Day numbers of the first and last days the table covers. */
24
+ export declare const BS_MIN_DAY_NUMBER = -18891;
25
+ export declare const BS_MAX_DAY_NUMBER: number;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * The Bikram Sambat (Nepali) calendar, as the lengths of its months from BS 1975 to 2100 (AD 1918 to 2044).
3
+ * Year and month lengths are not computed; they follow the calendar Nepal publishes each year. The table is the
4
+ * majority of five published tables (nepali-datetime for Python, nepali-date-converter, the Python and Node
5
+ * libraries of opensource-nepal, and the previous Nexus project); years after 2083 are those libraries' predictions,
6
+ * and 2096 has one day added (the sources give it 364 days, which no Bikram Sambat year has).
7
+ * `npm run test:dates` checks the table against known dates and round-trips every day in it.
8
+ *
9
+ * Dates are converted through day numbers (days since 1970-01-01 in the proleptic Gregorian calendar), with no
10
+ * `Date` objects and no time zone, so a conversion gives the same answer on every machine.
11
+ */
12
+ export const BS_FIRST_YEAR = 1975;
13
+ export const BS_LAST_YEAR = 2100;
14
+ /** Day number of BS 1975-01-01, which is AD 1918-04-13. */
15
+ const EPOCH_DAYS = -18891;
16
+ // One character per month, twelve per year from BS 1975: "0" to "3" mean 29 to 32 days.
17
+ const MONTH_DAYS = "223321101011232321110012132321110102223222101011223321101011" + // 1975-1979
18
+ "232321110012222322011011223222101011223321101011232321110012" + // 1980-1984
19
+ "222322011011223222101011232321101011232321110012222322011011" + // 1985-1989
20
+ "223222101011232321110011232321110102223222101011223222101011" + // 1990-1994
21
+ "232321110011232321110102223222101011223222101011232321110012" + // 1995-1999
22
+ "132321110102223222101011223321101011232321110012132321110102" + // 2000-2004
23
+ "223222101011223321101011232321110012222322011002223222101011" + // 2005-2009
24
+ "223321101011232321110012222322011011223222101011223321101011" + // 2010-2014
25
+ "232321110012222322011011223222101011232321101011232321110102" + // 2015-2019
26
+ "222322101011223222101011232321110011232321110102222322101011" + // 2020-2024
27
+ "223222101011232321110012132321110102223222101011223231101011" + // 2025-2029
28
+ "232321110012132321110102223222101011223321101011232321110012" + // 2030-2034
29
+ "132322011002223222101011223321101011232321110012222322011011" + // 2035-2039
30
+ "223222101011223321101011232321110012222322011011223222101011" + // 2040-2044
31
+ "232321101011232321110012222322101011223222101011232321110011" + // 2045-2049
32
+ "232321110102222322101011223222101011232321110011232321110102" + // 2050-2054
33
+ "223222101011223231101011232321110012132321110102223222101011" + // 2055-2059
34
+ "223321101011232321110012132322010102223222101011223321101011" + // 2060-2064
35
+ "232321110012222322011002223222101011223321101011232321110012" + // 2065-2069
36
+ "222322011011223222101011232321101011232321110012222322101011" + // 2070-2074
37
+ "223222101011232321110011232321110102222322101011223222101011" + // 2075-2079
38
+ "232321110011232321110102223222101011223222101011223221110111" + // 2080-2084
39
+ "232312110111132321110111223222110111123312110111132321110111" + // 2085-2089
40
+ "132321110111223222110111123321110111132321110111223221110111" + // 2090-2094
41
+ "223222101111123321111011232321110111223222010102223222100111" + // 2095-2099
42
+ "232312101011"; // 2100-2100;
43
+ // Days before each year, from the epoch, so a conversion walks no more than a few months.
44
+ const DAYS_BEFORE_YEAR = [];
45
+ {
46
+ let days = 0;
47
+ for (let index = 0; index < BS_LAST_YEAR - BS_FIRST_YEAR + 1; index++) {
48
+ DAYS_BEFORE_YEAR.push(days);
49
+ for (let month = 0; month < 12; month++)
50
+ days += MONTH_DAYS.charCodeAt(index * 12 + month) - 48 + 29;
51
+ }
52
+ DAYS_BEFORE_YEAR.push(days);
53
+ }
54
+ const inRange = (year) => Number.isInteger(year) && year >= BS_FIRST_YEAR && year <= BS_LAST_YEAR;
55
+ /** Days in a Bikram Sambat month (1 to 12), or 0 for a year outside the table. */
56
+ export function bsMonthLength(year, month) {
57
+ if (!inRange(year) || month < 1 || month > 12)
58
+ return 0;
59
+ return MONTH_DAYS.charCodeAt((year - BS_FIRST_YEAR) * 12 + month - 1) - 48 + 29;
60
+ }
61
+ /** Days in a Bikram Sambat year, or 0 for a year outside the table. */
62
+ export function bsYearLength(year) {
63
+ if (!inRange(year))
64
+ return 0;
65
+ const index = year - BS_FIRST_YEAR;
66
+ return DAYS_BEFORE_YEAR[index + 1] - DAYS_BEFORE_YEAR[index];
67
+ }
68
+ /** Day number of a Bikram Sambat date, or `null` when the date does not exist or falls outside the table. */
69
+ export function bsToDayNumber(year, month, day) {
70
+ const length = bsMonthLength(year, month);
71
+ if (!length || !Number.isInteger(day) || day < 1 || day > length)
72
+ return null;
73
+ const index = year - BS_FIRST_YEAR;
74
+ let days = DAYS_BEFORE_YEAR[index] + day - 1;
75
+ for (let m = 1; m < month; m++)
76
+ days += MONTH_DAYS.charCodeAt(index * 12 + m - 1) - 48 + 29;
77
+ return EPOCH_DAYS + days;
78
+ }
79
+ /** The Bikram Sambat date of a day number, or `null` outside the table. */
80
+ export function dayNumberToBs(dayNumber) {
81
+ let days = dayNumber - EPOCH_DAYS;
82
+ const total = DAYS_BEFORE_YEAR[DAYS_BEFORE_YEAR.length - 1];
83
+ if (!Number.isInteger(days) || days < 0 || days >= total)
84
+ return null;
85
+ // Binary search for the year, then walk its months.
86
+ let low = 0;
87
+ let high = DAYS_BEFORE_YEAR.length - 2;
88
+ while (low < high) {
89
+ const mid = (low + high + 1) >> 1;
90
+ if (DAYS_BEFORE_YEAR[mid] <= days)
91
+ low = mid;
92
+ else
93
+ high = mid - 1;
94
+ }
95
+ days -= DAYS_BEFORE_YEAR[low];
96
+ let month = 1;
97
+ for (; month < 12; month++) {
98
+ const length = MONTH_DAYS.charCodeAt(low * 12 + month - 1) - 48 + 29;
99
+ if (days < length)
100
+ break;
101
+ days -= length;
102
+ }
103
+ return { year: BS_FIRST_YEAR + low, month, day: days + 1 };
104
+ }
105
+ /** Day numbers of the first and last days the table covers. */
106
+ export const BS_MIN_DAY_NUMBER = EPOCH_DAYS;
107
+ export const BS_MAX_DAY_NUMBER = EPOCH_DAYS + DAYS_BEFORE_YEAR[DAYS_BEFORE_YEAR.length - 1] - 1;
@@ -0,0 +1,71 @@
1
+ import type { NumberFormatOptions } from "../Interfaces/InputInterfaces.ts";
2
+ /** Default locale for number text. Fixed rather than the browser's, so server-rendered text matches the browser's. */
3
+ export declare const DEFAULT_NUMBER_LOCALE = "en-US";
4
+ /** Most digits a number field takes. A JavaScript number holds 15 significant digits exactly; beyond that, digits change. */
5
+ export declare const MAX_NUMBER_DIGITS = 15;
6
+ export interface NumberSymbols {
7
+ /** Decimal separator, e.g. "." in en-US and "," in de-DE. */
8
+ decimal: string;
9
+ /** Group separator, e.g. "," in en-US, "." in de-DE, and a narrow space in fr-FR. */
10
+ group: string;
11
+ }
12
+ export interface NumberTextRules {
13
+ /** Most digits after the decimal separator; `0` allows none. */
14
+ decimals?: number;
15
+ /** Allows a leading minus sign. */
16
+ negative: boolean;
17
+ }
18
+ /** The decimal and group separators of a locale. */
19
+ export declare function getNumberSymbols(locale?: string): NumberSymbols;
20
+ /**
21
+ * Formats a number for display: `formatNumber(1250, { decimals: 2, fixedDecimals: true, grouping: true })` gives "1,250.00".
22
+ * Returns "" for `null`, `undefined`, and `NaN`. Digits are always 0–9, and the minus sign is "-", so the text can be typed back.
23
+ */
24
+ export declare function formatNumber(value: number | null | undefined, options?: NumberFormatOptions): string;
25
+ /**
26
+ * Reads a number written in the locale's format: "1,250.50" gives 1250.5, and in `de-DE` "1.250,50" does.
27
+ * Returns `null` for empty text (also a lone minus sign or decimal separator) and `NaN` for text that is not a number.
28
+ */
29
+ export declare function parseNumber(text: string | null | undefined, locale?: string): number | null;
30
+ /** Counts the digits in text, to keep numbers within `MAX_NUMBER_DIGITS`. */
31
+ export declare function countDigits(text: string): number;
32
+ /**
33
+ * Whether text typed so far can become a valid number: "", "-", "12.", and ".5" can; "1.2.3" and "12a" cannot.
34
+ * The text is edit text: digits, at most one decimal separator, and a leading minus sign, with no group separators.
35
+ */
36
+ export declare function isPartialNumber(text: string, decimal: string, rules: NumberTextRules): boolean;
37
+ /**
38
+ * Removes what cannot be part of a number from text that reached the field unchecked (an input method, autofill, a drop),
39
+ * keeping the caret where it was relative to the text that stays. Digits are never removed.
40
+ */
41
+ export declare function cleanNumberText(text: string, caret: number, decimal: string, rules: NumberTextRules): {
42
+ text: string;
43
+ caret: number;
44
+ };
45
+ /**
46
+ * Takes the number out of pasted text, such as "Rs 1,250.50", "1 250,50 €", or "-12%", and returns it as edit text
47
+ * ("1250.50"). Returns `null` when the text holds no single clear number, so a paste never turns into a wrong value.
48
+ */
49
+ export declare function readPastedNumber(text: string, locale?: string): string | null;
50
+ /**
51
+ * Rounds to a number of decimal places the way people do: 1.005 → 1.01, and -2.5 → -3.
52
+ * Works on the number's shortest decimal text, so binary fractions such as 1.005 (stored as 1.00499…) round up.
53
+ */
54
+ export declare function roundDecimal(value: number, digits: number): number;
55
+ /** Keeps a value within `min` and `max`, each optional. */
56
+ export declare function clampNumber(value: number, min?: number, max?: number): number;
57
+ /** Digits after the decimal point of a number: 0.25 → 2, 1e-7 → 7. */
58
+ export declare function countDecimals(value: number): number;
59
+ export interface StepOptions {
60
+ /** Default 1. */
61
+ step?: number;
62
+ min?: number;
63
+ max?: number;
64
+ /** Rounds the result, as the field does. */
65
+ decimals?: number;
66
+ }
67
+ /**
68
+ * The next value for an arrow key or a +/− button. Values move along the grid of `step` from `min` (or 0), so 2.3 with
69
+ * step 1 goes up to 3, and stay within `min` and `max`. An empty field starts at 0, or at the limit nearest to 0.
70
+ */
71
+ export declare function stepNumber(value: number | null, direction: 1 | -1, options?: StepOptions): number;