Should we move the Chakra UI Prose package in the core library? #469
Replies: 6 comments 4 replies
-
Love the idea to build a rich text editor into Chakra. We used tiptap at work which is a headless rich text editor built on top of Prose as well. Because it's headless, we were able to build the view with Chakra components. I really like the way this turned out, so excited to see what you guys can do with an official Chakra Prose package! |
Beta Was this translation helpful? Give feedback.
-
I think would be great to keep it as a separate Chakra UI package |
Beta Was this translation helpful? Give feedback.
-
Finally! Prose, As a heavy Chakra UI user who has built sites, applications for clients I am so glad to see this. I don't think it needs to be a core offering but @chakra-ui/prose would be a nice touch. I just added prose to a blog and removed 50+ lines of code that basically passed each HTML element to a component. |
Beta Was this translation helpful? Give feedback.
-
I'm working on a blog which used TailwindCSS earlier & is gradually migrating to Chakra-UI. The blog used the Also I think the project might benefit better if it was moved under the official Chakra-UI GitHub organisation (considering it's already being maintained by a Chakra-UI developer!) Moving the project under an official banner will gather more exposure to the project as well. |
Beta Was this translation helpful? Give feedback.
-
I would love to see this in the core package. This is something that I feel is greatly missing from Chakra UI and can greatly improve the library. |
Beta Was this translation helpful? Give feedback.
-
For anyone else where just restyling the components isn't enough and would up here like me, I created a parser which turns a html string into chakra-ui components. I needed it especially for turning links into next.js links so the state doesn't break on parsed links. I don't think that this should be in the main chakra-ui core library but I really do appreciate the theme config which I copy and pasted into my projects, I think this should be somewhere linked to from the chakra-ui docs though (it might be already I don't know 100%). <3 Here's a gist, and a preview below import type { As } from '@chakra-ui/react'
import { Heading, ListItem, OrderedList, Text } from '@chakra-ui/react'
import { NextLink } from 'design_system/utility/NextLink'
import type { DOMNode, Element, HTMLReactParserOptions } from 'html-react-parser'
import parse, { domToReact } from 'html-react-parser'
export const headingSizes = {
h1: ['4xl', '5xl', '6xl'],
h2: ['3xl', '4xl', '5xl'],
h3: ['2xl', '3xl', '4xl'],
h4: ['xl', '2xl', '3xl'],
h5: ['lg', 'xl', '2xl'],
h6: ['md', 'lg', 'xl'],
}
export type HeadingKey = keyof typeof headingSizes
export const asComponent = (plainHtml: string) => {
return <>{parse(plainHtml, options)}</>
}
function isParsedElement (domNode: DOMNode | Element): domNode is Element {
return domNode.constructor.name === 'Element' || domNode.type === 'tag'
}
const toCamelCase = (s: string) => s.replace(/-./g, x => x[1].toUpperCase())
const styleStringAsObject = (style: string) => {
const noWhitespaces = style.replace(/\s+/g, '')
const attributes = noWhitespaces.split(';')
return Object.fromEntries(attributes.map(attribute => {
const entry = attribute.split(/:(.+)/) // TODO refactor adds an unneccesary empty element at the end hence the filter on value
const key = entry.splice(0, 1)[0]
const value = entry.filter(e => e !== '').join(':')
return [key, value]
}))
}
const options: HTMLReactParserOptions = {
replace: domNode => {
if (isParsedElement(domNode)) {
const children = domNode.children
const tagName = domNode.name
const safeAttribs: { [key: string]: string | object } = {}
for (const [key, value] of Object.entries(domNode.attribs)) {
const safeKey = toCamelCase(key)
if (safeKey === 'style') {
safeAttribs[safeKey] = styleStringAsObject(value)
} else {
safeAttribs[safeKey] = value
}
}
const reHeading = /^h\d$/
if (tagName.match(reHeading)) {
const heading: As = (tagName as As)
return (
<Heading
as={heading}
marginLeft="auto"
marginRight="auto"
fontSize={headingSizes[tagName as HeadingKey]}
pb={['8px', '20px']}
pt={['20px', '40px']}
lineHeight={1}
{...safeAttribs}
>{domToReact(children, options)}
</Heading>
)
}
switch (tagName) {
case 'a': {
return (
<NextLink
color="primary.500"
_hover={{
textDecoration: 'underline',
}}
{...safeAttribs}
>{domToReact(children, options)}
</NextLink>
)
}
case 'ul': {
return (
<OrderedList
lineHeight="2rem"
{...safeAttribs}
>{domToReact(children, options)}
</OrderedList>
)
}
.... |
Beta Was this translation helpful? Give feedback.
-
Recently I've developed a Chakra UI Prose package that adds ready-made styling to a remote HTML content. We decided to roll it out as a separate package is to avoid bloating the core library while we figure out how much people actually need it.
This discussion will help us figure out if we should move it in the core library package. Let us know what you think. Add a reaction or comment if you need this to be part of the core package.
Beta Was this translation helpful? Give feedback.
All reactions