@praxisui/settings-panel 3.0.0-beta.8 → 4.0.0-beta.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/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Type, Injector, Provider, ComponentRef, ChangeDetectorRef, InjectionToken, OnInit, AfterViewInit, ViewContainerRef } from '@angular/core';
3
- import { OverlayRef, Overlay } from '@angular/cdk/overlay';
2
+ import { Type, Injector, ComponentRef, Provider, ChangeDetectorRef, InjectionToken, OnDestroy, OnInit, AfterViewInit, ViewContainerRef } from '@angular/core';
4
3
  import * as rxjs from 'rxjs';
5
4
  import { Observable, BehaviorSubject } from 'rxjs';
5
+ import { OverlayRef, Overlay } from '@angular/cdk/overlay';
6
+ import { PraxisI18nService, GlobalConfig, FormConfig, FormValueChangeEvent, AiCapabilityCategory, AiValueKind, AiCapability, AiCapabilityCatalog } from '@praxisui/core';
6
7
  import { MatDialog } from '@angular/material/dialog';
7
- import { GlobalConfig, FormConfig, FormValueChangeEvent, AiCapabilityCategory, AiValueKind, AiCapability, AiCapabilityCatalog } from '@praxisui/core';
8
8
  import { MatSnackBar } from '@angular/material/snack-bar';
9
9
  import { AiProviderCatalogItem } from '@praxisui/ai';
10
10
 
@@ -15,6 +15,10 @@ interface SettingsPanelConfig {
15
15
  titleIcon?: string;
16
16
  /** Optional initial expanded state */
17
17
  expanded?: boolean;
18
+ resizable?: boolean;
19
+ persistSizeKey?: string;
20
+ minWidth?: string;
21
+ maxWidth?: string;
18
22
  content: {
19
23
  component: Type<any>;
20
24
  inputs?: Record<string, any>;
@@ -107,10 +111,15 @@ declare class SettingsPanelRef {
107
111
  private savedSubject;
108
112
  private resetSubject;
109
113
  private closedSubject;
114
+ private sizeChangedSubject;
115
+ private sizePersistor?;
110
116
  applied$: rxjs.Observable<any>;
111
117
  saved$: rxjs.Observable<any>;
112
118
  reset$: rxjs.Observable<void>;
113
119
  closed$: rxjs.Observable<SettingsPanelCloseReason>;
120
+ sizeChanged$: rxjs.Observable<{
121
+ width: string;
122
+ }>;
114
123
  constructor(overlayRef: OverlayRef);
115
124
  apply(value: any): void;
116
125
  /**
@@ -121,17 +130,171 @@ declare class SettingsPanelRef {
121
130
  */
122
131
  save(value: any): void;
123
132
  reset(): void;
133
+ bindSizePersistor(fn: (width: string) => void): void;
124
134
  updateSize(width: string | number): void;
125
135
  close(reason?: SettingsPanelCloseReason): void;
126
136
  private complete;
127
137
  }
128
138
 
139
+ type SidePanelWidthPreset = 'narrow' | 'default' | 'wide' | 'full';
140
+ type SidePanelCssVarName = '--pfx-side-panel-width' | '--pfx-side-panel-max-width' | '--pfx-side-panel-header-height' | '--pfx-side-panel-header-gap' | '--pfx-side-panel-header-padding-x' | '--pfx-side-panel-body-padding' | '--pfx-side-panel-footer-padding' | '--pfx-side-panel-footer-gap' | '--pfx-side-panel-border-radius' | '--pfx-side-panel-elevation' | '--pfx-side-panel-backdrop' | '--pfx-side-panel-backdrop-blur' | '--pfx-side-panel-motion-duration-enter' | '--pfx-side-panel-motion-duration-exit' | '--pfx-side-panel-motion-easing-enter' | '--pfx-side-panel-motion-easing-exit';
141
+ interface SidePanelMotionContract {
142
+ durationEnterMs?: number;
143
+ durationExitMs?: number;
144
+ easingEnter?: string;
145
+ easingExit?: string;
146
+ respectReducedMotion?: boolean;
147
+ }
148
+ interface SidePanelThemeContract {
149
+ /**
150
+ * Host-provided width preset. The visual shell may translate the preset into
151
+ * concrete CSS variables, but the base contract stays product-neutral.
152
+ */
153
+ widthPreset?: SidePanelWidthPreset;
154
+ /**
155
+ * Additional host classes applied to the drawer shell to infer brand/theme
156
+ * without hardcoding product-level skin in the base component.
157
+ */
158
+ hostClasses?: string[];
159
+ /**
160
+ * Optional CSS custom properties injected by the host. Keys must use the
161
+ * neutral side-panel naming, never `settings-panel` naming.
162
+ */
163
+ cssVars?: Partial<Record<SidePanelCssVarName, string>>;
164
+ /**
165
+ * Motion remains host-driven and must support reduced motion.
166
+ */
167
+ motion?: SidePanelMotionContract;
168
+ }
169
+ /**
170
+ * Neutral theme contract for the future shared drawer base.
171
+ *
172
+ * This contract intentionally does not expose `settings-panel` naming so the
173
+ * runtime drawer can inherit host look-and-feel without importing authoring
174
+ * semantics or product-specific skin.
175
+ */
176
+ declare const SIDE_PANEL_THEME_CSS_VARS: readonly SidePanelCssVarName[];
177
+
178
+ type BaseSidePanelCloseReason = 'close' | 'backdrop' | 'esc';
179
+ type BaseSidePanelResizeAxis = 'x';
180
+ interface BaseSidePanelResult<T = unknown> {
181
+ type?: string;
182
+ data?: T;
183
+ }
184
+ interface BaseSidePanelRef<T = unknown> {
185
+ closed$: Observable<BaseSidePanelResult<T> | undefined>;
186
+ result$?: Observable<BaseSidePanelResult<T>>;
187
+ sizeChanged$?: Observable<{
188
+ width: string;
189
+ }>;
190
+ close(result?: BaseSidePanelResult<T>): void;
191
+ emitResult?(result: BaseSidePanelResult<T>): void;
192
+ updateTitle?(title: string): void;
193
+ updateSize?(size: SidePanelWidthPreset | string | {
194
+ width?: string;
195
+ }): void;
196
+ }
197
+ interface BaseSidePanelContent<TInputs = any> {
198
+ component: Type<any>;
199
+ inputs?: TInputs;
200
+ }
201
+ interface BaseSidePanelOpenOptions<TInputs = any> {
202
+ id: string;
203
+ title?: string;
204
+ titleIcon?: string;
205
+ subtitle?: string;
206
+ scope?: string;
207
+ widthPreset?: SidePanelWidthPreset;
208
+ width?: string;
209
+ minWidth?: string;
210
+ maxWidth?: string;
211
+ resizable?: boolean;
212
+ resizeAxis?: BaseSidePanelResizeAxis;
213
+ persistSizeKey?: string;
214
+ content: BaseSidePanelContent<TInputs>;
215
+ footer?: BaseSidePanelContent;
216
+ theme?: SidePanelThemeContract;
217
+ closeOnBackdrop?: boolean;
218
+ closeOnEsc?: boolean;
219
+ }
220
+
221
+ declare class BaseSidePanelOverlayRef<T = unknown> implements BaseSidePanelRef<T> {
222
+ private readonly closedSubject;
223
+ private readonly resultSubject;
224
+ private readonly sizeChangedSubject;
225
+ private overlayRef;
226
+ private titleUpdater?;
227
+ private sizePersistor?;
228
+ readonly closed$: rxjs.Observable<BaseSidePanelResult<T> | undefined>;
229
+ readonly result$: rxjs.Observable<BaseSidePanelResult<T>>;
230
+ readonly sizeChanged$: rxjs.Observable<{
231
+ width: string;
232
+ }>;
233
+ constructor(overlayRef: OverlayRef);
234
+ bindTitleUpdater(fn: (title: string) => void): void;
235
+ bindSizePersistor(fn: (width: string) => void): void;
236
+ emitResult(result: BaseSidePanelResult<T>): void;
237
+ updateTitle(title: string): void;
238
+ updateSize(size: string | {
239
+ width?: string;
240
+ }): void;
241
+ close(result?: BaseSidePanelResult<T>): void;
242
+ private resolveWidth;
243
+ }
244
+
245
+ interface SidePanelActiveRef {
246
+ readonly closed$: Observable<unknown>;
247
+ bindSizePersistor?: (fn: (width: string) => void) => void;
248
+ }
249
+ interface SidePanelHostOpenOptions<TComponent, TRef extends SidePanelActiveRef> {
250
+ readonly component: Type<TComponent>;
251
+ readonly config: BaseSidePanelOpenOptions;
252
+ readonly backdropClass?: string;
253
+ readonly panelClass?: string;
254
+ readonly overlayWidth?: string | null;
255
+ readonly overlaySize?: {
256
+ width?: string;
257
+ minWidth?: string;
258
+ maxWidth?: string;
259
+ height?: string;
260
+ minHeight?: string;
261
+ maxHeight?: string;
262
+ } | null;
263
+ readonly createRef: (overlayRef: OverlayRef) => TRef;
264
+ readonly attach: (panelRef: ComponentRef<TComponent>, ref: TRef, resolvedConfig: BaseSidePanelOpenOptions) => void;
265
+ readonly createCloser: (ref: TRef) => (reason?: string) => void;
266
+ readonly onBackdrop: (ref: TRef) => void;
267
+ readonly onEsc: (ref: TRef) => void;
268
+ }
269
+ declare class BaseSidePanelService {
270
+ private readonly overlay;
271
+ private readonly injector;
272
+ private readonly currentByScope;
273
+ constructor(overlay: Overlay, injector: Injector);
274
+ open<TInputs = any, TResult = unknown>(config: BaseSidePanelOpenOptions<TInputs>): BaseSidePanelOverlayRef<TResult>;
275
+ close(reason?: string): void;
276
+ openHost<TComponent, TRef extends SidePanelActiveRef>(options: SidePanelHostOpenOptions<TComponent, TRef>): TRef;
277
+ closeScope(scope: string, reason?: string): void;
278
+ private buildOverlayConfig;
279
+ private resolveWidth;
280
+ private resolveOpenConfig;
281
+ private resolvePersistedWidth;
282
+ private persistWidth;
283
+ private storageKey;
284
+ private isPixelWidth;
285
+ private closeResult;
286
+ private trackCurrentRef;
287
+ static ɵfac: i0.ɵɵFactoryDeclaration<BaseSidePanelService, never>;
288
+ static ɵprov: i0.ɵɵInjectableDeclaration<BaseSidePanelService>;
289
+ }
290
+
129
291
  declare class SettingsPanelService {
130
- private overlay;
292
+ private readonly baseSidePanelService;
131
293
  private injector;
132
294
  private currentRef?;
133
295
  private readonly i18n;
134
- constructor(overlay: Overlay, injector: Injector);
296
+ private readonly layerScale;
297
+ constructor(baseSidePanelService: BaseSidePanelService, injector: Injector);
135
298
  /**
136
299
  * Opens a new settings panel. If another panel is already open it will be
137
300
  * closed before the new one is created. Future improvements may reuse the
@@ -143,13 +306,48 @@ declare class SettingsPanelService {
143
306
  static ɵprov: i0.ɵɵInjectableDeclaration<SettingsPanelService>;
144
307
  }
145
308
 
146
- declare function providePraxisSettingsPanelBridge(): Provider;
309
+ declare function providePraxisSettingsPanelBridge(): Provider[];
310
+
311
+ declare function providePraxisSurfaceDrawerBridge(): Provider[];
312
+
313
+ declare class SurfaceDrawerComponent {
314
+ private readonly cdr;
315
+ private readonly i18n;
316
+ title: string;
317
+ titleIcon?: string;
318
+ subtitle?: string;
319
+ widthPreset: 'narrow' | 'default' | 'wide' | 'full';
320
+ useHostWidth: boolean;
321
+ theme: SidePanelThemeContract | null;
322
+ onClose?: () => void;
323
+ private static nextId;
324
+ titleId: string;
325
+ contentRef?: ComponentRef<any>;
326
+ private contentHost;
327
+ constructor(cdr: ChangeDetectorRef, i18n: PraxisI18nService);
328
+ get hostClasses(): string[];
329
+ get hostCssVars(): Record<string, string>;
330
+ get closeLabel(): string;
331
+ get hasHeader(): boolean;
332
+ get widthClass(): string | null;
333
+ setTitle(title: string): void;
334
+ attachContent(component: Type<any>, injector: Injector, inputs?: Record<string, unknown>): ComponentRef<any>;
335
+ private applyInputs;
336
+ private resolveSupportedInputs;
337
+ static ɵfac: i0.ɵɵFactoryDeclaration<SurfaceDrawerComponent, never>;
338
+ static ɵcmp: i0.ɵɵComponentDeclaration<SurfaceDrawerComponent, "praxis-surface-drawer", never, {}, {}, never, never, true, never>;
339
+ }
147
340
 
148
341
  declare class SettingsPanelComponent {
149
342
  private cdr;
150
343
  private dialog;
151
344
  title: string;
152
345
  titleIcon?: string;
346
+ width: string;
347
+ minWidth?: string;
348
+ maxWidth?: string;
349
+ resizable: boolean;
350
+ persistSizeKey?: string;
153
351
  expanded: boolean;
154
352
  ref: SettingsPanelRef;
155
353
  contentRef?: ComponentRef<any>;
@@ -159,11 +357,18 @@ declare class SettingsPanelComponent {
159
357
  isValid: boolean;
160
358
  isBusy: boolean;
161
359
  private lastSavedAt;
360
+ private activePointerId;
361
+ private dragStartX;
362
+ private dragStartWidth;
363
+ private collapsedWidthBeforeExpand;
162
364
  private readonly destroyRef;
163
365
  private readonly i18n;
164
366
  private contentHost;
165
367
  constructor(cdr: ChangeDetectorRef, dialog: MatDialog);
166
368
  get canApply(): boolean;
369
+ get panelInlineStyles(): Record<string, string | null>;
370
+ get showResizeHandle(): boolean;
371
+ get resizeHandleLabel(): string;
167
372
  get canSave(): boolean;
168
373
  get disabledReason(): string;
169
374
  get statusTone(): 'busy' | 'dirty' | 'saved' | 'idle';
@@ -178,8 +383,17 @@ declare class SettingsPanelComponent {
178
383
  private emitSave;
179
384
  private formatClock;
180
385
  toggleExpand(): void;
386
+ onResizeHandlePointerDown(event: PointerEvent): void;
387
+ onResizeHandleKeydown(event: KeyboardEvent): void;
181
388
  onCancel(): void;
182
389
  handleKeydown(event: KeyboardEvent): void;
390
+ onDocumentPointerMove(event: PointerEvent): void;
391
+ onDocumentPointerEnd(event: PointerEvent): void;
392
+ private getCurrentWidthPx;
393
+ private applyWidthPx;
394
+ private clampWidthPx;
395
+ private computeExpandedWidth;
396
+ private parseWidthPx;
183
397
  static ɵfac: i0.ɵɵFactoryDeclaration<SettingsPanelComponent, never>;
184
398
  static ɵcmp: i0.ɵɵComponentDeclaration<SettingsPanelComponent, "praxis-settings-panel", never, {}, {}, never, never, true, never>;
185
399
  }
@@ -187,6 +401,66 @@ declare class SettingsPanelComponent {
187
401
  declare const SETTINGS_PANEL_DATA: InjectionToken<any>;
188
402
  declare const SETTINGS_PANEL_REF: InjectionToken<SettingsPanelRef>;
189
403
 
404
+ declare const BASE_SIDE_PANEL_DATA: InjectionToken<any>;
405
+ declare const BASE_SIDE_PANEL_REF: InjectionToken<BaseSidePanelRef<unknown>>;
406
+
407
+ declare class BaseSidePanelComponent implements OnDestroy {
408
+ private readonly cdr;
409
+ private readonly i18n;
410
+ title: string;
411
+ titleIcon?: string;
412
+ subtitle?: string;
413
+ widthPreset: 'narrow' | 'default' | 'wide' | 'full';
414
+ width?: string;
415
+ minWidth?: string;
416
+ maxWidth?: string;
417
+ resizable: boolean;
418
+ resizeAxis: BaseSidePanelResizeAxis;
419
+ persistSizeKey?: string;
420
+ useHostWidth: boolean;
421
+ theme: SidePanelThemeContract | null;
422
+ onClose?: () => void;
423
+ onResizeWidth?: (width: string) => void;
424
+ private static nextId;
425
+ titleId: string;
426
+ private activePointerId;
427
+ private dragStartX;
428
+ private dragStartWidth;
429
+ contentRef?: ComponentRef<any>;
430
+ footerRef?: ComponentRef<any>;
431
+ private contentHost;
432
+ private footerHost;
433
+ constructor(cdr: ChangeDetectorRef, i18n: PraxisI18nService);
434
+ ngOnDestroy(): void;
435
+ get hostClasses(): string[];
436
+ get hostCssVars(): Record<string, string>;
437
+ get panelInlineStyles(): Record<string, string | null>;
438
+ get mergedHostStyles(): Record<string, string | null>;
439
+ get closeLabel(): string;
440
+ get resizeHandleLabel(): string;
441
+ get hasHeader(): boolean;
442
+ get hasFooter(): boolean;
443
+ get widthClass(): string | null;
444
+ get showResizeHandle(): boolean;
445
+ setTitle(title: string): void;
446
+ onResizeHandlePointerDown(event: PointerEvent): void;
447
+ onResizeHandleKeydown(event: KeyboardEvent): void;
448
+ onDocumentPointerMove(event: PointerEvent): void;
449
+ onDocumentPointerEnd(event: PointerEvent): void;
450
+ attachContent(component: Type<any>, injector: Injector, inputs?: Record<string, unknown>): ComponentRef<any>;
451
+ attachFooter(component: Type<any>, injector: Injector, inputs?: Record<string, unknown>): ComponentRef<any>;
452
+ clearFooter(): void;
453
+ private applyInputs;
454
+ private resolveSupportedInputs;
455
+ private stopResizeSession;
456
+ private getCurrentWidthPx;
457
+ private applyWidthPx;
458
+ private clampWidthPx;
459
+ private parseWidthPx;
460
+ static ɵfac: i0.ɵɵFactoryDeclaration<BaseSidePanelComponent, never>;
461
+ static ɵcmp: i0.ɵɵComponentDeclaration<BaseSidePanelComponent, "praxis-base-side-panel", never, {}, {}, never, never, true, never>;
462
+ }
463
+
190
464
  /**
191
465
  * Admin helper to load, patch and persist GlobalConfig.
192
466
  * Intended to be used by the Global Config Editor UI.
@@ -398,5 +672,5 @@ interface CapabilityCatalog extends AiCapabilityCatalog {
398
672
  }
399
673
  declare const SETTINGS_PANEL_AI_CAPABILITIES: CapabilityCatalog;
400
674
 
401
- export { GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT, GlobalConfigAdminService, GlobalConfigEditorComponent, SETTINGS_PANEL_AI_CAPABILITIES, SETTINGS_PANEL_DATA, SETTINGS_PANEL_REF, SettingsPanelComponent, SettingsPanelRef, SettingsPanelService, buildGlobalConfigFormConfig, openGlobalConfigEditor, providePraxisSettingsPanelBridge };
402
- export type { Capability, CapabilityCatalog, CapabilityCategory, GlobalConfigEditorFieldSpec, GlobalConfigEditorGroup, GlobalConfigEditorOption, GlobalConfigEditorState, OpenGlobalConfigOptions, SettingsPanelAction, SettingsPanelCloseReason, SettingsPanelConfig, SettingsValueProvider, ValueKind };
675
+ export { BASE_SIDE_PANEL_DATA, BASE_SIDE_PANEL_REF, BaseSidePanelComponent, BaseSidePanelOverlayRef, BaseSidePanelService, GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT, GlobalConfigAdminService, GlobalConfigEditorComponent, SETTINGS_PANEL_AI_CAPABILITIES, SETTINGS_PANEL_DATA, SETTINGS_PANEL_REF, SIDE_PANEL_THEME_CSS_VARS, SettingsPanelComponent, SettingsPanelRef, SettingsPanelService, SurfaceDrawerComponent, buildGlobalConfigFormConfig, openGlobalConfigEditor, providePraxisSettingsPanelBridge, providePraxisSurfaceDrawerBridge };
676
+ export type { BaseSidePanelCloseReason, BaseSidePanelContent, BaseSidePanelOpenOptions, BaseSidePanelRef, BaseSidePanelResizeAxis, BaseSidePanelResult, Capability, CapabilityCatalog, CapabilityCategory, GlobalConfigEditorFieldSpec, GlobalConfigEditorGroup, GlobalConfigEditorOption, GlobalConfigEditorState, OpenGlobalConfigOptions, SettingsPanelAction, SettingsPanelCloseReason, SettingsPanelConfig, SettingsValueProvider, SidePanelCssVarName, SidePanelMotionContract, SidePanelThemeContract, SidePanelWidthPreset, ValueKind };
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@praxisui/settings-panel",
3
- "version": "3.0.0-beta.8",
3
+ "version": "4.0.0-beta.0",
4
4
  "description": "Settings panel for Praxis UI libraries: open editors for configuration at runtime and persist settings.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^20.0.0",
7
7
  "@angular/core": "^20.0.0",
8
8
  "@angular/cdk": "^20.0.0",
9
9
  "@angular/material": "^20.0.0",
10
- "@praxisui/ai": "^3.0.0-beta.8",
11
- "@praxisui/core": "^3.0.0-beta.8",
12
- "@praxisui/dynamic-fields": "^3.0.0-beta.8"
10
+ "@praxisui/ai": "^4.0.0-beta.0",
11
+ "@praxisui/core": "^4.0.0-beta.0",
12
+ "@praxisui/dynamic-fields": "^4.0.0-beta.0"
13
13
  },
14
14
  "dependencies": {
15
15
  "tslib": "^2.3.0"