From 6afdc06f9eafa9c16e7e6fac41e77937bdff2fd8 Mon Sep 17 00:00:00 2001 From: Patrick Pircher Date: Wed, 29 Jul 2026 16:27:10 +0200 Subject: [PATCH 1/5] feat: implement remaining UIShell sub-components Adds HeaderMenu/HeaderMenuItem (dropdown submenus in the top Header nav), HeaderPanel and the top-level Switcher/SwitcherItem/SwitcherDivider (app switcher panel), SideNavHeader/SideNavDetails/SideNavIcon, and HeaderSideNavItems (mirrors header items into the side nav). Also adds HeaderContainer, a stateful wrapper that manages isSideNavExpanded and collapses it on Escape so consumers no longer have to manage that state themselves. Closes #638 Signed-off-by: Patrick Pircher --- .parity-check-data.json | 2 +- carbon-components-ember/package.json | 11 ++ .../src/components/ui-shell.gts | 15 +- .../components/ui-shell/-header-container.gts | 49 ++++++ .../src/components/ui-shell/-header.gts | 3 + .../ui-shell/-header/-menu-item.gts | 30 ++++ .../src/components/ui-shell/-header/-menu.gts | 55 ++++++ .../components/ui-shell/-header/-panel.gts | 32 ++++ .../ui-shell/-header/-side-nav-items.gts | 23 +++ .../src/components/ui-shell/-nav.gts | 5 +- .../src/components/ui-shell/-sidenav.gts | 15 +- .../components/ui-shell/-sidenav/-details.gts | 22 +++ .../components/ui-shell/-sidenav/-header.gts | 24 +++ .../components/ui-shell/-sidenav/-icon.gts | 22 +++ .../src/components/ui-shell/-switcher.gts | 27 +++ .../ui-shell/-switcher/-divider.gts | 13 ++ .../components/ui-shell/-switcher/-item.gts | 29 ++++ .../app/templates/2-components/ui-shell.md | 157 ++++++++++++++++++ test-app/tests/components/ui-shell-test.gts | 129 ++++++++++++++ 19 files changed, 657 insertions(+), 6 deletions(-) create mode 100644 carbon-components-ember/src/components/ui-shell/-header-container.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-header/-menu-item.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-header/-menu.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-header/-panel.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-header/-side-nav-items.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-sidenav/-details.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-sidenav/-header.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-sidenav/-icon.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-switcher.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-switcher/-divider.gts create mode 100644 carbon-components-ember/src/components/ui-shell/-switcher/-item.gts diff --git a/.parity-check-data.json b/.parity-check-data.json index 011dd1a60..37a94d95b 100644 --- a/.parity-check-data.json +++ b/.parity-check-data.json @@ -572,7 +572,7 @@ }, "UIShell": { "lastCheckedCommit": "5102bd860864c2580048183ffaf50d1ffd4400b5", - "lastSyncedCommit": "N/A", + "lastSyncedCommit": "5102bd860864c2580048183ffaf50d1ffd4400b5", "hasChanges": false, "changeCount": 0, "lastUpdate": null diff --git a/carbon-components-ember/package.json b/carbon-components-ember/package.json index d4d2dc17b..7cf59f98c 100644 --- a/carbon-components-ember/package.json +++ b/carbon-components-ember/package.json @@ -2968,15 +2968,26 @@ "./components/carbon/tooltip.js": "./dist/_app_/components/carbon/tooltip.js", "./components/carbon/tree-view.js": "./dist/_app_/components/carbon/tree-view.js", "./components/carbon/ui-shell.js": "./dist/_app_/components/carbon/ui-shell.js", + "./components/carbon/ui-shell/-header-container.js": "./dist/_app_/components/carbon/ui-shell/-header-container.js", "./components/carbon/ui-shell/-header.js": "./dist/_app_/components/carbon/ui-shell/-header.js", "./components/carbon/ui-shell/-header/-global-action.js": "./dist/_app_/components/carbon/ui-shell/-header/-global-action.js", + "./components/carbon/ui-shell/-header/-menu-item.js": "./dist/_app_/components/carbon/ui-shell/-header/-menu-item.js", + "./components/carbon/ui-shell/-header/-menu.js": "./dist/_app_/components/carbon/ui-shell/-header/-menu.js", + "./components/carbon/ui-shell/-header/-panel.js": "./dist/_app_/components/carbon/ui-shell/-header/-panel.js", + "./components/carbon/ui-shell/-header/-side-nav-items.js": "./dist/_app_/components/carbon/ui-shell/-header/-side-nav-items.js", "./components/carbon/ui-shell/-nav.js": "./dist/_app_/components/carbon/ui-shell/-nav.js", "./components/carbon/ui-shell/-nav/-item.js": "./dist/_app_/components/carbon/ui-shell/-nav/-item.js", "./components/carbon/ui-shell/-sidenav.js": "./dist/_app_/components/carbon/ui-shell/-sidenav.js", + "./components/carbon/ui-shell/-sidenav/-details.js": "./dist/_app_/components/carbon/ui-shell/-sidenav/-details.js", "./components/carbon/ui-shell/-sidenav/-divider.js": "./dist/_app_/components/carbon/ui-shell/-sidenav/-divider.js", "./components/carbon/ui-shell/-sidenav/-footer.js": "./dist/_app_/components/carbon/ui-shell/-sidenav/-footer.js", + "./components/carbon/ui-shell/-sidenav/-header.js": "./dist/_app_/components/carbon/ui-shell/-sidenav/-header.js", + "./components/carbon/ui-shell/-sidenav/-icon.js": "./dist/_app_/components/carbon/ui-shell/-sidenav/-icon.js", "./components/carbon/ui-shell/-sidenav/-menu.js": "./dist/_app_/components/carbon/ui-shell/-sidenav/-menu.js", "./components/carbon/ui-shell/-sidenav/-sub-menu.js": "./dist/_app_/components/carbon/ui-shell/-sidenav/-sub-menu.js", + "./components/carbon/ui-shell/-switcher.js": "./dist/_app_/components/carbon/ui-shell/-switcher.js", + "./components/carbon/ui-shell/-switcher/-divider.js": "./dist/_app_/components/carbon/ui-shell/-switcher/-divider.js", + "./components/carbon/ui-shell/-switcher/-item.js": "./dist/_app_/components/carbon/ui-shell/-switcher/-item.js", "./components/carbon/unordered-list.js": "./dist/_app_/components/carbon/unordered-list.js", "./helpers/carbon/default-to.js": "./dist/_app_/helpers/carbon/default-to.js", "./helpers/carbon/generic.js": "./dist/_app_/helpers/carbon/generic.js", diff --git a/carbon-components-ember/src/components/ui-shell.gts b/carbon-components-ember/src/components/ui-shell.gts index e718bb61b..df6d6d15d 100644 --- a/carbon-components-ember/src/components/ui-shell.gts +++ b/carbon-components-ember/src/components/ui-shell.gts @@ -1,6 +1,8 @@ import { default as Header } from './ui-shell/-header.gts'; import { default as Sidenav } from './ui-shell/-sidenav.gts'; import { default as Nav } from './ui-shell/-nav.gts'; +import { default as Switcher } from './ui-shell/-switcher.gts'; +import { default as HeaderContainer } from './ui-shell/-header-container.gts'; import Component from '@glimmer/component'; import UIShellHeader from './ui-shell/-header.gts'; import { hash } from '@ember/helper'; @@ -12,6 +14,8 @@ export interface UIShellSignature { Header: typeof UIShellHeader; Sidenav: typeof Sidenav; Nav: typeof Nav; + Switcher: typeof Switcher; + HeaderContainer: typeof HeaderContainer; }, ]; content: []; @@ -20,7 +24,16 @@ export interface UIShellSignature { export default class UIShell extends Component { } diff --git a/carbon-components-ember/src/components/ui-shell/-header/-menu-item.gts b/carbon-components-ember/src/components/ui-shell/-header/-menu-item.gts new file mode 100644 index 000000000..e893405a0 --- /dev/null +++ b/carbon-components-ember/src/components/ui-shell/-header/-menu-item.gts @@ -0,0 +1,30 @@ +import Component from '@glimmer/component'; + +export interface UIShellHeaderMenuItemSignature { + Element: HTMLAnchorElement; + Args: { + isActive?: boolean; + }; + Blocks: { + default: []; + }; +} + +export default class UIShellHeaderMenuItem extends Component { + +} diff --git a/carbon-components-ember/src/components/ui-shell/-header/-menu.gts b/carbon-components-ember/src/components/ui-shell/-header/-menu.gts new file mode 100644 index 000000000..d6193cc0b --- /dev/null +++ b/carbon-components-ember/src/components/ui-shell/-header/-menu.gts @@ -0,0 +1,55 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { on } from '@ember/modifier'; +import { ChevronDown } from '../../../icons.ts'; +import UIShellHeaderMenuItem from './-menu-item.gts'; + +export interface UIShellHeaderMenuSignature { + Element: HTMLLIElement; + Args: { + 'aria-label'?: string; + 'aria-labelledby'?: string; + menuLinkName: string; + isActive?: boolean; + }; + Blocks: { + default: [typeof UIShellHeaderMenuItem]; + }; +} + +export default class UIShellHeaderMenu extends Component { + @tracked expanded = false; + + toggleExpanded = () => { + this.expanded = !this.expanded; + }; + + +} diff --git a/carbon-components-ember/src/components/ui-shell/-header/-panel.gts b/carbon-components-ember/src/components/ui-shell/-header/-panel.gts new file mode 100644 index 000000000..69385f0f7 --- /dev/null +++ b/carbon-components-ember/src/components/ui-shell/-header/-panel.gts @@ -0,0 +1,32 @@ +import Component from '@glimmer/component'; +import { on } from '@ember/modifier'; + +export interface UIShellHeaderPanelSignature { + Element: HTMLDivElement; + Args: { + expanded?: boolean; + onToggle?: (value: boolean) => void; + }; + Blocks: { + default: []; + }; +} + +export default class UIShellHeaderPanel extends Component { + handleKeydown = (event: KeyboardEvent) => { + if (event.key === 'Escape') { + this.args.onToggle?.(false); + } + }; + + +} diff --git a/carbon-components-ember/src/components/ui-shell/-header/-side-nav-items.gts b/carbon-components-ember/src/components/ui-shell/-header/-side-nav-items.gts new file mode 100644 index 000000000..d24664173 --- /dev/null +++ b/carbon-components-ember/src/components/ui-shell/-header/-side-nav-items.gts @@ -0,0 +1,23 @@ +import Component from '@glimmer/component'; + +export interface UIShellHeaderSideNavItemsSignature { + Element: HTMLUListElement; + Args: { + hasDivider?: boolean; + }; + Blocks: { + default: []; + }; +} + +export default class UIShellHeaderSideNavItems extends Component { + +} diff --git a/carbon-components-ember/src/components/ui-shell/-nav.gts b/carbon-components-ember/src/components/ui-shell/-nav.gts index c7193bf78..f48b4bd40 100644 --- a/carbon-components-ember/src/components/ui-shell/-nav.gts +++ b/carbon-components-ember/src/components/ui-shell/-nav.gts @@ -1,10 +1,11 @@ import Component from '@glimmer/component'; import UIShellNavItem from '../../components/ui-shell/-nav/-item.gts'; +import UIShellHeaderMenu from '../../components/ui-shell/-header/-menu.gts'; export interface Signature { Element: null; Blocks: { - default: [typeof UIShellNavItem]; + default: [typeof UIShellNavItem, typeof UIShellHeaderMenu]; }; } @@ -12,7 +13,7 @@ export default class InnerClass extends Component { diff --git a/carbon-components-ember/src/components/ui-shell/-sidenav.gts b/carbon-components-ember/src/components/ui-shell/-sidenav.gts index 7b6ced226..714572ab0 100644 --- a/carbon-components-ember/src/components/ui-shell/-sidenav.gts +++ b/carbon-components-ember/src/components/ui-shell/-sidenav.gts @@ -4,6 +4,10 @@ import Component from '@glimmer/component'; import NavMenuComponent, { type SubMenu } from './-sidenav/-menu.gts'; import Divider from './-sidenav/-divider.gts'; import Footer from './-sidenav/-footer.gts'; +import SideNavHeader from './-sidenav/-header.gts'; +import SideNavDetails from './-sidenav/-details.gts'; +import SideNavIcon from './-sidenav/-icon.gts'; +import HeaderSideNavItems from './-header/-side-nav-items.gts'; import { fn } from '@ember/helper'; import { stylesheet } from 'astroturf'; import type Icon from '../icon'; @@ -22,7 +26,14 @@ export interface UIShellNavSignature { transitionTo: (menu: MenuItem | SubMenu) => void; }; Blocks: { - default: [typeof NavMenuComponent, typeof Divider]; + default: [ + typeof NavMenuComponent, + typeof Divider, + typeof SideNavHeader, + typeof SideNavDetails, + typeof SideNavIcon, + typeof HeaderSideNavItems, + ]; content: []; footer: [typeof Footer]; }; @@ -51,7 +62,7 @@ export default class UIShellNav extends Component { >