@yuuvis/client-framework 2.6.3 → 2.7.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/common/lib/components/busy-overlay/busy-overlay.component.d.ts +0 -1
- package/fesm2022/yuuvis-client-framework-common.mjs +1 -4
- package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-forms.mjs +7 -4
- package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-list.mjs +92 -58
- package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs +2 -2
- package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-object-versions.mjs +1 -1
- package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-query-list.mjs +269 -0
- package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -0
- package/fesm2022/yuuvis-client-framework-tile-list.mjs +83 -202
- package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework-tree.mjs +8 -5
- package/fesm2022/yuuvis-client-framework-tree.mjs.map +1 -1
- package/fesm2022/yuuvis-client-framework.mjs +716 -160
- package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
- package/lib/config/halo-focus-defaults/halo-excluded-elements.const.d.ts +26 -0
- package/lib/config/halo-focus-defaults/halo-focus-navigation-keys.const.d.ts +25 -0
- package/lib/config/halo-focus-defaults/halo-focus-offset.const.d.ts +25 -0
- package/lib/config/halo-focus-defaults/halo-focus-styles.const.d.ts +26 -0
- package/lib/config/halo-focus-defaults/index.d.ts +4 -0
- package/lib/config/index.d.ts +1 -0
- package/lib/models/halo-focus-config/halo-focus-config.model.d.ts +48 -0
- package/lib/models/halo-focus-config/index.d.ts +1 -0
- package/lib/models/index.d.ts +1 -0
- package/lib/providers/halo-focus/index.d.ts +1 -0
- package/lib/providers/halo-focus/provide-halo-focus.d.ts +58 -6
- package/lib/providers/index.d.ts +1 -1
- package/lib/services/halo-focus/halo-focus.service.d.ts +80 -17
- package/lib/services/halo-utility/halo-utility.service.d.ts +230 -0
- package/lib/services/index.d.ts +1 -0
- package/list/lib/list.component.d.ts +35 -6
- package/package.json +19 -15
- package/query-list/README.md +3 -0
- package/query-list/index.d.ts +2 -0
- package/query-list/lib/query-list.component.d.ts +139 -0
- package/query-list/lib/query-list.module.d.ts +7 -0
- package/tile-list/lib/tile-list/tile-list.component.d.ts +52 -34
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { HaloFocusConfig } from '../../models';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Utility service providing helper methods for the Halo Focus feature.
|
|
5
|
+
*
|
|
6
|
+
* This service contains pure utility functions for:
|
|
7
|
+
* - Element validation (focusability, visibility, focus-visible state)
|
|
8
|
+
* - Material form field detection and exclusion logic
|
|
9
|
+
* - Style calculations (colors, offsets, positioning)
|
|
10
|
+
* - DOM traversal (finding halo containers, checking parent visibility)
|
|
11
|
+
* - Halo element manipulation (size, color, position)
|
|
12
|
+
*
|
|
13
|
+
* **Scope & Performance:**
|
|
14
|
+
* This service is intentionally NOT provided in root (`providedIn: 'root'` is omitted).
|
|
15
|
+
* Instead, it's provided locally via `provideHaloFocus()`, ensuring it's only instantiated
|
|
16
|
+
* when the Halo Focus feature is actually used. This optimization prevents unnecessary
|
|
17
|
+
* service creation in applications that don't use halo focus.
|
|
18
|
+
*
|
|
19
|
+
* **Note:** This service is used exclusively by `HaloFocusService` and should not be
|
|
20
|
+
* injected or used elsewhere in the application.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export declare class HaloUtilityService {
|
|
25
|
+
/**
|
|
26
|
+
* Checks if an element is focusable (can receive keyboard focus).
|
|
27
|
+
*
|
|
28
|
+
* An element is considered focusable if:
|
|
29
|
+
* - It has a non-negative tabIndex (>= 0), OR
|
|
30
|
+
* - It's a natively focusable element (A, BUTTON, INPUT, SELECT, TEXTAREA), OR
|
|
31
|
+
* - It has contentEditable enabled
|
|
32
|
+
*
|
|
33
|
+
* @param element - Element to check
|
|
34
|
+
* @returns true if element can receive focus, false otherwise
|
|
35
|
+
*/
|
|
36
|
+
isFocusable(element: Element | null): element is HTMLElement;
|
|
37
|
+
/**
|
|
38
|
+
* Checks if an element is inside a Material form field (mat-form-field).
|
|
39
|
+
*
|
|
40
|
+
* Traverses up the DOM tree from the element to check if any parent
|
|
41
|
+
* has the `mat-form-field` tag name. This is used to determine if
|
|
42
|
+
* certain elements should skip halo focus because they're already
|
|
43
|
+
* styled by Angular Material.
|
|
44
|
+
*
|
|
45
|
+
* **Search Scope:**
|
|
46
|
+
* - Starts from element itself
|
|
47
|
+
* - Stops at document.body
|
|
48
|
+
* - Returns true on first mat-form-field match
|
|
49
|
+
*
|
|
50
|
+
* @param element - The element to check
|
|
51
|
+
* @returns true if element is inside a mat-form-field, false otherwise
|
|
52
|
+
*/
|
|
53
|
+
isElementInsideMatFormField(element: HTMLElement): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Determines if an element should be excluded from halo focus when inside mat-form-field.
|
|
56
|
+
*
|
|
57
|
+
* Checks two conditions:
|
|
58
|
+
* 1. Element tag name matches one of the excluded selectors (input, mat-select, etc.)
|
|
59
|
+
* 2. Element is inside a mat-form-field component
|
|
60
|
+
*
|
|
61
|
+
* If both conditions are true, the element should skip halo focus because
|
|
62
|
+
* Angular Material already provides adequate focus styling.
|
|
63
|
+
*
|
|
64
|
+
* **Excluded Elements (configurable via haloExcludedElementsInMatFormField):**
|
|
65
|
+
* - `input` elements inside mat-form-field
|
|
66
|
+
* - `textarea` elements inside mat-form-field
|
|
67
|
+
* - `mat-select` elements inside mat-form-field
|
|
68
|
+
*
|
|
69
|
+
* **Note:** Elements outside mat-form-field will NOT be skipped, even if
|
|
70
|
+
* their tag matches the exclusion list.
|
|
71
|
+
*
|
|
72
|
+
* @param element - The focused element to check
|
|
73
|
+
* @returns true if element should be skipped (no halo), false if halo should be shown
|
|
74
|
+
*/
|
|
75
|
+
shouldSkipElementInMatFormField(element: HTMLElement): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Determines if an element should display the halo based on :focus-visible state.
|
|
78
|
+
*
|
|
79
|
+
* This method respects the CSS :focus-visible pseudo-class, which indicates that
|
|
80
|
+
* focus was triggered by keyboard navigation (not mouse clicks). The halo only appears
|
|
81
|
+
* when both conditions are met:
|
|
82
|
+
* 1. Element matches :focus-visible (browser determines this)
|
|
83
|
+
* 2. Last user interaction was via keyboard (tracked by service)
|
|
84
|
+
*
|
|
85
|
+
* **Fallback:** If browser doesn't support :focus-visible, falls back to checking
|
|
86
|
+
* lastInteractionWasKeyboard only.
|
|
87
|
+
*
|
|
88
|
+
* @param element - The currently focused element
|
|
89
|
+
* @param lastInteractionWasKeyboard - Whether the last interaction was a keyboard event
|
|
90
|
+
* @returns true if halo should be visible, false otherwise
|
|
91
|
+
*/
|
|
92
|
+
matchesFocusVisible(element: HTMLElement, lastInteractionWasKeyboard: boolean): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Checks if an element is actually visible on the page.
|
|
95
|
+
*
|
|
96
|
+
* Performs comprehensive visibility checks including:
|
|
97
|
+
* - Element has non-zero dimensions (width and height > 0)
|
|
98
|
+
* - Element is not hidden via CSS (display: none, visibility: hidden, opacity: 0)
|
|
99
|
+
* - Element is not clipped by parent containers with overflow: hidden/clip
|
|
100
|
+
* - All parent elements in the hierarchy are visible
|
|
101
|
+
*
|
|
102
|
+
* This prevents the halo from appearing around technically focused but visually
|
|
103
|
+
* hidden elements (e.g., elements in collapsed sections, off-screen elements).
|
|
104
|
+
*
|
|
105
|
+
* @param element - Element to check for visibility
|
|
106
|
+
* @returns true if element is visible to the user, false otherwise
|
|
107
|
+
*/
|
|
108
|
+
isElementVisible(element: HTMLElement): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Recursively checks if all parent elements are visible and not clipping the target element.
|
|
111
|
+
*
|
|
112
|
+
* Traverses up the DOM tree from the element to document.body, checking each parent for:
|
|
113
|
+
* - Hidden state (display: none, visibility: hidden, opacity: 0)
|
|
114
|
+
* - Overflow clipping (overflow: hidden/clip) that completely hides the element
|
|
115
|
+
*
|
|
116
|
+
* If any parent has overflow clipping, calculates the visible intersection area.
|
|
117
|
+
* Returns false if element is completely clipped (no visible area).
|
|
118
|
+
*
|
|
119
|
+
* @param element - The element whose parents should be checked
|
|
120
|
+
* @param rect - The bounding rectangle of the element
|
|
121
|
+
* @returns true if element has visible area within all parent containers, false otherwise
|
|
122
|
+
*/
|
|
123
|
+
isParentVisible(element: HTMLElement, rect: DOMRect): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Generates the complete CSS styles for the halo element, merging defaults with custom config.
|
|
126
|
+
*
|
|
127
|
+
* Takes the base styles from `haloFocusStyles` constant and overrides specific properties
|
|
128
|
+
* if custom configuration is provided. This allows global style customization while
|
|
129
|
+
* maintaining all required base styles.
|
|
130
|
+
*
|
|
131
|
+
* **Configurable Properties:**
|
|
132
|
+
* - Inner color (via config.innerColor)
|
|
133
|
+
* - Outer color (via config.outerColor)
|
|
134
|
+
*
|
|
135
|
+
* **Non-configurable Properties:**
|
|
136
|
+
* - position, pointerEvents, zIndex, opacity, transform (always use defaults)
|
|
137
|
+
*
|
|
138
|
+
* @param config - Optional global configuration object
|
|
139
|
+
* @returns Complete CSS style declaration object for the halo element
|
|
140
|
+
*/
|
|
141
|
+
getHaloFocusStyles(config?: HaloFocusConfig): Partial<CSSStyleDeclaration>;
|
|
142
|
+
/**
|
|
143
|
+
* Finds the nearest parent element marked as a halo container.
|
|
144
|
+
*
|
|
145
|
+
* Traverses up the DOM tree looking for an element with the `halo-container` attribute.
|
|
146
|
+
* Container elements can define default halo styles (color, offset) that apply to all
|
|
147
|
+
* their focused children, unless overridden by child-specific halo-* attributes.
|
|
148
|
+
*
|
|
149
|
+
* **Search Scope:**
|
|
150
|
+
* - Starts from element's immediate parent
|
|
151
|
+
* - Stops at document.body (does not check body itself)
|
|
152
|
+
* - Returns first matching ancestor
|
|
153
|
+
*
|
|
154
|
+
* @param element - The focused element to search from
|
|
155
|
+
* @returns The nearest halo container element, or null if none found
|
|
156
|
+
*/
|
|
157
|
+
getHaloContainer(element: HTMLElement): HTMLElement | null;
|
|
158
|
+
/**
|
|
159
|
+
* Converts any CSS color format to rgba with specified alpha transparency.
|
|
160
|
+
*
|
|
161
|
+
* Handles multiple color formats:
|
|
162
|
+
* - **rgba**: Replaces existing alpha value
|
|
163
|
+
* - **rgb**: Converts to rgba by appending alpha
|
|
164
|
+
* - **Hex** (#RRGGBB): Converts to rgba format
|
|
165
|
+
* - **Named colors**: Uses modern CSS `color-mix` function with alpha
|
|
166
|
+
*
|
|
167
|
+
* Used internally to create outer colors with reduced opacity from inner colors.
|
|
168
|
+
*
|
|
169
|
+
* @param color - CSS color in any valid format (rgba, rgb, hex, named)
|
|
170
|
+
* @param alpha - Alpha transparency value (0-1)
|
|
171
|
+
* @returns Color in rgba format with specified alpha
|
|
172
|
+
*/
|
|
173
|
+
getColorWithAlpha(color: string, alpha: number): string;
|
|
174
|
+
/**
|
|
175
|
+
* Calculates the offset (distance) between the halo border and element edges.
|
|
176
|
+
*
|
|
177
|
+
* Determines offset using the following priority order:
|
|
178
|
+
* 1. **Element's own attributes** (highest priority):
|
|
179
|
+
* - `halo-offset="value"` - Custom numeric value
|
|
180
|
+
* 2. **Parent container attributes** (if element has no offset):
|
|
181
|
+
* - `halo-container-offset="value"`
|
|
182
|
+
* 3. **Default offset** (if nothing specified): 3px
|
|
183
|
+
*
|
|
184
|
+
* @param element - The focused element to calculate offset for
|
|
185
|
+
* @returns Offset value in pixels
|
|
186
|
+
*/
|
|
187
|
+
getTargetOffset(element: HTMLElement | null): number;
|
|
188
|
+
/**
|
|
189
|
+
* Applies custom color styling to the halo element based on element or container attributes.
|
|
190
|
+
*
|
|
191
|
+
* Color resolution priority:
|
|
192
|
+
* 1. **Element's own color**: `halo-color="color"` attribute (highest priority)
|
|
193
|
+
* 2. **Container's color**: `halo-container-color="color"` from nearest halo container
|
|
194
|
+
* 3. **Default color**: From global config or base styles (if no custom color found)
|
|
195
|
+
*
|
|
196
|
+
* When custom color is found:
|
|
197
|
+
* - Sets inner color (2px solid border) with the custom color
|
|
198
|
+
* - Sets outer color (shadow) to match, with 20% alpha transparency for subtle depth
|
|
199
|
+
*
|
|
200
|
+
* When no custom color:
|
|
201
|
+
* - Resets to default styles from config or haloFocusStyles constant
|
|
202
|
+
*
|
|
203
|
+
* @param element - The focused element (checked for halo-color attribute)
|
|
204
|
+
* @param haloElement - The halo DIV element to apply styles to
|
|
205
|
+
* @param config - Optional global config for default colors
|
|
206
|
+
*/
|
|
207
|
+
setCustomColor(element: HTMLElement, haloElement: HTMLDivElement, config?: HaloFocusConfig): void;
|
|
208
|
+
/**
|
|
209
|
+
* Positions and sizes the halo element to surround the focused element.
|
|
210
|
+
*
|
|
211
|
+
* Calculates halo dimensions and position based on:
|
|
212
|
+
* - Element's bounding rectangle (viewport-relative position)
|
|
213
|
+
* - Calculated offset from getTargetOffset() (custom or default)
|
|
214
|
+
* - Element's border-radius for matching rounded corners
|
|
215
|
+
*
|
|
216
|
+
* **Calculation Details:**
|
|
217
|
+
* - Position: Element's top/left minus offset (for outside positioning)
|
|
218
|
+
* - Size: Element's width/height plus 2× offset (to extend on all sides)
|
|
219
|
+
* - Border radius: Inherited from focused element's computed style
|
|
220
|
+
*
|
|
221
|
+
* Uses Math.floor for position and Math.ceil for dimensions to prevent
|
|
222
|
+
* subpixel rendering issues and ensure full element coverage.
|
|
223
|
+
*
|
|
224
|
+
* @param currentElement - The currently focused element to surround
|
|
225
|
+
* @param haloElement - The halo DIV element to position and size
|
|
226
|
+
*/
|
|
227
|
+
setHaloElementSize(currentElement: HTMLElement, haloElement: HTMLDivElement): void;
|
|
228
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<HaloUtilityService, never>;
|
|
229
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<HaloUtilityService>;
|
|
230
|
+
}
|
package/lib/services/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { BooleanInput } from '@angular/cdk/coercion';
|
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
/**
|
|
6
6
|
* Component rendering a simple list of items. It supports keyboard
|
|
7
|
-
* navigation
|
|
7
|
+
* navigation and takes care of accessibility. To create a list just wrap
|
|
8
8
|
* `yuvListItem` elements into this component:
|
|
9
9
|
*
|
|
10
10
|
* ```html
|
|
@@ -19,12 +19,16 @@ export declare class ListComponent implements AfterContentInit, OnDestroy {
|
|
|
19
19
|
onKeydown(event: KeyboardEvent): void;
|
|
20
20
|
onFocus(): void;
|
|
21
21
|
items: import("@angular/core").Signal<readonly ListItemDirective[]>;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Function that returns `true` if selection changes should be prevented.
|
|
24
|
+
* This can be used to temporarily block selection changes, e.g. while
|
|
25
|
+
* there is a pending change inside another component that refers to the
|
|
26
|
+
* current selection.
|
|
27
|
+
*/
|
|
25
28
|
preventChangeUntil: import("@angular/core").InputSignal<() => boolean>;
|
|
26
29
|
/**
|
|
27
30
|
* If `true`, multiple items can be selected at once.
|
|
31
|
+
* @default false
|
|
28
32
|
*/
|
|
29
33
|
multiselect: import("@angular/core").InputSignal<boolean>;
|
|
30
34
|
/**
|
|
@@ -35,10 +39,26 @@ export declare class ListComponent implements AfterContentInit, OnDestroy {
|
|
|
35
39
|
* @default false
|
|
36
40
|
*/
|
|
37
41
|
selfHandleSelection: import("@angular/core").InputSignal<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* By default the list handles click events on its items to select them.
|
|
44
|
+
* If this input is set to `true`, the parent component has to handle
|
|
45
|
+
* click events itself and call the `select()` method accordingly.
|
|
46
|
+
*
|
|
47
|
+
* If you for example use the `ClickDoubleDirective` on the list items,
|
|
48
|
+
* you have to set this input to `true` to prevent the list from
|
|
49
|
+
* selecting items on single click.
|
|
50
|
+
* @default false
|
|
51
|
+
*/
|
|
52
|
+
selfHandleClick: import("@angular/core").InputSignal<boolean>;
|
|
53
|
+
/**
|
|
54
|
+
* If `true`, the list will select an item automatically on initialization.
|
|
55
|
+
* First, list will search for an item item that has the "selected"-attribute
|
|
56
|
+
* and is not disabled. If no such item exists, the first item will be selected.
|
|
57
|
+
* @default false
|
|
58
|
+
*/
|
|
38
59
|
autoSelect: import("@angular/core").InputSignalWithTransform<boolean, BooleanInput>;
|
|
39
60
|
/**
|
|
40
61
|
* Emits the selected items indices.
|
|
41
|
-
* @type {output<number[]>}
|
|
42
62
|
*/
|
|
43
63
|
itemSelect: import("@angular/core").OutputEmitterRef<number[]>;
|
|
44
64
|
/**
|
|
@@ -54,7 +74,16 @@ export declare class ListComponent implements AfterContentInit, OnDestroy {
|
|
|
54
74
|
*/
|
|
55
75
|
disableSelection: import("@angular/core").InputSignal<boolean>;
|
|
56
76
|
focus(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Select multiple items by their indices.
|
|
79
|
+
*/
|
|
57
80
|
multiSelect(index: number[]): void;
|
|
81
|
+
/**
|
|
82
|
+
* Selects a single item by its index.
|
|
83
|
+
* @param index Index of the item to select.
|
|
84
|
+
* @param shiftKey If `true`, selection will be extended from the last selected item to the given index.
|
|
85
|
+
* @param ctrlKey If `true`, the item at the given index will be toggled in the selection.
|
|
86
|
+
*/
|
|
58
87
|
select(index: number, shiftKey?: boolean, ctrlKey?: boolean): void;
|
|
59
88
|
/**
|
|
60
89
|
* Clear the current selection.
|
|
@@ -64,5 +93,5 @@ export declare class ListComponent implements AfterContentInit, OnDestroy {
|
|
|
64
93
|
ngAfterContentInit(): void;
|
|
65
94
|
ngOnDestroy(): void;
|
|
66
95
|
static ɵfac: i0.ɵɵFactoryDeclaration<ListComponent, never>;
|
|
67
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ListComponent, "yuv-list", never, { "preventChangeUntil": { "alias": "preventChangeUntil"; "required": false; "isSignal": true; }; "multiselect": { "alias": "multiselect"; "required": false; "isSignal": true; }; "selfHandleSelection": { "alias": "selfHandleSelection"; "required": false; "isSignal": true; }; "autoSelect": { "alias": "autoSelect"; "required": false; "isSignal": true; }; "disableSelection": { "alias": "disableSelection"; "required": false; "isSignal": true; }; }, { "itemSelect": "itemSelect"; "itemFocus": "itemFocus"; }, ["items"], ["*"], true, never>;
|
|
96
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ListComponent, "yuv-list", never, { "preventChangeUntil": { "alias": "preventChangeUntil"; "required": false; "isSignal": true; }; "multiselect": { "alias": "multiselect"; "required": false; "isSignal": true; }; "selfHandleSelection": { "alias": "selfHandleSelection"; "required": false; "isSignal": true; }; "selfHandleClick": { "alias": "selfHandleClick"; "required": false; "isSignal": true; }; "autoSelect": { "alias": "autoSelect"; "required": false; "isSignal": true; }; "disableSelection": { "alias": "disableSelection"; "required": false; "isSignal": true; }; }, { "itemSelect": "itemSelect"; "itemFocus": "itemFocus"; }, ["items"], ["*"], true, never>;
|
|
68
97
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuuvis/client-framework",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"author": "OPTIMAL SYSTEMS GmbH <npm@optimal-systems.de>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
"@angular/common": "^19.2.1",
|
|
9
9
|
"@angular/core": "^19.2.1",
|
|
10
10
|
"angular-gridster2": "^19.0.0",
|
|
11
|
-
"@yuuvis/client-core": "^2.
|
|
12
|
-
"@yuuvis/client-shell-core": "^2.
|
|
11
|
+
"@yuuvis/client-core": "^2.7.0",
|
|
12
|
+
"@yuuvis/client-shell-core": "^2.7.0",
|
|
13
13
|
"ng-dynamic-component": "^10.8.2",
|
|
14
14
|
"modern-normalize": "^3.0.1"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@angular/material": "^19.2.15",
|
|
18
18
|
"@ngrx/signals": "^19.2.0",
|
|
19
|
-
"@yuuvis/material": "2.
|
|
19
|
+
"@yuuvis/material": "2.7.0",
|
|
20
20
|
"@yuuvis/media-viewer": "^2.0.12",
|
|
21
21
|
"angular-split": "^19.0.0",
|
|
22
22
|
"vis-network": "^10.0.2",
|
|
@@ -108,14 +108,14 @@
|
|
|
108
108
|
"types": "./object-versions/index.d.ts",
|
|
109
109
|
"default": "./fesm2022/yuuvis-client-framework-object-versions.mjs"
|
|
110
110
|
},
|
|
111
|
-
"./overflow-menu": {
|
|
112
|
-
"types": "./overflow-menu/index.d.ts",
|
|
113
|
-
"default": "./fesm2022/yuuvis-client-framework-overflow-menu.mjs"
|
|
114
|
-
},
|
|
115
111
|
"./overflow-hidden": {
|
|
116
112
|
"types": "./overflow-hidden/index.d.ts",
|
|
117
113
|
"default": "./fesm2022/yuuvis-client-framework-overflow-hidden.mjs"
|
|
118
114
|
},
|
|
115
|
+
"./overflow-menu": {
|
|
116
|
+
"types": "./overflow-menu/index.d.ts",
|
|
117
|
+
"default": "./fesm2022/yuuvis-client-framework-overflow-menu.mjs"
|
|
118
|
+
},
|
|
119
119
|
"./pagination": {
|
|
120
120
|
"types": "./pagination/index.d.ts",
|
|
121
121
|
"default": "./fesm2022/yuuvis-client-framework-pagination.mjs"
|
|
@@ -124,6 +124,10 @@
|
|
|
124
124
|
"types": "./popout/index.d.ts",
|
|
125
125
|
"default": "./fesm2022/yuuvis-client-framework-popout.mjs"
|
|
126
126
|
},
|
|
127
|
+
"./query-list": {
|
|
128
|
+
"types": "./query-list/index.d.ts",
|
|
129
|
+
"default": "./fesm2022/yuuvis-client-framework-query-list.mjs"
|
|
130
|
+
},
|
|
127
131
|
"./renderer": {
|
|
128
132
|
"types": "./renderer/index.d.ts",
|
|
129
133
|
"default": "./fesm2022/yuuvis-client-framework-renderer.mjs"
|
|
@@ -140,22 +144,22 @@
|
|
|
140
144
|
"types": "./sort/index.d.ts",
|
|
141
145
|
"default": "./fesm2022/yuuvis-client-framework-sort.mjs"
|
|
142
146
|
},
|
|
143
|
-
"./tile-list": {
|
|
144
|
-
"types": "./tile-list/index.d.ts",
|
|
145
|
-
"default": "./fesm2022/yuuvis-client-framework-tile-list.mjs"
|
|
146
|
-
},
|
|
147
147
|
"./split-view": {
|
|
148
148
|
"types": "./split-view/index.d.ts",
|
|
149
149
|
"default": "./fesm2022/yuuvis-client-framework-split-view.mjs"
|
|
150
150
|
},
|
|
151
|
-
"./
|
|
152
|
-
"types": "./
|
|
153
|
-
"default": "./fesm2022/yuuvis-client-framework-
|
|
151
|
+
"./tile-list": {
|
|
152
|
+
"types": "./tile-list/index.d.ts",
|
|
153
|
+
"default": "./fesm2022/yuuvis-client-framework-tile-list.mjs"
|
|
154
154
|
},
|
|
155
155
|
"./tree": {
|
|
156
156
|
"types": "./tree/index.d.ts",
|
|
157
157
|
"default": "./fesm2022/yuuvis-client-framework-tree.mjs"
|
|
158
158
|
},
|
|
159
|
+
"./upload-progress": {
|
|
160
|
+
"types": "./upload-progress/index.d.ts",
|
|
161
|
+
"default": "./fesm2022/yuuvis-client-framework-upload-progress.mjs"
|
|
162
|
+
},
|
|
159
163
|
"./widget-grid": {
|
|
160
164
|
"types": "./widget-grid/index.d.ts",
|
|
161
165
|
"default": "./fesm2022/yuuvis-client-framework-widget-grid.mjs"
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { TemplateRef } from '@angular/core';
|
|
2
|
+
import { PageEvent } from '@angular/material/paginator';
|
|
3
|
+
import { SearchQuery, SearchResultItem } from '@yuuvis/client-core';
|
|
4
|
+
import { ListComponent } from '@yuuvis/client-framework/list';
|
|
5
|
+
import { Pagination } from '@yuuvis/client-framework/pagination';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/**
|
|
8
|
+
* Component to display a list of items based on a search query.
|
|
9
|
+
* It will execute the query and render the results using the provided item template.
|
|
10
|
+
*
|
|
11
|
+
* The component supports pagination, multi-selection, and drag selection.
|
|
12
|
+
*
|
|
13
|
+
* If you don't provide a transformer function, the raw SearchResultItem objects will be
|
|
14
|
+
* used as items and passed to the template. The transformer function allows you to map
|
|
15
|
+
* the SearchResultItem objects to a custom format before rendering.
|
|
16
|
+
*
|
|
17
|
+
* Example usage:
|
|
18
|
+
* ```html
|
|
19
|
+
* <yuv-query-list [transformer]="transformResult" [query]="query" (itemSelect)="onItemSelect($event)">
|
|
20
|
+
|
|
21
|
+
<!-- template used to render result item -->
|
|
22
|
+
<ng-template #yuvQueryListItem let-item>
|
|
23
|
+
<yuv-list-tile>
|
|
24
|
+
<ng-template #titleSlot>{{ item.id }}</ng-template>
|
|
25
|
+
<ng-template #descriptionSlot>{{ item.modified }}</ng-template>
|
|
26
|
+
</yuv-list-tile>
|
|
27
|
+
</ng-template>
|
|
28
|
+
|
|
29
|
+
<!-- Content to display when the list is empty -->
|
|
30
|
+
<ng-template #yuvQueryListEmpty>
|
|
31
|
+
<div>No documents found.</div>
|
|
32
|
+
</ng-template>
|
|
33
|
+
|
|
34
|
+
</yuv-query-list>
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* @Component({...})
|
|
39
|
+
* export class TestQueryListComponent {
|
|
40
|
+
* query = 'SELECT * FROM system:document';
|
|
41
|
+
*
|
|
42
|
+
* transformResult = (items: SearchResultItem[]) =>
|
|
43
|
+
* items.map((item) => ({
|
|
44
|
+
* id: item.fields.get(BaseObjectTypeField.OBJECT_ID),
|
|
45
|
+
* modified: item.fields.get(BaseObjectTypeField.MODIFICATION_DATE)
|
|
46
|
+
* }));
|
|
47
|
+
* } *
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare class QueryListComponent {
|
|
51
|
+
#private;
|
|
52
|
+
list: import("@angular/core").Signal<ListComponent>;
|
|
53
|
+
itemTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
54
|
+
emptyTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
|
|
55
|
+
isTouchDevice: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* The query to execute (SearchQuery object or CMIS query string).
|
|
58
|
+
*/
|
|
59
|
+
query: import("@angular/core").InputSignal<string | SearchQuery | null | undefined>;
|
|
60
|
+
/**
|
|
61
|
+
* Optional transformer function to map SearchResultItem to a custom format.
|
|
62
|
+
*/
|
|
63
|
+
transformer: import("@angular/core").InputSignal<((items: SearchResultItem[]) => unknown[]) | null | undefined>;
|
|
64
|
+
/**
|
|
65
|
+
* Function that returns `true` if selection changes should be prevented.
|
|
66
|
+
* This can be used to temporarily block selection changes, e.g. while
|
|
67
|
+
* there is a pending change inside another component that refers to the
|
|
68
|
+
* current selection.
|
|
69
|
+
*/
|
|
70
|
+
preventChangeUntil: import("@angular/core").InputSignal<() => boolean>;
|
|
71
|
+
/**
|
|
72
|
+
* Event emitted when items are selected. Emits an array of selected item indices.
|
|
73
|
+
*
|
|
74
|
+
*/
|
|
75
|
+
itemSelect: import("@angular/core").OutputEmitterRef<number[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Event emitted during drag selection, providing the current selection of item indices.
|
|
78
|
+
*/
|
|
79
|
+
dragSelectChange: import("@angular/core").OutputEmitterRef<number[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Event emitted when an item is double-clicked, providing the index of the item.
|
|
82
|
+
*/
|
|
83
|
+
itemDoubleClick: import("@angular/core").OutputEmitterRef<number>;
|
|
84
|
+
/**
|
|
85
|
+
* Event emitted when the query result is available, providing total count of items.
|
|
86
|
+
*/
|
|
87
|
+
queryResult: import("@angular/core").OutputEmitterRef<{
|
|
88
|
+
totalCount: number;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* The list of result items after applying the optional transformer.
|
|
92
|
+
*/
|
|
93
|
+
resultItems: import("@angular/core").Signal<unknown[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Number of items to fetch per page when executing the query.
|
|
96
|
+
* @default SearchService.DEFAULT_QUERY_SIZE
|
|
97
|
+
*/
|
|
98
|
+
pageSize: import("@angular/core").InputSignal<number>;
|
|
99
|
+
/**
|
|
100
|
+
* Enables or disables drag selection of items. If `true`, users can select multiple items by dragging the mouse.
|
|
101
|
+
* @default true
|
|
102
|
+
*/
|
|
103
|
+
enableDragSelect: import("@angular/core").InputSignal<boolean>;
|
|
104
|
+
/**
|
|
105
|
+
* Sets up the ability to select multiple tiles
|
|
106
|
+
* @default false
|
|
107
|
+
*/
|
|
108
|
+
multiselect: import("@angular/core").InputSignal<boolean>;
|
|
109
|
+
/**
|
|
110
|
+
* If `true`, the component will handle selection itself. This means that
|
|
111
|
+
* the parent component will be responsible for styling the selected and
|
|
112
|
+
* focused items. If `false`, the component will take care of visualizing
|
|
113
|
+
* the selection and focus states.
|
|
114
|
+
* @default false
|
|
115
|
+
*/
|
|
116
|
+
selfHandleSelection: import("@angular/core").InputSignal<boolean>;
|
|
117
|
+
/**
|
|
118
|
+
* Indicator signal whether a query is currently being executed.
|
|
119
|
+
* You could use this to show a loading indicator in the UI.
|
|
120
|
+
*/
|
|
121
|
+
busy: import("@angular/core").WritableSignal<boolean>;
|
|
122
|
+
pagination?: Pagination;
|
|
123
|
+
onItemClick(idx: number, event: MouseEvent): void;
|
|
124
|
+
onItemDoubleClick(idx: number, event: MouseEvent): void;
|
|
125
|
+
onDragSelectChange(sel: number[]): void;
|
|
126
|
+
onDragSelect(sel: number[]): void;
|
|
127
|
+
/**
|
|
128
|
+
* Selects multiple items in the list.
|
|
129
|
+
*/
|
|
130
|
+
multiSelect(index: number[]): void;
|
|
131
|
+
/**
|
|
132
|
+
* Refreshes the list by re-executing the current query/page.
|
|
133
|
+
*/
|
|
134
|
+
refresh(): void;
|
|
135
|
+
changePage(pe: PageEvent): void;
|
|
136
|
+
goToPage(page: number): void;
|
|
137
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<QueryListComponent, never>;
|
|
138
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<QueryListComponent, "yuv-query-list", never, { "query": { "alias": "query"; "required": false; "isSignal": true; }; "transformer": { "alias": "transformer"; "required": false; "isSignal": true; }; "preventChangeUntil": { "alias": "preventChangeUntil"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "enableDragSelect": { "alias": "enableDragSelect"; "required": false; "isSignal": true; }; "multiselect": { "alias": "multiselect"; "required": false; "isSignal": true; }; "selfHandleSelection": { "alias": "selfHandleSelection"; "required": false; "isSignal": true; }; }, { "itemSelect": "itemSelect"; "dragSelectChange": "dragSelectChange"; "itemDoubleClick": "itemDoubleClick"; "queryResult": "queryResult"; }, ["itemTemplate", "emptyTemplate"], never, true, never>;
|
|
139
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import * as i1 from "./query-list.component";
|
|
3
|
+
export declare class YuvQueryListModule {
|
|
4
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<YuvQueryListModule, never>;
|
|
5
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<YuvQueryListModule, never, [typeof i1.QueryListComponent], [typeof i1.QueryListComponent]>;
|
|
6
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<YuvQueryListModule>;
|
|
7
|
+
}
|