import { withTheme } from 'emotion-theming'; import React, { FC } from 'react'; import { TwitterEditorTheme } from '../twitter-theme'; export interface CharacterCountIndicatorProps { /** An object describing the total characters and characters remaining */ characters?: { total: number; used: number }; size?: number; strokeWidth?: number; /** The number of characters remaining at which to display a warning */ warningThreshold?: number; theme: TwitterEditorTheme; } const CharacterCountIndicatorComponent: FC = ({ characters = { total: 280, used: 290 }, size = 27, strokeWidth = 3, warningThreshold = 18, theme, }) => { const { colors, font } = theme; const remainingCharacters = characters.total - characters.used; const warn = remainingCharacters <= warningThreshold; const ratio = characters.used / characters.total; const strokeColor = remainingCharacters < 0 ? colors.error : warn ? colors.warn : colors.primary; // SVG centers the stroke width on the radius, subtract out so circle fits in square const radius = (size - strokeWidth) / 2; // Arc length at 100% coverage is the circle circumference const dashArray = radius * Math.PI * 2; // Scale 100% coverage overlay with the actual percent const dashOffset = dashArray - dashArray * (ratio > 1 ? 1 : ratio); return (
{warn && (
{remainingCharacters}
)}
); }; interface CharacterCountCircleProps { size: number; radius: number; strokeWidth: number; strokeColor: string; dashArray: number; dashOffset: number; } const CharacterCountCircle: FC = ({ size, radius, strokeWidth, strokeColor, dashArray, dashOffset, }) => ( ); export const CharacterCountIndicator = withTheme(CharacterCountIndicatorComponent);