Skip to content

Commit 59e5d88

Browse files
committed
Rik teksteditor
1 parent 04f6e6c commit 59e5d88

File tree

10 files changed

+345
-273
lines changed

10 files changed

+345
-273
lines changed

.github/workflows/deploy.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
deploy-til-dev:
4444
name: Deploy til dev-gcp
4545
needs: bygg-og-push-docker-image
46-
if: github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/markerte-kandidater'
46+
if: github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/riktekst'
4747
runs-on: ubuntu-latest
4848
steps:
4949
- uses: actions/checkout@v3

package-lock.json

+247-96
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@tiptap/extension-underline": "^2.5.5",
4444
"@tiptap/pm": "^2.5.5",
4545
"@tiptap/react": "^2.5.5",
46+
"@tiptap/starter-kit": "^2.11.5",
4647
"classnames": "2.5.1",
4748
"deep-equal": "2.2.3",
4849
"history": "^5.3.0",

public/editor/iconbold.svg

+3
Loading

public/editor/iconitalic.svg

+3
Loading

public/editor/iconlist.svg

+3
Loading

public/editor/iconredo.svg

+3
Loading

public/editor/iconundo.svg

+3
Loading

src/felles/komponenter/rikteksteditor/RikTekstEditor.module.css

+9
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,12 @@
2424
.inaktivKnapp {
2525
background: #ffff;
2626
}
27+
28+
.editorContent {
29+
max-width: none;
30+
}
31+
32+
.editorContent :global(ul) {
33+
list-style-type: disc;
34+
padding-left: 1.5rem;
35+
}

src/felles/komponenter/rikteksteditor/RikTekstEditor.tsx

+72-176
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,12 @@
1-
import {
2-
ArrowRedoIcon,
3-
ArrowUndoIcon,
4-
BulletListIcon,
5-
ChevronRightDoubleIcon,
6-
LinkBrokenIcon,
7-
LinkIcon,
8-
NumberListIcon,
9-
} from '@navikt/aksel-icons';
10-
import { ErrorMessage, Loader } from '@navikt/ds-react';
11-
import Blockquote from '@tiptap/extension-blockquote';
12-
import Bold from '@tiptap/extension-bold';
13-
import BulletList from '@tiptap/extension-bullet-list';
14-
import Document from '@tiptap/extension-document';
15-
import HardBreak from '@tiptap/extension-hard-break';
16-
import Heading from '@tiptap/extension-heading';
17-
import History from '@tiptap/extension-history';
18-
import Italic from '@tiptap/extension-italic';
19-
import Link from '@tiptap/extension-link';
20-
import ListItem from '@tiptap/extension-list-item';
21-
import OrderedList from '@tiptap/extension-ordered-list';
22-
import Paragraph from '@tiptap/extension-paragraph';
23-
import Text from '@tiptap/extension-text';
24-
import Underline from '@tiptap/extension-underline';
1+
import { Box, Button, ErrorMessage } from '@navikt/ds-react';
252
import { EditorContent, useEditor } from '@tiptap/react';
26-
import * as React from 'react';
27-
import style from './RikTekstEditor.module.css';
3+
import StarterKit from '@tiptap/starter-kit';
4+
import IconBold from '../../../../public/editor/iconbold.svg';
5+
import IconItalic from '../../../../public/editor/iconitalic.svg';
6+
import IconList from '../../../../public/editor/iconlist.svg';
7+
import IconRedo from '../../../../public/editor/iconredo.svg';
8+
import IconUndo from '../../../../public/editor/iconundo.svg';
9+
import styles from './RikTekstEditor.module.css';
2810

2911
export interface IRikTekstEditor {
3012
skjulToolbar?: boolean;
@@ -41,166 +23,80 @@ const RikTekstEditor: React.FC<IRikTekstEditor> = ({
4123
skjulToolbar,
4224
feilMelding,
4325
}) => {
44-
const [headerValue, setHeaderValue] = React.useState<number>(0);
26+
const extensions = [
27+
StarterKit.configure({
28+
orderedList: false,
29+
blockquote: false,
30+
code: false,
31+
codeBlock: false,
32+
horizontalRule: false,
33+
strike: false,
34+
}),
35+
];
4536

4637
const editor = useEditor({
47-
extensions: [
48-
HardBreak,
49-
Document,
50-
Paragraph,
51-
Text,
52-
History,
53-
Bold,
54-
Italic,
55-
Underline,
56-
Blockquote,
57-
BulletList,
58-
OrderedList,
59-
ListItem,
60-
Link.configure({
61-
openOnClick: false,
62-
}),
63-
Heading.configure({
64-
levels: [1, 2, 3, 4, 5, 6],
65-
}),
66-
],
38+
extensions: extensions,
6739
content: tekst,
68-
onUpdate: ({ editor }) => onChange(editor.getHTML()),
69-
onTransaction: ({ editor, transaction }) => {
70-
if (transaction.selection) {
71-
const level = editor.getAttributes('heading').level;
72-
setHeaderValue(level ? level : 0);
73-
}
40+
onUpdate: ({ editor }) => {
41+
onChange(editor.getHTML());
7442
},
7543
});
7644

7745
if (!editor) {
78-
return <Loader />;
46+
return null;
7947
}
80-
81-
const setLink = () => {
82-
const url = prompt('Skriv inn lenke');
83-
if (url) {
84-
editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();
85-
}
86-
};
87-
88-
const unsetLink = () => {
89-
editor.chain().focus().unsetLink().run();
90-
};
91-
92-
const onSelectHeading = (value: string) => {
93-
const level = parseInt(value, 10);
94-
95-
if (level === 0) {
96-
editor.chain().focus().setParagraph().run();
97-
} else {
98-
// @ts-ignore
99-
editor.chain().focus().toggleHeading({ level }).run();
100-
}
101-
};
102-
10348
return (
104-
<div className={style.editor} id={id}>
105-
<div>
106-
{skjulToolbar ? (
107-
<div />
108-
) : (
109-
<div className={style.toolbar}>
110-
<select
111-
value={headerValue}
112-
onChange={(e) => onSelectHeading(e.target.value)}
113-
>
114-
<option value={0}>Normal</option>
115-
<option value={1}>H1</option>
116-
<option value={2}>H2</option>
117-
<option value={3}>H3</option>
118-
<option value={4}>H4</option>
119-
<option value={5}>H5</option>
120-
</select>
121-
<button
122-
onClick={() => editor.chain().focus().toggleBold().run()}
123-
className={
124-
editor.isActive('bold') ? style.aktivKnapp : style.inaktivKnapp
125-
}
126-
>
127-
<strong>B</strong>
128-
</button>
129-
<button
130-
onClick={() => editor.chain().focus().toggleItalic().run()}
131-
className={
132-
editor.isActive('italic') ? style.aktivKnapp : style.inaktivKnapp
133-
}
134-
>
135-
<strong>
136-
<i>I</i>
137-
</strong>
138-
</button>
139-
<button
140-
onClick={() => editor.chain().focus().toggleUnderline().run()}
141-
className={
142-
editor.isActive('underline') ? style.aktivKnapp : style.inaktivKnapp
143-
}
144-
>
145-
<strong>
146-
<ins>U</ins>
147-
</strong>
148-
</button>
149-
<button
150-
onClick={() => editor.chain().focus().toggleBlockquote().run()}
151-
className={style.inaktivKnapp}
152-
>
153-
<ChevronRightDoubleIcon />
154-
</button>
155-
<button
156-
onClick={() => editor.chain().focus().toggleBulletList().run()}
157-
className={
158-
editor.isActive('bulletList')
159-
? style.aktivKnapp
160-
: style.inaktivKnapp
161-
}
162-
>
163-
<BulletListIcon />
164-
</button>
165-
<button
166-
onClick={() => editor.chain().focus().toggleOrderedList().run()}
167-
className={
168-
editor.isActive('orderedList')
169-
? style.aktivKnapp
170-
: style.inaktivKnapp
171-
}
172-
>
173-
<NumberListIcon />
174-
</button>
175-
<button
176-
onClick={setLink}
177-
className={
178-
editor.isActive('link') ? style.aktivKnapp : style.inaktivKnapp
179-
}
180-
>
181-
<LinkIcon />
182-
</button>
183-
<button onClick={unsetLink} disabled={!editor.isActive('link')}>
184-
<LinkBrokenIcon />
185-
</button>
186-
<button
187-
onClick={() => editor.chain().focus().undo().run()}
188-
disabled={!editor.can().chain().focus().undo().run()}
189-
>
190-
<ArrowUndoIcon />
191-
</button>
192-
<button
193-
onClick={() => editor.chain().focus().redo().run()}
194-
disabled={!editor.can().chain().focus().redo().run()}
195-
>
196-
<ArrowRedoIcon />
197-
</button>
198-
</div>
199-
)}
200-
</div>
201-
<EditorContent editor={editor} />
49+
<Box borderWidth="1" padding="4" borderRadius="xlarge">
50+
{!skjulToolbar && (
51+
<Box style={{ display: 'flex', gap: '0.5rem', marginBottom: '10px' }}>
52+
<Button
53+
type="button"
54+
icon={<IconBold />}
55+
variant={editor.isActive('bold') ? 'primary-neutral' : 'secondary-neutral'}
56+
size="small"
57+
onClick={() => editor.commands.toggleBold()}
58+
aria-pressed={editor.isActive('bold')}
59+
/>
60+
<Button
61+
type="button"
62+
icon={<IconItalic />}
63+
variant={
64+
editor.isActive('italic') ? 'primary-neutral' : 'secondary-neutral'
65+
}
66+
size="small"
67+
onClick={() => editor.commands.toggleItalic()}
68+
aria-pressed={editor.isActive('italic')}
69+
/>
70+
<Button
71+
type="button"
72+
icon={<IconList />}
73+
variant={
74+
editor.isActive('bulletList') ? 'primary-neutral' : 'secondary-neutral'
75+
}
76+
size="small"
77+
onClick={() => editor.commands.toggleBulletList()}
78+
aria-pressed={editor.isActive('bulletList')}
79+
/>
80+
<Button
81+
type="button"
82+
icon={<IconUndo />}
83+
variant="secondary-neutral"
84+
size="small"
85+
onClick={() => editor.commands.undo()}
86+
/>
87+
<Button
88+
variant="secondary-neutral"
89+
type="button"
90+
icon={<IconRedo />}
91+
size="small"
92+
onClick={() => editor.commands.redo()}
93+
/>
94+
</Box>
95+
)}
96+
<hr />
97+
<EditorContent id={id} editor={editor} className={styles.editorContent} />
20298
{feilMelding && <ErrorMessage>{feilMelding}</ErrorMessage>}
203-
</div>
99+
</Box>
204100
);
205101
};
206102

0 commit comments

Comments
 (0)