reflex/reflex/components/suneditor/editor.py
Khaleel Al-Adhami 085b761f6b
replace old var system with immutable one (#3916)
* delete most references to varr

* [REF-3562][REF-3563] Replace chakra usage (#3872)

* only one mention of var

* delete vars.py why not

* remove reflex.vars

* rename immutable var to var

* rename ivars to vars

* add vars back smh

* ruff

* no more create_safe

* reorder deprecated

* remove raises

* remove all Var.create

* move to new api

* fix unit tests

* fix pyi hopefully

* sort literals

* fix event handler issues

* update poetry

* fix silly issues i'm very silly

* add var_operation_return

* rename immutable to not immutable

* add str type

* it's ruff out there

---------

Co-authored-by: Elijah Ahianyo <elijahahianyo@gmail.com>
2024-09-13 16:01:52 -07:00

245 lines
7.4 KiB
Python

"""A Rich Text Editor based on SunEditor."""
from __future__ import annotations
import enum
from typing import Dict, List, Literal, Optional, Union
from reflex.base import Base
from reflex.components.component import Component, NoSSRComponent
from reflex.event import EventHandler
from reflex.utils.format import to_camel_case
from reflex.utils.imports import ImportDict, ImportVar
from reflex.vars.base import Var
class EditorButtonList(list, enum.Enum):
"""List enum that provides three predefined button lists."""
BASIC = [
["font", "fontSize"],
["fontColor"],
["horizontalRule"],
["link", "image"],
]
FORMATTING = [
["undo", "redo"],
["bold", "underline", "italic", "strike", "subscript", "superscript"],
["removeFormat"],
["outdent", "indent"],
["fullScreen", "showBlocks", "codeView"],
["preview", "print"],
]
COMPLEX = [
["undo", "redo"],
["font", "fontSize", "formatBlock"],
["bold", "underline", "italic", "strike", "subscript", "superscript"],
["removeFormat"],
"/",
["fontColor", "hiliteColor"],
["outdent", "indent"],
["align", "horizontalRule", "list", "table"],
["link", "image", "video"],
["fullScreen", "showBlocks", "codeView"],
["preview", "print"],
["save", "template"],
]
class EditorOptions(Base):
"""Some of the additional options to configure the Editor.
Complete list of options found here:
https://github.com/JiHong88/SunEditor/blob/master/README.md#options.
"""
# Specifies default tag name of the editor.
# default: 'p' {String}
default_tag: Optional[str] = None
# The mode of the editor ('classic', 'inline', 'balloon', 'balloon-always').
# default: 'classic' {String}
mode: Optional[str] = None
# If true, the editor is set to RTL(Right To Left) mode.
# default: false {Boolean}
rtl: Optional[bool] = None
# List of buttons to use in the toolbar.
button_list: Optional[List[Union[List[str], str]]]
class Editor(NoSSRComponent):
"""A Rich Text Editor component based on SunEditor.
Not every JS prop is listed here (some are not easily usable from python),
refer to the library docs for a complete list.
"""
library = "suneditor-react"
tag = "SunEditor"
is_default = True
lib_dependencies: List[str] = ["suneditor"]
# Language of the editor.
# Alternatively to a string, a dict of your language can be passed to this prop.
# Please refer to the library docs for this.
# options: "en" | "da" | "de" | "es" | "fr" | "ja" | "ko" | "pt_br" |
# "ru" | "zh_cn" | "ro" | "pl" | "ckb" | "lv" | "se" | "ua" | "he" | "it"
# default : "en"
lang: Var[
Union[
Literal[
"en",
"da",
"de",
"es",
"fr",
"ja",
"ko",
"pt_br",
"ru",
"zh_cn",
"ro",
"pl",
"ckb",
"lv",
"se",
"ua",
"he",
"it",
],
dict,
]
]
# This is used to set the HTML form name of the editor.
# This means on HTML form submission,
# it will be submitted together with contents of the editor by the name provided.
name: Var[str]
# Sets the default value of the editor.
# This is useful if you don't want the on_change method to be called on render.
# If you want the on_change method to be called on render please use the set_contents prop
default_value: Var[str]
# Sets the width of the editor.
# px and percentage values are accepted, eg width="100%" or width="500px"
# default: 100%
width: Var[str]
# Sets the height of the editor.
# px and percentage values are accepted, eg height="100%" or height="100px"
height: Var[str]
# Sets the placeholder of the editor.
placeholder: Var[str]
# Should the editor receive focus when initialized?
auto_focus: Var[bool]
# Pass an EditorOptions instance to modify the behaviour of Editor even more.
set_options: Var[Dict]
# Whether all SunEditor plugins should be loaded.
# default: True
set_all_plugins: Var[bool]
# Set the content of the editor.
# Note: To set the initial contents of the editor
# without calling the on_change event,
# please use the default_value prop.
# set_contents is used to set the contents of the editor programmatically.
# You must be aware that, when the set_contents's prop changes,
# the on_change event is triggered.
set_contents: Var[str]
# Append editor content
append_contents: Var[str]
# Sets the default style of the editor's edit area
set_default_style: Var[str]
# Disable the editor
# default: False
disable: Var[bool]
# Hide the editor
# default: False
hide: Var[bool]
# Hide the editor toolbar
# default: False
hide_toolbar: Var[bool]
# Disable the editor toolbar
# default: False
disable_toolbar: Var[bool]
# Fired when the editor content changes.
on_change: EventHandler[lambda content: [content]]
# Fired when the something is inputted in the editor.
on_input: EventHandler[lambda e: [e]]
# Fired when the editor loses focus.
on_blur: EventHandler[lambda e, content: [content]]
# Fired when the editor is loaded.
on_load: EventHandler[lambda reload: [reload]]
# Fired when the editor is resized.
on_resize_editor: EventHandler[lambda height, prev_height: [height, prev_height]]
# Fired when the editor content is copied.
on_copy: EventHandler[lambda e, clipboard_data: [clipboard_data]]
# Fired when the editor content is cut.
on_cut: EventHandler[lambda e, clipboard_data: [clipboard_data]]
# Fired when the editor content is pasted.
on_paste: EventHandler[
lambda e, clean_data, max_char_count: [clean_data, max_char_count]
]
# Fired when the code view is toggled.
toggle_code_view: EventHandler[lambda is_code_view: [is_code_view]]
# Fired when the full screen mode is toggled.
toggle_full_screen: EventHandler[lambda is_full_screen: [is_full_screen]]
def add_imports(self) -> ImportDict:
"""Add imports for the Editor component.
Returns:
The import dict.
"""
return {
"": ImportVar(tag="suneditor/dist/css/suneditor.min.css", install=False)
}
@classmethod
def create(cls, set_options: Optional[EditorOptions] = None, **props) -> Component:
"""Create an instance of Editor. No children allowed.
Args:
set_options(Optional[EditorOptions]): Configuration object to further configure the instance.
**props: Any properties to be passed to the Editor
Returns:
An Editor instance.
Raises:
ValueError: If set_options is a state Var.
"""
if set_options is not None:
if isinstance(set_options, Var):
raise ValueError("EditorOptions cannot be a state Var")
props["set_options"] = {
to_camel_case(k): v
for k, v in set_options.dict().items()
if v is not None
}
return super().create(*[], **props)