Skip to content

Commit

Permalink
feat: added snowflake checklist widget and fixed the component struct…
Browse files Browse the repository at this point in the history
…ure for better reusability (#2378)

* add: snowflake checklist and fixed the component structure for reusability

* fix: readme image for dev handoff checklist

* fix: readme added image border for dev handoff checklist

* fix: manifest version for snowflake handoff checklist widget

* feat: added review list to snowflake and improved checkbox & listview components

* fix: removed spell errors from snowflake handoff checklsit widget

* fix: restructure

* chore: lint errors

---------

Co-authored-by: kamleshchandnani <[email protected]>
  • Loading branch information
saurav12 and kamleshchandnani authored Nov 8, 2024
1 parent ff1f383 commit a7b8302
Show file tree
Hide file tree
Showing 19 changed files with 371 additions and 112 deletions.
10 changes: 7 additions & 3 deletions packages/plugin-figma-blade-coverage/manifest.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{
"api": "1.0.0",
"editorType": ["figma"],
"id": "",
"editorType": [
"figma"
],
"id": "1258393250170675750",
"name": "Blade Coverage",
"main": "build/main.js",
"ui": "build/ui.js",
"permissions": ["currentuser"],
"permissions": [
"currentuser"
],
"enablePrivatePluginApi": true
}
63 changes: 0 additions & 63 deletions packages/widget-dev-handoff-checklist/components/ListView.tsx

This file was deleted.

Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ node_modules
out/
dist/
code.js
.env
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/no-empty-function */
import React from 'react';
const { AutoLayout, SVG: Svg, Text, Input, useSyncedState } = figma.widget;

interface CheckboxProps {
id: string;
optionText?: string;
helpText?: string;
isEditable?: boolean;
isEditablePlaceholderText?: string;
isEditableInputWithDateField?: boolean;
onCheckboxClick: (checkedState: true | false) => void;
}

Expand All @@ -15,6 +18,8 @@ function Checkbox({
optionText = 'An option text',
helpText,
isEditable = false,
isEditablePlaceholderText = "Reviewer's Name",
isEditableInputWithDateField = false,
onCheckboxClick,
}: CheckboxProps) {
const [isChecked, setChecked] = useSyncedState(`${id}_checked`, false);
Expand Down Expand Up @@ -75,7 +80,7 @@ function Checkbox({
</Text>
<Input
value={optionTextInput}
placeholder={"<Reviewer's Name>"}
placeholder={`<${isEditablePlaceholderText}>`}
onTextEditEnd={(e) => setOptionTextInput(e.characters)}
fontSize={14}
fontWeight={600}
Expand All @@ -97,7 +102,33 @@ function Checkbox({
{optionText}
</Text>
)}
{(helpText || isEditable) &&
{isEditable && isEditableInputWithDateField ? (
<Input
value={helpTextInput}
placeholder="<Review date>"
onTextEditEnd={(e) => setHelpTextInput(e.characters)}
fontSize={11}
fontWeight={400}
lineHeight={16}
fill="#768EA7"
italic={true}
width="fill-parent"
hoverStyle={{ fill: '#305EFF' }}
/>
) : null}
{helpText ? (
<Text
fontSize={11}
fontWeight={400}
lineHeight={16}
fill="#768EA7"
italic={true}
width="fill-parent"
>
{helpText}
</Text>
) : null}
{/* {(helpText || isEditableInputWithDateField) &&
(isEditable ? (
<Input
value={helpTextInput}
Expand All @@ -122,7 +153,7 @@ function Checkbox({
>
{helpText}
</Text>
))}
))} */}
</AutoLayout>
</AutoLayout>
</AutoLayout>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import React from 'react';
const { AutoLayout, Text, Input, useSyncedState } = figma.widget;

interface ListViewProps {
id: string;
listText: string;
helpText?: string;
isEditable?: boolean;
isEditablePlaceholderText?: string;
isEditableHelpText?: boolean;
isEditablePlaceholderHelpText?: string;
}

function ListView({
id,
listText,
helpText,
isEditable = false,
isEditableHelpText = false,
isEditablePlaceholderText = "<Reviewer's Name>",
isEditablePlaceholderHelpText = '<Review Date>',
}: ListViewProps) {
const [listTextInput, setListTextInput] = useSyncedState(`${id}_listInputText`, '');
const [dateTextInput, setDateTextInput] = useSyncedState(`${id}_dateInputText`, '');

return (
<AutoLayout
padding={{ horizontal: 4, vertical: 2 }}
cornerRadius={4}
direction="horizontal"
spacing={4}
width="fill-parent"
>
<AutoLayout verticalAlignItems="center" horizontalAlignItems="center" width={20} height={20}>
<Text fontSize={14} fontWeight={400} lineHeight={20} fill="#768EA7">
</Text>
</AutoLayout>
<AutoLayout direction="vertical" width="fill-parent">
<AutoLayout direction="horizontal" wrap={true} spacing={4} width="fill-parent">
<Text fontSize={14} fontWeight={400} lineHeight={20} fill="#40566D">
{listText}
</Text>
{isEditable ? (
<Input
value={listTextInput}
placeholder={`<${isEditablePlaceholderText}>`}
onTextEditEnd={(e) => setListTextInput(e.characters)}
fontSize={14}
fontWeight={600}
lineHeight={20}
fill="#40566D"
width="fill-parent"
hoverStyle={{ fill: '#305EFF' }}
/>
) : null}
</AutoLayout>
{helpText ? (
<AutoLayout direction="horizontal" wrap={true} spacing={4} width="fill-parent">
<Text fontSize={11} fontWeight={400} lineHeight={16} fill={'#768EA7'} italic={true}>
{helpText}
</Text>
</AutoLayout>
) : null}
{isEditableHelpText ? (
<AutoLayout direction="horizontal" wrap={true} spacing={4} width="fill-parent">
<Input
value={dateTextInput}
placeholder={`<${isEditablePlaceholderHelpText}>`}
onTextEditEnd={(e) => setDateTextInput(e.characters)}
fontSize={11}
fontWeight={400}
lineHeight={16}
italic={true}
fill="#768EA7"
width="fill-parent"
hoverStyle={{ fill: '#305EFF' }}
/>
</AutoLayout>
) : null}
</AutoLayout>
</AutoLayout>
);
}

export default ListView;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/no-empty-function */
import React from 'react';
import SectionHeader from './SectionHeader';
const { AutoLayout, Text } = figma.widget;

interface ProgressBarProps {
cardWidgetWidth: number;
numberOfCheckboxes: number;
checkedItems: number;
}

function ProgressBar({ cardWidgetWidth, numberOfCheckboxes, checkedItems }: ProgressBarProps) {
const isAllCheckboxesChecked = checkedItems === numberOfCheckboxes;

return (
<AutoLayout
direction="horizontal"
spacing="auto"
cornerRadius={4}
padding={{ horizontal: 8, vertical: 4 }}
width="fill-parent"
height={20}
fill="#ECF1FF"
>
<AutoLayout
positioning="absolute"
x={0}
y={0}
width={checkedItems === 0 ? 1 : checkedItems * (cardWidgetWidth / numberOfCheckboxes)}
height={20}
fill={isAllCheckboxesChecked ? '#00A251' : '#D0DBFF'}
/>
<Text fontSize={10} fontWeight={600} fill={isAllCheckboxesChecked ? '#ffffff' : '#768EA7'}>
{isAllCheckboxesChecked ? '🎉 Ready for handoff!' : '😕 Not ready for handoff'}
</Text>
<SectionHeader
title={`${checkedItems}/${numberOfCheckboxes}`}
color={isAllCheckboxesChecked ? '#ffffff' : '#768EA7'}
/>
</AutoLayout>
);
}

export default ProgressBar;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import React from 'react';
const { AutoLayout, Text } = figma.widget;

interface SectionHeaderProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The Design Handoff Checklist for Figma is a comprehensive tool designed to streamline the final design review process for designers and design leaders before handing off projects to developers. This widget ensures that all edge cases are considered and nothing is overlooked in the final stages of the design process.

![](./figma-handoff-widget.png)
![](./figma-dev-handoff-widget.png)

## Features
* Design reviews
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import Checkbox from './components/Checkbox';
import SectionHeader from './components/SectionHeader';
import Checkbox from '../components/Checkbox';
import SectionHeader from '../components/SectionHeader';
import ProgressBar from '../components/ProgressBar';
const { AutoLayout, Text, useSyncedState } = figma.widget;

function Widget() {
const [checkedItems, setCheckedItems] = useSyncedState('checkedStates', 0);
const cardWidgetWidth = 401;
const numberOfCheckboxes = 14;
const isAllCheckboxesChecked = checkedItems === numberOfCheckboxes;

const updateChecklist = (checkedState: true | false): void => {
if (checkedState) {
Expand All @@ -28,37 +26,9 @@ function Widget() {
>
<AutoLayout direction="vertical" spacing={8} width="fill-parent">
<Text fontSize={28} fontWeight={700} fill="#192839">
✏️ Handoff checklist
✏️ Dev handoff checklist
</Text>
<AutoLayout
direction="horizontal"
spacing="auto"
cornerRadius={4}
padding={{ horizontal: 8, vertical: 4 }}
width="fill-parent"
height={20}
fill="#ECF1FF"
>
<AutoLayout
positioning="absolute"
x={0}
y={0}
width={checkedItems === 0 ? 1 : checkedItems * (cardWidgetWidth / numberOfCheckboxes)}
height={20}
fill={isAllCheckboxesChecked ? '#00A251' : '#D0DBFF'}
/>
<Text
fontSize={10}
fontWeight={600}
fill={isAllCheckboxesChecked ? '#ffffff' : '#768EA7'}
>
{isAllCheckboxesChecked ? '🎉 Ready for handoff!' : '😕 Not ready for handoff'}
</Text>
<SectionHeader
title={`${checkedItems}/${numberOfCheckboxes}`}
color={isAllCheckboxesChecked ? '#ffffff' : '#768EA7'}
/>
</AutoLayout>
<ProgressBar cardWidgetWidth={401} numberOfCheckboxes={14} checkedItems={checkedItems} />
</AutoLayout>
<AutoLayout direction="vertical" spacing={4} width="fill-parent">
<SectionHeader title="Reviewers" />
Expand All @@ -67,18 +37,21 @@ function Widget() {
id="review1"
optionText="Design reviewed by "
isEditable={true}
isEditableInputWithDateField={true}
onCheckboxClick={updateChecklist}
/>
<Checkbox
id="review2"
optionText="Copy reviewed by "
isEditable={true}
isEditableInputWithDateField={true}
onCheckboxClick={updateChecklist}
/>
<Checkbox
id="review3"
optionText="Creatives reviewed by "
isEditable={true}
isEditableInputWithDateField={true}
onCheckboxClick={updateChecklist}
/>
</AutoLayout>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit a7b8302

Please sign in to comment.