Skip to content

fix: allow typing in relationship input field#2943

Open
Srvankit wants to merge 1 commit intoappwrite:mainfrom
Srvankit:fix-relationship-input
Open

fix: allow typing in relationship input field#2943
Srvankit wants to merge 1 commit intoappwrite:mainfrom
Srvankit:fix-relationship-input

Conversation

@Srvankit
Copy link
Copy Markdown

@Srvankit Srvankit commented Mar 29, 2026

This fixes the issue where users were unable to type or paste values into the relationship field.

Previously, the component used Input.Select, which restricted input to a dropdown-only section. This prevented manual entry of IDs.

This PR replaces Input.Select with Input, restoring the ability to type and paste values, matching the behaviour before v6.

##Changes:

  • Replaced Input-Select with Input
  • Removed unused options prop
  • Enabled manual input handling

##Issue
Closes #2119

Summary by CodeRabbit

  • Refactor
    • Simplified the input select component to use a generic input field instead of a specialized select component, removing options configuration support.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 29, 2026

Walkthrough

The inputSelect.svelte component was refactored to use a generic Input component instead of Input.Select. The exported options prop, which previously accepted an array of option objects with value, label, and optional metadata, was removed. Event handling was updated to include an explicit on:input handler that assigns the value from e.target.value, while retaining bind:value, validation, and the info slot.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: restoring typing capability in the relationship input field by replacing Input.Select with Input.
Linked Issues check ✅ Passed The PR directly addresses issue #2119 by restoring manual typing and pasting functionality to the relationship input field through component replacement.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the relationship input field by replacing Input.Select with Input and removing the unused options prop, with no extraneous modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 29, 2026

Greptile Summary

This PR attempts to fix a regression where users could not type or paste values into the relationship input field by replacing Input.Select with a plain Input in inputSelect.svelte. While the intent is valid, the implementation modifies a shared wrapper component used across ~69 files, causing a widespread regression throughout the application.

Key issues:

  • options prop silently dropped — every caller that passes options to <InputSelect> (boolean columns, enum columns, filter dropdowns, row-limit pickers, index-type selectors, etc.) will now render a plain text field instead of a constrained dropdown, risking invalid data entry and a broken UI across the databases and settings areas.
  • on:change no longer forwarded — all callers that rely on on:change for state updates (e.g. updateRelatedList() in relationship.svelte, limitChange in limit.svelte) will silently receive no event, breaking their functionality.
  • optionalText prop not passed through to the inner Input, silently losing optional-label rendering.
  • TypeScript unsafetye.target.value in the on:input handler needs a cast to HTMLInputElement.

The fix should be targeted: either modify the relationship-specific call sites in relationship.svelte directly, or introduce a new dedicated component / an opt-in prop, rather than changing the shared InputSelect component that the rest of the app depends on for dropdown behaviour.

Confidence Score: 1/5

Not safe to merge — the change breaks dropdown functionality across ~69 components app-wide and silently drops on:change callbacks.

A P0 issue exists: removing the options prop from a shared component that the entire app uses as a dropdown select destroys correct behaviour for boolean/enum/filter/limit/index-type inputs. A P1 issue also exists (on:change forwarding removed), which breaks state-update callbacks in relationship and other components. These are present, definite defects on shipped code paths, not speculative concerns.

src/lib/elements/forms/inputSelect.svelte — core change; all ~69 consuming files are indirectly affected.

Important Files Changed

Filename Overview
src/lib/elements/forms/inputSelect.svelte Replaces Input.Select with plain Input and drops the options prop, breaking all dropdown/select functionality for the ~69 callers across the app that rely on this shared component; also removes on:change forwarding, breaking state-update callbacks throughout the codebase.

Reviews (1): Last reviewed commit: "fix: allow typing in relationship input ..." | Re-trigger Greptile

Comment on lines +40 to +55
<Input
{id}
{label}
{placeholder}
{disabled}
{autofocus}
{leadingIcon}
helper={error ?? helper}
{required}
state={error ? 'error' : 'default'}
data-command-center-ignore
on:invalid={handleInvalid}
on:input={(e) => value = e.target.value}
bind:value>
<slot name="info" slot="info" />
</Input.Select>
</Input>
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.

P0 Shared component change breaks all dropdown usages across the codebase

inputSelect.svelte is a shared component used in ~69 files throughout the app. Replacing Input.Select with a plain Input and removing the options prop means every caller that passes options to <InputSelect> will silently receive a plain text field instead of a dropdown — with all option data being silently discarded.

Affected components (non-exhaustive):

  • columns/types/boolean.svelte — true/false selection becomes free-text input, allowing invalid values
  • columns/types/enum.svelte — enum value selection breaks; users can type arbitrary strings not in the enum
  • lib/components/filters/content.svelte and filtersModal.svelte — filter operator/value dropdowns break
  • lib/components/limit.svelte — row limit picker becomes free-text
  • databases/.../createColumn.svelte — column type picker breaks
  • databases/.../indexes/create.svelte — index type picker breaks
  • Every InputSelect call with options in relationship.svelte (to-many section, lines 303, 322, 352) — these now show plain text inputs too

The intent of this PR (restoring typing ability in the relationship field) is valid, but it should target only the relevant relationship input rather than changing this shared wrapper component. The fix should be applied directly in relationship.svelte where the relationship-specific InputSelect calls exist, or a separate component/prop should be introduced.

Comment on lines +51 to +52
on:invalid={handleInvalid}
on:input={(e) => value = e.target.value}
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.

P1 on:change no longer forwarded — breaks all callers that depend on it

The original component forwarded on:change to parent components. This PR removes that forwarding and only handles on:input internally. All existing callers that pass on:change handlers will receive no event.

For example, in relationship.svelte:

<InputSelect ... on:change={() => { if (!relatedList[0]) relatedList = [''] ; updateRelatedList(); }} />
<InputSelect ... on:change={updateRelatedList} />

These handlers won't fire, so relatedList and value will never be updated when the user selects/types a value.

Also in lib/components/limit.svelte:

<InputSelect id="rows" {options} bind:value={limit} on:change={limitChange} />

The row limit change callback will be silently dropped.

The on:change event should be forwarded alongside on:input:

Suggested change
on:invalid={handleInvalid}
on:input={(e) => value = e.target.value}
on:invalid={handleInvalid}
on:input={(e) => value = (e.target as HTMLInputElement).value}
on:change
bind:value>

state={error ? 'error' : 'default'}
data-command-center-ignore
on:invalid={handleInvalid}
on:input={(e) => value = e.target.value}
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.

P2 e.target is not typed as HTMLInputElement

e.target is typed as EventTarget | null, so accessing .value directly is not type-safe and will cause a TypeScript error.

Suggested change
on:input={(e) => value = e.target.value}
on:input={(e) => value = (e.target as HTMLInputElement).value}

Comment on lines +40 to 54
<Input
{id}
{label}
{placeholder}
{disabled}
{autofocus}
{leadingIcon}
helper={error ?? helper}
{required}
state={error ? 'error' : 'default'}
data-command-center-ignore
on:invalid={handleInvalid}
on:input={(e) => value = e.target.value}
bind:value>
<slot name="info" slot="info" />
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.

P2 optionalText prop is no longer passed to the inner component

The optionalText prop is declared on line 10 and was passed to Input.Select in the original code. It is not forwarded to the new Input component, so any caller relying on optional text display (e.g. "optional" labels) will silently lose that feature.

Copy link
Copy Markdown
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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/elements/forms/inputSelect.svelte`:
- Around line 40-55: The component currently exports optionalText but never
passes it to the child <Input>, so callers’ optional-labels stop rendering; fix
by either forwarding optionalText into the <Input> (e.g., add
optionalText={optionalText} to the <Input> element in inputSelect.svelte) or
remove the optionalText export from this component and update the public
API/consumers accordingly; locate the optionalText export in this file and the
<Input> usage to implement the chosen change.
- Around line 40-55: The change replaced the shared select wrapper (InputSelect)
with a plain text <Input>, which breaks select-specific features (options,
on:select, non-string option values); restore the original select element and
its select-specific behavior (ensure props like options, on:select, bind:value
and handlers such as handleInvalid remain functional and the info slot stays in
place). If free-form text is needed only for the relationship field, add an
explicit opt-in prop (e.g., allowCustom or freeForm) to InputSelect and only
render the plain <Input> when that prop is true; otherwise render the select
component (preserving option value types and select events).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e756d2d1-93d4-4810-9207-cf8677df367a

📥 Commits

Reviewing files that changed from the base of the PR and between 00d9765 and a5b8ecd.

📒 Files selected for processing (1)
  • src/lib/elements/forms/inputSelect.svelte

Comment on lines +40 to +55
<Input
{id}
{label}
{placeholder}
{disabled}
{autofocus}
{leadingIcon}
helper={error ?? helper}
{required}
state={error ? 'error' : 'default'}
data-command-center-ignore
on:invalid={handleInvalid}
on:input={(e) => value = e.target.value}
bind:value>
<slot name="info" slot="info" />
</Input.Select>
</Input>
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.

⚠️ Potential issue | 🟡 Minor

optionalText no longer has any effect.

Line 10 still exposes optionalText, but the new <Input> call never uses it. Any caller passing that prop will stop rendering its optional-label text with no compile-time signal. Either keep honoring the prop here or remove/update the public API in the same change.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/elements/forms/inputSelect.svelte` around lines 40 - 55, The
component currently exports optionalText but never passes it to the child
<Input>, so callers’ optional-labels stop rendering; fix by either forwarding
optionalText into the <Input> (e.g., add optionalText={optionalText} to the
<Input> element in inputSelect.svelte) or remove the optionalText export from
this component and update the public API/consumers accordingly; locate the
optionalText export in this file and the <Input> usage to implement the chosen
change.

⚠️ Potential issue | 🔴 Critical

Don't convert the shared select wrapper into a plain text input.

InputSelect is still used as a real dropdown in src/lib/components/billing/selectPaymentMethod.svelte:59-75, src/routes/(console)/organization-[organization]/billing/budgetAlert.svelte:105-115, src/routes/(console)/organization-[organization]/members/edit.svelte:81-93, and src/routes/(console)/organization-[organization]/createMember.svelte:73-85. With this change those screens silently ignore options, lose select-specific behavior like on:select, and coerce non-string option values into plain text. Please scope the free-form behavior to the relationship field, or make it opt-in instead of changing the shared default.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/elements/forms/inputSelect.svelte` around lines 40 - 55, The change
replaced the shared select wrapper (InputSelect) with a plain text <Input>,
which breaks select-specific features (options, on:select, non-string option
values); restore the original select element and its select-specific behavior
(ensure props like options, on:select, bind:value and handlers such as
handleInvalid remain functional and the info slot stays in place). If free-form
text is needed only for the relationship field, add an explicit opt-in prop
(e.g., allowCustom or freeForm) to InputSelect and only render the plain <Input>
when that prop is true; otherwise render the select component (preserving option
value types and select events).

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.

🐛 Bug Report: cannot type or copy into relationship input field

1 participant