はみ出る文字をいい感じにする Input
こんにちは。
編集ボタンを押したら編集できて、それ以外はテキストを表示するだけのフィールドを作ろうとしたところ、いい感じのフィールドができたので作り方のメモ。「編集ボタンを押したら編集できて、それ以外はテキストを表示するだけのフィールド」というのは、以下の gif のようなフィールドです。
編集と表示の切り替え方法
切り替えにはinput
のreadonly
用いています。デフォルトの属性の切り替えだけでできるので、実装もとても簡単です。
export const TextField = (props: { isEdit: boolean }) => {
const ref = useRef() as React.MutableRefObject<HTMLInputElement>
useEffect(() => {
// 編集ボタン押下時にフィールドにフォーカスさせる
if (props.isEdit) ref.current.focus()
}, [props.isEdit])
return (
<input
ref={ref}
readOnly={!props.isEdit}
/>
)
}
考えられる不便な点
ただ、この実装では少し懸念点があります。
それは文字がフィールドをはみ出た場合に、ユーザーが見落としやすい点です。以下の画像は、ユーザーがフィールドいっぱいに文字を入力して保存した時の図です。フィールドの端まで hello で埋め尽くされていますね。
しかし、このフィールドの末尾は hello ではなく、goodbye でした。
上の画像を見ただけでは、「まだ続く文字がある」という認識がしづらく、見落としてしまう可能性があります。
不便さを解消する方法
このような事態を防ぎやすくする手法として、css
ではtext-overflow
というプロパティがあります。このプロパティは、テキストが範囲外まで表示される場合どのように表示するのかを定義できるプロパティですが、これは普通のテキストにはもちろん、input
の readonly 時にも適用することができます。
デモはこちらから確認できますが、今回利用したいのはellipsis
という設定値です。これを設定することで、範囲外にはみ出る文字を「...」という表示にすることができます。
実装は以下のようにすると実現することができます。(styled-components
を利用しています)
const Input = styled.input<{
background?: string
isEllipse?: boolean
}>`
${(props) => (props.background
? `background: ${props.background};`
: '')}
${(props) =>
props.isEllipsis
? `
text-overflow: ellipsis;
overflow-x: hidden;
`
: ''}
`
export const TextField = (props: { isEdit: boolean }) => {
const ref = useRef() as React.MutableRefObject<HTMLInputElement>
useEffect(() => {
// 編集ボタン押下時にフィールドにフォーカスさせる
if (props.isEdit) ref.current.focus()
}, [props.isEdit])
return (
<Input
ref={ref}
background={props.isEdit ? 'gray' : 'transparent'}
readOnly={!props.isEdit}
isEllipse={!props.isEdit}
/>
)
}
この実装におけるユーザーに優しそうな点
input
におけるtext-overflow: ellipse
の嬉しい点は、テキストをフォーカスすると ellipse が解除され、フィールドの値を確認できる点です。
下の gif のように、readonly
のinput
に対してフォーカスすると、設定されているtext-overflow: ellipse
が解除され、フィールドの中身を確認できるようになります。通常のテキストでは少し工夫をして実装(テキストにフォーカスされたら、css
を書き換えるなど)しないとできないと思いますが、input
についてはデフォルトの挙動で実現することができます。
ユーザーからすると、以下のようなメリットがありそうです。
1 「このフィールドには見えない値がある」という認識がしやすくなる
2. フォーカスすることで、編集ボタンを押下せずとも中身が確認できる利便性を保つことができる
終わりに
フィールド関連のコンポーネントは、ユーザーがほぼ必ず触れるコンポーネントになると思うので、より考えることが多いなあと思いました。今回のような実装をせずとも「フィールドにテキストの入力でき、編集と表示を切り替えられる」という機能自体は実現できますが、ひと工夫を入れることでより使いやすいコンポーネントになれる可能性があるとも感じました。(使いにくくなる可能性もありますが。。)
Discussion