Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UX tweaks for query builder #8518

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 31 additions & 41 deletions frontend/src/__generated/index.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
// src/components/Search/SearchForm/SearchForm.css.ts
var combobox = "_10xh0c23 mt0ih23s mt0ih24c mt0ih24w mt0ih25g";
var comboboxGroup = "_10xh0c2i mt0ih23r mt0ih24b";
var comboboxItem = "_10xh0c2g";
var comboboxGroup = "_10xh0c2h mt0ih23r mt0ih24b";
var comboboxItem = "_10xh0c2f";
var comboboxNotEmpty = "_10xh0c24";
var comboboxPopover = "_10xh0c2e";
var comboboxResults = "_10xh0c2f _14ud0dc1";
var comboboxPopover = "_10xh0c2d";
var comboboxResults = "_10xh0c2e _14ud0dc1";
var comboboxTag = "_10xh0c26";
var comboboxTagActive = "_10xh0c2a";
var comboboxTagClose = "_10xh0c2c";
var comboboxTagError = "_10xh0c2b";
var comboboxTagErrorIndicator = "_10xh0c2d";
var comboboxTagActive = "_10xh0c29";
var comboboxTagClose = "_10xh0c2b";
var comboboxTagError = "_10xh0c2a";
var comboboxTagErrorIndicator = "_10xh0c2c";
var comboboxTagsContainer = "_10xh0c25";
var errorToken = "_10xh0c29";
var errorToken = "_10xh0c28";
var searchIcon = "_10xh0c20";
var searchIconWithActions = "_10xh0c21";
var token = "_10xh0c27";
var whitespaceToken = "_10xh0c28";
export {
combobox,
comboboxGroup,
Expand All @@ -32,6 +31,5 @@ export {
errorToken,
searchIcon,
searchIconWithActions,
token,
whitespaceToken
token
};
59 changes: 34 additions & 25 deletions frontend/src/components/Search/SearchForm/QueryPart.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
Ariakit,
Box,
IconSolidExclamationCircle,
IconSolidXCircle,
Expand All @@ -15,21 +14,22 @@ import { SearchToken } from '@/components/Search/utils'
import * as styles from './SearchForm.css'

export const QueryPart: React.FC<{
comboboxStore: Ariakit.ComboboxStore
typeaheadOpen: boolean
cursorIndex: number
index: number
tokenGroup: TokenGroup
showValues: boolean
onRemoveItem: (index: number) => void
showErrors: boolean
onRemoveItem?: (index: number) => void
}> = ({
comboboxStore,
typeaheadOpen,
cursorIndex,
index,
tokenGroup,
showValues,
showErrors,
onRemoveItem,
}) => {
const typeaheadOpen = comboboxStore.useState('open')
const active =
typeaheadOpen &&
cursorIndex >= tokenGroup.start &&
Expand All @@ -40,6 +40,7 @@ export const QueryPart: React.FC<{
const error = errorToken
? errorMessageForToken(errorToken, showValues)
: undefined
const showError = showErrors && error
const isExpression = tokenGroup.type === 'expression'

if (
Expand All @@ -54,7 +55,11 @@ export const QueryPart: React.FC<{
<>
{tokenGroup.tokens.map((token, index) => {
return (
<Token key={`${token.text}-${index}`} token={token} />
<Token
key={`${token.text}-${index}`}
token={token}
showErrors={showErrors}
/>
)
})}
</>
Expand All @@ -65,7 +70,7 @@ export const QueryPart: React.FC<{
<>
<Tooltip
placement="top-start"
open={active && !!error}
open={active && !!showError}
style={{ display: 'inline', wordBreak: 'break-word' }}
maxWidth={600}
shift={-3}
Expand All @@ -75,7 +80,7 @@ export const QueryPart: React.FC<{
cssClass={clsx({
[styles.comboboxTag]: isExpression,
[styles.comboboxTagActive]: active && isExpression,
[styles.comboboxTagError]: !!error,
[styles.comboboxTagError]: !!showError,
})}
position="relative"
display="inline-flex"
Expand All @@ -89,17 +94,20 @@ export const QueryPart: React.FC<{
<Token
key={`${token.text}-${index}`}
token={token}
showErrors={showErrors}
/>
)
})}
<IconSolidXCircle
className={styles.comboboxTagClose}
size={13}
onClick={() => onRemoveItem(index)}
style={{ cursor: 'pointer' }}
/>
{onRemoveItem && (
<IconSolidXCircle
className={styles.comboboxTagClose}
size={13}
onClick={() => onRemoveItem(index)}
style={{ cursor: 'pointer' }}
/>
)}

{error && (
{showError && (
<IconSolidExclamationCircle
className={styles.comboboxTagErrorIndicator}
size={13}
Expand All @@ -109,7 +117,7 @@ export const QueryPart: React.FC<{
</Box>
}
>
{error ? <ErrorRenderer error={error} /> : null}
{showError ? <ErrorRenderer error={error} /> : null}
</Tooltip>
</>
)
Expand All @@ -119,15 +127,22 @@ export const SEPARATORS = SearchGrammarParser.literalNames.map((name) =>
name?.replaceAll("'", ''),
)

export const Token = ({ token }: { token: SearchToken }): JSX.Element => {
export const Token = ({
showErrors,
token,
}: {
showErrors?: boolean
token: SearchToken
}): JSX.Element => {
const { errorMessage, text } = token
const showError = showErrors && errorMessage

if (SEPARATORS.includes(text.toUpperCase())) {
return (
<Box
as="span"
cssClass={clsx(styles.token, {
[styles.errorToken]: !!errorMessage,
[styles.errorToken]: !!showError,
})}
style={{ color: '#E93D82', zIndex: 1 }}
>
Expand All @@ -136,13 +151,7 @@ export const Token = ({ token }: { token: SearchToken }): JSX.Element => {
)
} else {
return (
<Box
as="span"
style={{ zIndex: 1 }}
cssClass={clsx(styles.token, {
[styles.whitespaceToken]: text.trim() === '',
})}
>
<Box as="span" style={{ zIndex: 1 }} cssClass={clsx(styles.token)}>
{text.split('').map((char, index) =>
char === '*' ? (
<span key={index} style={{ color: '#E93D82' }}>
Expand Down
23 changes: 8 additions & 15 deletions frontend/src/components/Search/SearchForm/SearchForm.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ export const searchIconWithActions = style({
top: 12,
})

const WORD_SPACING = 4

export const combobox = style([
sprinkles({
p: '6',
}),
typographyStyles.family.body,
typographyStyles.family.monospace,
typographyStyles.size.small,
{
background: 'transparent',
Expand All @@ -34,7 +32,6 @@ export const combobox = style([
fontWeight: '500 !important',
pointerEvents: 'auto',
width: '100%',
wordSpacing: WORD_SPACING,
selectors: {
'&:focus': {
outline: 0,
Expand All @@ -54,7 +51,7 @@ export const comboboxNotEmpty = style({
})

export const comboboxTagsContainer = style([
typographyStyles.family.body,
typographyStyles.family.monospace,
typographyStyles.size.small,
{
display: 'block',
Expand All @@ -79,16 +76,12 @@ export const comboboxTag = style({
height: 20,
})

export const token = style({
height: 20,
letterSpacing: 0,
wordSpacing: WORD_SPACING,
})

export const whitespaceToken = style({
letterSpacing: WORD_SPACING,
wordSpacing: 0,
})
export const token = style([
typographyStyles.family.monospace,
{
height: 20,
},
])

export const errorToken = style({
backgroundColor: 'rgba(255, 9, 87, 0.1)',
Expand Down