@ibobbyts/svelte-ui-utils 0.2.2 → 0.2.3

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.
Files changed (37) hide show
  1. package/README.md +50 -17
  2. package/dist/{modal → dialog}/ConfirmDialog.svelte +25 -8
  3. package/dist/{modal → dialog}/ConfirmDialog.svelte.d.ts +11 -2
  4. package/dist/dialog/ConfirmDialog.svelte.d.ts.map +1 -0
  5. package/dist/dialog/CsvUploadDialog.svelte +207 -0
  6. package/dist/dialog/CsvUploadDialog.svelte.d.ts +59 -0
  7. package/dist/dialog/CsvUploadDialog.svelte.d.ts.map +1 -0
  8. package/dist/{modal/Modal.svelte → dialog/Dialog.svelte} +37 -15
  9. package/dist/{modal/Modal.svelte.d.ts → dialog/Dialog.svelte.d.ts} +14 -6
  10. package/dist/dialog/Dialog.svelte.d.ts.map +1 -0
  11. package/dist/dialog/ImagePreviewDialog.svelte +75 -0
  12. package/dist/dialog/ImagePreviewDialog.svelte.d.ts +38 -0
  13. package/dist/dialog/ImagePreviewDialog.svelte.d.ts.map +1 -0
  14. package/dist/dialog/InputDialog.svelte +131 -0
  15. package/dist/dialog/InputDialog.svelte.d.ts +45 -0
  16. package/dist/dialog/InputDialog.svelte.d.ts.map +1 -0
  17. package/dist/dialog/PasswordCopyDialog.svelte +95 -0
  18. package/dist/dialog/PasswordCopyDialog.svelte.d.ts +40 -0
  19. package/dist/dialog/PasswordCopyDialog.svelte.d.ts.map +1 -0
  20. package/dist/dialog/index.d.ts +8 -0
  21. package/dist/dialog/index.d.ts.map +1 -0
  22. package/dist/dialog/index.js +6 -0
  23. package/dist/dialog/types.d.ts +4 -0
  24. package/dist/dialog/types.d.ts.map +1 -0
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/modal/index.d.ts +2 -3
  29. package/dist/modal/index.d.ts.map +1 -1
  30. package/dist/modal/index.js +2 -2
  31. package/dist/style.css +213 -33
  32. package/package.json +7 -2
  33. package/dist/modal/ConfirmDialog.svelte.d.ts.map +0 -1
  34. package/dist/modal/Modal.svelte.d.ts.map +0 -1
  35. package/dist/modal/types.d.ts +0 -3
  36. package/dist/modal/types.d.ts.map +0 -1
  37. /package/dist/{modal → dialog}/types.js +0 -0
package/README.md CHANGED
@@ -10,19 +10,19 @@ Install from the public npm registry. No GitHub Packages token is required.
10
10
  With Bun:
11
11
 
12
12
  ```bash
13
- bun add @ibobbyts/svelte-ui-utils@0.2.0
13
+ bun add @ibobbyts/svelte-ui-utils@0.2.3
14
14
  ```
15
15
 
16
16
  Canonical Bun pull address:
17
17
 
18
18
  ```text
19
- @ibobbyts/svelte-ui-utils@0.2.0
19
+ @ibobbyts/svelte-ui-utils@0.2.3
20
20
  ```
21
21
 
22
22
  With npm:
23
23
 
24
24
  ```bash
25
- npm install @ibobbyts/svelte-ui-utils@0.2.0
25
+ npm install @ibobbyts/svelte-ui-utils@0.2.3
26
26
  ```
27
27
 
28
28
  The repository does not track `dist/`; releases and local integration builds run
@@ -41,7 +41,7 @@ import '@ibobbyts/svelte-ui-utils/style.css';
41
41
  import { ToastManager, toast } from '@ibobbyts/svelte-ui-utils/toast';
42
42
  import { Dropdown } from '@ibobbyts/svelte-ui-utils/dropdown';
43
43
  import { DropdownSearch, DropdownSearchMultiSelect } from '@ibobbyts/svelte-ui-utils/dropdown-search';
44
- import { Modal, ConfirmDialog } from '@ibobbyts/svelte-ui-utils/modal';
44
+ import { Dialog, ConfirmDialog, InputDialog, CsvUploadDialog, ImagePreviewDialog, PasswordCopyDialog } from '@ibobbyts/svelte-ui-utils/dialog';
45
45
  import { DataTable, DateRangeFilter, FilterTable, NumberRangeFilter } from '@ibobbyts/svelte-ui-utils/table';
46
46
  </script>
47
47
  ```
@@ -49,7 +49,7 @@ import '@ibobbyts/svelte-ui-utils/style.css';
49
49
  The package root also re-exports the public modules:
50
50
 
51
51
  ```ts
52
- import { ToastManager, Dropdown, DropdownSearch, Modal, DataTable } from '@ibobbyts/svelte-ui-utils';
52
+ import { ToastManager, Dropdown, DropdownSearch, Dialog, DataTable } from '@ibobbyts/svelte-ui-utils';
53
53
  ```
54
54
 
55
55
  ## Toast
@@ -153,31 +153,37 @@ In multiselect mode, the text input remains a search query. Selecting an item
153
153
  adds or removes it from `selectedItems`, clears the query, and emits both
154
154
  `onChange` and `onSelectedItemsChange`.
155
155
 
156
- ## Modal and ConfirmDialog
156
+ ## Dialogs
157
157
 
158
158
  ```svelte
159
159
  <script lang="ts">
160
- import { ConfirmDialog, Modal } from '@ibobbyts/svelte-ui-utils/modal';
160
+ import { ConfirmDialog, Dialog, InputDialog } from '@ibobbyts/svelte-ui-utils/dialog';
161
161
 
162
- let modalOpen = false;
162
+ let dialogOpen = false;
163
163
  let confirmOpen = false;
164
+ let inputOpen = false;
165
+ let passwordOpen = false;
166
+ let name = '';
164
167
  </script>
165
168
 
166
- <button type="button" on:click={() => (modalOpen = true)}>Open modal</button>
169
+ <button type="button" on:click={() => (dialogOpen = true)}>Open dialog</button>
167
170
 
168
- <Modal
169
- open={modalOpen}
171
+ <Dialog
172
+ open={dialogOpen}
170
173
  title="Edit record"
171
174
  description="Update the shared fields."
172
175
  closeLabel="Close dialog"
173
- onClose={() => (modalOpen = false)}
176
+ blurBackdrop={true}
177
+ showCountdown={true}
178
+ countdownDurationMs={30000}
179
+ onClose={() => (dialogOpen = false)}
174
180
  >
175
181
  <p>Dialog body content goes here.</p>
176
182
  <svelte:fragment slot="footer">
177
- <button type="button" class="suu-modal__button" on:click={() => (modalOpen = false)}>Cancel</button>
178
- <button type="button" class="suu-modal__button suu-modal__button--primary">Save</button>
183
+ <button type="button" class="suu-dialog__button" on:click={() => (dialogOpen = false)}>Cancel</button>
184
+ <button type="button" class="suu-dialog__button suu-dialog__button--primary">Save</button>
179
185
  </svelte:fragment>
180
- </Modal>
186
+ </Dialog>
181
187
 
182
188
  <ConfirmDialog
183
189
  open={confirmOpen}
@@ -191,11 +197,38 @@ adds or removes it from `selectedItems`, clears the query, and emits both
191
197
  confirmOpen = false;
192
198
  }}
193
199
  />
200
+
201
+ <InputDialog
202
+ open={inputOpen}
203
+ title="Rename"
204
+ inputLabel="Name"
205
+ bind:inputValue={name}
206
+ onClose={() => (inputOpen = false)}
207
+ onConfirm={(value) => {
208
+ name = value;
209
+ inputOpen = false;
210
+ }}
211
+ />
212
+
213
+ <PasswordCopyDialog
214
+ open={passwordOpen}
215
+ title="Temporary password"
216
+ message="This value is shown only once."
217
+ value="Abc123xy"
218
+ valueLabel="Password"
219
+ copyLabel="Copy password"
220
+ copiedLabel="Copied"
221
+ doneLabel="Done"
222
+ onClose={() => (passwordOpen = false)}
223
+ />
194
224
  ```
195
225
 
196
- Both components are controlled by the consuming app. `Modal` calls `onClose`
226
+ Dialog components are controlled by the consuming app. `Dialog` calls `onClose`
197
227
  from the close button, backdrop, or Escape key when dismissible; it does not
198
- mutate `open` internally.
228
+ mutate `open` internally. Set `dimBackdrop={false}` to disable background
229
+ darkening, `blurBackdrop={true}` to blur content behind the dialog, and
230
+ `showCountdown={true}` with `countdownDurationMs` to show a toast-style top
231
+ countdown bar.
199
232
 
200
233
  ## Dropdown
201
234
 
@@ -1,8 +1,8 @@
1
1
  <svelte:options runes={false} />
2
2
 
3
3
  <script lang="ts">
4
- import Modal from './Modal.svelte';
5
- import type { ConfirmDialogIntent, ModalSize } from './types.js';
4
+ import Dialog from './Dialog.svelte';
5
+ import type { ConfirmDialogIntent, DialogSize } from './types.js';
6
6
 
7
7
  export let open = false;
8
8
  export let title = 'Confirm';
@@ -11,10 +11,19 @@
11
11
  export let cancelLabel = 'Cancel';
12
12
  export let closeLabel = 'Close dialog';
13
13
  export let intent: ConfirmDialogIntent = 'default';
14
- export let size: ModalSize = 'sm';
14
+ export let size: DialogSize = 'sm';
15
15
  export let confirmDisabled = false;
16
16
  export let cancelDisabled = false;
17
17
  export let dismissible = true;
18
+ export let closeOnBackdrop = true;
19
+ export let closeOnEscape = true;
20
+ export let dimBackdrop = true;
21
+ export let blurBackdrop = false;
22
+ export let backdropOpacity: number | string = 0.46;
23
+ export let backdropBlur = '6px';
24
+ export let showCountdown = false;
25
+ export let countdownDurationMs = 0;
26
+ export let countdownLabel = 'Dialog countdown';
18
27
  export let onConfirm: (() => void | Promise<void>) | undefined = undefined;
19
28
  export let onCancel: (() => void) | undefined = undefined;
20
29
  export let onClose: (() => void) | undefined = undefined;
@@ -33,13 +42,21 @@
33
42
  }
34
43
  </script>
35
44
 
36
- <Modal
45
+ <Dialog
37
46
  {open}
38
47
  {title}
39
48
  {closeLabel}
40
49
  {size}
41
50
  {dismissible}
42
- description={message}
51
+ {closeOnBackdrop}
52
+ {closeOnEscape}
53
+ {dimBackdrop}
54
+ {blurBackdrop}
55
+ {backdropOpacity}
56
+ {backdropBlur}
57
+ {showCountdown}
58
+ {countdownDurationMs}
59
+ {countdownLabel}
43
60
  onClose={handleClose}
44
61
  >
45
62
  <slot>
@@ -51,7 +68,7 @@
51
68
  <svelte:fragment slot="footer">
52
69
  <button
53
70
  type="button"
54
- class="suu-modal__button"
71
+ class="suu-dialog__button"
55
72
  disabled={cancelDisabled}
56
73
  on:click={handleCancel}
57
74
  >
@@ -59,11 +76,11 @@
59
76
  </button>
60
77
  <button
61
78
  type="button"
62
- class={`suu-modal__button suu-modal__button--primary suu-modal__button--${intent}`}
79
+ class={`suu-dialog__button suu-dialog__button--primary suu-dialog__button--${intent}`}
63
80
  disabled={confirmDisabled}
64
81
  on:click={handleConfirm}
65
82
  >
66
83
  {confirmLabel}
67
84
  </button>
68
85
  </svelte:fragment>
69
- </Modal>
86
+ </Dialog>
@@ -1,4 +1,4 @@
1
- import type { ConfirmDialogIntent, ModalSize } from './types.js';
1
+ import type { ConfirmDialogIntent, DialogSize } from './types.js';
2
2
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
4
  $$bindings?: Bindings;
@@ -25,10 +25,19 @@ declare const ConfirmDialog: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_P
25
25
  cancelLabel?: string;
26
26
  closeLabel?: string;
27
27
  intent?: ConfirmDialogIntent;
28
- size?: ModalSize;
28
+ size?: DialogSize;
29
29
  confirmDisabled?: boolean;
30
30
  cancelDisabled?: boolean;
31
31
  dismissible?: boolean;
32
+ closeOnBackdrop?: boolean;
33
+ closeOnEscape?: boolean;
34
+ dimBackdrop?: boolean;
35
+ blurBackdrop?: boolean;
36
+ backdropOpacity?: number | string;
37
+ backdropBlur?: string;
38
+ showCountdown?: boolean;
39
+ countdownDurationMs?: number;
40
+ countdownLabel?: string;
32
41
  onConfirm?: (() => void | Promise<void>) | undefined;
33
42
  onCancel?: (() => void) | undefined;
34
43
  onClose?: (() => void) | undefined;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/ConfirmDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAiElE,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AACD,KAAK,gCAAgC,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,GACvD,CAAC,KAAK,SAAS;IAAE,OAAO,EAAE,GAAG,CAAA;CAAE,GACzB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACnC,GAAG,GACH;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAE,GAClB,EAAE,CAAC,CAAC;AAId,QAAA,MAAM,aAAa;;;;;;;aAfqxB,mBAAmB;WAAS,UAAU;;;;;;;;sBAA8R,MAAM,GAAG,MAAM;;;;;gBAAkL,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS;eAAa,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;cAAY,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;;;;;;;cAetzC,CAAC;AACvF,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAe,aAAa,CAAC"}
@@ -0,0 +1,207 @@
1
+ <svelte:options runes={false} />
2
+
3
+ <script lang="ts">
4
+ import Dialog from './Dialog.svelte';
5
+ import type { DialogSize } from './types.js';
6
+
7
+ export let open = false;
8
+ export let title = 'Upload CSV';
9
+ export let description = '';
10
+ export let closeLabel = 'Close dialog';
11
+ export let size: DialogSize = 'lg';
12
+ export let dismissible = true;
13
+ export let closeOnBackdrop = true;
14
+ export let closeOnEscape = true;
15
+ export let dimBackdrop = true;
16
+ export let blurBackdrop = false;
17
+ export let backdropOpacity: number | string = 0.46;
18
+ export let backdropBlur = '6px';
19
+ export let templateUrl: string | undefined = undefined;
20
+ export let templateDownloadName: string | undefined = undefined;
21
+ export let downloadTemplateLabel = 'Download template';
22
+ export let fileLabel = 'Select CSV file';
23
+ export let uploadLabel = 'Upload';
24
+ export let cancelLabel = 'Cancel';
25
+ export let doneLabel = 'Done';
26
+ export let uploadAnotherLabel = 'Upload another';
27
+ export let instructionsTitle = 'Instructions';
28
+ export let instructions: string[] = [];
29
+ export let accept = '.csv,text/csv';
30
+ export let missingFileMessage = 'Please select a CSV file.';
31
+ export let uploadFailedMessage = 'Upload failed. Please try again.';
32
+ export let successMessage = 'Upload completed.';
33
+ export let externalError = '';
34
+ export let disabled = false;
35
+ export let onUpload: ((file: File) => void | Promise<void>) | undefined = undefined;
36
+ export let onCancel: (() => void) | undefined = undefined;
37
+ export let onClose: (() => void) | undefined = undefined;
38
+ export let onFileChange: ((file: File | null) => void) | undefined = undefined;
39
+
40
+ let selectedFile: File | null = null;
41
+ let fileInput: HTMLInputElement | undefined;
42
+ let localError = '';
43
+ let localUploading = false;
44
+ let uploadComplete = false;
45
+
46
+ $: isBusy = disabled || localUploading;
47
+ $: effectiveError = externalError || localError;
48
+
49
+ function resetFileState() {
50
+ selectedFile = null;
51
+ localError = '';
52
+ uploadComplete = false;
53
+ if (fileInput) {
54
+ fileInput.value = '';
55
+ }
56
+ onFileChange?.(null);
57
+ }
58
+
59
+ function handleClose() {
60
+ resetFileState();
61
+ onClose?.();
62
+ }
63
+
64
+ function handleCancel() {
65
+ resetFileState();
66
+ onCancel?.();
67
+ onClose?.();
68
+ }
69
+
70
+ function handleFileChange(event: Event) {
71
+ const target = event.currentTarget;
72
+ selectedFile = target instanceof HTMLInputElement
73
+ ? target.files?.[0] ?? null
74
+ : null;
75
+ localError = '';
76
+ uploadComplete = false;
77
+ onFileChange?.(selectedFile);
78
+ }
79
+
80
+ async function handleUpload() {
81
+ if (!selectedFile) {
82
+ localError = missingFileMessage;
83
+ return;
84
+ }
85
+
86
+ localError = '';
87
+ localUploading = true;
88
+
89
+ try {
90
+ await onUpload?.(selectedFile);
91
+ uploadComplete = true;
92
+ } catch (error) {
93
+ localError = error instanceof Error ? error.message : uploadFailedMessage;
94
+ } finally {
95
+ localUploading = false;
96
+ }
97
+ }
98
+ </script>
99
+
100
+ <Dialog
101
+ {open}
102
+ {title}
103
+ {description}
104
+ {closeLabel}
105
+ {size}
106
+ {dismissible}
107
+ {closeOnBackdrop}
108
+ {closeOnEscape}
109
+ {dimBackdrop}
110
+ {blurBackdrop}
111
+ {backdropOpacity}
112
+ {backdropBlur}
113
+ onClose={handleClose}
114
+ >
115
+ <div class="suu-csv-upload-dialog">
116
+ {#if templateUrl}
117
+ <div class="suu-csv-upload-dialog__center">
118
+ <a
119
+ class="suu-dialog__button"
120
+ href={templateUrl}
121
+ download={templateDownloadName}
122
+ >
123
+ {downloadTemplateLabel}
124
+ </a>
125
+ </div>
126
+ {/if}
127
+
128
+ <label class="suu-csv-upload-dialog__field">
129
+ <span>{fileLabel}</span>
130
+ <input
131
+ bind:this={fileInput}
132
+ type="file"
133
+ {accept}
134
+ disabled={isBusy}
135
+ on:change={handleFileChange}
136
+ />
137
+ </label>
138
+
139
+ {#if selectedFile}
140
+ <p class="suu-csv-upload-dialog__selected">{selectedFile.name}</p>
141
+ {/if}
142
+
143
+ {#if $$slots.preview}
144
+ <slot name="preview" file={selectedFile} uploading={localUploading} complete={uploadComplete} />
145
+ {/if}
146
+
147
+ {#if effectiveError}
148
+ <div class="suu-dialog__alert suu-dialog__alert--error" role="alert">
149
+ {effectiveError}
150
+ </div>
151
+ {/if}
152
+
153
+ {#if localUploading}
154
+ <div class="suu-dialog__status" role="status">
155
+ <span class="suu-dialog__spinner" aria-hidden="true"></span>
156
+ <span>{uploadLabel}...</span>
157
+ </div>
158
+ {/if}
159
+
160
+ {#if uploadComplete}
161
+ <div class="suu-dialog__alert suu-dialog__alert--success" role="status">
162
+ {successMessage}
163
+ </div>
164
+ {/if}
165
+
166
+ {#if instructions.length > 0}
167
+ <section class="suu-csv-upload-dialog__instructions" aria-label={instructionsTitle}>
168
+ <h3>{instructionsTitle}</h3>
169
+ <ul>
170
+ {#each instructions as instruction}
171
+ <li>{instruction}</li>
172
+ {/each}
173
+ </ul>
174
+ </section>
175
+ {/if}
176
+ </div>
177
+
178
+ <svelte:fragment slot="footer">
179
+ <button
180
+ type="button"
181
+ class="suu-dialog__button"
182
+ disabled={isBusy}
183
+ on:click={handleCancel}
184
+ >
185
+ {uploadComplete ? doneLabel : cancelLabel}
186
+ </button>
187
+ {#if uploadComplete}
188
+ <button
189
+ type="button"
190
+ class="suu-dialog__button suu-dialog__button--primary"
191
+ disabled={isBusy}
192
+ on:click={resetFileState}
193
+ >
194
+ {uploadAnotherLabel}
195
+ </button>
196
+ {:else}
197
+ <button
198
+ type="button"
199
+ class="suu-dialog__button suu-dialog__button--primary"
200
+ disabled={isBusy || !selectedFile}
201
+ on:click={handleUpload}
202
+ >
203
+ {uploadLabel}
204
+ </button>
205
+ {/if}
206
+ </svelte:fragment>
207
+ </Dialog>
@@ -0,0 +1,59 @@
1
+ import type { DialogSize } from './types.js';
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: Props & {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const CsvUploadDialog: $$__sveltets_2_IsomorphicComponent<{
16
+ open?: boolean;
17
+ title?: string;
18
+ description?: string;
19
+ closeLabel?: string;
20
+ size?: DialogSize;
21
+ dismissible?: boolean;
22
+ closeOnBackdrop?: boolean;
23
+ closeOnEscape?: boolean;
24
+ dimBackdrop?: boolean;
25
+ blurBackdrop?: boolean;
26
+ backdropOpacity?: number | string;
27
+ backdropBlur?: string;
28
+ templateUrl?: string | undefined;
29
+ templateDownloadName?: string | undefined;
30
+ downloadTemplateLabel?: string;
31
+ fileLabel?: string;
32
+ uploadLabel?: string;
33
+ cancelLabel?: string;
34
+ doneLabel?: string;
35
+ uploadAnotherLabel?: string;
36
+ instructionsTitle?: string;
37
+ instructions?: string[];
38
+ accept?: string;
39
+ missingFileMessage?: string;
40
+ uploadFailedMessage?: string;
41
+ successMessage?: string;
42
+ externalError?: string;
43
+ disabled?: boolean;
44
+ onUpload?: ((file: File) => void | Promise<void>) | undefined;
45
+ onCancel?: (() => void) | undefined;
46
+ onClose?: (() => void) | undefined;
47
+ onFileChange?: ((file: File | null) => void) | undefined;
48
+ }, {
49
+ [evt: string]: CustomEvent<any>;
50
+ }, {
51
+ preview: {
52
+ file: null;
53
+ uploading: boolean;
54
+ complete: boolean;
55
+ };
56
+ }, {}, string>;
57
+ type CsvUploadDialog = InstanceType<typeof CsvUploadDialog>;
58
+ export default CsvUploadDialog;
59
+ //# sourceMappingURL=CsvUploadDialog.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CsvUploadDialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/CsvUploadDialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA6K7C,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAUD,QAAA,MAAM,eAAe;;;;;WAfggC,UAAU;;;;;;sBAA4M,MAAM,GAAG,MAAM;;kBAAoD,MAAM,GAAG,SAAS;2BAAyB,MAAM,GAAG,SAAS;;;;;;;;mBAAqS,MAAM,EAAE;;;;;;;eAAiP,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS;eAAa,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;cAAY,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;mBAAiB,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS;;;;;;;;;cAep9D,CAAC;AACzF,KAAK,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;AAC9D,eAAe,eAAe,CAAC"}
@@ -2,29 +2,40 @@
2
2
 
3
3
  <script lang="ts">
4
4
  import { tick } from 'svelte';
5
- import type { ModalSize } from './types.js';
5
+ import type { DialogSize } from './types.js';
6
6
 
7
7
  export let open = false;
8
8
  export let title = '';
9
9
  export let description = '';
10
10
  export let closeLabel = 'Close dialog';
11
- export let size: ModalSize = 'md';
11
+ export let size: DialogSize = 'md';
12
12
  export let dismissible = true;
13
+ export let showCloseButton = true;
13
14
  export let closeOnBackdrop = true;
14
15
  export let closeOnEscape = true;
16
+ export let dimBackdrop = true;
17
+ export let blurBackdrop = false;
18
+ export let backdropOpacity: number | string = 0.46;
19
+ export let backdropBlur = '6px';
20
+ export let showCountdown = false;
21
+ export let countdownDurationMs = 0;
22
+ export let countdownLabel = 'Dialog countdown';
15
23
  export let labelledBy: string | undefined = undefined;
16
24
  export let describedBy: string | undefined = undefined;
17
25
  export let onClose: (() => void) | undefined = undefined;
18
26
 
19
27
  let dialogElement: HTMLElement | undefined;
20
- let titleId = `suu-modal-title-${Math.random().toString(36).slice(2)}`;
21
- let descriptionId = `suu-modal-description-${Math.random().toString(36).slice(2)}`;
28
+ let titleId = `suu-dialog-title-${Math.random().toString(36).slice(2)}`;
29
+ let descriptionId = `suu-dialog-description-${Math.random().toString(36).slice(2)}`;
22
30
  let wasOpen = false;
23
31
  let previouslyFocusedElement: HTMLElement | null = null;
24
32
 
25
33
  $: resolvedLabelledBy = labelledBy ?? (title ? titleId : undefined);
26
34
  $: resolvedDescribedBy =
27
35
  describedBy ?? (description ? descriptionId : undefined);
36
+ $: backdropStyle =
37
+ `--suu-dialog-backdrop-opacity: ${backdropOpacity}; --suu-dialog-backdrop-blur: ${backdropBlur};`;
38
+ $: countdownStyle = `--suu-dialog-countdown-duration: ${Math.max(0, countdownDurationMs)}ms;`;
28
39
  $: if (open && !wasOpen) {
29
40
  wasOpen = true;
30
41
  void focusDialog();
@@ -67,7 +78,7 @@
67
78
  }
68
79
 
69
80
  function handleKeydown(event: KeyboardEvent) {
70
- if (event.key === 'Escape' && closeOnEscape) {
81
+ if (open && event.key === 'Escape' && closeOnEscape) {
71
82
  event.preventDefault();
72
83
  requestClose();
73
84
  }
@@ -78,34 +89,45 @@
78
89
 
79
90
  {#if open}
80
91
  <div
81
- class="suu-modal-backdrop"
92
+ class="suu-dialog-backdrop"
93
+ data-dimmed={dimBackdrop ? 'true' : 'false'}
94
+ data-blurred={blurBackdrop ? 'true' : 'false'}
95
+ style={backdropStyle}
82
96
  role="presentation"
83
97
  on:mousedown={handleBackdropMouseDown}
84
98
  >
85
99
  <div
86
100
  bind:this={dialogElement}
87
- class={`suu-modal suu-modal--${size}`}
101
+ class={`suu-dialog suu-dialog--${size}`}
88
102
  role="dialog"
89
103
  aria-modal="true"
90
104
  aria-labelledby={resolvedLabelledBy}
91
105
  aria-describedby={resolvedDescribedBy}
92
106
  tabindex="-1"
93
107
  >
94
- <header class="suu-modal__header">
95
- <div class="suu-modal__heading">
108
+ {#if showCountdown && countdownDurationMs > 0}
109
+ <div
110
+ class="suu-dialog__countdown"
111
+ style={countdownStyle}
112
+ role="timer"
113
+ aria-label={countdownLabel}
114
+ ></div>
115
+ {/if}
116
+ <header class="suu-dialog__header">
117
+ <div class="suu-dialog__heading">
96
118
  {#if title}
97
- <h2 class="suu-modal__title" id={titleId}>{title}</h2>
119
+ <h2 class="suu-dialog__title" id={titleId}>{title}</h2>
98
120
  {/if}
99
121
  {#if description}
100
- <p class="suu-modal__description" id={descriptionId}>
122
+ <p class="suu-dialog__description" id={descriptionId}>
101
123
  {description}
102
124
  </p>
103
125
  {/if}
104
126
  </div>
105
- {#if dismissible}
127
+ {#if showCloseButton && dismissible}
106
128
  <button
107
129
  type="button"
108
- class="suu-modal__close"
130
+ class="suu-dialog__close"
109
131
  aria-label={closeLabel}
110
132
  title={closeLabel}
111
133
  on:click={requestClose}
@@ -117,12 +139,12 @@
117
139
  {/if}
118
140
  </header>
119
141
 
120
- <div class="suu-modal__body">
142
+ <div class="suu-dialog__body">
121
143
  <slot />
122
144
  </div>
123
145
 
124
146
  {#if $$slots.footer}
125
- <footer class="suu-modal__footer">
147
+ <footer class="suu-dialog__footer">
126
148
  <slot name="footer" />
127
149
  </footer>
128
150
  {/if}
@@ -1,4 +1,4 @@
1
- import type { ModalSize } from './types.js';
1
+ import type { DialogSize } from './types.js';
2
2
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
4
  $$bindings?: Bindings;
@@ -17,15 +17,23 @@ type $$__sveltets_2_PropsWithChildren<Props, Slots> = Props & (Slots extends {
17
17
  } ? Props extends Record<string, never> ? any : {
18
18
  children?: any;
19
19
  } : {});
20
- declare const Modal: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
20
+ declare const Dialog: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWithChildren<{
21
21
  open?: boolean;
22
22
  title?: string;
23
23
  description?: string;
24
24
  closeLabel?: string;
25
- size?: ModalSize;
25
+ size?: DialogSize;
26
26
  dismissible?: boolean;
27
+ showCloseButton?: boolean;
27
28
  closeOnBackdrop?: boolean;
28
29
  closeOnEscape?: boolean;
30
+ dimBackdrop?: boolean;
31
+ blurBackdrop?: boolean;
32
+ backdropOpacity?: number | string;
33
+ backdropBlur?: string;
34
+ showCountdown?: boolean;
35
+ countdownDurationMs?: number;
36
+ countdownLabel?: string;
29
37
  labelledBy?: string | undefined;
30
38
  describedBy?: string | undefined;
31
39
  onClose?: (() => void) | undefined;
@@ -38,6 +46,6 @@ declare const Modal: $$__sveltets_2_IsomorphicComponent<$$__sveltets_2_PropsWith
38
46
  default: {};
39
47
  footer: {};
40
48
  }, {}, string>;
41
- type Modal = InstanceType<typeof Modal>;
42
- export default Modal;
43
- //# sourceMappingURL=Modal.svelte.d.ts.map
49
+ type Dialog = InstanceType<typeof Dialog>;
50
+ export default Dialog;
51
+ //# sourceMappingURL=Dialog.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dialog.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dialog/Dialog.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAoI7C,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AACD,KAAK,gCAAgC,CAAC,KAAK,EAAE,KAAK,IAAI,KAAK,GACvD,CAAC,KAAK,SAAS;IAAE,OAAO,EAAE,GAAG,CAAA;CAAE,GACzB,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACnC,GAAG,GACH;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAA;CAAE,GAClB,EAAE,CAAC,CAAC;AAId,QAAA,MAAM,MAAM;;;;;WAfkoB,UAAU;;;;;;;sBAAsP,MAAM,GAAG,MAAM;;;;;iBAAmL,MAAM,GAAG,SAAS;kBAAgB,MAAM,GAAG,SAAS;cAAY,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS;;;;;;;;;cAevkC,CAAC;AAChF,KAAK,MAAM,GAAG,YAAY,CAAC,OAAO,MAAM,CAAC,CAAC;AAC5C,eAAe,MAAM,CAAC"}