import _ from 'lodash'; import { withBluefishFn } from '../bluefish'; import { measureText } from '../measureText'; import { NewBBox } from '../NewBBox'; // TODO: allow text within the text element instead of on contents arg export type TextProps = React.SVGProps & { contents: string } & Partial<{ x: number; y: number; }>; // TODO: use 'alphabetic' baseline in renderer? may need to figure out displacement again // TODO: maybe use https://airbnb.io/visx/docs/text? // TODO: maybe use alignmentBaseline="baseline" to measure the baseline as well?? need to add it as // a guide // TODO: very close to good alignment, but not quite there. Can I use more of the canvas // measurements somehow? export const Text = withBluefishFn( (props: TextProps) => { const partialNoUndef = _.pickBy(props, (v) => v !== undefined); const { fontStyle, fontWeight, fontSize, fontFamily } = { fontFamily: 'sans-serif', fontSize: '12px', fontWeight: 'normal', ...partialNoUndef, }; const measurements = measureText( props.contents, `${fontStyle ?? ''} ${fontWeight ?? ''} ${fontSize ?? ''} ${fontFamily ?? ''}`, ); // TODO: really need to figure out semantics of intrinsic vs. extrinsic dimensions return () => ({ left: 0, top: 0, width: measurements.width, height: measurements.fontHeight }); }, (props: TextProps & { $bbox?: Partial }) => { const { $bbox, ...rest } = props; return ( {props.contents} ); }, );