Lynx/Modules/Emoji Picker/EmojiGrid
@sigx/lynx-emoji · Stable · Component library

EmojiGrid#

The headless recycled glyph grid — a native <list> recycler in flow layout, so only the on-screen cells exist regardless of how many emoji you feed it. One of the parts EmojiPicker is assembled from, for when you want a custom layout.

Import#

TSX
import { EmojiGrid } from '@sigx/lynx-emoji';

Basic usage#

EmojiGrid takes a flat array of EmojiDatum and renders them as a tappable recycler. Because flex / percent heights on the native list resolve to zero, class and style land on a self-measuring wrapper that pins the list to a concrete px height — first paint is one frame after mount. onPick fires on tap; onPickTone fires on long-press of a tonal emoji (one that has uniform skin-tone variants).

TSX
import { EmojiGrid, enData } from '@sigx/lynx-emoji';

function AllEmoji({ onPick }: { onPick: (glyph: string) => void }) {
    return (
        <view style={{ height: '320px' }}>
            <EmojiGrid
                emojis={enData.emojis}
                columns={8}
                cellSize={26}
                onPick={(datum) => onPick(datum.e)}
            />
        </view>
    );
}

Driving it from a context#

EmojiGrid is one of the parts EmojiPicker composes. To build a custom surface, wire it against a context from createEmojiContext (or one read from an EmojiProvider via useEmojiContext). The skinTone store gives you the sticky grid-wide tone, and recents.push records a pick — here a recents strip:

TSX
import { EmojiGrid, createEmojiContext, enData } from '@sigx/lynx-emoji';

function RecentStrip() {
    const ctx = createEmojiContext(enData, { recentsCap: 16 });
    const tone = ctx.skinTone.state.tone;

    return (
        <EmojiGrid
            emojis={ctx.recents.recents}
            tone={tone}
            columns={8}
            cellSize={26}
            onPick={(datum) => ctx.recents.push(datum)}
        />
    );
}

The tone prop selects which skin-tone variant a cell renders; glyphForTone(datum, tone) is what resolves it internally, falling back to the base glyph for non-tonal emoji. Long-press a tonal emoji and onPickTone fires with that datum so you can open a SkinTonePopover.

Custom cells#

Pass renderCell to replace a cell's content (it renders inside the cell's Pressable), and cellClass to theme each cell:

TSX
import { EmojiGrid, enData } from '@sigx/lynx-emoji';
import { Text } from '@sigx/lynx-heroui';

function LabeledGrid() {
    return (
        <view style={{ height: '320px' }}>
            <EmojiGrid
                emojis={enData.emojis}
                cellClass="emoji-cell"
                renderCell={(datum, glyph) => <Text>{glyph}</Text>}
                onPick={(datum) => console.log(datum.n)}
            />
        </view>
    );
}

Props#

PropTypeDescription
emojisEmojiDatum[]Required. The emoji to render, as a flat array (e.g. a category slice, search hits, or recents).
toneSkinToneSkin tone applied grid-wide; 0 is the base glyph, 1..5 are light to dark. Default 0.
columnsnumberNumber of columns in the flow layout. Default 8.
cellSizenumberCell edge length in px. Default 26.
classstringClasses on the self-measuring wrapper that pins the list height.
cellClassstringClasses applied to each cell.
renderCellEmojiRenderCell(datum, glyph) => JSXElement — replaces a cell's content (rendered inside the cell's Pressable).
styleRecord<string, string | number>Inline style on the wrapper.

SkinTone, EmojiDatum and EmojiRenderCell are documented in the API reference.

Events#

EventTypeDescription
onPick(datum: EmojiDatum) => voidFired on tap, with the tapped emoji.
onPickTone(datum: EmojiDatum) => voidFired on long-press of a tonal emoji (one with uniform tone variants, datum.s), to open a skin-tone chooser.

See also#