Files
fn_registry/frontend/functions/ui/sticker_picker.md
T
egutierrez 47fac22230 chore: auto-commit (799 archivos)
- .claude/CLAUDE.md
- .claude/commands/subagentes.md
- .claude/rules/INDEX.md
- .mcp.json
- bash/functions/cybersecurity/analyze_dns.md
- bash/functions/cybersecurity/audit_http_headers.md
- bash/functions/cybersecurity/audit_ssh_config.md
- bash/functions/cybersecurity/check_firewall.md
- bash/functions/cybersecurity/detect_suspicious_users.md
- bash/functions/cybersecurity/encrypt_file.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:28:20 +02:00

106 lines
3.8 KiB
Markdown

---
name: sticker_picker
kind: component
lang: ts
domain: ui
version: "1.0.0"
framework: react
purity: impure
signature: "StickerPicker(props: StickerPickerProps): JSX.Element"
description: "Selector de emoji/sticker encapsulado en un Popover de Mantine. Monta emoji-mart Picker una sola vez para evitar re-creaciones en cada render."
tags: [emoji, sticker, picker, popover, mantine, emoji-mart, react, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports:
- "@mantine/core"
- "@emoji-mart/data"
- "emoji-mart"
tested: false
tests: []
test_file_path: ""
file_path: "frontend/functions/ui/sticker_picker.tsx"
props:
- name: opened
type: "boolean"
required: true
description: "Controla si el Popover está abierto."
- name: onClose
type: "() => void"
required: true
description: "Callback invocado al cerrar (click fuera, Escape, o tras selección)."
- name: onSelect
type: "(emoji: string) => void"
required: true
description: "Callback invocado con el emoji seleccionado. Prefiere unicode nativo; si no está disponible usa shortcode."
- name: target
type: "React.ReactNode"
required: true
description: "Elemento ancla que dispara el Popover."
- name: theme
type: '"dark" | "light" | "auto"'
required: false
description: 'Tema visual del Picker de emoji-mart. Por defecto "dark".'
- name: position
type: 'PopoverProps["position"]'
required: false
description: 'Posición del Popover respecto al ancla. Por defecto "bottom-start".'
emits: [onClose, onSelect]
has_state: false
output: "Popover de Mantine con emoji-mart Picker embebido. Tras selección emite onSelect(emoji) y onClose()."
params:
- name: opened
desc: "Estado de visibilidad del picker. Gestionado por el componente padre."
- name: onClose
desc: "Se llama cuando el picker debe cerrarse."
- name: onSelect
desc: "Se llama con el string unicode o shortcode del emoji elegido."
- name: target
desc: "Nodo React que actúa como ancla del Popover (generalmente un botón o icono)."
- name: theme
desc: 'Tema de color del picker. Valores: "dark" | "light" | "auto". Por defecto "dark".'
- name: position
desc: 'Posición del Popover. Cualquier valor de PopoverProps["position"] de Mantine. Por defecto "bottom-start".'
---
## Ejemplo
```tsx
import { useState } from "react";
import { ActionIcon } from "@mantine/core";
import { StickerPicker } from "@fn_library/sticker_picker";
function MyCard() {
const [pickerOpen, setPickerOpen] = useState(false);
const [sticker, setSticker] = useState<string | null>(null);
return (
<StickerPicker
opened={pickerOpen}
onClose={() => setPickerOpen(false)}
onSelect={(emoji) => setSticker(emoji)}
target={
<ActionIcon onClick={() => setPickerOpen((o) => !o)}>
{sticker ?? "😀"}
</ActionIcon>
}
theme="dark"
position="bottom-start"
/>
);
}
```
## Notas
**Dependencias externas requeridas** (no incluidas en el registry):
```bash
pnpm add @emoji-mart/data emoji-mart
```
El componente interno `PickerInner` instancia `emoji-mart` Picker con `useEffect` y lo monta en un `<div ref>`. El cleanup borra el `innerHTML` del div al desmontar. `onSelectRef` mantiene el callback actualizado sin recrear la instancia en cada render del padre. El prop `theme` se pasa al montar — cambios posteriores de `theme` no provocan remontaje (la instancia mantiene el tema inicial), comportamiento aceptable para la mayoría de casos de uso. Si se necesita cambio dinámico de tema, destructurar el key del componente padre fuerza remontaje.
El Popover usa `withinPortal` para evitar clipping por overflow de contenedores padre, `closeOnClickOutside` y `closeOnEscape` para comportamiento estándar, y `trapFocus={false}` para que emoji-mart gestione el foco internamente.