domma-js 0.56.0 → 0.58.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/README.md +2 -2
- package/assets/types/generated/public/assets/flags/africa.d.ts +6 -0
- package/assets/types/generated/public/assets/flags/americas.d.ts +6 -0
- package/assets/types/generated/public/assets/flags/asia.d.ts +6 -0
- package/assets/types/generated/public/assets/flags/europe.d.ts +9 -0
- package/assets/types/generated/public/assets/flags/index.d.ts +11 -0
- package/assets/types/generated/public/assets/flags/oceania.d.ts +2 -0
- package/assets/types/generated/public/assets/icons/buildings.d.ts +6 -0
- package/assets/types/generated/public/assets/icons/code.d.ts +2 -0
- package/assets/types/generated/public/assets/icons/commerce.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/communication.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/devices.d.ts +6 -0
- package/assets/types/generated/public/assets/icons/emojis.d.ts +6 -0
- package/assets/types/generated/public/assets/icons/files.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/finance.d.ts +6 -0
- package/assets/types/generated/public/assets/icons/forms.d.ts +5 -0
- package/assets/types/generated/public/assets/icons/health.d.ts +6 -0
- package/assets/types/generated/public/assets/icons/index.d.ts +24 -0
- package/assets/types/generated/public/assets/icons/media.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/navigation.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/seasonal.d.ts +6 -0
- package/assets/types/generated/public/assets/icons/social.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/sport.d.ts +6 -0
- package/assets/types/generated/public/assets/icons/status.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/transport.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/ui.d.ts +7 -0
- package/assets/types/generated/public/assets/icons/weather.d.ts +6 -0
- package/assets/types/generated/src/auth.d.ts +424 -0
- package/assets/types/generated/src/avatar.d.ts +270 -0
- package/assets/types/generated/src/binding-source.d.ts +58 -0
- package/assets/types/generated/src/butterfly-drawing.d.ts +2 -0
- package/assets/types/generated/src/component-factory.d.ts +150 -0
- package/assets/types/generated/src/component.d.ts +162 -0
- package/assets/types/generated/src/components/back-to-top.d.ts +150 -0
- package/assets/types/generated/src/components/badge.d.ts +208 -0
- package/assets/types/generated/src/components/card.d.ts +189 -0
- package/assets/types/generated/src/components/command-palette.d.ts +352 -0
- package/assets/types/generated/src/components/dropzone.d.ts +342 -0
- package/assets/types/generated/src/components/focus-trap.d.ts +238 -0
- package/assets/types/generated/src/components/loader.d.ts +133 -0
- package/assets/types/generated/src/components/modal.d.ts +339 -0
- package/assets/types/generated/src/components/range-slider.d.ts +267 -0
- package/assets/types/generated/src/components/shared.d.ts +91 -0
- package/assets/types/generated/src/components/split-pane.d.ts +239 -0
- package/assets/types/generated/src/components/toast.d.ts +284 -0
- package/assets/types/generated/src/components/tooltip.d.ts +200 -0
- package/assets/types/generated/src/components/virtual-list.d.ts +340 -0
- package/assets/types/generated/src/config.d.ts +193 -0
- package/assets/types/generated/src/context-cursor.d.ts +69 -0
- package/assets/types/generated/src/context-menu.d.ts +596 -0
- package/assets/types/generated/src/dates.d.ts +367 -0
- package/assets/types/generated/src/dom.d.ts +1221 -0
- package/assets/types/generated/src/effects.d.ts +1281 -0
- package/assets/types/generated/src/elements.d.ts +4994 -0
- package/assets/types/generated/src/escape.d.ts +5 -0
- package/assets/types/generated/src/flags-bundle.d.ts +4 -0
- package/assets/types/generated/src/flags.d.ts +338 -0
- package/assets/types/generated/src/forms.d.ts +1060 -0
- package/assets/types/generated/src/globals.d.ts +45 -0
- package/assets/types/generated/src/http.d.ts +131 -0
- package/assets/types/generated/src/i18n.d.ts +261 -0
- package/assets/types/generated/src/icons.d.ts +213 -0
- package/assets/types/generated/src/index.d.ts +249 -0
- package/assets/types/generated/src/input-group.d.ts +135 -0
- package/assets/types/generated/src/models.d.ts +968 -0
- package/assets/types/generated/src/popover.d.ts +413 -0
- package/assets/types/generated/src/router.d.ts +344 -0
- package/assets/types/generated/src/safe-url.d.ts +10 -0
- package/assets/types/generated/src/sanitize.d.ts +97 -0
- package/assets/types/generated/src/schema-builder.d.ts +420 -0
- package/assets/types/generated/src/skeleton.d.ts +135 -0
- package/assets/types/generated/src/smooth-caret.d.ts +61 -0
- package/assets/types/generated/src/sortable.d.ts +368 -0
- package/assets/types/generated/src/storage.d.ts +93 -0
- package/assets/types/generated/src/tables.d.ts +901 -0
- package/assets/types/generated/src/theme.d.ts +262 -0
- package/assets/types/generated/src/ticker-tape-drawing.d.ts +2 -0
- package/assets/types/generated/src/treeview.d.ts +504 -0
- package/assets/types/generated/src/utils.d.ts +1667 -0
- package/assets/types/generated/src/web-components/base/domma-element.d.ts +134 -0
- package/assets/types/generated/src/web-components/index.d.ts +14 -0
- package/assets/types/generated/vendor/domma-reactive.d.ts +587 -0
- package/assets/types/index.d.ts +104 -226
- package/package.json +5 -2
- package/public/dist/bundles/domma-complete.css +20 -14
- package/public/dist/bundles/domma-data-focused.css +20 -14
- package/public/dist/bundles/domma-essentials.css +20 -14
- package/public/dist/bundles/domma-full.css +20 -14
- package/public/dist/bundles/domma-minimal.css +8 -8
- package/public/dist/domma-flags.esm.js +3 -3
- package/public/dist/domma-flags.esm.js.map +1 -1
- package/public/dist/domma-flags.min.js +3 -3
- package/public/dist/domma-flags.min.js.map +1 -1
- package/public/dist/domma-syntax.min.js +3 -3
- package/public/dist/domma.css +3 -3
- package/public/dist/domma.esm.js +5 -5
- package/public/dist/domma.esm.js.map +1 -1
- package/public/dist/domma.min.js +5 -5
- package/public/dist/domma.min.js.map +1 -1
- package/public/dist/elements.css +9 -3
- package/public/dist/grid.css +3 -3
- package/public/dist/syntax.css +3 -3
- package/public/dist/themes/domma-themes.css +3 -3
- package/templates/kickstart/.claude/snippets.md +1 -1
- package/templates/kickstart/CLAUDE.md +1 -1
- package/templates/kickstart/frontend/types/domma.d.ts +7 -4
- package/templates/kickstart-spa/.claude/snippets.md +1 -1
- package/assets/types/config.d.ts +0 -136
- package/assets/types/dates.d.ts +0 -209
- package/assets/types/dom.d.ts +0 -448
- package/assets/types/elements.d.ts +0 -1168
- package/assets/types/flags.d.ts +0 -130
- package/assets/types/http.d.ts +0 -97
- package/assets/types/i18n.d.ts +0 -99
- package/assets/types/icons.d.ts +0 -147
- package/assets/types/models.d.ts +0 -260
- package/assets/types/smooth-caret.d.ts +0 -12
- package/assets/types/storage.d.ts +0 -93
- package/assets/types/tables.d.ts +0 -327
- package/assets/types/theme.d.ts +0 -137
- package/assets/types/utils.d.ts +0 -675
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for `A.init()`.
|
|
3
|
+
* @typedef {object} AuthOptions
|
|
4
|
+
* @property {string} [apiUrl] - Backend API URL (default: `http://<host>:3000/api` on localhost, else `<origin>/api`)
|
|
5
|
+
* @property {string} [storageKey='auth_token'] - Storage key for the token
|
|
6
|
+
* @property {string} [userStorageKey='auth_user'] - Storage key for the user object
|
|
7
|
+
* @property {boolean} [autoCheck=true] - Verify a stored token with `GET <apiUrl>/auth/me` on init
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The signed-in user, as the backend returned it (`response.user` from login, register or
|
|
11
|
+
* `/auth/me`). Domma reads `email` and `role`; anything else is the backend's.
|
|
12
|
+
* @typedef {{email?: string, name?: string, role?: string, [key: string]: any}} AuthUser
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Events `A.on()` can listen for: `login` / `register` (data: the user), `logout` (null),
|
|
16
|
+
* `error` (the message string) and `tokenExpired` (null - a stored token the server refused on init).
|
|
17
|
+
* @typedef {'login'|'register'|'logout'|'error'|'tokenExpired'} AuthEventName
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* An auth event handler. Gets the event's data (see AuthEventName).
|
|
21
|
+
* @callback AuthEventHandler
|
|
22
|
+
* @param {any} data
|
|
23
|
+
* @returns {void}
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* The auth module (`A`, `Domma.auth`).
|
|
27
|
+
* @typedef {object} Auth
|
|
28
|
+
* @property {string|null} apiUrl - Backend API URL (set by init)
|
|
29
|
+
* @property {string|null} token - Current JWT, or null
|
|
30
|
+
* @property {AuthUser|null} user - Current user, or null
|
|
31
|
+
* @property {AuthOptions} config - Resolved configuration (set by init)
|
|
32
|
+
* @property {Record<string, AuthEventHandler[]>} eventHandlers - Registered handlers by event name
|
|
33
|
+
* @property {boolean} initialized - Whether init() has run
|
|
34
|
+
* @property {(config?: AuthOptions) => void} init - Initialise the module: load the stored token and user, and (autoCheck) verify the token
|
|
35
|
+
* @property {(email: string, password: string) => Promise<AuthUser>} login - Log in (`POST <apiUrl>/auth/login`); stores the token and user and emits `login`. Rejects on failure (and emits `error`)
|
|
36
|
+
* @property {(email: string, password: string, name: string) => Promise<AuthUser>} register - Register (`POST <apiUrl>/auth/register`); stores the token and user and emits `register`. Rejects on failure (and emits `error`)
|
|
37
|
+
* @property {() => void} logout - Clear the token and user and emit `logout`
|
|
38
|
+
* @property {() => AuthUser|null} getUser - Current user or null
|
|
39
|
+
* @property {() => boolean} isAuthenticated - True when there is both a token and a user
|
|
40
|
+
* @property {() => {Authorization?: string}} getHeaders - `{Authorization: 'Bearer <token>'}`, or `{}` without a token
|
|
41
|
+
* @property {() => string|null} getApiUrl - The backend API URL
|
|
42
|
+
* @property {() => string|null} getRole - Current user's role ('admin', 'subscriber', 'guest') or null
|
|
43
|
+
* @property {(role: string) => boolean} hasRole - Whether the user has this role
|
|
44
|
+
* @property {(roles: string[]) => boolean} hasAnyRole - Whether the user has any of these roles
|
|
45
|
+
* @property {() => boolean} isAdmin - Role is 'admin'
|
|
46
|
+
* @property {() => boolean} isSubscriber - Role is 'subscriber'
|
|
47
|
+
* @property {() => boolean} isGuest - Role is 'guest'
|
|
48
|
+
* @property {(event: AuthEventName|(string & {}), callback: AuthEventHandler) => void} on - Subscribe to an event
|
|
49
|
+
* @property {(event: AuthEventName|(string & {}), callback?: AuthEventHandler) => void} off - Unsubscribe one handler, or every handler of the event when none is given
|
|
50
|
+
* @property {typeof LoginForm} LoginForm - Login form component class
|
|
51
|
+
* @property {typeof RegisterForm} RegisterForm - Registration form component class
|
|
52
|
+
* @property {typeof AuthTabs} AuthTabs - Login/Register tab switcher component class
|
|
53
|
+
* @property {typeof UserInfo} UserInfo - Signed-in user display with a logout button
|
|
54
|
+
* @property {(selector: string|HTMLElement, options?: LoginFormOptions) => LoginForm} createLoginForm - Create a LoginForm
|
|
55
|
+
* @property {(selector: string|HTMLElement, options?: RegisterFormOptions) => RegisterForm} createRegisterForm - Create a RegisterForm
|
|
56
|
+
* @property {(selector: string|HTMLElement, options?: AuthTabsOptions) => AuthTabs} createAuthTabs - Create an AuthTabs
|
|
57
|
+
* @property {(selector: string|HTMLElement, options?: UserInfoOptions) => UserInfo} createUserInfo - Create a UserInfo
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Options for `A.createLoginForm()` / `new A.LoginForm()`.
|
|
61
|
+
* @typedef {object} LoginFormOptions
|
|
62
|
+
* @property {string} [emailPlaceholder='your@email.com']
|
|
63
|
+
* @property {string} [passwordPlaceholder='Enter your password']
|
|
64
|
+
* @property {string} [buttonText='Login']
|
|
65
|
+
* @property {boolean} [showLabels=true]
|
|
66
|
+
* @property {((email: string, password: string) => void)|null} [onSubmit] - Called before the login request
|
|
67
|
+
* @property {((user: AuthUser|null) => void)|null} [onSuccess] - Called after a successful login
|
|
68
|
+
* @property {((error: Error) => void)|null} [onError] - Called when the login fails
|
|
69
|
+
*/
|
|
70
|
+
/**
|
|
71
|
+
* Options for `A.createRegisterForm()` / `new A.RegisterForm()`.
|
|
72
|
+
* @typedef {object} RegisterFormOptions
|
|
73
|
+
* @property {string} [namePlaceholder='Your name']
|
|
74
|
+
* @property {string} [emailPlaceholder='your@email.com']
|
|
75
|
+
* @property {string} [passwordPlaceholder='Create a password']
|
|
76
|
+
* @property {string} [buttonText='Register']
|
|
77
|
+
* @property {number} [minPasswordLength=6]
|
|
78
|
+
* @property {boolean} [showLabels=true]
|
|
79
|
+
* @property {((email: string, password: string, name: string) => void)|null} [onSubmit] - Called before the register request
|
|
80
|
+
* @property {((user: AuthUser|null) => void)|null} [onSuccess] - Called after a successful registration
|
|
81
|
+
* @property {((error: Error) => void)|null} [onError] - Called when registration fails (also for mismatched passwords)
|
|
82
|
+
*/
|
|
83
|
+
/**
|
|
84
|
+
* Options for `A.createAuthTabs()` / `new A.AuthTabs()`.
|
|
85
|
+
* @typedef {object} AuthTabsOptions
|
|
86
|
+
* @property {'login'|'register'} [activeTab='login']
|
|
87
|
+
* @property {string} [loginText='Login']
|
|
88
|
+
* @property {string} [registerText='Register']
|
|
89
|
+
* @property {((tab: string) => void)|null} [onChange] - Called with the tab switched to
|
|
90
|
+
*/
|
|
91
|
+
/**
|
|
92
|
+
* Options for `A.createUserInfo()` / `new A.UserInfo()`.
|
|
93
|
+
* @typedef {object} UserInfoOptions
|
|
94
|
+
* @property {boolean} [showIcon=true]
|
|
95
|
+
* @property {boolean} [showRole=true]
|
|
96
|
+
* @property {string} [logoutText='Logout']
|
|
97
|
+
* @property {(() => void)|null} [onLogout] - Called after the logout button logs out
|
|
98
|
+
*/
|
|
99
|
+
/** @type {Auth} */
|
|
100
|
+
export const auth: Auth;
|
|
101
|
+
/**
|
|
102
|
+
* LoginForm Component
|
|
103
|
+
*/
|
|
104
|
+
export class LoginForm extends Component {
|
|
105
|
+
static defaults: {
|
|
106
|
+
emailPlaceholder: string;
|
|
107
|
+
passwordPlaceholder: string;
|
|
108
|
+
buttonText: string;
|
|
109
|
+
showLabels: boolean;
|
|
110
|
+
onSubmit: any;
|
|
111
|
+
onSuccess: any;
|
|
112
|
+
onError: any;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* @param {string|HTMLElement} selector - Container element or selector
|
|
116
|
+
* @param {LoginFormOptions} [options]
|
|
117
|
+
*/
|
|
118
|
+
constructor(selector: string | HTMLElement, options?: LoginFormOptions);
|
|
119
|
+
_init(): void;
|
|
120
|
+
render(): void;
|
|
121
|
+
handleSubmit(): Promise<void>;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* RegisterForm Component
|
|
125
|
+
*/
|
|
126
|
+
export class RegisterForm extends Component {
|
|
127
|
+
static defaults: {
|
|
128
|
+
namePlaceholder: string;
|
|
129
|
+
emailPlaceholder: string;
|
|
130
|
+
passwordPlaceholder: string;
|
|
131
|
+
buttonText: string;
|
|
132
|
+
minPasswordLength: number;
|
|
133
|
+
showLabels: boolean;
|
|
134
|
+
onSubmit: any;
|
|
135
|
+
onSuccess: any;
|
|
136
|
+
onError: any;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* @param {string|HTMLElement} selector - Container element or selector
|
|
140
|
+
* @param {RegisterFormOptions} [options]
|
|
141
|
+
*/
|
|
142
|
+
constructor(selector: string | HTMLElement, options?: RegisterFormOptions);
|
|
143
|
+
_init(): void;
|
|
144
|
+
render(): void;
|
|
145
|
+
handleSubmit(): Promise<void>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* AuthTabs Component
|
|
149
|
+
*/
|
|
150
|
+
export class AuthTabs extends Component {
|
|
151
|
+
static defaults: {
|
|
152
|
+
activeTab: string;
|
|
153
|
+
loginText: string;
|
|
154
|
+
registerText: string;
|
|
155
|
+
onChange: any;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* @param {string|HTMLElement} selector - Container element or selector
|
|
159
|
+
* @param {AuthTabsOptions} [options]
|
|
160
|
+
*/
|
|
161
|
+
constructor(selector: string | HTMLElement, options?: AuthTabsOptions);
|
|
162
|
+
_init(): void;
|
|
163
|
+
render(): void;
|
|
164
|
+
/**
|
|
165
|
+
* @param {string} tab - 'login' or 'register'
|
|
166
|
+
*/
|
|
167
|
+
switchTab(tab: string): void;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* UserInfo Component
|
|
171
|
+
*/
|
|
172
|
+
export class UserInfo extends Component {
|
|
173
|
+
static defaults: {
|
|
174
|
+
showIcon: boolean;
|
|
175
|
+
showRole: boolean;
|
|
176
|
+
logoutText: string;
|
|
177
|
+
onLogout: any;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* @param {string|HTMLElement} selector
|
|
181
|
+
* @param {Object} [options]
|
|
182
|
+
*/
|
|
183
|
+
constructor(selector: string | HTMLElement, options?: any);
|
|
184
|
+
_init(): void;
|
|
185
|
+
_onAuthChange: () => void;
|
|
186
|
+
render(): void;
|
|
187
|
+
handleLogout(): void;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Options for `A.init()`.
|
|
191
|
+
*/
|
|
192
|
+
export type AuthOptions = {
|
|
193
|
+
/**
|
|
194
|
+
* - Backend API URL (default: `http://<host>:3000/api` on localhost, else `<origin>/api`)
|
|
195
|
+
*/
|
|
196
|
+
apiUrl?: string;
|
|
197
|
+
/**
|
|
198
|
+
* - Storage key for the token
|
|
199
|
+
*/
|
|
200
|
+
storageKey?: string;
|
|
201
|
+
/**
|
|
202
|
+
* - Storage key for the user object
|
|
203
|
+
*/
|
|
204
|
+
userStorageKey?: string;
|
|
205
|
+
/**
|
|
206
|
+
* - Verify a stored token with `GET <apiUrl>/auth/me` on init
|
|
207
|
+
*/
|
|
208
|
+
autoCheck?: boolean;
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* The signed-in user, as the backend returned it (`response.user` from login, register or
|
|
212
|
+
* `/auth/me`). Domma reads `email` and `role`; anything else is the backend's.
|
|
213
|
+
*/
|
|
214
|
+
export type AuthUser = {
|
|
215
|
+
email?: string;
|
|
216
|
+
name?: string;
|
|
217
|
+
role?: string;
|
|
218
|
+
[key: string]: any;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Events `A.on()` can listen for: `login` / `register` (data: the user), `logout` (null),
|
|
222
|
+
* `error` (the message string) and `tokenExpired` (null - a stored token the server refused on init).
|
|
223
|
+
*/
|
|
224
|
+
export type AuthEventName = "login" | "register" | "logout" | "error" | "tokenExpired";
|
|
225
|
+
/**
|
|
226
|
+
* An auth event handler. Gets the event's data (see AuthEventName).
|
|
227
|
+
*/
|
|
228
|
+
export type AuthEventHandler = (data: any) => void;
|
|
229
|
+
/**
|
|
230
|
+
* The auth module (`A`, `Domma.auth`).
|
|
231
|
+
*/
|
|
232
|
+
export type Auth = {
|
|
233
|
+
/**
|
|
234
|
+
* - Backend API URL (set by init)
|
|
235
|
+
*/
|
|
236
|
+
apiUrl: string | null;
|
|
237
|
+
/**
|
|
238
|
+
* - Current JWT, or null
|
|
239
|
+
*/
|
|
240
|
+
token: string | null;
|
|
241
|
+
/**
|
|
242
|
+
* - Current user, or null
|
|
243
|
+
*/
|
|
244
|
+
user: AuthUser | null;
|
|
245
|
+
/**
|
|
246
|
+
* - Resolved configuration (set by init)
|
|
247
|
+
*/
|
|
248
|
+
config: AuthOptions;
|
|
249
|
+
/**
|
|
250
|
+
* - Registered handlers by event name
|
|
251
|
+
*/
|
|
252
|
+
eventHandlers: Record<string, AuthEventHandler[]>;
|
|
253
|
+
/**
|
|
254
|
+
* - Whether init() has run
|
|
255
|
+
*/
|
|
256
|
+
initialized: boolean;
|
|
257
|
+
/**
|
|
258
|
+
* - Initialise the module: load the stored token and user, and (autoCheck) verify the token
|
|
259
|
+
*/
|
|
260
|
+
init: (config?: AuthOptions) => void;
|
|
261
|
+
/**
|
|
262
|
+
* - Log in (`POST <apiUrl>/auth/login`); stores the token and user and emits `login`. Rejects on failure (and emits `error`)
|
|
263
|
+
*/
|
|
264
|
+
login: (email: string, password: string) => Promise<AuthUser>;
|
|
265
|
+
/**
|
|
266
|
+
* - Register (`POST <apiUrl>/auth/register`); stores the token and user and emits `register`. Rejects on failure (and emits `error`)
|
|
267
|
+
*/
|
|
268
|
+
register: (email: string, password: string, name: string) => Promise<AuthUser>;
|
|
269
|
+
/**
|
|
270
|
+
* - Clear the token and user and emit `logout`
|
|
271
|
+
*/
|
|
272
|
+
logout: () => void;
|
|
273
|
+
/**
|
|
274
|
+
* - Current user or null
|
|
275
|
+
*/
|
|
276
|
+
getUser: () => AuthUser | null;
|
|
277
|
+
/**
|
|
278
|
+
* - True when there is both a token and a user
|
|
279
|
+
*/
|
|
280
|
+
isAuthenticated: () => boolean;
|
|
281
|
+
/**
|
|
282
|
+
* - `{Authorization: 'Bearer <token>'}`, or `{}` without a token
|
|
283
|
+
*/
|
|
284
|
+
getHeaders: () => {
|
|
285
|
+
Authorization?: string;
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* - The backend API URL
|
|
289
|
+
*/
|
|
290
|
+
getApiUrl: () => string | null;
|
|
291
|
+
/**
|
|
292
|
+
* - Current user's role ('admin', 'subscriber', 'guest') or null
|
|
293
|
+
*/
|
|
294
|
+
getRole: () => string | null;
|
|
295
|
+
/**
|
|
296
|
+
* - Whether the user has this role
|
|
297
|
+
*/
|
|
298
|
+
hasRole: (role: string) => boolean;
|
|
299
|
+
/**
|
|
300
|
+
* - Whether the user has any of these roles
|
|
301
|
+
*/
|
|
302
|
+
hasAnyRole: (roles: string[]) => boolean;
|
|
303
|
+
/**
|
|
304
|
+
* - Role is 'admin'
|
|
305
|
+
*/
|
|
306
|
+
isAdmin: () => boolean;
|
|
307
|
+
/**
|
|
308
|
+
* - Role is 'subscriber'
|
|
309
|
+
*/
|
|
310
|
+
isSubscriber: () => boolean;
|
|
311
|
+
/**
|
|
312
|
+
* - Role is 'guest'
|
|
313
|
+
*/
|
|
314
|
+
isGuest: () => boolean;
|
|
315
|
+
/**
|
|
316
|
+
* - Subscribe to an event
|
|
317
|
+
*/
|
|
318
|
+
on: (event: AuthEventName | (string & {}), callback: AuthEventHandler) => void;
|
|
319
|
+
/**
|
|
320
|
+
* - Unsubscribe one handler, or every handler of the event when none is given
|
|
321
|
+
*/
|
|
322
|
+
off: (event: AuthEventName | (string & {}), callback?: AuthEventHandler) => void;
|
|
323
|
+
/**
|
|
324
|
+
* - Login form component class
|
|
325
|
+
*/
|
|
326
|
+
LoginForm: typeof LoginForm;
|
|
327
|
+
/**
|
|
328
|
+
* - Registration form component class
|
|
329
|
+
*/
|
|
330
|
+
RegisterForm: typeof RegisterForm;
|
|
331
|
+
/**
|
|
332
|
+
* - Login/Register tab switcher component class
|
|
333
|
+
*/
|
|
334
|
+
AuthTabs: typeof AuthTabs;
|
|
335
|
+
/**
|
|
336
|
+
* - Signed-in user display with a logout button
|
|
337
|
+
*/
|
|
338
|
+
UserInfo: typeof UserInfo;
|
|
339
|
+
/**
|
|
340
|
+
* - Create a LoginForm
|
|
341
|
+
*/
|
|
342
|
+
createLoginForm: (selector: string | HTMLElement, options?: LoginFormOptions) => LoginForm;
|
|
343
|
+
/**
|
|
344
|
+
* - Create a RegisterForm
|
|
345
|
+
*/
|
|
346
|
+
createRegisterForm: (selector: string | HTMLElement, options?: RegisterFormOptions) => RegisterForm;
|
|
347
|
+
/**
|
|
348
|
+
* - Create an AuthTabs
|
|
349
|
+
*/
|
|
350
|
+
createAuthTabs: (selector: string | HTMLElement, options?: AuthTabsOptions) => AuthTabs;
|
|
351
|
+
/**
|
|
352
|
+
* - Create a UserInfo
|
|
353
|
+
*/
|
|
354
|
+
createUserInfo: (selector: string | HTMLElement, options?: UserInfoOptions) => UserInfo;
|
|
355
|
+
};
|
|
356
|
+
/**
|
|
357
|
+
* Options for `A.createLoginForm()` / `new A.LoginForm()`.
|
|
358
|
+
*/
|
|
359
|
+
export type LoginFormOptions = {
|
|
360
|
+
emailPlaceholder?: string;
|
|
361
|
+
passwordPlaceholder?: string;
|
|
362
|
+
buttonText?: string;
|
|
363
|
+
showLabels?: boolean;
|
|
364
|
+
/**
|
|
365
|
+
* - Called before the login request
|
|
366
|
+
*/
|
|
367
|
+
onSubmit?: ((email: string, password: string) => void) | null;
|
|
368
|
+
/**
|
|
369
|
+
* - Called after a successful login
|
|
370
|
+
*/
|
|
371
|
+
onSuccess?: ((user: AuthUser | null) => void) | null;
|
|
372
|
+
/**
|
|
373
|
+
* - Called when the login fails
|
|
374
|
+
*/
|
|
375
|
+
onError?: ((error: Error) => void) | null;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Options for `A.createRegisterForm()` / `new A.RegisterForm()`.
|
|
379
|
+
*/
|
|
380
|
+
export type RegisterFormOptions = {
|
|
381
|
+
namePlaceholder?: string;
|
|
382
|
+
emailPlaceholder?: string;
|
|
383
|
+
passwordPlaceholder?: string;
|
|
384
|
+
buttonText?: string;
|
|
385
|
+
minPasswordLength?: number;
|
|
386
|
+
showLabels?: boolean;
|
|
387
|
+
/**
|
|
388
|
+
* - Called before the register request
|
|
389
|
+
*/
|
|
390
|
+
onSubmit?: ((email: string, password: string, name: string) => void) | null;
|
|
391
|
+
/**
|
|
392
|
+
* - Called after a successful registration
|
|
393
|
+
*/
|
|
394
|
+
onSuccess?: ((user: AuthUser | null) => void) | null;
|
|
395
|
+
/**
|
|
396
|
+
* - Called when registration fails (also for mismatched passwords)
|
|
397
|
+
*/
|
|
398
|
+
onError?: ((error: Error) => void) | null;
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* Options for `A.createAuthTabs()` / `new A.AuthTabs()`.
|
|
402
|
+
*/
|
|
403
|
+
export type AuthTabsOptions = {
|
|
404
|
+
activeTab?: "login" | "register";
|
|
405
|
+
loginText?: string;
|
|
406
|
+
registerText?: string;
|
|
407
|
+
/**
|
|
408
|
+
* - Called with the tab switched to
|
|
409
|
+
*/
|
|
410
|
+
onChange?: ((tab: string) => void) | null;
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* Options for `A.createUserInfo()` / `new A.UserInfo()`.
|
|
414
|
+
*/
|
|
415
|
+
export type UserInfoOptions = {
|
|
416
|
+
showIcon?: boolean;
|
|
417
|
+
showRole?: boolean;
|
|
418
|
+
logoutText?: string;
|
|
419
|
+
/**
|
|
420
|
+
* - Called after the logout button logs out
|
|
421
|
+
*/
|
|
422
|
+
onLogout?: (() => void) | null;
|
|
423
|
+
};
|
|
424
|
+
import Component from './component.js';
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initials for a name.
|
|
3
|
+
*
|
|
4
|
+
* 'Jane Smith' -> 'JS' first and last word
|
|
5
|
+
* 'Jane Q. Public' -> 'JP'
|
|
6
|
+
* 'Madonna' -> 'M' one word, one letter
|
|
7
|
+
* 'jane.smith@example.com' -> 'JS' the part before the @, split on . _ - +
|
|
8
|
+
* 'Jean-Luc Picard' -> 'JP'
|
|
9
|
+
* 'Łukasz Żuk' -> 'ŁŻ'
|
|
10
|
+
* '王小明' -> '王'
|
|
11
|
+
* '', null, ' !! ' -> '' nothing to go on: callers show an icon
|
|
12
|
+
*
|
|
13
|
+
* Words are split on spaces, dots, underscores, hyphens and plus signs;
|
|
14
|
+
* anything that is not a letter or digit at the start of a word (quotes,
|
|
15
|
+
* brackets, emoji) is skipped, and bracketed notes like "(Admin)" are dropped.
|
|
16
|
+
* @param {string|null|undefined} name
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
export function avatarInitials(name: string | null | undefined): string;
|
|
20
|
+
/**
|
|
21
|
+
* The tone (0-7) for a name: FNV-1a over the trimmed, lower-cased, single-spaced
|
|
22
|
+
* name. Stable across pages, sessions and machines; case and spacing do not
|
|
23
|
+
* change it, so 'jane smith' and 'Jane Smith' match.
|
|
24
|
+
* @param {string} key
|
|
25
|
+
* @returns {number}
|
|
26
|
+
*/
|
|
27
|
+
export function avatarTone(key: string): number;
|
|
28
|
+
/**
|
|
29
|
+
* Render one avatar.
|
|
30
|
+
* @overload
|
|
31
|
+
* @param {string|Element|ArrayLike<Element>|null} target
|
|
32
|
+
* @param {AvatarOptions} [options]
|
|
33
|
+
* @returns {AvatarHandle|null}
|
|
34
|
+
*/
|
|
35
|
+
export function avatar(target: string | Element | ArrayLike<Element> | null, options?: AvatarOptions): AvatarHandle | null;
|
|
36
|
+
/**
|
|
37
|
+
* Render one avatar into a detached <span> for you to insert.
|
|
38
|
+
* @overload
|
|
39
|
+
* @param {AvatarOptions} options
|
|
40
|
+
* @returns {AvatarHandle}
|
|
41
|
+
*/
|
|
42
|
+
export function avatar(options: AvatarOptions): AvatarHandle;
|
|
43
|
+
export namespace avatar {
|
|
44
|
+
export { avatarInitials as initials };
|
|
45
|
+
export { avatarTone as tone };
|
|
46
|
+
/**
|
|
47
|
+
* The live handle on an element, if any - the same answer as E.get(target, 'avatar').
|
|
48
|
+
* @param {string|Element|ArrayLike<Element>} target
|
|
49
|
+
* @returns {AvatarHandle|null}
|
|
50
|
+
*/
|
|
51
|
+
export function get(target: string | Element | ArrayLike<Element>): AvatarHandle | null;
|
|
52
|
+
/**
|
|
53
|
+
* Turn every `[data-avatar]` under `root` (and `root` itself) into an avatar,
|
|
54
|
+
* once. Options come from `data-avatar-*`. Returns the new handles.
|
|
55
|
+
* @param {string|Element|Document} [root]
|
|
56
|
+
* @returns {AvatarHandle[]}
|
|
57
|
+
*/
|
|
58
|
+
export function scan(root?: string | Element | Document): AvatarHandle[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Render a stack of avatars with a "+N" overflow bubble.
|
|
62
|
+
*
|
|
63
|
+
* @param {string|Element|ArrayLike<Element>} target - a <ul>/<ol> to fill, or any element
|
|
64
|
+
* to put a new <ul> into (its content comes back on destroy())
|
|
65
|
+
* @param {AvatarGroupOptions} [options] - see GROUP_DEFAULTS
|
|
66
|
+
* @returns {AvatarGroupHandle|null} null if nothing matched
|
|
67
|
+
*/
|
|
68
|
+
export function avatarGroup(target: string | Element | ArrayLike<Element>, options?: AvatarGroupOptions): AvatarGroupHandle | null;
|
|
69
|
+
export namespace avatarGroup {
|
|
70
|
+
/**
|
|
71
|
+
* The live group handle on a host element (or its list), if any - the same answer as E.get(target, 'avatar-group').
|
|
72
|
+
* @param {string|Element|ArrayLike<Element>} target
|
|
73
|
+
* @returns {AvatarGroupHandle|null}
|
|
74
|
+
*/
|
|
75
|
+
function get(target: string | Element | ArrayLike<Element>): AvatarGroupHandle | null;
|
|
76
|
+
}
|
|
77
|
+
/** @type {AvatarSize[]} */
|
|
78
|
+
export const AVATAR_SIZES: AvatarSize[];
|
|
79
|
+
/** @type {AvatarShape[]} */
|
|
80
|
+
export const AVATAR_SHAPES: AvatarShape[];
|
|
81
|
+
/** @type {AvatarStatus[]} */
|
|
82
|
+
export const AVATAR_STATUSES: AvatarStatus[];
|
|
83
|
+
/** How many `.avatar-tone-*` classes elements.css defines. */
|
|
84
|
+
export const AVATAR_TONES: 8;
|
|
85
|
+
export default avatar;
|
|
86
|
+
export type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
87
|
+
export type AvatarShape = "circle" | "rounded" | "square";
|
|
88
|
+
export type AvatarStatus = "online" | "away" | "busy" | "offline";
|
|
89
|
+
export type AvatarOptions = {
|
|
90
|
+
/**
|
|
91
|
+
* - The person: initials, tone and accessible name come from it
|
|
92
|
+
*/
|
|
93
|
+
name?: string | null;
|
|
94
|
+
/**
|
|
95
|
+
* - Picture URL; falls back to the initials (or icon) if it fails to load
|
|
96
|
+
*/
|
|
97
|
+
src?: string | null;
|
|
98
|
+
/**
|
|
99
|
+
* - Accessible name when it should differ from name
|
|
100
|
+
*/
|
|
101
|
+
alt?: string | null;
|
|
102
|
+
/**
|
|
103
|
+
* - Size (default 'md')
|
|
104
|
+
*/
|
|
105
|
+
size?: AvatarSize;
|
|
106
|
+
/**
|
|
107
|
+
* - Shape (default 'circle')
|
|
108
|
+
*/
|
|
109
|
+
shape?: AvatarShape;
|
|
110
|
+
/**
|
|
111
|
+
* - Status dot; the word goes into the accessible name
|
|
112
|
+
*/
|
|
113
|
+
status?: AvatarStatus | null;
|
|
114
|
+
/**
|
|
115
|
+
* - Words for the statuses in the accessible name, e.g. {busy: 'in a meeting'}
|
|
116
|
+
*/
|
|
117
|
+
statusLabels?: Partial<Record<AvatarStatus, string>> | null;
|
|
118
|
+
/**
|
|
119
|
+
* - Icon name shown instead of initials ('user' when there is no name)
|
|
120
|
+
*/
|
|
121
|
+
icon?: string | null;
|
|
122
|
+
/**
|
|
123
|
+
* - Hover text; true = the accessible name
|
|
124
|
+
*/
|
|
125
|
+
title?: string | true | null;
|
|
126
|
+
/**
|
|
127
|
+
* - A primary-coloured ring (default false)
|
|
128
|
+
*/
|
|
129
|
+
ring?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* - 0-7 to choose the tint; default is a hash of the name
|
|
132
|
+
*/
|
|
133
|
+
tone?: number | null;
|
|
134
|
+
/**
|
|
135
|
+
* - aria-hidden: the name is written next to it (default false)
|
|
136
|
+
*/
|
|
137
|
+
decorative?: boolean;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* The handle E.avatar() returns. `options`, `initials`, `tone` and `label` are read only.
|
|
141
|
+
*/
|
|
142
|
+
export type AvatarHandle = {
|
|
143
|
+
/**
|
|
144
|
+
* - The avatar element
|
|
145
|
+
*/
|
|
146
|
+
element: HTMLElement;
|
|
147
|
+
/**
|
|
148
|
+
* - The options in force
|
|
149
|
+
*/
|
|
150
|
+
options: AvatarOptions;
|
|
151
|
+
/**
|
|
152
|
+
* - The initials drawn ('' when an icon is shown)
|
|
153
|
+
*/
|
|
154
|
+
initials: string;
|
|
155
|
+
/**
|
|
156
|
+
* - The tone 0-7, or null with nothing to hash
|
|
157
|
+
*/
|
|
158
|
+
tone: number | null;
|
|
159
|
+
/**
|
|
160
|
+
* - The accessible name, e.g. 'Jane Smith (online)'
|
|
161
|
+
*/
|
|
162
|
+
label: string;
|
|
163
|
+
/**
|
|
164
|
+
* - Merge options and redraw
|
|
165
|
+
*/
|
|
166
|
+
update: (options?: AvatarOptions) => AvatarHandle;
|
|
167
|
+
/**
|
|
168
|
+
* - Restore the element's previous children, classes and attributes
|
|
169
|
+
*/
|
|
170
|
+
destroy: () => HTMLElement;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* `E.avatar` - the factory with `initials`, `tone`, `get` and `scan`.
|
|
174
|
+
*/
|
|
175
|
+
export type AvatarStatic = typeof avatar;
|
|
176
|
+
/**
|
|
177
|
+
* One person in an avatar group.
|
|
178
|
+
*/
|
|
179
|
+
export type AvatarPerson = {
|
|
180
|
+
name?: string;
|
|
181
|
+
src?: string;
|
|
182
|
+
status?: AvatarStatus;
|
|
183
|
+
/**
|
|
184
|
+
* - Makes the avatar a link
|
|
185
|
+
*/
|
|
186
|
+
href?: string;
|
|
187
|
+
alt?: string;
|
|
188
|
+
icon?: string;
|
|
189
|
+
tone?: number;
|
|
190
|
+
/**
|
|
191
|
+
* - Hover text (default: the accessible name)
|
|
192
|
+
*/
|
|
193
|
+
title?: string | true;
|
|
194
|
+
};
|
|
195
|
+
export type AvatarGroupOptions = {
|
|
196
|
+
/**
|
|
197
|
+
* - People, or plain names
|
|
198
|
+
*/
|
|
199
|
+
people?: Array<AvatarPerson | string>;
|
|
200
|
+
/**
|
|
201
|
+
* - Show this many, then "+N"; null = everyone
|
|
202
|
+
*/
|
|
203
|
+
max?: number | null;
|
|
204
|
+
/**
|
|
205
|
+
* - Size (default 'md')
|
|
206
|
+
*/
|
|
207
|
+
size?: AvatarSize;
|
|
208
|
+
/**
|
|
209
|
+
* - Shape (default 'circle')
|
|
210
|
+
*/
|
|
211
|
+
shape?: AvatarShape;
|
|
212
|
+
/**
|
|
213
|
+
* - 'none' | 'sm' | 'md' | 'lg', pixels, or any CSS length; null = the stylesheet's 25%
|
|
214
|
+
*/
|
|
215
|
+
overlap?: "none" | "sm" | "md" | "lg" | number | string | null;
|
|
216
|
+
/**
|
|
217
|
+
* - Accessible name for the list
|
|
218
|
+
*/
|
|
219
|
+
label?: string | null;
|
|
220
|
+
statusLabels?: Partial<Record<AvatarStatus, string>> | null;
|
|
221
|
+
/**
|
|
222
|
+
* - Called when "+N" is pressed, instead of the popover
|
|
223
|
+
*/
|
|
224
|
+
onMore?: ((hidden: AvatarPerson[], event: MouseEvent) => void) | null;
|
|
225
|
+
/**
|
|
226
|
+
* - false: no popover, the hidden names go in the button's title (default true)
|
|
227
|
+
*/
|
|
228
|
+
popover?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* - The "+N" button's accessible name (default '3 more: A, B and C')
|
|
231
|
+
*/
|
|
232
|
+
moreLabel?: ((count: number, names: string[]) => string) | null;
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* The handle E.avatarGroup() returns. Everything but the methods is read only.
|
|
236
|
+
*/
|
|
237
|
+
export type AvatarGroupHandle = {
|
|
238
|
+
/**
|
|
239
|
+
* - The <ul>
|
|
240
|
+
*/
|
|
241
|
+
element: HTMLUListElement | HTMLOListElement;
|
|
242
|
+
options: AvatarGroupOptions;
|
|
243
|
+
people: AvatarPerson[];
|
|
244
|
+
/**
|
|
245
|
+
* - Drawn as avatars
|
|
246
|
+
*/
|
|
247
|
+
shown: AvatarPerson[];
|
|
248
|
+
/**
|
|
249
|
+
* - Folded into "+N"
|
|
250
|
+
*/
|
|
251
|
+
hidden: AvatarPerson[];
|
|
252
|
+
/**
|
|
253
|
+
* - The "+N" button, or null
|
|
254
|
+
*/
|
|
255
|
+
more: HTMLButtonElement | null;
|
|
256
|
+
/**
|
|
257
|
+
* - The "+N" popover, or null
|
|
258
|
+
*/
|
|
259
|
+
popover: import("./popover.js").PopoverInstance | null;
|
|
260
|
+
update: (options?: AvatarGroupOptions) => AvatarGroupHandle;
|
|
261
|
+
setPeople: (people: Array<AvatarPerson | string>) => AvatarGroupHandle;
|
|
262
|
+
/**
|
|
263
|
+
* - Remove everything and restore the host
|
|
264
|
+
*/
|
|
265
|
+
destroy: () => HTMLElement;
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* `E.avatarGroup` - the factory with `get`.
|
|
269
|
+
*/
|
|
270
|
+
export type AvatarGroupStatic = typeof avatarGroup;
|