(feat): add profile page
(feat): show user online-status (feat): make markdown input more modular
This commit is contained in:
parent
168694ae86
commit
55da8026a7
12 changed files with 609 additions and 63 deletions
|
|
@ -23,6 +23,7 @@ import {
|
|||
indentWithTab,
|
||||
} from "@codemirror/commands";
|
||||
import { useEffect, useRef } from "react";
|
||||
import type { CSSProperties } from "react";
|
||||
|
||||
import { collectInlineRanges, ensureMarkdownStyles } from "./markdown";
|
||||
|
||||
|
|
@ -33,8 +34,36 @@ export type InputProps = {
|
|||
setValue: (value: string) => void;
|
||||
onSubmit?: () => void;
|
||||
invertEnterBehavior?: boolean;
|
||||
styled?: boolean;
|
||||
fontSize?: CSSProperties["fontSize"];
|
||||
paddingX?: CSSProperties["padding"];
|
||||
paddingY?: CSSProperties["padding"];
|
||||
className?: string;
|
||||
};
|
||||
|
||||
type InputStyle = CSSProperties & {
|
||||
"--tm-md-content-padding"?: string;
|
||||
};
|
||||
|
||||
function toCssLength(value: CSSProperties["padding"]): string | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return typeof value === "number" ? `${value}px` : value;
|
||||
}
|
||||
|
||||
function toCssPadding(
|
||||
vertical: CSSProperties["padding"],
|
||||
horizontal: CSSProperties["padding"],
|
||||
styled: boolean,
|
||||
): string {
|
||||
const defaultVertical = styled ? "0.25rem" : "0";
|
||||
const defaultHorizontal = styled ? "0.625rem" : "0";
|
||||
|
||||
return `${toCssLength(vertical) ?? defaultVertical} ${toCssLength(horizontal) ?? defaultHorizontal}`;
|
||||
}
|
||||
|
||||
type TokenRange = {
|
||||
from: number;
|
||||
to: number;
|
||||
|
|
@ -80,6 +109,10 @@ const markdownDecorations = ViewPlugin.fromClass(
|
|||
export default function Input(props: InputProps) {
|
||||
ensureMarkdownStyles();
|
||||
|
||||
const shellClassName = props.styled
|
||||
? "min-h-8 w-full min-w-0 rounded-lg border border-input bg-transparent text-base transition-colors outline-none placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40"
|
||||
: "";
|
||||
|
||||
const elementRef = useRef<HTMLDivElement | null>(null);
|
||||
const viewRef = useRef<EditorView | undefined>(undefined);
|
||||
const ignoreSyncRef = useRef(false);
|
||||
|
|
@ -143,7 +176,22 @@ export default function Input(props: InputProps) {
|
|||
});
|
||||
}, [props.value]);
|
||||
|
||||
return <div ref={elementRef} className="tm-md-root w-full" />;
|
||||
return (
|
||||
<div
|
||||
ref={elementRef}
|
||||
className={`tm-md-root ${shellClassName} ${props.className ?? ""}`}
|
||||
style={
|
||||
{
|
||||
fontSize: props.fontSize ?? "1rem",
|
||||
"--tm-md-content-padding": toCssPadding(
|
||||
props.paddingY,
|
||||
props.paddingX,
|
||||
Boolean(props.styled),
|
||||
),
|
||||
} as InputStyle
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -204,7 +252,7 @@ function createEditorExtensions(
|
|||
}),
|
||||
EditorView.theme({
|
||||
"&": {
|
||||
fontSize: "1rem",
|
||||
fontSize: "inherit",
|
||||
},
|
||||
"&.cm-editor": {
|
||||
width: "100%",
|
||||
|
|
|
|||
|
|
@ -665,12 +665,12 @@ export const markdownStyles = `
|
|||
.tm-md-table th { background: hsl(var(--muted)); font-weight: 600; }
|
||||
.tm-md-hr { margin: 0.55rem 0; }
|
||||
|
||||
.cm-editor.tm-md-editor { border-radius: 0.65rem; background: hsl(var(--card)); caret-color: var(--foreground); }
|
||||
.cm-editor.tm-md-editor { border-radius: inherit; background: transparent; caret-color: var(--foreground); }
|
||||
.cm-editor.tm-md-editor.cm-focused { outline: none; box-shadow: none; }
|
||||
.cm-editor.tm-md-editor .cm-scroller { font-family: inherit; line-height: 1.55; max-height: 30vh; overflow-y: auto; overflow-x: hidden; }
|
||||
.cm-editor.tm-md-editor .cm-content { caret-color: var(--foreground); }
|
||||
.cm-editor.tm-md-editor .cm-content { padding: 0.7rem 0.85rem; min-height: 2.75rem; }
|
||||
.cm-editor.tm-md-editor .cm-line { padding: 0 1px; color: hsl(var(--foreground)); }
|
||||
.cm-editor.tm-md-editor .cm-content { padding: var(--tm-md-content-padding, 0.25rem 0.625rem); min-height: 2rem; }
|
||||
.cm-editor.tm-md-editor .cm-line { padding: 0; color: hsl(var(--foreground)); }
|
||||
.cm-editor.tm-md-editor .tm-md-hidden-token { color: transparent; opacity: 0; font-size: inherit; }
|
||||
.cm-editor.tm-md-editor .tm-md-code-line { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; background: hsl(var(--muted)); border-radius: 0.3rem; }
|
||||
`;
|
||||
|
|
|
|||
Loading…
Reference in a new issue