Skip to content

Commit

Permalink
💡 feat: tab views (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
unickhow authored May 7, 2023
1 parent b0a710b commit 4b0eb19
Show file tree
Hide file tree
Showing 18 changed files with 659 additions and 214 deletions.
66 changes: 23 additions & 43 deletions figma/code.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,30 @@
figma.showUI(__html__, {
width: 420,
height: 220
});
/// <reference types="@figma/plugin-typings" />
import handleDateTimeTab from './date-time'
import handleNumericTab from './numeric'

function setBaseNumber (base = '0', orderType = 'asc', length) {
const baseNumber = +base
let stack = 0
let res
return () => {
if (orderType === 'asc') {
res = baseNumber + stack
} else if (orderType === 'desc') {
res = baseNumber - stack
} else {
res = Math.floor(Math.random() * Math.pow(10, length))
}
stack += 1
return res.toString().padStart(length, '0')
}
enum TabHeight {
numeric = 220,
dateTime = 550
}

figma.ui.onmessage = async payload => {
const { prefix, baseNumber, orderType, action, isReverse } = payload
const nodes = figma.currentPage.selection
const nodesLength = nodes.length
if (action === 'generate') {
const isInvalid = nodes.some(node => node.type !== 'TEXT');
if (isInvalid) {
return "Select a single text node."
}

const genNextNumber = setBaseNumber(baseNumber, orderType, baseNumber.length)
figma.showUI(__html__, {
width: 350,
height: TabHeight.numeric
})

for (let i = 0; i < nodesLength; i += 1) {
//! Noted: order of page selections are not reliable.
await figma.loadFontAsync(nodes[i].fontName)
const result = isReverse
? `${genNextNumber()}${prefix}`
: `${prefix}${genNextNumber()}`
nodes[i].characters = result
nodes[i].name = result
figma.ui.onmessage = payload => {
// TODO: should separate tabChange and others
if (payload.action === 'tabChange') {
const height = TabHeight[payload.tab] as unknown as number
figma.ui.resize(350, height)
} else {
const tabHandlers = {
numeric: handleNumericTab,
dateTime: handleDateTimeTab
}
const tabHandler = tabHandlers[payload.tab]
if (tabHandler) {
tabHandler(payload)
}
}

// on cancel
if (action === 'cancel') {
figma.closePlugin();
}
};
78 changes: 78 additions & 0 deletions figma/date-time.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
function addDays (date: Date, days: number): Date {
const result = new Date(date)
result.setDate(result.getDate() + days)
return result
}

function formatDate(date: Date, format: string): string {
const month = date.getMonth() + 1
const day = date.getDate()
const year = date.getFullYear()
const weekday = date.getDay()
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']

const patterns = {
'YYYY-MM-DD': `${year}-${(month).toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`,
'MM-DD-YYYY': `${(month).toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}-${year}`,
'MM/DD/YYYY': `${month.toString().padStart(2, '0')}/${day.toString().padStart(2, '0')}/${year}`,
'MMMM DD, YYYY': `${months[date.getMonth()]} ${day}, ${year}`,
'MMMM DD, YYYY h:mm A': `${months[date.getMonth()]} ${day}, ${year} ${date.toLocaleTimeString('en-US', {hour: 'numeric', minute: 'numeric', hour12: true})}`,
'dddd, MMMM DD, YYYY h:mm A': `${days[weekday]}, ${months[date.getMonth()]} ${day}, ${year} ${date.toLocaleTimeString('en-US', {hour: 'numeric', minute: 'numeric', hour12: true})}`,
'M/D/YYYY': `${month}/${day}/${year}`,
'MMM D, YYYY': `${months[date.getMonth()].slice(0, 3)} ${day}, ${year}`,
'MMM D, YYYY h:mm A': `${months[date.getMonth()].slice(0, 3)} ${day}, ${year} ${date.toLocaleTimeString('en-US', {hour: 'numeric', minute: 'numeric', hour12: true})}`,
'ddd, MMM D, YYYY h:mm A': `${days[weekday].slice(0, 3)}, ${months[date.getMonth()].slice(0, 3)} ${date.getDate()}, ${date.getFullYear()} ${date.toLocaleTimeString('en-US', {hour: 'numeric', minute: 'numeric', hour12: true})}`
}

if (patterns[format]) {
return patterns[format]
} else {
throw new Error(`Unsupported format: ${format}`)
}
}

function setBaseDate (base = '', orderType = 'asc', format) {
const baseDate = new Date(base)
let stack = 0
let res
return () => {
if (orderType === 'asc') {
res = addDays(baseDate, stack)
} else if (orderType === 'desc') {
res = addDays(baseDate, -stack)
}
stack += 1
return formatDate(res, format)
}
}

export default async function handleDateTimeTab (payload) {
const {
action,
orderType,
selectedDate,
format
} = payload
const nodes = figma.currentPage.selection
const nodesLength = nodes.length
if (action === 'generate') {
const isInvalid = nodes.some(node => node.type !== 'TEXT');
if (isInvalid) {
return "Select a single text node."
}

const genNextDate = setBaseDate(selectedDate, orderType, format)

for (let i = 0; i < nodesLength; i += 1) {
//! Noted: order of page selections are not reliable.
await figma.loadFontAsync(nodes[i].fontName)
nodes[i].characters = genNextDate()
}
}

// on cancel
if (action === 'cancel') {
figma.closePlugin();
}
}
45 changes: 45 additions & 0 deletions figma/numeric.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
function setBaseNumber (base = '0', orderType = 'asc', length) {
const baseNumber = +base
let stack = 0
let res
return () => {
if (orderType === 'asc') {
res = baseNumber + stack
} else if (orderType === 'desc') {
res = baseNumber - stack
} else {
res = Math.floor(Math.random() * Math.pow(10, length))
}
stack += 1
return res.toString().padStart(length, '0')
}
}

export default async function handleNumericTab (payload) {
const { prefix, baseNumber, orderType, action, isReverse } = payload
const nodes = figma.currentPage.selection
const nodesLength = nodes.length
if (action === 'generate') {
const isInvalid = nodes.some(node => node.type !== 'TEXT');
if (isInvalid) {
return 'Select a single text node.'
}

const genNextNumber = setBaseNumber(baseNumber, orderType, baseNumber.length)

for (let i = 0; i < nodesLength; i += 1) {
//! Noted: order of page selections are not reliable.
await figma.loadFontAsync(nodes[i].fontName)
const result = isReverse
? `${genNextNumber()}${prefix}`
: `${prefix}${genNextNumber()}`
nodes[i].characters = result
nodes[i].name = result
}
}

// on cancel
if (action === 'cancel') {
figma.closePlugin();
}
}
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400&family=Roboto+Condensed:wght@300;400&display=swap" rel="stylesheet">
</head>
<body>
<div id="app"></div>
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"preview": "vite preview"
},
"dependencies": {
"@popperjs/core": "^2.11.7",
"dayjs": "^1.11.7",
"mixpanel-figma": "^2.0.1",
"v-calendar": "^3.0.3",
"vue": "^3.2.47"
},
"devDependencies": {
Expand Down
86 changes: 86 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4b0eb19

Please sign in to comment.