Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
headerTitle="Content title"
headerSubtitle="Subtitle"
>
<ix-icon-button icon="pen" variant="tertiary"> Button1 </ix-icon-button>
<ix-icon-button icon="trashcan" variant="tertiary">
<ix-icon-button icon="pen" variant="tertiary" slot="secondary-actions"> Button1 </ix-icon-button>
<ix-icon-button icon="trashcan" variant="tertiary" slot="secondary-actions">
Button2
</ix-icon-button>
<ix-icon-button icon="context-menu" variant="tertiary">
<ix-icon-button icon="context-menu" variant="tertiary" slot="secondary-actions">
Button3
</ix-icon-button>
</ix-content-header>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
header-subtitle="Subtitle"
>
<ix-pill slot="header" icon="info" class="margin-top">Label</ix-pill>
<ix-button variant="tertiary">Button1</ix-button>
<ix-button variant="tertiary">Button2</ix-button>
<ix-button variant="tertiary">Button3</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button1</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button2</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button3</ix-button>
<ix-button variant="primary">Important</ix-button>
</ix-content-header>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
headerTitle="Content title"
headerSubtitle="Subtitle"
>
<ix-button variant="tertiary">Button1</ix-button>
<ix-button variant="tertiary">Button2</ix-button>
<ix-button variant="tertiary">Button3</ix-button>
<ix-button variant="tertiary" slot="secondary-actions">Button1</ix-button>
<ix-button variant="tertiary" slot="secondary-actions">Button2</ix-button>
<ix-button variant="tertiary" slot="secondary-actions">Button3</ix-button>
</ix-content-header>
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
headerTitle="Content title"
headerSubtitle="Subtitle"
>
<ix-icon-button icon="pen" variant="tertiary"> Button1 </ix-icon-button>
<ix-icon-button icon="trashcan" variant="tertiary">
<ix-icon-button icon="pen" variant="tertiary" slot="secondary-actions"> Button1 </ix-icon-button>
<ix-icon-button icon="trashcan" variant="tertiary" slot="secondary-actions">
Button2
</ix-icon-button>
<ix-icon-button icon="context-menu" variant="tertiary">
<ix-icon-button icon="context-menu" variant="tertiary" slot="secondary-actions">
Button3
</ix-icon-button>
</ix-content-header>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
header-subtitle="Subtitle"
>
<ix-pill slot="header" icon="info" class="margin-top">Label</ix-pill>
<ix-button variant="tertiary">Button1</ix-button>
<ix-button variant="tertiary">Button2</ix-button>
<ix-button variant="tertiary">Button3</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button1</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button2</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button3</ix-button>
<ix-button variant="primary">Important</ix-button>
</ix-content-header>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
headerTitle="Content title"
headerSubtitle="Subtitle"
>
<ix-button variant="tertiary">Button1</ix-button>
<ix-button variant="tertiary">Button2</ix-button>
<ix-button variant="tertiary">Button3</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button1</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button2</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button3</ix-button>
</ix-content-header>
15 changes: 7 additions & 8 deletions packages/core/src/components/button/button-mixin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,12 @@
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;

overflow: hidden;

align-items: center;
justify-content: center;

width: 100%;
height: 100%;

overflow: var(--ix-button-inner-overflow, hidden);
padding: var(--ix-button-padding, 0 0.5rem);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

Expand All @@ -112,7 +109,8 @@
--ix-button-border-radius-right: var(--theme-btn--border-radius);

display: inline-block;
height: 2rem;
height: var(--ix-button-height, 2rem);
min-height: var(--ix-button-min-height, 2rem);
vertical-align: middle;
cursor: pointer;

Expand All @@ -131,9 +129,10 @@
.content {
display: inline-block;
position: relative;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
overflow: var(--ix-button-content-overflow, hidden);
white-space: var(--ix-button-text-white-space, nowrap);
text-overflow: var(--ix-button-content-text-overflow, ellipsis);
word-break: var(--ix-button-word-break, normal);
}

.content-start {
Expand Down
19 changes: 16 additions & 3 deletions packages/core/src/components/content-header/content-header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
flex-direction: column;
flex: 1 1 0;
min-width: 0;
white-space: nowrap;
margin-right: 0.5rem;

.titleOverflow {
overflow: hidden;
text-overflow: ellipsis;
overflow-wrap: break-word;
}

.headerTitleRow {
Expand Down Expand Up @@ -51,4 +49,19 @@
.buttons {
flex: 0 0 auto;
}

.actions {
flex: 0 0 auto;
display: flex;
flex-wrap: wrap;
align-items: center;

::slotted([slot='secondary-actions']) {
--ix-button-height: 2rem;
--ix-button-text-white-space: normal;
--ix-button-word-break: break-word;
--ix-button-inner-overflow: visible;
--ix-button-content-overflow: visible;
}
}
}
123 changes: 114 additions & 9 deletions packages/core/src/components/content-header/content-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,34 @@
* LICENSE file in the root directory of this source tree.
*/

import { iconArrowLeft } from '@siemens/ix-icons/icons';
import { Component, Event, EventEmitter, h, Host, Prop } from '@stencil/core';
import { iconArrowLeft, iconMoreMenu } from '@siemens/ix-icons/icons';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for changeset files related to content-header
fd -e md . .changeset/ --exec grep -l 'content-header' {} \; || echo "No changeset found for content-header"

Repository: siemens/ix

Length of output: 92


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .changeset files (names) =="
ls -1 .changeset 2>/dev/null || echo "(no .changeset dir)"

echo
echo "== Search for content-header / ContentHeader in .changeset =="
rg -n --no-heading "content-header|ContentHeader" .changeset || echo "No matches."

echo
echo "== Search for likely keywords in .changeset =="
rg -n --no-heading "dropdown|responsive|secondary actions|secondary actions|more menu|small viewport" .changeset || echo "No matches."

Repository: siemens/ix

Length of output: 354


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .changeset markdown files =="
fd -e md . .changeset --exec basename {} \; | sort | uniq

echo
echo "== Search all changesets for broader terms =="
for pat in "content" "header" "dropdown" "responsive" "secondary" "menu"; do
  echo "--- pattern: $pat ---"
  rg -n --no-heading "$pat" .changeset --glob '*.md' || echo "No matches for $pat"
  echo
done

Repository: siemens/ix

Length of output: 708


Add a changeset for the ContentHeader responsive + dropdown behavior
No .changeset/*.md entry exists for content-header/responsive/dropdown/secondary actions (only an unrelated modal-header-long-title changeset is present). Add a changeset in .changeset/ with scope @siemens/ix, the appropriate release type, and a summary of the new responsive secondary actions + dropdown pattern. Include migration guidance if this is a breaking behavior change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/components/content-header/content-header.tsx` at line 10,
Add a new changeset markdown file under .changeset that covers the ContentHeader
responsive secondary actions + dropdown pattern: set the scope to "`@siemens/ix`",
pick the appropriate release type (minor for new non-breaking feature, major if
it changes behavior), and write a short summary describing the responsive +
dropdown behavior for ContentHeader (mention "responsive secondary actions" and
"dropdown pattern"); if the change is breaking, include explicit migration
guidance for consumers (what to update in ContentHeader usage and props). Ensure
the changeset references the content-header/responsive/dropdown/secondary
actions change so it will trigger a release.

Source: Coding guidelines

import {
Component,
Element,
Event,
EventEmitter,
h,
Host,
Prop,
State,
} from '@stencil/core';
import type { ContentHeaderVariant } from './content-header.types';

const SMALL_BREAKPOINT_QUERY = '(max-width: 48em)';

/**
* @slot header - Content to be placed in the header area next to the title
* @slot - Default slot for action buttons or other content
* @slot secondary-actions - Secondary action buttons that collapse into the overflow menu on small viewports
* @slot - Default slot for primary content that remains visible at all viewport sizes
*/
@Component({
tag: 'ix-content-header',
styleUrl: 'content-header.scss',
shadow: true,
})
export class ContentHeader {
@Element() hostElement!: HTMLIxContentHeaderElement;

/**
* Variant of content header
*/
Expand All @@ -46,12 +60,85 @@ export class ContentHeader {
*/
@Event() backButtonClick!: EventEmitter<void>;

@State() isSmallBreakpoint = false;
@State() hasSecondaryActions = false;

mediaQuery?: MediaQueryList;
hasDisconnected = false;
secondarySlot: HTMLSlotElement | null = null;

readonly mediaQueryHandler = (e: MediaQueryListEvent) => {
this.isSmallBreakpoint = e.matches;
};

readonly slotChangeHandler = () => this.checkSecondarySlot();

checkSecondarySlot() {
this.hasSecondaryActions = Array.from(this.hostElement.childNodes).some(
(node) => {
if (node.nodeType === Node.TEXT_NODE) {
return false;
}
return (node as Element).getAttribute?.('slot') === 'secondary-actions';
}
);
}

componentWillLoad() {
if (globalThis.window !== undefined) {
this.mediaQuery = globalThis.window.matchMedia(SMALL_BREAKPOINT_QUERY);
this.isSmallBreakpoint = this.mediaQuery.matches;
this.mediaQuery.addEventListener('change', this.mediaQueryHandler);
}
}

componentDidLoad() {
this.checkSecondarySlot();

const slot = this.hostElement.shadowRoot?.querySelector(
'slot[name="secondary-actions"]'
) as HTMLSlotElement | null;

if (slot) {
this.secondarySlot = slot;
slot.addEventListener('slotchange', this.slotChangeHandler);
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

connectedCallback() {
if (this.hasDisconnected && globalThis.window !== undefined) {
this.mediaQuery = globalThis.window.matchMedia(SMALL_BREAKPOINT_QUERY);
this.isSmallBreakpoint = this.mediaQuery.matches;
this.mediaQuery.addEventListener('change', this.mediaQueryHandler);

const slot = this.hostElement.shadowRoot?.querySelector(
'slot[name="secondary-actions"]'
) as HTMLSlotElement | null;

if (slot) {
this.secondarySlot = slot;
slot.addEventListener('slotchange', this.slotChangeHandler);
}
}
}

disconnectedCallback() {
if (this.mediaQuery) {
this.mediaQuery.removeEventListener('change', this.mediaQueryHandler);
}
this.secondarySlot?.removeEventListener(
'slotchange',
this.slotChangeHandler
);
this.hasDisconnected = true;
}

render() {
return (
<Host>
{this.hasBackButton ? (
<ix-icon-button
class={'backButton'}
class="backButton"
variant="tertiary"
icon={iconArrowLeft}
onClick={() => this.backButtonClick.emit()}
Expand All @@ -75,8 +162,8 @@ export class ContentHeader {
</div>
{!!this.headerSubtitle && (
<ix-typography
format={'h6'}
text-color={'soft'}
format="h6"
text-color="soft"
class={{
subtitle: this.variant === 'secondary',
titleOverflow: true,
Expand All @@ -87,9 +174,27 @@ export class ContentHeader {
</ix-typography>
)}
</div>
<div class="buttons">
<slot />
</div>

{this.isSmallBreakpoint ? (
<div class="actions">
<slot />
{this.hasSecondaryActions && (
<ix-dropdown-button
icon={iconMoreMenu}
variant="tertiary"
label=""
aria-label="More actions"
>
<slot name="secondary-actions" />
</ix-dropdown-button>
)}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
</div>
) : (
<div class="actions">
<slot name="secondary-actions" />
<slot />
</div>
)}
</Host>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
header-title="Content title"
header-subtitle="Subtitle"
>
<ix-icon-button icon="pen" variant="tertiary">
<ix-icon-button icon="pen" variant="tertiary" slot="secondary-actions">
Button1
</ix-icon-button>
<ix-icon-button icon="trashcan" variant="tertiary">
<ix-icon-button icon="trashcan" variant="tertiary" slot="secondary-actions">
Button2
</ix-icon-button>
<ix-icon-button icon="context-menu" variant="tertiary">
<ix-icon-button icon="context-menu" variant="tertiary" slot="secondary-actions">
Button3
</ix-icon-button>
</ix-content-header>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@
header-subtitle="Subtitle"
>
<ix-pill slot="header" icon="info" class="margin-top">Label</ix-pill>
<ix-button variant="tertiary">Button1</ix-button>
<ix-button variant="tertiary">Button2</ix-button>
<ix-button variant="tertiary">Button3</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button1</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button2</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button3</ix-button>
<ix-button variant="primary">Important</ix-button>
</ix-content-header>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
header-title="Content title"
header-subtitle="Subtitle"
>
<ix-button variant="tertiary">Button1</ix-button>
<ix-button variant="tertiary">Button2</ix-button>
<ix-button variant="tertiary">Button3</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button1</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button2</ix-button>
<ix-button slot="secondary-actions" variant="tertiary">Button3</ix-button>
</ix-content-header>
<script type="module" src="./init.js"></script>
</body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export default () => {
header-title="Content title"
header-subtitle="Subtitle"
>
<IxIconButton icon={iconPen} variant="tertiary">
<IxIconButton icon={iconPen} variant="tertiary" slot="secondary-actions">
Button1
</IxIconButton>
<IxIconButton icon={iconTrashcan} variant="tertiary">
<IxIconButton icon={iconTrashcan} variant="tertiary" slot="secondary-actions">
Button2
</IxIconButton>
<IxIconButton icon={iconContextMenu} variant="tertiary">
<IxIconButton icon={iconContextMenu} variant="tertiary" slot="secondary-actions">
Button3
</IxIconButton>
</IxContentHeader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ export default () => {
<IxPill slot="header" icon={iconInfo} className="margin-top">
Label
</IxPill>
<IxButton variant='tertiary'>Button1</IxButton>
<IxButton variant='tertiary'>Button2</IxButton>
<IxButton variant='tertiary'>Button3</IxButton>
<IxButton slot='secondary-actions' variant='tertiary'>Button1</IxButton>
<IxButton slot='secondary-actions' variant='tertiary'>Button2</IxButton>
<IxButton slot='secondary-actions' variant='tertiary'>Button3</IxButton>
<IxButton variant='primary'>Important</IxButton>
</IxContentHeader>
);
};
Loading
Loading