@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.71 → 2.0.0-next.73

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.
Files changed (25) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +92 -13
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +116 -14
  4. package/dist/components/alert-menu-item/alert-menu-item.d.ts +39 -1
  5. package/dist/components/alert-menu-item/alert-menu-item.d.ts.map +1 -1
  6. package/dist/components/alert-menu-item/alert-menu-item.js +41 -0
  7. package/dist/components/alert-menu-item/alert-menu-item.js.map +1 -1
  8. package/dist/components/message-menu-item/message-menu-item.d.ts +4 -0
  9. package/dist/components/message-menu-item/message-menu-item.d.ts.map +1 -1
  10. package/dist/components/message-menu-item/message-menu-item.js +10 -0
  11. package/dist/components/message-menu-item/message-menu-item.js.map +1 -1
  12. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.css.js +17 -2
  13. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.css.js.map +1 -1
  14. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.d.ts +24 -2
  15. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.d.ts.map +1 -1
  16. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.js +32 -11
  17. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/components/alert-menu-item/alert-menu-item.stories.ts +40 -1
  20. package/src/components/alert-menu-item/alert-menu-item.ts +67 -1
  21. package/src/components/message-menu-item/message-menu-item.stories.ts +18 -0
  22. package/src/components/message-menu-item/message-menu-item.ts +6 -0
  23. package/src/integration-systems/integration-vessel-menu/integration-vessel-menu.css +15 -2
  24. package/src/integration-systems/integration-vessel-menu/integration-vessel-menu.stories.ts +102 -72
  25. package/src/integration-systems/integration-vessel-menu/integration-vessel-menu.ts +45 -11
@@ -2,11 +2,16 @@
2
2
  box-sizing: border-box;
3
3
  }
4
4
 
5
+ :host {
6
+ display: block;
7
+ }
8
+
5
9
  .wrapper {
6
10
  @mixin style style=integration-normal noClick=true;
7
11
  display: flex;
8
12
  flex-direction: column;
9
13
  align-items: center;
14
+ height: 100%;
10
15
  background: var(--container-global-color);
11
16
  border-radius: var(
12
17
  --app-components-integration-system-dropdown-menu-border-radius
@@ -31,6 +36,9 @@
31
36
  border-top: 1px solid var(--border-divider-color);
32
37
  background: var(--container-global-color);
33
38
  border-radius: 12px;
39
+ &.hidden {
40
+ display: none;
41
+ }
34
42
  }
35
43
 
36
44
  .content-area {
@@ -40,6 +48,9 @@
40
48
  gap: 8px;
41
49
  align-self: stretch;
42
50
  border-radius: 8px;
51
+ &.hidden {
52
+ display: none;
53
+ }
43
54
  }
44
55
 
45
56
  .footer-container slot[name="buttons"]::slotted(*) {
@@ -56,7 +67,8 @@
56
67
  gap: var(--app-components-integration-system-menu-action-spacing);
57
68
  }
58
69
 
59
- .buttons-slot {
70
+ .buttons-slot,
71
+ .content-slot {
60
72
  display: contents;
61
73
  }
62
74
 
@@ -68,13 +80,14 @@
68
80
  min-height: 0;
69
81
  flex: 1;
70
82
  border-radius: 8px;
71
- &.hidealarmlist {
83
+ &.hidden {
72
84
  display: none;
73
85
  }
74
86
  }
75
87
 
76
88
  .alertlist {
77
89
  width: 100%;
90
+ height: 100%;
78
91
  }
79
92
 
80
93
  .leading-icon {
@@ -102,31 +102,46 @@ const renderAlarms = () => html`
102
102
  </obc-alert-menu-item>
103
103
  `;
104
104
 
105
+ const renderButtons = () => html`
106
+ <obc-button slot="buttons" ?fullWidth=${true}>Action 1</obc-button>
107
+ <obc-button slot="buttons" ?fullWidth=${true}>Ac. 2</obc-button>
108
+ <obc-button slot="buttons" ?fullWidth=${true}>Action number 3</obc-button>
109
+ `;
110
+
111
+ const renderContent = () => html`
112
+ <div slot="content" style="padding: 16px;">
113
+ <p style="margin: 0;">Content area</p>
114
+ </div>
115
+ `;
116
+
105
117
  const meta: Meta<ObcIntegrationVesselMenu> = {
106
118
  title: 'Integration Systems/Integration Vessel Menu',
107
119
  component: 'obc-integration-vessel-menu',
108
120
  tags: ['alpha'],
109
- args: {hideAlarmList: false},
121
+ args: {hasActions: true, hasAlertList: true, hasContent: true},
110
122
  argTypes: {
111
- hideAlarmList: {
123
+ hasActions: {
124
+ control: 'boolean',
125
+ },
126
+ hasAlertList: {
127
+ control: 'boolean',
128
+ },
129
+ hasContent: {
112
130
  control: 'boolean',
113
131
  },
114
132
  },
115
133
  parameters: {
116
134
  layout: 'centered',
117
135
  },
118
- decorators: [
119
- (story) => html`
120
- <div style="height: 400px; display: flex;">${story()}</div>
121
- `,
122
- ],
123
136
  };
124
137
 
125
138
  export default meta;
126
139
  type Story = StoryObj<ObcIntegrationVesselMenu>;
127
140
 
128
141
  interface IntegrationVesselMenuArgs {
129
- hideAlarmList: boolean;
142
+ hasActions: boolean;
143
+ hasAlertList: boolean;
144
+ hasContent: boolean;
130
145
  }
131
146
 
132
147
  type IntegrationVesselMenuTemplate = (
@@ -134,69 +149,23 @@ type IntegrationVesselMenuTemplate = (
134
149
  ) => ReturnType<typeof html>;
135
150
 
136
151
  const template: IntegrationVesselMenuTemplate = (args) => html`
137
- <obc-integration-vessel-menu .hideAlarmList=${args.hideAlarmList}>
138
- <div slot="content" style="padding: 24px;">
139
- <div style="width: 496px; height: 256;">
140
- <p>Content area</p>
141
- </div>
142
- </div>
143
- <obc-button
144
- slot="buttons"
145
- @click=${() => console.log('Button 1 clicked')}
146
- ?fullWidth=${true}
147
- >
148
- <div>Action 1</div>
149
- </obc-button>
150
- <obc-button
151
- slot="buttons"
152
- @click=${() => console.log('Button 2 clicked')}
153
- ?fullWidth=${true}
154
- >
155
- Ac. 2
156
- </obc-button>
157
- <obc-button
158
- slot="buttons"
159
- @click=${() => console.log('Button 3 clicked')}
160
- ?fullWidth=${true}
161
- >
162
- Action number 3
163
- </obc-button>
164
-
165
- ${renderAlarms()}
166
- </obc-integration-vessel-menu>
167
- `;
168
-
169
- const templateWithoutAlarms: IntegrationVesselMenuTemplate = (args) => html`
170
- <obc-integration-vessel-menu .hideAlarmList=${args.hideAlarmList}>
171
- <obc-button
172
- slot="buttons"
173
- @click=${() => console.log('Button 1 clicked')}
174
- ?fullWidth=${true}
175
- >
176
- Action 1
177
- </obc-button>
178
- <obc-button
179
- slot="buttons"
180
- @click=${() => console.log('Button 2 clicked')}
181
- ?fullWidth=${true}
182
- >
183
- Ac. 2
184
- </obc-button>
185
- <obc-button
186
- slot="buttons"
187
- @click=${() => console.log('Button 3 clicked')}
188
- ?fullWidth=${true}
189
- >
190
- Action number 3
191
- </obc-button>
192
- <div slot="content" style="padding: 24px;">
193
- <p>Add content here</p>
194
- </div>
152
+ <obc-integration-vessel-menu
153
+ style="width: 400px;"
154
+ .hasActions=${args.hasActions}
155
+ .hasAlertList=${args.hasAlertList}
156
+ .hasContent=${args.hasContent}
157
+ >
158
+ ${renderButtons()} ${renderContent()} ${renderAlarms()}
195
159
  </obc-integration-vessel-menu>
196
160
  `;
197
161
 
198
162
  const templateWrappedButtons: IntegrationVesselMenuTemplate = (args) => html`
199
- <obc-integration-vessel-menu .hideAlarmList=${args.hideAlarmList}>
163
+ <obc-integration-vessel-menu
164
+ style="width: 600px; height: 400px;"
165
+ .hasActions=${args.hasActions}
166
+ .hasAlertList=${args.hasAlertList}
167
+ .hasContent=${args.hasContent}
168
+ >
200
169
  <div slot="buttons">
201
170
  <div style="display: contents;">
202
171
  <obc-button ?fullWidth=${true}>Open</obc-button>
@@ -218,15 +187,76 @@ export const Default: Story = {
218
187
  render: template,
219
188
  };
220
189
 
221
- export const WithoutAlarms: Story = {
222
- render: templateWithoutAlarms,
190
+ export const NoActions: Story = {
191
+ render: template,
192
+ args: {hasActions: false},
193
+ };
194
+
195
+ export const NoContent: Story = {
196
+ render: template,
197
+ args: {hasContent: false},
198
+ };
199
+
200
+ export const NoAlertList: Story = {
201
+ render: template,
202
+ args: {hasAlertList: false},
223
203
  };
224
204
 
225
- export const WithoutAlarmsHideEmptyAlarmList: Story = {
226
- render: templateWithoutAlarms,
227
- args: {hideAlarmList: true},
205
+ // Recommended bounded usage: the consumer caps the menu by setting a height on
206
+ // the host element. The menu fills that height and the alert list scrolls within
207
+ // the remaining space automatically — no per-slot sizing required.
208
+ const templateConstrained: IntegrationVesselMenuTemplate = (args) => html`
209
+ <obc-integration-vessel-menu
210
+ style="width: 400px; height: 500px;"
211
+ .hasActions=${args.hasActions}
212
+ .hasAlertList=${args.hasAlertList}
213
+ .hasContent=${args.hasContent}
214
+ >
215
+ ${renderButtons()} ${renderContent()} ${renderAlarms()}
216
+ </obc-integration-vessel-menu>
217
+ `;
218
+
219
+ export const Constrained: Story = {
220
+ render: templateConstrained,
221
+ };
222
+
223
+ // Without consumer bounding, tall content grows the whole menu unbounded.
224
+ const templateLongContent: IntegrationVesselMenuTemplate = (args) => html`
225
+ <obc-integration-vessel-menu
226
+ style="width: 400px;"
227
+ .hasActions=${args.hasActions}
228
+ .hasAlertList=${args.hasAlertList}
229
+ .hasContent=${args.hasContent}
230
+ >
231
+ ${renderButtons()}
232
+ <div slot="content" style="padding: 16px;">
233
+ <div style="height: 600px;">
234
+ <p style="margin: 0;">Tall content with no height cap</p>
235
+ </div>
236
+ </div>
237
+ </obc-integration-vessel-menu>
238
+ `;
239
+
240
+ export const LongContentOverflow: Story = {
241
+ render: templateLongContent,
242
+ args: {hasAlertList: false},
228
243
  };
229
244
 
230
245
  export const WithButtonsWrappedInDivWithoutStyling: Story = {
231
246
  render: templateWrappedButtons,
232
247
  };
248
+
249
+ const templateNoAlerts: IntegrationVesselMenuTemplate = (args) => html`
250
+ <obc-integration-vessel-menu
251
+ style="width: 400px;"
252
+ .hasActions=${args.hasActions}
253
+ .hasAlertList=${args.hasAlertList}
254
+ .hasContent=${args.hasContent}
255
+ >
256
+ ${renderButtons()} ${renderContent()}
257
+ </obc-integration-vessel-menu>
258
+ `;
259
+
260
+ export const NoAlerts: Story = {
261
+ render: templateNoAlerts,
262
+ };
@@ -7,11 +7,32 @@ import componentStyle from './integration-vessel-menu.css?inline';
7
7
  import '../../components/button/button.js';
8
8
  import '../../components/icon-button/icon-button.js';
9
9
  import '../../icons/icon-placeholder.js';
10
+ import '../../icons/icon-unacknowledged.js';
10
11
  import '../../building-blocks/alert-list/alert-list.js';
11
12
 
12
13
  /**
13
14
  * `<obc-integration-vessel-menu>` – A menu to be shown when selecting a obc-integration-button from a obc-integration-bar.
14
15
  *
16
+ * ## Sizing
17
+ *
18
+ * The menu hugs its content and never reserves more space than its slotted
19
+ * sections need; it deliberately does not impose a height of its own. Sizing is
20
+ * owned by the consumer, since only the consumer knows how large the menu may
21
+ * grow in a given layout.
22
+ *
23
+ * From a web components perspective, drive the size from the host element and
24
+ * the slotted light-DOM nodes — not from component properties:
25
+ *
26
+ * - **Bound the whole menu** by giving the host element a definite `height`. The
27
+ * menu fills that height and the alert list scrolls within the remaining space
28
+ * while the footer and content keep their size. This is the recommended
29
+ * approach. (A `max-height` alone will not bound the list — the internal
30
+ * scroll needs a definite height to resolve against.)
31
+ * - **Size sections independently** (advanced) by sizing the slotted nodes
32
+ * directly — e.g. a fixed-height `content` element, or a capped, scrollable
33
+ * wrapper around the `alarms` items.
34
+ * - **Leave it unbounded** to let the menu grow with its content.
35
+ *
15
36
  * @slot buttons - Buttons shown in the footer.
16
37
  * @slot content - Main content shown in the content area.
17
38
  * @slot alarms - Alarm items rendered inside the alert list.
@@ -19,30 +40,43 @@ import '../../building-blocks/alert-list/alert-list.js';
19
40
 
20
41
  @customElement('obc-integration-vessel-menu')
21
42
  export class ObcIntegrationVesselMenu extends LitElement {
22
- /** Hide the alarm list, ensuring it doesn't take space (display: none). */
23
- @property({type: Boolean}) hideAlarmList = false;
43
+ @property({type: Boolean, attribute: false}) hasActions = true;
44
+ @property({type: Boolean, attribute: false}) hasAlertList = true;
45
+ @property({type: Boolean, attribute: false}) hasContent = true;
24
46
 
25
47
  protected override render() {
26
48
  return html`
27
- <div
28
- class=${classMap({
29
- wrapper: true,
30
- })}
31
- >
32
- <div class="footer-container">
49
+ <div class="wrapper">
50
+ <div
51
+ class=${classMap({
52
+ 'footer-container': true,
53
+ hidden: !this.hasActions,
54
+ })}
55
+ >
33
56
  <slot name="buttons" class="buttons-slot"></slot>
34
57
  </div>
35
- <div class="content-area">
36
- <slot name="content"></slot>
58
+ <div
59
+ class=${classMap({
60
+ 'content-area': true,
61
+ hidden: !this.hasContent,
62
+ })}
63
+ >
64
+ <slot name="content" class="content-slot"></slot>
37
65
  </div>
38
66
  <div
39
67
  class=${classMap({
40
68
  'content-container': true,
41
- hidealarmlist: this.hideAlarmList,
69
+ hidden: !this.hasAlertList,
42
70
  })}
43
71
  >
44
72
  <obc-alert-list class="alertlist"
45
73
  ><slot name="alarms"></slot>
74
+ <div slot="empty-icon">
75
+ <obi-unacknowledged></obi-unacknowledged>
76
+ </div>
77
+ <div slot="empty-title">
78
+ <span>No alerts</span>
79
+ </div>
46
80
  </obc-alert-list>
47
81
  </div>
48
82
  </div>