From 250dba175e4e3107e46b2f70a60ba15399a59619 Mon Sep 17 00:00:00 2001 From: Sahil Garg Date: Thu, 29 May 2025 15:00:34 +0530 Subject: [PATCH 1/5] feat: added a radio button custom --- .../src/lib/ui/Input/Input.stories.ts | 78 +++++++++++-------- .../metagram/src/lib/ui/Input/Input.svelte | 66 +++++++++++++--- 2 files changed, 100 insertions(+), 44 deletions(-) diff --git a/platforms/metagram/src/lib/ui/Input/Input.stories.ts b/platforms/metagram/src/lib/ui/Input/Input.stories.ts index 44fd70fce..78ee26e83 100644 --- a/platforms/metagram/src/lib/ui/Input/Input.stories.ts +++ b/platforms/metagram/src/lib/ui/Input/Input.stories.ts @@ -1,54 +1,66 @@ -import { Input } from '..'; +import { Input } from ".."; export default { - title: 'UI/Input', - component: Input, - tags: ['autodocs'], - render: (args: { type: string; placeholder: string; helperText: string }) => ({ - Component: Input, - props: args - }) + title: "UI/Input", + component: Input, + tags: ["autodocs"], + render: (args: { + type: string; + placeholder: string; + group: string; + helperText: string; + }) => ({ + Component: Input, + props: args, + }), }; export const Text = { - args: { - type: 'text', - placeholder: 'Joe Biden' - } + args: { + type: "text", + placeholder: "Joe Biden", + }, }; export const Tel = { - args: { - type: 'tel', - placeholder: '987654321' - } + args: { + type: "tel", + placeholder: "987654321", + }, }; export const NumberInput = { - args: { - type: 'number', - placeholder: 'Enter something' - } + args: { + type: "number", + placeholder: "Enter something", + }, }; export const Email = { - args: { - type: 'email', - placeholder: 'example@email.com' - } + args: { + type: "email", + placeholder: "example@email.com", + }, }; export const Invalid = { - args: { - type: 'email', - placeholder: 'Invalid email', - value: 'not-an-email' - } + args: { + type: "email", + placeholder: "Invalid email", + value: "not-an-email", + }, }; export const Password = { - args: { - type: 'password', - placeholder: 'Please enter password' - } + args: { + type: "password", + placeholder: "Please enter password", + }, +}; + +export const Radio = { + args: { + type: "radio", + value: "option1", + }, }; diff --git a/platforms/metagram/src/lib/ui/Input/Input.svelte b/platforms/metagram/src/lib/ui/Input/Input.svelte index 37ec24b34..8884bfd8c 100644 --- a/platforms/metagram/src/lib/ui/Input/Input.svelte +++ b/platforms/metagram/src/lib/ui/Input/Input.svelte @@ -4,25 +4,69 @@ interface IInputProps extends HTMLInputAttributes { type: HTMLInputTypeAttribute; + selected?: string; + name?: string; } let { type = 'text', value = $bindable(), + selected = $bindable(), + name = '', placeholder = '', ...restProps }: IInputProps = $props(); - const cbase = $derived( - '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' - ); + let radioElement: HTMLInputElement | null = $state(null); + + const typeClasses: Record = { + radio: 'opacity-100' + }; + + const cbase = $derived({ + 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', + type: typeClasses[type] + }); + + const radioCustomStyles = $derived({ + 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-['']", + selected: + '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' + }); - +{#if type === 'radio'} + +{:else} + +{/if} From f8720aa1a45a07c73e07815afe3fbbfc205b60d8 Mon Sep 17 00:00:00 2001 From: Sahil Garg Date: Thu, 29 May 2025 15:01:48 +0530 Subject: [PATCH 2/5] docs: added name option in docs. --- platforms/metagram/src/lib/ui/Input/Input.stories.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/platforms/metagram/src/lib/ui/Input/Input.stories.ts b/platforms/metagram/src/lib/ui/Input/Input.stories.ts index 78ee26e83..5906d7bdd 100644 --- a/platforms/metagram/src/lib/ui/Input/Input.stories.ts +++ b/platforms/metagram/src/lib/ui/Input/Input.stories.ts @@ -62,5 +62,6 @@ export const Radio = { args: { type: "radio", value: "option1", + name: "option-1", }, }; From 4249ed2d48d20162f26aa1d3287cfe610c474961 Mon Sep 17 00:00:00 2001 From: Sahil Garg Date: Tue, 3 Jun 2025 15:15:45 +0530 Subject: [PATCH 3/5] chore: cleaned the unnecessary classes and variables for input type radio. --- .../metagram/src/lib/ui/Input/Input.svelte | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/platforms/metagram/src/lib/ui/Input/Input.svelte b/platforms/metagram/src/lib/ui/Input/Input.svelte index bf7280d92..b96980e0c 100644 --- a/platforms/metagram/src/lib/ui/Input/Input.svelte +++ b/platforms/metagram/src/lib/ui/Input/Input.svelte @@ -23,16 +23,10 @@ let radioElement: HTMLInputElement | null = $state(null); - const typeClasses: Record = { - radio: 'opacity-100' - }; + const cbase = + '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'; - const cbase = $derived({ - 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', - type: typeClasses[type] - }); - - const radioCustomStyles = $derived({ + const customRadioStyles = $derived({ 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-['']", selected: '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' @@ -42,7 +36,7 @@ {#if type === 'radio'}
@@ -71,7 +65,7 @@ {placeholder} bind:this={input} bind:value - class={cn([cbase.common, cbase.type, restProps.class].join(' '))} + class={cn([cbase, restProps.class].join(' '))} tabindex="0" /> {/if} From 504be58bc038afc215fe2c4b243919b382b107a3 Mon Sep 17 00:00:00 2001 From: Sahil Garg Date: Wed, 4 Jun 2025 15:45:50 +0530 Subject: [PATCH 4/5] fix: moved input radio to its own component. --- .../metagram/src/lib/ui/Input/Input.svelte | 57 +++---------------- .../lib/ui/InputRadio/InputRadio.stories.ts | 19 +++++++ .../src/lib/ui/InputRadio/InputRadio.svelte | 47 +++++++++++++++ platforms/metagram/src/lib/ui/index.ts | 15 ++--- 4 files changed, 83 insertions(+), 55 deletions(-) create mode 100644 platforms/metagram/src/lib/ui/InputRadio/InputRadio.stories.ts create mode 100644 platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte diff --git a/platforms/metagram/src/lib/ui/Input/Input.svelte b/platforms/metagram/src/lib/ui/Input/Input.svelte index b96980e0c..d3862fd55 100644 --- a/platforms/metagram/src/lib/ui/Input/Input.svelte +++ b/platforms/metagram/src/lib/ui/Input/Input.svelte @@ -4,8 +4,6 @@ interface IInputProps extends HTMLInputAttributes { type: HTMLInputTypeAttribute; - selected?: string; - name?: string; input?: HTMLInputElement; value: string | number | any; placeholder?: string; @@ -15,57 +13,20 @@ type = 'text', input = $bindable(), value = $bindable(), - selected = $bindable(), - name = '', placeholder = '', ...restProps }: IInputProps = $props(); - let radioElement: HTMLInputElement | null = $state(null); - const cbase = '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'; - - const customRadioStyles = $derived({ - 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-['']", - selected: - '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' - }); -{#if type === 'radio'} - -{:else} - -{/if} + diff --git a/platforms/metagram/src/lib/ui/InputRadio/InputRadio.stories.ts b/platforms/metagram/src/lib/ui/InputRadio/InputRadio.stories.ts new file mode 100644 index 000000000..4dbe6af35 --- /dev/null +++ b/platforms/metagram/src/lib/ui/InputRadio/InputRadio.stories.ts @@ -0,0 +1,19 @@ +import { InputRadio } from ".."; + +export default { + title: "UI/InputRadio", + component: InputRadio, + tags: ["autodocs"], + render: (args: { type: string; placeholder: string }) => ({ + Component: InputRadio, + props: args, + }), +}; + +export const Radio = { + args: { + type: "radio", + value: "option1", + name: "option-1", + }, +}; diff --git a/platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte b/platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte new file mode 100644 index 000000000..63dc7921e --- /dev/null +++ b/platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte @@ -0,0 +1,47 @@ + + + + + radioElement?.click()} +> + {#if selected === value} + + {/if} + diff --git a/platforms/metagram/src/lib/ui/index.ts b/platforms/metagram/src/lib/ui/index.ts index d28618f98..dfc0602f8 100644 --- a/platforms/metagram/src/lib/ui/index.ts +++ b/platforms/metagram/src/lib/ui/index.ts @@ -1,7 +1,8 @@ -export { default as Button } from './Button/Button.svelte'; -export { default as Avatar } from './Avatar/Avatar.svelte'; -export { default as Input } from './Input/Input.svelte'; -export { default as Select } from './Select/Select.svelte'; -export { default as Label } from './Label/Label.svelte'; -export { default as Toggle } from './Toggle/Toggle.svelte'; -export { default as Helper } from './Helper/Helper.svelte'; +export { default as Button } from "./Button/Button.svelte"; +export { default as Avatar } from "./Avatar/Avatar.svelte"; +export { default as Input } from "./Input/Input.svelte"; +export { default as Select } from "./Select/Select.svelte"; +export { default as Label } from "./Label/Label.svelte"; +export { default as Toggle } from "./Toggle/Toggle.svelte"; +export { default as Helper } from "./Helper/Helper.svelte"; +export { default as InputRadio } from "./InputRadio/InputRadio.svelte"; From eb442b6c2f536dddf073f26bbf4805cfc57865c9 Mon Sep 17 00:00:00 2001 From: Sahil Garg Date: Wed, 4 Jun 2025 16:42:58 +0530 Subject: [PATCH 5/5] fix: keydown events added. --- platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte b/platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte index 63dc7921e..522c30d04 100644 --- a/platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte +++ b/platforms/metagram/src/lib/ui/InputRadio/InputRadio.svelte @@ -39,6 +39,12 @@ tabindex="0" aria-checked={selected === value} onclick={() => radioElement?.click()} + onkeydown={(e) => { + if (e.key === ' ' || e.key === 'Enter') { + e.preventDefault(); + radioElement?.click(); + } + }} > {#if selected === value}