@softwareone/spi-sv5-library 1.6.0 → 1.7.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.
@@ -0,0 +1,79 @@
1
+ <script lang="ts">
2
+ import { Button, Input, Modal, Spinner, addToast } from '../index.js';
3
+
4
+ interface DeleteConfirmationProps {
5
+ confirmationName?: string;
6
+ enableDoubleConfirmation?: boolean;
7
+ showModal?: boolean;
8
+ ondelete: () => Promise<boolean> | boolean;
9
+ onclose?: VoidFunction;
10
+ ondeleteSuccess?: VoidFunction;
11
+ }
12
+
13
+ let {
14
+ confirmationName = '',
15
+ enableDoubleConfirmation = false,
16
+ showModal = $bindable(false),
17
+ ondelete,
18
+ onclose,
19
+ ondeleteSuccess
20
+ }: DeleteConfirmationProps = $props();
21
+
22
+ let confirmationText = $derived(
23
+ `Are you sure you want to delete ${confirmationName || 'this item'}?`
24
+ );
25
+ let value = $state('');
26
+ let isLoading = $state(false);
27
+ let enableButton = $derived(!enableDoubleConfirmation || confirmationName === value);
28
+
29
+ const handleDelete = async () => {
30
+ isLoading = true;
31
+ const isSuccessful = await ondelete();
32
+ isLoading = false;
33
+
34
+ if (isSuccessful) {
35
+ showModal = false;
36
+ ondeleteSuccess?.();
37
+ } else {
38
+ addToast({ message: 'There was an unexpected error.', type: 'danger' });
39
+ }
40
+ };
41
+ </script>
42
+
43
+ <Modal title="Delete confirmation" bind:showModal {onclose}>
44
+ <Spinner show={isLoading} />
45
+ <div class="content">
46
+ <p>{confirmationText}</p>
47
+ {#if enableDoubleConfirmation}
48
+ <p>
49
+ To confirm, type "<strong>{confirmationName}</strong>" in the box below
50
+ </p>
51
+ <Input
52
+ type="text"
53
+ bind:value
54
+ disableValidationColor
55
+ onpaste={(event) => event.preventDefault()}
56
+ placeholder="Type confirmation name"
57
+ />
58
+ {/if}
59
+ </div>
60
+
61
+ {#snippet footer()}
62
+ <Button variant="primary" variantColor="danger" disabled={!enableButton} onclick={handleDelete}>
63
+ Delete
64
+ </Button>
65
+ {/snippet}
66
+ </Modal>
67
+
68
+ <style>
69
+ .content {
70
+ display: flex;
71
+ flex-direction: column;
72
+ gap: 16px;
73
+ }
74
+
75
+ p {
76
+ margin: 0;
77
+ user-select: none;
78
+ }
79
+ </style>
@@ -0,0 +1,11 @@
1
+ interface DeleteConfirmationProps {
2
+ confirmationName?: string;
3
+ enableDoubleConfirmation?: boolean;
4
+ showModal?: boolean;
5
+ ondelete: () => Promise<boolean> | boolean;
6
+ onclose?: VoidFunction;
7
+ ondeleteSuccess?: VoidFunction;
8
+ }
9
+ declare const DeleteConfirmation: import("svelte").Component<DeleteConfirmationProps, {}, "showModal">;
10
+ type DeleteConfirmation = ReturnType<typeof DeleteConfirmation>;
11
+ export default DeleteConfirmation;
@@ -12,7 +12,7 @@
12
12
  width = 'xs',
13
13
  errorIcon,
14
14
  hideHeader,
15
- onclose = () => {},
15
+ onclose,
16
16
  children,
17
17
  footer,
18
18
  disablePadding
@@ -20,7 +20,7 @@
20
20
 
21
21
  const onHandleClose = () => {
22
22
  showModal = false;
23
- onclose();
23
+ onclose?.();
24
24
  };
25
25
  </script>
26
26
 
@@ -7,12 +7,14 @@
7
7
  tabs: Tab[];
8
8
  activeTab?: number;
9
9
  children?: Snippet;
10
+ onchange?: (index: number) => void;
10
11
  }
11
12
 
12
- let { tabs = [], activeTab = 0, children }: TabsProps = $props();
13
+ let { tabs = [], activeTab = 0, children, onchange }: TabsProps = $props();
13
14
 
14
15
  const handleClick = (index: number) => (): void => {
15
16
  activeTab = index;
17
+ onchange?.(index);
16
18
  };
17
19
  </script>
18
20
 
@@ -39,18 +41,18 @@
39
41
 
40
42
  {#each tabs as tab}
41
43
  {#if activeTab === tab.index}
42
- {#if tab.component}
43
- <div
44
- class="tabs-content"
45
- id="panel-{tab.index}"
46
- role="tabpanel"
47
- aria-labelledby="tab-{tab.index}"
48
- >
44
+ <div
45
+ class="tabs-content"
46
+ id="panel-{tab.index}"
47
+ role="tabpanel"
48
+ aria-labelledby="tab-{tab.index}"
49
+ >
50
+ {#if tab.component}
49
51
  {@render tab.component()}
50
- </div>
51
- {:else}
52
- {@render children?.()}
53
- {/if}
52
+ {:else}
53
+ {@render children?.()}
54
+ {/if}
55
+ </div>
54
56
  {/if}
55
57
  {/each}
56
58
  </div>
@@ -4,6 +4,7 @@ interface TabsProps {
4
4
  tabs: Tab[];
5
5
  activeTab?: number;
6
6
  children?: Snippet;
7
+ onchange?: (index: number) => void;
7
8
  }
8
9
  declare const Tabs: import("svelte").Component<TabsProps, {}, "">;
9
10
  type Tabs = ReturnType<typeof Tabs>;
@@ -25,7 +25,7 @@
25
25
  {#if toastNotifications.toasts.length > 0}
26
26
  <div class="toast-container" in:fly={transitionConfig} out:fly={transitionConfig}>
27
27
  {#each toastNotifications.toasts as toast}
28
- <div class="toast {toast.width ?? 'sm'}" in:fly={transitionConfig} out:fly={transitionConfig}>
28
+ <div class="toast" in:fly={transitionConfig} out:fly={transitionConfig}>
29
29
  <span class="status-indicator {toast.type}"></span>
30
30
  <div class="toast-content-container">
31
31
  <div class="toast-content">
@@ -61,8 +61,10 @@
61
61
  }
62
62
 
63
63
  .toast {
64
- width: var(--toast-width);
65
- height: var(--toast-height);
64
+ min-width: 400px;
65
+ max-width: 600px;
66
+ width: fit-content;
67
+ min-height: 52px;
66
68
  display: inline-flex;
67
69
  padding: 8px;
68
70
  gap: 16px;
@@ -75,31 +77,17 @@
75
77
  0px 1px 16px 0px rgba(51, 56, 64, 0.1);
76
78
  }
77
79
 
78
- .toast.sm {
79
- --toast-width: 400px;
80
- --toast-height: 52px;
81
- --toast-flex-direction: row;
82
- --toast-gap: 8px;
83
- --toast-close-button-align: center;
84
- }
85
-
86
- .toast.md {
87
- --toast-width: 600px;
88
- --toast-height: 88px;
89
- --toast-flex-direction: column;
90
- --toast-gap: 4px;
91
- --toast-close-button-align: flex-start;
92
- }
93
-
94
80
  .toast-content {
95
81
  display: flex;
96
82
  justify-content: space-between;
97
- flex-direction: var(--toast-flex-direction);
98
- gap: var(--toast-gap);
83
+ flex-direction: row;
84
+ flex-wrap: wrap;
85
+ gap: 8px;
99
86
  padding: 8px 0px;
100
87
  font-size: 14px;
101
88
  font-weight: 400;
102
89
  line-height: 20px;
90
+ align-items: center;
103
91
  }
104
92
 
105
93
  .toast-content-container {
@@ -111,7 +99,7 @@
111
99
 
112
100
  .status-indicator {
113
101
  width: 8px;
114
- height: calc(var(--toast-height) - 20px);
102
+ align-self: stretch;
115
103
  flex-shrink: 0;
116
104
  border-radius: 4px;
117
105
  background-color: var(--toast-bg);
@@ -147,7 +135,7 @@
147
135
 
148
136
  .toast-close-container {
149
137
  display: flex;
150
- align-items: var(--toast-close-button-align);
138
+ align-items: center;
151
139
  }
152
140
 
153
141
  .toast-close-button {
@@ -1,9 +1,7 @@
1
1
  type ToastType = 'info' | 'success' | 'warning' | 'danger' | 'neutral';
2
- type ToastWidth = 'sm' | 'md';
3
2
  export interface Toast {
4
3
  type: ToastType;
5
4
  message: string;
6
- width?: ToastWidth;
7
5
  link?: string;
8
6
  }
9
7
  interface ToastState extends Toast {
@@ -1,3 +1,4 @@
1
+ import { untrack } from 'svelte';
1
2
  const toastState = $state({
2
3
  toasts: [],
3
4
  duration: 5000
@@ -9,9 +10,11 @@ export const getToast = (duration) => {
9
10
  return toastState;
10
11
  };
11
12
  export const addToast = (toast) => {
12
- const newToast = { ...toast, id: crypto.randomUUID() };
13
- toastState.toasts.push(newToast);
14
- scheduleToastRemoval(newToast.id);
13
+ untrack(() => {
14
+ const newToast = { ...toast, id: crypto.randomUUID() };
15
+ toastState.toasts.push(newToast);
16
+ scheduleToastRemoval(newToast.id);
17
+ });
15
18
  };
16
19
  const scheduleToastRemoval = (id) => {
17
20
  setTimeout(() => {
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import Breadcrumbs from './Breadcrumbs/Breadcrumbs.svelte';
4
4
  import Button from './Button/Button.svelte';
5
5
  import Card from './Card/Card.svelte';
6
6
  import Chips from './Chips/Chips.svelte';
7
+ import DeleteConfirmationModal from './DeleteConfirmation/DeleteConfirmation.svelte';
7
8
  import ErrorPage from './ErrorPage/ErrorPage.svelte';
8
9
  import Footer from './Footer/Footer.svelte';
9
10
  import Form from './Form/FormController/Form.svelte';
@@ -57,4 +58,4 @@ import type { Toast } from './Toast/toastState.svelte';
57
58
  import type { WaffleItem } from './Waffle/waffleState.svelte.js';
58
59
  import type { AttachFileFormConfig, FileValidationCallback } from './Form/AttachFile/attachFile.svelte.js';
59
60
  import type { NotificationProps } from './Notification/notificationState.svelte.js';
60
- export { Accordion, Avatar, Breadcrumbs, Button, Card, Chips, ErrorPage, Footer, Form, Header, HeaderAccount, HeaderLoader, HeaderLogo, HighlightPanel, Home, Input, Link, Menu, Modal, Notification, Processing, ProgressPage, ProgressWizard, Search, Select, Sidebar, Spinner, Switcher, Tabs, TextArea, Toaster, Toggle, Tooltip, Waffle, AttachFile, addBreadcrumbsNameMap, addToast, getProgressWizardContext, setProgressWizardStepsContext, setStepValidity, setFormContext, getFormContext, validateSchema, createZodString, getSidebarItemsFromMenu, ChipType, ColumnType, ImageType, type BreadcrumbsNameMap, type HighlightPanelColumn, type HomeItem, type MainMenu, type MenuItem, type ModalProps, type ProgressWizardStep, type SelectOption, type SwitcherOption, type Tab, type Toast, type WaffleItem, type FormError, type FormContext, type SidebarItem, type AttachFileFormConfig, type FileValidationCallback, type NotificationProps };
61
+ export { Accordion, Avatar, Breadcrumbs, Button, Card, Chips, DeleteConfirmationModal, ErrorPage, Footer, Form, Header, HeaderAccount, HeaderLoader, HeaderLogo, HighlightPanel, Home, Input, Link, Menu, Modal, Notification, Processing, ProgressPage, ProgressWizard, Search, Select, Sidebar, Spinner, Switcher, Tabs, TextArea, Toaster, Toggle, Tooltip, Waffle, AttachFile, addBreadcrumbsNameMap, addToast, getProgressWizardContext, setProgressWizardStepsContext, setStepValidity, setFormContext, getFormContext, validateSchema, createZodString, getSidebarItemsFromMenu, ChipType, ColumnType, ImageType, type BreadcrumbsNameMap, type HighlightPanelColumn, type HomeItem, type MainMenu, type MenuItem, type ModalProps, type ProgressWizardStep, type SelectOption, type SwitcherOption, type Tab, type Toast, type WaffleItem, type FormError, type FormContext, type SidebarItem, type AttachFileFormConfig, type FileValidationCallback, type NotificationProps };
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import Breadcrumbs from './Breadcrumbs/Breadcrumbs.svelte';
5
5
  import Button from './Button/Button.svelte';
6
6
  import Card from './Card/Card.svelte';
7
7
  import Chips from './Chips/Chips.svelte';
8
+ import DeleteConfirmationModal from './DeleteConfirmation/DeleteConfirmation.svelte';
8
9
  import ErrorPage from './ErrorPage/ErrorPage.svelte';
9
10
  import Footer from './Footer/Footer.svelte';
10
11
  import Form from './Form/FormController/Form.svelte';
@@ -47,7 +48,7 @@ import { createZodString } from './Form/FormController/zod-validations.js';
47
48
  import { getSidebarItemsFromMenu } from './Menu/MenuState.svelte';
48
49
  export {
49
50
  // Components
50
- Accordion, Avatar, Breadcrumbs, Button, Card, Chips, ErrorPage, Footer, Form, Header, HeaderAccount, HeaderLoader, HeaderLogo, HighlightPanel, Home, Input, Link, Menu, Modal, Notification, Processing, ProgressPage, ProgressWizard, Search, Select, Sidebar, Spinner, Switcher, Tabs, TextArea, Toaster, Toggle, Tooltip, Waffle, AttachFile,
51
+ Accordion, Avatar, Breadcrumbs, Button, Card, Chips, DeleteConfirmationModal, ErrorPage, Footer, Form, Header, HeaderAccount, HeaderLoader, HeaderLogo, HighlightPanel, Home, Input, Link, Menu, Modal, Notification, Processing, ProgressPage, ProgressWizard, Search, Select, Sidebar, Spinner, Switcher, Tabs, TextArea, Toaster, Toggle, Tooltip, Waffle, AttachFile,
51
52
  // Functions and helpers
52
53
  addBreadcrumbsNameMap, addToast, getProgressWizardContext, setProgressWizardStepsContext, setStepValidity, setFormContext, getFormContext, validateSchema, createZodString, getSidebarItemsFromMenu,
53
54
  // Enums
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softwareone/spi-sv5-library",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Svelte components",
5
5
  "keywords": [
6
6
  "svelte",