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,111 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { messageBox } from "../Components/Layouts/MessageBox.js";
|
|
3
|
+
import { toast } from "../Components/Layouts/Toaster.js";
|
|
4
|
+
import { apiCallContext, createApiClient } from "../Helpers/ApiClient.js";
|
|
5
|
+
import { unwrapApiResult } from "../Helpers/ApiResponses.js";
|
|
6
|
+
import { getApiModules } from "../Helpers/ApiModules.js";
|
|
7
|
+
import { isApiEndpoint, joinUrl } from "../Helpers/ApiRoutes.js";
|
|
8
|
+
import { planApiToast, planLoadingToast } from "../Helpers/ApiToasts.js";
|
|
9
|
+
import { buildMessage } from "../Helpers/MessageBuilder.js";
|
|
10
|
+
let settings = {};
|
|
11
|
+
/**
|
|
12
|
+
* Sets up `api` for the app. Call it once in a client module that the root layout loads; later calls change only the
|
|
13
|
+
* settings they name. Nothing is needed when the proxy is at `/api/app` and the defaults suit.
|
|
14
|
+
*/
|
|
15
|
+
export function configureApi(config) {
|
|
16
|
+
settings = { ...settings, ...config };
|
|
17
|
+
}
|
|
18
|
+
/** Nexus error code for an expired token. */
|
|
19
|
+
const TOKEN_EXPIRED = 2003;
|
|
20
|
+
const TOAST_DURATION = 5000;
|
|
21
|
+
function showToast(plan, id) {
|
|
22
|
+
// `icon`, `duration`, and `closable` are set, so a loading toast turned into this one loses its spinner and timer.
|
|
23
|
+
toast(plan.title, { id, tone: plan.tone, message: plan.message, icon: undefined, duration: TOAST_DURATION, closable: true });
|
|
24
|
+
}
|
|
25
|
+
const config = {
|
|
26
|
+
resolveUrl: (endpoint, path) => joinUrl(getApiModules().browserUrl(endpoint.module), path),
|
|
27
|
+
headers: call => settings.headers?.(call),
|
|
28
|
+
token: call => settings.token?.(call),
|
|
29
|
+
get timeout() {
|
|
30
|
+
return settings.timeout;
|
|
31
|
+
},
|
|
32
|
+
get credentials() {
|
|
33
|
+
return settings.credentials;
|
|
34
|
+
},
|
|
35
|
+
dedupe: true,
|
|
36
|
+
onStart(call) {
|
|
37
|
+
const loading = planLoadingToast(call.context, call.options.toast);
|
|
38
|
+
const loadingId = loading ? toast.loading(loading) : undefined;
|
|
39
|
+
return result => {
|
|
40
|
+
if (result.status === 401 || result.errorCode === TOKEN_EXPIRED)
|
|
41
|
+
settings.onSignedOut?.(result);
|
|
42
|
+
settings.onResult?.(result, call);
|
|
43
|
+
const plan = planApiToast(result, call.method, call.context, call.options.toast, settings.toast);
|
|
44
|
+
if (!plan) {
|
|
45
|
+
if (loadingId)
|
|
46
|
+
toast.dismiss(loadingId);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// The same failure twice (two lists on a page loading the same URL) shows one toast, not two.
|
|
50
|
+
showToast(plan, loadingId ?? (plan.tone === "danger" && call.url ? `nx-api:${call.method}:${call.url}` : undefined));
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const client = createApiClient(config);
|
|
55
|
+
/** Actions that lose something, asked about in red. */
|
|
56
|
+
const DESTRUCTIVE = new Set(["delete", "trash", "reject", "cancel"]);
|
|
57
|
+
/**
|
|
58
|
+
* Asks first, then sends. The question comes from the message builder ("Delete Room 204?", "This cannot be undone.",
|
|
59
|
+
* a Delete button, in red for actions that lose something). Resolves with the answer, or `null` when the user said no.
|
|
60
|
+
*/
|
|
61
|
+
async function confirmThenSend(target, { question, ...options } = {}) {
|
|
62
|
+
const { context } = apiCallContext(target, options);
|
|
63
|
+
const yes = await messageBox.confirm({
|
|
64
|
+
title: buildMessage("confirm", context),
|
|
65
|
+
message: buildMessage("confirmDetail", context) || undefined,
|
|
66
|
+
tone: typeof context.action === "string" && DESTRUCTIVE.has(context.action) ? "danger" : "question",
|
|
67
|
+
confirmLabel: buildMessage("label", context),
|
|
68
|
+
...question,
|
|
69
|
+
});
|
|
70
|
+
return yes ? client.send(target, options) : null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Calls APIs from the browser, with toasts.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* const ROOMS = MODULES.controller(NexusModule.Reservation, "Room", "room"); // MODULES: the app's defineApiModules(…)
|
|
77
|
+
*
|
|
78
|
+
* const rooms = await api.get<Room[]>(ROOMS.listing); // error toast if it fails
|
|
79
|
+
* if (rooms.ok) setRows(rooms.result);
|
|
80
|
+
*
|
|
81
|
+
* await api.put(ROOMS.update, values, { subject: `Room ${values.number}` }); // "Room 204 saved." or why not
|
|
82
|
+
* await api.delete(ROOMS.delete, { params: { id }, toast: { loading: true } });
|
|
83
|
+
* await api.confirm(ROOMS.delete, { params: { id }, subject: "Room 204" }); // "Delete Room 204?" first; null if not
|
|
84
|
+
* await api.post("/api/demo-rooms", values, { toast: false }); // a URL, no toasts
|
|
85
|
+
*/
|
|
86
|
+
export const api = Object.assign(client, { confirm: confirmThenSend });
|
|
87
|
+
/**
|
|
88
|
+
* A dropdown's `loadOptions` for an API that sends pages (`{ results, totalCount, filterCount }`) or a whole list.
|
|
89
|
+
* Failures show in the dropdown, with Retry, not as a toast.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* <Dropdown name="roomId" label="Room" valueKey="id" labelKey="number" loadOptions={apiOptionsLoader(ROOMS.pagination)} />
|
|
93
|
+
*/
|
|
94
|
+
export function apiOptionsLoader(target, { toItem, request, call } = {}) {
|
|
95
|
+
const method = call?.method ?? (isApiEndpoint(target) ? target.method : "GET");
|
|
96
|
+
return async (page) => {
|
|
97
|
+
const sent = request ? request(page) : { searchKeyword: page.search || undefined, skipCount: page.skip, maxCount: page.pageSize };
|
|
98
|
+
const answer = unwrapApiResult(await api.send(target, {
|
|
99
|
+
...call,
|
|
100
|
+
method,
|
|
101
|
+
...(method === "GET" ? { query: { ...call?.query, ...sent } } : { body: sent }),
|
|
102
|
+
signal: page.signal,
|
|
103
|
+
toast: false,
|
|
104
|
+
}));
|
|
105
|
+
const rows = Array.isArray(answer) ? answer : (answer?.results ?? []);
|
|
106
|
+
const items = toItem ? rows.map(toItem) : rows;
|
|
107
|
+
if (Array.isArray(answer))
|
|
108
|
+
return { items, hasMore: false, total: items.length };
|
|
109
|
+
return { items, total: answer?.filterCount, hasMore: page.skip + rows.length < (answer?.filterCount ?? 0) };
|
|
110
|
+
};
|
|
111
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type ApiCall } from "../Helpers/ApiClient.ts";
|
|
2
|
+
import type { ApiModuleValue, ApiResult } from "../Interfaces/ApiInterfaces.ts";
|
|
3
|
+
/** Options of a server call, on top of every call's options. */
|
|
4
|
+
export interface ServerApiOptions {
|
|
5
|
+
/** Keeps the answer in the Next.js data cache for this many seconds; `false` until a tag is revalidated. Default: not cached. */
|
|
6
|
+
revalidate?: number | false;
|
|
7
|
+
/** Cache tags, to refresh the answer with `revalidateTag`. Alone, they keep the answer until then. */
|
|
8
|
+
tags?: string[];
|
|
9
|
+
/** The bearer token for this call. Default: the `token` of `configureServerApi`; `null` sends none. */
|
|
10
|
+
token?: string | null;
|
|
11
|
+
}
|
|
12
|
+
/** How server calls behave. Where they go (each module's root) is the app's `ApiModules`. */
|
|
13
|
+
export interface ServerApiConfig {
|
|
14
|
+
/** The app's own address, for relative roots and URLs such as `/api/…`. Default: `URL_CURRENT` from the environment. */
|
|
15
|
+
origin?: string | (() => string | undefined | Promise<string | undefined>);
|
|
16
|
+
/** The user's token for every call, such as from the session cookie. */
|
|
17
|
+
token?: () => string | null | undefined | Promise<string | null | undefined>;
|
|
18
|
+
/** Headers on every call, such as the tenant or branch. */
|
|
19
|
+
headers?: (call: ApiCall<ServerApiOptions>) => Record<string, string> | undefined | Promise<Record<string, string> | undefined>;
|
|
20
|
+
/** Milliseconds to wait for an answer. Default 60,000. */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
/** After every answer. Default: logs network failures, timeouts, and 5xx answers with `console.error`. */
|
|
23
|
+
onResult?: (result: ApiResult, call: ApiCall<ServerApiOptions>) => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sets up `serverApi` and the proxy. Call it in a server module that the calls import; later calls change only the
|
|
27
|
+
* settings they name. Nothing is needed when the modules' roots are absolute and calls need no token.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* configureServerApi({ token: async () => (await cookies()).get("access_token")?.value });
|
|
31
|
+
*/
|
|
32
|
+
export declare function configureServerApi(config: ServerApiConfig): void;
|
|
33
|
+
/**
|
|
34
|
+
* A module's absolute root URL on the server, from the app's `ApiModules`. Throws "The Reservation API address is not
|
|
35
|
+
* set (API_RESERVATION)." when it is missing. `origin` resolves a relative root, such as the proxy's request origin.
|
|
36
|
+
*/
|
|
37
|
+
export declare function serverModuleRoot(module: ApiModuleValue, origin?: string): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Calls APIs from the server. Import it from `nexus-shared/server`.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* // A server component
|
|
43
|
+
* const rooms = await serverApi.get<Room[]>(ROOMS.listing, { revalidate: 60, tags: ["rooms"] });
|
|
44
|
+
* if (!rooms.ok) return <p>{rooms.message}</p>;
|
|
45
|
+
*
|
|
46
|
+
* // Or let the error boundary show it
|
|
47
|
+
* const room = unwrapApiResult(await serverApi.get<Room>(ROOMS.details, { params: { id } }));
|
|
48
|
+
*/
|
|
49
|
+
export declare const serverApi: import("../Shared.Index.ts").ApiClient<ServerApiOptions>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createApiClient } from "../Helpers/ApiClient.js";
|
|
2
|
+
import { describeEndpoint, getApiModules, readEnvironment } from "../Helpers/ApiModules.js";
|
|
3
|
+
import { joinUrl } from "../Helpers/ApiRoutes.js";
|
|
4
|
+
let settings = {};
|
|
5
|
+
/**
|
|
6
|
+
* Sets up `serverApi` and the proxy. Call it in a server module that the calls import; later calls change only the
|
|
7
|
+
* settings they name. Nothing is needed when the modules' roots are absolute and calls need no token.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* configureServerApi({ token: async () => (await cookies()).get("access_token")?.value });
|
|
11
|
+
*/
|
|
12
|
+
export function configureServerApi(config) {
|
|
13
|
+
settings = { ...settings, ...config };
|
|
14
|
+
}
|
|
15
|
+
async function appOrigin() {
|
|
16
|
+
const value = typeof settings.origin === "function" ? await settings.origin() : settings.origin;
|
|
17
|
+
return value || readEnvironment("URL_CURRENT");
|
|
18
|
+
}
|
|
19
|
+
async function absolute(url, fallbackOrigin) {
|
|
20
|
+
if (/^https?:\/\//i.test(url))
|
|
21
|
+
return url;
|
|
22
|
+
const origin = fallbackOrigin ?? (await appOrigin());
|
|
23
|
+
if (!origin)
|
|
24
|
+
throw new Error(`"${url}" is relative, and the app's address is not set (URL_CURRENT).`);
|
|
25
|
+
return new URL(url.startsWith("/") ? url : `/${url}`, origin).toString();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A module's absolute root URL on the server, from the app's `ApiModules`. Throws "The Reservation API address is not
|
|
29
|
+
* set (API_RESERVATION)." when it is missing. `origin` resolves a relative root, such as the proxy's request origin.
|
|
30
|
+
*/
|
|
31
|
+
export async function serverModuleRoot(module, origin) {
|
|
32
|
+
return absolute(await getApiModules().serverUrl(module), origin);
|
|
33
|
+
}
|
|
34
|
+
/** Where a call went, for logs: the module and path, never the query (it may hold what a user searched for). */
|
|
35
|
+
function describeCall(call) {
|
|
36
|
+
const where = call.url ? call.url.split("?")[0] : call.endpoint ? describeEndpoint(call.endpoint) : String(call.target);
|
|
37
|
+
return `${call.method} ${where}`;
|
|
38
|
+
}
|
|
39
|
+
function logFailure(result, call) {
|
|
40
|
+
if (result.ok || result.aborted)
|
|
41
|
+
return;
|
|
42
|
+
const status = result.status;
|
|
43
|
+
if (result.network || result.timeout || status === undefined || status >= 500)
|
|
44
|
+
console.error(`[serverApi] ${describeCall(call)}: ${status ?? ""} ${result.message ?? ""}`.replace(/\s+/g, " ").trim());
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Calls APIs from the server. Import it from `nexus-shared/server`.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // A server component
|
|
51
|
+
* const rooms = await serverApi.get<Room[]>(ROOMS.listing, { revalidate: 60, tags: ["rooms"] });
|
|
52
|
+
* if (!rooms.ok) return <p>{rooms.message}</p>;
|
|
53
|
+
*
|
|
54
|
+
* // Or let the error boundary show it
|
|
55
|
+
* const room = unwrapApiResult(await serverApi.get<Room>(ROOMS.details, { params: { id } }));
|
|
56
|
+
*/
|
|
57
|
+
export const serverApi = createApiClient({
|
|
58
|
+
resolveUrl: async (endpoint, path) => joinUrl(await serverModuleRoot(endpoint.module), path),
|
|
59
|
+
resolveTarget: url => absolute(url),
|
|
60
|
+
headers: call => settings.headers?.(call),
|
|
61
|
+
token: call => (call.options.token !== undefined ? call.options.token : settings.token?.()),
|
|
62
|
+
get timeout() {
|
|
63
|
+
return settings.timeout;
|
|
64
|
+
},
|
|
65
|
+
prepare(init, call) {
|
|
66
|
+
const { revalidate, tags } = call.options;
|
|
67
|
+
// Next.js reads `next` and `cache` on a server fetch; `no-store` with `revalidate` would cancel both.
|
|
68
|
+
if (revalidate !== undefined)
|
|
69
|
+
return { ...init, next: { revalidate, ...(tags && { tags }) } };
|
|
70
|
+
if (tags)
|
|
71
|
+
return { ...init, cache: "force-cache", next: { tags } };
|
|
72
|
+
return { ...init, cache: "no-store" };
|
|
73
|
+
},
|
|
74
|
+
onResult: (result, call) => (settings.onResult ?? logFailure)(result, call),
|
|
75
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ThemeMode } from "../Interfaces/ThemeInterfaces.ts";
|
|
2
|
+
export interface ThemeState {
|
|
3
|
+
/** The active theme id. */
|
|
4
|
+
theme: string;
|
|
5
|
+
/** The chosen mode, which may be `system`. */
|
|
6
|
+
mode: ThemeMode;
|
|
7
|
+
/** The mode actually shown. */
|
|
8
|
+
resolvedMode: "light" | "dark";
|
|
9
|
+
setTheme: (theme: string) => void;
|
|
10
|
+
setMode: (mode: ThemeMode) => void;
|
|
11
|
+
}
|
|
12
|
+
/** Switches the theme on this page and saves it for the next visit. */
|
|
13
|
+
export declare function setTheme(theme: string): void;
|
|
14
|
+
/** Switches light, dark, or system on this page and saves it for the next visit. */
|
|
15
|
+
export declare function setThemeMode(mode: ThemeMode): void;
|
|
16
|
+
/** The current theme and mode, and functions to change them. */
|
|
17
|
+
export declare function useTheme(): ThemeState;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useSyncExternalStore } from "react";
|
|
3
|
+
import { THEME_ID_PATTERN } from "../Helpers/ThemeHelpers.js";
|
|
4
|
+
import { DEFAULT_THEME, THEME_ATTRIBUTE, THEME_MODE_ATTRIBUTE, THEME_MODE_STORAGE_KEY, THEME_STORAGE_KEY, } from "../Interfaces/ThemeInterfaces.js";
|
|
5
|
+
const DARK_QUERY = "(prefers-color-scheme: dark)";
|
|
6
|
+
// Before hydration there is no document; the real values follow right after.
|
|
7
|
+
const SERVER_SNAPSHOT = `${DEFAULT_THEME} system light`;
|
|
8
|
+
// Colors switch at once, instead of every button and border running its own transition.
|
|
9
|
+
function withoutTransitions(change) {
|
|
10
|
+
const style = document.createElement("style");
|
|
11
|
+
style.textContent = "*,*::before,*::after{transition:none!important}";
|
|
12
|
+
document.head.appendChild(style);
|
|
13
|
+
change();
|
|
14
|
+
void window.getComputedStyle(document.body).color;
|
|
15
|
+
window.setTimeout(() => style.remove(), 1);
|
|
16
|
+
}
|
|
17
|
+
function save(key, value) {
|
|
18
|
+
try {
|
|
19
|
+
localStorage.setItem(key, value);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Storage blocked (private mode, for example): the choice lasts until the page reloads.
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function applyTheme(theme) {
|
|
26
|
+
withoutTransitions(() => document.documentElement.setAttribute(THEME_ATTRIBUTE, theme));
|
|
27
|
+
}
|
|
28
|
+
function applyMode(mode) {
|
|
29
|
+
const root = document.documentElement;
|
|
30
|
+
withoutTransitions(() => (mode === "system" ? root.removeAttribute(THEME_MODE_ATTRIBUTE) : root.setAttribute(THEME_MODE_ATTRIBUTE, mode)));
|
|
31
|
+
}
|
|
32
|
+
/** Switches the theme on this page and saves it for the next visit. */
|
|
33
|
+
export function setTheme(theme) {
|
|
34
|
+
if (!THEME_ID_PATTERN.test(theme))
|
|
35
|
+
return;
|
|
36
|
+
applyTheme(theme);
|
|
37
|
+
save(THEME_STORAGE_KEY, theme);
|
|
38
|
+
}
|
|
39
|
+
/** Switches light, dark, or system on this page and saves it for the next visit. */
|
|
40
|
+
export function setThemeMode(mode) {
|
|
41
|
+
applyMode(mode);
|
|
42
|
+
save(THEME_MODE_STORAGE_KEY, mode);
|
|
43
|
+
}
|
|
44
|
+
function readSnapshot() {
|
|
45
|
+
const root = document.documentElement;
|
|
46
|
+
const theme = root.getAttribute(THEME_ATTRIBUTE) || DEFAULT_THEME;
|
|
47
|
+
const attribute = root.getAttribute(THEME_MODE_ATTRIBUTE);
|
|
48
|
+
const mode = attribute === "light" || attribute === "dark" ? attribute : "system";
|
|
49
|
+
const resolved = mode === "system" ? (window.matchMedia(DARK_QUERY).matches ? "dark" : "light") : mode;
|
|
50
|
+
return `${theme} ${mode} ${resolved}`;
|
|
51
|
+
}
|
|
52
|
+
// The attributes on <html> are the source of truth, so every picker on the page stays in step,
|
|
53
|
+
// including changes made by the system setting or in another tab.
|
|
54
|
+
function subscribe(onChange) {
|
|
55
|
+
const observer = new MutationObserver(onChange);
|
|
56
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: [THEME_ATTRIBUTE, THEME_MODE_ATTRIBUTE] });
|
|
57
|
+
const media = window.matchMedia(DARK_QUERY);
|
|
58
|
+
media.addEventListener("change", onChange);
|
|
59
|
+
const onStorage = (event) => {
|
|
60
|
+
if (event.key === THEME_STORAGE_KEY && event.newValue && THEME_ID_PATTERN.test(event.newValue))
|
|
61
|
+
applyTheme(event.newValue);
|
|
62
|
+
if (event.key === THEME_MODE_STORAGE_KEY && (event.newValue === "light" || event.newValue === "dark" || event.newValue === "system")) {
|
|
63
|
+
applyMode(event.newValue);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
window.addEventListener("storage", onStorage);
|
|
67
|
+
return () => {
|
|
68
|
+
observer.disconnect();
|
|
69
|
+
media.removeEventListener("change", onChange);
|
|
70
|
+
window.removeEventListener("storage", onStorage);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** The current theme and mode, and functions to change them. */
|
|
74
|
+
export function useTheme() {
|
|
75
|
+
const [theme, mode, resolvedMode] = useSyncExternalStore(subscribe, readSnapshot, () => SERVER_SNAPSHOT).split(" ");
|
|
76
|
+
return {
|
|
77
|
+
theme: theme ?? DEFAULT_THEME,
|
|
78
|
+
mode: (mode ?? "system"),
|
|
79
|
+
resolvedMode: resolvedMode === "dark" ? "dark" : "light",
|
|
80
|
+
setTheme,
|
|
81
|
+
setMode: setThemeMode,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export * from "./Components/Documents/Button.tsx";
|
|
2
|
+
export * from "./Components/Inputs/Field.tsx";
|
|
3
|
+
export * from "./Components/Layouts/ThemeScript.tsx";
|
|
4
|
+
export * from "./Components/Viewers/MarkdownView.tsx";
|
|
5
|
+
export * from "./Components/Viewers/RichTextView.tsx";
|
|
6
|
+
export * from "./Helpers/ApiClient.ts";
|
|
7
|
+
export * from "./Helpers/ApiFormHelpers.ts";
|
|
8
|
+
export * from "./Helpers/ApiModules.ts";
|
|
9
|
+
export * from "./Helpers/ApiResponses.ts";
|
|
10
|
+
export * from "./Helpers/ApiRoutes.ts";
|
|
11
|
+
export * from "./Helpers/ApiToasts.ts";
|
|
12
|
+
export * from "./Helpers/ClassHelpers.ts";
|
|
13
|
+
export * from "./Helpers/CrudBackend.ts";
|
|
14
|
+
export * from "./Helpers/CrudHelpers.ts";
|
|
15
|
+
export * from "./Helpers/DateHelpers.ts";
|
|
16
|
+
export * from "./Helpers/DateTimeHelpers.ts";
|
|
17
|
+
export * from "./Helpers/DropdownHelpers.ts";
|
|
18
|
+
export * from "./Helpers/FormDrafts.ts";
|
|
19
|
+
export * from "./Helpers/FormStore.ts";
|
|
20
|
+
export * from "./Helpers/InputParamsHelpers.ts";
|
|
21
|
+
export * from "./Helpers/MarkdownEditing.ts";
|
|
22
|
+
export * from "./Helpers/MarkdownHelpers.ts";
|
|
23
|
+
export * from "./Helpers/MessageBuilder.ts";
|
|
24
|
+
export * from "./Helpers/NepaliCalendar.ts";
|
|
25
|
+
export * from "./Helpers/NumberHelpers.ts";
|
|
26
|
+
export * from "./Helpers/Permissions.ts";
|
|
27
|
+
export * from "./Helpers/RichTextHelpers.ts";
|
|
28
|
+
export * from "./Helpers/RowsStore.ts";
|
|
29
|
+
export * from "./Helpers/TableHelpers.ts";
|
|
30
|
+
export * from "./Helpers/TableStore.ts";
|
|
31
|
+
export * from "./Helpers/ThemeHelpers.ts";
|
|
32
|
+
export * from "./Helpers/TimeHelpers.ts";
|
|
33
|
+
export * from "./Helpers/TreeStore.ts";
|
|
34
|
+
export * from "./Helpers/ValidationHelpers.ts";
|
|
35
|
+
export * from "./Interfaces/ApiInterfaces.ts";
|
|
36
|
+
export * from "./Interfaces/CrudInterfaces.ts";
|
|
37
|
+
export * from "./Interfaces/DateInterfaces.ts";
|
|
38
|
+
export * from "./Interfaces/FormInterfaces.ts";
|
|
39
|
+
export * from "./Interfaces/InputInterfaces.ts";
|
|
40
|
+
export * from "./Interfaces/MessageInterfaces.ts";
|
|
41
|
+
export * from "./Interfaces/TableInterfaces.ts";
|
|
42
|
+
export * from "./Interfaces/ThemeInterfaces.ts";
|
|
43
|
+
export * from "./Interfaces/TypeInterfaces.ts";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Works everywhere: server components, client components, and plain TypeScript.
|
|
2
|
+
// Components
|
|
3
|
+
export * from "./Components/Documents/Button.js";
|
|
4
|
+
export * from "./Components/Inputs/Field.js";
|
|
5
|
+
export * from "./Components/Layouts/ThemeScript.js";
|
|
6
|
+
export * from "./Components/Viewers/MarkdownView.js";
|
|
7
|
+
export * from "./Components/Viewers/RichTextView.js";
|
|
8
|
+
// Helpers
|
|
9
|
+
export * from "./Helpers/ApiClient.js";
|
|
10
|
+
export * from "./Helpers/ApiFormHelpers.js";
|
|
11
|
+
export * from "./Helpers/ApiModules.js";
|
|
12
|
+
export * from "./Helpers/ApiResponses.js";
|
|
13
|
+
export * from "./Helpers/ApiRoutes.js";
|
|
14
|
+
export * from "./Helpers/ApiToasts.js";
|
|
15
|
+
export * from "./Helpers/ClassHelpers.js";
|
|
16
|
+
export * from "./Helpers/CrudBackend.js";
|
|
17
|
+
export * from "./Helpers/CrudHelpers.js";
|
|
18
|
+
export * from "./Helpers/DateHelpers.js";
|
|
19
|
+
export * from "./Helpers/DateTimeHelpers.js";
|
|
20
|
+
export * from "./Helpers/DropdownHelpers.js";
|
|
21
|
+
export * from "./Helpers/FormDrafts.js";
|
|
22
|
+
export * from "./Helpers/FormStore.js";
|
|
23
|
+
export * from "./Helpers/InputParamsHelpers.js";
|
|
24
|
+
export * from "./Helpers/MarkdownEditing.js";
|
|
25
|
+
export * from "./Helpers/MarkdownHelpers.js";
|
|
26
|
+
export * from "./Helpers/MessageBuilder.js";
|
|
27
|
+
export * from "./Helpers/NepaliCalendar.js";
|
|
28
|
+
export * from "./Helpers/NumberHelpers.js";
|
|
29
|
+
export * from "./Helpers/Permissions.js";
|
|
30
|
+
export * from "./Helpers/RichTextHelpers.js";
|
|
31
|
+
export * from "./Helpers/RowsStore.js";
|
|
32
|
+
export * from "./Helpers/TableHelpers.js";
|
|
33
|
+
export * from "./Helpers/TableStore.js";
|
|
34
|
+
export * from "./Helpers/ThemeHelpers.js";
|
|
35
|
+
export * from "./Helpers/TimeHelpers.js";
|
|
36
|
+
export * from "./Helpers/TreeStore.js";
|
|
37
|
+
export * from "./Helpers/ValidationHelpers.js";
|
|
38
|
+
// Interfaces
|
|
39
|
+
export * from "./Interfaces/ApiInterfaces.js";
|
|
40
|
+
export * from "./Interfaces/CrudInterfaces.js";
|
|
41
|
+
export * from "./Interfaces/DateInterfaces.js";
|
|
42
|
+
export * from "./Interfaces/FormInterfaces.js";
|
|
43
|
+
export * from "./Interfaces/InputInterfaces.js";
|
|
44
|
+
export * from "./Interfaces/MessageInterfaces.js";
|
|
45
|
+
export * from "./Interfaces/TableInterfaces.js";
|
|
46
|
+
export * from "./Interfaces/ThemeInterfaces.js";
|
|
47
|
+
export * from "./Interfaces/TypeInterfaces.js";
|
package/package.json
CHANGED
|
@@ -1,33 +1,82 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "nexus-shared",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Nexus
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "nexus-shared",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "The Nexus component library for React and Next.js: params-driven inputs and forms, a data table with a CRUD on top, popups and toasts, an API layer with permissions, Markdown and rich text editors, and 7 themes in light and dark.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"nextjs",
|
|
8
|
+
"components",
|
|
9
|
+
"ui",
|
|
10
|
+
"forms",
|
|
11
|
+
"datatable",
|
|
12
|
+
"crud",
|
|
13
|
+
"inputs",
|
|
14
|
+
"design-system",
|
|
15
|
+
"typescript",
|
|
16
|
+
"nepali-calendar",
|
|
17
|
+
"nexus"
|
|
18
|
+
],
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"author": "Bijay Adhikari",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"sideEffects": [
|
|
23
|
+
"*.css"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/Shared.Index.d.ts",
|
|
28
|
+
"default": "./dist/Shared.Index.js"
|
|
29
|
+
},
|
|
30
|
+
"./client": {
|
|
31
|
+
"types": "./dist/Client.Index.d.ts",
|
|
32
|
+
"default": "./dist/Client.Index.js"
|
|
33
|
+
},
|
|
34
|
+
"./server": {
|
|
35
|
+
"types": "./dist/Server.Index.d.ts",
|
|
36
|
+
"default": "./dist/Server.Index.js"
|
|
37
|
+
},
|
|
38
|
+
"./styles.css": "./src/Styles/Nexus.Index.css",
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"src/Styles"
|
|
44
|
+
],
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc -p tsconfig.build.json",
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
48
|
+
"test": "node scripts/test-all.mjs",
|
|
49
|
+
"check:themes": "node scripts/check-themes.mjs",
|
|
50
|
+
"test:api": "node scripts/test-api.mts",
|
|
51
|
+
"test:dates": "node scripts/test-date-helpers.mts",
|
|
52
|
+
"test:datetimes": "node scripts/test-datetime-helpers.mts",
|
|
53
|
+
"test:drag": "node scripts/test-drag-helpers.mts",
|
|
54
|
+
"test:dropdown": "node scripts/test-dropdown-helpers.mts",
|
|
55
|
+
"test:forms": "node scripts/test-form-store.mts",
|
|
56
|
+
"test:markdown": "node scripts/test-markdown.mts",
|
|
57
|
+
"test:numbers": "node scripts/test-number-helpers.mts",
|
|
58
|
+
"test:popups": "node scripts/test-popup-rules.mts",
|
|
59
|
+
"test:richtext": "node scripts/test-richtext.mts",
|
|
60
|
+
"test:rows": "node scripts/test-rows-store.mts",
|
|
61
|
+
"test:table": "node scripts/test-table.mts",
|
|
62
|
+
"test:times": "node scripts/test-time-helpers.mts",
|
|
63
|
+
"test:tree": "node scripts/test-tree-store.mts",
|
|
64
|
+
"test:types": "tsc -p scripts/type-checks/tsconfig.json"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"nexus-icons": "^1.0.0"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"react": ">=19",
|
|
71
|
+
"react-dom": ">=19"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@types/react": "19.3.0"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=20.9"
|
|
78
|
+
},
|
|
79
|
+
"publishConfig": {
|
|
80
|
+
"access": "public"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/* Page defaults and small shared utilities. */
|
|
2
|
+
@layer nexus.base {
|
|
3
|
+
*,
|
|
4
|
+
*::before,
|
|
5
|
+
*::after {
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
body {
|
|
10
|
+
margin: 0;
|
|
11
|
+
background: var(--nx-bg);
|
|
12
|
+
color: var(--nx-text);
|
|
13
|
+
font: var(--nx-text-md) / var(--nx-leading) var(--nx-font);
|
|
14
|
+
-webkit-font-smoothing: antialiased;
|
|
15
|
+
text-rendering: optimizeLegibility;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
button,
|
|
19
|
+
input,
|
|
20
|
+
select,
|
|
21
|
+
textarea {
|
|
22
|
+
font: inherit;
|
|
23
|
+
color: inherit;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* Nepali text takes a font that has Devanagari glyphs, digits included. */
|
|
27
|
+
:lang(ne) {
|
|
28
|
+
font-family: var(--nx-font-devanagari);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:focus-visible {
|
|
32
|
+
outline: 2px solid var(--nx-primary);
|
|
33
|
+
outline-offset: 2px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Hidden on screen but still read by screen readers and reachable with the keyboard. */
|
|
37
|
+
.nx-visually-hidden {
|
|
38
|
+
position: absolute;
|
|
39
|
+
width: 1px;
|
|
40
|
+
height: 1px;
|
|
41
|
+
margin: -1px;
|
|
42
|
+
padding: 0;
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
clip-path: inset(50%);
|
|
45
|
+
white-space: nowrap;
|
|
46
|
+
border: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Icons sit on the text baseline and never shrink inside flex rows. */
|
|
50
|
+
.nx-icon {
|
|
51
|
+
flex-shrink: 0;
|
|
52
|
+
vertical-align: -0.125em;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.nx-spin {
|
|
56
|
+
animation: nx-spin 0.8s linear infinite;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@keyframes nx-spin {
|
|
60
|
+
to {
|
|
61
|
+
transform: rotate(360deg);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@media (prefers-reduced-motion: reduce) {
|
|
66
|
+
.nx-spin {
|
|
67
|
+
animation-duration: 2.4s;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|