-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
feat(dashboard): in-app editor form fields based on codemirror #6809
Conversation
✅ Deploy Preview for novu-stg-vite-dashboard-poc ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
@@ -43,10 +43,14 @@ | |||
"@segment/analytics-next": "^1.73.0", | |||
"@sentry/react": "^8.35.0", | |||
"@tanstack/react-query": "^5.59.6", | |||
"@uiw/codemirror-theme-white": "^4.23.6", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the CodeMirror white theme as default; we will adjust it to our needs
"@xyflow/react": "^12.3.2", | ||
"class-variance-authority": "^0.7.0", | ||
"clsx": "^2.1.1", | ||
"cmdk": "1.0.0", | ||
"codemirror-lang-liquid": "^1.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
liquid syntax and autocomplete
const editorVariants = cva('-mx-1 -mt-[2px] h-full w-full flex-1 [&_.cm-focused]:outline-none', { | ||
variants: { | ||
size: { | ||
default: 'text-xs [&_.cm-editor]:py-1', | ||
md: 'text-sm [&_.cm-editor]:py-2', | ||
}, | ||
}, | ||
defaultVariants: { | ||
size: 'default', | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these styles adjust the editor to look good when placed inside the InputField
component; basically to have the correct padding from the top
useEffect(() => { | ||
if (editor.current) { | ||
setContainer(editor.current); | ||
} | ||
}, [setContainer]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the recommended way from the docs
export const Editor = ({ value, placeholder, className, height, size, onChange }: EditorProps) => { | ||
const editor = useRef<HTMLDivElement>(null); | ||
const { setContainer } = useCodeMirror({ | ||
extensions: [LiquidHTML({}), EditorView.lineWrapping], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
liquid and line wrapping extensions
placeholder={placeholder} | ||
value={value.url} | ||
onChange={(val) => onChange({ ...value, url: val })} | ||
height={size === 'md' ? '38px' : '30px'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to do this better without hardcoding these values, basically, our inputs heights are md 40px
and default 32px
. These values exclude border.
And the height should be set if we want to have "single line" input, otherwise the editor will be growing with more content.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'll move to constants or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we using code mirror in online inputs to reuse the autocomplete functionality for variables? It's a smart approach to keep it dry, although it feels like an overkill for simple text or email inputs. I wonder if it's more future proof to have the autocomplete CodeMirror offers for code text areas and then implement it again with a popover for regular inputs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we use it in all form fields, subject, redirect etc.
The "regular" single-line fields are limited in the number of characters that you can type and also the way it works currently with CodeMirror is not optimal as you can move the text to the next line and in this case the previous line won't be visible. We need to think about the pattern here, the potential solution might be to have "auto" height on the fields, but then you can't build all types of form UI with this approach as you can easily break the UI.
@@ -178,7 +179,7 @@ const ConfigureActionPopover = ( | |||
}} | |||
> | |||
<PopoverTrigger {...rest} /> | |||
<PopoverContent> | |||
<PopoverContent className="max-w-72"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the editor fields expand the popover content, so I had to set the max
const [subject, setSubject] = useState(''); | ||
const [body, setBody] = useState(''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just temporarily
@novu/client
@novu/headless
@novu/framework
@novu/js
@novu/nest
@novu/nextjs
@novu/node
@novu/notification-center
novu
@novu/providers
@novu/react
@novu/react-native
@novu/shared
@novu/stateless
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code mirror!!! Yay!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I approve this one and we will chat about using CodeMirror editor across for all form fields separately.
placeholder={placeholder} | ||
value={value.url} | ||
onChange={(val) => onChange({ ...value, url: val })} | ||
height={size === 'md' ? '38px' : '30px'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we using code mirror in online inputs to reuse the autocomplete functionality for variables? It's a smart approach to keep it dry, although it feels like an overkill for simple text or email inputs. I wonder if it's more future proof to have the autocomplete CodeMirror offers for code text areas and then implement it again with a popover for regular inputs.
c66e756
to
4f7e176
Compare
4f7e176
to
840d002
Compare
840d002
to
23a001a
Compare
23a001a
to
15aa3de
Compare
What changed? Why was the change needed?
In-App Editor - updated the form fields to be based on the "editor" primitive, which is the CodeMirror component.
TODO:
Screenshots