Skip to content

Commit

Permalink
feat(dashboard): Add indentWithTab prop to Editor (#7411)
Browse files Browse the repository at this point in the history
  • Loading branch information
desiprisg authored Dec 31, 2024
1 parent 2c21e44 commit 7584918
Show file tree
Hide file tree
Showing 16 changed files with 75 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { EditorView } from '@uiw/react-codemirror';
import { Info } from 'lucide-react';
import { RiInputField, RiLayoutLine } from 'react-icons/ri';
import { FormProvider, useFormContext, UseFormReturn } from 'react-hook-form';
import { EditorView } from '@uiw/react-codemirror';
import { RiInputField, RiLayoutLine } from 'react-icons/ri';

import { InAppActionDropdown } from '@/components/in-app-action-dropdown';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/primitives/accordion';
import { ColorPicker } from '@/components/primitives/color-picker';
import type { InboxPlaygroundFormData } from './inbox-playground';
import { Editor } from '@/components/primitives/editor';
import { FormControl, FormField, FormItem } from '@/components/primitives/form/form';
import { InputField } from '@/components/primitives/input';
import { Editor } from '@/components/primitives/editor';
import { capitalize } from '@/utils/string';
import { InAppActionDropdown } from '@/components/in-app-action-dropdown';
import type { InboxPlaygroundFormData } from './inbox-playground';

interface PreviewStyle {
id: string;
Expand Down Expand Up @@ -173,6 +173,8 @@ function NotificationConfigSection() {
<FormItem className="w-full">
<FormControl>
<Editor
singleLine
indentWithTab={false}
fontFamily="inherit"
placeholder={capitalize(field.name)}
id={field.name}
Expand All @@ -195,6 +197,7 @@ function NotificationConfigSection() {
<InputField className="h-36 px-1">
<Editor
fontFamily="inherit"
indentWithTab={false}
placeholder={capitalize(field.name)}
id={field.name}
extensions={extensions}
Expand Down
2 changes: 2 additions & 0 deletions apps/dashboard/src/components/in-app-action-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ const ConfigureActionPopover = (props: ComponentProps<typeof PopoverTrigger> & {
<FormControl>
<InputField size="fit">
<Editor
singleLine
indentWithTab={false}
fontFamily="inherit"
placeholder="Button text"
value={field.value}
Expand Down
29 changes: 18 additions & 11 deletions apps/dashboard/src/components/primitives/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { flushSync } from 'react-dom';
import { useCodeMirror, ReactCodeMirrorProps, EditorView } from '@uiw/react-codemirror';
import createTheme from '@uiw/codemirror-themes';
import { autocompleteFooter, autocompleteHeader, functionIcon } from '@/components/primitives/constants';
import { tags as t } from '@lezer/highlight';
import createTheme from '@uiw/codemirror-themes';
import { EditorView, ReactCodeMirrorProps, useCodeMirror } from '@uiw/react-codemirror';
import { cva, VariantProps } from 'class-variance-authority';
import { autocompleteFooter, autocompleteHeader, functionIcon } from '@/components/primitives/constants';
import React, { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { flushSync } from 'react-dom';

const editorVariants = cva('h-full w-full flex-1 [&_.cm-focused]:outline-none', {
variants: {
Expand All @@ -18,12 +18,12 @@ const editorVariants = cva('h-full w-full flex-1 [&_.cm-focused]:outline-none',
},
});

const baseTheme = (options: { asInput?: boolean }) =>
const baseTheme = (options: { singleLine?: boolean }) =>
EditorView.baseTheme({
'&light': {
backgroundColor: 'transparent',
},
...(options.asInput
...(options.singleLine
? {
'.cm-scroller': {
overflow: 'hidden',
Expand Down Expand Up @@ -114,9 +114,10 @@ const baseTheme = (options: { asInput?: boolean }) =>

type EditorProps = {
value: string;
asInput?: boolean;
singleLine?: boolean;
placeholder?: string;
className?: string;
indentWithTab?: boolean;
height?: string;
onChange?: (value: string) => void;
fontFamily?: 'inherit';
Expand All @@ -131,9 +132,10 @@ export const Editor = React.forwardRef<{ focus: () => void; blur: () => void },
className,
height,
size,
asInput,
singleLine,
fontFamily,
onChange,
indentWithTab,
extensions: extensionsProp,
basicSetup: basicSetupProp,
...restCodeMirrorProps
Expand All @@ -142,15 +144,19 @@ export const Editor = React.forwardRef<{ focus: () => void; blur: () => void },
) => {
const editorRef = useRef<HTMLDivElement>(null);
const [shouldFocus, setShouldFocus] = useState(false);
const extensions = useMemo(() => [...(extensionsProp ?? []), baseTheme({ asInput })], [extensionsProp, asInput]);
const extensions = useMemo(
() => [...(extensionsProp ?? []), baseTheme({ singleLine })],
[extensionsProp, singleLine]
);
const basicSetup = useMemo(
() => ({
lineNumbers: false,
foldGutter: false,
highlightActiveLine: false,
defaultKeymap: !singleLine,
...((typeof basicSetupProp === 'object' ? basicSetupProp : {}) ?? {}),
}),
[basicSetupProp]
[basicSetupProp, singleLine]
);

const theme = useMemo(
Expand Down Expand Up @@ -189,6 +195,7 @@ export const Editor = React.forwardRef<{ focus: () => void; blur: () => void },
placeholder,
basicSetup,
container: editorRef.current,
indentWithTab,
value,
onChange: onChangeCallback,
theme,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export const AvatarPicker = forwardRef<HTMLInputElement, AvatarPickerProps>(
<Label>Avatar URL</Label>
<InputField size="fit">
<Editor
singleLine
indentWithTab={false}
fontFamily="inherit"
ref={ref}
placeholder="Enter avatar URL"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const BaseBody = () => {
<FormControl>
<InputField className="h-36 px-1">
<Editor
indentWithTab={false}
fontFamily="inherit"
placeholder={capitalize(field.name)}
id={field.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export const BaseSubject = () => {
<FormControl>
<InputField size="fit" className="px-1">
<Editor
singleLine
indentWithTab={false}
fontFamily="inherit"
placeholder={capitalize(field.name)}
id={field.name}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { RiBookMarkedLine, RiInputField, RiQuestionLine } from 'react-icons/ri';
import { motion } from 'motion/react';
import { Link } from 'react-router-dom';
import { RJSFSchema } from '@rjsf/utils';
import { type ControlsMetadata } from '@novu/shared';
import { ConfirmationModal } from '@/components/confirmation-modal';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/primitives/accordion';
import { InlineToast } from '@/components/primitives/inline-toast';
import { Separator } from '@/components/primitives/separator';
import { Switch } from '@/components/primitives/switch';
import { SidebarContent } from '@/components/side-navigation/sidebar';
import { useSaveForm } from '@/components/workflow-editor/steps/save-form-context';
import { WorkflowOriginEnum } from '@/utils/enums';
import { buildDefaultValuesOfDataSchema } from '@/utils/schema';
import { cn } from '@/utils/ui';
import { JsonForm } from './json-form';
import { useSaveForm } from '@/components/workflow-editor/steps/save-form-context';
import { type ControlsMetadata } from '@novu/shared';
import { RJSFSchema } from '@rjsf/utils';
import { motion } from 'motion/react';
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { RiBookMarkedLine, RiInputField, RiQuestionLine } from 'react-icons/ri';
import { Link } from 'react-router-dom';
import { useWorkflow } from '../../workflow-provider';
import { buildDefaultValuesOfDataSchema } from '@/utils/schema';
import { SidebarContent } from '@/components/side-navigation/sidebar';
import { ConfirmationModal } from '@/components/confirmation-modal';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/primitives/accordion';
import { InlineToast } from '@/components/primitives/inline-toast';
import { JsonForm } from './json-form';

type CustomStepControlsProps = {
dataSchema: ControlsMetadata['dataSchema'];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RegistryWidgetsType, UiSchema } from '@rjsf/utils';
import { ComponentProps } from 'react';
import { SelectWidget } from './select-widget';
import { SwitchWidget } from './switch-widget';
import { TextWidget } from './text-widget';
Expand All @@ -22,7 +23,7 @@ export const UI_SCHEMA: UiSchema = {

export const WIDGETS: RegistryWidgetsType = {
TextWidget: TextWidget,
URLWidget: TextWidget,
URLWidget: (props: ComponentProps<typeof TextWidget>) => <TextWidget {...props} singleLine />,
EmailWidget: TextWidget,
CheckboxWidget: SwitchWidget,
SelectWidget: SelectWidget,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export function TextWidget(props: WidgetProps) {
/>
) : (
<Editor
indentWithTab={false}
fontFamily="inherit"
placeholder={capitalize(label)}
id={label}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { autocompletion } from '@codemirror/autocomplete';
import { useMemo } from 'react';
import { useFormContext } from 'react-hook-form';
import { autocompletion } from '@codemirror/autocomplete';

import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/primitives/form/form';
import { InputFieldPure } from '@/components/primitives/input';
import { Code2 } from '@/components/icons/code-2';
import { Editor } from '@/components/primitives/editor';
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/primitives/form/form';
import { InputFieldPure } from '@/components/primitives/input';
import { useWorkflow } from '@/components/workflow-editor/workflow-provider';
import { parseStepVariablesToLiquidVariables } from '@/utils/parseStepVariablesToLiquidVariables';
import { completions } from '@/utils/liquid-autocomplete';
import { parseStepVariablesToLiquidVariables } from '@/utils/parseStepVariablesToLiquidVariables';

export const DigestKey = () => {
const { control } = useFormContext();
Expand All @@ -33,6 +33,8 @@ export const DigestKey = () => {
</FormLabel>
<FormControl>
<Editor
singleLine
indentWithTab={false}
fontFamily="inherit"
ref={field.ref}
placeholder="Add additional digest..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export const EmailSubject = () => {
<FormControl>
<Editor
size="lg"
singleLine
indentWithTab={false}
autoFocus={!field.value}
fontFamily="inherit"
placeholder={capitalize(field.name)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { WorkflowOriginEnum } from '@novu/shared';
import { StepEditorProps } from '@/components/workflow-editor/steps/configure-step-template-form';
import { EmailEditor } from '@/components/workflow-editor/steps/email/email-editor';
import { EmailEditorPreview } from '@/components/workflow-editor/steps/email/email-editor-preview';
import { CustomStepControls } from '../controls/custom-step-controls';
import { StepEditorProps } from '@/components/workflow-editor/steps/configure-step-template-form';
import { TemplateTabs } from '@/components/workflow-editor/steps/template-tabs';
import { WorkflowOriginEnum } from '@novu/shared';
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { CustomStepControls } from '../controls/custom-step-controls';
import { useEditorPreview } from '../use-editor-preview';

export const EmailTabs = (props: StepEditorProps) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const InAppBody = () => {
<InputField className="h-36 px-1">
<Editor
fontFamily="inherit"
indentWithTab={false}
placeholder={capitalize(field.name)}
id={field.name}
extensions={extensions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export const InAppSubject = () => {
<FormControl>
<Editor
fontFamily="inherit"
singleLine
indentWithTab={false}
placeholder={capitalize(field.name)}
id={field.name}
extensions={extensions}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { EditorView } from '@uiw/react-codemirror';
import { loadLanguage, LanguageName } from '@uiw/codemirror-extensions-langs';
import { Editor } from '@/components/primitives/editor';
import { LanguageName, loadLanguage } from '@uiw/codemirror-extensions-langs';
import { EditorView } from '@uiw/react-codemirror';
import { useMemo } from 'react';
import type { SnippetLanguage } from './types';

const basicSetup = { lineNumbers: true };
Expand Down
8 changes: 6 additions & 2 deletions apps/dashboard/src/components/workflow-editor/url-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { Editor } from '@/components/primitives/editor';
import { FormControl, FormField, FormItem, FormMessagePure } from '@/components/primitives/form/form';
import { Input, InputFieldProps, InputFieldPure, InputProps } from '@/components/primitives/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/primitives/select';
import { useSaveForm } from '@/components/workflow-editor/steps/save-form-context';
import { completions } from '@/utils/liquid-autocomplete';
import { LiquidVariable } from '@/utils/parseStepVariablesToLiquidVariables';
import { autocompletion } from '@codemirror/autocomplete';
import { useSaveForm } from '@/components/workflow-editor/steps/save-form-context';

type URLInputProps = Omit<InputProps, 'value' | 'onChange' | 'size'> & {
options: string[];
Expand Down Expand Up @@ -49,7 +49,11 @@ export const URLInput = ({
<FormControl>
{asEditor ? (
<Editor
asInput
singleLine
indentWithTab={false}
basicSetup={{
defaultKeymap: false,
}}
fontFamily="inherit"
placeholder={placeholder}
extensions={extensions}
Expand Down

0 comments on commit 7584918

Please sign in to comment.