@flightlesslabs/dodo-ui 0.2.0 → 0.3.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/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/stories/Home.mdx +1 -1
- package/dist/stories/components/Form/Button/Button.stories.svelte +10 -5
- package/dist/stories/components/Form/Button/Button.svelte +213 -208
- package/dist/stories/components/Form/Button/Button.svelte.d.ts +4 -1
- package/dist/stories/components/Form/Button/Events/Events.stories.svelte +40 -0
- package/dist/stories/components/Form/Button/Events/Events.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/Button/utils/scss/mixins.scss +21 -21
- package/dist/stories/components/Form/PasswordInput/Events/Events.stories.svelte +168 -0
- package/dist/stories/components/Form/PasswordInput/Events/Events.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/PasswordInput/PasswordInput.stories.svelte +37 -0
- package/dist/stories/components/Form/PasswordInput/PasswordInput.stories.svelte.d.ts +21 -0
- package/dist/stories/components/Form/PasswordInput/PasswordInput.svelte +219 -0
- package/dist/stories/components/Form/PasswordInput/PasswordInput.svelte.d.ts +59 -0
- package/dist/stories/components/Form/PasswordInput/Roundness/Roundness.stories.svelte +20 -0
- package/dist/stories/components/Form/{ExampleButton/ExampleButton.stories.svelte.d.ts → PasswordInput/Roundness/Roundness.stories.svelte.d.ts} +3 -4
- package/dist/stories/components/Form/PasswordInput/Size/Size.stories.svelte +16 -0
- package/dist/stories/components/Form/PasswordInput/Size/Size.stories.svelte.d.ts +26 -0
- package/dist/stories/components/Form/PasswordInput/WithIcon/WithIcon.stories.svelte +31 -0
- package/dist/stories/components/Form/PasswordInput/WithIcon/WithIcon.stories.svelte.d.ts +26 -0
- package/dist/stories/components/Form/TextInput/Events/Events.stories.svelte +148 -0
- package/dist/stories/components/Form/TextInput/Events/Events.stories.svelte.d.ts +18 -0
- package/dist/stories/components/Form/TextInput/Roundness/Roundness.stories.svelte +21 -0
- package/dist/stories/components/Form/TextInput/Roundness/Roundness.stories.svelte.d.ts +26 -0
- package/dist/stories/components/Form/TextInput/Size/Size.stories.svelte +17 -0
- package/dist/stories/components/Form/TextInput/Size/Size.stories.svelte.d.ts +26 -0
- package/dist/stories/components/Form/TextInput/TextInput.stories.svelte +35 -0
- package/dist/stories/components/Form/TextInput/TextInput.stories.svelte.d.ts +21 -0
- package/dist/stories/components/Form/TextInput/TextInput.svelte +166 -0
- package/dist/stories/components/Form/TextInput/TextInput.svelte.d.ts +56 -0
- package/dist/stories/components/Form/TextInput/WithIcon/WithIcon.stories.svelte +47 -0
- package/dist/stories/components/Form/TextInput/WithIcon/WithIcon.stories.svelte.d.ts +26 -0
- package/dist/styles/_components.css +8 -7
- package/dist/styles/_minimal-reset.css +3 -0
- package/dist/styles/global.css +1 -0
- package/package.json +1 -1
- package/src/lib/index.ts +13 -0
- package/src/lib/stories/components/Form/Button/Button.stories.svelte +10 -5
- package/src/lib/stories/components/Form/Button/Button.svelte +32 -22
- package/src/lib/stories/components/Form/Button/Events/Events.stories.svelte +42 -0
- package/src/lib/stories/components/Form/Button/utils/scss/mixins.scss +21 -21
- package/src/lib/stories/components/Form/PasswordInput/Events/Events.stories.svelte +174 -0
- package/src/lib/stories/components/Form/PasswordInput/PasswordInput.stories.svelte +41 -0
- package/src/lib/stories/components/Form/PasswordInput/PasswordInput.svelte +361 -0
- package/src/lib/stories/components/Form/PasswordInput/Roundness/Roundness.stories.svelte +20 -0
- package/src/lib/stories/components/Form/PasswordInput/Size/Size.stories.svelte +16 -0
- package/src/lib/stories/components/Form/PasswordInput/WithIcon/WithIcon.stories.svelte +31 -0
- package/src/lib/stories/components/Form/TextInput/Events/Events.stories.svelte +153 -0
- package/src/lib/stories/components/Form/TextInput/Roundness/Roundness.stories.svelte +21 -0
- package/src/lib/stories/components/Form/TextInput/Size/Size.stories.svelte +17 -0
- package/src/lib/stories/components/Form/TextInput/TextInput.stories.svelte +39 -0
- package/src/lib/stories/components/Form/TextInput/TextInput.svelte +293 -0
- package/src/lib/stories/components/Form/TextInput/WithIcon/WithIcon.stories.svelte +47 -0
- package/src/lib/styles/_components.css +8 -7
- package/src/lib/styles/_minimal-reset.css +3 -0
- package/src/lib/styles/global.css +1 -0
- package/dist/stories/components/Form/ExampleButton/ExampleButton.stories.svelte +0 -30
- package/dist/stories/components/Form/ExampleButton/ExampleButton.svelte +0 -14
- package/dist/stories/components/Form/ExampleButton/ExampleButton.svelte.d.ts +0 -16
- package/dist/stories/components/Form/ExampleButton/button.css +0 -30
- package/src/lib/stories/components/Form/ExampleButton/ExampleButton.stories.svelte +0 -30
- package/src/lib/stories/components/Form/ExampleButton/ExampleButton.svelte +0 -29
- package/src/lib/stories/components/Form/ExampleButton/button.css +0 -30
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import PasswordInput from '../PasswordInput.svelte';
|
|
4
|
+
import { storyPasswordInputArgTypes } from '../PasswordInput.stories.svelte';
|
|
5
|
+
import Icon from '@iconify/svelte';
|
|
6
|
+
|
|
7
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
8
|
+
const { Story } = defineMeta({
|
|
9
|
+
component: PasswordInput,
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
argTypes: storyPasswordInputArgTypes,
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<!-- PasswordInput icon in front. -->
|
|
16
|
+
<Story name="Icon Before">
|
|
17
|
+
<PasswordInput>
|
|
18
|
+
{#snippet before()}
|
|
19
|
+
<Icon icon="material-symbols:content-copy" />
|
|
20
|
+
{/snippet}
|
|
21
|
+
</PasswordInput>
|
|
22
|
+
</Story>
|
|
23
|
+
|
|
24
|
+
<!-- PasswordInput icon in front. -->
|
|
25
|
+
<Story name="Icon After">
|
|
26
|
+
<PasswordInput>
|
|
27
|
+
{#snippet after()}
|
|
28
|
+
<Icon icon="material-symbols:download-2" />
|
|
29
|
+
{/snippet}
|
|
30
|
+
</PasswordInput>
|
|
31
|
+
</Story>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import TextInput, {
|
|
4
|
+
type TextInputClipboardEvent,
|
|
5
|
+
type TextInputFocusEvent,
|
|
6
|
+
} from '../TextInput.svelte';
|
|
7
|
+
import { storyTextInputArgTypes } from '../TextInput.stories.svelte';
|
|
8
|
+
|
|
9
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
10
|
+
const { Story } = defineMeta({
|
|
11
|
+
component: TextInput,
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
argTypes: storyTextInputArgTypes,
|
|
14
|
+
});
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<Story
|
|
18
|
+
name="Input"
|
|
19
|
+
args={{
|
|
20
|
+
oninput: (e: Event) => {
|
|
21
|
+
const target = e.target as HTMLInputElement;
|
|
22
|
+
|
|
23
|
+
console.log('Input Event', target.value);
|
|
24
|
+
},
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
<TextInput
|
|
28
|
+
oninput={(e: Event) => {
|
|
29
|
+
const target = e.target as HTMLInputElement;
|
|
30
|
+
|
|
31
|
+
console.log('Input Event', target.value);
|
|
32
|
+
}}
|
|
33
|
+
/>
|
|
34
|
+
</Story>
|
|
35
|
+
|
|
36
|
+
<Story
|
|
37
|
+
name="Change"
|
|
38
|
+
args={{
|
|
39
|
+
onchange: (e: Event) => {
|
|
40
|
+
const target = e.target as HTMLInputElement;
|
|
41
|
+
|
|
42
|
+
console.log('onChange Event', target.value);
|
|
43
|
+
},
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<TextInput
|
|
47
|
+
onchange={(e: Event) => {
|
|
48
|
+
const target = e.target as HTMLInputElement;
|
|
49
|
+
|
|
50
|
+
console.log('onchange Event', target.value);
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
</Story>
|
|
54
|
+
|
|
55
|
+
<!-- `e: TextInputFocusEvent` -->
|
|
56
|
+
<Story
|
|
57
|
+
name="Focus"
|
|
58
|
+
args={{
|
|
59
|
+
onfocus: (e: TextInputFocusEvent) => {
|
|
60
|
+
const target = e.target as HTMLInputElement;
|
|
61
|
+
|
|
62
|
+
console.log('onfocus Event', target);
|
|
63
|
+
},
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<TextInput
|
|
67
|
+
onfocus={(e: TextInputFocusEvent) => {
|
|
68
|
+
const target = e.target as HTMLInputElement;
|
|
69
|
+
|
|
70
|
+
console.log('onfocus Event', target);
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
</Story>
|
|
74
|
+
|
|
75
|
+
<!-- `e: TextInputFocusEvent` -->
|
|
76
|
+
<Story
|
|
77
|
+
name="Blur"
|
|
78
|
+
args={{
|
|
79
|
+
onblur: (e: TextInputFocusEvent) => {
|
|
80
|
+
const target = e.target as HTMLInputElement;
|
|
81
|
+
|
|
82
|
+
console.log('onblur Event', target);
|
|
83
|
+
},
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
<TextInput
|
|
87
|
+
onblur={(e: TextInputFocusEvent) => {
|
|
88
|
+
const target = e.target as HTMLInputElement;
|
|
89
|
+
|
|
90
|
+
console.log('onblur Event', target);
|
|
91
|
+
}}
|
|
92
|
+
/>
|
|
93
|
+
</Story>
|
|
94
|
+
|
|
95
|
+
<!-- `e: TextInputClipboardEvent` -->
|
|
96
|
+
<Story
|
|
97
|
+
name="Copy"
|
|
98
|
+
args={{
|
|
99
|
+
oncopy: (e: TextInputClipboardEvent) => {
|
|
100
|
+
const target = e.target as HTMLInputElement;
|
|
101
|
+
|
|
102
|
+
console.log('oncopy Event', target);
|
|
103
|
+
},
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
<TextInput
|
|
107
|
+
oncopy={(e: TextInputClipboardEvent) => {
|
|
108
|
+
const target = e.target as HTMLInputElement;
|
|
109
|
+
|
|
110
|
+
console.log('oncopy Event', target);
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
</Story>
|
|
114
|
+
|
|
115
|
+
<!-- `e: TextInputClipboardEvent` -->
|
|
116
|
+
<Story
|
|
117
|
+
name="Cut"
|
|
118
|
+
args={{
|
|
119
|
+
oncut: (e: TextInputClipboardEvent) => {
|
|
120
|
+
const target = e.target as HTMLInputElement;
|
|
121
|
+
|
|
122
|
+
console.log('oncut Event', target);
|
|
123
|
+
},
|
|
124
|
+
}}
|
|
125
|
+
>
|
|
126
|
+
<TextInput
|
|
127
|
+
oncut={(e: TextInputClipboardEvent) => {
|
|
128
|
+
const target = e.target as HTMLInputElement;
|
|
129
|
+
|
|
130
|
+
console.log('oncut Event', target);
|
|
131
|
+
}}
|
|
132
|
+
/>
|
|
133
|
+
</Story>
|
|
134
|
+
|
|
135
|
+
<!-- `e: TextInputClipboardEvent` -->
|
|
136
|
+
<Story
|
|
137
|
+
name="Paste"
|
|
138
|
+
args={{
|
|
139
|
+
onpaste: (e: TextInputClipboardEvent) => {
|
|
140
|
+
const target = e.target as HTMLInputElement;
|
|
141
|
+
|
|
142
|
+
console.log('onpaste Event', target);
|
|
143
|
+
},
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
<TextInput
|
|
147
|
+
onpaste={(e: TextInputClipboardEvent) => {
|
|
148
|
+
const target = e.target as HTMLInputElement;
|
|
149
|
+
|
|
150
|
+
console.log('onpaste Event', target);
|
|
151
|
+
}}
|
|
152
|
+
/>
|
|
153
|
+
</Story>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import TextInput from '../TextInput.svelte';
|
|
4
|
+
import { storyTextInputArgTypes } from '../TextInput.stories.svelte';
|
|
5
|
+
|
|
6
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
7
|
+
const { Story } = defineMeta({
|
|
8
|
+
component: TextInput,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: storyTextInputArgTypes,
|
|
11
|
+
args: { value: 'Hello world!' },
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<Story name="Roundness 1x" />
|
|
16
|
+
|
|
17
|
+
<Story name="Roundness 2x" args={{ roundness: '2x' }} />
|
|
18
|
+
|
|
19
|
+
<Story name="Roundness 3x" args={{ roundness: '3x' }} />
|
|
20
|
+
|
|
21
|
+
<Story name="Roundness False" args={{ roundness: false }} />
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import TextInput from '../TextInput.svelte';
|
|
4
|
+
import { storyTextInputArgTypes } from '../TextInput.stories.svelte';
|
|
5
|
+
|
|
6
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
7
|
+
const { Story } = defineMeta({
|
|
8
|
+
component: TextInput,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: storyTextInputArgTypes,
|
|
11
|
+
args: { value: 'Hello world!' },
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<Story name="Normal" />
|
|
16
|
+
<Story name="Small" args={{ size: 'small' }} />
|
|
17
|
+
<Story name="Large" args={{ size: 'large' }} />
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import TextInput from './TextInput.svelte';
|
|
4
|
+
import type { StoryBookArgTypes } from '$lib/storybook-types.js';
|
|
5
|
+
|
|
6
|
+
export const storyTextInputArgTypes: StoryBookArgTypes = {
|
|
7
|
+
type: {
|
|
8
|
+
control: { type: 'select' },
|
|
9
|
+
options: ['text', 'tel', 'email', 'password', 'url', 'number'],
|
|
10
|
+
},
|
|
11
|
+
roundness: {
|
|
12
|
+
control: { type: 'select' },
|
|
13
|
+
options: [false, '1x', '2x', '3x'],
|
|
14
|
+
},
|
|
15
|
+
size: {
|
|
16
|
+
control: { type: 'select' },
|
|
17
|
+
options: ['normal', 'small', 'large'],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
22
|
+
const { Story } = defineMeta({
|
|
23
|
+
component: TextInput,
|
|
24
|
+
tags: ['autodocs'],
|
|
25
|
+
argTypes: storyTextInputArgTypes,
|
|
26
|
+
args: { value: 'Hello world!' },
|
|
27
|
+
});
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<!-- TextInput with default style -->
|
|
31
|
+
<Story name="Default" />
|
|
32
|
+
|
|
33
|
+
<Story name="Placeholder" args={{ value: '', placeholder: 'Type something...' }} />
|
|
34
|
+
|
|
35
|
+
<Story name="No Outline" args={{ outline: false }} />
|
|
36
|
+
|
|
37
|
+
<Story name="Error" args={{ error: true }} />
|
|
38
|
+
|
|
39
|
+
<Story name="Disabled" args={{ disabled: true }} />
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type TextInputRoundness = ComponentRoundness | false;
|
|
3
|
+
export type TextInputType = 'text' | 'tel' | 'email' | 'password' | 'url' | 'number';
|
|
4
|
+
|
|
5
|
+
export type TextInputFocusEvent = FocusEvent & {
|
|
6
|
+
currentTarget: EventTarget & HTMLInputElement;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type TextInputClipboardEvent = ClipboardEvent & {
|
|
10
|
+
currentTarget: EventTarget & HTMLInputElement;
|
|
11
|
+
};
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
import type { ComponentRoundness, ComponentSize } from '$lib/types.js';
|
|
16
|
+
import type { Snippet } from 'svelte';
|
|
17
|
+
import type {
|
|
18
|
+
ChangeEventHandler,
|
|
19
|
+
ClipboardEventHandler,
|
|
20
|
+
FocusEventHandler,
|
|
21
|
+
FormEventHandler,
|
|
22
|
+
} from 'svelte/elements';
|
|
23
|
+
|
|
24
|
+
interface TextInputProps {
|
|
25
|
+
/** Input type? */
|
|
26
|
+
type?: TextInputType;
|
|
27
|
+
/** How large should the button be? */
|
|
28
|
+
size?: ComponentSize;
|
|
29
|
+
/** How round should the border radius be? */
|
|
30
|
+
roundness?: TextInputRoundness;
|
|
31
|
+
/** Add a border around the button. Default True */
|
|
32
|
+
outline?: boolean;
|
|
33
|
+
/** Input value */
|
|
34
|
+
value?: string;
|
|
35
|
+
/** How round should the border radius be? */
|
|
36
|
+
placeholder?: string;
|
|
37
|
+
/** Button disabled state */
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
/** is there any associated Error ? */
|
|
40
|
+
error?: boolean;
|
|
41
|
+
/** Name */
|
|
42
|
+
name?: string;
|
|
43
|
+
/** Id */
|
|
44
|
+
id?: string;
|
|
45
|
+
/** Icon before button content */
|
|
46
|
+
before?: Snippet;
|
|
47
|
+
/** Icon after button content */
|
|
48
|
+
after?: Snippet;
|
|
49
|
+
/** Custom css class*/
|
|
50
|
+
class?: string;
|
|
51
|
+
/** oninput event handler */
|
|
52
|
+
oninput?: FormEventHandler<HTMLInputElement>;
|
|
53
|
+
/** onchange event handler */
|
|
54
|
+
onchange?: ChangeEventHandler<HTMLInputElement>;
|
|
55
|
+
/** onblur event handler */
|
|
56
|
+
onblur?: FocusEventHandler<HTMLInputElement>;
|
|
57
|
+
/** onfocus event handler */
|
|
58
|
+
onfocus?: FocusEventHandler<HTMLInputElement>;
|
|
59
|
+
/** onpaste event handler */
|
|
60
|
+
onpaste?: ClipboardEventHandler<HTMLInputElement>;
|
|
61
|
+
/** oncopy event handler */
|
|
62
|
+
oncopy?: ClipboardEventHandler<HTMLInputElement>;
|
|
63
|
+
/** oncut event handler */
|
|
64
|
+
oncut?: ClipboardEventHandler<HTMLInputElement>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let {
|
|
68
|
+
type = 'text',
|
|
69
|
+
size = 'normal',
|
|
70
|
+
roundness = '1x',
|
|
71
|
+
outline = true,
|
|
72
|
+
name,
|
|
73
|
+
id,
|
|
74
|
+
class: className = '',
|
|
75
|
+
disabled = false,
|
|
76
|
+
oninput,
|
|
77
|
+
onchange,
|
|
78
|
+
onblur,
|
|
79
|
+
onfocus,
|
|
80
|
+
onpaste,
|
|
81
|
+
oncopy,
|
|
82
|
+
oncut,
|
|
83
|
+
before,
|
|
84
|
+
after,
|
|
85
|
+
error = false,
|
|
86
|
+
value = $bindable<string>(),
|
|
87
|
+
placeholder,
|
|
88
|
+
}: TextInputProps = $props();
|
|
89
|
+
|
|
90
|
+
let focused: boolean = $state(false);
|
|
91
|
+
|
|
92
|
+
function onfocusMod(e: TextInputFocusEvent) {
|
|
93
|
+
focused = true;
|
|
94
|
+
|
|
95
|
+
if (onfocus) {
|
|
96
|
+
onfocus(e);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function onblurMod(e: TextInputFocusEvent) {
|
|
101
|
+
focused = false;
|
|
102
|
+
|
|
103
|
+
if (onblur) {
|
|
104
|
+
onblur(e);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<div
|
|
110
|
+
class:outline
|
|
111
|
+
class:disabled
|
|
112
|
+
class:error
|
|
113
|
+
class:focused
|
|
114
|
+
class={['dodo-ui-TextInput', `size--${size}`, `roundness--${roundness}`, className].join(' ')}
|
|
115
|
+
>
|
|
116
|
+
{#if before}
|
|
117
|
+
<span class="content--before">
|
|
118
|
+
{@render before()}
|
|
119
|
+
</span>
|
|
120
|
+
{/if}
|
|
121
|
+
<input
|
|
122
|
+
{type}
|
|
123
|
+
{name}
|
|
124
|
+
{id}
|
|
125
|
+
{disabled}
|
|
126
|
+
{oninput}
|
|
127
|
+
{onchange}
|
|
128
|
+
onfocus={onfocusMod}
|
|
129
|
+
onblur={onblurMod}
|
|
130
|
+
{onpaste}
|
|
131
|
+
{oncopy}
|
|
132
|
+
{oncut}
|
|
133
|
+
{placeholder}
|
|
134
|
+
bind:value
|
|
135
|
+
/>
|
|
136
|
+
{#if after}
|
|
137
|
+
<span class="content--after">
|
|
138
|
+
{@render after()}
|
|
139
|
+
</span>
|
|
140
|
+
{/if}
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<style lang="scss">
|
|
144
|
+
:global(:root) {
|
|
145
|
+
--dodo-ui-TextInput-border-color: var(--dodo-color-default-500);
|
|
146
|
+
--dodo-ui-TextInput-focus-border-color: var(--dodo-color-primary-500);
|
|
147
|
+
--dodo-ui-TextInput-error-border-color: var(--dodo-color-danger-500);
|
|
148
|
+
|
|
149
|
+
--dodo-ui-TextInput-disabled-color: var(--dodo-color-default-400);
|
|
150
|
+
--dodo-ui-TextInput-disabled-bg: var(--dodo-color-default-200);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
:global(.dodo-theme--dark) {
|
|
154
|
+
--dodo-ui-TextInput-border-color: var(--dodo-color-default-600);
|
|
155
|
+
--dodo-ui-TextInput-focus-border-color: var(--dodo-color-primary-600);
|
|
156
|
+
--dodo-ui-TextInput-error-border-color: var(--dodo-color-danger-600);
|
|
157
|
+
|
|
158
|
+
--dodo-ui-TextInput-disabled-bg: var(--dodo-color-default-100);
|
|
159
|
+
--dodo-ui-TextInput-disabled-color: var(--dodo-color-default-500);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.dodo-ui-TextInput {
|
|
163
|
+
display: flex;
|
|
164
|
+
overflow: hidden;
|
|
165
|
+
color: var(--dodo-color-default-800);
|
|
166
|
+
transition: all 150ms;
|
|
167
|
+
border: 0;
|
|
168
|
+
|
|
169
|
+
input {
|
|
170
|
+
flex: 1;
|
|
171
|
+
border: 0;
|
|
172
|
+
outline: 0;
|
|
173
|
+
height: 100%;
|
|
174
|
+
background-color: transparent;
|
|
175
|
+
font-family: inherit;
|
|
176
|
+
color: inherit;
|
|
177
|
+
letter-spacing: 0.3px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
&.outline {
|
|
181
|
+
border-style: solid;
|
|
182
|
+
border-width: var(--dodo-ui-element-border-width);
|
|
183
|
+
border-color: var(--dodo-ui-TextInput-border-color);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
&.focused {
|
|
187
|
+
border-color: var(--dodo-ui-TextInput-focus-border-color);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
&.error {
|
|
191
|
+
border-color: var(--dodo-ui-TextInput-error-border-color);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&.disabled {
|
|
195
|
+
cursor: initial;
|
|
196
|
+
background-color: var(--dodo-ui-TextInput-disabled-bg);
|
|
197
|
+
color: var(--dodo-ui-TextInput-disabled-color);
|
|
198
|
+
border-color: var(--dodo-ui-TextInput-disabled-bg);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.content {
|
|
202
|
+
&--after,
|
|
203
|
+
&--before {
|
|
204
|
+
&:empty {
|
|
205
|
+
display: none;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&--after,
|
|
210
|
+
&--before {
|
|
211
|
+
display: inline-flex;
|
|
212
|
+
height: 100%;
|
|
213
|
+
align-items: center;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
&.size {
|
|
218
|
+
&--normal {
|
|
219
|
+
height: var(--dodo-ui-element-height-normal);
|
|
220
|
+
input {
|
|
221
|
+
font-size: 1rem;
|
|
222
|
+
padding: 0 12px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.content {
|
|
226
|
+
&--before {
|
|
227
|
+
margin-left: 12px;
|
|
228
|
+
margin-right: -4px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
&--after {
|
|
232
|
+
margin-right: 12px;
|
|
233
|
+
margin-left: -4px;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
&--small {
|
|
239
|
+
height: var(--dodo-ui-element-height-small);
|
|
240
|
+
input {
|
|
241
|
+
padding: 0 8px;
|
|
242
|
+
font-size: 0.9rem;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.content {
|
|
246
|
+
&--before {
|
|
247
|
+
margin-left: 8px;
|
|
248
|
+
margin-right: -2px;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
&--after {
|
|
252
|
+
margin-right: 8px;
|
|
253
|
+
margin-left: -2px;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
&--large {
|
|
259
|
+
height: var(--dodo-ui-element-height-large);
|
|
260
|
+
input {
|
|
261
|
+
font-size: 1.1rem;
|
|
262
|
+
padding: 0 14px;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.content {
|
|
266
|
+
&--before {
|
|
267
|
+
margin-left: 14px;
|
|
268
|
+
margin-right: -4px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
&--after {
|
|
272
|
+
margin-right: 14px;
|
|
273
|
+
margin-left: -4px;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
&.roundness {
|
|
280
|
+
&--1x {
|
|
281
|
+
border-radius: var(--dodo-ui-element-roundness-1x);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
&--2x {
|
|
285
|
+
border-radius: var(--dodo-ui-element-roundness-2x);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
&--3x {
|
|
289
|
+
border-radius: var(--dodo-ui-element-roundness-3x);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
</style>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import TextInput from '../TextInput.svelte';
|
|
4
|
+
import { storyTextInputArgTypes } from '../TextInput.stories.svelte';
|
|
5
|
+
import Icon from '@iconify/svelte';
|
|
6
|
+
|
|
7
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
8
|
+
const { Story } = defineMeta({
|
|
9
|
+
component: TextInput,
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
argTypes: storyTextInputArgTypes,
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<!-- TextInput icon in front. -->
|
|
16
|
+
<Story name="Icon Before">
|
|
17
|
+
<TextInput>
|
|
18
|
+
{#snippet before()}
|
|
19
|
+
<Icon icon="material-symbols:content-copy" />
|
|
20
|
+
{/snippet}
|
|
21
|
+
</TextInput>
|
|
22
|
+
</Story>
|
|
23
|
+
|
|
24
|
+
<!-- TextInput icon in front. -->
|
|
25
|
+
<Story name="Icon After">
|
|
26
|
+
<TextInput>
|
|
27
|
+
{#snippet after()}
|
|
28
|
+
<Icon icon="material-symbols:download-2" />
|
|
29
|
+
{/snippet}
|
|
30
|
+
</TextInput>
|
|
31
|
+
</Story>
|
|
32
|
+
|
|
33
|
+
<Story name="Small" args={{ size: 'small' }}>
|
|
34
|
+
<TextInput size="small">
|
|
35
|
+
{#snippet before()}
|
|
36
|
+
<Icon icon="material-symbols:content-copy" />
|
|
37
|
+
{/snippet}
|
|
38
|
+
</TextInput>
|
|
39
|
+
</Story>
|
|
40
|
+
|
|
41
|
+
<Story name="Large" args={{ size: 'large' }}>
|
|
42
|
+
<TextInput size="large">
|
|
43
|
+
{#snippet before()}
|
|
44
|
+
<Icon icon="material-symbols:content-copy" />
|
|
45
|
+
{/snippet}
|
|
46
|
+
</TextInput>
|
|
47
|
+
</Story>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
--dodo-ui-element-height-
|
|
3
|
-
--dodo-ui-element-height-
|
|
4
|
-
--dodo-ui-element-height-large:
|
|
2
|
+
--dodo-ui-element-height-small: 34px;
|
|
3
|
+
--dodo-ui-element-height-normal: 40px;
|
|
4
|
+
--dodo-ui-element-height-large: 50px;
|
|
5
5
|
|
|
6
|
-
--dodo-ui-element-roundness-
|
|
7
|
-
--dodo-ui-element-roundness-
|
|
8
|
-
--dodo-ui-element-roundness-
|
|
9
|
-
|
|
6
|
+
--dodo-ui-element-roundness-1x: 7px;
|
|
7
|
+
--dodo-ui-element-roundness-2x: 13px;
|
|
8
|
+
--dodo-ui-element-roundness-3x: 31px;
|
|
9
|
+
|
|
10
|
+
--dodo-ui-element-border-width: 1px;
|
|
10
11
|
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<script module>
|
|
2
|
-
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
-
import ExampleButton from './ExampleButton.svelte';
|
|
4
|
-
import { fn } from '@storybook/test';
|
|
5
|
-
|
|
6
|
-
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
7
|
-
const { Story } = defineMeta({
|
|
8
|
-
component: ExampleButton,
|
|
9
|
-
tags: ['autodocs'],
|
|
10
|
-
argTypes: {
|
|
11
|
-
backgroundColor: { control: 'color' },
|
|
12
|
-
size: {
|
|
13
|
-
control: { type: 'select' },
|
|
14
|
-
options: ['small', 'medium', 'large'],
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
args: {
|
|
18
|
-
onClick: fn(),
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
</script>
|
|
22
|
-
|
|
23
|
-
<!-- More on writing stories with args: https://storybook.js.org/docs/writing-stories/args -->
|
|
24
|
-
<Story name="Primary" args={{ primary: true, label: 'Button' }} />
|
|
25
|
-
|
|
26
|
-
<Story name="Secondary" args={{ label: 'Button' }} />
|
|
27
|
-
|
|
28
|
-
<Story name="Large" args={{ size: 'large', label: 'Button' }} />
|
|
29
|
-
|
|
30
|
-
<Story name="Small" args={{ size: 'small', label: 'Button' }} />
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<script lang="ts">import './button.css';
|
|
2
|
-
const { primary = false, backgroundColor, size = 'medium', label, onClick } = $props();
|
|
3
|
-
</script>
|
|
4
|
-
|
|
5
|
-
<button
|
|
6
|
-
type="button"
|
|
7
|
-
class={['storybook-button', `storybook-button--${size}`].join(' ')}
|
|
8
|
-
class:storybook-button--primary={primary}
|
|
9
|
-
class:storybook-button--secondary={!primary}
|
|
10
|
-
style:background-color={backgroundColor}
|
|
11
|
-
onclick={onClick}
|
|
12
|
-
>
|
|
13
|
-
{label}
|
|
14
|
-
</button>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import './button.css';
|
|
2
|
-
interface Props {
|
|
3
|
-
/** Is this the principal call to action on the page? */
|
|
4
|
-
primary?: boolean;
|
|
5
|
-
/** What background color to use */
|
|
6
|
-
backgroundColor?: string;
|
|
7
|
-
/** How large should the button be? */
|
|
8
|
-
size?: 'small' | 'medium' | 'large';
|
|
9
|
-
/** Button contents */
|
|
10
|
-
label: string;
|
|
11
|
-
/** The onclick event handler */
|
|
12
|
-
onClick?: () => void;
|
|
13
|
-
}
|
|
14
|
-
declare const ExampleButton: import("svelte").Component<Props, {}, "">;
|
|
15
|
-
type ExampleButton = ReturnType<typeof ExampleButton>;
|
|
16
|
-
export default ExampleButton;
|