refactor(module:style): remove standalone RTL styles - #9892
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
There was a problem hiding this comment.
Pull request overview
This PR refactors component LESS to eliminate standalone rtl.less files by migrating directional rules into primary style sheets using CSS logical properties (e.g., margin-inline-*, inset-inline-*, text-align: start/end) and limited :dir(rtl) overrides where mirroring is still required.
Changes:
- Removed many component-level
rtl.less(and related patch RTL blocks) and dropped their imports fromindex.lessfiles. - Replaced left/right/top/bottom directional declarations with CSS logical properties across component styles and shared mixins/themes.
- Introduced
:dir(rtl)selectors for the remaining RTL-specific mirroring cases (e.g., some arrows/indicators/animations).
Reviewed changes
Copilot reviewed 141 out of 141 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| components/upload/style/rtl.less | Removed standalone RTL stylesheet. |
| components/upload/style/patch.less | Removed standalone RTL patch rule. |
| components/upload/style/index.less | Switched to logical properties; removed RTL import. |
| components/typography/style/rtl.less | Removed standalone RTL stylesheet. |
| components/typography/style/index.less | Switched to logical properties; removed RTL import. |
| components/tree/style/rtl.less | Removed standalone RTL stylesheet. |
| components/tree/style/mixin.less | Converted positional/margin rules to logical properties. |
| components/tree/style/index.less | Removed RTL import. |
| components/tree-select/style/index.less | Replaced *-rtl selectors with :dir(rtl) where needed. |
| components/transfer/style/rtl.less | Removed standalone RTL stylesheet. |
| components/transfer/style/index.less | Switched to logical properties; removed RTL import. |
| components/tooltip/style/rtl.less | Removed standalone RTL stylesheet. |
| components/tooltip/style/index.less | Removed RTL import. |
| components/timeline/style/rtl.less | Removed standalone RTL stylesheet. |
| components/timeline/style/index.less | Switched to logical properties; removed RTL import. |
| components/tag/style/rtl.less | Removed standalone RTL stylesheet. |
| components/tag/style/index.less | Switched to logical properties; removed RTL import. |
| components/tabs/style/rtl.less | Removed standalone RTL stylesheet. |
| components/tabs/style/patch.less | Removed RTL-only patch rules. |
| components/tabs/style/index.less | Removed RTL import; adjusted layout using logical properties. |
| components/tabs/style/card.less | Converted margins to logical properties. |
| components/tabs/style/card-style.rtl.less | Removed standalone RTL stylesheet. |
| components/tabs/style/card-style.less | Converted margins to logical properties; removed RTL import. |
| components/table/style/rtl.less | Removed standalone RTL stylesheet. |
| components/table/style/patch.less | Removed RTL-only patch rule. |
| components/table/style/index.less | Switched to logical properties; added :dir(rtl) rules for a few cases; removed RTL import. |
| components/switch/style/rtl.less | Removed standalone RTL stylesheet. |
| components/switch/style/index.less | Switched to logical properties; removed RTL import. |
| components/style/themes/variable.less | Removed unused RTL-specific tabs variable. |
| components/style/themes/default.less | Removed unused RTL-specific tabs variable. |
| components/style/mixins/compact-item.less | Simplified compact-item RTL handling via logical properties. |
| components/steps/style/rtl.less | Removed standalone RTL stylesheet. |
| components/steps/style/index.less | Moved RTL handling inline using :dir(rtl); removed RTL import. |
| components/statistic/style/rtl.less | Removed standalone RTL stylesheet. |
| components/statistic/style/index.less | Switched to logical properties; removed RTL import. |
| components/splitter/style/rtl.less | Removed standalone RTL stylesheet. |
| components/splitter/style/index.less | Removed RTL import. |
| components/spin/style/rtl.less | Removed standalone RTL stylesheet. |
| components/spin/style/index.less | Removed RTL import. |
| components/space/style/rtl.less | Removed standalone RTL stylesheet. |
| components/space/style/index.less | Removed RTL import. |
| components/slider/style/rtl.less | Removed standalone RTL stylesheet. |
| components/slider/style/index.less | Switched to logical properties; removed RTL import. |
| components/skeleton/style/rtl.less | Removed standalone RTL stylesheet. |
| components/skeleton/style/index.less | Switched to logical properties; added :dir(rtl) animation override; removed RTL import. |
| components/select/style/rtl.less | Removed standalone RTL stylesheet. |
| components/select/style/index.less | Removed RTL import. |
| components/segmented/style/rtl.less | Removed standalone RTL stylesheet. |
| components/segmented/style/index.less | Switched to logical properties; removed RTL import. |
| components/result/style/rtl.less | Removed standalone RTL stylesheet. |
| components/result/style/index.less | Switched to logical properties; removed RTL import. |
| components/rate/style/rtl.less | Removed standalone RTL stylesheet. |
| components/rate/style/index.less | Switched to logical properties; removed RTL import. |
| components/radio/style/rtl.less | Removed standalone RTL stylesheet. |
| components/radio/style/index.less | Switched to logical properties; removed RTL import. |
| components/progress/style/rtl.less | Removed standalone RTL stylesheet. |
| components/progress/style/index.less | Switched to logical properties; removed RTL import. |
| components/popover/style/rtl.less | Removed standalone RTL stylesheet. |
| components/popover/style/index.less | Switched to logical properties; removed RTL import. |
| components/pagination/style/rtl.less | Removed standalone RTL stylesheet. |
| components/pagination/style/index.less | Switched to logical properties; removed RTL import. |
| components/page-header/style/rtl.less | Removed standalone RTL stylesheet. |
| components/page-header/style/index.less | Switched to logical properties; removed RTL import. |
| components/notification/style/rtl.less | Removed standalone RTL stylesheet. |
| components/notification/style/index.less | Switched to logical properties; removed RTL import. |
| components/modal/style/rtl.less | Removed standalone RTL stylesheet. |
| components/modal/style/modal.less | Converted close/footer positioning to logical properties. |
| components/modal/style/index.less | Removed RTL import; reorganized prefix vars. |
| components/modal/style/confirm.less | Converted float/margins/text-align to logical properties. |
| components/message/style/rtl.less | Removed standalone RTL stylesheet. |
| components/message/style/index.less | Switched to logical properties; removed RTL import. |
| components/menu/style/rtl.less | Removed standalone RTL stylesheet. |
| components/menu/style/patch.less | Replaced directional offsets with logical inset properties. |
| components/menu/style/index.less | Inlined RTL handling via :dir(rtl); removed RTL import. |
| components/mention/style/rtl.less | Removed standalone RTL stylesheet. |
| components/mention/style/index.less | Removed RTL import. |
| components/list/style/rtl.less | Removed standalone RTL stylesheet. |
| components/list/style/responsive.less | Converted responsive margins to logical properties. |
| components/list/style/index.less | Switched to logical properties; removed RTL import. |
| components/layout/style/rtl.less | Removed standalone RTL stylesheet. |
| components/layout/style/index.less | Removed RTL import. |
| components/input/style/search-input.less | Converted borders/radius/margins to logical properties; removed RTL compact special-case block. |
| components/input/style/rtl.less | Removed standalone RTL stylesheet. |
| components/input/style/patch.less | Removed RTL-only patch rules. |
| components/input/style/mixin.less | Converted many border-radius/border-width/margins/floats to logical properties. |
| components/input/style/index.less | Removed RTL import; converted float/position to logical properties. |
| components/input/style/allow-clear.less | Converted margins/positioning to logical properties. |
| components/input/style/affix.less | Converted spacing to logical properties. |
| components/input-number/style/rtl.less | Removed standalone RTL stylesheet. |
| components/input-number/style/index.less | Switched to logical properties; removed RTL import. |
| components/grid/style/rtl.less | Removed standalone RTL stylesheet. |
| components/grid/style/index.less | Removed RTL import. |
| components/form/style/rtl.less | Removed standalone RTL stylesheet. |
| components/form/style/index.less | Switched to logical properties; inlined RTL overrides with :dir(rtl); removed RTL import. |
| components/float-button/style/index.less | Removed RTL direction-only rules. |
| components/empty/style/rtl.less | Removed standalone RTL stylesheet. |
| components/empty/style/index.less | Removed RTL import. |
| components/dropdown/style/rtl.less | Removed standalone RTL stylesheet. |
| components/dropdown/style/patch.less | Removed RTL-only arrow rotation patch. |
| components/dropdown/style/index.less | Switched to logical properties; removed RTL import. |
| components/drawer/style/rtl.less | Removed standalone RTL stylesheet. |
| components/drawer/style/index.less | Removed RTL import; reorganized prefix var. |
| components/drawer/style/drawer.less | Converted close spacing to logical properties. |
| components/divider/style/rtl.less | Removed standalone RTL stylesheet. |
| components/divider/style/index.less | Replaced RTL file with :dir(rtl) rules; removed RTL import. |
| components/descriptions/style/rtl.less | Removed standalone RTL stylesheet. |
| components/descriptions/style/index.less | Converted spacing/borders to logical properties; removed RTL import. |
| components/date-picker/style/rtl.less | Removed standalone RTL stylesheet. |
| components/date-picker/style/panel.less | Converted range/pseudo positioning to logical properties. |
| components/date-picker/style/index.less | Converted padding/margins/positioning to logical properties; removed RTL import. |
| components/comment/style/rtl.less | Removed standalone RTL stylesheet. |
| components/comment/style/index.less | Switched to logical properties; removed RTL import. |
| components/collapse/style/index.less | Removed RTL direction-only rule. |
| components/checkbox/style/rtl.less | Removed standalone RTL stylesheet. |
| components/checkbox/style/mixin.less | Converted margins to logical properties. |
| components/checkbox/style/index.less | Removed RTL import. |
| components/cascader/style/rtl.less | Removed standalone RTL stylesheet. |
| components/cascader/style/index.less | Switched to logical properties; removed RTL import. |
| components/carousel/style/rtl.less | Removed standalone RTL stylesheet. |
| components/carousel/style/index.less | Converted layout to logical properties; added :dir(rtl) arrow overrides; removed RTL import. |
| components/card/style/patch.less | Removed RTL-only skeleton header padding override. |
| components/card/style/index.less | Converted spacing/borders to logical properties; removed RTL-only blocks. |
| components/calendar/style/rtl.less | Removed standalone RTL stylesheet. |
| components/calendar/style/index.less | Switched to logical properties; removed RTL import. |
| components/button/style/space-compact.less | Removed RTL-only compact-item special cases. |
| components/button/style/rtl.less | Removed standalone RTL stylesheet. |
| components/button/style/mixin.less | Converted button-group spacing/radius to logical properties. |
| components/button/style/index.less | Converted spacing/borders to logical properties; removed RTL import. |
| components/breadcrumb/style/rtl.less | Removed standalone RTL stylesheet. |
| components/breadcrumb/style/patch.less | Removed RTL-only float override. |
| components/breadcrumb/style/index.less | Switched to logical properties; removed RTL import. |
| components/badge/style/rtl.less | Removed standalone RTL stylesheet. |
| components/badge/style/ribbon.less | Converted placement positioning to logical properties. |
| components/badge/style/index.less | Converted positioning to logical properties; added :dir(rtl) animation overrides; removed RTL import. |
| components/avatar/style/rtl.less | Removed standalone RTL stylesheet. |
| components/avatar/style/index.less | Removed RTL import. |
| components/avatar/style/group.less | Converted spacing to logical properties. |
| components/anchor/style/rtl.less | Removed standalone RTL stylesheet. |
| components/anchor/style/index.less | Converted positioning to logical properties; added :dir(rtl) transform override; removed RTL import. |
| components/alert/style/rtl.less | Removed standalone RTL stylesheet. |
| components/alert/style/index.less | Converted spacing to logical properties; removed RTL import. |
Suppressed comments (4)
components/steps/style/index.less:359
:dir(rtl)is nested under&::afterhere, which will compile to...::after:dir(rtl)and be ignored by CSS parsers. Move:dir(rtl)before the pseudo-element.
components/steps/style/index.less:446- Same issue: nesting
:dir(rtl)under&::afterwill compile to an invalid...::after:dir(rtl)selector, so this RTL spacing tweak won’t apply.
components/steps/style/index.less:473 - Same invalid selector pattern:
&::after { &:dir(rtl) { ... } }will become...::after:dir(rtl)and won’t match. Use&:dir(rtl)::afterinstead so the hover-area expansion works in RTL.
components/menu/style/index.less:792 :dir(rtl)is nested under&::after, which compiles to...::after:dir(rtl)and will be ignored. This RTL arrow-segment transform needs:dir(rtl)before the pseudo-element.
| &::after { | ||
| &:dir(rtl) { | ||
| right: 100%; | ||
| left: auto; | ||
| } | ||
| } |
| &::before { | ||
| &:dir(rtl) { | ||
| transform: rotate(-45deg) translateY(-2px); | ||
| } | ||
| } |
| &::after { | ||
| &:dir(rtl) { | ||
| right: auto; | ||
| left: 0; | ||
| } | ||
| } |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #9892 +/- ##
=======================================
Coverage 89.01% 89.02%
=======================================
Files 581 581
Lines 24145 24148 +3
Branches 4725 4725
=======================================
+ Hits 21492 21497 +5
Misses 1674 1674
+ Partials 979 977 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
那奇怪了,我本地再次验证了下样式没问题
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 157 out of 157 changed files in this pull request and generated no new comments.
Suppressed comments (4)
components/tooltip/style/index.less:69
- The Tooltip component still adds the
.ant-tooltip-rtlclass when Directionality isrtl, but the stylesheet no longer defines any RTL rule (the removedrtl.lesspreviously setdirection: rtl). Without restoring this, the-rtlclass becomes a no-op and RTL layouts may regress when consumers rely on NG-ZORRO’s class-based RTL (without a globaldir="rtl"attribute).
components/collapse/style/index.less:15 NzCollapseComponentstill toggles the.ant-collapse-rtlclass, but the style no longer setsdirection: rtlfor that class. Unless consumers also set adir="rtl"attribute, the RTL mode becomes a no-op and RTL-specific layout/flow can regress.
components/table/style/index.less:787- The table implementation uses class-based RTL (
.ant-table-wrapper-rtl/.ant-table-rtl), but these new rules rely on:dir(rtl)which only matches when the computeddirectionis RTL (typically via adir="rtl"attribute or a CSSdirectiondeclaration). With the standalonertl.lessremoved, these selectors may never match, regressing pagination alignment and expand-icon transforms in RTL.
components/steps/style/index.less:256 NzStepsComponentapplies the.ant-steps-rtlclass based onDirectionality, but the refactor switched the RTL rules to:dir(rtl)selectors without ensuring the steps subtree actually hasdirection: rtl. If the app doesn’t set a globaldir="rtl", these:dir(rtl)rules won’t match and RTL styles will not apply. Restoringdirection: rtlfor.ant-steps-rtlkeeps the new logical-property rules working while preserving the existing class-based RTL contract.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 168 out of 168 changed files in this pull request and generated no new comments.
Suppressed comments (9)
components/tooltip/style/index.less:69
ant-tooltip-rtlis still applied by the component (see tooltip.ts), but the LESS rule that setsdirection: rtlwas removed along with@import './rtl'. This will prevent RTL tooltips rendered in an LTR document from switching direction.
components/steps/style/index.less:289:dir(rtl)is nested under&::after, which compiles to a selector like...::after:dir(rtl)(invalid because pseudo-elements must be last). The RTL override for the connector will not apply.
components/menu/style/index.less:786:dir(rtl)is nested inside&::before, which compiles to...::before:dir(rtl)(invalid because pseudo-elements must be last). The RTL rotation for submenu arrows will not apply.
components/menu/style/index.less:806:dir(rtl)is nested under&::after, which compiles to an invalid::after:dir(rtl)selector. This will prevent the RTL active-indicator positioning override from being applied.
components/steps/style/index.less:447:dir(rtl)nested inside&::aftercompiles to...::after:dir(rtl)(invalid selector). The RTL margin override for progress-dot tails will not apply.
components/steps/style/index.less:363- Same selector issue as above: nesting
:dir(rtl)inside&::afterproduces an invalid::after:dir(rtl)selector, so the navigation arrow RTL transform/positioning won’t apply.
components/steps/style/index.less:474 :dir(rtl)is nested under&::after, producing an invalid::after:dir(rtl)selector. The RTL hover-area positioning for the dot will not apply.
components/menu/style/index.less:792- Same invalid selector issue: nesting
:dir(rtl)under&::aftercompiles to...::after:dir(rtl), so the RTL arrow rotation won’t apply.
components/badge/style/index.less:204 - In RTL mode the old styles explicitly forced badge count/dot/custom component to
direction: ltrand adjustedtransform-originto0% 0%to keep numbers and zoom animations consistent. The refactor keepstransformbut dropsdirectionandtransform-origin, which changes RTL rendering/animation behavior.
.@{badge-prefix-cls}:not(.@{badge-prefix-cls}-not-a-wrapper).@{badge-prefix-cls}-rtl {
.@{badge-prefix-cls}-count,
.@{badge-prefix-cls}-dot,
.@{number-prefix-cls}-custom-component {
transform: translate(-50%, -50%);
| &-primary { | ||
| .btn-primary(); | ||
|
|
||
| .@{btn-prefix-cls}-group &:not(:first-child):not(:last-child) { |
There was a problem hiding this comment.
button group was removed in v20
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 168 out of 168 changed files in this pull request and generated no new comments.
Suppressed comments (4)
components/menu/style/index.less:786
- These nested selectors compile to
...::before:dir(rtl)/...::after:dir(rtl), but pseudo-elements must be last in the selector, so the RTL transforms won’t apply. Rewrite as&:dir(rtl)::before/&:dir(rtl)::after(or wrap&::beforeinside an outer&:dir(rtl)block).
components/menu/style/index.less:806 - Same selector-order issue here:
&::after { &:dir(rtl) { ... } }compiles to...::after:dir(rtl)which is invalid. Use&:dir(rtl)::afterso the RTL positioning actually applies.
components/steps/style/index.less:289 &::after { &:dir(rtl) { ... } }compiles to...::after:dir(rtl)(invalid, since pseudo-elements must be last). This means the RTL-specific positioning won’t apply.
Update this (and the other similar occurrences later in this file, e.g. around the navigation connector arrow and progress-dot ::after rules) to use &:dir(rtl)::after instead.
components/tooltip/style/index.less:69
ant-tooltip-rtlis still added by the component (seetooltip.ts), but the RTL stylesheet import was removed and no.ant-tooltip-rtl { direction: rtl; }rule remains inindex.less. This makes RTL tooltips rely on externaldirpropagation and breaks the previous contract of theant-tooltip-rtlclass.
Add the missing RTL base rule back into index.less (and remove the stray trailing comment at EOF if it was accidental).
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 282 out of 282 changed files in this pull request and generated no new comments.
Suppressed comments (3)
components/dropdown/style/index.less:194
- The submenu expand arrow icon is no longer mirrored for RTL after removing the standalone RTL stylesheet. Without mirroring, submenu arrows will still point to the inline-end direction in RTL, which is visually incorrect.
components/input-number/style/index.less:20 - In RTL mode the input element is being set to
direction: rtl, but numeric inputs generally needdirection: ltr(as before) to avoid bidi/caret issues while still aligning to the RTL edge. With the current rules, typing/editing numbers can behave incorrectly in RTL locales.
components/badge/style/rtl.less:10 - RTL badge positioning removed the previous
direction: ltroverride for the badge count/custom component. Without forcing LTR for the number container, digits/caret/animation can be affected by RTL bidi rules in some locales.
.@{badge-prefix-cls}-count,
.@{badge-prefix-cls}-dot,
.@{number-prefix-cls}-custom-component {
transform: translate(-50%, -50%);
}
remove LESS vars `anchor-link-top` `anchor-link-left` and `anchor-link-padding`, please use `anchor-link-padding-block` and `anchor-link-padding-inline-start` instead
a5f4719 to
f2abff5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 282 out of 282 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
components/dropdown/style/index.less:194
- RTL dropdown submenus previously flipped the submenu arrow icon (so it points toward the opening direction). After removing
rtl.less, there is no remaining RTL-specific transform for.ant-dropdown-menu-submenu-arrow-icon, so in RTL the arrow will still point right.
| &-primary { | ||
| .btn-primary(); | ||
|
|
||
| .@{btn-prefix-cls}-group &:not(:first-child):not(:last-child) { | ||
| border-right-color: @btn-group-border; | ||
| border-left-color: @btn-group-border; | ||
|
|
||
| &:disabled { | ||
| border-color: @btn-default-border; | ||
| } | ||
| } | ||
|
|
||
| .@{btn-prefix-cls}-group &:first-child { | ||
| &:not(:last-child) { | ||
| border-right-color: @btn-group-border; | ||
|
|
||
| &[disabled] { | ||
| border-right-color: @btn-default-border; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| .@{btn-prefix-cls}-group &:last-child:not(:first-child), | ||
| .@{btn-prefix-cls}-group & + & { | ||
| border-left-color: @btn-group-border; | ||
|
|
||
| &[disabled] { | ||
| border-left-color: @btn-default-border; | ||
| } | ||
| } | ||
| } |
| &-rtl { | ||
| direction: rtl; | ||
|
|
||
| .@{input-number-prefix-cls}-input { | ||
| direction: rtl; | ||
| } | ||
| } |





PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Component styles are split between their primary LESS files and dedicated
rtl.lessfiles. RTL support relies on-rtlclass selectors, which duplicates directional layout declarations across components.Issue Number: #5453
What is the new behavior?
Directional layout rules are now expressed with CSS logical properties in the primary component styles. All standalone RTL style files and imports are removed. The few rules that must mirror an icon or animation use
:dir(rtl)instead of a-rtlclass selector.This keeps the rendered behavior and public API unchanged while reducing duplicated RTL-specific style code.
Does this PR introduce a breaking change?
Other information