Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type { HeadingProps, KeyboardProps, LinkProps }
import type { DividerProps } from '@/UI/Content/Divider';
import type { IconProps } from '@/UI/Customization';
import type { CheckboxProps, InputTextProps, SelectProps, SwitchProps, TextareaProps } from '@/UI/Forms';
import type { RadioProps } from '@/UI/Forms/Radio';
import type { RangeProps } from '@/UI/Forms/Range';
import type { TabProps, TabsProps } from '@/UI/Navigations';
import type { ModalProps, TooltipProps } from '@/UI/Overlays';
Expand Down Expand Up @@ -126,7 +127,7 @@ export interface ConfigurableComponentProps {
FoMenu: ConfigurableProps<MenuProps>;
FoModal: ConfigurableProps<Omit<ModalProps, 'backdrop'> & Colorable>;
FoRadialProgress: ConfigurableProps<RadialProgressProps & RadialProgressBackgroundProps>;
FoRadio: ConfigurableProps<ButtonProps>; // todo: temporary
FoRadio: ConfigurableProps<RadioProps>;
FoRange: ConfigurableProps<RangeProps>;
/** Select defaults */
FoSelect: ConfigurableProps<SelectProps> & LabelTypeComponentConfig & HorizontalPositionComponentConfig<HorizontalHelperTextPositionConfig>;
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/Lib/UseSize/Internal/Lib/UseSize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ export function useSize(
large: 'modal-dialog-lg',
extraLarge: 'modal-dialog-xl',
},
FoRadio: {
extraSmall: 'radio-xs',
small: 'radio-sm',
medium: '',
large: 'radio-lg',
extraLarge: 'radio-xl',
},
FoRange: {
extraSmall: 'range-xs',
small: 'range-sm',
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/Lib/UseSize/Types/Size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type SizableComponentName = Extract<
| 'FoLoading'
| 'FoMenu'
| 'FoModal'
| 'FoRadio'
| 'FoRange'
| 'FoSelect'
| 'FoStatus'
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/Types/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@ export type Default = 'default';
export type Direction = 'ltr' | 'rtl';
export type HorizontalPosition = 'left' | 'right';

export interface Image {
src: string;
alt: string;
}

export type VueClass = string | Record<string, boolean> | VueClass[];
3 changes: 2 additions & 1 deletion packages/core/src/UI/Components/Avatar/Types/Avatar.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Colorable, Preset, Presettable, Shape, Shapeable, Sizable } from '@/Lib';
import type { Image } from '@/Types';
import type { WithRequiredIcon } from '@/UI/Customization';

export type AvatarShape = Extract<Shape, 'rounded' | 'circle'>;
Expand All @@ -24,7 +25,7 @@ export interface AvatarProps extends Shapeable<AvatarShape>, Sizable {
* an object representing a placeholder icon or
* an object representing a placeholder text
*/
avatar: { src: string; alt: string } | AvatarIcon | AvatarTextProps;
avatar: Image | AvatarIcon | AvatarTextProps;

/** An indicator representing the status of the avatar with its own placement */
indicator?: { status: AvatarIndicatorStatus; placement: AvatarIndicatorPlacement };
Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/UI/Forms/Radio/Types/Radio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Colorable, Disableable, MaybeStringId, Sizable, Validity } from '@/Lib';
import type { Image } from '@/Types';
import type { WithHelperText, WithLabel } from '@/UI/Components';

interface RadioValue {
value: string;
}

export interface RadioProps extends MaybeStringId, RadioValue, Colorable, Disableable, Sizable, Validity, WithLabel, WithHelperText {
isInset?: boolean;
}

export interface ImageRadioProps extends RadioValue {
image: Image;
}
1 change: 1 addition & 0 deletions packages/core/src/UI/Forms/Radio/Types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@/UI/Forms/Radio/Types/Radio';
24 changes: 24 additions & 0 deletions packages/core/src/UI/Forms/Radio/UI/FoImageRadio.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<FoLabel class="custom-option p-0">
<span class="w-full">
<img :src="image.src"
:alt="image.alt"
>
</span>

<input v-model="checkedValue"
class="radio hidden"
type="radio"
:value="value"
>
</FoLabel>
</template>

<script setup lang="ts">
import type { ImageRadioProps } from '@/UI/Forms';
import { FoLabel } from '@/UI/Components/Label/Internal';

defineProps<ImageRadioProps>();

const checkedValue = defineModel<string>({ required: true });
</script>
85 changes: 85 additions & 0 deletions packages/core/src/UI/Forms/Radio/UI/FoRadio.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<component :is="isInJoin ? FoFragment : 'div'"
:class="isInJoin === false && ['flex', hasLabelAndHelperText ? 'gap-3' : 'items-center gap-1']"
v-bind="isInJoin === false && reactiveOmit($attrs, 'class')"
>
<input :id="id"
v-model="checkedValue"
:value="value"
type="radio"
:class="isInJoin ? [$attrs?.class, joinItemClass] : [
$attrs?.class,
'radio',
colorClass,
sizeClass,
validityClass,
joinItemClass,
hasLabelAndHelperText && 'mt-2',
isInset && 'radio-inset',
]"
:disabled="isDisabled"
:aria-label="isInJoin ? label : ''"
>

<FoLabel v-if="isInJoin === false && label !== undefined"
:for="id"
:class="hasLabelAndHelperText && 'flex flex-col'"
>
<span class="text-base">
{{ label }}
</span>

<FoHelperText v-if="helperText !== undefined">
{{ helperText }}
</FoHelperText>
</FoLabel>
</component>
</template>

<script setup lang="ts">
import type { ComponentName } from '@/Lib';
import type { RadioProps } from '@/UI/Forms/Radio';
import { useFlyonUIVueAppConfig } from '@/Lib';
import { useClass } from '@/Lib/UseClass/Internal';
import { useColor } from '@/Lib/UseColor/Internal';
import { useElementId } from '@/Lib/UseIdentifiable/Internal';
import { useSize } from '@/Lib/UseSize/Internal';
import { useValidity } from '@/Lib/UseValidity/Internal';
import { FoFragment } from '@/UI/Components/Fragment/Internal';
import { FoHelperText } from '@/UI/Components/HelperText/Internal';
import { FoLabel } from '@/UI/Components/Label/Internal';
import { isInJoinInjectionKey, useJoinItem } from '@/UI/Forms/Join/Internal';
import { reactiveOmit } from '@vueuse/core';
import { computed, inject } from 'vue';

defineOptions({
inheritAttrs: false,
});

const props = withDefaults(defineProps<RadioProps>(), {
isValid: undefined,
});

const checkedValue = defineModel<string>({ required: true });

const componentName: ComponentName = 'FoRadio';
const { config } = useFlyonUIVueAppConfig();

const isInJoin: boolean = inject(isInJoinInjectionKey, false);

const id = useElementId((): string | undefined => props.id);

const [
colorClass,
sizeClass,
validityClass,
joinItemClass,
] = [
useColor(config, componentName, () => props.color),
useSize(config, componentName, () => props.size),
useValidity(() => props.isValid),
useClass(isInJoin, () => `btn btn-soft ${useJoinItem(isInJoin).value}`),
];

const hasLabelAndHelperText = computed((): boolean => props.label !== undefined && props.helperText !== undefined);
</script>
2 changes: 2 additions & 0 deletions packages/core/src/UI/Forms/Radio/UI/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as FoImageRadio } from '@/UI/Forms/Radio/UI/FoImageRadio.vue';
export { default as FoRadio } from '@/UI/Forms/Radio/UI/FoRadio.vue';
2 changes: 2 additions & 0 deletions packages/core/src/UI/Forms/Radio/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from '@/UI/Forms/Radio/Types';
export * from '@/UI/Forms/Radio/UI';
1 change: 1 addition & 0 deletions packages/core/src/UI/Forms/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from '@/UI/Forms/Checkbox';
export * from '@/UI/Forms/InputText';
export * from '@/UI/Forms/Join';
export * from '@/UI/Forms/Radio';
export * from '@/UI/Forms/Range';
export * from '@/UI/Forms/Select';
export * from '@/UI/Forms/Switch';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,13 @@ export function useSidebarItems(): ComputedRef<SidebarItem[]> {
icon: 'mdi:account-plus',
children: [],
},
{
text: 'Radio',
to: `${flyonUIVueNextPath}/forms/radio`,
icon: 'mdi:radio-button-checked',
children: [],
badge: _unreleasedBadge,
},
{
text: 'Range',
to: `${flyonUIVueNextPath}/forms/range`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
>
<FoBadge :color="item.badge.color"
preset="dash"
size="small"
size="extraSmall"
shape="pilled"
>
{{ item.badge.text }}
Expand Down
2 changes: 2 additions & 0 deletions packages/docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import SkeletonDocs from '@/Next/Components/Sk
import StatusDocs from '@/Next/Components/Status/StatusDocs.vue';
import BlockQuoteDocs from '@/Next/Content/BlockQuote/BlockQuoteDocs.vue';
import DividerDocs from '@/Next/Content/Divider/DividerDocs.vue';
import RadioDocs from '@/Next/Forms/Radio/RadioDocs.vue';
import RangeDocs from '@/Next/Forms/Range/RangeDocs.vue';
import DataTableDocs from '@/Next/Tables/DataTable/DataTableDocs.vue';
import ModalDocs from '@/Overlays/Modal/ModalDocs.vue';
Expand Down Expand Up @@ -111,6 +112,7 @@ export default {
{ name: 'NavbarDocs', instance: NavbarDocs },
{ name: 'PaginationDocs', instance: PaginationDocs },
{ name: 'PopoverDocs', instance: PopoverDocs },
{ name: 'RadioDocs', instance: RadioDocs },
{ name: 'RangeDocs', instance: RangeDocs },
{ name: 'RadialProgressDocs', instance: RadialProgressDocs },
{ name: 'SkeletonDocs', instance: SkeletonDocs },
Expand Down
87 changes: 87 additions & 0 deletions packages/docs/Next/Forms/Radio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Radio

### Default

<RadioDocs section="default" />

### With label and helper text

<RadioDocs section="with-label-and-helper-text" />

### Insets

<RadioDocs section="inset" />

## Colors

### Solid

<RadioDocs section="color" />

### Solid insets

<RadioDocs section="inset-color" />

### Custom colors

<RadioDocs section="custom-color" />

## Sizes

### Default sizes

<RadioDocs section="size" />

### Inset sizes

<RadioDocs section="inset-size" />

## States

### Validation states

<RadioDocs section="validation-state" />

## Illustrations

### Disabled

<RadioDocs section="disabled" />

### Inline group

<RadioDocs section="inline-group" />

### Vertical group

<RadioDocs section="vertical-group" />

[//]: # (todo: radio in dropdown)

### List group

<RadioDocs section="list-group" />

### Horizontal list group

<RadioDocs section="horizontal-list-group" />

### Button group

<RadioDocs section="button-group" />

## Custom options

### Image

<RadioDocs section="image" />

## Api

### Props

<RadioDocs section="props" />

### Slots

<RadioDocs section="slots" />
34 changes: 34 additions & 0 deletions packages/docs/Next/Forms/Radio/CustomRadioColor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<FoRadio v-model="selectedValue"
class="[--input-color:pink]"
label="FlyonUI variable"
:value="selectedValue"
/>

<FoRadio v-model="selectedValue"
class="checked:text-pink-300"
label="Tailwind utility colors"
:value="selectedValue"
/>

<FoRadio v-model="selectedValue"
class="[--input-color:green]"
label="FlyonUI variable"
:value="selectedValue"
is-inset
/>

<FoRadio v-model="selectedValue"
class="checked:text-green-700"
label="FlyonUI variable"
:value="selectedValue"
is-inset
/>
</template>

<script setup lang="ts">
import { FoRadio } from 'flyonui-vue';
import { ref } from 'vue';

const selectedValue = ref<string>('value');
</script>
21 changes: 21 additions & 0 deletions packages/docs/Next/Forms/Radio/DefaultRadio.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<FoRadio v-model="selectedValue"
label="Default"
:value="defaultValue"
/>

<FoRadio v-model="selectedValue"
label="Checked"
:value="checkedValue"
/>
</template>

<script setup lang="ts">
import { FoRadio } from 'flyonui-vue';
import { ref } from 'vue';

const defaultValue = 'default';
const checkedValue = 'checked';

const selectedValue = ref<typeof defaultValue | typeof checkedValue>('checked');
</script>
Loading