All files / AxisLabel AxisLabel.tsx

100% Statements 13/13
100% Branches 16/16
100% Functions 1/1
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123            176x   176x   176x                                                       176x                   8x   8x 8x 8x   8x                                       176x 176x 176x                 176x                                                                          
import _ from 'lodash';
import React from 'react';
import PropTypes from 'react-peek/prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import { StandardProps, omitProps } from '../../util/component-types';
 
const cx = lucidClassNames.bind('&-AxisLabel');
 
const { number, string, oneOf, object } = PropTypes;
 
const defaultProps = {
	color: '#000',
};
 
export interface IAxisLabelProps extends StandardProps {
	/** Height of the margin this label should fit into. */
	height: number;
 
	/** Width of the margin this label should fit into. */
	width: number;
 
	/** Strings should match an existing color class unless they start with a '#' 
	 * for specific colors. E.g.:
	 * 
		- \`COLOR_0\`
		- \`COLOR_GOOD\`
		- \`'#123abc'\`
	`*/
	color: string;
 
	/** Contents of the label, should only ever be a string since we use a
		\`text\` under the hood. */
	label: string;
 
	/** Determine orientation of the label. */
	orient: 'top' | 'bottom' | 'left' | 'right';
}
 
export const AxisLabel = (props: IAxisLabelProps): React.ReactElement => {
	const {
		height,
		width,
		orient,
		label,
		color,
		style,
		className,
		...passThroughs
	} = props;
 
	const isH = orient === 'top' || orient === 'bottom';
	const isCustomColor = _.startsWith(color, '#');
	const colorStyle = isCustomColor ? { fill: color } : null;
 
	return (
		<text
			{...omitProps(passThroughs, undefined, _.keys(AxisLabel.propTypes))}
			style={{
				...colorStyle,
				...style,
			}}
			className={cx(className, '&', {
				[`&-${color}`]: !isCustomColor,
			})}
			x={isH ? width / 2 : (height / 2) * -1}
			y={orient === 'right' ? width : orient === 'bottom' ? height : 0}
			dy={orient === 'top' || orient === 'left' ? '1em' : '-.32em'}
			transform={isH ? '' : 'rotate(-90)'}
		>
			{label}
		</text>
	);
};
 
AxisLabel.defaultProps = defaultProps;
AxisLabel.displayName = 'AxisLabel';
AxisLabel.peek = {
	description: `
		\`AxisLabel\` is used within a \`svg\`
 
		Centered labels for axes that typically are fit into the margins of a
		chart.
	`,
	categories: ['visualizations', 'chart primitives'],
};
AxisLabel.propTypes = {
	style: object`
		Passed through to the root element.
	`,
 
	className: string`
		Appended to the component-specific class names set on the root element.
	`,
 
	height: number.isRequired`
		Height of the margin this label should fit into.
	`,
 
	width: number.isRequired`
		Width of the margin this label should fit into.
	`,
 
	color: string`
		Strings should match an existing color class unless they start with a '#'
		for specific colors. E.g.:
 
		- \`COLOR_0\`
		- \`COLOR_GOOD\`
		- \`'#123abc'\`
	`,
 
	label: string`
		Contents of the label, should only ever be a string since we use a
		\`text\` under the hood.
	`,
 
	orient: oneOf(['top', 'bottom', 'left', 'right'])`
		Determine orientation of the label.
	`,
};
 
export default AxisLabel;