From 302fbc3594fff269816d03ec5924dbc523c7444a Mon Sep 17 00:00:00 2001 From: John Leider Date: Sun, 3 Nov 2024 13:24:11 -0600 Subject: [PATCH] refactor(VStepperVertical): add support for item-props --- .../VStepperVertical/VStepperVertical.tsx | 12 +- .../VStepperVerticalItem.sass | 140 ++++++++++-------- .../VStepperVertical/VStepperVerticalItem.tsx | 10 +- 3 files changed, 91 insertions(+), 71 deletions(-) diff --git a/packages/vuetify/src/labs/VStepperVertical/VStepperVertical.tsx b/packages/vuetify/src/labs/VStepperVertical/VStepperVertical.tsx index ba3ee62ef8a..523b03b348e 100644 --- a/packages/vuetify/src/labs/VStepperVertical/VStepperVertical.tsx +++ b/packages/vuetify/src/labs/VStepperVertical/VStepperVertical.tsx @@ -63,10 +63,18 @@ export const VStepperVertical = genericComponent()({ const items = computed(() => props.items.map((item, index) => { const title = getPropertyFromItem(item, props.itemTitle, item) const value = getPropertyFromItem(item, props.itemValue, index + 1) + const itemProps = props.itemProps ? item : getPropertyFromItem(item, props.itemProps) - return { + const _props = { title, value, + ...itemProps, + } + + return { + title: _props.title, + value: _props.value, + props: _props, raw: item, } })) @@ -115,7 +123,7 @@ export const VStepperVertical = genericComponent()({ return ( <> { items.value.map(({ raw, ...item }) => ( - + {{ ...slots, default: slots[`item.${item.value}`], diff --git a/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.sass b/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.sass index 96967cabc2f..66daddd3887 100644 --- a/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.sass +++ b/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.sass @@ -2,73 +2,83 @@ @use '../../styles/tools' @use './variables' as * -.v-stepper-vertical-item - position: relative - transition-duration: $stepper-vertical-item-transition-duration - transition-property: $stepper-vertical-item-transition-property - transition-timing-function: $stepper-vertical-item-transition-timing-function - - &__title - font-size: 1rem - - &__subtitle - font-size: .75rem - - .v-expansion-panel-text - padding-inline-start: 32px - - &:not(:last-child):before - content: '' - position: absolute - width: 2px - height: calc(100% - 30px) - background: rgba(var(--v-border-color), var(--v-border-opacity)) - left: 35px - top: 44px - z-index: 1 - transition-duration: 300ms - transition-property: height - - &:after - display: none - - &.v-expansion-panel--disabled, - &:not(.v-stepper-vertical-item--editable) - .v-expansion-panel-title - pointer-events: none - - .v-expansion-panel-title__overlay - opacity: 0 - -.v-stepper-vertical-item__avatar.v-avatar - background: rgba(var(--v-theme-surface-variant), var(--v-medium-emphasis-opacity)) - color: rgb(var(--v-theme-on-surface-variant)) - transition-property: background +@include tools.layer('components') + .v-stepper-vertical-item + position: relative + transition-duration: $stepper-vertical-item-transition-duration + transition-property: $stepper-vertical-item-transition-property + transition-timing-function: $stepper-vertical-item-transition-timing-function - .v-icon - font-size: .875rem + .v-stepper--non-linear & + opacity: var(--v-high-emphasis-opacity) - .v-expansion-panel--active & - background: rgb(var(--v-theme-surface-variant)) + &--error + color: rgb(var(--v-theme-error)) - .v-stepper-vertical-item--error & - background: rgb(var(--v-theme-error)) - color: rgb(var(--v-theme-on-error)) + &__title + font-size: 1rem -.v-stepper-vertical-item__title - .v-stepper-vertical-item--error & - color: rgb(var(--v-theme-error)) + &__subtitle + font-size: .75rem -.v-stepper-vertical-item__subtitle - .v-stepper-vertical-item--error & - color: rgb(var(--v-theme-error)) - -.v-stepper-vertical-actions - &.v-stepper-actions - .v-btn - margin-inline-end: 8px - - .v-stepper & - justify-content: flex-end - padding: 24px 0 0 - flex-direction: row-reverse + .v-expansion-panel-title + opacity: var(--v-medium-emphasis-opacity) + + .v-expansion-panel-text + padding-inline-start: 32px + + &:not(:last-child):before + content: '' + position: absolute + width: 2px + height: calc(100% - 30px) + background: rgba(var(--v-border-color), var(--v-border-opacity)) + left: 35px + top: 44px + z-index: 1 + transition-duration: 300ms + transition-property: height + + &:after + display: none + + &.v-expansion-panel--disabled, + &:not(.v-stepper-vertical-item--editable) + .v-expansion-panel-title + pointer-events: none + + .v-expansion-panel-title__overlay + opacity: 0 + + .v-stepper-vertical-item__avatar.v-avatar + background: rgba(var(--v-theme-surface-variant), var(--v-medium-emphasis-opacity)) + color: rgb(var(--v-theme-on-surface-variant)) + transition-property: background + + .v-icon + font-size: .875rem + + .v-expansion-panel--active & + background: rgb(var(--v-theme-surface-variant)) + + .v-stepper-vertical-item--error & + background: rgb(var(--v-theme-error)) + color: rgb(var(--v-theme-on-error)) + + .v-stepper-vertical-item__title + .v-stepper-vertical-item--error & + color: rgb(var(--v-theme-error)) + + .v-stepper-vertical-item__subtitle + .v-stepper-vertical-item--error & + color: rgb(var(--v-theme-error)) + + .v-stepper-vertical-actions + &.v-stepper-actions + .v-btn + margin-inline-end: 8px + + .v-stepper & + justify-content: flex-end + padding: 24px 0 0 + flex-direction: row-reverse diff --git a/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.tsx b/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.tsx index e2d719e06da..671a286d9e8 100644 --- a/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.tsx +++ b/packages/vuetify/src/labs/VStepperVertical/VStepperVerticalItem.tsx @@ -56,10 +56,10 @@ export const VStepperVerticalItem = genericComponent( const step = computed(() => !isNaN(parseInt(props.value)) ? Number(props.value) : props.value) const groupItem = computed(() => vExpansionPanelRef.value?.groupItem) const isSelected = computed(() => groupItem.value?.isSelected.value ?? false) - const isValid = computed(() => isSelected.value ? props.rules.every(handler => handler() === true) : null) + const isValid = computed(() => props.rules.every(handler => handler() === true)) const canEdit = computed(() => !props.disabled && props.editable) - const hasError = computed(() => props.error || (isSelected.value && !isValid.value)) - const hasCompleted = computed(() => props.complete || (props.rules.length > 0 && isValid.value === true)) + const hasError = computed(() => props.error || !isValid.value) + const hasCompleted = computed(() => props.complete || (props.rules.length > 0 && isValid.value)) const disabled = computed(() => { if (props.disabled) return props.disabled @@ -107,8 +107,10 @@ export const VStepperVerticalItem = genericComponent( useRender(() => { const hasColor = ( + !groupItem.value || + groupItem.value?.isSelected.value || hasCompleted.value || - groupItem.value?.isSelected.value + canEdit.value ) && ( !hasError.value && !props.disabled