-
Notifications
You must be signed in to change notification settings - Fork 1
/
code.tsx
269 lines (244 loc) · 8.56 KB
/
code.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
This is Figma widget that contains a basic, best-practice checklist for design system component development
When placed on the Figma canvas near a component, the idea is that the checklist items help ensure the component is properly structured and robust enough for use in a design system setting.
*/
const { widget } = figma
const { useSyncedState, AutoLayout, Text, SVG } = widget
// src for SVG element for the various statuses
const successIcon = `
<svg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path d='M0 16C0 7.1625 7.1625 0 16 0C24.8375 0 32 7.1625 32 16C32 24.8375 24.8375 32 16 32C7.1625 32 0 24.8375 0 16ZM23.2375 13.2375C23.9187 12.5563 23.9187 11.4437 23.2375 10.7625C22.5562 10.0813 21.4438 10.0813 20.7625 10.7625L14 17.525L11.2375 14.7625C10.5563 14.0813 9.44375 14.0813 8.7625 14.7625C8.08125 15.4437 8.08125 16.5562 8.7625 17.2375L12.7625 21.2375C13.4437 21.9187 14.5563 21.9187 15.2375 21.2375L23.2375 13.2375Z' fill='#009B06'/>
</svg>
`
const undeterminedIcon = `
<svg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path d='M31.5 16C31.5 24.5614 24.5614 31.5 16 31.5C7.43864 31.5 0.5 24.5614 0.5 16C0.5 7.43864 7.43864 0.5 16 0.5C24.5614 0.5 31.5 7.43864 31.5 16Z' fill='white' stroke='#B1B1B1'/>
</svg>
`
const failureIcon = `
<svg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path d='M0 16C0 7.1625 7.1625 0 16 0C24.8375 0 32 7.1625 32 16C32 24.8375 24.8375 32 16 32C7.1625 32 0 24.8375 0 16ZM10.9375 13.0063L13.8813 15.9438L10.9375 18.9375C10.3562 19.525 10.3562 20.475 10.9375 21.0063C11.525 21.6438 12.475 21.6438 13.0063 21.0063L15.9438 18.1187L18.9375 21.0063C19.525 21.6438 20.475 21.6438 21.0063 21.0063C21.6438 20.475 21.6438 19.525 21.0063 18.9375L18.1187 15.9438L21.0063 13.0063C21.6438 12.475 21.6438 11.525 21.0063 10.9375C20.475 10.3562 19.525 10.3562 18.9375 10.9375L15.9438 13.8813L13.0063 10.9375C12.475 10.3562 11.525 10.3562 10.9375 10.9375C10.3562 11.525 10.3562 12.475 10.9375 13.0063Z' fill='#C20000'/>
</svg>
`
const notApplicableIcon = `
<svg width='32' height='32' viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path d='M0 16C0 7.1625 7.1625 0 16 0C24.8375 0 32 7.1625 32 16C32 24.8375 24.8375 32 16 32C7.1625 32 0 24.8375 0 16ZM10.5 14.5C9.66875 14.5 9 15.1687 9 16C9 16.8312 9.66875 17.5 10.5 17.5H21.5C22.3312 17.5 23 16.8312 23 16C23 15.1687 22.3312 14.5 21.5 14.5H10.5Z' fill='#6B6B6B'/>
</svg>
`
function Widget() {
// available status labels and icons
const statusIcons = [
{
label: "Undetermined",
icon: undeterminedIcon
},
{
label: "Success",
icon: successIcon
},
{
label: "Failure",
icon: failureIcon
},
{
label: "Not applicable",
icon: notApplicableIcon
}
]
// initial state
const initialRubricItems = [
{
position: 0,
title: "Name",
criteria: "Is the name of the component consistent with the codebase and documentation?",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 1,
title: "Layers",
criteria: "Are layer names formatted with meaningful values? (No Frame 234)",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 2,
title: "Color styles",
criteria: "Are all the colors from a style library / token and not hard-coded?",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 3,
title: "Text styles",
criteria: "Is each text layer from a defined text style library / token?",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 4,
title: "Spacing, padding and alignment",
criteria: "Are spacing, padding, and alignment values consistently applied and visually aligned?",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 5,
title: "Variants and component properties",
criteria: "Are variant and component properties correctly named? Consistent with code and among other components?",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 6,
title: "States",
criteria: "Are all the interactive states accounted for? (e.g., hover, focus, pressed)",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 7,
title: "Content",
criteria: "Does the component behave as expected with non-optimal concent is present? (e.g., long strings)",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 8,
title: "Layout",
criteria: "Does the component behave as expected when resized? (e.g., wrapping, alignment, text layer flow)",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 9,
title: "Configuration",
criteria: "Can all the required variations and states be acheived through the component properties panel? \n(e.g., no digging through Layers)",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
},
{
position: 10,
title: "Accessibility",
criteria: "Are color combinations accessible WCAG AAA compliant? Do focusable elements have a defined focus order?",
status: {
label: "Undetermined",
icon: undeterminedIcon
}
}
]
const [rubricItems, setRubricItems] = useSyncedState ('rubricItems', () => initialRubricItems)
const [lastUpdate, setLastUpdate] = useSyncedState('lastUpdate', null)
function getNextStatus (currentStatus) {
// based on the current status, find the next status and return it
const currentIndex = statusIcons.findIndex(item => item.label === currentStatus)
if(currentIndex >= 0 && currentIndex < statusIcons.length - 1) {
return statusIcons[currentIndex+1]
} else if (currentIndex === statusIcons.length -1) {
return statusIcons[0]
} else {
throw Error ("Status out of bounds")
}
}
function cycleStatus (item) {
// click event copies current updates the selected item status to the next status
setRubricItems(rubricItems => {
const temp = [...rubricItems]
temp[item.position].status = getNextStatus(item.status.label)
setLastUpdate(item.position)
return temp
})
}
return (
<AutoLayout
direction="vertical"
fill="#FFFFFF"
spacing={32}
padding={{
top: 12,
right: 32,
bottom: 12,
left: 32
}}>
{(lastUpdate !== null) ?
<Text fill="#999" fontSize={14}>{`${rubricItems[lastUpdate].title} set to "${rubricItems[lastUpdate].status.label}"`}</Text>
:
<Text fill="#999" fontSize={14}>Toggle checklist status to success, failure, or not applicable</Text>
}
{
rubricItems.map((item, index) => {
return (
<AutoLayout
key={index}
name="Rubric"
overflow="visible"
spacing={24}
width={900}
verticalAlignItems="start"
padding={{
top: 0,
right: 0,
bottom: 12,
left: 0,
}}
>
<AutoLayout
name="Status"
overflow="visible"
horizontalAlignItems="end"
verticalAlignItems="center"
>
<SVG src={item.status.icon} onClick={() => cycleStatus(item)} />
</AutoLayout>
<AutoLayout
name="Rubric Text"
overflow="visible"
direction="vertical"
spacing={8}
width="fill-parent"
>
<Text
name="Title"
fill="#000"
fontFamily="Inter"
fontSize={20}
fontWeight={500}
>
{item.title}
</Text>
<Text
name="Description"
fill="#555"
fontFamily="Inter"
>
{item.criteria}
</Text>
</AutoLayout>
</AutoLayout>
)
})
}
</AutoLayout>
)
}
widget.register(Widget)