@softwareone/spi-sv5-library 1.3.1 → 1.4.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.
Files changed (35) hide show
  1. package/dist/Form/Label.svelte +1 -3
  2. package/dist/Form/Select/Select.svelte +110 -95
  3. package/dist/Form/Toggle/Toggle.svelte +56 -21
  4. package/dist/Form/Toggle/Toggle.svelte.d.ts +3 -0
  5. package/dist/Header/Header.svelte +81 -24
  6. package/dist/Header/Header.svelte.d.ts +2 -1
  7. package/dist/Home/Home.svelte +6 -12
  8. package/dist/Menu/Menu.svelte +9 -50
  9. package/dist/Menu/Menu.svelte.d.ts +1 -1
  10. package/dist/Menu/MenuItem.svelte +2 -14
  11. package/dist/Menu/MenuItem.svelte.d.ts +0 -1
  12. package/dist/Modal/Modal.svelte +32 -23
  13. package/dist/Modal/ModalContent.svelte +7 -4
  14. package/dist/Modal/ModalContent.svelte.d.ts +1 -0
  15. package/dist/Modal/ModalHeader.svelte +14 -10
  16. package/dist/Modal/modalState.svelte.d.ts +2 -0
  17. package/dist/Processing/Processing.svelte +89 -0
  18. package/dist/Processing/Processing.svelte.d.ts +4 -0
  19. package/dist/Processing/processingState.svelte.d.ts +6 -0
  20. package/dist/Processing/processingState.svelte.js +1 -0
  21. package/dist/ProgressWizard/ProgressWizard.svelte +0 -1
  22. package/dist/Spinner/Spinner.svelte +1 -0
  23. package/dist/Switcher/Switcher.svelte +78 -0
  24. package/dist/Switcher/Switcher.svelte.d.ts +8 -0
  25. package/dist/Switcher/switcherState.svelte.d.ts +4 -0
  26. package/dist/Switcher/switcherState.svelte.js +1 -0
  27. package/dist/Waffle/Waffle.svelte +95 -0
  28. package/dist/Waffle/Waffle.svelte.d.ts +8 -0
  29. package/dist/Waffle/WaffleItems.svelte +82 -0
  30. package/dist/Waffle/WaffleItems.svelte.d.ts +9 -0
  31. package/dist/Waffle/waffleState.svelte.d.ts +6 -0
  32. package/dist/Waffle/waffleState.svelte.js +1 -0
  33. package/dist/index.d.ts +6 -1
  34. package/dist/index.js +4 -1
  35. package/package.json +1 -1
@@ -6,21 +6,13 @@
6
6
  import type { MenuItem } from './SidebarState.svelte';
7
7
 
8
8
  interface MenuProps {
9
- disableMenuButton?: boolean;
10
9
  menuItems: MenuItem[];
10
+ showMenu: boolean;
11
11
  }
12
12
 
13
- let showMenu: boolean = $state(false);
14
- let isMainMenu: boolean = $state(true);
15
- let activeItem: string = $state('');
13
+ let { menuItems, showMenu }: MenuProps = $props();
16
14
 
17
- const { disableMenuButton = false, menuItems }: MenuProps = $props();
18
-
19
- $effect(() => {
20
- if (showMenu) {
21
- setActiveMenuItem();
22
- }
23
- });
15
+ let activeItem = $state('');
24
16
 
25
17
  const setActiveMenuItem = () => {
26
18
  activeItem = menuItems.find((menuItem: MenuItem) => isActiveMenuItem(menuItem.url))?.text || '';
@@ -44,18 +36,13 @@
44
36
  const onHandleMenu = () => {
45
37
  showMenu = !showMenu;
46
38
  };
47
- </script>
48
39
 
49
- <button
50
- type="button"
51
- class="menu-button"
52
- class:disabled-menu={disableMenuButton}
53
- onclick={onHandleMenu}
54
- disabled={disableMenuButton}
55
- aria-label="menu button"
56
- >
57
- <span class="material-icons icon-span">menu</span>
58
- </button>
40
+ $effect(() => {
41
+ if (showMenu) {
42
+ setActiveMenuItem();
43
+ }
44
+ });
45
+ </script>
59
46
 
60
47
  {#if showMenu}
61
48
  <button
@@ -72,7 +59,6 @@
72
59
  item={menuItem}
73
60
  isCollapsed={false}
74
61
  activeItem={activeItem === menuItem.text}
75
- {isMainMenu}
76
62
  onClick={onClickMenuItem}
77
63
  />
78
64
  {/each}
@@ -81,28 +67,6 @@
81
67
  {/if}
82
68
 
83
69
  <style>
84
- .menu-button {
85
- display: flex;
86
- justify-content: center;
87
- align-items: center;
88
- border-radius: 50%;
89
- background: white;
90
- z-index: 40;
91
- cursor: pointer;
92
- border: none;
93
- width: 40px;
94
- height: 40px;
95
- }
96
-
97
- .menu-button:hover {
98
- background: #e0e5e8;
99
- }
100
-
101
- .icon-span {
102
- font-size: 32px;
103
- color: #6b7180;
104
- }
105
-
106
70
  .menu-principal {
107
71
  position: fixed;
108
72
  inset: 0;
@@ -138,11 +102,6 @@
138
102
  overflow-x: hidden;
139
103
  }
140
104
 
141
- .disabled-menu {
142
- cursor: not-allowed;
143
- opacity: 0.5;
144
- }
145
-
146
105
  @media (min-width: 768px) {
147
106
  .menu-list {
148
107
  min-width: 220px;
@@ -1,7 +1,7 @@
1
1
  import type { MenuItem } from './SidebarState.svelte';
2
2
  interface MenuProps {
3
- disableMenuButton?: boolean;
4
3
  menuItems: MenuItem[];
4
+ showMenu: boolean;
5
5
  }
6
6
  declare const Menu: import("svelte").Component<MenuProps, {}, "">;
7
7
  type Menu = ReturnType<typeof Menu>;
@@ -7,10 +7,9 @@
7
7
  isCollapsed: boolean;
8
8
  onClick?: (item: MenuItem) => void;
9
9
  activeItem: boolean;
10
- isMainMenu?: boolean;
11
10
  }
12
11
 
13
- let { item, isCollapsed = false, onClick, activeItem, isMainMenu }: MenuItemProps = $props();
12
+ let { item, isCollapsed = false, onClick, activeItem }: MenuItemProps = $props();
14
13
  </script>
15
14
 
16
15
  <li>
@@ -20,8 +19,7 @@
20
19
  class={[
21
20
  'item',
22
21
  isCollapsed ? 'collapsed' : 'expanded',
23
- activeItem && `active-${isCollapsed ? 'collapsed' : 'expanded'}`,
24
- isMainMenu && 'main-menu'
22
+ activeItem && `active-${isCollapsed ? 'collapsed' : 'expanded'}`
25
23
  ]}
26
24
  onclick={() => onClick?.(item)}
27
25
  >
@@ -108,16 +106,6 @@
108
106
  color: #472aff;
109
107
  }
110
108
 
111
- .main-menu.expanded:hover:not(.active-expanded),
112
- .main-menu.collapsed:hover:not(.active-collapsed) {
113
- background-color: #eaecff;
114
- }
115
-
116
- .main-menu:hover .item-name-span,
117
- .main-menu:hover .icon-span {
118
- color: #472aff;
119
- }
120
-
121
109
  .item.collapsed:focus,
122
110
  .item.collapsed:focus-visible {
123
111
  outline: none;
@@ -4,7 +4,6 @@ interface MenuItemProps {
4
4
  isCollapsed: boolean;
5
5
  onClick?: (item: MenuItem) => void;
6
6
  activeItem: boolean;
7
- isMainMenu?: boolean;
8
7
  }
9
8
  declare const MenuItem: import("svelte").Component<MenuItemProps, {}, "">;
10
9
  type MenuItem = ReturnType<typeof MenuItem>;
@@ -11,9 +11,11 @@
11
11
  title,
12
12
  width = 'xs',
13
13
  errorIcon,
14
+ hideHeader,
14
15
  onclose = () => {},
15
16
  children,
16
- footer
17
+ footer,
18
+ disablePadding
17
19
  }: ModalProps = $props();
18
20
 
19
21
  const onHandleClose = () => {
@@ -22,34 +24,37 @@
22
24
  };
23
25
  </script>
24
26
 
25
- <div class="modal-container">
26
- <div
27
- onclose={onHandleClose}
28
- class="modal {width}"
29
- transition:scale={{
30
- duration: 150,
31
- start: 0.95
32
- }}
33
- >
34
- <ModalHeader {title} {errorIcon} onclose={onHandleClose} />
35
- <ModalContent content={children} />
36
- <ModalFooter {footer} onclose={onHandleClose} />
27
+ <div class="modal-backdrop">
28
+ <div class="modal-container {width}">
29
+ <div
30
+ onclose={onHandleClose}
31
+ class="modal"
32
+ transition:scale={{
33
+ duration: 150,
34
+ start: 0.95
35
+ }}
36
+ >
37
+ <ModalHeader {title} {errorIcon} {hideHeader} onclose={onHandleClose} />
38
+ <ModalContent content={children} {disablePadding} />
39
+ <ModalFooter {footer} onclose={onHandleClose} />
40
+ </div>
37
41
  </div>
38
42
  </div>
39
43
 
40
44
  <style>
41
- .modal-container {
45
+ .modal-backdrop {
42
46
  display: flex;
43
47
  position: fixed;
44
48
  top: 0;
45
49
  left: 0;
46
50
  z-index: 1000;
51
+ justify-content: center;
47
52
  width: 100%;
48
53
  height: 100%;
49
54
  background-color: #e0e5e880;
50
55
  }
51
56
 
52
- .modal {
57
+ .modal-container {
53
58
  width: var(--modal-width);
54
59
  max-height: 90%;
55
60
  border-radius: 16px;
@@ -62,36 +67,40 @@
62
67
  0px 4px 5px 0px rgba(51, 56, 64, 0.14);
63
68
  }
64
69
 
65
- .modal.xs {
70
+ .modal {
71
+ position: relative;
72
+ }
73
+
74
+ .modal-container.xs {
66
75
  --modal-width: 500px;
67
76
  }
68
77
 
69
- .modal.md {
78
+ .modal-container.md {
70
79
  --modal-width: 600px;
71
80
  }
72
81
 
73
- .modal.lg {
82
+ .modal-container.lg {
74
83
  --modal-width: 800px;
75
84
  }
76
85
 
77
- .modal.xl {
86
+ .modal-container.xl {
78
87
  --modal-width: 1000px;
79
88
  }
80
89
 
81
- .modal::-webkit-scrollbar {
90
+ .modal-container::-webkit-scrollbar {
82
91
  width: 10px;
83
92
  }
84
93
 
85
- .modal::-webkit-scrollbar-thumb {
94
+ .modal-container::-webkit-scrollbar-thumb {
86
95
  background: #888;
87
96
  border-radius: 10px;
88
97
  }
89
98
 
90
- .modal::-webkit-scrollbar-thumb:hover {
99
+ .modal-container::-webkit-scrollbar-thumb:hover {
91
100
  background: #555;
92
101
  }
93
102
 
94
- :global(html:has(.modal-container)) {
103
+ :global(html:has(.modal-backdrop)) {
95
104
  overflow: hidden;
96
105
  }
97
106
  </style>
@@ -3,24 +3,27 @@
3
3
 
4
4
  interface ModalContentProps {
5
5
  content?: Snippet;
6
+ disablePadding?: boolean;
6
7
  }
7
8
 
8
- let { content }: ModalContentProps = $props();
9
+ let { content, disablePadding = false }: ModalContentProps = $props();
9
10
  </script>
10
11
 
11
- <div class="modal-content">
12
+ <div class="modal-content" class:padding={!disablePadding}>
12
13
  {@render content?.()}
13
14
  </div>
14
15
 
15
16
  <style>
16
17
  .modal-content {
17
18
  display: flex;
18
- padding: 24px;
19
19
  flex-direction: column;
20
20
  align-items: flex-start;
21
21
  gap: 24px;
22
22
  align-self: stretch;
23
23
  background: #fff;
24
- border-top: 1px solid #aeb1b9;
24
+ }
25
+
26
+ .padding {
27
+ padding: 24px;
25
28
  }
26
29
  </style>
@@ -1,6 +1,7 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  interface ModalContentProps {
3
3
  content?: Snippet;
4
+ disablePadding?: boolean;
4
5
  }
5
6
  declare const ModalContent: import("svelte").Component<ModalContentProps, {}, "">;
6
7
  type ModalContent = ReturnType<typeof ModalContent>;
@@ -4,20 +4,23 @@
4
4
  let {
5
5
  title = '',
6
6
  errorIcon = false,
7
+ hideHeader = false,
7
8
  onclose
8
9
  }: ModalHeaderProps & { onclose: VoidFunction } = $props();
9
10
  </script>
10
11
 
11
- <header class="modal-header">
12
- <div class="modal-header-title">
13
- {#if errorIcon}
14
- <span class="icon error material-icons-outlined">report</span>
15
- {/if}
16
- <h2>{title}</h2>
17
- </div>
18
- <button type="button" class="close-button material-icons-outlined" onclick={onclose}>close</button
19
- >
20
- </header>
12
+ {#if !hideHeader}
13
+ <header class="modal-header">
14
+ <div class="modal-header-title">
15
+ {#if errorIcon}
16
+ <span class="icon error material-icons-outlined">report</span>
17
+ {/if}
18
+ <h2>{title}</h2>
19
+ </div>
20
+ <button type="button" class="close-button material-icons-outlined" onclick={onclose}>close</button
21
+ >
22
+ </header>
23
+ {/if}
21
24
 
22
25
  <style>
23
26
  .modal-header,
@@ -29,6 +32,7 @@
29
32
  .modal-header {
30
33
  padding: 24px;
31
34
  align-self: stretch;
35
+ border-bottom: 1px solid #aeb1b9;
32
36
  }
33
37
 
34
38
  .modal-header-title > .icon {
@@ -4,10 +4,12 @@ export interface ModalProps extends ModalHeaderProps, ModalFooterProps {
4
4
  width?: WidthModal;
5
5
  children?: Snippet;
6
6
  onclose?: VoidFunction;
7
+ disablePadding?: boolean;
7
8
  }
8
9
  export interface ModalHeaderProps {
9
10
  title?: string;
10
11
  errorIcon?: boolean;
12
+ hideHeader?: boolean;
11
13
  }
12
14
  export interface ModalFooterProps {
13
15
  footer?: Snippet;
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import Modal from '../Modal/Modal.svelte';
3
+ import type { ProcessingProps } from './processingState.svelte.js';
4
+
5
+ let {
6
+ title = 'Processing your request',
7
+ text = '',
8
+ show = $bindable(true),
9
+ asModal = false
10
+ }: ProcessingProps = $props();
11
+ </script>
12
+
13
+ {#snippet processingContent()}
14
+ <div class="processing-header">
15
+ <span class="material-icons-outlined processing-icon">autorenew</span>
16
+ <div class="processing-content">
17
+ <h2 class="processing-title">{title}</h2>
18
+ {#if text}
19
+ <p class="processing-text">{text}</p>
20
+ {/if}
21
+ </div>
22
+ </div>
23
+ {/snippet}
24
+
25
+ {#if show}
26
+ {#if asModal}
27
+ <Modal bind:showModal={show} width="xs" hideHeader>
28
+ <div class="modal-processing-content">
29
+ {@render processingContent()}
30
+ </div>
31
+ </Modal>
32
+ {:else}
33
+ {@render processingContent()}
34
+ {/if}
35
+ {/if}
36
+
37
+ <style>
38
+ .processing-header {
39
+ display: flex;
40
+ flex-direction: column;
41
+ align-items: center;
42
+ text-align: center;
43
+ gap: 24px;
44
+ }
45
+
46
+ .processing-content {
47
+ display: flex;
48
+ flex-direction: column;
49
+ gap: 8px;
50
+ }
51
+
52
+ .processing-title {
53
+ font-size: 18px;
54
+ font-weight: 700;
55
+ }
56
+
57
+ .processing-text {
58
+ font-size: 16px;
59
+ white-space: pre-line;
60
+ line-height: 1.5;
61
+ }
62
+
63
+ .processing-icon {
64
+ background: linear-gradient(256deg, #00c9cd -2.41%, #472aff 31.72%, #392d9c 65.86%, #000 100%);
65
+ background-clip: text;
66
+ -webkit-background-clip: text;
67
+ -webkit-text-fill-color: transparent;
68
+ font-size: 32px;
69
+ animation: rotate 2s linear infinite;
70
+ }
71
+
72
+ @keyframes rotate {
73
+ from {
74
+ transform: rotate(0deg);
75
+ }
76
+ to {
77
+ transform: rotate(360deg);
78
+ }
79
+ }
80
+
81
+ .modal-processing-content {
82
+ display: flex;
83
+ flex-direction: column;
84
+ justify-content: center;
85
+ align-items: center;
86
+ min-height: 200px;
87
+ width: 100%;
88
+ }
89
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { ProcessingProps } from './processingState.svelte.js';
2
+ declare const Processing: import("svelte").Component<ProcessingProps, {}, "show">;
3
+ type Processing = ReturnType<typeof Processing>;
4
+ export default Processing;
@@ -0,0 +1,6 @@
1
+ export interface ProcessingProps {
2
+ title?: string;
3
+ text?: string;
4
+ show?: boolean;
5
+ asModal?: boolean;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -152,7 +152,6 @@
152
152
  display: flex;
153
153
  flex-direction: column;
154
154
  width: 100%;
155
- height: 100vh;
156
155
  }
157
156
 
158
157
  .progress-wizard-container {
@@ -41,6 +41,7 @@
41
41
  top: 0;
42
42
  left: 0;
43
43
  background-color: rgba(255, 255, 255, 0.8);
44
+ z-index: 99;
44
45
  }
45
46
 
46
47
  .spinner {
@@ -0,0 +1,78 @@
1
+ <script lang="ts">
2
+ import { type SwitcherOption } from '../index.js';
3
+
4
+ interface SwitcherProps {
5
+ options: string[] | SwitcherOption[];
6
+ value?: string | null;
7
+ }
8
+
9
+ let { options, value = $bindable() }: SwitcherProps = $props();
10
+
11
+ const isStringArray = (items: string[] | SwitcherOption[]): items is string[] =>
12
+ typeof items[0] === 'string';
13
+
14
+ const originalOptions = $derived<SwitcherOption[]>(
15
+ isStringArray(options) ? options.map((option) => ({ label: option, value: option })) : options
16
+ );
17
+ </script>
18
+
19
+ <div class="switcher-container">
20
+ {#each originalOptions as option}
21
+ <button
22
+ type="button"
23
+ class={['switcher-option', option.value === value && 'active']}
24
+ onclick={() => (value = option.value)}
25
+ >
26
+ {option.label}
27
+ </button>
28
+ {/each}
29
+ </div>
30
+
31
+ <style>
32
+ .switcher-container {
33
+ --primary-color: #472aff;
34
+ --white: #fff;
35
+ --info-1: #eaecff;
36
+ --gray-1: #f4f6f8;
37
+ --gray-3: #aeb1b9;
38
+ --gray-4: #6b7180;
39
+
40
+ display: flex;
41
+ flex-wrap: wrap;
42
+ width: fit-content;
43
+ padding: 4px;
44
+ gap: 12px;
45
+ border: 1px solid var(--gray-3);
46
+ border-radius: 8px;
47
+ }
48
+
49
+ .switcher-container > .switcher-option {
50
+ cursor: pointer;
51
+ border: none;
52
+ padding: 4px 20px;
53
+ font-size: 14px;
54
+ color: var(--gray-4);
55
+ font-weight: 500;
56
+ border-radius: 8px;
57
+ background: none;
58
+ }
59
+
60
+ .switcher-container > .switcher-option:hover {
61
+ background: var(--gray-1);
62
+ }
63
+
64
+ .switcher-container > .switcher-option:focus-visible {
65
+ box-shadow: 0px 0px 0px 3px #959bff;
66
+ outline: none;
67
+ }
68
+
69
+ .switcher-container > .switcher-option.active {
70
+ color: var(--white);
71
+ background: var(--primary-color);
72
+ transition: background 0.2s ease-in-out;
73
+ }
74
+
75
+ .switcher-container > .switcher-option.active:hover {
76
+ background: #3520bf;
77
+ }
78
+ </style>
@@ -0,0 +1,8 @@
1
+ import { type SwitcherOption } from '../index.js';
2
+ interface SwitcherProps {
3
+ options: string[] | SwitcherOption[];
4
+ value?: string | null;
5
+ }
6
+ declare const Switcher: import("svelte").Component<SwitcherProps, {}, "value">;
7
+ type Switcher = ReturnType<typeof Switcher>;
8
+ export default Switcher;
@@ -0,0 +1,4 @@
1
+ export interface SwitcherOption {
2
+ value: string;
3
+ label: string;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,95 @@
1
+ <script lang="ts">
2
+ import { fade } from 'svelte/transition';
3
+ import type { WaffleItem } from './waffleState.svelte.js';
4
+ import WaffleItems from './WaffleItems.svelte';
5
+
6
+ interface Props {
7
+ items?: WaffleItem[];
8
+ showWaffle?: boolean;
9
+ }
10
+
11
+ let { items = [], showWaffle = false }: Props = $props();
12
+
13
+ const handleTileClick = (item: WaffleItem) => {
14
+ onHandleWaffle();
15
+ window.open(item.url, '_blank', 'noopener,noreferrer');
16
+ };
17
+
18
+ const onHandleWaffle = () => {
19
+ showWaffle = !showWaffle;
20
+ };
21
+ </script>
22
+
23
+ {#if showWaffle}
24
+ <div
25
+ class="waffle-backdrop"
26
+ onclick={onHandleWaffle}
27
+ onkeydown={onHandleWaffle}
28
+ transition:fade={{ duration: 200 }}
29
+ role="button"
30
+ tabindex="0"
31
+ aria-label="Close waffle menu"
32
+ ></div>
33
+
34
+ <aside
35
+ class="waffle-dropdown"
36
+ transition:fade={{ duration: 250 }}
37
+ role="dialog"
38
+ aria-labelledby="waffle-title"
39
+ aria-modal="true"
40
+ >
41
+ <h2 class="waffle-title">SoftwareOne Cloud</h2>
42
+
43
+ <div class="waffle-content">
44
+ <ul class="waffle-grid" role="list">
45
+ {#each items as item (item.title)}
46
+ <li role="listitem">
47
+ <WaffleItems {...item} onclickwaffleitems={() => handleTileClick(item)} />
48
+ </li>
49
+ {/each}
50
+ </ul>
51
+ </div>
52
+ </aside>
53
+ {/if}
54
+
55
+ <style>
56
+ .waffle-backdrop {
57
+ position: fixed;
58
+ inset: 0;
59
+ background: rgba(243, 244, 246, 0.5);
60
+ cursor: pointer;
61
+ z-index: 30;
62
+ }
63
+
64
+ .waffle-dropdown {
65
+ position: absolute;
66
+ display: flex;
67
+ flex-direction: column;
68
+ border-radius: 8px;
69
+ background: #fff;
70
+ box-shadow:
71
+ 0 10px 15px -3px rgba(0, 0, 0, 0.1),
72
+ 0 4px 6px -2px rgba(0, 0, 0, 0.05);
73
+ top: 80px;
74
+ left: 0;
75
+ z-index: 40;
76
+ width: 600px;
77
+ }
78
+
79
+ .waffle-content {
80
+ padding: 20px 24px 24px 24px;
81
+ }
82
+
83
+ .waffle-title {
84
+ padding: 24px 24px 0 24px;
85
+ font-size: 14px;
86
+ font-weight: 600;
87
+ text-align: center;
88
+ }
89
+
90
+ .waffle-grid {
91
+ display: grid;
92
+ grid-template-columns: repeat(3, 1fr);
93
+ gap: 16px;
94
+ }
95
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { WaffleItem } from './waffleState.svelte.js';
2
+ interface Props {
3
+ items?: WaffleItem[];
4
+ showWaffle?: boolean;
5
+ }
6
+ declare const Waffle: import("svelte").Component<Props, {}, "">;
7
+ type Waffle = ReturnType<typeof Waffle>;
8
+ export default Waffle;