Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0ebffe9
feat(segmented-button): add icon and text support
hugomslv May 14, 2025
65d214b
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv May 21, 2025
5097b34
chore(segmented-button): apply changes requested in PR review
hugomslv Jun 4, 2025
448ac1e
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Jun 4, 2025
98a8862
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Jun 4, 2025
bcb6990
Merge branch '5154-segmented-button-enhancement' of https://github.co…
hugomslv Jun 4, 2025
30f316c
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Jun 11, 2025
593b841
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Jul 7, 2025
b7c5032
fix PR comments
hugomslv Jul 7, 2025
7b17665
Merge branch '5154-segmented-button-enhancement' of https://github.co…
hugomslv Jul 7, 2025
502991d
Update from main and modify pnpm-lock.yaml
hugomslv Aug 7, 2025
982efac
Delete _post-icon-version.scss
hugomslv Aug 8, 2025
dafe1fe
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Aug 18, 2025
9f5234c
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Aug 26, 2025
f7b132b
fix comments
hugomslv Aug 26, 2025
aabe4bf
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Aug 26, 2025
8061270
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Sep 2, 2025
81ef193
Update .changeset/stale-days-smoke.md
hugomslv Sep 9, 2025
ddfdeea
Update packages/documentation/src/stories/components/segmented-button…
hugomslv Sep 9, 2025
8967ac3
Merge branch 'main' into 5154-segmented-button-enhancement
hugomslv Sep 9, 2025
8b40d61
fix comments
hugomslv Sep 9, 2025
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
6 changes: 6 additions & 0 deletions .changeset/stale-days-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@swisspost/design-system-documentation': minor
'@swisspost/design-system-styles': minor
---

Enabled having icons in the segmented button.
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,21 @@ It allows users to toggle between two or more content sections within the same a
overflowing or word breaks.
</post-banner>

<Canvas of={SegmentedButtonStories.TextExample} sourceState="shown" />
<Controls of={SegmentedButtonStories.TextExample} />
<Canvas of={SegmentedButtonStories.Default} sourceState="shown" />
<Controls of={SegmentedButtonStories.Default} />

<StylesPackageImport components={['segmented-button']} />

## Segmented icon button

<Canvas of={SegmentedButtonStories.IconExample} sourceState="shown" />
<Controls of={SegmentedButtonStories.IconExample} />
Use only an icon for quick recognition when text is not needed.

<Canvas of={SegmentedButtonStories.Icon} />

## Segmented text and icon button

Combine label and icon with quick visual recognition. Useful when options benefit from both wording and imagery.

<Canvas of={SegmentedButtonStories.TextAndIcon} />


<StylesPackageImport components={['segmented-button']} />
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ export const SegmentedButton: Story = {
`,
)}
</fieldset>
<fieldset class="segmented-button">
${labels.map(
(label, index) => html`
<label class="segmented-button-label">
<input type="radio" name="text-icon-${count}-${scheme}" />
<post-icon name="${1000 + index}"></post-icon>
${label}
</label>
`,
)}
</fieldset>
</div>
`;
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Args, StoryObj } from '@storybook/web-components-vite';
import type { Args, StoryObj } from '@storybook/web-components-vite';
import { html, nothing } from 'lit';
import { MetaComponent } from '@root/types';
import type { MetaComponent } from '@root/types';

const MAX_LABELS = 8;

Expand All @@ -17,36 +17,48 @@ const meta: MetaComponent = {
},
args: {
labelCount: 4,
mode: 'text',
},
argTypes: {
labelCount: {
name: 'Number of segments',
description: `Defines the number of segments for the segmented button. The maximum number of supported segments is 8. If you need more options, please refer to the select component.`,
description:
'Defines the number of segments for the segmented button. The maximum number of supported segments is 8. If you need more options, please refer to the select component.',
control: { type: 'number', min: 1, max: MAX_LABELS },
table: { category: 'Content' },
},
mode: {
name: 'Content type',
description: 'Defines the type of content displayed in the buttons.',
control: { type: 'inline-radio' },
options: ['Text only', 'Icons only', 'Text and icons'],
table: { category: 'Content' },
},
},
};

export default meta;

type Story = StoryObj;

export const TextExample: Story = {
export const Default: Story = {
render: (args: Args) => {
const mode = args.mode || 'Text only';
const labelCount = Math.min(args.labelCount || 0, MAX_LABELS);
const labelsArray = Array.from({ length: labelCount }, (_, i) => `Label ${i + 1}`);
const name = `segmented-button-${Math.random().toString(36).slice(-6)}`;
const labels = Array.from({ length: labelCount }, (_, i) => `Label ${i + 1}`);
const name = `segmented-button-${crypto.randomUUID().replace(/-/g, '').slice(-6)}`;

return html`
<div class="segmented-button-container">
<fieldset class="segmented-button">
<legend>Choose one of the options</legend>
${labelsArray.map(
${labels.map(
(label, index) => html`
<label class="segmented-button-label">
<input name="${name}" type="radio" checked="${index === 0 ? '' : nothing}" />
${label}
<input type="radio" name="${name}" ?checked=${index === 0} />
${mode === 'Icons only'
? html`<span class="visually-hidden">${label}</span>`
: nothing}
${mode === 'Icons only"' || mode === 'Text and icons'
? html`<post-icon name="${1000 + index}"></post-icon>`
: nothing}
${mode === 'Text only' || mode === 'Text and icons' ? label : nothing}
</label>
`,
)}
Expand All @@ -56,26 +68,14 @@ export const TextExample: Story = {
},
};

export const IconExample: Story = {
render: (args: Args) => {
const labelCount = Math.min(args.labelCount || 0, MAX_LABELS);
const name = `segmented-button-${Math.random().toString(36).slice(-6)}`;
export default meta;

return html`
<div class="segmented-button-container">
<fieldset class="segmented-button">
<legend>Choose one of the options</legend>
${Array.from(
{ length: labelCount },
(_undefined, index) => html`
<label class="segmented-button-label">
<input type="radio" name="${name}" checked="${index === 0 ? '' : nothing}" />
<post-icon name="${1000 + index}" />
</label>
`,
)}
</fieldset>
</div>
`;
},
type Story = StoryObj;

export const Icon: Story = {
args: { mode: 'Icons only' },
};

export const TextAndIcon: Story = {
args: { mode: 'Text and icons' },
};
1 change: 1 addition & 0 deletions packages/styles/src/components/segmented-button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ $post-segmented-button-max-count: 8;
label {
flex: 0 1 100%;
display: flex;
gap: tokens.get('button-segmented-gap-inline');
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like the gap token is incorrect. Can you please check with @sandra-post?

justify-content: center;
align-items: center;
position: relative;
Expand Down