[BpkChatbotInput]Bpk component chatbox input#4279
[BpkChatbotInput]Bpk component chatbox input#4279GC Zhu (gc-skyscanner) merged 31 commits intomainfrom
Conversation
…operty (#4265) * add Claude SDD spec for BpkButton * add notes for the definition of themeable * Make corner radius configurable via bpk-themeable * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update specs/001-bpkbutton-baseline/spec.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * solve comment * [CLOV-1327] Address Copilot review comments - Fix Object.keys → Object.values in BpkButton-test.tsx forEach loop so tests iterate over kebab-case type values (e.g. primary-on-dark) that match actual BEM class names, not camelCase keys - Remove unused ButtonType import (no longer needed after removing cast) - Update plan.md: replace "snapshot regeneration" with accurate description of explicit assertion approach; expand Files changed list to include test, snapshot deletion, and spec documentation artefacts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * remove the BpkButton spec * add storybook example for the themed boder radius for BpkButton * imporve BpkButton unit test --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Bumps the artifacts-actions group with 1 update: [actions/download-artifact](https://github.com/actions/download-artifact). Updates `actions/download-artifact` from 7.0.0 to 8.0.0 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@37930b1...70fc10c) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: artifacts-actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new bpk-component-chatbot-input package to Backpack, providing a chat-style input with a default single-line mode and a composer (textarea) mode, plus supporting hooks, styling, tests, and Storybook examples.
Changes:
- Introduces
BpkChatbotInputwith default + composer modes and a send button/loading state. - Adds supporting hooks (
useChatbotInput,useChatbotInputManager,useTextAreaAutoResize,useInputHandlers) and component subparts (InputField,TextAreaField,SendButton). - Adds unit tests, accessibility tests, snapshots, and Storybook examples for the new component.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/bpk-component-chatbot-input/src/types.ts | Defines shared prop types for input field variants. |
| packages/bpk-component-chatbot-input/src/hooks/useTextAreaAutoResize.ts | Implements textarea measurement + auto-resize logic. |
| packages/bpk-component-chatbot-input/src/hooks/useTextAreaAutoResize-test.tsx | Tests textarea auto-resize behavior and scrolling behavior. |
| packages/bpk-component-chatbot-input/src/hooks/useInputHandlers.ts | Centralizes click/touch/change handlers for input controls. |
| packages/bpk-component-chatbot-input/src/hooks/useInputHandlers-test.tsx | Tests handler behavior for click/touch/change. |
| packages/bpk-component-chatbot-input/src/hooks/useChatbotInputManager.ts | Adds state management for chatbot input value and submit/autoclear behavior. |
| packages/bpk-component-chatbot-input/src/hooks/useChatbotInputManager-test.tsx | Tests input manager state transitions and submission logic. |
| packages/bpk-component-chatbot-input/src/hooks/useChatbotInput.ts | Provides UI state (focused/disabled/overlimit/etc) and input props for the component. |
| packages/bpk-component-chatbot-input/src/hooks/useChatbotInput-test.tsx | Tests derived state and key-handling behavior for the hook. |
| packages/bpk-component-chatbot-input/src/hooks/index.ts | Barrel exports for hooks used by the component. |
| packages/bpk-component-chatbot-input/src/constants.ts | Declares input type constants and default max character limit. |
| packages/bpk-component-chatbot-input/src/accessibility-test.tsx | Adds jest-axe coverage for default/composer/loading renders. |
| packages/bpk-component-chatbot-input/src/snapshots/BpkChatbotInput-test.tsx.snap | Stores render snapshots for default and composer variants. |
| packages/bpk-component-chatbot-input/src/TextAreaField/TextAreaField.tsx | Implements the composer textarea UI. |
| packages/bpk-component-chatbot-input/src/TextAreaField/TextAreaField.module.scss | Styles for composer textarea container/field. |
| packages/bpk-component-chatbot-input/src/TextAreaField/TextAreaField-test.tsx | Tests textarea field rendering, events, and axe checks. |
| packages/bpk-component-chatbot-input/src/SendButton/SendButton.tsx | Adds send button with icon + loading state behavior. |
| packages/bpk-component-chatbot-input/src/SendButton/SendButton-test.tsx | Tests send button render/click/disabled + axe. |
| packages/bpk-component-chatbot-input/src/LoadingButton/LoadingButton.tsx | Adds a loading button implementation (currently not referenced). |
| packages/bpk-component-chatbot-input/src/LoadingButton/LoadingButton.module.scss | Styles for the loading button. |
| packages/bpk-component-chatbot-input/src/InputField/InputField.tsx | Implements default single-line input UI. |
| packages/bpk-component-chatbot-input/src/InputField/InputField.module.scss | Styles for the single-line input field. |
| packages/bpk-component-chatbot-input/src/InputField/InputField-test.tsx | Tests input field rendering, events, and axe checks. |
| packages/bpk-component-chatbot-input/src/BpkChatbotInput.tsx | Main component wiring modes, hooks, and send button. |
| packages/bpk-component-chatbot-input/src/BpkChatbotInput.module.scss | Styles for default/composer container variants. |
| packages/bpk-component-chatbot-input/src/BpkChatbotInput-test.tsx | Component tests for variants, loading, and keyboard interactions. |
| packages/bpk-component-chatbot-input/index.ts | Public entrypoint exports for the new package. |
| packages/bpk-component-chatbot-input/README.md | Package documentation and usage instructions. |
| examples/bpk-component-chatbot-input/stories.tsx | Storybook story registration for the new component. |
| examples/bpk-component-chatbot-input/examples.tsx | Interactive examples for default/composer/loading states. |
| examples/bpk-component-chatbot-input/examples.module.scss | Example layout styling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| export const LINE_HEIGHT = 24; | ||
| export const MIN_INPUT_HEIGHT = LINE_HEIGHT; | ||
| export const MAX_INPUT_HEIGHT_PHASE_1 = LINE_HEIGHT * 4; | ||
| export const MAX_INPUT_HEIGHT_PHASE_2 = LINE_HEIGHT * 5; | ||
| export const MIN_CONTAINER_HEIGHT = 24; | ||
| export const MAX_CONTAINER_HEIGHT = 96; | ||
| export const PARENT_PADDING_TOP = 16; |
There was a problem hiding this comment.
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
| const measureElementRef = useRef<HTMLTextAreaElement | null>(null); | ||
| const previousValueRef = useRef<string>(''); | ||
| const shouldScrollRef = useRef<boolean>(false); | ||
| const isInitialRenderRef = useRef<boolean>(true); |
There was a problem hiding this comment.
Why useRef for all four?(same implementation with carhire's)
All four values share one thing in common: changes to them don't need to trigger a UI re-render.
| ref | reason |
|---|---|
| measureElementRef | Stores a DOM node — the classic use case for useRef |
| previousValueRef | A pure computation helper, only read/written inside effects, never affects render output |
| shouldScrollRef | A cross-effect signal flag — using useState would cause unnecessary re-renders or even an infinite loop |
| isInitialRenderRef | A one-time flag that flips once over the component's lifetime, has no impact on any UI |
Of the values in this hook, only dimensions uses useState — because those values are applied directly as inline styles and must trigger a re-render to take effect visually.
7090976 to
0ce94e4
Compare
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
| if (e.key === 'Enter') { | ||
| if (!isMultiLine) { | ||
| e.preventDefault(); | ||
| e.stopPropagation(); |
There was a problem hiding this comment.
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
| position: relative; | ||
| transition: | ||
| transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), | ||
| box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1); |
There was a problem hiding this comment.
Nit: Why composer variant use hard code ,but cars variant use box-shadow tokens.$bpk-duration-sm ease;
There was a problem hiding this comment.
similar here:
keep it same as carhires'
#4279 (comment)
| ); | ||
| ``` | ||
|
|
||
| ## Props |
There was a problem hiding this comment.
As Storybook already shows the props, we don’t need to document the props again in the README.
|
Visit https://backpack.github.io/storybook-prs/4279 to see this build running in a browser. |
|
Cars empty. There seems blue border |







Summary
Migrate BpkChatbotInput from carhire-homepage into Backpack and promote it as an official component.
Differences with carhire-hompage(the original implementation)
Input type API
DEFAULT→CARS,COMPOSOR→CARS_COMPOSER, added variantCOMPOSERCOMPOSERis the defaultinputTypeinputPlaceholder→placeholderInput types
CHATBOT_INPUT_TYPES.CARSuses a single-line<input>with a featured send button.CHATBOT_INPUT_TYPES.COMPOSERandCHATBOT_INPUT_TYPES.CARS_COMPOSERboth use a multi-line<textarea>with a primary send button, but differ in the following ways:COMPOSERCARS_COMPOSER$bpk-text-primary-day$bpk-text-secondary-dayTheming
BpkThemeProvidersupport viachatbotInputBorderRadiusandchatbotInputFocusBorderColorSCSS improvements
:hoverwith@include utils.bpk-hover(respects.bpk-no-touch-support)0.2stransition duration withtokens.$bpk-duration-smInternal refactoring
useChatbotInput,useChatbotInputManager,useInputHandlers,useTextAreaAutoResizeuseId()for accessible label/input ID pairingBug fixes
isPollingstate now correctly blocks submissionEscapecan now close a parent modal)Screenshots
composer
cars
cars-composer
Remember to include the following changes:
[Clover-123][BpkButton] Updating the colourREADME.md(If you have created a new component)README.md