Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
lib
react-ag-qeditor
Commits
bfd5fe15
Commit
bfd5fe15
authored
Aug 29, 2026
by
Яков
Browse files
update
parent
f888d58c
Changes
3
Show whitespace changes
Inline
Side-by-side
package.json
View file @
bfd5fe15
{
{
"name"
:
"react-ag-qeditor"
,
"name"
:
"react-ag-qeditor"
,
"version"
:
"1.1.8
4
"
,
"version"
:
"1.1.8
5
"
,
"description"
:
"WYSIWYG html editor"
,
"description"
:
"WYSIWYG html editor"
,
"author"
:
"atma"
,
"author"
:
"atma"
,
"license"
:
"
MIT
"
,
"license"
:
"
MIT
"
,
...
...
src/QEditor.jsx
View file @
bfd5fe15
...
@@ -953,6 +953,17 @@ const QEditor = ({
...
@@ -953,6 +953,17 @@ const QEditor = ({
})
})
// Открытие окна само по себе не трогает документ, а `shouldShow`
// у меню над выделением пересчитывается только на изменениях редактора.
// Без этого толчка меню осталось бы висеть до следующего нажатия клавиши.
// Пустая транзакция ничего не меняет в тексте — она лишь заставляет
// пересчитать видимость.
useEffect
(()
=>
{
if
(
editor
&&
!
editor
.
isDestroyed
)
{
editor
.
view
.
dispatch
(
editor
.
state
.
tr
)
}
},
[
modalGlossaryIsOpen
,
modalIsOpen
])
const
buildActionsModal
=
(
buttons
=
[])
=>
{
const
buildActionsModal
=
(
buttons
=
[])
=>
{
if
(
buttons
.
length
===
0
)
{
if
(
buttons
.
length
===
0
)
{
return
null
return
null
...
@@ -2030,6 +2041,19 @@ const QEditor = ({
...
@@ -2030,6 +2041,19 @@ const QEditor = ({
typpyOptions
=
{
{
followCursor
:
true
}
}
typpyOptions
=
{
{
followCursor
:
true
}
}
editor
=
{
editor
}
editor
=
{
editor
}
shouldShow
=
{
({...
o
})
=>
{
shouldShow
=
{
({...
o
})
=>
{
// Открыто окно — меню над выделением прячем.
//
// Выделение при открытии окна никуда не девается,
// поэтому меню продолжало висеть ПОВЕРХ модалки:
// нажимаешь «Добавить в глоссарий», окно открылось,
// а панелька так и стоит сверху. Своего z-index у неё
// нет — она в портале tippy, который заведомо выше
// модалки, так что чинить надо условием показа,
// а не слоями.
if
(
modalGlossaryIsOpen
||
modalIsOpen
)
{
return
false
}
if
(
o
.
state
.
selection
instanceof
NodeSelection
)
{
if
(
o
.
state
.
selection
instanceof
NodeSelection
)
{
const
selectedNode
=
o
.
state
.
selection
.
node
const
selectedNode
=
o
.
state
.
selection
.
node
...
@@ -2190,27 +2214,38 @@ const QEditor = ({
...
@@ -2190,27 +2214,38 @@ const QEditor = ({
{
getInnerModal
()
}
{
getInnerModal
()
}
{
buildActionsModal
(
buttons
)
}
{
buildActionsModal
(
buttons
)
}
</
EditorModal
>
</
EditorModal
>
{
/*
Ширина 560, а не 1100. Было «во весь экран» под два поля:
термин и короткое описание. Широкая форма читается хуже —
глаз идёт через пустое поле от подписи к вводу, — и заодно
накрывала собой текст модуля, из-за чего было непонятно,
к какому слову относится окно.
Кнопки — та же разметка и те же классы, что у остальных окон
редактора (buildActionsModal). Раньше здесь стояли кнопки antd:
другая форма, другой отступ и «Отменить» вместо «Отмена».
Два окна одного редактора не должны выглядеть из разных мест.
*/
}
<
Modal
<
Modal
width
=
{
110
0
}
width
=
{
56
0
}
open
=
{
modalGlossaryIsOpen
}
open
=
{
modalGlossaryIsOpen
}
title
=
{
'
Добавить слово
'
}
title
=
{
'
Добавить слово
'
}
onCancel
=
{
()
=>
{
onCancel
=
{
()
=>
{
setModalGlossaryIsOpen
(
false
);
setModalGlossaryIsOpen
(
false
);
}
}
}
}
footer
=
{
[
footer
=
{
<
Button
key
=
{
1
}
<
div
className
=
'atma-editor-modal-action'
>
size
=
{
'
middle
'
}
<
button
type
=
'button'
type
=
{
'
text
'
}
className
=
'atma-editor-btn atma-editor-cancel'
onClick
=
{
()
=>
{
onClick
=
{
()
=>
{
setModalGlossaryIsOpen
(
false
);
setModalGlossaryIsOpen
(
false
);
}
}
>
Отменить
</
Button
>,
}
}
>
Отмена
</
button
>
<
Button
key
=
{
2
}
<
button
type
=
'submit'
size
=
{
'
middle
'
}
type
=
{
'
primary
'
}
htmlType
=
{
'
submit
'
}
form
=
{
'
form-glossary
'
}
form
=
{
'
form-glossary
'
}
>
Сохранить
</
Button
>
className
=
'atma-editor-btn atma-editor-complete'
]
}
>
Сохранить
</
button
>
</
div
>
}
>
>
<
Form
<
Form
ref
=
{
formRef
}
ref
=
{
formRef
}
...
@@ -2220,7 +2255,7 @@ const QEditor = ({
...
@@ -2220,7 +2255,7 @@ const QEditor = ({
wrapperCol
=
{
{
span
:
32
}
}
wrapperCol
=
{
{
span
:
32
}
}
layout
=
"vertical"
layout
=
"vertical"
size
=
"middle"
size
=
"middle"
style
=
{
{
margin
:
'
3
0px
'
}
}
style
=
{
{
margin
Top
:
'
2
0px
'
}
}
onFinish
=
{
(
values
)
=>
{
onFinish
=
{
(
values
)
=>
{
editWord
(
values
);
editWord
(
values
);
}
}
}
}
...
...
src/icons.js
View file @
bfd5fe15
...
@@ -52,7 +52,18 @@ const ICONS = {
...
@@ -52,7 +52,18 @@ const ICONS = {
export_pdf
:
'
<path d="M6.3999999999999995 3h11.200000000000001a1.8 1.8 0 0 1 1.8 1.8v5.800000000000001a1.8 1.8 0 0 1 -1.8 1.8h-11.200000000000001a1.8 1.8 0 0 1 -1.8 -1.8v-5.800000000000001a1.8 1.8 0 0 1 1.8 -1.8z"></path><path d="M13.2 3v4.2a1.5 1.5 0 0 0 1.5 1.5h4.7"></path><path d="M12 14v6.6"></path><path d="M8.9 17.5 12 20.6l3.1-3.1"></path>
'
,
export_pdf
:
'
<path d="M6.3999999999999995 3h11.200000000000001a1.8 1.8 0 0 1 1.8 1.8v5.800000000000001a1.8 1.8 0 0 1 -1.8 1.8h-11.200000000000001a1.8 1.8 0 0 1 -1.8 -1.8v-5.800000000000001a1.8 1.8 0 0 1 1.8 -1.8z"></path><path d="M13.2 3v4.2a1.5 1.5 0 0 0 1.5 1.5h4.7"></path><path d="M12 14v6.6"></path><path d="M8.9 17.5 12 20.6l3.1-3.1"></path>
'
,
file
:
'
<path d="M5.5 6h13a2.5 2.5 0 0 1 2.5 2.5v7a2.5 2.5 0 0 1 -2.5 2.5h-13a2.5 2.5 0 0 1 -2.5 -2.5v-7a2.5 2.5 0 0 1 2.5 -2.5z"></path><path d="M7 9h2.5999999999999996a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-2.5999999999999996a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1z"></path><path d="M13.2 11h5"></path><path d="M13.2 15h3.2"></path>
'
,
file
:
'
<path d="M5.5 6h13a2.5 2.5 0 0 1 2.5 2.5v7a2.5 2.5 0 0 1 -2.5 2.5h-13a2.5 2.5 0 0 1 -2.5 -2.5v-7a2.5 2.5 0 0 1 2.5 -2.5z"></path><path d="M7 9h2.5999999999999996a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-2.5999999999999996a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1z"></path><path d="M13.2 11h5"></path><path d="M13.2 15h3.2"></path>
'
,
fontSize
:
'
<path d="M6 7.6v8.8"></path><path d="M4 9.6 6 7.6l2 2"></path><path d="M4 14.4l2 2 2-2"></path><path d="M11.5 8h8.5"></path><path d="M11.5 12h8.5"></path><path d="M11.5 16h5"></path>
'
,
fontSize
:
'
<path d="M6 7.6v8.8"></path><path d="M4 9.6 6 7.6l2 2"></path><path d="M4 14.4l2 2 2-2"></path><path d="M11.5 8h8.5"></path><path d="M11.5 12h8.5"></path><path d="M11.5 16h5"></path>
'
,
glossary
:
'
<path d="M7 3.4h10a2 2 0 0 1 2 2v3a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-3a2 2 0 0 1 2 -2z"></path><path d="M10.9 10.4l1.1 2.2 1.1-2.2"></path><path d="M6.6 16.4h10.8"></path><path d="M6.6 20h10.8" stroke-dasharray="1.8 2.4"></path>
'
,
// Глоссарий — ТА ЖЕ иконка, что в левом меню платформы
// (`public/i/glossary.svg`), а не своя из набора.
//
// Здесь важнее совпасть с платформой, чем с набором: одна и та же вещь
// должна выглядеть одинаково в меню и в редакторе, иначе автор не свяжет
// кнопку с разделом, куда попадёт слово. Отсюда исключение из правил
// набора: рисунок залит, а не обведён. Цвет всё равно наследуется —
// `fill="currentColor"`, поэтому все шесть состояний работают как у прочих.
//
// Исходник 16×14, поэтому масштаб 1.25 и сдвиг: так он встаёт в поле 20×20
// общей сетки 24×24.
glossary
:
'
<g transform="translate(2 3.25) scale(1.25)" fill="currentColor" stroke="none"><path d="M15.4286 0.734376H11.3429C10.4661 0.734376 9.60893 0.986161 8.87143 1.46116L8 2.02009L7.12857 1.46116C6.39181 0.986252 5.53371 0.733907 4.65714 0.734376H0.571429C0.255357 0.734376 0 0.989733 0 1.3058V11.4487C0 11.7647 0.255357 12.0201 0.571429 12.0201H4.65714C5.53393 12.0201 6.39107 12.2719 7.12857 12.7469L7.92143 13.2576C7.94464 13.2719 7.97143 13.2808 7.99821 13.2808C8.025 13.2808 8.05179 13.2737 8.075 13.2576L8.86786 12.7469C9.60714 12.2719 10.4661 12.0201 11.3429 12.0201H15.4286C15.7446 12.0201 16 11.7647 16 11.4487V1.3058C16 0.989733 15.7446 0.734376 15.4286 0.734376ZM4.65714 10.7344H1.28571V2.02009H4.65714C5.28929 2.02009 5.90357 2.20045 6.43393 2.54152L7.30536 3.10045L7.42857 3.1808V11.4308C6.57857 10.9737 5.62857 10.7344 4.65714 10.7344ZM14.7143 10.7344H11.3429C10.3714 10.7344 9.42143 10.9737 8.57143 11.4308V3.1808L8.69464 3.10045L9.56607 2.54152C10.0964 2.20045 10.7107 2.02009 11.3429 2.02009H14.7143V10.7344ZM5.94464 4.3058H2.62679C2.55714 4.3058 2.5 4.36652 2.5 4.43973V5.2433C2.5 5.31652 2.55714 5.37723 2.62679 5.37723H5.94286C6.0125 5.37723 6.06964 5.31652 6.06964 5.2433V4.43973C6.07143 4.36652 6.01429 4.3058 5.94464 4.3058ZM9.92857 4.43973V5.2433C9.92857 5.31652 9.98571 5.37723 10.0554 5.37723H13.3714C13.4411 5.37723 13.4982 5.31652 13.4982 5.2433V4.43973C13.4982 4.36652 13.4411 4.3058 13.3714 4.3058H10.0554C9.98571 4.3058 9.92857 4.36652 9.92857 4.43973ZM5.94464 6.8058H2.62679C2.55714 6.8058 2.5 6.86652 2.5 6.93973V7.7433C2.5 7.81652 2.55714 7.87723 2.62679 7.87723H5.94286C6.0125 7.87723 6.06964 7.81652 6.06964 7.7433V6.93973C6.07143 6.86652 6.01429 6.8058 5.94464 6.8058ZM13.3732 6.8058H10.0554C9.98571 6.8058 9.92857 6.86652 9.92857 6.93973V7.7433C9.92857 7.81652 9.98571 7.87723 10.0554 7.87723H13.3714C13.4411 7.87723 13.4982 7.81652 13.4982 7.7433V6.93973C13.5 6.86652 13.4429 6.8058 13.3732 6.8058Z"></path></g>
'
,
hardBreak
:
'
<path d="M20 6.4v5.6a2.5 2.5 0 0 1-2.5 2.5H5"></path><path d="M8.5 11 5 14.5 8.5 18"></path>
'
,
hardBreak
:
'
<path d="M20 6.4v5.6a2.5 2.5 0 0 1-2.5 2.5H5"></path><path d="M8.5 11 5 14.5 8.5 18"></path>
'
,
highlight
:
'
<path d="M6.4 6.2h11.2" stroke-width="2.2"></path><path d="M6.6000000000000005 10.4h10.799999999999999a2.2 2.2 0 0 1 2.2 2.2v2.1999999999999993a2.2 2.2 0 0 1 -2.2 2.2h-10.799999999999999a2.2 2.2 0 0 1 -2.2 -2.2v-2.1999999999999993a2.2 2.2 0 0 1 2.2 -2.2z"></path><path d="M7.6 13.7h8.8" stroke-width="2.4"></path><path d="M6.4 20.6h8" stroke-width="2.2"></path>
'
,
highlight
:
'
<path d="M6.4 6.2h11.2" stroke-width="2.2"></path><path d="M6.6000000000000005 10.4h10.799999999999999a2.2 2.2 0 0 1 2.2 2.2v2.1999999999999993a2.2 2.2 0 0 1 -2.2 2.2h-10.799999999999999a2.2 2.2 0 0 1 -2.2 -2.2v-2.1999999999999993a2.2 2.2 0 0 1 2.2 -2.2z"></path><path d="M7.6 13.7h8.8" stroke-width="2.4"></path><path d="M6.4 20.6h8" stroke-width="2.2"></path>
'
,
hr
:
'
<path d="M5 5.6h14"></path><path d="M5 9h9"></path><path d="M3.5 13h17" stroke-width="2.2"></path><path d="M5 17h14"></path><path d="M5 20.4h6"></path>
'
,
hr
:
'
<path d="M5 5.6h14"></path><path d="M5 9h9"></path><path d="M3.5 13h17" stroke-width="2.2"></path><path d="M5 17h14"></path><path d="M5 20.4h6"></path>
'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment