Skip to content

Conversation

@vaebe
Copy link
Owner

@vaebe vaebe commented Nov 18, 2025

添加Input组件

描述

此PR添加了Input组件的初版实现,为UI库提供了基础的输入框功能。

变更内容

  • 创建了Input组件的React实现 (tsx)
  • 添加了Input组件的类型定义
  • 实现了Input组件的样式 (scss)
  • 提供了Input组件的单元测试
  • 添加了Input组件的文档说明

文件变更

  • packages/ccui/ui/input/index.ts - Input组件入口文件
  • packages/ccui/ui/input/src/input-types.ts - Input组件类型定义
  • packages/ccui/ui/input/src/input.scss - Input组件样式
  • packages/ccui/ui/input/src/input.tsx - Input组件主要实现
  • packages/ccui/ui/input/test/input.test.ts - Input组件单元测试
  • packages/docs/components/input/index.md - Input组件文档

测试

  • Input组件已添加单元测试,确保基本功能正常工作

Summary by CodeRabbit

  • New Features

    • Added a registerable Input component with size variants, disabled/readonly states, clearable input, password visibility toggle, prepend/append/prefix/suffix slots, and standard event bindings.
  • Documentation

    • Added comprehensive Input docs with examples, props, events, types, and slots.
  • Style

    • Adjusted base corner radius, introduced new size tokens, and added small spacing utility classes.
  • Tests

    • Added unit tests covering rendering, interactions, states, and events.

@coderabbitai
Copy link

coderabbitai bot commented Nov 18, 2025

Walkthrough

Adds a Vue 3 Input component (props, JSX implementation, SCSS), tests, documentation, a plugin entrypoint (named and default exports with install), theme token updates, and four docs margin utility classes.

Changes

Cohort / File(s) Summary
Input plugin entrypoint
packages/ccui/ui/input/index.ts
Adds named export Input, assigns Input.install(app: App), and provides a default export object with metadata (title, category, status) and install(app: App) to register the component.
Input types & props
packages/ccui/ui/input/src/input-types.ts
New prop/type module: InputType, InputSize, inputProps definitions and exported InputProps (ExtractPropTypes).
Input component implementation
packages/ccui/ui/input/src/input.tsx
New JSX-based Vue 3 component CInput (default export) with internal state, computed currentType, class composition, handlers (input/change/focus/blur/clear/toggle password), emits, slots (prepend/append/prefix/suffix) and v-model support.
Input styles
packages/ccui/ui/input/src/input.scss
New SCSS root .#{$cls-prefix}-input with wrapper, prepend/append, inner, prefix/suffix, clear/password controls, size modifiers (large/default/small), hover/focus/disabled/placeholder rules and spacing tokens.
Input tests
packages/ccui/ui/input/test/input.test.ts
New unit tests covering rendering, type switching, size classes, placeholder, disabled/readonly, clearable behavior, prepend/append, emitted events, clear action, and password visibility toggle.
Docs — Input page
packages/docs/components/input/index.md
New Chinese documentation page with demos, usage patterns, prop/event/slot tables, and examples.
Docs CSS utilities
packages/docs/.vitepress/theme/styles/index.css
Adds margin utility classes: .mt-10, .mb-10, .ml-10, .mr-10 (10px).
Theme tokens
packages/theme/themes/light.ts
Updates border-radius from 2px4px and adds tokens: size-sm: 24px, size-md: 32px, size-lg: 40px.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant C as CInput
    participant S as State
    participant E as Events

    U->>C: type characters
    C->>S: set inputValue
    C->>E: emit input / update:modelValue
    Note right of C `#D3F9D8`: 'change' may emit on blur/confirm
    U->>C: blur / confirm
    C->>E: emit change

    U->>C: click clear (if clearable)
    C->>S: inputValue = ''
    C->>E: emit clear / update:modelValue

    U->>C: click password toggle (if showPassword)
    C->>S: toggle isPasswordVisible
    C->>C: re-render input type (text/password)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay extra attention to:
    • packages/ccui/ui/input/src/input.tsx — state syncing with v-model, emits, class composition, slot/prop interactions, and password toggle edge cases.
    • packages/ccui/ui/input/src/input.scss — size modifiers, prefix/suffix padding and token consistency.
    • packages/ccui/ui/input/test/input.test.ts — timing of emitted events and clear/password interactions.

Poem

🐇
I nibble props beneath the moonlit tree,
A clear button shines and secrets hide to be.
Styles stitched neat, tests tucked in a row,
Tokens hop in, and docs softly glow.
Hooray — an Input, spry and ready to show!

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 clearly and concisely describes the main change: adding an Input component to the UI library.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-input

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.

Copy link

@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: 6

🧹 Nitpick comments (3)
packages/ccui/ui/input/index.ts (1)

1-17: Input entrypoint and plugin wiring look correct

Named export Input plus a default meta object with install both register the same component and align with how the tests import Input from this entrypoint. Optional: you could delegate the default export’s install to Input.install to avoid duplicating the registration call.

packages/ccui/ui/input/test/input.test.ts (1)

14-205: Good coverage; consider adding v-model and prefix/suffix layout tests

The suite does a nice job covering core behaviors (types, size classes, disabled/readonly, clearable, prepend/append, events, password toggle). Two gaps worth adding:

  • A test that uses v-model:value (or the chosen v-model API) to catch regressions in the two‑way binding contract.
  • A layout‑level test for prefix/suffix/clearable that asserts the correct modifier classes exist on the block and that the inner input gets the expected padding; this would have surfaced the current BEM alignment issue with input.scss.

Otherwise the structure and use of useNamespace in the tests look good.

packages/ccui/ui/input/src/input.tsx (1)

73-81: Unused focus state

isFocused is set in handleFocus/handleBlur but never read anywhere, so it currently has no effect.

Either wire it into a focus class (e.g. ns.is('focused')) or remove it to keep the component lean:

-    const isFocused = ref(false)
@@
-    const handleFocus = (e: FocusEvent) => {
-      isFocused.value = true
-      emit('focus', e)
-    }
+    const handleFocus = (e: FocusEvent) => {
+      emit('focus', e)
+    }
@@
-    const handleBlur = (e: FocusEvent) => {
-      isFocused.value = false
-      emit('blur', e)
-    }
+    const handleBlur = (e: FocusEvent) => {
+      emit('blur', e)
+    }

Or, if you plan to add focus styles later, consider adding the corresponding class now so it’s testable.

Also applies to: 88-90

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b275306 and 4cc898a.

📒 Files selected for processing (8)
  • packages/ccui/ui/input/index.ts (1 hunks)
  • packages/ccui/ui/input/src/input-types.ts (1 hunks)
  • packages/ccui/ui/input/src/input.scss (1 hunks)
  • packages/ccui/ui/input/src/input.tsx (1 hunks)
  • packages/ccui/ui/input/test/input.test.ts (1 hunks)
  • packages/docs/.vitepress/theme/styles/index.css (1 hunks)
  • packages/docs/components/input/index.md (1 hunks)
  • packages/theme/themes/light.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/ccui/ui/input/src/input.tsx (2)
packages/ccui/ui/input/src/input-types.ts (2)
  • inputProps (6-47)
  • InputProps (49-49)
packages/ccui/ui/shared/hooks/use-namespace.ts (1)
  • useNamespace (31-47)
packages/ccui/ui/input/test/input.test.ts (2)
packages/ccui/ui/shared/hooks/use-namespace.ts (1)
  • useNamespace (31-47)
packages/ccui/ui/input/src/input-types.ts (1)
  • InputSize (4-4)
🪛 LanguageTool
packages/docs/components/input/index.md

[grammar] ~227-~227: Ensure spelling is correct
Context: ...emplate> <style> </style> ``` ::: ## Input参数 | 参数 | 类型 | ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (3)
packages/theme/themes/light.ts (1)

109-109: Token changes align with new Input sizing

Increasing 'border-radius' to 4px and adding 'size-sm' | 'size-md' | 'size-lg' tokens is consistent with the new Input SCSS usage and gives a cleaner, more modern look. Just be aware this is a global visual change for any component consuming these tokens.

Also applies to: 136-139

packages/docs/.vitepress/theme/styles/index.css (1)

10-24: Spacing utilities are simple and consistent

The .mt-10/.mb-10/.ml-10/.mr-10 helpers are straightforward and already used in the Input docs examples. Looks good.

packages/ccui/ui/input/src/input-types.ts (1)

3-49: Input prop typing is clear and matches usage

InputType, InputSize, and inputProps line up with both the tests and the docs (once event naming is fixed). Defaults (type: 'text', size: 'default', string props defaulting to '') are reasonable for a base input.

Comment on lines +37 to +89
&--large {
height: $ccui-size-lg;
font-size: $ccui-font-size-lg;

&.#{$cls-prefix}-input--prefix {
.#{$cls-prefix}-input__inner {
padding-left: 24px;
}
}

&.#{$cls-prefix}-input--suffix,
&.#{$cls-prefix}-input--clearable {
.#{$cls-prefix}-input__inner {
padding-right: 24px;
}
}
}

&--default {
height: $ccui-size-md;
font-size: $ccui-font-size-md;

&.#{$cls-prefix}-input--prefix {
.#{$cls-prefix}-input__inner {
padding-left: 24px;
}
}

&.#{$cls-prefix}-input--suffix,
&.#{$cls-prefix}-input--clearable {
.#{$cls-prefix}-input__inner {
padding-right: 24px;
}
}
}

&--small {
height: $ccui-size-sm;
font-size: $ccui-font-size-sm;

&.#{$cls-prefix}-input--prefix {
.#{$cls-prefix}-input__inner {
padding-left: 20px;
}
}

&.#{$cls-prefix}-input--suffix,
&.#{$cls-prefix}-input--clearable {
.#{$cls-prefix}-input__inner {
padding-right: 20px;
}
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Size‑based padding rules expect block modifiers, not element modifiers

The selectors like:

&--large {
  ...
  &.#{$cls-prefix}-input--prefix { ... }
  &.#{$cls-prefix}-input--suffix,
  &.#{$cls-prefix}-input--clearable { ... }
}

compile to .ccui-input--large.ccui-input--prefix .ccui-input__inner { ... } etc., i.e. they assume --prefix/--suffix/--clearable are applied on the block element.

Currently, in input.tsx these modifiers are added to the input element via inputClass, not to the block container, so these padding rules won’t ever match. After you fix the TSX to put these modifiers on the block (see comment in input.tsx), these SCSS rules will start working as intended.

  API(modelValue/update:modelValue),并相应地更新了测试和文档,使其完全一致
Copy link

@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: 0

🧹 Nitpick comments (1)
packages/ccui/ui/input/test/input.test.ts (1)

93-204: Consider adding a few edge‑case tests for events and suffix behavior

The event and interaction tests (input/change/focus/blur, clear, password toggle) are comprehensive. As a next step, you might consider:

  • Verifying update:modelValue via wrapper.emitted() or v-model binding.
  • Asserting that clear/password icons are not rendered (or are non‑interactive) when disabled/readonly is true but clearable/showPassword is enabled.
    These would lock in the newer disabled/readonly semantics and v-model contract.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 035ce68 and 78af026.

📒 Files selected for processing (4)
  • packages/ccui/ui/input/src/input-types.ts (1 hunks)
  • packages/ccui/ui/input/src/input.tsx (1 hunks)
  • packages/ccui/ui/input/test/input.test.ts (1 hunks)
  • packages/docs/components/input/index.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ccui/ui/input/src/input-types.ts
🧰 Additional context used
🧬 Code graph analysis (2)
packages/ccui/ui/input/test/input.test.ts (2)
packages/ccui/ui/shared/hooks/use-namespace.ts (1)
  • useNamespace (31-47)
packages/ccui/ui/input/src/input-types.ts (1)
  • InputSize (4-4)
packages/ccui/ui/input/src/input.tsx (2)
packages/ccui/ui/input/src/input-types.ts (2)
  • inputProps (6-47)
  • InputProps (49-49)
packages/ccui/ui/shared/hooks/use-namespace.ts (1)
  • useNamespace (31-47)
🪛 LanguageTool
packages/docs/components/input/index.md

[grammar] ~227-~227: Ensure spelling is correct
Context: ...emplate> <style> </style> ``` ::: ## Input参数 | 参数 | 类型 | ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🔇 Additional comments (4)
packages/ccui/ui/input/test/input.test.ts (1)

1-91: Core rendering and prop behavior tests look solid

The basic presence, type switching, size, placeholder, disabled/readonly, clearable, and prepend/append tests closely track the component API and BEM helpers; I don’t see functional issues here.

packages/ccui/ui/input/src/input.tsx (2)

7-43: Props, v-model wiring, and BEM class structure are consistent

Using inputProps + InputProps, update:modelValue + input emissions, and the getBaseClass / getWrapperClass / inputClass computations lines up well with the documented API and SCSS BEM structure. Block‑level modifiers for size/disabled/readonly/clearable/prefix/suffix are now correctly applied on the outer container while the inner input sticks to element + state classes, which should keep both styles and tests happy.

Also applies to: 45-58


87-101: Clear / password toggle / suffix rendering logic behaves correctly

clearInput and togglePasswordVisible cooperate with currentType and showPasswordVisible as expected, and renderSuffixIcons correctly:

  • Disables clear/password toggle when disabled or readonly is true.
  • Still renders the suffix slot when provided.
    Combined with getInputAttrs and the final render tree, this gives the right DOM and behavior for clearable/password inputs without leaking interactivity into disabled/readonly states.

Also applies to: 124-147, 149-167, 177-202

packages/docs/components/input/index.md (1)

15-37: Docs now match the actual Input API (v-model, props, events, slots)

The demos’ v-model usage, the props table (modelValue, show-password, clearable, sizes), the event table (update:modelValue, input/change/focus/blur/clear), and the slots list (prepend/append/prefix/suffix) are all aligned with the current component implementation and tests. This should make the docs reliably executable for consumers.

Also applies to: 29-33, 63-69, 139-191, 227-266

@vaebe vaebe merged commit 07cd26c into main Nov 18, 2025
4 checks passed
@vaebe vaebe deleted the feat-input branch November 18, 2025 05:51
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.

2 participants