Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/affine/blocks/list/src/list-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
EDGELESS_TOP_CONTENTEDITABLE_SELECTOR,
} from '@blocksuite/affine-shared/consts';
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { getViewportElement } from '@blocksuite/affine-shared/utils';
import { getViewportElement, getTextDirection } from '@blocksuite/affine-shared/utils';
import type { BlockComponent } from '@blocksuite/std';
import { BlockSelection, TextSelection } from '@blocksuite/std';
import {
Expand Down Expand Up @@ -194,6 +194,7 @@ export class ListBlockComponent extends CaptionedBlockComponent<ListBlockModel>
.inlineRangeProvider=${this._inlineRangeProvider}
.enableClipboard=${false}
.enableUndoRedo=${false}
.textDirection=${getTextDirection(this.model.props.text.yText.toString())}
.verticalScrollContainerGetter=${() =>
getViewportElement(this.host)}
></rich-text>
Expand Down
15 changes: 15 additions & 0 deletions packages/affine/blocks/list/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,20 @@ export const listBlockStyles = css`
color: var(--affine-text-secondary-color);
}

/* RTL support for list blocks */
[dir='rtl'] .affine-list-rich-text-wrapper {
flex-direction: row-reverse;
}

[dir='rtl'] .affine-list-block__numbered {
margin-left: 0;
margin-right: 2px;
}

[dir='rtl'] .affine-list-block__todo-prefix {
margin-left: 0;
margin-right: 2px;
}

${listPrefix}
`;
3 changes: 3 additions & 0 deletions packages/affine/blocks/paragraph/src/paragraph-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
calculateCollapsedSiblings,
getNearestHeadingBefore,
getViewportElement,
getTextDirection,
TextDirection,
} from '@blocksuite/affine-shared/utils';
import type { BlockComponent } from '@blocksuite/std';
import { TextSelection } from '@blocksuite/std';
Expand Down Expand Up @@ -334,6 +336,7 @@ export class ParagraphBlockComponent extends CaptionedBlockComponent<ParagraphBl
.inlineRangeProvider=${this._inlineRangeProvider}
.enableClipboard=${false}
.enableUndoRedo=${false}
.textDirection=${getTextDirection(this.model.props.text.yText.toString())}
.verticalScrollContainerGetter=${() =>
getViewportElement(this.host)}
></rich-text>
Expand Down
16 changes: 16 additions & 0 deletions packages/affine/blocks/paragraph/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,16 @@ export const paragraphBlockStyles = css`
border-radius: 18px;
}

/* RTL support for quote */
[dir='rtl'] .quote {
padding-left: 0;
padding-right: 17px;
}
[dir='rtl'] .quote::after {
left: auto;
right: 0;
}

.affine-paragraph-placeholder {
position: absolute;
display: none;
Expand All @@ -142,6 +152,12 @@ export const paragraphBlockStyles = css`
color: var(--affine-black-30);
fill: var(--affine-black-30);
}

/* RTL support for placeholder */
[dir='rtl'] .affine-paragraph-placeholder {
left: auto;
right: 0;
}
@media print {
.affine-paragraph-placeholder {
display: none !important;
Expand Down
9 changes: 9 additions & 0 deletions packages/affine/blocks/root/src/page/page-root-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ export class PageRootBlockComponent extends BlockComponent<RootBlockModel> {
display: block;
}

/* RTL support for page root */
[dir='rtl'] .affine-page-root-block-container {
text-align: right;
}

[dir='ltr'] .affine-page-root-block-container {
text-align: left;
}

@media print {
.selected {
background-color: transparent !important;
Expand Down
9 changes: 9 additions & 0 deletions packages/affine/model/src/consts/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum TextAlign {
Center = 'center',
Left = 'left',
Right = 'right',
Justify = 'justify',
}

export const TextAlignMap = createEnumMap(TextAlign);
Expand All @@ -24,6 +25,7 @@ export type TextStyleProps = {
fontStyle: FontStyle;
fontWeight: FontWeight;
textAlign: TextAlign;
textDirection?: TextDirection;
};

export enum FontWeight {
Expand Down Expand Up @@ -62,7 +64,14 @@ export enum TextResizing {
AUTO_HEIGHT,
}

export enum TextDirection {
LTR = 'ltr',
RTL = 'rtl',
Auto = 'auto',
}

export const FontFamilySchema = z.nativeEnum(FontFamily);
export const FontWeightSchema = z.nativeEnum(FontWeight);
export const FontStyleSchema = z.nativeEnum(FontStyle);
export const TextAlignSchema = z.nativeEnum(TextAlign);
export const TextDirectionSchema = z.nativeEnum(TextDirection);
52 changes: 52 additions & 0 deletions packages/affine/rich-text/src/rich-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import type {
AffineInlineEditor,
AffineTextAttributes,
} from '@blocksuite/affine-shared/types';
import {
getTextDirection,
getRTLTextAlignCSS,
TextDirection,
isRTL
} from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/lit';
import { ShadowlessElement } from '@blocksuite/std';
import {
Expand Down Expand Up @@ -56,11 +62,53 @@ export class RichText extends WithDisposable(ShadowlessElement) {
rich-text .nowrap-lines v-element span {
white-space: pre !important;
}

/* RTL support */
.inline-editor[dir="rtl"] {
text-align: right;
}

.inline-editor[dir="ltr"] {
text-align: left;
}
`;

#verticalScrollContainer: HTMLElement | null = null;

private readonly _inlineEditor$ = signal<AffineInlineEditor | null>(null);

@property({ attribute: false })
accessor textDirection: TextDirection = TextDirection.Auto;

/**
* Get the current text direction based on content
*/
private getCurrentTextDirection(): TextDirection {
if (this.textDirection !== TextDirection.Auto) {
return this.textDirection;
}

const inlineEditor = this.inlineEditor;
if (!inlineEditor) return TextDirection.LTR;

const text = inlineEditor.yTextString;
return getTextDirection(text);
}

/**
* Update the direction attribute on the inline editor
*/
private updateTextDirection() {
const inlineEditor = this.inlineEditor;
if (!inlineEditor) return;

const direction = this.getCurrentTextDirection();
const directionValue = direction === TextDirection.RTL ? 'rtl' : 'ltr';

if (inlineEditor.rootElement) {
inlineEditor.rootElement.setAttribute('dir', directionValue);
}
}

private readonly _onCopy = (e: ClipboardEvent) => {
const inlineEditor = this.inlineEditor;
Expand Down Expand Up @@ -399,9 +447,13 @@ export class RichText extends WithDisposable(ShadowlessElement) {
readonly: this.readonly,
});

const direction = this.getCurrentTextDirection();
const directionValue = direction === TextDirection.RTL ? 'rtl' : 'ltr';

return html`<div
contenteditable=${this.readonly ? 'false' : 'true'}
class=${classes}
dir=${directionValue}
></div>`;
}

Expand Down
1 change: 1 addition & 0 deletions packages/affine/shared/src/styles/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { fontBaseStyle, fontSMStyle, fontXSStyle } from './font';
export { panelBaseColorsStyle, panelBaseStyle } from './panel';
export { rtlStyles, rtlCSSVariables } from './rtl';
export { scrollbarStyle } from './scrollbar-style';
export { affineTextStyles } from './text';
Loading