@memberjunction/ng-versions 5.37.0 → 5.39.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
@@ -1,6 +1,8 @@
1
1
  # @memberjunction/ng-versions
2
2
 
3
- Angular components for viewing entity record version history in MemberJunction applications. Provides a slide panel, label creation, label detail, and record micro-view for working with the built-in Record Changes system.
3
+ Angular components for viewing entity record version history in MemberJunction applications. Provides label creation, label detail, and a record micro-view for working with the built-in Record Changes system.
4
+
5
+ > **Note:** the generic slide-in/dialog primitive `MjSlidePanelComponent` (`mj-slide-panel`) previously lived here and now lives in [`@memberjunction/ng-ui-components`](../ui-components). Import it from there.
4
6
 
5
7
  ## Installation
6
8
 
@@ -14,7 +16,7 @@ MemberJunction includes built-in version control ("Record Changes") that tracks
14
16
 
15
17
  ```mermaid
16
18
  flowchart TD
17
- subgraph Panel["SlidePanelComponent"]
19
+ subgraph Panel["Version History Panel"]
18
20
  A["Version List"]
19
21
  A --> B["RecordMicroViewComponent"]
20
22
  A --> C["LabelCreateComponent"]
@@ -48,16 +50,14 @@ import { VersionsModule } from '@memberjunction/ng-versions';
48
50
  export class YourModule {}
49
51
  ```
50
52
 
51
- ### Slide Panel
53
+ ### Slide Panel — moved
52
54
 
53
- ```html
54
- <mj-slide-panel
55
- [EntityName]="'Products'"
56
- [RecordID]="productId"
57
- [Mode]="'slide'"
58
- [Visible]="showVersionPanel">
59
- </mj-slide-panel>
60
- ```
55
+ > **`MjSlidePanelComponent` (`mj-slide-panel`) now lives in
56
+ > `@memberjunction/ng-ui-components`** as a first-class shared UI primitive.
57
+ > Import it from there:
58
+ > `import { MjSlidePanelComponent } from '@memberjunction/ng-ui-components';`
59
+ > (It's a standalone component — add it to your component/module `imports`.)
60
+ > The `SlidePanelMode` type moved with it.
61
61
 
62
62
  ### Record Micro View
63
63
 
@@ -82,7 +82,6 @@ export class YourModule {}
82
82
 
83
83
  | Component | Selector | Purpose |
84
84
  |-----------|----------|---------|
85
- | `SlidePanelComponent` | `mj-slide-panel` | Container for version history navigation |
86
85
  | `RecordMicroViewComponent` | `mj-record-micro-view` | Compact snapshot preview with field diffs |
87
86
  | `LabelCreateComponent` | `mj-label-create` | Create a named label/bookmark for a version |
88
87
  | `LabelDetailComponent` | `mj-label-detail` | View and manage label details |
@@ -113,15 +112,9 @@ interface FieldChangeView {
113
112
  }
114
113
  ```
115
114
 
116
- ### SlidePanelMode
117
-
118
- ```typescript
119
- type SlidePanelMode = 'slide' | 'dialog';
120
- ```
121
-
122
115
  ## Dependencies
123
116
 
124
- - [@memberjunction/core](../../MJCore/README.md) -- Metadata, RunView
125
- - [@memberjunction/core-entities](../../MJCoreEntities/README.md) -- RecordChange entities
126
- - [@memberjunction/graphql-dataprovider](../../GraphQLDataProvider/README.md) -- Data provider
117
+ - [@memberjunction/core](../../../MJCore/readme.md) -- Metadata, RunView
118
+ - [@memberjunction/core-entities](../../../MJCoreEntities/readme.md) -- RecordChange entities
119
+ - [@memberjunction/graphql-dataprovider](../../../GraphQLDataProvider/README.md) -- Data provider
127
120
  - [@memberjunction/ng-shared-generic](../shared/README.md) -- Loading component
@@ -54,12 +54,4 @@ describe('FieldChangeView type', () => {
54
54
  expect(change.ChangeType).toBe('Removed');
55
55
  });
56
56
  });
57
- describe('SlidePanelMode type', () => {
58
- it('should accept valid modes', () => {
59
- const slide = 'slide';
60
- const dialog = 'dialog';
61
- expect(slide).toBe('slide');
62
- expect(dialog).toBe('dialog');
63
- });
64
- });
65
57
  //# sourceMappingURL=types.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG9C,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,IAAI,GAAkB;YAC1B,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO;YACjB,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE;YACxD,UAAU,EAAE,IAAI;SACjB,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,IAAI,GAAkB;YAC1B,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO;YACjB,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,IAAI;YACpB,UAAU,EAAE,EAAE;SACf,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,MAAM,GAAoB;YAC9B,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE,cAAc;YACxB,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,UAAU;SACvB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAoB;YAC9B,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,aAAa;YACvB,UAAU,EAAE,OAAO;SACpB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAoB;YAC9B,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE,YAAY;YACtB,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,SAAS;SACtB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,KAAK,GAAmB,OAAO,CAAC;QACtC,MAAM,MAAM,GAAmB,QAAQ,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, it, expect } from 'vitest';\nimport type { MicroViewData, FieldChangeView, SlidePanelMode } from '../lib/types';\n\ndescribe('MicroViewData type', () => {\n it('should be constructable with required fields', () => {\n const data: MicroViewData = {\n EntityName: 'MJ: Users',\n EntityID: 'entity-1',\n RecordID: 'rec-1',\n RecordChangeID: 'change-1',\n FullRecordJSON: { Name: 'John', Email: 'john@test.com' },\n FieldDiffs: null\n };\n expect(data.EntityName).toBe('Users');\n expect(data.RecordID).toBe('rec-1');\n expect(data.FullRecordJSON).toEqual({ Name: 'John', Email: 'john@test.com' });\n });\n\n it('should accept null FullRecordJSON', () => {\n const data: MicroViewData = {\n EntityName: 'MJ: Users',\n EntityID: 'entity-1',\n RecordID: 'rec-1',\n RecordChangeID: 'change-1',\n FullRecordJSON: null,\n FieldDiffs: []\n };\n expect(data.FullRecordJSON).toBeNull();\n });\n});\n\ndescribe('FieldChangeView type', () => {\n it('should represent a modified field', () => {\n const change: FieldChangeView = {\n FieldName: 'Email',\n OldValue: 'old@test.com',\n NewValue: 'new@test.com',\n ChangeType: 'Modified'\n };\n expect(change.ChangeType).toBe('Modified');\n });\n\n it('should represent an added field', () => {\n const change: FieldChangeView = {\n FieldName: 'Phone',\n OldValue: '',\n NewValue: '+1-555-0123',\n ChangeType: 'Added'\n };\n expect(change.ChangeType).toBe('Added');\n });\n\n it('should represent a removed field', () => {\n const change: FieldChangeView = {\n FieldName: 'Notes',\n OldValue: 'Some notes',\n NewValue: '',\n ChangeType: 'Removed'\n };\n expect(change.ChangeType).toBe('Removed');\n });\n});\n\ndescribe('SlidePanelMode type', () => {\n it('should accept valid modes', () => {\n const slide: SlidePanelMode = 'slide';\n const dialog: SlidePanelMode = 'dialog';\n expect(slide).toBe('slide');\n expect(dialog).toBe('dialog');\n });\n});\n"]}
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG9C,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,IAAI,GAAkB;YAC1B,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO;YACjB,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE;YACxD,UAAU,EAAE,IAAI;SACjB,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,IAAI,GAAkB;YAC1B,UAAU,EAAE,WAAW;YACvB,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,OAAO;YACjB,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,IAAI;YACpB,UAAU,EAAE,EAAE;SACf,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,MAAM,GAAoB;YAC9B,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE,cAAc;YACxB,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,UAAU;SACvB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,MAAM,GAAoB;YAC9B,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,aAAa;YACvB,UAAU,EAAE,OAAO;SACpB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAoB;YAC9B,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE,YAAY;YACtB,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,SAAS;SACtB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, it, expect } from 'vitest';\nimport type { MicroViewData, FieldChangeView } from '../lib/types';\n\ndescribe('MicroViewData type', () => {\n it('should be constructable with required fields', () => {\n const data: MicroViewData = {\n EntityName: 'MJ: Users',\n EntityID: 'entity-1',\n RecordID: 'rec-1',\n RecordChangeID: 'change-1',\n FullRecordJSON: { Name: 'John', Email: 'john@test.com' },\n FieldDiffs: null\n };\n expect(data.EntityName).toBe('Users');\n expect(data.RecordID).toBe('rec-1');\n expect(data.FullRecordJSON).toEqual({ Name: 'John', Email: 'john@test.com' });\n });\n\n it('should accept null FullRecordJSON', () => {\n const data: MicroViewData = {\n EntityName: 'MJ: Users',\n EntityID: 'entity-1',\n RecordID: 'rec-1',\n RecordChangeID: 'change-1',\n FullRecordJSON: null,\n FieldDiffs: []\n };\n expect(data.FullRecordJSON).toBeNull();\n });\n});\n\ndescribe('FieldChangeView type', () => {\n it('should represent a modified field', () => {\n const change: FieldChangeView = {\n FieldName: 'Email',\n OldValue: 'old@test.com',\n NewValue: 'new@test.com',\n ChangeType: 'Modified'\n };\n expect(change.ChangeType).toBe('Modified');\n });\n\n it('should represent an added field', () => {\n const change: FieldChangeView = {\n FieldName: 'Phone',\n OldValue: '',\n NewValue: '+1-555-0123',\n ChangeType: 'Added'\n };\n expect(change.ChangeType).toBe('Added');\n });\n\n it('should represent a removed field', () => {\n const change: FieldChangeView = {\n FieldName: 'Notes',\n OldValue: 'Some notes',\n NewValue: '',\n ChangeType: 'Removed'\n };\n expect(change.ChangeType).toBe('Removed');\n });\n});\n"]}
@@ -17,6 +17,4 @@ export interface FieldChangeView {
17
17
  NewValue: string;
18
18
  ChangeType: 'Added' | 'Modified' | 'Removed';
19
19
  }
20
- /** Display mode for the slide panel container. */
21
- export type SlidePanelMode = 'slide' | 'dialog';
22
20
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/C,UAAU,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;CACxC;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;CAChD;AAED,kDAAkD;AAClD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/C,UAAU,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;CACxC;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;CAChD"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG","sourcesContent":["/**\n * Shared types for the ng-versions package.\n */\n\n/** Data passed to the record micro-view for displaying a snapshot record. */\nexport interface MicroViewData {\n EntityName: string;\n EntityID: string;\n RecordID: string;\n RecordChangeID: string;\n FullRecordJSON: Record<string, unknown> | null;\n FieldDiffs: FieldChangeView[] | null;\n}\n\n/** A single field-level change in a diff comparison. */\nexport interface FieldChangeView {\n FieldName: string;\n OldValue: string;\n NewValue: string;\n ChangeType: 'Added' | 'Modified' | 'Removed';\n}\n\n/** Display mode for the slide panel container. */\nexport type SlidePanelMode = 'slide' | 'dialog';\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG","sourcesContent":["/**\n * Shared types for the ng-versions package.\n */\n\n/** Data passed to the record micro-view for displaying a snapshot record. */\nexport interface MicroViewData {\n EntityName: string;\n EntityID: string;\n RecordID: string;\n RecordChangeID: string;\n FullRecordJSON: Record<string, unknown> | null;\n FieldDiffs: FieldChangeView[] | null;\n}\n\n/** A single field-level change in a diff comparison. */\nexport interface FieldChangeView {\n FieldName: string;\n OldValue: string;\n NewValue: string;\n ChangeType: 'Added' | 'Modified' | 'Removed';\n}\n"]}
@@ -1,14 +1,13 @@
1
1
  import * as i0 from "@angular/core";
2
- import * as i1 from "./panel/slide-panel.component";
3
- import * as i2 from "./record-micro-view/record-micro-view.component";
4
- import * as i3 from "./label-create/label-create.component";
5
- import * as i4 from "./label-detail/label-detail.component";
6
- import * as i5 from "@angular/common";
7
- import * as i6 from "@angular/forms";
8
- import * as i7 from "@memberjunction/ng-shared-generic";
2
+ import * as i1 from "./record-micro-view/record-micro-view.component";
3
+ import * as i2 from "./label-create/label-create.component";
4
+ import * as i3 from "./label-detail/label-detail.component";
5
+ import * as i4 from "@angular/common";
6
+ import * as i5 from "@angular/forms";
7
+ import * as i6 from "@memberjunction/ng-shared-generic";
9
8
  export declare class VersionsModule {
10
9
  static ɵfac: i0.ɵɵFactoryDeclaration<VersionsModule, never>;
11
- static ɵmod: i0.ɵɵNgModuleDeclaration<VersionsModule, [typeof i1.MjSlidePanelComponent, typeof i2.MjRecordMicroViewComponent, typeof i3.MjLabelCreateComponent, typeof i4.MjLabelDetailComponent], [typeof i5.CommonModule, typeof i6.FormsModule, typeof i7.SharedGenericModule], [typeof i1.MjSlidePanelComponent, typeof i2.MjRecordMicroViewComponent, typeof i3.MjLabelCreateComponent, typeof i4.MjLabelDetailComponent]>;
10
+ static ɵmod: i0.ɵɵNgModuleDeclaration<VersionsModule, [typeof i1.MjRecordMicroViewComponent, typeof i2.MjLabelCreateComponent, typeof i3.MjLabelDetailComponent], [typeof i4.CommonModule, typeof i5.FormsModule, typeof i6.SharedGenericModule], [typeof i1.MjRecordMicroViewComponent, typeof i2.MjLabelCreateComponent, typeof i3.MjLabelDetailComponent]>;
12
11
  static ɵinj: i0.ɵɵInjectorDeclaration<VersionsModule>;
13
12
  }
14
13
  //# sourceMappingURL=versions.module.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"versions.module.d.ts","sourceRoot":"","sources":["../../src/lib/versions.module.ts"],"names":[],"mappings":";;;;;;;;AAUA,qBAmBa,cAAc;yCAAd,cAAc;0CAAd,cAAc;0CAAd,cAAc;CAAG"}
1
+ {"version":3,"file":"versions.module.d.ts","sourceRoot":"","sources":["../../src/lib/versions.module.ts"],"names":[],"mappings":";;;;;;;AASA,qBAiBa,cAAc;yCAAd,cAAc;0CAAd,cAAc;0CAAd,cAAc;CAAG"}
@@ -2,7 +2,6 @@ import { NgModule } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { FormsModule } from '@angular/forms';
4
4
  import { SharedGenericModule } from '@memberjunction/ng-shared-generic';
5
- import { MjSlidePanelComponent } from './panel/slide-panel.component';
6
5
  import { MjRecordMicroViewComponent } from './record-micro-view/record-micro-view.component';
7
6
  import { MjLabelCreateComponent } from './label-create/label-create.component';
8
7
  import { MjLabelDetailComponent } from './label-detail/label-detail.component';
@@ -18,7 +17,6 @@ export class VersionsModule {
18
17
  type: NgModule,
19
18
  args: [{
20
19
  declarations: [
21
- MjSlidePanelComponent,
22
20
  MjRecordMicroViewComponent,
23
21
  MjLabelCreateComponent,
24
22
  MjLabelDetailComponent
@@ -29,20 +27,17 @@ export class VersionsModule {
29
27
  SharedGenericModule
30
28
  ],
31
29
  exports: [
32
- MjSlidePanelComponent,
33
30
  MjRecordMicroViewComponent,
34
31
  MjLabelCreateComponent,
35
32
  MjLabelDetailComponent
36
33
  ]
37
34
  }]
38
35
  }], null, null); })();
39
- (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(VersionsModule, { declarations: [MjSlidePanelComponent,
40
- MjRecordMicroViewComponent,
36
+ (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(VersionsModule, { declarations: [MjRecordMicroViewComponent,
41
37
  MjLabelCreateComponent,
42
38
  MjLabelDetailComponent], imports: [CommonModule,
43
39
  FormsModule,
44
- SharedGenericModule], exports: [MjSlidePanelComponent,
45
- MjRecordMicroViewComponent,
40
+ SharedGenericModule], exports: [MjRecordMicroViewComponent,
46
41
  MjLabelCreateComponent,
47
42
  MjLabelDetailComponent] }); })();
48
43
  //# sourceMappingURL=versions.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"versions.module.js","sourceRoot":"","sources":["../../src/lib/versions.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;;AAqB/E,MAAM,OAAO,cAAc;wGAAd,cAAc;4DAAd,cAAc;gEAXnB,YAAY;YACZ,WAAW;YACX,mBAAmB;;iFASd,cAAc;cAnB1B,QAAQ;eAAC;gBACN,YAAY,EAAE;oBACV,qBAAqB;oBACrB,0BAA0B;oBAC1B,sBAAsB;oBACtB,sBAAsB;iBACzB;gBACD,OAAO,EAAE;oBACL,YAAY;oBACZ,WAAW;oBACX,mBAAmB;iBACtB;gBACD,OAAO,EAAE;oBACL,qBAAqB;oBACrB,0BAA0B;oBAC1B,sBAAsB;oBACtB,sBAAsB;iBACzB;aACJ;;wFACY,cAAc,mBAjBnB,qBAAqB;QACrB,0BAA0B;QAC1B,sBAAsB;QACtB,sBAAsB,aAGtB,YAAY;QACZ,WAAW;QACX,mBAAmB,aAGnB,qBAAqB;QACrB,0BAA0B;QAC1B,sBAAsB;QACtB,sBAAsB","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\n\nimport { MjSlidePanelComponent } from './panel/slide-panel.component';\nimport { MjRecordMicroViewComponent } from './record-micro-view/record-micro-view.component';\nimport { MjLabelCreateComponent } from './label-create/label-create.component';\nimport { MjLabelDetailComponent } from './label-detail/label-detail.component';\n\n@NgModule({\n declarations: [\n MjSlidePanelComponent,\n MjRecordMicroViewComponent,\n MjLabelCreateComponent,\n MjLabelDetailComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n SharedGenericModule\n ],\n exports: [\n MjSlidePanelComponent,\n MjRecordMicroViewComponent,\n MjLabelCreateComponent,\n MjLabelDetailComponent\n ]\n})\nexport class VersionsModule {}\n"]}
1
+ {"version":3,"file":"versions.module.js","sourceRoot":"","sources":["../../src/lib/versions.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;;AAmB/E,MAAM,OAAO,cAAc;wGAAd,cAAc;4DAAd,cAAc;gEAVnB,YAAY;YACZ,WAAW;YACX,mBAAmB;;iFAQd,cAAc;cAjB1B,QAAQ;eAAC;gBACN,YAAY,EAAE;oBACV,0BAA0B;oBAC1B,sBAAsB;oBACtB,sBAAsB;iBACzB;gBACD,OAAO,EAAE;oBACL,YAAY;oBACZ,WAAW;oBACX,mBAAmB;iBACtB;gBACD,OAAO,EAAE;oBACL,0BAA0B;oBAC1B,sBAAsB;oBACtB,sBAAsB;iBACzB;aACJ;;wFACY,cAAc,mBAfnB,0BAA0B;QAC1B,sBAAsB;QACtB,sBAAsB,aAGtB,YAAY;QACZ,WAAW;QACX,mBAAmB,aAGnB,0BAA0B;QAC1B,sBAAsB;QACtB,sBAAsB","sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { SharedGenericModule } from '@memberjunction/ng-shared-generic';\n\nimport { MjRecordMicroViewComponent } from './record-micro-view/record-micro-view.component';\nimport { MjLabelCreateComponent } from './label-create/label-create.component';\nimport { MjLabelDetailComponent } from './label-detail/label-detail.component';\n\n@NgModule({\n declarations: [\n MjRecordMicroViewComponent,\n MjLabelCreateComponent,\n MjLabelDetailComponent\n ],\n imports: [\n CommonModule,\n FormsModule,\n SharedGenericModule\n ],\n exports: [\n MjRecordMicroViewComponent,\n MjLabelCreateComponent,\n MjLabelDetailComponent\n ]\n})\nexport class VersionsModule {}\n"]}
@@ -1,6 +1,5 @@
1
1
  export * from './lib/versions.module';
2
2
  export * from './lib/types';
3
- export * from './lib/panel/slide-panel.component';
4
3
  export * from './lib/record-micro-view/record-micro-view.component';
5
4
  export * from './lib/label-create/label-create.component';
6
5
  export * from './lib/label-detail/label-detail.component';
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,mCAAmC,CAAC;AAClD,cAAc,qDAAqD,CAAC;AACpE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC"}
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAG5B,cAAc,qDAAqD,CAAC;AACpE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC"}
@@ -1,6 +1,7 @@
1
1
  export * from './lib/versions.module';
2
2
  export * from './lib/types';
3
- export * from './lib/panel/slide-panel.component';
3
+ // NOTE: MjSlidePanelComponent moved to @memberjunction/ng-ui-components.
4
+ // Import it directly from there: import { MjSlidePanelComponent } from '@memberjunction/ng-ui-components';
4
5
  export * from './lib/record-micro-view/record-micro-view.component';
5
6
  export * from './lib/label-create/label-create.component';
6
7
  export * from './lib/label-detail/label-detail.component';
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,mCAAmC,CAAC;AAClD,cAAc,qDAAqD,CAAC;AACpE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC","sourcesContent":["export * from './lib/versions.module';\nexport * from './lib/types';\nexport * from './lib/panel/slide-panel.component';\nexport * from './lib/record-micro-view/record-micro-view.component';\nexport * from './lib/label-create/label-create.component';\nexport * from './lib/label-detail/label-detail.component';\n"]}
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,yEAAyE;AACzE,2GAA2G;AAC3G,cAAc,qDAAqD,CAAC;AACpE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC","sourcesContent":["export * from './lib/versions.module';\nexport * from './lib/types';\n// NOTE: MjSlidePanelComponent moved to @memberjunction/ng-ui-components.\n// Import it directly from there: import { MjSlidePanelComponent } from '@memberjunction/ng-ui-components';\nexport * from './lib/record-micro-view/record-micro-view.component';\nexport * from './lib/label-create/label-create.component';\nexport * from './lib/label-detail/label-detail.component';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-versions",
3
- "version": "5.37.0",
3
+ "version": "5.39.0",
4
4
  "description": "MemberJunction: Angular Version History Components - Label creation, detail viewing, and slide panel",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -26,12 +26,12 @@
26
26
  "@angular/forms": "21.1.3"
27
27
  },
28
28
  "dependencies": {
29
- "@memberjunction/core": "5.37.0",
30
- "@memberjunction/ng-base-types": "5.37.0",
31
- "@memberjunction/core-entities": "5.37.0",
32
- "@memberjunction/global": "5.37.0",
33
- "@memberjunction/graphql-dataprovider": "5.37.0",
34
- "@memberjunction/ng-shared-generic": "5.37.0",
29
+ "@memberjunction/core": "5.39.0",
30
+ "@memberjunction/ng-base-types": "5.39.0",
31
+ "@memberjunction/core-entities": "5.39.0",
32
+ "@memberjunction/global": "5.39.0",
33
+ "@memberjunction/graphql-dataprovider": "5.39.0",
34
+ "@memberjunction/ng-shared-generic": "5.39.0",
35
35
  "rxjs": "^7.8.2",
36
36
  "tslib": "^2.8.1"
37
37
  },
@@ -1,45 +0,0 @@
1
- import { EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, ElementRef, NgZone } from '@angular/core';
2
- import { SlidePanelMode } from '../types';
3
- import * as i0 from "@angular/core";
4
- export declare class MjSlidePanelComponent implements OnInit, OnDestroy {
5
- private cdr;
6
- private ngZone;
7
- private elRef;
8
- Mode: SlidePanelMode;
9
- Title: string;
10
- set Visible(value: boolean);
11
- get Visible(): boolean;
12
- private _visible;
13
- private initialized;
14
- Resizable: boolean;
15
- MinWidthPx: number;
16
- MaxWidthRatio: number;
17
- /** Initial width in pixels. Defaults to 65% of viewport for slide, 800px for dialog. */
18
- set WidthPx(value: number);
19
- get WidthPx(): number;
20
- Closed: EventEmitter<void>;
21
- WidthChanged: EventEmitter<number>;
22
- /**
23
- * Optional guard called before any close gesture (X button, backdrop click, Escape).
24
- * Return `false` to cancel the close — e.g., when an in-progress operation is running.
25
- * The panel itself never shows a dialog; the consumer is responsible for any confirmation UI.
26
- */
27
- CanClose: (() => boolean) | null;
28
- IsVisible: boolean;
29
- private _widthPx;
30
- private isResizing;
31
- private boundOnResizeMove;
32
- private boundOnResizeEnd;
33
- constructor(cdr: ChangeDetectorRef, ngZone: NgZone, elRef: ElementRef);
34
- ngOnInit(): void;
35
- ngOnDestroy(): void;
36
- OnEscapeKey(): void;
37
- OnClose(): void;
38
- OnBackdropClick(): void;
39
- OnResizeStart(event: MouseEvent): void;
40
- private onResizeMove;
41
- private onResizeEnd;
42
- static ɵfac: i0.ɵɵFactoryDeclaration<MjSlidePanelComponent, never>;
43
- static ɵcmp: i0.ɵɵComponentDeclaration<MjSlidePanelComponent, "mj-slide-panel", never, { "Mode": { "alias": "Mode"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "Visible": { "alias": "Visible"; "required": false; }; "Resizable": { "alias": "Resizable"; "required": false; }; "MinWidthPx": { "alias": "MinWidthPx"; "required": false; }; "MaxWidthRatio": { "alias": "MaxWidthRatio"; "required": false; }; "WidthPx": { "alias": "WidthPx"; "required": false; }; "CanClose": { "alias": "CanClose"; "required": false; }; }, { "Closed": "Closed"; "WidthChanged": "WidthChanged"; }, never, ["*", "[dialog-content]"], false, never>;
44
- }
45
- //# sourceMappingURL=slide-panel.component.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slide-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/panel/slide-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAyC,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxK,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;;AAE1C,qBAOa,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAyDvD,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IA1DR,IAAI,EAAE,cAAc,CAAW;IAC/B,KAAK,SAAM;IACpB,IACI,OAAO,CAAC,KAAK,EAAE,OAAO,EAezB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,WAAW,CAAS;IAEnB,SAAS,UAAQ;IACjB,UAAU,SAAO;IACjB,aAAa,SAAQ;IAE9B,wFAAwF;IACxF,IACI,OAAO,CAAC,KAAK,EAAE,MAAM,EAExB;IACD,IAAI,OAAO,IAAI,MAAM,CAEpB;IAES,MAAM,qBAA4B;IAClC,YAAY,uBAA8B;IAEpD;;;;OAIG;IACM,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,IAAI,CAAQ;IAE1C,SAAS,UAAS;IACzB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,iBAAiB,CAAgC;IACzD,OAAO,CAAC,gBAAgB,CAA+B;gBAG3C,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU;IAG7B,QAAQ,IAAI,IAAI;IAkBhB,WAAW,IAAI,IAAI;IAMZ,WAAW,IAAI,IAAI;IAInB,OAAO,IAAI,IAAI;IASf,eAAe,IAAI,IAAI;IAQvB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAa7C,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,WAAW;yCAhIV,qBAAqB;2CAArB,qBAAqB;CAyIjC"}
@@ -1,238 +0,0 @@
1
- import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, HostListener } from '@angular/core';
2
- import * as i0 from "@angular/core";
3
- const _c0 = ["*", [["", "dialog-content", ""]]];
4
- const _c1 = ["*", "[dialog-content]"];
5
- function MjSlidePanelComponent_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
6
- const _r1 = i0.ɵɵgetCurrentView();
7
- i0.ɵɵelementStart(0, "div", 7);
8
- i0.ɵɵlistener("mousedown", function MjSlidePanelComponent_Conditional_1_Conditional_1_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnResizeStart($event)); });
9
- i0.ɵɵelement(1, "div", 8);
10
- i0.ɵɵelementEnd();
11
- } }
12
- function MjSlidePanelComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
13
- const _r3 = i0.ɵɵgetCurrentView();
14
- i0.ɵɵelementStart(0, "div", 5)(1, "h2", 9);
15
- i0.ɵɵtext(2);
16
- i0.ɵɵelementEnd();
17
- i0.ɵɵelementStart(3, "button", 10);
18
- i0.ɵɵlistener("click", function MjSlidePanelComponent_Conditional_1_Conditional_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnClose()); });
19
- i0.ɵɵelement(4, "i", 11);
20
- i0.ɵɵelementEnd()();
21
- } if (rf & 2) {
22
- const ctx_r1 = i0.ɵɵnextContext(2);
23
- i0.ɵɵadvance(2);
24
- i0.ɵɵtextInterpolate(ctx_r1.Title);
25
- } }
26
- function MjSlidePanelComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
27
- i0.ɵɵelementStart(0, "div", 3);
28
- i0.ɵɵconditionalCreate(1, MjSlidePanelComponent_Conditional_1_Conditional_1_Template, 2, 0, "div", 4);
29
- i0.ɵɵconditionalCreate(2, MjSlidePanelComponent_Conditional_1_Conditional_2_Template, 5, 1, "div", 5);
30
- i0.ɵɵelementStart(3, "div", 6);
31
- i0.ɵɵprojection(4);
32
- i0.ɵɵelementEnd()();
33
- } if (rf & 2) {
34
- const ctx_r1 = i0.ɵɵnextContext();
35
- i0.ɵɵstyleProp("width", ctx_r1.WidthPx, "px")("max-width", ctx_r1.MaxWidthRatio * 100 + "vw");
36
- i0.ɵɵclassProp("visible", ctx_r1.IsVisible);
37
- i0.ɵɵadvance();
38
- i0.ɵɵconditional(ctx_r1.Resizable ? 1 : -1);
39
- i0.ɵɵadvance();
40
- i0.ɵɵconditional(ctx_r1.Title ? 2 : -1);
41
- } }
42
- function MjSlidePanelComponent_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
43
- const _r4 = i0.ɵɵgetCurrentView();
44
- i0.ɵɵelementStart(0, "div", 5)(1, "h2", 9);
45
- i0.ɵɵtext(2);
46
- i0.ɵɵelementEnd();
47
- i0.ɵɵelementStart(3, "button", 10);
48
- i0.ɵɵlistener("click", function MjSlidePanelComponent_Conditional_2_Conditional_1_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnClose()); });
49
- i0.ɵɵelement(4, "i", 11);
50
- i0.ɵɵelementEnd()();
51
- } if (rf & 2) {
52
- const ctx_r1 = i0.ɵɵnextContext(2);
53
- i0.ɵɵadvance(2);
54
- i0.ɵɵtextInterpolate(ctx_r1.Title);
55
- } }
56
- function MjSlidePanelComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
57
- i0.ɵɵelementStart(0, "div", 12);
58
- i0.ɵɵconditionalCreate(1, MjSlidePanelComponent_Conditional_2_Conditional_1_Template, 5, 1, "div", 5);
59
- i0.ɵɵelementStart(2, "div", 13);
60
- i0.ɵɵprojection(3, 1);
61
- i0.ɵɵelementEnd()();
62
- } if (rf & 2) {
63
- const ctx_r1 = i0.ɵɵnextContext();
64
- i0.ɵɵstyleProp("width", ctx_r1.WidthPx, "px");
65
- i0.ɵɵclassProp("visible", ctx_r1.IsVisible);
66
- i0.ɵɵadvance();
67
- i0.ɵɵconditional(ctx_r1.Title ? 1 : -1);
68
- } }
69
- export class MjSlidePanelComponent {
70
- cdr;
71
- ngZone;
72
- elRef;
73
- Mode = 'slide';
74
- Title = '';
75
- set Visible(value) {
76
- const changed = this._visible !== value;
77
- this._visible = value;
78
- if (changed && this.initialized) {
79
- if (value) {
80
- // Opening: animate in on next microtask
81
- Promise.resolve().then(() => {
82
- this.IsVisible = true;
83
- this.cdr.markForCheck();
84
- });
85
- }
86
- else {
87
- this.IsVisible = false;
88
- this.cdr.markForCheck();
89
- }
90
- }
91
- }
92
- get Visible() {
93
- return this._visible;
94
- }
95
- _visible = true;
96
- initialized = false;
97
- Resizable = true;
98
- MinWidthPx = 400;
99
- MaxWidthRatio = 0.92;
100
- /** Initial width in pixels. Defaults to 65% of viewport for slide, 800px for dialog. */
101
- set WidthPx(value) {
102
- this._widthPx = value;
103
- }
104
- get WidthPx() {
105
- return this._widthPx;
106
- }
107
- Closed = new EventEmitter();
108
- WidthChanged = new EventEmitter();
109
- /**
110
- * Optional guard called before any close gesture (X button, backdrop click, Escape).
111
- * Return `false` to cancel the close — e.g., when an in-progress operation is running.
112
- * The panel itself never shows a dialog; the consumer is responsible for any confirmation UI.
113
- */
114
- CanClose = null;
115
- IsVisible = false;
116
- _widthPx = 0;
117
- isResizing = false;
118
- boundOnResizeMove = this.onResizeMove.bind(this);
119
- boundOnResizeEnd = this.onResizeEnd.bind(this);
120
- constructor(cdr, ngZone, elRef) {
121
- this.cdr = cdr;
122
- this.ngZone = ngZone;
123
- this.elRef = elRef;
124
- }
125
- ngOnInit() {
126
- if (this._widthPx === 0) {
127
- this._widthPx = this.Mode === 'dialog'
128
- ? 800
129
- : Math.max(this.MinWidthPx, Math.min(window.innerWidth * 0.65, 1000));
130
- }
131
- this.initialized = true;
132
- // Animate in on next microtask if initially visible
133
- if (this._visible) {
134
- Promise.resolve().then(() => {
135
- this.IsVisible = true;
136
- this.cdr.markForCheck();
137
- });
138
- }
139
- }
140
- ngOnDestroy() {
141
- document.removeEventListener('mousemove', this.boundOnResizeMove);
142
- document.removeEventListener('mouseup', this.boundOnResizeEnd);
143
- }
144
- OnEscapeKey() {
145
- this.OnClose();
146
- }
147
- OnClose() {
148
- if (this.CanClose && !this.CanClose())
149
- return;
150
- this.IsVisible = false;
151
- this._visible = false;
152
- this.cdr.markForCheck();
153
- // Wait for CSS transition to complete
154
- setTimeout(() => this.Closed.emit(), 300);
155
- }
156
- OnBackdropClick() {
157
- this.OnClose();
158
- }
159
- // =========================================================================
160
- // Resize
161
- // =========================================================================
162
- OnResizeStart(event) {
163
- if (!this.Resizable || this.Mode === 'dialog')
164
- return;
165
- event.preventDefault();
166
- this.isResizing = true;
167
- document.body.style.cursor = 'col-resize';
168
- document.body.style.userSelect = 'none';
169
- this.ngZone.runOutsideAngular(() => {
170
- document.addEventListener('mousemove', this.boundOnResizeMove);
171
- document.addEventListener('mouseup', this.boundOnResizeEnd);
172
- });
173
- }
174
- onResizeMove(event) {
175
- if (!this.isResizing)
176
- return;
177
- const viewportWidth = window.innerWidth;
178
- const maxWidth = viewportWidth * this.MaxWidthRatio;
179
- this._widthPx = Math.max(this.MinWidthPx, Math.min(maxWidth, viewportWidth - event.clientX));
180
- this.ngZone.run(() => this.cdr.markForCheck());
181
- }
182
- onResizeEnd() {
183
- if (!this.isResizing)
184
- return;
185
- this.isResizing = false;
186
- document.body.style.cursor = '';
187
- document.body.style.userSelect = '';
188
- document.removeEventListener('mousemove', this.boundOnResizeMove);
189
- document.removeEventListener('mouseup', this.boundOnResizeEnd);
190
- this.WidthChanged.emit(this._widthPx);
191
- }
192
- static ɵfac = function MjSlidePanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MjSlidePanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i0.ElementRef)); };
193
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjSlidePanelComponent, selectors: [["mj-slide-panel"]], hostBindings: function MjSlidePanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
194
- i0.ɵɵlistener("keydown.escape", function MjSlidePanelComponent_keydown_escape_HostBindingHandler() { return ctx.OnEscapeKey(); }, i0.ɵɵresolveDocument);
195
- } }, inputs: { Mode: "Mode", Title: "Title", Visible: "Visible", Resizable: "Resizable", MinWidthPx: "MinWidthPx", MaxWidthRatio: "MaxWidthRatio", WidthPx: "WidthPx", CanClose: "CanClose" }, outputs: { Closed: "Closed", WidthChanged: "WidthChanged" }, standalone: false, ngContentSelectors: _c1, decls: 3, vars: 6, consts: [[1, "sp-backdrop", 3, "click"], [1, "sp-panel", 3, "visible", "width", "max-width"], [1, "sp-dialog", 3, "visible", "width"], [1, "sp-panel"], [1, "sp-resize-handle"], [1, "sp-header"], [1, "sp-body"], [1, "sp-resize-handle", 3, "mousedown"], [1, "sp-resize-grip"], [1, "sp-title"], [1, "sp-close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "sp-dialog"], [1, "sp-body", "sp-dialog-body"]], template: function MjSlidePanelComponent_Template(rf, ctx) { if (rf & 1) {
196
- i0.ɵɵprojectionDef(_c0);
197
- i0.ɵɵelementStart(0, "div", 0);
198
- i0.ɵɵlistener("click", function MjSlidePanelComponent_Template_div_click_0_listener() { return ctx.OnBackdropClick(); });
199
- i0.ɵɵelementEnd();
200
- i0.ɵɵconditionalCreate(1, MjSlidePanelComponent_Conditional_1_Template, 5, 8, "div", 1);
201
- i0.ɵɵconditionalCreate(2, MjSlidePanelComponent_Conditional_2_Template, 4, 5, "div", 2);
202
- } if (rf & 2) {
203
- i0.ɵɵclassProp("visible", ctx.IsVisible)("sp-dialog-backdrop", ctx.Mode === "dialog");
204
- i0.ɵɵadvance();
205
- i0.ɵɵconditional(ctx.Mode === "slide" ? 1 : -1);
206
- i0.ɵɵadvance();
207
- i0.ɵɵconditional(ctx.Mode === "dialog" ? 2 : -1);
208
- } }, styles: ["\n\n\n\n\n\n\n.sp-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: transparent;\n z-index: 1000;\n transition: background 0.3s ease;\n pointer-events: none;\n}\n\n.sp-backdrop.visible[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n pointer-events: auto;\n}\n\n.sp-dialog-backdrop.visible[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n}\n\n\n\n\n\n\n\n\n.sp-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 400px;\n max-width: 92vw;\n}\n\n.sp-panel.visible[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n\n\n\n\n\n\n\n.sp-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 360px;\n max-width: 95vw;\n}\n\n.sp-dialog.visible[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n\n\n\n\n\n.sp-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: -4px;\n top: 0;\n width: 8px;\n height: 100%;\n cursor: col-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover .sp-resize-grip[_ngcontent-%COMP%], \n.sp-resize-handle[_ngcontent-%COMP%]:active .sp-resize-grip[_ngcontent-%COMP%] {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n.sp-resize-grip[_ngcontent-%COMP%] {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease, background 0.2s ease;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, transparent);\n}\n\n\n\n\n\n\n\n\n.sp-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.sp-title[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.sp-close-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: none;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.sp-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n\n\n\n.sp-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.sp-dialog-body[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n\n\n\n\n\n\n\n@media (max-width: 768px) {\n .sp-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n min-width: unset;\n }\n\n .sp-resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n\n .sp-dialog[_ngcontent-%COMP%] {\n width: 95vw !important;\n max-height: 90vh;\n }\n}"], changeDetection: 0 });
209
- }
210
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjSlidePanelComponent, [{
211
- type: Component,
212
- args: [{ standalone: false, selector: 'mj-slide-panel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Backdrop overlay -->\n<div class=\"sp-backdrop\"\n [class.visible]=\"IsVisible\"\n [class.sp-dialog-backdrop]=\"Mode === 'dialog'\"\n (click)=\"OnBackdropClick()\">\n</div>\n\n<!-- Panel (slide-in from right) -->\n@if (Mode === 'slide') {\n <div\n class=\"sp-panel\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\"\n [style.max-width]=\"(MaxWidthRatio * 100) + 'vw'\">\n <!-- Resize handle -->\n @if (Resizable) {\n <div class=\"sp-resize-handle\" (mousedown)=\"OnResizeStart($event)\">\n <div class=\"sp-resize-grip\"></div>\n </div>\n }\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body\">\n <ng-content></ng-content>\n </div>\n </div>\n}\n\n<!-- Dialog (centered modal) -->\n@if (Mode === 'dialog') {\n <div\n class=\"sp-dialog\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\">\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body sp-dialog-body\">\n <ng-content select=\"[dialog-content]\"></ng-content>\n </div>\n </div>\n}\n", styles: ["/* ================================================================= */\n/* BACKDROP */\n/* ================================================================= */\n\n.sp-backdrop {\n position: fixed;\n inset: 0;\n background: transparent;\n z-index: 1000;\n transition: background 0.3s ease;\n pointer-events: none;\n}\n\n.sp-backdrop.visible {\n background: var(--mj-bg-overlay);\n pointer-events: auto;\n}\n\n.sp-dialog-backdrop.visible {\n background: var(--mj-bg-overlay);\n}\n\n/* ================================================================= */\n/* SLIDE PANEL */\n/* ================================================================= */\n\n.sp-panel {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 400px;\n max-width: 92vw;\n}\n\n.sp-panel.visible {\n transform: translateX(0);\n}\n\n/* ================================================================= */\n/* DIALOG (centered modal) */\n/* ================================================================= */\n\n.sp-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 360px;\n max-width: 95vw;\n}\n\n.sp-dialog.visible {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* ================================================================= */\n/* RESIZE HANDLE */\n/* ================================================================= */\n\n.sp-resize-handle {\n position: absolute;\n left: -4px;\n top: 0;\n width: 8px;\n height: 100%;\n cursor: col-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sp-resize-handle:hover .sp-resize-grip,\n.sp-resize-handle:active .sp-resize-grip {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n.sp-resize-grip {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease, background 0.2s ease;\n}\n\n.sp-resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, transparent);\n}\n\n/* ================================================================= */\n/* HEADER */\n/* ================================================================= */\n\n.sp-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.sp-title {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.sp-close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: none;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.sp-close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* ================================================================= */\n/* BODY */\n/* ================================================================= */\n\n.sp-body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.sp-dialog-body {\n padding: 0;\n}\n\n/* ================================================================= */\n/* RESPONSIVE */\n/* ================================================================= */\n\n@media (max-width: 768px) {\n .sp-panel {\n width: 100% !important;\n min-width: unset;\n }\n\n .sp-resize-handle {\n display: none;\n }\n\n .sp-dialog {\n width: 95vw !important;\n max-height: 90vh;\n }\n}\n"] }]
213
- }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.ElementRef }], { Mode: [{
214
- type: Input
215
- }], Title: [{
216
- type: Input
217
- }], Visible: [{
218
- type: Input
219
- }], Resizable: [{
220
- type: Input
221
- }], MinWidthPx: [{
222
- type: Input
223
- }], MaxWidthRatio: [{
224
- type: Input
225
- }], WidthPx: [{
226
- type: Input
227
- }], Closed: [{
228
- type: Output
229
- }], WidthChanged: [{
230
- type: Output
231
- }], CanClose: [{
232
- type: Input
233
- }], OnEscapeKey: [{
234
- type: HostListener,
235
- args: ['document:keydown.escape']
236
- }] }); })();
237
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjSlidePanelComponent, { className: "MjSlidePanelComponent", filePath: "src/lib/panel/slide-panel.component.ts", lineNumber: 11 }); })();
238
- //# sourceMappingURL=slide-panel.component.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slide-panel.component.js","sourceRoot":"","sources":["../../../src/lib/panel/slide-panel.component.ts","../../../src/lib/panel/slide-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, ChangeDetectionStrategy, HostListener, ElementRef, NgZone } from '@angular/core';\nimport { SlidePanelMode } from '../types';\n\n@Component({\n standalone: false,\n selector: 'mj-slide-panel',\n templateUrl: './slide-panel.component.html',\n styleUrls: ['./slide-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MjSlidePanelComponent implements OnInit, OnDestroy {\n @Input() Mode: SlidePanelMode = 'slide';\n @Input() Title = '';\n @Input()\n set Visible(value: boolean) {\n const changed = this._visible !== value;\n this._visible = value;\n if (changed && this.initialized) {\n if (value) {\n // Opening: animate in on next microtask\n Promise.resolve().then(() => {\n this.IsVisible = true;\n this.cdr.markForCheck();\n });\n } else {\n this.IsVisible = false;\n this.cdr.markForCheck();\n }\n }\n }\n get Visible(): boolean {\n return this._visible;\n }\n private _visible = true;\n private initialized = false;\n\n @Input() Resizable = true;\n @Input() MinWidthPx = 400;\n @Input() MaxWidthRatio = 0.92;\n\n /** Initial width in pixels. Defaults to 65% of viewport for slide, 800px for dialog. */\n @Input()\n set WidthPx(value: number) {\n this._widthPx = value;\n }\n get WidthPx(): number {\n return this._widthPx;\n }\n\n @Output() Closed = new EventEmitter<void>();\n @Output() WidthChanged = new EventEmitter<number>();\n\n /**\n * Optional guard called before any close gesture (X button, backdrop click, Escape).\n * Return `false` to cancel the close — e.g., when an in-progress operation is running.\n * The panel itself never shows a dialog; the consumer is responsible for any confirmation UI.\n */\n @Input() CanClose: (() => boolean) | null = null;\n\n public IsVisible = false;\n private _widthPx = 0;\n private isResizing = false;\n\n private boundOnResizeMove = this.onResizeMove.bind(this);\n private boundOnResizeEnd = this.onResizeEnd.bind(this);\n\n constructor(\n private cdr: ChangeDetectorRef,\n private ngZone: NgZone,\n private elRef: ElementRef\n ) {}\n\n ngOnInit(): void {\n if (this._widthPx === 0) {\n this._widthPx = this.Mode === 'dialog'\n ? 800\n : Math.max(this.MinWidthPx, Math.min(window.innerWidth * 0.65, 1000));\n }\n\n this.initialized = true;\n\n // Animate in on next microtask if initially visible\n if (this._visible) {\n Promise.resolve().then(() => {\n this.IsVisible = true;\n this.cdr.markForCheck();\n });\n }\n }\n\n ngOnDestroy(): void {\n document.removeEventListener('mousemove', this.boundOnResizeMove);\n document.removeEventListener('mouseup', this.boundOnResizeEnd);\n }\n\n @HostListener('document:keydown.escape')\n public OnEscapeKey(): void {\n this.OnClose();\n }\n\n public OnClose(): void {\n if (this.CanClose && !this.CanClose()) return;\n this.IsVisible = false;\n this._visible = false;\n this.cdr.markForCheck();\n // Wait for CSS transition to complete\n setTimeout(() => this.Closed.emit(), 300);\n }\n\n public OnBackdropClick(): void {\n this.OnClose();\n }\n\n // =========================================================================\n // Resize\n // =========================================================================\n\n public OnResizeStart(event: MouseEvent): void {\n if (!this.Resizable || this.Mode === 'dialog') return;\n event.preventDefault();\n this.isResizing = true;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n\n this.ngZone.runOutsideAngular(() => {\n document.addEventListener('mousemove', this.boundOnResizeMove);\n document.addEventListener('mouseup', this.boundOnResizeEnd);\n });\n }\n\n private onResizeMove(event: MouseEvent): void {\n if (!this.isResizing) return;\n const viewportWidth = window.innerWidth;\n const maxWidth = viewportWidth * this.MaxWidthRatio;\n this._widthPx = Math.max(this.MinWidthPx, Math.min(maxWidth, viewportWidth - event.clientX));\n this.ngZone.run(() => this.cdr.markForCheck());\n }\n\n private onResizeEnd(): void {\n if (!this.isResizing) return;\n this.isResizing = false;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n document.removeEventListener('mousemove', this.boundOnResizeMove);\n document.removeEventListener('mouseup', this.boundOnResizeEnd);\n this.WidthChanged.emit(this._widthPx);\n }\n}\n","<!-- Backdrop overlay -->\n<div class=\"sp-backdrop\"\n [class.visible]=\"IsVisible\"\n [class.sp-dialog-backdrop]=\"Mode === 'dialog'\"\n (click)=\"OnBackdropClick()\">\n</div>\n\n<!-- Panel (slide-in from right) -->\n@if (Mode === 'slide') {\n <div\n class=\"sp-panel\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\"\n [style.max-width]=\"(MaxWidthRatio * 100) + 'vw'\">\n <!-- Resize handle -->\n @if (Resizable) {\n <div class=\"sp-resize-handle\" (mousedown)=\"OnResizeStart($event)\">\n <div class=\"sp-resize-grip\"></div>\n </div>\n }\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body\">\n <ng-content></ng-content>\n </div>\n </div>\n}\n\n<!-- Dialog (centered modal) -->\n@if (Mode === 'dialog') {\n <div\n class=\"sp-dialog\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\">\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body sp-dialog-body\">\n <ng-content select=\"[dialog-content]\"></ng-content>\n </div>\n </div>\n}\n"]}