every bug is a lesson in disguise. Here are the pearls of wisdom I've gathered along the way.
Simple error handling trick to display error messages returned from a pocketbase server
const error = mutation?.error as ClientResponseError;
const pbError = error?.data?.data as Record<string, {message: string,code:string}>
useEffect(() => {
pbError&&Object?.entries(pbError)?.forEach(([key, value]) => {
form.setFieldMeta(key as any,(prev)=>{
return {...prev, errorMap:{
onChange:value?.message
}}
});
});
}, [pbError]);
Copied from a tanstack form discussion 👇
Switching from dark to light modes can be dull and jittery , but a great way to make it look smoother can be adding animations
transition: all 0.3s ease;
but we can take this further by using the newly added view transitions
/* Angled */
[data-style="angled"]::view-transition-old(root) {
animation: none;
z-index: -1;
}
[data-style="angled"]::view-transition-new(root) {
animation: unclip 1s;
clip-path: polygon(-100vmax 100%, 100% 100%, 100% -100vmax);
}
@keyframes unclip {
0% {
clip-path: polygon(100% 100%, 100% 100%, 100% 100%);
}
}
and trigger the animations using the view transitions
function transitionColors() {
if (typeof window !== "undefined") {
try {
document.startViewTransition(() => {
const newTheme = theme === "light" ? "dark" : "light";
document.documentElement.dataset.theme = newTheme;
updateTheme(newTheme);
});
} catch (error) {
const newTheme = theme === "light" ? "dark" : "light";
document.documentElement.dataset.theme = newTheme;
updateTheme(newTheme);
}
}
}
📝 Note
Remember to add thedata-theme
anddata-style
attribute in thehtml
element to make the changes visible
learned how to convert an object type into a union of the keys of all the objcets including the nested ones
type Join<K, P> = K extends string | number
? P extends string | number
? `${K}${"" extends P ? "" : "."}${P}`
: never
: never;
// recurse to depth (neede to avoid infinite recursion)
type Prev = [
never,
0,
1,
2,
3,
4,
5,
...0[],
];
// type will reursivly join keys into a union
export type PossibleNestedUnions<T, D extends number = 10> = [D] extends [never]
? never
: T extends object
? {
[K in keyof T]-?: K extends string | number
? `${K}` | (D extends 0 ? never : Join<K, PossibleNestedUnions<T[K], Prev[D]>>)
: never;
}[keyof T]
: "";
// Example usage:
type ExampleType = {
a: string;
b: {
c: number;
d: {
e: boolean;
f: {
g: string;
};
};
};
h: Date;
};
type NestedKeys1 = NestedUnionsToDepth<ExampleType, 1>; // "a" | "b" | "h"
type NestedKeys2 = NestedUnionsToDepth<ExampleType, 2>; // "a" | "b" | "b.c" | "b.d" | "h"
type NestedKeys3 = NestedUnionsToDepth<ExampleType, 3>; // "a" | "b" | "b.c" | "b.d" | "b.d.e" | "b.d.f" | "h"
type NestedKeysAll = NestedUnionsToDepth<ExampleType, 10>; // All nested