@ruc-lib/drawer 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,11 +27,41 @@ npm install @uxpractice/ruc-lib
27
27
  ```
28
28
 
29
29
  ### Install Individual Component
30
+
30
31
  If you only need the Drawer component:
32
+
33
+ **For Angular 15:**
34
+ ```bash
35
+ npm install @ruc-lib/drawer@3.2.0 @angular/material@^15.0.0 @angular/cdk@^15.0.0
36
+ ```
37
+
38
+ **For Angular 16:**
39
+ ```bash
40
+ npm install @ruc-lib/drawer@3.2.0 @angular/material@^16.0.0 @angular/cdk@^16.0.0
41
+ ```
42
+
43
+ **For Angular 17:**
44
+ ```bash
45
+ npm install @ruc-lib/drawer@4.0.0 @angular/material@^17.0.0 @angular/cdk@^17.0.0
46
+ ```
47
+
48
+ **For Angular 18:**
49
+ ```bash
50
+ npm install @ruc-lib/drawer@4.0.0 @angular/material@^18.0.0 @angular/cdk@^18.0.0
51
+ ```
52
+
53
+ **For Angular 19:**
54
+ ```bash
55
+ npm install @ruc-lib/drawer@4.0.0 @angular/material@^19.0.0 @angular/cdk@^19.0.0
56
+ ```
57
+
58
+ **For Angular 20:**
31
59
  ```bash
32
- npm install @ruc-lib/drawer
60
+ npm install @ruc-lib/drawer@4.0.0
33
61
  ```
34
62
 
63
+ > **Note:** When installing in Angular 15-19 apps, you must specify the matching `@angular/material` and `@angular/cdk` versions to avoid peer dependency conflicts. Angular 20 will automatically use the correct versions.
64
+
35
65
  ### 📦 Version Compatibility
36
66
 
37
67
  Please ensure you install the correct version of `@ruc-lib/drawer` based on your Angular version.
@@ -40,36 +70,34 @@ Please ensure you install the correct version of `@ruc-lib/drawer` based on your
40
70
  |--------------------|------------------------------------------|
41
71
  | 15.x.x | `npm install @ruc-lib/drawer@^3.2.0` |
42
72
  | 16.x.x | `npm install @ruc-lib/drawer@^3.2.0` |
73
+ | 17.x.x | `npm install @ruc-lib/drawer@^4.0.0` |
74
+ | 18.x.x | `npm install @ruc-lib/drawer@^4.0.0` |
75
+ | 19.x.x | `npm install @ruc-lib/drawer@^4.0.0` |
76
+ | 20.x.x | `npm install @ruc-lib/drawer@^4.0.0` |
43
77
 
44
78
 
45
79
  ## Usage
46
80
 
47
- ### 1. Import the Module
48
- In your Angular module file (e.g., `app.module.ts`), import the `RuclibDrawerModule`:
81
+ ### 1. Import the Component
82
+ In your Angular component file (e.g., `app.component.ts`), import the `RuclibDrawerComponent`:
49
83
 
50
84
  ```typescript
85
+ import { Component } from '@angular/core';
86
+
51
87
  // For Complete Library
52
- import { RuclibDrawerModule } from '@uxpractice/ruc-lib/drawer';
88
+ import { RuclibDrawerComponent } from '@uxpractice/ruc-lib/drawer';
53
89
 
54
90
  // For Individual Package
55
- import { RuclibDrawerModule } from '@ruc-lib/drawer';
56
-
57
- import { AppComponent } from './app.component';
58
- import { NgModule } from '@angular/core';
59
- import { BrowserModule } from '@angular/platform-browser';
60
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
61
-
62
- @NgModule({
63
- declarations: [AppComponent],
64
- imports: [
65
- BrowserModule,
66
- BrowserAnimationsModule,
67
- RuclibDrawerModule
68
- ],
69
- providers: [],
70
- bootstrap: [AppComponent]
91
+ import { RuclibDrawerComponent } from '@ruc-lib/drawer';
92
+
93
+ @Component({
94
+ selector: 'app-root',
95
+ imports: [RuclibDrawerComponent],
96
+ templateUrl: './app.component.html',
71
97
  })
72
- export class AppModule {}
98
+ export class AppComponent {
99
+ // Component code here
100
+ }
73
101
  ```
74
102
 
75
103
  ### 2. Use the Component
@@ -235,4 +263,4 @@ Contributions are welcome! Feel free to open issues or pull requests for any enh
235
263
 
236
264
  # Acknowledgements
237
265
 
238
- Thank you for choosing the Drawer Component Library. If you have any feedback or suggestions, please let us know!
266
+ Thank you for choosing the Drawer Component Library. If you have any feedback or suggestions, please let us know!
@@ -0,0 +1,456 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Pipe, EventEmitter, ViewContainerRef, HostListener, ViewChild, Output, Input, Component } from '@angular/core';
3
+ import { trigger, state, transition, style, animate } from '@angular/animations';
4
+ import * as i1$1 from '@angular/common';
5
+ import { CommonModule } from '@angular/common';
6
+ import * as i4 from '@angular/material/sidenav';
7
+ import { MatSidenavModule } from '@angular/material/sidenav';
8
+ import * as i2 from '@angular/material/button';
9
+ import { MatButtonModule } from '@angular/material/button';
10
+ import { MatToolbarModule } from '@angular/material/toolbar';
11
+ import * as i3 from '@angular/material/icon';
12
+ import { MatIconModule } from '@angular/material/icon';
13
+ import * as i1 from '@angular/platform-browser';
14
+
15
+ /**
16
+ * @Pipe SafeHtmlPipe
17
+ * @name safeHtml
18
+ * @description A pipe that bypasses Angular's built-in security and sanitizes HTML content,
19
+ * allowing it to be safely rendered in the DOM. Use with caution and only with trusted HTML sources.
20
+ */
21
+ class SafeHtmlPipe {
22
+ /**
23
+ * @param sanitizer - An instance of DomSanitizer used to bypass security.
24
+ */
25
+ constructor(sanitizer) {
26
+ this.sanitizer = sanitizer;
27
+ }
28
+ /**
29
+ * Transforms a string containing HTML into a SafeHtml object that can be bound to [innerHTML].
30
+ * @param value - The HTML string to sanitize.
31
+ * @returns A SafeHtml object, which Angular trusts as safe HTML.
32
+ */
33
+ transform(value) {
34
+ if (value === null || value === undefined) {
35
+ return value;
36
+ }
37
+ return this.sanitizer.bypassSecurityTrustHtml(value);
38
+ }
39
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SafeHtmlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
40
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.9", ngImport: i0, type: SafeHtmlPipe, isStandalone: true, name: "safeHtml" }); }
41
+ }
42
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: SafeHtmlPipe, decorators: [{
43
+ type: Pipe,
44
+ args: [{ name: 'safeHtml', standalone: true }]
45
+ }], ctorParameters: () => [{ type: i1.DomSanitizer }] });
46
+
47
+ /* eslint-disable @typescript-eslint/no-inferrable-types */
48
+ class RuclibDrawerComponent {
49
+ constructor(cdr) {
50
+ this.cdr = cdr;
51
+ /**
52
+ * Input data for configuring the drawer's appearance and behavior.
53
+ * @see RuclibDrawerInput interface for detailed properties.
54
+ */
55
+ this.rucInputData = {};
56
+ /**
57
+ * EventEmitter for various drawer events.
58
+ * Emits objects with `type` (e.g., 'openedStart', 'closedStart', 'openedChange', 'drawerToggle')
59
+ * and `opened` (boolean) and `position` (string) properties.
60
+ */
61
+ this.rucEvent = new EventEmitter();
62
+ /** Reference to the dynamically created component. */
63
+ this.dynamicComponentRef = null;
64
+ /**
65
+ * Current animation state of the drawer ('in' or 'out').
66
+ * @public
67
+ */
68
+ this.drawerAnimationState = 'out';
69
+ /**
70
+ * Current active position of the drawer.
71
+ * @public
72
+ * @default 'left'
73
+ */
74
+ this.currentDrawerPosition = 'left'; // Default
75
+ /**
76
+ * Stores the next position if the drawer is currently open and a new position is requested.
77
+ * Used to sequence close and open animations.
78
+ * @private
79
+ */
80
+ this.pendingDrawerPosition = null;
81
+ /**
82
+ * Flag to indicate if an animation is currently in progress to prevent rapid toggling.
83
+ * @public
84
+ */
85
+ this.isAnimating = false;
86
+ /**
87
+ * Effective animation duration for the drawer, derived from input or default.
88
+ * @public
89
+ * @default '300ms'
90
+ */
91
+ this.effectiveAnimationDuration = '300ms';
92
+ /**
93
+ * Mode of the drawer, primarily for determining backdrop behavior with custom animations.
94
+ * @public
95
+ * @default 'side'
96
+ */
97
+ this.matDrawerMode = 'side';
98
+ /**
99
+ * Actual position ('start' or 'end') used by Angular Material's MatDrawer if it were directly used.
100
+ * Retained for logical consistency in determining layout.
101
+ * @public
102
+ * @default 'start'
103
+ */
104
+ this.matActualPosition = 'start';
105
+ /**
106
+ * Flag indicating if the drawer is in a vertical layout (top/bottom).
107
+ * Helps determine if width or height should be 100%.
108
+ * @public
109
+ */
110
+ this.isVerticalLayout = false;
111
+ /**
112
+ * Effective dimension (width or height) of the drawer panel.
113
+ * @public
114
+ * @default '250px'
115
+ */
116
+ this.effectiveDrawerDimension = '250px';
117
+ }
118
+ /**
119
+ * Angular lifecycle hook that is called after data-bound properties of a directive are initialized.
120
+ */
121
+ ngOnInit() {
122
+ this.applyInputs();
123
+ this.drawerAnimationState = 'out';
124
+ this.loadDynamicContent();
125
+ }
126
+ /**
127
+ * Angular lifecycle hook that is called after Angular has fully initialized a component's view.
128
+ */
129
+ ngAfterViewInit() {
130
+ if (this.rucInputData.initialOpenedState && this.drawerAnimationState === 'out') {
131
+ // Defer state update to the next microtask queue.
132
+ // This helps avoid ExpressionChangedAfterItHasBeenCheckedError when initializing the drawer's open state.
133
+ Promise.resolve().then(() => this.setDrawerOpenState(true));
134
+ }
135
+ }
136
+ /**
137
+ * Angular lifecycle hook that is called when any data-bound property of a directive changes.
138
+ * @param changes - Object containing the changed properties.
139
+ */
140
+ ngOnChanges(changes) {
141
+ if (changes['rucInputData']) {
142
+ const previousRucInputData = changes['rucInputData'].previousValue || {};
143
+ const currentRucInputData = changes['rucInputData'].currentValue || {};
144
+ const oldPosition = previousRucInputData.drawerPosition ?? this.currentDrawerPosition;
145
+ const wasOpen = this.drawerAnimationState === 'in';
146
+ this.currentDrawerPosition = currentRucInputData.drawerPosition ?? 'left';
147
+ this.applyInputs();
148
+ const newPosition = this.currentDrawerPosition;
149
+ const shouldBeOpen = this.rucInputData.initialOpenedState ?? false;
150
+ if (wasOpen && oldPosition !== newPosition) {
151
+ this.pendingDrawerPosition = newPosition;
152
+ this.setDrawerOpenState(false);
153
+ }
154
+ else if (wasOpen !== shouldBeOpen) {
155
+ setTimeout(() => {
156
+ this.setDrawerOpenState(shouldBeOpen);
157
+ });
158
+ }
159
+ else {
160
+ this.loadDynamicContent();
161
+ }
162
+ this.cdr.detectChanges();
163
+ }
164
+ }
165
+ /**
166
+ * Applies input data to component properties, calculating dimensions and positions.
167
+ * @private
168
+ */
169
+ applyInputs() {
170
+ this.matDrawerMode = this.rucInputData.mode ?? 'side';
171
+ this.effectiveAnimationDuration = this.rucInputData.animationDuration || '300ms';
172
+ const getDimension = (inputDimension, defaultDimension) => {
173
+ return (inputDimension && inputDimension.trim() !== '') ? inputDimension : defaultDimension;
174
+ };
175
+ switch (this.currentDrawerPosition) {
176
+ case 'right':
177
+ this.matActualPosition = 'end';
178
+ this.isVerticalLayout = false;
179
+ this.effectiveDrawerDimension = getDimension(this.rucInputData.drawerWidth, '250px');
180
+ break;
181
+ case 'top':
182
+ this.matActualPosition = 'start';
183
+ this.isVerticalLayout = true;
184
+ this.effectiveDrawerDimension = getDimension(this.rucInputData.drawerHeight, '200px');
185
+ break;
186
+ case 'bottom':
187
+ this.matActualPosition = 'end';
188
+ this.isVerticalLayout = true;
189
+ this.effectiveDrawerDimension = getDimension(this.rucInputData.drawerHeight, '200px');
190
+ break;
191
+ case 'left':
192
+ default:
193
+ this.matActualPosition = 'start';
194
+ this.isVerticalLayout = false;
195
+ this.effectiveDrawerDimension = getDimension(this.rucInputData.drawerWidth, '250px');
196
+ break;
197
+ }
198
+ }
199
+ /**
200
+ * Toggles the drawer's open/close state or switches to a new position.
201
+ * @param requestedPosition - The desired position to open the drawer from. If not provided, uses `currentDrawerPosition`.
202
+ */
203
+ toggleDrawer(requestedPosition) {
204
+ if (this.isAnimating && !this.pendingDrawerPosition) {
205
+ return;
206
+ }
207
+ const positionToToggle = requestedPosition || this.currentDrawerPosition;
208
+ const isDrawerOpen = this.drawerAnimationState === 'in';
209
+ const isSamePosition = this.currentDrawerPosition === positionToToggle;
210
+ if (isDrawerOpen) {
211
+ if (isSamePosition) {
212
+ this.setDrawerOpenState(false);
213
+ }
214
+ else {
215
+ this.pendingDrawerPosition = positionToToggle;
216
+ this.setDrawerOpenState(false);
217
+ }
218
+ }
219
+ else {
220
+ if (!isSamePosition) {
221
+ this.currentDrawerPosition = positionToToggle;
222
+ this.applyInputs();
223
+ }
224
+ this.setDrawerOpenState(true);
225
+ }
226
+ }
227
+ /**
228
+ * Sets the drawer's open state and triggers the animation.
229
+ * @param open - Boolean indicating whether to open (true) or close (false) the drawer.
230
+ * @private
231
+ */
232
+ setDrawerOpenState(open) {
233
+ if (this.isAnimating && !this.pendingDrawerPosition && open === (this.drawerAnimationState === 'in')) {
234
+ return;
235
+ }
236
+ this.isAnimating = true;
237
+ this.drawerAnimationState = open ? 'in' : 'out';
238
+ this.rucEvent.emit({
239
+ type: open ? 'openedStart' : 'closedStart',
240
+ opened: open,
241
+ position: this.currentDrawerPosition
242
+ });
243
+ this.cdr.detectChanges();
244
+ }
245
+ /**
246
+ * Callback for when a drawer animation finishes.
247
+ * Manages state transitions, especially when switching between open drawers.
248
+ * @param event - The Angular AnimationEvent.
249
+ */
250
+ onAnimationDone(event) {
251
+ if (event.element.classList.contains('dynamic-drawer')) {
252
+ if (event.toState === 'out') {
253
+ this.rucEvent.emit({ type: 'openedChange', opened: false, position: this.currentDrawerPosition });
254
+ this.rucEvent.emit({ type: 'drawerToggle', opened: false, position: this.currentDrawerPosition });
255
+ if (this.pendingDrawerPosition) {
256
+ this.currentDrawerPosition = this.pendingDrawerPosition;
257
+ this.pendingDrawerPosition = null;
258
+ this.applyInputs();
259
+ setTimeout(() => {
260
+ this.setDrawerOpenState(true);
261
+ });
262
+ return;
263
+ }
264
+ }
265
+ else if (event.toState === 'in') {
266
+ this.rucEvent.emit({ type: 'openedChange', opened: true, position: this.currentDrawerPosition });
267
+ this.rucEvent.emit({ type: 'drawerToggle', opened: true, position: this.currentDrawerPosition });
268
+ }
269
+ this.isAnimating = false;
270
+ this.cdr.detectChanges();
271
+ }
272
+ }
273
+ /**
274
+ * Loads the dynamic component into the drawer if specified in rucInputData.
275
+ * Clears existing dynamic component if any.
276
+ * @private
277
+ */
278
+ loadDynamicContent() {
279
+ this.clearDynamicContent();
280
+ const componentType = this.rucInputData.content?.drawerContentComponent;
281
+ if (componentType && this.drawerComponentHost) {
282
+ this.dynamicComponentRef = this.drawerComponentHost.createComponent(componentType);
283
+ if (this.dynamicComponentRef.instance) {
284
+ this.dynamicComponentRef.changeDetectorRef.detectChanges();
285
+ }
286
+ if (this.rucInputData.drawerContentComponentData && this.dynamicComponentRef.instance) {
287
+ Object.keys(this.rucInputData.drawerContentComponentData).forEach(key => {
288
+ if (key in this.dynamicComponentRef.instance) {
289
+ this.dynamicComponentRef.instance[key] = this.rucInputData.drawerContentComponentData[key];
290
+ }
291
+ });
292
+ this.dynamicComponentRef.changeDetectorRef.detectChanges();
293
+ }
294
+ this.cdr.detectChanges();
295
+ }
296
+ }
297
+ /**
298
+ * Getter for the current animation parameters to be passed to the animation triggers in the template.
299
+ * Includes the current animation state ('in' or 'out') and the effective duration.
300
+ */
301
+ get animationParams() {
302
+ return { value: this.drawerAnimationState, params: { duration: this.effectiveAnimationDuration } };
303
+ }
304
+ /**
305
+ * Getter for the backdrop animation parameters.
306
+ * Typically uses a faster duration than the main drawer animation.
307
+ */
308
+ get backdropAnimationParams() {
309
+ let durationMs = 0;
310
+ if (this.effectiveAnimationDuration.endsWith('ms')) {
311
+ durationMs = parseInt(this.effectiveAnimationDuration, 10);
312
+ }
313
+ else if (this.effectiveAnimationDuration.endsWith('s')) {
314
+ durationMs = parseFloat(this.effectiveAnimationDuration) * 1000;
315
+ }
316
+ else {
317
+ durationMs = parseInt(this.effectiveAnimationDuration, 10) || 300; // Fallback if format is unexpected
318
+ }
319
+ const backdropDurationValue = Math.floor(durationMs / 2); // Ensure integer for ms
320
+ const backdropDuration = backdropDurationValue > 0 ? `${backdropDurationValue}ms` : '150ms'; // Fallback if calculated duration is 0 or less
321
+ return { value: this.drawerAnimationState, params: { duration: backdropDuration } };
322
+ }
323
+ /**
324
+ * Generates an accessible label for the toggle button based on the drawer's state and position.
325
+ * @returns The ARIA label string for the toggle button.
326
+ */
327
+ getToggleButtonAriaLabel() {
328
+ const defaultOpen = `Open ${this.currentDrawerPosition} Drawer`;
329
+ const defaultClose = `Close ${this.currentDrawerPosition} Drawer`;
330
+ const openText = this.rucInputData.toggleButtonText?.open || defaultOpen;
331
+ const closeText = this.rucInputData.toggleButtonText?.close || defaultClose;
332
+ return this.drawerAnimationState === 'in' ? closeText : openText;
333
+ }
334
+ /**
335
+ * Handles clicks on the backdrop.
336
+ * Closes the drawer only if `disableClose` is not true.
337
+ * @public
338
+ */
339
+ handleBackdropClick() {
340
+ if (!(this.rucInputData.disableClose ?? false)) {
341
+ this.toggleDrawer(this.currentDrawerPosition);
342
+ }
343
+ }
344
+ /**
345
+ * Listens for Escape key presses on the document.
346
+ * Closes the drawer if it's open and `disableClose` is not true.
347
+ * @param event - The KeyboardEvent.
348
+ */
349
+ onKeydownHandler(event) {
350
+ if (this.drawerAnimationState === 'in' && !(this.rucInputData.disableClose ?? false)) {
351
+ this.toggleDrawer(this.currentDrawerPosition);
352
+ }
353
+ }
354
+ /**
355
+ * Clears any dynamically loaded component.
356
+ * @private
357
+ */
358
+ clearDynamicContent() {
359
+ if (this.drawerComponentHost) {
360
+ this.drawerComponentHost.clear();
361
+ }
362
+ if (this.dynamicComponentRef) {
363
+ this.dynamicComponentRef.destroy();
364
+ this.dynamicComponentRef = null;
365
+ }
366
+ }
367
+ /**
368
+ * Angular lifecycle hook that is called clear dynamic component content.
369
+ */
370
+ ngOnDestroy() {
371
+ this.clearDynamicContent();
372
+ }
373
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibDrawerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
374
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: RuclibDrawerComponent, isStandalone: true, selector: "uxp-ruclib-drawer", inputs: { rucInputData: "rucInputData", customTheme: "customTheme" }, outputs: { rucEvent: "rucEvent" }, host: { listeners: { "document:keydown.escape": "onKeydownHandler($event)" } }, viewQueries: [{ propertyName: "drawerComponentHost", first: true, predicate: ["drawerComponentHost"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: "<!--\r\nCustom Backdrop element.\r\nVisible only when:\r\n- rucInputData.mode is 'over'\r\n- rucInputData.hasBackdrop is true (or undefined, defaulting to true)\r\n- drawerAnimationState is 'in' (drawer is open or opening)\r\nAnimates using 'backdropFade' trigger.\r\nClicking the backdrop will toggle the drawer for the current position.\r\nBackground color can be customized via rucInputData.backdropBackgroundColor.\r\n-->\r\n@if (rucInputData.mode === 'over' && (rucInputData.hasBackdrop ?? true) && drawerAnimationState === 'in') {\r\n <div class=\"custom-backdrop\"\r\n [@backdropFade]=\"backdropAnimationParams\"\r\n (click)=\"handleBackdropClick()\"\r\n [style.background-color]=\"rucInputData.hasBackdrop ? rucInputData.backdropBackgroundColor : ''\">\r\n </div>\r\n}\r\n\r\n<!--\r\nCustom Dynamic Drawer element.\r\nThis is the main panel that slides in and out.\r\n- Applies CSS classes based on currentDrawerPosition and customTheme.\r\n- Dynamically sets width and height based on drawer orientation and input data.\r\n- Uses one of four animation triggers (slideInOutLeft, slideInOutRight, slideInOutTop, slideInOutBottom)\r\nbased on currentDrawerPosition. Only the active trigger runs its animation; others are set to an\r\ninstant 'out' state to prevent interference.\r\n- Animation completion events are handled by onAnimationDone().\r\n-->\r\n<div class=\"dynamic-drawer\"\r\n [ngClass]=\"'drawer-' + currentDrawerPosition + ' ' + (customTheme || '')\"\r\n [style.width]=\"!isVerticalLayout ? effectiveDrawerDimension : '100%'\"\r\n [style.height]=\"isVerticalLayout ? effectiveDrawerDimension : '100%'\"\r\n\r\n [@slideInOutLeft]=\"currentDrawerPosition === 'left' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutLeft.done)=\"currentDrawerPosition === 'left' && onAnimationDone($event)\"\r\n\r\n [@slideInOutRight]=\"currentDrawerPosition === 'right' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutRight.done)=\"currentDrawerPosition === 'right' && onAnimationDone($event)\"\r\n\r\n [@slideInOutTop]=\"currentDrawerPosition === 'top' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutTop.done)=\"currentDrawerPosition === 'top' && onAnimationDone($event)\"\r\n\r\n [@slideInOutBottom]=\"currentDrawerPosition === 'bottom' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutBottom.done)=\"currentDrawerPosition === 'bottom' && onAnimationDone($event)\">\r\n\r\n <!-- Wrapper for the content inside the drawer, handles padding and layout. -->\r\n <div class=\"drawer-content-wrapper\">\r\n <!-- Optional title for the drawer. -->\r\n @if (rucInputData.content?.drawerTitle) {\r\n <h2 class=\"ruclib-drawer-title\">\r\n {{ rucInputData.content?.drawerTitle }}\r\n </h2>\r\n }\r\n <!--\r\n Optional close button inside the drawer.\r\n Toggles the drawer for the current position when clicked.\r\n ARIA label provides accessibility.\r\n Dimensions can be customized via rucInputData.closeButtonDimensions.\r\n -->\r\n @if (rucInputData.showCloseIcon) {\r\n <button\r\n mat-icon-button class=\"ruclib-drawer-close-button\"\r\n (click)=\"toggleDrawer(currentDrawerPosition)\"\r\n [attr.aria-label]=\"'Close ' + currentDrawerPosition + ' drawer'\"\r\n [style.width]=\"rucInputData.closeButtonDimensions?.width\"\r\n [style.height]=\"rucInputData.closeButtonDimensions?.height\">\r\n <!-- Material icon for the close button. Size can be customized. -->\r\n <mat-icon [style.font-size]=\"rucInputData.closeButtonDimensions?.iconSize\">close</mat-icon>\r\n </button>\r\n }\r\n <!-- Main body content of the drawer. -->\r\n <div class=\"ruclib-drawer-body\">\r\n <!-- Host for dynamically injected component -->\r\n <ng-template #drawerComponentHost></ng-template>\r\n <!-- Fallback to HTML content if no component is provided -->\r\n @if (!rucInputData.content?.drawerContentComponent) {\r\n <div [innerHTML]=\"rucInputData.content?.drawerBody || '' | safeHtml\"></div>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!--\r\nAngular Material Drawer Container.\r\nActs as the main container for the drawer system, especially if 'side' or 'push' modes\r\nwere to be implemented with MatDrawer's native behavior. With custom fixed-position animations,\r\nits primary role here is to host the mat-drawer-content.\r\n- Applies 'vertical-layout' class if the drawer is top/bottom.\r\n- MatDrawer's own backdrop is disabled as a custom one is used.\r\n-->\r\n<mat-drawer-container\r\n class=\"ruclib-drawer-container\"\r\n [class.vertical-layout]=\"isVerticalLayout\"\r\n [hasBackdrop]=\"false\"> <!-- MatDrawer's backdrop is not used with custom animation -->\r\n <mat-drawer-content class=\"ruclib-main-content\">\r\n <button [disabled]=\"rucInputData.disableToggleButtonInMainContent\"\r\n mat-raised-button\r\n color=\"primary\"\r\n title=\"Toggle Drawer\"\r\n class=\"drawer-toggle-button\"\r\n [style.width]=\"rucInputData.toggleButtonDimensions?.width\"\r\n [style.height]=\"rucInputData.toggleButtonDimensions?.height\"\r\n [style.padding]=\"rucInputData.toggleButtonDimensions?.padding\"\r\n [style.font-size]=\"rucInputData.toggleButtonDimensions?.fontSize\"\r\n (click)=\"toggleDrawer(currentDrawerPosition)\"\r\n [attr.aria-label]=\"getToggleButtonAriaLabel()\"\r\n [attr.aria-expanded]=\"drawerAnimationState === 'in'\">\r\n <!-- Optional Material icon for the toggle button. Show only if no image URL is provided. -->\r\n @if (rucInputData.toggleButtonIcon && !rucInputData.toggleButtonImageUrl) {\r\n <mat-icon [style.font-size]=\"rucInputData.toggleButtonDimensions?.iconSize\">{{ rucInputData.toggleButtonIcon }}</mat-icon>\r\n }\r\n <!-- Optional image for the toggle button. If present, it should fill the button. -->\r\n @if (rucInputData.toggleButtonImageUrl) {\r\n <img\r\n [src]=\"rucInputData.toggleButtonImageUrl\"\r\n [alt]=\"rucInputData.toggleButtonImageAlt || 'Toggle Drawer'\"\r\n class=\"ruclib-drawer-toggle-image\"\r\n [style.width]=\"rucInputData.toggleButtonDimensions?.width\"\r\n [style.height]=\"rucInputData.toggleButtonDimensions?.height\"\r\n [style.padding]=\"rucInputData.toggleButtonDimensions?.padding\">\r\n }\r\n <!-- Text for the toggle button. Show only if NO icon AND NO image URL is provided. -->\r\n @if (!rucInputData.toggleButtonIcon && !rucInputData.toggleButtonImageUrl && (rucInputData.toggleButtonText?.open || rucInputData.toggleButtonText?.close)) {\r\n <span>\r\n {{ drawerAnimationState === 'in' ? (rucInputData.toggleButtonText?.close || 'Close') : (rucInputData.toggleButtonText?.open || 'Open') }}\r\n </span>\r\n }\r\n <!-- Text for the toggle button when an icon (but NO image) IS also present. -->\r\n @if (rucInputData.toggleButtonIcon && !rucInputData.toggleButtonImageUrl && (rucInputData.toggleButtonText?.open || rucInputData.toggleButtonText?.close)) {\r\n <span class=\"toggle-button-text-with-icon\">\r\n {{ drawerAnimationState === 'in' ? (rucInputData.toggleButtonText?.close || 'Close') : (rucInputData.toggleButtonText?.open || 'Open') }}\r\n </span>\r\n }\r\n </button>\r\n <!-- Main application content area, rendered from HTML string via safeHtml pipe. -->\r\n <div [innerHTML]=\"rucInputData.content?.mainBody || '' | safeHtml\"></div>\r\n </mat-drawer-content>\r\n</mat-drawer-container>\r\n", styles: [":host{display:block;position:relative;overflow:hidden}.custom-backdrop{position:absolute;inset:0;background-color:#000;z-index:999;visibility:hidden}.ruclib-drawer-container{width:100%;height:400px;border:1px solid #ccc;position:relative;overflow:hidden}.drawer-content-wrapper{padding:16px;position:relative;box-sizing:border-box;height:100%;display:flex;flex-direction:column}.ruclib-drawer-title{margin-top:0;margin-bottom:16px;font-size:1.5em;flex-shrink:0}.ruclib-drawer-close-button{position:absolute;top:8px;right:8px;padding:5px 0 0!important;flex-shrink:0}.ruclib-drawer-body{flex-grow:1;overflow-y:auto;word-break:break-word}.dynamic-drawer{background-color:var(--mat-sidenav-content-background-color, white);position:absolute;box-sizing:border-box;box-shadow:0 2px 10px #0003;z-index:1000;overflow:hidden}.dynamic-drawer.drawer-left{top:0;bottom:0;left:0}.dynamic-drawer.drawer-right{top:0;bottom:0;right:0}.dynamic-drawer.drawer-top{top:0;left:0;right:0}.dynamic-drawer.drawer-bottom{bottom:0;left:0;right:0}.dynamic-drawer.light-theme{background-color:#fff;color:#000000de}.dynamic-drawer.light-theme .ruclib-drawer-title{color:#000000de}.dynamic-drawer.light-theme .ruclib-drawer-close-button .mat-icon{color:#0000008a}.dynamic-drawer.dark-theme{background-color:#424242;color:#fff}.dynamic-drawer.dark-theme .ruclib-drawer-title,.dynamic-drawer.dark-theme .ruclib-drawer-close-button .mat-icon{color:#fff}.dynamic-drawer.custom-theme-one{background-color:#fff;color:#000000de}.dynamic-drawer.custom-theme-one .ruclib-drawer-title{color:#000000de}.dynamic-drawer.custom-theme-one .ruclib-drawer-close-button .mat-icon{color:#0000008a}.dynamic-drawer.custom-theme-two{background-color:#424242;color:#fff}.dynamic-drawer.custom-theme-two .ruclib-drawer-title,.dynamic-drawer.custom-theme-two .ruclib-drawer-close-button .mat-icon{color:#fff}.ruclib-drawer-toggle-image{object-fit:contain;display:block}.drawer-toggle-button{margin-bottom:15px;display:inline-flex;align-items:center;justify-content:center;gap:8px}.ruclib-main-content{padding:16px;display:flex;flex-direction:column;align-items:flex-start}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i4.MatDrawerContainer, selector: "mat-drawer-container", inputs: ["autosize", "hasBackdrop"], outputs: ["backdropClick"], exportAs: ["matDrawerContainer"] }, { kind: "component", type: i4.MatDrawerContent, selector: "mat-drawer-content" }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }], animations: [
375
+ trigger('backdropFade', [
376
+ state('out', style({ opacity: 0, visibility: 'hidden' })),
377
+ state('in', style({ opacity: 0.6, visibility: 'visible' })),
378
+ transition('out => in', animate('{{duration}} ease-in')),
379
+ transition('in => out', animate('{{duration}} ease-out')),
380
+ ]),
381
+ trigger('slideInOutLeft', [
382
+ state('out', style({ transform: 'translateX(-100%)', visibility: 'hidden' })),
383
+ state('in', style({ transform: 'translateX(0)', visibility: 'visible' })),
384
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
385
+ ]),
386
+ trigger('slideInOutRight', [
387
+ state('out', style({ transform: 'translateX(100%)', visibility: 'hidden' })),
388
+ state('in', style({ transform: 'translateX(0)', visibility: 'visible' })),
389
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
390
+ ]),
391
+ trigger('slideInOutTop', [
392
+ state('out', style({ transform: 'translateY(-100%)', visibility: 'hidden' })),
393
+ state('in', style({ transform: 'translateY(0%)', visibility: 'visible' })),
394
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
395
+ ]),
396
+ trigger('slideInOutBottom', [
397
+ state('out', style({ transform: 'translateY(100%)', visibility: 'hidden' })),
398
+ state('in', style({ transform: 'translateY(0%)', visibility: 'visible' })),
399
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
400
+ ])
401
+ ] }); }
402
+ }
403
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: RuclibDrawerComponent, decorators: [{
404
+ type: Component,
405
+ args: [{ selector: 'uxp-ruclib-drawer', imports: [CommonModule,
406
+ MatButtonModule,
407
+ MatIconModule,
408
+ MatSidenavModule,
409
+ MatToolbarModule, SafeHtmlPipe], animations: [
410
+ trigger('backdropFade', [
411
+ state('out', style({ opacity: 0, visibility: 'hidden' })),
412
+ state('in', style({ opacity: 0.6, visibility: 'visible' })),
413
+ transition('out => in', animate('{{duration}} ease-in')),
414
+ transition('in => out', animate('{{duration}} ease-out')),
415
+ ]),
416
+ trigger('slideInOutLeft', [
417
+ state('out', style({ transform: 'translateX(-100%)', visibility: 'hidden' })),
418
+ state('in', style({ transform: 'translateX(0)', visibility: 'visible' })),
419
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
420
+ ]),
421
+ trigger('slideInOutRight', [
422
+ state('out', style({ transform: 'translateX(100%)', visibility: 'hidden' })),
423
+ state('in', style({ transform: 'translateX(0)', visibility: 'visible' })),
424
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
425
+ ]),
426
+ trigger('slideInOutTop', [
427
+ state('out', style({ transform: 'translateY(-100%)', visibility: 'hidden' })),
428
+ state('in', style({ transform: 'translateY(0%)', visibility: 'visible' })),
429
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
430
+ ]),
431
+ trigger('slideInOutBottom', [
432
+ state('out', style({ transform: 'translateY(100%)', visibility: 'hidden' })),
433
+ state('in', style({ transform: 'translateY(0%)', visibility: 'visible' })),
434
+ transition('out <=> in', animate('{{duration}} ease-in-out')),
435
+ ])
436
+ ], template: "<!--\r\nCustom Backdrop element.\r\nVisible only when:\r\n- rucInputData.mode is 'over'\r\n- rucInputData.hasBackdrop is true (or undefined, defaulting to true)\r\n- drawerAnimationState is 'in' (drawer is open or opening)\r\nAnimates using 'backdropFade' trigger.\r\nClicking the backdrop will toggle the drawer for the current position.\r\nBackground color can be customized via rucInputData.backdropBackgroundColor.\r\n-->\r\n@if (rucInputData.mode === 'over' && (rucInputData.hasBackdrop ?? true) && drawerAnimationState === 'in') {\r\n <div class=\"custom-backdrop\"\r\n [@backdropFade]=\"backdropAnimationParams\"\r\n (click)=\"handleBackdropClick()\"\r\n [style.background-color]=\"rucInputData.hasBackdrop ? rucInputData.backdropBackgroundColor : ''\">\r\n </div>\r\n}\r\n\r\n<!--\r\nCustom Dynamic Drawer element.\r\nThis is the main panel that slides in and out.\r\n- Applies CSS classes based on currentDrawerPosition and customTheme.\r\n- Dynamically sets width and height based on drawer orientation and input data.\r\n- Uses one of four animation triggers (slideInOutLeft, slideInOutRight, slideInOutTop, slideInOutBottom)\r\nbased on currentDrawerPosition. Only the active trigger runs its animation; others are set to an\r\ninstant 'out' state to prevent interference.\r\n- Animation completion events are handled by onAnimationDone().\r\n-->\r\n<div class=\"dynamic-drawer\"\r\n [ngClass]=\"'drawer-' + currentDrawerPosition + ' ' + (customTheme || '')\"\r\n [style.width]=\"!isVerticalLayout ? effectiveDrawerDimension : '100%'\"\r\n [style.height]=\"isVerticalLayout ? effectiveDrawerDimension : '100%'\"\r\n\r\n [@slideInOutLeft]=\"currentDrawerPosition === 'left' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutLeft.done)=\"currentDrawerPosition === 'left' && onAnimationDone($event)\"\r\n\r\n [@slideInOutRight]=\"currentDrawerPosition === 'right' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutRight.done)=\"currentDrawerPosition === 'right' && onAnimationDone($event)\"\r\n\r\n [@slideInOutTop]=\"currentDrawerPosition === 'top' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutTop.done)=\"currentDrawerPosition === 'top' && onAnimationDone($event)\"\r\n\r\n [@slideInOutBottom]=\"currentDrawerPosition === 'bottom' ? animationParams : {value: 'out', params: {duration: '0ms'}}\"\r\n (@slideInOutBottom.done)=\"currentDrawerPosition === 'bottom' && onAnimationDone($event)\">\r\n\r\n <!-- Wrapper for the content inside the drawer, handles padding and layout. -->\r\n <div class=\"drawer-content-wrapper\">\r\n <!-- Optional title for the drawer. -->\r\n @if (rucInputData.content?.drawerTitle) {\r\n <h2 class=\"ruclib-drawer-title\">\r\n {{ rucInputData.content?.drawerTitle }}\r\n </h2>\r\n }\r\n <!--\r\n Optional close button inside the drawer.\r\n Toggles the drawer for the current position when clicked.\r\n ARIA label provides accessibility.\r\n Dimensions can be customized via rucInputData.closeButtonDimensions.\r\n -->\r\n @if (rucInputData.showCloseIcon) {\r\n <button\r\n mat-icon-button class=\"ruclib-drawer-close-button\"\r\n (click)=\"toggleDrawer(currentDrawerPosition)\"\r\n [attr.aria-label]=\"'Close ' + currentDrawerPosition + ' drawer'\"\r\n [style.width]=\"rucInputData.closeButtonDimensions?.width\"\r\n [style.height]=\"rucInputData.closeButtonDimensions?.height\">\r\n <!-- Material icon for the close button. Size can be customized. -->\r\n <mat-icon [style.font-size]=\"rucInputData.closeButtonDimensions?.iconSize\">close</mat-icon>\r\n </button>\r\n }\r\n <!-- Main body content of the drawer. -->\r\n <div class=\"ruclib-drawer-body\">\r\n <!-- Host for dynamically injected component -->\r\n <ng-template #drawerComponentHost></ng-template>\r\n <!-- Fallback to HTML content if no component is provided -->\r\n @if (!rucInputData.content?.drawerContentComponent) {\r\n <div [innerHTML]=\"rucInputData.content?.drawerBody || '' | safeHtml\"></div>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!--\r\nAngular Material Drawer Container.\r\nActs as the main container for the drawer system, especially if 'side' or 'push' modes\r\nwere to be implemented with MatDrawer's native behavior. With custom fixed-position animations,\r\nits primary role here is to host the mat-drawer-content.\r\n- Applies 'vertical-layout' class if the drawer is top/bottom.\r\n- MatDrawer's own backdrop is disabled as a custom one is used.\r\n-->\r\n<mat-drawer-container\r\n class=\"ruclib-drawer-container\"\r\n [class.vertical-layout]=\"isVerticalLayout\"\r\n [hasBackdrop]=\"false\"> <!-- MatDrawer's backdrop is not used with custom animation -->\r\n <mat-drawer-content class=\"ruclib-main-content\">\r\n <button [disabled]=\"rucInputData.disableToggleButtonInMainContent\"\r\n mat-raised-button\r\n color=\"primary\"\r\n title=\"Toggle Drawer\"\r\n class=\"drawer-toggle-button\"\r\n [style.width]=\"rucInputData.toggleButtonDimensions?.width\"\r\n [style.height]=\"rucInputData.toggleButtonDimensions?.height\"\r\n [style.padding]=\"rucInputData.toggleButtonDimensions?.padding\"\r\n [style.font-size]=\"rucInputData.toggleButtonDimensions?.fontSize\"\r\n (click)=\"toggleDrawer(currentDrawerPosition)\"\r\n [attr.aria-label]=\"getToggleButtonAriaLabel()\"\r\n [attr.aria-expanded]=\"drawerAnimationState === 'in'\">\r\n <!-- Optional Material icon for the toggle button. Show only if no image URL is provided. -->\r\n @if (rucInputData.toggleButtonIcon && !rucInputData.toggleButtonImageUrl) {\r\n <mat-icon [style.font-size]=\"rucInputData.toggleButtonDimensions?.iconSize\">{{ rucInputData.toggleButtonIcon }}</mat-icon>\r\n }\r\n <!-- Optional image for the toggle button. If present, it should fill the button. -->\r\n @if (rucInputData.toggleButtonImageUrl) {\r\n <img\r\n [src]=\"rucInputData.toggleButtonImageUrl\"\r\n [alt]=\"rucInputData.toggleButtonImageAlt || 'Toggle Drawer'\"\r\n class=\"ruclib-drawer-toggle-image\"\r\n [style.width]=\"rucInputData.toggleButtonDimensions?.width\"\r\n [style.height]=\"rucInputData.toggleButtonDimensions?.height\"\r\n [style.padding]=\"rucInputData.toggleButtonDimensions?.padding\">\r\n }\r\n <!-- Text for the toggle button. Show only if NO icon AND NO image URL is provided. -->\r\n @if (!rucInputData.toggleButtonIcon && !rucInputData.toggleButtonImageUrl && (rucInputData.toggleButtonText?.open || rucInputData.toggleButtonText?.close)) {\r\n <span>\r\n {{ drawerAnimationState === 'in' ? (rucInputData.toggleButtonText?.close || 'Close') : (rucInputData.toggleButtonText?.open || 'Open') }}\r\n </span>\r\n }\r\n <!-- Text for the toggle button when an icon (but NO image) IS also present. -->\r\n @if (rucInputData.toggleButtonIcon && !rucInputData.toggleButtonImageUrl && (rucInputData.toggleButtonText?.open || rucInputData.toggleButtonText?.close)) {\r\n <span class=\"toggle-button-text-with-icon\">\r\n {{ drawerAnimationState === 'in' ? (rucInputData.toggleButtonText?.close || 'Close') : (rucInputData.toggleButtonText?.open || 'Open') }}\r\n </span>\r\n }\r\n </button>\r\n <!-- Main application content area, rendered from HTML string via safeHtml pipe. -->\r\n <div [innerHTML]=\"rucInputData.content?.mainBody || '' | safeHtml\"></div>\r\n </mat-drawer-content>\r\n</mat-drawer-container>\r\n", styles: [":host{display:block;position:relative;overflow:hidden}.custom-backdrop{position:absolute;inset:0;background-color:#000;z-index:999;visibility:hidden}.ruclib-drawer-container{width:100%;height:400px;border:1px solid #ccc;position:relative;overflow:hidden}.drawer-content-wrapper{padding:16px;position:relative;box-sizing:border-box;height:100%;display:flex;flex-direction:column}.ruclib-drawer-title{margin-top:0;margin-bottom:16px;font-size:1.5em;flex-shrink:0}.ruclib-drawer-close-button{position:absolute;top:8px;right:8px;padding:5px 0 0!important;flex-shrink:0}.ruclib-drawer-body{flex-grow:1;overflow-y:auto;word-break:break-word}.dynamic-drawer{background-color:var(--mat-sidenav-content-background-color, white);position:absolute;box-sizing:border-box;box-shadow:0 2px 10px #0003;z-index:1000;overflow:hidden}.dynamic-drawer.drawer-left{top:0;bottom:0;left:0}.dynamic-drawer.drawer-right{top:0;bottom:0;right:0}.dynamic-drawer.drawer-top{top:0;left:0;right:0}.dynamic-drawer.drawer-bottom{bottom:0;left:0;right:0}.dynamic-drawer.light-theme{background-color:#fff;color:#000000de}.dynamic-drawer.light-theme .ruclib-drawer-title{color:#000000de}.dynamic-drawer.light-theme .ruclib-drawer-close-button .mat-icon{color:#0000008a}.dynamic-drawer.dark-theme{background-color:#424242;color:#fff}.dynamic-drawer.dark-theme .ruclib-drawer-title,.dynamic-drawer.dark-theme .ruclib-drawer-close-button .mat-icon{color:#fff}.dynamic-drawer.custom-theme-one{background-color:#fff;color:#000000de}.dynamic-drawer.custom-theme-one .ruclib-drawer-title{color:#000000de}.dynamic-drawer.custom-theme-one .ruclib-drawer-close-button .mat-icon{color:#0000008a}.dynamic-drawer.custom-theme-two{background-color:#424242;color:#fff}.dynamic-drawer.custom-theme-two .ruclib-drawer-title,.dynamic-drawer.custom-theme-two .ruclib-drawer-close-button .mat-icon{color:#fff}.ruclib-drawer-toggle-image{object-fit:contain;display:block}.drawer-toggle-button{margin-bottom:15px;display:inline-flex;align-items:center;justify-content:center;gap:8px}.ruclib-main-content{padding:16px;display:flex;flex-direction:column;align-items:flex-start}\n"] }]
437
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { rucInputData: [{
438
+ type: Input
439
+ }], customTheme: [{
440
+ type: Input
441
+ }], rucEvent: [{
442
+ type: Output
443
+ }], drawerComponentHost: [{
444
+ type: ViewChild,
445
+ args: ['drawerComponentHost', { read: ViewContainerRef, static: true }]
446
+ }], onKeydownHandler: [{
447
+ type: HostListener,
448
+ args: ['document:keydown.escape', ['$event']]
449
+ }] } });
450
+
451
+ /**
452
+ * Generated bundle index. Do not edit.
453
+ */
454
+
455
+ export { RuclibDrawerComponent };
456
+ //# sourceMappingURL=ruc-lib-drawer.mjs.map