@collabchron/notiq 0.2.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.
- package/README.md +71 -0
- package/components.json +21 -0
- package/eslint.config.mjs +16 -0
- package/next.config.ts +12 -0
- package/package.json +108 -0
- package/postcss.config.mjs +5 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/images/icons/plus.svg +10 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/src/app/actions.ts +2 -0
- package/src/app/api/ai/route.ts +175 -0
- package/src/app/api/edgestore/[...edgestore]/route.ts +28 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +205 -0
- package/src/app/layout.tsx +38 -0
- package/src/app/page.tsx +12 -0
- package/src/components/editor/Core.tsx +220 -0
- package/src/components/editor/hooks/instructions-messages.ts +300 -0
- package/src/components/editor/hooks/use-mobile.ts +19 -0
- package/src/components/editor/hooks/useReport.ts +67 -0
- package/src/components/editor/hooks/useResizeObservert.ts +22 -0
- package/src/components/editor/index.tsx +39 -0
- package/src/components/editor/lexical-on-change.tsx +28 -0
- package/src/components/editor/nodes/CollapsibleNode/CollapsibleContainerNode.ts +92 -0
- package/src/components/editor/nodes/CollapsibleNode/CollapsibleContentNode.ts +65 -0
- package/src/components/editor/nodes/CollapsibleNode/CollapsibleTitleNode.ts +105 -0
- package/src/components/editor/nodes/EquationNode/EquationComponent.tsx +143 -0
- package/src/components/editor/nodes/EquationNode/EquationNode.tsx +170 -0
- package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawComponent.tsx +228 -0
- package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawImage.tsx +137 -0
- package/src/components/editor/nodes/ExcalidrawNode/ImageResizer.tsx +317 -0
- package/src/components/editor/nodes/ExcalidrawNode/index.tsx +204 -0
- package/src/components/editor/nodes/FigmaNode/FigmaNode.tsx +134 -0
- package/src/components/editor/nodes/Hint/HintComponet.tsx +221 -0
- package/src/components/editor/nodes/Hint/index.tsx +190 -0
- package/src/components/editor/nodes/ImageNode/index.tsx +328 -0
- package/src/components/editor/nodes/InlineImageNode/InlineImageComponent.tsx +383 -0
- package/src/components/editor/nodes/InlineImageNode/InlineImageNode.css +94 -0
- package/src/components/editor/nodes/InlineImageNode/InlineImageNode.tsx +309 -0
- package/src/components/editor/nodes/LayoutNode/LayoutContainerNode.ts +146 -0
- package/src/components/editor/nodes/LayoutNode/LayoutItemNode.ts +79 -0
- package/src/components/editor/nodes/PollNode/index.tsx +204 -0
- package/src/components/editor/nodes/Stepper/index.tsx +260 -0
- package/src/components/editor/nodes/TweetNode/index.tsx +214 -0
- package/src/components/editor/nodes/index.ts +81 -0
- package/src/components/editor/plugins/AutoEmbedPlugin/index.tsx +350 -0
- package/src/components/editor/plugins/AutoLinkPlugin/index.tsx +56 -0
- package/src/components/editor/plugins/CodeActionMenuPlugin/components/CopyButton.tsx +70 -0
- package/src/components/editor/plugins/CodeActionMenuPlugin/components/PrettierButton.tsx +192 -0
- package/src/components/editor/plugins/CodeActionMenuPlugin/index.tsx +217 -0
- package/src/components/editor/plugins/CodeActionMenuPlugin/utils.ts +26 -0
- package/src/components/editor/plugins/CodeHighlightPlugin/index.ts +21 -0
- package/src/components/editor/plugins/CollapsiblePlugin/Collapsible.css +76 -0
- package/src/components/editor/plugins/CollapsiblePlugin/index.ts +228 -0
- package/src/components/editor/plugins/DragDropPastePlugin/index.tsx +44 -0
- package/src/components/editor/plugins/DraggableBlockPlugin/index.tsx +52 -0
- package/src/components/editor/plugins/EquationsPlugin/index.tsx +85 -0
- package/src/components/editor/plugins/ExcalidrawPlugin/index.tsx +98 -0
- package/src/components/editor/plugins/FigmaPlugin/index.tsx +42 -0
- package/src/components/editor/plugins/FloatingLinkEditorPlugin/index.tsx +445 -0
- package/src/components/editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +275 -0
- package/src/components/editor/plugins/ImagesPlugin/index.tsx +222 -0
- package/src/components/editor/plugins/InlineImagePlugin/index.tsx +351 -0
- package/src/components/editor/plugins/LayoutPlugin/index.tsx +238 -0
- package/src/components/editor/plugins/LinkPlugin/index.tsx +36 -0
- package/src/components/editor/plugins/LinkWithMetaData/index.tsx +271 -0
- package/src/components/editor/plugins/MarkdownShortcutPlugin/index.tsx +11 -0
- package/src/components/editor/plugins/MarkdownTransformers/index.tsx +304 -0
- package/src/components/editor/plugins/PollPlugin/index.tsx +49 -0
- package/src/components/editor/plugins/ShortcutsPlugin/index.tsx +180 -0
- package/src/components/editor/plugins/ShortcutsPlugin/shortcuts.ts +253 -0
- package/src/components/editor/plugins/SlashCommand/index.tsx +621 -0
- package/src/components/editor/plugins/SpeechToTextPlugin/index.ts +127 -0
- package/src/components/editor/plugins/TabFocusPlugin/index.ts +58 -0
- package/src/components/editor/plugins/TableCellActionMenuPlugin/index.tsx +759 -0
- package/src/components/editor/plugins/TableCellResizer/index.tsx +438 -0
- package/src/components/editor/plugins/TableHoverActionsPlugin/index.tsx +314 -0
- package/src/components/editor/plugins/TablePlugin/index.tsx +99 -0
- package/src/components/editor/plugins/ToolbarPlugin/index.tsx +522 -0
- package/src/components/editor/plugins/TwitterPlugin/index.ts +35 -0
- package/src/components/editor/plugins/YouTubeNode/index.tsx +179 -0
- package/src/components/editor/plugins/YouTubePlugin/index.ts +41 -0
- package/src/components/editor/themes/editor-theme.ts +113 -0
- package/src/components/editor/themes/theme.css +377 -0
- package/src/components/editor/utils/ai.ts +291 -0
- package/src/components/editor/utils/canUseDOM.ts +12 -0
- package/src/components/editor/utils/editorFormatting.ts +282 -0
- package/src/components/editor/utils/environment.ts +50 -0
- package/src/components/editor/utils/extract-data.ts +166 -0
- package/src/components/editor/utils/getAllLexicalChildren.ts +13 -0
- package/src/components/editor/utils/getDOMRangeRect.ts +27 -0
- package/src/components/editor/utils/getSelectedNode.ts +27 -0
- package/src/components/editor/utils/gif.ts +29 -0
- package/src/components/editor/utils/invariant.ts +15 -0
- package/src/components/editor/utils/setFloatingElemPosition.ts +51 -0
- package/src/components/editor/utils/setFloatingElemPositionForLinkEditor.ts +40 -0
- package/src/components/editor/utils/setNodePlaceholderFromSelection/getNodePlaceholder.ts +51 -0
- package/src/components/editor/utils/setNodePlaceholderFromSelection/setNodePlaceholderFromSelection.ts +15 -0
- package/src/components/editor/utils/setNodePlaceholderFromSelection/setPlaceholderOnSelection.ts +114 -0
- package/src/components/editor/utils/setNodePlaceholderFromSelection/styles.css +6 -0
- package/src/components/editor/utils/url.ts +109 -0
- package/src/components/editor/utils/useLayoutEffect.ts +13 -0
- package/src/components/providers/QueryProvider.tsx +15 -0
- package/src/components/providers/SharedHistoryContext.tsx +28 -0
- package/src/components/providers/ToolbarContext.tsx +123 -0
- package/src/components/providers/theme-provider.tsx +11 -0
- package/src/components/theme/ModeToggle.tsx +40 -0
- package/src/components/ui/FileInput.tsx +40 -0
- package/src/components/ui/Input.css +32 -0
- package/src/components/ui/Select.css +42 -0
- package/src/components/ui/Select.tsx +36 -0
- package/src/components/ui/TextInput.tsx +48 -0
- package/src/components/ui/ai/ai-button.tsx +574 -0
- package/src/components/ui/ai/border.tsx +99 -0
- package/src/components/ui/ai/placeholder-input-vanish.tsx +282 -0
- package/src/components/ui/button.tsx +89 -0
- package/src/components/ui/card.tsx +76 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/command.tsx +153 -0
- package/src/components/ui/dialog/Dialog.css +25 -0
- package/src/components/ui/dialog/Dialog.tsx +34 -0
- package/src/components/ui/dialog.tsx +122 -0
- package/src/components/ui/drop-downs/background-color.tsx +183 -0
- package/src/components/ui/drop-downs/block-format.tsx +159 -0
- package/src/components/ui/drop-downs/code.tsx +42 -0
- package/src/components/ui/drop-downs/color.tsx +177 -0
- package/src/components/ui/drop-downs/font-size.tsx +138 -0
- package/src/components/ui/drop-downs/font.tsx +155 -0
- package/src/components/ui/drop-downs/index.tsx +122 -0
- package/src/components/ui/drop-downs/insert-node.tsx +213 -0
- package/src/components/ui/drop-downs/text-align.tsx +123 -0
- package/src/components/ui/drop-downs/text-format.tsx +104 -0
- package/src/components/ui/dropdown-menu.tsx +201 -0
- package/src/components/ui/equation/EquationEditor.css +38 -0
- package/src/components/ui/equation/EquationEditor.tsx +56 -0
- package/src/components/ui/equation/KatexEquationAlterer.css +41 -0
- package/src/components/ui/equation/KatexEquationAlterer.tsx +83 -0
- package/src/components/ui/equation/KatexRenderer.tsx +66 -0
- package/src/components/ui/excalidraw/ExcalidrawModal.css +64 -0
- package/src/components/ui/excalidraw/ExcalidrawModal.tsx +234 -0
- package/src/components/ui/excalidraw/Modal.css +62 -0
- package/src/components/ui/excalidraw/Modal.tsx +110 -0
- package/src/components/ui/hover-card.tsx +29 -0
- package/src/components/ui/image/error-image.tsx +17 -0
- package/src/components/ui/image/file-upload.tsx +240 -0
- package/src/components/ui/image/image-resizer.tsx +297 -0
- package/src/components/ui/image/image-toolbar.tsx +264 -0
- package/src/components/ui/image/index.tsx +408 -0
- package/src/components/ui/image/lazy-image.tsx +68 -0
- package/src/components/ui/image/lazy-video.tsx +71 -0
- package/src/components/ui/input.tsx +22 -0
- package/src/components/ui/models/custom-dialog.tsx +320 -0
- package/src/components/ui/models/insert-gif.tsx +90 -0
- package/src/components/ui/models/insert-image.tsx +52 -0
- package/src/components/ui/models/insert-poll.tsx +29 -0
- package/src/components/ui/models/insert-table.tsx +62 -0
- package/src/components/ui/models/use-model.tsx +91 -0
- package/src/components/ui/poll/poll-component.tsx +304 -0
- package/src/components/ui/popover.tsx +33 -0
- package/src/components/ui/progress.tsx +28 -0
- package/src/components/ui/scroll-area.tsx +48 -0
- package/src/components/ui/separator.tsx +31 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/sonner.tsx +31 -0
- package/src/components/ui/stepper/step.tsx +179 -0
- package/src/components/ui/stepper/stepper.tsx +89 -0
- package/src/components/ui/textarea.tsx +22 -0
- package/src/components/ui/toggle.tsx +71 -0
- package/src/components/ui/tooltip.tsx +32 -0
- package/src/components/ui/write/text-format-floting-toolbar.tsx +346 -0
- package/src/lib/edgestore.ts +9 -0
- package/src/lib/pinecone-client.ts +0 -0
- package/src/lib/utils.ts +6 -0
- package/src/utils/docSerialization.ts +77 -0
- package/src/utils/emoji-list.ts +16615 -0
- package/src/utils/getDOMRangeRect.ts +27 -0
- package/src/utils/getSelectedNode.ts +27 -0
- package/src/utils/getThemeSelector.ts +25 -0
- package/src/utils/isMobileWidth.ts +7 -0
- package/src/utils/joinClasses.ts +13 -0
- package/src/utils/setFloatingElemPosition.ts +74 -0
- package/src/utils/setFloatingElemPositionForLinkEditor.ts +46 -0
- package/src/utils/swipe.ts +127 -0
- package/src/utils/url.ts +38 -0
- package/tsconfig.json +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Notiq
|
|
2
|
+
|
|
3
|
+
A modern, extensible note-taking and document editor built with Next.js, TypeScript, Tailwind CSS, and Lexical. Features include rich text editing, image and media embeds, equations, polls, and more.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ⚡️ Fast, responsive editor powered by Lexical
|
|
8
|
+
- 🖼️ Image, inline image, and media embeds (YouTube, Twitter, Figma, GIFs)
|
|
9
|
+
- 🧮 Equation and math support (KaTeX)
|
|
10
|
+
- 📊 Polls, tables, and code blocks
|
|
11
|
+
- 🎨 Customizable themes with Tailwind CSS
|
|
12
|
+
- 🗂️ Modular plugin architecture
|
|
13
|
+
- 🌐 Next.js app with API routes
|
|
14
|
+
|
|
15
|
+
## Getting Started
|
|
16
|
+
|
|
17
|
+
### Prerequisites
|
|
18
|
+
|
|
19
|
+
- Node.js (v18+ recommended)
|
|
20
|
+
- pnpm (or npm/yarn)
|
|
21
|
+
|
|
22
|
+
### Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Development
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Open [http://localhost:3000](http://localhost:3000) in your browser.
|
|
35
|
+
|
|
36
|
+
### Build
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pnpm build
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Project Structure
|
|
43
|
+
|
|
44
|
+
- `src/app/` — Next.js app routes and layout
|
|
45
|
+
- `src/components/editor/` — Editor core, plugins, nodes, and UI
|
|
46
|
+
- `src/components/ui/` — Reusable UI components
|
|
47
|
+
- `src/lib/` — Utility libraries (EdgeStore, Pinecone, etc.)
|
|
48
|
+
- `public/` — Static assets
|
|
49
|
+
|
|
50
|
+
## Editor Plugins & Nodes
|
|
51
|
+
|
|
52
|
+
- **Plugins:** Toolbar, Floating Toolbar, AutoEmbed, Equations, Excalidraw, Inline Images, Polls, Tables, Code Actions, Slash Commands, etc.
|
|
53
|
+
- **Nodes:** ImageNode, InlineImageNode, EquationNode, ExcalidrawNode, PollNode, etc.
|
|
54
|
+
|
|
55
|
+
## Customization
|
|
56
|
+
|
|
57
|
+
- Tailwind CSS config: `tailwind.config.ts`
|
|
58
|
+
- ESLint config: `eslint.config.mjs`
|
|
59
|
+
- Editor themes: `src/components/editor/themes/`
|
|
60
|
+
|
|
61
|
+
## Contributing
|
|
62
|
+
|
|
63
|
+
1. Fork the repo
|
|
64
|
+
2. Create your feature branch (`git checkout -b feature/foo`)
|
|
65
|
+
3. Commit your changes (`git commit -am 'Add feature'`)
|
|
66
|
+
4. Push to the branch (`git push origin feature/foo`)
|
|
67
|
+
5. Create a Pull Request
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT
|
package/components.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"rsc": true,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "tailwind.config.ts",
|
|
8
|
+
"css": "src/app/globals.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true,
|
|
11
|
+
"prefix": ""
|
|
12
|
+
},
|
|
13
|
+
"aliases": {
|
|
14
|
+
"components": "@/components",
|
|
15
|
+
"utils": "@/lib/utils",
|
|
16
|
+
"ui": "@/components/ui",
|
|
17
|
+
"lib": "@/lib",
|
|
18
|
+
"hooks": "@/hooks"
|
|
19
|
+
},
|
|
20
|
+
"iconLibrary": "lucide"
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { dirname } from "path";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = dirname(__filename);
|
|
7
|
+
|
|
8
|
+
const compat = new FlatCompat({
|
|
9
|
+
baseDirectory: __dirname,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const eslintConfig = [
|
|
13
|
+
...compat.extends("next/core-web-vitals", "next/typescript"),
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export default eslintConfig;
|
package/next.config.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@collabchron/notiq",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Notion AI + Figma + Excalidraw + 3D + Code Editor + Markdown Editor + Real-time Collaboration + Embeds + More = Notiq",
|
|
6
|
+
"author": "Chinonso Chikelue (fluantiX) <chinonsoneft@gmail.com>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/chinonsochikelue/notiq.git"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"dev": "next dev --turbopack",
|
|
14
|
+
"build": "next build",
|
|
15
|
+
"start": "next start",
|
|
16
|
+
"lint": "next lint"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@ai-sdk/openai": "^2.0.30",
|
|
20
|
+
"@ai-sdk/react": "^2.0.44",
|
|
21
|
+
"@edgestore/react": "^0.5.4",
|
|
22
|
+
"@edgestore/server": "^0.5.4",
|
|
23
|
+
"@excalidraw/excalidraw": "^0.18.0",
|
|
24
|
+
"@lexical/clipboard": "^0.35.0",
|
|
25
|
+
"@lexical/code": "^0.35.0",
|
|
26
|
+
"@lexical/code-shiki": "^0.35.0",
|
|
27
|
+
"@lexical/devtools-core": "^0.35.0",
|
|
28
|
+
"@lexical/dragon": "^0.35.0",
|
|
29
|
+
"@lexical/eslint-plugin": "^0.35.0",
|
|
30
|
+
"@lexical/file": "^0.35.0",
|
|
31
|
+
"@lexical/hashtag": "^0.35.0",
|
|
32
|
+
"@lexical/headless": "^0.35.0",
|
|
33
|
+
"@lexical/history": "^0.35.0",
|
|
34
|
+
"@lexical/html": "^0.35.0",
|
|
35
|
+
"@lexical/link": "^0.35.0",
|
|
36
|
+
"@lexical/list": "^0.35.0",
|
|
37
|
+
"@lexical/mark": "^0.35.0",
|
|
38
|
+
"@lexical/markdown": "^0.35.0",
|
|
39
|
+
"@lexical/offset": "^0.35.0",
|
|
40
|
+
"@lexical/overflow": "^0.35.0",
|
|
41
|
+
"@lexical/react": "^0.35.0",
|
|
42
|
+
"@lexical/rich-text": "^0.35.0",
|
|
43
|
+
"@lexical/selection": "^0.35.0",
|
|
44
|
+
"@lexical/table": "^0.35.0",
|
|
45
|
+
"@lexical/text": "^0.35.0",
|
|
46
|
+
"@lexical/utils": "^0.35.0",
|
|
47
|
+
"@lexical/yjs": "^0.35.0",
|
|
48
|
+
"@mantine/hooks": "^8.3.1",
|
|
49
|
+
"@pinecone-database/pinecone": "^6.1.2",
|
|
50
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
51
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
52
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
53
|
+
"@radix-ui/react-hover-card": "^1.1.15",
|
|
54
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
55
|
+
"@radix-ui/react-progress": "^1.1.7",
|
|
56
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
57
|
+
"@radix-ui/react-separator": "^1.1.7",
|
|
58
|
+
"@radix-ui/react-slot": "^1.2.3",
|
|
59
|
+
"@radix-ui/react-toggle": "^1.1.10",
|
|
60
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
61
|
+
"@react-three/fiber": "^9.3.0",
|
|
62
|
+
"@tailwindcss/postcss": "^4.1.13",
|
|
63
|
+
"@tanstack/react-query": "^5.87.4",
|
|
64
|
+
"@uiw/react-color": "^2.8.0",
|
|
65
|
+
"ai": "^5.0.44",
|
|
66
|
+
"class-variance-authority": "^0.7.1",
|
|
67
|
+
"clsx": "^2.1.1",
|
|
68
|
+
"cmdk": "^1.1.1",
|
|
69
|
+
"framer-motion": "^12.23.12",
|
|
70
|
+
"katex": "^0.16.22",
|
|
71
|
+
"lexical": "^0.35.0",
|
|
72
|
+
"lodash-es": "^4.17.21",
|
|
73
|
+
"lucide-react": "^0.544.0",
|
|
74
|
+
"motion": "^12.23.12",
|
|
75
|
+
"next-themes": "^0.4.6",
|
|
76
|
+
"openai": "^5.20.2",
|
|
77
|
+
"react": "^19.1.1",
|
|
78
|
+
"react-dom": "^19.1.1",
|
|
79
|
+
"react-error-boundary": "^6.0.0",
|
|
80
|
+
"react-markdown": "^10.1.0",
|
|
81
|
+
"redis": "^5.8.2",
|
|
82
|
+
"sonner": "^2.0.7",
|
|
83
|
+
"tailwind-merge": "^3.3.1",
|
|
84
|
+
"tailwindcss-animate": "^1.0.7",
|
|
85
|
+
"three": "^0.180.0",
|
|
86
|
+
"tw-animate-css": "^1.3.8",
|
|
87
|
+
"zod": "^4.1.8",
|
|
88
|
+
"zustand": "^5.0.8"
|
|
89
|
+
},
|
|
90
|
+
"devDependencies": {
|
|
91
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
92
|
+
"@tailwindcss/typography": "^0.5.16",
|
|
93
|
+
"@tanstack/eslint-plugin-query": "^5.86.0",
|
|
94
|
+
"@types/lodash-es": "^4.17.12",
|
|
95
|
+
"@types/node": "^24.4.0",
|
|
96
|
+
"@types/react": "^19.1.13",
|
|
97
|
+
"@types/react-dom": "^19.1.9",
|
|
98
|
+
"@types/three": "^0.180.0",
|
|
99
|
+
"autoprefixer": "^10.4.21",
|
|
100
|
+
"eslint": "^9.35.0",
|
|
101
|
+
"eslint-config-next": "15.5.3",
|
|
102
|
+
"next": "15.5.3",
|
|
103
|
+
"postcss": "^8.5.6",
|
|
104
|
+
"prettier": "3.6.2",
|
|
105
|
+
"tailwindcss": "^4.1.13",
|
|
106
|
+
"typescript": "^5.9.2"
|
|
107
|
+
}
|
|
108
|
+
}
|
package/public/file.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
package/public/globe.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
package/public/next.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AIAction,
|
|
3
|
+
autoCompleteInstruction,
|
|
4
|
+
FixSpellingGrammarInstruction,
|
|
5
|
+
improveMesgInstruction,
|
|
6
|
+
MakeLongInstruction,
|
|
7
|
+
MakeShortInstruction,
|
|
8
|
+
SimplifyLanguageInstruction,
|
|
9
|
+
StepsInstruction,
|
|
10
|
+
} from "@/components/editor/hooks/instructions-messages";
|
|
11
|
+
import { ExtractedBlock } from "@/components/editor/utils/extract-data";
|
|
12
|
+
import { openai } from "@ai-sdk/openai";
|
|
13
|
+
import { CoreMessage, streamText } from "ai";
|
|
14
|
+
import { createClient } from "redis";
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
const client = createClient({
|
|
19
|
+
username: "default",
|
|
20
|
+
password: process.env.REDIS_PASSWORD,
|
|
21
|
+
socket: {
|
|
22
|
+
host: process.env.REDIS_URL,
|
|
23
|
+
port: parseInt(process.env.REDIS_PORT!),
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
client.connect().catch((err) => console.error("Redis connection error:", err));
|
|
28
|
+
|
|
29
|
+
export const maxDuration = 30;
|
|
30
|
+
const MAX_TOKEN = 60000;
|
|
31
|
+
|
|
32
|
+
function estimateTokenCount(text: string): number {
|
|
33
|
+
return Math.ceil(text.length / 4);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
function computeHash(text: string): string {
|
|
38
|
+
let hash = 0;
|
|
39
|
+
for (let i = 0; i < text.length; i++) {
|
|
40
|
+
hash = (hash << 5) - hash + text.charCodeAt(i);
|
|
41
|
+
hash |= 0; // Convert to 32bit integer
|
|
42
|
+
}
|
|
43
|
+
return hash.toString();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function flattenBlocks(blocks: ExtractedBlock[]): string {
|
|
47
|
+
return blocks
|
|
48
|
+
.map((block) => {
|
|
49
|
+
let content = block.content;
|
|
50
|
+
if (block.children) {
|
|
51
|
+
content += `\n${flattenBlocks(block.children)}`;
|
|
52
|
+
}
|
|
53
|
+
return content;
|
|
54
|
+
})
|
|
55
|
+
.join("\n\n");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Asynchronously process the raw context JSON string.
|
|
60
|
+
* It checks Redis for a cached version (valid for 30 seconds),
|
|
61
|
+
* and if not found, processes the JSON into flat text, applies smart truncation,
|
|
62
|
+
* stores it in Redis, and returns the processed text.
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
async function processContext(rawContext: string): Promise<string> {
|
|
67
|
+
const currentHash = computeHash(rawContext);
|
|
68
|
+
const cacheKey = `context:${currentHash}`;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const cached = await client.get(cacheKey);
|
|
72
|
+
if (cached) {
|
|
73
|
+
const cachedData = JSON.parse(cached);
|
|
74
|
+
if (Date.now() - cachedData.timestamp < 30000) {
|
|
75
|
+
console.log("Returning cached context from Redis");
|
|
76
|
+
return cachedData.processedText;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error("Redis error while fetching cache:", error);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const blocks: ExtractedBlock[] = JSON.parse(rawContext);
|
|
85
|
+
let processedText = flattenBlocks(blocks);
|
|
86
|
+
|
|
87
|
+
// If processed text is too long, preserve important sections and truncate
|
|
88
|
+
if (estimateTokenCount(processedText) > MAX_TOKEN) {
|
|
89
|
+
const importantSections = blocks
|
|
90
|
+
.filter((b) =>
|
|
91
|
+
[
|
|
92
|
+
"heading",
|
|
93
|
+
"Collapsible",
|
|
94
|
+
"Table",
|
|
95
|
+
"text",
|
|
96
|
+
"paragraph",
|
|
97
|
+
"list",
|
|
98
|
+
"quote",
|
|
99
|
+
"code",
|
|
100
|
+
"CollapsibleContent",
|
|
101
|
+
"Collapsible",
|
|
102
|
+
"list-item",
|
|
103
|
+
].includes(b.blockType)
|
|
104
|
+
)
|
|
105
|
+
.map((b) => b.content + (b.children ? `\n${flattenBlocks(b.children)}` : ""))
|
|
106
|
+
.join("\n\n");
|
|
107
|
+
|
|
108
|
+
processedText = `${importantSections}\n\n${
|
|
109
|
+
blocks
|
|
110
|
+
.filter((b) => !["heading", "quote", "Table","paragraph"].includes(b.blockType))
|
|
111
|
+
.map((b) => b.content)
|
|
112
|
+
.join("\n")
|
|
113
|
+
}`.slice(0, MAX_TOKEN * 4);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Store in Redis with an expiration of 30 seconds
|
|
117
|
+
const cacheData = JSON.stringify({ processedText, timestamp: Date.now() });
|
|
118
|
+
try {
|
|
119
|
+
await client.set(cacheKey, cacheData, { EX: maxDuration });
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error("Redis error while setting cache:", error);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return processedText;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("Context processing failed:", error);
|
|
127
|
+
return rawContext.slice(0, MAX_TOKEN * 4);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function buildSystemMessage(action: AIAction, context: string): string {
|
|
132
|
+
const baseInstructions: any = {
|
|
133
|
+
autoComplete: autoCompleteInstruction,
|
|
134
|
+
FixSpellingGrammar: FixSpellingGrammarInstruction,
|
|
135
|
+
ImproveWriting: improveMesgInstruction,
|
|
136
|
+
MakeLongInstruction: MakeLongInstruction,
|
|
137
|
+
MakeShortInstruction: MakeShortInstruction,
|
|
138
|
+
SimplifyLanguage: SimplifyLanguageInstruction,
|
|
139
|
+
Steps: StepsInstruction,
|
|
140
|
+
ChatWithSelectedString: `You're an editor assistant. Use all the provided context from the document to answer the user's question directly in concise Markdown format. Answer ONLY the question without including additional suggestions or extra context. If the blog does not contain the necessary data, you may supplement your answer with external information.
|
|
141
|
+
Context:
|
|
142
|
+
${context}`,
|
|
143
|
+
GenerateAgain: `Improve the response based on the full content.
|
|
144
|
+
Context:
|
|
145
|
+
${context}
|
|
146
|
+
Consider: 1. Phrasing 2. Details 3. Alternatives`,
|
|
147
|
+
default: "You are a professional writing assistant",
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return baseInstructions[action] || baseInstructions.default!;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export async function POST(req: Request) {
|
|
154
|
+
const { prompt: userQuestion, action, context } = await req.json();
|
|
155
|
+
const processedContext = context ? await processContext(context) : "";
|
|
156
|
+
const systemMessage = buildSystemMessage(action, processedContext);
|
|
157
|
+
const messages: CoreMessage[] = [
|
|
158
|
+
{ role: "system", content: systemMessage },
|
|
159
|
+
{ role: "user", content: userQuestion },
|
|
160
|
+
];
|
|
161
|
+
try {
|
|
162
|
+
const result = streamText({
|
|
163
|
+
model: openai("gpt-4o"),
|
|
164
|
+
messages,
|
|
165
|
+
temperature: 0.2,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return result.toDataStreamResponse();
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error("Streaming failed:", error);
|
|
171
|
+
return new Response("Error generating response", { status: 500 });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { initEdgeStore } from '@edgestore/server';
|
|
2
|
+
import { createEdgeStoreNextHandler } from '@edgestore/server/adapters/next/app';
|
|
3
|
+
|
|
4
|
+
// Initialize the EdgeStore
|
|
5
|
+
const es = initEdgeStore.create();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* This is the main router for the Edge Store buckets.
|
|
9
|
+
* We're configuring a file bucket that allows all file types and limits size to 1GB.
|
|
10
|
+
*/
|
|
11
|
+
const edgeStoreRouter = es.router({
|
|
12
|
+
publicFiles: es.fileBucket({
|
|
13
|
+
// Set file size limit to 1 GB (1 GB = 1,073,741,824 bytes)
|
|
14
|
+
maxSize: 1_073_741_824,
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Create the handler for the GET and POST routes
|
|
19
|
+
const handler = createEdgeStoreNextHandler({
|
|
20
|
+
router: edgeStoreRouter,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export { handler as GET, handler as POST };
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* This type is used to create the type-safe client for the frontend.
|
|
27
|
+
*/
|
|
28
|
+
export type EdgeStoreRouter = typeof edgeStoreRouter;
|
|
Binary file
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/* @import url('https://fonts.googleapis.com/css2?family=Monomakh&display=swap'); */
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@tailwind base;
|
|
5
|
+
@tailwind components;
|
|
6
|
+
@tailwind utilities;
|
|
7
|
+
@import "tailwindcss";
|
|
8
|
+
@plugin "@tailwindcss/typography";
|
|
9
|
+
|
|
10
|
+
body {
|
|
11
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
input[type="number"]::-webkit-inner-spin-button,
|
|
15
|
+
input[type="number"]::-webkit-outer-spin-button {
|
|
16
|
+
-webkit-appearance: none;
|
|
17
|
+
margin: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.select-none {
|
|
21
|
+
user-select: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#toolbar {
|
|
25
|
+
scrollbar-width: none;
|
|
26
|
+
/* Firefox */
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#toolbar::-webkit-scrollbar {
|
|
30
|
+
display: none;
|
|
31
|
+
/* Chrome, Safari, Edge */
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.code {
|
|
35
|
+
scrollbar-width: none;
|
|
36
|
+
/* Firefox */
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.code::-webkit-scrollbar {
|
|
40
|
+
display: none;
|
|
41
|
+
/* Chrome, Safari, Edge */
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@layer base {
|
|
45
|
+
:root {
|
|
46
|
+
--font-gray: #9B9A97;
|
|
47
|
+
--font-brown: #64473A;
|
|
48
|
+
--font-orange: #D9730D;
|
|
49
|
+
--font-yellow: #DFAB01;
|
|
50
|
+
--font-green: #0F7B6C;
|
|
51
|
+
--font-blue: #0B6E99;
|
|
52
|
+
--font-purple: #6940A5;
|
|
53
|
+
--font-pink: #AD1A72;
|
|
54
|
+
--font-red: #E03E3E;
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
--background-gray: #EBECED;
|
|
58
|
+
--background-brown: #E9E5E3;
|
|
59
|
+
--background-orange: #FAEBDD;
|
|
60
|
+
--background-yellow: #FBF3DB;
|
|
61
|
+
--background-green: #DDEDEA;
|
|
62
|
+
--background-blue: #DDEDEA;
|
|
63
|
+
--background-purple: #EAE4F2;
|
|
64
|
+
--background-pink: #F4DFEB;
|
|
65
|
+
--background-red: #FBE4E4;
|
|
66
|
+
|
|
67
|
+
--background: 0 0% 100%;
|
|
68
|
+
--foreground: 0 0% 3.9%;
|
|
69
|
+
--card: 0 0% 100%;
|
|
70
|
+
--card-foreground: 0 0% 3.9%;
|
|
71
|
+
--popover: 0 0% 100%;
|
|
72
|
+
--popover-foreground: 0 0% 3.9%;
|
|
73
|
+
--primary: 0 0% 9%;
|
|
74
|
+
--primary-foreground: 0 0% 98%;
|
|
75
|
+
--secondary: 0 0% 96.1%;
|
|
76
|
+
--secondary-foreground: 0 0% 9%;
|
|
77
|
+
--muted: 0 0% 96.1%;
|
|
78
|
+
--muted-foreground: 0 0% 45.1%;
|
|
79
|
+
--accent: 0 0% 96.1%;
|
|
80
|
+
--accent-foreground: 0 0% 9%;
|
|
81
|
+
--destructive: 0 84.2% 60.2%;
|
|
82
|
+
--destructive-foreground: 0 0% 98%;
|
|
83
|
+
--border: 0 0% 89.8%;
|
|
84
|
+
--input: 0 0% 89.8%;
|
|
85
|
+
--ring: 0 0% 3.9%;
|
|
86
|
+
--chart-1: 12 76% 61%;
|
|
87
|
+
--chart-2: 173 58% 39%;
|
|
88
|
+
--chart-3: 197 37% 24%;
|
|
89
|
+
--chart-4: 43 74% 66%;
|
|
90
|
+
--chart-5: 27 87% 67%;
|
|
91
|
+
--radius: 0.5rem;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.dark {
|
|
95
|
+
|
|
96
|
+
--font-gray: #9B9A97;
|
|
97
|
+
--font-brown: #937264;
|
|
98
|
+
--font-orange: #FFA344;
|
|
99
|
+
--font-yellow: #FFDC49;
|
|
100
|
+
--font-green: #4DAB9A;
|
|
101
|
+
--font-blue: #529CCA;
|
|
102
|
+
--font-purple: #9A6DD7;
|
|
103
|
+
--font-pink: #E255A1;
|
|
104
|
+
--font-red: #FF7369;
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
--background-gray: #454B4E;
|
|
108
|
+
--background-brown: #434040;
|
|
109
|
+
--background-orange: #594A3A;
|
|
110
|
+
--background-yellow: #59563B;
|
|
111
|
+
--background-green: #354C4B;
|
|
112
|
+
--background-blue: #364954;
|
|
113
|
+
--background-purple: #443F57;
|
|
114
|
+
--background-pink: #533B4C;
|
|
115
|
+
--background-red: #594141;
|
|
116
|
+
|
|
117
|
+
--background: 0 0% 3.9%;
|
|
118
|
+
--foreground: 0 0% 98%;
|
|
119
|
+
--card: 0 0% 3.9%;
|
|
120
|
+
--card-foreground: 0 0% 98%;
|
|
121
|
+
--popover: 0 0% 3.9%;
|
|
122
|
+
--popover-foreground: 0 0% 98%;
|
|
123
|
+
--primary: 0 0% 98%;
|
|
124
|
+
--primary-foreground: 0 0% 9%;
|
|
125
|
+
--secondary: 0 0% 14.9%;
|
|
126
|
+
--secondary-foreground: 0 0% 98%;
|
|
127
|
+
--muted: 0 0% 14.9%;
|
|
128
|
+
--muted-foreground: 0 0% 63.9%;
|
|
129
|
+
--accent: 0 0% 14.9%;
|
|
130
|
+
--accent-foreground: 0 0% 98%;
|
|
131
|
+
--destructive: 0 62.8% 30.6%;
|
|
132
|
+
--destructive-foreground: 0 0% 98%;
|
|
133
|
+
--border: 0 0% 14.9%;
|
|
134
|
+
--input: 0 0% 14.9%;
|
|
135
|
+
--ring: 0 0% 83.1%;
|
|
136
|
+
--chart-1: 220 70% 50%;
|
|
137
|
+
--chart-2: 160 60% 45%;
|
|
138
|
+
--chart-3: 30 80% 55%;
|
|
139
|
+
--chart-4: 280 65% 60%;
|
|
140
|
+
--chart-5: 340 75% 55%;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.editor-shell .editor-image .image-edit-button {
|
|
145
|
+
border: 1px solid rgba(0, 0, 0, 0.3);
|
|
146
|
+
border-radius: 5px;
|
|
147
|
+
background-image: url(/src/images/icons/pencil-fill.svg);
|
|
148
|
+
background-size: 16px;
|
|
149
|
+
background-position: center;
|
|
150
|
+
background-repeat: no-repeat;
|
|
151
|
+
width: 35px;
|
|
152
|
+
height: 35px;
|
|
153
|
+
vertical-align: -0.25em;
|
|
154
|
+
position: absolute;
|
|
155
|
+
right: 4px;
|
|
156
|
+
top: 4px;
|
|
157
|
+
cursor: pointer;
|
|
158
|
+
user-select: none;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.editor-shell .editor-image .image-edit-button:hover {
|
|
162
|
+
background-color: rgba(60, 132, 244, 0.1);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.editor-shell .inline-editor-image .image-edit-button {
|
|
166
|
+
display: block;
|
|
167
|
+
position: absolute;
|
|
168
|
+
top: 12px;
|
|
169
|
+
right: 12px;
|
|
170
|
+
padding: 6px 8px;
|
|
171
|
+
margin: 0 auto;
|
|
172
|
+
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
173
|
+
border-radius: 5px;
|
|
174
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
175
|
+
min-width: 60px;
|
|
176
|
+
color: #fff;
|
|
177
|
+
cursor: pointer;
|
|
178
|
+
user-select: none;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.editor-shell .inline-editor-image .image-edit-button:hover {
|
|
182
|
+
background-color: rgba(60, 132, 244, 0.5);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
/* @layer base {
|
|
187
|
+
* {
|
|
188
|
+
@apply border-border;
|
|
189
|
+
}
|
|
190
|
+
body {
|
|
191
|
+
@apply bg-background text-foreground;
|
|
192
|
+
}
|
|
193
|
+
} */
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
/* @layer base {
|
|
198
|
+
* {
|
|
199
|
+
@apply border border-border outline-ring/50;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
body {
|
|
203
|
+
@apply bg-background text-foreground;
|
|
204
|
+
}
|
|
205
|
+
} */
|