@malaya_jeeva/rich-text-editor 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -5,8 +5,9 @@ type RichTextEditorProps = {
5
5
  value?: string;
6
6
  onChange?: (value: string) => void;
7
7
  toolbar?: ToolbarItem[];
8
+ theme?: "light" | "dark";
8
9
  };
9
10
 
10
- declare function RichTextEditor({ value, onChange, toolbar }: RichTextEditorProps): ReactElement;
11
+ declare function RichTextEditor({ value, onChange, toolbar, theme }: RichTextEditorProps): ReactElement;
11
12
 
12
13
  export { type RichTextEditorProps, RichTextEditor as default };
package/dist/index.d.ts CHANGED
@@ -5,8 +5,9 @@ type RichTextEditorProps = {
5
5
  value?: string;
6
6
  onChange?: (value: string) => void;
7
7
  toolbar?: ToolbarItem[];
8
+ theme?: "light" | "dark";
8
9
  };
9
10
 
10
- declare function RichTextEditor({ value, onChange, toolbar }: RichTextEditorProps): ReactElement;
11
+ declare function RichTextEditor({ value, onChange, toolbar, theme }: RichTextEditorProps): ReactElement;
11
12
 
12
13
  export { type RichTextEditorProps, RichTextEditor as default };
package/dist/index.js CHANGED
@@ -64,64 +64,107 @@ var PALETTE = [
64
64
  "#20124d",
65
65
  "#4c1130"
66
66
  ];
67
+ var DARK = `
68
+ --rte-toolbar-bg:#1e1e1e;--rte-toolbar-border:#333;
69
+ --rte-btn:#ccc;--rte-btn-hover-bg:#2e2e2e;--rte-btn-active-bg:#1a3a5c;--rte-btn-active:#90c4ff;
70
+ --rte-btn-danger:#ff6b6b;--rte-btn-danger-hover-bg:#3a1a1a;
71
+ --rte-sep:#3a3a3a;
72
+ --rte-select-bg:#2a2a2a;--rte-select-border:#444;--rte-select:#ccc;
73
+ --rte-cpick-bg:#222;--rte-cpick-border:#444;
74
+ --rte-cactions-border:#333;--rte-caction-hover-bg:#2a2a2a;--rte-caction-hover-border:#444;
75
+ --rte-tpick-bg:#222;--rte-tpick-border:#444;
76
+ --rte-tpcell-bg:#2a2a2a;--rte-tpcell-border:#444;--rte-tpcell-on-bg:#1a3a5c;--rte-tpcell-on-border:#90c4ff;
77
+ --rte-ipick-bg:#222;--rte-ipick-border:#444;
78
+ --rte-itabs-border:#333;--rte-itab-hover-bg:#2a2a2a;
79
+ --rte-idrop-border:#555;--rte-idrop-hover-bg:#1a3a5c;--rte-idrop-hover-border:#90c4ff;
80
+ --rte-float-bg:#222;--rte-float-border:#444;--rte-float-arrow-border:#444;--rte-float-arrow-bg:#222;
81
+ --rte-linkinput-bg:#1a1a1a;--rte-linkinput-border:#555;--rte-linkinput:#ddd;
82
+ --rte-area-bg:#141414;
83
+ --rte-body:#ddd;--rte-table-border:#444;--rte-th-bg:#2a2a2a;
84
+ --rte-pre-bg:#1e1e2e;--rte-pre-border:#333;
85
+ --rte-footer-bg:#1a1a1a;--rte-footer-border:#2a2a2a;--rte-footer:#aaa;
86
+ --rte-iepanel-bg:#222;--rte-iepanel-border:#444;
87
+ --rte-ietabs-border:#333;--rte-ietab-hover-bg:#2a2a2a;
88
+ --rte-ieinput-bg:#1a1a1a;--rte-ieinput-border:#444;--rte-ieinput:#ddd;
89
+ `;
67
90
  var CSS = `
68
91
  *{box-sizing:border-box;}
69
- .rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:#f8f8f8;border-bottom:1px solid #e0e0e0;position: sticky;top: 0;z-index: 9;}
70
- @media(prefers-color-scheme:dark){.rte-toolbar{background:#1e1e1e;border-color:#333;}}
71
- .rte-btn{background:transparent;border:none;border-radius:3px;cursor:pointer;height:30px;min-width:30px;padding:0 6px;color:#444;font-size:13px;font-weight:500;font-family:var(--font-sans);display:inline-flex;align-items:center;justify-content:center;user-select:none;white-space:nowrap;transition:background 0.1s;flex-shrink:0;}
72
- .rte-btn:hover{background:#e8e8e8;}.rte-btn.active{background:#d0e4ff;color:#1a5fb4;}
73
- .rte-btn.danger{color:#c0392b;}.rte-btn.danger:hover{background:#fdecea;}
74
- @media(prefers-color-scheme:dark){.rte-btn{color:#ccc;}.rte-btn:hover{background:#2e2e2e;}.rte-btn.active{background:#1a3a5c;color:#90c4ff;}.rte-btn.danger{color:#ff6b6b;}.rte-btn.danger:hover{background:#3a1a1a;}}
75
- .rte-sep{width:1px;height:20px;background:#d8d8d8;margin:0 4px;flex-shrink:0;}
76
- @media(prefers-color-scheme:dark){.rte-sep{background:#3a3a3a;}}
77
- .rte-select{height:28px;border:1px solid #d8d8d8;border-radius:3px;background:#fff;color:#333;font-size:12px;padding:0 22px 0 7px;cursor:pointer;outline:none;font-family:var(--font-sans);appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;}
78
- @media(prefers-color-scheme:dark){.rte-select{background-color:#2a2a2a;border-color:#444;color:#ccc;}}
92
+
93
+ /* \u2500\u2500\u2500 Theme tokens \u2500\u2500\u2500 */
94
+ .customeditor{
95
+ max-height:350px;overflow-y:auto;position:relative;
96
+ /* light (default) */
97
+ --rte-toolbar-bg:#f8f8f8;--rte-toolbar-border:#e0e0e0;
98
+ --rte-btn:#444;--rte-btn-hover-bg:#e8e8e8;--rte-btn-active-bg:#d0e4ff;--rte-btn-active:#1a5fb4;
99
+ --rte-btn-danger:#c0392b;--rte-btn-danger-hover-bg:#fdecea;
100
+ --rte-sep:#d8d8d8;
101
+ --rte-select-bg:#fff;--rte-select-border:#d8d8d8;--rte-select:#333;
102
+ --rte-cpick-bg:#fff;--rte-cpick-border:#ccc;
103
+ --rte-cactions-border:#eee;--rte-caction-hover-bg:#f0f0f0;--rte-caction-hover-border:#ddd;
104
+ --rte-tpick-bg:#fff;--rte-tpick-border:#d8d8d8;
105
+ --rte-tpcell-bg:#fff;--rte-tpcell-border:#ddd;--rte-tpcell-on-bg:#d0e4ff;--rte-tpcell-on-border:#1a5fb4;
106
+ --rte-ipick-bg:#fff;--rte-ipick-border:#ccc;
107
+ --rte-itabs-border:#eee;--rte-itab-hover-bg:#f8f8f8;
108
+ --rte-idrop-border:#ccc;--rte-idrop-hover-bg:#f0f4ff;--rte-idrop-hover-border:#1a5fb4;
109
+ --rte-float-bg:#fff;--rte-float-border:#d0d0d0;--rte-float-arrow-border:#d0d0d0;--rte-float-arrow-bg:#fff;
110
+ --rte-linkinput-bg:#fff;--rte-linkinput-border:#ccc;--rte-linkinput:#222;
111
+ --rte-area-bg:#fff;
112
+ --rte-body:#222;--rte-table-border:#ccc;--rte-th-bg:#f5f5f5;
113
+ --rte-pre-bg:#f4f4f4;--rte-pre-border:#e0e0e0;
114
+ --rte-footer-bg:#fafafa;--rte-footer-border:#e8e8e8;--rte-footer:#999;
115
+ --rte-iepanel-bg:#fff;--rte-iepanel-border:#d0d0d0;
116
+ --rte-ietabs-border:#eee;--rte-ietab-hover-bg:#f8f8f8;
117
+ --rte-ieinput-bg:#fff;--rte-ieinput-border:#ccc;--rte-ieinput:#222;
118
+ }
119
+ /* Explicit dark */
120
+ .customeditor.rte-dark{${DARK}}
121
+ /* OS-level auto dark (ignored when an explicit theme class is present) */
122
+ @media(prefers-color-scheme:dark){
123
+ .customeditor:not(.rte-light):not(.rte-dark){${DARK}}
124
+ }
125
+
126
+ /* \u2500\u2500\u2500 Component styles \u2500\u2500\u2500 */
127
+ .rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:var(--rte-toolbar-bg);border-bottom:1px solid var(--rte-toolbar-border);position:sticky;top:0;z-index:9;}
128
+ .rte-btn{background:transparent;border:none;border-radius:3px;cursor:pointer;height:30px;min-width:30px;padding:0 6px;color:var(--rte-btn);font-size:13px;font-weight:500;font-family:var(--font-sans);display:inline-flex;align-items:center;justify-content:center;user-select:none;white-space:nowrap;transition:background 0.1s;flex-shrink:0;}
129
+ .rte-btn:hover{background:var(--rte-btn-hover-bg);}
130
+ .rte-btn.active{background:var(--rte-btn-active-bg);color:var(--rte-btn-active);}
131
+ .rte-btn.danger{color:var(--rte-btn-danger);}
132
+ .rte-btn.danger:hover{background:var(--rte-btn-danger-hover-bg);}
133
+ .rte-sep{width:1px;height:20px;background:var(--rte-sep);margin:0 4px;flex-shrink:0;}
134
+ .rte-select{height:28px;border:1px solid var(--rte-select-border);border-radius:3px;background:var(--rte-select-bg);color:var(--rte-select);font-size:12px;padding:0 22px 0 7px;cursor:pointer;outline:none;font-family:var(--font-sans);appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;}
79
135
  .rte-swatch{width:14px;height:3px;border-radius:1px;margin-top:2px;}
80
- .rte-cpick{background:#fff;border:1px solid #ccc;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);padding:8px;min-width:190px;}
81
- @media(prefers-color-scheme:dark){.rte-cpick{background:#222;border-color:#444;}}
136
+ .rte-cpick{background:var(--rte-cpick-bg);border:1px solid var(--rte-cpick-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);padding:8px;min-width:190px;}
82
137
  .rte-cgrid{display:grid;grid-template-columns:repeat(8,20px);gap:2px;margin-bottom:6px;}
83
138
  .rte-ccell{width:20px;height:20px;border-radius:3px;cursor:pointer;border:1px solid rgba(0,0,0,0.12);transition:transform 0.08s,box-shadow 0.08s;}
84
139
  .rte-ccell:hover{transform:scale(1.2);box-shadow:0 1px 4px rgba(0,0,0,0.3);z-index:1;position:relative;}
85
140
  .rte-ccell.sel{outline:2px solid #1a5fb4;outline-offset:1px;}
86
- .rte-cactions{display:flex;align-items:center;gap:2px;border-top:1px solid #eee;padding-top:6px;margin-top:2px;}
87
- @media(prefers-color-scheme:dark){.rte-cactions{border-color:#333;}}
141
+ .rte-cactions{display:flex;align-items:center;gap:2px;border-top:1px solid var(--rte-cactions-border);padding-top:6px;margin-top:2px;}
88
142
  .rte-caction{flex:1;height:28px;display:flex;align-items:center;justify-content:center;border-radius:4px;cursor:pointer;border:1px solid transparent;transition:background 0.1s;}
89
- .rte-caction:hover{background:#f0f0f0;border-color:#ddd;}
90
- @media(prefers-color-scheme:dark){.rte-caction:hover{background:#2a2a2a;border-color:#444;}}
91
- .rte-tpick{background:#fff;border:1px solid #d8d8d8;border-radius:6px;box-shadow:0 4px 16px rgba(0,0,0,0.12);padding:10px;}
92
- @media(prefers-color-scheme:dark){.rte-tpick{background:#222;border-color:#444;}}
143
+ .rte-caction:hover{background:var(--rte-caction-hover-bg);border-color:var(--rte-caction-hover-border);}
144
+ .rte-tpick{background:var(--rte-tpick-bg);border:1px solid var(--rte-tpick-border);border-radius:6px;box-shadow:0 4px 16px rgba(0,0,0,0.12);padding:10px;}
93
145
  .rte-tplbl{font-size:11px;color:#888;text-align:center;margin-bottom:8px;font-family:var(--font-sans);}
94
146
  .rte-tpgrid{display:grid;grid-template-columns:repeat(8,18px);gap:2px;}
95
- .rte-tpcell{width:18px;height:18px;border-radius:2px;border:1px solid #ddd;cursor:pointer;background:#fff;transition:background 0.08s;}
96
- .rte-tpcell.on{background:#d0e4ff;border-color:#1a5fb4;}
97
- @media(prefers-color-scheme:dark){.rte-tpcell{background:#2a2a2a;border-color:#444;}.rte-tpcell.on{background:#1a3a5c;border-color:#90c4ff;}}
98
- .rte-ipick{background:#fff;border:1px solid #ccc;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:300px;overflow:hidden;}
99
- @media(prefers-color-scheme:dark){.rte-ipick{background:#222;border-color:#444;}}
100
- .rte-itabs{display:flex;border-bottom:1px solid #eee;}
101
- @media(prefers-color-scheme:dark){.rte-itabs{border-color:#333;}}
147
+ .rte-tpcell{width:18px;height:18px;border-radius:2px;border:1px solid var(--rte-tpcell-border);cursor:pointer;background:var(--rte-tpcell-bg);transition:background 0.08s;}
148
+ .rte-tpcell.on{background:var(--rte-tpcell-on-bg);border-color:var(--rte-tpcell-on-border);}
149
+ .rte-ipick{background:var(--rte-ipick-bg);border:1px solid var(--rte-ipick-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:300px;overflow:hidden;}
150
+ .rte-itabs{display:flex;border-bottom:1px solid var(--rte-itabs-border);}
102
151
  .rte-itab{flex:1;padding:8px 4px;font-size:12px;font-weight:500;background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;color:#888;font-family:var(--font-sans);}
103
- .rte-itab:hover{color:#444;background:#f8f8f8;}.rte-itab.active{color:#1a5fb4;border-bottom-color:#1a5fb4;}
104
- @media(prefers-color-scheme:dark){.rte-itab:hover{background:#2a2a2a;}}
152
+ .rte-itab:hover{color:#444;background:var(--rte-itab-hover-bg);}
153
+ .rte-itab.active{color:#1a5fb4;border-bottom-color:#1a5fb4;}
105
154
  .rte-ipbody{padding:12px;display:flex;flex-direction:column;gap:10px;}
106
- .rte-idrop{border:2px dashed #ccc;border-radius:6px;padding:24px 12px;text-align:center;cursor:pointer;transition:border-color 0.15s,background 0.15s;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;min-height:110px;}
107
- .rte-idrop:hover,.rte-idrop.drag{border-color:#1a5fb4;background:#f0f4ff;}
108
- @media(prefers-color-scheme:dark){.rte-idrop{border-color:#555;}.rte-idrop:hover,.rte-idrop.drag{background:#1a3a5c;border-color:#90c4ff;}}
155
+ .rte-idrop{border:2px dashed var(--rte-idrop-border);border-radius:6px;padding:24px 12px;text-align:center;cursor:pointer;transition:border-color 0.15s,background 0.15s;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;min-height:110px;}
156
+ .rte-idrop:hover,.rte-idrop.drag{border-color:var(--rte-idrop-hover-border);background:var(--rte-idrop-hover-bg);}
109
157
  .rte-iinsert{width:100%;height:30px;background:#1a6fc4;color:#fff;border:none;border-radius:4px;font-size:12px;font-weight:600;cursor:pointer;}
110
158
  .rte-iinsert:disabled{opacity:0.4;cursor:not-allowed;}
111
- .rte-float{position:absolute;z-index:50;background:#fff;border:1px solid #d0d0d0;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.13);padding:4px 6px;display:flex;align-items:center;gap:1px;flex-wrap:wrap;}
112
- @media(prefers-color-scheme:dark){.rte-float{background:#222;border-color:#444;}}
159
+ .rte-float{position:absolute;z-index:50;background:var(--rte-float-bg);border:1px solid var(--rte-float-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.13);padding:4px 6px;display:flex;align-items:center;gap:1px;flex-wrap:wrap;}
113
160
  .rte-float-arrow{position:absolute;top:-7px;width:14px;height:7px;}
114
161
  .rte-float-arrow::before,.rte-float-arrow::after{content:'';position:absolute;left:0;border-left:7px solid transparent;border-right:7px solid transparent;}
115
- .rte-float-arrow::before{top:0;border-bottom:7px solid #d0d0d0;}
116
- .rte-float-arrow::after{top:1px;border-bottom:6px solid #fff;}
117
- @media(prefers-color-scheme:dark){.rte-float-arrow::before{border-bottom-color:#444;}.rte-float-arrow::after{border-bottom-color:#222;}}
162
+ .rte-float-arrow::before{top:0;border-bottom:7px solid var(--rte-float-arrow-border);}
163
+ .rte-float-arrow::after{top:1px;border-bottom:6px solid var(--rte-float-arrow-bg);}
118
164
  .rte-linkbar{min-width:340px;}
119
- .rte-linkbar input{flex:1;height:26px;border:1px solid #ccc;border-radius:3px;padding:0 8px;font-size:13px;outline:none;font-family:var(--font-sans);background:#fff;color:#222;min-width:0;}
120
- @media(prefers-color-scheme:dark){.rte-linkbar input{background:#1a1a1a;border-color:#555;color:#ddd;}}
121
- .rte-area{position:relative;background:#fff;}
122
- @media(prefers-color-scheme:dark){.rte-area{background:#141414;}}
123
- .rte-body{min-height:280px;outline:none;font-size:15px;line-height:1.75;color:#222;caret-color:#222;padding:18px 20px;}
124
- @media(prefers-color-scheme:dark){.rte-body{color:#ddd;caret-color:#ddd;}}
165
+ .rte-linkbar input{flex:1;height:26px;border:1px solid var(--rte-linkinput-border);border-radius:3px;padding:0 8px;font-size:13px;outline:none;font-family:var(--font-sans);background:var(--rte-linkinput-bg);color:var(--rte-linkinput);min-width:0;}
166
+ .rte-area{position:relative;background:var(--rte-area-bg);}
167
+ .rte-body{min-height:280px;outline:none;font-size:15px;line-height:1.75;color:var(--rte-body);caret-color:var(--rte-body);padding:18px 20px;}
125
168
  .rte-body h1{font-size:26px;font-weight:600;margin:0.6em 0 0.2em;}
126
169
  .rte-body h2{font-size:20px;font-weight:600;margin:0.6em 0 0.2em;}
127
170
  .rte-body h3{font-size:16px;font-weight:600;margin:0.6em 0 0.2em;}
@@ -129,38 +172,32 @@ var CSS = `
129
172
  .rte-body ol{list-style-type:decimal;padding-left:1.6em;margin:0.3em 0;}
130
173
  .rte-body ol ol{list-style-type:lower-alpha;padding-left:1.6em;}
131
174
  .rte-body ol ol ol{list-style-type:lower-roman;padding-left:1.6em;}
132
- .rte-body ol ol ol ol{list-style-type:decimal;padding-left:1.6em;}
175
+ .rte-body ol ol ol ol{list-style-type:upper-alpha;padding-left:1.6em;}
133
176
  .rte-body ul{list-style-type:disc;padding-left:1.6em;margin:0.3em 0;}
134
177
  .rte-body ul ul{list-style-type:circle;padding-left:1.6em;}
135
178
  .rte-body ul ul ul{list-style-type:square;padding-left:1.6em;}
136
179
  .rte-body li{margin:0.1em 0;}
137
180
  .rte-body a{color:#1a6fc4;text-decoration:underline;cursor:pointer;}
138
- .rte-body pre{background:#f4f4f4;border:1px solid #e0e0e0;border-radius:4px;padding:12px 14px;margin:0.6em 0;overflow-x:auto;}
181
+ .rte-body pre{background:var(--rte-pre-bg);border:1px solid var(--rte-pre-border);border-radius:4px;padding:12px 14px;margin:0.6em 0;overflow-x:auto;}
139
182
  .rte-body code{font-family:var(--font-mono);font-size:13px;}
140
183
  .rte-body:empty:before{content:attr(data-ph);color:#aaa;pointer-events:none;}
141
184
  .rte-body table{border-collapse:collapse;width:100%;margin:0.8em 0;}
142
- .rte-body td,.rte-body th{border:1px solid #ccc;padding:7px 10px;min-width:60px;text-align:left;vertical-align:top;}
143
- .rte-body th{background:#f5f5f5;font-weight:600;}
144
- @media(prefers-color-scheme:dark){.rte-body td,.rte-body th{border-color:#444;}.rte-body th{background:#2a2a2a;}}
185
+ .rte-body td,.rte-body th{border:1px solid var(--rte-table-border);padding:7px 10px;min-width:60px;text-align:left;vertical-align:top;}
186
+ .rte-body th{background:var(--rte-th-bg);font-weight:600;}
145
187
  .rte-body td.rte-sel,.rte-body th.rte-sel{background:rgba(26,95,180,0.15)!important;outline:2px solid #1a5fb4;outline-offset:-2px;}
146
188
  .rte-body img{max-width:100%;height:auto;display:block;margin:4px 0;cursor:pointer;}
147
189
  .rte-body figure{margin:0.8em 0;display:block;overflow:hidden;}
148
190
  .rte-body figcaption{font-size:13px;color:#666;text-align:center;padding:4px 0;outline:none;clear:both;display:block;}
149
191
  .rte-code{min-height:280px;width:100%;background:#1e1e2e;color:#cdd6f4;font-family:var(--font-mono);font-size:13px;line-height:1.6;padding:18px 20px;border:none;outline:none;resize:vertical;}
150
- .rte-footer{font-size:11px;color:#999;padding:4px 20px 5px;border-top:1px solid #e8e8e8;background:#fafafa;}
151
- @media(prefers-color-scheme:dark){.rte-footer{border-color:#2a2a2a;background:#1a1a1a;color:#555;}}
152
- .rte-ie-panel{position:absolute;z-index:52;background:#fff;border:1px solid #d0d0d0;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:210px;overflow:hidden;}
153
- @media(prefers-color-scheme:dark){.rte-ie-panel{background:#222;border-color:#444;}}
154
- .rte-ie-tabs{display:flex;border-bottom:1px solid #eee;}
155
- @media(prefers-color-scheme:dark){.rte-ie-tabs{border-color:#333;}}
192
+ .rte-footer{font-size:11px;color:var(--rte-footer);padding:4px 20px 5px;border-top:1px solid var(--rte-footer-border);background:var(--rte-footer-bg);}
193
+ .rte-ie-panel{position:absolute;z-index:52;background:var(--rte-iepanel-bg);border:1px solid var(--rte-iepanel-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:210px;overflow:hidden;}
194
+ .rte-ie-tabs{display:flex;border-bottom:1px solid var(--rte-ietabs-border);}
156
195
  .rte-ie-tab{flex:1;padding:7px 4px;font-size:11px;font-weight:500;background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;color:#888;font-family:var(--font-sans);}
157
196
  .rte-ie-tab.active{color:#1a5fb4;border-bottom-color:#1a5fb4;}
158
- .rte-ie-tab:hover{background:#f8f8f8;}
159
- @media(prefers-color-scheme:dark){.rte-ie-tab:hover{background:#2a2a2a;}}
197
+ .rte-ie-tab:hover{background:var(--rte-ietab-hover-bg);}
160
198
  .rte-ie-body{padding:10px;display:flex;flex-direction:column;gap:8px;}
161
199
  .rte-ie-label{font-size:10px;color:#888;margin-bottom:3px;font-family:var(--font-sans);}
162
- .rte-ie-input{width:100%;height:26px;border:1px solid #ccc;border-radius:4px;padding:0 8px;font-size:11px;outline:none;font-family:var(--font-sans);background:#fff;color:#222;}
163
- @media(prefers-color-scheme:dark){.rte-ie-input{background:#1a1a1a;border-color:#444;color:#ddd;}}
200
+ .rte-ie-input{width:100%;height:26px;border:1px solid var(--rte-ieinput-border);border-radius:4px;padding:0 8px;font-size:11px;outline:none;font-family:var(--font-sans);background:var(--rte-ieinput-bg);color:var(--rte-ieinput);}
164
201
  .rte-ie-row{display:flex;gap:4px;}
165
202
  .rte-ie-seg-btn{flex:1;height:26px;font-size:11px;border:1px solid #ccc;border-radius:4px;background:transparent;color:#444;cursor:pointer;font-family:var(--font-sans);transition:all 0.1s;}
166
203
  .rte-ie-seg-btn.active{background:#d0e4ff;border-color:#1a5fb4;color:#1a5fb4;}
@@ -170,12 +207,13 @@ var CSS = `
170
207
  .rte-ie-apply{flex:1;height:26px;background:#1a6fc4;color:#fff;border:none;border-radius:4px;font-size:11px;font-weight:600;cursor:pointer;}
171
208
  .rte-ie-remove{flex:1;height:26px;background:#fdecea;color:#c0392b;border:1px solid #f5c6c2;border-radius:4px;font-size:11px;cursor:pointer;}
172
209
  .rte-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #1a5fb4;border-radius:2px;pointer-events:all;z-index:53;}
173
- .customeditor {
174
- max-height: 350px;
175
- overflow-y: auto;
176
- position: relative;
177
- }
178
-
210
+ .rte-body blockquote{background-color: rgb(245, 243, 255);
211
+ border-left: 4px solid rgb(100, 80, 220);
212
+ margin: 8px 0;
213
+ padding: 10px 16px;
214
+ font-style: italic;
215
+ color: rgb(75, 85, 99);
216
+ border-radius: 0 4px 4px 0;}
179
217
  `;
180
218
 
181
219
  // src/rte/utils.ts
@@ -1150,7 +1188,7 @@ function ImageEditor({ img, containerRef, onClose, onDelete, onChange }) {
1150
1188
 
1151
1189
  // src/RichTextEditor.tsx
1152
1190
  var import_jsx_runtime7 = require("react/jsx-runtime");
1153
- function RichTextEditor({ value, onChange, toolbar }) {
1191
+ function RichTextEditor({ value, onChange, toolbar, theme }) {
1154
1192
  var _a;
1155
1193
  const editorRef = (0, import_react5.useRef)(null);
1156
1194
  const editorAreaRef = (0, import_react5.useRef)(null);
@@ -1212,6 +1250,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1212
1250
  }, []);
1213
1251
  const refresh = (0, import_react5.useCallback)(() => {
1214
1252
  var _a2, _b, _c, _d;
1253
+ fixListNesting();
1215
1254
  const raw = document.queryCommandValue("formatBlock").toLowerCase().replace(/[<>]/g, "");
1216
1255
  const block = ["h1", "h2", "h3"].includes(raw) ? raw : "p";
1217
1256
  setColor(getColorAtCursor(editorRef.current));
@@ -1253,6 +1292,78 @@ function RichTextEditor({ value, onChange, toolbar }) {
1253
1292
  if (!((_a3 = p.textContent) == null ? void 0 : _a3.trim()) && !p.querySelector("img, br")) p.remove();
1254
1293
  });
1255
1294
  }, []);
1295
+ const tryAutoList = (0, import_react5.useCallback)(() => {
1296
+ var _a2, _b, _c, _d, _e, _f;
1297
+ const sel = window.getSelection();
1298
+ if (!(sel == null ? void 0 : sel.rangeCount) || !sel.getRangeAt(0).collapsed) return false;
1299
+ const range = sel.getRangeAt(0);
1300
+ const anchor = range.startContainer;
1301
+ if (anchor.nodeType !== Node.TEXT_NODE) return false;
1302
+ const textBefore = (_b = (_a2 = anchor.textContent) == null ? void 0 : _a2.slice(0, range.startOffset)) != null ? _b : "";
1303
+ const marker = textBefore.trim();
1304
+ if (!marker) return false;
1305
+ const block = (_c = anchor.parentElement) == null ? void 0 : _c.closest("p, div");
1306
+ if (!block || ((_d = block.textContent) != null ? _d : "").trim() !== marker) return false;
1307
+ if (block.tagName === "LI") return false;
1308
+ const romanToInt = (s) => {
1309
+ var _a3;
1310
+ const map = { i: 1, v: 5, x: 10, l: 50, c: 100, d: 500, m: 1e3 };
1311
+ let n = 0, prev = 0;
1312
+ for (const ch of s.toLowerCase().split("").reverse()) {
1313
+ const v = (_a3 = map[ch]) != null ? _a3 : 0;
1314
+ n += v < prev ? -v : v;
1315
+ prev = v;
1316
+ }
1317
+ return n;
1318
+ };
1319
+ let spec = null;
1320
+ const dM = marker.match(/^(\d+)\.$/), aM = marker.match(/^([a-z])\.$/);
1321
+ const AM = marker.match(/^([A-Z])\.$/), rM = marker.match(/^([ivxlcdm]{1,6})\.$/i);
1322
+ if (/^[-*]$/.test(marker)) spec = { tag: "ul" };
1323
+ else if (dM) spec = { tag: "ol", olType: "1", start: parseInt(dM[1]) };
1324
+ else if (aM) spec = { tag: "ol", olType: "a", start: aM[1].charCodeAt(0) - 96 };
1325
+ else if (AM) spec = { tag: "ol", olType: "A", start: AM[1].charCodeAt(0) - 64 };
1326
+ else if (rM && romanToInt(rM[1]) > 0) spec = { tag: "ol", olType: "i", start: romanToInt(rM[1]) };
1327
+ if (!spec) return false;
1328
+ const listMatches = (el) => {
1329
+ var _a3;
1330
+ if (spec.tag === "ul") return el.tagName === "UL";
1331
+ if (el.tagName !== "OL") return false;
1332
+ return (el.getAttribute("type") || "1") === ((_a3 = spec.olType) != null ? _a3 : "1");
1333
+ };
1334
+ const parentLi = ((_e = block.parentElement) == null ? void 0 : _e.tagName) === "LI" ? block.parentElement : null;
1335
+ let targetList = null;
1336
+ let sib = block.previousElementSibling;
1337
+ while (sib) {
1338
+ if (listMatches(sib)) {
1339
+ targetList = sib;
1340
+ break;
1341
+ }
1342
+ if (!parentLi && ((_f = sib.textContent) != null ? _f : "").trim()) break;
1343
+ sib = sib.previousElementSibling;
1344
+ }
1345
+ const newLi = document.createElement("li");
1346
+ newLi.appendChild(document.createElement("br"));
1347
+ if (targetList) {
1348
+ targetList.appendChild(newLi);
1349
+ block.remove();
1350
+ } else {
1351
+ const list = document.createElement(spec.tag);
1352
+ if (spec.tag === "ol") {
1353
+ if (spec.olType && spec.olType !== "1") list.setAttribute("type", spec.olType);
1354
+ if (spec.start && spec.start > 1) list.setAttribute("start", String(spec.start));
1355
+ }
1356
+ list.appendChild(newLi);
1357
+ block.replaceWith(list);
1358
+ }
1359
+ const r = document.createRange();
1360
+ r.setStart(newLi, 0);
1361
+ r.collapse(true);
1362
+ sel.removeAllRanges();
1363
+ sel.addRange(r);
1364
+ refresh();
1365
+ return true;
1366
+ }, [refresh]);
1256
1367
  const exec = (0, import_react5.useCallback)((cmd, val = null) => {
1257
1368
  var _a2;
1258
1369
  (_a2 = editorRef.current) == null ? void 0 : _a2.focus();
@@ -1307,9 +1418,99 @@ function RichTextEditor({ value, onChange, toolbar }) {
1307
1418
  }
1308
1419
  }, [applySelection]);
1309
1420
  const handleKeyDown = (0, import_react5.useCallback)((e) => {
1310
- var _a2, _b;
1421
+ var _a2, _b, _c, _d, _e, _f, _g, _h;
1311
1422
  clearSelection();
1312
1423
  clearImageSel();
1424
+ if (e.key === " ") {
1425
+ if (tryAutoList()) {
1426
+ e.preventDefault();
1427
+ return;
1428
+ }
1429
+ }
1430
+ if (e.key === "Enter" && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
1431
+ const sel = window.getSelection();
1432
+ if (sel == null ? void 0 : sel.rangeCount) {
1433
+ const anchor = sel.getRangeAt(0).startContainer;
1434
+ const p = (_a2 = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor) == null ? void 0 : _a2.closest("p");
1435
+ const li = ((_b = p == null ? void 0 : p.parentElement) == null ? void 0 : _b.tagName) === "LI" ? p.parentElement : null;
1436
+ const parentList = li == null ? void 0 : li.parentElement;
1437
+ if (p && li && ((parentList == null ? void 0 : parentList.tagName) === "OL" || (parentList == null ? void 0 : parentList.tagName) === "UL")) {
1438
+ e.preventDefault();
1439
+ const pIsEmpty = !((_c = p.textContent) == null ? void 0 : _c.trim()) && !p.querySelector("img, table");
1440
+ if (pIsEmpty) {
1441
+ const newLi = document.createElement("li");
1442
+ newLi.appendChild(document.createElement("br"));
1443
+ li.insertAdjacentElement("afterend", newLi);
1444
+ p.remove();
1445
+ const r = document.createRange();
1446
+ r.setStart(newLi, 0);
1447
+ r.collapse(true);
1448
+ sel.removeAllRanges();
1449
+ sel.addRange(r);
1450
+ } else {
1451
+ const newP = document.createElement("p");
1452
+ newP.appendChild(document.createElement("br"));
1453
+ p.insertAdjacentElement("afterend", newP);
1454
+ const r = document.createRange();
1455
+ r.setStart(newP, 0);
1456
+ r.collapse(true);
1457
+ sel.removeAllRanges();
1458
+ sel.addRange(r);
1459
+ }
1460
+ refresh();
1461
+ return;
1462
+ }
1463
+ }
1464
+ }
1465
+ if (e.key === "Backspace" && !e.ctrlKey && !e.metaKey && !e.altKey) {
1466
+ const sel = window.getSelection();
1467
+ if ((sel == null ? void 0 : sel.rangeCount) && sel.getRangeAt(0).collapsed) {
1468
+ const anchor = sel.getRangeAt(0).startContainer;
1469
+ const li = (_d = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor) == null ? void 0 : _d.closest("li");
1470
+ if (li) {
1471
+ const isEmpty = !((_e = li.textContent) == null ? void 0 : _e.trim()) && !li.querySelector("img, table, ol, ul");
1472
+ const parentList = li.parentElement;
1473
+ const grandParent = parentList == null ? void 0 : parentList.parentElement;
1474
+ if (isEmpty && parentList) {
1475
+ const prevLi = ((_f = li.previousElementSibling) == null ? void 0 : _f.tagName) === "LI" ? li.previousElementSibling : null;
1476
+ if (prevLi) {
1477
+ e.preventDefault();
1478
+ li.remove();
1479
+ const p = document.createElement("p");
1480
+ p.appendChild(document.createElement("br"));
1481
+ prevLi.appendChild(p);
1482
+ const r = document.createRange();
1483
+ r.setStart(p, 0);
1484
+ r.collapse(true);
1485
+ sel.removeAllRanges();
1486
+ sel.addRange(r);
1487
+ refresh();
1488
+ return;
1489
+ }
1490
+ const isNested = (grandParent == null ? void 0 : grandParent.tagName) === "LI" || (grandParent == null ? void 0 : grandParent.tagName) === "OL" || (grandParent == null ? void 0 : grandParent.tagName) === "UL";
1491
+ if (isNested && grandParent) {
1492
+ e.preventDefault();
1493
+ li.remove();
1494
+ const p = document.createElement("p");
1495
+ p.appendChild(document.createElement("br"));
1496
+ if (!parentList.querySelector("li")) {
1497
+ parentList.insertAdjacentElement("afterend", p);
1498
+ parentList.remove();
1499
+ } else {
1500
+ parentList.insertAdjacentElement("afterend", p);
1501
+ }
1502
+ const r = document.createRange();
1503
+ r.setStart(p, 0);
1504
+ r.collapse(true);
1505
+ sel.removeAllRanges();
1506
+ sel.addRange(r);
1507
+ refresh();
1508
+ return;
1509
+ }
1510
+ }
1511
+ }
1512
+ }
1513
+ }
1313
1514
  if (!e.ctrlKey && !e.metaKey && !e.altKey && e.key.length === 1) {
1314
1515
  const sel = window.getSelection();
1315
1516
  if (sel == null ? void 0 : sel.rangeCount) {
@@ -1332,8 +1533,8 @@ function RichTextEditor({ value, onChange, toolbar }) {
1332
1533
  }
1333
1534
  return;
1334
1535
  }
1335
- const node = (_a2 = window.getSelection()) == null ? void 0 : _a2.anchorNode;
1336
- const li = (node == null ? void 0 : node.nodeType) === 1 ? node.closest("li") : (_b = node == null ? void 0 : node.parentElement) == null ? void 0 : _b.closest("li");
1536
+ const node = (_g = window.getSelection()) == null ? void 0 : _g.anchorNode;
1537
+ const li = (node == null ? void 0 : node.nodeType) === 1 ? node.closest("li") : (_h = node == null ? void 0 : node.parentElement) == null ? void 0 : _h.closest("li");
1337
1538
  if (li) exec(e.shiftKey ? "outdent" : "indent");
1338
1539
  else document.execCommand("insertText", false, "\xA0\xA0\xA0\xA0");
1339
1540
  }
@@ -1351,7 +1552,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1351
1552
  exec("underline");
1352
1553
  }
1353
1554
  }
1354
- }, [exec, clearSelection, clearImageSel, fmt.block]);
1555
+ }, [exec, tryAutoList, clearSelection, clearImageSel, fmt.block]);
1355
1556
  const insertTable = (rows, cols) => {
1356
1557
  var _a2;
1357
1558
  (_a2 = editorRef.current) == null ? void 0 : _a2.focus();
@@ -1528,7 +1729,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1528
1729
  const show = (key) => !toolbar || toolbar.includes(key);
1529
1730
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { padding: "1rem 0" }, children: [
1530
1731
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: CSS }),
1531
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "customeditor", style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
1732
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `customeditor${theme ? ` rte-${theme}` : ""}`, style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
1532
1733
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rte-toolbar", children: [
1533
1734
  !isCode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1534
1735
  show("bold") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
@@ -1544,7 +1745,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1544
1745
  active: showColor,
1545
1746
  style: { flexDirection: "column", gap: 1, padding: "3px 6px" },
1546
1747
  children: [
1547
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: 13, fontWeight: 800, fontFamily: "Georgia,serif", lineHeight: 1, color: "#222" }, children: "A" }),
1748
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: { fontSize: 13, fontWeight: 800, fontFamily: "Georgia,serif", lineHeight: 1 }, children: "A" }),
1548
1749
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rte-swatch", style: { background: color } })
1549
1750
  ]
1550
1751
  }
package/dist/index.mjs CHANGED
@@ -43,64 +43,107 @@ var PALETTE = [
43
43
  "#20124d",
44
44
  "#4c1130"
45
45
  ];
46
+ var DARK = `
47
+ --rte-toolbar-bg:#1e1e1e;--rte-toolbar-border:#333;
48
+ --rte-btn:#ccc;--rte-btn-hover-bg:#2e2e2e;--rte-btn-active-bg:#1a3a5c;--rte-btn-active:#90c4ff;
49
+ --rte-btn-danger:#ff6b6b;--rte-btn-danger-hover-bg:#3a1a1a;
50
+ --rte-sep:#3a3a3a;
51
+ --rte-select-bg:#2a2a2a;--rte-select-border:#444;--rte-select:#ccc;
52
+ --rte-cpick-bg:#222;--rte-cpick-border:#444;
53
+ --rte-cactions-border:#333;--rte-caction-hover-bg:#2a2a2a;--rte-caction-hover-border:#444;
54
+ --rte-tpick-bg:#222;--rte-tpick-border:#444;
55
+ --rte-tpcell-bg:#2a2a2a;--rte-tpcell-border:#444;--rte-tpcell-on-bg:#1a3a5c;--rte-tpcell-on-border:#90c4ff;
56
+ --rte-ipick-bg:#222;--rte-ipick-border:#444;
57
+ --rte-itabs-border:#333;--rte-itab-hover-bg:#2a2a2a;
58
+ --rte-idrop-border:#555;--rte-idrop-hover-bg:#1a3a5c;--rte-idrop-hover-border:#90c4ff;
59
+ --rte-float-bg:#222;--rte-float-border:#444;--rte-float-arrow-border:#444;--rte-float-arrow-bg:#222;
60
+ --rte-linkinput-bg:#1a1a1a;--rte-linkinput-border:#555;--rte-linkinput:#ddd;
61
+ --rte-area-bg:#141414;
62
+ --rte-body:#ddd;--rte-table-border:#444;--rte-th-bg:#2a2a2a;
63
+ --rte-pre-bg:#1e1e2e;--rte-pre-border:#333;
64
+ --rte-footer-bg:#1a1a1a;--rte-footer-border:#2a2a2a;--rte-footer:#aaa;
65
+ --rte-iepanel-bg:#222;--rte-iepanel-border:#444;
66
+ --rte-ietabs-border:#333;--rte-ietab-hover-bg:#2a2a2a;
67
+ --rte-ieinput-bg:#1a1a1a;--rte-ieinput-border:#444;--rte-ieinput:#ddd;
68
+ `;
46
69
  var CSS = `
47
70
  *{box-sizing:border-box;}
48
- .rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:#f8f8f8;border-bottom:1px solid #e0e0e0;position: sticky;top: 0;z-index: 9;}
49
- @media(prefers-color-scheme:dark){.rte-toolbar{background:#1e1e1e;border-color:#333;}}
50
- .rte-btn{background:transparent;border:none;border-radius:3px;cursor:pointer;height:30px;min-width:30px;padding:0 6px;color:#444;font-size:13px;font-weight:500;font-family:var(--font-sans);display:inline-flex;align-items:center;justify-content:center;user-select:none;white-space:nowrap;transition:background 0.1s;flex-shrink:0;}
51
- .rte-btn:hover{background:#e8e8e8;}.rte-btn.active{background:#d0e4ff;color:#1a5fb4;}
52
- .rte-btn.danger{color:#c0392b;}.rte-btn.danger:hover{background:#fdecea;}
53
- @media(prefers-color-scheme:dark){.rte-btn{color:#ccc;}.rte-btn:hover{background:#2e2e2e;}.rte-btn.active{background:#1a3a5c;color:#90c4ff;}.rte-btn.danger{color:#ff6b6b;}.rte-btn.danger:hover{background:#3a1a1a;}}
54
- .rte-sep{width:1px;height:20px;background:#d8d8d8;margin:0 4px;flex-shrink:0;}
55
- @media(prefers-color-scheme:dark){.rte-sep{background:#3a3a3a;}}
56
- .rte-select{height:28px;border:1px solid #d8d8d8;border-radius:3px;background:#fff;color:#333;font-size:12px;padding:0 22px 0 7px;cursor:pointer;outline:none;font-family:var(--font-sans);appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;}
57
- @media(prefers-color-scheme:dark){.rte-select{background-color:#2a2a2a;border-color:#444;color:#ccc;}}
71
+
72
+ /* \u2500\u2500\u2500 Theme tokens \u2500\u2500\u2500 */
73
+ .customeditor{
74
+ max-height:350px;overflow-y:auto;position:relative;
75
+ /* light (default) */
76
+ --rte-toolbar-bg:#f8f8f8;--rte-toolbar-border:#e0e0e0;
77
+ --rte-btn:#444;--rte-btn-hover-bg:#e8e8e8;--rte-btn-active-bg:#d0e4ff;--rte-btn-active:#1a5fb4;
78
+ --rte-btn-danger:#c0392b;--rte-btn-danger-hover-bg:#fdecea;
79
+ --rte-sep:#d8d8d8;
80
+ --rte-select-bg:#fff;--rte-select-border:#d8d8d8;--rte-select:#333;
81
+ --rte-cpick-bg:#fff;--rte-cpick-border:#ccc;
82
+ --rte-cactions-border:#eee;--rte-caction-hover-bg:#f0f0f0;--rte-caction-hover-border:#ddd;
83
+ --rte-tpick-bg:#fff;--rte-tpick-border:#d8d8d8;
84
+ --rte-tpcell-bg:#fff;--rte-tpcell-border:#ddd;--rte-tpcell-on-bg:#d0e4ff;--rte-tpcell-on-border:#1a5fb4;
85
+ --rte-ipick-bg:#fff;--rte-ipick-border:#ccc;
86
+ --rte-itabs-border:#eee;--rte-itab-hover-bg:#f8f8f8;
87
+ --rte-idrop-border:#ccc;--rte-idrop-hover-bg:#f0f4ff;--rte-idrop-hover-border:#1a5fb4;
88
+ --rte-float-bg:#fff;--rte-float-border:#d0d0d0;--rte-float-arrow-border:#d0d0d0;--rte-float-arrow-bg:#fff;
89
+ --rte-linkinput-bg:#fff;--rte-linkinput-border:#ccc;--rte-linkinput:#222;
90
+ --rte-area-bg:#fff;
91
+ --rte-body:#222;--rte-table-border:#ccc;--rte-th-bg:#f5f5f5;
92
+ --rte-pre-bg:#f4f4f4;--rte-pre-border:#e0e0e0;
93
+ --rte-footer-bg:#fafafa;--rte-footer-border:#e8e8e8;--rte-footer:#999;
94
+ --rte-iepanel-bg:#fff;--rte-iepanel-border:#d0d0d0;
95
+ --rte-ietabs-border:#eee;--rte-ietab-hover-bg:#f8f8f8;
96
+ --rte-ieinput-bg:#fff;--rte-ieinput-border:#ccc;--rte-ieinput:#222;
97
+ }
98
+ /* Explicit dark */
99
+ .customeditor.rte-dark{${DARK}}
100
+ /* OS-level auto dark (ignored when an explicit theme class is present) */
101
+ @media(prefers-color-scheme:dark){
102
+ .customeditor:not(.rte-light):not(.rte-dark){${DARK}}
103
+ }
104
+
105
+ /* \u2500\u2500\u2500 Component styles \u2500\u2500\u2500 */
106
+ .rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:1px;padding:4px 8px;background:var(--rte-toolbar-bg);border-bottom:1px solid var(--rte-toolbar-border);position:sticky;top:0;z-index:9;}
107
+ .rte-btn{background:transparent;border:none;border-radius:3px;cursor:pointer;height:30px;min-width:30px;padding:0 6px;color:var(--rte-btn);font-size:13px;font-weight:500;font-family:var(--font-sans);display:inline-flex;align-items:center;justify-content:center;user-select:none;white-space:nowrap;transition:background 0.1s;flex-shrink:0;}
108
+ .rte-btn:hover{background:var(--rte-btn-hover-bg);}
109
+ .rte-btn.active{background:var(--rte-btn-active-bg);color:var(--rte-btn-active);}
110
+ .rte-btn.danger{color:var(--rte-btn-danger);}
111
+ .rte-btn.danger:hover{background:var(--rte-btn-danger-hover-bg);}
112
+ .rte-sep{width:1px;height:20px;background:var(--rte-sep);margin:0 4px;flex-shrink:0;}
113
+ .rte-select{height:28px;border:1px solid var(--rte-select-border);border-radius:3px;background:var(--rte-select-bg);color:var(--rte-select);font-size:12px;padding:0 22px 0 7px;cursor:pointer;outline:none;font-family:var(--font-sans);appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 6px center;}
58
114
  .rte-swatch{width:14px;height:3px;border-radius:1px;margin-top:2px;}
59
- .rte-cpick{background:#fff;border:1px solid #ccc;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);padding:8px;min-width:190px;}
60
- @media(prefers-color-scheme:dark){.rte-cpick{background:#222;border-color:#444;}}
115
+ .rte-cpick{background:var(--rte-cpick-bg);border:1px solid var(--rte-cpick-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);padding:8px;min-width:190px;}
61
116
  .rte-cgrid{display:grid;grid-template-columns:repeat(8,20px);gap:2px;margin-bottom:6px;}
62
117
  .rte-ccell{width:20px;height:20px;border-radius:3px;cursor:pointer;border:1px solid rgba(0,0,0,0.12);transition:transform 0.08s,box-shadow 0.08s;}
63
118
  .rte-ccell:hover{transform:scale(1.2);box-shadow:0 1px 4px rgba(0,0,0,0.3);z-index:1;position:relative;}
64
119
  .rte-ccell.sel{outline:2px solid #1a5fb4;outline-offset:1px;}
65
- .rte-cactions{display:flex;align-items:center;gap:2px;border-top:1px solid #eee;padding-top:6px;margin-top:2px;}
66
- @media(prefers-color-scheme:dark){.rte-cactions{border-color:#333;}}
120
+ .rte-cactions{display:flex;align-items:center;gap:2px;border-top:1px solid var(--rte-cactions-border);padding-top:6px;margin-top:2px;}
67
121
  .rte-caction{flex:1;height:28px;display:flex;align-items:center;justify-content:center;border-radius:4px;cursor:pointer;border:1px solid transparent;transition:background 0.1s;}
68
- .rte-caction:hover{background:#f0f0f0;border-color:#ddd;}
69
- @media(prefers-color-scheme:dark){.rte-caction:hover{background:#2a2a2a;border-color:#444;}}
70
- .rte-tpick{background:#fff;border:1px solid #d8d8d8;border-radius:6px;box-shadow:0 4px 16px rgba(0,0,0,0.12);padding:10px;}
71
- @media(prefers-color-scheme:dark){.rte-tpick{background:#222;border-color:#444;}}
122
+ .rte-caction:hover{background:var(--rte-caction-hover-bg);border-color:var(--rte-caction-hover-border);}
123
+ .rte-tpick{background:var(--rte-tpick-bg);border:1px solid var(--rte-tpick-border);border-radius:6px;box-shadow:0 4px 16px rgba(0,0,0,0.12);padding:10px;}
72
124
  .rte-tplbl{font-size:11px;color:#888;text-align:center;margin-bottom:8px;font-family:var(--font-sans);}
73
125
  .rte-tpgrid{display:grid;grid-template-columns:repeat(8,18px);gap:2px;}
74
- .rte-tpcell{width:18px;height:18px;border-radius:2px;border:1px solid #ddd;cursor:pointer;background:#fff;transition:background 0.08s;}
75
- .rte-tpcell.on{background:#d0e4ff;border-color:#1a5fb4;}
76
- @media(prefers-color-scheme:dark){.rte-tpcell{background:#2a2a2a;border-color:#444;}.rte-tpcell.on{background:#1a3a5c;border-color:#90c4ff;}}
77
- .rte-ipick{background:#fff;border:1px solid #ccc;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:300px;overflow:hidden;}
78
- @media(prefers-color-scheme:dark){.rte-ipick{background:#222;border-color:#444;}}
79
- .rte-itabs{display:flex;border-bottom:1px solid #eee;}
80
- @media(prefers-color-scheme:dark){.rte-itabs{border-color:#333;}}
126
+ .rte-tpcell{width:18px;height:18px;border-radius:2px;border:1px solid var(--rte-tpcell-border);cursor:pointer;background:var(--rte-tpcell-bg);transition:background 0.08s;}
127
+ .rte-tpcell.on{background:var(--rte-tpcell-on-bg);border-color:var(--rte-tpcell-on-border);}
128
+ .rte-ipick{background:var(--rte-ipick-bg);border:1px solid var(--rte-ipick-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:300px;overflow:hidden;}
129
+ .rte-itabs{display:flex;border-bottom:1px solid var(--rte-itabs-border);}
81
130
  .rte-itab{flex:1;padding:8px 4px;font-size:12px;font-weight:500;background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;color:#888;font-family:var(--font-sans);}
82
- .rte-itab:hover{color:#444;background:#f8f8f8;}.rte-itab.active{color:#1a5fb4;border-bottom-color:#1a5fb4;}
83
- @media(prefers-color-scheme:dark){.rte-itab:hover{background:#2a2a2a;}}
131
+ .rte-itab:hover{color:#444;background:var(--rte-itab-hover-bg);}
132
+ .rte-itab.active{color:#1a5fb4;border-bottom-color:#1a5fb4;}
84
133
  .rte-ipbody{padding:12px;display:flex;flex-direction:column;gap:10px;}
85
- .rte-idrop{border:2px dashed #ccc;border-radius:6px;padding:24px 12px;text-align:center;cursor:pointer;transition:border-color 0.15s,background 0.15s;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;min-height:110px;}
86
- .rte-idrop:hover,.rte-idrop.drag{border-color:#1a5fb4;background:#f0f4ff;}
87
- @media(prefers-color-scheme:dark){.rte-idrop{border-color:#555;}.rte-idrop:hover,.rte-idrop.drag{background:#1a3a5c;border-color:#90c4ff;}}
134
+ .rte-idrop{border:2px dashed var(--rte-idrop-border);border-radius:6px;padding:24px 12px;text-align:center;cursor:pointer;transition:border-color 0.15s,background 0.15s;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;min-height:110px;}
135
+ .rte-idrop:hover,.rte-idrop.drag{border-color:var(--rte-idrop-hover-border);background:var(--rte-idrop-hover-bg);}
88
136
  .rte-iinsert{width:100%;height:30px;background:#1a6fc4;color:#fff;border:none;border-radius:4px;font-size:12px;font-weight:600;cursor:pointer;}
89
137
  .rte-iinsert:disabled{opacity:0.4;cursor:not-allowed;}
90
- .rte-float{position:absolute;z-index:50;background:#fff;border:1px solid #d0d0d0;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.13);padding:4px 6px;display:flex;align-items:center;gap:1px;flex-wrap:wrap;}
91
- @media(prefers-color-scheme:dark){.rte-float{background:#222;border-color:#444;}}
138
+ .rte-float{position:absolute;z-index:50;background:var(--rte-float-bg);border:1px solid var(--rte-float-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.13);padding:4px 6px;display:flex;align-items:center;gap:1px;flex-wrap:wrap;}
92
139
  .rte-float-arrow{position:absolute;top:-7px;width:14px;height:7px;}
93
140
  .rte-float-arrow::before,.rte-float-arrow::after{content:'';position:absolute;left:0;border-left:7px solid transparent;border-right:7px solid transparent;}
94
- .rte-float-arrow::before{top:0;border-bottom:7px solid #d0d0d0;}
95
- .rte-float-arrow::after{top:1px;border-bottom:6px solid #fff;}
96
- @media(prefers-color-scheme:dark){.rte-float-arrow::before{border-bottom-color:#444;}.rte-float-arrow::after{border-bottom-color:#222;}}
141
+ .rte-float-arrow::before{top:0;border-bottom:7px solid var(--rte-float-arrow-border);}
142
+ .rte-float-arrow::after{top:1px;border-bottom:6px solid var(--rte-float-arrow-bg);}
97
143
  .rte-linkbar{min-width:340px;}
98
- .rte-linkbar input{flex:1;height:26px;border:1px solid #ccc;border-radius:3px;padding:0 8px;font-size:13px;outline:none;font-family:var(--font-sans);background:#fff;color:#222;min-width:0;}
99
- @media(prefers-color-scheme:dark){.rte-linkbar input{background:#1a1a1a;border-color:#555;color:#ddd;}}
100
- .rte-area{position:relative;background:#fff;}
101
- @media(prefers-color-scheme:dark){.rte-area{background:#141414;}}
102
- .rte-body{min-height:280px;outline:none;font-size:15px;line-height:1.75;color:#222;caret-color:#222;padding:18px 20px;}
103
- @media(prefers-color-scheme:dark){.rte-body{color:#ddd;caret-color:#ddd;}}
144
+ .rte-linkbar input{flex:1;height:26px;border:1px solid var(--rte-linkinput-border);border-radius:3px;padding:0 8px;font-size:13px;outline:none;font-family:var(--font-sans);background:var(--rte-linkinput-bg);color:var(--rte-linkinput);min-width:0;}
145
+ .rte-area{position:relative;background:var(--rte-area-bg);}
146
+ .rte-body{min-height:280px;outline:none;font-size:15px;line-height:1.75;color:var(--rte-body);caret-color:var(--rte-body);padding:18px 20px;}
104
147
  .rte-body h1{font-size:26px;font-weight:600;margin:0.6em 0 0.2em;}
105
148
  .rte-body h2{font-size:20px;font-weight:600;margin:0.6em 0 0.2em;}
106
149
  .rte-body h3{font-size:16px;font-weight:600;margin:0.6em 0 0.2em;}
@@ -108,38 +151,32 @@ var CSS = `
108
151
  .rte-body ol{list-style-type:decimal;padding-left:1.6em;margin:0.3em 0;}
109
152
  .rte-body ol ol{list-style-type:lower-alpha;padding-left:1.6em;}
110
153
  .rte-body ol ol ol{list-style-type:lower-roman;padding-left:1.6em;}
111
- .rte-body ol ol ol ol{list-style-type:decimal;padding-left:1.6em;}
154
+ .rte-body ol ol ol ol{list-style-type:upper-alpha;padding-left:1.6em;}
112
155
  .rte-body ul{list-style-type:disc;padding-left:1.6em;margin:0.3em 0;}
113
156
  .rte-body ul ul{list-style-type:circle;padding-left:1.6em;}
114
157
  .rte-body ul ul ul{list-style-type:square;padding-left:1.6em;}
115
158
  .rte-body li{margin:0.1em 0;}
116
159
  .rte-body a{color:#1a6fc4;text-decoration:underline;cursor:pointer;}
117
- .rte-body pre{background:#f4f4f4;border:1px solid #e0e0e0;border-radius:4px;padding:12px 14px;margin:0.6em 0;overflow-x:auto;}
160
+ .rte-body pre{background:var(--rte-pre-bg);border:1px solid var(--rte-pre-border);border-radius:4px;padding:12px 14px;margin:0.6em 0;overflow-x:auto;}
118
161
  .rte-body code{font-family:var(--font-mono);font-size:13px;}
119
162
  .rte-body:empty:before{content:attr(data-ph);color:#aaa;pointer-events:none;}
120
163
  .rte-body table{border-collapse:collapse;width:100%;margin:0.8em 0;}
121
- .rte-body td,.rte-body th{border:1px solid #ccc;padding:7px 10px;min-width:60px;text-align:left;vertical-align:top;}
122
- .rte-body th{background:#f5f5f5;font-weight:600;}
123
- @media(prefers-color-scheme:dark){.rte-body td,.rte-body th{border-color:#444;}.rte-body th{background:#2a2a2a;}}
164
+ .rte-body td,.rte-body th{border:1px solid var(--rte-table-border);padding:7px 10px;min-width:60px;text-align:left;vertical-align:top;}
165
+ .rte-body th{background:var(--rte-th-bg);font-weight:600;}
124
166
  .rte-body td.rte-sel,.rte-body th.rte-sel{background:rgba(26,95,180,0.15)!important;outline:2px solid #1a5fb4;outline-offset:-2px;}
125
167
  .rte-body img{max-width:100%;height:auto;display:block;margin:4px 0;cursor:pointer;}
126
168
  .rte-body figure{margin:0.8em 0;display:block;overflow:hidden;}
127
169
  .rte-body figcaption{font-size:13px;color:#666;text-align:center;padding:4px 0;outline:none;clear:both;display:block;}
128
170
  .rte-code{min-height:280px;width:100%;background:#1e1e2e;color:#cdd6f4;font-family:var(--font-mono);font-size:13px;line-height:1.6;padding:18px 20px;border:none;outline:none;resize:vertical;}
129
- .rte-footer{font-size:11px;color:#999;padding:4px 20px 5px;border-top:1px solid #e8e8e8;background:#fafafa;}
130
- @media(prefers-color-scheme:dark){.rte-footer{border-color:#2a2a2a;background:#1a1a1a;color:#555;}}
131
- .rte-ie-panel{position:absolute;z-index:52;background:#fff;border:1px solid #d0d0d0;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:210px;overflow:hidden;}
132
- @media(prefers-color-scheme:dark){.rte-ie-panel{background:#222;border-color:#444;}}
133
- .rte-ie-tabs{display:flex;border-bottom:1px solid #eee;}
134
- @media(prefers-color-scheme:dark){.rte-ie-tabs{border-color:#333;}}
171
+ .rte-footer{font-size:11px;color:var(--rte-footer);padding:4px 20px 5px;border-top:1px solid var(--rte-footer-border);background:var(--rte-footer-bg);}
172
+ .rte-ie-panel{position:absolute;z-index:52;background:var(--rte-iepanel-bg);border:1px solid var(--rte-iepanel-border);border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);width:210px;overflow:hidden;}
173
+ .rte-ie-tabs{display:flex;border-bottom:1px solid var(--rte-ietabs-border);}
135
174
  .rte-ie-tab{flex:1;padding:7px 4px;font-size:11px;font-weight:500;background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;color:#888;font-family:var(--font-sans);}
136
175
  .rte-ie-tab.active{color:#1a5fb4;border-bottom-color:#1a5fb4;}
137
- .rte-ie-tab:hover{background:#f8f8f8;}
138
- @media(prefers-color-scheme:dark){.rte-ie-tab:hover{background:#2a2a2a;}}
176
+ .rte-ie-tab:hover{background:var(--rte-ietab-hover-bg);}
139
177
  .rte-ie-body{padding:10px;display:flex;flex-direction:column;gap:8px;}
140
178
  .rte-ie-label{font-size:10px;color:#888;margin-bottom:3px;font-family:var(--font-sans);}
141
- .rte-ie-input{width:100%;height:26px;border:1px solid #ccc;border-radius:4px;padding:0 8px;font-size:11px;outline:none;font-family:var(--font-sans);background:#fff;color:#222;}
142
- @media(prefers-color-scheme:dark){.rte-ie-input{background:#1a1a1a;border-color:#444;color:#ddd;}}
179
+ .rte-ie-input{width:100%;height:26px;border:1px solid var(--rte-ieinput-border);border-radius:4px;padding:0 8px;font-size:11px;outline:none;font-family:var(--font-sans);background:var(--rte-ieinput-bg);color:var(--rte-ieinput);}
143
180
  .rte-ie-row{display:flex;gap:4px;}
144
181
  .rte-ie-seg-btn{flex:1;height:26px;font-size:11px;border:1px solid #ccc;border-radius:4px;background:transparent;color:#444;cursor:pointer;font-family:var(--font-sans);transition:all 0.1s;}
145
182
  .rte-ie-seg-btn.active{background:#d0e4ff;border-color:#1a5fb4;color:#1a5fb4;}
@@ -149,12 +186,13 @@ var CSS = `
149
186
  .rte-ie-apply{flex:1;height:26px;background:#1a6fc4;color:#fff;border:none;border-radius:4px;font-size:11px;font-weight:600;cursor:pointer;}
150
187
  .rte-ie-remove{flex:1;height:26px;background:#fdecea;color:#c0392b;border:1px solid #f5c6c2;border-radius:4px;font-size:11px;cursor:pointer;}
151
188
  .rte-handle{position:absolute;width:10px;height:10px;background:#fff;border:2px solid #1a5fb4;border-radius:2px;pointer-events:all;z-index:53;}
152
- .customeditor {
153
- max-height: 350px;
154
- overflow-y: auto;
155
- position: relative;
156
- }
157
-
189
+ .rte-body blockquote{background-color: rgb(245, 243, 255);
190
+ border-left: 4px solid rgb(100, 80, 220);
191
+ margin: 8px 0;
192
+ padding: 10px 16px;
193
+ font-style: italic;
194
+ color: rgb(75, 85, 99);
195
+ border-radius: 0 4px 4px 0;}
158
196
  `;
159
197
 
160
198
  // src/rte/utils.ts
@@ -1129,7 +1167,7 @@ function ImageEditor({ img, containerRef, onClose, onDelete, onChange }) {
1129
1167
 
1130
1168
  // src/RichTextEditor.tsx
1131
1169
  import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1132
- function RichTextEditor({ value, onChange, toolbar }) {
1170
+ function RichTextEditor({ value, onChange, toolbar, theme }) {
1133
1171
  var _a;
1134
1172
  const editorRef = useRef4(null);
1135
1173
  const editorAreaRef = useRef4(null);
@@ -1191,6 +1229,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1191
1229
  }, []);
1192
1230
  const refresh = useCallback3(() => {
1193
1231
  var _a2, _b, _c, _d;
1232
+ fixListNesting();
1194
1233
  const raw = document.queryCommandValue("formatBlock").toLowerCase().replace(/[<>]/g, "");
1195
1234
  const block = ["h1", "h2", "h3"].includes(raw) ? raw : "p";
1196
1235
  setColor(getColorAtCursor(editorRef.current));
@@ -1232,6 +1271,78 @@ function RichTextEditor({ value, onChange, toolbar }) {
1232
1271
  if (!((_a3 = p.textContent) == null ? void 0 : _a3.trim()) && !p.querySelector("img, br")) p.remove();
1233
1272
  });
1234
1273
  }, []);
1274
+ const tryAutoList = useCallback3(() => {
1275
+ var _a2, _b, _c, _d, _e, _f;
1276
+ const sel = window.getSelection();
1277
+ if (!(sel == null ? void 0 : sel.rangeCount) || !sel.getRangeAt(0).collapsed) return false;
1278
+ const range = sel.getRangeAt(0);
1279
+ const anchor = range.startContainer;
1280
+ if (anchor.nodeType !== Node.TEXT_NODE) return false;
1281
+ const textBefore = (_b = (_a2 = anchor.textContent) == null ? void 0 : _a2.slice(0, range.startOffset)) != null ? _b : "";
1282
+ const marker = textBefore.trim();
1283
+ if (!marker) return false;
1284
+ const block = (_c = anchor.parentElement) == null ? void 0 : _c.closest("p, div");
1285
+ if (!block || ((_d = block.textContent) != null ? _d : "").trim() !== marker) return false;
1286
+ if (block.tagName === "LI") return false;
1287
+ const romanToInt = (s) => {
1288
+ var _a3;
1289
+ const map = { i: 1, v: 5, x: 10, l: 50, c: 100, d: 500, m: 1e3 };
1290
+ let n = 0, prev = 0;
1291
+ for (const ch of s.toLowerCase().split("").reverse()) {
1292
+ const v = (_a3 = map[ch]) != null ? _a3 : 0;
1293
+ n += v < prev ? -v : v;
1294
+ prev = v;
1295
+ }
1296
+ return n;
1297
+ };
1298
+ let spec = null;
1299
+ const dM = marker.match(/^(\d+)\.$/), aM = marker.match(/^([a-z])\.$/);
1300
+ const AM = marker.match(/^([A-Z])\.$/), rM = marker.match(/^([ivxlcdm]{1,6})\.$/i);
1301
+ if (/^[-*]$/.test(marker)) spec = { tag: "ul" };
1302
+ else if (dM) spec = { tag: "ol", olType: "1", start: parseInt(dM[1]) };
1303
+ else if (aM) spec = { tag: "ol", olType: "a", start: aM[1].charCodeAt(0) - 96 };
1304
+ else if (AM) spec = { tag: "ol", olType: "A", start: AM[1].charCodeAt(0) - 64 };
1305
+ else if (rM && romanToInt(rM[1]) > 0) spec = { tag: "ol", olType: "i", start: romanToInt(rM[1]) };
1306
+ if (!spec) return false;
1307
+ const listMatches = (el) => {
1308
+ var _a3;
1309
+ if (spec.tag === "ul") return el.tagName === "UL";
1310
+ if (el.tagName !== "OL") return false;
1311
+ return (el.getAttribute("type") || "1") === ((_a3 = spec.olType) != null ? _a3 : "1");
1312
+ };
1313
+ const parentLi = ((_e = block.parentElement) == null ? void 0 : _e.tagName) === "LI" ? block.parentElement : null;
1314
+ let targetList = null;
1315
+ let sib = block.previousElementSibling;
1316
+ while (sib) {
1317
+ if (listMatches(sib)) {
1318
+ targetList = sib;
1319
+ break;
1320
+ }
1321
+ if (!parentLi && ((_f = sib.textContent) != null ? _f : "").trim()) break;
1322
+ sib = sib.previousElementSibling;
1323
+ }
1324
+ const newLi = document.createElement("li");
1325
+ newLi.appendChild(document.createElement("br"));
1326
+ if (targetList) {
1327
+ targetList.appendChild(newLi);
1328
+ block.remove();
1329
+ } else {
1330
+ const list = document.createElement(spec.tag);
1331
+ if (spec.tag === "ol") {
1332
+ if (spec.olType && spec.olType !== "1") list.setAttribute("type", spec.olType);
1333
+ if (spec.start && spec.start > 1) list.setAttribute("start", String(spec.start));
1334
+ }
1335
+ list.appendChild(newLi);
1336
+ block.replaceWith(list);
1337
+ }
1338
+ const r = document.createRange();
1339
+ r.setStart(newLi, 0);
1340
+ r.collapse(true);
1341
+ sel.removeAllRanges();
1342
+ sel.addRange(r);
1343
+ refresh();
1344
+ return true;
1345
+ }, [refresh]);
1235
1346
  const exec = useCallback3((cmd, val = null) => {
1236
1347
  var _a2;
1237
1348
  (_a2 = editorRef.current) == null ? void 0 : _a2.focus();
@@ -1286,9 +1397,99 @@ function RichTextEditor({ value, onChange, toolbar }) {
1286
1397
  }
1287
1398
  }, [applySelection]);
1288
1399
  const handleKeyDown = useCallback3((e) => {
1289
- var _a2, _b;
1400
+ var _a2, _b, _c, _d, _e, _f, _g, _h;
1290
1401
  clearSelection();
1291
1402
  clearImageSel();
1403
+ if (e.key === " ") {
1404
+ if (tryAutoList()) {
1405
+ e.preventDefault();
1406
+ return;
1407
+ }
1408
+ }
1409
+ if (e.key === "Enter" && !e.shiftKey && !e.ctrlKey && !e.metaKey) {
1410
+ const sel = window.getSelection();
1411
+ if (sel == null ? void 0 : sel.rangeCount) {
1412
+ const anchor = sel.getRangeAt(0).startContainer;
1413
+ const p = (_a2 = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor) == null ? void 0 : _a2.closest("p");
1414
+ const li = ((_b = p == null ? void 0 : p.parentElement) == null ? void 0 : _b.tagName) === "LI" ? p.parentElement : null;
1415
+ const parentList = li == null ? void 0 : li.parentElement;
1416
+ if (p && li && ((parentList == null ? void 0 : parentList.tagName) === "OL" || (parentList == null ? void 0 : parentList.tagName) === "UL")) {
1417
+ e.preventDefault();
1418
+ const pIsEmpty = !((_c = p.textContent) == null ? void 0 : _c.trim()) && !p.querySelector("img, table");
1419
+ if (pIsEmpty) {
1420
+ const newLi = document.createElement("li");
1421
+ newLi.appendChild(document.createElement("br"));
1422
+ li.insertAdjacentElement("afterend", newLi);
1423
+ p.remove();
1424
+ const r = document.createRange();
1425
+ r.setStart(newLi, 0);
1426
+ r.collapse(true);
1427
+ sel.removeAllRanges();
1428
+ sel.addRange(r);
1429
+ } else {
1430
+ const newP = document.createElement("p");
1431
+ newP.appendChild(document.createElement("br"));
1432
+ p.insertAdjacentElement("afterend", newP);
1433
+ const r = document.createRange();
1434
+ r.setStart(newP, 0);
1435
+ r.collapse(true);
1436
+ sel.removeAllRanges();
1437
+ sel.addRange(r);
1438
+ }
1439
+ refresh();
1440
+ return;
1441
+ }
1442
+ }
1443
+ }
1444
+ if (e.key === "Backspace" && !e.ctrlKey && !e.metaKey && !e.altKey) {
1445
+ const sel = window.getSelection();
1446
+ if ((sel == null ? void 0 : sel.rangeCount) && sel.getRangeAt(0).collapsed) {
1447
+ const anchor = sel.getRangeAt(0).startContainer;
1448
+ const li = (_d = anchor.nodeType === Node.TEXT_NODE ? anchor.parentElement : anchor) == null ? void 0 : _d.closest("li");
1449
+ if (li) {
1450
+ const isEmpty = !((_e = li.textContent) == null ? void 0 : _e.trim()) && !li.querySelector("img, table, ol, ul");
1451
+ const parentList = li.parentElement;
1452
+ const grandParent = parentList == null ? void 0 : parentList.parentElement;
1453
+ if (isEmpty && parentList) {
1454
+ const prevLi = ((_f = li.previousElementSibling) == null ? void 0 : _f.tagName) === "LI" ? li.previousElementSibling : null;
1455
+ if (prevLi) {
1456
+ e.preventDefault();
1457
+ li.remove();
1458
+ const p = document.createElement("p");
1459
+ p.appendChild(document.createElement("br"));
1460
+ prevLi.appendChild(p);
1461
+ const r = document.createRange();
1462
+ r.setStart(p, 0);
1463
+ r.collapse(true);
1464
+ sel.removeAllRanges();
1465
+ sel.addRange(r);
1466
+ refresh();
1467
+ return;
1468
+ }
1469
+ const isNested = (grandParent == null ? void 0 : grandParent.tagName) === "LI" || (grandParent == null ? void 0 : grandParent.tagName) === "OL" || (grandParent == null ? void 0 : grandParent.tagName) === "UL";
1470
+ if (isNested && grandParent) {
1471
+ e.preventDefault();
1472
+ li.remove();
1473
+ const p = document.createElement("p");
1474
+ p.appendChild(document.createElement("br"));
1475
+ if (!parentList.querySelector("li")) {
1476
+ parentList.insertAdjacentElement("afterend", p);
1477
+ parentList.remove();
1478
+ } else {
1479
+ parentList.insertAdjacentElement("afterend", p);
1480
+ }
1481
+ const r = document.createRange();
1482
+ r.setStart(p, 0);
1483
+ r.collapse(true);
1484
+ sel.removeAllRanges();
1485
+ sel.addRange(r);
1486
+ refresh();
1487
+ return;
1488
+ }
1489
+ }
1490
+ }
1491
+ }
1492
+ }
1292
1493
  if (!e.ctrlKey && !e.metaKey && !e.altKey && e.key.length === 1) {
1293
1494
  const sel = window.getSelection();
1294
1495
  if (sel == null ? void 0 : sel.rangeCount) {
@@ -1311,8 +1512,8 @@ function RichTextEditor({ value, onChange, toolbar }) {
1311
1512
  }
1312
1513
  return;
1313
1514
  }
1314
- const node = (_a2 = window.getSelection()) == null ? void 0 : _a2.anchorNode;
1315
- const li = (node == null ? void 0 : node.nodeType) === 1 ? node.closest("li") : (_b = node == null ? void 0 : node.parentElement) == null ? void 0 : _b.closest("li");
1515
+ const node = (_g = window.getSelection()) == null ? void 0 : _g.anchorNode;
1516
+ const li = (node == null ? void 0 : node.nodeType) === 1 ? node.closest("li") : (_h = node == null ? void 0 : node.parentElement) == null ? void 0 : _h.closest("li");
1316
1517
  if (li) exec(e.shiftKey ? "outdent" : "indent");
1317
1518
  else document.execCommand("insertText", false, "\xA0\xA0\xA0\xA0");
1318
1519
  }
@@ -1330,7 +1531,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1330
1531
  exec("underline");
1331
1532
  }
1332
1533
  }
1333
- }, [exec, clearSelection, clearImageSel, fmt.block]);
1534
+ }, [exec, tryAutoList, clearSelection, clearImageSel, fmt.block]);
1334
1535
  const insertTable = (rows, cols) => {
1335
1536
  var _a2;
1336
1537
  (_a2 = editorRef.current) == null ? void 0 : _a2.focus();
@@ -1507,7 +1708,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1507
1708
  const show = (key) => !toolbar || toolbar.includes(key);
1508
1709
  return /* @__PURE__ */ jsxs6("div", { style: { padding: "1rem 0" }, children: [
1509
1710
  /* @__PURE__ */ jsx7("style", { children: CSS }),
1510
- /* @__PURE__ */ jsxs6("div", { className: "customeditor", style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
1711
+ /* @__PURE__ */ jsxs6("div", { className: `customeditor${theme ? ` rte-${theme}` : ""}`, style: { border: "1px solid #d8d8d8", borderRadius: 4, boxShadow: "0 1px 3px rgba(0,0,0,0.06)" }, children: [
1511
1712
  /* @__PURE__ */ jsxs6("div", { className: "rte-toolbar", children: [
1512
1713
  !isCode && /* @__PURE__ */ jsxs6(Fragment4, { children: [
1513
1714
  show("bold") && /* @__PURE__ */ jsx7(Btn, { onClick: () => exec("bold"), title: "Bold (Ctrl+B)", active: fmt.bold, style: { fontWeight: 800, fontFamily: "Georgia,serif" }, children: "B" }),
@@ -1523,7 +1724,7 @@ function RichTextEditor({ value, onChange, toolbar }) {
1523
1724
  active: showColor,
1524
1725
  style: { flexDirection: "column", gap: 1, padding: "3px 6px" },
1525
1726
  children: [
1526
- /* @__PURE__ */ jsx7("span", { style: { fontSize: 13, fontWeight: 800, fontFamily: "Georgia,serif", lineHeight: 1, color: "#222" }, children: "A" }),
1727
+ /* @__PURE__ */ jsx7("span", { style: { fontSize: 13, fontWeight: 800, fontFamily: "Georgia,serif", lineHeight: 1 }, children: "A" }),
1527
1728
  /* @__PURE__ */ jsx7("span", { className: "rte-swatch", style: { background: color } })
1528
1729
  ]
1529
1730
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malaya_jeeva/rich-text-editor",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Custom React Rich Text Editor",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",