@nanahoshi/mona-ui 0.24.0 → 0.24.2
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/README.md +2 -0
- package/fesm2022/nanahoshi-mona-ui-button-group.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-button.mjs +122 -60
- package/fesm2022/nanahoshi-mona-ui-calendar.mjs +1 -2
- package/fesm2022/nanahoshi-mona-ui-chip.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-common.mjs +265 -159
- package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-dialog.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-dropdown-button.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-editor.mjs +13 -13
- package/fesm2022/nanahoshi-mona-ui-filter.mjs +1 -1
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-row.component-CnPhVIr4.mjs → nanahoshi-mona-ui-grid-grid-footer-row.component-x_euoNnS.mjs} +2 -2
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-list.component-DxY6bfTX.mjs → nanahoshi-mona-ui-grid-grid-list.component-C1_6vq77.mjs} +4 -4
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-row.component-CaO5Lae6.mjs → nanahoshi-mona-ui-grid-grid-row.component-BhukVWIy.mjs} +3 -3
- package/fesm2022/{nanahoshi-mona-ui-grid-grid-virtual-list.component-jNYtqg5B.mjs → nanahoshi-mona-ui-grid-grid-virtual-list.component-XQKOPPVs.mjs} +4 -4
- package/fesm2022/{nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-9FtfCutf.mjs → nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-Iw-wvKGl.mjs} +13 -12
- package/fesm2022/nanahoshi-mona-ui-grid.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-list-box.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-notification.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +2 -2
- package/fesm2022/nanahoshi-mona-ui-pager.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-sheet.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-split-button.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-splitter.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-tabs.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-text-box.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +1 -1
- package/fesm2022/nanahoshi-mona-ui-window.mjs +1 -1
- package/package.json +1 -1
- package/types/nanahoshi-mona-ui-button.d.ts +44 -20
- package/types/nanahoshi-mona-ui-common.d.ts +116 -73
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { Signal } from '@angular/core';
|
|
2
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
3
4
|
import { VariantInputs } from '@nanahoshi/mona-ui/internal';
|
|
4
5
|
import { VariantProps } from 'class-variance-authority';
|
|
5
6
|
import { Subject } from 'rxjs';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Values accepted by the `aria-haspopup` input of `ButtonDirective`. `"false"` (the default) omits the attribute.
|
|
10
|
+
*/
|
|
11
|
+
type ButtonAriaHasPopup = "dialog" | "false" | "grid" | "listbox" | "menu" | "tree" | "true";
|
|
12
|
+
|
|
7
13
|
declare const buttonThemeVariants: (props?: ({
|
|
8
14
|
disabled?: boolean | null | undefined;
|
|
9
15
|
iconOnly?: boolean | null | undefined;
|
|
@@ -18,41 +24,44 @@ type ButtonVariantsInput = VariantInputs<ButtonVariantProps>;
|
|
|
18
24
|
|
|
19
25
|
declare class ButtonDirective implements ButtonVariantsInput {
|
|
20
26
|
#private;
|
|
21
|
-
protected readonly
|
|
27
|
+
protected readonly baseClass: _angular_core.Signal<string>;
|
|
22
28
|
protected readonly effectiveDisabled: _angular_core.Signal<boolean>;
|
|
23
29
|
protected readonly effectiveLook: _angular_core.Signal<"default" | "primary" | "success" | "error" | "warning" | "info" | "outline" | "secondary" | "ghost" | "link" | "clear" | null | undefined>;
|
|
24
30
|
protected readonly effectiveRounded: _angular_core.Signal<"full" | "large" | "medium" | "none" | "small" | null | undefined>;
|
|
25
31
|
protected readonly effectiveSize: _angular_core.Signal<"large" | "medium" | "small" | null | undefined>;
|
|
26
32
|
protected readonly effectiveToggleable: _angular_core.Signal<boolean>;
|
|
27
|
-
protected readonly isInButtonGroup: _angular_core.Signal<boolean>;
|
|
28
|
-
protected readonly baseClass: _angular_core.Signal<string>;
|
|
29
33
|
protected readonly loadingSize: _angular_core.Signal<12 | 16 | 14>;
|
|
30
34
|
/**
|
|
31
35
|
* @description Value forwarded to the `aria-haspopup` attribute. Set when this button triggers a popup, menu,
|
|
32
36
|
* listbox, tree, grid, or dialog. Omit or leave as `"false"` for plain action buttons.
|
|
33
37
|
* @default "false"
|
|
34
38
|
*/
|
|
35
|
-
readonly ariaHasPopup: _angular_core.InputSignal<
|
|
39
|
+
readonly ariaHasPopup: _angular_core.InputSignal<ButtonAriaHasPopup>;
|
|
36
40
|
/**
|
|
37
41
|
* @description Renders the component with reduced visual emphasis and removes pointer interaction.
|
|
38
|
-
*
|
|
42
|
+
* Accepts the bare attribute form (`<button monaButton disabled>`).
|
|
43
|
+
* When inside a `ButtonGroup`, the button is disabled when either it or the group is disabled.
|
|
39
44
|
* @default false
|
|
40
45
|
*/
|
|
41
|
-
readonly disabled: _angular_core.
|
|
46
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
42
47
|
/**
|
|
43
48
|
* @description Removes horizontal padding and fixes a square aspect ratio sized to match `size`.
|
|
44
|
-
* Provide `aria-label` on the host when using icon-only buttons
|
|
49
|
+
* Provide `aria-label` on the host when using icon-only buttons; in dev mode, an icon-only button without an
|
|
50
|
+
* accessible name logs a warning.
|
|
45
51
|
* @default false
|
|
46
52
|
*/
|
|
47
|
-
readonly iconOnly: _angular_core.
|
|
53
|
+
readonly iconOnly: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
48
54
|
/**
|
|
49
55
|
* @description Displays a loading indicator and prevents interaction while an operation is in progress.
|
|
50
|
-
* Sets `aria-busy="true"` on the host.
|
|
56
|
+
* Sets `aria-busy="true"` and `aria-disabled="true"` on the host. The button stays focusable, so keyboard focus
|
|
57
|
+
* isn't lost when loading starts, and clicks (including form submission) are blocked until it ends.
|
|
51
58
|
* @default false
|
|
52
59
|
*/
|
|
53
|
-
readonly loading: _angular_core.
|
|
60
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
54
61
|
/**
|
|
55
62
|
* @description Visual style variant of the button. When inside a `ButtonGroup`, the group's look takes precedence.
|
|
63
|
+
* `"outline"` looks the same as `"default"`. `"clear"` shows no selected state, so use another look for
|
|
64
|
+
* toggle buttons.
|
|
56
65
|
* @default "default"
|
|
57
66
|
*/
|
|
58
67
|
readonly look: _angular_core.ModelSignal<"default" | "primary" | "success" | "error" | "warning" | "info" | "outline" | "secondary" | "ghost" | "link" | "clear" | null | undefined>;
|
|
@@ -75,23 +84,23 @@ declare class ButtonDirective implements ButtonVariantsInput {
|
|
|
75
84
|
*/
|
|
76
85
|
readonly size: _angular_core.InputSignal<"large" | "medium" | "small" | null | undefined>;
|
|
77
86
|
/**
|
|
78
|
-
* @description Tab index of the host element. Automatically overridden to `-1` when the button is disabled
|
|
79
|
-
* Accepts a numeric string and converts it to a number
|
|
87
|
+
* @description Tab index of the host element. Automatically overridden to `-1` when the button is disabled.
|
|
88
|
+
* Accepts a numeric string and converts it to a number; a value that is not a number falls back to `0`.
|
|
80
89
|
* @default 0
|
|
81
90
|
*/
|
|
82
91
|
readonly tabindex: _angular_core.InputSignalWithTransform<number, string | number>;
|
|
92
|
+
/**
|
|
93
|
+
* @description Enables toggle behavior — each click flips the `selected` state and `aria-pressed` is managed.
|
|
94
|
+
* Accepts the bare attribute form. Buttons in a `ButtonGroup` are toggleable unless this is set to `false`.
|
|
95
|
+
* @default undefined
|
|
96
|
+
*/
|
|
97
|
+
readonly toggleable: _angular_core.InputSignalWithTransform<boolean | undefined, unknown>;
|
|
83
98
|
/**
|
|
84
99
|
* @description Native `type` attribute of the button. Defaults to `"button"` to prevent accidental
|
|
85
100
|
* form submission; set to `"submit"` or `"reset"` explicitly when that behavior is intended.
|
|
86
101
|
* @default "button"
|
|
87
102
|
*/
|
|
88
103
|
readonly type: _angular_core.InputSignal<"button" | "reset" | "submit">;
|
|
89
|
-
/**
|
|
90
|
-
* @description Enables toggle behavior — each click flips the `selected` state and `aria-pressed` is managed.
|
|
91
|
-
* Must use `[toggleable]="true"` binding syntax, not bare attribute form.
|
|
92
|
-
* @default undefined
|
|
93
|
-
*/
|
|
94
|
-
readonly toggleable: _angular_core.InputSignal<boolean | undefined>;
|
|
95
104
|
/**
|
|
96
105
|
* @description Additional CSS classes merged onto the host element via `tailwind-merge`.
|
|
97
106
|
* @default ""
|
|
@@ -99,19 +108,34 @@ declare class ButtonDirective implements ButtonVariantsInput {
|
|
|
99
108
|
readonly userClass: _angular_core.InputSignal<string>;
|
|
100
109
|
constructor();
|
|
101
110
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ButtonDirective, never>;
|
|
102
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ButtonDirective, "button[monaButton]", never, { "ariaHasPopup": { "alias": "aria-haspopup"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "look": { "alias": "look"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "tabindex": { "alias": "tabindex"; "required": false; "isSignal": true; }; "
|
|
111
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ButtonDirective, "button[monaButton]", never, { "ariaHasPopup": { "alias": "aria-haspopup"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "look": { "alias": "look"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "tabindex": { "alias": "tabindex"; "required": false; "isSignal": true; }; "toggleable": { "alias": "toggleable"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; }, { "look": "lookChange"; "selected": "selectedChange"; }, never, never, true, never>;
|
|
103
112
|
}
|
|
104
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Coordinates a `mona-button-group` with its buttons: the group publishes its look, size, rounding, disabled state
|
|
116
|
+
* and members here, and buttons report clicks and receive selection changes through it. It is public so the
|
|
117
|
+
* button-group entry point can provide it; applications don't need to use it directly.
|
|
118
|
+
*/
|
|
105
119
|
declare class ButtonService {
|
|
120
|
+
#private;
|
|
106
121
|
readonly buttonClick$: Subject<[ButtonDirective, boolean]>;
|
|
107
122
|
readonly buttonSelect$: Subject<[ButtonDirective, boolean]>;
|
|
108
123
|
readonly groupDisabled: _angular_core.WritableSignal<boolean>;
|
|
109
124
|
readonly groupLook: _angular_core.WritableSignal<"default" | "primary" | "success" | "error" | "warning" | "info" | "outline" | "secondary" | "ghost" | "link" | "clear" | null | undefined>;
|
|
110
125
|
readonly groupRounded: _angular_core.WritableSignal<"full" | "large" | "medium" | "none" | "small" | null | undefined>;
|
|
111
126
|
readonly groupSize: _angular_core.WritableSignal<"large" | "medium" | "small" | null | undefined>;
|
|
127
|
+
/**
|
|
128
|
+
* The buttons that belong to the group. Only these follow the group's look, size, rounding, disabled state and
|
|
129
|
+
* selection; other buttons that can inject this service ignore it.
|
|
130
|
+
*/
|
|
131
|
+
readonly members: Signal<readonly ButtonDirective[]>;
|
|
132
|
+
/**
|
|
133
|
+
* Sets the source of the group's members, such as the group's `contentChildren(ButtonDirective)` query.
|
|
134
|
+
*/
|
|
135
|
+
setMembers(members: Signal<readonly ButtonDirective[]>): void;
|
|
112
136
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ButtonService, never>;
|
|
113
137
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<ButtonService>;
|
|
114
138
|
}
|
|
115
139
|
|
|
116
140
|
export { ButtonDirective, ButtonService };
|
|
117
|
-
export type { ButtonVariantProps, ButtonVariantsInput };
|
|
141
|
+
export type { ButtonAriaHasPopup, ButtonVariantProps, ButtonVariantsInput };
|
|
@@ -60,7 +60,12 @@ declare class ContainsPipe implements PipeTransform {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
declare class SlicePipe implements PipeTransform {
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Returns the elements from `start` up to, but not including, `end`, with the semantics of `Array.prototype.slice`:
|
|
65
|
+
* negative indices count from the end, and an omitted `end` slices to the end. Returns an empty array for
|
|
66
|
+
* `null` or `undefined`, such as the first value of the `async` pipe.
|
|
67
|
+
*/
|
|
68
|
+
transform<T>(value: Iterable<T> | null | undefined, start: number, end?: number): T[];
|
|
64
69
|
static ɵfac: i0.ɵɵFactoryDeclaration<SlicePipe, never>;
|
|
65
70
|
static ɵpipe: i0.ɵɵPipeDeclaration<SlicePipe, "monaSlice", true>;
|
|
66
71
|
}
|
|
@@ -76,10 +81,12 @@ type BuiltIn = Primitive | Date | RegExp | Function | Map<unknown, unknown> | Se
|
|
|
76
81
|
type DeepPartial<T> = T extends BuiltIn ? T : T extends Array<infer U> ? Array<DeepPartial<U>> : {
|
|
77
82
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
78
83
|
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Every key path into `T`. Paths stop at built-in values (dates, maps, sets, functions), and index arrays by
|
|
86
|
+
* number, so `['tags', 0]` is a path and `['tags', 'map']` is not.
|
|
87
|
+
*/
|
|
88
|
+
type Path<T> = T extends BuiltIn ? never : T extends ReadonlyArray<infer U> ? [number] | (Path<U> extends infer P ? (P extends ReadonlyArray<PropertyKey> ? [number, ...P] : never) : never) : T extends object ? {
|
|
89
|
+
[K in keyof T]-?: [K] | (Path<T[K]> extends infer P ? (P extends ReadonlyArray<PropertyKey> ? [K, ...P] : never) : never);
|
|
83
90
|
}[keyof T] : never;
|
|
84
91
|
type PathValue<T, P> = P extends readonly [infer K, ...infer R] ? K extends keyof T ? R["length"] extends 0 ? T[K] : PathValue<T[K], Extract<R, ReadonlyArray<PropertyKey>>> : never : never;
|
|
85
92
|
type ArrayStrategy = {
|
|
@@ -92,18 +99,40 @@ type ArrayStrategy = {
|
|
|
92
99
|
};
|
|
93
100
|
interface DeepMergeOptions {
|
|
94
101
|
arrayStrategy?: ArrayStrategy | ((key: PropertyKey, path: ReadonlyArray<PropertyKey>) => ArrayStrategy);
|
|
102
|
+
/**
|
|
103
|
+
* What an own `undefined` value in the patch does. `"skip"` (the default) keeps the base value;
|
|
104
|
+
* `"assign"` sets the field to `undefined`.
|
|
105
|
+
*/
|
|
106
|
+
undefinedValues?: "assign" | "skip";
|
|
95
107
|
}
|
|
96
108
|
declare const isEmptyObject: (obj: Record<PropertyKey, unknown>) => boolean;
|
|
97
109
|
declare const isPlainObject: (v: unknown) => v is Record<PropertyKey, unknown>;
|
|
110
|
+
/**
|
|
111
|
+
* Merges `patch` into a copy of `base`. Only plain objects (object literals, `JSON.parse` output) are merged
|
|
112
|
+
* key by key. Any other value in the patch, including a class instance, a `Date`, a `Map` or a `Set`, replaces
|
|
113
|
+
* the base value as a whole, so a partial patch for a class-instance field must carry the whole value.
|
|
114
|
+
* `__proto__` keys in the patch are ignored.
|
|
115
|
+
*/
|
|
98
116
|
declare function deepMerge<T>(base: T, patch: DeepPartial<T>, options?: DeepMergeOptions, path?: ReadonlyArray<PropertyKey>): T;
|
|
99
117
|
declare function deepMerge<T>(base: DeepPartial<T>, patch: DeepPartial<T>, options?: DeepMergeOptions, path?: ReadonlyArray<PropertyKey>): DeepPartial<T>;
|
|
100
118
|
declare function mergeInto<T>(base: T, patch: DeepPartial<T>, options?: DeepMergeOptions): T;
|
|
101
119
|
declare function mergePatchInto<T>(base: DeepPartial<T>, patch: DeepPartial<T>, options?: DeepMergeOptions): DeepPartial<T>;
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Builds a patch that sets `leaf` at `keys`. When `current` (the value the patch will be merged into) holds an
|
|
122
|
+
* array along the path, the patch carries a copy of that array with the one element replaced, since arrays are
|
|
123
|
+
* replaced rather than merged. Without `current`, every level is an object.
|
|
124
|
+
*/
|
|
125
|
+
declare function buildNested(keys: ReadonlyArray<PropertyKey>, leaf: unknown, current?: unknown): Record<PropertyKey, unknown>;
|
|
126
|
+
declare function patchAt<T, P extends Path<T>>(path: P, value: PathValue<T, P>, current?: T): DeepPartial<T>;
|
|
104
127
|
declare function setAt<T, P extends Path<T>>(obj: T, path: P, value: PathValue<T, P>, options?: DeepMergeOptions): T;
|
|
105
128
|
declare function prunePatch<T>(base: T, patch: DeepPartial<T>): DeepPartial<T> | undefined;
|
|
106
129
|
declare function prunePatch<T>(base: DeepPartial<T>, patch: DeepPartial<T>): DeepPartial<T> | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Structural equality for plain objects, arrays, `Date`, `RegExp`, `Map` and `Set`. Primitives are equal when
|
|
132
|
+
* `===` says so, and `NaN` equals `NaN`. Dates are equal when they hold the same time (two invalid dates are
|
|
133
|
+
* equal). Map keys and set members are matched by `SameValueZero`, like `Map.prototype.has`. Cyclic values are
|
|
134
|
+
* supported.
|
|
135
|
+
*/
|
|
107
136
|
declare function deepEquals<T>(o1: T, o2: T): boolean;
|
|
108
137
|
|
|
109
138
|
/**
|
|
@@ -142,18 +171,6 @@ interface IObjectPatchStore<T> {
|
|
|
142
171
|
* pending changes (i.e. the draft is an empty object).
|
|
143
172
|
*/
|
|
144
173
|
readonly changes: Signal<DeepPartial<T> | undefined>;
|
|
145
|
-
/**
|
|
146
|
-
* `true` when the current draft is structurally equal to the last
|
|
147
|
-
* committed snapshot, i.e. no unsaved changes exist relative to the
|
|
148
|
-
* last commit point.
|
|
149
|
-
*/
|
|
150
|
-
readonly pristine: Signal<boolean>;
|
|
151
|
-
/**
|
|
152
|
-
* The live merged view of base + draft. Prefer `select()` over reading
|
|
153
|
-
* this directly in computed signals when you only care about a specific
|
|
154
|
-
* slice of the object, to avoid unnecessary downstream invalidations.
|
|
155
|
-
*/
|
|
156
|
-
readonly view: Signal<T>;
|
|
157
174
|
/**
|
|
158
175
|
* Discard the current draft without affecting the committed snapshot.
|
|
159
176
|
* The view reverts to the base value.
|
|
@@ -174,7 +191,8 @@ interface IObjectPatchStore<T> {
|
|
|
174
191
|
* Deep-merge `patch` into the current draft. Only the fields present in
|
|
175
192
|
* `patch` are affected; all other fields retain their current draft or
|
|
176
193
|
* base values. Automatically prunes fields that match the base value so
|
|
177
|
-
* the draft stays minimal.
|
|
194
|
+
* the draft stays minimal. A field set to `undefined` is cleared, unless
|
|
195
|
+
* `options.undefinedValues` is `"skip"`.
|
|
178
196
|
*/
|
|
179
197
|
patch(patch: DeepPartial<T>, options?: DeepMergeOptions): void;
|
|
180
198
|
/**
|
|
@@ -185,26 +203,17 @@ interface IObjectPatchStore<T> {
|
|
|
185
203
|
* store.patchPath(['address', 'city'], 'London');
|
|
186
204
|
*/
|
|
187
205
|
patchPath<P extends Path<T>>(path: P, value: PathValue<T, P>, options?: DeepMergeOptions): void;
|
|
206
|
+
/**
|
|
207
|
+
* `true` when the current draft is structurally equal to the last
|
|
208
|
+
* committed snapshot, i.e. no unsaved changes exist relative to the
|
|
209
|
+
* last commit point.
|
|
210
|
+
*/
|
|
211
|
+
readonly pristine: Signal<boolean>;
|
|
188
212
|
/**
|
|
189
213
|
* Discard both the draft and the committed snapshot, fully resetting
|
|
190
214
|
* the store to a pristine, empty state.
|
|
191
215
|
*/
|
|
192
216
|
reset(): void;
|
|
193
|
-
/**
|
|
194
|
-
* Directly replace the draft with the given patch object, bypassing the
|
|
195
|
-
* merge logic. Use with care — this does not prune against the base.
|
|
196
|
-
* Prefer `patch()` for most use cases.
|
|
197
|
-
*/
|
|
198
|
-
setDraft(patch: DeepPartial<T>): void;
|
|
199
|
-
/**
|
|
200
|
-
* Convenience wrapper over `patch` that sets a single path to a value.
|
|
201
|
-
* Unlike the old implementation, this merges rather than replaces the
|
|
202
|
-
* draft, so unrelated draft fields are preserved.
|
|
203
|
-
*
|
|
204
|
-
* @example
|
|
205
|
-
* store.setPath(['address', 'city'], 'London');
|
|
206
|
-
*/
|
|
207
|
-
setPath<P extends Path<T>>(path: P, value: PathValue<T, P>, options?: DeepMergeOptions): void;
|
|
208
217
|
/**
|
|
209
218
|
* Returns a `Signal` that emits only the slice of `view` selected by
|
|
210
219
|
* `projector`. Uses `deepEquals` as the equality function, so downstream
|
|
@@ -222,6 +231,28 @@ interface IObjectPatchStore<T> {
|
|
|
222
231
|
* readonly city = store.select(v => v.address.city);
|
|
223
232
|
*/
|
|
224
233
|
select<R>(projector: (view: T) => R, equal?: (a: R, b: R) => boolean): Signal<R>;
|
|
234
|
+
/**
|
|
235
|
+
* Directly replace the draft with the given patch object, bypassing the
|
|
236
|
+
* merge logic. Use with care — this does not prune against the base, so
|
|
237
|
+
* a field equal to its base value still counts in `changes` and
|
|
238
|
+
* `hasDraft()`, while `pristine` ignores it. Prefer `patch()` for most use
|
|
239
|
+
* cases.
|
|
240
|
+
*/
|
|
241
|
+
setDraft(patch: DeepPartial<T>): void;
|
|
242
|
+
/**
|
|
243
|
+
* Same as `patchPath`: sets a single path to a value, merging into the
|
|
244
|
+
* draft, so unrelated draft fields are preserved.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* store.setPath(['address', 'city'], 'London');
|
|
248
|
+
*/
|
|
249
|
+
setPath<P extends Path<T>>(path: P, value: PathValue<T, P>, options?: DeepMergeOptions): void;
|
|
250
|
+
/**
|
|
251
|
+
* The live merged view of base + draft. Prefer `select()` over reading
|
|
252
|
+
* this directly in computed signals when you only care about a specific
|
|
253
|
+
* slice of the object, to avoid unnecessary downstream invalidations.
|
|
254
|
+
*/
|
|
255
|
+
readonly view: Signal<T>;
|
|
225
256
|
}
|
|
226
257
|
declare class ObjectPatchStore<T> implements IObjectPatchStore<T> {
|
|
227
258
|
#private;
|
|
@@ -236,11 +267,16 @@ declare class ObjectPatchStore<T> implements IObjectPatchStore<T> {
|
|
|
236
267
|
patch(patch: DeepPartial<T>, options?: DeepMergeOptions): void;
|
|
237
268
|
patchPath<P extends Path<T>>(path: P, value: PathValue<T, P>, options?: DeepMergeOptions): void;
|
|
238
269
|
reset(): void;
|
|
270
|
+
select<R>(projector: (view: T) => R, equal?: (a: R, b: R) => boolean): Signal<R>;
|
|
239
271
|
setDraft(patch: DeepPartial<T>): void;
|
|
240
272
|
setPath<P extends Path<T>>(path: P, value: PathValue<T, P>, options?: DeepMergeOptions): void;
|
|
241
|
-
select<R>(projector: (view: T) => R, equal?: (a: R, b: R) => boolean): Signal<R>;
|
|
242
273
|
}
|
|
243
274
|
interface IterablePatchStoreOptions<TItem, TId> {
|
|
275
|
+
/**
|
|
276
|
+
* Controls what happens to uncommitted drafts when the base signal emits
|
|
277
|
+
* a new value. Defaults to `'wipe'`.
|
|
278
|
+
*/
|
|
279
|
+
baseChangeStrategy?: BaseChangeStrategy;
|
|
244
280
|
/** Extracts the stable identity key from an item. */
|
|
245
281
|
idOf: (item: TItem) => TId;
|
|
246
282
|
/**
|
|
@@ -248,13 +284,10 @@ interface IterablePatchStoreOptions<TItem, TId> {
|
|
|
248
284
|
* per-row edits). Accepts either a `Map` or an `ImmutableDictionary`.
|
|
249
285
|
*/
|
|
250
286
|
initial?: () => Map<TId, DeepPartial<TItem>> | ImmutableDictionary<TId, DeepPartial<TItem>>;
|
|
287
|
+
/** Default merge options applied to all patch operations unless overridden per-call. */
|
|
288
|
+
mergeOptions?: DeepMergeOptions;
|
|
251
289
|
/** Factory that returns the authoritative base signal for this store. */
|
|
252
290
|
source: () => Signal<Iterable<TItem>>;
|
|
253
|
-
/**
|
|
254
|
-
* Controls what happens to uncommitted drafts when the base signal emits
|
|
255
|
-
* a new value. Defaults to `'wipe'`.
|
|
256
|
-
*/
|
|
257
|
-
baseChangeStrategy?: BaseChangeStrategy;
|
|
258
291
|
}
|
|
259
292
|
interface IIterablePatchStore<TItem, TId> {
|
|
260
293
|
/**
|
|
@@ -262,18 +295,6 @@ interface IIterablePatchStore<TItem, TId> {
|
|
|
262
295
|
* with its current draft. Items without a draft are excluded.
|
|
263
296
|
*/
|
|
264
297
|
readonly changes: Signal<TItem[]>;
|
|
265
|
-
/**
|
|
266
|
-
* `true` when every item's current draft is structurally equal to its
|
|
267
|
-
* last committed snapshot.
|
|
268
|
-
*/
|
|
269
|
-
readonly pristine: Signal<boolean>;
|
|
270
|
-
/**
|
|
271
|
-
* The live merged view of all base items with their drafts applied.
|
|
272
|
-
* Items without a draft are returned as-is (same reference).
|
|
273
|
-
* Prefer `select()` over reading this directly in computed signals when
|
|
274
|
-
* you only care about a specific slice.
|
|
275
|
-
*/
|
|
276
|
-
readonly view: Signal<TItem[]>;
|
|
277
298
|
/**
|
|
278
299
|
* Discard the draft for the item identified by `id`.
|
|
279
300
|
* Has no effect if the item has no draft.
|
|
@@ -298,6 +319,8 @@ interface IIterablePatchStore<TItem, TId> {
|
|
|
298
319
|
* Deep-merge `patch` into the draft for the item identified by `id`.
|
|
299
320
|
* Automatically prunes fields that now match the base item so the draft
|
|
300
321
|
* stays minimal. Removes the draft entry entirely if it becomes empty.
|
|
322
|
+
* A field set to `undefined` is cleared, unless `options.undefinedValues`
|
|
323
|
+
* is `"skip"`.
|
|
301
324
|
*/
|
|
302
325
|
patch(id: TId, patch: DeepPartial<TItem>, options?: DeepMergeOptions): void;
|
|
303
326
|
/**
|
|
@@ -314,26 +337,16 @@ interface IIterablePatchStore<TItem, TId> {
|
|
|
314
337
|
* store.patchPath(itemId, ['address', 'city'], 'London');
|
|
315
338
|
*/
|
|
316
339
|
patchPath<P extends Path<TItem>>(id: TId, path: P, value: PathValue<TItem, P>, options?: DeepMergeOptions): void;
|
|
340
|
+
/**
|
|
341
|
+
* `true` when every item's current draft is structurally equal to its
|
|
342
|
+
* last committed snapshot.
|
|
343
|
+
*/
|
|
344
|
+
readonly pristine: Signal<boolean>;
|
|
317
345
|
/**
|
|
318
346
|
* Discard all drafts and committed snapshots, fully resetting the store
|
|
319
347
|
* to a pristine, empty state.
|
|
320
348
|
*/
|
|
321
349
|
reset(): void;
|
|
322
|
-
/**
|
|
323
|
-
* Directly replace the draft for `id` with the given patch object,
|
|
324
|
-
* bypassing the merge logic. Use with care — this does not prune against
|
|
325
|
-
* the base item. Prefer `patch()` for most use cases.
|
|
326
|
-
*/
|
|
327
|
-
setDraft(id: TId, patch: DeepPartial<TItem>): void;
|
|
328
|
-
/**
|
|
329
|
-
* Convenience wrapper over `patch` that sets a single path to a value
|
|
330
|
-
* for a specific item. Merges into the existing draft rather than
|
|
331
|
-
* replacing it, so unrelated draft fields are preserved.
|
|
332
|
-
*
|
|
333
|
-
* @example
|
|
334
|
-
* store.setPath(itemId, ['address', 'city'], 'London');
|
|
335
|
-
*/
|
|
336
|
-
setPath<P extends Path<TItem>>(id: TId, path: P, value: PathValue<TItem, P>, options?: DeepMergeOptions): void;
|
|
337
350
|
/**
|
|
338
351
|
* Returns a `Signal` that emits only the slice of `view` selected by
|
|
339
352
|
* `projector`. Uses `deepEquals` as the equality function by default,
|
|
@@ -347,6 +360,30 @@ interface IIterablePatchStore<TItem, TId> {
|
|
|
347
360
|
* readonly cities = store.select(items => items.map(i => i.address.city));
|
|
348
361
|
*/
|
|
349
362
|
select<R>(projector: (view: TItem[]) => R, equal?: (a: R, b: R) => boolean): Signal<R>;
|
|
363
|
+
/**
|
|
364
|
+
* Directly replace the draft for `id` with the given patch object,
|
|
365
|
+
* bypassing the merge logic. An empty patch removes the draft. Use with
|
|
366
|
+
* care — this does not prune against the base item, so a field equal to
|
|
367
|
+
* its base value still counts in `changes`, `hasDraft()` and
|
|
368
|
+
* `dirtyCount()`, while `pristine` ignores it. Prefer `patch()` for most
|
|
369
|
+
* use cases.
|
|
370
|
+
*/
|
|
371
|
+
setDraft(id: TId, patch: DeepPartial<TItem>): void;
|
|
372
|
+
/**
|
|
373
|
+
* Same as `patchPath`: sets a single path to a value for a specific item,
|
|
374
|
+
* merging into the existing draft, so unrelated draft fields are preserved.
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* store.setPath(itemId, ['address', 'city'], 'London');
|
|
378
|
+
*/
|
|
379
|
+
setPath<P extends Path<TItem>>(id: TId, path: P, value: PathValue<TItem, P>, options?: DeepMergeOptions): void;
|
|
380
|
+
/**
|
|
381
|
+
* The live merged view of all base items with their drafts applied.
|
|
382
|
+
* Items without a draft are returned as-is (same reference).
|
|
383
|
+
* Prefer `select()` over reading this directly in computed signals when
|
|
384
|
+
* you only care about a specific slice.
|
|
385
|
+
*/
|
|
386
|
+
readonly view: Signal<TItem[]>;
|
|
350
387
|
}
|
|
351
388
|
declare class IterablePatchStore<TItem, TId> implements IIterablePatchStore<TItem, TId> {
|
|
352
389
|
#private;
|
|
@@ -360,13 +397,13 @@ declare class IterablePatchStore<TItem, TId> implements IIterablePatchStore<TIte
|
|
|
360
397
|
dirtyCount(): number;
|
|
361
398
|
getCommitted(): ImmutableDictionary<TId, DeepPartial<TItem>>;
|
|
362
399
|
hasDraft(id: TId): boolean;
|
|
363
|
-
patch(id: TId, patch: DeepPartial<TItem>, options?: DeepMergeOptions): void;
|
|
364
|
-
patchMany(patchTuple: Iterable<[TId, DeepPartial<TItem>]>, options?: DeepMergeOptions): void;
|
|
400
|
+
patch(id: TId, patch: DeepPartial<TItem>, options?: DeepMergeOptions | undefined): void;
|
|
401
|
+
patchMany(patchTuple: Iterable<[TId, DeepPartial<TItem>]>, options?: DeepMergeOptions | undefined): void;
|
|
365
402
|
patchPath<P extends Path<TItem>>(id: TId, path: P, value: PathValue<TItem, P>, options?: DeepMergeOptions): void;
|
|
366
403
|
reset(): void;
|
|
404
|
+
select<R>(projector: (view: TItem[]) => R, equal?: (a: R, b: R) => boolean): Signal<R>;
|
|
367
405
|
setDraft(id: TId, patch: DeepPartial<TItem>): void;
|
|
368
406
|
setPath<P extends Path<TItem>>(id: TId, path: P, value: PathValue<TItem, P>, options?: DeepMergeOptions): void;
|
|
369
|
-
select<R>(projector: (view: TItem[]) => R, equal?: (a: R, b: R) => boolean): Signal<R>;
|
|
370
407
|
}
|
|
371
408
|
declare const createIterablePatchStore: <TItem, TId>(options: IterablePatchStoreOptions<TItem, TId>) => IIterablePatchStore<TItem, TId>;
|
|
372
409
|
declare const createObjectPatchStore: <T>(options: ObjectPatchStoreOptions<T>) => IObjectPatchStore<T>;
|
|
@@ -378,12 +415,18 @@ declare const classInputToClass: (input: ClassInputType) => string;
|
|
|
378
415
|
* @param value The current value.
|
|
379
416
|
* @param min The minimum value.
|
|
380
417
|
* @param max The maximum value.
|
|
381
|
-
* @param precision The number of decimal places to round the percentage to.
|
|
418
|
+
* @param precision The number of decimal places to round the percentage to, clamped to 0–100.
|
|
382
419
|
* @default 2
|
|
383
|
-
* @returns The percentage of the value within the range, rounded to the specified precision
|
|
420
|
+
* @returns The percentage of the value within the range, rounded to the specified precision, or 0 when the range
|
|
421
|
+
* or the value is not finite.
|
|
384
422
|
*/
|
|
385
423
|
declare const getPercentage: (value: number, min: number, max: number, precision?: number) => number;
|
|
386
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Moves the items at `indices` by `offset` positions, keeping their relative order. Returns a copy of the array
|
|
427
|
+
* unchanged when the offset is 0 or not an integer, or when any index is not an integer, is out of bounds, or would
|
|
428
|
+
* move out of bounds. Duplicate indices count once.
|
|
429
|
+
*/
|
|
387
430
|
declare function moveIndices<T>(array: T[], indices: number[], offset: number): T[];
|
|
388
431
|
|
|
389
432
|
export { AnyPipe, ContainsPipe, FilterChangeEvent, IterablePatchStore, ObjectPatchStore, PreventableEvent, SlicePipe, TakeFirstPipe, buildNested, classInputToClass, createIterablePatchStore, createObjectPatchStore, deepEquals, deepMerge, getPercentage, isEmptyObject, isPlainObject, mergeInto, mergePatchInto, moveIndices, patchAt, prunePatch, setAt };
|