├── src
├── actions
│ ├── repeat.ts
│ ├── index.js
│ ├── output-types.ts
│ ├── helper-functions.ts
│ └── random-number.tsx
├── logo.svg
├── components
│ ├── label.tsx
│ ├── app.tsx
│ ├── nav.tsx
│ ├── footer.tsx
│ ├── actions-list.tsx
│ ├── field.tsx
│ ├── nav-button.tsx
│ ├── index.ts
│ ├── action-button.tsx
│ ├── output.tsx
│ ├── automation.tsx
│ ├── input.tsx
│ └── action.tsx
├── code.ts
├── utils.ts
├── hooks
│ ├── use-selection.ts
│ └── Sortable.js
├── store.ts
├── figma-actions.ts
├── io.js
├── ui.html
└── ui.tsx
├── prettier.config.js
├── lib
└── figma-plugin-ds
│ ├── scss
│ ├── base
│ │ ├── _base.scss
│ │ ├── _typography.scss
│ │ ├── _mixins.scss
│ │ └── _variables.scss
│ ├── components
│ │ ├── _divider.scss
│ │ ├── _label.scss
│ │ ├── _section-title.scss
│ │ ├── _onboarding-tip.scss
│ │ ├── _textarea.scss
│ │ ├── _switch.scss
│ │ ├── _checkbox.scss
│ │ ├── _icon.scss
│ │ ├── _button.scss
│ │ ├── _input.scss
│ │ ├── _input-icon.scss
│ │ ├── _disclosure.scss
│ │ ├── _visual-bell.scss
│ │ ├── _type.scss
│ │ └── _select-menu.scss
│ ├── icons
│ │ ├── _plus.scss
│ │ ├── _minus.scss
│ │ ├── _warning.scss
│ │ ├── _layout-align-horiz-cent.scss
│ │ ├── _layout-align-vert-cent.scss
│ │ ├── _star-on.scss
│ │ ├── _type.scss
│ │ ├── _corner-radius.scss
│ │ ├── _play.scss
│ │ ├── _angle.scss
│ │ ├── _frame.scss
│ │ ├── _draft.scss
│ │ ├── _list.scss
│ │ ├── _layout-grid-columns.scss
│ │ ├── _layout-grid-rows.scss
│ │ ├── _stroke-weight.scss
│ │ ├── _dist-vert-spacing.scss
│ │ ├── _instance.scss
│ │ ├── _tidy-up-list-vert.scss
│ │ ├── _layout-align-top.scss
│ │ ├── _layout-align-bottom.scss
│ │ ├── _layout-align-left.scss
│ │ ├── _layout-align-right.scss
│ │ ├── _tidy-up-list-horiz.scss
│ │ ├── _dist-horiz-spacing.scss
│ │ ├── _align-top.scss
│ │ ├── _align-bottom.scss
│ │ ├── _close.scss
│ │ ├── _return.scss
│ │ ├── _resolve-filled.scss
│ │ ├── _arrow-up-down.scss
│ │ ├── _arrow-left-right.scss
│ │ ├── _corners.scss
│ │ ├── _link-broken.scss
│ │ ├── _star-off.scss
│ │ ├── _lock-unlocked.scss
│ │ ├── _animated-fill.scss
│ │ ├── _recent.scss
│ │ ├── _lock.scss
│ │ ├── _list-detailed.scss
│ │ ├── _search-large.scss
│ │ ├── _align-middle.scss
│ │ ├── _eyedropper.scss
│ │ ├── _link-connected.scss
│ │ ├── _ellipses.scss
│ │ ├── _resolve.scss
│ │ ├── _vector-handles.scss
│ │ ├── _comment.scss
│ │ ├── _restore.scss
│ │ ├── _import.scss
│ │ ├── _trash.scss
│ │ ├── _node-connect.scss
│ │ ├── _reset-instance.scss
│ │ ├── _resize-to-fit.scss
│ │ ├── _search.scss
│ │ ├── _tidy-up-grid.scss
│ │ ├── _mask.scss
│ │ ├── _layout-grid-uniform.scss
│ │ ├── _group.scss
│ │ ├── _visible.scss
│ │ ├── _styles.scss
│ │ ├── _hidden.scss
│ │ ├── _adjust.scss
│ │ ├── _hyperlink.scss
│ │ ├── _alert.scss
│ │ ├── _blend.scss
│ │ ├── _image.scss
│ │ ├── _component.scss
│ │ ├── _timer.scss
│ │ ├── _smiley.scss
│ │ ├── _blend-empty.scss
│ │ ├── _break.scss
│ │ ├── _share.scss
│ │ ├── _effects.scss
│ │ └── _library.scss
│ └── figma-plugin-ds.scss
│ └── js
│ ├── disclosure.js
│ ├── iconInput.js
│ └── selectMenu.js
├── publish
├── cover.png
└── icon.png
├── manifest.json
├── .vscode
└── settings.json
├── tsconfig.json
├── README.md
├── LICENSE
├── package.json
├── .gitignore
└── webpack.config.js
/src/actions/repeat.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | export default {}
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/base/_base.scss:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
--------------------------------------------------------------------------------
/publish/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdes/figma-automations/HEAD/publish/cover.png
--------------------------------------------------------------------------------
/publish/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cdes/figma-automations/HEAD/publish/icon.png
--------------------------------------------------------------------------------
/src/actions/index.js:
--------------------------------------------------------------------------------
1 | import RandomNumber from "./random-number";
2 |
3 | export default [RandomNumber];
4 |
--------------------------------------------------------------------------------
/src/actions/output-types.ts:
--------------------------------------------------------------------------------
1 | export const NUMBER = "NUMBER",
2 | STRING = "STRING",
3 | LAYER_ID = "LAYER_ID";
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Automations",
3 | "id": "740887843052935395",
4 | "api": "1.0.0",
5 | "main": "dist/code.js",
6 | "ui": "dist/ui.html"
7 | }
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "workbench.colorCustomizations": {
3 | "activityBar.background": "#013613",
4 | "titleBar.activeBackground": "#014B1A",
5 | "titleBar.activeForeground": "#ECFFF3"
6 | }
7 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "jsx": "react",
6 | "lib": ["es7", "dom"],
7 | "resolveJsonModule": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_divider.scss:
--------------------------------------------------------------------------------
1 | .divider {
2 | display: block;
3 |
4 | width: 100%;
5 | height: 1px;
6 | margin: 8px 0 8px 0;
7 | padding: 0;
8 |
9 | background-color: $figma-silver;
10 | }
11 |
--------------------------------------------------------------------------------
/src/actions/helper-functions.ts:
--------------------------------------------------------------------------------
1 | export function getSupportedOptions(store, currentActionId, OPTION_TYPE) {
2 | const options = Object.keys(store).filter(id => id !== currentActionId).map(id => store[id].option).filter(option => option.type === OPTION_TYPE);
3 | return options;
4 | }
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_label.scss:
--------------------------------------------------------------------------------
1 | .label {
2 | display: flex;
3 | align-items: center;
4 |
5 | height: 32px;
6 | padding: 8px 4px 8px 8px;
7 |
8 | color: $figma-black-3;
9 | background-color: $figma-white;
10 |
11 | @include font-ui-pos('small', 'normal');
12 | }
13 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_section-title.scss:
--------------------------------------------------------------------------------
1 | .section-title {
2 | display: flex;
3 | align-items: center;
4 |
5 | height: 32px;
6 | padding: 8px 4px 8px 8px;
7 |
8 | color: $figma-black-8;
9 | background-color: $figma-white;
10 |
11 | @include font-ui-pos('small', 'bold');
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/label.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.label`
5 | font-size: 12px;
6 | color: #383838;
7 | `;
8 |
9 | const Label = ({ children }) => (
10 |
11 | {children}
12 |
13 | );
14 |
15 | export default Label;
--------------------------------------------------------------------------------
/src/code.ts:
--------------------------------------------------------------------------------
1 | import { script as io } from './io';
2 |
3 | figma.showUI(__html__, {
4 | width: 504,
5 | height: 640,
6 | });
7 |
8 | io.on("run", (automation) => {
9 | // automation
10 | });
11 |
12 | setInterval(() => {
13 | const { selection } = figma.currentPage;
14 |
15 | io.send("selection", selection.map(s => ({
16 | id: s.id,
17 | width: s.width,
18 | height: s.height,
19 | })));
20 | }, 150);
21 |
--------------------------------------------------------------------------------
/src/components/app.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.div`
5 | display: flex;
6 | flex-direction: row;
7 | justify-content: space-between;
8 | align-items: flex-start;
9 | overflow: hidden;
10 | max-height: 100%;
11 | `;
12 |
13 | const App = ({ children }) => (
14 |
15 | {children}
16 |
17 | );
18 |
19 | export default App;
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const setPosition = (node, x: number, y: number) => {
2 | node.relativeTransform = [[1, 0, x], [0, 1, y]];
3 | };
4 |
5 | export const getNodesByIds = (ids: string[]) => {
6 | const all = figma.currentPage.findAll(n => ids.includes(n.id));
7 | return (figma.currentPage.selection = [].concat(all));
8 | };
9 |
10 | export const selectAll = (page: PageNode) => {
11 | const all = figma.currentPage.findAll();
12 | page.selection = [].concat(all);
13 | };
14 |
--------------------------------------------------------------------------------
/src/components/nav.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.div`
5 | background-color: #333;
6 | display: flex;
7 | flex-direction: row;
8 | justify-content: space-between;
9 | align-items: center;
10 | overflow: hidden;
11 | width: 304px;
12 | position: fixed;
13 | top: 0;
14 | left: 0;
15 | `;
16 |
17 | const Nav = ({ children }) => (
18 |
19 | {children}
20 |
21 | );
22 |
23 | export default Nav;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_plus.scss:
--------------------------------------------------------------------------------
1 | .icon--plus {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m15.5 15.5v-5h1v5h5v1h-5v5h-1v-5h-5v-1z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m15.5 47.5v-5h1v5h5v1h-5v5h-1v-5h-5v-1z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m15.5 79.5v-5h1v5h5v1h-5v5h-1v-5h-5v-1z" fill="%2318a0fb"/%3E%3Cpath d="m15.5 111.5v-5h1v5h5v1h-5v5h-1v-5h-5v-1z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/footer.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.div`
5 | background: #F3F5F8;
6 | padding: 8px;
7 | font-size: 12px;
8 | color: #383838;
9 | display: flex;
10 | flex-direction: row;
11 | justify-content: space-between;
12 | align-items: center;
13 | border-radius: 0 0 8px 8px;
14 | `;
15 |
16 | const Footer = ({ children }) => (
17 |
18 | {children}
19 |
20 | );
21 |
22 | export default Footer;
--------------------------------------------------------------------------------
/src/components/actions-list.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.div`
5 | background-color: #eee;
6 | display: flex;
7 | flex-direction: column;
8 | justify-content: flex-start;
9 | align-items: stretch;
10 | overflow-y: scroll;
11 | width: 200px;
12 | height: 100%;
13 | min-height: 100%;
14 | `;
15 |
16 | const ActionsList = ({ children }) => (
17 |
18 | {children}
19 |
20 | );
21 |
22 | export default ActionsList;
--------------------------------------------------------------------------------
/src/components/field.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.div`
5 | background: #fff;
6 | padding: 8px;
7 | display: flex;
8 | flex-direction: row;
9 | justify-content: space-between;
10 | align-items: center;
11 | border-bottom: 1px solid #F3F5F8;
12 |
13 | :last-child {
14 | border: none;
15 | }
16 | `;
17 |
18 | const Field = ({ children }) => (
19 |
20 | {children}
21 |
22 | );
23 |
24 | export default Field;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_minus.scss:
--------------------------------------------------------------------------------
1 | .icon--minus {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cg clip-rule=\'evenodd\' fill-rule=\'evenodd\'%3E%3Cpath d=\'m21.5 16.5h-11v-1h11z\' fill=\'%23000\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m21.5 48.5h-11v-1h11z\' fill=\'%23000\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m21.5 80.5h-11v-1h11z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m21.5 112.5h-11v-1h11z\' fill=\'%23fff\'/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/hooks/use-selection.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { html as io } from '../io.js';
3 |
4 | const { useState, useEffect } = React;
5 |
6 | export default function useSelection(){
7 | const [selection, setSelection] = useState([]);
8 |
9 | function onSelection(newSelection) {
10 | setSelection(newSelection);
11 | }
12 |
13 | useEffect(() => {
14 | io.on("selection", onSelection);
15 |
16 | return () => {
17 | io.off("selection", onSelection);
18 | }
19 | }, [selection]);
20 |
21 | return selection;
22 | };
--------------------------------------------------------------------------------
/src/components/nav-button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.button`
5 | background: #333;
6 | border-radius: 40px;
7 | display: flex;
8 | justify-content: center;
9 | align-items: center;
10 | height: 40px;
11 | border: none;
12 | color: white;
13 | font-weight: bold;
14 | min-width: 40px;
15 | `;
16 |
17 | const NavButton = ({ children, onClick }) => (
18 |
19 | {children}
20 |
21 | );
22 |
23 | export default NavButton;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_warning.scss:
--------------------------------------------------------------------------------
1 | .icon--warning {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m16 38 10 18h-20zm-1 11v-4h2v4zm0 2v2h2v-2z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16 6 10 18h-20zm-1 11v-4h2v4zm0 2v2h2v-2z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16 70 10 18h-20zm-1 11v-4h2v4zm0 2v2h2v-2z" fill="%2318a0fb"/%3E%3Cpath d="m16 102 10 18h-20zm-1 11v-4h2v4zm0 2v2h2v-2z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/store.ts:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | interface IContext {
4 | store: object;
5 | dispatch: Function;
6 | }
7 |
8 | export const Context = React.createContext({});
9 |
10 | export function reducer(state: any, action) : any {
11 | switch (action.type) {
12 | case "random-number": {
13 | const oldState = state[action.id] || {};
14 | return {
15 | ...state,
16 | [action.id]: {
17 | ...oldState,
18 | ...action.state,
19 | }
20 | };
21 | }
22 | default: {
23 | return state;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export { default as ActionButton } from './action-button';
2 | export { default as Action } from './action';
3 | export { default as ActionsList } from './actions-list';
4 | export { default as App } from './app';
5 | export { default as Automation } from './automation';
6 | export { default as Field } from './field';
7 | export { default as Footer } from './footer';
8 | export { default as Input } from './input';
9 | export { default as Label } from './label';
10 | export { default as NavButton } from './nav-button';
11 | export { default as Nav } from './nav';
12 | export { default as Output } from './output';
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-align-horiz-cent.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-align-horiz-cent {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m16.5 9.5h-1v3h-5v2h5v3h-3v2h3v3h1v-3h3v-2h-3v-3h5v-2h-5z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16.5 41.5h-1v3h-5v2h5v3h-3v2h3v3h1v-3h3v-2h-3v-3h5v-2h-5z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16.5 73.5h-1v3h-5v2h5v3h-3v2h3v3h1v-3h3v-2h-3v-3h5v-2h-5z" fill="%2318a0fb"/%3E%3Cpath d="m16.5 105.5h-1v3h-5v2h5v3h-3v2h3v3h1v-3h3v-2h-3v-3h5v-2h-5z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-align-vert-cent.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-align-vert-cent {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m12.5 15.5v-5h2v5h3v-3h2v3h3v1h-3v3h-2v-3h-3v5h-2v-5h-3v-1z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m12.5 47.5v-5h2v5h3v-3h2v3h3v1h-3v3h-2v-3h-3v5h-2v-5h-3v-1z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m12.5 79.5v-5h2v5h3v-3h2v3h3v1h-3v3h-2v-3h-3v5h-2v-5h-3v-1z" fill="%2318a0fb"/%3E%3Cpath d="m12.5 111.5v-5h2v5h3v-3h2v3h3v1h-3v3h-2v-3h-3v5h-2v-5h-3v-1z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_star-on.scss:
--------------------------------------------------------------------------------
1 | .icon--star-on {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m16 8 2 6 6-.0141-5 4.0141 2 6-5-3.7945-5 3.7945 2-6-5-4.0141 6 .0141z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16 40 2 6 6-.0141-5 4.0141 2 6-5-3.7945-5 3.7945 2-6-5-4.0141 6 .0141z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16 72 2 6 6-.0141-5 4.0141 2 6-5-3.7945-5 3.7945 2-6-5-4.0141 6 .0141z" fill="%2318a0fb"/%3E%3Cpath d="m16 104 2 6 6-.014-5 4.014 2 6-5-3.794-5 3.794 2-6-5-4.014 6 .014z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_type.scss:
--------------------------------------------------------------------------------
1 | .icon--type {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m10 10h11v3h-1v-2h-4v9.9986h1.9442v1h-4.8884v-1h1.9442v-9.9986h-4v2h-1z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m10 42h11v3h-1v-2h-4v9.9986h1.9442v1h-4.8884v-1h1.9442v-9.9986h-4v2h-1z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m10 74h11v3h-1v-2h-4v9.9986h1.9442v1h-4.8884v-1h1.9442v-9.9986h-4v2h-1z" fill="%2318a0fb"/%3E%3Cpath d="m10 106h11v3h-1v-2h-4v9.999h1.9442v1h-4.8884v-1h1.9442v-9.999h-4v2h-1z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_corner-radius.scss:
--------------------------------------------------------------------------------
1 | .icon--corner-radius {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath d=\'m21 13h-4c-2.2091 0-4 1.7909-4 4v4h-1v-4c0-2.7614 2.2386-5 5-5h4z\' fill=\'%23000\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m21 45h-4c-2.2091 0-4 1.7909-4 4v4h-1v-4c0-2.7614 2.2386-5 5-5h4z\' fill=\'%23000\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m21 77h-4c-2.2091 0-4 1.7909-4 4v4h-1v-4c0-2.7614 2.2386-5 5-5h4z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m21 109h-4c-2.2091 0-4 1.791-4 4v4h-1v-4c0-2.761 2.2386-5 5-5h4z\' fill=\'%23fff\'/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/action-button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.button`
5 | background: #fff;
6 | box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1), 0px 1px 2px rgba(0, 0, 0, 0.1);
7 | border-radius: 8px;
8 | display: flex;
9 | justify-content: center;
10 | align-items: center;
11 | height: 40px;
12 | margin: 16px 16px 0;
13 | border: none;
14 | flex-shrink: 0;
15 |
16 | :last-child {
17 | margin-bottom: 16px;
18 | }
19 | `;
20 |
21 | const Button = ({ children, onClick }) => (
22 |
23 | {children}
24 |
25 | );
26 |
27 | export default Button;
--------------------------------------------------------------------------------
/src/components/output.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 |
4 | const Container = styled.div`
5 | height: 24px;
6 | background: ${props => props.color};
7 | box-shadow: 0px 1px 2px rgba(66,82,107,0.22);
8 | border-radius: 99px;
9 | padding: 0 8px;
10 | font-style: normal;
11 | font-weight: bold;
12 | font-size: 11px;
13 | line-height: 24px;
14 | color: rgba(255,255,255,.8);
15 | display: flex;
16 | flex-direction: row;
17 | justify-content: center;
18 | `;
19 |
20 | const Output = ({ children, color }) => (
21 |
22 | {children}
23 |
24 | );
25 |
26 | export default Output;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_play.scss:
--------------------------------------------------------------------------------
1 | .icon--play {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m13 10.0979 9.4434 5.9021-9.4434 5.9021zm1 1.8042v8.1958l6.5566-4.0979z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m13 42.0979 9.4434 5.9021-9.4434 5.9021zm1 1.8042v8.1958l6.5566-4.0979z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m13 74.0979 9.4434 5.9021-9.4434 5.9021zm1 1.8042v8.1958l6.5566-4.0979z" fill="%2318a0fb"/%3E%3Cpath d="m13 106.098 9.4434 5.902-9.4434 5.902zm1 1.804v8.196l6.5566-4.098z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_onboarding-tip.scss:
--------------------------------------------------------------------------------
1 | .onboarding-tip {
2 | display: flex;
3 | align-items: top;
4 | flex-direction: row;
5 |
6 | padding: 0 16px 0 0;
7 |
8 | &__icon {
9 | width: 32px;
10 | height: 32px;
11 | margin-right: 8px;
12 | }
13 |
14 | &__msg {
15 | padding: 8px 0 8px 0;
16 |
17 | color: $figma-black-8;
18 |
19 | @include font-ui-pos('small', 'normal');
20 |
21 | a:link, a:hover, a:active, a:visited {
22 | text-decoration: none;
23 |
24 | color: $figma-blue;
25 | }
26 | }
27 |
28 |
29 | &--hidden {
30 | display: none;
31 | }
32 |
33 | &--light {
34 | color: $figma-black-3;
35 | }
36 |
37 | &--pt5 {
38 | padding-top: 8px;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### WIP: Figma automations
2 |
3 | - [x] Design temp UI
4 | - [ ] Improve UI design
5 | - [x] Basic foundation
6 | - [x] Sample actions
7 | - [ ] Typed input/output in actions
8 | - [ ] Pipe data between actions
9 | - [ ] Picking only from supported input types (react-select?)
10 | - [ ] Error handling
11 | - [ ] More actions
12 | - [ ] Name & save multiple automations to plugin data
13 | - [ ] More automation info: creator name and icon
14 | - [ ] Browse/open saved automations
15 | - [ ] Sharable automations (serialized arrays? encoded?)
16 | - [ ] Prebuilt automations
17 | - [ ] Readme
18 | - [ ] Docs & Tutorial
19 | - [ ] Tutorial inside the plugin UI
20 | - [ ] Step by step playback
21 | - [ ] Eslint & tests 🤷🏻♂️
22 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_angle.scss:
--------------------------------------------------------------------------------
1 | .icon--angle {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cg clip-rule=\'evenodd\' fill-rule=\'evenodd\'%3E%3Cpath d=\'m12 12v8h8v-1h-3c0-2.2091-1.7909-4-4-4v-3zm1 4v3h3c0-1.6569-1.3431-3-3-3z\' fill=\'%23000\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m12 44v8h8v-1h-3c0-2.2091-1.7909-4-4-4v-3zm1 4v3h3c0-1.6569-1.3431-3-3-3z\' fill=\'%23000\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m12 76v8h8v-1h-3c0-2.2091-1.7909-4-4-4v-3zm1 4v3h3c0-1.6569-1.3431-3-3-3z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m12 108v8h8v-1h-3c0-2.209-1.7909-4-4-4v-3zm1 4v3h3c0-1.657-1.3431-3-3-3z\' fill=\'%23fff\'/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_frame.scss:
--------------------------------------------------------------------------------
1 | .icon--frame {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m11 24v-3h-3v-1h3v-8h-3v-1h3v-3h1v3h8v-3h1v3h3v1h-3v8h3v1h-3v3h-1v-3h-8v3zm9-4v-8h-8v8z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m11 56v-3h-3v-1h3v-8h-3v-1h3v-3h1v3h8v-3h1v3h3v1h-3v8h3v1h-3v3h-1v-3h-8v3zm9-4v-8h-8v8z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m11 88v-3h-3v-1h3v-8h-3v-1h3v-3h1v3h8v-3h1v3h3v1h-3v8h3v1h-3v3h-1v-3h-8v3zm9-4v-8h-8v8z" fill="%2318a0fb"/%3E%3Cpath d="m11 120v-3h-3v-1h3v-8h-3v-1h3v-3h1v3h8v-3h1v3h3v1h-3v8h3v1h-3v3h-1v-3h-8v3zm9-4v-8h-8v8z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_draft.scss:
--------------------------------------------------------------------------------
1 | .icon--draft {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m10 9h7.7071l4.2929 4.2929v9.7071h-12zm1 1v12h10v-8h-4v-4zm7 .7071 2.2929 2.2929h-2.2929z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m10 41h7.7071l4.2929 4.2929v9.7071h-12zm1 1v12h10v-8h-4v-4zm7 .7071 2.2929 2.2929h-2.2929z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m10 73h7.7071l4.2929 4.2929v9.7071h-12zm1 1v12h10v-8h-4v-4zm7 .7071 2.2929 2.2929h-2.2929z" fill="%2318a0fb"/%3E%3Cpath d="m10 105h7.7071l4.2929 4.293v9.707h-12zm1 1v12h10v-8h-4v-4zm7 .707 2.2929 2.293h-2.2929z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_list.scss:
--------------------------------------------------------------------------------
1 | .icon--list {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m23 10h-14v1h14z" fill-opacity=".8"/%3E%3Cpath d="m9 15.5h14v1h-14z" fill-opacity=".8"/%3E%3Cpath d="m9 21h14v1h-14z" fill-opacity=".8"/%3E%3Cpath d="m23 42h-14v1h14z" fill-opacity=".3"/%3E%3Cpath d="m9 47.5h14v1h-14z" fill-opacity=".3"/%3E%3Cpath d="m9 53h14v1h-14z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m23 74h-14v1h14z" fill="%2318a0fb"/%3E%3Cpath d="m9 79.5h14v1h-14z" fill="%2318a0fb"/%3E%3Cpath d="m9 85h14v1h-14z" fill="%2318a0fb"/%3E%3Cpath d="m23 106h-14v1h14z" fill="%23fff"/%3E%3Cpath d="m9 111.5h14v1h-14z" fill="%23fff"/%3E%3Cpath d="m9 117h14v1h-14z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-grid-columns.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-grid-columns {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m9 9h3v14h-3z" fill-opacity=".8"/%3E%3Cpath d="m14.5 9h3v14h-3z" fill-opacity=".8"/%3E%3Cpath d="m20 9h3v14h-3z" fill-opacity=".8"/%3E%3Cpath d="m9 41h3v14h-3z" fill-opacity=".3"/%3E%3Cpath d="m14.5 41h3v14h-3z" fill-opacity=".3"/%3E%3Cpath d="m20 41h3v14h-3z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m9 73h3v14h-3z" fill="%2318a0fb"/%3E%3Cpath d="m14.5 73h3v14h-3z" fill="%2318a0fb"/%3E%3Cpath d="m20 73h3v14h-3z" fill="%2318a0fb"/%3E%3Cpath d="m9 105h3v14h-3z" fill="%23fff"/%3E%3Cpath d="m14.5 105h3v14h-3z" fill="%23fff"/%3E%3Cpath d="m20 105h3v14h-3z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-grid-rows.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-grid-rows {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m9 9h14v3h-14z" fill-opacity=".8"/%3E%3Cpath d="m9 14.5h14v3h-14z" fill-opacity=".8"/%3E%3Cpath d="m9 20h14v3h-14z" fill-opacity=".8"/%3E%3Cpath d="m9 41h14v3h-14z" fill-opacity=".3"/%3E%3Cpath d="m9 46.5h14v3h-14z" fill-opacity=".3"/%3E%3Cpath d="m9 52h14v3h-14z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m9 73h14v3h-14z" fill="%2318a0fb"/%3E%3Cpath d="m9 78.5h14v3h-14z" fill="%2318a0fb"/%3E%3Cpath d="m9 84h14v3h-14z" fill="%2318a0fb"/%3E%3Cpath d="m9 105h14v3h-14z" fill="%23fff"/%3E%3Cpath d="m9 110.5h14v3h-14z" fill="%23fff"/%3E%3Cpath d="m9 116h14v3h-14z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_stroke-weight.scss:
--------------------------------------------------------------------------------
1 | .icon--stroke-weight {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m10 10h12v1h-12z" fill-opacity=".8"/%3E%3Cpath d="m10 14h12v2h-12z" fill-opacity=".8"/%3E%3Cpath d="m22 19h-12v3h12z" fill-opacity=".8"/%3E%3Cpath d="m10 42h12v1h-12z" fill-opacity=".3"/%3E%3Cpath d="m10 46h12v2h-12z" fill-opacity=".3"/%3E%3Cpath d="m22 51h-12v3h12z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m10 74h12v1h-12z" fill="%2318a0fb"/%3E%3Cpath d="m10 78h12v2h-12z" fill="%2318a0fb"/%3E%3Cpath d="m22 83h-12v3h12z" fill="%2318a0fb"/%3E%3Cpath d="m10 106h12v1h-12z" fill="%23fff"/%3E%3Cpath d="m10 110h12v2h-12z" fill="%23fff"/%3E%3Cpath d="m22 115h-12v3h12z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_dist-vert-spacing.scss:
--------------------------------------------------------------------------------
1 | .icon--dist-vert-spacing {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m9.5 10h13v1h-13z" fill-opacity=".8"/%3E%3Cpath d="m12.5 15h7v2h-7z" fill-opacity=".8"/%3E%3Cpath d="m22.5 21h-13v1h13z" fill-opacity=".8"/%3E%3Cpath d="m9.5 42h13v1h-13z" fill-opacity=".3"/%3E%3Cpath d="m12.5 47h7v2h-7z" fill-opacity=".3"/%3E%3Cpath d="m22.5 53h-13v1h13z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m9.5 74h13v1h-13z" fill="%2318a0fb"/%3E%3Cpath d="m12.5 79h7v2h-7z" fill="%2318a0fb"/%3E%3Cpath d="m22.5 85h-13v1h13z" fill="%2318a0fb"/%3E%3Cpath d="m9.5 106h13v1h-13z" fill="%23fff"/%3E%3Cpath d="m12.5 111h7v2h-7z" fill="%23fff"/%3E%3Cpath d="m22.5 117h-13v1h13z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_instance.scss:
--------------------------------------------------------------------------------
1 | .icon--instance {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m7.00037 15.9999 8.99983-8.99999 8.9999 8.99999-8.9999 9.0001zm8.99983 7.6565 7.6564-7.6565-7.6564-7.65648-7.65634 7.65648z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m7.00037 47.9999 8.99983-9 8.9999 9-8.9999 9.0001zm8.99983 7.6565 7.6564-7.6565-7.6564-7.6565-7.65634 7.6565z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m7.00037 79.9999 8.99983-9 8.9999 9-8.9999 9.0001zm8.99983 7.6565 7.6564-7.6565-7.6564-7.6565-7.65634 7.6565z" fill="%2318a0fb"/%3E%3Cpath d="m7.00037 112 8.99983-9 8.9999 9-8.9999 9zm8.99983 7.656 7.6564-7.656-7.6564-7.657-7.65634 7.657z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_tidy-up-list-vert.scss:
--------------------------------------------------------------------------------
1 | .icon--tidy-up-list-vert {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m9.5 10h13v2h-13z" fill-opacity=".8"/%3E%3Cpath d="m9.5 15h13v2h-13z" fill-opacity=".8"/%3E%3Cpath d="m22.5 20h-13v2h13z" fill-opacity=".8"/%3E%3Cpath d="m9.5 42h13v2h-13z" fill-opacity=".3"/%3E%3Cpath d="m9.5 47h13v2h-13z" fill-opacity=".3"/%3E%3Cpath d="m22.5 52h-13v2h13z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m9.5 74h13v2h-13z" fill="%2318a0fb"/%3E%3Cpath d="m9.5 79h13v2h-13z" fill="%2318a0fb"/%3E%3Cpath d="m22.5 84h-13v2h13z" fill="%2318a0fb"/%3E%3Cpath d="m9.5 106h13v2h-13z" fill="%23fff"/%3E%3Cpath d="m9.5 111h13v2h-13z" fill="%23fff"/%3E%3Cpath d="m22.5 116h-13v2h13z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-align-top.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-align-top {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m14.5 22v-10h-2v10z" fill-opacity=".8"/%3E%3Cpath d="m22.5 10v-1h-13v1z" fill-opacity=".8"/%3E%3Cpath d="m19.5 12v6h-2v-6z" fill-opacity=".8"/%3E%3Cpath d="m14.5 54v-10h-2v10z" fill-opacity=".3"/%3E%3Cpath d="m22.5 42v-1h-13v1z" fill-opacity=".3"/%3E%3Cpath d="m19.5 44v6h-2v-6z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m14.5 86v-10h-2v10z" fill="%2318a0fb"/%3E%3Cpath d="m22.5 74v-1h-13v1z" fill="%2318a0fb"/%3E%3Cpath d="m19.5 76v6h-2v-6z" fill="%2318a0fb"/%3E%3Cpath d="m14.5 118v-10h-2v10z" fill="%23fff"/%3E%3Cpath d="m22.5 106v-1h-13v1z" fill="%23fff"/%3E%3Cpath d="m19.5 108v6h-2v-6z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-align-bottom.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-align-bottom {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m14.5 10v10h-2v-10z" fill-opacity=".8"/%3E%3Cpath d="m22.5 22v1h-13v-1z" fill-opacity=".8"/%3E%3Cpath d="m19.5 20v-6h-2v6z" fill-opacity=".8"/%3E%3Cpath d="m14.5 42v10h-2v-10z" fill-opacity=".3"/%3E%3Cpath d="m22.5 54v1h-13v-1z" fill-opacity=".3"/%3E%3Cpath d="m19.5 52v-6h-2v6z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m14.5 74v10h-2v-10z" fill="%2318a0fb"/%3E%3Cpath d="m22.5 86v1h-13v-1z" fill="%2318a0fb"/%3E%3Cpath d="m19.5 84v-6h-2v6z" fill="%2318a0fb"/%3E%3Cpath d="m14.5 106v10h-2v-10z" fill="%23fff"/%3E%3Cpath d="m22.5 118v1h-13v-1z" fill="%23fff"/%3E%3Cpath d="m19.5 116v-6h-2v6z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-align-left.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-align-left {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m10 22.5h-1v-13h1z" fill-opacity=".8"/%3E%3Cpath d="m22 14.5h-10v-2h10z" fill-opacity=".8"/%3E%3Cpath d="m12 19.5h6v-2h-6z" fill-opacity=".8"/%3E%3Cpath d="m10 54.5h-1v-13h1z" fill-opacity=".3"/%3E%3Cpath d="m22 46.5h-10v-2h10z" fill-opacity=".3"/%3E%3Cpath d="m12 51.5h6v-2h-6z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m10 86.5h-1v-13h1z" fill="%2318a0fb"/%3E%3Cpath d="m22 78.5h-10v-2h10z" fill="%2318a0fb"/%3E%3Cpath d="m12 83.5h6v-2h-6z" fill="%2318a0fb"/%3E%3Cpath d="m10 118.5h-1v-13h1z" fill="%23fff"/%3E%3Cpath d="m22 110.5h-10v-2h10z" fill="%23fff"/%3E%3Cpath d="m12 115.5h6v-2h-6z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-align-right.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-align-right {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m22 22.5h1v-13h-1z" fill-opacity=".8"/%3E%3Cpath d="m10 14.5h10v-2h-10z" fill-opacity=".8"/%3E%3Cpath d="m20 19.5h-6v-2h6z" fill-opacity=".8"/%3E%3Cpath d="m22 54.5h1v-13h-1z" fill-opacity=".3"/%3E%3Cpath d="m10 46.5h10v-2h-10z" fill-opacity=".3"/%3E%3Cpath d="m20 51.5h-6v-2h6z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m22 86.5h1v-13h-1z" fill="%2318a0fb"/%3E%3Cpath d="m10 78.5h10v-2h-10z" fill="%2318a0fb"/%3E%3Cpath d="m20 83.5h-6v-2h6z" fill="%2318a0fb"/%3E%3Cpath d="m22 118.5h1v-13h-1z" fill="%23fff"/%3E%3Cpath d="m10 110.5h10v-2h-10z" fill="%23fff"/%3E%3Cpath d="m20 115.5h-6v-2h6z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_tidy-up-list-horiz.scss:
--------------------------------------------------------------------------------
1 | .icon--tidy-up-list-horiz {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m10 22.5v-13h2v13z" fill-opacity=".8"/%3E%3Cpath d="m15 22.5v-13h2v13z" fill-opacity=".8"/%3E%3Cpath d="m20 9.5v13h2v-13z" fill-opacity=".8"/%3E%3Cpath d="m10 54.5v-13h2v13z" fill-opacity=".3"/%3E%3Cpath d="m15 54.5v-13h2v13z" fill-opacity=".3"/%3E%3Cpath d="m20 41.5v13h2v-13z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m10 86.5v-13h2v13z" fill="%2318a0fb"/%3E%3Cpath d="m15 86.5v-13h2v13z" fill="%2318a0fb"/%3E%3Cpath d="m20 73.5v13h2v-13z" fill="%2318a0fb"/%3E%3Cpath d="m10 118.5v-13h2v13z" fill="%23fff"/%3E%3Cpath d="m15 118.5v-13h2v13z" fill="%23fff"/%3E%3Cpath d="m20 105.5v13h2v-13z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_dist-horiz-spacing.scss:
--------------------------------------------------------------------------------
1 | .icon--dist-horiz-spacing {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m11 22.5v-13h-1v13z" fill-opacity=".8"/%3E%3Cpath d="m22 9.5v13h-1v-13z" fill-opacity=".8"/%3E%3Cpath d="m17 12.5v7h-2v-7z" fill-opacity=".8"/%3E%3Cpath d="m11 54.5v-13h-1v13z" fill-opacity=".3"/%3E%3Cpath d="m22 41.5v13h-1v-13z" fill-opacity=".3"/%3E%3Cpath d="m17 44.5v7h-2v-7z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m11 86.5v-13h-1v13z" fill="%2318a0fb"/%3E%3Cpath d="m22 73.5v13h-1v-13z" fill="%2318a0fb"/%3E%3Cpath d="m17 76.5v7h-2v-7z" fill="%2318a0fb"/%3E%3Cpath d="m11 118.5v-13h-1v13z" fill="%23fff"/%3E%3Cpath d="m22 105.5v13h-1v-13z" fill="%23fff"/%3E%3Cpath d="m17 108.5v7h-2v-7z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/base/_typography.scss:
--------------------------------------------------------------------------------
1 | /* Typography */
2 | @font-face {
3 | font-family: 'Inter';
4 | font-style: normal;
5 | font-weight: 400;
6 | src: url("https://rsms.me/inter/font-files/Inter-Regular.woff2?v=3.7") format("woff2"),
7 | url("https://rsms.me/inter/font-files/Inter-Regular.woff?v=3.7") format("woff");
8 | }
9 |
10 | @font-face {
11 | font-family: 'Inter';
12 | font-style: normal;
13 | font-weight: 500;
14 | src: url("https://rsms.me/inter/font-files/Inter-Medium.woff2?v=3.7") format("woff2"),
15 | url("https://rsms.me/inter/font-files/Inter-Medium.woff2?v=3.7") format("woff");
16 | }
17 |
18 | @font-face {
19 | font-family: 'Inter';
20 | font-style: normal;
21 | font-weight: 600;
22 | src: url("https://rsms.me/inter/font-files/Inter-SemiBold.woff2?v=3.7") format("woff2"),
23 | url("https://rsms.me/inter/font-files/Inter-SemiBold.woff2?v=3.7") format("woff");
24 | }
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_align-top.scss:
--------------------------------------------------------------------------------
1 | .icon--align-top {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m23 9h-15v1h15z" fill-opacity=".8"/%3E%3Cpath d="m15.5 12.7929-3.8536 3.8535.7072.7072 2.6464-2.6465v8.2929h1v-8.2929l2.6464 2.6465.7072-.7072z" fill-opacity=".8"/%3E%3Cpath d="m23 41h-15v1h15z" fill-opacity=".3"/%3E%3Cpath d="m15.5 44.7929-3.8536 3.8535.7072.7072 2.6464-2.6465v8.2929h1v-8.2929l2.6464 2.6465.7072-.7072z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m23 73h-15v1h15z" fill="%2318a0fb"/%3E%3Cpath d="m15.5 76.7929-3.8536 3.8535.7072.7072 2.6464-2.6465v8.2929h1v-8.2929l2.6464 2.6465.7072-.7072z" fill="%2318a0fb"/%3E%3Cpath d="m23 105h-15v1h15z" fill="%23fff"/%3E%3Cpath d="m15.5 108.793-3.8536 3.853.7072.708 2.6464-2.647v8.293h1v-8.293l2.6464 2.647.7072-.708z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_align-bottom.scss:
--------------------------------------------------------------------------------
1 | .icon--align-bottom {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m23 23h-15v-1h15z" fill-opacity=".8"/%3E%3Cpath d="m15.5 19.2071-3.8536-3.8535.7072-.7072 2.6464 2.6465v-8.2929h1v8.2929l2.6464-2.6465.7072.7072z" fill-opacity=".8"/%3E%3Cpath d="m23 55h-15v-1h15z" fill-opacity=".3"/%3E%3Cpath d="m15.5 51.2071-3.8536-3.8535.7072-.7072 2.6464 2.6465v-8.2929h1v8.2929l2.6464-2.6465.7072.7072z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m23 87h-15v-1h15z" fill="%2318a0fb"/%3E%3Cpath d="m15.5 83.2071-3.8536-3.8535.7072-.7072 2.6464 2.6465v-8.2929h1v8.2929l2.6464-2.6465.7072.7072z" fill="%2318a0fb"/%3E%3Cpath d="m23 119h-15v-1h15z" fill="%23fff"/%3E%3Cpath d="m15.5 115.207-3.8536-3.853.7072-.708 2.6464 2.647v-8.293h1v8.293l2.6464-2.647.7072.708z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_close.scss:
--------------------------------------------------------------------------------
1 | .icon--close {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m16 15.293 4.6465-4.6464.7071.7071-4.6465 4.6464 4.6465 4.6465-.7071.7071-4.6465-4.6464-4.6464 4.6464-.7071-.7071 4.6464-4.6465-4.6464-4.6463.7071-.7071z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16 47.293 4.6465-4.6464.7071.7071-4.6465 4.6464 4.6465 4.6465-.7071.7071-4.6465-4.6464-4.6464 4.6464-.7071-.7071 4.6464-4.6465-4.6464-4.6463.7071-.7071z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16 79.293 4.6465-4.6464.7071.7071-4.6465 4.6464 4.6465 4.6465-.7071.7071-4.6465-4.6464-4.6464 4.6464-.7071-.7071 4.6464-4.6465-4.6464-4.6463.7071-.7071z" fill="%2318a0fb"/%3E%3Cpath d="m16 111.293 4.6465-4.646.7071.707-4.6465 4.646 4.6465 4.647-.7071.707-4.6465-4.647-4.6464 4.647-.7071-.707 4.6464-4.647-4.6464-4.646.7071-.707z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_return.scss:
--------------------------------------------------------------------------------
1 | .icon--return {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m11.7072 14 2.6464 2.6464-.7071.7071-3.85353-3.8535 3.85353-3.85358.7071.70708-2.6464 2.6465h3.7929c3.5761 0 6.5 2.9238 6.5 6.5v1.5h-1v-1.5c0-3.0239-2.4762-5.5-5.5-5.5z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m11.7072 46 2.6464 2.6464-.7071.7071-3.85353-3.8535 3.85353-3.8536.7071.7071-2.6464 2.6465h3.7929c3.5761 0 6.5 2.9238 6.5 6.5v1.5h-1v-1.5c0-3.0239-2.4762-5.5-5.5-5.5z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m11.7072 78 2.6464 2.6464-.7071.7071-3.85353-3.8535 3.85353-3.8536.7071.7071-2.6464 2.6465h3.7929c3.5761 0 6.5 2.9238 6.5 6.5v1.5h-1v-1.5c0-3.0239-2.4762-5.5-5.5-5.5z" fill="%2318a0fb"/%3E%3Cpath d="m11.7072 110 2.6464 2.646-.7071.708-3.85353-3.854 3.85353-3.854.7071.708-2.6464 2.646h3.7929c3.5761 0 6.5 2.924 6.5 6.5v1.5h-1v-1.5c0-3.024-2.4762-5.5-5.5-5.5z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_textarea.scss:
--------------------------------------------------------------------------------
1 | .textarea {
2 | @include font-ui-pos('small', 'normal');
3 |
4 | display: flex;
5 | overflow: hidden;
6 | align-items: center;
7 | width: calc(100% - 16px);
8 | min-height: 62px;
9 | margin: 1px 8px 1px 8px;
10 | padding: 7px 7px 7px 7px;
11 |
12 | resize: none;
13 |
14 | color: $figma-black-8;
15 | border: 1px solid $figma-black-1;
16 | border-radius: $border-radius-small;
17 | outline: none;
18 | background-color: $figma-white;
19 |
20 | &:active, &:focus {
21 | padding: 6px 6px 6px 6px;
22 |
23 | color: $figma-black;
24 | border: 2px solid $figma-blue;
25 | border-radius: $border-radius-small;
26 | }
27 |
28 | &::selection {
29 | color: $figma-black;
30 | background-color: $figma-blue-3;
31 | }
32 |
33 | &::placeholder {
34 | color: $figma-black-3;
35 | }
36 |
37 | &:disabled {
38 | color: $figma-black-3;
39 |
40 | &:focus, &:active {
41 | padding: 7px 7px 7px 7px;
42 |
43 | border: 1px solid $figma-black-1;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_resolve-filled.scss:
--------------------------------------------------------------------------------
1 | .icon--resolve-filled {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m16 23.9999c4.4183 0 8-3.5817 8-8s-3.5817-8.00002-8-8.00002-8 3.58172-8 8.00002 3.5817 8 8 8zm3.9111-9.6345-.8222-.7308-3.6125 4.0639-2.5875-2.5874-.7778.7778 3.4125 3.4123z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16 55.9999c4.4183 0 8-3.5817 8-8s-3.5817-8-8-8-8 3.5817-8 8 3.5817 8 8 8zm3.9111-9.6345-.8222-.7308-3.6125 4.0639-2.5875-2.5874-.7778.7778 3.4125 3.4123z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16 87.9999c4.4183 0 8-3.5817 8-8s-3.5817-8-8-8-8 3.5817-8 8 3.5817 8 8 8zm3.9111-9.6345-.8222-.7308-3.6125 4.0639-2.5875-2.5874-.7778.7778 3.4125 3.4123z" fill="%2318a0fb"/%3E%3Cpath d="m16 120c4.4183 0 8-3.582 8-8s-3.5817-8-8-8-8 3.582-8 8 3.5817 8 8 8zm3.9111-9.635-.8222-.73-3.6125 4.064-2.5875-2.588-.7778.778 3.4125 3.412z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_arrow-up-down.scss:
--------------------------------------------------------------------------------
1 | .icon--arrow-up-down {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m16.0005 10.2924 2.8536 2.8535-.7071.7071-1.6465-1.6464v7.5858l1.6465-1.6465.7071.7071-2.8536 2.8536-2.8535-2.8536.7071-.7071 1.6464 1.6465v-7.5858l-1.6464 1.6464-.7071-.7071z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16.0005 42.2924 2.8536 2.8535-.7071.7071-1.6465-1.6464v7.5858l1.6465-1.6465.7071.7071-2.8536 2.8536-2.8535-2.8536.7071-.7071 1.6464 1.6465v-7.5858l-1.6464 1.6464-.7071-.7071z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16.0005 74.2924 2.8536 2.8535-.7071.7071-1.6465-1.6464v7.5858l1.6465-1.6465.7071.7071-2.8536 2.8536-2.8535-2.8536.7071-.7071 1.6464 1.6465v-7.5858l-1.6464 1.6464-.7071-.7071z" fill="%2318a0fb"/%3E%3Cpath d="m16.0005 106.292 2.8536 2.854-.7071.707-1.6465-1.646v7.585l1.6465-1.646.7071.707-2.8536 2.854-2.8535-2.854.7071-.707 1.6464 1.646v-7.585l-1.6464 1.646-.7071-.707z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_arrow-left-right.scss:
--------------------------------------------------------------------------------
1 | .icon--arrow-left-right {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m12.2071 16.5 1.6464 1.6465-.7071.7071-2.8536-2.8536 2.8536-2.8535.7071.7071-1.6464 1.6464h7.5857l-1.6464-1.6464.7071-.7071 2.8536 2.8535-2.8536 2.8536-.7071-.7071 1.6464-1.6465z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m12.2071 48.5 1.6464 1.6465-.7071.7071-2.8536-2.8536 2.8536-2.8535.7071.7071-1.6464 1.6464h7.5857l-1.6464-1.6464.7071-.7071 2.8536 2.8535-2.8536 2.8536-.7071-.7071 1.6464-1.6465z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m12.2071 80.5 1.6464 1.6465-.7071.7071-2.8536-2.8536 2.8536-2.8535.7071.7071-1.6464 1.6464h7.5857l-1.6464-1.6464.7071-.7071 2.8536 2.8535-2.8536 2.8536-.7071-.7071 1.6464-1.6465z" fill="%2318a0fb"/%3E%3Cpath d="m12.2071 112.5 1.6464 1.646-.7071.708-2.8536-2.854 2.8536-2.854.7071.708-1.6464 1.646h7.5857l-1.6464-1.646.7071-.708 2.8536 2.854-2.8536 2.854-.7071-.708 1.6464-1.646z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ahmad Al Haddad
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_corners.scss:
--------------------------------------------------------------------------------
1 | .icon--corners {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cg fill=\'%23000\'%3E%3Cpath d=\'m11 11h3v1h-2v2h-1z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m18 11h3v3h-1v-2h-2z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m12 20v-2h-1v3h3v-1z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m21 18v3h-3v-1h2v-2z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m11 43h3v1h-2v2h-1z\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m18 43h3v3h-1v-2h-2z\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m12 52v-2h-1v3h3v-1z\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m21 50v3h-3v-1h2v-2z\' fill-opacity=\'.3\'/%3E%3C/g%3E%3Cpath d=\'m11 75h3v1h-2v2h-1z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m18 75h3v3h-1v-2h-2z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m12 84v-2h-1v3h3v-1z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m21 82v3h-3v-1h2v-2z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m11 107h3v1h-2v2h-1z\' fill=\'%23fff\'/%3E%3Cpath d=\'m18 107h3v3h-1v-2h-2z\' fill=\'%23fff\'/%3E%3Cpath d=\'m12 116v-2h-1v3h3v-1z\' fill=\'%23fff\'/%3E%3Cpath d=\'m21 114v3h-3v-1h2v-2z\' fill=\'%23fff\'/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/automation.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 | import { Droppable } from 'react-beautiful-dnd';
4 |
5 | const Container = styled.div`
6 | display: flex;
7 | flex-direction: column;
8 | justify-content: flex-start;
9 | align-items: stretch;
10 | width: 304px;
11 | height: calc(100% - 40px);
12 | overflow-y: scroll;
13 | margin-top: 40px;
14 | min-height: calc(100% - 40px);
15 | padding: 0 0 16px;
16 | box-sizing: border-box;
17 | `;
18 |
19 | const Automation = ({ children }) => {
20 | if(children.length === 0) {
21 | return (
22 |
23 | Add actions from the right 👉🏼
24 |
25 | );
26 | }
27 | else {
28 | return (
29 |
30 | {provided => (
31 |
32 | {children}
33 | {provided.placeholder}
34 |
35 | )}
36 |
37 | );
38 | }
39 | };
40 |
41 | export default Automation;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_link-broken.scss:
--------------------------------------------------------------------------------
1 | .icon--link-broken {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m18 14v-2c0-1.1046-.8954-2-2-2s-2 .8954-2 2v2h-1v-2c0-1.6569 1.3431-3 3-3s3 1.3431 3 3v2z" fill-opacity=".8"/%3E%3Cpath d="m19 18h-1v2c0 1.1046-.8954 2-2 2s-2-.8954-2-2v-2h-1v2c0 1.6569 1.3431 3 3 3s3-1.3431 3-3z" fill-opacity=".8"/%3E%3Cpath d="m18 46v-2c0-1.1046-.8954-2-2-2s-2 .8954-2 2v2h-1v-2c0-1.6569 1.3431-3 3-3s3 1.3431 3 3v2z" fill-opacity=".3"/%3E%3Cpath d="m19 50h-1v2c0 1.1046-.8954 2-2 2s-2-.8954-2-2v-2h-1v2c0 1.6569 1.3431 3 3 3s3-1.3431 3-3z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m18 78v-2c0-1.1046-.8954-2-2-2s-2 .8954-2 2v2h-1v-2c0-1.6569 1.3431-3 3-3s3 1.3431 3 3v2z" fill="%2318a0fb"/%3E%3Cpath d="m19 82h-1v2c0 1.1046-.8954 2-2 2s-2-.8954-2-2v-2h-1v2c0 1.6569 1.3431 3 3 3s3-1.3431 3-3z" fill="%2318a0fb"/%3E%3Cpath d="m18 110v-2c0-1.105-.8954-2-2-2s-2 .895-2 2v2h-1v-2c0-1.657 1.3431-3 3-3s3 1.343 3 3v2z" fill="%23fff"/%3E%3Cpath d="m19 114h-1v2c0 1.105-.8954 2-2 2s-2-.895-2-2v-2h-1v2c0 1.657 1.3431 3 3 3s3-1.343 3-3z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_star-off.scss:
--------------------------------------------------------------------------------
1 | .icon--star-off {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m18 14-2-6-2 6-6-.0141 5 4.0141-2 6 5-3.7945 5 3.7945-2-6 5-4.0141zm3.1487.9926-3.8689.0091-1.2798-3.8394-1.2798 3.8394-3.8689-.0091 3.3175 2.6633-1.1976 3.5928 3.0288-2.2985 3.0288 2.2985-1.1976-3.5928z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m18 46-2-6-2 6-6-.0141 5 4.0141-2 6 5-3.7945 5 3.7945-2-6 5-4.0141zm3.1487.9926-3.8689.0091-1.2798-3.8394-1.2798 3.8394-3.8689-.0091 3.3175 2.6633-1.1976 3.5928 3.0288-2.2985 3.0288 2.2985-1.1976-3.5928z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m18 78-2-6-2 6-6-.0141 5 4.0141-2 6 5-3.7945 5 3.7945-2-6 5-4.0141zm3.1487.9926-3.8689.0091-1.2798-3.8394-1.2798 3.8394-3.8689-.0091 3.3175 2.6633-1.1976 3.5928 3.0288-2.2985 3.0288 2.2985-1.1976-3.5928z" fill="%2318a0fb"/%3E%3Cpath d="m18 110-2-6-2 6-6-.014 5 4.014-2 6 5-3.794 5 3.794-2-6 5-4.014zm3.1487.993-3.8689.009-1.2798-3.84-1.2798 3.84-3.8689-.009 3.3175 2.663-1.1976 3.593 3.0288-2.299 3.0288 2.299-1.1976-3.593z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_lock-unlocked.scss:
--------------------------------------------------------------------------------
1 | .icon--lock-unlocked {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m18 15h.5c.2761 0 .5.2239.5.5v5c0 .2761-.2239.5-.5.5h-6c-.2761 0-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5h4.5v-2.5c0-1.3807 1.1193-2.5 2.5-2.5s2.5 1.1193 2.5 2.5v1.5h-1v-1.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5 1.5z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m18 47h.5c.2761 0 .5.2239.5.5v5c0 .2761-.2239.5-.5.5h-6c-.2761 0-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5h4.5v-2.5c0-1.3807 1.1193-2.5 2.5-2.5s2.5 1.1193 2.5 2.5v1.5h-1v-1.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5 1.5z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m18 79h.5c.2761 0 .5.2239.5.5v5c0 .2761-.2239.5-.5.5h-6c-.2761 0-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5h4.5v-2.5c0-1.3807 1.1193-2.5 2.5-2.5s2.5 1.1193 2.5 2.5v1.5h-1v-1.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5 1.5z" fill="%2318a0fb"/%3E%3Cpath d="m18 111h.5c.2761 0 .5.224.5.5v5c0 .276-.2239.5-.5.5h-6c-.2761 0-.5-.224-.5-.5v-5c0-.276.2239-.5.5-.5h4.5v-2.5c0-1.381 1.1193-2.5 2.5-2.5s2.5 1.119 2.5 2.5v1.5h-1v-1.5c0-.828-.6716-1.5-1.5-1.5s-1.5.672-1.5 1.5z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_animated-fill.scss:
--------------------------------------------------------------------------------
1 | .icon--animated-fill {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m13.6667 13.0833v5.8334l5.25-2.9167z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m9 10c0-.55228.44772-1 1-1h12c.5523 0 1 .44772 1 1v12c0 .5523-.4477 1-1 1h-12c-.55228 0-1-.4477-1-1zm1 0h12v12h-12z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m13.6667 45.0833v5.8334l5.25-2.9167z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m9 42c0-.5523.44772-1 1-1h12c.5523 0 1 .4477 1 1v12c0 .5523-.4477 1-1 1h-12c-.55228 0-1-.4477-1-1zm1 0h12v12h-12z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m13.6667 77.0833v5.8334l5.25-2.9167z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m9 74c0-.5523.44772-1 1-1h12c.5523 0 1 .4477 1 1v12c0 .5523-.4477 1-1 1h-12c-.55228 0-1-.4477-1-1zm1 0h12v12h-12z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m13.6667 109.083v5.834l5.25-2.917z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m9 106c0-.552.44772-1 1-1h12c.5523 0 1 .448 1 1v12c0 .552-.4477 1-1 1h-12c-.55228 0-1-.448-1-1zm1 0h12v12h-12z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_recent.scss:
--------------------------------------------------------------------------------
1 | .icon--recent {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m15 12v5h5v-1h-4v-4z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m24 16c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m15 44v5h5v-1h-4v-4z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m24 48c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m15 76v5h5v-1h-4v-4z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m24 80c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m15 108v5h5v-1h-4v-4z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m24 112c0 4.418-3.5817 8-8 8s-8-3.582-8-8 3.5817-8 8-8 8 3.582 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/figma-actions.ts:
--------------------------------------------------------------------------------
1 | import { setPosition, getNodesByIds, selectAll, } from "./utils";
2 |
3 | const actionsData = {
4 | actions: {
5 | "delete": {
6 | id: "delete",
7 | name: "Delete",
8 | run(ids: [] = []) {
9 | let target: readonly SceneNode[];
10 |
11 | if(ids.length === 0) {
12 | target = figma.currentPage.selection;
13 | }
14 | else {
15 | target = getNodesByIds(ids);
16 | }
17 |
18 | target.map(node => {node.remove()});
19 | }
20 | },
21 | "select-all": {
22 | id: "select-all",
23 | name: "Select All Layers",
24 | run() {
25 | selectAll(figma.currentPage);
26 | }
27 | },
28 | "rename": {
29 | id: "rename",
30 | name: "Rename Layer",
31 | run(nodes: BaseNode[], newName: string) {
32 | nodes.map(node => node.name = newName);
33 | }
34 | },
35 | "each": {
36 | id: "each",
37 | name: "Each"
38 | },
39 | "resize": {
40 | id: "resize",
41 | name: "Resize",
42 | run(nodes: SceneNode[], x, y) {
43 | nodes.map((node:SceneNode) => node.resize(x, y));
44 | }
45 | },
46 | },
47 | automation: [],
48 | }
49 |
50 | export default actionsData;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_lock.scss:
--------------------------------------------------------------------------------
1 | .icon--lock {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m13.5 15v-1.5c0-1.3807 1.1193-2.5 2.5-2.5s2.5 1.1193 2.5 2.5v1.5h.5c.2761 0 .5.2239.5.5v5c0 .2761-.2239.5-.5.5h-6c-.2761 0-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5zm4-1.5v1.5h-3v-1.5c0-.8284.6716-1.5 1.5-1.5s1.5.6716 1.5 1.5z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m13.5 47v-1.5c0-1.3807 1.1193-2.5 2.5-2.5s2.5 1.1193 2.5 2.5v1.5h.5c.2761 0 .5.2239.5.5v5c0 .2761-.2239.5-.5.5h-6c-.2761 0-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5zm4-1.5v1.5h-3v-1.5c0-.8284.6716-1.5 1.5-1.5s1.5.6716 1.5 1.5z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m13.5 79v-1.5c0-1.3807 1.1193-2.5 2.5-2.5s2.5 1.1193 2.5 2.5v1.5h.5c.2761 0 .5.2239.5.5v5c0 .2761-.2239.5-.5.5h-6c-.2761 0-.5-.2239-.5-.5v-5c0-.2761.2239-.5.5-.5zm4-1.5v1.5h-3v-1.5c0-.8284.6716-1.5 1.5-1.5s1.5.6716 1.5 1.5z" fill="%2318a0fb"/%3E%3Cpath d="m13.5 111v-1.5c0-1.381 1.1193-2.5 2.5-2.5s2.5 1.119 2.5 2.5v1.5h.5c.2761 0 .5.224.5.5v5c0 .276-.2239.5-.5.5h-6c-.2761 0-.5-.224-.5-.5v-5c0-.276.2239-.5.5-.5zm4-1.5v1.5h-3v-1.5c0-.828.6716-1.5 1.5-1.5s1.5.672 1.5 1.5z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/io.js:
--------------------------------------------------------------------------------
1 | import {
2 | EventEmitter
3 | } from 'events';
4 |
5 | function createInterface(renderer) {
6 | const emitter = new EventEmitter();
7 |
8 | const receive = result => {
9 | if (result && result.event) {
10 | emitter.emit(result.event, result.data);
11 | }
12 | };
13 |
14 | if (renderer) {
15 | window.onmessage = ev => receive(ev.data.pluginMessage);
16 | } else {
17 | figma.ui.onmessage = data => receive(data);
18 | }
19 |
20 | emitter.send = function (event, data) {
21 | if (typeof event !== 'string') {
22 | throw new Error('Expected first argument to be an event name string');
23 | }
24 | const postData = {
25 | event,
26 | data
27 | };
28 | if (renderer) {
29 | window.parent.postMessage({
30 | pluginMessage: postData
31 | }, '*');
32 | } else {
33 | figma.ui.postMessage(postData);
34 | }
35 | };
36 |
37 | emitter.async = function (ev) {
38 | return new Promise((resolve) => {
39 | this.once(ev, resolve);
40 | });
41 | };
42 |
43 | return emitter;
44 | }
45 |
46 | const isRenderer = typeof figma === 'undefined';
47 | export const html = isRenderer ? createInterface(true) : undefined;
48 | export const script = isRenderer ? undefined : createInterface();
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "watch": "webpack --mode=development --watch",
4 | "build": "webpack --mode=production",
5 | "lint:fix": "eslint './src/**/*.{ts,tsx,js}'"
6 | },
7 | "devDependencies": {
8 | "@types/react": "^16.9.2",
9 | "@types/react-beautiful-dnd": "^11.0.3",
10 | "@types/react-dom": "^16.8.5",
11 | "@types/styled-components": "^4.1.18",
12 | "css-loader": "^3.1.0",
13 | "html-webpack-inline-source-plugin": "^0.0.10",
14 | "html-webpack-plugin": "^3.2.0",
15 | "node-sass": "^4.12.0",
16 | "prettier": "^1.18.2",
17 | "sass-loader": "^7.1.0",
18 | "style-loader": "^0.23.1",
19 | "ts-loader": "^6.0.4",
20 | "typescript": "^3.5.3",
21 | "url-loader": "^2.1.0",
22 | "webpack": "^4.39.1",
23 | "webpack-cli": "^3.3.6"
24 | },
25 | "dependencies": {
26 | "@atlaskit/css-reset": "^5.0.6",
27 | "@mdi/js": "^4.1.95",
28 | "@mdi/react": "^1.2.1",
29 | "immer": "^3.2.0",
30 | "random-color": "^1.0.1",
31 | "react": "^16.8.6",
32 | "react-beautiful-dnd": "^11.0.5",
33 | "react-dom": "^16.8.6",
34 | "react-easy-state": "^6.1.3",
35 | "react-select": "^3.0.4",
36 | "styled-components": "^4.3.2",
37 | "uuid": "^3.3.3",
38 | "validator": "^11.1.0"
39 | },
40 | "license": "MIT"
41 | }
42 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_list-detailed.scss:
--------------------------------------------------------------------------------
1 | .icon--list-detailed {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m12 10h-2v1h2z" fill-opacity=".8"/%3E%3Cpath d="m12 20h-2v1h2z" fill-opacity=".8"/%3E%3Cpath d="m10 15h2v1h-2z" fill-opacity=".8"/%3E%3Cpath d="m22 10h-8v1h8z" fill-opacity=".8"/%3E%3Cpath d="m14 20h8v1h-8z" fill-opacity=".8"/%3E%3Cpath d="m22 15h-8v1h8z" fill-opacity=".8"/%3E%3Cpath d="m12 42h-2v1h2z" fill-opacity=".3"/%3E%3Cpath d="m12 52h-2v1h2z" fill-opacity=".3"/%3E%3Cpath d="m10 47h2v1h-2z" fill-opacity=".3"/%3E%3Cpath d="m22 42h-8v1h8z" fill-opacity=".3"/%3E%3Cpath d="m14 52h8v1h-8z" fill-opacity=".3"/%3E%3Cpath d="m22 47h-8v1h8z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m12 74h-2v1h2z" fill="%2318a0fb"/%3E%3Cpath d="m12 84h-2v1h2z" fill="%2318a0fb"/%3E%3Cpath d="m10 79h2v1h-2z" fill="%2318a0fb"/%3E%3Cpath d="m22 74h-8v1h8z" fill="%2318a0fb"/%3E%3Cpath d="m14 84h8v1h-8z" fill="%2318a0fb"/%3E%3Cpath d="m22 79h-8v1h8z" fill="%2318a0fb"/%3E%3Cpath d="m12 106h-2v1h2z" fill="%23fff"/%3E%3Cpath d="m12 116h-2v1h2z" fill="%23fff"/%3E%3Cpath d="m10 111h2v1h-2z" fill="%23fff"/%3E%3Cpath d="m22 106h-8v1h8z" fill="%23fff"/%3E%3Cpath d="m14 116h8v1h-8z" fill="%23fff"/%3E%3Cpath d="m22 111h-8v1h8z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_search-large.scss:
--------------------------------------------------------------------------------
1 | .icon--search-large {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m18.8744 19.5815c-1.0453.8849-2.3975 1.4185-3.8744 1.4185-3.3137 0-6-2.6863-6-6s2.6863-6 6-6 6 2.6863 6 6c0 1.4769-.5336 2.8291-1.4185 3.8744l4.2721 4.272-.7072.7072zm1.1256-4.5815c0 2.7614-2.2386 5-5 5s-5-2.2386-5-5 2.2386-5 5-5 5 2.2386 5 5z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m18.8744 51.5815c-1.0453.8849-2.3975 1.4185-3.8744 1.4185-3.3137 0-6-2.6863-6-6s2.6863-6 6-6 6 2.6863 6 6c0 1.4769-.5336 2.8291-1.4185 3.8744l4.2721 4.272-.7072.7072zm1.1256-4.5815c0 2.7614-2.2386 5-5 5s-5-2.2386-5-5 2.2386-5 5-5 5 2.2386 5 5z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m18.8744 83.5815c-1.0453.8849-2.3975 1.4185-3.8744 1.4185-3.3137 0-6-2.6863-6-6s2.6863-6 6-6 6 2.6863 6 6c0 1.4769-.5336 2.8291-1.4185 3.8744l4.2721 4.272-.7072.7072zm1.1256-4.5815c0 2.7614-2.2386 5-5 5s-5-2.2386-5-5 2.2386-5 5-5 5 2.2386 5 5z" fill="%2318a0fb"/%3E%3Cpath d="m18.8744 115.582c-1.0453.884-2.3975 1.418-3.8744 1.418-3.3137 0-6-2.686-6-6s2.6863-6 6-6 6 2.686 6 6c0 1.477-.5336 2.829-1.4185 3.874l4.2721 4.272-.7072.708zm1.1256-4.582c0 2.761-2.2386 5-5 5s-5-2.239-5-5 2.2386-5 5-5 5 2.239 5 5z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_switch.scss:
--------------------------------------------------------------------------------
1 | .switch {
2 | @include font-ui-pos('small', 'normal');
3 |
4 | position: relative;
5 | display: flex;
6 | align-items: center;
7 | flex-direction: row;
8 | height: 32px;
9 |
10 | cursor: default;
11 |
12 |
13 | &__toggle {
14 | display: none;
15 |
16 |
17 | &:checked + label:before {
18 | background-color: $figma-black;
19 | }
20 |
21 | &:checked + label:after {
22 | transform: translateX(14px);
23 | }
24 |
25 | &:disabled + label {
26 | opacity: 0.3;
27 | }
28 | }
29 |
30 |
31 | &__label {
32 | display: flex;
33 | width: 100%;
34 | padding-left: 40px;
35 |
36 | user-select: none;
37 |
38 |
39 | //track
40 | &:before {
41 | position: absolute;
42 | top: 10px;
43 | left: 6px;
44 | display: block;
45 | width: 24px;
46 | height: 10px;
47 |
48 | content: '';
49 |
50 | transition: background-color 0 0.2s;
51 |
52 | border: 1px solid $figma-black;
53 | border-radius: 6px;
54 | background-color: $figma-white;
55 | }
56 |
57 | //slider
58 | &:after {
59 | position: absolute;
60 | top: 10px;
61 | left: 6px;
62 | display: block;
63 | width: 10px;
64 | height: 10px;
65 |
66 | content: '';
67 |
68 | transition: transform 0.2s;
69 |
70 | border: 1px solid $figma-black;
71 | border-radius: 50%;
72 | background-color: white;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_align-middle.scss:
--------------------------------------------------------------------------------
1 | .icon--align-middle {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m15.5 13.7071-2.8536-2.8535.7072-.7072 1.6464 1.6465v-4.7929h1v4.7929l1.6464-1.6465.7072.7072z" fill-opacity=".8"/%3E%3Cpath d="m8 16v-1h15v1z" fill-opacity=".8"/%3E%3Cpath d="m15.5 17.2929 2.8536 2.8536-.7072.7071-1.6464-1.6465v4.7929h-1v-4.7929l-1.6464 1.6465-.7072-.7071z" fill-opacity=".8"/%3E%3Cpath d="m15.5 45.7071-2.8536-2.8535.7072-.7072 1.6464 1.6465v-4.7929h1v4.7929l1.6464-1.6465.7072.7072z" fill-opacity=".3"/%3E%3Cpath d="m8 48v-1h15v1z" fill-opacity=".3"/%3E%3Cpath d="m15.5 49.2929 2.8536 2.8536-.7072.7071-1.6464-1.6465v4.7929h-1v-4.7929l-1.6464 1.6465-.7072-.7071z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m15.5 77.7071-2.8536-2.8535.7072-.7072 1.6464 1.6465v-4.7929h1v4.7929l1.6464-1.6465.7072.7072z" fill="%2318a0fb"/%3E%3Cpath d="m8 80v-1h15v1z" fill="%2318a0fb"/%3E%3Cpath d="m15.5 81.2929 2.8536 2.8536-.7072.7071-1.6464-1.6465v4.7929h-1v-4.7929l-1.6464 1.6465-.7072-.7071z" fill="%2318a0fb"/%3E%3Cpath d="m15.5 109.707-2.8536-2.853.7072-.708 1.6464 1.647v-4.793h1v4.793l1.6464-1.647.7072.708z" fill="%23fff"/%3E%3Cpath d="m8 112v-1h15v1z" fill="%23fff"/%3E%3Cpath d="m15.5 113.293 2.8536 2.853-.7072.708-1.6464-1.647v4.793h-1v-4.793l-1.6464 1.647-.7072-.708z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_eyedropper.scss:
--------------------------------------------------------------------------------
1 | .icon--eyedropper {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="m22.4473 9.6c-.8-.8-2-.8-2.8 0l-2.8001 2.8-.8-.7c-.4-.4-1-.4-1.4 0s-.4 1 0 1.4l.7.7-5.79995 5.8c-.4.4-1 1.9 0 2.9.99995 1 2.49995.4 2.89995 0l5.8-5.8.7001.7c.4.4 1 .4 1.4 0s.4-1 0-1.4l-.7-.7 2.8-2.8c.8-.9.8-2.1 0-2.9zm-10.9001 11.9h-1v-1l5.8-5.8 1 1c-.1 0-5.8 5.8-5.8 5.8z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m22.4473 41.6c-.8-.8-2-.8-2.8 0l-2.8001 2.8-.8-.7c-.4-.4-1-.4-1.4 0s-.4 1 0 1.4l.7.7-5.79995 5.8c-.4.4-1 1.9 0 2.9.99995 1 2.49995.4 2.89995 0l5.8-5.8.7001.7c.4.4 1 .4 1.4 0s.4-1 0-1.4l-.7-.7 2.8-2.8c.8-.9.8-2.1 0-2.9zm-10.9001 11.9h-1v-1l5.8-5.8 1 1c-.1 0-5.8 5.8-5.8 5.8z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m22.4473 73.6c-.8-.8-2-.8-2.8 0l-2.8001 2.8-.8-.7c-.4-.4-1-.4-1.4 0s-.4 1 0 1.4l.7.7-5.79995 5.8c-.4.4-1 1.9 0 2.9.99995 1 2.49995.4 2.89995 0l5.8-5.8.7001.7c.4.4 1 .4 1.4 0s.4-1 0-1.4l-.7-.7 2.8-2.8c.8-.9.8-2.1 0-2.9zm-10.9001 11.9h-1v-1l5.8-5.8 1 1c-.1 0-5.8 5.8-5.8 5.8z" fill="%2318a0fb"/%3E%3Cpath d="m22.4473 105.6c-.8-.8-2-.8-2.8 0l-2.8001 2.8-.8-.7c-.4-.4-1-.4-1.4 0s-.4 1 0 1.4l.7.7-5.79995 5.8c-.4.4-1 1.9 0 2.9.99995 1 2.49995.4 2.89995 0l5.8-5.8.7001.7c.4.4 1 .4 1.4 0s.4-1 0-1.4l-.7-.7 2.8-2.8c.8-.9.8-2.1 0-2.9zm-10.9001 11.9h-1v-1l5.8-5.8 1 1c-.1 0-5.8 5.8-5.8 5.8z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_link-connected.scss:
--------------------------------------------------------------------------------
1 | .icon--link-connected {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cg fill=\'%23000\'%3E%3Cpath d=\'m16 10c1.1046 0 2 .8954 2 2v2h1v-2c0-1.6569-1.3431-3-3-3s-3 1.3431-3 3v2h1v-2c0-1.1046.8954-2 2-2z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m18 18h1v2c0 1.6569-1.3431 3-3 3s-3-1.3431-3-3v-2h1v2c0 1.1046.8954 2 2 2s2-.8954 2-2z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m15.5 13v6h1v-6z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m16 42c1.1046 0 2 .8954 2 2v2h1v-2c0-1.6569-1.3431-3-3-3s-3 1.3431-3 3v2h1v-2c0-1.1046.8954-2 2-2z\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m18 50h1v2c0 1.6569-1.3431 3-3 3s-3-1.3431-3-3v-2h1v2c0 1.1046.8954 2 2 2s2-.8954 2-2z\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m15.5 45v6h1v-6z\' fill-opacity=\'.3\'/%3E%3C/g%3E%3Cpath d=\'m16 74c1.1046 0 2 .8954 2 2v2h1v-2c0-1.6569-1.3431-3-3-3s-3 1.3431-3 3v2h1v-2c0-1.1046.8954-2 2-2z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m18 82h1v2c0 1.6569-1.3431 3-3 3s-3-1.3431-3-3v-2h1v2c0 1.1046.8954 2 2 2s2-.8954 2-2z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m15.5 77v6h1v-6z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m16 106c1.1046 0 2 .895 2 2v2h1v-2c0-1.657-1.3431-3-3-3s-3 1.343-3 3v2h1v-2c0-1.105.8954-2 2-2z\' fill=\'%23fff\'/%3E%3Cpath d=\'m18 114h1v2c0 1.657-1.3431 3-3 3s-3-1.343-3-3v-2h1v2c0 1.105.8954 2 2 2s2-.895 2-2z\' fill=\'%23fff\'/%3E%3Cpath d=\'m15.5 109v6h1v-6z\' fill=\'%23fff\'/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_checkbox.scss:
--------------------------------------------------------------------------------
1 | .checkbox {
2 | @include font-ui-pos('small', 'normal');
3 |
4 | position: relative;
5 | display: flex;
6 | align-items: center;
7 | flex-direction: row;
8 | height: 32px;
9 |
10 | cursor: default;
11 |
12 | &__box {
13 | display: none;
14 |
15 |
16 | &:checked + label:before {
17 | border: 1px solid $figma-blue;
18 | background-color: $figma-blue;
19 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%227%22%20viewBox%3D%220%200%208%207%22%20width%3D%228%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m1.17647%201.88236%201.88235%201.88236%203.76471-3.76472%201.17647%201.17648-4.94118%204.9412-3.05882-3.05884z%22%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E');
20 | background-repeat: no-repeat;
21 | background-position: 1px 2px;
22 | }
23 |
24 | &:disabled + label {
25 | opacity: 0.3;
26 | }
27 |
28 | &:checked:disabled + label:before {
29 | border: 1px solid $figma-black;
30 | background-color: $figma-black;
31 | }
32 | }
33 |
34 |
35 | &__label {
36 | display: flex;
37 | width: 100%;
38 |
39 | user-select: none;
40 |
41 | &:before {
42 | display: block;
43 | width: 10px;
44 | height: 10px;
45 | margin: 2px 10px 0 10px;
46 |
47 | content: '';
48 |
49 | border: 1px solid $figma-black;
50 | border-radius: $border-radius-small;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_ellipses.scss:
--------------------------------------------------------------------------------
1 | .icon--ellipses {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cg clip-rule=\'evenodd\' fill-rule=\'evenodd\'%3E%3Cpath d=\'m11.5 16c0 .8284-.6716 1.5-1.5 1.5-.82843 0-1.5-.6716-1.5-1.5s.67157-1.5 1.5-1.5c.8284 0 1.5.6716 1.5 1.5zm6 0c0 .8284-.6716 1.5-1.5 1.5s-1.5-.6716-1.5-1.5.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5zm4.5 1.5c.8284 0 1.5-.6716 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5z\' fill=\'%23000\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m11.5 48c0 .8284-.6716 1.5-1.5 1.5-.82843 0-1.5-.6716-1.5-1.5s.67157-1.5 1.5-1.5c.8284 0 1.5.6716 1.5 1.5zm6 0c0 .8284-.6716 1.5-1.5 1.5s-1.5-.6716-1.5-1.5.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5zm4.5 1.5c.8284 0 1.5-.6716 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5z\' fill=\'%23000\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m11.5 80c0 .8284-.6716 1.5-1.5 1.5-.82843 0-1.5-.6716-1.5-1.5s.67157-1.5 1.5-1.5c.8284 0 1.5.6716 1.5 1.5zm6 0c0 .8284-.6716 1.5-1.5 1.5s-1.5-.6716-1.5-1.5.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5zm4.5 1.5c.8284 0 1.5-.6716 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m11.5 112c0 .828-.6716 1.5-1.5 1.5-.82843 0-1.5-.672-1.5-1.5s.67157-1.5 1.5-1.5c.8284 0 1.5.672 1.5 1.5zm6 0c0 .828-.6716 1.5-1.5 1.5s-1.5-.672-1.5-1.5.6716-1.5 1.5-1.5 1.5.672 1.5 1.5zm4.5 1.5c.8284 0 1.5-.672 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.672-1.5 1.5.6716 1.5 1.5 1.5z\' fill=\'%23fff\'/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_resolve.scss:
--------------------------------------------------------------------------------
1 | .icon--resolve {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m19.9111 14.3654-.8222-.7308-3.6125 4.0639-2.5875-2.5874-.7778.7778 3.4125 3.4123z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m24 15.9999c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8.00002 8-8.00002 8 3.58172 8 8.00002zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7.00002 7-7.00002 7 3.13402 7 7.00002z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m19.9111 46.3654-.8222-.7308-3.6125 4.0639-2.5875-2.5874-.7778.7778 3.4125 3.4123z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m24 47.9999c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m19.9111 78.3654-.8222-.7308-3.6125 4.0639-2.5875-2.5874-.7778.7778 3.4125 3.4123z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m24 79.9999c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m19.9111 110.365-.8222-.73-3.6125 4.064-2.5875-2.588-.7778.778 3.4125 3.412z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m24 112c0 4.418-3.5817 8-8 8s-8-3.582-8-8 3.5817-8 8-8 8 3.582 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/ui.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
39 | Figma Automations
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_icon.scss:
--------------------------------------------------------------------------------
1 | .icon {
2 | width: 32px;
3 | height: 32px;
4 |
5 | cursor: default;
6 |
7 | color: $figma-black;
8 | background-repeat: no-repeat;
9 | background-position: 0 0;
10 |
11 | &--black-3 {
12 | color: $figma-black-3;
13 | background-position: 0 -32px;
14 | }
15 |
16 | &--blue {
17 | color: $figma-blue;
18 | background-position: 0 -64px;
19 | }
20 |
21 | &--white {
22 | color: $figma-blue;
23 | background-position: 0 -96px;
24 | }
25 |
26 | &--button {
27 | width: 32px;
28 | height: 32px;
29 |
30 | border: 1px solid transparent;
31 | border-radius: $border-radius-small;
32 | outline: none;
33 | background-position: -1px -1px;
34 |
35 | &:hover {
36 | background-color: $figma-hover-fill;
37 | }
38 |
39 | &:active {
40 | border: 1px solid $figma-blue;
41 | background-color: $figma-hover-fill;
42 | box-shadow: inset 0 0 0 1px $figma-blue;
43 | }
44 |
45 | &:disabled {
46 | opacity: .37;
47 | }
48 | }
49 |
50 | &--selected {
51 | color: $figma-white;
52 | border: 1px solid transparent;
53 | background-color: $figma-blue;
54 | background-position: -1px -97px;
55 |
56 | &:hover {
57 | color: $figma-white;
58 | background-color: $figma-blue;
59 | }
60 |
61 | &:active {
62 | color: $figma-white;
63 | background-color: $figma-blue;
64 | }
65 | }
66 |
67 | &--text {
68 | display: flex;
69 | align-items: center;
70 | justify-content: center;
71 |
72 | font-family: $font-stack;
73 | font-size: $font-size-small;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_vector-handles.scss:
--------------------------------------------------------------------------------
1 | .icon--vector-handles {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m10.5 13.5-2.5 2.5 2.5 2.5 2-2h2.0854c.2059.5826.7615 1 1.4146 1s1.2087-.4174 1.4146-1h2.0854l2 2 2.5-2.5-2.5-2.5-2 2h-2.0854c-.2059-.5826-.7615-1-1.4146-1s-1.2087.4174-1.4146 1h-2.0854zm1.0858 2.5-1.0858-1.0858-1.08579 1.0858 1.08579 1.0858zm11 0-1.0858-1.0858-1.0858 1.0858 1.0858 1.0858z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m10.5 45.5-2.5 2.5 2.5 2.5 2-2h2.0854c.2059.5826.7615 1 1.4146 1s1.2087-.4174 1.4146-1h2.0854l2 2 2.5-2.5-2.5-2.5-2 2h-2.0854c-.2059-.5826-.7615-1-1.4146-1s-1.2087.4174-1.4146 1h-2.0854zm1.0858 2.5-1.0858-1.0858-1.08579 1.0858 1.08579 1.0858zm11 0-1.0858-1.0858-1.0858 1.0858 1.0858 1.0858z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m10.5 77.5-2.5 2.5 2.5 2.5 2-2h2.0854c.2059.5826.7615 1 1.4146 1s1.2087-.4174 1.4146-1h2.0854l2 2 2.5-2.5-2.5-2.5-2 2h-2.0854c-.2059-.5826-.7615-1-1.4146-1s-1.2087.4174-1.4146 1h-2.0854zm1.0858 2.5-1.0858-1.0858-1.08579 1.0858 1.08579 1.0858zm11 0-1.0858-1.0858-1.0858 1.0858 1.0858 1.0858z" fill="%2318a0fb"/%3E%3Cpath d="m10.5 109.5-2.5 2.5 2.5 2.5 2-2h2.0854c.2059.583.7615 1 1.4146 1s1.2087-.417 1.4146-1h2.0854l2 2 2.5-2.5-2.5-2.5-2 2h-2.0854c-.2059-.583-.7615-1-1.4146-1s-1.2087.417-1.4146 1h-2.0854zm1.0858 2.5-1.0858-1.086-1.08579 1.086 1.08579 1.086zm11 0-1.0858-1.086-1.0858 1.086 1.0858 1.086z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 | import CreatableSelect from 'react-select/creatable';
4 |
5 | const Container = styled.div`
6 | width: 144px;
7 | height: 32px;
8 | `;
9 |
10 | const customStyles = {
11 | option: (provided, state) => ({
12 | ...provided,
13 | fontFamily: "Inter",
14 | fontSize: 12,
15 | }),
16 | control: (provided) => ({
17 | ...provided,
18 | height: 32,
19 | minHeight: 32,
20 | fontSize: 12,
21 | fontFamily: "Inter",
22 | borderColor: "#E5E5E5"
23 | }),
24 | indicatorSeparator: () => ({}),
25 | indicatorsContainer: (provided) => ({
26 | ...provided,
27 | transform: "scale(0.75)",
28 | }),
29 | clearIndicator: (provided) => ({
30 | ...provided,
31 | padding: 4
32 | }),
33 | dropdownIndicator: (provided) => ({
34 | ...provided,
35 | padding: 4
36 | }),
37 | input: (provided) => ({
38 | ...provided,
39 | fontSize: 12,
40 | fontFamily: "Inter",
41 | }),
42 | noOptionsMessage: (provided) => ({
43 | ...provided,
44 | fontSize: 12,
45 | fontFamily: "Inter",
46 | }),
47 | }
48 |
49 | const Input = ({ onChange, onInputChange, options }) => (
50 |
51 | `Use ${inputValue}`}
58 | />
59 |
60 | );
61 |
62 | export default Input;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_comment.scss:
--------------------------------------------------------------------------------
1 | .icon--comment {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m8 23 5.812-.7664c.9562.4899 2.0398.7664 3.188.7664 3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7c0 .945.1872 1.8462.5266 2.6686zm3.6399-4.2552-.1889-.4577c-.2903-.7035-.451-1.4753-.451-2.2871 0-3.3137 2.6863-6 6-6s6 2.6863 6 6-2.6863 6-6 6c-.986 0-1.9136-.237-2.7319-.6564l-.2776-.1422-4.09891.5405z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m8 55 5.812-.7664c.9562.4899 2.0398.7664 3.188.7664 3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7c0 .945.1872 1.8462.5266 2.6686zm3.6399-4.2552-.1889-.4577c-.2903-.7035-.451-1.4753-.451-2.2871 0-3.3137 2.6863-6 6-6s6 2.6863 6 6-2.6863 6-6 6c-.986 0-1.9136-.237-2.7319-.6564l-.2776-.1422-4.09891.5405z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m8 87 5.812-.7664c.9562.4899 2.0398.7664 3.188.7664 3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7c0 .945.1872 1.8462.5266 2.6686zm3.6399-4.2552-.1889-.4577c-.2903-.7035-.451-1.4753-.451-2.2871 0-3.3137 2.6863-6 6-6s6 2.6863 6 6-2.6863 6-6 6c-.986 0-1.9136-.237-2.7319-.6564l-.2776-.1422-4.09891.5405z" fill="%2318a0fb"/%3E%3Cpath d="m8 119 5.812-.766c.9562.49 2.0398.766 3.188.766 3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7c0 .945.1872 1.846.5266 2.669zm3.6399-4.255-.1889-.458c-.2903-.703-.451-1.475-.451-2.287 0-3.314 2.6863-6 6-6s6 2.686 6 6-2.6863 6-6 6c-.986 0-1.9136-.237-2.7319-.656l-.2776-.143-4.09891.541z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/action.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import styled from "styled-components";
3 | import { Draggable } from 'react-beautiful-dnd';
4 |
5 | interface ContainerProps {
6 | readonly isDragging: boolean;
7 | };
8 |
9 | const Container = styled.div`
10 | margin: 16px 16px 0;
11 | background: #FFFFFF;
12 | box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1), 0px 1px 2px #A0AEC0;
13 | border-radius: 8px;
14 | position: relative;
15 |
16 | /* :after {
17 | content: "";
18 | width: 2px;
19 | height: 16px;
20 | background: #ddd;
21 | position: absolute;
22 | bottom: -17px;
23 | left: calc(50% - 1px);
24 | display: ${props => props.isDragging ? 'none' : 'block'}
25 | }
26 |
27 | :last-child:after {
28 | display: none;
29 | } */
30 | `;
31 |
32 | const Title = styled.div`
33 | display: flex;
34 | flex-direction: row;
35 | justify-content: flex-start;
36 | align-items: center;
37 | background: #F3F5F8;
38 | border-radius: 8px 8px 0 0;
39 | height: 24px;
40 | color: #383838;
41 | font-weight: bold;
42 | padding: 0 8px;
43 | font-size: 11px;
44 | `;
45 |
46 | const Action = ({ children, index, draggableId }) => (
47 |
48 | {(provided, snapshot) => (
49 |
50 | Random Number
51 | {children}
52 |
53 | )}
54 |
55 | );
56 |
57 | export default Action;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_restore.scss:
--------------------------------------------------------------------------------
1 | .icon--restore {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m11.2071 11 1.1465 1.1465-.7072.7071-2.35351-2.3536 2.35351-2.35355.7072.70711-1.1465 1.14644h4.7929c3.8017.0344 6.873 3.1554 6.873 7 0 3.866-3.1056 7-6.9365 7s-6.9365-3.134-6.9365-7h1c0 3.3223 2.6664 6 5.9365 6s5.9365-2.6777 5.9365-6c0-3.3215-2.6651-5.9987-5.9341-6z" fill-opacity=".8"/%3E%3Cpath d="m14 14v5h5v-1h-4v-4z" fill-opacity=".8"/%3E%3Cpath d="m11.2071 43 1.1465 1.1465-.7072.7071-2.35351-2.3536 2.35351-2.3535.7072.7071-1.1465 1.1464h4.7929c3.8017.0344 6.873 3.1554 6.873 7 0 3.866-3.1056 7-6.9365 7s-6.9365-3.134-6.9365-7h1c0 3.3223 2.6664 6 5.9365 6s5.9365-2.6777 5.9365-6c0-3.3215-2.6651-5.9987-5.9341-6z" fill-opacity=".3"/%3E%3Cpath d="m14 46v5h5v-1h-4v-4z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m11.2071 75 1.1465 1.1465-.7072.7071-2.35351-2.3536 2.35351-2.3535.7072.7071-1.1465 1.1464h4.7929c3.8017.0344 6.873 3.1554 6.873 7 0 3.866-3.1056 7-6.9365 7s-6.9365-3.134-6.9365-7h1c0 3.3223 2.6664 6 5.9365 6s5.9365-2.6777 5.9365-6c0-3.3215-2.6651-5.9987-5.9341-6z" fill="%2318a0fb"/%3E%3Cpath d="m14 78v5h5v-1h-4v-4z" fill="%2318a0fb"/%3E%3Cpath d="m11.2071 107 1.1465 1.146-.7072.708-2.35351-2.354 2.35351-2.354.7072.708-1.1465 1.146h4.7929c3.8017.034 6.873 3.155 6.873 7 0 3.866-3.1056 7-6.9365 7s-6.9365-3.134-6.9365-7h1c0 3.322 2.6664 6 5.9365 6s5.9365-2.678 5.9365-6-2.6651-5.999-5.9341-6z" fill="%23fff"/%3E%3Cpath d="m14 110v5h5v-1h-4v-4z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_import.scss:
--------------------------------------------------------------------------------
1 | .icon--import {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m23 23v-6h-1v5h-12v-12h5v-1h-6v14z" fill-opacity=".8"/%3E%3Cpath d="m17 15c0-1.656.4715-2.8894 1.2911-3.7089.8195-.8196 2.0529-1.2911 3.7089-1.2911h1v-1h-1c-1.844 0-3.3606.52854-4.4161 1.5839-1.0554 1.0555-1.5839 2.5721-1.5839 4.4161v2.2929l-1.6464-1.6465-.7072.7072 2.8536 2.8535 2.8536-2.8535-.7072-.7072-1.6464 1.6465z" fill-opacity=".8"/%3E%3Cpath d="m23 55v-6h-1v5h-12v-12h5v-1h-6v14z" fill-opacity=".3"/%3E%3Cpath d="m17 47c0-1.656.4715-2.8894 1.2911-3.7089.8195-.8196 2.0529-1.2911 3.7089-1.2911h1v-1h-1c-1.844 0-3.3606.5285-4.4161 1.5839-1.0554 1.0555-1.5839 2.5721-1.5839 4.4161v2.2929l-1.6464-1.6465-.7072.7072 2.8536 2.8535 2.8536-2.8535-.7072-.7072-1.6464 1.6465z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m23 87v-6h-1v5h-12v-12h5v-1h-6v14z" fill="%2318a0fb"/%3E%3Cpath d="m17 79c0-1.656.4715-2.8894 1.2911-3.7089.8195-.8196 2.0529-1.2911 3.7089-1.2911h1v-1h-1c-1.844 0-3.3606.5285-4.4161 1.5839-1.0554 1.0555-1.5839 2.5721-1.5839 4.4161v2.2929l-1.6464-1.6465-.7072.7072 2.8536 2.8535 2.8536-2.8535-.7072-.7072-1.6464 1.6465z" fill="%2318a0fb"/%3E%3Cpath d="m23 119v-6h-1v5h-12v-12h5v-1h-6v14z" fill="%23fff"/%3E%3Cpath d="m17 111c0-1.656.4715-2.889 1.2911-3.709.8195-.82 2.0529-1.291 3.7089-1.291h1v-1h-1c-1.844 0-3.3606.529-4.4161 1.584-1.0554 1.055-1.5839 2.572-1.5839 4.416v2.293l-1.6464-1.647-.7072.708 2.8536 2.853 2.8536-2.853-.7072-.708-1.6464 1.647z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_trash.scss:
--------------------------------------------------------------------------------
1 | .icon--trash {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m14 18.5v-4h1v4z" fill-opacity=".8"/%3E%3Cpath d="m17 18.5v-4h1v4z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m19 10.5c0-1.10457-.8954-2-2-2h-2c-1.1046 0-2 .89543-2 2h-3v1h1v10c0 1.1046.8954 2 2 2h6c1.1046 0 2-.8954 2-2v-10h1v-1zm-4-1c-.5523 0-1 .44772-1 1h4c0-.55228-.4477-1-1-1zm5 2h-8v10c0 .5523.4477 1 1 1h6c.5523 0 1-.4477 1-1z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m14 50.5v-4h1v4z" fill-opacity=".3"/%3E%3Cpath d="m17 50.5v-4h1v4z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m19 42.5c0-1.1046-.8954-2-2-2h-2c-1.1046 0-2 .8954-2 2h-3v1h1v10c0 1.1046.8954 2 2 2h6c1.1046 0 2-.8954 2-2v-10h1v-1zm-4-1c-.5523 0-1 .4477-1 1h4c0-.5523-.4477-1-1-1zm5 2h-8v10c0 .5523.4477 1 1 1h6c.5523 0 1-.4477 1-1z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m14 82.5v-4h1v4z" fill="%2318a0fb"/%3E%3Cpath d="m17 82.5v-4h1v4z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m19 74.5c0-1.1046-.8954-2-2-2h-2c-1.1046 0-2 .8954-2 2h-3v1h1v10c0 1.1046.8954 2 2 2h6c1.1046 0 2-.8954 2-2v-10h1v-1zm-4-1c-.5523 0-1 .4477-1 1h4c0-.5523-.4477-1-1-1zm5 2h-8v10c0 .5523.4477 1 1 1h6c.5523 0 1-.4477 1-1z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m14 114.5v-4h1v4z" fill="%23fff"/%3E%3Cpath d="m17 114.5v-4h1v4z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m19 106.5c0-1.105-.8954-2-2-2h-2c-1.1046 0-2 .895-2 2h-3v1h1v10c0 1.105.8954 2 2 2h6c1.1046 0 2-.895 2-2v-10h1v-1zm-4-1c-.5523 0-1 .448-1 1h4c0-.552-.4477-1-1-1zm5 2h-8v10c0 .552.4477 1 1 1h6c.5523 0 1-.448 1-1z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_node-connect.scss:
--------------------------------------------------------------------------------
1 | .icon--node-connect {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m15.5 9h-6.5v-1h7.5v5.708c.7355.3214 1.2865.9863 1.45 1.792h5.3429l-2.1465-2.1464.7072-.7072 3.3535 3.3536-3.3535 3.3536-.7072-.7072 2.1465-2.1464h-5.3429c-.1635.8057-.7145 1.4706-1.45 1.792v5.708h-7.5v-1h6.5v-4.5c-1.3807 0-2.5-1.1193-2.5-2.5s1.1193-2.5 2.5-2.5zm0 8.5c.8284 0 1.5-.6716 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m15.5 41h-6.5v-1h7.5v5.708c.7355.3214 1.2865.9863 1.45 1.792h5.3429l-2.1465-2.1464.7072-.7072 3.3535 3.3536-3.3535 3.3536-.7072-.7072 2.1465-2.1464h-5.3429c-.1635.8057-.7145 1.4706-1.45 1.792v5.708h-7.5v-1h6.5v-4.5c-1.3807 0-2.5-1.1193-2.5-2.5s1.1193-2.5 2.5-2.5zm0 8.5c.8284 0 1.5-.6716 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m15.5 73h-6.5v-1h7.5v5.708c.7355.3214 1.2865.9863 1.45 1.792h5.3429l-2.1465-2.1464.7072-.7072 3.3535 3.3536-3.3535 3.3536-.7072-.7072 2.1465-2.1464h-5.3429c-.1635.8057-.7145 1.4706-1.45 1.792v5.708h-7.5v-1h6.5v-4.5c-1.3807 0-2.5-1.1193-2.5-2.5s1.1193-2.5 2.5-2.5zm0 8.5c.8284 0 1.5-.6716 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5z" fill="%2318a0fb"/%3E%3Cpath d="m15.5 105h-6.5v-1h7.5v5.708c.7355.321 1.2865.986 1.45 1.792h5.3429l-2.1465-2.146.7072-.708 3.3535 3.354-3.3535 3.354-.7072-.708 2.1465-2.146h-5.3429c-.1635.806-.7145 1.471-1.45 1.792v5.708h-7.5v-1h6.5v-4.5c-1.3807 0-2.5-1.119-2.5-2.5s1.1193-2.5 2.5-2.5zm0 8.5c.8284 0 1.5-.672 1.5-1.5s-.6716-1.5-1.5-1.5-1.5.672-1.5 1.5.6716 1.5 1.5 1.5z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/js/disclosure.js:
--------------------------------------------------------------------------------
1 | (function(){
2 |
3 | 'use strict';
4 |
5 | // DEFAULT SETTINGS //////////
6 | var defaults = {
7 | selector: 'disclosure'
8 | }
9 |
10 | var selector;
11 |
12 | //PRIVATE FUNCTIONS //////////
13 | var disclosureHandler = function(event) {
14 | let disclosureSet = this.parentNode.parentNode;
15 | let disclosuresInSet = disclosureSet.querySelectorAll('li');
16 | let alreadyActive = this.parentNode.classList.contains(selector + '--expanded');
17 | console.log(alreadyActive);
18 |
19 | disclosuresInSet.forEach((disclosure) => {
20 | disclosure.classList.remove(selector + '--expanded');
21 | });
22 |
23 | this.parentNode.classList.add(selector + '--expanded');
24 |
25 | if (alreadyActive) {
26 | this.parentNode.classList.remove(selector + '--expanded');
27 | }
28 |
29 | }
30 |
31 | //PUBLIC FUNCTIONS //////////
32 | window.disclosure = {
33 |
34 | init: function(opts) {
35 |
36 | let settings = Object.assign({}, defaults, opts);
37 | selector = settings.selector;
38 | let disclosures = document.querySelectorAll('.' + selector + '__label');
39 |
40 | disclosures.forEach((disclosure) => {
41 | disclosure.addEventListener('click', disclosureHandler, false);
42 | });
43 |
44 | },
45 |
46 | destroy: function() {
47 |
48 | let disclosures = document.querySelectorAll('.' + selector + '__label');
49 |
50 | disclosures.forEach((disclosure) => {
51 | disclosure.removeEventListener('click', disclosureHandler, false);
52 | });
53 |
54 | }
55 |
56 | };
57 |
58 | })();
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_button.scss:
--------------------------------------------------------------------------------
1 | .button {
2 | display: inline-block;
3 | flex-shrink: 0;
4 | margin: 1px 0 1px 0;
5 | padding: 5px 16px 5px 16px;
6 |
7 | text-decoration: none;
8 |
9 | border: 2px solid transparent;
10 | border-radius: $border-radius-large;
11 | outline: none;
12 |
13 | //Primary
14 | &--primary {
15 | @include font-ui-neg('small', 'medium');
16 |
17 | color: $figma-white;
18 | background-color: $figma-blue;
19 |
20 | &:active, &:focus {
21 | border: 2px solid $figma-black-3;
22 | }
23 |
24 | &:disabled {
25 | background-color: $figma-black-3;
26 | }
27 | }
28 |
29 | //Primary Destructive
30 | &--primary-destructive {
31 | @include font-ui-neg('small', 'medium');
32 |
33 | color: $figma-white;
34 | background-color: $figma-red;
35 |
36 | &:active, &:focus {
37 | border: 2px solid $figma-black-3;
38 | }
39 |
40 | &:disabled {
41 | opacity: 0.4;
42 | }
43 | }
44 |
45 | //Secondary
46 | &--secondary {
47 | @include font-ui-pos('small', 'medium');
48 |
49 | color: $figma-black-8;
50 | border: 1px solid $figma-black-8;
51 | background-color: $figma-white;
52 |
53 | &:active, &:focus {
54 | padding: 4px 15px 4px 15px;
55 |
56 | border: 2px solid $figma-blue;
57 | }
58 |
59 | &:disabled {
60 | color: $figma-black-3;
61 | border: 1px solid $figma-black-3;
62 | }
63 | }
64 |
65 | &--secondary-destructive {
66 | @include font-ui-pos('small', 'medium');
67 |
68 | color: $figma-red;
69 | border: 1px solid $figma-red;
70 | background-color: $figma-white;
71 |
72 | &:active, &:focus {
73 | padding: 4px 15px 4px 15px;
74 |
75 | border: 2px solid $figma-red;
76 | }
77 |
78 | &:disabled {
79 | opacity: 0.4;
80 | }
81 | }
82 |
83 | &--margin-right {
84 | margin-right: 8px;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_reset-instance.scss:
--------------------------------------------------------------------------------
1 | .icon--reset-instance {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m6.79291 15.5 8.70709-8.70709 8.7071 8.70709-.7071.7071-8-7.99998-7.29288 7.29288 7.29288 7.2929 4-4 .7071.7071-4.7071 4.7071z" fill-opacity=".8"/%3E%3Cpath d="m14.7071 15h2.2929c3.3137 0 6 2.6863 6 6 0 1.6569-.6716 3.1569-1.7574 4.2427l-.7071-.7072c.9049-.9048 1.4645-2.1548 1.4645-3.5355 0-2.7614-2.2386-5-5-5h-2.2929l1.6465 1.6465-.7072.7071-2.8535-2.8536 2.8535-2.8535.7072.7071z" fill-opacity=".8"/%3E%3Cpath d="m6.79291 47.5 8.70709-8.7071 8.7071 8.7071-.7071.7071-8-8-7.29288 7.2929 7.29288 7.2929 4-4 .7071.7071-4.7071 4.7071z" fill-opacity=".3"/%3E%3Cpath d="m14.7071 47h2.2929c3.3137 0 6 2.6863 6 6 0 1.6569-.6716 3.1569-1.7574 4.2427l-.7071-.7072c.9049-.9048 1.4645-2.1548 1.4645-3.5355 0-2.7614-2.2386-5-5-5h-2.2929l1.6465 1.6465-.7072.7071-2.8535-2.8536 2.8535-2.8535.7072.7071z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m6.79291 79.5 8.70709-8.7071 8.7071 8.7071-.7071.7071-8-8-7.29288 7.2929 7.29288 7.2929 4-4 .7071.7071-4.7071 4.7071z" fill="%2318a0fb"/%3E%3Cpath d="m14.7071 79h2.2929c3.3137 0 6 2.6863 6 6 0 1.6569-.6716 3.1569-1.7574 4.2427l-.7071-.7072c.9049-.9048 1.4645-2.1548 1.4645-3.5355 0-2.7614-2.2386-5-5-5h-2.2929l1.6465 1.6465-.7072.7071-2.8535-2.8536 2.8535-2.8535.7072.7071z" fill="%2318a0fb"/%3E%3Cpath d="m6.79291 111.5 8.70709-8.707 8.7071 8.707-.7071.707-8-8-7.29288 7.293 7.29288 7.293 4-4 .7071.707-4.7071 4.707z" fill="%23fff"/%3E%3Cpath d="m14.7071 111h2.2929c3.3137 0 6 2.686 6 6 0 1.657-.6716 3.157-1.7574 4.243l-.7071-.707c.9049-.905 1.4645-2.155 1.4645-3.536 0-2.761-2.2386-5-5-5h-2.2929l1.6465 1.646-.7072.708-2.8535-2.854 2.8535-2.854.7072.708z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/js/iconInput.js:
--------------------------------------------------------------------------------
1 | (function(){
2 |
3 | 'use strict';
4 |
5 | // DEFAULT SETTINGS //////////
6 | var defaults = {
7 | selector: '.input-icon'
8 | }
9 |
10 | //VARIABLES //////////
11 | var selector;
12 |
13 | //PRIVATE FUNCTIONS //////////
14 | var inputIconFocusIn = function(event) {
15 | let parent = this.parentNode;
16 | let iconNode = parent.querySelector('.icon');
17 | iconNode.classList.remove('icon--black-3');
18 | iconNode.classList.add('icon--blue');
19 | }
20 |
21 | var inputIconFocusOut = function(event) {
22 | let parent = this.parentNode;
23 | let iconNode = parent.querySelector('.icon');
24 | iconNode.classList.add('icon--black-3');
25 | iconNode.classList.remove('icon--blue');
26 | }
27 |
28 | //PUBLIC FUNCTIONS //////////
29 | window.iconInput = {
30 |
31 | init: function(opts) {
32 | let settings = Object.assign({}, defaults, opts);
33 | selector = settings.selector;
34 | let elements = document.querySelectorAll(selector);
35 |
36 | //initialize
37 | elements.forEach((element) => {
38 | element.addEventListener('focusin', inputIconFocusIn, false);
39 | element.addEventListener('focusout', inputIconFocusOut, false);
40 | });
41 | },
42 |
43 | destroy: function() {
44 | let elements = document.querySelectorAll(selector);
45 |
46 | //initialize
47 | elements.forEach((element) => {
48 | element.removeEventListener('focusin', inputIconFocusIn, false);
49 | element.removeEventListener('focusout', inputIconFocusOut, false);
50 | });
51 |
52 | }
53 |
54 | };
55 |
56 | })();
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_input.scss:
--------------------------------------------------------------------------------
1 | .input {
2 | @include font-ui-pos('small', 'normal');
3 |
4 | position: relative;
5 | display: flex;
6 | overflow: visible;
7 | align-items: center;
8 | width: 100%;
9 | height: 30px;
10 | margin: 1px 0 1px 0;
11 | padding: 8px 4px 8px 7px;
12 |
13 | color: $figma-black-8;
14 | border: 1px solid transparent;
15 | border-radius: $border-radius-small;
16 | outline: none;
17 | background-color: $figma-white;
18 |
19 | &:hover {
20 | color: $figma-black-8;
21 | border: 1px solid $figma-black-1;
22 | }
23 |
24 | &::selection {
25 | color: $figma-black;
26 | background-color: $figma-blue-3;
27 | }
28 |
29 | &::placeholder {
30 | color: $figma-black-3;
31 | border: 1px solid transparent;
32 | }
33 |
34 | &:not(:disabled):not(:hover):placeholder-shown {
35 | border: 1px solid transparent;
36 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcAAAAABCAYAAABJ5n7WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgSURBVHgB7cMBCQAACMTAiR3sX1TQHr+DK2B+I0lSjj29qAEYlIbeBgAAAABJRU5ErkJggg==');
37 | background-repeat: no-repeat;
38 | background-position: center bottom -0.9px;
39 | background-size: calc(100% - 10px) 1px;
40 | }
41 |
42 | &:not(:disabled):focus:placeholder-shown {
43 | border: 2px solid $figma-blue;
44 | }
45 |
46 | &:not(:disabled):focus:not(:placeholder-shown) {
47 | padding-left: 6px;
48 | }
49 |
50 | &:disabled:hover {
51 | border: 1px solid transparent;
52 | }
53 |
54 | &:active, &:focus {
55 | padding: 8px 4px 8px 6px;
56 |
57 | color: $figma-black;
58 | border: 2px solid $figma-blue;
59 | border-radius: $border-radius-small;
60 | }
61 |
62 | &:disabled {
63 | position: relative;
64 |
65 | color: $figma-black-3;
66 | }
67 |
68 | &:disabled:active {
69 | padding: 8px 4px 8px 7px;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_resize-to-fit.scss:
--------------------------------------------------------------------------------
1 | .icon--resize-to-fit {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m8.64648 9.35356 3.64642 3.64644h-2.2929v1h4v-4h-1v2.2929l-3.64641-3.64645z" fill-opacity=".8"/%3E%3Cpath d="m19.7071 13 3.6465-3.64644-.7071-.70711-3.6465 3.64645v-2.2929h-1v4h4v-1z" fill-opacity=".8"/%3E%3Cpath d="m19.7071 19 3.6465 3.6465-.7071.7071-3.6465-3.6465v2.2929h-1v-4h4v1z" fill-opacity=".8"/%3E%3Cpath d="m12.2929 19-3.64642 3.6465.70711.7071 3.64641-3.6465v2.2929h1v-4h-4v1z" fill-opacity=".8"/%3E%3Cpath d="m8.64648 41.3536 3.64642 3.6464h-2.2929v1h4v-4h-1v2.2929l-3.64641-3.6464z" fill-opacity=".3"/%3E%3Cpath d="m19.7071 45 3.6465-3.6464-.7071-.7071-3.6465 3.6464v-2.2929h-1v4h4v-1z" fill-opacity=".3"/%3E%3Cpath d="m19.7071 51 3.6465 3.6465-.7071.7071-3.6465-3.6465v2.2929h-1v-4h4v1z" fill-opacity=".3"/%3E%3Cpath d="m12.2929 51-3.64642 3.6465.70711.7071 3.64641-3.6465v2.2929h1v-4h-4v1z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m8.64648 73.3536 3.64642 3.6464h-2.2929v1h4v-4h-1v2.2929l-3.64641-3.6464z" fill="%2318a0fb"/%3E%3Cpath d="m19.7071 77 3.6465-3.6464-.7071-.7071-3.6465 3.6464v-2.2929h-1v4h4v-1z" fill="%2318a0fb"/%3E%3Cpath d="m19.7071 83 3.6465 3.6465-.7071.7071-3.6465-3.6465v2.2929h-1v-4h4v1z" fill="%2318a0fb"/%3E%3Cpath d="m12.2929 83-3.64642 3.6465.70711.7071 3.64641-3.6465v2.2929h1v-4h-4v1z" fill="%2318a0fb"/%3E%3Cpath d="m8.64648 105.354 3.64642 3.646h-2.2929v1h4v-4h-1v2.293l-3.64641-3.647z" fill="%23fff"/%3E%3Cpath d="m19.7071 109 3.6465-3.646-.7071-.708-3.6465 3.647v-2.293h-1v4h4v-1z" fill="%23fff"/%3E%3Cpath d="m19.7071 115 3.6465 3.646-.7071.708-3.6465-3.647v2.293h-1v-4h4v1z" fill="%23fff"/%3E%3Cpath d="m12.2929 115-3.64642 3.646.70711.708 3.64641-3.647v2.293h1v-4h-4v1z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/node
3 | # Edit at https://www.gitignore.io/?templates=node
4 |
5 | ### Node ###
6 | # Logs
7 | logs
8 | *.log
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | lerna-debug.log*
13 |
14 | # Diagnostic reports (https://nodejs.org/api/report.html)
15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
16 |
17 | # Runtime data
18 | pids
19 | *.pid
20 | *.seed
21 | *.pid.lock
22 |
23 | # Directory for instrumented libs generated by jscoverage/JSCover
24 | lib-cov
25 |
26 | # Coverage directory used by tools like istanbul
27 | coverage
28 | *.lcov
29 |
30 | # nyc test coverage
31 | .nyc_output
32 |
33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
34 | .grunt
35 |
36 | # Bower dependency directory (https://bower.io/)
37 | bower_components
38 |
39 | # node-waf configuration
40 | .lock-wscript
41 |
42 | # Compiled binary addons (https://nodejs.org/api/addons.html)
43 | build/Release
44 |
45 | # Dependency directories
46 | node_modules/
47 | jspm_packages/
48 |
49 | # TypeScript v1 declaration files
50 | typings/
51 |
52 | # TypeScript cache
53 | *.tsbuildinfo
54 |
55 | # Optional npm cache directory
56 | .npm
57 |
58 | # Optional eslint cache
59 | .eslintcache
60 |
61 | # Optional REPL history
62 | .node_repl_history
63 |
64 | # Output of 'npm pack'
65 | *.tgz
66 |
67 | # Yarn Integrity file
68 | .yarn-integrity
69 |
70 | # dotenv environment variables file
71 | .env
72 | .env.test
73 |
74 | # parcel-bundler cache (https://parceljs.org/)
75 | .cache
76 |
77 | # next.js build output
78 | .next
79 |
80 | # nuxt.js build output
81 | .nuxt
82 |
83 | # vuepress build output
84 | .vuepress/dist
85 |
86 | # Serverless directories
87 | .serverless/
88 |
89 | # FuseBox cache
90 | .fusebox/
91 |
92 | # DynamoDB Local files
93 | .dynamodb/
94 |
95 | # End of https://www.gitignore.io/api/node
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_search.scss:
--------------------------------------------------------------------------------
1 | .icon--search {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m18.3972 18.6046c-.7793.625-1.7687.9988-2.8455.9988-2.5138 0-4.5517-2.0378-4.5517-4.5517 0-2.5138 2.0379-4.5517 4.5517-4.5517 2.5139 0 4.5517 2.0379 4.5517 4.5517 0 1.0769-.3739 2.0664-.999 2.8458l3.2491 3.2492-.7071.7071zm.7062-3.5529c0 1.9616-1.5901 3.5517-3.5517 3.5517-1.9615 0-3.5517-1.5901-3.5517-3.5517 0-1.9615 1.5902-3.5517 3.5517-3.5517 1.9616 0 3.5517 1.5902 3.5517 3.5517z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m18.3972 50.6046c-.7793.625-1.7687.9988-2.8455.9988-2.5138 0-4.5517-2.0378-4.5517-4.5517 0-2.5138 2.0379-4.5517 4.5517-4.5517 2.5139 0 4.5517 2.0379 4.5517 4.5517 0 1.0769-.3739 2.0664-.999 2.8458l3.2491 3.2492-.7071.7071zm.7062-3.5529c0 1.9616-1.5901 3.5517-3.5517 3.5517-1.9615 0-3.5517-1.5901-3.5517-3.5517 0-1.9615 1.5902-3.5517 3.5517-3.5517 1.9616 0 3.5517 1.5902 3.5517 3.5517z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m18.3972 82.6046c-.7793.625-1.7687.9988-2.8455.9988-2.5138 0-4.5517-2.0378-4.5517-4.5517 0-2.5138 2.0379-4.5517 4.5517-4.5517 2.5139 0 4.5517 2.0379 4.5517 4.5517 0 1.0769-.3739 2.0664-.999 2.8458l3.2491 3.2492-.7071.7071zm.7062-3.5529c0 1.9616-1.5901 3.5517-3.5517 3.5517-1.9615 0-3.5517-1.5901-3.5517-3.5517 0-1.9615 1.5902-3.5517 3.5517-3.5517 1.9616 0 3.5517 1.5902 3.5517 3.5517z" fill="%2318a0fb"/%3E%3Cpath d="m18.3972 114.605c-.7793.625-1.7687.998-2.8455.998-2.5138 0-4.5517-2.037-4.5517-4.551s2.0379-4.552 4.5517-4.552c2.5139 0 4.5517 2.038 4.5517 4.552 0 1.077-.3739 2.066-.999 2.846l3.2491 3.249-.7071.707zm.7062-3.553c0 1.961-1.5901 3.551-3.5517 3.551-1.9615 0-3.5517-1.59-3.5517-3.551 0-1.962 1.5902-3.552 3.5517-3.552 1.9616 0 3.5517 1.59 3.5517 3.552z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_tidy-up-grid.scss:
--------------------------------------------------------------------------------
1 | .icon--tidy-up-grid {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m10 10h2v2h-2z" fill-opacity=".8"/%3E%3Cpath d="m20 10h2v2h-2z" fill-opacity=".8"/%3E%3Cpath d="m12 15h-2v2h2z" fill-opacity=".8"/%3E%3Cpath d="m20 15h2v2h-2z" fill-opacity=".8"/%3E%3Cpath d="m12 20h-2v2h2z" fill-opacity=".8"/%3E%3Cpath d="m20 20h2v2h-2z" fill-opacity=".8"/%3E%3Cpath d="m17 10h-2v2h2z" fill-opacity=".8"/%3E%3Cpath d="m15 15h2v2h-2z" fill-opacity=".8"/%3E%3Cpath d="m17 20h-2v2h2z" fill-opacity=".8"/%3E%3Cpath d="m10 42h2v2h-2z" fill-opacity=".3"/%3E%3Cpath d="m20 42h2v2h-2z" fill-opacity=".3"/%3E%3Cpath d="m12 47h-2v2h2z" fill-opacity=".3"/%3E%3Cpath d="m20 47h2v2h-2z" fill-opacity=".3"/%3E%3Cpath d="m12 52h-2v2h2z" fill-opacity=".3"/%3E%3Cpath d="m20 52h2v2h-2z" fill-opacity=".3"/%3E%3Cpath d="m17 42h-2v2h2z" fill-opacity=".3"/%3E%3Cpath d="m15 47h2v2h-2z" fill-opacity=".3"/%3E%3Cpath d="m17 52h-2v2h2z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m10 74h2v2h-2z" fill="%2318a0fb"/%3E%3Cpath d="m20 74h2v2h-2z" fill="%2318a0fb"/%3E%3Cpath d="m12 79h-2v2h2z" fill="%2318a0fb"/%3E%3Cpath d="m20 79h2v2h-2z" fill="%2318a0fb"/%3E%3Cpath d="m12 84h-2v2h2z" fill="%2318a0fb"/%3E%3Cpath d="m20 84h2v2h-2z" fill="%2318a0fb"/%3E%3Cpath d="m17 74h-2v2h2z" fill="%2318a0fb"/%3E%3Cpath d="m15 79h2v2h-2z" fill="%2318a0fb"/%3E%3Cpath d="m17 84h-2v2h2z" fill="%2318a0fb"/%3E%3Cpath d="m10 106h2v2h-2z" fill="%23fff"/%3E%3Cpath d="m20 106h2v2h-2z" fill="%23fff"/%3E%3Cpath d="m12 111h-2v2h2z" fill="%23fff"/%3E%3Cpath d="m20 111h2v2h-2z" fill="%23fff"/%3E%3Cpath d="m12 116h-2v2h2z" fill="%23fff"/%3E%3Cpath d="m20 116h2v2h-2z" fill="%23fff"/%3E%3Cpath d="m17 106h-2v2h2z" fill="%23fff"/%3E%3Cpath d="m15 111h2v2h-2z" fill="%23fff"/%3E%3Cpath d="m17 116h-2v2h2z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_mask.scss:
--------------------------------------------------------------------------------
1 | .icon--mask {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m16 7.99893c-4.4188 0-8.00098 3.58217-8.00098 8.00107 0 4.4188 3.58218 8.001 8.00098 8.001 4.4189 0 8.0011-3.5822 8.0011-8.001 0-4.4189-3.5822-8.00107-8.0011-8.00107zm-1.965 1.27953c.6234-.18195 1.2828-.27953 1.965-.27953 3.8666 0 7.0011 3.13447 7.0011 7.00107 0 3.8665-3.1345 7.001-7.0011 7.001-.6815 0-1.3402-.0974-1.9631-.279 2.0967-1.4961 3.4638-3.949 3.4638-6.7211 0-2.7729-1.3679-5.2264-3.4657-6.72244z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16 39.9989c-4.4188 0-8.00098 3.5822-8.00098 8.0011 0 4.4188 3.58218 8.001 8.00098 8.001 4.4189 0 8.0011-3.5822 8.0011-8.001 0-4.4189-3.5822-8.0011-8.0011-8.0011zm-1.965 1.2796c.6234-.182 1.2828-.2796 1.965-.2796 3.8666 0 7.0011 3.1345 7.0011 7.0011 0 3.8665-3.1345 7.001-7.0011 7.001-.6815 0-1.3402-.0974-1.9631-.279 2.0967-1.4961 3.4638-3.949 3.4638-6.7211 0-2.7729-1.3679-5.2264-3.4657-6.7224z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16 71.9989c-4.4188 0-8.00098 3.5822-8.00098 8.0011 0 4.4188 3.58218 8.001 8.00098 8.001 4.4189 0 8.0011-3.5822 8.0011-8.001 0-4.4189-3.5822-8.0011-8.0011-8.0011zm-1.965 1.2796c.6234-.182 1.2828-.2796 1.965-.2796 3.8666 0 7.0011 3.1345 7.0011 7.0011 0 3.8665-3.1345 7.001-7.0011 7.001-.6815 0-1.3402-.0974-1.9631-.279 2.0967-1.4961 3.4638-3.949 3.4638-6.7211 0-2.7729-1.3679-5.2264-3.4657-6.7224z" fill="%2318a0fb"/%3E%3Cpath d="m16 103.999c-4.4188 0-8.00098 3.582-8.00098 8.001s3.58218 8.001 8.00098 8.001c4.4189 0 8.0011-3.582 8.0011-8.001s-3.5822-8.001-8.0011-8.001zm-1.965 1.279c.6234-.181 1.2828-.279 1.965-.279 3.8666 0 7.0011 3.134 7.0011 7.001s-3.1345 7.001-7.0011 7.001c-.6815 0-1.3402-.097-1.9631-.279 2.0967-1.496 3.4638-3.949 3.4638-6.721 0-2.773-1.3679-5.227-3.4657-6.723z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_layout-grid-uniform.scss:
--------------------------------------------------------------------------------
1 | .icon--layout-grid-uniform {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m9 9h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m20 9h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m14.5 9h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m9 14.5h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m20 14.5h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m14.5 14.5h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m9 20h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m20 20h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m14.5 20h3v3h-3z" fill-opacity=".8"/%3E%3Cpath d="m9 41h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m20 41h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m14.5 41h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m9 46.5h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m20 46.5h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m14.5 46.5h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m9 52h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m20 52h3v3h-3z" fill-opacity=".3"/%3E%3Cpath d="m14.5 52h3v3h-3z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m9 73h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m20 73h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m14.5 73h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m9 78.5h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m20 78.5h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m14.5 78.5h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m9 84h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m20 84h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m14.5 84h3v3h-3z" fill="%2318a0fb"/%3E%3Cpath d="m9 105h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m20 105h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m14.5 105h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m9 110.5h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m20 110.5h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m14.5 110.5h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m9 116h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m20 116h3v3h-3z" fill="%23fff"/%3E%3Cpath d="m14.5 116h3v3h-3z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_input-icon.scss:
--------------------------------------------------------------------------------
1 | .input-icon {
2 | position: relative;
3 | width: 100%;
4 |
5 | &__icon {
6 | position: absolute;
7 | top: -1px;
8 | left: 0;
9 | width: 32px;
10 | height: 32px;
11 | }
12 |
13 | &__input {
14 | @include font-ui-pos('small', 'normal');
15 |
16 | display: flex;
17 | align-items: center;
18 | width: 100%;
19 | height: 30px;
20 | margin: 1px 0 1px 0;
21 | padding: 8px 4px 8px 0;
22 |
23 | text-indent: 32px;
24 |
25 | color: $figma-black-8;
26 | border: 1px solid transparent;
27 | border-radius: $border-radius-small;
28 | outline: none;
29 | background-color: $figma-white;
30 |
31 | &:hover {
32 | color: $figma-black-8;
33 | border: 1px solid $figma-black-1;
34 | }
35 |
36 | &:active, &:focus {
37 | margin-left: -1px;
38 | padding: 8px 4px 8px 0;
39 |
40 | color: $figma-black;
41 | border: 2px solid $figma-blue;
42 | border-radius: $border-radius-small;
43 | }
44 |
45 | &::selection {
46 | color: $figma-black;
47 | background-color: $figma-blue-3;
48 | }
49 |
50 | &::placeholder {
51 | color: $figma-black-3;
52 | }
53 |
54 | &:not(:disabled):not(:hover):placeholder-shown {
55 | border: 1px solid transparent;
56 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAcAAAAABCAYAAABJ5n7WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgSURBVHgB7cMBCQAACMTAiR3sX1TQHr+DK2B+I0lSjj29qAEYlIbeBgAAAABJRU5ErkJggg==');
57 | background-repeat: no-repeat;
58 | background-position: center bottom -0.9px;
59 | background-size: calc(100% - 10px) 1px;
60 | }
61 |
62 | &:not(:disabled):focus:placeholder-shown {
63 | border: 2px solid $figma-blue;
64 | }
65 |
66 | &:not(:disabled):focus:not(:placeholder-shown) {
67 | padding-left: 0;
68 | }
69 |
70 | &:disabled {
71 | color: $figma-black-3;
72 | }
73 |
74 | &:disabled:hover {
75 | border: 1px solid transparent;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/base/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Type mixins
2 | @mixin font-ui-pos($size, $weight) {
3 | font-family: $font-stack;
4 |
5 | //weight
6 | @if $weight == 'bold' {
7 | font-weight: $font-weight-bold;
8 | } @else if $weight == 'medium' {
9 | font-weight: $font-weight-medium;
10 | } @else {
11 | font-weight: $font-weight-normal;
12 | }
13 | //letterspacing + size
14 | @if $size == 'small' {
15 | font-size: $font-size-small;
16 | line-height: $font-lineheight;
17 | letter-spacing: $font-letterspacing-pos-small;
18 | } @else if $size == 'medium' {
19 | font-size: $font-size-medium;
20 | line-height: $font-lineheight;
21 | letter-spacing: $font-letterspacing-pos-medium;
22 | } @else if $size == 'large' {
23 | font-size: $font-size-large;
24 | line-height: $font-lineheight-large;
25 | letter-spacing: $font-letterspacing-pos-xlarge;
26 | } @else {
27 | font-size: $font-size-xlarge;
28 | line-height: $font-lineheight-large;
29 | letter-spacing: $font-letterspacing-pos-xlarge;
30 | }
31 | }
32 |
33 | @mixin font-ui-neg($size, $weight) {
34 | font-family: $font-stack;
35 |
36 | //weight
37 | @if $weight == 'bold' {
38 | font-weight: $font-weight-bold;
39 | } @else if $weight == 'medium' {
40 | font-weight: $font-weight-medium;
41 | } @else {
42 | font-weight: $font-weight-normal;
43 | }
44 |
45 | //letterspacing + size
46 | @if $size == 'small' {
47 | font-size: $font-size-small;
48 | line-height: $font-lineheight;
49 | letter-spacing: $font-letterspacing-neg-small;
50 | } @else if $size == 'medium' {
51 | font-size: $font-size-medium;
52 | line-height: $font-lineheight;
53 | letter-spacing: $font-letterspacing-neg-medium;
54 | } @else if $size == 'large' {
55 | font-size: $font-size-large;
56 | line-height: $font-lineheight-large;
57 | letter-spacing: $font-letterspacing-neg-xlarge;
58 | } @else {
59 | font-size: $font-size-xlarge;
60 | line-height: $font-lineheight-large;
61 | letter-spacing: $font-letterspacing-neg-xlarge;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_group.scss:
--------------------------------------------------------------------------------
1 | .icon--group {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m17.4 9h-2.8v1h2.8z" fill-opacity=".8"/%3E%3Cpath d="m20.9 22h1.1v-1.1h1v2.1h-2.1z" fill-opacity=".8"/%3E%3Cpath d="m10 14.6v2.8h-1v-2.8z" fill-opacity=".8"/%3E%3Cpath d="m22 11.1v-1.1h-1.1v-1h2.1v2.1z" fill-opacity=".8"/%3E%3Cpath d="m22 14.6v2.8h1v-2.8z" fill-opacity=".8"/%3E%3Cpath d="m10 11.1v-1.1h1.1v-1h-2.1v2.1z" fill-opacity=".8"/%3E%3Cpath d="m9 20.9h1v1.1h1.1v1h-2.1z" fill-opacity=".8"/%3E%3Cpath d="m17.4 22h-2.8v1h2.8z" fill-opacity=".8"/%3E%3Cpath d="m17.4 41h-2.8v1h2.8z" fill-opacity=".3"/%3E%3Cpath d="m20.9 54h1.1v-1.1h1v2.1h-2.1z" fill-opacity=".3"/%3E%3Cpath d="m10 46.6v2.8h-1v-2.8z" fill-opacity=".3"/%3E%3Cpath d="m22 43.1v-1.1h-1.1v-1h2.1v2.1z" fill-opacity=".3"/%3E%3Cpath d="m22 46.6v2.8h1v-2.8z" fill-opacity=".3"/%3E%3Cpath d="m10 43.1v-1.1h1.1v-1h-2.1v2.1z" fill-opacity=".3"/%3E%3Cpath d="m9 52.9h1v1.1h1.1v1h-2.1z" fill-opacity=".3"/%3E%3Cpath d="m17.4 54h-2.8v1h2.8z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m17.4 73h-2.8v1h2.8z" fill="%2318a0fb"/%3E%3Cpath d="m20.9 86h1.1v-1.1h1v2.1h-2.1z" fill="%2318a0fb"/%3E%3Cpath d="m10 78.6v2.8h-1v-2.8z" fill="%2318a0fb"/%3E%3Cpath d="m22 75.1v-1.1h-1.1v-1h2.1v2.1z" fill="%2318a0fb"/%3E%3Cpath d="m22 78.6v2.8h1v-2.8z" fill="%2318a0fb"/%3E%3Cpath d="m10 75.1v-1.1h1.1v-1h-2.1v2.1z" fill="%2318a0fb"/%3E%3Cpath d="m9 84.9h1v1.1h1.1v1h-2.1z" fill="%2318a0fb"/%3E%3Cpath d="m17.4 86h-2.8v1h2.8z" fill="%2318a0fb"/%3E%3Cpath d="m17.4 105h-2.8v1h2.8z" fill="%23fff"/%3E%3Cpath d="m20.9 118h1.1v-1.1h1v2.1h-2.1z" fill="%23fff"/%3E%3Cpath d="m10 110.6v2.8h-1v-2.8z" fill="%23fff"/%3E%3Cpath d="m22 107.1v-1.1h-1.1v-1h2.1v2.1z" fill="%23fff"/%3E%3Cpath d="m22 110.6v2.8h1v-2.8z" fill="%23fff"/%3E%3Cpath d="m10 107.1v-1.1h1.1v-1h-2.1v2.1z" fill="%23fff"/%3E%3Cpath d="m9 116.9h1v1.1h1.1v1h-2.1z" fill="%23fff"/%3E%3Cpath d="m17.4 118h-2.8v1h2.8z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_visible.scss:
--------------------------------------------------------------------------------
1 | .icon--visible {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m16.0004 18c1.1045 0 2-.8954 2-2s-.8955-2-2-2c-1.1046 0-2 .8954-2 2s.8954 2 2 2z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m16.0001 12c2.878 0 5.3774 1.6211 6.6349 4-1.2575 2.3789-3.7569 4-6.6349 4-2.8781 0-5.3775-1.6211-6.63499-4 1.25749-2.3789 3.75689-4 6.63499-4zm0 7c-2.2999 0-4.3222-1.1942-5.4784-3 1.1562-1.8058 3.1785-3 5.4784-3 2.2998 0 4.3221 1.1942 5.4783 3-1.1562 1.8058-3.1785 3-5.4783 3z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m16.0004 50c1.1045 0 2-.8954 2-2s-.8955-2-2-2c-1.1046 0-2 .8954-2 2s.8954 2 2 2z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m16.0001 44c2.878 0 5.3774 1.6211 6.6349 4-1.2575 2.3789-3.7569 4-6.6349 4-2.8781 0-5.3775-1.6211-6.63499-4 1.25749-2.3789 3.75689-4 6.63499-4zm0 7c-2.2999 0-4.3222-1.1942-5.4784-3 1.1562-1.8058 3.1785-3 5.4784-3 2.2998 0 4.3221 1.1942 5.4783 3-1.1562 1.8058-3.1785 3-5.4783 3z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m16.0004 82c1.1045 0 2-.8954 2-2s-.8955-2-2-2c-1.1046 0-2 .8954-2 2s.8954 2 2 2z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m16.0001 76c2.878 0 5.3774 1.6211 6.6349 4-1.2575 2.3789-3.7569 4-6.6349 4-2.8781 0-5.3775-1.6211-6.63499-4 1.25749-2.3789 3.75689-4 6.63499-4zm0 7c-2.2999 0-4.3222-1.1942-5.4784-3 1.1562-1.8058 3.1785-3 5.4784-3 2.2998 0 4.3221 1.1942 5.4783 3-1.1562 1.8058-3.1785 3-5.4783 3z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m16.0004 114c1.1045 0 2-.895 2-2s-.8955-2-2-2c-1.1046 0-2 .895-2 2s.8954 2 2 2z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m16.0001 108c2.878 0 5.3774 1.621 6.6349 4-1.2575 2.379-3.7569 4-6.6349 4-2.8781 0-5.3775-1.621-6.63499-4 1.25749-2.379 3.75689-4 6.63499-4zm0 7c-2.2999 0-4.3222-1.194-5.4784-3 1.1562-1.806 3.1785-3 5.4784-3 2.2998 0 4.3221 1.194 5.4783 3-1.1562 1.806-3.1785 3-5.4783 3z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_styles.scss:
--------------------------------------------------------------------------------
1 | .icon--styles {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m11.5 13c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill-opacity=".8"/%3E%3Cpath d="m17.5 13c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill-opacity=".8"/%3E%3Cpath d="m19 20.5c-.8284 0-1.5-.6716-1.5-1.5s.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5-.6716 1.5-1.5 1.5z" fill-opacity=".8"/%3E%3Cpath d="m11.5 19c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill-opacity=".8"/%3E%3Cpath d="m11.5 45c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill-opacity=".3"/%3E%3Cpath d="m17.5 45c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill-opacity=".3"/%3E%3Cpath d="m19 52.5c-.8284 0-1.5-.6716-1.5-1.5s.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5-.6716 1.5-1.5 1.5z" fill-opacity=".3"/%3E%3Cpath d="m11.5 51c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m11.5 77c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill="%2318a0fb"/%3E%3Cpath d="m17.5 77c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill="%2318a0fb"/%3E%3Cpath d="m19 84.5c-.8284 0-1.5-.6716-1.5-1.5s.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5-.6716 1.5-1.5 1.5z" fill="%2318a0fb"/%3E%3Cpath d="m11.5 83c0 .8284.6716 1.5 1.5 1.5s1.5-.6716 1.5-1.5-.6716-1.5-1.5-1.5-1.5.6716-1.5 1.5z" fill="%2318a0fb"/%3E%3Cpath d="m11.5 109c0 .828.6716 1.5 1.5 1.5s1.5-.672 1.5-1.5-.6716-1.5-1.5-1.5-1.5.672-1.5 1.5z" fill="%23fff"/%3E%3Cpath d="m17.5 109c0 .828.6716 1.5 1.5 1.5s1.5-.672 1.5-1.5-.6716-1.5-1.5-1.5-1.5.672-1.5 1.5z" fill="%23fff"/%3E%3Cpath d="m19 116.5c-.8284 0-1.5-.672-1.5-1.5s.6716-1.5 1.5-1.5 1.5.672 1.5 1.5-.6716 1.5-1.5 1.5z" fill="%23fff"/%3E%3Cpath d="m11.5 115c0 .828.6716 1.5 1.5 1.5s1.5-.672 1.5-1.5-.6716-1.5-1.5-1.5-1.5.672-1.5 1.5z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_hidden.scss:
--------------------------------------------------------------------------------
1 | .icon--hidden {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m21.5085 15.8012c.5554-.5276 1.0351-1.134 1.421-1.8012h-1.1842c-1.2655 1.8142-3.3673 3-5.7454 3-2.3782 0-4.48-1.1858-5.7454-3h-1.18428c.38597.6673.86567 1.2737 1.42108 1.8013l-1.59482 1.5949.70712.7071 1.6573-1.6574c.7108.5234 1.5112.9321 2.3742 1.1988l-.6171 2.2213.9636.2676.6262-2.2543c.452.0793.9172.1207 1.3921.1207.4748 0 .9399-.0414 1.392-.1207l.6261 2.2543.9636-.2676-.617-2.2213c.863-.2666 1.6635-.6754 2.3743-1.1989l1.6576 1.6575.7071-.7071z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m21.5085 47.8012c.5554-.5276 1.0351-1.134 1.421-1.8012h-1.1842c-1.2655 1.8142-3.3673 3-5.7454 3-2.3782 0-4.48-1.1858-5.7454-3h-1.18428c.38597.6673.86567 1.2737 1.42108 1.8013l-1.59482 1.5949.70712.7071 1.6573-1.6574c.7108.5234 1.5112.9321 2.3742 1.1988l-.6171 2.2213.9636.2676.6262-2.2543c.452.0793.9172.1207 1.3921.1207.4748 0 .9399-.0414 1.392-.1207l.6261 2.2543.9636-.2676-.617-2.2213c.863-.2666 1.6635-.6754 2.3743-1.1989l1.6576 1.6575.7071-.7071z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m21.5085 79.8012c.5554-.5276 1.0351-1.134 1.421-1.8012h-1.1842c-1.2655 1.8142-3.3673 3-5.7454 3-2.3782 0-4.48-1.1858-5.7454-3h-1.18428c.38597.6673.86567 1.2737 1.42108 1.8013l-1.59482 1.5949.70712.7071 1.6573-1.6574c.7108.5234 1.5112.9321 2.3742 1.1988l-.6171 2.2213.9636.2676.6262-2.2543c.452.0793.9172.1207 1.3921.1207.4748 0 .9399-.0414 1.392-.1207l.6261 2.2543.9636-.2676-.617-2.2213c.863-.2666 1.6635-.6754 2.3743-1.1989l1.6576 1.6575.7071-.7071z" fill="%2318a0fb"/%3E%3Cpath d="m21.5085 111.801c.5554-.527 1.0351-1.134 1.421-1.801h-1.1842c-1.2655 1.814-3.3673 3-5.7454 3-2.3782 0-4.48-1.186-5.7454-3h-1.18428c.38597.667.86567 1.274 1.42108 1.801l-1.59482 1.595.70712.707 1.6573-1.657c.7108.523 1.5112.932 2.3742 1.199l-.6171 2.221.9636.268.6262-2.255c.452.08.9172.121 1.3921.121.4748 0 .9399-.041 1.392-.121l.6261 2.255.9636-.268-.617-2.221c.863-.267 1.6635-.676 2.3743-1.199l1.6576 1.657.7071-.707z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_disclosure.scss:
--------------------------------------------------------------------------------
1 | .disclosure {
2 | position: relative;
3 | display: block;
4 | width: 100%;
5 | margin: 0;
6 | padding: 0;
7 | list-style-type: none;
8 |
9 | &__item {
10 | @include font-ui-pos('small','normal');
11 |
12 | display: flex;
13 | flex-direction: column;
14 |
15 | border-bottom: 1px solid $figma-silver;
16 | background-color: $figma-white;
17 |
18 | &:last-child {
19 | border-bottom: 1px solid transparent;
20 | }
21 | }
22 |
23 | &__label {
24 | @include font-ui-pos('small','normal');
25 |
26 | position: relative;
27 | display: flex;
28 | align-items: center;
29 | height: 32px;
30 | padding: 0 8px 0 24px;
31 |
32 | cursor: default;
33 | user-select: none;
34 |
35 | color: $figma-black-8;
36 |
37 | &:before {
38 | position: absolute;
39 | top: 8px;
40 | left: 4px;
41 | display: block;
42 | width: 16px;
43 | height: 16px;
44 |
45 | content: '';
46 |
47 | opacity: 0.3;
48 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20width%3D%2216%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m11%208-4-3v6z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E');
49 | background-repeat: no-repeat;
50 | background-position: center center;
51 | }
52 |
53 | &:hover {
54 | &:before {
55 | opacity: 0.8;
56 | }
57 | }
58 | }
59 |
60 | &__content {
61 | @include font-ui-pos('small','normal');
62 |
63 | display: none;
64 | padding: 8px 8px 8px 24px;
65 |
66 | color: $figma-black-8;
67 | }
68 |
69 | &--section & {
70 | &__label {
71 | @include font-ui-pos('small','bold');
72 | }
73 | }
74 |
75 | &--expanded & {
76 | &__content {
77 | display: block;
78 |
79 | border-bottom: 1px solid transparent;
80 | }
81 |
82 | &__label {
83 | &:before {
84 | opacity: 0.8;
85 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20width%3D%2216%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m9%2010%203-4h-6z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E');
86 | }
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_adjust.scss:
--------------------------------------------------------------------------------
1 | .icon--adjust {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cg clip-rule=\'evenodd\' fill-rule=\'evenodd\'%3E%3Cg fill=\'%23000\'%3E%3Cpath d=\'m12 16.05v-7.05h1v7.05c1.1411.2316 2 1.2405 2 2.45s-.8589 2.2184-2 2.45v2.05h-1v-2.05c-1.1411-.2316-2-1.2405-2-2.45s.8589-2.2184 2-2.45zm2 2.45c0 .8284-.6716 1.5-1.5 1.5s-1.5-.6716-1.5-1.5.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m19 23h1v-7.05c1.1411-.2316 2-1.2405 2-2.45s-.8589-2.2184-2-2.45v-2.05h-1v2.05c-1.1411.2316-2 1.2405-2 2.45s.8589 2.2184 2 2.45zm2-9.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5 1.5-.6716 1.5-1.5z\' fill-opacity=\'.8\'/%3E%3Cpath d=\'m12 48.05v-7.05h1v7.05c1.1411.2316 2 1.2405 2 2.45s-.8589 2.2184-2 2.45v2.05h-1v-2.05c-1.1411-.2316-2-1.2405-2-2.45s.8589-2.2184 2-2.45zm2 2.45c0 .8284-.6716 1.5-1.5 1.5s-1.5-.6716-1.5-1.5.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5z\' fill-opacity=\'.3\'/%3E%3Cpath d=\'m19 55h1v-7.05c1.1411-.2316 2-1.2405 2-2.45s-.8589-2.2184-2-2.45v-2.05h-1v2.05c-1.1411.2316-2 1.2405-2 2.45s.8589 2.2184 2 2.45zm2-9.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5 1.5-.6716 1.5-1.5z\' fill-opacity=\'.3\'/%3E%3C/g%3E%3Cpath d=\'m12 80.05v-7.05h1v7.05c1.1411.2316 2 1.2405 2 2.45s-.8589 2.2184-2 2.45v2.05h-1v-2.05c-1.1411-.2316-2-1.2405-2-2.45s.8589-2.2184 2-2.45zm2 2.45c0 .8284-.6716 1.5-1.5 1.5s-1.5-.6716-1.5-1.5.6716-1.5 1.5-1.5 1.5.6716 1.5 1.5z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m19 87h1v-7.05c1.1411-.2316 2-1.2405 2-2.45s-.8589-2.2184-2-2.45v-2.05h-1v2.05c-1.1411.2316-2 1.2405-2 2.45s.8589 2.2184 2 2.45zm2-9.5c0-.8284-.6716-1.5-1.5-1.5s-1.5.6716-1.5 1.5.6716 1.5 1.5 1.5 1.5-.6716 1.5-1.5z\' fill=\'%2318a0fb\'/%3E%3Cpath d=\'m12 112.05v-7.05h1v7.05c1.1411.232 2 1.241 2 2.45s-.8589 2.218-2 2.45v2.05h-1v-2.05c-1.1411-.232-2-1.241-2-2.45s.8589-2.218 2-2.45zm2 2.45c0 .828-.6716 1.5-1.5 1.5s-1.5-.672-1.5-1.5.6716-1.5 1.5-1.5 1.5.672 1.5 1.5z\' fill=\'%23fff\'/%3E%3Cpath d=\'m19 119h1v-7.05c1.1411-.232 2-1.241 2-2.45s-.8589-2.218-2-2.45v-2.05h-1v2.05c-1.1411.232-2 1.241-2 2.45s.8589 2.218 2 2.45zm2-9.5c0-.828-.6716-1.5-1.5-1.5s-1.5.672-1.5 1.5.6716 1.5 1.5 1.5 1.5-.672 1.5-1.5z\' fill=\'%23fff\'/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_hyperlink.scss:
--------------------------------------------------------------------------------
1 | .icon--hyperlink {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m13.5 18c1.9593 0 3.6262-1.2522 4.2439-3h1.0491c-.653 2.3085-2.7754 4-5.293 4-3.0376 0-5.5-2.4624-5.5-5.5s2.4624-5.5 5.5-5.5c2.5176 0 4.64 1.6915 5.293 4h-1.0491c-.6177-1.7478-2.2846-3-4.2439-3-2.4853 0-4.5 2.0147-4.5 4.5s2.0147 4.5 4.5 4.5z" fill-opacity=".8"/%3E%3Cpath d="m18.5 23c2.4853 0 4.5-2.0147 4.5-4.5s-2.0147-4.5-4.5-4.5c-1.9593 0-3.6262 1.2522-4.2439 3h-1.0491c.653-2.3085 2.7754-4 5.293-4 3.0376 0 5.5 2.4624 5.5 5.5s-2.4624 5.5-5.5 5.5c-2.5176 0-4.64-1.6915-5.293-4h1.0491c.6177 1.7478 2.2846 3 4.2439 3z" fill-opacity=".8"/%3E%3Cpath d="m13.5 50c1.9593 0 3.6262-1.2522 4.2439-3h1.0491c-.653 2.3085-2.7754 4-5.293 4-3.0376 0-5.5-2.4624-5.5-5.5s2.4624-5.5 5.5-5.5c2.5176 0 4.64 1.6915 5.293 4h-1.0491c-.6177-1.7478-2.2846-3-4.2439-3-2.4853 0-4.5 2.0147-4.5 4.5s2.0147 4.5 4.5 4.5z" fill-opacity=".3"/%3E%3Cpath d="m18.5 55c2.4853 0 4.5-2.0147 4.5-4.5s-2.0147-4.5-4.5-4.5c-1.9593 0-3.6262 1.2522-4.2439 3h-1.0491c.653-2.3085 2.7754-4 5.293-4 3.0376 0 5.5 2.4624 5.5 5.5s-2.4624 5.5-5.5 5.5c-2.5176 0-4.64-1.6915-5.293-4h1.0491c.6177 1.7478 2.2846 3 4.2439 3z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m13.5 82c1.9593 0 3.6262-1.2522 4.2439-3h1.0491c-.653 2.3085-2.7754 4-5.293 4-3.0376 0-5.5-2.4624-5.5-5.5s2.4624-5.5 5.5-5.5c2.5176 0 4.64 1.6915 5.293 4h-1.0491c-.6177-1.7478-2.2846-3-4.2439-3-2.4853 0-4.5 2.0147-4.5 4.5s2.0147 4.5 4.5 4.5z" fill="%2318a0fb"/%3E%3Cpath d="m18.5 87c2.4853 0 4.5-2.0147 4.5-4.5s-2.0147-4.5-4.5-4.5c-1.9593 0-3.6262 1.2522-4.2439 3h-1.0491c.653-2.3085 2.7754-4 5.293-4 3.0376 0 5.5 2.4624 5.5 5.5s-2.4624 5.5-5.5 5.5c-2.5176 0-4.64-1.6915-5.293-4h1.0491c.6177 1.7478 2.2846 3 4.2439 3z" fill="%2318a0fb"/%3E%3Cpath d="m13.5 114c1.9593 0 3.6262-1.252 4.2439-3h1.0491c-.653 2.309-2.7754 4-5.293 4-3.0376 0-5.5-2.462-5.5-5.5s2.4624-5.5 5.5-5.5c2.5176 0 4.64 1.691 5.293 4h-1.0491c-.6177-1.748-2.2846-3-4.2439-3-2.4853 0-4.5 2.015-4.5 4.5s2.0147 4.5 4.5 4.5z" fill="%23fff"/%3E%3Cpath d="m18.5 119c2.4853 0 4.5-2.015 4.5-4.5s-2.0147-4.5-4.5-4.5c-1.9593 0-3.6262 1.252-4.2439 3h-1.0491c.653-2.309 2.7754-4 5.293-4 3.0376 0 5.5 2.462 5.5 5.5s-2.4624 5.5-5.5 5.5c-2.5176 0-4.64-1.691-5.293-4h1.0491c.6177 1.748 2.2846 3 4.2439 3z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_alert.scss:
--------------------------------------------------------------------------------
1 | .icon--alert {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath clip-rule="evenodd" d="m21.25 17.3929c0 .72.4349 1.3385 1.0563 1.6071.2127.0919.4473.1429.6937.1429v.8571h-14v-.8571c.24643 0 .48097-.051.69365-.1429.62145-.2686 1.05635-.8871 1.05635-1.6071v-3.3929c0-3.3137 2.3505-6 5.25-6s5.25 2.6863 5.25 6zm-1-3.3929v3.3929c0 .5999.1921 1.155.5182 1.6071h-9.5364c.3261-.4521.5182-1.0072.5182-1.6071v-3.3929c0-2.891 2.024-5 4.25-5s4.25 2.109 4.25 5z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m16 23c-1.1046 0-2-.8954-2-2h-1c0 1.6569 1.3431 3 3 3s3-1.3431 3-3h-1c0 1.1046-.8954 2-2 2z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m21.25 49.3929c0 .72.4349 1.3385 1.0563 1.6071.2127.0919.4473.1429.6937.1429v.8571h-14v-.8571c.24643 0 .48097-.051.69365-.1429.62145-.2686 1.05635-.8871 1.05635-1.6071v-3.3929c0-3.3137 2.3505-6 5.25-6s5.25 2.6863 5.25 6zm-1-3.3929v3.3929c0 .5999.1921 1.155.5182 1.6071h-9.5364c.3261-.4521.5182-1.0072.5182-1.6071v-3.3929c0-2.891 2.024-5 4.25-5s4.25 2.109 4.25 5z" fill-opacity=".3" fill-rule="evenodd"/%3E%3Cpath d="m16 55c-1.1046 0-2-.8954-2-2h-1c0 1.6569 1.3431 3 3 3s3-1.3431 3-3h-1c0 1.1046-.8954 2-2 2z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath clip-rule="evenodd" d="m21.25 81.3929c0 .72.4349 1.3385 1.0563 1.6071.2127.0919.4473.1429.6937.1429v.8571h-14v-.8571c.24643 0 .48097-.051.69365-.1429.62145-.2686 1.05635-.8871 1.05635-1.6071v-3.3929c0-3.3137 2.3505-6 5.25-6s5.25 2.6863 5.25 6zm-1-3.3929v3.3929c0 .5999.1921 1.155.5182 1.6071h-9.5364c.3261-.4521.5182-1.0072.5182-1.6071v-3.3929c0-2.891 2.024-5 4.25-5s4.25 2.109 4.25 5z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m16 87c-1.1046 0-2-.8954-2-2h-1c0 1.6569 1.3431 3 3 3s3-1.3431 3-3h-1c0 1.1046-.8954 2-2 2z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m21.25 113.393c0 .72.4349 1.338 1.0563 1.607.2127.092.4473.143.6937.143v.857h-14v-.857c.24643 0 .48097-.051.69365-.143.62145-.269 1.05635-.887 1.05635-1.607v-3.393c0-3.314 2.3505-6 5.25-6s5.25 2.686 5.25 6zm-1-3.393v3.393c0 .6.1921 1.155.5182 1.607h-9.5364c.3261-.452.5182-1.007.5182-1.607v-3.393c0-2.891 2.024-5 4.25-5s4.25 2.109 4.25 5z" fill="%23fff" fill-rule="evenodd"/%3E%3Cpath d="m16 119c-1.1046 0-2-.895-2-2h-1c0 1.657 1.3431 3 3 3s3-1.343 3-3h-1c0 1.105-.8954 2-2 2z" fill="%23fff"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_blend.scss:
--------------------------------------------------------------------------------
1 | .icon--blend {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m16.0016 11.0016c.2421.2504.4732.4895.6932.7185 2.2035 2.2923 3.3052 3.5738 3.3052 5.1318.0025 1.0624-.388 2.1256-1.1716 2.9361-1.562 1.616-4.0947 1.616-5.6567 0-.7836-.8105-1.1742-1.8737-1.1717-2.9361 0-1.558 1.1018-2.8395 3.3053-5.1318.2201-.229.4512-.4681.6933-.7186l.001-.001zm-2.1968 3.9096c.5019-.6803 1.2187-1.4542 2.1953-2.4708.9764 1.0166 1.6933 1.7905 2.1951 2.4708.5998.8133.8048 1.38.8048 1.9407v.0024c.0001.0486-.0008.0972-.0029.1457h-5.9942c-.002-.0485-.003-.0971-.0029-.1458v-.0023c0-.5607.205-1.1274.8048-1.9407z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16.0016 43.0016c.2421.2504.4732.4895.6932.7185 2.2035 2.2923 3.3052 3.5738 3.3052 5.1318.0025 1.0624-.388 2.1256-1.1716 2.9361-1.562 1.616-4.0947 1.616-5.6567 0-.7836-.8105-1.1742-1.8737-1.1717-2.9361 0-1.558 1.1018-2.8395 3.3053-5.1318.2201-.229.4512-.4681.6933-.7186l.001-.001zm-2.1968 3.9096c.5019-.6803 1.2187-1.4542 2.1953-2.4708.9764 1.0166 1.6933 1.7905 2.1951 2.4708.5998.8133.8048 1.38.8048 1.9407v.0024c.0001.0486-.0008.0972-.0029.1457h-5.9942c-.002-.0485-.003-.0971-.0029-.1458v-.0023c0-.5607.205-1.1274.8048-1.9407z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16.0016 75.0016c.2421.2504.4732.4895.6932.7185 2.2035 2.2923 3.3052 3.5738 3.3052 5.1318.0025 1.0624-.388 2.1256-1.1716 2.9361-1.562 1.616-4.0947 1.616-5.6567 0-.7836-.8105-1.1742-1.8737-1.1717-2.9361 0-1.558 1.1018-2.8395 3.3053-5.1318.2201-.229.4512-.4681.6933-.7186l.001-.001zm-2.1968 3.9096c.5019-.6803 1.2187-1.4542 2.1953-2.4708.9764 1.0166 1.6933 1.7905 2.1951 2.4708.5998.8133.8048 1.38.8048 1.9407v.0024c.0001.0486-.0008.0972-.0029.1457h-5.9942c-.002-.0485-.003-.0971-.0029-.1458v-.0023c0-.5607.205-1.1274.8048-1.9407z" fill="%2318a0fb"/%3E%3Cpath d="m16.0016 107.002c.2421.25.4732.489.6932.718 2.2035 2.292 3.3052 3.574 3.3052 5.132.0025 1.062-.388 2.125-1.1716 2.936-1.562 1.616-4.0947 1.616-5.6567 0-.7836-.811-1.1742-1.874-1.1717-2.936 0-1.558 1.1018-2.84 3.3053-5.132.2201-.229.4512-.468.6933-.718l.001-.002zm-2.1968 3.909c.5019-.68 1.2187-1.454 2.1953-2.471.9764 1.017 1.6933 1.791 2.1951 2.471.5998.813.8048 1.38.8048 1.941v.002c.0001.049-.0008.097-.0029.146h-5.9942c-.002-.049-.003-.097-.0029-.146v-.002c0-.561.205-1.128.8048-1.941z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_image.scss:
--------------------------------------------------------------------------------
1 | .icon--image {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cg fill="%23000"%3E%3Cpath d="m20.6667 13.6667c0 1.2886-1.0447 2.3333-2.3334 2.3333-1.2886 0-2.3333-1.0447-2.3333-2.3333 0-1.2887 1.0447-2.3334 2.3333-2.3334 1.2887 0 2.3334 1.0447 2.3334 2.3334zm-1 0c0 .7363-.597 1.3333-1.3334 1.3333-.7363 0-1.3333-.597-1.3333-1.3333 0-.7364.597-1.3334 1.3333-1.3334.7364 0 1.3334.597 1.3334 1.3334z" fill-opacity=".8"/%3E%3Cpath d="m10 9c-.55228 0-1 .44772-1 1v12c0 .5523.44772 1 1 1h12c.5523 0 1-.4477 1-1v-12c0-.55228-.4477-1-1-1zm12 1h-12v7.7929l3.0833-3.0833 7.2905 7.2904h1.6262zm-12 12v-2.7929l3.0833-3.0833 5.8763 5.8762z" fill-opacity=".8"/%3E%3Cpath d="m20.6667 45.6667c0 1.2886-1.0447 2.3333-2.3334 2.3333-1.2886 0-2.3333-1.0447-2.3333-2.3333 0-1.2887 1.0447-2.3334 2.3333-2.3334 1.2887 0 2.3334 1.0447 2.3334 2.3334zm-1 0c0 .7363-.597 1.3333-1.3334 1.3333-.7363 0-1.3333-.597-1.3333-1.3333 0-.7364.597-1.3334 1.3333-1.3334.7364 0 1.3334.597 1.3334 1.3334z" fill-opacity=".3"/%3E%3Cpath d="m10 41c-.55228 0-1 .4477-1 1v12c0 .5523.44772 1 1 1h12c.5523 0 1-.4477 1-1v-12c0-.5523-.4477-1-1-1zm12 1h-12v7.7929l3.0833-3.0833 7.2905 7.2904h1.6262zm-12 12v-2.7929l3.0833-3.0833 5.8763 5.8762z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m20.6667 77.6667c0 1.2886-1.0447 2.3333-2.3334 2.3333-1.2886 0-2.3333-1.0447-2.3333-2.3333 0-1.2887 1.0447-2.3334 2.3333-2.3334 1.2887 0 2.3334 1.0447 2.3334 2.3334zm-1 0c0 .7363-.597 1.3333-1.3334 1.3333-.7363 0-1.3333-.597-1.3333-1.3333 0-.7364.597-1.3334 1.3333-1.3334.7364 0 1.3334.597 1.3334 1.3334z" fill="%2318a0fb"/%3E%3Cpath d="m10 73c-.55228 0-1 .4477-1 1v12c0 .5523.44772 1 1 1h12c.5523 0 1-.4477 1-1v-12c0-.5523-.4477-1-1-1zm12 1h-12v7.7929l3.0833-3.0833 7.2905 7.2904h1.6262zm-12 12v-2.7929l3.0833-3.0833 5.8763 5.8762z" fill="%2318a0fb"/%3E%3Cpath d="m20.6667 109.667c0 1.288-1.0447 2.333-2.3334 2.333-1.2886 0-2.3333-1.045-2.3333-2.333 0-1.289 1.0447-2.334 2.3333-2.334 1.2887 0 2.3334 1.045 2.3334 2.334zm-1 0c0 .736-.597 1.333-1.3334 1.333-.7363 0-1.3333-.597-1.3333-1.333 0-.737.597-1.334 1.3333-1.334.7364 0 1.3334.597 1.3334 1.334z" fill="%23fff"/%3E%3Cpath d="m10 105c-.55228 0-1 .448-1 1v12c0 .552.44772 1 1 1h12c.5523 0 1-.448 1-1v-12c0-.552-.4477-1-1-1zm12 1h-12v7.793l3.0833-3.083 7.2905 7.29h1.6262zm-12 12v-2.793l3.0833-3.083 5.8763 5.876z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin')
2 | const HtmlWebpackPlugin = require('html-webpack-plugin')
3 | const path = require('path')
4 | const webpack = require('webpack');
5 |
6 | module.exports = (env, argv) => ({
7 | mode: argv.mode === 'production' ? 'production' : 'development',
8 |
9 | // This is necessary because Figma's 'eval' works differently than normal eval
10 | devtool: argv.mode === 'production' ? false : 'inline-source-map',
11 |
12 | entry: {
13 | ui: './src/ui.tsx', // The entry point for your UI code
14 | code: './src/code.ts', // The entry point for your plugin code
15 | },
16 |
17 | module: {
18 | rules: [
19 | // Converts TypeScript code to JavaScript
20 | {
21 | test: /\.tsx?$/,
22 | use: 'ts-loader',
23 | exclude: /node_modules/
24 | },
25 |
26 | // Enables including CSS by doing "import './file.css'" in your TypeScript code
27 | {
28 | test: /\.css$/,
29 | loader: [{
30 | loader: 'style-loader'
31 | }, {
32 | loader: 'css-loader'
33 | }]
34 | },
35 |
36 | // Enables including CSS by doing "import './file.scss'" in your TypeScript code
37 | {
38 | test: /\.scss$/,
39 | use: [
40 | "style-loader", // creates style nodes from JS strings
41 | "css-loader", // translates CSS into CommonJS
42 | "sass-loader" // compiles Sass to CSS, using Node Sass by default
43 | ]
44 | },
45 |
46 | // Allows you to use "<%= require('./file.svg') %>" in your HTML code to get a data URI
47 | {
48 | test: /\.(png|jpg|gif|webp|svg)$/,
49 | loader: [{
50 | loader: 'url-loader'
51 | }]
52 | },
53 | ],
54 | },
55 |
56 | // Webpack tries these extensions for you if you omit the extension like "import './file'"
57 | resolve: {
58 | extensions: ['.tsx', '.ts', '.jsx', '.js']
59 | },
60 |
61 | output: {
62 | filename: '[name].js',
63 | path: path.resolve(__dirname, 'dist'), // Compile into a folder called "dist"
64 | },
65 |
66 | // Tells Webpack to generate "ui.html" and to inline "ui.ts" into it
67 | plugins: [
68 | new HtmlWebpackPlugin({
69 | template: './src/ui.html',
70 | filename: 'ui.html',
71 | inlineSource: '.(js)$',
72 | chunks: ['ui'],
73 | }),
74 | new HtmlWebpackInlineSourcePlugin(),
75 | ],
76 | })
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_component.scss:
--------------------------------------------------------------------------------
1 | .icon--component {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cg fill="%23000"%3E%3Cpath d="m12.0625 10.9375 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.52329z" fill-opacity=".8"/%3E%3Cpath d="m12.0625 21.0625 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill-opacity=".8"/%3E%3Cpath d="m7 16 3.9375-3.9375 3.9375 3.9375-3.9375 3.9375zm3.9375 2.5233 2.5233-2.5233-2.5233-2.5233-2.52329 2.5233z" fill-opacity=".8"/%3E%3Cpath d="m17.125 16 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill-opacity=".8"/%3E%3Cpath d="m12.0625 42.9375 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill-opacity=".3"/%3E%3Cpath d="m12.0625 53.0625 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill-opacity=".3"/%3E%3Cpath d="m7 48 3.9375-3.9375 3.9375 3.9375-3.9375 3.9375zm3.9375 2.5233 2.5233-2.5233-2.5233-2.5233-2.52329 2.5233z" fill-opacity=".3"/%3E%3Cpath d="m17.125 48 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill-opacity=".3"/%3E%3C/g%3E%3Cpath d="m12.0625 74.9375 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill="%2318a0fb"/%3E%3Cpath d="m12.0625 85.0625 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill="%2318a0fb"/%3E%3Cpath d="m7 80 3.9375-3.9375 3.9375 3.9375-3.9375 3.9375zm3.9375 2.5233 2.5233-2.5233-2.5233-2.5233-2.52329 2.5233z" fill="%2318a0fb"/%3E%3Cpath d="m17.125 80 3.9375 3.9375 3.9375-3.9375-3.9375-3.9375zm6.4608 0-2.5233 2.5233-2.5233-2.5233 2.5233-2.5233z" fill="%2318a0fb"/%3E%3Cpath d="m12.0625 106.938 3.9375 3.937 3.9375-3.937-3.9375-3.938zm6.4608 0-2.5233 2.523-2.5233-2.523 2.5233-2.524z" fill="%23fff"/%3E%3Cpath d="m12.0625 117.062 3.9375 3.938 3.9375-3.938-3.9375-3.937zm6.4608 0-2.5233 2.524-2.5233-2.524 2.5233-2.523z" fill="%23fff"/%3E%3Cpath d="m7 112 3.9375-3.938 3.9375 3.938-3.9375 3.938zm3.9375 2.523 2.5233-2.523-2.5233-2.523-2.52329 2.523z" fill="%23fff"/%3E%3Cpath d="m17.125 112 3.9375 3.938 3.9375-3.938-3.9375-3.938zm6.4608 0-2.5233 2.523-2.5233-2.523 2.5233-2.523z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_visual-bell.scss:
--------------------------------------------------------------------------------
1 | .visual-bell {
2 | display: flex;
3 | align-items: center;
4 | align-self: flex-start;
5 | flex-shrink: 1;
6 | width: 100%;
7 | height: 36px;
8 | padding: 0 16px 0 16px;
9 |
10 | transition: all 0.3s ease-out;
11 |
12 | border: 1px solid $figma-black-1;
13 | border-radius: $border-radius-med;
14 | background-color: $figma-hud;
15 | box-shadow: $shadow-hud;
16 |
17 | &__msg {
18 | @include font-ui-pos('xlarge', 'normal');
19 |
20 | display: block;
21 |
22 | color: $figma-white;
23 | }
24 |
25 | &__spinner-container {
26 | display: none;
27 | overflow: hidden;
28 | width: 24px;
29 | height: 24px;
30 | margin-right: 8px;
31 | margin-left: -4px;
32 | }
33 |
34 | &__spinner {
35 | display: block;
36 | width: 24px;
37 | height: 24px;
38 |
39 | animation: rotating 1.0s linear infinite;
40 |
41 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M4.848%209.74l.477.15-.477-.15zm2.622-3.08a.5.5%200%200%200-.617-.787l.617.787zm10.677%201.99a7%207%200%200%201%20.838%203.803l.998.065a8%208%200%200%200-.958-4.346l-.878.478zm.838%203.803a7%207%200%200%201-1.324%203.662l.81.588a8%208%200%200%200%201.513-4.186l-.998-.065zm-1.324%203.662a7%207%200%200%201-3.076%202.388l.37.93a8%208%200%200%200%203.515-2.729l-.81-.588zm-3.076%202.388a7%207%200%200%201-3.876.375l-.184.983a8%208%200%200%200%204.43-.428l-.37-.93zm-3.876.375a7%207%200%200%201-3.477-1.755l-.68.732a8%208%200%200%200%203.973%202.005l.184-.983zm-3.477-1.755a7%207%200%200%201-2.001-3.341l-.967.255a8%208%200%200%200%202.287%203.818l.68-.732zm-2-3.34a7%207%200%200%201%20.094-3.893l-.954-.3a8%208%200%200%200-.107%204.449l.967-.255zm.094-3.893c.323-1.024.863-1.835%201.326-2.394.23-.278.44-.49.6-.632l.175-.157.044-.037c.01-.008.01-.008-.298-.402l-.31-.393-.026.02-.06.05-.21.2c-.175.165-.413.407-.674.722-.52.627-1.137%201.55-1.5%202.73l.954.3z%22%20fill%3D%22%23a5a5a5%22%2F%3E%3C%2Fsvg%3E');
42 | background-repeat: none;
43 | }
44 |
45 | &--loading {
46 | .visual-bell__spinner-container {
47 | display: block;
48 | }
49 | }
50 |
51 | &--hidden {
52 | margin-top: 8px;
53 |
54 | opacity: 0;
55 | }
56 |
57 | &--error {
58 | border: 1px solid $figma-red;
59 | background-color: $figma-red;
60 | }
61 | }
62 |
63 | @keyframes rotating {
64 | from {
65 | transform: rotate(0deg);
66 | }
67 | to {
68 | transform: rotate(360deg);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_timer.scss:
--------------------------------------------------------------------------------
1 | .icon--timer {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m19 8h-6v-1h6z" fill-opacity=".8"/%3E%3Cpath d="m16.5 17v-5h-1v5c0 .2761.2239.5.5.5s.5-.2239.5-.5z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m22.7146 12.6492 1.5278-1.5279-2.1213-2.1213-1.4818 1.4818c-1.3085-.93298-2.9098-1.4818-4.6393-1.4818-4.4183 0-8 3.5817-8 8s3.5817 8 8 8 8-3.5817 8-8c0-1.6044-.4723-3.0985-1.2854-4.3508zm.2854 4.3508c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7c1.7683 0 3.3835.6557 4.6157 1.7372l.6471.6471c1.0815 1.2322 1.7372 2.8474 1.7372 4.6157zm-1.0077-5.3004.1288.1288.7071-.7071-.7071-.7071-.7013.7013c.2005.1849.3916.3798.5725.5841z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m19 40h-6v-1h6z" fill-opacity=".3"/%3E%3Cpath d="m16.5 49v-5h-1v5c0 .2761.2239.5.5.5s.5-.2239.5-.5z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m22.7146 44.6492 1.5278-1.5279-2.1213-2.1213-1.4818 1.4818c-1.3085-.933-2.9098-1.4818-4.6393-1.4818-4.4183 0-8 3.5817-8 8s3.5817 8 8 8 8-3.5817 8-8c0-1.6044-.4723-3.0985-1.2854-4.3508zm.2854 4.3508c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7c1.7683 0 3.3835.6557 4.6157 1.7372l.6471.6471c1.0815 1.2322 1.7372 2.8474 1.7372 4.6157zm-1.0077-5.3004.1288.1288.7071-.7071-.7071-.7071-.7013.7013c.2005.1849.3916.3798.5725.5841z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m19 72h-6v-1h6z" fill="%2318a0fb"/%3E%3Cpath d="m16.5 81v-5h-1v5c0 .2761.2239.5.5.5s.5-.2239.5-.5z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m22.7146 76.6492 1.5278-1.5279-2.1213-2.1213-1.4818 1.4818c-1.3085-.933-2.9098-1.4818-4.6393-1.4818-4.4183 0-8 3.5817-8 8s3.5817 8 8 8 8-3.5817 8-8c0-1.6044-.4723-3.0985-1.2854-4.3508zm.2854 4.3508c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7c1.7683 0 3.3835.6557 4.6157 1.7372l.6471.6471c1.0815 1.2322 1.7372 2.8474 1.7372 4.6157zm-1.0077-5.3004.1288.1288.7071-.7071-.7071-.7071-.7013.7013c.2005.1849.3916.3798.5725.5841z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m19 104h-6v-1h6z" fill="%23fff"/%3E%3Cpath d="m16.5 113v-5h-1v5c0 .276.2239.5.5.5s.5-.224.5-.5z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m22.7146 108.649 1.5278-1.528-2.1213-2.121-1.4818 1.482c-1.3085-.933-2.9098-1.482-4.6393-1.482-4.4183 0-8 3.582-8 8s3.5817 8 8 8 8-3.582 8-8c0-1.604-.4723-3.098-1.2854-4.351zm.2854 4.351c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7c1.7683 0 3.3835.656 4.6157 1.737l.6471.647c1.0815 1.232 1.7372 2.848 1.7372 4.616zm-1.0077-5.3.1288.128.7071-.707-.7071-.707-.7013.702c.2005.184.3916.379.5725.584z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/actions/random-number.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { Field, Label, Input, Footer, Output } from '../components'
4 | import { Context } from '../store';
5 | const { useState, useEffect, useContext } = React;
6 | import isUUID from 'validator/lib/isUUID';
7 | import { NUMBER } from "./output-types";
8 | import { getSupportedOptions } from "./helper-functions";
9 |
10 | function RandomNumber({ id, index, color }) {
11 | const { store, dispatch } = useContext(Context);
12 | const [min, setMin] = useState(0);
13 | const [max, setMax] = useState(10);
14 |
15 | useEffect(() => {
16 | dispatch({
17 | type: "random-number",
18 | id,
19 | state: {
20 | option: {
21 | label: `Random Number ${index+1}`,
22 | value: id,
23 | type: NUMBER
24 | },
25 | index,
26 | min,
27 | max,
28 | }
29 | })
30 | }, [min, max])
31 |
32 | const setMinValue = (newValue) => {
33 | if(newValue.length === 0) {
34 | setMin(0);
35 | }
36 | else if(typeof newValue === "object") {
37 | if(isUUID(newValue.value)) {
38 | setMin(newValue.value);
39 | }
40 | else {
41 | setMin(parseInt(newValue.value));
42 | }
43 | }
44 | else if(parseInt(newValue) === NaN) {
45 | setMin(0);
46 | }
47 | else {
48 | setMin(parseInt(newValue));
49 | }
50 | }
51 |
52 | const setMaxValue = (newValue) => {
53 | if(newValue.length === 0) {
54 | setMax(10);
55 | }
56 | else if(typeof newValue === "object") {
57 | if(isUUID(newValue.value)) {
58 | setMax(newValue.value);
59 | }
60 | else {
61 | setMax(parseInt(newValue.value));
62 | }
63 | }
64 | else if(parseInt(newValue) === NaN) {
65 | setMax(10);
66 | }
67 | else {
68 | setMax(parseInt(newValue));
69 | }
70 | }
71 |
72 | return (
73 | <>
74 |
75 |
76 | setMinValue(newValue)} onInputChange={(newValue) => setMinValue(newValue)} options={getSupportedOptions(store, id, NUMBER)} />
77 |
78 |
79 |
80 | setMaxValue(newValue)} onInputChange={(newValue) => setMaxValue(newValue)} options={getSupportedOptions(store, id, NUMBER)} />
81 |
82 |
88 | >
89 | );
90 | }
91 |
92 | export default RandomNumber;
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_type.scss:
--------------------------------------------------------------------------------
1 | .type {
2 | //Positive
3 |
4 | //11px
5 | &--pos-small-normal {
6 | @include font-ui-pos('small', 'normal');
7 | }
8 | &--pos-small-medium {
9 | @include font-ui-pos('small', 'medium');
10 | }
11 | &--pos-small-bold {
12 | @include font-ui-pos('small', 'bold');
13 | }
14 |
15 | //12px
16 | &--pos-medium-normal {
17 | @include font-ui-pos('medium', 'normal');
18 | }
19 | &--pos-medium-medium {
20 | @include font-ui-pos('medium', 'medium');
21 | }
22 | &--pos-medium-bold {
23 | @include font-ui-pos('medium', 'bold');
24 | }
25 |
26 | //13px
27 | &--pos-large-normal {
28 | @include font-ui-pos('large', 'normal');
29 | }
30 | &--pos-large-medium {
31 | @include font-ui-pos('large', 'medium');
32 | }
33 | &--pos-large-bold {
34 | @include font-ui-pos('large', 'bold');
35 | }
36 |
37 | //14px
38 | &--pos-xlarge-normal {
39 | @include font-ui-pos('xlarge', 'normal');
40 | }
41 | &--pos-xlarge-medium {
42 | @include font-ui-pos('xlarge', 'medium');
43 | }
44 | &--pos-xlarge-bold {
45 | @include font-ui-pos('xlarge', 'bold');
46 | }
47 |
48 | &--figma-black {
49 | color: $figma-black;
50 | }
51 | &--figma-black-3 {
52 | color: $figma-black-3;
53 | }
54 | &--figma-black-8 {
55 | color: $figma-black-8;
56 | }
57 |
58 |
59 |
60 | //Negative
61 |
62 | //11px
63 | &--neg-small-normal {
64 | @include font-ui-neg('small', 'normal');
65 | }
66 | &--neg-small-medium {
67 | @include font-ui-neg('small', 'medium');
68 | }
69 | &--neg-small-bold {
70 | @include font-ui-neg('small', 'bold');
71 | }
72 |
73 | //12px
74 | &--neg-medium-normal {
75 | @include font-ui-neg('medium', 'normal');
76 | }
77 | &--neg-medium-medium {
78 | @include font-ui-neg('medium', 'medium');
79 | }
80 | &--neg-medium-bold {
81 | @include font-ui-neg('medium', 'bold');
82 | }
83 |
84 | //13px
85 | &--neg-large-normal {
86 | @include font-ui-neg('large', 'normal');
87 | }
88 | &--neg-large-medium {
89 | @include font-ui-neg('large', 'medium');
90 | }
91 | &--neg-large-bold {
92 | @include font-ui-neg('large', 'bold');
93 | }
94 |
95 | //14px
96 | &--neg-xlarge-normal {
97 | @include font-ui-neg('xlarge', 'normal');
98 | }
99 | &--neg-xlarge-medium {
100 | @include font-ui-neg('xlarge', 'medium');
101 | }
102 | &--neg-xlarge-bold {
103 | @include font-ui-neg('xlarge', 'bold');
104 | }
105 |
106 | &--figma-white {
107 | color: $figma-white;
108 | }
109 | &--figma-white-4 {
110 | color: $figma-white-4;
111 | }
112 | &--figma-white-8 {
113 | color: $figma-white-8;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_smiley.scss:
--------------------------------------------------------------------------------
1 | .icon--smiley {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m15.9999 20c-1.8638 0-3.4299-1.2748-3.8739-3h1.0446c.4119 1.1652 1.5231 2 2.8293 2 1.3063 0 2.4175-.8348 2.8293-2h1.0447c-.444 1.7252-2.0101 3-3.874 3z" fill-opacity=".8"/%3E%3Cpath d="m19.5 14.125c0 .4832-.3918.875-.875.875s-.875-.3918-.875-.875.3918-.875.875-.875.875.3918.875.875z" fill-opacity=".8"/%3E%3Cpath d="m13.125 15c.4832 0 .875-.3918.875-.875s-.3918-.875-.875-.875-.875.3918-.875.875.3918.875.875.875z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m24 16c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m15.9999 52c-1.8638 0-3.4299-1.2748-3.8739-3h1.0446c.4119 1.1652 1.5231 2 2.8293 2 1.3063 0 2.4175-.8348 2.8293-2h1.0447c-.444 1.7252-2.0101 3-3.874 3z" fill-opacity=".3"/%3E%3Cpath d="m19.5 46.125c0 .4832-.3918.875-.875.875s-.875-.3918-.875-.875.3918-.875.875-.875.875.3918.875.875z" fill-opacity=".3"/%3E%3Cpath d="m13.125 47c.4832 0 .875-.3918.875-.875s-.3918-.875-.875-.875-.875.3918-.875.875.3918.875.875.875z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m24 48c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m15.9999 84c-1.8638 0-3.4299-1.2748-3.8739-3h1.0446c.4119 1.1652 1.5231 2 2.8293 2 1.3063 0 2.4175-.8348 2.8293-2h1.0447c-.444 1.7252-2.0101 3-3.874 3z" fill="%2318a0fb"/%3E%3Cpath d="m19.5 78.125c0 .4832-.3918.875-.875.875s-.875-.3918-.875-.875.3918-.875.875-.875.875.3918.875.875z" fill="%2318a0fb"/%3E%3Cpath d="m13.125 79c.4832 0 .875-.3918.875-.875s-.3918-.875-.875-.875-.875.3918-.875.875.3918.875.875.875z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m24 80c0 4.4183-3.5817 8-8 8s-8-3.5817-8-8 3.5817-8 8-8 8 3.5817 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m15.9999 116c-1.8638 0-3.4299-1.275-3.8739-3h1.0446c.4119 1.165 1.5231 2 2.8293 2 1.3063 0 2.4175-.835 2.8293-2h1.0447c-.444 1.725-2.0101 3-3.874 3z" fill="%23fff"/%3E%3Cpath d="m19.5 110.125c0 .483-.3918.875-.875.875s-.875-.392-.875-.875.3918-.875.875-.875.875.392.875.875z" fill="%23fff"/%3E%3Cpath d="m13.125 111c.4832 0 .875-.392.875-.875s-.3918-.875-.875-.875-.875.392-.875.875.3918.875.875.875z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m24 112c0 4.418-3.5817 8-8 8s-8-3.582-8-8 3.5817-8 8-8 8 3.582 8 8zm-1 0c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_blend-empty.scss:
--------------------------------------------------------------------------------
1 | .icon--blend-empty {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m16.6948 11.7201c-.22-.229-.4511-.4681-.6932-.7185-.0005-.0005-.001-.0011-.0015-.0016l-.0005.0005c-.0003.0003-.0007.0007-.001.001-.2421.2505-.4732.4896-.6933.7185-2.2035 2.2924-3.3053 3.5739-3.3053 5.1319-.0025 1.0624.3881 2.1256 1.1717 2.9361 1.562 1.616 4.0947 1.616 5.6567 0 .7836-.8105 1.1741-1.8737 1.1716-2.9361 0-1.558-1.1017-2.8395-3.3052-5.1318zm-.6947.7203c-.9766 1.0166-1.6934 1.7905-2.1953 2.4708-.5998.8133-.8048 1.38-.8048 1.9407v.0023c-.0019.8178.2984 1.6262.8907 2.2388 1.1689 1.2093 3.0498 1.2093 4.2188 0 .5921-.6126.8924-1.4209.8905-2.2387v-.0024c0-.5607-.205-1.1274-.8048-1.9407-.5018-.6803-1.2187-1.4542-2.1951-2.4708z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m16.6948 43.7201c-.22-.229-.4511-.4681-.6932-.7185-.0005-.0005-.001-.0011-.0015-.0016l-.0005.0005c-.0003.0003-.0007.0007-.001.001-.2421.2505-.4732.4896-.6933.7185-2.2035 2.2924-3.3053 3.5739-3.3053 5.1319-.0025 1.0624.3881 2.1256 1.1717 2.9361 1.562 1.616 4.0947 1.616 5.6567 0 .7836-.8105 1.1741-1.8737 1.1716-2.9361 0-1.558-1.1017-2.8395-3.3052-5.1318zm-.6947.7203c-.9766 1.0166-1.6934 1.7905-2.1953 2.4708-.5998.8133-.8048 1.38-.8048 1.9407v.0023c-.0019.8178.2984 1.6262.8907 2.2388 1.1689 1.2093 3.0498 1.2093 4.2188 0 .5921-.6126.8924-1.4209.8905-2.2387v-.0024c0-.5607-.205-1.1274-.8048-1.9407-.5018-.6803-1.2187-1.4542-2.1951-2.4708z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m16.6948 75.7201c-.22-.229-.4511-.4681-.6932-.7185-.0005-.0005-.001-.0011-.0015-.0016l-.0005.0005c-.0003.0003-.0007.0007-.001.001-.2421.2505-.4732.4896-.6933.7185-2.2035 2.2924-3.3053 3.5739-3.3053 5.1319-.0025 1.0624.3881 2.1256 1.1717 2.9361 1.562 1.616 4.0947 1.616 5.6567 0 .7836-.8105 1.1741-1.8737 1.1716-2.9361 0-1.558-1.1017-2.8395-3.3052-5.1318zm-.6947.7203c-.9766 1.0166-1.6934 1.7905-2.1953 2.4708-.5998.8133-.8048 1.38-.8048 1.9407v.0023c-.0019.8178.2984 1.6262.8907 2.2388 1.1689 1.2093 3.0498 1.2093 4.2188 0 .5921-.6126.8924-1.4209.8905-2.2387v-.0024c0-.5607-.205-1.1274-.8048-1.9407-.5018-.6803-1.2187-1.4542-2.1951-2.4708z" fill="%2318a0fb"/%3E%3Cpath d="m16.6948 107.72c-.22-.229-.4511-.468-.6932-.718-.0005-.001-.001-.001-.0015-.002h-.0005c-.0003.001-.0007.001-.001.002-.2421.25-.4732.489-.6933.718-2.2035 2.292-3.3053 3.574-3.3053 5.132-.0025 1.062.3881 2.125 1.1717 2.936 1.562 1.616 4.0947 1.616 5.6567 0 .7836-.811 1.1741-1.874 1.1716-2.936 0-1.558-1.1017-2.84-3.3052-5.132zm-.6947.72c-.9766 1.017-1.6934 1.791-2.1953 2.471-.5998.813-.8048 1.38-.8048 1.941v.002c-.0019.818.2984 1.626.8907 2.239 1.1689 1.209 3.0498 1.209 4.2188 0 .5921-.613.8924-1.421.8905-2.239v-.002c0-.561-.205-1.128-.8048-1.941-.5018-.68-1.2187-1.454-2.1951-2.471z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/base/_variables.scss:
--------------------------------------------------------------------------------
1 | // COLORS//////////
2 |
3 | //accent
4 | $figma-blue: #18a0fb; // Primary accent, used sparingly for primary actions
5 | $figma-purple: #7b61ff; //used for components + instances
6 | $figma-hot-pink: #ff00ff;
7 | $figma-green: #1bc47d;
8 | $figma-red: #f24822; // Used to communicate error
9 | $figma-yellow: #ffeb00; // Used to communicate cautionary warning
10 |
11 | //foreground
12 | $figma-black: #000000; // Used for active states when text is being edited or highlighted
13 | $figma-black-8: rgba(0, 0, 0, .8); // Used for elements in resting state
14 | $figma-black-3: rgba(0, 0, 0, .3); // Lower priority UI elements like labels, disabled UI
15 | $figma-white: #ffffff; // Primary background for UI, text on menus
16 | $figma-white-8: rgba(255, 255, 255, .8); // Only used for toolbar
17 | $figma-white-4: rgba(255, 255, 255, .4); // Use for disabled menu items on black
18 |
19 | //background
20 | $figma-grey: #f0f0f0; // For buttons and controls in active or selected state
21 | $figma-silver: #e5e5e5; // For UI seperator lines
22 | $figma-hud: #222222; // Used for heads up display, menu backgrouhnds and visual bell
23 | $figma-toolbar: #2c2c2c;
24 |
25 | //special
26 | $figma-black-1: rgba(0, 0, 0, .1); // Primarily for Input borders on hover
27 | $figma-blue-3: rgba(24, 145, 251, .3); //Used for text selection in inputs
28 | $figma-purple-4: rgba(123, 97, 255, .4);
29 | $figma-hover-fill: rgba(0, 0, 0, .06); // Light grey hover state for borderless UI controls
30 | $figma-selection-a: #daebf7;
31 | $figma-selection-b: #edf5fa; //edf5fa
32 | $figma-white-2: rgba(255, 255, 255, .2); // Use for menu dividers
33 |
34 |
35 | // TYPOGRAPHY //////////
36 | // pos = positive applications, white on black bg, neg = inverse
37 |
38 | //font-stack
39 | $font-stack: 'Inter', sans-serif;
40 |
41 | //font-size
42 | $font-size-small: 11px;
43 | $font-size-medium: 12px;
44 | $font-size-large: 13px;
45 | $font-size-xlarge: 14px;
46 |
47 | //font-weight
48 | $font-weight-normal: 400;
49 | $font-weight-medium: 500;
50 | $font-weight-bold: 600;
51 |
52 | //lineheight
53 | $font-lineheight: 16px; //For 11px, 12px type
54 | $font-lineheight-large: 24px; //13px, 14px
55 |
56 | //letterspacing
57 | $font-letterspacing-pos-small: .005em;
58 | $font-letterspacing-neg-small: .01em;
59 | $font-letterspacing-pos-medium: 0;
60 | $font-letterspacing-neg-medium: .005em;
61 | $font-letterspacing-pos-large: -.0025em;
62 | $font-letterspacing-neg-large: .0025em;
63 | $font-letterspacing-pos-xlarge: -.001em;
64 | $font-letterspacing-neg-xlarge: -.001em;
65 |
66 |
67 | // BORDER RADIUS //////////
68 |
69 | $border-radius-small: 2px;
70 | $border-radius-med: 5px;
71 | $border-radius-large: 6px;
72 |
73 |
74 | //SHADOWS //////////
75 |
76 | $shadow-hud: 0 5px 17px rgba(0, 0, 0, .2), 0 2px 7px rgba(0, 0, 0, .15);
77 | $shadow-floating-window: 0 2px 14px rgba(0, 0, 0, .15);
78 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_break.scss:
--------------------------------------------------------------------------------
1 | .icon--break {
2 | background-image: url('data:image/svg+xml,%3Csvg fill=\'none\' height=\'128\' viewBox=\'0 0 32 128\' width=\'32\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cg fill=\'%23000\' fill-opacity=\'.8\' opacity=\'.9\'%3E%3Cpath d=\'m13.0002 9v3h1v-3z\'/%3E%3Cpath d=\'m22.1033 9.89644c-1.1617-1.16176-3.0453-1.16176-4.2071.00002l-2.7499 2.74994.7071.7071 2.7499-2.7499c.7712-.77128 2.0217-.77129 2.7929 0 .7712.7712.7713 2.0216 0 2.7928l-2.7499 2.75.7071.7071 2.7499-2.75c1.1618-1.1617 1.1618-3.0453 0-4.20706z\'/%3E%3Cpath d=\'m9.89639 22.1035c-1.16176-1.1617-1.16177-3.0453-.00001-4.2071l2.75002-2.75.7071.7071-2.75 2.75c-.77124.7713-.77124 2.0217 0 2.7929.7712.7713 2.0216.7713 2.7929 0l2.75-2.75.7071.7071-2.75 2.75c-1.1618 1.1618-3.0454 1.1618-4.20711 0z\'/%3E%3Cpath d=\'m22.9998 19h-3v-1h3z\'/%3E%3Cpath d=\'m19.0004 20v3h-1v-3z\'/%3E%3Cpath d=\'m11.9998 13h-3.00004v1h3.00004z\'/%3E%3C/g%3E%3Cg fill=\'%23000\' fill-opacity=\'.3\' opacity=\'.9\'%3E%3Cpath d=\'m13.0002 41v3h1v-3z\'/%3E%3Cpath d=\'m22.1033 41.8964c-1.1617-1.1617-3.0453-1.1617-4.2071.0001l-2.7499 2.7499.7071.7071 2.7499-2.7499c.7712-.7713 2.0217-.7713 2.7929 0 .7712.7712.7713 2.0216 0 2.7928l-2.7499 2.75.7071.7071 2.7499-2.75c1.1618-1.1617 1.1618-3.0453 0-4.2071z\'/%3E%3Cpath d=\'m9.89639 54.1035c-1.16176-1.1617-1.16177-3.0453-.00001-4.2071l2.75002-2.75.7071.7071-2.75 2.75c-.77124.7713-.77124 2.0217 0 2.7929.7712.7713 2.0216.7713 2.7929 0l2.75-2.75.7071.7071-2.75 2.75c-1.1618 1.1618-3.0454 1.1618-4.20711 0z\'/%3E%3Cpath d=\'m22.9998 51h-3v-1h3z\'/%3E%3Cpath d=\'m19.0004 52v3h-1v-3z\'/%3E%3Cpath d=\'m11.9998 45h-3.00004v1h3.00004z\'/%3E%3C/g%3E%3Cg fill=\'%2318a0fb\' opacity=\'.9\'%3E%3Cpath d=\'m13.0002 73v3h1v-3z\'/%3E%3Cpath d=\'m22.1033 73.8964c-1.1617-1.1617-3.0453-1.1617-4.2071.0001l-2.7499 2.7499.7071.7071 2.7499-2.7499c.7712-.7713 2.0217-.7713 2.7929 0 .7712.7712.7713 2.0216 0 2.7928l-2.7499 2.75.7071.7071 2.7499-2.75c1.1618-1.1617 1.1618-3.0453 0-4.2071z\'/%3E%3Cpath d=\'m9.89639 86.1035c-1.16176-1.1617-1.16177-3.0453-.00001-4.2071l2.75002-2.75.7071.7071-2.75 2.75c-.77124.7713-.77124 2.0217 0 2.7929.7712.7713 2.0216.7713 2.7929 0l2.75-2.75.7071.7071-2.75 2.75c-1.1618 1.1618-3.0454 1.1618-4.20711 0z\'/%3E%3Cpath d=\'m22.9998 83h-3v-1h3z\'/%3E%3Cpath d=\'m19.0004 84v3h-1v-3z\'/%3E%3Cpath d=\'m11.9998 77h-3.00004v1h3.00004z\'/%3E%3C/g%3E%3Cg fill=\'%23fff\' opacity=\'.9\'%3E%3Cpath d=\'m13.0002 105v3h1v-3z\'/%3E%3Cpath d=\'m22.1033 105.896c-1.1617-1.161-3.0453-1.161-4.2071 0l-2.7499 2.75.7071.708 2.7499-2.75c.7712-.772 2.0217-.772 2.7929 0 .7712.771.7713 2.021 0 2.792l-2.7499 2.75.7071.708 2.7499-2.75c1.1618-1.162 1.1618-3.046 0-4.208z\'/%3E%3Cpath d=\'m9.89639 118.104c-1.16176-1.162-1.16177-3.046-.00001-4.208l2.75002-2.75.7071.708-2.75 2.75c-.77124.771-.77124 2.021 0 2.792.7712.772 2.0216.772 2.7929 0l2.75-2.75.7071.708-2.75 2.75c-1.1618 1.161-3.0454 1.161-4.20711 0z\'/%3E%3Cpath d=\'m22.9998 115h-3v-1h3z\'/%3E%3Cpath d=\'m19.0004 116v3h-1v-3z\'/%3E%3Cpath d=\'m11.9998 109h-3.00004v1h3.00004z\'/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/figma-plugin-ds.scss:
--------------------------------------------------------------------------------
1 | @import 'base/base';
2 | @import 'base/typography';
3 | @import 'base/variables';
4 | @import 'base/mixins';
5 |
6 | //Components — customize this to import only the components you need
7 | @import 'components/label';
8 | @import 'components/section-title';
9 | @import 'components/type';
10 | @import 'components/button';
11 | @import 'components/input';
12 | @import 'components/input-icon';
13 | @import 'components/textarea';
14 | @import 'components/select-menu';
15 | @import 'components/switch';
16 | @import 'components/checkbox';
17 | @import 'components/divider';
18 | @import 'components/visual-bell';
19 | @import 'components/onboarding-tip';
20 | @import 'components/disclosure';
21 |
22 | //master icon component
23 | @import 'components/icon';
24 |
25 | //icons — customize this to import only the icons you need for performance improvements
26 | @import 'icons/adjust';
27 | @import 'icons/alert';
28 | @import 'icons/align-bottom';
29 | @import 'icons/align-middle';
30 | @import 'icons/align-top';
31 | @import 'icons/angle';
32 | @import 'icons/animated-fill';
33 | @import 'icons/arrow-left-right';
34 | @import 'icons/arrow-up-down';
35 | @import 'icons/blend-empty';
36 | @import 'icons/blend';
37 | @import 'icons/break';
38 | @import 'icons/close';
39 | @import 'icons/comment';
40 | @import 'icons/component';
41 | @import 'icons/corner-radius';
42 | @import 'icons/corners';
43 | @import 'icons/dist-horiz-spacing';
44 | @import 'icons/dist-vert-spacing';
45 | @import 'icons/draft';
46 | @import 'icons/effects';
47 | @import 'icons/ellipses';
48 | @import 'icons/eyedropper';
49 | @import 'icons/frame';
50 | @import 'icons/group';
51 | @import 'icons/hidden';
52 | @import 'icons/hyperlink';
53 | @import 'icons/image';
54 | @import 'icons/import';
55 | @import 'icons/instance';
56 | @import 'icons/layout-align-bottom';
57 | @import 'icons/layout-align-horiz-cent';
58 | @import 'icons/layout-align-left';
59 | @import 'icons/layout-align-right';
60 | @import 'icons/layout-align-top';
61 | @import 'icons/layout-align-vert-cent';
62 | @import 'icons/layout-grid-columns';
63 | @import 'icons/layout-grid-rows';
64 | @import 'icons/layout-grid-uniform';
65 | @import 'icons/library';
66 | @import 'icons/link-broken';
67 | @import 'icons/link-connected';
68 | @import 'icons/list-detailed';
69 | @import 'icons/list';
70 | @import 'icons/lock-unlocked';
71 | @import 'icons/lock';
72 | @import 'icons/mask';
73 | @import 'icons/minus';
74 | @import 'icons/node-connect';
75 | @import 'icons/play';
76 | @import 'icons/plus';
77 | @import 'icons/recent';
78 | @import 'icons/reset-instance';
79 | @import 'icons/resize-to-fit';
80 | @import 'icons/resolve-filled';
81 | @import 'icons/resolve';
82 | @import 'icons/restore';
83 | @import 'icons/return';
84 | @import 'icons/search-large';
85 | @import 'icons/search';
86 | @import 'icons/share';
87 | @import 'icons/smiley';
88 | @import 'icons/star-off';
89 | @import 'icons/star-on';
90 | @import 'icons/stroke-weight';
91 | @import 'icons/styles';
92 | @import 'icons/tidy-up-grid';
93 | @import 'icons/tidy-up-list-horiz';
94 | @import 'icons/tidy-up-list-vert';
95 | @import 'icons/timer';
96 | @import 'icons/trash';
97 | @import 'icons/type';
98 | @import 'icons/vector-handles';
99 | @import 'icons/visible';
100 | @import 'icons/warning';
101 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_share.scss:
--------------------------------------------------------------------------------
1 | .icon--share {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m20 9.5c-1.933 0-3.5 1.567-3.5 3.5 0 1.442.872 2.6803 2.1175 3.2164-1.1371.3667-2.0766 1.1736-2.6175 2.22-.5409-1.0464-1.4803-1.8533-2.6175-2.22 1.2455-.5361 2.1175-1.7744 2.1175-3.2164 0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5c0 1.442.87203 2.6803 2.1175 3.2164-1.80889.5833-3.1175 2.2806-3.1175 4.2836v1.5h17v-1.5c0-2.003-1.3086-3.7003-3.1175-4.2836 1.2455-.5361 2.1175-1.7744 2.1175-3.2164 0-1.933-1.567-3.5-3.5-3.5zm-2.5 3.5c0-1.3807 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.1193 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.1193-2.5-2.5zm-1 8v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5v.5zm-1-.5v.5h-7v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5zm-6-7.5c0-1.3807 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.1193 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.1193-2.5-2.5z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m20 41.5c-1.933 0-3.5 1.567-3.5 3.5 0 1.442.872 2.6803 2.1175 3.2164-1.1371.3667-2.0766 1.1736-2.6175 2.22-.5409-1.0464-1.4803-1.8533-2.6175-2.22 1.2455-.5361 2.1175-1.7744 2.1175-3.2164 0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5c0 1.442.87203 2.6803 2.1175 3.2164-1.80889.5833-3.1175 2.2806-3.1175 4.2836v1.5h17v-1.5c0-2.003-1.3086-3.7003-3.1175-4.2836 1.2455-.5361 2.1175-1.7744 2.1175-3.2164 0-1.933-1.567-3.5-3.5-3.5zm-2.5 3.5c0-1.3807 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.1193 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.1193-2.5-2.5zm-1 8v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5v.5zm-1-.5v.5h-7v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5zm-6-7.5c0-1.3807 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.1193 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.1193-2.5-2.5z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m20 73.5c-1.933 0-3.5 1.567-3.5 3.5 0 1.442.872 2.6803 2.1175 3.2164-1.1371.3667-2.0766 1.1736-2.6175 2.22-.5409-1.0464-1.4803-1.8533-2.6175-2.22 1.2455-.5361 2.1175-1.7744 2.1175-3.2164 0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5c0 1.442.87203 2.6803 2.1175 3.2164-1.80889.5833-3.1175 2.2806-3.1175 4.2836v1.5h17v-1.5c0-2.003-1.3086-3.7003-3.1175-4.2836 1.2455-.5361 2.1175-1.7744 2.1175-3.2164 0-1.933-1.567-3.5-3.5-3.5zm-2.5 3.5c0-1.3807 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.1193 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.1193-2.5-2.5zm-1 8v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5v.5zm-1-.5v.5h-7v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5zm-6-7.5c0-1.3807 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.1193 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.1193-2.5-2.5z" fill="%2318a0fb"/%3E%3Cpath d="m20 105.5c-1.933 0-3.5 1.567-3.5 3.5 0 1.442.872 2.68 2.1175 3.216-1.1371.367-2.0766 1.174-2.6175 2.22-.5409-1.046-1.4803-1.853-2.6175-2.22 1.2455-.536 2.1175-1.774 2.1175-3.216 0-1.933-1.567-3.5-3.5-3.5s-3.5 1.567-3.5 3.5c0 1.442.87203 2.68 2.1175 3.216-1.80889.584-3.1175 2.281-3.1175 4.284v1.5h17v-1.5c0-2.003-1.3086-3.7-3.1175-4.284 1.2455-.536 2.1175-1.774 2.1175-3.216 0-1.933-1.567-3.5-3.5-3.5zm-2.5 3.5c0-1.381 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.119 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.119-2.5-2.5zm-1 8v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5v.5zm-1-.5v.5h-7v-.5c0-1.933 1.567-3.5 3.5-3.5s3.5 1.567 3.5 3.5zm-6-7.5c0-1.381 1.1193-2.5 2.5-2.5 1.3808 0 2.5 1.119 2.5 2.5s-1.1192 2.5-2.5 2.5c-1.3807 0-2.5-1.119-2.5-2.5z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_effects.scss:
--------------------------------------------------------------------------------
1 | .icon--effects {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg fill="%23000"%3E%3Cpath d="m16.5 8.5h-1v3h1z" fill-opacity=".8"/%3E%3Cpath d="m11.0503 10.3431-.7071.7072 2.1213 2.1213.7071-.7071z" fill-opacity=".8"/%3E%3Cpath d="m21.657 11.0503-.7071-.7071-2.1214 2.1213.7071.7071z" fill-opacity=".8"/%3E%3Cpath d="m8.5 15.5v1h3v-1z" fill-opacity=".8"/%3E%3Cpath d="m20.5 15.5v1h3v-1z" fill-opacity=".8"/%3E%3Cpath d="m13.1716 19.5355-.7071-.7071-2.1213 2.1214.7071.7071z" fill-opacity=".8"/%3E%3Cpath d="m19.5354 18.8284-.7071.7071 2.1213 2.1214.7071-.7071z" fill-opacity=".8"/%3E%3Cpath d="m16.5 20.5h-1v3h1z" fill-opacity=".8"/%3E%3Cpath clip-rule="evenodd" d="m18.4978 15.9979c0 1.3807-1.1193 2.5-2.5 2.5s-2.5-1.1193-2.5-2.5 1.1193-2.5 2.5-2.5 2.5 1.1193 2.5 2.5zm-1 0c0 .8285-.6716 1.5-1.5 1.5s-1.5-.6715-1.5-1.5c0-.8284.6716-1.5 1.5-1.5s1.5.6716 1.5 1.5z" fill-opacity=".8" fill-rule="evenodd"/%3E%3Cpath d="m16.5 40.5h-1v3h1z" fill-opacity=".3"/%3E%3Cpath d="m11.0503 42.3431-.7071.7072 2.1213 2.1213.7071-.7071z" fill-opacity=".3"/%3E%3Cpath d="m21.657 43.0503-.7071-.7071-2.1214 2.1213.7071.7071z" fill-opacity=".3"/%3E%3Cpath d="m8.5 47.5v1h3v-1z" fill-opacity=".3"/%3E%3Cpath d="m20.5 47.5v1h3v-1z" fill-opacity=".3"/%3E%3Cpath d="m13.1716 51.5355-.7071-.7071-2.1213 2.1214.7071.7071z" fill-opacity=".3"/%3E%3Cpath d="m19.5354 50.8284-.7071.7071 2.1213 2.1214.7071-.7071z" fill-opacity=".3"/%3E%3Cpath d="m16.5 52.5h-1v3h1z" fill-opacity=".3"/%3E%3Cpath clip-rule="evenodd" d="m18.4978 47.9979c0 1.3807-1.1193 2.5-2.5 2.5s-2.5-1.1193-2.5-2.5 1.1193-2.5 2.5-2.5 2.5 1.1193 2.5 2.5zm-1 0c0 .8285-.6716 1.5-1.5 1.5s-1.5-.6715-1.5-1.5c0-.8284.6716-1.5 1.5-1.5s1.5.6716 1.5 1.5z" fill-opacity=".3" fill-rule="evenodd"/%3E%3C/g%3E%3Cpath d="m16.5 72.5h-1v3h1z" fill="%2318a0fb"/%3E%3Cpath d="m11.0503 74.3431-.7071.7072 2.1213 2.1213.7071-.7071z" fill="%2318a0fb"/%3E%3Cpath d="m21.657 75.0503-.7071-.7071-2.1214 2.1213.7071.7071z" fill="%2318a0fb"/%3E%3Cpath d="m8.5 79.5v1h3v-1z" fill="%2318a0fb"/%3E%3Cpath d="m20.5 79.5v1h3v-1z" fill="%2318a0fb"/%3E%3Cpath d="m13.1716 83.5355-.7071-.7071-2.1213 2.1214.7071.7071z" fill="%2318a0fb"/%3E%3Cpath d="m19.5354 82.8284-.7071.7071 2.1213 2.1214.7071-.7071z" fill="%2318a0fb"/%3E%3Cpath d="m16.5 84.5h-1v3h1z" fill="%2318a0fb"/%3E%3Cpath clip-rule="evenodd" d="m18.4978 79.9979c0 1.3807-1.1193 2.5-2.5 2.5s-2.5-1.1193-2.5-2.5 1.1193-2.5 2.5-2.5 2.5 1.1193 2.5 2.5zm-1 0c0 .8285-.6716 1.5-1.5 1.5s-1.5-.6715-1.5-1.5c0-.8284.6716-1.5 1.5-1.5s1.5.6716 1.5 1.5z" fill="%2318a0fb" fill-rule="evenodd"/%3E%3Cpath d="m16.5 104.5h-1v3h1z" fill="%23fff"/%3E%3Cpath d="m11.0503 106.343-.7071.707 2.1213 2.122.7071-.708z" fill="%23fff"/%3E%3Cpath d="m21.657 107.05-.7071-.707-2.1214 2.121.7071.708z" fill="%23fff"/%3E%3Cpath d="m8.5 111.5v1h3v-1z" fill="%23fff"/%3E%3Cpath d="m20.5 111.5v1h3v-1z" fill="%23fff"/%3E%3Cpath d="m13.1716 115.536-.7071-.708-2.1213 2.122.7071.707z" fill="%23fff"/%3E%3Cpath d="m19.5354 114.828-.7071.708 2.1213 2.121.7071-.707z" fill="%23fff"/%3E%3Cpath d="m16.5 116.5h-1v3h1z" fill="%23fff"/%3E%3Cpath clip-rule="evenodd" d="m18.4978 111.998c0 1.381-1.1193 2.5-2.5 2.5s-2.5-1.119-2.5-2.5 1.1193-2.5 2.5-2.5 2.5 1.119 2.5 2.5zm-1 0c0 .828-.6716 1.5-1.5 1.5s-1.5-.672-1.5-1.5c0-.829.6716-1.5 1.5-1.5s1.5.671 1.5 1.5z" fill="%23fff" fill-rule="evenodd"/%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/src/ui.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import { DragDropContext } from 'react-beautiful-dnd';
4 | import "@atlaskit/css-reset";
5 |
6 | import { html as io } from './io';
7 | import actions from './actions';
8 |
9 | import Action from './components/action';
10 | import ActionButton from './components/action-button';
11 | import ActionsList from './components/actions-list';
12 | import App from './components/app';
13 | import Automation from './components/automation';
14 | import Nav from './components/nav';
15 | import NavButton from './components/nav-button';
16 |
17 | import Icon from '@mdi/react';
18 | import { mdiPlay, mdiCheck } from '@mdi/js';
19 |
20 | const { useState, useReducer, useCallback } = React;
21 |
22 | import { v4 as uuid } from 'uuid';
23 | import * as randomcolor from "random-color";
24 |
25 | import { reducer, Context } from "./store";
26 |
27 | const reorder = (list, startIndex, endIndex) => {
28 | const result = Array.from(list);
29 | const [removed] = result.splice(startIndex, 1);
30 | result.splice(endIndex, 0, removed);
31 |
32 | return result;
33 | };
34 |
35 | const PluginUI: React.FC = () => {
36 | const [automation, setAutomation] = useState([]);
37 |
38 | const [store, dispatch] = useReducer(reducer, {});
39 |
40 | const onDragEnd = (result) => {
41 | const { destination, source } = result;
42 |
43 | // drop outside
44 | if(!destination) {
45 | return;
46 | }
47 |
48 | // drop in the same position
49 | if(
50 | destination.droppableId === source.droppableId &&
51 | destination.index === source.index
52 | ) {
53 | return;
54 | }
55 |
56 | const items = reorder(
57 | automation,
58 | source.index,
59 | destination.index
60 | );
61 |
62 | setAutomation(items);
63 | }
64 |
65 | const addAction = (action) => () => {
66 | setAutomation([...automation, {
67 | id: uuid(),
68 | action,
69 | color: randomcolor(0.3, 0.7).hexString()
70 | }]);
71 | }
72 |
73 | const runAutomation = () => {
74 | io.send("run", automation);
75 | }
76 |
77 | return (
78 |
79 |
87 |
88 |
89 |
90 | {automation.map((ActionObject, index) => (
91 |
92 |
93 |
94 | ))}
95 |
96 |
97 | {actions.map(action => (
98 |
99 | {action.name.replace(/([A-Z])/g, ' $1').trim()}
100 |
101 | ))}
102 |
103 |
104 |
105 |
106 | );
107 | }
108 |
109 | ReactDOM.render(, document.getElementById('react-page'))
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/icons/_library.scss:
--------------------------------------------------------------------------------
1 | .icon--library {
2 | background-image: url('data:image/svg+xml,%3Csvg fill="none" height="128" viewBox="0 0 32 128" width="32" xmlns="http://www.w3.org/2000/svg"%3E%3Cg clip-rule="evenodd" fill-rule="evenodd"%3E%3Cpath d="m7 12.0898s.87687-2.0898 4.5-2.0898c2.0378 0 3.2069.6611 3.8398 1.2397.3516.3214.5378.6174.6154.7603h.0896c.0776-.1429.2638-.4389.6154-.7603.6329-.5786 1.802-1.2397 3.8398-1.2397 3.6231 0 4.5 2.0898 4.5 2.0898v8.9102h-1.4875c-2.3815-1.0176-4.408-.681-5.8864.1813-.3793.2213-.7148.4985-.995.8187h-1.2579c-.2803-.3225-.6164-.6017-.997-.8246-1.4773-.8654-3.006-1.1939-5.3887-.1754h-1.9875zm8.5.387h-.4192c-.0024.0011-.0024.0012-.0024.0013l.0006.0012.001.0024.0018.0042.0028.0065c.0015.0033.0023.0049.0022.0048-.0001-.0002-.0034-.0071-.0102-.0197-.0137-.0252-.0414-.0729-.0862-.1361-.0893-.126-.246-.313-.4955-.507-.4849-.3769-1.3904-.8344-2.9949-.8344s-2.50998.4575-2.99494.8344c-.24946.194-.4062.381-.49549.507l-.00957.0137v7.6449h.78741c1.21949-.4959 2.29809-.6896 3.30659-.6161 1.0638.0775 1.964.4462 2.7877.9287.2176.1275.4243.2702.6183.4266zm1 8.2688v-8.2688h.4192c.0024.0011.0024.0012.0024.0013l-.0006.0012-.001.0024-.0018.0042-.0028.0065-.0022.0047c.0001-.0002.0034-.007.0102-.0196.0137-.0252.0414-.0729.0862-.1361.0893-.126.246-.313.4955-.507.4849-.3769 1.3904-.8344 2.9949-.8344s2.51.4575 2.9949.8344c.2495.194.4062.381.4955.507l.0096.0137v7.6449h-.2884c-2.5969-1.0455-4.8842-.6771-6.5894.3176-.219.1278-.427.2709-.6222.428z" fill="%23000" fill-opacity=".8"/%3E%3Cpath d="m7 44.0898s.87687-2.0898 4.5-2.0898c2.0378 0 3.2069.6611 3.8398 1.2397.3516.3214.5378.6174.6154.7603h.0896c.0776-.1429.2638-.4389.6154-.7603.6329-.5786 1.802-1.2397 3.8398-1.2397 3.6231 0 4.5 2.0898 4.5 2.0898v8.9102h-1.4875c-2.3815-1.0176-4.408-.681-5.8864.1813-.3793.2213-.7148.4985-.995.8187h-1.2579c-.2803-.3225-.6164-.6017-.997-.8246-1.4773-.8654-3.006-1.1939-5.3887-.1754h-1.9875zm8.5.387h-.4192c-.0024.0011-.0024.0012-.0024.0013l.0006.0012.001.0024.0018.0042.0028.0065c.0015.0033.0023.0049.0022.0048-.0001-.0002-.0034-.0071-.0102-.0197-.0137-.0252-.0414-.0729-.0862-.1361-.0893-.126-.246-.313-.4955-.507-.4849-.3769-1.3904-.8344-2.9949-.8344s-2.50998.4575-2.99494.8344c-.24946.194-.4062.381-.49549.507l-.00957.0137v7.6449h.78741c1.21949-.4959 2.29809-.6896 3.30659-.6161 1.0638.0775 1.964.4462 2.7877.9287.2176.1275.4243.2702.6183.4266zm1 8.2688v-8.2688h.4192c.0024.0011.0024.0012.0024.0013l-.0006.0012-.001.0024-.0018.0042-.0028.0065-.0022.0047c.0001-.0002.0034-.007.0102-.0196.0137-.0252.0414-.0729.0862-.1361.0893-.126.246-.313.4955-.507.4849-.3769 1.3904-.8344 2.9949-.8344s2.51.4575 2.9949.8344c.2495.194.4062.381.4955.507l.0096.0137v7.6449h-.2884c-2.5969-1.0455-4.8842-.6771-6.5894.3176-.219.1278-.427.2709-.6222.428z" fill="%23000" fill-opacity=".3"/%3E%3Cpath d="m7 76.0898s.87687-2.0898 4.5-2.0898c2.0378 0 3.2069.6611 3.8398 1.2397.3516.3214.5378.6174.6154.7603h.0896c.0776-.1429.2638-.4389.6154-.7603.6329-.5786 1.802-1.2397 3.8398-1.2397 3.6231 0 4.5 2.0898 4.5 2.0898v8.9102h-1.4875c-2.3815-1.0176-4.408-.681-5.8864.1813-.3793.2213-.7148.4985-.995.8187h-1.2579c-.2803-.3225-.6164-.6017-.997-.8246-1.4773-.8654-3.006-1.1939-5.3887-.1754h-1.9875zm8.5.387h-.4192c-.0024.0011-.0024.0012-.0024.0013l.0006.0012.001.0024.0018.0042.0028.0065c.0015.0033.0023.0049.0022.0048-.0001-.0002-.0034-.0071-.0102-.0197-.0137-.0252-.0414-.0729-.0862-.1361-.0893-.126-.246-.313-.4955-.507-.4849-.3769-1.3904-.8344-2.9949-.8344s-2.50998.4575-2.99494.8344c-.24946.194-.4062.381-.49549.507l-.00957.0137v7.6449h.78741c1.21949-.4959 2.29809-.6896 3.30659-.6161 1.0638.0775 1.964.4462 2.7877.9287.2176.1275.4243.2702.6183.4266zm1 8.2688v-8.2688h.4192c.0024.0011.0024.0012.0024.0013l-.0006.0012-.001.0024-.0018.0042-.0028.0065-.0022.0047c.0001-.0002.0034-.007.0102-.0196.0137-.0252.0414-.0729.0862-.1361.0893-.126.246-.313.4955-.507.4849-.3769 1.3904-.8344 2.9949-.8344s2.51.4575 2.9949.8344c.2495.194.4062.381.4955.507l.0096.0137v7.6449h-.2884c-2.5969-1.0455-4.8842-.6771-6.5894.3176-.219.1278-.427.2709-.6222.428z" fill="%2318a0fb"/%3E%3Cpath d="m7 108.09s.87687-2.09 4.5-2.09c2.0378 0 3.2069.661 3.8398 1.24.3516.321.5378.617.6154.76h.0896c.0776-.143.2638-.439.6154-.76.6329-.579 1.802-1.24 3.8398-1.24 3.6231 0 4.5 2.09 4.5 2.09v8.91h-1.4875c-2.3815-1.018-4.408-.681-5.8864.181-.3793.222-.7148.499-.995.819h-1.2579c-.2803-.322-.6164-.602-.997-.825-1.4773-.865-3.006-1.193-5.3887-.175h-1.9875zm8.5.387h-.4192c-.0024.001-.0024.001-.0024.001l.0006.001.001.003.0018.004.0028.006c.0015.004.0023.005.0022.005s-.0034-.007-.0102-.019c-.0137-.026-.0414-.073-.0862-.137-.0893-.126-.246-.313-.4955-.507-.4849-.377-1.3904-.834-2.9949-.834s-2.50998.457-2.99494.834c-.24946.194-.4062.381-.49549.507l-.00957.014v7.645h.78741c1.21949-.496 2.29809-.69 3.30659-.616 1.0638.077 1.964.446 2.7877.929.2176.127.4243.27.6183.426zm1 8.269v-8.269h.4192c.0024.001.0024.001.0024.001l-.0006.001-.001.003-.0018.004-.0028.006-.0022.005c.0001 0 .0034-.007.0102-.019.0137-.026.0414-.073.0862-.137.0893-.126.246-.313.4955-.507.4849-.377 1.3904-.834 2.9949-.834s2.51.457 2.9949.834c.2495.194.4062.381.4955.507l.0096.014v7.645h-.2884c-2.5969-1.045-4.8842-.677-6.5894.318-.219.127-.427.271-.6222.428z" fill="%23fff"/%3E%3C/g%3E%3C/svg%3E');
3 | }
4 |
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/scss/components/_select-menu.scss:
--------------------------------------------------------------------------------
1 | .select-menu {
2 | position: relative;
3 | display: block;
4 | box-sizing: border-box;
5 | width: 100%;
6 |
7 | cursor: default;
8 |
9 | &:disabled {
10 | opacity: 0.3;
11 | }
12 |
13 |
14 | &__button {
15 | @include font-ui-pos('small', 'normal');
16 |
17 | position: relative;
18 | display: flex;
19 | justify-content: space-between;
20 | width: 100%;
21 | height: 30px;
22 | margin: 1px 0 1px 0;
23 | padding: 6px 0 6px 8px;
24 |
25 | cursor: default;
26 |
27 | color: $figma-black-8;
28 | border: 1px solid transparent;
29 | border-radius: $border-radius-small;
30 | background-color: $figma-white;
31 |
32 | &:hover {
33 | border: 1px solid $figma-black-1;
34 |
35 | span:after {
36 | opacity: 0;
37 | }
38 |
39 | .select-menu__icon {
40 | opacity: 1;
41 | }
42 | }
43 |
44 | &:focus, &:active {
45 | width: 100%;
46 | padding: 5px 0 5px 7px;
47 |
48 | border: 2px solid $figma-blue;
49 | outline: none;
50 |
51 | span:after {
52 | opacity: 0;
53 | }
54 |
55 | .select-menu__icon {
56 | top: -1px;
57 | right: -1px;
58 |
59 | opacity: 1;
60 | }
61 | }
62 |
63 | &--active {
64 | &:hover {
65 | width: 100%;
66 | padding: 5px 0 5px 7px;
67 |
68 | border: 2px solid $figma-blue;
69 | outline: none;
70 | }
71 | }
72 | }
73 |
74 | &__button-label {
75 | display: inline-block;
76 |
77 | text-align: left;
78 |
79 | &:after {
80 | display: inline-block;
81 | width: 7px;
82 | height: 5px;
83 | margin-top: 6px;
84 | margin-left: 4px;
85 |
86 | content: '';
87 |
88 | background-color: transparent;
89 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%225%22%20viewBox%3D%220%200%207%205%22%20width%3D%227%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m3%203.70711-3-3.000003.707107-.707107%202.646443%202.64645%202.64645-2.64645.70711.707107-3%203.000003-.35356.35355z%22%20fill%3D%22%23000%22%20fill-opacity%3D%22.3%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E');
90 | }
91 | }
92 |
93 | &__icon {
94 | position: absolute;
95 | top: 0;
96 | right: 0;
97 | width: 30px;
98 | height: 30px;
99 |
100 | opacity: 0;
101 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2230%22%20viewBox%3D%220%200%2030%2030%22%20width%3D%2230%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m15%2016.7071-3-3%20.7071-.7071%202.6465%202.6464%202.6464-2.6464.7071.7071-3%203-.3535.3536z%22%20fill%3D%22%23000%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E');
102 | background-repeat: no-repeat;
103 | background-position: center center;
104 | }
105 |
106 | &__list {
107 | position: absolute;
108 | z-index: 2;
109 | display: none;
110 | flex-direction: column;
111 | width: 100%;
112 | margin: 0;
113 | padding: 8px 0 8px 0;
114 |
115 | border-radius: $border-radius-small;
116 | background-color: $figma-hud;
117 | box-shadow: $shadow-hud;
118 |
119 | &--active {
120 | display: flex;
121 | }
122 | }
123 |
124 | &__list-item {
125 | @include font-ui-neg('medium', 'normal');
126 |
127 | display: flex;
128 | align-items: center;
129 | width: 100%;
130 | height: 24px;
131 | padding: 0 8px 0 4px;
132 |
133 | color: $figma-white;
134 |
135 |
136 | &--active &-icon {
137 | opacity: 1 !important;
138 | }
139 |
140 | &:hover {
141 | background-color: $figma-blue;
142 | }
143 | }
144 |
145 | &__list-item-text {
146 | display: flex;
147 | align-items: center;
148 | width: 100%;
149 | height: 100%;
150 | padding: 0 0 0 4px;
151 | }
152 |
153 | &__list-item-icon {
154 | display: block;
155 | flex-shrink: 0;
156 | width: 24px;
157 | height: 24px;
158 |
159 | opacity: 0;
160 | background-image: url('data:image/svg+xml;utf8,%3Csvg%20fill%3D%22none%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20width%3D%2216%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20clip-rule%3D%22evenodd%22%20d%3D%22m13.2069%205.20724-5.50002%205.49996-.70711.7072-.70711-.7072-3-2.99996%201.41422-1.41421%202.29289%202.29289%204.79293-4.79289z%22%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E');
161 | background-repeat: no-repeat;
162 | background-position: center center;
163 | }
164 |
165 |
166 | &__divider {
167 | margin: 0;
168 | }
169 |
170 | &__divider-line {
171 | display: block;
172 | height: 1px;
173 | margin: 8px 0 7px;
174 |
175 | background-color: $figma-white-2;
176 | }
177 |
178 | &__divider-label {
179 | @include font-ui-neg('medium', 'normal');
180 |
181 | display: flex;
182 | align-items: center;
183 | height: 32px;
184 | margin-top: 8px;
185 | padding: 8px 8px 0 32px;
186 |
187 | color: $figma-white-4;
188 | border-top: 1px solid $figma-white-2;
189 |
190 | &--first {
191 | height: 24px;
192 | margin-top: 0;
193 | padding: 0 8px 0 32px;
194 |
195 | border-top: none;
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/src/hooks/Sortable.js:
--------------------------------------------------------------------------------
1 | import React, {
2 | createContext,
3 | useContext,
4 | useEffect,
5 | useReducer,
6 | useRef, useState
7 | } from 'react';
8 |
9 | // Tired of immutable update patterns? Take a look at immer, it's awesome!
10 | import produce from 'immer';
11 |
12 | // Hooks do not share any state between components, but we have context for it
13 | const SortableContext = createContext();
14 |
15 | // Our library needs DOM nodes of every single item we want to reorder
16 | // This custom hook will add React ref to the element and then push respective DOM node to the array on nodes on mount
17 | function useSortableElement() {
18 | const ref = useRef(null);
19 |
20 | // TODO use sortableBits to subscribe to only certain parts of context
21 | const { addNode } = useContext(SortableContext);
22 |
23 | useEffect(() => {
24 | addNode(ref.current);
25 | }, []);
26 |
27 | return {
28 | ref,
29 | style: {
30 | userSelect: 'none'
31 | }
32 | };
33 | }
34 |
35 | // We pass initial array of items to this hook which will reorder them after every 'dragEnd'
36 | // Our component will then be automatically notified about it and rerender
37 | function useSortable(initialItems) {
38 | const [items, setItems] = useState(initialItems);
39 |
40 | // TODO use sortableBits to subscribe to only certain parts of context
41 | const { isDragging, oldIndex, newIndex } = useContext(SortableContext);
42 |
43 | useEffect(() => {
44 | // When dragging has ended and had results
45 | if (isDragging === false && oldIndex !== newIndex) {
46 | // Move item from old index to new index in array
47 | setItems(produce(items, draft => {
48 | draft.splice(newIndex, 0, draft.splice(oldIndex, 1)[0]);
49 | }));
50 | }
51 | }, [isDragging]);
52 |
53 | return items;
54 | }
55 |
56 | // This is where the state is managed
57 | // "produce" stuff comes from immer and makes updating immutable data less painful
58 | function reducer(state, action) {
59 | switch (action.type) {
60 | // When sortable components are mounted they are added to "elements" array
61 | case 'ADD_NODE':
62 | return produce(state, draft => {
63 | draft.nodes.push(action.payload);
64 | });
65 | case 'DRAG_START':
66 | return produce(state, draft => {
67 | draft.isDragging = true;
68 | draft.initialY = action.payload.initialY;
69 | draft.draggedElement = {
70 | node: action.payload.node,
71 | rect: action.payload.node.getBoundingClientRect()
72 | };
73 | draft.draggedElementIndex = state.nodes.findIndex(node => node === action.payload.node);
74 | // We won't actually manipulate the original draggable node, that's why we create a duplicate
75 | draft.duplicateNode = action.payload.node.cloneNode(true);
76 | });
77 | case 'DRAG_END':
78 | return produce(state, draft => {
79 | draft.isDragging = false;
80 | });
81 | case 'SET_CURRENT_Y':
82 | return produce(state, draft => {
83 | draft.currentY = action.payload
84 | });
85 | case 'SET_NEW_INDEX':
86 | return produce(state, draft => {
87 | draft.draggedElementNewIndex = action.payload
88 | });
89 | default:
90 | return state;
91 | }
92 | }
93 |
94 | function Sortable(props) {
95 | const initialState = {
96 | nodes: []
97 | };
98 |
99 | const [state, dispatch] = useReducer(reducer, initialState);
100 |
101 | const containerRef = useRef();
102 |
103 | function addNode(node) {
104 | dispatch({ type: 'ADD_NODE', payload: node });
105 | }
106 |
107 | // Event handlers
108 | function onDragStart(e) {
109 | const clientY = e.type === 'touchstart' ? e.touches[0].clientY : e.clientY;
110 | if (state.nodes.some(node => node === e.target)) {
111 | dispatch({ type: 'DRAG_START', payload: { initialY: clientY, node: e.target } });
112 | }
113 | }
114 |
115 | function onDragEnd() {
116 | dispatch({ type: 'DRAG_END' });
117 | }
118 |
119 | function onDrag(e) {
120 | if (state.isDragging) {
121 | e.preventDefault();
122 |
123 | const clientY = e.type === 'touchmove' ? e.touches[0].clientY : e.clientY;
124 | dispatch({ type: 'SET_CURRENT_Y', payload: clientY - state.initialY });
125 | }
126 | }
127 |
128 | function addEventHandlers() {
129 | containerRef.current.addEventListener('mousedown', onDragStart, false);
130 | window.addEventListener('mousemove', onDrag, false);
131 | window.addEventListener('mouseup', onDragEnd, false);
132 | containerRef.current.addEventListener("touchstart", onDragStart, false);
133 | window.addEventListener("touchend", onDragEnd, false);
134 | window.addEventListener("touchmove", onDrag, false);
135 | }
136 |
137 | function removeEventHandlers() {
138 | containerRef.current.removeEventListener('mousedown', onDragStart, false);
139 | window.removeEventListener('mousemove', onDrag, false);
140 | window.removeEventListener('mouseup', onDragEnd, false);
141 | containerRef.current.removeEventListener("touchstart", onDragStart, false);
142 | window.removeEventListener("touchend", onDragEnd, false);
143 | window.removeEventListener("touchmove", onDrag, false);
144 | }
145 |
146 | function startDragging() {
147 | const originalRect = state.draggedElement.node.getBoundingClientRect();
148 |
149 | // We don't manipulate the original draggable node, but the duplicate
150 | // We append it to body, position exactly above original, move it around the page and remove after dragging has ended
151 | state.duplicateNode.style.position = 'absolute';
152 | state.duplicateNode.style.left = `${originalRect.left}px`;
153 | state.duplicateNode.style.top = `${originalRect.top}px`;
154 | state.duplicateNode.style.height = `${originalRect.height}px`;
155 | state.duplicateNode.style.width = `${originalRect.width}px`;
156 |
157 | document.body.appendChild(state.duplicateNode);
158 |
159 | // Hide original node
160 | state.draggedElement.node.style.visibility = 'hidden';
161 |
162 | // We want to animate our nodes
163 | state.nodes.forEach((node, i) => {
164 | if (i !== state.draggedElementIndex) {
165 | node.style.webkitTransition = 'transform 0.3s';
166 | }
167 | });
168 | }
169 |
170 | function endDragging() {
171 | document.body.removeChild(state.duplicateNode);
172 | state.draggedElement.node.style.visibility = 'visible';
173 | state.nodes.forEach(node => {
174 | node.style.webkitTransition = '';
175 | node.style.transform = '';
176 | });
177 | }
178 |
179 | // Move duplicate node across the screen
180 | // We don't use HTML5 drag and drop API and do the whole dragging animation manually
181 | function doDraggingAnimation() {
182 | state.duplicateNode.style.transform = `translate3d(0, ${state.currentY}px, 0)`;
183 | }
184 |
185 | function doReorderingAnimations() {
186 | const draggedRect = state.draggedElement.rect;
187 | const offset = state.currentY + draggedRect.y + draggedRect.height / 2;
188 |
189 | const draggedElementIndex = state.draggedElementIndex;
190 |
191 | // Computer science baby! This is where reordering animation happens
192 | // Every time cursor position changes we decide which node to move up/down using translate3D
193 | // Algorithm is crappy, but the purpose of this library is not to become better at algorithms
194 | state.nodes.forEach((node, index) => {
195 | const rect = node.getBoundingClientRect();
196 | // We do nothing with the node that is currently dragged
197 | if (index !== draggedElementIndex) {
198 | if (offset > rect.y && draggedElementIndex < index) {
199 | state.nodes[index].style.transform = `translate3d(0, -${draggedRect.height}px, 0)`;
200 | } else if (offset < rect.y + rect.height && draggedElementIndex > index) {
201 | state.nodes[index].style.transform = `translate3d(0, ${draggedRect.height}px, 0)`;
202 | } else {
203 | state.nodes[index].style.transform = `translate3d(0, 0, 0)`;
204 | }
205 | }
206 |
207 | // Update newIndex in state, we will expose this variable to children
208 | if (offset > rect.y && offset < rect.y + rect.height) {
209 | dispatch({ type: 'SET_NEW_INDEX', payload: index });
210 | }
211 | });
212 | }
213 |
214 | // Assignment of event handlers
215 | useEffect(() => {
216 | addEventHandlers();
217 | // If your effect returns a function React will run it when it is time to clean up (componentWillUnmount)
218 | return () => {
219 | removeEventHandlers();
220 | }
221 | // So this part here is confusing
222 | // Theoretically all of our event listeners should only be initialized on mount (useEffect(..., []))
223 | // But our event handlers depend on some variables which won't be updated unless we specify them here
224 | // But it also means that our event handlers will be reassigned every time these variables change
225 | // https://github.com/facebook/react/issues/14092#issuecomment-435907249
226 | // "This is a known limitation. We want to provide a better solution"
227 | }, [state.nodes, state.isDragging]);
228 |
229 | // Stuff we do when dragging started/ended
230 | useEffect(() => {
231 | if (state.isDragging) {
232 | startDragging();
233 | } else {
234 | if (state.draggedElement) {
235 | // Cleanup after dragging has ended
236 | // Remove duplicate, show original node, remove transformations and transitions
237 | endDragging();
238 | }
239 | }
240 | }, [state.isDragging]);
241 |
242 | // This gets called every time the Y coordinate of our dragged element has changed (often)
243 | useEffect(() => {
244 | if (state.duplicateNode) {
245 | doDraggingAnimation();
246 | doReorderingAnimations();
247 | }
248 | }, [state.currentY]);
249 |
250 | // We decide what to expose to child components through context
251 | const ctx = {
252 | addNode,
253 | isDragging: state.isDragging,
254 | oldIndex: state.draggedElementIndex,
255 | newIndex: state.draggedElementNewIndex
256 | };
257 |
258 | return
259 | {props.children}
260 | ;
261 | }
262 |
263 | export default Sortable;
264 |
265 | export {
266 | useSortable,
267 | useSortableElement
268 | }
--------------------------------------------------------------------------------
/lib/figma-plugin-ds/js/selectMenu.js:
--------------------------------------------------------------------------------
1 | (function(){
2 |
3 | 'use strict';
4 |
5 | // DEFAULT SETTINGS //////////
6 | var defaults = {
7 | selector: 'select-menu',
8 | position: 'under'
9 | }
10 | //position options
11 | // 'positionToSelected' = open menu to selected item
12 | // 'under' opens drop down below select menu
13 | // 'overlap' opens dropdown menu with first menu item overlapping select menu
14 |
15 | // VARIABLES /////////////
16 | var settings, selector, targets, optionList, selectedItem, itemHeight;
17 |
18 | var init = false;
19 |
20 | //PRIVATE FUNCTIONS //////////
21 |
22 | //create the select menus
23 | function createMenus() {
24 |
25 | let targetLen = targets.length;
26 | for (let i = 0; i < targetLen; i++) {
27 |
28 | //create menu element wrapper + ul + button + hide select menu
29 | createWrapper(document.createElement('div'), i);
30 |
31 | let optionGroups = targets[i].getElementsByTagName('optgroup');
32 | selectedItem = targets[i].selectedIndex;
33 | itemHeight = 0;
34 |
35 | //create option groups if they are present else create normal list items
36 | if (optionGroups.length != 0) {
37 | //yes there are option groups
38 |
39 | //determine if option groups have labels present
40 | let hasLabels;
41 | if (!optionGroups[0].label) {
42 | hasLabels = false;
43 | } else {
44 | hasLabels = true;
45 | }
46 |
47 | //loop through option groups
48 | for (let k = 0; k < optionGroups.length; k++) {
49 |
50 | //get children of option groups
51 | let optionGroupChildren = optionGroups[k].getElementsByTagName('option');
52 |
53 | //create divider element
54 | let divider = document.createElement('div');
55 | divider.className = selector + '__divider';
56 |
57 | // if labels are present, put them before the list item
58 | // otherwise put a divider after (unless it is the last item)
59 | if (hasLabels == true) {
60 |
61 | //create divider
62 | let dividerLabel = document.createElement('span');
63 | let labelText = document.createTextNode(optionGroups[k].label);
64 | dividerLabel.className = selector + '__divider-label';
65 |
66 | if (k === 0) {
67 | dividerLabel.classList.add(selector + '__divider-label--first');
68 | }
69 |
70 | dividerLabel.appendChild(labelText);
71 | divider.appendChild(dividerLabel);
72 | optionList.appendChild(divider);
73 |
74 | //calculate height of divider
75 | addItemHeight(dividerLabel);
76 |
77 | // create the list item
78 | for (let j = 0; j < optionGroupChildren.length; j++) {
79 | createListItem(optionGroupChildren[j]);
80 | }
81 |
82 | } else {
83 |
84 | // create the list item
85 | for (let j = 0; j < optionGroupChildren.length; j++) {
86 | createListItem(optionGroupChildren[j]);
87 | }
88 |
89 | if (k != optionGroups.length-1) {
90 | //create line
91 | let dividerLine = document.createElement('span');
92 | dividerLine.className = selector + '__divider-line';
93 | divider.appendChild(dividerLine);
94 | optionList.appendChild(divider);
95 |
96 | //calculate height of item to offset menu items
97 | addItemHeight(dividerLine);
98 |
99 | }
100 |
101 | }
102 |
103 | //prevent clicks on optgroup dividers
104 | divider.addEventListener('click', stopProp, false);
105 |
106 | }
107 |
108 | } else {
109 | //no there are no option groups
110 |
111 | //create select items (no groups)
112 | for (let k = 0; k < targets[i].length; k++) {
113 | //console.log(objectData.elements[i].options[k]);
114 | createListItem(targets[i].options[k]);
115 | }
116 |
117 | }
118 |
119 | }
120 |
121 | }
122 |
123 | //create wrapper element
124 | function createWrapper(selectWrapper, count) {
125 | let element = targets[count];
126 |
127 | //handle the select menu
128 | element.style.display = 'none'; //hide the select menu
129 |
130 | //set the selected option to the correct element if not set
131 | element.options[element.selectedIndex].selected = true;
132 |
133 |
134 | //create the div wrapper
135 | element.parentNode.insertBefore(selectWrapper, element);
136 | selectWrapper.appendChild(element);
137 | selectWrapper.className = selector;
138 |
139 | //create the new button element
140 | let selectButton = document.createElement('button');
141 | let selectButtonLabel = document.createElement('span');
142 | let selectButtonIcon = document.createElement('span');
143 | optionList = document.createElement('ul');
144 |
145 | //determine button label
146 | let selectButtonLabelText;
147 | if (element.selectedIndex == 0) {
148 | selectButtonLabelText = document.createTextNode(element.options[0].text);
149 | } else {
150 | let index = element.selectedIndex;
151 | selectButtonLabelText = document.createTextNode(element.options[index].text);
152 | }
153 |
154 | //assign class names
155 | selectButton.className = selector + '__button';
156 | selectButtonLabel.className = selector + '__button-label';
157 | selectButtonIcon.className = selector + '__icon';
158 | optionList.className = selector + '__list';
159 |
160 | //add button to dom
161 | selectWrapper.appendChild(selectButton);
162 | selectWrapper.appendChild(optionList);
163 | selectButton.appendChild(selectButtonLabel);
164 | selectButton.appendChild(selectButtonIcon);
165 | selectButtonLabel.appendChild(selectButtonLabelText);
166 |
167 | //overlap the position of the menu if setting selected
168 | if (settings.position == 'overlap') {
169 | optionList.style.top = 0;
170 | }
171 |
172 | //add event listener
173 | selectButton.addEventListener('click', displayMenu, false);
174 | }
175 |
176 | //create list item
177 | function createListItem(item) {
178 | if (item.value != "") {
179 | let listItem = document.createElement("li");
180 | let listIcon = document.createElement("span");
181 | let listText= document.createElement("span");
182 |
183 | listItem.className = selector + '__list-item';
184 | listIcon.className = selector + '__list-item-icon';
185 | listText.className = selector + '__list-item-text';
186 |
187 | listItem.setAttribute('data-value', item.value);
188 | listText.innerHTML +=item.text;
189 |
190 | listItem.appendChild(listIcon);
191 | listItem.appendChild(listText);
192 | optionList.appendChild(listItem);
193 |
194 | //add data attributes to item if positionToSelection is set
195 | if (settings.position == 'positionToSelection') {
196 | listItem.setAttribute('position', itemHeight);
197 | addItemHeight(listItem);
198 | }
199 |
200 | //if item is selected, add active class
201 | if (item.index == selectedItem) {
202 | listItem.classList.add(selector + '__list-item--active');
203 |
204 | if (settings.position == 'positionToSelection') {
205 | let menuPosition = -Math.abs(parseInt(listItem.getAttribute('position')));
206 | optionList.style.top = menuPosition + 'px';
207 | }
208 |
209 | }
210 |
211 | //event listener
212 | listItem.addEventListener('click', displayMenu, false);
213 | }
214 |
215 | }
216 |
217 | //function display menu
218 | var displayMenu = function(event) {
219 |
220 | let element = this;
221 |
222 | //determine if the the menu button or item is clicked
223 | if (element.tagName == 'BUTTON') {
224 |
225 | this.classList.toggle(selector + '__button--active');
226 |
227 | //toggle the dropdown
228 | let dropdown = element.parentNode.querySelector('UL');
229 | dropdown.classList.toggle(selector + '__list--active');
230 |
231 | } else if (element.tagName == 'LI') {
232 |
233 | let dropdown = element.parentNode.parentNode.querySelector('UL');
234 |
235 | //remove active classses from all menus
236 | let listItems = dropdown.getElementsByTagName('LI');
237 | for (let i = 0; i < listItems.length; i++) {
238 | listItems[i].classList.remove(selector + '__list-item--active');
239 | }
240 |
241 | //add active class
242 | element.classList.add(selector + '__list-item--active');
243 |
244 | //update the value of the select menu
245 | let select = dropdown.parentNode.querySelector('SELECT');
246 | let selectedValue = element.getAttribute('data-value');
247 | let selectItems = select.querySelectorAll('option');
248 | let selectItemsLen = selectItems.length;
249 |
250 | selectItems.forEach((item) => {
251 | item.removeAttribute("selected");
252 | });
253 |
254 | select.value = selectedValue;
255 |
256 | for (let i = 0; i < selectItemsLen; i++) {
257 | let value = selectItems[i].value;
258 | if (value == selectedValue) {
259 | selectItems[i].setAttribute('selected','selected')
260 | }
261 | }
262 |
263 |
264 | //update the dropdown button
265 | let button = element.parentNode.parentNode.querySelector('BUTTON');
266 | let buttonLabel = button.querySelector('.' + selector + '__button-label');
267 | buttonLabel.textContent = element.textContent;
268 | button.classList.toggle(selector + '__button--active');
269 |
270 | //toggle the dropdown
271 | dropdown.classList.toggle(selector + '__list--active');
272 |
273 | if (settings.position == 'positionToSelection') {
274 | let menuPosition = -Math.abs(parseInt(element.getAttribute('position')));
275 | element.parentNode.style.top = menuPosition + 'px';
276 | }
277 |
278 | }
279 |
280 | }
281 |
282 | //updates the selected value of the select menu
283 | function selectItem(selectedID, selectedValue) {
284 | let selectElement = document.getElementById(selectedID);
285 | selectElement.value = selectedValue;
286 | selectElement.setAttribute('selected', 'selected');
287 | }
288 |
289 |
290 | //EVENT HANDLERS //////////
291 |
292 | //stop event propagation
293 | var stopProp = function(event) {
294 | event.stopPropagation();
295 | }
296 |
297 | //track clicks outside the menu
298 | var isOutside = function(event) {
299 | let menus = document.querySelectorAll('select.' + selector);
300 |
301 | menus.forEach((menu) => {
302 | let parent = menu.parentNode;
303 | let menuList = parent.querySelector('UL');
304 | let button = parent.querySelector('BUTTON');
305 |
306 | if (menuList.classList.contains(selector + '__list--active')) {
307 | let clickInside = parent.contains(event.target);
308 | if (!clickInside) {
309 | menuList.classList.remove(selector + '__list--active');
310 | button.classList.remove(selector + '__button--active');
311 | }
312 | }
313 | });
314 | }
315 |
316 |
317 | //HELPER FUNCTIONS //////////
318 |
319 | //increment itemHeight
320 | function addItemHeight(element) {
321 |
322 | //get key dimensions to calculate height
323 | let dimensions = [
324 | parseInt(window.getComputedStyle(element, null).getPropertyValue('margin-top')),
325 | parseInt(window.getComputedStyle(element, null).getPropertyValue('margin-bottom')),
326 | parseInt(window.getComputedStyle(element, null).getPropertyValue('padding-top')),
327 | parseInt(window.getComputedStyle(element, null).getPropertyValue('padding-bottom')),
328 | parseInt(window.getComputedStyle(element, null).getPropertyValue('height')),
329 | ];
330 | itemHeight += arraySum(dimensions);
331 | }
332 |
333 | //helper function to return sum of array
334 | function arraySum(data) {
335 | return data.reduce(function(a,b){
336 | return a + b
337 | }, 0);
338 | }
339 |
340 |
341 | // PUBLIC FUNCTIONS /////////////
342 | window.selectMenu = {
343 |
344 | init: function(opts) {
345 |
346 | if (init == true) {
347 | selectMenu.destroy();
348 | }
349 |
350 | settings = Object.assign({}, defaults, opts);
351 | selector = settings.selector;
352 | targets = document.querySelectorAll('.' + selector);
353 |
354 | createMenus();
355 |
356 | //click handler for clicks outside of menu
357 | document.addEventListener('click', isOutside, false);
358 |
359 | init = true;
360 | },
361 |
362 | destroy: function() {
363 |
364 | //destroy the elements
365 | let selectMenus = document.querySelectorAll('select.' + selector);
366 |
367 | selectMenus.forEach((menu) => {
368 |
369 | let parent = menu.parentNode;
370 | let button = parent.querySelector('BUTTON');
371 | let menuList = parent.querySelector('UL');
372 |
373 | button.remove();
374 | menuList.remove();
375 |
376 | parent.outerHTML = parent.innerHTML;
377 |
378 | });
379 |
380 | //remove event handler
381 | document.removeEventListener('click', isOutside, false);
382 |
383 | init = false;
384 | }
385 |
386 | }
387 |
388 | })();
--------------------------------------------------------------------------------