Skip to content

feat: add input component - #1173

Merged
danielroe merged 16 commits into
npmx-dev:mainfrom
alexdln:feat/add-input-component
Feb 8, 2026
Merged

feat: add input component#1173
danielroe merged 16 commits into
npmx-dev:mainfrom
alexdln:feat/add-input-component

Conversation

@alexdln

Copy link
Copy Markdown
Member

Added a common component for text-like inputs and used it throughout the site. The current search-field is used as a basis, with soft rounding, a light border, a bright border on hover, an accent border on focus, and an accent outline 2px from the input on focus

I went through all the places and made additional adjustments where needed. Where I could, I increased the size a bit (to 32px instead of 28.6). Also, if it was a group with a button or block, I adjusted the size for them as well.

I made the inputs a consistent height to avoid having to play exact matches in the future. Generally, leading-none with padding covered this issue, but sometimes it would break, so I explicitly specified the height as well.

(logic is covered for 100%, so I hope I configured everything correctly)

Closes#1172

@coderabbitai

coderabbitaiBot commented Feb 7, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a new InputBase Vue component (props: disabled, size, noCorrect; emits: focus, blur; exposes focus() and blur()). Replaces numerous native input elements across the app with InputBase (header, search, auth/connector modals, compare UI, org panels, package controls, date inputs, OTP input), standardising classes and sizes. Adjusts AppHeader centre alignment to use justify-end on the home page and justify-center elsewhere while preserving the existing search-expanded visibility condition. Adds unit and accessibility tests for InputBase. No existing exported public signatures were removed.

Possibly related PRs

Suggested reviewers

  • danielroe
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check nameStatusExplanation
Description check✅ PassedThe pull request description accurately describes the implementation of a reusable input component and its application throughout the codebase.
Linked Issues check✅ PassedThe pull request fully implements all stated objectives from issue #1172: creates InputBase component with specified styling, replaces text inputs site-wide, and achieves 100% test coverage.
Out of Scope Changes check✅ PassedAll code changes are directly aligned with the input component consolidation objective; no unrelated modifications detected.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/components/Filter/Panel.vue (1)

116-119: ⚠️ Potential issue | 🟡 Minor

Switch from @input and :value to @update:modelValue and :model-value with InputBase.

InputBase defines only update:modelValue (plus focus and blur events), not native input events. Using @input and :value will not work correctly with this component. Update the handler signature to accept a string value directly instead of an Event object.

Suggested fix
-function handleTextInput(event: Event) {- const target = event.target as HTMLInputElement- emit('update:text', target.value)-}+function handleTextInput(value: string) {+ emit('update:text', value)+}
 <InputBase
id="filter-search"
type="text"
- :value="filters.text"+ :model-value="filters.text"
:placeholder="searchPlaceholder"
autocomplete="off"
class="w-full min-w-25"
size="medium"
noCorrect
- `@input`="handleTextInput"+ `@update`:modelValue="handleTextInput"
/>
🧹 Nitpick comments (1)
app/components/Input/Base.vue (1)

2-8: Prop name shadows imported utility.

The prop noCorrect (line 8) shadows the imported noCorrect utility (line 2). While this works because you access the utility via props.noCorrect ? noCorrect : undefined, the naming could be clearer.

Consider renaming the prop to disableCorrect or similar to avoid confusion with the imported utility object.

♻️ Suggested rename
-import { noCorrect } from '~/utils/input'+import { noCorrect as noCorrectAttrs } from '~/utils/input'
const props = withDefaults(
defineProps<{
modelValue?: string
size?: 'small' | 'medium' | 'large'
noCorrect?: boolean
}>(),

Then update line 41:

- v-bind="props.noCorrect ? noCorrect : undefined"+ v-bind="props.noCorrect ? noCorrectAttrs : undefined"

Comment threadapp/components/Header/SearchBox.vue
Comment threadapp/components/Org/MembersPanel.vue
Comment threadapp/components/Org/OperationsQueue.vue
Comment threadapp/components/Org/TeamsPanel.vue
Comment threadapp/components/Org/TeamsPanel.vue
Comment threadtest/nuxt/components/Input/Base.spec.ts
@alexdln

Copy link
Copy Markdown
MemberAuthor

I'm afraid I need rounded-l here, not rounded-is, since that component doesn't change its direction at all. I'm looking for a way to ignore this error

@danielroe

Copy link
Copy Markdown
Member

I'm afraid I need rounded-l here, not rounded-is, since that component doesn't change its direction at all. I'm looking for a way to ignore this error

cc: @userquin

@alexdln

Copy link
Copy Markdown
MemberAuthor

Oh, it was wrong before as well. I've restored this fragment, I hope I'll find time later to polish these pages too and improve them for rtl

@userquin

Copy link
Copy Markdown
Member

I'm afraid I need rounded-l here, not rounded-is, since that component doesn't change its direction at all. I'm looking for a way to ignore this error

cc: @userquin

we can add a custom rule/shorcut for this

@alexdln

Copy link
Copy Markdown
MemberAuthor

I think it would be useful to leave the option to skip the error for now (for example, by writing the reason and continuing to receive warnings)

Essentially, these are places where we haven't yet worked out the RTL perfectly and we have a group of elements going from left to right. We probably need to collect all these elements and understand how they should look, and then continue following this guide for these situations...

@vercel

vercelBot commented Feb 7, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
npmx.devReadyReadyPreview, CommentFeb 8, 2026 6:34pm
2 Skipped Deployments
ProjectDeploymentActionsUpdated (UTC)
docs.npmx.devIgnoredIgnoredPreviewFeb 8, 2026 6:34pm
npmx-lunariaIgnoredIgnoredFeb 8, 2026 6:34pm

Request Review

@userquin

userquin commented Feb 7, 2026

Copy link
Copy Markdown
Member

I'm afraid I need rounded-l here, not rounded-is, since that component doesn't change its direction at all. I'm looking for a way to ignore this error

Use force-rounded-l once #1179 merged

@alexdln

Copy link
Copy Markdown
MemberAuthor

Huge thanks @userquin

@danielroe

Copy link
Copy Markdown
Member

(it's merged)

Comment threadapp/components/Input/Base.vue Outdated
@codecov

codecovBot commented Feb 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.26087% with 5 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
app/pages/index.vue0.00%1 Missing and 2 partials ⚠️
app/components/Header/SearchBox.vue0.00%0 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

Comment threadapp/components/Input/Base.vue Outdated
)

const emit = defineEmits<{
'update:modelValue': [value: string]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

let' use defineModel for every prop/emit pair...

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Thanks, looks much better now (I don’t remember why I made it so complicated)

Comment threadapp/components/Input/Base.vue Outdated
defineExpose({
focus: () => el.value?.focus(),
blur: () => el.value?.blur(),
getBoundingClientRect: () => el.value?.getBoundingClientRect(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

do we need this one anywhere?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

No, and it doesn't seem to be useful, I'll remove it, thanks

Comment threadapp/components/Org/MembersPanel.vue Outdated
:placeholder="$t('org.members.username_placeholder')"
v-bind="noCorrect"
class="w-full px-2 py-1.5 font-mono text-sm bg-bg border border-border rounded text-fg placeholder:text-fg-subtle transition-colors duration-200 focus:border-border-hover focus-visible:outline-accent/70"
noCorrect

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

normally we'd do kebab-cased no-correct in a template.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Thanks, I forget every time, even if there is nothing more logical than kebab in the markup...

@danielroedanielroe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

great work! just added a couple of small comments from a vue pov

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Comment threadapp/components/Compare/PackageSelector.vue
Comment threadapp/components/Package/ListControls.vue
Sign up for freeto 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.

feat(ui): Add input component

4 participants

@alexdln@danielroe@userquin@knowler