From 64cb0815d75008e1a0be3a4a4aebea47983f70d2 Mon Sep 17 00:00:00 2001 From: Ernst Kaese Date: Thu, 9 Jul 2026 09:39:30 +0000 Subject: [PATCH 1/2] feat: add menu dropdown style overrides to PromptInput style API Adds a new `style.menu` sub-object to `PromptInputProps.Style` that lets design-system consumers (e.g. Horizon-Rhythm-Core) override the visual appearance of the trigger-based menus/shortcuts dropdown. New style properties: - style.menu.backgroundColor -> dropdown content-wrapper background - style.menu.borderColor -> dropdown border colour - style.menu.borderRadius -> dropdown border radius - style.menu.borderWidth -> dropdown border width Implementation: - 4 new custom CSS properties added to the generator list - getPromptInputStyles() maps them onto the root element as CSS vars - InternalPromptInput threads style.menu down to TokenMode - TokenMode builds a DropdownProps.Style and passes it to Dropdown - Existing Dropdown style API (dropdownContentBorder* CSS vars) reused - Unit tests updated; dev page added (menu-style.page.tsx) --- build-tools/utils/custom-css-properties.js | 5 +++ pages/prompt-input/menu-style.page.tsx | 48 ++++++++++++++++++++++ src/prompt-input/__tests__/styles.test.tsx | 10 +++++ src/prompt-input/components/token-mode.tsx | 16 ++++++++ src/prompt-input/interfaces.ts | 25 +++++++++++ src/prompt-input/internal.tsx | 1 + src/prompt-input/styles.tsx | 4 ++ 7 files changed, 109 insertions(+) create mode 100644 pages/prompt-input/menu-style.page.tsx diff --git a/build-tools/utils/custom-css-properties.js b/build-tools/utils/custom-css-properties.js index 73511df043..cb51af6453 100644 --- a/build-tools/utils/custom-css-properties.js +++ b/build-tools/utils/custom-css-properties.js @@ -155,6 +155,11 @@ const customCssPropertiesList = [ 'promptInputStylePlaceholderFontSize', 'promptInputStylePlaceholderFontStyle', 'promptInputStylePlaceholderFontWeight', + // Prompt input menu/dropdown style properties + 'promptInputMenuStyleBackgroundColor', + 'promptInputMenuStyleBorderColor', + 'promptInputMenuStyleBorderRadius', + 'promptInputMenuStyleBorderWidth', // Progress bar style properties 'progressBarBackgroundColor', 'progressBarBorderRadius', diff --git a/pages/prompt-input/menu-style.page.tsx b/pages/prompt-input/menu-style.page.tsx new file mode 100644 index 0000000000..ed707a5263 --- /dev/null +++ b/pages/prompt-input/menu-style.page.tsx @@ -0,0 +1,48 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import React, { useState } from 'react'; + +import PromptInput, { PromptInputProps } from '~components/prompt-input'; + +const menuStyle: PromptInputProps.Style['menu'] = { + backgroundColor: 'light-dark(#faf5ff, #2d1b4e)', + borderColor: '#a78bfa', + borderRadius: '12px', + borderWidth: '1.5px', +}; + +const options: PromptInputProps.MenuDefinition['options'] = [ + { value: 'help', label: '/help', description: 'Show help' }, + { value: 'search', label: '/search', description: 'Search content' }, + { value: 'clear', label: '/clear', description: 'Clear the input' }, +]; + +export default function MenuStylePage() { + const [value, setValue] = useState(''); + const [tokens, setTokens] = useState([]); + + return ( + <> +

PromptInput — menu style override

+

+ Type / to open the command menu. The dropdown uses the custom style.menu overrides + (purple border, rounded corners, themed background). +

+ { + setValue(detail.value); + if (detail.tokens) { + setTokens(detail.tokens); + } + }} + onAction={() => {}} + i18nStrings={{ actionButtonAriaLabel: 'Send' }} + /> + + ); +} diff --git a/src/prompt-input/__tests__/styles.test.tsx b/src/prompt-input/__tests__/styles.test.tsx index beee993c47..547b0ae51a 100644 --- a/src/prompt-input/__tests__/styles.test.tsx +++ b/src/prompt-input/__tests__/styles.test.tsx @@ -60,6 +60,12 @@ describe('getPromptInputStyles', () => { fontWeight: '400', fontStyle: 'italic', }, + menu: { + backgroundColor: '#1a1a2e', + borderColor: '#7b2d8b', + borderRadius: '12px', + borderWidth: '1.5px', + }, }; expect(getPromptInputStyles(allStyles)).toEqual({ @@ -93,6 +99,10 @@ describe('getPromptInputStyles', () => { [customCssProps.promptInputStylePlaceholderFontSize]: '14px', [customCssProps.promptInputStylePlaceholderFontWeight]: '400', [customCssProps.promptInputStylePlaceholderFontStyle]: 'italic', + [customCssProps.promptInputMenuStyleBackgroundColor]: '#1a1a2e', + [customCssProps.promptInputMenuStyleBorderColor]: '#7b2d8b', + [customCssProps.promptInputMenuStyleBorderRadius]: '12px', + [customCssProps.promptInputMenuStyleBorderWidth]: '1.5px', }); }); diff --git a/src/prompt-input/components/token-mode.tsx b/src/prompt-input/components/token-mode.tsx index b5716048bc..8c3374b9c2 100644 --- a/src/prompt-input/components/token-mode.tsx +++ b/src/prompt-input/components/token-mode.tsx @@ -4,6 +4,7 @@ import React from 'react'; import clsx from 'clsx'; +import { DropdownProps } from '../../dropdown/interfaces'; import Dropdown from '../../dropdown/internal'; import DropdownFooter from '../../internal/components/dropdown-footer'; import { DropdownStatusResult } from '../../internal/components/dropdown-status'; @@ -53,6 +54,8 @@ interface TokenModeProps { i18nStrings?: PromptInputProps['i18nStrings']; maxMenuHeight?: number; + /** Style overrides forwarded to the menu dropdown. */ + menuStyle?: PromptInputProps.Style['menu']; } const MENU_MIN_WIDTH = 300; @@ -76,6 +79,7 @@ export default function TokenMode({ menuItemsHandlers, menuDropdownStatus, maxMenuHeight, + menuStyle, handleInput, handleLoadMore, editableElementAttributes, @@ -117,6 +121,18 @@ export default function TokenMode({ minWidth={MENU_MIN_WIDTH} maxHeight={maxMenuHeight} expandToViewport={true} + style={ + menuStyle + ? ({ + dropdown: { + background: menuStyle.backgroundColor, + borderColor: menuStyle.borderColor, + borderRadius: menuStyle.borderRadius, + borderWidth: menuStyle.borderWidth, + }, + } satisfies DropdownProps.Style) + : undefined + } open={ !!( shouldRenderMenuDropdown && diff --git a/src/prompt-input/interfaces.ts b/src/prompt-input/interfaces.ts index 36011abcee..393e1dda64 100644 --- a/src/prompt-input/interfaces.ts +++ b/src/prompt-input/interfaces.ts @@ -574,5 +574,30 @@ export namespace PromptInputProps { fontStyle?: string; fontWeight?: string; }; + /** + * Style overrides for the menus/shortcuts dropdown that appears when a trigger + * character is typed. Use this to match the dropdown's visual appearance to a + * custom design system theme. + * + * @awsuiSystem core + */ + menu?: { + /** + * Background color of the dropdown content wrapper. + */ + backgroundColor?: string; + /** + * Border color of the dropdown content wrapper. + */ + borderColor?: string; + /** + * Border radius of the dropdown content wrapper. + */ + borderRadius?: string; + /** + * Border width of the dropdown content wrapper. + */ + borderWidth?: string; + }; } } diff --git a/src/prompt-input/internal.tsx b/src/prompt-input/internal.tsx index 4a042cc067..716e5e3c80 100644 --- a/src/prompt-input/internal.tsx +++ b/src/prompt-input/internal.tsx @@ -444,6 +444,7 @@ const InternalPromptInput = React.forwardRef( menuItemsHandlers={tokenMode.menuItemsHandlers} menuDropdownStatus={tokenMode.menuDropdownStatus} maxMenuHeight={maxMenuHeight} + menuStyle={style?.menu} handleInput={tokenMode.handleInput} handleLoadMore={tokenMode.handleLoadMore} editableElementAttributes={tokenMode.editableElementAttributes} diff --git a/src/prompt-input/styles.tsx b/src/prompt-input/styles.tsx index f993af759d..ec7013277f 100644 --- a/src/prompt-input/styles.tsx +++ b/src/prompt-input/styles.tsx @@ -40,5 +40,9 @@ export function getPromptInputStyles(style: PromptInputProps['style']) { [customCssProps.promptInputStylePlaceholderFontSize]: style?.placeholder?.fontSize, [customCssProps.promptInputStylePlaceholderFontWeight]: style?.placeholder?.fontWeight, [customCssProps.promptInputStylePlaceholderFontStyle]: style?.placeholder?.fontStyle, + [customCssProps.promptInputMenuStyleBackgroundColor]: style?.menu?.backgroundColor, + [customCssProps.promptInputMenuStyleBorderColor]: style?.menu?.borderColor, + [customCssProps.promptInputMenuStyleBorderRadius]: style?.menu?.borderRadius, + [customCssProps.promptInputMenuStyleBorderWidth]: style?.menu?.borderWidth, }; } From 0bfb606cfb3dd2880455e9fd3bc94b0bee1a6659 Mon Sep 17 00:00:00 2001 From: Ernst Kaese Date: Thu, 9 Jul 2026 10:50:36 +0000 Subject: [PATCH 2/2] chore(prompt-input): trim redundant comments on menu style API Remove per-property JSDoc that restated prop names (inconsistent with sibling root/placeholder style sub-objects) and a redundant internal prop comment. Keep the public menu block doc + @awsuiSystem core tag, and add a short note on the DropdownProps.Style background<-backgroundColor bridge. --- src/prompt-input/components/token-mode.tsx | 2 +- src/prompt-input/interfaces.ts | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/prompt-input/components/token-mode.tsx b/src/prompt-input/components/token-mode.tsx index 8c3374b9c2..c6aa8b3e45 100644 --- a/src/prompt-input/components/token-mode.tsx +++ b/src/prompt-input/components/token-mode.tsx @@ -54,7 +54,6 @@ interface TokenModeProps { i18nStrings?: PromptInputProps['i18nStrings']; maxMenuHeight?: number; - /** Style overrides forwarded to the menu dropdown. */ menuStyle?: PromptInputProps.Style['menu']; } @@ -124,6 +123,7 @@ export default function TokenMode({ style={ menuStyle ? ({ + // DropdownProps.Style names the fill `background`; PromptInput exposes it as `backgroundColor`. dropdown: { background: menuStyle.backgroundColor, borderColor: menuStyle.borderColor, diff --git a/src/prompt-input/interfaces.ts b/src/prompt-input/interfaces.ts index 393e1dda64..ee7569a7e3 100644 --- a/src/prompt-input/interfaces.ts +++ b/src/prompt-input/interfaces.ts @@ -582,21 +582,9 @@ export namespace PromptInputProps { * @awsuiSystem core */ menu?: { - /** - * Background color of the dropdown content wrapper. - */ backgroundColor?: string; - /** - * Border color of the dropdown content wrapper. - */ borderColor?: string; - /** - * Border radius of the dropdown content wrapper. - */ borderRadius?: string; - /** - * Border width of the dropdown content wrapper. - */ borderWidth?: string; }; }