@axium/client 0.25.2 → 0.26.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/assets/styles.css CHANGED
@@ -217,6 +217,9 @@ div.success {
217
217
  :disabled,
218
218
  .disabled {
219
219
  cursor: not-allowed;
220
+ color: var(--fg-disabled);
221
+ accent-color: var(--fg-disabled);
222
+ border: var(--border-disabled);
220
223
  }
221
224
 
222
225
  :popover-open {
package/assets/theme.css CHANGED
@@ -43,11 +43,14 @@ html {
43
43
  --fg-normal: hsl(0 0 var(--fg-light));
44
44
  --fg-accent: hsl(var(--hue) 15 var(--fg-light));
45
45
  --fg-strong: hsl(var(--hue) 25 calc(var(--fg-light) - var(--light-step)));
46
+ --fg-disabled: hsl(0 0 calc(var(--fg-light) - var(--light-step)));
46
47
 
47
48
  --fg-error: hsl(0 50 calc(var(--fg-light) - var(--light-step)));
48
49
  --fg-warning: hsl(60 50 calc(var(--fg-light) - var(--light-step)));
49
50
 
51
+ --border-disabled: 1px solid hsl(0 5 calc(var(--bg-light) - var(--light-step)));
50
52
  --border-accent: 1px solid hsl(var(--hue) 10 calc(var(--bg-light) + (var(--light-step) * 3)));
53
+ --border-strong: 1px solid hsl(var(--hue) 20 calc(var(--bg-light) + (var(--light-step) * 3)));
51
54
 
52
55
  --border-error: 1px solid hsl(0 50 var(--fg-light));
53
56
  --border-warning: 1px solid hsl(60 50 var(--fg-light));
package/dist/apps.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { AppPreferences } from '@axium/core';
2
+ export declare function getAppPreferences<A extends string>(userId: string, appId: A): Promise<AppPreferences<A>>;
3
+ export declare function setAppPreferences<A extends string>(userId: string, appId: A, preferences: AppPreferences<A>): Promise<AppPreferences<A>>;
4
+ export declare function clearAppPreferences<A extends string>(userId: string, appId: A): Promise<AppPreferences<A>>;
5
+ export declare function appPref<A extends string, K extends keyof AppPreferences<A>>(userId: string, appId: A, key: K): Promise<AppPreferences<A>[K]>;
package/dist/apps.js ADDED
@@ -0,0 +1,31 @@
1
+ import { appPreferences } from '@axium/core';
2
+ import { fetchAPI } from './requests.js';
3
+ import { useCache } from './cache.js';
4
+ export async function getAppPreferences(userId, appId) {
5
+ const schema = appPreferences.get(appId);
6
+ if (!schema)
7
+ throw new Error(`Missing schema for "${appId}"`);
8
+ const pref = await useCache('app_preferences', userId + ':' + appId, async () => {
9
+ const result = await fetchAPI('GET', 'users/:id/preferences/:appId', {}, userId, appId);
10
+ return schema.parse(result);
11
+ });
12
+ return pref;
13
+ }
14
+ export async function setAppPreferences(userId, appId, preferences) {
15
+ const schema = appPreferences.get(appId);
16
+ if (!schema)
17
+ throw new Error(`Missing schema for "${appId}"`);
18
+ const result = await fetchAPI('POST', 'users/:id/preferences/:appId', preferences, userId, appId);
19
+ return schema.parse(result);
20
+ }
21
+ export async function clearAppPreferences(userId, appId) {
22
+ const schema = appPreferences.get(appId);
23
+ if (!schema)
24
+ throw new Error(`Missing schema for "${appId}"`);
25
+ const result = await fetchAPI('DELETE', 'users/:id/preferences/:appId', {}, userId, appId);
26
+ return schema.parse(result);
27
+ }
28
+ export async function appPref(userId, appId, key) {
29
+ const pref = await getAppPreferences(userId, appId);
30
+ return pref[key];
31
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './access.js';
2
+ export * from './apps.js';
2
3
  export * from './cache.js';
3
4
  export * from './config.js';
4
5
  export * from './locales.js';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './access.js';
2
+ export * from './apps.js';
2
3
  export * from './cache.js';
3
4
  export * from './config.js';
4
5
  export * from './locales.js';
package/dist/locales.d.ts CHANGED
@@ -30,6 +30,10 @@ declare let currentLoaded: {
30
30
  readonly back: "Take me back";
31
31
  readonly question: "Are you sure you want to log out?";
32
32
  };
33
+ readonly AppPreferences: {
34
+ readonly title: "Preferences for {name}";
35
+ readonly save: "Save";
36
+ };
33
37
  readonly Register: {
34
38
  readonly email: "Email";
35
39
  readonly login: "Login instead";
@@ -0,0 +1,38 @@
1
+ <script lang="ts">
2
+ import { getAppPreferences, setAppPreferences, text } from '@axium/client';
3
+ import { structurallyEqual } from 'utilium';
4
+ import type { ZodObject } from 'zod';
5
+ import ZodInput from './ZodInput.svelte';
6
+
7
+ const { userId, appId, schema }: { userId: string; appId: string; schema: ZodObject } = $props();
8
+
9
+ let initialValue = $state(await getAppPreferences(userId, appId));
10
+ let currentValue = $state({ ...initialValue });
11
+
12
+ function cancel() {
13
+ currentValue = { ...initialValue };
14
+ }
15
+
16
+ async function save() {
17
+ initialValue = await setAppPreferences(userId, appId, currentValue);
18
+ }
19
+ </script>
20
+
21
+ <h2>{text('AppPreferences.title', { name: text(`app_name.${appId}`) })}</h2>
22
+
23
+ <ZodInput {schema} updateValue={() => {}} bind:rootValue={currentValue} path="" />
24
+
25
+ <div class="actions">
26
+ <button onclick={cancel}>{text('generic.cancel')}</button>
27
+ <button onclick={save} class={!structurallyEqual(initialValue, currentValue) && 'save-pending'}>{text('AppPreferences.save')}</button>
28
+ </div>
29
+
30
+ <style>
31
+ .actions {
32
+ margin-top: 2em;
33
+ }
34
+
35
+ .save-pending {
36
+ border: var(--border-strong);
37
+ }
38
+ </style>
@@ -43,6 +43,13 @@
43
43
 
44
44
  let value = $state<any>(getByString(rootValue, path));
45
45
 
46
+ let lastRoot = rootValue;
47
+ $effect(() => {
48
+ if (rootValue === lastRoot) return;
49
+ lastRoot = rootValue;
50
+ value = getByString(rootValue, path);
51
+ });
52
+
46
53
  let error = $state();
47
54
 
48
55
  function dateAttr(date: Date | null, format: 'date' | 'time' | 'datetime' | 'time+sec') {
@@ -156,7 +163,7 @@
156
163
  {:else if schema.type == 'literal'}
157
164
  <div class="ZodInput">
158
165
  <label for={id}>{labelText}</label>
159
- <select bind:value {id} {oninput} required={!optional}>
166
+ <select bind:value {id} {onchange} required={!optional}>
160
167
  {#each schema.values as literal}
161
168
  <option value={literal} selected={value === literal}>{subText(String(literal), { $default: String(literal) })}</option>
162
169
  {/each}
package/lib/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { default as AccessControlDialog } from './AccessControlDialog.svelte';
2
2
  export { default as AppMenu } from './AppMenu.svelte';
3
+ export { default as AppPreferences } from './AppPreferences.svelte';
3
4
  export { default as Audio } from './Audio.svelte';
4
5
  export { default as ColorPicker } from './ColorPicker.svelte';
5
6
  export { default as ClipboardCopy } from './ClipboardCopy.svelte';
package/locales/en.json CHANGED
@@ -24,6 +24,10 @@
24
24
  "back": "Take me back",
25
25
  "question": "Are you sure you want to log out?"
26
26
  },
27
+ "AppPreferences": {
28
+ "title": "Preferences for {name}",
29
+ "save": "Save"
30
+ },
27
31
  "Register": {
28
32
  "email": "Email",
29
33
  "login": "Login instead",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/client",
3
- "version": "0.25.2",
3
+ "version": "0.26.1",
4
4
  "author": "James Prevett <jp@jamespre.dev>",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -45,11 +45,11 @@
45
45
  "build": "tsc"
46
46
  },
47
47
  "peerDependencies": {
48
- "@axium/core": ">=0.29.0",
48
+ "@axium/core": ">=0.30.0",
49
49
  "ioium": "^1.0.2",
50
50
  "semver": "^7.7.4",
51
51
  "svelte": "^5.36.0",
52
- "utilium": "^3.0.0",
52
+ "utilium": "^3.2.0",
53
53
  "zod": "^4.0.5"
54
54
  },
55
55
  "dependencies": {