mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: add truncation and tooltips (#10498)
This PR uses the existing Truncator component to add truncation and tooltips for long names.
This commit is contained in:
		
							parent
							
								
									05ea405bf6
								
							
						
					
					
						commit
						a99e5bc4b4
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -4,6 +4,7 @@ npm-debug | ||||
| .DS_Store | ||||
| /dist | ||||
| .vscode | ||||
| .claude | ||||
| 
 | ||||
| # Logs | ||||
| logs | ||||
|  | ||||
| @ -5,6 +5,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit | ||||
| import { TooltipLink } from 'component/common/TooltipLink/TooltipLink'; | ||||
| import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; | ||||
| import { Highlighter } from 'component/common/Highlighter/Highlighter'; | ||||
| import { Truncator } from 'component/common/Truncator/Truncator'; | ||||
| 
 | ||||
| const StyledBox = styled(Box)(({ theme }) => ({ | ||||
|     display: 'flex', | ||||
| @ -13,10 +14,7 @@ const StyledBox = styled(Box)(({ theme }) => ({ | ||||
|     padding: theme.spacing(1, 0, 1, 2), | ||||
| })); | ||||
| 
 | ||||
| const StyledLink = styled(Link)(({ theme }) => ({ | ||||
|     overflow: 'hidden', | ||||
|     textOverflow: 'ellipsis', | ||||
|     whiteSpace: 'nowrap', | ||||
| const StyledLink = styled(Link)(() => ({ | ||||
|     textDecoration: 'none', | ||||
|     '&:hover, &:focus': { | ||||
|         textDecoration: 'underline', | ||||
| @ -53,12 +51,13 @@ export const FeaturesCell: VFC<FeaturesCellProps> = ({ value, project }) => { | ||||
|                 show={featureNames?.map((featureName: string) => ( | ||||
|                     <StyledLink | ||||
|                         key={featureName} | ||||
|                         title={featureName} | ||||
|                         to={`/projects/${project}/features/${featureName}`} | ||||
|                     > | ||||
|                         <Highlighter search={searchQuery}> | ||||
|                             {featureName} | ||||
|                         </Highlighter> | ||||
|                         <Truncator lines={1} title={featureName} arrow> | ||||
|                             <Highlighter search={searchQuery}> | ||||
|                                 {featureName} | ||||
|                             </Highlighter> | ||||
|                         </Truncator> | ||||
|                     </StyledLink> | ||||
|                 ))} | ||||
|                 elseShow={ | ||||
| @ -69,12 +68,17 @@ export const FeaturesCell: VFC<FeaturesCellProps> = ({ value, project }) => { | ||||
|                                 {featureNames?.map((featureName: string) => ( | ||||
|                                     <StyledTooltipLink | ||||
|                                         key={featureName} | ||||
|                                         title={featureName} | ||||
|                                         to={`/projects/${project}/features/${featureName}`} | ||||
|                                     > | ||||
|                                         <Highlighter search={searchQuery}> | ||||
|                                             {featureName} | ||||
|                                         </Highlighter> | ||||
|                                         <Truncator | ||||
|                                             lines={1} | ||||
|                                             title={featureName} | ||||
|                                             arrow | ||||
|                                         > | ||||
|                                             <Highlighter search={searchQuery}> | ||||
|                                                 {featureName} | ||||
|                                             </Highlighter> | ||||
|                                         </Truncator> | ||||
|                                     </StyledTooltipLink> | ||||
|                                 ))} | ||||
|                             </StyledTooltipContainer> | ||||
|  | ||||
| @ -5,7 +5,7 @@ import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes'; | ||||
| import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons'; | ||||
| import { useSearchHighlightContext } from '../../SearchHighlightContext/SearchHighlightContext.tsx'; | ||||
| import { Highlighter } from '../../../Highlighter/Highlighter.tsx'; | ||||
| import { StyledDescription, StyledTitle } from '../LinkCell/LinkCell.styles'; | ||||
| import { StyledDescription } from '../LinkCell/LinkCell.styles'; | ||||
| import { Link } from 'react-router-dom'; | ||||
| import { Badge } from '../../../Badge/Badge.tsx'; | ||||
| import { HtmlTooltip } from '../../../HtmlTooltip/HtmlTooltip.tsx'; | ||||
| @ -15,6 +15,7 @@ import { useLocationSettings } from 'hooks/useLocationSettings'; | ||||
| import { getLocalizedDateString } from '../../../util.ts'; | ||||
| import { Tag } from 'component/common/Tag/Tag'; | ||||
| import { formatTag } from 'utils/format-tag'; | ||||
| import { Truncator } from 'component/common/Truncator/Truncator'; | ||||
| 
 | ||||
| interface IFeatureNameCellProps { | ||||
|     row: { | ||||
| @ -135,15 +136,20 @@ const FeatureName: FC<{ | ||||
|     return ( | ||||
|         <Box sx={(theme) => ({ fontWeight: theme.typography.fontWeightBold })}> | ||||
|             <StyledFeatureLink to={`/projects/${project}/features/${feature}`}> | ||||
|                 <StyledTitle | ||||
|                     style={{ | ||||
|                         WebkitLineClamp: 1, | ||||
|                         lineClamp: 1, | ||||
|                 <Truncator | ||||
|                     lines={1} | ||||
|                     title={feature} | ||||
|                     arrow | ||||
|                     sx={{ | ||||
|                         overflowWrap: 'anywhere', | ||||
|                     }} | ||||
|                 > | ||||
|                     <Highlighter search={searchQuery}>{feature}</Highlighter> | ||||
|                 </StyledTitle> | ||||
|                     <span> | ||||
|                         <Highlighter search={searchQuery}> | ||||
|                             {feature} | ||||
|                         </Highlighter> | ||||
|                     </span> | ||||
|                 </Truncator> | ||||
|             </StyledFeatureLink> | ||||
|         </Box> | ||||
|     ); | ||||
| @ -154,14 +160,18 @@ const ArchivedFeatureName: FC<{ | ||||
|     searchQuery: string; | ||||
| }> = ({ feature, searchQuery }) => { | ||||
|     return ( | ||||
|         <Box | ||||
|         <Truncator | ||||
|             lines={1} | ||||
|             title={feature} | ||||
|             arrow | ||||
|             sx={(theme) => ({ | ||||
|                 fontWeight: theme.typography.fontWeightBold, | ||||
|                 color: theme.palette.neutral.main, | ||||
|                 overflowWrap: 'anywhere', | ||||
|             })} | ||||
|         > | ||||
|             <Highlighter search={searchQuery}>{feature}</Highlighter> | ||||
|         </Box> | ||||
|         </Truncator> | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -5,6 +5,7 @@ import { useSearchHighlightContext } from 'component/common/Table/SearchHighligh | ||||
| import { Box, styled } from '@mui/material'; | ||||
| import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||
| import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; | ||||
| import { Truncator } from 'component/common/Truncator/Truncator'; | ||||
| 
 | ||||
| interface IHighlightCellProps { | ||||
|     value: string; | ||||
| @ -21,14 +22,7 @@ const StyledContainer = styled(Box)(({ theme }) => ({ | ||||
|     padding: theme.spacing(1, 2), | ||||
| })); | ||||
| 
 | ||||
| const StyledTitle = styled('span')(({ theme }) => ({ | ||||
|     overflow: 'hidden', | ||||
|     textOverflow: 'ellipsis', | ||||
|     display: '-webkit-box', | ||||
|     WebkitBoxOrient: 'vertical', | ||||
|     WebkitLineClamp: '1', | ||||
|     lineClamp: '1', | ||||
| })); | ||||
| const StyledTitle = styled('span')(() => ({})); | ||||
| 
 | ||||
| const StyledSubtitle = styled('span')(({ theme }) => ({ | ||||
|     color: theme.palette.text.secondary, | ||||
| @ -73,16 +67,17 @@ export const HighlightCell: FC<IHighlightCellProps> = ({ | ||||
| 
 | ||||
|     return ( | ||||
|         <StyledContainer> | ||||
|             <StyledTitle | ||||
|                 style={{ | ||||
|                     WebkitLineClamp: subtitle ? 1 : 2, | ||||
|                     lineClamp: subtitle ? 1 : 2, | ||||
|                 }} | ||||
|             <Truncator | ||||
|                 lines={subtitle ? 1 : 2} | ||||
|                 title={value} | ||||
|                 arrow | ||||
|                 data-loading | ||||
|             > | ||||
|                 <Highlighter search={searchQuery}>{value}</Highlighter> | ||||
|                 {afterTitle} | ||||
|             </StyledTitle> | ||||
|                 <StyledTitle> | ||||
|                     <Highlighter search={searchQuery}>{value}</Highlighter> | ||||
|                     {afterTitle} | ||||
|                 </StyledTitle> | ||||
|             </Truncator> | ||||
|             <ConditionallyRender | ||||
|                 condition={Boolean(subtitle)} | ||||
|                 show={renderSubtitle} | ||||
|  | ||||
| @ -33,13 +33,6 @@ export const StyledContainer = styled('div')(({ theme }) => ({ | ||||
|     wordBreak: 'break-all', | ||||
| })); | ||||
| 
 | ||||
| export const StyledTitle = styled('span')(({ theme }) => ({ | ||||
|     overflow: 'hidden', | ||||
|     textOverflow: 'ellipsis', | ||||
|     display: '-webkit-box', | ||||
|     WebkitBoxOrient: 'vertical', | ||||
| })); | ||||
| 
 | ||||
| export const StyledDescription = styled('span')(({ theme }) => ({ | ||||
|     color: theme.palette.text.secondary, | ||||
|     textDecoration: 'none', | ||||
|  | ||||
| @ -4,11 +4,11 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit | ||||
| import { Highlighter } from 'component/common/Highlighter/Highlighter'; | ||||
| import { useSearchHighlightContext } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext'; | ||||
| import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip'; | ||||
| import { Truncator } from 'component/common/Truncator/Truncator'; | ||||
| import { | ||||
|     StyledWrapper, | ||||
|     StyledLink, | ||||
|     StyledContainer, | ||||
|     StyledTitle, | ||||
|     StyledDescription, | ||||
| } from './LinkCell.styles'; | ||||
| 
 | ||||
| @ -51,16 +51,17 @@ export const LinkCell: React.FC<ILinkCellProps> = ({ | ||||
| 
 | ||||
|     const content = ( | ||||
|         <StyledContainer> | ||||
|             <StyledTitle | ||||
|             <Truncator | ||||
|                 lines={subtitle ? 1 : 2} | ||||
|                 title={title} | ||||
|                 arrow | ||||
|                 data-loading | ||||
|                 style={{ | ||||
|                     WebkitLineClamp: subtitle ? 1 : 2, | ||||
|                     lineClamp: subtitle ? 1 : 2, | ||||
|                 }} | ||||
|             > | ||||
|                 <Highlighter search={searchQuery}>{title}</Highlighter> | ||||
|                 {children} | ||||
|             </StyledTitle> | ||||
|                 <span> | ||||
|                     <Highlighter search={searchQuery}>{title}</Highlighter> | ||||
|                     {children} | ||||
|                 </span> | ||||
|             </Truncator> | ||||
|             <ConditionallyRender | ||||
|                 condition={Boolean(subtitle)} | ||||
|                 show={renderSubtitle} | ||||
|  | ||||
| @ -275,16 +275,21 @@ exports[`renders an empty list correctly 1`] = ` | ||||
|                       className="css-u8cmsa" | ||||
|                     > | ||||
|                       <span | ||||
|                         className="css-697v50" | ||||
|                         aria-label="" | ||||
|                         aria-labelledby={null} | ||||
|                         className=" MuiBox-root css-gzore8" | ||||
|                         data-loading={true} | ||||
|                         style={ | ||||
|                           { | ||||
|                             "WebkitLineClamp": 1, | ||||
|                             "lineClamp": 1, | ||||
|                           } | ||||
|                         } | ||||
|                         data-mui-internal-clone-element={true} | ||||
|                         onBlur={[Function]} | ||||
|                         onFocus={[Function]} | ||||
|                         onMouseLeave={[Function]} | ||||
|                         onMouseOver={[Function]} | ||||
|                         onTouchEnd={[Function]} | ||||
|                         onTouchStart={[Function]} | ||||
|                       > | ||||
|                         Tag type name | ||||
|                         <span> | ||||
|                           Tag type name | ||||
|                         </span> | ||||
|                       </span> | ||||
|                       <span | ||||
|                         className="css-1121jr7" | ||||
| @ -449,16 +454,21 @@ exports[`renders an empty list correctly 1`] = ` | ||||
|                       className="css-u8cmsa" | ||||
|                     > | ||||
|                       <span | ||||
|                         className="css-697v50" | ||||
|                         aria-label="" | ||||
|                         aria-labelledby={null} | ||||
|                         className=" MuiBox-root css-gzore8" | ||||
|                         data-loading={true} | ||||
|                         style={ | ||||
|                           { | ||||
|                             "WebkitLineClamp": 1, | ||||
|                             "lineClamp": 1, | ||||
|                           } | ||||
|                         } | ||||
|                         data-mui-internal-clone-element={true} | ||||
|                         onBlur={[Function]} | ||||
|                         onFocus={[Function]} | ||||
|                         onMouseLeave={[Function]} | ||||
|                         onMouseOver={[Function]} | ||||
|                         onTouchEnd={[Function]} | ||||
|                         onTouchStart={[Function]} | ||||
|                       > | ||||
|                         Tag type name | ||||
|                         <span> | ||||
|                           Tag type name | ||||
|                         </span> | ||||
|                       </span> | ||||
|                       <span | ||||
|                         className="css-1121jr7" | ||||
| @ -623,16 +633,21 @@ exports[`renders an empty list correctly 1`] = ` | ||||
|                       className="css-u8cmsa" | ||||
|                     > | ||||
|                       <span | ||||
|                         className="css-697v50" | ||||
|                         aria-label="" | ||||
|                         aria-labelledby={null} | ||||
|                         className=" MuiBox-root css-gzore8" | ||||
|                         data-loading={true} | ||||
|                         style={ | ||||
|                           { | ||||
|                             "WebkitLineClamp": 1, | ||||
|                             "lineClamp": 1, | ||||
|                           } | ||||
|                         } | ||||
|                         data-mui-internal-clone-element={true} | ||||
|                         onBlur={[Function]} | ||||
|                         onFocus={[Function]} | ||||
|                         onMouseLeave={[Function]} | ||||
|                         onMouseOver={[Function]} | ||||
|                         onTouchEnd={[Function]} | ||||
|                         onTouchStart={[Function]} | ||||
|                       > | ||||
|                         Tag type name | ||||
|                         <span> | ||||
|                           Tag type name | ||||
|                         </span> | ||||
|                       </span> | ||||
|                       <span | ||||
|                         className="css-1121jr7" | ||||
| @ -797,16 +812,21 @@ exports[`renders an empty list correctly 1`] = ` | ||||
|                       className="css-u8cmsa" | ||||
|                     > | ||||
|                       <span | ||||
|                         className="css-697v50" | ||||
|                         aria-label="" | ||||
|                         aria-labelledby={null} | ||||
|                         className=" MuiBox-root css-gzore8" | ||||
|                         data-loading={true} | ||||
|                         style={ | ||||
|                           { | ||||
|                             "WebkitLineClamp": 1, | ||||
|                             "lineClamp": 1, | ||||
|                           } | ||||
|                         } | ||||
|                         data-mui-internal-clone-element={true} | ||||
|                         onBlur={[Function]} | ||||
|                         onFocus={[Function]} | ||||
|                         onMouseLeave={[Function]} | ||||
|                         onMouseOver={[Function]} | ||||
|                         onTouchEnd={[Function]} | ||||
|                         onTouchStart={[Function]} | ||||
|                       > | ||||
|                         Tag type name | ||||
|                         <span> | ||||
|                           Tag type name | ||||
|                         </span> | ||||
|                       </span> | ||||
|                       <span | ||||
|                         className="css-1121jr7" | ||||
| @ -971,16 +991,21 @@ exports[`renders an empty list correctly 1`] = ` | ||||
|                       className="css-u8cmsa" | ||||
|                     > | ||||
|                       <span | ||||
|                         className="css-697v50" | ||||
|                         aria-label="" | ||||
|                         aria-labelledby={null} | ||||
|                         className=" MuiBox-root css-gzore8" | ||||
|                         data-loading={true} | ||||
|                         style={ | ||||
|                           { | ||||
|                             "WebkitLineClamp": 1, | ||||
|                             "lineClamp": 1, | ||||
|                           } | ||||
|                         } | ||||
|                         data-mui-internal-clone-element={true} | ||||
|                         onBlur={[Function]} | ||||
|                         onFocus={[Function]} | ||||
|                         onMouseLeave={[Function]} | ||||
|                         onMouseOver={[Function]} | ||||
|                         onTouchEnd={[Function]} | ||||
|                         onTouchStart={[Function]} | ||||
|                       > | ||||
|                         Tag type name | ||||
|                         <span> | ||||
|                           Tag type name | ||||
|                         </span> | ||||
|                       </span> | ||||
|                       <span | ||||
|                         className="css-1121jr7" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user