Bullet and Numeric list
This commit is contained in:
parent
f50a072293
commit
9090560302
3
public/icons/editor-ol.svg
Normal file
3
public/icons/editor-ol.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="19" height="16" viewBox="0 0 19 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.00002 4.00003H1.00001V1.00001H0V0H2.00002V4.00003ZM2.00002 13.5V13H0V12H3.00003V16H0V15H2.00002V14.5H1.00001V13.5H2.00002ZM0 6.99998H1.80002L0 9.1V10H3.00003V9H1.20001L3.00003 6.89998V5.99998H0V6.99998ZM4.9987 2.99967V0.999648H18.9988V2.99967H4.9987ZM4.9987 15.0001H18.9988V13.0001H4.9987V15.0001ZM18.9988 8.99987H4.9987V6.99986H18.9988V8.99987Z" fill="currentColor"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 524 B |
|
@ -237,5 +237,6 @@
|
||||||
"Enter URL address": "Enter URL address",
|
"Enter URL address": "Enter URL address",
|
||||||
"Invalid url format": "Invalid url format",
|
"Invalid url format": "Invalid url format",
|
||||||
"Headers": "Headers",
|
"Headers": "Headers",
|
||||||
"Quotes": "Quotes"
|
"Quotes": "Quotes",
|
||||||
|
"Lists": "Lists"
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,5 +255,6 @@
|
||||||
"Enter URL address": "Введите адрес ссылки",
|
"Enter URL address": "Введите адрес ссылки",
|
||||||
"Invalid url format": "Неверный формат ссылки",
|
"Invalid url format": "Неверный формат ссылки",
|
||||||
"Headers": "Заголовки",
|
"Headers": "Заголовки",
|
||||||
"Quotes": "Цитаты"
|
"Quotes": "Цитаты",
|
||||||
|
"Lists": "Списки"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
|
||||||
|
.triangle {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
|
@ -80,10 +84,14 @@
|
||||||
.actions {
|
.actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: flex-start;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.bubbleMenuButton {
|
.bubbleMenuButton {
|
||||||
min-width: 40px;
|
min-width: 40px;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { clsx } from 'clsx'
|
||||||
import { createEditorTransaction } from 'solid-tiptap'
|
import { createEditorTransaction } from 'solid-tiptap'
|
||||||
import { useLocalize } from '../../context/localize'
|
import { useLocalize } from '../../context/localize'
|
||||||
import validateUrl from '../../utils/validateUrl'
|
import validateUrl from '../../utils/validateUrl'
|
||||||
|
import list from '../Feed/List'
|
||||||
|
|
||||||
type BubbleMenuProps = {
|
type BubbleMenuProps = {
|
||||||
editor: Editor
|
editor: Editor
|
||||||
|
@ -15,6 +16,7 @@ type BubbleMenuProps = {
|
||||||
export const EditorBubbleMenu = (props: BubbleMenuProps) => {
|
export const EditorBubbleMenu = (props: BubbleMenuProps) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const [textSizeBubbleOpen, setTextSizeBubbleOpen] = createSignal<boolean>(false)
|
const [textSizeBubbleOpen, setTextSizeBubbleOpen] = createSignal<boolean>(false)
|
||||||
|
const [listBubbleOpen, setListBubbleOpen] = createSignal<boolean>(false)
|
||||||
const [linkEditorOpen, setLinkEditorOpen] = createSignal<boolean>(false)
|
const [linkEditorOpen, setLinkEditorOpen] = createSignal<boolean>(false)
|
||||||
const [url, setUrl] = createSignal<string>('')
|
const [url, setUrl] = createSignal<string>('')
|
||||||
const [prevUrl, setPrevUrl] = createSignal<string | null>(null)
|
const [prevUrl, setPrevUrl] = createSignal<string | null>(null)
|
||||||
|
@ -46,6 +48,15 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => {
|
||||||
() => props.editor,
|
() => props.editor,
|
||||||
(editor) => editor && editor.isActive('blockquote')
|
(editor) => editor && editor.isActive('blockquote')
|
||||||
)
|
)
|
||||||
|
const isOrderedList = createEditorTransaction(
|
||||||
|
() => props.editor,
|
||||||
|
(editor) => editor && editor.isActive('isOrderedList')
|
||||||
|
)
|
||||||
|
const isBulletList = createEditorTransaction(
|
||||||
|
() => props.editor,
|
||||||
|
(editor) => editor && editor.isActive('isBulletList')
|
||||||
|
)
|
||||||
|
|
||||||
const isLink = createEditorTransaction(
|
const isLink = createEditorTransaction(
|
||||||
() => props.editor,
|
() => props.editor,
|
||||||
(editor) => {
|
(editor) => {
|
||||||
|
@ -75,6 +86,15 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleTextSizePopup = () => {
|
||||||
|
if (listBubbleOpen()) setListBubbleOpen(false)
|
||||||
|
setTextSizeBubbleOpen((prev) => !prev)
|
||||||
|
}
|
||||||
|
const toggleListPopup = () => {
|
||||||
|
if (textSizeBubbleOpen()) setTextSizeBubbleOpen(false)
|
||||||
|
setListBubbleOpen((prev) => !prev)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div ref={props.ref} class={styles.bubbleMenu}>
|
<div ref={props.ref} class={styles.bubbleMenu}>
|
||||||
|
@ -105,10 +125,10 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => {
|
||||||
class={clsx(styles.bubbleMenuButton, {
|
class={clsx(styles.bubbleMenuButton, {
|
||||||
[styles.bubbleMenuButtonActive]: textSizeBubbleOpen()
|
[styles.bubbleMenuButtonActive]: textSizeBubbleOpen()
|
||||||
})}
|
})}
|
||||||
onClick={() => setTextSizeBubbleOpen(!textSizeBubbleOpen())}
|
onClick={toggleTextSizePopup}
|
||||||
>
|
>
|
||||||
<Icon name="editor-text-size" />
|
<Icon name="editor-text-size" />
|
||||||
<Icon name="down-triangle" />
|
<Icon name="down-triangle" class={styles.triangle} />
|
||||||
</button>
|
</button>
|
||||||
<Show when={textSizeBubbleOpen()}>
|
<Show when={textSizeBubbleOpen()}>
|
||||||
<div class={styles.dropDown}>
|
<div class={styles.dropDown}>
|
||||||
|
@ -192,9 +212,41 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => {
|
||||||
<Icon name="editor-footnote" />
|
<Icon name="editor-footnote" />
|
||||||
</button>
|
</button>
|
||||||
<div class={styles.delimiter} />
|
<div class={styles.delimiter} />
|
||||||
<button type="button" class={styles.bubbleMenuButton}>
|
<div class={styles.dropDownHolder}>
|
||||||
<Icon name="editor-ul" />
|
<button
|
||||||
</button>
|
type="button"
|
||||||
|
class={clsx(styles.bubbleMenuButton, { [styles.bubbleMenuButtonActive]: listBubbleOpen() })}
|
||||||
|
onClick={toggleListPopup}
|
||||||
|
>
|
||||||
|
<Icon name="editor-ul" />
|
||||||
|
<Icon name="down-triangle" class={styles.triangle} />
|
||||||
|
</button>
|
||||||
|
<Show when={listBubbleOpen()}>
|
||||||
|
<div class={styles.dropDown}>
|
||||||
|
<header>{t('Lists')}</header>
|
||||||
|
<div class={styles.actions}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class={clsx(styles.bubbleMenuButton, {
|
||||||
|
[styles.bubbleMenuButtonActive]: isBulletList()
|
||||||
|
})}
|
||||||
|
onClick={() => props.editor.commands.toggleBulletList()}
|
||||||
|
>
|
||||||
|
<Icon name="editor-ul" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class={clsx(styles.bubbleMenuButton, {
|
||||||
|
[styles.bubbleMenuButtonActive]: isOrderedList()
|
||||||
|
})}
|
||||||
|
onClick={() => props.editor.commands.toggleOrderedList()}
|
||||||
|
>
|
||||||
|
<Icon name="editor-ol" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user