fuma 0.2.6 → 0.3.3

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.
Files changed (72) hide show
  1. package/dist/api/client.d.ts +3 -0
  2. package/dist/api/client.js +24 -0
  3. package/dist/api/config.d.ts +46 -0
  4. package/dist/api/config.js +7 -0
  5. package/dist/api/index.d.ts +3 -0
  6. package/dist/api/index.js +3 -0
  7. package/dist/api/server.d.ts +11 -0
  8. package/dist/api/server.js +17 -0
  9. package/dist/{Meta.svelte → private/Meta.svelte} +4 -4
  10. package/dist/private/api.d.ts +61 -0
  11. package/dist/private/api.js +10 -0
  12. package/dist/private/constant.d.ts +14 -0
  13. package/dist/private/constant.js +6 -0
  14. package/dist/private/model.d.ts +78 -0
  15. package/dist/private/model.js +25 -0
  16. package/dist/server/auth.js +1 -1
  17. package/dist/server/parseFormData.js +21 -1
  18. package/dist/server/parseQuery.d.ts +1 -10
  19. package/dist/server/parseQuery.js +4 -5
  20. package/dist/server/try.js +0 -1
  21. package/dist/ui/drawer/Drawer.svelte +19 -11
  22. package/dist/ui/drawer/Drawer.svelte.d.ts +42 -7
  23. package/dist/ui/drawer/layers.d.ts +2 -1
  24. package/dist/ui/drawer/layers.js +5 -4
  25. package/dist/ui/form/Form.svelte +43 -24
  26. package/dist/ui/form/Form.svelte.d.ts +20 -12
  27. package/dist/ui/form/FormInput.svelte.d.ts +4 -0
  28. package/dist/ui/form/form.d.ts +20 -12
  29. package/dist/ui/form/form.js +34 -26
  30. package/dist/ui/form/formInput.d.ts +3 -1
  31. package/dist/ui/input/FormControl.svelte.d.ts +1 -1
  32. package/dist/ui/input/InputBoolean.svelte +4 -2
  33. package/dist/ui/input/InputBoolean.svelte.d.ts +2 -2
  34. package/dist/ui/input/InputCheckboxs.svelte.d.ts +2 -2
  35. package/dist/ui/input/InputCheckboxsMenu.svelte +5 -5
  36. package/dist/ui/input/InputCheckboxsMenu.svelte.d.ts +2 -2
  37. package/dist/ui/input/InputCombo.svelte.d.ts +2 -2
  38. package/dist/ui/input/InputDate.svelte +10 -7
  39. package/dist/ui/input/InputDate.svelte.d.ts +1 -1
  40. package/dist/ui/input/InputDatetime.svelte +24 -12
  41. package/dist/ui/input/InputDatetime.svelte.d.ts +2 -2
  42. package/dist/ui/input/InputNumber.svelte +12 -11
  43. package/dist/ui/input/InputNumber.svelte.d.ts +1 -1
  44. package/dist/ui/input/InputPassword.svelte.d.ts +2 -2
  45. package/dist/ui/input/InputRadio.svelte.d.ts +2 -2
  46. package/dist/ui/input/InputRelation.svelte +10 -3
  47. package/dist/ui/input/InputRelation.svelte.d.ts +2 -0
  48. package/dist/ui/input/InputRelations.svelte +10 -3
  49. package/dist/ui/input/InputRelations.svelte.d.ts +2 -0
  50. package/dist/ui/input/InputSelect.svelte +4 -2
  51. package/dist/ui/input/InputText.svelte.d.ts +2 -2
  52. package/dist/ui/input/textRich/InputTextRich.svelte.d.ts +1 -1
  53. package/dist/ui/input/textRich/extensions.js +1 -1
  54. package/dist/ui/input/types.d.ts +2 -2
  55. package/dist/ui/login/Login.svelte +7 -3
  56. package/dist/ui/table/field.d.ts +1 -1
  57. package/dist/ui/table/head/TableHeadNumber.svelte +1 -1
  58. package/dist/utils/constant.d.ts +4 -0
  59. package/dist/utils/constant.js +4 -0
  60. package/dist/utils/index.d.ts +1 -0
  61. package/dist/utils/index.js +1 -0
  62. package/dist/utils/jsonParse.d.ts +1 -1
  63. package/dist/utils/jsonParse.js +5 -3
  64. package/dist/utils/options.d.ts +2 -1
  65. package/dist/validation/form.d.ts +6 -5
  66. package/dist/validation/form.js +8 -8
  67. package/dist/validation/zod.d.ts +109 -55
  68. package/dist/validation/zod.js +11 -31
  69. package/package.json +13 -3
  70. /package/dist/{Meta.svelte.d.ts → private/Meta.svelte.d.ts} +0 -0
  71. /package/dist/{server → private}/prisma.d.ts +0 -0
  72. /package/dist/{server → private}/prisma.js +0 -0
@@ -0,0 +1,3 @@
1
+ import { type CreateAxiosDefaults } from 'axios';
2
+ import type { TypeMap, ApiConfig, ApiClient } from './config.js';
3
+ export declare function useApiClient<T extends TypeMap, C extends ApiConfig<T>>(prismaConfig: C, axiosConfig?: CreateAxiosDefaults): ApiClient<T, C>;
@@ -0,0 +1,24 @@
1
+ import axios, {} from 'axios';
2
+ import * as devalue from 'devalue';
3
+ export function useApiClient(prismaConfig, axiosConfig = {}) {
4
+ const _axios = axios.create({ baseURL: '/api', ...axiosConfig });
5
+ function useSearch(model) {
6
+ return async (search) => {
7
+ const config = { params: { search, model } };
8
+ const { data, headers } = await _axios.get('', config);
9
+ ensureJson(headers);
10
+ return devalue.unflatten(data);
11
+ };
12
+ }
13
+ const api = Object.keys(prismaConfig).reduce((acc, model) => ({
14
+ ...acc,
15
+ [model]: useSearch(model)
16
+ }), {});
17
+ return api;
18
+ }
19
+ function ensureJson(headers) {
20
+ const contentType = headers['content-type'];
21
+ if (contentType !== 'application/json') {
22
+ throw new Error(`Response Content-type is '${contentType}' instead 'application/json'`);
23
+ }
24
+ }
@@ -0,0 +1,46 @@
1
+ import type { OperationPayload, GetResult } from '@prisma/client/runtime/library.js';
2
+ export type Operation = 'findFirst' | 'findFirstOrThrow' | 'findUnique' | 'findUniqueOrThrow' | 'findMany' | 'create' | 'createMany' | 'update' | 'updateMany' | 'upsert' | 'delete' | 'deleteMany' | 'aggregate' | 'count' | 'groupBy';
3
+ export type TypeMap = {
4
+ model: {
5
+ [M: string]: {
6
+ payload: OperationPayload;
7
+ operations: {
8
+ [O in Operation]: {
9
+ args: {};
10
+ };
11
+ };
12
+ };
13
+ };
14
+ };
15
+ export type Result<T extends TypeMap, M extends keyof T['model'], Query extends {}, Payload extends T['model'][M]['payload'] = T['model'][M]['payload']> = GetResult<Payload, Query, 'findMany'>;
16
+ export type Query<T extends TypeMap, M extends keyof T['model'], O extends Operation = 'findMany'> = T['model'][M]['operations'][O]['args'];
17
+ export type QueryToResult<T extends TypeMap, M extends keyof T['model'], O extends Operation = 'findMany', Q extends Query<T, M, O> = {}> = (query: Q) => Promise<Result<T, M, Q>>;
18
+ export type ApiPrismaClient<T extends TypeMap> = {
19
+ [M in keyof T['model']]: {
20
+ [O in Operation]: QueryToResult<T, M, O>;
21
+ };
22
+ };
23
+ /**
24
+ * @example
25
+ * const config = {
26
+ * user: (contains) => ({ where: { username: { contains } } }),
27
+ * } satisfies ApiConfig<Prisma.TypeMap>
28
+ */
29
+ export type ApiConfig<T extends TypeMap> = {
30
+ [M in keyof T['model']]?: (search: string) => Query<T, M, 'findMany'>;
31
+ };
32
+ export type ApiClient<T extends TypeMap, C extends ApiConfig<T>> = {
33
+ [M in keyof C]: C[M] extends (...args: any) => infer Q ? (search: string) => Promise<Result<T, M & string, Q & {}>> : never;
34
+ };
35
+ export type ModelApiQuery = {
36
+ model: string;
37
+ search?: string;
38
+ take?: number;
39
+ skip?: number;
40
+ };
41
+ export declare const modelApiQuery: {
42
+ model: import("zod").ZodString;
43
+ search: import("zod").ZodDefault<import("zod").ZodString>;
44
+ take: import("zod").ZodDefault<import("zod").ZodNumber>;
45
+ skip: import("zod").ZodDefault<import("zod").ZodNumber>;
46
+ };
@@ -0,0 +1,7 @@
1
+ import { z } from '../validation/zod.js';
2
+ export const modelApiQuery = {
3
+ model: z.string(),
4
+ search: z.string().default(''),
5
+ take: z.number().default(10),
6
+ skip: z.number().default(0)
7
+ };
@@ -0,0 +1,3 @@
1
+ export * from './config.js';
2
+ export * from './client.js';
3
+ export * from './server.js';
@@ -0,0 +1,3 @@
1
+ export * from './config.js';
2
+ export * from './client.js';
3
+ export * from './server.js';
@@ -0,0 +1,11 @@
1
+ import { type RequestHandler } from '@sveltejs/kit';
2
+ import { type ApiConfig, type TypeMap } from './config.js';
3
+ interface BasicPrismaClient {
4
+ [K: string]: any;
5
+ $connect: any;
6
+ $transaction: any;
7
+ }
8
+ export declare function apiServer<T extends TypeMap>(config: ApiConfig<T>, client: BasicPrismaClient): {
9
+ GET: RequestHandler;
10
+ };
11
+ export {};
@@ -0,0 +1,17 @@
1
+ import { error } from '@sveltejs/kit';
2
+ import { json } from '../server/json.js';
3
+ import { parseQuery } from '../server/parseQuery.js';
4
+ import { modelApiQuery } from './config.js';
5
+ export function apiServer(config, client) {
6
+ return {
7
+ async GET(event) {
8
+ const { model, search, take, skip } = parseQuery(event.url, modelApiQuery);
9
+ if (!(model in config))
10
+ error(400, `Model "${model}" is not exposed in this API.`);
11
+ const baseQuery = { take, skip };
12
+ //@ts-ignore
13
+ const result = await client[model].findMany({ ...baseQuery, ...config[model](search) });
14
+ return json(result);
15
+ }
16
+ };
17
+ }
@@ -1,9 +1,9 @@
1
1
  <script>import {} from "svelte";
2
2
  import { slide } from "svelte/transition";
3
3
  import { mdiEyeOffOutline, mdiEyeOutline } from "@mdi/js";
4
- import { Card } from "./ui/card/index.js";
5
- import { Table } from "./ui/table/index.js";
6
- import { Icon } from "./ui/icon/index.js";
4
+ import { Card } from "../ui/card/index.js";
5
+ import { Table } from "../ui/table/index.js";
6
+ import { Icon } from "../ui/icon/index.js";
7
7
  export let name = "";
8
8
  export let description = "";
9
9
  export let component;
@@ -27,7 +27,7 @@ function updateComponentMeta(c) {
27
27
  }
28
28
  </script>
29
29
 
30
- <Card class="mx-auto mt-6 max-w-4xl">
30
+ <Card class="mx-auto mb-6 max-w-4xl">
31
31
  <div slot="title" class="flex items-center gap-4">
32
32
  <span class="grow">{name}</span>
33
33
  <button class="btn btn-square btn-sm" on:click={() => (isPropsVisible = !isPropsVisible)}>
@@ -0,0 +1,61 @@
1
+ import type { Prisma } from '@prisma/client';
2
+ export declare const apiConfig: {
3
+ Tag: (search: string) => {
4
+ where: {
5
+ name: {
6
+ contains: string;
7
+ };
8
+ };
9
+ };
10
+ Post: (search: string) => {
11
+ where: {
12
+ tags: {
13
+ some: {
14
+ name: {
15
+ contains: string;
16
+ };
17
+ };
18
+ };
19
+ };
20
+ include: {
21
+ tags: true;
22
+ };
23
+ };
24
+ PostType: (search: string) => {
25
+ where: {
26
+ name: {
27
+ contains: string;
28
+ };
29
+ };
30
+ };
31
+ };
32
+ export declare const api: import("../api/config.js").ApiClient<Prisma.TypeMap<import("@prisma/client/runtime/library").DefaultArgs>, {
33
+ Tag: (search: string) => {
34
+ where: {
35
+ name: {
36
+ contains: string;
37
+ };
38
+ };
39
+ };
40
+ Post: (search: string) => {
41
+ where: {
42
+ tags: {
43
+ some: {
44
+ name: {
45
+ contains: string;
46
+ };
47
+ };
48
+ };
49
+ };
50
+ include: {
51
+ tags: true;
52
+ };
53
+ };
54
+ PostType: (search: string) => {
55
+ where: {
56
+ name: {
57
+ contains: string;
58
+ };
59
+ };
60
+ };
61
+ }>;
@@ -0,0 +1,10 @@
1
+ import { useApiClient } from '../api/client.js';
2
+ export const apiConfig = {
3
+ Tag: (search) => ({ where: { name: { contains: search } } }),
4
+ Post: (search) => ({
5
+ where: { tags: { some: { name: { contains: search } } } },
6
+ include: { tags: true }
7
+ }),
8
+ PostType: (search) => ({ where: { name: { contains: search } } })
9
+ };
10
+ export const api = useApiClient(apiConfig);
@@ -0,0 +1,14 @@
1
+ export declare const POST_PUBLICATION: {
2
+ private: {
3
+ label: string;
4
+ icon: string;
5
+ };
6
+ friends: {
7
+ label: string;
8
+ icon: string;
9
+ };
10
+ public: {
11
+ label: string;
12
+ icon: string;
13
+ };
14
+ };
@@ -0,0 +1,6 @@
1
+ import { mdiAccountGroup, mdiFileLockOutline, mdiWeb } from '@mdi/js';
2
+ export const POST_PUBLICATION = {
3
+ private: { label: 'Private', icon: mdiFileLockOutline },
4
+ friends: { label: 'Friends', icon: mdiAccountGroup },
5
+ public: { label: 'Public', icon: mdiWeb }
6
+ };
@@ -0,0 +1,78 @@
1
+ export declare const modelPost: {
2
+ title: import("zod").ZodString;
3
+ content: import("zod").ZodString;
4
+ isFavourite: import("zod").ZodBoolean;
5
+ likeCount: import("zod").ZodNumber;
6
+ writingAt: import("zod").ZodDate;
7
+ writingDuration: import("zod").ZodDate;
8
+ isInteressing: import("zod").ZodOptional<import("zod").ZodBoolean>;
9
+ viewCounter: import("zod").ZodOptional<import("zod").ZodNumber>;
10
+ publishedAt: import("zod").ZodOptional<import("zod").ZodDate>;
11
+ publishedAtTime: import("zod").ZodOptional<import("zod").ZodDate>;
12
+ publication: import("zod").ZodEnum<["private", "friends", "public"]>;
13
+ type: import("zod").ZodEffects<import("zod").ZodObject<{
14
+ id: import("zod").ZodString;
15
+ }, "strip", import("zod").ZodTypeAny, {
16
+ id: string;
17
+ }, {
18
+ id: string;
19
+ }>, {
20
+ connect: {
21
+ id: string;
22
+ };
23
+ }, {
24
+ id: string;
25
+ }>;
26
+ tags: import("zod").ZodEffects<import("zod").ZodArray<import("zod").ZodObject<{
27
+ id: import("zod").ZodString;
28
+ }, "strip", import("zod").ZodTypeAny, {
29
+ id: string;
30
+ }, {
31
+ id: string;
32
+ }>, "many">, Partial<Record<"set" | "delete" | "connect" | "disconnect", {
33
+ id: string;
34
+ }[]>>, {
35
+ id: string;
36
+ }[]>;
37
+ };
38
+ export declare const modelPostUpdate: {
39
+ id: import("zod").ZodString;
40
+ tags: import("zod").ZodEffects<import("zod").ZodArray<import("zod").ZodObject<{
41
+ id: import("zod").ZodString;
42
+ }, "strip", import("zod").ZodTypeAny, {
43
+ id: string;
44
+ }, {
45
+ id: string;
46
+ }>, "many">, Partial<Record<"set" | "delete" | "connect" | "disconnect", {
47
+ id: string;
48
+ }[]>>, {
49
+ id: string;
50
+ }[]>;
51
+ title: import("zod").ZodString;
52
+ content: import("zod").ZodString;
53
+ isFavourite: import("zod").ZodBoolean;
54
+ likeCount: import("zod").ZodNumber;
55
+ writingAt: import("zod").ZodDate;
56
+ writingDuration: import("zod").ZodDate;
57
+ isInteressing: import("zod").ZodOptional<import("zod").ZodBoolean>;
58
+ viewCounter: import("zod").ZodOptional<import("zod").ZodNumber>;
59
+ publishedAt: import("zod").ZodOptional<import("zod").ZodDate>;
60
+ publishedAtTime: import("zod").ZodOptional<import("zod").ZodDate>;
61
+ publication: import("zod").ZodEnum<["private", "friends", "public"]>;
62
+ type: import("zod").ZodEffects<import("zod").ZodObject<{
63
+ id: import("zod").ZodString;
64
+ }, "strip", import("zod").ZodTypeAny, {
65
+ id: string;
66
+ }, {
67
+ id: string;
68
+ }>, {
69
+ connect: {
70
+ id: string;
71
+ };
72
+ }, {
73
+ id: string;
74
+ }>;
75
+ };
76
+ export declare const modelTag: {
77
+ name: import("zod").ZodString;
78
+ };
@@ -0,0 +1,25 @@
1
+ import { toTuple, z } from '../validation/zod.js';
2
+ import { POST_PUBLICATION } from './constant.js';
3
+ export const modelPost = {
4
+ title: z.string().min(1, 'Required'),
5
+ content: z.string().min(10),
6
+ isFavourite: z.boolean(),
7
+ likeCount: z.number(),
8
+ writingAt: z.date(),
9
+ writingDuration: z.date(),
10
+ isInteressing: z.boolean().optional(),
11
+ viewCounter: z.number().optional(),
12
+ publishedAt: z.date().optional(),
13
+ publishedAtTime: z.date().optional(),
14
+ publication: z.enum(toTuple(POST_PUBLICATION)),
15
+ type: z.relation.connect,
16
+ tags: z.relations.connect
17
+ };
18
+ export const modelPostUpdate = {
19
+ ...modelPost,
20
+ id: z.string(),
21
+ tags: z.relations.set
22
+ };
23
+ export const modelTag = {
24
+ name: z.string().min(1, 'Required')
25
+ };
@@ -1,7 +1,7 @@
1
1
  import { Lucia } from 'lucia';
2
2
  import { dev } from '$app/environment';
3
3
  import { PrismaAdapter } from '@lucia-auth/adapter-prisma';
4
- import { prisma } from './prisma.js';
4
+ import { prisma } from '../private/prisma.js';
5
5
  const adapter = new PrismaAdapter(prisma.session, prisma.user);
6
6
  export const lucia = new Lucia(adapter, {
7
7
  sessionCookie: {
@@ -1,3 +1,5 @@
1
+ import { USE_COERCE_BOOLEAN, USE_COERCE_DATE, USE_COERCE_JSON, USE_COERCE_NUMBER } from '../utils/constant.js';
2
+ import { jsonParse } from '../utils/jsonParse.js';
1
3
  import z from 'zod';
2
4
  export async function parseFormData(requestOrFormData, shapes, validation) {
3
5
  const formData = requestOrFormData instanceof Request ? await requestOrFormData.formData() : requestOrFormData;
@@ -5,7 +7,8 @@ export async function parseFormData(requestOrFormData, shapes, validation) {
5
7
  const shema = z.object(firstShap).superRefine(validation || (() => { }));
6
8
  unionShaps.forEach((shap) => shema.or(z.object(shap)));
7
9
  const formDataFlateObject = Object.fromEntries(formData);
8
- const formDataObject = flateToNeestedObject(formDataFlateObject);
10
+ const formDataFlateObjectCoerced = coerceFlateData(formDataFlateObject);
11
+ const formDataObject = flateToNeestedObject(formDataFlateObjectCoerced);
9
12
  const parsed = shema.safeParse(formDataObject);
10
13
  if (parsed.success === false) {
11
14
  const issueToPOJO = (issue) => ({
@@ -21,6 +24,23 @@ export async function parseFormData(requestOrFormData, shapes, validation) {
21
24
  }
22
25
  return { data: parsed.data, formData };
23
26
  }
27
+ function coerceFlateData(flateData) {
28
+ const coerceMap = {
29
+ [USE_COERCE_JSON]: (value) => jsonParse(value, {}),
30
+ [USE_COERCE_DATE]: (value) => (value ? new Date(value) : undefined),
31
+ [USE_COERCE_NUMBER]: (value) => (value === '' || value === null ? null : +value),
32
+ [USE_COERCE_BOOLEAN]: (value) => value === 'true'
33
+ };
34
+ function coerceValue(value) {
35
+ if (typeof value !== 'string')
36
+ return value;
37
+ const coerce = Object.entries(coerceMap).find(([TOKEN]) => value.startsWith(TOKEN));
38
+ if (!coerce)
39
+ return value;
40
+ return coerce[1](value.replace(coerce[0], ''));
41
+ }
42
+ return Object.entries(flateData).reduce((acc, [key, value]) => ({ ...acc, [key]: coerceValue(value) }), {});
43
+ }
24
44
  function flateToNeestedObject(flatObject) {
25
45
  const obj = {};
26
46
  Object.entries(flatObject).forEach(([key, value]) => {
@@ -1,11 +1,2 @@
1
- /// <reference types="@sveltejs/kit" />
2
1
  import type { ZodRawShape } from 'zod';
3
- export declare function parseQuery<Type extends ZodRawShape>(url: URL, shape: Type): {
4
- err: import("@sveltejs/kit").ActionFailure<{
5
- issues: import("zod").ZodIssue[];
6
- }>;
7
- data?: undefined;
8
- } | {
9
- data: { [k_1 in keyof import("zod").objectUtil.addQuestionMarks<import("zod").baseObjectOutputType<Type>, { [k in keyof import("zod").baseObjectOutputType<Type>]: undefined extends import("zod").baseObjectOutputType<Type>[k] ? never : k; }[keyof Type]>]: import("zod").objectUtil.addQuestionMarks<import("zod").baseObjectOutputType<Type>, { [k_2 in keyof import("zod").baseObjectOutputType<Type>]: undefined extends import("zod").baseObjectOutputType<Type>[k_2] ? never : k_2; }[keyof Type]>[k_1]; };
10
- err?: undefined;
11
- };
2
+ export declare function parseQuery<Type extends ZodRawShape>(url: URL, shape: Type): { [k_1 in keyof import("zod").objectUtil.addQuestionMarks<import("zod").baseObjectOutputType<Type>, { [k in keyof import("zod").baseObjectOutputType<Type>]: undefined extends import("zod").baseObjectOutputType<Type>[k] ? never : k; }[keyof Type]>]: import("zod").objectUtil.addQuestionMarks<import("zod").baseObjectOutputType<Type>, { [k_2 in keyof import("zod").baseObjectOutputType<Type>]: undefined extends import("zod").baseObjectOutputType<Type>[k_2] ? never : k_2; }[keyof Type]>[k_1]; };
@@ -1,4 +1,4 @@
1
- import { fail } from '@sveltejs/kit';
1
+ import { error } from '@sveltejs/kit';
2
2
  import { z } from '../validation/zod.js';
3
3
  export function parseQuery(url, shape) {
4
4
  const queryRaw = {};
@@ -8,8 +8,7 @@ export function parseQuery(url, shape) {
8
8
  queryRaw[name] = param;
9
9
  });
10
10
  const parsed = z.object(shape).safeParse(queryRaw);
11
- if (parsed.success === false) {
12
- return { err: fail(400, { issues: parsed.error.issues }) };
13
- }
14
- return { data: parsed.data };
11
+ if (parsed.success === false)
12
+ error(400, { message: parsed.error.message });
13
+ return parsed.data;
15
14
  }
@@ -20,7 +20,6 @@ redirectTo) {
20
20
  }
21
21
  // Handle parseFormData error
22
22
  if ('issues' in error) {
23
- console.log(error.issues);
24
23
  return fail(400, { issues: error.issues });
25
24
  }
26
25
  const { message } = error;
@@ -8,19 +8,22 @@ import { subscibeDrawerLayers } from "./layers.js";
8
8
  import { contextContainer } from "../context.js";
9
9
  export let title = "";
10
10
  export let key;
11
- export let value = "1";
12
11
  let klass = "";
13
12
  export { klass as class };
14
13
  export let maxWidth = "32rem";
15
14
  export let classHeader = "";
16
15
  export let classBody = "";
17
- export function open() {
18
- goto($urlParam.with({ [key]: value }), { replaceState: true, noScroll: true });
16
+ export function open(value = 1, options = {}) {
17
+ return goto($urlParam.with({ [key]: value }), {
18
+ ...options,
19
+ replaceState: true,
20
+ noScroll: true
21
+ });
19
22
  }
20
- export function close() {
21
- goto($urlParam.without(key), { replaceState: true, noScroll: true });
23
+ export function close(options = {}) {
24
+ return goto($urlParam.without(key), { ...options, replaceState: true, noScroll: true });
22
25
  }
23
- const { offset, destroy, isActive } = subscibeDrawerLayers(key, value);
26
+ const { offset, index, destroy, isActive } = subscibeDrawerLayers(key);
24
27
  onDestroy(destroy);
25
28
  contextContainer.set("drawer");
26
29
  </script>
@@ -28,15 +31,20 @@ contextContainer.set("drawer");
28
31
  {#if $isActive}
29
32
  <!-- svelte-ignore a11y-no-static-element-interactions -->
30
33
  <div
31
- on:click={close}
32
- on:keyup={close}
34
+ on:click={() => close()}
35
+ on:keyup={() => close()}
33
36
  transition:fade={{ duration: 200 }}
34
- class="fixed inset-0 z-10 bg-black/15 backdrop-blur-[1.5px] dark:bg-white/15"
37
+ style="z-index: {10 + $index};"
38
+ class="fixed inset-0 bg-black/15 backdrop-blur-[1.5px] dark:bg-white/15"
35
39
  />
36
40
 
37
41
  <aside
38
42
  transition:fly|local={{ x: 500, duration: 200, opacity: 1 }}
39
- style="max-width: min(100%, {maxWidth}); transform: translateX({-$offset * 4}rem);"
43
+ style="
44
+ z-index: {10 + $index};
45
+ max-width: min(100%, {maxWidth});
46
+ transform: translateX({-$offset * 4}rem);
47
+ "
40
48
  class="{klass}
41
49
  fixed bottom-0 right-0 top-0 z-10 flex
42
50
  w-full flex-col overflow-y-scroll bg-base-100
@@ -50,7 +58,7 @@ contextContainer.set("drawer");
50
58
  "
51
59
  >
52
60
  <h2 class="title">{title}</h2>
53
- <button on:click={close} class="btn btn-square btn-sm">
61
+ <button on:click={() => close()} class="btn btn-square btn-sm">
54
62
  <Icon path={mdiClose} title="annuler" />
55
63
  </button>
56
64
  </div>
@@ -3,21 +3,44 @@ declare const __propDef: {
3
3
  props: {
4
4
  title?: string | undefined;
5
5
  /** Key used in url query params */ key: string;
6
- /** Value need to match in url query params*/ value?: string | undefined;
7
6
  class?: string | undefined;
8
7
  maxWidth?: string | undefined;
9
8
  classHeader?: string | undefined;
10
9
  classBody?: string | undefined;
11
- open?: (() => void) | undefined;
12
- close?: (() => void) | undefined;
10
+ open?: ((value?: number, options?: {
11
+ replaceState?: boolean | undefined;
12
+ noScroll?: boolean | undefined;
13
+ keepFocus?: boolean | undefined;
14
+ invalidateAll?: boolean | undefined;
15
+ state?: App.PageState | undefined;
16
+ } | undefined) => Promise<void>) | undefined;
17
+ close?: ((options?: {
18
+ replaceState?: boolean | undefined;
19
+ noScroll?: boolean | undefined;
20
+ keepFocus?: boolean | undefined;
21
+ invalidateAll?: boolean | undefined;
22
+ state?: App.PageState | undefined;
23
+ } | undefined) => Promise<void>) | undefined;
13
24
  };
14
25
  events: {
15
26
  [evt: string]: CustomEvent<any>;
16
27
  };
17
28
  slots: {
18
29
  default: {
19
- open: () => void;
20
- close: () => void;
30
+ open: (value?: number, options?: {
31
+ replaceState?: boolean | undefined;
32
+ noScroll?: boolean | undefined;
33
+ keepFocus?: boolean | undefined;
34
+ invalidateAll?: boolean | undefined;
35
+ state?: App.PageState | undefined;
36
+ } | undefined) => Promise<void>;
37
+ close: (options?: {
38
+ replaceState?: boolean | undefined;
39
+ noScroll?: boolean | undefined;
40
+ keepFocus?: boolean | undefined;
41
+ invalidateAll?: boolean | undefined;
42
+ state?: App.PageState | undefined;
43
+ } | undefined) => Promise<void>;
21
44
  };
22
45
  };
23
46
  };
@@ -25,7 +48,19 @@ export type DrawerProps = typeof __propDef.props;
25
48
  export type DrawerEvents = typeof __propDef.events;
26
49
  export type DrawerSlots = typeof __propDef.slots;
27
50
  export default class Drawer extends SvelteComponent<DrawerProps, DrawerEvents, DrawerSlots> {
28
- get open(): () => void;
29
- get close(): () => void;
51
+ get open(): (value?: number, options?: {
52
+ replaceState?: boolean | undefined;
53
+ noScroll?: boolean | undefined;
54
+ keepFocus?: boolean | undefined;
55
+ invalidateAll?: boolean | undefined;
56
+ state?: App.PageState | undefined;
57
+ } | undefined) => Promise<void>;
58
+ get close(): (options?: {
59
+ replaceState?: boolean | undefined;
60
+ noScroll?: boolean | undefined;
61
+ keepFocus?: boolean | undefined;
62
+ invalidateAll?: boolean | undefined;
63
+ state?: App.PageState | undefined;
64
+ } | undefined) => Promise<void>;
30
65
  }
31
66
  export {};
@@ -1,7 +1,8 @@
1
1
  /// <reference types="svelte" />
2
2
  import { type Readable } from 'svelte/store';
3
- export declare function subscibeDrawerLayers(key: string, value: string): {
3
+ export declare function subscibeDrawerLayers(key: string): {
4
4
  isActive: Readable<boolean>;
5
+ index: Readable<number>;
5
6
  offset: Readable<number>;
6
7
  destroy(): void;
7
8
  };
@@ -1,4 +1,4 @@
1
- import { derived, get, writable } from 'svelte/store';
1
+ import { derived, writable } from 'svelte/store';
2
2
  import { page } from '$app/stores';
3
3
  import { browser } from '$app/environment';
4
4
  const layers = writable([]);
@@ -9,10 +9,10 @@ const layersOffset = derived(layers, ($layers) => {
9
9
  return { ...acc, [layer]: drawerOffset };
10
10
  }, {});
11
11
  });
12
- export function subscibeDrawerLayers(key, value) {
12
+ export function subscibeDrawerLayers(key) {
13
13
  const layerId = Math.random().toString().slice(2, 12);
14
14
  let isInitialized = false;
15
- const isActive = derived(page, ({ url }) => url.searchParams.get(key) === value, false);
15
+ const isActive = derived(page, ({ url }) => url.searchParams.has(key), false);
16
16
  const isActiveUnsubscribe = isActive.subscribe(($isActive) => {
17
17
  if ($isActive)
18
18
  addLayer();
@@ -41,7 +41,8 @@ export function subscibeDrawerLayers(key, value) {
41
41
  }
42
42
  return {
43
43
  isActive,
44
- offset: derived(layersOffset, (drawers) => drawers[layerId]),
44
+ index: derived(layers, ($layers) => $layers.indexOf(layerId)),
45
+ offset: derived(layersOffset, (offsets) => offsets[layerId]),
45
46
  destroy() {
46
47
  removeLayer();
47
48
  isActiveUnsubscribe();