|
|
4 months ago | |
|---|---|---|
| .. | ||
| README.md | 5 months ago | |
| highlight.css | 5 months ago | |
| highlight.svelte | 4 months ago | |
| index.ts | 5 months ago | |
| types.ts | 5 months ago | |
README.md
Eidos Highlight
Substring highlighter primitive. Wraps a <span> shell containing the
input text and replaces matches of query with <mark> elements
that inherit the same recipe as the standalone <Mark> primitive.
Composes inside any inline-flow primitive (Text, Heading, paragraph).
Superficie
<Highlight text="Hello world" query="world" />
<Highlight text={message} query={['error', 'failed']} color="threat" />
<Highlight text="Case study" query="case" ignoreCase={false} />
Baseline
Origen: air/components/typography/highlight (rama morfo-runtime).
Adaptaciones para eidos:
- Reuses Mark recipe: air's Highlight imported
../mark/mark.cssdirectly. Eidos keeps the same idea — the inner<mark>elements stampdata-markso the Mark recipe applies without duplication. - Palette canonized: same migration as Mark —
yellow / green / blue / red / purple→ intent vocabulary. - Default
fulfill: consistent with Mark. - Pure CSS: the highlight shell is
<span>+font: inherit. Air did the same.
Comparativa
| Capacidad | UIX Highlight | Mantine Highlight | Radix Themes | Chakra Highlight |
|---|---|---|---|---|
| Substring match | Sí | Sí | No | Sí |
| Multiple terms | Sí (query array) |
Sí (highlight array) |
No | Sí (query array) |
| Case-insensitive | Sí (ignoreCase) |
Sí (highlightStyles) |
No | Sí (styles.matchCase) |
| Color palette | Intent | free | No | colorScheme |
| Regex query | No (literal escape) | Yes (with prop) | No | No |
| Inherits typography | Sí | Sí | No | Sí |
Decisiones
- Inner marks reuse Mark recipe: avoids two parallel highlight surfaces. The Mark recipe is the single visual source.
- Outer shell is
<span>: keeps Highlight composable inline. Consumers wrap it inside<Text>/<Heading>for typography. queryis literal: each term is regex-escaped, so consumers can pass user input safely. Noregexopt-in today — if a power use case emerges, add apatternprop that accepts aRegExp.ignoreCasedefaulttrue: search-result UX expects case-insensitive matching. Opt out viaignoreCase={false}when the consumer needs case-sensitive logic (code search).- No empty-query gotcha: if
queryis empty / whitespace-only, render the text unchanged (no marks).
Eventos Sema
Highlight declara 0 eventos. Visual-only — el primitive es un formatter, no input.
Gaps
| Gap | Disposición | Detalle |
|---|---|---|
| Regex query support | diferir | Si emerge, añadir pattern: RegExp prop como alternativa a query. |
| Token / word-boundary match | diferir | Requiere parser; cubrir cuando llegue un caso real. |
| Snippet-based render override | diferir | Si un consumer necesita custom Mark per term, ya puede componer Mark manualmente sin Highlight. |
| Per-term different colors | diferir | Hoy todos los matches usan el mismo color. Si emerge, aceptar un map { term: color }. |
| Free hex color | descartar | Mismo razón que Mark — contrato de contraste. |
Referencias
- Mantine Highlight: https://mantine.dev/core/highlight/
- Chakra UI Highlight: https://chakra-ui.com/docs/components/highlight
- MDN
<mark>: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark
Passive justification
Visual-only (scope: ['eidos']). Una sola part Provider (<span data-highlight> shell). El primitive es un formatter: dado text +
query produce un árbol de segmentos, marcando los matches con
<mark data-mark>. Sin estados, sin keyboard, sin ARIA propia.
La recipe del mark inner es compartida con <Mark>.