Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sbb-icon-list styles #3038

Merged
merged 10 commits into from
Sep 25, 2024
2 changes: 1 addition & 1 deletion src/elements/_index.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
@forward 'core/styles' hide development-style, link-base, link-focus-visible, link-hover,
link-active, link-consolidation;
link-active, link-consolidation, base-marker-list;
4 changes: 4 additions & 0 deletions src/elements/core/styles/lists.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@
.sbb-step-list {
@include lists.step-list;
}

.sbb-icon-list {
@include lists.icon-list;
}
204 changes: 128 additions & 76 deletions src/elements/core/styles/mixins/lists.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,90 +76,77 @@
}
MarioCastigliano marked this conversation as resolved.
Show resolved Hide resolved
}

@mixin step-list {
--sbb-step-list-marker-dimensions: #{functions.px-to-rem-build(34)};
--sbb-step-list-padding-block: var(--sbb-spacing-fixed-3x);
--sbb-step-list-padding-inline: var(--sbb-spacing-responsive-xxs);
--sbb-step-list-marker-to-text-gap: var(--sbb-spacing-responsive-xxxs);
--sbb-step-list-border-radius: var(--sbb-border-radius-4x);

// Additional space from overall li padding to the text because text
// has to be centered to marker number.
--sbb-step-list-text-to-marker-block-offset: calc(
0.5 *
(
var(--sbb-step-list-marker-dimensions) - var(--sbb-typo-line-height-body-text) *
var(--sbb-text-font-size)
)
);
--sbb-step-list-vertical-gap: var(--sbb-spacing-fixed-1x);
@mixin description-list {
// Support both top level usage (& is empty / falsy)
// and applied to a selector usage.
#{if(&, '&:where(dl)', 'dl')} {
@include typo.text-s--regular;

list-style: none;
margin: 0;
padding: 0;
counter-reset: steps;
margin: 0;
padding: 0;
display: grid;

&:where(.sbb-text-s) {
--sbb-step-list-padding-block: var(--sbb-spacing-fixed-4x);
// Ensure that description is always attached to the label
grid-template-columns: auto minmax(20%, 1fr);
gap: var(--sbb-spacing-fixed-1x) var(--sbb-spacing-fixed-2x);
color: var(--sbb-color-iron);

:is(dt, dd) {
margin: 0;
padding: 0;
}
}
}

&:where(.sbb-text-m, .sbb-text-l, .sbb-text-xl) {
--sbb-step-list-padding-block: var(--sbb-spacing-fixed-5x);
@mixin base-marker-list(
$dimensions,
$padding-inline,
$to-text-gap,
$vertical-gap,
$text-to-marker-block-offset
) {
& {
#{$dimensions}: #{functions.px-to-rem-build(34)};
#{$padding-inline}: var(--sbb-spacing-responsive-xxs);
#{$to-text-gap}: var(--sbb-spacing-responsive-xxxs);

// Additional space from overall li padding to the text because text
// has to be centered to marker number.
#{$text-to-marker-block-offset}: calc(
0.5 *
(var(#{$dimensions}) - var(--sbb-typo-line-height-body-text) * var(--sbb-text-font-size))
);
list-style: none;
margin: 0;
padding: 0;
}

&:where(.sbb-text-xl) {
@include mediaqueries.mq($from: medium) {
--sbb-step-list-marker-dimensions: #{functions.px-to-rem-build(41)};
#{$dimensions}: #{functions.px-to-rem-build(41)};
}
}

/* stylelint-disable-next-line no-descending-specificity */
> li {
position: relative;
counter-increment: steps;
background-color: var(--sbb-color-milk);
padding-block: calc(
var(--sbb-step-list-padding-block) + var(--sbb-step-list-text-to-marker-block-offset)
)
var(--sbb-step-list-padding-block);
padding-inline: calc(
var(--sbb-step-list-padding-inline) + var(--sbb-step-list-marker-dimensions) +
var(--sbb-step-list-marker-to-text-gap)
)
var(--sbb-step-list-padding-inline);
min-height: calc(
var(--sbb-step-list-marker-dimensions) + 2 * var(--sbb-step-list-padding-block)
);

&:first-of-type {
border-start-start-radius: var(--sbb-step-list-border-radius);
border-start-end-radius: var(--sbb-step-list-border-radius);
}

&:last-of-type {
border-end-start-radius: var(--sbb-step-list-border-radius);
border-end-end-radius: var(--sbb-step-list-border-radius);
}
padding-inline: calc(var(#{$padding-inline}) + var(#{$dimensions}) + var(#{$to-text-gap}))
var(#{$padding-inline});
min-height: var(#{$dimensions});

&::before {
@include typo.text-xxs--bold;

content: counter(steps);
position: absolute;
display: flex;
align-items: center;
justify-content: center;
height: var(--sbb-step-list-marker-dimensions);
width: var(--sbb-step-list-marker-dimensions);
margin-block-start: calc(-1 * var(--sbb-step-list-text-to-marker-block-offset));
inset-inline-start: var(--sbb-step-list-padding-inline);
border: var(--sbb-border-width-1x) solid var(--sbb-color-cement);
height: var(#{$dimensions});
width: var(#{$dimensions});
margin-block-start: calc(-1 * var(#{$text-to-marker-block-offset}));
inset-inline-start: var(#{$padding-inline});
border-radius: 50%;
color: var(--sbb-color-charcoal);
}

+ li {
margin-block-start: var(--sbb-step-list-vertical-gap);
margin-block-start: var(#{$vertical-gap});
}

p {
Expand All @@ -173,24 +160,89 @@
}
}

@mixin description-list {
// Support both top level usage (& is empty / falsy)
// and applied to a selector usage.
#{if(&, '&:where(dl)', 'dl')} {
@include typo.text-s--regular;
@mixin icon-list {
@include base-marker-list(
$dimensions: '--sbb-icon-list-dimensions',
$padding-inline: '--sbb-icon-list-padding-inline',
$to-text-gap: '--sbb-icon-list-to-text-gap',
$vertical-gap: '--sbb-icon-list-vertical-gap',
$text-to-marker-block-offset: '--sbb-icon-list-text-to-marker-block-offset'
);

margin: 0;
padding: 0;
display: grid;
& {
--sbb-icon-list-marker-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="%23000" fill-rule="evenodd" d="M3 12a9 9 0 0 1 9-9 9 9 0 0 1 9 9 9 9 0 0 1-9 9 9 9 0 0 1-9-9m9-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2m-1.104 13.305 5-6.5-.792-.61-4.69 6.096-2.102-1.681-.624.78 2.5 2 .398.319z" clip-rule="evenodd"></path></svg>');
--sbb-icon-list-marker-icon-color: currentcolor;
--sbb-icon-list-vertical-gap: var(--sbb-spacing-fixed-2x);
--sbb-icon-list-dimensions: var(--sbb-size-icon-ui-small);
--sbb-icon-list-to-text-gap: var(--sbb-spacing-fixed-2x);
}

// Ensure that description is always attached to the label
grid-template-columns: auto minmax(20%, 1fr);
gap: var(--sbb-spacing-fixed-1x) var(--sbb-spacing-fixed-2x);
color: var(--sbb-color-iron);
> li::before {
content: '';
background-color: var(--sbb-icon-list-marker-icon-color);
mask-image: var(--sbb-icon-list-marker-icon);
mask-repeat: no-repeat;
mask-position: center;
mask-size: 100%;
}
}

:is(dt, dd) {
margin: 0;
padding: 0;
@mixin step-list {
@include base-marker-list(
$dimensions: '--sbb-step-list-dimensions',
$padding-inline: '--sbb-step-list-padding-inline',
$to-text-gap: '--sbb-step-list-to-text-gap',
$vertical-gap: '--sbb-step-list-vertical-gap',
$text-to-marker-block-offset: '--sbb-step-list-text-to-marker-block-offset'
);

& {
--sbb-step-list-padding-block: var(--sbb-spacing-fixed-3x);
--sbb-step-list-vertical-gap: var(--sbb-spacing-fixed-1x);
--sbb-step-list-border-radius: var(--sbb-border-radius-4x);

counter-reset: steps;
}

&:where(.sbb-text-s) {
--sbb-step-list-padding-block: var(--sbb-spacing-fixed-4x);
}

&:where(.sbb-text-m, .sbb-text-l, .sbb-text-xl) {
--sbb-step-list-padding-block: var(--sbb-spacing-fixed-5x);
}

> li {
counter-increment: steps;
background-color: var(--sbb-color-milk);
padding-block: calc(
var(--sbb-step-list-padding-block) + var(--sbb-step-list-text-to-marker-block-offset)
)
var(--sbb-step-list-padding-block);
padding-inline: calc(
var(--sbb-step-list-padding-inline) + var(--sbb-step-list-dimensions) +
var(--sbb-step-list-to-text-gap)
)
var(--sbb-step-list-padding-inline);
min-height: calc(var(--sbb-step-list-dimensions) + 2 * var(--sbb-step-list-padding-block));

&::before {
content: counter(steps);
display: flex;
align-items: center;
justify-content: center;
border: var(--sbb-border-width-1x) solid var(--sbb-color-cement);
color: var(--sbb-color-charcoal);
}

&:first-of-type {
border-start-start-radius: var(--sbb-step-list-border-radius);
border-start-end-radius: var(--sbb-step-list-border-radius);
}

&:last-of-type {
border-end-start-radius: var(--sbb-step-list-border-radius);
border-end-end-radius: var(--sbb-step-list-border-radius);
}
}
}
70 changes: 68 additions & 2 deletions src/storybook/styles/list/list.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const OrderedListTemplate = (): TemplateResult => html`
)}
`;

const StepsTemplate = (): TemplateResult => html`
const StepListTemplate = (): TemplateResult => html`
${['xs', 's', 'm', 'l', 'xl'].map(
(textSize) => html`
<sbb-title level="5">Text size ${textSize}</sbb-title>
Expand All @@ -66,6 +66,60 @@ const StepsTemplate = (): TemplateResult => html`
)}
`;

const IconListTemplate = (): TemplateResult => html`
${['xs', 's', 'm', 'l', 'xl'].map(
(textSize) => html`
<sbb-title level="5">Text size ${textSize}</sbb-title>
<ol class=${`sbb-icon-list sbb-text-${textSize}`}>
${ListContent()}
<li>
Nested list
<ol class="sbb-list">
${ListContent()}
</ol>
</li>
</ol>
`,
)}
`;

const IconListCustomIconTemplate = (): TemplateResult => html`
${['xs', 's', 'm', 'l', 'xl'].map(
(textSize) => html`
<sbb-title level="5">Text size ${textSize}</sbb-title>
<ol
class=${`sbb-icon-list sbb-text-${textSize}`}
style="--sbb-icon-list-marker-icon-color: var(--sbb-color-red); --sbb-icon-list-marker-icon: url('https://icons.app.sbb.ch/icons/circle-cross-small.svg')"
>
${ListContent()}
<li>
Nested list
<ol class="sbb-list">
${ListContent()}
</ol>
</li>
</ol>
`,
)}
`;

const IconListCustomColorTemplate = (): TemplateResult => html`
${['xs', 's', 'm', 'l', 'xl'].map(
(textSize) => html`
<sbb-title level="5">Text size ${textSize}</sbb-title>
<ol class=${`sbb-icon-list sbb-text-${textSize}`} style="color: var(--sbb-color-green);">
${ListContent()}
<li>
Nested list
<ol class="sbb-list">
${ListContent()}
</ol>
</li>
</ol>
`,
)}
`;

const DescriptionListTemplate = (): TemplateResult => html`
<dl class="sbb-list">
<dt>Label:</dt>
Expand Down Expand Up @@ -93,7 +147,19 @@ export const OrderedList: StoryObj = {
};

export const StepList: StoryObj = {
render: StepsTemplate,
render: StepListTemplate,
};

export const IconList: StoryObj = {
render: IconListTemplate,
};

export const IconListCustomIcon: StoryObj = {
render: IconListCustomIconTemplate,
};

export const IconListCustomColor: StoryObj = {
render: IconListCustomColorTemplate,
};

export const DescriptionList: StoryObj = {
Expand Down
Loading
Loading