@nexterajs/ui 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +64 -0
- package/fesm2022/nexterajs-ui-animations.mjs +184 -0
- package/fesm2022/nexterajs-ui-animations.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-core.mjs +326 -0
- package/fesm2022/nexterajs-ui-core.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-dropdowns.mjs +953 -0
- package/fesm2022/nexterajs-ui-dropdowns.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-excel.mjs +779 -0
- package/fesm2022/nexterajs-ui-excel.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-file-uploader.mjs +125 -0
- package/fesm2022/nexterajs-ui-file-uploader.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-forms.mjs +1113 -0
- package/fesm2022/nexterajs-ui-forms.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-grid.mjs +4145 -0
- package/fesm2022/nexterajs-ui-grid.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-intl.mjs +377 -0
- package/fesm2022/nexterajs-ui-intl.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-pivot.mjs +4739 -0
- package/fesm2022/nexterajs-ui-pivot.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-styling.mjs +59 -0
- package/fesm2022/nexterajs-ui-styling.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-tree-view.mjs +202 -0
- package/fesm2022/nexterajs-ui-tree-view.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-validation.mjs +269 -0
- package/fesm2022/nexterajs-ui-validation.mjs.map +1 -0
- package/fesm2022/nexterajs-ui.mjs +23 -0
- package/fesm2022/nexterajs-ui.mjs.map +1 -0
- package/package.json +100 -0
- package/styles/_button-directives.scss +39 -0
- package/styles/_dropdown.scss +113 -0
- package/styles/_editor.scss +146 -0
- package/styles/_mixins.scss +2 -0
- package/styles/_tokens.scss +77 -0
- package/styles/_widget.scss +58 -0
- package/styles/index.scss +83 -0
- package/types/nexterajs-ui-animations.d.ts +22 -0
- package/types/nexterajs-ui-core.d.ts +328 -0
- package/types/nexterajs-ui-dropdowns.d.ts +334 -0
- package/types/nexterajs-ui-excel.d.ts +159 -0
- package/types/nexterajs-ui-file-uploader.d.ts +47 -0
- package/types/nexterajs-ui-forms.d.ts +296 -0
- package/types/nexterajs-ui-grid.d.ts +1485 -0
- package/types/nexterajs-ui-intl.d.ts +125 -0
- package/types/nexterajs-ui-pivot.d.ts +1470 -0
- package/types/nexterajs-ui-styling.d.ts +40 -0
- package/types/nexterajs-ui-tree-view.d.ts +69 -0
- package/types/nexterajs-ui-validation.d.ts +102 -0
- package/types/nexterajs-ui.d.ts +12 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { OverlayRef } from '@angular/cdk/overlay';
|
|
2
|
+
import { Subscription } from 'rxjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Marker class carried by every nxe surface — component hosts and CDK overlay panes alike.
|
|
6
|
+
*
|
|
7
|
+
* It is the nxe counterpart of DevExtreme's `.dx-widget` base and is what gives a surface its
|
|
8
|
+
* font family/size/weight/line-height (see styling/_widget.scss).
|
|
9
|
+
*
|
|
10
|
+
* It matters most on overlays: a CDK pane is appended to `<body>`, so a portaled dropdown
|
|
11
|
+
* inherits the page, not the editor that opened it. Without this class a panel silently falls
|
|
12
|
+
* back to the host app's body font — which is how the select-box list ended up rendering 14px in
|
|
13
|
+
* an app whose every other text surface is 12.24px.
|
|
14
|
+
*/
|
|
15
|
+
declare const NXE_WIDGET_CLASS = "nxe-widget";
|
|
16
|
+
/** Set on the pane while the overlay is rendered ABOVE its origin instead of below. */
|
|
17
|
+
declare const NXE_PANE_FLIPPED_CLASS = "nxe-pane-flipped";
|
|
18
|
+
/**
|
|
19
|
+
* Build the `panelClass` for a library-created overlay, guaranteeing the widget contract.
|
|
20
|
+
*
|
|
21
|
+
* panelClass: nxePane('nxe-select-pane')
|
|
22
|
+
* panelClass: nxePane('nxe-dropdownbox-pane', ...wrapperClass.split(/\s+/))
|
|
23
|
+
*
|
|
24
|
+
* Blank/undefined entries are dropped so callers can splat user-supplied class strings directly.
|
|
25
|
+
*/
|
|
26
|
+
declare function nxePane(...extra: (string | null | undefined)[]): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Track whether a connected overlay has flipped above its origin, exposing it as
|
|
29
|
+
* {@link NXE_PANE_FLIPPED_CLASS} on the pane.
|
|
30
|
+
*
|
|
31
|
+
* DevExtreme drew dropdowns flush against the editor — no border on the shared edge — and moved
|
|
32
|
+
* that seam to the other side when the popup flipped up
|
|
33
|
+
* (`.dx-overlay-content.dx-dropdowneditor-overlay-flipped { border-top-width:1px; border-bottom-width:0 }`).
|
|
34
|
+
* CDK does not emit any equivalent hook, so panels need this to reproduce it.
|
|
35
|
+
*
|
|
36
|
+
* Returns the subscription; callers dispose it with the overlay.
|
|
37
|
+
*/
|
|
38
|
+
declare function trackPaneFlip(overlayRef: OverlayRef): Subscription | undefined;
|
|
39
|
+
|
|
40
|
+
export { NXE_PANE_FLIPPED_CLASS, NXE_WIDGET_CLASS, nxePane, trackPaneFlip };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/** A node in the assembled tree (children built from the flat `parentIdExpr` list). */
|
|
4
|
+
interface NxeTreeNode {
|
|
5
|
+
key: unknown;
|
|
6
|
+
text: string;
|
|
7
|
+
/** The original data row (consumers read `itemData` off the click event = this). */
|
|
8
|
+
data: Record<string, unknown>;
|
|
9
|
+
children: NxeTreeNode[];
|
|
10
|
+
hasChildren: boolean;
|
|
11
|
+
level: number;
|
|
12
|
+
}
|
|
13
|
+
/** DevExtreme-shaped `onItemClick` payload (consumers read `event.itemData.<field>`). */
|
|
14
|
+
interface NxeTreeItemClickEvent {
|
|
15
|
+
itemData: Record<string, unknown>;
|
|
16
|
+
node: NxeTreeNode;
|
|
17
|
+
event: Event;
|
|
18
|
+
component: NxeTreeViewComponent;
|
|
19
|
+
element: HTMLElement;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* `nxe-tree-view` — drop-in replacement for DevExtreme `dx-tree-view`.
|
|
23
|
+
*
|
|
24
|
+
* The single usage (settings sidebar) feeds a FLAT list (`dataStructure="plain"`) and lets the
|
|
25
|
+
* widget assemble the hierarchy via `keyExpr`/`parentIdExpr`/`rootValue`; so this builds the tree
|
|
26
|
+
* internally. Single selection, `selectByClick`, optional search box, and a programmatic
|
|
27
|
+
* `expandAll()` (called via `@ViewChild(NxeTreeViewComponent).instance.expandAll()` after async
|
|
28
|
+
* load). `(onItemClick)` emits `{ itemData: <full original row>, ... }` so the navigation handler
|
|
29
|
+
* keeps reading `event.itemData.url/urlParams/objectName`.
|
|
30
|
+
*/
|
|
31
|
+
declare class NxeTreeViewComponent {
|
|
32
|
+
readonly dataSource: _angular_core.InputSignal<readonly unknown[]>;
|
|
33
|
+
/** Accepted for parity; this component always assembles a tree from the flat list. */
|
|
34
|
+
readonly dataStructure: _angular_core.InputSignal<"plain" | "tree">;
|
|
35
|
+
readonly keyExpr: _angular_core.InputSignal<string>;
|
|
36
|
+
readonly displayExpr: _angular_core.InputSignal<string>;
|
|
37
|
+
readonly parentIdExpr: _angular_core.InputSignal<string>;
|
|
38
|
+
readonly rootValue: _angular_core.InputSignal<unknown>;
|
|
39
|
+
/** Accepted for parity (no-op: rows carry no `expanded` field; use `expandAll()`). */
|
|
40
|
+
readonly expandedExpr: _angular_core.InputSignal<string>;
|
|
41
|
+
readonly selectionMode: _angular_core.InputSignal<"single" | "multiple" | "none">;
|
|
42
|
+
readonly selectByClick: _angular_core.InputSignal<boolean>;
|
|
43
|
+
readonly searchEnabled: _angular_core.InputSignal<boolean>;
|
|
44
|
+
readonly searchMode: _angular_core.InputSignal<"contains" | "startswith" | "equals">;
|
|
45
|
+
/** Accepted for parity (native scrolling is the default here anyway). */
|
|
46
|
+
readonly useNativeScrolling: _angular_core.InputSignal<boolean>;
|
|
47
|
+
readonly width: _angular_core.InputSignal<string | number>;
|
|
48
|
+
readonly onItemClick: _angular_core.OutputEmitterRef<NxeTreeItemClickEvent>;
|
|
49
|
+
readonly expanded: _angular_core.WritableSignal<ReadonlySet<unknown>>;
|
|
50
|
+
readonly selectedKey: _angular_core.WritableSignal<unknown>;
|
|
51
|
+
readonly searchText: _angular_core.WritableSignal<string>;
|
|
52
|
+
/** DevExtreme `.instance` facade — `expandAll()` is the only method used. */
|
|
53
|
+
get instance(): this;
|
|
54
|
+
protected readonly widthStyle: _angular_core.Signal<string>;
|
|
55
|
+
private readonly tree;
|
|
56
|
+
/** Flattened list of currently-visible nodes (respects expand state + search). */
|
|
57
|
+
protected readonly visibleNodes: _angular_core.Signal<NxeTreeNode[]>;
|
|
58
|
+
expandAll(): void;
|
|
59
|
+
collapseAll(): void;
|
|
60
|
+
protected isExpanded(node: NxeTreeNode): boolean;
|
|
61
|
+
protected toggle(node: NxeTreeNode, event: Event): void;
|
|
62
|
+
protected onNodeClick(node: NxeTreeNode, event: Event): void;
|
|
63
|
+
protected onSearch(event: Event): void;
|
|
64
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeTreeViewComponent, never>;
|
|
65
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeTreeViewComponent, "nxe-tree-view", never, { "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "dataStructure": { "alias": "dataStructure"; "required": false; "isSignal": true; }; "keyExpr": { "alias": "keyExpr"; "required": false; "isSignal": true; }; "displayExpr": { "alias": "displayExpr"; "required": false; "isSignal": true; }; "parentIdExpr": { "alias": "parentIdExpr"; "required": false; "isSignal": true; }; "rootValue": { "alias": "rootValue"; "required": false; "isSignal": true; }; "expandedExpr": { "alias": "expandedExpr"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "selectByClick": { "alias": "selectByClick"; "required": false; "isSignal": true; }; "searchEnabled": { "alias": "searchEnabled"; "required": false; "isSignal": true; }; "searchMode": { "alias": "searchMode"; "required": false; "isSignal": true; }; "useNativeScrolling": { "alias": "useNativeScrolling"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; }, { "onItemClick": "onItemClick"; }, never, never, true, never>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { NxeTreeViewComponent };
|
|
69
|
+
export type { NxeTreeItemClickEvent, NxeTreeNode };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { NxeValidationResult } from '@nexterajs/ui/core';
|
|
3
|
+
import { ValidatorFn } from '@angular/forms';
|
|
4
|
+
|
|
5
|
+
/** DevExtreme validation rule type (the codebase uses `required`, `compare`, and `range`). */
|
|
6
|
+
type NxeValidationRuleType = 'required' | 'compare' | 'custom' | 'pattern' | 'email' | 'range';
|
|
7
|
+
/**
|
|
8
|
+
* The message shown when a rule fails and the caller gave none.
|
|
9
|
+
*
|
|
10
|
+
* These are DevExtreme's own defaults, verbatim from its `validation-*` message keys. Without
|
|
11
|
+
* them a rule with no `message` blocks its group and displays nothing at all, because every
|
|
12
|
+
* editor renders its error bubble under `@if (validationError())` — falsy for the empty string.
|
|
13
|
+
*/
|
|
14
|
+
declare const NXE_DEFAULT_VALIDATION_MESSAGES: Readonly<Record<NxeValidationRuleType, string>>;
|
|
15
|
+
/** Payload passed to a `custom` rule's `validationCallback` (mirrors DevExtreme). */
|
|
16
|
+
interface NxeCustomRuleData {
|
|
17
|
+
value: unknown;
|
|
18
|
+
rule: NxeValidationRuleComponent;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* `nxe-validation-rule` — drop-in for DevExtreme `dxi-validation-rule`.
|
|
22
|
+
*
|
|
23
|
+
* A no-template configuration child of `nxe-validator`. The codebase uses the universal element
|
|
24
|
+
* with a `type` attribute (overwhelmingly `type="required"`), so a single component with a
|
|
25
|
+
* `type` input covers 100% of usage.
|
|
26
|
+
*/
|
|
27
|
+
declare class NxeValidationRuleComponent {
|
|
28
|
+
readonly type: _angular_core.InputSignal<NxeValidationRuleType>;
|
|
29
|
+
readonly message: _angular_core.InputSignal<string>;
|
|
30
|
+
/** `compare` rule: returns the value to compare against. Mirrors `comparisonTarget`. */
|
|
31
|
+
readonly comparisonTarget: _angular_core.InputSignal<() => unknown>;
|
|
32
|
+
/** `compare` rule comparison operator (default `==`). */
|
|
33
|
+
readonly comparisonType: _angular_core.InputSignal<"==" | "===" | "!=" | "!==" | ">" | "<" | ">=" | "<=">;
|
|
34
|
+
/** `custom` rule: returns true when valid. Mirrors `validationCallback`. */
|
|
35
|
+
readonly validationCallback: _angular_core.InputSignal<(data: NxeCustomRuleData) => boolean>;
|
|
36
|
+
/** `pattern` rule. */
|
|
37
|
+
readonly pattern: _angular_core.InputSignal<string | RegExp>;
|
|
38
|
+
/** `range` rule bounds (DevExtreme RangeRule: empty values pass, bounds are inclusive). */
|
|
39
|
+
readonly min: _angular_core.InputSignal<number>;
|
|
40
|
+
readonly max: _angular_core.InputSignal<number>;
|
|
41
|
+
/**
|
|
42
|
+
* The message to show when this rule fails: the caller's, or DevExtreme's default for the
|
|
43
|
+
* rule type. Whitespace counts as absent — a message of spaces is still an empty bubble.
|
|
44
|
+
*/
|
|
45
|
+
readonly resolvedMessage: _angular_core.Signal<string>;
|
|
46
|
+
/** Whether `value` satisfies this rule. */
|
|
47
|
+
evaluate(value: unknown): boolean;
|
|
48
|
+
/** DevExtreme RequiredRule semantics: null/undefined/''/false are "not specified". */
|
|
49
|
+
private isEmpty;
|
|
50
|
+
private compare;
|
|
51
|
+
private inRange;
|
|
52
|
+
private matchesPattern;
|
|
53
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeValidationRuleComponent, never>;
|
|
54
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeValidationRuleComponent, "nxe-validation-rule", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "comparisonTarget": { "alias": "comparisonTarget"; "required": false; "isSignal": true; }; "comparisonType": { "alias": "comparisonType"; "required": false; "isSignal": true; }; "validationCallback": { "alias": "validationCallback"; "required": false; "isSignal": true; }; "pattern": { "alias": "pattern"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `nxe-validator` — drop-in for DevExtreme `dx-validator`.
|
|
59
|
+
*
|
|
60
|
+
* Placed inside an editor (`<nxe-text-box><nxe-validator><nxe-validation-rule .../></nxe-validator></nxe-text-box>`),
|
|
61
|
+
* it adapts the editor via {@link NXE_VALIDATION_TARGET}, collects its `nxe-validation-rule`
|
|
62
|
+
* children, and registers into the {@link NxeValidationGroupRegistry} under the editor's
|
|
63
|
+
* `validationGroup`. Validation is on-demand (matching DevExtreme: not auto-run on change) —
|
|
64
|
+
* `validate()` is invoked by `nxe-button[validationGroup]` (group-level) or directly.
|
|
65
|
+
*/
|
|
66
|
+
declare class NxeValidatorComponent {
|
|
67
|
+
private readonly target;
|
|
68
|
+
private readonly registry;
|
|
69
|
+
readonly rules: _angular_core.Signal<readonly NxeValidationRuleComponent[]>;
|
|
70
|
+
/** Explicit group; otherwise inherited from the wrapped editor's `validationGroup`. */
|
|
71
|
+
readonly validationGroupInput: _angular_core.InputSignal<string>;
|
|
72
|
+
private readonly group;
|
|
73
|
+
/** Last validation outcome (false once a rule has failed, until re-validated). */
|
|
74
|
+
readonly isValid: _angular_core.WritableSignal<boolean>;
|
|
75
|
+
/** DevExtreme parity: existing code calls `validator.instance.validate()` via `@ViewChild`. */
|
|
76
|
+
get instance(): NxeValidatorComponent;
|
|
77
|
+
private readonly member;
|
|
78
|
+
constructor();
|
|
79
|
+
/** Run all rules against the editor's current value; pushes the first failing message. */
|
|
80
|
+
validate(): NxeValidationResult;
|
|
81
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<NxeValidatorComponent, never>;
|
|
82
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<NxeValidatorComponent, "nxe-validator", never, { "validationGroupInput": { "alias": "validationGroup"; "required": false; "isSignal": true; }; }, {}, ["rules"], ["*"], true, never>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare class NxeValidators {
|
|
86
|
+
/**
|
|
87
|
+
* Check for empty (optional fields) values
|
|
88
|
+
*
|
|
89
|
+
* @param value
|
|
90
|
+
*/
|
|
91
|
+
static isEmptyInputValue(value: any): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Must match validator
|
|
94
|
+
*
|
|
95
|
+
* @param controlPath A dot-delimited string values that define the path to the control.
|
|
96
|
+
* @param matchingControlPath A dot-delimited string values that define the path to the matching control.
|
|
97
|
+
*/
|
|
98
|
+
static mustMatch(controlPath: string, matchingControlPath: string): ValidatorFn;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { NXE_DEFAULT_VALIDATION_MESSAGES, NxeValidationRuleComponent, NxeValidatorComponent, NxeValidators };
|
|
102
|
+
export type { NxeCustomRuleData, NxeValidationRuleType };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from '@nexterajs/ui/animations';
|
|
2
|
+
export * from '@nexterajs/ui/core';
|
|
3
|
+
export * from '@nexterajs/ui/dropdowns';
|
|
4
|
+
export * from '@nexterajs/ui/excel';
|
|
5
|
+
export * from '@nexterajs/ui/file-uploader';
|
|
6
|
+
export * from '@nexterajs/ui/forms';
|
|
7
|
+
export * from '@nexterajs/ui/grid';
|
|
8
|
+
export * from '@nexterajs/ui/intl';
|
|
9
|
+
export * from '@nexterajs/ui/pivot';
|
|
10
|
+
export * from '@nexterajs/ui/styling';
|
|
11
|
+
export * from '@nexterajs/ui/tree-view';
|
|
12
|
+
export * from '@nexterajs/ui/validation';
|