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 124 125            5x   5x   5x                                                       5x                   27x   27x 27x 27x   27x                                       5x 5x 5x       5x                                                                                        
import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import { StandardProps } 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
			{...(passThroughs as any)}
			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 = {
	/**
		Passed through to the root element.
	*/
	style: object,
 
	/**
		Appended to the component-specific class names set on the root element.
	*/
	className: string,
 
	/**
		Height of the margin this label should fit into.
	*/
	height: number.isRequired,
 
	/**
		Width of the margin this label should fit into.
	*/
	width: number.isRequired,
 
	/**
		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: oneOf(['top', 'bottom', 'left', 'right']),
};
 
export default AxisLabel;