@dvcol/neo-svelte 0.1.2 → 0.1.4
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/CHANGELOG.md +83 -0
- package/README.md +25 -26
- package/dist/buttons/NeoButton.svelte +140 -128
- package/dist/buttons/NeoButtonGroup.svelte +99 -108
- package/dist/buttons/neo-button-group.model.d.ts +18 -19
- package/dist/buttons/neo-button.model.d.ts +6 -10
- package/dist/cards/NeoCard.svelte +176 -73
- package/dist/cards/NeoCard.svelte.d.ts +1 -1
- package/dist/cards/neo-card.model.d.ts +29 -1
- package/dist/containers/NeoTransitionContainer.svelte +13 -2
- package/dist/containers/neo-transition-container.model.d.ts +9 -1
- package/dist/divider/NeoDivider.svelte +11 -11
- package/dist/icons/IconAccount.svelte +10 -2
- package/dist/icons/IconAdd.svelte +10 -2
- package/dist/icons/IconAlert.svelte +2 -2
- package/dist/icons/IconCalendar.svelte +23 -0
- package/dist/icons/IconCalendar.svelte.d.ts +26 -0
- package/dist/icons/IconCheckbox.svelte +87 -0
- package/dist/icons/IconCheckbox.svelte.d.ts +55 -0
- package/dist/icons/IconCircleLoading.svelte +2 -2
- package/dist/icons/IconClear.svelte +10 -2
- package/dist/icons/IconClose.svelte +2 -2
- package/dist/icons/IconConfirm.svelte +2 -2
- package/dist/icons/IconDownload.svelte +17 -0
- package/dist/icons/IconDownload.svelte.d.ts +26 -0
- package/dist/icons/IconEmpty.svelte +2 -2
- package/dist/icons/IconFileUpload.svelte +2 -2
- package/dist/icons/IconGithub.svelte +2 -2
- package/dist/icons/IconImage.svelte +2 -2
- package/dist/icons/IconMinus.svelte +2 -2
- package/dist/icons/IconMoon.svelte +2 -2
- package/dist/icons/IconPaint.svelte +19 -0
- package/dist/icons/{IconSunrise.svelte.d.ts → IconPaint.svelte.d.ts} +3 -3
- package/dist/icons/IconPencil.svelte +13 -0
- package/dist/icons/IconPencil.svelte.d.ts +26 -0
- package/dist/icons/IconRadio.svelte +14 -0
- package/dist/icons/IconRadio.svelte.d.ts +22 -0
- package/dist/icons/IconSave.svelte +1 -1
- package/dist/icons/IconSave.svelte.d.ts +3 -3
- package/dist/icons/IconSaveOff.svelte +1 -1
- package/dist/icons/IconSaveOff.svelte.d.ts +3 -3
- package/dist/icons/IconSearch.svelte +2 -2
- package/dist/icons/IconSun.svelte +3 -3
- package/dist/icons/{IconSunrise.svelte → IconSunFull.svelte} +5 -4
- package/dist/icons/IconSunFull.svelte.d.ts +26 -0
- package/dist/icons/IconVideo.svelte +2 -2
- package/dist/icons/IconWatch.svelte +2 -2
- package/dist/icons/IconWatchOff.svelte +2 -2
- package/dist/inputs/NeoCheckbox.svelte +316 -0
- package/dist/inputs/NeoCheckbox.svelte.d.ts +19 -0
- package/dist/inputs/NeoColorPicker.svelte +140 -0
- package/dist/inputs/NeoColorPicker.svelte.d.ts +19 -0
- package/dist/inputs/NeoDateTime.svelte +96 -0
- package/dist/inputs/NeoDateTime.svelte.d.ts +19 -0
- package/dist/inputs/NeoFilePicker.svelte +528 -0
- package/dist/inputs/NeoFilePicker.svelte.d.ts +19 -0
- package/dist/inputs/NeoFilePickerCard.svelte +314 -0
- package/dist/inputs/NeoFilePickerCard.svelte.d.ts +19 -0
- package/dist/inputs/NeoNumberStep.svelte +174 -0
- package/dist/inputs/NeoNumberStep.svelte.d.ts +19 -0
- package/dist/inputs/NeoPassword.svelte +86 -17
- package/dist/inputs/NeoPassword.svelte.d.ts +19 -16
- package/dist/inputs/NeoPin.svelte +589 -0
- package/dist/inputs/NeoPin.svelte.d.ts +19 -0
- package/dist/inputs/NeoRadio.svelte +254 -0
- package/dist/inputs/NeoRadio.svelte.d.ts +19 -0
- package/dist/inputs/NeoRange.svelte +518 -0
- package/dist/inputs/NeoRange.svelte.d.ts +18 -0
- package/dist/inputs/NeoSwitch.svelte +373 -0
- package/dist/inputs/NeoSwitch.svelte.d.ts +19 -0
- package/dist/inputs/NeoTextarea.svelte +335 -301
- package/dist/inputs/NeoTextarea.svelte.d.ts +5 -2
- package/dist/inputs/common/NeoAffix.svelte +166 -0
- package/dist/inputs/common/NeoAffix.svelte.d.ts +19 -0
- package/dist/inputs/common/NeoBaseInput.svelte +338 -0
- package/dist/inputs/common/NeoBaseInput.svelte.d.ts +30 -0
- package/dist/inputs/common/NeoInput.svelte +684 -0
- package/dist/inputs/{NeoInput.svelte.d.ts → common/NeoInput.svelte.d.ts} +2 -10
- package/dist/inputs/common/NeoInputValidation.svelte +45 -0
- package/dist/inputs/common/NeoInputValidation.svelte.d.ts +22 -0
- package/dist/inputs/common/NeoLabel.svelte +93 -0
- package/dist/inputs/common/NeoLabel.svelte.d.ts +19 -0
- package/dist/inputs/{NeoValidation.svelte → common/NeoValidation.svelte} +9 -16
- package/dist/inputs/common/NeoValidation.svelte.d.ts +22 -0
- package/dist/inputs/common/neo-affix.model.d.ts +32 -0
- package/dist/inputs/common/neo-input-validation.model.d.ts +20 -0
- package/dist/inputs/common/neo-input-validation.model.js +1 -0
- package/dist/inputs/{neo-input.model.d.ts → common/neo-input.model.d.ts} +148 -68
- package/dist/inputs/common/neo-label.model.d.ts +36 -0
- package/dist/inputs/common/neo-label.model.js +1 -0
- package/dist/inputs/common/neo-validation.model.d.ts +70 -0
- package/dist/inputs/common/neo-validation.model.js +1 -0
- package/dist/inputs/index.d.ts +2 -2
- package/dist/inputs/index.js +1 -1
- package/dist/inputs/neo-checkbox.model.d.ts +9 -0
- package/dist/inputs/neo-checkbox.model.js +1 -0
- package/dist/inputs/neo-color-picker.model.d.ts +17 -0
- package/dist/inputs/neo-color-picker.model.js +1 -0
- package/dist/inputs/neo-date-time.model.d.ts +8 -0
- package/dist/inputs/neo-date-time.model.js +1 -0
- package/dist/inputs/neo-file-picker.model.d.ts +138 -0
- package/dist/inputs/neo-file-picker.model.js +1 -0
- package/dist/inputs/neo-number-step.model.d.ts +24 -0
- package/dist/inputs/neo-number-step.model.js +1 -0
- package/dist/inputs/neo-password.model.d.ts +13 -0
- package/dist/inputs/neo-password.model.js +1 -0
- package/dist/inputs/neo-pin.model.d.ts +47 -0
- package/dist/inputs/neo-pin.model.js +1 -0
- package/dist/inputs/neo-radio.model.d.ts +3 -0
- package/dist/inputs/neo-radio.model.js +1 -0
- package/dist/inputs/neo-switch.model.d.ts +9 -0
- package/dist/inputs/neo-switch.model.js +1 -0
- package/dist/nav/NeoTab.svelte +29 -25
- package/dist/nav/NeoTabPanel.svelte +1 -1
- package/dist/nav/NeoTabs.svelte +51 -44
- package/dist/nav/NeoTabsCard.svelte +8 -10
- package/dist/nav/neo-tabs-context.svelte.d.ts +2 -11
- package/dist/nav/neo-tabs-context.svelte.js +1 -41
- package/dist/nav/neo-tabs.model.d.ts +6 -0
- package/dist/providers/NeoThemeProvider.svelte +417 -305
- package/dist/providers/NeoThemeSelector.svelte +10 -10
- package/dist/providers/neo-theme-provider-context.svelte.js +16 -15
- package/dist/providers/neo-theme-provider.model.d.ts +6 -6
- package/dist/providers/neo-theme-provider.model.js +17 -12
- package/dist/providers/neo-theme-selector.model.d.ts +2 -2
- package/dist/skeletons/NeoSkeletonMedia.svelte +4 -4
- package/dist/skeletons/NeoSkeletonText.svelte +12 -12
- package/dist/styles/common/colors.scss +85 -97
- package/dist/styles/common/filters.scss +17 -0
- package/dist/styles/common/shadows.scss +531 -293
- package/dist/styles/common/spacing.scss +7 -3
- package/dist/styles/common/typography.scss +1 -1
- package/dist/styles/common/utils.scss +1 -1
- package/dist/styles/common/z-index.scss +1 -1
- package/dist/styles/mixin.scss +80 -27
- package/dist/styles/reset.scss +8 -1
- package/dist/styles/theme.scss +39 -16
- package/dist/utils/html-element.utils.d.ts +3 -0
- package/dist/utils/regex.utils.d.ts +3 -0
- package/dist/utils/regex.utils.js +3 -0
- package/dist/utils/shadow.utils.d.ts +30 -3
- package/dist/utils/shadow.utils.js +41 -14
- package/dist/utils/transition.utils.d.ts +4 -0
- package/dist/utils/transition.utils.js +10 -1
- package/dist/utils/utils.svelte.d.ts +6 -0
- package/dist/utils/utils.svelte.js +13 -0
- package/package.json +13 -12
- package/dist/inputs/NeoInput.svelte +0 -750
- package/dist/inputs/NeoValidation.svelte.d.ts +0 -22
- package/dist/inputs/neo-validation.model.d.ts +0 -40
- /package/dist/inputs/{neo-validation.model.js → common/neo-affix.model.js} +0 -0
- /package/dist/inputs/{neo-input.model.js → common/neo-input.model.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type NeoInputMethods, type NeoTextareaProps } from './neo-input.model.js';
|
|
1
|
+
import { type NeoInputMethods, type NeoTextareaProps } from './common/neo-input.model.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;
|
|
@@ -22,6 +22,9 @@ declare const NeoTextarea: $$__sveltets_2_IsomorphicComponent<NeoTextareaProps,
|
|
|
22
22
|
/**
|
|
23
23
|
* Clear the input state
|
|
24
24
|
*/ clear: NeoInputMethods<HTMLTextAreaElement>["clear"];
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Change the value of the input
|
|
27
|
+
*/ change: NeoInputMethods<HTMLTextAreaElement>["change"];
|
|
28
|
+
}, "value" | "ref" | "hovered" | "focused" | "touched" | "dirty" | "valid" | "labelRef" | "afterRef">;
|
|
26
29
|
type NeoTextarea = InstanceType<typeof NeoTextarea>;
|
|
27
30
|
export default NeoTextarea;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { fade } from 'svelte/transition';
|
|
3
|
+
|
|
4
|
+
import type { NeoAffixProps } from './neo-affix.model.js';
|
|
5
|
+
|
|
6
|
+
import IconAlert from '../../icons/IconAlert.svelte';
|
|
7
|
+
import IconCircleLoading from '../../icons/IconCircleLoading.svelte';
|
|
8
|
+
import IconClear from '../../icons/IconClear.svelte';
|
|
9
|
+
import IconConfirm from '../../icons/IconConfirm.svelte';
|
|
10
|
+
import { leaveDefaultTransition } from '../../utils/transition.utils.js';
|
|
11
|
+
|
|
12
|
+
/* eslint-disable prefer-const -- necessary for binding checked */
|
|
13
|
+
let {
|
|
14
|
+
// States
|
|
15
|
+
ref = $bindable(),
|
|
16
|
+
loading,
|
|
17
|
+
close,
|
|
18
|
+
valid,
|
|
19
|
+
skeleton,
|
|
20
|
+
disabled,
|
|
21
|
+
|
|
22
|
+
// Styles
|
|
23
|
+
size = '1.25rem',
|
|
24
|
+
|
|
25
|
+
// Other props
|
|
26
|
+
closeProps,
|
|
27
|
+
...rest
|
|
28
|
+
}: NeoAffixProps = $props();
|
|
29
|
+
/* eslint-enable prefer-const */
|
|
30
|
+
|
|
31
|
+
const leave = $derived(!loading && !close && valid === undefined ? undefined : leaveDefaultTransition);
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<span bind:this={ref} class:neo-affix-container={true} class:neo-skeleton={skeleton} style:--neo-affix-size={size} role="none" {...rest}>
|
|
35
|
+
{#if loading}
|
|
36
|
+
<span class="neo-affix-loading" out:fade={leave}>
|
|
37
|
+
<IconCircleLoading width={size} height={size} />
|
|
38
|
+
</span>
|
|
39
|
+
{:else if close && !disabled}
|
|
40
|
+
<button {disabled} class:neo-affix-clear={true} aria-label="clear" in:fade out:fade={leave} {...closeProps}>
|
|
41
|
+
<IconClear width={size} height={size} />
|
|
42
|
+
</button>
|
|
43
|
+
{:else}
|
|
44
|
+
<span class="neo-affix-validation" data-valid={valid} in:fade={leave}>
|
|
45
|
+
{#if valid !== undefined}
|
|
46
|
+
{#if valid}
|
|
47
|
+
<IconConfirm width={size} height={size} />
|
|
48
|
+
{:else}
|
|
49
|
+
<IconAlert width={size} height={size} />
|
|
50
|
+
{/if}
|
|
51
|
+
{/if}
|
|
52
|
+
</span>
|
|
53
|
+
{/if}
|
|
54
|
+
</span>
|
|
55
|
+
|
|
56
|
+
<style>.neo-affix-validation,
|
|
57
|
+
.neo-affix-loading,
|
|
58
|
+
.neo-affix-clear {
|
|
59
|
+
display: inline-flex;
|
|
60
|
+
box-sizing: border-box;
|
|
61
|
+
width: var(--neo-affix-size, 1.25rem);
|
|
62
|
+
height: var(--neo-affix-size, 1.25rem);
|
|
63
|
+
font: inherit;
|
|
64
|
+
text-decoration: none;
|
|
65
|
+
outline: none;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.neo-affix-container {
|
|
69
|
+
display: inline-grid;
|
|
70
|
+
grid-template-areas: "affix";
|
|
71
|
+
align-items: center;
|
|
72
|
+
box-sizing: border-box;
|
|
73
|
+
min-width: max-content;
|
|
74
|
+
min-height: max-content;
|
|
75
|
+
padding: var(--neo-affix-padding, 0.75rem);
|
|
76
|
+
border: none;
|
|
77
|
+
}
|
|
78
|
+
.neo-affix-container > * {
|
|
79
|
+
grid-area: affix;
|
|
80
|
+
}
|
|
81
|
+
.neo-affix-container .neo-affix-validation {
|
|
82
|
+
display: inline-flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
}
|
|
85
|
+
.neo-affix-container .neo-affix-validation[data-valid=true] {
|
|
86
|
+
color: var(--neo-affix-validation-color-success, var(--neo-color-success));
|
|
87
|
+
}
|
|
88
|
+
.neo-affix-container .neo-affix-validation[data-valid=false] {
|
|
89
|
+
color: var(--neo-affix-validation-color-error, var(--neo-color-error));
|
|
90
|
+
}
|
|
91
|
+
.neo-affix-container .neo-affix-clear {
|
|
92
|
+
align-items: center;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
margin: 0;
|
|
95
|
+
padding: 0;
|
|
96
|
+
color: var(--neo-affix-clear-color, inherit);
|
|
97
|
+
background-color: var(--neo-background-color-darker);
|
|
98
|
+
border: none;
|
|
99
|
+
border-radius: 50%;
|
|
100
|
+
aspect-ratio: 1;
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
transition: opacity 0.2s ease-in, color 0.3s ease, background-color 0.3s ease;
|
|
103
|
+
}
|
|
104
|
+
.neo-affix-container .neo-affix-clear :global(svg) {
|
|
105
|
+
width: 100%;
|
|
106
|
+
height: 100%;
|
|
107
|
+
margin: -0.05rem;
|
|
108
|
+
padding: 0.05rem;
|
|
109
|
+
}
|
|
110
|
+
.neo-affix-container .neo-affix-clear:focus-visible {
|
|
111
|
+
color: var(--neo-close-color-focused, rgba(255, 0, 0, 0.5));
|
|
112
|
+
background-color: var(--neo-close-bg-color-focused, rgba(255, 0, 0, 0.05));
|
|
113
|
+
}
|
|
114
|
+
.neo-affix-container .neo-affix-clear:hover {
|
|
115
|
+
color: var(--neo-close-color-hover, rgba(255, 0, 0, 0.75));
|
|
116
|
+
background-color: var(--neo-close-bg-color-hover, rgba(255, 0, 0, 0.07));
|
|
117
|
+
}
|
|
118
|
+
.neo-affix-container .neo-affix-clear:active {
|
|
119
|
+
color: var(--neo-affix-active-color, var(--neo-text-color-hover-active));
|
|
120
|
+
scale: 0.9;
|
|
121
|
+
}
|
|
122
|
+
.neo-affix-container .neo-affix-clear:disabled {
|
|
123
|
+
color: var(--neo-text-color-disabled);
|
|
124
|
+
cursor: not-allowed;
|
|
125
|
+
scale: 1;
|
|
126
|
+
}
|
|
127
|
+
.neo-affix-container.neo-skeleton > * {
|
|
128
|
+
border-radius: 50%;
|
|
129
|
+
--neo-skeleton-color-start: var(--neo-skeleton-color);
|
|
130
|
+
--neo-skeleton-color-end: oklch(from var(--neo-skeleton-color) calc(l - var(--neo-skeleton-color-step, 0.05)) c h);
|
|
131
|
+
color: var(--neo-skeleton-color-start);
|
|
132
|
+
background-color: var(--neo-skeleton-color-start);
|
|
133
|
+
border-color: var(--neo-skeleton-color-start);
|
|
134
|
+
transition: background-color 1s ease, color 1s ease, border-color 1s ease;
|
|
135
|
+
animation: skeleton 3s var(--neo-transition-skeleton) infinite;
|
|
136
|
+
animation-delay: 1s;
|
|
137
|
+
}
|
|
138
|
+
.neo-affix-container.neo-skeleton > *::before, .neo-affix-container.neo-skeleton > *::after,
|
|
139
|
+
.neo-affix-container.neo-skeleton > * :global(> *::before),
|
|
140
|
+
.neo-affix-container.neo-skeleton > * :global(> *::after),
|
|
141
|
+
.neo-affix-container.neo-skeleton > * :global(> *) {
|
|
142
|
+
visibility: hidden;
|
|
143
|
+
pointer-events: none;
|
|
144
|
+
}
|
|
145
|
+
@keyframes skeleton {
|
|
146
|
+
0% {
|
|
147
|
+
color: var(--neo-skeleton-color-start);
|
|
148
|
+
background-color: var(--neo-skeleton-color-start);
|
|
149
|
+
border-color: var(--neo-skeleton-color-start);
|
|
150
|
+
}
|
|
151
|
+
40% {
|
|
152
|
+
color: var(--neo-skeleton-color-end);
|
|
153
|
+
background-color: var(--neo-skeleton-color-end);
|
|
154
|
+
border-color: var(--neo-skeleton-color-end);
|
|
155
|
+
}
|
|
156
|
+
80% {
|
|
157
|
+
color: var(--neo-skeleton-color-start);
|
|
158
|
+
background-color: var(--neo-skeleton-color-start);
|
|
159
|
+
border-color: var(--neo-skeleton-color-start);
|
|
160
|
+
}
|
|
161
|
+
100% {
|
|
162
|
+
color: var(--neo-skeleton-color-start);
|
|
163
|
+
background-color: var(--neo-skeleton-color-start);
|
|
164
|
+
border-color: var(--neo-skeleton-color-start);
|
|
165
|
+
}
|
|
166
|
+
}</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { NeoAffixProps } from './neo-affix.model.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 NeoAffix: $$__sveltets_2_IsomorphicComponent<NeoAffixProps, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, "ref">;
|
|
18
|
+
type NeoAffix = InstanceType<typeof NeoAffix>;
|
|
19
|
+
export default NeoAffix;
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { tick } from 'svelte';
|
|
3
|
+
|
|
4
|
+
import type { EventHandler, FocusEventHandler, FormEventHandler } from 'svelte/elements';
|
|
5
|
+
|
|
6
|
+
import type { SvelteEvent } from '../../utils/html-element.utils.js';
|
|
7
|
+
|
|
8
|
+
import { type NeoBaseInputProps, type NeoInputMethods, type NeoInputState, type NeoInputValue } from './neo-input.model.js';
|
|
9
|
+
import { toAction, toActionProps } from '../../utils/action.utils.js';
|
|
10
|
+
|
|
11
|
+
/* eslint-disable prefer-const -- necessary for binding checked */
|
|
12
|
+
let {
|
|
13
|
+
// States
|
|
14
|
+
id,
|
|
15
|
+
ref = $bindable(),
|
|
16
|
+
|
|
17
|
+
files = $bindable(), // type="file"
|
|
18
|
+
value = $bindable(),
|
|
19
|
+
group = $bindable(), // type="radio"
|
|
20
|
+
checked = $bindable(), // type="checkbox"
|
|
21
|
+
indeterminate = $bindable(), // type="checkbox"
|
|
22
|
+
|
|
23
|
+
initial = $bindable(),
|
|
24
|
+
touched = $bindable(false),
|
|
25
|
+
valid = $bindable(),
|
|
26
|
+
dirty = $bindable(false),
|
|
27
|
+
focused = $bindable(false),
|
|
28
|
+
disabled,
|
|
29
|
+
readonly,
|
|
30
|
+
nullable = true,
|
|
31
|
+
|
|
32
|
+
dirtyOnInput,
|
|
33
|
+
dirtyOnBlur,
|
|
34
|
+
validateOnInput,
|
|
35
|
+
validateOnBlur,
|
|
36
|
+
validationMessage = $bindable(),
|
|
37
|
+
|
|
38
|
+
// Styles
|
|
39
|
+
before,
|
|
40
|
+
after,
|
|
41
|
+
|
|
42
|
+
// Actions
|
|
43
|
+
use,
|
|
44
|
+
|
|
45
|
+
// Events
|
|
46
|
+
onblur,
|
|
47
|
+
onfocus,
|
|
48
|
+
oninput,
|
|
49
|
+
onchange,
|
|
50
|
+
oninvalid,
|
|
51
|
+
|
|
52
|
+
onclear,
|
|
53
|
+
onmark,
|
|
54
|
+
|
|
55
|
+
// Other props
|
|
56
|
+
...rest
|
|
57
|
+
}: NeoBaseInputProps = $props();
|
|
58
|
+
/* eslint-enable prefer-const */
|
|
59
|
+
|
|
60
|
+
const getValue = () => {
|
|
61
|
+
if (rest.type === 'file') return files;
|
|
62
|
+
if (rest.type === 'checkbox' || rest.type === 'radio') return checked;
|
|
63
|
+
return value;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const typedValue = $derived(getValue());
|
|
67
|
+
const hasValue = () => {
|
|
68
|
+
if (rest?.type === 'file') return !!files?.length;
|
|
69
|
+
if (rest?.type === 'checkbox' || rest.type === 'radio') return checked !== undefined;
|
|
70
|
+
if (typeof value === 'string') return !!value.length;
|
|
71
|
+
return value !== undefined && value !== null;
|
|
72
|
+
};
|
|
73
|
+
const fallback = () => {
|
|
74
|
+
if (nullable) return value;
|
|
75
|
+
if (rest?.defaultValue === undefined) return value;
|
|
76
|
+
if (rest.type && ['file', 'checkbox', 'radio'].includes(rest.type)) return value;
|
|
77
|
+
if (hasValue()) return value;
|
|
78
|
+
value = rest?.defaultValue;
|
|
79
|
+
return value;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const reset = () => {
|
|
83
|
+
if (rest.type === 'checkbox' || rest.type === 'radio') {
|
|
84
|
+
checked = rest?.defaultChecked ?? rest?.defaultValue ?? false;
|
|
85
|
+
if (rest.type === 'checkbox') indeterminate = false;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
value = nullable ? '' : (rest?.defaultValue ?? '');
|
|
89
|
+
if (rest.type === 'file') files = new DataTransfer().files;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const currentState = $derived<NeoInputState<HTMLInputElement>>({ touched, dirty, valid, value: typedValue, initial });
|
|
93
|
+
|
|
94
|
+
const validate: NeoInputMethods<HTMLInputElement>['validate'] = (update: { dirty?: boolean; valid?: boolean } = { dirty: true, valid: true }) => {
|
|
95
|
+
if (update.dirty) dirty = typedValue !== initial;
|
|
96
|
+
if (!update.valid) return { ...currentState };
|
|
97
|
+
valid = ref?.checkValidity();
|
|
98
|
+
validationMessage = ref?.validationMessage;
|
|
99
|
+
return { ...currentState };
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Change the state of the input
|
|
104
|
+
* @param state
|
|
105
|
+
*/
|
|
106
|
+
export const mark: NeoInputMethods<HTMLInputElement>['mark'] = (state: NeoInputState<HTMLInputElement>) => {
|
|
107
|
+
if (state.touched !== undefined) touched = state.touched;
|
|
108
|
+
if (state.valid !== undefined) valid = state.valid;
|
|
109
|
+
if (state.dirty === undefined) return onmark?.({ ...currentState });
|
|
110
|
+
dirty = state.dirty;
|
|
111
|
+
if (!dirty) initial = typedValue;
|
|
112
|
+
return onmark?.({ ...currentState });
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const focus = () => {
|
|
116
|
+
if (focused || disabled || readonly) return;
|
|
117
|
+
ref?.focus();
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Clear the input state
|
|
122
|
+
*/
|
|
123
|
+
export const clear: NeoInputMethods<HTMLInputElement>['clear'] = async (
|
|
124
|
+
state?: NeoInputState<HTMLInputElement>,
|
|
125
|
+
event?: InputEvent | SvelteEvent<InputEvent>,
|
|
126
|
+
) => {
|
|
127
|
+
reset();
|
|
128
|
+
await tick();
|
|
129
|
+
focus();
|
|
130
|
+
if (state) mark({ touched: false, dirty: false, ...state });
|
|
131
|
+
else validate();
|
|
132
|
+
onclear?.({ ...currentState }, event);
|
|
133
|
+
if (event) return ref?.dispatchEvent(event);
|
|
134
|
+
const _event: InputEventInit = { bubbles: true, cancelable: false, data: value, inputType: 'clear' };
|
|
135
|
+
oninput?.(new InputEvent('input', _event) as SvelteEvent<InputEvent, any>);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Change the state of the input
|
|
140
|
+
*/
|
|
141
|
+
export const change: NeoInputMethods<HTMLInputElement>['change'] = (_value: NeoInputValue<HTMLInputElement>, event?: InputEvent) => {
|
|
142
|
+
if (rest.type === 'checkbox' || rest.type === 'radio') {
|
|
143
|
+
checked = !!_value;
|
|
144
|
+
} else {
|
|
145
|
+
value = _value?.toString();
|
|
146
|
+
}
|
|
147
|
+
focus();
|
|
148
|
+
if (event) ref?.dispatchEvent(event);
|
|
149
|
+
return validate();
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const onFocus: FocusEventHandler<HTMLInputElement> = e => {
|
|
153
|
+
focused = true;
|
|
154
|
+
touched = true;
|
|
155
|
+
onfocus?.(e);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const onBlur: FocusEventHandler<HTMLInputElement> = e => {
|
|
159
|
+
focused = false;
|
|
160
|
+
validate({ dirty: dirtyOnBlur, valid: validateOnBlur });
|
|
161
|
+
onblur?.(e);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const onInput: FormEventHandler<HTMLInputElement> = e => {
|
|
165
|
+
touched = true;
|
|
166
|
+
validate({ dirty: dirtyOnInput, valid: validateOnInput });
|
|
167
|
+
oninput?.(e);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const onChange: FormEventHandler<HTMLInputElement> = e => {
|
|
171
|
+
touched = true;
|
|
172
|
+
validate();
|
|
173
|
+
fallback();
|
|
174
|
+
onchange?.(e);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const onInvalid: EventHandler<Event, HTMLInputElement> = e => {
|
|
178
|
+
valid = false;
|
|
179
|
+
validationMessage = ref?.validationMessage;
|
|
180
|
+
e.preventDefault();
|
|
181
|
+
oninvalid?.(e);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
$effect(() => {
|
|
185
|
+
if (!ref) return;
|
|
186
|
+
Object.assign(ref, { mark, clear, change, validate });
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
$effect(() => {
|
|
190
|
+
if (group === undefined) return;
|
|
191
|
+
checked = !!ref?.checked;
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const useFn = $derived(toAction(use));
|
|
195
|
+
const useProps = $derived(toActionProps(use));
|
|
196
|
+
</script>
|
|
197
|
+
|
|
198
|
+
{#if rest.type === 'file'}
|
|
199
|
+
<input
|
|
200
|
+
aria-invalid={valid === undefined ? undefined : !valid}
|
|
201
|
+
type="file"
|
|
202
|
+
{id}
|
|
203
|
+
{disabled}
|
|
204
|
+
{readonly}
|
|
205
|
+
bind:this={ref}
|
|
206
|
+
bind:files
|
|
207
|
+
bind:value
|
|
208
|
+
bind:group
|
|
209
|
+
bind:indeterminate
|
|
210
|
+
class:neo-input={true}
|
|
211
|
+
class:neo-after={after}
|
|
212
|
+
class:neo-before={before}
|
|
213
|
+
onblur={onBlur}
|
|
214
|
+
onfocus={onFocus}
|
|
215
|
+
oninput={onInput}
|
|
216
|
+
onchange={onChange}
|
|
217
|
+
oninvalid={onInvalid}
|
|
218
|
+
use:useFn={useProps}
|
|
219
|
+
{...rest}
|
|
220
|
+
/>
|
|
221
|
+
{:else if rest.type === 'checkbox'}
|
|
222
|
+
<input
|
|
223
|
+
aria-invalid={valid === undefined ? undefined : !valid}
|
|
224
|
+
type="checkbox"
|
|
225
|
+
{id}
|
|
226
|
+
{disabled}
|
|
227
|
+
{readonly}
|
|
228
|
+
{value}
|
|
229
|
+
bind:this={ref}
|
|
230
|
+
bind:group
|
|
231
|
+
bind:checked
|
|
232
|
+
bind:indeterminate
|
|
233
|
+
class:neo-input={true}
|
|
234
|
+
class:neo-after={after}
|
|
235
|
+
class:neo-before={before}
|
|
236
|
+
onblur={onBlur}
|
|
237
|
+
onfocus={onFocus}
|
|
238
|
+
oninput={onInput}
|
|
239
|
+
onchange={onChange}
|
|
240
|
+
oninvalid={onInvalid}
|
|
241
|
+
use:useFn={useProps}
|
|
242
|
+
{...rest}
|
|
243
|
+
/>
|
|
244
|
+
{:else if rest.type === 'radio'}
|
|
245
|
+
<input
|
|
246
|
+
type="radio"
|
|
247
|
+
{id}
|
|
248
|
+
{disabled}
|
|
249
|
+
{readonly}
|
|
250
|
+
{value}
|
|
251
|
+
bind:this={ref}
|
|
252
|
+
bind:group
|
|
253
|
+
bind:indeterminate
|
|
254
|
+
class:neo-input={true}
|
|
255
|
+
class:neo-after={after}
|
|
256
|
+
class:neo-before={before}
|
|
257
|
+
onblur={onBlur}
|
|
258
|
+
onfocus={onFocus}
|
|
259
|
+
oninput={onInput}
|
|
260
|
+
onchange={onChange}
|
|
261
|
+
oninvalid={onInvalid}
|
|
262
|
+
use:useFn={useProps}
|
|
263
|
+
{...rest}
|
|
264
|
+
/>
|
|
265
|
+
{:else}
|
|
266
|
+
<input
|
|
267
|
+
aria-invalid={valid === undefined ? undefined : !valid}
|
|
268
|
+
{id}
|
|
269
|
+
{disabled}
|
|
270
|
+
{readonly}
|
|
271
|
+
bind:this={ref}
|
|
272
|
+
bind:value
|
|
273
|
+
bind:group
|
|
274
|
+
bind:indeterminate
|
|
275
|
+
class:neo-input={true}
|
|
276
|
+
class:neo-after={after}
|
|
277
|
+
class:neo-before={before}
|
|
278
|
+
onblur={onBlur}
|
|
279
|
+
onfocus={onFocus}
|
|
280
|
+
oninput={onInput}
|
|
281
|
+
onchange={onChange}
|
|
282
|
+
oninvalid={onInvalid}
|
|
283
|
+
use:useFn={useProps}
|
|
284
|
+
{...rest}
|
|
285
|
+
/>
|
|
286
|
+
{/if}
|
|
287
|
+
|
|
288
|
+
<style>.neo-input {
|
|
289
|
+
display: inline-flex;
|
|
290
|
+
flex: 1 1 auto;
|
|
291
|
+
align-self: center;
|
|
292
|
+
box-sizing: border-box;
|
|
293
|
+
width: 100%;
|
|
294
|
+
min-width: var(--neo-input-min-width, 1ch);
|
|
295
|
+
max-width: 100%;
|
|
296
|
+
min-height: var(--neo-input-min-height, fit-content);
|
|
297
|
+
padding: var(--neo-input-padding, 0.75rem);
|
|
298
|
+
color: inherit;
|
|
299
|
+
font: inherit;
|
|
300
|
+
text-decoration: none;
|
|
301
|
+
text-overflow: ellipsis;
|
|
302
|
+
background-color: transparent;
|
|
303
|
+
border: none;
|
|
304
|
+
border-radius: var(--neo-input-border-radius, var(--neo-border-radius));
|
|
305
|
+
outline: none;
|
|
306
|
+
transition: color 0.3s ease, margin 0.3s ease, padding 0.3s ease, background-color 0.3s ease, backdrop-filter 0.3s ease, border-color 0.3s ease, border-radius 0.3s ease, box-shadow 0.3s ease-out;
|
|
307
|
+
}
|
|
308
|
+
.neo-input.neo-before {
|
|
309
|
+
padding-left: 0;
|
|
310
|
+
border-top-left-radius: 0;
|
|
311
|
+
border-bottom-left-radius: 0;
|
|
312
|
+
}
|
|
313
|
+
.neo-input.neo-after {
|
|
314
|
+
padding-right: 0;
|
|
315
|
+
border-top-right-radius: 0;
|
|
316
|
+
border-bottom-right-radius: 0;
|
|
317
|
+
}
|
|
318
|
+
.neo-input::placeholder {
|
|
319
|
+
color: var(--neo-input-placeholder-color, var(--neo-text-color-disabled));
|
|
320
|
+
transition: opacity 0.3s ease;
|
|
321
|
+
}
|
|
322
|
+
.neo-input:read-only {
|
|
323
|
+
cursor: inherit;
|
|
324
|
+
}
|
|
325
|
+
.neo-input:disabled {
|
|
326
|
+
color: var(--neo-text-color-disabled);
|
|
327
|
+
cursor: not-allowed;
|
|
328
|
+
}
|
|
329
|
+
.neo-input[type=password]:not(:placeholder-shown) {
|
|
330
|
+
letter-spacing: 0.2em;
|
|
331
|
+
-webkit-text-stroke-width: 0.15em;
|
|
332
|
+
}
|
|
333
|
+
@supports (-webkit-touch-callout: none) {
|
|
334
|
+
.neo-input[type=password]:not(:placeholder-shown) {
|
|
335
|
+
font: small-caption;
|
|
336
|
+
font-size: var(--neo-font-size-xs, 0.75rem);
|
|
337
|
+
}
|
|
338
|
+
}</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type NeoBaseInputProps, type NeoInputMethods } from './neo-input.model.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 NeoBaseInput: $$__sveltets_2_IsomorphicComponent<NeoBaseInputProps, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {
|
|
18
|
+
/**
|
|
19
|
+
* Change the state of the input
|
|
20
|
+
* @param state
|
|
21
|
+
*/ mark: NeoInputMethods<HTMLInputElement>["mark"];
|
|
22
|
+
/**
|
|
23
|
+
* Clear the input state
|
|
24
|
+
*/ clear: NeoInputMethods<HTMLInputElement>["clear"];
|
|
25
|
+
/**
|
|
26
|
+
* Change the state of the input
|
|
27
|
+
*/ change: NeoInputMethods<HTMLInputElement>["change"];
|
|
28
|
+
}, "value" | "group" | "ref" | "checked" | "focused" | "validationMessage" | "files" | "indeterminate" | "touched" | "dirty" | "valid" | "initial">;
|
|
29
|
+
type NeoBaseInput = InstanceType<typeof NeoBaseInput>;
|
|
30
|
+
export default NeoBaseInput;
|