@softwareone/spi-sv5-library 1.0.0 → 1.2.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 +75 -19
- package/dist/Accordion/Accordion.svelte +89 -0
- package/dist/Accordion/Accordion.svelte.d.ts +9 -0
- package/dist/Button/Button.svelte +12 -1
- package/dist/Button/Button.svelte.d.ts +1 -1
- package/dist/Card/Card.svelte +2 -16
- package/dist/Card/Card.svelte.d.ts +0 -1
- package/dist/Chips/Chips.svelte +31 -34
- package/dist/Chips/Chips.svelte.d.ts +1 -1
- package/dist/ErrorPage/ErrorPage.svelte +6 -7
- package/dist/ErrorPage/ErrorPage.svelte.d.ts +1 -2
- package/dist/Form/Input/Input.svelte +16 -43
- package/dist/Form/Input/Input.svelte.d.ts +3 -2
- package/dist/Form/Label.svelte +37 -0
- package/dist/Form/Label.svelte.d.ts +9 -0
- package/dist/Form/Select/Select.svelte +457 -0
- package/dist/Form/Select/Select.svelte.d.ts +22 -0
- package/dist/Form/Select/selectState.svelte.d.ts +4 -0
- package/dist/Form/Select/selectState.svelte.js +1 -0
- package/dist/Form/TextArea/TextArea.svelte +9 -27
- package/dist/Form/TextArea/TextArea.svelte.d.ts +2 -2
- package/dist/Header/Header.svelte +29 -33
- package/dist/Header/Header.svelte.d.ts +2 -3
- package/dist/Header/HeaderAccount.svelte +8 -6
- package/dist/Header/HeaderLoader.svelte +2 -2
- package/dist/Header/HeaderLogo.svelte +7 -4
- package/dist/Header/HeaderLogo.svelte.d.ts +14 -6
- package/dist/Menu/Menu.svelte +11 -11
- package/dist/Menu/MenuItem.svelte +7 -11
- package/dist/Modal/Modal.svelte +84 -27
- package/dist/Modal/Modal.svelte.d.ts +2 -9
- package/dist/Modal/ModalContent.svelte +4 -77
- package/dist/Modal/ModalContent.svelte.d.ts +2 -3
- package/dist/Modal/ModalFooter.svelte +17 -58
- package/dist/Modal/ModalFooter.svelte.d.ts +5 -5
- package/dist/Modal/ModalHeader.svelte +49 -31
- package/dist/Modal/ModalHeader.svelte.d.ts +5 -4
- package/dist/Modal/modalState.svelte.d.ts +15 -0
- package/dist/Modal/modalState.svelte.js +1 -0
- package/dist/Notification/Notification.svelte +69 -0
- package/dist/Notification/Notification.svelte.d.ts +4 -0
- package/dist/Notification/notificationState.svelte.d.ts +9 -0
- package/dist/Notification/notificationState.svelte.js +1 -0
- package/dist/ProgressPage/ProgressPage.svelte +95 -0
- package/dist/ProgressPage/ProgressPage.svelte.d.ts +11 -0
- package/dist/ProgressWizard/ProgressWizard.svelte +271 -278
- package/dist/ProgressWizard/ProgressWizard.svelte.d.ts +11 -13
- package/dist/ProgressWizard/progressWizardState.svelte.d.ts +6 -0
- package/dist/ProgressWizard/progressWizardState.svelte.js +1 -0
- package/dist/Search/Search.svelte +161 -0
- package/dist/Search/Search.svelte.d.ts +10 -0
- package/dist/Spinner/Spinner.svelte +23 -34
- package/dist/Spinner/Spinner.svelte.d.ts +3 -2
- package/dist/Toast/Toast.svelte +109 -42
- package/dist/Toast/toastState.svelte.d.ts +7 -3
- package/dist/Toast/toastState.svelte.js +13 -10
- package/dist/Tooltip/Tooltip.svelte +0 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +7 -2
- package/package.json +4 -6
package/README.md
CHANGED
|
@@ -15,32 +15,88 @@ npm install @softwareone/swo-spi-svelte5-library
|
|
|
15
15
|
Import the components you need into your Svelte application:
|
|
16
16
|
|
|
17
17
|
```javascript
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
18
|
+
import {
|
|
19
|
+
Avatar,
|
|
20
|
+
Breadcrumbs,
|
|
21
|
+
Button,
|
|
22
|
+
Card,
|
|
23
|
+
Chips,
|
|
24
|
+
ErrorPage,
|
|
25
|
+
Footer,
|
|
26
|
+
Header,
|
|
27
|
+
HeaderAccount,
|
|
28
|
+
HeaderLoader,
|
|
29
|
+
HeaderLogo,
|
|
30
|
+
HighlightPanel,
|
|
31
|
+
Input,
|
|
32
|
+
Menu,
|
|
33
|
+
Modal,
|
|
34
|
+
ProgressWizard,
|
|
35
|
+
Sidebar,
|
|
36
|
+
Tabs,
|
|
37
|
+
TextArea,
|
|
38
|
+
Toaster,
|
|
39
|
+
Toggle,
|
|
40
|
+
Tooltip
|
|
41
|
+
} from '@softwareone/swo-spi-svelte5-library';
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Import the types you need into your Svelte application:
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
import {
|
|
48
|
+
type BreadcrumbsNameMap,
|
|
49
|
+
type HighlightPanelColumn,
|
|
50
|
+
type MenuItem,
|
|
51
|
+
type ModalProps,
|
|
52
|
+
type ProgressWizardStep,
|
|
53
|
+
type Tab,
|
|
54
|
+
type Toast
|
|
55
|
+
} from '@softwareone/swo-spi-svelte5-library';
|
|
33
56
|
```
|
|
34
57
|
|
|
35
58
|
# List of components
|
|
36
59
|
|
|
60
|
+
- Avatar
|
|
61
|
+
- Breadcrumbs
|
|
37
62
|
- Button
|
|
63
|
+
- Card
|
|
64
|
+
- Chips
|
|
65
|
+
- ErrorPage
|
|
66
|
+
- Footer
|
|
67
|
+
- Form
|
|
68
|
+
- Input
|
|
69
|
+
- TextArea
|
|
70
|
+
- Toggle
|
|
71
|
+
- Header (including a loader)
|
|
72
|
+
- HeaderAccount
|
|
73
|
+
- HeaderLoader
|
|
74
|
+
- HeaderLogo
|
|
75
|
+
- HighlightPanel
|
|
76
|
+
- Menu
|
|
77
|
+
- Sidebar
|
|
38
78
|
- Modal
|
|
79
|
+
- ProgressWizard
|
|
39
80
|
- Spinner
|
|
81
|
+
- Tabs
|
|
40
82
|
- Toaster
|
|
41
|
-
-
|
|
42
|
-
|
|
83
|
+
- Tooltip
|
|
84
|
+
|
|
85
|
+
# List of types per component
|
|
86
|
+
|
|
43
87
|
- Breadcrumbs
|
|
88
|
+
- BreadcrumbsNameMap
|
|
44
89
|
- Chips
|
|
45
|
-
-
|
|
46
|
-
-
|
|
90
|
+
- ChipType
|
|
91
|
+
- HighlightPanel
|
|
92
|
+
- ColumnType
|
|
93
|
+
- HighlightPanelColumn
|
|
94
|
+
- ImageType
|
|
95
|
+
- Menu
|
|
96
|
+
- MenuItem
|
|
97
|
+
- Modal
|
|
98
|
+
- ModalProps
|
|
99
|
+
- ProgressWizard
|
|
100
|
+
- ProgressWizardStep
|
|
101
|
+
- Tab
|
|
102
|
+
- Toast
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface AccordionProps {
|
|
5
|
+
title: string;
|
|
6
|
+
disableBorder?: boolean;
|
|
7
|
+
content: Snippet;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { title, disableBorder = false, content }: AccordionProps = $props();
|
|
11
|
+
|
|
12
|
+
let isOpen = $state(false);
|
|
13
|
+
|
|
14
|
+
const toggleAccordion = () => {
|
|
15
|
+
isOpen = !isOpen;
|
|
16
|
+
};
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<aside class="accordion-container" class:border={!disableBorder}>
|
|
20
|
+
<div class="accordion-content">
|
|
21
|
+
<section class="header" class:is-open={isOpen}>
|
|
22
|
+
<button class="button" onclick={toggleAccordion}>
|
|
23
|
+
<span class="material-icons-outlined icon-span">
|
|
24
|
+
{isOpen ? 'keyboard_arrow_down' : 'keyboard_arrow_right'}
|
|
25
|
+
</span>
|
|
26
|
+
</button>
|
|
27
|
+
|
|
28
|
+
<h2 class="header-title">{title}</h2>
|
|
29
|
+
</section>
|
|
30
|
+
|
|
31
|
+
{#if isOpen}
|
|
32
|
+
{@render content()}
|
|
33
|
+
{/if}
|
|
34
|
+
</div>
|
|
35
|
+
</aside>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
.accordion-container {
|
|
39
|
+
width: 100%;
|
|
40
|
+
height: 100%;
|
|
41
|
+
padding: 32px;
|
|
42
|
+
display: flex;
|
|
43
|
+
|
|
44
|
+
--border-color: #e0e5e8;
|
|
45
|
+
--color: #472aff;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.accordion-content {
|
|
49
|
+
flex-direction: column;
|
|
50
|
+
flex: 1 1 0;
|
|
51
|
+
gap: 4px;
|
|
52
|
+
display: flex;
|
|
53
|
+
font-size: 14px;
|
|
54
|
+
line-height: 20px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.is-open {
|
|
58
|
+
padding-bottom: 10px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.header {
|
|
62
|
+
gap: 16px;
|
|
63
|
+
display: inline-flex;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.header-title {
|
|
67
|
+
font-weight: 600;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.border {
|
|
71
|
+
border: 1px solid var(--border-color);
|
|
72
|
+
border-radius: 8px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.button {
|
|
76
|
+
background: transparent;
|
|
77
|
+
border: none;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
border-radius: 50%;
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
justify-content: center;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.icon-span {
|
|
86
|
+
color: var(--color);
|
|
87
|
+
font-size: 20px;
|
|
88
|
+
}
|
|
89
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface AccordionProps {
|
|
3
|
+
title: string;
|
|
4
|
+
disableBorder?: boolean;
|
|
5
|
+
content: Snippet;
|
|
6
|
+
}
|
|
7
|
+
declare const Accordion: import("svelte").Component<AccordionProps, {}, "">;
|
|
8
|
+
type Accordion = ReturnType<typeof Accordion>;
|
|
9
|
+
export default Accordion;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
4
4
|
|
|
5
|
-
type Variant = 'primary' | 'secondary' | 'outline';
|
|
5
|
+
type Variant = 'primary' | 'secondary' | 'outline' | 'outline-none';
|
|
6
6
|
type VariantColor = 'primary' | 'danger';
|
|
7
7
|
|
|
8
8
|
interface ButtonProps extends HTMLButtonAttributes {
|
|
@@ -78,6 +78,17 @@
|
|
|
78
78
|
background: #eaecff;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
.btn-outline-none-primary {
|
|
82
|
+
border: none;
|
|
83
|
+
background: #fff;
|
|
84
|
+
color: #472aff;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.btn-outline-none-primary:hover:not(:disabled),
|
|
88
|
+
.btn-outline-none-primary:focus:not(:disabled) {
|
|
89
|
+
background: #e0e5e8;
|
|
90
|
+
}
|
|
91
|
+
|
|
81
92
|
.btn-primary-danger {
|
|
82
93
|
background: #dc182c;
|
|
83
94
|
color: #fff;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
-
type Variant = 'primary' | 'secondary' | 'outline';
|
|
3
|
+
type Variant = 'primary' | 'secondary' | 'outline' | 'outline-none';
|
|
4
4
|
type VariantColor = 'primary' | 'danger';
|
|
5
5
|
interface ButtonProps extends HTMLButtonAttributes {
|
|
6
6
|
variant?: Variant;
|
package/dist/Card/Card.svelte
CHANGED
|
@@ -2,24 +2,20 @@
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
|
|
4
4
|
interface CardProps {
|
|
5
|
-
alignItems?: 'left' | 'center' | 'right';
|
|
6
5
|
type?: 'layout' | 'highlight';
|
|
7
6
|
children?: Snippet;
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
let {
|
|
9
|
+
let { type = 'layout', children }: CardProps = $props();
|
|
11
10
|
</script>
|
|
12
11
|
|
|
13
|
-
<div class="card card-{type}"
|
|
12
|
+
<div class="card card-{type}">
|
|
14
13
|
{@render children?.()}
|
|
15
14
|
</div>
|
|
16
15
|
|
|
17
16
|
<style>
|
|
18
17
|
.card {
|
|
19
|
-
display: inline-flex;
|
|
20
|
-
flex-direction: column;
|
|
21
18
|
width: 100%;
|
|
22
|
-
min-width: 222px;
|
|
23
19
|
min-height: var(--card-min-height, auto);
|
|
24
20
|
background: #fff;
|
|
25
21
|
margin-bottom: 24px;
|
|
@@ -33,14 +29,4 @@
|
|
|
33
29
|
.card-layout {
|
|
34
30
|
--card-min-height: 100vh;
|
|
35
31
|
}
|
|
36
|
-
|
|
37
|
-
.card[data-align='left'] {
|
|
38
|
-
align-items: flex-start;
|
|
39
|
-
}
|
|
40
|
-
.card[data-align='center'] {
|
|
41
|
-
align-items: center;
|
|
42
|
-
}
|
|
43
|
-
.card[data-align='right'] {
|
|
44
|
-
align-items: flex-end;
|
|
45
|
-
}
|
|
46
32
|
</style>
|
package/dist/Chips/Chips.svelte
CHANGED
|
@@ -1,74 +1,71 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { ChipType } from '
|
|
2
|
+
import { ChipType } from './chipsState.svelte.js';
|
|
3
3
|
|
|
4
4
|
interface ChipsProps {
|
|
5
5
|
type?: ChipType;
|
|
6
6
|
text?: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
let { type, text }: ChipsProps =
|
|
10
|
-
|
|
11
|
-
type = type || ChipType.Info;
|
|
12
|
-
text = text || type.charAt(0).toUpperCase() + type.slice(1); // Default to capitalized type
|
|
13
|
-
|
|
14
|
-
let className = `chip chip-${type}`;
|
|
9
|
+
let { type = ChipType.Info, text = type.charAt(0).toUpperCase() + type.slice(1) }: ChipsProps =
|
|
10
|
+
$props();
|
|
15
11
|
</script>
|
|
16
12
|
|
|
17
|
-
<div class={
|
|
13
|
+
<div class="chip {type}">
|
|
18
14
|
{text}
|
|
19
15
|
</div>
|
|
20
16
|
|
|
21
17
|
<style>
|
|
22
18
|
.chip {
|
|
23
|
-
display: inline-
|
|
24
|
-
padding: 2px 8px;
|
|
25
|
-
align-items: center;
|
|
26
|
-
gap: 8px;
|
|
27
|
-
border-radius: 4px;
|
|
19
|
+
display: inline-block;
|
|
28
20
|
font-size: 14px;
|
|
29
|
-
font-
|
|
30
|
-
font-weight: 400;
|
|
21
|
+
font-weight: 500;
|
|
31
22
|
line-height: 20px;
|
|
32
23
|
background: var(--chip-bg);
|
|
33
24
|
color: var(--chip-text);
|
|
25
|
+
padding: 2px 8px;
|
|
26
|
+
border-radius: 4px;
|
|
27
|
+
cursor: default;
|
|
34
28
|
}
|
|
35
29
|
|
|
36
30
|
.chip:hover {
|
|
37
|
-
background: var(--chip-hover);
|
|
31
|
+
background: var(--chip-bg-hover);
|
|
38
32
|
}
|
|
39
33
|
|
|
40
34
|
.chip:focus {
|
|
41
|
-
|
|
42
|
-
box-shadow: 0px 0px 0px 3px var(--chip-hover);
|
|
35
|
+
box-shadow: 0px 0px 0px 3px #959bff;
|
|
43
36
|
}
|
|
44
|
-
|
|
45
|
-
.chip-info {
|
|
46
|
-
--chip-bg: #eaecff;
|
|
37
|
+
.chip.info {
|
|
47
38
|
--chip-text: #3520bf;
|
|
48
|
-
--chip-
|
|
39
|
+
--chip-bg: #eaecff;
|
|
40
|
+
--chip-text-hover: #2b1999;
|
|
41
|
+
--chip-bg-hover: #959bff;
|
|
49
42
|
}
|
|
50
43
|
|
|
51
|
-
.chip
|
|
52
|
-
--chip-bg: #e6f9f2;
|
|
44
|
+
.chip.success {
|
|
53
45
|
--chip-text: #00784d;
|
|
54
|
-
--chip-
|
|
46
|
+
--chip-bg: #e6f9f2;
|
|
47
|
+
--chip-text-hover: #005838;
|
|
48
|
+
--chip-bg-hover: #80e1ae;
|
|
55
49
|
}
|
|
56
50
|
|
|
57
|
-
.chip
|
|
58
|
-
--chip-bg: #fdf2e9;
|
|
51
|
+
.chip.warning {
|
|
59
52
|
--chip-text: #a15d26;
|
|
60
|
-
--chip-
|
|
53
|
+
--chip-bg: #fdf2e9;
|
|
54
|
+
--chip-text-hover: #733f11;
|
|
55
|
+
--chip-bg-hover: #f1b178;
|
|
61
56
|
}
|
|
62
57
|
|
|
63
|
-
.chip
|
|
64
|
-
--chip-bg: #fce8ea;
|
|
58
|
+
.chip.error {
|
|
65
59
|
--chip-text: #bb1425;
|
|
66
|
-
--chip-
|
|
60
|
+
--chip-bg: #fce8ea;
|
|
61
|
+
--chip-text-hover: #8f101d;
|
|
62
|
+
--chip-bg-hover: #ee8c96;
|
|
67
63
|
}
|
|
68
64
|
|
|
69
|
-
.chip
|
|
70
|
-
--chip-bg: #f4f6f8;
|
|
65
|
+
.chip.neutral {
|
|
71
66
|
--chip-text: #434952;
|
|
72
|
-
--chip-
|
|
67
|
+
--chip-bg: #f4f6f8;
|
|
68
|
+
--chip-text-hover: #25282d;
|
|
69
|
+
--chip-bg-hover: #e0e5e8;
|
|
73
70
|
}
|
|
74
71
|
</style>
|
|
@@ -2,22 +2,20 @@
|
|
|
2
2
|
import { goto } from '$app/navigation';
|
|
3
3
|
import { page } from '$app/state';
|
|
4
4
|
|
|
5
|
-
import { StatusCodes } from 'http-status-codes';
|
|
6
|
-
|
|
7
5
|
import FeedbackIcon from '../assets/icons/feedback.svg';
|
|
8
6
|
import { Button } from '../index.js';
|
|
9
7
|
|
|
10
8
|
interface ErrorPageProps {
|
|
11
|
-
status:
|
|
9
|
+
status: number;
|
|
12
10
|
title?: string;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
let { status, title }: ErrorPageProps = $props();
|
|
16
14
|
|
|
17
15
|
const errorTitle: Record<number, string> = {
|
|
18
|
-
[
|
|
19
|
-
[
|
|
20
|
-
[
|
|
16
|
+
[404]: 'Page not found',
|
|
17
|
+
[403]: 'Access denied',
|
|
18
|
+
[500]: 'An unexpected error occurred'
|
|
21
19
|
};
|
|
22
20
|
</script>
|
|
23
21
|
|
|
@@ -26,7 +24,7 @@
|
|
|
26
24
|
|
|
27
25
|
<div class="feedback-detail">
|
|
28
26
|
<h1>{title || errorTitle[status]}</h1>
|
|
29
|
-
{#if status ===
|
|
27
|
+
{#if status === 404}
|
|
30
28
|
<div>
|
|
31
29
|
<p>We couldn’t find the page:</p>
|
|
32
30
|
<p class="link">{page.url}</p>
|
|
@@ -79,6 +77,7 @@
|
|
|
79
77
|
|
|
80
78
|
.feedback-detail > h1 {
|
|
81
79
|
font-size: 24px;
|
|
80
|
+
font-weight: bold;
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
.feedback-detail .link {
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
3
|
import InputIcon from './InputIcon.svelte';
|
|
4
|
+
import Label from '../Label.svelte';
|
|
4
5
|
|
|
5
6
|
type InputType = 'text' | 'password' | 'number' | 'date' | 'money';
|
|
6
7
|
|
|
7
8
|
interface InputProps extends Omit<HTMLInputAttributes, 'type' | 'value'> {
|
|
8
9
|
label?: string;
|
|
9
10
|
type?: InputType;
|
|
10
|
-
value?: string | number;
|
|
11
|
+
value?: string | number | null;
|
|
11
12
|
optional?: boolean;
|
|
12
|
-
error?: string;
|
|
13
|
+
error?: string | string[];
|
|
13
14
|
description?: string;
|
|
14
15
|
currency?: string;
|
|
16
|
+
disableValidationColor?: boolean;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
let {
|
|
@@ -19,14 +21,15 @@
|
|
|
19
21
|
type = 'text',
|
|
20
22
|
value = $bindable(''),
|
|
21
23
|
optional = false,
|
|
24
|
+
required = false,
|
|
22
25
|
error,
|
|
23
26
|
description,
|
|
24
27
|
currency,
|
|
25
28
|
id,
|
|
26
29
|
disabled,
|
|
27
30
|
readonly,
|
|
28
|
-
required,
|
|
29
31
|
oninput,
|
|
32
|
+
disableValidationColor = false,
|
|
30
33
|
...props
|
|
31
34
|
}: InputProps = $props();
|
|
32
35
|
|
|
@@ -45,39 +48,22 @@
|
|
|
45
48
|
money: 'number',
|
|
46
49
|
password: isPasswordVisible ? 'text' : 'password'
|
|
47
50
|
});
|
|
48
|
-
|
|
49
|
-
const handleInput = (event: Event): void => {
|
|
50
|
-
const target = event.target as HTMLInputElement;
|
|
51
|
-
value = type === 'number' || type === 'money' ? target.valueAsNumber : target.value;
|
|
52
|
-
oninput?.(event as Event & { currentTarget: EventTarget & HTMLInputElement });
|
|
53
|
-
};
|
|
54
51
|
</script>
|
|
55
52
|
|
|
56
53
|
<div class="form-container">
|
|
57
|
-
{
|
|
58
|
-
<div class="form-label-container">
|
|
59
|
-
<label for={inputId}>{label}</label>
|
|
60
|
-
{#if required}
|
|
61
|
-
<span class="form-label-required">Required</span>
|
|
62
|
-
{:else if optional}
|
|
63
|
-
<span class="form-label-optional">Optional</span>
|
|
64
|
-
{/if}
|
|
65
|
-
</div>
|
|
66
|
-
{/if}
|
|
67
|
-
|
|
54
|
+
<Label {label} {id} {optional} {required} />
|
|
68
55
|
<div
|
|
69
56
|
class={[
|
|
70
57
|
'form-input-wrapper',
|
|
71
|
-
isInvalid && 'error',
|
|
72
|
-
isValid && 'success',
|
|
58
|
+
!disableValidationColor && [isInvalid && 'error', isValid && 'success'],
|
|
73
59
|
type === 'money' && currency && 'money-with-icon'
|
|
74
60
|
]}
|
|
75
61
|
>
|
|
76
62
|
<input
|
|
63
|
+
bind:value
|
|
77
64
|
{...props}
|
|
78
65
|
id={inputId}
|
|
79
66
|
type={transformationType[type] ?? type}
|
|
80
|
-
{value}
|
|
81
67
|
{disabled}
|
|
82
68
|
{readonly}
|
|
83
69
|
class={[
|
|
@@ -88,7 +74,6 @@
|
|
|
88
74
|
showDatePicker && 'form-input-date'
|
|
89
75
|
]}
|
|
90
76
|
aria-invalid={isInvalid}
|
|
91
|
-
oninput={handleInput}
|
|
92
77
|
/>
|
|
93
78
|
|
|
94
79
|
{#if type === 'money' && currency}
|
|
@@ -102,7 +87,7 @@
|
|
|
102
87
|
type === 'password' && hasStatus && 'form-input-icon-container-password'
|
|
103
88
|
]}
|
|
104
89
|
>
|
|
105
|
-
{#if hasStatus}
|
|
90
|
+
{#if !disableValidationColor && hasStatus}
|
|
106
91
|
<InputIcon type={isInvalid ? 'error' : 'success'} isDateInput={showDatePicker} />
|
|
107
92
|
{/if}
|
|
108
93
|
|
|
@@ -120,7 +105,7 @@
|
|
|
120
105
|
{/if}
|
|
121
106
|
{#if isInvalid}
|
|
122
107
|
<p class="form-message form-message-error">
|
|
123
|
-
{error}
|
|
108
|
+
{Array.isArray(error) ? error[0] : error}
|
|
124
109
|
</p>
|
|
125
110
|
{/if}
|
|
126
111
|
</div>
|
|
@@ -134,20 +119,6 @@
|
|
|
134
119
|
line-height: 20px;
|
|
135
120
|
}
|
|
136
121
|
|
|
137
|
-
.form-label-container {
|
|
138
|
-
display: flex;
|
|
139
|
-
gap: 8px;
|
|
140
|
-
font-weight: 500;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.form-label-optional {
|
|
144
|
-
color: #6b7180;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.form-label-required {
|
|
148
|
-
color: #dc2626;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
122
|
.form-message {
|
|
152
123
|
font-size: 12px;
|
|
153
124
|
}
|
|
@@ -259,7 +230,7 @@
|
|
|
259
230
|
right: 43px;
|
|
260
231
|
top: 0;
|
|
261
232
|
bottom: 0;
|
|
262
|
-
width:
|
|
233
|
+
width: 0.5px;
|
|
263
234
|
background-color: #6b7180;
|
|
264
235
|
z-index: 1;
|
|
265
236
|
}
|
|
@@ -327,7 +298,7 @@
|
|
|
327
298
|
left: 0;
|
|
328
299
|
top: -8px;
|
|
329
300
|
bottom: -8px;
|
|
330
|
-
width:
|
|
301
|
+
width: 0.5px;
|
|
331
302
|
background-color: #6b7180;
|
|
332
303
|
z-index: 1;
|
|
333
304
|
}
|
|
@@ -351,7 +322,9 @@
|
|
|
351
322
|
border-color: #008556;
|
|
352
323
|
}
|
|
353
324
|
|
|
354
|
-
.form-input-wrapper.success:hover:not(:has(.form-input:disabled)):not(
|
|
325
|
+
.form-input-wrapper.success:hover:not(:has(.form-input:disabled)):not(
|
|
326
|
+
:has(.form-input:read-only)
|
|
327
|
+
),
|
|
355
328
|
.form-input-wrapper.success:focus-within {
|
|
356
329
|
border-color: #10b981;
|
|
357
330
|
}
|
|
@@ -3,11 +3,12 @@ type InputType = 'text' | 'password' | 'number' | 'date' | 'money';
|
|
|
3
3
|
interface InputProps extends Omit<HTMLInputAttributes, 'type' | 'value'> {
|
|
4
4
|
label?: string;
|
|
5
5
|
type?: InputType;
|
|
6
|
-
value?: string | number;
|
|
6
|
+
value?: string | number | null;
|
|
7
7
|
optional?: boolean;
|
|
8
|
-
error?: string;
|
|
8
|
+
error?: string | string[];
|
|
9
9
|
description?: string;
|
|
10
10
|
currency?: string;
|
|
11
|
+
disableValidationColor?: boolean;
|
|
11
12
|
}
|
|
12
13
|
declare const Input: import("svelte").Component<InputProps, {}, "value">;
|
|
13
14
|
type Input = ReturnType<typeof Input>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface LabelProps {
|
|
3
|
+
label?: string;
|
|
4
|
+
id?: string | null;
|
|
5
|
+
required?: boolean | null;
|
|
6
|
+
optional?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { label, id, required, optional }: LabelProps = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
{#if label}
|
|
13
|
+
<div class="form-label-container">
|
|
14
|
+
<label for={id}>{label}</label>
|
|
15
|
+
{#if required}
|
|
16
|
+
<span class="form-label-required">Required</span>
|
|
17
|
+
{:else if optional}
|
|
18
|
+
<span class="form-label-optional">Optional</span>
|
|
19
|
+
{/if}
|
|
20
|
+
</div>
|
|
21
|
+
{/if}
|
|
22
|
+
|
|
23
|
+
<style>
|
|
24
|
+
.form-label-container {
|
|
25
|
+
display: flex;
|
|
26
|
+
gap: 8px;
|
|
27
|
+
font-weight: 500;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.form-label-optional {
|
|
31
|
+
color: #6b7180;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.form-label-required {
|
|
35
|
+
color: #dc2626;
|
|
36
|
+
}
|
|
37
|
+
</style>
|