@ship-ui/core 0.15.18 → 0.15.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _ship_ui_core from '@ship-ui/core';
2
2
  import * as _angular_core from '@angular/core';
3
- import { ElementRef, QueryList, ComponentRef, OutputRefSubscription, Type, AfterContentInit, TemplateRef, WritableSignal, OnDestroy, InjectionToken } from '@angular/core';
3
+ import { ElementRef, QueryList, ComponentRef, OutputRefSubscription, Type, OutputEmitterRef, AfterViewInit, OnDestroy, AfterContentInit, TemplateRef, WritableSignal, InjectionToken } from '@angular/core';
4
4
  import { NgModel } from '@angular/forms';
5
5
 
6
6
  type ShipAlertItem = {
@@ -118,13 +118,110 @@ declare class ShipDialogService {
118
118
  compClosedSub: OutputRefSubscription | null;
119
119
  open<T, K = any>(component: Type<T>, options?: ShipDialogServiceOptions<K>): {
120
120
  component: T;
121
- close: () => void;
121
+ close: <U>(arg?: U | undefined) => void;
122
+ closed: OutputEmitterRef<void>;
122
123
  };
123
124
  ngOnDestroy(): void;
124
125
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShipDialogService, never>;
125
126
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<ShipDialogService>;
126
127
  }
127
128
 
129
+ type Port = {
130
+ id: string;
131
+ name: string;
132
+ };
133
+ type BlueprintNode = {
134
+ id: string;
135
+ name?: string;
136
+ coordinates: Coordinates;
137
+ inputs: Port[];
138
+ outputs: Port[];
139
+ connections: Connection[];
140
+ };
141
+ type Connection = {
142
+ fromNode: string;
143
+ fromPort: string;
144
+ toNode: string;
145
+ toPort: string;
146
+ };
147
+ type DragState = {
148
+ fromNode: string;
149
+ fromPort: string;
150
+ x2: number;
151
+ y2: number;
152
+ };
153
+ type Coordinates = [x: number, y: number];
154
+ declare const TEST_NODES: BlueprintNode[];
155
+ type ValidationErrors = {
156
+ duplicateNodeIds: string[];
157
+ duplicatePortIds: {
158
+ nodeId: string;
159
+ duplicatePortIds: string[];
160
+ }[];
161
+ };
162
+ declare class ShipBlueprintComponent implements AfterViewInit, OnDestroy {
163
+ #private;
164
+ asDots: _angular_core.Signal<boolean>;
165
+ lightMode: _angular_core.Signal<boolean>;
166
+ forceUnique: _angular_core.InputSignal<boolean>;
167
+ autoLayout: _angular_core.InputSignal<boolean>;
168
+ gridSize: _angular_core.InputSignal<number>;
169
+ snapToGrid: _angular_core.InputSignal<boolean>;
170
+ gridColor: _angular_core.InputSignal<[string, string]>;
171
+ nodes: _angular_core.ModelSignal<BlueprintNode[]>;
172
+ panX: _angular_core.WritableSignal<number>;
173
+ panY: _angular_core.WritableSignal<number>;
174
+ zoomLevel: _angular_core.WritableSignal<number>;
175
+ gridSnapSize: _angular_core.WritableSignal<number>;
176
+ isHoveringNode: _angular_core.WritableSignal<boolean>;
177
+ midpointDivPosition: _angular_core.WritableSignal<{
178
+ x: number;
179
+ y: number;
180
+ } | null>;
181
+ showMidpointDiv: _angular_core.WritableSignal<boolean>;
182
+ isLocked: _angular_core.WritableSignal<boolean>;
183
+ draggingConnection: _angular_core.WritableSignal<DragState | null>;
184
+ validationErrors: _angular_core.WritableSignal<ValidationErrors | null>;
185
+ highlightedConnection: _angular_core.WritableSignal<Connection | null>;
186
+ canvasRef: ElementRef<HTMLCanvasElement>;
187
+ constructor();
188
+ ngAfterViewInit(): void;
189
+ ngOnDestroy(): void;
190
+ applyAutolayout(): void;
191
+ updateCanvasSize(): void;
192
+ drawCanvas(): void;
193
+ drawGrid(ctx: CanvasRenderingContext2D): void;
194
+ drawConnections(ctx: CanvasRenderingContext2D): void;
195
+ drawDraggingPath(ctx: CanvasRenderingContext2D): void;
196
+ drawCurvedPath(ctx: CanvasRenderingContext2D, start: Coordinates, end: Coordinates): void;
197
+ onMouseUp(event: MouseEvent): void;
198
+ onClick(event: MouseEvent): void;
199
+ onEscape(event: KeyboardEvent): void;
200
+ onMouseMove(event: MouseEvent): void;
201
+ onTouchMove(event: TouchEvent): void;
202
+ startNodeDrag(event: MouseEvent | TouchEvent, nodeId: string): void;
203
+ endNodeDrag(): void;
204
+ nodeDrag(event: MouseEvent | Touch): void;
205
+ startPortDrag(event: MouseEvent, nodeId: string, portId: string): void;
206
+ endPortDrag(_: MouseEvent, toNodeId: string, toPortId: string): void;
207
+ cancelPortDrag(): void;
208
+ updatePathOnMove(event: MouseEvent | Touch): void;
209
+ getNodePortPosition(nodeId: string, portId: string): Coordinates;
210
+ startPan(event: MouseEvent): void;
211
+ endPan(): void;
212
+ pan(event: MouseEvent): void;
213
+ zoom(event: WheelEvent): void;
214
+ handleTouchStart(event: TouchEvent): void;
215
+ handleTouchMove(event: TouchEvent): void;
216
+ handleTouchEnd(): void;
217
+ closeMidpointDiv(): void;
218
+ getDisplayCoordinates(node: BlueprintNode): string;
219
+ removeConnection(): void;
220
+ getNewNodeCoordinates(panToCoordinates?: boolean): Coordinates;
221
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShipBlueprintComponent, never>;
222
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ShipBlueprintComponent, "sh-blueprint", never, { "forceUnique": { "alias": "forceUnique"; "required": false; "isSignal": true; }; "autoLayout": { "alias": "autoLayout"; "required": false; "isSignal": true; }; "gridSize": { "alias": "gridSize"; "required": false; "isSignal": true; }; "snapToGrid": { "alias": "snapToGrid"; "required": false; "isSignal": true; }; "gridColor": { "alias": "gridColor"; "required": false; "isSignal": true; }; "nodes": { "alias": "nodes"; "required": false; "isSignal": true; }; }, { "nodes": "nodesChange"; }, never, ["*"], true, never>;
223
+ }
224
+
128
225
  declare class ShipButtonGroupComponent {
129
226
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShipButtonGroupComponent, never>;
130
227
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<ShipButtonGroupComponent, "sh-button-group", never, {}, {}, never, ["*"], true, never>;
@@ -778,5 +875,5 @@ interface ShipConfig {
778
875
  sidenavType?: 'overlay' | 'simple';
779
876
  }
780
877
 
781
- export { GridSortableDirective, SHIP_CONFIG, ShipAlertComponent, ShipAlertContainerComponent, ShipAlertModule, ShipAlertService, ShipButtonComponent, ShipButtonGroupComponent, ShipCardComponent, ShipCheckboxComponent, ShipChipComponent, ShipColorPickerComponent, ShipDatepickerComponent, ShipDatepickerInputComponent, ShipDaterangeInputComponent, ShipDialogComponent, ShipDialogService, ShipDividerComponent, ShipEventCardComponent, ShipFileDragDropDirective, ShipFileUploadComponent, ShipFormFieldComponent, ShipIconComponent, ShipListComponent, ShipMenuComponent, ShipPopoverComponent, ShipPreventWheelDirective, ShipProgressBarComponent, ShipRadioComponent, ShipRangeSliderComponent, ShipResizeDirective, ShipSelectComponent, ShipSidenavComponent, ShipSortDirective, ShipSortableComponent, ShipSortableDirective, ShipSpinnerComponent, ShipStepperComponent, ShipStickyColumnsDirective, ShipTableComponent, ShipTabsComponent, ShipToggleCardComponent, ShipToggleComponent, ShipTooltipComponent, ShipTooltipDirective, ShipTooltipWrapper, ShipVirtualScrollComponent, moveIndex, watchHostClass };
782
- export type { AfterDropResponse, ShipAlertItem, ShipAlertItemInternal, ShipAlertType, ShipDialogOptions, ShipDialogReturn, ShipDialogServiceOptions, ShipPopoverOptions, ShipProgressBarMode, ShipSidenavType };
878
+ export { GridSortableDirective, SHIP_CONFIG, ShipAlertComponent, ShipAlertContainerComponent, ShipAlertModule, ShipAlertService, ShipBlueprintComponent, ShipButtonComponent, ShipButtonGroupComponent, ShipCardComponent, ShipCheckboxComponent, ShipChipComponent, ShipColorPickerComponent, ShipDatepickerComponent, ShipDatepickerInputComponent, ShipDaterangeInputComponent, ShipDialogComponent, ShipDialogService, ShipDividerComponent, ShipEventCardComponent, ShipFileDragDropDirective, ShipFileUploadComponent, ShipFormFieldComponent, ShipIconComponent, ShipListComponent, ShipMenuComponent, ShipPopoverComponent, ShipPreventWheelDirective, ShipProgressBarComponent, ShipRadioComponent, ShipRangeSliderComponent, ShipResizeDirective, ShipSelectComponent, ShipSidenavComponent, ShipSortDirective, ShipSortableComponent, ShipSortableDirective, ShipSpinnerComponent, ShipStepperComponent, ShipStickyColumnsDirective, ShipTableComponent, ShipTabsComponent, ShipToggleCardComponent, ShipToggleComponent, ShipTooltipComponent, ShipTooltipDirective, ShipTooltipWrapper, ShipVirtualScrollComponent, TEST_NODES, moveIndex, watchHostClass };
879
+ export type { AfterDropResponse, BlueprintNode, Coordinates, ShipAlertItem, ShipAlertItemInternal, ShipAlertType, ShipDialogOptions, ShipDialogReturn, ShipDialogServiceOptions, ShipPopoverOptions, ShipProgressBarMode, ShipSidenavType };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ship-ui/core",
3
3
  "license": "MIT",
4
- "version": "0.15.18",
4
+ "version": "0.15.22",
5
5
  "peerDependencies": {
6
6
  "@angular/common": ">=19",
7
7
  "@angular/core": ">=19"
@@ -41,6 +41,9 @@
41
41
  "calendar",
42
42
  "minus-bold",
43
43
  "info",
44
+ "list",
45
+ "trash",
46
+ "tree-structure",
44
47
  "check-bold",
45
48
  "check-circle",
46
49
  "warning-octagon",
@@ -0,0 +1,238 @@
1
+ @use '../helpers.scss' as *;
2
+ $shipBlueprint: true !default;
3
+
4
+ @if $shipBlueprint == true {
5
+ sh-blueprint {
6
+ --bp-bg: var(--base-1);
7
+ --bp-icon-c: var(--base-6);
8
+ --bp-stroke-c: var(--base-7);
9
+ --bp-stroke-ca: var(--primary-8);
10
+
11
+ display: flex;
12
+ position: relative;
13
+ width: 100%;
14
+ height: 100%;
15
+
16
+ > * {
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ sh-icon {
21
+ font-size: p2r(16);
22
+ color: var(--bp-icon-c);
23
+ }
24
+
25
+ .validation-errors {
26
+ position: absolute;
27
+ top: 50%;
28
+ left: 50%;
29
+ transform: translate(-50%, -50%);
30
+ padding: p2r(16);
31
+ }
32
+
33
+ .midpoint-div {
34
+ position: absolute;
35
+ background-color: var(--base-2);
36
+ border: 1px solid var(--base-4);
37
+ padding: p2r(8);
38
+ gap: p2r(8);
39
+ border-radius: var(--shape-2);
40
+ transform: translate(-50%, -50%);
41
+ z-index: 100;
42
+ display: flex;
43
+ align-items: center;
44
+ cursor: pointer;
45
+
46
+ sh-icon {
47
+ color: var(--base-12);
48
+ }
49
+ }
50
+
51
+ .canvas-container {
52
+ position: relative;
53
+ width: 100%;
54
+ height: 100%;
55
+ overflow: hidden;
56
+
57
+ &.hovering-connection {
58
+ cursor: pointer;
59
+ }
60
+
61
+ &.locked {
62
+ .node {
63
+ pointer-events: none;
64
+ }
65
+ }
66
+ }
67
+
68
+ .action-panel {
69
+ position: absolute;
70
+ top: p2r(8);
71
+ right: p2r(8);
72
+ gap: p2r(8);
73
+ display: flex;
74
+ align-items: center;
75
+ z-index: 1000;
76
+ }
77
+
78
+ canvas {
79
+ position: absolute;
80
+ top: 0;
81
+ left: 0;
82
+ width: 100%;
83
+ height: 100%;
84
+ }
85
+ .nodes-wrapper {
86
+ position: absolute;
87
+ top: 0;
88
+ left: 0;
89
+ width: 100%;
90
+ height: 100%;
91
+ will-change: transform;
92
+ }
93
+ .canvas {
94
+ height: 100%;
95
+ width: 100%;
96
+ background-color: var(--bp-bg);
97
+ overflow: hidden;
98
+ touch-action: none;
99
+ position: relative;
100
+ }
101
+
102
+ .grid {
103
+ position: absolute;
104
+ inset: 0;
105
+ will-change: transform;
106
+ }
107
+
108
+ .tile {
109
+ position: absolute;
110
+ box-sizing: border-box;
111
+ width: 800px;
112
+ height: 800px;
113
+ background-image:
114
+ repeating-linear-gradient(0deg, var(--bp-grid-c) 0 2px, transparent 2px 100%),
115
+ repeating-linear-gradient(90deg, var(--bp-grid-c) 0 2px, transparent 2px 100%);
116
+ background-size: 20px 20px;
117
+ }
118
+
119
+ .node {
120
+ position: absolute;
121
+ min-width: 150px;
122
+ // min-height: 100px;
123
+ padding: 0;
124
+ transition: box-shadow 0.2s ease-in-out;
125
+ box-shadow: var(--box-shadow-10);
126
+ will-change: transform;
127
+
128
+ display: flex;
129
+ flex-direction: column;
130
+
131
+ header {
132
+ padding: p2r(8);
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: space-between;
136
+ background-color: var(--base-2);
137
+ border-bottom: 1px solid var(--base-4);
138
+ cursor: grab;
139
+ user-select: none;
140
+
141
+ &:active {
142
+ cursor: grabbing;
143
+ }
144
+ }
145
+
146
+ &:has(header:hover) {
147
+ box-shadow: 0 0 10px 2px var(--primary-6);
148
+ }
149
+ }
150
+
151
+ .ports {
152
+ padding: p2r(8 0);
153
+ display: flex;
154
+ gap: p2r(8);
155
+ }
156
+
157
+ .inputs,
158
+ .outputs {
159
+ display: flex;
160
+ flex-direction: column;
161
+ justify-content: space-around;
162
+ flex: 1 0;
163
+ height: 100%;
164
+ }
165
+
166
+ .inputs {
167
+ .port {
168
+ border-radius: 0 50% 50% 0;
169
+ border-left-width: 0;
170
+ }
171
+ }
172
+
173
+ .outputs {
174
+ align-items: flex-end;
175
+
176
+ .port {
177
+ border-radius: 50% 0 0 50%;
178
+ border-right-width: 0;
179
+ }
180
+ }
181
+
182
+ .port-wrap {
183
+ display: flex;
184
+ gap: p2r(4);
185
+ align-items: center;
186
+ }
187
+
188
+ .port {
189
+ width: p2r(12);
190
+ height: p2r(12);
191
+ background-color: var(--bp-stroke-c);
192
+ border-radius: 50%;
193
+ border: 1px solid var(--base-8);
194
+ cursor: pointer;
195
+ position: relative;
196
+ }
197
+
198
+ .port:hover {
199
+ background-color: var(--bp-stroke-ca);
200
+ }
201
+
202
+ .port-name {
203
+ font: var(--paragraph-40);
204
+ color: var(--base-12);
205
+ white-space: nowrap;
206
+ }
207
+
208
+ .svg-wrap {
209
+ position: absolute;
210
+ top: 0;
211
+ left: 0;
212
+ width: 100%;
213
+ height: 100%;
214
+ pointer-events: none;
215
+ }
216
+
217
+ .connections-svg {
218
+ width: 100%;
219
+ height: 100%;
220
+ pointer-events: none;
221
+ }
222
+
223
+ .connection-path {
224
+ stroke: var(--bp-stroke-c);
225
+ stroke-width: 3;
226
+ fill: none;
227
+ pointer-events: none;
228
+ }
229
+
230
+ .drag-path {
231
+ stroke: var(--bp-stroke-ca);
232
+ stroke-width: 3;
233
+ fill: none;
234
+ stroke-dasharray: 5, 5;
235
+ pointer-events: none;
236
+ }
237
+ }
238
+ }
package/styles/index.scss CHANGED
@@ -17,6 +17,7 @@ $shipButtonShadow: false !default;
17
17
  $shipChipShadow: false !default;
18
18
 
19
19
  $shipAlert: true !default;
20
+ $shipBlueprint: true !default;
20
21
  $shipToggle: true !default;
21
22
  $shipButton: true !default;
22
23
  $shipProgressBar: true !default;
@@ -55,6 +56,9 @@ $shipFileUpload: true !default;
55
56
  @use './components/ship-alert.component.scss' with (
56
57
  $shipAlert: $shipAlert
57
58
  );
59
+ @use './components/ship-blueprint.component.scss' with (
60
+ $shipBlueprint: $shipBlueprint
61
+ );
58
62
  @use './components/ship-toggle.component.scss' with (
59
63
  $shipToggle: $shipToggle
60
64
  );