diff --git a/packages/react/.storybook/preview.js b/packages/react/.storybook/preview.js index e74c0cf17d18..3ba18aeb89bc 100644 --- a/packages/react/.storybook/preview.js +++ b/packages/react/.storybook/preview.js @@ -306,20 +306,23 @@ const parameters = { const decorators = [ (Story, context) => { const { layoutDensity, layoutSize, locale, dir, theme } = context.globals; + const [randomKey, setRandomKey] = React.useState(1); React.useEffect(() => { document.documentElement.setAttribute('data-carbon-theme', theme); }, [theme]); - React.useEffect(() => { + React.useLayoutEffect(() => { document.documentElement.lang = locale; document.documentElement.dir = dir; + // Need to set random key to recalculate Popover coordinates + setRandomKey(Math.floor(Math.random() * 10)); }, [locale, dir]); return ( - + ); diff --git a/packages/react/src/components/DataTable/stories/DataTable-batch-actions.stories.js b/packages/react/src/components/DataTable/stories/DataTable-batch-actions.stories.js index 27d7642f7624..ecca479c61b3 100644 --- a/packages/react/src/components/DataTable/stories/DataTable-batch-actions.stories.js +++ b/packages/react/src/components/DataTable/stories/DataTable-batch-actions.stories.js @@ -146,7 +146,6 @@ export const Default = () => ( @@ -247,7 +246,6 @@ export const Playground = (args) => ( diff --git a/packages/react/src/components/Popover/Popover.stories.js b/packages/react/src/components/Popover/Popover.stories.js index bdfffc3beecd..bf2dbda70843 100644 --- a/packages/react/src/components/Popover/Popover.stories.js +++ b/packages/react/src/components/Popover/Popover.stories.js @@ -229,9 +229,10 @@ export const AutoAlign = () => {
@@ -260,7 +261,14 @@ export const AutoAlign = () => {

-
+
@@ -274,7 +282,13 @@ export const AutoAlign = () => {
+ style={{ + position: 'absolute', + insetBlockEnd: 0, + insetInlineEnd: 0, + marginBlock: '3rem', + marginInline: '3rem', + }}>
@@ -287,7 +301,14 @@ export const AutoAlign = () => {
-
+
diff --git a/packages/react/src/components/Text/Text.tsx b/packages/react/src/components/Text/Text.tsx index 9f2785deb8f8..d5c3aedabe43 100644 --- a/packages/react/src/components/Text/Text.tsx +++ b/packages/react/src/components/Text/Text.tsx @@ -22,7 +22,7 @@ export type TextProps = PolymorphicProps< function Text({ as, children, - dir = 'auto', + dir, ...rest }: TextProps) { // TODO: Update with context typing once its been converted to TS diff --git a/packages/react/src/components/TreeView/TreeNode.js b/packages/react/src/components/TreeView/TreeNode.js index 32fe2d43a1f5..b29a85c77f15 100644 --- a/packages/react/src/components/TreeView/TreeNode.js +++ b/packages/react/src/components/TreeView/TreeNode.js @@ -161,8 +161,8 @@ export default function TreeNode({ }; if (currentNodeLabel.current) { - currentNodeLabel.current.style.marginLeft = `-${calcOffset()}rem`; - currentNodeLabel.current.style.paddingLeft = `${calcOffset()}rem`; + currentNodeLabel.current.style.marginInlineStart = `-${calcOffset()}rem`; + currentNodeLabel.current.style.paddingInlineStart = `${calcOffset()}rem`; } // sync props and state diff --git a/packages/styles/scss/components/accordion/_accordion.scss b/packages/styles/scss/components/accordion/_accordion.scss index 95b014705c94..6f564e1c4c44 100644 --- a/packages/styles/scss/components/accordion/_accordion.scss +++ b/packages/styles/scss/components/accordion/_accordion.scss @@ -149,9 +149,8 @@ $content-padding: 0 0 0 $spacing-05 !default; @include type-style('body-01'); z-index: 1; - margin: $title-margin; inline-size: 100%; - padding-inline-end: $spacing-05; + padding-inline-start: $spacing-05; text-align: start; } @@ -293,6 +292,17 @@ $content-padding: 0 0 0 $spacing-05 !default; .#{$prefix}--accordion__item--active .#{$prefix}--accordion__arrow { @include high-contrast-mode('icon-fill'); } + + // RTL overrides + [dir='rtl'] .#{$prefix}--accordion--start .#{$prefix}--accordion__heading { + padding-inline-end: 0; + padding-inline-start: layout.density('padding-inline'); + } + + [dir='rtl'] .#{$prefix}--accordion--start .#{$prefix}--accordion__title { + margin-inline-end: 0; + padding-inline-start: 0; + } } @mixin -content-visible { diff --git a/packages/styles/scss/components/breadcrumb/_breadcrumb.scss b/packages/styles/scss/components/breadcrumb/_breadcrumb.scss index c1ef8792b13a..4c56850d1bba 100644 --- a/packages/styles/scss/components/breadcrumb/_breadcrumb.scss +++ b/packages/styles/scss/components/breadcrumb/_breadcrumb.scss @@ -146,6 +146,12 @@ inset-inline-start: $caret-size * 2; } + [dir='rtl'] + .#{$prefix}--breadcrumb-menu-options.#{$prefix}--overflow-menu-options::after { + inset-inline-end: $caret-size * 2; + inset-inline-start: initial; + } + // Skeleton State .#{$prefix}--breadcrumb.#{$prefix}--skeleton .#{$prefix}--link { @include skeleton; diff --git a/packages/styles/scss/components/button/_button.scss b/packages/styles/scss/components/button/_button.scss index c46d5e602ee9..f68157c4eb60 100644 --- a/packages/styles/scss/components/button/_button.scss +++ b/packages/styles/scss/components/button/_button.scss @@ -403,4 +403,9 @@ .#{$prefix}--btn--ghost.#{$prefix}--btn--icon-only .#{$prefix}--btn__icon { @include high-contrast-mode('icon-fill'); } + + // RTL overrides + [dir='rtl'] .#{$prefix}--btn-set .#{$prefix}--btn:not(:focus) { + box-shadow: convert.to-rem(1px) 0 0 0 $button-separator; + } } diff --git a/packages/styles/scss/components/checkbox/_checkbox.scss b/packages/styles/scss/components/checkbox/_checkbox.scss index 8e6fbf333775..1c8b0dae675f 100644 --- a/packages/styles/scss/components/checkbox/_checkbox.scss +++ b/packages/styles/scss/components/checkbox/_checkbox.scss @@ -115,9 +115,9 @@ inline-size: convert.to-rem(9px); inset-block-start: convert.to-rem(7.5px); inset-inline-start: convert.to-rem(7px); - margin-block-start: convert.to-rem(-3px) #{'/*rtl:0rem*/'}; + margin-block-start: convert.to-rem(-3px); transform: scale(0) rotate(-45deg); - transform-origin: bottom right #{'/*rtl:center*/'}; + transform-origin: bottom right; } //---------------------------------------------- @@ -136,7 +136,7 @@ // Display the check .#{$prefix}--checkbox:checked + .#{$prefix}--checkbox-label::after, .#{$prefix}--checkbox-label[data-contained-checkbox-state='true']::after { - transform: scale(1) rotate(-45deg) #{'/*!rtl:scale(1.2) rotate3d(.5, 1, 0, 158deg)*/'}; + transform: scale(1) rotate(-45deg); } // Indeterminate symbol @@ -345,4 +345,19 @@ .#{$prefix}--checkbox--inline { position: relative; } + + // RTL overrides + [dir='rtl'] .#{$prefix}--checkbox-label::after { + margin-block-start: 0; + margin-inline-start: convert.to-rem(-1px); + transform-origin: center; + } + + [dir='rtl'] + .#{$prefix}--checkbox:checked + + .#{$prefix}--checkbox-label::after, + [dir='rtl'] + .#{$prefix}--checkbox-label[data-contained-checkbox-state='true']::after { + transform: scale(1.2) rotate3d(0.5, 1, 0, 158deg); + } } diff --git a/packages/styles/scss/components/data-table/_data-table.scss b/packages/styles/scss/components/data-table/_data-table.scss index 808f5f1305ba..602bef2d0e0e 100644 --- a/packages/styles/scss/components/data-table/_data-table.scss +++ b/packages/styles/scss/components/data-table/_data-table.scss @@ -43,8 +43,10 @@ // Table title text //---------------------------------------------------------------------------- .#{$prefix}--data-table-header { - padding: $spacing-05 0 $spacing-06 $spacing-05; background: $layer; + padding-block-end: $spacing-06; + padding-block-start: $spacing-05; + padding-inline: $spacing-05; } .#{$prefix}--data-table-header__title { @@ -86,7 +88,6 @@ @include type-style('body-compact-01'); background-color: $layer; - inline-size: 100%; } diff --git a/packages/styles/scss/components/data-table/action/_data-table-action.scss b/packages/styles/scss/components/data-table/action/_data-table-action.scss index 8a7c49b32599..4dfafbd54b17 100644 --- a/packages/styles/scss/components/data-table/action/_data-table-action.scss +++ b/packages/styles/scss/components/data-table/action/_data-table-action.scss @@ -416,7 +416,8 @@ align-items: center; } - .#{$prefix}--action-list .#{$prefix}--btn { + .#{$prefix}--action-list .#{$prefix}--btn, + .#{$prefix}--batch-summary .#{$prefix}--btn { color: $text-on-color; padding-inline-end: $spacing-05; padding-inline-start: $spacing-05; @@ -453,7 +454,8 @@ display: none; } - .#{$prefix}--action-list .#{$prefix}--btn--primary:focus { + .#{$prefix}--action-list .#{$prefix}--btn--primary:focus, + .#{$prefix}--batch-summary .#{$prefix}--btn--primary:focus { outline: 2px solid $layer; outline-offset: convert.to-rem(-2px); } diff --git a/packages/styles/scss/components/list-box/_list-box.scss b/packages/styles/scss/components/list-box/_list-box.scss index e7fa2d3400b6..c55822839188 100644 --- a/packages/styles/scss/components/list-box/_list-box.scss +++ b/packages/styles/scss/components/list-box/_list-box.scss @@ -307,11 +307,13 @@ $list-box-menu-width: convert.to-rem(300px); display: inline-flex; overflow: hidden; align-items: center; - padding: 0 $spacing-09 0 $spacing-05; // Account for the border in `.bx--list-box` block-size: calc(100% + 1px); cursor: pointer; outline: none; + padding-block: 0; + padding-inline-end: $spacing-09; + padding-inline-start: $spacing-05; text-overflow: ellipsis; vertical-align: top; white-space: nowrap; diff --git a/packages/styles/scss/components/notification/_actionable-notification.scss b/packages/styles/scss/components/notification/_actionable-notification.scss index e81609ca18d4..6d493f3f1989 100644 --- a/packages/styles/scss/components/notification/_actionable-notification.scss +++ b/packages/styles/scss/components/notification/_actionable-notification.scss @@ -193,7 +193,7 @@ .#{$prefix}--actionable-notification__details { display: flex; flex-grow: 1; - margin: 0 $spacing-09 0 convert.to-rem(13px); + margin-inline: convert.to-rem(13px) $spacing-09; } .#{$prefix}--actionable-notification:not( diff --git a/packages/styles/scss/components/notification/_inline-notification.scss b/packages/styles/scss/components/notification/_inline-notification.scss index 0d6a8c05d0c9..9b24e5d62eb1 100644 --- a/packages/styles/scss/components/notification/_inline-notification.scss +++ b/packages/styles/scss/components/notification/_inline-notification.scss @@ -182,7 +182,7 @@ .#{$prefix}--inline-notification__details { display: flex; flex-grow: 1; - margin: 0 $spacing-09 0 convert.to-rem(13px); + margin-inline: convert.to-rem(13px) $spacing-09; @include breakpoint(md) { margin: 0 convert.to-rem(13px); @@ -204,7 +204,7 @@ .#{$prefix}--inline-notification__title { @include type-style('heading-compact-01'); - margin: 0 $spacing-02 0 0; + margin-inline-end: $spacing-02; } .#{$prefix}--inline-notification__subtitle { diff --git a/packages/styles/scss/components/pagination-nav/_pagination-nav.scss b/packages/styles/scss/components/pagination-nav/_pagination-nav.scss index 31ecc7307422..97a5c07ff601 100644 --- a/packages/styles/scss/components/pagination-nav/_pagination-nav.scss +++ b/packages/styles/scss/components/pagination-nav/_pagination-nav.scss @@ -168,4 +168,9 @@ .#{$prefix}--pagination-nav__accessibility-label { @include visually-hidden; } + + // RTL overrides + [dir='rtl'] .#{$prefix}--pagination-nav__list-item svg { + transform: rotate(0.5turn); + } } diff --git a/packages/styles/scss/components/pagination/_pagination.scss b/packages/styles/scss/components/pagination/_pagination.scss index 8c68ca39c79a..da1dda308662 100644 --- a/packages/styles/scss/components/pagination/_pagination.scss +++ b/packages/styles/scss/components/pagination/_pagination.scss @@ -98,7 +98,7 @@ .#{$prefix}--pagination .#{$prefix}--select--inline .#{$prefix}--select-input { - padding: 0 2.25rem 0 $spacing-05; + padding-inline: $spacing-05 2.25rem; } .#{$prefix}--pagination--sm .#{$prefix}--select-input { @@ -280,4 +280,9 @@ .#{$prefix}--btn--ghost.#{$prefix}--pagination__button { @include high-contrast-mode('outline'); } + + // RTL overrides + [dir='rtl'] .#{$prefix}--pagination .#{$prefix}--select__arrow { + transform: translate(0.5rem, -50%); + } } diff --git a/packages/styles/scss/components/popover/_popover.scss b/packages/styles/scss/components/popover/_popover.scss index 91a01f14c079..124c28d9bd57 100644 --- a/packages/styles/scss/components/popover/_popover.scss +++ b/packages/styles/scss/components/popover/_popover.scss @@ -197,6 +197,13 @@ $popover-caret-height: custom-property.get-var( transform: translate(-50%, calc(100% + $popover-offset)); } + [dir='rtl'] + .#{$prefix}--popover--bottom + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + transform: translate(50%, calc(100% + $popover-offset)); + } + .#{$prefix}--popover--bottom-left > .#{$prefix}--popover > .#{$prefix}--popover-content { @@ -208,6 +215,14 @@ $popover-caret-height: custom-property.get-var( ); } + [dir='rtl'] + .#{$prefix}--popover--bottom-left + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + inset-inline-end: 0; + inset-inline-start: initial; + } + .#{$prefix}--popover--bottom-right > .#{$prefix}--popover > .#{$prefix}--popover-content { @@ -216,6 +231,13 @@ $popover-caret-height: custom-property.get-var( transform: translate($popover-offset, calc(100% + $popover-offset)); } + [dir='rtl'] + .#{$prefix}--popover--bottom-right + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + inset-inline-start: 0; + } + // Popover hover area placement .#{$prefix}--popover--bottom > .#{$prefix}--popover @@ -251,6 +273,21 @@ $popover-caret-height: custom-property.get-var( transform: translate(-50%, $popover-offset); } + [dir='rtl'] + .#{$prefix}--popover--bottom + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--bottom-left + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--bottom-right + > .#{$prefix}--popover + > .#{$prefix}--popover-caret { + transform: translate(50%, $popover-offset); + } + //----------------------------------------------------------------------------- // Top //----------------------------------------------------------------------------- @@ -264,6 +301,13 @@ $popover-caret-height: custom-property.get-var( transform: translate(-50%, calc(-100% - $popover-offset)); } + [dir='rtl'] + .#{$prefix}--popover--top + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + transform: translate(50%, calc(-100% - $popover-offset)); + } + .#{$prefix}--popover--top-left > .#{$prefix}--popover > .#{$prefix}--popover-content { @@ -275,6 +319,14 @@ $popover-caret-height: custom-property.get-var( ); } + [dir='rtl'] + .#{$prefix}--popover--top-left + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + inset-inline-end: 0; + inset-inline-start: initial; + } + .#{$prefix}--popover--top-right > .#{$prefix}--popover > .#{$prefix}--popover-content { @@ -283,6 +335,13 @@ $popover-caret-height: custom-property.get-var( transform: translate($popover-offset, calc(-100% - $popover-offset)); } + [dir='rtl'] + .#{$prefix}--popover--top-right + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + inset-inline-start: 0; + } + // Popover hover area placement .#{$prefix}--popover--top > .#{$prefix}--popover @@ -316,6 +375,21 @@ $popover-caret-height: custom-property.get-var( transform: translate(-50%, calc(-1 * $popover-offset)); } + [dir='rtl'] + .#{$prefix}--popover--top + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--top-left + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--top-right + > .#{$prefix}--popover + > .#{$prefix}--popover-caret { + transform: translate(50%, calc(-1 * $popover-offset)); + } + //----------------------------------------------------------------------------- // Right //----------------------------------------------------------------------------- @@ -350,6 +424,22 @@ $popover-caret-height: custom-property.get-var( transform: translate($popover-offset, calc(0.5 * $popover-offset + 16px)); } + [dir='rtl'] + .#{$prefix}--popover--right + > .#{$prefix}--popover + > .#{$prefix}--popover-content, + [dir='rtl'] + .#{$prefix}--popover--right-bottom + > .#{$prefix}--popover + > .#{$prefix}--popover-content, + [dir='rtl'] + .#{$prefix}--popover--right-top + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + inset-inline-end: 100%; + inset-inline-start: initial; + } + // Popover hover area placement .#{$prefix}--popover--right > .#{$prefix}--popover @@ -385,6 +475,22 @@ $popover-caret-height: custom-property.get-var( transform: translate(calc($popover-offset - 100%), -50%); } + [dir='rtl'] + .#{$prefix}--popover--right + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--right-top + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--right-bottom + > .#{$prefix}--popover + > .#{$prefix}--popover-caret { + inset-inline-end: 100%; + inset-inline-start: initial; + } + //----------------------------------------------------------------------------- // Left //----------------------------------------------------------------------------- @@ -426,6 +532,22 @@ $popover-caret-height: custom-property.get-var( ); } + [dir='rtl'] + .#{$prefix}--popover--left + > .#{$prefix}--popover + > .#{$prefix}--popover-content, + [dir='rtl'] + .#{$prefix}--popover--left-bottom + > .#{$prefix}--popover + > .#{$prefix}--popover-content, + [dir='rtl'] + .#{$prefix}--popover--left-top + > .#{$prefix}--popover + > .#{$prefix}--popover-content { + inset-inline-end: initial; + inset-inline-start: 100%; + } + // Popover hover area placement .#{$prefix}--popover--left > .#{$prefix}--popover @@ -461,6 +583,22 @@ $popover-caret-height: custom-property.get-var( transform: translate(calc(-1 * $popover-offset + 100%), -50%); } + [dir='rtl'] + .#{$prefix}--popover--left + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--left-top + > .#{$prefix}--popover + > .#{$prefix}--popover-caret, + [dir='rtl'] + .#{$prefix}--popover--left-bottom + > .#{$prefix}--popover + > .#{$prefix}--popover-caret { + inset-inline-end: initial; + inset-inline-start: 100%; + } + //----------------------------------------------------------------------------- // Tab Tip Variant //----------------------------------------------------------------------------- diff --git a/packages/styles/scss/components/progress-indicator/_progress-indicator.scss b/packages/styles/scss/components/progress-indicator/_progress-indicator.scss index b10ce1df6002..d8e953a1ba17 100644 --- a/packages/styles/scss/components/progress-indicator/_progress-indicator.scss +++ b/packages/styles/scss/components/progress-indicator/_progress-indicator.scss @@ -70,11 +70,12 @@ $progress-indicator-bar-width: 1px inset transparent !default; position: relative; z-index: 1; flex-shrink: 0; - margin: convert.to-rem(10px) $spacing-03 0 0; block-size: $spacing-05; border-radius: 50%; fill: $interactive; inline-size: $spacing-05; + margin-block-start: convert.to-rem(10px); + margin-inline-end: $spacing-03; } .#{$prefix}--progress--space-equal .#{$prefix}--progress-text { diff --git a/packages/styles/scss/components/radio-button/_radio-button.scss b/packages/styles/scss/components/radio-button/_radio-button.scss index f88b0d43df40..93aa17653fcd 100644 --- a/packages/styles/scss/components/radio-button/_radio-button.scss +++ b/packages/styles/scss/components/radio-button/_radio-button.scss @@ -83,13 +83,12 @@ $radio-border-width: 1px !default; flex-shrink: 0; border: $radio-border-width solid $icon-primary; - margin: convert.to-rem(1px) $spacing-03 convert.to-rem(2px) - convert.to-rem(2px); background-color: transparent; block-size: convert.to-rem(18px); border-radius: 50%; - inline-size: convert.to-rem(18px); + margin-block: convert.to-rem(1px) convert.to-rem(2px); + margin-inline: convert.to-rem(2px) $spacing-03; } .#{$prefix}--radio-button:checked @@ -169,8 +168,8 @@ $radio-border-width: 1px !default; } .#{$prefix}--radio-button__invalid-icon { - margin: 0 convert.to-rem(1px) 0 convert.to-rem(3px); fill: $support-error; + margin-inline: convert.to-rem(3px) convert.to-rem(1px); } .#{$prefix}--radio-button__invalid-icon--warning { diff --git a/packages/styles/scss/components/toggle/_toggle.scss b/packages/styles/scss/components/toggle/_toggle.scss index e2fc7dff87aa..53b06b6c6bf3 100644 --- a/packages/styles/scss/components/toggle/_toggle.scss +++ b/packages/styles/scss/components/toggle/_toggle.scss @@ -218,4 +218,15 @@ inline-size: convert.to-rem(24px); margin-inline-start: convert.to-rem(8px); } + + // RTL overrides + [dir='rtl'] .#{$prefix}--toggle__switch--checked::before { + transform: translateX(convert.to-rem(-24px)); + } + + [dir='rtl'] + .#{$prefix}--toggle__appearance--sm + .#{$prefix}--toggle__switch--checked::before { + transform: translateX(convert.to-rem(-16px)); + } }