diff --git a/CHANGELOG.md b/CHANGELOG.md index e15b8c9e5..031c1a279 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [4.11.1] - 2024-07-03 +### Changed + - Stepper Design in vertical mode [#1246](https://github.com/IgniteUI/igniteui-webcomponents/issues/1246) + +## [4.11.0] - 2024-07-03 +### Changed + - Toast Component Indigo Theme [#1249](https://github.com/IgniteUI/igniteui-webcomponents/pull/1249) + - Rating Component Indigo Theme [#1249](https://github.com/IgniteUI/igniteui-webcomponents/pull/1249) + - Stepper Component Indigo Theme [#1249](https://github.com/IgniteUI/igniteui-webcomponents/pull/1249) + ## [4.10.0] - 2024-07-01 ### Added - Banner component [#1174](https://github.com/IgniteUI/igniteui-webcomponents/issues/1174) @@ -485,6 +495,8 @@ Initial release of Ignite UI Web Components - Ripple component - Switch component +[4.11.1]: https://github.com/IgniteUI/igniteui-webcomponents/compare/4.11.0...4.11.1 +[4.11.0]: https://github.com/IgniteUI/igniteui-webcomponents/compare/4.10.0...4.11.0 [4.10.0]: https://github.com/IgniteUI/igniteui-webcomponents/compare/4.9.0...4.10.0 [4.9.0]: https://github.com/IgniteUI/igniteui-webcomponents/compare/4.8.2...4.9.0 [4.8.2]: https://github.com/IgniteUI/igniteui-webcomponents/compare/4.8.1...4.8.2 diff --git a/src/components/stepper/animations.ts b/src/components/stepper/animations.ts index 8506f6d5d..9bcf6fa66 100644 --- a/src/components/stepper/animations.ts +++ b/src/components/stepper/animations.ts @@ -1,38 +1,127 @@ -import { fadeIn, fadeOut } from '../../animations/presets/fade/index.js'; -import { growVerIn, growVerOut } from '../../animations/presets/grow/index.js'; +import { EaseOut } from '../../animations/easings.js'; import { - slideInHor, - slideOutHor, -} from '../../animations/presets/slide/index.js'; -import { animation } from '../../animations/types.js'; + type AnimationReferenceMetadata, + animation, +} from '../../animations/types.js'; + +const baseOptions: KeyframeAnimationOptions = { + duration: 320, + easing: EaseOut.Quad, +}; -const noopAnimation = () => animation([], {}); export type Animation = 'grow' | 'fade' | 'slide' | 'none'; -export const animations = new Map( + +export type AnimationOptions = { + keyframe: KeyframeAnimationOptions; + step?: object; +}; + +const fadeIn = (options: AnimationOptions = { keyframe: baseOptions }) => + animation([{ opacity: 0 }, { opacity: 1 }], options.keyframe); + +const fadeOut = (options: AnimationOptions = { keyframe: baseOptions }) => + animation([{ opacity: 1 }, { opacity: 0 }], options.keyframe); + +const slideInHor = ( + options: AnimationOptions = { + keyframe: baseOptions, + } +) => + animation( + [{ transform: 'translateX(100%)' }, { transform: 'translateX(0)' }], + options.keyframe + ); + +const slideOutHor = ( + options: AnimationOptions = { + keyframe: baseOptions, + } +) => + animation( + [{ transform: 'translateX(0)' }, { transform: 'translateX(-100%)' }], + options.keyframe + ); + +const growVerIn = ( + options: AnimationOptions = { + keyframe: baseOptions, + step: {}, + } +) => + animation( + [ + { opacity: 1, ...options.step }, + { opacity: 1, height: 'auto' }, + ], + options.keyframe + ); + +const growVerOut = ( + options: AnimationOptions = { + keyframe: baseOptions, + step: {}, + } +) => + animation( + [ + { opacity: 1, height: 'auto' }, + { opacity: 1, ...options.step }, + ], + options.keyframe + ); + +const noopAnimation = () => animation([], {}); + +const animationPair = (animations: { + in: (options: AnimationOptions) => AnimationReferenceMetadata; + out: (options: AnimationOptions) => AnimationReferenceMetadata; +}) => { + return new Map( + Object.entries({ + in: animations.in, + out: animations.out, + }) + ); +}; + +export const bodyAnimations = new Map( + Object.entries({ + grow: animationPair({ + in: growVerIn, + out: growVerOut, + }), + fade: animationPair({ + in: noopAnimation, + out: noopAnimation, + }), + slide: animationPair({ + in: slideInHor, + out: slideOutHor, + }), + none: animationPair({ + in: noopAnimation, + out: noopAnimation, + }), + }) +); + +export const contentAnimations = new Map( Object.entries({ - grow: new Map( - Object.entries({ - in: growVerIn, - out: growVerOut, - }) - ), - fade: new Map( - Object.entries({ - in: fadeIn, - out: fadeOut, - }) - ), - slide: new Map( - Object.entries({ - in: slideInHor, - out: slideOutHor, - }) - ), - none: new Map( - Object.entries({ - in: noopAnimation, - out: noopAnimation, - }) - ), + grow: animationPair({ + in: fadeIn, + out: fadeOut, + }), + fade: animationPair({ + in: fadeIn, + out: fadeOut, + }), + slide: animationPair({ + in: fadeIn, + out: fadeOut, + }), + none: animationPair({ + in: noopAnimation, + out: noopAnimation, + }), }) ); diff --git a/src/components/stepper/step.ts b/src/components/stepper/step.ts index 0cac84348..605892544 100644 --- a/src/components/stepper/step.ts +++ b/src/components/stepper/step.ts @@ -9,7 +9,11 @@ import { themes } from '../../theming/theming-decorator.js'; import { watch } from '../common/decorators/watch.js'; import { registerComponent } from '../common/definitions/register.js'; import { partNameMap } from '../common/util.js'; -import { type Animation, animations } from './animations.js'; +import { + type Animation, + bodyAnimations, + contentAnimations, +} from './animations.js'; import { styles as shared } from './themes/step/shared/step.common.css.js'; import { styles } from './themes/step/step.base.css.js'; import { all } from './themes/step/themes.js'; @@ -55,8 +59,13 @@ export default class IgcStepComponent extends LitElement { } private bodyRef: Ref = createRef(); + private contentRef: Ref = createRef(); - private animationPlayer = addAnimationController(this, this.bodyRef); + private bodyAnimationPlayer = addAnimationController(this, this.bodyRef); + private contentAnimationPlayer = addAnimationController( + this, + this.contentRef + ); @queryAssignedElements({ slot: 'title' }) private _titleChildren!: Array; @@ -146,7 +155,11 @@ export default class IgcStepComponent extends LitElement { type: 'in' | 'out', direction: 'normal' | 'reverse' = 'normal' ) { - const animation = animations.get(this.animation)!.get(type)!; + const bodyAnimation = bodyAnimations.get(this.animation)!.get(type)!; + const contentAnimation = contentAnimations.get(this.animation)!.get(type)!; + const bodyHeight = window + .getComputedStyle(this) + .getPropertyValue('--vertical-body-height'); const options: KeyframeAnimationOptions = { duration: this.animationDuration, @@ -154,9 +167,17 @@ export default class IgcStepComponent extends LitElement { direction, }; + const step = { + height: bodyHeight, + }; + const [_, event] = await Promise.all([ - this.animationPlayer.stopAll(), - this.animationPlayer.play(animation(options)), + this.bodyAnimationPlayer.stopAll(), + this.bodyAnimationPlayer.play(bodyAnimation({ keyframe: options, step })), + this.contentAnimationPlayer.stopAll(), + this.contentAnimationPlayer.play( + contentAnimation({ keyframe: options, step }) + ), ]); return event.type; @@ -276,7 +297,7 @@ export default class IgcStepComponent extends LitElement { role="tabpanel" aria-labelledby="igc-step-header-${this.index}" > -
+
`; diff --git a/src/components/stepper/themes/step/step.base.scss b/src/components/stepper/themes/step/step.base.scss index 11afc6c32..4fff6f636 100644 --- a/src/components/stepper/themes/step/step.base.scss +++ b/src/components/stepper/themes/step/step.base.scss @@ -107,7 +107,6 @@ [part~='body'] { display: block; - opacity: 0; grid-row-start: var(--body-top, 2); grid-column: 1 / span var(--steps-count); padding-inline-start: calc(var(--body-indent--vertical) / 2); @@ -138,6 +137,7 @@ display: block; height: auto; overflow: auto; + opacity: 0; > slot { display: block; @@ -261,7 +261,6 @@ :host([active]) { [part~='body'] { height: 100%; - opacity: 1; } [part~='body bottom'] { @@ -272,6 +271,7 @@ [part='content'] { pointer-events: all; + opacity: 1; } } diff --git a/src/components/stepper/themes/stepper/stepper.base.scss b/src/components/stepper/themes/stepper/stepper.base.scss index e9a3c1003..8df0a50e1 100644 --- a/src/components/stepper/themes/stepper/stepper.base.scss +++ b/src/components/stepper/themes/stepper/stepper.base.scss @@ -117,7 +117,7 @@ :host(:not([orientation='horizontal'])) { --vertical-header-z-index: 2; --vertical-body-disply: block; - --vertical-body-height: 0; + --vertical-body-height: #{rem(24px)}; --header-width-vertical: 100%; --hide-horizontal-separator: none; @@ -137,6 +137,7 @@ } ::slotted(igc-step:last-of-type) { + --vertical-body-height: 0; --hide-last-separator: none; } } diff --git a/stories/stepper.stories.ts b/stories/stepper.stories.ts index a67493ad0..858febfab 100644 --- a/stories/stepper.stories.ts +++ b/stories/stepper.stories.ts @@ -3,11 +3,12 @@ import { html } from 'lit'; import { IgcButtonComponent, + IgcInputComponent, IgcStepperComponent, defineComponents, } from '../src/index.js'; -defineComponents(IgcStepperComponent, IgcButtonComponent); +defineComponents(IgcStepperComponent, IgcButtonComponent, IgcInputComponent); // region default const metadata: Meta = { @@ -148,17 +149,25 @@ const BasicTemplate = ({ Step1 (completed) - - +

Next
- + Step 2 (default) - - +

Prev Next