Skip to content

Commit

Permalink
editor localization (#1351)
Browse files Browse the repository at this point in the history
* editor localization

* wire up the hungarian translation

* Add missing translations

* review fix
  • Loading branch information
Zoltan Takacs authored Jun 25, 2021
1 parent 0ea1143 commit f042f93
Show file tree
Hide file tree
Showing 19 changed files with 191 additions and 73 deletions.
32 changes: 4 additions & 28 deletions apps/sensenet/src/components/field-controls/rich-text-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,14 @@
* @module FieldControls
*/
import { ReactClientFieldSetting, RichTextEditor as SnRichTextEditor } from '@sensenet/controls-react'
import { createStyles, makeStyles, Theme } from '@material-ui/core'
import React from 'react'

const useStyles = makeStyles((theme: Theme) => {
return createStyles({
richTextEditor: {
width: '100%',
'& .ql-toolbar': {
backgroundColor: theme.palette.type === 'light' ? theme.palette.common.white : '#1e1e1e',
borderColor: theme.palette.type === 'light' ? 'rgb(204, 204, 204)' : '#1e1e1e',
},
'& .ql-fill': {
fill: theme.palette.type === 'light' ? '#444' : 'white',
},
'& .ql-stroke': {
stroke: theme.palette.type === 'light' ? '#444' : 'white',
},
'& .ql-picker-label': {
color: theme.palette.type === 'light' ? '#444' : 'white',
},
'& .ql-container': {
minHeight: '124px',
},
},
})
})
import { useLocalization } from '../../hooks'

/**
* Field control that represents a LongText field. Available values will be populated from the FieldSettings.
* Field control that represents a RichText field. Available values will be populated from the FieldSettings.
*/
export const RichTextEditor: React.FC<ReactClientFieldSetting> = (props) => {
const classes = useStyles()
const localization = useLocalization()

return <SnRichTextEditor {...props} classes={classes} />
return <SnRichTextEditor {...props} localization={{ richTextEditor: localization.editor }} />
}
5 changes: 4 additions & 1 deletion apps/sensenet/src/components/react-control-mapper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Repository } from '@sensenet/client-core'
import { FieldControls as SnFieldControls, reactControlMapper as snReactControlMapper } from '@sensenet/controls-react'
import { LongTextFieldSetting, ReferenceFieldSetting } from '@sensenet/default-content-types'
import { LongTextFieldSetting, ReferenceFieldSetting, RichTextFieldSetting } from '@sensenet/default-content-types'
import * as FieldControls from './field-controls'

/**
Expand Down Expand Up @@ -42,6 +42,9 @@ export const reactControlMapper = (repository: Repository) => {

return SnFieldControls.Textarea
})
.setupFieldSettingDefault<RichTextFieldSetting>('RichTextFieldSetting', () => {
return FieldControls.RichTextEditor
})
.setupFieldSettingDefault('NullFieldSetting', (setting) => {
if (setting.Name === 'Avatar') {
return FieldControls.Avatar
Expand Down
8 changes: 8 additions & 0 deletions apps/sensenet/src/localization/default.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import { DeepPartial } from '@sensenet/client-utils'
import { LocalizationType as EditorLocalization } from '@sensenet/editor-react'

export type Localization = DeepPartial<typeof import('./default').default> & {
editor?: EditorLocalization
}

const values = {
addButton: {
tooltip: 'Create or upload content',
Expand Down Expand Up @@ -631,6 +638,7 @@ const values = {
example: 'Example:',
defaultPayload: 'Default payload',
},
editor: {},
}

export default values
45 changes: 43 additions & 2 deletions apps/sensenet/src/localization/hungarian.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DeepPartial } from '@sensenet/client-utils'
import { Localization } from './default'

const values: DeepPartial<typeof import('./default').default> = {
const values: Localization = {
addButton: {
new: 'Új...',
addNew: 'Új hozzáadása',
Expand Down Expand Up @@ -306,6 +306,47 @@ const values: DeepPartial<typeof import('./default').default> = {
'Saját payload bármilyen valid JSON lehet. Ha az alapértelmezett payload-ot szeretné használni, hagyja üresen ezt a mezőt.',
example: 'Példa:',
},
editor: {
common: {
cancel: 'Mégse',
},
menubar: {
typography: 'Címsor',
bold: 'Félkövér',
italic: 'Dőlt',
underline: 'Aláhúzott',
blockquote: 'Idézet blokk',
code: 'Kód',
alignLeft: 'Balra igazítás',
alignCenter: 'Középre igazítás',
alignRight: 'Jobbra igazítás',
alignJustify: 'Sorkizárt',
bulletList: 'Felsorolás',
orderedList: 'Számozás',
link: 'Hivatkozás',
clearFormat: 'Formázás törlése',
undo: 'Visszavonás',
redo: 'Ismét',
},
bubbleMenu: {
removeImage: 'kép törlése',
removeLink: 'hivatkozás törlése',
},
imageControl: {
title: 'Képbeszúrás',
submit: 'Beszúrás',
},
linkControl: {
title: 'Hivatkozás beszúrása',
url: 'Url',
openInNewTab: 'Megnyitás új lapon',
submit: 'Beszúrás',
},
typographyControl: {
paragraph: 'Normál',
heading: 'Címsor',
},
},
}

export default values
5 changes: 4 additions & 1 deletion packages/sn-controls-react/src/fieldcontrols/localization.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DeepPartial } from '@sensenet/client-utils'
import { LocalizationType } from '@sensenet/editor-react'

export const defaultLocalization = {
allowedChildTypes: {
Expand Down Expand Up @@ -76,4 +77,6 @@ export const defaultLocalization = {
},
}

export type FieldLocalization = DeepPartial<typeof defaultLocalization>
export type FieldLocalization = DeepPartial<typeof defaultLocalization> & {
richTextEditor?: LocalizationType
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const RichTextEditor: React.FC<
<InputLabel shrink htmlFor={props.settings.Name} required={props.settings.Compulsory}>
{props.settings.DisplayName}
</InputLabel>

<Suspense
fallback={
<div style={{ textAlign: 'center' }}>
Expand All @@ -71,6 +72,7 @@ export const RichTextEditor: React.FC<
autofocus={props.autoFocus}
placeholder={props.settings.DisplayName}
readOnly={props.settings.ReadOnly}
localization={props.localization?.richTextEditor}
onChange={({ editor }) => {
props.fieldOnChange?.(props.settings.Name, {
text: editor.getHTML(),
Expand All @@ -79,6 +81,7 @@ export const RichTextEditor: React.FC<
}}
/>
</Suspense>

{!props.hideDescription && <FormHelperText>{props.settings.Description}</FormHelperText>}
</div>
)
Expand Down
1 change: 1 addition & 0 deletions packages/sn-editor-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@babel/runtime": "^7.13.9",
"@material-ui/core": "^4.11.4",
"@material-ui/icons": "^4.11.2",
"@sensenet/client-utils": "^2.1.0",
"@tiptap/core": "^2.0.0-beta.73",
"@tiptap/extension-blockquote": "^2.0.0-beta.13",
"@tiptap/extension-bold": "^2.0.0-beta.13",
Expand Down
7 changes: 5 additions & 2 deletions packages/sn-editor-react/src/components/bubble-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import CloseIcon from '@material-ui/icons/Close'
import DeleteIcon from '@material-ui/icons/Delete'
import { Editor, posToDOMRect, BubbleMenu as TiptapBubbleMenu } from '@tiptap/react'
import React, { FC } from 'react'
import { useLocalization } from '../hooks'

const useStyles = makeStyles((theme) => {
return createStyles({
Expand All @@ -28,6 +29,8 @@ interface BubbleMenuProps {

export const BubbleMenu: FC<BubbleMenuProps> = (props) => {
const classes = useStyles()
const localization = useLocalization()

return (
<TiptapBubbleMenu
className={classes.root}
Expand Down Expand Up @@ -55,7 +58,7 @@ export const BubbleMenu: FC<BubbleMenuProps> = (props) => {
editor={props.editor}>
{props.editor.isActive('image') && (
<IconButton
aria-label="remove image"
aria-label={localization.bubbleMenu.removeImage}
size="small"
onClick={() => props.editor.chain().focus().deleteSelection().run()}>
<DeleteIcon fontSize="inherit" />
Expand All @@ -72,7 +75,7 @@ export const BubbleMenu: FC<BubbleMenuProps> = (props) => {
{props.editor.getMarkAttributes('link').href}
</Link>
<IconButton
aria-label="remove link"
aria-label={localization.bubbleMenu.removeLink}
size="small"
onClick={() => props.editor.chain().focus().unsetLink().run()}>
<CloseIcon fontSize="inherit" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import ImageIcon from '@material-ui/icons/Image'
import { Editor } from '@tiptap/react'
import React, { FC, useRef, useState } from 'react'
import { useLocalization } from '../../hooks'

const useStyles = makeStyles(() => {
return createStyles({
Expand Down Expand Up @@ -42,6 +43,7 @@ export const ImageControl: FC<ImageControlProps> = ({ buttonProps, editor }) =>
const fileInput = useRef<HTMLInputElement>(null)

const classes = useStyles()
const localization = useLocalization()

const handleClickOpen = () => {
if (isUploadInProgress) {
Expand Down Expand Up @@ -91,7 +93,7 @@ export const ImageControl: FC<ImageControlProps> = ({ buttonProps, editor }) =>

return (
<>
<Tooltip title="Insert image">
<Tooltip title={localization.imageControl.title}>
<IconButton onClick={handleClickOpen} {...buttonProps}>
<ImageIcon />
</IconButton>
Expand Down Expand Up @@ -119,7 +121,7 @@ export const ImageControl: FC<ImageControlProps> = ({ buttonProps, editor }) =>
fileInput.current.value = ''
}
}}>
<DialogTitle id="form-dialog-title">Image insert</DialogTitle>
<DialogTitle id="form-dialog-title">{localization.imageControl.title}</DialogTitle>
<DialogContent>
{uploadedFile ? (
<>
Expand All @@ -133,14 +135,14 @@ export const ImageControl: FC<ImageControlProps> = ({ buttonProps, editor }) =>
)}
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleClose}>{localization.common.cancel}</Button>
<Button
onClick={() => {
handleClose()
addImage()
}}
color="primary">
Insert
{localization.imageControl.submit}
</Button>
</DialogActions>
</Dialog>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { Link } from '@material-ui/icons'
import { Editor } from '@tiptap/react'
import React, { FC, useState } from 'react'
import { useLocalization } from '../../hooks'

const useStyles = makeStyles(() => {
return createStyles({
Expand All @@ -35,6 +36,7 @@ export const LinkControl: FC<LinkControlProps> = ({ editor, buttonProps }) => {
const [link, setLink] = useState('')
const [inNewTab, setInNewTab] = useState(false)
const classes = useStyles()
const localization = useLocalization()

const handleClickOpen = () => {
if (editor.state.selection.empty) {
Expand Down Expand Up @@ -65,7 +67,7 @@ export const LinkControl: FC<LinkControlProps> = ({ editor, buttonProps }) => {

return (
<>
<Tooltip title="Link">
<Tooltip title={localization.menubar.link}>
<IconButton onClick={handleClickOpen} color={editor.isActive('link') ? 'primary' : 'default'} {...buttonProps}>
<Link />
</IconButton>
Expand All @@ -80,12 +82,12 @@ export const LinkControl: FC<LinkControlProps> = ({ editor, buttonProps }) => {
setLink('')
setInNewTab(false)
}}>
<DialogTitle id="link-control-title">Insert a link</DialogTitle>
<DialogTitle id="link-control-title">{localization.linkControl.title}</DialogTitle>
<DialogContent>
<TextField
autoFocus
margin="dense"
label="Url"
label={localization.linkControl.url}
type="url"
required
fullWidth
Expand All @@ -97,19 +99,19 @@ export const LinkControl: FC<LinkControlProps> = ({ editor, buttonProps }) => {
control={
<Checkbox checked={inNewTab} onChange={(event) => setInNewTab(event.target.checked)} color="primary" />
}
label="Open link in a new tab"
label={localization.linkControl.openInNewTab}
className={classes.inNewTab}
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleClose}>{localization.common.cancel}</Button>
<Button
onClick={() => {
handleClose()
addLink()
}}
color="primary">
Insert
{localization.linkControl.submit}
</Button>
</DialogActions>
</Dialog>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createStyles, makeStyles, MenuItem, Select, Tooltip } from '@material-u
import { Editor } from '@tiptap/core'
import { HeadingOptions } from '@tiptap/extension-heading'
import React, { ChangeEvent, FC } from 'react'
import { useLocalization } from '../../hooks'

const useStyles = makeStyles((theme) => {
return createStyles({
Expand All @@ -19,6 +20,7 @@ interface TypographyControlProps {
type Level = 0 | HeadingOptions['levels'][number]

export const TypographyControl: FC<TypographyControlProps> = (props) => {
const localization = useLocalization()
const classes = useStyles()
const getActiveValue = () => {
if (props.editor.isActive('paragraph')) {
Expand Down Expand Up @@ -49,7 +51,7 @@ export const TypographyControl: FC<TypographyControlProps> = (props) => {
}

return (
<Tooltip title="Heading">
<Tooltip title={localization.menubar.typography}>
<Select
id="demo-simple-select"
value={getActiveValue()}
Expand All @@ -67,13 +69,13 @@ export const TypographyControl: FC<TypographyControlProps> = (props) => {
},
getContentAnchorEl: null,
}}>
<MenuItem value={0}>Paragraph</MenuItem>
<MenuItem value={1}>Heading 1</MenuItem>
<MenuItem value={2}>Heading 2</MenuItem>
<MenuItem value={3}>Heading 3</MenuItem>
<MenuItem value={4}>Heading 4</MenuItem>
<MenuItem value={5}>Heading 5</MenuItem>
<MenuItem value={6}>Heading 6</MenuItem>
<MenuItem value={0}>{localization.typographyControl.paragraph}</MenuItem>
<MenuItem value={1}>{localization.typographyControl.heading} 1</MenuItem>
<MenuItem value={2}>{localization.typographyControl.heading} 2</MenuItem>
<MenuItem value={3}>{localization.typographyControl.heading} 3</MenuItem>
<MenuItem value={4}>{localization.typographyControl.heading} 4</MenuItem>
<MenuItem value={5}>{localization.typographyControl.heading} 5</MenuItem>
<MenuItem value={6}>{localization.typographyControl.heading} 6</MenuItem>
</Select>
</Tooltip>
)
Expand Down
Loading

0 comments on commit f042f93

Please sign in to comment.