Slope - Figma plugin (1)
a very first open source plugin I made.
序
在去年 (2021) 五月,台北開始全面居隔前後,未來室友提出了一個有挑戰性的需求
🧏♀️ 我們那個編號每次都要一個一個點好麻煩喔,外掛都只有隨機號碼,但像是我們需要房號啊日期什麼的,都馬是照順序排下來的,好希望有個可以有序列產生號碼的工具喔
嗯,於是這篇文章的序就這麼開端了
起手當然先找官方文件,API 及規範都還蠻完整的,但實際找起來有點耗時,畢竟是第一次開發這種封裝好的應用程式外掛,所以文件看歸看,還是找了很多範例教學來臨摹 😅
Become a Figma developer: create your first plugin
一般來說,使用 Figma 並不一定要下載 app,因為他本身也是以網頁的形式在運作,所以如果沒有開發的需求,網頁版足以一般設計師使用,但由於本文有開發需求,就直接帶入 app 畫面
開啟一個專門測試 plugin 的專案,並在模板空白處右鍵點選 New Plugin (如上圖)
當年還沒有 FigJam 這老兄,所以我是直接使用右邊的 Figma Design (for Figma only)
接著選擇 plugin 的模式:
- Empty: 空白模板,但沒有細究是幹嘛用的 …
- Run once: 啟動時做某件處理,比較跟使用無關
- With UI & browser APIs: 這是大多數開發者的選項,主要是在設計師操作時能給予輔助的 GUI 工具
最後一步 Figma 會自動產生開發環境所需的檔案,把專案存在本機電腦後,在專案內安裝相應套件後即可開始
npm install --save-dev @figma/plugin-typings
ui.html
為介面呈現的主要入口,而邏輯部分則是寫在 code.ts
(記住不是 .js),開發時記得先在 VS Code 執行 watch server command ⌘
+ ⇧
+ B
tsc: watch - tsconfig.json
開發完成後要發佈也很簡單,Figma app 介面就可以找到 publish
填寫一些關於要給使用者的資訊及此插件的描述等等的內容,一鍵發布就完成了(easy 👍)
happy coding! 但其實開發圖中最惱人的是他並不支援 hot reload,可能是現代框架開發習慣了,沒有即時看到反饋實在是很不舒服
後記 2022/06
一年之後,很榮幸的下載數來到了 50 大關,就興致一起來改個版,這期間未來室友一直在許願可以有日期的功能,以及前後對調的功能,在第一版時,Slope 僅支援 prefix + number 排列
概念上我覺得這兩個功能都不會太難達成,但由於專案起創時是最原始的 html + css + js,於是趁著這次想改版的念頭乾脆把 framework 引進來,考慮到專案大小不太需要完整的 vue,看了 svelte、solidjs,最後還是選擇了尤教授的輕量版 vue: petite-vue,在 MVVM 的幫助下又找回了舒適的 DX 🥴 但這畢竟不是一個完整的打包環境,所以在 UI framework 及 Icon 上使用還是有點受限,暫時先繼續使用 bulma cdn,幾個小時的較調下,v2 順應而生
這次提供了前後文的對調功能,在文字的選擇上更加彈性,至於日期嘛 … 就破 100 再來看看嘍 😃
https://github.com/unickhow/slope
再記 2023/05
繼上次引入 petite-vue 後又事隔一年,使用數竟然來到了 300up 🫢 (Figma plugin 現在採即時引用而非像過去一樣「仿下載」的操作),也算是沾到一點「開源開發者」的邊了吧,終於要來實踐一年前的「日期字串」承諾。
依慣例先巡了一下目前的架構,又是一如既往的不滿足啊 😒 於是秉持「工欲善其事,必先利其器」的精神,還是先來梳理開發環境吧!由於這次對整個功能有更多的想像,所以想先將現代 SPA 的環境整組套上
- Vite
- Vue3
畢竟終究只是個 html + js 的產物,過程怎麼樣都不打緊吧~先照 vite 的流程起手,之後再新增一個 figma/code.ts
放 plugin 與 figma 溝通用的主要邏輯,接著新增 public/manifest.json
,內容應同 create figma plugin 時提供的檔案 (包含 id 及 name),這樣打包後就會原封不動的搬進 dist,最終開發完要提供給 figma 的就是這包 dist,所以接下來要從 vite.config.ts 中把打包產物都設定好
dist
|- index.html
|- code.js
|- manifest.json
在改版前可以看到所有的 css 都被寫在 html 中,主要是因為 manifest 中並沒有任何關於 css 的路徑參照,如果用相對路徑在 html 中引入的話,在部署到 figma 上後可能又會不一樣,所以這邊選擇將 css 全部壓進 html,配上前端開發必備良藥 unocss,而 code.ts 則輸出成 code.js
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { viteSingleFile } from 'vite-plugin-singlefile'import UnoCSS from 'unocss/vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
viteSingleFile(), UnoCSS()
],
build: {
cssCodeSplit: false, // 不另外打包 css
rollupOptions: {
input: {
index: 'index.html',
code: 'figma/code.ts'
},
output: {
entryFileNames: '[name].js'
}
}
}
})
值得注意的點是,為了達到 js, css all in html 而安裝的 vite-plugin-singlefile 似乎會遇到一些相容性的 bug,所以安裝時要指定版號 @0.7.1
,雖然作者表示在 @0.10.0 已修復,依舊無效 🤨
以下就是這次全新版本的開發環境 vite + vue3 + unocss !!
既然都走到這了就發個 template 吧 figma-plugin-vite-vue-template
幾番折騰後終於進入正題了,有了如此神助的 DX,每次開發都一百分呢 🚀
before | after |
---|---|
然後是說了很久的 datetime 字串功能,由於介面使用上與現有的方式有點不同,打算採用 tab 來切換兩個功能,看了一下其他有 tab 的 plugin 總感覺有一個 design guideline 但又找不到相關的文件
拼拼湊湊看下來,最接近的是 menu,但 Unplash 有帶 icon 卻看不到文件中有可以指定 icon 的欄位,而因為我想要的是開發上 HMR 的即時反饋體驗,至少在介面開發上可以更快速的實作,如果要借助 figma sdk 去切換會造成 local 開發極大的不便,於是我想用盡量相仿的視覺設計,透過 component 切換來做 plugin 內部的控管,再加上我可以自己控制 component 的生命週期,所以在切換頁面上可以有效降低每次 init 的啟動時間,唯一的問題是:不知道會不會因為不符合規範被下架 😐,再加上另一個潛在的問題是,parameter 這欄位似乎是可以對不同 tab 做什麼 (目前沒用他的 tab 就沒繼續深究) ,如果之後有類似的需求可能就要整組打掉重練。
開始動手前先釐清了幾個要點:
- date picker 不能手動輸入,必須透過日曆上的點擊動作觸發
→ 節省多餘的驗證步驟,也考慮到這是 wireframe 設計,大多數時間只需要帶格式的字串即可 - format 不能手動輸入,採限定選項的 select
→ 各家的格式定義不一,光這次採用的 dayjs 就跟 v-calendar 有些微出入了,如果再考慮用戶從其他 library (e.g. momentjs) 習慣格式搬過來的話,要處理太多可能性的轉換
YYYY-MM-DD
MM-DD-YYYY
MM/DD/YYYY
MMMM DD, YYYY
MMMM DD, YYYY h:mm A
dddd, MMMM DD, YYYY h:mm A
M/D/YYYY
MMM D, YYYY
MMM D, YYYY h:mm A
ddd, MMM D, YYYY h:mm A
- calendar 的呈現方式主要考量兩種,一是跟一般常用的 form 表單一樣,透過點擊 input 觸發才顯示,二是直接丟在介面上 → 想跟第一個 tab 的介面做出差異,選擇直接呈現
voilà
基於這次上述 format 的考量,我先把 dayjs 現有的 format 全部丟上去,然後再埋 mixpanel 來追蹤一下大家使用的習慣,以利後續更新參考 🤫,這邊有個小坑著墨了一段時間,就是官方提供的 https://github.com/mixpanel/mixpanel-js 並不適用於 figma plugin,因為背後會去存取使用者的 cookie/localStorage,而 figma plugin 是以 Data-URI 的方式透過 iframe 嵌入,並不能操作到 cookie (即便用上了 disable_persistence
也無效 …),所以找到了專為 figma plugin 而生的二創套件 https://github.com/okotoki/mixpanel-figma,去掉了 cookie/localStorage 的部分,但這樣的代價是如果設計師同時開了多個項目在使用 plugin,將被視為不同的使用者紀錄,不過對於目前需求已經很夠用了!於是進一步把 mixpanel dashboard 都設置好,便可以準備一窺設計師們的習性了 👀
總結一下這次一年一度卯起來的改版,整體來說非常的充實啊,從開發環境開始搞到畫面產出,都有源源不絕的動力,卡最久的本來以為會是 vite 架構,但其實時間都花在找 tab guideline …,找到後試著改寫才發現跟 dev server 相性很差,於是又跳回 SPA 的開發模式繼續衝,至於 Todo 中還有一項:append element,也就是不需要先選擇字串就可以無中生有的功能嘛 … 就再看看什麼時候有緣了 😅