@memberjunction/ng-versions 5.38.0 → 5.40.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 +11 -18
- package/dist/__tests__/types.test.js +0 -8
- package/dist/__tests__/types.test.js.map +1 -1
- package/dist/lib/types.d.ts +0 -2
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/versions.module.d.ts +7 -8
- package/dist/lib/versions.module.d.ts.map +1 -1
- package/dist/lib/versions.module.js +2 -7
- package/dist/lib/versions.module.js.map +1 -1
- package/dist/public-api.d.ts +0 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +2 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +7 -7
- package/dist/lib/panel/slide-panel.component.d.ts +0 -45
- package/dist/lib/panel/slide-panel.component.d.ts.map +0 -1
- package/dist/lib/panel/slide-panel.component.js +0 -238
- package/dist/lib/panel/slide-panel.component.js.map +0 -1
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
|
|
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["
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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,12 +112,6 @@ 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
117
|
- [@memberjunction/core](../../../MJCore/readme.md) -- Metadata, RunView
|
|
@@ -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
|
|
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"]}
|
package/dist/lib/types.d.ts
CHANGED
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -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
|
|
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"}
|
package/dist/lib/types.js.map
CHANGED
|
@@ -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
|
|
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 "./
|
|
3
|
-
import * as i2 from "./
|
|
4
|
-
import * as i3 from "./label-
|
|
5
|
-
import * as i4 from "
|
|
6
|
-
import * as i5 from "@angular/
|
|
7
|
-
import * as i6 from "@
|
|
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.
|
|
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":"
|
|
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: [
|
|
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: [
|
|
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,
|
|
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"]}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -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';
|
package/dist/public-api.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/public-api.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './lib/versions.module';
|
|
2
2
|
export * from './lib/types';
|
|
3
|
-
|
|
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';
|
package/dist/public-api.js.map
CHANGED
|
@@ -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,
|
|
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.
|
|
3
|
+
"version": "5.40.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.
|
|
30
|
-
"@memberjunction/ng-base-types": "5.
|
|
31
|
-
"@memberjunction/core-entities": "5.
|
|
32
|
-
"@memberjunction/global": "5.
|
|
33
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
34
|
-
"@memberjunction/ng-shared-generic": "5.
|
|
29
|
+
"@memberjunction/core": "5.40.0",
|
|
30
|
+
"@memberjunction/ng-base-types": "5.40.0",
|
|
31
|
+
"@memberjunction/core-entities": "5.40.0",
|
|
32
|
+
"@memberjunction/global": "5.40.0",
|
|
33
|
+
"@memberjunction/graphql-dataprovider": "5.40.0",
|
|
34
|
+
"@memberjunction/ng-shared-generic": "5.40.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":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAwC,uBAAuB,EAAE,YAAY,EAAsB,MAAM,eAAe,CAAC;;;;;;ICgBlK,8BAAkE;IAApC,mNAAa,4BAAqB,KAAC;IAC/D,yBAAkC;IACpC,iBAAM;;;;IAKJ,AADF,8BAAuB,YACA;IAAA,YAAS;IAAA,iBAAK;IACnC,kCAAiD;IAApB,wMAAS,gBAAS,KAAC;IAC9C,wBAAiC;IAErC,AADE,iBAAS,EACL;;;IAJiB,eAAS;IAAT,kCAAS;;;IAdpC,8BAImD;IAEjD,qGAAiB;IAMjB,qGAAa;IASb,8BAAqB;IACnB,kBAAyB;IAE7B,AADE,iBAAM,EACF;;;IApBJ,AADA,6CAA0B,gDACsB;IAFhD,2CAA2B;IAI3B,cAIC;IAJD,2CAIC;IAED,cAOC;IAPD,uCAOC;;;;IAiBG,AADF,8BAAuB,YACA;IAAA,YAAS;IAAA,iBAAK;IACnC,kCAAiD;IAApB,wMAAS,gBAAS,KAAC;IAC9C,wBAAiC;IAErC,AADE,iBAAS,EACL;;;IAJiB,eAAS;IAAT,kCAAS;;;IAPpC,+BAG6B;IAE3B,qGAAa;IASb,+BAAoC;IAClC,qBAAmD;IAEvD,AADE,iBAAM,EACF;;;IAdJ,6CAA0B;IAD1B,2CAA2B;IAG3B,cAOC;IAPD,uCAOC;;ADxCL,MAAM,OAAO,qBAAqB;IAyDlB;IACA;IACA;IA1DH,IAAI,GAAmB,OAAO,CAAC;IAC/B,KAAK,GAAG,EAAE,CAAC;IACpB,IACI,OAAO,CAAC,KAAc;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC9B,IAAI,KAAK,EAAE,CAAC;gBACR,wCAAwC;gBACxC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;oBACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;oBACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;gBAC5B,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC5B,CAAC;QACL,CAAC;IACL,CAAC;IACD,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IACO,QAAQ,GAAG,IAAI,CAAC;IAChB,WAAW,GAAG,KAAK,CAAC;IAEnB,SAAS,GAAG,IAAI,CAAC;IACjB,UAAU,GAAG,GAAG,CAAC;IACjB,aAAa,GAAG,IAAI,CAAC;IAE9B,wFAAwF;IACxF,IACI,OAAO,CAAC,KAAa;QACrB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAES,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAClC,YAAY,GAAG,IAAI,YAAY,EAAU,CAAC;IAEpD;;;;OAIG;IACM,QAAQ,GAA2B,IAAI,CAAC;IAE1C,SAAS,GAAG,KAAK,CAAC;IACjB,QAAQ,GAAG,CAAC,CAAC;IACb,UAAU,GAAG,KAAK,CAAC;IAEnB,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEvD,YACY,GAAsB,EACtB,MAAc,EACd,KAAiB;QAFjB,QAAG,GAAH,GAAG,CAAmB;QACtB,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAY;IAC1B,CAAC;IAEJ,QAAQ;QACJ,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAClC,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,oDAAoD;QACpD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;gBACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC5B,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,WAAW;QACP,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAClE,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACnE,CAAC;IAGM,WAAW;QACd,IAAI,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;IAEM,OAAO;QACV,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAAE,OAAO;QAC9C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QACxB,sCAAsC;QACtC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC;IAEM,eAAe;QAClB,IAAI,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;IAED,4EAA4E;IAC5E,SAAS;IACT,4EAA4E;IAErE,aAAa,CAAC,KAAiB;QAClC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO;QACtD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC;QAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;QAExC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE;YAC/B,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC/D,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,YAAY,CAAC,KAAiB;QAClC,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAC7B,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC;QACxC,MAAM,QAAQ,GAAG,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACpD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7F,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IACnD,CAAC;IAEO,WAAW;QACf,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;QACpC,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAClE,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC/D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;+GAxIQ,qBAAqB;6DAArB,qBAAqB;YAArB,4GAAA,iBAAa,0BAAQ;;;YCTlC,8BAG8B;YAA5B,+FAAS,qBAAiB,IAAC;YAC7B,iBAAM;YAGN,uFAAwB;YA6BxB,uFAAyB;;YAlCvB,AADA,wCAA2B,6CACmB;YAKhD,cA0BC;YA1BD,+CA0BC;YAGD,cAmBC;YAnBD,gDAmBC;;;iFD9CY,qBAAqB;cAPjC,SAAS;6BACI,KAAK,YACL,gBAAgB,mBAGT,uBAAuB,CAAC,MAAM;;kBAG9C,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAuBL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAGL,KAAK;;kBAQL,MAAM;;kBACN,MAAM;;kBAON,KAAK;;kBAsCL,YAAY;mBAAC,yBAAyB;;kFArF9B,qBAAqB","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"]}
|