-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sbb-stepper): introduce
sbb-stepper
component (#2491)
--------- Co-authored-by: Tommmaso Menga <[email protected]> Co-authored-by: Davide Mininni <[email protected]>
- Loading branch information
1 parent
2059719
commit d389572
Showing
30 changed files
with
2,758 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './stepper/step.js'; | ||
export * from './stepper/step-label.js'; | ||
export * from './stepper/stepper.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './step-label/step-label.js'; |
132 changes: 132 additions & 0 deletions
132
src/elements/stepper/step-label/__snapshots__/step-label.spec.snap.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* @web/test-runner snapshot v1 */ | ||
export const snapshots = {}; | ||
|
||
snapshots["sbb-step-label renders DOM"] = | ||
`<sbb-step-label | ||
data-action="" | ||
data-button="" | ||
dir="ltr" | ||
id="sbb-step-label-0" | ||
role="tab" | ||
slot="step-label" | ||
tabindex="-1" | ||
> | ||
Label | ||
</sbb-step-label> | ||
`; | ||
/* end snapshot sbb-step-label renders DOM */ | ||
|
||
snapshots["sbb-step-label renders Shadow DOM"] = | ||
`<div class="sbb-step-label"> | ||
<span class="sbb-step-label__prefix"> | ||
<slot name="icon"> | ||
</slot> | ||
</span> | ||
<span class="sbb-step-label__text"> | ||
<slot> | ||
</slot> | ||
</span> | ||
</div> | ||
`; | ||
/* end snapshot sbb-step-label renders Shadow DOM */ | ||
|
||
snapshots["sbb-step-label renders with icon DOM"] = | ||
`<sbb-step-label | ||
data-action="" | ||
data-button="" | ||
dir="ltr" | ||
icon-name="tick-small" | ||
id="sbb-step-label-2" | ||
role="tab" | ||
slot="step-label" | ||
tabindex="-1" | ||
> | ||
Label | ||
</sbb-step-label> | ||
`; | ||
/* end snapshot sbb-step-label renders with icon DOM */ | ||
|
||
snapshots["sbb-step-label renders with icon Shadow DOM"] = | ||
`<div class="sbb-step-label"> | ||
<span class="sbb-step-label__prefix"> | ||
<slot name="icon"> | ||
<sbb-icon | ||
aria-hidden="true" | ||
data-namespace="default" | ||
name="tick-small" | ||
role="img" | ||
> | ||
</sbb-icon> | ||
</slot> | ||
</span> | ||
<span class="sbb-step-label__text"> | ||
<slot> | ||
</slot> | ||
</span> | ||
</div> | ||
`; | ||
/* end snapshot sbb-step-label renders with icon Shadow DOM */ | ||
|
||
snapshots["sbb-step-label renders disabled DOM"] = | ||
`<sbb-step-label | ||
data-action="" | ||
data-button="" | ||
data-disabled="" | ||
dir="ltr" | ||
disabled="" | ||
id="sbb-step-label-4" | ||
role="tab" | ||
slot="step-label" | ||
tabindex="-1" | ||
> | ||
Label | ||
</sbb-step-label> | ||
`; | ||
/* end snapshot sbb-step-label renders disabled DOM */ | ||
|
||
snapshots["sbb-step-label renders disabled Shadow DOM"] = | ||
`<div class="sbb-step-label"> | ||
<span class="sbb-step-label__prefix"> | ||
<slot name="icon"> | ||
</slot> | ||
</span> | ||
<span class="sbb-step-label__text"> | ||
<slot> | ||
</slot> | ||
</span> | ||
</div> | ||
`; | ||
/* end snapshot sbb-step-label renders disabled Shadow DOM */ | ||
|
||
snapshots["sbb-step-label A11y tree Chrome"] = | ||
`<p> | ||
{ | ||
"role": "WebArea", | ||
"name": "", | ||
"children": [ | ||
{ | ||
"role": "tab", | ||
"name": "Label" | ||
} | ||
] | ||
} | ||
</p> | ||
`; | ||
/* end snapshot sbb-step-label A11y tree Chrome */ | ||
|
||
snapshots["sbb-step-label A11y tree Firefox"] = | ||
`<p> | ||
{ | ||
"role": "document", | ||
"name": "", | ||
"children": [ | ||
{ | ||
"role": "tab", | ||
"name": "Label" | ||
} | ||
] | ||
} | ||
</p> | ||
`; | ||
/* end snapshot sbb-step-label A11y tree Firefox */ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
Use the `sbb-step-label` with the `sbb-stepper` to display a step label. | ||
|
||
```html | ||
<sbb-step-label>Step label</sbb-step-label> | ||
``` | ||
|
||
## Slots | ||
|
||
It has an implicit slot named `step-label`. | ||
|
||
## States | ||
|
||
The component can be displayed in `disabled` state using the self-named property. | ||
|
||
```html | ||
<sbb-step-label disabled>Step label</sbb-step-label> | ||
``` | ||
|
||
## Style | ||
|
||
If it is used in an `sbb-stepper` and no `icon-name` is specified, it displays a counter in the label prefix to keep track of the step number. | ||
|
||
```html | ||
<!-- Displays a tick icon in the prefix circle --> | ||
<sbb-step-label icon-name="tick-small">Step label</sbb-step-label> | ||
|
||
<!-- Displays a number in the prefix circle --> | ||
<sbb-step-label>Step label</sbb-step-label> | ||
``` | ||
|
||
## Accessibility | ||
|
||
The accessibility properties `aria-controls`, `aria-setsize`, `aria-posinset` are set automatically. | ||
|
||
<!-- Auto Generated Below --> | ||
|
||
## Properties | ||
|
||
| Name | Attribute | Privacy | Type | Default | Description | | ||
| ---------- | ----------- | ------- | ------------------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------- | | ||
| `disabled` | `disabled` | public | `boolean` | `false` | Whether the component is disabled. | | ||
| `form` | `form` | public | `string \| undefined` | | The <form> element to associate the button with. | | ||
| `iconName` | `icon-name` | public | `string \| undefined` | | The icon name we want to use, choose from the small icon variants from the ui-icons category from here https://icons.app.sbb.ch. | | ||
| `name` | `name` | public | `string` | | The name of the button element. | | ||
| `step` | - | public | `SbbStepElement \| null` | `null` | The step controlled by the label. | | ||
| `type` | `type` | public | `SbbButtonType` | `'button'` | The type attribute to use for the button. | | ||
| `value` | `value` | public | `string` | | The value of the button element. | | ||
|
||
## Slots | ||
|
||
| Name | Description | | ||
| ------ | ------------------------------------------------ | | ||
| | Use the unnamed slot to provide a label. | | ||
| `icon` | Use this to display an icon in the label bubble. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
@use '../../core/styles' as sbb; | ||
|
||
// Box-sizing rules contained in typography are not traversing Shadow DOM boundaries. We need to include box-sizing mixin in every component. | ||
@include sbb.box-sizing; | ||
|
||
:host { | ||
--sbb-step-label-color: var(--sbb-color-iron); | ||
--sbb-step-label-animation-duration: var( | ||
--sbb-disable-animation-zero-time, | ||
var(--sbb-animation-duration-2x) | ||
); | ||
--sbb-step-label-prefix-size: var(--sbb-size-element-xxs); | ||
--sbb-step-label-prefix-border-style: solid; | ||
--sbb-step-label-prefix-border-color: var(--sbb-color-cloud); | ||
--sbb-step-label-prefix-background-color: var(--sbb-color-white); | ||
|
||
position: relative; | ||
min-width: 0; | ||
max-width: fit-content; | ||
|
||
&::before { | ||
@include sbb.text-xxs--regular; | ||
@include sbb.absolute-center-x-y; | ||
|
||
cursor: var(--sbb-step-label-cursor); | ||
color: var(--sbb-step-label-color); | ||
|
||
// The `--sbb-font-size-text-l` is beign used here to align the bubble's inner text to | ||
// the label text which includes the `sbb.text-l--bold` mixin. | ||
inset-block-start: calc( | ||
var(--sbb-font-size-text-l) * (var(--sbb-typo-line-height-body-text) / 2) + | ||
(var(--sbb-border-width-1x) / 2) | ||
); | ||
inset-inline-start: calc(var(--sbb-step-label-prefix-size) / 2); | ||
line-height: 1; | ||
z-index: 1; | ||
transform: translate( | ||
-50%, | ||
calc(-50% + var(--sbb-step-label-translate-y-content-hover, #{sbb.px-to-rem-build(0)})) | ||
); | ||
transition: transform var(--sbb-step-label-animation-duration) var(--sbb-animation-easing); | ||
} | ||
|
||
@include sbb.if-forced-colors { | ||
--sbb-step-label-color: ButtonText; | ||
--sbb-step-label-prefix-border-color: ButtonText; | ||
} | ||
} | ||
|
||
:host([data-selected]) { | ||
@include sbb.text-xxs--bold; | ||
|
||
--sbb-step-label-color: var(--sbb-color-charcoal); | ||
|
||
@include sbb.if-forced-colors { | ||
--sbb-step-label-color: Highlight !important; | ||
} | ||
} | ||
|
||
:host([disabled]) { | ||
--sbb-step-label-color: var(--sbb-color-granite); | ||
--sbb-step-label-prefix-border-style: dashed; | ||
|
||
@include sbb.if-forced-colors { | ||
--sbb-step-label-color: GrayText !important; | ||
} | ||
} | ||
|
||
:host(:hover:not([disabled])) { | ||
@include sbb.hover-mq($hover: true) { | ||
--sbb-step-label-cursor: pointer; | ||
--sbb-step-label-prefix-background-color: var(--sbb-color-milk); | ||
--sbb-step-label-translate-y-content-hover: #{sbb.px-to-rem-build(-1)}; | ||
--sbb-step-label-prefix-size-grow-hover: calc(var(--sbb-border-width-2x) * -1); | ||
} | ||
} | ||
|
||
// Hide focus outline when focus origin is mouse or touch. This is being used as a workaround in various components. | ||
:host(:focus-visible:not([data-focus-origin='mouse'], [data-focus-origin='touch'])) { | ||
@include sbb.focus-outline; | ||
|
||
border-radius: var(--sbb-border-radius-1x); | ||
} | ||
|
||
:host([data-orientation='vertical']) { | ||
transition: margin var(--sbb-stepper-animation-duration) var(--sbb-animation-easing); | ||
} | ||
|
||
:host([data-orientation='vertical']:not(:first-of-type)) { | ||
margin-block-start: var(--sbb-spacing-fixed-6x); | ||
} | ||
|
||
:host([data-selected][data-orientation='vertical']) { | ||
margin-block-end: var(--sbb-spacing-fixed-8x); | ||
} | ||
|
||
.sbb-step-label { | ||
@include sbb.text-l--bold; | ||
|
||
cursor: var(--sbb-step-label-cursor); | ||
position: relative; | ||
display: flex; | ||
gap: var(--sbb-spacing-fixed-4x); | ||
color: var(--sbb-step-label-color); | ||
} | ||
|
||
.sbb-step-label__prefix { | ||
position: relative; | ||
display: flex; | ||
flex-shrink: 0; | ||
align-items: center; | ||
justify-content: center; | ||
width: var(--sbb-step-label-prefix-size); | ||
height: var(--sbb-step-label-prefix-size); | ||
inset-block-start: calc( | ||
1em * (var(--sbb-typo-line-height-body-text) / 2) + (var(--sbb-border-width-1x) / 2) - | ||
(var(--sbb-step-label-prefix-size) / 2) | ||
); | ||
|
||
&::before { | ||
content: ''; | ||
position: absolute; | ||
inset: calc(var(--sbb-step-label-prefix-size-grow-hover, #{sbb.px-to-rem-build(0)})); | ||
border-radius: var(--sbb-border-radius-infinity); | ||
border: var(--sbb-border-width-1x) var(--sbb-step-label-prefix-border-style) | ||
var(--sbb-step-label-prefix-border-color); | ||
background-color: var(--sbb-step-label-prefix-background-color); | ||
transition: { | ||
duration: var(--sbb-step-label-animation-duration); | ||
timing-function: var(--sbb-animation-easing); | ||
property: background-color, inset; | ||
} | ||
} | ||
} | ||
|
||
.sbb-step-label__text { | ||
:host([data-orientation='horizontal']) & { | ||
@include sbb.ellipsis; | ||
} | ||
} | ||
|
||
::slotted(sbb-icon), | ||
sbb-icon { | ||
z-index: 1; | ||
background-color: var(--sbb-step-label-prefix-background-color); | ||
border-radius: var(--sbb-border-radius-infinity); | ||
transform: translateY(var(--sbb-step-label-translate-y-content-hover, #{sbb.px-to-rem-build(0)})); | ||
transition: { | ||
duration: var(--sbb-step-label-animation-duration); | ||
timing-function: var(--sbb-animation-easing); | ||
property: background-color, transform; | ||
} | ||
} |
Oops, something went wrong.