15
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Inline SVG の foreignObject で input を置く

Last updated at Posted at 2018-10-09

React でSVGベースのアプリを作ってて、途中で inline に input 要素を置きたかったがSVGにはそういうインタラクティブな要素がない。座標計算してポップアップを置いてもいいが、だるい。

と思っていろいろ考えてたが、svg には inline で HTML を埋め込める foreignObject という要素があるのを思い出した。

React の SVG 要素でなんやかんややって値を取る


<svg width={800} height={600}>
  <g transform="translate(60,10)">
    <foreignObject
      x={0}
      y={0}
      width="110"
      height="32"
      style={{ background: "red" }}
    >
      <input
        style={{ width: 100 }}
        defaultValue="10px"
        onChange={ev => {
          console.log("value", ev.target.value);
        }}
      />
    </foreignObject>
  </g>
</svg>;

最終的にこうなった

type InlineInputProps = {
  width: number;
  height: number;
  value: string;
  onChange: (ev: any) => void;
};
class InlineInput extends React.Component<
  InlineInputProps,
  {
    value: string;
  }
> {
  constructor(props: InlineInputProps) {
    super(props);
    this.state = {
      value: this.props.value
    };
  }
  render() {
    return (
      <foreignObject width={this.props.width} height={this.props.height}>
        <input
          style={{
            padding: 0,
            margin: 0,
            width: this.props.width,
            height: this.props.height,
            outline: "none",
            boxSizing: "border-box"
          }}
          value={this.state.value}
          onChange={ev => {
            this.props.onChange(ev);
            this.setState({ value: ev.target.value });
          }}
        />
      </foreignObject>
    );
  }
}
15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?