Skip to content

feat: progressbar new way of handling classes #1607

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

Merged
merged 2 commits into from
May 25, 2025

Conversation

jjagielka
Copy link
Contributor

@jjagielka jjagielka commented May 25, 2025

📑 Description

Proposal of the new prop classes that replaces the customization props like: divClass, insideLabelClass, etc.

Now the component has a prop classes which accept the object that is a record of twVariants slots names and overriding classes:

<Progressbar {progress} labelInsideClass="..." oustsideSpanClass="..." oustsideProgressClass="..." labeloutsidedivClass=".." />
<Progressbar {progress} classes={{labelInside:"...", oustsideSpan:"...", oustsideProgress:"...", outsideDiv:".."}} />

This will reduce the number of props per element while increasing the type safety.

Status

  • Not Completed
  • Completed

✅ Checks

  • My pull request adheres to the code style of this project
  • My code requires changes to the documentation
  • I have updated the documentation as required
  • I have checked the page with https://validator.unl.edu/
  • All the tests have passed
  • My pull request is based on the latest commit (not the npm version).

ℹ Additional Information

Summary by CodeRabbit

  • New Features

    • Simplified and unified customization of Progressbar and Progressradial components by introducing a single classes prop and a main class prop for styling, replacing multiple individual class-related props.
  • Documentation

    • Updated documentation and usage examples to reflect the new classes prop and revised styling approach for Progressbar and Progressradial components.
  • Chores

    • Improved type safety and clarity for progress components by enhancing and reorganizing type definitions and imports.
    • Updated component metadata JSON files to match the new prop structure.

Copy link

vercel bot commented May 25, 2025

@jjagielka is attempting to deploy a commit to the Themesberg Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented May 25, 2025

Walkthrough

The changes refactor class handling for Progressbar and Progressradial components by consolidating multiple class-related props into a single classes object and a main class: className prop. Type definitions and documentation are updated accordingly, new variant types are introduced for improved type safety, and JSON metadata and docs examples are revised to reflect these updates.

Changes

File(s) Change Summary
src/lib/progress/Progressbar.svelte, src/lib/progress/Progressradial.svelte Replaced multiple individual class props with a unified classes object and class: className; removed twMerge usage. Updated class merging logic accordingly.
src/lib/progress/theme.ts Added and updated types: ProgressbarClasses, ProgressbarVariants, ProgressradialClasses, and ProgressradialVariants for enhanced typing of classes and variants.
src/lib/types.ts Reorganized and added imports; extended ProgressbarProps and ProgressradialProps with variant types; removed obsolete class-related props; minor formatting refinements.
src/routes/component-data/Progressbar.json, src/routes/component-data/Progressradial.json Reformatted JSON props arrays; removed old individual class props; added class: className and classes props with empty defaults.
src/routes/docs/components/progress.md Updated documentation and usage examples to replace labelInsideClass with classes.labelInsideDiv for styling.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Progressbar
    participant Theme

    User->>Progressbar: Render with { class: className, classes }
    Progressbar->>Theme: Apply base styles and merge with classes/className
    Progressbar-->>User: Rendered progress bar with unified class handling
Loading
sequenceDiagram
    participant User
    participant Progressradial
    participant Theme

    User->>Progressradial: Render with { class: className, classes }
    Progressradial->>Theme: Apply base styles and merge with classes/className
    Progressradial-->>User: Rendered radial progress with unified class handling
Loading

Poem

In the meadow of code, where progress bars gleam,
Classes once scattered now flow in one stream.
No more twMerge tangles, just classes and grace—
Our props are now tidy, each style in its place!
🐇✨ Hopping forward, unified and bright,
Progress made simple—what a delight!


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73f9b6f and 4c2c933.

📒 Files selected for processing (3)
  • src/lib/progress/Progressbar.svelte (3 hunks)
  • src/lib/progress/Progressradial.svelte (4 hunks)
  • src/lib/progress/theme.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/progress/theme.ts
  • src/lib/progress/Progressradial.svelte
  • src/lib/progress/Progressbar.svelte
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Playwright and Lint
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/routes/docs/components/progress.md (1)

158-158: Fix grammatical issue by adding the missing article.

The sentence should include "the" before "prop" for better readability.

-Use `labelInsideDiv` prop to style your progressbar.
+Use the `labelInsideDiv` prop to style your progressbar.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~158-~158: You might be missing the article “the” here.
Context: ...le" /> ``` ## Custom style Use labelInsideDiv prop to style your progr...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c24124c and 73f9b6f.

📒 Files selected for processing (7)
  • src/lib/progress/Progressbar.svelte (3 hunks)
  • src/lib/progress/Progressradial.svelte (5 hunks)
  • src/lib/progress/theme.ts (2 hunks)
  • src/lib/types.ts (9 hunks)
  • src/routes/component-data/Progressbar.json (1 hunks)
  • src/routes/component-data/Progressradial.json (1 hunks)
  • src/routes/docs/components/progress.md (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/lib/types.ts (2)
src/lib/toolbar/theme.ts (1)
  • ToolbarGroupVariants (87-87)
src/lib/progress/theme.ts (2)
  • ProgressbarVariants (4-4)
  • ProgressradialVariants (123-123)
🪛 LanguageTool
src/routes/docs/components/progress.md

[uncategorized] ~158-~158: You might be missing the article “the” here.
Context: ...le" /> ``` ## Custom style Use labelInsideDiv prop to style your progr...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Playwright and Lint
🔇 Additional comments (22)
src/routes/docs/components/progress.md (3)

165-170: LGTM! Documentation correctly reflects the new classes prop structure.

The examples properly demonstrate the transition from individual class props to the unified classes object approach, which aligns with the PR objectives.


184-186: LGTM! Animation examples updated correctly.

The animation examples correctly use the new classes={{labelInsideDiv: "..."}} pattern instead of the deprecated labelInsideClass prop.


199-202: LGTM! Custom color examples follow the new pattern.

The custom color examples correctly demonstrate the new classes prop usage with different background colors.

src/routes/component-data/Progressradial.json (2)

8-63: LGTM! Props structure correctly updated for the new classes approach.

The JSON correctly reflects the removal of individual class props (labelInsideClass, outsideSpanClass, etc.) and the addition of the unified class: className and classes props, which aligns with the PR objectives.


5-5:

✅ Verification successful

Verify the updated type definition link.

The link has been updated to point to line 1259. Please ensure this accurately reflects the location of the ProgressradialProps type definition.


🏁 Script executed:

#!/bin/bash
# Description: Verify the ProgressradialProps type definition location
# Expected: The type should be found around line 1259

ast-grep --pattern 'export interface ProgressradialProps'

Length of output: 59


🏁 Script executed:

#!/bin/bash
# Locate the type definition for ProgressradialProps in src/lib/types.ts

# Confirm the file exists
if [[ ! -f src/lib/types.ts ]]; then
  echo "ERROR: src/lib/types.ts not found"
  exit 1
fi

# Search with both casing variations
rg -n 'ProgressradialProps' src/lib/types.ts || true
rg -n 'ProgressRadialProps' src/lib/types.ts || true

Length of output: 233


Validated type definition link

The ProgressradialProps interface is indeed exported at line 1259 of src/lib/types.ts, so the GitHub URL is accurate. No further action needed.

src/routes/component-data/Progressbar.json (2)

8-51: LGTM! Props structure correctly updated for the new classes approach.

The JSON correctly reflects the removal of individual class props (labelInsideClass, oustsideSpanClass, etc.) and the addition of the unified class: className and classes props, maintaining consistency with the refactoring.


5-5:

✅ Verification successful

Verify the updated type definition link.

The link has been updated to point to line 1247. Please ensure this accurately reflects the location of the ProgressbarProps type definition.


🏁 Script executed:

#!/bin/bash
# Description: Verify the ProgressbarProps type definition location
# Expected: The type should be found around line 1247

ast-grep --pattern 'export interface ProgressbarProps'

Length of output: 56


🏁 Script executed:

#!/bin/bash
# Search for the ProgressbarProps definition or references in the codebase
rg -n "ProgressbarProps" -C2 .

Length of output: 3127


ProgressbarProps link verified

The link in src/routes/component-data/Progressbar.json correctly points to line 1247 in src/lib/types.ts where the ProgressbarProps interface is defined. No changes required.

src/lib/progress/theme.ts (3)

1-1: LGTM! Import properly extended for variant types.

Adding the VariantProps import is necessary for the new type definitions that follow.


3-4: LGTM! Well-structured type definitions for Progressbar.

The type definitions follow a good pattern:

  • ProgressbarClasses provides type safety for the classes prop by referencing the theme slots
  • ProgressbarVariants properly combines variant props with the classes object

122-123: LGTM! Consistent type definitions for Progressradial.

The type definitions maintain the same pattern as Progressbar, ensuring consistency across components and proper type safety for the new classes prop structure.

src/lib/progress/Progressradial.svelte (6)

2-3: LGTM! Imports properly organized for the new approach.

The imports are correctly updated to include the theme and types, and twMerge is appropriately removed since it's no longer needed with the new classes structure.


8-8: LGTM! Props destructuring correctly implements the new classes approach.

The destructuring properly includes the new class: className and classes props while removing the individual class props, which aligns perfectly with the PR objectives.


38-41: LGTM! Outside label styling correctly uses the new classes structure.

The implementation properly uses the theme functions with the classes object for outsideDiv, outsideSpan, and outsideProgress styling.


44-44: LGTM! Base element styling properly combines all class sources.

The base element correctly combines size, classes?.base, and className using clsx, which provides a clean and flexible approach to class merging.


54-54: LGTM! Inside label styling follows the new pattern.

The inside label correctly uses the labelInsideDiv function with the classes object for consistent styling.


79-80: LGTM! JSDoc comments updated to reflect the new props.

The JSDoc properly documents the new class: className and classes props, replacing the previous individual class props.

src/lib/progress/Progressbar.svelte (3)

2-2: Good import organization.

Moving the type import to the top improves code readability and follows best practices for import organization.


8-8: Excellent prop consolidation.

The refactoring from multiple individual class props to a single classes object and class: className significantly improves the component's API and reduces prop clutter.


46-60: Documentation accurately reflects the API changes.

The component documentation has been properly updated to reflect the new consolidated class handling approach, removing references to old individual class props and adding the new class: className and classes props.

src/lib/types.ts (3)

1174-1174: Import supports the new variant type system.

The addition of ProgressbarVariants and ProgressradialVariants imports properly supports the new consolidated class handling approach.


1247-1257: Excellent type safety improvement.

Extending ProgressbarProps with ProgressbarVariants provides proper type safety for the new classes object while maintaining compatibility with standard HTML div attributes.


1259-1272: Consistent type definition pattern.

The ProgressradialProps interface follows the same excellent pattern as ProgressbarProps, ensuring consistency across the progress component family and proper type safety for the refactored class handling.

{_progress.current.toFixed(precision)}%
</div>
{:else}
<div class={twMerge(insideDiv(), size, clsx(labelInsideClass))} style="width: {_progress.current}%"></div>
<div class={insideDiv({ class: clsx(classes?.labelInsideDiv, size) })} style="width: {_progress.current}%"></div>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect class reference.

There's a copy-paste error where classes?.labelInsideDiv is used instead of classes?.insideDiv. This will apply the wrong styling to the inside div element.

Apply this fix:

-    <div class={insideDiv({ class: clsx(classes?.labelInsideDiv, size) })} style="width: {_progress.current}%"></div>
+    <div class={insideDiv({ class: clsx(classes?.insideDiv, size) })} style="width: {_progress.current}%"></div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div class={insideDiv({ class: clsx(classes?.labelInsideDiv, size) })} style="width: {_progress.current}%"></div>
<div class={insideDiv({ class: clsx(classes?.insideDiv, size) })} style="width: {_progress.current}%"></div>
🤖 Prompt for AI Agents
In src/lib/progress/Progressbar.svelte at line 38, the class reference uses
classes?.labelInsideDiv instead of the correct classes?.insideDiv, causing
incorrect styling. Replace classes?.labelInsideDiv with classes?.insideDiv in
the clsx function call to apply the proper styles to the inside div element.

@shinokada
Copy link
Collaborator

shinokada commented May 25, 2025

Can we use the following to set ClassValue to all classes?

export type ProgressbarSlots = Partial<{
  [K in keyof typeof progressbar["slots"]]: ClassValue;
}>;

So that uses can use complex inputs. The following is not supposed to be practical, just as an example.

<Progressbar classes={{insideDiv: ["mx-2", loadingArg ? "animate-spin" : "animate-none" , variant && `btn-${variant}`, custom-class], labelInsideDiv: "text-black"}}>10</Progressbar>

If we can use this, then all class should be wrapped with clsx().

<div class={outsideDiv({ class: clsx(classes?.outsideDiv) })}>
    <span class={outsideSpan({ class: clsx(classes?.outsideSpan) })}>{labelOutside}</span>
    <span class={outsideProgress({ class: clsx(classes?.outsideProgress) })}>{formattedProgress}%</span>
</div>

@jjagielka
Copy link
Contributor Author

Yes. That make sense. Good one.

@shinokada shinokada merged commit 7dd865e into themesberg:main May 25, 2025
1 of 2 checks passed
@shinokada
Copy link
Collaborator

We need to get rid of pnpm check errors after this change.

@shinokada
Copy link
Collaborator

What is your idea like Accordion.svelte that uses only one slot, base but it uses activeClass and inactiveClass that used for setContext.

Are you still planning to use classes for this kind of components? There are quite few compoenents uses setContext and getContext.

@shinokada
Copy link
Collaborator

shinokada commented May 27, 2025

Since this change will be BREAKING CHANGE that leads us to v2. How about we change class names for props that will be used to setContext. Something like activeCtxClass. We use Ctx to warn it is used for context and Class tells it is a class. Adapting this, we don't need them to classes and the purpose of prop is clearer.

@shinokada
Copy link
Collaborator

shinokada commented May 27, 2025

We also need to clean up transition related prop names. Some use transitionType and some use transition. And we need to check transitionParam and params.
And at the same time, we can adaput Svelte's preferReducedMotion, https://svelte.dev/docs/svelte/svelte-motion#prefersReducedMotion

@shinokada
Copy link
Collaborator

For your info: I found this line, class?: ClassValue | undefined | null; and this docs that Svelte class accepts ClassValue` already.

@jjagielka
Copy link
Contributor Author

For your info: I found this line, class?: ClassValue | undefined | null; and this docs that Svelte class accepts ClassValue` already.

Yes, and svelte uses clsx internally for handling those ClassValue props.

@jjagielka jjagielka deleted the progress branch May 27, 2025 17:36
@shinokada
Copy link
Collaborator

@jjagielka I'm thinking this inplementation to other components will be a breaking change, we need to start using v2.0.0-next.1 branch/tag and commit future changes to this branch/tag. What do you think?

@jjagielka
Copy link
Contributor Author

Yes. agree. This is a big change that will cause a lot of changes at user's codes.

We can use generic type in types.ts:

// Generic type definition for ComponentVariants
export type ComponentVariants<T extends ((...args: any) => any) & { slots: object }> = (
  VariantProps<T> & { classes?: Partial<{ [K in keyof T["slots"]]: ClassValue }> }
);

then in components it will be only:

export type ProgressbarVariants = ComponentVariants<typeof progressbar>;

@coderabbitai coderabbitai bot mentioned this pull request May 28, 2025
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants