figrelay 0.9.1 → 0.10.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.
Binary file
Binary file
Binary file
Binary file
@@ -2,7 +2,7 @@
2
2
  // Receives {id, command, params} from the Go bridge (relayed through ui.html),
3
3
  // executes it against the Figma Plugin API, and replies {id, result|error}.
4
4
 
5
- figma.showUI(__html__, { width: 280, height: 104 });
5
+ figma.showUI(__html__, { width: 280, height: 104, themeColors: true });
6
6
 
7
7
  // The UI can collapse to a dot; selection changes must not resize it back.
8
8
  let collapsed = false;
@@ -197,10 +197,18 @@ function serialize(n, depth, compact) {
197
197
  return s;
198
198
  }
199
199
 
200
+ function has(x) {
201
+ return x !== undefined && x !== null;
202
+ }
203
+
204
+ function need(n, prop, what, id = n.id) {
205
+ if (!(prop in n)) throw new Error("node " + id + " " + what);
206
+ }
207
+
200
208
  async function parentOf(params) {
201
209
  if (params.parent_id) {
202
210
  const p = await node(params.parent_id);
203
- if (!("appendChild" in p)) throw new Error("node " + params.parent_id + " cannot have children");
211
+ need(p, "appendChild", "cannot have children", params.parent_id);
204
212
  return p;
205
213
  }
206
214
  return figma.currentPage;
@@ -213,7 +221,7 @@ function buildGradient(g) {
213
221
  const c = hexToRGB(s.color);
214
222
  return {
215
223
  position: s.position,
216
- color: { r: c.r, g: c.g, b: c.b, a: s.opacity === undefined || s.opacity === null ? 1 : s.opacity },
224
+ color: { r: c.r, g: c.g, b: c.b, a: has(s.opacity) ? s.opacity : 1 },
217
225
  };
218
226
  });
219
227
  if (stops.length < 2) throw new Error("gradient needs at least 2 stops");
@@ -249,7 +257,7 @@ function buildEffects(list) {
249
257
  throw new Error("unsupported effect type: " + type);
250
258
  }
251
259
  const color = hexToRGB(e.color || "#000000");
252
- color.a = e.color_opacity === undefined ? 0.25 : e.color_opacity;
260
+ color.a = has(e.color_opacity) ? e.color_opacity : 0.25;
253
261
  return {
254
262
  type,
255
263
  color,
@@ -272,6 +280,12 @@ function applyShapeParams(n, params) {
272
280
  }
273
281
  }
274
282
 
283
+ async function makeShape(n, params) {
284
+ applyShapeParams(n, params);
285
+ (await parentOf(params)).appendChild(n);
286
+ return summarize(n);
287
+ }
288
+
275
289
  // Tracking the nodes a script creates needs a wrapper around figma, but the
276
290
  // host object's properties are non-configurable and non-writable, so a Proxy
277
291
  // get trap that returns anything else (even a bound copy) breaks the Proxy
@@ -388,7 +402,7 @@ function buildTransition(item) {
388
402
  const t = {
389
403
  type,
390
404
  easing: { type: (item.easing || "EASE_OUT").toUpperCase() },
391
- duration: item.duration === undefined || item.duration === null ? 0.3 : item.duration,
405
+ duration: has(item.duration) ? item.duration : 0.3,
392
406
  };
393
407
  if (directional) {
394
408
  t.direction = (item.direction || "LEFT").toUpperCase();
@@ -485,23 +499,15 @@ const handlers = {
485
499
  // Figma gives new frames an opaque white fill, which silently covers
486
500
  // whatever sits behind a nested frame. Transparent unless asked.
487
501
  if (!params.fill_color || params.fill_color === "none") f.fills = [];
488
- applyShapeParams(f, params);
489
- (await parentOf(params)).appendChild(f);
490
- return summarize(f);
502
+ return makeShape(f, params);
491
503
  },
492
504
 
493
505
  async create_rectangle(params) {
494
- const r = figma.createRectangle();
495
- applyShapeParams(r, params);
496
- (await parentOf(params)).appendChild(r);
497
- return summarize(r);
506
+ return makeShape(figma.createRectangle(), params);
498
507
  },
499
508
 
500
509
  async create_ellipse(params) {
501
- const e = figma.createEllipse();
502
- applyShapeParams(e, params);
503
- (await parentOf(params)).appendChild(e);
504
- return summarize(e);
510
+ return makeShape(figma.createEllipse(), params);
505
511
  },
506
512
 
507
513
  async create_line(params) {
@@ -511,7 +517,7 @@ const handlers = {
511
517
  l.resize(params.length > 0 ? params.length : 100, 0);
512
518
  l.strokes = [{ type: "SOLID", color: hexToRGB(params.stroke_color || "#000000") }];
513
519
  if (params.stroke_weight) l.strokeWeight = params.stroke_weight;
514
- if (params.rotation !== undefined && params.rotation !== null) l.rotation = params.rotation;
520
+ if (has(params.rotation)) l.rotation = params.rotation;
515
521
  if (params.name) l.name = params.name;
516
522
  (await parentOf(params)).appendChild(l);
517
523
  return summarize(l);
@@ -523,7 +529,7 @@ const handlers = {
523
529
  let n;
524
530
  if (params.node_id) {
525
531
  n = await node(params.node_id);
526
- if (!("fills" in n)) throw new Error("node " + params.node_id + " has no fills");
532
+ need(n, "fills", "has no fills", params.node_id);
527
533
  n.fills = [paint];
528
534
  } else {
529
535
  const size = await image.getSizeAsync();
@@ -549,7 +555,7 @@ const handlers = {
549
555
  if (params.font_size) t.fontSize = params.font_size;
550
556
  if (params.fill_color) t.fills = [{ type: "SOLID", color: hexToRGB(params.fill_color) }];
551
557
  if (params.line_height) t.lineHeight = { value: params.line_height, unit: "PIXELS" };
552
- if (params.letter_spacing !== undefined && params.letter_spacing !== null) {
558
+ if (has(params.letter_spacing)) {
553
559
  t.letterSpacing = { value: params.letter_spacing, unit: "PIXELS" };
554
560
  }
555
561
  if (params.text_align) t.textAlignHorizontal = params.text_align;
@@ -589,10 +595,10 @@ const handlers = {
589
595
  } else {
590
596
  throw new Error('set_fills needs color, gradient, or color: "none" to clear');
591
597
  }
592
- if (params.opacity !== undefined && params.opacity !== null) paint.opacity = params.opacity;
598
+ if (has(params.opacity)) paint.opacity = params.opacity;
593
599
  }
594
600
  for (const n of nodes) {
595
- if (!("fills" in n)) throw new Error("node " + n.id + " has no fills");
601
+ need(n, "fills", "has no fills");
596
602
  n.fills = clear ? [] : [paint];
597
603
  }
598
604
  return done(params, nodes);
@@ -602,7 +608,7 @@ const handlers = {
602
608
  const out = [];
603
609
  for (const item of params.items) {
604
610
  const n = await node(item.node_id);
605
- if (!("x" in n)) throw new Error("node " + item.node_id + " cannot be moved");
611
+ need(n, "x", "cannot be moved", item.node_id);
606
612
  n.x = item.x;
607
613
  n.y = item.y;
608
614
  out.push(n);
@@ -614,7 +620,7 @@ const handlers = {
614
620
  const out = [];
615
621
  for (const item of params.items) {
616
622
  const n = await node(item.node_id);
617
- if (!("resize" in n)) throw new Error("node " + item.node_id + " cannot be resized");
623
+ need(n, "resize", "cannot be resized", item.node_id);
618
624
  n.resize(item.width, item.height);
619
625
  out.push(n);
620
626
  }
@@ -633,17 +639,17 @@ const handlers = {
633
639
 
634
640
  async set_auto_layout(params) {
635
641
  const n = await node(params.node_id);
636
- if (!("layoutMode" in n)) throw new Error("node " + params.node_id + " does not support auto-layout");
642
+ need(n, "layoutMode", "does not support auto-layout", params.node_id);
637
643
  n.layoutMode = params.layout_mode;
638
644
  if (params.layout_mode === "NONE") return done(params, n);
639
- if (params.item_spacing !== undefined) n.itemSpacing = params.item_spacing;
640
- if (params.padding !== undefined) {
645
+ if (has(params.item_spacing)) n.itemSpacing = params.item_spacing;
646
+ if (has(params.padding)) {
641
647
  n.paddingTop = n.paddingRight = n.paddingBottom = n.paddingLeft = params.padding;
642
648
  }
643
- if (params.padding_top !== undefined) n.paddingTop = params.padding_top;
644
- if (params.padding_right !== undefined) n.paddingRight = params.padding_right;
645
- if (params.padding_bottom !== undefined) n.paddingBottom = params.padding_bottom;
646
- if (params.padding_left !== undefined) n.paddingLeft = params.padding_left;
649
+ if (has(params.padding_top)) n.paddingTop = params.padding_top;
650
+ if (has(params.padding_right)) n.paddingRight = params.padding_right;
651
+ if (has(params.padding_bottom)) n.paddingBottom = params.padding_bottom;
652
+ if (has(params.padding_left)) n.paddingLeft = params.padding_left;
647
653
  if (params.primary_axis_align) n.primaryAxisAlignItems = params.primary_axis_align;
648
654
  if (params.counter_axis_align) n.counterAxisAlignItems = params.counter_axis_align;
649
655
  if (params.primary_axis_sizing) n.primaryAxisSizingMode = params.primary_axis_sizing;
@@ -654,18 +660,18 @@ const handlers = {
654
660
  async set_corner_radius(params) {
655
661
  const nodes = await targets(params);
656
662
  for (const n of nodes) {
657
- if (params.radius !== undefined) {
658
- if (!("cornerRadius" in n)) throw new Error("node " + n.id + " has no corner radius");
663
+ if (has(params.radius)) {
664
+ need(n, "cornerRadius", "has no corner radius");
659
665
  n.cornerRadius = params.radius;
660
666
  }
661
667
  if (!("topLeftRadius" in n)) {
662
- if (params.radius === undefined) throw new Error("node " + n.id + " has no per-corner radius");
668
+ if (!has(params.radius)) throw new Error("node " + n.id + " has no per-corner radius");
663
669
  continue;
664
670
  }
665
- if (params.top_left !== undefined) n.topLeftRadius = params.top_left;
666
- if (params.top_right !== undefined) n.topRightRadius = params.top_right;
667
- if (params.bottom_right !== undefined) n.bottomRightRadius = params.bottom_right;
668
- if (params.bottom_left !== undefined) n.bottomLeftRadius = params.bottom_left;
671
+ if (has(params.top_left)) n.topLeftRadius = params.top_left;
672
+ if (has(params.top_right)) n.topRightRadius = params.top_right;
673
+ if (has(params.bottom_right)) n.bottomRightRadius = params.bottom_right;
674
+ if (has(params.bottom_left)) n.bottomLeftRadius = params.bottom_left;
669
675
  }
670
676
  return done(params, nodes);
671
677
  },
@@ -673,15 +679,15 @@ const handlers = {
673
679
  async set_strokes(params) {
674
680
  const nodes = await targets(params);
675
681
  for (const n of nodes) {
676
- if (!("strokes" in n)) throw new Error("node " + n.id + " has no strokes");
682
+ need(n, "strokes", "has no strokes");
677
683
  if (params.color && params.color !== "none") {
678
684
  const paint = { type: "SOLID", color: hexToRGB(params.color) };
679
- if (params.opacity !== undefined && params.opacity !== null) paint.opacity = params.opacity;
685
+ if (has(params.opacity)) paint.opacity = params.opacity;
680
686
  n.strokes = [paint];
681
687
  } else {
682
688
  n.strokes = [];
683
689
  }
684
- if (params.weight !== undefined && "strokeWeight" in n) n.strokeWeight = params.weight;
690
+ if (has(params.weight) && "strokeWeight" in n) n.strokeWeight = params.weight;
685
691
  if (params.align && "strokeAlign" in n) n.strokeAlign = params.align;
686
692
  }
687
693
  return done(params, nodes);
@@ -691,7 +697,7 @@ const handlers = {
691
697
  const nodes = await targets(params);
692
698
  const effects = buildEffects(params.effects);
693
699
  for (const n of nodes) {
694
- if (!("effects" in n)) throw new Error("node " + n.id + " has no effects");
700
+ need(n, "effects", "has no effects");
695
701
  n.effects = effects;
696
702
  }
697
703
  return done(params, nodes);
@@ -729,10 +735,10 @@ const handlers = {
729
735
  n.fontName = font;
730
736
  }
731
737
  if (params.font_size) n.fontSize = params.font_size;
732
- if (params.line_height !== undefined && params.line_height !== null) {
738
+ if (has(params.line_height)) {
733
739
  n.lineHeight = { value: params.line_height, unit: "PIXELS" };
734
740
  }
735
- if (params.letter_spacing !== undefined && params.letter_spacing !== null) {
741
+ if (has(params.letter_spacing)) {
736
742
  n.letterSpacing = { value: params.letter_spacing, unit: "PIXELS" };
737
743
  }
738
744
  if (params.text_align) n.textAlignHorizontal = params.text_align;
@@ -748,7 +754,7 @@ const handlers = {
748
754
  for (const item of params.items) {
749
755
  try {
750
756
  const target = await node(item.node_id);
751
- if (!("exportAsync" in target)) throw new Error("node " + item.node_id + " cannot be exported");
757
+ need(target, "exportAsync", "cannot be exported", item.node_id);
752
758
  const format = (item.format || "PNG").toUpperCase();
753
759
  let settings;
754
760
  if (format === "SVG") {
@@ -787,7 +793,7 @@ const handlers = {
787
793
  if (params.node_id) scope = await node(params.node_id);
788
794
  else if (params.page) scope = await resolvePage(params.page);
789
795
  else scope = figma.currentPage;
790
- if (!("findAll" in scope)) throw new Error("node " + scope.id + " has no children to search");
796
+ need(scope, "findAll", "has no children to search");
791
797
  const name = params.name ? params.name.toLowerCase() : null;
792
798
  const text = params.text ? params.text.toLowerCase() : null;
793
799
  const types = params.types && params.types.length ? params.types : null;
@@ -804,7 +810,7 @@ const handlers = {
804
810
  const hex = solidFillHex(n);
805
811
  if (!hex || hex.toLowerCase() !== fill) return false;
806
812
  }
807
- if (fontSize !== undefined && fontSize !== null) {
813
+ if (has(fontSize)) {
808
814
  if (n.type !== "TEXT" || val(n.fontSize) !== fontSize) return false;
809
815
  }
810
816
  if (fontStyle) {
@@ -858,7 +864,7 @@ const handlers = {
858
864
 
859
865
  async append_children(params) {
860
866
  const parent = await node(params.parent_id);
861
- if (!("appendChild" in parent)) throw new Error("node " + params.parent_id + " cannot have children");
867
+ need(parent, "appendChild", "cannot have children", params.parent_id);
862
868
  const moved = [];
863
869
  const warnings = [];
864
870
  let index = params.index;
@@ -872,7 +878,7 @@ const handlers = {
872
878
  "; Figma renames detached variants to <Set>/<Variant>",
873
879
  );
874
880
  }
875
- if (index === undefined || index === null) {
881
+ if (!has(index)) {
876
882
  parent.appendChild(n);
877
883
  } else {
878
884
  parent.insertChild(index++, n);
@@ -884,15 +890,15 @@ const handlers = {
884
890
 
885
891
  async clone_node(params) {
886
892
  const n = await node(params.node_id);
887
- if (!("clone" in n)) throw new Error("node " + params.node_id + " cannot be cloned");
893
+ need(n, "clone", "cannot be cloned", params.node_id);
888
894
  const copy = n.clone();
889
895
  if (params.parent_id) {
890
896
  const p = await node(params.parent_id);
891
- if (!("appendChild" in p)) throw new Error("node " + params.parent_id + " cannot have children");
897
+ need(p, "appendChild", "cannot have children", params.parent_id);
892
898
  p.appendChild(copy);
893
899
  }
894
- if (params.x !== undefined) copy.x = params.x;
895
- if (params.y !== undefined) copy.y = params.y;
900
+ if (has(params.x)) copy.x = params.x;
901
+ if (has(params.y)) copy.y = params.y;
896
902
  if (params.name) copy.name = params.name;
897
903
  return summarize(copy);
898
904
  },
@@ -943,8 +949,8 @@ const handlers = {
943
949
  const c = await node(params.component_id);
944
950
  if (c.type !== "COMPONENT") throw new Error("node " + params.component_id + " is " + c.type + ", not a COMPONENT");
945
951
  const inst = c.createInstance();
946
- if (params.x !== undefined) inst.x = params.x;
947
- if (params.y !== undefined) inst.y = params.y;
952
+ if (has(params.x)) inst.x = params.x;
953
+ if (has(params.y)) inst.y = params.y;
948
954
  (await parentOf(params)).appendChild(inst);
949
955
  return summarize(inst);
950
956
  },
@@ -973,7 +979,7 @@ const handlers = {
973
979
  // Figma requires a default of the matching kind; pick the empty one
974
980
  // rather than failing a call that only omitted it.
975
981
  let def = params.default_value;
976
- if (def === undefined || def === null) def = type === "BOOLEAN" ? false : "";
982
+ if (!has(def)) def = type === "BOOLEAN" ? false : "";
977
983
  const key = c.addComponentProperty(params.name, type, def);
978
984
  if (params.bind_node_id) {
979
985
  const t = await node(params.bind_node_id);
@@ -1036,7 +1042,7 @@ const handlers = {
1036
1042
  const s = figma.createPaintStyle();
1037
1043
  s.name = params.name;
1038
1044
  const paint = { type: "SOLID", color: hexToRGB(params.color) };
1039
- if (params.opacity !== undefined && params.opacity !== null) paint.opacity = params.opacity;
1045
+ if (has(params.opacity)) paint.opacity = params.opacity;
1040
1046
  s.paints = [paint];
1041
1047
  return { id: s.id, name: s.name };
1042
1048
  },
@@ -1130,7 +1136,7 @@ const handlers = {
1130
1136
  const c = await figma.variables.getVariableCollectionByIdAsync(params.collection_id);
1131
1137
  if (!c) throw new Error("variable collection not found: " + params.collection_id);
1132
1138
  const v = figma.variables.createVariable(params.name, c, params.type);
1133
- if (params.value !== undefined && params.value !== null) {
1139
+ if (has(params.value)) {
1134
1140
  v.setValueForMode(c.defaultModeId, variableValue(v, params.value));
1135
1141
  }
1136
1142
  return { id: v.id, name: v.name, resolvedType: v.resolvedType, collectionId: c.id };
@@ -1152,7 +1158,7 @@ const handlers = {
1152
1158
  const field = params.field;
1153
1159
  for (const n of nodes) {
1154
1160
  if (field === "fills" || field === "strokes") {
1155
- if (!(field in n)) throw new Error("node " + n.id + " has no " + field);
1161
+ need(n, field, "has no " + field);
1156
1162
  const paints = n[field].length ? n[field] : [{ type: "SOLID", color: { r: 0, g: 0, b: 0 } }];
1157
1163
  n[field] = [figma.variables.setBoundVariableForPaint(paints[0], "color", v)].concat(paints.slice(1));
1158
1164
  } else {
@@ -1270,7 +1276,7 @@ const handlers = {
1270
1276
  } else {
1271
1277
  target = figma.currentPage;
1272
1278
  }
1273
- if (!("exportAsync" in target)) throw new Error("node " + target.id + " cannot be exported");
1279
+ need(target, "exportAsync", "cannot be exported");
1274
1280
  // With dynamic-page access a node can be reachable before its page is
1275
1281
  // loaded, and exporting then yields a blank image with no error.
1276
1282
  let owner = target;
@@ -16,15 +16,19 @@
16
16
  sans-serif;
17
17
  margin: 0;
18
18
  padding: 10px;
19
- color: #2c2c34;
20
- background: linear-gradient(160deg, #f6f7fb 0%, #eef0f7 100%);
19
+ color: var(--figma-color-text, #2c2c34);
20
+ background: linear-gradient(
21
+ 160deg,
22
+ var(--figma-color-bg-secondary, #f6f7fb) 0%,
23
+ var(--figma-color-bg-secondary, #eef0f7) 100%
24
+ );
21
25
  display: flex;
22
26
  flex-direction: column;
23
27
  }
24
28
 
25
29
  .card {
26
- background: #fff;
27
- border: 1px solid #e6e8f0;
30
+ background: var(--figma-color-bg, #fff);
31
+ border: 1px solid var(--figma-color-border, #e6e8f0);
28
32
  border-radius: 9px;
29
33
  padding: 7px 9px;
30
34
  box-shadow: 0 1px 2px rgba(30, 34, 60, 0.04);
@@ -37,7 +41,7 @@
37
41
  cursor: pointer;
38
42
  font-weight: 600;
39
43
  font-size: 13px;
40
- color: #1f2330;
44
+ color: var(--figma-color-text, #1f2330);
41
45
  }
42
46
 
43
47
  #dot {
@@ -45,7 +49,7 @@
45
49
  width: 9px;
46
50
  height: 9px;
47
51
  border-radius: 50%;
48
- background: #e0555b;
52
+ background: var(--figma-color-icon-danger, #e0555b);
49
53
  box-shadow: 0 0 0 3px rgba(224, 85, 91, 0.15);
50
54
  transition:
51
55
  background 0.2s,
@@ -53,7 +57,7 @@
53
57
  }
54
58
 
55
59
  #dot.on {
56
- background: #22a06b;
60
+ background: var(--figma-color-icon-success, #22a06b);
57
61
  box-shadow: 0 0 0 3px rgba(34, 160, 107, 0.15);
58
62
  }
59
63
 
@@ -65,15 +69,15 @@
65
69
  border: 0;
66
70
  border-radius: 5px;
67
71
  background: transparent;
68
- color: #8288a0;
72
+ color: var(--figma-color-text-secondary, #8288a0);
69
73
  font-size: 13px;
70
74
  line-height: 1;
71
75
  cursor: pointer;
72
76
  }
73
77
 
74
78
  #collapse:hover {
75
- background: #eef0f7;
76
- color: #2c2c34;
79
+ background: var(--figma-color-bg-hover, #eef0f7);
80
+ color: var(--figma-color-text, #2c2c34);
77
81
  }
78
82
 
79
83
  /* Collapsed: the dot only, at Figma's 70px minimum width. */
@@ -96,7 +100,7 @@
96
100
  }
97
101
 
98
102
  #hint {
99
- color: #6b6f7d;
103
+ color: var(--figma-color-text-secondary, #6b6f7d);
100
104
  margin-top: 5px;
101
105
  font-size: 10px;
102
106
  line-height: 1.35;
@@ -105,7 +109,7 @@
105
109
  #result {
106
110
  display: none;
107
111
  margin-top: 10px;
108
- border-top: 1px solid #eceef5;
112
+ border-top: 1px solid var(--figma-color-border, #eceef5);
109
113
  padding-top: 9px;
110
114
  }
111
115
 
@@ -123,7 +127,7 @@
123
127
  .res-title {
124
128
  font-weight: 600;
125
129
  font-size: 11px;
126
- color: #1f2330;
130
+ color: var(--figma-color-text, #1f2330);
127
131
  }
128
132
 
129
133
  .res-list {
@@ -139,9 +143,9 @@
139
143
  align-items: center;
140
144
  gap: 6px;
141
145
  padding: 5px 7px;
142
- border: 1px solid #e6e8f0;
146
+ border: 1px solid var(--figma-color-border, #e6e8f0);
143
147
  border-radius: 7px;
144
- background: #fbfcfe;
148
+ background: var(--figma-color-bg-secondary, #fbfcfe);
145
149
  }
146
150
 
147
151
  .res-name {
@@ -151,22 +155,22 @@
151
155
  text-overflow: ellipsis;
152
156
  white-space: nowrap;
153
157
  font-size: 11px;
154
- color: #2c2c34;
158
+ color: var(--figma-color-text, #2c2c34);
155
159
  }
156
160
 
157
161
  .res-type {
158
162
  flex: none;
159
163
  font-size: 9px;
160
- color: #a0a4b0;
164
+ color: var(--figma-color-text-tertiary, #a0a4b0);
161
165
  text-transform: uppercase;
162
166
  letter-spacing: 0.03em;
163
167
  }
164
168
 
165
169
  .copy-btn {
166
170
  flex: none;
167
- border: 1px solid #d6d9e6;
168
- background: #fff;
169
- color: #4b5168;
171
+ border: 1px solid var(--figma-color-border-strong, #d6d9e6);
172
+ background: var(--figma-color-bg, #fff);
173
+ color: var(--figma-color-text-secondary, #4b5168);
170
174
  border-radius: 6px;
171
175
  padding: 2px 8px;
172
176
  font-size: 10px;
@@ -174,13 +178,13 @@
174
178
  }
175
179
 
176
180
  .copy-btn:hover {
177
- background: #f0f2f8;
181
+ background: var(--figma-color-bg-hover, #f0f2f8);
178
182
  }
179
183
 
180
184
  .copy-btn.done {
181
- color: #22a06b;
182
- border-color: #bfe6d3;
183
- background: #f0faf5;
185
+ color: var(--figma-color-text-success, #22a06b);
186
+ border-color: var(--figma-color-border-success, #bfe6d3);
187
+ background: var(--figma-color-bg-success-tertiary, #f0faf5);
184
188
  }
185
189
 
186
190
  .copy-all {
@@ -196,9 +200,9 @@
196
200
 
197
201
  .filter-btn {
198
202
  flex: none;
199
- border: 1px solid #d6d9e6;
200
- background: #fff;
201
- color: #6b6f7d;
203
+ border: 1px solid var(--figma-color-border-strong, #d6d9e6);
204
+ background: var(--figma-color-bg, #fff);
205
+ color: var(--figma-color-text-secondary, #6b6f7d);
202
206
  border-radius: 6px;
203
207
  padding: 3px 9px;
204
208
  font-size: 10px;
@@ -206,32 +210,32 @@
206
210
  }
207
211
 
208
212
  .filter-btn:hover {
209
- background: #f0f2f8;
213
+ background: var(--figma-color-bg-hover, #f0f2f8);
210
214
  }
211
215
 
212
216
  .filter-btn.on {
213
- background: #2c2c34;
214
- border-color: #2c2c34;
215
- color: #fff;
217
+ background: var(--figma-color-bg-inverse, #2c2c34);
218
+ border-color: var(--figma-color-bg-inverse, #2c2c34);
219
+ color: var(--figma-color-text-oninverse, #fff);
216
220
  }
217
221
 
218
222
  .res-empty {
219
223
  font-size: 11px;
220
- color: #a0a4b0;
224
+ color: var(--figma-color-text-tertiary, #a0a4b0);
221
225
  padding: 6px 2px;
222
226
  }
223
227
 
224
228
  .key-prompt {
225
229
  margin-bottom: 8px;
226
230
  padding: 7px 8px;
227
- border: 1px solid #ffe0a6;
228
- background: #fff9ec;
231
+ border: 1px solid var(--figma-color-border-warning, #ffe0a6);
232
+ background: var(--figma-color-bg-warning-tertiary, #fff9ec);
229
233
  border-radius: 7px;
230
234
  }
231
235
 
232
236
  .key-note {
233
237
  font-size: 10px;
234
- color: #8a6d3b;
238
+ color: var(--figma-color-text-warning, #8a6d3b);
235
239
  line-height: 1.4;
236
240
  margin-bottom: 5px;
237
241
  }
@@ -244,7 +248,9 @@
244
248
  .key-input {
245
249
  flex: 1;
246
250
  min-width: 0;
247
- border: 1px solid #d6d9e6;
251
+ border: 1px solid var(--figma-color-border-strong, #d6d9e6);
252
+ background: var(--figma-color-bg, #fff);
253
+ color: var(--figma-color-text, #000);
248
254
  border-radius: 6px;
249
255
  padding: 3px 6px;
250
256
  font-size: 10px;
@@ -252,8 +258,9 @@
252
258
 
253
259
  .key-save {
254
260
  flex: none;
255
- border: 1px solid #d6d9e6;
256
- background: #fff;
261
+ border: 1px solid var(--figma-color-border-strong, #d6d9e6);
262
+ background: var(--figma-color-bg, #fff);
263
+ color: var(--figma-color-text, #000);
257
264
  border-radius: 6px;
258
265
  padding: 3px 10px;
259
266
  font-size: 10px;
@@ -261,24 +268,24 @@
261
268
  }
262
269
 
263
270
  .key-save:hover {
264
- background: #f0f2f8;
271
+ background: var(--figma-color-bg-hover, #f0f2f8);
265
272
  }
266
273
 
267
274
  #credit {
268
275
  margin-top: auto;
269
276
  padding-top: 7px;
270
277
  text-align: center;
271
- color: #a0a4b0;
278
+ color: var(--figma-color-text-tertiary, #a0a4b0);
272
279
  font-size: 10px;
273
280
  }
274
281
 
275
282
  #version {
276
- color: #8288a0;
283
+ color: var(--figma-color-text-secondary, #8288a0);
277
284
  margin-right: 4px;
278
285
  }
279
286
 
280
287
  #credit a {
281
- color: #8288a0;
288
+ color: var(--figma-color-text-secondary, #8288a0);
282
289
  text-decoration: none;
283
290
  }
284
291
 
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "figrelay",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "scripts": {
5
5
  "prepublishOnly": "cp ../README.md ./README.md"
6
6
  },