master 612afa98a79d cached
28 files
121.2 KB
30.5k tokens
1 requests
Download .txt
Repository: thomas-lowry/figma-plugin-ds-svelte
Branch: master
Commit: 612afa98a79d
Files: 28
Total size: 121.2 KB

Directory structure:
gitextract_z97jab7u/

├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── public/
│   └── index.html
├── rollup.config.js
└── src/
    ├── App.svelte
    ├── components/
    │   ├── Button/
    │   │   └── index.svelte
    │   ├── Checkbox/
    │   │   └── index.svelte
    │   ├── Disclosure/
    │   │   └── index.svelte
    │   ├── DisclosureItem/
    │   │   └── index.svelte
    │   ├── Icon/
    │   │   └── index.svelte
    │   ├── IconButton/
    │   │   └── index.svelte
    │   ├── Input/
    │   │   └── index.svelte
    │   ├── Label/
    │   │   └── index.svelte
    │   ├── OnboardingTip/
    │   │   └── index.svelte
    │   ├── Radio/
    │   │   └── index.svelte
    │   ├── Section/
    │   │   └── index.svelte
    │   ├── SelectDivider/
    │   │   └── index.svelte
    │   ├── SelectItem/
    │   │   └── index.svelte
    │   ├── SelectMenu/
    │   │   └── index.svelte
    │   ├── Switch/
    │   │   └── index.svelte
    │   ├── Textarea/
    │   │   └── index.svelte
    │   └── Type/
    │       └── index.svelte
    ├── global.css
    ├── index.js
    └── test.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
 *.* linguist-language=JavaScript


================================================
FILE: .gitignore
================================================
public/components.js
todo.md

.DS_Store
node_modules
yarn.lock
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 Thomas Lowry

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Figma Plugin DS Svelte

WORK IN PROGRESS—This is a Svelte version of the Figma Plugin DS specifically for use in creating Figma Plugins. I decided to create this because Svelte seems like a great lightweight approach well suited for creating Figma plugins, and also improves the developer experience when compared to my vanilla JS Figma Plugin DS due to simplified markup.

You can also get started with [Figsvelte](https://github.com/thomas-lowry/figsvelte), a boilerplate for Figma plugins that already has this library setup as a dependency.

## Installation

To install into your own Svelte project.
`npm i -D figma-plugin-ds-svelte`

## To use

```javascript
//import the global css which includes Figma color, spacing, and type vars
//also includes a basic set of utility classes
import { GlobalCSS } from 'figma-plugin-ds-svelte';

//import the desired components
import { Button, Input, SelectMenu } from 'figma-plugin-ds-svelte';
```

---

## Components
_All components can accept class props to add global or utility classes to each component_

* [Button](#Button)
* [Checkbox](#Checkbox)
* [Disclosure panel](#Disclosure)
* [Icon](#Icon)
* [Icon button](#Icon-button)
* [Input](#Input)
* [Labels and sections](#Labels-and-sections)
* [Onboarding tip](#Onboarding-tip)
* [Radio button](#Radio-button)
* [Select menu](#Select-menu)
* [Switch](#Switch)
* [Textarea](#Textarea)
* [Type](#Type)
* [Tokens](#Tokens)

---

### Button
```javascript
import { Button } from 'figma-plugin-ds-svelte';
```
```html
<Button on:click={funcName}>Label</Button>
<Button on:click={funcName} variant="secondary">Label</Button>
<Button on:click={funcName} variant="secondary" destructive>Label</Button>
<Button on:click={funcName} disabled>Label</Button>
```
**Props**

| Prop           | Type    | Options/notes                                                   |
|:---------------|:--------|:----------------------------------------------------------------|
| `on:click`     | Func    | Assign a function to execute on click. Ex: `on:click={funcName}`|
| `variant`      | String  | Default: `"primary"`, Options: `"secondary"`, `"tertiary"`      |
| `disabled`     | Boolean | Default: `false`                                                |
| `destructive` | Boolean | Default: `false`                                                |

---

### Checkbox
```javascript
import { Checkbox } from 'figma-plugin-ds-svelte';
```
```html
<Checkbox>Label</Checkbox>
<Checkbox checked>Label</Checkbox>
<Checkbox disabled>Label</Checkbox>
```
**Props**

| Prop       | Type    | Options/notes                                                                            |
|:-----------|:--------|:-----------------------------------------------------------------------------------------|
| `on:change`| Func    | Funtion to execute on change. Ex: `on:change={funcName}`                                 |
| `value`    | Boolean | Default: `false`;                                                                        |
| `checked`  | Boolean | Default: `false`; You can bind the value when checked to a var. `bind:checked={varName}` |
| `disabled` | Boolean | Default: `false`                                                                         |

---

### Disclosure
```javascript
import { Disclosure, DisclosureItem } from 'figma-plugin-ds-svelte';
```
```html
<Disclosure>
  <DisclosureItem title="Item 1" open>Content here</DisclosureItem>
  <DisclosureItem title="Item 2">Content here</DisclosureItem>
  <DisclosureItem title="Item 3">Content here</DisclosureItem>
</Disclosure>
```
**Props**

| Prop       | Type    | Options/notes                                                     |
|:-----------|:--------|:------------------------------------------------------------------|
| `title`    | String  | Title of disclosure item                                          |
| `open`     | Boolean | Default: `false`; Only one disclosure item can be opened at once  |
| `section`  | Boolean | Default: `false`; Bold section header for disclosure title        |

---

### Icon
```javascript
//You need to import the icon component + whatever icons you want to use,
//pass the names of your icon modules to the iconName prop in the Icon component
import { Icon, IconName } from 'figma-plugin-ds-svelte';

//You can also import your own svg icon (32x32) and pass it to the icon component
import SvgName from './src/directory/image.svg';

//Example
import { Icon, IconVisible, IconSpinner } from 'figma-plugin-ds-svelte';
```
```html
<Icon iconName={IconVisible} color="black"/>
<Icon iconName={IconSpinner} color="blue" spin/>
<Icon iconText="W" color="blue"/>
```
**Props**

| Prop       | Type    | Options/notes                                                                                |
|:-----------|:--------|:---------------------------------------------------------------------------------------------|
| `iconName` | Var     | Pass an imported SVG to this prop. `iconName={IconImport}`                                   |
| `iconText` | String  | Pass a text character to use instead of an icon. Ex: width and height inputs `iconText="W"`  |
| `color`    | String  | Pass the name of any Figma color var to this prop. `color="blue"`                            |
| `spin`     | Boolean | Default: `false`; This will rotate the icon in an endless loop.                              |

**Icons**


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


---

### Icon button
```javascript
//use this component as you would an Icon, it accepts the same props (except color)
import { IconButton } from 'figma-plugin-ds-svelte';
```
```html
<IconButton on:click={funcName} iconName={IconVisible}/>
<IconButton on:click={funcName} iconName={IconVisible} selected/>
<IconButton on:click={funcName} iconText="@"/>
```
**Props**

| Prop       | Type    | Options/notes                                                    |
|------------|---------|------------------------------------------------------------------|
| `on:click` | Func    | Assign a function to execute on click. Ex: `on:click={funcName}` |
| `selected` | Boolean | Default: `false`                                                 |
| `iconName` | String  | _See Icon component for usage._                                  |
| `IconText` | String  | _See Icon component for usage._                                  |
| `spin`     | Boolean | _See Icon component for usage._                                  |

---

### Input
```javascript
import { Input } from 'figma-plugin-ds-svelte';

//var to define and store value
var inputValue = 'Default value'; 
```
```html
<Input bind:value={inputValue}/>
<Input bind:value={inputValue} disabled/>
<Input placeholder="Enter some info..."/>

<!-- You can also pass Icon props to use the icon component inside the input -->
<Input iconName={IconName} />
<Input iconName={IconSpinner} spin placeholder="Fetching data..." />

<!-- Force borders on the input -->
<Input value="Value" borders/>
```
**Props**

| Prop          | Type    | Options/notes                                                      |
|:--------------|:--------|:-------------------------------------------------------------------|
| `on:change`   | Func    | Funtion to execute on change. Ex: `on:change={funcName}`           |
| `value`       | String  | Value that will get populated by user or specify predefined value. You can also bind this to a variable. |
| `placeholder` | String  | Placeholder text.                                                  |
| `borders`     | Boolean | Default: `false`; Force a border on the input field.               |
| `disabled`    | Boolean | Default: `false`                                                   |
| `iconName`    | Var     | _See Icon component for usage._                                    |
| `iconText`    | String  | _See Icon component for usage._                                    |
| `spin`        | Boolean | _See Icon component for usage._                                    |

---

### Labels and sections
```javascript
import { Label, SectionHeader } from 'figma-plugin-ds-svelte';
```
```html
<Label>Label name</Label>
<Section>Section name</Section>
```

---

### Onboarding tip
```javascript
import { OnboardingTip } from 'figma-plugin-ds-svelte';
```
```html
<OnboardingTip iconName={IconStyles}>
  Tip text goes here
</OnboardingTip>
```
**Props**

| Prop       | Type    | Options/notes                   |
|:-----------|:--------|:--------------------------------|
| `iconName` | Var     | _See Icon component for usage._ |
| `iconText` | String  | _See Icon component for usage._ |
| `spin`     | Boolean | _See Icon component for usage._ |

---

### Radio button
```javascript
import { Radio } from 'figma-plugin-ds-svelte';

//use bind:group, with a var to create a radio group and store the value of selected item
//set value if this var to same value as radio item to set initial selection
var radioValue;
```
```html
<Radio bind:group={radioValue} value="a">Label</Radio>
<Radio bind:group={radioValue} value="b">Label</Radio>
```
**Props**

| Prop       | Type    | Options/notes                                             |
|:-----------|:--------|:----------------------------------------------------------|
| `on:change`| Func    | Funtion to execute on change. Ex: `on:change={funcName}`  |
| `group`    | Var     | Pass name of var to store selected item from radio group. |
| `value`    | String  | Value of radio item.                                      |
| `disabled` | Boolean | Default: `false`                                          |

---

### Select menu
```javascript
import { SelectMenu } from 'figma-plugin-ds-svelte';

//You will need to pass and bind an array of menu items to this
//Note: it is up to you to sort this array however you want
let menuItemArray = [
  { 'value': 'item1', 'label': 'Menu item 1', 'group': null, 'selected': false },
  { 'value': 'item2', 'label': 'Menu item 2 ', 'group': null, 'selected': false }
];

//use bind:value, with a var bind the data of the selected item
var selectedItem;
```
```html
<SelectMenu bind:menuItems={menuItemArray} bind:value={selectedItem}/>
<SelectMenu bind:menuItems={menuItemArray} bind:value={selectedItem} showGroupLabels/>
<SelectMenu bind:menuItems={menuItemArray} bind:value={selectedItem} iconName={IconBlend}/>
<SelectMenu bind:menuItems={menuItemArray} bind:value={selectedItem} disabled/>
```
**Props**

| Prop              | Type    | Options/notes                                                                                                                            |
|-------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------|
| `on:change`       | Func    | Function to execute on change. Ex: `on:change={funcName}`                                                                                |
| `menuItems`       | Var     | Pass in array of menu item objects. See example above for format.  If you want to use option groups, update the group keys to a string.  |
| `value`           | Var     | Bind the value of the selected item to a var. Ex: `bind:value={selectedItem}`                                                       |
| `placeholder`     | String  | Override default placeholder text with a string when there is no item selected.                                                          |
| `showGroupLabels` | Boolean | Default: `false`; If you are using option groups, this will show the group labels.                                                       |
| `disabled`        | Boolean | Default: `false`                                                                                                                         |
| `macOSBlink`      | Boolean | Default: `false`; Easter egg, old school Mac OS triple blink on select.                                                                  |
| `iconName`        | Var     | _See Icon component for usage._                                                                                                          |
| `iconText`        | String  | _See Icon component for usage._                                                                                                          |

---

### Switch
```javascript
import { Switch } from 'figma-plugin-ds-svelte';

//use bind:group, with a var to create a radio group and store the value of selected item
//set value if this var to same value as radio item to set initial selection
var switchValue;
```
```html
<Switch value="value" bind:checked={switchValue}>Label</Switch>
```
**Props**

| Prop       | Type    | Options/notes                                                                            |
|:-----------|:--------|:-----------------------------------------------------------------------------------------|
| `on:change`| Func    | Funtion to execute on change. Ex: `on:change={funcName}`                                 |
| `value`    | Boolean | Default: `false`;                                                                        |
| `checked`  | Boolean | Default: `false`; You can bind the value when checked to a var. `bind:checked={varName}` |
| `disabled` | Boolean | Default: `false`                                                                         |

---

### Textarea
```javascript
import { Textarea } from 'figma-plugin-ds-svelte';
```
```html
<Textarea placeholder="Enter some text"></Textarea>
```
**Props**

| Prop          | Type    | Options/notes                                                         |
|:--------------|:--------|:----------------------------------------------------------------------|
| `on:change`   | Func    | Function to execute on change. Ex: `on:change={funcName}`             |
| `value`       | String  | Value of textarea. Can bind to a variable. Ex: `bind:value={someVar}` |
| `placeholder` | String  | Override default placeholder text with a string.                      |
| `rows`        | Int     | Default: `2`; Number of rows (height) to display.                     |
| `disabled`    | Boolean | Default: `false`                                                      |

---

### Type
```javascript
import { Type } from 'figma-plugin-ds-svelte';
```
```html
<Type size="large" weight="bold">Content here</Type>
```
**Props**

| Prop      | Type    | Options/notes                                                                          |
|:----------|:--------|:---------------------------------------------------------------------------------------|
| `size`    | String  | Default: `"small"`; Also accepts `"xsmall"`,`"large"`, `"xlarge"`                      |
| `weight`  | String  | Default: `"normal"`; Also accepts `"medium"`,`"bold"`                                  |
| `color`   | String  | Default: `"black8"`; Pass the name of any Figma color var to this prop. `color="blue"`, Default color is white when inverse is `true` and no value specified |
| `inverse` | Boolean | Default: `false`; Optimizes letter-spacing for light on dark applications.             |

---

## Tokens

**Color**

| Name          | Var               | Type             | Notes                                                         |
|:--------------|:------------------|:-----------------|:--------------------------------------------------------------|
| blue          | `--blue`          | Accent           | Ex: primary button, hyperlinks, focus/selected states         |
| purple        | `--purple`        | Accent           | Ex: components/instances                                      |
| hot-pink      | `--hot-pink`      | Accent           | Ex: smart selection handles                                   |
| green         | `--green`         | Accent           | Ex: Toolbar selections                                        |
| red           | `--red`           | Accent           | Ex: Error                                                     |
| yellow        | `--yellow`        | Accent           | Ex: Caution/warning                                           |
| black         | `--black`         | Basic foreground | Ex: active states                                             |
| black8        | `--black8`        | Basic foreground | 80% black, ex: most common black used in UI text and icons    |
| black8-opaque | `--black8-opaque` | Basic foreground | Opaque version of black8                                      |
| black3        | `--black3`        | Basic foreground | 30% black, ex: lower priority messages, disabled states       |
| black3-opaque | `--black3-opaque` | Basic foreground | Opaque version of black3                                      |
| white         | `--white`         | Basic foreground | Used in same way as black8, but on dark backgrounds           |
| white8        | `--white8`        | Basic foreground | Rarely used, only in toolbar                                  |
| white4        | `--white4`        | Basic foreground | Used in same way as black3, Ex: option group headers in menus |
| white         | `--white`         | Basic background | (Duplicate) White is also the most common background color    |
| grey          | `--grey`          | Basic background | Used behind controls in active state                          |
| silver        | `--silver`        | Basic background | Ex: horizontal separators, default canvas background          |
| hud           | `--hud`           | Basic background | Ex: background for menus                                      |
| toolbar       | `--toolbar`       | Basic background | Ex: background for the toolbar                                |
| black1        | `--black1`        | Special          | Ex: input placeholder underline, textarea border              |
| blue3         | `--blue3`         | Special          | Ex: text range selection in inputs                            |
| purple4       | `--purple4`       | Special          | Ex: disabled components/instances                             |
| hover-fill    | `--hover-fill`    | Special          | Hover state for items without borders, ex: icon button        |
| selection-a   | `--selection-a`   | Special          | Selected cells, ex: selected top level layer                  |
| selection-b   | `--selection-b`   | Special          | Selected cells, ex: selected child layers                     |
| white2        | `--white2`        | Special          | Ex: menu separators                                           |


**Type**

| Property         | Var                                | Value               | Notes                                                        |
|:-----------------|:-----------------------------------|:--------------------|:-------------------------------------------------------------|
| `font-family`    | `--font-stack`                     | 'Inter', sans-serif | Default font everywhere                                      |
| `font-size`      | `--font-size-xsmall`               | 11px                | Most common font size                                        |
| `font-size`      | `--font-size-small`                | 12px                | Used in menus                                                |
| `font-size`      | `--font-size-large`                | 13px                | Rarely used in editor                                        |
| `font-size`      | `--font-size-xlarge`               | 14px                | Rarely used in editor                                        |
| `font-weight`    | `--font-weight-normal`             | 400                 |                                                              |
| `font-weight`    | `--font-weight-medium`             | 500                 |                                                              |
| `font-weight`    | `--font-weight-bold`               | 600                 |                                                              |
| `line-height`    | `--font-line-height`               | 16px                | For use with xsmall and small font sizes                     |
| `line-height`    | `--font-line-height-large`         | 24px                | For use with large and xlarge font sizes                     |
| `letter-spacing` | `--font-letter-spacing-pos-xsmall` | .005em              | Optimized letter spacing for xsmall text on light background |
| `letter-spacing` | `--font-letter-spacing-neg-xsmall` | .01em               | Optimized letter spacing for xsmall text on dark background  |
| `letter-spacing` | `--font-letter-spacing-pos-small`  | 0                   | Optimized letter spacing for small text on light background  |
| `letter-spacing` | `--font-letter-spacing-neg-small`  | .005em              | Optimized letter spacing for small text on dark background   |
| `letter-spacing` | `--font-letter-spacing-pos-large`  | -.0025em            | Optimized letter spacing for large text on light background  |
| `letter-spacing` | `--font-letter-spacing-neg-large`  | .0025em             | Optimized letter spacing for large text on dark background   |
| `letter-spacing` | `--font-letter-spacing-pos-xlarge` | -.001em             | Optimized letter spacing for xlarge text on light background |
| `letter-spacing` | `--font-letter-spacing-neg-xlarge` | -.001em             | Optimized letter spacing for xlarge text on dark background  |

**Border Radius**

| Var                     | Value | Notes                                 |
|:------------------------|:------|:--------------------------------------|
| `--border-radius-small` | 2px   | Ex: menus, input borders, icon button |
| `--border-radius-med`   | 5px   | Ex: visual bell, toasts               |
| `--border-radius-large` | 6px   | Ex: buttons                           |

**Shadows**

| Var                         | Notes                       |
|:----------------------------|:----------------------------|
| `--shadow-hud`              | Ex: menus, tooltips, toasts |
| `--shadow-floating-window:` | Ex: modal, dialog           |

**Sizes**

| Var               | Value |
|:------------------|:------|
| `--size-xxxsmall` | 4px   |
| `--size-xxsmall`  | 8px   |
| `--size-xsmall`   | 16px  |
| `--size-small`    | 24px  |
| `--size-medium`   | 32px  |
| `--size-large`    | 40px  |
| `--size-xlarge`   | 48px  |
| `--size-xxlarge`  | 64px  |
| `--size-huge`     | 80px  |


================================================
FILE: package.json
================================================
{
  "name": "figma-plugin-ds-svelte",
  "version": "1.3.8",
  "description": "A collection of Svelte components that match the Figma UI for building plugins.",
  "svelte": "./src/index.js",
  "dependencies": {
    "svelte-click-outside": "^1.0.0"
  },
  "devDependencies": {
    "npm-run-all": "^4.1.5",
    "rollup": "^1.32.1",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-livereload": "^1.1.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-postcss": "^2.9.0",
    "rollup-plugin-serve": "^1.0.1",
    "rollup-plugin-svelte": "^5.1.1",
    "rollup-plugin-svg": "^2.0.0",
    "svelte": "^3.20.1"
  },
  "scripts": {
    "build": "rollup -c",
    "autobuild": "rollup -c -w",
    "dev": "rollup -c -w",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/thomas-lowry/figma-plugin-ds-svelte.git"
  },
  "keywords": [
    "figma",
    "plugin",
    "ds",
    "design",
    "system",
    "ui",
    "svelte",
    "components"
  ],
  "files": [
    "src"
  ],
  "author": "Thomas Lowry",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/thomas-lowry/figma-plugin-ds-svelte/issues"
  },
  "homepage": "https://github.com/thomas-lowry/figma-plugin-ds-svelte#readme",
  "main": "./src/index.js"
}


================================================
FILE: public/index.html
================================================
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf8" />
        <meta name="viewport" content="width=device-width" />

        <title>Figma Plugin DS Svelte components</title>

    </head>

    <body>
        <script src="components.js"></script>
    </body>
</html>


================================================
FILE: rollup.config.js
================================================
import svelte from 'rollup-plugin-svelte';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
import svg from 'rollup-plugin-svg';
import postcss from 'rollup-plugin-postcss';

const production = !process.env.ROLLUP_WATCH

export default {
    input: 'src/test.js',
    output: {
        file: `public/components.js`,
        format: 'iife',
        name: 'components',
    },
    plugins: [
        svelte({
            include: ['src/**/*.svelte', 'node_modules/**/src/*.svelte'],
            dev: true,
        }),
        resolve(),
        commonjs(),
        svg(),
        postcss({
            plugins: []
        }),
        !production && serve('public'),
        !production && livereload('public'),
    ],
    watch: {
		clearScreen: false
	}
}

================================================
FILE: src/App.svelte
================================================
<script>
    //This is a simple app playground to test components and their markup

    // Global CSS
    import style from './global.css';

    //Components
    import Button from './components/Button/index.svelte';
    import Checkbox from './components/Checkbox/index.svelte';
    import Switch from './components/Switch/index.svelte';
    import Disclosure from './components/Disclosure/index.svelte';
    import DisclosureItem from './components/DisclosureItem/index.svelte';
    import Icon from './components/Icon/index.svelte';
    import IconButton from './components/IconButton/index.svelte';
    import Input from './components/Input/index.svelte';
    import Label from './components/Label/index.svelte';
    import OnboardingTip from './components/OnboardingTip/index.svelte';
    import Radio from './components/Radio/index.svelte';
    import Section from './components/Section/index.svelte';
    import SelectMenu from './components/SelectMenu/index.svelte';
    import Textarea from './components/Textarea/index.svelte';
    import Type from './components/Type/index.svelte';

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

    //var to store the selected value of our radio button group
    var radioValue = 'a';

    //Arrays for select menu
    //example without a selected item
    let menuItemsExample0;

    //this function dynamically updates the first empty select menu example with data
    function populateMenu() {
        menuItemsExample0 = [
            { 'value': 'item1', 'label': 'Menu item 1', 'group': null, 'selected': true },
            { 'value': 'item2', 'label': 'Menu item 2 ', 'group': null, 'selected': false },
        ]
    }

    let menuItemsExample1 = [
        { 'value': 'item1', 'label': 'Menu item 1', 'group': null, 'selected': false },
        { 'value': 'item2', 'label': 'Menu item 2 ', 'group': null, 'selected': false },
        { 'value': 'item3', 'label': 'Menu item 3', 'group': null, 'selected': false },
        { 'value': 'item4', 'label': 'Menu item 4', 'group': null, 'selected': false }
    ];
    //example with an initial selection
    let menuItemsExample2 = [
        { 'value': 'item1', 'label': 'Menu item 1', 'group': null, 'selected': false },
        { 'value': 'item2', 'label': 'Menu item 2 ', 'group': null, 'selected': true },
        { 'value': 'item3', 'label': 'Menu item 3', 'group': null, 'selected': false },
        { 'value': 'item4', 'label': 'Menu item 4', 'group': null, 'selected': false }
    ];
    //example with option groups (we will show the labels with a prop)
    let menuItemsExample3 = [
        { 'value': 'item1', 'label': 'Granny Smith', 'group': 'Apples', 'selected': false },
        { 'value': 'item2', 'label': 'Honey Crisp ', 'group': 'Apples', 'selected': true },
        { 'value': 'item3', 'label': 'Blood', 'group': 'Oranges', 'selected': false },
        { 'value': 'item4', 'label': 'Valencia', 'group': 'Oranges', 'selected': false }
    ];
    //example with an initial selection and option groups 
    let menuItemsExample4 = [
        { 'value': 'item1', 'label': 'Passthrough', 'group': 'group1', 'selected': true },
        { 'value': 'item2', 'label': 'Normal ', 'group': 'group1', 'selected': false },
        { 'value': 'item3', 'label': 'Darken', 'group': 'group2', 'selected': false },
        { 'value': 'item4', 'label': 'Multiply', 'group': 'group2', 'selected': false },
        { 'value': 'item4', 'label': 'Color Burn', 'group': 'group2', 'selected': false }
    ];
    


</script>


<div class="wrapper" style="background-color: var(--figma-color-bg)">

<h1>Figma Plugin UI Svelte</h1>

    <section>
        <h2>Buttons</h2>

        <div class="mb-xsmall">
            <h3>Primary</h3>
            <div class="flex row">
                <Button class="mr-xxsmall">Label</Button>
                <Button disabled class="mr-xxsmall">Label</Button>
                <Button destructive class="mr-xxsmall">Label</Button>
                <Button destructive disabled>Label</Button>
            </div>
        </div>

        <div class="mb-xsmall">
            <h3>Secondary</h3>
            <div class="flex row">
                <Button variant="secondary" class="mr-xxsmall">Label</Button>
                <Button variant="secondary" disabled class="mr-xxsmall">Label</Button>
                <Button variant="secondary" destructive class="mr-xxsmall">Label</Button>
                <Button variant="secondary" destructive disabled class="mr-xxsmall">Label</Button>
            </div>
        </div>

        <div>
            <h3>Teritary</h3>
            <div class="flex row">
                <Button variant="tertiary" class="mr-xxsmall">Label</Button>
                <Button variant="tertiary" disabled class="mr-xxsmall">Label</Button>
                <Button variant="tertiary" destructive class="mr-xxsmall">Label</Button>
                <Button variant="tertiary" destructive disabled class="mr-xxsmall">Label</Button>
            </div>
        </div>

    </section>

    <section>
        <h2>Checkboxes</h2>
        <Checkbox>Label</Checkbox>
        <Checkbox checked>Label</Checkbox>
        <Checkbox disabled>Label</Checkbox>
        <Checkbox checked disabled>Label</Checkbox>
    </section>

    <section>
        <h2>Switches</h2>
        <Switch>Label</Switch>
        <Switch checked>Label</Switch>
        <Switch disabled>Label</Switch>
        <Switch checked disabled>Label</Switch>
    </section>

    <section>
        <h2>Radio buttons</h2>
        <Radio bind:group={radioValue} value="a">Label Label with really long text content Label with really really really really long text content Label with really long text content Label with really long text content</Radio>
        <Radio bind:group={radioValue} value="b">Label</Radio>
        <Radio bind:group={radioValue} value="c" disabled>Label</Radio>

    </section>

    <section>
        <h2>Disclosure panels</h2>
        <Disclosure>
            <DisclosureItem title="Item 1" open>Content here</DisclosureItem>
            <DisclosureItem title="Item 2">Content here</DisclosureItem>
            <DisclosureItem title="Item 3">Content here</DisclosureItem>
        </Disclosure>
    </section>

    <section>
        <h2>Icon</h2>
        <h3>Icons and props</h3>
        <caption class="mb-xsmall">You can import and pass an SVG string to the iconName prop, or you can display text inside an icon by passing a string including a character to the iconText prop. You can pass the name of any color from the Figma DS to the color prop (ex: color="red", color="purple4"). Icons can also accept the spin prop. The IconButton, Input, and OnboardingTip all make use of the Icon component and can accept its props.</caption>
        <div class="flex row mb-xsmall">
            <Icon iconName={IconVisible} color="black"/>
            <Icon iconName={IconVisible} color="black8"/>
            <Icon iconName={IconVisible} color="black3"/>
            <Icon iconName={IconVisible} color="blue"/>
            <Icon iconName={IconVisible} color="purple"/>
            <Icon iconName={IconVisible} color="yellow"/>
            <Icon iconName={IconVisible} color="red"/>
            <Icon iconName={IconVisible} color="green"/>
            <Icon iconText="W"/>
            <Icon iconText="H" color="black3"/>
            <Icon iconText="#" color="blue"/>
            <Icon iconText="@" color="red"/>
            <Icon iconText="→" color="blue" spin/>
            <Icon iconName={IconSpinner} spin/>
        </div>
        <h3>Icons</h3>
        <div class="flex row flex-wrap">
            <Icon iconName={IconAdjust}/>
            <Icon iconName={IconAlert}/>
            <Icon iconName={IconAngle}/>
            <Icon iconName={IconArrowLeftRight}/>
            <Icon iconName={IconUpDown}/>
            <Icon iconName={IconAutoLayoutHorizontal}/>
            <Icon iconName={IconAutoLayoutVertical}/>
            <Icon iconName={IconBack}/>
            <Icon iconName={IconBlendEmpty}/>
            <Icon iconName={IconBlend}/>
            <Icon iconName={IconBreak}/>
            <Icon iconName={IconCaretDown}/>
            <Icon iconName={IconCaretLeft}/>
            <Icon iconName={IconCaretRight}/>
            <Icon iconName={IconCaretUp}/>
            <Icon iconName={IconCheck}/>
            <Icon iconName={IconClose}/>
            <Icon iconName={IconComponent}/>
            <Icon iconName={IconCornerRadius}/>
            <Icon iconName={IconCorners}/>
            <Icon iconName={IconDistributeHorizontalSpacing}/>
            <Icon iconName={IconDistributeVerticalSpacing}/>
            <Icon iconName={IconDraft}/>
            <Icon iconName={IconEffects}/>
            <Icon iconName={IconEllipses}/>
            <Icon iconName={IconEyedropper}/>
            <Icon iconName={IconForward}/>
            <Icon iconName={IconFrame}/>
            <Icon iconName={IconGroup}/>
            <Icon iconName={IconHidden}/>
            <Icon iconName={IconHorizontalPadding}/>
            <Icon iconName={IconHyperlink}/>
            <Icon iconName={IconImage}/>
            <Icon iconName={IconInstance}/>
            <Icon iconName={IconKey}/>
            <Icon iconName={IconLayoutAlignBottom}/>
            <Icon iconName={IconAlignHorizontalCenters}/>
            <Icon iconName={IconAlignLeft}/>
            <Icon iconName={IconAlignRight}/>
            <Icon iconName={IconAlignTop}/>
            <Icon iconName={IconAlignVerticalCenters}/>
            <Icon iconName={IconLayoutGridColumns}/>
            <Icon iconName={IconLayoutGridRows}/>
            <Icon iconName={IconLayoutGridUniform}/>
            <Icon iconName={IconLibrary}/>
            <Icon iconName={IconLinkBroken}/>
            <Icon iconName={IconLinkConnected}/>
            <Icon iconName={IconListDetailed}/>
            <Icon iconName={IconListTile}/>
            <Icon iconName={IconList}/>
            <Icon iconName={IconLockOff}/>
            <Icon iconName={IconLockOn}/>
            <Icon iconName={IconMinus}/>
            <Icon iconName={IconPlay}/>
            <Icon iconName={IconPlus}/>
            <Icon iconName={IconRandom}/>
            <Icon iconName={IconRecent}/>
            <Icon iconName={IconResizeToFit}/>
            <Icon iconName={IconResolveFilled}/>
            <Icon iconName={IconResolve}/>
            <Icon iconName={IconReverse}/>
            <Icon iconName={IconSearchLarge}/>
            <Icon iconName={IconSearch}/>
            <Icon iconName={IconSettings}/>
            <Icon iconName={IconShare}/>
            <Icon iconName={IconSmiley}/>
            <Icon iconName={IconSortAlphaAsc}/>
            <Icon iconName={IconSortAlphaDsc}/>
            <Icon iconName={IconSortTopBottom}/>
            <Icon iconName={IconSpacing}/>
            <Icon iconName={IconSpinner}/>
            <Icon iconName={IconStarOff}/>
            <Icon iconName={IconStarOn}/>
            <Icon iconName={IconStrokeWeight}/>
            <Icon iconName={IconStyles}/>
            <Icon iconName={IconSwap}/>
            <Icon iconName={IconTheme}/>
            <Icon iconName={IconTidyUpGrid}/>
            <Icon iconName={IconTidyUpListHorizontal}/>
            <Icon iconName={IconTidyUpListVertical}/>
            <Icon iconName={IconTimer}/>
            <Icon iconName={IconTrash}/>
            <Icon iconName={IconVerticalPadding}/>
            <Icon iconName={IconVisible}/>
            <Icon iconName={IconWarningLarge}/>
            <Icon iconName={IconWarning}/>
        </div>
    </section>

    <section>
        <h2>Icon Button</h2>
        <div class="flex row">
            <IconButton iconName={IconVisible} class="mr-xxsmall"/>
            <IconButton iconName={IconVisible} selected class="mr-xxsmall"/>
            <IconButton iconText="@"/>
        </div>
    </section>

    <section>
        <h2>Input</h2>
        <Input placeholder="This is an example with a placeholder" class="mb-xsmall"/>
        <Input value="This is an example with a value" class="mb-xsmall"/>
        <Input value="This is an example with a value but also disabled" disabled class="mb-xsmall"/>
        <Input value="This is an example with a forced border" borders class="mb-xsmall"/>
        <Input value="This is an invalid example" class="mb-xsmall" invalid=true/>
        <Input iconName={IconVisible} value="This is an example with a value and an icon" class="mb-xsmall"/>
        <Input iconText="W" value="This is an example with a value and a text icon, for example a width input"/>
    </section>

    <section>
        <h2>Labels and sections</h2>
        <Label>Label goes here</Label>
        <Section>Section header goes here</Section>
    </section>

    <section>
        <h2>Onboarding Tip</h2>
        <OnboardingTip iconName={IconStyles}>To create a style, select a layer and click on the style icon in the inspector panel</OnboardingTip>
    </section>

    <section>
        <h2>Select Menu</h2>
        <div class="flex row">
        <SelectMenu bind:menuItems={menuItemsExample0} class="mb-xsmall"/>
        <Button variant="secondary" class="mr-xxsmall mb-xsmall" on:click={populateMenu}>Populate menu</Button>
        </div>

        <SelectMenu placeholder="Please make a selection" bind:menuItems={menuItemsExample1} class="mb-xsmall"/>
        <SelectMenu bind:menuItems={menuItemsExample2} class="mb-xsmall"/>
        <SelectMenu bind:menuItems={menuItemsExample3} showGroupLabels class="mb-xsmall"/>
        <SelectMenu bind:menuItems={menuItemsExample4} iconName={IconBlend}/>
    </section>

    <section>
        <h2>Textarea</h2>
        <Textarea placeholder="Enter some text" class="mb-xsmall" />
        <Textarea class="mb-xsmall" value="Initial value" />
        <Textarea value="Text area with a value that is disabled" disabled />
    </section>

    <section>
        <h2>Type</h2>
        <div class="flex row">
            <div class="p-xsmall mr-xxsmall" style="border: 1px solid var(--black1)">
                <div class="mb-xxsmall">
                    <Type>UI11 &mdash; size: xsmall, weight: normal, inverse: false</Type>
                    <Type size="small">UI12 &mdash; size: small, weight: normal, inverse: false</Type>
                    <Type size="large">UI13 &mdash; size: large, weight: normal, inverse: false</Type>
                    <Type size="xlarge">UI14 &mdash; size: xlarge, weight: normal, inverse: false</Type>
                </div>

                <div class="mb-xxsmall">
                    <Type weight="medium">UI1 &mdash; size: xsmall, weight: medium, inverse: false</Type>
                    <Type size="small" weight="medium">UI2 &mdash; size: small, weight: medium, inverse: false</Type>
                    <Type size="large" weight="medium">UI3 &mdash; size: large, weight: medium, inverse: false</Type>
                    <Type size="xlarge" weight="medium">UI4 &mdash; size: xlarge, weight: medium, inverse: false</Type>
                </div>

                <Type weight="bold">UI1 &mdash; size: xsmall, weight: bold, inverse: false</Type>
                <Type size="small" weight="bold">UI2 &mdash; size: small, weight: bold, inverse: false</Type>
                <Type size="large" weight="bold">UI3 &mdash; size: large, weight: bold, inverse: false</Type>
                <Type size="xlarge" weight="bold">UI4 &mdash; size: xlarge, weight: bold, inverse: false</Type>
            </div>

            <div class="p-xsmall" style="background-color: var(--black)">
                <div class="mb-xxsmall">
                    <Type inverse>UI1 &mdash; size: xsmall, weight: normal, inverse: true</Type>
                    <Type size="small" inverse>UI2 &mdash; size: small, weight: normal, inverse: true</Type>
                    <Type size="large" inverse>UI3 &mdash; size: large, weight: normal, inverse: true</Type>
                    <Type size="xlarge" inverse>UI4 &mdash; size: xlarge, weight: normal, inverse: true</Type>
                </div>

                <div class="mb-xxsmall">
                    <Type weight="medium" inverse>UI1 &mdash; size: xsmall, weight: medium, inverse: true</Type>
                    <Type size="small" weight="medium" inverse>UI2 &mdash; size: small, weight: medium, inverse: true</Type>
                    <Type size="large" weight="medium" inverse>UI3 &mdash; size: large, weight: medium, inverse: true</Type>
                    <Type size="xlarge" weight="medium" inverse>UI4 &mdash; size: xlarge, weight: medium, inverse: true</Type>
                </div>

                <Type weight="bold" inverse>UI1 &mdash; size: xsmall, weight: bold, inverse: true</Type>
                <Type size="small" weight="bold" inverse>UI2 &mdash; size: small, weight: bold, inverse: true</Type>
                <Type size="large" weight="bold" inverse>UI3 &mdash; size: large, weight: bold, inverse: true</Type>
                <Type size="xlarge" weight="bold" inverse>UI4 &mdash; size: xlarge, weight: bold, inverse: true</Type>
            </div>
        </div>
    </section>

</div>


<style>

    .wrapper {
        padding: 24px;
    }

    h1 {
        font-size: 24px;
        padding: 0;
        margin: 0 0 24px 0;
    }

    h2 {
        font-size: 16px;
        padding: 0;
        margin: 0 0 16px 0;
    }

    h3 {
        font-weight: normal;
        font-size: 12px;
        padding: 0;
        margin: 0 0 8px 0;
    }

    caption {
        font-size: 11px;
        color: var(--black3);
        display: block;
        text-align: left;
    }
    
    section {
        border-bottom: 1px solid var(--black);
        padding-bottom: var(--size-medium);
        margin-bottom: var(--size-medium);
    }
    section:last-child {
        border-bottom: 1px solid transparent;
        margin-bottom: 0px;
    }

</style>

================================================
FILE: src/components/Button/index.svelte
================================================
<script>
    import { onMount } from 'svelte';

    export let variant = 'primary';
    export let disabled = false;
    export let destructive = false;
    export { className as class };

    let className = '';

</script>

<button
    on:click
    on:submit|preventDefault
    onclick="this.blur();"
    {variant}
    {disabled}
    class:destructive={destructive}
    class="{variant} {className}">
        <slot />
</button>

<style>

    button {
        display: flex;
        align-items: center;
        border-radius: var(--border-radius-large);
        color: var(--figma-color-text-onbrand);
        flex-shrink: 0;
        font-family: var(--font-stack);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-medium);
        letter-spacing: var(--font-letter-spacing-neg-small);
        line-height: var(--font-line-height);
        height: var(--size-medium);
        padding: 0 var(--size-xsmall) 0 var(--size-xsmall);
        text-decoration: none;
        outline: none;
        border: 2px solid transparent;
        user-select: none;
    }

    /* Primary styles */
    .primary {
        background-color: var(--figma-color-bg-brand);
        color: var(--figma-color-text-onbrand);
    }
    .primary:enabled:active, .primary:enabled:focus {
        border: 2px solid var(--figma-color-border-brand-strong);
    }
    .primary:disabled {
        background-color: var(--figma-color-bg-disabled);
    }
    .primary.destructive {
        background-color: var(--figma-color-bg-danger);
    }
    .primary.destructive:active, .primary.destructive:focus {
        border: 2px solid var(--figma-color-border-disabled-strong);
    }
    .primary.destructive:disabled  {
        background-color: var(--figma-color-bg-disabled);
    }

    /* Secondary styles */
    .secondary {
        background-color: transparent;
        border: 1px solid var(--figma-color-border-strong);
        color: var(--figma-color-text);
        padding: 0 calc(var(--size-xsmall) + 1px) 0 calc(var(--size-xsmall) + 1px);
        letter-spacing: var(--font-letter-spacing-pos-small);
    }
    .secondary:enabled:active, .secondary:enabled:focus {
        border: 2px solid var(--figma-color-border-selected);
        padding: 0 var(--size-xsmall) 0 var(--size-xsmall);
    }
    .secondary:disabled {
        border: 1px solid var(--figma-color-border-disabled-strong);
        color: var(--figma-color-text-disabled);
    }
    .secondary.destructive {
       /* this should be deprecated */ 
       border-color: var(--figma-color-border-danger-strong);
       color: var(--figma-color-text-danger);
    }
    .secondary.destructive:enabled:active, .secondary.destructive:enabled:focus {
       border: 2px solid var(--figma-color-border-danger-strong);
        padding: 0 var(--size-xsmall) 0 var(--size-xsmall);
    }
    .secondary.destructive:disabled {
        opacity: 0.4;
    }

    /* tertiary styles */
    .tertiary {
        border: 1px solid transparent;
        color: var(--figma-color-text-brand);
        background: initial;
        padding: 0;
        font-weight: var(--font-weight-normal);
        letter-spacing: var(--font-letter-spacing-pos-small);
        cursor: pointer;
    }
    .tertiary:enabled:focus {
        text-decoration: underline;
    }
    .tertiary:disabled {
        color: var(--figma-color-text-disabled);
    }
    .tertiary.destructive {
       color: var(--figma-color-text-danger);
    }
    .tertiary.destructive:enabled:focus {
        text-decoration: underline;
    }
    .tertiary.destructive:disabled {
       opacity: 0.4;
    }

</style>


================================================
FILE: src/components/Checkbox/index.svelte
================================================
<script>

    export let checked = false;
    export let value = '';
    export let disabled = false;
    export let tabindex = 0;
    export { className as class };

    let uniqueId = 'checkbox--' + ((Math.random() * 10000000).toFixed(0)).toString();
    let className = '';
    
</script>

<div class={className}>
    <input 
        type="checkbox"
        id={uniqueId}
        bind:checked={checked}
        bind:value={value}
        {disabled} 
        {tabindex}
        onclick="this.blur();"
        on:change
        on:focus
        on:blur>
    <label for={uniqueId}>
        <slot />
    </label>
</div>	

<style>

    div {
        align-items: center;
        cursor: default;
        display: flex;
        position: relative;
    }

    input {
        opacity: 0;
        width: 10px;
        height: 10px;
        margin: 0;
        padding: 0;
        flex-shrink: 0;
    }
    input:checked + label:before {
        border: 1px solid var(--figma-color-bg-brand);
        background-color: var(--figma-color-bg-brand);
        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');
        background-repeat: no-repeat;
        background-position: 1px 2px;
    }
    input:disabled + label {
        color: var(--figma-color-text-disabled);
    }

    input:checked:disabled + label:before {
        border: 1px solid transparent;
		background-color: var(--figma-color-icon-disabled);
    }

    label {
        color: var(--figma-color-text);
        display: flex;
        font-family: var(--font-stack);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        line-height: var(--font-line-height);
        letter-spacing: var(--font-letter-spacing-pos-xsmall);
        margin-left: -16px;
        padding: var(--size-xxsmall) var(--size-xsmall) var(--size-xxsmall) var(--size-small);
        user-select: none;
    }
    label:before {
        border: 1px solid var(--figma-color-icon);
		border-radius: var(--border-radius-small);
        content: '';
        display: block;
        width: 10px;
        height: 10px;
        margin: 2px 10px 0 -8px;
        flex-shrink: 0;
    }

    input:enabled:checked:focus + label:before {
        border: 1px solid var(--figma-color-bg);
        box-shadow: 0 0 0 2px var(--figma-color-border-brand-strong);
        border-radius: var(--border-radius-small);
    }

    input:enabled:focus + label:before {
        border: 1px solid var(--figma-color-border-brand-strong);
        box-shadow: 0 0 0 1px var(--figma-color-border-brand-strong);
    }

</style>

================================================
FILE: src/components/Disclosure/index.svelte
================================================
<script>

    import { createEventDispatcher, setContext, onMount } from 'svelte';
    import { writable } from 'svelte/store';
    import DisclosureItem, { disclosure } from "./../DisclosureItem/index.svelte";
    
    const dispatch = createEventDispatcher();
    const selected = writable(null);
    let className = '';
    let disclosureWrapper;

    const clickHandler = function(itemId) {
        let currentVal = getValue(selected);
        if (currentVal != itemId) {
            selected.set(itemId);
            dispatch("change", itemId);
        } else {
            selected.set(null);
            dispatch("change", null);
        }
    };

    setContext(disclosure, { clickHandler, selected});

    function getValue(store) {
        let $val;
        store.subscribe($ => $val = $)()
        return $val
    }

</script>

<ul class={className} bind:this={disclosureWrapper}>
    <slot></slot>
</ul>

<style>

    ul {
        position: relative;
        width: 100%;
        margin: 0;
        padding: 0;
        list-style-type: none;
    }

</style>

================================================
FILE: src/components/DisclosureItem/index.svelte
================================================
<script context="module">
    export const disclosure = {};
</script>

<script>

    import { getContext, onMount } from 'svelte';
    import Icon from './../Icon/index.svelte';
    import CaretRight from './../../icons/caret-right.svg';
    import CaretDown from './../../icons/caret-down.svg';

    export let uniqueId = 'disclosureItem--' + ((Math.random() * 10000000).toFixed(0)).toString();
    export let title = null;
    export let expanded = false;
    export let section = false;
    export let open = false;

    const { clickHandler, selected } = getContext(disclosure);

    $: expanded = $selected === uniqueId;
    
    if (open) {
        selected.set(uniqueId);
    }

</script>

<li {open} {title} id={uniqueId} class:expanded={expanded}>
    <div on:click={clickHandler.bind(null, uniqueId)} class="header" class:section={section}>
        <div class="icon">
            {#if expanded}
                <Icon iconName={CaretDown} color="black" />
            {:else}
                <Icon iconName={CaretRight} color="black" />
            {/if}
        </div>
        <div class="title">{title}</div>
    </div>
    <div class="content">
        <slot />
    </div>
</li>

<style>

    li {
        display: flex;
        flex-direction: column;
        position: relative;
        width: 100%;
        margin: 0;
        padding: 0;
        list-style-type: none;
        border-bottom: 1px solid var(--figma-color-border);
    }
    li:last-child {
        border-bottom: 1px solid transparent;
    }

    .header {
        display: flex;
        align-items: center;
        height: var(--size-medium);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-pos-xsmall);
        line-height: var(--line-height);
        color: var(--figma-color-text);
    }
    .header:hover .icon {
        opacity: 0.9;
    }

    .title {
        margin-left: -4px;
        user-select: none;
    }

    .icon {
        margin-left: -4px;
        opacity: 0.3;
    }
    .expanded .icon {
        opacity: 0.8;
    }

    .section {
        font-weight: var(--font-weight-bold);
    }

    .content {
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-pos-xsmall);
        line-height: var(--line-height);
        color: var(--figma-color-text);
        padding: var(--size-xxsmall) var(--size-xxsmall) var(--size-xxsmall) var(--size-small);
        display: none;
        user-select: none;
        pointer-events: none;
    }
    
    .expanded .content {
        display: block;
    }

</style>

================================================
FILE: src/components/Icon/index.svelte
================================================
<script>
    export let iconName = null; //pass svg data into this var by importing an svg in parent
    export let spin = false;
    export let iconText = null;
    export let color = '--figma-color-icon';
    export { className as class };

    let className = '';

</script>

<div 
    class:spin={spin}
    {iconText}
    {iconName} 
    class="icon-component {className}"
    style="color: var({color}); fill: var({color})"
    on:click>
    {#if iconText}
        {iconText}
    {:else}
        {@html iconName}
    {/if}
</div>

<style>

    .icon-component {
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: default;
        width: var(--size-medium);
        height: var(--size-medium);
        font-family: var(--font-stack);
        font-size: var(--font-size-xsmall);
        user-select: none;
    }

    .spin {
        animation: rotating 1.0s linear infinite;
    }

    @keyframes rotating {
        from {
            transform: rotate(0deg);
        }
        to {
            transform: rotate(360deg);
        }
    }

    :global(.icon-component *) {
        fill: inherit;
        color: inherit;
    }

</style>

================================================
FILE: src/components/IconButton/index.svelte
================================================
<script>
    import Icon from './../Icon/index.svelte';

    export let iconName = '';
    export let iconText = null;
    export let selected = false;
    export let spin = false;
    export let tabindex = 0;
    export { className as class };

    let className = '';

</script>

<div on:click onclick="this.blur();" class:selected={selected} class="{className}" tabindex={tabindex}>
    {#if selected === true}
        <Icon {iconName} {iconText} {spin} color="--figma-color-icon-onbrand"/>
    {:else}
        <Icon {iconName} {iconText} {spin} color="--figma-color-icon"/>
    {/if}
</div>

<style>

    div {
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        width: var(--size-medium);
        height: var(--size-medium);
        border-radius: var(--border-radius-small);
        border: 2px solid transparent;
    }
    div:hover {
        background: var(--figma-color-bg-hover);
    }
    div:active, div:focus {
        border: 2px solid var(--figma-color-border-brand-strong);
        outline: none;
    }

    .selected {
        background-color: var(--figma-color-bg-selected-strong);
    }
    .selected:hover {
        background-color: var(--figma-color-bg-selected-strong);
    }
    .selected:active, .selected:focus {
        border: 2px solid var(--figma-color-border-selected-strong);
    }

</style>

================================================
FILE: src/components/Input/index.svelte
================================================
<script>

    import Icon from './../Icon/index.svelte';

    export let id = null;
    export let value = null;
    export let name = null;
    export let iconText = null;
    export let borders = false;
    export let disabled = false;
    export let iconName = null;
    export let spin = false;
    export let invalid = false;
    export let errorMessage = 'Error message';
    export let placeholder = 'Input something here...';
    export { className as class };

    let className = '';

</script>

{#if iconName || iconText}
    <div class="input {className}">
        <div class="icon">
            <Icon {iconName} {iconText} {spin} color="--figma-color-icon"/>
        </div>
        <input 
            type="input"
            on:input
            on:change
            on:keydown
            on:focus
            on:blur
            bind:value={value}
            {id}
            {name}
            {disabled}
            {placeholder}
            {errorMessage}
            class="indent"
            class:borders={borders}
            class:invalid={invalid}
        >
        {#if invalid}
            <div class="error">
                {errorMessage}
            </div>
        {/if}
    </div>
{:else}
    <div class="input {className}">
        <input 
            type="input"
            on:input
            on:change
            on:keydown
            on:focus
            on:blur
            bind:value={value}
            {id}
            {name}
            {disabled}
            {placeholder}
            {errorMessage}
            class:borders={borders}
            class:invalid={invalid}
        >
        {#if invalid}
            <div class="error">
                {errorMessage}
            </div>
        {/if}
    </div>
{/if}
<style>

    .input {
        position: relative;
        transition: flex 0s 0.2s; 
    }

    input {
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-neg-xsmall);
        line-height: var(--line-height);
        position: relative;
        display: flex;
        overflow: visible;
        align-items: center;
        width: 100%;
        height: 30px;
        margin: 1px 0 1px 0;
        padding: var(--size-xxsmall) var(--size-xxxsmall) var(--size-xxsmall) var(--size-xxsmall);
        color: var(--figma-color-text);
        border: 1px solid transparent;
        border-radius: var(--border-radius-small);
        outline: none;
        background-color: var(--figma-color-bg);
    }
    input:hover, input:placeholder-shown:hover {
		color: var(--figma-color-text-hover);
		border: 1px solid var(--figma-color-border);
        background-image: none;
	}
	input::selection {
		color: var(--figma-color-text);
		background-color: var(--text-highlight); 
	}
	input::placeholder {
		color: var(--figma-color-text-tertiary);
		border: 1px solid transparent;
	}
	input:placeholder-shown {
		color: var(--figma-color-text);
        border: 1px solid var(--figma-color-border);
        background-image: none;
	}
    input:focus:placeholder-shown {
        border: 1px solid var(--figma-color-border-selected);
        outline: 1px solid var(--figma-color-border-selected);
        outline-offset: -2px;
    }
	input:disabled:hover {
		border: 1px solid transparent;
	}
	input:active, input:focus {

		color: var(--figma-color-text);
        border: 1px solid var(--figma-color-border-selected);
        outline: 1px solid var(--figma-color-border-selected);
        outline-offset: -2px;
	}
	input:disabled {
		position: relative;
		color: var(--figma-color-text-disabled);
        background-image: none;
	}
	input:disabled:active {
        outline: none;
    }

    .borders {
        border: 1px solid var(--figma-color-border);
        background-image: none;
    }
    .borders:disabled {
        border: 1px solid transparent;
        background-image: none;
    }
    .borders:disabled:placeholder-shown {
        border: 1px solid transparent;
        background-image: none;
    }
    .borders:disabled:placeholder-shown:active {
        border: 1px solid transparent;
        outline: none;
    }
    .borders:placeholder-shown {
        border: 1px solid var(--figma-color-border);
        background-image: none;
    }
    
    .indent {
        padding-left: 32px;
    }

    .invalid, .invalid:hover, .invalid:focus {
        border: 1px solid var(--figma-color-border-danger-strong);
        outline: 1px solid var(--figma-color-border-danger-strong);
        outline-offset: -2px;
    }

    .icon {
        position: absolute;
		top: -1px;
		left: 0;
        width: var(--size-medium);
        height: var(--size-medium);
        z-index: 1;
    }

    .error {
        color: var(--figma-color-text-danger);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-neg-xsmall);
        line-height: var(--line-height);
        padding-top: var(--size-xxxsmall);
        padding-left: var(--size-xxsmall);
    }

</style>

================================================
FILE: src/components/Label/index.svelte
================================================
<script>

    export { className as class };
    let className = '';

</script>

<div class="{className}">
    <slot></slot>
</div>

<style>

    div {
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-pos-xsmall);
        line-height: var(--line-height);
        color: var(--figma-color-text-secondary);
        height: var(--size-medium);
        width: 100%;
        display: flex;
        align-items: center;
        cursor: default;
        user-select: none;
        padding: 0 calc(var(--size-xxsmall) / 2) 0 var(--size-xxsmall);
    }

</style>

================================================
FILE: src/components/OnboardingTip/index.svelte
================================================
<script>
    import Icon from './../Icon/index.svelte';

    export let spin = false;
    export let color = "black8";
    export let iconName = null;
    export let iconText = null;
    export { className as class };

    let className = '';

</script>

<div class="onboarding-tip {className}">
    <div class="icon">
        <Icon {iconName} {iconText} {color} {spin}/>
    </div>
    <p>
        <slot></slot>
    </p>
</div>

<style>

    .onboarding-tip {
        display: flex;
        align-items: top;
        padding: 0 var(--size-xsmall) 0 0;
    }

    .icon {
        width: var(--size-medium);
        height: var(--size-medium);
        margin-right: var(--size-xxsmall);
    }

    p   {
        padding: var(--size-xxsmall) 0 var(--size-xxsmall) 0;
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-pos-xsmall);
        line-height: var(--line-height);
        color: var(--figma-color-text);
        margin: 0;
    }

</style>

================================================
FILE: src/components/Radio/index.svelte
================================================
<script>

    export let group = null;
    export let value = null;
    export let disabled = false;
    export let tabindex = 0;
    export { className as class };

    let uniqueId = 'radio--' + ((Math.random() * 10000000).toFixed(0)).toString();
    let className = '';
    $: checked = group === value;

</script>

<div class={className}>
    <input 
        type="radio"
        {value}
        {checked}
        {disabled} 
        {tabindex}
        id={uniqueId}
        bind:group={group}
        onclick="this.blur();"
        on:change
        on:focus
        on:blur>
    <label for={uniqueId}>
        <slot />
    </label>
</div>

<style>

    div {
        align-items: center;
        cursor: default;
        display: flex;
        position: relative;
    }

    input {
        opacity: 0;
        width: 10px;
        height: 10px;
        margin: 0;
        padding: 0;
        flex-shrink: 0;
    }
    input:checked + label:after {
        background-color: var(--figma-color-icon);
    }
    input:disabled + label {
        opacity: 0.3;
    }
    input:checked:disabled + label:before {
        border: 1px solid var(--figma-color-icon);
    }

    label {
        color: var(--figma-color-text);
        display: flex;
        font-family: var(--font-stack);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        line-height: var(--font-line-height);
        letter-spacing: var(--font-letter-spacing-pos-xsmall);
        margin-left: -16px;
        padding: var(--size-xxsmall) var(--size-xsmall) var(--size-xxsmall) var(--size-small);
        user-select: none;
    }
    /* checked dot */
    label:after {
        content: '';
        width: 6px;
        height: 6px;
        background-color: transparent;
        border-radius: 50%;
        position: absolute;
        top: 13px;
        left: 13px;
    }

    /* circle */
    label:before {
        border: 1px solid var(--figma-color-icon); 
		border-radius: var(--border-radius-small);
        content: '';
        display: block;
        width: 10px;
        height: 10px;
        margin: 2px 10px 0 -8px;
        border-radius: 50%;
        flex-shrink: 0;
    }

    input:enabled:checked:focus + label:before {
        border: 1px solid var(--figma-color-border-selected);
        box-shadow: 0 0 0 1px var(--figma-color-border-selected);
        border-radius: var(--border-radius-small);
        border-radius: 50%;
    }

    input:enabled:focus + label:before {
        border: 1px solid var(--figma-color-border-selected);
        box-shadow: 0 0 0 1px var(--figma-color-border-selected);
    }

</style>


================================================
FILE: src/components/Section/index.svelte
================================================
<script>

    let className = '';

</script>

<div>
    <slot></slot>
</div>

<style>

    div {
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-bold);
        letter-spacing: var( --font-letter-spacing-pos-xsmall);
        line-height: var(--line-height);
        color: var(--figma-color-text);
        height: var(--size-medium);
        width: 100%;
        display: flex;
        align-items: center;
        cursor: default;
        user-select: none;
        padding: 0 calc(var(--size-xxsmall) / 2) 0 var(--size-xxsmall);
    }

</style>

================================================
FILE: src/components/SelectDivider/index.svelte
================================================
<script>

    export let label = false;
    
</script>

{#if label===true}
    <li class="label"><slot/></li>
{:else}
    <li class="divider"></li>
{/if}

<style>

    .label {
        font-size: var(--font-size-small);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-neg-small);
        line-height: var(--line-height);
        display: flex;
        align-items: center;
		height: var(--size-small);
		margin-top: var(--size-xxsmall);
		padding: 0 var(--size-xxsmall) 0 var(--size-medium);
		color: var( --color-text-menu-secondary);
    }
    .label:first-child {
        border-top: none;
        margin-top: 0;
    }

    .divider {
        background-color: var(--color-border-menu);
        display: block;
		height: 1px;
		margin: 8px 0 7px 0;
    }

</style>

================================================
FILE: src/components/SelectItem/index.svelte
================================================
<script>
    
    export let itemId;
    export let selected = false;
    export { className as class };

    let className = '';

</script>

<li {itemId} tabindex={itemId+1} class:highlight={selected} class={className} on:mouseenter on:click>
    <div class="icon" class:selected={selected}>
    </div>
    <div class="label"><slot /></div>
</li>

<style>

    li {
        align-items: center;
        color: var(--color-text-menu-text);
        cursor: default;
        display: flex;
        font-family: var(--font-stack);
        font-size: var(--font-size-small);
        font-weight: var(--font-weight-normal);
        letter-spacing: var(--font-letter-spacing-neg-xsmall);
        line-height: var(--font-line-height);
        height: var(--size-small);
        padding: 0px var(--size-xsmall) 0px var(--size-xxsmall);
        user-select: none;
        outline: none;
        transition-property: background-color;
        transition-duration: 30ms;
    }

    .label {
        overflow-x: hidden;
        white-space: nowrap; 
        text-overflow: ellipsis;
        pointer-events: none;
    }

    .highlight, li:hover, li:focus {
        background-color: var(--figma-color-bg-brand);
    }

    .icon {
        width: var(--size-xsmall);
        height: var(--size-xsmall);
        margin-right: var(--size-xxsmall);
        opacity: 0;
        pointer-events: none;
        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');
        background-repeat: no-repeat;
		background-position: center center;
    }
    .icon.selected {
        opacity: 1.0;
    }

    .blink, .blink:hover {
        background-color: transparent;
    }

</style>

================================================
FILE: src/components/SelectMenu/index.svelte
================================================
<script>
    import { onMount } from 'svelte';
    import { createEventDispatcher } from 'svelte';
    import ClickOutside from 'svelte-click-outside';
    import SelectItem from './../SelectItem/index.svelte';
    import SelectDivider from './../SelectDivider/index.svelte';
    import Icon from './../Icon/index.svelte';

    export let iconName = null;
    export let iconText = null;
    export let disabled = false;
    export let macOSBlink = false;
    export let menuItems = []; //pass data in via this prop to generate menu items
    export let placeholder = "Please make a selection.";
    export let value = null; //stores the current selection, note, the value will be an object from your array
    export let showGroupLabels = false; //default prop, true will show option group labels
    export { className as class };

    const dispatch = createEventDispatcher();
    let className = '';
    let groups = checkGroups();
    let menuWrapper, menuButton, menuList;
    $:menuItems, updateSelectedAndIds();

    //FUNCTIONS

    //assign id's to the input array
    onMount(async () => {
        updateSelectedAndIds();
    });

    // this function runs everytime the menuItems array os updated
    // it will auto assign ids and keep the value var updated
    function updateSelectedAndIds() {
        if (menuItems) {
            menuItems.forEach((item, index) => {
                //update id
                item['id'] = index;
                //update selection
                if (item.selected === true) {
                    value =  item;
                }
            });
        }
        //set placeholder
        if (menuItems.length <= 0) {
            placeholder = 'There are no items to select';
            disabled = true;
        } else {
            placeholder = 'Please make a selection';
            disabled = false;
        }
    }

    //determine if option groups are present
    function checkGroups() {
        let groupCount = 0;
        if (menuItems) {
            menuItems.forEach(item => {
                if (item.group != null) { groupCount++; }
            });
            if (groupCount === menuItems.length) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    //menu highlight function on the selected menu item
    function removeHighlight(event) {
        let items = Array.from(event.target.parentNode.children);
        items.forEach(item => {
            item.blur();
            item.classList.remove('highlight');
        });
    }

    //run for all menu click events
    //this opens/closes the menu
    function menuClick(event) {

        resetMenuProperties();

        if (!event.target) {
            menuList.classList.add('hidden');

        } else if (event.target.contains(menuButton)) {
            let topPos = 0;

            if (value) {
                //toggle menu
                menuList.classList.remove('hidden');

                let id = value.id;
                let selectedItem = menuList.querySelector('[itemId="'+id+'"]');
                selectedItem.focus(); //set focus to the currently selected item

                // calculate distance from top so that we can position the dropdown menu
                let parentTop = menuList.getBoundingClientRect().top;
                let itemTop = selectedItem.getBoundingClientRect().top;
                let topPos = (itemTop - parentTop) - 3;
                menuList.style.top = -Math.abs(topPos) + 'px';

                //update size and position based on plugin UI
                resizeAndPosition();

            } else {
                menuList.classList.remove('hidden');
                menuList.style.top = '0px';
                let firstItem = menuList.querySelector('[itemId="0"]');
                firstItem.focus();

                //update size and position based on plugin UI
                resizeAndPosition();

            }

        } else if (menuList.contains(event.target)) {
            //find selected item in array
            let itemId = parseInt(event.target.getAttribute('itemId')); 

            //remove current selection if there is one
            if (value) {
                menuItems[value.id].selected = false;
            }
            menuItems[itemId].selected = true; //select current item
            updateSelectedAndIds();
            dispatch('change', menuItems[itemId]);

            if (macOSBlink) {
                var x = 4;
                var interval = 70;
                
                //blink the background
                for (var i = 0; i < x; i++) {
                    setTimeout(function () {
                        event.target.classList.toggle('blink');
                    }, i * interval)
                }
                //delay closing the menu
                setTimeout(function () {
                    menuList.classList.add('hidden'); //hide the menu
                }, (interval * x) + 40)

            } else {
                menuList.classList.add('hidden'); //hide the menu
                menuButton.classList.remove('selected'); //remove selected state from button
            }
        }
    }

    // this function ensures that the select menu
    // fits inside the plugin viewport
    // if its too big, it will resize it and enable a scrollbar
    // if its off screen it will shift the position
    function resizeAndPosition() {

        //set the max height of the menu based on plugin/iframe window
        let maxMenuHeight = window.innerHeight - 16;
        let menuHeight = menuList.offsetHeight;
        let menuResized = false;

        if (menuHeight > maxMenuHeight) {
            menuList.style.height = maxMenuHeight + 'px';
            menuResized = true;
        }

        //lets adjust the position of the menu if its cut off from viewport
        let bounding = menuList.getBoundingClientRect();
        let parentBounding = menuButton.getBoundingClientRect();

        if (bounding.top < 0) {
            menuList.style.top = -Math.abs(parentBounding.top - 8) + 'px';
        }
        if (bounding.bottom > (window.innerHeight || document.documentElement.clientHeight)) {
            let minTop = -Math.abs(parentBounding.top - (window.innerHeight - menuHeight - 8));
            let newTop = -Math.abs(bounding.bottom - window.innerHeight + 16);
            if (menuResized) {
                menuList.style.top = -Math.abs(parentBounding.top - 8) + 'px'; 
            } else if (newTop > minTop) {
                menuList.style.top = minTop + 'px';
            } else {
                 menuList.style.top = newTop + 'px';
            }
            
        }

    }
    function resetMenuProperties() {
        menuList.style.height = 'auto';
        menuList.style.top = '0px';
    }

</script>

<ClickOutside on:clickoutside={menuClick}>
    <div 
        on:change
        on:focus
        on:blur
        bind:this={menuWrapper}
        {disabled}
        {placeholder}
        {showGroupLabels}
        {macOSBlink}
        class="wrapper {className}"
        >

        <button bind:this={menuButton} on:click={menuClick} disabled={disabled}>
            {#if iconName}
                <span class="icon"><Icon iconName={iconName} color="black3"/></span>
            {:else if iconText}
                <span class="icon"><Icon iconText={iconText} color="black3"/></span>
            {/if}

            {#if value}
                <span class="label">{value.label}</span>
            {:else}
                <span class="placeholder">{placeholder}</span>
            {/if}

            {#if !disabled}
                <span class="caret">
                    <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M3.64645 5.35359L0.646454 2.35359L1.35356 1.64648L4.00001 4.29293L6.64645 1.64648L7.35356 2.35359L4.35356 5.35359L4.00001 5.70714L3.64645 5.35359Z" fill="black"/> </svg>
                </span>
            {/if}
        </button>

        <ul class="menu hidden" bind:this={menuList}>
        {#if menuItems && menuItems.length > 0}
            {#each menuItems as item, i}
                {#if i === 0}
                    {#if item.group && showGroupLabels}
                        <SelectDivider label>{item.group}</SelectDivider>
                    {/if}
                {:else if i > 0 && item.group && menuItems[i - 1].group != item.group}
                    {#if showGroupLabels}
                        <SelectDivider />
                        <SelectDivider label>{item.group}</SelectDivider>
                    {:else}
                        <SelectDivider />
                    {/if}
                {/if}
                <SelectItem on:click={menuClick} on:mouseenter={removeHighlight} itemId={item.id} bind:selected={item.selected}>{item.label}</SelectItem>
            {/each}
        {/if}
        </ul>
    </div>
</ClickOutside>


<style>

    .wrapper {
        position: relative;
    }

    button {
        display: flex;
        align-items: center;
        border: 1px solid transparent;
        height: 30px;
        width: 100%;
        margin: 1px 0 1px 0;
        padding: 4px var(--size-xxsmall) 0px var(--size-xxsmall);   
        overflow-y: hidden;
        border-radius: var(--border-radius-small);
        background-color: var(--white);
    }
    button:hover, button:active {
        border-color: var(--black1);
    }
    button:hover .placeholder {
        color: var(--black8);
    }
    button:hover .caret svg path, button:focus .caret svg path {
        fill: var(--black8);
    }
    button:hover .caret, button:focus .caret {
        margin-left: auto;
    }
    button:focus {
        border: 1px solid var(--blue);
        outline: 1px solid var(--blue);
        outline-offset: -2px;
        padding-left: calc(var(--size-xxsmall) + 1px);
    }
    button:focus .placeholder {
        color: var(--black8);
    }
    button:disabled .label {
        color: var(--black3);
    }
    button:disabled:hover {
        justify-content: flex-start;
        border-color: transparent;
    }
    button:disabled:hover .placeholder {
        color: var(--black3);
    }
    button:disabled:hover .caret svg path {
        fill: var(--black3);
    }
    button * {
        pointer-events: none;
    }

    .label, .placeholder {
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-neg-xsmall);
        line-height: var(--line-height);
        color: var(--figma-color-text);
        margin-right: 6px;
        margin-top: -3px;
        white-space: nowrap;
        overflow-x: hidden;
        text-overflow: ellipsis;
    }

    .placeholder {
        color: var(--figma-color-text-tertiary);
    }

    .caret {
        display: block;
        margin-top: -1px;
    }

    .caret svg path {
        fill: var(--figma-color-icon-tertiary);
    }

    .icon {
        margin-left: -8px;
        margin-top: -2px;
        margin-right: 0;
    }

    .menu {
        position: absolute;
        top:32px;
        left:0;
        width: 100%;
        background-color: var(--color-bg-menu);
        box-shadow: var(--shadow-hud);
        padding: var(--size-xxsmall) 0 var(--size-xxsmall) 0;
        border-radius: var(--border-radius-small);
        margin: 0;
        z-index: 50;
        overflow-x: overlay;
        overflow-y: auto;
    }
    .menu::-webkit-scrollbar{
        width:12px;
        background-color:transparent;
        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=);
        background-repeat:repeat;
        background-size:100% auto
    }
    .menu::-webkit-scrollbar-track{
        border:solid 3px transparent;
        -webkit-box-shadow:inset 0 0 10px 10px transparent;
        box-shadow:inset 0 0 10px 10px transparent;
    }
    .menu::-webkit-scrollbar-thumb{
        border:solid 3px transparent;
        border-radius:6px;
        -webkit-box-shadow:inset 0 0 10px 10px rgba(255,255,255,.4);
        box-shadow:inset 0 0 10px 10px rgba(255,255,255,.4);
    }
        

</style>

================================================
FILE: src/components/Switch/index.svelte
================================================
<script>
    
    export let checked = false;
    export let value = '';
    export let disabled = false;
    export let tabindex = 0;
    export { className as class };

    let uniqueId = 'switch--' + ((Math.random() * 10000000).toFixed(0)).toString();
    let className = '';
    
</script>

<div class={className}>
    <input 
        type="checkbox" 
        id={uniqueId} 
        bind:checked={checked} 
        bind:value={value} 
        {disabled}  
        {tabindex}
        onclick="this.blur();"
        on:change
        on:focus
        on:blur>
    <label for={uniqueId}>
        <slot />
    </label>
</div>

<style>

    div {
        align-items: center;
        cursor: default;
        display: flex;
        position: relative;
    }

    input {
        opacity: 0;
    }
    input:checked + label:before {
        color: var(--figma-color-icon);
        background-color: var(--figma-color-bg-brand);
    }

    input:checked + label:after {
        transform: translateX(12px);
    }
    input:disabled + label {
        color: var(--figma-color-icon-disabled);
        opacity: 0.3;
    }
    input:checked:disabled + label:before {
        border: 1px solid var(--figma-color-icon);
        background-color: var(--figma-color-icon);
    }

    input:focus + label:before {
        box-shadow: 0 0 0 2px var(--figma-color-border-selected);
    }

    label {
        color: var(--figma-color-text);
        display: flex;
        font-family: var(--font-stack);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var(--font-letter-spacing-pos-xsmall);
        line-height: var(--font-line-height);
        margin-left: -16px;
        padding: var(--size-xxsmall) var(--size-xsmall) var(--size-xxsmall) calc(var(--size-xlarge) - 2px);
        user-select: none;
    }
    /* track */
    label:before {
        background-color: var(--figma-color-icon-tertiary);
        border-radius: 6px;
        content: '';
        display: block;
        height: 12px;
        left: 8px;
        position: absolute;
        top: 10px;
        transition: background-color 0.2s 0.1s;
        width: 24px;
    }
    /* slider */
    label:after {
        background-color: var(--figma-color-icon-onbrand);
        border-radius: 50%;
        content: '';
        display: block;
        height: 10px;
        left: 9px;
        position: absolute;
        top: 11px;
        transition: transform 0.2s;
        width: 10px;

    }

</style>

================================================
FILE: src/components/Textarea/index.svelte
================================================
<script>
    export let id = null;
    export let value = null;
    export let rows = 2;
    export let name = null;
    export let disabled = false;
    export let placeholder = 'Input something here...';
    export { className as class };

    let className = '';

</script>

<div class="textarea {className}">
    <textarea 
        type="input"
        on:input
        on:change
        on:keydown
        on:focus
        on:blur
        {id}
        {name}
        {rows}
        {disabled}
        {placeholder}
        >{value}</textarea>
</div>

<style>

    .textarea {
        position: relative;
    }

    textarea {
        font-family: var(--font-stack);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        letter-spacing: var( --font-letter-spacing-neg-xsmall);
        line-height: var(--line-height);
        position: relative;
        display: flex;
        overflow: visible;
        align-items: center;
        width: 100%;
        min-height: 62px;
        margin: 1px 0 1px 0;
        padding: 7px 4px 9px 7px;
        color: var(--figma-color-text);
        border: 1px solid var(--figma-color-border);
        border-radius: var(--border-radius-small);
        outline: none;
        background-color: var(--figma-color-bg);
        resize: none;
        overflow-y: auto;
    }
    textarea:hover, textarea:placeholder-shown:hover {
		color: var(--figma-color-text);
		border: 1px solid var(--figma-color-border);
        background-image: none;
	}
	textarea::selection {
		color: var(--figma-color-text);
		background-color: var(--text-highlight);
	}
	textarea::placeholder {
		color: var(--figma-color-text-tertiary);
		border: 1px solid transparent;
	}
    textarea:focus:placeholder-shown {
        border: 1px solid var(--figma-color-border-selected);
        outline: 1px solid var(--figma-color-border-selected);
        outline-offset: -2px;
    }
	textarea:active, textarea:focus {
		padding: 7px 4px 9px 7px;

		color: var(--figma-color-text);
        border: 1px solid var(--figma-color-border-selected);
        outline: 1px solid var(--figma-color-border-selected);
        outline-offset: -2px;
	}
	textarea:disabled, textarea:disabled:hover {
		position: relative;
        color: var(--figma-color-text-disabled);
        border: 1px solid transparent;
	}
	textarea:disabled:active {
		padding: 7px 4px 9px 7px;
        outline: none;
    }

</style>

================================================
FILE: src/components/Type/index.svelte
================================================
<script>
    import { onMount } from 'svelte';

    export let size = 'xsmall';
    export let weight = 'normal';
    export let inverse = false; //this prop uses different letterspacing values for inversed type (light on dark)
    export let color = '--figma-color-text';
    export let inline = false;
    export { className as class };
    
    let className = '';
    let cssColorVar; 

    onMount(async () => {
        if (color = 'black8' && inverse) {
            color = 'white';
        }
    });


    cssColorVar = 'var(' + color + ')';

</script>

<div class="type {className} {size} {weight}" class:inverse={inverse} class:inline={inline} style="color: {cssColorVar}">
    <slot/>
</div>

<style>

    .type {
        font-family: var(--font-stack);
        font-size: var(--font-size-xsmall);
        font-weight: var(--font-weight-normal);
        line-height: var(--font-line-height);
        letter-spacing: var(--font-letter-spacing-pos-xsmall);
    }

    /* sizes */
    .small {
        font-size: var(--font-size-small);
        letter-spacing: var(--font-letter-spacing-pos-small);
    }
    .large {
        font-size: var(--font-size-large);
        line-height: var(--font-line-height-large);
        letter-spacing: var(--font-letter-spacing-pos-large);
    }
    .xlarge {
        font-size: var(--font-size-xlarge);
        line-height: var(--font-line-height-large);
        letter-spacing: var(--font-letter-spacing-pos-xlarge);
    }

    /* weights */
    .medium {
        font-weight: var(--font-weight-medium);
    }
    .bold {
        font-weight: var(--font-weight-bold);
    }

    /* letter spacing adjustments based pos/neg application */
    .inverse {
        letter-spacing: var(--font-letter-spacing-neg-xsmall);
    }
    .inverse.small {
        letter-spacing: var(--font-letter-spacing-neg-small);
    }
    .inverse.large {
        letter-spacing: var(--font-letter-spacing-neg-large);
    }
    .inverse.xlarge {
        letter-spacing: var(--font-letter-spacing-neg-xlarge);
    }

    .inline {
        display: inline-block;
    }

</style>

================================================
FILE: src/global.css
================================================
/* Vars */
:root {
	/* COLORS */

    /*
    This has been updated to work with Figma's color tokens.
    The following variables are included for legacy support, 
    where they may be referenced in your own custom components.

    All of these variables (where possible) will now map to 
    Figma's color variables.

    Components part of this package will directly consume
    Figma's variables to support light and dark mode.
    */



    /* Accent */
    --blue: var(--figma-color-bg-brand); 
    --purple: var(--figma-color-bg-component); 
    --hot-pink: #ff00ff;
    --green: #1bc47d;
    --red: var(--figma-color-bg-danger);
    --yellow: var(--figma-color-bg-warning);

    /* Basic foreground */
    --black: #000000;
    --black8: var(--figma-color-text); 
    --black8-opaque: #333333; 
    --black3: var(--figma-color-text-secondary);
    --black3-opaque: #7A7A7A; 
    --white: var(--figma-color-bg); 
    --white8: var(--figma-color-text-onbrand-secondary); 
    --white4: var(--figma-color-text-onbrand-tertiary); 

    /* Basic background */
    --grey: #f0f0f0; 
    --silver: var(--figma-color-border); 
    --hud: #222222;
    --toolbar: var(--figma-color-bg-inverse);

    /* Special */
    --black1: rgba(0, 0, 0, .1); 
    --blue3: rgba(24, 145, 251, .3); 
    --purple4: var(--figma-color-text-component-secondary);
    --hover-fill: var(--figma-color-bg-hover);
    --selection-a: var(--figma-color-bg-selected);
    --selection-b: var(--figma-color-bg-selected-secondary);
    --white2: var(--figma-color-text-onbrand-tertiary); 

    /* SHIM */
    --color-bg-menu: #1e1e1e; /* to update */
    --color-text-menu-text: #FFFFFF;
    --color-text-menu-secondary: rgba(255, 255, 255, 0.7);
    --color-border-menu: #383838;
    --text-highlight: rgba(13, 153, 255, 0.4);


    /* TYPOGRAPHY */
    /* Pos = positive applications (black on white) */
    /* Neg = negative applications (white on black) */
    
    /* Font stack */
    --font-stack: 'Inter', sans-serif;

    /* Font sizes */
    --font-size-xsmall: 11px;
    --font-size-small: 12px;
    --font-size-large: 13px;
    --font-size-xlarge: 14px;

    /* Font weights */
    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-bold: 600;

    /* Lineheight */
    --font-line-height: 16px; /* Use For xsmall, small font sizes */
    --font-line-height-large: 24px; /* Use For large, xlarge font sizes */
    
    /* Letterspacing */
    --font-letter-spacing-pos-xsmall: .005em;
    --font-letter-spacing-neg-xsmall: .01em;
    --font-letter-spacing-pos-small: 0;
    --font-letter-spacing-neg-small: .005em;
    --font-letter-spacing-pos-large: -.0025em;
    --font-letter-spacing-neg-large: .0025em;
    --font-letter-spacing-pos-xlarge: -.001em;
    --font-letter-spacing-neg-xlarge: -.001em;


    /* BORDER RADIUS */
    --border-radius-small: 2px;
    --border-radius-med: 5px;
    --border-radius-large: 6px;


    /* SHADOWS */
    --shadow-hud: 0 5px 17px rgba(0, 0, 0, .2), 0 2px 7px rgba(0, 0, 0, .15);
    --shadow-floating-window: 0 2px 14px rgba(0, 0, 0, .15);


    /* SPACING + SIZING */
    --size-xxxsmall: 4px;
    --size-xxsmall: 8px;
    --size-xsmall: 16px;
    --size-small: 24px;
    --size-medium: 32px;
    --size-large: 40px;
    --size-xlarge: 48px;
    --size-xxlarge: 64px;
    --size-huge: 80px;
}

/* Global styles */

* {
	box-sizing: border-box;
}

body {
    position: relative;
	box-sizing: border-box;
    font-family: 'Inter', sans-serif;
    margin: 0;
    padding: 0;
}


/*  FONTS */
@font-face {
	font-family: 'Inter';
	font-weight: 400;
	font-style: normal;
	src: url('https://rsms.me/inter/font-files/Inter-Regular.woff2?v=3.7') format('woff2'),
	url('https://rsms.me/inter/font-files/Inter-Regular.woff?v=3.7') format('woff');
}

@font-face {
	font-family: 'Inter';
	font-weight: 500;
	font-style: normal;
	src: url('https://rsms.me/inter/font-files/Inter-Medium.woff2?v=3.7') format('woff2'),
	url('https://rsms.me/inter/font-files/Inter-Medium.woff2?v=3.7') format('woff');
}

@font-face {
	font-family: 'Inter';
	font-weight: 600;
	font-style: normal;
	src: url('https://rsms.me/inter/font-files/Inter-SemiBold.woff2?v=3.7') format('woff2'),
	url('https://rsms.me/inter/font-files/Inter-SemiBold.woff2?v=3.7') format('woff');
}

/* Hyperlink styling */
a {
    color: var(--blue);
    text-decoration: none;
    cursor: pointer;
}
a:hover {
    color: var(--blue);
}
a:active {
    color: var(--blue);
}
a:focus {
    text-decoration: underline;
}

/* UTILITIES */

/* padding */
.p-xxxsmall { padding: var(--size-xxxsmall); }
.p-xxsmall { padding: var(--size-xxsmall); }
.p-xsmall { padding: var(--size-xsmall); }
.p-small { padding: var(--size-small); }
.p-medium { padding: var(--size-medium); }
.p-large { padding: var(--size-large); }
.p-xlarge { padding: var(--size-xlarge); }
.p-xxlarge { padding: var(--size-xxlarge); }
.p-huge { padding: var(--size-huge); }

/* padding top */
.pt-xxxsmall { padding-top: var(--size-xxxsmall); }
.pt-xxsmall { padding-top: var(--size-xxsmall); }
.pt-xsmall { padding-top: var(--size-xsmall); }
.pt-small { padding-top: var(--size-small); }
.pt-medium { padding-top: var(--size-medium); }
.pt-large { padding-top: var(--size-large); }
.pt-xlarge { padding-top: var(--size-xlarge); }
.pt-xxlarge { padding-top: var(--size-xxlarge); }
.pt-huge { padding-top: var(--size-huge); }

/* padding right */
.pr-xxxsmall { padding-right: var(--size-xxxsmall); }
.pr-xxsmall { padding-right: var(--size-xxsmall); }
.pr-xsmall { padding-right: var(--size-xsmall); }
.pr-small { padding-right: var(--size-small); }
.pr-medium { padding-right: var(--size-medium); }
.pr-large { padding-right: var(--size-large); }
.pr-xlarge { padding-right: var(--size-xlarge); }
.pr-xxlarge { padding-right: var(--size-xxlarge); }
.pr-huge { padding-right: var(--size-huge); }

/* padding bottom */
.pb-xxxsmall { padding-bottom: var(--size-xxxsmall); }
.pb-xxsmall { padding-bottom: var(--size-xxsmall); }
.pb-xsmall { padding-bottom: var(--size-xsmall); }
.pb-small { padding-bottom: var(--size-small); }
.pb-medium { padding-bottom: var(--size-medium); }
.pb-large { padding-bottom: var(--size-large); }
.pb-xlarge { padding-bottom: var(--size-xlarge); }
.pb-xxlarge { padding-bottom: var(--size-xxlarge); }
.pb-huge { padding-bottom: var(--size-huge); }

/* padding left */
.pl-xxxsmall { padding-left: var(--size-xxxsmall); }
.pl-xxsmall { padding-left: var(--size-xxsmall); }
.pl-xsmall { padding-left: var(--size-xsmall); }
.pl-small { padding-left: var(--size-small); }
.pl-medium { padding-left: var(--size-medium); }
.pl-large { padding-left: var(--size-large); }
.pl-xlarge { padding-left: var(--size-xlarge); }
.pl-xxlarge { padding-left: var(--size-xxlarge); }
.pl-huge { padding-left: var(--size-huge); }

/* margin */
.m-xxxsmall { margin: var(--size-xxxsmall); }
.m-xxsmall { margin: var(--size-xxsmall); }
.m-xsmall { margin: var(--size-xsmall); }
.m-small { margin: var(--size-small); }
.m-medium { margin: var(--size-medium); }
.m-large { margin: var(--size-large); }
.m-xlarge { margin: var(--size-xlarge); }
.m-xxlarge { margin: var(--size-xxlarge); }
.m-huge { margin: var(--size-huge); }

/* margin top */
.mt-xxxsmall { margin-top: var(--size-xxxsmall); }
.mt-xxsmall { margin-top: var(--size-xxsmall); }
.mt-xsmall { margin-top: var(--size-xsmall); }
.mt-small { margin-top: var(--size-small); }
.mt-medium { margin-top: var(--size-medium); }
.mt-large { margin-top: var(--size-large); }
.mt-xlarge { margin-top: var(--size-xlarge); }
.mt-xxlarge { margin-top: var(--size-xxlarge); }
.mt-huge { margin-top: var(--size-huge); }

/* margin right */
.mr-xxxsmall { margin-right: var(--size-xxxsmall); }
.mr-xxsmall { margin-right: var(--size-xxsmall); }
.mr-xsmall { margin-right: var(--size-xsmall); }
.mr-small { margin-right: var(--size-small); }
.mr-medium { margin-right: var(--size-medium); }
.mr-large { margin-right: var(--size-large); }
.mr-xlarge { margin-right: var(--size-xlarge); }
.mr-xxlarge { margin-right: var(--size-xxlarge); }
.mr-huge { margin-right: var(--size-huge); }

/* margin bottom */
.mb-xxxsmall { margin-bottom: var(--size-xxxsmall); }
.mb-xxsmall { margin-bottom: var(--size-xxsmall); }
.mb-xsmall { margin-bottom: var(--size-xsmall); }
.mb-small { margin-bottom: var(--size-small); }
.mb-medium { margin-bottom: var(--size-medium); }
.mb-large { margin-bottom: var(--size-large); }
.mb-xlarge { margin-bottom: var(--size-xlarge); }
.mb-xxlarge { margin-bottom: var(--size-xxlarge); }
.mb-huge { margin-bottom: var(--size-huge); }

/* margin left */
.ml-xxxsmall { margin-left: var(--size-xxxsmall); }
.ml-xxsmall { margin-left: var(--size-xxsmall); }
.ml-xsmall { margin-left: var(--size-xsmall); }
.ml-small { margin-left: var(--size-small); }
.ml-medium { margin-left: var(--size-medium); }
.ml-large { margin-left: var(--size-large); }
.ml-xlarge { margin-left: var(--size-xlarge); }
.ml-xxlarge { margin-left: var(--size-xxlarge); }
.ml-huge { margin-left: var(--size-huge); }

/* layout utilities */
.hidden { display: none; }
.inline { display: inline; }
.block { display: block; }
.inline-block { display: inline-block; }
.flex { display: flex; }
.inline-flex {display: inline-flex; }

.column { flex-direction: column;}
.column-reverse { flex-direction: column-reverse; }
.row { flex-direction: row; }
.row-reverse { flex-direction: row-reverse; }

.flex-wrap { flex-wrap: wrap; }
.flex-wrap-reverse { flex-wrap: wrap-reverse; }
.flex-no-wrap { flex-wrap: nowrap }

.flex-shrink { flex-shrink: 1; }
.flex-no-shrink { flex-shrink: 0; }
.flex-grow { flex-grow: 1; }
.flex-no-grow { flex-grow: 0; }
  

.justify-content-start { justify-content: flex-start; }
.justify-content-end { justify-content: flex-end; }
.justify-content-center { justify-content: center; }
.justify-content-between { justify-content: space-between; }
.justify-content-around { justify-content: space-around; }

.align-items-start { align-items: flex-start; }
.align-items-end { align-items: flex-end; }
.align-items-center { align-items: center; }
.align-items-stretch { align-items: stretch; }

.align-content-start { align-content: flex-start; }
.align-content-end { align-content: flex-end; }
.align-content-center { align-content: center; }
.align-content-stretch { align-content: stretch; }

.align-self-start { align-self: flex-start; }
.align-self-end { align-self: flex-end; }
.align-self-center { align-self: center; }
.align-self-stretch { align-self: stretch; }


================================================
FILE: src/index.js
================================================
//Global CSS
import GlobalCSS from './global.css';

//Components
import Button from './components/Button/index.svelte';
import Checkbox from './components/Checkbox/index.svelte';
import Disclosure from './components/Disclosure/index.svelte';
import DisclosureItem from './components/DisclosureItem/index.svelte';
import Icon from './components/Icon/index.svelte';
import IconButton from './components/IconButton/index.svelte';
import Input from './components/Input/index.svelte';
import Label from './components/Label/index.svelte';
import OnboardingTip from './components/OnboardingTip/index.svelte';
import Radio from './components/Radio/index.svelte';
import Section from './components/Section/index.svelte';
import SelectDivider from './components/SelectDivider/index.svelte';
import SelectItem from './components/SelectItem/index.svelte';
import SelectMenu from './components/SelectMenu/index.svelte';
import Switch from './components/Switch/index.svelte';
import Textarea from './components/Textarea/index.svelte';
import Type from './components/Type/index.svelte';

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


export { GlobalCSS, Button, Checkbox, Disclosure, DisclosureItem, Icon, IconButton, Input, Label, OnboardingTip, Radio, Section, SelectDivider, SelectItem, SelectMenu, Switch, Textarea, Type, IconAdjust, IconAlert, IconAngle, IconArrowLeftRight, IconUpDown, IconAutoLayoutHorizontal, IconAutoLayoutVertical, IconBack, IconBlendEmpty, IconBlend, IconBreak, IconCaretDown, IconCaretLeft, IconCaretRight, IconCaretUp, IconCheck, IconClose, IconComponent, IconCornerRadius, IconCorners, IconDistributeHorizontalSpacing, IconDistributeVerticalSpacing, IconDraft, IconEffects, IconEllipses, IconEyedropper, IconForward, IconFrame, IconGroup, IconHidden, IconHorizontalPadding, IconHyperlink, IconImage, IconInstance, IconKey, IconLayoutAlignBottom, IconAlignHorizontalCenters, IconAlignLeft, IconAlignRight, IconAlignTop, IconAlignVerticalCenters, IconLayoutGridColumns, IconLayoutGridRows, IconLayoutGridUniform, IconLibrary, IconLinkBroken, IconLinkConnected, IconListDetailed, IconListTile, IconList, IconLockOff, IconLockOn, IconMinus, IconPlay, IconPlus, IconRandom, IconRecent, IconResizeToFit, IconResolveFilled, IconResolve, IconReverse, IconSearchLarge, IconSearch, IconSettings, IconShare, IconSmiley, IconSortAlphaAsc, IconSortAlphaDsc, IconSortTopBottom, IconSpacing, IconSpinner, IconStarOff, IconStarOn, IconStrokeWeight, IconStyles, IconSwap, IconTheme, IconTidyUpGrid, IconTidyUpListHorizontal, IconTidyUpListVertical, IconTimer, IconTrash, IconVerticalPadding, IconVisible, IconWarningLarge, IconWarning };


================================================
FILE: src/test.js
================================================
// for testing
import App from './App.svelte';

const app = new App({
    target: document.body,
});

export default app;
Download .txt
gitextract_z97jab7u/

├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── public/
│   └── index.html
├── rollup.config.js
└── src/
    ├── App.svelte
    ├── components/
    │   ├── Button/
    │   │   └── index.svelte
    │   ├── Checkbox/
    │   │   └── index.svelte
    │   ├── Disclosure/
    │   │   └── index.svelte
    │   ├── DisclosureItem/
    │   │   └── index.svelte
    │   ├── Icon/
    │   │   └── index.svelte
    │   ├── IconButton/
    │   │   └── index.svelte
    │   ├── Input/
    │   │   └── index.svelte
    │   ├── Label/
    │   │   └── index.svelte
    │   ├── OnboardingTip/
    │   │   └── index.svelte
    │   ├── Radio/
    │   │   └── index.svelte
    │   ├── Section/
    │   │   └── index.svelte
    │   ├── SelectDivider/
    │   │   └── index.svelte
    │   ├── SelectItem/
    │   │   └── index.svelte
    │   ├── SelectMenu/
    │   │   └── index.svelte
    │   ├── Switch/
    │   │   └── index.svelte
    │   ├── Textarea/
    │   │   └── index.svelte
    │   └── Type/
    │       └── index.svelte
    ├── global.css
    ├── index.js
    └── test.js
Condensed preview — 28 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (130K chars).
[
  {
    "path": ".gitattributes",
    "chars": 88,
    "preview": "# Auto detect text files and perform LF normalization\n *.* linguist-language=JavaScript\n"
  },
  {
    "path": ".gitignore",
    "chars": 1364,
    "preview": "public/components.js\ntodo.md\n\n.DS_Store\nnode_modules\nyarn.lock\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*"
  },
  {
    "path": "LICENSE",
    "chars": 1069,
    "preview": "MIT License\n\nCopyright (c) 2020 Thomas Lowry\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
  },
  {
    "path": "README.md",
    "chars": 33557,
    "preview": "# Figma Plugin DS Svelte\n\nWORK IN PROGRESS—This is a Svelte version of the Figma Plugin DS specifically for use in creat"
  },
  {
    "path": "package.json",
    "chars": 1319,
    "preview": "{\n  \"name\": \"figma-plugin-ds-svelte\",\n  \"version\": \"1.3.8\",\n  \"description\": \"A collection of Svelte components that mat"
  },
  {
    "path": "public/index.html",
    "chars": 277,
    "preview": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf8\" />\n        <meta name=\"viewport\" content=\"width=device-wi"
  },
  {
    "path": "rollup.config.js",
    "chars": 894,
    "preview": "import svelte from 'rollup-plugin-svelte';\nimport resolve from 'rollup-plugin-node-resolve';\nimport commonjs from 'rollu"
  },
  {
    "path": "src/App.svelte",
    "chars": 22657,
    "preview": "<script>\n    //This is a simple app playground to test components and their markup\n\n    // Global CSS\n    import style f"
  },
  {
    "path": "src/components/Button/index.svelte",
    "chars": 3623,
    "preview": "<script>\n    import { onMount } from 'svelte';\n\n    export let variant = 'primary';\n    export let disabled = false;\n   "
  },
  {
    "path": "src/components/Checkbox/index.svelte",
    "chars": 2945,
    "preview": "<script>\n\n    export let checked = false;\n    export let value = '';\n    export let disabled = false;\n    export let tab"
  },
  {
    "path": "src/components/Disclosure/index.svelte",
    "chars": 1069,
    "preview": "<script>\n\n    import { createEventDispatcher, setContext, onMount } from 'svelte';\n    import { writable } from 'svelte/"
  },
  {
    "path": "src/components/DisclosureItem/index.svelte",
    "chars": 2686,
    "preview": "<script context=\"module\">\n    export const disclosure = {};\n</script>\n\n<script>\n\n    import { getContext, onMount } from"
  },
  {
    "path": "src/components/Icon/index.svelte",
    "chars": 1187,
    "preview": "<script>\n    export let iconName = null; //pass svg data into this var by importing an svg in parent\n    export let spin"
  },
  {
    "path": "src/components/IconButton/index.svelte",
    "chars": 1391,
    "preview": "<script>\n    import Icon from './../Icon/index.svelte';\n\n    export let iconName = '';\n    export let iconText = null;\n "
  },
  {
    "path": "src/components/Input/index.svelte",
    "chars": 5089,
    "preview": "<script>\n\n    import Icon from './../Icon/index.svelte';\n\n    export let id = null;\n    export let value = null;\n    exp"
  },
  {
    "path": "src/components/Label/index.svelte",
    "chars": 647,
    "preview": "<script>\n\n    export { className as class };\n    let className = '';\n\n</script>\n\n<div class=\"{className}\">\n    <slot></s"
  },
  {
    "path": "src/components/OnboardingTip/index.svelte",
    "chars": 1036,
    "preview": "<script>\n    import Icon from './../Icon/index.svelte';\n\n    export let spin = false;\n    export let color = \"black8\";\n "
  },
  {
    "path": "src/components/Radio/index.svelte",
    "chars": 2647,
    "preview": "<script>\n\n    export let group = null;\n    export let value = null;\n    export let disabled = false;\n    export let tabi"
  },
  {
    "path": "src/components/Section/index.svelte",
    "chars": 580,
    "preview": "<script>\n\n    let className = '';\n\n</script>\n\n<div>\n    <slot></slot>\n</div>\n\n<style>\n\n    div {\n        font-size: var("
  },
  {
    "path": "src/components/SelectDivider/index.svelte",
    "chars": 818,
    "preview": "<script>\n\n    export let label = false;\n    \n</script>\n\n{#if label===true}\n    <li class=\"label\"><slot/></li>\n{:else}\n  "
  },
  {
    "path": "src/components/SelectItem/index.svelte",
    "chars": 2054,
    "preview": "<script>\n    \n    export let itemId;\n    export let selected = false;\n    export { className as class };\n\n    let classN"
  },
  {
    "path": "src/components/SelectMenu/index.svelte",
    "chars": 12281,
    "preview": "<script>\n    import { onMount } from 'svelte';\n    import { createEventDispatcher } from 'svelte';\n    import ClickOutsi"
  },
  {
    "path": "src/components/Switch/index.svelte",
    "chars": 2519,
    "preview": "<script>\n    \n    export let checked = false;\n    export let value = '';\n    export let disabled = false;\n    export let"
  },
  {
    "path": "src/components/Textarea/index.svelte",
    "chars": 2442,
    "preview": "<script>\n    export let id = null;\n    export let value = null;\n    export let rows = 2;\n    export let name = null;\n   "
  },
  {
    "path": "src/components/Type/index.svelte",
    "chars": 2096,
    "preview": "<script>\n    import { onMount } from 'svelte';\n\n    export let size = 'xsmall';\n    export let weight = 'normal';\n    ex"
  },
  {
    "path": "src/global.css",
    "chars": 10480,
    "preview": "/* Vars */\n:root {\n\t/* COLORS */\n\n    /*\n    This has been updated to work with Figma's color tokens.\n    The following "
  },
  {
    "path": "src/index.js",
    "chars": 7158,
    "preview": "//Global CSS\nimport GlobalCSS from './global.css';\n\n//Components\nimport Button from './components/Button/index.svelte';\n"
  },
  {
    "path": "src/test.js",
    "chars": 122,
    "preview": "// for testing\nimport App from './App.svelte';\n\nconst app = new App({\n    target: document.body,\n});\n\nexport default app"
  }
]

About this extraction

This page contains the full source code of the thomas-lowry/figma-plugin-ds-svelte GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 28 files (121.2 KB), approximately 30.5k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!