Skip to content

Commit

Permalink
feat(dropdown): add value variants using tags
Browse files Browse the repository at this point in the history
  • Loading branch information
donaldjbrady committed Aug 20, 2020
1 parent 475ae3a commit 1aae340
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ const teaOptions = [
},
];

const valueVariants = {
none: undefined,
...variants,
};

storiesOf('Dropdown', module)
.add(
'Basic',
Expand All @@ -95,6 +100,7 @@ storiesOf('Dropdown', module)
options={cities}
variant={select('variant', variants, variants.outline)}
optionsVariant={select('optionsVariant', variants, variants.outline)}
valueVariant={select('valueVariant', valueVariants, valueVariants.none)}
values={values}
/>
</Label>
Expand Down
60 changes: 51 additions & 9 deletions packages/hs-react-ui/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import Button from '../Button/Button';
import variants from '../../enums/variants';
import timings from '../../enums/timings';
import { Div, Span } from '../../htmlElements';
import Tag, { TagProps } from '../Tag/Tag';
import Text from '../Text/Text';
import { getFontColorFromVariant, getBackgroundColorFromVariant } from '../../utils/color';
import { SubcomponentPropsType } from '../commonTypes';
import { getShadowStyle } from '../../utils/styles';
import { getShadowStyle, getDropdownTagStyle } from '../../utils/styles';

export type OptionProps = {
id: number | string;
Expand Down Expand Up @@ -119,12 +120,12 @@ const OptionItem = styled(Div)`
: getFontColorFromVariant(variant, color)
};
background-color: ${backgroundColor};
&:hover {
background-color: ${
backgroundColor !== 'transparent' ? darken(0.05, backgroundColor) : 'rgba(0, 0, 0, 0.05)'
};
cursor: pointer;
outline: none;
}
Expand Down Expand Up @@ -157,6 +158,22 @@ const PlaceholderContainer = styled(Text.Container)`
opacity: 0.8;
`;

const StyledTagContainer = styled(Tag.Container)`
${({
dropdownVariant,
tagVariant,
dropdownColor,
transparentColor,
}: {
dropdownVariant: variants;
tagVariant: variants;
dropdownColor: string;
transparentColor: string;
}) => `
${getDropdownTagStyle(dropdownVariant, tagVariant, dropdownColor, transparentColor)}
`}
`;

export interface DropdownProps {
StyledContainer?: string & StyledComponentBase<any, {}>;
StyledValueContainer?: string & StyledComponentBase<any, {}>;
Expand All @@ -173,6 +190,7 @@ export interface DropdownProps {
optionItemProps?: SubcomponentPropsType;
checkContainerProps?: SubcomponentPropsType;
placeholderProps?: SubcomponentPropsType;
valueItemTagProps?: TagProps;

color?: string;
elevation?: number;
Expand All @@ -189,6 +207,7 @@ export interface DropdownProps {
tabIndex?: number;
variant?: variants;
optionsVariant?: variants;
valueVariant?: variants;
}

const Dropdown = ({
Expand All @@ -207,6 +226,7 @@ const Dropdown = ({
optionItemProps,
checkContainerProps,
placeholderProps,
valueItemTagProps = {},

color,
elevation = 0,
Expand All @@ -219,7 +239,8 @@ const Dropdown = ({
options = [],
tabIndex = 0,
variant = variants.outline,
optionsVariant = variant,
optionsVariant = variants.outline,
valueVariant,
values = [],
}: DropdownProps): JSX.Element | null => {
const { colors } = useTheme();
Expand All @@ -233,6 +254,8 @@ const Dropdown = ({
...placeholderProps,
};

const tagContainerItemProps = valueItemTagProps.containerProps || {};

const optionsHash: { [key: string]: OptionProps } = {};
options.forEach(option => {
optionsHash[option.id] = { ...option, isSelected: values.includes(option.id) };
Expand Down Expand Up @@ -400,12 +423,31 @@ const Dropdown = ({
>
{values
.filter(val => val !== undefined && optionsHash[val] !== undefined)
.map((val, i) =>
.map((val, i, arr) =>
optionsHash[val] !== undefined ? (
<span key={val}>
{i !== 0 && ', '}
{optionsHash[val].optionValue}
</span>
valueVariant ? (
<Tag
StyledContainer={StyledTagContainer}
variant={valueVariant}
{...valueItemTagProps}
containerProps={{
...tagContainerItemProps,
dropdownVariant: variant,
tagVariant: valueVariant,
dropdownColor: defaultedColor,
transparentColor: colors.transparent,
}}
key={val}
>
{optionsHash[val].optionValue}
{valueVariant === variants.text && i !== arr.length - 1 && ','}
</Tag>
) : (
<span key={val}>
{optionsHash[val].optionValue}
{i !== arr.length - 1 && ', '}
</span>
)
) : (
undefined
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1490,9 +1490,9 @@ exports[`Dropdown renders two values when given matching option ids through prop
>
<span>
Bulbasaur
,
</span>
<span>
,
Charmander
</span>
</div>
Expand Down Expand Up @@ -1612,9 +1612,9 @@ exports[`Dropdown renders two values when given matching option ids through prop
>
<span>
Bulbasaur
,
</span>
<span>
,
Charmander
</span>
</div>
Expand Down Expand Up @@ -1734,9 +1734,9 @@ exports[`Dropdown selects options from values prop 1`] = `
>
<span>
Bulbasaur
,
</span>
<span>
,
Charmander
</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ storiesOf('InteractionFeedback', module).add(
opacity: entranceOpacity,
},
leave: {
r: `${number('Ending circle radius', 0, { range: true, min: 0, max: 100, step: 1}, 'Circle radius')}`,
r: `${number(
'Ending circle radius',
0,
{ range: true, min: 0, max: 100, step: 1 },
'Circle radius',
)}`,
opacity: exitOpacity,
},
config: {
Expand Down
7 changes: 3 additions & 4 deletions packages/hs-react-ui/src/components/Tag/Tag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import timings from '../../enums/timings';
import { useTheme } from '../../context';
import variants from '../../enums/variants';
import Progress from '../Progress/Progress';
import { Div } from '../../htmlElements';
import { Div, Span } from '../../htmlElements';
import { getFontColorFromVariant, getBackgroundColorFromVariant } from '../../utils/color';
import { SubcomponentPropsType } from '../commonTypes';
import { getShadowStyle } from '../../utils/styles';
Expand Down Expand Up @@ -44,7 +44,7 @@ export type TagProps = {
StyledLoadingBar?: string & StyledComponentBase<any, {}>;
};

export const Container: string & StyledComponentBase<any, {}, TagContainerProps> = styled(Div)`
export const Container: string & StyledComponentBase<any, {}, TagContainerProps> = styled(Span)`
${({ elevation = 0, color, variant }: TagContainerProps) => {
const { colors } = useTheme();
const backgroundColor = getBackgroundColorFromVariant(variant, color, colors.transparent);
Expand All @@ -63,8 +63,7 @@ export const Container: string & StyledComponentBase<any, {}, TagContainerProps>
box-shadow ${timings.slow};
${getShadowStyle(elevation, colors.shadow)}
outline: 0 none;
border: ${variant === variants.outline ? `1px solid ${color || colors.grayDark}` : '0 none;'};
cursor: pointer;
border: ${variant === variants.outline ? `1px solid ${color || colors.grayDark};` : '0 none;'}
background-color: ${backgroundColor};
color: ${fontColor};
align-items: center;
Expand Down
Loading

0 comments on commit 1aae340

Please sign in to comment.