feat(fase-19): wire EmojiPicker into 4 integration sites + EP-E specs
Replaces the four legacy hardcoded emoji arrays (settings avatar,
onboarding-create, CreateCollectiveModal, manage-collective rename) with
`<EmojiPicker selected={…} onSelect={…} />`. The shared component
delivers ~280 codepoints across 4 tabs instead of the previous 8–24
per surface, with consistent layout and behaviour.
Backwards-incompatible testid change on the manage page: the old
`collective-emoji-option-{e}` per-cell testid is gone — every cell now
lives under the picker's `emoji-picker-cell-{e}` namespace. Two existing
specs (onboarding O-02 + rename MC-01a) are updated to drive the new
tab → cell flow.
New e2e file `tests/e2e/emoji-picker.test.ts` covers EP-E-01..02:
- EP-E-01 — Ana on /settings picks 🍎 from "Comida"; DB row updates.
- EP-E-02 — Eva on /onboarding creates a collective with 🐱 from
"Animales"; sidebar reflects the choice.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
import { currentUser } from '$lib/stores/auth';
|
||||
import { currentCollective, collectiveMembers, userCollectives } from '$lib/stores/collective';
|
||||
import Avatar from '$lib/components/Avatar.svelte';
|
||||
import EmojiPicker from '$lib/components/EmojiPicker.svelte';
|
||||
import Spinner from '$lib/components/Spinner.svelte';
|
||||
import type { FeatureFlags, SectionKey, ItemFrequency } from '@colectivo/types';
|
||||
import { SECTION_KEYS } from '@colectivo/types';
|
||||
@@ -174,11 +175,9 @@
|
||||
let nameSaved = $state(false);
|
||||
let emojiPickerOpen = $state(false);
|
||||
|
||||
const EMOJI_OPTIONS = [
|
||||
'🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏨',
|
||||
'🏩', '🏪', '🏫', '🏬', '🏭', '🏯', '🏰', '🗼',
|
||||
'🌆', '🌇', '🌃', '🌉', '🏙️', '⛺', '🌴', '🌵'
|
||||
];
|
||||
// Fase 19 — emoji catalog moved into the shared `EmojiPicker` component.
|
||||
// `selectEmoji` (admin-write path) is still local because it includes
|
||||
// the closed-state toggle + the persistence round-trip.
|
||||
|
||||
// Keep nameDraft in sync with $currentCollective.
|
||||
$effect(() => {
|
||||
@@ -635,19 +634,11 @@
|
||||
</button>
|
||||
</div>
|
||||
{#if emojiPickerOpen}
|
||||
<div class="mt-3 grid grid-cols-8 gap-1 rounded-lg bg-surface-container-low p-3 dark:bg-surface-raised">
|
||||
{#each EMOJI_OPTIONS as e}
|
||||
<button
|
||||
type="button"
|
||||
data-testid="collective-emoji-option-{e}"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-xl transition-colors
|
||||
{$currentCollective.emoji === e
|
||||
? 'bg-slate-900 dark:bg-slate-100'
|
||||
: 'hover:bg-slate-100 dark:hover:bg-slate-700'}"
|
||||
onclick={() => void selectEmoji(e)}
|
||||
aria-label={e}
|
||||
>{e}</button>
|
||||
{/each}
|
||||
<div class="mt-3 rounded-lg bg-surface-container-low p-3 dark:bg-surface-raised">
|
||||
<EmojiPicker
|
||||
selected={$currentCollective.emoji}
|
||||
onSelect={(e) => void selectEmoji(e)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { logout } from '$lib/auth';
|
||||
import Avatar from '$lib/components/Avatar.svelte';
|
||||
import ImageCropper from '$lib/components/ImageCropper.svelte';
|
||||
import EmojiPicker from '$lib/components/EmojiPicker.svelte';
|
||||
import ThemeToggle from '$lib/components/ThemeToggle.svelte';
|
||||
import SyncConflictsPanel from '$lib/components/SyncConflictsPanel.svelte';
|
||||
import TagChip from '$lib/components/TagChip.svelte';
|
||||
@@ -51,12 +52,9 @@
|
||||
let cropperFile = $state<File | null>(null);
|
||||
let uploading = $state(false);
|
||||
|
||||
const EMOJI_GRID = [
|
||||
'😀','😎','🥳','🤓','👻','🐱','🐶','🦊',
|
||||
'🐸','🦁','🐻','🐼','🐨','🐯','🦄','🐧',
|
||||
'🦋','🌈','⭐','🌙','☀️','🌊','🌴','🌺',
|
||||
'🍕','🍦','🎸','🎯','🚀','⚽','🎮','🎨'
|
||||
];
|
||||
// Fase 19 — emoji avatars expansion. The legacy `EMOJI_GRID` hardcoded
|
||||
// array (8 faces + 24 others) is replaced by the tabbed `EmojiPicker`
|
||||
// component which surfaces ~280 codepoints across 4 categories.
|
||||
|
||||
const keycloakAccountUrl = `${PUBLIC_KEYCLOAK_URL}/realms/${PUBLIC_KEYCLOAK_REALM}/account`;
|
||||
|
||||
@@ -413,16 +411,7 @@
|
||||
</div>
|
||||
|
||||
{#if avatarType === 'emoji'}
|
||||
<div class="grid grid-cols-8 gap-1">
|
||||
{#each EMOJI_GRID as e}
|
||||
<button
|
||||
onclick={() => selectEmojiAvatar(e)}
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-xl
|
||||
{avatarEmoji === e ? 'bg-slate-900 dark:bg-slate-100' : 'hover:bg-slate-100 dark:hover:bg-slate-700'}"
|
||||
aria-label={e}
|
||||
>{e}</button>
|
||||
{/each}
|
||||
</div>
|
||||
<EmojiPicker selected={avatarEmoji} onSelect={selectEmojiAvatar} />
|
||||
{:else if avatarType === 'upload'}
|
||||
<label
|
||||
class="flex cursor-pointer items-center gap-2 rounded-lg border border-dashed
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { getSupabase } from '$lib/supabase';
|
||||
import { currentCollective, userCollectives } from '$lib/stores/collective';
|
||||
import EmojiPicker from '$lib/components/EmojiPicker.svelte';
|
||||
import * as m from '$lib/paraglide/messages';
|
||||
|
||||
type Tab = 'create' | 'join';
|
||||
@@ -14,11 +15,9 @@
|
||||
let creating = $state(false);
|
||||
let createError = $state<string | null>(null);
|
||||
|
||||
const EMOJI_OPTIONS = [
|
||||
'🏠', '🏡', '🏢', '🏣', '🏤', '🏥', '🏦', '🏨',
|
||||
'🏩', '🏪', '🏫', '🏬', '🏭', '🏯', '🏰', '🗼',
|
||||
'🌆', '🌇', '🌃', '🌉', '🏙️', '⛺', '🌴', '🌵'
|
||||
];
|
||||
// Fase 19 — emoji catalog moved to the shared `EmojiPicker` component
|
||||
// (4 tabs, ~280 codepoints). The legacy 24-item `EMOJI_OPTIONS` array
|
||||
// is gone.
|
||||
|
||||
// Join via invite link
|
||||
let inviteLink = $state('');
|
||||
@@ -126,19 +125,10 @@
|
||||
<p class="mb-2 text-sm font-medium text-slate-700 dark:text-slate-300">
|
||||
{m.onboarding_collective_emoji()}
|
||||
</p>
|
||||
<div class="grid grid-cols-8 gap-1">
|
||||
{#each EMOJI_OPTIONS as e}
|
||||
<button
|
||||
type="button"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-xl transition-colors
|
||||
{collectiveEmoji === e
|
||||
? 'bg-slate-900 dark:bg-slate-100'
|
||||
: 'hover:bg-slate-100 dark:hover:bg-slate-700'}"
|
||||
onclick={() => (collectiveEmoji = e)}
|
||||
aria-label={e}
|
||||
>{e}</button>
|
||||
{/each}
|
||||
</div>
|
||||
<EmojiPicker
|
||||
selected={collectiveEmoji}
|
||||
onSelect={(e) => (collectiveEmoji = e)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if createError}
|
||||
|
||||
Reference in New Issue
Block a user