@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.58 → 2.0.0-next.60
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/bundle/openbridge-webcomponents.bundle.js +8144 -5241
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +1937 -78
- package/dist/alert-severity.d.ts +38 -0
- package/dist/alert-severity.d.ts.map +1 -0
- package/dist/alert-severity.js +176 -0
- package/dist/alert-severity.js.map +1 -0
- package/dist/ar/building-blocks/poi-header/poi-header.css.js +38 -7
- package/dist/ar/building-blocks/poi-header/poi-header.css.js.map +1 -1
- package/dist/ar/building-blocks/poi-header/poi-header.d.ts +7 -2
- package/dist/ar/building-blocks/poi-header/poi-header.d.ts.map +1 -1
- package/dist/ar/building-blocks/poi-header/poi-header.js +5 -0
- package/dist/ar/building-blocks/poi-header/poi-header.js.map +1 -1
- package/dist/ar/poi-button/poi-button.css.js +110 -32
- package/dist/ar/poi-button/poi-button.css.js.map +1 -1
- package/dist/ar/poi-button/poi-button.d.ts +7 -2
- package/dist/ar/poi-button/poi-button.d.ts.map +1 -1
- package/dist/ar/poi-button/poi-button.js +15 -0
- package/dist/ar/poi-button/poi-button.js.map +1 -1
- package/dist/ar/types.d.ts +6 -1
- package/dist/ar/types.d.ts.map +1 -1
- package/dist/ar/types.js +5 -0
- package/dist/ar/types.js.map +1 -1
- package/dist/automation/automation-badge/automation-badge.d.ts +9 -1
- package/dist/automation/automation-badge/automation-badge.d.ts.map +1 -1
- package/dist/automation/automation-badge/automation-badge.js +119 -12
- package/dist/automation/automation-badge/automation-badge.js.map +1 -1
- package/dist/automation/automation-button/abstract-automation-button-storybook-helpers.d.ts +25 -1
- package/dist/automation/automation-button/abstract-automation-button-storybook-helpers.d.ts.map +1 -1
- package/dist/automation/automation-button/abstract-automation-button-storybook-helpers.js +7 -2
- package/dist/automation/automation-button/abstract-automation-button-storybook-helpers.js.map +1 -1
- package/dist/automation/automation-button/abstract-automation-button.d.ts +10 -3
- package/dist/automation/automation-button/abstract-automation-button.d.ts.map +1 -1
- package/dist/automation/automation-button/abstract-automation-button.js +23 -2
- package/dist/automation/automation-button/abstract-automation-button.js.map +1 -1
- package/dist/automation/automation-button/automation-button.css.js +9 -4
- package/dist/automation/automation-button/automation-button.css.js.map +1 -1
- package/dist/automation/automation-button/automation-button.d.ts +4 -2
- package/dist/automation/automation-button/automation-button.d.ts.map +1 -1
- package/dist/automation/automation-button/automation-button.js +24 -6
- package/dist/automation/automation-button/automation-button.js.map +1 -1
- package/dist/automation/automation-tank/automation-tank.d.ts +3 -2
- package/dist/automation/automation-tank/automation-tank.d.ts.map +1 -1
- package/dist/automation/automation-tank/automation-tank.js +13 -2
- package/dist/automation/automation-tank/automation-tank.js.map +1 -1
- package/dist/components/accordion-card/accordion-card.css.js +34 -0
- package/dist/components/accordion-card/accordion-card.css.js.map +1 -1
- package/dist/components/accordion-card/accordion-card.d.ts +3 -2
- package/dist/components/accordion-card/accordion-card.d.ts.map +1 -1
- package/dist/components/accordion-card/accordion-card.js +4 -3
- package/dist/components/accordion-card/accordion-card.js.map +1 -1
- package/dist/components/alert-button/alert-button.css.js +744 -7
- package/dist/components/alert-button/alert-button.css.js.map +1 -1
- package/dist/components/alert-button/alert-button.d.ts +3 -1
- package/dist/components/alert-button/alert-button.d.ts.map +1 -1
- package/dist/components/alert-button/alert-button.js +33 -31
- package/dist/components/alert-button/alert-button.js.map +1 -1
- package/dist/components/alert-frame/alert-frame.css.js +116 -29
- package/dist/components/alert-frame/alert-frame.css.js.map +1 -1
- package/dist/components/alert-frame/alert-frame.d.ts +42 -15
- package/dist/components/alert-frame/alert-frame.d.ts.map +1 -1
- package/dist/components/alert-frame/alert-frame.js +68 -17
- package/dist/components/alert-frame/alert-frame.js.map +1 -1
- package/dist/components/alert-frame/critical-badge.d.ts +12 -0
- package/dist/components/alert-frame/critical-badge.d.ts.map +1 -0
- package/dist/components/alert-frame/critical-badge.js +47 -0
- package/dist/components/alert-frame/critical-badge.js.map +1 -0
- package/dist/components/alert-frame/diagnostic-badge.d.ts +12 -0
- package/dist/components/alert-frame/diagnostic-badge.d.ts.map +1 -0
- package/dist/components/alert-frame/diagnostic-badge.js +60 -0
- package/dist/components/alert-frame/diagnostic-badge.js.map +1 -0
- package/dist/components/alert-icon/alert-icon.d.ts +6 -1
- package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
- package/dist/components/alert-icon/alert-icon.js +96 -38
- package/dist/components/alert-icon/alert-icon.js.map +1 -1
- package/dist/components/alert-icon/icons/icon-critical.d.ts +3 -0
- package/dist/components/alert-icon/icons/icon-critical.d.ts.map +1 -0
- package/dist/components/alert-icon/icons/icon-critical.js +26 -0
- package/dist/components/alert-icon/icons/icon-critical.js.map +1 -0
- package/dist/components/alert-list-details/alert-list-details.d.ts.map +1 -1
- package/dist/components/alert-list-details/alert-list-details.js +6 -7
- package/dist/components/alert-list-details/alert-list-details.js.map +1 -1
- package/dist/components/badge/badge.css.js +50 -2
- package/dist/components/badge/badge.css.js.map +1 -1
- package/dist/components/badge/badge.d.ts +13 -2
- package/dist/components/badge/badge.d.ts.map +1 -1
- package/dist/components/badge/badge.js +54 -0
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/navigation-item/navigation-item.css.js +5 -0
- package/dist/components/navigation-item/navigation-item.css.js.map +1 -1
- package/dist/components/navigation-item/navigation-item.d.ts +18 -0
- package/dist/components/navigation-item/navigation-item.d.ts.map +1 -1
- package/dist/components/navigation-item/navigation-item.js +49 -1
- package/dist/components/navigation-item/navigation-item.js.map +1 -1
- package/dist/components/navigation-item-group/navigation-item-group.css.js +8 -0
- package/dist/components/navigation-item-group/navigation-item-group.css.js.map +1 -1
- package/dist/components/navigation-item-group/navigation-item-group.d.ts +22 -0
- package/dist/components/navigation-item-group/navigation-item-group.d.ts.map +1 -1
- package/dist/components/navigation-item-group/navigation-item-group.js +63 -1
- package/dist/components/navigation-item-group/navigation-item-group.js.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.d.ts +29 -1
- package/dist/components/navigation-menu/navigation-menu.d.ts.map +1 -1
- package/dist/components/navigation-menu/navigation-menu.js +105 -0
- package/dist/components/navigation-menu/navigation-menu.js.map +1 -1
- package/dist/components/tree-navigation/tree-navigation.css.js +18 -0
- package/dist/components/tree-navigation/tree-navigation.css.js.map +1 -0
- package/dist/components/tree-navigation/tree-navigation.d.ts +74 -0
- package/dist/components/tree-navigation/tree-navigation.d.ts.map +1 -0
- package/dist/components/tree-navigation/tree-navigation.js +120 -0
- package/dist/components/tree-navigation/tree-navigation.js.map +1 -0
- package/dist/components/tree-navigation-group/tree-navigation-group.css.js +22 -0
- package/dist/components/tree-navigation-group/tree-navigation-group.css.js.map +1 -0
- package/dist/components/tree-navigation-group/tree-navigation-group.d.ts +94 -0
- package/dist/components/tree-navigation-group/tree-navigation-group.d.ts.map +1 -0
- package/dist/components/tree-navigation-group/tree-navigation-group.js +116 -0
- package/dist/components/tree-navigation-group/tree-navigation-group.js.map +1 -0
- package/dist/components/tree-navigation-item/tree-navigation-item.css.js +429 -0
- package/dist/components/tree-navigation-item/tree-navigation-item.css.js.map +1 -0
- package/dist/components/tree-navigation-item/tree-navigation-item.d.ts +160 -0
- package/dist/components/tree-navigation-item/tree-navigation-item.d.ts.map +1 -0
- package/dist/components/tree-navigation-item/tree-navigation-item.js +208 -0
- package/dist/components/tree-navigation-item/tree-navigation-item.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/internal/tree-roving-navigator.d.ts +71 -0
- package/dist/internal/tree-roving-navigator.d.ts.map +1 -0
- package/dist/internal/tree-roving-navigator.js +172 -0
- package/dist/internal/tree-roving-navigator.js.map +1 -0
- package/dist/manual-icon/icon-alerts-critical-twotone.d.ts +30 -0
- package/dist/manual-icon/icon-alerts-critical-twotone.d.ts.map +1 -0
- package/dist/manual-icon/icon-alerts-critical-twotone.js +55 -0
- package/dist/manual-icon/icon-alerts-critical-twotone.js.map +1 -0
- package/dist/manual-icon/icon-alerts-diagnostic-twotone.d.ts +30 -0
- package/dist/manual-icon/icon-alerts-diagnostic-twotone.d.ts.map +1 -0
- package/dist/manual-icon/icon-alerts-diagnostic-twotone.js +55 -0
- package/dist/manual-icon/icon-alerts-diagnostic-twotone.js.map +1 -0
- package/dist/navigation-instruments/readout/readout.css.js +3 -18
- package/dist/navigation-instruments/readout/readout.css.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.d.ts +6 -7
- package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout.js +54 -52
- package/dist/navigation-instruments/readout/readout.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +9 -36
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +8 -8
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js +49 -42
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
- package/dist/openbridge.css +155 -0
- package/dist/types.d.ts +7 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +18 -7
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/alert-severity.ts +225 -0
- package/src/ar/building-blocks/poi-header/poi-header.css +38 -7
- package/src/ar/building-blocks/poi-header/poi-header.ts +6 -1
- package/src/ar/poi-button/poi-button.css +126 -32
- package/src/ar/poi-button/poi-button.ts +16 -1
- package/src/ar/types.ts +5 -0
- package/src/automation/automation-badge/automation-badge.ts +124 -17
- package/src/automation/automation-button/abstract-automation-button-storybook-helpers.ts +5 -0
- package/src/automation/automation-button/abstract-automation-button.ts +21 -3
- package/src/automation/automation-button/automation-button.css +9 -4
- package/src/automation/automation-button/automation-button.ts +25 -7
- package/src/automation/automation-tank/automation-tank.stories.ts +22 -0
- package/src/automation/automation-tank/automation-tank.ts +12 -3
- package/src/components/accordion-card/accordion-card.css +33 -0
- package/src/components/accordion-card/accordion-card.stories.ts +2 -1
- package/src/components/accordion-card/accordion-card.ts +3 -4
- package/src/components/alert-button/alert-button.css +89 -5
- package/src/components/alert-button/alert-button.stories.ts +43 -0
- package/src/components/alert-button/alert-button.ts +43 -32
- package/src/components/alert-frame/alert-frame.css +116 -29
- package/src/components/alert-frame/alert-frame.stories.ts +63 -3
- package/src/components/alert-frame/alert-frame.ts +114 -23
- package/src/components/alert-frame/critical-badge.ts +39 -0
- package/src/components/alert-frame/diagnostic-badge.ts +52 -0
- package/src/components/alert-icon/alert-icon.stories.ts +41 -0
- package/src/components/alert-icon/alert-icon.ts +101 -38
- package/src/components/alert-icon/icons/icon-critical.ts +23 -0
- package/src/components/alert-list-details/alert-list-details.stories.ts +67 -0
- package/src/components/alert-list-details/alert-list-details.ts +11 -10
- package/src/components/badge/badge.css +52 -2
- package/src/components/badge/badge.stories.ts +75 -0
- package/src/components/badge/badge.ts +70 -2
- package/src/components/navigation-item/navigation-item.css +5 -0
- package/src/components/navigation-item/navigation-item.ts +56 -1
- package/src/components/navigation-item-group/navigation-item-group.css +8 -0
- package/src/components/navigation-item-group/navigation-item-group.ts +71 -1
- package/src/components/navigation-menu/navigation-menu.stories.ts +54 -0
- package/src/components/navigation-menu/navigation-menu.ts +151 -0
- package/src/components/tree-navigation/tree-navigation.css +7 -0
- package/src/components/tree-navigation/tree-navigation.stories.ts +162 -0
- package/src/components/tree-navigation/tree-navigation.ts +188 -0
- package/src/components/tree-navigation-group/tree-navigation-group.css +11 -0
- package/src/components/tree-navigation-group/tree-navigation-group.ts +157 -0
- package/src/components/tree-navigation-item/tree-navigation-item.css +258 -0
- package/src/components/tree-navigation-item/tree-navigation-item.stories.ts +119 -0
- package/src/components/tree-navigation-item/tree-navigation-item.ts +307 -0
- package/src/internal/tree-roving-navigator.ts +231 -0
- package/src/main.css +1 -0
- package/src/manual-icon/icon-alerts-critical-twotone.ts +60 -0
- package/src/manual-icon/icon-alerts-diagnostic-twotone.ts +60 -0
- package/src/mixins/alert.css +29 -0
- package/src/navigation-instruments/readout/readout.css +3 -24
- package/src/navigation-instruments/readout/readout.stories.ts +57 -4
- package/src/navigation-instruments/readout/readout.ts +69 -63
- package/src/navigation-instruments/readout-list-item/readout-list-item.css +9 -42
- package/src/navigation-instruments/readout-list-item/readout-list-item.stories.ts +57 -14
- package/src/navigation-instruments/readout-list-item/readout-list-item.ts +54 -44
- package/src/palettes/critical.md +95 -0
- package/src/palettes/manual.css +165 -0
- package/src/types.ts +20 -3
|
@@ -6,6 +6,12 @@ import {ifDefined} from 'lit/directives/if-defined.js';
|
|
|
6
6
|
import '../../icons/icon-arrow-flyout-google.js';
|
|
7
7
|
import {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';
|
|
8
8
|
import {customElement} from '../../decorator.js';
|
|
9
|
+
import '../tree-navigation-item/tree-navigation-item.js';
|
|
10
|
+
import {
|
|
11
|
+
TreeBranchType,
|
|
12
|
+
TreeTerminalType,
|
|
13
|
+
} from '../tree-navigation-item/tree-navigation-item.js';
|
|
14
|
+
import {BadgeType} from '../badge/badge.js';
|
|
9
15
|
|
|
10
16
|
enum NavigationItemRole {
|
|
11
17
|
Button = 'button',
|
|
@@ -142,8 +148,32 @@ export class ObcNavigationItem extends LitElement {
|
|
|
142
148
|
|
|
143
149
|
@property({type: Boolean}) hasTrailingIcon = false;
|
|
144
150
|
|
|
151
|
+
/** Set by `obc-navigation-menu` in its Tree variant — renders the row as a tree item. */
|
|
152
|
+
@property({type: Boolean}) treeMode = false;
|
|
153
|
+
|
|
154
|
+
/** Indentation columns for tree mode, assigned by `obc-navigation-menu`. */
|
|
155
|
+
@property({type: Array}) treeBranches: TreeBranchType[] = [];
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Terminal type for the row in the Tree variant — one of `regular` (default),
|
|
159
|
+
* `aggregated-header`, or `group-header`. Has no effect in the flat variants.
|
|
160
|
+
*/
|
|
161
|
+
@property({type: String}) terminalType: string = TreeTerminalType.regular;
|
|
162
|
+
|
|
163
|
+
/** Whether a trailing alert counter badge is shown (Tree variant only). */
|
|
164
|
+
@property({type: Boolean}) hasAlertBadge = false;
|
|
165
|
+
|
|
166
|
+
/** The number shown in the alert badge when `hasAlertBadge` is true (Tree variant only). */
|
|
167
|
+
@property({type: Number}) alertCount = 0;
|
|
168
|
+
|
|
169
|
+
/** The severity/type of the alert badge — one of the `obc-badge` types (Tree variant only). */
|
|
170
|
+
@property({type: String}) alertType: string = BadgeType.alarm;
|
|
171
|
+
|
|
145
172
|
@query('a') private anchorElement?: HTMLAnchorElement;
|
|
146
173
|
|
|
174
|
+
// In tree mode the row renders an `obc-tree-navigation-item` instead of an `<a>`.
|
|
175
|
+
@query('obc-tree-navigation-item') private treeItemElement?: HTMLElement;
|
|
176
|
+
|
|
147
177
|
/**
|
|
148
178
|
* Fired when the navigation item is clicked (either as a link or button).
|
|
149
179
|
* @fires click {CustomEvent<void>}
|
|
@@ -165,7 +195,7 @@ export class ObcNavigationItem extends LitElement {
|
|
|
165
195
|
}
|
|
166
196
|
|
|
167
197
|
public override focus(options?: FocusOptions): void {
|
|
168
|
-
this.anchorElement?.focus(options);
|
|
198
|
+
(this.treeItemElement ?? this.anchorElement)?.focus(options);
|
|
169
199
|
}
|
|
170
200
|
|
|
171
201
|
private getItemRole(): NavigationItemRole | undefined {
|
|
@@ -188,6 +218,31 @@ export class ObcNavigationItem extends LitElement {
|
|
|
188
218
|
}
|
|
189
219
|
|
|
190
220
|
override render() {
|
|
221
|
+
if (this.treeMode) {
|
|
222
|
+
// Delegate the whole row to the tree item: it owns focus, keyboard
|
|
223
|
+
// activation, the checked-inert behavior, and href navigation. Forward its
|
|
224
|
+
// activation as this item's own `click` so selection wiring is unchanged.
|
|
225
|
+
return html`
|
|
226
|
+
<obc-tree-navigation-item
|
|
227
|
+
class="tree"
|
|
228
|
+
.label=${this.label}
|
|
229
|
+
.branches=${this.treeBranches}
|
|
230
|
+
?checked=${this.checked}
|
|
231
|
+
.hasLeadingIcon=${this.hasIcon}
|
|
232
|
+
.href=${this.href}
|
|
233
|
+
.terminalType=${this.terminalType}
|
|
234
|
+
?hasAlertBadge=${this.hasAlertBadge}
|
|
235
|
+
.alertCount=${this.alertCount}
|
|
236
|
+
.alertType=${this.alertType}
|
|
237
|
+
@click=${this.onClick}
|
|
238
|
+
>
|
|
239
|
+
${this.hasIcon
|
|
240
|
+
? html`<slot name="icon" slot="icon"></slot>`
|
|
241
|
+
: nothing}
|
|
242
|
+
</obc-tree-navigation-item>
|
|
243
|
+
`;
|
|
244
|
+
}
|
|
245
|
+
|
|
191
246
|
const showFlyout =
|
|
192
247
|
this.group && this.variant !== ObcNavigationMenuVariant.IconOnly;
|
|
193
248
|
const isCompact = this.variant === ObcNavigationMenuVariant.Compact;
|
|
@@ -4,6 +4,12 @@ import compentStyle from './navigation-item-group.css?inline';
|
|
|
4
4
|
import {ObcNavigationMenuVariant} from '../navigation-menu/navigation-menu.js';
|
|
5
5
|
import {classMap} from 'lit/directives/class-map.js';
|
|
6
6
|
import {customElement} from '../../decorator.js';
|
|
7
|
+
import '../tree-navigation-item/tree-navigation-item.js';
|
|
8
|
+
import {
|
|
9
|
+
TreeBranchType,
|
|
10
|
+
TreeTerminalType,
|
|
11
|
+
} from '../tree-navigation-item/tree-navigation-item.js';
|
|
12
|
+
import {BadgeType} from '../badge/badge.js';
|
|
7
13
|
|
|
8
14
|
/**
|
|
9
15
|
* `<obc-navigation-item-group>` – A collapsible navigation group component for organizing related navigation items under a single expandable label.
|
|
@@ -90,9 +96,47 @@ export class ObcNavigationItemGroup extends LitElement {
|
|
|
90
96
|
|
|
91
97
|
@property({type: Boolean}) hasIcon = false;
|
|
92
98
|
|
|
99
|
+
/** Set by `obc-navigation-menu` in its Tree variant — renders the group as a tree row. */
|
|
100
|
+
@property({type: Boolean}) treeMode = false;
|
|
101
|
+
|
|
102
|
+
/** Indentation columns for tree mode, assigned by `obc-navigation-menu`. */
|
|
103
|
+
@property({type: Array}) treeBranches: TreeBranchType[] = [];
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Terminal type for the group header in the Tree variant — one of `regular`
|
|
107
|
+
* (default), `aggregated-header`, or `group-header`. No effect in flat variants.
|
|
108
|
+
*/
|
|
109
|
+
@property({type: String}) terminalType: string = TreeTerminalType.regular;
|
|
110
|
+
|
|
111
|
+
/** Whether a trailing alert counter badge is shown on the header (Tree variant only). */
|
|
112
|
+
@property({type: Boolean}) hasAlertBadge = false;
|
|
113
|
+
|
|
114
|
+
/** The number shown in the header's alert badge when `hasAlertBadge` is true (Tree variant only). */
|
|
115
|
+
@property({type: Number}) alertCount = 0;
|
|
116
|
+
|
|
117
|
+
/** The severity/type of the header's alert badge — one of the `obc-badge` types (Tree variant only). */
|
|
118
|
+
@property({type: String}) alertType: string = BadgeType.alarm;
|
|
119
|
+
|
|
120
|
+
/** Whether the group starts expanded. Useful for trees that open by default. */
|
|
121
|
+
@property({type: Boolean}) defaultOpen = false;
|
|
122
|
+
|
|
93
123
|
@state() private openContainer = false;
|
|
94
124
|
|
|
95
|
-
|
|
125
|
+
// Flat mode renders an `obc-navigation-item` header; tree mode renders an
|
|
126
|
+
// `obc-tree-navigation-item`. Match whichever is present so `focus()` works in both.
|
|
127
|
+
@query('obc-navigation-item, obc-tree-navigation-item')
|
|
128
|
+
private groupItem?: HTMLElement;
|
|
129
|
+
|
|
130
|
+
override firstUpdated() {
|
|
131
|
+
if (this.defaultOpen) {
|
|
132
|
+
this.openContainer = true;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Whether the group is currently open (its children are disclosed). */
|
|
137
|
+
public get expanded(): boolean {
|
|
138
|
+
return this.openContainer;
|
|
139
|
+
}
|
|
96
140
|
|
|
97
141
|
private onClickGroup() {
|
|
98
142
|
if (this.openContainer) {
|
|
@@ -123,6 +167,32 @@ export class ObcNavigationItemGroup extends LitElement {
|
|
|
123
167
|
}
|
|
124
168
|
|
|
125
169
|
override render() {
|
|
170
|
+
if (this.treeMode) {
|
|
171
|
+
return html`
|
|
172
|
+
<obc-tree-navigation-item
|
|
173
|
+
part="header"
|
|
174
|
+
.label=${this.label}
|
|
175
|
+
.branches=${this.treeBranches}
|
|
176
|
+
expandable
|
|
177
|
+
?expanded=${this.openContainer}
|
|
178
|
+
?checked=${this.checked}
|
|
179
|
+
.hasLeadingIcon=${this.hasIcon}
|
|
180
|
+
.terminalType=${this.terminalType}
|
|
181
|
+
?hasAlertBadge=${this.hasAlertBadge}
|
|
182
|
+
.alertCount=${this.alertCount}
|
|
183
|
+
.alertType=${this.alertType}
|
|
184
|
+
@expand-toggle=${this.onClickGroup}
|
|
185
|
+
>
|
|
186
|
+
${this.hasIcon
|
|
187
|
+
? html`<slot name="icon" slot="icon"></slot>`
|
|
188
|
+
: nothing}
|
|
189
|
+
</obc-tree-navigation-item>
|
|
190
|
+
<div part="children" role="group" ?hidden=${!this.openContainer}>
|
|
191
|
+
<slot></slot>
|
|
192
|
+
</div>
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
|
|
126
196
|
return html`
|
|
127
197
|
<obc-navigation-item
|
|
128
198
|
@click=${this.onClickGroup}
|
|
@@ -252,3 +252,57 @@ export const TestDynamicElementsInSpan: Story = {
|
|
|
252
252
|
await expect(newItem.variant).toBe(ObcNavigationMenuVariant.Compact);
|
|
253
253
|
},
|
|
254
254
|
};
|
|
255
|
+
|
|
256
|
+
export const Tree: Story = {
|
|
257
|
+
args: {
|
|
258
|
+
variant: ObcNavigationMenuVariant.Tree,
|
|
259
|
+
},
|
|
260
|
+
render: (args) => {
|
|
261
|
+
return html`
|
|
262
|
+
<obc-navigation-menu
|
|
263
|
+
.variant=${args.variant}
|
|
264
|
+
style="position: fixed; top: 0; bottom: 0; left: 0;"
|
|
265
|
+
>
|
|
266
|
+
<obc-navigation-item-group
|
|
267
|
+
slot="main"
|
|
268
|
+
label="Vessel"
|
|
269
|
+
hasIcon
|
|
270
|
+
defaultOpen
|
|
271
|
+
>
|
|
272
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
273
|
+
<obc-navigation-item-group
|
|
274
|
+
label="Engine room"
|
|
275
|
+
hasIcon
|
|
276
|
+
defaultOpen
|
|
277
|
+
terminalType="aggregated-header"
|
|
278
|
+
>
|
|
279
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
280
|
+
<obc-navigation-item label="Main engine" hasIcon checked>
|
|
281
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
282
|
+
</obc-navigation-item>
|
|
283
|
+
<obc-navigation-item
|
|
284
|
+
label="Cooling system"
|
|
285
|
+
hasIcon
|
|
286
|
+
hasAlertBadge
|
|
287
|
+
.alertCount=${3}
|
|
288
|
+
>
|
|
289
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
290
|
+
</obc-navigation-item>
|
|
291
|
+
</obc-navigation-item-group>
|
|
292
|
+
<obc-navigation-item-group label="Bridge" hasIcon>
|
|
293
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
294
|
+
<obc-navigation-item label="Radar" hasIcon>
|
|
295
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
296
|
+
</obc-navigation-item>
|
|
297
|
+
<obc-navigation-item label="Autopilot" hasIcon>
|
|
298
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
299
|
+
</obc-navigation-item>
|
|
300
|
+
</obc-navigation-item-group>
|
|
301
|
+
<obc-navigation-item label="Deck" hasIcon>
|
|
302
|
+
<obi-placeholder slot="icon"></obi-placeholder>
|
|
303
|
+
</obc-navigation-item>
|
|
304
|
+
</obc-navigation-item-group>
|
|
305
|
+
</obc-navigation-menu>
|
|
306
|
+
`;
|
|
307
|
+
},
|
|
308
|
+
};
|
|
@@ -4,6 +4,29 @@ import compentStyle from './navigation-menu.css?inline';
|
|
|
4
4
|
import {ObcNavigationItemGroup} from '../navigation-item-group/navigation-item-group.js';
|
|
5
5
|
import {ObcNavigationItem} from '../navigation-item/navigation-item.js';
|
|
6
6
|
import {customElement} from '../../decorator.js';
|
|
7
|
+
import {
|
|
8
|
+
ObcTreeNavigationItem,
|
|
9
|
+
TreeBranchType,
|
|
10
|
+
} from '../tree-navigation-item/tree-navigation-item.js';
|
|
11
|
+
import {
|
|
12
|
+
TreeRovingNavigator,
|
|
13
|
+
TreeRovingAdapter,
|
|
14
|
+
} from '../../internal/tree-roving-navigator.js';
|
|
15
|
+
|
|
16
|
+
/** A nav-menu tree row is either a navigation item or a navigation item group. */
|
|
17
|
+
type NavTreeRow = ObcNavigationItem | ObcNavigationItemGroup;
|
|
18
|
+
|
|
19
|
+
const NAV_ITEM_TAG = 'obc-navigation-item';
|
|
20
|
+
const NAV_GROUP_TAG = 'obc-navigation-item-group';
|
|
21
|
+
|
|
22
|
+
function isNavGroup(el: Element): el is ObcNavigationItemGroup {
|
|
23
|
+
return el.tagName.toLowerCase() === NAV_GROUP_TAG;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isNavRow(el: Element): el is NavTreeRow {
|
|
27
|
+
const tag = el.tagName.toLowerCase();
|
|
28
|
+
return tag === NAV_ITEM_TAG || tag === NAV_GROUP_TAG;
|
|
29
|
+
}
|
|
7
30
|
|
|
8
31
|
/**
|
|
9
32
|
* `ObcNavigationMenuVariant` – Enumerates the available visual and behavioral variants for `<obc-navigation-menu>`.
|
|
@@ -12,6 +35,7 @@ import {customElement} from '../../decorator.js';
|
|
|
12
35
|
* - `IconOnly`: Compact menu showing only icons (should only be used when no flyouts/submenus are present).
|
|
13
36
|
* - `IconOnlyLarge`: Icon-only menu variant designed for use when flyouts/submenus are present.
|
|
14
37
|
* - `Compact`: Space-saving menu with reduced padding and layout.
|
|
38
|
+
* - `Tree`: Hierarchical tree — groups expand inline and rows are indented by depth.
|
|
15
39
|
*
|
|
16
40
|
* Use these variants to adapt the navigation menu to different layouts or device sizes.
|
|
17
41
|
*/
|
|
@@ -20,6 +44,7 @@ export enum ObcNavigationMenuVariant {
|
|
|
20
44
|
IconOnly = 'icon-only', // Should only be used when no flyouts are present in the navigation menu
|
|
21
45
|
IconOnlyLarge = 'icon-only-large', // Should be used when flyouts are present in the navigation menu
|
|
22
46
|
Compact = 'compact',
|
|
47
|
+
Tree = 'tree',
|
|
23
48
|
}
|
|
24
49
|
|
|
25
50
|
/**
|
|
@@ -49,6 +74,11 @@ export enum ObcNavigationMenuFlyoutVariant {
|
|
|
49
74
|
* - **IconOnly:** Shows only icons for a compact appearance. *Should only be used when no navigation items have sub-items or flyouts.*
|
|
50
75
|
* - **IconOnlyLarge:** Icon-only mode that supports flyouts/submenus. Use when navigation contains groups or nested items.
|
|
51
76
|
* - **Compact:** Reduces padding and overall width for a space-saving layout.
|
|
77
|
+
* - **Tree:** Renders the same `obc-navigation-item` / `obc-navigation-item-group`
|
|
78
|
+
* markup as a hierarchical tree. Groups expand inline (instead of as flyouts),
|
|
79
|
+
* rows are indented by depth, multiple branches can stay open at once, and the
|
|
80
|
+
* tree-row presentation (alert badge, terminal marker) is available via the
|
|
81
|
+
* items' `hasAlertBadge`/`alertCount`/`alertType`/`terminalType` properties.
|
|
52
82
|
* - **Responsive Layout:**
|
|
53
83
|
* - `smallScreen` property adapts the footer and logo layout for smaller viewports.
|
|
54
84
|
* - **Slot-based Content:**
|
|
@@ -71,6 +101,10 @@ export enum ObcNavigationMenuFlyoutVariant {
|
|
|
71
101
|
* - Use the `Full` variant for standard navigation with both icons and labels.
|
|
72
102
|
* - Use `IconOnly` only when there are no nested groups or flyouts; otherwise, use `IconOnlyLarge` for icon-only navigation with flyout support.
|
|
73
103
|
* - The `Compact` variant is suitable for layouts with limited space or when a minimal navigation appearance is desired.
|
|
104
|
+
* - Use the `Tree` variant for hierarchical navigation (file trees, nested
|
|
105
|
+
* sections). The existing item/group markup is reused unchanged — only the
|
|
106
|
+
* `variant` changes. Footer and logo slots remain flat. Mark a group with
|
|
107
|
+
* `defaultOpen` to have it start expanded.
|
|
74
108
|
* - Set `smallScreen` to `true` to optimize the layout for smaller devices or responsive breakpoints.
|
|
75
109
|
*
|
|
76
110
|
* **TODO(designer):** Provide additional guidance on when to use each variant and recommended slot content for best usability.
|
|
@@ -129,6 +163,7 @@ export class ObcNavigationMenu extends LitElement {
|
|
|
129
163
|
* - `icon-only`: Compact, icon-only menu (use only when no flyouts/groups are present).
|
|
130
164
|
* - `icon-only-large`: Icon-only menu supporting flyouts/groups.
|
|
131
165
|
* - `compact`: Minimal, space-saving menu.
|
|
166
|
+
* - `tree`: Hierarchical tree — groups expand inline and rows are indented by depth.
|
|
132
167
|
*/
|
|
133
168
|
@property({type: String}) variant: ObcNavigationMenuVariant =
|
|
134
169
|
ObcNavigationMenuVariant.Full;
|
|
@@ -148,6 +183,59 @@ export class ObcNavigationMenu extends LitElement {
|
|
|
148
183
|
private slotObservers: MutationObserver[] = [];
|
|
149
184
|
@state() private hasFooter = false;
|
|
150
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Roving-tabindex + arrow-key navigation for the Tree variant, sharing the
|
|
188
|
+
* navigator that drives `obc-tree-navigation`. Engaged only while
|
|
189
|
+
* `variant === Tree` (see `onTreeKeydown`).
|
|
190
|
+
*/
|
|
191
|
+
private readonly treeNavigator = new TreeRovingNavigator<NavTreeRow>(this, {
|
|
192
|
+
getRows: () => this.treeRootRows(),
|
|
193
|
+
childRows: (row) => this.treeChildRows(row),
|
|
194
|
+
isGroup: (row) => isNavGroup(row),
|
|
195
|
+
// Read the group's own synchronous open state, not the shadow header's
|
|
196
|
+
// attribute (which lags a render tick behind a keyboard expand/collapse).
|
|
197
|
+
isExpanded: (row) => isNavGroup(row) && row.expanded,
|
|
198
|
+
setExpanded: (row, expanded) => {
|
|
199
|
+
if (!isNavGroup(row)) return;
|
|
200
|
+
if (expanded) row.open();
|
|
201
|
+
else row.close();
|
|
202
|
+
},
|
|
203
|
+
innerItem: (row) => this.treeInnerItem(row),
|
|
204
|
+
} satisfies TreeRovingAdapter<NavTreeRow>);
|
|
205
|
+
|
|
206
|
+
/** Top-level tree rows of the main slot (mirrors `assignTreeBranches`'s filter). */
|
|
207
|
+
private treeRootRows(): NavTreeRow[] {
|
|
208
|
+
return Array.from(this.children).filter((child): child is NavTreeRow => {
|
|
209
|
+
if (!isNavRow(child)) return false;
|
|
210
|
+
const slot = child.getAttribute('slot');
|
|
211
|
+
return slot === null || slot === 'main';
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Direct tree-row children of a row, in document order. */
|
|
216
|
+
private treeChildRows(row: NavTreeRow): NavTreeRow[] {
|
|
217
|
+
return Array.from(row.children).filter(isNavRow);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** The inline `obc-tree-navigation-item` a tree-mode row renders in its shadow root. */
|
|
221
|
+
private treeInnerItem(row: NavTreeRow): ObcTreeNavigationItem | null {
|
|
222
|
+
return (
|
|
223
|
+
row.shadowRoot?.querySelector<ObcTreeNavigationItem>(
|
|
224
|
+
'obc-tree-navigation-item'
|
|
225
|
+
) ?? null
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private onTreeKeydown = (event: KeyboardEvent): void => {
|
|
230
|
+
if (this.variant !== ObcNavigationMenuVariant.Tree) return;
|
|
231
|
+
if (this.treeNavigator.handleKeydown(event)) event.preventDefault();
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
override connectedCallback(): void {
|
|
235
|
+
super.connectedCallback();
|
|
236
|
+
this.addEventListener('keydown', this.onTreeKeydown);
|
|
237
|
+
}
|
|
238
|
+
|
|
151
239
|
findAllElements<T extends Element>(
|
|
152
240
|
el: Element,
|
|
153
241
|
tag: string,
|
|
@@ -212,6 +300,7 @@ export class ObcNavigationMenu extends LitElement {
|
|
|
212
300
|
registerGroup(groups: ObcNavigationItemGroup[]) {
|
|
213
301
|
groups.forEach((group) => {
|
|
214
302
|
group.addEventListener('open', () => {
|
|
303
|
+
if (this.variant === ObcNavigationMenuVariant.Tree) return;
|
|
215
304
|
groups.forEach((g) => {
|
|
216
305
|
if (g !== group) {
|
|
217
306
|
g.close();
|
|
@@ -296,6 +385,7 @@ export class ObcNavigationMenu extends LitElement {
|
|
|
296
385
|
override disconnectedCallback(): void {
|
|
297
386
|
super.disconnectedCallback();
|
|
298
387
|
this.cleanupSlotObservers();
|
|
388
|
+
this.removeEventListener('keydown', this.onTreeKeydown);
|
|
299
389
|
}
|
|
300
390
|
|
|
301
391
|
private handleSlotChange() {
|
|
@@ -303,7 +393,68 @@ export class ObcNavigationMenu extends LitElement {
|
|
|
303
393
|
this.setupSlotObservers();
|
|
304
394
|
}
|
|
305
395
|
|
|
396
|
+
private assignTreeBranches(el: Element, depth: number): void {
|
|
397
|
+
for (const child of el.children) {
|
|
398
|
+
const tag = child.tagName.toLowerCase();
|
|
399
|
+
const isItem = tag === 'obc-navigation-item';
|
|
400
|
+
const isGroup = tag === 'obc-navigation-item-group';
|
|
401
|
+
if (!isItem && !isGroup) continue;
|
|
402
|
+
// Top-level rows are slotted; only treeify the main slot. Nested rows have
|
|
403
|
+
// no slot attribute and always belong to their group's tree.
|
|
404
|
+
if (depth === 0) {
|
|
405
|
+
const slot = child.getAttribute('slot');
|
|
406
|
+
if (slot !== null && slot !== 'main') continue;
|
|
407
|
+
}
|
|
408
|
+
const branches: TreeBranchType[] = Array.from(
|
|
409
|
+
{length: depth},
|
|
410
|
+
() => TreeBranchType.blank
|
|
411
|
+
);
|
|
412
|
+
const row = child as ObcNavigationItem | ObcNavigationItemGroup;
|
|
413
|
+
row.treeMode = true;
|
|
414
|
+
row.treeBranches = branches;
|
|
415
|
+
if (isGroup) {
|
|
416
|
+
this.assignTreeBranches(child, depth + 1);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Reset tree mode on every descendant item/group so switching away from the
|
|
422
|
+
// Tree variant restores the flat rendering.
|
|
423
|
+
private clearTreeMode(el: Element): void {
|
|
424
|
+
for (const child of el.children) {
|
|
425
|
+
const tag = child.tagName.toLowerCase();
|
|
426
|
+
const isItem = tag === 'obc-navigation-item';
|
|
427
|
+
const isGroup = tag === 'obc-navigation-item-group';
|
|
428
|
+
if (!isItem && !isGroup) continue;
|
|
429
|
+
const row = child as ObcNavigationItem | ObcNavigationItemGroup;
|
|
430
|
+
row.treeMode = false;
|
|
431
|
+
row.treeBranches = [];
|
|
432
|
+
if (isGroup) {
|
|
433
|
+
this.clearTreeMode(child);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
306
438
|
private setupItems() {
|
|
439
|
+
if (this.variant === ObcNavigationMenuVariant.Tree) {
|
|
440
|
+
this.assignTreeBranches(this, 0);
|
|
441
|
+
// Footer and logo are not part of the tree — keep them as flat full-variant
|
|
442
|
+
// items (and clear any tree mode left over from the main slot's walk).
|
|
443
|
+
(['footer', 'logo'] as const).forEach((slot) => {
|
|
444
|
+
this.findAllItems(this, slot).forEach((item) => {
|
|
445
|
+
item.treeMode = false;
|
|
446
|
+
item.treeBranches = [];
|
|
447
|
+
item.variant = ObcNavigationMenuVariant.Full;
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
// Defer so the rows' inline tree-item headers exist before the roving
|
|
451
|
+
// tabindex is assigned to them.
|
|
452
|
+
queueMicrotask(() => this.treeNavigator.refresh());
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
this.clearTreeMode(this);
|
|
457
|
+
|
|
307
458
|
const hug =
|
|
308
459
|
this.variant !== ObcNavigationMenuVariant.Full ||
|
|
309
460
|
this.flyoutVariant === ObcNavigationMenuFlyoutVariant.Compact;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type {Meta, StoryObj} from '@storybook/web-components-vite';
|
|
2
|
+
import {ObcTreeNavigation} from './tree-navigation.js';
|
|
3
|
+
import './tree-navigation.js';
|
|
4
|
+
import '../tree-navigation-group/tree-navigation-group.js';
|
|
5
|
+
import '../tree-navigation-item/tree-navigation-item.js';
|
|
6
|
+
import {TreeTerminalType} from '../tree-navigation-item/tree-navigation-item.js';
|
|
7
|
+
import {iconIdToIconHtml} from '../../storybook-util.js';
|
|
8
|
+
import {LitElement, html} from 'lit';
|
|
9
|
+
import {state} from 'lit/decorators.js';
|
|
10
|
+
import {customElement} from '../../decorator.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* `<obc-tree-navigation>` builds the guide lines automatically from the nested
|
|
14
|
+
* markup. Write groups and items as real nested elements; the container assigns
|
|
15
|
+
* each row's `branches` from its position. Click a group header to expand or
|
|
16
|
+
* collapse — the guides recompute to match.
|
|
17
|
+
*/
|
|
18
|
+
const meta: Meta<typeof ObcTreeNavigation> = {
|
|
19
|
+
title: 'UI Components/Menus and Navigation/Tree Navigation',
|
|
20
|
+
tags: ['autodocs', '6.0'],
|
|
21
|
+
component: 'obc-tree-navigation',
|
|
22
|
+
render: () => html`
|
|
23
|
+
<obc-tree-navigation>
|
|
24
|
+
<obc-tree-navigation-group label="Vessel" expanded>
|
|
25
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
26
|
+
<obc-tree-navigation-group
|
|
27
|
+
label="Engine room"
|
|
28
|
+
expanded
|
|
29
|
+
.terminalType=${TreeTerminalType.aggregatedHeader}
|
|
30
|
+
>
|
|
31
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
32
|
+
<obc-tree-navigation-item label="Main engine" checked>
|
|
33
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
34
|
+
</obc-tree-navigation-item>
|
|
35
|
+
<obc-tree-navigation-group
|
|
36
|
+
label="Auxiliary engine"
|
|
37
|
+
expanded
|
|
38
|
+
hasAlertBadge
|
|
39
|
+
.alertCount=${3}
|
|
40
|
+
>
|
|
41
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
42
|
+
<obc-tree-navigation-item label="Fuel pump">
|
|
43
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
44
|
+
</obc-tree-navigation-item>
|
|
45
|
+
<obc-tree-navigation-item
|
|
46
|
+
label="Starter"
|
|
47
|
+
hasAlertBadge
|
|
48
|
+
.alertCount=${1}
|
|
49
|
+
>
|
|
50
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
51
|
+
</obc-tree-navigation-item>
|
|
52
|
+
<obc-tree-navigation-item label="Oil filter">
|
|
53
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
54
|
+
</obc-tree-navigation-item>
|
|
55
|
+
</obc-tree-navigation-group>
|
|
56
|
+
<obc-tree-navigation-group label="Cooling system" expanded>
|
|
57
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
58
|
+
<obc-tree-navigation-item label="Seawater pump">
|
|
59
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
60
|
+
</obc-tree-navigation-item>
|
|
61
|
+
</obc-tree-navigation-group>
|
|
62
|
+
</obc-tree-navigation-group>
|
|
63
|
+
<obc-tree-navigation-group label="Bridge" expanded>
|
|
64
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
65
|
+
<obc-tree-navigation-item label="Radar">
|
|
66
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
67
|
+
</obc-tree-navigation-item>
|
|
68
|
+
<obc-tree-navigation-item label="Autopilot" disabled>
|
|
69
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
70
|
+
</obc-tree-navigation-item>
|
|
71
|
+
<obc-tree-navigation-item label="ECDIS">
|
|
72
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
73
|
+
</obc-tree-navigation-item>
|
|
74
|
+
</obc-tree-navigation-group>
|
|
75
|
+
<obc-tree-navigation-item label="Deck">
|
|
76
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
77
|
+
</obc-tree-navigation-item>
|
|
78
|
+
</obc-tree-navigation-group>
|
|
79
|
+
<obc-tree-navigation-item label="Shore power">
|
|
80
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
81
|
+
</obc-tree-navigation-item>
|
|
82
|
+
</obc-tree-navigation>
|
|
83
|
+
`,
|
|
84
|
+
} satisfies Meta<ObcTreeNavigation>;
|
|
85
|
+
|
|
86
|
+
export default meta;
|
|
87
|
+
type Story = StoryObj<ObcTreeNavigation>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* A fully expanded tree. The guide lines — pass-through verticals, intersections,
|
|
91
|
+
* and last-child corners — are all computed by the container from the nested
|
|
92
|
+
* markup. The header rows are groups; the leaves are items.
|
|
93
|
+
*/
|
|
94
|
+
export const Default: Story = {};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* `<tree-navigation-selection-demo>` – Wraps the tree to track which leaf is
|
|
98
|
+
* selected. Selection is purely consumer state: it sets `checked` on the chosen
|
|
99
|
+
* item; the container still owns all guide-line logic.
|
|
100
|
+
*
|
|
101
|
+
* Not exported: Storybook treats every module export as a story, so the demo
|
|
102
|
+
* element is kept file-local and registered only via the `@customElement` side
|
|
103
|
+
* effect.
|
|
104
|
+
*/
|
|
105
|
+
@customElement('tree-navigation-selection-demo')
|
|
106
|
+
class TreeNavigationSelectionDemo extends LitElement {
|
|
107
|
+
@state() private selectedLabel = 'Main engine';
|
|
108
|
+
|
|
109
|
+
override createRenderRoot() {
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private select(label: string) {
|
|
114
|
+
this.selectedLabel = label;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private leaf(label: string) {
|
|
118
|
+
return html`<obc-tree-navigation-item
|
|
119
|
+
label=${label}
|
|
120
|
+
?checked=${this.selectedLabel === label}
|
|
121
|
+
@click=${() => this.select(label)}
|
|
122
|
+
>
|
|
123
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
124
|
+
</obc-tree-navigation-item>`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
override render() {
|
|
128
|
+
return html`
|
|
129
|
+
<obc-tree-navigation>
|
|
130
|
+
<obc-tree-navigation-group label="Vessel" expanded>
|
|
131
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
132
|
+
<obc-tree-navigation-group label="Engine room" expanded>
|
|
133
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
134
|
+
${this.leaf('Main engine')} ${this.leaf('Auxiliary engine')}
|
|
135
|
+
${this.leaf('Cooling system')}
|
|
136
|
+
</obc-tree-navigation-group>
|
|
137
|
+
<obc-tree-navigation-group label="Bridge" expanded>
|
|
138
|
+
${iconIdToIconHtml('placeholder', {slot: 'icon'})}
|
|
139
|
+
${this.leaf('Radar')} ${this.leaf('Autopilot')}
|
|
140
|
+
</obc-tree-navigation-group>
|
|
141
|
+
${this.leaf('Deck')}
|
|
142
|
+
</obc-tree-navigation-group>
|
|
143
|
+
</obc-tree-navigation>
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
declare global {
|
|
149
|
+
interface HTMLElementTagNameMap {
|
|
150
|
+
'tree-navigation-selection-demo': TreeNavigationSelectionDemo;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Click a leaf to select it; click a group chevron to expand or collapse. The
|
|
156
|
+
* container keeps the guide lines correct through every change — the consumer
|
|
157
|
+
* only tracks the selected item.
|
|
158
|
+
*/
|
|
159
|
+
export const Interactive: Story = {
|
|
160
|
+
render: () =>
|
|
161
|
+
html`<tree-navigation-selection-demo></tree-navigation-selection-demo>`,
|
|
162
|
+
};
|