Skip to content

Commit 7ba32ef

Browse files
authored
Feat/radio input (#176)
* feat: added a radio button custom * docs: added name option in docs. * chore: cleaned the unnecessary classes and variables for input type radio. * fix: moved input radio to its own component. * fix: keydown events added.
1 parent 52fa5ad commit 7ba32ef

File tree

5 files changed

+124
-44
lines changed

5 files changed

+124
-44
lines changed
Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,62 @@
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 }) => ({
8-
Component: Input,
9-
props: args
10-
})
4+
title: "UI/Input",
5+
component: Input,
6+
tags: ["autodocs"],
7+
render: (args: { type: string; placeholder: string }) => ({
8+
Component: Input,
9+
props: args,
10+
}),
1111
};
1212

1313
export const Text = {
14-
args: {
15-
type: 'text',
16-
placeholder: 'Joe Biden'
17-
}
14+
args: {
15+
type: "text",
16+
placeholder: "Joe Biden",
17+
},
1818
};
1919

2020
export const Tel = {
21-
args: {
22-
type: 'tel',
23-
placeholder: '987654321'
24-
}
21+
args: {
22+
type: "tel",
23+
placeholder: "987654321",
24+
},
2525
};
2626

2727
export const NumberInput = {
28-
args: {
29-
type: 'number',
30-
placeholder: 'Enter something'
31-
}
28+
args: {
29+
type: "number",
30+
placeholder: "Enter something",
31+
},
3232
};
3333

3434
export const Email = {
35-
args: {
36-
type: 'email',
37-
placeholder: '[email protected]'
38-
}
35+
args: {
36+
type: "email",
37+
placeholder: "[email protected]",
38+
},
3939
};
4040

4141
export const Invalid = {
42-
args: {
43-
type: 'email',
44-
placeholder: 'Invalid email',
45-
value: 'not-an-email'
46-
}
42+
args: {
43+
type: "email",
44+
placeholder: "Invalid email",
45+
value: "not-an-email",
46+
},
4747
};
4848

4949
export const Password = {
50-
args: {
51-
type: 'password',
52-
placeholder: 'Please enter password'
53-
}
50+
args: {
51+
type: "password",
52+
placeholder: "Please enter password",
53+
},
54+
};
55+
56+
export const Radio = {
57+
args: {
58+
type: "radio",
59+
value: "option1",
60+
name: "option-1",
61+
},
5462
};

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,16 @@
1717
...restProps
1818
}: IInputProps = $props();
1919
20-
const cbase = $derived(
21-
'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'
22-
);
20+
const cbase =
21+
'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';
2322
</script>
2423

2524
<input
2625
{...restProps}
2726
{type}
2827
{placeholder}
29-
bind:value
3028
bind:this={input}
29+
bind:value
3130
class={cn([cbase, restProps.class].join(' '))}
3231
tabindex="0"
3332
/>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { InputRadio } from "..";
2+
3+
export default {
4+
title: "UI/InputRadio",
5+
component: InputRadio,
6+
tags: ["autodocs"],
7+
render: (args: { type: string; placeholder: string }) => ({
8+
Component: InputRadio,
9+
props: args,
10+
}),
11+
};
12+
13+
export const Radio = {
14+
args: {
15+
type: "radio",
16+
value: "option1",
17+
name: "option-1",
18+
},
19+
};
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script lang="ts">
2+
import { cn } from '$lib/utils';
3+
import type { HTMLAttributes } from 'svelte/elements';
4+
5+
interface IInputRadioProps extends HTMLAttributes<HTMLElement> {
6+
selected?: string;
7+
name?: string;
8+
value: string;
9+
}
10+
11+
let {
12+
value = '',
13+
selected = $bindable(''),
14+
name = '',
15+
...restProps
16+
}: IInputRadioProps = $props();
17+
18+
let radioElement: HTMLInputElement | null = $state(null);
19+
20+
const cbase =
21+
"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-['']";
22+
</script>
23+
24+
<input
25+
{...restProps}
26+
type="radio"
27+
{value}
28+
bind:group={selected}
29+
bind:this={radioElement}
30+
{name}
31+
checked={selected === value}
32+
class={cn(['hidden', restProps.class].join(' '))}
33+
/>
34+
35+
<span
36+
{...restProps}
37+
class={cn([cbase, restProps.class].join(' '))}
38+
role="radio"
39+
tabindex="0"
40+
aria-checked={selected === value}
41+
onclick={() => radioElement?.click()}
42+
onkeydown={(e) => {
43+
if (e.key === ' ' || e.key === 'Enter') {
44+
e.preventDefault();
45+
radioElement?.click();
46+
}
47+
}}
48+
>
49+
{#if selected === value}
50+
<span class="bg-brand-burnt-orange bottom-0.75 left-0.25 absolute h-2.5 w-2.5 rounded-full"
51+
></span>
52+
{/if}
53+
</span>
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
export { default as Button } from './Button/Button.svelte';
2-
export { default as Avatar } from './Avatar/Avatar.svelte';
3-
export { default as Input } from './Input/Input.svelte';
4-
export { default as Select } from './Select/Select.svelte';
5-
export { default as Label } from './Label/Label.svelte';
6-
export { default as Toggle } from './Toggle/Toggle.svelte';
7-
export { default as Helper } from './Helper/Helper.svelte';
1+
export { default as Button } from "./Button/Button.svelte";
2+
export { default as Avatar } from "./Avatar/Avatar.svelte";
3+
export { default as Input } from "./Input/Input.svelte";
4+
export { default as Select } from "./Select/Select.svelte";
5+
export { default as Label } from "./Label/Label.svelte";
6+
export { default as Toggle } from "./Toggle/Toggle.svelte";
7+
export { default as Helper } from "./Helper/Helper.svelte";
8+
export { default as InputRadio } from "./InputRadio/InputRadio.svelte";

0 commit comments

Comments
 (0)