Skip to content

Commit b22fa35

Browse files
authored
feat: Chrome extension (0xa3k5#177)
1 parent 16528db commit b22fa35

File tree

16 files changed

+511
-15
lines changed

16 files changed

+511
-15
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: Chrome Extension
2+
3+
on:
4+
# Build on PRs that touch extension code
5+
pull_request:
6+
paths:
7+
- "apps/chrome-extension/**"
8+
- "packages/core/**"
9+
- "packages/common/**"
10+
11+
# Publish when a GitHub release is created (after changeset release)
12+
release:
13+
types: [published]
14+
15+
# Manual trigger for testing
16+
workflow_dispatch:
17+
inputs:
18+
publish:
19+
description: "Publish to Chrome Web Store"
20+
required: false
21+
default: "false"
22+
type: choice
23+
options:
24+
- "false"
25+
- "true"
26+
27+
concurrency:
28+
group: chrome-extension-${{ github.ref }}
29+
cancel-in-progress: true
30+
31+
jobs:
32+
build:
33+
name: Build Extension
34+
runs-on: ubuntu-latest
35+
steps:
36+
- name: Check out
37+
uses: actions/checkout@v4
38+
39+
- name: Install Bun
40+
uses: oven-sh/setup-bun@v2
41+
with:
42+
bun-version-file: package.json
43+
44+
- name: Install dependencies
45+
run: bun install --frozen-lockfile
46+
47+
- name: Build packages (core + common)
48+
run: bun run build:packages
49+
50+
- name: Build Chrome extension
51+
working-directory: apps/chrome-extension
52+
run: bun run build
53+
54+
- name: Package extension
55+
working-directory: apps/chrome-extension
56+
run: cd dist && zip -r ../web3icons-chrome.zip .
57+
58+
- name: Upload build artifact
59+
uses: actions/upload-artifact@v4
60+
with:
61+
name: chrome-extension
62+
path: apps/chrome-extension/web3icons-chrome.zip
63+
retention-days: 30
64+
65+
publish:
66+
name: Publish to Chrome Web Store
67+
needs: build
68+
runs-on: ubuntu-latest
69+
# Only publish on release events or manual trigger with publish=true
70+
if: >
71+
github.event_name == 'release' ||
72+
(github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true')
73+
steps:
74+
- name: Download build artifact
75+
uses: actions/download-artifact@v4
76+
with:
77+
name: chrome-extension
78+
79+
- name: Upload to Chrome Web Store
80+
uses: mnao305/chrome-extension-upload@v5.0.0
81+
with:
82+
file-path: web3icons-chrome.zip
83+
extension-id: ${{ secrets.CHROME_EXTENSION_ID }}
84+
client-id: ${{ secrets.CHROME_CLIENT_ID }}
85+
client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
86+
refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}
87+
publish: true

apps/chrome-extension/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist/
2+
node_modules/
2.25 KB
Loading
675 Bytes
Loading
1.12 KB
Loading
1.65 KB
Loading
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"manifest_version": 3,
3+
"name": "Web3 Icons",
4+
"version": "1.0.0",
5+
"description": "Browse and copy 2,500+ crypto icons. Tokens, networks, wallets, and exchanges in branded, mono, and background variants.",
6+
"permissions": ["clipboardWrite"],
7+
"action": {
8+
"default_popup": "popup.html",
9+
"default_icon": {
10+
"16": "icons/icon-16.png",
11+
"32": "icons/icon-32.png",
12+
"48": "icons/icon-48.png",
13+
"128": "icons/icon-128.png"
14+
}
15+
},
16+
"icons": {
17+
"16": "icons/icon-16.png",
18+
"32": "icons/icon-32.png",
19+
"48": "icons/icon-48.png",
20+
"128": "icons/icon-128.png"
21+
}
22+
}

apps/chrome-extension/package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "@web3icons/chrome-extension",
3+
"version": "1.0.0",
4+
"private": true,
5+
"description": "Browse and copy 2,500+ crypto icons from any tab. Tokens, networks, wallets, and exchanges in branded, mono, and background variants.",
6+
"author": "AK <hey@akml.io>",
7+
"scripts": {
8+
"dev": "bun run build:css --watch & bun run build:js --watch",
9+
"build": "bun run build:css && bun run build:js",
10+
"build:css": "npx @tailwindcss/cli --input ./src/css/input.css --output ./dist/popup.css --minify",
11+
"build:js": "bun run scripts/build.ts"
12+
},
13+
"dependencies": {
14+
"@web3icons/core": "4.0.50",
15+
"@web3icons/common": "0.11.45"
16+
},
17+
"devDependencies": {
18+
"tailwindcss": "^4.1.11",
19+
"typescript": ">=5"
20+
}
21+
}

apps/chrome-extension/popup.html

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<link rel="stylesheet" href="popup.css">
7+
</head>
8+
<body class="bg-gray-darkest font-mono text-xs">
9+
<main id="app" class="flex w-[360px] flex-col gap-3 p-4" style="min-height: 500px; max-height: 580px;">
10+
<!-- Tabs -->
11+
<div id="tabs" class="relative flex w-full border-b border-gray-lightest pb-2">
12+
<div id="tab-indicator" class="absolute bottom-0 left-0 h-[1px] bg-white transition-all duration-150"></div>
13+
</div>
14+
15+
<!-- Search -->
16+
<div class="relative flex w-full items-center gap-2 rounded-full border border-gray-lightest bg-gray-light px-4 focus-within:border-primary">
17+
<input
18+
id="search"
19+
type="text"
20+
placeholder="Search icons..."
21+
class="h-8 w-full bg-transparent text-white placeholder:text-white/40 focus:outline-none"
22+
/>
23+
</div>
24+
25+
<!-- Variant Toggle -->
26+
<div id="variants" class="relative inline-flex w-full rounded-full border border-gray-lightest bg-gray-light p-1 text-white"></div>
27+
28+
<!-- Icon Grid -->
29+
<div id="icon-grid" class="flex-1 overflow-y-auto -mx-4" style="max-height: 360px;">
30+
<div id="icons" class="grid grid-cols-4 gap-0"></div>
31+
</div>
32+
33+
<!-- Toast -->
34+
<div id="toast" class="fixed bottom-16 left-1/2 -translate-x-1/2 rounded-full bg-primary px-4 py-2 text-xs text-white opacity-0 transition-opacity duration-200 pointer-events-none">
35+
Copied!
36+
</div>
37+
38+
<!-- Footer -->
39+
<div class="flex items-center justify-between border-t border-gray-lightest pt-3 -mx-4 px-4">
40+
<a href="https://web3icons.io" target="_blank" rel="noopener" class="text-white/30 hover:text-white/60 transition-colors">web3icons.io</a>
41+
<a href="https://akml.io" target="_blank" rel="noopener" class="text-white/30 hover:text-white/60 transition-colors">by AK</a>
42+
</div>
43+
</main>
44+
<script src="popup.js"></script>
45+
</body>
46+
</html>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { build } from 'bun'
2+
import { cpSync, mkdirSync, existsSync } from 'fs'
3+
import { join } from 'path'
4+
5+
const ROOT = join(import.meta.dir, '..')
6+
const DIST = join(ROOT, 'dist')
7+
8+
// Ensure dist exists
9+
mkdirSync(DIST, { recursive: true })
10+
11+
// Bundle popup.ts
12+
await build({
13+
entrypoints: [join(ROOT, 'src/popup.ts')],
14+
outdir: DIST,
15+
naming: 'popup.js',
16+
minify: true,
17+
target: 'browser',
18+
format: 'esm',
19+
})
20+
21+
// Copy static files
22+
cpSync(join(ROOT, 'popup.html'), join(DIST, 'popup.html'))
23+
cpSync(join(ROOT, 'manifest.json'), join(DIST, 'manifest.json'))
24+
25+
// Copy icons if they exist
26+
const iconsDir = join(ROOT, 'icons')
27+
if (existsSync(iconsDir)) {
28+
cpSync(iconsDir, join(DIST, 'icons'), { recursive: true })
29+
}
30+
31+
console.log('Build complete: dist/')

0 commit comments

Comments
 (0)