fuma 0.1.19 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/ui/card/Card.svelte +2 -0
- package/dist/ui/context.d.ts +6 -0
- package/dist/ui/context.js +12 -0
- package/dist/ui/drawer/Drawer.svelte +10 -7
- package/dist/ui/drawer/Drawer.svelte.d.ts +2 -0
- package/dist/ui/form/Form.svelte +21 -5
- package/dist/ui/form/Form.svelte.d.ts +2 -1
- package/dist/ui/form/formInput.d.ts +3 -2
- package/dist/ui/form/formInput.js +2 -1
- package/dist/ui/input/textRich/InputTextRich.svelte +11 -11
- package/dist/ui/input/textRich/InputTextRich.svelte.d.ts +10 -1
- package/dist/ui/input/textRich/index.d.ts +2 -0
- package/dist/ui/input/textRich/index.js +2 -0
- package/dist/ui/input/textRich/tiptapParser.d.ts +4 -0
- package/dist/ui/input/textRich/tiptapParser.js +29 -0
- package/dist/ui/tabs/Tabs.svelte +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/nestedPaths.d.ts +24 -0
- package/dist/utils/nestedPaths.js +2 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -10,10 +10,13 @@ echo "Enter mysql username : " && read mysql_username
|
|
|
10
10
|
|
|
11
11
|
pn create svelte@latest $project_name
|
|
12
12
|
cd $project_name
|
|
13
|
-
px svelte-add@latest tailwindcss --tailwindcss-daisyui
|
|
13
|
+
px svelte-add@latest tailwindcss --tailwindcss-daisyui --tailwindcss-typography
|
|
14
14
|
pn install
|
|
15
15
|
pn install fuma prisma lucia oslo @lucia-auth/adapter-prisma
|
|
16
16
|
sed -i "s|\}'\],|\}', './node_modules/**/fuma/dist/**/*.svelte'\],|g" tailwind.config.cjs
|
|
17
|
+
# TODO: tailwind.config {darkMode: 'class', }
|
|
18
|
+
|
|
19
|
+
|
|
17
20
|
sed -i 's|"singleQuote": true,|"singleQuote": true,\n\t"semi": false,|g' .prettierrc
|
|
18
21
|
|
|
19
22
|
# Prisma
|
package/dist/ui/card/Card.svelte
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<script>import { mdiArrowLeft } from "@mdi/js";
|
|
2
2
|
import { Icon } from "../../index.js";
|
|
3
|
+
import { contextContainer } from "../context.js";
|
|
3
4
|
let klass = "";
|
|
4
5
|
export { klass as class };
|
|
5
6
|
export let bodyClass = "";
|
|
6
7
|
export let headerClass = "";
|
|
7
8
|
export let returnUrl = "";
|
|
8
9
|
export let style = "";
|
|
10
|
+
contextContainer.set("card");
|
|
9
11
|
</script>
|
|
10
12
|
|
|
11
13
|
<div class="card bordered border bg-base-100 shadow-lg {klass}" {style}>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
const KEYS = {
|
|
3
|
+
container: 'container'
|
|
4
|
+
};
|
|
5
|
+
export const contextContainer = {
|
|
6
|
+
set(container) {
|
|
7
|
+
return setContext(KEYS.container, container);
|
|
8
|
+
},
|
|
9
|
+
get() {
|
|
10
|
+
return getContext(KEYS.container);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -5,21 +5,24 @@ import { goto } from "$app/navigation";
|
|
|
5
5
|
import { urlParam } from "../../store/param.js";
|
|
6
6
|
import { Icon } from "../index.js";
|
|
7
7
|
import { subscibeDrawerLayers } from "./layers.js";
|
|
8
|
+
import { contextContainer } from "../context.js";
|
|
8
9
|
export let title = "";
|
|
9
10
|
export let key;
|
|
10
11
|
export let value = "1";
|
|
11
12
|
let klass = "";
|
|
12
13
|
export { klass as class };
|
|
13
14
|
export let maxWidth = "32rem";
|
|
15
|
+
export let classHeader = "";
|
|
16
|
+
export let classBody = "";
|
|
14
17
|
export function open() {
|
|
15
|
-
goto($urlParam.with({ key: value }), { replaceState: true });
|
|
18
|
+
goto($urlParam.with({ [key]: value }), { replaceState: true });
|
|
16
19
|
}
|
|
17
20
|
export function close() {
|
|
18
|
-
console.log("close");
|
|
19
21
|
goto($urlParam.without(key), { replaceState: true });
|
|
20
22
|
}
|
|
21
23
|
const { offset, destroy, isActive } = subscibeDrawerLayers(key, value);
|
|
22
24
|
onDestroy(destroy);
|
|
25
|
+
contextContainer.set("drawer");
|
|
23
26
|
</script>
|
|
24
27
|
|
|
25
28
|
<svelte:head>
|
|
@@ -39,20 +42,20 @@ onDestroy(destroy);
|
|
|
39
42
|
on:keyup={close}
|
|
40
43
|
transition:fade={{ duration: 200 }}
|
|
41
44
|
class="
|
|
42
|
-
fixed inset-0 z-10 bg-black/
|
|
43
|
-
dark:bg-white/
|
|
45
|
+
fixed inset-0 z-10 bg-black/15 backdrop-blur-[1.5px]
|
|
46
|
+
dark:bg-white/15"
|
|
44
47
|
/>
|
|
45
48
|
|
|
46
49
|
<aside
|
|
47
50
|
transition:fly|local={{ x: 500, duration: 200 }}
|
|
48
51
|
style="max-width: min(100%, {maxWidth}); transform: translateX({-$offset * 4}rem);"
|
|
49
52
|
class="{klass}
|
|
50
|
-
fixed bottom-0 right-0 top-0 z-10 flex
|
|
53
|
+
fixed bottom-0 right-0 top-0 z-10 flex w-full
|
|
51
54
|
flex-col overflow-y-scroll bg-base-100 transition-transform
|
|
52
55
|
"
|
|
53
56
|
>
|
|
54
57
|
<div
|
|
55
|
-
class="
|
|
58
|
+
class="{classHeader}
|
|
56
59
|
sticky top-0 z-10 flex items-center
|
|
57
60
|
justify-between gap-32 border-b bg-base-100 p-4 pl-8
|
|
58
61
|
"
|
|
@@ -63,7 +66,7 @@ onDestroy(destroy);
|
|
|
63
66
|
</button>
|
|
64
67
|
</div>
|
|
65
68
|
|
|
66
|
-
<div class="grow">
|
|
69
|
+
<div class="{classBody} grow pl-8 pr-4">
|
|
67
70
|
<slot />
|
|
68
71
|
</div>
|
|
69
72
|
</aside>
|
|
@@ -6,6 +6,8 @@ declare const __propDef: {
|
|
|
6
6
|
/** Value need to match in url query params*/ value?: string | undefined;
|
|
7
7
|
class?: string | undefined;
|
|
8
8
|
maxWidth?: string | undefined;
|
|
9
|
+
classHeader?: string | undefined;
|
|
10
|
+
classBody?: string | undefined;
|
|
9
11
|
open?: (() => void) | undefined;
|
|
10
12
|
close?: (() => void) | undefined;
|
|
11
13
|
};
|
package/dist/ui/form/Form.svelte
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
<script>import {
|
|
2
|
-
initData,
|
|
3
|
-
getFieldType
|
|
4
|
-
} from "./form.js";
|
|
1
|
+
<script>import { contextContainer } from "../context.js";
|
|
5
2
|
import { createEventDispatcher, onMount } from "svelte";
|
|
6
3
|
import { fade } from "svelte/transition";
|
|
7
4
|
import { page } from "$app/stores";
|
|
5
|
+
import {
|
|
6
|
+
initData,
|
|
7
|
+
getFieldType
|
|
8
|
+
} from "./form.js";
|
|
8
9
|
import { useForm } from "../../validation/form.js";
|
|
9
10
|
import Input from "./FormInput.svelte";
|
|
10
11
|
import FormSection from "./FormSection.svelte";
|
|
11
12
|
let klass = "";
|
|
12
13
|
export { klass as class };
|
|
13
14
|
export let classSection = "";
|
|
15
|
+
export let classAction = "";
|
|
14
16
|
export let fields = [];
|
|
15
17
|
export let sections = [{}];
|
|
16
18
|
export let data = initData(fields);
|
|
@@ -38,6 +40,15 @@ function lookupValueFromParams() {
|
|
|
38
40
|
data[key] = value;
|
|
39
41
|
});
|
|
40
42
|
}
|
|
43
|
+
const actionPadding = getActionPadding();
|
|
44
|
+
function getActionPadding() {
|
|
45
|
+
const container = contextContainer.get();
|
|
46
|
+
if (container === "card")
|
|
47
|
+
return "-mx-2 sm:-mx-8 px-2 sm:px-8";
|
|
48
|
+
if (container === "drawer")
|
|
49
|
+
return "-ml-8 -mr-4 pl-8 pr-4";
|
|
50
|
+
return "";
|
|
51
|
+
}
|
|
41
52
|
const getBoolean = (bool) => (_data) => typeof bool === "boolean" || bool === void 0 ? !!bool : !!bool(_data);
|
|
42
53
|
</script>
|
|
43
54
|
|
|
@@ -80,7 +91,12 @@ const getBoolean = (bool) => (_data) => typeof bool === "boolean" || bool === vo
|
|
|
80
91
|
{/if}
|
|
81
92
|
{/each}
|
|
82
93
|
|
|
83
|
-
<div
|
|
94
|
+
<div
|
|
95
|
+
class="
|
|
96
|
+
{classAction} {actionPadding}
|
|
97
|
+
sticky bottom-0 col-span-full mt-2 flex gap-2 border-t py-4 backdrop-blur-sm
|
|
98
|
+
"
|
|
99
|
+
>
|
|
84
100
|
{#if actionDelete}
|
|
85
101
|
<button
|
|
86
102
|
class="btn-ghos btn text-error"
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import { type FormField, type FormSectionProps } from './form.js';
|
|
3
2
|
import type { z } from 'zod';
|
|
3
|
+
import { type FormField, type FormSectionProps } from './form.js';
|
|
4
4
|
declare class __sveltets_Render<Shape extends z.ZodRawShape> {
|
|
5
5
|
props(): {
|
|
6
6
|
class?: string | undefined;
|
|
7
7
|
classSection?: string | undefined;
|
|
8
|
+
classAction?: string | undefined;
|
|
8
9
|
fields?: FormField<Shape>[][] | undefined;
|
|
9
10
|
sections?: FormSectionProps<Shape>[] | undefined;
|
|
10
11
|
data?: Partial<z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]> extends infer T ? { [k in keyof T]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<Shape>, { [k_1 in keyof z.baseObjectOutputType<Shape>]: undefined extends z.baseObjectOutputType<Shape>[k_1] ? never : k_1; }[keyof Shape]>[k]; } : never> | undefined;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { ComponentProps } from 'svelte';
|
|
2
|
-
import { InputText, InputTextarea, InputBoolean, InputDate, InputDatetime, InputNumber, InputPassword, InputRadio, InputSelect, InputRelation, InputRelations } from '../input/index.js';
|
|
2
|
+
import { InputText, InputTextarea, InputBoolean, InputDate, InputDatetime, InputNumber, InputPassword, InputRadio, InputSelect, InputRelation, InputRelations, InputTextRich } from '../input/index.js';
|
|
3
3
|
export declare const formInputs: {
|
|
4
4
|
readonly text: typeof InputText;
|
|
5
5
|
readonly textarea: typeof InputTextarea;
|
|
6
|
+
readonly textrich: typeof InputTextRich;
|
|
6
7
|
readonly boolean: typeof InputBoolean;
|
|
7
8
|
readonly date: typeof InputDate;
|
|
8
9
|
readonly datetime: typeof InputDatetime;
|
|
@@ -19,7 +20,7 @@ export type FormInputProps<T extends FormInputsType> = ComponentProps<InstanceTy
|
|
|
19
20
|
export type FormInputsProps = {
|
|
20
21
|
[T in FormInputsType]: FormInputProps<T>;
|
|
21
22
|
};
|
|
22
|
-
export declare const formInputsType: ("number" | "boolean" | "select" | "date" | "textarea" | "text" | "password" | "radio" | "datetime" | "relation" | "relations")[];
|
|
23
|
+
export declare const formInputsType: ("number" | "boolean" | "select" | "date" | "textarea" | "text" | "password" | "radio" | "textrich" | "datetime" | "relation" | "relations")[];
|
|
23
24
|
export declare function relationProps<Item extends {
|
|
24
25
|
id: string;
|
|
25
26
|
}>(props: ComponentProps<InstanceType<typeof InputRelation<Item>>>): {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { InputText, InputTextarea, InputBoolean, InputDate, InputDatetime, InputNumber, InputPassword, InputRadio, InputSelect, InputRelation, InputRelations } from '../input/index.js';
|
|
1
|
+
import { InputText, InputTextarea, InputBoolean, InputDate, InputDatetime, InputNumber, InputPassword, InputRadio, InputSelect, InputRelation, InputRelations, InputTextRich } from '../input/index.js';
|
|
2
2
|
export const formInputs = {
|
|
3
3
|
text: InputText,
|
|
4
4
|
textarea: InputTextarea,
|
|
5
|
+
textrich: InputTextRich,
|
|
5
6
|
boolean: InputBoolean,
|
|
6
7
|
date: InputDate,
|
|
7
8
|
datetime: InputDatetime,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import { Editor } from "@tiptap/core";
|
|
3
3
|
import debounce from "debounce";
|
|
4
4
|
import { jsonParse } from "../../../utils/jsonParse.js";
|
|
5
|
+
import { FormControl } from "../../index.js";
|
|
5
6
|
import ToolsBar from "./ToolsBar.svelte";
|
|
6
7
|
import { extensions } from "./extensions.js";
|
|
7
8
|
export let value = "";
|
|
8
|
-
export let key = "";
|
|
9
9
|
export let classToolbar = "";
|
|
10
10
|
let element;
|
|
11
11
|
let editor = null;
|
|
@@ -38,7 +38,6 @@ const updateValue = debounce(() => {
|
|
|
38
38
|
if (!editor)
|
|
39
39
|
return;
|
|
40
40
|
const newValue = JSON.stringify(editor.getJSON());
|
|
41
|
-
console.log(newValue);
|
|
42
41
|
if (newValue === value)
|
|
43
42
|
return;
|
|
44
43
|
value = newValue;
|
|
@@ -46,13 +45,14 @@ const updateValue = debounce(() => {
|
|
|
46
45
|
}, 120);
|
|
47
46
|
</script>
|
|
48
47
|
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
<FormControl {...$$restProps} let:key>
|
|
49
|
+
<div class="bordered relative rounded-lg border">
|
|
50
|
+
{#if editor}
|
|
51
|
+
<ToolsBar {editor} class={classToolbar} />
|
|
52
|
+
{/if}
|
|
53
|
+
<div bind:this={element} class="min-h-[20rem] p-4 pb-10" />
|
|
54
|
+
</div>
|
|
55
|
+
{#if key}
|
|
56
|
+
<input type="hidden" name={key} {value} />
|
|
52
57
|
{/if}
|
|
53
|
-
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
{#if key}
|
|
57
|
-
<input type="hidden" name={key} {value} />
|
|
58
|
-
{/if}
|
|
58
|
+
</FormControl>
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
|
-
|
|
4
|
+
class?: string | undefined;
|
|
5
|
+
classLabel?: string | undefined;
|
|
5
6
|
key?: string | undefined;
|
|
7
|
+
label?: string | undefined;
|
|
8
|
+
error?: string | undefined;
|
|
9
|
+
hint?: string | undefined;
|
|
10
|
+
prefix?: string | number | undefined;
|
|
11
|
+
prefixFor?: string | number | undefined;
|
|
12
|
+
enhanceDisabled?: boolean | undefined;
|
|
13
|
+
} & {
|
|
14
|
+
value?: string | undefined;
|
|
6
15
|
classToolbar?: string | undefined;
|
|
7
16
|
};
|
|
8
17
|
events: {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { generateHTML, generateJSON } from '@tiptap/html';
|
|
2
|
+
import { extensions } from './extensions.js';
|
|
3
|
+
import { jsonParse } from '../../../utils/jsonParse.js';
|
|
4
|
+
export const tiptapParser = {
|
|
5
|
+
toHTML(jsonAsString) {
|
|
6
|
+
try {
|
|
7
|
+
if (!jsonAsString.startsWith('{'))
|
|
8
|
+
return jsonAsString;
|
|
9
|
+
const json = jsonParse(jsonAsString, []);
|
|
10
|
+
if (!json)
|
|
11
|
+
return '';
|
|
12
|
+
return generateHTML(json, extensions);
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error(err);
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
toJSON(html) {
|
|
20
|
+
try {
|
|
21
|
+
const json = generateJSON(html, extensions);
|
|
22
|
+
return JSON.stringify(json);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.error(err);
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
package/dist/ui/tabs/Tabs.svelte
CHANGED
|
@@ -15,6 +15,7 @@ export { klass as class };
|
|
|
15
15
|
{@const active = tab.isActive ?? $page.url.pathname.startsWith(tab.href)}
|
|
16
16
|
<a
|
|
17
17
|
href={tab.href}
|
|
18
|
+
data-sveltekit-noscroll
|
|
18
19
|
class="
|
|
19
20
|
menu-item grow flex-col justify-center gap-0 rounded-lg py-2
|
|
20
21
|
text-sm lg:flex-row lg:gap-3 lg:text-base
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type GenericObject = Record<PropertyKey, unknown>;
|
|
2
|
+
type Join<L extends PropertyKey | undefined, R extends PropertyKey | undefined> = L extends string | number ? R extends string | number ? `${L}.${R}` : L : R extends string | number ? R : undefined;
|
|
3
|
+
type Union<L extends unknown | undefined, R extends unknown | undefined> = L extends undefined ? R extends undefined ? undefined : R : R extends undefined ? L : L | R;
|
|
4
|
+
/**
|
|
5
|
+
* NestedPaths
|
|
6
|
+
* Get all the possible paths of an object
|
|
7
|
+
* @example
|
|
8
|
+
* type Keys = NestedPaths<{ a: { b: { c: string } }>
|
|
9
|
+
* // 'a' | 'a.b' | 'a.b.c'
|
|
10
|
+
*/
|
|
11
|
+
export type NestedPaths<T extends GenericObject, Prev extends PropertyKey | undefined = undefined, Path extends PropertyKey | undefined = undefined> = {
|
|
12
|
+
[K in keyof T]: Required<T>[K] extends GenericObject ? NestedPaths<Required<T>[K], Union<Prev, Path>, Join<Path, K>> : Union<Union<Prev, Path>, Join<Path, K>>;
|
|
13
|
+
}[keyof T];
|
|
14
|
+
/**
|
|
15
|
+
* TypeFromPath
|
|
16
|
+
* Get the type of the element specified by the path
|
|
17
|
+
* @example
|
|
18
|
+
* type TypeOfAB = TypeFromPath<{ a: { b: { c: string } }, 'a.b'>
|
|
19
|
+
* // { c: string }
|
|
20
|
+
*/
|
|
21
|
+
export type TypeFromPath<T extends GenericObject, Path extends string> = {
|
|
22
|
+
[K in Path]: K extends keyof T ? T[K] : K extends `${infer P}.${infer S}` ? T[P] extends GenericObject ? TypeFromPath<T[P], S> : never : never;
|
|
23
|
+
}[Path];
|
|
24
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fuma",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "My fullstack material build with sveltekit, daisyui, zod and more",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Jonas Voisard",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"@sveltejs/kit": "^2.5.6",
|
|
34
34
|
"@sveltejs/package": "^2.0.0",
|
|
35
35
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
|
36
|
+
"@tailwindcss/typography": "^0.5.13",
|
|
36
37
|
"@types/debounce": "^1.2.4",
|
|
37
38
|
"@types/eslint": "^8.56.0",
|
|
38
39
|
"@types/node": "^20.12.7",
|
|
@@ -72,6 +73,7 @@
|
|
|
72
73
|
"@tiptap/extension-text-align": "^2.3.0",
|
|
73
74
|
"@tiptap/extension-text-style": "^2.3.0",
|
|
74
75
|
"@tiptap/extension-youtube": "^2.3.0",
|
|
76
|
+
"@tiptap/html": "^2.3.0",
|
|
75
77
|
"@tiptap/pm": "^2.3.0",
|
|
76
78
|
"@tiptap/starter-kit": "^2.3.0",
|
|
77
79
|
"@tiptap/suggestion": "^2.3.0",
|