figma-plugin-utilities 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# figma-plugin-
|
|
1
|
+
# figma-plugin-utilities
|
|
2
2
|
|
|
3
3
|
Shared Svelte components and utilities for Figma plugins.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install figma-plugin-
|
|
8
|
+
npm install figma-plugin-ulities
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
ListItem,
|
|
24
24
|
LoadingState,
|
|
25
25
|
FieldGroup,
|
|
26
|
+
CheckboxCard,
|
|
26
27
|
// Utilities
|
|
27
28
|
sendToPlugin,
|
|
28
29
|
createMessageHandler,
|
|
@@ -56,6 +57,7 @@ import { sendToPlugin, createMessageHandler } from "figma-plugin-utils/lib";
|
|
|
56
57
|
| `ListItem` | Selectable list items with metadata slot and action menu |
|
|
57
58
|
| `LoadingState` | Centered loading indicator with custom message |
|
|
58
59
|
| `FieldGroup` | Label + input wrapper for form fields |
|
|
60
|
+
| `CheckboxCard` | Large checkbox with card styling and better touch targets |
|
|
59
61
|
|
|
60
62
|
### Header
|
|
61
63
|
|
|
@@ -140,6 +142,37 @@ Types: `info`, `success`, `error`, `warning`. Auto-dismisses after 4s for `info`
|
|
|
140
142
|
</ListItem>
|
|
141
143
|
```
|
|
142
144
|
|
|
145
|
+
### CheckboxCard
|
|
146
|
+
|
|
147
|
+
Large checkbox with card-style background and better touch targets.
|
|
148
|
+
|
|
149
|
+
```svelte
|
|
150
|
+
<!-- Basic usage -->
|
|
151
|
+
<CheckboxCard
|
|
152
|
+
checked={isSelected}
|
|
153
|
+
on:change={handleToggle}
|
|
154
|
+
>
|
|
155
|
+
Small
|
|
156
|
+
</CheckboxCard>
|
|
157
|
+
|
|
158
|
+
<!-- With secondary text -->
|
|
159
|
+
<CheckboxCard
|
|
160
|
+
checked={isSelected}
|
|
161
|
+
on:change={handleToggle}
|
|
162
|
+
>
|
|
163
|
+
Small
|
|
164
|
+
<svelte:fragment slot="secondary">400px</svelte:fragment>
|
|
165
|
+
</CheckboxCard>
|
|
166
|
+
|
|
167
|
+
<!-- Disabled state -->
|
|
168
|
+
<CheckboxCard
|
|
169
|
+
checked={true}
|
|
170
|
+
disabled={true}
|
|
171
|
+
>
|
|
172
|
+
Large
|
|
173
|
+
</CheckboxCard>
|
|
174
|
+
```
|
|
175
|
+
|
|
143
176
|
## Utilities
|
|
144
177
|
|
|
145
178
|
### Messages (`lib/messages.js`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figma-plugin-utilities",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Shared Svelte components and utilities for Figma plugins",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"svelte": "./src/index.js",
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
"import": "./src/lib/index.js",
|
|
22
22
|
"default": "./src/lib/index.js"
|
|
23
23
|
},
|
|
24
|
+
"./lib/*": {
|
|
25
|
+
"import": "./src/lib/*.js"
|
|
26
|
+
},
|
|
24
27
|
"./lib/figma-helpers": {
|
|
25
28
|
"types": "./src/lib/figma-helpers.ts",
|
|
26
29
|
"import": "./src/lib/figma-helpers.ts",
|
|
@@ -47,7 +50,7 @@
|
|
|
47
50
|
"author": "Marius Roosendaal",
|
|
48
51
|
"license": "MIT",
|
|
49
52
|
"dependencies": {
|
|
50
|
-
"figma-ui3-kit-svelte": "
|
|
53
|
+
"figma-ui3-kit-svelte": "file:../figma-ui3-kit-svelte",
|
|
51
54
|
"svelte": "^4.2.20"
|
|
52
55
|
}
|
|
53
56
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
import { Checkbox } from "figma-ui3-kit-svelte";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Large checkbox card component with better touch targets
|
|
7
|
+
* Wraps the standard checkbox in a card-like layout
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* <CheckboxCard
|
|
11
|
+
* checked={isSelected}
|
|
12
|
+
* on:change={handleToggle}
|
|
13
|
+
* >
|
|
14
|
+
* Small
|
|
15
|
+
* </CheckboxCard>
|
|
16
|
+
*
|
|
17
|
+
* @example with secondary text
|
|
18
|
+
* <CheckboxCard
|
|
19
|
+
* checked={isSelected}
|
|
20
|
+
* on:change={handleToggle}
|
|
21
|
+
* >
|
|
22
|
+
* Small
|
|
23
|
+
* <svelte:fragment slot="secondary">400px</svelte:fragment>
|
|
24
|
+
* </CheckboxCard>
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const dispatch = createEventDispatcher();
|
|
28
|
+
|
|
29
|
+
/** Whether checkbox is checked */
|
|
30
|
+
export let checked = false;
|
|
31
|
+
|
|
32
|
+
/** Whether checkbox is disabled */
|
|
33
|
+
export let disabled = false;
|
|
34
|
+
|
|
35
|
+
function handleCardClick(e) {
|
|
36
|
+
if (disabled) return;
|
|
37
|
+
|
|
38
|
+
// Don't toggle if clicking directly on the checkbox or label
|
|
39
|
+
// (let the checkbox handle it natively)
|
|
40
|
+
const target = e.target;
|
|
41
|
+
const isCheckboxOrLabel =
|
|
42
|
+
target.tagName === "INPUT" ||
|
|
43
|
+
target.tagName === "LABEL" ||
|
|
44
|
+
target.closest("label");
|
|
45
|
+
|
|
46
|
+
if (isCheckboxOrLabel) return;
|
|
47
|
+
|
|
48
|
+
// Toggle and dispatch change event
|
|
49
|
+
checked = !checked;
|
|
50
|
+
dispatch("change", { checked });
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<div
|
|
55
|
+
class="checkbox-card"
|
|
56
|
+
class:disabled
|
|
57
|
+
on:click={handleCardClick}
|
|
58
|
+
on:keydown={(e) => e.key === "Enter" && handleCardClick(e)}
|
|
59
|
+
role="button"
|
|
60
|
+
tabindex={disabled ? -1 : 0}
|
|
61
|
+
>
|
|
62
|
+
<Checkbox {checked} {disabled} on:change>
|
|
63
|
+
<slot />
|
|
64
|
+
</Checkbox>
|
|
65
|
+
{#if $$slots.secondary}
|
|
66
|
+
<div class="checkbox-card__secondary">
|
|
67
|
+
<slot name="secondary" />
|
|
68
|
+
</div>
|
|
69
|
+
{/if}
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<style>
|
|
73
|
+
.checkbox-card {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: space-between;
|
|
77
|
+
padding: 0 var(--size-xxxsmall);
|
|
78
|
+
background: var(--figma-color-bg-secondary);
|
|
79
|
+
border: 1px solid transparent;
|
|
80
|
+
border-radius: var(--border-radius-medium);
|
|
81
|
+
cursor: pointer;
|
|
82
|
+
min-height: 24px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.checkbox-card:hover {
|
|
86
|
+
border-color: var(--figma-color-border);
|
|
87
|
+
background: var(--figma-color-bg-secondary);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.checkbox-card.disabled {
|
|
91
|
+
opacity: 0.4;
|
|
92
|
+
cursor: not-allowed;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Custom checkbox styling for card variant */
|
|
96
|
+
.checkbox-card :global(.checkbox-box) {
|
|
97
|
+
background-color: var(--figma-color-bg);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.checkbox-card__secondary {
|
|
101
|
+
font-size: var(--body-small-font-size);
|
|
102
|
+
font-weight: var(--body-small-font-weight);
|
|
103
|
+
letter-spacing: var(--body-small-letter-spacing);
|
|
104
|
+
line-height: var(--body-small-line-height);
|
|
105
|
+
color: var(--figma-color-text-secondary);
|
|
106
|
+
margin-left: auto;
|
|
107
|
+
padding-left: var(--size-xsmall);
|
|
108
|
+
}
|
|
109
|
+
</style>
|
|
@@ -30,12 +30,14 @@
|
|
|
30
30
|
/** Whether to center vertically */
|
|
31
31
|
export let centered = true;
|
|
32
32
|
|
|
33
|
+
let className = '';
|
|
34
|
+
export { className as class };
|
|
33
35
|
// Normalize actions
|
|
34
36
|
$: normalizedActions = actions ? actions : action ? [action] : null;
|
|
35
37
|
</script>
|
|
36
38
|
|
|
37
39
|
<div
|
|
38
|
-
class="empty-state"
|
|
40
|
+
class="empty-state {className}"
|
|
39
41
|
class:centered
|
|
40
42
|
class:small={size === "small"}
|
|
41
43
|
class:large={size === "large"}
|
|
@@ -16,11 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
/** For attribute for the label (optional) */
|
|
18
18
|
export let labelFor = "";
|
|
19
|
+
|
|
20
|
+
/** Size of the label (optional) */
|
|
21
|
+
export let size = undefined;
|
|
19
22
|
</script>
|
|
20
23
|
|
|
21
|
-
<div class="field-group">
|
|
24
|
+
<div class="field-group" class:small={size === "small"}>
|
|
22
25
|
{#if label}
|
|
23
|
-
<Label for={labelFor}>{label}</Label>
|
|
26
|
+
<Label for={labelFor} {size}>{label}</Label>
|
|
24
27
|
{/if}
|
|
25
28
|
<slot />
|
|
26
29
|
</div>
|
|
@@ -31,4 +34,8 @@
|
|
|
31
34
|
flex-direction: column;
|
|
32
35
|
gap: var(--size-xxsmall);
|
|
33
36
|
}
|
|
37
|
+
|
|
38
|
+
.field-group.small {
|
|
39
|
+
gap: var(--size-xxxsmall);
|
|
40
|
+
}
|
|
34
41
|
</style>
|
package/src/components/index.js
CHANGED