feat(ui): redesign UI with Tailwind CSS, CodeMirror 6, and new layout
- Replace all hand-written CSS with Tailwind utility classes - Upgrade CodeMirror 5 to CodeMirror 6 (scoped @codemirror/* packages) - Redesign layout with responsive sidebar navigation using JSX/Mithril - Flatten admin routes (e.g. /admin/presets -> /presets) - Add "remember me" login option with 2-week persistent cookie - Add delete confirmation dialogs across admin pages - Upgrade esbuild from 0.21 to 0.27 and update browser targets - Add Inter and Roboto Mono variable fonts with subset script
This commit is contained in:
1 parent
a7256620e0
commit
4a191afdec
64 files changed
+4147
-2421
No files matched your search
+22
-16
@@ -6,21 +6,25 @@ const component: ClosureComponent = (): Component => {
|
||||
view: (vnode) => {
|
||||
const text = vnode.attrs["text"];
|
||||
const element = vnode.attrs["element"] || "span";
|
||||
const className = vnode.attrs["class"] || "";
|
||||
|
||||
function overflowed(_vnode): void {
|
||||
_vnode.dom.classList.add("long-text-overflowed");
|
||||
_vnode.dom.classList.add("cursor-pointer", "hover:underline");
|
||||
_vnode.dom.setAttribute("title", text);
|
||||
_vnode.dom.onclick = (e) => {
|
||||
overlay.open(() => {
|
||||
return m("textarea.long-text", {
|
||||
value: text,
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
readonly: "",
|
||||
oncreate: (vnode2) => {
|
||||
(vnode2.dom as HTMLTextAreaElement).focus();
|
||||
(vnode2.dom as HTMLTextAreaElement).select();
|
||||
return m(
|
||||
"textarea.font-mono text-sm focus:ring-cyan-500 focus:border-cyan-500 border border-stone-300 rounded-md",
|
||||
{
|
||||
value: text,
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
readonly: "",
|
||||
oncreate: (vnode2) => {
|
||||
(vnode2.dom as HTMLTextAreaElement).focus();
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
});
|
||||
// prevent index page selection
|
||||
e.stopPropagation();
|
||||
@@ -32,21 +36,23 @@ const component: ClosureComponent = (): Component => {
|
||||
element,
|
||||
{
|
||||
oncreate: (vnode2) => {
|
||||
if (vnode2.dom.clientWidth !== vnode2.dom.scrollWidth)
|
||||
overflowed(vnode2);
|
||||
const w = Math.round(vnode2.dom.getBoundingClientRect().width);
|
||||
if (w !== vnode2.dom.scrollWidth) overflowed(vnode2);
|
||||
},
|
||||
onupdate: (vnode2) => {
|
||||
if (vnode2.dom.clientWidth === vnode2.dom.scrollWidth) {
|
||||
const w = Math.round(vnode2.dom.getBoundingClientRect().width);
|
||||
if (w === vnode2.dom.scrollWidth) {
|
||||
(vnode2.dom as HTMLElement).classList.remove(
|
||||
"long-text-overflowed",
|
||||
"cursor-pointer",
|
||||
"hover:underline",
|
||||
);
|
||||
(vnode2.dom as HTMLElement).onclick = null;
|
||||
(vnode2.dom as HTMLElement).removeAttribute("title");
|
||||
} else {
|
||||
overflowed(vnode2);
|
||||
}
|
||||
},
|
||||
class: "long-text",
|
||||
title: text,
|
||||
class: "block truncate decoration-dotted max-w-full " + className,
|
||||
},
|
||||
text,
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user