Skip to content

Commit 7ef87b1

Browse files
authored
Merge pull request #235 from devtron-labs/feat/input-ref-search-bar
feat: add input ref support for search bar component & make Tippy dynamic such that it only shows on truncate
2 parents 6ee05a8 + 551c39a commit 7ef87b1

File tree

18 files changed

+133
-119
lines changed

18 files changed

+133
-119
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "0.2.1",
3+
"version": "0.2.2",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

src/Common/AddCDButton/AddCDButton.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import React from 'react'
1817
import Tippy from '@tippyjs/react'
1918
import { AddCDButtonProps, TooltipContentProps } from './types'
2019
import { AddCDPositions } from '../Types'

src/Common/ClipboardButton/ClipboardButton.tsx

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export default function ClipboardButton({
5252
},
5353
[content],
5454
)
55+
const iconClassName = `icon-dim-${iconSize} dc__no-shrink`
5556

5657
useEffect(() => {
5758
if (!copied) return
@@ -71,28 +72,22 @@ export default function ClipboardButton({
7172
}
7273
}, [trigger, handleCopyContent])
7374
return (
74-
<div className="icon-dim-16 flex center">
75-
<Tippy
76-
className="default-tt"
77-
content={copied ? copiedTippyText : 'Copy'}
78-
placement="bottom"
79-
visible={copied || enableTippy}
80-
arrow={false}
75+
<Tippy
76+
className="default-tt"
77+
content={copied ? copiedTippyText : 'Copy'}
78+
placement="bottom"
79+
visible={copied || enableTippy}
80+
arrow={false}
81+
>
82+
<button
83+
type="button"
84+
className={`dc__outline-none-imp p-0 flex dc__transparent--unstyled dc__no-border ${rootClassName}`}
85+
onMouseEnter={handleEnableTippy}
86+
onMouseLeave={handleDisableTippy}
87+
onClick={handleCopyContent}
8188
>
82-
<button
83-
type="button"
84-
className={`dc__outline-none-imp p-0 flex bcn-0 dc__no-border ${rootClassName}`}
85-
onMouseEnter={handleEnableTippy}
86-
onMouseLeave={handleDisableTippy}
87-
onClick={handleCopyContent}
88-
>
89-
{copied ? (
90-
<Check className={`icon-dim-${iconSize}`} />
91-
) : (
92-
<ICCopy className={`icon-dim-${iconSize}`} />
93-
)}
94-
</button>
95-
</Tippy>
96-
</div>
89+
{copied ? <Check className={iconClassName} /> : <ICCopy className={iconClassName} />}
90+
</button>
91+
</Tippy>
9792
)
9893
}

src/Common/RJSF/common/FieldRow.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
import React from 'react'
18-
import { ConditionalWrap } from '../../Helper'
17+
import { Tooltip } from '@Common/Tooltip'
1918
import { FieldRowProps } from './types'
2019
import { DEFAULT_FIELD_TITLE } from '../constants'
21-
import { getTippyWrapperWithContent } from '../utils'
2220

2321
export const FieldRowWithLabel = ({
2422
showLabel,
@@ -38,11 +36,11 @@ export const FieldRowWithLabel = ({
3836
>
3937
{showLabel && (
4038
<label className="cn-7 fs-13 lh-20 fw-4 flexbox mb-0" htmlFor={id}>
41-
<ConditionalWrap condition={!!rawDescription} wrap={getTippyWrapperWithContent(rawDescription, 'top')}>
39+
<Tooltip alwaysShowTippyOnHover={!!rawDescription} content={rawDescription}>
4240
<span className={`dc__ellipsis-right ${rawDescription ? 'text-underline-dashed-300' : ''}`}>
4341
{label || DEFAULT_FIELD_TITLE}
4442
</span>
45-
</ConditionalWrap>
43+
</Tooltip>
4644
{required && <span className="cr-5">&nbsp;*</span>}
4745
</label>
4846
)}

src/Common/RJSF/constants.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,3 @@ export const PLACEHOLDERS = {
2121
}
2222

2323
export const DEFAULT_FIELD_TITLE = 'Key not available'
24-
25-
export const ADD_BUTTON_WIDTH = {
26-
MAX_WIDTH_VALUE: 250,
27-
MAX_WIDTH_CLASSNAME: 'dc__mxw-250',
28-
}

src/Common/RJSF/templates/ButtonTemplates/AddButton.tsx

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616

1717
import { IconButtonProps } from '@rjsf/utils'
1818

19-
import Tippy from '../../../Tippy'
20-
import { ADD_BUTTON_WIDTH } from '../../constants'
19+
import { Tooltip } from '@Common/Tooltip'
2120
import { ReactComponent as PlusIcon } from '../../../../Assets/Icon/ic-add.svg'
2221

2322
export const AddButton = ({
@@ -32,23 +31,17 @@ export const AddButton = ({
3231

3332
return (
3433
<div className="flexbox flex-justify-start">
35-
<Tippy
36-
className="default-tt dc__word-break"
37-
arrow={false}
38-
placement="right"
39-
content={content}
40-
truncateWidth={ADD_BUTTON_WIDTH.MAX_WIDTH_VALUE}
34+
<button
35+
{...props}
36+
type="button"
37+
className="dc__outline-none-imp p-0 dc__transparent flex dc__gap-4 cursor dc__mxw-250"
38+
title="Add"
4139
>
42-
<button
43-
{...props}
44-
type="button"
45-
className={`dc__outline-none-imp p-0 dc__transparent flex dc__gap-4 cursor ${ADD_BUTTON_WIDTH.MAX_WIDTH_CLASSNAME}`}
46-
title="Add"
47-
>
48-
<PlusIcon className="icon-dim-16 fcb-5" />
40+
<PlusIcon className="icon-dim-16 fcb-5" />
41+
<Tooltip placement="right" content={content}>
4942
<span className="cb-5 fs-13 lh-34 dc__truncate">{content}</span>
50-
</button>
51-
</Tippy>
43+
</Tooltip>
44+
</button>
5245
</div>
5346
)
5447
}

src/Common/RJSF/templates/TitleField.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,14 @@
1414
* limitations under the License.
1515
*/
1616

17-
import React from 'react'
18-
import { ConditionalWrap } from '../../Helper'
1917
import { TitleFieldProps } from '@rjsf/utils'
20-
import { getTippyWrapperWithContent } from '../utils'
18+
import { Tooltip } from '@Common/Tooltip'
2119

2220
export const TitleField = ({ id, title, required, description }: TitleFieldProps & Partial<Record<'description', string>>) => (
2321
<legend className="fs-13 fw-6 cn-9 lh-20 dc__no-border py-9 mb-0" id={id}>
24-
<ConditionalWrap condition={!!description} wrap={getTippyWrapperWithContent(description, 'top')}>
22+
<Tooltip alwaysShowTippyOnHover={!!description} content={description}>
2523
<span className={`${description ? 'text-underline-dashed-300' : ''}`}>{title}</span>
26-
</ConditionalWrap>
24+
</Tooltip>
2725
{required && <span className="cr-5">&nbsp;*</span>}
2826
</legend>
2927
)

src/Common/RJSF/utils.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
import { TranslatableString, englishStringTranslator } from '@rjsf/utils'
18-
import Tippy from '../Tippy'
1918

2019
/**
2120
* Override for the TranslatableString from RJSF
@@ -136,18 +135,3 @@ export const getInferredTypeFromValueType = (value) => {
136135
return 'null'
137136
}
138137
}
139-
140-
export const getTippyWrapperWithContent =
141-
(content, placement?: React.ComponentProps<typeof Tippy>['placement'], truncateWidth = 0) =>
142-
(children) => (
143-
<Tippy
144-
className="default-tt"
145-
maxWidth={300}
146-
arrow={false}
147-
placement={placement || 'right'}
148-
content={content}
149-
truncateWidth={truncateWidth}
150-
>
151-
{children}
152-
</Tippy>
153-
)

src/Common/SearchBar/SearchBar.component.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ const SearchBar = ({
116116
}
117117
}
118118

119+
const inputCallbackRef: React.RefCallback<HTMLInputElement> = (node = null) => {
120+
if (inputProps.ref) {
121+
// eslint-disable-next-line no-param-reassign
122+
inputProps.ref.current = node
123+
}
124+
inputRef.current = node
125+
}
126+
119127
return (
120128
<div className={containerClassName}>
121129
<div
@@ -133,7 +141,7 @@ const SearchBar = ({
133141
} ${noBackgroundAndBorder ? 'dc__no-background' : 'bc-n50'}`}
134142
onChange={handleChange}
135143
onKeyDown={handleKeyDown}
136-
ref={inputRef}
144+
ref={inputCallbackRef}
137145
/>
138146
{/* TODO: Sync with product since it should have ic-enter in case of not applied */}
139147
{showClearButton && (

src/Common/SearchBar/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export interface SearchBarProps {
3434
/**
3535
* Input props for the search input
3636
*/
37-
inputProps?: React.InputHTMLAttributes<HTMLInputElement>
37+
inputProps?: React.InputHTMLAttributes<HTMLInputElement> &
38+
Partial<Record<'ref', React.MutableRefObject<HTMLInputElement>>>
3839
/**
3940
* Class name for the container; can be used for handling width
4041
*/

src/Common/SortableTableHeaderCell/SortableTableHeaderCell.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { Tooltip } from '@Common/Tooltip'
1718
import { ReactComponent as SortIcon } from '../../Assets/Icon/ic-arrow-up-down.svg'
1819
import { ReactComponent as SortArrowDown } from '../../Assets/Icon/ic-sort-arrow-down.svg'
1920
import { SortingOrder } from '../Constants'
@@ -41,6 +42,7 @@ const SortableTableHeaderCell = ({
4142
title,
4243
disabled,
4344
isSortable = true,
45+
showTippyOnTruncate = false,
4446
}: SortableTableHeaderCellProps) => {
4547
const renderSortIcon = () => {
4648
if (!isSortable) {
@@ -65,7 +67,9 @@ const SortableTableHeaderCell = ({
6567
onClick={isSortable ? triggerSorting : noop}
6668
disabled={disabled}
6769
>
68-
<span className="dc__uppercase dc__ellipsis-right">{title}</span>
70+
<Tooltip showOnTruncate={showTippyOnTruncate} content={title}>
71+
<span className="dc__uppercase dc__ellipsis-right">{title}</span>
72+
</Tooltip>
6973
{renderSortIcon()}
7074
</button>
7175
)

src/Common/SortableTableHeaderCell/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,9 @@ export interface SortableTableHeaderCellProps {
4444
* @default true
4545
*/
4646
isSortable?: boolean
47+
/**
48+
* If true, the tippy is shown on Sortable header if text is truncated
49+
* @default false
50+
*/
51+
showTippyOnTruncate?: boolean
4752
}

src/Common/Tippy.tsx

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/Common/Tooltip/Tooltip.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useCallback, useState, cloneElement } from 'react'
2+
import TippyJS from '@tippyjs/react'
3+
import { TooltipProps } from './types'
4+
5+
const Tooltip = ({
6+
alwaysShowTippyOnHover,
7+
// NOTE: if alwaysShowTippyOnHover is being passed by user don't apply truncation logic at all
8+
showOnTruncate = alwaysShowTippyOnHover === undefined,
9+
wordBreak = true,
10+
children: child,
11+
...rest
12+
}: TooltipProps) => {
13+
const [isTextTruncated, setIsTextTruncated] = useState(false)
14+
15+
const refCallback = useCallback((node: HTMLDivElement) => {
16+
if (node) {
17+
// NOTE: for line-clamp we need to check scrollHeight against clientHeight since orientation
18+
// is set to vertical through -webkit-box-orient prop that is needed for line-clamp to work
19+
// see: https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp
20+
setIsTextTruncated(node.scrollWidth > node.clientWidth || node.scrollHeight > node.clientHeight)
21+
}
22+
}, [])
23+
24+
return (!isTextTruncated || !showOnTruncate) && !alwaysShowTippyOnHover ? (
25+
cloneElement(child, { ...child.props, ref: refCallback })
26+
) : (
27+
<TippyJS
28+
arrow={false}
29+
placement="top"
30+
{...rest}
31+
className={`default-tt ${wordBreak ? 'dc__word-break-all' : ''} dc__mxw-200 ${rest.className}`}
32+
>
33+
{cloneElement(child, { ...child.props, ref: refCallback })}
34+
</TippyJS>
35+
)
36+
}
37+
38+
export default Tooltip

src/Common/Tooltip/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as Tooltip } from './Tooltip'

0 commit comments

Comments
 (0)