@happyvertical/smrt-users 0.34.5 → 0.34.7

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "timestamp": 1782261300893,
3
+ "timestamp": 1782290145802,
4
4
  "packageName": "@happyvertical/smrt-users",
5
- "packageVersion": "0.34.5",
5
+ "packageVersion": "0.34.7",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-users:UsersCliAuthRequestCollection": {
8
8
  "name": "userscliauthrequestcollection",
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-06-24T00:35:01.978Z",
3
+ "generatedAt": "2026-06-24T08:35:46.471Z",
4
4
  "packageName": "@happyvertical/smrt-users",
5
- "packageVersion": "0.34.5",
5
+ "packageVersion": "0.34.7",
6
6
  "sourceManifestPath": "dist/manifest.json",
7
7
  "agentDocPath": "AGENTS.md",
8
8
  "sourceHashes": {
9
- "manifest": "78c77572889f7baa73c696240c9b7958f6f718d6fb0c63528e6f3acda6066820",
10
- "packageJson": "8725ed59c9abcd0c00ea3b58eef21733664cb800a83e2dc69d3fd3da832f9223",
9
+ "manifest": "e3a0eaccd7320f651393d447e8094beaed5ee2844969d1ab93eecbbab0c7352b",
10
+ "packageJson": "d734740f8ce3ffa6bc1904b5f362286fdf16b5a62638c3cd1fbf7e0749413fe2",
11
11
  "agents": "2684404a1735fd4993d4383f2dfed5f9c0f4de68f0cbfcd996f7e94eb50ac9c8"
12
12
  },
13
13
  "exports": [
@@ -1,7 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { RoleSelector } from '@happyvertical/smrt-ui';
3
3
  import { Modal } from '@happyvertical/smrt-ui/feedback';
4
+ import { Form, Input } from '@happyvertical/smrt-ui/forms';
4
5
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
6
+ import { Button } from '@happyvertical/smrt-ui/ui';
5
7
  import type { Role, Tenant } from '@happyvertical/smrt-users';
6
8
  import { M } from '../i18n.js';
7
9
 
@@ -44,8 +46,7 @@ $effect(() => {
44
46
  }
45
47
  });
46
48
 
47
- function handleSubmit(e: Event) {
48
- e.preventDefault();
49
+ function handleSubmit() {
49
50
  error = '';
50
51
 
51
52
  if (!email) {
@@ -84,57 +85,60 @@ function handleClose() {
84
85
  closeOnBackdrop={!loading}
85
86
  closeOnEscape={!loading}
86
87
  >
87
- <form id={formId} onsubmit={handleSubmit}>
88
- {#if error}
89
- <div class="error">{error}</div>
90
- {/if}
91
-
92
- <div class="field">
93
- <label for="invite-email">{t(M['users.invite_user_modal.email_address'])}</label>
94
- <input
95
- id="invite-email"
96
- type="email"
97
- bind:value={email}
98
- placeholder={t(M['users.invite_user_modal.email_placeholder'])}
99
- disabled={loading}
100
- required
101
- />
102
- </div>
103
-
104
- <div class="field">
105
- <label for="invite-role">Role</label>
106
- <RoleSelector
107
- {roles}
108
- value={roleId}
109
- onchange={(id: string) => (roleId = id)}
110
- disabled={loading}
111
- showDescription
112
- />
113
- </div>
114
-
115
- <div class="checkbox-field">
116
- <input id="send-email" type="checkbox" bind:checked={sendEmail} disabled={loading} />
117
- <label for="send-email">{t(M['users.invite_user_modal.send_invitation_email'])}</label>
118
- </div>
119
-
120
- {#if !sendEmail}
121
- <div class="hint">
122
- {t(M['users.invite_user_modal.pending_hint'])}
88
+ <div class="invite-form-shell">
89
+ <Form id={formId} class="invite-form" onsubmit={handleSubmit}>
90
+ {#if error}
91
+ <div class="error">{error}</div>
92
+ {/if}
93
+
94
+ <div class="field">
95
+ <label for="invite-email">{t(M['users.invite_user_modal.email_address'])}</label>
96
+ <Input
97
+ id="invite-email"
98
+ type="email"
99
+ bind:value={email}
100
+ placeholder={t(M['users.invite_user_modal.email_placeholder'])}
101
+ disabled={loading}
102
+ required
103
+ />
123
104
  </div>
124
- {/if}
125
- </form>
105
+
106
+ <div class="field">
107
+ <label for="invite-role">Role</label>
108
+ <RoleSelector
109
+ {roles}
110
+ value={roleId}
111
+ onchange={(id: string) => (roleId = id)}
112
+ disabled={loading}
113
+ showDescription
114
+ />
115
+ </div>
116
+
117
+ <div class="checkbox-field">
118
+ <!-- raw-primitive-allow: native checkbox; no Provider-free checkbox primitive (Toggle is a switch with different semantics, CheckboxInput requires a Provider) -->
119
+ <input id="send-email" type="checkbox" bind:checked={sendEmail} disabled={loading} />
120
+ <label for="send-email">{t(M['users.invite_user_modal.send_invitation_email'])}</label>
121
+ </div>
122
+
123
+ {#if !sendEmail}
124
+ <div class="hint">
125
+ {t(M['users.invite_user_modal.pending_hint'])}
126
+ </div>
127
+ {/if}
128
+ </Form>
129
+ </div>
126
130
 
127
131
  {#snippet footer()}
128
- <button type="button" class="btn-secondary" onclick={handleClose} disabled={loading}>
132
+ <Button variant="secondary" type="button" onclick={handleClose} disabled={loading}>
129
133
  Cancel
130
- </button>
131
- <button type="submit" form={formId} class="btn-primary" disabled={loading}>
134
+ </Button>
135
+ <Button variant="primary" type="submit" form={formId} disabled={loading}>
132
136
  {#if loading}
133
137
  {t(M['users.invite_user_modal.sending'])}
134
138
  {:else}
135
139
  {t(M['users.invite_user_modal.send_invite'])}
136
140
  {/if}
137
- </button>
141
+ </Button>
138
142
  {/snippet}
139
143
  </Modal>
140
144
 
@@ -142,7 +146,7 @@ function handleClose() {
142
146
  /* The dialog chrome (backdrop, surface, header, footer bar, close button) is
143
147
  supplied by the smrt-ui Modal. Only the form-content + footer-button styles
144
148
  live here. */
145
- form {
149
+ .invite-form-shell :global(.invite-form) {
146
150
  display: flex;
147
151
  flex-direction: column;
148
152
  gap: var(--smrt-spacing-md, 1rem);
@@ -168,25 +172,6 @@ function handleClose() {
168
172
  color: var(--smrt-color-on-surface-variant, #43474e);
169
173
  }
170
174
 
171
- input[type='email'] {
172
- padding: var(--smrt-spacing-sm, 0.5rem) var(--smrt-spacing-md, 0.75rem);
173
- border: 1px solid var(--smrt-color-outline-variant, #c4c6cf);
174
- border-radius: var(--smrt-radius-medium, 0.5rem);
175
- font: var(--smrt-typography-body-medium-font, 0.875rem / 1.25 sans-serif);
176
- transition: border-color var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
177
- }
178
-
179
- input[type='email']:focus {
180
- outline: none;
181
- border-color: var(--smrt-color-primary, #005ac1);
182
- box-shadow: 0 0 0 3px var(--smrt-color-primary-container, rgba(0, 90, 193, 0.1));
183
- }
184
-
185
- input[type='email']:disabled {
186
- background: var(--smrt-color-surface-container, #f3f4f6);
187
- cursor: not-allowed;
188
- }
189
-
190
175
  .checkbox-field {
191
176
  display: flex;
192
177
  align-items: center;
@@ -210,45 +195,4 @@ function handleClose() {
210
195
  background: var(--smrt-color-surface-container-low, #f9fafb);
211
196
  border-radius: var(--smrt-radius-small, 0.25rem);
212
197
  }
213
-
214
- button {
215
- padding: var(--smrt-spacing-sm, 0.5rem) var(--smrt-spacing-md, 1rem);
216
- border-radius: var(--smrt-radius-medium, 0.5rem);
217
- font: var(--smrt-typography-label-large-font, 500 0.875rem / 1.25 sans-serif);
218
- cursor: pointer;
219
- transition: all var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
220
- }
221
-
222
- button:disabled {
223
- opacity: 0.6;
224
- cursor: not-allowed;
225
- }
226
-
227
- .btn-primary {
228
- background: var(--smrt-color-primary, #005ac1);
229
- color: var(--smrt-color-on-primary, #ffffff);
230
- border: none;
231
- }
232
-
233
- .btn-primary:hover:not(:disabled) {
234
- background: var(--smrt-color-primary-container, #005ac1);
235
- opacity: 0.9;
236
- }
237
-
238
- .btn-secondary {
239
- background: var(--smrt-color-surface, white);
240
- color: var(--smrt-color-on-surface-variant, #43474e);
241
- border: 1px solid var(--smrt-color-outline-variant, #c4c6cf);
242
- }
243
-
244
- .btn-secondary:hover:not(:disabled) {
245
- background: var(--smrt-color-surface-container-low, #f9fafb);
246
- }
247
-
248
- @media (prefers-reduced-motion: reduce) {
249
- button,
250
- input[type='email'] {
251
- transition: none;
252
- }
253
- }
254
198
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"InviteUserModal.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/InviteUserModal.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAI9D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,OAAO,CAAC;KACpB,KAAK,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA4GD,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"InviteUserModal.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/InviteUserModal.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAI9D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC,IAAI,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,OAAO,CAAC;KACpB,KAAK,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAgHD,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -43,6 +43,7 @@ const statusClass = $derived.by(() => {
43
43
  });
44
44
  </script>
45
45
 
46
+ <!-- raw-primitive-allow: large pressable selection card wrapping rich content (avatar, name, email, role/status) with selected state and ripple; no Button primitive owns this structural pattern -->
46
47
  <button
47
48
  type="button"
48
49
  class="user-card"
@@ -1 +1 @@
1
- {"version":3,"file":"UserCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/UserCard.svelte.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAItD,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAwDD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"UserCard.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/UserCard.svelte.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAItD,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAyDD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -1,7 +1,9 @@
1
1
  <script lang="ts">
2
2
  import type { Profile } from '@happyvertical/smrt-profiles';
3
3
  import { UserStatus } from '@happyvertical/smrt-types';
4
+ import { Form, Input, Select } from '@happyvertical/smrt-ui/forms';
4
5
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
6
+ import { Button } from '@happyvertical/smrt-ui/ui';
5
7
  import type { User } from '@happyvertical/smrt-users';
6
8
  import { M } from '../i18n.js';
7
9
 
@@ -60,53 +62,54 @@ $effect(() => {
60
62
  status = user?.status ?? UserStatus.ACTIVE;
61
63
  });
62
64
 
63
- function handleSubmit(e: Event) {
64
- e.preventDefault();
65
+ function handleSubmit() {
65
66
  onsubmit({ name, email, status });
66
67
  }
67
68
  </script>
68
69
 
69
- <form class="user-form" onsubmit={handleSubmit}>
70
- <div class="field">
71
- <label for="name">Name</label>
72
- <input id="name" type="text" bind:value={name} required disabled={loading} />
73
- </div>
74
-
75
- <div class="field">
76
- <label for="email">Email</label>
77
- <input id="email" type="email" bind:value={email} required disabled={loading || !!user} />
78
- {#if user}
79
- <span class="hint">{t(M['users.user_form.email_cannot_be_changed'])}</span>
80
- {/if}
81
- </div>
82
-
83
- <div class="field">
84
- <label for="status">Status</label>
85
- <select id="status" bind:value={status} disabled={loading}>
86
- {#each statusOptions as option (option.value)}
87
- <option value={option.value}>{option.label}</option>
88
- {/each}
89
- </select>
90
- </div>
91
-
92
- <div class="actions">
93
- {#if oncancel}
94
- <button type="button" class="btn-secondary" onclick={oncancel} disabled={loading}>
95
- Cancel
96
- </button>
97
- {/if}
98
- <button type="submit" class="btn-primary" disabled={loading}>
99
- {#if loading}
100
- Saving...
101
- {:else}
102
- {user ? 'Update User' : 'Create User'}
70
+ <div class="user-form-shell">
71
+ <Form class="user-form" onsubmit={handleSubmit}>
72
+ <div class="field">
73
+ <label for="name">Name</label>
74
+ <Input id="name" type="text" bind:value={name} required disabled={loading} />
75
+ </div>
76
+
77
+ <div class="field">
78
+ <label for="email">Email</label>
79
+ <Input id="email" type="email" bind:value={email} required disabled={loading || !!user} />
80
+ {#if user}
81
+ <span class="hint">{t(M['users.user_form.email_cannot_be_changed'])}</span>
103
82
  {/if}
104
- </button>
105
- </div>
106
- </form>
83
+ </div>
84
+
85
+ <div class="field">
86
+ <label for="status">Status</label>
87
+ <Select id="status" bind:value={status} disabled={loading}>
88
+ {#each statusOptions as option (option.value)}
89
+ <option value={option.value}>{option.label}</option>
90
+ {/each}
91
+ </Select>
92
+ </div>
93
+
94
+ <div class="actions">
95
+ {#if oncancel}
96
+ <Button variant="secondary" type="button" onclick={oncancel} disabled={loading}>
97
+ Cancel
98
+ </Button>
99
+ {/if}
100
+ <Button variant="primary" type="submit" disabled={loading}>
101
+ {#if loading}
102
+ Saving...
103
+ {:else}
104
+ {user ? 'Update User' : 'Create User'}
105
+ {/if}
106
+ </Button>
107
+ </div>
108
+ </Form>
109
+ </div>
107
110
 
108
111
  <style>
109
- .user-form {
112
+ .user-form-shell :global(.user-form) {
110
113
  display: flex;
111
114
  flex-direction: column;
112
115
  gap: var(--smrt-spacing-md, 1rem);
@@ -123,28 +126,6 @@ function handleSubmit(e: Event) {
123
126
  color: var(--smrt-color-on-surface-variant, #43474e);
124
127
  }
125
128
 
126
- input,
127
- select {
128
- padding: var(--smrt-spacing-sm, 0.5rem) var(--smrt-spacing-md, 0.75rem);
129
- border: 1px solid var(--smrt-color-outline-variant, #c4c6cf);
130
- border-radius: var(--smrt-radius-medium, 0.5rem);
131
- font: var(--smrt-typography-body-medium-font, 0.875rem / 1.25 sans-serif);
132
- transition: border-color var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
133
- }
134
-
135
- input:focus,
136
- select:focus {
137
- outline: none;
138
- border-color: var(--smrt-color-primary, #005ac1);
139
- box-shadow: 0 0 0 3px var(--smrt-color-primary-container, rgba(0, 90, 193, 0.1));
140
- }
141
-
142
- input:disabled,
143
- select:disabled {
144
- background: var(--smrt-color-surface-container, #f3f4f6);
145
- cursor: not-allowed;
146
- }
147
-
148
129
  .hint {
149
130
  font: var(--smrt-typography-body-small-font, 0.75rem / 1.25 sans-serif);
150
131
  color: var(--smrt-color-on-surface-variant, #43474e);
@@ -156,46 +137,4 @@ function handleSubmit(e: Event) {
156
137
  gap: var(--smrt-spacing-sm, 0.5rem);
157
138
  margin-top: var(--smrt-spacing-sm, 0.5rem);
158
139
  }
159
-
160
- button {
161
- padding: var(--smrt-spacing-sm, 0.5rem) var(--smrt-spacing-md, 1rem);
162
- border-radius: var(--smrt-radius-medium, 0.5rem);
163
- font: var(--smrt-typography-label-large-font, 500 0.875rem / 1.25 sans-serif);
164
- cursor: pointer;
165
- transition: all var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
166
- }
167
-
168
- button:disabled {
169
- opacity: 0.6;
170
- cursor: not-allowed;
171
- }
172
-
173
- .btn-primary {
174
- background: var(--smrt-color-primary, #005ac1);
175
- color: var(--smrt-color-on-primary, #ffffff);
176
- border: none;
177
- }
178
-
179
- .btn-primary:hover:not(:disabled) {
180
- background: var(--smrt-color-primary-container, #005ac1);
181
- opacity: 0.9;
182
- }
183
-
184
- .btn-secondary {
185
- background: var(--smrt-color-surface, white);
186
- color: var(--smrt-color-on-surface-variant, #43474e);
187
- border: 1px solid var(--smrt-color-outline-variant, #c4c6cf);
188
- }
189
-
190
- .btn-secondary:hover:not(:disabled) {
191
- background: var(--smrt-color-surface-container-low, #f9fafb);
192
- }
193
-
194
- @media (prefers-reduced-motion: reduce) {
195
- input,
196
- select,
197
- button {
198
- transition: none;
199
- }
200
- }
201
140
  </style>
@@ -1 +1 @@
1
- {"version":3,"file":"UserForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/UserForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAItD,MAAM,WAAW,KAAK;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAuGD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"UserForm.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/UserForm.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAIvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAItD,MAAM,WAAW,KAAK;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA0GD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -171,6 +171,7 @@ function getInitials(name: string): string {
171
171
  <svelte:window onclick={handleClickOutside} onkeydown={handleKeydown} />
172
172
 
173
173
  <div class="user-menu" id={menuId}>
174
+ <!-- raw-primitive-allow: WAI-ARIA menu-button trigger with bind:this focus management, aria-haspopup/aria-expanded/aria-controls and roving-tabindex keyboard nav; structural menu button no primitive owns -->
174
175
  <button
175
176
  bind:this={triggerButton}
176
177
  id="{menuId}-trigger"
@@ -1 +1 @@
1
- {"version":3,"file":"UserMenu.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/UserMenu.svelte.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAO5D,uCAAuC;AACvC,MAAM,WAAW,KAAK;IACpB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8DAA8D;IAC9D,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,uBAAuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmMD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"UserMenu.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/UserMenu.svelte.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAO5D,uCAAuC;AACvC,MAAM,WAAW,KAAK;IACpB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8DAA8D;IAC9D,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,uBAAuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAoMD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-users",
3
- "version": "0.34.5",
3
+ "version": "0.34.7",
4
4
  "description": "Multi-tenant user management for the SMRT framework - users, tenants, roles, permissions, groups",
5
5
  "type": "module",
6
+ "smrtRawPrimitives": "strict",
6
7
  "main": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
8
9
  "exports": {
@@ -42,12 +43,12 @@
42
43
  "dependencies": {
43
44
  "@happyvertical/logger": "^0.74.7",
44
45
  "jose": "^6.1.3",
45
- "@happyvertical/smrt-core": "0.34.5",
46
- "@happyvertical/smrt-profiles": "0.34.5",
47
- "@happyvertical/smrt-tenancy": "0.34.5",
48
- "@happyvertical/smrt-types": "0.34.5",
49
- "@happyvertical/smrt-config": "0.34.5",
50
- "@happyvertical/smrt-ui": "0.34.5"
46
+ "@happyvertical/smrt-config": "0.34.7",
47
+ "@happyvertical/smrt-core": "0.34.7",
48
+ "@happyvertical/smrt-profiles": "0.34.7",
49
+ "@happyvertical/smrt-tenancy": "0.34.7",
50
+ "@happyvertical/smrt-types": "0.34.7",
51
+ "@happyvertical/smrt-ui": "0.34.7"
51
52
  },
52
53
  "devDependencies": {
53
54
  "@happyvertical/sql": "^0.74.7",
@@ -60,7 +61,7 @@
60
61
  "typescript": "^5.9.3",
61
62
  "vite": "^7.3.1",
62
63
  "vitest": "^4.0.17",
63
- "@happyvertical/smrt-vitest": "0.34.5"
64
+ "@happyvertical/smrt-vitest": "0.34.7"
64
65
  },
65
66
  "keywords": [
66
67
  "smrt",