@devtron-labs/devtron-fe-common-lib 0.0.54 → 0.0.55-beta-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +16 -84
- package/.github/workflows/release-package.yml +3 -2
- package/dist/Common/Common.service.d.ts +2 -2
- package/dist/Common/Constants.d.ts +0 -1
- package/dist/Common/DebouncedSearch/DebouncedSearch.d.ts +0 -2
- package/dist/Common/Grid/Grid.d.ts +1 -1
- package/dist/Common/Grid/types.d.ts +2 -2
- package/dist/Common/Helper.d.ts +4 -5
- package/dist/Common/Hooks/index.d.ts +0 -1
- package/dist/Common/Types.d.ts +2 -15
- package/dist/Common/index.d.ts +0 -2
- package/dist/index.js +225 -474
- package/package.json +3 -21
- package/src/Common/Constants.ts +1 -3
- package/src/Common/DebouncedSearch/DebouncedSearch.tsx +0 -2
- package/src/Common/Grid/Grid.tsx +2 -7
- package/src/Common/Grid/types.ts +1 -3
- package/src/Common/Helper.tsx +23 -31
- package/src/Common/Hooks/index.ts +0 -1
- package/src/Common/Types.ts +2 -15
- package/src/Common/index.ts +0 -2
- package/.eslintignore +0 -96
- package/.github/pull_request_template.md +0 -25
- package/.github/workflows/ci.yml +0 -31
- package/.husky/pre-commit +0 -5
- package/.lintstagedrc +0 -3
- package/.nvmrc +0 -1
- package/dist/Common/DraggableWrapper/DraggableButton.d.ts +0 -3
- package/dist/Common/DraggableWrapper/DraggableWrapper.d.ts +0 -9
- package/dist/Common/DraggableWrapper/index.d.ts +0 -3
- package/dist/Common/DraggableWrapper/types.d.ts +0 -23
- package/dist/Common/Hooks/UseWindowSize/UseWindowSize.d.ts +0 -4
- package/dist/Common/SearchBar/SearchBar.component.d.ts +0 -39
- package/dist/Common/SearchBar/index.d.ts +0 -2
- package/dist/Common/SearchBar/types.d.ts +0 -35
- package/src/Assets/Icon/ic-drag.svg +0 -8
- package/src/Assets/Icon/ic-search.svg +0 -6
- package/src/Common/DraggableWrapper/DraggableButton.tsx +0 -14
- package/src/Common/DraggableWrapper/DraggableWrapper.tsx +0 -116
- package/src/Common/DraggableWrapper/index.ts +0 -3
- package/src/Common/DraggableWrapper/types.ts +0 -27
- package/src/Common/Hooks/UseWindowSize/UseWindowSize.tsx +0 -31
- package/src/Common/SearchBar/SearchBar.component.tsx +0 -120
- package/src/Common/SearchBar/index.ts +0 -2
- package/src/Common/SearchBar/searchBar.scss +0 -31
- package/src/Common/SearchBar/types.ts +0 -36
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useRef, useState } from 'react'
|
|
2
|
-
import Draggable, { ControlPosition, DraggableData } from 'react-draggable'
|
|
3
|
-
import { DraggableWrapperProps, DraggablePositionVariant } from './types'
|
|
4
|
-
import { useWindowSize } from '../Hooks'
|
|
5
|
-
import { MAX_Z_INDEX } from '../Constants'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* TODO: import it as lazy, after it is supported in common
|
|
9
|
-
* 1. If using react select please use menuPlacement='auto'
|
|
10
|
-
* 2. dragSelector will be used to identify the grabbable button that will grab the div to drag
|
|
11
|
-
* 3. parentRef is the reference point from which we will derive the base top:0 ,left: 0 position
|
|
12
|
-
*/
|
|
13
|
-
export default function DraggableWrapper({
|
|
14
|
-
children,
|
|
15
|
-
zIndex = MAX_Z_INDEX,
|
|
16
|
-
positionVariant,
|
|
17
|
-
dragSelector,
|
|
18
|
-
parentRef,
|
|
19
|
-
boundaryGap = 16,
|
|
20
|
-
childDivProps = {},
|
|
21
|
-
}: DraggableWrapperProps) {
|
|
22
|
-
const windowSize = useWindowSize()
|
|
23
|
-
const nodeRef = useRef<HTMLDivElement>(null)
|
|
24
|
-
|
|
25
|
-
const [position, setPosition] = useState<ControlPosition>({
|
|
26
|
-
x: 0,
|
|
27
|
-
y: 0,
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
const getDefaultPosition = (positionVariant: DraggablePositionVariant): ControlPosition => {
|
|
31
|
-
// if this return x: 0, y: 0 then it will be top left corner of parentDiv
|
|
32
|
-
const parentRect =
|
|
33
|
-
parentRef?.current?.getBoundingClientRect() ??
|
|
34
|
-
({
|
|
35
|
-
width: 0,
|
|
36
|
-
height: 0,
|
|
37
|
-
top: 0,
|
|
38
|
-
left: 0,
|
|
39
|
-
bottom: 0,
|
|
40
|
-
} as DOMRect)
|
|
41
|
-
const nodeRefHeight = nodeRef.current?.getBoundingClientRect().height ?? 0
|
|
42
|
-
const nodeRefWidth = nodeRef.current?.getBoundingClientRect().width ?? 0
|
|
43
|
-
|
|
44
|
-
switch (positionVariant) {
|
|
45
|
-
case DraggablePositionVariant.PARENT_BOTTOM_CENTER: {
|
|
46
|
-
// currently at parentRect.x and need to start to the center of its width and half of node should lie on left of center and other half on right
|
|
47
|
-
const x = (parentRect.width - nodeRefWidth) / 2
|
|
48
|
-
// currently at parentRect.y now parent height can be greater than windowSize.height so taking min
|
|
49
|
-
// subtracting parentRect.top since window height already contains that
|
|
50
|
-
const baseY =
|
|
51
|
-
parentRect.height > windowSize.height ? windowSize.height - parentRect.top : parentRect.height
|
|
52
|
-
const y = baseY - nodeRefHeight - boundaryGap
|
|
53
|
-
return { x, y }
|
|
54
|
-
}
|
|
55
|
-
// Add more cases for other variants if needed
|
|
56
|
-
default: {
|
|
57
|
-
// Since need node to be in center of screen so subtracting width/2 by left of parentRect it will start the node from center but want node's midpoint at center so subtracting node's width from it.
|
|
58
|
-
const x = windowSize.width / 2 - parentRect.left - nodeRefWidth / 2
|
|
59
|
-
// subtracting top since windowSize already contains that
|
|
60
|
-
const y = windowSize.height - parentRect.top - nodeRefHeight - boundaryGap
|
|
61
|
-
|
|
62
|
-
return { x, y }
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// On change of windowSize we will reset the position to default
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
const defaultPosition = getDefaultPosition(positionVariant)
|
|
70
|
-
setPosition(defaultPosition)
|
|
71
|
-
}, [nodeRef, positionVariant, windowSize])
|
|
72
|
-
|
|
73
|
-
// Would be called on drag and will not update the state if the new position is out of window screen
|
|
74
|
-
function handlePositionChange(e, data: DraggableData) {
|
|
75
|
-
const offsetX = parentRef?.current?.getBoundingClientRect().left ?? 0
|
|
76
|
-
const offsetY = parentRef?.current?.getBoundingClientRect().top ?? 0
|
|
77
|
-
|
|
78
|
-
const nodeRefHeight = nodeRef.current?.getBoundingClientRect().height ?? 0
|
|
79
|
-
const nodeRefWidth = nodeRef.current?.getBoundingClientRect().width ?? 0
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
offsetX + data.x + nodeRefWidth + boundaryGap > windowSize.width ||
|
|
83
|
-
offsetY + data.y + nodeRefHeight + boundaryGap > windowSize.height ||
|
|
84
|
-
offsetX + data.x < 0 ||
|
|
85
|
-
offsetY + data.y < 0
|
|
86
|
-
) {
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
setPosition({
|
|
91
|
-
x: data.x,
|
|
92
|
-
y: data.y,
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<div
|
|
98
|
-
className="dc__position-fixed"
|
|
99
|
-
style={{
|
|
100
|
-
zIndex,
|
|
101
|
-
}}
|
|
102
|
-
>
|
|
103
|
-
<Draggable handle={dragSelector} nodeRef={nodeRef} position={position} onDrag={handlePositionChange}>
|
|
104
|
-
<div
|
|
105
|
-
ref={nodeRef}
|
|
106
|
-
{...childDivProps}
|
|
107
|
-
style={{
|
|
108
|
-
zIndex,
|
|
109
|
-
}}
|
|
110
|
-
>
|
|
111
|
-
{children}
|
|
112
|
-
</div>
|
|
113
|
-
</Draggable>
|
|
114
|
-
</div>
|
|
115
|
-
)
|
|
116
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { HTMLAttributes, ReactNode, RefObject } from 'react'
|
|
2
|
-
|
|
3
|
-
export enum DraggablePositionVariant {
|
|
4
|
-
PARENT_BOTTOM_CENTER = 'PARENT_BOTTOM_CENTER',
|
|
5
|
-
SCREEN_BOTTOM_CENTER = 'SCREEN_BOTTOM_CENTER',
|
|
6
|
-
// Can add more based on requirement
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface DraggableWrapperProps {
|
|
10
|
-
children: ReactNode
|
|
11
|
-
zIndex?: number
|
|
12
|
-
positionVariant?: DraggablePositionVariant
|
|
13
|
-
/**
|
|
14
|
-
* dragSelector (class - (append with .), id, etc) will be used to identify the grabbable button that will grab the div to drag
|
|
15
|
-
*/
|
|
16
|
-
dragSelector: string
|
|
17
|
-
parentRef?: RefObject<HTMLDivElement>
|
|
18
|
-
boundaryGap?: number
|
|
19
|
-
childDivProps?: HTMLAttributes<HTMLDivElement>
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* dragClassName is the class that we feed to Draggable to identify dragging buttons
|
|
24
|
-
*/
|
|
25
|
-
export interface DraggableButtonProps {
|
|
26
|
-
dragClassName: string
|
|
27
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react'
|
|
2
|
-
|
|
3
|
-
let timeout
|
|
4
|
-
|
|
5
|
-
const getSize = () => {
|
|
6
|
-
return {
|
|
7
|
-
width: window.innerWidth,
|
|
8
|
-
height: window.innerHeight,
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const useWindowSize = () => {
|
|
13
|
-
const [windowSize, setWindowSize] = useState(getSize)
|
|
14
|
-
|
|
15
|
-
function handleResize(e) {
|
|
16
|
-
if (timeout) {
|
|
17
|
-
window.cancelAnimationFrame(timeout)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
timeout = window.requestAnimationFrame(function () {
|
|
21
|
-
setWindowSize(getSize())
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
window.addEventListener('resize', handleResize, false)
|
|
27
|
-
return () => window.removeEventListener('resize', handleResize, false)
|
|
28
|
-
}, [])
|
|
29
|
-
|
|
30
|
-
return windowSize
|
|
31
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { ChangeEvent, useCallback, useRef, useState, KeyboardEvent } from 'react'
|
|
2
|
-
import { ReactComponent as Search } from '../../Assets/Icon/ic-search.svg'
|
|
3
|
-
import { ReactComponent as Clear } from '../../Assets/Icon/ic-error-cross.svg'
|
|
4
|
-
import { SearchBarProps } from './types'
|
|
5
|
-
import './searchBar.scss'
|
|
6
|
-
import { debounce } from '../Helper'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Generic search input component with support for enter based and debounced search
|
|
10
|
-
* Note: The component is uncontrolled
|
|
11
|
-
*
|
|
12
|
-
* @example Usage with default debounced search
|
|
13
|
-
* ```tsx
|
|
14
|
-
* <SearchBar handleSearchChange={triggerSearchApi} shouldDebounce />
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
|
-
* @example Initial search text
|
|
18
|
-
* ```tsx
|
|
19
|
-
* <SearchBar initialSearchText="Keyword" />
|
|
20
|
-
* ```
|
|
21
|
-
*
|
|
22
|
-
* @example Custom width
|
|
23
|
-
* ```tsx
|
|
24
|
-
* <SearchBar containerClassName="w-300" />
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* @example Trigger search on enter key press
|
|
28
|
-
* ```tsx
|
|
29
|
-
* <SearchBar handleEnter={triggerSearchApi} />
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* @example Custom timeout for debounced search
|
|
33
|
-
* ```tsx
|
|
34
|
-
* <SearchBar handleSearchChange={triggerSearchApi} shouldDebounce debounceTimeout={500} />
|
|
35
|
-
* ```
|
|
36
|
-
*
|
|
37
|
-
* @example Placeholder for the search
|
|
38
|
-
* ```tsx
|
|
39
|
-
* <SearchBar inputProps={{ placeholder: 'Enter search text' }} />
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
const SearchBar = ({
|
|
43
|
-
initialSearchText = '',
|
|
44
|
-
handleSearchChange = () => {},
|
|
45
|
-
handleEnter = () => {},
|
|
46
|
-
inputProps = {},
|
|
47
|
-
containerClassName,
|
|
48
|
-
shouldDebounce = false,
|
|
49
|
-
debounceTimeout = 300,
|
|
50
|
-
}: SearchBarProps) => {
|
|
51
|
-
const [showClearButton, setShowClearButton] = useState(!!initialSearchText)
|
|
52
|
-
const inputRef = useRef<HTMLInputElement>()
|
|
53
|
-
const debouncedSearchChange = useCallback(debounce(handleSearchChange, debounceTimeout), [
|
|
54
|
-
handleSearchChange,
|
|
55
|
-
debounceTimeout,
|
|
56
|
-
])
|
|
57
|
-
|
|
58
|
-
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
59
|
-
const { value } = e.target
|
|
60
|
-
setShowClearButton(!!value)
|
|
61
|
-
if (shouldDebounce) {
|
|
62
|
-
debouncedSearchChange(value)
|
|
63
|
-
} else {
|
|
64
|
-
handleSearchChange(value)
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const _applySearch = (value: string) => {
|
|
69
|
-
handleSearchChange(value)
|
|
70
|
-
handleEnter(value)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
74
|
-
const { key } = e
|
|
75
|
-
|
|
76
|
-
if (key === 'Enter') {
|
|
77
|
-
const inputTarget = e.target as HTMLInputElement
|
|
78
|
-
const value = inputTarget.value.trim()
|
|
79
|
-
_applySearch(value)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const clearSearch = () => {
|
|
84
|
-
inputRef.current.value = ''
|
|
85
|
-
_applySearch('')
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return (
|
|
89
|
-
<div className={containerClassName}>
|
|
90
|
-
<div className="search-bar bcn-0 dc__block w-100 min-w-200 dc__position-rel en-2 bw-1 br-4 h-32">
|
|
91
|
-
<Search className="search-bar__icon dc__position-abs icon-color-n6 icon-dim-18" />
|
|
92
|
-
<input
|
|
93
|
-
placeholder="Search"
|
|
94
|
-
data-testid="search-bar"
|
|
95
|
-
type="text"
|
|
96
|
-
{...inputProps}
|
|
97
|
-
defaultValue={initialSearchText}
|
|
98
|
-
className={`search-bar__input bcn-0 dc__position-abs w-100 h-100 br-4 dc__no-border pt-6 pr-10 pb-6 pl-30 fs-13 lh-20 fw-4 cn-9 placeholder-cn5 ${
|
|
99
|
-
showClearButton ? 'pr-30' : 'pr-10'
|
|
100
|
-
}`}
|
|
101
|
-
onChange={handleChange}
|
|
102
|
-
onKeyDown={handleKeyDown}
|
|
103
|
-
ref={inputRef}
|
|
104
|
-
/>
|
|
105
|
-
{showClearButton && (
|
|
106
|
-
<button
|
|
107
|
-
className="flex search-bar__clear-button dc__position-abs dc__transparent mt-0 mb-0 mr-5 ml-5"
|
|
108
|
-
type="button"
|
|
109
|
-
onClick={clearSearch}
|
|
110
|
-
aria-label="Clear search"
|
|
111
|
-
>
|
|
112
|
-
<Clear className="icon-dim-18 icon-n4 dc__vertical-align-middle" />
|
|
113
|
-
</button>
|
|
114
|
-
)}
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export default SearchBar
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
.search-bar {
|
|
2
|
-
|
|
3
|
-
&:focus,
|
|
4
|
-
&:focus-within {
|
|
5
|
-
outline: none;
|
|
6
|
-
border: solid 1px var(--B500);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
&__input {
|
|
10
|
-
|
|
11
|
-
&:focus,
|
|
12
|
-
&:focus-visible {
|
|
13
|
-
border: none;
|
|
14
|
-
outline: none;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
&__icon {
|
|
19
|
-
z-index: 1;
|
|
20
|
-
top: 50%;
|
|
21
|
-
left: 8px;
|
|
22
|
-
transform: translateY(-50%);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
&__clear-button {
|
|
26
|
-
right: 0;
|
|
27
|
-
top: 50%;
|
|
28
|
-
transform: translateY(-50%);
|
|
29
|
-
z-index: 1;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { InputHTMLAttributes } from 'react'
|
|
2
|
-
|
|
3
|
-
export interface SearchBarProps {
|
|
4
|
-
/**
|
|
5
|
-
* Initial search text
|
|
6
|
-
*
|
|
7
|
-
* @default ''
|
|
8
|
-
*/
|
|
9
|
-
initialSearchText?: string
|
|
10
|
-
/**
|
|
11
|
-
* Search handler for the search input
|
|
12
|
-
*/
|
|
13
|
-
handleSearchChange?: (searchText: string) => void
|
|
14
|
-
/**
|
|
15
|
-
* Enter event handler for the search input
|
|
16
|
-
*/
|
|
17
|
-
handleEnter?: (searchText: string) => void
|
|
18
|
-
/**
|
|
19
|
-
* Input props for the search input
|
|
20
|
-
*/
|
|
21
|
-
inputProps?: InputHTMLAttributes<HTMLInputElement>
|
|
22
|
-
/**
|
|
23
|
-
* Class name for the container; can be used for handling width
|
|
24
|
-
*/
|
|
25
|
-
containerClassName?: string
|
|
26
|
-
/**
|
|
27
|
-
* If true, the change handler would be triggered with debounce
|
|
28
|
-
*
|
|
29
|
-
* @default false
|
|
30
|
-
*/
|
|
31
|
-
shouldDebounce?: boolean
|
|
32
|
-
/**
|
|
33
|
-
* Timeout for the debounce handler to be triggered
|
|
34
|
-
*/
|
|
35
|
-
debounceTimeout?: number
|
|
36
|
-
}
|