Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
NoriSte committed Feb 26, 2024
1 parent 3b4cca3 commit 8b3e347
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 117 deletions.
179 changes: 118 additions & 61 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { on, showUI } from '@create-figma-plugin/utilities'
import type { LogOptions, UiOptions } from './types'

const uiOptions = { width: 480, height: 240 } as const

Expand All @@ -7,25 +8,35 @@ const uiOptions = { width: 480, height: 240 } as const
// - log on ui change
// - log on open
// - enable/disable
// - relog current selection
// - show diff?
// - store config

const defaultUiOptions: UiOptions = {
enabled: true,
expandedUi: true,
expressionsToEvaluate: '',
hideExpressionErrors: false,
altoStringifyEvaluatedExpressions: false,
formatStringifiedEvaluatedExpressions: false,
}
const defaultConfiguration: LogOptions = {
enabled: true,
expressionsToEvaluate: '',
hideExpressionErrors: false,
altoStringifyEvaluatedExpressions: false,
formatStringifiedEvaluatedExpressions: false,
}
const currentConfiguration: LogOptions = {
...defaultConfiguration,
}

function logElements({
logHint,
elements,
alsoStringify,
expressionsToEvaluate,
}: {
elements: unknown[]
logHint: boolean
alsoStringify: boolean
expressionsToEvaluate: string
}) {
for (const element of elements) {
logElement({
logHint,
element,
alsoStringify,
expressionsToEvaluate,
})
function processItems(items: readonly unknown[], logOptions: LogOptions) {
for (const item of items) {
processItem(
item,
logOptions,
)
}
}

Expand All @@ -35,68 +46,84 @@ function evaluateStringOnObject(obj, str) {
return new Function('obj', `return obj.${str}`)(obj)
}

function logElement({
// logHint,
element,
alsoStringify,
expressionsToEvaluate,
}: {
element: unknown
logHint: boolean
alsoStringify: boolean
expressionsToEvaluate: string
}) {
const expressions = expressionsToEvaluate.split(',')

for (const expression of expressions) {
let value
let stringifiedValue = ''
function processItem(item: unknown, logOptions: LogOptions) {
console.log(item)

try {
value = evaluateStringOnObject(element, expression)
if (alsoStringify)
stringifiedValue = JSON.stringify(value)
const expressions = logOptions.expressionsToEvaluate.split(',')

logExpression(expression, value)
if (stringifiedValue)
logExpression(`${expression}(stringified):`, stringifiedValue)
for (const expression of expressions)
{

Check failure on line 55 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Expected indentation of 2 spaces but found 4

Check failure on line 55 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Opening curly brace does not appear on the same line as controlling statement
const trimmedExpression = expression.trim()

Check failure on line 56 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Expected indentation of 4 spaces but found 6
if(expression === '') continue

Check failure on line 57 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Expected indentation of 4 spaces but found 6

Check failure on line 57 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Expected space(s) after "if"

Check failure on line 57 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Expect newline after if
processExpression(item, trimmedExpression, logOptions)}

Check failure on line 58 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Expected indentation of 4 spaces but found 6

Check failure on line 58 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Requires a space before '}'

Check failure on line 58 in src/main.ts

View workflow job for this annotation

GitHub Actions / Node.js Quick

Closing curly brace should be on the same line as opening curly brace or on the line after the previous block
}

function processExpression(
item: unknown,
expression: string,
logOptions: LogOptions,
) {
const { altoStringifyEvaluatedExpressions, hideExpressionErrors, formatStringifiedEvaluatedExpressions } = logOptions
let value
let stringifiedValue = ''
let errored = false

try {
value = evaluateStringOnObject(item, expression)
logExpression(expression, value)
}
catch (e) {
errored = true
if (!hideExpressionErrors)
logExpressionError(expression, stringifyError(e))
}

if (altoStringifyEvaluatedExpressions && !errored) {
try {
stringifiedValue = formatStringifiedEvaluatedExpressions ? JSON.stringify(value, null, 2) : JSON.stringify(value)
logExpression(`${expression} (stringified):`, stringifiedValue)
}
catch (e) {
logExpressionError(expression, e instanceof Error ? e.message : `${e}`)
logExpressionError(`${expression} (stringified):`, stringifyError(e))
}

}
}

function logCurrentSelection() {
logElements({
logHint: false,
alsoStringify: true,
// @ts-expect-error TODO:
elements: figma.currentPage.selection,
expressionsToEvaluate: 'id,name,reactions,reactionssss[0],reactions[0]',
})
function processCurrentSelection() {
processItems(
figma.currentPage.selection,
currentConfiguration,
)
}

function createSelectAndInspect() {
function onSelectionChange() {
if (!currentConfiguration.enabled)
return
signedLog('Selection changed')
logCurrentSelection()
processCurrentSelection()
}

function onConfigurationChange() {
signedLog('Configuration changed')
processCurrentSelection()
}

function start() {
signedLog('Plugin opened')
showUI(uiOptions, { generatedXStateConfig: undefined })
showUI(uiOptions, { uiOptions: defaultUiOptions })
figma.on('selectionchange', onSelectionChange)
logCurrentSelection()
processCurrentSelection()
}

function cleanup() {
figma.off('selectionchange', onSelectionChange)
}

return {
start,
cleanup,
onConfigurationChange,
}
}

Expand All @@ -105,7 +132,34 @@ export default function main() {
selectAndInspect.start()

// UI EVENTS
// on('REGENERATE', selectAndInspect.log)
on('enabledChanged', (value: boolean) => {
currentConfiguration.enabled = value
if (currentConfiguration.enabled)
selectAndInspect.onConfigurationChange()
})
on('resetToDefaultUiOptions', () => {
currentConfiguration.enabled = defaultConfiguration.enabled
currentConfiguration.expressionsToEvaluate = defaultConfiguration.expressionsToEvaluate
currentConfiguration.hideExpressionErrors = defaultConfiguration.hideExpressionErrors
currentConfiguration.altoStringifyEvaluatedExpressions = defaultConfiguration.altoStringifyEvaluatedExpressions
selectAndInspect.onConfigurationChange()
})
on('expressionsToEvaluateChanged', (value: string) => {
currentConfiguration.expressionsToEvaluate = value
selectAndInspect.onConfigurationChange()
})
on('altoStringifyEvaluatedExpressionsChanged', (value: boolean) => {
currentConfiguration.altoStringifyEvaluatedExpressions = value
selectAndInspect.onConfigurationChange()
})
on('hideExpressionErrorsChanged', (value: boolean) => {
currentConfiguration.hideExpressionErrors = value
selectAndInspect.onConfigurationChange()
})
on('formatStringifiedEvaluatedExpressionsChanged', (value: boolean) => {
currentConfiguration.formatStringifiedEvaluatedExpressions = value
selectAndInspect.onConfigurationChange()
})
}

function signedLog(...args: unknown[]) {
Expand All @@ -117,16 +171,19 @@ function signedLog(...args: unknown[]) {
}
function logExpression(expression: string, ...args: unknown[]) {
console.log(
`%c ${expression}`,
`%c └──${expression}`,
'color: #FF7AAC; font-style: italic;',
...args,
)
}
function logExpressionError(expression: string, error: unknown) {
function logExpressionError(expression: string, ...args: unknown[]) {
console.log(
`%c ${expression}`,
'color: #FF7AAC; font-style: italic;',
`%c ${error}`,
'color: #a3120a;',
`%c └──${expression} 🚨`,
'color: #A3120A; font-style: italic;',
...args,
)
}

function stringifyError(error: unknown) {
return error instanceof Error ? error.message : `${error}`
}
80 changes: 27 additions & 53 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,40 @@
// TYPES
// --------------------------------------------------

/**
* Contain all the Figma prototype-related but agnostic data useful to generate the state machine.
* The object is a proxy between the traversed Figma document and the state machine generators.
*/
export interface FigmaAgnosticDescriptor {
readonly pageName: string
/**
* A tree that reflects the Figma document structure, which contains only the frames and the
* interactive nodes that belong to the frames. Compared to a standard tree, there are multiple
* root frames.
*/
readonly simplifiedFrames: SimplifiedFrames

export interface LogOptions {
enabled: boolean
expressionsToEvaluate: string
hideExpressionErrors: boolean
altoStringifyEvaluatedExpressions: boolean
}

export type SimplifiedFrames = SimplifiedFrame[]

export type SimplifiedFrame = Pick<FrameNode, 'id' | 'name'> & {
reactionsData: ReactionData[]
}

export type ReactionData = ReactionDataCommonProperties & ReactionDataTriggerProperties & ReactionDataNavigationProperties

export interface ReactionDataCommonProperties {
// The node name or the name of the first text element found inside
generatedName: string
export interface UiOptions {
enabled: boolean
expandedUi: boolean
expressionsToEvaluate: string
hideExpressionErrors: boolean
altoStringifyEvaluatedExpressions: boolean
}

export type ReactionDataTriggerProperties = {
triggerType: 'ON_CLICK' | 'ON_DRAG'
export type UiEvents = {
type: 'resetToDefaultUiOptions'
} | {
type: 'enabledChanged'
value: boolean
}
| {
triggerType: 'MOUSE_ENTER' | 'MOUSE_LEAVE' | 'MOUSE_UP' | 'MOUSE_DOWN'

// In the Figma UI, the delay can be set only if the device is mobile and the events are
// MOUSE_LEAVE, MOUSE_ENTER, TOUCH_DOWN, TOUCH_UP even if the TOUCH events are typed as mouse
// ones. It's better to specify this detail in the docs. If the delay is 0, the property is not defined
delay?: MillisecondsGreaterThanZero
type: 'expandedUiChanged'
value: boolean
}

type ReactionDataNavigationProperties = {
navigationType: 'NAVIGATE'
destinationFrameId: string
destinationFrameName: string
} | {
navigationType: 'SCROLL_TO'
destinationNodeId: string
destinationNodeName: string
| {
type: 'expressionsToEvaluateChanged'
value: string
}

type MillisecondsGreaterThanZero = number

// --------------------------------------------------
// GUARDS
// --------------------------------------------------

export function isFrame(node: SceneNode): node is FrameNode {
return node.type === 'FRAME'
| {
type: 'altoStringifyEvaluatedExpressionsChanged'
value: string
}

export function isGroup(node: BaseNode): node is GroupNode {
return node.type === 'GROUP'
| {
type: 'hideExpressionErrorsChanged'
value: boolean
}
Loading

0 comments on commit 8b3e347

Please sign in to comment.