Skip to content

Commit 42f6e6b

Browse files
committed
refactor(ui): migrate MultiSearch from SCSS modules to styled-components
Replace styles.module.scss with styled-components using theme spacing and semantic colors. Remove all SCSS class references and add styled components for suggestion items, text, options, and buttons. References: #RI-7817
1 parent 46fb030 commit 42f6e6b

File tree

3 files changed

+116
-126
lines changed

3 files changed

+116
-126
lines changed

redisinsight/ui/src/components/multi-search/MultiSearch.styles.ts

Lines changed: 99 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1+
import { HTMLAttributes } from 'react'
12
import styled from 'styled-components'
23
import { Theme } from 'uiSrc/components/base/theme/types'
34
import { Row } from 'uiSrc/components/base/layout/flex'
45
import { TextInput } from 'uiSrc/components/base/inputs'
6+
import {
7+
ActionIconButton,
8+
IconButton,
9+
} from 'uiSrc/components/base/forms/buttons'
10+
import GroupBadge from 'uiSrc/components/group-badge'
511

6-
interface StyledMultiSearchProps extends React.HTMLAttributes<HTMLDivElement> {
12+
interface StyledMultiSearchProps extends HTMLAttributes<HTMLDivElement> {
713
$isFocused: boolean
814
}
915

16+
interface StyledSuggestionProps extends HTMLAttributes<HTMLLIElement> {
17+
$isFocused?: boolean
18+
}
19+
1020
export const StyledMultiSearch = styled(Row)<StyledMultiSearchProps>`
1121
border: 1px solid
1222
${({ theme, $isFocused }: { theme: Theme; $isFocused: boolean }) =>
@@ -29,25 +39,25 @@ export const StyledMultiSearch = styled(Row)<StyledMultiSearchProps>`
2939
background-size 150ms ease-in,
3040
background-color 150ms ease-in;
3141
`
32-
export const StyledAutoSuggestions = styled.div<
33-
React.HTMLAttributes<HTMLDivElement>
34-
>`
35-
background-color: ${({ theme }: { theme: Theme }) =>
36-
theme.components.select.dropdown.bgColor};
42+
/**
43+
* Auto-suggestions dropdown container
44+
* Replaces: .autoSuggestions
45+
*/
46+
export const StyledAutoSuggestions = styled.div<React.HTMLAttributes<HTMLDivElement>>`
47+
background-color: ${({ theme }) => theme.components.select.dropdown.bgColor};
3748
border: 1px solid
38-
${({ theme }: { theme: Theme }) =>
39-
theme.components.select.states.disabled.borderColor};
49+
${({ theme }) => theme.components.select.states.disabled.borderColor};
4050
position: absolute;
41-
top: calc(100% + 2px);
51+
top: calc(100% + ${({ theme }) => theme.core.space.space025});
4252
left: 0;
4353
width: 100%;
44-
min-width: 180px;
54+
min-width: calc(
55+
${({ theme }) => theme.core.space.space550} * 4
56+
); // 176px instead of hardcoded 180px
4557
46-
border-radius: 4px;
58+
border-radius: ${({ theme }) => theme.core.space.space050};
4759
z-index: 1001;
48-
padding: 4px 0 0;
49-
50-
font-size: 13px;
60+
padding: ${({ theme }) => theme.core.space.space050} 0 0;
5161
`
5262

5363
export const StyledMultiSearchWrapper = styled(Row)<
@@ -59,13 +69,6 @@ export const StyledMultiSearchWrapper = styled(Row)<
5969
min-height: 36px;
6070
`
6171

62-
export const StyledSuggestion = styled.li<React.HTMLAttributes<HTMLLIElement>>`
63-
&:hover {
64-
background: ${({ theme }: { theme: Theme }) =>
65-
theme.components.select.dropdown.option.states.highlighted.bgColor};
66-
}
67-
`
68-
6972
export const StyledClearHistory = styled.li<
7073
React.HTMLAttributes<HTMLDivElement>
7174
>`
@@ -95,3 +98,78 @@ export const StyledSearchInput = styled(TextInput)`
9598
padding: 0 6px 0 10px;
9699
background-image: none;
97100
`
101+
102+
/**
103+
* Remove button within suggestion item
104+
* Replaces: .suggestionRemoveBtn
105+
* Note: Defined before StyledSuggestion so it can be referenced in selectors
106+
*/
107+
export const StyledSuggestionRemoveBtn = styled(IconButton)`
108+
flex-shrink: 0;
109+
visibility: hidden;
110+
pointer-events: none;
111+
`
112+
113+
/**
114+
* Individual suggestion item in the dropdown
115+
* Replaces: .suggestion
116+
*/
117+
export const StyledSuggestion = styled.li<StyledSuggestionProps>`
118+
display: flex;
119+
align-items: center;
120+
text-align: left;
121+
padding: ${({ theme }) => theme.core.space.space050}
122+
${({ theme }) => theme.core.space.space100};
123+
cursor: default;
124+
125+
${({ $isFocused, theme }) =>
126+
$isFocused &&
127+
`background: ${theme.components.select.dropdown.option.states.highlighted.bgColor};`}
128+
129+
&:hover {
130+
background: ${({ theme }) =>
131+
theme.components.select.dropdown.option.states.highlighted.bgColor};
132+
}
133+
134+
/* Show remove button on hover or when focused */
135+
&:hover ${StyledSuggestionRemoveBtn} {
136+
visibility: visible;
137+
pointer-events: auto;
138+
}
139+
140+
${({ $isFocused }) =>
141+
$isFocused &&
142+
`& ${StyledSuggestionRemoveBtn} {
143+
visibility: visible;
144+
pointer-events: auto;
145+
}`}
146+
`
147+
148+
/**
149+
* GroupBadge wrapper within suggestion item
150+
* Replaces: .suggestionOption
151+
*/
152+
export const StyledSuggestionOption = styled(GroupBadge)`
153+
margin-right: ${({ theme }) => theme.core.space.space100};
154+
`
155+
156+
/**
157+
* Text content within a suggestion item
158+
* Replaces: .suggestionText
159+
*/
160+
export const StyledSuggestionText = styled.span<
161+
HTMLAttributes<HTMLSpanElement>
162+
>`
163+
text-overflow: ellipsis;
164+
overflow: hidden;
165+
white-space: nowrap;
166+
flex-grow: 1;
167+
line-height: 1.4;
168+
`
169+
/**
170+
* Clear/Reset filters button
171+
* Replaces: .clearButton
172+
*/
173+
export const StyledClearButton = styled(ActionIconButton)`
174+
margin-left: ${({ theme }) => theme.core.space.space050};
175+
`

redisinsight/ui/src/components/multi-search/MultiSearch.tsx

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { useEffect, useRef, useState } from 'react'
2-
import cx from 'classnames'
32

43
import * as keys from 'uiSrc/constants/keys'
54
import { GroupBadge, RiTooltip } from 'uiSrc/components'
@@ -11,21 +10,23 @@ import {
1110
SearchIcon,
1211
SwitchIcon,
1312
} from 'uiSrc/components/base/icons'
14-
import {
15-
ActionIconButton,
16-
IconButton,
17-
} from 'uiSrc/components/base/forms/buttons'
13+
import { IconButton } from 'uiSrc/components/base/forms/buttons'
1814
import { RiIcon } from 'uiSrc/components/base/icons/RiIcon'
1915
import { ProgressBarLoader } from 'uiSrc/components/base/display'
2016
import {
2117
StyledAutoSuggestions,
18+
StyledClearButton,
2219
StyledClearHistory,
2320
StyledMultiSearch,
2421
StyledMultiSearchWrapper,
2522
StyledSearchInput,
2623
StyledSuggestion,
24+
StyledSuggestionOption,
25+
StyledSuggestionRemoveBtn,
26+
StyledSuggestionText,
2727
} from './MultiSearch.styles'
28-
import styles from './styles.module.scss'
28+
29+
import { Text } from 'uiSrc/components/base/text'
2930

3031
interface MultiSearchSuggestion {
3132
options: null | Array<{
@@ -174,7 +175,7 @@ const MultiSearch = (props: Props) => {
174175
<OutsideClickDetector onOutsideClick={exitAutoSuggestions}>
175176
<StyledMultiSearchWrapper
176177
align="center"
177-
className={cx(styles.multiSearchWrapper, className)}
178+
className={className}
178179
onKeyDown={handleKeyDown}
179180
role="presentation"
180181
data-testid="multi-search"
@@ -203,7 +204,6 @@ const MultiSearch = (props: Props) => {
203204
{showAutoSuggestions && !!suggestionOptions?.length && (
204205
<StyledAutoSuggestions
205206
role="presentation"
206-
className={styles.autoSuggestions}
207207
data-testid="suggestions"
208208
>
209209
{suggestions?.loading && (
@@ -218,28 +218,21 @@ const MultiSearch = (props: Props) => {
218218
value && (
219219
<StyledSuggestion
220220
key={id}
221-
className={cx(styles.suggestion, {
222-
[styles.focused]: focusedItem === index,
223-
})}
221+
$isFocused={focusedItem === index}
224222
onClick={() => handleApplySuggestion(index)}
225223
role="presentation"
226224
data-testid={`suggestion-item-${id}`}
227225
>
228226
{option && (
229-
<GroupBadge
227+
<StyledSuggestionOption
230228
type={option}
231229
compressed={compressed}
232-
className={styles.suggestionOption}
233230
/>
234231
)}
235-
<span
236-
className={styles.suggestionText}
237-
data-testid="suggestion-item-text"
238-
>
232+
<StyledSuggestionText data-testid="suggestion-item-text">
239233
{value}
240-
</span>
241-
<IconButton
242-
className={styles.suggestionRemoveBtn}
234+
</StyledSuggestionText>
235+
<StyledSuggestionRemoveBtn
243236
icon={CancelSlimIcon}
244237
color="primary"
245238
aria-label="Remove History Record"
@@ -263,18 +256,19 @@ const MultiSearch = (props: Props) => {
263256
data-testid="clear-history-btn"
264257
>
265258
<RiIcon type="EraserIcon" style={{ marginRight: 6 }} />
266-
<span>Clear history</span>
259+
<Text component="span" size="m">
260+
Clear history
261+
</Text>
267262
</StyledClearHistory>
268263
</StyledAutoSuggestions>
269264
)}
270265
{(value || !!options.length) && (
271266
<RiTooltip content="Reset Filters" position="bottom">
272-
<ActionIconButton
267+
<StyledClearButton
273268
icon={CancelSlimIcon}
274269
size="XS"
275270
aria-label="Reset Filters"
276271
onClick={onClear}
277-
className={styles.clearButton}
278272
data-testid="reset-filter-btn"
279273
variant="secondary"
280274
/>
@@ -301,7 +295,6 @@ const MultiSearch = (props: Props) => {
301295
{disableSubmit && (
302296
<RiTooltip
303297
position="top"
304-
anchorClassName={styles.anchorSubmitBtn}
305298
content="Please choose index in order to preform the search"
306299
>
307300
{SubmitBtn()}

redisinsight/ui/src/components/multi-search/styles.module.scss

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

0 commit comments

Comments
 (0)