inconel 0.1.39 → 0.1.41

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.
Files changed (28) hide show
  1. package/dist/cjs/components/RichTextEditor/RichTextEditor.cjs +2 -0
  2. package/dist/cjs/components/RichTextEditor/RichTextEditor.cjs.map +1 -0
  3. package/dist/cjs/components/RichTextEditor/icons.cjs +2 -0
  4. package/dist/cjs/components/RichTextEditor/icons.cjs.map +1 -0
  5. package/dist/cjs/components/RichTextEditor/sanitize.cjs +2 -0
  6. package/dist/cjs/components/RichTextEditor/sanitize.cjs.map +1 -0
  7. package/dist/cjs/index.cjs +1 -1
  8. package/dist/cjs/styles.css +1 -1
  9. package/dist/components/RichTextEditor/RichTextEditor.d.ts +24 -0
  10. package/dist/components/RichTextEditor/RichTextEditor.d.ts.map +1 -0
  11. package/dist/components/RichTextEditor/RichTextEditor.js +337 -0
  12. package/dist/components/RichTextEditor/RichTextEditor.js.map +1 -0
  13. package/dist/components/RichTextEditor/icons.d.ts +22 -0
  14. package/dist/components/RichTextEditor/icons.d.ts.map +1 -0
  15. package/dist/components/RichTextEditor/icons.js +67 -0
  16. package/dist/components/RichTextEditor/icons.js.map +1 -0
  17. package/dist/components/RichTextEditor/index.d.ts +4 -0
  18. package/dist/components/RichTextEditor/index.d.ts.map +1 -0
  19. package/dist/components/RichTextEditor/sanitize.d.ts +3 -0
  20. package/dist/components/RichTextEditor/sanitize.d.ts.map +1 -0
  21. package/dist/components/RichTextEditor/sanitize.js +63 -0
  22. package/dist/components/RichTextEditor/sanitize.js.map +1 -0
  23. package/dist/components/index.d.ts +1 -0
  24. package/dist/components/index.d.ts.map +1 -1
  25. package/dist/index.js +88 -84
  26. package/dist/index.js.map +1 -1
  27. package/dist/styles.css +1 -1
  28. package/package.json +13 -13
@@ -0,0 +1,337 @@
1
+ import { jsxs as c, jsx as n } from "react/jsx-runtime";
2
+ import { useId as re, useRef as w, useState as y, useEffect as oe, useCallback as se } from "react";
3
+ import ce from "../FieldFeedback/FieldFeedback.js";
4
+ /* empty css */
5
+ /* empty css */
6
+ import { icons as l } from "./icons.js";
7
+ import { sanitizeHtml as b } from "./sanitize.js";
8
+ const ue = [
9
+ { tag: "p", label: "Paragraf" },
10
+ { tag: "h1", label: "Başlık 1" },
11
+ { tag: "h2", label: "Başlık 2" },
12
+ { tag: "h3", label: "Başlık 3" },
13
+ { tag: "blockquote", label: "Alıntı" }
14
+ ], de = [12, 14, 16, 18, 24, 32], me = (r) => new Promise((m, _) => {
15
+ const a = new FileReader();
16
+ a.onload = () => m(String(a.result)), a.onerror = () => _(a.error), a.readAsDataURL(r);
17
+ });
18
+ function N({ label: r, onClick: m, disabled: _, active: a, children: L }) {
19
+ return /* @__PURE__ */ n(
20
+ "button",
21
+ {
22
+ type: "button",
23
+ className: `inconel-rte__btn${a ? " inconel-is-active" : ""}`,
24
+ "aria-label": r,
25
+ title: r,
26
+ "aria-pressed": a,
27
+ disabled: _,
28
+ onMouseDown: (x) => x.preventDefault(),
29
+ onClick: m,
30
+ children: L
31
+ }
32
+ );
33
+ }
34
+ function ke({
35
+ value: r = "",
36
+ onChange: m,
37
+ onBlur: _,
38
+ label: a,
39
+ placeholder: L,
40
+ id: x,
41
+ disabled: p = !1,
42
+ required: D,
43
+ fullWidth: $ = !0,
44
+ className: K,
45
+ minHeight: j = 200,
46
+ onImageUpload: E,
47
+ onRequestMedia: z,
48
+ hint: H,
49
+ errorMessage: k
50
+ }) {
51
+ const Y = re(), C = x ?? `inconel-rte-${Y.replace(/:/g, "")}`, M = `${C}-hint`, I = `${C}-error`, o = w(null), F = w(null), v = w(null), [f, J] = y(!1), [U, G] = y(""), [u, B] = y(null), [O, P] = y(""), [Z, Q] = y({}), [V, R] = y(!r);
52
+ oe(() => {
53
+ const e = o.current;
54
+ if (!e || r === v.current) return;
55
+ const t = b(r);
56
+ e.innerHTML !== t && (e.innerHTML = t), v.current = r, R(!e.textContent && !e.querySelector("img"));
57
+ }, [r, f]);
58
+ const h = se(() => {
59
+ const e = o.current;
60
+ if (!e) return;
61
+ const t = !!e.textContent || !!e.querySelector("img"), s = t ? b(e.innerHTML) : "";
62
+ R(!t), v.current = s, m?.(s);
63
+ }, [m]), d = () => {
64
+ const e = window.getSelection(), t = o.current;
65
+ e && e.rangeCount > 0 && t?.contains(e.getRangeAt(0).commonAncestorContainer) && (F.current = e.getRangeAt(0).cloneRange());
66
+ }, T = () => {
67
+ o.current?.focus();
68
+ const e = window.getSelection();
69
+ e && F.current && (e.removeAllRanges(), e.addRange(F.current));
70
+ }, A = () => {
71
+ const e = (t) => {
72
+ try {
73
+ return document.queryCommandState(t);
74
+ } catch {
75
+ return !1;
76
+ }
77
+ };
78
+ Q({
79
+ bold: e("bold"),
80
+ italic: e("italic"),
81
+ underline: e("underline"),
82
+ strikeThrough: e("strikeThrough"),
83
+ justifyLeft: e("justifyLeft"),
84
+ justifyCenter: e("justifyCenter"),
85
+ justifyRight: e("justifyRight"),
86
+ justifyFull: e("justifyFull"),
87
+ insertUnorderedList: e("insertUnorderedList"),
88
+ insertOrderedList: e("insertOrderedList")
89
+ });
90
+ }, S = (e, t) => {
91
+ T(), document.execCommand("styleWithCSS", !1, "true"), document.execCommand(e, !1, t), d(), A(), h();
92
+ }, X = (e) => {
93
+ T(), document.execCommand("styleWithCSS", !1, "false"), document.execCommand("fontSize", !1, "7"), o.current?.querySelectorAll('font[size="7"]').forEach((t) => {
94
+ const s = document.createElement("span");
95
+ s.style.fontSize = `${e}px`, s.append(...Array.from(t.childNodes)), t.replaceWith(s);
96
+ }), d(), h();
97
+ }, ee = (e) => {
98
+ T(), document.execCommand("insertHTML", !1, b(e)), d(), h();
99
+ }, q = (e) => {
100
+ d(), P(""), B(u === e ? null : e);
101
+ }, W = () => {
102
+ const e = O.trim();
103
+ e && (u === "link" ? (S("createLink", e), o.current?.querySelectorAll("a").forEach((t) => {
104
+ /^https?:/i.test(t.getAttribute("href") ?? "") && (t.setAttribute("target", "_blank"), t.setAttribute("rel", "noopener noreferrer"));
105
+ }), h()) : u === "image" && S("insertImage", e), B(null));
106
+ }, te = async (e) => {
107
+ const t = e.target.files?.[0];
108
+ if (e.target.value = "", !t || !t.type.startsWith("image/")) return;
109
+ const s = E ? await E(t) : await me(t);
110
+ S("insertImage", s), B(null);
111
+ }, ne = (e) => {
112
+ const t = e.clipboardData.getData("text/html");
113
+ t && (e.preventDefault(), document.execCommand("insertHTML", !1, b(t)), h());
114
+ }, le = () => {
115
+ if (f) {
116
+ const e = b(U);
117
+ v.current = null, o.current && (o.current.innerHTML = e), v.current = e, R(!e), m?.(e);
118
+ } else
119
+ G(b(o.current?.innerHTML ?? ""));
120
+ B(null), J(!f);
121
+ }, ie = [H && !k ? M : void 0, k ? I : void 0].filter(Boolean).join(" ") || void 0, g = p || f, i = (e, t, s, ae) => /* @__PURE__ */ n(
122
+ N,
123
+ {
124
+ label: t,
125
+ active: Z[e],
126
+ disabled: g,
127
+ onClick: () => S(e, ae),
128
+ children: s
129
+ }
130
+ );
131
+ return /* @__PURE__ */ c(
132
+ "div",
133
+ {
134
+ className: [
135
+ "inconel-field",
136
+ $ ? "inconel-field--full-width" : "",
137
+ K ?? ""
138
+ ].join(" "),
139
+ children: [
140
+ a && /* @__PURE__ */ c("label", { className: "inconel-field__label", htmlFor: C, children: [
141
+ a,
142
+ D && /* @__PURE__ */ n("span", { "aria-hidden": "true", children: " *" })
143
+ ] }),
144
+ /* @__PURE__ */ c(
145
+ "div",
146
+ {
147
+ className: [
148
+ "inconel-rte",
149
+ k ? "inconel-is-invalid" : "",
150
+ p ? "inconel-is-disabled" : ""
151
+ ].join(" "),
152
+ children: [
153
+ /* @__PURE__ */ c("div", { className: "inconel-rte__toolbar", role: "toolbar", "aria-label": "Biçimlendirme", children: [
154
+ i("bold", "Kalın", l.bold),
155
+ i("italic", "İtalik", l.italic),
156
+ i("underline", "Altı çizili", l.underline),
157
+ i("strikeThrough", "Üstü çizili", l.strike),
158
+ /* @__PURE__ */ n("span", { className: "inconel-rte__sep" }),
159
+ /* @__PURE__ */ c(
160
+ "select",
161
+ {
162
+ className: "inconel-rte__select",
163
+ "aria-label": "Biçim",
164
+ disabled: g,
165
+ value: "",
166
+ onChange: (e) => {
167
+ e.target.value && S("formatBlock", e.target.value);
168
+ },
169
+ children: [
170
+ /* @__PURE__ */ n("option", { value: "", children: "Biçim" }),
171
+ ue.map((e) => /* @__PURE__ */ n("option", { value: e.tag, children: e.label }, e.tag))
172
+ ]
173
+ }
174
+ ),
175
+ /* @__PURE__ */ c(
176
+ "select",
177
+ {
178
+ className: "inconel-rte__select",
179
+ "aria-label": "Yazı boyutu",
180
+ disabled: g,
181
+ value: "",
182
+ onChange: (e) => {
183
+ e.target.value && X(Number(e.target.value));
184
+ },
185
+ children: [
186
+ /* @__PURE__ */ n("option", { value: "", children: "Boyut" }),
187
+ de.map((e) => /* @__PURE__ */ c("option", { value: e, children: [
188
+ e,
189
+ "px"
190
+ ] }, e))
191
+ ]
192
+ }
193
+ ),
194
+ /* @__PURE__ */ n("span", { className: "inconel-rte__sep" }),
195
+ i("justifyLeft", "Sola hizala", l.alignLeft),
196
+ i("justifyCenter", "Ortala", l.alignCenter),
197
+ i("justifyRight", "Sağa hizala", l.alignRight),
198
+ i("justifyFull", "İki yana yasla", l.alignJustify),
199
+ /* @__PURE__ */ n("span", { className: "inconel-rte__sep" }),
200
+ i("insertUnorderedList", "Madde işaretli liste", l.listUl),
201
+ i("insertOrderedList", "Numaralı liste", l.listOl),
202
+ i("outdent", "Girintiyi azalt", l.outdent),
203
+ i("indent", "Girintiyi artır", l.indent),
204
+ i("removeFormat", "Biçimi temizle", l.clearFormat),
205
+ /* @__PURE__ */ n("span", { className: "inconel-rte__sep" }),
206
+ /* @__PURE__ */ n(
207
+ N,
208
+ {
209
+ label: "Bağlantı ekle",
210
+ disabled: g,
211
+ active: u === "link",
212
+ onClick: () => q("link"),
213
+ children: l.link
214
+ }
215
+ ),
216
+ /* @__PURE__ */ n(
217
+ N,
218
+ {
219
+ label: "Görsel ekle",
220
+ disabled: g,
221
+ active: u === "image",
222
+ onClick: () => q("image"),
223
+ children: l.image
224
+ }
225
+ ),
226
+ z && /* @__PURE__ */ n(
227
+ N,
228
+ {
229
+ label: "Medya galerisi",
230
+ disabled: g,
231
+ onClick: () => {
232
+ d(), z(ee);
233
+ },
234
+ children: l.gallery
235
+ }
236
+ ),
237
+ /* @__PURE__ */ n("span", { className: "inconel-rte__sep" }),
238
+ i("undo", "Geri al", l.undo),
239
+ i("redo", "Yinele", l.redo),
240
+ /* @__PURE__ */ n(
241
+ N,
242
+ {
243
+ label: "HTML kaynağı",
244
+ disabled: p,
245
+ active: f,
246
+ onClick: le,
247
+ children: l.code
248
+ }
249
+ )
250
+ ] }),
251
+ u && !f && /* @__PURE__ */ c("div", { className: "inconel-rte__panel", children: [
252
+ /* @__PURE__ */ n(
253
+ "input",
254
+ {
255
+ type: "url",
256
+ className: "inconel-rte__input",
257
+ "aria-label": u === "link" ? "Bağlantı adresi" : "Görsel adresi",
258
+ placeholder: u === "link" ? "https://…" : "Görsel URL (https://…)",
259
+ value: O,
260
+ autoFocus: !0,
261
+ onChange: (e) => P(e.target.value),
262
+ onKeyDown: (e) => {
263
+ e.key === "Enter" && (e.preventDefault(), W());
264
+ }
265
+ }
266
+ ),
267
+ /* @__PURE__ */ n("button", { type: "button", className: "inconel-rte__action", onClick: W, children: "Ekle" }),
268
+ u === "image" && /* @__PURE__ */ c("label", { className: "inconel-rte__action", children: [
269
+ "Dosya seç",
270
+ /* @__PURE__ */ n(
271
+ "input",
272
+ {
273
+ type: "file",
274
+ accept: "image/*",
275
+ hidden: !0,
276
+ "aria-label": "Görsel dosyası",
277
+ onChange: te
278
+ }
279
+ )
280
+ ] })
281
+ ] }),
282
+ f ? /* @__PURE__ */ n(
283
+ "textarea",
284
+ {
285
+ id: C,
286
+ className: "inconel-rte__source",
287
+ style: { minHeight: j },
288
+ "aria-label": a ?? "HTML kaynağı",
289
+ value: U,
290
+ disabled: p,
291
+ spellCheck: !1,
292
+ onChange: (e) => G(e.target.value)
293
+ }
294
+ ) : /* @__PURE__ */ c("div", { className: "inconel-rte__surface", style: { minHeight: j }, children: [
295
+ V && L && /* @__PURE__ */ n("span", { className: "inconel-rte__placeholder", "aria-hidden": "true", children: L }),
296
+ /* @__PURE__ */ n(
297
+ "div",
298
+ {
299
+ ref: o,
300
+ id: C,
301
+ className: "inconel-rte__content",
302
+ role: "textbox",
303
+ "aria-multiline": "true",
304
+ "aria-label": a,
305
+ "aria-required": D,
306
+ "aria-invalid": !!k,
307
+ "aria-describedby": ie,
308
+ "aria-disabled": p,
309
+ contentEditable: !p,
310
+ suppressContentEditableWarning: !0,
311
+ style: { minHeight: j },
312
+ onInput: h,
313
+ onPaste: ne,
314
+ onKeyUp: () => {
315
+ d(), A();
316
+ },
317
+ onMouseUp: () => {
318
+ d(), A();
319
+ },
320
+ onBlur: () => {
321
+ d(), _?.();
322
+ }
323
+ }
324
+ )
325
+ ] })
326
+ ]
327
+ }
328
+ ),
329
+ /* @__PURE__ */ n(ce, { hint: H, errorMessage: k, hintId: M, errorId: I })
330
+ ]
331
+ }
332
+ );
333
+ }
334
+ export {
335
+ ke as default
336
+ };
337
+ //# sourceMappingURL=RichTextEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RichTextEditor.js","sources":["../../../src/components/RichTextEditor/RichTextEditor.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ChangeEvent,\n type ReactNode,\n} from 'react'\n\nimport FieldFeedback from '../FieldFeedback/FieldFeedback'\nimport type { FieldFeedbackContentProps } from '../FieldFeedback/FieldFeedback'\nimport '../shared/field.css'\nimport './styles.css'\nimport { icons } from './icons'\nimport { sanitizeHtml } from './sanitize'\n\nexport interface RichTextEditorProps extends FieldFeedbackContentProps {\n value?: string\n onChange?: (html: string) => void\n onBlur?: () => void\n label?: string\n placeholder?: string\n id?: string\n disabled?: boolean\n required?: boolean\n fullWidth?: boolean\n className?: string\n /** Editör içerik alanının minimum yüksekliği (px). */\n minHeight?: number\n /** Görsel dosyası seçilince çağrılır; dönen URL görsel olarak eklenir. Verilmezse base64 gömülür. */\n onImageUpload?: (file: File) => Promise<string>\n /**\n * Verilirse araç çubuğuna galeri düğmesi eklenir. Düğmeye basınca çağrılır;\n * uygulama kendi medya kütüphanesini açıp seçilen içeriği `insert(html)` ile ekler.\n */\n onRequestMedia?: (insert: (html: string) => void) => void\n}\n\nconst BLOCKS = [\n { tag: 'p', label: 'Paragraf' },\n { tag: 'h1', label: 'Başlık 1' },\n { tag: 'h2', label: 'Başlık 2' },\n { tag: 'h3', label: 'Başlık 3' },\n { tag: 'blockquote', label: 'Alıntı' },\n]\n\nconst FONT_SIZES = [12, 14, 16, 18, 24, 32]\n\ntype Panel = 'link' | 'image' | null\n\nconst readFileAsDataUrl = (file: File) =>\n new Promise<string>((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => resolve(String(reader.result))\n reader.onerror = () => reject(reader.error)\n reader.readAsDataURL(file)\n })\n\ninterface ToolButtonProps {\n label: string\n onClick: () => void\n disabled?: boolean\n active?: boolean\n children: ReactNode\n}\n\nfunction ToolButton({ label, onClick, disabled, active, children }: ToolButtonProps) {\n return (\n <button\n type=\"button\"\n className={`inconel-rte__btn${active ? ' inconel-is-active' : ''}`}\n aria-label={label}\n title={label}\n aria-pressed={active}\n disabled={disabled}\n onMouseDown={(event) => event.preventDefault()}\n onClick={onClick}\n >\n {children}\n </button>\n )\n}\n\nexport default function RichTextEditor({\n value = '',\n onChange,\n onBlur,\n label,\n placeholder,\n id,\n disabled = false,\n required,\n fullWidth = true,\n className,\n minHeight = 200,\n onImageUpload,\n onRequestMedia,\n hint,\n errorMessage,\n}: RichTextEditorProps) {\n const generatedId = useId()\n const editorId = id ?? `inconel-rte-${generatedId.replace(/:/g, '')}`\n const hintId = `${editorId}-hint`\n const errorId = `${editorId}-error`\n\n const editorRef = useRef<HTMLDivElement>(null)\n const savedRange = useRef<Range | null>(null)\n const lastHtml = useRef<string | null>(null)\n const [sourceMode, setSourceMode] = useState(false)\n const [source, setSource] = useState('')\n const [panel, setPanel] = useState<Panel>(null)\n const [url, setUrl] = useState('')\n const [formats, setFormats] = useState<Record<string, boolean>>({})\n const [empty, setEmpty] = useState(!value)\n\n // Dışarıdan gelen value değişince (kendi çıktımız değilse) içeriği güncelle.\n useEffect(() => {\n const editor = editorRef.current\n if (!editor || value === lastHtml.current) return\n const clean = sanitizeHtml(value)\n if (editor.innerHTML !== clean) editor.innerHTML = clean\n lastHtml.current = value\n setEmpty(!editor.textContent && !editor.querySelector('img'))\n }, [value, sourceMode])\n\n const emit = useCallback(() => {\n const editor = editorRef.current\n if (!editor) return\n const hasContent = Boolean(editor.textContent) || Boolean(editor.querySelector('img'))\n const html = hasContent ? sanitizeHtml(editor.innerHTML) : ''\n setEmpty(!hasContent)\n lastHtml.current = html\n onChange?.(html)\n }, [onChange])\n\n const saveSelection = () => {\n const selection = window.getSelection()\n const editor = editorRef.current\n if (\n selection &&\n selection.rangeCount > 0 &&\n editor?.contains(selection.getRangeAt(0).commonAncestorContainer)\n ) {\n savedRange.current = selection.getRangeAt(0).cloneRange()\n }\n }\n\n const restoreSelection = () => {\n editorRef.current?.focus()\n const selection = window.getSelection()\n if (selection && savedRange.current) {\n selection.removeAllRanges()\n selection.addRange(savedRange.current)\n }\n }\n\n const refreshFormats = () => {\n const query = (command: string) => {\n try {\n return document.queryCommandState(command)\n } catch {\n return false\n }\n }\n setFormats({\n bold: query('bold'),\n italic: query('italic'),\n underline: query('underline'),\n strikeThrough: query('strikeThrough'),\n justifyLeft: query('justifyLeft'),\n justifyCenter: query('justifyCenter'),\n justifyRight: query('justifyRight'),\n justifyFull: query('justifyFull'),\n insertUnorderedList: query('insertUnorderedList'),\n insertOrderedList: query('insertOrderedList'),\n })\n }\n\n const exec = (command: string, arg?: string) => {\n restoreSelection()\n document.execCommand('styleWithCSS', false, 'true')\n document.execCommand(command, false, arg)\n saveSelection()\n refreshFormats()\n emit()\n }\n\n const applyFontSize = (px: number) => {\n restoreSelection()\n document.execCommand('styleWithCSS', false, 'false')\n document.execCommand('fontSize', false, '7')\n editorRef.current?.querySelectorAll('font[size=\"7\"]').forEach((font) => {\n const span = document.createElement('span')\n span.style.fontSize = `${px}px`\n span.append(...Array.from(font.childNodes))\n font.replaceWith(span)\n })\n saveSelection()\n emit()\n }\n\n const insertHtml = (html: string) => {\n restoreSelection()\n document.execCommand('insertHTML', false, sanitizeHtml(html))\n saveSelection()\n emit()\n }\n\n const openPanel = (next: Exclude<Panel, null>) => {\n saveSelection()\n setUrl('')\n setPanel(panel === next ? null : next)\n }\n\n const submitPanel = () => {\n const target = url.trim()\n if (!target) return\n if (panel === 'link') {\n exec('createLink', target)\n editorRef.current?.querySelectorAll('a').forEach((a) => {\n if (/^https?:/i.test(a.getAttribute('href') ?? '')) {\n a.setAttribute('target', '_blank')\n a.setAttribute('rel', 'noopener noreferrer')\n }\n })\n emit()\n } else if (panel === 'image') {\n exec('insertImage', target)\n }\n setPanel(null)\n }\n\n const handleImageFile = async (event: ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0]\n event.target.value = ''\n if (!file || !file.type.startsWith('image/')) return\n const src = onImageUpload ? await onImageUpload(file) : await readFileAsDataUrl(file)\n exec('insertImage', src)\n setPanel(null)\n }\n\n const handlePaste = (event: React.ClipboardEvent<HTMLDivElement>) => {\n const html = event.clipboardData.getData('text/html')\n if (html) {\n event.preventDefault()\n document.execCommand('insertHTML', false, sanitizeHtml(html))\n emit()\n }\n }\n\n const toggleSource = () => {\n if (sourceMode) {\n const clean = sanitizeHtml(source)\n lastHtml.current = null\n if (editorRef.current) editorRef.current.innerHTML = clean\n lastHtml.current = clean\n setEmpty(!clean)\n onChange?.(clean)\n } else {\n setSource(sanitizeHtml(editorRef.current?.innerHTML ?? ''))\n }\n setPanel(null)\n setSourceMode(!sourceMode)\n }\n\n const describedBy =\n [hint && !errorMessage ? hintId : undefined, errorMessage ? errorId : undefined]\n .filter(Boolean)\n .join(' ') || undefined\n const toolsDisabled = disabled || sourceMode\n\n const btn = (\n command: string,\n text: string,\n content: ReactNode,\n arg?: string,\n ) => (\n <ToolButton\n label={text}\n active={formats[command]}\n disabled={toolsDisabled}\n onClick={() => exec(command, arg)}\n >\n {content}\n </ToolButton>\n )\n\n return (\n <div\n className={[\n 'inconel-field',\n fullWidth ? 'inconel-field--full-width' : '',\n className ?? '',\n ].join(' ')}\n >\n {label && (\n <label className=\"inconel-field__label\" htmlFor={editorId}>\n {label}\n {required && <span aria-hidden=\"true\"> *</span>}\n </label>\n )}\n <div\n className={[\n 'inconel-rte',\n errorMessage ? 'inconel-is-invalid' : '',\n disabled ? 'inconel-is-disabled' : '',\n ].join(' ')}\n >\n <div className=\"inconel-rte__toolbar\" role=\"toolbar\" aria-label=\"Biçimlendirme\">\n {btn('bold', 'Kalın', icons.bold)}\n {btn('italic', 'İtalik', icons.italic)}\n {btn('underline', 'Altı çizili', icons.underline)}\n {btn('strikeThrough', 'Üstü çizili', icons.strike)}\n <span className=\"inconel-rte__sep\" />\n <select\n className=\"inconel-rte__select\"\n aria-label=\"Biçim\"\n disabled={toolsDisabled}\n value=\"\"\n onChange={(event) => {\n if (event.target.value) exec('formatBlock', event.target.value)\n }}\n >\n <option value=\"\">Biçim</option>\n {BLOCKS.map((block) => (\n <option key={block.tag} value={block.tag}>\n {block.label}\n </option>\n ))}\n </select>\n <select\n className=\"inconel-rte__select\"\n aria-label=\"Yazı boyutu\"\n disabled={toolsDisabled}\n value=\"\"\n onChange={(event) => {\n if (event.target.value) applyFontSize(Number(event.target.value))\n }}\n >\n <option value=\"\">Boyut</option>\n {FONT_SIZES.map((size) => (\n <option key={size} value={size}>\n {size}px\n </option>\n ))}\n </select>\n <span className=\"inconel-rte__sep\" />\n {btn('justifyLeft', 'Sola hizala', icons.alignLeft)}\n {btn('justifyCenter', 'Ortala', icons.alignCenter)}\n {btn('justifyRight', 'Sağa hizala', icons.alignRight)}\n {btn('justifyFull', 'İki yana yasla', icons.alignJustify)}\n <span className=\"inconel-rte__sep\" />\n {btn('insertUnorderedList', 'Madde işaretli liste', icons.listUl)}\n {btn('insertOrderedList', 'Numaralı liste', icons.listOl)}\n {btn('outdent', 'Girintiyi azalt', icons.outdent)}\n {btn('indent', 'Girintiyi artır', icons.indent)}\n {btn('removeFormat', 'Biçimi temizle', icons.clearFormat)}\n <span className=\"inconel-rte__sep\" />\n <ToolButton\n label=\"Bağlantı ekle\"\n disabled={toolsDisabled}\n active={panel === 'link'}\n onClick={() => openPanel('link')}\n >\n {icons.link}\n </ToolButton>\n <ToolButton\n label=\"Görsel ekle\"\n disabled={toolsDisabled}\n active={panel === 'image'}\n onClick={() => openPanel('image')}\n >\n {icons.image}\n </ToolButton>\n {onRequestMedia && (\n <ToolButton\n label=\"Medya galerisi\"\n disabled={toolsDisabled}\n onClick={() => {\n saveSelection()\n onRequestMedia(insertHtml)\n }}\n >\n {icons.gallery}\n </ToolButton>\n )}\n <span className=\"inconel-rte__sep\" />\n {btn('undo', 'Geri al', icons.undo)}\n {btn('redo', 'Yinele', icons.redo)}\n <ToolButton\n label=\"HTML kaynağı\"\n disabled={disabled}\n active={sourceMode}\n onClick={toggleSource}\n >\n {icons.code}\n </ToolButton>\n </div>\n\n {panel && !sourceMode && (\n <div className=\"inconel-rte__panel\">\n <input\n type=\"url\"\n className=\"inconel-rte__input\"\n aria-label={panel === 'link' ? 'Bağlantı adresi' : 'Görsel adresi'}\n placeholder={panel === 'link' ? 'https://…' : 'Görsel URL (https://…)'}\n value={url}\n autoFocus\n onChange={(event) => setUrl(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault()\n submitPanel()\n }\n }}\n />\n <button type=\"button\" className=\"inconel-rte__action\" onClick={submitPanel}>\n Ekle\n </button>\n {panel === 'image' && (\n <label className=\"inconel-rte__action\">\n Dosya seç\n <input\n type=\"file\"\n accept=\"image/*\"\n hidden\n aria-label=\"Görsel dosyası\"\n onChange={handleImageFile}\n />\n </label>\n )}\n </div>\n )}\n\n {sourceMode ? (\n <textarea\n id={editorId}\n className=\"inconel-rte__source\"\n style={{ minHeight }}\n aria-label={label ?? 'HTML kaynağı'}\n value={source}\n disabled={disabled}\n spellCheck={false}\n onChange={(event) => setSource(event.target.value)}\n />\n ) : (\n <div className=\"inconel-rte__surface\" style={{ minHeight }}>\n {empty && placeholder && (\n <span className=\"inconel-rte__placeholder\" aria-hidden=\"true\">\n {placeholder}\n </span>\n )}\n <div\n ref={editorRef}\n id={editorId}\n className=\"inconel-rte__content\"\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={label}\n aria-required={required}\n aria-invalid={Boolean(errorMessage)}\n aria-describedby={describedBy}\n aria-disabled={disabled}\n contentEditable={!disabled}\n suppressContentEditableWarning\n style={{ minHeight }}\n onInput={emit}\n onPaste={handlePaste}\n onKeyUp={() => {\n saveSelection()\n refreshFormats()\n }}\n onMouseUp={() => {\n saveSelection()\n refreshFormats()\n }}\n onBlur={() => {\n saveSelection()\n onBlur?.()\n }}\n />\n </div>\n )}\n </div>\n <FieldFeedback hint={hint} errorMessage={errorMessage} hintId={hintId} errorId={errorId} />\n </div>\n )\n}\n"],"names":["BLOCKS","FONT_SIZES","readFileAsDataUrl","file","resolve","reject","reader","ToolButton","label","onClick","disabled","active","children","jsx","event","RichTextEditor","value","onChange","onBlur","placeholder","id","required","fullWidth","className","minHeight","onImageUpload","onRequestMedia","hint","errorMessage","generatedId","useId","editorId","hintId","errorId","editorRef","useRef","savedRange","lastHtml","sourceMode","setSourceMode","useState","source","setSource","panel","setPanel","url","setUrl","formats","setFormats","empty","setEmpty","useEffect","editor","clean","sanitizeHtml","emit","useCallback","hasContent","html","saveSelection","selection","restoreSelection","refreshFormats","query","command","exec","arg","applyFontSize","px","font","span","insertHtml","openPanel","next","submitPanel","target","a","handleImageFile","src","handlePaste","toggleSource","describedBy","toolsDisabled","btn","text","content","jsxs","icons","block","size","FieldFeedback"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export declare const icons: {
2
+ bold: import("react").JSX.Element;
3
+ italic: import("react").JSX.Element;
4
+ underline: import("react").JSX.Element;
5
+ strike: import("react").JSX.Element;
6
+ alignLeft: import("react").JSX.Element;
7
+ alignCenter: import("react").JSX.Element;
8
+ alignRight: import("react").JSX.Element;
9
+ alignJustify: import("react").JSX.Element;
10
+ listUl: import("react").JSX.Element;
11
+ listOl: import("react").JSX.Element;
12
+ outdent: import("react").JSX.Element;
13
+ indent: import("react").JSX.Element;
14
+ clearFormat: import("react").JSX.Element;
15
+ link: import("react").JSX.Element;
16
+ image: import("react").JSX.Element;
17
+ gallery: import("react").JSX.Element;
18
+ undo: import("react").JSX.Element;
19
+ redo: import("react").JSX.Element;
20
+ code: import("react").JSX.Element;
21
+ };
22
+ //# sourceMappingURL=icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/RichTextEditor/icons.tsx"],"names":[],"mappings":"AAmBA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;CA8CjB,CAAA"}
@@ -0,0 +1,67 @@
1
+ import { jsx as h, jsxs as M, Fragment as a } from "react/jsx-runtime";
2
+ const t = (d) => /* @__PURE__ */ h(
3
+ "svg",
4
+ {
5
+ width: "18",
6
+ height: "18",
7
+ viewBox: "0 0 24 24",
8
+ fill: "none",
9
+ stroke: "currentColor",
10
+ strokeWidth: "2",
11
+ strokeLinecap: "round",
12
+ strokeLinejoin: "round",
13
+ "aria-hidden": "true",
14
+ focusable: "false",
15
+ children: d
16
+ }
17
+ ), i = {
18
+ bold: t(/* @__PURE__ */ h("path", { d: "M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z" })),
19
+ italic: t(/* @__PURE__ */ h("path", { d: "M19 4h-9M14 20H5M15 4 9 20" })),
20
+ underline: t(/* @__PURE__ */ h("path", { d: "M7 4v7a5 5 0 0 0 10 0V4M5 20h14" })),
21
+ strike: t(
22
+ /* @__PURE__ */ h("path", { d: "M16 6a4 4 0 0 0-4-2c-2.5 0-4 1.3-4 3s1.5 2.5 4 3M4 12h16M8 18a4 4 0 0 0 4 2c2.5 0 4-1.3 4-3 0-.9-.4-1.6-1.2-2.1" })
23
+ ),
24
+ alignLeft: t(/* @__PURE__ */ h("path", { d: "M4 6h16M4 10h10M4 14h16M4 18h10" })),
25
+ alignCenter: t(/* @__PURE__ */ h("path", { d: "M4 6h16M7 10h10M4 14h16M7 18h10" })),
26
+ alignRight: t(/* @__PURE__ */ h("path", { d: "M4 6h16M10 10h10M4 14h16M10 18h10" })),
27
+ alignJustify: t(/* @__PURE__ */ h("path", { d: "M4 6h16M4 10h16M4 14h16M4 18h16" })),
28
+ listUl: t(
29
+ /* @__PURE__ */ M(a, { children: [
30
+ /* @__PURE__ */ h("path", { d: "M9 6h11M9 12h11M9 18h11" }),
31
+ /* @__PURE__ */ h("path", { d: "M4.5 6h.01M4.5 12h.01M4.5 18h.01", strokeWidth: "3" })
32
+ ] })
33
+ ),
34
+ listOl: t(
35
+ /* @__PURE__ */ M(a, { children: [
36
+ /* @__PURE__ */ h("path", { d: "M10 6h10M10 12h10M10 18h10" }),
37
+ /* @__PURE__ */ h("path", { d: "M4 5.5 5.5 5v4.5M4 14.5a1.5 1.5 0 1 1 3 0c0 1-3 2-3 3.5h3", strokeWidth: "1.5" })
38
+ ] })
39
+ ),
40
+ outdent: t(/* @__PURE__ */ h("path", { d: "M4 6h16M10 10h10M10 14h10M4 18h16M7 9l-3 3 3 3" })),
41
+ indent: t(/* @__PURE__ */ h("path", { d: "M4 6h16M10 10h10M10 14h10M4 18h16M4 9l3 3-3 3" })),
42
+ clearFormat: t(/* @__PURE__ */ h("path", { d: "M6 5h12M12 5l-1.5 6M9 19h4M4 4l16 16" })),
43
+ link: t(
44
+ /* @__PURE__ */ h("path", { d: "M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1" })
45
+ ),
46
+ image: t(
47
+ /* @__PURE__ */ M(a, { children: [
48
+ /* @__PURE__ */ h("rect", { x: "3", y: "4", width: "18", height: "16", rx: "2" }),
49
+ /* @__PURE__ */ h("circle", { cx: "9", cy: "10", r: "1.5" }),
50
+ /* @__PURE__ */ h("path", { d: "m3 17 5-5 4 4 3-3 6 6" })
51
+ ] })
52
+ ),
53
+ gallery: t(
54
+ /* @__PURE__ */ M(a, { children: [
55
+ /* @__PURE__ */ h("path", { d: "M7 7V5a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1h-2" }),
56
+ /* @__PURE__ */ h("rect", { x: "3", y: "8", width: "15", height: "12", rx: "1.5" }),
57
+ /* @__PURE__ */ h("path", { d: "m3 17 4-4 3 3 3-3 5 5" })
58
+ ] })
59
+ ),
60
+ undo: t(/* @__PURE__ */ h("path", { d: "M9 14 4 9l5-5M4 9h10a6 6 0 0 1 0 12h-3" })),
61
+ redo: t(/* @__PURE__ */ h("path", { d: "m15 14 5-5-5-5M20 9H10a6 6 0 0 0 0 12h3" })),
62
+ code: t(/* @__PURE__ */ h("path", { d: "m8 7-5 5 5 5M16 7l5 5-5 5" }))
63
+ };
64
+ export {
65
+ i as icons
66
+ };
67
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sources":["../../../src/components/RichTextEditor/icons.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\n\nconst icon = (paths: ReactNode) => (\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n {paths}\n </svg>\n)\n\nexport const icons = {\n bold: icon(<path d=\"M7 5h6a3.5 3.5 0 0 1 0 7H7zM7 12h7a3.5 3.5 0 0 1 0 7H7z\" />),\n italic: icon(<path d=\"M19 4h-9M14 20H5M15 4 9 20\" />),\n underline: icon(<path d=\"M7 4v7a5 5 0 0 0 10 0V4M5 20h14\" />),\n strike: icon(\n <path d=\"M16 6a4 4 0 0 0-4-2c-2.5 0-4 1.3-4 3s1.5 2.5 4 3M4 12h16M8 18a4 4 0 0 0 4 2c2.5 0 4-1.3 4-3 0-.9-.4-1.6-1.2-2.1\" />,\n ),\n alignLeft: icon(<path d=\"M4 6h16M4 10h10M4 14h16M4 18h10\" />),\n alignCenter: icon(<path d=\"M4 6h16M7 10h10M4 14h16M7 18h10\" />),\n alignRight: icon(<path d=\"M4 6h16M10 10h10M4 14h16M10 18h10\" />),\n alignJustify: icon(<path d=\"M4 6h16M4 10h16M4 14h16M4 18h16\" />),\n listUl: icon(\n <>\n <path d=\"M9 6h11M9 12h11M9 18h11\" />\n <path d=\"M4.5 6h.01M4.5 12h.01M4.5 18h.01\" strokeWidth=\"3\" />\n </>,\n ),\n listOl: icon(\n <>\n <path d=\"M10 6h10M10 12h10M10 18h10\" />\n <path d=\"M4 5.5 5.5 5v4.5M4 14.5a1.5 1.5 0 1 1 3 0c0 1-3 2-3 3.5h3\" strokeWidth=\"1.5\" />\n </>,\n ),\n outdent: icon(<path d=\"M4 6h16M10 10h10M10 14h10M4 18h16M7 9l-3 3 3 3\" />),\n indent: icon(<path d=\"M4 6h16M10 10h10M10 14h10M4 18h16M4 9l3 3-3 3\" />),\n clearFormat: icon(<path d=\"M6 5h12M12 5l-1.5 6M9 19h4M4 4l16 16\" />),\n link: icon(\n <path d=\"M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1\" />,\n ),\n image: icon(\n <>\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <circle cx=\"9\" cy=\"10\" r=\"1.5\" />\n <path d=\"m3 17 5-5 4 4 3-3 6 6\" />\n </>,\n ),\n gallery: icon(\n <>\n <path d=\"M7 7V5a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1h-2\" />\n <rect x=\"3\" y=\"8\" width=\"15\" height=\"12\" rx=\"1.5\" />\n <path d=\"m3 17 4-4 3 3 3-3 5 5\" />\n </>,\n ),\n undo: icon(<path d=\"M9 14 4 9l5-5M4 9h10a6 6 0 0 1 0 12h-3\" />),\n redo: icon(<path d=\"m15 14 5-5-5-5M20 9H10a6 6 0 0 0 0 12h3\" />),\n code: icon(<path d=\"m8 7-5 5 5 5M16 7l5 5-5 5\" />),\n}\n"],"names":["icon","paths","jsx","icons","jsxs","Fragment"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { default as RichTextEditor } from './RichTextEditor';
2
+ export type { RichTextEditorProps } from './RichTextEditor';
3
+ export { sanitizeHtml } from './sanitize';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RichTextEditor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC5D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ /** HTML'i izin verilen etiket/özelliklerle sınırlar (script, on* olayları, javascript: vb. temizlenir). */
2
+ export declare function sanitizeHtml(html: string): string;
3
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../src/components/RichTextEditor/sanitize.ts"],"names":[],"mappings":"AA2EA,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD"}
@@ -0,0 +1,63 @@
1
+ const l = /* @__PURE__ */ new Set([
2
+ "a",
3
+ "b",
4
+ "strong",
5
+ "i",
6
+ "em",
7
+ "u",
8
+ "s",
9
+ "strike",
10
+ "del",
11
+ "p",
12
+ "div",
13
+ "span",
14
+ "br",
15
+ "ul",
16
+ "ol",
17
+ "li",
18
+ "h1",
19
+ "h2",
20
+ "h3",
21
+ "h4",
22
+ "blockquote",
23
+ "img",
24
+ "sub",
25
+ "sup"
26
+ ]), m = {
27
+ a: ["href", "target", "rel", "title", "class"],
28
+ img: ["src", "alt", "title", "width", "height", "class"]
29
+ }, f = /* @__PURE__ */ new Set(["text-align", "font-size"]), u = /* @__PURE__ */ new Set(["script", "style", "iframe", "object", "embed", "noscript"]), c = (r, e) => {
30
+ const t = Array.from(r).filter((n) => n.charCodeAt(0) > 32).join("");
31
+ return e && /^data:image\/(png|jpe?g|gif|webp|bmp);/i.test(t) ? !0 : /^(https?:|mailto:|tel:|\/|#|\.{1,2}\/)/i.test(t) || !/^[a-z][a-z0-9+.-]*:/i.test(t);
32
+ }, b = (r) => r.split(";").map((e) => e.split(":").map((t) => t.trim())).filter(
33
+ ([e, t]) => f.has(e?.toLowerCase()) && t && /^[\w\s.%-]+$/.test(t)
34
+ ).map(([e, t]) => `${e.toLowerCase()}: ${t}`).join("; "), i = (r) => {
35
+ Array.from(r.children).forEach((e) => {
36
+ const t = e.tagName.toLowerCase();
37
+ if (u.has(t)) {
38
+ e.remove();
39
+ return;
40
+ }
41
+ if (i(e), !l.has(t)) {
42
+ e.replaceWith(...Array.from(e.childNodes));
43
+ return;
44
+ }
45
+ const n = m[t] ?? [];
46
+ Array.from(e.attributes).forEach((s) => {
47
+ const o = s.name.toLowerCase();
48
+ if (o === "style") {
49
+ const a = b(s.value);
50
+ a ? e.setAttribute("style", a) : e.removeAttribute("style");
51
+ } else o === "class" ? (!n.includes("class") || !/^[\w\s-]+$/.test(s.value)) && e.removeAttribute(s.name) : n.includes(o) ? (o === "href" || o === "src") && !c(s.value, t === "img") && e.removeAttribute(s.name) : e.removeAttribute(s.name);
52
+ }), t === "a" && e.getAttribute("target") === "_blank" && e.setAttribute("rel", "noopener noreferrer");
53
+ });
54
+ };
55
+ function p(r) {
56
+ if (!r) return "";
57
+ const e = new DOMParser().parseFromString(`<body>${r}</body>`, "text/html");
58
+ return i(e.body), e.body.innerHTML;
59
+ }
60
+ export {
61
+ p as sanitizeHtml
62
+ };
63
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sources":["../../../src/components/RichTextEditor/sanitize.ts"],"sourcesContent":["const ALLOWED_TAGS = new Set([\n 'a', 'b', 'strong', 'i', 'em', 'u', 's', 'strike', 'del', 'p', 'div', 'span',\n 'br', 'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'blockquote', 'img', 'sub', 'sup',\n])\n\nconst ALLOWED_ATTRS: Record<string, string[]> = {\n a: ['href', 'target', 'rel', 'title', 'class'],\n img: ['src', 'alt', 'title', 'width', 'height', 'class'],\n}\n\nconst ALLOWED_STYLES = new Set(['text-align', 'font-size'])\nconst DROP_WITH_CONTENT = new Set(['script', 'style', 'iframe', 'object', 'embed', 'noscript'])\n\nconst isSafeUrl = (value: string, allowDataImage: boolean) => {\n const url = Array.from(value)\n .filter((char) => char.charCodeAt(0) > 32)\n .join('')\n if (allowDataImage && /^data:image\\/(png|jpe?g|gif|webp|bmp);/i.test(url)) return true\n return /^(https?:|mailto:|tel:|\\/|#|\\.{1,2}\\/)/i.test(url) || !/^[a-z][a-z0-9+.-]*:/i.test(url)\n}\n\nconst cleanStyle = (value: string) =>\n value\n .split(';')\n .map((rule) => rule.split(':').map((part) => part.trim()))\n .filter(\n ([prop, val]) =>\n ALLOWED_STYLES.has(prop?.toLowerCase()) && val && /^[\\w\\s.%-]+$/.test(val),\n )\n .map(([prop, val]) => `${prop.toLowerCase()}: ${val}`)\n .join('; ')\n\nconst cleanNode = (node: Element) => {\n Array.from(node.children).forEach((child) => {\n const tag = child.tagName.toLowerCase()\n\n if (DROP_WITH_CONTENT.has(tag)) {\n child.remove()\n return\n }\n\n cleanNode(child)\n\n if (!ALLOWED_TAGS.has(tag)) {\n child.replaceWith(...Array.from(child.childNodes))\n return\n }\n\n const allowed = ALLOWED_ATTRS[tag] ?? []\n Array.from(child.attributes).forEach((attr) => {\n const name = attr.name.toLowerCase()\n if (name === 'style') {\n const style = cleanStyle(attr.value)\n if (style) child.setAttribute('style', style)\n else child.removeAttribute('style')\n } else if (name === 'class') {\n if (!allowed.includes('class') || !/^[\\w\\s-]+$/.test(attr.value)) {\n child.removeAttribute(attr.name)\n }\n } else if (!allowed.includes(name)) {\n child.removeAttribute(attr.name)\n } else if (\n (name === 'href' || name === 'src') &&\n !isSafeUrl(attr.value, tag === 'img')\n ) {\n child.removeAttribute(attr.name)\n }\n })\n\n if (tag === 'a' && child.getAttribute('target') === '_blank') {\n child.setAttribute('rel', 'noopener noreferrer')\n }\n })\n}\n\n/** HTML'i izin verilen etiket/özelliklerle sınırlar (script, on* olayları, javascript: vb. temizlenir). */\nexport function sanitizeHtml(html: string): string {\n if (!html) return ''\n const doc = new DOMParser().parseFromString(`<body>${html}</body>`, 'text/html')\n cleanNode(doc.body)\n return doc.body.innerHTML\n}\n"],"names":["ALLOWED_TAGS","ALLOWED_ATTRS","ALLOWED_STYLES","DROP_WITH_CONTENT","isSafeUrl","value","allowDataImage","url","char","cleanStyle","rule","part","prop","val","cleanNode","node","child","tag","allowed","attr","name","style","sanitizeHtml","html","doc"],"mappings":"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"}
@@ -30,6 +30,7 @@ export * from './MultiSelectWithCheckbox';
30
30
  export * from './Option';
31
31
  export * from './OptionWithIcon';
32
32
  export * from './RadioGroup';
33
+ export * from './RichTextEditor';
33
34
  export * from './ReadOnly';
34
35
  export * from './Select';
35
36
  export * from './SlideTabs';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,UAAU,CAAA;AACxB,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,OAAO,CAAA;AACrB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,UAAU,CAAA;AACxB,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,OAAO,CAAA;AACrB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA"}