Skip to content

Commit

Permalink
Feat: textfield allow component label
Browse files Browse the repository at this point in the history
  • Loading branch information
Seedy authored Jan 28, 2022
1 parent 8674337 commit b8437d8
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 12 deletions.
62 changes: 60 additions & 2 deletions components/TextField/TextField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';

import { Flex } from '../Flex';
import { Label } from '../Label';
import { Text } from '../Text';
import { Popover, PopoverTrigger, PopoverContent } from '../Popover';
import { TextField, TextFieldProps, TextFieldVariants } from './TextField';
import { MagnifyingGlassIcon } from '@radix-ui/react-icons';
import { MagnifyingGlassIcon, InfoCircledIcon } from '@radix-ui/react-icons';
import { styled } from '../../stitches.config';
import { modifyVariantsForStory } from '../../utils/modifyVariantsForStory';
import ignoreArgType from '../../utils/ignoreArgType';

Expand Down Expand Up @@ -97,4 +101,58 @@ DisplayClearable.args = {
id: 'displayclearable',
clearable: true,
};
ignoreArgType('id', DisplayClearable);
ignoreArgType('id', DisplayClearable);

export const LabelComponent: ComponentStory<typeof TextFieldForStory> = ({ id, ...args }) => (
<Flex direction="column" gap={2}>
<TextFieldForStory
id={`${id}-basic`}
{...args}
/>
<TextFieldForStory
id={`${id}-invalid`}
state="invalid"
{...args}
/>
<TextFieldForStory
id={`${id}-disabled`}
value="disabled"
disabled
{...args}
/>

</Flex>
)

const StyledInfoCircledIcon = styled(InfoCircledIcon, {
ml: '$2',
'@hover': {
'&:hover': {
cursor: 'pointer'
}
}
});

const label = (props) => (
<Label {...props}>
<Flex align="center">
Field Label
<Popover>
<PopoverTrigger asChild>
<StyledInfoCircledIcon />
</PopoverTrigger>
<PopoverContent css={{ p: '$3' }}>
<Text as="p" css={{ color: 'currentColor' }}>
More information
</Text>
</PopoverContent>
</Popover>
</Flex>
</Label >
)

LabelComponent.args = {
id: 'labelcomponent',
label: label,
}
ignoreArgType('id', LabelComponent);
35 changes: 28 additions & 7 deletions components/TextField/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ import {
} from '@radix-ui/react-icons';

// TYPES
export interface TextFieldLabelProps {
variant: 'red' | 'subtle' | 'contrast' | 'default'
disabled?: boolean
invalid?: boolean
htmlFor?: string
}
export type TextFieldProps = InputProps & {
type?: string;
clearable?: boolean;
label?: string;
label?: string | ((props: TextFieldLabelProps) => JSX.Element);
};

export type TextFieldVariants = InputVariants;
Expand Down Expand Up @@ -60,7 +66,7 @@ const StyledCrossCircledIcon = styled(CrossCircledIcon, {

export const TextField = React.forwardRef<React.ElementRef<typeof Input>, TextFieldProps>(
(
{ state, clearable, label, id, type, disabled, readOnly, onBlur, onFocus, css, ...props },
{ state, clearable, label: LabelOrComponent, id, type, disabled, readOnly, onBlur, onFocus, css, ...props },
forwardedRef
) => {
const inputRef = React.useRef<InputHandle | null>(null);
Expand All @@ -85,6 +91,25 @@ export const TextField = React.forwardRef<React.ElementRef<typeof Input>, TextFi
return 'default';
}, [invalid, disabled, inputHasFocus]);

const LabelNode = React.useMemo(
() => {
if (LabelOrComponent === undefined || LabelOrComponent === null) {
return null;
}
if (typeof LabelOrComponent === 'string') {
return (
<Label variant={labelVariant} disabled={disabled} invalid={invalid} htmlFor={id}>
{LabelOrComponent}
</Label>
);
}
return (
<LabelOrComponent variant={labelVariant} disabled={disabled} invalid={invalid} htmlFor={id} />
);
},
[LabelOrComponent, labelVariant, disabled, invalid, id],
);

const isPasswordType = React.useMemo(() => type === 'password', [type]);

const typeOrInnerType = React.useMemo(() => (isPasswordType ? innerType : type), [
Expand Down Expand Up @@ -154,11 +179,7 @@ export const TextField = React.forwardRef<React.ElementRef<typeof Input>, TextFi

return (
<Box css={css}>
{label && (
<Label variant={labelVariant} disabled={disabled} invalid={invalid} htmlFor={id}>
{label}
</Label>
)}
{LabelNode}
<Input
id={id}
ref={inputRef}
Expand Down
3 changes: 0 additions & 3 deletions components/Tooltip/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import { modifyVariantsForStory } from '../../utils/modifyVariantsForStory';
import { Text } from '../Text';
import { Container } from '../Container';
import { Flex } from '../Flex';
import { Button } from '../Button';
import { Box } from '../Box';
import { Bubble } from '../Bubble';
import { TextField } from '../TextField';
import { CrossCircledIcon, ExclamationTriangleIcon } from '@radix-ui/react-icons';
import { styled } from '../../stitches.config';

Expand Down

0 comments on commit b8437d8

Please sign in to comment.