66 */
77
88import React from 'react' ;
9+ import type { ReactNode } from 'react' ;
910import {
1011 EuiBadge ,
1112 EuiButtonIcon ,
1213 EuiFlexGroup ,
1314 EuiFlexItem ,
15+ EuiIcon ,
1416 EuiSplitPanel ,
15- EuiText ,
17+ EuiTitle ,
1618 useEuiTheme ,
1719} from '@elastic/eui' ;
20+ import type { IconType } from '@elastic/eui' ;
1821import { css } from '@emotion/react' ;
1922import type { ActionButton } from '@kbn/agent-builder-browser/attachments' ;
2023import { i18n } from '@kbn/i18n' ;
@@ -39,6 +42,10 @@ export const HEADER_HEIGHT = 72;
3942
4043interface AttachmentHeaderProps {
4144 title : string ;
45+ /** Optional icon rendered to the left of the title, sized to span title + badge height. */
46+ icon ?: IconType ;
47+ /** Optional badge or content rendered below the title, inside the header. */
48+ headerBadge ?: ReactNode ;
4249 actionButtons ?: ActionButton [ ] ;
4350 onClose ?: ( ) => void ;
4451 /**
@@ -52,19 +59,14 @@ interface AttachmentHeaderProps {
5259
5360export const AttachmentHeader : React . FC < AttachmentHeaderProps > = ( {
5461 title,
62+ icon,
63+ headerBadge,
5564 actionButtons,
5665 onClose,
5766 previewBadgeState = 'none' ,
5867} ) => {
5968 const { euiTheme } = useEuiTheme ( ) ;
6069
61- const textStyles = css `
62- font-weight : ${ euiTheme . font . weight . semiBold } ;
63- overflow : hidden;
64- white-space : nowrap;
65- text-overflow : ellipsis;
66- ` ;
67-
6870 const headerStyles = css `
6971 position : relative;
7072 display : flex;
@@ -82,7 +84,17 @@ export const AttachmentHeader: React.FC<AttachmentHeaderProps> = ({
8284 z-index : ${ euiTheme . levels . content } ;
8385 ` ;
8486
85- if ( ! actionButtons || actionButtons . length === 0 ) {
87+ const iconContainerStyles = css `
88+ border-right : ${ euiTheme . border . thin } ;
89+ padding : ${ euiTheme . size . m } ;
90+ padding-left : 0 ;
91+ display : flex;
92+ align-items : center;
93+ justify-content : center;
94+ flex-shrink : 0 ;
95+ ` ;
96+
97+ if ( ! actionButtons ?. length && ! icon && ! headerBadge ) {
8698 return null ;
8799 }
88100
@@ -98,17 +110,36 @@ export const AttachmentHeader: React.FC<AttachmentHeaderProps> = ({
98110 justifyContent = "spaceBetween"
99111 alignItems = "center"
100112 style = { { width : '100%' } }
113+ gutterSize = "s"
101114 >
115+ { icon && (
116+ < EuiFlexItem grow = { false } >
117+ < div css = { iconContainerStyles } >
118+ < EuiIcon type = { icon } size = "l" color = "subdued" aria-hidden = { true } />
119+ </ div >
120+ </ EuiFlexItem >
121+ ) }
102122 < EuiFlexItem grow = { true } style = { { minWidth : 0 } } >
103- < EuiText css = { textStyles } size = "s" >
104- { title }
105- </ EuiText >
123+ < EuiFlexGroup
124+ direction = "column"
125+ gutterSize = "xs"
126+ alignItems = "flexStart"
127+ responsive = { false }
128+ >
129+ < EuiFlexItem grow = { false } >
130+ < EuiTitle size = "xs" >
131+ { /* h3 would be semantically preferred, but browser UA styles override EuiTitle's size prop here; h5 native size is close enough to xs that it doesn't. */ }
132+ < h5 > { title } </ h5 >
133+ </ EuiTitle >
134+ </ EuiFlexItem >
135+ { headerBadge && < EuiFlexItem grow = { false } > { headerBadge } </ EuiFlexItem > }
136+ </ EuiFlexGroup >
106137 </ EuiFlexItem >
107- { previewBadgeState !== 'previewing' && (
138+ { previewBadgeState !== 'previewing' && actionButtons ?. length ? (
108139 < EuiFlexItem grow = { false } style = { { flexShrink : 0 } } >
109140 < AttachmentActions buttons = { actionButtons } />
110141 </ EuiFlexItem >
111- ) }
142+ ) : null }
112143 { previewBadgeState === 'previewing' && (
113144 < EuiFlexItem grow = { false } style = { { flexShrink : 0 } } >
114145 < EuiBadge iconType = "eye" color = "success" >
0 commit comments