@rogieking/figui3 2.0.4 → 2.0.5

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/components.css CHANGED
@@ -2620,6 +2620,129 @@ fig-input-angle {
2620
2620
  }
2621
2621
  }
2622
2622
 
2623
+ /* Layer */
2624
+ fig-layer {
2625
+ --indent: var(--spacer-4);
2626
+ display: block;
2627
+ color: var(--figma-color-text);
2628
+ position: relative;
2629
+ user-select: none;
2630
+ border-radius: var(--radius-medium);
2631
+
2632
+ &:has(fig-layer)[open]:not([open="false"]),
2633
+ &:has(fig-layer):hover {
2634
+ & > .fig-layer-row::before {
2635
+ visibility: visible;
2636
+ }
2637
+ }
2638
+
2639
+ &:not(:has(.fig-layer-icon)) {
2640
+ & > .fig-layer-row {
2641
+ padding-left: var(--spacer-3);
2642
+ }
2643
+ }
2644
+
2645
+ & > .fig-layer-row {
2646
+ display: flex;
2647
+ align-items: center;
2648
+ gap: var(--spacer-1);
2649
+ padding: var(--spacer-1) var(--spacer-2);
2650
+ margin-left: var(--spacer-2);
2651
+ border-radius: var(--radius-medium);
2652
+ cursor: pointer;
2653
+ position: relative;
2654
+
2655
+ /* Chevron using mask-image approach like details */
2656
+ &::before {
2657
+ content: "";
2658
+ mask-image: var(--icon-chevron);
2659
+ mask-size: contain;
2660
+ mask-repeat: no-repeat;
2661
+ mask-position: center;
2662
+ display: flex;
2663
+ visibility: hidden;
2664
+ margin-left: calc(-1 * (var(--spacer-3) + var(--spacer-1) + 2px));
2665
+ margin-right: calc(-1 * (var(--spacer-1) + 2px));
2666
+ background: var(--figma-color-text-tertiary);
2667
+ width: var(--spacer-3);
2668
+ height: var(--spacer-3);
2669
+ flex-shrink: 0;
2670
+ transform: rotate(-90deg);
2671
+ transition: transform 0.15s;
2672
+ }
2673
+
2674
+ &:hover {
2675
+ background: var(--figma-color-bg-secondary);
2676
+
2677
+ .fig-layer-actions {
2678
+ opacity: 1;
2679
+ }
2680
+ }
2681
+
2682
+ /* Layer icon */
2683
+ .fig-layer-icon {
2684
+ flex-shrink: 0;
2685
+ width: var(--spacer-3);
2686
+ height: var(--spacer-3);
2687
+ color: var(--figma-color-icon);
2688
+ }
2689
+
2690
+ > label {
2691
+ flex: 1;
2692
+ min-width: 0;
2693
+ overflow: hidden;
2694
+ text-overflow: ellipsis;
2695
+ white-space: nowrap;
2696
+ cursor: pointer;
2697
+ color: var(--figma-color-text);
2698
+ }
2699
+ }
2700
+
2701
+ .fig-layer-actions {
2702
+ display: flex;
2703
+ margin-right: calc(-1 * var(--spacer-1));
2704
+ gap: 0;
2705
+ opacity: 0;
2706
+ transition: opacity 0.15s;
2707
+ flex-shrink: 0;
2708
+
2709
+ > * {
2710
+ flex-shrink: 0;
2711
+ }
2712
+ }
2713
+
2714
+ /* Nested layers indentation */
2715
+ > fig-layer {
2716
+ padding-left: var(--indent);
2717
+ margin-top: 1px;
2718
+ }
2719
+
2720
+ /* Collapsed state - hide children */
2721
+ &:not([open]) > fig-layer,
2722
+ &[open="false"] > fig-layer {
2723
+ display: none;
2724
+ }
2725
+
2726
+ /* Rotate chevron when open */
2727
+ &[open]:not([open="false"]) .fig-layer-row::before {
2728
+ transform: rotate(0deg);
2729
+ }
2730
+
2731
+ /* Dimmed when not visible */
2732
+ &[visible="false"] > .fig-layer-row {
2733
+ & > label {
2734
+ color: var(--figma-color-text-tertiary);
2735
+ }
2736
+ }
2737
+
2738
+ /* Selected state */
2739
+ &[selected]:not([selected="false"]) {
2740
+ & > .fig-layer-row {
2741
+ background: var(--figma-color-bg-selected);
2742
+ }
2743
+ }
2744
+ }
2745
+
2623
2746
  /* Shimmer */
2624
2747
  fig-shimmer {
2625
2748
  display: contents;
package/example.html CHANGED
@@ -178,6 +178,7 @@
178
178
  <a href="#input-joystick">Input Joystick</a>
179
179
  <a href="#input-number">Input Number</a>
180
180
  <a href="#input-text">Input Text</a>
181
+ <a href="#layer">Layer</a>
181
182
  <a href="#popover">Popover</a>
182
183
  <a href="#radio">Radio</a>
183
184
  <a href="#segmented-control">Segmented Control</a>
@@ -194,6 +195,7 @@
194
195
  <a href="#vstack">VStack</a>
195
196
  <a href="#hr">HR</a>
196
197
  <a href="#code">Code</a>
198
+ <a href="#details">Details</a>
197
199
  </div>
198
200
  <div class="theme-switch">
199
201
  <fig-button id="theme-light-btn"
@@ -1176,6 +1178,505 @@
1176
1178
  </section>
1177
1179
  <hr>
1178
1180
 
1181
+ <!-- Layer -->
1182
+ <section id="layer">
1183
+ <h2>Layer</h2>
1184
+ <p class="description">A hierarchical layer component for displaying nested content with expand/collapse and
1185
+ visibility states.</p>
1186
+
1187
+ <h3>Single Layer</h3>
1188
+ <fig-layer>
1189
+ <div class="fig-layer-row">
1190
+ <svg class="fig-layer-icon"
1191
+ width="16"
1192
+ height="16"
1193
+ viewBox="0 0 16 16"
1194
+ fill="none">
1195
+ <rect x="4"
1196
+ y="4"
1197
+ width="8"
1198
+ height="8"
1199
+ rx="1"
1200
+ stroke="currentColor"
1201
+ stroke-width="1.25" />
1202
+ </svg>
1203
+ <label>Rectangle</label>
1204
+ </div>
1205
+ </fig-layer>
1206
+
1207
+ <h3>Without Icon</h3>
1208
+ <fig-layer>
1209
+ <div class="fig-layer-row">
1210
+ <label>Layer with no icon</label>
1211
+ </div>
1212
+ </fig-layer>
1213
+
1214
+ <h3>Nested Layers (Expanded)</h3>
1215
+ <fig-layer open>
1216
+ <div class="fig-layer-row">
1217
+ <svg class="fig-layer-icon"
1218
+ width="16"
1219
+ height="16"
1220
+ viewBox="0 0 16 16"
1221
+ fill="none">
1222
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1223
+ stroke="currentColor"
1224
+ stroke-width="1.25" />
1225
+ </svg>
1226
+ <label>Frame</label>
1227
+ </div>
1228
+ <fig-layer>
1229
+ <div class="fig-layer-row">
1230
+ <svg class="fig-layer-icon"
1231
+ width="16"
1232
+ height="16"
1233
+ viewBox="0 0 16 16"
1234
+ fill="none">
1235
+ <rect x="4"
1236
+ y="4"
1237
+ width="8"
1238
+ height="8"
1239
+ rx="1"
1240
+ stroke="currentColor"
1241
+ stroke-width="1.25" />
1242
+ </svg>
1243
+ <label>Rectangle</label>
1244
+ </div>
1245
+ </fig-layer>
1246
+ <fig-layer>
1247
+ <div class="fig-layer-row">
1248
+ <svg class="fig-layer-icon"
1249
+ width="16"
1250
+ height="16"
1251
+ viewBox="0 0 16 16"
1252
+ fill="none">
1253
+ <circle cx="8"
1254
+ cy="8"
1255
+ r="4"
1256
+ stroke="currentColor"
1257
+ stroke-width="1.25" />
1258
+ </svg>
1259
+ <label>Ellipse</label>
1260
+ </div>
1261
+ </fig-layer>
1262
+ </fig-layer>
1263
+
1264
+ <h3>Collapsed Layers</h3>
1265
+ <fig-layer open="false">
1266
+ <div class="fig-layer-row">
1267
+ <svg class="fig-layer-icon"
1268
+ width="16"
1269
+ height="16"
1270
+ viewBox="0 0 16 16"
1271
+ fill="none">
1272
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1273
+ stroke="currentColor"
1274
+ stroke-width="1.25" />
1275
+ </svg>
1276
+ <label>Group (collapsed - click chevron to expand)</label>
1277
+ </div>
1278
+ <fig-layer>
1279
+ <div class="fig-layer-row">
1280
+ <svg class="fig-layer-icon"
1281
+ width="16"
1282
+ height="16"
1283
+ viewBox="0 0 16 16"
1284
+ fill="none">
1285
+ <rect x="4"
1286
+ y="4"
1287
+ width="8"
1288
+ height="8"
1289
+ rx="1"
1290
+ stroke="currentColor"
1291
+ stroke-width="1.25" />
1292
+ </svg>
1293
+ <label>Hidden Child</label>
1294
+ </div>
1295
+ </fig-layer>
1296
+ </fig-layer>
1297
+
1298
+ <h3>Hidden Layer (Dimmed)</h3>
1299
+ <fig-layer visible="false">
1300
+ <div class="fig-layer-row">
1301
+ <svg class="fig-layer-icon"
1302
+ width="16"
1303
+ height="16"
1304
+ viewBox="0 0 16 16"
1305
+ fill="none">
1306
+ <rect x="4"
1307
+ y="4"
1308
+ width="8"
1309
+ height="8"
1310
+ rx="1"
1311
+ stroke="currentColor"
1312
+ stroke-width="1.25" />
1313
+ </svg>
1314
+ <label>Hidden Rectangle</label>
1315
+ </div>
1316
+ </fig-layer>
1317
+
1318
+ <h3>With Action Buttons</h3>
1319
+ <fig-layer>
1320
+ <div class="fig-layer-row">
1321
+ <svg class="fig-layer-icon"
1322
+ width="16"
1323
+ height="16"
1324
+ viewBox="0 0 16 16"
1325
+ fill="none">
1326
+ <rect x="4"
1327
+ y="4"
1328
+ width="8"
1329
+ height="8"
1330
+ rx="1"
1331
+ stroke="currentColor"
1332
+ stroke-width="1.25" />
1333
+ </svg>
1334
+ <label>Layer with actions (hover to see)</label>
1335
+ <div class="fig-layer-actions">
1336
+ <fig-button variant="ghost"
1337
+ type="toggle"
1338
+ icon>
1339
+ <svg width="16"
1340
+ height="16"
1341
+ viewBox="0 0 16 16"
1342
+ fill="none">
1343
+ <path d="M8 3V8M8 8V13M8 8H13M8 8H3"
1344
+ stroke="currentColor"
1345
+ stroke-width="1.5"
1346
+ stroke-linecap="round" />
1347
+ </svg>
1348
+ </fig-button>
1349
+ <fig-button variant="ghost"
1350
+ type="toggle"
1351
+ icon>
1352
+ <svg width="16"
1353
+ height="16"
1354
+ viewBox="0 0 16 16"
1355
+ fill="none">
1356
+ <path d="M4 8H12"
1357
+ stroke="currentColor"
1358
+ stroke-width="1.5"
1359
+ stroke-linecap="round" />
1360
+ </svg>
1361
+ </fig-button>
1362
+ </div>
1363
+ </div>
1364
+ </fig-layer>
1365
+
1366
+ <h3>Deep Nesting</h3>
1367
+ <fig-layer open>
1368
+ <div class="fig-layer-row">
1369
+ <svg class="fig-layer-icon"
1370
+ width="16"
1371
+ height="16"
1372
+ viewBox="0 0 16 16"
1373
+ fill="none">
1374
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1375
+ stroke="currentColor"
1376
+ stroke-width="1.25" />
1377
+ </svg>
1378
+ <label>Page</label>
1379
+ </div>
1380
+ <fig-layer open>
1381
+ <div class="fig-layer-row">
1382
+ <svg class="fig-layer-icon"
1383
+ width="16"
1384
+ height="16"
1385
+ viewBox="0 0 16 16"
1386
+ fill="none">
1387
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1388
+ stroke="currentColor"
1389
+ stroke-width="1.25" />
1390
+ </svg>
1391
+ <label>Frame</label>
1392
+ </div>
1393
+ <fig-layer>
1394
+ <div class="fig-layer-row">
1395
+ <svg class="fig-layer-icon"
1396
+ width="16"
1397
+ height="16"
1398
+ viewBox="0 0 16 16"
1399
+ fill="none">
1400
+ <rect x="4"
1401
+ y="4"
1402
+ width="8"
1403
+ height="8"
1404
+ rx="1"
1405
+ stroke="currentColor"
1406
+ stroke-width="1.25" />
1407
+ </svg>
1408
+ <label>Button</label>
1409
+ </div>
1410
+ </fig-layer>
1411
+ <fig-layer>
1412
+ <div class="fig-layer-row">
1413
+ <svg class="fig-layer-icon"
1414
+ width="16"
1415
+ height="16"
1416
+ viewBox="0 0 16 16"
1417
+ fill="none">
1418
+ <path d="M3 5H13M3 8H13M3 11H10"
1419
+ stroke="currentColor"
1420
+ stroke-width="1.25"
1421
+ stroke-linecap="round" />
1422
+ </svg>
1423
+ <label>Text</label>
1424
+ </div>
1425
+ </fig-layer>
1426
+ </fig-layer>
1427
+ </fig-layer>
1428
+
1429
+ <h2>Selected Layers</h2>
1430
+
1431
+ <h3>Single Layer (Selected)</h3>
1432
+ <fig-layer selected>
1433
+ <div class="fig-layer-row">
1434
+ <svg class="fig-layer-icon"
1435
+ width="16"
1436
+ height="16"
1437
+ viewBox="0 0 16 16"
1438
+ fill="none">
1439
+ <rect x="4"
1440
+ y="4"
1441
+ width="8"
1442
+ height="8"
1443
+ rx="1"
1444
+ stroke="currentColor"
1445
+ stroke-width="1.25" />
1446
+ </svg>
1447
+ <label>Rectangle</label>
1448
+ </div>
1449
+ </fig-layer>
1450
+
1451
+ <h3>Without Icon (Selected)</h3>
1452
+ <fig-layer selected>
1453
+ <div class="fig-layer-row">
1454
+ <label>Layer with no icon</label>
1455
+ </div>
1456
+ </fig-layer>
1457
+
1458
+ <h3>Nested Layers (Selected Parent)</h3>
1459
+ <fig-layer open
1460
+ selected>
1461
+ <div class="fig-layer-row">
1462
+ <svg class="fig-layer-icon"
1463
+ width="16"
1464
+ height="16"
1465
+ viewBox="0 0 16 16"
1466
+ fill="none">
1467
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1468
+ stroke="currentColor"
1469
+ stroke-width="1.25" />
1470
+ </svg>
1471
+ <label>Frame</label>
1472
+ </div>
1473
+ <fig-layer>
1474
+ <div class="fig-layer-row">
1475
+ <svg class="fig-layer-icon"
1476
+ width="16"
1477
+ height="16"
1478
+ viewBox="0 0 16 16"
1479
+ fill="none">
1480
+ <rect x="4"
1481
+ y="4"
1482
+ width="8"
1483
+ height="8"
1484
+ rx="1"
1485
+ stroke="currentColor"
1486
+ stroke-width="1.25" />
1487
+ </svg>
1488
+ <label>Rectangle</label>
1489
+ </div>
1490
+ </fig-layer>
1491
+ <fig-layer>
1492
+ <div class="fig-layer-row">
1493
+ <svg class="fig-layer-icon"
1494
+ width="16"
1495
+ height="16"
1496
+ viewBox="0 0 16 16"
1497
+ fill="none">
1498
+ <circle cx="8"
1499
+ cy="8"
1500
+ r="4"
1501
+ stroke="currentColor"
1502
+ stroke-width="1.25" />
1503
+ </svg>
1504
+ <label>Ellipse</label>
1505
+ </div>
1506
+ </fig-layer>
1507
+ </fig-layer>
1508
+
1509
+ <h3>Collapsed Layers (Selected)</h3>
1510
+ <fig-layer open="false"
1511
+ selected>
1512
+ <div class="fig-layer-row">
1513
+ <svg class="fig-layer-icon"
1514
+ width="16"
1515
+ height="16"
1516
+ viewBox="0 0 16 16"
1517
+ fill="none">
1518
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1519
+ stroke="currentColor"
1520
+ stroke-width="1.25" />
1521
+ </svg>
1522
+ <label>Group (collapsed - click chevron to expand)</label>
1523
+ </div>
1524
+ <fig-layer>
1525
+ <div class="fig-layer-row">
1526
+ <svg class="fig-layer-icon"
1527
+ width="16"
1528
+ height="16"
1529
+ viewBox="0 0 16 16"
1530
+ fill="none">
1531
+ <rect x="4"
1532
+ y="4"
1533
+ width="8"
1534
+ height="8"
1535
+ rx="1"
1536
+ stroke="currentColor"
1537
+ stroke-width="1.25" />
1538
+ </svg>
1539
+ <label>Hidden Child</label>
1540
+ </div>
1541
+ </fig-layer>
1542
+ </fig-layer>
1543
+
1544
+ <h3>Hidden Layer (Selected)</h3>
1545
+ <fig-layer visible="false"
1546
+ selected>
1547
+ <div class="fig-layer-row">
1548
+ <svg class="fig-layer-icon"
1549
+ width="16"
1550
+ height="16"
1551
+ viewBox="0 0 16 16"
1552
+ fill="none">
1553
+ <rect x="4"
1554
+ y="4"
1555
+ width="8"
1556
+ height="8"
1557
+ rx="1"
1558
+ stroke="currentColor"
1559
+ stroke-width="1.25" />
1560
+ </svg>
1561
+ <label>Hidden Rectangle</label>
1562
+ </div>
1563
+ </fig-layer>
1564
+
1565
+ <h3>With Action Buttons (Selected)</h3>
1566
+ <fig-layer selected>
1567
+ <div class="fig-layer-row">
1568
+ <svg class="fig-layer-icon"
1569
+ width="16"
1570
+ height="16"
1571
+ viewBox="0 0 16 16"
1572
+ fill="none">
1573
+ <rect x="4"
1574
+ y="4"
1575
+ width="8"
1576
+ height="8"
1577
+ rx="1"
1578
+ stroke="currentColor"
1579
+ stroke-width="1.25" />
1580
+ </svg>
1581
+ <label>Layer with actions (hover to see)</label>
1582
+ <div class="fig-layer-actions">
1583
+ <fig-button variant="ghost"
1584
+ type="toggle"
1585
+ icon>
1586
+ <svg width="16"
1587
+ height="16"
1588
+ viewBox="0 0 16 16"
1589
+ fill="none">
1590
+ <path d="M8 3V8M8 8V13M8 8H13M8 8H3"
1591
+ stroke="currentColor"
1592
+ stroke-width="1.5"
1593
+ stroke-linecap="round" />
1594
+ </svg>
1595
+ </fig-button>
1596
+ <fig-button variant="ghost"
1597
+ type="toggle"
1598
+ icon>
1599
+ <svg width="16"
1600
+ height="16"
1601
+ viewBox="0 0 16 16"
1602
+ fill="none">
1603
+ <path d="M4 8H12"
1604
+ stroke="currentColor"
1605
+ stroke-width="1.5"
1606
+ stroke-linecap="round" />
1607
+ </svg>
1608
+ </fig-button>
1609
+ </div>
1610
+ </div>
1611
+ </fig-layer>
1612
+
1613
+ <h3>Deep Nesting (Selected Child)</h3>
1614
+ <fig-layer open>
1615
+ <div class="fig-layer-row">
1616
+ <svg class="fig-layer-icon"
1617
+ width="16"
1618
+ height="16"
1619
+ viewBox="0 0 16 16"
1620
+ fill="none">
1621
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1622
+ stroke="currentColor"
1623
+ stroke-width="1.25" />
1624
+ </svg>
1625
+ <label>Page</label>
1626
+ </div>
1627
+ <fig-layer open>
1628
+ <div class="fig-layer-row">
1629
+ <svg class="fig-layer-icon"
1630
+ width="16"
1631
+ height="16"
1632
+ viewBox="0 0 16 16"
1633
+ fill="none">
1634
+ <path d="M2 5C2 3.89543 2.89543 3 4 3H12C13.1046 3 14 3.89543 14 5V11C14 12.1046 13.1046 13 12 13H4C2.89543 13 2 12.1046 2 11V5Z"
1635
+ stroke="currentColor"
1636
+ stroke-width="1.25" />
1637
+ </svg>
1638
+ <label>Frame</label>
1639
+ </div>
1640
+ <fig-layer selected
1641
+ open>
1642
+ <div class="fig-layer-row">
1643
+ <svg class="fig-layer-icon"
1644
+ width="16"
1645
+ height="16"
1646
+ viewBox="0 0 16 16"
1647
+ fill="none">
1648
+ <rect x="4"
1649
+ y="4"
1650
+ width="8"
1651
+ height="8"
1652
+ rx="1"
1653
+ stroke="currentColor"
1654
+ stroke-width="1.25" />
1655
+ </svg>
1656
+ <label>Button</label>
1657
+ </div>
1658
+ <fig-layer>
1659
+ <div class="fig-layer-row">
1660
+ <svg class="fig-layer-icon"
1661
+ width="16"
1662
+ height="16"
1663
+ viewBox="0 0 16 16"
1664
+ fill="none">
1665
+ <path d="M3 5H13M3 8H13M3 11H10"
1666
+ stroke="currentColor"
1667
+ stroke-width="1.25"
1668
+ stroke-linecap="round" />
1669
+ </svg>
1670
+ <label>Text</label>
1671
+ </div>
1672
+ </fig-layer>
1673
+ </fig-layer>
1674
+
1675
+ </fig-layer>
1676
+ </fig-layer>
1677
+ </section>
1678
+ <hr>
1679
+
1179
1680
  <!-- Popover -->
1180
1681
  <section id="popover">
1181
1682
  <h2>Popover</h2>
@@ -1992,6 +2493,78 @@ button.addEventListener('click', () => {
1992
2493
  border-radius: 6px;
1993
2494
  }</code></pre>
1994
2495
  </section>
2496
+ <hr>
2497
+
2498
+ <!-- Details -->
2499
+ <section id="details">
2500
+ <h2>Details</h2>
2501
+ <p class="description">A disclosure widget for expandable/collapsible content.</p>
2502
+
2503
+ <h3>Default (Closed)</h3>
2504
+ <details style="font-size: 13px; color: var(--figma-color-text);">
2505
+ <summary style="cursor: pointer; padding: 8px 0;">Click to expand</summary>
2506
+ <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
2507
+ This is the hidden content that appears when the details element is expanded.
2508
+ </p>
2509
+ </details>
2510
+
2511
+ <h3>Default Open</h3>
2512
+ <details open
2513
+ style="font-size: 13px; color: var(--figma-color-text);">
2514
+ <summary style="cursor: pointer; padding: 8px 0;">Already expanded</summary>
2515
+ <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
2516
+ This content is visible by default because of the <code>open</code> attribute.
2517
+ </p>
2518
+ </details>
2519
+
2520
+ <h3>Multiple Sections</h3>
2521
+ <vstack style="gap: 0;">
2522
+ <details
2523
+ style="font-size: 13px; color: var(--figma-color-text); border-bottom: 1px solid var(--figma-color-border);">
2524
+ <summary style="cursor: pointer; padding: 8px 0;">Section One</summary>
2525
+ <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
2526
+ Content for section one.
2527
+ </p>
2528
+ </details>
2529
+ <details
2530
+ style="font-size: 13px; color: var(--figma-color-text); border-bottom: 1px solid var(--figma-color-border);">
2531
+ <summary style="cursor: pointer; padding: 8px 0;">Section Two</summary>
2532
+ <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
2533
+ Content for section two.
2534
+ </p>
2535
+ </details>
2536
+ <details style="font-size: 13px; color: var(--figma-color-text);">
2537
+ <summary style="cursor: pointer; padding: 8px 0;">Section Three</summary>
2538
+ <p style="padding: 8px 0 8px 16px; margin: 0; color: var(--figma-color-text-secondary);">
2539
+ Content for section three.
2540
+ </p>
2541
+ </details>
2542
+ </vstack>
2543
+
2544
+ <h3>With Rich Content</h3>
2545
+ <details style="font-size: 13px; color: var(--figma-color-text);">
2546
+ <summary style="cursor: pointer; padding: 8px 0;">Advanced Settings</summary>
2547
+ <vstack style="padding: 8px 0 8px 16px;">
2548
+ <fig-field direction="horizontal"
2549
+ style="width: 240px;">
2550
+ <label>Opacity</label>
2551
+ <fig-slider value="100"
2552
+ text="true"
2553
+ units="%"></fig-slider>
2554
+ </fig-field>
2555
+ <fig-field direction="horizontal"
2556
+ style="width: 240px;">
2557
+ <label>Blend Mode</label>
2558
+ <fig-dropdown>
2559
+ <option>Normal</option>
2560
+ <option>Multiply</option>
2561
+ <option>Screen</option>
2562
+ </fig-dropdown>
2563
+ </fig-field>
2564
+ <fig-checkbox label="Enable effects"></fig-checkbox>
2565
+ </vstack>
2566
+ </details>
2567
+ </section>
1995
2568
  </main>
1996
2569
 
1997
2570
  <script>
package/fig.js CHANGED
@@ -3556,3 +3556,101 @@ class FigShimmer extends HTMLElement {
3556
3556
  }
3557
3557
  }
3558
3558
  customElements.define("fig-shimmer", FigShimmer);
3559
+
3560
+ // FigLayer
3561
+ class FigLayer extends HTMLElement {
3562
+ static get observedAttributes() {
3563
+ return ["open", "visible"];
3564
+ }
3565
+
3566
+ connectedCallback() {
3567
+ // Add click listener for chevron toggle
3568
+ this.addEventListener("click", this.#handleClick.bind(this));
3569
+ }
3570
+
3571
+ disconnectedCallback() {
3572
+ this.removeEventListener("click", this.#handleClick.bind(this));
3573
+ }
3574
+
3575
+ #handleClick(e) {
3576
+ // Toggle when clicking on the row (but not on actions or interactive elements)
3577
+ const row = e.target.closest(".fig-layer-row");
3578
+ if (row && row.parentElement === this) {
3579
+ // Don't toggle if clicking on actions or buttons
3580
+ if (e.target.closest(".fig-layer-actions") || e.target.closest("fig-button")) {
3581
+ return;
3582
+ }
3583
+ e.stopPropagation();
3584
+ this.open = !this.open;
3585
+ }
3586
+ }
3587
+
3588
+ get open() {
3589
+ const attr = this.getAttribute("open");
3590
+ return attr !== null && attr !== "false";
3591
+ }
3592
+
3593
+ set open(value) {
3594
+ const oldValue = this.open;
3595
+ if (value) {
3596
+ this.setAttribute("open", "true");
3597
+ } else {
3598
+ this.setAttribute("open", "false");
3599
+ }
3600
+ if (oldValue !== value) {
3601
+ this.dispatchEvent(
3602
+ new CustomEvent("openchange", {
3603
+ detail: { open: value },
3604
+ bubbles: true,
3605
+ })
3606
+ );
3607
+ }
3608
+ }
3609
+
3610
+ get visible() {
3611
+ const attr = this.getAttribute("visible");
3612
+ return attr !== "false";
3613
+ }
3614
+
3615
+ set visible(value) {
3616
+ const oldValue = this.visible;
3617
+ if (value) {
3618
+ this.setAttribute("visible", "true");
3619
+ } else {
3620
+ this.setAttribute("visible", "false");
3621
+ }
3622
+ if (oldValue !== value) {
3623
+ this.dispatchEvent(
3624
+ new CustomEvent("visibilitychange", {
3625
+ detail: { visible: value },
3626
+ bubbles: true,
3627
+ })
3628
+ );
3629
+ }
3630
+ }
3631
+
3632
+ attributeChangedCallback(name, oldValue, newValue) {
3633
+ if (oldValue === newValue) return;
3634
+
3635
+ if (name === "open") {
3636
+ const isOpen = newValue !== null && newValue !== "false";
3637
+ this.dispatchEvent(
3638
+ new CustomEvent("openchange", {
3639
+ detail: { open: isOpen },
3640
+ bubbles: true,
3641
+ })
3642
+ );
3643
+ }
3644
+
3645
+ if (name === "visible") {
3646
+ const isVisible = newValue !== "false";
3647
+ this.dispatchEvent(
3648
+ new CustomEvent("visibilitychange", {
3649
+ detail: { visible: isVisible },
3650
+ bubbles: true,
3651
+ })
3652
+ );
3653
+ }
3654
+ }
3655
+ }
3656
+ customElements.define("fig-layer", FigLayer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rogieking/figui3",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "devDependencies": {