import {
Attributes,
ComponentChild,
ComponentChildren,
JSX,
VNode,
toChildArray,
} from "preact";
import { render } from "preact-render-to-string";
import { writeText } from "copy-paste";
// i know it's out of date; i just want something simple
import { randomInt } from "https://deno.land/std@0.146.0/node/internal/crypto/random.ts";
export function Main({
children,
...attributes
}: {
children?: ComponentChildren;
style?: JSX.CSSProperties;
attributes?: JSX.HTMLAttributes;
}) {
return (
{...toChildArray(children)}
);
}
export const HCenter = ({
children,
...attrs
}: {
children: ComponentChildren;
attrs?: Attributes;
}) => (
{...toChildArray(children)}
);
export const eggbug_emotions = (attrs: JSX.HTMLAttributes) =>
({
smiling: (
),
frowning: (
),
revengeance: (
),
jpeg_annihilation: (
),
golfball: (
),
} as const);
export type EggbugEmotion = keyof ReturnType;
type bla = ({
type: EggbugEmotion;
} & JSX.HTMLAttributes)["type"];
export const EggbugImg = ({
type,
...attrs
}: { type: EggbugEmotion } & Omit<
JSX.HTMLAttributes,
"type"
>) => eggbug_emotions(attrs)[type];
export const render_and_copy = (elem: VNode, pretty = false) => {
const rendered = render(elem, null, { pretty });
writeText(rendered);
console.log(rendered);
};
export const mk_class_wrapper =
(klass: string) =>
({ children }: { children?: ComponentChildren }) =>
{...toChildArray(children)}
;
export const slidify = (
Slide: (_: {
slide: JSX.Element;
next?: JSX.Element;
n: number;
max: number;
}) => JSX.Element,
slides: JSX.Element[],
n = 1,
max = slides.length
): JSX.Element =>
slides[0] ? (
) : (
<>>
);
// https://cohost.org/lexyeevee/post/2107474-css-for-css-baby-3 (wayyy down at the bottom)
export const DisappearOnClick = ({
children,
className,
}: {
className?: string;
children: ComponentChildren;
}) => (
{children}
);
/// make sure the margins are all legit
export const ToggleOnClick = ({
children: [a, b],
}: {
children: [ComponentChild, ComponentChild];
}) => (
{a}
{b}
);
// TODO: probably doesn't work
export const ReduceOnClick = ({ children }: { children: VNode<{}>[] }) => {
if (children.length == 0) return <>>;
if (children.length == 1) return children[1];
return (
{children[0]}
{...children.slice(1)}
);
};
export function shuffle(array: T[]): T[] {
let currentIndex = array.length,
randomIndex;
// While there remain elements to shuffle.
while (currentIndex != 0) {
// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex],
];
}
return array;
}
// type NOf = R["length"] extends N
// ? R
// : NOf;
// export function n_of(
// n: N,
// x: T
// ): NOf {
// return [];
// }
export function n_of(n: number, x: T): T[] {
return new Array(n).fill(x);
}
export const static_url = (res: string) => `https://static.pyrope.net/${res}`;
export const randirect = (...urls: string[]) =>
`https://pyrope.net/randirect#${urls.join("::")}`;
export const serverside_randirect = (...urls: string[]) =>
`https://pyrope.net/serverside-randirect?${urls.join("::")}`;
// could do some [T, ...T[]] shenanigans for totality but meh
// kinda bad name
// unhappy with the randomness so i'm going way overkill lol
export const pick_random = (xs: readonly T[]): T =>
xs[randomInt(xs.length)];
export const jitter = (n: number) => n * (Math.random() - 0.5);
export const svg_url = (svg: string) => `data:image/svg+xml,${encodeURI(svg)}`;
// something higher-level might be worthwhile...
// could namespace; e.g. css.font.sans_serif
// could put various beziers
export const css = {
url(href: string) {
return `url('${href}')`;
},
px(n: number) {
return `${n}px`;
},
em(n: number) {
return `${n}em`;
},
rem(n: number) {
return `${n}rem`;
},
deg(n: number) {
return `${n}deg`;
},
rad(n: number) {
return `${n}rad`;
},
turn(n: number) {
return `${n}turn`;
},
// now i feel like this could be generalizable
// but js metaprogramming SUCKS
transform(...ts: string[]) {
return ts.join(" ");
},
rotate(by: string) {
return `rotate(${by})`;
},
translateX(by: string) {
return `translateX(${by})`;
},
translateY(by: string) {
return `translateY(${by})`;
},
translate(x: string, y: string) {
return `translate(${x}, ${y})`;
},
fontstack(...fonts: string[]) {
return fonts.join(", ");
},
// # ruby i wont you ..
inline_block: "inline-block",
block: "block",
grid: "grid",
flex: "flex",
fit_content: "fit-content",
min_content: "min-content",
max_content: "max-content",
} as const;
export const Filler = ({ height }: { height: string }) => (
);
/// nonfunctional, deno's toplevel await (:D) is generally the best workaround
export function make_sync_no_matter_the_cost(promise: Promise): T {
let done = false;
let out;
promise.then(t => {
out = t;
done = true;
});
return out as T;
}
// INFINITE CREDIT TO @BLACKLE https://cohost.org/blackle/post/72096-h3-style-text-alig
export const Cycle = ({
width_px,
height_px,
children,
style,
credit = true,
}: {
width_px: number;
height_px: number;
children: [ComponentChild, ...ComponentChild[]];
style?: Record;
credit?: boolean;
}) => (
{...children.map((c, i) => (
{c}
))}
);
// yet another banger from @blackle
// i don't think we need the row height stuff for maximum genericity?
export const DragResizableImage = ({
url,
top,
left,
width,
height,
indicator = true,
indicator_opacity = 0.3,
}: {
url: string;
top: number;
left: number;
width: number;
height: number;
indicator?: boolean;
indicator_opacity?: number;
}) => (
);