@simplysm/angular 14.0.23 → 14.0.24
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/package.json +6 -7
- package/README.md +0 -310
- package/docs/core.md +0 -909
- package/docs/features.md +0 -402
- package/docs/styling.md +0 -309
- package/docs/ui-data.md +0 -249
- package/docs/ui-form.md +0 -421
- package/docs/ui-layout.md +0 -216
- package/docs/ui-navigation.md +0 -243
- package/docs/ui-overlay.md +0 -330
- package/docs/ui-visual.md +0 -131
package/docs/core.md
DELETED
|
@@ -1,909 +0,0 @@
|
|
|
1
|
-
# Core
|
|
2
|
-
|
|
3
|
-
Providers, plugins, directives, pipes, and utility functions that form the foundation of the `@simplysm/angular` framework.
|
|
4
|
-
|
|
5
|
-
## `TXT_CHANGE_IGNORE_CONFIRM`
|
|
6
|
-
|
|
7
|
-
Korean string constant used for "ignore unsaved changes?" confirmation dialogs.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
const TXT_CHANGE_IGNORE_CONFIRM: string;
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## `provideSdAngular`
|
|
14
|
-
|
|
15
|
-
Bootstraps all core Angular providers for a Simplysm application.
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
function provideSdAngular(opt: { clientName: string }): EnvironmentProviders;
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Registers: `IMAGE_CONFIG`, NgIcons, theme/local-storage initialization, global error handler, 6 event/command plugins, zoneless change detection, service worker update poller (5 min interval), and router navigation busy counter.
|
|
22
|
-
|
|
23
|
-
## `SdAngularConfigProvider`
|
|
24
|
-
|
|
25
|
-
Global configuration holder for the application client name.
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
@Injectable({ providedIn: "root" })
|
|
29
|
-
class SdAngularConfigProvider {
|
|
30
|
-
clientName: string;
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## `SdThemeProvider`
|
|
35
|
-
|
|
36
|
-
Dark/light theme toggle. When `dark` is `true`, the `sd-theme-dark` class is applied to `<body>`.
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
@Injectable({ providedIn: "root" })
|
|
40
|
-
class SdThemeProvider {
|
|
41
|
-
dark: WritableSignal<boolean>;
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## `SdSystemLogProvider`
|
|
46
|
-
|
|
47
|
-
Centralized logging service.
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
@Injectable({ providedIn: "root" })
|
|
51
|
-
class SdSystemLogProvider {
|
|
52
|
-
writeFn?: (severity: "error" | "warn" | "log", ...data: any[]) => Promise<void> | void;
|
|
53
|
-
async writeAsync(severity: "error" | "warn" | "log", ...data: any[]): Promise<void>;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
| Field | Type | Description |
|
|
58
|
-
|-------|------|-------------|
|
|
59
|
-
| `writeFn` | `((severity, ...data) => Promise<void> \| void) \| undefined` | Optional external log handler |
|
|
60
|
-
|
|
61
|
-
## `SdAppStructureProvider`
|
|
62
|
-
|
|
63
|
-
Abstract provider that maps application structure (menus, permissions) from a declarative item tree.
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
@Injectable({ providedIn: "root" })
|
|
67
|
-
abstract class SdAppStructureProvider<TModule> {
|
|
68
|
-
abstract items: TSdAppStructureItem<TModule>[];
|
|
69
|
-
abstract usableModules: Signal<TModule[] | undefined>;
|
|
70
|
-
abstract permRecord: Signal<Record<string, boolean> | undefined>;
|
|
71
|
-
|
|
72
|
-
usableMenus: Signal<ISdMenu<TModule>[]>;
|
|
73
|
-
usableFlatMenus: Signal<ISdFlatMenu<TModule>[]>;
|
|
74
|
-
getPermissionsByStructure(items: TSdAppStructureItem<TModule>[], codeChain?: string[]): ISdPermission<TModule>[];
|
|
75
|
-
getTitleByFullCode(fullCode: string): string;
|
|
76
|
-
getItemChainByFullCode(fullCode: string): TSdAppStructureItem<TModule>[];
|
|
77
|
-
getPermsByFullCode<K extends string>(fullCodes: string[], permKeys: K[]): K[];
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## `SdAppStructureUtils`
|
|
82
|
-
|
|
83
|
-
Static utility class for app structure operations without provider injection.
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
abstract class SdAppStructureUtils {
|
|
87
|
-
static getTitleByFullCode<TModule>(items: TSdAppStructureItem<TModule>[], fullCode: string): string;
|
|
88
|
-
static getPermsByFullCode<TModule, K extends string>(items: TSdAppStructureItem<TModule>[], fullCodes: string[], permKeys: K[], permRecord: Record<string, boolean>): K[];
|
|
89
|
-
static getItemChainByFullCode<TModule>(items: TSdAppStructureItem<TModule>[], fullCode: string): TSdAppStructureItem<TModule>[];
|
|
90
|
-
static getMenus<TModule>(items: TSdAppStructureItem<TModule>[], codeChain: string[], usableModules: TModule[] | undefined, permRecord: Record<string, boolean> | undefined): ISdMenu<TModule>[];
|
|
91
|
-
static getFlatMenus<TModule>(items: TSdAppStructureItem<TModule>[], usableModules: TModule[] | undefined, permRecord: Record<string, boolean> | undefined): ISdFlatMenu<TModule>[];
|
|
92
|
-
static getPermissions<TModule>(items: TSdAppStructureItem<TModule>[], codeChain: string[], usableModules: TModule[] | undefined): ISdPermission<TModule>[];
|
|
93
|
-
static getFlatPermissions<TModule>(items: TSdAppStructureItem<TModule>[], usableModules: TModule[] | undefined): ISdFlatPermission<TModule>[];
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## `TSdAppStructureItem`
|
|
98
|
-
|
|
99
|
-
Discriminated union for app structure tree nodes.
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
type TSdAppStructureItem<TModule> = ISdAppStructureGroupItem<TModule> | ISdAppStructureLeafItem<TModule>;
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## `ISdMenu`
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
interface ISdMenu<TModule> {
|
|
109
|
-
title: string;
|
|
110
|
-
codeChain: string[];
|
|
111
|
-
icon: string | undefined;
|
|
112
|
-
modules: TModule[] | undefined;
|
|
113
|
-
children: ISdMenu<TModule>[] | undefined;
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
| Field | Type | Description |
|
|
118
|
-
|-------|------|-------------|
|
|
119
|
-
| `title` | `string` | Menu display text |
|
|
120
|
-
| `codeChain` | `string[]` | Hierarchical code path |
|
|
121
|
-
| `icon` | `string \| undefined` | Icon SVG string |
|
|
122
|
-
| `modules` | `TModule[] \| undefined` | Required modules for visibility |
|
|
123
|
-
| `children` | `ISdMenu<TModule>[] \| undefined` | Sub-menus |
|
|
124
|
-
|
|
125
|
-
## `ISdFlatMenu`
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
interface ISdFlatMenu<TModule> {
|
|
129
|
-
titleChain: string[];
|
|
130
|
-
codeChain: string[];
|
|
131
|
-
modulesChain: TModule[][];
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
| Field | Type | Description |
|
|
136
|
-
|-------|------|-------------|
|
|
137
|
-
| `titleChain` | `string[]` | Flattened title breadcrumb |
|
|
138
|
-
| `codeChain` | `string[]` | Flattened code path |
|
|
139
|
-
| `modulesChain` | `TModule[][]` | Module requirements per level |
|
|
140
|
-
|
|
141
|
-
## `ISdPermission`
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
interface ISdPermission<TModule> {
|
|
145
|
-
title: string;
|
|
146
|
-
codeChain: string[];
|
|
147
|
-
modules: TModule[] | undefined;
|
|
148
|
-
perms: ("use" | "edit")[] | undefined;
|
|
149
|
-
children: ISdPermission<TModule>[] | undefined;
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
| Field | Type | Description |
|
|
154
|
-
|-------|------|-------------|
|
|
155
|
-
| `title` | `string` | Permission display text |
|
|
156
|
-
| `codeChain` | `string[]` | Hierarchical code path |
|
|
157
|
-
| `modules` | `TModule[] \| undefined` | Required modules |
|
|
158
|
-
| `perms` | `("use" \| "edit")[] \| undefined` | Permission keys |
|
|
159
|
-
| `children` | `ISdPermission<TModule>[] \| undefined` | Sub-permissions |
|
|
160
|
-
|
|
161
|
-
## `ISdFlatPermission`
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
interface ISdFlatPermission<TModule> {
|
|
165
|
-
titleChain: string[];
|
|
166
|
-
codeChain: string[];
|
|
167
|
-
modulesChain: TModule[][];
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
| Field | Type | Description |
|
|
172
|
-
|-------|------|-------------|
|
|
173
|
-
| `titleChain` | `string[]` | Flattened title breadcrumb |
|
|
174
|
-
| `codeChain` | `string[]` | Flattened code path |
|
|
175
|
-
| `modulesChain` | `TModule[][]` | Module requirements per level |
|
|
176
|
-
|
|
177
|
-
## `usePermsSignal`
|
|
178
|
-
|
|
179
|
-
Reactive permission checker as a computed signal.
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
function usePermsSignal<K extends string>(viewCodes: string[], keys: K[]): Signal<K[]>;
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Returns a signal containing the subset of `keys` the current user has permission for across the given `viewCodes`.
|
|
186
|
-
|
|
187
|
-
## `SdFileDialogProvider`
|
|
188
|
-
|
|
189
|
-
Opens a native file picker dialog via a hidden `<input type="file">`.
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
@Injectable({ providedIn: "root" })
|
|
193
|
-
class SdFileDialogProvider {
|
|
194
|
-
async showAsync(multiple?: false, accept?: string): Promise<File | undefined>;
|
|
195
|
-
async showAsync(multiple: true, accept?: string): Promise<File[] | undefined>;
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## `SdLocalStorageProvider`
|
|
200
|
-
|
|
201
|
-
Typed wrapper around `localStorage` with `clientName`-prefixed keys and JSON serialization.
|
|
202
|
-
|
|
203
|
-
```typescript
|
|
204
|
-
@Injectable({ providedIn: "root" })
|
|
205
|
-
class SdLocalStorageProvider<T> {
|
|
206
|
-
set<K extends keyof T & string>(key: K, value: T[K]): void;
|
|
207
|
-
get<K extends keyof T & string>(key: K): T[K] | undefined;
|
|
208
|
-
remove(key: keyof T & string): void;
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## `SdSystemConfigProvider`
|
|
213
|
-
|
|
214
|
-
Async config storage abstraction. Falls back to local storage when no external handler is set.
|
|
215
|
-
|
|
216
|
-
```typescript
|
|
217
|
-
@Injectable({ providedIn: "root" })
|
|
218
|
-
class SdSystemConfigProvider<T> {
|
|
219
|
-
fn?: {
|
|
220
|
-
set<K extends keyof T & string>(key: K, data: T[K]): Promise<void> | void;
|
|
221
|
-
get(key: keyof T & string): PromiseLike<any>;
|
|
222
|
-
};
|
|
223
|
-
async setAsync<K extends keyof T & string>(key: K, data: T[K]): Promise<void>;
|
|
224
|
-
async getAsync(key: keyof T & string): Promise<any>;
|
|
225
|
-
}
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
## `SdServiceClientFactoryProvider`
|
|
229
|
-
|
|
230
|
-
Manages `ServiceClient` connections by key.
|
|
231
|
-
|
|
232
|
-
```typescript
|
|
233
|
-
@Injectable({ providedIn: "root" })
|
|
234
|
-
class SdServiceClientFactoryProvider {
|
|
235
|
-
async connectAsync(key: string, options?: Partial<ServiceConnectionOptions>): Promise<void>;
|
|
236
|
-
async closeAsync(key: string): Promise<void>;
|
|
237
|
-
get(key: string): ServiceClient;
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## `SdSharedDataProvider`
|
|
242
|
-
|
|
243
|
-
Abstract provider for shared (cached, event-driven) data. Subclass and register data sources.
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
@Injectable()
|
|
247
|
-
abstract class SdSharedDataProvider<T extends Record<string, ISharedDataBase<string | number>>> {
|
|
248
|
-
loadingCount: WritableSignal<number>;
|
|
249
|
-
abstract initialize(): void;
|
|
250
|
-
register<K extends string & keyof T>(name: K, info: ISharedDataInfo<T[K]>): void;
|
|
251
|
-
getHandle<K extends string & keyof T>(name: K): SharedDataHandle<T[K]>;
|
|
252
|
-
async emitAsync<K extends string & keyof T>(name: K, changeKeys?: (string | number)[]): Promise<void>;
|
|
253
|
-
async wait(): Promise<void>;
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
## `SdSharedDataChangeEvent`
|
|
258
|
-
|
|
259
|
-
Event definition for shared data change notifications across service connections.
|
|
260
|
-
|
|
261
|
-
```typescript
|
|
262
|
-
const SdSharedDataChangeEvent: EventDef<{ name: string; filter: unknown }, (string | number)[] | undefined>;
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
## `ISharedDataBase`
|
|
266
|
-
|
|
267
|
-
Base interface for shared data items.
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
interface ISharedDataBase<TKey extends string | number> {
|
|
271
|
-
__valueKey: TKey;
|
|
272
|
-
__searchText: string;
|
|
273
|
-
__isHidden: boolean;
|
|
274
|
-
__parentKey?: TKey;
|
|
275
|
-
}
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
| Field | Type | Description |
|
|
279
|
-
|-------|------|-------------|
|
|
280
|
-
| `__valueKey` | `TKey` | Unique identifier |
|
|
281
|
-
| `__searchText` | `string` | Text used for search filtering |
|
|
282
|
-
| `__isHidden` | `boolean` | Whether the item is hidden from display |
|
|
283
|
-
| `__parentKey` | `TKey \| undefined` | Parent key for tree hierarchy |
|
|
284
|
-
|
|
285
|
-
## `ISharedDataInfo`
|
|
286
|
-
|
|
287
|
-
Registration descriptor for a shared data source.
|
|
288
|
-
|
|
289
|
-
```typescript
|
|
290
|
-
interface ISharedDataInfo<T extends ISharedDataBase<string | number>> {
|
|
291
|
-
serviceKey: string;
|
|
292
|
-
getter: (changeKeys?: (string | number)[]) => Promise<T[]>;
|
|
293
|
-
filter?: unknown;
|
|
294
|
-
orderBy?: (a: T, b: T) => number;
|
|
295
|
-
}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
| Field | Type | Description |
|
|
299
|
-
|-------|------|-------------|
|
|
300
|
-
| `serviceKey` | `string` | Service connection key |
|
|
301
|
-
| `getter` | `(changeKeys?) => Promise<T[]>` | Data fetch function; receives changed keys for incremental update |
|
|
302
|
-
| `filter` | `unknown` | Optional filter passed to the service event |
|
|
303
|
-
| `orderBy` | `((a, b) => number) \| undefined` | Optional sort comparator |
|
|
304
|
-
|
|
305
|
-
## `SharedDataHandle`
|
|
306
|
-
|
|
307
|
-
Read handle returned by `SdSharedDataProvider.getHandle()`.
|
|
308
|
-
|
|
309
|
-
```typescript
|
|
310
|
-
interface SharedDataHandle<T extends ISharedDataBase<string | number>> {
|
|
311
|
-
items: Signal<T[]>;
|
|
312
|
-
get(key: T["__valueKey"] | undefined): T | undefined;
|
|
313
|
-
}
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
| Field | Type | Description |
|
|
317
|
-
|-------|------|-------------|
|
|
318
|
-
| `items` | `Signal<T[]>` | Reactive list of all items |
|
|
319
|
-
| `get` | `(key) => T \| undefined` | Lookup a single item by key |
|
|
320
|
-
|
|
321
|
-
## `SdNavigateWindowProvider`
|
|
322
|
-
|
|
323
|
-
Manages new-window navigation with auto-close on parent `beforeunload`.
|
|
324
|
-
|
|
325
|
-
```typescript
|
|
326
|
-
@Injectable({ providedIn: "root" })
|
|
327
|
-
class SdNavigateWindowProvider {
|
|
328
|
-
get isWindow(): boolean;
|
|
329
|
-
open(navigate: string, params?: Record<string, string>, features?: string): void;
|
|
330
|
-
}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
## `SdPrintProvider`
|
|
334
|
-
|
|
335
|
-
Dynamically renders a component for printing or PDF generation.
|
|
336
|
-
|
|
337
|
-
```typescript
|
|
338
|
-
@Injectable({ providedIn: "root" })
|
|
339
|
-
class SdPrintProvider {
|
|
340
|
-
async printAsync<T extends ISdPrint>(template: ISdPrintInput<T>, options?: { size?: string; margin?: string }): Promise<void>;
|
|
341
|
-
async getPdfBufferAsync<T extends ISdPrint>(template: ISdPrintInput<T>, options?: { orientation?: "portrait" | "landscape"; pageSize?: string }): Promise<Uint8Array>;
|
|
342
|
-
}
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
## `ISdPrint`
|
|
346
|
-
|
|
347
|
-
Contract for printable components.
|
|
348
|
-
|
|
349
|
-
```typescript
|
|
350
|
-
interface ISdPrint {
|
|
351
|
-
initialized: Signal<boolean>;
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
## `ISdPrintInput`
|
|
356
|
-
|
|
357
|
-
Input descriptor for `SdPrintProvider`.
|
|
358
|
-
|
|
359
|
-
```typescript
|
|
360
|
-
interface ISdPrintInput<T, X extends keyof any = ""> {
|
|
361
|
-
type: Type<T>;
|
|
362
|
-
inputs: Omit<TDirectiveInputSignals<T>, X>;
|
|
363
|
-
}
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
| Field | Type | Description |
|
|
367
|
-
|-------|------|-------------|
|
|
368
|
-
| `type` | `Type<T>` | Component class to render |
|
|
369
|
-
| `inputs` | `Omit<TDirectiveInputSignals<T>, X>` | Input values to set on the component |
|
|
370
|
-
|
|
371
|
-
## `SdGlobalErrorHandlerPlugin`
|
|
372
|
-
|
|
373
|
-
Global error handler that logs via `SdSystemLogProvider`, shows a full-screen error overlay, and reloads on click.
|
|
374
|
-
|
|
375
|
-
```typescript
|
|
376
|
-
@Injectable({ providedIn: null })
|
|
377
|
-
class SdGlobalErrorHandlerPlugin implements ErrorHandler {
|
|
378
|
-
handleError(event: any): void;
|
|
379
|
-
}
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
## `SdOptionEventPlugin`
|
|
383
|
-
|
|
384
|
-
Event plugin that adds `.capture`, `.passive`, `.once` suffix support to native DOM events.
|
|
385
|
-
|
|
386
|
-
```typescript
|
|
387
|
-
@Injectable({ providedIn: null })
|
|
388
|
-
class SdOptionEventPlugin extends EventManagerPlugin {
|
|
389
|
-
supports(eventName: string): boolean;
|
|
390
|
-
addEventListener(element: HTMLElement, eventName: string, handler: Function): () => void;
|
|
391
|
-
}
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
## `SdResizeEventPlugin`
|
|
395
|
-
|
|
396
|
-
Event plugin for the `sdResize` custom event using `ResizeObserver`.
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
@Injectable({ providedIn: null })
|
|
400
|
-
class SdResizeEventPlugin extends EventManagerPlugin {
|
|
401
|
-
supports(eventName: string): boolean;
|
|
402
|
-
addEventListener(element: HTMLElement, eventName: string, handler: Function): () => void;
|
|
403
|
-
}
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
## `ISdResizeEvent`
|
|
407
|
-
|
|
408
|
-
```typescript
|
|
409
|
-
interface ISdResizeEvent {
|
|
410
|
-
heightChanged: boolean;
|
|
411
|
-
widthChanged: boolean;
|
|
412
|
-
target: Element;
|
|
413
|
-
contentRect: DOMRectReadOnly;
|
|
414
|
-
}
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
| Field | Type | Description |
|
|
418
|
-
|-------|------|-------------|
|
|
419
|
-
| `heightChanged` | `boolean` | Whether height changed |
|
|
420
|
-
| `widthChanged` | `boolean` | Whether width changed |
|
|
421
|
-
| `target` | `Element` | Observed element |
|
|
422
|
-
| `contentRect` | `DOMRectReadOnly` | New content rect |
|
|
423
|
-
|
|
424
|
-
## `SdIntersectionEventPlugin`
|
|
425
|
-
|
|
426
|
-
Event plugin for the `sdIntersection` custom event using `IntersectionObserver`.
|
|
427
|
-
|
|
428
|
-
```typescript
|
|
429
|
-
@Injectable({ providedIn: null })
|
|
430
|
-
class SdIntersectionEventPlugin extends EventManagerPlugin {
|
|
431
|
-
supports(eventName: string): boolean;
|
|
432
|
-
addEventListener(element: HTMLElement, eventName: string, handler: Function): () => void;
|
|
433
|
-
}
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
## `ISdIntersectionEvent`
|
|
437
|
-
|
|
438
|
-
```typescript
|
|
439
|
-
interface ISdIntersectionEvent {
|
|
440
|
-
entry: IntersectionObserverEntry;
|
|
441
|
-
}
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
| Field | Type | Description |
|
|
445
|
-
|-------|------|-------------|
|
|
446
|
-
| `entry` | `IntersectionObserverEntry` | Intersection observer entry |
|
|
447
|
-
|
|
448
|
-
## `SdSaveCommandEventPlugin`
|
|
449
|
-
|
|
450
|
-
Event plugin for `sdSaveCommand` — fires on `Ctrl+S` (no Alt/Shift). Scoped to the topmost open modal.
|
|
451
|
-
|
|
452
|
-
```typescript
|
|
453
|
-
@Injectable({ providedIn: null })
|
|
454
|
-
class SdSaveCommandEventPlugin extends EventManagerPlugin { }
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
## `SdRefreshCommandEventPlugin`
|
|
458
|
-
|
|
459
|
-
Event plugin for `sdRefreshCommand` — fires on `Ctrl+Alt+L`.
|
|
460
|
-
|
|
461
|
-
```typescript
|
|
462
|
-
@Injectable({ providedIn: null })
|
|
463
|
-
class SdRefreshCommandEventPlugin extends EventManagerPlugin { }
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
## `SdInsertCommandEventPlugin`
|
|
467
|
-
|
|
468
|
-
Event plugin for `sdInsertCommand` — fires on `Ctrl+Insert`.
|
|
469
|
-
|
|
470
|
-
```typescript
|
|
471
|
-
@Injectable({ providedIn: null })
|
|
472
|
-
class SdInsertCommandEventPlugin extends EventManagerPlugin { }
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
## `SdEventsDirective`
|
|
476
|
-
|
|
477
|
-
Directive that exposes captured/passive/once event variants and custom events as Angular outputs.
|
|
478
|
-
|
|
479
|
-
```typescript
|
|
480
|
-
@Directive({ standalone: true })
|
|
481
|
-
class SdEventsDirective {
|
|
482
|
-
// Outputs include:
|
|
483
|
-
// "click.capture", "click.once", "click.capture.once",
|
|
484
|
-
// "mousedown.capture", "mouseup.capture", "mouseover.capture", "mouseout.capture",
|
|
485
|
-
// "keydown.capture", "keyup.capture", "focus.capture", "blur.capture",
|
|
486
|
-
// "invalid.capture", "scroll.capture", "scroll.passive", "scroll.capture.passive",
|
|
487
|
-
// "wheel.passive", "wheel.capture.passive",
|
|
488
|
-
// "touchstart.passive", "touchstart.capture.passive",
|
|
489
|
-
// "touchmove.passive", "touchmove.capture.passive",
|
|
490
|
-
// "touchend.passive", "dragover.capture", "dragenter.capture",
|
|
491
|
-
// "dragleave.capture", "drop.capture",
|
|
492
|
-
// "transitionend.once", "animationend.once",
|
|
493
|
-
// "sdResize", "sdRefreshCommand", "sdSaveCommand", "sdInsertCommand"
|
|
494
|
-
}
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
## `SdRippleDirective`
|
|
498
|
-
|
|
499
|
-
Applies a material-style ripple effect to the host element.
|
|
500
|
-
|
|
501
|
-
```typescript
|
|
502
|
-
@Directive({ standalone: true, selector: "[sd-ripple]" })
|
|
503
|
-
class SdRippleDirective {
|
|
504
|
-
enabled: InputSignal<boolean>; // alias: "sd-ripple"
|
|
505
|
-
}
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
## `SdShowEffectDirective`
|
|
509
|
-
|
|
510
|
-
Applies an entrance animation (fade + slide) when the host element enters the viewport.
|
|
511
|
-
|
|
512
|
-
```typescript
|
|
513
|
-
@Directive({ standalone: true, selector: "[sd-show-effect]" })
|
|
514
|
-
class SdShowEffectDirective {
|
|
515
|
-
enabled: InputSignal<boolean>; // alias: "sd-show-effect"
|
|
516
|
-
sdShowEffectType: InputSignal<"l2r" | "t2b">; // default: "t2b"
|
|
517
|
-
}
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
## `SdInvalidDirective`
|
|
521
|
-
|
|
522
|
-
Adds a validation indicator dot and hidden `<input>` with `setCustomValidity` to the host element.
|
|
523
|
-
|
|
524
|
-
```typescript
|
|
525
|
-
@Directive({ standalone: true, selector: "[sd-invalid]" })
|
|
526
|
-
class SdInvalidDirective {
|
|
527
|
-
invalidMessage: InputSignal<string>; // alias: "sd-invalid"
|
|
528
|
-
}
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
## `SdTypedTemplateDirective`
|
|
532
|
-
|
|
533
|
-
Provides type-safe template context via Angular's `ngTemplateContextGuard`.
|
|
534
|
-
|
|
535
|
-
```typescript
|
|
536
|
-
@Directive({ standalone: true, selector: "ng-template[typed]" })
|
|
537
|
-
class SdTypedTemplateDirective<T> {
|
|
538
|
-
typed: InputSignal<T>;
|
|
539
|
-
static ngTemplateContextGuard<TypeToken>(dir: SdTypedTemplateDirective<TypeToken>, ctx: unknown): ctx is TypeToken;
|
|
540
|
-
}
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
## `SdItemOfTemplateDirective`
|
|
544
|
-
|
|
545
|
-
Template directive for typed item iteration with context.
|
|
546
|
-
|
|
547
|
-
```typescript
|
|
548
|
-
@Directive({ standalone: true, selector: "ng-template[itemOf]" })
|
|
549
|
-
class SdItemOfTemplateDirective<TItem> {
|
|
550
|
-
itemOf: InputSignal<TItem[]>;
|
|
551
|
-
static ngTemplateContextGuard<TContextItem>(dir: SdItemOfTemplateDirective<TContextItem>, ctx: unknown): ctx is SdItemOfTemplateContext<TContextItem>;
|
|
552
|
-
}
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
## `SdItemOfTemplateContext`
|
|
556
|
-
|
|
557
|
-
```typescript
|
|
558
|
-
interface SdItemOfTemplateContext<TItem> {
|
|
559
|
-
$implicit: TItem;
|
|
560
|
-
item: TItem;
|
|
561
|
-
index: number;
|
|
562
|
-
depth: number;
|
|
563
|
-
}
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
| Field | Type | Description |
|
|
567
|
-
|-------|------|-------------|
|
|
568
|
-
| `$implicit` | `TItem` | Current item (default template variable) |
|
|
569
|
-
| `item` | `TItem` | Current item (named) |
|
|
570
|
-
| `index` | `number` | Item index |
|
|
571
|
-
| `depth` | `number` | Nesting depth (for tree structures) |
|
|
572
|
-
|
|
573
|
-
## `SdRouterLinkDirective`
|
|
574
|
-
|
|
575
|
-
Enhanced router link with support for Ctrl/Shift-click (new tab), window popup mode, and outlet navigation.
|
|
576
|
-
|
|
577
|
-
```typescript
|
|
578
|
-
@Directive({ standalone: true, selector: "[sd-router-link]" })
|
|
579
|
-
class SdRouterLinkDirective {
|
|
580
|
-
option: InputSignal<{
|
|
581
|
-
link: string;
|
|
582
|
-
params?: Record<string, string>;
|
|
583
|
-
window?: { width?: number; height?: number };
|
|
584
|
-
outletName?: string;
|
|
585
|
-
queryParams?: Record<string, string>;
|
|
586
|
-
} | undefined>; // alias: "sd-router-link"
|
|
587
|
-
}
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
## `FormatPipe`
|
|
591
|
-
|
|
592
|
-
Pipe that formats `DateTime`, `DateOnly`, or `string` values.
|
|
593
|
-
|
|
594
|
-
```typescript
|
|
595
|
-
@Pipe({ name: "format", standalone: true })
|
|
596
|
-
class FormatPipe implements PipeTransform {
|
|
597
|
-
transform(value: string | DateTime | DateOnly | undefined, format: string): string;
|
|
598
|
-
}
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
- `DateTime`/`DateOnly`: calls `toFormatString(format)`
|
|
602
|
-
- `string`: applies `X`-placeholder pattern matching (patterns separated by `|`)
|
|
603
|
-
- `undefined`: returns `""`
|
|
604
|
-
|
|
605
|
-
## `setSafeStyle`
|
|
606
|
-
|
|
607
|
-
Applies multiple CSS style properties at once via `Renderer2.setStyle`.
|
|
608
|
-
|
|
609
|
-
```typescript
|
|
610
|
-
function setSafeStyle(renderer: Renderer2, el: HTMLElement, style: Partial<CSSStyleDeclaration>): void;
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
## `setupBgTheme`
|
|
614
|
-
|
|
615
|
-
Sets the body `--background-color` CSS variable to a theme token during component lifetime.
|
|
616
|
-
|
|
617
|
-
```typescript
|
|
618
|
-
function setupBgTheme(options?: {
|
|
619
|
-
theme?: "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "gray" | "blue-gray";
|
|
620
|
-
lightness?: "lightest" | "lighter";
|
|
621
|
-
}): void;
|
|
622
|
-
```
|
|
623
|
-
|
|
624
|
-
## `setupRipple`
|
|
625
|
-
|
|
626
|
-
Attaches ripple effect event handlers to the current component's host element.
|
|
627
|
-
|
|
628
|
-
```typescript
|
|
629
|
-
function setupRipple(enableFn?: () => boolean): void;
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
## `setupRevealOnShow`
|
|
633
|
-
|
|
634
|
-
Applies an IntersectionObserver-driven entrance animation to the component host.
|
|
635
|
-
|
|
636
|
-
```typescript
|
|
637
|
-
function setupRevealOnShow(optFn?: () => { type?: "l2r" | "t2b"; enabled?: boolean }): void;
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
## `setupInvalid`
|
|
641
|
-
|
|
642
|
-
Injects a validation indicator and hidden input with custom validity into the host element.
|
|
643
|
-
|
|
644
|
-
```typescript
|
|
645
|
-
function setupInvalid(getInvalidMessage: () => string): void;
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
## `setupModelHook`
|
|
649
|
-
|
|
650
|
-
Intercepts `WritableSignal.set` to guard value changes with a sync or async predicate.
|
|
651
|
-
|
|
652
|
-
```typescript
|
|
653
|
-
function setupModelHook<T, S extends WritableSignal<T>>(model: S, canFn: Signal<(item: T) => boolean | Promise<boolean>>): void;
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
## `setupCanDeactivate`
|
|
657
|
-
|
|
658
|
-
Registers a deactivation guard on the current modal or route.
|
|
659
|
-
|
|
660
|
-
```typescript
|
|
661
|
-
function setupCanDeactivate(fn: () => boolean): void;
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
## `setupCumulateSelectedKeys`
|
|
665
|
-
|
|
666
|
-
Keeps `selectedItems` and `selectedItemKeys` in sync as the `items` list changes.
|
|
667
|
-
|
|
668
|
-
```typescript
|
|
669
|
-
function setupCumulateSelectedKeys<TItem, TKey>(options: {
|
|
670
|
-
items: Signal<TItem[]>;
|
|
671
|
-
selectedItems: WritableSignal<TItem[]>;
|
|
672
|
-
selectedItemKeys: WritableSignal<TKey[]>;
|
|
673
|
-
selectMode: () => "single" | "multi" | undefined;
|
|
674
|
-
keySelectorFn: (item: TItem) => TKey | undefined;
|
|
675
|
-
}): void;
|
|
676
|
-
```
|
|
677
|
-
|
|
678
|
-
## `setupCloserWhenSingleSelectionChange`
|
|
679
|
-
|
|
680
|
-
Auto-emits `close` when selection changes in single-select mode.
|
|
681
|
-
|
|
682
|
-
```typescript
|
|
683
|
-
function setupCloserWhenSingleSelectionChange<TItem, TKey>(options: {
|
|
684
|
-
selectedItemKeys: Signal<TKey[]>;
|
|
685
|
-
selectedItems: Signal<TItem[]>;
|
|
686
|
-
selectMode: () => "single" | "multi" | undefined;
|
|
687
|
-
close: OutputEmitterRef<{ selectedItemKeys: TKey[]; selectedItems: TItem[] }>;
|
|
688
|
-
}): void;
|
|
689
|
-
```
|
|
690
|
-
|
|
691
|
-
## `useSdSystemConfigResource`
|
|
692
|
-
|
|
693
|
-
Angular `resource` wrapper backed by `SdSystemConfigProvider`.
|
|
694
|
-
|
|
695
|
-
```typescript
|
|
696
|
-
function useSdSystemConfigResource<T>(options: {
|
|
697
|
-
key: Signal<string | undefined>;
|
|
698
|
-
}): {
|
|
699
|
-
value: Signal<T | undefined>;
|
|
700
|
-
isLoading: Signal<boolean>;
|
|
701
|
-
status: Signal<ResourceStatus>;
|
|
702
|
-
hasValue(): boolean;
|
|
703
|
-
reload(): void;
|
|
704
|
-
set(value: T): void;
|
|
705
|
-
update(fn: (prev: T | undefined) => T): void;
|
|
706
|
-
};
|
|
707
|
-
```
|
|
708
|
-
|
|
709
|
-
## `useCurrentPageCodeSignal`
|
|
710
|
-
|
|
711
|
-
Returns a signal with the current route's page code (dot-separated path segments).
|
|
712
|
-
|
|
713
|
-
```typescript
|
|
714
|
-
function useCurrentPageCodeSignal(): Signal<string> | undefined;
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
## `useFullPageCodeSignal`
|
|
718
|
-
|
|
719
|
-
Returns a signal with the full URL path converted to dot-separated page code. Updates on `NavigationEnd`.
|
|
720
|
-
|
|
721
|
-
```typescript
|
|
722
|
-
function useFullPageCodeSignal(): Signal<string>;
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
## `useViewTitleSignal`
|
|
726
|
-
|
|
727
|
-
Returns the current view title from modal or app structure.
|
|
728
|
-
|
|
729
|
-
```typescript
|
|
730
|
-
function useViewTitleSignal(): Signal<string>;
|
|
731
|
-
```
|
|
732
|
-
|
|
733
|
-
## `useViewTypeSignal`
|
|
734
|
-
|
|
735
|
-
Returns the current view context type.
|
|
736
|
-
|
|
737
|
-
```typescript
|
|
738
|
-
function useViewTypeSignal(getComp: () => object): Signal<TSdViewType>;
|
|
739
|
-
```
|
|
740
|
-
|
|
741
|
-
## `TSdViewType`
|
|
742
|
-
|
|
743
|
-
```typescript
|
|
744
|
-
type TSdViewType = "page" | "modal" | "control";
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
## `useExpandingManager`
|
|
748
|
-
|
|
749
|
-
Manages tree expand/collapse state for hierarchical item lists.
|
|
750
|
-
|
|
751
|
-
```typescript
|
|
752
|
-
function useExpandingManager<T>(binding: {
|
|
753
|
-
items: Signal<T[]>;
|
|
754
|
-
expandedItems: WritableSignal<T[]>;
|
|
755
|
-
getChildrenFn: Signal<((item: T, index: number) => T[] | undefined) | undefined>;
|
|
756
|
-
sort: (items: T[]) => T[];
|
|
757
|
-
}): {
|
|
758
|
-
displayItems: Signal<T[]>;
|
|
759
|
-
hasExpandable: Signal<boolean>;
|
|
760
|
-
isAllExpanded: Signal<boolean>;
|
|
761
|
-
toggle(item: T): void;
|
|
762
|
-
toggleAll(): void;
|
|
763
|
-
isVisible(item: T): boolean;
|
|
764
|
-
def(item: T): IExpandItemDef<T>;
|
|
765
|
-
};
|
|
766
|
-
```
|
|
767
|
-
|
|
768
|
-
## `IExpandItemDef`
|
|
769
|
-
|
|
770
|
-
```typescript
|
|
771
|
-
interface IExpandItemDef<T> {
|
|
772
|
-
item: T;
|
|
773
|
-
parentDef: IExpandItemDef<T> | undefined;
|
|
774
|
-
hasChildren: boolean;
|
|
775
|
-
depth: number;
|
|
776
|
-
}
|
|
777
|
-
```
|
|
778
|
-
|
|
779
|
-
| Field | Type | Description |
|
|
780
|
-
|-------|------|-------------|
|
|
781
|
-
| `item` | `T` | The data item |
|
|
782
|
-
| `parentDef` | `IExpandItemDef<T> \| undefined` | Parent node definition |
|
|
783
|
-
| `hasChildren` | `boolean` | Whether this node has children |
|
|
784
|
-
| `depth` | `number` | Nesting depth (0-based) |
|
|
785
|
-
|
|
786
|
-
## `useSelectionManager`
|
|
787
|
-
|
|
788
|
-
Manages item selection state with single/multi mode support.
|
|
789
|
-
|
|
790
|
-
```typescript
|
|
791
|
-
function useSelectionManager<T>(options: {
|
|
792
|
-
displayItems: Signal<T[]>;
|
|
793
|
-
selectedItems: WritableSignal<T[]>;
|
|
794
|
-
selectMode: Signal<"single" | "multi" | undefined>;
|
|
795
|
-
getItemSelectableFn: Signal<((item: T) => boolean | string) | undefined>;
|
|
796
|
-
}): {
|
|
797
|
-
hasSelectable: Signal<boolean>;
|
|
798
|
-
isAllSelected: Signal<boolean>;
|
|
799
|
-
getSelectable(item: T): true | string | undefined;
|
|
800
|
-
getCanChangeFn(item: T): () => boolean;
|
|
801
|
-
select(item: T): void;
|
|
802
|
-
deselect(item: T): void;
|
|
803
|
-
toggle(item: T): void;
|
|
804
|
-
toggleAll(): void;
|
|
805
|
-
isSelected(item: T): boolean;
|
|
806
|
-
};
|
|
807
|
-
```
|
|
808
|
-
|
|
809
|
-
## `useSortingManager`
|
|
810
|
-
|
|
811
|
-
Manages multi-column sorting state with toggle behavior.
|
|
812
|
-
|
|
813
|
-
```typescript
|
|
814
|
-
function useSortingManager(options: {
|
|
815
|
-
sorts: WritableSignal<ISortingDef[]>;
|
|
816
|
-
}): {
|
|
817
|
-
defMap: Signal<Map<string, { indexText?: string; desc: boolean }>>;
|
|
818
|
-
toggle(key: string, multiple: boolean): void;
|
|
819
|
-
sort<T>(items: T[]): T[];
|
|
820
|
-
};
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
- `toggle`: cycles none → asc → desc → remove. `multiple` preserves existing sorts.
|
|
824
|
-
- `sort`: sorts items by current `sorts` definitions. Strings use `localeCompare`; nulls sort first.
|
|
825
|
-
|
|
826
|
-
## `ISortingDef`
|
|
827
|
-
|
|
828
|
-
```typescript
|
|
829
|
-
interface ISortingDef {
|
|
830
|
-
key: string;
|
|
831
|
-
desc: boolean;
|
|
832
|
-
}
|
|
833
|
-
```
|
|
834
|
-
|
|
835
|
-
| Field | Type | Description |
|
|
836
|
-
|-------|------|-------------|
|
|
837
|
-
| `key` | `string` | Property name to sort by |
|
|
838
|
-
| `desc` | `boolean` | Descending order when `true` |
|
|
839
|
-
|
|
840
|
-
## `injectParent`
|
|
841
|
-
|
|
842
|
-
Traverses the Angular component tree to find a parent component instance.
|
|
843
|
-
|
|
844
|
-
```typescript
|
|
845
|
-
function injectParent(): unknown;
|
|
846
|
-
function injectParent<T>(type: AbstractType<T>): T;
|
|
847
|
-
function injectParent<T>(type: AbstractType<T>, options: { optional: true }): T | undefined;
|
|
848
|
-
```
|
|
849
|
-
|
|
850
|
-
## `TDirectiveInputSignals`
|
|
851
|
-
|
|
852
|
-
Extracts input signal value types from a component/directive class, converting `undefined`-accepting inputs to optional properties.
|
|
853
|
-
|
|
854
|
-
```typescript
|
|
855
|
-
type TDirectiveInputSignals<T> = /* mapped type extracting InputSignal value types with TUndefToOptional */;
|
|
856
|
-
```
|
|
857
|
-
|
|
858
|
-
Example: `{ name = input.required<string>(); age = input(0) }` → `{ name: string; age: number }`
|
|
859
|
-
|
|
860
|
-
## `TUndefToOptional`
|
|
861
|
-
|
|
862
|
-
Converts properties whose type includes `undefined` to optional properties.
|
|
863
|
-
|
|
864
|
-
```typescript
|
|
865
|
-
type TUndefToOptional<T> = /* { a: string; b: number | undefined } → { a: string; b?: number } */;
|
|
866
|
-
```
|
|
867
|
-
|
|
868
|
-
## `TWithOptional`
|
|
869
|
-
|
|
870
|
-
Converts specified keys of a type to optional.
|
|
871
|
-
|
|
872
|
-
```typescript
|
|
873
|
-
type TWithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
874
|
-
```
|
|
875
|
-
|
|
876
|
-
## `withBusy`
|
|
877
|
-
|
|
878
|
-
Wraps an async function with a busy signal increment/decrement. Increments `busyCount` before execution and decrements in `finally`.
|
|
879
|
-
|
|
880
|
-
```typescript
|
|
881
|
-
async function withBusy(
|
|
882
|
-
busyCount: WritableSignal<number>,
|
|
883
|
-
fn: () => Promise<void>,
|
|
884
|
-
): Promise<void>;
|
|
885
|
-
```
|
|
886
|
-
|
|
887
|
-
## `mark`
|
|
888
|
-
|
|
889
|
-
Manually notifies signal consumers of a change. Useful when an object/array is mutated in place rather than replaced.
|
|
890
|
-
|
|
891
|
-
```typescript
|
|
892
|
-
function mark(sig: WritableSignal<any>, clone?: boolean): void;
|
|
893
|
-
```
|
|
894
|
-
|
|
895
|
-
| Parameter | Type | Description |
|
|
896
|
-
|-----------|------|-------------|
|
|
897
|
-
| `sig` | `WritableSignal<any>` | The signal to mark as changed |
|
|
898
|
-
| `clone` | `boolean` (optional) | If `true`, performs a shallow clone via `update()` (array spread or object spread). If `false`/omitted, directly increments the signal version using Angular internal primitives (`producerIncrementEpoch`, `producerNotifyConsumers`). |
|
|
899
|
-
|
|
900
|
-
## `setupModelHook`
|
|
901
|
-
|
|
902
|
-
Intercepts a `WritableSignal.set` to guard value changes with a sync/async predicate.
|
|
903
|
-
|
|
904
|
-
```typescript
|
|
905
|
-
function setupModelHook<T, S extends WritableSignal<T>>(
|
|
906
|
-
model: S,
|
|
907
|
-
canFn: Signal<(item: T) => boolean | Promise<boolean>>,
|
|
908
|
-
): void;
|
|
909
|
-
```
|