├── public
├── desktop.png
├── desktop2.png
└── mobile.png
├── postcss.config.js
├── .idea
├── .gitignore
├── vcs.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── modules.xml
└── shadcn-comments.iml
├── examples
└── vite-tailwind-app
│ ├── postcss.config.js
│ ├── vite.config.ts
│ ├── tailwind.config.js
│ ├── tsconfig.node.json
│ ├── src
│ ├── main.tsx
│ ├── App.tsx
│ ├── App.css
│ ├── index.css
│ ├── theme-provider.tsx
│ └── DemoComment.tsx
│ ├── .gitignore
│ ├── index.html
│ ├── .eslintrc.cjs
│ ├── tsconfig.json
│ └── package.json
├── src
├── types
│ ├── user.ts
│ └── comment.ts
├── index.ts
├── lib
│ └── utils.ts
├── components
│ ├── PreviewComment.tsx
│ ├── Input.tsx
│ ├── EmojiSelect.tsx
│ ├── Popover.tsx
│ ├── EditorCommentStyle2.tsx
│ ├── Avatar.tsx
│ ├── Alert.tsx
│ ├── Button.tsx
│ ├── DropdownMenu.tsx
│ ├── EditingEditorComment.tsx
│ ├── EditorComment.tsx
│ └── CommentSection.tsx
├── index.css
└── mdx-style.css
├── .eslintrc.js
├── tsconfig.json
├── .eslintrc.cjs
├── vite.config.ts
├── LICENSE
├── .github
└── workflows
│ └── actions.yml
├── package.json
├── tailwind.config.js
├── .gitignore
└── README.md
/public/desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tecklens/shadcn-comments/HEAD/public/desktop.png
--------------------------------------------------------------------------------
/public/desktop2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tecklens/shadcn-comments/HEAD/public/desktop2.png
--------------------------------------------------------------------------------
/public/mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tecklens/shadcn-comments/HEAD/public/mobile.png
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/src/types/user.ts:
--------------------------------------------------------------------------------
1 |
2 | export type User = {
3 | id: string,
4 | fullName: string,
5 | userProfile?: string,
6 | avatarUrl?: string,
7 | }
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,ts,jsx,tsx}",
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": ["vite.config.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.tsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/src/App.tsx:
--------------------------------------------------------------------------------
1 | import './App.css'
2 | import 'shadcn-comments/dist/style.css';
3 | import DemoComment from "./DemoComment.tsx";
4 | import {ThemeProvider} from "./theme-provider.tsx";
5 |
6 | export default function App() {
7 |
8 | return (
9 |
10 |
11 |
12 | )
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export {Button, buttonVariants, type ButtonProps} from './components/Button';
2 | export {Avatar, AvatarFallback, AvatarImage} from './components/Avatar';
3 | export {Alert, AlertDescription, AlertTitle} from './components/Alert';
4 | export {Input} from './components/Input';
5 | export {EditorComment} from './components/EditorComment';
6 | export {CommentSection} from './components/CommentSection';
7 | export * from './types/comment'
8 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Shadcn Comments
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: { browser: true, es2020: true },
3 | extends: [
4 | 'eslint:recommended',
5 | 'plugin:@typescript-eslint/recommended',
6 | 'plugin:react-hooks/recommended',
7 | ],
8 | parser: '@typescript-eslint/parser',
9 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
10 | plugins: ['react-refresh'],
11 | rules: {
12 | 'react-refresh/only-export-components': 'warn',
13 | },
14 | }
15 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2020: true
5 | },
6 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended'],
7 | parser: '@typescript-eslint/parser',
8 | parserOptions: {
9 | ecmaVersion: 'latest',
10 | sourceType: 'module'
11 | },
12 | plugins: ['react-refresh'],
13 | rules: {
14 | 'react-refresh/only-export-components': 'warn'
15 | },
16 | ignorePatterns: ["**/node_modules/**"]
17 | };
--------------------------------------------------------------------------------
/.idea/shadcn-comments.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { ClassValue, clsx } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
8 | export function makeid(length: number) {
9 | let result = '';
10 | const characters = 'abcdefghijklmnopqrstuvwxyz'.toUpperCase();
11 | const charactersLength = characters.length;
12 | let counter = 0;
13 | while (counter < length) {
14 | result += characters.charAt(Math.floor(Math.random() * charactersLength));
15 | counter += 1;
16 | }
17 | return result;
18 | }
19 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "jsx": "react-jsxdev",
17 | "outDir": "dist",
18 | "declaration": true,
19 | "declarationMap": true,
20 | },
21 | "include": ["./src"]
22 | }
23 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
5 | "module": "ESNext",
6 | "skipLibCheck": true,
7 |
8 | /* Bundler mode */
9 | "moduleResolution": "bundler",
10 | "allowImportingTsExtensions": true,
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "noEmit": true,
14 | "jsx": "react-jsx",
15 |
16 | /* Linting */
17 | "strict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "noFallthroughCasesInSwitch": true
21 | },
22 | "include": ["src"],
23 | "references": [{ "path": "./tsconfig.node.json" }]
24 | }
25 |
--------------------------------------------------------------------------------
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2020: true
5 | },
6 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended'],
7 | parser: '@typescript-eslint/parser',
8 | parserOptions: {
9 | ecmaVersion: 'latest',
10 | sourceType: 'module'
11 | },
12 | plugins: ['react-refresh'],
13 | rules: {
14 | 'react-refresh/only-export-components': 'warn',
15 | '@typescript-eslint/no-empty-function': 'off',
16 | '@typescript-eslint/no-explicit-any': 'off',
17 | '@typescript-eslint/no-unused-vars': 'off',
18 | '@typescript-eslint/no-empty-interface': 'off',
19 | '@typescript-eslint/ban-ts-comment': 'off'
20 | },
21 | ignorePatterns: ["**/node_modules/**"]
22 | };
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | }
5 |
6 | .logo {
7 | height: 6em;
8 | padding: 1.5em;
9 | will-change: filter;
10 | transition: filter 300ms;
11 | }
12 | .logo:hover {
13 | filter: drop-shadow(0 0 2em #646cffaa);
14 | }
15 | .logo.react:hover {
16 | filter: drop-shadow(0 0 2em #61dafbaa);
17 | }
18 |
19 | @keyframes logo-spin {
20 | from {
21 | transform: rotate(0deg);
22 | }
23 | to {
24 | transform: rotate(360deg);
25 | }
26 | }
27 |
28 | @media (prefers-reduced-motion: no-preference) {
29 | a:nth-of-type(2) .logo {
30 | animation: logo-spin infinite 20s linear;
31 | }
32 | }
33 |
34 | .card {
35 | padding: 2em;
36 | }
37 |
38 | .read-the-docs {
39 | color: #888;
40 | }
41 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import { resolve } from 'path'
3 | // @ts-ignore
4 | import { peerDependencies, dependencies } from './package.json'
5 | import react from '@vitejs/plugin-react'
6 | import dts from 'vite-plugin-dts';
7 |
8 | export default defineConfig({
9 | publicDir: false,
10 | plugins: [
11 | react({
12 | 'jsxRuntime': 'classic'
13 | }),
14 | dts({
15 | include: ['src/**/*'],
16 | })
17 | ],
18 | build: {
19 | lib: {
20 | entry: resolve(__dirname, 'src', 'index.ts'),
21 | formats: ['es', 'cjs'],
22 | fileName: (ext) => `index.${ext}.js`,
23 | },
24 | rollupOptions: {
25 | external: [...Object.keys(peerDependencies), ...Object.keys(dependencies)],
26 | output: { preserveModules: true, exports: 'named' }
27 | },
28 |
29 | target: 'esnext',
30 | sourcemap: true
31 | }
32 | })
--------------------------------------------------------------------------------
/src/components/PreviewComment.tsx:
--------------------------------------------------------------------------------
1 | import type {ReactNode} from "react";
2 | import React, {useEffect, useState} from "react";
3 | import {Fragment, jsx, jsxs} from "react/jsx-runtime";
4 | import type {EvaluateOptions} from "@mdx-js/mdx";
5 | import {evaluate} from "@mdx-js/mdx";
6 | import type {MDXProps} from "mdx/types";
7 |
8 | type ReactMDXContent = (props: MDXProps) => ReactNode;
9 | type Runtime = Pick;
10 |
11 | const runtime = { jsx, jsxs, Fragment } as Runtime;
12 |
13 | const PreviewComment: any = ({ source = "hêlo" }) => {
14 | const [MdxContent, setMdxContent] = useState(() => () => null);
15 |
16 | useEffect(() => {
17 | evaluate(source, runtime).then(r => {
18 | setMdxContent(() => r.default)
19 | });
20 | }, [source]);
21 |
22 | // @ts-ignore
23 | return ;
24 | };
25 |
26 | export default PreviewComment
--------------------------------------------------------------------------------
/src/components/Input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | import { cn } from "../lib/utils"
4 |
5 | export interface InputProps
6 | extends React.InputHTMLAttributes {}
7 |
8 | const Input = React.forwardRef(
9 | ({ className, type, ...props }, ref) => {
10 | return (
11 |
20 | )
21 | }
22 | )
23 | Input.displayName = "Input"
24 |
25 | export { Input }
26 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vite-tailwind-app",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0",
15 | "shadcn-comments": "file:../.."
16 | },
17 | "devDependencies": {
18 | "@types/react": "^18.2.25",
19 | "@types/react-dom": "^18.0.11",
20 | "@typescript-eslint/eslint-plugin": "^5.57.1",
21 | "@typescript-eslint/parser": "^5.57.1",
22 | "@vitejs/plugin-react": "^4.0.0",
23 | "autoprefixer": "^10.4.14",
24 | "eslint": "^8.38.0",
25 | "eslint-plugin-react-hooks": "^4.6.0",
26 | "eslint-plugin-react-refresh": "^0.3.4",
27 | "postcss": "^8.4.47",
28 | "tailwindcss": "^3.3.2",
29 | "typescript": "^5.0.2",
30 | "vite": "^5.4.6"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Rajesh Babu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/components/EmojiSelect.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import {ACTIONS, ACTIONS_TYPE} from "../types/comment";
3 |
4 | interface EmojiSelectProps {
5 | className?: string;
6 | value?: string[];
7 | onSelect: (id: string[], changeValue: ACTIONS_TYPE) => void;
8 | onUnSelect: (id: string[], changeValue: ACTIONS_TYPE) => void;
9 | }
10 |
11 | export default function EmojiSelect({className = '', value, onSelect, onUnSelect}: EmojiSelectProps) {
12 | return (
13 |
14 | {
15 | ACTIONS.map(e => (
16 |
{
20 | if (value?.includes(e.id))
21 | onUnSelect(value?.filter(f => f != e.id), e.id)
22 | else onSelect(value ? [...value, e.id] : [e.id], e.id)
23 | }}
24 | >
25 | {e.emoji}
26 |
27 | ))
28 | }
29 |
30 | )
31 | }
--------------------------------------------------------------------------------
/src/components/Popover.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as PopoverPrimitive from "@radix-ui/react-popover"
3 |
4 | import { cn } from "../lib/utils"
5 |
6 | const Popover = PopoverPrimitive.Root
7 |
8 | const PopoverTrigger = PopoverPrimitive.Trigger
9 |
10 | const PopoverAnchor = PopoverPrimitive.Anchor
11 |
12 | const PopoverContent = React.forwardRef<
13 | React.ElementRef,
14 | React.ComponentPropsWithoutRef
15 | >(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
16 |
17 |
27 |
28 | ))
29 | PopoverContent.displayName = PopoverPrimitive.Content.displayName
30 |
31 | export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
32 |
--------------------------------------------------------------------------------
/src/types/comment.ts:
--------------------------------------------------------------------------------
1 | import {User} from "./user";
2 |
3 | export const LIST_EMOJI = [
4 | '👍',
5 | '👎',
6 | '😄',
7 | '🎉',
8 | '😕',
9 | '❤️',
10 | '🚀',
11 | '👀',
12 | ]
13 |
14 | export enum ACTIONS_TYPE {
15 | THUMB_UP = 'THUMB_UP',
16 | THUMB_DOWN = 'THUMB_DOWN',
17 | LAUGH = 'LAUGH',
18 | HOORAY = 'HOORAY',
19 | CONFUSED = 'CONFUSED',
20 | HEART = 'HEART',
21 | ROCKET = 'ROCKET',
22 | EYE = 'EYE',
23 | UPVOTE = 'UPVOTE'
24 | }
25 |
26 | export const ACTIONS = [
27 | {
28 | id: ACTIONS_TYPE.THUMB_UP,
29 | emoji: LIST_EMOJI[0]
30 | },
31 | {
32 | id: ACTIONS_TYPE.THUMB_DOWN,
33 | emoji: LIST_EMOJI[1]
34 | },
35 | {
36 | id: ACTIONS_TYPE.LAUGH,
37 | emoji: LIST_EMOJI[2]
38 | },
39 | {
40 | id: ACTIONS_TYPE.HOORAY,
41 | emoji: LIST_EMOJI[3]
42 | },
43 | {
44 | id: ACTIONS_TYPE.CONFUSED,
45 | emoji: LIST_EMOJI[4]
46 | },
47 | {
48 | id: ACTIONS_TYPE.HEART,
49 | emoji: LIST_EMOJI[5]
50 | },
51 | {
52 | id: ACTIONS_TYPE.ROCKET,
53 | emoji: LIST_EMOJI[6]
54 | },
55 | {
56 | id: ACTIONS_TYPE.EYE,
57 | emoji: LIST_EMOJI[7]
58 | },
59 | ]
60 |
61 | export type Comment = {
62 | user: User,
63 | id: string,
64 | parentId?: string;
65 | text: string,
66 | replies?: Comment[],
67 | createdAt: Date;
68 | actions?: {[key in ACTIONS_TYPE]: number};
69 | selectedActions?: ACTIONS_TYPE[];
70 | allowUpvote?: boolean;
71 | }
--------------------------------------------------------------------------------
/src/components/EditorCommentStyle2.tsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from "react";
2 | import {Avatar, AvatarFallback, AvatarImage} from "./Avatar";
3 | import {Input} from "./Input";
4 | import {Camera, SendIcon, SmileIcon} from "lucide-react";
5 | import {User} from "../types/user";
6 |
7 | interface EditorCommentStyle2Props {
8 | value?: string;
9 | onChange?: (val: string) => void;
10 | currentUser: User;
11 | }
12 |
13 | export const EditorCommentStyle2 = ({
14 | value = '',
15 | onChange = () => {
16 | },
17 | currentUser,
18 | }: EditorCommentStyle2Props) => {
19 | const [tempValue, setTempValue] = useState('')
20 | return (
21 |
22 |
23 |
24 | CN
25 |
26 |
27 |
28 | setTempValue(v.target.value)}
33 | onKeyDown={e => {
34 | if (e.code === 'Enter') {
35 | onChange(tempValue)
36 | setTempValue('')
37 | }
38 | }}
39 | />
40 |
41 |
42 | )
43 | }
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
7 | line-height: 1.5;
8 | font-weight: 400;
9 |
10 | color-scheme: light dark;
11 | color: rgba(255, 255, 255, 0.87);
12 | background-color: #242424;
13 |
14 | font-synthesis: none;
15 | text-rendering: optimizeLegibility;
16 | -webkit-font-smoothing: antialiased;
17 | -moz-osx-font-smoothing: grayscale;
18 | -webkit-text-size-adjust: 100%;
19 | }
20 |
21 | a {
22 | font-weight: 500;
23 | color: #646cff;
24 | text-decoration: inherit;
25 | }
26 | a:hover {
27 | color: #535bf2;
28 | }
29 |
30 | body {
31 | margin: 0;
32 | display: flex;
33 | place-items: center;
34 | min-width: 320px;
35 | min-height: 100vh;
36 | }
37 |
38 | h1 {
39 | font-size: 3.2em;
40 | line-height: 1.1;
41 | }
42 |
43 | button {
44 | border-radius: 8px;
45 | border: 1px solid transparent;
46 | padding: 0.6em 1.2em;
47 | font-size: 1em;
48 | font-weight: 500;
49 | font-family: inherit;
50 | background-color: #1a1a1a;
51 | cursor: pointer;
52 | transition: border-color 0.25s;
53 | }
54 | button:hover {
55 | border-color: #646cff;
56 | }
57 | button:focus,
58 | button:focus-visible {
59 | outline: 4px auto -webkit-focus-ring-color;
60 | }
61 |
62 | @media (prefers-color-scheme: light) {
63 | :root {
64 | color: #213547;
65 | background-color: #ffffff;
66 | }
67 | a:hover {
68 | color: #747bff;
69 | }
70 | button {
71 | background-color: #f9f9f9;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/components/Avatar.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import * as AvatarPrimitive from "@radix-ui/react-avatar"
3 |
4 | import { cn } from "../lib/utils";
5 |
6 | const Avatar = React.forwardRef<
7 | React.ElementRef,
8 | React.ComponentPropsWithoutRef
9 | >(({ className, ...props }, ref) => (
10 |
18 | ))
19 | Avatar.displayName = AvatarPrimitive.Root.displayName
20 |
21 | const AvatarImage = React.forwardRef<
22 | React.ElementRef,
23 | React.ComponentPropsWithoutRef
24 | >(({ className, ...props }, ref) => (
25 |
30 | ))
31 | AvatarImage.displayName = AvatarPrimitive.Image.displayName
32 |
33 | const AvatarFallback = React.forwardRef<
34 | React.ElementRef,
35 | React.ComponentPropsWithoutRef
36 | >(({ className, ...props }, ref) => (
37 |
45 | ))
46 | AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
47 |
48 | export { Avatar, AvatarImage, AvatarFallback }
49 |
--------------------------------------------------------------------------------
/.github/workflows/actions.yml:
--------------------------------------------------------------------------------
1 | # Simple workflow for deploying static content to GitHub Pages
2 | name: Deploy static content to Pages
3 |
4 | on:
5 | # Runs on pushes targeting the default branch
6 | push:
7 | branches: ['main']
8 |
9 | # Allows you to run this workflow manually from the Actions tab
10 | workflow_dispatch:
11 |
12 | # Sets the GITHUB_TOKEN permissions to allow deployment to GitHub Pages
13 | permissions:
14 | contents: read
15 | pages: write
16 | id-token: write
17 |
18 | # Allow one concurrent deployment
19 | concurrency:
20 | group: 'pages'
21 | cancel-in-progress: true
22 |
23 | jobs:
24 | # Single deploy job since we're just deploying
25 | deploy:
26 | environment:
27 | name: github-pages
28 | url: ${{ steps.deployment.outputs.page_url }}
29 | runs-on: ubuntu-latest
30 | defaults:
31 | run:
32 | working-directory: ./examples/vite-tailwind-app
33 | steps:
34 | - name: Checkout
35 | uses: actions/checkout@v4
36 | - name: Set up Node
37 | uses: actions/setup-node@v4
38 | with:
39 | node-version: 18
40 | cache: 'npm'
41 | - name: Install dependencies
42 | run: npm i
43 | - name: Build
44 | run: npm run build
45 | - name: Setup Pages
46 | uses: actions/configure-pages@v4
47 | - name: Upload artifact
48 | uses: actions/upload-pages-artifact@v3
49 | with:
50 | # Upload dist folder
51 | path: './examples/vite-tailwind-app/dist'
52 | - name: Deploy to GitHub Pages
53 | id: deployment
54 | uses: actions/deploy-pages@v4
55 |
--------------------------------------------------------------------------------
/src/components/Alert.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { cva, type VariantProps } from "class-variance-authority"
3 |
4 | import { cn } from "../lib/utils"
5 |
6 | const alertVariants = cva(
7 | "relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11",
8 | {
9 | variants: {
10 | variant: {
11 | default: "bg-background text-foreground",
12 | destructive:
13 | "text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive",
14 | },
15 | },
16 | defaultVariants: {
17 | variant: "default",
18 | },
19 | }
20 | )
21 |
22 | const Alert = React.forwardRef<
23 | HTMLDivElement,
24 | React.HTMLAttributes & VariantProps
25 | >(({ className, variant, ...props }, ref) => (
26 |
32 | ))
33 | Alert.displayName = "Alert"
34 |
35 | const AlertTitle = React.forwardRef<
36 | HTMLParagraphElement,
37 | React.HTMLAttributes
38 | >(({ className, ...props }, ref) => (
39 |
44 | ))
45 | AlertTitle.displayName = "AlertTitle"
46 |
47 | const AlertDescription = React.forwardRef<
48 | HTMLParagraphElement,
49 | React.HTMLAttributes
50 | >(({ className, ...props }, ref) => (
51 |
56 | ))
57 | AlertDescription.displayName = "AlertDescription"
58 |
59 | export { Alert, AlertTitle, AlertDescription }
60 |
--------------------------------------------------------------------------------
/src/components/Button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 | import { Slot } from "@radix-ui/react-slot"
3 | import { cva, type VariantProps } from "class-variance-authority"
4 |
5 | import { cn } from "../lib/utils"
6 |
7 | const buttonVariants = cva(
8 | "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
9 | {
10 | variants: {
11 | variant: {
12 | default: "bg-primary text-primary-foreground hover:bg-primary/90",
13 | destructive:
14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90",
15 | outline:
16 | "border border-input hover:bg-accent hover:text-accent-foreground",
17 | secondary:
18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19 | ghost: "hover:bg-accent hover:text-accent-foreground",
20 | link: "underline-offset-4 hover:underline text-primary",
21 | },
22 | size: {
23 | default: "h-9 px-4 py-2",
24 | sm: "h-8 rounded-md px-3 text-xs",
25 | lg: "h-10 rounded-md px-8",
26 | icon: "h-9 w-9",
27 | },
28 | },
29 | defaultVariants: {
30 | variant: "default",
31 | size: "default",
32 | },
33 | }
34 | )
35 |
36 | export interface ButtonProps
37 | extends React.ButtonHTMLAttributes,
38 | VariantProps {
39 | asChild?: boolean
40 | }
41 |
42 | const Button = React.forwardRef(
43 | ({ className, variant, size, asChild = false, ...props }, ref) => {
44 | const Comp = asChild ? Slot : "button"
45 | return (
46 |
51 | )
52 | }
53 | )
54 | Button.displayName = "Button"
55 |
56 | export { Button, buttonVariants }
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shadcn-comments",
3 | "description": "Shadcn React component library for a functioning comments section",
4 | "private": false,
5 | "version": "1.0.5",
6 | "type": "module",
7 | "main": "dist/index.cjs.js",
8 | "module": "dist/index.es.js",
9 | "types": "dist/index.d.ts",
10 | "sideEffects": false,
11 | "files": [
12 | "dist"
13 | ],
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/tecklens/shadcn-comments"
17 | },
18 | "scripts": {
19 | "dev": "vite",
20 | "build": "tsc && vite build && npm run build:styles",
21 | "build:styles": "postcss ./src/index.css -o ./dist/style.css && postcss ./src/mdx-style.css -o ./dist/mdx-style.css",
22 | "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
23 | },
24 | "peerDependencies": {
25 | "react": "^18.3.1",
26 | "react-dom": "^18.3.1"
27 | },
28 | "dependencies": {
29 | "@mdx-js/mdx": "^3.0.1",
30 | "@mdx-js/react": "^3.0.1",
31 | "@mdxeditor/editor": "^3.11.3",
32 | "@radix-ui/react-avatar": "^1.0.3",
33 | "@radix-ui/react-popover": "^1.1.2",
34 | "@radix-ui/react-slot": "^1.0.2",
35 | "class-variance-authority": "^0.6.0",
36 | "clsx": "^1.2.1",
37 | "date-fns": "^3.6.0",
38 | "lucide-react": "^0.453.0",
39 | "tailwind-merge": "^1.12.0",
40 | "tailwindcss-animate": "^1.0.5"
41 | },
42 | "devDependencies": {
43 | "@types/react": "^18.3.5",
44 | "@types/react-dom": "^18.3.0",
45 | "@typescript-eslint/eslint-plugin": "^5.57.1",
46 | "@typescript-eslint/parser": "^5.57.1",
47 | "@vitejs/plugin-react": "^4.0.0",
48 | "autoprefixer": "^10.4.14",
49 | "eslint": "^8.38.0",
50 | "eslint-plugin-react-hooks": "^4.6.0",
51 | "eslint-plugin-react-refresh": "^0.3.4",
52 | "postcss": "^8.4.47",
53 | "postcss-cli": "^10.1.0",
54 | "prop-types": "^15.8.1",
55 | "tailwindcss": "^3.3.2",
56 | "typescript": "^5.0.2",
57 | "vite": "^5.4.6",
58 | "vite-plugin-dts": "^2.3.0"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/src/theme-provider.tsx:
--------------------------------------------------------------------------------
1 | import { createContext, useContext, useEffect, useState } from 'react'
2 |
3 | type Theme = 'dark' | 'light' | 'system'
4 |
5 | type ThemeProviderProps = {
6 | children: React.ReactNode
7 | defaultTheme?: Theme
8 | storageKey?: string
9 | }
10 |
11 | type ThemeProviderState = {
12 | theme: Theme
13 | setTheme: (theme: Theme) => void
14 | }
15 |
16 | const initialState: ThemeProviderState = {
17 | theme: 'system',
18 | setTheme: () => null,
19 | }
20 |
21 | const ThemeProviderContext = createContext(initialState)
22 |
23 | export function ThemeProvider({
24 | children,
25 | defaultTheme = 'system',
26 | storageKey = 'theme',
27 | ...props
28 | }: ThemeProviderProps) {
29 | const [theme, setTheme] = useState(
30 | () => (localStorage.getItem(storageKey) as Theme) || defaultTheme,
31 | )
32 |
33 | useEffect(() => {
34 | const root = window.document.documentElement
35 |
36 | root.classList.remove('light', 'dark')
37 |
38 | if (theme === 'system') {
39 | const systemTheme = window.matchMedia('(prefers-color-scheme: dark)')
40 | .matches
41 | ? 'dark'
42 | : 'light'
43 |
44 | root.classList.add(systemTheme)
45 | return
46 | }
47 |
48 | root.classList.add(theme)
49 | }, [theme])
50 |
51 | const value = {
52 | theme,
53 | setTheme: (theme: Theme) => {
54 | localStorage.setItem(storageKey, theme)
55 | setTheme(theme)
56 | },
57 | }
58 |
59 | return (
60 |
61 |
62 | {children}
63 |
64 |
65 | )
66 | }
67 |
68 | // eslint-disable-next-line react-refresh/only-export-components
69 | export const useTheme = () => {
70 | const context = useContext(ThemeProviderContext)
71 |
72 | if (context === undefined)
73 | throw new Error('useTheme must be used within a ThemeProvider')
74 |
75 | return context
76 | }
77 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | const { fontFamily } = require("tailwindcss/defaultTheme")
2 |
3 | /** @type {import('tailwindcss').Config} */
4 | module.exports = {
5 | darkMode: ["class"],
6 | content: ["./src/**/*.{js,ts,jsx,tsx}"],
7 | safelist: [
8 | 'dark'
9 | ],
10 | theme: {
11 | container: {
12 | center: true,
13 | padding: "2rem",
14 | screens: {
15 | "2xl": "1400px",
16 | },
17 | },
18 | extend: {
19 | colors: {
20 | border: "hsl(var(--border))",
21 | input: "hsl(var(--input))",
22 | ring: "hsl(var(--ring))",
23 | background: "hsl(var(--background))",
24 | foreground: "hsl(var(--foreground))",
25 | primary: {
26 | DEFAULT: "hsl(var(--primary))",
27 | foreground: "hsl(var(--primary-foreground))",
28 | },
29 | secondary: {
30 | DEFAULT: "hsl(var(--secondary))",
31 | foreground: "hsl(var(--secondary-foreground))",
32 | },
33 | destructive: {
34 | DEFAULT: "hsl(var(--destructive))",
35 | foreground: "hsl(var(--destructive-foreground))",
36 | },
37 | muted: {
38 | DEFAULT: "hsl(var(--muted))",
39 | foreground: "hsl(var(--muted-foreground))",
40 | },
41 | accent: {
42 | DEFAULT: "hsl(var(--accent))",
43 | foreground: "hsl(var(--accent-foreground))",
44 | },
45 | popover: {
46 | DEFAULT: "hsl(var(--popover))",
47 | foreground: "hsl(var(--popover-foreground))",
48 | },
49 | card: {
50 | DEFAULT: "hsl(var(--card))",
51 | foreground: "hsl(var(--card-foreground))",
52 | },
53 | },
54 | borderRadius: {
55 | lg: `var(--radius)`,
56 | md: `calc(var(--radius) - 2px)`,
57 | sm: "calc(var(--radius) - 4px)",
58 | },
59 | fontFamily: {
60 | sans: ["var(--font-sans)", ...fontFamily.sans],
61 | },
62 | keyframes: {
63 | "accordion-down": {
64 | from: { height: 0 },
65 | to: { height: "var(--radix-accordion-content-height)" },
66 | },
67 | "accordion-up": {
68 | from: { height: "var(--radix-accordion-content-height)" },
69 | to: { height: 0 },
70 | },
71 | },
72 | animation: {
73 | "accordion-down": "accordion-down 0.2s ease-out",
74 | "accordion-up": "accordion-up 0.2s ease-out",
75 | },
76 | },
77 | },
78 | plugins: [require("tailwindcss-animate")],
79 | }
80 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 | .pnpm-debug.log*
9 |
10 | # Diagnostic reports (https://nodejs.org/api/report.html)
11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12 |
13 | # Runtime data
14 | pids
15 | *.pid
16 | *.seed
17 | *.pid.lock
18 |
19 | # Directory for instrumented libs generated by jscoverage/JSCover
20 | lib-cov
21 |
22 | # Coverage directory used by tools like istanbul
23 | coverage
24 | *.lcov
25 |
26 | # nyc test coverage
27 | .nyc_output
28 |
29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30 | .grunt
31 |
32 | # Bower dependency directory (https://bower.io/)
33 | bower_components
34 |
35 | # node-waf configuration
36 | .lock-wscript
37 |
38 | # Compiled binary addons (https://nodejs.org/api/addons.html)
39 | build/Release
40 |
41 | # Dependency directories
42 | node_modules/
43 | jspm_packages/
44 |
45 | # Snowpack dependency directory (https://snowpack.dev/)
46 | web_modules/
47 |
48 | # TypeScript cache
49 | *.tsbuildinfo
50 |
51 | # Optional npm cache directory
52 | .npm
53 |
54 | # Optional eslint cache
55 | .eslintcache
56 |
57 | # Optional stylelint cache
58 | .stylelintcache
59 |
60 | # Microbundle cache
61 | .rpt2_cache/
62 | .rts2_cache_cjs/
63 | .rts2_cache_es/
64 | .rts2_cache_umd/
65 |
66 | # Optional REPL history
67 | .node_repl_history
68 |
69 | # Output of 'npm pack'
70 | *.tgz
71 |
72 | # Yarn Integrity file
73 | .yarn-integrity
74 |
75 | # dotenv environment variable files
76 | .env
77 | .env.development.local
78 | .env.test.local
79 | .env.production.local
80 | .env.local
81 |
82 | # parcel-bundler cache (https://parceljs.org/)
83 | .cache
84 | .parcel-cache
85 |
86 | # Next.js build output
87 | .next
88 | out
89 |
90 | # Nuxt.js build / generate output
91 | .nuxt
92 | dist
93 |
94 | # Gatsby files
95 | .cache/
96 | # EditorComment in the public line in if your project uses Gatsby and not Next.js
97 | # https://nextjs.org/blog/next-9-1#public-directory-support
98 | # public
99 |
100 | # vuepress build output
101 | .vuepress/dist
102 |
103 | # vuepress v2.x temp and cache directory
104 | .temp
105 | .cache
106 |
107 | # Docusaurus cache and generated files
108 | .docusaurus
109 |
110 | # Serverless directories
111 | .serverless/
112 |
113 | # FuseBox cache
114 | .fusebox/
115 |
116 | # DynamoDB Local files
117 | .dynamodb/
118 |
119 | # TernJS port file
120 | .tern-port
121 |
122 | # Stores VSCode versions used for testing VSCode extensions
123 | .vscode-test
124 |
125 | # yarn v2
126 | .yarn/cache
127 | .yarn/unplugged
128 | .yarn/build-state.yml
129 | .yarn/install-state.gz
130 | .pnp.*
131 |
--------------------------------------------------------------------------------
/src/components/DropdownMenu.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useRef, useState} from "react";
2 | import {EllipsisVertical} from "lucide-react";
3 | import {Comment} from "../types/comment";
4 | import {User} from "../types/user";
5 |
6 | export function DropdownMenu({comment, openEditor, currentUser, deleteComment}: {
7 | comment: Comment,
8 | openEditor: () => void,
9 | deleteComment: () => void,
10 | currentUser: User
11 | }) {
12 | const ref = useRef()
13 | const [open, setOpen] = useState(false)
14 |
15 | const copyToClipboard = async () => {
16 | const textToCopy = window.location.host + `#comment-${comment.id}`;
17 | // Navigator clipboard api needs a secure context (https)
18 | if (navigator.clipboard && window.isSecureContext) {
19 | await navigator.clipboard.writeText(textToCopy ?? '');
20 | setOpen(false)
21 | }
22 | }
23 |
24 | const del = () => {
25 | setOpen(false)
26 | if (confirm('Are you sure you want to delete this?')) {
27 | deleteComment()
28 | }
29 | }
30 |
31 | useEffect(() => {
32 | /**
33 | * Alert if clicked on outside of element
34 | */
35 | function handleClickOutside(event: any) {
36 | if (ref.current && !ref.current.contains(event.target)) {
37 | if (open) setOpen(false)
38 | }
39 | }
40 |
41 | // Bind the event listener
42 | document.addEventListener("mousedown", handleClickOutside);
43 | return () => {
44 | // Unbind the event listener on clean up
45 | document.removeEventListener("mousedown", handleClickOutside);
46 | };
47 | }, [open, ref]);
48 |
49 | return (
50 |
51 |
setOpen(!open)} className={'w-8 h-8 flex justify-center items-center cursor-pointer dropbtn'}>
52 |
53 |
54 |
57 |
63 | {currentUser.id === comment.user.id &&
{
65 | openEditor()
66 | setOpen(false)
67 | }}
68 | className={'px-3 py-2 text-sm hover:bg-blue-500 hover:text-white'}
69 | >
70 |
Edit
71 |
}
72 | {currentUser.id === comment.user.id &&
}
78 |
79 |
80 | )
81 | }
--------------------------------------------------------------------------------
/examples/vite-tailwind-app/src/DemoComment.tsx:
--------------------------------------------------------------------------------
1 | import {useState} from "react";
2 | import {Terminal} from "lucide-react";
3 | import {useTheme} from "./theme-provider.tsx";
4 | import {Alert, AlertDescription, AlertTitle, Button, CommentSection, ACTIONS_TYPE} from 'shadcn-comments'
5 |
6 | export default function DemoComment() {
7 | const {theme, setTheme} = useTheme()
8 | const [value, setValue] = useState([
9 | {
10 | user: {
11 | id: '1',
12 | userProfile: '',
13 | fullName: 'victorcesae',
14 | avatarUrl: ''
15 | },
16 | id: '2',
17 | text: 'Another utility is to add text adornments, doing some simple typechecking so if a string is passed you can style a background, else render the react node.',
18 | replies: [],
19 | createdAt: new Date('2024-06-01'),
20 | selectedActions: [ACTIONS_TYPE.UPVOTE, ACTIONS_TYPE.ROCKET, ACTIONS_TYPE.HEART],
21 | actions: {
22 | [ACTIONS_TYPE.UPVOTE]: 1,
23 | [ACTIONS_TYPE.ROCKET]: 10,
24 | [ACTIONS_TYPE.HEART]: 10,
25 | }
26 | },
27 | {
28 | user: {
29 | id: '4',
30 | userProfile: '',
31 | fullName: 'UltimateGG',
32 | avatarUrl: ''
33 | },
34 | id: '3',
35 | text: 'Another utility is to add text adornments, doing some simple typechecking so if a string is passed you can style a background, else render the react node.',
36 | replies: [{
37 | user: {
38 | id: '4',
39 | userProfile: '',
40 | fullName: 'UltimateGG',
41 | avatarUrl: ''
42 | },
43 | id: '8',
44 | text: 'Another utility is to add text adornments',
45 | replies: [],
46 | createdAt: new Date('2024-09-02')
47 | }],
48 | createdAt: new Date('2024-09-01')
49 | }
50 | ])
51 |
52 | const toggleDarkMode = () => {
53 | setTheme(theme === 'light' ? 'dark' : 'light');
54 | };
55 |
56 | return (
57 |
58 |
59 |
60 | Built using shadcn-comments
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | Heads up!
69 |
70 | You can add components and dependencies to your app using the cli.
71 |
72 |
73 |
74 |
75 |
{
85 | setValue(val)
86 | }}
87 | className={''}
88 | allowUpVote={true}
89 | />
90 |
91 | )
92 | }
--------------------------------------------------------------------------------
/src/components/EditingEditorComment.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from "react";
2 | import {
3 | BlockTypeSelect,
4 | BoldItalicUnderlineToggles,
5 | CreateLink,
6 | headingsPlugin,
7 | imagePlugin,
8 | InsertImage,
9 | InsertTable,
10 | linkDialogPlugin,
11 | linkPlugin,
12 | listsPlugin,
13 | ListsToggle,
14 | markdownShortcutPlugin,
15 | MDXEditor,
16 | quotePlugin,
17 | Separator,
18 | tablePlugin,
19 | thematicBreakPlugin,
20 | toolbarPlugin,
21 | UndoRedo
22 | } from "@mdxeditor/editor";
23 | import {Button} from "./Button";
24 | import {User} from "../types/user";
25 |
26 | interface EditorCommentProps {
27 | value?: string;
28 | onChange?: (val: string) => void;
29 | placeholder?: string,
30 | onUpload?: (image: File) => Promise;
31 | theme: 'light' | 'dark' | 'system',
32 | currentUser: User;
33 | }
34 |
35 | export const EditingEditorComment = ({
36 | value = '', onChange = () => {
37 | },
38 | placeholder = 'Add your comment here...',
39 | onUpload,
40 | theme,
41 | currentUser,
42 | }: EditorCommentProps) => {
43 | const [tempValue, setTempValue] = useState(value)
44 |
45 | return (
46 |
47 |
48 |
49 |
(
58 |
59 | {' '}
60 |
61 |
62 |
63 |
64 | {/*
72 | )
73 | }),
74 | headingsPlugin(),
75 | listsPlugin(),
76 | quotePlugin(),
77 | thematicBreakPlugin(),
78 | markdownShortcutPlugin(),
79 | tablePlugin(),
80 | imagePlugin({
81 | imageUploadHandler: onUpload,
82 | }),
83 | linkPlugin(),
84 | linkDialogPlugin(),
85 | ]}
86 | />
87 |
88 |
89 |
90 |
93 |
97 |
98 |
99 | )
100 | }
--------------------------------------------------------------------------------
/src/components/EditorComment.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, useState} from "react";
2 | import {
3 | BlockTypeSelect,
4 | BoldItalicUnderlineToggles,
5 | CreateLink,
6 | headingsPlugin,
7 | imagePlugin,
8 | InsertImage,
9 | InsertTable,
10 | linkDialogPlugin,
11 | linkPlugin,
12 | listsPlugin,
13 | ListsToggle,
14 | markdownShortcutPlugin,
15 | MDXEditor,
16 | quotePlugin,
17 | Separator,
18 | tablePlugin,
19 | thematicBreakPlugin,
20 | toolbarPlugin,
21 | UndoRedo
22 | } from "@mdxeditor/editor";
23 | import {Avatar, AvatarFallback, AvatarImage} from "./Avatar";
24 | import {Button} from "./Button";
25 | import {User} from "../types/user";
26 |
27 | interface EditorCommentProps {
28 | value?: string;
29 | onChange?: (val: string) => void;
30 | placeholder?: string,
31 | onUpload?: (image: File) => Promise;
32 | theme: 'light' | 'dark' | 'system',
33 | currentUser: User;
34 | }
35 |
36 | export const EditorComment = ({
37 | value = '', onChange = () => {
38 | },
39 | placeholder = 'Add your comment here...',
40 | onUpload,
41 | theme,
42 | currentUser,
43 | }: EditorCommentProps) => {
44 | const [tempValue, setTempValue] = useState('')
45 |
46 | useEffect(() => {
47 | setTempValue(value)
48 | }, [value])
49 |
50 | return (
51 |
52 |
53 |
54 |
55 | CN
56 |
57 |
58 |
59 |
(
68 |
69 | {' '}
70 |
71 |
72 |
73 |
74 | {/*
82 | )
83 | }),
84 | headingsPlugin(),
85 | listsPlugin(),
86 | quotePlugin(),
87 | thematicBreakPlugin(),
88 | markdownShortcutPlugin(),
89 | tablePlugin(),
90 | imagePlugin({
91 | imageUploadHandler: onUpload,
92 | }),
93 | linkPlugin(),
94 | linkDialogPlugin(),
95 | ]}
96 | />
97 |
98 |
99 |
100 |
104 |
105 |
106 | )
107 | }
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @import "./mdx-style.css";
2 |
3 | @tailwind base;
4 | @tailwind components;
5 | @tailwind utilities;
6 |
7 | @layer base {
8 | :root {
9 | --background: 0 0% 100%;
10 | --foreground: 222.2 47.4% 11.2%;
11 |
12 | --muted: 210 40% 96.1%;
13 | --muted-foreground: 215.4 16.3% 46.9%;
14 |
15 | --popover: 0 0% 100%;
16 | --popover-foreground: 222.2 47.4% 11.2%;
17 |
18 | --card: 0 0% 100%;
19 | --card-foreground: 222.2 47.4% 11.2%;
20 |
21 | --border: 214.3 31.8% 91.4%;
22 | --input: 214.3 31.8% 91.4%;
23 |
24 | --primary: 222.2 47.4% 11.2%;
25 | --primary-foreground: 210 40% 98%;
26 |
27 | --secondary: 210 40% 96.1%;
28 | --secondary-foreground: 222.2 47.4% 11.2%;
29 |
30 | --accent: 210 40% 96.1%;
31 | --accent-foreground: 222.2 47.4% 11.2%;
32 |
33 | --destructive: 0 100% 50%;
34 | --destructive-foreground: 210 40% 98%;
35 |
36 | --ring: 215 20.2% 65.1%;
37 |
38 | --radius: 0.5rem;
39 |
40 | --caret-bg: #f6f8fa;
41 | --caret-border: #d1d9e0;
42 | }
43 |
44 | .dark {
45 | --background: 224 71% 4%;
46 | --foreground: 213 31% 91%;
47 |
48 | --muted: 223 47% 11%;
49 | --muted-foreground: 215.4 16.3% 56.9%;
50 |
51 | --popover: 224 71% 4%;
52 | --popover-foreground: 215 20.2% 65.1%;
53 |
54 | --card: 224 71% 4%;
55 | --card-foreground: 213 31% 91%;
56 |
57 | --border: 216 34% 17%;
58 | --input: 216 34% 17%;
59 |
60 | --primary: 210 40% 98%;
61 | --primary-foreground: 222.2 47.4% 1.2%;
62 |
63 | --secondary: 222.2 47.4% 11.2%;
64 | --secondary-foreground: 210 40% 98%;
65 |
66 | --accent: 216 34% 17%;
67 | --accent-foreground: 210 40% 98%;
68 |
69 | --destructive: 0 63% 31%;
70 | --destructive-foreground: 210 40% 98%;
71 |
72 | --ring: 216 34% 17%;
73 |
74 | --radius: 0.5rem;
75 |
76 | --caret-bg: #3d444d;
77 | --caret-border: #d1d9e0;
78 | }
79 | }
80 |
81 | @layer base {
82 | * {
83 | @apply border-border;
84 | }
85 |
86 | body {
87 | @apply bg-background text-foreground;
88 | font-feature-settings: "rlig" 1, "calt" 1;
89 | }
90 | }
91 |
92 | .s-comment-card {
93 | position: relative;
94 | }
95 |
96 | .s-comment-card .user {
97 | background-color: var(--caret-bg);
98 | }
99 |
100 | .s-comment-card::before {
101 | background-color: var(--caret-border);
102 | color: var(--caret-bg);
103 | position: absolute;
104 | top: 11px;
105 | right: 100%;
106 | left: calc(0.5rem * -1);
107 | display: block;
108 | width: 8px;
109 | height: 16px;
110 | pointer-events: none;
111 | content: " ";
112 | clip-path: polygon(0 50%, 100% 0, 100% 100%);
113 | }
114 |
115 | .s-comment-card::after {
116 | margin-left: 1px;
117 | background-color: var(--caret-bg);
118 | position: absolute;
119 | top: 11px;
120 | right: 100%;
121 | left: calc(0.5rem * -1);
122 | display: block;
123 | width: 8px;
124 | height: 16px;
125 | pointer-events: none;
126 | content: " ";
127 | clip-path: polygon(0 50%, 100% 0, 100% 100%);
128 | }
129 |
130 | /* The container - needed to position the dropdown content */
131 | .dropdown {
132 | position: relative;
133 | display: inline-block;
134 | }
135 |
136 | /* Dropdown Content (Hidden by Default) */
137 | .dropdown-content {
138 | display: none;
139 | position: absolute;
140 | background-color: var(--caret-bg);
141 | width: 160px;
142 | right: 0;
143 | box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
144 | z-index: 3;
145 | }
146 |
147 | /* Change color of dropdown links on hover */
148 | .dropdown-content a:hover {background-color: #f1f1f1}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Shadcn Comments
2 |
3 | ---
4 | [Demo](https://shadcn-comment.pages.dev/)
5 | ## Install
6 |
7 | Install the latest version!
8 |
9 | ```shell
10 | npm i shadcn-comments
11 | ```
12 | ---
13 |
14 | `shadcn-comments` is a simple but multi-functional shadcn-react comment section component that helps you create
15 | comments section similar to github for your React App. `shadcn-comments` is very useful for react beginners
16 | who want a comment section in their project but want to skip it's commplexity.
17 | This library will give a fully functional comment section with the
18 | following features:
19 |
20 | - User can reply to comments
21 | - User can edit his/her comments
22 | - User can delete his/her comments
23 |
24 | Live demo of the library: [here](#)
25 |
26 | ---
27 |
28 | ## Default Example
29 |
30 | You can find the source code [here](#)
31 | ### Mobile
32 | 
33 | ### Desktop (max-w-screen-md)
34 | 
35 |
36 | ### Desktop editing (max-w-screen-md)
37 | 
38 |
39 | ---
40 |
41 | ## Usage
42 |
43 | Following is a basic example to start testing the library in your project. This library works on a user basis system and here are a few important points to remember:
44 |
45 | | Props | Data Types | Default |
46 | |--------------|-------------------------------|---------|
47 | | theme | 'light' \| 'dark' \| 'system' | light |
48 | | currentUser | [User](#types) | default |
49 | | value | [Comment\[\]](#types) | [] |
50 | | onChange | (comments: Comment[]) => void | |
51 | | className | string | |
52 | | allowUpVote | boolean | false |
53 | | onVoteChange | (checked: boolean) => void | false |
54 |
55 | ```tsx
56 | import {useState} from "react";
57 | import {Terminal} from "lucide-react";
58 | import {useTheme} from "./theme-provider.tsx";
59 | import {Alert, AlertDescription, AlertTitle, Button, CommentSection, ACTIONS_TYPE} from 'shadcn-comments'
60 |
61 | export default function DemoComment() {
62 | const {theme, setTheme} = useTheme()
63 | const [value, setValue] = useState
([
64 | {
65 | user: {
66 | id: '1',
67 | userProfile: '',
68 | fullName: 'victorcesae',
69 | avatarUrl: ''
70 | },
71 | id: '2',
72 | text: 'Another utility is to add text adornments, doing some simple typechecking so if a string is passed you can style a background, else render the react node.',
73 | replies: [],
74 | createdAt: new Date('2024-06-01'),
75 | selectedActions: [ACTIONS_TYPE.UPVOTE, ACTIONS_TYPE.ROCKET, ACTIONS_TYPE.HEART],
76 | actions: {
77 | [ACTIONS_TYPE.UPVOTE]: 1,
78 | [ACTIONS_TYPE.ROCKET]: 10,
79 | [ACTIONS_TYPE.HEART]: 10,
80 | }
81 | },
82 | {
83 | user: {
84 | id: '4',
85 | userProfile: '',
86 | fullName: 'UltimateGG',
87 | avatarUrl: ''
88 | },
89 | id: '3',
90 | text: 'Another utility is to add text adornments, doing some simple typechecking so if a string is passed you can style a background, else render the react node.',
91 | replies: [{
92 | user: {
93 | id: '4',
94 | userProfile: '',
95 | fullName: 'UltimateGG',
96 | avatarUrl: ''
97 | },
98 | id: '8',
99 | text: 'Another utility is to add text adornments',
100 | replies: [],
101 | createdAt: new Date('2024-09-02')
102 | }],
103 | createdAt: new Date('2024-09-01')
104 | }
105 | ])
106 |
107 | const toggleDarkMode = () => {
108 | setTheme(theme === 'light' ? 'dark' : 'light');
109 | };
110 |
111 | return (
112 |
113 |
114 |
115 | Built using shadcn-comments
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | Heads up!
124 |
125 | You can add components and dependencies to your app using the cli.
126 |
127 |
128 |
129 |
130 |
{
140 | setValue(val)
141 | }}
142 | className={''}
143 | allowUpVote={true}
144 | />
145 |
146 | )
147 | }
148 | ```
149 | ---
150 |
151 | ### Types
152 |
153 | ```typescript
154 | // User
155 | export type User = {
156 | id: string,
157 | fullName: string,
158 | userProfile?: string,
159 | avatarUrl?: string,
160 | }
161 | ```
162 |
163 | ```typescript
164 | // Comment
165 | export type Comment = {
166 | user: User,
167 | id: string,
168 | parentId?: string;
169 | text: string,
170 | replies?: Comment[],
171 | createdAt: Date;
172 | }
173 | ```
174 | ---
175 | ## Change log
176 |
177 | v1.0.3: add edit/delete/copy link/actions emoji for comment
178 | ---
179 |
180 | ## License
181 |
182 | MIT © [dieptv1999](https://github.com/dieptv1999)
--------------------------------------------------------------------------------
/src/components/CommentSection.tsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from "react";
2 | import {Avatar, AvatarFallback, AvatarImage} from "./Avatar";
3 | import {ArrowUpIcon, CircleIcon, SmileIcon} from "lucide-react";
4 | import {EditorComment} from "./EditorComment";
5 | import {ACTIONS, ACTIONS_TYPE, Comment} from "../types/comment";
6 | import {User} from "../types/user";
7 | import {EditorCommentStyle2} from "./EditorCommentStyle2";
8 | import {makeid} from "../lib/utils";
9 | import {MDXProvider} from "@mdx-js/react";
10 | import PreviewComment from "./PreviewComment";
11 | import {formatDistance} from 'date-fns';
12 | import {Popover, PopoverContent, PopoverTrigger} from "./Popover";
13 | import EmojiSelect from "./EmojiSelect";
14 | import {DropdownMenu} from "./DropdownMenu";
15 | import {EditingEditorComment} from "./EditingEditorComment";
16 |
17 | interface CommentProps {
18 | className?: string;
19 | isMdxEditor?: boolean;
20 | formatDate?: string;
21 | value: Comment[];
22 | currentUser: User,
23 | onChange?: (value: Comment[]) => void,
24 | theme: 'light' | 'dark' | 'system',
25 | allowUpVote?: boolean;
26 | onVoteChange?: (checked: boolean) => void
27 | }
28 |
29 | interface CommentCardProps {
30 | comment: Comment,
31 | onReply: (val: string) => void,
32 | currentUser: User,
33 | allowUpVote?: boolean;
34 | onChange: (change: any) => void;
35 | onDelete: () => void;
36 | onVoteChange: (change: boolean) => void;
37 | theme: 'light' | 'dark' | 'system',
38 | }
39 |
40 | export const CommentCard = ({
41 | comment,
42 | onReply = () => {
43 | },
44 | currentUser,
45 | allowUpVote,
46 | onChange,
47 | onVoteChange,
48 | theme,
49 | onDelete,
50 | }: CommentCardProps) => {
51 | const [replying, setReplying] = useState(false)
52 | const [editing, setEditing] = useState(false)
53 |
54 | const actions = ACTIONS.filter(e => comment.actions && comment.actions[e.id] && comment.selectedActions?.includes(e.id))
55 |
56 | const upvote = (comment.actions ?? {})[ACTIONS_TYPE.UPVOTE];
57 |
58 | const upvoted = comment.selectedActions?.includes(ACTIONS_TYPE.UPVOTE);
59 |
60 | return (
61 |
208 | )
209 | }
210 |
211 | export const CommentSection = ({
212 | className = '',
213 | formatDate,
214 | isMdxEditor,
215 | value,
216 | onChange = () => {
217 | },
218 | theme = 'light',
219 | currentUser,
220 | allowUpVote = false,
221 | onVoteChange = (change: boolean) => {
222 | }
223 | }: CommentProps) => {
224 | return (
225 | ;
229 | },
230 | }}
231 | >
232 |
233 | {
237 | onChange([{
238 | id: makeid(8),
239 | user: currentUser,
240 | createdAt: new Date(),
241 | replies: [],
242 | text: val,
243 | }, ...(value ?? [])])
244 | }}/>
245 | {value.map(e => (
246 | {
249 | if (value) {
250 | onChange(value.map(f => f.id === e.id ? {
251 | ...f,
252 | replies: [{
253 | id: makeid(8),
254 | parentId: e.id,
255 | user: currentUser,
256 | createdAt: new Date(),
257 | replies: [],
258 | text: rep,
259 | }, ...(f.replies ?? [])]
260 | } : f))
261 | }
262 | }}
263 | onChange={(change: any) => {
264 | if (value)
265 | onChange(value.map(f => f.id === e.id ? {
266 | ...f,
267 | ...change,
268 | } : f))
269 | }}
270 | onDelete={() => {
271 | onChange(value.filter(f => f.id !== e.id))
272 | }}
273 | comment={e}
274 | key={e.id}
275 | allowUpVote={allowUpVote}
276 | theme={theme}
277 | onVoteChange={onVoteChange}
278 | />
279 | ))}
280 |
281 |
282 | )
283 | }
--------------------------------------------------------------------------------
/src/mdx-style.css:
--------------------------------------------------------------------------------
1 | :root, .light, .light-theme {
2 | --blue-1: #fbfdff;
3 | --blue-2: #f4faff;
4 | --blue-3: #e6f4fe;
5 | --blue-4: #d5efff;
6 | --blue-5: #c2e5ff;
7 | --blue-6: #acd8fc;
8 | --blue-7: #8ec8f6;
9 | --blue-8: #5eb1ef;
10 | --blue-9: #0090ff;
11 | --blue-10: #0588f0;
12 | --blue-11: #0d74ce;
13 | --blue-12: #113264;
14 | }
15 |
16 | @supports (color: color(display-p3 1 1 1)) {
17 | @media (color-gamut: p3) {
18 | :root, .light, .light-theme {
19 | --blue-1: color(display-p3 0.986 0.992 0.999);
20 | --blue-2: color(display-p3 0.96 0.979 0.998);
21 | --blue-3: color(display-p3 0.912 0.956 0.991);
22 | --blue-4: color(display-p3 0.853 0.932 1);
23 | --blue-5: color(display-p3 0.788 0.894 0.998);
24 | --blue-6: color(display-p3 0.709 0.843 0.976);
25 | --blue-7: color(display-p3 0.606 0.777 0.947);
26 | --blue-8: color(display-p3 0.451 0.688 0.917);
27 | --blue-9: color(display-p3 0.247 0.556 0.969);
28 | --blue-10: color(display-p3 0.234 0.523 0.912);
29 | --blue-11: color(display-p3 0.15 0.44 0.84);
30 | --blue-12: color(display-p3 0.102 0.193 0.379);
31 | }
32 | }
33 | }
34 |
35 | .dark, .dark-theme {
36 | --blue-1: #0d1520;
37 | --blue-2: #111927;
38 | --blue-3: #0d2847;
39 | --blue-4: #003362;
40 | --blue-5: #004074;
41 | --blue-6: #104d87;
42 | --blue-7: #205d9e;
43 | --blue-8: #2870bd;
44 | --blue-9: #0090ff;
45 | --blue-10: #3b9eff;
46 | --blue-11: #70b8ff;
47 | --blue-12: #c2e6ff;
48 | }
49 |
50 | @supports (color: color(display-p3 1 1 1)) {
51 | @media (color-gamut: p3) {
52 | .dark, .dark-theme {
53 | --blue-1: color(display-p3 0.057 0.081 0.122);
54 | --blue-2: color(display-p3 0.072 0.098 0.147);
55 | --blue-3: color(display-p3 0.078 0.154 0.27);
56 | --blue-4: color(display-p3 0.033 0.197 0.37);
57 | --blue-5: color(display-p3 0.08 0.245 0.441);
58 | --blue-6: color(display-p3 0.14 0.298 0.511);
59 | --blue-7: color(display-p3 0.195 0.361 0.6);
60 | --blue-8: color(display-p3 0.239 0.434 0.72);
61 | --blue-9: color(display-p3 0.247 0.556 0.969);
62 | --blue-10: color(display-p3 0.344 0.612 0.973);
63 | --blue-11: color(display-p3 0.49 0.72 1);
64 | --blue-12: color(display-p3 0.788 0.898 0.99);
65 | }
66 | }
67 | }
68 |
69 | :root, .light, .light-theme {
70 | --slate-1: #fcfcfd;
71 | --slate-2: #f9f9fb;
72 | --slate-3: #f0f0f3;
73 | --slate-4: #e8e8ec;
74 | --slate-5: #e0e1e6;
75 | --slate-6: #d9d9e0;
76 | --slate-7: #cdced6;
77 | --slate-8: #b9bbc6;
78 | --slate-9: #8b8d98;
79 | --slate-10: #80838d;
80 | --slate-11: #60646c;
81 | --slate-12: #1c2024;
82 | --baseModalBg: white;
83 | }
84 |
85 | @supports (color: color(display-p3 1 1 1)) {
86 | @media (color-gamut: p3) {
87 | :root, .light, .light-theme {
88 | --slate-1: color(display-p3 0.988 0.988 0.992);
89 | --slate-2: color(display-p3 0.976 0.976 0.984);
90 | --slate-3: color(display-p3 0.94 0.941 0.953);
91 | --slate-4: color(display-p3 0.908 0.909 0.925);
92 | --slate-5: color(display-p3 0.88 0.881 0.901);
93 | --slate-6: color(display-p3 0.85 0.852 0.876);
94 | --slate-7: color(display-p3 0.805 0.808 0.838);
95 | --slate-8: color(display-p3 0.727 0.733 0.773);
96 | --slate-9: color(display-p3 0.547 0.553 0.592);
97 | --slate-10: color(display-p3 0.503 0.512 0.549);
98 | --slate-11: color(display-p3 0.379 0.392 0.421);
99 | --slate-12: color(display-p3 0.113 0.125 0.14);
100 | }
101 | }
102 | }
103 |
104 | .dark, .dark-theme {
105 | --slate-1: #111113;
106 | --slate-2: #18191b;
107 | --slate-3: #212225;
108 | --slate-4: #272a2d;
109 | --slate-5: #2e3135;
110 | --slate-6: #363a3f;
111 | --slate-7: #43484e;
112 | --slate-8: #5a6169;
113 | --slate-9: #696e77;
114 | --slate-10: #777b84;
115 | --slate-11: #b0b4ba;
116 | --slate-12: #edeef0;
117 | --baseModalBg: rgba(0,0,0,0.6);
118 | }
119 |
120 | @supports (color: color(display-p3 1 1 1)) {
121 | @media (color-gamut: p3) {
122 | .dark, .dark-theme {
123 | --slate-1: color(display-p3 0.067 0.067 0.074);
124 | --slate-2: color(display-p3 0.095 0.098 0.105);
125 | --slate-3: color(display-p3 0.13 0.135 0.145);
126 | --slate-4: color(display-p3 0.156 0.163 0.176);
127 | --slate-5: color(display-p3 0.183 0.191 0.206);
128 | --slate-6: color(display-p3 0.215 0.226 0.244);
129 | --slate-7: color(display-p3 0.265 0.28 0.302);
130 | --slate-8: color(display-p3 0.357 0.381 0.409);
131 | --slate-9: color(display-p3 0.415 0.431 0.463);
132 | --slate-10: color(display-p3 0.469 0.483 0.514);
133 | --slate-11: color(display-p3 0.692 0.704 0.728);
134 | --slate-12: color(display-p3 0.93 0.933 0.94);
135 | }
136 | }
137 | }
138 |
139 | :root, .light, .light-theme {
140 | --grass-1: #fbfefb;
141 | --grass-2: #f5fbf5;
142 | --grass-3: #e9f6e9;
143 | --grass-4: #daf1db;
144 | --grass-5: #c9e8ca;
145 | --grass-6: #b2ddb5;
146 | --grass-7: #94ce9a;
147 | --grass-8: #65ba74;
148 | --grass-9: #46a758;
149 | --grass-10: #3e9b4f;
150 | --grass-11: #2a7e3b;
151 | --grass-12: #203c25;
152 | }
153 |
154 | @supports (color: color(display-p3 1 1 1)) {
155 | @media (color-gamut: p3) {
156 | :root, .light, .light-theme {
157 | --grass-1: color(display-p3 0.986 0.996 0.985);
158 | --grass-2: color(display-p3 0.966 0.983 0.964);
159 | --grass-3: color(display-p3 0.923 0.965 0.917);
160 | --grass-4: color(display-p3 0.872 0.94 0.865);
161 | --grass-5: color(display-p3 0.811 0.908 0.802);
162 | --grass-6: color(display-p3 0.733 0.864 0.724);
163 | --grass-7: color(display-p3 0.628 0.803 0.622);
164 | --grass-8: color(display-p3 0.477 0.72 0.482);
165 | --grass-9: color(display-p3 0.38 0.647 0.378);
166 | --grass-10: color(display-p3 0.344 0.598 0.342);
167 | --grass-11: color(display-p3 0.263 0.488 0.261);
168 | --grass-12: color(display-p3 0.151 0.233 0.153);
169 | }
170 | }
171 | }
172 |
173 | :root, .light, .light-theme {
174 | --cyan-1: #fafdfe;
175 | --cyan-2: #f2fafb;
176 | --cyan-3: #def7f9;
177 | --cyan-4: #caf1f6;
178 | --cyan-5: #b5e9f0;
179 | --cyan-6: #9ddde7;
180 | --cyan-7: #7dcedc;
181 | --cyan-8: #3db9cf;
182 | --cyan-9: #00a2c7;
183 | --cyan-10: #0797b9;
184 | --cyan-11: #107d98;
185 | --cyan-12: #0d3c48;
186 | }
187 |
188 | @supports (color: color(display-p3 1 1 1)) {
189 | @media (color-gamut: p3) {
190 | :root, .light, .light-theme {
191 | --cyan-1: color(display-p3 0.982 0.992 0.996);
192 | --cyan-2: color(display-p3 0.955 0.981 0.984);
193 | --cyan-3: color(display-p3 0.888 0.965 0.975);
194 | --cyan-4: color(display-p3 0.821 0.941 0.959);
195 | --cyan-5: color(display-p3 0.751 0.907 0.935);
196 | --cyan-6: color(display-p3 0.671 0.862 0.9);
197 | --cyan-7: color(display-p3 0.564 0.8 0.854);
198 | --cyan-8: color(display-p3 0.388 0.715 0.798);
199 | --cyan-9: color(display-p3 0.282 0.627 0.765);
200 | --cyan-10: color(display-p3 0.264 0.583 0.71);
201 | --cyan-11: color(display-p3 0.08 0.48 0.63);
202 | --cyan-12: color(display-p3 0.108 0.232 0.277);
203 | }
204 | }
205 | }
206 |
207 | :root, .light, .light-theme {
208 | --amber-1: #fefdfb;
209 | --amber-2: #fefbe9;
210 | --amber-3: #fff7c2;
211 | --amber-4: #ffee9c;
212 | --amber-5: #fbe577;
213 | --amber-6: #f3d673;
214 | --amber-7: #e9c162;
215 | --amber-8: #e2a336;
216 | --amber-9: #ffc53d;
217 | --amber-10: #ffba18;
218 | --amber-11: #ab6400;
219 | --amber-12: #4f3422;
220 | }
221 |
222 | @supports (color: color(display-p3 1 1 1)) {
223 | @media (color-gamut: p3) {
224 | :root, .light, .light-theme {
225 | --amber-1: color(display-p3 0.995 0.992 0.985);
226 | --amber-2: color(display-p3 0.994 0.986 0.921);
227 | --amber-3: color(display-p3 0.994 0.969 0.782);
228 | --amber-4: color(display-p3 0.989 0.937 0.65);
229 | --amber-5: color(display-p3 0.97 0.902 0.527);
230 | --amber-6: color(display-p3 0.936 0.844 0.506);
231 | --amber-7: color(display-p3 0.89 0.762 0.443);
232 | --amber-8: color(display-p3 0.85 0.65 0.3);
233 | --amber-9: color(display-p3 1 0.77 0.26);
234 | --amber-10: color(display-p3 0.959 0.741 0.274);
235 | --amber-11: color(display-p3 0.64 0.4 0);
236 | --amber-12: color(display-p3 0.294 0.208 0.145);
237 | }
238 | }
239 | }
240 |
241 | :root, .light, .light-theme {
242 | --red-1: #fffcfc;
243 | --red-2: #fff7f7;
244 | --red-3: #feebec;
245 | --red-4: #ffdbdc;
246 | --red-5: #ffcdce;
247 | --red-6: #fdbdbe;
248 | --red-7: #f4a9aa;
249 | --red-8: #eb8e90;
250 | --red-9: #e5484d;
251 | --red-10: #dc3e42;
252 | --red-11: #ce2c31;
253 | --red-12: #641723;
254 | }
255 |
256 | @supports (color: color(display-p3 1 1 1)) {
257 | @media (color-gamut: p3) {
258 | :root, .light, .light-theme {
259 | --red-1: color(display-p3 0.998 0.989 0.988);
260 | --red-2: color(display-p3 0.995 0.971 0.971);
261 | --red-3: color(display-p3 0.985 0.925 0.925);
262 | --red-4: color(display-p3 0.999 0.866 0.866);
263 | --red-5: color(display-p3 0.984 0.812 0.811);
264 | --red-6: color(display-p3 0.955 0.751 0.749);
265 | --red-7: color(display-p3 0.915 0.675 0.672);
266 | --red-8: color(display-p3 0.872 0.575 0.572);
267 | --red-9: color(display-p3 0.83 0.329 0.324);
268 | --red-10: color(display-p3 0.798 0.294 0.285);
269 | --red-11: color(display-p3 0.744 0.234 0.222);
270 | --red-12: color(display-p3 0.36 0.115 0.143);
271 | }
272 | }
273 | }
274 |
275 | /** Code mirror */
276 |
277 | .mdxeditor .cm-editor {
278 | --sp-font-mono: var(--font-mono);
279 | --sp-font-body: var(--font-body);
280 | padding: var(--sp-space-4) 0;
281 | }
282 |
283 | .mdxeditor .sp-editor .cm-editor {
284 | padding-bottom: 0;
285 | }
286 |
287 | .mdxeditor .cm-scroller {
288 | padding: 0 !important;
289 | }
290 |
291 | .mdxeditor .cm-focused {
292 | outline: none;
293 | }
294 |
295 | .mdxeditor .sp-wrapper {
296 | overflow: hidden;
297 | }
298 |
299 | .mdxeditor .sp-layout {
300 | border: none;
301 | }
302 |
303 | .mdxeditor .sp-cm pre {
304 | white-space: break-spaces;
305 | word-break: break-word;
306 | overflow-wrap: anywhere;
307 | flex-shrink: 1;
308 | }
309 |
310 | /** Diff viewer */
311 |
312 | .mdxeditor .cm-mergeView .cm-scroller {
313 | font-family: var(--font-mono);
314 | line-height: 1.3rem;
315 | font-size: var(--text-xs);
316 | }
317 |
318 | /** Diff viewer */
319 |
320 | .mdxeditor .cm-sourceView .cm-scroller {
321 | font-family: var(--font-mono);
322 | line-height: 1.3rem;
323 | font-size: var(--text-xs);
324 | }
325 |
326 | .mdxeditor .cm-gutters {
327 | background: transparent;
328 | font-size: var(--text-xxs);
329 | }
330 |
331 | .mdxeditor .cm-activeLine {
332 | background: transparent;
333 | }
334 |
335 | .mdxeditor .cm-tooltip-autocomplete {
336 | background: var(--baseBgSubtle);
337 | }
338 |
339 | .mdxeditor hr.selected[data-lexical-decorator=true] {
340 | outline: 2px solid highlight;
341 | }
342 | ._editorRoot_uazmk_53 {
343 | --accentBase: var(--blue-1);
344 | --accentBgSubtle: var(--blue-2);
345 | --accentBg: var(--blue-3);
346 | --accentBgHover: var(--blue-4);
347 | --accentBgActive: var(--blue-5);
348 | --accentLine: var(--blue-6);
349 | --accentBorder: var(--blue-7);
350 | --accentBorderHover: var(--blue-8);
351 | --accentSolid: var(--blue-9);
352 | --accentSolidHover: var(--blue-10);
353 | --accentText: var(--blue-11);
354 | --accentTextContrast: var(--blue-12);
355 |
356 | --basePageBg: white;
357 | --baseBase: var(--slate-1);
358 | --baseBgSubtle: var(--slate-2);
359 | --baseBg: var(--slate-3);
360 | --baseBgHover: var(--slate-4);
361 | --baseBgActive: var(--slate-5);
362 | --baseLine: var(--slate-6);
363 | --baseBorder: var(--slate-7);
364 | --baseBorderHover: var(--slate-8);
365 | --baseSolid: var(--slate-9);
366 | --baseSolidHover: var(--slate-10);
367 | --baseText: var(--slate-11);
368 | --baseTextContrast: var(--slate-12);
369 |
370 | --admonitionTipBg: var(--cyan-4);
371 | --admonitionTipBorder: var(--cyan-8);
372 |
373 | --admonitionInfoBg: var(--grass-4);
374 | --admonitionInfoBorder: var(--grass-8);
375 |
376 | --admonitionCautionBg: var(--amber-4);
377 | --admonitionCautionBorder: var(--amber-8);
378 |
379 | --admonitionDangerBg: var(--red-4);
380 | --admonitionDangerBorder: var(--red-8);
381 |
382 | --admonitionNoteBg: var(--slate-4);
383 | --admonitionNoteBorder: var(--slate-8);
384 |
385 | --error-color: var(--red-10);
386 |
387 | --spacing-0: 0px;
388 | --spacing-px: 1px;
389 | --spacing-0_5: 0.125rem;
390 | --spacing-1: 0.25rem;
391 | --spacing-1_5: 0.375rem;
392 | --spacing-2: 0.5rem;
393 | --spacing-2_5: 0.625rem;
394 | --spacing-3: 0.75rem;
395 | --spacing-3_5: 0.875rem;
396 | --spacing-4: 1rem;
397 | --spacing-5: 1.25rem;
398 | --spacing-6: 1.5rem;
399 | --spacing-7: 1.75rem;
400 | --spacing-8: 2rem;
401 | --spacing-9: 2.25rem;
402 | --spacing-10: 2.5rem;
403 | --spacing-11: 2.75rem;
404 | --spacing-12: 3rem;
405 | --spacing-14: 3.5rem;
406 | --spacing-16: 4rem;
407 | --spacing-20: 5rem;
408 | --spacing-24: 6rem;
409 | --spacing-28: 7rem;
410 | --spacing-32: 8rem;
411 | --spacing-36: 9rem;
412 | --spacing-40: 10rem;
413 | --spacing-44: 11rem;
414 | --spacing-48: 12rem;
415 | --spacing-52: 13rem;
416 | --spacing-56: 14rem;
417 | --spacing-60: 15rem;
418 | --spacing-64: 16rem;
419 | --spacing-72: 18rem;
420 | --spacing-80: 20rem;
421 | --spacing-96: 24rem;
422 |
423 | --radius-none: 0px;
424 | --radius-small: var(--spacing-0_5);
425 | --radius-base: var(--spacing-1);
426 | --radius-medium: var(--spacing-1_5);
427 | --radius-large: var(--spacing-2);
428 | --radius-extra-large: var(--spacing-3);
429 | --radius-full: 9999px;
430 |
431 | --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
432 | --font-body: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
433 |
434 | --text-base: 1rem;
435 | --text-sm: 0.875rem;
436 | --text-xs: 0.75rem;
437 | --text-xxs: 0.6rem;
438 |
439 | font-family: var(--font-body);
440 | color: var(--baseText);
441 | }
442 |
443 | ._editorWrapper_uazmk_154 {}
444 |
445 | ._nestedListItem_uazmk_156 {
446 | list-style: none;
447 | }
448 |
449 | ._toolbarRoot_uazmk_160 {
450 | z-index: 2;
451 | display: flex;
452 | flex-direction: row;
453 | gap: var(--spacing-1);
454 | border-top-left-radius: var(--radius-medium);
455 | border-top-right-radius: var(--radius-medium);
456 | padding: var(--spacing-1_5);
457 | align-items: center;
458 | overflow-x: auto;
459 | position: sticky;
460 | top: 0;
461 | background-color: var(--baseBg);
462 | width: inherit;
463 | }
464 |
465 | ._toolbarRoot_uazmk_160 div[role=separator] {
466 | margin: var(--spacing-2) var(--spacing-1);
467 | border-left: 1px solid var(--baseBorder);
468 | border-right: 1px solid var(--baseBase);
469 | height: var(--spacing-4);
470 | }
471 |
472 | ._toolbarRoot_uazmk_160 svg {
473 | color: var(--baseTextContrast);
474 | display: block;
475 | }
476 |
477 | ._readOnlyToolbarRoot_uazmk_187 {
478 | pointer-events: none;
479 | background: var(--baseBase);
480 | }
481 |
482 | ._readOnlyToolbarRoot_uazmk_187>div {
483 | opacity: 0.5;
484 | }
485 |
486 | ._toolbarModeSwitch_uazmk_196 {
487 | opacity: 1 !important;
488 | margin-left: auto;
489 | align-self: stretch;
490 | align-items: stretch;
491 | display: flex;
492 | border: 1px solid var(--baseBg);
493 | border-radius: var(--radius-medium);
494 | font-size: var(--text-xs);
495 | }
496 |
497 | ._toolbarModeSwitch_uazmk_196 ._toolbarToggleItem_uazmk_206 {
498 | padding-inline-end: var(--spacing-4);
499 | padding-inline-start: var(--spacing-4);
500 | }
501 |
502 | ._toolbarModeSwitch_uazmk_196 ._toolbarToggleItem_uazmk_206:active,
503 | ._toolbarModeSwitch_uazmk_196 ._toolbarToggleItem_uazmk_206[data-state=on] {
504 | background-color: var(--baseBorder);
505 | }
506 |
507 | ._toolbarGroupOfGroups_uazmk_217 {
508 | display: flex;
509 | margin: 0 var(--spacing-1);
510 | }
511 |
512 | ._toolbarToggleSingleGroup_uazmk_222:first-of-type ._toolbarToggleItem_uazmk_206:only-child,
513 | ._toolbarToggleSingleGroup_uazmk_222:only-child ._toolbarToggleItem_uazmk_206:first-child,
514 | ._toolbarModeSwitch_uazmk_196 ._toolbarToggleItem_uazmk_206:first-child {
515 | border-top-left-radius: var(--radius-base);
516 | border-bottom-left-radius: var(--radius-base);
517 | }
518 |
519 | ._toolbarToggleSingleGroup_uazmk_222:last-of-type ._toolbarToggleItem_uazmk_206:only-child,
520 | ._toolbarToggleSingleGroup_uazmk_222:only-child ._toolbarToggleItem_uazmk_206:last-child,
521 | ._toolbarModeSwitch_uazmk_196 ._toolbarToggleItem_uazmk_206:last-child {
522 | border-top-right-radius: var(--radius-base);
523 | border-bottom-right-radius: var(--radius-base);
524 | }
525 |
526 | ._toolbarToggleItem_uazmk_206,
527 | ._toolbarButton_uazmk_237 {
528 | border: 0;
529 | background-color: transparent;
530 | font-size: inherit;
531 | -webkit-appearance: none;
532 | -moz-appearance: none;
533 | appearance: none;
534 | all: unset;
535 | box-sizing: border-box;
536 | cursor: default;
537 | padding: var(--spacing-0_5);
538 | }
539 |
540 | @media (hover: hover) {
541 | ._toolbarToggleItem_uazmk_206:hover, ._toolbarButton_uazmk_237:hover {
542 | background-color: var(--baseBgActive);
543 | }
544 | }
545 |
546 | ._toolbarToggleItem_uazmk_206:active svg, ._toolbarButton_uazmk_237:active svg {
547 | transform: translate(1px, 1px);
548 | }
549 |
550 | ._toolbarToggleItem_uazmk_206[data-state=on],
551 | ._toolbarButton_uazmk_237[data-state=on],
552 | ._toolbarToggleItem_uazmk_206:active,
553 | ._toolbarButton_uazmk_237:active {
554 | color: var(--baseTextContrast);
555 | background-color: var(--baseBgActive);
556 | }
557 |
558 | ._toolbarToggleItem_uazmk_206[data-disabled], ._toolbarButton_uazmk_237[data-disabled] {
559 | pointer-events: none;
560 | }
561 |
562 | ._toolbarToggleItem_uazmk_206[data-disabled] svg, ._toolbarButton_uazmk_237[data-disabled] svg {
563 | color: var(--baseBorderHover);
564 | }
565 |
566 | ._toolbarButton_uazmk_237 {
567 | border-radius: var(--radius-base);
568 | }
569 |
570 | ._toolbarButton_uazmk_237 + ._toolbarButton_uazmk_237 {
571 | margin-left: var(--spacing-1);
572 | }
573 |
574 | ._activeToolbarButton_uazmk_274 {
575 | color: var(--accentText);
576 | }
577 |
578 | ._toolbarToggleSingleGroup_uazmk_222 {
579 | display: flex;
580 | align-items: center;
581 | white-space: nowrap;
582 | }
583 |
584 | ._toolbarNodeKindSelectContainer_uazmk_284,
585 | ._toolbarButtonDropdownContainer_uazmk_285,
586 | ._toolbarCodeBlockLanguageSelectContent_uazmk_286,
587 | ._selectContainer_uazmk_287 {
588 | filter: drop-shadow(0 2px 2px rgb(0 0 0 / 0.20));
589 | z-index: 3;
590 | width: var(--spacing-36);
591 | border-bottom-left-radius: var(--radius-base);
592 | border-bottom-right-radius: var(--radius-base);
593 | background-color: var(--basePageBg);
594 | font-size: var(--text-sm);
595 | }
596 |
597 | ._toolbarButtonDropdownContainer_uazmk_285 {
598 | border-top-right-radius: var(--radius-base);
599 | }
600 |
601 | ._toolbarButtonDropdownContainer_uazmk_285 ._selectItem_uazmk_300:first-child {
602 | border-top-right-radius: var(--radius-base);
603 | }
604 |
605 | ._toolbarNodeKindSelectTrigger_uazmk_305,
606 | ._toolbarButtonSelectTrigger_uazmk_306,
607 | ._selectTrigger_uazmk_307 {
608 | border: 0;
609 | background-color: transparent;
610 | display: flex;
611 | color: inherit;
612 | align-items: center;
613 | width: var(--spacing-36);
614 | padding: var(--spacing-0_5) var(--spacing-1);
615 | padding-inline-start: var(--spacing-2);
616 | border-radius: var(--radius-medium);
617 | white-space: nowrap;
618 | flex-wrap: nowrap;
619 | font-size: var(--text-sm);
620 | background-color: var(--basePageBg);
621 | margin: 0 var(--spacing-1);
622 | }
623 |
624 | ._toolbarNodeKindSelectTrigger_uazmk_305[data-state=open], ._toolbarButtonSelectTrigger_uazmk_306[data-state=open], ._selectTrigger_uazmk_307[data-state=open] {
625 | filter: drop-shadow(0 2px 2px rgb(0 0 0 / 0.20));
626 | border-bottom-right-radius: var(--radius-none);
627 | border-bottom-left-radius: var(--radius-none);
628 | }
629 |
630 | ._selectTrigger_uazmk_307[data-placeholder]>span:first-child {
631 | color: var(--baseBorderHover);
632 | }
633 |
634 | /** used in the sandpack */
635 | ._toolbarButtonSelectTrigger_uazmk_306 {
636 | width: auto;
637 | padding-inline-start: var(--spacing-2);
638 | padding-inline-end: var(--spacing-1);
639 | padding-block: var(--spacing-0_5);
640 | }
641 |
642 | ._toolbarCodeBlockLanguageSelectTrigger_uazmk_342,
643 | ._toolbarCodeBlockLanguageSelectContent_uazmk_286 {
644 | width: var(--spacing-48);
645 | }
646 |
647 | ._toolbarNodeKindSelectItem_uazmk_347,
648 | ._selectItem_uazmk_300 {
649 | cursor: default;
650 | display: flex;
651 | padding: var(--spacing-2);
652 | }
653 |
654 | ._toolbarNodeKindSelectItem_uazmk_347[data-highlighted], ._selectItem_uazmk_300[data-highlighted] {
655 | background-color: var(--baseBg);
656 | }
657 |
658 | ._toolbarNodeKindSelectItem_uazmk_347[data-state=checked], ._selectItem_uazmk_300[data-state=checked] {
659 | color: var(--baseTextContrast);
660 | background-color: var(--baseBg);
661 | }
662 |
663 | ._toolbarNodeKindSelectItem_uazmk_347[data-highlighted], ._selectItem_uazmk_300[data-highlighted] {
664 | outline: none;
665 | }
666 |
667 | ._toolbarNodeKindSelectItem_uazmk_347:last-child, ._selectItem_uazmk_300:last-child {
668 | border-bottom-left-radius: var(--radius-base);
669 | border-bottom-right-radius: var(--radius-base);
670 | }
671 |
672 | ._toolbarNodeKindSelectDropdownArrow_uazmk_372,
673 | ._selectDropdownArrow_uazmk_373 {
674 | margin-left: auto;
675 | display: flex;
676 | align-items: center;
677 | }
678 |
679 | ._contentEditable_uazmk_379 {
680 | box-sizing: border-box;
681 | width: 100%;
682 | color: var(--baseTextContrast);
683 |
684 | padding: var(--spacing-3);
685 | }
686 |
687 | ._contentEditable_uazmk_379:focus {
688 | outline: none;
689 | }
690 |
691 | ._codeMirrorWrapper_uazmk_391 {
692 | margin-bottom: var(--spacing-5);
693 | border: 1px solid var(--baseLine);
694 | border-radius: var(--radius-medium);
695 | overflow: hidden;
696 | padding: 0.8rem;
697 | position: relative;
698 | }
699 |
700 | ._sandPackWrapper_uazmk_400 {
701 | margin-bottom: var(--spacing-5);
702 | border: 1px solid var(--baseLine);
703 | border-radius: var(--radius-medium);
704 | overflow: hidden;
705 | position: relative;
706 | }
707 |
708 | ._codeMirrorToolbar_uazmk_408 {
709 | position: absolute;
710 | right: 0;
711 | top: 0;
712 | display: flex;
713 | gap: var(--spacing-1);
714 | padding: var(--spacing-1);
715 | z-index: 1;
716 | background-color: var(--baseBase);
717 | border-bottom-left-radius: var(--radius-base);
718 | }
719 |
720 | ._frontmatterWrapper_uazmk_412 {
721 | border-radius: var(--radius-medium);
722 | padding: var(--spacing-3);
723 | background-color: var(--baseBgSubtle);
724 | }
725 |
726 | ._frontmatterWrapper_uazmk_412[data-expanded=true] {
727 | margin-bottom: var(--spacing-10);
728 | }
729 |
730 | ._frontmatterToggleButton_uazmk_422 {
731 | border: 0;
732 | background-color: transparent;
733 | font-size: inherit;
734 | -webkit-appearance: none;
735 | -moz-appearance: none;
736 | appearance: none;
737 | all: unset;
738 | box-sizing: border-box;
739 | cursor: default;
740 | display: flex;
741 | align-items: center;
742 | gap: var(--spacing-1);
743 | font-size: var(--text-sm);
744 | }
745 |
746 | ._propertyPanelTitle_uazmk_430 {
747 | font-size: var(--text-xs);
748 | font-weight: 400;
749 | margin: 0;
750 | padding-top: var(--spacing-2);
751 | padding-left: var(--spacing-2);
752 | }
753 |
754 | ._propertyEditorTable_uazmk_438 {
755 | table-layout: fixed;
756 | border-spacing: var(--spacing-2);
757 | }
758 |
759 | ._propertyEditorTable_uazmk_438 th {
760 | text-align: left;
761 | font-size: var(--text-sm);
762 | padding: var(--spacing-2) var(--spacing-3);
763 | }
764 |
765 | ._propertyEditorTable_uazmk_438 col:nth-child(1) {
766 | width: 30%;
767 | }
768 |
769 | ._propertyEditorTable_uazmk_438 col:nth-child(2) {
770 | width: 70%;
771 | }
772 |
773 | ._propertyEditorTable_uazmk_438 td:last-child ._iconButton_uazmk_456 {
774 | margin-left: var(--spacing-4);
775 | margin-right: var(--spacing-4);
776 | }
777 |
778 | ._propertyEditorTable_uazmk_438 ._readOnlyColumnCell_uazmk_461 {
779 | padding-left: 0;
780 | }
781 |
782 | ._propertyEditorLabelCell_uazmk_466 {
783 | font-weight: 400;
784 | }
785 |
786 | ._readOnlyColumnCell_uazmk_461 {
787 | padding-left: 0;
788 | }
789 |
790 | ._buttonsFooter_uazmk_474 {
791 | display: flex;
792 | justify-content: flex-end;
793 | gap: var(--spacing-2);
794 | }
795 |
796 | ._propertyEditorInput_uazmk_480 {
797 | border: 0;
798 | background-color: transparent;
799 | font-size: inherit;
800 | -webkit-appearance: none;
801 | -moz-appearance: none;
802 | appearance: none;
803 | all: unset;
804 | box-sizing: border-box;
805 | cursor: default;
806 | width: 100%;
807 | padding: var(--spacing-2) var(--spacing-3);
808 | border-radius: var(--radius-base);
809 | border: 1px solid var(--baseBorder);
810 | background-color: var(--baseBase);
811 | font-size: var(--text-sm);
812 | }
813 |
814 | ._iconButton_uazmk_456 {
815 | border: 0;
816 | background-color: transparent;
817 | font-size: inherit;
818 | -webkit-appearance: none;
819 | -moz-appearance: none;
820 | appearance: none;
821 | all: unset;
822 | box-sizing: border-box;
823 | cursor: default;
824 | color: var(--baseText);
825 | }
826 |
827 | @media (hover: hover) {
828 | ._iconButton_uazmk_456:hover {
829 | color: var(--baseTextContrast);
830 | }
831 | }
832 |
833 | ._iconButton_uazmk_456:disabled,
834 | ._iconButton_uazmk_456:disabled:hover {
835 | color: var(--baseLine);
836 | }
837 |
838 | ._primaryButton_uazmk_506,
839 | ._secondaryButton_uazmk_507 {
840 | border: 0;
841 | background-color: transparent;
842 | font-size: inherit;
843 | -webkit-appearance: none;
844 | -moz-appearance: none;
845 | appearance: none;
846 | all: unset;
847 | box-sizing: border-box;
848 | cursor: default;
849 | padding: var(--spacing-2) var(--spacing-3);
850 | border: 1px solid var(--accentBorder);
851 | background-color: var(--accentSolidHover);
852 | color: var(--baseBase);
853 | font-size: var(--text-xs);
854 | border-radius: var(--radius-medium);
855 | }
856 |
857 | ._primaryButton_uazmk_506:disabled, ._secondaryButton_uazmk_507:disabled {
858 | background: var(--accentLine);
859 | border-color: var(--accentBg);
860 | }
861 |
862 | ._smallButton_uazmk_522 {
863 | font-size: var(--text-xs);
864 | padding: var(--spacing-1) var(--spacing-2);
865 | border-radius: var(--radius-base);
866 | }
867 |
868 | ._secondaryButton_uazmk_507 {
869 | border: 1px solid var(--baseBorder);
870 | background-color: var(--baseSolidHover);
871 | color: var(--baseBase);
872 | }
873 |
874 | ._dialogForm_uazmk_534 {
875 | display: flex;
876 | flex-direction: row;
877 | gap: var(--spacing-2);
878 | }
879 |
880 | ._linkDialogEditForm_uazmk_540 {
881 | display: flex;
882 | flex-direction: column;
883 | align-items: stretch;
884 | gap: var(--spacing-2);
885 | padding: 0;
886 | }
887 |
888 | ._linkDialogInputContainer_uazmk_548 {
889 | display: flex;
890 | flex-direction: column;
891 | align-items: stretch;
892 | }
893 |
894 | ._linkDialogInputWrapper_uazmk_554 {
895 | display: flex;
896 | align-items: center;
897 | background-color: var(--baseBase);
898 |
899 | border-radius: var(--radius-base);
900 | border: 1px solid var(--baseBorder);
901 | }
902 |
903 | ._linkDialogInputWrapper_uazmk_554[data-visible-dropdown=true] {
904 | border-bottom-left-radius: var(--radius-none);
905 | border-bottom-right-radius: var(--radius-none);
906 | border-bottom-width: 0;
907 | }
908 |
909 | ._linkDialogInputWrapper_uazmk_554>button {
910 | border: 0;
911 | background-color: transparent;
912 | font-size: inherit;
913 | -webkit-appearance: none;
914 | -moz-appearance: none;
915 | appearance: none;
916 | all: unset;
917 | box-sizing: border-box;
918 | cursor: default;
919 | padding-right: var(--spacing-2);
920 | }
921 |
922 | ._linkDialogInput_uazmk_548,
923 | ._dialogInput_uazmk_575 {
924 | border: 0;
925 | background-color: transparent;
926 | font-size: inherit;
927 | -webkit-appearance: none;
928 | -moz-appearance: none;
929 | appearance: none;
930 | all: unset;
931 | box-sizing: border-box;
932 | cursor: default;
933 | width: 20rem;
934 | padding: var(--spacing-2) var(--spacing-3);
935 | font-size: var(--text-sm);
936 | }
937 |
938 | ._linkDialogInput_uazmk_548::-moz-placeholder, ._dialogInput_uazmk_575::-moz-placeholder {
939 | color: var(--baseBorder);
940 | }
941 |
942 | ._linkDialogInput_uazmk_548::placeholder, ._dialogInput_uazmk_575::placeholder {
943 | color: var(--baseBorder);
944 | }
945 |
946 | ._linkDialogAnchor_uazmk_586 {
947 | position: fixed;
948 | background-color: highlight;
949 | z-index: -1;
950 | }
951 |
952 | ._linkDialogAnchor_uazmk_586[data-visible=true] {
953 | visibility: visible;
954 | }
955 |
956 | ._linkDialogAnchor_uazmk_586[data-visible=false] {
957 | visibility: hidden;
958 | }
959 |
960 | ._linkDialogPopoverContent_uazmk_600,
961 | ._tableColumnEditorPopoverContent_uazmk_601,
962 | ._dialogContent_uazmk_602 {
963 | filter: drop-shadow(0 2px 2px rgb(0 0 0 / 0.20));
964 | display: flex;
965 | align-items: center;
966 | gap: var(--spacing-0_5);
967 | border-radius: var(--radius-medium);
968 | border: 1px solid var(--baseBg);
969 | background-color: var(--baseModalBg);
970 | padding: var(--spacing-1) var(--spacing-1);
971 | font-size: var(--text-sm);
972 | }
973 |
974 | ._largeDialogContent_uazmk_614 {
975 | filter: drop-shadow(0 2px 2px rgb(0 0 0 / 0.20));
976 | gap: var(--spacing-0_5);
977 | border-radius: var(--radius-medium);
978 | border: 1px solid var(--baseBorder);
979 | background-color: var(--baseBgSubtle);
980 | padding: var(--spacing-4);
981 | font-size: var(--text-sm);
982 | }
983 |
984 | ._dialogTitle_uazmk_624 {
985 | font-size: var(--text-base);
986 | font-weight: 600;
987 | padding-left: var(--spacing-2);
988 | }
989 |
990 | ._dialogCloseButton_uazmk_630 {
991 | border: 0;
992 | background-color: transparent;
993 | font-size: inherit;
994 | -webkit-appearance: none;
995 | -moz-appearance: none;
996 | appearance: none;
997 | all: unset;
998 | box-sizing: border-box;
999 | cursor: default;
1000 | position: absolute;
1001 | top: 10px;
1002 | right: 10px;
1003 | }
1004 |
1005 | ._popoverContent_uazmk_637 {
1006 | filter: drop-shadow(0 2px 2px rgb(0 0 0 / 0.20));
1007 | display: flex;
1008 | align-items: center;
1009 | gap: var(--spacing-0_5);
1010 | border-radius: var(--radius-medium);
1011 | background-color: var(--baseBgSubtle);
1012 | padding: var(--spacing-2) var(--spacing-2);
1013 | font-size: var(--text-sm);
1014 | z-index: 1;
1015 | }
1016 |
1017 | ._popoverArrow_uazmk_649 {
1018 | fill: var(--basePageBg);
1019 | }
1020 |
1021 | ._linkDialogPreviewAnchor_uazmk_653 {
1022 | margin-right: var(--spacing-1);
1023 | display: flex;
1024 | align-items: center;
1025 | color: var(--accentText);
1026 | text-decoration: none;
1027 |
1028 | border: 1px solid transparent;
1029 | }
1030 |
1031 | @media (hover: hover) {
1032 | ._linkDialogPreviewAnchor_uazmk_653:hover {
1033 | color: var(--accentSolidHover);
1034 | }
1035 | }
1036 |
1037 | ._linkDialogPreviewAnchor_uazmk_653 span {
1038 | max-width: 14rem;
1039 | overflow-x: hidden;
1040 | text-overflow: ellipsis;
1041 | white-space: nowrap;
1042 | }
1043 |
1044 | ._tooltipTrigger_uazmk_676 {
1045 | align-self: center;
1046 | }
1047 |
1048 | ._tooltipContent_uazmk_680 {
1049 | z-index: 2;
1050 | position: relative;
1051 | border-radius: var(--radius-medium);
1052 | padding: var(--spacing-1) var(--spacing-2);
1053 | font-size: var(--text-xs);
1054 | background-color: var(--baseText);
1055 | color: var(--baseBase);
1056 | }
1057 |
1058 | ._tooltipContent_uazmk_680 svg {
1059 | fill: var(--baseText);
1060 | }
1061 |
1062 | ._actionButton_uazmk_694 {
1063 | border: 0;
1064 | background-color: transparent;
1065 | font-size: inherit;
1066 | -webkit-appearance: none;
1067 | -moz-appearance: none;
1068 | appearance: none;
1069 | all: unset;
1070 | box-sizing: border-box;
1071 | cursor: default;
1072 | padding: var(--spacing-1);
1073 | color: var(--baseTextContrast);
1074 | padding: var(--spacing-1) var(--spacing-1);
1075 | border-radius: var(--radius-medium);
1076 | color: var(--baseTextContrast);
1077 | }
1078 |
1079 | ._actionButton_uazmk_694 svg {
1080 | display: block;
1081 | }
1082 |
1083 | @media (hover: hover) {
1084 | ._actionButton_uazmk_694:hover {
1085 | background-color: var(--baseBg);
1086 | }
1087 | }
1088 |
1089 | ._actionButton_uazmk_694:active svg {
1090 | transform: translate(1px, 1px);
1091 | }
1092 |
1093 | ._actionButton_uazmk_694[data-state=on],
1094 | ._actionButton_uazmk_694:active {
1095 | background-color: var(--baseBg);
1096 | color: var(--baseTextContrast);
1097 | }
1098 |
1099 | ._primaryActionButton_uazmk_701 {
1100 | background-color: var(--accentSolid);
1101 | color: var(--baseBase);
1102 | }
1103 |
1104 | @media (hover: hover) {
1105 | ._primaryActionButton_uazmk_701:hover {
1106 | background-color: var(--accentSolidHover);
1107 | color: var(--baseBase);
1108 | }
1109 | }
1110 |
1111 | ._tableEditor_uazmk_713 {
1112 | table-layout: fixed;
1113 | width: 100%;
1114 | height: 100%;
1115 | border-spacing: 0;
1116 | border-collapse: collapse;
1117 | }
1118 |
1119 | ._tableEditor_uazmk_713 thead>tr>th {
1120 | text-align: right;
1121 | }
1122 |
1123 | ._tableEditor_uazmk_713>tbody>tr>td:not(._toolCell_uazmk_724),
1124 | ._tableEditor_uazmk_713>tbody>tr>th:not(._toolCell_uazmk_724):not([data-tool-cell="true"]) {
1125 | border: 1px solid var(--baseBgActive);
1126 | padding: var(--spacing-1) var(--spacing-2);
1127 | white-space: normal;
1128 | }
1129 |
1130 | :is(._tableEditor_uazmk_713>tbody>tr>td:not(._toolCell_uazmk_724),._tableEditor_uazmk_713>tbody>tr>th:not(._toolCell_uazmk_724):not([data-tool-cell="true"]))>div {
1131 | outline: none;
1132 | }
1133 |
1134 | :is(._tableEditor_uazmk_713>tbody>tr>td:not(._toolCell_uazmk_724),._tableEditor_uazmk_713>tbody>tr>th:not(._toolCell_uazmk_724):not([data-tool-cell="true"]))>div>p {
1135 | margin: 0;
1136 | }
1137 |
1138 | [data-active=true]:is(._tableEditor_uazmk_713>tbody>tr>td:not(._toolCell_uazmk_724),._tableEditor_uazmk_713>tbody>tr>th:not(._toolCell_uazmk_724):not([data-tool-cell="true"])) {
1139 | outline: solid 1px var(--baseSolid);
1140 | }
1141 |
1142 | ._tableEditor_uazmk_713 ._tableColumnEditorTrigger_uazmk_743,
1143 | ._tableEditor_uazmk_713 ._tableRowEditorTrigger_uazmk_744,
1144 | ._tableEditor_uazmk_713 ._addRowButton_uazmk_745,
1145 | ._tableEditor_uazmk_713 ._addColumnButton_uazmk_746,
1146 | ._tableEditor_uazmk_713 ._iconButton_uazmk_456 {
1147 | opacity: .15;
1148 | }
1149 |
1150 | @media (hover: hover) {
1151 |
1152 | ._tableEditor_uazmk_713:hover ._tableColumnEditorTrigger_uazmk_743,
1153 | ._tableEditor_uazmk_713:hover ._tableRowEditorTrigger_uazmk_744,
1154 | ._tableEditor_uazmk_713:hover ._addRowButton_uazmk_745,
1155 | ._tableEditor_uazmk_713:hover ._addColumnButton_uazmk_746,
1156 | ._tableEditor_uazmk_713:hover ._iconButton_uazmk_456 {
1157 | opacity: 0.3;
1158 | }
1159 |
1160 | ._tableEditor_uazmk_713:hover ._tableColumnEditorTrigger_uazmk_743:hover, ._tableEditor_uazmk_713:hover ._tableRowEditorTrigger_uazmk_744:hover, ._tableEditor_uazmk_713:hover ._addRowButton_uazmk_745:hover, ._tableEditor_uazmk_713:hover ._addColumnButton_uazmk_746:hover, ._tableEditor_uazmk_713:hover ._iconButton_uazmk_456:hover {
1161 | opacity: 1;
1162 | }
1163 | }
1164 |
1165 | ._toolCell_uazmk_724 {
1166 | text-align: right;
1167 | }
1168 |
1169 | ._toolCell_uazmk_724 button {
1170 | margin: auto;
1171 | display: block;
1172 | }
1173 |
1174 | ._tableColumnEditorTrigger_uazmk_743 {
1175 | border: 0;
1176 | background-color: transparent;
1177 | font-size: inherit;
1178 | -webkit-appearance: none;
1179 | -moz-appearance: none;
1180 | appearance: none;
1181 | all: unset;
1182 | box-sizing: border-box;
1183 | cursor: default;
1184 | padding: var(--spacing-1);
1185 | color: var(--baseTextContrast);
1186 | padding: var(--spacing-1);
1187 | border-radius: var(--radius-full);
1188 | opacity: 0.2;
1189 | }
1190 |
1191 | ._tableColumnEditorTrigger_uazmk_743 svg {
1192 | display: block;
1193 | }
1194 |
1195 | @media (hover: hover) {
1196 | ._tableColumnEditorTrigger_uazmk_743:hover {
1197 | background-color: var(--baseBg);
1198 | }
1199 | }
1200 |
1201 | ._tableColumnEditorTrigger_uazmk_743:active svg {
1202 | transform: translate(1px, 1px);
1203 | }
1204 |
1205 | ._tableColumnEditorTrigger_uazmk_743[data-state=on],
1206 | ._tableColumnEditorTrigger_uazmk_743:active {
1207 | background-color: var(--baseBg);
1208 | color: var(--baseTextContrast);
1209 | }
1210 |
1211 | ._tableColumnEditorTrigger_uazmk_743[data-active=true] {
1212 | opacity: 1 !important;
1213 | }
1214 |
1215 | ._tableColumnEditorToolbar_uazmk_789 {
1216 | display: flex;
1217 | }
1218 |
1219 | ._tableColumnEditorToolbar_uazmk_789>button {
1220 | border: 0;
1221 | background-color: transparent;
1222 | font-size: inherit;
1223 | -webkit-appearance: none;
1224 | -moz-appearance: none;
1225 | appearance: none;
1226 | all: unset;
1227 | box-sizing: border-box;
1228 | cursor: default;
1229 | padding: var(--spacing-1);
1230 | color: var(--baseTextContrast);
1231 | }
1232 |
1233 | ._tableColumnEditorToolbar_uazmk_789>button svg {
1234 | display: block;
1235 | }
1236 |
1237 | @media (hover: hover) {
1238 | ._tableColumnEditorToolbar_uazmk_789>button:hover {
1239 | background-color: var(--baseBg);
1240 | }
1241 | }
1242 |
1243 | ._tableColumnEditorToolbar_uazmk_789>button:active svg {
1244 | transform: translate(1px, 1px);
1245 | }
1246 |
1247 | ._tableColumnEditorToolbar_uazmk_789>button[data-state=on],
1248 | ._tableColumnEditorToolbar_uazmk_789>button:active {
1249 | background-color: var(--baseBg);
1250 | color: var(--baseTextContrast);
1251 | }
1252 |
1253 | ._tableColumnEditorToolbar_uazmk_789 [role=separator] {
1254 | margin-left: var(--spacing-1);
1255 | margin-right: var(--spacing-1);
1256 | }
1257 |
1258 |
1259 | ._toggleGroupRoot_uazmk_803 {
1260 | display: inline-flex;
1261 | }
1262 |
1263 |
1264 | ._toggleGroupRoot_uazmk_803 button {
1265 | border: 0;
1266 | background-color: transparent;
1267 | font-size: inherit;
1268 | -webkit-appearance: none;
1269 | -moz-appearance: none;
1270 | appearance: none;
1271 | all: unset;
1272 | box-sizing: border-box;
1273 | cursor: default;
1274 | padding: var(--spacing-1);
1275 | color: var(--baseTextContrast);
1276 | }
1277 |
1278 |
1279 | ._toggleGroupRoot_uazmk_803 button svg {
1280 | display: block;
1281 | }
1282 |
1283 |
1284 | @media (hover: hover) {
1285 | ._toggleGroupRoot_uazmk_803 button:hover {
1286 | background-color: var(--baseBg);
1287 | }
1288 | }
1289 |
1290 |
1291 | ._toggleGroupRoot_uazmk_803 button:active svg {
1292 | transform: translate(1px, 1px);
1293 | }
1294 |
1295 |
1296 | ._toggleGroupRoot_uazmk_803 button[data-state=on],
1297 | ._toggleGroupRoot_uazmk_803 button:active {
1298 | background-color: var(--baseBg);
1299 | color: var(--baseTextContrast);
1300 | }
1301 |
1302 |
1303 | ._toggleGroupRoot_uazmk_803 button:first-child {
1304 | border-top-left-radius: var(--radius-base);
1305 | border-bottom-left-radius: var(--radius-base);
1306 | }
1307 |
1308 |
1309 | ._toggleGroupRoot_uazmk_803 button:last-child {
1310 | border-top-right-radius: var(--radius-base);
1311 | border-bottom-right-radius: var(--radius-base);
1312 | }
1313 |
1314 | ._tableToolsColumn_uazmk_821 {
1315 | width: 2rem;
1316 | }
1317 |
1318 | ._tableToolsColumn_uazmk_821 button {
1319 | margin: auto;
1320 | display: block;
1321 | }
1322 |
1323 | ._leftAlignedCell_uazmk_830 {
1324 | text-align: left;
1325 | }
1326 |
1327 | ._rightAlignedCell_uazmk_834 {
1328 | text-align: right;
1329 | }
1330 |
1331 | ._centeredCell_uazmk_838 {
1332 | text-align: center;
1333 | }
1334 |
1335 | ._addColumnButton_uazmk_746,
1336 | ._addRowButton_uazmk_745 {
1337 | border: 0;
1338 | background-color: transparent;
1339 | font-size: inherit;
1340 | -webkit-appearance: none;
1341 | -moz-appearance: none;
1342 | appearance: none;
1343 | all: unset;
1344 | box-sizing: border-box;
1345 | cursor: default;
1346 | padding: var(--spacing-1);
1347 | color: var(--baseTextContrast);
1348 | background-color: var(--baseBase);
1349 |
1350 | display: flex;
1351 | align-items: center;
1352 | }
1353 |
1354 | ._addColumnButton_uazmk_746 svg, ._addRowButton_uazmk_745 svg {
1355 | display: block;
1356 | }
1357 |
1358 | @media (hover: hover) {
1359 | ._addColumnButton_uazmk_746:hover, ._addRowButton_uazmk_745:hover {
1360 | background-color: var(--baseBg);
1361 | }
1362 | }
1363 |
1364 | ._addColumnButton_uazmk_746:active svg, ._addRowButton_uazmk_745:active svg {
1365 | transform: translate(1px, 1px);
1366 | }
1367 |
1368 | ._addColumnButton_uazmk_746[data-state=on],
1369 | ._addRowButton_uazmk_745[data-state=on],
1370 | ._addColumnButton_uazmk_746:active,
1371 | ._addRowButton_uazmk_745:active {
1372 | background-color: var(--baseBg);
1373 | color: var(--baseTextContrast);
1374 | }
1375 |
1376 | ._addColumnButton_uazmk_746 svg, ._addRowButton_uazmk_745 svg {
1377 | margin: auto;
1378 | }
1379 |
1380 | ._addRowButton_uazmk_745 {
1381 | width: 100%;
1382 | margin-top: var(--spacing-px);
1383 | box-sizing: border-box;
1384 | border-bottom-right-radius: var(--radius-medium);
1385 | border-bottom-left-radius: var(--radius-medium);
1386 | }
1387 |
1388 | ._addColumnButton_uazmk_746 {
1389 | margin-left: var(--spacing-px);
1390 | height: 100%;
1391 | border-top-right-radius: var(--radius-medium);
1392 | border-bottom-right-radius: var(--radius-medium);
1393 | }
1394 |
1395 | /** Dialog */
1396 | ._dialogOverlay_uazmk_871 {
1397 | position: fixed;
1398 | inset: 0;
1399 | animation: _overlayShow_uazmk_1 150ms cubic-bezier(0.16, 1, 0.3, 1);
1400 | background-color: var(--baseBase);
1401 | z-index: 51;
1402 | opacity: 0.5;
1403 | }
1404 |
1405 | ._dialogContent_uazmk_602,
1406 | ._largeDialogContent_uazmk_614 {
1407 | position: fixed;
1408 | top: 50%;
1409 | left: 50%;
1410 | transform: translate(-50%, -50%);
1411 | animation: _contentShow_uazmk_1 150ms cubic-bezier(0.16, 1, 0.3, 1);
1412 | z-index: 52;
1413 | }
1414 |
1415 | ._dialogContent_uazmk_602:focus,
1416 | ._largeDialogContent_uazmk_614:focus {
1417 | outline: none;
1418 | }
1419 |
1420 |
1421 | @keyframes _overlayShow_uazmk_1 {
1422 | from {
1423 | opacity: 0;
1424 | }
1425 |
1426 | to {
1427 | opacity: .5;
1428 | }
1429 | }
1430 |
1431 | @keyframes _contentShow_uazmk_1 {
1432 | from {
1433 | opacity: 0;
1434 | transform: translate(-50%, -48%) scale(0.96);
1435 | }
1436 |
1437 | to {
1438 | opacity: 1;
1439 | transform: translate(-50%, -50%) scale(1);
1440 | }
1441 | }
1442 |
1443 | ._focusedImage_uazmk_918 {
1444 | outline: highlight solid 2px;
1445 | }
1446 |
1447 | ._imageWrapper_uazmk_922 {
1448 | display: inline-block;
1449 | position: relative;
1450 | }
1451 |
1452 | ._imageWrapper_uazmk_922[draggable=true] {
1453 | cursor: move;
1454 | /* fallback if grab cursor is unsupported */
1455 | cursor: grab;
1456 | cursor: -webkit-grab;
1457 | }
1458 |
1459 | ._editImageToolbar_uazmk_935 {
1460 | position: absolute;
1461 | right: 0;
1462 | top: 0;
1463 | display: flex;
1464 | gap: var(--spacing-1);
1465 | padding: var(--spacing-1);
1466 | z-index: 1;
1467 | background-color: var(--baseBase);
1468 | border-bottom-left-radius: var(--radius-base);
1469 | }
1470 |
1471 | ._editImageButton_uazmk_939 svg {
1472 | display: block;
1473 | }
1474 |
1475 | ._inlineEditor_uazmk_945 {
1476 | display: inline-flex;
1477 | border-radius: var(--radius-medium);
1478 | padding: var(--spacing-1);
1479 | gap: var(--spacing-2);
1480 | align-items: center;
1481 | background: var(--baseBg);
1482 | }
1483 |
1484 | ._blockEditor_uazmk_954 {
1485 | display: flex;
1486 | justify-content: stretch;
1487 | border-radius: var(--radius-medium);
1488 | padding: var(--spacing-2);
1489 | gap: var(--spacing-2);
1490 | align-items: center;
1491 | background: var(--baseBg);
1492 | }
1493 |
1494 | ._blockEditor_uazmk_954 ._nestedEditor_uazmk_963 {
1495 | flex-grow: 1;
1496 | }
1497 |
1498 | ._nestedEditor_uazmk_963 {
1499 | background: var(--basePageBg);
1500 | padding: var(--spacing-1) var(--spacing-2);
1501 | border-radius: var(--radius-medium);
1502 | }
1503 |
1504 | ._nestedEditor_uazmk_963>p {
1505 | margin: 0;
1506 | }
1507 |
1508 | ._nestedEditor_uazmk_963:focus {
1509 | outline: none;
1510 | }
1511 |
1512 | ._genericComponentName_uazmk_982 {
1513 | font-size: var(--text-sm);
1514 | color: var(--baseText);
1515 | padding-right: var(--spacing-2);
1516 | }
1517 |
1518 | ._diffSourceToggle_uazmk_988 {
1519 | border-radius: var(--radius-medium);
1520 | display: flex;
1521 | }
1522 |
1523 | ._diffSourceToggle_uazmk_988 ._toolbarToggleItem_uazmk_206 {
1524 | padding: 0;
1525 | }
1526 |
1527 | ._diffSourceToggle_uazmk_988 ._toolbarToggleItem_uazmk_206>span {
1528 | display: block;
1529 | padding: var(--spacing-1) var(--spacing-1);
1530 | }
1531 |
1532 | ._selectWithLabel_uazmk_1002 {
1533 | display: flex;
1534 | align-items: center;
1535 | gap: var(--spacing-2);
1536 | margin-left: var(--spacing-2);
1537 | }
1538 |
1539 | ._selectWithLabel_uazmk_1002>label {
1540 | font-size: var(--text-sm);
1541 | }
1542 |
1543 | ._selectWithLabel_uazmk_1002 ._selectTrigger_uazmk_307 {
1544 | border: 1px solid var(--baseBorder);
1545 | }
1546 |
1547 | ._toolbarTitleMode_uazmk_1017 {
1548 | font-size: var(--text-sm);
1549 | margin-left: var(--spacing-2);
1550 | }
1551 |
1552 |
1553 | ._imageControlWrapperResizing_uazmk_1023 {
1554 | touch-action: none;
1555 | }
1556 |
1557 | ._imageResizer_uazmk_1027 {
1558 | display: block;
1559 | width: 7px;
1560 | height: 7px;
1561 | position: absolute;
1562 | background-color: var(--accentText);
1563 | border: 1px solid var(--baseBg);
1564 | }
1565 |
1566 | ._imageResizer_uazmk_1027._imageResizerN_uazmk_1036 {
1567 | top: -6px;
1568 | left: 48%;
1569 | cursor: n-resize;
1570 | }
1571 |
1572 | ._imageResizer_uazmk_1027._imageResizerNe_uazmk_1042 {
1573 | top: -6px;
1574 | right: -6px;
1575 | cursor: ne-resize;
1576 | }
1577 |
1578 | ._imageResizer_uazmk_1027._imageResizerE_uazmk_1048 {
1579 | bottom: 48%;
1580 | right: -6px;
1581 | cursor: e-resize;
1582 | }
1583 |
1584 | ._imageResizer_uazmk_1027._imageResizerSe_uazmk_1054 {
1585 | bottom: -2px;
1586 | right: -6px;
1587 | cursor: nwse-resize;
1588 | }
1589 |
1590 | ._imageResizer_uazmk_1027._imageResizerS_uazmk_1054 {
1591 | bottom: -2px;
1592 | left: 48%;
1593 | cursor: s-resize;
1594 | }
1595 |
1596 | ._imageResizer_uazmk_1027._imageResizerSw_uazmk_1066 {
1597 | bottom: -2px;
1598 | left: -6px;
1599 | cursor: sw-resize;
1600 | }
1601 |
1602 | ._imageResizer_uazmk_1027._imageResizerW_uazmk_1072 {
1603 | bottom: 48%;
1604 | left: -6px;
1605 | cursor: w-resize;
1606 | }
1607 |
1608 | ._imageResizer_uazmk_1027._imageResizerNw_uazmk_1078 {
1609 | top: -6px;
1610 | left: -6px;
1611 | cursor: nw-resize;
1612 | }
1613 |
1614 | ._placeholder_uazmk_1084 {
1615 | color: var(--baseSolid);
1616 | overflow: hidden;
1617 | position: absolute;
1618 | top: 0;
1619 | padding: var(--spacing-3);
1620 | text-overflow: ellipsis;
1621 | -webkit-user-select: none;
1622 | -moz-user-select: none;
1623 | user-select: none;
1624 | white-space: nowrap;
1625 | display: inline-block;
1626 | pointer-events: none;
1627 | }
1628 |
1629 | ._rootContentEditableWrapper_uazmk_1097 {
1630 | position: relative;
1631 | }
1632 |
1633 |
1634 |
1635 | ._downshiftContainer_uazmk_1103 {
1636 | display: flex;
1637 | flex-direction: column;
1638 | align-items: stretch;
1639 | }
1640 |
1641 | ._downshiftInputWrapper_uazmk_1109 {
1642 | display: flex;
1643 | align-items: center;
1644 | background-color: var(--baseBase);
1645 |
1646 | border-radius: var(--radius-base);
1647 | border: 1px solid var(--baseBorder);
1648 | }
1649 |
1650 | ._downshiftInputWrapper_uazmk_1109[data-visible-dropdown=true] {
1651 | border-bottom-left-radius: var(--radius-none);
1652 | border-bottom-right-radius: var(--radius-none);
1653 | border-bottom-width: 0;
1654 | }
1655 |
1656 | ._downshiftInputWrapper_uazmk_1109>button {
1657 | border: 0;
1658 | background-color: transparent;
1659 | font-size: inherit;
1660 | -webkit-appearance: none;
1661 | -moz-appearance: none;
1662 | appearance: none;
1663 | all: unset;
1664 | box-sizing: border-box;
1665 | cursor: default;
1666 | padding-right: var(--spacing-2);
1667 | }
1668 |
1669 | ._downshiftInput_uazmk_1109 {
1670 | border: 0;
1671 | background-color: transparent;
1672 | font-size: inherit;
1673 | -webkit-appearance: none;
1674 | -moz-appearance: none;
1675 | appearance: none;
1676 | all: unset;
1677 | box-sizing: border-box;
1678 | cursor: default;
1679 | width: 20rem;
1680 | padding: var(--spacing-2) var(--spacing-3);
1681 | font-size: var(--text-sm);
1682 | }
1683 |
1684 | ._downshiftInput_uazmk_1109::-moz-placeholder {
1685 | color: var(--baseBorder);
1686 | }
1687 |
1688 | ._downshiftInput_uazmk_1109::placeholder {
1689 | color: var(--baseBorder);
1690 | }
1691 |
1692 | ._downshiftAutocompleteContainer_uazmk_1140 {
1693 | position: relative;
1694 | }
1695 |
1696 | ._downshiftAutocompleteContainer_uazmk_1140 ul {
1697 | all: unset;
1698 | box-sizing: border-box;
1699 | position: absolute;
1700 | font-size: var(--text-sm);
1701 | width: 100%;
1702 | display: none;
1703 | border-bottom-left-radius: var(--radius-medium);
1704 | border-bottom-right-radius: var(--radius-medium);
1705 | max-height: var(--spacing-48);
1706 | overflow-x: hidden;
1707 | overflow-y: auto;
1708 | border: 1px solid var(--baseBorder);
1709 | border-top-width: 0;
1710 | background-color: var(--baseBase);
1711 | }
1712 |
1713 | ._downshiftAutocompleteContainer_uazmk_1140 ul[data-visible=true] {
1714 | display: block;
1715 | }
1716 |
1717 | ._downshiftAutocompleteContainer_uazmk_1140 ul li {
1718 | padding: var(--spacing-2) var(--spacing-3);
1719 | white-space: nowrap;
1720 | margin-bottom: var(--spacing-1);
1721 | overflow-x: hidden;
1722 | text-overflow: ellipsis;
1723 | }
1724 |
1725 | ._downshiftAutocompleteContainer_uazmk_1140 ul li[data-selected=true] {
1726 | background-color: var(--baseBgSubtle);
1727 | }
1728 |
1729 | ._downshiftAutocompleteContainer_uazmk_1140 ul li[data-highlighted=true] {
1730 | background-color: var(--baseBgHover);
1731 | }
1732 |
1733 | ._downshiftAutocompleteContainer_uazmk_1140 ul li:last-of-type {
1734 | border-bottom-left-radius: var(--radius-medium);
1735 | border-bottom-right-radius: var(--radius-medium);
1736 | }
1737 |
1738 | ._textInput_uazmk_1186 {
1739 | all: unset;
1740 | border-radius: var(--radius-base);
1741 | border: 1px solid var(--baseBorder);
1742 | background-color: var(--baseBase);
1743 | padding: var(--spacing-2) var(--spacing-3);
1744 | }
1745 |
1746 | form._multiFieldForm_uazmk_1194 {
1747 | display: flex;
1748 | flex-direction: column;
1749 | padding: var(--spacing-2);
1750 | gap: var(--spacing-2);
1751 | }
1752 |
1753 | form._multiFieldForm_uazmk_1194 ._formField_uazmk_1200 {
1754 | display: flex;
1755 | flex-direction: column;
1756 | gap: var(--spacing-2);
1757 | }
1758 |
1759 | form._multiFieldForm_uazmk_1194 ._formField_uazmk_1200 label {
1760 | font-size: var(--text-xs);
1761 | }
1762 |
1763 | ._markdownParseError_uazmk_1211 {
1764 | border-radius: var(--radius-base);
1765 | border: 1px solid var(--error-color);
1766 | padding: var(--spacing-2);
1767 | margin-block: var(--spacing-2);
1768 | color: var(--error-color);
1769 | font-size: var(--text-xs);
1770 | }
1771 |
1772 | ._popupContainer_uazmk_1220 {
1773 | position: relative;
1774 | z-index: 2;
1775 | }
1776 |
1777 | ._inputSizer_uazmk_1225 {
1778 | display: inline-grid;
1779 | vertical-align: baseline;
1780 | align-items: center;
1781 | position: relative;
1782 | }
1783 |
1784 | ._inputSizer_uazmk_1225::after,
1785 | ._inputSizer_uazmk_1225 input {
1786 | width: auto;
1787 | min-width: 1rem;
1788 | grid-area: 1 / 2;
1789 | font: inherit;
1790 | margin: 0;
1791 | padding: 0 2px;
1792 | resize: none;
1793 | background: none;
1794 | -webkit-appearance: none;
1795 | -moz-appearance: none;
1796 | appearance: none;
1797 | border: none;
1798 | color: inherit;
1799 | }
1800 |
1801 | ._inputSizer_uazmk_1225 span {
1802 | padding: 0.25em;
1803 | }
1804 |
1805 | ._inputSizer_uazmk_1225::after {
1806 | content: attr(data-value);
1807 | white-space: pre-wrap;
1808 | }
1809 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1810 | --blue-1: #fbfdff;
1811 | --blue-2: #f4faff;
1812 | --blue-3: #e6f4fe;
1813 | --blue-4: #d5efff;
1814 | --blue-5: #c2e5ff;
1815 | --blue-6: #acd8fc;
1816 | --blue-7: #8ec8f6;
1817 | --blue-8: #5eb1ef;
1818 | --blue-9: #0090ff;
1819 | --blue-10: #0588f0;
1820 | --blue-11: #0d74ce;
1821 | --blue-12: #113264;
1822 | }
1823 |
1824 | @supports (color: color(display-p3 1 1 1)) {
1825 | @media (color-gamut: p3) {
1826 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1827 | --blue-1: color(display-p3 0.986 0.992 0.999);
1828 | --blue-2: color(display-p3 0.96 0.979 0.998);
1829 | --blue-3: color(display-p3 0.912 0.956 0.991);
1830 | --blue-4: color(display-p3 0.853 0.932 1);
1831 | --blue-5: color(display-p3 0.788 0.894 0.998);
1832 | --blue-6: color(display-p3 0.709 0.843 0.976);
1833 | --blue-7: color(display-p3 0.606 0.777 0.947);
1834 | --blue-8: color(display-p3 0.451 0.688 0.917);
1835 | --blue-9: color(display-p3 0.247 0.556 0.969);
1836 | --blue-10: color(display-p3 0.234 0.523 0.912);
1837 | --blue-11: color(display-p3 0.15 0.44 0.84);
1838 | --blue-12: color(display-p3 0.102 0.193 0.379);
1839 | }
1840 | }
1841 | }
1842 |
1843 | ._dark_1tncs_1, ._dark-theme_1tncs_1 {
1844 | --blue-1: #0d1520;
1845 | --blue-2: #111927;
1846 | --blue-3: #0d2847;
1847 | --blue-4: #003362;
1848 | --blue-5: #004074;
1849 | --blue-6: #104d87;
1850 | --blue-7: #205d9e;
1851 | --blue-8: #2870bd;
1852 | --blue-9: #0090ff;
1853 | --blue-10: #3b9eff;
1854 | --blue-11: #70b8ff;
1855 | --blue-12: #c2e6ff;
1856 | }
1857 |
1858 | @supports (color: color(display-p3 1 1 1)) {
1859 | @media (color-gamut: p3) {
1860 | ._dark_1tncs_1, ._dark-theme_1tncs_1 {
1861 | --blue-1: color(display-p3 0.057 0.081 0.122);
1862 | --blue-2: color(display-p3 0.072 0.098 0.147);
1863 | --blue-3: color(display-p3 0.078 0.154 0.27);
1864 | --blue-4: color(display-p3 0.033 0.197 0.37);
1865 | --blue-5: color(display-p3 0.08 0.245 0.441);
1866 | --blue-6: color(display-p3 0.14 0.298 0.511);
1867 | --blue-7: color(display-p3 0.195 0.361 0.6);
1868 | --blue-8: color(display-p3 0.239 0.434 0.72);
1869 | --blue-9: color(display-p3 0.247 0.556 0.969);
1870 | --blue-10: color(display-p3 0.344 0.612 0.973);
1871 | --blue-11: color(display-p3 0.49 0.72 1);
1872 | --blue-12: color(display-p3 0.788 0.898 0.99);
1873 | }
1874 | }
1875 | }
1876 |
1877 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1878 | --slate-1: #fcfcfd;
1879 | --slate-2: #f9f9fb;
1880 | --slate-3: #f0f0f3;
1881 | --slate-4: #e8e8ec;
1882 | --slate-5: #e0e1e6;
1883 | --slate-6: #d9d9e0;
1884 | --slate-7: #cdced6;
1885 | --slate-8: #b9bbc6;
1886 | --slate-9: #8b8d98;
1887 | --slate-10: #80838d;
1888 | --slate-11: #60646c;
1889 | --slate-12: #1c2024;
1890 | }
1891 |
1892 | @supports (color: color(display-p3 1 1 1)) {
1893 | @media (color-gamut: p3) {
1894 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1895 | --slate-1: color(display-p3 0.988 0.988 0.992);
1896 | --slate-2: color(display-p3 0.976 0.976 0.984);
1897 | --slate-3: color(display-p3 0.94 0.941 0.953);
1898 | --slate-4: color(display-p3 0.908 0.909 0.925);
1899 | --slate-5: color(display-p3 0.88 0.881 0.901);
1900 | --slate-6: color(display-p3 0.85 0.852 0.876);
1901 | --slate-7: color(display-p3 0.805 0.808 0.838);
1902 | --slate-8: color(display-p3 0.727 0.733 0.773);
1903 | --slate-9: color(display-p3 0.547 0.553 0.592);
1904 | --slate-10: color(display-p3 0.503 0.512 0.549);
1905 | --slate-11: color(display-p3 0.379 0.392 0.421);
1906 | --slate-12: color(display-p3 0.113 0.125 0.14);
1907 | }
1908 | }
1909 | }
1910 |
1911 | ._dark_1tncs_1, ._dark-theme_1tncs_1 {
1912 | --slate-1: #111113;
1913 | --slate-2: #18191b;
1914 | --slate-3: #212225;
1915 | --slate-4: #272a2d;
1916 | --slate-5: #2e3135;
1917 | --slate-6: #363a3f;
1918 | --slate-7: #43484e;
1919 | --slate-8: #5a6169;
1920 | --slate-9: #696e77;
1921 | --slate-10: #777b84;
1922 | --slate-11: #b0b4ba;
1923 | --slate-12: #edeef0;
1924 | }
1925 |
1926 | @supports (color: color(display-p3 1 1 1)) {
1927 | @media (color-gamut: p3) {
1928 | ._dark_1tncs_1, ._dark-theme_1tncs_1 {
1929 | --slate-1: color(display-p3 0.067 0.067 0.074);
1930 | --slate-2: color(display-p3 0.095 0.098 0.105);
1931 | --slate-3: color(display-p3 0.13 0.135 0.145);
1932 | --slate-4: color(display-p3 0.156 0.163 0.176);
1933 | --slate-5: color(display-p3 0.183 0.191 0.206);
1934 | --slate-6: color(display-p3 0.215 0.226 0.244);
1935 | --slate-7: color(display-p3 0.265 0.28 0.302);
1936 | --slate-8: color(display-p3 0.357 0.381 0.409);
1937 | --slate-9: color(display-p3 0.415 0.431 0.463);
1938 | --slate-10: color(display-p3 0.469 0.483 0.514);
1939 | --slate-11: color(display-p3 0.692 0.704 0.728);
1940 | --slate-12: color(display-p3 0.93 0.933 0.94);
1941 | }
1942 | }
1943 | }
1944 |
1945 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1946 | --grass-1: #fbfefb;
1947 | --grass-2: #f5fbf5;
1948 | --grass-3: #e9f6e9;
1949 | --grass-4: #daf1db;
1950 | --grass-5: #c9e8ca;
1951 | --grass-6: #b2ddb5;
1952 | --grass-7: #94ce9a;
1953 | --grass-8: #65ba74;
1954 | --grass-9: #46a758;
1955 | --grass-10: #3e9b4f;
1956 | --grass-11: #2a7e3b;
1957 | --grass-12: #203c25;
1958 | }
1959 |
1960 | @supports (color: color(display-p3 1 1 1)) {
1961 | @media (color-gamut: p3) {
1962 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1963 | --grass-1: color(display-p3 0.986 0.996 0.985);
1964 | --grass-2: color(display-p3 0.966 0.983 0.964);
1965 | --grass-3: color(display-p3 0.923 0.965 0.917);
1966 | --grass-4: color(display-p3 0.872 0.94 0.865);
1967 | --grass-5: color(display-p3 0.811 0.908 0.802);
1968 | --grass-6: color(display-p3 0.733 0.864 0.724);
1969 | --grass-7: color(display-p3 0.628 0.803 0.622);
1970 | --grass-8: color(display-p3 0.477 0.72 0.482);
1971 | --grass-9: color(display-p3 0.38 0.647 0.378);
1972 | --grass-10: color(display-p3 0.344 0.598 0.342);
1973 | --grass-11: color(display-p3 0.263 0.488 0.261);
1974 | --grass-12: color(display-p3 0.151 0.233 0.153);
1975 | }
1976 | }
1977 | }
1978 |
1979 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1980 | --cyan-1: #fafdfe;
1981 | --cyan-2: #f2fafb;
1982 | --cyan-3: #def7f9;
1983 | --cyan-4: #caf1f6;
1984 | --cyan-5: #b5e9f0;
1985 | --cyan-6: #9ddde7;
1986 | --cyan-7: #7dcedc;
1987 | --cyan-8: #3db9cf;
1988 | --cyan-9: #00a2c7;
1989 | --cyan-10: #0797b9;
1990 | --cyan-11: #107d98;
1991 | --cyan-12: #0d3c48;
1992 | }
1993 |
1994 | @supports (color: color(display-p3 1 1 1)) {
1995 | @media (color-gamut: p3) {
1996 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
1997 | --cyan-1: color(display-p3 0.982 0.992 0.996);
1998 | --cyan-2: color(display-p3 0.955 0.981 0.984);
1999 | --cyan-3: color(display-p3 0.888 0.965 0.975);
2000 | --cyan-4: color(display-p3 0.821 0.941 0.959);
2001 | --cyan-5: color(display-p3 0.751 0.907 0.935);
2002 | --cyan-6: color(display-p3 0.671 0.862 0.9);
2003 | --cyan-7: color(display-p3 0.564 0.8 0.854);
2004 | --cyan-8: color(display-p3 0.388 0.715 0.798);
2005 | --cyan-9: color(display-p3 0.282 0.627 0.765);
2006 | --cyan-10: color(display-p3 0.264 0.583 0.71);
2007 | --cyan-11: color(display-p3 0.08 0.48 0.63);
2008 | --cyan-12: color(display-p3 0.108 0.232 0.277);
2009 | }
2010 | }
2011 | }
2012 |
2013 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
2014 | --amber-1: #fefdfb;
2015 | --amber-2: #fefbe9;
2016 | --amber-3: #fff7c2;
2017 | --amber-4: #ffee9c;
2018 | --amber-5: #fbe577;
2019 | --amber-6: #f3d673;
2020 | --amber-7: #e9c162;
2021 | --amber-8: #e2a336;
2022 | --amber-9: #ffc53d;
2023 | --amber-10: #ffba18;
2024 | --amber-11: #ab6400;
2025 | --amber-12: #4f3422;
2026 | }
2027 |
2028 | @supports (color: color(display-p3 1 1 1)) {
2029 | @media (color-gamut: p3) {
2030 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
2031 | --amber-1: color(display-p3 0.995 0.992 0.985);
2032 | --amber-2: color(display-p3 0.994 0.986 0.921);
2033 | --amber-3: color(display-p3 0.994 0.969 0.782);
2034 | --amber-4: color(display-p3 0.989 0.937 0.65);
2035 | --amber-5: color(display-p3 0.97 0.902 0.527);
2036 | --amber-6: color(display-p3 0.936 0.844 0.506);
2037 | --amber-7: color(display-p3 0.89 0.762 0.443);
2038 | --amber-8: color(display-p3 0.85 0.65 0.3);
2039 | --amber-9: color(display-p3 1 0.77 0.26);
2040 | --amber-10: color(display-p3 0.959 0.741 0.274);
2041 | --amber-11: color(display-p3 0.64 0.4 0);
2042 | --amber-12: color(display-p3 0.294 0.208 0.145);
2043 | }
2044 | }
2045 | }
2046 |
2047 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
2048 | --red-1: #fffcfc;
2049 | --red-2: #fff7f7;
2050 | --red-3: #feebec;
2051 | --red-4: #ffdbdc;
2052 | --red-5: #ffcdce;
2053 | --red-6: #fdbdbe;
2054 | --red-7: #f4a9aa;
2055 | --red-8: #eb8e90;
2056 | --red-9: #e5484d;
2057 | --red-10: #dc3e42;
2058 | --red-11: #ce2c31;
2059 | --red-12: #641723;
2060 | }
2061 |
2062 | @supports (color: color(display-p3 1 1 1)) {
2063 | @media (color-gamut: p3) {
2064 | :root, ._light_1tncs_1, ._light-theme_1tncs_1 {
2065 | --red-1: color(display-p3 0.998 0.989 0.988);
2066 | --red-2: color(display-p3 0.995 0.971 0.971);
2067 | --red-3: color(display-p3 0.985 0.925 0.925);
2068 | --red-4: color(display-p3 0.999 0.866 0.866);
2069 | --red-5: color(display-p3 0.984 0.812 0.811);
2070 | --red-6: color(display-p3 0.955 0.751 0.749);
2071 | --red-7: color(display-p3 0.915 0.675 0.672);
2072 | --red-8: color(display-p3 0.872 0.575 0.572);
2073 | --red-9: color(display-p3 0.83 0.329 0.324);
2074 | --red-10: color(display-p3 0.798 0.294 0.285);
2075 | --red-11: color(display-p3 0.744 0.234 0.222);
2076 | --red-12: color(display-p3 0.36 0.115 0.143);
2077 | }
2078 | }
2079 | }
2080 |
2081 | ._bold_1tncs_10 {
2082 | font-weight: bold;
2083 | }
2084 |
2085 | ._italic_1tncs_14 {
2086 | font-style: italic;
2087 | }
2088 |
2089 | ._underline_1tncs_18 {
2090 | text-decoration: underline;
2091 | }
2092 |
2093 | ._bold_1tncs_10 {
2094 | font-weight: 700;
2095 | }
2096 |
2097 | ._italic_1tncs_14 {
2098 | font-style: italic;
2099 | }
2100 |
2101 | ._underline_1tncs_18 {
2102 | text-decoration: underline
2103 | }
2104 |
2105 | ._strikethrough_1tncs_34 {
2106 | text-decoration: line-through
2107 | }
2108 |
2109 | ._underlineStrikethrough_1tncs_38 {
2110 | text-decoration: underline line-through
2111 | }
2112 |
2113 | ._subscript_1tncs_42 {
2114 | font-size: .8em;
2115 | vertical-align: sub !important
2116 | }
2117 |
2118 | ._superscript_1tncs_47 {
2119 | font-size: .8em;
2120 | vertical-align: super
2121 | }
2122 |
2123 | ._code_1tncs_52 {
2124 | background-color: var(--baseBg);
2125 | padding: 1px .25rem;
2126 | font-family: var(--font-mono);
2127 | font-size: 94%
2128 | }
2129 |
2130 | ._nestedListItem_1tncs_59 {
2131 | list-style: none;
2132 | list-style-type: none;
2133 | }
2134 |
2135 | ._nestedListItem_1tncs_59:before,
2136 | ._nestedListItem_1tncs_59:after {
2137 | display: none;
2138 | }
2139 |
2140 | ._listitem_1tncs_69 {
2141 | margin: var(--spacing-2) 0;
2142 | }
2143 |
2144 | ._listItemChecked_1tncs_73,
2145 | ._listItemUnchecked_1tncs_74 {
2146 | position: relative;
2147 | margin-left: 0;
2148 | margin-right: 0;
2149 | margin-inline-start: -1rem;
2150 | padding-left: var(--spacing-6);
2151 | padding-right: var(--spacing-6);
2152 | list-style-type: none;
2153 | outline: none;
2154 | }
2155 |
2156 | ._listItemChecked_1tncs_73 {
2157 | text-decoration: line-through;
2158 | }
2159 |
2160 | ._listItemUnchecked_1tncs_74:before,
2161 | ._listItemChecked_1tncs_73:before {
2162 | content: '';
2163 | width: var(--spacing-4);
2164 | height: var(--spacing-4);
2165 | top: 0;
2166 | left: 0;
2167 | cursor: pointer;
2168 | display: block;
2169 | background-size: cover;
2170 | position: absolute;
2171 | }
2172 |
2173 | ._listItemUnchecked_1tncs_74[dir='rtl']:before,
2174 | ._listItemChecked_1tncs_73[dir='rtl']:before {
2175 | left: auto;
2176 | right: 0;
2177 | }
2178 |
2179 | ._listItemUnchecked_1tncs_74:focus:before,
2180 | ._listItemChecked_1tncs_73:focus:before {
2181 | box-shadow: 0 0 0 2px var(--accentBgActive);
2182 | border-radius: var(--radius-small);
2183 | }
2184 |
2185 | ._listItemUnchecked_1tncs_74:before {
2186 | border: 1px solid var(--baseBorder);
2187 | border-radius: var(--radius-small);
2188 | }
2189 |
2190 | ._listItemChecked_1tncs_73:before {
2191 | border: 1px solid var(--accentBorder);
2192 | border-radius: var(--radius-small);
2193 | background-color: var(--accentSolid);
2194 | background-repeat: no-repeat;
2195 | }
2196 |
2197 | ._listItemChecked_1tncs_73:after {
2198 | content: '';
2199 | cursor: pointer;
2200 | border-color: var(--baseBase);
2201 | border-style: solid;
2202 | position: absolute;
2203 | display: block;
2204 | top: var(--spacing-0_5);
2205 | width: var(--spacing-1);
2206 | left: var(--spacing-1_5);
2207 | right: var(--spacing-1_5);
2208 | height: var(--spacing-2);
2209 | transform: rotate(45deg);
2210 | border-width: 0 var(--spacing-0_5) var(--spacing-0_5) 0;
2211 | }
2212 |
2213 | ._nestedListItem_1tncs_59 {
2214 | list-style-type: none;
2215 | }
2216 |
2217 | ._nestedListItem_1tncs_59:before,
2218 | ._nestedListItem_1tncs_59:after {
2219 | display: none;
2220 | }
2221 |
2222 | ._admonitionDanger_1tncs_151,
2223 | ._admonitionInfo_1tncs_152,
2224 | ._admonitionNote_1tncs_153,
2225 | ._admonitionTip_1tncs_154,
2226 | ._admonitionCaution_1tncs_155 {
2227 | padding: var(--spacing-2);
2228 | margin-top: var(--spacing-2);
2229 | margin-bottom: var(--spacing-2);
2230 | border-left: 3px solid var(--admonitionBorder);
2231 | background-color: var(--admonitionBg);
2232 | }
2233 |
2234 | ._admonitionInfo_1tncs_152 {
2235 | --admonitionBorder: var(--admonitionInfoBorder);
2236 | --admonitionBg: var(--admonitionInfoBg);
2237 | }
2238 |
2239 | ._admonitionTip_1tncs_154 {
2240 | --admonitionBorder: var(--admonitionTipBorder);
2241 | --admonitionBg: var(--admonitionTipBg);
2242 | }
2243 |
2244 | ._admonitionCaution_1tncs_155 {
2245 | --admonitionBorder: var(--admonitionCautionBorder);
2246 | --admonitionBg: var(--admonitionCautionBg);
2247 | }
2248 |
2249 | ._admonitionDanger_1tncs_151 {
2250 | --admonitionBorder: var(--admonitionDangerBorder);
2251 | --admonitionBg: var(--admonitionDangerBg);
2252 | }
2253 |
2254 | ._admonitionNote_1tncs_153 {
2255 | --admonitionBorder: var(--admonitionNoteBorder);
2256 | --admonitionBg: var(--admonitionNoteBg);
2257 | }
2258 |
2259 | ._mdxExpression_1tncs_188 {
2260 | font-family: var(--font-mono);
2261 | font-size: 84%;
2262 | color: var(--accentText);
2263 | }
2264 |
2265 | ._mdxExpression_1tncs_188 input:focus-visible {
2266 | outline: none;
2267 | }
2268 |
2269 | .editor-content-container {
2270 | max-width: calc(100vw - 1.5rem);
2271 | }
2272 |
2273 | .editor-content p {
2274 | white-space: normal;
2275 | }
2276 |
2277 | .editor-content button {
2278 | color: var(--baseTextContrast);
2279 | }
--------------------------------------------------------------------------------