@axium/client 0.14.5 → 0.15.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/assets/styles.css CHANGED
@@ -2,9 +2,6 @@
2
2
 
3
3
  * {
4
4
  box-sizing: border-box;
5
- color: hsl(0 0 var(--fg-light));
6
- accent-color: hsl(0 0 var(--fg-light));
7
- font-family: sans-serif;
8
5
  }
9
6
 
10
7
  body {
@@ -16,6 +13,11 @@ body {
16
13
  overflow-y: scroll;
17
14
  }
18
15
 
16
+ a {
17
+ text-decoration: none;
18
+ color: inherit;
19
+ }
20
+
19
21
  .main {
20
22
  padding: 2em;
21
23
  border-radius: 1em;
@@ -57,6 +59,13 @@ select {
57
59
  padding: 0.5em 1em;
58
60
  }
59
61
 
62
+ button.reset {
63
+ border-radius: unset;
64
+ border: none;
65
+ background-color: unset;
66
+ padding: unset;
67
+ }
68
+
60
69
  textarea {
61
70
  background: var(--bg-normal);
62
71
  border: 1px solid var(--border-accent);
@@ -219,19 +228,19 @@ input.error {
219
228
  display: flex;
220
229
  flex-direction: column;
221
230
  gap: 0.1em;
222
- }
223
231
 
224
- [popover] .menu-item {
225
- display: inline-flex;
226
- align-items: center;
227
- padding: 0.5em 0.75em;
228
- gap: 1em;
229
- border-radius: 0.5em;
230
- user-select: none;
232
+ .menu-item {
233
+ display: inline-flex;
234
+ align-items: center;
235
+ padding: 0.5em 0.75em;
236
+ gap: 1em;
237
+ border-radius: 0.5em;
238
+ user-select: none;
231
239
 
232
- &:hover {
233
- background-color: var(--bg-strong);
234
- cursor: pointer;
240
+ &:hover {
241
+ background-color: var(--bg-strong);
242
+ cursor: pointer;
243
+ }
235
244
  }
236
245
  }
237
246
 
@@ -11,11 +11,11 @@
11
11
  }
12
12
  </script>
13
13
 
14
- <div {onclick}>
14
+ <div class="Popover" {onclick} style:display="contents">
15
15
  {#if toggle}
16
16
  {@render toggle()}
17
17
  {:else}
18
- <span class={['popover-toggle', showToggle == 'hover' && 'toggle-hover']}>
18
+ <span class={[showToggle == 'hover' && 'toggle-hover']}>
19
19
  <Icon i="ellipsis" />
20
20
  </span>
21
21
  {/if}
@@ -26,12 +26,17 @@
26
26
  </div>
27
27
 
28
28
  <style>
29
- .popover-toggle:hover {
30
- cursor: pointer;
31
- }
29
+ div.Popover {
30
+ anchor-scope: --popover;
31
+
32
+ > :global(:first-child:hover) {
33
+ cursor: pointer;
34
+ }
32
35
 
33
- .popover-toggle {
34
- user-select: none;
36
+ > :global(:first-child) {
37
+ user-select: none;
38
+ anchor-name: --popover;
39
+ }
35
40
  }
36
41
 
37
42
  @media (width > 700px) {
@@ -44,7 +49,8 @@
44
49
  }
45
50
  }
46
51
 
47
- .popover-toggle + [popover] {
52
+ :popover-open {
53
+ position-anchor: --popover;
48
54
  position-try-fallbacks:
49
55
  flip-inline,
50
56
  flip-block,
@@ -1,66 +1,78 @@
1
1
  <script lang="ts">
2
- import type { User } from '@axium/core/user';
3
- import { getUserImage } from '@axium/core';
4
2
  import { fetchAPI } from '@axium/client/requests';
3
+ import { getUserImage } from '@axium/core';
4
+ import type { UserPublic } from '@axium/core/user';
5
5
  import Icon from './Icon.svelte';
6
- import Popover from './Popover.svelte';
7
6
  import Logout from './Logout.svelte';
7
+ import Popover from './Popover.svelte';
8
8
 
9
- const { user }: { user: Partial<User> } = $props();
9
+ const { user }: { user?: UserPublic } = $props();
10
10
  </script>
11
11
 
12
- <Popover>
13
- {#snippet toggle()}
14
- <div style:display="contents">
15
- <img src={getUserImage(user)} alt={user.name} />
16
- {user.name}
17
- </div>
18
- {/snippet}
19
-
20
- <a class="menu-item" href="/account">
21
- <Icon i="user" --size="1.5em" />
22
- <span>Your Account</span>
23
- </a>
12
+ {#if user}
13
+ <Popover>
14
+ {#snippet toggle()}
15
+ <div class="UserMenu toggle">
16
+ <img src={getUserImage(user)} alt={user.name} />
17
+ {user.name}
18
+ </div>
19
+ {/snippet}
24
20
 
25
- {#if user.isAdmin}
26
- <a class="menu-item" href="/admin">
27
- <Icon i="gear-complex" --size="1.5em" />
28
- <span>Administration</span>
21
+ <a class="menu-item" href="/account">
22
+ <Icon i="user" --size="1.5em" />
23
+ <span>Your Account</span>
29
24
  </a>
30
- {/if}
31
25
 
32
- {#await fetchAPI('GET', 'apps')}
33
- <i>Loading...</i>
34
- {:then apps}
35
- {#each apps as app}
36
- <a class="menu-item" href="/{app.id}">
37
- {#if app.image}
38
- <img src={app.image} alt={app.name} width="1em" height="1em" />
39
- {:else if app.icon}
40
- <Icon i={app.icon} --size="1.5em" />
41
- {:else}
42
- <Icon i="image-circle-xmark" --size="1.5em" />
43
- {/if}
44
- <span>{app.name}</span>
26
+ {#if user.isAdmin}
27
+ <a class="menu-item" href="/admin">
28
+ <Icon i="gear-complex" --size="1.5em" />
29
+ <span>Administration</span>
45
30
  </a>
46
- {:else}
47
- <i>No apps available.</i>
48
- {/each}
49
- {:catch}
50
- <i>Couldn't load apps.</i>
51
- {/await}
31
+ {/if}
52
32
 
53
- <button style:display="contents" command="show-modal" commandfor="logout">
54
- <span class="menu-item logout">
33
+ {#await fetchAPI('GET', 'apps')}
34
+ <i>Loading...</i>
35
+ {:then apps}
36
+ {#each apps as app}
37
+ <a class="menu-item" href="/{app.id}">
38
+ {#if app.image}
39
+ <img src={app.image} alt={app.name} width="1em" height="1em" />
40
+ {:else if app.icon}
41
+ <Icon i={app.icon} --size="1.5em" />
42
+ {:else}
43
+ <Icon i="image-circle-xmark" --size="1.5em" />
44
+ {/if}
45
+ <span>{app.name}</span>
46
+ </a>
47
+ {:else}
48
+ <i>No apps available.</i>
49
+ {/each}
50
+ {:catch}
51
+ <i>Couldn't load apps.</i>
52
+ {/await}
53
+
54
+ <button class="menu-item logout reset" command="show-modal" commandfor="logout">
55
55
  <Icon i="right-from-bracket" --size="1.5em" --fill="hsl(0 33 var(--fg-light))" />
56
56
  <span>Logout</span>
57
- </span>
58
- </button>
59
- </Popover>
57
+ </button>
58
+ </Popover>
60
59
 
61
- <Logout />
60
+ <Logout />
61
+ {:else}
62
+ <div class="UserMenu login">
63
+ <a href="/login?after={location.pathname}">Login</a>
64
+ </div>
65
+ {/if}
62
66
 
63
67
  <style>
68
+ .UserMenu {
69
+ border-radius: 0.5em;
70
+ padding: 0.5em;
71
+ border: 1px solid var(--border-accent);
72
+ cursor: pointer;
73
+ background-color: var(--bg-alt);
74
+ }
75
+
64
76
  img {
65
77
  width: 2em;
66
78
  height: 2em;
@@ -69,7 +81,18 @@
69
81
  margin-right: 0.5em;
70
82
  }
71
83
 
72
- span.logout > span {
84
+ .logout {
73
85
  color: hsl(0 33 var(--fg-light));
86
+ font-size: 16px;
87
+ }
88
+
89
+ :global(.UserMenu + div:popover-open) {
90
+ position: fixed;
91
+ left: unset;
92
+ right: anchor(right);
93
+ top: calc(anchor(bottom) + 0.5em);
94
+ width: fit-content;
95
+ height: fit-content;
96
+ cursor: default;
74
97
  }
75
98
  </style>
package/lib/index.ts CHANGED
@@ -14,6 +14,7 @@ export { default as Toast } from './Toast.svelte';
14
14
  export { default as Upload } from './Upload.svelte';
15
15
  export { default as URLText } from './URLText.svelte';
16
16
  export { default as UserCard } from './UserCard.svelte';
17
+ export { default as UserDiscovery } from './UserDiscovery.svelte';
17
18
  export { default as UserMenu } from './UserMenu.svelte';
18
19
  export { default as Version } from './Version.svelte';
19
20
  export { default as ZodForm } from './ZodForm.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axium/client",
3
- "version": "0.14.5",
3
+ "version": "0.15.0",
4
4
  "author": "James Prevett <jp@jamespre.dev>",
5
5
  "funding": {
6
6
  "type": "individual",