Commit 3607e730 by Яков

update

parent 099e92bd
const path = require('path');
module.exports = {
webpack: {
configure: (webpackConfig) => {
webpackConfig.watchOptions = {
ignored: /node_modules(?!\/react-ag-qeditor)/,
};
return webpackConfig;
},
},
};
SKIP_PREFLIGHT_CHECK=true
DISABLE_ESLINT_PLUGIN=true
FAST_REFRESH=false
...@@ -4,15 +4,16 @@ ...@@ -4,15 +4,16 @@
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-scripts start", "start": "craco start",
"build": "react-scripts build", "build": "craco build",
"test": "react-scripts test", "test": "craco test",
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },
"dependencies": { "dependencies": {
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
"@craco/craco": "^7.1.0",
"react": "^17.0.2", "react": "^17.0.2",
"react-ag-qeditor": "file:..", "react-ag-qeditor": "*",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-scripts": "^5.0.1" "react-scripts": "^5.0.1"
}, },
......
...@@ -7,7 +7,8 @@ const App = () => { ...@@ -7,7 +7,8 @@ const App = () => {
return <div style={{padding:40}}> return <div style={{padding:40}}>
<QEditor <QEditor
// value={`<iframe src="https://cdn.atmaguru.online/2/atmacompany/8/b/8bTfGoWtAuv5waVabQRTtWaNOrve5uv8UBXFbGOH9cowQ1K56dYi7TFz6h5jUfzr.pdf" width="100%" /><iframe src="https://www.youtube.com/embed/YmZGP7YP8c4" frameborder="0" allowfullscreen="true"></iframe><video src="https://cdn.atmaguru.online/2/demo/V/k/VkrEXjkxnutXLgcJPt5CLXNgEj4RaL9Zk4SQhIMUjOeIRpu0dSKtQCIMl49pJM6N.webm" controls="true"></video><p>Так исторически сложилось, что взрослым людям стараются дать максимум материалов: часовые лекции, объемные массивы текста и должностных инструкций. Сотрудник изучает огромный объем информации. Пытается его запомнить, а потом в конце курса сдать большой аттестационный экзамен. Вы не учитывете при этом, что мозг взрослого человека перегружен, ему нужно выполнять обязанности по работе, думать о домашних делах, его постоянно отвлекают менеджеры и коллеги по работе… Единственный правильный способ — это давать информацию небольшими кусочками и после каждой порции проверять усвоена она или нет.</p><p></p><p>что-то новое о компании<br><a href="https://cdn.atmaguru.online/1/demo/T/G/TGvSAoLawONkteJ47yyNfmsC8zNe3ZRG4iO0ZfAjmvOIZkm20BWp8KdWCH5p1Rrx.gif" target="_blank" download="Редактор.gif" data-size="37 Мб">РСкачать книгу</a> <br></p>`} // value={`<iframe src="https://cdn.atmaguru.online/2/atmacompany/8/b/8bTfGoWtAuv5waVabQRTtWaNOrve5uv8UBXFbGOH9cowQ1K56dYi7TFz6h5jUfzr.pdf" width="100%" /><iframe src="https://www.youtube.com/embed/YmZGP7YP8c4" frameborder="0" allowfullscreen="true"></iframe><video src="https://cdn.atmaguru.online/2/demo/V/k/VkrEXjkxnutXLgcJPt5CLXNgEj4RaL9Zk4SQhIMUjOeIRpu0dSKtQCIMl49pJM6N.webm" controls="true"></video><p>Так исторически сложилось, что взрослым людям стараются дать максимум материалов: часовые лекции, объемные массивы текста и должностных инструкций. Сотрудник изучает огромный объем информации. Пытается его запомнить, а потом в конце курса сдать большой аттестационный экзамен. Вы не учитывете при этом, что мозг взрослого человека перегружен, ему нужно выполнять обязанности по работе, думать о домашних делах, его постоянно отвлекают менеджеры и коллеги по работе… Единственный правильный способ — это давать информацию небольшими кусочками и после каждой порции проверять усвоена она или нет.</p><p></p><p>что-то новое о компании<br><a href="https://cdn.atmaguru.online/1/demo/T/G/TGvSAoLawONkteJ47yyNfmsC8zNe3ZRG4iO0ZfAjmvOIZkm20BWp8KdWCH5p1Rrx.gif" target="_blank" download="Редактор.gif" data-size="37 Мб">РСкачать книгу</a> <br></p>`}
value={"<p style=\"text-align: left\"><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://telemost.yandex.ru/j/5911922929\">дшдлодлод</a></p><table data-bordered=\"true\" class=\"\" style=\"min-width: 75px\"><colgroup><col style=\"min-width: 25px\"><col style=\"min-width: 25px\"><col style=\"min-width: 25px\"></colgroup><tbody><tr><th colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></th><th colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\"></p></th><th colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></th></tr><tr><td colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></td><td colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\"></p></td><td colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></td></tr></tbody></table><p style=\"text-align: left\"></p>"} // value={"<p style=\"text-align: left\"><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://telemost.yandex.ru/j/5911922929\">дшдлодлод</a></p><table data-bordered=\"true\" class=\"\" style=\"min-width: 75px\"><colgroup><col style=\"min-width: 25px\"><col style=\"min-width: 25px\"><col style=\"min-width: 25px\"></colgroup><tbody><tr><th colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></th><th colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\"></p></th><th colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></th></tr><tr><td colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></td><td colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\"></p></td><td colspan=\"1\" rowspan=\"1\"><p style=\"text-align: left\">sdfsdf</p></td></tr></tbody></table><p style=\"text-align: left\"></p>"}
value={"<h2 style=\"text-align: center\">В данном разделе Вы сможете изучить профильные системы KRAUSS и их предназначения.</h2><h2 style=\"text-align: center\">Профильные системы с которыми мы работаем</h2><p style=\"text-align: left\"></p><p style=\"text-align: left\"><img src=\"https://cdn.atmaguru.online/1/galereya-okon/t/J/tJkxP0341Yu58FNTDNtan20IxGVVegvv4Ns8kQvn1SdiWbRBTKj009cPUNpYfD4S.png\" alt=\"fgdgdfdg&amp;#10;sdfsdf&amp;#10;SDfsdf&amp;#10;sdfsdf\" width=\"798\" height=\"449\" data-align=\"center\" style=\"display: block; margin-left: auto; margin-right: auto; width: 798px; height: 449px\" data-node-id=\"img-1752479121918-zsmot20zn\">​</p><p style=\"text-align: left\"><img src=\"https://cdn.atmaguru.online/1/galereya-okon/6/D/6DPwk96e0ja5vPaXFSDzz3SVmeJgWvMLeysYxxYXu5YgOjr57CxS21vzsMThgMgz.png\" alt=\"\" width=\"798\" height=\"431\" data-align=\"center\" style=\"display: block; margin-left: auto; margin-right: auto; width: 798px; height: 431px\" data-node-id=\"img-1752479121912-lk1uabgxv\">​</p><p style=\"text-align: left\"><span style=\"color: rgb(243, 76, 55)\"><strong>Примечание: профильные системы KRAUSS мы закупаем у компании \"Реалит\". Офис данной компании находится в г. Уфа.</strong></span></p><h2 style=\"text-align: left\"><a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://disk.yandex.ru/d/KvB3VMNFKu4ULg\">Ссылка для скачивания видео-курсов от компании \"Реалит\" https://disk.yandex.ru/d/KvB3VMNFKu4ULg</a></h2><h2 style=\"text-align: left\">Файл для скачивания: <a target=\"_blank\" rel=\"noopener noreferrer nofollow\" href=\"https://cdn.atmaguru.online/1/galereya-okon/4/N/4N30p3UR8gb4jph1m1u8KijlQmDp6H9DgHKucRjvxOPUnMprnJyBaK2S1dGZPqaD.pdf\">Профильные системы</a></h2><p style=\"text-align: left\"></p>"}
onChange={(value)=>{ onChange={(value)=>{
console.log(value); console.log(value);
}} }}
......
{ {
"name": "react-ag-qeditor", "name": "react-ag-qeditor",
"version": "1.1.6", "version": "1.1.7",
"description": "WYSIWYG html editor", "description": "WYSIWYG html editor",
"author": "atma", "author": "atma",
"license": "MIT", "license": "MIT",
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
"dist" "dist"
], ],
"dependencies": { "dependencies": {
"@ant-design/icons": "^6.0.0",
"@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-environment-visitor": "^7.24.7",
"@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
"@tiptap/core": "^2.12.0", "@tiptap/core": "^2.12.0",
......
...@@ -74,12 +74,51 @@ export const DragAndDrop = Extension.create({ ...@@ -74,12 +74,51 @@ export const DragAndDrop = Extension.create({
if (!result?.file_path) throw new Error('Invalid response from server'); if (!result?.file_path) throw new Error('Invalid response from server');
const node = view.state.schema.nodes[nodeType].create({
src: result.file_path, const id = `img-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
alt: file.name,
title: file.name, // Создадим временное изображение, чтобы определить размеры
'data-node-id': `img-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` if (nodeType === 'image') {
}); const img = new Image();
img.src = result.file_path;
img.onload = () => {
const editorElement = view.dom.closest('.atma-editor-content');
const editorWidth = editorElement ? editorElement.clientWidth : 800;
let width = img.naturalWidth;
let height = img.naturalHeight;
if (width > editorWidth) {
const ratio = editorWidth / width;
width = editorWidth;
height = Math.round(height * ratio);
}
const node = view.state.schema.nodes[nodeType].create({
src: result.file_path,
alt: file.name,
title: file.name,
width,
height,
align: 'left',
'data-node-id': id
});
const tr = view.state.tr.insert(position || view.state.selection.from, node);
view.dispatch(tr);
extension.options.onUploadSuccess(result);
};
} else {
const node = view.state.schema.nodes[nodeType].create({
src: result.file_path,
alt: file.name,
title: file.name,
'data-node-id': id
});
const tr = view.state.tr.insert(position || view.state.selection.from, node);
view.dispatch(tr);
extension.options.onUploadSuccess(result);
}
const tr = view.state.tr.insert(position || view.state.selection.from, node); const tr = view.state.tr.insert(position || view.state.selection.from, node);
view.dispatch(tr); view.dispatch(tr);
......
import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react"; import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
import React, { useEffect, useRef, useState, Fragment } from "react"; import React, { useEffect, useRef, useState, Fragment } from "react";
import TipTapImage from "@tiptap/extension-image"; import TipTapImage from "@tiptap/extension-image";
import { Button, Modal, Input } from 'antd';
import Icon, {FontSizeOutlined} from "@ant-design/icons";
const { TextArea } = Input;
const MIN_WIDTH = 60; const MIN_WIDTH = 60;
const BORDER_COLOR = '#0096fd'; const BORDER_COLOR = '#0096fd';
...@@ -12,6 +16,9 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select ...@@ -12,6 +16,9 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
const [showAlignMenu, setShowAlignMenu] = useState(false); const [showAlignMenu, setShowAlignMenu] = useState(false);
const isInitialized = useRef(false); const isInitialized = useRef(false);
const [isResizing, setIsResizing] = useState(false); const [isResizing, setIsResizing] = useState(false);
const [altModalVisible, setAltModalVisible] = useState(false);
const [tempAlt, setTempAlt] = useState(node.attrs.alt || '');
// Добавляем прозрачный нулевой пробел после изображения // Добавляем прозрачный нулевой пробел после изображения
useEffect(() => { useEffect(() => {
...@@ -391,6 +398,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select ...@@ -391,6 +398,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
}}> }}>
{ALIGN_OPTIONS.map(align => ( {ALIGN_OPTIONS.map(align => (
<button <button
type="button"
key={align} key={align}
onClick={() => handleAlign(align)} onClick={() => handleAlign(align)}
style={{ style={{
...@@ -409,6 +417,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select ...@@ -409,6 +417,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
)} )}
<button <button
type="button"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setShowAlignMenu(!showAlignMenu); setShowAlignMenu(!showAlignMenu);
...@@ -416,7 +425,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select ...@@ -416,7 +425,7 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
style={{ style={{
position: 'absolute', position: 'absolute',
top: -30, top: -30,
left: '50%', left: 'calc(50% - 6px)',
transform: 'translateX(-50%)', transform: 'translateX(-50%)',
backgroundColor: 'white', backgroundColor: 'white',
border: `1px solid ${BORDER_COLOR}`, border: `1px solid ${BORDER_COLOR}`,
...@@ -429,8 +438,45 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select ...@@ -429,8 +438,45 @@ const ResizableImageTemplate = ({ node, updateAttributes, editor, getPos, select
> >
Align Align
</button> </button>
<Button
size="default"
shape={'circle'}
type={node.attrs.alt?.length > 0 ? 'primary' : 'default'}
onClick={(e) => {
e.stopPropagation();
setTempAlt(node.attrs.alt || '');
setAltModalVisible(true);
}}
style={{
position: 'absolute',
top: 4,
right: 4,
zIndex: 15,
}}
>
<FontSizeOutlined />
</Button>
</Fragment> </Fragment>
)} )}
<Modal
title="Редактировать описание изображения (alt)"
open={altModalVisible}
onOk={() => {
updateAttributes({ alt: tempAlt });
setAltModalVisible(false);
}}
onCancel={() => setAltModalVisible(false)}
okText="Применить"
cancelText="Отмена"
>
<TextArea
value={tempAlt}
onChange={(e) => setTempAlt(e.target.value)}
rows={4}
placeholder="Введите alt-текст изображения..."
/>
</Modal>
</NodeViewWrapper> </NodeViewWrapper>
); );
}; };
...@@ -440,7 +486,18 @@ const ResizableImageExtension = TipTapImage.extend({ ...@@ -440,7 +486,18 @@ const ResizableImageExtension = TipTapImage.extend({
return { return {
...this.parent?.(), ...this.parent?.(),
src: { default: null }, src: { default: null },
alt: { default: null }, alt: {
default: null,
parseHTML: element => {
const raw = element.getAttribute('alt')
return raw?.replace(/&#10;/g, '\n') || null
},
renderHTML: attributes => {
return attributes.alt
? { alt: attributes.alt.replace(/\n/g, '&#10;') }
: {}
}
},
title: { default: null }, title: { default: null },
width: { width: {
default: null, default: null,
......
...@@ -32,9 +32,7 @@ export const ToggleBlockComponent = ({ node, updateAttributes }) => { ...@@ -32,9 +32,7 @@ export const ToggleBlockComponent = ({ node, updateAttributes }) => {
> >
{title || 'Заголовок'} {title || 'Заголовок'}
</span> </span>
<button className="toggle-button" onClick={toggle}> <button className={"toggle-button " + (open ? 'open' : '')} onClick={toggle}></button>
{open ? '▼' : '▶'}
</button>
<input <input
type="text" type="text"
className="toggle-header" className="toggle-header"
...@@ -49,8 +47,6 @@ export const ToggleBlockComponent = ({ node, updateAttributes }) => { ...@@ -49,8 +47,6 @@ export const ToggleBlockComponent = ({ node, updateAttributes }) => {
className="toggle-body" className="toggle-body"
style={{ style={{
maxHeight: open ? '1000px' : '0', maxHeight: open ? '1000px' : '0',
overflow: 'hidden',
transition: 'max-height 0.3s ease',
}} }}
> >
<div className="toggle-body-wrapper"> <div className="toggle-body-wrapper">
...@@ -75,7 +71,21 @@ const ToggleBlock = Node.create({ ...@@ -75,7 +71,21 @@ const ToggleBlock = Node.create({
}, },
parseHTML() { parseHTML() {
return [{ tag: 'div.toggle-block' }] return [{
tag: 'div.toggle-block',
getAttrs: (element) => {
const wrapper = element.querySelector('.toggle-block-inner')
const titleEl = wrapper?.querySelector('.toggle-header')
const title = titleEl?.textContent?.trim() || 'Заголовок'
// удаляем заголовок из DOM, чтобы не попал в content
if (titleEl?.parentNode) {
titleEl.parentNode.removeChild(titleEl)
}
return { title }
}
}]
}, },
renderHTML({ HTMLAttributes }) { renderHTML({ HTMLAttributes }) {
...@@ -83,12 +93,11 @@ const ToggleBlock = Node.create({ ...@@ -83,12 +93,11 @@ const ToggleBlock = Node.create({
'div', 'div',
{ {
class: 'toggle-block', class: 'toggle-block',
'data-open': HTMLAttributes.open ? 'true' : 'false',
}, },
[ [
'div', 'div',
{ class: 'toggle-block-inner' }, { class: 'toggle-block-inner' },
['span', { class: 'toggle-button' }, HTMLAttributes.open ? '▼' : '▶'], ['span', { class: 'toggle-button ' }],
['span', { class: 'toggle-header' }, HTMLAttributes.title || 'Заголовок'], ['span', { class: 'toggle-header' }, HTMLAttributes.title || 'Заголовок'],
], ],
['div', { class: 'toggle-body' }, ['div', { class: 'toggle-content' }, 0]], ['div', { class: 'toggle-body' }, ['div', { class: 'toggle-content' }, 0]],
......
...@@ -1154,10 +1154,10 @@ body{ ...@@ -1154,10 +1154,10 @@ body{
} }
.toggle-block[data-open="true"] .toggle-body { .toggle-block[data-open="true"] .toggle-body {
max-height: 1000px; max-height: 1000px;
border: 1px dashed #aaa; border: 1px dashed #D9D9D9;
border-radius: 6px; border-radius: 6px;
padding: 10px; padding: 10px;
background: #fafafa; background: #FAFAFA;
} }
.toggle-block { .toggle-block {
margin-bottom: 12px; margin-bottom: 12px;
...@@ -1165,7 +1165,7 @@ body{ ...@@ -1165,7 +1165,7 @@ body{
.toggle-header-wrapper { .toggle-header-wrapper {
position: relative; position: relative;
display: inline-block; display: inline-block;
margin-bottom: 5px; margin-bottom: 10px;
} }
.toggle-header-measurer { .toggle-header-measurer {
...@@ -1182,12 +1182,31 @@ body{ ...@@ -1182,12 +1182,31 @@ body{
.toggle-header { .toggle-header {
font: inherit; font: inherit;
padding: 2px 6px; padding: 2px 6px;
border: 1px solid #ccc; border: 1px solid #D9D9D9;
border-radius: 4px; border-radius: 4px;
margin-left: 5px; margin-left: 10px;
color: #000000D9;
font-weight: bold;
font-size: 14px;
line-height: 22px;
height: 32px;
} }
.toggle-button { .toggle-button {
height: 25px; height: 24px;
vertical-align: top; width: 24px;
vertical-align: middle;
padding: 0;
border-radius: 50%;
border: 1px solid #D9D9D9;
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHZpZXdCb3g9IjAgMCAxNCAxNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzYxMDlfNDAzMjYpIj4KPHJlY3Qgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNi43NDc1NiA0LjIxMzMzQzYuODc3NDUgNC4wNjQzMSA3LjEyNDkxIDQuMDY0MzEgNy4yNTM0MiA0LjIxMzMzTDExLjc0MjcgOS40MTkzOEMxMS45MDk0IDkuNjEzNTIgMTEuNzU5MSA5Ljg5NzkgMTEuNDg5OCA5Ljg5NzlIMi41MTAyNkMyLjI0MDk5IDkuODk3OSAyLjA5MDcyIDkuNjEzNTIgMi4yNTczMyA5LjQxOTM4TDYuNzQ3NTYgNC4yMTMzM1oiIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjAuODUiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF82MTA5XzQwMzI2Ij4KPHJlY3Qgd2lkdGg9IjE0IiBoZWlnaHQ9IjE0IiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo=);
background-repeat: no-repeat;
background-position: 4px 3px;
transform: rotate(0deg);
background-color: white;
cursor: pointer;
&.open {
transform: rotate(180deg) !important;
}
} }
...@@ -22,6 +22,13 @@ ...@@ -22,6 +22,13 @@
dependencies: dependencies:
"@ant-design/fast-color" "^2.0.6" "@ant-design/fast-color" "^2.0.6"
"@ant-design/colors@^8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.0.tgz#92b5aa1cd44896b62c7b67133b4d5a6a00266162"
integrity sha512-6YzkKCw30EI/E9kHOIXsQDHmMvTllT8STzjMb4K2qzit33RW2pqCJP0sk+hidBntXxE+Vz4n1+RvCTfBw6OErw==
dependencies:
"@ant-design/fast-color" "^3.0.0"
"@ant-design/cssinjs-utils@^1.1.3": "@ant-design/cssinjs-utils@^1.1.3":
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.3.tgz#5dd79126057920a6992d57b38dd84e2c0b707977" resolved "https://registry.yarnpkg.com/@ant-design/cssinjs-utils/-/cssinjs-utils-1.1.3.tgz#5dd79126057920a6992d57b38dd84e2c0b707977"
...@@ -51,6 +58,11 @@ ...@@ -51,6 +58,11 @@
dependencies: dependencies:
"@babel/runtime" "^7.24.7" "@babel/runtime" "^7.24.7"
"@ant-design/fast-color@^3.0.0":
version "3.0.0"
resolved "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-3.0.0.tgz#fb5178203de825f284809538f5142203d0ef3d80"
integrity sha512-eqvpP7xEDm2S7dUzl5srEQCBTXZMmY3ekf97zI+M2DHOYyKdJGH0qua0JACHTqbkRnD/KHFQP9J1uMJ/XWVzzA==
"@ant-design/icons-svg@^4.4.0": "@ant-design/icons-svg@^4.4.0":
version "4.4.2" version "4.4.2"
resolved "https://registry.yarnpkg.com/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz#ed2be7fb4d82ac7e1d45a54a5b06d6cecf8be6f6" resolved "https://registry.yarnpkg.com/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz#ed2be7fb4d82ac7e1d45a54a5b06d6cecf8be6f6"
...@@ -67,6 +79,16 @@ ...@@ -67,6 +79,16 @@
classnames "^2.2.6" classnames "^2.2.6"
rc-util "^5.31.1" rc-util "^5.31.1"
"@ant-design/icons@^6.0.0":
version "6.0.0"
resolved "https://registry.npmjs.org/@ant-design/icons/-/icons-6.0.0.tgz#302c935b8b0b429e4444cbc45809247276186d94"
integrity sha512-o0aCCAlHc1o4CQcapAwWzHeaW2x9F49g7P3IDtvtNXgHowtRWYb7kiubt8sQPFvfVIVU/jLw2hzeSlNt0FU+Uw==
dependencies:
"@ant-design/colors" "^8.0.0"
"@ant-design/icons-svg" "^4.4.0"
"@rc-component/util" "^1.2.1"
classnames "^2.2.6"
"@ant-design/react-slick@~1.1.2": "@ant-design/react-slick@~1.1.2":
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/@ant-design/react-slick/-/react-slick-1.1.2.tgz#f84ce3e4d0dc941f02b16f1d1d6d7a371ffbb4f1" resolved "https://registry.yarnpkg.com/@ant-design/react-slick/-/react-slick-1.1.2.tgz#f84ce3e4d0dc941f02b16f1d1d6d7a371ffbb4f1"
...@@ -1860,6 +1882,13 @@ ...@@ -1860,6 +1882,13 @@
rc-resize-observer "^1.3.1" rc-resize-observer "^1.3.1"
rc-util "^5.44.0" rc-util "^5.44.0"
"@rc-component/util@^1.2.1":
version "1.2.1"
resolved "https://registry.npmjs.org/@rc-component/util/-/util-1.2.1.tgz#2c3158f11a4193478cec44ca42915da31f67d8a0"
integrity sha512-AUVu6jO+lWjQnUOOECwu8iR0EdElQgWW5NBv5vP/Uf9dWbAX3udhMutRlkVXjuac2E40ghkFy+ve00mc/3Fymg==
dependencies:
react-is "^18.2.0"
"@remirror/core-constants@3.0.0": "@remirror/core-constants@3.0.0":
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-3.0.0.tgz#96fdb89d25c62e7b6a5d08caf0ce5114370e3b8f" resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-3.0.0.tgz#96fdb89d25c62e7b6a5d08caf0ce5114370e3b8f"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment