본문으로 건너뛰기

PlHighlight

읽고 있던 글 안에서, 찾고 있던 단어를 표시합니다. 이 컴포넌트는 스타일링만이 아니라 검색 그 자체입니다. query는 검색창이 들고 있는 바로 그 값입니다.

React
tsx
import { PlHighlight } from 'plass-ui';

<PlHighlight query={search}>{result.summary}</PlHighlight>;
dart
import 'package:plass_ui/plass_ui.dart';

PlHighlight(result.summary, query: search);

Props

Prop타입기본값설명
query * string | string[] | RegExp찾을 것. 문자열은 한 단어, 배열은 여러 개이며 긴 것부터 시도합니다. RegExp는 쓰인 그대로 쓰이되 global 플래그가 켜지고, caseSensitive와 wholeWord는 무시됩니다
variant공통'solid' | 'glass' | 'ghost''solid'표시의 재질. solid는 형광펜, glass는 헤어라인 상자, ghost는 강조색뿐입니다. 여기서 glass는 흐림 없이 쓰입니다 — 20px짜리 인라인 상자 뒤에는 문지를 만한 배경이 없습니다
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''warning'의미론적 색 역할. 기본값이 warning인 것은 임의가 아닙니다 — 그러데이션이 밝고 잉크가 어두운 유일한 계열이라, solid warning 표시가 검은 글자 위의 노란 형광펜이 됩니다
caseSensitivebooleanfalsea와 A를 다른 글자로 볼지
wholeWordbooleanfalse단어 하나로 서 있을 때만 표시할지 — cat이 "cat"은 표시하고 "concatenate"는 표시하지 않게. 띄어쓰기로 구를 나누지 않는 한국어·일본어에서는 의미가 거의 없고, 그래서 기본값이 꺼짐입니다
underlinebooleanfalse표시에 밑줄도 긋습니다. 모든 variant와 겹칩니다
weight'regular' | 'medium' | 'semibold' | 'bold'표시의 굵기. 생략하면 주변 글자의 굵기를 그대로 씁니다 — 표면이 이미 "이것"이라고 말하고 있고, 문장 속에서 굵어진 단어는 줄 전체의 리듬을 바꿉니다
childrenReactNode검색할 텍스트. 요소는 안으로 걸어 들어가되 그대로 남으므로, strong 안의 일치도 표시되고 strong도 살아남습니다
Prop타입기본값설명
text * String검색할 텍스트, 첫 번째 위치 인자. React와 달리 위젯 트리가 아닙니다 — Widget은 불투명해서 안의 텍스트에 닿을 수 없습니다
query * Object찾을 것: String, RegExp, 또는 둘 중 하나의 List. Dart에 union이 없어 Object이고, 생성자가 단언합니다. 여러 개면 긴 것부터 시도합니다
variant공통PlassVariantPlassVariant.solid표시의 재질. solid는 형광펜, glass는 헤어라인 상자, ghost는 강조색뿐입니다. 여기서 glass는 흐림 없이 쓰입니다 — 20px짜리 인라인 상자 뒤에는 문지를 만한 배경이 없습니다
color공통PlassColorPlassColor.warning의미론적 색 역할. 기본값이 warning인 것은 임의가 아닙니다 — 그러데이션이 밝고 잉크가 어두운 유일한 계열이라, solid warning 표시가 검은 글자 위의 노란 형광펜이 됩니다
caseSensitiveboolfalsea와 A를 다른 글자로 볼지
wholeWordboolfalse단어 하나로 서 있을 때만 표시할지 — cat이 "cat"은 표시하고 "concatenate"는 표시하지 않게. 띄어쓰기로 구를 나누지 않는 한국어·일본어에서는 의미가 거의 없고, 그래서 기본값이 꺼짐입니다
underlineboolfalse표시에 밑줄도 긋습니다. 모든 variant와 겹칩니다
weightPlTypographyWeight?표시의 굵기. 생략하면 주변 글자의 굵기를 그대로 씁니다 — 표면이 이미 "이것"이라고 말하고 있고, 문장 속에서 굵어진 단어는 줄 전체의 리듬을 바꿉니다
styleTextStyle?표시되지 않은 글의 스타일. 주변 DefaultTextStyle 위에 병합됩니다
alignTextAlign?텍스트 정렬
linesint?이 줄 수로 잘라 말줄임합니다

네이티브 <span> 속성은 감싸는 요소에 그대로 전달됩니다. color는 여기서 Plass의 prop이라 전달 대상에서 제외됩니다.

텍스트는 첫 번째 위치 인자이고 위젯이 아니라 String입니다. 그 대가와 이유는 아래 중첩된 내용에 있습니다.

query의 타입은 Object인데, Dart에 없는 union을 쓰는 방법입니다. String, RegExp, 또는 둘 중 하나의 List이고, 생성자가 그것을 단언합니다.

size는 없고, 이것이 아마 가장 먼저 찾게 될 prop일 것입니다. 표시는 흐르는 글 안에 놓이므로 그 글의 크기여야 합니다. size prop은 틀릴 방법만 늘려 줍니다.

라이브러리 전체에서 공유 축(variant color)이 뜻하는 바는 prop 규칙에 있습니다.

Examples

query

문자열은 한 단어입니다. 배열은 여러 개이고 긴 것부터 시도합니다. 정규식의 교대(alternation)는 먼저 맞는 쪽이 이기므로, 그러지 않으면 ['data', 'database']data만 표시하고 base를 표시 바깥에 남깁니다.

RegExp는 쓰인 그대로 쓰입니다. caseSensitivewholeWord는 무시되는데, 정규식은 이미 그 둘을 스스로 나타내고 있기 때문입니다.

React

중첩된 내용

children은 문자열이 아니라 트리입니다. 요소는 안으로 걸어 들어가되 그 밖에는 손대지 않으므로, <strong> 안의 일치도 표시되고 <strong>도 살아남습니다. 문자열을 요구하는 것이 대부분의 라이브러리가 하는 일이고, 마크업이 들어 있는 첫 번째 검색 결과에서 곧바로 무너집니다.

React

Flutter 빌드는 String을 받고, 그것은 빠뜨린 것이 아니라 진짜 차이입니다. React의 children은 안으로 걸어 들어갈 props.children을 가진 요소의 트리이지만 Flutter의 Widget은 불투명합니다. 건네받은 Text 안의 문자열에 닿을 방법이 없고, 그 문자열을 표시한 채로 위젯을 다시 만들 방법은 더더욱 없습니다.

그래서 텍스트는 글자로 들어오고 표시는 span으로 나옵니다. 이 방식으로 다룰 수 없는 경우는 이미 중간에 스타일이 바뀌는 글이고, 이 컴포넌트가 존재하는 이유인 검색 결과는 문자열로 들어옵니다.

variant

여기서 glass는 일부러 흐리지 않습니다. 라이브러리에서 재질을 쓰는 대신 인용하는 유일한 자리입니다. 표시는 한 줄의 글 위에 놓인 높이 20px짜리 상자입니다. 뒤에 문지를 만한 배경이 없습니다.

React

color

기본값 warning은 임의로 고른 것이 아닙니다. 그러데이션이 밝고 잉크가 어두운 유일한 계열이라, solid warning 표시는 색 덩어리 위의 흰 글자가 아니라 검은 글자 위의 노란 형광펜이 됩니다.

React

Accessibility

  • 표시는 진짜 <mark>입니다. 독자에게 관련 있는 텍스트를 위한 요소이고, 그렇게 읽힙니다.
  • 여기에는 알아 둘 만한 결과가 하나 따라옵니다. 한 문단에서 열한 단어를 표시하는 것은 스크린리더에게 열한 가지가 중요하다고 알리는 것이고, 그것은 아무 말도 하지 않는 방법입니다. 표시는 몇 개의 일치를 위한 것입니다.
  • 전체 텍스트는 언제나 순서 그대로 남아 있습니다. 표시는 문자열을 나눌 뿐, 다시 쓰거나 빠뜨리지 않습니다.
  • 표시는 아주 약간의 padding을 더하고 같은 양을 음수 margin으로 되돌려 줍니다. 그래서 표시된 줄은 표시 전과 정확히 같은 길이입니다. 표시가 주변 글자를 움직여서는 안 됩니다.
  • 스크린리더에 닿는 것은 문자열 전체이고, 순서대로 한 번 읽힙니다. 표시는 문단 안에 놓인 위젯이라, 그렇게 하지 않으면 표시되지 않은 글 사이사이에 placeholder가 늘어선 것을 듣게 됩니다.
  • 그래도 표시는 몇 개의 일치를 위한 것입니다. 여기서는 표시가 스스로를 알리지 않으니 이유가 눈으로 보는 쪽에 있습니다. 한 문단에서 열한 단어를 표시하는 것은 아무것도 표시하지 않는 방법입니다.
  • 전체 텍스트는 언제나 순서 그대로 남아 있습니다. 표시는 문자열을 나눌 뿐, 다시 쓰거나 빠뜨리지 않습니다.

React 빌드와 다른 점

ReactFlutter이유
트리로서의 childrenString으로서의 텍스트Widget은 불투명합니다. 건네받은 위젯 안의 텍스트에 닿을 방법이 없습니다. 중첩된 내용을 보세요.
읽히는 진짜 <mark>위젯 span, 그리고 라벨로서의 문자열 전체Flutter에는 mark role이 없습니다. 대신 있는 것은 여전히 한 문장으로 읽혀야 하는 문단입니다.
표시가 자기 padding을 상쇄함상쇄하지 않음음수 margin은 Flutter의 Padding이 받아 주지 않습니다. 표시는 표시하는 단어보다 4px 넓고, 흐르는 글 위에서 이 문서가 밝혀야 할 차이가 그것입니다.
줄바꿈을 넘는 box-decoration-clone표시는 줄을 넘지 않음표시는 줄 안의 위젯 하나라, 긴 구절은 자기 표면 안에서 줄바꿈하는 대신 통째로 다음 줄로 넘어갑니다.
caseSensitive, wholeWord같은 이름, 같은 두 규칙wholeWord는 여기서도 모든 문자 체계의 글자·숫자·밑줄을 셉니다. café에는 뜻대로 동작하고, 한국어에는 거의 아무 뜻이 없습니다.

Released under the MIT License