@axium/client 0.21.0 → 0.22.1
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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/locales.d.ts +11 -0
- package/dist/locales.js +13 -1
- package/lib/LocationSelect.svelte +20 -0
- package/lib/UserPFP.svelte +1 -0
- package/lib/ZodForm.svelte +2 -2
- package/lib/ZodInput.svelte +53 -13
- package/lib/index.ts +1 -0
- package/locales/en.json +8 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/locales.d.ts
CHANGED
|
@@ -235,10 +235,19 @@ declare let currentLoaded: {
|
|
|
235
235
|
readonly failed: "Login Failed";
|
|
236
236
|
};
|
|
237
237
|
};
|
|
238
|
+
readonly location: {
|
|
239
|
+
readonly country: "Country";
|
|
240
|
+
readonly subdivision: "State / province";
|
|
241
|
+
readonly locality: "City / town";
|
|
242
|
+
readonly postal_code: "Postal code";
|
|
243
|
+
readonly street1: "Street address";
|
|
244
|
+
readonly street2: "Street address line 2";
|
|
245
|
+
};
|
|
238
246
|
readonly preference: {
|
|
239
247
|
readonly debug: "Debug mode";
|
|
240
248
|
};
|
|
241
249
|
};
|
|
250
|
+
export declare let currentMonthNames: string[];
|
|
242
251
|
/**
|
|
243
252
|
* Current locale
|
|
244
253
|
*/
|
|
@@ -259,6 +268,8 @@ type _ArgsValue<V extends string[]> = UnionToIntersection<{
|
|
|
259
268
|
type Replacements<K extends string> = ReplacementOptions & (GetByString<Locale, K> extends string ? _ArgsValue<Split<GetByString<Locale, K> & string, '{'>> : Record<string, any>);
|
|
260
269
|
type ReplacementsArgs<K extends string> = {} extends Replacements<K> ? [replacements?: Replacements<K>] : [replacements: Replacements<K>];
|
|
261
270
|
export declare function useLocale(newLocale: string): void;
|
|
271
|
+
export declare function countryName(code: string): string | undefined;
|
|
272
|
+
export declare function dateField(name: string): string | undefined;
|
|
262
273
|
export declare function escape(text: string): string;
|
|
263
274
|
/**
|
|
264
275
|
* Get localized text for a given translation key
|
package/dist/locales.js
CHANGED
|
@@ -15,7 +15,8 @@ export function extendLocale(locale, data) {
|
|
|
15
15
|
debug('Extending locale: ' + locale);
|
|
16
16
|
deepAssign(loadedLocales[locale], data);
|
|
17
17
|
}
|
|
18
|
-
let currentLoaded = en;
|
|
18
|
+
let currentLoaded = en, currentRegionNames, currentDateFields;
|
|
19
|
+
export let currentMonthNames;
|
|
19
20
|
/**
|
|
20
21
|
* Current locale
|
|
21
22
|
*/
|
|
@@ -25,6 +26,17 @@ export function useLocale(newLocale) {
|
|
|
25
26
|
throw new Error('Locale is not available: ' + newLocale);
|
|
26
27
|
currentLocale = newLocale;
|
|
27
28
|
currentLoaded = loadedLocales[newLocale];
|
|
29
|
+
currentRegionNames = new Intl.DisplayNames(newLocale, { type: 'region' });
|
|
30
|
+
currentDateFields = new Intl.DisplayNames(newLocale, { type: 'dateTimeField' });
|
|
31
|
+
const formatter = new Intl.DateTimeFormat(newLocale, { month: 'long' });
|
|
32
|
+
currentMonthNames = Array.from({ length: 12 }, (_, monthIndex) => formatter.format(new Date(Date.UTC(2000, monthIndex + 1, 1))));
|
|
33
|
+
}
|
|
34
|
+
useLocale('en');
|
|
35
|
+
export function countryName(code) {
|
|
36
|
+
return currentRegionNames.of(code);
|
|
37
|
+
}
|
|
38
|
+
export function dateField(name) {
|
|
39
|
+
return currentDateFields.of(name);
|
|
28
40
|
}
|
|
29
41
|
const localeReplacement = /\{(\w+)\}/g;
|
|
30
42
|
const escapePattern = /[&<>"']/g;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { countryName, text } from '@axium/client';
|
|
3
|
+
import { countries, type LocationInit } from '@axium/core';
|
|
4
|
+
|
|
5
|
+
let { value = $bindable<LocationInit>() }: { value: LocationInit } = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<select bind:value={value.country} placeholder={text('location.country')}>
|
|
9
|
+
{#each countries as country}
|
|
10
|
+
<option value={country}>{countryName(country)}</option>
|
|
11
|
+
{/each}
|
|
12
|
+
</select>
|
|
13
|
+
|
|
14
|
+
<input type="text" placeholder={text('location.street1')} bind:value={value.street1} />
|
|
15
|
+
<input type="text" placeholder={text('location.street2')} bind:value={value.street2} />
|
|
16
|
+
<input type="text" placeholder={text('location.locality')} bind:value={value.locality} />
|
|
17
|
+
<div>
|
|
18
|
+
<input type="text" placeholder={text('location.subdivision')} bind:value={value.subdivision} />
|
|
19
|
+
<input type="text" placeholder={text('location.postal_code')} bind:value={value.postalCode} />
|
|
20
|
+
</div>
|
package/lib/UserPFP.svelte
CHANGED
package/lib/ZodForm.svelte
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
interface Props {
|
|
6
6
|
rootValue: any;
|
|
7
7
|
schema: ZodObject;
|
|
8
|
-
labels
|
|
8
|
+
labels?: Record<string, string>;
|
|
9
9
|
updateValue(value: any): void;
|
|
10
10
|
idPrefix?: string;
|
|
11
11
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
<div class="ZodForm">
|
|
17
17
|
{#each Object.keys(schema.shape).sort((a, b) => a.localeCompare(b)) as path}
|
|
18
|
-
<ZodInput bind:rootValue {updateValue} {idPrefix} {path} schema={schema.shape[path]} label={labels[path] || path} />
|
|
18
|
+
<ZodInput bind:rootValue {updateValue} {idPrefix} {path} schema={schema.shape[path]} label={labels?.[path] || path} />
|
|
19
19
|
{/each}
|
|
20
20
|
</div>
|
|
21
21
|
|
package/lib/ZodInput.svelte
CHANGED
|
@@ -14,15 +14,17 @@
|
|
|
14
14
|
path: string;
|
|
15
15
|
label?: string;
|
|
16
16
|
schema: ZodPref;
|
|
17
|
+
_parseSchema?: ZodPref;
|
|
17
18
|
defaultValue?: any;
|
|
18
19
|
optional?: boolean;
|
|
19
|
-
|
|
20
|
+
readonly?: boolean;
|
|
21
|
+
noLabel?: boolean | 'placeholder';
|
|
20
22
|
updateValue(value: any): void;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
let { rootValue = $bindable(), ...props }: Props = $props();
|
|
24
26
|
|
|
25
|
-
let { label, path, schema, optional, defaultValue, idPrefix, updateValue, noLabel } = props;
|
|
27
|
+
let { label, path, schema, _parseSchema = schema, optional, readonly, defaultValue, idPrefix, updateValue, noLabel } = props;
|
|
26
28
|
|
|
27
29
|
const id = (idPrefix ? idPrefix + ':' : '') + path.replaceAll(' ', '_');
|
|
28
30
|
|
|
@@ -85,13 +87,28 @@
|
|
|
85
87
|
const oninput = onchange;
|
|
86
88
|
|
|
87
89
|
const labelText = $derived(zKeys.has(props.schema) ? text(zKeys.get(props.schema)!.key) : label || path);
|
|
90
|
+
const placeholder = noLabel == 'placeholder' ? labelText : undefined;
|
|
91
|
+
|
|
92
|
+
/** Array element types that indicate the array should put elements on their own lines */
|
|
93
|
+
const largeArrayTypes = ['object', 'array', 'record', 'tuple'];
|
|
88
94
|
</script>
|
|
89
95
|
|
|
90
96
|
{#snippet _in(rest: HTMLInputAttributes)}
|
|
91
97
|
<div class="ZodInput">
|
|
92
98
|
{#if !noLabel}<label for={id}>{labelText}</label>{/if}
|
|
93
99
|
{#if error}<span class="ZodInput-error">{error}</span>{/if}
|
|
94
|
-
<input
|
|
100
|
+
<input
|
|
101
|
+
{id}
|
|
102
|
+
{...rest}
|
|
103
|
+
bind:value
|
|
104
|
+
{onchange}
|
|
105
|
+
{oninput}
|
|
106
|
+
required={!optional}
|
|
107
|
+
{defaultValue}
|
|
108
|
+
{placeholder}
|
|
109
|
+
{readonly}
|
|
110
|
+
class={[error && 'error']}
|
|
111
|
+
/>
|
|
95
112
|
</div>
|
|
96
113
|
{/snippet}
|
|
97
114
|
|
|
@@ -104,7 +121,7 @@
|
|
|
104
121
|
{:else if schema.type == 'boolean'}
|
|
105
122
|
<div class="ZodInput">
|
|
106
123
|
{#if !noLabel}<label for="{id}:checkbox">{labelText}</label>{/if}
|
|
107
|
-
<input bind:checked={value} id="{id}:checkbox" type="checkbox" {onchange} required={!optional} />
|
|
124
|
+
<input bind:checked={value} id="{id}:checkbox" type="checkbox" {onchange} required={!optional} {placeholder} />
|
|
108
125
|
<label for="{id}:checkbox" {id} class="checkbox">
|
|
109
126
|
{#if value}<Icon i="check" --size="1.3em" />{/if}
|
|
110
127
|
</label>
|
|
@@ -128,19 +145,22 @@
|
|
|
128
145
|
</div>
|
|
129
146
|
{:else if schema.type == 'template_literal'}
|
|
130
147
|
<!-- todo -->
|
|
148
|
+
{:else if schema.type == 'readonly'}
|
|
149
|
+
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.innerType} readonly />
|
|
131
150
|
{:else if schema.type == 'default'}
|
|
132
151
|
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.innerType} defaultValue={schema.def.defaultValue} />
|
|
133
152
|
{:else if schema.type == 'nullable' || schema.type == 'optional'}
|
|
134
153
|
<!-- defaults are handled differently -->
|
|
135
154
|
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.innerType} optional={true} />
|
|
155
|
+
{:else if schema.type == 'nonoptional'}
|
|
156
|
+
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.innerType} optional={false} />
|
|
136
157
|
{:else if schema.type == 'array'}
|
|
137
158
|
<div class="ZodInput">
|
|
138
159
|
{#if !noLabel}<label for={id}>{labelText}</label>{/if}
|
|
139
|
-
|
|
140
|
-
<div class="ZodInput-array">
|
|
160
|
+
<div class={['ZodInput-array', largeArrayTypes.includes(schema.element.type) && 'large']}>
|
|
141
161
|
{#each value, i}
|
|
142
162
|
<div class="ZodInput-element">
|
|
143
|
-
<
|
|
163
|
+
<ZodInput bind:rootValue {updateValue} {idPrefix} path="{path}.{i}" schema={schema.element} noLabel={noLabel || true} />
|
|
144
164
|
<button
|
|
145
165
|
onclick={e => {
|
|
146
166
|
value.splice(i, 1);
|
|
@@ -151,8 +171,11 @@
|
|
|
151
171
|
</button>
|
|
152
172
|
</div>
|
|
153
173
|
{/each}
|
|
154
|
-
<button onclick={() => value.push('')}>
|
|
174
|
+
<button class="icon-text" onclick={() => value.push('')}>
|
|
155
175
|
<Icon i="plus" --size="16px" />
|
|
176
|
+
{#if noLabel == 'placeholder'}
|
|
177
|
+
<span>{labelText}</span>
|
|
178
|
+
{/if}
|
|
156
179
|
</button>
|
|
157
180
|
</div>
|
|
158
181
|
</div>
|
|
@@ -161,14 +184,14 @@
|
|
|
161
184
|
{#each Object.keys(value) as key}
|
|
162
185
|
<div class="ZodInput-record-entry">
|
|
163
186
|
{#if !noLabel}<label for={id}>{key}</label>{/if}
|
|
164
|
-
<ZodInput bind:rootValue {updateValue} {idPrefix} path="{path}.{key}" schema={schema.valueType} />
|
|
187
|
+
<ZodInput bind:rootValue {updateValue} {idPrefix} {noLabel} path="{path}.{key}" schema={schema.valueType} />
|
|
165
188
|
</div>
|
|
166
189
|
{/each}
|
|
167
190
|
</div>
|
|
168
191
|
{:else if schema.type == 'object'}
|
|
169
192
|
<!-- <div class="ZodInput-object"> -->
|
|
170
193
|
{#each Object.entries(schema.shape) as [key, value]}
|
|
171
|
-
<ZodInput bind:rootValue {updateValue} {idPrefix} path="{path}.{key}" schema={value} />
|
|
194
|
+
<ZodInput bind:rootValue {updateValue} {idPrefix} {noLabel} path="{path}.{key}" schema={value} />
|
|
172
195
|
{/each}
|
|
173
196
|
<!-- </div> -->
|
|
174
197
|
{:else if schema.type == 'tuple'}
|
|
@@ -187,6 +210,14 @@
|
|
|
187
210
|
{/each}
|
|
188
211
|
</select>
|
|
189
212
|
</div>
|
|
213
|
+
{:else if schema.type == 'success'}
|
|
214
|
+
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.innerType} {_parseSchema} />
|
|
215
|
+
{:else if schema.type == 'pipe'}
|
|
216
|
+
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.in} {_parseSchema} />
|
|
217
|
+
{:else if schema.type == 'union'}
|
|
218
|
+
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.options[0]} {_parseSchema} />
|
|
219
|
+
{:else if schema.type == 'intersection'}
|
|
220
|
+
<ZodInput bind:rootValue {...props} label={labelText} schema={schema.def.left} {_parseSchema} />
|
|
190
221
|
{:else}
|
|
191
222
|
<!-- No idea how to render this -->
|
|
192
223
|
<i class="error">{text('ZodInput.invalid_type', { type: JSON.stringify((schema as ZodPref)?.def?.type) })}</i>
|
|
@@ -217,9 +248,14 @@
|
|
|
217
248
|
gap: 0.5em;
|
|
218
249
|
align-items: center;
|
|
219
250
|
|
|
220
|
-
button {
|
|
221
|
-
|
|
222
|
-
|
|
251
|
+
& > button {
|
|
252
|
+
display: contents;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
& > .ZodInput {
|
|
256
|
+
gap: 0.25em;
|
|
257
|
+
display: flex;
|
|
258
|
+
flex-direction: column;
|
|
223
259
|
}
|
|
224
260
|
}
|
|
225
261
|
|
|
@@ -227,6 +263,10 @@
|
|
|
227
263
|
display: flex;
|
|
228
264
|
gap: 0.5em;
|
|
229
265
|
align-items: center;
|
|
266
|
+
|
|
267
|
+
&.large {
|
|
268
|
+
flex-direction: column;
|
|
269
|
+
}
|
|
230
270
|
}
|
|
231
271
|
|
|
232
272
|
.ZodInput-object,
|
package/lib/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { default as ColorPicker } from './ColorPicker.svelte';
|
|
|
4
4
|
export { default as ClipboardCopy } from './ClipboardCopy.svelte';
|
|
5
5
|
export { default as FormDialog } from './FormDialog.svelte';
|
|
6
6
|
export { default as Icon } from './Icon.svelte';
|
|
7
|
+
export { default as LocationSelect } from './LocationSelect.svelte';
|
|
7
8
|
export { default as Login } from './Login.svelte';
|
|
8
9
|
export { default as Logout } from './Logout.svelte';
|
|
9
10
|
export { default as NumberBar } from './NumberBar.svelte';
|
package/locales/en.json
CHANGED
|
@@ -229,6 +229,14 @@
|
|
|
229
229
|
"failed": "Login Failed"
|
|
230
230
|
}
|
|
231
231
|
},
|
|
232
|
+
"location": {
|
|
233
|
+
"country": "Country",
|
|
234
|
+
"subdivision": "State / province",
|
|
235
|
+
"locality": "City / town",
|
|
236
|
+
"postal_code": "Postal code",
|
|
237
|
+
"street1": "Street address",
|
|
238
|
+
"street2": "Street address line 2"
|
|
239
|
+
},
|
|
232
240
|
"preference": {
|
|
233
241
|
"debug": "Debug mode"
|
|
234
242
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"author": "James Prevett <jp@jamespre.dev>",
|
|
5
5
|
"funding": {
|
|
6
6
|
"type": "individual",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"build": "tsc"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@axium/core": ">=0.
|
|
48
|
+
"@axium/core": ">=0.26.0",
|
|
49
49
|
"svelte": "^5.36.0",
|
|
50
50
|
"utilium": "^2.8.0",
|
|
51
51
|
"zod": "^4.0.5"
|