Skip to content

feat: element-plus style optimization #6379

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

Closed

Conversation

wyc001122
Copy link
Contributor

@wyc001122 wyc001122 commented Jun 12, 2025

Description

主要对Element Plus组件的主题色和圆角设置进行优化,实现与项目整体设计风格的统一。
并在 apps/web-ele/src/views/demos/element/index.vue 添加了更多组件便于审查样式。

颜色改动:

  • 改动前

image

  • 改动后

image

圆角统一

  • el-table改动前
    image

  • el-table改动后
    image

  • popper一系列组件改动前
    image

  • popper一系列组件改动后
    image

  • el-description改动前
    image

  • el-description改动后
    image

  • el-pagination改动前
    image

  • el-pagination改动后
    image

  • el-tabs改动前
    image

  • el-tabs改动后
    image

  • popconfirm 改动前
    image

  • popconfirm 改动后
    image

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)

Checklist

ℹ️ Check all checkboxes - this will indicate that you have done everything in accordance with the rules in CONTRIBUTING.

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs:dev command.
  • Run the tests with pnpm test.
  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Expanded the demo page with a wide range of Element Plus UI component examples, including enhanced button styles, tags, descriptions, pagination, tabs, and various popper-related components.
    • Added interactive demos for toggling tag states and displaying message boxes.
  • Style

    • Improved visual consistency by applying unified border-radius styling across multiple UI components.
    • Refined layouts and margins for a cleaner, more cohesive appearance.
  • Chores

    • Updated color token fallbacks for light mode to use slightly different color shades, improving visual clarity in light themes.

Copy link

changeset-bot bot commented Jun 12, 2025

⚠️ No Changeset found

Latest commit: ae277ea

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Jun 13, 2025

Walkthrough

This update expands the Element Plus demo page with a wide range of new UI component examples, introduces a new message box function, and enhances button and tag demonstrations. It also updates CSS variables for color tokens in design tokens and applies consistent border-radius styles to various Element UI components using a CSS variable.

Changes

File(s) Change Summary
apps/web-ele/src/views/demos/element/index.vue Expanded demo page with new UI component examples, new showMessageBox function, enhanced button/tag demos, reactive states, computed properties, and layout refinements.
packages/effects/hooks/src/use-design-tokens.ts Updated fallback CSS variable values for several light color tokens in the design tokens function to use different shade variables.
packages/styles/src/ele/index.css Added border-radius styles using --radius for Element UI components and adjusted borders for tables, descriptions, tabs, and poppers for consistent styling.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DemoPage
    participant ElementPlusComponents
    participant MessageBox

    User->>DemoPage: Interacts with UI (e.g., clicks button)
    DemoPage->>ElementPlusComponents: Render UI components (Buttons, Tags, Tables, etc.)
    User->>DemoPage: Triggers showMessageBox()
    DemoPage->>MessageBox: Show alert dialog
    MessageBox->>DemoPage: Callback on confirm
    DemoPage->>ElementPlusComponents: Display info message
Loading

Suggested reviewers

  • anncwb
  • mynetfan

Poem

A bunny hopped through fields of code,
With buttons bright and tags that glowed.
Rounded corners, colors new,
Tables, tabs, and poppers too!
"Try the message box," it said with glee,
"Element Plus is fun—come see!"
🐇✨


📜 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 8121e95 and ae277ea.

📒 Files selected for processing (1)
  • packages/styles/src/ele/index.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/styles/src/ele/index.css
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: post-update (windows-latest)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: Check (ubuntu-latest)
  • GitHub Check: Check (windows-latest)
  • GitHub Check: Lint (ubuntu-latest)
  • GitHub Check: Lint (windows-latest)

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

🔭 Outside diff range comments (1)
packages/effects/hooks/src/use-design-tokens.ts (1)

208-214: 💡 Verification agent

🧩 Analysis chain

Duplicate shade used for light-7 and light-8

--el-color-*-light-7 and light-8 now both read from the -200 token.
That collapses two distinct tints into the same color and defeats Element Plus’s semantic scale.

Double-check the intended mapping; light-8 is usually lighter than light-7 (-100 or -50 in your scale).

Also applies to: 228-234, 252-258, 272-278, 292-298


🏁 Script executed:

#!/bin/bash
echo "=== light-7 mappings ==="
rg -n --color=never "light-7" -C3 packages/effects/hooks/src/use-design-tokens.ts

echo ""
echo "=== light-8 mappings ==="
rg -n --color=never "light-8" -C3 packages/effects/hooks/src/use-design-tokens.ts

Length of output: 4497


Duplicate -200 mapping for light-7 and light-8

In packages/effects/hooks/src/use-design-tokens.ts, all five palettes (danger, error, primary, success, warning) currently fall back to --*-200 in light mode for both light-7 and light-8, collapsing two distinct tints into one:

  • Danger (lines 205–210)
  • Error (225–230)
  • Primary (249–254)
  • Success (269–274)
  • Warning (289–294)

Typically, light-8 should be one step lighter than light-7 (e.g. --*-100). Please update each light-8 else-branch accordingly. For example:

- '--el-color-danger-light-8': isDark.value
-   ? getCssVariableValue('--destructive-900')
-   : getCssVariableValue('--destructive-200'),
+ '--el-color-danger-light-8': isDark.value
+   ? getCssVariableValue('--destructive-900')
+   : getCssVariableValue('--destructive-100'),

Repeat for error, primary, success, and warning palettes.

🧹 Nitpick comments (2)
packages/styles/src/ele/index.css (2)

10-14: Fix typo in comment

/* propper 圆角 *//* popper 圆角 */.
Minor, but keeping comments accurate avoids confusion.


45-84: Deep selector chain may break on Element-Plus updates

The multi-line .el-descriptions .el-descriptions__table.is-bordered … rules rely on internal DOM/class structure.
Element Plus has changed these internals before; a minor version bump could silently drop the rounding.

Consider targeting the public CSS vars (--el-border-radius-base) or wrapping the component in a utility class instead of overriding each cell.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c0962fe and 5a6bb30.

📒 Files selected for processing (3)
  • apps/web-ele/src/views/demos/element/index.vue (4 hunks)
  • packages/effects/hooks/src/use-design-tokens.ts (5 hunks)
  • packages/styles/src/ele/index.css (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: post-update (windows-latest)
  • GitHub Check: Check (ubuntu-latest)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: Check (windows-latest)

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: 2

🧹 Nitpick comments (1)
apps/web-ele/src/views/demos/element/index.vue (1)

80-86: Unintended array coercion and missing typing in options generation

[idx % 10] creates a 1-element array which is coerced to string ("4"). A simple string template is clearer and avoids needless array creation. Additionally, specifying the item type helps TypeScript catch field name typos later.

-const options = Array.from({ length: 1000 }).map((_, idx) => ({
-  value: `Option ${idx + 1}`,
-  label: `${[idx % 10]}${idx}`,
-}));
+interface SelectOption {
+  value: string;
+  label: string;
+}
+
+const options: SelectOption[] = Array.from({ length: 1000 }, (_, idx) => ({
+  value: `Option ${idx + 1}`,
+  label: `${idx % 10}${idx}`,
+}));

Minor, but it shaves a tiny bit of memory and improves readability & type-safety.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 64695fe and c1587c4.

📒 Files selected for processing (1)
  • apps/web-ele/src/views/demos/element/index.vue (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: Check (windows-latest)
  • GitHub Check: Lint (windows-latest)
  • GitHub Check: Check (ubuntu-latest)
  • GitHub Check: Lint (ubuntu-latest)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: post-update (windows-latest)
🔇 Additional comments (2)
apps/web-ele/src/views/demos/element/index.vue (2)

381-388: ElTreeSelect expects tree-node objects – flat options will not render

ElTreeSelect’s data prop requires nodes with { label, value, children? }.
Passing the flat options array will produce an empty tree.

Consider mapping options into a minimal tree or use ElSelectV2 when a flat list suffices.

const treeData = options.map((o) => ({
  label: o.label,
  value: o.value,
}));

…and bind :data="treeData".


362-367: 🟢 Good choice using ElSelectV2 for 1 000 options

ElSelectV2 provides virtual scrolling, so the large list won’t hurt performance.

Comment on lines 57 to 67
function messageBox() {
ElMessageBox.alert('This is a message', 'Title', {
confirmButtonText: 'OK',
callback: (action: any) => {
ElMessage({
type: 'info',
message: `action: ${action}`,
});
},
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Prefer promise-based handling for ElMessageBox instead of the deprecated callback API

ElMessageBox.alert already returns a Promise that resolves with the button action ('confirm' | 'cancel' | 'close'). Mixing the callback style with the Promise return value can lead to double-handling or unhandled-rejection noise when the user presses Esc / clicks the close icon.

-function messageBox() {
-  ElMessageBox.alert('This is a message', 'Title', {
-    confirmButtonText: 'OK',
-    callback: (action: any) => {
-      ElMessage({
-        type: 'info',
-        message: `action: ${action}`,
-      });
-    },
-  });
-}
+import type { MessageBoxAction } from 'element-plus';
+
+function messageBox() {
+  ElMessageBox.alert('This is a message', 'Title', {
+    confirmButtonText: 'OK',
+  }).then((action: MessageBoxAction) => {
+    ElMessage({
+      type: 'info',
+      message: `action: ${action}`,
+    });
+  });
+}

Benefits: cleaner flow, typed action, consistent with Element-Plus docs going forward.

📝 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
function messageBox() {
ElMessageBox.alert('This is a message', 'Title', {
confirmButtonText: 'OK',
callback: (action: any) => {
ElMessage({
type: 'info',
message: `action: ${action}`,
});
},
});
}
import type { MessageBoxAction } from 'element-plus';
function messageBox() {
ElMessageBox.alert('This is a message', 'Title', {
confirmButtonText: 'OK',
}).then((action: MessageBoxAction) => {
ElMessage({
type: 'info',
message: `action: ${action}`,
});
});
}
🤖 Prompt for AI Agents
In apps/web-ele/src/views/demos/element/index.vue around lines 57 to 67, the
messageBox function uses the deprecated callback API for ElMessageBox.alert.
Refactor the function to use the Promise-based API by removing the callback
option and instead chaining a .then() handler on the returned Promise to handle
the action. This will provide a cleaner flow, properly typed action, and avoid
potential double-handling or unhandled rejections.

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

♻️ Duplicate comments (1)
apps/web-ele/src/views/demos/element/index.vue (1)

57-67: ElMessageBox.alert still uses the deprecated callback API – please switch to the Promise interface
This exact point was raised in a previous review and remains unresolved. Switching removes double-handling risk and gives you a typed action.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c1587c4 and 5aaac0e.

📒 Files selected for processing (1)
  • apps/web-ele/src/views/demos/element/index.vue (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Lint (windows-latest)
  • GitHub Check: Check (windows-latest)
  • GitHub Check: Check (ubuntu-latest)
  • GitHub Check: Lint (ubuntu-latest)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: post-update (windows-latest)
🔇 Additional comments (1)
apps/web-ele/src/views/demos/element/index.vue (1)

383-389: Verify ElTreeSelect data shape

ElTreeSelect expects hierarchical nodes with label, value, and optional children.
The flat options array you pass lacks children, so expanding nodes will show nothing.
If only a flat list is intended, consider using ElSelect instead or transform the data accordingly.

Comment on lines 80 to 85
const type1 = ref();
const date = ref();
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${[idx % 10]}${idx}`,
}));
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add explicit types & fix redundant template‐string construction

  1. ref() without a generic defaults to Ref<undefined>, which later forces any casting when bound to Element-Plus models.
  2. The label template literal currently does ${[idx % 10]} – the array wrapper is unnecessary and yields the same string via the array’s toString().
-const type1 = ref();
-const date = ref();
-const options = Array.from({ length: 1000 }).map((_, idx) => ({
-  value: `Option ${idx + 1}`,
-  label: `${[idx % 10]}${idx}`,
-}));
+const type1 = ref<string | null>(null);
+const date = ref<Date | null>(null);
+const options = Array.from({ length: 1000 }).map((_, idx) => ({
+  value: `Option ${idx + 1}`,
+  label: `${idx % 10}${idx}`,
+}));

Benefits: keeps strict-type safety and avoids the small string-construction inefficiency.

📝 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
const type1 = ref();
const date = ref();
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${[idx % 10]}${idx}`,
}));
const type1 = ref<string | null>(null);
const date = ref<Date | null>(null);
const options = Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`,
label: `${idx % 10}${idx}`,
}));
🤖 Prompt for AI Agents
In apps/web-ele/src/views/demos/element/index.vue around lines 80 to 85, the
refs type1 and date are declared without explicit types, causing them to default
to Ref<undefined> and leading to any casting issues later. Also, the label
template string uses an unnecessary array wrapper around idx % 10. Fix this by
specifying explicit generic types for the refs to match their intended use and
simplify the label template string by removing the array wrapper, directly
embedding idx % 10.

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: 0

♻️ Duplicate comments (2)
apps/web-ele/src/views/demos/element/index.vue (2)

125-136: Callback API for ElMessageBox.alert was already flagged – please migrate to the Promise-based variant

Previous review pointed out that the callback style is deprecated and can lead to double handling/unhandled rejections.
Refactor to:

-import type { MessageBoxAction } from 'element-plus'

-const showMessageBox = () => {
-  ElMessageBox.alert('This is a message', 'Title', {
-    confirmButtonText: 'OK',
-    callback: (action: any) => {
-      ElMessage({ type: 'info', message: `action: ${action}` })
-    },
-  })
-}
+import type { MessageBoxAction } from 'element-plus'
+
+const showMessageBox = () => {
+  ElMessageBox.alert('This is a message', 'Title', {
+    confirmButtonText: 'OK',
+  }).then((action: MessageBoxAction) => {
+    ElMessage({ type: 'info', message: `action: ${action}` })
+  })
+}

Keeps the flow cleaner and fully typed.


78-85: 🛠️ Refactor suggestion

date is typed as string but is bound to multiple date/time pickers

ElDatePicker, ElTimePicker, and ElTimeSelect expect Date / number / dayjs values, not plain strings.
Storing heterogeneous types in the same ref can introduce subtle runtime coercion issues.

-const date = ref<string>('');
+const date = ref<Date | null>(null);

You’ll need to adjust the initial model and clear behaviour accordingly.

🧹 Nitpick comments (1)
apps/web-ele/src/views/demos/element/index.vue (1)

88-93: Avoid recreating 1 000-item array on every computed re-evaluation

selectOptions has no reactive dependencies, but each access still allocates a new array.
Extract it as a module-level constant or wrap in shallowRef to freeze the reference.

-const selectOptions = computed(() =>
-  Array.from({ length: 1000 }).map((_, idx) => ({
-    value: `Option ${idx + 1}`,
-    label: `${idx % 10}${idx}`,
-  })),
-);
+const selectOptions = shallowRef(
+  Array.from({ length: 1000 }).map((_, idx) => ({
+    value: `Option ${idx + 1}`,
+    label: `${idx % 10}${idx}`,
+  })),
+);

Reduces unnecessary allocations and keeps change detection cheap.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5aaac0e and 8121e95.

📒 Files selected for processing (2)
  • apps/web-ele/src/views/demos/element/index.vue (1 hunks)
  • packages/styles/src/ele/index.css (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/styles/src/ele/index.css
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: Check (windows-latest)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Check (ubuntu-latest)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: post-update (windows-latest)
🔇 Additional comments (1)
apps/web-ele/src/views/demos/element/index.vue (1)

486-494: Flat selectOptions fed into ElTreeSelect – verify expected structure

ElTreeSelect expects a tree-shaped list with label, value, and optional children.
Passing the 1-level selectOptions array (label/value only) may silently break search or expansion features.

Please confirm via manual test or convert the data:

const treeOptions = selectOptions.value.map(o => ({ ...o, children: [] }))

If a flat list is intended, consider using ElSelectV2 instead.

@wyc001122 wyc001122 closed this Jun 13, 2025
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.

1 participant