notra-editor 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,76 @@
2
2
  Editor-specific Variables
3
3
  ===================== */
4
4
  .notra-editor {
5
+ overflow: auto;
6
+
5
7
  --notra-cursor-color: rgba(98, 41, 255, 1);
6
8
  --notra-selection-color: rgba(157, 138, 255, 0.2);
7
9
  --notra-placeholder-color: rgba(40, 44, 51, 0.42);
10
+
11
+ /* Toolbar design tokens (from Tiptap simple-next) */
12
+ --white: rgba(255, 255, 255, 1);
13
+ --black: rgba(14, 14, 17, 1);
14
+ --transparent: rgba(255, 255, 255, 0);
15
+
16
+ /* Gray alpha scale (light mode) */
17
+ --tt-gray-light-a-50: rgba(56, 56, 56, 0.04);
18
+ --tt-gray-light-a-100: rgba(15, 22, 36, 0.05);
19
+ --tt-gray-light-a-200: rgba(37, 39, 45, 0.1);
20
+ --tt-gray-light-a-300: rgba(47, 50, 55, 0.2);
21
+ --tt-gray-light-a-400: rgba(40, 44, 51, 0.42);
22
+ --tt-gray-light-a-500: rgba(52, 55, 60, 0.64);
23
+ --tt-gray-light-a-600: rgba(36, 39, 46, 0.78);
24
+ --tt-gray-light-a-700: rgba(35, 37, 42, 0.87);
25
+ --tt-gray-light-a-800: rgba(30, 32, 36, 0.95);
26
+ --tt-gray-light-a-900: rgba(29, 30, 32, 0.98);
27
+
28
+ /* Gray solid scale (light mode) */
29
+ --tt-gray-light-200: rgba(234, 234, 235, 1);
30
+
31
+ /* Radius & transitions */
32
+ --tt-radius-lg: 0.75rem;
33
+ --tt-transition-duration-default: 0.2s;
34
+ --tt-transition-easing-default: cubic-bezier(0.46, 0.03, 0.52, 0.96);
35
+
36
+ /* Toolbar */
37
+ --tt-toolbar-height: 2.75rem;
38
+ --tt-toolbar-bg-color: var(--white);
39
+ --tt-toolbar-border-color: var(--tt-gray-light-a-100);
40
+
41
+ /* Ghost button colors */
42
+ --tt-button-default-bg-color: var(--transparent);
43
+ --tt-button-hover-bg-color: var(--tt-gray-light-200);
44
+ --tt-button-disabled-bg-color: var(--transparent);
45
+ --tt-button-default-icon-color: var(--tt-gray-light-a-600);
46
+ --tt-button-hover-icon-color: var(--tt-gray-light-a-900);
47
+ --tt-button-disabled-icon-color: var(--tt-gray-light-a-400);
48
+
49
+ /* Separator */
50
+ --tt-separator-color: var(--tt-gray-light-a-200);
51
+ }
52
+
53
+ /* =====================
54
+ Editor Layout
55
+ ===================== */
56
+ .notra-editor .notra-editor-content {
57
+ max-width: 648px;
58
+ width: 100%;
59
+ margin: 0 auto;
60
+ height: 100%;
61
+ display: flex;
62
+ flex-direction: column;
63
+ flex: 1;
64
+ }
65
+
66
+ .notra-editor .notra-editor-content .tiptap.ProseMirror {
67
+ flex: 1;
68
+ padding: 3rem 3rem 30vh;
69
+ }
70
+
71
+ @media screen and (max-width: 480px) {
72
+ .notra-editor .notra-editor-content .tiptap.ProseMirror {
73
+ padding: 1rem 1.5rem 30vh;
74
+ }
8
75
  }
9
76
 
10
77
  /* =====================
@@ -74,3 +141,174 @@
74
141
  width: 100%;
75
142
  height: 0.188rem;
76
143
  }
144
+
145
+ /* =====================
146
+ Toolbar
147
+ ===================== */
148
+ .notra-editor .tiptap-toolbar {
149
+ display: flex;
150
+ align-items: center;
151
+ gap: 0.25rem;
152
+ }
153
+
154
+ .notra-editor .tiptap-toolbar[data-variant='fixed'] {
155
+ position: sticky;
156
+ top: 0;
157
+ z-index: 50;
158
+ width: 100%;
159
+ min-height: var(--tt-toolbar-height);
160
+ background: var(--tt-toolbar-bg-color);
161
+ border-bottom: 1px solid var(--tt-toolbar-border-color);
162
+ padding: 0 0.5rem;
163
+ overflow-x: auto;
164
+ overscroll-behavior-x: contain;
165
+ -webkit-overflow-scrolling: touch;
166
+ scrollbar-width: none;
167
+ -ms-overflow-style: none;
168
+ }
169
+
170
+ .notra-editor .tiptap-toolbar[data-variant='fixed']::-webkit-scrollbar {
171
+ display: none;
172
+ }
173
+
174
+ .notra-editor .tiptap-toolbar-group {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: 0.125rem;
178
+ }
179
+
180
+ .notra-editor .tiptap-toolbar-group:empty {
181
+ display: none;
182
+ }
183
+
184
+ /* =====================
185
+ Separator
186
+ ===================== */
187
+ .notra-editor .tiptap-separator {
188
+ flex-shrink: 0;
189
+ background-color: var(--tt-separator-color);
190
+ }
191
+
192
+ .notra-editor .tiptap-separator[data-orientation='vertical'] {
193
+ height: 1.5rem;
194
+ width: 1px;
195
+ }
196
+
197
+ .notra-editor .tiptap-separator[data-orientation='horizontal'] {
198
+ height: 1px;
199
+ width: 100%;
200
+ margin: 0.5rem 0;
201
+ }
202
+
203
+ /* =====================
204
+ Button
205
+ ===================== */
206
+ .notra-editor .tiptap-button {
207
+ font-size: 0.875rem;
208
+ font-weight: 500;
209
+ line-height: 1.15;
210
+ height: 2rem;
211
+ min-width: 2rem;
212
+ border: none;
213
+ padding: 0.5rem;
214
+ gap: 0.25rem;
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ border-radius: var(--tt-radius-lg);
219
+ cursor: pointer;
220
+ background-color: var(--tt-button-default-bg-color);
221
+ color: var(--tt-button-default-icon-color);
222
+ transition-property: background-color, color, opacity;
223
+ transition-duration: var(--tt-transition-duration-default);
224
+ transition-timing-function: var(--tt-transition-easing-default);
225
+ }
226
+
227
+ .notra-editor .tiptap-button:focus-visible {
228
+ outline: none;
229
+ }
230
+
231
+ .notra-editor .tiptap-button:hover:not([disabled]) {
232
+ background-color: var(--tt-button-hover-bg-color);
233
+ color: var(--tt-button-hover-icon-color);
234
+ }
235
+
236
+ .notra-editor .tiptap-button:disabled {
237
+ background-color: var(--tt-button-disabled-bg-color);
238
+ color: var(--tt-button-disabled-icon-color);
239
+ cursor: default;
240
+ }
241
+
242
+ /* =====================
243
+ Additional Variables
244
+ ===================== */
245
+ .notra-editor {
246
+ --tt-brand-color-500: rgba(98, 41, 255, 1);
247
+ --tt-shadow-elevated-md:
248
+ 0px 16px 48px 0px rgba(17, 24, 39, 0.04),
249
+ 0px 12px 24px 0px rgba(17, 24, 39, 0.04),
250
+ 0px 6px 8px 0px rgba(17, 24, 39, 0.02),
251
+ 0px 2px 3px 0px rgba(17, 24, 39, 0.02);
252
+ --tt-radius-md: 0.5rem;
253
+
254
+ /* Dropdown menu */
255
+ --tt-dropdown-menu-bg-color: var(--white);
256
+ --tt-dropdown-menu-text-color: var(--tt-gray-light-a-600);
257
+ }
258
+
259
+ /* =====================
260
+ Button Active State
261
+ ===================== */
262
+ .notra-editor .tiptap-button[data-active-state='on'] {
263
+ background-color: var(--tt-gray-light-a-100);
264
+ color: var(--tt-brand-color-500);
265
+ }
266
+
267
+ .notra-editor .tiptap-button[data-active-state='on']:hover:not([disabled]) {
268
+ background-color: var(--tt-gray-light-200);
269
+ }
270
+
271
+ /* =====================
272
+ Button Extras
273
+ ===================== */
274
+ .notra-editor .tiptap-button-dropdown-arrows {
275
+ width: 0.75rem;
276
+ height: 0.75rem;
277
+ color: var(--tt-gray-light-a-600);
278
+ }
279
+
280
+ .notra-editor .tiptap-button-text {
281
+ padding: 0 0.125rem;
282
+ }
283
+
284
+ /* =====================
285
+ Dropdown Menu
286
+ ===================== */
287
+ .notra-editor .tiptap-dropdown-menu-content {
288
+ z-index: 9999;
289
+ min-width: 8rem;
290
+ border-radius: calc(0.375rem + var(--tt-radius-lg));
291
+ padding: 0.375rem;
292
+ background-color: var(--tt-dropdown-menu-bg-color);
293
+ color: var(--tt-dropdown-menu-text-color);
294
+ box-shadow: var(--tt-shadow-elevated-md);
295
+ overflow: hidden;
296
+ transform: translateX(-50%);
297
+ animation: dropdown-in 100ms ease forwards;
298
+ }
299
+
300
+ .notra-editor .tiptap-dropdown-menu-group {
301
+ display: flex;
302
+ flex-direction: column;
303
+ }
304
+
305
+ @keyframes dropdown-in {
306
+ from {
307
+ opacity: 0;
308
+ transform: translateX(-50%) scale(0.95) translateY(-0.25rem);
309
+ }
310
+ to {
311
+ opacity: 1;
312
+ transform: translateX(-50%) scale(1) translateY(0);
313
+ }
314
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "notra-editor",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.3.0",
5
5
  "description": "A Markdown-first rich text editor for React",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -25,7 +25,8 @@
25
25
  },
26
26
  "./themes/default/shared.css": "./dist/themes/default/shared.css",
27
27
  "./themes/default/editor.css": "./dist/themes/default/editor.css",
28
- "./themes/default/reader.css": "./dist/themes/default/reader.css"
28
+ "./themes/default/reader.css": "./dist/themes/default/reader.css",
29
+ "./styles/globals.css": "./dist/styles/globals.css"
29
30
  },
30
31
  "main": "./dist/index.cjs",
31
32
  "module": "./dist/index.mjs",
@@ -34,10 +35,11 @@
34
35
  "dist"
35
36
  ],
36
37
  "peerDependencies": {
37
- "react": "^18.0.0 || ^19.0.0",
38
- "react-dom": "^18.0.0 || ^19.0.0"
38
+ "react": "^19.0.0",
39
+ "react-dom": "^19.0.0"
39
40
  },
40
41
  "dependencies": {
42
+ "@radix-ui/react-slot": "^1.2.4",
41
43
  "@tiptap/core": "^3.22.4",
42
44
  "@tiptap/extension-link": "^3.22.4",
43
45
  "@tiptap/extension-list": "^3.22.4",
@@ -45,22 +47,32 @@
45
47
  "@tiptap/react": "^3.22.4",
46
48
  "@tiptap/starter-kit": "^3.22.4",
47
49
  "@tiptap/static-renderer": "^3.22.4",
50
+ "class-variance-authority": "^0.7.1",
51
+ "clsx": "^2.1.1",
52
+ "lucide-react": "^1.9.0",
53
+ "radix-ui": "^1.4.3",
54
+ "tailwind-merge": "^3.5.0",
48
55
  "tiptap-markdown": "^0.8.10"
49
56
  },
50
57
  "devDependencies": {
58
+ "@tailwindcss/postcss": "^4.2.4",
51
59
  "@testing-library/jest-dom": "^6.6.3",
52
60
  "@testing-library/react": "^16.3.0",
53
61
  "@types/react": "19.2.2",
54
62
  "@types/react-dom": "19.2.2",
55
63
  "jsdom": "^26.1.0",
64
+ "postcss": "^8.5.10",
65
+ "postcss-cli": "^11.0.1",
56
66
  "react": "^19.2.0",
57
67
  "react-dom": "^19.2.0",
68
+ "tailwindcss": "^4.2.4",
58
69
  "tsup": "^8.4.0",
59
70
  "typescript": "^5.8.0",
60
71
  "vitest": "^4.0.18"
61
72
  },
62
73
  "scripts": {
63
- "build": "tsup",
74
+ "build": "tsup && pnpm build:css",
75
+ "build:css": "postcss src/styles/globals.css -o dist/styles/globals.css",
64
76
  "dev": "tsup --watch",
65
77
  "test": "vitest run --passWithNoTests",
66
78
  "test:watch": "vitest",