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(web-core): circle progress bar component #8402

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

S3bastianCZ
Copy link
Contributor

@S3bastianCZ S3bastianCZ commented Mar 4, 2025

Description

Create a circle progress bar component.
4 sizes (extra small, small, medium, large)
4 accents (info, success, warning, medium)

Screenshot

Capture d’écran 2025-03-05 à 08 58 17

Checklist

  • Commit
    • Title follows commit conventions
    • Reference the relevant issue (Fixes #007, See xoa-support#42, See https://...)
    • If bug fix, add Introduced by
  • Changelog
    • If visible by XOA users, add changelog entry
    • Update "Packages to release" in CHANGELOG.unreleased.md
  • PR
    • If UI changes, add screenshots
    • If not finished or not tested, open as Draft

Review process

This 2-passes review process aims to:

  • develop skills of junior reviewers
  • limit the workload for senior reviewers
  • limit the number of unnecessary changes by the author
  1. The author creates a PR.
  2. Review process:
    1. The author assigns the junior reviewer.
    2. The junior reviewer conducts their review:
      • Resolves their comments if they are addressed.
      • Adds comments if necessary or approves the PR.
    3. The junior reviewer assigns the senior reviewer.
    4. The senior reviewer conducts their review:
      • If there are no unresolved comments on the PR → merge.
      • Otherwise, we continue with 3.
  3. The author responds to comments and/or makes corrections, and we go back to 2.

Notes:

  1. The author can request a review at any time, even if the PR is still a Draft.
  2. In theory, there should not be more than one reviewer at a time.
  3. The author should not make any changes:
    • When a reviewer is assigned.
    • Between the junior and senior reviews.

@S3bastianCZ S3bastianCZ self-assigned this Mar 4, 2025
@S3bastianCZ S3bastianCZ force-pushed the circle-progress-bar-component branch from 2f71351 to 05503e3 Compare March 4, 2025 12:52
@S3bastianCZ S3bastianCZ force-pushed the circle-progress-bar-component branch from bb7e54b to 0f0982d Compare March 5, 2025 07:59
@S3bastianCZ S3bastianCZ requested review from J0ris-K and OlivierFL and removed request for J0ris-K March 5, 2025 07:59
@S3bastianCZ S3bastianCZ marked this pull request as ready for review March 5, 2025 08:17
Comment on lines +111 to +152
<style lang="postcss" scoped>
.progress-circle-container {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
}

.progress-circle-background {
stroke: v-bind(backgroundStrokeColor);
stroke-width: v-bind(strokeWidth);
}

.progress-circle-foreground {
stroke-width: v-bind(strokeWidth);
stroke-linecap: butt;
transition: stroke-dashoffset 0.3s ease;
transform: rotate(-90deg);
transform-origin: center;
}

.progress-circle-fill {
stroke: v-bind(strokeColor);
stroke-dasharray: v-bind(circumference);
stroke-dashoffset: v-bind(dashOffset);
}

.progress-circle-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

.progress-circle-text {
color: v-bind(strokeColor);
}

.progress-circle-icon {
font-size: v-bind(iconSize);
}
</style>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to use our guidelines for CSS

@@ -0,0 +1,152 @@
<!-- v3 -->
<template>
<div class="progress-circle-container">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS class should match the component's name and the guidelines

}

const iconSizeMap = {
'extra-small': '',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can use undefined here? The same applies on line 70.

large: 16,
}

const fontClasses = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep consistency?

Suggested change
const fontClasses = {
const fontClassesMap = {

accent: ProgressCircleAccent
size: ProgressCircleSize
value: number
maxValue: number
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if maxValue could be optional, and in this case, compute the completion percentage based on a default value?
I mean, in most cases, we would want to display the completion based on 100%, so maybe this could be the default value?

return circumference.value * (1 - valuePercent.value / 100)
})

const percentValue = computed(() => `${valuePercent.value}%`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use n from useI18n(), it will handle space between the value and %, which may differ based on the locale:

Suggested change
const percentValue = computed(() => `${valuePercent.value}%`)
const percentValue = computed(() => n(valuePercent.value / 100, 'percent'))

const backgroundStrokeColor = computed(() => `var(--color-${accent}-background-selected)`)

const iconAccent = computed(() =>
isComplete.value && (accent === 'info' || accent === 'success') ? 'success' : accent
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the condition isComplete.value && (accent === 'info' || accent === 'success') is used twice, maybe it could be refactored into a computed property:

const isCompleteWithSuccess = computed(() => isComplete.value && ['info', 'success'].includes(accent))

/>
</svg>
<div v-if="size !== 'extra-small'" class="progress-circle-overlay">
<VtsIcon v-if="isComplete" :icon="icon" class="progress-circle-icon" :accent="iconAccent" />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<VtsIcon v-if="isComplete" :icon="icon" class="progress-circle-icon" :accent="iconAccent" />
<VtsIcon v-if="isComplete" :icon class="progress-circle-icon" :accent="iconAccent" />

v-slot="{ properties }"
:params="[
prop('value').num().preset(75).required().widget(),
prop('max-value').num().default(100).preset(100).widget(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prop is required, plus there is no default value (only preset is enough):

Suggested change
prop('max-value').num().default(100).preset(100).widget(),
prop('max-value').num().required().preset(100).widget(),

Comment on lines +21 to +34
const presets = {
'Half of 500': {
props: {
'max-value': 500,
value: 250,
},
},
'75% of 300': {
props: {
'max-value': 300,
value: 225,
},
},
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be careful to use all the required props (accent and size are missing)

@OlivierFL OlivierFL requested a review from ByScripts March 5, 2025 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants