px-react-ui-components 1.1.10 → 1.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/MyEditor/MyEditor.js +1109 -164
- package/dist/components/MyEditor/MyEditor.scss +112 -0
- package/dist/components/MyInput/MyInput.module.css +1 -1
- package/dist/components/__yedek/MyEditor/MyEditor.js +368 -0
- package/dist/components/__yedek/MyEditor/MyEditor.scss +277 -0
- package/dist/components/__yedek/MyEditor copy/MyEditor.js +368 -0
- package/dist/components/__yedek/MyEditor copy/MyEditor.scss +277 -0
- package/package.json +1 -1
|
@@ -5,30 +5,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactQuill = _interopRequireDefault(require("react-quill"));
|
|
9
|
+
require("react-quill/dist/quill.snow.css");
|
|
10
|
+
var _quill = _interopRequireDefault(require("quill"));
|
|
11
|
+
var _quillTable = _interopRequireDefault(require("quill-table"));
|
|
12
|
+
var _katex = _interopRequireDefault(require("katex"));
|
|
13
|
+
require("katex/dist/katex.min.css");
|
|
8
14
|
require("./MyEditor.scss");
|
|
9
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
let hasQuillDependencies = false;
|
|
14
|
-
try {
|
|
15
|
-
ReactQuill = require("react-quill");
|
|
16
|
-
require("react-quill/dist/quill.snow.css");
|
|
17
|
-
Quill = require("quill");
|
|
18
|
-
ImageResize = require("quill-image-resize");
|
|
19
|
-
QuillTable = require("quill-table");
|
|
20
|
-
katex = require("katex");
|
|
21
|
-
require("katex/dist/katex.min.css");
|
|
22
|
-
hasQuillDependencies = true;
|
|
23
|
-
} catch (error) {
|
|
24
|
-
console.warn("MyEditor: Quill bağımlılıkları bulunamadı. MyEditor bileşenini kullanmak için aşağıdaki paketleri yükleyin:", {
|
|
25
|
-
"react-quill": "^2.0.0",
|
|
26
|
-
"quill": "^1.3.7",
|
|
27
|
-
"quill-image-resize-module-react": "^3.0.0",
|
|
28
|
-
"quill-table-ui": "^1.0.7",
|
|
29
|
-
"katex": "^0.16.21"
|
|
30
|
-
});
|
|
31
|
-
}
|
|
18
|
+
// KaTeX'i global hale getir
|
|
19
|
+
window.katex = _katex.default;
|
|
32
20
|
|
|
33
21
|
// Özel font listesini tanımla
|
|
34
22
|
const fonts = [{
|
|
@@ -123,58 +111,179 @@ const fonts = [{
|
|
|
123
111
|
value: "segoe-ui"
|
|
124
112
|
}];
|
|
125
113
|
|
|
126
|
-
// Quill
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
114
|
+
// Quill font formatını genişlet
|
|
115
|
+
const Font = _quill.default.import("formats/font");
|
|
116
|
+
Font.whitelist = fonts.map(f => f.value);
|
|
117
|
+
_quill.default.register(Font, true);
|
|
118
|
+
|
|
119
|
+
// Custom Image Resize Module
|
|
120
|
+
class CustomImageResize {
|
|
121
|
+
constructor(quill, options = {}) {
|
|
122
|
+
this.quill = quill;
|
|
123
|
+
this.options = options;
|
|
124
|
+
this.handleResize = this.handleResize.bind(this);
|
|
125
|
+
this.init();
|
|
131
126
|
}
|
|
127
|
+
init() {
|
|
128
|
+
// Resme tek tıklamada handles göster
|
|
129
|
+
this.quill.root.addEventListener('click', e => {
|
|
130
|
+
if (e.target && e.target.tagName === 'IMG') {
|
|
131
|
+
e.stopPropagation();
|
|
132
|
+
this.showResizeHandles(e.target);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
132
135
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
// Editör dışına tıklandığında resize handles'ı kaldır
|
|
137
|
+
document.addEventListener('click', e => {
|
|
138
|
+
const isInsideEditor = e.target.closest('.ql-editor');
|
|
139
|
+
const isImage = e.target.tagName === 'IMG';
|
|
140
|
+
const isHandle = e.target.classList.contains('resize-handle');
|
|
141
|
+
if (!isInsideEditor && !isHandle) {
|
|
142
|
+
this.hideResizeHandles();
|
|
143
|
+
} else if (isInsideEditor && !isImage && !isHandle) {
|
|
144
|
+
this.hideResizeHandles();
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
showResizeHandles(img) {
|
|
149
|
+
this.hideResizeHandles();
|
|
150
|
+
const box = document.createElement('div');
|
|
151
|
+
box.className = 'image-resize-box';
|
|
152
|
+
box.style.cssText = 'position: absolute; border: 2px solid #0066cc; z-index: 100;';
|
|
153
|
+
const rect = img.getBoundingClientRect();
|
|
154
|
+
const editorRect = this.quill.root.getBoundingClientRect();
|
|
155
|
+
box.style.left = rect.left - editorRect.left + this.quill.root.scrollLeft + 'px';
|
|
156
|
+
box.style.top = rect.top - editorRect.top + this.quill.root.scrollTop + 'px';
|
|
157
|
+
box.style.width = rect.width + 'px';
|
|
158
|
+
box.style.height = rect.height + 'px';
|
|
137
159
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
160
|
+
// Resize handles
|
|
161
|
+
const positions = ['nw', 'ne', 'sw', 'se'];
|
|
162
|
+
positions.forEach(pos => {
|
|
163
|
+
const handle = document.createElement('div');
|
|
164
|
+
handle.className = `resize-handle resize-handle-${pos}`;
|
|
165
|
+
handle.style.cssText = 'position: absolute; width: 12px; height: 12px; background: #0066cc; border: 2px solid white; cursor: ' + pos + '-resize;';
|
|
166
|
+
if (pos === 'nw') {
|
|
167
|
+
handle.style.top = '-6px';
|
|
168
|
+
handle.style.left = '-6px';
|
|
169
|
+
}
|
|
170
|
+
if (pos === 'ne') {
|
|
171
|
+
handle.style.top = '-6px';
|
|
172
|
+
handle.style.right = '-6px';
|
|
173
|
+
}
|
|
174
|
+
if (pos === 'sw') {
|
|
175
|
+
handle.style.bottom = '-6px';
|
|
176
|
+
handle.style.left = '-6px';
|
|
177
|
+
}
|
|
178
|
+
if (pos === 'se') {
|
|
179
|
+
handle.style.bottom = '-6px';
|
|
180
|
+
handle.style.right = '-6px';
|
|
181
|
+
}
|
|
182
|
+
handle.addEventListener('mousedown', e => this.startResize(e, img, pos));
|
|
183
|
+
box.appendChild(handle);
|
|
184
|
+
});
|
|
185
|
+
this.quill.root.style.position = 'relative';
|
|
186
|
+
this.quill.root.appendChild(box);
|
|
187
|
+
this.currentBox = box;
|
|
188
|
+
this.currentImg = img;
|
|
141
189
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
190
|
+
startResize(e, img, position) {
|
|
191
|
+
e.preventDefault();
|
|
192
|
+
const startX = e.clientX;
|
|
193
|
+
const startY = e.clientY;
|
|
194
|
+
const startWidth = img.width;
|
|
195
|
+
const startHeight = img.height;
|
|
196
|
+
const aspectRatio = startWidth / startHeight;
|
|
197
|
+
const doResize = e => {
|
|
198
|
+
const deltaX = e.clientX - startX;
|
|
199
|
+
const deltaY = e.clientY - startY;
|
|
200
|
+
let newWidth = startWidth;
|
|
201
|
+
let newHeight = startHeight;
|
|
202
|
+
if (position === 'se') {
|
|
203
|
+
newWidth = startWidth + deltaX;
|
|
204
|
+
} else if (position === 'sw') {
|
|
205
|
+
newWidth = startWidth - deltaX;
|
|
206
|
+
} else if (position === 'ne') {
|
|
207
|
+
newWidth = startWidth + deltaX;
|
|
208
|
+
} else if (position === 'nw') {
|
|
209
|
+
newWidth = startWidth - deltaX;
|
|
210
|
+
}
|
|
211
|
+
newHeight = newWidth / aspectRatio;
|
|
212
|
+
if (newWidth > 50) {
|
|
213
|
+
img.width = newWidth;
|
|
214
|
+
img.height = newHeight;
|
|
215
|
+
this.updateBoxSize(img);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const stopResize = () => {
|
|
219
|
+
document.removeEventListener('mousemove', doResize);
|
|
220
|
+
document.removeEventListener('mouseup', stopResize);
|
|
221
|
+
};
|
|
222
|
+
document.addEventListener('mousemove', doResize);
|
|
223
|
+
document.addEventListener('mouseup', stopResize);
|
|
148
224
|
}
|
|
225
|
+
updateBoxSize(img) {
|
|
226
|
+
if (this.currentBox) {
|
|
227
|
+
const rect = img.getBoundingClientRect();
|
|
228
|
+
const editorRect = this.quill.root.getBoundingClientRect();
|
|
229
|
+
this.currentBox.style.left = rect.left - editorRect.left + this.quill.root.scrollLeft + 'px';
|
|
230
|
+
this.currentBox.style.top = rect.top - editorRect.top + this.quill.root.scrollTop + 'px';
|
|
231
|
+
this.currentBox.style.width = rect.width + 'px';
|
|
232
|
+
this.currentBox.style.height = rect.height + 'px';
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
hideResizeHandles() {
|
|
236
|
+
const boxes = this.quill.root.querySelectorAll('.image-resize-box');
|
|
237
|
+
boxes.forEach(box => box.remove());
|
|
238
|
+
this.currentBox = null;
|
|
239
|
+
this.currentImg = null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
149
242
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
243
|
+
// Custom Image Resize modülünü kaydet
|
|
244
|
+
try {
|
|
245
|
+
_quill.default.register("modules/imageResize", CustomImageResize, true);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.log('CustomImageResize registration skipped:', error.message);
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
// Table modüllerini kaydet
|
|
251
|
+
_quill.default.register({
|
|
252
|
+
'modules/table': _quillTable.default.TableModule,
|
|
253
|
+
'formats/table': _quillTable.default.Table,
|
|
254
|
+
'formats/table-cell': _quillTable.default.TableCell,
|
|
255
|
+
'formats/table-row': _quillTable.default.TableRow,
|
|
256
|
+
'formats/table-container': _quillTable.default.Contain
|
|
257
|
+
}, true);
|
|
258
|
+
} catch (error) {
|
|
259
|
+
// Zaten kayıtlı, sorun yok
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Formula Embed için düzeltme
|
|
263
|
+
const Embed = _quill.default.import("blots/embed");
|
|
264
|
+
class FormulaEmbed extends Embed {
|
|
265
|
+
static create(value) {
|
|
266
|
+
let node = super.create();
|
|
267
|
+
if (value) {
|
|
268
|
+
node.setAttribute("data-value", value);
|
|
269
|
+
try {
|
|
270
|
+
window.katex.render(value, node, {
|
|
271
|
+
throwOnError: false
|
|
272
|
+
});
|
|
273
|
+
} catch (err) {
|
|
274
|
+
console.error("KaTeX render error:", err);
|
|
170
275
|
}
|
|
171
276
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
277
|
+
return node;
|
|
278
|
+
}
|
|
279
|
+
static value(node) {
|
|
280
|
+
return node.getAttribute("data-value");
|
|
176
281
|
}
|
|
177
282
|
}
|
|
283
|
+
FormulaEmbed.blotName = "formula";
|
|
284
|
+
FormulaEmbed.tagName = "SPAN";
|
|
285
|
+
FormulaEmbed.className = "ql-formula";
|
|
286
|
+
_quill.default.register("formats/formula", FormulaEmbed);
|
|
178
287
|
function MyEditor({
|
|
179
288
|
value,
|
|
180
289
|
onChange,
|
|
@@ -184,50 +293,481 @@ function MyEditor({
|
|
|
184
293
|
}) {
|
|
185
294
|
const [editorValue, setEditorValue] = (0, _react.useState)("");
|
|
186
295
|
const [isFullscreen, setIsFullscreen] = (0, _react.useState)(false);
|
|
296
|
+
const [showImageModal, setShowImageModal] = (0, _react.useState)(false);
|
|
297
|
+
const [imageWidth, setImageWidth] = (0, _react.useState)(0);
|
|
298
|
+
const [imageHeight, setImageHeight] = (0, _react.useState)(0);
|
|
299
|
+
const [imageAlignment, setImageAlignment] = (0, _react.useState)('none');
|
|
187
300
|
const editorRef = (0, _react.useRef)(null);
|
|
188
301
|
const timeoutRef = (0, _react.useRef)(null);
|
|
189
302
|
const isFirstRender = (0, _react.useRef)(true);
|
|
303
|
+
const selectedImageRef = (0, _react.useRef)(null);
|
|
304
|
+
const imageDataRef = (0, _react.useRef)({
|
|
305
|
+
width: 0,
|
|
306
|
+
height: 0
|
|
307
|
+
});
|
|
190
308
|
|
|
191
|
-
//
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
borderRadius: "4px",
|
|
212
|
-
fontSize: "12px",
|
|
213
|
-
textAlign: "left",
|
|
214
|
-
overflow: "auto"
|
|
215
|
-
},
|
|
216
|
-
children: `npm install react-quill quill quill-image-resize-module-react quill-table-ui katex`
|
|
217
|
-
})]
|
|
218
|
-
});
|
|
219
|
-
}
|
|
309
|
+
// Manuel double-click için
|
|
310
|
+
const lastClickTimeRef = (0, _react.useRef)(0);
|
|
311
|
+
const lastClickedImageRef = (0, _react.useRef)(null);
|
|
312
|
+
const clickTimeoutRef = (0, _react.useRef)(null);
|
|
313
|
+
const imageWidthInputRef = (0, _react.useRef)(null);
|
|
314
|
+
const imageHeightInputRef = (0, _react.useRef)(null);
|
|
315
|
+
|
|
316
|
+
// findDOMNode uyarılarını bastır
|
|
317
|
+
(0, _react.useEffect)(() => {
|
|
318
|
+
const originalError = console.error;
|
|
319
|
+
console.error = (...args) => {
|
|
320
|
+
if (typeof args[0] === 'string' && (args[0].includes('findDOMNode') || args[0].includes('DOMNodeInserted'))) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
originalError.call(console, ...args);
|
|
324
|
+
};
|
|
325
|
+
return () => {
|
|
326
|
+
console.error = originalError;
|
|
327
|
+
};
|
|
328
|
+
}, []);
|
|
220
329
|
const handleFullscreen = () => {
|
|
221
330
|
setIsFullscreen(!isFullscreen);
|
|
222
331
|
};
|
|
223
332
|
|
|
224
|
-
// Custom buton tanımı
|
|
333
|
+
// Custom buton tanımı - React 19 uyumlu
|
|
225
334
|
(0, _react.useEffect)(() => {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
335
|
+
try {
|
|
336
|
+
const icons = _quill.default.import('ui/icons');
|
|
337
|
+
icons['fullscreen'] = `<svg viewbox="0 0 18 18">
|
|
338
|
+
<path d="M4,4H0v2h6V0H4V4z M14,4V0h-2v6h6V4H14z M6,14H0v2h4v4h2V14z M14,18h2v-4h4v-2h-6V18z"/>
|
|
339
|
+
</svg>`;
|
|
340
|
+
} catch (error) {
|
|
341
|
+
console.warn('Icon registration failed:', error);
|
|
342
|
+
}
|
|
230
343
|
}, []);
|
|
344
|
+
|
|
345
|
+
// Resize handles göster/gizle fonksiyonları
|
|
346
|
+
const showResizeHandlesCallback = (0, _react.useCallback)((img, editor) => {
|
|
347
|
+
showResizeHandles(img, editor);
|
|
348
|
+
}, []);
|
|
349
|
+
const hideResizeHandlesCallback = (0, _react.useCallback)(() => {
|
|
350
|
+
hideResizeHandles();
|
|
351
|
+
}, []);
|
|
352
|
+
|
|
353
|
+
// Resimlere tıklama event'i ekle (Manuel double-click)
|
|
354
|
+
(0, _react.useEffect)(() => {
|
|
355
|
+
if (editorRef.current) {
|
|
356
|
+
const editor = editorRef.current.getEditor();
|
|
357
|
+
if (editor && editor.root) {
|
|
358
|
+
// Manuel double-click mantığı (timeout ile)
|
|
359
|
+
const handleImageClick = e => {
|
|
360
|
+
if (e.target.tagName === 'IMG') {
|
|
361
|
+
e.stopPropagation();
|
|
362
|
+
const now = Date.now();
|
|
363
|
+
const timeSinceLastClick = now - lastClickTimeRef.current;
|
|
364
|
+
const isSameImage = lastClickedImageRef.current === e.target;
|
|
365
|
+
|
|
366
|
+
// Double-click algıla (400ms içinde aynı resme tıklandıysa)
|
|
367
|
+
if (timeSinceLastClick < 400 && timeSinceLastClick > 0 && isSameImage) {
|
|
368
|
+
// Pending timeout'u iptal et
|
|
369
|
+
if (clickTimeoutRef.current) {
|
|
370
|
+
clearTimeout(clickTimeoutRef.current);
|
|
371
|
+
clickTimeoutRef.current = null;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Modal aç
|
|
375
|
+
hideResizeHandles();
|
|
376
|
+
const img = e.target;
|
|
377
|
+
|
|
378
|
+
// Resmin GERÇEK güncel boyutlarını al
|
|
379
|
+
const computedStyle = window.getComputedStyle(img);
|
|
380
|
+
let currentWidth = parseInt(computedStyle.width);
|
|
381
|
+
let currentHeight = parseInt(computedStyle.height);
|
|
382
|
+
|
|
383
|
+
// Eğer computedStyle'dan alamadıysak
|
|
384
|
+
if (!currentWidth || isNaN(currentWidth)) {
|
|
385
|
+
currentWidth = img.clientWidth || img.width || img.naturalWidth;
|
|
386
|
+
}
|
|
387
|
+
if (!currentHeight || isNaN(currentHeight)) {
|
|
388
|
+
currentHeight = img.clientHeight || img.height || img.naturalHeight;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Mevcut hizalamayı tespit et
|
|
392
|
+
const currentStyle = img.style.cssText;
|
|
393
|
+
let alignment = 'none';
|
|
394
|
+
if (currentStyle.includes('float: left')) {
|
|
395
|
+
alignment = 'left';
|
|
396
|
+
} else if (currentStyle.includes('float: right')) {
|
|
397
|
+
alignment = 'right';
|
|
398
|
+
} else if (currentStyle.includes('display: block') && currentStyle.includes('margin') && currentStyle.includes('auto')) {
|
|
399
|
+
alignment = 'center';
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Ref'e kaydet
|
|
403
|
+
selectedImageRef.current = img;
|
|
404
|
+
imageDataRef.current = {
|
|
405
|
+
width: currentWidth,
|
|
406
|
+
height: currentHeight
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
// State'e de kaydet
|
|
410
|
+
setImageWidth(currentWidth);
|
|
411
|
+
setImageHeight(currentHeight);
|
|
412
|
+
setImageAlignment(alignment);
|
|
413
|
+
setShowImageModal(true);
|
|
414
|
+
|
|
415
|
+
// Reset
|
|
416
|
+
lastClickTimeRef.current = 0;
|
|
417
|
+
lastClickedImageRef.current = null;
|
|
418
|
+
} else {
|
|
419
|
+
// Single click olabilir - bekle
|
|
420
|
+
|
|
421
|
+
// Önceki timeout'u iptal et
|
|
422
|
+
if (clickTimeoutRef.current) {
|
|
423
|
+
clearTimeout(clickTimeoutRef.current);
|
|
424
|
+
}
|
|
425
|
+
const clickedImage = e.target;
|
|
426
|
+
|
|
427
|
+
// 250ms bekle, eğer ikinci tıklama gelmezse resize handles göster
|
|
428
|
+
clickTimeoutRef.current = setTimeout(() => {
|
|
429
|
+
showResizeHandlesCallback(clickedImage, editor);
|
|
430
|
+
clickTimeoutRef.current = null;
|
|
431
|
+
}, 250);
|
|
432
|
+
|
|
433
|
+
// Zamanı ve resmi kaydet
|
|
434
|
+
lastClickTimeRef.current = now;
|
|
435
|
+
lastClickedImageRef.current = e.target;
|
|
436
|
+
}
|
|
437
|
+
} else if (!e.target.classList.contains('resize-handle')) {
|
|
438
|
+
hideResizeHandlesCallback();
|
|
439
|
+
lastClickTimeRef.current = 0;
|
|
440
|
+
lastClickedImageRef.current = null;
|
|
441
|
+
if (clickTimeoutRef.current) {
|
|
442
|
+
clearTimeout(clickTimeoutRef.current);
|
|
443
|
+
clickTimeoutRef.current = null;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// Editör dışına tıklama - Handles gizle
|
|
449
|
+
const handleOutsideClick = e => {
|
|
450
|
+
if (!e.target.closest('.ql-editor') && !e.target.classList.contains('resize-handle')) {
|
|
451
|
+
hideResizeHandlesCallback();
|
|
452
|
+
lastClickTimeRef.current = 0;
|
|
453
|
+
lastClickedImageRef.current = null;
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
editor.root.addEventListener('click', handleImageClick);
|
|
457
|
+
document.addEventListener('click', handleOutsideClick);
|
|
458
|
+
return () => {
|
|
459
|
+
editor.root.removeEventListener('click', handleImageClick);
|
|
460
|
+
document.removeEventListener('click', handleOutsideClick);
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}, [showResizeHandlesCallback, hideResizeHandlesCallback]);
|
|
465
|
+
|
|
466
|
+
// Resize handles göster
|
|
467
|
+
const showResizeHandles = (img, editor) => {
|
|
468
|
+
hideResizeHandles();
|
|
469
|
+
|
|
470
|
+
// Resme data attribute ekle (Quill'i tetiklemeyen yöntem)
|
|
471
|
+
img.setAttribute('data-selected', 'true');
|
|
472
|
+
img.style.outline = '2px solid #0066cc';
|
|
473
|
+
img.style.outlineOffset = '2px';
|
|
474
|
+
img.style.boxShadow = '0 0 0 4px rgba(0, 102, 204, 0.1)';
|
|
475
|
+
const wrapper = document.createElement('div');
|
|
476
|
+
wrapper.className = 'image-resize-wrapper';
|
|
477
|
+
wrapper.style.cssText = 'position: fixed; z-index: 10000;';
|
|
478
|
+
const rect = img.getBoundingClientRect();
|
|
479
|
+
wrapper.style.left = rect.left + 'px';
|
|
480
|
+
wrapper.style.top = rect.top + 'px';
|
|
481
|
+
wrapper.style.width = rect.width + 'px';
|
|
482
|
+
wrapper.style.height = rect.height + 'px';
|
|
483
|
+
|
|
484
|
+
// 8 handle ekle: 4 köşe (orantılı) + 4 kenar (serbest)
|
|
485
|
+
const positions = [
|
|
486
|
+
// Köşeler (orantılı resize)
|
|
487
|
+
{
|
|
488
|
+
name: 'nw',
|
|
489
|
+
cursor: 'nw-resize',
|
|
490
|
+
top: '-8px',
|
|
491
|
+
left: '-8px',
|
|
492
|
+
type: 'corner'
|
|
493
|
+
}, {
|
|
494
|
+
name: 'ne',
|
|
495
|
+
cursor: 'ne-resize',
|
|
496
|
+
top: '-8px',
|
|
497
|
+
right: '-8px',
|
|
498
|
+
type: 'corner'
|
|
499
|
+
}, {
|
|
500
|
+
name: 'sw',
|
|
501
|
+
cursor: 'sw-resize',
|
|
502
|
+
bottom: '-8px',
|
|
503
|
+
left: '-8px',
|
|
504
|
+
type: 'corner'
|
|
505
|
+
}, {
|
|
506
|
+
name: 'se',
|
|
507
|
+
cursor: 'se-resize',
|
|
508
|
+
bottom: '-8px',
|
|
509
|
+
right: '-8px',
|
|
510
|
+
type: 'corner'
|
|
511
|
+
},
|
|
512
|
+
// Kenarlar (serbest resize)
|
|
513
|
+
{
|
|
514
|
+
name: 'n',
|
|
515
|
+
cursor: 'n-resize',
|
|
516
|
+
top: '-8px',
|
|
517
|
+
left: '50%',
|
|
518
|
+
type: 'edge'
|
|
519
|
+
}, {
|
|
520
|
+
name: 's',
|
|
521
|
+
cursor: 's-resize',
|
|
522
|
+
bottom: '-8px',
|
|
523
|
+
left: '50%',
|
|
524
|
+
type: 'edge'
|
|
525
|
+
}, {
|
|
526
|
+
name: 'w',
|
|
527
|
+
cursor: 'w-resize',
|
|
528
|
+
top: '50%',
|
|
529
|
+
left: '-8px',
|
|
530
|
+
type: 'edge'
|
|
531
|
+
}, {
|
|
532
|
+
name: 'e',
|
|
533
|
+
cursor: 'e-resize',
|
|
534
|
+
top: '50%',
|
|
535
|
+
right: '-8px',
|
|
536
|
+
type: 'edge'
|
|
537
|
+
}];
|
|
538
|
+
positions.forEach(pos => {
|
|
539
|
+
const handle = document.createElement('div');
|
|
540
|
+
handle.className = `resize-handle resize-handle-${pos.name}`;
|
|
541
|
+
|
|
542
|
+
// Köşeler yuvarlak, kenarlar kare
|
|
543
|
+
const borderRadius = pos.type === 'corner' ? '50%' : '4px';
|
|
544
|
+
handle.style.cssText = `position: absolute; width: 16px; height: 16px; background: #ffffff;
|
|
545
|
+
border: 3px solid #0066cc; cursor: ${pos.cursor}; border-radius: ${borderRadius};
|
|
546
|
+
box-shadow: 0 2px 6px rgba(0,0,0,0.3); z-index: 10001;`;
|
|
547
|
+
Object.assign(handle.style, {
|
|
548
|
+
top: pos.top || 'auto',
|
|
549
|
+
bottom: pos.bottom || 'auto',
|
|
550
|
+
left: pos.left || 'auto',
|
|
551
|
+
right: pos.right || 'auto'
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// Kenarlar için margin-left ekle (ortalamak için)
|
|
555
|
+
if (pos.left === '50%' || pos.right === '50%') {
|
|
556
|
+
handle.style.marginLeft = '-8px';
|
|
557
|
+
}
|
|
558
|
+
// Kenarlar için margin-top ekle (ortalamak için)
|
|
559
|
+
if (pos.top === '50%' || pos.bottom === '50%') {
|
|
560
|
+
handle.style.marginTop = '-8px';
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Hover effect
|
|
564
|
+
handle.addEventListener('mouseenter', () => {
|
|
565
|
+
handle.style.transform = 'scale(1.2)';
|
|
566
|
+
handle.style.background = '#0066cc';
|
|
567
|
+
handle.style.borderColor = '#ffffff';
|
|
568
|
+
});
|
|
569
|
+
handle.addEventListener('mouseleave', () => {
|
|
570
|
+
handle.style.transform = 'scale(1)';
|
|
571
|
+
handle.style.background = '#ffffff';
|
|
572
|
+
handle.style.borderColor = '#0066cc';
|
|
573
|
+
});
|
|
574
|
+
handle.addEventListener('mousedown', e => startResize(e, img, pos.name, wrapper, editor, pos.type));
|
|
575
|
+
wrapper.appendChild(handle);
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
// Wrapper'ı body'ye ekle (editor'a değil)
|
|
579
|
+
document.body.appendChild(wrapper);
|
|
580
|
+
|
|
581
|
+
// Scroll ve resize eventleri için wrapper pozisyonunu güncelle
|
|
582
|
+
const updateWrapperPosition = () => {
|
|
583
|
+
const newRect = img.getBoundingClientRect();
|
|
584
|
+
wrapper.style.left = newRect.left + 'px';
|
|
585
|
+
wrapper.style.top = newRect.top + 'px';
|
|
586
|
+
wrapper.style.width = newRect.width + 'px';
|
|
587
|
+
wrapper.style.height = newRect.height + 'px';
|
|
588
|
+
};
|
|
589
|
+
editor.root.addEventListener('scroll', updateWrapperPosition);
|
|
590
|
+
window.addEventListener('scroll', updateWrapperPosition);
|
|
591
|
+
window.addEventListener('resize', updateWrapperPosition);
|
|
592
|
+
wrapper.setAttribute('data-update-fn', 'true');
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
// Resize başlat
|
|
596
|
+
const startResize = (e, img, position, wrapper, editor, type) => {
|
|
597
|
+
e.preventDefault();
|
|
598
|
+
e.stopPropagation();
|
|
599
|
+
const startX = e.clientX;
|
|
600
|
+
const startY = e.clientY;
|
|
601
|
+
const startWidth = img.width || img.naturalWidth;
|
|
602
|
+
const startHeight = img.height || img.naturalHeight;
|
|
603
|
+
const aspectRatio = startWidth / startHeight;
|
|
604
|
+
let currentWidth = startWidth;
|
|
605
|
+
let currentHeight = startHeight;
|
|
606
|
+
const doResize = e => {
|
|
607
|
+
e.preventDefault();
|
|
608
|
+
e.stopPropagation();
|
|
609
|
+
const deltaX = e.clientX - startX;
|
|
610
|
+
const deltaY = e.clientY - startY;
|
|
611
|
+
let newWidth = startWidth;
|
|
612
|
+
let newHeight = startHeight;
|
|
613
|
+
if (type === 'corner') {
|
|
614
|
+
// Köşeler: Orantılı resize (aspect ratio korunur)
|
|
615
|
+
if (position === 'se' || position === 'ne') {
|
|
616
|
+
newWidth = startWidth + deltaX;
|
|
617
|
+
} else if (position === 'sw' || position === 'nw') {
|
|
618
|
+
newWidth = startWidth - deltaX;
|
|
619
|
+
}
|
|
620
|
+
newHeight = newWidth / aspectRatio;
|
|
621
|
+
} else {
|
|
622
|
+
// Kenarlar: Serbest resize
|
|
623
|
+
if (position === 'e') {
|
|
624
|
+
newWidth = startWidth + deltaX;
|
|
625
|
+
newHeight = startHeight; // Height sabit
|
|
626
|
+
} else if (position === 'w') {
|
|
627
|
+
newWidth = startWidth - deltaX;
|
|
628
|
+
newHeight = startHeight; // Height sabit
|
|
629
|
+
} else if (position === 's') {
|
|
630
|
+
newWidth = startWidth; // Width sabit
|
|
631
|
+
newHeight = startHeight + deltaY;
|
|
632
|
+
} else if (position === 'n') {
|
|
633
|
+
newWidth = startWidth; // Width sabit
|
|
634
|
+
newHeight = startHeight - deltaY;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Minimum boyut kontrolü
|
|
639
|
+
if (newWidth > 50 && newHeight > 50) {
|
|
640
|
+
currentWidth = Math.round(newWidth);
|
|
641
|
+
currentHeight = Math.round(newHeight);
|
|
642
|
+
|
|
643
|
+
// Mevcut inline style'ı koru (hizalama ayarları)
|
|
644
|
+
const currentStyle = img.style.cssText;
|
|
645
|
+
const hasFloat = currentStyle.includes('float');
|
|
646
|
+
|
|
647
|
+
// Yeni style'ı oluştur (mevcut hizalama ayarlarını koru)
|
|
648
|
+
let newStyle = `width: ${currentWidth}px; height: ${currentHeight}px; max-width: 100%;`;
|
|
649
|
+
if (hasFloat && currentStyle.includes('float: left')) {
|
|
650
|
+
newStyle = `float: left; margin: 0 15px 10px 0; ${newStyle}`;
|
|
651
|
+
} else if (hasFloat && currentStyle.includes('float: right')) {
|
|
652
|
+
newStyle = `float: right; margin: 0 0 10px 15px; ${newStyle}`;
|
|
653
|
+
} else if (currentStyle.includes('display: block') && currentStyle.includes('margin') && currentStyle.includes('auto')) {
|
|
654
|
+
newStyle = `display: block; margin: 10px auto; ${newStyle}`;
|
|
655
|
+
} else if (!hasFloat) {
|
|
656
|
+
newStyle = `display: inline-block; ${newStyle}`;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Boyutları uygula (inline style ile)
|
|
660
|
+
img.width = currentWidth;
|
|
661
|
+
img.height = currentHeight;
|
|
662
|
+
img.setAttribute('width', currentWidth.toString());
|
|
663
|
+
img.setAttribute('height', currentHeight.toString());
|
|
664
|
+
img.style.cssText = newStyle;
|
|
665
|
+
|
|
666
|
+
// Wrapper'ı güncelle (fixed position)
|
|
667
|
+
const newRect = img.getBoundingClientRect();
|
|
668
|
+
wrapper.style.left = newRect.left + 'px';
|
|
669
|
+
wrapper.style.top = newRect.top + 'px';
|
|
670
|
+
wrapper.style.width = newRect.width + 'px';
|
|
671
|
+
wrapper.style.height = newRect.height + 'px';
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
const stopResize = () => {
|
|
675
|
+
document.removeEventListener('mousemove', doResize);
|
|
676
|
+
document.removeEventListener('mouseup', stopResize);
|
|
677
|
+
|
|
678
|
+
// Handles'ı kaldır ama boyutu koru
|
|
679
|
+
hideResizeHandles();
|
|
680
|
+
};
|
|
681
|
+
document.addEventListener('mousemove', doResize);
|
|
682
|
+
document.addEventListener('mouseup', stopResize);
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
// Resize handles gizle
|
|
686
|
+
const hideResizeHandles = () => {
|
|
687
|
+
// Resize wrapper'ları kaldır
|
|
688
|
+
const wrappers = document.querySelectorAll('.image-resize-wrapper');
|
|
689
|
+
wrappers.forEach(wrapper => wrapper.remove());
|
|
690
|
+
|
|
691
|
+
// Seçili resmin border'ını kaldır
|
|
692
|
+
const selectedImages = document.querySelectorAll('[data-selected="true"]');
|
|
693
|
+
selectedImages.forEach(img => {
|
|
694
|
+
img.removeAttribute('data-selected');
|
|
695
|
+
img.style.outline = '';
|
|
696
|
+
img.style.outlineOffset = '';
|
|
697
|
+
img.style.boxShadow = '';
|
|
698
|
+
});
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
// Resim boyutunu güncelle (Modal'dan)
|
|
702
|
+
const handleImageResize = () => {
|
|
703
|
+
const img = selectedImageRef.current;
|
|
704
|
+
if (!img) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// State'ten güncel değerleri al
|
|
709
|
+
const finalWidth = imageWidth;
|
|
710
|
+
const finalHeight = imageHeight;
|
|
711
|
+
|
|
712
|
+
// Mevcut boyutları al
|
|
713
|
+
const currentWidth = img.width || parseInt(img.style.width) || parseInt(img.getAttribute('width'));
|
|
714
|
+
const currentHeight = img.height || parseInt(img.style.height) || parseInt(img.getAttribute('height'));
|
|
715
|
+
|
|
716
|
+
// Eğer boyutlar değişmediyse, sadece modal'ı kapat
|
|
717
|
+
if (currentWidth === finalWidth && currentHeight === finalHeight) {
|
|
718
|
+
setShowImageModal(false);
|
|
719
|
+
selectedImageRef.current = null;
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
if (finalWidth <= 0 || finalHeight <= 0) {
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// Editörü al
|
|
727
|
+
const editor = editorRef.current?.getEditor();
|
|
728
|
+
|
|
729
|
+
// Mevcut inline style'ı koru (float, margin vs.)
|
|
730
|
+
const currentStyle = img.style.cssText;
|
|
731
|
+
const hasFloat = currentStyle.includes('float');
|
|
732
|
+
const hasMargin = currentStyle.includes('margin');
|
|
733
|
+
const hasDisplay = currentStyle.includes('display');
|
|
734
|
+
|
|
735
|
+
// Yeni style'ı oluştur (mevcut hizalama ayarlarını koru)
|
|
736
|
+
let newStyle = `width: ${finalWidth}px; height: ${finalHeight}px; max-width: 100%;`;
|
|
737
|
+
if (hasFloat && currentStyle.includes('float: left')) {
|
|
738
|
+
newStyle = `float: left; margin: 0 15px 10px 0; ${newStyle}`;
|
|
739
|
+
} else if (hasFloat && currentStyle.includes('float: right')) {
|
|
740
|
+
newStyle = `float: right; margin: 0 0 10px 15px; ${newStyle}`;
|
|
741
|
+
} else if (hasDisplay && currentStyle.includes('display: block')) {
|
|
742
|
+
newStyle = `display: block; margin: 10px auto; ${newStyle}`;
|
|
743
|
+
} else {
|
|
744
|
+
newStyle = `display: inline-block; ${newStyle}`;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// Boyutları uygula (inline style ile)
|
|
748
|
+
img.width = finalWidth;
|
|
749
|
+
img.height = finalHeight;
|
|
750
|
+
img.setAttribute('width', finalWidth.toString());
|
|
751
|
+
img.setAttribute('height', finalHeight.toString());
|
|
752
|
+
img.style.cssText = newStyle;
|
|
753
|
+
|
|
754
|
+
// Modal'ı kapat
|
|
755
|
+
setShowImageModal(false);
|
|
756
|
+
selectedImageRef.current = null;
|
|
757
|
+
|
|
758
|
+
// İçeriği güncelle
|
|
759
|
+
if (editor) {
|
|
760
|
+
setTimeout(() => {
|
|
761
|
+
const content = editor.root.innerHTML;
|
|
762
|
+
setEditorValue(content);
|
|
763
|
+
if (onChange) {
|
|
764
|
+
onChange({
|
|
765
|
+
value: content
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
}, 50);
|
|
769
|
+
}
|
|
770
|
+
};
|
|
231
771
|
(0, _react.useEffect)(() => {
|
|
232
772
|
if (isFirstRender.current) {
|
|
233
773
|
isFirstRender.current = false;
|
|
@@ -247,10 +787,7 @@ function MyEditor({
|
|
|
247
787
|
}
|
|
248
788
|
timeoutRef.current = setTimeout(() => {
|
|
249
789
|
if (onChange) onChange({
|
|
250
|
-
value: html
|
|
251
|
-
target: {
|
|
252
|
-
value: html
|
|
253
|
-
}
|
|
790
|
+
value: html
|
|
254
791
|
});
|
|
255
792
|
}, 500);
|
|
256
793
|
};
|
|
@@ -285,79 +822,487 @@ function MyEditor({
|
|
|
285
822
|
script: "sub"
|
|
286
823
|
}, {
|
|
287
824
|
script: "super"
|
|
288
|
-
}], ["image"]
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
825
|
+
}], ["image"], ["formula"], [{
|
|
826
|
+
table: tableOptions
|
|
827
|
+
}, {
|
|
828
|
+
table: "append-row"
|
|
829
|
+
}, {
|
|
830
|
+
table: "append-col"
|
|
831
|
+
}]]
|
|
292
832
|
},
|
|
293
833
|
table: {
|
|
294
|
-
operationMenu:
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
834
|
+
operationMenu: {
|
|
835
|
+
items: {
|
|
836
|
+
insertColumnRight: {
|
|
837
|
+
text: 'Sağa Sütun Ekle'
|
|
838
|
+
},
|
|
839
|
+
insertColumnLeft: {
|
|
840
|
+
text: 'Sola Sütun Ekle'
|
|
841
|
+
},
|
|
842
|
+
insertRowUp: {
|
|
843
|
+
text: 'Yukarı Satır Ekle'
|
|
844
|
+
},
|
|
845
|
+
insertRowDown: {
|
|
846
|
+
text: 'Aşağı Satır Ekle'
|
|
847
|
+
},
|
|
848
|
+
mergeCells: {
|
|
849
|
+
text: 'Hücreleri Birleştir'
|
|
850
|
+
},
|
|
851
|
+
unmergeCells: {
|
|
852
|
+
text: 'Hücreleri Ayır'
|
|
853
|
+
},
|
|
854
|
+
deleteColumn: {
|
|
855
|
+
text: 'Sütunu Sil'
|
|
856
|
+
},
|
|
857
|
+
deleteRow: {
|
|
858
|
+
text: 'Satırı Sil'
|
|
859
|
+
},
|
|
860
|
+
deleteTable: {
|
|
861
|
+
text: 'Tabloyu Sil'
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
298
865
|
},
|
|
299
866
|
clipboard: {
|
|
300
867
|
matchVisual: false
|
|
301
|
-
},
|
|
302
|
-
imageResize: {
|
|
303
|
-
modules: ["Resize", "DisplaySize"],
|
|
304
|
-
displaySize: true,
|
|
305
|
-
handleStyles: {
|
|
306
|
-
backgroundColor: '#000',
|
|
307
|
-
border: 'none',
|
|
308
|
-
color: '#fff'
|
|
309
|
-
}
|
|
310
868
|
}
|
|
311
869
|
};
|
|
870
|
+
(0, _react.useEffect)(() => {
|
|
871
|
+
if (showImageModal && imageWidthInputRef.current) {
|
|
872
|
+
imageWidthInputRef.current.focus();
|
|
873
|
+
}
|
|
874
|
+
}, [showImageModal]);
|
|
312
875
|
|
|
313
|
-
// Font adlarını gerçek isimleriyle göstermek için toolbar'ı güncelle
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
876
|
+
// Font adlarını gerçek isimleriyle göstermek için toolbar'ı güncelle - React 19 uyumlu
|
|
877
|
+
(0, _react.useEffect)(() => {
|
|
878
|
+
const updateFontPicker = () => {
|
|
879
|
+
try {
|
|
880
|
+
const fontPicker = document.querySelector(".ql-font");
|
|
881
|
+
if (fontPicker) {
|
|
882
|
+
const items = fontPicker.querySelectorAll(".ql-picker-item");
|
|
883
|
+
items.forEach((item, index) => {
|
|
884
|
+
if (fonts[index]) {
|
|
885
|
+
item.textContent = fonts[index].label; // React 19'da textContent kullan
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
const pickerLabel = fontPicker.querySelector(".ql-picker-label");
|
|
889
|
+
if (pickerLabel) {
|
|
890
|
+
pickerLabel.textContent = fonts[0].label; // Varsayılan font ismi
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
} catch (error) {
|
|
894
|
+
console.warn('Font picker update failed:', error);
|
|
320
895
|
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
// DOM yüklendikten sonra çalıştır
|
|
899
|
+
const timer = setTimeout(updateFontPicker, 100);
|
|
900
|
+
return () => clearTimeout(timer);
|
|
901
|
+
}, []);
|
|
902
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
903
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
904
|
+
className: 'myEditorContainer ' + (isFullscreen ? 'fullscreen' : ''),
|
|
905
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
906
|
+
className: "myEditorContainerContent",
|
|
907
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
|
|
908
|
+
onClick: handleFullscreen,
|
|
909
|
+
className: "myEditorContainerFullscreenButton",
|
|
910
|
+
title: isFullscreen ? "Minimize" : "Maximize",
|
|
911
|
+
children: isFullscreen ? /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
|
|
912
|
+
viewBox: "0 0 18 18",
|
|
913
|
+
width: "18",
|
|
914
|
+
height: "18",
|
|
915
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
|
|
916
|
+
d: "M4,4h2v6H0V8h4V4z M14,4v4h4v2h-6V4H14z M6,14H4v-4H0v-2h6V14z M14,14h-2v-6h6v2h-4V14z"
|
|
917
|
+
})
|
|
918
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
|
|
919
|
+
viewBox: "0 0 18 18",
|
|
920
|
+
width: "18",
|
|
921
|
+
height: "18",
|
|
922
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
|
|
923
|
+
d: "M4,4H0v2h6V0H4V4z M14,4V0h-2v6h6V4H14z M6,14H0v2h4v4h2V14z M14,18h2v-4h4v-2h-6V18z"
|
|
924
|
+
})
|
|
348
925
|
})
|
|
349
|
-
})
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
})
|
|
360
|
-
})
|
|
926
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactQuill.default, {
|
|
927
|
+
ref: editorRef,
|
|
928
|
+
theme: "snow",
|
|
929
|
+
value: editorValue,
|
|
930
|
+
onChange: handleChange,
|
|
931
|
+
modules: modules,
|
|
932
|
+
formats: formats,
|
|
933
|
+
style: style,
|
|
934
|
+
preserveWhitespace: true
|
|
935
|
+
})]
|
|
936
|
+
})
|
|
937
|
+
}), showImageModal && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
938
|
+
style: {
|
|
939
|
+
position: 'fixed',
|
|
940
|
+
top: 0,
|
|
941
|
+
left: 0,
|
|
942
|
+
right: 0,
|
|
943
|
+
bottom: 0,
|
|
944
|
+
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
945
|
+
display: 'flex',
|
|
946
|
+
alignItems: 'center',
|
|
947
|
+
justifyContent: 'center',
|
|
948
|
+
zIndex: 9999
|
|
949
|
+
},
|
|
950
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
951
|
+
style: {
|
|
952
|
+
backgroundColor: 'white',
|
|
953
|
+
padding: '20px',
|
|
954
|
+
borderRadius: '8px',
|
|
955
|
+
minWidth: '300px'
|
|
956
|
+
},
|
|
957
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h3", {
|
|
958
|
+
style: {
|
|
959
|
+
marginBottom: '15px'
|
|
960
|
+
},
|
|
961
|
+
children: "Resim Ayarlar\u0131"
|
|
962
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
963
|
+
style: {
|
|
964
|
+
marginBottom: '15px'
|
|
965
|
+
},
|
|
966
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("label", {
|
|
967
|
+
style: {
|
|
968
|
+
display: 'block',
|
|
969
|
+
marginBottom: '8px',
|
|
970
|
+
fontWeight: 'bold'
|
|
971
|
+
},
|
|
972
|
+
children: "Hizalama:"
|
|
973
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
974
|
+
style: {
|
|
975
|
+
display: 'flex',
|
|
976
|
+
gap: '8px',
|
|
977
|
+
justifyContent: 'center'
|
|
978
|
+
},
|
|
979
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
|
|
980
|
+
type: "button",
|
|
981
|
+
onClick: () => {
|
|
982
|
+
const img = selectedImageRef.current;
|
|
983
|
+
if (img) {
|
|
984
|
+
img.className = '';
|
|
985
|
+
img.style.cssText = `float: left; margin: 0 15px 10px 0; max-width: 100%; width: ${img.width}px; height: ${img.height}px;`;
|
|
986
|
+
setImageAlignment('left');
|
|
987
|
+
}
|
|
988
|
+
},
|
|
989
|
+
style: {
|
|
990
|
+
padding: '8px 12px',
|
|
991
|
+
backgroundColor: imageAlignment === 'left' ? '#e3f2fd' : '#f8f9fa',
|
|
992
|
+
border: imageAlignment === 'left' ? '3px solid #0066cc' : '2px solid #dee2e6',
|
|
993
|
+
borderRadius: '4px',
|
|
994
|
+
cursor: 'pointer',
|
|
995
|
+
display: 'flex',
|
|
996
|
+
flexDirection: 'column',
|
|
997
|
+
alignItems: 'center',
|
|
998
|
+
gap: '4px',
|
|
999
|
+
minWidth: '70px',
|
|
1000
|
+
transition: 'all 0.2s'
|
|
1001
|
+
},
|
|
1002
|
+
title: "Sola Hizala",
|
|
1003
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
|
|
1004
|
+
width: "24",
|
|
1005
|
+
height: "24",
|
|
1006
|
+
viewBox: "0 0 24 24",
|
|
1007
|
+
fill: "none",
|
|
1008
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("rect", {
|
|
1009
|
+
x: "4",
|
|
1010
|
+
y: "6",
|
|
1011
|
+
width: "10",
|
|
1012
|
+
height: "12",
|
|
1013
|
+
fill: "#0066cc",
|
|
1014
|
+
opacity: "0.3"
|
|
1015
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1016
|
+
x1: "16",
|
|
1017
|
+
y1: "8",
|
|
1018
|
+
x2: "20",
|
|
1019
|
+
y2: "8",
|
|
1020
|
+
stroke: "#333",
|
|
1021
|
+
strokeWidth: "2"
|
|
1022
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1023
|
+
x1: "16",
|
|
1024
|
+
y1: "12",
|
|
1025
|
+
x2: "20",
|
|
1026
|
+
y2: "12",
|
|
1027
|
+
stroke: "#333",
|
|
1028
|
+
strokeWidth: "2"
|
|
1029
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1030
|
+
x1: "16",
|
|
1031
|
+
y1: "16",
|
|
1032
|
+
x2: "20",
|
|
1033
|
+
y2: "16",
|
|
1034
|
+
stroke: "#333",
|
|
1035
|
+
strokeWidth: "2"
|
|
1036
|
+
})]
|
|
1037
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
1038
|
+
style: {
|
|
1039
|
+
fontSize: '12px',
|
|
1040
|
+
fontWeight: imageAlignment === 'left' ? 'bold' : 'normal',
|
|
1041
|
+
color: '#333'
|
|
1042
|
+
},
|
|
1043
|
+
children: "Sol"
|
|
1044
|
+
})]
|
|
1045
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
|
|
1046
|
+
type: "button",
|
|
1047
|
+
onClick: () => {
|
|
1048
|
+
const img = selectedImageRef.current;
|
|
1049
|
+
if (img) {
|
|
1050
|
+
img.className = '';
|
|
1051
|
+
img.style.cssText = `display: block; margin: 10px auto; max-width: 100%; width: ${img.width}px; height: ${img.height}px;`;
|
|
1052
|
+
setImageAlignment('center');
|
|
1053
|
+
}
|
|
1054
|
+
},
|
|
1055
|
+
style: {
|
|
1056
|
+
padding: '8px 12px',
|
|
1057
|
+
backgroundColor: imageAlignment === 'center' ? '#e3f2fd' : '#f8f9fa',
|
|
1058
|
+
border: imageAlignment === 'center' ? '3px solid #0066cc' : '2px solid #dee2e6',
|
|
1059
|
+
borderRadius: '4px',
|
|
1060
|
+
cursor: 'pointer',
|
|
1061
|
+
display: 'flex',
|
|
1062
|
+
flexDirection: 'column',
|
|
1063
|
+
alignItems: 'center',
|
|
1064
|
+
gap: '4px',
|
|
1065
|
+
minWidth: '70px',
|
|
1066
|
+
transition: 'all 0.2s'
|
|
1067
|
+
},
|
|
1068
|
+
title: "Ortala",
|
|
1069
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
|
|
1070
|
+
width: "24",
|
|
1071
|
+
height: "24",
|
|
1072
|
+
viewBox: "0 0 24 24",
|
|
1073
|
+
fill: "none",
|
|
1074
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("rect", {
|
|
1075
|
+
x: "7",
|
|
1076
|
+
y: "6",
|
|
1077
|
+
width: "10",
|
|
1078
|
+
height: "12",
|
|
1079
|
+
fill: "#0066cc",
|
|
1080
|
+
opacity: "0.3"
|
|
1081
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1082
|
+
x1: "4",
|
|
1083
|
+
y1: "12",
|
|
1084
|
+
x2: "6",
|
|
1085
|
+
y2: "12",
|
|
1086
|
+
stroke: "#333",
|
|
1087
|
+
strokeWidth: "2"
|
|
1088
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1089
|
+
x1: "18",
|
|
1090
|
+
y1: "12",
|
|
1091
|
+
x2: "20",
|
|
1092
|
+
y2: "12",
|
|
1093
|
+
stroke: "#333",
|
|
1094
|
+
strokeWidth: "2"
|
|
1095
|
+
})]
|
|
1096
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
1097
|
+
style: {
|
|
1098
|
+
fontSize: '12px',
|
|
1099
|
+
fontWeight: imageAlignment === 'center' ? 'bold' : 'normal',
|
|
1100
|
+
color: '#333'
|
|
1101
|
+
},
|
|
1102
|
+
children: "Orta"
|
|
1103
|
+
})]
|
|
1104
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
|
|
1105
|
+
type: "button",
|
|
1106
|
+
onClick: () => {
|
|
1107
|
+
const img = selectedImageRef.current;
|
|
1108
|
+
if (img) {
|
|
1109
|
+
img.className = '';
|
|
1110
|
+
img.style.cssText = `float: right; margin: 0 0 10px 15px; max-width: 100%; width: ${img.width}px; height: ${img.height}px;`;
|
|
1111
|
+
setImageAlignment('right');
|
|
1112
|
+
}
|
|
1113
|
+
},
|
|
1114
|
+
style: {
|
|
1115
|
+
padding: '8px 12px',
|
|
1116
|
+
backgroundColor: imageAlignment === 'right' ? '#e3f2fd' : '#f8f9fa',
|
|
1117
|
+
border: imageAlignment === 'right' ? '3px solid #0066cc' : '2px solid #dee2e6',
|
|
1118
|
+
borderRadius: '4px',
|
|
1119
|
+
cursor: 'pointer',
|
|
1120
|
+
display: 'flex',
|
|
1121
|
+
flexDirection: 'column',
|
|
1122
|
+
alignItems: 'center',
|
|
1123
|
+
gap: '4px',
|
|
1124
|
+
minWidth: '70px',
|
|
1125
|
+
transition: 'all 0.2s'
|
|
1126
|
+
},
|
|
1127
|
+
title: "Sa\u011Fa Hizala",
|
|
1128
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
|
|
1129
|
+
width: "24",
|
|
1130
|
+
height: "24",
|
|
1131
|
+
viewBox: "0 0 24 24",
|
|
1132
|
+
fill: "none",
|
|
1133
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("rect", {
|
|
1134
|
+
x: "10",
|
|
1135
|
+
y: "6",
|
|
1136
|
+
width: "10",
|
|
1137
|
+
height: "12",
|
|
1138
|
+
fill: "#0066cc",
|
|
1139
|
+
opacity: "0.3"
|
|
1140
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1141
|
+
x1: "4",
|
|
1142
|
+
y1: "8",
|
|
1143
|
+
x2: "8",
|
|
1144
|
+
y2: "8",
|
|
1145
|
+
stroke: "#333",
|
|
1146
|
+
strokeWidth: "2"
|
|
1147
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1148
|
+
x1: "4",
|
|
1149
|
+
y1: "12",
|
|
1150
|
+
x2: "8",
|
|
1151
|
+
y2: "12",
|
|
1152
|
+
stroke: "#333",
|
|
1153
|
+
strokeWidth: "2"
|
|
1154
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("line", {
|
|
1155
|
+
x1: "4",
|
|
1156
|
+
y1: "16",
|
|
1157
|
+
x2: "8",
|
|
1158
|
+
y2: "16",
|
|
1159
|
+
stroke: "#333",
|
|
1160
|
+
strokeWidth: "2"
|
|
1161
|
+
})]
|
|
1162
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
1163
|
+
style: {
|
|
1164
|
+
fontSize: '12px',
|
|
1165
|
+
fontWeight: imageAlignment === 'right' ? 'bold' : 'normal',
|
|
1166
|
+
color: '#333'
|
|
1167
|
+
},
|
|
1168
|
+
children: "Sa\u011F"
|
|
1169
|
+
})]
|
|
1170
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
|
|
1171
|
+
type: "button",
|
|
1172
|
+
onClick: () => {
|
|
1173
|
+
const img = selectedImageRef.current;
|
|
1174
|
+
if (img) {
|
|
1175
|
+
img.className = '';
|
|
1176
|
+
img.style.cssText = `display: inline-block; max-width: 100%; width: ${img.width}px; height: ${img.height}px;`;
|
|
1177
|
+
setImageAlignment('none');
|
|
1178
|
+
}
|
|
1179
|
+
},
|
|
1180
|
+
style: {
|
|
1181
|
+
padding: '8px 12px',
|
|
1182
|
+
backgroundColor: imageAlignment === 'none' ? '#f0f0f0' : '#f8f9fa',
|
|
1183
|
+
border: imageAlignment === 'none' ? '3px solid #6c757d' : '2px solid #dee2e6',
|
|
1184
|
+
borderRadius: '4px',
|
|
1185
|
+
cursor: 'pointer',
|
|
1186
|
+
display: 'flex',
|
|
1187
|
+
flexDirection: 'column',
|
|
1188
|
+
alignItems: 'center',
|
|
1189
|
+
gap: '4px',
|
|
1190
|
+
minWidth: '70px',
|
|
1191
|
+
transition: 'all 0.2s'
|
|
1192
|
+
},
|
|
1193
|
+
title: "Hizalama Yok",
|
|
1194
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {
|
|
1195
|
+
width: "24",
|
|
1196
|
+
height: "24",
|
|
1197
|
+
viewBox: "0 0 24 24",
|
|
1198
|
+
fill: "none",
|
|
1199
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("rect", {
|
|
1200
|
+
x: "7",
|
|
1201
|
+
y: "6",
|
|
1202
|
+
width: "10",
|
|
1203
|
+
height: "12",
|
|
1204
|
+
fill: "#6c757d",
|
|
1205
|
+
opacity: "0.3"
|
|
1206
|
+
})
|
|
1207
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
1208
|
+
style: {
|
|
1209
|
+
fontSize: '12px',
|
|
1210
|
+
fontWeight: imageAlignment === 'none' ? 'bold' : 'normal',
|
|
1211
|
+
color: '#333'
|
|
1212
|
+
},
|
|
1213
|
+
children: "Yok"
|
|
1214
|
+
})]
|
|
1215
|
+
})]
|
|
1216
|
+
})]
|
|
1217
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
1218
|
+
style: {
|
|
1219
|
+
marginBottom: '10px'
|
|
1220
|
+
},
|
|
1221
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("label", {
|
|
1222
|
+
style: {
|
|
1223
|
+
display: 'block',
|
|
1224
|
+
marginBottom: '5px'
|
|
1225
|
+
},
|
|
1226
|
+
children: "Geni\u015Flik (px):"
|
|
1227
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
|
|
1228
|
+
ref: imageWidthInputRef,
|
|
1229
|
+
type: "number",
|
|
1230
|
+
value: imageWidth,
|
|
1231
|
+
onChange: e => setImageWidth(parseInt(e.target.value) || 0),
|
|
1232
|
+
onKeyDown: e => {
|
|
1233
|
+
if (e.key === 'Enter') {
|
|
1234
|
+
imageHeightInputRef.current?.focus();
|
|
1235
|
+
}
|
|
1236
|
+
},
|
|
1237
|
+
style: {
|
|
1238
|
+
width: '100%',
|
|
1239
|
+
padding: '8px',
|
|
1240
|
+
border: '1px solid #ddd',
|
|
1241
|
+
borderRadius: '4px'
|
|
1242
|
+
}
|
|
1243
|
+
})]
|
|
1244
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
1245
|
+
style: {
|
|
1246
|
+
marginBottom: '15px'
|
|
1247
|
+
},
|
|
1248
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("label", {
|
|
1249
|
+
style: {
|
|
1250
|
+
display: 'block',
|
|
1251
|
+
marginBottom: '5px'
|
|
1252
|
+
},
|
|
1253
|
+
children: "Y\xFCkseklik (px):"
|
|
1254
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("input", {
|
|
1255
|
+
type: "number",
|
|
1256
|
+
ref: imageHeightInputRef,
|
|
1257
|
+
value: imageHeight,
|
|
1258
|
+
onChange: e => setImageHeight(parseInt(e.target.value) || 0),
|
|
1259
|
+
onKeyDown: e => {
|
|
1260
|
+
if (e.key === 'Enter') {
|
|
1261
|
+
handleImageResize();
|
|
1262
|
+
}
|
|
1263
|
+
},
|
|
1264
|
+
style: {
|
|
1265
|
+
width: '100%',
|
|
1266
|
+
padding: '8px',
|
|
1267
|
+
border: '1px solid #ddd',
|
|
1268
|
+
borderRadius: '4px'
|
|
1269
|
+
}
|
|
1270
|
+
})]
|
|
1271
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
1272
|
+
style: {
|
|
1273
|
+
display: 'flex',
|
|
1274
|
+
gap: '10px',
|
|
1275
|
+
justifyContent: 'flex-end'
|
|
1276
|
+
},
|
|
1277
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
|
|
1278
|
+
onClick: () => {
|
|
1279
|
+
setShowImageModal(false);
|
|
1280
|
+
selectedImageRef.current = null;
|
|
1281
|
+
},
|
|
1282
|
+
style: {
|
|
1283
|
+
padding: '8px 16px',
|
|
1284
|
+
backgroundColor: '#6c757d',
|
|
1285
|
+
color: 'white',
|
|
1286
|
+
border: 'none',
|
|
1287
|
+
borderRadius: '4px',
|
|
1288
|
+
cursor: 'pointer'
|
|
1289
|
+
},
|
|
1290
|
+
children: "\u0130ptal"
|
|
1291
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
|
|
1292
|
+
onClick: handleImageResize,
|
|
1293
|
+
style: {
|
|
1294
|
+
padding: '8px 16px',
|
|
1295
|
+
backgroundColor: '#0066cc',
|
|
1296
|
+
color: 'white',
|
|
1297
|
+
border: 'none',
|
|
1298
|
+
borderRadius: '4px',
|
|
1299
|
+
cursor: 'pointer'
|
|
1300
|
+
},
|
|
1301
|
+
children: "Uygula"
|
|
1302
|
+
})]
|
|
1303
|
+
})]
|
|
1304
|
+
})
|
|
1305
|
+
})]
|
|
361
1306
|
});
|
|
362
1307
|
}
|
|
363
1308
|
var _default = exports.default = MyEditor;
|