Skip to content
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

Simplify implementation of custom editor styling #5278

Merged
merged 5 commits into from
Feb 1, 2023

Conversation

kylemclean
Copy link
Contributor

Description
This PR switches Slate back to using inline styles for default editor styles, which reverts the changes in #5206 that made default styles come from injected <style> tags. This simplifies the implementation of custom editor styling, and fixes the previous implementation being incompatible with certain Content Security Policies.

Fortunately, all default editor styles can still be easily overridden by passing a style prop to the Editable component, and a new disableDefaultStyles prop can be passed if a user wishes to provide styles using a stylesheet and className.

Finally, documentation has been added regarding the styling of editors, as well as an example page that demonstrates this and some tests.

Issue
Fixes: default styles not working with certain CSPs, #5236

Example
Screenshot of Styling example page

After this change, editors can be styled as shown above with the following component:

const StylingExample = () => {
  const editor1 = useMemo(() => withHistory(withReact(createEditor())), [])
  const editor2 = useMemo(() => withHistory(withReact(createEditor())), [])

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '40px' }}>
      <Slate
        editor={editor1}
        value={[
          {
            type: 'paragraph',
            children: [{ text: 'This editor is styled using the style prop.' }],
          },
        ]}
      >
        <Editable
          style={{
            backgroundColor: 'rgb(255, 230, 156)',
            minHeight: '200px',
            outline: 'rgb(0, 128, 0) solid 2px',
          }}
        />
      </Slate>

      <Slate
        editor={editor2}
        value={[
          {
            type: 'paragraph',
            children: [
              { text: 'This editor is styled using the className prop.' },
            ],
          },
        ]}
      >
        <Editable className="fancy" disableDefaultStyles />
      </Slate>
    </div>
  )
}

and CSS:

.fancy {
  background-color: rgb(218, 225, 255);
  padding: 40px;
  font-size: 20px;
  min-height: 150px;
  outline: 3px dashed rgb(0, 94, 128);
  border-radius: 20px;
  outline-offset: -20px;
  white-space: pre-wrap;
}

Context
Prior to this change, #5206 made it possible for users to give editors custom styles by adding a style prop or className prop and stylesheet. This was accomplished by making the default editor styles come from an injected <style> element instead of inline styles, which can not be easily overridden with a stylesheet.

The full rationale for this change can be read in this comment, but in summary, injecting <style> elements does not work optimally in an SSR environment, can cause performance issues, and is problematic for users with a Content Security Policy that prohibits scripts from adding internal stylesheets. Additionally, the implementation of custom editor styling by injecting <style> elements is significantly more complex and error-prone than the implementation with inline styles.

Many of the changes made in #5206 are reverted by this PR, but some still remain. #5206 fixed #4314, which prevented min-height from being set on editors, and this is still fixed. Also, #5206 fixed editor height not adjusting to the height of its placeholder if its placeholder changes height in between renders, which is still fixed.

Checks

  • The new code matches the existing patterns and styles.
  • The tests pass with yarn test.
  • The linter passes with yarn lint. (Fix errors with yarn fix.)
  • The relevant examples still work. (Run examples with yarn start.)
  • You've added a changeset if changing functionality. (Add one with yarn changeset add.)

@changeset-bot
Copy link

changeset-bot bot commented Jan 31, 2023

🦋 Changeset detected

Latest commit: 6614bb6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
slate-react Minor
slate Minor

Not sure what this means? Click here to learn what changesets are.

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

Copy link
Collaborator

@dylans dylans left a comment

Choose a reason for hiding this comment

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

Looks fine overall, thanks! It looks like some of the integration tests are failing, but maybe not.

@dylans dylans merged commit 9c4097a into ianstormtaylor:main Feb 1, 2023
@github-actions github-actions bot mentioned this pull request Feb 1, 2023
@gajus
Copy link

gajus commented Oct 31, 2023

Is this the only change between version 0.88.1 and 0.90.0?

Trying to identify why some of our tests are failing with:

 FAIL  src/core/plugins/withBreaksOnExpandedSelection.test.tsx > withBreaksOnExpandedSelection > should replace expanded selection with empty paragraph and add empty paragraph when inserting break on expanded selection
Error: Cannot get the parent path of the root path [].
 ❯ Object.parent ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/interfaces/path.ts:324:13
 ❯ Object.parent ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/interfaces/node.ts:558:29
 ❯ applyToDraft ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/transforms/general.ts:132:27
 ❯ Object.transform ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/transforms/general.ts:327:19
 ❯ Object.apply ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/create-editor.ts:82:18
 ❯ fn ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/transforms/node.ts:558:18
 ❯ Object.withoutNormalizing ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/interfaces/editor.ts:1707:7
 ❯ Object.removeNodes ../../node_modules/.pnpm/slate@0.90.0/node_modules/slate/src/transforms/node.ts:532:12
 ❯ src/core/plugins/withBreaksOnExpandedSelection.ts:46:22
     44|
     45|         if (path) {
     46|           Transforms.removeNodes(editor, { at: path });
       |                      ^
     47|         }
     48|       });

after this upgrade

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.

minHeight is no longer respected in slate-react 0.62+
3 participants