@axium/client 0.9.13 → 0.10.0
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/dist/config.d.ts +1 -1
- package/lib/Preference.svelte +35 -25
- package/package.json +2 -2
package/dist/config.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare const ClientConfig: z.ZodObject<{
|
|
|
17
17
|
emailVerified: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
18
18
|
image: z.ZodOptional<z.ZodNullable<z.ZodURL>>;
|
|
19
19
|
preferences: z.ZodObject<{
|
|
20
|
-
debug: z.ZodBoolean
|
|
20
|
+
debug: z.ZodDefault<z.ZodBoolean>;
|
|
21
21
|
}, z.core.$strip>;
|
|
22
22
|
roles: z.ZodArray<z.ZodString>;
|
|
23
23
|
registeredAt: z.ZodCoercedDate<unknown>;
|
package/lib/Preference.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { fetchAPI } from '@axium/client/requests';
|
|
3
|
-
import {
|
|
3
|
+
import type { Preferences, ZodPref } from '@axium/core';
|
|
4
4
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
5
5
|
import { getByString, pick, setByString } from 'utilium';
|
|
6
6
|
import Icon from './Icon.svelte';
|
|
@@ -11,15 +11,16 @@
|
|
|
11
11
|
preferences: Preferences;
|
|
12
12
|
path: string;
|
|
13
13
|
schema: ZodPref;
|
|
14
|
+
defaultValue?: any;
|
|
14
15
|
optional?: boolean;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
let { preferences = $bindable(), userId, path, schema, optional = false }: Props = $props();
|
|
18
|
+
let { preferences = $bindable(), userId, path, schema, optional = false, defaultValue }: Props = $props();
|
|
18
19
|
const id = $props.id();
|
|
19
20
|
|
|
20
21
|
let input = $state<HTMLInputElement | HTMLSelectElement>()!;
|
|
21
22
|
let checked = $state(schema.def.type == 'boolean' && getByString<boolean>(preferences, path));
|
|
22
|
-
const initialValue = $derived<any>(getByString(preferences, path)
|
|
23
|
+
const initialValue = $derived<any>(getByString(preferences, path));
|
|
23
24
|
|
|
24
25
|
function dateAttr(date: Date | null, format: 'date' | 'time' | 'datetime' | 'time+sec') {
|
|
25
26
|
if (!date) return null;
|
|
@@ -50,77 +51,86 @@
|
|
|
50
51
|
|
|
51
52
|
function onchange(e: Event) {
|
|
52
53
|
const value = schema.parse(input instanceof HTMLInputElement && input.type === 'checkbox' ? input.checked : input.value);
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
const oldValue = getByString(preferences, path);
|
|
55
|
+
if (value == oldValue) return;
|
|
56
|
+
|
|
57
|
+
if (defaultValue == value) {
|
|
58
|
+
const parts = path.split('.');
|
|
59
|
+
const prop = parts.pop()!;
|
|
60
|
+
delete getByString<Record<string, any>>(preferences, parts.join('.'))[prop];
|
|
61
|
+
} else setByString(preferences, path, value);
|
|
62
|
+
|
|
55
63
|
fetchAPI('PATCH', 'users/:id', { preferences }, userId);
|
|
56
64
|
}
|
|
57
65
|
</script>
|
|
58
66
|
|
|
59
67
|
{#snippet _in(rest: HTMLInputAttributes)}
|
|
60
|
-
<input bind:this={input} {id} {...rest} value={initialValue} {onchange} required={!optional} />
|
|
68
|
+
<input bind:this={input} {id} {...rest} value={initialValue} {onchange} required={!optional} {defaultValue} />
|
|
61
69
|
{/snippet}
|
|
62
70
|
|
|
63
|
-
{#if
|
|
71
|
+
{#if schema.type == 'string'}
|
|
64
72
|
{@render _in({ type: schema.format == 'email' ? 'email' : 'text', ...pick(schema, 'minLength', 'maxLength') })}
|
|
65
|
-
{:else if
|
|
73
|
+
{:else if schema.type == 'number'}
|
|
66
74
|
{@render _in({ type: 'number', min: schema.minValue, max: schema.maxValue, step: schema.format?.includes('int') ? 1 : 0.1 })}
|
|
67
|
-
{:else if
|
|
75
|
+
{:else if schema.type == 'bigint'}
|
|
68
76
|
{@render _in({ type: 'number', min: Number(schema.minValue), max: Number(schema.maxValue), step: 1 })}
|
|
69
|
-
{:else if
|
|
77
|
+
{:else if schema.type == 'boolean'}
|
|
70
78
|
<input bind:checked bind:this={input} {id} type="checkbox" {onchange} required={!optional} />
|
|
71
79
|
<label for={id} class="checkbox">
|
|
72
80
|
{#if checked}<Icon i="check" --size="1.3em" />{/if}
|
|
73
81
|
</label>
|
|
74
|
-
{:else if
|
|
82
|
+
{:else if schema.type == 'date'}
|
|
75
83
|
{@render _in({
|
|
76
84
|
type: 'date',
|
|
77
85
|
min: dateAttr(schema.minDate, 'date'),
|
|
78
86
|
max: dateAttr(schema.maxDate, 'date'),
|
|
79
87
|
})}
|
|
80
|
-
{:else if
|
|
88
|
+
{:else if schema.type == 'file'}
|
|
81
89
|
<!-- todo -->
|
|
82
|
-
{:else if
|
|
90
|
+
{:else if schema.type == 'literal'}
|
|
83
91
|
<select bind:this={input} {id} {onchange} required={!optional}>
|
|
84
92
|
{#each schema.values as value}
|
|
85
93
|
<option {value} selected={initialValue === value}>{value}</option>
|
|
86
94
|
{/each}
|
|
87
95
|
</select>
|
|
88
|
-
{:else if
|
|
96
|
+
{:else if schema.type == 'template_literal'}
|
|
89
97
|
<!-- todo -->
|
|
90
|
-
{:else if
|
|
98
|
+
{:else if schema.type == 'default'}
|
|
99
|
+
<Preference {userId} bind:preferences {path} schema={schema.def.innerType} defaultValue={schema.def.defaultValue} />
|
|
100
|
+
{:else if schema.type == 'nullable' || schema.type == 'optional'}
|
|
91
101
|
<!-- defaults are handled differently -->
|
|
92
|
-
<Preference {userId} bind:preferences {path} schema={schema.def.innerType} optional={true} />
|
|
93
|
-
{:else if
|
|
102
|
+
<Preference {userId} bind:preferences {path} {defaultValue} schema={schema.def.innerType} optional={true} />
|
|
103
|
+
{:else if schema.type == 'array'}
|
|
94
104
|
<div class="pref-sub">
|
|
95
105
|
{#each initialValue, i}
|
|
96
106
|
<div class="pref-record-entry">
|
|
97
|
-
<Preference {userId} bind:preferences path="{path}.{i}" schema={schema.element} />
|
|
107
|
+
<Preference {userId} bind:preferences {defaultValue} path="{path}.{i}" schema={schema.element} />
|
|
98
108
|
</div>
|
|
99
109
|
{/each}
|
|
100
110
|
</div>
|
|
101
|
-
{:else if
|
|
111
|
+
{:else if schema.type == 'record'}
|
|
102
112
|
<div class="pref-sub">
|
|
103
113
|
{#each Object.keys(initialValue) as key}
|
|
104
114
|
<div class="pref-record-entry">
|
|
105
115
|
<label for={id}>{key}</label>
|
|
106
|
-
<Preference {userId} bind:preferences path="{path}.{key}" schema={schema.valueType} />
|
|
116
|
+
<Preference {userId} bind:preferences {defaultValue} path="{path}.{key}" schema={schema.valueType} />
|
|
107
117
|
</div>
|
|
108
118
|
{/each}
|
|
109
119
|
</div>
|
|
110
|
-
{:else if
|
|
120
|
+
{:else if schema.type == 'object'}
|
|
111
121
|
{#each Object.entries(schema.shape) as [key, value]}
|
|
112
122
|
<div class="pref-sub">
|
|
113
123
|
<label for={id}>{key}</label>
|
|
114
|
-
<Preference {userId} bind:preferences path="{path}.{key}" schema={value} />
|
|
124
|
+
<Preference {userId} bind:preferences {defaultValue} path="{path}.{key}" schema={value} />
|
|
115
125
|
</div>
|
|
116
126
|
{/each}
|
|
117
|
-
{:else if
|
|
127
|
+
{:else if schema.type == 'tuple'}
|
|
118
128
|
<div class="pref-sub" data-rest={schema.def.rest}>
|
|
119
129
|
{#each schema.def.items as item, i}
|
|
120
|
-
<Preference {userId} bind:preferences path="{path}.{i}" schema={item} />
|
|
130
|
+
<Preference {userId} bind:preferences {defaultValue} path="{path}.{i}" schema={item} />
|
|
121
131
|
{/each}
|
|
122
132
|
</div>
|
|
123
|
-
{:else if
|
|
133
|
+
{:else if schema.type == 'enum'}
|
|
124
134
|
<select bind:this={input} {id} {onchange} required={!optional}>
|
|
125
135
|
{#each Object.entries(schema.enum) as [key, value]}
|
|
126
136
|
<option {value} selected={initialValue === value}>{key}</option>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"author": "James Prevett <jp@jamespre.dev>",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"build": "tsc"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@axium/core": ">=0.
|
|
43
|
+
"@axium/core": ">=0.16.0",
|
|
44
44
|
"utilium": "^2.3.8",
|
|
45
45
|
"zod": "^4.0.5",
|
|
46
46
|
"svelte": "^5.36.0"
|