Skip to content

feat(FoRadio): First implementation#136

Merged
michaelcozzolino merged 8 commits into2.xfrom
feat/radio
Mar 1, 2026
Merged

feat(FoRadio): First implementation#136
michaelcozzolino merged 8 commits into2.xfrom
feat/radio

Conversation

@michaelcozzolino
Copy link
Owner

@michaelcozzolino michaelcozzolino commented Mar 1, 2026

Summary by CodeRabbit

New Features

  • Radio Component - New form input component with support for standard and image-based options.
  • Comprehensive Radio Variants - Radio inputs support colors, multiple sizes (extraSmall to extraLarge), validation states, labels, helper text, and inset styling.
  • Grouped Radios - Support for inline, vertical, list-based, and button-grouped radio arrangements.
  • Image-Based Selection - Image radio variant enables visual selection options.
  • Documentation - Complete Radio component documentation with live examples.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 1, 2026

Warning

Rate limit exceeded

@michaelcozzolino has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 36 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 8922582 and 2c07f7a.

📒 Files selected for processing (4)
  • packages/core/src/UI/Forms/Radio/Types/Radio.ts
  • packages/core/src/UI/Forms/Radio/UI/FoRadio.vue
  • packages/docs/Next/Forms/Radio/RadioHorizontalListGroup.vue
  • packages/docs/Next/Forms/Radio/RadioListGroup.vue

Walkthrough

This pull request introduces a new Radio component system for FlyonUI Vue. It adds RadioProps and ImageRadioProps type definitions, creates FoRadio.vue and FoImageRadio.vue Vue components, and integrates them into the component sizing system via useSize. The Image interface is added to Utils.ts and referenced in both Avatar and Radio components. The Radio module is exported through barrel files and registered in the app configuration. Documentation is added including a RadioDocs.vue component and 19 example components demonstrating various configurations such as colors, sizes, validation states, image variants, and grouped layouts. A sidebar entry for Radio documentation is also added.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(FoRadio): First implementation' clearly and directly describes the main change—introducing the FoRadio component for the first time, which aligns with the substantial addition of Radio component types, UI components, configuration updates, and comprehensive documentation throughout the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/radio

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 1, 2026

Deploying flyonui-vue with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2c07f7a
Status: ✅  Deploy successful!
Preview URL: https://c1d13178.flyonui-vue.pages.dev
Branch Preview URL: https://feat-radio.flyonui-vue.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 1, 2026

Deploying flyonui-vue-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2c07f7a
Status: ✅  Deploy successful!
Preview URL: https://e8d5d653.flyonui-vue-v3.pages.dev
Branch Preview URL: https://feat-radio.flyonui-vue-v3.pages.dev

View logs

@michaelcozzolino michaelcozzolino marked this pull request as ready for review March 1, 2026 12:35
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (3)
packages/docs/Next/Forms/Radio/RadioButtonGroup.vue (1)

16-31: Prefer a single source of truth for default selection.

buttons is static but stored in a ref, and selectedValue hardcodes '1'. If options change later, the default can drift. Use a plain constant for options and derive the default from it.

♻️ Suggested refactor
-const buttons = ref<{ label: string; value: string }[]>([
+const buttons = [
     {
         label: 'Radio 1',
         value: '1',
@@
     {
         label: 'Radio 3',
         value: '3',
     },
-]);
+];

-const selectedValue = ref<string>('1');
+const selectedValue = ref<string>(buttons[0]?.value ?? '');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/docs/Next/Forms/Radio/RadioButtonGroup.vue` around lines 16 - 31,
The component currently uses a reactive ref for the static options (buttons) and
hardcodes selectedValue to '1', which risks drift if options change; change
buttons to a plain constant (e.g., const buttons = [...]) and derive the default
selectedValue from that constant (e.g., initialize selectedValue using the first
option's value) so the default is always tied to the options; update any
references to buttons and selectedValue in RadioButtonGroup.vue accordingly.
packages/docs/Next/Forms/Radio/RadioListGroup.vue (1)

25-38: Consider using a plain const instead of ref for static data.

The languages array is never mutated, so wrapping it in ref adds unnecessary reactivity overhead.

♻️ Proposed refactor
-const languages = ref<{ label: string; value: string }[]>([
+const languages: { label: string; value: string }[] = [
     {
         label: 'C++',
         value: 'c++',
     },
     {
         label: 'Ruby',
         value: 'ruby',
     },
     {
         label: 'Swift',
         value: 'swift',
     },
-]);
+];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/docs/Next/Forms/Radio/RadioListGroup.vue` around lines 25 - 38, The
languages array is defined as a ref but never mutated; replace ref with a plain
const declaration (const languages: { label: string; value: string }[] = [...])
to avoid unnecessary reactivity overhead, and update any code in
RadioListGroup.vue that currently accesses languages.value to use languages
directly (e.g., in templates or methods) so references match the new non-ref
variable.
packages/docs/Next/Forms/Radio/RadioDocs.vue (1)

2-5: Consider including FoImageRadio in API documentation.

The api-docs-component-names prop only specifies "FoRadio", but the 'image' section demonstrates FoImageRadio. Consider adding it for complete API coverage.

📖 Suggested change
     <ComponentDocs :previews="previews"
                    :section="section"
-                   api-docs-component-names="FoRadio"
+                   api-docs-component-names="FoRadio,FoImageRadio"
     />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/docs/Next/Forms/Radio/RadioDocs.vue` around lines 2 - 5, The API
docs currently only list "FoRadio" in the ComponentDocs prop
`api-docs-component-names` but the docs also demonstrate `FoImageRadio`; update
the `ComponentDocs` invocation to include both component names (e.g. add
"FoImageRadio" alongside "FoRadio" in the `api-docs-component-names` prop) so
the image variant is included in the generated API documentation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/UI/Forms/Radio/UI/FoImageRadio.vue`:
- Around line 1-24: The radio input in FoImageRadio.vue lacks an id and
aria-label and FoLabel is not semantically associated, so update the template to
generate and bind a unique id (e.g., computed/constant like imageRadioId) to the
input element used with v-model (checkedValue) and set FoLabel's :for to that
id; also add an aria-label on the input (use image.alt or a prop fallback) so
screen readers announce the image radio option. Ensure the id is derived
deterministically (e.g., from value or a small uniqueId helper) and keep the
v-model (checkedValue), :value (value) and existing image.src / image.alt usage
unchanged.

In `@packages/core/src/UI/Forms/Radio/UI/FoRadio.vue`:
- Around line 21-30: Normalize the incoming label before rendering: add a
computed prop (e.g., normalizedLabel) in FoRadio.vue that returns label if it's
a string, otherwise resolves common fields (label.text, label.label) or falls
back to String(label) / JSON.stringify(label) safely (or empty string if null);
use normalizedLabel for the :aria-label binding (so isInJoin uses the normalized
name even when label is an object) and for the displayed text inside <FoLabel>
and the other occurrence around line 84 to avoid rendering “[object Object]”.

In `@packages/docs/Next/Forms/Radio.md`:
- Around line 1-5: The document's heading hierarchy is incorrect: change the
"### Default" heading to "## Default" (or insert an h2 parent before other h3s)
so it follows the top-level "# Radio" correctly; update the heading that
precedes the <RadioDocs section="default" /> component (and any other standalone
h3s) to use h2 or nest h3s under a new h2 to restore proper incremental heading
levels.

In `@packages/docs/Next/Forms/Radio/CustomRadioColor.vue`:
- Around line 2-34: The FoRadio options all set :value="selectedValue" so every
radio shares the same value and selection can't change; update each FoRadio to
supply a unique literal or distinct identifier for its :value (e.g., strings
like "pink-variable", "pink-utility", "green-variable", "green-utility") instead
of binding to the shared selectedValue ref, keeping the v-model="selectedValue"
on each radio so the group can track the chosen value.

In `@packages/docs/Next/Forms/Radio/InsetRadioColor.vue`:
- Around line 2-70: The radios all bind :value to the model (selectedValue) so
every FoRadio ends up with the same value; change each FoRadio's value prop to a
unique literal (e.g., value="default", value="neutral", value="primary", etc.)
while keeping v-model="selectedValue", and ensure selectedValue's initial value
matches one of those option strings; update the FoRadio instances (component
name: FoRadio, model variable: selectedValue) accordingly so each option
represents a distinct selection.

In `@packages/docs/Next/Forms/Radio/RadioColor.vue`:
- Around line 2-53: The FoRadio instances all use :value="selectedValue", so
every radio shares the same value and cannot be distinguished; change each
FoRadio's value prop to a distinct literal (e.g., value="default",
value="neutral", value="primary", value="secondary", value="accent",
value="info", value="success", value="warning", value="error") while keeping
v-model="selectedValue", and initialize the selectedValue data property to one
of those string values so the radio group behaves correctly.

In `@packages/docs/Next/Forms/Radio/RadioHorizontalListGroup.vue`:
- Line 5: Update the heading copy in the RadioHorizontalListGroup.vue component
to fix the typo: change the text "Select you favourite language:" to "Select
your favourite language:" inside the template where the heading string is
rendered (look for the literal string "Select you favourite language:" in
RadioHorizontalListGroup.vue and replace it with "Select your favourite
language:").

In `@packages/docs/Next/Forms/Radio/RadioListGroup.vue`:
- Line 5: In the template of the RadioListGroup.vue component update the typo in
the label string: change "Select you favourite language:" to "Select your
favourite language:" so the UI reads correctly; locate the text in the
component/template and replace the incorrect "you" with "your".

In `@packages/docs/Next/Forms/Radio/RadioValidationState.vue`:
- Around line 1-39: The radios share only two values (deleteValue and
archiveValue) bound to a single v-model (selectedValue) so clicking one selects
its duplicate; fix by giving each radio a unique value or splitting into two
radio groups: either change the value constants used in the template (FoRadio
:value attributes) so each radio has a unique identifier instead of reuse of
deleteValue/archiveValue, or create two separate v-model refs (e.g.,
selectedValid and selectedInvalid) and bind the top two radios to one ref and
the bottom two to the other so FoRadio, selectedValue, deleteValue and
archiveValue usages no longer cause cross-selection.

---

Nitpick comments:
In `@packages/docs/Next/Forms/Radio/RadioButtonGroup.vue`:
- Around line 16-31: The component currently uses a reactive ref for the static
options (buttons) and hardcodes selectedValue to '1', which risks drift if
options change; change buttons to a plain constant (e.g., const buttons = [...])
and derive the default selectedValue from that constant (e.g., initialize
selectedValue using the first option's value) so the default is always tied to
the options; update any references to buttons and selectedValue in
RadioButtonGroup.vue accordingly.

In `@packages/docs/Next/Forms/Radio/RadioDocs.vue`:
- Around line 2-5: The API docs currently only list "FoRadio" in the
ComponentDocs prop `api-docs-component-names` but the docs also demonstrate
`FoImageRadio`; update the `ComponentDocs` invocation to include both component
names (e.g. add "FoImageRadio" alongside "FoRadio" in the
`api-docs-component-names` prop) so the image variant is included in the
generated API documentation.

In `@packages/docs/Next/Forms/Radio/RadioListGroup.vue`:
- Around line 25-38: The languages array is defined as a ref but never mutated;
replace ref with a plain const declaration (const languages: { label: string;
value: string }[] = [...]) to avoid unnecessary reactivity overhead, and update
any code in RadioListGroup.vue that currently accesses languages.value to use
languages directly (e.g., in templates or methods) so references match the new
non-ref variable.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bade25d and 8922582.

⛔ Files ignored due to path filters (16)
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-button-group-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-color-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-custom-color-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-default-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-disabled-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-horizontal-list-group-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-image-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-inline-group-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-inset-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-inset-color-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-inset-size-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-list-group-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-size-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-validation-state-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-vertical-group-chromium-linux.png is excluded by !**/*.png
  • packages/docs/tests/EndToEnd/Docs.browser.spec.ts-snapshots/forms-radio-with-label-and-helper-text-chromium-linux.png is excluded by !**/*.png
📒 Files selected for processing (33)
  • packages/core/src/Lib/UseFlyonUIVueAppConfig/Types/FlyonUIVueAppConfig.ts
  • packages/core/src/Lib/UseSize/Internal/Lib/UseSize.ts
  • packages/core/src/Lib/UseSize/Types/Size.ts
  • packages/core/src/Types/Utils.ts
  • packages/core/src/UI/Components/Avatar/Types/Avatar.ts
  • packages/core/src/UI/Forms/Radio/Types/Radio.ts
  • packages/core/src/UI/Forms/Radio/Types/index.ts
  • packages/core/src/UI/Forms/Radio/UI/FoImageRadio.vue
  • packages/core/src/UI/Forms/Radio/UI/FoRadio.vue
  • packages/core/src/UI/Forms/Radio/UI/index.ts
  • packages/core/src/UI/Forms/Radio/index.ts
  • packages/core/src/UI/Forms/index.ts
  • packages/docs/.vitepress/theme/Components/Layout/Features/Sidebar/Lib/UseSidebarItems.ts
  • packages/docs/.vitepress/theme/Components/Layout/Features/Sidebar/UI/SidebarNode.vue
  • packages/docs/.vitepress/theme/index.ts
  • packages/docs/Next/Forms/Radio.md
  • packages/docs/Next/Forms/Radio/CustomRadioColor.vue
  • packages/docs/Next/Forms/Radio/DefaultRadio.vue
  • packages/docs/Next/Forms/Radio/DisabledRadio.vue
  • packages/docs/Next/Forms/Radio/ImageRadio.vue
  • packages/docs/Next/Forms/Radio/InlineRadioGroup.vue
  • packages/docs/Next/Forms/Radio/InsetRadio.vue
  • packages/docs/Next/Forms/Radio/InsetRadioColor.vue
  • packages/docs/Next/Forms/Radio/InsetRadioSize.vue
  • packages/docs/Next/Forms/Radio/RadioButtonGroup.vue
  • packages/docs/Next/Forms/Radio/RadioColor.vue
  • packages/docs/Next/Forms/Radio/RadioDocs.vue
  • packages/docs/Next/Forms/Radio/RadioHorizontalListGroup.vue
  • packages/docs/Next/Forms/Radio/RadioListGroup.vue
  • packages/docs/Next/Forms/Radio/RadioSize.vue
  • packages/docs/Next/Forms/Radio/RadioValidationState.vue
  • packages/docs/Next/Forms/Radio/RadioWithLabelAndHelperText.vue
  • packages/docs/Next/Forms/Radio/VerticalRadioGroup.vue

michaelcozzolino and others added 4 commits March 1, 2026 14:02
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@michaelcozzolino michaelcozzolino merged commit e15d21e into 2.x Mar 1, 2026
7 checks passed
@michaelcozzolino michaelcozzolino deleted the feat/radio branch March 1, 2026 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant