Skip to content

Commit

Permalink
fix: Combobox padding (#531)
Browse files Browse the repository at this point in the history
  • Loading branch information
dogmar authored Oct 23, 2023
1 parent cdf4dea commit 3791bc1
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 87 deletions.
67 changes: 42 additions & 25 deletions src/components/Chip.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Flex, type FlexProps } from 'honorable'
import { type FlexProps } from 'honorable'
import PropTypes from 'prop-types'
import {
type ComponentProps,
Expand Down Expand Up @@ -84,16 +84,43 @@ const sizeToCloseHeight = {
large: 12,
} as const satisfies Record<ChipSize, number>

const ChipCardSC = styled(Card)(({ theme }) => ({
'.closeIcon': {
color: theme.colors['text-light'],
},
'&:hover': {
const ChipCardSC = styled(Card)<{ $size: ChipSize; $severity: ChipSeverity }>(({
$size,
$severity,
theme,
}) => {
const textColor =
theme.mode === 'light'
? theme.colors['text-light']
: theme.colors[severityToColor[$severity]] || theme.colors.text

return {
'.closeIcon': {
color: theme.colors.text,
color: theme.colors['text-light'],
paddingLeft: theme.spacing.xsmall,
},
'&:hover': {
'.closeIcon': {
color: theme.colors.text,
},
},
'.spinner': {
marginRight: theme.spacing.xsmall,
},
'.icon': {
marginRight: theme.spacing.xsmall,
},
},
}))
'.children': {
display: 'flex',
...theme.partials.text.body2,
color: textColor,
fontSize: $size === 'small' ? 12 : 14,
fontWeight: $size === 'small' ? 400 : 600,
lineHeight: $size === 'small' ? '16px' : '20px',
gap: 4,
},
}
})

function ChipRef(
{
Expand All @@ -114,8 +141,7 @@ function ChipRef(
const theme = useTheme()

hue = hue || parentFillLevelToHue[parentFillLevel]
const textColor =
theme.mode === 'light' ? 'text-light' : severityToColor[severity] || 'text'

const iconCol = severityToIconColor[severity] || 'icon-default'

return (
Expand All @@ -130,39 +156,30 @@ function ChipRef(
alignItems="center"
display="inline-flex"
textDecoration="none"
$size={size}
$severity={severity}
{...(as ? { forwardedAs: as } : {})}
{...props}
>
{loading && (
<Spinner
className="spinner"
color={theme.colors[iconCol]}
size={size === 'large' ? 15 : 13}
marginRight="xsmall"
/>
)}
{icon && (
<icon.type
className="icon"
size={size === 'large' ? 15 : 13}
marginRight="xsmall"
color={theme.colors[iconCol]}
/>
)}
<Flex
body2
color={textColor}
fontSize={size === 'small' ? 12 : 14}
fontWeight={size === 'small' ? 400 : 600}
lineHeight={size === 'small' ? '16px' : '20px'}
gap={4}
>
{children}
</Flex>
<div className="children">{children}</div>
{closeButton && (
<CloseIcon
className="closeIcon"
paddingLeft="xsmall"
size={sizeToCloseHeight[size]}
_hover={{ color: 'blue' }}
/>
)}
</ChipCardSC>
Expand Down
72 changes: 27 additions & 45 deletions src/components/ComboBox.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ExtendTheme, Spinner, mergeTheme } from 'honorable'
import { mergeTheme } from 'honorable'
import { omitBy } from 'lodash'
import { isUndefined, omit, pick } from 'lodash-es'
import {
Expand Down Expand Up @@ -28,6 +28,7 @@ import { useFloatingDropdown } from '../hooks/useFloatingDropdown'
import DropdownArrowIcon from './icons/DropdownArrowIcon'
import SearchIcon from './icons/SearchIcon'
import Input, { type InputProps } from './Input'
import { Spinner } from './Spinner'

import { type ListBoxItemBaseProps } from './ListBoxItem'
import { PopoverListBox } from './PopoverListBox'
Expand Down Expand Up @@ -131,21 +132,6 @@ const OpenButton = styled(
},
}))

const StartIconButton = styled.div(({ theme }) => ({
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
paddingLeft: theme.spacing.medium,
paddingRight: theme.spacing.medium,
}))

const comboBoxLeftRightStyles = {
alignSelf: 'stretch',
paddingHorizontal: 0,
marginLeft: 0,
marginRight: 0,
}

const honorableInputPropNames = [
'onChange',
'onFocus',
Expand Down Expand Up @@ -213,42 +199,38 @@ function ComboBoxInput({
Root: [{ paddingRight: 0 }],
EndIcon: [
{
...comboBoxLeftRightStyles,
alignSelf: 'stretch',
paddingHorizontal: 0,
marginLeft: 0,
marginRight: 0,
},
],
},
})
}

return (
<ExtendTheme theme={themeExtension}>
<Input
startIcon={
loading ? (
<StartIconButton>
<Spinner />
</StartIconButton>
) : (
startIcon && <StartIconButton>{startIcon}</StartIconButton>
)
}
endIcon={
showArrow ? (
<OpenButton
isOpen={isOpen}
buttonRef={buttonRef}
buttonProps={buttonProps}
/>
) : undefined
}
inputProps={{
ref: inputRef,
onClick: onInputClick,
...innerInputProps,
}}
{...outerInputProps}
/>
</ExtendTheme>
<Input
themeExtension={themeExtension}
startIcon={
loading ? <Spinner color={theme.colors['icon-xlight']} /> : startIcon
}
endIcon={
showArrow ? (
<OpenButton
isOpen={isOpen}
buttonRef={buttonRef}
buttonProps={buttonProps}
/>
) : undefined
}
inputProps={{
ref: inputRef,
onClick: onInputClick,
...innerInputProps,
}}
{...outerInputProps}
/>
)
}

Expand Down
10 changes: 7 additions & 3 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { ExtendTheme, Input as HonorableInput } from 'honorable'
import { ExtendTheme, Input as HonorableInput, mergeTheme } from 'honorable'
import type { InputProps as HonorableInputProps } from 'honorable'
import { type ComponentProps, type ReactNode, forwardRef, useRef } from 'react'
import styled from 'styled-components'
import { mergeRefs } from 'react-merge-refs'

import { mergeProps } from 'react-aria'

import { simulateInputChange } from '../utils/simulateInputChange'
Expand All @@ -21,6 +20,7 @@ export type InputProps = HonorableInputProps & {
prefix?: ReactNode
titleContent?: ReactNode
showClearButton?: boolean
themeExtension?: Record<string, any>
}

const PrefixSuffix = styled.div(({ theme }) => ({
Expand Down Expand Up @@ -85,6 +85,7 @@ const Input = forwardRef(
showClearButton,
titleContent,
inputProps,
themeExtension: themeExtensionProp,
...props
}: InputProps,
ref
Expand All @@ -95,7 +96,7 @@ const Input = forwardRef(
...(inputProps ?? {}),
ref: mergeRefs([inputRef, ...(inputProps?.ref ? [inputProps.ref] : [])]),
}
const themeExtension: any = {
let themeExtension: any = {
Input: {
Root: [
{
Expand Down Expand Up @@ -135,6 +136,9 @@ const Input = forwardRef(
],
},
}

themeExtension = mergeTheme(themeExtension, themeExtensionProp)

const parentFillLevel = useFillLevel()
const size = (props as any).large
? 'large'
Expand Down
50 changes: 40 additions & 10 deletions src/components/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,53 @@
import { Spinner as HonorableSpinner } from 'honorable'
import { type ComponentProps } from 'react'
import styled from 'styled-components'
import styled, { keyframes } from 'styled-components'

const SpinnerSC = styled(HonorableSpinner)<{ $color: string }>(
({ $color }) => ({
'&&::before': {
borderTopColor: $color || 'red',
},
})
)
const rotateAnim = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`

const SpinnerSC = styled(
styled('div')<{ $color: string; $size: number }>(
({ theme, $color, $size }) => ({
display: 'block',
width: $size,
height: $size,
position: 'relative',
'&::before': {
content: '""',
position: 'absolute',
top: '50%',
left: '50%',
width: $size,
height: $size,
marginTop: $size * -0.5,
marginLeft: $size * -0.5,
borderRadius: '50%',
borderTop: `2px solid ${$color || theme.colors['icon-default']}`,
borderRight: `2px solid transparent`,
},
})
)
)`
&::before {
animation: ${rotateAnim} 0.8s linear infinite;
}
`

export function Spinner({
color,
size = 16,
as,
...props
}: { color: string } & ComponentProps<typeof SpinnerSC>) {
}: { color?: string; size?: number } & ComponentProps<typeof SpinnerSC>) {
return (
<SpinnerSC
$color={color}
$size={size}
{...(as ? { forwardedAs: as } : {})}
{...props}
/>
Expand Down
14 changes: 10 additions & 4 deletions src/stories/ComboBox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ const ChipList = styled(ListBoxItemChipList)(({ theme }) => ({
justifyContent: 'start',
}))

function Template({ onFillLevel }: { onFillLevel: any }) {
function Template({ onFillLevel, ...args }: { onFillLevel: any }) {
const [selectedKeys, setSelectedKeys] = useState(new Set<Key>())
const [inputValue, setInputValue] = useState('')

Expand Down Expand Up @@ -242,6 +242,7 @@ function Template({ onFillLevel }: { onFillLevel: any }) {
onSelectionChange={onSelectionChange}
onInputChange={onInputChange}
inputProps={{ placeholder: 'Pick something' }}
{...args}
>
{searchResults.map(
({ item, score: _score, refIndex: _refIndex }) => (
Expand Down Expand Up @@ -280,7 +281,7 @@ function Template({ onFillLevel }: { onFillLevel: any }) {
)
}

function TagsTemplate() {
function TagsTemplate({ ...args }: any) {
const [selectedKeys, setSelectedKeys] = useState(new Set<Key>())
const [inputValue, setInputValue] = useState('')
const [isOpen, setIsOpen] = useState(false)
Expand Down Expand Up @@ -370,6 +371,7 @@ function TagsTemplate() {
}
maxHeight={232}
allowsEmptyCollection={!!newKey}
{...args}
>
{searchResults.map(({ item, score: _score, refIndex: _refIndex }) => (
<ListBoxItem
Expand Down Expand Up @@ -405,7 +407,11 @@ function TagsTemplate() {

export const Default = Template.bind({})

Default.args = {}
Default.args = {
loading: false,
}

export const Tags = TagsTemplate.bind({})
Default.args = {}
Default.args = {
loading: false,
}

0 comments on commit 3791bc1

Please sign in to comment.