-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): added fontSize and basic implementation of textStyles
started adding font-related slices, added a basic implementation of a dropdown wip #22
- Loading branch information
1 parent
dea53c6
commit a27d854
Showing
21 changed files
with
638 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { StateKeys } from "../../constants"; | ||
import { DropdownItem } from "./DropdownItem"; | ||
import { DropdownItemModel, DropdownSetItem } from "./types"; | ||
const { widget } = figma; | ||
const { SVG, Text, AutoLayout, useSyncedState } = widget; | ||
|
||
type Props = { | ||
label: string; | ||
items: DropdownItemModel[]; | ||
selectedId: string; | ||
setNewItem: DropdownSetItem; | ||
}; | ||
|
||
export const Dropdown = ({ label, items, selectedId, setNewItem }: Props) => { | ||
const svg = ` | ||
<svg width='7' height='7' viewBox='0 0 7 7' fill='none' xmlns='http://www.w3.org/2000/svg'> | ||
<path d='M3.5 7L0.468911 1.75L6.53109 1.75L3.5 7Z' fill='black'/> | ||
</svg> | ||
`; | ||
|
||
const [isVisible, setIsVisible] = useSyncedState( | ||
StateKeys.IsDropdownVisible, | ||
false | ||
); | ||
|
||
const selected = items.find((item) => item.id === selectedId); | ||
const filteredItems = items.filter((item) => item.id !== selectedId); | ||
|
||
return ( | ||
<AutoLayout | ||
name="Dropdown" | ||
overflow="visible" | ||
direction="vertical" | ||
spacing={5} | ||
verticalAlignItems="start" | ||
onClick={() => setIsVisible((prev) => !prev)} | ||
> | ||
<Text | ||
name="Label" | ||
fill="#000" | ||
fontFamily="Inter" | ||
fontSize={13} | ||
fontWeight={700} | ||
> | ||
{label} | ||
</Text> | ||
<AutoLayout | ||
name="Frame 4" | ||
fill="#FFF" | ||
stroke="#000" | ||
cornerRadius={4} | ||
strokeWidth={0.5} | ||
spacing={10} | ||
padding={{ | ||
vertical: 4, | ||
horizontal: 6, | ||
}} | ||
verticalAlignItems="center" | ||
> | ||
<Text | ||
name="S" | ||
fill="#000" | ||
fontFamily="Inter" | ||
fontSize={11} | ||
fontWeight={500} | ||
> | ||
{selected?.name} | ||
</Text> | ||
<SVG name="Icon" height={7} width={7} src={svg} /> | ||
</AutoLayout> | ||
<AutoLayout | ||
verticalAlignItems="center" | ||
fill="#FFF" | ||
stroke="#000" | ||
cornerRadius={4} | ||
strokeWidth={0.5} | ||
width="fill-parent" | ||
direction="vertical" | ||
y={50} | ||
hidden={!isVisible} | ||
> | ||
{filteredItems.map((item) => ( | ||
<DropdownItem key={item.id} {...item} setNewItem={setNewItem} /> | ||
))} | ||
</AutoLayout> | ||
</AutoLayout> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { DropdownItemModel, DropdownSetItem } from "./types"; | ||
|
||
const { widget } = figma; | ||
const { Text, AutoLayout } = widget; | ||
|
||
interface Props extends DropdownItemModel { | ||
setNewItem: DropdownSetItem; | ||
} | ||
|
||
export const DropdownItem = ({ name, id, setNewItem }: Props) => { | ||
return ( | ||
<AutoLayout | ||
hoverStyle={{ fill: { r: 0.5, g: 0.5, b: 0.5, a: 0.2 } }} | ||
onClick={() => setNewItem(id)} | ||
width="fill-parent" | ||
padding={{ | ||
vertical: 4, | ||
horizontal: 6, | ||
}} | ||
fill="#FFF" | ||
> | ||
<Text | ||
name="S" | ||
fill="#000" | ||
fontFamily="Inter" | ||
fontSize={11} | ||
fontWeight={500} | ||
> | ||
{name} | ||
</Text> | ||
</AutoLayout> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export interface DropdownItemModel { | ||
id: string; | ||
name: string; | ||
} | ||
|
||
export type DropdownSetItem = (id: string) => void; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { FontSliceItem, Slice, Store } from "../../types"; | ||
import { DeleteButton } from "../Buttons/DeleteButton"; | ||
import { deleteFontSize } from "./deleteFontSize"; | ||
|
||
const { widget } = figma; | ||
const { Frame, Text, Input, AutoLayout, Rectangle } = widget; | ||
|
||
interface Props extends FontSliceItem { | ||
store: Store; | ||
} | ||
|
||
export const FontSizeSlice = ({ store, ...slice }: Props) => { | ||
const { [Slice.FontSizes]: fontSizesMap, [Slice.TextStyles]: textStylesMap } = | ||
store; | ||
const boxSize = slice.value > 41 ? slice.value : 41; | ||
const deleteSlice = () => | ||
deleteFontSize({ id: slice.id, fontSizesMap, textStylesMap }); | ||
return ( | ||
<AutoLayout | ||
name="Font size Slice" | ||
strokeWidth={0} | ||
overflow="visible" | ||
direction="horizontal" | ||
verticalAlignItems="center" | ||
spacing={8} | ||
key={slice.id} | ||
> | ||
<Frame width={boxSize} height={boxSize}> | ||
<AutoLayout | ||
height={boxSize} | ||
width={boxSize} | ||
direction="horizontal" | ||
spacing={2} | ||
horizontalAlignItems="center" | ||
verticalAlignItems="center" | ||
> | ||
<Text | ||
name="A" | ||
fill="#000" | ||
width="hug-contents" | ||
height="hug-contents" | ||
fontFamily="Inter" | ||
fontSize={slice.value} | ||
> | ||
A | ||
</Text> | ||
<AutoLayout | ||
name="Frame6" | ||
strokeWidth={0.5} | ||
direction="vertical" | ||
width={slice.value / 5} | ||
height={slice.value} | ||
verticalAlignItems="center" | ||
horizontalAlignItems="center" | ||
> | ||
<Rectangle | ||
name="Rectangle 25" | ||
fill="#DD00E1" | ||
width="fill-parent" | ||
height={1} | ||
/> | ||
<Rectangle | ||
name="Rectangle 23" | ||
fill="#DD00E1" | ||
width={1} | ||
height="fill-parent" | ||
/> | ||
<Rectangle | ||
name="Rectangle 25" | ||
fill="#DD00E1" | ||
width="fill-parent" | ||
height={1} | ||
/> | ||
</AutoLayout> | ||
</AutoLayout> | ||
<DeleteButton onClick={deleteSlice} width={boxSize} height={boxSize} /> | ||
</Frame> | ||
<AutoLayout direction="vertical" spacing={2}> | ||
<Input | ||
name={slice.name} | ||
x={48} | ||
y={2} | ||
fill="#000" | ||
fontFamily="Inter" | ||
fontWeight={700} | ||
value={slice.name} | ||
width={40} | ||
inputBehavior="truncate" | ||
inputFrameProps={{ direction: "horizontal" }} | ||
onTextEditEnd={() => {}} | ||
/> | ||
<Input | ||
width="fill-parent" | ||
name="Font size value" | ||
x={48} | ||
y={21} | ||
fill="#000" | ||
fontFamily="Inter" | ||
fontSize={10} | ||
fontWeight={500} | ||
strokeWidth={1} | ||
value={`${slice.value}`} | ||
onTextEditEnd={() => {}} | ||
/> | ||
</AutoLayout> | ||
</AutoLayout> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { Slice, Store } from "../../types"; | ||
import { AddButton } from "../Buttons/AddButton"; | ||
import { FontSizeSlice } from "./FontSizeSlice"; | ||
const { widget } = figma; | ||
const { Text, AutoLayout } = widget; | ||
|
||
type Props = { | ||
store: Store; | ||
}; | ||
|
||
export const FontSizeSlices = ({ store }: Props) => { | ||
const add = () => {}; | ||
return ( | ||
<AutoLayout | ||
name="Font sizes frame" | ||
strokeWidth={0} | ||
overflow="visible" | ||
direction="vertical" | ||
spacing={30} | ||
> | ||
<AutoLayout | ||
verticalAlignItems="center" | ||
spacing={10} | ||
name="Group 10" | ||
strokeWidth={0} | ||
overflow="visible" | ||
width={102} | ||
height={35} | ||
> | ||
<Text | ||
name="Font sizes" | ||
fill="#000" | ||
fontFamily="Inter" | ||
fontSize={28} | ||
fontWeight={500} | ||
strokeWidth={2} | ||
> | ||
Font sizes | ||
</Text> | ||
<AddButton onClick={add} /> | ||
</AutoLayout> | ||
<AutoLayout | ||
name="Frame 2" | ||
y={65} | ||
overflow="visible" | ||
spacing={40} | ||
direction="horizontal" | ||
verticalAlignItems="center" | ||
> | ||
{store[Slice.FontSizes].values().map((fontSize) => ( | ||
<FontSizeSlice {...fontSize} store={store} /> | ||
))} | ||
</AutoLayout> | ||
</AutoLayout> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { mockSyncedMap } from "../../test-utils/mockSyncedMap"; | ||
import { FontSliceItem, TextStyleSliceItem } from "../../types"; | ||
import { deleteFontSize } from "./deleteFontSize"; | ||
|
||
describe("deleteFontSize", () => { | ||
it("should delete a fontSize and replace the reference on textStyles when is used in one of them", () => { | ||
const fontSizesMap = mockSyncedMap<FontSliceItem>({ | ||
"font-size-1": { id: "font-size-1", name: "any name", value: 10 }, | ||
"font-size-2": { id: "font-size-2", name: "any name", value: 20 }, | ||
}); | ||
const textStylesMap = mockSyncedMap<TextStyleSliceItem>({ | ||
"text-style-1": { | ||
id: "text-style-1", | ||
name: "any name", | ||
fontSizeId: "font-size-1", | ||
}, | ||
}); | ||
deleteFontSize({ id: "font-size-1", fontSizesMap, textStylesMap }); | ||
|
||
expect(fontSizesMap.delete).toBeCalledTimes(1); | ||
expect(fontSizesMap.delete).toBeCalledWith("font-size-1"); | ||
expect(textStylesMap.set).toBeCalledWith("text-style-1", { | ||
id: "text-style-1", | ||
name: "any name", | ||
fontSizeId: "font-size-2", | ||
}); | ||
}); | ||
it("should prevent the user to delete all slices", () => { | ||
const fontSizesMap = mockSyncedMap<FontSliceItem>({ | ||
"font-size-1": { id: "font-size-1", name: "any name", value: 10 }, | ||
}); | ||
const textStylesMap = mockSyncedMap<TextStyleSliceItem>(); | ||
deleteFontSize({ id: "font-size-1", fontSizesMap, textStylesMap }); | ||
|
||
expect(fontSizesMap.delete).not.toBeCalled(); | ||
expect(figma.notify).toBeCalledTimes(1); | ||
expect(figma.notify).toBeCalledWith( | ||
expect.any(String), | ||
expect.objectContaining({ error: true }) | ||
); | ||
}); | ||
}); |
Oops, something went wrong.