Skip to content

Commit 250dba1

Browse files
committed
feat: added a radio button custom
1 parent 36f772a commit 250dba1

2 files changed

Lines changed: 100 additions & 44 deletions

File tree

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,66 @@
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+
group: string;
11+
helperText: string;
12+
}) => ({
13+
Component: Input,
14+
props: args,
15+
}),
1116
};
1217

1318
export const Text = {
14-
args: {
15-
type: 'text',
16-
placeholder: 'Joe Biden'
17-
}
19+
args: {
20+
type: "text",
21+
placeholder: "Joe Biden",
22+
},
1823
};
1924

2025
export const Tel = {
21-
args: {
22-
type: 'tel',
23-
placeholder: '987654321'
24-
}
26+
args: {
27+
type: "tel",
28+
placeholder: "987654321",
29+
},
2530
};
2631

2732
export const NumberInput = {
28-
args: {
29-
type: 'number',
30-
placeholder: 'Enter something'
31-
}
33+
args: {
34+
type: "number",
35+
placeholder: "Enter something",
36+
},
3237
};
3338

3439
export const Email = {
35-
args: {
36-
type: 'email',
37-
placeholder: 'example@email.com'
38-
}
40+
args: {
41+
type: "email",
42+
placeholder: "example@email.com",
43+
},
3944
};
4045

4146
export const Invalid = {
42-
args: {
43-
type: 'email',
44-
placeholder: 'Invalid email',
45-
value: 'not-an-email'
46-
}
47+
args: {
48+
type: "email",
49+
placeholder: "Invalid email",
50+
value: "not-an-email",
51+
},
4752
};
4853

4954
export const Password = {
50-
args: {
51-
type: 'password',
52-
placeholder: 'Please enter password'
53-
}
55+
args: {
56+
type: "password",
57+
placeholder: "Please enter password",
58+
},
59+
};
60+
61+
export const Radio = {
62+
args: {
63+
type: "radio",
64+
value: "option1",
65+
},
5466
};

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

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,69 @@
44
55
interface IInputProps extends HTMLInputAttributes {
66
type: HTMLInputTypeAttribute;
7+
selected?: string;
8+
name?: string;
79
}
810
911
let {
1012
type = 'text',
1113
value = $bindable(),
14+
selected = $bindable(),
15+
name = '',
1216
placeholder = '',
1317
...restProps
1418
}: IInputProps = $props();
1519
16-
const cbase = $derived(
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'
18-
);
20+
let radioElement: HTMLInputElement | null = $state(null);
21+
22+
const typeClasses: Record<string, string> = {
23+
radio: 'opacity-100'
24+
};
25+
26+
const cbase = $derived({
27+
common: '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',
28+
type: typeClasses[type]
29+
});
30+
31+
const radioCustomStyles = $derived({
32+
common: "before:h-4.5 before:w-4.5 before:border-brand-burnt-orange before:-left-0.75 before:-bottom-0.25 relative before:absolute before:rounded-full before:border-2 before:bg-white before:content-['']",
33+
selected:
34+
'after:h-2.5 after:w-2.5 after:bg-brand-burnt-orange after:absolute after:bottom-0.75 after:left-0.25 after:rounded-full'
35+
});
1936
</script>
2037

21-
<input
22-
{...restProps}
23-
{type}
24-
{placeholder}
25-
bind:value
26-
class={cn([cbase, restProps.class].join(' '))}
27-
tabindex="0"
28-
/>
38+
{#if type === 'radio'}
39+
<div
40+
class={cn(
41+
[radioCustomStyles.common, selected === value ? radioCustomStyles.selected : ''].join(
42+
' '
43+
)
44+
)}
45+
aria-checked={selected === value}
46+
role="radio"
47+
tabindex="0"
48+
onclick={() => radioElement?.click()}
49+
onkeypress={() => radioElement?.click()}
50+
>
51+
<input
52+
{...restProps}
53+
type="radio"
54+
{value}
55+
bind:group={selected}
56+
bind:this={radioElement}
57+
{name}
58+
checked={selected === value}
59+
class={cn([cbase.common, cbase.type, restProps.class].join(' '))}
60+
tabindex="0"
61+
/>
62+
</div>
63+
{:else}
64+
<input
65+
{...restProps}
66+
{type}
67+
{placeholder}
68+
bind:value
69+
class={cn([cbase.common, cbase.type, restProps.class].join(' '))}
70+
tabindex="0"
71+
/>
72+
{/if}

0 commit comments

Comments
 (0)