Skip to content

Commit 2d77b9c

Browse files
feat: message-input (#144)
* feat: message-input * fix: classes merge and a files as a prop * feat: variant added * feat: icon replaced * fix: as per code rabbit suggestions * fix: icon * fix: input file button * fix: as per suggestion * fix: classes * fix: no need of error and disabled classes * fix: input * feat: invalid inputs * feat: add number input storybook --------- Co-authored-by: Soham Jaiswal <[email protected]>
1 parent 97d3bc9 commit 2d77b9c

File tree

8 files changed

+191
-91
lines changed

8 files changed

+191
-91
lines changed

.vscode/extensions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"streetsidesoftware.code-spell-checker",
2323
"1YiB.rust-bundle",
2424
"bradlc.vscode-tailwindcss",
25-
"tauri-apps.tauri-vscode"
25+
"tauri-apps.tauri-vscode",
26+
"coderabbit.coderabbit-vscode"
2627
]
2728
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { ComponentProps } from 'svelte';
2+
import MessageInput from './MessageInput.svelte';
3+
4+
export default {
5+
title: 'UI/MessageInput',
6+
component: MessageInput,
7+
tags: ['autodocs'],
8+
render: (args: { Component: MessageInput; props: ComponentProps<typeof MessageInput> }) => ({
9+
Component: MessageInput,
10+
props: args
11+
})
12+
};
13+
14+
export const Comment = {
15+
args: {
16+
variant: 'comment',
17+
placeholder: 'Write your comment',
18+
handleSend: () => alert('sent')
19+
}
20+
};
21+
22+
export const Dm = {
23+
args: {
24+
variant: 'dm',
25+
placeholder: 'Write your message',
26+
handleAdd: () => alert('add'),
27+
handleSend: () => alert('sent')
28+
}
29+
};
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<script lang="ts">
2+
import { Avatar, Input } from '$lib/ui';
3+
import { cn } from '$lib/utils';
4+
import { ImageCompositionOvalIcon, PlusSignIcon, SentIcon } from '@hugeicons/core-free-icons';
5+
import { HugeiconsIcon } from '@hugeicons/svelte';
6+
import type { HTMLAttributes } from 'svelte/elements';
7+
8+
interface IMessageInputProps extends HTMLAttributes<HTMLElement> {
9+
variant: 'comment' | 'dm';
10+
src: string;
11+
value: string;
12+
placeholder?: string;
13+
files?: FileList | undefined;
14+
handleAdd?: () => void;
15+
handleSend: () => Promise<void>;
16+
}
17+
18+
let {
19+
variant = 'comment',
20+
src = 'https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250',
21+
value,
22+
placeholder,
23+
files = $bindable(),
24+
handleAdd,
25+
handleSend,
26+
...restProps
27+
}: IMessageInputProps = $props();
28+
29+
let fileInput: HTMLInputElement | undefined = $state();
30+
31+
const cBase = 'flex items-center justify-between gap-2';
32+
</script>
33+
34+
<div {...restProps} class={cn([cBase, restProps.class].join(' '))}>
35+
{#if variant === 'comment'}
36+
<Avatar size="sm" {src} />
37+
{:else}
38+
<!-- svelte-ignore a11y_click_events_have_key_events -->
39+
<!-- svelte-ignore a11y_no_static_element_interactions -->
40+
<button
41+
type="button"
42+
class="bg-grey flex aspect-square h-13 w-13 items-center justify-center rounded-full border-0 p-0"
43+
onclick={handleAdd}
44+
aria-label="Add attachment"
45+
>
46+
<HugeiconsIcon size="24px" icon={PlusSignIcon} color="var(--color-black-400)" />
47+
</button>
48+
{/if}
49+
<Input type="text" bind:value {placeholder} />
50+
{#if value || variant === 'dm'}
51+
<!-- svelte-ignore a11y_click_events_have_key_events -->
52+
<!-- svelte-ignore a11y_no_static_element_interactions -->
53+
<div
54+
class="bg-grey flex aspect-square h-13 w-13 items-center justify-center rounded-full"
55+
onclick={handleSend}
56+
>
57+
<HugeiconsIcon size="24px" icon={SentIcon} color="var(--color-black-400)" />
58+
</div>
59+
{:else}
60+
<div class="bg-grey flex aspect-square h-13 w-13 items-center justify-center rounded-full">
61+
<input
62+
id="add-image"
63+
type="file"
64+
class="hidden"
65+
accept="image/*"
66+
bind:files
67+
bind:this={fileInput}
68+
/>
69+
<button
70+
type="button"
71+
class="bg-grey flex aspect-square h-13 w-13 items-center justify-center rounded-full border-0 p-0"
72+
aria-label="add-image"
73+
onclick={() => fileInput?.click()}
74+
>
75+
<HugeiconsIcon
76+
size="24px"
77+
icon={ImageCompositionOvalIcon}
78+
color="var(--color-black-400)"
79+
/>
80+
</button>
81+
</div>
82+
{/if}
83+
</div>
Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,38 @@
1-
import type { ComponentProps } from "svelte";
2-
import Post from "./Post.svelte";
1+
import type { ComponentProps } from 'svelte';
2+
import Post from './Post.svelte';
33

44
export default {
5-
title: "Fragments/Post",
6-
component: Post,
7-
tags: ["autodocs"],
8-
render: (args: {
9-
Component: Post;
10-
props: ComponentProps<typeof Post>;
11-
}) => ({
12-
Component: Post,
13-
props: args,
14-
}),
5+
title: 'Fragments/Post',
6+
component: Post,
7+
tags: ['autodocs'],
8+
render: (args: { Component: Post; props: ComponentProps<typeof Post> }) => ({
9+
Component: Post,
10+
props: args
11+
})
1512
};
1613

1714
export const Primary = {
18-
args: {
19-
avatar: "https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250",
20-
username: "blurryface",
21-
imgUri: "https://graphicsfamily.com/wp-content/uploads/edd/2023/01/Free-Photographer-Social-Media-Post-Design-Template-870x870.jpg",
22-
postAlt: "Sample",
23-
text: "Took some pictures today! Really love how this one in particular turned out! ",
24-
time: "2 hours ago",
25-
count: {
26-
likes: 100,
27-
comments: 50,
28-
},
29-
callback: {
30-
like: () => {
31-
alert("Like clicked");
32-
},
33-
comment: () => {
34-
alert("Comment clicked");
35-
},
36-
menu: () => {
37-
alert("Menu clicked");
38-
},
39-
},
40-
},
15+
args: {
16+
avatar: 'https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250',
17+
username: 'blurryface',
18+
imgUri: 'https://graphicsfamily.com/wp-content/uploads/edd/2023/01/Free-Photographer-Social-Media-Post-Design-Template-870x870.jpg',
19+
postAlt: 'Sample',
20+
text: 'Took some pictures today! Really love how this one in particular turned out! ',
21+
time: '2 hours ago',
22+
count: {
23+
likes: 100,
24+
comments: 50
25+
},
26+
callback: {
27+
like: () => {
28+
alert('Like clicked');
29+
},
30+
comment: () => {
31+
alert('Comment clicked');
32+
},
33+
menu: () => {
34+
alert('Menu clicked');
35+
}
36+
}
37+
}
4138
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { default as BottomNav } from './BottomNav/BottomNav.svelte';
22
export { default as SettingsNavigationButton } from './SettingsNavigationButton/SettingsNavigationButton.svelte';
3+
export { default as MessageInput } from './MessageInput/MessageInput.svelte';
34
export { default as InputFile } from './InputFile/InputFile.svelte';
Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,58 @@
1-
import { Input } from '..';
1+
import { Input } from "..";
22

33
export default {
4-
title: 'UI/Input',
5-
component: Input,
6-
tags: ['autodocs'],
7-
render: (args: { type: string; placeholder: string; helperText: string }) => ({
8-
Component: Input,
9-
props: args
10-
})
4+
title: "UI/Input",
5+
component: Input,
6+
tags: ["autodocs"],
7+
render: (args: {
8+
type: string;
9+
placeholder: string;
10+
helperText: string;
11+
}) => ({
12+
Component: Input,
13+
props: args,
14+
}),
1115
};
1216

1317
export const Text = {
14-
args: {
15-
type: 'text',
16-
placeholder: 'Joe Biden',
17-
isRequired: true
18-
}
18+
args: {
19+
type: "text",
20+
placeholder: "Joe Biden",
21+
},
1922
};
2023

2124
export const Tel = {
22-
args: {
23-
type: 'tel',
24-
placeholder: '987654321',
25-
isRequired: true
26-
}
25+
args: {
26+
type: "tel",
27+
placeholder: "987654321",
28+
},
2729
};
2830

29-
export const isError = {
30-
args: {
31-
type: 'text',
32-
placeholder: 'Enter something',
33-
isError: true
34-
}
31+
export const NumberInput = {
32+
args: {
33+
type: "number",
34+
placeholder: "Enter something",
35+
},
3536
};
3637

3738
export const Email = {
38-
args: {
39-
type: 'email',
40-
placeholder: '[email protected]'
41-
}
39+
args: {
40+
type: "email",
41+
placeholder: "[email protected]",
42+
},
4243
};
4344

44-
export const Password = {
45-
args: {
46-
type: 'password',
47-
placeholder: 'Please enter password',
48-
isRequired: true
49-
}
45+
export const Invalid = {
46+
args: {
47+
type: "email",
48+
placeholder: "Invalid email",
49+
value: "not-an-email",
50+
},
5051
};
5152

52-
export const Disabled = {
53-
args: {
54-
type: 'text',
55-
placeholder: 'Joe Biden',
56-
isRequired: true,
57-
isDisabled: true
58-
}
53+
export const Password = {
54+
args: {
55+
type: "password",
56+
placeholder: "Please enter password",
57+
},
5958
};
Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
<script lang="ts">
22
import { cn } from '$lib/utils';
3-
import type { HTMLInputAttributes } from 'svelte/elements';
3+
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from 'svelte/elements';
44
55
interface IInputProps extends HTMLInputAttributes {
6-
type: 'text' | 'number' | 'email' | 'tel' | 'password';
7-
value: string | number;
8-
placeholder: string;
9-
isRequired: boolean;
10-
isDisabled: boolean;
11-
isError: boolean;
6+
type: HTMLInputTypeAttribute;
127
}
138
149
let {
1510
type = 'text',
1611
value = $bindable(),
1712
placeholder = '',
18-
isRequired = false,
19-
isDisabled = false,
20-
isError = false,
2113
...restProps
2214
}: IInputProps = $props();
2315
2416
const cbase = $derived(
25-
`w-full bg-grey py-3.5 px-6 text-[15px] text-black-800 font-geist font-normal placeholder:text-black-600 rounded-4xl outline-0 border border-transparent ${isError && 'border border-red text-red focus:text-black-800 focus:border-transparent'} ${isDisabled && 'cursor-not-allowed'}`
17+
'w-full bg-grey py-3.5 px-6 text-[15px] text-black-800 font-geist font-normal placeholder:text-black-600 rounded-4xl outline-0 border border-transparent invalid:border-red invalid:text-red focus:invalid:text-black-800 focus:invalid:border-transparent'
2618
);
2719
</script>
2820

@@ -31,8 +23,6 @@
3123
{type}
3224
{placeholder}
3325
bind:value
34-
required={isRequired}
35-
disabled={isDisabled}
3626
class={cn([cbase, restProps.class].join(' '))}
3727
tabindex="0"
3828
/>

platforms/metagram/src/lib/ui/Toggle/Toggle.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<label
1515
{...restProps}
1616
for={uniqueId}
17-
class={cn(["relative",restProps.class].join(" "))}
17+
class={cn(['relative', restProps.class].join(' '))}
1818
aria-label={restProps['aria-label'] || 'Toggle'}
1919
role="switch"
2020
aria-checked={checked}

0 commit comments

Comments
 (0)