Skip to content

Commit

Permalink
[lexical][lexical-rich-text][lexical-playground] Feature: Support cap…
Browse files Browse the repository at this point in the history
…italization format (#6897)

Co-authored-by: Fadekemi Adebayo <fadekemi.adebayo@pau.edu.ng>
Co-authored-by: Bob Ippolito <bob@redivi.com>
  • Loading branch information
3 people authored Dec 14, 2024
1 parent 70cfd2f commit 8d9d945
Show file tree
Hide file tree
Showing 21 changed files with 503 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ import {
selectCharacters,
toggleBold,
toggleBulletList,
toggleCapitalize,
toggleChecklist,
toggleInsertCodeBlock,
toggleItalic,
toggleLowercase,
toggleNumberedList,
toggleStrikethrough,
toggleSubscript,
toggleSuperscript,
toggleUnderline,
toggleUppercase,
} from '../keyboardShortcuts/index.mjs';
import {
assertHTML,
Expand Down Expand Up @@ -112,6 +115,18 @@ const alignmentTestCases = [
];

const additionalStylesTestCases = [
{
applyShortcut: (page) => toggleLowercase(page),
style: 'Lowercase',
},
{
applyShortcut: (page) => toggleUppercase(page),
style: 'Uppercase',
},
{
applyShortcut: (page) => toggleCapitalize(page),
style: 'Capitalize',
},
{
applyShortcut: (page) => toggleStrikethrough(page),
style: 'Strikethrough',
Expand Down
142 changes: 142 additions & 0 deletions packages/lexical-playground/__tests__/e2e/TextFormatting.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import {
moveToLineEnd,
selectCharacters,
toggleBold,
toggleCapitalize,
toggleItalic,
toggleLowercase,
toggleUnderline,
toggleUppercase,
} from '../keyboardShortcuts/index.mjs';
import {
assertHTML,
Expand Down Expand Up @@ -428,6 +431,145 @@ test.describe.parallel('TextFormatting', () => {
});
});

const capitalizationFormats = [
{
applyCapitalization: toggleLowercase,
className: 'PlaygroundEditorTheme__textLowercase',
format: 'lowercase',
},
{
applyCapitalization: toggleUppercase,
className: 'PlaygroundEditorTheme__textUppercase',
format: 'uppercase',
},
{
applyCapitalization: toggleCapitalize,
className: 'PlaygroundEditorTheme__textCapitalize',
format: 'capitalize',
},
];

capitalizationFormats.forEach(({className, format, applyCapitalization}) => {
test(`Can select text and change it to ${format}`, async ({
page,
isPlainText,
}) => {
test.skip(isPlainText);

await focusEditor(page);
await page.keyboard.type('Hello world!');
await moveLeft(page);
await selectCharacters(page, 'left', 5);

await assertSelection(page, {
anchorOffset: 11,
anchorPath: [0, 0, 0],
focusOffset: 6,
focusPath: [0, 0, 0],
});

await applyCapitalization(page);
await assertHTML(
page,
html`
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span data-lexical-text="true">Hello</span>
<span class="${className}" data-lexical-text="true">world</span>
<span data-lexical-text="true">!</span>
</p>
`,
);

await assertSelection(page, {
anchorOffset: 5,
anchorPath: [0, 1, 0],
focusOffset: 0,
focusPath: [0, 1, 0],
});
});
});

const capitalizationResettingTestCases = [
{
expectedFinalHTML: html`
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span class="$formatClassName" data-lexical-text="true">Hello</span>
<span data-lexical-text="true">world!</span>
</p>
`,
key: 'Space',
},
{
expectedFinalHTML: html`
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span class="$formatClassName" data-lexical-text="true">Hello</span>
<span
class="PlaygroundEditorTheme__tabNode"
data-lexical-text="true"></span>
<span data-lexical-text="true">world!</span>
</p>
`,
key: 'Tab',
},
{
expectedFinalHTML: html`
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span class="$formatClassName" data-lexical-text="true">Hello</span>
</p>
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span data-lexical-text="true">world!</span>
</p>
`,
key: 'Enter',
},
];

capitalizationFormats.forEach(({format, className, applyCapitalization}) => {
capitalizationResettingTestCases.forEach(({key, expectedFinalHTML}) => {
test(`Pressing ${key} resets ${format} format`, async ({
page,
isPlainText,
}) => {
test.skip(isPlainText);

await focusEditor(page);

await applyCapitalization(page);
await page.keyboard.type('Hello');

await assertHTML(
page,
html`
<p
class="PlaygroundEditorTheme__paragraph PlaygroundEditorTheme__ltr"
dir="ltr">
<span class="${className}" data-lexical-text="true">Hello</span>
</p>
`,
);

// Pressing the key should reset the format
await page.keyboard.press(key);
await page.keyboard.type(' world!');

await assertHTML(
page,
expectedFinalHTML.replace('$formatClassName', className),
);
});
});
});

test(`Can select text and increase the font-size`, async ({
page,
isPlainText,
Expand Down
24 changes: 24 additions & 0 deletions packages/lexical-playground/__tests__/keyboardShortcuts/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,30 @@ export async function toggleInsertCodeBlock(page) {
await page.keyboard.up('Shift');
}

export async function toggleLowercase(page) {
await keyDownCtrlOrMeta(page);
await page.keyboard.down('Shift');
await page.keyboard.press('1');
await keyUpCtrlOrMeta(page);
await page.keyboard.up('Shift');
}

export async function toggleUppercase(page) {
await keyDownCtrlOrMeta(page);
await page.keyboard.down('Shift');
await page.keyboard.press('2');
await keyUpCtrlOrMeta(page);
await page.keyboard.up('Shift');
}

export async function toggleCapitalize(page) {
await keyDownCtrlOrMeta(page);
await page.keyboard.down('Shift');
await page.keyboard.press('3');
await keyUpCtrlOrMeta(page);
await page.keyboard.up('Shift');
}

export async function toggleStrikethrough(page) {
await keyDownCtrlOrMeta(page);
await page.keyboard.down('Shift');
Expand Down
5 changes: 5 additions & 0 deletions packages/lexical-playground/src/context/ToolbarContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export const blockTypeToBlockName = {
quote: 'Quote',
};

//disable eslint sorting rule for quick reference to toolbar state
/* eslint-disable sort-keys-fix/sort-keys-fix */
const INITIAL_TOOLBAR_STATE = {
bgColor: '#fff',
blockType: 'paragraph' as keyof typeof blockTypeToBlockName,
Expand All @@ -63,6 +65,9 @@ const INITIAL_TOOLBAR_STATE = {
isSubscript: false,
isSuperscript: false,
isUnderline: false,
isLowercase: false,
isUppercase: false,
isCapitalize: false,
rootType: 'root' as keyof typeof rootTypeToRootName,
};

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions packages/lexical-playground/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,18 @@ i.underline {
background-image: url(images/icons/type-underline.svg);
}

i.uppercase {
background-image: url(images/icons/type-uppercase.svg);
}

i.lowercase {
background-image: url(images/icons/type-lowercase.svg);
}

i.capitalize {
background-image: url(images/icons/type-capitalize.svg);
}

i.strikethrough {
background-image: url(images/icons/type-strikethrough.svg);
}
Expand Down
Loading

0 comments on commit 8d9d945

Please sign in to comment.