Coder Social home page Coder Social logo

figma-plugin-ds's Introduction

Figma Plugin DS

A lightweight UI library for creating Figma plugins.

Contents

Intro

This package contains CSS and Javascript to closely match the look, feel and function of those found in Figma. It has been created without any frameworks (like React, Vue, etc.) and only leverages (native) javascript for components not possible without.

Getting started

You can install this package as a dependecy on your own project: npm install figma-plugin-ds

Styles To use the styles, you can use them via a link tag, or import them like a module using a CSS loader.

<!-- Standard link tag-->
<link rel="stylesheet" href="../../node_modules/figma-plugin-ds/dist/figma-plugin-ds.css">
//You could also inport the css via a CSS Loader in your JS environment (refer to syntax of whatever loader you are using)
import styles from 'figma-plugin-ds/dist/figma-plugin-ds.css'

To use the Select menu or Disclosure components, you will need to import the Javascript files as well. This package supports both standard IIFE (Immediately Invoked Function Expressions) and ES6 Modules. There are a number of ways to get started.

Scripts: IIFE hosted on CDN (quick and easy, I don't want to mess with npm packages)

<script src="https://cdn.jsdelivr.net/gh/thomas-lowry/figma-plugin-ds/dist/iife/figma-plugin-ds.js"></script>
<script>
    selectMenu.init(); //initiates the select menu component
    disclosure.init(); //initiates the disclosure component
<script>

Scripts: IIFE

<!-- Standard link tag-->
<script src="../node_modules/figma-plugin-ds/dist/iife/figma-plugin-ds.js"></script> 

Scripts: ES6 Modules

import { selectMenu, disclosure } from 'figma-plugin-ds';

Roadmap

  • New documentation website
  • Improved support for keyboard nav in the select menu
  • Slider component

Components

Button

To use the button, use the following HTML markup. Each button has a destructive option. Teritary buttons are styled like hyperlinks.

<!-- Primary -->
<button class='button button--primary'>Label</button> 
<button class='button button--primary-destructive'>Label</button>
<button class='button button--primary' disabled>Label</button> 

<!-- Secondary -->
<button class='button button--secondary'>Label</button>
<button class='button button--secondary-destructive'>Label</button>
<button class='button button--secondary' disabled>Label</button>

<!-- Tertirary (Hyperlink style button) -->
<button class='button button--tertiary'>Label</button>
<button class='button button--tertiary-destructive'>Label</button>
<button class='button button--tertiary' disabled>Label</button>

Modifiers

Modifier class Description
button--primary Primary button
button--primary-destructive Primary button with red destructive variant for actions such as deleting something
button--secondary Secondary button with outline style
button--secondary-destructive Secondary button with red destructive variant for actions such as deleting something
button--tertiary Tertiary button with hyperlink style
button--tertiary-destructive Tertiary button with red destructive variant for actions such as deleting something

Checkbox

To use the checkbox, use the following HTML markup. Remember each checkbox should get a unique ID that is referenced in the label. This ensures the checkbox and the entire label are clickable.

<!-- Checkbox unchecked -->
<div class="checkbox">
  <input id="uniqueId" type="checkbox" class="checkbox__box">
  <label for="uniqueId" class="checkbox__label">Label</label>
</div>

<!-- Checkbox checked -->
<div class="checkbox">
  <input id="uniqueId" type="checkbox" class="checkbox__box" checked>
  <label for="uniqueId" class="checkbox__label">Label</label>
</div>

<!-- Checkbox disabled -->
<div class="checkbox">
  <input id="uniqueId" type="checkbox" class="checkbox__box" disabled>
  <label for="uniqueId" class="checkbox__label">Label</label>
</div>

Disclosure

To use a disclosure panel, you must use the following markup and also make sure you initialize the Javascript for the disclosure to work.

<!-- Disclosure -->
<ul class="disclosure">
  <li class="disclosure__item disclosure--expanded">
    <div class="disclosure__label disclosure--section">Disclosure heading</div> <!-- This item is styled as a section -->
    <div class="disclosure__content">Panel content here</div>
  </li>

  <li class="disclosure__item disclosure--expanded"> <!-- This item is expanded on load -->
    <div class="disclosure__label">Disclosure heading</div>
    <div class="disclosure__content">Panel content here</div>
  </li>

  <li class="disclosure__item">
    <div class="disclosure__label">Disclosure heading</div>
    <div class="disclosure__content">Panel content here</div>
  </li>
</ul>

To initialize with Javascript:

//initialize all disclosure panels
disclosure.init();

//uninitialize all disclosure panels
disclosure.destroy();

Modifiers

Modifier class Description
disclosure--section Add this class to the disclosure__label to style it like a heading
disclosure--expanded Add this class to the disclosure__item to have it expanded on load

Icon

To use the icon component, use the following markup. Apply the appropriate modifier class to select the item you wish to use, you can also add additional modifiers to change the color, or even spin the icon. You can also specify no icon name to use a text character as an icon (for example, like found in the width + height icon inputs in Figma)

<!-- Icon -->
<div class="icon icon--theme"></div>

<!-- Icon with blue modifier class to change color -->
<div class="icon icon--theme icon--blue"></div>

<!-- Spinner icon with spinning animation-->
<div class="icon icon--spinner icon--spin"></div>

<!-- Text icon -->
<div class="icon">W</div>

Modifiers

Modifier class Description
icon--iconName* Sepcify which icon to use. Ex: icon--adjust or icon--settings
icon--spin Causes the icon to spin in an endless loop (for example: a loader used with icon--spinner)
icon--colorName* Pass the name of any Figma color var to this prop. Ex: icon--blue or icon--black3

*Colors accepted: icon--blue, icon--purple, icon--purple4, icon--hot-pink, icon--green, icon--red, icon--yellow, icon--black, icon--black8, icon--black3, icon--white, icon--white8, icon--white4

Icons

To use an icon, add one of the following modifier classes (see markup example above).

Icon Modifier class
IconAdjust icon--adjust
IconAlert icon--alert
IconAngle icon--angle
IconArrowLeftRight icon--arrow-left-right
IconUpDown icon--updown
IconAutoLayoutHorizontal icon--auto-layout-horizontal
IconAutoLayoutVertical icon--auto-layout-vertical
IconBack icon--back
IconBlendEmpty icon--blend-empty
IconBlend icon--blend
IconBreak icon--break
IconCaretDown icon--caret-down
IconCaretLeft icon--caret-left
IconCaretRight icon--caret-right
IconCaretUp icon--caret-up
IconCheck icon--check
IconClose icon--close
IconComponent icon--component
IconCornerRadius icon--corner-radius
IconCorners icon--corners
IconDistributeHorizontalSpacing icon--distribute-horizontal-spacing
IconDistributeVerticalSpacing icon--distribute-vertical-spacing
IconDraft icon--draft
IconEffects icon--effects
IconEllipses icon--ellipses
IconEyedropper icon--eyedropper
IconForward icon--forward
IconFrame icon--frame
IconGroup icon--group
IconHidden icon--hidden
IconHorizontalPadding icon--horizontal-padding
IconHyperlink icon--hyperlink
IconImage icon--image
IconInstance icon--instance
IconKey icon--key
IconLayoutAlignBottom icon--layout-align-bottom
IconAlignHorizontalCenters icon--align-horizontal-centers
IconAlignLeft icon--align-left
IconAlignRight icon--align-right
IconAlignTop icon--align-top
IconAlignVerticalCenters icon--align-vertical-centers
IconLayoutGridColumns icon--layout-grid-columns
IconLayoutGridRows icon--layout-grid-rows
IconLayoutGridUniform icon--layout-grid-uniform
IconLibrary icon--library
IconLinkBroken icon--link-broken
IconLinkConnected icon--link-connected
IconListDetailed icon--list-detailed
IconListTile icon--list-tile
IconList icon--list
IconLockOff icon--lock-off
IconLockOn icon--lock-on
IconMinus icon--minus
IconPlay icon--play
IconPlus icon--plus
IconRandom icon--random
IconRecent icon--recent
IconResizeToFit icon--resize-to-fit
IconResolveFilled icon--resolve-filled
IconResolve icon--resolve
IconReverse icon--reverse
IconSearchLarge icon--search-large
IconSearch icon--search
IconSettings icon--settings
IconShare icon--share
IconSmiley icon--smiley
IconSortAlphaAsc icon--sort-alpha-asc
IconSortAlphaDsc icon--sort-alpha-dsc
IconSortTopBottom icon--sort-top-bottom
IconSpacing icon--spacing
IconSpinner icon--spinner
IconStarOff icon--star-off
IconStarOn icon--star-on
IconStrokeWeight icon--stroke-weight
IconStyles icon--styles
IconSwap icon--swap
IconTheme icon--theme
IconTidyUpGrid icon--tidy-up-grid
IconTidyUpListHorizontal icon--tidy-up-list-horizontal
IconTidyUpListVertical icon--tidy-up-list-vertical
IconTimer icon--timer
IconTrash icon--trash
IconVerticalPadding icon--vertical-padding
IconVisible icon--visible
IconWarningLarge icon--warning-large
IconWarning icon--warning

Icon button

The icon button is essentially a wrapper for the icon component. Refer to the icon component above for its usage.

<!-- Icon button with a blend icon -->
<div class="icon-button">
  <div class="icon icon--blend"></div>
</div>

<!-- Icon button with selected modifier -->
<div class="icon-button icon-button--selected">
  <div class="icon icon--blend"></div>
</div>

Input

To use the input, use the following markup. You can also insert an icon into the input (see Icon component for usage).

<!-- Input with placeholder -->
<div class="input">
  <input type="input" class="input__field" placeholder="Placeholder">
</div>

<!-- Input with initial value -->
<div class="input">
  <input type="input" class="input__field" value="Initial value">
</div>

<!-- Disabled input -->
<div class="input">
  <input type="input" class="input__field" value="Initial value" disabled>
</div>

<!-- Input with icon -->
<div class="input input--with-icon">
  <div class="icon icon--angle"></div>
  <input type="input" class="input__field" value="Value">
</div>

Modifiers

Modifier class Description
input--with-icon* Add this modifier class if you plan to include the icon component within the input

Labels and sections

To use a label or section, use the following markup.

<!-- Label -->
<div class="label">Label</div>

<!-- Section title -->
<div class="section-title">Section title</div>

Onboarding tip

To create an onboarding tip, use the following markup. The tip also makes use of the icon component (see Icon component for usage).

<div class="onboarding-tip">
  <div class="icon icon--styles"></div>
  <div class="onboarding-tip__msg">Onboarding tip goes here.</div>
</div>

Radio button

To create an radio button, use the following markup. Remember each group of radio buttons must share the same name so that they are related to one another. Each button should have a unique id so that its label is associated with it and remains part of the clickable hit area.

<!-- Radio button -->
<div class="radio">
    <input id="radioButton1"type="radio" class="radio__button" value="Value" name="radioGroup" >
    <label for="radioButton1" class="radio__label">Radio button</label>
</div>

<!-- Radio button checked -->
<div class="radio">
    <input id="radioButton2"type="radio" class="radio__button" value="Value" name="radioGroup" checked>
    <label for="radioButton2" class="radio__label">Radio button</label>
</div>

<!-- Radio button disabled-->
<div class="radio">
    <input id="radioButton3"type="radio" class="radio__button" value="Value" name="radioGroup" disabled>
    <label for="radioButton3" class="radio__label">Radio button</label>
</div>

Select menu

To create an select menu, use the following markup. The select menu also requires you to initalize it with Javascript. If your plugin requires you to add or remove items in the select menu, simply use Javascript to modify the select menu and the select will reinitialize.

The select menu will open and position the menu to the selected object. If there is no vertical room inside your plugin's iFrame, the position of the menu will be moved to ensure it fits inside the iframe. If you have a select menu with too many options to fit within the iFrame, the menu will scroll vertically.

<!-- Select menu, default behavior is for the initial item to get selected -->
<select id="uniqueId" class="select-menu">
  <option value="1" >Item 1</option>
  <option value="2" >Item 2</option>
  <option value="3" >Item 3</option>
</select>

<!-- Select menu, provide an initial item with no value to have no items selected -->
<select id="uniqueId" class="select-menu">
  <option>Please make a selection</option>
  <option value="2" >Item 2</option>
  <option value="3" >Item 3</option>
</select>

<!-- Disabled select menu -->
<select id="uniqueId" class="select-menu" disabled>
  <option value="1" >Item 1</option>
  <option value="2" >Item 2</option>
  <option value="3" >Item 3</option>
</select>

To initialize with Javascript:

//initialize all select menus
selectMenu.init();

//uninitialize all select menus
selectMenu.destroy();

Switch

To use the switch, use the following HTML markup. Remember each switch should get a unique ID that is referenced in the label. This ensures the switch and the entire label are clickable.

<!-- Switch -->
<div class="switch">
    <input class="switch__toggle" type="checkbox" id="uniqueId">
    <label class="switch__label" for="uniqueIdA">Label</label>
</div>

<!-- Switch checked -->
<div class="switch">
    <input class="switch__toggle" type="checkbox" id="uniqueId" checked>
    <label class="switch__label" for="uniqueId">Label</label>
</div>

<!-- Disabled switch -->
<div class="switch">
    <input class="switch__toggle" type="checkbox" id="uniqueId" disabled>
    <label class="switch__label" for="uniqueId">Label</label>
</div>

Textarea

To use the textarea, use the following HTML markup.

<!-- Textarea -->
<textarea class="textarea" rows="2">Initial value</textarea>

<!-- Disabled textarea -->
<textarea class="textarea" rows="2" disabled>Initial value</textarea>

Type

To use the typography that is styled like it is in the Figma UI, use the following markup plus additional modifier classes to modify the size, weight, and letterspacing that is optimized for positive (dark text on light background) and negative (light text on dark background) applications.

<div class="type">UI11, size: xsmall (default) weight: normal, positive</div>
<div class="type type--large type--bold">UI13, size: large, weight: bold, positive</div>
<div class="type type--small type--medium type--inverse">UI12, size: large, weight: medium, negative</div>

Modifiers

Modifier class Description
type--small Font size 12px
type--large Font size 13px
type--xlarge Font size 14px
type--medium Font weight medium
type--bold Font weight bold
type--inverse Inversed (negative) application where light text is on dark background with increased letterspacing

Defaults: Font size 11px, normal weight, positive application

figma-plugin-ds's People

Contributors

brianlovin avatar jackiecorn avatar jb1905 avatar nil avatar thomas-lowry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

figma-plugin-ds's Issues

Web Components?

After using your lib more often, I might have the idea, that web-components might be a good way to distribute it (at least for those components that need javascript backup). What brought me to web-components rather than using an existing FE framework:

  • It's main purpose is to be used within just html/css, figma plugin sandbox luckily doesn't come with any specific framework/library out of the box
  • In case somebody decides to use his favorite framework/library, it still can be used
  • It's the common lowest common denominator amongst all that

Have you also thought about this? What's your stance?

Publishing package to npm

Hi! I love this little DS โค๏ธ Have you considered publishing figma-plugin-ds as an npm package?

Buttons not reacting to presses correct

Seems when you press the button, it keeps it in the clicked/active state until you click on something outside of it, instead of just doing it when clicking on it.

Could try to fix this, but blocked because of #8

Interactive elements (like button, switch, etc) inside the disclosure are not clickable

According to the CSS declaration for .disclosure__content, the content is not clickable

pointer-events: none;

But if a user puts an interactive element (eg. a button, a switch, etc.) inside the "disclosure" component, the interactive element is not clickable. I suggest overwriting the property when the disclose is expanded:

.disclosure--expanded .disclosure__content {
    pointer-events: all;
}

(Happy to open a PR if you think is OK)

Select menu broken, if there are no options

Hey,

fantastic job on this UI toolkit for figma plugins. I just used it and I figured there is a bug with the select-menu. It fails and breaks everything after, if there are no options.

Bildschirmfoto 2019-12-30 um 18 57 10

Here is a screenshot I took from current development.

Looks like this is the affected line:

element.options[element.selectedIndex].selected = true;

as this is the only .selected occurence ;)

My workaround is, that I only add the class class="select-menu" if I know I have options to that select and run the init after.

License

The company I work for requires a licenses to use open source code. Would it be possible to add a license to this?

Thanks!

Dropdown?

Any interest in adding a dropdown list as well? Would be great to have. If someone does the same design they have in Figma, I think I could implement and submit a patch relatively quickly.

How to use this library?

Hello, sorry for posting issue. I don't understand how to use this kit. I have put <link> stylesheet in ui.html file, then I tried to make a full html page in ui.html and put these tags in <head /> then I tried to copy css from node_modules directly to ui.html and reference it as href="./css/figma-plugin-ds.css" but Figma seems to ignore any links and iframe is displayed as base64

image
This is the popup that appears with plugin

The menu of a <select> control doesn't refresh when it is dynamically populated with <option>

I have a select control that uses the figma-plugin-ds CSS. When I dynamically populate it with multiple option elements using JavaScript, the menu only shows the options that existed before adding them (even though in the code they are there). Is there a way to force the control to refresh?

If I use a native, non-skinned, select control I can see the dynamically added option elements.

I suggest replacing it

parent.outerHTML = parent.innerHTML;

I suggest replacing it with because:

  1. The menu is hidden above, but you should at least display it again.
  2. replaceWith does not create new nodes, which preserves their properties.
menu.style.display = "";
parent.replaceWith(menu)

What happened to .visual-bell ?

I was using .visual-bell and its various states in the previous version of this design system and now it doesn't seem to be present? Is it called something else? Removed?

Figma Integrated Color Picker Support

I just started using this library and realized that there is no dedicated element style support for the integrated Figma color input which uses an integrated sandbox for color picking with RGB, HEX and HSB. It was quite disappointing to not find any style class for it in this repository as it is the standard for any color input in any newer Figma plugin

<div class="input">
  <input type="color" id="color1" class="colorPicker"/>
  <label for="colorPicker">Color 1</label>
</div>

Is there any possibility for the inclusion of the color input element style support in this repository in the future?

Developer/contributing documentation?

Seems there is a lot of steps to build, minify and otherwise be able to reproduce the same files that exists here in this repository.

In order to contribute, it'd be great to be able to run these steps locally too. Currently I'm trying to figure out why the <select> element is not firing change events and was gonna use this websites examples as a base, but because I don't know/understand how this project is built, I cannot use it...

Dark mode updates?

With Figma's latest release of dark mode, any chance of this being updated to include dark mode elements/UI updates?

Texts to show default cursor on hover

Hey Tom, great work on the plugin ds!
I'm wondering if texts elements like Labels should remove the cursor change on hover, since in the native Figma UI almost all texts keeps the cursor unchanged.
What do you think?

Getting up and running

Hi, i'm trying to get the plugin up and running. Have followed the instructions but styles are not showing up.

<link
  rel="stylesheet"
  href="./node_modules/figma-plugin-ds/dist/figma-plugin-ds.css"
/>

Missing Effect Icons

These icons are present in the Figma UI but missing from UI2 doc and the package

  • Drop Shadow
  • Layer Blur
  • Background Blur
  • Inner Blur

image

Spinning icon is not centered correctly

When an icon (in particular the spinner) is spinning, the center of the icon has an offset that makes the animation look wrong:
Screen Recording 2020-09-09 at 11 25 19

You can see a live demo here:
https://codesandbox.io/s/vigilant-dubinsky-ywl8q?file=/index.html

It is caused by this line:

background-position: -2px -1px;

which I have no idea why it was introduced. Looks a strange declaration to me, probably should just be:

background-position: 50% 50%;

Do you think we can fix this? Happy to open a PR for this.

Backward compatibility is broken?

I just checked classnames for components, and it seems not backward compatible with previous realization. For sure it looks better, because it's kind of BEM, but good to mention this in README

SelectMenu: cannot read property 'classList' of null

Hey! First of all, great job on making this awesome resource ๐Ÿ‘

I'm having some issues with using the Select menu component in the way it's presented on the docs. I'm importing the whole figma-plugin-ds.min.js and then running the code in the docs to initialize, i.e.:

I'm doing this

selectMenu.init({
    position: 'positionToSelection' //other options: 'under', 'overlap'
});

The markup is also the same as in the docs:

<select name="" id="select-menu1" class="select-menu">
    <option value="1" selected="selected">Item 1</option>
    <option value="2" >Item 2</option>
</select>

Then I get this error

But when I do this, figma-plugin-ds.min.js is throwing this error:

Uncaught TypeError: Cannot read property 'classList' of null

This seems easy enough to work around, but I can't help but feel like I'm doing something silly :)

Has anyone else stumbled upon this issue? Or alternatively, does someone know how to initialize it properly?

import styles from

Am I missing something? You have import styles from 'figma-plugin-ds/dist/figma-plugin-ds.css' listed in the documentation, but that file isn't a module.css file so it comes back undefined if you console.log the styles export and if you try and use it in your code with {styles.button} or something it throws caught TypeError: Cannot read properties of undefined (reading 'button')

Disclosures not working in React UI

Hey Thomas - I can't seem to get the Disclosures to work out of the box in a React UI. Clicking on them doesn't seem to be swapping the --expanded class properly. If I add it manually in the React code it does get the correct --expanded styling, so I think the issue may be somewhere in the JS itself.

Start using tags & releases

Hey,

it would be great if you could tag releases and add the changes to a release so one can easily see the difference on the github releases page. ๐Ÿ‘

Publish to npm

It'd be great if these components (JS/CSS/SCSS/etc) were published to npm!

Use "currentColor" for the SVG icons fill

Do you think it would be possible to use currentColor instead of #000 for the fill of the SVG icons (or potentially just leave it empty, so it inherits the color value)? In this way it would be easier to tint the icons (instead of using CSS filters). Also, since the current fill is black anyway, this probably would have a minimal impact on the existing usage of the icons.

If it's something you would consider, let me know that I can open a PR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.