- this is a basic example of tiptap. Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists: -
-- Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block: -
-body {
- display: none;
-}
- - I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too. -
-- Wow, that's amazing. Good work, boy! 👏 -- `, + content: '
- — Mom -
Hello World!
', }) diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue deleted file mode 100644 index b58e52b..0000000 --- a/src/components/HelloWorld.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - -
- Edit
- components/HelloWorld.vue to test HMR
-
- Check out - create-vue, the official Vue + Vite starter -
-- Learn more about IDE Support for Vue in the - Vue Docs Scaling up Guide. -
-Click on the Vite and Vue logos to learn more
- - - diff --git a/src/main.ts b/src/main.ts index 01433bc..daf956b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,5 @@ import { createApp } from 'vue' +import './monacoWorker' import App from './App.vue' createApp(App).mount('#app') diff --git a/src/monacoWorker.ts b/src/monacoWorker.ts new file mode 100644 index 0000000..0d1adb0 --- /dev/null +++ b/src/monacoWorker.ts @@ -0,0 +1,26 @@ + +import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' +import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' +import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' +import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' +import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' + +self.MonacoEnvironment = { + getWorker(_: any, label: string) { + if (label === 'json') { + return new jsonWorker() + } + if (label === 'css' || label === 'scss' || label === 'less') { + return new cssWorker() + } + if (label === 'html' || label === 'handlebars' || label === 'razor') { + return new htmlWorker() + } + if (label === 'typescript' || label === 'javascript') { + return new tsWorker() + } + return new editorWorker() + }, +} + + diff --git a/src/styles/components.css b/src/styles/components.css new file mode 100644 index 0000000..e4e649a --- /dev/null +++ b/src/styles/components.css @@ -0,0 +1,143 @@ +/* Bubble Menu & Floating Menu */ +.bubble-menu, +.floating-menu { + display: flex; + background-color: var(--bg-primary); + padding: 0.2rem; + border-radius: 0.5rem; + box-shadow: var(--shadow-md); + border: 1px solid var(--border-color); +} + +.bubble-menu button, +.floating-menu button { + border: none; + background: none; + color: var(--text-secondary); + font-size: 0.875rem; + font-weight: 500; + padding: 0.25rem 0.5rem; + cursor: pointer; + border-radius: 0.25rem; + display: flex; + align-items: center; +} + +.bubble-menu button:hover, +.floating-menu button:hover, +.bubble-menu button.is-active, +.floating-menu button.is-active { + color: var(--text-heading); + background-color: var(--bg-hover); +} + +.bubble-menu .icon { + width: 1rem; + height: 1rem; +} + +/* Drag Handle */ +.drag-handle { + position: fixed; + opacity: 1; + transition: opacity 0.2s; + border-radius: 0.25rem; + cursor: grab; + background-image: none; +} + +.drag-handle:hover { + background-color: var(--bg-hover); +} + +.drag-handle-icon { + display: flex; + align-items: center; + justify-content: center; + width: 1.5rem; + height: 1.5rem; + color: var(--text-secondary); +} + +/* Code Block Component */ +.code-block-wrapper { + background-color: var(--bg-code-block); + border-radius: 0.5rem; + margin: 1rem 0; + overflow: hidden; + position: relative; +} + +.code-block-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem 1rem; + background-color: var(--bg-code-header); + border-bottom: 1px solid var(--border-code); +} + +.language-select { + background: transparent; + color: var(--text-code-primary); + border: none; + font-size: 0.875rem; + cursor: pointer; + outline: none; +} + +.language-select:disabled { + opacity: 0.7; + cursor: default; +} + +.actions { + display: flex; + gap: 0.5rem; +} + +.action-btn { + background: transparent; + border: none; + color: var(--text-code-secondary); + cursor: pointer; + padding: 0.25rem; + border-radius: 0.25rem; + display: flex; + align-items: center; + justify-content: center; +} + +.action-btn:hover { + background-color: var(--bg-code-hover); + color: var(--text-code-primary); +} + +.icon { + width: 1rem; + height: 1rem; +} + +.code-block-content { + padding: 1rem; + overflow-x: auto; + font-family: 'JetBrains Mono', monospace; + font-size: 0.875rem; + line-height: 1.5; + cursor: text; +} + +.monaco-container { + height: 300px; + min-height: 200px; +} + +/* Shiki styles */ +.shiki-container { + margin: 0; +} + +:deep(.shiki) { + background-color: transparent !important; + margin: 0; +} \ No newline at end of file diff --git a/src/styles/editor.css b/src/styles/editor.css new file mode 100644 index 0000000..2556ec3 --- /dev/null +++ b/src/styles/editor.css @@ -0,0 +1,80 @@ +/* Basic Editor Styles */ +.editor-container { + max-width: 800px; + margin: 4rem auto; + padding: 0 1rem; + background-color: var(--bg-primary); + color: var(--text-primary); + transition: background-color 0.3s, color 0.3s; +} + +.ProseMirror { + outline: none; +} + +.ProseMirror p.is-editor-empty:first-child::before { + color: var(--text-placeholder); + content: attr(data-placeholder); + float: left; + height: 0; + pointer-events: none; +} + +.ProseMirror p { + margin: 0; +} + +/* Table Styles */ +.ProseMirror table { + border-collapse: collapse; + table-layout: fixed; + width: 100%; + margin: 0; + overflow: hidden; +} + +.ProseMirror td, +.ProseMirror th { + min-width: 1em; + border: 2px solid var(--border-table); + padding: 3px 5px; + vertical-align: top; + box-sizing: border-box; + position: relative; +} + +.ProseMirror th { + font-weight: bold; + text-align: left; + background-color: var(--bg-table-header); +} + +.ProseMirror .selectedCell:after { + z-index: 2; + position: absolute; + content: ""; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: var(--selection-color); + pointer-events: none; +} + +.ProseMirror .column-resize-handle { + position: absolute; + right: -2px; + top: 0; + bottom: -2px; + width: 4px; + background-color: var(--resize-handle-color); + pointer-events: none; +} + +.tableWrapper { + overflow-x: auto; +} + +.resize-cursor { + cursor: col-resize; +} \ No newline at end of file diff --git a/src/styles/index.css b/src/styles/index.css new file mode 100644 index 0000000..a57fc42 --- /dev/null +++ b/src/styles/index.css @@ -0,0 +1,12 @@ +@import './variables.css'; +@import './typography.css'; +@import './editor.css'; +@import './components.css'; + +body { + background-color: var(--bg-primary); + color: var(--text-primary); + transition: background-color 0.3s, color 0.3s; + margin: 0; + font-family: 'Inter', sans-serif; +} \ No newline at end of file diff --git a/src/styles/typography.css b/src/styles/typography.css new file mode 100644 index 0000000..793a563 --- /dev/null +++ b/src/styles/typography.css @@ -0,0 +1,75 @@ +/* Typography */ +h1 { + font-size: 2.5rem; + font-weight: 700; + margin-top: 2.5rem; + margin-bottom: 1rem; + line-height: 1.2; + color: var(--text-heading); +} + +h2 { + font-size: 1.75rem; + font-weight: 600; + margin-top: 2rem; + margin-bottom: 0.75rem; + line-height: 1.3; + color: var(--text-heading); +} + +h3 { + font-size: 1.25rem; + font-weight: 600; + margin-top: 1.5rem; + margin-bottom: 0.5rem; + line-height: 1.4; + color: var(--text-heading); +} + +p { + margin-bottom: 1rem; + line-height: 1.6; + color: var(--text-primary); +} + +ul, +ol { + padding-left: 1.5rem; + margin-bottom: 1rem; + color: var(--text-primary); +} + +li { + margin-bottom: 0.25rem; +} + +blockquote { + border-left: 3px solid var(--border-color); + padding-left: 1rem; + margin-left: 0; + margin-bottom: 1rem; + font-style: italic; + color: var(--text-secondary); +} + +pre { + background: var(--bg-code); + color: var(--text-code); + font-family: 'JetBrainsMono', monospace; + padding: 0.75rem 1rem; + border-radius: 0.5rem; + margin-bottom: 1rem; +} + +code { + color: var(--text-secondary); + background: none; + font-size: 0.8em; +} + +pre code { + color: inherit; + padding: 0; + background: none; + font-size: 0.8rem; +} \ No newline at end of file diff --git a/src/styles/variables.css b/src/styles/variables.css new file mode 100644 index 0000000..11beee9 --- /dev/null +++ b/src/styles/variables.css @@ -0,0 +1,66 @@ +:root { + /* Colors - Light Mode */ + --bg-primary: #ffffff; + --bg-secondary: #f8fafc; + --bg-hover: #f1f5f9; + --bg-code: #0d0d0d; + --bg-table-header: #f1f3f5; + + --text-primary: #334155; + --text-secondary: #64748b; + --text-heading: #0f172a; + --text-code: #ffffff; + --text-placeholder: #adb5bd; + + --border-color: #e2e8f0; + --border-table: #ced4da; + + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + + --accent-color: #000000; + --selection-color: rgba(200, 200, 255, 0.4); + --resize-handle-color: #adf; + + /* Code Block - Light (using dark theme by default for code) */ + --bg-code-block: #0d1117; + --bg-code-header: #161b22; + --border-code: #30363d; + --text-code-primary: #c9d1d9; + --text-code-secondary: #8b949e; + --bg-code-hover: #30363d; +} + +.dark { + /* Colors - Dark Mode */ + --bg-primary: #1e1e1e; + --bg-secondary: #252526; + --bg-hover: #2d2d2d; + --bg-code: #0d0d0d; + /* Keep code blocks dark for now or adjust */ + --bg-table-header: #2d2d2d; + + --text-primary: #d4d4d4; + --text-secondary: #a3a3a3; + --text-heading: #ffffff; + --text-code: #ffffff; + --text-placeholder: #6e6e6e; + + --border-color: #3e3e42; + --border-table: #4a4a4a; + + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5), 0 2px 4px -1px rgba(0, 0, 0, 0.3); + + --accent-color: #ffffff; + --selection-color: rgba(100, 100, 255, 0.3); + --resize-handle-color: #61afef; + + /* Code Block - Dark */ + --bg-code-block: #0d1117; + --bg-code-header: #161b22; + --border-code: #30363d; + --text-code-primary: #c9d1d9; + --text-code-secondary: #8b949e; + --bg-code-hover: #30363d; +} \ No newline at end of file diff --git a/tsconfig.app.json b/tsconfig.app.json index 8d16e42..a8403a0 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -2,8 +2,9 @@ "extends": "@vue/tsconfig/tsconfig.dom.json", "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - "types": ["vite/client"], - + "types": [ + "vite/client" + ], /* Linting */ "strict": true, "noUnusedLocals": true, @@ -12,5 +13,9 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] -} + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "src/**/*.vue" + ] +} \ No newline at end of file