@aquera/nile-elements 0.1.67-beta-1.4 → 0.1.67-beta-1.5

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.
@@ -1,158 +1,65 @@
1
1
  import{css as e}from"lit";const r=e`
2
- /* ---- SAFER RESET INSIDE THE EDITOR -------------------------------------- */
3
- .editor * {
4
- all: revert; /* keep your reset… */
5
- box-sizing: border-box; /* …but preserve sane layout */
6
- overflow-wrap: anywhere; /* break long words/URLs */
7
- word-break: break-word;
2
+ .editor * {
3
+ all: revert;
8
4
  }
9
5
 
10
- /* Let component & editor shrink inside flex/grid parents */
11
- nile-rich-text-editor,
12
- .editor {
13
- display: block;
14
- min-width: 0;
15
- max-width: 100%;
16
- font-family: inherit;
17
- }
18
-
19
- /* ---- TOOLBAR ------------------------------------------------------------- */
20
- nile-rte-toolbar,
21
- .toolbar {
22
- display: flex;
23
- flex-wrap: wrap; /* allow wrapping to next row */
24
- align-items: center;
25
- gap: 8px;
26
- padding: 8px;
27
- border: 1px solid #e5e7eb;
28
- border-bottom: none;
29
- border-radius: 8px 8px 0 0;
30
- background: #fff;
31
- box-sizing: border-box;
32
- width: 100%;
33
- }
34
-
35
- /* allow children to shrink instead of forcing overflow */
36
- nile-rte-toolbar > *,
37
- .toolbar > * {
38
- flex: 0 1 auto;
39
- min-width: 0;
40
- }
6
+ nile-rich-text-editor { position: relative; display: block; font-family: inherit; }
41
7
 
42
- /* buttons */
8
+
43
9
  nile-rte-toolbar-item > nile-button::part(base) {
44
- width: 32px;
45
- height: 32px;
46
- padding: 0 6px;
10
+
11
+ width:32px; height:32px; padding:0px 6px;
47
12
  border: none;
48
13
  }
49
-
50
- nile-rte-toolbar-item > button,
51
- .toolbar button,
52
- nile-rte-toolbar button {
53
- border: 1px solid #e5e7eb;
54
- background: #fff;
55
- border-radius: 6px;
56
- cursor: pointer;
57
- }
58
-
59
- nile-rte-toolbar-item > button nile-icon { pointer-events: none; }
60
-
61
- nile-rte-toolbar-item > button.active {
62
- border-color: #2563eb;
63
- background: #eff6ff;
64
- }
65
-
66
- /* selects should be able to shrink on small screens */
67
- nile-rte-select select {
68
- height: 32px;
69
- border: 1px solid #e5e7eb;
70
- border-radius: 6px;
71
- background: #fff;
72
- min-width: 0;
73
- max-width: 100%;
74
- }
75
-
76
- /* color input */
77
- nile-rte-color input[type="color"] {
78
- height: 32px;
79
- width: 36px;
80
- border: 1px solid #e5e7eb;
81
- padding: 0;
82
- border-radius: 6px;
83
- background: #fff;
84
- }
85
-
86
- nile-rte-divider {
87
- width: 1px;
88
- height: 20px;
89
- background: #e5e7eb;
90
- display: inline-block;
91
- margin: 0 4px;
92
- }
93
-
94
- /* ---- EDITOR AREA --------------------------------------------------------- */
95
- .editor {
96
- min-height: 160px;
97
- padding: 12px;
98
- border: 1px solid #e5e7eb;
99
- border-radius: 0 0 8px 8px;
100
- background: #fff;
101
- outline: none;
102
- white-space: pre-wrap;
103
- tab-size: 4;
104
- -moz-tab-size: 4;
105
- overflow-wrap: anywhere;
106
- box-sizing: border-box;
107
- width: 100%;
108
- }
109
-
110
14
 
111
- .editor p { margin: 1em 0; }
112
- .editor h1, .editor h2, .editor h3, .editor h4, .editor h5, .editor h6 {
113
- margin-left: 0;
114
- margin-right: 0;
115
- font-weight: bold;
116
- }
117
- .editor h1 { font-size: 2em; margin: 0.67em 0; }
118
- .editor h2 { font-size: 1.5em; margin: 0.83em 0; }
119
- .editor h3 { font-size: 1.17em; margin: 1em 0; }
120
- .editor h4 { font-size: 1em; margin: 1.33em 0; }
121
- .editor h5 { font-size: 0.83em; margin: 1.67em 0; }
122
- .editor h6 { font-size: 0.67em; margin: 2.33em 0; }
123
-
124
- /* Keep typical wide content inside the box */
125
- .editor img,
126
- .editor svg,
127
- .editor table,
128
- .editor pre,
129
- .editor code,
130
- .editor blockquote {
131
- max-width: 100%;
132
- box-sizing: border-box;
133
- }
134
-
135
- /* Make <pre> wrap on small screens */
136
- .editor pre {
137
- white-space: pre-wrap;
138
- word-break: break-word;
139
- }
140
-
141
- /* Long links shouldn’t push layout */
142
- .editor a { word-break: break-all; }
15
+
143
16
 
144
- /* ---- PREVIEW ------------------------------------------------------------- */
145
- nile-rte-preview {
146
- display: block;
147
- margin-top: 10px;
148
- padding: 10px;
149
- border: 1px dashed #cbd5e1;
150
- border-radius: 8px;
151
- background: #fafafa;
152
- }
153
17
 
154
- /* ---- COLOR TRIGGER (unchanged) ------------------------------------------ */
155
- .rte-color-trigger {
18
+ .toolbar, nile-rte-toolbar {
19
+ display:flex; align-items:center; gap:8px; padding:8px;
20
+ border:1px solid #e5e7eb; border-bottom:none; border-radius:8px 8px 0 0; background:#fff;
21
+ }
22
+
23
+ nile-rte-toolbar-item > button, .toolbar button, nile-rte-toolbar button {
24
+ border:1px solid #e5e7eb; background:#fff; border-radius:6px;
25
+ cursor:pointer;
26
+ }
27
+
28
+
29
+ /* Ensure clicks hit the button (not nested icon internals) */
30
+ nile-rte-toolbar-item > button nile-icon { pointer-events:none; }
31
+
32
+ nile-rte-toolbar-item > button.active { border-color:#2563eb; background:#eff6ff; }
33
+ nile-rte-select select { height:32px; border:1px solid #e5e7eb; border-radius:6px; background:#fff; }
34
+ nile-rte-color input[type="color"] { height:32px; width:36px; border:1px solid #e5e7eb; padding:0; border-radius:6px; background:#fff; }
35
+ nile-rte-divider { width:1px; height:20px; background:#e5e7eb; display:inline-block; margin:0 4px; }
36
+
37
+ .editor p { margin:1em 0; }
38
+ .editor h1 { font-size:2em, all: revert; display: block;
39
+ font-size: 2em;
40
+ margin-top: 0.67em;
41
+ margin-bottom: 0.67em;
42
+ margin-left: 0;
43
+ margin-right: 0;
44
+ font-weight: bold; }
45
+ .editor h2 { all: revert; display: block;
46
+ font-size: 1.5em;
47
+ margin-top: 0.83em;
48
+ margin-bottom: 0.83em;
49
+ margin-left: 0;
50
+ margin-right: 0;
51
+ font-weight: bold;}
52
+ .editor h3 { font-size:1.17em }
53
+ .editor h4 { font-size:1em }
54
+ .editor h5 { font-size:0.83em }
55
+ .editor h6 { font-size:0.67em }
56
+
57
+ .editor { min-height:160px; padding:12px; border:1px solid #e5e7eb; border-radius:0 0 8px 8px; background:#fff; outline:none; white-space: pre-wrap;
58
+ tab-size: 4;
59
+ -moz-tab-size: 4; }
60
+ nile-rte-preview { display:block; margin-top:10px; padding:10px; border:1px dashed #cbd5e1; border-radius:8px; background:#fafafa; }
61
+
62
+ .rte-color-trigger {
156
63
  display: inline-flex;
157
64
  align-items: center;
158
65
  justify-content: center;
@@ -163,49 +70,35 @@ nile-rte-preview {
163
70
  background: #fff;
164
71
  cursor: pointer;
165
72
  }
73
+
166
74
  .rte-color-trigger .glyph-stack {
167
- display: grid;
168
- grid-auto-rows: max-content;
75
+ display: grid; /* stack vertically */
76
+ grid-auto-rows: max-content;
169
77
  align-items: center;
170
78
  justify-items: center;
171
79
  line-height: 1;
172
80
  }
81
+
173
82
  .rte-color-trigger .glyph {
174
83
  font-size: 14px;
175
84
  line-height: 1;
176
- margin-bottom: 2px;
85
+ margin-bottom: 2px; /* little breathing space above underline */
177
86
  }
87
+
178
88
  .rte-color-trigger .underline {
179
89
  width: 18px;
180
90
  height: 3px;
181
91
  border-radius: 2px;
182
- background: currentColor;
92
+ background: currentColor; /* we override via JS with backgroundColor */
183
93
  }
94
+
95
+ /* (unchanged) highlight square */
184
96
  .rte-color-trigger .swatch-box {
185
97
  width: 18px;
186
98
  height: 16px;
187
99
  border-radius: 4px;
188
100
  border: 1px solid rgba(0,0,0,0.35);
189
- background: currentColor;
190
- }
191
-
192
- /* ---- RESPONSIVE TWEAKS --------------------------------------------------- */
193
- @media (max-width: 900px) {
194
- nile-rte-toolbar { gap: 6px; padding: 6px; }
195
- nile-rte-select select { max-width: 160px; }
196
- }
197
-
198
- @media (max-width: 600px) {
199
- nile-rte-toolbar { gap: 4px; }
200
- nile-rte-select select { max-width: 120px; }
201
- /* optional fallback if wrapping still feels tight */
202
- /* nile-rte-toolbar { overflow-x: auto; } */
101
+ background: currentColor; /* overridden via JS */
203
102
  }
204
103
 
205
- @media (max-width: 420px) {
206
- nile-rte-select select { max-width: 100px; }
207
- nile-rte-divider { display: none; }
208
- }
209
-
210
-
211
104
  `;export{r as s};
@@ -1 +1 @@
1
- import{__decorate as t}from"tslib";import{LitElement as i}from"lit";import{property as s,state as e,customElement as n}from"lit/decorators.js";import"./nile-rte-toolbar.esm.js";import"./nile-rte-toolbar-item.esm.js";import"./nile-rte-select.esm.js";import"./nile-rte-color.esm.js";import"./nile-rte-divider.esm.js";import"./nile-rte-preview.esm.js";import"./nile-rte-mentions.esm.js";import{s as o,a as r,b as h,c as l,d as c,i as a,t as u,n as d,e as f,r as m}from"./utils.esm.js";import{s as p}from"./nile-rich-text-editor.css.esm.js";const b={bold:"format_bold",italic:"format_italic",underline:"format_underline",link:"link_2",left:"format_align_left",center:"format_align_middle",right:"format_align_right",justify:"format_align_justify",ul:"nile-ul",ol:"nile-ol",clear:"error"};let g=class extends i{constructor(){super(...arguments),this.value="",this.mentions={},this.content="",this.previewEl=null,this.toolbarEl=null,this.lastRange=null,this.buttonMap=new Map,this.headingSelect=null,this.fontSelect=null,this.colorInput=null,this.bgColorInput=null,this.colorSwatchEl=null,this.bgSwatchEl=null,this.mentionsEl=null,this.onPaste=t=>{const i=t.clipboardData?.getData("text/html");if(!i)return;t.preventDefault(),this.focusAndRestore();const s=document.createElement("div");s.innerHTML=i;const e=document.createTreeWalker(s,NodeFilter.SHOW_ELEMENT),n=new Set(["width","height","max-width","min-width","margin","padding","position","left","right","top","bottom","float","display","border","line-height","white-space"]);for(;e.nextNode();){const t=e.currentNode;if(t.removeAttribute("width"),t.removeAttribute("height"),t.hasAttribute("style")){const i=(t.getAttribute("style")||"").split(";").map((t=>t.trim())).filter(Boolean).filter((t=>{const i=t.split(":")[0]?.trim().toLowerCase();return i&&!n.has(i)}));i.length?t.setAttribute("style",i.join("; ")):t.removeAttribute("style")}}const o=window.getSelection();if(o&&o.rangeCount){const t=o.getRangeAt(0);t.deleteContents();const i=document.createDocumentFragment();for(;s.firstChild;)i.appendChild(s.firstChild);t.insertNode(i),o.removeAllRanges(),o.addRange(t)}this.ensureAtLeastOneParagraph(),this.updateContent(),this.updateToolbarState()},this.onEditorKeydown=t=>{if("Tab"!==t.key)return;t.preventDefault(),this.focusAndRestore();const i=window.getSelection();if(!i||0===i.rangeCount)return;const s=i.getRangeAt(0);if(t.shiftKey){if(s.collapsed&&s.startContainer.nodeType===Node.TEXT_NODE){const t=s.startContainer,e=s.startOffset,n=t.data.slice(0,e),o=n.replace(/(\t|[ \u00a0]{2})$/,"");if(o.length!==n.length){t.data=o+t.data.slice(e);const s=document.createRange();s.setStart(t,o.length),s.collapse(!0),i.removeAllRanges(),i.addRange(s),this.updateContent(),this.updateToolbarState()}}return}s.deleteContents();const e=document.createTextNode("\t");s.insertNode(e);const n=document.createRange();n.setStartAfter(e),n.collapse(!0),i.removeAllRanges(),i.addRange(n),this.updateContent(),this.updateToolbarState()},this.onSelectionChange=()=>{if(!this.editorEl)return;const t=document.getSelection();if(!t||0===t.rangeCount)return;const i=t.getRangeAt(0);this.editorEl.contains(i.commonAncestorContainer)&&(this.lastRange=i.cloneRange(),this.updateToolbarState())}}createRenderRoot(){return this}shouldUpdate(){return!1}injectCss(t){if(this.querySelector("style[data-rte-style]"))return;const i=document.createElement("style");i.setAttribute("data-rte-style","true"),i.textContent=t,this.insertBefore(i,this.firstChild)}connectedCallback(){super.connectedCallback(),this.injectCss(p.cssText),this.toolbarEl=this.querySelector("nile-rte-toolbar"),this.previewEl=this.querySelector("nile-rte-preview"),this.ensureEditor(),this.value&&!this.editorEl.innerHTML.trim()&&(this.editorEl.innerHTML=this.value),this.content=this.editorEl.innerHTML,this.toolbarEl&&this.wireAuthoredToolbar(this.toolbarEl),this.mentionsEl=this.querySelector("nile-rte-mentions"),this.mentionsEl&&(this.mentionsEl.attach?.(this.editorEl,this),this.mentionsEl.setExternalConfig?.(this.mentions)),this.wireEditor(),this.updateToolbarState(),this.syncPreview(),document.addEventListener("selectionchange",this.onSelectionChange,!0)}disconnectedCallback(){document.removeEventListener("selectionchange",this.onSelectionChange,!0),this.mentionsEl&&this.mentionsEl.detach&&this.mentionsEl.detach(),super.disconnectedCallback()}ensureEditor(){if(this.editorEl=this.querySelector(".editor"),!this.editorEl){const t=document.createElement("article");t.className="editor",t.setAttribute("contenteditable","true"),this.toolbarEl?.nextSibling?this.insertBefore(t,this.toolbarEl.nextSibling):this.previewEl?this.insertBefore(t,this.previewEl):this.appendChild(t),this.editorEl=t}this.editorEl.innerHTML.trim()||(this.editorEl.innerHTML="<p><br></p>"),this.ensureAtLeastOneParagraph()}wireEditor(){this.editorEl.addEventListener("input",(()=>{this.ensureAtLeastOneParagraph(),this.updateContent()})),this.editorEl.addEventListener("mouseup",(()=>this.saveSelection())),this.editorEl.addEventListener("keyup",(()=>this.saveSelection())),this.editorEl.addEventListener("keydown",this.onEditorKeydown),this.editorEl.addEventListener("paste",this.onPaste)}wireAuthoredToolbar(t){this.buttonMap.clear(),this.headingSelect=null,this.fontSelect=null,this.colorInput=null,Array.from(t.children).forEach((t=>{const i=t.tagName.toLowerCase();if("nile-rte-select"!==i||"align"!==t.getAttribute("type")){if("nile-rte-toolbar-item"===i){let i=t.querySelector(":scope > nile-button");const s=t.getAttribute("name")||"",e=t.getAttribute("label")||s,n=t.getAttribute("icon"),o=t.innerHTML.trim().length>0;if(i||(i=document.createElement("nile-button"),i.variant="tertiary",i.size="small"),n)i.innerHTML=`<nile-icon name="${n}" aria-label="${e}"></nile-icon>`,t.innerHTML="";else if(o)i.innerHTML=t.innerHTML,t.innerHTML="";else{const n=b[s];n?i.innerHTML=`<nile-icon name="${n}" size="20" color="black" aria-label="${e}"></nile-icon>`:i.textContent=e||s,t.innerHTML=""}i.isConnected||t.appendChild(i),i.setAttribute("aria-label",e),i.addEventListener("mousedown",(t=>t.preventDefault())),i.addEventListener("click",(()=>this.onToolbarCommand(s)));const r=this.buttonMap.get(s)??[];return r.push(i),void this.buttonMap.set(s,r)}if("nile-rte-select"!==i){if("nile-rte-color"===i){const i=t.getAttribute("label")??"Text color",s=t.getAttribute("value")??"#000000",e=t.getAttribute("mode")??"text";let n=t.querySelector(':scope > input[type="color"]');n||(n=document.createElement("input"),n.type="color",n.style.position="absolute",n.style.opacity="0",n.style.pointerEvents="none",t.appendChild(n)),n.title=i,n.value=s;let o=t.querySelector(":scope > button.rte-color-trigger");o||(o=document.createElement("button"),o.type="button",o.className="rte-color-trigger",o.setAttribute("aria-label",i),o.innerHTML="background"===e?'\n <span class="swatch-box" aria-hidden="true"></span>\n ':'\n <span class="glyph-stack" aria-hidden="true">\n <span class="glyph">A</span>\n <span class="underline"></span>\n </span>\n ',t.appendChild(o));const r=o.querySelector(".underline"),h=o.querySelector(".swatch-box");"background"===e?(this.bgColorInput=n,this.bgSwatchEl=h,this.bgSwatchEl&&(this.bgSwatchEl.style.backgroundColor=n.value)):(this.colorInput=n,this.colorSwatchEl=r,this.colorSwatchEl&&(this.colorSwatchEl.style.backgroundColor=n.value)),o.addEventListener("click",(t=>{t.preventDefault(),this.focusAndRestore(),n.click()})),n.addEventListener("input",(()=>{this.focusAndRestore(),"background"===e?(l(this.editorEl,n.value),this.bgSwatchEl&&(this.bgSwatchEl.style.backgroundColor=n.value)):(c(this.editorEl,n.value),this.colorSwatchEl&&(this.colorSwatchEl.style.backgroundColor=n.value)),this.updateContent(),this.updateToolbarState()})),o.addEventListener("mousedown",(t=>t.preventDefault())),n.addEventListener("mousedown",(t=>t.preventDefault()))}}else{const i=t.getAttribute("type")||"";t.addEventListener("change",(t=>{this.focusAndRestore();const s=t.detail;"heading"===i?r(this.editorEl,s):"font"===i&&h(this.editorEl,s),this.updateContent(),this.updateToolbarState()}))}}else t.addEventListener("change",(t=>{this.focusAndRestore();const i=t.detail;o(this.editorEl,i),this.updateContent(),this.updateToolbarState()}))}))}saveSelection(){const t=window.getSelection();t&&t.rangeCount&&(this.lastRange=t.getRangeAt(0).cloneRange())}restoreSelection(){if(!this.lastRange)return;const t=document.getSelection();t&&(t.removeAllRanges(),t.addRange(this.lastRange))}focusAndRestore(){this.editorEl?.focus(),this.restoreSelection()}insertList(t){if(this.restoreSelection(),!this.lastRange)return;const i=document.createElement(t),s=this.lastRange.extractContents(),e=document.createElement("div");e.appendChild(s),Array.from(e.childNodes).forEach((t=>{if(t.nodeType===Node.TEXT_NODE&&!t.textContent?.trim())return;const s=document.createElement("li");s.appendChild(t),i.appendChild(s)})),this.lastRange.insertNode(i),this.afterListEdit(i)}afterListEdit(t){const i=document.createRange();i.setStartAfter(t),i.collapse(!0);const s=window.getSelection();s?.removeAllRanges(),s?.addRange(i),this.saveSelection(),this.updateContent(),this.updateToolbarState()}ensureAtLeastOneParagraph(){const t=this.editorEl;if(!t)return;const i=""===(t.textContent??"").replace(/\u200B/g,"").trim();if(0===t.childNodes.length||i)return void(t.innerHTML="<p><br></p>");if(!t.querySelector("p,h1,h2,h3,h4,h5,h6,ul,ol,table,blockquote,pre")){const i=document.createElement("p");for(;t.firstChild;)i.appendChild(t.firstChild);return i.hasChildNodes()||i.appendChild(document.createElement("br")),void t.appendChild(i)}t.querySelectorAll("p").forEach((t=>{""===(t.textContent??"").replace(/\u200B/g,"")&&(t.innerHTML.toLowerCase().includes("<br")||(t.innerHTML="<br>"))}))}onToolbarCommand(t){switch(this.focusAndRestore(),t){case"bold":u(this.editorEl,"strong");break;case"italic":u(this.editorEl,"em");break;case"underline":u(this.editorEl,"u");break;case"left":o(this.editorEl,"left");break;case"center":o(this.editorEl,"center");break;case"right":o(this.editorEl,"right");break;case"justify":o(this.editorEl,"justify");break;case"ul":this.insertList("ul");break;case"ol":this.insertList("ol");break;case"link":a(this.editorEl);break;case"clear":const t=document.createTreeWalker(this.editorEl,NodeFilter.SHOW_ELEMENT),i=[];for(;t.nextNode();){const s=t.currentNode;s.removeAttribute("style"),["B","STRONG","I","EM","U","SPAN","FONT"].includes(s.tagName)&&i.push(s)}for(const t of i){for(;t.firstChild;)t.parentNode?.insertBefore(t.firstChild,t);t.remove()}this.ensureAtLeastOneParagraph()}this.updateContent(),this.updateToolbarState()}setBtnActive(t,i){const s=this.buttonMap.get(t);if(s)for(const t of s)t.toggleAttribute("data-active",!!i)}updateToolbarState(){if(!this.editorEl)return;const t=document.getSelection();if(!t||0===t.rangeCount)return;const i=t.getRangeAt(0);if(!this.editorEl.contains(i.commonAncestorContainer))return;const s=d(i.startContainer)||this.editorEl,e=getComputedStyle(s),n=f(i.startContainer,this.editorEl)||this.editorEl,o=(()=>{let t=s;for(;t&&t!==this.editorEl;){if(t instanceof HTMLElement){const i=t.tagName.toLowerCase();if("strong"===i||"b"===i)return!0;const s=getComputedStyle(t).fontWeight;if(parseInt(s,10)>=600)return!0}t=t.parentNode}return!1})(),r=(()=>{let t=s;for(;t&&t!==this.editorEl;){if(t instanceof HTMLElement){const i=t.tagName.toLowerCase();if("em"===i||"i"===i)return!0;if("italic"===getComputedStyle(t).fontStyle)return!0}t=t.parentNode}return!1})(),h=(()=>{let t=s;for(;t&&t!==this.editorEl;){if(t instanceof HTMLElement){const i=getComputedStyle(t).textDecorationLine;if(i&&i.includes("underline"))return!0;if("u"===t.tagName.toLowerCase())return!0}t=t.parentNode}return!1})(),l=!!s.closest("a"),c=n.style.textAlign||getComputedStyle(n).textAlign||"start",a="start"===c?"left":c,u=!!s.closest("li")&&s.closest("ul,ol")?.tagName.toLowerCase()||"";if(this.setBtnActive("bold",o),this.setBtnActive("italic",r),this.setBtnActive("underline",h),this.setBtnActive("link",l),this.setBtnActive("left","left"===a&&!["center","right","justify"].includes(a)),this.setBtnActive("center","center"===a),this.setBtnActive("right","right"===a),this.setBtnActive("justify","justify"===a),this.setBtnActive("ul","ul"===u),this.setBtnActive("ol","ol"===u),this.headingSelect){const t=n.tagName.toLowerCase(),i=["h1","h2","h3"].includes(t)?t:"p";this.headingSelect.value!==i&&(this.headingSelect.value=i)}if(this.fontSelect){const t=(e.fontFamily||"").replace(/["']/g,"").split(",")[0].trim().toLowerCase();if(t)for(const i of Array.from(this.fontSelect.options))if(i.value.toLowerCase()===t){this.fontSelect.value=i.value;break}}if(this.colorInput){const t=m(e.color);t&&this.colorInput.value.toLowerCase()!==t.toLowerCase()&&(this.colorInput.value=t),this.colorSwatchEl&&(this.colorSwatchEl.style.backgroundColor=this.colorInput.value)}if(this.bgColorInput){const t=getComputedStyle(s).backgroundColor;if(t&&!/transparent|rgba\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)/i.test(t)){const i=m(t);i&&this.bgColorInput.value.toLowerCase()!==i.toLowerCase()&&(this.bgColorInput.value=i)}this.bgSwatchEl&&(this.bgSwatchEl.style.backgroundColor=this.bgColorInput.value)}}syncPreview(){this.updateContent()}updateContent(){if(!this.editorEl)return;this.ensureAtLeastOneParagraph();const t=this.editorEl.cloneNode(!0),i=document.createTreeWalker(this.editorEl,NodeFilter.SHOW_ELEMENT),s=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT);for(;i.nextNode()&&s.nextNode();){const t=i.currentNode,e=s.currentNode;if(e.removeAttribute("style"),["B","STRONG","I","EM","U","H1","H2","H3","H4","H5","H6"].includes(e.tagName))continue;const n=this.collectMinimalInline(t);n&&e.setAttribute("style",n)}this.content=t.innerHTML,this.previewEl&&(this.previewEl.innerHTML=this.content),this.dispatchEvent(new CustomEvent("content-changed",{detail:{content:this.content},bubbles:!0,composed:!0}))}collectMinimalInline(t){const i=getComputedStyle(t),s=t.parentElement?getComputedStyle(t.parentElement):null,e=[],n=(t,i)=>{i&&e.push(`${t}:${i}`)};if(["P","DIV","LI","TD","TH","BLOCKQUOTE","H1","H2","H3","H4","H5","H6"].includes(t.tagName)){const t=i.textAlign;t!==(s?.textAlign||"start")&&"start"!==t&&n("text-align",t)}s&&i.color===s.color||n("color",i.color);const o=i.backgroundColor;/transparent|rgba\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)/i.test(o)||n("background-color",o);const r=this.normalizeFontFamily(i.fontFamily),h=this.normalizeFontFamily(s?.fontFamily||"");if(r&&r!==h&&n("font-family",i.fontFamily),"SPAN"===t.tagName||t.style.fontSize){const t=i.fontSize,e=s?.fontSize;e&&t===e||n("font-size",t)}if("UL"===t.tagName||"OL"===t.tagName){const s=i.listStyleType,e="UL"===t.tagName?"disc":"decimal";s&&s!==e&&n("list-style-type",s)}const l=i.textDecorationLine;return l&&"none"!==l&&"U"!==t.tagName&&n("text-decoration-line",l),e.join(";")}normalizeFontFamily(t){return(t||"").replace(/["']/g,"").split(",")[0].trim().toLowerCase()}};t([s({type:String})],g.prototype,"value",void 0),t([s({attribute:"mentions",converter:{fromAttribute:t=>{try{const i=JSON.parse(t),s={};for(const t of Object.keys(i)){const e=i[t];Array.isArray(e)&&(s[t]=e.filter((t=>t&&"string"==typeof t.key&&"string"==typeof t.label)).map((t=>({key:t.key,label:t.label}))))}return s}catch{return{}}},toAttribute:t=>JSON.stringify(t)}})],g.prototype,"mentions",void 0),t([e()],g.prototype,"content",void 0),g=t([n("nile-rich-text-editor")],g);export{g as N};
1
+ import{__decorate as t}from"tslib";import{LitElement as i}from"lit";import{property as s,state as e,customElement as n}from"lit/decorators.js";import"./nile-rte-toolbar.esm.js";import"./nile-rte-toolbar-item.esm.js";import"./nile-rte-select.esm.js";import"./nile-rte-color.esm.js";import"./nile-rte-divider.esm.js";import"./nile-rte-preview.esm.js";import"./nile-rte-mentions.esm.js";import{s as o,a as r,b as h,c as l,d as c,i as a,t as u,n as d,e as f,r as m}from"./utils.esm.js";import{s as p}from"./nile-rich-text-editor.css.esm.js";const b={bold:"format_bold",italic:"format_italic",underline:"format_underline",link:"link_2",left:"format_align_left",center:"format_align_middle",right:"format_align_right",justify:"format_align_justify",ul:"nile-ul",ol:"nile-ol",clear:"error"};let g=class extends i{constructor(){super(...arguments),this.value="",this.mentions={},this.content="",this.previewEl=null,this.toolbarEl=null,this.lastRange=null,this.buttonMap=new Map,this.headingSelect=null,this.fontSelect=null,this.colorInput=null,this.bgColorInput=null,this.colorSwatchEl=null,this.bgSwatchEl=null,this.mentionsEl=null,this.onEditorKeydown=t=>{if("Tab"!==t.key)return;t.preventDefault(),this.focusAndRestore();const i=window.getSelection();if(!i||0===i.rangeCount)return;const s=i.getRangeAt(0);if(t.shiftKey){if(s.collapsed&&s.startContainer.nodeType===Node.TEXT_NODE){const t=s.startContainer,e=s.startOffset,n=t.data.slice(0,e),o=n.replace(/(\t|[ \u00a0]{2})$/,"");if(o.length!==n.length){t.data=o+t.data.slice(e);const s=document.createRange();s.setStart(t,o.length),s.collapse(!0),i.removeAllRanges(),i.addRange(s),this.updateContent(),this.updateToolbarState()}}return}s.deleteContents();const e=document.createTextNode("\t");s.insertNode(e);const n=document.createRange();n.setStartAfter(e),n.collapse(!0),i.removeAllRanges(),i.addRange(n),this.updateContent(),this.updateToolbarState()},this.onSelectionChange=()=>{if(!this.editorEl)return;const t=document.getSelection();if(!t||0===t.rangeCount)return;const i=t.getRangeAt(0);this.editorEl.contains(i.commonAncestorContainer)&&(this.lastRange=i.cloneRange(),this.updateToolbarState())}}createRenderRoot(){return this}shouldUpdate(){return!1}injectCss(t){if(this.querySelector("style[data-rte-style]"))return;const i=document.createElement("style");i.setAttribute("data-rte-style","true"),i.textContent=t,this.insertBefore(i,this.firstChild)}connectedCallback(){super.connectedCallback(),this.injectCss(p.cssText),this.toolbarEl=this.querySelector("nile-rte-toolbar"),this.previewEl=this.querySelector("nile-rte-preview"),this.ensureEditor(),this.value&&!this.editorEl.innerHTML.trim()&&(this.editorEl.innerHTML=this.value),this.content=this.editorEl.innerHTML,this.toolbarEl&&this.wireAuthoredToolbar(this.toolbarEl),this.mentionsEl=this.querySelector("nile-rte-mentions"),this.mentionsEl&&(this.mentionsEl.attach?.(this.editorEl,this),this.mentionsEl.setExternalConfig?.(this.mentions)),this.wireEditor(),this.updateToolbarState(),this.syncPreview(),document.addEventListener("selectionchange",this.onSelectionChange,!0)}disconnectedCallback(){document.removeEventListener("selectionchange",this.onSelectionChange,!0),this.mentionsEl&&this.mentionsEl.detach&&this.mentionsEl.detach(),super.disconnectedCallback()}ensureEditor(){if(this.editorEl=this.querySelector(".editor"),!this.editorEl){const t=document.createElement("article");t.className="editor",t.setAttribute("contenteditable","true"),this.toolbarEl?.nextSibling?this.insertBefore(t,this.toolbarEl.nextSibling):this.previewEl?this.insertBefore(t,this.previewEl):this.appendChild(t),this.editorEl=t}this.editorEl.innerHTML.trim()||(this.editorEl.innerHTML="<p><br></p>"),this.ensureAtLeastOneParagraph()}wireEditor(){this.editorEl.addEventListener("input",(()=>{this.ensureAtLeastOneParagraph(),this.updateContent()})),this.editorEl.addEventListener("mouseup",(()=>this.saveSelection())),this.editorEl.addEventListener("keyup",(()=>this.saveSelection())),this.editorEl.addEventListener("keydown",this.onEditorKeydown)}wireAuthoredToolbar(t){this.buttonMap.clear(),this.headingSelect=null,this.fontSelect=null,this.colorInput=null,Array.from(t.children).forEach((t=>{const i=t.tagName.toLowerCase();if("nile-rte-select"!==i||"align"!==t.getAttribute("type")){if("nile-rte-toolbar-item"===i){let i=t.querySelector(":scope > nile-button");const s=t.getAttribute("name")||"",e=t.getAttribute("label")||s,n=t.getAttribute("icon"),o=t.innerHTML.trim().length>0;if(i||(i=document.createElement("nile-button"),i.variant="tertiary",i.size="small"),n)i.innerHTML=`<nile-icon name="${n}" aria-label="${e}"></nile-icon>`,t.innerHTML="";else if(o)i.innerHTML=t.innerHTML,t.innerHTML="";else{const n=b[s];n?i.innerHTML=`<nile-icon name="${n}" size="20" color="black" aria-label="${e}"></nile-icon>`:i.textContent=e||s,t.innerHTML=""}i.isConnected||t.appendChild(i),i.setAttribute("aria-label",e),i.addEventListener("mousedown",(t=>t.preventDefault())),i.addEventListener("click",(()=>this.onToolbarCommand(s)));const r=this.buttonMap.get(s)??[];return r.push(i),void this.buttonMap.set(s,r)}if("nile-rte-select"!==i){if("nile-rte-color"===i){const i=t.getAttribute("label")??"Text color",s=t.getAttribute("value")??"#000000",e=t.getAttribute("mode")??"text";let n=t.querySelector(':scope > input[type="color"]');n||(n=document.createElement("input"),n.type="color",n.style.position="absolute",n.style.opacity="0",n.style.pointerEvents="none",t.appendChild(n)),n.title=i,n.value=s;let o=t.querySelector(":scope > button.rte-color-trigger");o||(o=document.createElement("button"),o.type="button",o.className="rte-color-trigger",o.setAttribute("aria-label",i),o.innerHTML="background"===e?'\n <span class="swatch-box" aria-hidden="true"></span>\n ':'\n <span class="glyph-stack" aria-hidden="true">\n <span class="glyph">A</span>\n <span class="underline"></span>\n </span>\n ',t.appendChild(o));const r=o.querySelector(".underline"),h=o.querySelector(".swatch-box");"background"===e?(this.bgColorInput=n,this.bgSwatchEl=h,this.bgSwatchEl&&(this.bgSwatchEl.style.backgroundColor=n.value)):(this.colorInput=n,this.colorSwatchEl=r,this.colorSwatchEl&&(this.colorSwatchEl.style.backgroundColor=n.value)),o.addEventListener("click",(t=>{t.preventDefault(),this.focusAndRestore(),n.click()})),n.addEventListener("input",(()=>{this.focusAndRestore(),"background"===e?(l(this.editorEl,n.value),this.bgSwatchEl&&(this.bgSwatchEl.style.backgroundColor=n.value)):(c(this.editorEl,n.value),this.colorSwatchEl&&(this.colorSwatchEl.style.backgroundColor=n.value)),this.updateContent(),this.updateToolbarState()})),o.addEventListener("mousedown",(t=>t.preventDefault())),n.addEventListener("mousedown",(t=>t.preventDefault()))}}else{const i=t.getAttribute("type")||"";t.addEventListener("change",(t=>{this.focusAndRestore();const s=t.detail;"heading"===i?r(this.editorEl,s):"font"===i&&h(this.editorEl,s),this.updateContent(),this.updateToolbarState()}))}}else t.addEventListener("change",(t=>{this.focusAndRestore();const i=t.detail;o(this.editorEl,i),this.updateContent(),this.updateToolbarState()}))}))}saveSelection(){const t=window.getSelection();t&&t.rangeCount&&(this.lastRange=t.getRangeAt(0).cloneRange())}restoreSelection(){if(!this.lastRange)return;const t=document.getSelection();t&&(t.removeAllRanges(),t.addRange(this.lastRange))}focusAndRestore(){this.editorEl?.focus(),this.restoreSelection()}insertList(t){if(this.restoreSelection(),!this.lastRange)return;const i=document.createElement(t),s=this.lastRange.extractContents(),e=document.createElement("div");e.appendChild(s),Array.from(e.childNodes).forEach((t=>{if(t.nodeType===Node.TEXT_NODE&&!t.textContent?.trim())return;const s=document.createElement("li");s.appendChild(t),i.appendChild(s)})),this.lastRange.insertNode(i),this.afterListEdit(i)}afterListEdit(t){const i=document.createRange();i.setStartAfter(t),i.collapse(!0);const s=window.getSelection();s?.removeAllRanges(),s?.addRange(i),this.saveSelection(),this.updateContent(),this.updateToolbarState()}ensureAtLeastOneParagraph(){const t=this.editorEl;if(!t)return;const i=""===(t.textContent??"").replace(/\u200B/g,"").trim();if(0===t.childNodes.length||i)return void(t.innerHTML="<p><br></p>");if(!t.querySelector("p,h1,h2,h3,h4,h5,h6,ul,ol,table,blockquote,pre")){const i=document.createElement("p");for(;t.firstChild;)i.appendChild(t.firstChild);return i.hasChildNodes()||i.appendChild(document.createElement("br")),void t.appendChild(i)}t.querySelectorAll("p").forEach((t=>{""===(t.textContent??"").replace(/\u200B/g,"")&&(t.innerHTML.toLowerCase().includes("<br")||(t.innerHTML="<br>"))}))}onToolbarCommand(t){switch(this.focusAndRestore(),t){case"bold":u(this.editorEl,"strong");break;case"italic":u(this.editorEl,"em");break;case"underline":u(this.editorEl,"u");break;case"left":o(this.editorEl,"left");break;case"center":o(this.editorEl,"center");break;case"right":o(this.editorEl,"right");break;case"justify":o(this.editorEl,"justify");break;case"ul":this.insertList("ul");break;case"ol":this.insertList("ol");break;case"link":a(this.editorEl);break;case"clear":const t=document.createTreeWalker(this.editorEl,NodeFilter.SHOW_ELEMENT),i=[];for(;t.nextNode();){const s=t.currentNode;s.removeAttribute("style"),["B","STRONG","I","EM","U","SPAN","FONT"].includes(s.tagName)&&i.push(s)}for(const t of i){for(;t.firstChild;)t.parentNode?.insertBefore(t.firstChild,t);t.remove()}this.ensureAtLeastOneParagraph()}this.updateContent(),this.updateToolbarState()}setBtnActive(t,i){const s=this.buttonMap.get(t);if(s)for(const t of s)t.toggleAttribute("data-active",!!i)}updateToolbarState(){if(!this.editorEl)return;const t=document.getSelection();if(!t||0===t.rangeCount)return;const i=t.getRangeAt(0);if(!this.editorEl.contains(i.commonAncestorContainer))return;const s=d(i.startContainer)||this.editorEl,e=getComputedStyle(s),n=f(i.startContainer,this.editorEl)||this.editorEl,o=(()=>{let t=s;for(;t&&t!==this.editorEl;){if(t instanceof HTMLElement){const i=t.tagName.toLowerCase();if("strong"===i||"b"===i)return!0;const s=getComputedStyle(t).fontWeight;if(parseInt(s,10)>=600)return!0}t=t.parentNode}return!1})(),r=(()=>{let t=s;for(;t&&t!==this.editorEl;){if(t instanceof HTMLElement){const i=t.tagName.toLowerCase();if("em"===i||"i"===i)return!0;if("italic"===getComputedStyle(t).fontStyle)return!0}t=t.parentNode}return!1})(),h=(()=>{let t=s;for(;t&&t!==this.editorEl;){if(t instanceof HTMLElement){const i=getComputedStyle(t).textDecorationLine;if(i&&i.includes("underline"))return!0;if("u"===t.tagName.toLowerCase())return!0}t=t.parentNode}return!1})(),l=!!s.closest("a"),c=n.style.textAlign||getComputedStyle(n).textAlign||"start",a="start"===c?"left":c,u=!!s.closest("li")&&s.closest("ul,ol")?.tagName.toLowerCase()||"";if(this.setBtnActive("bold",o),this.setBtnActive("italic",r),this.setBtnActive("underline",h),this.setBtnActive("link",l),this.setBtnActive("left","left"===a&&!["center","right","justify"].includes(a)),this.setBtnActive("center","center"===a),this.setBtnActive("right","right"===a),this.setBtnActive("justify","justify"===a),this.setBtnActive("ul","ul"===u),this.setBtnActive("ol","ol"===u),this.headingSelect){const t=n.tagName.toLowerCase(),i=["h1","h2","h3"].includes(t)?t:"p";this.headingSelect.value!==i&&(this.headingSelect.value=i)}if(this.fontSelect){const t=(e.fontFamily||"").replace(/["']/g,"").split(",")[0].trim().toLowerCase();if(t)for(const i of Array.from(this.fontSelect.options))if(i.value.toLowerCase()===t){this.fontSelect.value=i.value;break}}if(this.colorInput){const t=m(e.color);t&&this.colorInput.value.toLowerCase()!==t.toLowerCase()&&(this.colorInput.value=t),this.colorSwatchEl&&(this.colorSwatchEl.style.backgroundColor=this.colorInput.value)}if(this.bgColorInput){const t=getComputedStyle(s).backgroundColor;if(t&&!/transparent|rgba\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)/i.test(t)){const i=m(t);i&&this.bgColorInput.value.toLowerCase()!==i.toLowerCase()&&(this.bgColorInput.value=i)}this.bgSwatchEl&&(this.bgSwatchEl.style.backgroundColor=this.bgColorInput.value)}}syncPreview(){this.updateContent()}updateContent(){if(!this.editorEl)return;this.ensureAtLeastOneParagraph();const t=this.editorEl.cloneNode(!0),i=document.createTreeWalker(this.editorEl,NodeFilter.SHOW_ELEMENT),s=document.createTreeWalker(t,NodeFilter.SHOW_ELEMENT);for(;i.nextNode()&&s.nextNode();){const t=i.currentNode,e=s.currentNode,n=window.getComputedStyle(t),o=Array.from(n).map((t=>`${t}:${n.getPropertyValue(t)}`)).join(";");e.setAttribute("style",o)}this.content=t.innerHTML,this.previewEl&&(this.previewEl.innerHTML=this.content),this.dispatchEvent(new CustomEvent("content-changed",{detail:{content:this.content},bubbles:!0,composed:!0}))}};t([s({type:String})],g.prototype,"value",void 0),t([s({attribute:"mentions",converter:{fromAttribute:t=>{try{const i=JSON.parse(t),s={};for(const t of Object.keys(i)){const e=i[t];Array.isArray(e)&&(s[t]=e.filter((t=>t&&"string"==typeof t.key&&"string"==typeof t.label)).map((t=>({key:t.key,label:t.label}))))}return s}catch{return{}}},toAttribute:t=>JSON.stringify(t)}})],g.prototype,"mentions",void 0),t([e()],g.prototype,"content",void 0),g=t([n("nile-rich-text-editor")],g);export{g as N};
@@ -1,160 +1,67 @@
1
1
  // rte-styles.ts
2
2
  import { css } from 'lit';
3
3
  export const styles = css `
4
- /* ---- SAFER RESET INSIDE THE EDITOR -------------------------------------- */
5
- .editor * {
6
- all: revert; /* keep your reset… */
7
- box-sizing: border-box; /* …but preserve sane layout */
8
- overflow-wrap: anywhere; /* break long words/URLs */
9
- word-break: break-word;
4
+ .editor * {
5
+ all: revert;
10
6
  }
11
7
 
12
- /* Let component & editor shrink inside flex/grid parents */
13
- nile-rich-text-editor,
14
- .editor {
15
- display: block;
16
- min-width: 0;
17
- max-width: 100%;
18
- font-family: inherit;
19
- }
20
-
21
- /* ---- TOOLBAR ------------------------------------------------------------- */
22
- nile-rte-toolbar,
23
- .toolbar {
24
- display: flex;
25
- flex-wrap: wrap; /* allow wrapping to next row */
26
- align-items: center;
27
- gap: 8px;
28
- padding: 8px;
29
- border: 1px solid #e5e7eb;
30
- border-bottom: none;
31
- border-radius: 8px 8px 0 0;
32
- background: #fff;
33
- box-sizing: border-box;
34
- width: 100%;
35
- }
36
-
37
- /* allow children to shrink instead of forcing overflow */
38
- nile-rte-toolbar > *,
39
- .toolbar > * {
40
- flex: 0 1 auto;
41
- min-width: 0;
42
- }
8
+ nile-rich-text-editor { position: relative; display: block; font-family: inherit; }
43
9
 
44
- /* buttons */
10
+
45
11
  nile-rte-toolbar-item > nile-button::part(base) {
46
- width: 32px;
47
- height: 32px;
48
- padding: 0 6px;
12
+
13
+ width:32px; height:32px; padding:0px 6px;
49
14
  border: none;
50
15
  }
51
-
52
- nile-rte-toolbar-item > button,
53
- .toolbar button,
54
- nile-rte-toolbar button {
55
- border: 1px solid #e5e7eb;
56
- background: #fff;
57
- border-radius: 6px;
58
- cursor: pointer;
59
- }
60
-
61
- nile-rte-toolbar-item > button nile-icon { pointer-events: none; }
62
-
63
- nile-rte-toolbar-item > button.active {
64
- border-color: #2563eb;
65
- background: #eff6ff;
66
- }
67
-
68
- /* selects should be able to shrink on small screens */
69
- nile-rte-select select {
70
- height: 32px;
71
- border: 1px solid #e5e7eb;
72
- border-radius: 6px;
73
- background: #fff;
74
- min-width: 0;
75
- max-width: 100%;
76
- }
77
-
78
- /* color input */
79
- nile-rte-color input[type="color"] {
80
- height: 32px;
81
- width: 36px;
82
- border: 1px solid #e5e7eb;
83
- padding: 0;
84
- border-radius: 6px;
85
- background: #fff;
86
- }
87
-
88
- nile-rte-divider {
89
- width: 1px;
90
- height: 20px;
91
- background: #e5e7eb;
92
- display: inline-block;
93
- margin: 0 4px;
94
- }
95
-
96
- /* ---- EDITOR AREA --------------------------------------------------------- */
97
- .editor {
98
- min-height: 160px;
99
- padding: 12px;
100
- border: 1px solid #e5e7eb;
101
- border-radius: 0 0 8px 8px;
102
- background: #fff;
103
- outline: none;
104
- white-space: pre-wrap;
105
- tab-size: 4;
106
- -moz-tab-size: 4;
107
- overflow-wrap: anywhere;
108
- box-sizing: border-box;
109
- width: 100%;
110
- }
111
-
112
16
 
113
- .editor p { margin: 1em 0; }
114
- .editor h1, .editor h2, .editor h3, .editor h4, .editor h5, .editor h6 {
115
- margin-left: 0;
116
- margin-right: 0;
117
- font-weight: bold;
118
- }
119
- .editor h1 { font-size: 2em; margin: 0.67em 0; }
120
- .editor h2 { font-size: 1.5em; margin: 0.83em 0; }
121
- .editor h3 { font-size: 1.17em; margin: 1em 0; }
122
- .editor h4 { font-size: 1em; margin: 1.33em 0; }
123
- .editor h5 { font-size: 0.83em; margin: 1.67em 0; }
124
- .editor h6 { font-size: 0.67em; margin: 2.33em 0; }
125
-
126
- /* Keep typical wide content inside the box */
127
- .editor img,
128
- .editor svg,
129
- .editor table,
130
- .editor pre,
131
- .editor code,
132
- .editor blockquote {
133
- max-width: 100%;
134
- box-sizing: border-box;
135
- }
136
-
137
- /* Make <pre> wrap on small screens */
138
- .editor pre {
139
- white-space: pre-wrap;
140
- word-break: break-word;
141
- }
142
-
143
- /* Long links shouldn’t push layout */
144
- .editor a { word-break: break-all; }
17
+
145
18
 
146
- /* ---- PREVIEW ------------------------------------------------------------- */
147
- nile-rte-preview {
148
- display: block;
149
- margin-top: 10px;
150
- padding: 10px;
151
- border: 1px dashed #cbd5e1;
152
- border-radius: 8px;
153
- background: #fafafa;
154
- }
155
19
 
156
- /* ---- COLOR TRIGGER (unchanged) ------------------------------------------ */
157
- .rte-color-trigger {
20
+ .toolbar, nile-rte-toolbar {
21
+ display:flex; align-items:center; gap:8px; padding:8px;
22
+ border:1px solid #e5e7eb; border-bottom:none; border-radius:8px 8px 0 0; background:#fff;
23
+ }
24
+
25
+ nile-rte-toolbar-item > button, .toolbar button, nile-rte-toolbar button {
26
+ border:1px solid #e5e7eb; background:#fff; border-radius:6px;
27
+ cursor:pointer;
28
+ }
29
+
30
+
31
+ /* Ensure clicks hit the button (not nested icon internals) */
32
+ nile-rte-toolbar-item > button nile-icon { pointer-events:none; }
33
+
34
+ nile-rte-toolbar-item > button.active { border-color:#2563eb; background:#eff6ff; }
35
+ nile-rte-select select { height:32px; border:1px solid #e5e7eb; border-radius:6px; background:#fff; }
36
+ nile-rte-color input[type="color"] { height:32px; width:36px; border:1px solid #e5e7eb; padding:0; border-radius:6px; background:#fff; }
37
+ nile-rte-divider { width:1px; height:20px; background:#e5e7eb; display:inline-block; margin:0 4px; }
38
+
39
+ .editor p { margin:1em 0; }
40
+ .editor h1 { font-size:2em, all: revert; display: block;
41
+ font-size: 2em;
42
+ margin-top: 0.67em;
43
+ margin-bottom: 0.67em;
44
+ margin-left: 0;
45
+ margin-right: 0;
46
+ font-weight: bold; }
47
+ .editor h2 { all: revert; display: block;
48
+ font-size: 1.5em;
49
+ margin-top: 0.83em;
50
+ margin-bottom: 0.83em;
51
+ margin-left: 0;
52
+ margin-right: 0;
53
+ font-weight: bold;}
54
+ .editor h3 { font-size:1.17em }
55
+ .editor h4 { font-size:1em }
56
+ .editor h5 { font-size:0.83em }
57
+ .editor h6 { font-size:0.67em }
58
+
59
+ .editor { min-height:160px; padding:12px; border:1px solid #e5e7eb; border-radius:0 0 8px 8px; background:#fff; outline:none; white-space: pre-wrap;
60
+ tab-size: 4;
61
+ -moz-tab-size: 4; }
62
+ nile-rte-preview { display:block; margin-top:10px; padding:10px; border:1px dashed #cbd5e1; border-radius:8px; background:#fafafa; }
63
+
64
+ .rte-color-trigger {
158
65
  display: inline-flex;
159
66
  align-items: center;
160
67
  justify-content: center;
@@ -165,51 +72,37 @@ nile-rte-preview {
165
72
  background: #fff;
166
73
  cursor: pointer;
167
74
  }
75
+
168
76
  .rte-color-trigger .glyph-stack {
169
- display: grid;
170
- grid-auto-rows: max-content;
77
+ display: grid; /* stack vertically */
78
+ grid-auto-rows: max-content;
171
79
  align-items: center;
172
80
  justify-items: center;
173
81
  line-height: 1;
174
82
  }
83
+
175
84
  .rte-color-trigger .glyph {
176
85
  font-size: 14px;
177
86
  line-height: 1;
178
- margin-bottom: 2px;
87
+ margin-bottom: 2px; /* little breathing space above underline */
179
88
  }
89
+
180
90
  .rte-color-trigger .underline {
181
91
  width: 18px;
182
92
  height: 3px;
183
93
  border-radius: 2px;
184
- background: currentColor;
94
+ background: currentColor; /* we override via JS with backgroundColor */
185
95
  }
96
+
97
+ /* (unchanged) highlight square */
186
98
  .rte-color-trigger .swatch-box {
187
99
  width: 18px;
188
100
  height: 16px;
189
101
  border-radius: 4px;
190
102
  border: 1px solid rgba(0,0,0,0.35);
191
- background: currentColor;
192
- }
193
-
194
- /* ---- RESPONSIVE TWEAKS --------------------------------------------------- */
195
- @media (max-width: 900px) {
196
- nile-rte-toolbar { gap: 6px; padding: 6px; }
197
- nile-rte-select select { max-width: 160px; }
198
- }
199
-
200
- @media (max-width: 600px) {
201
- nile-rte-toolbar { gap: 4px; }
202
- nile-rte-select select { max-width: 120px; }
203
- /* optional fallback if wrapping still feels tight */
204
- /* nile-rte-toolbar { overflow-x: auto; } */
103
+ background: currentColor; /* overridden via JS */
205
104
  }
206
105
 
207
- @media (max-width: 420px) {
208
- nile-rte-select select { max-width: 100px; }
209
- nile-rte-divider { display: none; }
210
- }
211
-
212
-
213
106
  `;
214
107
  export default [styles];
215
108
  //# sourceMappingURL=nile-rich-text-editor.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nile-rich-text-editor.css.js","sourceRoot":"","sources":["../../../src/nile-rich-text-editor/nile-rich-text-editor.css.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkNxB,CAAC;AAEF,eAAe,CAAC,MAAM,CAAC,CAAC","sourcesContent":["// rte-styles.ts\nimport { css } from 'lit';\n\nexport const styles = css`\n /* ---- SAFER RESET INSIDE THE EDITOR -------------------------------------- */\n.editor * {\n all: revert; /* keep your reset… */\n box-sizing: border-box; /* …but preserve sane layout */\n overflow-wrap: anywhere; /* break long words/URLs */\n word-break: break-word;\n}\n\n/* Let component & editor shrink inside flex/grid parents */\nnile-rich-text-editor,\n.editor {\n display: block;\n min-width: 0;\n max-width: 100%;\n font-family: inherit;\n}\n\n/* ---- TOOLBAR ------------------------------------------------------------- */\nnile-rte-toolbar,\n.toolbar {\n display: flex;\n flex-wrap: wrap; /* allow wrapping to next row */\n align-items: center;\n gap: 8px;\n padding: 8px;\n border: 1px solid #e5e7eb;\n border-bottom: none;\n border-radius: 8px 8px 0 0;\n background: #fff;\n box-sizing: border-box;\n width: 100%;\n}\n\n/* allow children to shrink instead of forcing overflow */\nnile-rte-toolbar > *,\n.toolbar > * {\n flex: 0 1 auto;\n min-width: 0;\n}\n\n/* buttons */\nnile-rte-toolbar-item > nile-button::part(base) {\n width: 32px;\n height: 32px;\n padding: 0 6px;\n border: none;\n}\n\nnile-rte-toolbar-item > button,\n.toolbar button,\nnile-rte-toolbar button {\n border: 1px solid #e5e7eb;\n background: #fff;\n border-radius: 6px;\n cursor: pointer;\n}\n\nnile-rte-toolbar-item > button nile-icon { pointer-events: none; }\n\nnile-rte-toolbar-item > button.active {\n border-color: #2563eb;\n background: #eff6ff;\n}\n\n/* selects should be able to shrink on small screens */\nnile-rte-select select {\n height: 32px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n min-width: 0;\n max-width: 100%;\n}\n\n/* color input */\nnile-rte-color input[type=\"color\"] {\n height: 32px;\n width: 36px;\n border: 1px solid #e5e7eb;\n padding: 0;\n border-radius: 6px;\n background: #fff;\n}\n\nnile-rte-divider {\n width: 1px;\n height: 20px;\n background: #e5e7eb;\n display: inline-block;\n margin: 0 4px;\n}\n\n/* ---- EDITOR AREA --------------------------------------------------------- */\n.editor {\n min-height: 160px;\n padding: 12px;\n border: 1px solid #e5e7eb;\n border-radius: 0 0 8px 8px;\n background: #fff;\n outline: none;\n white-space: pre-wrap;\n tab-size: 4;\n -moz-tab-size: 4;\n overflow-wrap: anywhere;\n box-sizing: border-box;\n width: 100%;\n}\n\n \n.editor p { margin: 1em 0; }\n.editor h1, .editor h2, .editor h3, .editor h4, .editor h5, .editor h6 {\n margin-left: 0;\n margin-right: 0;\n font-weight: bold;\n}\n.editor h1 { font-size: 2em; margin: 0.67em 0; }\n.editor h2 { font-size: 1.5em; margin: 0.83em 0; }\n.editor h3 { font-size: 1.17em; margin: 1em 0; }\n.editor h4 { font-size: 1em; margin: 1.33em 0; }\n.editor h5 { font-size: 0.83em; margin: 1.67em 0; }\n.editor h6 { font-size: 0.67em; margin: 2.33em 0; }\n\n/* Keep typical wide content inside the box */\n.editor img,\n.editor svg,\n.editor table,\n.editor pre,\n.editor code,\n.editor blockquote {\n max-width: 100%;\n box-sizing: border-box;\n}\n\n/* Make <pre> wrap on small screens */\n.editor pre {\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n/* Long links shouldn’t push layout */\n.editor a { word-break: break-all; }\n\n/* ---- PREVIEW ------------------------------------------------------------- */\nnile-rte-preview {\n display: block;\n margin-top: 10px;\n padding: 10px;\n border: 1px dashed #cbd5e1;\n border-radius: 8px;\n background: #fafafa;\n}\n\n/* ---- COLOR TRIGGER (unchanged) ------------------------------------------ */\n.rte-color-trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--nile-color-border, #d9d9d9);\n border-radius: 6px;\n background: #fff;\n cursor: pointer;\n}\n.rte-color-trigger .glyph-stack {\n display: grid;\n grid-auto-rows: max-content;\n align-items: center;\n justify-items: center;\n line-height: 1;\n}\n.rte-color-trigger .glyph {\n font-size: 14px;\n line-height: 1;\n margin-bottom: 2px;\n}\n.rte-color-trigger .underline {\n width: 18px;\n height: 3px;\n border-radius: 2px;\n background: currentColor;\n}\n.rte-color-trigger .swatch-box {\n width: 18px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0,0,0,0.35);\n background: currentColor;\n}\n\n/* ---- RESPONSIVE TWEAKS --------------------------------------------------- */\n@media (max-width: 900px) {\n nile-rte-toolbar { gap: 6px; padding: 6px; }\n nile-rte-select select { max-width: 160px; }\n}\n\n@media (max-width: 600px) {\n nile-rte-toolbar { gap: 4px; }\n nile-rte-select select { max-width: 120px; }\n /* optional fallback if wrapping still feels tight */\n /* nile-rte-toolbar { overflow-x: auto; } */\n}\n\n@media (max-width: 420px) {\n nile-rte-select select { max-width: 100px; }\n nile-rte-divider { display: none; }\n}\n\n\n`;\n\nexport default [styles];"]}
1
+ {"version":3,"file":"nile-rich-text-editor.css.js","sourceRoot":"","sources":["../../../src/nile-rich-text-editor/nile-rich-text-editor.css.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuGxB,CAAC;AAEF,eAAe,CAAC,MAAM,CAAC,CAAC","sourcesContent":["// rte-styles.ts\nimport { css } from 'lit';\n\nexport const styles = css`\n .editor * {\n all: revert;\n}\n\n nile-rich-text-editor { position: relative; display: block; font-family: inherit; }\n\n \nnile-rte-toolbar-item > nile-button::part(base) {\n \n width:32px; height:32px; padding:0px 6px;\n border: none;\n}\n \n \n\n\n .toolbar, nile-rte-toolbar {\n display:flex; align-items:center; gap:8px; padding:8px; \n border:1px solid #e5e7eb; border-bottom:none; border-radius:8px 8px 0 0; background:#fff;\n }\n\n nile-rte-toolbar-item > button, .toolbar button, nile-rte-toolbar button {\n border:1px solid #e5e7eb; background:#fff; border-radius:6px;\n cursor:pointer;\n }\n\n \n /* Ensure clicks hit the button (not nested icon internals) */\n nile-rte-toolbar-item > button nile-icon { pointer-events:none; }\n\n nile-rte-toolbar-item > button.active { border-color:#2563eb; background:#eff6ff; }\n nile-rte-select select { height:32px; border:1px solid #e5e7eb; border-radius:6px; background:#fff; }\n nile-rte-color input[type=\"color\"] { height:32px; width:36px; border:1px solid #e5e7eb; padding:0; border-radius:6px; background:#fff; }\n nile-rte-divider { width:1px; height:20px; background:#e5e7eb; display:inline-block; margin:0 4px; }\n\n .editor p { margin:1em 0; }\n .editor h1 { font-size:2em, all: revert; display: block;\nfont-size: 2em;\nmargin-top: 0.67em;\nmargin-bottom: 0.67em;\nmargin-left: 0;\nmargin-right: 0;\nfont-weight: bold; }\n .editor h2 { all: revert;\tdisplay: block;\nfont-size: 1.5em;\nmargin-top: 0.83em;\nmargin-bottom: 0.83em;\nmargin-left: 0;\nmargin-right: 0;\nfont-weight: bold;}\n .editor h3 { font-size:1.17em }\n .editor h4 { font-size:1em }\n .editor h5 { font-size:0.83em }\n .editor h6 { font-size:0.67em }\n\n .editor { min-height:160px; padding:12px; border:1px solid #e5e7eb; border-radius:0 0 8px 8px; background:#fff; outline:none; white-space: pre-wrap;\n tab-size: 4; \n -moz-tab-size: 4; }\n nile-rte-preview { display:block; margin-top:10px; padding:10px; border:1px dashed #cbd5e1; border-radius:8px; background:#fafafa; }\n\n .rte-color-trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 28px;\n padding: 0 8px;\n border: 1px solid var(--nile-color-border, #d9d9d9);\n border-radius: 6px;\n background: #fff;\n cursor: pointer;\n}\n\n.rte-color-trigger .glyph-stack {\n display: grid; /* stack vertically */\n grid-auto-rows: max-content; \n align-items: center;\n justify-items: center;\n line-height: 1;\n}\n\n.rte-color-trigger .glyph {\n font-size: 14px;\n line-height: 1;\n margin-bottom: 2px; /* little breathing space above underline */\n}\n\n.rte-color-trigger .underline {\n width: 18px;\n height: 3px;\n border-radius: 2px;\n background: currentColor; /* we override via JS with backgroundColor */\n}\n\n/* (unchanged) highlight square */\n.rte-color-trigger .swatch-box {\n width: 18px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid rgba(0,0,0,0.35);\n background: currentColor; /* overridden via JS */\n}\n\n`;\n\nexport default [styles];"]}
@@ -34,7 +34,6 @@ export declare class NileRichTextEditor extends LitElement {
34
34
  connectedCallback(): void;
35
35
  disconnectedCallback(): void;
36
36
  private ensureEditor;
37
- private onPaste;
38
37
  private wireEditor;
39
38
  private onEditorKeydown;
40
39
  private wireAuthoredToolbar;
@@ -50,8 +49,6 @@ export declare class NileRichTextEditor extends LitElement {
50
49
  private updateToolbarState;
51
50
  private syncPreview;
52
51
  private updateContent;
53
- private collectMinimalInline;
54
- private normalizeFontFamily;
55
52
  }
56
53
  declare global {
57
54
  interface HTMLElementTagNameMap {