Skip to content

feat(ChatInput): add feedback, an attached rating prompt on the composer - #3886

Open
annamalailakshmann wants to merge 7 commits into
feat/chat-feedbackfrom
feat/chat-input-attached-feedback
Open

feat(ChatInput): add feedback, an attached rating prompt on the composer#3886
annamalailakshmann wants to merge 7 commits into
feat/chat-feedbackfrom
feat/chat-input-attached-feedback

Conversation

@annamalailakshmann

@annamalailakshmann annamalailakshmann commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Description

One new prop on the existing component:

<ChatInput
  placeholder="Ask anything..."
  feedback={{ question: "How's this going?", moodIcons, onSubmit, onDismiss }}
/>

Pass it and a ChatFeedback prompt attaches to the composer's top edge, the two sharing one tinted surface so they read as a single object. Omit it and the composer renders exactly as it does today — verified: the flag-off snapshot contains no frame CSS at all, because those properties are only emitted when the prop is present.

The composer takeover

Picking the prompt's free-text tag (feedback.freeTextTag, default 'Other') hands the composer over: placeholder swaps, a dismissable Feedback tag replaces the upload link, focus moves to the field, and Enter submits the comment.

Chat draft stashed on entry, restored on exit
Enter submits the feedback. The chat path is blocked, not redirected
The strip's tick hidden — the composer's send arrow is the submit
Exits Esc · the tag's ✕ · submitting · deselecting the tag · the prompt going away

Every exit also releases the tag. Leaving it selected strands the user: the tick stays hidden because the only tag picked is the free-text one, and the composer has gone back to chatting — a choice made with no way left to send it.

Enter is blocked rather than rerouted because sending someone's candid feedback to the assistant as a prompt is not a recoverable mistake.

Why the prompt lives inside ChatInput

The obvious composition — render ChatFeedback above a ChatInput — is silently broken. The composer keeps its validation region mounted directly above the card even with no error, and it swallows clicks aimed at anything stacked there (fixed in #3883). Owning the prompt here means the layer it sits on is decided in the same file as the layer the error region sits on.

Changes

  • feedback prop + ChatInputFeedbackProps; ChatInputFeedback owns surface, spacing, layering and entry/exit
  • leadingSlot on the action bar, for the mode indicator
  • The surface now dissolves rather than dropping: background and padding transition on the same beat as the prompt's fade, so the composer no longer jumps up by the padding as the confirmation leaves
  • Native throws a dev error, matching how accept is handled
  • KitchenSink story, docs stories, unit tests, interaction tests

On the tests

The important interaction test asserts by hit-testing, not clicking:

expect(button.contains(document.elementFromPoint(x, y))).toBe(true); ```

`userEvent.click` dispatches at an element regardless of what covers it, so a click-based test would have passed against the very bug this guards.

The takeover's unit tests pin the two failure modes that are silent when wrong: the chat draft surviving a round trip, and `onSubmit` **never** firing while feedback is being collected.

## Additional Information

Last of a stack of four; based on #3885.

Container values (20px radius, 8px padding, 4px gap, `surface.background.primary.subtle`, no border) come from the design frame. The design specifies 6px padding, which is not on Blade's spacing scale — it steps 4 to 8 — so this rounds up rather than inventing an off-scale value. Flagging for a designer's call.

## Component Checklist

- [x] Update Component Status Page
- [ ] Perform Manual Testing in Other Browsers
- [x] Add KitchenSink Story
- [x] Add Interaction Tests (if applicable)
- [x] Add changeset

🤖 Generated with [Claude Code](https://claude.com/claude-code)

@changeset-bot

changeset-bot Bot commented Aug 14, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ad7a421

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@razorpay/blade Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added react-native blade Changes to packages/blade labels Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash PR Healer has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@annamalailakshmann
annamalailakshmann force-pushed the feat/chat-input-attached-feedback branch from 19d1943 to 26dfd90 Compare August 14, 2026 18:23
@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@rzpcibot

rzpcibot commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

🛡️ Coverage Report

Summary


=============================== Coverage summary ===============================
Statements   : 82.62% ( 11428/13832 )
Branches     : 68.92% ( 7159/10387 )
Functions    : 82.01% ( 2617/3191 )
Lines        : 83.57% ( 11121/13306 )
================================================================================
Full Coverage Details
---------------------------------------|---------|----------|---------|---------|-------------------
File                                   | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------------------------------|---------|----------|---------|---------|-------------------
All files                              |   82.62 |    68.92 |   82.01 |   83.57 |                   
 blade                                 |     100 |      100 |     100 |     100 |                   
  jestStyledComponentsSerializer.js    |     100 |      100 |     100 |     100 |                   
 ...odemods/brand-refresh/transformers |    89.1 |     89.6 |   98.85 |   88.99 |                   
  index.ts                             |   88.23 |    84.37 |     100 |   88.23 | ...15,144,179,215 
  migrate-actionlist-and-table.ts      |      75 |      100 |     100 |      75 | 23                
  migrate-amount.ts                    |   86.48 |       75 |     100 |   86.48 | 27-31,101,133,164 
  migrate-badge.ts                     |      75 |      100 |     100 |      75 | 21                
  migrate-card.ts                      |    87.5 |      100 |     100 |    87.5 | 36                
  ...te-contrast-intent-color-props.ts |   89.83 |      100 |     100 |   89.65 | ...28,153,245,291 
  migrate-divider.ts                   |   83.33 |      100 |     100 |   83.33 | 31                
  migrate-dropdown.ts                  |   91.66 |      100 |     100 |   91.66 | 72                
  migrate-typography.ts                |    90.9 |    88.13 |   96.96 |   90.82 | ...34,245,325,355 
  utils.ts                             |     100 |      100 |     100 |     100 |                   
 ...migrate-motion-tokens/transformers |    87.5 |       50 |     100 |    87.5 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  migrate-motion.ts                    |    87.5 |       50 |     100 |    87.5 | 18                
 ...s/migrate-progressbar/transformers |   78.26 |       75 |     100 |   78.26 |                   
  index.ts                             |   78.26 |       75 |     100 |   78.26 | 9,39,64-68,78     
 blade/src/components/Accordion        |    87.5 |    69.29 |   95.83 |   89.83 |                   
  Accordion.tsx                        |     100 |      100 |     100 |     100 |                   
  AccordionButton.web.tsx              |   93.33 |    68.75 |     100 |    92.3 | 41                
  AccordionContext.tsx                 |   85.71 |       50 |     100 |   85.71 | 29,42             
  AccordionItem.tsx                    |   88.23 |       88 |     100 |   88.23 | 98,112            
  AccordionItemBody.tsx                |     100 |    58.33 |     100 |     100 | 58-61             
  AccordionItemHeader.tsx              |      68 |    45.45 |      75 |   80.95 | 21-22,63,70       
  AccordionSurface.web.tsx             |     100 |      100 |     100 |     100 |                   
  StyledAccordionButton.web.tsx        |   82.35 |    77.77 |     100 |   81.25 | 24-30             
  commonStyles.ts                      |     100 |      100 |     100 |     100 |                   
  componentIds.ts                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  styles.web.ts                        |     100 |      100 |     100 |     100 |                   
 blade/src/components/ActionList       |   70.41 |    53.47 |   69.35 |   70.56 |                   
  ActionList.tsx                       |     100 |      100 |     100 |     100 |                   
  ActionListBox.web.tsx                |   67.08 |    40.47 |   73.68 |   67.08 | ...00,243,318-326 
  ActionListItem.tsx                   |   67.12 |    47.54 |      55 |   68.05 | ...19,361,392,414 
  ActionListItemAsset.web.tsx          |     100 |      100 |     100 |     100 |                   
  ActionListNoResults.tsx              |     100 |      100 |     100 |     100 |                   
  actionListUtils.ts                   |   63.63 |    50.94 |   69.23 |   63.07 | ...09,223,240,247 
  componentIds.ts                      |     100 |      100 |     100 |     100 |                   
  getA11yRoles.ts                      |   82.14 |    80.95 |      80 |   82.14 | 33,48-52,81       
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/ActionList/styles |     100 |      100 |     100 |     100 |                   
  StyledListBoxWrapper.web.tsx         |     100 |      100 |     100 |     100 |                   
  getBaseListBoxWrapperStyles.ts       |     100 |      100 |     100 |     100 |                   
 blade/src/components/Alert            |   80.55 |    75.96 |     100 |      80 |                   
  Alert.tsx                            |   77.04 |     73.5 |     100 |   76.27 | ...91,264-266,305 
  StyledAlert.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  styles.ts                            |     100 |      100 |     100 |     100 |                   
 blade/src/components/Amount           |    87.8 |    70.43 |   81.81 |    88.6 |                   
  Amount.tsx                           |   87.17 |    70.43 |   81.81 |      88 | ...16,350,416-417 
  amountTokens.ts                      |     100 |      100 |     100 |     100 |                   
  index.tsx                            |       0 |        0 |       0 |       0 |                   
 ...src/components/AnimateInteractions |   76.92 |    28.57 |   55.55 |      80 |                   
  AnimateInteractions.web.tsx          |   71.42 |      100 |   33.33 |   71.42 | 43-46             
  AnimateInteractionsProvider.tsx      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useFocusWithin.web.ts                |   73.33 |    16.66 |      60 |   78.57 | 17,22-23          
 .../src/components/AnnouncementBanner |     100 |      100 |     100 |     100 |                   
  AnnouncementBanner.tsx               |     100 |      100 |     100 |     100 |                   
  StyledAnnouncementBanner.tsx         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  styles.ts                            |     100 |      100 |     100 |     100 |                   
 blade/src/components/AppBar           |   97.22 |     86.2 |     100 |   97.22 |                   
  AppBar.web.tsx                       |   96.15 |     86.2 |     100 |   96.15 | 253               
  AppBarContext.tsx                    |     100 |      100 |     100 |     100 |                   
  appBarTokens.ts                      |     100 |      100 |     100 |     100 |                   
 blade/src/components/Avatar           |   94.44 |    80.61 |    90.9 |   94.44 |                   
  Avatar.web.tsx                       |   95.83 |    76.31 |     100 |   95.83 | 74                
  AvatarButton.tsx                     |     100 |    88.88 |     100 |     100 | 19-21             
  AvatarGroup.web.tsx                  |   93.33 |    81.25 |     100 |   93.33 | 43                
  AvatarGroupContext.tsx               |     100 |      100 |     100 |     100 |                   
  StyledAvatar.tsx                     |     100 |      100 |     100 |     100 |                   
  StyledAvatarButton.tsx               |     100 |    69.23 |     100 |     100 | 11-13,25          
  StyledAvatarGroup.tsx                |     100 |      100 |     100 |     100 |                   
  TrustedBadgeIcon.web.tsx             |   33.33 |      100 |       0 |   33.33 | 6-7               
  avatarTokens.ts                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Badge            |     100 |     91.3 |     100 |     100 |                   
  Badge.tsx                            |     100 |     91.3 |     100 |     100 | 112,152           
  StyledBadge.web.tsx                  |     100 |      100 |     100 |     100 |                   
  badgeTokens.ts                       |     100 |      100 |     100 |     100 |                   
  getStyledBadgeStyles.ts              |     100 |      100 |     100 |     100 |                   
  index.tsx                            |       0 |        0 |       0 |       0 |                   
 blade/src/components/BaseHeaderFooter |   94.11 |    79.31 |      90 |   94.11 |                   
  BaseFooter.tsx                       |     100 |    85.71 |     100 |     100 | 34                
  BaseHeader.tsx                       |   93.75 |    78.75 |   88.88 |   93.75 | 340,383,421       
 blade/src/components/BaseMenu         |     100 |      100 |     100 |     100 |                   
  BaseMenuContext.ts                   |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
 ...c/components/BaseMenu/BaseMenuItem |     100 |    85.18 |     100 |     100 |                   
  BaseMenuItem.tsx                     |     100 |    84.21 |     100 |     100 | 69,109,121        
  StyledMenuItemContainer.web.tsx      |     100 |      100 |     100 |     100 |                   
  getBaseMenuItemStyles.ts             |     100 |       50 |     100 |     100 | 11                
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
 blade/src/components/BaseMotion       |   97.43 |    94.28 |     100 |   97.43 |                   
  BaseMotion.web.tsx                   |     100 |    95.65 |     100 |     100 | 101               
  baseMotionUtils.ts                   |   94.44 |    91.66 |     100 |   94.44 | 33                
  index.ts                             |       0 |        0 |       0 |       0 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/BladeProvider    |   91.17 |       75 |   83.33 |    90.9 |                   
  BladeProvider.web.tsx                |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  stylisCSSHigherSpecificity.ts        |     100 |      100 |     100 |     100 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
  useBladeProvider.ts                  |     100 |     87.5 |     100 |     100 | 32                
  useTheme.ts                          |      70 |       50 |      50 |      70 | 21,28,34          
 blade/src/components/BottomNav        |   94.44 |    78.26 |     100 |   94.44 |                   
  BottomNav.web.tsx                    |   94.44 |    78.26 |     100 |   94.44 | 76                
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/BottomSheet      |   83.33 |    75.43 |   79.72 |   83.62 |                   
  BottomSheet.web.tsx                  |   81.21 |    68.04 |   89.65 |   81.25 | ...76-382,389-396 
  BottomSheetBackdrop.web.tsx          |     100 |      100 |     100 |     100 |                   
  BottomSheetBody.web.tsx              |   94.73 |    93.75 |     100 |     100 | 35                
  BottomSheetCommon.tsx                |    87.5 |    83.33 |     100 |    87.5 | 59                
  BottomSheetContext.ts                |     100 |      100 |      25 |     100 |                   
  BottomSheetFooter.web.tsx            |     100 |      100 |     100 |     100 |                   
  BottomSheetGrabHandle.web.tsx        |     100 |      100 |     100 |     100 |                   
  BottomSheetHeader.web.tsx            |   93.33 |    94.73 |     100 |     100 | 38                
  BottomSheetStack.tsx                 |   92.85 |      100 |   71.42 |   91.66 | 17-19             
  componentIds.ts                      |     100 |      100 |     100 |     100 |                   
  getBottomSheetGrabHandleStyles.ts    |     100 |       75 |     100 |     100 | 38                
  index.ts                             |       0 |        0 |       0 |       0 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
  utils.ts                             |   16.66 |    14.28 |      50 |   16.66 | 11-25             
 blade/src/components/Box              |   96.42 |    78.57 |     100 |   96.42 |                   
  Box.tsx                              |   96.42 |    78.57 |     100 |   96.42 | 239               
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Box/BaseBox      |   94.38 |    94.31 |     100 |   94.31 |                   
  BaseBox.web.tsx                      |     100 |      100 |     100 |     100 |                   
  baseBoxStyles.ts                     |    98.3 |    96.96 |     100 |   98.27 | 308               
  getResponsiveValue.web.ts            |      90 |    92.85 |     100 |      90 | 67                
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useMemoizedStyles.web.ts             |      80 |        0 |     100 |      80 | 22-30             
 ...e/src/components/Box/BaseBox/types |     100 |      100 |     100 |     100 |                   
  propsTypes.ts                        |     100 |      100 |     100 |     100 |                   
 blade/src/components/Box/styledProps  |     100 |      100 |     100 |     100 |                   
  getStyledProps.ts                    |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useStyledProps.ts                    |     100 |      100 |     100 |     100 |                   
 blade/src/components/Breadcrumb       |     100 |       72 |     100 |     100 |                   
  Breadcrumb.web.tsx                   |     100 |     92.3 |     100 |     100 | 20                
  BreadcrumbContext.tsx                |     100 |      100 |     100 |     100 |                   
  BreadcrumbItem.web.tsx               |     100 |       50 |     100 |     100 | 25-53             
  index.ts                             |       0 |        0 |       0 |       0 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Button           |       0 |        0 |       0 |       0 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Button/BaseButton |   75.77 |       69 |   84.84 |   77.17 |                   
  AnimatedButtonContent.web.tsx        |     100 |      100 |     100 |     100 |                   
  BaseButton.tsx                       |   71.85 |    67.07 |      80 |   73.24 | ...26-532,719-724 
  StyledBaseButton.web.tsx             |     100 |    76.47 |     100 |     100 | 25,45-56,70       
  buttonTokens.ts                      |     100 |      100 |     100 |     100 |                   
  getStyledBaseButtonStyles.ts         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Button/Button    |     100 |      100 |     100 |     100 |                   
  Button.tsx                           |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Button/IconButton |    91.3 |    70.73 |     100 |    91.3 |                   
  IconButton.tsx                       |     100 |      100 |     100 |     100 |                   
  StyledIconButton.web.tsx             |    87.5 |    69.23 |     100 |    87.5 | 41-45             
  index.ts                             |       0 |        0 |       0 |       0 |                   
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
 blade/src/components/ButtonGroup      |   88.46 |       72 |     100 |   88.46 |                   
  ButtonGroup.web.tsx                  |   81.25 |    66.66 |     100 |   81.25 | 31-39             
  ButtonGroupContext.tsx               |     100 |      100 |     100 |     100 |                   
  StyledButtonGroup.web.tsx            |     100 |       80 |     100 |     100 | 8                 
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Card             |   59.58 |    41.44 |   44.44 |   61.47 |                   
  Card.tsx                             |   92.59 |    80.85 |     100 |     100 | 278-288,324-337   
  CardContext.tsx                      |     100 |       75 |     100 |     100 | 9                 
  CardFooter.tsx                       |     100 |    63.82 |     100 |     100 | ...49-158,172-174 
  CardHeader.tsx                       |   82.97 |       80 |      60 |   82.97 | ...72,79-81,95-97 
  CardInfoSurface.tsx                  |      25 |        0 |       0 |      25 | 35-38             
  CardRoot.web.tsx                     |   81.81 |    77.27 |   71.42 |   89.47 | 96-97             
  CardSurface.web.tsx                  |     100 |    33.33 |     100 |     100 | 14-20             
  CardTicketSurface.web.tsx            |   14.58 |        0 |       0 |   15.21 | ...,84-86,125-181 
  InfoCard.tsx                         |      50 |        0 |       0 |      50 | 59-90             
  LinkOverlay.web.tsx                  |     100 |      100 |     100 |     100 |                   
  TicketCard.tsx                       |      50 |        0 |       0 |      50 | 59-90             
  constants.ts                         |     100 |      100 |     100 |     100 |                   
  createSectionedCardSlot.tsx          |      75 |      100 |      50 |      75 | 18                
  index.ts                             |       0 |        0 |       0 |       0 |                   
  sectionedCardConstants.ts            |     100 |      100 |     100 |     100 |                   
  splitSectionedCardChildren.ts        |    7.14 |        0 |       0 |    7.14 | 23-50             
  useSectionedCardState.ts             |    5.55 |        0 |       0 |    6.25 | 43-71             
 blade/src/components/Carousel         |    71.5 |    64.74 |   61.11 |   74.13 |                   
  Carousel.web.tsx                     |    67.7 |    66.15 |   56.25 |   70.46 | ...75,489,545-565 
  CarouselContext.tsx                  |   83.33 |       50 |     100 |   83.33 | 30                
  CarouselItem.web.tsx                 |     100 |    58.33 |     100 |     100 | 44-53,76-77       
  constants.ts                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
  utils.ts                             |     100 |      100 |     100 |     100 |                   
 ...src/components/Carousel/Indicators |   74.35 |     40.9 |   55.55 |   76.31 |                   
  CircularIndicatorButton.web.tsx      |   57.89 |        0 |       0 |   61.11 | 29,64-76          
  IndicatorButton.tsx                  |     100 |      100 |     100 |     100 |                   
  Indicators.web.tsx                   |   81.81 |       50 |   66.66 |   81.81 | 26,40             
  StyledIndicatorButton.web.tsx        |     100 |      100 |     100 |     100 |                   
  getIndicatorButtonStyles.ts          |     100 |     87.5 |     100 |     100 | 32                
 ...mponents/Carousel/NavigationButton |   80.76 |    55.55 |      80 |   80.76 |                   
  NavigationButton.tsx                 |   61.53 |       60 |   66.66 |   61.53 | 23-28,34-37       
  StyledNavigationButton.web.tsx       |     100 |      100 |     100 |     100 |                   
  getNavigationButtonStyles.ts         |     100 |       50 |     100 |     100 | 11-70             
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Charts           |       0 |        0 |       0 |       0 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Charts/AreaChart |   91.66 |    71.13 |      90 |   95.76 |                   
  AreaChart.web.tsx                    |    91.6 |    71.13 |      90 |   95.72 | 219-223,317       
  componentIds.ts                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Charts/BarChart  |   89.39 |    64.44 |   78.57 |   89.06 |                   
  BarChart.web.tsx                     |    87.5 |    64.44 |   76.92 |   87.27 | ...49-253,288-291 
  BarChartContext.ts                   |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
 ...nents/Charts/CommonChartComponents |   74.45 |    61.72 |   82.22 |   74.42 |                   
  CommonChartComponents.web.tsx        |      80 |    64.18 |   85.36 |      80 | ...94-810,839-840 
  CommonChartComponentsContext.tsx     |      60 |      100 |   33.33 |      60 | 6-9               
  index.ts                             |       0 |        0 |       0 |       0 |                   
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
  utils.ts                             |   36.11 |    35.71 |     100 |   35.29 | 45-82             
 ...e/src/components/Charts/DonutChart |   79.88 |    66.38 |   77.77 |    82.2 |                   
  DonutChart.web.tsx                   |   79.04 |    66.38 |   77.77 |   81.41 | ...75,513,562-565 
  index.ts                             |       0 |        0 |       0 |       0 |                   
  tokens.tsx                           |     100 |      100 |     100 |     100 |                   
 blade/src/components/Charts/LineChart |   87.42 |    71.92 |   77.27 |   90.71 |                   
  LineChart.web.tsx                    |   87.66 |    71.92 |   78.57 |   91.17 | ...41,421-425,457 
  LineChartContext.tsx                 |      75 |      100 |      50 |   66.66 | 10                
  componentIds.ts                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../src/components/Charts/SankeyChart |   91.16 |    72.51 |   97.72 |   92.02 |                   
  SankeyChart.web.tsx                  |    92.1 |     72.8 |   97.67 |   93.25 | ...21,505-507,735 
  humanizeIndian.ts                    |   63.63 |    66.66 |     100 |   63.63 | 5-6,9-10          
  index.ts                             |       0 |        0 |       0 |       0 |                   
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
 blade/src/components/Charts/utils     |   87.31 |    73.84 |     100 |   88.52 |                   
  getHighestColorInRange.ts            |   73.33 |    66.66 |     100 |   73.33 | 22-23,50-53       
  index.tsx                            |       0 |        0 |       0 |       0 |                   
  isSequentialColor.tsx                |      50 |       50 |     100 |      50 | 25-31             
  nullBridgeUtils.ts                   |    91.3 |     73.8 |     100 |   93.75 | 45-48,75          
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
  useColorTheme.tsx                    |   93.75 |    83.33 |     100 |   93.75 | 47                
 ...harts/utils/assignDataColorMapping |     100 |      100 |     100 |     100 |                   
  assignDataColorMapping.ts            |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...onents/Charts/utils/sanitizeString |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  sanitizeString.ts                    |     100 |      100 |     100 |     100 |                   
 blade/src/components/ChatFeedback     |   99.09 |    81.63 |     100 |     100 |                   
  ChatFeedback.web.tsx                 |     100 |       80 |     100 |     100 | ...12-249,308-320 
  ChatFeedbackCheck.web.tsx            |     100 |      100 |     100 |     100 |                   
  ChatFeedbackMoodScale.web.tsx        |     100 |      100 |     100 |     100 |                   
  chatFeedbackTokens.ts                |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useChatFeedback.ts                   |   97.77 |    81.81 |     100 |     100 | 24,103            
 .../components/ChatFeedback/moodIcons |     100 |      100 |     100 |     100 |                   
  BadIcon.tsx                          |     100 |      100 |     100 |     100 |                   
  GoodIcon.tsx                         |     100 |      100 |     100 |     100 |                   
  LoveItIcon.tsx                       |     100 |      100 |     100 |     100 |                   
  TerribleIcon.tsx                     |     100 |      100 |     100 |     100 |                   
  index.tsx                            |     100 |      100 |     100 |     100 |                   
  whenActive.ts                        |     100 |      100 |     100 |     100 |                   
 blade/src/components/ChatInput        |   78.36 |    74.53 |   76.47 |   82.96 |                   
  ChatInput.web.tsx                    |   90.47 |    84.14 |   84.21 |   93.42 | ...82,214-215,569 
  ChatInputActionBar.tsx               |     100 |    77.77 |     100 |     100 | 29,44             
  ChatInputFeedback.web.tsx            |   93.33 |    84.61 |     100 |     100 | 143-176           
  ChatInputGhostSuggestion.tsx         |      80 |       75 |     100 |     100 | 20                
  chatInputTokens.ts                   |     100 |      100 |     100 |     100 |                   
  getChatInputSubmitDisabled.ts        |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useChatInput.web.ts                  |   61.11 |    52.08 |   59.09 |   65.78 | ...96-198,205-219 
 blade/src/components/ChatMessage      |   39.42 |    32.57 |   23.33 |   41.83 |                   
  ChatMessage.web.tsx                  |     100 |    84.84 |     100 |     100 | 32,64,70,112      
  DefaultMessageBubble.web.tsx         |     100 |     40.9 |     100 |     100 | 30-71             
  ReasoningTraces.web.tsx              |    12.5 |        0 |       0 |      14 | ...79,114,163-273 
  Rotate.web.tsx                       |     100 |      100 |     100 |     100 |                   
  SelfMessageBubble.web.tsx            |     100 |       80 |     100 |     100 | 30                
  ThumbnailPreview.web.tsx             |   26.31 |        0 |       0 |   26.31 | 23,33-37,55-106   
  token.ts                             |     100 |      100 |     100 |     100 |                   
  utils.ts                             |     100 |      100 |     100 |     100 |                   
 blade/src/components/Checkbox         |   90.76 |    89.61 |     100 |   92.18 |                   
  Checkbox.tsx                         |     100 |    94.23 |     100 |     100 | 151,158,238       
  checkboxTokens.ts                    |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useCheckbox.ts                       |      80 |       80 |     100 |   82.75 | 58,72-74,112      
 .../components/Checkbox/CheckboxGroup |   85.36 |    77.14 |   86.66 |   86.48 |                   
  CheckboxGroup.tsx                    |     100 |    95.23 |     100 |     100 | 166               
  CheckboxGroupContext.ts              |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useCheckboxGroup.ts                  |   76.92 |       50 |   83.33 |   77.27 | 60-64,71,79       
 ...c/components/Checkbox/CheckboxIcon |     100 |    96.42 |     100 |     100 |                   
  CheckboxIcon.tsx                     |     100 |      100 |     100 |     100 |                   
  CheckboxIconWrapper.web.tsx          |     100 |      100 |     100 |     100 |                   
  CheckboxIconWrapperStyles.ts         |     100 |    91.66 |     100 |     100 | 31                
  Fade.web.tsx                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Chip             |   91.24 |    82.94 |     100 |   94.53 |                   
  AnimatedChip.web.tsx                 |     100 |      100 |     100 |     100 |                   
  Chip.tsx                             |   91.37 |    81.48 |     100 |   98.14 | 74                
  ChipGroup.tsx                        |   83.33 |    91.17 |     100 |   83.33 | 59,65             
  ChipGroupContext.tsx                 |    87.5 |       50 |     100 |    87.5 | 12                
  StyledChipWrapper.web.tsx            |     100 |    88.88 |     100 |     100 | 10                
  chipTokens.ts                        |     100 |       50 |     100 |     100 | 163               
  getAnimatedChipStyles.ts             |     100 |    33.33 |     100 |     100 | 11-29             
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useChipGroup.ts                      |    87.5 |    85.71 |     100 |   88.88 | 64,75,78          
 blade/src/components/Collapsible      |   88.18 |    75.67 |   86.66 |   87.61 |                   
  Collapsible.tsx                      |   94.44 |    92.85 |     100 |   94.44 | 130               
  CollapsibleBody.tsx                  |     100 |      100 |     100 |     100 |                   
  CollapsibleBodyContent.web.tsx       |   76.47 |       50 |      70 |   76.47 | 69,109-119        
  CollapsibleButton.tsx                |     100 |       50 |     100 |     100 | 51                
  CollapsibleChevronIcon.web.tsx       |     100 |      100 |     100 |     100 |                   
  CollapsibleContext.ts                |   85.71 |       50 |     100 |   85.71 | 19                
  CollapsibleLink.tsx                  |     100 |      100 |     100 |     100 |                   
  CollapsibleText.web.tsx              |   72.72 |    71.42 |   66.66 |   72.72 | 35-37             
  commonStyles.ts                      |     100 |       75 |     100 |     100 | 23-24             
  componentIds.ts                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  styles.web.ts                        |     100 |      100 |     100 |     100 |                   
 blade/src/components/Counter          |     100 |    84.21 |     100 |     100 |                   
  Counter.tsx                          |     100 |    84.21 |     100 |     100 | 56-57,122         
  StyledCounter.web.tsx                |     100 |      100 |     100 |     100 |                   
  counterTokens.ts                     |     100 |      100 |     100 |     100 |                   
  getStyledCounterStyles.ts            |     100 |      100 |     100 |     100 |                   
  index.tsx                            |       0 |        0 |       0 |       0 |                   
 blade/src/components/CounterInput     |      90 |    77.63 |      96 |      95 |                   
  CounterInput.web.tsx                 |   88.75 |    77.63 |   95.65 |   94.28 | 149-154           
  CounterInputContext.tsx              |     100 |      100 |     100 |     100 |                   
  StyledCounterInput.tsx               |     100 |      100 |     100 |     100 |                   
  token.ts                             |     100 |      100 |     100 |     100 |                   
 blade/src/components/DatePicker       |   61.31 |    50.42 |    70.5 |   61.42 |                   
  BaseDatePicker.web.tsx               |   67.02 |    68.59 |      60 |   67.03 | ...66,504,591-625 
  Calendar.web.tsx                     |   62.71 |    85.71 |    37.5 |   63.63 | ...49-153,168-186 
  CalendarFooter.web.tsx               |    87.5 |       75 |     100 |     100 | 27,33,42-44       
  CalendarHeader.web.tsx               |   54.54 |    54.54 |      50 |   54.54 | ...09-120,172-181 
  CalendarStyles.web.tsx               |     100 |       75 |     100 |     100 | 162-306           
  DateInput.web.tsx                    |   69.76 |     46.6 |   84.61 |   70.58 | ...51,304,310,515 
  DatePicker.web.tsx                   |     100 |      100 |     100 |     100 |                   
  DatePickerContext.tsx                |     100 |      100 |     100 |     100 |                   
  constants.ts                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  shiftTimezone.tsx                    |      65 |    64.28 |      75 |   63.15 | 10-13,29-33       
  useControlledDates.ts                |   34.78 |       16 |     100 |   34.78 | 42-73             
  useDatesState.ts                     |   78.75 |    81.17 |     100 |    78.2 | ...1-74,93-96,106 
  usePopup.ts                          |   94.73 |    58.33 |     100 |   94.73 | 46                
  utils.ts                             |    37.5 |    24.16 |   78.26 |   36.31 | ...81-421,484-710 
 ...ts/DatePicker/FilterChipDatePicker |   91.66 |    75.86 |     100 |   91.66 |                   
  DatePickerFilterChip.web.tsx         |    90.9 |       75 |     100 |    90.9 | 86,90             
  FilterChipDatePicker.web.tsx         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...mponents/DatePicker/QuickSelection |   41.66 |    20.75 |   17.64 |   44.44 |                   
  PresetSideBar.web.tsx                |   23.07 |    16.66 |   16.66 |   18.18 | 18-65             
  QuickSelectionItem.web.tsx           |      50 |        0 |       0 |      50 | 14                
  renderPresetDropdown.web.tsx         |   16.66 |        0 |       0 |   16.66 | 14-29             
  usePresetState.ts                    |   57.57 |    34.48 |   33.33 |   61.29 | ...36,57,69,86-96 
  utils.ts                             |   16.66 |        0 |       0 |      25 | 8-11              
 blade/src/components/Divider          |     100 |       90 |     100 |     100 |                   
  Divider.tsx                          |     100 |       90 |     100 |     100 | 80                
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Drawer           |    92.3 |       80 |   77.77 |    92.3 |                   
  Drawer.web.tsx                       |   88.23 |    76.74 |      80 |   88.23 | 135-136,217-218   
  DrawerContext.ts                     |     100 |      100 |       0 |     100 |                   
  DrawerSubcomponents.web.tsx          |   95.45 |      100 |   83.33 |   95.45 | 49                
  StackProvider.tsx                    |      95 |       50 |      80 |      95 | 37                
  drawerComponentIds.ts                |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Dropdown         |   71.07 |     63.8 |    63.8 |   72.51 |                   
  Dropdown.tsx                         |   96.82 |    74.07 |     100 |   96.77 | 138,160           
  DropdownButton.tsx                   |     100 |      100 |     100 |     100 |                   
  DropdownHeaderFooter.tsx             |   78.57 |       50 |      75 |   78.57 | 49-52             
  DropdownIconButton.tsx               |   22.22 |        0 |       0 |   22.22 | 38-70             
  DropdownLink.tsx                     |   77.77 |    83.33 |      75 |   77.77 | 79-81             
  DropdownOverlay.web.tsx              |     100 |    96.55 |     100 |     100 | 136               
  FilterChipGroup.web.tsx              |     100 |    94.11 |     100 |     100 | 57                
  FilterChipGroupContext.web.tsx       |     100 |      100 |   66.66 |     100 |                   
  FilterChipSelectInput.web.tsx        |   63.73 |    62.68 |      50 |   67.07 | ...81,188-199,229 
  InputDropdownButton.web.tsx          |   46.42 |     30.3 |   33.33 |      52 | 184,206-225       
  StyledDropdownOverlay.tsx            |     100 |       75 |     100 |     100 | 18                
  dropdownComponentIds.ts              |     100 |      100 |     100 |     100 |                   
  dropdownUtils.ts                     |   54.28 |    53.27 |   53.33 |   54.45 | ...73-276,292-307 
  filterChipSelectInputUtils.ts        |   85.71 |    83.33 |     100 |   84.61 | 47,54             
  index.ts                             |       0 |        0 |       0 |       0 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
  useDropdown.ts                       |   69.56 |    66.66 |   58.82 |   70.78 | ...19-438,463,468 
 blade/src/components/Elevate          |     100 |      100 |     100 |     100 |                   
  Elevate.web.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/EmptyState       |     100 |      100 |     100 |     100 |                   
  EmptyState.web.tsx                   |     100 |      100 |     100 |     100 |                   
  emptyStateTokens.ts                  |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Fade             |     100 |       60 |     100 |     100 |                   
  Fade.web.tsx                         |     100 |       60 |     100 |     100 | 41-61             
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/FileUpload       |   50.23 |    54.66 |   35.29 |   53.73 |                   
  FileUpload.web.tsx                   |   43.28 |    51.67 |   25.71 |   47.89 | ...20-227,374-460 
  FileUploadItem.tsx                   |   69.23 |    68.75 |   42.85 |   69.23 | 110-124,153-159   
  FileUploadItemIcon.tsx               |   40.62 |    30.76 |     100 |   40.62 | 42-61,72-75       
  StyledFileUploadItemWrapper.web.tsx  |     100 |       75 |     100 |     100 | 18-32             
  StyledFileUploadWrapper.web.tsx      |     100 |      100 |     100 |     100 |                   
  fileUploadTokens.ts                  |   57.14 |        0 |      25 |   61.53 | 83-90             
  isFileAccepted.tsx                   |   78.57 |    58.33 |     100 |   78.57 | 19,24-27          
 blade/src/components/FilterChip       |   96.15 |       75 |   88.88 |   96.15 |                   
  BaseFilterChip.web.tsx               |      96 |       75 |   88.88 |      96 | 161               
  tokens.ts                            |     100 |      100 |     100 |     100 |                   
 blade/src/components/Form             |   96.07 |    84.61 |     100 |   96.07 |                   
  FormHint.tsx                         |     100 |       88 |     100 |     100 | 30-35,114         
  FormHintWrapper.web.tsx              |     100 |      100 |     100 |     100 |                   
  FormLabel.tsx                        |   88.88 |     82.5 |     100 |   88.88 | 106,163           
  formTokens.ts                        |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  useFormId.ts                         |     100 |      100 |     100 |     100 |                   
 ...c/components/Form/CharacterCounter |     100 |      100 |     100 |     100 |                   
  CharacterCounter.tsx                 |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Form/Selector    |   96.87 |    71.87 |     100 |     100 |                   
  SelectorGroupField.tsx               |   88.88 |    66.66 |     100 |     100 | 33-45             
  SelectorInput.web.tsx                |     100 |      100 |     100 |     100 |                   
  SelectorLabel.web.tsx                |     100 |      100 |     100 |     100 |                   
  SelectorSupportText.tsx              |     100 |       50 |     100 |     100 | 24-29             
  SelectorTitle.tsx                    |     100 |    66.66 |     100 |     100 | 7                 
 blade/src/components/GenUI            |   82.75 |    74.12 |   89.24 |   82.81 |                   
  GenUIComponents.web.tsx              |      90 |    78.01 |   94.73 |   89.68 | ...1303,1332,1691 
  GenUIContext.web.tsx                 |     100 |      100 |     100 |     100 |                   
  GenUIProvider.web.tsx                |     100 |      100 |     100 |     100 |                   
  GenUISchemaRenderer.web.tsx          |   89.04 |    85.71 |   84.61 |   90.14 | 18,231-238        
  GenUISpacing.ts                      |     100 |    91.66 |     100 |     100 | 33,52             
  rehypeAnimate.ts                     |   18.33 |    15.78 |    9.09 |   19.29 | ...0,44-63,89-119 
 blade/src/components/Icons            |       0 |        0 |       0 |       0 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
  types.ts                             |       0 |        0 |       0 |       0 |                   
 ...nts/Icons/AcceptPaymentsFilledIcon |     100 |      100 |     100 |     100 |                   
  AcceptPaymentsFilledIcon.tsx         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...omponents/Icons/AcceptPaymentsIcon |     100 |      100 |     100 |     100 |                   
  AcceptPaymentsIcon.tsx               |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../src/components/Icons/ActivityIcon |     100 |      100 |     100 |     100 |                   
  ActivityIcon.tsx                     |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...c/components/Icons/AddressBookIcon |     100 |      100 |     100 |     100 |                   
  AddressBookIcon.tsx                  |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ents/Icons/AffordabilityFilledIcon |     100 |      100 |     100 |     100 |                   
  AffordabilityFilledIcon.tsx          |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...components/Icons/AffordabilityIcon |     100 |      100 |     100 |     100 |                   
  AffordabilityIcon.tsx                |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...c/components/Icons/AgentStudioIcon |     100 |      100 |     100 |     100 |                   
  AgentStudioIcon.tsx                  |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Icons/AirplayIcon |     100 |      100 |     100 |     100 |                   
  AirplayIcon.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...c/components/Icons/AlertCircleIcon |     100 |      100 |     100 |     100 |                   
  AlertCircleIcon.tsx                  |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../components/Icons/AlertOctagonIcon |     100 |      100 |     100 |     100 |                   
  AlertOctagonIcon.tsx                 |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...src/components/Icons/AlertOnlyIcon |     100 |      100 |     100 |     100 |                   
  AlertOnlyIcon.tsx                    |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...components/Icons/AlertTriangleIcon |     100 |      100 |     100 |     100 |                   
  AlertTriangleIcon.tsx                |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...c/components/Icons/AlignCenterIcon |     100 |      100 |     100 |     100 |                   
  AlignCenterIcon.tsx                  |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../components/Icons/AlignJustifyIcon |     100 |      100 |     100 |     100 |                   
  AlignJustifyIcon.tsx                 |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...src/components/Icons/AlignLeftIcon |     100 |      100 |     100 |     100 |                   
  AlignLeftIcon.tsx                    |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...rc/components/Icons/AlignRightIcon |     100 |      100 |     100 |     100 |                   
  AlignRightIcon.tsx                   |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/AnchorIcon |     100 |      100 |     100 |     100 |                   
  AnchorIcon.tsx                       |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Icons/AndroidIcon |     100 |      100 |     100 |     100 |                   
  AndroidIcon.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../components/Icons/AnnouncementIcon |     100 |      100 |     100 |     100 |                   
  AnnouncementIcon.tsx                 |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../src/components/Icons/ApertureIcon |     100 |      100 |     100 |     100 |                   
  ApertureIcon.tsx                     |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../src/components/Icons/AppStoreIcon |     100 |      100 |     100 |     100 |                   
  AppStoreIcon.tsx                     |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/AppleIcon  |     100 |      100 |     100 |     100 |                   
  AppleIcon.tsx                        |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...src/components/Icons/ArrowDownIcon |     100 |      100 |     100 |     100 |                   
  ArrowDownIcon.tsx                    |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...components/Icons/ArrowDownLeftIcon |     100 |      100 |     100 |     100 |                   
  ArrowDownLeftIcon.tsx                |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...omponents/Icons/ArrowDownRightIcon |     100 |      100 |     100 |     100 |                   
  ArrowDownRightIcon.tsx               |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...src/components/Icons/ArrowLeftIcon |     100 |      100 |     100 |     100 |                   
  ArrowLeftIcon.tsx                    |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...rc/components/Icons/ArrowRightIcon |     100 |      100 |     100 |     100 |                   
  ArrowRightIcon.tsx                   |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...mponents/Icons/ArrowSquareDownIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareDownIcon.tsx              |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ents/Icons/ArrowSquareDownLeftIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareDownLeftIcon.tsx          |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...nts/Icons/ArrowSquareDownRightIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareDownRightIcon.tsx         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...mponents/Icons/ArrowSquareLeftIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareLeftIcon.tsx              |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ponents/Icons/ArrowSquareRightIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareRightIcon.tsx             |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...components/Icons/ArrowSquareUpIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareUpIcon.tsx                |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...onents/Icons/ArrowSquareUpLeftIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareUpLeftIcon.tsx            |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...nents/Icons/ArrowSquareUpRightIcon |     100 |      100 |     100 |     100 |                   
  ArrowSquareUpRightIcon.tsx           |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Icons/ArrowUpIcon |     100 |      100 |     100 |     100 |                   
  ArrowUpIcon.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...c/components/Icons/ArrowUpLeftIcon |     100 |      100 |     100 |     100 |                   
  ArrowUpLeftIcon.tsx                  |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../components/Icons/ArrowUpRightIcon |     100 |      100 |     100 |     100 |                   
  ArrowUpRightIcon.tsx                 |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/AtSignIcon |     100 |      100 |     100 |     100 |                   
  AtSignIcon.tsx                       |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...rc/components/Icons/AttachmentIcon |     100 |      100 |     100 |     100 |                   
  AttachmentIcon.tsx                   |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...nents/Icons/AutomateAccountingIcon |     100 |      100 |     100 |     100 |                   
  AutomateAccountingIcon.tsx           |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ts/Icons/AutomatePayrollFilledIcon |     100 |      100 |     100 |     100 |                   
  AutomatePayrollFilledIcon.tsx        |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...mponents/Icons/AutomatePayrollIcon |     100 |      100 |     100 |     100 |                   
  AutomatePayrollIcon.tsx              |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/AwardIcon  |     100 |      100 |     100 |     100 |                   
  AwardIcon.tsx                        |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../BankAccountVerificationFilledIcon |     100 |      100 |     100 |     100 |                   
  ...AccountVerificationFilledIcon.tsx |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../Icons/BankAccountVerificationIcon |     100 |      100 |     100 |     100 |                   
  BankAccountVerificationIcon.tsx      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BankIcon   |     100 |      100 |     100 |     100 |                   
  BankIcon.tsx                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...c/components/Icons/BarChartAltIcon |     100 |      100 |     100 |     100 |                   
  BarChartAltIcon.tsx                  |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../src/components/Icons/BarChartIcon |     100 |      100 |     100 |     100 |                   
  BarChartIcon.tsx                     |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Icons/BarCodeIcon |     100 |      100 |     100 |     100 |                   
  BarCodeIcon.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...onents/Icons/Battery100PercentIcon |     100 |      100 |     100 |     100 |                   
  Battery100PercentIcon.tsx            |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ponents/Icons/Battery20PercentIcon |     100 |      100 |     100 |     100 |                   
  Battery20PercentIcon.tsx             |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ponents/Icons/Battery40PercentIcon |     100 |      100 |     100 |     100 |                   
  Battery40PercentIcon.tsx             |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ponents/Icons/Battery60PercentIcon |     100 |      100 |     100 |     100 |                   
  Battery60PercentIcon.tsx             |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...ponents/Icons/Battery80PercentIcon |     100 |      100 |     100 |     100 |                   
  Battery80PercentIcon.tsx             |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...mponents/Icons/BatteryChargingIcon |     100 |      100 |     100 |     100 |                   
  BatteryChargingIcon.tsx              |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Icons/BatteryIcon |     100 |      100 |     100 |     100 |                   
  BatteryIcon.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BellIcon   |     100 |      100 |     100 |     100 |                   
  BellIcon.tsx                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...e/src/components/Icons/BellOffIcon |     100 |      100 |     100 |     100 |                   
  BellOffIcon.tsx                      |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...rc/components/Icons/BfsiFilledIcon |     100 |      100 |     100 |     100 |                   
  BfsiFilledIcon.tsx                   |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BfsiIcon   |     100 |      100 |     100 |     100 |                   
  BfsiIcon.tsx                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BillIcon   |     100 |      100 |     100 |     100 |                   
  BillIcon.tsx                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../components/Icons/BillMeFilledIcon |     100 |      100 |     100 |     100 |                   
  BillMeFilledIcon.tsx                 |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BillMeIcon |     100 |      100 |     100 |     100 |                   
  BillMeIcon.tsx                       |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 ...src/components/Icons/BluetoothIcon |     100 |      100 |     100 |     100 |                   
  BluetoothIcon.tsx                    |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BoldIcon   |     100 |      100 |     100 |     100 |                   
  BoldIcon.tsx                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BookIcon   |     100 |      100 |     100 |     100 |                   
  BookIcon.tsx                         |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 .../src/components/Icons/BookmarkIcon |     100 |      100 |     100 |     100 |                   
  BookmarkIcon.tsx                     |     100 |      100 |     100 |     100 |                   
  index.ts                             |       0 |        0 |       0 |       0 |                   
 blade/src/components/Icons/BoxIcon    |     100 |      100 |     100 |     100 |                   
  BoxIcon.tsx                          |     100 |      100 |     100 |     100 |                   
  index.ts       ...*[Comment body truncated]*

@rzp-slash rzp-slash Bot 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.

✨ Agentic PR Review ✨

UI Review

✅ 6 passed

Passing checks (6)
Check Screenshot
With feedback prompt (attached)
With custom mood icons
Default (regression check)
With validation error (regression check)
Full featured (regression check)
KitchenSink - ChatInput (regression check)

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    moodIcons,
    isVisible: showFeedback,
    question: "How's this assistant doing so far?",
    onMoodSelect: ({ mood }) => setPicked(mood),
    onSubmit: ({ mood, tags }) => setShowFeedback(false),
    onDismiss: () => setShowFeedback(false),
  }}
/>

* change that shows up as unexplained diff noise in every snapshot downstream.
*/
const isFeedbackVisible = Boolean(feedback) && feedback?.isVisible !== false;
const frameProps = feedback

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.

🟠 [MAJOR] · code-quality-critique · confidence: 8/10

Problem: Error popup mispositioned when feedback is visible. The error popup uses bottom="calc(100% - 12px)" (line 328) relative to the outer BaseBox, whose height now includes the feedback strip + padding + gap when frameProps is applied. The popup lands at the top of the feedback strip instead of sliding out from behind the input card's top edge.

Suggestion: Move the error popup inside the input card's positioned wrapper (<BaseBox position="relative" zIndex={1}> at line 278) so bottom: calc(100% - 12px) resolves against the input card height, not the full frame.

@github-actions

github-actions Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@rzp-slash rzp-slash Bot 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.

✨ Agentic PR Review ✨

UI Review

✅ 8 passed

Passing checks (8)
Check Screenshot
ChatInput with feedback prompt (attached)
ChatInput with custom mood icons
MoodScaleIsNotCovered interaction test
ErrorRegionIsReachableWhenShowing interaction test
PickingAMoodAdvancesTheFlow interaction test
ComposerHoldsStillAcrossSteps interaction test
ChatInput default (no feedback prop)
ChatInput KitchenSink (all stories including feedback)

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    moodIcons,
    question: "How's this assistant doing so far?",
    onMoodSelect: ({ mood }) => {},
    onSubmit: ({ mood, tags }) => {},
    onDismiss: () => {},
  }}
/>

return (
<BaseBox
position="relative"
{...frameProps}

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.

🟠 [MAJOR] · code-quality-critique · confidence: 8/10

Problem: Error popup is misaligned when the feedback surface is showing: frameProps adds 8px padding and the feedback strip to the container, but the error popup's bottom/left/right were calibrated for the no-frame case — it overhangs the card by 8px on each side and sits above the strip instead of behind the card's top edge

Suggestion: Move the error popup inside the card wrapper BaseBox (which already has position:relative), or adjust bottom/left/right to account for the frame padding when isFeedbackVisible is true

@kamaleshs-bridge4 kamaleshs-bridge4 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✨ Agentic PR Review ✨

UI Review

✅ 2 passed · ❌ 1 failed

Check Problem
With feedback prompt (attached)
Passing checks (2)
Check
With custom mood icons
KitchenSink ChatInput

Usage

import { ChatInput } from '@razorpay/blade/components';

const moodIcons = {
  'very-dissatisfied': <SadFaceIcon />,
  'dissatisfied': <FrownIcon />,
  'satisfied': <SmileIcon />,
  'very-satisfied': <GrinIcon />,
};

<ChatInput
  feedback={{
    moodIcons,
    question: 'How is it going?',
    onMoodSelect: ({ mood }) => trackMood(mood),
    onSubmit: ({ mood, tags, comment }) => submitFeedback({ mood, tags, comment }),
    onDismiss: () => setShowFeedback(false),
  }}
/>

* the page chrome. No border — the tint alone separates it from the page, and an outline
* around an outline (the card carries its own) reads as two boxes rather than one.
*/
backgroundColor: isFeedbackVisible ? 'surface.background.primary.subtle' : 'transparent',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 [MAJOR] · code-quality-critique · confidence: 7/10

Problem: When isVisible transitions from true to false, backgroundColor and padding in frameProps change instantly (tinted to transparent, spacing.3 to spacing.0), while the Move exit animation is still playing. This causes two visible glitches: (1) the feedback content appears to float without its tinted background during the exit animation, and (2) the input card jumps up by ~12px because the padding change is immediate rather than animated. The ComposerHoldsStillAcrossSteps test only covers step changes (mood to tags), not the dismissal transition, so this is untested.

Suggestion: Delay the frame's background/padding removal until the Move exit animation completes. One approach: track a local isAnimatingOut state and keep the visible frame props until the animation finishes, or animate the container's padding and background alongside the content exit.

const isFeedbackVisible = Boolean(feedback) && feedback?.isVisible !== false;
const frameProps = feedback
? ({
display: 'flex',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [MINOR] · code-quality-critique · confidence: 8/10

Problem: frameProps sets display: 'flex', but {...getStyledProps(rest)} is spread after it on line 262. Since display is part of StyledPropsBlade, a consumer passing display (e.g. display="block") to ChatInput would override the frame's display: 'flex', silently breaking the flex column layout — flexDirection and gap become no-ops without flex, removing the 4px spacing between the prompt and the card.

Suggestion: Apply display: 'flex' via a styled component or inline style that cannot be overridden by consumer styled props, or spread frameProps after getStyledProps(rest) for layout-critical props only.

*/
type ChatInputFeedbackProps = Pick<
ChatFeedbackProps,
'question' | 'moodConfig' | 'moodIcons' | 'isDisabled' | 'onMoodSelect' | 'onSubmit' | 'onDismiss'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🙏🏻 [NEEDS CLARIFICATION] · api-decision-critique · confidence: 4/10

ChatInputFeedbackProps picks 'moodIcons' from ChatFeedbackProps, where it is a required prop of type ChatFeedbackMoodIcons. However, ChatFeedbackMoodIcons is not re-exported from ChatFeedback/index.ts (only 5 of 6 types are exported). Consumers who want to pre-declare a typed mood-icons object — rather than relying on inference from an inline literal — cannot import the type from the public API. Should ChatFeedback/index.ts add ChatFeedbackMoodIcons to its export list, or is the expectation that consumers construct Record<ChatFeedbackMood, React.ReactNode> manually?

@kamaleshs-bridge4 kamaleshs-bridge4 added the Human Help Needed 🧑🏻‍💻 Poor AI needs help from human for something label Aug 14, 2026
@annamalailakshmann
annamalailakshmann force-pushed the feat/chat-input-attached-feedback branch from 95b0238 to 85b640c Compare August 17, 2026 04:58
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@rzp-slash-public rzp-slash-public Bot 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.

✨ Agentic PR Review ✨

Status: Approved ✅

UI Review

✅ 11 passed

Passing checks (11)
Check Screenshot
ChatInput with feedback prompt (attached)
ChatInput with feedback prompt — follow-up step
ChatInput with feedback prompt — after dismiss
ChatInput with custom mood icons
KitchenSink ChatInput
ChatInput Interaction Tests — MoodScaleIsNotCovered
ChatInput Interaction Tests — ErrorRegionIsReachableWhenShowing
ChatInput Interaction Tests — PickingAMoodAdvancesTheFlow
ChatInput Interaction Tests — ComposerHoldsStillAcrossSteps
ChatInput Default (regression check vs master)
ChatInput FullFeatured (regression check)

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    moodIcons,
    isVisible,
    question: "How's this assistant doing so far?",
    onMoodSelect: ({ mood }) => setPicked(mood),
    onSubmit: ({ mood, tags }) => recordAnswer(mood, tags),
    onDismiss: () => setShowFeedback(false),
  }}
/>

@rzp-slash-public rzp-slash-public Bot added the rcore:eligible-for-auto-approval PR is approved by slash label Aug 17, 2026
@annamalailakshmann
annamalailakshmann force-pushed the feat/chat-input-attached-feedback branch from 85b640c to 0930cbe Compare August 17, 2026 10:05
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@kamaleshs-bridge4 kamaleshs-bridge4 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✨ Agentic PR Review ✨

Status: Approved ✅

UI Review

✅ 7 passed

Passing checks (7)
Check Screenshot
ChatFeedback Default
ChatFeedback Without auto dismiss
ChatFeedback Custom mood config
ChatInput With feedback prompt (attached)
ChatInput With custom mood icons
ChatInput Default (regression check)
ChatInput KitchenSink

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    question: "How's this going?",
    moodIcons,
    moodConfig,
    isVisible,
    freeTextTag: 'Other',
    commentPlaceholder: 'Anything else? (optional)',
    onMoodSelect,
    onSubmit,
    onDismiss,
  }}
/>

* collects the free-text comment needs to submit the flow from its own send button, and to
* release the tag again when the user backs out of typing.
*/
controlsRef?: React.MutableRefObject<ChatFeedbackControls | null>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [MINOR] · code-quality-critique · confidence: 9/10

Problem: Stale JSDoc: says onSubmit 'Fires once when tags are submitted, and again with comment populated if the user goes on to add a free-text follow-up', but the comment step was removed in this PR — onSubmit now fires only once. The 'and again with comment' phrase describes the removed submitComment/openComment flow.

Suggestion: Update JSDoc to reflect that onSubmit fires once on submit, with comment populated by the host (e.g. composer) if free text was collected

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@rzp-slash rzp-slash Bot 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.

✨ Agentic PR Review ✨

UI Review

✅ 4 passed

Passing checks (4)
Check Screenshot
With feedback prompt (attached)
With custom mood icons
ChatFeedback Default
KitchenSink ChatInput

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    question: "How's this going?",
    moodIcons,
    onSubmit: ({ mood, tags, comment }) => record(mood, tags, comment),
    onDismiss: () => setShowFeedback(false),
  }}
/>

hideLabelText
hideFormHint
placeholder={showGhostSuggestion ? '' : placeholder}
placeholder={

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.

🟠 [MAJOR] · code-quality-critique · confidence: 8/10

Problem: The placeholder prop was updated to account for isFeedbackInput, but the inputRowOverlay prop (unchanged, ~line 499) was not. When entering feedback mode, the chat draft is cleared, making showGhostSuggestion true if suggestions are provided. The ghost suggestion overlay then renders on top of the feedback placeholder, showing chat suggestions to a user who is supposed to be typing feedback. Additionally, handleComposerKeyDown only handles Escape and Enter in feedback mode — Tab is silently dropped, so the visible ghost suggestion cannot even be accepted.

Suggestion: Guard the inputRowOverlay with !isFeedbackInput, e.g. inputRowOverlay={!isFeedbackInput && showGhostSuggestion && suggestions ? (...) : null}. This ensures ghost suggestions are suppressed while the composer is collecting feedback.

[clearTimers, onMoodSelect, schedule, setSelectedTags, theme.motion.duration.quick],
);

const submitTags = React.useCallback(() => {

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.

🟠 [MAJOR] · api-decision-critique · confidence: 8/10

Problem: The comment prop is declared on ChatFeedbackProps (per the decisions doc and ChatFeedbackSubmitPayload) but is never wired through. submitTags calls onSubmit?.({ mood: selectedMood, tags: selectedTags }) with no comment field, and UseChatFeedbackProps does not Pick comment. A consumer using ChatFeedback directly and passing comment will have it silently ignored — onSubmit receives { mood, tags } only. The ChatInputFeedback wrapper works around this by intercepting onSubmit and injecting comment manually, confirming the author knows ChatFeedback itself doesn't handle it.

Suggestion: Pass comment from ChatFeedbackProps into useChatFeedback and include it in the submitTags payload: onSubmit?.({ mood: selectedMood, tags: selectedTags, comment }). Then ChatInputFeedback can pass comment directly to ChatFeedback instead of intercepting onSubmit.

<ChatInputActionBar
isDisabled={isDisabled}
isGenerating={isGenerating}
isSubmitDisabled={isSubmitDisabled}

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.

🔵 [MINOR] · code-quality-critique · confidence: 6/10

Problem: The onSubmit prop on ChatInputActionBar was changed to route to submitFeedbackInput in feedback mode, but isSubmitDisabled (passed unchanged) still reflects the chat submit's empty-text check. In feedback mode with no typed comment, the send button is disabled — yet Enter in handleComposerKeyDown calls submitFeedbackInput unconditionally. This creates an inconsistency: the user can submit empty feedback via Enter but not via the send button.

Suggestion: Override isSubmitDisabled in feedback mode (e.g. pass isSubmitDisabled={isFeedbackInput ? false : isSubmitDisabled}), or add an empty-text guard to the Enter handler in handleComposerKeyDown to match the button's behavior.

which is why that state had to move off the glyph.
*/}
<MoodIconSlot aria-hidden="true">{moodIcons[mood]}</MoodIconSlot>
<MoodIconSlot aria-hidden="true">{moodIcons?.[mood]}</MoodIconSlot>

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.

🔵 [MINOR] · code-quality-critique · confidence: 6/10

Problem: The expression changed from moodIcons[mood] to moodIcons?.[mood], adding optional chaining. But moodIcons is typed as ChatFeedbackMoodIcons = Record<ChatFeedbackMood, React.ReactNode> — a required prop. The optional chaining is inconsistent with the type contract and could mask a bug where moodIcons is accidentally omitted.

Suggestion: Revert to moodIcons[mood] to match the required type. If there is a real scenario where moodIcons can be undefined, make the type optional instead of silently weakening the runtime check.

@annamalailakshmann
annamalailakshmann force-pushed the feat/chat-input-attached-feedback branch from 3805480 to bf8d78d Compare August 18, 2026 05:24
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@annamalailakshmann
annamalailakshmann force-pushed the feat/chat-input-attached-feedback branch from bf8d78d to baf5963 Compare August 18, 2026 06:03

@kamaleshs-bridge4 kamaleshs-bridge4 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✨ Agentic PR Review ✨

Status: Approved ✅

UI Review

✅ 10 passed

Passing checks (10)
Check Screenshot
With feedback prompt (attached) — prompt renders and mood selection works
With feedback prompt (attached) — composer takeover via 'Other' tag
With feedback prompt (attached) — draft stashing and restoration
With custom mood icons — emoji glyphs render and selection records
MoodScaleIsNotCovered — hit-test confirms buttons are not overlapped
ErrorRegionIsReachableWhenShowing — alert has pointerEvents auto
PickingAMoodAdvancesTheFlow — mood picked and follow-up step shown
ComposerHoldsStillAcrossSteps — composer position unchanged after step swap
Default story — no feedback prompt, existing functionality intact
Full Featured story — ghost suggestion and action bar unaffected

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    feedbackIcons: emojiMoodIcons,
    isVisible: showFeedback,
    question: "How's this assistant doing so far?",
    onMoodSelect: ({ mood }) => setAnswer(mood),
    onSubmit: ({ mood, tags, comment }) => record({ mood, tags, comment }),
    onDismiss: () => setShowFeedback(false),
    freeTextTag: 'Other',
    commentPlaceholder: 'Anything else? (optional)',
  }}
/>

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@rzp-slash-public rzp-slash-public Bot 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.

✨ Agentic PR Review ✨

UI Review

✅ 6 passed

Passing checks (6)
Check
ChatInput with feedback prompt
ChatInput free-text composer takeover
ChatInput with custom mood icons
ChatInput default docs story (regression)
ChatInput FullFeatured story (regression)
ChatInput WithValidationError story (regression)

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    question: "How's this going?",
    feedbackIcons,
    onSubmit: ({ mood, tags, comment }) => { ... },
    onDismiss: () => { ... },
  }}
/>

Comment thread packages/blade/src/components/ChatInput/ChatInput.web.tsx
@github-actions

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash PR Healer has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@annamalailakshmann
annamalailakshmann force-pushed the feat/chat-input-attached-feedback branch from 5082b5f to 6f543ef Compare August 18, 2026 09:24
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

(Review Cancelled - Superseded by a new run)

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Slash AI Review has been triggered. View execution logs

@rzp-slash-public rzp-slash-public Bot 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.

✨ Agentic PR Review ✨

Status: Approved ✅

UI Review

✅ 9 passed

Passing checks (9)
Check Screenshot
ChatInput With feedback prompt
ChatInput With custom mood icons
ChatInput Default
ChatInput With Ghost Suggestions
ChatInput With File Upload
ChatInput With Validation Error
ChatInput Stop Generation
ChatInput Full Featured
ChatInput Paste Image Upload

Usage

import { ChatInput } from '@razorpay/blade/components';

<ChatInput
  placeholder="Ask anything..."
  feedback={{
    feedbackIcons,
    isVisible: showFeedback,
    question: "How's Ray doing so far?",
    freeTextTag: 'Other',
    commentPlaceholder: 'Anything else? (optional)',
    onMoodSelect: ({ mood }) => setPicked(mood),
    onSubmit: ({ mood, tags, comment }) => record(mood, tags, comment),
    onDismiss: () => setShowFeedback(false),
  }}
/>

@kamaleshs-bridge4 kamaleshs-bridge4 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blade Changes to packages/blade Human Help Needed 🧑🏻‍💻 Poor AI needs help from human for something rcore:eligible-for-auto-approval PR is approved by slash react-native

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants