sjdemartini / mui-tiptap Goto Github PK
View Code? Open in Web Editor NEWA Material UI (MUI) styled WYSIWYG rich text editor, using Tiptap
License: MIT License
A Material UI (MUI) styled WYSIWYG rich text editor, using Tiptap
License: MIT License
Hi,
i have some problems when i try to use MenuButtonTextColor
or MenuButtonUnderline
.
I am getting the error
Uncaugt TypeError: editor.can(...).setColor is not a function
I have already set up a codesandsbox where you can see the error:
Everything was working fine so far, because useRef is used for the components. But the color picker buttton works with event.currentTarget, which isn't accessible in the shadow dom. Any idea how i can solve that?
<MenuButton onClick={(e) => anchorEl ? handleClose() : setAnchorEl(e.currentTarget) } aria-describedby={popperId} {...otherMenuButtonProps} >
Steps to reproduce the behavior:
Warnings in the console.
<MenuButtonHorizontalRule />
Should not have warnings.
react_devtools_backend_compact.js:13096 TextSelection endpoint not pointing into a node with inline content (doc)
at MenuButtonHorizontalRule (webpack-internal:///./node_modules/mui-tiptap/dist/esm/controls/MenuButtonHorizontalRule.js:16:86)
at div
at MenuControlsContainer (webpack-internal:///./node_modules/mui-tiptap/dist/esm/controls/MenuControlsContainer.js:26:34)
at Menu (webpack-internal:///./src/components/RichText/Menu.tsx:16:88)
at DebounceRender (webpack-internal:///./node_modules/mui-tiptap/dist/esm/utils/DebounceRender.js:39:9)
at div
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Transition (webpack-internal:///./node_modules/react-transition-group/esm/Transition.js:133:30)
at Collapse (webpack-internal:///./node_modules/@mui/material/Collapse/Collapse.js:115:82)
at MenuBar (webpack-internal:///./node_modules/mui-tiptap/dist/esm/MenuBar.js:43:20)
at div
at FieldContainer (webpack-internal:///./node_modules/mui-tiptap/dist/esm/FieldContainer.js:70:27)
at RichTextField (webpack-internal:///./node_modules/mui-tiptap/dist/esm/RichTextField.js:67:26)
at RichTextEditorProvider (webpack-internal:///./node_modules/mui-tiptap/dist/esm/RichTextEditorProvider.js:18:35)
at RichTextEditor (webpack-internal:///./node_modules/mui-tiptap/dist/esm/RichTextEditor.js:27:100)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Box (webpack-internal:///./node_modules/@mui/system/esm/createBox.js:37:72)
at eval (webpack-internal:///./src/components/RichText/RichText.tsx:22:13)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Grid (webpack-internal:///./node_modules/@mui/system/esm/Stack/createStack.js:153:24)
at form
at Form (webpack-internal:///./src/components/forms/Form.tsx:15:13)
at FormProvider (webpack-internal:///./node_modules/react-hook-form/dist/index.esm.mjs:180:13)
at FormContainer (webpack-internal:///./src/components/forms/FormContainer.tsx:53:13)
at Form (webpack-internal:///./src/views/calendar/Form.tsx:70:13)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Box (webpack-internal:///./node_modules/@mui/system/esm/createBox.js:37:72)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Paper (webpack-internal:///./node_modules/@mui/material/Paper/Paper.js:79:83)
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Transition (webpack-internal:///./node_modules/react-transition-group/esm/Transition.js:133:30)
at Slide (webpack-internal:///./node_modules/@mui/material/Slide/Slide.js:98:77)
at FocusTrap (webpack-internal:///./node_modules/@mui/base/FocusTrap/FocusTrap.js:95:5)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Portal (webpack-internal:///./node_modules/@mui/base/Portal/Portal.js:36:5)
at Modal (webpack-internal:///./node_modules/@mui/base/Modal/Modal.js:81:7)
at Modal (webpack-internal:///./node_modules/@mui/material/Modal/Modal.js:83:82)
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Drawer (webpack-internal:///./node_modules/@mui/material/Drawer/Drawer.js:155:83)
at SidebarRight (webpack-internal:///./src/views/calendar/SidebarRight.tsx:27:13)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Box (webpack-internal:///./node_modules/@mui/system/esm/createBox.js:37:72)
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Container (webpack-internal:///./src/views/calendar/Container.tsx:36:90)
at Calendar
at main
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at Box (webpack-internal:///./node_modules/@mui/system/esm/createBox.js:37:72)
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at div
at eval (webpack-internal:///./node_modules/@emotion/react/dist/emotion-element-c39617d8.browser.esm.js:60:66)
at VerticalLayout (webpack-internal:///./src/@core/layouts/VerticalLayout.tsx:79:13)
at Layout (webpack-internal:///./src/@core/layouts/Layout.tsx:18:13)
at UserLayout (webpack-internal:///./src/layouts/UserLayout.tsx:33:11)
at LocalizationProvider (webpack-internal:///./node_modules/@mui/x-date-pickers/LocalizationProvider/LocalizationProvider.js:32:19)
at AuthGuard (webpack-internal:///./src/layouts/auth/AuthGuard.tsx:21:13)
at Direction (webpack-internal:///./src/layouts/components/Direction.tsx:30:13)
at ThemeProvider (webpack-internal:///./node_modules/@mui/private-theming/ThemeProvider/ThemeProvider.js:43:5)
at ThemeProvider (webpack-internal:///./node_modules/@mui/system/esm/ThemeProvider/ThemeProvider.js:54:5)
at ThemeProvider (webpack-internal:///./node_modules/@mui/material/styles/ThemeProvider.js:27:14)
at ThemeComponent (webpack-internal:///./src/@core/theme/ThemeComponent.tsx:27:13)
at SettingsProvider (webpack-internal:///./src/@core/context/settingsContext.tsx:76:11)
at QueryClientProvider (webpack-internal:///./node_modules/@tanstack/react-query/build/lib/QueryClientProvider.mjs:48:3)
at App (webpack-internal:///./pages/_app.tsx:85:13)
at PathnameContextProviderAdapter (webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:74:11)
at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:306:63)
at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:858:919)
at Container (webpack-internal:///./node_modules/next/dist/client/index.js:92:1)
at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:197:11)
at Root (webpack-internal:///./node_modules/next/dist/client/index.js:380:11)
this is not working on:
--- @mui/[email protected]
--- [email protected]
--- @tiptap/[email protected]
code sample:
editor.jsx
import { useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import {
MenuButtonBold,
MenuButtonItalic,
MenuControlsContainer,
MenuDivider,
MenuSelectHeading,
RichTextEditorProvider,
RichTextField,
} from "mui-tiptap";
export default function Quill() {
return <RichTextReadOnly content="<p>Hello world</p>" extensions={[StarterKit]} />
}
error:
ERROR in ./node_modules/@mui/utils/useControlled.js
Module build failed (from ./node_modules/source-map-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/ali/Projects/Nomreyar/client/node_modules/@mui/utils/useControlled.js'
ERROR in ./node_modules/@mui/utils/useEnhancedEffect.js
Module build failed (from ./node_modules/source-map-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/ali/Projects/Nomreyar/client/node_modules/@mui/utils/useEnhancedEffect.js'
ERROR in ./node_modules/@mui/utils/useEventCallback.js
Module build failed (from ./node_modules/source-map-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/ali/Projects/Nomreyar/client/node_modules/@mui/utils/useEventCallback.js'
ERROR in ./node_modules/@mui/utils/useForkRef.js
Module build failed (from ./node_modules/source-map-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/ali/Projects/Nomreyar/client/node_modules/@mui/utils/useForkRef.js'
ERROR in ./node_modules/@mui/utils/useId.js
Module build failed (from ./node_modules/source-map-loader/dist/cjs.js):
Error: ENOENT: no such file or directory, open '/Users/ali/Projects/Nomreyar/client/node_modules/@mui/utils/useId.js'
ERROR
[eslint]
src/parts/quill.jsx
Line 14:11: 'RichTextReadOnly' is not defined react/jsx-no-undef
Search for the keywords to learn more about each error.
I just found this package. It's amazing and it's the alternative I was looking to replace react-mui-draft-wysiwyg
.
Right now, I know this package depends on a lot of @tip/tap
packages.
It creates a clutter in the package.json
"@tiptap/core": "2.0.3",
"@tiptap/extension-blockquote": "2.0.3",
"@tiptap/extension-bold": "2.0.3",
"@tiptap/extension-bubble-menu": "2.0.3",
"@tiptap/extension-bullet-list": "2.0.3",
"@tiptap/extension-code": "2.0.3",
"@tiptap/extension-code-block": "2.0.3",
"@tiptap/extension-document": "2.0.3",
"@tiptap/extension-dropcursor": "2.0.3",
"@tiptap/extension-floating-menu": "2.0.3",
"@tiptap/extension-gapcursor": "2.0.3",
"@tiptap/extension-hard-break": "2.0.3",
"@tiptap/extension-heading": "2.0.3",
"@tiptap/extension-history": "2.0.3",
"@tiptap/extension-image": "2.0.3",
"@tiptap/extension-italic": "2.0.3",
"@tiptap/extension-link": "2.0.3",
"@tiptap/extension-list-item": "2.0.3",
"@tiptap/extension-ordered-list": "2.0.3",
"@tiptap/extension-paragraph": "2.0.3",
"@tiptap/extension-placeholder": "2.0.3",
"@tiptap/extension-strike": "2.0.3",
"@tiptap/extension-subscript": "2.0.3",
"@tiptap/extension-superscript": "2.0.3",
"@tiptap/extension-table": "2.0.3",
"@tiptap/extension-table-cell": "2.0.3",
"@tiptap/extension-table-header": "2.0.3",
"@tiptap/extension-table-row": "2.0.3",
"@tiptap/extension-task-item": "2.0.3",
"@tiptap/extension-task-list": "2.0.3",
"@tiptap/extension-text": "2.0.3",
"@tiptap/pm": "^2.0.3",
"@tiptap/react": "2.0.3",
Side note: Why do you need react-icons
when you have @mui/icons-material
that already works with tree-shaking? https://mui.com/material-ui/guides/minimizing-bundle-size/
Remove react-icons
and just use @mui/icons-material
. Include @tip-tap
peer depenencies as dependences in this package.
To make this package a true replacement for react-mui-draft-wysiwyg there are a few menu buttons that you can add.
Implement the following suggestions:
@tiptap/extension-history
(#65)@tiptap/extension-history
(#65)@tiptap/extension-highlight
(#135)@tiptap/extension-text-style
@tiptap/extension-color
(#135)MenuHeadingSelect
@tiptap/extension-text-style
(new FontSize
extension and MenuSelectFontSize
in #94 and #95)@tiptap/extension-text-style
@tiptap/extension-font-family
(#110)@tiptap/extension-text-align
(#69, #70)@tiptap/extension-text-align
(#69, #70)@tiptap/extension-text-align
(#69, #70)@tiptap/extension-text-align
(#69, #70)@tiptap/extension-image
@tiptap/extension-horizontal-rule
(#66)@tiptap/extension-underline
(#68)A clear and concise description of any alternative solutions or features you've considered.
Add any other context or screenshots about the feature request here.
I've been using your text editor module with MUI and TipTap integration and it's been invaluable in my project.
I was wondering, is there currently a way to see the applied text color without having to save and manually deselect the text? If not, I'd like to suggest a feature. It would be great if there was an option for a preview that automatically deselects the text while it's still in focus, so users can instantly see the chosen color.
I'm trying to use mui-tiptap in my Next.js project but got this error during build time. I've got @mui/material version 5.14.11, @mui/icons-material is at 5.11.11. When can find the CheckList icon on their docs, but cannot import it in my project.
In the current project that I am working on we have a error state for form fields that highlights the outside of the dropdown or text field red. We would like to continue this pattern with this rich text field. Using class overrides in the props I am able to make the bottom border of the header red but I am not able to change the outside border of the TextArea red. Attached below are pictures of what am able to do at this point and what I would like to be able to do.
Here is a snippet of the code that ive tried to override the outer border... I've tried to work with all the code commented out but with no effect
<RichTextField
// classes={{
// content: styles.formError,
// outlined: styles.formError,
// standard: styles.formError,
// root: styles.formError,
// menuBar: styles.formError,
// menuBarContent: styles.formError,
// }}
// RichTextContentProps={{
// className: styles.formError,
// classes: { root: styles.formError, editable: styles.formError },
// }}
MenuBarProps={{ className: styles.formError }}
// className={styles.formError}
disabled={inputDisabled}
Ideally it would be awesome to have an error prop but that seems like a huge lift. I believe the easiest solution for my problem would to be able to override the classes.notchedOutline
styling in the FieldContainer.tsx file. Im not sure if that could be handled like the other fields in the RichTextField classes override that i tried above
open to any suggestions
On some platforms, such as Nextjs 13, an issue emerges due to the large bundle size of mui-tiptap / it's import method for some of "@mui/icons-material". For most of the codebase, direct path imports are used. There are some areas where the tree shaking imports are used, which bloat the package and are strangely linked to issues on Nextjs 13.
Not possible to reproduce without a full Nextjs 13 deployment on Vercel. Not necessarily relevant, either.
Steps to reproduce the behavior:
The inclusion of mui-tiptap should safely import the icons from @mui/icons-material using the direct path. Then, the application runs smoothly.
Simply need to change from
to this
Regardless, this will reduce the bundle size and is considered best practice. (See mui docs https://mui.com/material-ui/icons/#usage )
The imports should be changed to direct path imports unless the techniques specified here are used https://mui.com/material-ui/guides/minimizing-bundle-size/#option-two-use-a-babel-plugin
It is my first time contributing on OSS, so please forgive any mishaps. I am a really big fan of this project and am impressed with the design & codebase. I will attempt to open a PR for this issue shortly.
I am importing mui-tiptap
dynamically into a Nextjs component. I am receiving a Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
error.
Please include a CodeSandbox demo of the problem if possible.
Code Sandbox
Steps to reproduce the behavior:
mui-tiptap
in Nextjs project (app router)Ref should be used in RichTextEditor as expected
If applicable, add screenshots to help explain your problem.
extensions
array used for the editor: BulletList,
Document,
ListItem,
OrderedList,
Paragraph,
Text,
Bold,
Italic,
Underline,
HeadingWithAnchor,
History,
I found this function formatHref
in file: /src/LinkBubbleMenu/EditLinkMenuContent.tsx
How can I remove or skip its behavior?
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
A clear and concise description of what you want to happen.
A clear and concise description of any alternative solutions or features you've considered.
Add any other context or screenshots about the feature request here.
Fails to install with the following error:
preinstall: npx only-allow pnpm
ReadMe say use "npm install mui-tiptap"
Any way this can be installed via npm?
Question:
I know this is a weird question, since HeadingWithAnchor has an opinion in the name itself, but is there perhaps a standard way to avoid showing those anchor links on hover?
The solutions I can think of:
.MuiTiptap-RichTextContent-readonly {
.MuiTiptap-HeadingWithAnchorComponent-link {
display: none;
}
}
Motivation behind this is long form documents and non-unique headings.
Here on the repo on src/controls/MenuButtonUnindent.tsx
, the button import is correct, but when I checked my project's node_modules
in node_modules/mui-tiptap/dist/controls/MenuButtonUnindent.js
, there's
const FormatIndentIncrease_1 = __importDefault(require("@mui/icons-material/FormatIndentIncrease"));
on line 7
Is there a way to embed a preview of a Google Sheets file?
I'm imagining a user adds a link with public permissions and selects a column x row range to display.
Or how would one go about implementing this?
Curious what are the implications of upgrading underlying TipTap (and it's deps) to latest version (currently 2.2.6).
Authors insight; Did you already go down this path? Any gotchas to be aware?
Hey, sorry this isn't a feature request but I couldn't figure out the best way to ask a question!
I haven't actually been using it, but this package is great! I've been working on my own implementation of TipTap for Chakra UI, and this package has provided a lot of useful examples of how to make custom extensions and properly type some of the examples they have in the original demos.
The one thing I have not been able to figure out though, is how you manage to maintain the text selection inside the editor when other elements are focused. In my case specifically, I'm trying to prevent a selected block of text from unselecting as soon as I click on the font selector dropdown. I've found some hacky ways to do it by re-selecting the current selection after the dropdown opens, but it prevents my dropdown from being interactable (using my chakra wrapper for react select). I'd be very grateful if you could provide any info on how you managed to accomplish this, even if that's just to point me somewhere in this repo where you handle that.
Hopefully this isn't me just doing something stupid haha.
I am trying to change the z-index by code for the popper of the menu items. I want to do this by code and not by CSS.
How can I achieve this?
Hi,
Is there a way to prevent the choosen text color to be reseted to default on pressing return?
I find it pretty non intuitive to have to select again the color on each line change.
would it be possible to add a aria-label to the inputs like font family and font size? There currently is one, but it's not on the input so there is a missing label error from an accessibility standpoint
Originally posted by @sgober in #174 (comment)
Based on https://mui.com/material-ui/react-select/#accessibility, it seems we perhaps shouldn't be providing an aria-label
the way we are, though it's not entirely clear to me what the right pattern is when you don't have a separate label element. (https://mui.com/material-ui/react-select/#accessibility, https://mui.com/material-ui/react-text-field/#accessibility)
For what it's worth, the Select
's input
itself has aria-hidden="true"
, so I don't think it needs the aria-label, but there may be a better way to handle a11y with these components.
Please leave a comment and/or feel free to make a PR if you have suggestions on the "right way" to improve this!
I can use npm --force to install and everything still works fine. Can we remove the preinstall requirement for pnpm?
With the ListItem
extension installed I am unable to even click the MenuButtonIndent button.
I would like to use this button to easily create paragraphs.
Please include a CodeSandbox demo of the problem if possible. (You can fork this CodeSandbox.)
Steps to reproduce the behavior:
Scenario 1:
Scenario 2:
I expect the MenuButtonIndent button to be clickable
If applicable, add screenshots to help explain your problem.
extensions
array used for the editor: TableImproved.configure({
resizable: true,
}),
TableRow,
TableHeader,
TableCell,
BulletList.configure({
HTMLAttributes: {
class: "ml-5",
},
}),
CodeBlock,
Document,
HardBreak,
ListItem,
OrderedList.configure({
HTMLAttributes: {
class: "ml-5",
},
}),
Paragraph.configure({
HTMLAttributes: {
class: "mb-2",
},
}),
CustomSubscript,
CustomSuperscript,
Text,
// Blockquote must come after Bold, since we want the "Cmd+B" shortcut to
// have lower precedence than the Blockquote "Cmd+Shift+B" shortcut.
// Otherwise using "Cmd+Shift+B" will mistakenly toggle the bold mark.
// (See https://github.com/ueberdosis/tiptap/issues/4005,
// https://github.com/ueberdosis/tiptap/issues/4006)
Bold,
Blockquote,
Code,
Italic,
Underline,
Strike,
CustomLinkExtension.configure({
// autolink is generally useful for changing text into links if they
// appear to be URLs (like someone types in literally "example.com"),
// though it comes with the caveat that if you then *remove* the link
// from the text, and then add a space or newline directly after the
// text, autolink will turn the text back into a link again. Not ideal,
// but probably still overall worth having autolink enabled, and that's
// how a lot of other tools behave as well.
autolink: true,
linkOnPaste: true,
openOnClick: false,
}),
LinkBubbleMenuHandler,
// Extensions
Gapcursor,
HeadingWithAnchor,
TextAlign.configure({
types: ["heading", "paragraph", "image"],
}),
TextStyle,
Color,
FontFamily,
FontSize,
Highlight.configure({ multicolor: true }),
HorizontalRule,
ResizableImage,
// When images are dragged, we want to show the "drop cursor" for where they'll
// land
Dropcursor,
TaskList,
TaskItem.configure({
nested: true,
}),
// Mention.configure({
// suggestion: mentionSuggestionOptions,
// }),
Placeholder.configure({
placeholder,
}),
// We use the regular `History` (undo/redo) extension when not using
// collaborative editing
History,
Add any other context about the problem here.
When I try to use RichTextEditor with React Hook Form and change the form value via onUpdate
prop with HTML format, the cursor jumps to the end of the content each time.
Steps to reproduce the behavior:
The content should be updated, and the cursor should stay in the same position
I want to set the editor height by lines or by pixels.
That means the initial editor without content already has a certain height, which should also stay the same with a lot of content. If required, scrollbars should appear.
Can that be achieved already, or does that require a code improvement?
When I selected the Link Menu Button it shows in the wrong place. I traced the problem to the transform that the class MuiTiptap-ControlledBubbleMenu-root
has.
Steps to reproduce the behavior:
The bubble menu should be centered or below the link menu button.
Add any other context about the problem here.
When using <MenuButtonTextColor />
and <MenuButtonHighlightColor />
color pickers in the TipTap placed in a modal, color pickers are rendered in a layer below the modal.
Steps to reproduce the behavior:
The same is happening with editing links, however, for links there is a special component <LinkBubbleMenu />
that can be modified by passing an argument for container
prop that is a reference to a container in which the popup should be rendered, if proper modal container is passed in, the link popup is rendered in a correct layer without having to mess with z-index
. The expected behaviour would be the same as it is for links.
<LinkBubbleMenu container={props.dialogRef?.current} />
extensions
array used for the editor: return [
BulletList,
CodeBlock,
Document,
HardBreak,
ListItem,
OrderedList,
Paragraph,
Text,
Bold,
Blockquote,
Code,
Italic,
Underline,
CustomLinkExtension.configure({
autolink: true,
linkOnPaste: true,
openOnClick: false,
}),
LinkBubbleMenuHandler,
Gapcursor,
HeadingWithAnchor,
TextAlign.configure({
types: ['heading', 'paragraph', 'image'],
}),
TextStyle,
Color,
FontSize,
Highlight.configure({ multicolor: true }),
HorizontalRule,
ResizableImage,
Dropcursor,
History,
];
starter-kit
2.1.13
I have default settings and in the heading menu select heading h2 is 0.75 rem instead of 1.75rem.
extensions={[StarterKit, ...extension]}
In my custom extensions is not anything, that overrides heading config.
Chrome
No response
I expected that font sizes go chronologically.
No response
Mui has an option to configure the locale for their components using the global theme and importing the language tag from the locale package. The locale package exports named objects with the language tag that override the default props of the component and changes the language of the different texts that component has.
https://github.com/mui/material-ui/blob/master/packages/mui-material/src/locale/index.ts
Add a locale prop to each component or configure a global locale override. Simple components like Menu Buttons have only the label but bubble menus and other extensions have multiple labels and texts.
Make each label/text prop of all extensions/controls customizable.
Dependencies from mui-tiptap are conflicting with other dependencies. Specifically there's a conflict when utilizing styled-components with MUI V5, and tss-react from mui-tiptap.
Error: ModuleNotFoundError: Module not found: Error: Can't resolve '@mui/material/styles'
Compatability between tss-react and projects utilizing styled-components
ModuleNotFoundError: Module not found: Error: Can't resolve '@mui/material/styles' in '/Users/me/dev/clients/node_modules/tss-react/esm'
at /Users/me/dev/clients/node_modules/webpack/lib/Compilation.js:2014:28
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:791:13
at eval (eval at create (/Users/me/dev/clients/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:10:1)
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:265:22
at eval (eval at create (/Users/me/dev/clients/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:427:22
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:111:11
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:663:25
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:848:8
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:968:5
at /Users/me/dev/clients/node_modules/neo-async/async.js:6883:13
at /Users/me/dev/clients/node_modules/webpack/lib/NormalModuleFactory.js:951:45
at finishWithoutResolve (/Users/me/dev/clients/node_modules/enhanced-resolve/lib/Resolver.js:312:11)
at /Users/me/dev/clients/node_modules/enhanced-resolve/lib/Resolver.js:386:15
at /Users/me/dev/clients/node_modules/enhanced-resolve/lib/Resolver.js:435:5
at eval (eval at create (/Users/me/dev/clients/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
resolve '@mui/material/styles' in '/Users/me/dev/clients/node_modules/tss-react/esm'
Parsed request is a module
using description file: /Users/me/dev/clients/node_modules/tss-react/package.json (relative path: ./esm)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
/Users/me/dev/clients/node_modules/tss-react/esm/node_modules doesn't exist or is not a directory
/Users/me/dev/clients/node_modules/tss-react/node_modules doesn't exist or is not a directory
/Users/me/dev/clients/node_modules/node_modules doesn't exist or is not a directory
looking for modules in /Users/me/dev/clients/node_modules
/Users/me/dev/clients/node_modules/@mui/material doesn't exist
looking for modules in /Users/me/dev/node_modules
/Users/me/dev/node_modules/@mui/material doesn't exist
looking for modules in /Users/me/node_modules
/Users/me/node_modules/@mui/material doesn't exist
/Users/node_modules doesn't exist or is not a directory
/node_modules doesn't exist or is not a directory
looking for modules in /Users/me/dev/clients/node_modules/react-scripts/node_modules
/Users/me/dev/clients/node_modules/react-scripts/node_modules/@mui/material doesn't exist
Add any other context about the problem here.
Find it hard to believe that there is no way to display a defaultValue in a RichTextField... if there is please tell me
Firstly, great thanks for contributors.
I'm using the editor with example here codesandbox.
I had to edit ResizableImage extension options in "useExtensions.ts" to enable image paste when writing.
I don't know why but when directly copying content from page, image was not copy-pasted into the editor.
After I enabled options, resizing feature by dragging is not working properly.
enable inline true.
Image resize by dragging is not possible.
extensions
array used for the editor:[
// We incorporate all of the functionality that's part of
// https://tiptap.dev/api/extensions/starter-kit, plus a few additional
// extensions, including mui-tiptap's
// Note that the Table extension must come before other nodes that also have "tab"
// shortcut keys so that when using the tab key within a table on a node that also
// responds to that shortcut, it respects that inner node with higher precedence
// than the Table. For instance, if you want to indent or dedent a list item
// inside a table, you should be able to do that by pressing tab. Tab should only
// move between table cells if not within such a nested node. See comment here for
// notes on extension ordering
// https://github.com/ueberdosis/tiptap/issues/1547#issuecomment-890848888, and
// note in prosemirror-tables on the need to have these plugins be lower
// precedence
// https://github.com/ueberdosis/prosemirror-tables/blob/1a0428af3ca891d7db648ce3f08a2c74d47dced7/src/index.js#L26-L30
TableImproved.configure({
resizable: true,
}),
TableRow,
TableHeader,
TableCell,
BulletList,
CodeBlock,
Document,
HardBreak,
ListItem,
OrderedList,
Paragraph,
CustomSubscript,
CustomSuperscript,
Text,
// Blockquote must come after Bold, since we want the "Cmd+B" shortcut to
// have lower precedence than the Blockquote "Cmd+Shift+B" shortcut.
// Otherwise using "Cmd+Shift+B" will mistakenly toggle the bold mark.
// (See https://github.com/ueberdosis/tiptap/issues/4005,
// https://github.com/ueberdosis/tiptap/issues/4006)
Bold,
Blockquote,
Code,
Italic,
Underline,
Strike,
CustomLinkExtension.configure({
// autolink is generally useful for changing text into links if they
// appear to be URLs (like someone types in literally "example.com"),
// though it comes with the caveat that if you then *remove* the link
// from the text, and then add a space or newline directly after the
// text, autolink will turn the text back into a link again. Not ideal,
// but probably still overall worth having autolink enabled, and that's
// how a lot of other tools behave as well.
autolink: true,
linkOnPaste: true,
openOnClick: false,
}),
LinkBubbleMenuHandler,
// Extensions
Gapcursor,
HeadingWithAnchor,
TextAlign.configure({
types: ["heading", "paragraph", "image"],
}),
TextStyle,
Color,
FontFamily,
FontSize,
Highlight.configure({ multicolor: true }),
HorizontalRule,
ResizableImage.configure({
// allowBase64: false,
inline: true,
}),
// When images are dragged, we want to show the "drop cursor" for where they'll
// land
Dropcursor,
TaskList,
TaskItem.configure({
nested: true,
}),
Mention.configure({
suggestion: mentionSuggestionOptions,
}),
Placeholder.configure({
placeholder,
}),
// We use the regular `History` (undo/redo) extension when not using
// collaborative editing
History,
]
Hello ! Hope you're fine. I need some help on this issue I have when I try to use mui-tiptap :
Module not found: Error: Package path ./dist is not exported from package /home/philippe/stylotendu/node_modules/mui-tiptap (see exports field in /home/philippe/stylotendu/node_modules/mui-tiptap/package.json)
Here is a copy of my package.json :
{
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.1",
"@mui/material": "^5.15.1",
"@mui/x-data-grid": "^6.18.5",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@tiptap/core": "^2.1.13",
"@tiptap/extension-heading": "^2.1.13",
"@tiptap/extension-image": "^2.1.13",
"@tiptap/extension-table": "^2.1.13",
"@tiptap/pm": "^2.1.13",
"@tiptap/react": "^2.1.13",
"@tiptap/starter-kit": "^2.1.13",
"mui-tiptap": "^1.8.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "^6.20.1",
"react-router-dom": "^6.21.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Thank you!
I am unable to use like half of the mui-tiptap
components as they fail with errors like setColor
or toggleUnderline
are not functions (see screenshot below)
Steps to reproduce the behavior:
This is what I am trying to use with json forms:
<RichTextEditorProvider editor={editor}>
<RichTextField
controls={
<MenuControlsContainer>
{/* <MenuSelectFontFamily /> */}
<MenuSelectHeading />
{/* <MenuSelectFontSize /> */}
<MenuDivider />
<MenuButtonBold />
<MenuButtonItalic />
<MenuButtonUnderline />
<MenuButtonStrikethrough />
{/* <MenuButtonSubscript /> */}
{/* <MenuButtonSuperscript /> */}
<MenuDivider />
{/* <MenuButtonTextColor
defaultTextColor="fff"
swatchColors={[
{ value: '#000000', label: 'Black' },
{ value: '#ffffff', label: 'White' },
{ value: '#888888', label: 'Grey' },
{ value: '#ff0000', label: 'Red' },
{ value: '#ff9900', label: 'Orange' },
{ value: '#ffff00', label: 'Yellow' },
{ value: '#00d000', label: 'Green' },
{ value: '#0000ff', label: 'Blue' }
]}
/> */}
{/* <MenuButtonHighlightColor /> */}
{/* <MenuDivider /> */}
<MenuButtonEditLink />
<MenuDivider />
{/* <MenuSelectTextAlign /> */}
{/* <MenuButtonAlignLeft />
<MenuButtonAlignCenter />
<MenuButtonAlignRight />
<MenuButtonAlignJustify />
<MenuDivider /> */}
<MenuButtonOrderedList />
<MenuButtonBulletedList />
{/* <MenuButtonTaskList /> */}
<MenuDivider />
{/* TODO: why are these disabled */}
{/* <MenuButtonIndent />
<MenuButtonUnindent />
<MenuDivider /> */}
<MenuButtonBlockquote />
<MenuDivider />
<MenuButtonCode />
<MenuButtonCodeBlock />
<MenuDivider />
<MenuButtonUndo />
<MenuButtonRedo />
</MenuControlsContainer>
}
/>
</RichTextEditorProvider>
With editor defined as follows:
const editor = useEditor({
extensions: [StarterKit],
content: data,
onUpdate({ editor }) {
handleChange(path, editor.getHTML());
}
});
Every mui-tiptap
component above that is commented out results in an error similar to the one I described above. It is odd that some of them work and some of them don't
Error when I try to use MenuButtonUnderline
:
All other error are similar, not sure if this is a tiptap
error or something specific to mui-tiptap
Add any other context about the problem here.
I want to set the border style, border color, table width to 100%, background colors for the cells.
Add options to the table tooltip that allow more customization.
For know I manually edit the html output
Here is how some of the new options can look like based on microsoft word options.
The pop-up box for inputting the URL for editing a link does not show up.
While using the control inside of a mui-tiptap editor:
Expectation: A popup box appears allowing user to input URL
Actual: Nothing
Add any other context about the problem here.
Right now, there's a general-purpose "insert image" button via MenuButtonAddImage
. You provide your own onClick
(where you could use your own interface to type in a URL, or you could trigger a file upload), like in the simple example in the internal demo.
As originally mentioned/requested in #52, we might also want to add support for more functionality/UI built into mui-tiptap, with:
See example screenshots here #52 (comment)
If RichTextEditor with LinkBubbleMenu placed into an HTML form, editing link and hitting "Save" button leads to submission of this form.
I believe this happens because even despite in HTML these two forms are not connected, React bubbles submit event up through Portal to outer form component.
Steps to reproduce the behavior:
Use <RichTextEditor>
inside a form, start editing a link, then hit "Save" button.
const TestLinkEdit = () => {
const handleSubmit = () => {
alert("Gotcha!");
};
return (
<form onSubmit={handleSubmit}>
<RichTextEditor
extensions={[StarterKit, Link, LinkBubbleMenuHandler]}
content="<p>Hello world</p>"
renderControls={() => (
<MenuControlsContainer>
<MenuButtonEditLink />
</MenuControlsContainer>
)}
>
{() => <LinkBubbleMenu />}
</RichTextEditor>
</form>
);
};
Saving a link from pop-up form doesn't submit outer form.
Currently workaround is to wrap <LinkBubbleMenu />
with a dummy form, catching submit event. However, it leads to incorrect HTML structure ("form cannot appear as a descendant of form")
<RichTextEditor {...}>
{() => (
<form onSubmit={(e) => e.stopPropagation()}>
<LinkBubbleMenu />
</form>
)}
</RichTextEditor>
During development, all CSS classes are nicely available. For example, MuiTiptap-RichTextField-content
can be found in the DOM. This is nice, because we can override some styles using CSS this way.
However, in a production build the CSS properties are minified. Now, MuiTiptap-Xy-content
can be found in the DOM. This is probabily because the function names are minified, and the function names are used to generate the CSS classes.
To reproduce, you can open the default demo (https://codesandbox.io/p/sandbox/mui-tiptap-demo-3zl2l6) and in the terminal, use the build
step. Then, open the 'preview' URL (change port 5173 to 4173). The CSS classes are now different.
I would expect the CSS classes to be the same in a development build, and in a production build.
If applicable, add screenshots to help explain your problem.
Probabily, the use of function.name
needs to be avoided, because the function name is minified in most production builds.
See: https://github.com/sjdemartini/mui-tiptap/blob/main/src/RichTextContent.tsx#L19C20-L19C20
Hard-coding the component name is, I think, the only option here. MUI seems to do that aswell.
LinkBubbleMenu is very stubborn, basially I want to change the color of inputs in LinkBubbleMenu. I changed some colors like for buttons using custom CSS.
I know there is always a workaround for every issue. But I think if there is an option to set the theme as Mui does. Or an option to map existing Mui config with the Mui TipTap.
I have used custom CSS for buttons but still wrapping my head with an MUI fieldset at least one should have the option to pass its own component or color as a prop.
Add any other context or screenshots about the feature request here.
Thanks for the nicer solution.
Is there a way to not blur on Tab key press?
If you put the Editor in a Dialog/Modal the color picker will appear behind the dialog/modal popup
Just add the Editor in a Dialog or Modal and the color picker tooltip will stay behind the popup
https://codesandbox.io/p/devbox/mui-tiptap-demo-forked-vmndxj
Steps to reproduce the behavior:
The tooltips should stay in front of the Dialog
I used the Demo
If I style some text as Heading 1, I cannot switch it to any other heading level, because they are disabled in the MenuSelectHeading
component. I have to first switch it to Paragraph and then to the desired Heading 2-6.
This only happens with Heading 1, all other heading levels are fine.
I'll try to replicate it in codesandbox when I have the time.
Steps to reproduce the behaviour:
MenuSelectHeading
dropdownAll heading levels in the dropdown should be enabled and selectable.
E.g. it should be possible to select the option Heading 2, which should switch the selected/focused text to the Heading 2 style.
All heading levels are disabled and cannot be selected. You have to first select Paragraph, and then the desired Heading 2-6.
I compared this behaviour with your Codesandbox example, and there it works fine - you can switch heading levels directly. I tried replicating the codesandbox code as closely as possible in my project - using the same versions of the tiptap and mui-tiptap packages, using the HeadingWithAnchor
instead of the basic Heading
extension, same order of the extensions. Nothing helped. The older package versions caused weird internal "cannot access property of undefined" errors.
const editor = useEditor({
editorProps: {
attributes: {
'data-ui-input': 'rich-text-editor-input-field',
},
},
extensions: [
BulletList,
CodeBlock,
Document,
HardBreak,
ListItem,
OrderedList,
Paragraph,
CustomSubscript,
CustomSuperscript,
Text,
Bold,
Blockquote,
Code,
Italic,
Underline,
Strike,
CustomLinkExtension.configure({
autolink: true,
linkOnPaste: true,
openOnClick: false,
}),
LinkBubbleMenuHandler,
Gapcursor,
Heading,
HorizontalRule,
Dropcursor,
TaskList,
TaskItem.configure({
nested: true,
}),
History,
Placeholder.configure({
emptyEditorClass: styles.isEditorEmpty,
placeholder,
}),
CharacterCount.configure({
limit: maxLength,
}),
],
content,
}, [placeholder, content])
<ThemeProvider theme={muiTheme}>
<RichTextEditorProvider editor={editor}>
<RichTextField
className={styles.editor}
RichTextContentProps={{
className: clsx(styles.richTextField, richTextFieldClassName),
}}
controls={(
<MenuControlsContainer>
<MenuButtonUndo
data-ui-element="rich-text-menu-item-undo"
tooltipLabel={t('richTextEditor.undo')}
/>
<MenuButtonRedo
data-ui-element="rich-text-menu-item-redo"
tooltipLabel={t('richTextEditor.redo')}
/>
<MenuDivider />
<MenuSelectHeading
data-ui-element="rich-text-menu-item-select-heading"
className={styles.menuSelectHeading}
tooltipTitle={t('richTextEditor.selectHeadingTooltip')}
labels={{
paragraph: t('richTextEditor.paragraph'),
heading1: t('richTextEditor.heading1'),
heading2: t('richTextEditor.heading2'),
heading3: t('richTextEditor.heading3'),
heading4: t('richTextEditor.heading4'),
heading5: t('richTextEditor.heading5'),
heading6: t('richTextEditor.heading6'),
}}
/>
<MenuDivider />
<MenuButtonBold
data-ui-element="rich-text-menu-item-bold"
tooltipLabel={t('richTextEditor.bold')}
/>
<MenuButtonItalic
data-ui-element="rich-text-menu-item-italic"
tooltipLabel={t('richTextEditor.italic')}
/>
<MenuButtonUnderline
data-ui-element="rich-text-menu-item-underline"
tooltipLabel={t('richTextEditor.underline')}
/>
<MenuButtonStrikethrough
data-ui-element="rich-text-menu-item-strikethrough"
tooltipLabel={t('richTextEditor.strikethrough')}
/>
<MenuButtonSubscript
data-ui-element="rich-text-menu-item-subscript"
tooltipLabel={t('richTextEditor.subscript')}
/>
<MenuButtonSuperscript
data-ui-element="rich-text-menu-item-superscript"
tooltipLabel={t('richTextEditor.superscript')}
/>
<MenuDivider />
<MenuButtonEditLink
data-ui-element="rich-text-menu-item-edit-link"
tooltipLabel={t('richTextEditor.link')}
/>
<MenuDivider />
<MenuButtonOrderedList
data-ui-element="rich-text-menu-item-ordered-list"
tooltipLabel={t('richTextEditor.orderedList')}
/>
<MenuButtonBulletedList
data-ui-element="rich-text-menu-item-bullet-list"
tooltipLabel={t('richTextEditor.bulletedList')}
/>
<MenuButtonTaskList
data-ui-element="rich-text-menu-item-task-list"
tooltipLabel={t('richTextEditor.taskChecklist')}
/>
<MenuDivider />
<MenuButtonBlockquote
data-ui-element="rich-text-menu-item-blockquote"
tooltipLabel={t('richTextEditor.blockquote')}
/>
<MenuDivider />
<MenuButtonCode
data-ui-element="rich-text-menu-item-code"
tooltipLabel={t('richTextEditor.code')}
/>
<MenuButtonCodeBlock
data-ui-element="rich-text-menu-item-code-block"
tooltipLabel={t('richTextEditor.codeBlock')}
/>
<MenuDivider />
<MenuButtonHorizontalRule
data-ui-element="rich-text-menu-item-horizontal-rule"
tooltipLabel={t('richTextEditor.insertHorizontalLine')}
/>
<MenuButtonRemoveFormatting
data-ui-element="rich-text-menu-item-remove-formatting"
tooltipLabel={t('richTextEditor.removeInlineFormatting')}
/>
</MenuControlsContainer>
)}
/>
<LinkBubbleMenu
labels={{
viewLinkEditButtonLabel: t('edit'),
viewLinkRemoveButtonLabel: t('remove'),
editLinkAddTitle: t('richTextEditor.addLink'),
editLinkEditTitle: t('richTextEditor.editLink'),
editLinkCancelButtonLabel: t('cancel'),
editLinkTextInputLabel: t('text'),
editLinkHrefInputLabel: t('richTextEditor.link'),
editLinkSaveButtonLabel: t('save'),
}}
/>
</RichTextEditorProvider>
</ThemeProvider>
Ok, maybe that's also a bug that happens because of my shadow dom. But when I give an initial value to the content property, the html and the styling is not right.
when I give the string
"<p><span style="color: #333333; font-family: helvetica, 'microsoft sans serif', arial, sans-serif; font-size: 12px; background-color: #ffffdd;">Der Untersuchungsrahmen nach §7 NABEG weist auf die Möglichkeit von</span></p>"
to the content, the html rendered this:
<p><span style="color: #333333">Der Untersuchungsrahmen nach §7 NABEG weist auf die Möglichkeit von</span></p>
so half of the styling is missing...
BTW great work you're doing, the best looking and working editor I've seen so far...
When draggable
is enabled on non-inline items , and text is selected , the selection is lost - randomly .
Please include a CodeSandbox demo of the problem if possible. (You can fork this CodeSandbox.)
Steps to reproduce the behavior:
Text selectable
If applicable, add screenshots to help explain your problem.
You can use this easily as a controlled component like this
const [content, setContent] = useState('');
useEffect(() => {
setContent(<p>Some saved content</p>)
}, []);
<RichTextEditor
content={content}
onUpdate={({ editor }) => {
setContent(editor.getHTML());
}}
/>
I am using the following code programmatically to set a new content to my editor:
const currentSelection = editor?.state.selection || 0; editor?.chain().setContent(newContent).setTextSelection(currentSelection).run();
I was expecting that the useEditor hook callback for onUpdate would be called. Is there any callback that gets executed when setting the content for the editor programmatically?
Setting the content programmatically to the editor should call the useEditor hook onUpdate callback.
Wanted to use this package, but seeing react-icons being added as an extra dependency to my project is a bummer. Would love if there is an option to only use the mui icons that are already available in every mui project.
I am not sure whether there's just documentation missing or this isn't possible yet, but I was unable to figure out how to do it.
In my project I have defined a theme for MUI stylings, and the TipTap is properly using them. However, in my case, I need to be able to override styles for particular components, only when they're used inside TipTap. For example, here's how I can style a button from a theme definition file:
createTheme({
components: {
MuiInputBase: {
styleOverrides: {
root: {
height: '32px',
},
input: {
fontSize: '14px',
fontWeight: 400,
},
},
},
}
})
In a similar fashion, I'd like to be able to select the tiptap root and then apply relative styling for classes that are inside it, maybe something like this:
createTheme({
components: {
MuiTipTap: {
styleOverrides: {
// some styling for the texteditor maybe?
},
'& .MenuButton-root': {
background: 'blue'
}
}
}
})
I understand I can wrap the editor in a box and then put styling in there and select classes I need to change, but it would be much better to be able to select the editors components from the theme. Thank you!
Hi, thanks for this project. Very easy to get started with and looks like a good API so far :)
I personally don't like the "compressed" style chosen for the editor content:
EDIT: I had another style which set the line-height to be smaller which exacerbate the issue. Without this using the default 1.5 line-height things looks a lot better.
I see that many styling elements can be adjusted using the MUI theme mechanism (very nice), but the margin is locked to 0 unless I'm mistaken.
I'm not sure what the best solution would be, but a contentClassName
prop which disables the default style if set would be simple solution. This would allow a user to provide a fully customized style. Doing slight modifications would require building a whole new set of styles (though I see the getEditorStyles
is importable, so maybe possible to use that as a base), but I think that would be fine. Especially since many slight modifications can be done using the MUI theme. (or through RichTextContentProps
)
I've passed in a class name to the RichTextContent
using RichTextContentProps
to override the margins on h1
, p
, etc.. The problem is that unless the specificity is perfectly balanced, such overrides mess up the table styling[1] - adding unwanted margins inside the cells. Balancing the specificity require controlling the CSS order, which in some cases is not trivial.
[1] The header margin class end up overriding .css-s26in7-RichTextField-content-RichTextContent-root-RichTextContent-editable .ProseMirror table td > * { margin-bottom: 0px; }
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.