@seliseblocks/mailcraft 0.1.0 → 0.2.0

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 (69) hide show
  1. package/DOCS.md +240 -12
  2. package/README.md +11 -3
  3. package/README.md.txt +134 -0
  4. package/dist/mailcraft-editor.bundle.js +51 -39
  5. package/dist/mailcraft-editor.bundle.js.map +3 -3
  6. package/examples/templates/order-confirmed.html +80 -80
  7. package/examples/vanilla.html +242 -23
  8. package/package.json +7 -2
  9. package/src/core/assets.js +10 -15
  10. package/src/core/binder.js +120 -118
  11. package/src/core/blocks.js +14 -1
  12. package/src/core/css-cascade.js +117 -117
  13. package/src/core/editor-core.js +1530 -1492
  14. package/src/core/export.js +142 -55
  15. package/src/core/i18n/ar.js +219 -177
  16. package/src/core/i18n/bg.js +196 -152
  17. package/src/core/i18n/bn.js +218 -176
  18. package/src/core/i18n/ca.js +196 -152
  19. package/src/core/i18n/cs.js +196 -152
  20. package/src/core/i18n/da.js +196 -152
  21. package/src/core/i18n/de-CH.js +196 -152
  22. package/src/core/i18n/de.js +196 -152
  23. package/src/core/i18n/dz.js +221 -179
  24. package/src/core/i18n/el.js +196 -152
  25. package/src/core/i18n/en.js +3 -10
  26. package/src/core/i18n/es.js +196 -152
  27. package/src/core/i18n/et.js +196 -152
  28. package/src/core/i18n/fi.js +196 -152
  29. package/src/core/i18n/fr.js +196 -152
  30. package/src/core/i18n/hr.js +196 -152
  31. package/src/core/i18n/hu.js +196 -152
  32. package/src/core/i18n/index.js +83 -83
  33. package/src/core/i18n/it.js +196 -152
  34. package/src/core/i18n/lt.js +196 -152
  35. package/src/core/i18n/lv.js +196 -152
  36. package/src/core/i18n/nb.js +196 -152
  37. package/src/core/i18n/nl.js +196 -152
  38. package/src/core/i18n/pl.js +196 -152
  39. package/src/core/i18n/pt.js +196 -152
  40. package/src/core/i18n/ro.js +196 -152
  41. package/src/core/i18n/ru.js +196 -152
  42. package/src/core/i18n/sk.js +196 -152
  43. package/src/core/i18n/sl.js +196 -152
  44. package/src/core/i18n/sv.js +196 -152
  45. package/src/core/i18n/tables.js +50 -50
  46. package/src/core/i18n/tr.js +196 -152
  47. package/src/core/i18n/uk.js +196 -152
  48. package/src/core/icons.js +237 -235
  49. package/src/core/ids.js +1 -1
  50. package/src/core/import-html.js +1025 -959
  51. package/src/core/layout-style.js +100 -100
  52. package/src/core/parse.js +10 -10
  53. package/src/core/placeholder.js +15 -15
  54. package/src/core/sanitize.js +141 -141
  55. package/src/core/storage-limits.js +184 -184
  56. package/src/core/storage.js +85 -85
  57. package/src/core/theme.js +1 -1
  58. package/src/core/variables.js +11 -11
  59. package/src/index.js +9 -9
  60. package/src/mailcraft-editor.js +26 -14
  61. package/src/render/block-body.js +49 -6
  62. package/src/render/canvas.js +31 -2
  63. package/src/render/fields.js +602 -588
  64. package/src/render/focus-preserve.js +158 -158
  65. package/src/render/rte.js +241 -212
  66. package/src/render/screenshot.js +132 -132
  67. package/src/render/story.js +415 -415
  68. package/src/render/style.js +8 -0
  69. package/types/index.d.ts +419 -0
@@ -1,152 +1,196 @@
1
- /** Hungarian (Magyar) — `hu`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
- export const HU = {
3
- 'action.undoHint': 'Visszavonás — ⌘Z',
4
- 'action.redoHint': 'Ismétlés — ⌘⇧Z',
5
- 'action.chromeToDark': 'Sötét',
6
- 'action.chromeToLight': 'Világos',
7
- 'action.chromeHint': 'Szerkesztő téma világos / sötét',
8
- 'action.aiCopy': 'Szöveg',
9
- 'action.aiCopyHint': 'Szöveg írása MI-vel',
10
- 'action.code': 'Kód',
11
- 'action.codeHint': 'Nyers HTML szerkesztése élő előnézettel',
12
- 'action.preview': 'Előnézet',
13
- 'action.export': 'Exportálás',
14
- 'device.desktop': 'Asztali',
15
- 'device.desktopHint': 'Asztali szélesség',
16
- 'device.mobile': 'Mobil',
17
- 'device.mobileHint': 'Mobil szélesség',
18
- 'device.dark': 'Sötét',
19
- 'device.darkHint': 'Sötét beérkezőlevelek mód',
20
- 'status.autosaveOn': 'automatikus mentés bekapcsolva',
21
- 'status.saved': 'mentve {time}',
22
- 'status.saveFailed': 'nem mentve — a tárhely megtelt',
23
- 'canvas.meta': '{rows} sor · {blocks} blokk · {width}px',
24
- 'tab.design': 'Stílus',
25
- 'tab.designHint': 'Kijelölés stílusa',
26
- 'tab.blocks': 'Blokkok',
27
- 'tab.blocksHint': 'Tartalomblokkok és változók',
28
- 'tab.rows': 'Szakaszok',
29
- 'tab.rowsHint': 'Szakaszelrendezések és a rajzvászon modellje',
30
- 'tab.files': 'Fájlok',
31
- 'tab.filesHint': 'Erőforrás-könyvtár',
32
- 'tab.layers': 'Struktúra',
33
- 'tab.layersHint': 'A dokumentum szerkezete',
34
- 'tab.theme': 'Téma',
35
- 'tab.themeHint': 'Globális stílusok',
36
- 'tab.data': 'Vált.',
37
- 'tab.dataHint': 'A kódod által biztosított változók',
38
- 'inspector.blockProperties': 'A blokk tulajdonságai',
39
- 'inspector.sectionProperties': 'A szakasz tulajdonságai',
40
- 'inspector.title': 'Vizsgáló',
41
- 'inspector.sectionLabel': 'Szakasz',
42
- 'inspector.nothingSelected': 'Nincs kijelölés',
43
- 'action.duplicateHint': 'Kettőzés — ⌘D',
44
- 'action.deleteHint': 'Törlés — ⌫',
45
- 'inspector.emptyBody':
46
- 'Válassz ki egy sort vagy blokkot a rajzvásznon, hogy itt formázhasd. Húzz blokkokat a <strong style="color: var(--ed-text); font-weight: 600;">Blokkok</strong> fülről; kattints duplán bármely szövegre a helyben szerkesztéshez.',
47
- 'inspector.shortcuts': 'Billentyűparancsok',
48
- 'shortcut.undoRedo': '⌘Z / ⌘⇧Z visszavonás, ismétlés',
49
- 'shortcut.duplicate': '⌘D — kijelölés kettőzése',
50
- 'shortcut.delete': 'kijelölés törlése',
51
- 'shortcut.export': '⌘EHTML exportálása',
52
- 'shortcut.escape': 'ESC — kijelölés megszüntetése, bezárás',
53
- 'blocks.dragHint': 'Húzd a rajzvászonra',
54
- 'blocks.count': '{count} blokk',
55
- 'rows.sectionLayouts': 'Szakaszelrendezések',
56
- 'rows.customMarkup': 'Egyéni kód',
57
- 'rows.htmlRowHint': 'Húzd be, vagy kattints a hozzáadáshoz — egy teljes szélességű sor, amelyet nyers HTML-lel töltesz meg',
58
- 'rows.rawHtmlSection': 'Nyers HTML szakasz',
59
- 'rows.rawHtmlDesc': 'Teljes szélességű szakasz, saját kódod, továbbra is húzható',
60
- 'rows.canvasModel': 'Rajzvászon modellje',
61
- 'rows.modeRowBased': 'Soralapú',
62
- 'rows.modeFreeStack': 'Szabad halmozás',
63
- 'rows.hintRows':
64
- 'Szakaszalapú: először helyezz el egy elrendezést, majd blokkokat az oszlopaiba — minden szakasznak saját háttere, kerete, flex vagy rács beállításai vannak.',
65
- 'rows.hintStack': 'Szabad halmozás: elrendezések nélkül — minden elhelyezett blokk saját teljes szélességű szakasszá válik, sorrendben egymásra halmozva.',
66
- 'files.libraryCount': 'Könyvtár{count} fájl',
67
- 'files.openManager': 'Fájlkezelő megnyitása',
68
- 'files.dragToCanvas': 'Húzz bármely fájlt közvetlenül a rajzvászonra, hogy képblokként helyezd el.',
69
- 'layers.structure': 'Struktúra',
70
- 'layers.sectionSingle': 'Szakasz',
71
- 'layers.sectionMulti': 'Szakasz · {count} oszlop',
72
- 'layers.blockCount': '{count} blokk',
73
- 'theme.globalStyles': 'Globális stílusok',
74
- 'vars.title': 'Változók',
75
- 'vars.fromCode': '{count} a kódodból',
76
- 'vars.declaredNote': 'Az alkalmazásod deklarálta — a rajzvászon mindig a tokent mutatja, sosem az értéket.',
77
- 'vars.filterPlaceholder': 'Változók szűrése…',
78
- 'vars.insertHint': 'Kattints a kijelölt szövegbe, címsorba vagy gombba való beszúráshoz',
79
- 'vars.insert': 'beszúrás',
80
- 'vars.noMatch': 'Egyetlen változó sem felel meg ennek a szűrőnek.',
81
- 'vars.noneDeclared': 'Az alkalmazásod még nem deklarált változókat.',
82
- 'vars.rteHint': 'Szöveg szerkesztése közben egy változót közvetlenül a beágyazott eszköztár legördülő menüjéből is kiválaszthatsz.',
83
- 'modal.fileManager': 'Fájlkezelő',
84
- 'modal.assetsTitle': 'Erőforrások',
85
- 'modal.replaceImage': 'Kép cseréje',
86
- 'library.searchPlaceholder': 'Fájlok keresése…',
87
- 'action.upload': 'Feltöltés',
88
- 'library.clickToPlace': 'Kattints egy fájlra az elhelyezéshez · vagy húzz egy fájlt a rajzvászonra',
89
- 'library.clickToReplace': 'Kattints egy fájlra a kijelölt kép cseréjéhez',
90
- 'library.storageLabel': '{count} fájl · {size}',
91
- 'library.folders': 'Mappák',
92
- 'library.dropHint': 'Húzz ide képfájlokat a feltöltéshez — vagy használd a Feltöltés gombot.',
93
- 'library.deleteFileHint': 'Fájl törlése',
94
- 'library.del': 'TÖRL',
95
- 'toast.assetDeleted': '{name} törölve',
96
- 'modal.export': 'Exportálás',
97
- 'modal.exportTitle': 'Táblázat alapú e-mail HTML',
98
- 'export.copy': 'Másolás',
99
- 'export.copied': 'Másolva',
100
- 'action.download': 'Letöltés',
101
- 'export.meta': '{kb} KB · táblázatok + soron belüli stílusok · Outlook-biztos szélességek',
102
- 'modal.rawHtmlTitle': 'Nyers HTML, élő előnézet',
103
- 'code.statusEdited': 'Kódnézet szerkesztve élő előnézet, még nincs alkalmazva',
104
- 'code.statusSynced': 'Kódnézet szinkronban a rajzvászonnal',
105
- 'action.reload': 'Újratöltés',
106
- 'action.reloadHint': 'Forrás újratöltése a rajzvászonról',
107
- 'action.applyToCanvas': 'Alkalmazás a rajzvászonra',
108
- 'action.applyToCanvasHint': 'A forrás visszaalakítása szerkeszthető sorokká',
109
- 'action.closeWithoutApplyingHint': 'Bezárás alkalmazás nélkül',
110
- 'code.source': 'Forrás',
111
- 'code.livePreview': 'Élő előnézet',
112
- 'code.liveHtmlPreviewTitle': 'Élő HTML előnézet',
113
- 'code.applyNote':
114
- 'Az alkalmazás minden legfelső szintű táblázatsort egy rajzvászon-sorrá alakít, amelyet továbbra is kijelölhetsz, átrendezhetsz és törölhetsz a kézzel írt kód sértetlenül éli túl a folyamatot.',
115
- 'code.meta': '{kb} KB · {lines} sor',
116
- 'toast.sourceReloaded': 'A forrás újratöltve a rajzvászonról',
117
- 'toast.sourceAppliedOne': 'Forrás alkalmazva — 1 sor a rajzvásznon',
118
- 'toast.sourceAppliedMany': 'Forrás alkalmazva — {rows} sor a rajzvásznon',
119
- 'toast.parseError': 'Nem sikerült elemezni ezt a HTML-t',
120
- 'modal.copyAssist': 'Szövegíró segéd',
121
- 'modal.draftCopyTitle': 'Szöveg írása ehhez a kampányhoz',
122
- 'ai.goal': 'Cél',
123
- 'ai.tone': 'Hangnem',
124
- 'ai.briefLabel': 'Miről szól ez az e-mail?',
125
- 'ai.briefPlaceholder': 'pl. Őszi kollekció, 15% kedvezmény feliratkozóknak, ingyenes szállítás 150 000 Ft felett',
126
- 'ai.generate': 'Szöveg generálása',
127
- 'ai.writing': 'Írás…',
128
- 'ai.kindHeadline': 'Címsor',
129
- 'ai.kindBody': 'Törzsszöveg',
130
- 'ai.kindButton': 'Gomb szövege',
131
- 'ai.actionInsertHeading': 'Beszúrás címsorként',
132
- 'ai.actionInsertText': 'Beszúrás szövegblokként',
133
- 'ai.actionInsertButton': 'Beszúrás gombként',
134
- 'toast.headingAdded': 'Címsor hozzáadva',
135
- 'toast.textBlockAdded': 'Szövegblokk hozzáadva',
136
- 'toast.buttonAdded': 'Gomb hozzáadva',
137
- 'preview.kickerMobile': 'Előnézetmobil 375px',
138
- 'preview.kickerDark': 'Előnézet sötét beérkezőlevelek',
139
- 'preview.kickerDesktop': 'Előnézet — asztali {width}px',
140
- 'action.close': 'Bezárás',
141
- 'toast.duplicated': 'Kettőzve',
142
- 'toast.fileUploadedOne': '1 fájl feltöltve',
143
- 'toast.fileUploadedMany': '{count} fájl feltöltve',
144
- 'toast.imageReplaced': 'Kép kicserélve',
145
- 'toast.imageAdded': 'Kép hozzáadva a rajzvászonhoz',
146
- 'toast.htmlCopied': 'HTML a vágólapra másolva',
147
- 'toast.templateLoaded': '{name} betöltve',
148
- 'toast.snippetDefaultLabel': 'Részlet',
149
- 'toast.snippetInserted': '{name} beszúrva',
150
- 'toast.snippetCopied': '{name} másolva — jelölj ki egy szövegblokkot a beszúráshoz',
151
- };
152
-
1
+ /** Hungarian (Magyar) — `hu`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
+ export const HU = {
3
+ 'action.undoHint': 'Visszavonás — ⌘Z',
4
+ 'action.redoHint': 'Ismétlés — ⌘⇧Z',
5
+ 'action.chromeToDark': 'Sötét',
6
+ 'action.chromeToLight': 'Világos',
7
+ 'action.chromeHint': 'Szerkesztő téma világos / sötét',
8
+ 'action.chromeHintToDark': 'Sötét mód',
9
+ 'action.chromeHintToLight': 'Világos mód',
10
+ 'action.aiDraft': 'Vázlat',
11
+ 'action.aiDraftHint': 'E-mail tartalmának megírása MI-vel',
12
+ 'action.code': 'Kód',
13
+ 'action.codeHint': 'Nyers HTML szerkesztése élő előnézettel',
14
+ 'action.preview': 'Előnézet',
15
+ 'action.previewHint': 'E-mail előnézete',
16
+ 'action.export': 'Exportálás',
17
+ 'action.exportHint': 'E-mail exportálása',
18
+ 'device.desktop': 'Asztali',
19
+ 'device.desktopHint': 'Asztali szélesség',
20
+ 'device.mobile': 'Mobil',
21
+ 'device.mobileHint': 'Mobil szélesség',
22
+ 'status.autosaveOn': 'automatikus mentés bekapcsolva',
23
+ 'status.saved': 'mentve {time}',
24
+ 'status.saveFailed': 'nem mentve — a tárhely megtelt',
25
+ 'canvas.meta': '{rows} sor · {blocks} blokk · {width}px',
26
+ 'tab.design': 'Stílus',
27
+ 'tab.designHint': 'Kijelölés stílusa',
28
+ 'tab.blocks': 'Blokkok',
29
+ 'tab.blocksHint': 'Tartalomblokkok és változók',
30
+ 'tab.rows': 'Szakaszok',
31
+ 'tab.rowsHint': 'Szakaszelrendezések és a rajzvászon modellje',
32
+ 'tab.files': 'Fájlok',
33
+ 'tab.filesHint': 'Erőforrás-könyvtár',
34
+ 'tab.layers': 'Struktúra',
35
+ 'tab.layersHint': 'A dokumentum szerkezete',
36
+ 'tab.settings': 'Beállítások',
37
+ 'tab.settingsHint': 'E-mail beállításai',
38
+ 'tab.data': 'Vált.',
39
+ 'tab.dataHint': 'A kódod által biztosított változók',
40
+ 'inspector.blockProperties': 'A blokk tulajdonságai',
41
+ 'inspector.sectionProperties': 'A szakasz tulajdonságai',
42
+ 'inspector.title': 'Vizsgáló',
43
+ 'inspector.sectionLabel': 'Szakasz',
44
+ 'inspector.nothingSelected': 'Nincs kijelölés',
45
+ 'action.duplicateHint': 'Kettőzés — ⌘D',
46
+ 'action.deleteHint': 'Törlés ',
47
+ 'inspector.emptyBody':
48
+ 'Válassz ki egy sort vagy blokkot a rajzvásznon, hogy itt formázhasd. Húzz blokkokat a <strong style="color: var(--ed-text); font-weight: 600;">Blokkok</strong> fülről; kattints duplán bármely szövegre a helyben szerkesztéshez.',
49
+ 'inspector.shortcuts': 'Billentyűparancsok',
50
+ 'shortcut.undoRedo': '⌘Z / ⌘⇧Z visszavonás, ismétlés',
51
+ 'shortcut.duplicate': '⌘Dkijelölés kettőzése',
52
+ 'shortcut.delete': ' — kijelölés törlése',
53
+ 'shortcut.export': '⌘E HTML exportálása',
54
+ 'shortcut.escape': 'ESC — kijelölés megszüntetése, bezárás',
55
+ 'blocks.dragHint': 'Húzd a rajzvászonra',
56
+ 'blocks.count': '{count} blokk',
57
+ 'rows.sectionLayouts': 'Szakaszelrendezések',
58
+ 'rows.customMarkup': 'Egyéni kód',
59
+ 'rows.htmlRowHint': 'Húzd be, vagy kattints a hozzáadáshoz — egy teljes szélességű sor, amelyet nyers HTML-lel töltesz meg',
60
+ 'rows.rawHtmlSection': 'Nyers HTML szakasz',
61
+ 'rows.rawHtmlDesc': 'Teljes szélességű szakasz, saját kódod, továbbra is húzható',
62
+ 'rows.canvasModel': 'Rajzvászon modellje',
63
+ 'rows.modeRowBased': 'Soralapú',
64
+ 'rows.modeFreeStack': 'Szabad halmozás',
65
+ 'rows.hintRows':
66
+ 'Szakaszalapú: először helyezz el egy elrendezést, majd blokkokat az oszlopaiba minden szakasznak saját háttere, kerete, flex vagy rács beállításai vannak.',
67
+ 'rows.hintStack': 'Szabad halmozás: elrendezések nélkül — minden elhelyezett blokk saját teljes szélességű szakasszá válik, sorrendben egymásra halmozva.',
68
+ 'files.libraryCount': 'Könyvtár {count} fájl',
69
+ 'files.openManager': 'Fájlkezelő megnyitása',
70
+ 'files.dragToCanvas': 'Húzz bármely fájlt közvetlenül a rajzvászonra, hogy képblokként helyezd el.',
71
+ 'layers.structure': 'Struktúra',
72
+ 'layers.sectionSingle': 'Szakasz',
73
+ 'layers.sectionMulti': 'Szakasz · {count} oszlop',
74
+ 'layers.column': '{index}. oszlop',
75
+ 'layers.blockCount': '{count} blokk',
76
+ 'vars.title': 'Változók',
77
+ 'vars.fromCode': '{count} a kódodból',
78
+ 'vars.declaredNote': 'Az alkalmazásod deklarálta — a rajzvászon mindig a tokent mutatja, sosem az értéket.',
79
+ 'vars.filterPlaceholder': 'Változók szűrése…',
80
+ 'vars.insertHint': 'Kattints a kijelölt szövegbe, címsorba vagy gombba való beszúráshoz',
81
+ 'vars.insert': 'beszúrás',
82
+ 'vars.noMatch': 'Egyetlen változó sem felel meg ennek a szűrőnek.',
83
+ 'vars.noneDeclared': 'Az alkalmazásod még nem deklarált változókat.',
84
+ 'vars.rteHint': 'Szöveg szerkesztése közben egy változót közvetlenül a beágyazott eszköztár legördülő menüjéből is kiválaszthatsz.',
85
+ 'modal.fileManager': 'Fájlkezelő',
86
+ 'modal.assetsTitle': 'Erőforrások',
87
+ 'modal.replaceImage': 'Kép cseréje',
88
+ 'library.searchPlaceholder': 'Fájlok keresése…',
89
+ 'action.upload': 'Feltöltés',
90
+ 'library.clickToPlace': 'Kattints egy fájlra az elhelyezéshez · vagy húzz egy fájlt a rajzvászonra',
91
+ 'library.clickToReplace': 'Kattints egy fájlra a kijelölt kép cseréjéhez',
92
+ 'library.storageLabel': '{count} fájl · {size}',
93
+ 'library.folders': 'Mappák',
94
+ 'library.dropHint': 'Húzz ide képfájlokat a feltöltéshez — vagy használd a Feltöltés gombot.',
95
+ 'library.deleteFileHint': 'Fájl törlése',
96
+ 'library.del': 'TÖRL',
97
+ 'toast.assetDeleted': '{name} törölve',
98
+ 'library.allFiles': 'Összes fájl',
99
+ 'library.loadMore': 'Továbbiak betöltése',
100
+ 'library.empty': 'Itt még nincsenek fájlok.',
101
+ 'storage.loading': 'Fájlok betöltése…',
102
+ 'storage.uploading': '{count} feltöltése…',
103
+ 'storage.errLoadFailed': 'A fájlkönyvtár nem tölthető be {reason}',
104
+ 'storage.errNoLimits': 'A feltöltés ki van kapcsolva: ez az alkalmazás nem állított be feltöltési korlátokat.',
105
+ 'storage.errNoAccept': 'A feltöltés ki van kapcsolva: nincs engedélyezett fájlformátum.',
106
+ 'storage.errNoMaxBytes': 'A feltöltés ki van kapcsolva: nincs beállítva maximális fájlméret.',
107
+ 'storage.errTooLarge': 'A(z) {name} mérete {size} — a korlát {max}.',
108
+ 'storage.errFormat': 'A(z) {name} egy {type} fájl, ami itt nem engedélyezett.',
109
+ 'storage.errSvg': 'A(z) {name} egy SVG, amit ez az alkalmazás nem fogad el.',
110
+ 'storage.errDimensions': 'A(z) {name} mérete {w}×{ht}px — a korlát {maxW}×{maxH}px.',
111
+ 'storage.errTooMany': 'Egyszerre csak {max} fájl tölthető fel.',
112
+ 'storage.errUnreadable': 'A(z) {name} nem olvasható kép.',
113
+ 'storage.errUploadFailed': 'A(z) {name} nem tölthető fel — {reason}',
114
+ 'storage.errDeleteFailed': 'A(z) {name} nem törölhető{reason}',
115
+ 'modal.export': 'Exportálás',
116
+ 'modal.exportTitle': 'Táblázat alapú e-mail HTML',
117
+ 'export.copy': 'Másolás',
118
+ 'export.copied': 'Másolva',
119
+ 'action.download': 'Letöltés',
120
+ 'export.meta': '{kb} KB · táblázatok + soron belüli stílusok · Outlook-biztos szélességek',
121
+ 'modal.rawHtmlTitle': 'Nyers HTML, élő előnézet',
122
+ 'code.statusEdited': 'Kódnézet — szerkesztve — élő előnézet, még nincs alkalmazva',
123
+ 'code.statusSynced': 'Kódnézet — szinkronban a rajzvászonnal',
124
+ 'action.reload': 'Újratöltés',
125
+ 'action.reloadHint': 'Forrás újratöltése a rajzvászonról',
126
+ 'action.applyToCanvas': 'Alkalmazás a rajzvászonra',
127
+ 'action.applyToCanvasHint': 'A forrás visszaalakítása szerkeszthető sorokká',
128
+ 'action.closeWithoutApplyingHint': 'Bezárás alkalmazás nélkül',
129
+ 'code.source': 'Forrás',
130
+ 'code.livePreview': 'Élő előnézet',
131
+ 'code.liveHtmlPreviewTitle': 'Élő HTML előnézet',
132
+ 'code.applyNote':
133
+ 'Az alkalmazás minden legfelső szintű táblázatsort egy rajzvászon-sorrá alakít, amelyet továbbra is kijelölhetsz, átrendezhetsz és törölhetsz — a kézzel írt kód sértetlenül éli túl a folyamatot.',
134
+ 'code.meta': '{kb} KB · {lines} sor',
135
+ 'toast.sourceReloaded': 'A forrás újratöltve a rajzvászonról',
136
+ 'toast.sourceAppliedOne': 'Forrás alkalmazva — 1 sor a rajzvásznon',
137
+ 'toast.sourceAppliedMany': 'Forrás alkalmazva {rows} sor a rajzvásznon',
138
+ 'toast.parseError': 'Nem sikerült elemezni ezt a HTML-t',
139
+ 'modal.aiDraft': 'MI írássegéd',
140
+ 'modal.aiDraftTitle': 'Írd meg az e-mailed MI-vel',
141
+ 'ai.disclosure': 'Az MI a rövid leírásod alapján készít javaslatokat. Küldés előtt nézd át és szerkeszd az eredményt.',
142
+ 'ai.goal': 'Cél',
143
+ 'ai.tone': 'Hangnem',
144
+ 'ai.briefLabel': 'Miről szól ez az e-mail?',
145
+ 'ai.briefPlaceholder': 'pl. Őszi kollekció, 15% kedvezmény feliratkozóknak, ingyenes szállítás 150 000 Ft felett',
146
+ 'ai.generate': 'Szöveg generálása',
147
+ 'ai.writing': 'Írás…',
148
+ 'ai.kindHeadline': 'Címsor',
149
+ 'ai.kindBody': 'Törzsszöveg',
150
+ 'ai.kindButton': 'Gomb szövege',
151
+ 'ai.actionInsertHeading': 'Beszúrás címsorként',
152
+ 'ai.actionInsertText': 'Beszúrás szövegblokként',
153
+ 'ai.actionInsertButton': 'Beszúrás gombként',
154
+ 'toast.headingAdded': 'Címsor hozzáadva',
155
+ 'toast.textBlockAdded': 'Szövegblokk hozzáadva',
156
+ 'toast.buttonAdded': 'Gomb hozzáadva',
157
+ 'preview.kickerMobile': 'Előnézet — mobil 375px',
158
+ 'preview.kickerDesktop': 'Előnézet — asztali {width}px',
159
+ 'action.close': 'Bezárás',
160
+ 'toast.duplicated': 'Kettőzve',
161
+ 'toast.fileUploadedOne': '1 fájl feltöltve',
162
+ 'toast.fileUploadedMany': '{count} fájl feltöltve',
163
+ 'toast.imageReplaced': 'Kép kicserélve',
164
+ 'toast.imageAdded': 'Kép hozzáadva a rajzvászonhoz',
165
+ 'toast.htmlCopied': 'HTML a vágólapra másolva',
166
+ 'toast.templateLoaded': '{name} betöltve',
167
+ 'toast.snippetDefaultLabel': 'Részlet',
168
+ 'toast.snippetInserted': '{name} beszúrva',
169
+ 'toast.snippetCopied': '{name} másolva — jelölj ki egy szövegblokkot a beszúráshoz',
170
+ 'rte.textStyle': 'Szövegstílus',
171
+ 'rte.mergeTags': 'Egyesítési mezők',
172
+ 'rte.noMergeTags': 'Nincs elérhető egyesítési mező',
173
+ 'rte.textColor': 'Szöveg színe',
174
+ 'rte.highlightColor': 'Kiemelés színe',
175
+ 'rte.removeHighlight': 'Kiemelés eltávolítása',
176
+ 'rte.clearFormatting': 'Formázás törlése',
177
+ 'action.downloadPng': 'PNG letöltése',
178
+ 'action.screenshot': 'Képernyőkép',
179
+ 'action.screenshotHint': 'A teljes sablon megtekintése képként, majd letöltése',
180
+ 'toast.pngSaved': 'Képernyőkép letöltve',
181
+ 'toast.pngFailed': 'A képernyőkép nem sikerült — egy külső képet nem sikerült betölteni',
182
+ 'toast.pngCopied': 'Képernyőkép a vágólapra másolva',
183
+ 'toast.pngCopyFailed': 'Ez a böngésző nem fogadott el képet a vágólapon',
184
+ 'story.kicker': 'Képernyőkép',
185
+ 'story.rendering': 'A képernyőkép készül',
186
+ 'story.renderingHint': 'Minden blokk 2×-es méretben rajzolódik — hosszú sablonnál ez eltart egy pillanatig.',
187
+ 'story.failed': 'A képernyőkép nem sikerült',
188
+ 'story.failedHint': 'A sablon egyik képét nem sikerült betölteni a rögzítéshez.',
189
+ 'story.retry': 'Próbáld újra',
190
+ 'story.play': 'Lejátszás',
191
+ 'story.pause': 'Szünet',
192
+ 'story.replay': 'Újrajátszás',
193
+ 'story.copy': 'Másolás',
194
+ 'story.meta': '{w}×{h} · {i}/{n} képernyő',
195
+ 'footer.poweredBy': 'Működteti a SELISE Blocks © 2026',
196
+ };
@@ -1,83 +1,83 @@
1
- import { EN as ENBase } from './en.js';
2
-
3
- /**
4
- * Builds a translator. `overrides` is whatever a host passes as `.messages`
5
- * on the element -- a host's own table, an imported locale, or both merged
6
- * via `defineMessages` below.
7
- *
8
- * Three deliberate properties:
9
- * 1. English always resolves. A locale is an overlay, never a replacement,
10
- * so a partial or missing translation shows English rather than a gap.
11
- * 2. Params interpolate `{name}`.
12
- * 3. A truly missing key (not in `overrides`, not in `EN`) renders as the
13
- * key itself, not an empty string -- a visible `toast.deleted` in the UI
14
- * is obviously wrong and names the exact key to add, where blank text
15
- * just looks like a broken build.
16
- */
17
- export function createTranslator(overrides) {
18
- const table = overrides || {};
19
- return function t(key, params) {
20
- const template = table[key] ?? ENBase[key] ?? key;
21
- if (!params) return template;
22
- return template.replace(/\{(\w+)\}/g, (whole, name) => (name in params ? String(params[name]) : whole));
23
- };
24
- }
25
-
26
- /** Merges a locale over a base, for a host assembling its own table -- the documented way to combine a shipped locale with a few product-specific overrides. */
27
- export function defineMessages(base, overrides) {
28
- return Object.assign({}, base, overrides);
29
- }
30
-
31
- /** Keys in `base` that `locale` does not translate. What a translator has left to do. */
32
- export function missingKeys(locale, base) {
33
- const source = base || ENBase;
34
- return Object.keys(source).filter((key) => locale[key] === undefined).sort();
35
- }
36
-
37
- /**
38
- * Every locale that ships, for a host building a language switcher.
39
- * Metadata only -- no message tables -- so listing the locales never pulls
40
- * every translation file into a consumer's bundle; a host deep-imports the
41
- * one it wants, e.g. `mailcraft-editor/src/core/i18n/bn.js`.
42
- */
43
- export const LOCALES = [
44
- { tag: 'en', name: 'English' },
45
- { tag: 'ar', name: 'Arabic', rtl: true },
46
- { tag: 'bn', name: 'Bangla' },
47
- { tag: 'dz', name: 'Dzongkha' },
48
- { tag: 'bg', name: 'Bulgarian' },
49
- { tag: 'ca', name: 'Catalan' },
50
- { tag: 'cs', name: 'Czech' },
51
- { tag: 'da', name: 'Danish' },
52
- { tag: 'de', name: 'German' },
53
- { tag: 'de-CH', name: 'Swiss German' },
54
- { tag: 'el', name: 'Greek' },
55
- { tag: 'es', name: 'Spanish' },
56
- { tag: 'et', name: 'Estonian' },
57
- { tag: 'fi', name: 'Finnish' },
58
- { tag: 'fr', name: 'French' },
59
- { tag: 'hr', name: 'Croatian' },
60
- { tag: 'hu', name: 'Hungarian' },
61
- { tag: 'it', name: 'Italian' },
62
- { tag: 'lt', name: 'Lithuanian' },
63
- { tag: 'lv', name: 'Latvian' },
64
- { tag: 'nb', name: 'Norwegian Bokmål' },
65
- { tag: 'nl', name: 'Dutch' },
66
- { tag: 'pl', name: 'Polish' },
67
- { tag: 'pt', name: 'Portuguese' },
68
- { tag: 'ro', name: 'Romanian' },
69
- { tag: 'ru', name: 'Russian' },
70
- { tag: 'sk', name: 'Slovak' },
71
- { tag: 'sl', name: 'Slovenian' },
72
- { tag: 'sv', name: 'Swedish' },
73
- { tag: 'tr', name: 'Turkish' },
74
- { tag: 'uk', name: 'Ukrainian' },
75
- ];
76
-
77
- /** `true` when the tag is written right to left. Metadata only -- `dir` is still what actually flips the layout. */
78
- export function isRtl(tag) {
79
- const entry = LOCALES.find((l) => l.tag === tag);
80
- return entry ? entry.rtl === true : false;
81
- }
82
-
83
- export { EN, MESSAGE_KEYS } from './en.js';
1
+ import { EN as ENBase } from './en.js';
2
+
3
+ /**
4
+ * Builds a translator. `overrides` is whatever a host passes as `.messages`
5
+ * on the element -- a host's own table, an imported locale, or both merged
6
+ * via `defineMessages` below.
7
+ *
8
+ * Three deliberate properties:
9
+ * 1. English always resolves. A locale is an overlay, never a replacement,
10
+ * so a partial or missing translation shows English rather than a gap.
11
+ * 2. Params interpolate `{name}`.
12
+ * 3. A truly missing key (not in `overrides`, not in `EN`) renders as the
13
+ * key itself, not an empty string -- a visible `toast.deleted` in the UI
14
+ * is obviously wrong and names the exact key to add, where blank text
15
+ * just looks like a broken build.
16
+ */
17
+ export function createTranslator(overrides) {
18
+ const table = overrides || {};
19
+ return function t(key, params) {
20
+ const template = table[key] ?? ENBase[key] ?? key;
21
+ if (!params) return template;
22
+ return template.replace(/\{(\w+)\}/g, (whole, name) => (name in params ? String(params[name]) : whole));
23
+ };
24
+ }
25
+
26
+ /** Merges a locale over a base, for a host assembling its own table -- the documented way to combine a shipped locale with a few product-specific overrides. */
27
+ export function defineMessages(base, overrides) {
28
+ return Object.assign({}, base, overrides);
29
+ }
30
+
31
+ /** Keys in `base` that `locale` does not translate. What a translator has left to do. */
32
+ export function missingKeys(locale, base) {
33
+ const source = base || ENBase;
34
+ return Object.keys(source).filter((key) => locale[key] === undefined).sort();
35
+ }
36
+
37
+ /**
38
+ * Every locale that ships, for a host building a language switcher.
39
+ * Metadata only -- no message tables -- so listing the locales never pulls
40
+ * every translation file into a consumer's bundle; a host deep-imports the
41
+ * one it wants, e.g. `mailcraft-editor/src/core/i18n/bn.js`.
42
+ */
43
+ export const LOCALES = [
44
+ { tag: 'en', name: 'English' },
45
+ { tag: 'ar', name: 'Arabic', rtl: true },
46
+ { tag: 'bn', name: 'Bangla' },
47
+ { tag: 'dz', name: 'Dzongkha' },
48
+ { tag: 'bg', name: 'Bulgarian' },
49
+ { tag: 'ca', name: 'Catalan' },
50
+ { tag: 'cs', name: 'Czech' },
51
+ { tag: 'da', name: 'Danish' },
52
+ { tag: 'de', name: 'German' },
53
+ { tag: 'de-CH', name: 'Swiss German' },
54
+ { tag: 'el', name: 'Greek' },
55
+ { tag: 'es', name: 'Spanish' },
56
+ { tag: 'et', name: 'Estonian' },
57
+ { tag: 'fi', name: 'Finnish' },
58
+ { tag: 'fr', name: 'French' },
59
+ { tag: 'hr', name: 'Croatian' },
60
+ { tag: 'hu', name: 'Hungarian' },
61
+ { tag: 'it', name: 'Italian' },
62
+ { tag: 'lt', name: 'Lithuanian' },
63
+ { tag: 'lv', name: 'Latvian' },
64
+ { tag: 'nb', name: 'Norwegian Bokmål' },
65
+ { tag: 'nl', name: 'Dutch' },
66
+ { tag: 'pl', name: 'Polish' },
67
+ { tag: 'pt', name: 'Portuguese' },
68
+ { tag: 'ro', name: 'Romanian' },
69
+ { tag: 'ru', name: 'Russian' },
70
+ { tag: 'sk', name: 'Slovak' },
71
+ { tag: 'sl', name: 'Slovenian' },
72
+ { tag: 'sv', name: 'Swedish' },
73
+ { tag: 'tr', name: 'Turkish' },
74
+ { tag: 'uk', name: 'Ukrainian' },
75
+ ];
76
+
77
+ /** `true` when the tag is written right to left. Metadata only -- `dir` is still what actually flips the layout. */
78
+ export function isRtl(tag) {
79
+ const entry = LOCALES.find((l) => l.tag === tag);
80
+ return entry ? entry.rtl === true : false;
81
+ }
82
+
83
+ export { EN, MESSAGE_KEYS } from './en.js';