Skip to content

Commit

Permalink
Design maintenance: add radio icon and description options (viamrobot…
Browse files Browse the repository at this point in the history
  • Loading branch information
micheal-parks authored Feb 21, 2024
1 parent 668f5e0 commit 66b671d
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@viamrobotics/prime-core",
"version": "0.0.91",
"version": "0.0.92",
"publishConfig": {
"access": "public"
},
Expand Down
63 changes: 45 additions & 18 deletions packages/core/src/lib/radio.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,17 @@ import Label from '$lib/label.svelte';
import { Icon, type IconName } from '$lib/icon';
import { preventHandler, preventKeyboardHandler } from '$lib/prevent-handler';
interface Option {
label: string;
value: string;
description?: string;
icon?: IconName;
}
type Options = (string | Option)[];
/** The set of options that is available in the radio button. */
export let options: string[];
export let options: Options;
/** The name for the inputs in the fieldset of radio options. */
export let name: string;
Expand All @@ -41,11 +50,13 @@ export let direction: 'col' | 'row' = 'col';
let extraClasses: cx.Argument = '';
export { extraClasses as cx };
$: isSelected = (option: string) => option === selected;
let optionsInternal: Option[] = [];
$: optionsInternal = options.map((option) =>
typeof option === 'string' ? { label: option, value: option } : option
);
$: handleDisabled = preventHandler(disabled);
$: handleDisabledKeydown = preventKeyboardHandler(disabled);
$: getIcon = (option: string): IconName =>
isSelected(option) ? 'radiobox-marked' : 'radiobox-blank';
</script>

<fieldset
Expand All @@ -56,7 +67,7 @@ $: getIcon = (option: string): IconName =>
{#if $$slots.legend}
<legend
class={cx(
cx('mb-1 flex text-xs text-subtle-1', {
cx('mb-2 flex text-xs text-subtle-1', {
'after:text-danger-dark after:content-["*"]': required,
})
)}
Expand All @@ -66,31 +77,31 @@ $: getIcon = (option: string): IconName =>
{/if}

<div
class={cx('flex', {
class={cx('flex gap-2', {
'flex-col': direction === 'col',
'flex-row gap-2': direction === 'row',
'flex-row': direction === 'row',
})}
>
{#each options as option}
{#each optionsInternal as { label, value, description, icon }}
{@const isSelected = value === selected}
{@const radioIcon = isSelected ? 'radiobox-marked' : 'radiobox-blank'}
<Label
position="left"
{disabled}
cx={[
'h-7.5 whitespace-nowrap text-xs',
'whitespace-nowrap text-xs',
{
'font-semibold': isSelected(option),
'text-default': isSelected(option) && !disabled,
'text-subtle-1': !isSelected(option) && !disabled,
'text-subtle-1': !isSelected && !disabled,
'cursor-not-allowed text-disabled-dark': disabled,
},
]}
>
<input
{name}
{value}
type="radio"
value={option}
class="peer appearance-none"
checked={isSelected(option)}
checked={isSelected}
readonly={disabled ? true : undefined}
aria-disabled={disabled ? true : undefined}
bind:group={selected}
Expand All @@ -100,15 +111,31 @@ $: getIcon = (option: string): IconName =>
on:keydown|capture={handleDisabledKeydown}
/>
<Icon
name={getIcon(option)}
name={radioIcon}
cx={cx({
'text-disabled-dark': disabled,
'text-gray-9': !disabled && option === selected,
'text-gray-6': !disabled && option !== selected,
'text-gray-9': !disabled && isSelected,
'text-gray-6': !disabled && !isSelected,
})}
/>
<span class="pl-1.5">
{option}
<span class="flex gap-1.5">
{#if icon}
<Icon
cx="text-gray-7"
name={icon}
/>
{/if}
<span
class={cx({
'font-semibold': isSelected,
'text-default': isSelected && !disabled,
})}>{label}</span
>
</span>
{#if description}
<p class="mt-0.5 text-subtle-2">{description}</p>
{/if}
</span>
</Label>
{/each}
Expand Down
8 changes: 8 additions & 0 deletions packages/storybook/src/stories/radio.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@ import { Radio } from '@viamrobotics/prime-core';
<Canvas>
<Story of={RadioStories.Disabled} />
</Canvas>

<Canvas>
<Story of={RadioStories.WithDescription} />
</Canvas>

<Canvas>
<Story of={RadioStories.WithIcon} />
</Canvas>
45 changes: 45 additions & 0 deletions packages/storybook/src/stories/radio.stories.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,48 @@ import { Radio } from '@viamrobotics/prime-core';
<svelte:fragment slot="legend">Favorite animal</svelte:fragment>
</Radio>
</Story>

<Story name="With description">
<Radio
name="Upload model"
options={[
{
label: 'New model',
value: 'new model',
description: 'Upload a new model',
},
{
label: 'New version',
value: 'new version',
description:
'Upload a new version of a model that already exists in Viam',
},
]}
selected="new model"
>
<svelte:fragment slot="legend">Upload model</svelte:fragment>
</Radio>
</Story>

<Story name="With icon">
<Radio
name="Visibility"
options={[
{
label: 'Public',
value: 'public',
description: 'Can be used by external organizations',
icon: 'earth',
},
{
label: 'Private',
value: 'private',
description: 'Only for internal use within this organization',
icon: 'lock',
},
]}
selected="public"
>
<svelte:fragment slot="legend">Visibility</svelte:fragment>
</Radio>
</Story>

0 comments on commit 66b671d

Please sign in to comment.