diff --git a/frontend/appflowy_flutter/assets/icons/icons.json b/frontend/appflowy_flutter/assets/icons/icons.json
new file mode 100644
index 0000000000..4ad858c414
--- /dev/null
+++ b/frontend/appflowy_flutter/assets/icons/icons.json
@@ -0,0 +1 @@
+{ "artificial_intelligence": [ { "name": "ai-chip-spark", "keywords": [ "chip", "processor", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-cloud-spark", "keywords": [ "cloud", "internet", "server", "network", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-edit-spark", "keywords": [ "change", "edit", "modify", "pencil", "write", "writing", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-email-generator-spark", "keywords": [ "mail", "envelope", "inbox", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-gaming-spark", "keywords": [ "remote", "control", "controller", "technology", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-generate-landscape-image-spark", "keywords": [ "picture", "photography", "photo", "image", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-generate-music-spark", "keywords": [ "music", "audio", "note", "entertainment", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-generate-portrait-image-spark", "keywords": [ "picture", "photography", "photo", "image", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-generate-variation-spark", "keywords": [ "module", "application", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-navigation-spark", "keywords": [ "map", "location", "direction", "travel", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-network-spark", "keywords": [ "globe", "internet", "world", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-prompt-spark", "keywords": [ "app", "code", "apps", "window", "website", "web", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-redo-spark", "keywords": [ "arrow", "refresh", "sync", "synchronize", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-science-spark", "keywords": [ "atom", "scientific", "experiment", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-settings-spark", "keywords": [ "cog", "gear", "settings", "machine", "artificial", "intelligence" ], "content": "\n" }, { "name": "ai-technology-spark", "keywords": [ "lightbulb", "idea", "bright", "lighting", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "ai-upscale-spark", "keywords": [ "magnifier", "zoom", "view", "find", "search", "ai" ], "content": "\n" }, { "name": "ai-vehicle-spark-1", "keywords": [ "car", "automated", "transportation", "artificial", "intelligence", "ai" ], "content": "\n" }, { "name": "artificial-intelligence-spark", "keywords": [ "brain", "thought", "ai", "automated", "ai" ], "content": "\n" } ], "computer_devices": [ { "name": "adobe", "keywords": [], "content": "\n" }, { "name": "alt", "keywords": [ "windows", "key", "alt", "pc", "keyboard" ], "content": "\n" }, { "name": "amazon", "keywords": [], "content": "\n" }, { "name": "android", "keywords": [ "android", "code", "apps", "bugdroid", "programming" ], "content": "\n" }, { "name": "app-store", "keywords": [], "content": "\n" }, { "name": "apple", "keywords": [ "os", "system", "apple" ], "content": "\n" }, { "name": "asterisk-1", "keywords": [ "asterisk", "star", "keyboard" ], "content": "\n" }, { "name": "battery-alert-1", "keywords": [ "phone", "mobile", "charge", "device", "electricity", "power", "battery", "alert", "warning" ], "content": "\n" }, { "name": "battery-charging", "keywords": [ "phone", "mobile", "charge", "device", "electricity", "power", "battery", "charging" ], "content": "\n" }, { "name": "battery-empty-1", "keywords": [ "phone", "mobile", "charge", "device", "electricity", "empty", "power", "battery" ], "content": "\n" }, { "name": "battery-empty-2", "keywords": [ "phone", "mobile", "charge", "device", "electricity", "empty", "power", "battery" ], "content": "\n" }, { "name": "battery-full-1", "keywords": [ "phone", "mobile", "charge", "device", "electricity", "power", "battery", "full" ], "content": "\n" }, { "name": "battery-low-1", "keywords": [ "phone", "mobile", "charge", "device", "electricity", "power", "battery", "low" ], "content": "\n" }, { "name": "battery-medium-1", "keywords": [ "phone", "mobile", "charge", "medium", "device", "electricity", "power", "battery" ], "content": "\n" }, { "name": "bluetooth", "keywords": [ "bluetooth", "internet", "server", "network", "wireless", "connection" ], "content": "\n" }, { "name": "bluetooth-disabled", "keywords": [ "bluetooth", "internet", "server", "network", "wireless", "disabled", "off", "connection" ], "content": "\n" }, { "name": "bluetooth-searching", "keywords": [ "bluetooth", "internet", "server", "network", "wireless", "searching", "connecting", "connection" ], "content": "\n" }, { "name": "browser-wifi", "keywords": [ "wireless", "wifi", "internet", "server", "network", "browser", "connection" ], "content": "\n" }, { "name": "chrome", "keywords": [], "content": "\n" }, { "name": "command", "keywords": [ "mac", "command", "apple", "keyboard" ], "content": "\n" }, { "name": "computer-chip-1", "keywords": [ "computer", "device", "chip", "electronics", "cpu", "microprocessor" ], "content": "\n" }, { "name": "computer-chip-2", "keywords": [ "core", "microprocessor", "device", "electronics", "chip", "computer" ], "content": "\n" }, { "name": "computer-pc-desktop", "keywords": [ "screen", "desktop", "monitor", "device", "electronics", "display", "pc", "computer" ], "content": "\n" }, { "name": "controller", "keywords": [ "remote", "quadcopter", "drones", "flying", "drone", "control", "controller", "technology", "fly" ], "content": "\n" }, { "name": "controller-1", "keywords": [ "remote", "quadcopter", "drones", "flying", "drone", "control", "controller", "technology", "fly" ], "content": "\n" }, { "name": "controller-wireless", "keywords": [ "remote", "gaming", "drones", "drone", "control", "controller", "technology", "console" ], "content": "\n" }, { "name": "cursor-click", "keywords": [], "content": "\n" }, { "name": "cyborg", "keywords": [ "artificial", "robotics", "intelligence", "machine", "technology", "android" ], "content": "\n" }, { "name": "cyborg-2", "keywords": [ "artificial", "robotics", "intelligence", "machine", "technology", "android" ], "content": "\n" }, { "name": "database", "keywords": [ "raid", "storage", "code", "disk", "programming", "database", "array", "hard", "disc" ], "content": "\n" }, { "name": "database-check", "keywords": [ "raid", "storage", "code", "disk", "programming", "database", "array", "hard", "disc", "check", "approve" ], "content": "\n" }, { "name": "database-lock", "keywords": [ "raid", "storage", "code", "disk", "programming", "database", "array", "hard", "disc", "password", "security", "protection", "lock", "secure" ], "content": "\n" }, { "name": "database-refresh", "keywords": [ "raid", "storage", "code", "disk", "programming", "database", "array", "hard", "disc", "refresh" ], "content": "\n" }, { "name": "database-remove", "keywords": [ "raid", "storage", "code", "disk", "programming", "database", "array", "hard", "disc", "remove", "delete", "cross" ], "content": "\n" }, { "name": "database-server-1", "keywords": [ "server", "network", "internet" ], "content": "\n" }, { "name": "database-server-2", "keywords": [ "server", "network", "internet" ], "content": "\n" }, { "name": "database-setting", "keywords": [ "raid", "storage", "code", "disk", "programming", "database", "array", "hard", "disc", "setting" ], "content": "\n" }, { "name": "database-subtract-2-raid-storage-code-disk-programming-database-array-hard-disc-minus", "keywords": [], "content": "\n" }, { "name": "delete-keyboard", "keywords": [], "content": "\n" }, { "name": "desktop-chat", "keywords": [ "bubble", "chat", "customer", "service", "conversation", "display", "device" ], "content": "\n" }, { "name": "desktop-check", "keywords": [ "success", "approve", "device", "display", "desktop", "computer" ], "content": "\n" }, { "name": "desktop-code", "keywords": [ "desktop", "device", "display", "computer", "code", "terminal", "html", "css", "programming", "system" ], "content": "\n" }, { "name": "desktop-delete", "keywords": [ "device", "remove", "display", "computer", "deny", "desktop", "fail", "failure", "cross" ], "content": "\n" }, { "name": "desktop-dollar", "keywords": [ "cash", "desktop", "display", "device", "notification", "computer", "money", "currency" ], "content": "\n" }, { "name": "desktop-emoji", "keywords": [ "device", "display", "desktop", "padlock", "smiley" ], "content": "\n" }, { "name": "desktop-favorite-star", "keywords": [ "desktop", "device", "display", "like", "favorite", "star" ], "content": "\n" }, { "name": "desktop-game", "keywords": [ "controller", "display", "device", "computer", "games", "leisure" ], "content": "\n" }, { "name": "desktop-help", "keywords": [ "device", "help", "information", "display", "desktop", "question", "info" ], "content": "\n" }, { "name": "device-database-encryption-1", "keywords": [], "content": "\n" }, { "name": "discord", "keywords": [], "content": "\n" }, { "name": "drone", "keywords": [ "artificial", "robotics", "intelligence", "machine", "technology", "android", "flying" ], "content": "\n" }, { "name": "dropbox", "keywords": [], "content": "\n" }, { "name": "eject", "keywords": [ "eject", "unmount", "dismount", "remove", "keyboard" ], "content": "\n" }, { "name": "electric-cord-1", "keywords": [ "electricity", "electronic", "appliances", "device", "cord", "cable", "plug", "connection" ], "content": "\n" }, { "name": "electric-cord-3", "keywords": [ "electricity", "electronic", "appliances", "device", "cord", "cable", "plug", "connection" ], "content": "\n" }, { "name": "facebook-1", "keywords": [ "media", "facebook", "social" ], "content": "\n" }, { "name": "figma", "keywords": [], "content": "\n" }, { "name": "floppy-disk", "keywords": [ "disk", "floppy", "electronics", "device", "disc", "computer", "storage" ], "content": "\n" }, { "name": "gmail", "keywords": [], "content": "\n" }, { "name": "google", "keywords": [ "media", "google", "social" ], "content": "\n" }, { "name": "google-drive", "keywords": [], "content": "\n" }, { "name": "hand-held", "keywords": [ "tablet", "kindle", "device", "electronics", "ipad", "computer" ], "content": "\n" }, { "name": "hand-held-tablet-drawing", "keywords": [ "tablet", "kindle", "device", "electronics", "ipad", "digital", "drawing", "canvas" ], "content": "\n" }, { "name": "hand-held-tablet-writing", "keywords": [ "tablet", "kindle", "device", "electronics", "ipad", "writing", "digital", "paper", "notepad" ], "content": "\n" }, { "name": "hard-disk", "keywords": [ "device", "disc", "drive", "disk", "electronics", "platter", "turntable", "raid", "storage" ], "content": "\n" }, { "name": "hard-drive-1", "keywords": [ "disk", "device", "electronics", "disc", "drive", "raid", "storage" ], "content": "\n" }, { "name": "instagram", "keywords": [], "content": "\n" }, { "name": "keyboard", "keywords": [ "keyboard", "device", "electronics", "dvorak", "qwerty" ], "content": "\n" }, { "name": "keyboard-virtual", "keywords": [ "remote", "device", "electronics", "qwerty", "keyboard", "virtual", "interface" ], "content": "\n" }, { "name": "keyboard-wireless-2", "keywords": [ "remote", "device", "wireless", "electronics", "qwerty", "keyboard", "bluetooth" ], "content": "\n" }, { "name": "laptop-charging", "keywords": [ "device", "laptop", "electronics", "computer", "notebook", "charging" ], "content": "\n" }, { "name": "linkedin", "keywords": [ "network", "linkedin", "professional" ], "content": "\n" }, { "name": "local-storage-folder", "keywords": [], "content": "\n" }, { "name": "meta", "keywords": [], "content": "\n" }, { "name": "mouse", "keywords": [ "device", "electronics", "mouse" ], "content": "\n" }, { "name": "mouse-wireless", "keywords": [ "remote", "wireless", "device", "electronics", "mouse", "computer" ], "content": "\n" }, { "name": "mouse-wireless-1", "keywords": [ "remote", "wireless", "device", "electronics", "mouse", "computer" ], "content": "\n" }, { "name": "netflix", "keywords": [], "content": "\n" }, { "name": "network", "keywords": [ "network", "server", "internet", "ethernet", "connection" ], "content": "\n" }, { "name": "next", "keywords": [ "next", "arrow", "right", "keyboard" ], "content": "\n" }, { "name": "paypal", "keywords": [ "payment", "paypal" ], "content": "\n" }, { "name": "play-store", "keywords": [], "content": "\n" }, { "name": "printer", "keywords": [ "scan", "device", "electronics", "printer", "print", "computer" ], "content": "\n" }, { "name": "return-2", "keywords": [ "arrow", "return", "enter", "keyboard" ], "content": "\n" }, { "name": "screen-1", "keywords": [ "screen", "device", "electronics", "monitor", "diplay", "computer" ], "content": "\n" }, { "name": "screen-2", "keywords": [ "screen", "device", "electronics", "monitor", "diplay", "computer" ], "content": "\n" }, { "name": "screen-curve", "keywords": [ "screen", "curved", "device", "electronics", "monitor", "diplay", "computer" ], "content": "\n" }, { "name": "screensaver-monitor-wallpaper", "keywords": [], "content": "\n" }, { "name": "shift", "keywords": [ "key", "shift", "up", "arrow", "keyboard" ], "content": "\n" }, { "name": "shredder", "keywords": [ "device", "electronics", "shred", "paper", "cut", "destroy", "remove", "delete" ], "content": "\n" }, { "name": "signal-loading", "keywords": [ "bracket", "loading", "internet", "angle", "signal", "server", "network", "connecting", "connection" ], "content": "\n" }, { "name": "slack", "keywords": [], "content": "\n" }, { "name": "spotify", "keywords": [], "content": "\n" }, { "name": "telegram", "keywords": [], "content": "\n" }, { "name": "tiktok", "keywords": [], "content": "\n" }, { "name": "tinder", "keywords": [], "content": "\n" }, { "name": "twitter", "keywords": [ "media", "twitter", "social" ], "content": "\n" }, { "name": "usb-drive", "keywords": [ "usb", "drive", "stick", "memory", "storage", "data", "connection" ], "content": "\n" }, { "name": "virtual-reality", "keywords": [ "gaming", "virtual", "gear", "controller", "reality", "games", "headset", "technology", "vr", "eyewear" ], "content": "\n" }, { "name": "voice-mail", "keywords": [ "mic", "audio", "mike", "music", "microphone" ], "content": "\n" }, { "name": "voice-mail-off", "keywords": [ "mic", "audio", "mike", "music", "microphone", "mute", "off" ], "content": "\n" }, { "name": "VPN-connection", "keywords": [], "content": "\n" }, { "name": "watch-1", "keywords": [ "device", "timepiece", "cirle", "electronics", "face", "blank", "watch", "smart" ], "content": "\n" }, { "name": "watch-2", "keywords": [ "device", "square", "timepiece", "electronics", "face", "blank", "watch", "smart" ], "content": "\n" }, { "name": "watch-circle-charging", "keywords": [ "device", "timepiece", "circle", "watch", "round", "charge", "charging", "power" ], "content": "\n" }, { "name": "watch-circle-heartbeat-monitor-1", "keywords": [ "device", "timepiece", "circle", "watch", "round", "heart", "beat", "monitor", "healthcare" ], "content": "\n" }, { "name": "watch-circle-heartbeat-monitor-2", "keywords": [ "device", "timepiece", "circle", "watch", "round", "heart", "beat", "monitor", "healthcare" ], "content": "\n" }, { "name": "watch-circle-menu", "keywords": [ "device", "timepiece", "circle", "watch", "round", "menu", "list", "option", "app" ], "content": "\n" }, { "name": "watch-circle-time", "keywords": [ "device", "timepiece", "circle", "watch", "round", "time", "clock", "analog" ], "content": "\n" }, { "name": "webcam", "keywords": [ "webcam", "camera", "future", "tech", "chat", "skype", "technology", "video" ], "content": "\n" }, { "name": "webcam-video", "keywords": [ "work", "video", "meeting", "camera", "company", "conference", "office" ], "content": "\n" }, { "name": "webcam-video-circle", "keywords": [ "work", "video", "meeting", "camera", "company", "conference", "office" ], "content": "\n" }, { "name": "webcam-video-off", "keywords": [ "work", "video", "meeting", "camera", "company", "conference", "office", "off" ], "content": "\n" }, { "name": "whatsapp", "keywords": [], "content": "\n" }, { "name": "wifi", "keywords": [ "wireless", "wifi", "internet", "server", "network", "connection" ], "content": "\n" }, { "name": "wifi-antenna", "keywords": [ "wireless", "wifi", "internet", "server", "network", "antenna", "connection" ], "content": "\n" }, { "name": "wifi-disabled", "keywords": [ "wireless", "wifi", "internet", "server", "network", "disabled", "off", "offline", "connection" ], "content": "\n" }, { "name": "wifi-horizontal", "keywords": [ "wireless", "wifi", "internet", "server", "network", "horizontal", "connection" ], "content": "\n" }, { "name": "wifi-router", "keywords": [ "wireless", "wifi", "internet", "server", "network", "connection" ], "content": "\n" }, { "name": "windows", "keywords": [ "os", "system", "microsoft" ], "content": "\n" } ], "culture": [ { "name": "christian-cross-1", "keywords": [ "religion", "christian", "cross", "culture", "bold" ], "content": "\n" }, { "name": "christian-cross-2", "keywords": [ "religion", "christian", "cross", "culture", "bold" ], "content": "\n" }, { "name": "christianity", "keywords": [ "religion", "jesus", "christianity", "christ", "fish", "culture" ], "content": "\n" }, { "name": "dhammajak", "keywords": [ "religion", "dhammajak", "culture", "bhuddhism", "buddish" ], "content": "\n" }, { "name": "hexagram", "keywords": [ "star", "jew", "jewish", "judaism", "hexagram", "culture", "religion", "david" ], "content": "\n" }, { "name": "hinduism", "keywords": [ "religion", "hinduism", "culture", "hindu" ], "content": "\n" }, { "name": "islam", "keywords": [ "religion", "islam", "moon", "crescent", "muslim", "culture", "star" ], "content": "\n" }, { "name": "news-paper", "keywords": [ "newspaper", "periodical", "fold", "content", "entertainment" ], "content": "\n" }, { "name": "peace-symbol", "keywords": [ "religion", "peace", "war", "culture", "symbol" ], "content": "\n" }, { "name": "politics-compaign", "keywords": [], "content": "\n" }, { "name": "politics-speech", "keywords": [], "content": "\n" }, { "name": "politics-vote-2", "keywords": [], "content": "\n" }, { "name": "ticket-1", "keywords": [ "hobby", "ticket", "event", "entertainment", "stub", "theater", "entertainment", "culture" ], "content": "\n" }, { "name": "tickets", "keywords": [ "hobby", "ticket", "event", "entertainment", "stub", "theater", "entertainment", "culture" ], "content": "\n" }, { "name": "yin-yang-symbol", "keywords": [ "religion", "tao", "yin", "yang", "taoism", "culture", "symbol" ], "content": "\n" }, { "name": "zodiac-1", "keywords": [ "sign", "astrology", "stars", "space", "scorpio" ], "content": "\n" }, { "name": "zodiac-10", "keywords": [ "sign", "astrology", "stars", "space", "pisces" ], "content": "\n" }, { "name": "zodiac-11", "keywords": [ "sign", "astrology", "stars", "space", "sagittarius" ], "content": "\n" }, { "name": "zodiac-12", "keywords": [ "sign", "astrology", "stars", "space", "cancer" ], "content": "\n" }, { "name": "zodiac-2", "keywords": [ "sign", "astrology", "stars", "space", "virgo" ], "content": "\n" }, { "name": "zodiac-3", "keywords": [ "sign", "astrology", "stars", "space", "leo" ], "content": "\n" }, { "name": "zodiac-4", "keywords": [ "sign", "astrology", "stars", "space", "aquarius" ], "content": "\n" }, { "name": "zodiac-5", "keywords": [ "sign", "astrology", "stars", "space", "taurus" ], "content": "\n" }, { "name": "zodiac-6", "keywords": [ "sign", "astrology", "stars", "space", "capricorn" ], "content": "\n" }, { "name": "zodiac-7", "keywords": [ "sign", "astrology", "stars", "space", "ares" ], "content": "\n" }, { "name": "zodiac-8", "keywords": [ "sign", "astrology", "stars", "space", "libra" ], "content": "\n" }, { "name": "zodiac-9", "keywords": [ "sign", "astrology", "stars", "space", "gemini" ], "content": "\n" } ], "entertainment": [ { "name": "balloon", "keywords": [ "hobby", "entertainment", "party", "balloon" ], "content": "\n" }, { "name": "bow", "keywords": [ "entertainment", "gaming", "bow", "weapon" ], "content": "\n" }, { "name": "button-fast-forward-1", "keywords": [ "button", "controls", "fast", "forward", "movies", "television", "video", "tv" ], "content": "\n" }, { "name": "button-fast-forward-2", "keywords": [ "button", "controls", "fast", "forward", "movies", "television", "video", "tv" ], "content": "\n" }, { "name": "button-next", "keywords": [ "button", "television", "buttons", "movies", "skip", "next", "video", "controls" ], "content": "\n" }, { "name": "button-pause-2", "keywords": [ "button", "television", "buttons", "movies", "tv", "pause", "video", "controls" ], "content": "\n" }, { "name": "button-play", "keywords": [ "button", "television", "buttons", "movies", "play", "tv", "video", "controls" ], "content": "\n" }, { "name": "button-power-1", "keywords": [ "power", "button", "on", "off" ], "content": "\n" }, { "name": "button-previous", "keywords": [ "button", "television", "buttons", "movies", "skip", "previous", "video", "controls" ], "content": "\n" }, { "name": "button-record-3", "keywords": [ "button", "television", "buttons", "movies", "record", "tv", "video", "controls" ], "content": "\n" }, { "name": "button-rewind-1", "keywords": [ "rewind", "television", "button", "movies", "buttons", "tv", "video", "controls" ], "content": "\n" }, { "name": "button-rewind-2", "keywords": [ "rewind", "television", "button", "movies", "buttons", "tv", "video", "controls" ], "content": "\n" }, { "name": "button-stop", "keywords": [ "button", "television", "buttons", "movies", "stop", "tv", "video", "controls" ], "content": "\n" }, { "name": "camera-video", "keywords": [ "film", "television", "tv", "camera", "movies", "video", "recorder" ], "content": "\n" }, { "name": "cards", "keywords": [], "content": "\n" }, { "name": "chess-bishop", "keywords": [], "content": "\n" }, { "name": "chess-king", "keywords": [], "content": "\n" }, { "name": "chess-knight", "keywords": [], "content": "\n" }, { "name": "chess-pawn", "keywords": [], "content": "\n" }, { "name": "cloud-gaming-1", "keywords": [ "entertainment", "cloud", "gaming" ], "content": "\n" }, { "name": "clubs-symbol", "keywords": [ "entertainment", "gaming", "card", "clubs", "symbol" ], "content": "\n" }, { "name": "diamonds-symbol", "keywords": [ "entertainment", "gaming", "card", "diamonds", "symbol" ], "content": "\n" }, { "name": "dice-1", "keywords": [], "content": "\n" }, { "name": "dice-2", "keywords": [], "content": "\n" }, { "name": "dice-3", "keywords": [], "content": "\n" }, { "name": "dice-4", "keywords": [], "content": "\n" }, { "name": "dice-5", "keywords": [], "content": "\n" }, { "name": "dice-6", "keywords": [], "content": "\n" }, { "name": "dices-entertainment-gaming-dices", "keywords": [], "content": "\n" }, { "name": "earpods", "keywords": [ "airpods", "audio", "earpods", "music", "earbuds", "true", "wireless", "entertainment" ], "content": "\n" }, { "name": "epic-games-1", "keywords": [ "epic", "games", "entertainment", "gaming" ], "content": "\n" }, { "name": "esports", "keywords": [ "entertainment", "gaming", "esports" ], "content": "\n" }, { "name": "fireworks-rocket", "keywords": [ "hobby", "entertainment", "party", "fireworks", "rocket" ], "content": "\n" }, { "name": "gameboy", "keywords": [ "entertainment", "gaming", "device", "gameboy" ], "content": "\n" }, { "name": "gramophone", "keywords": [ "music", "audio", "note", "gramophone", "player", "vintage", "entertainment" ], "content": "\n" }, { "name": "hearts-symbol", "keywords": [ "entertainment", "gaming", "card", "hearts", "symbol" ], "content": "\n" }, { "name": "music-equalizer", "keywords": [ "music", "audio", "note", "wave", "sound", "equalizer", "entertainment" ], "content": "\n" }, { "name": "music-note-1", "keywords": [ "music", "audio", "note", "entertainment" ], "content": "\n" }, { "name": "music-note-2", "keywords": [ "music", "audio", "note", "entertainment" ], "content": "\n" }, { "name": "music-note-off-1", "keywords": [ "music", "audio", "note", "off", "mute", "entertainment" ], "content": "\n" }, { "name": "music-note-off-2", "keywords": [ "music", "audio", "note", "off", "mute", "entertainment" ], "content": "\n" }, { "name": "nintendo-switch", "keywords": [ "nintendo", "switch", "entertainment", "gaming" ], "content": "\n" }, { "name": "one-vesus-one", "keywords": [ "entertainment", "gaming", "one", "vesus", "one" ], "content": "\n" }, { "name": "pacman", "keywords": [ "entertainment", "gaming", "pacman", "video" ], "content": "\n" }, { "name": "party-popper", "keywords": [ "hobby", "entertainment", "party", "popper", "confetti", "event" ], "content": "\n" }, { "name": "play-list-4", "keywords": [ "screen", "television", "display", "player", "movies", "players", "tv", "media", "video", "entertainment" ], "content": "\n" }, { "name": "play-list-5", "keywords": [ "player", "television", "movies", "slider", "media", "tv", "players", "video", "stack", "entertainment" ], "content": "\n" }, { "name": "play-list-8", "keywords": [ "player", "television", "movies", "slider", "media", "tv", "players", "video", "stack", "entertainment" ], "content": "\n" }, { "name": "play-list-9", "keywords": [ "player", "television", "movies", "slider", "media", "tv", "players", "video", "stack", "entertainment" ], "content": "\n" }, { "name": "play-list-folder", "keywords": [ "player", "television", "movies", "slider", "media", "tv", "players", "video" ], "content": "\n" }, { "name": "play-station", "keywords": [ "play", "station", "entertainment", "gaming" ], "content": "\n" }, { "name": "radio", "keywords": [ "antenna", "audio", "music", "radio", "entertainment" ], "content": "\n" }, { "name": "recording-tape-bubble-circle", "keywords": [ "phone", "device", "mail", "mobile", "voice", "machine", "answering", "chat", "entertainment" ], "content": "\n" }, { "name": "recording-tape-bubble-square", "keywords": [ "phone", "device", "mail", "mobile", "voice", "machine", "answering", "chat", "entertainment" ], "content": "\n" }, { "name": "song-recommendation", "keywords": [ "song", "recommendation", "entertainment" ], "content": "\n" }, { "name": "spades-symbol", "keywords": [ "entertainment", "gaming", "card", "spades", "symbol" ], "content": "\n" }, { "name": "speaker-1", "keywords": [ "speaker", "music", "audio", "subwoofer", "entertainment" ], "content": "\n" }, { "name": "speaker-2", "keywords": [ "speakers", "music", "audio", "entertainment" ], "content": "\n" }, { "name": "stream", "keywords": [ "stream", "entertainment", "gaming" ], "content": "\n" }, { "name": "tape-cassette-record", "keywords": [ "music", "entertainment", "tape", "cassette", "record" ], "content": "\n" }, { "name": "volume-down", "keywords": [ "speaker", "down", "volume", "control", "audio", "music", "decrease", "entertainment" ], "content": "\n" }, { "name": "volume-level-high", "keywords": [ "speaker", "high", "volume", "control", "audio", "music", "entertainment" ], "content": "\n" }, { "name": "volume-level-low", "keywords": [ "volume", "speaker", "lower", "down", "control", "music", "low", "audio", "entertainment" ], "content": "\n" }, { "name": "volume-level-off", "keywords": [ "volume", "speaker", "control", "music", "audio", "entertainment" ], "content": "\n" }, { "name": "volume-mute", "keywords": [ "speaker", "remove", "volume", "control", "audio", "music", "mute", "off", "cross", "entertainment" ], "content": "\n" }, { "name": "volume-off", "keywords": [ "speaker", "music", "mute", "volume", "control", "audio", "off", "mute", "entertainment" ], "content": "\n" }, { "name": "vr-headset-1", "keywords": [ "entertainment", "gaming", "vr", "headset" ], "content": "\n" }, { "name": "vr-headset-2", "keywords": [ "entertainment", "gaming", "vr", "headset" ], "content": "\n" }, { "name": "xbox", "keywords": [ "xbox", "entertainment", "gaming" ], "content": "\n" } ], "food_drink": [ { "name": "beer-mug", "keywords": [ "beer", "cook", "brewery", "drink", "mug", "cooking", "nutrition", "brew", "brewing", "food" ], "content": "\n" }, { "name": "beer-pitch", "keywords": [ "drink", "glass", "beer", "pitch" ], "content": "\n" }, { "name": "burger", "keywords": [ "burger", "fast", "cook", "cooking", "nutrition", "food" ], "content": "\n" }, { "name": "burrito-fastfood", "keywords": [], "content": "\n" }, { "name": "cake-slice", "keywords": [ "cherry", "cake", "birthday", "event", "special", "sweet", "bake" ], "content": "\n" }, { "name": "candy-cane", "keywords": [ "candy", "sweet", "cane", "christmas" ], "content": "\n" }, { "name": "champagne-party-alcohol", "keywords": [], "content": "\n" }, { "name": "cheese", "keywords": [ "cook", "cheese", "animal", "products", "cooking", "nutrition", "dairy", "food" ], "content": "\n" }, { "name": "cherries", "keywords": [ "cook", "plant", "cherry", "plants", "cooking", "nutrition", "vegetarian", "fruit", "food", "cherries" ], "content": "\n" }, { "name": "chicken-grilled-stream", "keywords": [], "content": "\n" }, { "name": "cocktail", "keywords": [ "cook", "alcohol", "food", "cocktail", "drink", "cooking", "nutrition", "alcoholic", "beverage", "glass" ], "content": "\n" }, { "name": "coffee-bean", "keywords": [ "cook", "cooking", "nutrition", "coffee", "bean" ], "content": "\n" }, { "name": "coffee-mug", "keywords": [ "coffee", "cook", "cup", "drink", "mug", "cooking", "nutrition", "cafe", "caffeine", "food" ], "content": "\n" }, { "name": "coffee-takeaway-cup", "keywords": [ "cup", "coffee", "hot", "takeaway", "drink", "caffeine" ], "content": "\n" }, { "name": "donut", "keywords": [ "dessert", "donut" ], "content": "\n" }, { "name": "fork-knife", "keywords": [ "fork", "spoon", "knife", "food", "dine", "cook", "utensils", "eat", "restaurant", "dining", "kitchenware" ], "content": "\n" }, { "name": "fork-spoon", "keywords": [ "fork", "spoon", "food", "dine", "cook", "utensils", "eat", "restaurant", "dining", "kitchenware" ], "content": "\n" }, { "name": "ice-cream-2", "keywords": [ "cook", "frozen", "popsicle", "freezer", "nutrition", "cream", "stick", "cold", "ice", "cooking" ], "content": "\n" }, { "name": "ice-cream-3", "keywords": [ "cook", "frozen", "cone", "cream", "ice", "cooking", "nutrition", "freezer", "cold", "food" ], "content": "\n" }, { "name": "lemon-fruit-seasoning", "keywords": [], "content": "\n" }, { "name": "microwave", "keywords": [ "cook", "food", "appliances", "cooking", "nutrition", "appliance", "microwave", "kitchenware" ], "content": "\n" }, { "name": "milkshake", "keywords": [ "milkshake", "drink", "takeaway", "cup", "cold", "beverage" ], "content": "\n" }, { "name": "popcorn", "keywords": [ "cook", "corn", "movie", "snack", "cooking", "nutrition", "bake", "popcorn" ], "content": "\n" }, { "name": "pork-meat", "keywords": [], "content": "\n" }, { "name": "refrigerator", "keywords": [ "fridge", "cook", "appliances", "cooking", "nutrition", "freezer", "appliance", "food", "kitchenware" ], "content": "\n" }, { "name": "serving-dome", "keywords": [ "cook", "tool", "dome", "kitchen", "serving", "paltter", "dish", "tools", "food", "kitchenware" ], "content": "\n" }, { "name": "shrimp", "keywords": [ "sea", "food", "shrimp" ], "content": "\n" }, { "name": "strawberry", "keywords": [ "fruit", "sweet", "berries", "plant", "strawberry" ], "content": "\n" }, { "name": "tea-cup", "keywords": [ "herbal", "cook", "tea", "tisane", "cup", "drink", "cooking", "nutrition", "mug", "food" ], "content": "\n" }, { "name": "toast", "keywords": [ "bread", "toast", "breakfast" ], "content": "\n" }, { "name": "water-glass", "keywords": [ "glass", "water", "juice", "drink", "liquid" ], "content": "\n" }, { "name": "wine", "keywords": [ "drink", "cook", "glass", "cooking", "wine", "nutrition", "food" ], "content": "\n" } ], "health": [ { "name": "ambulance", "keywords": [ "car", "emergency", "health", "medical", "ambulance" ], "content": "\n" }, { "name": "bacteria-virus-cells-biology", "keywords": [], "content": "\n" }, { "name": "bandage", "keywords": [ "health", "medical", "hospital", "medicine", "capsule", "bandage", "vaccine" ], "content": "\n" }, { "name": "blood-bag-donation", "keywords": [], "content": "\n" }, { "name": "blood-donate-drop", "keywords": [], "content": "\n" }, { "name": "blood-drop-donation", "keywords": [], "content": "\n" }, { "name": "brain", "keywords": [ "medical", "health", "brain" ], "content": "\n" }, { "name": "brain-cognitive", "keywords": [ "health", "medical", "brain", "cognitive", "specialities" ], "content": "\n" }, { "name": "call-center-support-service", "keywords": [], "content": "\n" }, { "name": "checkup-medical-report-clipboard", "keywords": [], "content": "\n" }, { "name": "ear-hearing", "keywords": [ "health", "medical", "hearing", "ear" ], "content": "\n" }, { "name": "eye-optic", "keywords": [ "health", "medical", "eye", "optic" ], "content": "\n" }, { "name": "flu-mask", "keywords": [ "health", "medical", "hospital", "mask", "flu", "vaccine", "protection" ], "content": "\n" }, { "name": "health-care-2", "keywords": [ "health", "medical", "hospital", "heart", "care", "symbol" ], "content": "\n" }, { "name": "heart-rate-pulse-graph", "keywords": [], "content": "\n" }, { "name": "heart-rate-search", "keywords": [ "health", "medical", "monitor", "heart", "rate", "search" ], "content": "\n" }, { "name": "hospital-sign-circle", "keywords": [ "health", "sign", "medical", "symbol", "hospital", "circle", "emergency" ], "content": "\n" }, { "name": "hospital-sign-square", "keywords": [ "health", "sign", "medical", "symbol", "hospital", "square", "emergency" ], "content": "\n" }, { "name": "insurance-hand", "keywords": [ "health", "medical", "insurance", "hand", "cross" ], "content": "\n" }, { "name": "medical-bag", "keywords": [ "health", "sign", "medical", "symbol", "hospital", "bag", "medicine", "medkit" ], "content": "\n" }, { "name": "medical-cross-sign-healthcare", "keywords": [], "content": "\n" }, { "name": "medical-cross-symbol", "keywords": [ "health", "sign", "medical", "symbol", "hospital", "emergency" ], "content": "\n" }, { "name": "medical-files-report-history", "keywords": [], "content": "\n" }, { "name": "medical-ribbon-1", "keywords": [ "ribbon", "medical", "cancer", "health", "beauty", "symbol" ], "content": "\n" }, { "name": "medical-search-diagnosis", "keywords": [], "content": "\n" }, { "name": "microscope-observation-sciene", "keywords": [], "content": "\n" }, { "name": "nurse-assistant-emergency", "keywords": [], "content": "\n" }, { "name": "nurse-hat", "keywords": [ "health", "medical", "hospital", "nurse", "doctor", "cap" ], "content": "\n" }, { "name": "online-medical-call-service", "keywords": [], "content": "\n" }, { "name": "online-medical-service-monitor", "keywords": [], "content": "\n" }, { "name": "online-medical-web-service", "keywords": [], "content": "\n" }, { "name": "petri-dish-lab-equipment", "keywords": [], "content": "\n" }, { "name": "pharmacy", "keywords": [ "health", "medical", "pharmacy", "sign", "medicine", "mortar", "pestle" ], "content": "\n" }, { "name": "prescription-pills-drugs-healthcare", "keywords": [], "content": "\n" }, { "name": "sign-cross-square", "keywords": [ "health", "sign", "medical", "symbol", "hospital", "cross", "square" ], "content": "\n" }, { "name": "sos-help-emergency-sign", "keywords": [], "content": "\n" }, { "name": "stethoscope", "keywords": [ "instrument", "health", "medical", "stethoscope" ], "content": "\n" }, { "name": "syringe", "keywords": [ "instrument", "medical", "syringe", "health", "beauty", "needle" ], "content": "\n" }, { "name": "tablet-capsule", "keywords": [ "health", "medical", "hospital", "medicine", "capsule", "tablet" ], "content": "\n" }, { "name": "tooth", "keywords": [ "health", "medical", "tooth" ], "content": "\n" }, { "name": "virus-antivirus", "keywords": [ "health", "medical", "covid19", "flu", "influenza", "virus", "antivirus" ], "content": "\n" }, { "name": "waiting-appointments-calendar", "keywords": [], "content": "\n" }, { "name": "wheelchair", "keywords": [ "health", "medical", "hospital", "wheelchair", "disable", "help", "sign" ], "content": "\n" } ], "images_photography": [ { "name": "auto-flash", "keywords": [], "content": "\n" }, { "name": "camera-1", "keywords": [ "photos", "picture", "camera", "photography", "photo", "pictures" ], "content": "\n" }, { "name": "camera-disabled", "keywords": [ "photos", "picture", "camera", "photography", "photo", "pictures", "disabled", "off" ], "content": "\n" }, { "name": "camera-loading", "keywords": [ "photos", "picture", "camera", "photography", "photo", "pictures", "loading", "option", "setting" ], "content": "\n" }, { "name": "camera-square", "keywords": [ "photos", "picture", "camera", "photography", "photo", "pictures", "frame", "square" ], "content": "\n" }, { "name": "composition-oval", "keywords": [ "camera", "frame", "composition", "photography", "pictures", "landscape", "photo", "oval" ], "content": "\n" }, { "name": "composition-vertical", "keywords": [ "camera", "portrait", "frame", "vertical", "composition", "photography", "photo" ], "content": "\n" }, { "name": "compsition-horizontal", "keywords": [ "camera", "horizontal", "panorama", "composition", "photography", "photo", "pictures" ], "content": "\n" }, { "name": "edit-image-photo", "keywords": [], "content": "\n" }, { "name": "film-roll-1", "keywords": [ "photos", "camera", "shutter", "picture", "photography", "pictures", "photo", "film", "roll" ], "content": "\n" }, { "name": "film-slate", "keywords": [ "pictures", "photo", "film", "slate" ], "content": "\n" }, { "name": "flash-1", "keywords": [ "flash", "power", "connect", "charge", "electricity", "lightning" ], "content": "\n" }, { "name": "flash-2", "keywords": [ "flash", "power", "connect", "charge", "electricity", "lightning" ], "content": "\n" }, { "name": "flash-3", "keywords": [ "flash", "power", "connect", "charge", "electricity", "lightning" ], "content": "\n" }, { "name": "flash-off", "keywords": [ "flash", "power", "connect", "charge", "off", "electricity", "lightning" ], "content": "\n" }, { "name": "flower", "keywords": [ "photos", "photo", "picture", "camera", "photography", "pictures", "flower", "image" ], "content": "\n" }, { "name": "focus-points", "keywords": [ "camera", "frame", "photography", "pictures", "photo", "focus", "position" ], "content": "\n" }, { "name": "landscape-2", "keywords": [ "photos", "photo", "landscape", "picture", "photography", "camera", "pictures", "image" ], "content": "\n" }, { "name": "landscape-setting", "keywords": [ "design", "composition", "horizontal", "lanscape" ], "content": "\n" }, { "name": "laptop-camera", "keywords": [ "photos", "photo", "picture", "photography", "camera", "pictures", "laptop", "computer" ], "content": "\n" }, { "name": "mobile-phone-camera", "keywords": [ "photos", "photo", "picture", "photography", "camera", "pictures", "phone" ], "content": "\n" }, { "name": "orientation-landscape", "keywords": [ "photos", "photo", "orientation", "landscape", "picture", "photography", "camera", "pictures", "image" ], "content": "\n" }, { "name": "orientation-portrait", "keywords": [ "photos", "photo", "orientation", "portrait", "picture", "photography", "camera", "pictures", "image" ], "content": "\n" }, { "name": "polaroid-four", "keywords": [ "photos", "camera", "polaroid", "picture", "photography", "pictures", "four", "photo", "image" ], "content": "\n" } ], "interface_essential": [ { "name": "add-1", "keywords": [ "expand", "cross", "buttons", "button", "more", "remove", "plus", "add", "+", "mathematics", "math" ], "content": "\n" }, { "name": "add-bell-notification", "keywords": [ "notification", "alarm", "alert", "bell", "add" ], "content": "\n" }, { "name": "add-circle", "keywords": [ "button", "remove", "cross", "add", "buttons", "plus", "circle", "+", "mathematics", "math" ], "content": "\n" }, { "name": "add-layer-2", "keywords": [ "layer", "add", "design", "plus", "layers", "square", "box" ], "content": "\n" }, { "name": "add-square", "keywords": [ "square", "remove", "cross", "buttons", "add", "plus", "button", "+", "mathematics", "math" ], "content": "\n" }, { "name": "alarm-clock", "keywords": [ "time", "tock", "stopwatch", "measure", "clock", "tick" ], "content": "\n" }, { "name": "align-back-1", "keywords": [ "back", "design", "layer", "layers", "pile", "stack", "arrange", "square" ], "content": "\n" }, { "name": "align-center", "keywords": [ "text", "alignment", "align", "paragraph", "centered", "formatting", "center" ], "content": "\n" }, { "name": "align-front-1", "keywords": [ "design", "front", "layer", "layers", "pile", "stack", "arrange", "square" ], "content": "\n" }, { "name": "align-left", "keywords": [ "paragraph", "text", "alignment", "align", "left", "formatting", "right" ], "content": "\n" }, { "name": "align-right", "keywords": [ "rag", "paragraph", "text", "alignment", "align", "right", "formatting", "left" ], "content": "\n" }, { "name": "ampersand", "keywords": [], "content": "\n" }, { "name": "archive-box", "keywords": [ "box", "content", "banker", "archive", "file" ], "content": "\n" }, { "name": "arrow-bend-left-down-2", "keywords": [ "arrow", "bend", "curve", "change", "direction", "left", "to", "down" ], "content": "\n" }, { "name": "arrow-bend-right-down-2", "keywords": [ "arrow", "bend", "curve", "change", "direction", "right", "to", "down" ], "content": "\n" }, { "name": "arrow-crossover-down", "keywords": [ "cross", "move", "over", "arrow", "arrows", "down" ], "content": "\n" }, { "name": "arrow-crossover-left", "keywords": [ "cross", "move", "over", "arrow", "arrows", "left" ], "content": "\n" }, { "name": "arrow-crossover-right", "keywords": [ "cross", "move", "over", "arrow", "arrows", "ight" ], "content": "\n" }, { "name": "arrow-crossover-up", "keywords": [ "cross", "move", "over", "arrow", "arrows", "right" ], "content": "\n" }, { "name": "arrow-cursor-1", "keywords": [ "mouse", "select", "cursor" ], "content": "\n" }, { "name": "arrow-cursor-2", "keywords": [ "mouse", "select", "cursor" ], "content": "\n" }, { "name": "arrow-curvy-up-down-1", "keywords": [ "both", "direction", "arrow", "curvy", "diagram", "zigzag", "vertical" ], "content": "\n" }, { "name": "arrow-curvy-up-down-2", "keywords": [], "content": "\n" }, { "name": "arrow-down-2", "keywords": [ "down", "move", "arrow", "arrows" ], "content": "\n" }, { "name": "arrow-down-dashed-square", "keywords": [ "arrow", "keyboard", "button", "down", "square", "dashes" ], "content": "\n" }, { "name": "arrow-expand", "keywords": [ "expand", "small", "bigger", "retract", "smaller", "big" ], "content": "\n" }, { "name": "arrow-infinite-loop", "keywords": [ "arrow", "diagram", "loop", "infinity", "repeat" ], "content": "\n" }, { "name": "arrow-move", "keywords": [ "move", "button", "arrows", "direction" ], "content": "\n" }, { "name": "arrow-reload-horizontal-1", "keywords": [ "arrows", "load", "arrow", "sync", "square", "loading", "reload", "synchronize" ], "content": "\n" }, { "name": "arrow-reload-horizontal-2", "keywords": [], "content": "\n" }, { "name": "arrow-reload-vertical-1", "keywords": [ "arrows", "load", "arrow", "sync", "square", "loading", "reload", "synchronize" ], "content": "\n" }, { "name": "arrow-reload-vertical-2", "keywords": [], "content": "\n" }, { "name": "arrow-roadmap", "keywords": [], "content": "\n" }, { "name": "arrow-round-left", "keywords": [ "diagram", "round", "arrow", "left" ], "content": "\n" }, { "name": "arrow-round-right", "keywords": [ "diagram", "round", "arrow", "right" ], "content": "\n" }, { "name": "arrow-shrink", "keywords": [ "expand", "retract", "shrink", "bigger", "big", "small", "smaller" ], "content": "\n" }, { "name": "arrow-shrink-diagonal-1", "keywords": [ "expand", "retract", "shrink", "bigger", "big", "small", "smaller" ], "content": "\n" }, { "name": "arrow-shrink-diagonal-2", "keywords": [ "expand", "retract", "shrink", "bigger", "big", "small", "smaller" ], "content": "\n" }, { "name": "arrow-transfer-diagonal-1", "keywords": [ "arrows", "arrow", "server", "data", "diagonal", "internet", "transfer", "network" ], "content": "\n" }, { "name": "arrow-transfer-diagonal-2", "keywords": [ "arrows", "arrow", "server", "data", "diagonal", "internet", "transfer", "network" ], "content": "\n" }, { "name": "arrow-transfer-diagonal-3", "keywords": [ "arrows", "arrow", "server", "data", "diagonal", "internet", "transfer", "network" ], "content": "\n" }, { "name": "arrow-up-1", "keywords": [ "arrow", "up", "keyboard" ], "content": "\n" }, { "name": "arrow-up-dashed-square", "keywords": [ "arrow", "keyboard", "button", "up", "square", "dashes" ], "content": "\n" }, { "name": "ascending-number-order", "keywords": [], "content": "\n" }, { "name": "attribution", "keywords": [], "content": "\n" }, { "name": "blank-calendar", "keywords": [ "blank", "calendar", "date", "day", "month", "empty" ], "content": "\n" }, { "name": "blank-notepad", "keywords": [ "content", "notes", "book", "notepad", "notebook" ], "content": "\n" }, { "name": "block-bell-notification", "keywords": [ "notification", "alarm", "alert", "bell", "block" ], "content": "\n" }, { "name": "bomb", "keywords": [ "delete", "bomb", "remove" ], "content": "\n" }, { "name": "bookmark", "keywords": [ "bookmarks", "tags", "favorite" ], "content": "\n" }, { "name": "braces-circle", "keywords": [ "interface", "math", "braces", "sign", "mathematics" ], "content": "\n" }, { "name": "brightness-1", "keywords": [ "bright", "adjust", "brightness", "adjustment", "sun", "raise", "controls" ], "content": "\n" }, { "name": "brightness-2", "keywords": [ "bright", "adjust", "brightness", "adjustment", "sun", "raise", "controls", "half" ], "content": "\n" }, { "name": "brightness-3", "keywords": [ "bright", "adjust", "brightness", "adjustment", "sun", "raise", "controls", "dot", "small" ], "content": "\n" }, { "name": "broken-link-2", "keywords": [ "break", "broken", "hyperlink", "link", "remove", "unlink", "chain" ], "content": "\n" }, { "name": "bullet-list", "keywords": [ "points", "bullet", "unordered", "list", "lists", "bullets" ], "content": "\n" }, { "name": "calendar-add", "keywords": [ "add", "calendar", "date", "day", "month" ], "content": "\n" }, { "name": "calendar-edit", "keywords": [ "calendar", "date", "day", "compose", "edit", "note" ], "content": "\n" }, { "name": "calendar-jump-to-date", "keywords": [], "content": "\n" }, { "name": "calendar-star", "keywords": [ "calendar", "date", "day", "favorite", "like", "month", "star" ], "content": "\n" }, { "name": "celsius", "keywords": [ "degrees", "temperature", "centigrade", "celsius", "degree", "weather" ], "content": "\n" }, { "name": "check", "keywords": [ "check", "form", "validation", "checkmark", "success", "add", "addition", "tick" ], "content": "\n" }, { "name": "check-square", "keywords": [ "check", "form", "validation", "checkmark", "success", "add", "addition", "box", "square", "tick" ], "content": "\n" }, { "name": "circle", "keywords": [ "geometric", "circle", "round", "design", "shape", "shapes", "shape" ], "content": "\n" }, { "name": "circle-clock", "keywords": [ "clock", "loading", "measure", "time", "circle" ], "content": "\n" }, { "name": "clipboard-add", "keywords": [ "edit", "task", "edition", "add", "clipboard", "form" ], "content": "\n" }, { "name": "clipboard-check", "keywords": [ "checkmark", "edit", "task", "edition", "checklist", "check", "success", "clipboard", "form" ], "content": "\n" }, { "name": "clipboard-remove", "keywords": [ "edit", "task", "edition", "remove", "delete", "clipboard", "form" ], "content": "\n" }, { "name": "cloud", "keywords": [ "cloud", "meteorology", "cloudy", "overcast", "cover", "weather" ], "content": "\n" }, { "name": "cog", "keywords": [ "work", "loading", "cog", "gear", "settings", "machine" ], "content": "\n" }, { "name": "color-palette", "keywords": [ "color", "palette", "company", "office", "supplies", "work" ], "content": "\n" }, { "name": "color-picker", "keywords": [ "color", "colors", "design", "dropper", "eye", "eyedrop", "eyedropper", "painting", "picker" ], "content": "\n" }, { "name": "color-swatches", "keywords": [ "color", "colors", "design", "painting", "palette", "sample", "swatch" ], "content": "\n" }, { "name": "cone-shape", "keywords": [], "content": "\n" }, { "name": "convert-PDF-2", "keywords": [ "essential", "files", "folder", "convert", "to", "PDF" ], "content": "\n" }, { "name": "copy-paste", "keywords": [ "clipboard", "copy", "cut", "paste" ], "content": "\n" }, { "name": "creative-commons", "keywords": [], "content": "\n" }, { "name": "crop-selection", "keywords": [ "artboard", "crop", "design", "image", "picture" ], "content": "\n" }, { "name": "crown", "keywords": [ "reward", "social", "rating", "media", "queen", "vip", "king", "crown" ], "content": "\n" }, { "name": "customer-support-1", "keywords": [ "customer", "headset", "help", "microphone", "phone", "support" ], "content": "\n" }, { "name": "cut", "keywords": [ "coupon", "cut", "discount", "price", "prices", "scissors" ], "content": "\n" }, { "name": "dark-dislay-mode", "keywords": [], "content": "\n" }, { "name": "dashboard-3", "keywords": [ "app", "application", "dashboard", "home", "layout", "vertical" ], "content": "\n" }, { "name": "dashboard-circle", "keywords": [ "app", "application", "dashboard", "home", "layout", "circle" ], "content": "\n" }, { "name": "delete-1", "keywords": [ "remove", "add", "button", "buttons", "delete", "cross", "x", "mathematics", "multiply", "math" ], "content": "\n" }, { "name": "descending-number-order", "keywords": [], "content": "\n" }, { "name": "disable-bell-notification", "keywords": [ "disable", "silent", "notification", "off", "silence", "alarm", "bell", "alert" ], "content": "\n" }, { "name": "disable-heart", "keywords": [], "content": "\n" }, { "name": "division-circle", "keywords": [ "interface", "math", "divided", "by", "sign", "mathematics" ], "content": "\n" }, { "name": "download-box-1", "keywords": [ "arrow", "box", "down", "download", "internet", "network", "server", "upload" ], "content": "\n" }, { "name": "download-circle", "keywords": [ "arrow", "circle", "down", "download", "internet", "network", "server", "upload" ], "content": "\n" }, { "name": "download-computer", "keywords": [ "action", "actions", "computer", "desktop", "device", "display", "download", "monitor", "screen" ], "content": "\n" }, { "name": "download-file", "keywords": [], "content": "\n" }, { "name": "empty-clipboard", "keywords": [ "work", "plain", "clipboard", "task", "list", "company", "office" ], "content": "\n" }, { "name": "equal-sign", "keywords": [ "interface", "math", "equal", "sign", "mathematics" ], "content": "\n" }, { "name": "expand", "keywords": [ "big", "bigger", "design", "expand", "larger", "resize", "size", "square" ], "content": "\n" }, { "name": "expand-horizontal-1", "keywords": [ "expand", "resize", "bigger", "horizontal", "smaller", "size", "arrow", "arrows", "big" ], "content": "\n" }, { "name": "expand-window-2", "keywords": [ "expand", "small", "bigger", "retract", "smaller", "big" ], "content": "\n" }, { "name": "face-scan-1", "keywords": [ "identification", "angle", "secure", "human", "id", "person", "face", "security", "brackets" ], "content": "\n" }, { "name": "factorial", "keywords": [ "interface", "math", "number", "factorial", "sign", "mathematics" ], "content": "\n" }, { "name": "fahrenheit", "keywords": [ "degrees", "temperature", "fahrenheit", "degree", "weather" ], "content": "\n" }, { "name": "fastforward-clock", "keywords": [ "time", "clock", "reset", "stopwatch", "circle", "measure", "loading" ], "content": "\n" }, { "name": "file-add-alternate", "keywords": [ "file", "common", "add" ], "content": "\n" }, { "name": "file-delete-alternate", "keywords": [ "file", "common", "delete", "cross" ], "content": "\n" }, { "name": "file-remove-alternate", "keywords": [ "file", "common", "remove", "minus", "subtract" ], "content": "\n" }, { "name": "filter-2", "keywords": [ "funnel", "filter", "angle", "oil" ], "content": "\n" }, { "name": "fingerprint-1", "keywords": [ "identification", "password", "touch", "id", "secure", "fingerprint", "finger", "security" ], "content": "\n" }, { "name": "fingerprint-2", "keywords": [ "identification", "password", "touch", "id", "secure", "fingerprint", "finger", "security" ], "content": "\n" }, { "name": "fist", "keywords": [], "content": "\n" }, { "name": "fit-to-height-square", "keywords": [], "content": "\n" }, { "name": "flip-vertical-arrow-2", "keywords": [ "arrow", "design", "flip", "reflect", "up", "down" ], "content": "\n" }, { "name": "flip-vertical-circle-1", "keywords": [ "flip", "bottom", "object", "work" ], "content": "\n" }, { "name": "flip-vertical-square-2", "keywords": [ "design", "up", "flip", "reflect", "vertical" ], "content": "\n" }, { "name": "folder-add", "keywords": [ "add", "folder", "plus" ], "content": "\n" }, { "name": "folder-check", "keywords": [ "remove", "check", "folder" ], "content": "\n" }, { "name": "folder-delete", "keywords": [ "remove", "minus", "folder", "subtract", "delete" ], "content": "\n" }, { "name": "front-camera", "keywords": [], "content": "\n" }, { "name": "gif-format", "keywords": [], "content": "\n" }, { "name": "give-gift", "keywords": [ "reward", "social", "rating", "media", "queen", "vip", "gift" ], "content": "\n" }, { "name": "glasses", "keywords": [ "vision", "sunglasses", "protection", "spectacles", "correction", "sun", "eye", "glasses" ], "content": "\n" }, { "name": "half-star-1", "keywords": [ "reward", "rating", "rate", "social", "star", "media", "favorite", "like", "stars", "half" ], "content": "\n" }, { "name": "hand-cursor", "keywords": [ "hand", "select", "cursor", "finger" ], "content": "\n" }, { "name": "hand-grab", "keywords": [ "hand", "select", "cursor", "finger", "grab" ], "content": "\n" }, { "name": "heading-1-paragraph-styles-heading", "keywords": [], "content": "\n" }, { "name": "heading-2-paragraph-styles-heading", "keywords": [], "content": "\n" }, { "name": "heading-3-paragraph-styles-heading", "keywords": [], "content": "\n" }, { "name": "heart", "keywords": [ "reward", "social", "rating", "media", "heart", "it", "like", "favorite", "love" ], "content": "\n" }, { "name": "help-chat-2", "keywords": [ "bubble", "help", "mark", "message", "query", "question", "speech", "circle" ], "content": "\n" }, { "name": "help-question-1", "keywords": [ "circle", "faq", "frame", "help", "info", "mark", "more", "query", "question" ], "content": "\n" }, { "name": "hierarchy-10", "keywords": [ "node", "organization", "links", "structure", "link", "nodes", "network", "hierarchy" ], "content": "\n" }, { "name": "hierarchy-13", "keywords": [ "node", "organization", "links", "structure", "link", "nodes", "network", "hierarchy" ], "content": "\n" }, { "name": "hierarchy-14", "keywords": [ "node", "organization", "links", "structure", "link", "nodes", "network", "hierarchy" ], "content": "\n" }, { "name": "hierarchy-2", "keywords": [ "node", "organization", "links", "structure", "link", "nodes", "network", "hierarchy" ], "content": "\n" }, { "name": "hierarchy-4", "keywords": [ "node", "organization", "links", "structure", "link", "nodes", "network", "hierarchy" ], "content": "\n" }, { "name": "hierarchy-7", "keywords": [ "node", "organization", "links", "structure", "link", "nodes", "network", "hierarchy" ], "content": "\n" }, { "name": "home-3", "keywords": [ "home", "house", "roof", "shelter" ], "content": "\n" }, { "name": "home-4", "keywords": [ "home", "house", "roof", "shelter" ], "content": "\n" }, { "name": "horizontal-menu-circle", "keywords": [ "navigation", "dots", "three", "circle", "button", "horizontal", "menu" ], "content": "\n" }, { "name": "humidity-none", "keywords": [ "humidity", "drop", "weather" ], "content": "\n" }, { "name": "image-blur", "keywords": [], "content": "\n" }, { "name": "image-saturation", "keywords": [], "content": "\n" }, { "name": "information-circle", "keywords": [ "information", "frame", "info", "more", "help", "point", "circle" ], "content": "\n" }, { "name": "input-box", "keywords": [ "cursor", "text", "formatting", "type", "format" ], "content": "\n" }, { "name": "insert-side", "keywords": [ "points", "bullet", "align", "paragraph", "formatting", "bullets", "text" ], "content": "\n" }, { "name": "insert-top-left", "keywords": [ "alignment", "wrap", "formatting", "paragraph", "image", "left", "text" ], "content": "\n" }, { "name": "insert-top-right", "keywords": [ "paragraph", "image", "text", "alignment", "wrap", "right", "formatting" ], "content": "\n" }, { "name": "invisible-1", "keywords": [ "disable", "eye", "eyeball", "hide", "off", "view" ], "content": "\n" }, { "name": "invisible-2", "keywords": [], "content": "\n" }, { "name": "jump-object", "keywords": [], "content": "\n" }, { "name": "key", "keywords": [ "entry", "key", "lock", "login", "pass", "unlock", "access" ], "content": "\n" }, { "name": "keyhole-lock-circle", "keywords": [ "circle", "frame", "key", "keyhole", "lock", "locked", "secure", "security" ], "content": "\n" }, { "name": "lasso-tool", "keywords": [], "content": "\n" }, { "name": "layers-1", "keywords": [ "design", "layer", "layers", "pile", "stack", "align" ], "content": "\n" }, { "name": "layers-2", "keywords": [ "design", "layer", "layers", "pile", "stack", "align" ], "content": "\n" }, { "name": "layout-window-1", "keywords": [ "column", "layout", "layouts", "left", "sidebar" ], "content": "\n" }, { "name": "layout-window-11", "keywords": [], "content": "\n" }, { "name": "layout-window-2", "keywords": [ "column", "header", "layout", "layouts", "masthead", "sidebar" ], "content": "\n" }, { "name": "layout-window-8", "keywords": [ "grid", "header", "layout", "layouts", "masthead" ], "content": "\n" }, { "name": "lightbulb", "keywords": [ "lighting", "light", "incandescent", "bulb", "lights" ], "content": "\n" }, { "name": "like-1", "keywords": [ "reward", "social", "up", "rating", "media", "like", "thumb", "hand" ], "content": "\n" }, { "name": "link-chain", "keywords": [ "create", "hyperlink", "link", "make", "unlink", "connection", "chain" ], "content": "\n" }, { "name": "live-video", "keywords": [], "content": "\n" }, { "name": "lock-rotation", "keywords": [], "content": "\n" }, { "name": "login-1", "keywords": [ "arrow", "enter", "frame", "left", "login", "point", "rectangle" ], "content": "\n" }, { "name": "logout-1", "keywords": [ "arrow", "exit", "frame", "leave", "logout", "rectangle", "right" ], "content": "\n" }, { "name": "loop-1", "keywords": [ "multimedia", "multi", "button", "repeat", "media", "loop", "infinity", "controls" ], "content": "\n" }, { "name": "magic-wand-2", "keywords": [ "design", "magic", "star", "supplies", "tool", "wand" ], "content": "\n" }, { "name": "magnifying-glass", "keywords": [ "glass", "search", "magnifying" ], "content": "\n" }, { "name": "magnifying-glass-circle", "keywords": [ "circle", "glass", "search", "magnifying" ], "content": "\n" }, { "name": "manual-book", "keywords": [], "content": "\n" }, { "name": "megaphone-2", "keywords": [ "bullhorn", "loud", "megaphone", "share", "speaker", "transmit" ], "content": "\n" }, { "name": "minimize-window-2", "keywords": [ "expand", "retract", "shrink", "bigger", "big", "small", "smaller" ], "content": "\n" }, { "name": "moon-cloud", "keywords": [ "cloud", "meteorology", "cloudy", "partly", "sunny", "weather" ], "content": "\n" }, { "name": "move-left", "keywords": [ "move", "left", "arrows" ], "content": "\n" }, { "name": "move-right", "keywords": [ "move", "right", "arrows" ], "content": "\n" }, { "name": "multiple-file-2", "keywords": [ "double", "common", "file" ], "content": "\n" }, { "name": "music-folder-song", "keywords": [], "content": "\n" }, { "name": "new-file", "keywords": [ "empty", "common", "file", "content" ], "content": "\n" }, { "name": "new-folder", "keywords": [ "empty", "folder" ], "content": "\n" }, { "name": "new-sticky-note", "keywords": [ "empty", "common", "file" ], "content": "\n" }, { "name": "not-equal-sign", "keywords": [ "interface", "math", "not", "equal", "sign", "mathematics" ], "content": "\n" }, { "name": "ok-hand", "keywords": [], "content": "\n" }, { "name": "one-finger-drag-horizontal", "keywords": [], "content": "\n" }, { "name": "one-finger-drag-vertical", "keywords": [], "content": "\n" }, { "name": "one-finger-hold", "keywords": [], "content": "\n" }, { "name": "one-finger-tap", "keywords": [], "content": "\n" }, { "name": "open-book", "keywords": [ "content", "books", "book", "open" ], "content": "\n" }, { "name": "open-umbrella", "keywords": [ "storm", "rain", "umbrella", "open", "weather" ], "content": "\n" }, { "name": "padlock-square-1", "keywords": [ "combination", "combo", "lock", "locked", "padlock", "secure", "security", "shield", "keyhole" ], "content": "\n" }, { "name": "page-setting", "keywords": [ "page", "setting", "square", "triangle", "circle", "line", "combination", "variation" ], "content": "\n" }, { "name": "paint-bucket", "keywords": [ "bucket", "color", "colors", "design", "paint", "painting" ], "content": "\n" }, { "name": "paint-palette", "keywords": [ "color", "colors", "design", "paint", "painting", "palette" ], "content": "\n" }, { "name": "paintbrush-1", "keywords": [ "brush", "color", "colors", "design", "paint", "painting" ], "content": "\n" }, { "name": "paintbrush-2", "keywords": [ "brush", "color", "colors", "design", "paint", "painting" ], "content": "\n" }, { "name": "paperclip-1", "keywords": [ "attachment", "link", "paperclip", "unlink" ], "content": "\n" }, { "name": "paragraph", "keywords": [ "alignment", "paragraph", "formatting", "text" ], "content": "\n" }, { "name": "pathfinder-divide", "keywords": [], "content": "\n" }, { "name": "pathfinder-exclude", "keywords": [], "content": "\n" }, { "name": "pathfinder-intersect", "keywords": [], "content": "\n" }, { "name": "pathfinder-merge", "keywords": [], "content": "\n" }, { "name": "pathfinder-minus-front-1", "keywords": [], "content": "\n" }, { "name": "pathfinder-trim", "keywords": [], "content": "\n" }, { "name": "pathfinder-union", "keywords": [], "content": "\n" }, { "name": "peace-hand", "keywords": [], "content": "\n" }, { "name": "pen-3", "keywords": [ "content", "creation", "edit", "pen", "pens", "write" ], "content": "\n" }, { "name": "pen-draw", "keywords": [], "content": "\n" }, { "name": "pen-tool", "keywords": [], "content": "\n" }, { "name": "pencil", "keywords": [ "change", "edit", "modify", "pencil", "write", "writing" ], "content": "\n" }, { "name": "pentagon", "keywords": [ "pentagon", "design", "geometric", "shape", "shapes", "shape" ], "content": "\n" }, { "name": "pi-symbol-circle", "keywords": [ "interface", "math", "pi", "sign", "mathematics", "22", "7" ], "content": "\n" }, { "name": "pictures-folder-memories", "keywords": [], "content": "\n" }, { "name": "podium", "keywords": [ "work", "desk", "notes", "company", "presentation", "office", "podium", "microphone" ], "content": "\n" }, { "name": "polygon", "keywords": [ "polygon", "octangle", "design", "geometric", "shape", "shapes", "shape" ], "content": "\n" }, { "name": "praying-hand", "keywords": [], "content": "\n" }, { "name": "projector-board", "keywords": [ "projector", "screen", "work", "meeting", "presentation" ], "content": "\n" }, { "name": "pyramid-shape", "keywords": [], "content": "\n" }, { "name": "quotation-2", "keywords": [ "quote", "quotation", "format", "formatting", "open", "close", "marks", "text" ], "content": "\n" }, { "name": "radioactive-2", "keywords": [ "warning", "radioactive", "radiation", "emergency", "danger", "safety" ], "content": "\n" }, { "name": "rain-cloud", "keywords": [ "cloud", "rain", "rainy", "meteorology", "precipitation", "weather" ], "content": "\n" }, { "name": "recycle-bin-2", "keywords": [ "remove", "delete", "empty", "bin", "trash", "garbage" ], "content": "\n" }, { "name": "ringing-bell-notification", "keywords": [ "notification", "vibrate", "ring", "sound", "alarm", "alert", "bell", "noise" ], "content": "\n" }, { "name": "rock-and-roll-hand", "keywords": [], "content": "\n" }, { "name": "rotate-angle-45", "keywords": [ "rotate", "angle", "company", "office", "supplies", "work" ], "content": "\n" }, { "name": "round-cap", "keywords": [], "content": "\n" }, { "name": "satellite-dish", "keywords": [ "broadcast", "satellite", "share", "transmit", "satellite" ], "content": "\n" }, { "name": "scanner", "keywords": [], "content": "\n" }, { "name": "search-visual", "keywords": [], "content": "\n" }, { "name": "select-circle-area-1", "keywords": [ "select", "area", "object", "work" ], "content": "\n" }, { "name": "share-link", "keywords": [ "share", "transmit" ], "content": "\n" }, { "name": "shield-1", "keywords": [ "shield", "protection", "security", "defend", "crime", "war", "cover" ], "content": "\n" }, { "name": "shield-2", "keywords": [ "shield", "protection", "security", "defend", "crime", "war", "cover" ], "content": "\n" }, { "name": "shield-check", "keywords": [ "shield", "protection", "security", "defend", "crime", "war", "cover", "check" ], "content": "\n" }, { "name": "shield-cross", "keywords": [ "shield", "secure", "security", "cross", "add", "plus" ], "content": "\n" }, { "name": "shrink-horizontal-1", "keywords": [ "resize", "shrink", "bigger", "horizontal", "smaller", "size", "arrow", "arrows", "big" ], "content": "\n" }, { "name": "shuffle", "keywords": [ "multimedia", "shuffle", "multi", "button", "controls", "media" ], "content": "\n" }, { "name": "sigma", "keywords": [ "formula", "text", "format", "sigma", "formatting", "sum" ], "content": "\n" }, { "name": "skull-1", "keywords": [ "crash", "death", "delete", "die", "error", "garbage", "remove", "skull", "trash" ], "content": "\n" }, { "name": "sleep", "keywords": [], "content": "\n" }, { "name": "snow-flake", "keywords": [ "winter", "freeze", "snow", "freezing", "ice", "cold", "weather", "snowflake" ], "content": "\n" }, { "name": "sort-descending", "keywords": [], "content": "\n" }, { "name": "spiral-shape", "keywords": [], "content": "\n" }, { "name": "split-vertical", "keywords": [], "content": "\n" }, { "name": "spray-paint", "keywords": [ "can", "color", "colors", "design", "paint", "painting", "spray" ], "content": "\n" }, { "name": "square-brackets-circle", "keywords": [ "interface", "math", "brackets", "sign", "mathematics" ], "content": "\n" }, { "name": "square-cap", "keywords": [], "content": "\n" }, { "name": "square-clock", "keywords": [ "clock", "loading", "frame", "measure", "time", "circle" ], "content": "\n" }, { "name": "square-root-x-circle", "keywords": [ "interface", "math", "square", "root", "sign", "mathematics" ], "content": "\n" }, { "name": "star-1", "keywords": [ "reward", "rating", "rate", "social", "star", "media", "favorite", "like", "stars" ], "content": "\n" }, { "name": "star-2", "keywords": [ "reward", "rating", "rate", "social", "star", "media", "favorite", "like", "stars", "spark" ], "content": "\n" }, { "name": "star-badge", "keywords": [ "ribbon", "reward", "like", "social", "rating", "media" ], "content": "\n" }, { "name": "straight-cap", "keywords": [], "content": "\n" }, { "name": "subtract-1", "keywords": [ "button", "delete", "buttons", "subtract", "horizontal", "remove", "line", "add", "mathematics", "math", "minus" ], "content": "\n" }, { "name": "subtract-circle", "keywords": [ "delete", "add", "circle", "subtract", "button", "buttons", "remove", "mathematics", "math", "minus" ], "content": "\n" }, { "name": "subtract-square", "keywords": [ "subtract", "buttons", "remove", "add", "button", "square", "delete", "mathematics", "math", "minus" ], "content": "\n" }, { "name": "sun-cloud", "keywords": [ "cloud", "meteorology", "cloudy", "partly", "sunny", "weather" ], "content": "\n" }, { "name": "synchronize-disable", "keywords": [ "arrows", "loading", "load", "sync", "synchronize", "arrow", "reload" ], "content": "\n" }, { "name": "synchronize-warning", "keywords": [ "arrow", "fail", "notification", "sync", "warning", "failure", "synchronize", "error" ], "content": "\n" }, { "name": "table-lamp-1", "keywords": [ "lighting", "light", "incandescent", "bulb", "lights", "table", "lamp" ], "content": "\n" }, { "name": "tag", "keywords": [ "tags", "bookmark", "favorite" ], "content": "\n" }, { "name": "text-flow-rows", "keywords": [], "content": "\n" }, { "name": "text-square", "keywords": [ "text", "options", "formatting", "format", "square", "color", "border", "fill" ], "content": "\n" }, { "name": "text-style", "keywords": [ "text", "style", "formatting", "format" ], "content": "\n" }, { "name": "thermometer", "keywords": [ "temperature", "thermometer", "weather", "level", "meter", "mercury", "measure" ], "content": "\n" }, { "name": "trending-content", "keywords": [ "lit", "flame", "torch", "trending" ], "content": "\n" }, { "name": "trophy", "keywords": [ "reward", "rating", "trophy", "social", "award", "media" ], "content": "\n" }, { "name": "two-finger-drag-hotizontal", "keywords": [], "content": "\n" }, { "name": "two-finger-tap", "keywords": [], "content": "\n" }, { "name": "underline-text-1", "keywords": [ "text", "underline", "formatting", "format" ], "content": "\n" }, { "name": "upload-box-1", "keywords": [ "arrow", "box", "download", "internet", "network", "server", "up", "upload" ], "content": "\n" }, { "name": "upload-circle", "keywords": [ "arrow", "circle", "download", "internet", "network", "server", "up", "upload" ], "content": "\n" }, { "name": "upload-computer", "keywords": [ "action", "actions", "computer", "desktop", "device", "display", "monitor", "screen", "upload" ], "content": "\n" }, { "name": "upload-file", "keywords": [], "content": "\n" }, { "name": "user-add-plus", "keywords": [ "actions", "add", "close", "geometric", "human", "person", "plus", "single", "up", "user" ], "content": "\n" }, { "name": "user-check-validate", "keywords": [ "actions", "close", "checkmark", "check", "geometric", "human", "person", "single", "success", "up", "user" ], "content": "\n" }, { "name": "user-circle-single", "keywords": [ "circle", "geometric", "human", "person", "single", "user" ], "content": "\n" }, { "name": "user-identifier-card", "keywords": [], "content": "\n" }, { "name": "user-multiple-circle", "keywords": [ "close", "geometric", "human", "multiple", "person", "up", "user", "circle" ], "content": "\n" }, { "name": "user-multiple-group", "keywords": [ "close", "geometric", "human", "multiple", "person", "up", "user" ], "content": "\n" }, { "name": "user-profile-focus", "keywords": [ "close", "geometric", "human", "person", "profile", "focus", "user" ], "content": "\n" }, { "name": "user-protection-2", "keywords": [ "shield", "secure", "security", "profile", "person" ], "content": "\n" }, { "name": "user-remove-subtract", "keywords": [ "actions", "remove", "close", "geometric", "human", "person", "minus", "single", "up", "user" ], "content": "\n" }, { "name": "user-single-neutral-male", "keywords": [ "close", "geometric", "human", "person", "single", "up", "user", "male" ], "content": "\n" }, { "name": "user-sync-online-in-person", "keywords": [], "content": "\n" }, { "name": "vertical-slider-square", "keywords": [ "adjustment", "adjust", "controls", "fader", "vertical", "settings", "slider", "square" ], "content": "\n" }, { "name": "video-swap-camera", "keywords": [], "content": "\n" }, { "name": "visible", "keywords": [ "eye", "eyeball", "open", "view" ], "content": "\n" }, { "name": "voice-scan-2", "keywords": [ "identification", "secure", "id", "soundwave", "sound", "voice", "brackets", "security" ], "content": "\n" }, { "name": "waning-cresent-moon", "keywords": [ "night", "new", "moon", "crescent", "weather", "time", "waning" ], "content": "\n" }, { "name": "warning-octagon", "keywords": [ "frame", "alert", "warning", "octagon", "exclamation", "caution" ], "content": "\n" }, { "name": "warning-triangle", "keywords": [ "frame", "alert", "warning", "triangle", "exclamation", "caution" ], "content": "\n" } ], "mail": [ { "name": "chat-bubble-oval", "keywords": [ "messages", "message", "bubble", "chat", "oval" ], "content": "\n" }, { "name": "chat-bubble-oval-notification", "keywords": [ "messages", "message", "bubble", "chat", "oval", "notify", "ping" ], "content": "\n" }, { "name": "chat-bubble-oval-smiley-1", "keywords": [ "messages", "message", "bubble", "chat", "oval", "smiley", "smile" ], "content": "\n" }, { "name": "chat-bubble-oval-smiley-2", "keywords": [ "messages", "message", "bubble", "chat", "oval", "smiley", "smile" ], "content": "\n" }, { "name": "chat-bubble-square-block", "keywords": [ "messages", "message", "bubble", "chat", "square", "block" ], "content": "\n" }, { "name": "chat-bubble-square-question", "keywords": [ "bubble", "square", "messages", "notification", "chat", "message", "question", "help" ], "content": "\n" }, { "name": "chat-bubble-square-warning", "keywords": [ "bubble", "square", "messages", "notification", "chat", "message", "warning", "alert" ], "content": "\n" }, { "name": "chat-bubble-square-write", "keywords": [ "messages", "message", "bubble", "chat", "square", "write", "review", "pen", "pencil", "compose" ], "content": "\n" }, { "name": "chat-bubble-text-square", "keywords": [ "messages", "message", "bubble", "text", "square", "chat" ], "content": "\n" }, { "name": "chat-bubble-typing-oval", "keywords": [ "messages", "message", "bubble", "typing", "chat" ], "content": "\n" }, { "name": "chat-two-bubbles-oval", "keywords": [ "messages", "message", "bubble", "chat", "oval", "conversation" ], "content": "\n" }, { "name": "discussion-converstion-reply", "keywords": [], "content": "\n" }, { "name": "happy-face", "keywords": [ "smiley", "chat", "message", "smile", "emoji", "face", "satisfied" ], "content": "\n" }, { "name": "inbox-block", "keywords": [ "mail", "envelope", "email", "message", "block", "spam", "remove" ], "content": "\n" }, { "name": "inbox-favorite", "keywords": [ "mail", "envelope", "email", "message", "star", "favorite", "important", "bookmark" ], "content": "\n" }, { "name": "inbox-favorite-heart", "keywords": [ "mail", "envelope", "email", "message", "heart", "favorite", "like", "love", "important", "bookmark" ], "content": "\n" }, { "name": "inbox-lock", "keywords": [ "mail", "envelope", "email", "message", "secure", "password", "lock", "encryption" ], "content": "\n" }, { "name": "inbox-tray-1", "keywords": [ "mail", "email", "outbox", "drawer", "empty", "open", "inbox", "arrow", "down" ], "content": "\n" }, { "name": "inbox-tray-2", "keywords": [ "mail", "email", "outbox", "drawer", "empty", "open", "inbox", "arrow", "up" ], "content": "\n" }, { "name": "mail-incoming", "keywords": [ "inbox", "envelope", "email", "message", "down", "arrow", "inbox" ], "content": "\n" }, { "name": "mail-search", "keywords": [ "inbox", "envelope", "email", "message", "search" ], "content": "\n" }, { "name": "mail-send-email-message", "keywords": [ "send", "email", "paper", "airplane", "deliver" ], "content": "\n" }, { "name": "mail-send-envelope", "keywords": [ "envelope", "email", "message", "unopened", "sealed", "close" ], "content": "\n" }, { "name": "mail-send-reply-all", "keywords": [ "email", "message", "reply", "all", "actions", "action", "arrow" ], "content": "\n" }, { "name": "sad-face", "keywords": [ "smiley", "chat", "message", "emoji", "sad", "face", "unsatisfied" ], "content": "\n" }, { "name": "send-email", "keywords": [ "mail", "send", "email", "paper", "airplane" ], "content": "\n" }, { "name": "sign-at", "keywords": [ "mail", "email", "at", "sign", "read", "address" ], "content": "\n" }, { "name": "sign-hashtag", "keywords": [ "mail", "sharp", "sign", "hashtag", "tag" ], "content": "\n" }, { "name": "smiley-angry", "keywords": [], "content": "\n" }, { "name": "smiley-cool", "keywords": [], "content": "\n" }, { "name": "smiley-crying-1", "keywords": [], "content": "\n" }, { "name": "smiley-cute", "keywords": [], "content": "\n" }, { "name": "smiley-drool", "keywords": [], "content": "\n" }, { "name": "smiley-emoji-kiss-nervous", "keywords": [], "content": "\n" }, { "name": "smiley-emoji-terrified", "keywords": [], "content": "\n" }, { "name": "smiley-grumpy", "keywords": [], "content": "\n" }, { "name": "smiley-happy", "keywords": [], "content": "\n" }, { "name": "smiley-in-love", "keywords": [], "content": "\n" }, { "name": "smiley-kiss", "keywords": [], "content": "\n" }, { "name": "smiley-laughing-3", "keywords": [], "content": "\n" } ], "map_travel": [ { "name": "airplane", "keywords": [ "travel", "plane", "adventure", "airplane", "transportation" ], "content": "\n" }, { "name": "airport-plane-transit", "keywords": [], "content": "\n" }, { "name": "airport-plane", "keywords": [], "content": "\n" }, { "name": "airport-security", "keywords": [], "content": "\n" }, { "name": "anchor", "keywords": [ "anchor", "marina", "harbor", "port", "travel", "places" ], "content": "\n" }, { "name": "baggage", "keywords": [ "check", "baggage", "travel", "adventure", "luggage", "bag", "checked", "airport" ], "content": "\n" }, { "name": "beach", "keywords": [ "island", "waves", "outdoor", "recreation", "tree", "beach", "palm", "wave", "water", "travel", "places" ], "content": "\n" }, { "name": "bicycle-bike", "keywords": [], "content": "\n" }, { "name": "braille-blind", "keywords": [ "disability", "braille", "blind" ], "content": "\n" }, { "name": "bus", "keywords": [ "transportation", "travel", "bus", "transit", "transport", "motorcoach", "public" ], "content": "\n" }, { "name": "camping-tent", "keywords": [ "outdoor", "recreation", "camping", "tent", "teepee", "tipi", "travel", "places" ], "content": "\n" }, { "name": "cane", "keywords": [ "disability", "cane" ], "content": "\n" }, { "name": "capitol", "keywords": [ "capitol", "travel", "places" ], "content": "\n" }, { "name": "car-battery-charging", "keywords": [], "content": "\n" }, { "name": "car-taxi-1", "keywords": [ "transportation", "travel", "taxi", "transport", "cab", "car" ], "content": "\n" }, { "name": "city-hall", "keywords": [ "city", "hall", "travel", "places" ], "content": "\n" }, { "name": "compass-navigator", "keywords": [], "content": "\n" }, { "name": "crutch", "keywords": [ "disability", "crutch" ], "content": "\n" }, { "name": "dangerous-zone-sign", "keywords": [], "content": "\n" }, { "name": "earth-1", "keywords": [ "planet", "earth", "globe", "world" ], "content": "\n" }, { "name": "earth-airplane", "keywords": [ "travel", "plane", "trip", "airplane", "international", "adventure", "globe", "world", "airport" ], "content": "\n" }, { "name": "emergency-exit", "keywords": [], "content": "\n" }, { "name": "fire-alarm-2", "keywords": [], "content": "\n" }, { "name": "fire-extinguisher-sign", "keywords": [], "content": "\n" }, { "name": "gas-station-fuel-petroleum", "keywords": [], "content": "\n" }, { "name": "hearing-deaf-1", "keywords": [ "disability", "hearing", "deaf" ], "content": "\n" }, { "name": "hearing-deaf-2", "keywords": [ "disability", "hearing", "deaf" ], "content": "\n" }, { "name": "high-speed-train-front", "keywords": [], "content": "\n" }, { "name": "hot-spring", "keywords": [ "relax", "location", "outdoor", "recreation", "spa", "travel", "places" ], "content": "\n" }, { "name": "hotel-air-conditioner", "keywords": [ "heating", "ac", "air", "hvac", "cool", "cooling", "cold", "hot", "conditioning", "hotel" ], "content": "\n" }, { "name": "hotel-bed-2", "keywords": [ "bed", "double", "bedroom", "bedrooms", "queen", "king", "full", "hotel", "hotel" ], "content": "\n" }, { "name": "hotel-laundry", "keywords": [ "laundry", "machine", "hotel" ], "content": "\n" }, { "name": "hotel-one-star", "keywords": [ "one", "star", "reviews", "review", "rating", "hotel", "star" ], "content": "\n" }, { "name": "hotel-shower-head", "keywords": [ "bathe", "bath", "bathroom", "shower", "water", "head", "hotel" ], "content": "\n" }, { "name": "hotel-two-star", "keywords": [ "two", "stars", "reviews", "review", "rating", "hotel", "star" ], "content": "\n" }, { "name": "information-desk-customer", "keywords": [], "content": "\n" }, { "name": "information-desk", "keywords": [], "content": "\n" }, { "name": "iron", "keywords": [ "laundry", "iron", "heat", "hotel" ], "content": "\n" }, { "name": "ladder", "keywords": [ "business", "product", "metaphor", "ladder" ], "content": "\n" }, { "name": "lift", "keywords": [ "arrow", "up", "human", "down", "person", "user", "lift", "elevator" ], "content": "\n" }, { "name": "lift-disability", "keywords": [ "arrow", "up", "human", "down", "person", "user", "lift", "elevator", "disability", "wheelchair", "accessible" ], "content": "\n" }, { "name": "location-compass-1", "keywords": [ "arrow", "compass", "location", "gps", "map", "maps", "point" ], "content": "\n" }, { "name": "location-pin-3", "keywords": [ "navigation", "map", "maps", "pin", "gps", "location" ], "content": "\n" }, { "name": "location-pin-disabled", "keywords": [ "navigation", "map", "maps", "pin", "gps", "location", "disabled", "off" ], "content": "\n" }, { "name": "location-target-1", "keywords": [ "navigation", "location", "map", "services", "maps", "gps", "target" ], "content": "\n" }, { "name": "lost-and-found", "keywords": [], "content": "\n" }, { "name": "man-symbol", "keywords": [ "geometric", "gender", "boy", "person", "male", "human", "user" ], "content": "\n" }, { "name": "map-fold", "keywords": [ "navigation", "map", "maps", "gps", "travel", "fold" ], "content": "\n" }, { "name": "navigation-arrow-off", "keywords": [ "compass", "arrow", "map", "bearing", "navigation", "maps", "heading", "gps", "off", "disable" ], "content": "\n" }, { "name": "navigation-arrow-on", "keywords": [ "compass", "arrow", "map", "bearing", "navigation", "maps", "heading", "gps", "off", "disable" ], "content": "\n" }, { "name": "parking-sign", "keywords": [ "discount", "coupon", "parking", "price", "prices", "hotel" ], "content": "\n" }, { "name": "parliament", "keywords": [ "travel", "places", "parliament" ], "content": "\n" }, { "name": "passport", "keywords": [ "travel", "book", "id", "adventure", "visa", "airport" ], "content": "\n" }, { "name": "pet-paw", "keywords": [ "paw", "foot", "animals", "pets", "footprint", "track", "hotel" ], "content": "\n" }, { "name": "pets-allowed", "keywords": [ "travel", "wayfinder", "pets", "allowed" ], "content": "\n" }, { "name": "pool-ladder", "keywords": [ "pool", "stairs", "swim", "swimming", "water", "ladder", "hotel" ], "content": "\n" }, { "name": "rock-slide", "keywords": [ "hill", "cliff", "sign", "danger", "stone" ], "content": "\n" }, { "name": "sail-ship", "keywords": [ "travel", "boat", "transportation", "transport", "ocean", "ship", "sea", "water" ], "content": "\n" }, { "name": "school-bus-side", "keywords": [], "content": "\n" }, { "name": "smoke-detector", "keywords": [ "smoke", "alert", "fire", "signal" ], "content": "\n" }, { "name": "smoking-area", "keywords": [], "content": "\n" }, { "name": "snorkle", "keywords": [ "diving", "scuba", "outdoor", "recreation", "ocean", "mask", "water", "sea", "snorkle", "travel", "places" ], "content": "\n" }, { "name": "steering-wheel", "keywords": [], "content": "\n" }, { "name": "street-road", "keywords": [], "content": "\n" }, { "name": "street-sign", "keywords": [ "crossroad", "street", "sign", "metaphor", "directions", "travel", "places" ], "content": "\n" }, { "name": "take-off", "keywords": [ "travel", "plane", "adventure", "airplane", "take", "off", "airport" ], "content": "\n" }, { "name": "toilet-man", "keywords": [ "travel", "wayfinder", "toilet", "man" ], "content": "\n" }, { "name": "toilet-sign-man-woman-2", "keywords": [ "toilet", "sign", "restroom", "bathroom", "user", "human", "person" ], "content": "\n" }, { "name": "toilet-women", "keywords": [ "travel", "wayfinder", "toilet", "women" ], "content": "\n" }, { "name": "traffic-cone", "keywords": [ "street", "sign", "traffic", "cone", "road" ], "content": "\n" }, { "name": "triangle-flag", "keywords": [ "navigation", "map", "maps", "flag", "gps", "location", "destination", "goal" ], "content": "\n" }, { "name": "wheelchair-1", "keywords": [ "person", "access", "wheelchair", "accomodation", "human", "disability", "disabled", "user" ], "content": "\n" }, { "name": "woman-symbol", "keywords": [ "geometric", "gender", "female", "person", "human", "user" ], "content": "\n" } ], "money_shopping": [ { "name": "annoncement-megaphone", "keywords": [], "content": "\n" }, { "name": "backpack", "keywords": [ "bag", "backpack", "school", "baggage", "cloth", "clothing", "accessories" ], "content": "\n" }, { "name": "bag", "keywords": [ "bag", "payment", "cash", "money", "finance" ], "content": "\n" }, { "name": "bag-dollar", "keywords": [ "bag", "payment", "cash", "money", "finance" ], "content": "\n" }, { "name": "bag-pound", "keywords": [ "bag", "payment", "cash", "money", "finance" ], "content": "\n" }, { "name": "bag-rupee", "keywords": [ "bag", "payment", "cash", "money", "finance" ], "content": "\n" }, { "name": "bag-suitcase-1", "keywords": [ "product", "business", "briefcase" ], "content": "\n" }, { "name": "bag-suitcase-2", "keywords": [ "product", "business", "briefcase" ], "content": "\n" }, { "name": "bag-yen", "keywords": [ "bag", "payment", "cash", "money", "finance" ], "content": "\n" }, { "name": "ball", "keywords": [ "sports", "ball", "sport", "basketball", "shopping", "catergories" ], "content": "\n" }, { "name": "bank", "keywords": [ "institution", "saving", "bank", "payment", "finance" ], "content": "\n" }, { "name": "beanie", "keywords": [ "beanie", "winter", "hat", "warm", "cloth", "clothing", "wearable", "accessories" ], "content": "\n" }, { "name": "bill-1", "keywords": [ "billing", "bills", "payment", "finance", "cash", "currency", "money", "accounting" ], "content": "\n" }, { "name": "bill-2", "keywords": [ "currency", "billing", "payment", "finance", "cash", "bill", "money", "accounting" ], "content": "\n" }, { "name": "bill-4", "keywords": [ "accounting", "billing", "payment", "finance", "cash", "currency", "money", "bill", "dollar", "stack" ], "content": "\n" }, { "name": "bill-cashless", "keywords": [ "currency", "billing", "payment", "finance", "no", "cash", "bill", "money", "accounting", "cashless" ], "content": "\n" }, { "name": "binance-circle", "keywords": [ "crypto", "circle", "payment", "blockchain", "finance", "binance", "currency" ], "content": "\n" }, { "name": "bitcoin", "keywords": [ "crypto", "circle", "payment", "blokchain", "finance", "bitcoin", "money", "currency" ], "content": "\n" }, { "name": "bow-tie", "keywords": [ "bow", "tie", "dress", "gentleman", "cloth", "clothing", "accessories" ], "content": "\n" }, { "name": "briefcase-dollar", "keywords": [ "briefcase", "payment", "cash", "money", "finance", "baggage", "bag" ], "content": "\n" }, { "name": "building-2", "keywords": [ "real", "home", "tower", "building", "house", "estate" ], "content": "\n" }, { "name": "business-card", "keywords": [ "name", "card", "business", "information", "money", "payment" ], "content": "\n" }, { "name": "business-handshake", "keywords": [ "deal", "contract", "business", "money", "payment", "agreement" ], "content": "\n" }, { "name": "business-idea-money", "keywords": [], "content": "\n" }, { "name": "business-profession-home-office", "keywords": [ "workspace", "home", "office", "work", "business", "remote", "working" ], "content": "\n" }, { "name": "business-progress-bar-2", "keywords": [ "business", "production", "arrow", "workflow", "money", "flag", "timeline" ], "content": "\n" }, { "name": "business-user-curriculum", "keywords": [], "content": "\n" }, { "name": "calculator-1", "keywords": [ "shop", "shopping", "pay", "payment", "store", "cash", "calculate", "math" ], "content": "\n" }, { "name": "calculator-2", "keywords": [ "shop", "shopping", "pay", "payment", "store", "cash", "calculate", "math", "sign" ], "content": "\n" }, { "name": "cane", "keywords": [ "walking", "stick", "cane", "accessories", "gentleman", "accessories" ], "content": "\n" }, { "name": "chair", "keywords": [ "chair", "business", "product", "comfort", "decoration", "sit", "furniture" ], "content": "\n" }, { "name": "closet", "keywords": [ "closet", "dressing", "dresser", "product", "decoration", "cloth", "clothing", "cabinet", "furniture" ], "content": "\n" }, { "name": "coin-share", "keywords": [ "payment", "cash", "money", "finance", "receive", "give", "coin", "hand" ], "content": "\n" }, { "name": "coins-stack", "keywords": [ "accounting", "billing", "payment", "stack", "cash", "coins", "currency", "money", "finance" ], "content": "\n" }, { "name": "credit-card-1", "keywords": [ "credit", "pay", "payment", "debit", "card", "finance", "plastic", "money", "atm" ], "content": "\n" }, { "name": "credit-card-2", "keywords": [ "deposit", "payment", "finance", "atm", "withdraw", "atm" ], "content": "\n" }, { "name": "diamond-2", "keywords": [ "diamond", "money", "payment", "finance", "wealth", "jewelry" ], "content": "\n" }, { "name": "discount-percent-badge", "keywords": [ "shop", "shops", "stores", "discount", "coupon" ], "content": "\n" }, { "name": "discount-percent-circle", "keywords": [ "store", "shop", "shops", "stores", "discount", "coupon" ], "content": "\n" }, { "name": "discount-percent-coupon", "keywords": [ "shop", "shops", "stores", "discount", "coupon", "voucher" ], "content": "\n" }, { "name": "discount-percent-cutout", "keywords": [ "store", "shop", "shops", "stores", "discount", "coupon" ], "content": "\n" }, { "name": "discount-percent-fire", "keywords": [ "shop", "shops", "stores", "discount", "coupon", "hot", "trending" ], "content": "\n" }, { "name": "dollar-coin", "keywords": [ "accounting", "billing", "payment", "cash", "coin", "currency", "money", "finance" ], "content": "\n" }, { "name": "dollar-coin-1", "keywords": [ "accounting", "billing", "payment", "cash", "coin", "currency", "money", "finance" ], "content": "\n" }, { "name": "dressing-table", "keywords": [ "makeup", "dressing", "table", "mirror", "cabinet", "product", "decoration", "furniture" ], "content": "\n" }, { "name": "ethereum", "keywords": [ "crypto", "circle", "payment", "blokchain", "finance", "ethereum", "eth", "currency" ], "content": "\n" }, { "name": "ethereum-circle", "keywords": [ "crypto", "circle", "payment", "blockchain", "finance", "eth", "currency" ], "content": "\n" }, { "name": "euro", "keywords": [ "exchange", "payment", "euro", "forex", "finance", "foreign", "currency" ], "content": "\n" }, { "name": "gift", "keywords": [ "reward", "box", "social", "present", "gift", "media", "rating", "bow" ], "content": "\n" }, { "name": "gift-2", "keywords": [ "reward", "box", "social", "present", "gift", "media", "rating", "bow" ], "content": "\n" }, { "name": "gold", "keywords": [ "gold", "money", "payment", "bars", "finance", "wealth", "bullion", "jewelry" ], "content": "\n" }, { "name": "graph", "keywords": [ "analytics", "business", "product", "graph", "data", "chart", "analysis" ], "content": "\n" }, { "name": "graph-arrow-decrease", "keywords": [ "down", "stats", "graph", "descend", "right", "arrow" ], "content": "\n" }, { "name": "graph-arrow-increase", "keywords": [ "ascend", "growth", "up", "arrow", "stats", "graph", "right", "grow" ], "content": "\n" }, { "name": "graph-bar-decrease", "keywords": [ "arrow", "product", "performance", "down", "decrease", "graph", "business", "chart" ], "content": "\n" }, { "name": "graph-bar-increase", "keywords": [ "up", "product", "performance", "increase", "arrow", "graph", "business", "chart" ], "content": "\n" }, { "name": "graph-dot", "keywords": [ "product", "data", "bars", "analysis", "analytics", "graph", "business", "chart", "dot" ], "content": "\n" }, { "name": "investment-selection", "keywords": [], "content": "\n" }, { "name": "justice-hammer", "keywords": [ "hammer", "work", "mallet", "office", "company", "gavel", "justice", "judge", "arbitration", "court" ], "content": "\n" }, { "name": "justice-scale-1", "keywords": [ "office", "work", "scale", "justice", "company", "arbitration", "balance", "court" ], "content": "\n" }, { "name": "justice-scale-2", "keywords": [ "office", "work", "scale", "justice", "unequal", "company", "arbitration", "unbalance", "court" ], "content": "\n" }, { "name": "lipstick", "keywords": [ "fashion", "beauty", "lip", "lipstick", "makeup", "shopping" ], "content": "\n" }, { "name": "make-up-brush", "keywords": [ "fashion", "beauty", "make", "up", "brush" ], "content": "\n" }, { "name": "moustache", "keywords": [ "fashion", "beauty", "moustache", "grooming" ], "content": "\n" }, { "name": "mouth-lip", "keywords": [ "fashion", "beauty", "mouth", "lip" ], "content": "\n" }, { "name": "necklace", "keywords": [ "diamond", "money", "payment", "finance", "wealth", "accessory", "necklace", "jewelry" ], "content": "\n" }, { "name": "necktie", "keywords": [ "necktie", "businessman", "business", "cloth", "clothing", "gentleman", "accessories" ], "content": "\n" }, { "name": "payment-10", "keywords": [ "deposit", "payment", "finance", "atm", "transfer", "dollar" ], "content": "\n" }, { "name": "payment-cash-out-3", "keywords": [], "content": "\n" }, { "name": "pie-chart", "keywords": [ "product", "data", "analysis", "analytics", "pie", "business", "chart" ], "content": "\n" }, { "name": "piggy-bank", "keywords": [ "institution", "saving", "bank", "payment", "finance" ], "content": "\n" }, { "name": "polka-dot-circle", "keywords": [ "crypto", "circle", "payment", "blockchain", "finance", "polka", "dot", "currency" ], "content": "\n" }, { "name": "production-belt", "keywords": [ "production", "produce", "box", "belt", "factory", "product", "package", "business" ], "content": "\n" }, { "name": "qr-code", "keywords": [ "codes", "tags", "code", "qr" ], "content": "\n" }, { "name": "receipt", "keywords": [ "shop", "shopping", "pay", "payment", "store", "cash", "bill", "receipt" ], "content": "\n" }, { "name": "receipt-add", "keywords": [ "shop", "shopping", "pay", "payment", "store", "cash", "bill", "receipt", "add", "plus", "new" ], "content": "\n" }, { "name": "receipt-check", "keywords": [ "shop", "shopping", "pay", "payment", "store", "cash", "bill", "receipt", "check", "confirm" ], "content": "\n" }, { "name": "receipt-subtract", "keywords": [ "shop", "shopping", "pay", "payment", "store", "cash", "bill", "receipt", "subtract", "minus", "remove" ], "content": "\n" }, { "name": "safe-vault", "keywords": [ "saving", "combo", "payment", "safe", "combination", "finance" ], "content": "\n" }, { "name": "scanner-3", "keywords": [ "payment", "electronic", "cash", "dollar", "codes", "tags", "upc", "barcode", "qr" ], "content": "\n" }, { "name": "scanner-bar-code", "keywords": [ "codes", "tags", "upc", "barcode" ], "content": "\n" }, { "name": "shelf", "keywords": [ "shelf", "drawer", "cabinet", "prodcut", "decoration", "furniture" ], "content": "\n" }, { "name": "shopping-bag-hand-bag-2", "keywords": [ "shopping", "bag", "purse", "goods", "item", "products" ], "content": "\n" }, { "name": "shopping-basket-1", "keywords": [ "shopping", "basket" ], "content": "\n" }, { "name": "shopping-basket-2", "keywords": [ "shopping", "basket" ], "content": "\n" }, { "name": "shopping-cart-1", "keywords": [ "shopping", "cart", "checkout" ], "content": "\n" }, { "name": "shopping-cart-2", "keywords": [ "shopping", "cart", "checkout" ], "content": "\n" }, { "name": "shopping-cart-3", "keywords": [ "shopping", "cart", "checkout" ], "content": "\n" }, { "name": "shopping-cart-add", "keywords": [ "shopping", "cart", "checkout", "add", "plus", "new" ], "content": "\n" }, { "name": "shopping-cart-check", "keywords": [ "shopping", "cart", "checkout", "check", "confirm" ], "content": "\n" }, { "name": "shopping-cart-subtract", "keywords": [ "shopping", "cart", "checkout", "subtract", "minus", "remove" ], "content": "\n" }, { "name": "signage-3", "keywords": [ "street", "sandwich", "shops", "shop", "stores", "board", "sign", "store" ], "content": "\n" }, { "name": "signage-4", "keywords": [ "street", "billboard", "shops", "shop", "stores", "board", "sign", "ads", "banner" ], "content": "\n" }, { "name": "startup", "keywords": [ "shop", "rocket", "launch", "startup" ], "content": "\n" }, { "name": "stock", "keywords": [ "price", "stock", "wallstreet", "dollar", "money", "currency", "fluctuate", "candlestick", "business" ], "content": "\n" }, { "name": "store-1", "keywords": [ "store", "shop", "shops", "stores" ], "content": "\n" }, { "name": "store-2", "keywords": [ "store", "shop", "shops", "stores" ], "content": "\n" }, { "name": "store-computer", "keywords": [ "store", "shop", "shops", "stores", "online", "computer", "website", "desktop", "app" ], "content": "\n" }, { "name": "subscription-cashflow", "keywords": [], "content": "\n" }, { "name": "tag", "keywords": [ "codes", "tags", "tag", "product", "label" ], "content": "\n" }, { "name": "tall-hat", "keywords": [ "tall", "hat", "cloth", "clothing", "wearable", "magician", "gentleman", "accessories" ], "content": "\n" }, { "name": "target", "keywords": [ "shop", "bullseye", "arrow", "target" ], "content": "\n" }, { "name": "target-3", "keywords": [ "shop", "bullseye", "shooting", "target" ], "content": "\n" }, { "name": "wallet", "keywords": [ "money", "payment", "finance", "wallet" ], "content": "\n" }, { "name": "wallet-purse", "keywords": [ "money", "payment", "finance", "wallet", "purse" ], "content": "\n" }, { "name": "xrp-circle", "keywords": [ "crypto", "circle", "payment", "blockchain", "finance", "xrp", "currency" ], "content": "\n" }, { "name": "yuan", "keywords": [ "exchange", "payment", "forex", "finance", "yuan", "foreign", "currency" ], "content": "\n" }, { "name": "yuan-circle", "keywords": [ "exchange", "payment", "forex", "finance", "yuan", "foreign", "currency" ], "content": "\n" } ], "nature_ecology": [ { "name": "affordable-and-clean-energy", "keywords": [], "content": "\n" }, { "name": "alien", "keywords": [ "science", "extraterristerial", "life", "form", "space", "universe", "head", "astronomy" ], "content": "\n" }, { "name": "bone", "keywords": [ "nature", "pet", "dog", "bone", "food", "snack" ], "content": "\n" }, { "name": "cat-1", "keywords": [ "nature", "head", "cat", "pet", "animals", "felyne" ], "content": "\n" }, { "name": "circle-flask", "keywords": [ "science", "experiment", "lab", "flask", "chemistry", "solution" ], "content": "\n" }, { "name": "clean-water-and-sanitation", "keywords": [], "content": "\n" }, { "name": "comet", "keywords": [ "nature", "meteor", "fall", "space", "object", "danger" ], "content": "\n" }, { "name": "decent-work-and-economic-growth", "keywords": [], "content": "\n" }, { "name": "dna", "keywords": [ "science", "biology", "experiment", "lab", "science" ], "content": "\n" }, { "name": "erlenmeyer-flask", "keywords": [ "science", "experiment", "lab", "flask", "chemistry", "solution" ], "content": "\n" }, { "name": "flower", "keywords": [ "nature", "plant", "tree", "flower", "petals", "bloom" ], "content": "\n" }, { "name": "galaxy-1", "keywords": [ "science", "space", "universe", "astronomy" ], "content": "\n" }, { "name": "galaxy-2", "keywords": [ "science", "space", "universe", "astronomy" ], "content": "\n" }, { "name": "gender-equality", "keywords": [], "content": "\n" }, { "name": "good-health-and-well-being", "keywords": [], "content": "\n" }, { "name": "industry-innovation-and-infrastructure", "keywords": [], "content": "\n" }, { "name": "leaf", "keywords": [ "nature", "environment", "leaf", "ecology", "plant", "plants", "eco" ], "content": "\n" }, { "name": "log", "keywords": [ "nature", "tree", "plant", "circle", "round", "log" ], "content": "\n" }, { "name": "no-poverty", "keywords": [], "content": "\n" }, { "name": "octopus", "keywords": [ "nature", "sealife", "animals" ], "content": "\n" }, { "name": "planet", "keywords": [ "science", "solar", "system", "ring", "planet", "saturn", "space", "astronomy", "astronomy" ], "content": "\n" }, { "name": "potted-flower-tulip", "keywords": [ "nature", "flower", "plant", "tree", "pot" ], "content": "\n" }, { "name": "quality-education", "keywords": [], "content": "\n" }, { "name": "rainbow", "keywords": [ "nature", "arch", "rain", "colorful", "rainbow", "curve", "half", "circle" ], "content": "\n" }, { "name": "recycle-1", "keywords": [ "nature", "sign", "environment", "protect", "save", "arrows" ], "content": "\n" }, { "name": "reduced-inequalities", "keywords": [], "content": "\n" }, { "name": "rose", "keywords": [ "nature", "flower", "rose", "plant", "tree" ], "content": "\n" }, { "name": "shell", "keywords": [ "nature", "sealife", "animals" ], "content": "\n" }, { "name": "shovel-rake", "keywords": [ "nature", "crops", "plants" ], "content": "\n" }, { "name": "sprout", "keywords": [], "content": "\n" }, { "name": "telescope", "keywords": [ "science", "experiment", "star", "gazing", "sky", "night", "space", "universe", "astronomy", "astronomy" ], "content": "\n" }, { "name": "test-tube", "keywords": [ "science", "experiment", "lab", "chemistry", "test", "tube", "solution" ], "content": "\n" }, { "name": "tidal-wave", "keywords": [ "nature", "ocean", "wave" ], "content": "\n" }, { "name": "tree-2", "keywords": [ "nature", "tree", "plant", "circle", "round", "park" ], "content": "\n" }, { "name": "tree-3", "keywords": [ "nature", "tree", "plant", "cloud", "shape", "park" ], "content": "\n" }, { "name": "volcano", "keywords": [ "nature", "eruption", "erupt", "mountain", "volcano", "lava", "magma", "explosion" ], "content": "\n" }, { "name": "windmill", "keywords": [], "content": "\n" }, { "name": "zero-hunger", "keywords": [], "content": "\n" } ], "phone": [ { "name": "airplane-disabled", "keywords": [ "server", "plane", "airplane", "disabled", "off", "wireless", "mode", "internet", "network" ], "content": "\n" }, { "name": "airplane-enabled", "keywords": [ "server", "plane", "airplane", "enabled", "on", "wireless", "mode", "internet", "network" ], "content": "\n" }, { "name": "back-camera-1", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "camera", "lenses" ], "content": "\n" }, { "name": "call-hang-up", "keywords": [ "phone", "telephone", "mobile", "device", "smartphone", "call", "hang", "up" ], "content": "\n" }, { "name": "cellular-network-4g", "keywords": [], "content": "\n" }, { "name": "cellular-network-5g", "keywords": [], "content": "\n" }, { "name": "cellular-network-lte", "keywords": [], "content": "\n" }, { "name": "contact-phonebook-2", "keywords": [], "content": "\n" }, { "name": "hang-up-1", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "telephone", "hang", "up" ], "content": "\n" }, { "name": "hang-up-2", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "telephone", "hang", "up" ], "content": "\n" }, { "name": "incoming-call", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "ringing", "incoming", "call" ], "content": "\n" }, { "name": "missed-call", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "missed", "call" ], "content": "\n" }, { "name": "notification-alarm-2", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "alert", "bell", "alarm" ], "content": "\n" }, { "name": "notification-application-1", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "alert", "box" ], "content": "\n" }, { "name": "notification-application-2", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "alert", "box" ], "content": "\n" }, { "name": "notification-message-alert", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "alert", "message", "text" ], "content": "\n" }, { "name": "outgoing-call", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "ringing", "outgoing", "call" ], "content": "\n" }, { "name": "phone", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone" ], "content": "\n" }, { "name": "phone-mobile-phone", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone" ], "content": "\n" }, { "name": "phone-qr", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "qr", "code", "scan" ], "content": "\n" }, { "name": "phone-ringing-1", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "ringing", "incoming", "call" ], "content": "\n" }, { "name": "phone-ringing-2", "keywords": [ "android", "phone", "mobile", "device", "smartphone", "iphone", "ringing" ], "content": "\n" }, { "name": "signal-full", "keywords": [ "phone", "mobile", "device", "signal", "wireless", "smartphone", "iphone", "bar", "bars", "full", "android" ], "content": "\n" }, { "name": "signal-low", "keywords": [ "phone", "mobile", "device", "signal", "wireless", "smartphone", "iphone", "bar", "low", "bars", "android" ], "content": "\n" }, { "name": "signal-medium", "keywords": [ "smartphone", "phone", "mobile", "device", "iphone", "signal", "medium", "wireless", "bar", "bars", "android" ], "content": "\n" }, { "name": "signal-none", "keywords": [ "phone", "mobile", "device", "signal", "wireless", "smartphone", "iphone", "bar", "bars", "no", "zero", "android" ], "content": "\n" } ], "programing": [ { "name": "application-add", "keywords": [ "application", "new", "add", "square" ], "content": "\n" }, { "name": "bracket", "keywords": [ "code", "angle", "programming", "file", "bracket" ], "content": "\n" }, { "name": "browser-add", "keywords": [ "app", "code", "apps", "add", "window", "plus" ], "content": "\n" }, { "name": "browser-block", "keywords": [ "block", "access", "denied", "window", "browser", "privacy", "remove" ], "content": "\n" }, { "name": "browser-build", "keywords": [ "build", "website", "development", "window", "code", "web", "backend", "browser", "dev" ], "content": "\n" }, { "name": "browser-check", "keywords": [ "checkmark", "pass", "window", "app", "code", "success", "check", "apps" ], "content": "\n" }, { "name": "browser-delete", "keywords": [ "app", "code", "apps", "fail", "delete", "window", "remove", "cross" ], "content": "\n" }, { "name": "browser-hash", "keywords": [ "window", "hash", "code", "internet", "language", "browser", "web", "tag" ], "content": "\n" }, { "name": "browser-lock", "keywords": [ "secure", "password", "window", "browser", "lock", "security", "login", "encryption" ], "content": "\n" }, { "name": "browser-multiple-window", "keywords": [ "app", "code", "apps", "two", "window", "cascade" ], "content": "\n" }, { "name": "browser-remove", "keywords": [ "app", "code", "apps", "subtract", "window", "minus" ], "content": "\n" }, { "name": "browser-website-1", "keywords": [ "app", "code", "apps", "window", "website", "web" ], "content": "\n" }, { "name": "bug", "keywords": [ "code", "bug", "security", "programming", "secure", "computer" ], "content": "\n" }, { "name": "bug-antivirus-debugging", "keywords": [ "code", "bug", "security", "programming", "secure", "computer", "antivirus", "block", "protection", "malware", "debugging" ], "content": "\n" }, { "name": "bug-antivirus-shield", "keywords": [ "code", "bug", "security", "programming", "secure", "computer", "antivirus", "shield", "protection", "malware" ], "content": "\n" }, { "name": "bug-virus-browser", "keywords": [ "bug", "browser", "file", "virus", "threat", "danger", "internet" ], "content": "\n" }, { "name": "bug-virus-document", "keywords": [ "bug", "document", "file", "virus", "threat", "danger" ], "content": "\n" }, { "name": "bug-virus-folder", "keywords": [ "bug", "document", "folder", "virus", "threat", "danger" ], "content": "\n" }, { "name": "cloud-add", "keywords": [ "cloud", "network", "internet", "add", "server", "plus" ], "content": "\n" }, { "name": "cloud-block", "keywords": [ "cloud", "network", "internet", "block", "server", "deny" ], "content": "\n" }, { "name": "cloud-check", "keywords": [ "cloud", "network", "internet", "check", "server", "approve" ], "content": "\n" }, { "name": "cloud-data-transfer", "keywords": [ "cloud", "data", "transfer", "internet", "server", "network" ], "content": "\n" }, { "name": "cloud-refresh", "keywords": [ "cloud", "network", "internet", "server", "refresh" ], "content": "\n" }, { "name": "cloud-share", "keywords": [ "cloud", "network", "internet", "server", "share" ], "content": "\n" }, { "name": "cloud-warning", "keywords": [ "cloud", "network", "internet", "server", "warning", "alert" ], "content": "\n" }, { "name": "cloud-wifi", "keywords": [ "cloud", "wifi", "internet", "server", "network" ], "content": "\n" }, { "name": "code-analysis", "keywords": [], "content": "\n" }, { "name": "code-monitor-1", "keywords": [ "code", "tags", "angle", "bracket", "monitor" ], "content": "\n" }, { "name": "code-monitor-2", "keywords": [ "code", "tags", "angle", "image", "ui", "ux", "design" ], "content": "\n" }, { "name": "css-three", "keywords": [ "language", "three", "code", "programming", "html", "css" ], "content": "\n" }, { "name": "curly-brackets", "keywords": [], "content": "\n" }, { "name": "file-code-1", "keywords": [ "code", "files", "angle", "programming", "file", "bracket" ], "content": "\n" }, { "name": "incognito-mode", "keywords": [ "internet", "safe", "mode", "browser" ], "content": "\n" }, { "name": "insert-cloud-video", "keywords": [], "content": "\n" }, { "name": "markdown-circle-programming", "keywords": [], "content": "\n" }, { "name": "markdown-document-programming", "keywords": [], "content": "\n" }, { "name": "module-puzzle-1", "keywords": [ "code", "puzzle", "module", "programming", "plugin", "piece" ], "content": "\n" }, { "name": "module-puzzle-3", "keywords": [ "code", "puzzle", "module", "programming", "plugin", "piece" ], "content": "\n" }, { "name": "module-three", "keywords": [ "code", "three", "module", "programming", "plugin" ], "content": "\n" }, { "name": "rss-square", "keywords": [ "wireless", "rss", "feed", "square", "transmit", "broadcast" ], "content": "\n" } ], "shipping": [ { "name": "box-sign", "keywords": [ "box", "package", "label", "delivery", "shipment", "shipping", "this", "way", "up", "arrow", "sign", "sticker" ], "content": "\n" }, { "name": "container", "keywords": [ "box", "package", "label", "delivery", "shipment", "shipping", "container" ], "content": "\n" }, { "name": "fragile", "keywords": [ "fragile", "shipping", "glass", "delivery", "wine", "crack", "shipment", "sign", "sticker" ], "content": "\n" }, { "name": "parachute-drop", "keywords": [ "package", "box", "fulfillment", "cart", "warehouse", "shipping", "delivery", "drop", "parachute" ], "content": "\n" }, { "name": "shipment-add", "keywords": [ "shipping", "parcel", "shipment", "add" ], "content": "\n" }, { "name": "shipment-check", "keywords": [ "shipping", "parcel", "shipment", "check", "approved" ], "content": "\n" }, { "name": "shipment-download", "keywords": [ "shipping", "parcel", "shipment", "download" ], "content": "\n" }, { "name": "shipment-remove", "keywords": [ "shipping", "parcel", "shipment", "remove", "subtract" ], "content": "\n" }, { "name": "shipment-upload", "keywords": [ "shipping", "parcel", "shipment", "upload" ], "content": "\n" }, { "name": "shipping-box-1", "keywords": [ "box", "package", "label", "delivery", "shipment", "shipping" ], "content": "\n" }, { "name": "shipping-truck", "keywords": [ "truck", "shipping", "delivery", "transfer" ], "content": "\n" }, { "name": "transfer-motorcycle", "keywords": [ "motorcycle", "shipping", "delivery", "courier", "transfer" ], "content": "\n" }, { "name": "transfer-van", "keywords": [ "van", "shipping", "delivery", "transfer" ], "content": "\n" }, { "name": "warehouse-1", "keywords": [ "delivery", "warehouse", "shipping", "fulfillment" ], "content": "\n" } ], "work_education": [ { "name": "book-reading", "keywords": [ "book", "reading", "learning" ], "content": "\n" }, { "name": "class-lesson", "keywords": [ "class", "lesson", "education", "teacher" ], "content": "\n" }, { "name": "collaborations-idea", "keywords": [ "collaborations", "idea", "work" ], "content": "\n" }, { "name": "definition-search-book", "keywords": [], "content": "\n" }, { "name": "dictionary-language-book", "keywords": [], "content": "\n" }, { "name": "global-learning", "keywords": [ "global", "learning", "education" ], "content": "\n" }, { "name": "graduation-cap", "keywords": [ "graduation", "cap", "education" ], "content": "\n" }, { "name": "group-meeting-call", "keywords": [ "group", "meeting", "call", "work" ], "content": "\n" }, { "name": "office-building-1", "keywords": [ "office", "building", "work" ], "content": "\n" }, { "name": "office-worker", "keywords": [ "office", "worker", "human", "resources" ], "content": "\n" }, { "name": "search-dollar", "keywords": [ "search", "pay", "product", "currency", "query", "magnifying", "cash", "business", "money", "glass" ], "content": "\n" }, { "name": "strategy-tasks", "keywords": [ "strategy", "tasks", "work" ], "content": "\n" }, { "name": "task-list", "keywords": [ "task", "list", "work" ], "content": "\n" }, { "name": "workspace-desk", "keywords": [ "workspace", "desk", "work" ], "content": "\n" } ] }
\ No newline at end of file
diff --git a/frontend/appflowy_flutter/integration_test/shared/editor_test_operations.dart b/frontend/appflowy_flutter/integration_test/shared/editor_test_operations.dart
index 33106c42d1..a92f6548bb 100644
--- a/frontend/appflowy_flutter/integration_test/shared/editor_test_operations.dart
+++ b/frontend/appflowy_flutter/integration_test/shared/editor_test_operations.dart
@@ -1,13 +1,9 @@
import 'dart:async';
import 'dart:ui';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/base/emoji/emoji_picker.dart';
import 'package:appflowy/plugins/base/emoji/emoji_skin_tone.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_add_button.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/header/cover_editor.dart';
@@ -15,8 +11,11 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/header/doc
import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emoji_icon_widget.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/upload_image_menu/widgets/embed_image_url_widget.dart';
import 'package:appflowy/plugins/inline_actions/widgets/inline_actions_handler.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -85,7 +84,7 @@ class EditorOperations {
final Finder button = !isInPicker
? find.text(LocaleKeys.document_plugins_cover_removeIcon.tr())
: find.descendant(
- of: find.byType(FlowyIconPicker),
+ of: find.byType(FlowyIconEmojiPicker),
matching: find.text(LocaleKeys.button_remove.tr()),
);
await tester.tapButton(button);
diff --git a/frontend/appflowy_flutter/integration_test/shared/workspace.dart b/frontend/appflowy_flutter/integration_test/shared/workspace.dart
index 4d20d88ce1..67506879d5 100644
--- a/frontend/appflowy_flutter/integration_test/shared/workspace.dart
+++ b/frontend/appflowy_flutter/integration_test/shared/workspace.dart
@@ -1,5 +1,5 @@
import 'package:appflowy/generated/locale_keys.g.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_actions.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
@@ -58,7 +58,7 @@ extension AppFlowyWorkspace on WidgetTester {
);
expect(iconButton, findsOneWidget);
await tapButton(iconButton);
- final iconPicker = find.byType(FlowyIconPicker);
+ final iconPicker = find.byType(FlowyIconEmojiPicker);
expect(iconPicker, findsOneWidget);
await tapButton(find.findTextInFlowyText(icon));
}
diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart
index 480b56f4f4..ccd663a5b3 100644
--- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart
+++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart
@@ -5,7 +5,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/mobile/presentation/home/mobile_home_setting_page.dart';
import 'package:appflowy/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart';
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/util/built_in_svgs.dart';
import 'package:appflowy/workspace/application/user/settings_user_bloc.dart';
@@ -133,6 +133,7 @@ class _MobileWorkspace extends StatelessWidget {
fontSize: 16.0,
enableEdit: false,
alignment: Alignment.centerLeft,
+ figmaLineHeight: 16.0,
onSelected: (result) => context.read().add(
UserWorkspaceEvent.updateWorkspaceIcon(
currentWorkspace.workspaceId,
diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart
index 9c79f5b20b..53d28387e9 100644
--- a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart
+++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart
@@ -144,6 +144,7 @@ class _WorkspaceMenuItem extends StatelessWidget {
enableEdit: false,
iconSize: 26,
fontSize: 16.0,
+ figmaLineHeight: 16.0,
workspace: workspace,
onSelected: (result) => context.read().add(
UserWorkspaceEvent.updateWorkspaceIcon(
diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/tab_bar.dart b/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/tab_bar.dart
index 37768e3e7b..35fb6ea067 100644
--- a/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/tab_bar.dart
+++ b/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/tab_bar.dart
@@ -68,17 +68,16 @@ class MobileNotificationTabBar extends StatelessWidget {
controller: tabController,
tabs: tabs.map((e) => Tab(text: e.tr)).toList(),
indicatorSize: TabBarIndicatorSize.label,
- indicatorColor: Theme.of(context).primaryColor,
isScrollable: true,
labelStyle: labelStyle,
labelColor: baseStyle?.color,
labelPadding: const EdgeInsets.symmetric(horizontal: 12.0),
unselectedLabelStyle: unselectedLabelStyle,
overlayColor: WidgetStateProperty.all(Colors.transparent),
- indicator: RoundUnderlineTabIndicator(
+ indicator: const RoundUnderlineTabIndicator(
width: 28.0,
borderSide: BorderSide(
- color: Theme.of(context).primaryColor,
+ color: Color(0xFF00C8FF),
width: 3,
),
),
diff --git a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker.dart b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker.dart
index bcdcf9816d..f2c9f53551 100644
--- a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker.dart
+++ b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker.dart
@@ -1,10 +1,9 @@
-import 'package:flutter/material.dart';
-
import 'package:appflowy/plugins/base/emoji/emoji_picker_header.dart';
-import 'package:appflowy/plugins/base/emoji/emoji_search_bar.dart';
import 'package:appflowy/plugins/base/emoji/emoji_skin_tone.dart';
+import 'package:appflowy/shared/icon_emoji_picker/emoji_search_bar.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
+import 'package:flutter/material.dart';
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
// use a global value to store the selected emoji to prevent reloading every time.
@@ -65,36 +64,43 @@ class _FlowyEmojiPickerState extends State {
perLine: widget.emojiPerLine,
),
onEmojiSelected: widget.onEmojiSelected,
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
headerBuilder: (context, category) {
return FlowyEmojiHeader(
category: category,
);
},
itemBuilder: (context, emojiId, emoji, callback) {
- return SizedBox(
- width: 36,
- height: 36,
+ final name = emojiData?.emojis[emojiId]?.name ?? '';
+ return SizedBox.square(
+ dimension: 36.0,
child: FlowyButton(
margin: EdgeInsets.zero,
radius: Corners.s8Border,
- text: FlowyText.emoji(
- emoji,
- fontSize: 24.0,
+ text: FlowyTooltip(
+ message: name,
+ child: FlowyText.emoji(
+ emoji,
+ fontSize: 24.0,
+ ),
),
onTap: () => callback(emojiId, emoji),
),
);
},
searchBarBuilder: (context, keyword, skinTone) {
- return FlowyEmojiSearchBar(
- emojiData: emojiData!,
- onKeywordChanged: (value) {
- keyword.value = value;
- },
- onSkinToneChanged: (value) {
- skinTone.value = value;
- },
- onRandomEmojiSelected: widget.onEmojiSelected,
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ child: FlowyEmojiSearchBar(
+ emojiData: emojiData!,
+ onKeywordChanged: (value) {
+ keyword.value = value;
+ },
+ onSkinToneChanged: (value) {
+ skinTone.value = value;
+ },
+ onRandomEmojiSelected: widget.onEmojiSelected,
+ ),
);
},
);
diff --git a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker_screen.dart b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker_screen.dart
index 85e2197cb7..ed9dccfcf9 100644
--- a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker_screen.dart
+++ b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_picker_screen.dart
@@ -1,5 +1,5 @@
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
import 'package:appflowy/plugins/base/icon/icon_picker_page.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_skin_tone.dart b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_skin_tone.dart
index 3add90773d..5206075769 100644
--- a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_skin_tone.dart
+++ b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_skin_tone.dart
@@ -2,7 +2,6 @@ import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart
deleted file mode 100644
index 08e63251e0..0000000000
--- a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker.dart
+++ /dev/null
@@ -1,111 +0,0 @@
-import 'package:appflowy/generated/locale_keys.g.dart';
-import 'package:appflowy/plugins/base/emoji/emoji_picker.dart';
-import 'package:appflowy_backend/protobuf/flowy-folder/icon.pbenum.dart';
-import 'package:appflowy_editor/appflowy_editor.dart';
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flutter/material.dart';
-
-extension ToProto on FlowyIconType {
- ViewIconTypePB toProto() {
- switch (this) {
- case FlowyIconType.emoji:
- return ViewIconTypePB.Emoji;
- case FlowyIconType.icon:
- return ViewIconTypePB.Icon;
- case FlowyIconType.custom:
- return ViewIconTypePB.Url;
- }
- }
-}
-
-enum FlowyIconType {
- emoji,
- icon,
- custom;
-}
-
-class EmojiPickerResult {
- factory EmojiPickerResult.none() =>
- const EmojiPickerResult(FlowyIconType.icon, '');
-
- factory EmojiPickerResult.emoji(String emoji) =>
- EmojiPickerResult(FlowyIconType.emoji, emoji);
-
- const EmojiPickerResult(
- this.type,
- this.emoji,
- );
-
- final FlowyIconType type;
- final String emoji;
-}
-
-class FlowyIconPicker extends StatelessWidget {
- const FlowyIconPicker({
- super.key,
- required this.onSelected,
- });
-
- final void Function(EmojiPickerResult result) onSelected;
-
- @override
- Widget build(BuildContext context) {
- return Padding(
- padding: const EdgeInsets.symmetric(horizontal: 8.0),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- const VSpace(8.0),
- Row(
- children: [
- FlowyText(LocaleKeys.newSettings_workplace_chooseAnIcon.tr()),
- const Spacer(),
- _RemoveIconButton(
- onTap: () => onSelected(EmojiPickerResult.none()),
- ),
- ],
- ),
- const VSpace(12.0),
- const Divider(height: 0.5),
- Expanded(
- child: FlowyEmojiPicker(
- emojiPerLine: _getEmojiPerLine(context),
- onEmojiSelected: (_, emoji) =>
- onSelected(EmojiPickerResult.emoji(emoji)),
- ),
- ),
- ],
- ),
- );
- }
-
- int _getEmojiPerLine(BuildContext context) {
- if (PlatformExtension.isDesktopOrWeb) {
- return 9;
- }
- final width = MediaQuery.of(context).size.width;
- return width ~/ 40.0; // the size of the emoji
- }
-}
-
-class _RemoveIconButton extends StatelessWidget {
- const _RemoveIconButton({required this.onTap});
-
- final VoidCallback onTap;
-
- @override
- Widget build(BuildContext context) {
- return SizedBox(
- height: 24,
- child: FlowyButton(
- onTap: onTap,
- useIntrinsicWidth: true,
- text: FlowyText.regular(
- LocaleKeys.button_remove.tr(),
- color: Theme.of(context).hintColor,
- ),
- ),
- );
- }
-}
diff --git a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart
index 15cc8c59e0..6977141956 100644
--- a/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart
+++ b/frontend/appflowy_flutter/lib/plugins/base/icon/icon_picker_page.dart
@@ -1,9 +1,8 @@
-import 'package:flutter/material.dart';
-
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/presentation/base/app_bar/app_bar.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter/material.dart';
class IconPickerPage extends StatelessWidget {
const IconPickerPage({
@@ -22,7 +21,7 @@ class IconPickerPage extends StatelessWidget {
titleText: title ?? LocaleKeys.titleBar_pageIcon.tr(),
),
body: SafeArea(
- child: FlowyIconPicker(onSelected: onSelected),
+ child: FlowyIconEmojiPicker(onSelectedEmoji: onSelected),
),
);
}
diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart
index c2e8273fd5..7550076726 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart
@@ -24,7 +24,6 @@ import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/widget/error_page.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart' hide Card;
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart
index 4504563a97..b74f83cebc 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart
@@ -9,7 +9,6 @@ import 'package:appflowy_board/appflowy_board.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart
index acc6db2f0f..6bba024eb0 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart
@@ -17,7 +17,6 @@ import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_event_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_event_editor.dart
index 10f078c805..dfbf0d6bc0 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_event_editor.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_event_editor.dart
@@ -21,7 +21,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class CalendarEventEditor extends StatelessWidget {
diff --git a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart
index 82c43845b6..746305264b 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart
@@ -20,7 +20,6 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart
index 453247a8cb..ebf655552c 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart
@@ -13,7 +13,6 @@ import 'package:appflowy_backend/protobuf/flowy-database2/number_entities.pb.dar
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/text_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/text_card_cell.dart
index b86ff495cc..36d4f24142 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/text_card_cell.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/card_cell_skeleton/text_card_cell.dart
@@ -6,7 +6,6 @@ import 'package:appflowy/plugins/database/application/database_controller.dart';
import 'package:appflowy/plugins/database/application/cell/bloc/text_cell_bloc.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_date_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_date_cell.dart
index 537207c12c..5f30aff36e 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_date_cell.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_grid/desktop_grid_date_cell.dart
@@ -7,7 +7,6 @@ import 'package:appflowy/plugins/database/widgets/cell_editor/date_editor.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/widgets.dart';
import '../editable_cell_skeleton/date.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_checklist_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_checklist_cell.dart
index 39804c6851..b870040660 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_checklist_cell.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_checklist_cell.dart
@@ -8,7 +8,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_date_cell.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_date_cell.dart
index 071ed0ab84..94e0159a02 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_date_cell.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell/desktop_row_detail/desktop_row_detail_date_cell.dart
@@ -7,7 +7,6 @@ import 'package:appflowy/plugins/database/widgets/cell_editor/date_editor.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
class DesktopRowDetailDateCellSkin extends IEditableDateCellSkin {
diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart
index dc1b9435e8..22dc9c3b47 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart
@@ -13,7 +13,6 @@ import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/em
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart
index 430f817095..bdc1812926 100644
--- a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart
@@ -12,7 +12,6 @@ import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/database_document/presentation/database_document_title.dart b/frontend/appflowy_flutter/lib/plugins/database_document/presentation/database_document_title.dart
index 37905ac88b..8a71e26efa 100644
--- a/frontend/appflowy_flutter/lib/plugins/database_document/presentation/database_document_title.dart
+++ b/frontend/appflowy_flutter/lib/plugins/database_document/presentation/database_document_title.dart
@@ -15,7 +15,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart
index 1e96e5648b..42d05c0f9e 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/document_collaborators.dart
@@ -5,7 +5,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:avatar_stack/avatar_stack.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:string_validator/string_validator.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart
index 266529b360..9723158be5 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/align_toolbar_item/align_toolbar_item.dart
@@ -4,7 +4,6 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
const String leftAlignmentKey = 'left';
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart
index db6231a70a..a487634a93 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/emoji_picker_button.dart
@@ -1,5 +1,5 @@
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/block_menu/block_menu_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/block_menu/block_menu_button.dart
index 120343a277..735b6b15df 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/block_menu/block_menu_button.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/block_menu/block_menu_button.dart
@@ -1,6 +1,5 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
class MenuBlockButton extends StatelessWidget {
diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart
index b0bafb1f63..21565493c1 100644
--- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart
+++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart
@@ -1,13 +1,10 @@
import 'dart:io';
-import 'package:flutter/material.dart';
-
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart';
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
import 'package:appflowy/plugins/base/emoji/emoji_picker_screen.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
import 'package:appflowy/plugins/document/application/document_bloc.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/header/desktop_cover.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/header/emoji_icon_widget.dart';
@@ -17,6 +14,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/image/uplo
import 'package:appflowy/plugins/document/presentation/editor_plugins/migration/editor_migration.dart';
import 'package:appflowy/plugins/document/presentation/editor_style.dart';
import 'package:appflowy/shared/appflowy_network_image.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/application/view/view_listener.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
@@ -25,6 +23,7 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart';
+import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:string_validator/string_validator.dart';
@@ -352,11 +351,12 @@ class _DocumentHeaderToolbarState extends State {
offset: const Offset(0, 8),
direction: PopoverDirection.bottomWithCenterAligned,
constraints: BoxConstraints.loose(const Size(360, 380)),
+ margin: EdgeInsets.zero,
child: child,
popupBuilder: (BuildContext popoverContext) {
isPopoverOpen = true;
- return FlowyIconPicker(
- onSelected: (result) {
+ return FlowyIconEmojiPicker(
+ onSelectedEmoji: (result) {
widget.onIconOrCoverChanged(icon: result.emoji);
_popoverController.close();
},
@@ -725,10 +725,11 @@ class _DocumentIconState extends State {
controller: _popoverController,
offset: const Offset(0, 8),
constraints: BoxConstraints.loose(const Size(360, 380)),
+ margin: EdgeInsets.zero,
child: child,
popupBuilder: (BuildContext popoverContext) {
- return FlowyIconPicker(
- onSelected: (result) {
+ return FlowyIconEmojiPicker(
+ onSelectedEmoji: (result) {
widget.onChangeIcon(result.emoji);
_popoverController.close();
},
diff --git a/frontend/appflowy_flutter/lib/plugins/shared/share/publish_tab.dart b/frontend/appflowy_flutter/lib/plugins/shared/share/publish_tab.dart
index a1baf32e30..87610b916b 100644
--- a/frontend/appflowy_flutter/lib/plugins/shared/share/publish_tab.dart
+++ b/frontend/appflowy_flutter/lib/plugins/shared/share/publish_tab.dart
@@ -15,7 +15,6 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_search_bar.dart b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/emoji_search_bar.dart
similarity index 98%
rename from frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_search_bar.dart
rename to frontend/appflowy_flutter/lib/shared/icon_emoji_picker/emoji_search_bar.dart
index c6cec89ecc..57dba3c93e 100644
--- a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_search_bar.dart
+++ b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/emoji_search_bar.dart
@@ -4,7 +4,6 @@ import 'package:appflowy/plugins/base/emoji/emoji_skin_tone.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
@@ -142,6 +141,7 @@ class _SearchTextFieldState extends State<_SearchTextField> {
fontWeight: FontWeight.w400,
color: Theme.of(context).hintColor,
),
+ enableBorderColor: const Color(0x1E171717),
controller: controller,
onChanged: widget.onKeywordChanged,
prefixIcon: const Padding(
diff --git a/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart
new file mode 100644
index 0000000000..e91a6a3cae
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart
@@ -0,0 +1,180 @@
+import 'package:appflowy/generated/locale_keys.g.dart';
+import 'package:appflowy/plugins/base/emoji/emoji_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
+import 'package:appflowy_backend/protobuf/flowy-folder/icon.pbenum.dart';
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flowy_infra_ui/flowy_infra_ui.dart';
+import 'package:flutter/material.dart' hide Icon;
+
+import 'icon.dart';
+
+extension ToProto on FlowyIconType {
+ ViewIconTypePB toProto() {
+ switch (this) {
+ case FlowyIconType.emoji:
+ return ViewIconTypePB.Emoji;
+ case FlowyIconType.icon:
+ return ViewIconTypePB.Icon;
+ case FlowyIconType.custom:
+ return ViewIconTypePB.Url;
+ }
+ }
+}
+
+enum FlowyIconType {
+ emoji,
+ icon,
+ custom;
+}
+
+class EmojiPickerResult {
+ factory EmojiPickerResult.none() =>
+ const EmojiPickerResult(FlowyIconType.icon, '');
+
+ factory EmojiPickerResult.emoji(String emoji) =>
+ EmojiPickerResult(FlowyIconType.emoji, emoji);
+
+ const EmojiPickerResult(
+ this.type,
+ this.emoji,
+ );
+
+ final FlowyIconType type;
+ final String emoji;
+}
+
+class FlowyIconEmojiPicker extends StatefulWidget {
+ const FlowyIconEmojiPicker({
+ super.key,
+ this.onSelectedEmoji,
+ this.onSelectedIcon,
+ this.tabs = const [PickerTabType.emoji],
+ });
+
+ final void Function(EmojiPickerResult result)? onSelectedEmoji;
+ final void Function(IconGroup? group, Icon? icon, String? color)?
+ onSelectedIcon;
+ final List tabs;
+
+ @override
+ State createState() => _FlowyIconEmojiPickerState();
+}
+
+class _FlowyIconEmojiPickerState extends State
+ with SingleTickerProviderStateMixin {
+ late final controller = TabController(
+ length: widget.tabs.length,
+ vsync: this,
+ );
+ int currentIndex = 0;
+
+ @override
+ void dispose() {
+ controller.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ height: 46,
+ padding: const EdgeInsets.only(left: 4.0, right: 12.0),
+ child: Row(
+ children: [
+ Expanded(
+ child: PickerTab(
+ controller: controller,
+ tabs: widget.tabs,
+ onTap: (index) => currentIndex = index,
+ ),
+ ),
+ _RemoveIconButton(
+ onTap: () {
+ final currentTab = widget.tabs[currentIndex];
+ if (currentTab == PickerTabType.emoji) {
+ widget.onSelectedEmoji?.call(
+ EmojiPickerResult.none(),
+ );
+ } else {
+ widget.onSelectedIcon?.call(null, null, null);
+ }
+ },
+ ),
+ ],
+ ),
+ ),
+ const FlowyDivider(),
+ Expanded(
+ child: TabBarView(
+ controller: controller,
+ children: widget.tabs.map((tab) {
+ switch (tab) {
+ case PickerTabType.emoji:
+ return _buildEmojiPicker();
+ case PickerTabType.icon:
+ return _buildIconPicker();
+ }
+ }).toList(),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget _buildEmojiPicker() {
+ return FlowyEmojiPicker(
+ emojiPerLine: _getEmojiPerLine(context),
+ onEmojiSelected: (_, emoji) => widget.onSelectedEmoji?.call(
+ EmojiPickerResult.emoji(emoji),
+ ),
+ );
+ }
+
+ int _getEmojiPerLine(BuildContext context) {
+ if (PlatformExtension.isDesktopOrWeb) {
+ return 9;
+ }
+ final width = MediaQuery.of(context).size.width;
+ return width ~/ 40.0; // the size of the emoji
+ }
+
+ Widget _buildIconPicker() {
+ return Expanded(
+ child: FlowyIconPicker(
+ onSelectedIcon: (iconGroup, icon, color) {
+ debugPrint('icon: ${icon.toJson()}, color: $color');
+ widget.onSelectedIcon?.call(iconGroup, icon, color);
+ },
+ ),
+ );
+ }
+}
+
+class _RemoveIconButton extends StatelessWidget {
+ const _RemoveIconButton({required this.onTap});
+
+ final VoidCallback onTap;
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ height: 32,
+ child: FlowyButton(
+ onTap: onTap,
+ useIntrinsicWidth: true,
+ text: FlowyText(
+ fontSize: 14.0,
+ figmaLineHeight: 16.0,
+ fontWeight: FontWeight.w500,
+ LocaleKeys.button_remove.tr(),
+ color: Theme.of(context).hintColor,
+ ),
+ ),
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon.dart b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon.dart
new file mode 100644
index 0000000000..d1f3dd9d42
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon.dart
@@ -0,0 +1,62 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'icon.g.dart';
+
+@JsonSerializable()
+class IconGroup {
+ factory IconGroup.fromJson(Map json) =>
+ _$IconGroupFromJson(json);
+
+ factory IconGroup.fromMapEntry(MapEntry entry) =>
+ IconGroup.fromJson({
+ 'name': entry.key,
+ 'icons': entry.value,
+ });
+
+ IconGroup({
+ required this.name,
+ required this.icons,
+ });
+
+ final String name;
+ final List icons;
+
+ String get displayName => name.replaceAll('_', ' ');
+
+ IconGroup filter(String keyword) {
+ final filteredIcons = icons
+ .where(
+ (icon) => icon.keywords.any((k) => k.contains(keyword.toLowerCase())),
+ )
+ .toList();
+ return IconGroup(name: name, icons: filteredIcons);
+ }
+
+ String? getSvgContent(String iconName) {
+ final icon = icons.firstWhere(
+ (icon) => icon.name == iconName,
+ );
+ return icon.content;
+ }
+
+ Map toJson() => _$IconGroupToJson(this);
+}
+
+@JsonSerializable()
+class Icon {
+ factory Icon.fromJson(Map json) => _$IconFromJson(json);
+
+ Icon({
+ required this.name,
+ required this.keywords,
+ required this.content,
+ });
+
+ final String name;
+ final List keywords;
+ final String content;
+
+ String get displayName => name.replaceAll('-', ' ');
+
+ Map toJson() => _$IconToJson(this);
+}
diff --git a/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_color_picker.dart b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_color_picker.dart
new file mode 100644
index 0000000000..b4221ff42a
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_color_picker.dart
@@ -0,0 +1,44 @@
+import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart';
+import 'package:flowy_infra_ui/style_widget/hover.dart';
+import 'package:flutter/material.dart';
+
+class IconColorPicker extends StatelessWidget {
+ const IconColorPicker({
+ super.key,
+ required this.onSelected,
+ });
+
+ final void Function(String color) onSelected;
+
+ @override
+ Widget build(BuildContext context) {
+ return GridView.count(
+ shrinkWrap: true,
+ crossAxisCount: 6,
+ mainAxisSpacing: 4.0,
+ children: builtInSpaceColors.map((color) {
+ return FlowyHover(
+ style: HoverStyle(borderRadius: BorderRadius.circular(8.0)),
+ child: GestureDetector(
+ onTap: () => onSelected(color),
+ child: Container(
+ width: 34,
+ height: 34,
+ padding: const EdgeInsets.all(5.0),
+ child: Container(
+ clipBehavior: Clip.antiAlias,
+ decoration: ShapeDecoration(
+ color: Color(int.parse(color)),
+ shape: RoundedRectangleBorder(
+ side: const BorderSide(color: Color(0x2D333333)),
+ borderRadius: BorderRadius.circular(8),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }).toList(),
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_picker.dart b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_picker.dart
new file mode 100644
index 0000000000..f9d5cbf9b5
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_picker.dart
@@ -0,0 +1,271 @@
+import 'dart:convert';
+import 'dart:math';
+
+import 'package:appflowy/generated/flowy_svgs.g.dart';
+import 'package:appflowy/shared/icon_emoji_picker/icon.dart';
+import 'package:appflowy/shared/icon_emoji_picker/icon_search_bar.dart';
+import 'package:appflowy/util/debounce.dart';
+import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart';
+import 'package:appflowy_backend/log.dart';
+import 'package:appflowy_popover/appflowy_popover.dart';
+import 'package:collection/collection.dart';
+import 'package:flowy_infra_ui/flowy_infra_ui.dart';
+import 'package:flutter/material.dart' hide Icon;
+import 'package:flutter/services.dart';
+
+import 'icon_color_picker.dart';
+
+// cache the icon groups to avoid loading them multiple times
+List? kIconGroups;
+
+extension IconGroupFilter on List {
+ String? findSvgContent(String key) {
+ final values = key.split('/');
+ if (values.length != 2) {
+ return null;
+ }
+ final groupName = values[0];
+ final iconName = values[1];
+ final svgString = kIconGroups
+ ?.firstWhereOrNull(
+ (group) => group.name == groupName,
+ )
+ ?.icons
+ .firstWhereOrNull(
+ (icon) => icon.name == iconName,
+ )
+ ?.content;
+ return svgString;
+ }
+
+ (IconGroup, Icon) randomIcon() {
+ final random = Random();
+ final group = this[random.nextInt(length)];
+ final icon = group.icons[random.nextInt(group.icons.length)];
+ return (group, icon);
+ }
+}
+
+Future> loadIconGroups() async {
+ if (kIconGroups != null) {
+ return kIconGroups!;
+ }
+
+ final stopwatch = Stopwatch()..start();
+ final jsonString = await rootBundle.loadString('assets/icons/icons.json');
+ try {
+ final json = jsonDecode(jsonString) as Map;
+ final iconGroups = json.entries.map(IconGroup.fromMapEntry).toList();
+ kIconGroups = iconGroups;
+ return iconGroups;
+ } catch (e) {
+ Log.error('Failed to decode icons.json', e);
+ return [];
+ } finally {
+ stopwatch.stop();
+ Log.info('Loaded icon groups in ${stopwatch.elapsedMilliseconds}ms');
+ }
+}
+
+class FlowyIconPicker extends StatefulWidget {
+ const FlowyIconPicker({
+ super.key,
+ required this.onSelectedIcon,
+ });
+
+ final void Function(IconGroup group, Icon icon, String color) onSelectedIcon;
+
+ @override
+ State createState() => _FlowyIconPickerState();
+}
+
+class _FlowyIconPickerState extends State {
+ late final Future> iconGroups;
+ final ValueNotifier keyword = ValueNotifier('');
+ final debounce = Debounce(duration: const Duration(milliseconds: 150));
+
+ @override
+ void initState() {
+ super.initState();
+
+ iconGroups = loadIconGroups();
+ }
+
+ @override
+ void dispose() {
+ keyword.dispose();
+ debounce.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ child: IconSearchBar(
+ onRandomTap: () {
+ final value = kIconGroups?.randomIcon();
+ if (value == null) {
+ return;
+ }
+ final color = generateRandomSpaceColor();
+ widget.onSelectedIcon(value.$1, value.$2, color);
+ },
+ onKeywordChanged: (keyword) => {
+ debounce.call(() {
+ this.keyword.value = keyword;
+ }),
+ },
+ ),
+ ),
+ Expanded(
+ child: kIconGroups != null
+ ? _buildIcons(kIconGroups!)
+ : FutureBuilder(
+ future: iconGroups,
+ builder: (context, snapshot) {
+ if (snapshot.connectionState != ConnectionState.done) {
+ return const Center(
+ child: SizedBox.square(
+ dimension: 24.0,
+ child: CircularProgressIndicator(
+ strokeWidth: 2.0,
+ ),
+ ),
+ );
+ }
+ final iconGroups = snapshot.data as List;
+ return _buildIcons(iconGroups);
+ },
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget _buildIcons(List iconGroups) {
+ return ValueListenableBuilder(
+ valueListenable: keyword,
+ builder: (_, keyword, __) {
+ if (keyword.isNotEmpty) {
+ final filteredIconGroups = iconGroups
+ .map((iconGroup) => iconGroup.filter(keyword))
+ .where((iconGroup) => iconGroup.icons.isNotEmpty)
+ .toList();
+ return IconPicker(
+ iconGroups: filteredIconGroups,
+ onSelectedIcon: widget.onSelectedIcon,
+ );
+ }
+ return IconPicker(
+ iconGroups: iconGroups,
+ onSelectedIcon: widget.onSelectedIcon,
+ );
+ },
+ );
+ }
+}
+
+class IconPicker extends StatefulWidget {
+ const IconPicker({
+ super.key,
+ required this.onSelectedIcon,
+ required this.iconGroups,
+ });
+
+ final List iconGroups;
+ final void Function(IconGroup group, Icon icon, String color) onSelectedIcon;
+
+ @override
+ State createState() => _IconPickerState();
+}
+
+class _IconPickerState extends State {
+ final mutex = PopoverMutex();
+
+ @override
+ Widget build(BuildContext context) {
+ return ListView.builder(
+ itemCount: widget.iconGroups.length,
+ padding: const EdgeInsets.symmetric(horizontal: 16.0),
+ itemBuilder: (context, index) {
+ final iconGroup = widget.iconGroups[index];
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ FlowyText(
+ iconGroup.displayName,
+ fontSize: 12,
+ figmaLineHeight: 18.0,
+ color: const Color(0x80171717),
+ ),
+ const VSpace(4.0),
+ Wrap(
+ children: iconGroup.icons.map(
+ (icon) {
+ return _Icon(
+ icon: icon,
+ mutex: mutex,
+ onSelectedColor: (context, color) {
+ widget.onSelectedIcon(iconGroup, icon, color);
+ PopoverContainer.of(context).close();
+ },
+ );
+ },
+ ).toList(),
+ ),
+ const VSpace(12.0),
+ ],
+ );
+ },
+ );
+ }
+}
+
+class _Icon extends StatelessWidget {
+ const _Icon({
+ required this.icon,
+ required this.mutex,
+ required this.onSelectedColor,
+ });
+
+ final Icon icon;
+ final PopoverMutex mutex;
+ final void Function(BuildContext context, String color) onSelectedColor;
+
+ @override
+ Widget build(BuildContext context) {
+ return AppFlowyPopover(
+ direction: PopoverDirection.bottomWithCenterAligned,
+ offset: const Offset(0, 6),
+ mutex: mutex,
+ child: FlowyTooltip(
+ message: icon.displayName,
+ preferBelow: false,
+ child: FlowyButton(
+ useIntrinsicWidth: true,
+ margin: const EdgeInsets.all(8.0),
+ text: Center(
+ child: FlowySvg.string(
+ icon.content,
+ size: const Size.square(20),
+ color: const Color(0xFF171717),
+ opacity: 0.7,
+ ),
+ ),
+ ),
+ ),
+ popupBuilder: (context) {
+ return Container(
+ padding: const EdgeInsets.all(6.0),
+ child: IconColorPicker(
+ onSelected: (color) => onSelectedColor(context, color),
+ ),
+ );
+ },
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_search_bar.dart b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_search_bar.dart
new file mode 100644
index 0000000000..06a3566d21
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/icon_search_bar.dart
@@ -0,0 +1,162 @@
+import 'package:appflowy/generated/flowy_svgs.g.dart';
+import 'package:appflowy/generated/locale_keys.g.dart';
+import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:easy_localization/easy_localization.dart';
+import 'package:flowy_infra_ui/flowy_infra_ui.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
+
+typedef IconKeywordChangedCallback = void Function(String keyword);
+typedef EmojiSkinToneChanged = void Function(EmojiSkinTone skinTone);
+
+class IconSearchBar extends StatefulWidget {
+ const IconSearchBar({
+ super.key,
+ required this.onRandomTap,
+ required this.onKeywordChanged,
+ });
+
+ final VoidCallback onRandomTap;
+ final IconKeywordChangedCallback onKeywordChanged;
+
+ @override
+ State createState() => _IconSearchBarState();
+}
+
+class _IconSearchBarState extends State {
+ final TextEditingController controller = TextEditingController();
+
+ @override
+ void dispose() {
+ controller.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: 12.0,
+ horizontal: PlatformExtension.isDesktopOrWeb ? 0.0 : 8.0,
+ ),
+ child: Row(
+ children: [
+ Expanded(
+ child: _SearchTextField(
+ onKeywordChanged: widget.onKeywordChanged,
+ ),
+ ),
+ const HSpace(8.0),
+ _RandomIconButton(
+ onRandomTap: widget.onRandomTap,
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class _RandomIconButton extends StatelessWidget {
+ const _RandomIconButton({
+ required this.onRandomTap,
+ });
+
+ final VoidCallback onRandomTap;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: 36,
+ height: 36,
+ decoration: ShapeDecoration(
+ shape: RoundedRectangleBorder(
+ side: const BorderSide(color: Color(0x1E171717)),
+ borderRadius: BorderRadius.circular(8),
+ ),
+ ),
+ child: FlowyTooltip(
+ message: LocaleKeys.emoji_random.tr(),
+ child: FlowyButton(
+ useIntrinsicWidth: true,
+ text: const FlowySvg(
+ FlowySvgs.icon_shuffle_s,
+ ),
+ onTap: onRandomTap,
+ ),
+ ),
+ );
+ }
+}
+
+class _SearchTextField extends StatefulWidget {
+ const _SearchTextField({
+ required this.onKeywordChanged,
+ });
+
+ final IconKeywordChangedCallback onKeywordChanged;
+
+ @override
+ State<_SearchTextField> createState() => _SearchTextFieldState();
+}
+
+class _SearchTextFieldState extends State<_SearchTextField> {
+ final TextEditingController controller = TextEditingController();
+ final FocusNode focusNode = FocusNode();
+
+ @override
+ void dispose() {
+ controller.dispose();
+ focusNode.dispose();
+
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ height: 36.0,
+ child: FlowyTextField(
+ focusNode: focusNode,
+ hintText: LocaleKeys.search_label.tr(),
+ hintStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
+ fontSize: 14.0,
+ fontWeight: FontWeight.w400,
+ color: Theme.of(context).hintColor,
+ ),
+ enableBorderColor: const Color(0x1E171717),
+ controller: controller,
+ onChanged: widget.onKeywordChanged,
+ prefixIcon: const Padding(
+ padding: EdgeInsets.only(
+ left: 14.0,
+ right: 8.0,
+ ),
+ child: FlowySvg(
+ FlowySvgs.search_s,
+ ),
+ ),
+ prefixIconConstraints: const BoxConstraints(
+ maxHeight: 20.0,
+ ),
+ suffixIcon: Padding(
+ padding: const EdgeInsets.all(4.0),
+ child: FlowyButton(
+ text: const FlowySvg(
+ FlowySvgs.m_app_bar_close_s,
+ ),
+ margin: EdgeInsets.zero,
+ useIntrinsicWidth: true,
+ onTap: () {
+ if (controller.text.isNotEmpty) {
+ controller.clear();
+ widget.onKeywordChanged('');
+ } else {
+ focusNode.unfocus();
+ }
+ },
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/tab.dart b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/tab.dart
new file mode 100644
index 0000000000..56a363132c
--- /dev/null
+++ b/frontend/appflowy_flutter/lib/shared/icon_emoji_picker/tab.dart
@@ -0,0 +1,67 @@
+import 'package:appflowy/mobile/presentation/home/tab/_round_underline_tab_indicator.dart';
+import 'package:flutter/material.dart';
+
+enum PickerTabType {
+ emoji,
+ icon;
+
+ String get tr {
+ switch (this) {
+ case PickerTabType.emoji:
+ return 'Emojis';
+ case PickerTabType.icon:
+ return 'Icons';
+ }
+ }
+}
+
+class PickerTab extends StatelessWidget {
+ const PickerTab({
+ super.key,
+ this.onTap,
+ required this.controller,
+ required this.tabs,
+ });
+
+ final List tabs;
+ final TabController controller;
+ final ValueChanged? onTap;
+
+ @override
+ Widget build(BuildContext context) {
+ final baseStyle = Theme.of(context).textTheme.bodyMedium;
+ final style = baseStyle?.copyWith(
+ fontWeight: FontWeight.w500,
+ fontSize: 14.0,
+ height: 16.0 / 14.0,
+ );
+ return TabBar(
+ controller: controller,
+ indicatorSize: TabBarIndicatorSize.label,
+ indicatorColor: Theme.of(context).colorScheme.primary,
+ isScrollable: true,
+ labelStyle: style,
+ labelColor: baseStyle?.color,
+ labelPadding: const EdgeInsets.symmetric(horizontal: 12.0),
+ unselectedLabelStyle: style?.copyWith(
+ color: Theme.of(context).hintColor,
+ ),
+ overlayColor: WidgetStateProperty.all(Colors.transparent),
+ indicator: RoundUnderlineTabIndicator(
+ width: 34.0,
+ borderSide: BorderSide(
+ color: Theme.of(context).colorScheme.primary,
+ width: 3,
+ ),
+ ),
+ onTap: onTap,
+ tabs: tabs
+ .map(
+ (tab) => Tab(
+ text: tab.tr,
+ ),
+ )
+ .toList(),
+ );
+ }
+}
diff --git a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart
index e8b52ee4be..d879f07578 100644
--- a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart
+++ b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart
@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:appflowy/mobile/application/mobile_router.dart';
import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
import 'package:appflowy/shared/feature_flags.dart';
+import 'package:appflowy/shared/icon_emoji_picker/icon_picker.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/user_settings_service.dart';
import 'package:appflowy/workspace/application/action_navigation/action_navigation_bloc.dart';
@@ -41,6 +42,8 @@ class InitAppWidgetTask extends LaunchTask {
await NotificationService.initialize();
+ await loadIconGroups();
+
final widget = context.getIt().create(context.config);
final appearanceSetting =
await UserSettingsBackendService().getAppearanceSetting();
diff --git a/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart
index 9d79ca8550..fb96d53d0a 100644
--- a/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart
+++ b/frontend/appflowy_flutter/lib/workspace/application/sidebar/space/space_bloc.dart
@@ -183,6 +183,21 @@ class SpaceBloc extends Bloc {
} catch (e) {
Log.error('Failed to migrating cover: $e');
}
+ } else if (icon == null) {
+ try {
+ final extra = space.extra;
+ final Map current = extra.isNotEmpty == true
+ ? jsonDecode(extra)
+ : {};
+ current.remove(ViewExtKeys.spaceIconKey);
+ current.remove(ViewExtKeys.spaceIconColorKey);
+ await ViewBackendService.updateView(
+ viewId: space.id,
+ extra: jsonEncode(current),
+ );
+ } catch (e) {
+ Log.error('Failed to migrating cover: $e');
+ }
}
if (permission != null) {
@@ -691,8 +706,10 @@ class SpaceEvent with _$SpaceEvent {
required bool createNewPageByDefault,
}) = _Create;
const factory SpaceEvent.rename(ViewPB space, String name) = _Rename;
- const factory SpaceEvent.changeIcon(String icon, String iconColor) =
- _ChangeIcon;
+ const factory SpaceEvent.changeIcon(
+ String? icon,
+ String? iconColor,
+ ) = _ChangeIcon;
const factory SpaceEvent.duplicate() = _Duplicate;
const factory SpaceEvent.update({
String? name,
diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart
index 0d6c8f7826..3be0636d07 100644
--- a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart
+++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart
@@ -9,10 +9,12 @@ import 'package:appflowy/plugins/database/grid/presentation/grid_page.dart';
import 'package:appflowy/plugins/database/grid/presentation/mobile_grid_page.dart';
import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart';
import 'package:appflowy/plugins/document/document.dart';
+import 'package:appflowy/shared/icon_emoji_picker/icon_picker.dart';
import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
+import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
class PluginArgumentKeys {
@@ -134,7 +136,7 @@ extension ViewExtension on ViewPB {
}
}
- FlowySvg? get spaceIconSvg {
+ FlowySvg? buildSpaceIconSvg(BuildContext context, {Size? size}) {
try {
final ext = jsonDecode(extra);
final icon = ext[ViewExtKeys.spaceIconKey];
@@ -142,10 +144,36 @@ extension ViewExtension on ViewPB {
if (icon == null || color == null) {
return null;
}
- return FlowySvg(
- FlowySvgData('assets/flowy_icons/16x/$icon.svg'),
- color: Color(int.parse(color)),
- blendMode: BlendMode.srcOut,
+ // before version 0.6.7
+ if (icon.contains('space_icon')) {
+ return FlowySvg(
+ FlowySvgData('assets/flowy_icons/16x/$icon.svg'),
+ color: Theme.of(context).colorScheme.surface,
+ );
+ }
+
+ final values = icon.split('/');
+ if (values.length != 2) {
+ return null;
+ }
+ final groupName = values[0];
+ final iconName = values[1];
+ final svgString = kIconGroups
+ ?.firstWhereOrNull(
+ (group) => group.name == groupName,
+ )
+ ?.icons
+ .firstWhereOrNull(
+ (icon) => icon.name == iconName,
+ )
+ ?.content;
+ if (svgString == null) {
+ return null;
+ }
+ return FlowySvg.string(
+ svgString,
+ color: Theme.of(context).colorScheme.surface,
+ size: size,
);
} catch (e) {
return null;
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart
index de293d894d..3bd2ffe67f 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_pin_action.dart
@@ -5,7 +5,6 @@ import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart
index 03a69e0865..d16c11b963 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart
@@ -11,7 +11,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart
index 2f6da2db3b..db631d2b34 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart
@@ -15,7 +15,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hotkey_manager/hotkey_manager.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/create_space_popup.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/create_space_popup.dart
index d46982f377..d901513d16 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/create_space_popup.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/create_space_popup.dart
@@ -17,8 +17,8 @@ class CreateSpacePopup extends StatefulWidget {
class _CreateSpacePopupState extends State {
String spaceName = LocaleKeys.space_defaultSpaceName.tr();
- String spaceIcon = builtInSpaceIcons.first;
- String spaceIconColor = builtInSpaceColors.first;
+ String? spaceIcon = builtInSpaceIcons.first;
+ String? spaceIconColor = builtInSpaceColors.first;
SpacePermission spacePermission = SpacePermission.publicToAll;
@override
@@ -80,8 +80,9 @@ class _CreateSpacePopupState extends State {
context.read().add(
SpaceEvent.create(
name: spaceName,
- icon: spaceIcon,
- iconColor: spaceIconColor,
+ // fixme: space issue
+ icon: spaceIcon!,
+ iconColor: spaceIconColor!,
permission: spacePermission,
createNewPageByDefault: true,
),
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/manage_space_popup.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/manage_space_popup.dart
index b677b4056c..52f22c5e3d 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/manage_space_popup.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/manage_space_popup.dart
@@ -77,7 +77,7 @@ class _SpaceNameTextField extends StatelessWidget {
});
final void Function(String name) onNameChanged;
- final void Function(String icon, String color) onIconChanged;
+ final void Function(String? icon, String? color) onIconChanged;
@override
Widget build(BuildContext context) {
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart
index 21f67c56ba..719c3bf25c 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/shared_widget.dart
@@ -1,7 +1,3 @@
-import 'package:flutter/cupertino.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/util/theme_extension.dart';
@@ -21,7 +17,9 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SpacePermissionSwitch extends StatefulWidget {
@@ -280,9 +278,9 @@ class ConfirmPopupColor {
static Color descriptionColor(BuildContext context) {
if (Theme.of(context).isLightMode) {
- return const Color(0xFF171717).withOpacity(0.8);
+ return const Color(0xFF171717).withOpacity(0.7);
}
- return const Color(0xFFffffff).withOpacity(0.72);
+ return const Color(0xFFffffff).withOpacity(0.7);
}
}
@@ -374,15 +372,21 @@ class _ConfirmPopupState extends State {
Expanded(
child: FlowyText(
widget.title,
- fontSize: 14.0,
+ fontSize: 16.0,
+ figmaLineHeight: 22.0,
+ fontWeight: FontWeight.w500,
overflow: TextOverflow.ellipsis,
color: ConfirmPopupColor.titleColor(context),
),
),
const HSpace(6.0),
FlowyButton(
+ margin: const EdgeInsets.all(3),
useIntrinsicWidth: true,
- text: const FlowySvg(FlowySvgs.upgrade_close_s),
+ text: const FlowySvg(
+ FlowySvgs.upgrade_close_s,
+ size: Size.square(18.0),
+ ),
onTap: () => Navigator.of(context).pop(),
),
],
@@ -392,10 +396,10 @@ class _ConfirmPopupState extends State {
Widget _buildDescription() {
return FlowyText.regular(
widget.description,
- fontSize: 12.0,
+ fontSize: 16.0,
color: ConfirmPopupColor.descriptionColor(context),
- maxLines: 3,
- lineHeight: 1.4,
+ maxLines: 5,
+ figmaLineHeight: 22.0,
);
}
@@ -492,16 +496,22 @@ class CurrentSpace extends StatelessWidget {
final child = Row(
mainAxisSize: MainAxisSize.min,
children: [
- SpaceIcon(
- dimension: 20,
- space: space,
- cornerRadius: 6.0,
- ),
- const HSpace(10),
+ if (space.spaceIcon != null) ...[
+ SpaceIcon(
+ dimension: 22,
+ space: space,
+ svgSize: 13,
+ cornerRadius: 8.0,
+ ),
+ const HSpace(10),
+ ] else ...[
+ const HSpace(2),
+ ],
Flexible(
child: FlowyText.medium(
space.name,
fontSize: 14.0,
+ figmaLineHeight: 18.0,
overflow: TextOverflow.ellipsis,
),
),
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart
index fc87902dd9..e5897d7470 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_header.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:appflowy/generated/locale_keys.g.dart';
+import 'package:appflowy/shared/icon_emoji_picker/icon.dart';
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/manage_space_popup.dart';
@@ -13,8 +14,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
-import 'package:flutter/material.dart';
+import 'package:flutter/material.dart' hide Icon;
import 'package:flutter_bloc/flutter_bloc.dart';
class SidebarSpaceHeader extends StatefulWidget {
@@ -171,8 +171,19 @@ class _SidebarSpaceHeaderState extends State {
await _showRenameDialog();
break;
case SpaceMoreActionType.changeIcon:
- final (String icon, String iconColor) = data;
- context.read().add(SpaceEvent.changeIcon(icon, iconColor));
+ final (IconGroup? group, Icon? icon, String? iconColor) = data;
+
+ final groupName = group?.name;
+ final iconName = icon?.name;
+ final name = groupName != null && iconName != null
+ ? '$groupName/$iconName'
+ : null;
+ context.read().add(
+ SpaceEvent.changeIcon(
+ name,
+ iconColor,
+ ),
+ );
break;
case SpaceMoreActionType.manage:
_showManageSpaceDialog(context);
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart
index 5a21780186..68cb4b0893 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart
@@ -9,7 +9,6 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon.dart
index 871dc0e475..43c8fccdd2 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon.dart
@@ -1,4 +1,6 @@
+import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/workspace/application/view/view_ext.dart';
+import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart';
@@ -8,19 +10,71 @@ class SpaceIcon extends StatelessWidget {
required this.dimension,
this.cornerRadius = 0,
required this.space,
+ this.svgSize,
});
final double dimension;
final double cornerRadius;
final ViewPB space;
+ final double? svgSize;
@override
Widget build(BuildContext context) {
- return SizedBox.square(
- dimension: dimension,
- child: ClipRRect(
- borderRadius: BorderRadius.circular(cornerRadius),
- child: space.spaceIconSvg,
+ final spaceIconColor = space.spaceIconColor;
+ final color = spaceIconColor != null
+ ? Color(int.parse(spaceIconColor))
+ : Colors.transparent;
+ final svg = space.buildSpaceIconSvg(
+ context,
+ size: svgSize != null ? Size.square(svgSize!) : null,
+ );
+ if (svg == null) {
+ return const SizedBox.shrink();
+ }
+
+ return ClipRRect(
+ borderRadius: BorderRadius.circular(cornerRadius),
+ child: Container(
+ width: dimension,
+ height: dimension,
+ color: color,
+ child: Center(
+ child: svgSize == null
+ ? svg
+ : SizedBox.square(dimension: svgSize!, child: svg),
+ ),
+ ),
+ );
+ }
+}
+
+class DefaultSpaceIcon extends StatelessWidget {
+ const DefaultSpaceIcon({
+ super.key,
+ required this.dimension,
+ required this.iconDimension,
+ this.cornerRadius = 0,
+ });
+
+ final double dimension;
+ final double cornerRadius;
+ final double iconDimension;
+
+ @override
+ Widget build(BuildContext context) {
+ final svg = builtInSpaceIcons.first;
+ final color = Color(int.parse(builtInSpaceColors.first));
+ return ClipRRect(
+ borderRadius: BorderRadius.circular(cornerRadius),
+ child: Container(
+ width: dimension,
+ height: dimension,
+ color: color,
+ child: FlowySvg(
+ FlowySvgData('assets/flowy_icons/16x/$svg.svg'),
+ color: Theme.of(context).colorScheme.surface,
+ size: Size.square(iconDimension),
+ ),
),
);
}
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart
index 091f288552..83ce2c21b8 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart
@@ -1,9 +1,15 @@
+import 'dart:math';
+
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
+import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flutter/material.dart';
+import 'package:flutter/material.dart' hide Icon;
final builtInSpaceColors = [
'0xFFA34AFD',
@@ -20,6 +26,11 @@ final builtInSpaceColors = [
'0xFFFF8933',
];
+String generateRandomSpaceColor() {
+ final random = Random();
+ return builtInSpaceColors[random.nextInt(builtInSpaceColors.length)];
+}
+
final builtInSpaceIcons =
List.generate(15, (index) => 'space_icon_${index + 1}');
@@ -34,7 +45,7 @@ class SpaceIconPopup extends StatefulWidget {
final String? icon;
final String? iconColor;
- final void Function(String icon, String color) onIconChanged;
+ final void Function(String? icon, String? color) onIconChanged;
final double cornerRadius;
@override
@@ -42,10 +53,12 @@ class SpaceIconPopup extends StatefulWidget {
}
class _SpaceIconPopupState extends State {
- late ValueNotifier selectedColor =
- ValueNotifier(widget.iconColor ?? builtInSpaceColors.first);
- late ValueNotifier selectedIcon =
- ValueNotifier(widget.icon ?? builtInSpaceIcons.first);
+ late ValueNotifier selectedIcon = ValueNotifier(
+ widget.icon,
+ );
+ late ValueNotifier selectedColor = ValueNotifier(
+ widget.iconColor ?? builtInSpaceColors.first,
+ );
@override
void dispose() {
@@ -58,19 +71,30 @@ class _SpaceIconPopupState extends State {
Widget build(BuildContext context) {
return AppFlowyPopover(
offset: const Offset(0, 4),
- constraints: const BoxConstraints(maxWidth: 220),
- margin: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 12.0),
+ constraints: BoxConstraints.loose(const Size(380, 432)),
+ margin: const EdgeInsets.all(0),
direction: PopoverDirection.bottomWithCenterAligned,
child: _buildPreview(),
- popupBuilder: (_) => SpaceIconPicker(
- icon: selectedIcon.value,
- iconColor: selectedColor.value,
- onIconChanged: (icon, iconColor) {
- selectedIcon.value = icon;
- selectedColor.value = iconColor;
- widget.onIconChanged(icon, iconColor);
- },
- ),
+ popupBuilder: (context) {
+ return FlowyIconEmojiPicker(
+ tabs: const [PickerTabType.icon],
+ onSelectedIcon: (group, icon, color) {
+ if (group == null || icon == null) {
+ selectedIcon.value = null;
+ } else {
+ selectedIcon.value = '${group.name}/${icon.name}';
+ }
+
+ if (color != null) {
+ selectedColor.value = color;
+ }
+
+ widget.onIconChanged(selectedIcon.value, selectedColor.value);
+
+ PopoverContainer.of(context).close();
+ },
+ );
+ },
);
}
@@ -87,15 +111,36 @@ class _SpaceIconPopupState extends State {
builder: (_, color, __) {
return ValueListenableBuilder(
valueListenable: selectedIcon,
- builder: (_, icon, __) {
- final child = ClipRRect(
- borderRadius: BorderRadius.circular(widget.cornerRadius),
- child: FlowySvg(
- FlowySvgData('assets/flowy_icons/16x/$icon.svg'),
- color: Color(int.parse(color)),
- blendMode: BlendMode.srcOut,
- ),
- );
+ builder: (_, value, __) {
+ Widget child;
+ if (value == null) {
+ child = const DefaultSpaceIcon(
+ cornerRadius: 16.0,
+ dimension: 32,
+ iconDimension: 32,
+ );
+ } else {
+ final content = kIconGroups?.findSvgContent(value);
+ if (content == null) {
+ child = const SizedBox.shrink();
+ } else {
+ child = ClipRRect(
+ borderRadius:
+ BorderRadius.circular(widget.cornerRadius),
+ child: Container(
+ color: Color(int.parse(color)),
+ child: Align(
+ child: FlowySvg.string(
+ content,
+ size: const Size.square(24),
+ color: Theme.of(context).colorScheme.surface,
+ ),
+ ),
+ ),
+ );
+ }
+ }
+
if (onHover) {
return Stack(
children: [
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart
index 266ea62e72..be827ccfa8 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/space/space_more_popup.dart
@@ -1,16 +1,15 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/tab.dart';
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
-import 'package:appflowy/workspace/application/view/view_ext.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_action_type.dart';
-import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart';
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -108,20 +107,19 @@ class SpaceMoreActionTypeWrapper extends CustomActionCell {
PopoverController controller,
) {
final child = _buildActionButton(context, null);
- final spaceBloc = context.read();
- final color = spaceBloc.state.currentSpace?.spaceIconColor;
-
return AppFlowyPopover(
- constraints: BoxConstraints.loose(const Size(216, 256)),
- margin: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 12.0),
+ constraints: BoxConstraints.loose(const Size(380, 432)),
+ margin: const EdgeInsets.all(0),
clickHandler: PopoverClickHandler.gestureDetector,
- popupBuilder: (_) => SpaceIconPicker(
- iconColor: color,
- skipFirstNotification: true,
- onIconChanged: (icon, color) {
- onTap(controller, (icon, color));
- },
- ),
+ offset: const Offset(0, -40),
+ popupBuilder: (context) {
+ return FlowyIconEmojiPicker(
+ tabs: const [PickerTabType.icon],
+ onSelectedIcon: (group, icon, color) {
+ onTap(controller, (group, icon, color));
+ },
+ );
+ },
child: child,
);
}
@@ -172,6 +170,8 @@ class SpaceMoreActionTypeWrapper extends CustomActionCell {
rightIconBuilder: (_) => inner.rightIcon,
textBuilder: (onHover) => FlowyText.regular(
inner.name,
+ fontSize: 14.0,
+ figmaLineHeight: 18.0,
color: inner == SpaceMoreActionType.delete && onHover
? Theme.of(context).colorScheme.error
: null,
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart
index 2b8a798ffa..5163bfd56a 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart
@@ -1,6 +1,6 @@
import 'dart:math';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/util/color_generator/color_generator.dart';
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
@@ -18,6 +18,7 @@ class WorkspaceIcon extends StatefulWidget {
this.borderRadius = 4,
this.emojiSize,
this.alignment,
+ required this.figmaLineHeight,
});
final UserWorkspacePB workspace;
@@ -28,6 +29,7 @@ class WorkspaceIcon extends StatefulWidget {
final void Function(EmojiPickerResult) onSelected;
final double borderRadius;
final Alignment? alignment;
+ final double figmaLineHeight;
@override
State createState() => _WorkspaceIconState();
@@ -45,7 +47,8 @@ class _WorkspaceIconState extends State {
child: FlowyText.emoji(
widget.workspace.icon,
fontSize: widget.emojiSize ?? widget.iconSize,
- figmaLineHeight: 21.0,
+ figmaLineHeight: widget.figmaLineHeight,
+ optimizeEmojiAlign: true,
),
)
: Container(
@@ -76,8 +79,9 @@ class _WorkspaceIconState extends State {
direction: PopoverDirection.bottomWithLeftAligned,
constraints: BoxConstraints.loose(const Size(364, 356)),
clickHandler: PopoverClickHandler.gestureDetector,
- popupBuilder: (_) => FlowyIconPicker(
- onSelected: (result) {
+ margin: const EdgeInsets.all(0),
+ popupBuilder: (_) => FlowyIconEmojiPicker(
+ onSelectedEmoji: (result) {
widget.onSelected(result);
controller.close();
},
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart
index 8a1b172aff..e9dec98685 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart
@@ -14,7 +14,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -172,6 +171,7 @@ class _WorkspaceMenuItemState extends State {
workspace: widget.workspace,
iconSize: 22,
fontSize: 16,
+ figmaLineHeight: 32.0,
enableEdit: true,
onSelected: (result) => context.read().add(
UserWorkspaceEvent.updateWorkspaceIcon(
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart
index c27514f1ee..f6b1931570 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart
@@ -242,6 +242,7 @@ class _SidebarSwitchWorkspaceButtonState
emojiSize: 18,
enableEdit: false,
borderRadius: 8.0,
+ figmaLineHeight: 21.0,
onSelected: (result) => context.read().add(
UserWorkspaceEvent.updateWorkspaceIcon(
widget.currentWorkspace.workspaceId,
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart
index ba57046f11..9371f11b40 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart
@@ -2,7 +2,7 @@ import 'dart:async';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
@@ -28,7 +28,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -583,6 +582,7 @@ class _SingleInnerViewItemState extends State {
controller: controller,
direction: PopoverDirection.rightWithCenterAligned,
constraints: BoxConstraints.loose(const Size(364, 356)),
+ margin: const EdgeInsets.all(0),
onClose: () => setState(() => isIconPickerOpened = false),
child: GestureDetector(
// prevent the tap event from being passed to the parent widget
@@ -594,8 +594,8 @@ class _SingleInnerViewItemState extends State {
),
popupBuilder: (context) {
isIconPickerOpened = true;
- return FlowyIconPicker(
- onSelected: (result) {
+ return FlowyIconEmojiPicker(
+ onSelectedEmoji: (result) {
ViewBackendService.updateViewIcon(
viewId: widget.view.id,
viewIcon: result.emoji,
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart
index 0383c9c1e1..8c64563eb3 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_more_action_button.dart
@@ -1,5 +1,5 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/move_to/move_page_menu.dart';
@@ -161,10 +161,10 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
return AppFlowyPopover(
constraints: BoxConstraints.loose(const Size(364, 356)),
- margin: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 12.0),
+ margin: const EdgeInsets.all(0),
clickHandler: PopoverClickHandler.gestureDetector,
- popupBuilder: (_) => FlowyIconPicker(
- onSelected: (result) => onTap(controller, result),
+ popupBuilder: (_) => FlowyIconEmojiPicker(
+ onSelectedEmoji: (result) => onTap(controller, result),
),
child: child,
);
@@ -256,6 +256,8 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
iconPadding: 10.0,
textBuilder: (onHover) => FlowyText.regular(
inner.name,
+ fontSize: 14.0,
+ figmaLineHeight: 18.0,
color: inner == ViewMoreActionType.delete && onHover
? Theme.of(context).colorScheme.error
: null,
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart
index eae3c29d76..0fe3fdf75c 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart
@@ -11,7 +11,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class NotificationButton extends StatefulWidget {
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart
index 3e9c445068..af31e19181 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_account_view.dart
@@ -1,7 +1,7 @@
import 'package:appflowy/env/cloud_env.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
-import 'package:appflowy/plugins/base/icon/icon_picker.dart';
+import 'package:appflowy/shared/icon_emoji_picker/flowy_icon_emoji_picker.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/auth/auth_service.dart';
import 'package:appflowy/user/application/prelude.dart';
@@ -18,7 +18,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -466,9 +465,9 @@ class _UserProfileSettingState extends State {
Container(
height: 380,
width: 360,
- margin: const EdgeInsets.symmetric(horizontal: 12),
- child: FlowyIconPicker(
- onSelected: (r) {
+ margin: const EdgeInsets.all(0),
+ child: FlowyIconEmojiPicker(
+ onSelectedEmoji: (r) {
context
.read()
.add(SettingsUserEvent.updateUserIcon(iconUrl: r.emoji));
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart
index 07d662f38d..71687a271b 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_plan_comparison_dialog.dart
@@ -11,7 +11,6 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../generated/locale_keys.g.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart
index 972e818b55..1491af3d4c 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_shortcuts_view.dart
@@ -23,7 +23,6 @@ import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/widget/error_page.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SettingsShortcutsView extends StatefulWidget {
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart
index 3bb810e6d5..abe56bf611 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/settings_workspace_view.dart
@@ -356,6 +356,7 @@ class _WorkspaceIconSetting extends StatelessWidget {
workspace: workspace!,
iconSize: workspace!.icon.isNotEmpty == true ? 46 : 20,
fontSize: 16.0,
+ figmaLineHeight: 46,
enableEdit: true,
onSelected: (r) => context
.read()
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_category.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_category.dart
index 34f25dd41e..8ec9c72510 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_category.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_category.dart
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
/// Renders a simple category taking a title and the list
/// of children (settings) to be rendered.
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_input_field.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_input_field.dart
index a41e98dfc8..d5a81655a5 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_input_field.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/shared/settings_input_field.dart
@@ -5,7 +5,6 @@ import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
/// This is used to describe a settings input field
///
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart
index 7d132c2962..c5f27a1d9c 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/members/workspace_member_page.dart
@@ -16,7 +16,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:string_validator/string_validator.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart
index e54de4d9c5..6751213251 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/setting_supabase_cloud.dart
@@ -18,7 +18,6 @@ import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/widget/error_page.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SettingSupabaseCloudView extends StatelessWidget {
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/image_viewer/interactive_image_toolbar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/image_viewer/interactive_image_toolbar.dart
index 1431cb45b8..5c07d6d5b1 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/image_viewer/interactive_image_toolbar.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/image_viewer/interactive_image_toolbar.dart
@@ -15,7 +15,6 @@ import 'package:flowy_infra/file_picker/file_picker_impl.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart
index f9f46cfba9..0a9dc6dd26 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/more_view_actions/more_view_actions.dart
@@ -11,7 +11,6 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart
index 38bee0bc2f..7be2a4b155 100644
--- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart
+++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart
@@ -8,7 +8,6 @@ import 'package:appflowy/workspace/presentation/widgets/rename_view_popover.dart
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -173,7 +172,7 @@ class _ViewTitleState extends State<_ViewTitle> {
return Container(
alignment: Alignment.center,
margin: const EdgeInsets.symmetric(horizontal: 6.0),
- child: _buildIconAndName(state, false),
+ child: _buildIconAndName(context, state, false),
);
}
@@ -185,7 +184,7 @@ class _ViewTitleState extends State<_ViewTitle> {
child: FlowyButton(
useIntrinsicWidth: true,
margin: const EdgeInsets.symmetric(horizontal: 6.0),
- text: _buildIconAndName(state, false),
+ text: _buildIconAndName(context, state, false),
),
),
);
@@ -216,13 +215,18 @@ class _ViewTitleState extends State<_ViewTitle> {
child: FlowyButton(
useIntrinsicWidth: true,
margin: const EdgeInsets.symmetric(horizontal: 6.0),
- text: _buildIconAndName(state, true),
+ text: _buildIconAndName(context, state, true),
),
),
);
}
- Widget _buildIconAndName(ViewTitleState state, bool isEditable) {
+ Widget _buildIconAndName(
+ BuildContext context,
+ ViewTitleState state,
+ bool isEditable,
+ ) {
+ final spaceIcon = state.view?.buildSpaceIconSvg(context);
return SingleChildScrollView(
child: Row(
children: [
@@ -234,10 +238,10 @@ class _ViewTitleState extends State<_ViewTitle> {
),
const HSpace(4.0),
],
- if (state.view?.isSpace == true &&
- state.view?.spaceIconSvg != null) ...[
+ if (state.view?.isSpace == true && spaceIcon != null) ...[
SpaceIcon(
dimension: 14,
+ svgSize: 8.5,
space: state.view!,
cornerRadius: 4,
),
diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart
index 92e459937e..d8e8604386 100644
--- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart
+++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/flowy_infra_ui.dart
@@ -1,4 +1,5 @@
// Basis
+export '/widget/flowy_tooltip.dart';
export '/widget/separated_flex.dart';
export '/widget/spacing.dart';
export 'basis.dart';
diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/error_page.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/error_page.dart
index fd6b734715..d395873bd7 100644
--- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/error_page.dart
+++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/error_page.dart
@@ -7,7 +7,6 @@ import 'package:flutter/services.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
-import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
import 'package:flowy_svg/flowy_svg.dart';
import 'package:url_launcher/url_launcher.dart';
diff --git a/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart b/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart
index aa70ee9d1f..a69a4bb90d 100644
--- a/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart
+++ b/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart
@@ -24,8 +24,29 @@ class FlowySvg extends StatelessWidget {
this.color,
this.blendMode = BlendMode.srcIn,
this.opacity = 1.0,
+ this.svgString,
});
+ /// Construct a FlowySvg Widget from a string
+ factory FlowySvg.string(
+ String svgString, {
+ Key? key,
+ Size? size,
+ Color? color,
+ BlendMode? blendMode = BlendMode.srcIn,
+ double opacity = 1.0,
+ }) {
+ return FlowySvg(
+ const FlowySvgData(''),
+ key: key,
+ size: size,
+ color: color,
+ blendMode: blendMode,
+ opacity: opacity,
+ svgString: svgString,
+ );
+ }
+
/// The data for the flowy svg. Will be generated by the generator in this
/// package within bin/flowy_svg.dart
final FlowySvgData svg;
@@ -33,6 +54,9 @@ class FlowySvg extends StatelessWidget {
/// The size of the svg
final Size? size;
+ /// The svg string
+ final String? svgString;
+
/// The color of the svg.
///
/// This property will not be applied to the underlying svg widget if the
@@ -57,22 +81,41 @@ class FlowySvg extends StatelessWidget {
final iconColor =
(color ?? Theme.of(context).iconTheme.color)?.withOpacity(opacity);
final textScaleFactor = MediaQuery.textScalerOf(context).scale(1);
+
+ final Widget svg;
+
+ if (svgString != null) {
+ svg = SvgPicture.string(
+ svgString!,
+ width: size?.width,
+ height: size?.height,
+ colorFilter: iconColor != null && blendMode != null
+ ? ColorFilter.mode(
+ iconColor,
+ blendMode!,
+ )
+ : null,
+ );
+ } else {
+ svg = SvgPicture.asset(
+ _normalized(),
+ width: size?.width,
+ height: size?.height,
+ colorFilter: iconColor != null && blendMode != null
+ ? ColorFilter.mode(
+ iconColor,
+ blendMode!,
+ )
+ : null,
+ );
+ }
+
return Transform.scale(
scale: textScaleFactor,
child: SizedBox(
width: size?.width,
height: size?.height,
- child: SvgPicture.asset(
- _normalized(),
- width: size?.width,
- height: size?.height,
- colorFilter: iconColor != null && blendMode != null
- ? ColorFilter.mode(
- iconColor,
- blendMode!,
- )
- : null,
- ),
+ child: svg,
),
);
}
diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock
index 6f338092c0..4827c94bbc 100644
--- a/frontend/appflowy_flutter/pubspec.lock
+++ b/frontend/appflowy_flutter/pubspec.lock
@@ -740,8 +740,8 @@ packages:
dependency: "direct main"
description:
path: "."
- ref: "4a5cac"
- resolved-ref: "4a5cac57e31c0ffd49cd6257a9e078f084ae342c"
+ ref: "38c2c42"
+ resolved-ref: "38c2c429212af6b72a0af829bb0dd3f3eb4ce2c7"
url: "https://github.com/LucasXu0/emoji_mart.git"
source: git
version: "1.0.2"
diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml
index 621383ecf1..17c37f3287 100644
--- a/frontend/appflowy_flutter/pubspec.yaml
+++ b/frontend/appflowy_flutter/pubspec.yaml
@@ -111,7 +111,7 @@ dependencies:
flutter_emoji_mart:
git:
url: https://github.com/LucasXu0/emoji_mart.git
- ref: "4a5cac"
+ ref: "38c2c42"
# Notifications
# TODO: Consider implementing custom package
@@ -283,6 +283,7 @@ flutter:
- assets/images/emoji/
- assets/images/login/
- assets/translations/
+ - assets/icons/icons.json
# The following assets will be excluded in release.
# BEGIN: EXCLUDE_IN_RELEASE