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.
- package/LICENSE +21 -0
- package/README.md +903 -0
- package/dist/Client.Index.d.ts +44 -0
- package/dist/Client.Index.js +49 -0
- package/dist/Components/Documents/Button.d.ts +29 -0
- package/dist/Components/Documents/Button.js +11 -0
- package/dist/Components/Documents/Menu.d.ts +102 -0
- package/dist/Components/Documents/Menu.js +238 -0
- package/dist/Components/Documents/SplitButton.d.ts +64 -0
- package/dist/Components/Documents/SplitButton.js +127 -0
- package/dist/Components/Documents/TabButtons.d.ts +62 -0
- package/dist/Components/Documents/TabButtons.js +19 -0
- package/dist/Components/Forms/ApiForm.d.ts +21 -0
- package/dist/Components/Forms/ApiForm.js +99 -0
- package/dist/Components/Forms/Crud.d.ts +17 -0
- package/dist/Components/Forms/Crud.js +556 -0
- package/dist/Components/Forms/CrudParts.d.ts +15 -0
- package/dist/Components/Forms/CrudParts.js +36 -0
- package/dist/Components/Forms/Form.d.ts +52 -0
- package/dist/Components/Forms/Form.js +319 -0
- package/dist/Components/Forms/SubmitForm.d.ts +65 -0
- package/dist/Components/Forms/SubmitForm.js +198 -0
- package/dist/Components/Inputs/Calendar.d.ts +69 -0
- package/dist/Components/Inputs/Calendar.js +258 -0
- package/dist/Components/Inputs/CheckBox.d.ts +53 -0
- package/dist/Components/Inputs/CheckBox.js +87 -0
- package/dist/Components/Inputs/CheckBoxGroup.d.ts +20 -0
- package/dist/Components/Inputs/CheckBoxGroup.js +80 -0
- package/dist/Components/Inputs/ChoiceField.d.ts +122 -0
- package/dist/Components/Inputs/ChoiceField.js +169 -0
- package/dist/Components/Inputs/DatePicker.d.ts +54 -0
- package/dist/Components/Inputs/DatePicker.js +246 -0
- package/dist/Components/Inputs/DateRangePicker.d.ts +62 -0
- package/dist/Components/Inputs/DateRangePicker.js +283 -0
- package/dist/Components/Inputs/DateTimePicker.d.ts +75 -0
- package/dist/Components/Inputs/DateTimePicker.js +399 -0
- package/dist/Components/Inputs/Dropdown.d.ts +117 -0
- package/dist/Components/Inputs/Dropdown.js +839 -0
- package/dist/Components/Inputs/DropdownParts.d.ts +84 -0
- package/dist/Components/Inputs/DropdownParts.js +102 -0
- package/dist/Components/Inputs/EditorShell.d.ts +45 -0
- package/dist/Components/Inputs/EditorShell.js +214 -0
- package/dist/Components/Inputs/Field.d.ts +53 -0
- package/dist/Components/Inputs/Field.js +16 -0
- package/dist/Components/Inputs/GroupForm.d.ts +20 -0
- package/dist/Components/Inputs/GroupForm.js +170 -0
- package/dist/Components/Inputs/InputField.d.ts +59 -0
- package/dist/Components/Inputs/InputField.js +169 -0
- package/dist/Components/Inputs/InputRenderer.d.ts +35 -0
- package/dist/Components/Inputs/InputRenderer.js +99 -0
- package/dist/Components/Inputs/MarkdownEditor.d.ts +67 -0
- package/dist/Components/Inputs/MarkdownEditor.js +289 -0
- package/dist/Components/Inputs/NumberBox.d.ts +53 -0
- package/dist/Components/Inputs/NumberBox.js +228 -0
- package/dist/Components/Inputs/RadioGroup.d.ts +20 -0
- package/dist/Components/Inputs/RadioGroup.js +43 -0
- package/dist/Components/Inputs/ReadOnlyNotice.d.ts +36 -0
- package/dist/Components/Inputs/ReadOnlyNotice.js +116 -0
- package/dist/Components/Inputs/RichTextEditor.d.ts +103 -0
- package/dist/Components/Inputs/RichTextEditor.js +1170 -0
- package/dist/Components/Inputs/RichTextParts.d.ts +63 -0
- package/dist/Components/Inputs/RichTextParts.js +157 -0
- package/dist/Components/Inputs/RowsInput.d.ts +104 -0
- package/dist/Components/Inputs/RowsInput.js +259 -0
- package/dist/Components/Inputs/Slider.d.ts +87 -0
- package/dist/Components/Inputs/Slider.js +216 -0
- package/dist/Components/Inputs/TabularForm.d.ts +23 -0
- package/dist/Components/Inputs/TabularForm.js +283 -0
- package/dist/Components/Inputs/TextArea.d.ts +43 -0
- package/dist/Components/Inputs/TextArea.js +31 -0
- package/dist/Components/Inputs/TextBox.d.ts +52 -0
- package/dist/Components/Inputs/TextBox.js +58 -0
- package/dist/Components/Inputs/TextField.d.ts +31 -0
- package/dist/Components/Inputs/TextField.js +35 -0
- package/dist/Components/Inputs/TimePanel.d.ts +34 -0
- package/dist/Components/Inputs/TimePanel.js +288 -0
- package/dist/Components/Inputs/TimePicker.d.ts +54 -0
- package/dist/Components/Inputs/TimePicker.js +239 -0
- package/dist/Components/Inputs/TreeView.d.ts +160 -0
- package/dist/Components/Inputs/TreeView.js +947 -0
- package/dist/Components/Layouts/MessageBox.d.ts +71 -0
- package/dist/Components/Layouts/MessageBox.js +104 -0
- package/dist/Components/Layouts/Popup.d.ts +92 -0
- package/dist/Components/Layouts/Popup.js +376 -0
- package/dist/Components/Layouts/PopupContext.d.ts +2 -0
- package/dist/Components/Layouts/PopupContext.js +4 -0
- package/dist/Components/Layouts/PopupDock.d.ts +22 -0
- package/dist/Components/Layouts/PopupDock.js +121 -0
- package/dist/Components/Layouts/PopupHost.d.ts +56 -0
- package/dist/Components/Layouts/PopupHost.js +163 -0
- package/dist/Components/Layouts/PopupRules.d.ts +30 -0
- package/dist/Components/Layouts/PopupRules.js +63 -0
- package/dist/Components/Layouts/ThemePicker.d.ts +13 -0
- package/dist/Components/Layouts/ThemePicker.js +22 -0
- package/dist/Components/Layouts/ThemeScript.d.ts +14 -0
- package/dist/Components/Layouts/ThemeScript.js +13 -0
- package/dist/Components/Layouts/ThemeSwitcher.d.ts +13 -0
- package/dist/Components/Layouts/ThemeSwitcher.js +29 -0
- package/dist/Components/Layouts/Toaster.d.ts +76 -0
- package/dist/Components/Layouts/Toaster.js +172 -0
- package/dist/Components/Viewers/DataTable.d.ts +25 -0
- package/dist/Components/Viewers/DataTable.js +542 -0
- package/dist/Components/Viewers/DataTableParts.d.ts +134 -0
- package/dist/Components/Viewers/DataTableParts.js +145 -0
- package/dist/Components/Viewers/MarkdownView.d.ts +26 -0
- package/dist/Components/Viewers/MarkdownView.js +79 -0
- package/dist/Components/Viewers/RichTextView.d.ts +18 -0
- package/dist/Components/Viewers/RichTextView.js +17 -0
- package/dist/Helpers/AnimationHelpers.d.ts +6 -0
- package/dist/Helpers/AnimationHelpers.js +35 -0
- package/dist/Helpers/ApiClient.d.ts +74 -0
- package/dist/Helpers/ApiClient.js +197 -0
- package/dist/Helpers/ApiFormHelpers.d.ts +26 -0
- package/dist/Helpers/ApiFormHelpers.js +56 -0
- package/dist/Helpers/ApiModules.d.ts +135 -0
- package/dist/Helpers/ApiModules.js +194 -0
- package/dist/Helpers/ApiResponses.d.ts +41 -0
- package/dist/Helpers/ApiResponses.js +159 -0
- package/dist/Helpers/ApiRoutes.d.ts +150 -0
- package/dist/Helpers/ApiRoutes.js +191 -0
- package/dist/Helpers/ApiToasts.d.ts +21 -0
- package/dist/Helpers/ApiToasts.js +22 -0
- package/dist/Helpers/ClassHelpers.d.ts +3 -0
- package/dist/Helpers/ClassHelpers.js +4 -0
- package/dist/Helpers/CrudBackend.d.ts +56 -0
- package/dist/Helpers/CrudBackend.js +119 -0
- package/dist/Helpers/CrudHelpers.d.ts +76 -0
- package/dist/Helpers/CrudHelpers.js +202 -0
- package/dist/Helpers/DateHelpers.d.ts +88 -0
- package/dist/Helpers/DateHelpers.js +363 -0
- package/dist/Helpers/DatePreferences.d.ts +14 -0
- package/dist/Helpers/DatePreferences.js +94 -0
- package/dist/Helpers/DateTimeHelpers.d.ts +87 -0
- package/dist/Helpers/DateTimeHelpers.js +286 -0
- package/dist/Helpers/DragHelpers.d.ts +129 -0
- package/dist/Helpers/DragHelpers.js +281 -0
- package/dist/Helpers/DropdownHelpers.d.ts +56 -0
- package/dist/Helpers/DropdownHelpers.js +180 -0
- package/dist/Helpers/FormDrafts.d.ts +18 -0
- package/dist/Helpers/FormDrafts.js +76 -0
- package/dist/Helpers/FormStore.d.ts +231 -0
- package/dist/Helpers/FormStore.js +734 -0
- package/dist/Helpers/InputParamsHelpers.d.ts +79 -0
- package/dist/Helpers/InputParamsHelpers.js +388 -0
- package/dist/Helpers/MarkdownEditing.d.ts +27 -0
- package/dist/Helpers/MarkdownEditing.js +250 -0
- package/dist/Helpers/MarkdownHelpers.d.ts +82 -0
- package/dist/Helpers/MarkdownHelpers.js +775 -0
- package/dist/Helpers/MessageBuilder.d.ts +74 -0
- package/dist/Helpers/MessageBuilder.js +254 -0
- package/dist/Helpers/NepaliCalendar.d.ts +25 -0
- package/dist/Helpers/NepaliCalendar.js +107 -0
- package/dist/Helpers/NumberHelpers.d.ts +71 -0
- package/dist/Helpers/NumberHelpers.js +202 -0
- package/dist/Helpers/Permissions.d.ts +62 -0
- package/dist/Helpers/Permissions.js +133 -0
- package/dist/Helpers/PopoverHelpers.d.ts +43 -0
- package/dist/Helpers/PopoverHelpers.js +91 -0
- package/dist/Helpers/RichTextHelpers.d.ts +77 -0
- package/dist/Helpers/RichTextHelpers.js +1072 -0
- package/dist/Helpers/RowsStore.d.ts +160 -0
- package/dist/Helpers/RowsStore.js +584 -0
- package/dist/Helpers/TableColumns.d.ts +40 -0
- package/dist/Helpers/TableColumns.js +254 -0
- package/dist/Helpers/TableExport.d.ts +30 -0
- package/dist/Helpers/TableExport.js +97 -0
- package/dist/Helpers/TableHelpers.d.ts +102 -0
- package/dist/Helpers/TableHelpers.js +281 -0
- package/dist/Helpers/TableStore.d.ts +142 -0
- package/dist/Helpers/TableStore.js +530 -0
- package/dist/Helpers/ThemeHelpers.d.ts +15 -0
- package/dist/Helpers/ThemeHelpers.js +16 -0
- package/dist/Helpers/TimeHelpers.d.ts +73 -0
- package/dist/Helpers/TimeHelpers.js +253 -0
- package/dist/Helpers/TreeStore.d.ts +188 -0
- package/dist/Helpers/TreeStore.js +577 -0
- package/dist/Helpers/ValidationHelpers.d.ts +124 -0
- package/dist/Helpers/ValidationHelpers.js +301 -0
- package/dist/Interfaces/ApiInterfaces.d.ts +149 -0
- package/dist/Interfaces/ApiInterfaces.js +24 -0
- package/dist/Interfaces/CrudInterfaces.d.ts +171 -0
- package/{src/sso-client.tsx → dist/Interfaces/CrudInterfaces.js} +1 -1
- package/dist/Interfaces/DateInterfaces.d.ts +154 -0
- package/dist/Interfaces/DateInterfaces.js +29 -0
- package/dist/Interfaces/FormInterfaces.d.ts +352 -0
- package/dist/Interfaces/FormInterfaces.js +1 -0
- package/dist/Interfaces/InputInterfaces.d.ts +141 -0
- package/dist/Interfaces/InputInterfaces.js +1 -0
- package/dist/Interfaces/MessageInterfaces.d.ts +111 -0
- package/dist/Interfaces/MessageInterfaces.js +5 -0
- package/dist/Interfaces/TableInterfaces.d.ts +291 -0
- package/dist/Interfaces/TableInterfaces.js +1 -0
- package/dist/Interfaces/ThemeInterfaces.d.ts +17 -0
- package/dist/Interfaces/ThemeInterfaces.js +17 -0
- package/dist/Interfaces/TypeInterfaces.d.ts +4 -0
- package/dist/Interfaces/TypeInterfaces.js +1 -0
- package/dist/Server.Index.d.ts +2 -0
- package/dist/Server.Index.js +5 -0
- package/dist/Services/ApiProxy.d.ts +32 -0
- package/dist/Services/ApiProxy.js +111 -0
- package/dist/Services/BrowserApi.d.ts +78 -0
- package/dist/Services/BrowserApi.js +111 -0
- package/dist/Services/ServerApi.d.ts +49 -0
- package/dist/Services/ServerApi.js +75 -0
- package/dist/Services/ThemeService.d.ts +17 -0
- package/dist/Services/ThemeService.js +83 -0
- package/dist/Shared.Index.d.ts +43 -0
- package/dist/Shared.Index.js +47 -0
- package/package.json +82 -33
- package/src/Styles/Nexus.Base.css +70 -0
- package/src/Styles/Nexus.Button.css +151 -0
- package/src/Styles/Nexus.Calendar.css +275 -0
- package/src/Styles/Nexus.Choice.css +345 -0
- package/src/Styles/Nexus.Crud.css +84 -0
- package/src/Styles/Nexus.DateTime.css +81 -0
- package/src/Styles/Nexus.Dropdown.css +774 -0
- package/src/Styles/Nexus.Editor.css +297 -0
- package/src/Styles/Nexus.Form.css +298 -0
- package/src/Styles/Nexus.Index.css +34 -0
- package/src/Styles/Nexus.Input.css +637 -0
- package/src/Styles/Nexus.Markdown.css +265 -0
- package/src/Styles/Nexus.Menu.css +249 -0
- package/src/Styles/Nexus.Popup.css +731 -0
- package/src/Styles/Nexus.RichText.css +463 -0
- package/src/Styles/Nexus.Rows.css +566 -0
- package/src/Styles/Nexus.Slider.css +278 -0
- package/src/Styles/Nexus.Tab.Buttons.css +364 -0
- package/src/Styles/Nexus.Table.css +1014 -0
- package/src/Styles/Nexus.Theme.Picker.css +159 -0
- package/src/Styles/Nexus.Themes.css +194 -0
- package/src/Styles/Nexus.Time.css +147 -0
- package/src/Styles/Nexus.Toast.css +265 -0
- package/src/Styles/Nexus.Tokens.css +72 -0
- package/src/Styles/Nexus.Tree.css +435 -0
- package/src/api-services/authentication-service.tsx +0 -23
- package/src/api-services/preference-service.tsx +0 -5
- package/src/api-services/system-service.tsx +0 -34
- package/src/client.ts +0 -31
- package/src/components/documents/button.tsx +0 -142
- package/src/components/documents/icon-box.tsx +0 -93
- package/src/components/documents/page-title.tsx +0 -7
- package/src/components/documents/tab-button.tsx +0 -172
- package/src/components/documents/tag.tsx +0 -30
- package/src/components/index.js +0 -0
- package/src/components/inputs/checkbox-input.tsx +0 -66
- package/src/components/inputs/input-box.tsx +0 -48
- package/src/components/inputs/input-element.tsx +0 -65
- package/src/components/inputs/input-form.tsx +0 -164
- package/src/components/inputs/input.tsx +0 -181
- package/src/components/inputs/number-input.tsx +0 -108
- package/src/components/inputs/radiobox-input.tsx +0 -53
- package/src/components/inputs/textarea-input.tsx +0 -47
- package/src/components/inputs/textbox-input.tsx +0 -45
- package/src/components/layouts/global-dialogbox.tsx +0 -431
- package/src/components/layouts/global-layout.tsx +0 -59
- package/src/components/layouts/layout-helpers.tsx +0 -20
- package/src/components/layouts/panels/user-panel.tsx +0 -112
- package/src/components/layouts/utility-menu.tsx +0 -49
- package/src/components/panels/theme-panel.tsx +0 -46
- package/src/helpers/bitwise-helpers.tsx +0 -11
- package/src/helpers/browser-helpers.tsx +0 -156
- package/src/helpers/datasource-helpers.tsx +0 -99
- package/src/helpers/element-helpers.tsx +0 -57
- package/src/helpers/input-helpers.tsx +0 -74
- package/src/helpers/string-helpers.tsx +0 -28
- package/src/helpers/utility-helpers.tsx +0 -45
- package/src/helpers/validation-helpers.tsx +0 -302
- package/src/index.ts +0 -26
- package/src/interface.ts +0 -19
- package/src/interfaces/auth-token-interfaces.tsx +0 -6
- package/src/interfaces/browser-interfaces.tsx +0 -36
- package/src/interfaces/button-interfaces.tsx +0 -63
- package/src/interfaces/datasource-interfaces.tsx +0 -22
- package/src/interfaces/datatable-interfaces.tsx +0 -25
- package/src/interfaces/dialogbox-interfaces.tsx +0 -5
- package/src/interfaces/exception-interfaces.tsx +0 -99
- package/src/interfaces/http-interfaces.tsx +0 -129
- package/src/interfaces/icon-interfaces.tsx +0 -129
- package/src/interfaces/input-interfaces.tsx +0 -410
- package/src/interfaces/layout-interfaces.tsx +0 -191
- package/src/interfaces/menu-interfaces.tsx +0 -49
- package/src/interfaces/message-interfaces.tsx +0 -32
- package/src/interfaces/permission-interfaces.tsx +0 -9
- package/src/interfaces/storage-interfaces.tsx +0 -5
- package/src/interfaces/system-interfaces.tsx +0 -22
- package/src/interfaces/theme-interfaces.tsx +0 -123
- package/src/interfaces/type-interfaces.tsx +0 -28
- package/src/interfaces/user-interfaces.tsx +0 -47
- package/src/nexus-client.tsx +0 -21
- package/src/nexus.environments.tsx +0 -66
- package/src/proxy-api/proxy-backend.tsx +0 -60
- package/src/proxy-api/proxy-constants.tsx +0 -28
- package/src/proxy-api/proxy-helpers.tsx +0 -91
- package/src/proxy-api-client.tsx +0 -1
- package/src/proxy-api-server.tsx +0 -2
- package/src/services/http-client-services.tsx +0 -75
- package/src/services/http-services.tsx +0 -158
- package/src/services/loader-service.tsx +0 -185
- package/src/services/localstorage-service.tsx +0 -119
- package/src/services/message-services.tsx +0 -383
- package/src/services/theme-service.tsx +0 -161
- package/src/services/user-services.tsx +0 -10
- package/src/sso-config/auth-token-validation.ts +0 -16
- package/src/sso-config/callback-route.tsx +0 -35
- package/src/sso-config/cookie-encryption.ts +0 -51
- package/src/sso-config/cookie-helpers.tsx +0 -102
- package/src/sso-config/forgot-password-route.tsx +0 -36
- package/src/sso-config/oauth-callback-state.ts +0 -61
- package/src/sso-config/pkce-helpers.ts +0 -9
- package/src/sso-config/provider-complete-route.tsx +0 -18
- package/src/sso-config/redirect-context-actions.tsx +0 -45
- package/src/sso-config/redirect-context-helpers.tsx +0 -159
- package/src/sso-config/redirect-context-persist.tsx +0 -18
- package/src/sso-config/redirect-context-route.tsx +0 -45
- package/src/sso-config/refresh-route.tsx +0 -23
- package/src/sso-config/sign-in-route.tsx +0 -74
- package/src/sso-config/sign-out-route.tsx +0 -57
- package/src/sso-config/sign-up-route.tsx +0 -57
- package/src/sso-config/sso-backend-flow.ts +0 -38
- package/src/sso-config/sso-complete-route.tsx +0 -50
- package/src/sso-config/sso-config.ts +0 -59
- package/src/sso-config/sso-interfaces.tsx +0 -99
- package/src/sso-config/sso-response-helpers.tsx +0 -20
- package/src/sso-server.tsx +0 -21
- package/src/styles/nexus.animation.css +0 -269
- package/src/styles/nexus.core.css +0 -119
- package/src/styles/nexus.dialog.css +0 -144
- package/src/styles/nexus.icon.css +0 -51
- package/src/styles/nexus.input.css +0 -207
- package/src/styles/nexus.loader.css +0 -11
- package/src/styles/nexus.logic.css +0 -47
- package/src/styles/nexus.utility.css +0 -347
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { DEFAULT_TIME_FORMAT } from "../Interfaces/DateInterfaces.js";
|
|
2
|
+
import { toDevanagariDigits, toLatinDigits } from "./DateHelpers.js";
|
|
3
|
+
/*
|
|
4
|
+
* Pure time helpers. A time of day is an ISO string "HH:mm" or "HH:mm:ss" on a 24-hour clock, with no date and no zone,
|
|
5
|
+
* so the same value means the same time on every machine (a .NET `TimeOnly`). Arithmetic runs on seconds since
|
|
6
|
+
* midnight. How a time is written (12 or 24 hours, Devanagari digits) is only its display.
|
|
7
|
+
*/
|
|
8
|
+
export const SECONDS_PER_DAY = 86400;
|
|
9
|
+
/** "14:30" or "14:30:15": hours 00 to 23, a two-digit minute, an optional two-digit second. */
|
|
10
|
+
export const ISO_TIME_PATTERN = /^([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?$/;
|
|
11
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
12
|
+
/** Whether text is an ISO time: "14:30" or "14:30:15". */
|
|
13
|
+
export function isIsoTime(text) {
|
|
14
|
+
return typeof text === "string" && ISO_TIME_PATTERN.test(text);
|
|
15
|
+
}
|
|
16
|
+
/** Seconds since midnight of an ISO time. The text must be an ISO time (`isIsoTime`). */
|
|
17
|
+
export function timeToSeconds(iso) {
|
|
18
|
+
return Number(iso.slice(0, 2)) * 3600 + Number(iso.slice(3, 5)) * 60 + (iso.length > 5 ? Number(iso.slice(6, 8)) : 0);
|
|
19
|
+
}
|
|
20
|
+
/** The ISO time of seconds since midnight, wrapping past midnight both ways: "HH:mm", or "HH:mm:ss" with `seconds`. */
|
|
21
|
+
export function secondsToIsoTime(total, seconds = false) {
|
|
22
|
+
const value = ((Math.floor(total) % SECONDS_PER_DAY) + SECONDS_PER_DAY) % SECONDS_PER_DAY;
|
|
23
|
+
const time = `${pad(Math.floor(value / 3600))}:${pad(Math.floor(value / 60) % 60)}`;
|
|
24
|
+
return seconds ? `${time}:${pad(value % 60)}` : time;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Turns anything a time can arrive as into an ISO time, or `null`:
|
|
28
|
+
* - "14:30", "9:05", "14:30:15", "14:30:15.250" (a .NET `TimeOnly` or SQL `time`);
|
|
29
|
+
* - an ISO date-time with a zone, "2026-09-17T08:45:00Z", becomes the browser's local time of that instant;
|
|
30
|
+
* - one without a zone, "2026-09-17T14:30:00", keeps its time part;
|
|
31
|
+
* - a `Date` gives its local time, like `new Date()` for now.
|
|
32
|
+
* Without `seconds` the result is "HH:mm" and any seconds are dropped; with it, "HH:mm:ss".
|
|
33
|
+
*/
|
|
34
|
+
export function toIsoTime(input, seconds = false) {
|
|
35
|
+
if (input === null || input === undefined || input === "")
|
|
36
|
+
return null;
|
|
37
|
+
if (input instanceof Date) {
|
|
38
|
+
return Number.isNaN(input.getTime()) ? null : secondsToIsoTime(input.getHours() * 3600 + input.getMinutes() * 60 + input.getSeconds(), seconds);
|
|
39
|
+
}
|
|
40
|
+
const text = input.trim();
|
|
41
|
+
const time = /^(\d{1,2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?$/.exec(text);
|
|
42
|
+
if (time) {
|
|
43
|
+
const hour = Number(time[1]);
|
|
44
|
+
const minute = Number(time[2]);
|
|
45
|
+
const second = Number(time[3] ?? 0);
|
|
46
|
+
if (hour > 23 || minute > 59 || second > 59)
|
|
47
|
+
return null;
|
|
48
|
+
return secondsToIsoTime(hour * 3600 + minute * 60 + second, seconds);
|
|
49
|
+
}
|
|
50
|
+
const dateTime = /^\d{4}-\d{2}-\d{2}[T ](\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?)(Z|[+-]\d{2}:?\d{2})?$/i.exec(text);
|
|
51
|
+
if (!dateTime)
|
|
52
|
+
return null;
|
|
53
|
+
if (!dateTime[2])
|
|
54
|
+
return toIsoTime(dateTime[1], seconds);
|
|
55
|
+
return toIsoTime(new Date(text), seconds);
|
|
56
|
+
}
|
|
57
|
+
/** The time now where the browser is. */
|
|
58
|
+
export function nowIsoTime(seconds = false) {
|
|
59
|
+
return toIsoTime(new Date(), seconds);
|
|
60
|
+
}
|
|
61
|
+
/** Adds minutes (negative to go back), wrapping past midnight: `addMinutes("23:30", 45)` is "00:15". Keeps the value's seconds. */
|
|
62
|
+
export function addMinutes(iso, minutes) {
|
|
63
|
+
return secondsToIsoTime(timeToSeconds(iso) + minutes * 60, iso.length > 5);
|
|
64
|
+
}
|
|
65
|
+
/** Negative when `a` is earlier than `b`. "14:30" and "14:30:00" are the same time. */
|
|
66
|
+
export const compareIsoTimes = (a, b) => timeToSeconds(a) - timeToSeconds(b);
|
|
67
|
+
/**
|
|
68
|
+
* Whether a time lies within inclusive limits, given as seconds since midnight. With `max` earlier than `min` the
|
|
69
|
+
* range runs past midnight: 22:00 to 06:00 allows 23:00 and 05:00, not 12:00.
|
|
70
|
+
*/
|
|
71
|
+
export function isSecondsInRange(value, min, max) {
|
|
72
|
+
if (min !== null && max !== null && max < min)
|
|
73
|
+
return value >= min || value <= max;
|
|
74
|
+
return (min === null || value >= min) && (max === null || value <= max);
|
|
75
|
+
}
|
|
76
|
+
/** Whether an ISO time lies within limits given as time inputs; see `isSecondsInRange` for ranges past midnight. */
|
|
77
|
+
export function isTimeInRange(iso, min, max) {
|
|
78
|
+
const from = toIsoTime(min, true);
|
|
79
|
+
const to = toIsoTime(max, true);
|
|
80
|
+
return isSecondsInRange(timeToSeconds(iso), from === null ? null : timeToSeconds(from), to === null ? null : timeToSeconds(to));
|
|
81
|
+
}
|
|
82
|
+
/** A step in seconds as the components use it: a whole number from 1 to a day, 60 when missing or invalid. */
|
|
83
|
+
export function normalizeTimeStep(step) {
|
|
84
|
+
return step !== undefined && Number.isFinite(step) && step >= 1 ? Math.min(Math.round(step), SECONDS_PER_DAY) : 60;
|
|
85
|
+
}
|
|
86
|
+
/** Whether a step needs seconds: any step that is not a whole number of minutes. */
|
|
87
|
+
export const stepHasSeconds = (step) => normalizeTimeStep(step) % 60 !== 0;
|
|
88
|
+
/** "15 minutes", "1 hour", "30 seconds", "1 minute 30 seconds": a step as words, for messages. */
|
|
89
|
+
export function describeTimeStep(step) {
|
|
90
|
+
const value = normalizeTimeStep(step);
|
|
91
|
+
const units = [
|
|
92
|
+
[Math.floor(value / 3600), "hour"],
|
|
93
|
+
[Math.floor(value / 60) % 60, "minute"],
|
|
94
|
+
[value % 60, "second"],
|
|
95
|
+
];
|
|
96
|
+
return units
|
|
97
|
+
.filter(([count]) => count > 0)
|
|
98
|
+
.map(([count, unit]) => `${count} ${unit}${count === 1 ? "" : "s"}`)
|
|
99
|
+
.join(" ");
|
|
100
|
+
}
|
|
101
|
+
// Formatting and parsing
|
|
102
|
+
const FORMAT_TOKENS = /HH|H|hh|h|mm|m|ss|s|A|a/g;
|
|
103
|
+
const MERIDIEM_LATIN = ["AM", "PM"];
|
|
104
|
+
const MERIDIEM_DEVANAGARI = ["पूर्वाह्न", "अपराह्न"];
|
|
105
|
+
/** Whether a time format is on a 12-hour clock: it has an `hh` or `h` token. */
|
|
106
|
+
export const isTwelveHourFormat = (format) => /h/.test(format);
|
|
107
|
+
/** The names of the two halves of the day: AM and PM, or पूर्वाह्न and अपराह्न. */
|
|
108
|
+
export function getMeridiemNames(script = "latin") {
|
|
109
|
+
return script === "devanagari" ? MERIDIEM_DEVANAGARI : MERIDIEM_LATIN;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A format with or without seconds: `true` adds ":ss" after the minutes of a format that has none ("hh:mm A" gives
|
|
113
|
+
* "hh:mm:ss A"), `false` removes the seconds and the separator before them. `undefined` keeps the format.
|
|
114
|
+
*/
|
|
115
|
+
export function timeFormatWithSeconds(format, seconds) {
|
|
116
|
+
if (seconds === undefined)
|
|
117
|
+
return format;
|
|
118
|
+
if (seconds)
|
|
119
|
+
return /s/.test(format) ? format : format.replace(/mm|m/, token => `${token}:ss`);
|
|
120
|
+
return format.replace(/[:.]?ss?/g, "");
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Writes a time with a format of tokens: `HH` `H` 24-hour, `hh` `h` 12-hour, `mm` `m` minute, `ss` `s` second, `A`
|
|
124
|
+
* AM/PM, `a` am/pm. "hh:mm A" gives 02:30 PM; "HH:mm" gives 14:30. With the Devanagari script, digits and the
|
|
125
|
+
* halves of the day are Nepali: ०२:३० अपराह्न. Returns "" for an empty or invalid input.
|
|
126
|
+
*/
|
|
127
|
+
export function formatTime(input, options = {}) {
|
|
128
|
+
const iso = toIsoTime(input, true);
|
|
129
|
+
if (!iso)
|
|
130
|
+
return "";
|
|
131
|
+
const script = options.script ?? "latin";
|
|
132
|
+
const format = timeFormatWithSeconds(options.format || DEFAULT_TIME_FORMAT, options.seconds);
|
|
133
|
+
const total = timeToSeconds(iso);
|
|
134
|
+
const hour = Math.floor(total / 3600);
|
|
135
|
+
const hour12 = hour % 12 || 12;
|
|
136
|
+
const minute = Math.floor(total / 60) % 60;
|
|
137
|
+
const second = total % 60;
|
|
138
|
+
const digits = (value, width) => {
|
|
139
|
+
const text = width === 2 ? pad(value) : String(value);
|
|
140
|
+
return script === "devanagari" ? toDevanagariDigits(text) : text;
|
|
141
|
+
};
|
|
142
|
+
const meridiem = getMeridiemNames(script)[hour < 12 ? 0 : 1];
|
|
143
|
+
return format.replace(FORMAT_TOKENS, token => {
|
|
144
|
+
switch (token) {
|
|
145
|
+
case "HH":
|
|
146
|
+
return digits(hour, 2);
|
|
147
|
+
case "H":
|
|
148
|
+
return digits(hour, 1);
|
|
149
|
+
case "hh":
|
|
150
|
+
return digits(hour12, 2);
|
|
151
|
+
case "h":
|
|
152
|
+
return digits(hour12, 1);
|
|
153
|
+
case "mm":
|
|
154
|
+
return digits(minute, 2);
|
|
155
|
+
case "m":
|
|
156
|
+
return digits(minute, 1);
|
|
157
|
+
case "ss":
|
|
158
|
+
return digits(second, 2);
|
|
159
|
+
case "s":
|
|
160
|
+
return digits(second, 1);
|
|
161
|
+
case "A":
|
|
162
|
+
return meridiem;
|
|
163
|
+
default:
|
|
164
|
+
return script === "devanagari" ? meridiem : meridiem.toLowerCase();
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/** AM or PM from the letters of typed text: "am", "a.m.", "A", "p", "PM", पूर्वाह्न, अपराह्न. `undefined` for other words. */
|
|
169
|
+
function meridiemFromLetters(letters) {
|
|
170
|
+
if (!letters)
|
|
171
|
+
return null;
|
|
172
|
+
if (letters === "a" || letters === "am")
|
|
173
|
+
return "am";
|
|
174
|
+
if (letters === "p" || letters === "pm")
|
|
175
|
+
return "pm";
|
|
176
|
+
if (letters.startsWith("पूर्व") || letters.startsWith("पुर्व"))
|
|
177
|
+
return "am";
|
|
178
|
+
if (letters.startsWith("अपर"))
|
|
179
|
+
return "pm";
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Reads a time the user typed, on either clock: "14:30", "2:30 pm", "2.30p", "230 PM", "1430", "9", "12 am",
|
|
184
|
+
* "14:30:15", "०२:३० अपराह्न". Without AM or PM the hours are read on a 24-hour clock, so "2:30" is 02:30. Returns the
|
|
185
|
+
* ISO time, "HH:mm" (typed seconds are dropped) or "HH:mm:ss" with `seconds`, or `null` for text that is not a time.
|
|
186
|
+
*/
|
|
187
|
+
export function parseTimeText(text, options = {}) {
|
|
188
|
+
const clean = toLatinDigits(text).trim().toLowerCase();
|
|
189
|
+
if (!clean)
|
|
190
|
+
return null;
|
|
191
|
+
const meridiem = meridiemFromLetters(clean.replace(/[^\p{L}\p{M}]/gu, ""));
|
|
192
|
+
if (meridiem === undefined)
|
|
193
|
+
return null;
|
|
194
|
+
// Only digits, separators, and the letters of AM or PM.
|
|
195
|
+
if (/[^\d\s:.\p{L}\p{M}]/u.test(clean))
|
|
196
|
+
return null;
|
|
197
|
+
const groups = clean.match(/\d+/g) ?? [];
|
|
198
|
+
let parts;
|
|
199
|
+
if (groups.length === 1) {
|
|
200
|
+
const digits = groups[0];
|
|
201
|
+
if (digits.length <= 2)
|
|
202
|
+
parts = [Number(digits), 0, 0];
|
|
203
|
+
else if (digits.length <= 6 && digits.length !== 5) {
|
|
204
|
+
// 230, 1430, 143015: the hour first, then two digits for each of minutes and seconds.
|
|
205
|
+
const hourDigits = digits.length === 3 ? 1 : 2;
|
|
206
|
+
parts = [Number(digits.slice(0, hourDigits)), Number(digits.slice(hourDigits, hourDigits + 2)), Number(digits.slice(hourDigits + 2) || 0)];
|
|
207
|
+
}
|
|
208
|
+
else
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
else if (groups.length === 2 || groups.length === 3) {
|
|
212
|
+
if (groups.slice(1).some(group => group.length !== 2) || groups[0].length > 2)
|
|
213
|
+
return null;
|
|
214
|
+
parts = [Number(groups[0]), Number(groups[1]), Number(groups[2] ?? 0)];
|
|
215
|
+
}
|
|
216
|
+
else
|
|
217
|
+
return null;
|
|
218
|
+
let [hour, minute, second] = parts;
|
|
219
|
+
if (minute > 59 || second > 59)
|
|
220
|
+
return null;
|
|
221
|
+
if (meridiem) {
|
|
222
|
+
// 12 am is midnight and 12 pm is noon; an hour past 12 already says which half it is.
|
|
223
|
+
if (hour > 23)
|
|
224
|
+
return null;
|
|
225
|
+
if (hour <= 12)
|
|
226
|
+
hour = (hour % 12) + (meridiem === "pm" ? 12 : 0);
|
|
227
|
+
}
|
|
228
|
+
else if (hour > 23)
|
|
229
|
+
return null;
|
|
230
|
+
return secondsToIsoTime(hour * 3600 + minute * 60 + second, options.seconds ?? false);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* The times a list of slots offers: every `step` seconds from `min` (or midnight) to `max` (or the end of the day),
|
|
234
|
+
* past midnight when `max` is earlier than `min`. Returns ISO times, with seconds when the step needs them.
|
|
235
|
+
*/
|
|
236
|
+
export function listTimeSlots(step, min, max) {
|
|
237
|
+
const size = normalizeTimeStep(step);
|
|
238
|
+
const seconds = size % 60 !== 0;
|
|
239
|
+
const from = toIsoTime(min, true);
|
|
240
|
+
const to = toIsoTime(max, true);
|
|
241
|
+
const start = from === null ? null : timeToSeconds(from);
|
|
242
|
+
const end = to === null ? null : timeToSeconds(to);
|
|
243
|
+
// Slots are counted from midnight, as the step is.
|
|
244
|
+
const before = [];
|
|
245
|
+
const after = [];
|
|
246
|
+
for (let value = 0; value < SECONDS_PER_DAY; value += size) {
|
|
247
|
+
if (!isSecondsInRange(value, start, end))
|
|
248
|
+
continue;
|
|
249
|
+
// A range past midnight lists the evening first, then the morning after.
|
|
250
|
+
(start !== null && value < start ? after : before).push(secondsToIsoTime(value, seconds));
|
|
251
|
+
}
|
|
252
|
+
return before.concat(after);
|
|
253
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
export type TreeValue = string | number;
|
|
2
|
+
/** An item of a tree: any object with a value, a parent value, and a label under the keys the tree is given. */
|
|
3
|
+
export type TreeItem = object;
|
|
4
|
+
/** A box: checked, unchecked, or `mixed` for a parent with some of its items checked. */
|
|
5
|
+
export type TreeCheckState = "checked" | "mixed" | "unchecked";
|
|
6
|
+
/**
|
|
7
|
+
* Which checked items make up the value, with `cascade`:
|
|
8
|
+
* - `leaves`: items without children, such as the actions of a permission tree. A parent follows its items.
|
|
9
|
+
* - `checked`: every checked item, and a parent when all of its items are checked.
|
|
10
|
+
* - `any`: every checked item, and every parent with at least one checked item (a menu to show because one of its actions is allowed).
|
|
11
|
+
*/
|
|
12
|
+
export type TreeValueMode = "leaves" | "checked" | "any";
|
|
13
|
+
export interface TreeStoreOptions<TItem extends TreeItem = TreeItem> {
|
|
14
|
+
/** The item field that holds its value. Default `id`. */
|
|
15
|
+
valueKey?: string;
|
|
16
|
+
/** The item field that holds its parent's value; empty for a top-level item. Default `parentId`. */
|
|
17
|
+
parentKey?: string;
|
|
18
|
+
/** The item field shown as its name. Default `label`. */
|
|
19
|
+
labelKey?: string;
|
|
20
|
+
/** Items that cannot be checked, changed, or deleted, and pass that on to their children. Default: `disabled: true` or `isDisabled: true`. */
|
|
21
|
+
isItemDisabled?: (item: TItem) => boolean;
|
|
22
|
+
/** Items checked at the start when no value is given. Default: `checked: true` or `isChecked: true`. */
|
|
23
|
+
isItemChecked?: (item: TItem) => boolean;
|
|
24
|
+
/** Checking a parent checks its items, and a parent shows the state of its items. Default true. */
|
|
25
|
+
cascade?: boolean;
|
|
26
|
+
/** Default `leaves`. Ignored without `cascade`, where the value is every checked item. */
|
|
27
|
+
valueMode?: TreeValueMode;
|
|
28
|
+
}
|
|
29
|
+
export interface TreeNode<TItem extends TreeItem = TreeItem> {
|
|
30
|
+
/** A number unique to this node for its whole life, for React keys and element ids. */
|
|
31
|
+
readonly uid: number;
|
|
32
|
+
/** The value as text: the key in maps, so `7` and `"7"` are the same item. */
|
|
33
|
+
key: string;
|
|
34
|
+
value: TreeValue;
|
|
35
|
+
item: TItem;
|
|
36
|
+
label: string;
|
|
37
|
+
parent: TreeNode<TItem> | null;
|
|
38
|
+
children: TreeNode<TItem>[];
|
|
39
|
+
/** 0 for a top-level item. */
|
|
40
|
+
depth: number;
|
|
41
|
+
/** The index among its siblings. */
|
|
42
|
+
position: number;
|
|
43
|
+
/** The item's own flag. */
|
|
44
|
+
disabled: boolean;
|
|
45
|
+
/** The item or one of its parents is disabled. */
|
|
46
|
+
disabledPath: boolean;
|
|
47
|
+
/** Cannot be checked, changed, or deleted: disabled, under a disabled parent, or every child is locked. */
|
|
48
|
+
locked: boolean;
|
|
49
|
+
expanded: boolean;
|
|
50
|
+
/** A leaf's state with `cascade`; any node's state without it. */
|
|
51
|
+
checked: boolean;
|
|
52
|
+
/** Leaves in this subtree, 1 for a leaf. */
|
|
53
|
+
leaves: number;
|
|
54
|
+
/** Checked leaves in this subtree. */
|
|
55
|
+
checkedLeaves: number;
|
|
56
|
+
/** Leaves in this subtree that are not locked. */
|
|
57
|
+
openLeaves: number;
|
|
58
|
+
/** Checked leaves in this subtree that are not locked. */
|
|
59
|
+
openChecked: number;
|
|
60
|
+
/** Being created and not saved yet: not part of the value or the items. */
|
|
61
|
+
draft: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** What expanding or collapsing did to the visible rows, for an animation. */
|
|
64
|
+
export interface TreeRowsChange<TItem extends TreeItem = TreeItem> {
|
|
65
|
+
/** The row index where rows were added or removed. */
|
|
66
|
+
at: number;
|
|
67
|
+
/** How many rows were added or removed. */
|
|
68
|
+
count: number;
|
|
69
|
+
/** The rows before the change. */
|
|
70
|
+
before: readonly TreeNode<TItem>[];
|
|
71
|
+
}
|
|
72
|
+
export declare const TREE_DEFAULT_KEYS: {
|
|
73
|
+
readonly value: "id";
|
|
74
|
+
readonly parent: "parentId";
|
|
75
|
+
readonly label: "label";
|
|
76
|
+
};
|
|
77
|
+
/** The text key of a value, or `null` for no value. */
|
|
78
|
+
export declare function treeKey(value: unknown): string | null;
|
|
79
|
+
/**
|
|
80
|
+
* A tree built from a flat list. Items whose parent is missing become top-level items, and a loop of parents is
|
|
81
|
+
* broken at the first item of the loop. Siblings keep the order of the list; a repeated value keeps its first item.
|
|
82
|
+
*/
|
|
83
|
+
export declare class TreeStore<TItem extends TreeItem = TreeItem> {
|
|
84
|
+
readonly valueKey: string;
|
|
85
|
+
readonly parentKey: string;
|
|
86
|
+
readonly labelKey: string;
|
|
87
|
+
readonly cascade: boolean;
|
|
88
|
+
readonly valueMode: TreeValueMode;
|
|
89
|
+
private readonly isDisabled;
|
|
90
|
+
private readonly isChecked;
|
|
91
|
+
roots: TreeNode<TItem>[];
|
|
92
|
+
/** The visible rows in order: top-level items, and the children of every expanded item whose parents are expanded. A new array after each change. */
|
|
93
|
+
rows: readonly TreeNode<TItem>[];
|
|
94
|
+
private byKey;
|
|
95
|
+
/** Without `cascade`: checked nodes, nodes that are not locked, and the checked ones among them. */
|
|
96
|
+
private checkedNodes;
|
|
97
|
+
private openNodes;
|
|
98
|
+
private openCheckedNodes;
|
|
99
|
+
private indexCache;
|
|
100
|
+
constructor(items?: readonly TItem[], options?: TreeStoreOptions<TItem>, value?: readonly TreeValue[]);
|
|
101
|
+
/** Items in the tree, drafts included. */
|
|
102
|
+
get size(): number;
|
|
103
|
+
/** The node of a value. */
|
|
104
|
+
get(value: TreeValue | null | undefined): TreeNode<TItem> | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Replaces the items. Expanded items stay expanded. The checked items come from `value` when given, otherwise from
|
|
107
|
+
* the items' own flags.
|
|
108
|
+
*/
|
|
109
|
+
setItems(items: readonly TItem[], value?: readonly TreeValue[]): void;
|
|
110
|
+
/** Every item in tree order, without drafts. */
|
|
111
|
+
items(): TItem[];
|
|
112
|
+
/** A node and everything under it, in tree order. */
|
|
113
|
+
subtree(node: TreeNode<TItem>): TreeNode<TItem>[];
|
|
114
|
+
/** The node's parents, the top-level one first. */
|
|
115
|
+
path(node: TreeNode<TItem>): TreeNode<TItem>[];
|
|
116
|
+
/** The state of a node's box. */
|
|
117
|
+
state(node: TreeNode<TItem>): TreeCheckState;
|
|
118
|
+
/** Checked boxes and all boxes: leaves with `cascade`, every item without it. Drafts count. */
|
|
119
|
+
counts(): {
|
|
120
|
+
checked: number;
|
|
121
|
+
total: number;
|
|
122
|
+
};
|
|
123
|
+
/** The checked values, in tree order, following `valueMode`. */
|
|
124
|
+
value(): TreeValue[];
|
|
125
|
+
/** The items of the value, in the same order. */
|
|
126
|
+
valueItems(): TItem[];
|
|
127
|
+
/** Checks exactly these values. Locks do not apply: this is the saved state, not a user's change. Returns whether anything changed. */
|
|
128
|
+
setValue(values: readonly TreeValue[]): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* What a click on the node's box does. With `cascade` it checks every item under the node that is not locked, or
|
|
131
|
+
* unchecks them when they are all checked already. Returns whether anything changed; nothing does on a locked node.
|
|
132
|
+
*/
|
|
133
|
+
toggle(node: TreeNode<TItem>): boolean;
|
|
134
|
+
/** Checks or unchecks a node; with `cascade`, every item under it that is not locked. Returns whether anything changed. */
|
|
135
|
+
setChecked(node: TreeNode<TItem>, checked: boolean): boolean;
|
|
136
|
+
/** The state of a "select all" box, over the items that are not locked; `null` when every item is locked. */
|
|
137
|
+
allState(): TreeCheckState | null;
|
|
138
|
+
/** What a click on a "select all" box does: checks every item that is not locked, or unchecks them all when all are checked. */
|
|
139
|
+
toggleAll(): boolean;
|
|
140
|
+
/** Checks or unchecks every item that is not locked. Returns whether anything changed. */
|
|
141
|
+
checkAll(checked: boolean): boolean;
|
|
142
|
+
/** Whether every parent of the node is expanded, so the node is a row. */
|
|
143
|
+
isVisible(node: TreeNode<TItem>): boolean;
|
|
144
|
+
/** The node's row index, or -1 when it is not a row. */
|
|
145
|
+
indexOf(node: TreeNode<TItem>): number;
|
|
146
|
+
/** Expands a node. Returns the rows it added, or `null` when no rows changed. */
|
|
147
|
+
expand(node: TreeNode<TItem>): TreeRowsChange<TItem> | null;
|
|
148
|
+
/** Collapses a node. Returns the rows it removed, or `null` when no rows changed. */
|
|
149
|
+
collapse(node: TreeNode<TItem>): TreeRowsChange<TItem> | null;
|
|
150
|
+
/** Expands every item, or only the first `levels` levels (1 expands the top-level items). */
|
|
151
|
+
expandAll(levels?: number): void;
|
|
152
|
+
collapseAll(): void;
|
|
153
|
+
/** Expands these items and their parents, so the items and their children show. */
|
|
154
|
+
expandValues(values: readonly TreeValue[]): void;
|
|
155
|
+
/** The values of the expanded items, in tree order. */
|
|
156
|
+
expandedValues(): TreeValue[];
|
|
157
|
+
/** Expands the parents of a node so it becomes a row. Returns whether rows changed. */
|
|
158
|
+
reveal(node: TreeNode<TItem>): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* Adds an item under `parent` (at the top level for `null`), as its last child unless `index` is given, and expands
|
|
161
|
+
* the parent. A `draft` is not part of the value or the items until `update` saves it. Throws on a value in use.
|
|
162
|
+
*/
|
|
163
|
+
insert(parent: TreeNode<TItem> | null, item: TItem, options?: {
|
|
164
|
+
index?: number;
|
|
165
|
+
draft?: boolean;
|
|
166
|
+
}): TreeNode<TItem>;
|
|
167
|
+
/**
|
|
168
|
+
* Replaces a node's item, e.g. after a rename, or once a draft is saved and the server gave it an id. The value can
|
|
169
|
+
* change; the parent cannot. Throws on a value another item uses.
|
|
170
|
+
*/
|
|
171
|
+
update(node: TreeNode<TItem>, item: TItem, options?: {
|
|
172
|
+
draft?: boolean;
|
|
173
|
+
}): void;
|
|
174
|
+
/** Removes a node and everything under it. Returns the removed nodes in tree order. */
|
|
175
|
+
remove(node: TreeNode<TItem>): TreeNode<TItem>[];
|
|
176
|
+
private createNode;
|
|
177
|
+
private keysOf;
|
|
178
|
+
/** With `valueMode: "checked"`, a parent in the value stands for all of its items. */
|
|
179
|
+
private checkedByParent;
|
|
180
|
+
/** Locks and counts for every node, given in tree order: parents pass locks down, children pass counts up. */
|
|
181
|
+
private recount;
|
|
182
|
+
/** Sets every open leaf under a node (the node itself for a leaf), updating counts up the path of each leaf that changes. */
|
|
183
|
+
private setLeaves;
|
|
184
|
+
private setNodeChecked;
|
|
185
|
+
private checkedInOrder;
|
|
186
|
+
}
|
|
187
|
+
/** Nodes in tree order: each node, then its children. No recursion, so even a chain 100,000 levels deep works. */
|
|
188
|
+
export declare function preOrder<TItem extends TreeItem>(nodes: readonly TreeNode<TItem>[]): TreeNode<TItem>[];
|