Skip to content

Commit

Permalink
feat(VProgressLinear): add new buffer color / opacity props (#19190)
Browse files Browse the repository at this point in the history
Co-authored-by: John Leider <john@vuetifyjs.com>
  • Loading branch information
KaelWD and johnleider authored Apr 15, 2024
1 parent 614262e commit f257755
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 17 deletions.
3 changes: 3 additions & 0 deletions packages/api-generator/src/locale/en/VProgressLinear.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
"active": "Reduce the height to 0, hiding component.",
"bgOpacity": "Background opacity, if null it defaults to 0.3 if background color is not specified or 1 otherwise.",
"bottom": "Aligns the component towards the bottom.",
"bufferColor": "Sets the color of the buffer bar.",
"bufferOpacity": "Set the opacity of the buffer bar.",
"bufferValue": "The percentage value for the buffer.",
"clickable": "Clicking on the progress track will automatically set the value.",
"indeterminate": "Constantly animates, use when loading progress is unknown.",
"max": "Sets the maximum value the progress can reach.",
"opacity": "Set the opacity of the progress bar.",
"reverse": "Displays reversed progress (right to left in LTR mode and left to right in RTL).",
"roundedBar": "Applies a border radius to the progress bar.",
"stream": "An alternative style for portraying loading that works in tandem with **buffer-value**.",
Expand Down
24 changes: 24 additions & 0 deletions packages/docs/src/examples/v-progress-linear/misc-buffer-color.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<v-sheet
class="d-flex align-center px-4 py-8 mx-auto"
color="#181a1b"
max-width="250"
rounded="lg"
>
<v-progress-linear
:location="false"
bg-color="#92aed9"
buffer-color="#6a3e0b"
buffer-opacity="1"
buffer-value="3"
color="#12512a"
height="12"
max="9"
min="0"
model-value="2"
rounded
></v-progress-linear>

<div class="ms-4 text-h6">3/9</div>
</v-sheet>
</template>
12 changes: 12 additions & 0 deletions packages/docs/src/pages/en/components/progress-linear.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,15 @@ The `v-progress-linear` component is good for communicating to the user that the
Using the **absolute** prop we are able to position the `v-progress-linear` component at the bottom of the `v-toolbar`. We also use the **active** prop which allows us to control the visibility of the progress.

<ExamplesExample file="v-progress-linear/misc-toolbar-loader" />

#### Buffer color and opacity

::: success

This feature was introduced in [v3.6.0 (Nebula)](/getting-started/release-notes/?version=v3.6.0)

:::

The buffer color and opacity can be controlled using the **buffer-color** and **buffer-opacity** props. This enables you to make multi colored progress bars.

<ExamplesExample file="v-progress-linear/misc-buffer-color" />
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
@include tools.rounded($progress-linear-border-radius)

// Elements
.v-progress-linear__background
.v-progress-linear__background,
.v-progress-linear__buffer
background: $progress-linear-background
bottom: 0
left: 0
opacity: $progress-linear-background-opacity
position: absolute
top: 0
width: 100%
transition-property: width, left, right
transition: inherit

Expand Down
52 changes: 37 additions & 15 deletions packages/vuetify/src/components/VProgressLinear/VProgressLinear.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { makeThemeProps, provideTheme } from '@/composables/theme'

// Utilities
import { computed, Transition } from 'vue'
import { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'
import { clamp, convertToUnit, genericComponent, propsFactory, useRender } from '@/util'

type VProgressLinearSlots = {
default: { value: number, buffer: number }
Expand All @@ -32,6 +32,8 @@ export const makeVProgressLinearProps = propsFactory({
type: [Number, String],
default: 0,
},
bufferColor: String,
bufferOpacity: [Number, String],
clickable: Boolean,
color: String,
height: {
Expand All @@ -47,6 +49,7 @@ export const makeVProgressLinearProps = propsFactory({
type: [Number, String],
default: 0,
},
opacity: [Number, String],
reverse: Boolean,
stream: Boolean,
striped: Boolean,
Expand Down Expand Up @@ -74,22 +77,27 @@ export const VProgressLinear = genericComponent<VProgressLinearSlots>()({
const { themeClasses } = provideTheme(props)
const { locationStyles } = useLocation(props)
const { textColorClasses, textColorStyles } = useTextColor(props, 'color')
const { backgroundColorClasses, backgroundColorStyles } = useBackgroundColor(computed(() => props.bgColor || props.color))
const { backgroundColorClasses: barColorClasses, backgroundColorStyles: barColorStyles } = useBackgroundColor(props, 'color')
const {
backgroundColorClasses,
backgroundColorStyles,
} = useBackgroundColor(computed(() => props.bgColor || props.color))
const {
backgroundColorClasses: bufferColorClasses,
backgroundColorStyles: bufferColorStyles,
} = useBackgroundColor(computed(() => props.bufferColor || props.bgColor || props.color))
const {
backgroundColorClasses: barColorClasses,
backgroundColorStyles: barColorStyles,
} = useBackgroundColor(props, 'color')
const { roundedClasses } = useRounded(props)
const { intersectionRef, isIntersecting } = useIntersectionObserver()

const max = computed(() => parseInt(props.max, 10))
const height = computed(() => parseInt(props.height, 10))
const normalizedBuffer = computed(() => parseFloat(props.bufferValue) / max.value * 100)
const normalizedValue = computed(() => parseFloat(progress.value) / max.value * 100)
const max = computed(() => parseFloat(props.max))
const height = computed(() => parseFloat(props.height))
const normalizedBuffer = computed(() => clamp(parseFloat(props.bufferValue) / max.value * 100, 0, 100))
const normalizedValue = computed(() => clamp(parseFloat(progress.value) / max.value * 100, 0, 100))
const isReversed = computed(() => isRtl.value !== props.reverse)
const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition')
const opacity = computed(() => {
return props.bgOpacity == null
? props.bgOpacity
: parseFloat(props.bgOpacity)
})

function handleClick (e: MouseEvent) {
if (!intersectionRef.value) return
Expand Down Expand Up @@ -146,7 +154,7 @@ export const VProgressLinear = genericComponent<VProgressLinearSlots>()({
...textColorStyles.value,
[isReversed.value ? 'left' : 'right']: convertToUnit(-height.value),
borderTop: `${convertToUnit(height.value / 2)} dotted`,
opacity: opacity.value,
opacity: parseFloat(props.bufferOpacity!),
top: `calc(50% - ${convertToUnit(height.value / 4)})`,
width: convertToUnit(100 - normalizedBuffer.value, '%'),
'--v-progress-linear-stream-to': convertToUnit(height.value * (isReversed.value ? 1 : -1)),
Expand All @@ -162,8 +170,22 @@ export const VProgressLinear = genericComponent<VProgressLinearSlots>()({
style={[
backgroundColorStyles.value,
{
opacity: opacity.value,
width: convertToUnit((!props.stream ? 100 : normalizedBuffer.value), '%'),
opacity: parseFloat(props.bgOpacity!),
width: props.stream ? 0 : undefined,
},
]}
/>

<div
class={[
'v-progress-linear__buffer',
bufferColorClasses.value,
]}
style={[
bufferColorStyles.value,
{
opacity: parseFloat(props.bufferOpacity!),
width: convertToUnit(normalizedBuffer.value, '%'),
},
]}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('VProgressLinear', () => {
<VProgressLinear modelValue={ 25 } stream bufferValue={ 50 } />
</CenteredGrid>
))
.get('.v-progress-linear__background')
.get('.v-progress-linear__buffer')
.should('have.css', 'width', '50px')
})

Expand Down

0 comments on commit f257755

Please sign in to comment.