Skip to content

Commit

Permalink
feat(TextArea): Make initial component (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeltaranto authored Mar 15, 2019
1 parent db6f79e commit 3123068
Show file tree
Hide file tree
Showing 25 changed files with 428 additions and 70 deletions.
1 change: 1 addition & 0 deletions lib/atoms/makeSizes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export default (tokens: Tokens) =>
merge(
{},
makeSizeRules(tokens, 'height'),
makeSizeRules(tokens, 'minHeight'),
makeSizeRules(tokens, 'width'),
width,
);
6 changes: 6 additions & 0 deletions lib/atoms/normalizeAtoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ export default (
xxlarge: atoms.marginRightDesktop_xxlarge,
xxsmall: atoms.marginRightDesktop_xxsmall,
},
minHeight: {
largeText: atoms.height_largeText,
largeTextInline: atoms.height_largeTextInline,
standardText: atoms.height_standardText,
standardTextInline: atoms.height_standardTextInline,
},
paddingBottom: {
none: atoms.paddingBottom_none,
large: atoms.paddingBottom_large,
Expand Down
4 changes: 4 additions & 0 deletions lib/components/Box/Box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Transition,
Transform,
Width,
IconSize,
} from '../../themes/theme';

function getResponsiveClasses<AtomName extends string>(
Expand Down Expand Up @@ -48,6 +49,7 @@ export interface BoxProps extends ResetProps {
boxShadow?: BoxShadow;
transform?: Transform;
transition?: Transition;
minHeight?: IconSize;
width?: Width;
}

Expand All @@ -71,6 +73,7 @@ export default class Box extends Component<BoxProps> {
boxShadow,
transition,
transform,
minHeight,
width,
className,
...restProps
Expand All @@ -89,6 +92,7 @@ export default class Box extends Component<BoxProps> {
atoms.boxShadow[boxShadow!],
atoms.transition[transition!],
atoms.transform[transform!],
atoms.minHeight[minHeight!],
atoms.width[width!],
marginTop &&
getResponsiveClasses(
Expand Down
8 changes: 1 addition & 7 deletions lib/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,7 @@ export default class Checkbox extends Component<CheckboxProps, State> {
</Box>
) : null}
</div>
{message !== false ? (
<FieldMessage
id={fieldMessageId}
tone={tone}
message={message}
/>
) : null}
<FieldMessage id={fieldMessageId} tone={tone} message={message} />
</div>
);
}}
Expand Down
2 changes: 1 addition & 1 deletion lib/components/FieldLabel/FieldLabel.css.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default {
'.root': {
'.spaceBetween': {
justifyContent: 'space-between',
},
};
2 changes: 1 addition & 1 deletion lib/components/FieldLabel/FieldLabel.css.js.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is automatically generated.
// Please do not change this file!
export const root: string;
export const spaceBetween: string;
38 changes: 26 additions & 12 deletions lib/components/FieldLabel/FieldLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,40 @@ export interface FieldLabelProps {
label?: ReactNode;
secondaryLabel?: ReactNode;
tertiaryLabel?: ReactNode;
description?: ReactNode;
}

export default class FieldLabel extends Component<FieldLabelProps> {
static displayName = 'FieldLabel';

render() {
const { label, id, secondaryLabel, tertiaryLabel } = this.props;
const {
id,
label,
secondaryLabel,
tertiaryLabel,
description,
} = this.props;

return label ? (
<Box paddingBottom="xsmall" display="flex" className={styles.root}>
<label htmlFor={id}>
<Text component="span">
<Strong>{label}</Strong>
{secondaryLabel ? (
<Secondary>&nbsp;({secondaryLabel})</Secondary>
) : null}
</Text>
</label>
{tertiaryLabel ? (
<Text component="span">&nbsp;{tertiaryLabel}</Text>
<Box paddingBottom="xsmall">
<Box component="span" display="flex" className={styles.spaceBetween}>
<label htmlFor={id}>
<Text component="span">
<Strong>{label}</Strong>
{secondaryLabel ? (
<Secondary>&nbsp;({secondaryLabel})</Secondary>
) : null}
</Text>
</label>
{tertiaryLabel ? (
<Text component="span">&nbsp;{tertiaryLabel}</Text>
) : null}
</Box>
{description ? (
<Box paddingTop="xxsmall" paddingBottom="xxsmall">
<Text color="secondary">{description}</Text>
</Box>
) : null}
</Box>
) : null;
Expand Down
10 changes: 7 additions & 3 deletions lib/components/FieldMessage/FieldMessage.css.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
export default {
'.content': {
display: 'flex',
'.root': {
justifyContent: 'flex-end',
},
'.icon': {
'.grow': {
flexGrow: 1,
},
'.fixedSize': {
flexShrink: 0,
flexGrow: 0,
},
};
5 changes: 3 additions & 2 deletions lib/components/FieldMessage/FieldMessage.css.js.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// This file is automatically generated.
// Please do not change this file!
export const content: string;
export const icon: string;
export const fixedSize: string;
export const grow: string;
export const root: string;
16 changes: 12 additions & 4 deletions lib/components/FieldMessage/FieldMessage.docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@ const docs: ComponentDocs = {
examples: [
{
label: 'Critical Field Message',
render: () => (
<FieldMessage tone="critical" message="This is a critical message." />
render: ({ id }) => (
<FieldMessage
id={id}
tone="critical"
message="This is a critical message."
/>
),
},
{
label: 'Positive Field Message',
render: () => (
<FieldMessage tone="positive" message="This is a positive message." />
render: ({ id }) => (
<FieldMessage
id={id}
tone="positive"
message="This is a positive message."
/>
),
},
{
Expand Down
67 changes: 39 additions & 28 deletions lib/components/FieldMessage/FieldMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,61 @@ import ErrorIcon from '../icons/ErrorIcon/ErrorIcon';
import TickCircleIcon from '../icons/TickCircleIcon/TickCircleIcon';
import styles from './FieldMessage.css.js';

type FieldTone = 'neutral' | 'critical' | 'positive';

export interface FieldMessageProps extends TextProps {
id?: string;
tone?: 'neutral' | 'critical' | 'positive';
id: string;
message: ReactNode | false;
tone?: FieldTone;
secondaryMessage?: ReactNode;
}

const renderIcon = (tone: FieldMessageProps['tone']) => {
if (tone === 'critical') {
return (
<Box paddingRight="xsmall" className={styles.icon}>
<ErrorIcon fill="critical" />
</Box>
);
const renderIcon = (tone: FieldTone = 'neutral') => {
if (tone === 'neutral') {
return null;
}

if (tone === 'positive') {
return (
<Box paddingRight="xsmall" className={styles.icon}>
<TickCircleIcon fill="positive" />
</Box>
);
}
const Icon: Record<FieldTone, ReactNode> = {
neutral: null,
critical: <ErrorIcon fill="critical" />,
positive: <TickCircleIcon fill="positive" />,
};

return null;
return (
<Box paddingRight="xsmall" className={styles.fixedSize}>
{Icon[tone]}
</Box>
);
};

export default class FieldMessage extends Component<FieldMessageProps> {
static displayName = 'FieldMessage';

render() {
const { id, tone = 'neutral', message } = this.props;
const { id, tone = 'neutral', message, secondaryMessage } = this.props;

return message === false ? null : (
<ThemeConsumer>
{theme => (
<Box id={id} paddingBottom="small" tabIndex={-1}>
<Text color={tone}>
<div className={styles.content}>
{/* This element acts as a min-height, preserving vertical space for the message: */}
<div className={theme.atoms.height.standardText} />
{renderIcon(tone)}
<div>{message}</div>
</div>
</Text>
{({ atoms }) => (
<Box
id={id}
paddingBottom="small"
display="flex"
className={styles.root}
>
<Box minHeight="standardText" className={styles.grow}>
<Text color={tone}>
<Box display="flex">
{renderIcon(tone)}
{message}
</Box>
</Text>
</Box>
{secondaryMessage ? (
<Box paddingLeft="xsmall" className={styles.fixedSize}>
{secondaryMessage}
</Box>
) : null}
</Box>
)}
</ThemeConsumer>
Expand Down
8 changes: 1 addition & 7 deletions lib/components/Radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,7 @@ export default class Radio extends Component<RadioProps, State> {
</Box>
) : null}
</div>
{message !== false ? (
<FieldMessage
id={fieldMessageId}
tone={tone}
message={message}
/>
) : null}
<FieldMessage id={fieldMessageId} tone={tone} message={message} />
</div>
);
}}
Expand Down
24 changes: 24 additions & 0 deletions lib/components/TextArea/TextArea.css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export default {
'.root': {
position: 'relative',
},
'.textarea': {
resize: 'vertical',
'&:focus': {
outline: 'none',
},
},
'.focusOverlay': {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
opacity: 0,
pointerEvents: 'none',
transition: 'opacity 0.2s',
'.textarea:focus ~ &': {
opacity: 1,
},
},
};
5 changes: 5 additions & 0 deletions lib/components/TextArea/TextArea.css.js.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This file is automatically generated.
// Please do not change this file!
export const focusOverlay: string;
export const root: string;
export const textarea: string;
Loading

0 comments on commit 3123068

Please sign in to comment.