@gallop.software/studio 0.1.39 → 0.1.40

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.
@@ -4,7 +4,7 @@ import {
4
4
  colors,
5
5
  fontSize,
6
6
  fontStack
7
- } from "./chunk-DIJR5Y6S.mjs";
7
+ } from "./chunk-HXE6XCG2.mjs";
8
8
 
9
9
  // src/components/StudioUI.tsx
10
10
  import { useEffect as useEffect3, useCallback as useCallback2, useState as useState6 } from "react";
@@ -321,13 +321,15 @@ var spin = keyframes2`
321
321
  var styles2 = {
322
322
  toolbar: css2`
323
323
  display: flex;
324
- flex-wrap: wrap;
324
+ flex-wrap: nowrap;
325
325
  align-items: center;
326
326
  justify-content: space-between;
327
327
  gap: 8px;
328
328
  padding: 12px 16px;
329
329
  background-color: ${colors.surface};
330
330
  border-bottom: 1px solid ${colors.border};
331
+ overflow-x: auto;
332
+ min-width: 0;
331
333
 
332
334
  @media (min-width: 768px) {
333
335
  padding: 12px 24px;
@@ -335,13 +337,15 @@ var styles2 = {
335
337
  `,
336
338
  left: css2`
337
339
  display: flex;
338
- flex-wrap: wrap;
340
+ flex-wrap: nowrap;
341
+ flex-shrink: 0;
339
342
  align-items: center;
340
343
  gap: 8px;
341
344
  `,
342
345
  right: css2`
343
346
  display: flex;
344
- flex-wrap: wrap;
347
+ flex-wrap: nowrap;
348
+ flex-shrink: 0;
345
349
  align-items: center;
346
350
  gap: 8px;
347
351
  `,
@@ -475,8 +479,13 @@ var styles2 = {
475
479
  }
476
480
  `,
477
481
  viewBtnActive: css2`
478
- background-color: ${colors.background};
479
- color: ${colors.text};
482
+ background-color: ${colors.primaryLight};
483
+ color: ${colors.primary};
484
+
485
+ &:hover {
486
+ background-color: ${colors.primaryLight};
487
+ color: ${colors.primary};
488
+ }
480
489
  `
481
490
  };
482
491
  function StudioToolbar() {
@@ -803,6 +812,9 @@ function StudioToolbar() {
803
812
  setSearchQuery(e.target.value);
804
813
  }, [setSearchQuery]);
805
814
  const hasSelection = selectedItems.size > 0;
815
+ const hasImagesSelected = Array.from(selectedItems).some(
816
+ (path) => path === "public/images" || path.startsWith("public/images/")
817
+ );
806
818
  if (focusedItem) {
807
819
  return null;
808
820
  }
@@ -884,8 +896,8 @@ function StudioToolbar() {
884
896
  {
885
897
  css: styles2.btn,
886
898
  onClick: handleProcessImages,
887
- disabled: processing || isInImagesFolder,
888
- title: isInImagesFolder ? "Cannot process images from within the images folder" : void 0,
899
+ disabled: processing || isInImagesFolder || hasImagesSelected,
900
+ title: isInImagesFolder || hasImagesSelected ? "Cannot process protected images folder" : void 0,
889
901
  children: [
890
902
  /* @__PURE__ */ jsx2(ImageStackIcon, {}),
891
903
  processing ? "Processing..." : "Process Images"
@@ -897,7 +909,8 @@ function StudioToolbar() {
897
909
  {
898
910
  css: [styles2.btn, styles2.btnDanger],
899
911
  onClick: handleDeleteClick,
900
- disabled: !hasSelection,
912
+ disabled: !hasSelection || hasImagesSelected,
913
+ title: hasImagesSelected ? "Cannot delete protected images folder items" : void 0,
901
914
  children: [
902
915
  /* @__PURE__ */ jsx2(TrashIcon, {}),
903
916
  "Delete"
@@ -1034,13 +1047,13 @@ var styles3 = {
1034
1047
  `,
1035
1048
  grid: css3`
1036
1049
  display: grid;
1037
- grid-template-columns: repeat(2, 1fr);
1050
+ grid-template-columns: 1fr;
1038
1051
  gap: 12px;
1039
1052
 
1040
- @media (min-width: 640px) { grid-template-columns: repeat(3, 1fr); }
1041
- @media (min-width: 768px) { grid-template-columns: repeat(4, 1fr); }
1042
- @media (min-width: 1024px) { grid-template-columns: repeat(5, 1fr); }
1043
- @media (min-width: 1280px) { grid-template-columns: repeat(6, 1fr); }
1053
+ @media (min-width: 480px) { grid-template-columns: repeat(2, 1fr); }
1054
+ @media (min-width: 768px) { grid-template-columns: repeat(3, 1fr); }
1055
+ @media (min-width: 1024px) { grid-template-columns: repeat(4, 1fr); }
1056
+ @media (min-width: 1280px) { grid-template-columns: repeat(5, 1fr); }
1044
1057
  `,
1045
1058
  item: css3`
1046
1059
  position: relative;
@@ -1184,14 +1197,69 @@ var styles3 = {
1184
1197
  `,
1185
1198
  labelRow: css3`
1186
1199
  display: flex;
1187
- align-items: center;
1188
- justify-content: space-between;
1189
- gap: 8px;
1200
+ flex-direction: column;
1201
+ gap: 6px;
1190
1202
  `,
1191
1203
  labelText: css3`
1192
1204
  flex: 1;
1193
1205
  min-width: 0;
1194
1206
  `,
1207
+ buttonRow: css3`
1208
+ display: flex;
1209
+ gap: 6px;
1210
+ `,
1211
+ copyBtn: css3`
1212
+ position: relative;
1213
+ flex-shrink: 0;
1214
+ height: 28px;
1215
+ width: 28px;
1216
+ font-size: ${fontSize.xs};
1217
+ color: ${colors.textSecondary};
1218
+ background: ${colors.surface};
1219
+ border: 1px solid ${colors.border};
1220
+ padding: 0;
1221
+ cursor: pointer;
1222
+ border-radius: 4px;
1223
+ transition: all 0.15s ease;
1224
+ display: inline-flex;
1225
+ align-items: center;
1226
+ justify-content: center;
1227
+
1228
+ &:hover {
1229
+ background: ${colors.surfaceHover};
1230
+ border-color: ${colors.borderHover};
1231
+ color: ${colors.text};
1232
+ }
1233
+ `,
1234
+ copyIcon: css3`
1235
+ width: 14px;
1236
+ height: 14px;
1237
+ `,
1238
+ tooltip: css3`
1239
+ position: absolute;
1240
+ bottom: 100%;
1241
+ left: 50%;
1242
+ transform: translateX(-50%);
1243
+ background: #1a1f36;
1244
+ color: white;
1245
+ padding: 4px 8px;
1246
+ border-radius: 4px;
1247
+ font-size: 12px;
1248
+ white-space: nowrap;
1249
+ margin-bottom: 6px;
1250
+ pointer-events: none;
1251
+ z-index: 100;
1252
+
1253
+ &::after {
1254
+ content: '';
1255
+ position: absolute;
1256
+ top: 100%;
1257
+ left: 50%;
1258
+ transform: translateX(-50%);
1259
+ border: 4px solid transparent;
1260
+ border-top-color: #1a1f36;
1261
+ }
1262
+ `,
1195
1263
  name: css3`
1196
1264
  font-size: ${fontSize.sm};
1197
1265
  font-weight: 500;
@@ -1387,9 +1455,17 @@ function StudioFileGrid() {
1387
1455
  ] });
1388
1456
  }
1389
1457
  function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1458
+ const [showCopied, setShowCopied] = useState2(false);
1390
1459
  const isFolder = item.type === "folder";
1391
1460
  const isImage = !isFolder && item.thumbnail !== void 0;
1392
1461
  const isImagesFolder = isFolder && (item.name === "images" || item.path.includes("/images/"));
1462
+ const handleCopyPath = (e) => {
1463
+ e.stopPropagation();
1464
+ const pathToCopy = "/" + item.path;
1465
+ navigator.clipboard.writeText(pathToCopy);
1466
+ setShowCopied(true);
1467
+ setTimeout(() => setShowCopied(false), 1500);
1468
+ };
1393
1469
  return /* @__PURE__ */ jsxs3(
1394
1470
  "div",
1395
1471
  {
@@ -1448,17 +1524,31 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1448
1524
  item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
1449
1525
  ] }) : item.size !== void 0 && /* @__PURE__ */ jsx3("p", { css: styles3.size, children: formatFileSize(item.size) })
1450
1526
  ] }),
1451
- /* @__PURE__ */ jsx3(
1452
- "button",
1453
- {
1454
- css: styles3.openBtn,
1455
- onClick: (e) => {
1456
- e.stopPropagation();
1457
- onOpen();
1458
- },
1459
- children: "Open"
1460
- }
1461
- )
1527
+ /* @__PURE__ */ jsxs3("div", { css: styles3.buttonRow, children: [
1528
+ /* @__PURE__ */ jsxs3(
1529
+ "button",
1530
+ {
1531
+ css: styles3.copyBtn,
1532
+ onClick: handleCopyPath,
1533
+ title: "Copy file path",
1534
+ children: [
1535
+ showCopied && /* @__PURE__ */ jsx3("span", { css: styles3.tooltip, children: "Copied!" }),
1536
+ /* @__PURE__ */ jsx3("svg", { css: styles3.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
1537
+ ]
1538
+ }
1539
+ ),
1540
+ /* @__PURE__ */ jsx3(
1541
+ "button",
1542
+ {
1543
+ css: styles3.openBtn,
1544
+ onClick: (e) => {
1545
+ e.stopPropagation();
1546
+ onOpen();
1547
+ },
1548
+ children: "Open"
1549
+ }
1550
+ )
1551
+ ] })
1462
1552
  ] }) })
1463
1553
  ]
1464
1554
  }
@@ -1581,12 +1671,66 @@ var styles4 = {
1581
1671
  checkboxCell: css4`
1582
1672
  padding: 12px 16px;
1583
1673
  cursor: pointer;
1674
+ vertical-align: middle;
1584
1675
  `,
1585
1676
  checkbox: css4`
1586
1677
  width: 16px;
1587
1678
  height: 16px;
1588
1679
  accent-color: ${colors.primary};
1589
1680
  cursor: pointer;
1681
+ display: block;
1682
+ `,
1683
+ copyBtn: css4`
1684
+ position: relative;
1685
+ flex-shrink: 0;
1686
+ height: 28px;
1687
+ width: 28px;
1688
+ font-size: ${fontSize.xs};
1689
+ color: ${colors.textSecondary};
1690
+ background: ${colors.surface};
1691
+ border: 1px solid ${colors.border};
1692
+ padding: 0;
1693
+ cursor: pointer;
1694
+ border-radius: 4px;
1695
+ transition: all 0.15s ease;
1696
+ display: inline-flex;
1697
+ align-items: center;
1698
+ justify-content: center;
1699
+
1700
+ &:hover {
1701
+ background: ${colors.surfaceHover};
1702
+ border-color: ${colors.borderHover};
1703
+ color: ${colors.text};
1704
+ }
1705
+ `,
1706
+ copyIcon: css4`
1707
+ width: 14px;
1708
+ height: 14px;
1709
+ `,
1710
+ tooltip: css4`
1711
+ position: absolute;
1712
+ bottom: 100%;
1713
+ left: 50%;
1714
+ transform: translateX(-50%);
1715
+ background: #1a1f36;
1716
+ color: white;
1717
+ padding: 4px 8px;
1718
+ border-radius: 4px;
1719
+ font-size: 12px;
1720
+ white-space: nowrap;
1721
+ margin-bottom: 6px;
1722
+ pointer-events: none;
1723
+ z-index: 100;
1724
+
1725
+ &::after {
1726
+ content: '';
1727
+ position: absolute;
1728
+ top: 100%;
1729
+ left: 50%;
1730
+ transform: translateX(-50%);
1731
+ border: 4px solid transparent;
1732
+ border-top-color: #1a1f36;
1733
+ }
1590
1734
  `,
1591
1735
  nameCell: css4`
1592
1736
  display: flex;
@@ -1834,9 +1978,17 @@ function StudioFileList() {
1834
1978
  ] }) });
1835
1979
  }
1836
1980
  function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1981
+ const [showCopied, setShowCopied] = useState3(false);
1837
1982
  const isFolder = item.type === "folder";
1838
1983
  const isImage = !isFolder && item.thumbnail !== void 0;
1839
1984
  const isImagesFolder = isFolder && (item.name === "images" || item.path.includes("/images/"));
1985
+ const handleCopyPath = (e) => {
1986
+ e.stopPropagation();
1987
+ const pathToCopy = "/" + item.path;
1988
+ navigator.clipboard.writeText(pathToCopy);
1989
+ setShowCopied(true);
1990
+ setTimeout(() => setShowCopied(false), 1500);
1991
+ };
1840
1992
  return /* @__PURE__ */ jsxs4(
1841
1993
  "tr",
1842
1994
  {
@@ -1876,6 +2028,18 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1876
2028
  }
1877
2029
  ) : /* @__PURE__ */ jsx4("svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
1878
2030
  /* @__PURE__ */ jsx4("span", { css: styles4.name, title: item.name, children: truncateMiddle2(item.name) }),
2031
+ /* @__PURE__ */ jsxs4(
2032
+ "button",
2033
+ {
2034
+ css: styles4.copyBtn,
2035
+ onClick: handleCopyPath,
2036
+ title: "Copy file path",
2037
+ children: [
2038
+ showCopied && /* @__PURE__ */ jsx4("span", { css: styles4.tooltip, children: "Copied!" }),
2039
+ /* @__PURE__ */ jsx4("svg", { css: styles4.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
2040
+ ]
2041
+ }
2042
+ ),
1879
2043
  /* @__PURE__ */ jsx4(
1880
2044
  "button",
1881
2045
  {
@@ -1963,10 +2127,16 @@ var styles5 = {
1963
2127
  background: ${colors.background};
1964
2128
  overflow: auto;
1965
2129
  `,
1966
- mainCloseBtn: css5`
2130
+ headerButtons: css5`
1967
2131
  position: absolute;
1968
2132
  top: 16px;
1969
2133
  right: 16px;
2134
+ display: flex;
2135
+ gap: 8px;
2136
+ z-index: 10;
2137
+ `,
2138
+ copyBtn: css5`
2139
+ position: relative;
1970
2140
  padding: 8px;
1971
2141
  background: ${colors.surface};
1972
2142
  border: 1px solid ${colors.border};
@@ -1976,7 +2146,6 @@ var styles5 = {
1976
2146
  display: flex;
1977
2147
  align-items: center;
1978
2148
  justify-content: center;
1979
- z-index: 10;
1980
2149
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
1981
2150
 
1982
2151
  &:hover {
@@ -1984,11 +2153,58 @@ var styles5 = {
1984
2153
  border-color: ${colors.borderHover};
1985
2154
  }
1986
2155
  `,
1987
- mainCloseIcon: css5`
2156
+ copyIcon: css5`
1988
2157
  width: 20px;
1989
2158
  height: 20px;
1990
2159
  color: ${colors.textSecondary};
1991
2160
  `,
2161
+ tooltip: css5`
2162
+ position: absolute;
2163
+ bottom: 100%;
2164
+ left: 50%;
2165
+ transform: translateX(-50%);
2166
+ background: #1a1f36;
2167
+ color: white;
2168
+ padding: 4px 8px;
2169
+ border-radius: 4px;
2170
+ font-size: 12px;
2171
+ white-space: nowrap;
2172
+ margin-bottom: 6px;
2173
+ pointer-events: none;
2174
+ z-index: 100;
2175
+
2176
+ &::after {
2177
+ content: '';
2178
+ position: absolute;
2179
+ top: 100%;
2180
+ left: 50%;
2181
+ transform: translateX(-50%);
2182
+ border: 4px solid transparent;
2183
+ border-top-color: #1a1f36;
2184
+ }
2185
+ `,
2186
+ mainCloseBtn: css5`
2187
+ padding: 8px;
2188
+ background: ${colors.danger};
2189
+ border: 1px solid ${colors.danger};
2190
+ border-radius: 8px;
2191
+ cursor: pointer;
2192
+ transition: all 0.15s ease;
2193
+ display: flex;
2194
+ align-items: center;
2195
+ justify-content: center;
2196
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
2197
+
2198
+ &:hover {
2199
+ background-color: ${colors.dangerHover};
2200
+ border-color: ${colors.dangerHover};
2201
+ }
2202
+ `,
2203
+ mainCloseIcon: css5`
2204
+ width: 20px;
2205
+ height: 20px;
2206
+ color: white;
2207
+ `,
1992
2208
  mediaWrapper: css5`
1993
2209
  max-width: 100%;
1994
2210
  max-height: 100%;
@@ -2129,6 +2345,7 @@ function StudioDetailView() {
2129
2345
  const { focusedItem, setFocusedItem, triggerRefresh, clearSelection } = useStudio();
2130
2346
  const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
2131
2347
  const [alertMessage, setAlertMessage] = useState4(null);
2348
+ const [showCopied, setShowCopied] = useState4(false);
2132
2349
  if (!focusedItem) return null;
2133
2350
  const isImage = isImageFile(focusedItem.name);
2134
2351
  const isVideo = isVideoFile(focusedItem.name);
@@ -2136,6 +2353,12 @@ function StudioDetailView() {
2136
2353
  const handleClose = () => {
2137
2354
  setFocusedItem(null);
2138
2355
  };
2356
+ const handleCopyPath = () => {
2357
+ const pathToCopy = "/" + focusedItem.path;
2358
+ navigator.clipboard.writeText(pathToCopy);
2359
+ setShowCopied(true);
2360
+ setTimeout(() => setShowCopied(false), 1500);
2361
+ };
2139
2362
  const handleRename = () => {
2140
2363
  const newName = prompt("Enter new name:", focusedItem.name);
2141
2364
  if (newName && newName !== focusedItem.name) {
@@ -2209,7 +2432,13 @@ function StudioDetailView() {
2209
2432
  ),
2210
2433
  /* @__PURE__ */ jsx5("div", { css: styles5.overlay, onClick: handleClose, children: /* @__PURE__ */ jsxs5("div", { css: styles5.container, onClick: (e) => e.stopPropagation(), children: [
2211
2434
  /* @__PURE__ */ jsxs5("div", { css: styles5.main, children: [
2212
- /* @__PURE__ */ jsx5("button", { css: styles5.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsx5("svg", { css: styles5.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }),
2435
+ /* @__PURE__ */ jsxs5("div", { css: styles5.headerButtons, children: [
2436
+ /* @__PURE__ */ jsxs5("button", { css: styles5.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
2437
+ showCopied && /* @__PURE__ */ jsx5("span", { css: styles5.tooltip, children: "Copied!" }),
2438
+ /* @__PURE__ */ jsx5("svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
2439
+ ] }),
2440
+ /* @__PURE__ */ jsx5("button", { css: styles5.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsx5("svg", { css: styles5.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
2441
+ ] }),
2213
2442
  /* @__PURE__ */ jsx5("div", { css: styles5.mediaWrapper, children: renderMedia() })
2214
2443
  ] }),
2215
2444
  /* @__PURE__ */ jsxs5("div", { css: styles5.sidebar, children: [
@@ -2378,6 +2607,8 @@ var styles6 = {
2378
2607
  font-size: ${fontSize.xs};
2379
2608
  color: ${colors.textSecondary};
2380
2609
  border: 1px solid ${colors.border};
2610
+ overflow-x: auto;
2611
+ white-space: nowrap;
2381
2612
  `,
2382
2613
  copyBtn: css6`
2383
2614
  position: absolute;
@@ -2398,6 +2629,31 @@ var styles6 = {
2398
2629
  border-color: ${colors.borderHover};
2399
2630
  }
2400
2631
  `,
2632
+ tooltip: css6`
2633
+ position: absolute;
2634
+ bottom: 100%;
2635
+ left: 50%;
2636
+ transform: translateX(-50%);
2637
+ background: #1a1f36;
2638
+ color: white;
2639
+ padding: 4px 8px;
2640
+ border-radius: 4px;
2641
+ font-size: 12px;
2642
+ white-space: nowrap;
2643
+ margin-bottom: 6px;
2644
+ pointer-events: none;
2645
+ z-index: 100;
2646
+
2647
+ &::after {
2648
+ content: '';
2649
+ position: absolute;
2650
+ top: 100%;
2651
+ left: 50%;
2652
+ transform: translateX(-50%);
2653
+ border: 4px solid transparent;
2654
+ border-top-color: #1a1f36;
2655
+ }
2656
+ `,
2401
2657
  copyIcon: css6`
2402
2658
  width: 14px;
2403
2659
  height: 14px;
@@ -2528,7 +2784,10 @@ function SettingsPanel({ onClose }) {
2528
2784
  /* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Cloudflare R2" }),
2529
2785
  /* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Configure in .env.local file:" }),
2530
2786
  /* @__PURE__ */ jsxs6("div", { css: styles6.codeWrapper, children: [
2531
- /* @__PURE__ */ jsx6("button", { css: styles6.copyBtn, onClick: handleCopy, title: copied ? "Copied!" : "Copy to clipboard", children: copied ? /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) }) }),
2787
+ /* @__PURE__ */ jsxs6("button", { css: styles6.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
2788
+ copied && /* @__PURE__ */ jsx6("span", { css: styles6.tooltip, children: "Copied!" }),
2789
+ copied ? /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
2790
+ ] }),
2532
2791
  /* @__PURE__ */ jsxs6("div", { css: styles6.code, children: [
2533
2792
  /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
2534
2793
  /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
@@ -2864,4 +3123,4 @@ export {
2864
3123
  StudioUI,
2865
3124
  StudioUI_default as default
2866
3125
  };
2867
- //# sourceMappingURL=StudioUI-RHBJ6LVY.mjs.map
3126
+ //# sourceMappingURL=StudioUI-4RENMCDG.mjs.map