Fix comrpessing bug on null buffers, make pinned floaters resizable and optimize a few things here and there
This commit is contained in:
parent
b19d2d1b41
commit
26aa0847d9
|
|
@ -2,7 +2,9 @@ import { Database } from "bun:sqlite";
|
||||||
import { BunSQLiteDatabase, drizzle } from "drizzle-orm/bun-sqlite";
|
import { BunSQLiteDatabase, drizzle } from "drizzle-orm/bun-sqlite";
|
||||||
import * as schema from '../db/schema';
|
import * as schema from '../db/schema';
|
||||||
|
|
||||||
let instance: BunSQLiteDatabase<typeof schema>;
|
let instance: BunSQLiteDatabase<typeof schema> & {
|
||||||
|
$client: Database;
|
||||||
|
};
|
||||||
export default function useDatabase()
|
export default function useDatabase()
|
||||||
{
|
{
|
||||||
if(!instance)
|
if(!instance)
|
||||||
|
|
@ -13,6 +15,7 @@ export default function useDatabase()
|
||||||
|
|
||||||
instance.run("PRAGMA journal_mode = WAL;");
|
instance.run("PRAGMA journal_mode = WAL;");
|
||||||
instance.run("PRAGMA foreign_keys = true;");
|
instance.run("PRAGMA foreign_keys = true;");
|
||||||
|
instance.run("PRAGMA optimize=0x10002;");
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
|
|
|
||||||
BIN
db.sqlite-shm
BIN
db.sqlite-shm
Binary file not shown.
BIN
db.sqlite-wal
BIN
db.sqlite-wal
Binary file not shown.
|
|
@ -35,7 +35,7 @@ export default defineEventHandler(async (e) => {
|
||||||
return data.content;
|
return data.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
catch(_e)
|
catch(_e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,10 @@ export default defineEventHandler(async (event) => {
|
||||||
//@ts-expect-error
|
//@ts-expect-error
|
||||||
_end.call(event.node.res, await Bun.zstdCompress(buffer), ...args);
|
_end.call(event.node.res, await Bun.zstdCompress(buffer), ...args);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//@ts-expect-error
|
||||||
|
_end.call(event.node.res, body, ...args);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
@ -105,8 +105,8 @@ function reshapeContent(content: string, type: FileType): string | null
|
||||||
return content;
|
return content;
|
||||||
case "canvas":
|
case "canvas":
|
||||||
const data = JSON.parse(content) as CanvasContent;
|
const data = JSON.parse(content) as CanvasContent;
|
||||||
data.edges?.forEach(e => { console.log(e.color); e.color = typeof e.color === 'string' ? getColor(e.color) : undefined; console.log(e.color); });
|
data.edges?.forEach(e => e.color = typeof e.color === 'string' ? getColor(e.color) : undefined);
|
||||||
data.nodes?.forEach(e => { console.log(e.color); e.color = typeof e.color === 'string' ? getColor(e.color) : undefined; console.log(e.color); });
|
data.nodes?.forEach(e => e.color = typeof e.color === 'string' ? getColor(e.color) : undefined);
|
||||||
return JSON.stringify(data);
|
return JSON.stringify(data);
|
||||||
default:
|
default:
|
||||||
case 'folder':
|
case 'folder':
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ export function hasPermissions(userPermissions: string[], neededPermissions: str
|
||||||
{
|
{
|
||||||
for(let i = 0; i < neededPermissions.length; i++)
|
for(let i = 0; i < neededPermissions.length; i++)
|
||||||
{
|
{
|
||||||
const list = neededPermissions[i].split(' ');
|
const list = neededPermissions[i]!.split(' ');
|
||||||
|
|
||||||
if(list.every(e => userPermissions.includes(e)))
|
if(list.every(e => userPermissions.includes(e)))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,6 @@ export class Node extends EventTarget
|
||||||
{ border: `border-light-40 dark:border-dark-40`, bg: `bg-light-40 dark:bg-dark-40` }
|
{ border: `border-light-40 dark:border-dark-40`, bg: `bg-light-40 dark:bg-dark-40` }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NodeEditable extends Node
|
export class NodeEditable extends Node
|
||||||
{
|
{
|
||||||
edges: Set<EdgeEditable> = new Set();
|
edges: Set<EdgeEditable> = new Set();
|
||||||
|
|
@ -440,6 +439,7 @@ export class Canvas
|
||||||
mount()
|
mount()
|
||||||
{
|
{
|
||||||
const dragMove = (e: MouseEvent) => {
|
const dragMove = (e: MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
this.dragMove(e);
|
this.dragMove(e);
|
||||||
};
|
};
|
||||||
const dragEnd = (e: MouseEvent) => {
|
const dragEnd = (e: MouseEvent) => {
|
||||||
|
|
@ -515,6 +515,7 @@ export class Canvas
|
||||||
this.container.removeEventListener('touchmove', touchmove);
|
this.container.removeEventListener('touchmove', touchmove);
|
||||||
};
|
};
|
||||||
const touchmove = (e: TouchEvent) => {
|
const touchmove = (e: TouchEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
const pos = center(e.touches);
|
const pos = center(e.touches);
|
||||||
this._x = this.visualX = this._x - (this.lastX - pos.x) / this._zoom;
|
this._x = this.visualX = this._x - (this.lastX - pos.x) / this._zoom;
|
||||||
this._y = this.visualY = this._y - (this.lastY - pos.y) / this._zoom;
|
this._y = this.visualY = this._y - (this.lastY - pos.y) / this._zoom;
|
||||||
|
|
|
||||||
|
|
@ -502,32 +502,61 @@ export function tabgroup(tabs: Array<{ id: string, title: NodeChildren, content:
|
||||||
})
|
})
|
||||||
return container as HTMLDivElement & { refresh: () => void };
|
return container as HTMLDivElement & { refresh: () => void };
|
||||||
}
|
}
|
||||||
export function floater(container: HTMLElement, content: NodeChildren | (() => NodeChildren), settings?: { class?: Class, position?: Placement, pinned?: boolean, cover?: 'width' | 'height' | 'all' | 'none' })
|
export function floater(container: HTMLElement, content: NodeChildren | (() => NodeChildren), settings?: { class?: Class, position?: Placement, pinned?: boolean, cover?: 'width' | 'height' | 'all' | 'none', events?: { show: Array<keyof HTMLElementEventMap>, hide: Array<keyof HTMLElementEventMap>, onshow?: (this: HTMLElement) => boolean, onhide?: (this: HTMLElement) => boolean }, title?: string })
|
||||||
{
|
{
|
||||||
let viewport = document.getElementById('mainContainer') ?? undefined;
|
let viewport = document.getElementById('mainContainer') ?? undefined;
|
||||||
|
let diffX, diffY, targetWidth, targetHeight;
|
||||||
|
|
||||||
const dragstart = (e: MouseEvent) => {
|
const dragstart = (e: MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
window.addEventListener('mousemove', dragmove);
|
window.addEventListener('mousemove', dragmove);
|
||||||
window.addEventListener('mouseup', dragend);
|
window.addEventListener('mouseup', dragend);
|
||||||
|
|
||||||
|
const box = floating.content.getBoundingClientRect();
|
||||||
|
diffX = e.clientX - box.x;
|
||||||
|
diffY = e.clientY - box.y;
|
||||||
};
|
};
|
||||||
|
const resizestart = (e: MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
window.addEventListener('mousemove', resizemove);
|
||||||
|
window.addEventListener('mouseup', resizeend);
|
||||||
|
};
|
||||||
|
|
||||||
const dragmove = (e: MouseEvent) => {
|
const dragmove = (e: MouseEvent) => {
|
||||||
const box = floating.content.getBoundingClientRect();
|
const box = floating.content.getBoundingClientRect();
|
||||||
const viewbox = viewport?.getBoundingClientRect();
|
const viewbox = viewport?.getBoundingClientRect() ?? { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight, left: 0, right: window.innerWidth, top: 0, bottom: window.innerHeight };
|
||||||
box.x = clamp(box.x + e.movementX, viewbox?.left ?? 0, (viewbox?.right ?? Infinity) - box.width);
|
box.x = clamp(e.clientX - diffX!, viewbox?.left ?? 0, viewbox.right - box.width);
|
||||||
box.y = clamp(box.y + e.movementY, viewbox?.top ?? 0, (viewbox?.bottom ?? Infinity) - box.height);
|
box.y = clamp(e.clientY - diffY!, viewbox?.top ?? 0, viewbox.bottom - box.height);
|
||||||
|
|
||||||
Object.assign(floating.content.style, {
|
Object.assign(floating.content.style, {
|
||||||
left: `${box.x}px`,
|
left: `${box.x}px`,
|
||||||
top: `${box.y}px`,
|
top: `${box.y}px`,
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
const resizemove = (e: MouseEvent) => {
|
||||||
|
const box = floating.content.getBoundingClientRect();
|
||||||
|
const viewbox = viewport?.getBoundingClientRect() ?? { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight, left: 0, right: window.innerWidth, top: 0, bottom: window.innerHeight };
|
||||||
|
box.width = clamp(e.clientX - box.x, 200, Math.min(750, viewbox.right - box.x));
|
||||||
|
box.height = clamp(e.clientY - box.y, 150, Math.min(750, viewbox.bottom - box.y));
|
||||||
|
|
||||||
|
Object.assign(floating.content.style, {
|
||||||
|
width: `${box.width}px`,
|
||||||
|
height: `${box.height}px`,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const dragend = (e: MouseEvent) => {
|
const dragend = (e: MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
window.removeEventListener('mousemove', dragmove);
|
window.removeEventListener('mousemove', dragmove);
|
||||||
window.removeEventListener('mouseup', dragend);
|
window.removeEventListener('mouseup', dragend);
|
||||||
};
|
};
|
||||||
|
const resizeend = (e: MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
window.removeEventListener('mousemove', resizemove);
|
||||||
|
window.removeEventListener('mouseup', resizeend);
|
||||||
|
};
|
||||||
|
|
||||||
const floating = popper(container, {
|
const floating = popper(container, {
|
||||||
arrow: true,
|
arrow: true,
|
||||||
|
|
@ -535,18 +564,37 @@ export function floater(container: HTMLElement, content: NodeChildren | (() => N
|
||||||
offset: 12,
|
offset: 12,
|
||||||
cover: settings?.cover,
|
cover: settings?.cover,
|
||||||
placement: settings?.position,
|
placement: settings?.position,
|
||||||
class: 'bg-light-10 dark:bg-dark-10 border border-light-35 dark:border-dark-35 group-data-[pinned]:bg-light-15 dark:group-data-[pinned]:bg-dark-15 group-data-[pinned]:border-light-50 dark:group-data-[pinned]:border-dark-50 text-light-100 dark:text-dark-100 z-[45]',
|
class: 'bg-light-10 dark:bg-dark-10 border border-light-35 dark:border-dark-35 group-data-[pinned]:bg-light-15 dark:group-data-[pinned]:bg-dark-15 group-data-[pinned]:border-light-50 dark:group-data-[pinned]:border-dark-50 text-light-100 dark:text-dark-100 z-[45] relative group-data-[pinned]:h-full',
|
||||||
content: () => [ settings?.pinned !== undefined ? dom('div', { class: 'hidden group-data-[pinned]:flex flex-row gap-4 justify-end border-b border-light-35 dark:border-dark-35 cursor-move', listeners: { mousedown: dragstart } }, [ tooltip(icon('radix-icons:cross-1', { width: 12, height: 12, listeners: { click: (e) => { e.preventDefault(); floating.hide(); } }, class: 'p-1 cursor-pointer' }), 'Fermer', 'right') ]) : undefined, div('min-w-[200px] min-h-[150px] max-w-[600px] max-h-[600px] w-full overflow-auto box-content', typeof content === 'function' ? content() : content) ],
|
content: () => [ settings?.pinned !== undefined ? div('hidden group-data-[pinned]:flex flex-row justify-end border-b border-light-35 dark:border-dark-35', [ dom('span', { class: 'w-full cursor-move text-xs', listeners: { mousedown: dragstart }, text: settings?.title }), tooltip(dom('div', { class: 'cursor-pointer flex', listeners: { mousedown: (e) => { e.stopImmediatePropagation(); floating.hide(); } } }, [icon('radix-icons:cross-1', { width: 12, height: 12, class: 'p-1' })]), 'Fermer', 'right') ]) : undefined, div('h-full group-data-[pinned]:h-[calc(100%-21px)] w-full min-w-[200px] min-h-[150px] max-w-[600px] max-h-[600px] group-data-[pinned]:min-h-[initial] group-data-[pinned]:min-w-[initial] group-data-[pinned]:max-h-[initial] group-data-[pinned]:max-w-[initial] overflow-auto box-content', typeof content === 'function' ? content() : content), dom('span', { class: 'hidden group-data-[pinned]:flex absolute bottom-0 right-0 cursor-nw-resize z-50', listeners: { mousedown: resizestart } }, [ icon('ph:notches', { width: 12, height: 12 }) ]) ],
|
||||||
viewport
|
viewport
|
||||||
});
|
});
|
||||||
|
|
||||||
if(settings?.pinned === false)
|
if(settings?.pinned === false)
|
||||||
|
{
|
||||||
floating.content.addEventListener('click', () => {
|
floating.content.addEventListener('click', () => {
|
||||||
|
if(floating.content.hasAttribute('data-pinned'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const box = floating.content.children.item(0)!.getBoundingClientRect();
|
||||||
|
Object.assign(floating.content.style, {
|
||||||
|
width: `${box.width + 21}px`,
|
||||||
|
height: `${box.height + 21}px`,
|
||||||
|
});
|
||||||
floating.stop();
|
floating.stop();
|
||||||
|
|
||||||
floating.content.addEventListener('mousedown', function() {
|
floating.content.addEventListener('mousedown', function() {
|
||||||
|
if(!floating.content.hasAttribute('data-pinned'))
|
||||||
|
return;
|
||||||
|
|
||||||
this.parentElement?.appendChild(this);
|
this.parentElement?.appendChild(this);
|
||||||
}, { passive: true, capture: true })
|
}, { passive: true });
|
||||||
}, { once: true });
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
floating.stop();
|
||||||
|
floating.show();
|
||||||
|
}
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,9 @@ export class Content
|
||||||
if(Content._ready)
|
if(Content._ready)
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
|
|
||||||
|
if(Content.initPromise)
|
||||||
|
return Content.initPromise;
|
||||||
|
|
||||||
Content.initPromise = new Promise(async (res) => {
|
Content.initPromise = new Promise(async (res) => {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -116,9 +116,6 @@ export interface IconProperties
|
||||||
rotate?: number|string;
|
rotate?: number|string;
|
||||||
style?: Record<string, string | undefined> | string;
|
style?: Record<string, string | undefined> | string;
|
||||||
class?: Class;
|
class?: Class;
|
||||||
listeners?: {
|
|
||||||
[K in keyof HTMLElementEventMap]?: Listener<K>
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
const iconCache: Map<string, HTMLElement> = new Map();
|
const iconCache: Map<string, HTMLElement> = new Map();
|
||||||
export function icon(name: string, properties?: IconProperties): HTMLElement
|
export function icon(name: string, properties?: IconProperties): HTMLElement
|
||||||
|
|
@ -160,17 +157,6 @@ export function icon(name: string, properties?: IconProperties): HTMLElement
|
||||||
else
|
else
|
||||||
for(const [k, v] of Object.entries(properties.style)) if(v !== undefined) element.attributeStyleMap.set(k, v);
|
for(const [k, v] of Object.entries(properties.style)) if(v !== undefined) element.attributeStyleMap.set(k, v);
|
||||||
}
|
}
|
||||||
if(properties?.listeners)
|
|
||||||
{
|
|
||||||
for(let [k, v] of Object.entries(properties.listeners))
|
|
||||||
{
|
|
||||||
const key = k as keyof HTMLElementEventMap, value = v as Listener<typeof key>;
|
|
||||||
if(typeof value === 'function')
|
|
||||||
element.addEventListener(key, value.bind(element));
|
|
||||||
else if(value)
|
|
||||||
element.addEventListener(key, value.listener.bind(element), value.options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,12 @@ export interface PopperProperties extends FloatingProperties
|
||||||
{
|
{
|
||||||
content?: NodeChildren | (() => NodeChildren);
|
content?: NodeChildren | (() => NodeChildren);
|
||||||
delay?: number;
|
delay?: number;
|
||||||
|
events?: {
|
||||||
onShow?: () => boolean | void;
|
show: Array<keyof HTMLElementEventMap>;
|
||||||
onHide?: () => boolean | void;
|
hide: Array<keyof HTMLElementEventMap>;
|
||||||
|
onshow?: () => boolean;
|
||||||
|
onhide?: () => boolean;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModalProperties
|
export interface ModalProperties
|
||||||
|
|
@ -36,13 +39,13 @@ export interface ModalProperties
|
||||||
let teleport: HTMLDivElement;
|
let teleport: HTMLDivElement;
|
||||||
export function init()
|
export function init()
|
||||||
{
|
{
|
||||||
teleport = dom('div', { attributes: { id: 'popper-container' }, class: 'absolute top-0 left-0' });
|
teleport = dom('div', { attributes: { id: 'popper-container' }, class: 'absolute top-0 left-0 z-40' });
|
||||||
document.body.appendChild(teleport);
|
document.body.appendChild(teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function popper(container: HTMLElement, properties?: PopperProperties)
|
export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
{
|
{
|
||||||
let shown = false, manualStop = false, timeout: Timer;
|
let state: 'shown' | 'showing' | 'hidden' | 'hiding' | 'pinned' = 'hidden', manualStop = false, timeout: Timer;
|
||||||
const arrow = svg('svg', { class: ' group-data-[pinned]:hidden absolute fill-light-35 dark:fill-dark-35', attributes: { width: "12", height: "8", viewBox: "0 0 20 10" } }, [svg('polygon', { attributes: { points: "0,0 20,0 10,10" } })]);
|
const arrow = svg('svg', { class: ' group-data-[pinned]:hidden absolute fill-light-35 dark:fill-dark-35', attributes: { width: "12", height: "8", viewBox: "0 0 20 10" } }, [svg('polygon', { attributes: { points: "0,0 20,0 10,10" } })]);
|
||||||
const content = dom('div', { class: properties?.class, style: properties?.style });
|
const content = dom('div', { class: properties?.class, style: properties?.style });
|
||||||
const floater = dom('div', { class: 'fixed hidden group', attributes: { 'data-state': 'closed' } }, [ content, properties?.arrow ? arrow : undefined ]);
|
const floater = dom('div', { class: 'fixed hidden group', attributes: { 'data-state': 'closed' } }, [ content, properties?.arrow ? arrow : undefined ]);
|
||||||
|
|
@ -110,7 +113,7 @@ export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
let _stop: () => void | undefined, empty = true;
|
let _stop: () => void | undefined, empty = true;
|
||||||
function show()
|
function show()
|
||||||
{
|
{
|
||||||
if(shown || !properties?.onShow || properties?.onShow() !== false)
|
if(state !== 'shown' && state !== 'showing' && state !== 'pinned' && (!properties?.events?.onshow || properties?.events?.onshow() !== false))
|
||||||
{
|
{
|
||||||
if(typeof properties?.content === 'function')
|
if(typeof properties?.content === 'function')
|
||||||
properties.content = properties.content();
|
properties.content = properties.content();
|
||||||
|
|
@ -122,9 +125,10 @@ export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
|
state = 'showing';
|
||||||
|
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
if(!shown)
|
if(state !== 'shown')
|
||||||
{
|
{
|
||||||
teleport!.appendChild(floater);
|
teleport!.appendChild(floater);
|
||||||
|
|
||||||
|
|
@ -132,6 +136,7 @@ export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
floater.classList.toggle('hidden', false);
|
floater.classList.toggle('hidden', false);
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
_stop && _stop();
|
||||||
_stop = FloatingUI.autoUpdate(container, floater, update, {
|
_stop = FloatingUI.autoUpdate(container, floater, update, {
|
||||||
animationFrame: true,
|
animationFrame: true,
|
||||||
layoutShift: false,
|
layoutShift: false,
|
||||||
|
|
@ -139,35 +144,39 @@ export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
ancestorScroll: false,
|
ancestorScroll: false,
|
||||||
ancestorResize: false,
|
ancestorResize: false,
|
||||||
});
|
});
|
||||||
|
console.log("Starting", floater);
|
||||||
}
|
}
|
||||||
shown = true;
|
state = 'shown';
|
||||||
}, properties?.delay ?? 0);
|
}, properties?.delay ?? 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide()
|
function hide()
|
||||||
{
|
{
|
||||||
if(!manualStop && (!properties?.onHide || properties?.onHide() !== false))
|
if(state !== 'hiding' && state !== 'pinned' && (!properties?.events?.onhide || properties?.events?.onhide() !== false))
|
||||||
{
|
{
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
|
state = 'hiding';
|
||||||
|
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
floater.remove();
|
floater.remove();
|
||||||
_stop && _stop();
|
_stop && _stop();
|
||||||
|
console.log('Stoping', floater);
|
||||||
|
|
||||||
floater.setAttribute('data-state', 'closed');
|
floater.setAttribute('data-state', 'closed');
|
||||||
floater.classList.toggle('hidden', true);
|
floater.classList.toggle('hidden', true);
|
||||||
|
|
||||||
shown = false;
|
state = 'hidden';
|
||||||
}, shown ? properties?.delay ?? 0 : 0);
|
}, properties?.delay ?? 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function start()
|
function start()
|
||||||
{
|
{
|
||||||
manualStop = false;
|
state = 'hidden';
|
||||||
floater.toggleAttribute('data-pinned', false);
|
floater.toggleAttribute('data-pinned', false);
|
||||||
update();
|
update();
|
||||||
|
_stop && _stop();
|
||||||
_stop = FloatingUI.autoUpdate(container, floater, update, {
|
_stop = FloatingUI.autoUpdate(container, floater, update, {
|
||||||
animationFrame: true,
|
animationFrame: true,
|
||||||
layoutShift: false,
|
layoutShift: false,
|
||||||
|
|
@ -175,33 +184,28 @@ export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
ancestorScroll: false,
|
ancestorScroll: false,
|
||||||
ancestorResize: false,
|
ancestorResize: false,
|
||||||
});
|
});
|
||||||
|
console.log('Starting', floater);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stop()
|
function stop()
|
||||||
{
|
{
|
||||||
manualStop = true;
|
state = 'pinned';
|
||||||
floater.toggleAttribute('data-pinned', true);
|
floater.toggleAttribute('data-pinned', true);
|
||||||
_stop && _stop();
|
_stop && _stop();
|
||||||
|
console.log('Stoping', floater);
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
function link(element: HTMLElement) {
|
function link(element: HTMLElement) {
|
||||||
Object.entries({
|
(properties?.events?.show ?? ['mouseenter', 'mousemove', 'focus']).forEach((e: keyof HTMLElementEventMap) => element.addEventListener(e, show));
|
||||||
'mouseenter': show,
|
(properties?.events?.hide ?? ['mouseleave', 'blur']).forEach((e: keyof HTMLElementEventMap) => element.addEventListener(e, hide));
|
||||||
'mousemove': show,
|
|
||||||
'mouseleave': hide,
|
|
||||||
'focus': show,
|
|
||||||
'blur': hide,
|
|
||||||
} as Record<keyof HTMLElementEventMap, () => void>).forEach(([event, listener]) => {
|
|
||||||
element.addEventListener(event, listener);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
link(container);
|
link(container);
|
||||||
link(floater);
|
link(floater);
|
||||||
|
|
||||||
return { container, content: floater, stop, start, show: () => {
|
return { container, content: floater, stop, start, show: () => {
|
||||||
if(!shown)
|
if(state !== 'shown')
|
||||||
{
|
{
|
||||||
teleport!.appendChild(floater);
|
teleport!.appendChild(floater);
|
||||||
|
|
||||||
|
|
@ -210,10 +214,11 @@ export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
shown = true;
|
state = 'shown';
|
||||||
}, hide: () => {
|
}, hide: () => {
|
||||||
floater.remove();
|
floater.remove();
|
||||||
_stop && _stop();
|
_stop && _stop();
|
||||||
|
console.log('Stoping', floater);
|
||||||
|
|
||||||
floater.setAttribute('data-state', 'closed');
|
floater.setAttribute('data-state', 'closed');
|
||||||
floater.classList.toggle('hidden', true);
|
floater.classList.toggle('hidden', true);
|
||||||
|
|
@ -221,7 +226,7 @@ export function popper(container: HTMLElement, properties?: PopperProperties)
|
||||||
manualStop = false;
|
manualStop = false;
|
||||||
floater.toggleAttribute('data-pinned', false);
|
floater.toggleAttribute('data-pinned', false);
|
||||||
|
|
||||||
shown = false;
|
state = 'hidden';
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
export function followermenu(target: FloatingUI.ReferenceElement, content: NodeChildren, properties?: FollowerProperties)
|
export function followermenu(target: FloatingUI.ReferenceElement, content: NodeChildren, properties?: FollowerProperties)
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export const a: Prose = {
|
||||||
{
|
{
|
||||||
const canvas = new Canvas((_content as LocalContent<'canvas'>).content);
|
const canvas = new Canvas((_content as LocalContent<'canvas'>).content);
|
||||||
queueMicrotask(() => canvas.mount());
|
queueMicrotask(() => canvas.mount());
|
||||||
return dom('div', { class: 'w-[600px] h-[600px] relative' }, [canvas.container]);
|
return dom('div', { class: 'w-[600px] h-[600px] group-data-[pinned]:h-full group-data-[pinned]:w-full h-[600px] relative w-[600px] relative' }, [canvas.container]);
|
||||||
}
|
}
|
||||||
return div('');
|
return div('');
|
||||||
})).current], { position: 'bottom-start', pinned: false }) : element;
|
})).current], { position: 'bottom-start', pinned: false }) : element;
|
||||||
|
|
@ -55,23 +55,13 @@ export const preview: Prose = {
|
||||||
|
|
||||||
const overview = Content.getFromPath(pathname === '' && hash.length > 0 ? unifySlug(router.currentRoute.value.params.path ?? '') : pathname);
|
const overview = Content.getFromPath(pathname === '' && hash.length > 0 ? unifySlug(router.currentRoute.value.params.path ?? '') : pathname);
|
||||||
|
|
||||||
const el = dom('span', { class: ['cursor-pointer text-accent-blue inline-flex items-center', properties?.class] }, [
|
const element = dom('span', { class: ['cursor-pointer text-accent-blue inline-flex items-center', properties?.class] }, [
|
||||||
...(children ?? []),
|
...(children ?? []),
|
||||||
overview && overview.type !== 'markdown' ? icon(iconByType[overview.type], { class: 'w-4 h-4 inline-block', inline: true }) : undefined
|
overview && overview.type !== 'markdown' ? icon(iconByType[overview.type], { class: 'w-4 h-4 inline-block', inline: true }) : undefined
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const magicKeys = useMagicKeys();
|
const magicKeys = useMagicKeys();
|
||||||
return overview ? popper(el, {
|
return !!overview ? floater(element, () => [async('large', Content.getContent(overview.id).then((_content) => {
|
||||||
arrow: true,
|
|
||||||
delay: 150,
|
|
||||||
offset: 12,
|
|
||||||
cover: "height",
|
|
||||||
placement: 'bottom-start',
|
|
||||||
class: ['data-[side=bottom]:animate-slideUpAndFade data-[side=right]:animate-slideLeftAndFade data-[side=left]:animate-slideRightAndFade data-[side=top]:animate-slideDownAndFade w-[300px] bg-light-10 dark:bg-dark-10 border border-light-35 dark:border-dark-35 data-[state=open]:transition-transform text-light-100 dark:text-dark-100 w-full z-[45]',
|
|
||||||
{ 'min-w-[200px] min-h-[150px] max-w-[600px] max-h-[600px]': !properties?.size || properties.size === 'large', 'max-w-[400px] max-h-[250px]': properties.size === 'small' }
|
|
||||||
],
|
|
||||||
content: () => {
|
|
||||||
return [async('large', Content.getContent(overview.id).then((_content) => {
|
|
||||||
if(_content?.type === 'markdown')
|
if(_content?.type === 'markdown')
|
||||||
{
|
{
|
||||||
return render((_content as LocalContent<'markdown'>).content ?? '', hash.length > 0 ? hash.substring(1) : undefined, { class: 'w-full max-h-full overflow-auto py-4 px-6' });
|
return render((_content as LocalContent<'markdown'>).content ?? '', hash.length > 0 ? hash.substring(1) : undefined, { class: 'w-full max-h-full overflow-auto py-4 px-6' });
|
||||||
|
|
@ -80,16 +70,17 @@ export const preview: Prose = {
|
||||||
{
|
{
|
||||||
const canvas = new Canvas((_content as LocalContent<'canvas'>).content);
|
const canvas = new Canvas((_content as LocalContent<'canvas'>).content);
|
||||||
queueMicrotask(() => canvas.mount());
|
queueMicrotask(() => canvas.mount());
|
||||||
return dom('div', { class: 'w-[600px] h-[600px] relative' }, [canvas.container]);
|
return dom('div', { class: 'w-[600px] h-[600px] group-data-[pinned]:h-full group-data-[pinned]:w-full h-[600px] relative w-[600px] relative' }, [canvas.container]);
|
||||||
}
|
}
|
||||||
return div('');
|
return div('');
|
||||||
})).current];
|
})).current], { position: 'bottom-start', pinned: false,
|
||||||
},
|
events: {
|
||||||
onShow() {
|
show: ['mouseenter', 'mousemove'],
|
||||||
if(!magicKeys.current.has('control') || magicKeys.current.has('meta'))
|
hide: ['mouseleave'],
|
||||||
return false;
|
onshow() {
|
||||||
},
|
return !magicKeys.current.has('control') || !magicKeys.current.has('meta');
|
||||||
}).container : el;
|
}
|
||||||
|
}, }) : element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const callout: Prose = {
|
export const callout: Prose = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue