@airoom/nextmin-react 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/SchemaForm.js +17 -2
- package/dist/components/SchemaSuggestionList.d.ts +7 -0
- package/dist/components/SchemaSuggestionList.js +43 -0
- package/dist/components/editor/TiptapEditor.d.ts +11 -0
- package/dist/components/editor/TiptapEditor.js +330 -0
- package/dist/components/editor/Toolbar.d.ts +7 -0
- package/dist/components/editor/Toolbar.js +99 -0
- package/dist/components/editor/components/CommandList.d.ts +7 -0
- package/dist/components/editor/components/CommandList.js +47 -0
- package/dist/components/editor/components/DistrictGridModal.d.ts +12 -0
- package/dist/components/editor/components/DistrictGridModal.js +67 -0
- package/dist/components/editor/components/ImageBubbleMenu.d.ts +6 -0
- package/dist/components/editor/components/ImageBubbleMenu.js +15 -0
- package/dist/components/editor/components/ImageComponent.d.ts +3 -0
- package/dist/components/editor/components/ImageComponent.js +45 -0
- package/dist/components/editor/components/SchemaInsertionModal.d.ts +15 -0
- package/dist/components/editor/components/SchemaInsertionModal.js +91 -0
- package/dist/components/editor/components/TableBubbleMenu.d.ts +6 -0
- package/dist/components/editor/components/TableBubbleMenu.js +8 -0
- package/dist/components/editor/extensions/Container.d.ts +2 -0
- package/dist/components/editor/extensions/Container.js +51 -0
- package/dist/components/editor/extensions/Grid.d.ts +3 -0
- package/dist/components/editor/extensions/Grid.js +89 -0
- package/dist/components/editor/extensions/Layout.d.ts +3 -0
- package/dist/components/editor/extensions/Layout.js +116 -0
- package/dist/components/editor/extensions/ResizableImage.d.ts +1 -0
- package/dist/components/editor/extensions/ResizableImage.js +52 -0
- package/dist/components/editor/extensions/SlashCommand.d.ts +15 -0
- package/dist/components/editor/extensions/SlashCommand.js +161 -0
- package/dist/components/editor/utils/upload.d.ts +1 -0
- package/dist/components/editor/utils/upload.js +49 -0
- package/dist/editor.css +460 -0
- package/dist/lib/upload.d.ts +1 -0
- package/dist/lib/upload.js +53 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/nextmin.css +1 -1
- package/dist/router/NextMinRouter.d.ts +1 -0
- package/dist/router/NextMinRouter.js +1 -0
- package/dist/views/list/useListData.js +4 -0
- package/package.json +34 -8
- package/tsconfig.json +8 -3
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Extension } from '@tiptap/core';
|
|
2
|
+
import Suggestion from '@tiptap/suggestion';
|
|
3
|
+
import { ReactRenderer } from '@tiptap/react';
|
|
4
|
+
import { CommandList } from '../components/CommandList';
|
|
5
|
+
import { List, LayoutTemplate, LayoutPanelLeft } from 'lucide-react'; // Assuming these icons are available
|
|
6
|
+
export const SlashCommand = Extension.create({
|
|
7
|
+
name: 'slashCommand',
|
|
8
|
+
addOptions() {
|
|
9
|
+
return {
|
|
10
|
+
suggestion: {
|
|
11
|
+
char: '/',
|
|
12
|
+
command: ({ editor, range }) => {
|
|
13
|
+
// Just delete the range (the "/") to clean up
|
|
14
|
+
editor.chain().focus().deleteRange(range).run();
|
|
15
|
+
},
|
|
16
|
+
items: ({ query }) => {
|
|
17
|
+
const allCommands = [
|
|
18
|
+
{
|
|
19
|
+
title: 'Bullet List',
|
|
20
|
+
description: 'Create a simple bullet list.',
|
|
21
|
+
icon: List,
|
|
22
|
+
command: ({ editor, range }) => {
|
|
23
|
+
editor.chain().focus().deleteRange(range).toggleBulletList().run();
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: '2 Columns',
|
|
28
|
+
description: 'Insert 2 responsive columns',
|
|
29
|
+
icon: LayoutTemplate,
|
|
30
|
+
command: ({ editor, range }) => {
|
|
31
|
+
editor
|
|
32
|
+
.chain()
|
|
33
|
+
.focus()
|
|
34
|
+
.deleteRange(range)
|
|
35
|
+
.insertContent('<p></p>') // Ensure separation
|
|
36
|
+
.insertContent('<div data-type="layout-row" data-cols="2"><div data-type="layout-column"><p></p></div><div data-type="layout-column"><p></p></div></div>')
|
|
37
|
+
.run();
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
title: '3 Columns',
|
|
42
|
+
description: 'Insert 3 responsive columns',
|
|
43
|
+
icon: LayoutPanelLeft,
|
|
44
|
+
command: ({ editor, range }) => {
|
|
45
|
+
editor
|
|
46
|
+
.chain()
|
|
47
|
+
.focus()
|
|
48
|
+
.deleteRange(range)
|
|
49
|
+
.insertContent('<p></p>') // Ensure separation
|
|
50
|
+
.insertContent('<div data-type="layout-row" data-cols="3"><div data-type="layout-column"><p></p></div><div data-type="layout-column"><p></p></div><div data-type="layout-column"><p></p></div></div>')
|
|
51
|
+
.run();
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
// Add other static commands here if any
|
|
55
|
+
];
|
|
56
|
+
// Filter commands based on query
|
|
57
|
+
return allCommands
|
|
58
|
+
.filter((item) => item.title.toLowerCase().startsWith(query.toLowerCase()))
|
|
59
|
+
.slice(0, 10);
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
addProseMirrorPlugins() {
|
|
65
|
+
return [
|
|
66
|
+
Suggestion({
|
|
67
|
+
editor: this.editor,
|
|
68
|
+
...this.options.suggestion,
|
|
69
|
+
}),
|
|
70
|
+
];
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
export const getSuggestionOptions = (items, onSelect) => ({
|
|
74
|
+
items: ({ query }) => {
|
|
75
|
+
return items
|
|
76
|
+
.filter((item) => item.modelName.toLowerCase().startsWith(query.toLowerCase()))
|
|
77
|
+
.slice(0, 10);
|
|
78
|
+
},
|
|
79
|
+
command: ({ editor, range }) => {
|
|
80
|
+
// For schema-only suggestions, we just delete the range.
|
|
81
|
+
// The actual selection logic (onSelect) is handled in the render function's command prop.
|
|
82
|
+
editor.chain().focus().deleteRange(range).run();
|
|
83
|
+
},
|
|
84
|
+
render: () => {
|
|
85
|
+
let component;
|
|
86
|
+
let popup = null;
|
|
87
|
+
let container = null;
|
|
88
|
+
return {
|
|
89
|
+
onStart: (props) => {
|
|
90
|
+
component = new ReactRenderer(CommandList, {
|
|
91
|
+
props: {
|
|
92
|
+
...props,
|
|
93
|
+
// Fix 1: Explicitly pass the command prop expected by CommandList
|
|
94
|
+
command: (item) => {
|
|
95
|
+
// If external callback provided, use it
|
|
96
|
+
if (onSelect) {
|
|
97
|
+
onSelect(item);
|
|
98
|
+
}
|
|
99
|
+
// CRITICAL: Call the original command to close the popup and delete the "/"
|
|
100
|
+
props.command(item);
|
|
101
|
+
},
|
|
102
|
+
items: props.items,
|
|
103
|
+
},
|
|
104
|
+
editor: props.editor,
|
|
105
|
+
});
|
|
106
|
+
// Create container for popup
|
|
107
|
+
container = document.createElement('div');
|
|
108
|
+
container.style.position = 'absolute';
|
|
109
|
+
container.style.zIndex = '9999';
|
|
110
|
+
container.style.display = 'none'; // Hidden until positioned
|
|
111
|
+
document.body.appendChild(container);
|
|
112
|
+
// Mount component
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
container.appendChild(component.element);
|
|
115
|
+
// Position it
|
|
116
|
+
const coords = props.clientRect?.();
|
|
117
|
+
if (coords && container) {
|
|
118
|
+
container.style.display = 'block';
|
|
119
|
+
container.style.left = `${coords.left}px`;
|
|
120
|
+
container.style.top = `${coords.bottom + 10}px`;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
onUpdate(props) {
|
|
124
|
+
component.updateProps({
|
|
125
|
+
...props,
|
|
126
|
+
// Fix 2: Ensure command prop is preserved during updates
|
|
127
|
+
command: (item) => {
|
|
128
|
+
if (onSelect) {
|
|
129
|
+
onSelect(item);
|
|
130
|
+
}
|
|
131
|
+
props.command(item);
|
|
132
|
+
},
|
|
133
|
+
items: props.items,
|
|
134
|
+
});
|
|
135
|
+
const coords = props.clientRect?.();
|
|
136
|
+
if (coords && container) {
|
|
137
|
+
container.style.left = `${coords.left}px`;
|
|
138
|
+
container.style.top = `${coords.bottom + 10}px`;
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
onKeyDown(props) {
|
|
142
|
+
if (props.event.key === 'Escape') {
|
|
143
|
+
if (container) {
|
|
144
|
+
container.remove();
|
|
145
|
+
container = null;
|
|
146
|
+
}
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
return component.ref?.onKeyDown(props);
|
|
151
|
+
},
|
|
152
|
+
onExit() {
|
|
153
|
+
if (container) {
|
|
154
|
+
container.remove();
|
|
155
|
+
container = null;
|
|
156
|
+
}
|
|
157
|
+
component.destroy();
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function uploadFile(file: File): Promise<string>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Utility to upload files reusing existing API logic
|
|
2
|
+
const DEFAULT_ENDPOINT = ((process.env.NEXT_PUBLIC_NEXTMIN_API_URL || '') + '/files').replace(/\/+$/, '') || '/files';
|
|
3
|
+
const defaultAuthHeaders = () => {
|
|
4
|
+
if (typeof window === 'undefined')
|
|
5
|
+
return {};
|
|
6
|
+
let token;
|
|
7
|
+
let apiKey;
|
|
8
|
+
try {
|
|
9
|
+
const raw = localStorage.getItem('nextmin.user');
|
|
10
|
+
if (raw) {
|
|
11
|
+
const u = JSON.parse(raw);
|
|
12
|
+
token = u?.token ?? u?.data?.token;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
catch { }
|
|
16
|
+
token = token ?? localStorage.getItem('nextmin.token') ?? undefined;
|
|
17
|
+
apiKey =
|
|
18
|
+
localStorage.getItem('nextmin.apiKey') ??
|
|
19
|
+
process.env.NEXT_PUBLIC_NEXTMIN_API_KEY;
|
|
20
|
+
const h = {};
|
|
21
|
+
if (token)
|
|
22
|
+
h.Authorization = `Bearer ${token}`;
|
|
23
|
+
if (apiKey)
|
|
24
|
+
h['x-api-key'] = apiKey;
|
|
25
|
+
return h;
|
|
26
|
+
};
|
|
27
|
+
export async function uploadFile(file) {
|
|
28
|
+
const headers = defaultAuthHeaders();
|
|
29
|
+
const endpoint = DEFAULT_ENDPOINT;
|
|
30
|
+
// XHR for progress support if needed, but fetch is simpler for now
|
|
31
|
+
const formData = new FormData();
|
|
32
|
+
formData.append('file', file);
|
|
33
|
+
const response = await fetch(endpoint, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: {
|
|
36
|
+
...headers
|
|
37
|
+
// Content-Type is set automatically by fetch with FormData
|
|
38
|
+
},
|
|
39
|
+
body: formData
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error('Upload failed');
|
|
43
|
+
}
|
|
44
|
+
const json = await response.json();
|
|
45
|
+
if (!json.success || !json.data || !json.data.length) {
|
|
46
|
+
throw new Error(json.message || 'Upload failed');
|
|
47
|
+
}
|
|
48
|
+
return json.data[0].url;
|
|
49
|
+
}
|
package/dist/editor.css
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
.editor-input {
|
|
2
|
+
min-height: 150px;
|
|
3
|
+
resize: none;
|
|
4
|
+
font-size: 15px;
|
|
5
|
+
caret-color: rgb(5, 5, 5);
|
|
6
|
+
display: block;
|
|
7
|
+
position: relative;
|
|
8
|
+
tab-size: 1;
|
|
9
|
+
outline: 0;
|
|
10
|
+
padding: 10px;
|
|
11
|
+
caret-color: #444;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.editor-placeholder {
|
|
15
|
+
color: #999;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
position: absolute;
|
|
18
|
+
text-overflow: ellipsis;
|
|
19
|
+
top: 15px;
|
|
20
|
+
left: 10px;
|
|
21
|
+
font-size: 15px;
|
|
22
|
+
user-select: none;
|
|
23
|
+
display: inline-block;
|
|
24
|
+
pointer-events: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.editor-text-bold {
|
|
28
|
+
font-weight: bold;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.editor-text-italic {
|
|
32
|
+
font-style: italic;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.editor-text-underline {
|
|
36
|
+
text-decoration: underline !important;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.image-resizer {
|
|
40
|
+
display: block;
|
|
41
|
+
width: 12px;
|
|
42
|
+
height: 12px;
|
|
43
|
+
position: absolute;
|
|
44
|
+
background-color: rgb(60, 132, 244);
|
|
45
|
+
border: 1px solid #fff;
|
|
46
|
+
z-index: 100 !important;
|
|
47
|
+
box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.editor-text-strikethrough {
|
|
51
|
+
text-decoration: line-through;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.editor-text-underlineStrikethrough {
|
|
55
|
+
text-decoration: underline line-through;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.editor-text-code {
|
|
59
|
+
background-color: rgb(240, 242, 245);
|
|
60
|
+
padding: 1px 0.25rem;
|
|
61
|
+
font-family: Menlo, Consolas, Monaco, monospace;
|
|
62
|
+
font-size: 94%;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.editor-link {
|
|
66
|
+
color: rgb(33, 111, 219);
|
|
67
|
+
text-decoration: none;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.editor-code {
|
|
71
|
+
background-color: rgb(240, 242, 245);
|
|
72
|
+
font-family: Menlo, Consolas, Monaco, monospace;
|
|
73
|
+
display: block;
|
|
74
|
+
padding: 8px 8px 8px 52px;
|
|
75
|
+
line-height: 1.53;
|
|
76
|
+
font-size: 13px;
|
|
77
|
+
margin: 0;
|
|
78
|
+
margin-top: 8px;
|
|
79
|
+
margin-bottom: 8px;
|
|
80
|
+
tab-size: 2;
|
|
81
|
+
overflow-x: auto;
|
|
82
|
+
position: relative;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.editor-code:before {
|
|
86
|
+
content: attr(data-gutter);
|
|
87
|
+
position: absolute;
|
|
88
|
+
background-color: #eee;
|
|
89
|
+
left: 0;
|
|
90
|
+
top: 0;
|
|
91
|
+
border-right: 1px solid #ccc;
|
|
92
|
+
padding: 8px;
|
|
93
|
+
color: #777;
|
|
94
|
+
white-space: pre-wrap;
|
|
95
|
+
text-align: right;
|
|
96
|
+
min-width: 25px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.editor-paragraph {
|
|
100
|
+
margin: 0;
|
|
101
|
+
margin-bottom: 8px;
|
|
102
|
+
position: relative;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.editor-heading-h1 {
|
|
106
|
+
font-size: 24px;
|
|
107
|
+
color: rgb(5, 5, 5);
|
|
108
|
+
font-weight: bold;
|
|
109
|
+
margin: 0;
|
|
110
|
+
margin-bottom: 12px;
|
|
111
|
+
padding: 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.editor-heading-h2 {
|
|
115
|
+
font-size: 15px;
|
|
116
|
+
color: rgb(101, 103, 107);
|
|
117
|
+
font-weight: bold;
|
|
118
|
+
margin: 0;
|
|
119
|
+
margin-top: 10px;
|
|
120
|
+
padding: 0;
|
|
121
|
+
text-transform: uppercase;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.editor-quote {
|
|
125
|
+
margin: 0;
|
|
126
|
+
margin-left: 20px;
|
|
127
|
+
font-size: 15px;
|
|
128
|
+
color: rgb(101, 103, 107);
|
|
129
|
+
border-left-color: rgb(206, 208, 212);
|
|
130
|
+
border-left-width: 4px;
|
|
131
|
+
border-left-style: solid;
|
|
132
|
+
padding-left: 16px;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.editor-list-ol {
|
|
136
|
+
padding: 0;
|
|
137
|
+
margin: 0;
|
|
138
|
+
margin-left: 20px;
|
|
139
|
+
list-style-type: decimal;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.editor-list-ul {
|
|
143
|
+
padding: 0;
|
|
144
|
+
margin: 0;
|
|
145
|
+
margin-left: 20px;
|
|
146
|
+
list-style-type: disc;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.editor-listitem {
|
|
150
|
+
margin: 8px 32px 8px 32px;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.editor-nested-listitem {
|
|
154
|
+
list-style-type: none;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Image Resizer Styles */
|
|
158
|
+
.editor-image {
|
|
159
|
+
cursor: default;
|
|
160
|
+
display: inline-block;
|
|
161
|
+
position: relative;
|
|
162
|
+
user-select: none;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.editor-image img {
|
|
166
|
+
max-width: 100%;
|
|
167
|
+
cursor: default;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.editor-image.focused {
|
|
171
|
+
outline: 2px solid rgb(60, 132, 244);
|
|
172
|
+
user-select: none;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
.image-resizer-n {
|
|
178
|
+
top: -6px;
|
|
179
|
+
left: 48%;
|
|
180
|
+
cursor: n-resize;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.image-resizer-ne {
|
|
184
|
+
top: -6px;
|
|
185
|
+
right: -6px;
|
|
186
|
+
cursor: ne-resize;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.image-resizer-e {
|
|
190
|
+
bottom: 48%;
|
|
191
|
+
right: -6px;
|
|
192
|
+
cursor: e-resize;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.image-resizer-se {
|
|
196
|
+
bottom: -6px;
|
|
197
|
+
right: -6px;
|
|
198
|
+
cursor: se-resize;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.image-resizer-s {
|
|
202
|
+
bottom: -6px;
|
|
203
|
+
left: 48%;
|
|
204
|
+
cursor: s-resize;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.image-resizer-sw {
|
|
208
|
+
bottom: -6px;
|
|
209
|
+
left: -6px;
|
|
210
|
+
cursor: sw-resize;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.image-resizer-w {
|
|
214
|
+
bottom: 48%;
|
|
215
|
+
left: -6px;
|
|
216
|
+
cursor: w-resize;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.image-resizer-nw {
|
|
220
|
+
top: -6px;
|
|
221
|
+
left: -6px;
|
|
222
|
+
cursor: nw-resize;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.editor-table {
|
|
226
|
+
border-collapse: collapse;
|
|
227
|
+
border-spacing: 0;
|
|
228
|
+
max-width: 100%;
|
|
229
|
+
overflow-y: scroll;
|
|
230
|
+
table-layout: fixed;
|
|
231
|
+
width: 100%;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.editor-tableRow {}
|
|
235
|
+
|
|
236
|
+
.editor-tableCell {
|
|
237
|
+
border: 1px solid #bbb;
|
|
238
|
+
min-width: 75px;
|
|
239
|
+
padding: 8px;
|
|
240
|
+
position: relative;
|
|
241
|
+
vertical-align: top;
|
|
242
|
+
z-index: 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.editor-tableCellHeader {
|
|
246
|
+
background-color: #f2f3f5;
|
|
247
|
+
text-align: start;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.editor-layout-container {
|
|
251
|
+
display: grid;
|
|
252
|
+
gap: 10px;
|
|
253
|
+
margin: 10px 0;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.editor-layout-item {
|
|
257
|
+
border: 1px dashed #ddd;
|
|
258
|
+
padding: 8px;
|
|
259
|
+
min-height: 50px;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* ========================================================================= */
|
|
263
|
+
/* MERGED: NextMin Custom Editor Components (Grid, Layout, Image) */
|
|
264
|
+
/* ========================================================================= */
|
|
265
|
+
|
|
266
|
+
/* Editor Grid System (replacing Tailwind) */
|
|
267
|
+
|
|
268
|
+
/* Grid Container */
|
|
269
|
+
.nm-editor-grid {
|
|
270
|
+
display: grid;
|
|
271
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
272
|
+
gap: 1.5rem;
|
|
273
|
+
/* gap-6 equivalent */
|
|
274
|
+
margin-top: 1rem;
|
|
275
|
+
margin-bottom: 1rem;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@media (min-width: 640px) {
|
|
279
|
+
.nm-editor-grid {
|
|
280
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
@media (min-width: 768px) {
|
|
285
|
+
.nm-editor-grid {
|
|
286
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* Layout Rows */
|
|
291
|
+
.nm-editor-row-1 {
|
|
292
|
+
display: grid;
|
|
293
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
294
|
+
gap: 1rem;
|
|
295
|
+
margin-top: 1.5rem;
|
|
296
|
+
margin-bottom: 1.5rem;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.nm-editor-row-2 {
|
|
300
|
+
display: grid;
|
|
301
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
302
|
+
gap: 1rem;
|
|
303
|
+
margin-top: 1rem;
|
|
304
|
+
margin-bottom: 1rem;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@media (min-width: 768px) {
|
|
308
|
+
.nm-editor-row-2 {
|
|
309
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.nm-editor-row-3 {
|
|
314
|
+
display: grid;
|
|
315
|
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
316
|
+
gap: 1rem;
|
|
317
|
+
margin-top: 1rem;
|
|
318
|
+
margin-bottom: 1rem;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@media (min-width: 768px) {
|
|
322
|
+
.nm-editor-row-3 {
|
|
323
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
/* Grid Item Wrapper (div) */
|
|
329
|
+
/* Grid Item (Card) */
|
|
330
|
+
.nm-editor-grid-card {
|
|
331
|
+
/* Container Styles */
|
|
332
|
+
border-width: 1px;
|
|
333
|
+
border-style: solid;
|
|
334
|
+
border-color: #e5e7eb;
|
|
335
|
+
/* gray-200 */
|
|
336
|
+
border-radius: var(--nm-grid-radius, 0.5rem);
|
|
337
|
+
/* rounded-lg with override */
|
|
338
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
339
|
+
/* shadow-sm */
|
|
340
|
+
background-color: var(--nm-grid-card-bg, #ffffff);
|
|
341
|
+
overflow: hidden;
|
|
342
|
+
|
|
343
|
+
/* Transition */
|
|
344
|
+
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
|
345
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
346
|
+
transition-duration: 150ms;
|
|
347
|
+
|
|
348
|
+
/* Content/Layout Styles */
|
|
349
|
+
display: flex;
|
|
350
|
+
flex-direction: column;
|
|
351
|
+
align-items: center;
|
|
352
|
+
justify-content: center;
|
|
353
|
+
text-align: center;
|
|
354
|
+
width: 100%;
|
|
355
|
+
height: 100%;
|
|
356
|
+
padding: 10px;
|
|
357
|
+
/* p-5 */
|
|
358
|
+
|
|
359
|
+
/* Text Styles */
|
|
360
|
+
font-weight: 500;
|
|
361
|
+
font-size: 1rem;
|
|
362
|
+
color: #374151;
|
|
363
|
+
/* gray-700 */
|
|
364
|
+
text-decoration: none !important;
|
|
365
|
+
cursor: pointer;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.nm-editor-grid-card:hover {
|
|
369
|
+
background-color: #f9fafb;
|
|
370
|
+
/* gray-50 */
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* Ensure content inside grid cards is compact */
|
|
374
|
+
.nm-editor-grid-card p {
|
|
375
|
+
margin: 0 !important;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/* Dark Mode support */
|
|
379
|
+
.dark .nm-editor-grid-card {
|
|
380
|
+
border-color: #1f2937;
|
|
381
|
+
/* gray-800 */
|
|
382
|
+
background-color: #18181b;
|
|
383
|
+
/* zinc-900 */
|
|
384
|
+
color: #e5e7eb;
|
|
385
|
+
/* gray-200 */
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.dark .nm-editor-grid-card:hover {
|
|
389
|
+
background-color: #27272a;
|
|
390
|
+
/* zinc-800 */
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
/* Layout Column */
|
|
395
|
+
.nm-editor-col {
|
|
396
|
+
width: 100%;
|
|
397
|
+
height: 100%;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* Image Component Styles */
|
|
401
|
+
.nm-editor-w-full {
|
|
402
|
+
width: 100%;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.nm-editor-img {
|
|
406
|
+
border-radius: 0.125rem;
|
|
407
|
+
/* rounded-sm */
|
|
408
|
+
max-width: 100%;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.nm-editor-img-wrapper {
|
|
412
|
+
position: relative;
|
|
413
|
+
line-height: 1;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.nm-editor-img-container {
|
|
417
|
+
position: relative;
|
|
418
|
+
display: inline-flex;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.nm-editor-ring-selected {
|
|
422
|
+
border-radius: 0.125rem;
|
|
423
|
+
box-shadow: 0 0 0 2px var(--nm-primary, #3b82f6);
|
|
424
|
+
/* ring-2 ring-primary */
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.nm-editor-group {
|
|
428
|
+
/* placeholder for group if needed */
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* Table Resizing */
|
|
432
|
+
.resize-cursor {
|
|
433
|
+
cursor: col-resize;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.column-resize-handle {
|
|
437
|
+
background-color: #3b82f6;
|
|
438
|
+
/* blue-500 */
|
|
439
|
+
bottom: -2px;
|
|
440
|
+
pointer-events: none;
|
|
441
|
+
position: absolute;
|
|
442
|
+
right: -2px;
|
|
443
|
+
top: 0;
|
|
444
|
+
width: 4px;
|
|
445
|
+
z-index: 10;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
/* Standalone Container */
|
|
450
|
+
.nm-editor-container {
|
|
451
|
+
display: block;
|
|
452
|
+
width: 100%;
|
|
453
|
+
margin-top: 1.5rem;
|
|
454
|
+
margin-bottom: 1.5rem;
|
|
455
|
+
overflow: hidden;
|
|
456
|
+
/* Default padding if user puts text directly */
|
|
457
|
+
padding: 1rem;
|
|
458
|
+
border: 1px dashed transparent;
|
|
459
|
+
/* Helps selection visualization if needed */
|
|
460
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function uploadFile(file: File): Promise<string | null>;
|