feat: add profile language preferences and refine toast, dropdown and history UI
This commit is contained in:
@@ -8,9 +8,31 @@
|
||||
*/
|
||||
|
||||
import { EMOJI_GROUPS } from "@rustpad/emoji-data";
|
||||
import { t } from "@rustpad/i18n";
|
||||
|
||||
const RECENTS_KEY = "rustpad:recent-emojis";
|
||||
const MAX_RECENTS = 24;
|
||||
const GROUP_KEYS = new Map([
|
||||
["Smileys & Emotion", "emoji.group.smileysEmotion"],
|
||||
["People & Body", "emoji.group.peopleBody"],
|
||||
["Animals & Nature", "emoji.group.animalsNature"],
|
||||
["Food & Drink", "emoji.group.foodDrink"],
|
||||
["Travel & Places", "emoji.group.travelPlaces"],
|
||||
["Activities", "emoji.group.activities"],
|
||||
["Objects", "emoji.group.objects"],
|
||||
["Symbols", "emoji.group.symbols"],
|
||||
["Flags", "emoji.group.flags"],
|
||||
]);
|
||||
|
||||
function groupLabel(name) {
|
||||
if (name === "Recently Used") return t("emoji.recentGroup", {}, "Recently Used");
|
||||
const key = GROUP_KEYS.get(name);
|
||||
return key ? t(key, {}, name) : name;
|
||||
}
|
||||
|
||||
function itemLabel(item) {
|
||||
return t("emoji.itemLabel", { emoji: item.emoji }, `Emoji ${item.emoji}`);
|
||||
}
|
||||
|
||||
function loadRecents() {
|
||||
try {
|
||||
@@ -50,7 +72,7 @@ export function bindEmojiPicker({ editor, details, search, categories, grid, emp
|
||||
const found = group.items.find(item => item.emoji === value);
|
||||
if (found) return found;
|
||||
}
|
||||
return { emoji: value, name: "Recent emoji", keywords: "recent" };
|
||||
return { emoji: value, name: t("emoji.recentItem", {}, "Recent emoji"), keywords: "recent" };
|
||||
});
|
||||
return recentItems.length ? [{ name: "Recently Used", items: recentItems }, ...EMOJI_GROUPS] : EMOJI_GROUPS;
|
||||
};
|
||||
@@ -64,8 +86,9 @@ export function bindEmojiPicker({ editor, details, search, categories, grid, emp
|
||||
button.className = "emoji-category";
|
||||
button.dataset.emojiGroup = group.name;
|
||||
button.textContent = group.items[0]?.emoji || "•";
|
||||
button.title = group.name;
|
||||
button.setAttribute("aria-label", group.name);
|
||||
const label = groupLabel(group.name);
|
||||
button.title = label;
|
||||
button.setAttribute("aria-label", label);
|
||||
button.setAttribute("aria-pressed", String(group.name === activeGroup));
|
||||
return button;
|
||||
}));
|
||||
@@ -75,9 +98,9 @@ export function bindEmojiPicker({ editor, details, search, categories, grid, emp
|
||||
const query = normalize(search.value.trim());
|
||||
let items;
|
||||
if (query) {
|
||||
items = EMOJI_GROUPS.flatMap(group => group.items).filter(item =>
|
||||
normalize(`${item.name} ${item.keywords}`).includes(query)
|
||||
);
|
||||
items = EMOJI_GROUPS.flatMap(group => group.items.map(item => ({ item, group })))
|
||||
.filter(({ item, group }) => normalize(`${item.name} ${item.keywords} ${groupLabel(group.name)}`).includes(query))
|
||||
.map(({ item }) => item);
|
||||
} else {
|
||||
items = groups().find(group => group.name === activeGroup)?.items || [];
|
||||
}
|
||||
@@ -88,8 +111,9 @@ export function bindEmojiPicker({ editor, details, search, categories, grid, emp
|
||||
button.type = "button";
|
||||
button.className = "emoji-item";
|
||||
button.dataset.emoji = item.emoji;
|
||||
button.title = item.name;
|
||||
button.setAttribute("aria-label", item.name);
|
||||
const label = itemLabel(item);
|
||||
button.title = label;
|
||||
button.setAttribute("aria-label", label);
|
||||
button.textContent = item.emoji;
|
||||
fragment.append(button);
|
||||
}
|
||||
@@ -126,4 +150,7 @@ export function bindEmojiPicker({ editor, details, search, categories, grid, emp
|
||||
document.addEventListener("pointerdown", event => {
|
||||
if (details.open && !details.contains(event.target)) details.removeAttribute("open");
|
||||
});
|
||||
document.addEventListener("rustpad:languagechange", () => {
|
||||
if (details.open) render();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user