@behindthemusictree/genre-tree-view 5.0.0 → 6.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/dist/index.cjs +467 -547
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -18
- package/dist/index.d.ts +15 -18
- package/dist/index.js +462 -542
- package/dist/index.js.map +1 -1
- package/dist/styles.css +71 -24
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -51,7 +51,6 @@ module.exports = __toCommonJS(src_exports);
|
|
|
51
51
|
// src/GenreTree.tsx
|
|
52
52
|
var import_react8 = require("react");
|
|
53
53
|
var d3 = __toESM(require("d3"), 1);
|
|
54
|
-
var import_md6 = require("react-icons/md");
|
|
55
54
|
|
|
56
55
|
// src/NodeHelper.tsx
|
|
57
56
|
var import_server = __toESM(require("react-dom/server"), 1);
|
|
@@ -75,6 +74,9 @@ var MENU_WIDTH = 130;
|
|
|
75
74
|
var PER_TREE_ACCENT_DOT = true;
|
|
76
75
|
var ROOT_TINT_RATIO = 0.08;
|
|
77
76
|
var POP_SECTOR_TINT_RATIO = 0.8;
|
|
77
|
+
var UNDERGROUND_DARKEN_RATIO = 0.62;
|
|
78
|
+
var UNDERGROUND_SECTOR_FILL_OPACITY = 0.15;
|
|
79
|
+
var SCENE_SECTOR_OUTER_RADIUS = 1e5;
|
|
78
80
|
var CENTER_NODE_NAME = "Mainstream Pop";
|
|
79
81
|
var TREE_COLORS = [
|
|
80
82
|
"#4F46E5",
|
|
@@ -156,6 +158,11 @@ function isMainstreamPopLineage(index, nodeId) {
|
|
|
156
158
|
const topRoot = index.ancestorsOf(nodeId)[0] ?? index.byId.get(nodeId);
|
|
157
159
|
return topRoot?.name === CENTER_NODE_NAME;
|
|
158
160
|
}
|
|
161
|
+
function shadeSurface(hex, ratio) {
|
|
162
|
+
const channel = (offset) => parseInt(hex.slice(offset, offset + 2), 16);
|
|
163
|
+
const toHex = (value) => Math.round(value * ratio).toString(16).padStart(2, "0");
|
|
164
|
+
return `#${toHex(channel(1))}${toHex(channel(3))}${toHex(channel(5))}`;
|
|
165
|
+
}
|
|
159
166
|
function getGenreNodeStyle(index, nodeId) {
|
|
160
167
|
if (isMainstreamPopLineage(index, nodeId)) {
|
|
161
168
|
return { fill: tintSurface("#ffffff", POP_SECTOR_TINT_RATIO), textColor: TEXT_COLOR };
|
|
@@ -244,10 +251,13 @@ function calculateRootLabelFontSize(layoutFontSize, zoomScale) {
|
|
|
244
251
|
return Math.max(layoutFontSize, ROOT_LABEL_MIN_SCREEN_PX / zoomScale);
|
|
245
252
|
}
|
|
246
253
|
var NODE_DOT_MIN_RADIUS = 3;
|
|
247
|
-
var NODE_DOT_MAX_RADIUS =
|
|
254
|
+
var NODE_DOT_MAX_RADIUS = 24;
|
|
248
255
|
var NODE_DOT_LABEL_GAP = 6;
|
|
256
|
+
var NODE_LAYOUT_SLOT_RADIUS = 8;
|
|
249
257
|
function calculateNodeDotRadius(itemCount, range) {
|
|
250
|
-
|
|
258
|
+
const minArea = NODE_DOT_MIN_RADIUS ** 2;
|
|
259
|
+
const maxArea = NODE_DOT_MAX_RADIUS ** 2;
|
|
260
|
+
return Math.sqrt(minArea + logarithmicPosition(itemCount, range) * (maxArea - minArea));
|
|
251
261
|
}
|
|
252
262
|
var WHEEL_RADIUS = 260;
|
|
253
263
|
var WHEEL_VIEWPORT_HEIGHT = WHEEL_RADIUS * 2 + MAX_NODE_HEIGHT / 2;
|
|
@@ -634,6 +644,61 @@ function renderTree(d3Lib, svgRef, treeData, svgWidth, svgHeight, reparentingNod
|
|
|
634
644
|
return svg;
|
|
635
645
|
}
|
|
636
646
|
|
|
647
|
+
// src/FloatingControls.tsx
|
|
648
|
+
var import_md = require("react-icons/md");
|
|
649
|
+
|
|
650
|
+
// src/BusyIndicator.tsx
|
|
651
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
652
|
+
function BusyIndicator() {
|
|
653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "gtv-busy", role: "status", "aria-live": "polite", children: [
|
|
654
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gtv-busy-ring", "aria-hidden": "true" }),
|
|
655
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gtv-skeleton-sr-only", children: "Updating genre tree\u2026" })
|
|
656
|
+
] });
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// src/FloatingControls.tsx
|
|
660
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
661
|
+
function FloatingControls({ panZoom, onFit, orientation, leading, busy }) {
|
|
662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
663
|
+
"div",
|
|
664
|
+
{
|
|
665
|
+
className: [
|
|
666
|
+
"gtv-wheel-floating-controls",
|
|
667
|
+
orientation === "horizontal" && "gtv-wheel-floating-controls--horizontal"
|
|
668
|
+
].filter(Boolean).join(" "),
|
|
669
|
+
children: [
|
|
670
|
+
busy && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BusyIndicator, {}),
|
|
671
|
+
leading && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "gtv-floating-controls-leading", children: leading }),
|
|
672
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "gtv-zoom-controls", children: [
|
|
673
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
674
|
+
"button",
|
|
675
|
+
{
|
|
676
|
+
type: "button",
|
|
677
|
+
className: ["gtv-zoom-btn", !panZoom.canZoomIn && "gtv-zoom-btn--disabled"].filter(Boolean).join(" "),
|
|
678
|
+
disabled: !panZoom.canZoomIn,
|
|
679
|
+
onClick: panZoom.zoomIn,
|
|
680
|
+
"aria-label": "Zoom in",
|
|
681
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_md.MdZoomIn, { className: "gtv-icon", size: 18 })
|
|
682
|
+
}
|
|
683
|
+
),
|
|
684
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
685
|
+
"button",
|
|
686
|
+
{
|
|
687
|
+
type: "button",
|
|
688
|
+
className: ["gtv-zoom-btn", !panZoom.canZoomOut && "gtv-zoom-btn--disabled"].filter(Boolean).join(" "),
|
|
689
|
+
disabled: !panZoom.canZoomOut,
|
|
690
|
+
onClick: panZoom.zoomOut,
|
|
691
|
+
"aria-label": "Zoom out",
|
|
692
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_md.MdZoomOut, { className: "gtv-icon", size: 18 })
|
|
693
|
+
}
|
|
694
|
+
),
|
|
695
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "gtv-zoom-btn", onClick: onFit, "aria-label": "Fit to frame", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_md.MdFitScreen, { className: "gtv-icon", size: 18 }) })
|
|
696
|
+
] })
|
|
697
|
+
]
|
|
698
|
+
}
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
|
|
637
702
|
// src/use-pan-zoom.ts
|
|
638
703
|
var import_react = require("react");
|
|
639
704
|
|
|
@@ -1270,13 +1335,13 @@ function useTreeIndex(nodes) {
|
|
|
1270
1335
|
|
|
1271
1336
|
// src/InfoPanel.tsx
|
|
1272
1337
|
var import_react6 = require("react");
|
|
1273
|
-
var
|
|
1338
|
+
var import_md5 = require("react-icons/md");
|
|
1274
1339
|
|
|
1275
1340
|
// src/InfoPanelExpandButton.tsx
|
|
1276
|
-
var
|
|
1277
|
-
var
|
|
1341
|
+
var import_md2 = require("react-icons/md");
|
|
1342
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1278
1343
|
function InfoPanelExpandButton({ expanded, onExpandedChange, style }) {
|
|
1279
|
-
return /* @__PURE__ */ (0,
|
|
1344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1280
1345
|
"button",
|
|
1281
1346
|
{
|
|
1282
1347
|
type: "button",
|
|
@@ -1284,19 +1349,19 @@ function InfoPanelExpandButton({ expanded, onExpandedChange, style }) {
|
|
|
1284
1349
|
style,
|
|
1285
1350
|
onClick: () => onExpandedChange(!expanded),
|
|
1286
1351
|
"aria-label": expanded ? "Collapse panel" : "Expand panel",
|
|
1287
|
-
children: expanded ? /* @__PURE__ */ (0,
|
|
1352
|
+
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_md2.MdCloseFullscreen, { className: "gtv-icon", size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_md2.MdOpenInFull, { className: "gtv-icon", size: 16 })
|
|
1288
1353
|
}
|
|
1289
1354
|
);
|
|
1290
1355
|
}
|
|
1291
1356
|
|
|
1292
1357
|
// src/InfoPanelSection.tsx
|
|
1293
1358
|
var import_react4 = require("react");
|
|
1294
|
-
var
|
|
1295
|
-
var
|
|
1359
|
+
var import_md3 = require("react-icons/md");
|
|
1360
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1296
1361
|
function InfoPanelSection({ title, children }) {
|
|
1297
1362
|
const [open, setOpen] = (0, import_react4.useState)(true);
|
|
1298
|
-
return /* @__PURE__ */ (0,
|
|
1299
|
-
/* @__PURE__ */ (0,
|
|
1363
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "gtv-info-panel-children", children: [
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1300
1365
|
"button",
|
|
1301
1366
|
{
|
|
1302
1367
|
type: "button",
|
|
@@ -1304,8 +1369,8 @@ function InfoPanelSection({ title, children }) {
|
|
|
1304
1369
|
"aria-expanded": open,
|
|
1305
1370
|
onClick: () => setOpen((isOpen) => !isOpen),
|
|
1306
1371
|
children: [
|
|
1307
|
-
/* @__PURE__ */ (0,
|
|
1308
|
-
/* @__PURE__ */ (0,
|
|
1372
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "gtv-info-panel-children-title", children: title }),
|
|
1373
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_md3.MdExpandMore, { className: "gtv-icon gtv-info-panel-section-chevron", size: 16 })
|
|
1309
1374
|
]
|
|
1310
1375
|
}
|
|
1311
1376
|
),
|
|
@@ -1315,10 +1380,10 @@ function InfoPanelSection({ title, children }) {
|
|
|
1315
1380
|
|
|
1316
1381
|
// src/NodeToolbar.tsx
|
|
1317
1382
|
var import_react5 = require("react");
|
|
1318
|
-
var
|
|
1383
|
+
var import_md4 = require("react-icons/md");
|
|
1319
1384
|
var import_fa = require("react-icons/fa");
|
|
1320
1385
|
var import_pi2 = require("react-icons/pi");
|
|
1321
|
-
var
|
|
1386
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1322
1387
|
function NodeToolbar({
|
|
1323
1388
|
node,
|
|
1324
1389
|
playingNodeId,
|
|
@@ -1339,9 +1404,9 @@ function NodeToolbar({
|
|
|
1339
1404
|
const isPlayable = node.itemCount > 0;
|
|
1340
1405
|
const isThisPlaying = playingNodeId === node.id;
|
|
1341
1406
|
const playLabel = isThisPlaying && playState === "playing" ? "Pause" : isThisPlaying && playState === "loading" ? "Loading..." : "Play";
|
|
1342
|
-
const playIcon = isThisPlaying && playState === "playing" ? /* @__PURE__ */ (0,
|
|
1343
|
-
return /* @__PURE__ */ (0,
|
|
1344
|
-
/* @__PURE__ */ (0,
|
|
1407
|
+
const playIcon = isThisPlaying && playState === "playing" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fa.FaPause, { className: "gtv-icon", size: "0.6em" }) : isThisPlaying && playState === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fa.FaSpinner, { className: "gtv-icon gtv-icon--spin", size: "0.6em" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fa.FaPlay, { className: "gtv-icon", size: "0.6em" });
|
|
1408
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: ["gtv-toolbar", className].filter(Boolean).join(" "), children: [
|
|
1409
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1345
1410
|
"button",
|
|
1346
1411
|
{
|
|
1347
1412
|
type: "button",
|
|
@@ -1353,8 +1418,8 @@ function NodeToolbar({
|
|
|
1353
1418
|
children: playIcon
|
|
1354
1419
|
}
|
|
1355
1420
|
),
|
|
1356
|
-
isActionable && /* @__PURE__ */ (0,
|
|
1357
|
-
/* @__PURE__ */ (0,
|
|
1421
|
+
isActionable && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1422
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1358
1423
|
"button",
|
|
1359
1424
|
{
|
|
1360
1425
|
type: "button",
|
|
@@ -1362,13 +1427,13 @@ function NodeToolbar({
|
|
|
1362
1427
|
title: "Add sub-genre",
|
|
1363
1428
|
"aria-label": "Add sub-genre",
|
|
1364
1429
|
onClick: () => onAddChild?.(node.id),
|
|
1365
|
-
children: /* @__PURE__ */ (0,
|
|
1430
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fa.FaPlus, { className: "gtv-icon", size: "0.6em" })
|
|
1366
1431
|
}
|
|
1367
1432
|
),
|
|
1368
1433
|
primaryExtraActions.map((action) => {
|
|
1369
1434
|
const enabled = action.enabled ? action.enabled(node) : true;
|
|
1370
1435
|
const label = action.label(node);
|
|
1371
|
-
return /* @__PURE__ */ (0,
|
|
1436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1372
1437
|
"button",
|
|
1373
1438
|
{
|
|
1374
1439
|
type: "button",
|
|
@@ -1382,8 +1447,8 @@ function NodeToolbar({
|
|
|
1382
1447
|
action.key
|
|
1383
1448
|
);
|
|
1384
1449
|
}),
|
|
1385
|
-
/* @__PURE__ */ (0,
|
|
1386
|
-
/* @__PURE__ */ (0,
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "gtv-toolbar-overflow", children: [
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1387
1452
|
"button",
|
|
1388
1453
|
{
|
|
1389
1454
|
type: "button",
|
|
@@ -1393,11 +1458,11 @@ function NodeToolbar({
|
|
|
1393
1458
|
"aria-haspopup": "menu",
|
|
1394
1459
|
"aria-expanded": menuOpen,
|
|
1395
1460
|
onClick: () => setMenuOpen((open) => !open),
|
|
1396
|
-
children: /* @__PURE__ */ (0,
|
|
1461
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_md4.MdMoreVert, { size: "0.6em" })
|
|
1397
1462
|
}
|
|
1398
1463
|
),
|
|
1399
|
-
menuOpen && /* @__PURE__ */ (0,
|
|
1400
|
-
/* @__PURE__ */ (0,
|
|
1464
|
+
menuOpen && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "gtv-menu-card gtv-toolbar-overflow-menu", children: [
|
|
1465
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1401
1466
|
"button",
|
|
1402
1467
|
{
|
|
1403
1468
|
type: "button",
|
|
@@ -1407,12 +1472,12 @@ function NodeToolbar({
|
|
|
1407
1472
|
onRenameRequest?.(node);
|
|
1408
1473
|
},
|
|
1409
1474
|
children: [
|
|
1410
|
-
/* @__PURE__ */ (0,
|
|
1411
|
-
/* @__PURE__ */ (0,
|
|
1475
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_md4.MdModeEdit, { className: "gtv-icon", size: 13 }) }),
|
|
1476
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-label", children: "Rename" })
|
|
1412
1477
|
]
|
|
1413
1478
|
}
|
|
1414
1479
|
),
|
|
1415
|
-
/* @__PURE__ */ (0,
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1416
1481
|
"button",
|
|
1417
1482
|
{
|
|
1418
1483
|
type: "button",
|
|
@@ -1422,14 +1487,14 @@ function NodeToolbar({
|
|
|
1422
1487
|
onReparentRequest?.(node);
|
|
1423
1488
|
},
|
|
1424
1489
|
children: [
|
|
1425
|
-
/* @__PURE__ */ (0,
|
|
1426
|
-
/* @__PURE__ */ (0,
|
|
1490
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_pi2.PiGraphFill, { className: "gtv-icon", size: 13 }) }),
|
|
1491
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-label", children: "Change parent" })
|
|
1427
1492
|
]
|
|
1428
1493
|
}
|
|
1429
1494
|
),
|
|
1430
1495
|
overflowExtraActions.map((action) => {
|
|
1431
1496
|
const enabled = action.enabled ? action.enabled(node) : true;
|
|
1432
|
-
return /* @__PURE__ */ (0,
|
|
1497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1433
1498
|
"button",
|
|
1434
1499
|
{
|
|
1435
1500
|
type: "button",
|
|
@@ -1440,15 +1505,15 @@ function NodeToolbar({
|
|
|
1440
1505
|
action.onClick(event, node);
|
|
1441
1506
|
},
|
|
1442
1507
|
children: [
|
|
1443
|
-
/* @__PURE__ */ (0,
|
|
1444
|
-
/* @__PURE__ */ (0,
|
|
1508
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-icon", children: action.icon(node) }),
|
|
1509
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-label", children: action.label(node) })
|
|
1445
1510
|
]
|
|
1446
1511
|
},
|
|
1447
1512
|
action.key
|
|
1448
1513
|
);
|
|
1449
1514
|
}),
|
|
1450
|
-
/* @__PURE__ */ (0,
|
|
1451
|
-
/* @__PURE__ */ (0,
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "gtv-menu-divider" }),
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1452
1517
|
"button",
|
|
1453
1518
|
{
|
|
1454
1519
|
type: "button",
|
|
@@ -1458,8 +1523,8 @@ function NodeToolbar({
|
|
|
1458
1523
|
onDeleteRequest?.(node);
|
|
1459
1524
|
},
|
|
1460
1525
|
children: [
|
|
1461
|
-
/* @__PURE__ */ (0,
|
|
1462
|
-
/* @__PURE__ */ (0,
|
|
1526
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_fa.FaTrashAlt, { className: "gtv-icon", size: 13 }) }),
|
|
1527
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "gtv-menu-row-label", children: "Delete" })
|
|
1463
1528
|
]
|
|
1464
1529
|
}
|
|
1465
1530
|
)
|
|
@@ -1470,7 +1535,7 @@ function NodeToolbar({
|
|
|
1470
1535
|
}
|
|
1471
1536
|
|
|
1472
1537
|
// src/InfoPanel.tsx
|
|
1473
|
-
var
|
|
1538
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1474
1539
|
var MINI_NODE_MIN_DIAMETER = 14;
|
|
1475
1540
|
var MINI_NODE_MAX_DIAMETER = 32;
|
|
1476
1541
|
var MINI_NODE_MIN_FONT_SIZE = 10;
|
|
@@ -1502,10 +1567,6 @@ function InfoPanel({
|
|
|
1502
1567
|
onZoomIn,
|
|
1503
1568
|
actions,
|
|
1504
1569
|
readOnly = false,
|
|
1505
|
-
editMode = false,
|
|
1506
|
-
onEditModeChange,
|
|
1507
|
-
renderTitleEditor,
|
|
1508
|
-
renderParentsEditor,
|
|
1509
1570
|
renderDangerZone,
|
|
1510
1571
|
expanded = false,
|
|
1511
1572
|
onExpandedChange,
|
|
@@ -1516,10 +1577,8 @@ function InfoPanel({
|
|
|
1516
1577
|
(0, import_react6.useEffect)(() => {
|
|
1517
1578
|
panelRef.current?.toggleAttribute("inert", collapsed);
|
|
1518
1579
|
}, [collapsed]);
|
|
1519
|
-
const editing = editMode && !readOnly;
|
|
1520
|
-
const shownParent = editing && renderParentsEditor ? null : parentNode;
|
|
1521
1580
|
const miniTreeRange = getItemCountRange([
|
|
1522
|
-
...
|
|
1581
|
+
...parentNode ? [parentNode.node] : [],
|
|
1523
1582
|
node,
|
|
1524
1583
|
...childNodes.map((child) => child.node)
|
|
1525
1584
|
]);
|
|
@@ -1533,9 +1592,9 @@ function InfoPanel({
|
|
|
1533
1592
|
};
|
|
1534
1593
|
const miniNodeContent = (target, background, range) => {
|
|
1535
1594
|
const { diameter, fontSize } = miniNodeSize(target, range);
|
|
1536
|
-
return /* @__PURE__ */ (0,
|
|
1537
|
-
/* @__PURE__ */ (0,
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
1595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1596
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "gtv-info-panel-mini-dot", style: { background, width: diameter, height: diameter } }),
|
|
1597
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "gtv-info-panel-mini-label", style: { fontSize }, children: target.name })
|
|
1539
1598
|
] });
|
|
1540
1599
|
};
|
|
1541
1600
|
const sortedChildNodes = [...childNodes].sort((a, b) => b.node.itemCount - a.node.itemCount);
|
|
@@ -1548,9 +1607,9 @@ function InfoPanel({
|
|
|
1548
1607
|
document.addEventListener("keydown", onKeyDown);
|
|
1549
1608
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
1550
1609
|
}, [expanded, onExpandedChange]);
|
|
1551
|
-
const dangerZone =
|
|
1552
|
-
const toolbar = actions ? /* @__PURE__ */ (0,
|
|
1553
|
-
const ancestors = ancestorNodes.length > 0 ? /* @__PURE__ */ (0,
|
|
1610
|
+
const dangerZone = !readOnly && renderDangerZone && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "gtv-info-panel-danger-zone", children: renderDangerZone(node) });
|
|
1611
|
+
const toolbar = actions ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NodeToolbar, { node, className: "gtv-info-panel-toolbar", ...actions }, node.id) : null;
|
|
1612
|
+
const ancestors = ancestorNodes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(InfoPanelSection, { title: "Ancestors", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { className: "gtv-info-panel-children-list gtv-info-panel-ancestors-list", children: ancestorNodes.map(({ node: ancestor, fill: fill2 }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1554
1613
|
"button",
|
|
1555
1614
|
{
|
|
1556
1615
|
type: "button",
|
|
@@ -1560,76 +1619,73 @@ function InfoPanel({
|
|
|
1560
1619
|
children: miniNodeContent(ancestor, fill2, ancestorRange)
|
|
1561
1620
|
}
|
|
1562
1621
|
) }, ancestor.id)) }) }) : null;
|
|
1563
|
-
const family = /* @__PURE__ */ (0,
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1622
|
+
const family = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(InfoPanelSection, { title: "Family", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "gtv-info-panel-mini-tree", children: [
|
|
1623
|
+
parentNode && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "gtv-info-panel-mini-tree-parent", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1624
|
+
"button",
|
|
1625
|
+
{
|
|
1626
|
+
type: "button",
|
|
1627
|
+
className: "gtv-info-panel-child",
|
|
1628
|
+
title: parentNode.node.name,
|
|
1629
|
+
onClick: () => onSelectNode(parentNode.node.id),
|
|
1630
|
+
children: miniNodeContent(parentNode.node, parentNode.fill, miniTreeRange)
|
|
1631
|
+
}
|
|
1632
|
+
) }),
|
|
1633
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1634
|
+
"div",
|
|
1635
|
+
{
|
|
1636
|
+
className: `gtv-info-panel-mini-tree-node${childNodes.length === 0 ? " gtv-info-panel-mini-tree-node--leaf" : ""}`,
|
|
1637
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1638
|
+
"span",
|
|
1639
|
+
{
|
|
1640
|
+
className: "gtv-info-panel-child gtv-info-panel-mini-tree-current",
|
|
1641
|
+
title: node.name,
|
|
1642
|
+
children: miniNodeContent(node, fill, miniTreeRange)
|
|
1643
|
+
}
|
|
1644
|
+
)
|
|
1645
|
+
}
|
|
1646
|
+
),
|
|
1647
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "gtv-info-panel-mini-tree-children", children: [
|
|
1648
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "gtv-info-panel-children-title", children: [
|
|
1649
|
+
childNodes.length,
|
|
1650
|
+
" ",
|
|
1651
|
+
childNodes.length <= 1 ? "child" : "children"
|
|
1652
|
+
] }),
|
|
1653
|
+
childNodes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { className: "gtv-info-panel-children-list", children: sortedChildNodes.map(({ node: child, fill: fill2 }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1567
1654
|
"button",
|
|
1568
1655
|
{
|
|
1569
1656
|
type: "button",
|
|
1570
1657
|
className: "gtv-info-panel-child",
|
|
1571
|
-
title:
|
|
1572
|
-
onClick: () => onSelectNode(
|
|
1573
|
-
children: miniNodeContent(
|
|
1658
|
+
title: child.name,
|
|
1659
|
+
onClick: () => onSelectNode(child.id),
|
|
1660
|
+
children: miniNodeContent(child, fill2, miniTreeRange)
|
|
1574
1661
|
}
|
|
1575
|
-
) })
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
"span",
|
|
1582
|
-
{
|
|
1583
|
-
className: "gtv-info-panel-child gtv-info-panel-mini-tree-current",
|
|
1584
|
-
title: node.name,
|
|
1585
|
-
children: miniNodeContent(node, fill, miniTreeRange)
|
|
1586
|
-
}
|
|
1587
|
-
)
|
|
1588
|
-
}
|
|
1589
|
-
),
|
|
1590
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "gtv-info-panel-mini-tree-children", children: [
|
|
1591
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "gtv-info-panel-children-title", children: [
|
|
1592
|
-
childNodes.length,
|
|
1593
|
-
" ",
|
|
1594
|
-
childNodes.length <= 1 ? "child" : "children"
|
|
1595
|
-
] }),
|
|
1596
|
-
childNodes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "gtv-info-panel-children-list", children: sortedChildNodes.map(({ node: child, fill: fill2 }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1597
|
-
"button",
|
|
1598
|
-
{
|
|
1599
|
-
type: "button",
|
|
1600
|
-
className: "gtv-info-panel-child",
|
|
1601
|
-
title: child.name,
|
|
1602
|
-
onClick: () => onSelectNode(child.id),
|
|
1603
|
-
children: miniNodeContent(child, fill2, miniTreeRange)
|
|
1604
|
-
}
|
|
1605
|
-
) }, child.id)) })
|
|
1606
|
-
] })
|
|
1607
|
-
] }) })
|
|
1608
|
-
] });
|
|
1609
|
-
const itemCount = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("dl", { className: "gtv-info-panel-fields", children: [
|
|
1610
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dt", { children: itemCountLabel }),
|
|
1611
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("dd", { children: node.itemCount })
|
|
1662
|
+
) }, child.id)) })
|
|
1663
|
+
] })
|
|
1664
|
+
] }) }) });
|
|
1665
|
+
const itemCount = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("dl", { className: "gtv-info-panel-fields", children: [
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("dt", { children: itemCountLabel }),
|
|
1667
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("dd", { children: node.itemCount })
|
|
1612
1668
|
] });
|
|
1613
|
-
const { primary, aside } = renderInfoPanelBody ? renderInfoPanelBody(node, { toolbar, ancestors, family, itemCount }) : { primary: /* @__PURE__ */ (0,
|
|
1669
|
+
const { primary, aside } = renderInfoPanelBody ? renderInfoPanelBody(node, { toolbar, ancestors, family, itemCount }) : { primary: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1614
1670
|
toolbar,
|
|
1615
1671
|
ancestors,
|
|
1616
1672
|
family,
|
|
1617
1673
|
itemCount
|
|
1618
1674
|
] }) };
|
|
1619
1675
|
const hasAside = aside !== void 0 && aside !== null && aside !== false;
|
|
1620
|
-
return /* @__PURE__ */ (0,
|
|
1676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1621
1677
|
"div",
|
|
1622
1678
|
{
|
|
1623
1679
|
className: `gtv-info-panel gtv-info-panel--${side}${expanded ? " gtv-info-panel--expanded" : ""}${expanded && !hasAside ? " gtv-info-panel--expanded-solo" : ""}${collapsed ? " gtv-info-panel--collapsed" : ""}`,
|
|
1624
1680
|
ref: panelRef,
|
|
1625
1681
|
children: [
|
|
1626
|
-
/* @__PURE__ */ (0,
|
|
1682
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1627
1683
|
"div",
|
|
1628
1684
|
{
|
|
1629
1685
|
className: "gtv-info-panel-header",
|
|
1630
1686
|
style: { background: fill, color: textColor },
|
|
1631
1687
|
children: [
|
|
1632
|
-
onPrevious && /* @__PURE__ */ (0,
|
|
1688
|
+
onPrevious && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1633
1689
|
"button",
|
|
1634
1690
|
{
|
|
1635
1691
|
type: "button",
|
|
@@ -1638,21 +1694,21 @@ function InfoPanel({
|
|
|
1638
1694
|
onClick: onPrevious,
|
|
1639
1695
|
"aria-label": previousLabel ? `Previous: ${previousLabel}` : "Previous",
|
|
1640
1696
|
title: previousLabel,
|
|
1641
|
-
children: /* @__PURE__ */ (0,
|
|
1697
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_md5.MdArrowBack, { className: "gtv-icon", size: 16 })
|
|
1642
1698
|
}
|
|
1643
1699
|
),
|
|
1644
|
-
|
|
1700
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1645
1701
|
"span",
|
|
1646
1702
|
{
|
|
1647
1703
|
className: `gtv-info-panel-title${hideTitle ? " gtv-info-panel-title--hidden" : ""}`,
|
|
1648
1704
|
style: { color: textColor },
|
|
1649
1705
|
children: [
|
|
1650
1706
|
node.name,
|
|
1651
|
-
node.umbrella && /* @__PURE__ */ (0,
|
|
1707
|
+
node.umbrella && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "gtv-info-panel-umbrella-badge", children: "umbrella" })
|
|
1652
1708
|
]
|
|
1653
1709
|
}
|
|
1654
1710
|
),
|
|
1655
|
-
onZoomIn && /* @__PURE__ */ (0,
|
|
1711
|
+
onZoomIn && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1656
1712
|
"button",
|
|
1657
1713
|
{
|
|
1658
1714
|
type: "button",
|
|
@@ -1661,22 +1717,11 @@ function InfoPanel({
|
|
|
1661
1717
|
onClick: onZoomIn,
|
|
1662
1718
|
"aria-label": "Zoom in",
|
|
1663
1719
|
title: "Zoom in",
|
|
1664
|
-
children: /* @__PURE__ */ (0,
|
|
1720
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_md5.MdZoomIn, { className: "gtv-icon", size: 16 })
|
|
1665
1721
|
}
|
|
1666
1722
|
),
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
{
|
|
1670
|
-
type: "button",
|
|
1671
|
-
className: "gtv-info-panel-edit",
|
|
1672
|
-
style: { color: textColor },
|
|
1673
|
-
onClick: () => onEditModeChange(!editMode),
|
|
1674
|
-
"aria-pressed": editMode,
|
|
1675
|
-
children: editMode ? "Done" : "Edit"
|
|
1676
|
-
}
|
|
1677
|
-
),
|
|
1678
|
-
onExpandedChange && !hideExpandButton && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InfoPanelExpandButton, { expanded, onExpandedChange, style: { color: textColor } }),
|
|
1679
|
-
!hideClose && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1723
|
+
onExpandedChange && !hideExpandButton && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(InfoPanelExpandButton, { expanded, onExpandedChange, style: { color: textColor } }),
|
|
1724
|
+
!hideClose && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1680
1725
|
"button",
|
|
1681
1726
|
{
|
|
1682
1727
|
type: "button",
|
|
@@ -1684,18 +1729,18 @@ function InfoPanel({
|
|
|
1684
1729
|
style: { color: textColor },
|
|
1685
1730
|
onClick: onClose,
|
|
1686
1731
|
"aria-label": "Close",
|
|
1687
|
-
children: /* @__PURE__ */ (0,
|
|
1732
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_md5.MdClose, { className: "gtv-icon", size: 16 })
|
|
1688
1733
|
}
|
|
1689
1734
|
)
|
|
1690
1735
|
]
|
|
1691
1736
|
}
|
|
1692
1737
|
),
|
|
1693
|
-
/* @__PURE__ */ (0,
|
|
1694
|
-
/* @__PURE__ */ (0,
|
|
1738
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "gtv-info-panel-body", children: [
|
|
1739
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "gtv-info-panel-primary", children: [
|
|
1695
1740
|
primary,
|
|
1696
1741
|
expanded && !hasAside && dangerZone
|
|
1697
1742
|
] }),
|
|
1698
|
-
hasAside && /* @__PURE__ */ (0,
|
|
1743
|
+
hasAside && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "gtv-info-panel-aside", children: [
|
|
1699
1744
|
aside,
|
|
1700
1745
|
expanded && dangerZone
|
|
1701
1746
|
] })
|
|
@@ -1708,8 +1753,8 @@ function InfoPanel({
|
|
|
1708
1753
|
|
|
1709
1754
|
// src/OverlayPanel.tsx
|
|
1710
1755
|
var import_react7 = require("react");
|
|
1711
|
-
var
|
|
1712
|
-
var
|
|
1756
|
+
var import_md6 = require("react-icons/md");
|
|
1757
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1713
1758
|
function OverlayPanel({
|
|
1714
1759
|
title,
|
|
1715
1760
|
content,
|
|
@@ -1744,21 +1789,21 @@ function OverlayPanel({
|
|
|
1744
1789
|
expanded && !extraContent && "gtv-info-panel--expanded-solo",
|
|
1745
1790
|
collapsed && "gtv-info-panel--collapsed"
|
|
1746
1791
|
].filter(Boolean).join(" ");
|
|
1747
|
-
return /* @__PURE__ */ (0,
|
|
1748
|
-
/* @__PURE__ */ (0,
|
|
1749
|
-
/* @__PURE__ */ (0,
|
|
1750
|
-
onExpandedChange && !hideExpandButton && /* @__PURE__ */ (0,
|
|
1751
|
-
!hideClose && /* @__PURE__ */ (0,
|
|
1792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className, ref: panelRef, children: [
|
|
1793
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "gtv-info-panel-header", children: [
|
|
1794
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: `gtv-info-panel-title${hideTitle ? " gtv-info-panel-title--hidden" : ""}`, children: title }),
|
|
1795
|
+
onExpandedChange && !hideExpandButton && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(InfoPanelExpandButton, { expanded, onExpandedChange }),
|
|
1796
|
+
!hideClose && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "gtv-info-panel-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_md6.MdClose, { className: "gtv-icon", size: 16 }) })
|
|
1752
1797
|
] }),
|
|
1753
|
-
/* @__PURE__ */ (0,
|
|
1754
|
-
/* @__PURE__ */ (0,
|
|
1755
|
-
extraContent && /* @__PURE__ */ (0,
|
|
1798
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "gtv-info-panel-body", children: [
|
|
1799
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "gtv-info-panel-aside gtv-overlay-content", children: content }),
|
|
1800
|
+
extraContent && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "gtv-info-panel-primary gtv-overlay-content", children: extraContent })
|
|
1756
1801
|
] })
|
|
1757
1802
|
] });
|
|
1758
1803
|
}
|
|
1759
1804
|
|
|
1760
1805
|
// src/GenreTree.tsx
|
|
1761
|
-
var
|
|
1806
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1762
1807
|
function GenreTree({
|
|
1763
1808
|
nodes,
|
|
1764
1809
|
className,
|
|
@@ -1786,10 +1831,6 @@ function GenreTree({
|
|
|
1786
1831
|
hideInfoPanelTitle = false,
|
|
1787
1832
|
itemCountLabel,
|
|
1788
1833
|
readOnly,
|
|
1789
|
-
editMode,
|
|
1790
|
-
onEditModeChange,
|
|
1791
|
-
renderTitleEditor,
|
|
1792
|
-
renderParentsEditor,
|
|
1793
1834
|
renderDangerZone,
|
|
1794
1835
|
expanded,
|
|
1795
1836
|
onExpandedChange,
|
|
@@ -1799,7 +1840,9 @@ function GenreTree({
|
|
|
1799
1840
|
wheelZoom,
|
|
1800
1841
|
defaultViewport,
|
|
1801
1842
|
onViewportChange,
|
|
1802
|
-
controlsOrientation = "vertical"
|
|
1843
|
+
controlsOrientation = "vertical",
|
|
1844
|
+
floatingControlsLeading,
|
|
1845
|
+
busy
|
|
1803
1846
|
}) {
|
|
1804
1847
|
const index = useTreeIndex(nodes);
|
|
1805
1848
|
const svgRef = (0, import_react8.useRef)(null);
|
|
@@ -1955,7 +1998,7 @@ function GenreTree({
|
|
|
1955
1998
|
hasInitialFitRef.current = true;
|
|
1956
1999
|
panZoom.fitToFrame(elements, { silent: true });
|
|
1957
2000
|
});
|
|
1958
|
-
const svg = /* @__PURE__ */ (0,
|
|
2001
|
+
const svg = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1959
2002
|
"svg",
|
|
1960
2003
|
{
|
|
1961
2004
|
ref: svgRef,
|
|
@@ -1965,13 +2008,14 @@ function GenreTree({
|
|
|
1965
2008
|
}
|
|
1966
2009
|
);
|
|
1967
2010
|
if (!interactive) {
|
|
1968
|
-
return /* @__PURE__ */ (0,
|
|
2011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className, children: svg });
|
|
1969
2012
|
}
|
|
1970
|
-
return /* @__PURE__ */ (0,
|
|
2013
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1971
2014
|
"div",
|
|
1972
2015
|
{
|
|
1973
2016
|
ref: viewportRef,
|
|
1974
2017
|
className,
|
|
2018
|
+
"aria-busy": busy,
|
|
1975
2019
|
style: {
|
|
1976
2020
|
position: "relative",
|
|
1977
2021
|
overflow: "hidden",
|
|
@@ -1994,7 +2038,7 @@ function GenreTree({
|
|
|
1994
2038
|
},
|
|
1995
2039
|
onPointerDown: panZoom.handlePointerDown,
|
|
1996
2040
|
children: [
|
|
1997
|
-
/* @__PURE__ */ (0,
|
|
2041
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1998
2042
|
"div",
|
|
1999
2043
|
{
|
|
2000
2044
|
ref: stageRef,
|
|
@@ -2008,7 +2052,7 @@ function GenreTree({
|
|
|
2008
2052
|
children: svg
|
|
2009
2053
|
}
|
|
2010
2054
|
),
|
|
2011
|
-
panel && /* @__PURE__ */ (0,
|
|
2055
|
+
panel && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2012
2056
|
InfoPanel,
|
|
2013
2057
|
{
|
|
2014
2058
|
node: panel.node,
|
|
@@ -2058,10 +2102,6 @@ function GenreTree({
|
|
|
2058
2102
|
hideTitle: hideInfoPanelTitle,
|
|
2059
2103
|
itemCountLabel,
|
|
2060
2104
|
readOnly,
|
|
2061
|
-
editMode,
|
|
2062
|
-
onEditModeChange,
|
|
2063
|
-
renderTitleEditor,
|
|
2064
|
-
renderParentsEditor,
|
|
2065
2105
|
renderDangerZone,
|
|
2066
2106
|
expanded,
|
|
2067
2107
|
onExpandedChange,
|
|
@@ -2080,54 +2120,15 @@ function GenreTree({
|
|
|
2080
2120
|
} : void 0
|
|
2081
2121
|
}
|
|
2082
2122
|
),
|
|
2083
|
-
overlayPanel && /* @__PURE__ */ (0,
|
|
2084
|
-
/* @__PURE__ */ (0,
|
|
2085
|
-
|
|
2123
|
+
overlayPanel && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(OverlayPanel, { ...overlayPanel }),
|
|
2124
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2125
|
+
FloatingControls,
|
|
2086
2126
|
{
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2093
|
-
"button",
|
|
2094
|
-
{
|
|
2095
|
-
type: "button",
|
|
2096
|
-
className: [
|
|
2097
|
-
"gtv-zoom-btn",
|
|
2098
|
-
!panZoom.canZoomIn && "gtv-zoom-btn--disabled"
|
|
2099
|
-
].filter(Boolean).join(" "),
|
|
2100
|
-
disabled: !panZoom.canZoomIn,
|
|
2101
|
-
onClick: panZoom.zoomIn,
|
|
2102
|
-
"aria-label": "Zoom in",
|
|
2103
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_md6.MdZoomIn, { className: "gtv-icon", size: 18 })
|
|
2104
|
-
}
|
|
2105
|
-
),
|
|
2106
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2107
|
-
"button",
|
|
2108
|
-
{
|
|
2109
|
-
type: "button",
|
|
2110
|
-
className: [
|
|
2111
|
-
"gtv-zoom-btn",
|
|
2112
|
-
!panZoom.canZoomOut && "gtv-zoom-btn--disabled"
|
|
2113
|
-
].filter(Boolean).join(" "),
|
|
2114
|
-
disabled: !panZoom.canZoomOut,
|
|
2115
|
-
onClick: panZoom.zoomOut,
|
|
2116
|
-
"aria-label": "Zoom out",
|
|
2117
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_md6.MdZoomOut, { className: "gtv-icon", size: 18 })
|
|
2118
|
-
}
|
|
2119
|
-
),
|
|
2120
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2121
|
-
"button",
|
|
2122
|
-
{
|
|
2123
|
-
type: "button",
|
|
2124
|
-
className: "gtv-zoom-btn",
|
|
2125
|
-
onClick: () => panZoom.fitToFrame(queryTreeContentElements(svgRef.current)),
|
|
2126
|
-
"aria-label": "Fit to frame",
|
|
2127
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_md6.MdFitScreen, { className: "gtv-icon", size: 18 })
|
|
2128
|
-
}
|
|
2129
|
-
)
|
|
2130
|
-
] })
|
|
2127
|
+
panZoom,
|
|
2128
|
+
orientation: controlsOrientation,
|
|
2129
|
+
leading: floatingControlsLeading,
|
|
2130
|
+
busy,
|
|
2131
|
+
onFit: () => panZoom.fitToFrame(queryTreeContentElements(svgRef.current))
|
|
2131
2132
|
}
|
|
2132
2133
|
)
|
|
2133
2134
|
]
|
|
@@ -2137,7 +2138,6 @@ function GenreTree({
|
|
|
2137
2138
|
|
|
2138
2139
|
// src/GenreTreeWheelBase.tsx
|
|
2139
2140
|
var import_react9 = require("react");
|
|
2140
|
-
var import_md7 = require("react-icons/md");
|
|
2141
2141
|
var d32 = __toESM(require("d3"), 1);
|
|
2142
2142
|
|
|
2143
2143
|
// src/root-grouping.ts
|
|
@@ -2213,7 +2213,7 @@ function computeRotationForSelection(currentRotationDeg, targetAngle, landingAng
|
|
|
2213
2213
|
}
|
|
2214
2214
|
|
|
2215
2215
|
// src/GenreTreeWheelBase.tsx
|
|
2216
|
-
var
|
|
2216
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2217
2217
|
function WheelCore({
|
|
2218
2218
|
nodes,
|
|
2219
2219
|
className,
|
|
@@ -2239,10 +2239,6 @@ function WheelCore({
|
|
|
2239
2239
|
hideInfoPanelTitle = false,
|
|
2240
2240
|
itemCountLabel,
|
|
2241
2241
|
readOnly,
|
|
2242
|
-
editMode,
|
|
2243
|
-
onEditModeChange,
|
|
2244
|
-
renderTitleEditor,
|
|
2245
|
-
renderParentsEditor,
|
|
2246
2242
|
renderDangerZone,
|
|
2247
2243
|
expanded,
|
|
2248
2244
|
onExpandedChange,
|
|
@@ -2253,6 +2249,8 @@ function WheelCore({
|
|
|
2253
2249
|
defaultViewport,
|
|
2254
2250
|
onViewportChange,
|
|
2255
2251
|
controlsOrientation = "vertical",
|
|
2252
|
+
floatingControlsLeading,
|
|
2253
|
+
busy,
|
|
2256
2254
|
selectedNodeId
|
|
2257
2255
|
}) {
|
|
2258
2256
|
const treeOrientation = direction === "left" ? "horizontal-anchored" : "vertical";
|
|
@@ -2368,10 +2366,11 @@ function WheelCore({
|
|
|
2368
2366
|
);
|
|
2369
2367
|
showNodeInfo(targetNode, element, viewportRef.current, { notify: false });
|
|
2370
2368
|
}, [selectedNodeId, effectiveRootId, nodes, panel, showNodeInfo]);
|
|
2371
|
-
return /* @__PURE__ */ (0,
|
|
2369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2372
2370
|
"div",
|
|
2373
2371
|
{
|
|
2374
2372
|
ref: viewportRef,
|
|
2373
|
+
"aria-busy": busy,
|
|
2375
2374
|
className: [
|
|
2376
2375
|
"gtv-wheel-container",
|
|
2377
2376
|
direction === "left" && "gtv-wheel-container--left",
|
|
@@ -2386,7 +2385,7 @@ function WheelCore({
|
|
|
2386
2385
|
},
|
|
2387
2386
|
onPointerDown: panZoom.handlePointerDown,
|
|
2388
2387
|
children: [
|
|
2389
|
-
/* @__PURE__ */ (0,
|
|
2388
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2390
2389
|
"div",
|
|
2391
2390
|
{
|
|
2392
2391
|
ref: stageRef,
|
|
@@ -2399,7 +2398,7 @@ function WheelCore({
|
|
|
2399
2398
|
transform: panZoom.transform,
|
|
2400
2399
|
transformOrigin: "0 0"
|
|
2401
2400
|
},
|
|
2402
|
-
children: /* @__PURE__ */ (0,
|
|
2401
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2403
2402
|
"div",
|
|
2404
2403
|
{
|
|
2405
2404
|
className: "gtv-wheel-stage",
|
|
@@ -2407,7 +2406,7 @@ function WheelCore({
|
|
|
2407
2406
|
[chipHalfExtentVar]: `${rootChipHalfExtent}px`
|
|
2408
2407
|
},
|
|
2409
2408
|
children: [
|
|
2410
|
-
selectedGroup && /* @__PURE__ */ (0,
|
|
2409
|
+
selectedGroup && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "gtv-wheel-tree-anchor", ref: treeAnchorRef, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2411
2410
|
GenreTree,
|
|
2412
2411
|
{
|
|
2413
2412
|
nodes: selectedGroup.nodes,
|
|
@@ -2445,9 +2444,9 @@ function WheelCore({
|
|
|
2445
2444
|
},
|
|
2446
2445
|
selectedGroup.root.id
|
|
2447
2446
|
) }),
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2449
|
-
centerLabel && /* @__PURE__ */ (0,
|
|
2450
|
-
/* @__PURE__ */ (0,
|
|
2447
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "gtv-wheel-circle", ref: wheelCircleRef }),
|
|
2448
|
+
centerLabel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "gtv-wheel-center-label", children: centerLabel }),
|
|
2449
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2451
2450
|
"div",
|
|
2452
2451
|
{
|
|
2453
2452
|
className: "gtv-wheel",
|
|
@@ -2455,7 +2454,7 @@ function WheelCore({
|
|
|
2455
2454
|
"--gtv-wheel-rotation": `${rotationDeg}deg`
|
|
2456
2455
|
},
|
|
2457
2456
|
children: [
|
|
2458
|
-
sectorFillGradient && /* @__PURE__ */ (0,
|
|
2457
|
+
sectorFillGradient && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2459
2458
|
"div",
|
|
2460
2459
|
{
|
|
2461
2460
|
className: "gtv-wheel-sector-fill",
|
|
@@ -2464,7 +2463,7 @@ function WheelCore({
|
|
|
2464
2463
|
}
|
|
2465
2464
|
}
|
|
2466
2465
|
),
|
|
2467
|
-
groups.length > 1 && groups.map((group, index) => /* @__PURE__ */ (0,
|
|
2466
|
+
groups.length > 1 && groups.map((group, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2468
2467
|
"div",
|
|
2469
2468
|
{
|
|
2470
2469
|
className: "gtv-wheel-divider",
|
|
@@ -2487,12 +2486,12 @@ function WheelCore({
|
|
|
2487
2486
|
rootItemCount,
|
|
2488
2487
|
rootItemCountRange
|
|
2489
2488
|
);
|
|
2490
|
-
return /* @__PURE__ */ (0,
|
|
2489
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2491
2490
|
"div",
|
|
2492
2491
|
{
|
|
2493
2492
|
className: "gtv-wheel-slot",
|
|
2494
2493
|
style: { "--gtv-chip-angle": `${angle}deg` },
|
|
2495
|
-
children: /* @__PURE__ */ (0,
|
|
2494
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "gtv-wheel-chip-anchor", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2496
2495
|
"button",
|
|
2497
2496
|
{
|
|
2498
2497
|
type: "button",
|
|
@@ -2528,8 +2527,8 @@ function WheelCore({
|
|
|
2528
2527
|
}
|
|
2529
2528
|
},
|
|
2530
2529
|
children: [
|
|
2531
|
-
PER_TREE_ACCENT_DOT && /* @__PURE__ */ (0,
|
|
2532
|
-
/* @__PURE__ */ (0,
|
|
2530
|
+
PER_TREE_ACCENT_DOT && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "gtv-wheel-chip-dot" }),
|
|
2531
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2533
2532
|
"span",
|
|
2534
2533
|
{
|
|
2535
2534
|
className: "gtv-node-label gtv-node-label--root",
|
|
@@ -2552,7 +2551,7 @@ function WheelCore({
|
|
|
2552
2551
|
)
|
|
2553
2552
|
}
|
|
2554
2553
|
),
|
|
2555
|
-
panel && /* @__PURE__ */ (0,
|
|
2554
|
+
panel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2556
2555
|
InfoPanel,
|
|
2557
2556
|
{
|
|
2558
2557
|
node: panel.node,
|
|
@@ -2599,10 +2598,6 @@ function WheelCore({
|
|
|
2599
2598
|
hideTitle: hideInfoPanelTitle,
|
|
2600
2599
|
itemCountLabel,
|
|
2601
2600
|
readOnly,
|
|
2602
|
-
editMode,
|
|
2603
|
-
onEditModeChange,
|
|
2604
|
-
renderTitleEditor,
|
|
2605
|
-
renderParentsEditor,
|
|
2606
2601
|
renderDangerZone,
|
|
2607
2602
|
expanded,
|
|
2608
2603
|
onExpandedChange,
|
|
@@ -2621,57 +2616,18 @@ function WheelCore({
|
|
|
2621
2616
|
} : void 0
|
|
2622
2617
|
}
|
|
2623
2618
|
),
|
|
2624
|
-
overlayPanel && /* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2626
|
-
|
|
2619
|
+
overlayPanel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(OverlayPanel, { ...overlayPanel }),
|
|
2620
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2621
|
+
FloatingControls,
|
|
2627
2622
|
{
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
type: "button",
|
|
2637
|
-
className: [
|
|
2638
|
-
"gtv-zoom-btn",
|
|
2639
|
-
!panZoom.canZoomIn && "gtv-zoom-btn--disabled"
|
|
2640
|
-
].filter(Boolean).join(" "),
|
|
2641
|
-
disabled: !panZoom.canZoomIn,
|
|
2642
|
-
onClick: panZoom.zoomIn,
|
|
2643
|
-
"aria-label": "Zoom in",
|
|
2644
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_md7.MdZoomIn, { className: "gtv-icon", size: 18 })
|
|
2645
|
-
}
|
|
2646
|
-
),
|
|
2647
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2648
|
-
"button",
|
|
2649
|
-
{
|
|
2650
|
-
type: "button",
|
|
2651
|
-
className: [
|
|
2652
|
-
"gtv-zoom-btn",
|
|
2653
|
-
!panZoom.canZoomOut && "gtv-zoom-btn--disabled"
|
|
2654
|
-
].filter(Boolean).join(" "),
|
|
2655
|
-
disabled: !panZoom.canZoomOut,
|
|
2656
|
-
onClick: panZoom.zoomOut,
|
|
2657
|
-
"aria-label": "Zoom out",
|
|
2658
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_md7.MdZoomOut, { className: "gtv-icon", size: 18 })
|
|
2659
|
-
}
|
|
2660
|
-
),
|
|
2661
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2662
|
-
"button",
|
|
2663
|
-
{
|
|
2664
|
-
type: "button",
|
|
2665
|
-
className: "gtv-zoom-btn",
|
|
2666
|
-
onClick: () => panZoom.fitToFrame([
|
|
2667
|
-
wheelCircleRef.current,
|
|
2668
|
-
...queryTreeContentElements(treeAnchorRef.current)
|
|
2669
|
-
]),
|
|
2670
|
-
"aria-label": "Fit to frame",
|
|
2671
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_md7.MdFitScreen, { className: "gtv-icon", size: 18 })
|
|
2672
|
-
}
|
|
2673
|
-
)
|
|
2674
|
-
] })
|
|
2623
|
+
panZoom,
|
|
2624
|
+
orientation: controlsOrientation,
|
|
2625
|
+
leading: floatingControlsLeading,
|
|
2626
|
+
busy,
|
|
2627
|
+
onFit: () => panZoom.fitToFrame([
|
|
2628
|
+
wheelCircleRef.current,
|
|
2629
|
+
...queryTreeContentElements(treeAnchorRef.current)
|
|
2630
|
+
])
|
|
2675
2631
|
}
|
|
2676
2632
|
)
|
|
2677
2633
|
]
|
|
@@ -2680,20 +2636,19 @@ function WheelCore({
|
|
|
2680
2636
|
}
|
|
2681
2637
|
|
|
2682
2638
|
// src/GenreTreeWheel.tsx
|
|
2683
|
-
var
|
|
2639
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2684
2640
|
function GenreTreeWheel(props) {
|
|
2685
|
-
return /* @__PURE__ */ (0,
|
|
2641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(WheelCore, { ...props, direction: "bottom" });
|
|
2686
2642
|
}
|
|
2687
2643
|
|
|
2688
2644
|
// src/GenreTreeWheelRight.tsx
|
|
2689
|
-
var
|
|
2645
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2690
2646
|
function GenreTreeWheelRight(props) {
|
|
2691
|
-
return /* @__PURE__ */ (0,
|
|
2647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(WheelCore, { ...props, direction: "left" });
|
|
2692
2648
|
}
|
|
2693
2649
|
|
|
2694
2650
|
// src/GenreTreeWheelRadialBase.tsx
|
|
2695
2651
|
var import_react10 = require("react");
|
|
2696
|
-
var import_md8 = require("react-icons/md");
|
|
2697
2652
|
var d33 = __toESM(require("d3"), 1);
|
|
2698
2653
|
|
|
2699
2654
|
// src/defer-click.ts
|
|
@@ -2877,6 +2832,7 @@ function pickEmptyLabelSpot(area, width, height, obstacles, prefer = () => true)
|
|
|
2877
2832
|
var POP_WEDGE_SPAN_DEGREES = 80;
|
|
2878
2833
|
var POP_SUBTREE_OUTER_MARGIN = 24;
|
|
2879
2834
|
var POP_HIERARCHY_ROOT_ABSOLUTE_DEPTH = 1;
|
|
2835
|
+
var DOT_RADIUS_TRANSITION_MS = 250;
|
|
2880
2836
|
function getRadialDepthRadius(depth, coreRootCircleRadius, depthSpacing) {
|
|
2881
2837
|
return coreRootCircleRadius + depth * depthSpacing;
|
|
2882
2838
|
}
|
|
@@ -2899,14 +2855,13 @@ function calculatePopSubtreeRadialExtent(hierarchy, coreRootCircleRadius = 0) {
|
|
|
2899
2855
|
POP_TREE_DEPTH_RADIAL_SPACING
|
|
2900
2856
|
) + MAX_NODE_WIDTH / 2 + POP_SUBTREE_OUTER_MARGIN;
|
|
2901
2857
|
}
|
|
2902
|
-
function computePopRadialLayout(d3Lib, hierarchy, wedgeCenterAngleDegrees, coreRootCircleRadius, wedgeSpanDegrees = POP_WEDGE_SPAN_DEGREES, depthSpacing = POP_TREE_DEPTH_RADIAL_SPACING
|
|
2858
|
+
function computePopRadialLayout(d3Lib, hierarchy, wedgeCenterAngleDegrees, coreRootCircleRadius, wedgeSpanDegrees = POP_WEDGE_SPAN_DEGREES, depthSpacing = POP_TREE_DEPTH_RADIAL_SPACING) {
|
|
2903
2859
|
return layoutWedge(
|
|
2904
2860
|
d3Lib,
|
|
2905
2861
|
hierarchy,
|
|
2906
2862
|
wedgeCenterAngleDegrees,
|
|
2907
2863
|
wedgeSpanDegrees,
|
|
2908
|
-
popRadiusOfDepth(coreRootCircleRadius, depthSpacing)
|
|
2909
|
-
itemCountRange
|
|
2864
|
+
popRadiusOfDepth(coreRootCircleRadius, depthSpacing)
|
|
2910
2865
|
);
|
|
2911
2866
|
}
|
|
2912
2867
|
var MIN_DOT_GAP = 5.6;
|
|
@@ -2916,15 +2871,15 @@ function popRadiusOfDepth(coreRootCircleRadius, depthSpacing) {
|
|
|
2916
2871
|
function coreRadiusOfDepth(coreRootCircleRadius, depthSpacing) {
|
|
2917
2872
|
return (depth) => getRadialDepthRadius(depth + 1, coreRootCircleRadius, depthSpacing);
|
|
2918
2873
|
}
|
|
2919
|
-
function measureWedge(_d3Lib, hierarchy, radiusOfDepth
|
|
2920
|
-
const dotRadius = (
|
|
2874
|
+
function measureWedge(_d3Lib, hierarchy, radiusOfDepth) {
|
|
2875
|
+
const dotRadius = () => NODE_LAYOUT_SLOT_RADIUS;
|
|
2921
2876
|
const offsetFromParent = /* @__PURE__ */ new Map();
|
|
2922
2877
|
const shiftLevel = (level, by) => ({
|
|
2923
2878
|
left: { ...level.left, x: level.left.x + by },
|
|
2924
2879
|
right: { ...level.right, x: level.right.x + by }
|
|
2925
2880
|
});
|
|
2926
2881
|
const pack = (node) => {
|
|
2927
|
-
const own = { x: 0, dotRadius: dotRadius(
|
|
2882
|
+
const own = { x: 0, dotRadius: dotRadius() };
|
|
2928
2883
|
if (!node.children) return [{ left: own, right: own }];
|
|
2929
2884
|
const below = [];
|
|
2930
2885
|
const childOffsets = [];
|
|
@@ -2956,7 +2911,7 @@ function measureWedge(_d3Lib, hierarchy, radiusOfDepth, itemCountRange) {
|
|
|
2956
2911
|
let min = Infinity;
|
|
2957
2912
|
let max = -Infinity;
|
|
2958
2913
|
hierarchy.each((d) => {
|
|
2959
|
-
const inset = (dotRadius(
|
|
2914
|
+
const inset = (dotRadius() + MIN_DOT_GAP / 2) / radiusOfDepth(d.depth);
|
|
2960
2915
|
min = Math.min(min, d.x - inset);
|
|
2961
2916
|
max = Math.max(max, d.x + inset);
|
|
2962
2917
|
});
|
|
@@ -2966,13 +2921,44 @@ function measureWedge(_d3Lib, hierarchy, radiusOfDepth, itemCountRange) {
|
|
|
2966
2921
|
return max - min;
|
|
2967
2922
|
}
|
|
2968
2923
|
var MAX_WEDGE_STRETCH = 1.42;
|
|
2969
|
-
function
|
|
2970
|
-
|
|
2924
|
+
function splitAtBranching(hierarchy) {
|
|
2925
|
+
let branching = hierarchy;
|
|
2926
|
+
const chain = [];
|
|
2927
|
+
while (branching.children?.length === 1) {
|
|
2928
|
+
chain.push(branching);
|
|
2929
|
+
branching = branching.children[0];
|
|
2930
|
+
}
|
|
2931
|
+
const children = branching.children;
|
|
2932
|
+
return children && children.length > 1 ? { chain, branching, children } : null;
|
|
2933
|
+
}
|
|
2934
|
+
function layoutWedge(d3Lib, hierarchy, wedgeCenterAngleDegrees, wedgeSpanDegrees, radiusOfDepth, slack = "center") {
|
|
2935
|
+
const neededRad = measureWedge(d3Lib, hierarchy, radiusOfDepth);
|
|
2971
2936
|
const wedgeSpanRad = wedgeSpanDegrees * Math.PI / 180;
|
|
2972
2937
|
const scale = Math.min(MAX_WEDGE_STRETCH, wedgeSpanRad / neededRad);
|
|
2973
|
-
const
|
|
2938
|
+
const wedgeCenterRad = wedgeCenterAngleDegrees * Math.PI / 180;
|
|
2939
|
+
const centeredStartRad = wedgeCenterRad - neededRad * scale / 2;
|
|
2940
|
+
const branchingSplit = slack === "between-children" ? splitAtBranching(hierarchy) : null;
|
|
2941
|
+
if (!branchingSplit) {
|
|
2942
|
+
hierarchy.each((d) => {
|
|
2943
|
+
const angleRad = centeredStartRad + d.x * scale;
|
|
2944
|
+
const radius = radiusOfDepth(d.depth);
|
|
2945
|
+
d.x = radius * Math.sin(angleRad);
|
|
2946
|
+
d.y = -radius * Math.cos(angleRad);
|
|
2947
|
+
});
|
|
2948
|
+
return hierarchy;
|
|
2949
|
+
}
|
|
2950
|
+
const { chain, branching, children } = branchingSplit;
|
|
2951
|
+
const gap = Math.max(0, wedgeSpanRad - neededRad * scale) / (children.length - 1);
|
|
2952
|
+
const wedgeStartRad = wedgeCenterRad - wedgeSpanRad / 2;
|
|
2953
|
+
const angleOffsetRad = /* @__PURE__ */ new Map();
|
|
2954
|
+
hierarchy.each((d) => angleOffsetRad.set(d, d.x * scale));
|
|
2955
|
+
children.forEach((child, i) => {
|
|
2956
|
+
child.each((d) => angleOffsetRad.set(d, angleOffsetRad.get(d) + i * gap));
|
|
2957
|
+
});
|
|
2958
|
+
const recenter = gap * (children.length - 1) / 2;
|
|
2959
|
+
[...chain, branching].forEach((d) => angleOffsetRad.set(d, angleOffsetRad.get(d) + recenter));
|
|
2974
2960
|
hierarchy.each((d) => {
|
|
2975
|
-
const angleRad = wedgeStartRad + d
|
|
2961
|
+
const angleRad = wedgeStartRad + angleOffsetRad.get(d);
|
|
2976
2962
|
const radius = radiusOfDepth(d.depth);
|
|
2977
2963
|
d.x = radius * Math.sin(angleRad);
|
|
2978
2964
|
d.y = -radius * Math.cos(angleRad);
|
|
@@ -3059,7 +3045,8 @@ function renderPopSubtree(d3Lib, svg, hierarchy, rootColor, reparentingNodeId, r
|
|
|
3059
3045
|
rootLinkOrigin,
|
|
3060
3046
|
isMainstreamSector = false,
|
|
3061
3047
|
selectedNodeId = null,
|
|
3062
|
-
nodeFillOf
|
|
3048
|
+
nodeFillOf,
|
|
3049
|
+
dotRadiusMemory
|
|
3063
3050
|
} = options;
|
|
3064
3051
|
const { onReparentTargetSelect, onNodeClick, onNodeDoubleClick, onNodeHover } = callbacks;
|
|
3065
3052
|
const isForbidden = (d) => reparentForbiddenIds.includes(d.data.id);
|
|
@@ -3122,13 +3109,18 @@ function renderPopSubtree(d3Lib, svg, hierarchy, rootColor, reparentingNodeId, r
|
|
|
3122
3109
|
);
|
|
3123
3110
|
d3Lib.select(this).attr("x", hitArea.x0).attr("y", hitArea.y0).attr("width", hitArea.x1 - hitArea.x0).attr("height", hitArea.y1 - hitArea.y0);
|
|
3124
3111
|
}).attr("fill", "transparent").attr("pointer-events", "all");
|
|
3125
|
-
|
|
3112
|
+
const targetDotRadius = (d) => calculateNodeDotRadius(d.data.itemCount, itemCountRange);
|
|
3113
|
+
const animateDots = dotRadiusMemory !== void 0 && !(typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches);
|
|
3114
|
+
const startDotRadius = (d) => (animateDots ? dotRadiusMemory?.get(d.data.id) : void 0) ?? targetDotRadius(d);
|
|
3115
|
+
nodes.append("circle").attr("class", "gtv-node-dot").attr("r", startDotRadius).attr("fill", nodeFill).attr(
|
|
3126
3116
|
"stroke",
|
|
3127
3117
|
(d) => isSelected(d) ? ACCENT_COLOR : isMainstreamSector ? TEXT_COLOR : SURFACE_BORDER_COLOR
|
|
3128
3118
|
).attr(
|
|
3129
3119
|
"stroke-width",
|
|
3130
3120
|
(d) => isSelected(d) ? calculateSelectedNodeBorderWidth(calculateNodeDotRadius(d.data.itemCount, itemCountRange)) : calculateNodeBorderWidth(d.data.itemCount, itemCountRange)
|
|
3131
|
-
).style("pointer-events", "none");
|
|
3121
|
+
).style("pointer-events", "none").filter((d) => startDotRadius(d) !== targetDotRadius(d)).transition().duration(DOT_RADIUS_TRANSITION_MS).ease(d3Lib.easeCubicOut).attr("r", targetDotRadius);
|
|
3122
|
+
nodes.each((d) => dotRadiusMemory?.set(d.data.id, targetDotRadius(d)));
|
|
3123
|
+
nodes.sort((a, b) => targetDotRadius(b) - targetDotRadius(a));
|
|
3132
3124
|
nodes.append("text").attr(
|
|
3133
3125
|
"class",
|
|
3134
3126
|
"gtv-node-label"
|
|
@@ -3251,14 +3243,14 @@ function buildCoreHierarchy(d3Lib, coreNodes) {
|
|
|
3251
3243
|
});
|
|
3252
3244
|
return hierarchy;
|
|
3253
3245
|
}
|
|
3254
|
-
function computeCoreRadialLayout(d3Lib, hierarchy, wedgeCenterAngleDegrees, wedgeSpanDegrees, coreRootCircleRadius, depthSpacing
|
|
3246
|
+
function computeCoreRadialLayout(d3Lib, hierarchy, wedgeCenterAngleDegrees, wedgeSpanDegrees, coreRootCircleRadius, depthSpacing) {
|
|
3255
3247
|
return layoutWedge(
|
|
3256
3248
|
d3Lib,
|
|
3257
3249
|
hierarchy,
|
|
3258
3250
|
wedgeCenterAngleDegrees,
|
|
3259
3251
|
wedgeSpanDegrees,
|
|
3260
3252
|
coreRadiusOfDepth(coreRootCircleRadius, depthSpacing),
|
|
3261
|
-
|
|
3253
|
+
"between-children"
|
|
3262
3254
|
);
|
|
3263
3255
|
}
|
|
3264
3256
|
function calculateCoreSubtreeRadialExtent(hierarchy, depthSpacing, coreRootCircleRadius = 0) {
|
|
@@ -3298,7 +3290,7 @@ function splitRootGroupBySide(group) {
|
|
|
3298
3290
|
}
|
|
3299
3291
|
|
|
3300
3292
|
// src/GenreTreeWheelRadialBase.tsx
|
|
3301
|
-
var
|
|
3293
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
3302
3294
|
var LANDING_ANGLE = 90;
|
|
3303
3295
|
function computeContinuousAngles(groups, layout, previous) {
|
|
3304
3296
|
const angles = /* @__PURE__ */ new Map();
|
|
@@ -3333,10 +3325,6 @@ function WheelRadialCore({
|
|
|
3333
3325
|
hideInfoPanelTitle = false,
|
|
3334
3326
|
itemCountLabel,
|
|
3335
3327
|
readOnly,
|
|
3336
|
-
editMode,
|
|
3337
|
-
onEditModeChange,
|
|
3338
|
-
renderTitleEditor,
|
|
3339
|
-
renderParentsEditor,
|
|
3340
3328
|
renderDangerZone,
|
|
3341
3329
|
expanded,
|
|
3342
3330
|
onExpandedChange,
|
|
@@ -3347,6 +3335,8 @@ function WheelRadialCore({
|
|
|
3347
3335
|
defaultViewport,
|
|
3348
3336
|
onViewportChange,
|
|
3349
3337
|
controlsOrientation = "vertical",
|
|
3338
|
+
floatingControlsLeading,
|
|
3339
|
+
busy,
|
|
3350
3340
|
selectedNodeId
|
|
3351
3341
|
}) {
|
|
3352
3342
|
const index = useTreeIndex(nodes);
|
|
@@ -3505,8 +3495,7 @@ function WheelRadialCore({
|
|
|
3505
3495
|
angle,
|
|
3506
3496
|
span,
|
|
3507
3497
|
wheelRadius,
|
|
3508
|
-
POP_TREE_DEPTH_RADIAL_SPACING
|
|
3509
|
-
wheelItemCountRange
|
|
3498
|
+
POP_TREE_DEPTH_RADIAL_SPACING
|
|
3510
3499
|
);
|
|
3511
3500
|
const reparentForbiddenIds = reparentingNodeId ? laidOut.descendants().find((d) => d.data.id === reparentingNodeId)?.descendants().map((d) => d.data.id) ?? [] : [];
|
|
3512
3501
|
const branchGroup = sectorGroup.append("g").attr("class", "gtv-wheel-core-branch").attr("data-gtv-branch-index", branchIndex);
|
|
@@ -3622,10 +3611,11 @@ function WheelRadialCore({
|
|
|
3622
3611
|
};
|
|
3623
3612
|
});
|
|
3624
3613
|
}, [groups, continuousAngleByRootId, sectorSpanByRootId]);
|
|
3625
|
-
return /* @__PURE__ */ (0,
|
|
3614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3626
3615
|
"div",
|
|
3627
3616
|
{
|
|
3628
3617
|
ref: viewportRef,
|
|
3618
|
+
"aria-busy": busy,
|
|
3629
3619
|
className: [
|
|
3630
3620
|
"gtv-wheel-container",
|
|
3631
3621
|
"gtv-wheel-container--radial",
|
|
@@ -3639,7 +3629,7 @@ function WheelRadialCore({
|
|
|
3639
3629
|
},
|
|
3640
3630
|
onPointerDown: panZoom.handlePointerDown,
|
|
3641
3631
|
children: [
|
|
3642
|
-
/* @__PURE__ */ (0,
|
|
3632
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3643
3633
|
"div",
|
|
3644
3634
|
{
|
|
3645
3635
|
ref: stageRef,
|
|
@@ -3652,9 +3642,9 @@ function WheelRadialCore({
|
|
|
3652
3642
|
transform: panZoom.transform,
|
|
3653
3643
|
transformOrigin: "0 0"
|
|
3654
3644
|
},
|
|
3655
|
-
children: /* @__PURE__ */ (0,
|
|
3656
|
-
/* @__PURE__ */ (0,
|
|
3657
|
-
/* @__PURE__ */ (0,
|
|
3645
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "gtv-wheel-stage", children: [
|
|
3646
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gtv-wheel-circle", ref: wheelCircleRef }),
|
|
3647
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gtv-wheel", children: sectorFills.map((sector) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3658
3648
|
"div",
|
|
3659
3649
|
{
|
|
3660
3650
|
className: "gtv-wheel-sector",
|
|
@@ -3666,7 +3656,7 @@ function WheelRadialCore({
|
|
|
3666
3656
|
},
|
|
3667
3657
|
`sector-${sector.rootId}`
|
|
3668
3658
|
)) }),
|
|
3669
|
-
/* @__PURE__ */ (0,
|
|
3659
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3670
3660
|
"svg",
|
|
3671
3661
|
{
|
|
3672
3662
|
ref: coreSvgRef,
|
|
@@ -3675,9 +3665,9 @@ function WheelRadialCore({
|
|
|
3675
3665
|
height: wheelRadius * 2
|
|
3676
3666
|
}
|
|
3677
3667
|
),
|
|
3678
|
-
centerLabel && /* @__PURE__ */ (0,
|
|
3679
|
-
/* @__PURE__ */ (0,
|
|
3680
|
-
dividerAngles.map((angle, index2) => /* @__PURE__ */ (0,
|
|
3668
|
+
centerLabel && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gtv-wheel-center-label", children: centerLabel }),
|
|
3669
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "gtv-wheel", children: [
|
|
3670
|
+
dividerAngles.map((angle, index2) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3681
3671
|
"div",
|
|
3682
3672
|
{
|
|
3683
3673
|
className: "gtv-wheel-divider",
|
|
@@ -3700,12 +3690,12 @@ function WheelRadialCore({
|
|
|
3700
3690
|
rootItemCount,
|
|
3701
3691
|
rootItemCountRange
|
|
3702
3692
|
);
|
|
3703
|
-
return /* @__PURE__ */ (0,
|
|
3693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3704
3694
|
"div",
|
|
3705
3695
|
{
|
|
3706
3696
|
className: "gtv-wheel-slot",
|
|
3707
3697
|
style: { "--gtv-chip-angle": `${angle}deg` },
|
|
3708
|
-
children: /* @__PURE__ */ (0,
|
|
3698
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gtv-wheel-chip-anchor", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3709
3699
|
"button",
|
|
3710
3700
|
{
|
|
3711
3701
|
type: "button",
|
|
@@ -3738,8 +3728,8 @@ function WheelRadialCore({
|
|
|
3738
3728
|
}
|
|
3739
3729
|
},
|
|
3740
3730
|
children: [
|
|
3741
|
-
PER_TREE_ACCENT_DOT && /* @__PURE__ */ (0,
|
|
3742
|
-
/* @__PURE__ */ (0,
|
|
3731
|
+
PER_TREE_ACCENT_DOT && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "gtv-wheel-chip-dot" }),
|
|
3732
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3743
3733
|
"span",
|
|
3744
3734
|
{
|
|
3745
3735
|
className: "gtv-node-label gtv-node-label--root",
|
|
@@ -3758,7 +3748,7 @@ function WheelRadialCore({
|
|
|
3758
3748
|
] })
|
|
3759
3749
|
}
|
|
3760
3750
|
),
|
|
3761
|
-
panel && /* @__PURE__ */ (0,
|
|
3751
|
+
panel && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3762
3752
|
InfoPanel,
|
|
3763
3753
|
{
|
|
3764
3754
|
node: panel.node,
|
|
@@ -3804,10 +3794,6 @@ function WheelRadialCore({
|
|
|
3804
3794
|
hideTitle: hideInfoPanelTitle,
|
|
3805
3795
|
itemCountLabel,
|
|
3806
3796
|
readOnly,
|
|
3807
|
-
editMode,
|
|
3808
|
-
onEditModeChange,
|
|
3809
|
-
renderTitleEditor,
|
|
3810
|
-
renderParentsEditor,
|
|
3811
3797
|
renderDangerZone,
|
|
3812
3798
|
expanded,
|
|
3813
3799
|
onExpandedChange,
|
|
@@ -3826,54 +3812,15 @@ function WheelRadialCore({
|
|
|
3826
3812
|
} : void 0
|
|
3827
3813
|
}
|
|
3828
3814
|
),
|
|
3829
|
-
overlayPanel && /* @__PURE__ */ (0,
|
|
3830
|
-
/* @__PURE__ */ (0,
|
|
3831
|
-
|
|
3815
|
+
overlayPanel && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(OverlayPanel, { ...overlayPanel }),
|
|
3816
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3817
|
+
FloatingControls,
|
|
3832
3818
|
{
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3839
|
-
"button",
|
|
3840
|
-
{
|
|
3841
|
-
type: "button",
|
|
3842
|
-
className: [
|
|
3843
|
-
"gtv-zoom-btn",
|
|
3844
|
-
!panZoom.canZoomIn && "gtv-zoom-btn--disabled"
|
|
3845
|
-
].filter(Boolean).join(" "),
|
|
3846
|
-
disabled: !panZoom.canZoomIn,
|
|
3847
|
-
onClick: panZoom.zoomIn,
|
|
3848
|
-
"aria-label": "Zoom in",
|
|
3849
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_md8.MdZoomIn, { className: "gtv-icon", size: 18 })
|
|
3850
|
-
}
|
|
3851
|
-
),
|
|
3852
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3853
|
-
"button",
|
|
3854
|
-
{
|
|
3855
|
-
type: "button",
|
|
3856
|
-
className: [
|
|
3857
|
-
"gtv-zoom-btn",
|
|
3858
|
-
!panZoom.canZoomOut && "gtv-zoom-btn--disabled"
|
|
3859
|
-
].filter(Boolean).join(" "),
|
|
3860
|
-
disabled: !panZoom.canZoomOut,
|
|
3861
|
-
onClick: panZoom.zoomOut,
|
|
3862
|
-
"aria-label": "Zoom out",
|
|
3863
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_md8.MdZoomOut, { className: "gtv-icon", size: 18 })
|
|
3864
|
-
}
|
|
3865
|
-
),
|
|
3866
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3867
|
-
"button",
|
|
3868
|
-
{
|
|
3869
|
-
type: "button",
|
|
3870
|
-
className: "gtv-zoom-btn",
|
|
3871
|
-
onClick: () => panZoom.fitToFrame([wheelCircleRef.current, coreSvgRef.current]),
|
|
3872
|
-
"aria-label": "Fit to frame",
|
|
3873
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_md8.MdFitScreen, { className: "gtv-icon", size: 18 })
|
|
3874
|
-
}
|
|
3875
|
-
)
|
|
3876
|
-
] })
|
|
3819
|
+
panZoom,
|
|
3820
|
+
orientation: controlsOrientation,
|
|
3821
|
+
leading: floatingControlsLeading,
|
|
3822
|
+
busy,
|
|
3823
|
+
onFit: () => panZoom.fitToFrame([wheelCircleRef.current, coreSvgRef.current])
|
|
3877
3824
|
}
|
|
3878
3825
|
)
|
|
3879
3826
|
]
|
|
@@ -3882,14 +3829,13 @@ function WheelRadialCore({
|
|
|
3882
3829
|
}
|
|
3883
3830
|
|
|
3884
3831
|
// src/GenreTreeWheelRadial.tsx
|
|
3885
|
-
var
|
|
3832
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3886
3833
|
function GenreTreeWheelRadial(props) {
|
|
3887
|
-
return /* @__PURE__ */ (0,
|
|
3834
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(WheelRadialCore, { ...props });
|
|
3888
3835
|
}
|
|
3889
3836
|
|
|
3890
3837
|
// src/GenreTreeWheelRadialPopCoreBase.tsx
|
|
3891
3838
|
var import_react13 = require("react");
|
|
3892
|
-
var import_md10 = require("react-icons/md");
|
|
3893
3839
|
var d34 = __toESM(require("d3"), 1);
|
|
3894
3840
|
|
|
3895
3841
|
// src/use-focus-history.ts
|
|
@@ -3918,17 +3864,17 @@ function useFocusHistory(focusNodeId, isFocusable) {
|
|
|
3918
3864
|
|
|
3919
3865
|
// src/WheelBreadcrumb.tsx
|
|
3920
3866
|
var import_react12 = require("react");
|
|
3921
|
-
var
|
|
3922
|
-
var
|
|
3867
|
+
var import_md7 = require("react-icons/md");
|
|
3868
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3923
3869
|
var MAX_VISIBLE_ANCESTORS = 3;
|
|
3924
3870
|
var ANCESTORS_KEPT_WHEN_COLLAPSED = 2;
|
|
3925
3871
|
function WheelBreadcrumb({ ancestors, currentName, onHome, onAncestor }) {
|
|
3926
3872
|
const [expanded, setExpanded] = (0, import_react12.useState)(false);
|
|
3927
3873
|
const collapsed = !expanded && ancestors.length > MAX_VISIBLE_ANCESTORS;
|
|
3928
3874
|
const visibleAncestors = collapsed ? ancestors.slice(-ANCESTORS_KEPT_WHEN_COLLAPSED) : ancestors;
|
|
3929
|
-
const separator = /* @__PURE__ */ (0,
|
|
3930
|
-
return /* @__PURE__ */ (0,
|
|
3931
|
-
/* @__PURE__ */ (0,
|
|
3875
|
+
const separator = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: "\u203A" });
|
|
3876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("nav", { className: "gtv-wheel-breadcrumb", "aria-label": "Breadcrumb", children: [
|
|
3877
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3932
3878
|
"button",
|
|
3933
3879
|
{
|
|
3934
3880
|
type: "button",
|
|
@@ -3936,12 +3882,12 @@ function WheelBreadcrumb({ ancestors, currentName, onHome, onAncestor }) {
|
|
|
3936
3882
|
"aria-label": "All genres",
|
|
3937
3883
|
title: "All genres",
|
|
3938
3884
|
onClick: onHome,
|
|
3939
|
-
children: /* @__PURE__ */ (0,
|
|
3885
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_md7.MdHome, { className: "gtv-icon", size: 14 })
|
|
3940
3886
|
}
|
|
3941
3887
|
),
|
|
3942
3888
|
separator,
|
|
3943
|
-
collapsed && /* @__PURE__ */ (0,
|
|
3944
|
-
/* @__PURE__ */ (0,
|
|
3889
|
+
collapsed && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
3890
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3945
3891
|
"button",
|
|
3946
3892
|
{
|
|
3947
3893
|
type: "button",
|
|
@@ -3954,11 +3900,11 @@ function WheelBreadcrumb({ ancestors, currentName, onHome, onAncestor }) {
|
|
|
3954
3900
|
),
|
|
3955
3901
|
separator
|
|
3956
3902
|
] }),
|
|
3957
|
-
visibleAncestors.map((ancestor) => /* @__PURE__ */ (0,
|
|
3958
|
-
/* @__PURE__ */ (0,
|
|
3903
|
+
visibleAncestors.map((ancestor) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react12.Fragment, { children: [
|
|
3904
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "gtv-wheel-breadcrumb-crumb", onClick: () => onAncestor(ancestor.id), children: ancestor.name }),
|
|
3959
3905
|
separator
|
|
3960
3906
|
] }, ancestor.id)),
|
|
3961
|
-
/* @__PURE__ */ (0,
|
|
3907
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "gtv-wheel-breadcrumb-current", "aria-current": "page", children: currentName })
|
|
3962
3908
|
] });
|
|
3963
3909
|
}
|
|
3964
3910
|
|
|
@@ -4019,7 +3965,7 @@ function resolvePopCoreFrame(nodes, focusNodeId) {
|
|
|
4019
3965
|
}
|
|
4020
3966
|
|
|
4021
3967
|
// src/GenreTreeWheelRadialPopCoreBase.tsx
|
|
4022
|
-
var
|
|
3968
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4023
3969
|
var LANDING_ANGLE2 = 90;
|
|
4024
3970
|
var CHIP_GAP = 16;
|
|
4025
3971
|
var sum = (values) => values.reduce((total, value) => total + value, 0);
|
|
@@ -4056,10 +4002,6 @@ function WheelRadialPopCoreCore({
|
|
|
4056
4002
|
hideInfoPanelTitle = false,
|
|
4057
4003
|
itemCountLabel,
|
|
4058
4004
|
readOnly,
|
|
4059
|
-
editMode,
|
|
4060
|
-
onEditModeChange,
|
|
4061
|
-
renderTitleEditor,
|
|
4062
|
-
renderParentsEditor,
|
|
4063
4005
|
renderDangerZone,
|
|
4064
4006
|
expanded,
|
|
4065
4007
|
onExpandedChange,
|
|
@@ -4070,6 +4012,8 @@ function WheelRadialPopCoreCore({
|
|
|
4070
4012
|
defaultViewport,
|
|
4071
4013
|
onViewportChange,
|
|
4072
4014
|
controlsOrientation = "vertical",
|
|
4015
|
+
floatingControlsLeading,
|
|
4016
|
+
busy,
|
|
4073
4017
|
allowWheelRotation = true,
|
|
4074
4018
|
selectedNodeId,
|
|
4075
4019
|
focusNodeId: requestedFocusNodeId = null,
|
|
@@ -4142,6 +4086,7 @@ function WheelRadialPopCoreCore({
|
|
|
4142
4086
|
}
|
|
4143
4087
|
const viewportRef = (0, import_react13.useRef)(null);
|
|
4144
4088
|
const stageRef = (0, import_react13.useRef)(null);
|
|
4089
|
+
const dotRadiusMemoryRef = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
|
|
4145
4090
|
const panZoom = usePanZoom(viewportRef, wheelZoom, stageRef, { defaultViewport, onViewportChange });
|
|
4146
4091
|
const { panel: openPanel, showNodeInfo, closeNodeInfo } = useNodeInfoPanel({ selectedNodeId, onSelectedNodeChange });
|
|
4147
4092
|
const isInFrame = (id) => id === focusNodeId || centerSubtreeNodeIds.has(id) || ringRootById.has(id);
|
|
@@ -4248,8 +4193,8 @@ function WheelRadialPopCoreCore({
|
|
|
4248
4193
|
centerSubtreeHierarchy,
|
|
4249
4194
|
0,
|
|
4250
4195
|
POP_TREE_DEPTH_RADIAL_SPACING
|
|
4251
|
-
) :
|
|
4252
|
-
[centerSubtreeHierarchy
|
|
4196
|
+
) : NODE_LAYOUT_SLOT_RADIUS,
|
|
4197
|
+
[centerSubtreeHierarchy]
|
|
4253
4198
|
);
|
|
4254
4199
|
const maxCoreExtentDelta = (0, import_react13.useMemo)(() => {
|
|
4255
4200
|
let extent = 0;
|
|
@@ -4257,11 +4202,7 @@ function WheelRadialPopCoreCore({
|
|
|
4257
4202
|
core.forEach((hierarchy) => {
|
|
4258
4203
|
extent = Math.max(
|
|
4259
4204
|
extent,
|
|
4260
|
-
calculateCoreSubtreeRadialExtent(
|
|
4261
|
-
hierarchy,
|
|
4262
|
-
POP_TREE_DEPTH_RADIAL_SPACING,
|
|
4263
|
-
0
|
|
4264
|
-
)
|
|
4205
|
+
calculateCoreSubtreeRadialExtent(hierarchy, POP_TREE_DEPTH_RADIAL_SPACING, 0)
|
|
4265
4206
|
);
|
|
4266
4207
|
});
|
|
4267
4208
|
});
|
|
@@ -4275,7 +4216,7 @@ function WheelRadialPopCoreCore({
|
|
|
4275
4216
|
(radius) => new Map(
|
|
4276
4217
|
groups.map((group) => {
|
|
4277
4218
|
const { pop, core } = branchHierarchiesByRootId.get(group.root.id);
|
|
4278
|
-
const chipWidth = 2 *
|
|
4219
|
+
const chipWidth = 2 * NODE_LAYOUT_SLOT_RADIUS;
|
|
4279
4220
|
return [
|
|
4280
4221
|
group.root.id,
|
|
4281
4222
|
{
|
|
@@ -4283,16 +4224,14 @@ function WheelRadialPopCoreCore({
|
|
|
4283
4224
|
(hierarchy) => measureWedge(
|
|
4284
4225
|
d34,
|
|
4285
4226
|
hierarchy,
|
|
4286
|
-
popRadiusOfDepth(radius, POP_TREE_DEPTH_RADIAL_SPACING)
|
|
4287
|
-
wheelItemCountRange
|
|
4227
|
+
popRadiusOfDepth(radius, POP_TREE_DEPTH_RADIAL_SPACING)
|
|
4288
4228
|
)
|
|
4289
4229
|
),
|
|
4290
4230
|
core: core.map(
|
|
4291
4231
|
(hierarchy) => measureWedge(
|
|
4292
4232
|
d34,
|
|
4293
4233
|
hierarchy,
|
|
4294
|
-
coreRadiusOfDepth(radius, POP_TREE_DEPTH_RADIAL_SPACING)
|
|
4295
|
-
wheelItemCountRange
|
|
4234
|
+
coreRadiusOfDepth(radius, POP_TREE_DEPTH_RADIAL_SPACING)
|
|
4296
4235
|
)
|
|
4297
4236
|
),
|
|
4298
4237
|
chip: 2 * Math.asin(Math.min(1, (chipWidth / 2 + CHIP_GAP) / radius))
|
|
@@ -4300,7 +4239,7 @@ function WheelRadialPopCoreCore({
|
|
|
4300
4239
|
];
|
|
4301
4240
|
})
|
|
4302
4241
|
),
|
|
4303
|
-
[groups, branchHierarchiesByRootId
|
|
4242
|
+
[groups, branchHierarchiesByRootId]
|
|
4304
4243
|
);
|
|
4305
4244
|
const coreRootCircleRadius = (0, import_react13.useMemo)(
|
|
4306
4245
|
() => solveRingRadius(
|
|
@@ -4418,8 +4357,7 @@ function WheelRadialPopCoreCore({
|
|
|
4418
4357
|
angle,
|
|
4419
4358
|
coreRootCircleRadius,
|
|
4420
4359
|
span,
|
|
4421
|
-
POP_TREE_DEPTH_RADIAL_SPACING
|
|
4422
|
-
wheelItemCountRange
|
|
4360
|
+
POP_TREE_DEPTH_RADIAL_SPACING
|
|
4423
4361
|
);
|
|
4424
4362
|
const reparentForbiddenIds = reparentingNodeId ? laidOut.descendants().find((d) => d.data.id === reparentingNodeId)?.descendants().map((d) => d.data.id) ?? [] : [];
|
|
4425
4363
|
const branchGroup = sectorGroup.append("g").attr("class", "gtv-wheel-pop-branch").attr("data-gtv-branch-index", branchIndex);
|
|
@@ -4463,6 +4401,7 @@ function WheelRadialPopCoreCore({
|
|
|
4463
4401
|
{
|
|
4464
4402
|
rootLinkOrigin,
|
|
4465
4403
|
selectedNodeId: panel?.node.id ?? null,
|
|
4404
|
+
dotRadiusMemory: dotRadiusMemoryRef.current,
|
|
4466
4405
|
nodeFillOf: (node) => getGenreNodeStyle(index, node.id).fill
|
|
4467
4406
|
}
|
|
4468
4407
|
);
|
|
@@ -4475,16 +4414,42 @@ function WheelRadialPopCoreCore({
|
|
|
4475
4414
|
);
|
|
4476
4415
|
const sectorGroup = originGroup.append("g").attr("class", "gtv-wheel-core-sector").attr("data-gtv-root-id", rootId);
|
|
4477
4416
|
branches.forEach(({ hierarchy, angle, span }, branchIndex) => {
|
|
4417
|
+
const undergroundIds = new Set(
|
|
4418
|
+
hierarchy.descendants().filter((d) => d.ancestors().some((a) => a.data.scene === "underground")).map((d) => d.data.id)
|
|
4419
|
+
);
|
|
4478
4420
|
const laidOut = computeCoreRadialLayout(
|
|
4479
4421
|
d34,
|
|
4480
4422
|
hierarchy,
|
|
4481
4423
|
angle,
|
|
4482
4424
|
span,
|
|
4483
4425
|
coreRootCircleRadius,
|
|
4484
|
-
POP_TREE_DEPTH_RADIAL_SPACING
|
|
4485
|
-
wheelItemCountRange
|
|
4426
|
+
POP_TREE_DEPTH_RADIAL_SPACING
|
|
4486
4427
|
);
|
|
4487
4428
|
const reparentForbiddenIds = reparentingNodeId ? laidOut.descendants().find((d) => d.data.id === reparentingNodeId)?.descendants().map((d) => d.data.id) ?? [] : [];
|
|
4429
|
+
const angleOf = (d) => {
|
|
4430
|
+
const deg = Math.atan2(d.x, -d.y) * 180 / Math.PI;
|
|
4431
|
+
return angle + ((deg - angle + 540) % 360 + 360) % 360 - 180;
|
|
4432
|
+
};
|
|
4433
|
+
const subtreeRange = (d) => {
|
|
4434
|
+
const angles = d.descendants().map(angleOf);
|
|
4435
|
+
return { min: Math.min(...angles), max: Math.max(...angles) };
|
|
4436
|
+
};
|
|
4437
|
+
laidOut.descendants().filter((d) => d.data.scene === "underground" && !d.ancestors().slice(1).some((a) => a.data.scene === "underground")).forEach((ug) => {
|
|
4438
|
+
const mine = subtreeRange(ug);
|
|
4439
|
+
const siblings = ug.parent?.children ?? [];
|
|
4440
|
+
const at = siblings.indexOf(ug);
|
|
4441
|
+
const prev = at > 0 ? siblings[at - 1] : void 0;
|
|
4442
|
+
const next = at >= 0 ? siblings[at + 1] : void 0;
|
|
4443
|
+
const startDeg = prev ? (subtreeRange(prev).max + mine.min) / 2 : angle - span / 2;
|
|
4444
|
+
const endDeg = next ? (mine.max + subtreeRange(next).min) / 2 : angle + span / 2;
|
|
4445
|
+
const arcPath = d34.arc()({
|
|
4446
|
+
innerRadius: coreRootCircleRadius,
|
|
4447
|
+
outerRadius: SCENE_SECTOR_OUTER_RADIUS,
|
|
4448
|
+
startAngle: startDeg * Math.PI / 180,
|
|
4449
|
+
endAngle: endDeg * Math.PI / 180
|
|
4450
|
+
});
|
|
4451
|
+
sectorGroup.append("path").attr("class", "gtv-wheel-scene-sector").attr("d", arcPath).attr("fill", shadeSurface(getGenreNodeColor(index, rootId), UNDERGROUND_DARKEN_RATIO)).attr("fill-opacity", UNDERGROUND_SECTOR_FILL_OPACITY);
|
|
4452
|
+
});
|
|
4488
4453
|
const branchGroup = sectorGroup.append("g").attr("class", "gtv-wheel-core-branch").attr("data-gtv-branch-index", branchIndex);
|
|
4489
4454
|
renderPopSubtree(
|
|
4490
4455
|
d34,
|
|
@@ -4527,7 +4492,11 @@ function WheelRadialPopCoreCore({
|
|
|
4527
4492
|
isCoreSector: true,
|
|
4528
4493
|
rootLinkOrigin,
|
|
4529
4494
|
selectedNodeId: panel?.node.id ?? null,
|
|
4530
|
-
|
|
4495
|
+
dotRadiusMemory: dotRadiusMemoryRef.current,
|
|
4496
|
+
nodeFillOf: (node) => {
|
|
4497
|
+
const fill = getGenreNodeStyle(index, node.id).fill;
|
|
4498
|
+
return undergroundIds.has(node.id) ? shadeSurface(fill, UNDERGROUND_DARKEN_RATIO) : fill;
|
|
4499
|
+
}
|
|
4531
4500
|
}
|
|
4532
4501
|
);
|
|
4533
4502
|
});
|
|
@@ -4582,6 +4551,7 @@ function WheelRadialPopCoreCore({
|
|
|
4582
4551
|
skipRootNode: true,
|
|
4583
4552
|
isMainstreamSector: isCenterMainstream,
|
|
4584
4553
|
selectedNodeId: panel?.node.id ?? null,
|
|
4554
|
+
dotRadiusMemory: dotRadiusMemoryRef.current,
|
|
4585
4555
|
nodeFillOf: (node) => getGenreNodeStyle(index, node.id).fill
|
|
4586
4556
|
}
|
|
4587
4557
|
);
|
|
@@ -4777,10 +4747,11 @@ function WheelRadialPopCoreCore({
|
|
|
4777
4747
|
};
|
|
4778
4748
|
});
|
|
4779
4749
|
}, [groups, continuousAngleByRootId, sectorSpanByRootId]);
|
|
4780
|
-
return /* @__PURE__ */ (0,
|
|
4750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4781
4751
|
"div",
|
|
4782
4752
|
{
|
|
4783
4753
|
ref: viewportRef,
|
|
4754
|
+
"aria-busy": busy,
|
|
4784
4755
|
className: [
|
|
4785
4756
|
"gtv-wheel-container",
|
|
4786
4757
|
"gtv-wheel-container--radial",
|
|
@@ -4795,7 +4766,7 @@ function WheelRadialPopCoreCore({
|
|
|
4795
4766
|
},
|
|
4796
4767
|
onPointerDown: panZoom.handlePointerDown,
|
|
4797
4768
|
children: [
|
|
4798
|
-
/* @__PURE__ */ (0,
|
|
4769
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
4799
4770
|
"div",
|
|
4800
4771
|
{
|
|
4801
4772
|
ref: stageRef,
|
|
@@ -4809,9 +4780,9 @@ function WheelRadialPopCoreCore({
|
|
|
4809
4780
|
transformOrigin: "0 0"
|
|
4810
4781
|
},
|
|
4811
4782
|
children: [
|
|
4812
|
-
/* @__PURE__ */ (0,
|
|
4813
|
-
/* @__PURE__ */ (0,
|
|
4814
|
-
isPopExpanded && /* @__PURE__ */ (0,
|
|
4783
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "gtv-wheel-stage", children: [
|
|
4784
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "gtv-wheel-circle", ref: wheelCircleRef }),
|
|
4785
|
+
isPopExpanded && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4815
4786
|
"div",
|
|
4816
4787
|
{
|
|
4817
4788
|
className: "gtv-wheel-middle-circle",
|
|
@@ -4820,8 +4791,8 @@ function WheelRadialPopCoreCore({
|
|
|
4820
4791
|
}
|
|
4821
4792
|
}
|
|
4822
4793
|
),
|
|
4823
|
-
/* @__PURE__ */ (0,
|
|
4824
|
-
sectorFills.map((sector) => /* @__PURE__ */ (0,
|
|
4794
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "gtv-wheel", children: [
|
|
4795
|
+
sectorFills.map((sector) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4825
4796
|
"div",
|
|
4826
4797
|
{
|
|
4827
4798
|
className: "gtv-wheel-sector",
|
|
@@ -4833,8 +4804,8 @@ function WheelRadialPopCoreCore({
|
|
|
4833
4804
|
},
|
|
4834
4805
|
`sector-${sector.rootId}`
|
|
4835
4806
|
)),
|
|
4836
|
-
/* @__PURE__ */ (0,
|
|
4837
|
-
isPopExpanded && /* @__PURE__ */ (0,
|
|
4807
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "gtv-wheel-inner-tint" }),
|
|
4808
|
+
isPopExpanded && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4838
4809
|
"div",
|
|
4839
4810
|
{
|
|
4840
4811
|
className: "gtv-wheel-middle-tint",
|
|
@@ -4844,7 +4815,7 @@ function WheelRadialPopCoreCore({
|
|
|
4844
4815
|
}
|
|
4845
4816
|
)
|
|
4846
4817
|
] }),
|
|
4847
|
-
/* @__PURE__ */ (0,
|
|
4818
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4848
4819
|
"svg",
|
|
4849
4820
|
{
|
|
4850
4821
|
ref: popSvgRef,
|
|
@@ -4853,7 +4824,7 @@ function WheelRadialPopCoreCore({
|
|
|
4853
4824
|
height: svgCanvasRadius * 2
|
|
4854
4825
|
}
|
|
4855
4826
|
),
|
|
4856
|
-
/* @__PURE__ */ (0,
|
|
4827
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "gtv-wheel-center-node", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "gtv-wheel-chip-anchor", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4857
4828
|
"button",
|
|
4858
4829
|
{
|
|
4859
4830
|
ref: centerChipRef,
|
|
@@ -4891,8 +4862,8 @@ function WheelRadialPopCoreCore({
|
|
|
4891
4862
|
"aria-label": centerNode.name
|
|
4892
4863
|
}
|
|
4893
4864
|
) }) }),
|
|
4894
|
-
/* @__PURE__ */ (0,
|
|
4895
|
-
dividerAngles.map((angle, index2) => /* @__PURE__ */ (0,
|
|
4865
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "gtv-wheel", children: [
|
|
4866
|
+
dividerAngles.map((angle, index2) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4896
4867
|
"div",
|
|
4897
4868
|
{
|
|
4898
4869
|
className: "gtv-wheel-divider",
|
|
@@ -4911,12 +4882,12 @@ function WheelRadialPopCoreCore({
|
|
|
4911
4882
|
group.root.id
|
|
4912
4883
|
);
|
|
4913
4884
|
const diameter = 2 * calculateNodeDotRadius(rootItemCount, wheelItemCountRange);
|
|
4914
|
-
return /* @__PURE__ */ (0,
|
|
4885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4915
4886
|
"div",
|
|
4916
4887
|
{
|
|
4917
4888
|
className: "gtv-wheel-slot",
|
|
4918
4889
|
style: { "--gtv-chip-angle": `${angle}deg` },
|
|
4919
|
-
children: /* @__PURE__ */ (0,
|
|
4890
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "gtv-wheel-chip-anchor", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4920
4891
|
"button",
|
|
4921
4892
|
{
|
|
4922
4893
|
type: "button",
|
|
@@ -4958,7 +4929,7 @@ function WheelRadialPopCoreCore({
|
|
|
4958
4929
|
})
|
|
4959
4930
|
] })
|
|
4960
4931
|
] }),
|
|
4961
|
-
regionLabel && index.byId.has(regionLabel.rootId) && /* @__PURE__ */ (0,
|
|
4932
|
+
regionLabel && index.byId.has(regionLabel.rootId) && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4962
4933
|
"div",
|
|
4963
4934
|
{
|
|
4964
4935
|
ref: regionLabelRef,
|
|
@@ -4976,7 +4947,7 @@ function WheelRadialPopCoreCore({
|
|
|
4976
4947
|
]
|
|
4977
4948
|
}
|
|
4978
4949
|
),
|
|
4979
|
-
panel && /* @__PURE__ */ (0,
|
|
4950
|
+
panel && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
4980
4951
|
InfoPanel,
|
|
4981
4952
|
{
|
|
4982
4953
|
node: panel.node,
|
|
@@ -5003,10 +4974,6 @@ function WheelRadialPopCoreCore({
|
|
|
5003
4974
|
hideTitle: hideInfoPanelTitle,
|
|
5004
4975
|
itemCountLabel,
|
|
5005
4976
|
readOnly,
|
|
5006
|
-
editMode,
|
|
5007
|
-
onEditModeChange,
|
|
5008
|
-
renderTitleEditor,
|
|
5009
|
-
renderParentsEditor,
|
|
5010
4977
|
renderDangerZone,
|
|
5011
4978
|
expanded,
|
|
5012
4979
|
onExpandedChange,
|
|
@@ -5026,8 +4993,8 @@ function WheelRadialPopCoreCore({
|
|
|
5026
4993
|
onZoomIn: onFocusChange && panel.node.id !== focusNodeId && isZoomableNode(nodes, panel.node.id) ? () => onFocusChange(panel.node.id, "zoom-in") : void 0
|
|
5027
4994
|
}
|
|
5028
4995
|
),
|
|
5029
|
-
overlayPanel && /* @__PURE__ */ (0,
|
|
5030
|
-
onFocusChange && focusNodeId !== null && /* @__PURE__ */ (0,
|
|
4996
|
+
overlayPanel && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(OverlayPanel, { ...overlayPanel }),
|
|
4997
|
+
onFocusChange && focusNodeId !== null && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5031
4998
|
WheelBreadcrumb,
|
|
5032
4999
|
{
|
|
5033
5000
|
ancestors: index.ancestorsOf(focusNodeId).filter((ancestor) => isZoomableNode(nodes, ancestor.id)),
|
|
@@ -5043,56 +5010,17 @@ function WheelRadialPopCoreCore({
|
|
|
5043
5010
|
},
|
|
5044
5011
|
focusNodeId
|
|
5045
5012
|
),
|
|
5046
|
-
/* @__PURE__ */ (0,
|
|
5047
|
-
|
|
5013
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5014
|
+
FloatingControls,
|
|
5048
5015
|
{
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
type: "button",
|
|
5058
|
-
className: [
|
|
5059
|
-
"gtv-zoom-btn",
|
|
5060
|
-
!panZoom.canZoomIn && "gtv-zoom-btn--disabled"
|
|
5061
|
-
].filter(Boolean).join(" "),
|
|
5062
|
-
disabled: !panZoom.canZoomIn,
|
|
5063
|
-
onClick: panZoom.zoomIn,
|
|
5064
|
-
"aria-label": "Zoom in",
|
|
5065
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_md10.MdZoomIn, { className: "gtv-icon", size: 18 })
|
|
5066
|
-
}
|
|
5067
|
-
),
|
|
5068
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5069
|
-
"button",
|
|
5070
|
-
{
|
|
5071
|
-
type: "button",
|
|
5072
|
-
className: [
|
|
5073
|
-
"gtv-zoom-btn",
|
|
5074
|
-
!panZoom.canZoomOut && "gtv-zoom-btn--disabled"
|
|
5075
|
-
].filter(Boolean).join(" "),
|
|
5076
|
-
disabled: !panZoom.canZoomOut,
|
|
5077
|
-
onClick: panZoom.zoomOut,
|
|
5078
|
-
"aria-label": "Zoom out",
|
|
5079
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_md10.MdZoomOut, { className: "gtv-icon", size: 18 })
|
|
5080
|
-
}
|
|
5081
|
-
),
|
|
5082
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5083
|
-
"button",
|
|
5084
|
-
{
|
|
5085
|
-
type: "button",
|
|
5086
|
-
className: "gtv-zoom-btn",
|
|
5087
|
-
onClick: () => panZoom.fitToFrame([
|
|
5088
|
-
wheelCircleRef.current,
|
|
5089
|
-
...queryTreeContentElements(popSvgRef.current)
|
|
5090
|
-
]),
|
|
5091
|
-
"aria-label": "Fit to frame",
|
|
5092
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_md10.MdFitScreen, { className: "gtv-icon", size: 18 })
|
|
5093
|
-
}
|
|
5094
|
-
)
|
|
5095
|
-
] })
|
|
5016
|
+
panZoom,
|
|
5017
|
+
orientation: controlsOrientation,
|
|
5018
|
+
leading: floatingControlsLeading,
|
|
5019
|
+
busy,
|
|
5020
|
+
onFit: () => panZoom.fitToFrame([
|
|
5021
|
+
wheelCircleRef.current,
|
|
5022
|
+
...queryTreeContentElements(popSvgRef.current)
|
|
5023
|
+
])
|
|
5096
5024
|
}
|
|
5097
5025
|
)
|
|
5098
5026
|
]
|
|
@@ -5101,14 +5029,14 @@ function WheelRadialPopCoreCore({
|
|
|
5101
5029
|
}
|
|
5102
5030
|
|
|
5103
5031
|
// src/GenreTreeWheelRadialPopCore.tsx
|
|
5104
|
-
var
|
|
5032
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5105
5033
|
function GenreTreeWheelRadialPopCore(props) {
|
|
5106
|
-
return /* @__PURE__ */ (0,
|
|
5034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(WheelRadialPopCoreCore, { ...props });
|
|
5107
5035
|
}
|
|
5108
5036
|
|
|
5109
5037
|
// src/GenreTreeOutline.tsx
|
|
5110
5038
|
var import_react14 = require("react");
|
|
5111
|
-
var
|
|
5039
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5112
5040
|
function createOutlineStore(initial) {
|
|
5113
5041
|
let state = initial;
|
|
5114
5042
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -5182,9 +5110,9 @@ function OutlineNodeView({
|
|
|
5182
5110
|
const { itemCount } = node;
|
|
5183
5111
|
const children = model.index.childrenByParentId.get(nodeId) ?? [];
|
|
5184
5112
|
const split = isRoot ? model.ringSplitById.get(nodeId) : void 0;
|
|
5185
|
-
const row = /* @__PURE__ */ (0,
|
|
5186
|
-
/* @__PURE__ */ (0,
|
|
5187
|
-
/* @__PURE__ */ (0,
|
|
5113
|
+
const row = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: ["gtv-outline-row", isSelected && "gtv-outline-row--selected"].filter(Boolean).join(" "), children: [
|
|
5114
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "gtv-outline-dot", style: { background: model.styleOf(node).fill } }),
|
|
5115
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5188
5116
|
"button",
|
|
5189
5117
|
{
|
|
5190
5118
|
type: "button",
|
|
@@ -5201,16 +5129,16 @@ function OutlineNodeView({
|
|
|
5201
5129
|
children: node.name
|
|
5202
5130
|
}
|
|
5203
5131
|
),
|
|
5204
|
-
/* @__PURE__ */ (0,
|
|
5132
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "gtv-outline-count", children: itemCount })
|
|
5205
5133
|
] });
|
|
5206
5134
|
const itemProps = { model, store, callbacks };
|
|
5207
|
-
return /* @__PURE__ */ (0,
|
|
5208
|
-
/* @__PURE__ */ (0,
|
|
5209
|
-
isOpen && /* @__PURE__ */ (0,
|
|
5210
|
-
/* @__PURE__ */ (0,
|
|
5211
|
-
/* @__PURE__ */ (0,
|
|
5212
|
-
] }) : children.map((child) => /* @__PURE__ */ (0,
|
|
5213
|
-
] }) : /* @__PURE__ */ (0,
|
|
5135
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("li", { className: "gtv-outline-item", "data-gtv-node-id": nodeId, children: children.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("details", { open: isOpen, children: [
|
|
5136
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("summary", { onClick: (event) => handleSummaryClick(event, () => callbacks.toggleOpen(nodeId)), children: row }),
|
|
5137
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("ul", { className: "gtv-outline-list", children: split ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
5138
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OutlineSection, { rootId: nodeId, kind: "core", branches: split.coreBranches, ...itemProps }),
|
|
5139
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OutlineSection, { rootId: nodeId, kind: "pop", branches: split.popBranches, ...itemProps })
|
|
5140
|
+
] }) : children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OutlineNode, { nodeId: child.id, isRoot: false, ...itemProps }, child.id)) })
|
|
5141
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "gtv-outline-leaf", children: row }) });
|
|
5214
5142
|
}
|
|
5215
5143
|
var OutlineNode = (0, import_react14.memo)(OutlineNodeView);
|
|
5216
5144
|
var OutlineSection = (0, import_react14.memo)(function OutlineSection2({
|
|
@@ -5224,9 +5152,9 @@ var OutlineSection = (0, import_react14.memo)(function OutlineSection2({
|
|
|
5224
5152
|
const key = sectionKey(kind, rootId);
|
|
5225
5153
|
const isOpen = useOutlineState(store, (s) => s.openIds.has(key));
|
|
5226
5154
|
if (branches.length === 0) return null;
|
|
5227
|
-
return /* @__PURE__ */ (0,
|
|
5228
|
-
/* @__PURE__ */ (0,
|
|
5229
|
-
isOpen && /* @__PURE__ */ (0,
|
|
5155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("li", { className: "gtv-outline-item", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("details", { open: isOpen, children: [
|
|
5156
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("summary", { onClick: (event) => handleSummaryClick(event, () => callbacks.toggleOpen(key)), children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "gtv-outline-section-label", children: kind === "core" ? "Core" : "Pop" }) }),
|
|
5157
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("ul", { className: "gtv-outline-list", children: branches.map(({ child }) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OutlineNode, { nodeId: child.id, isRoot: false, model, store, callbacks }, child.id)) })
|
|
5230
5158
|
] }) });
|
|
5231
5159
|
});
|
|
5232
5160
|
function GenreTreeOutline(props) {
|
|
@@ -5243,10 +5171,6 @@ function GenreTreeOutline(props) {
|
|
|
5243
5171
|
hideInfoPanelTitle = false,
|
|
5244
5172
|
itemCountLabel,
|
|
5245
5173
|
readOnly,
|
|
5246
|
-
editMode,
|
|
5247
|
-
onEditModeChange,
|
|
5248
|
-
renderTitleEditor,
|
|
5249
|
-
renderParentsEditor,
|
|
5250
5174
|
renderDangerZone,
|
|
5251
5175
|
expanded,
|
|
5252
5176
|
onExpandedChange,
|
|
@@ -5347,12 +5271,12 @@ function GenreTreeOutline(props) {
|
|
|
5347
5271
|
}, [selectedNodeId, store]);
|
|
5348
5272
|
const selectedNode = selectedId === null ? void 0 : index.byId.get(selectedId);
|
|
5349
5273
|
const itemProps = { model, store, callbacks };
|
|
5350
|
-
return /* @__PURE__ */ (0,
|
|
5351
|
-
/* @__PURE__ */ (0,
|
|
5352
|
-
/* @__PURE__ */ (0,
|
|
5353
|
-
model.detachedRoots.length > 0 && /* @__PURE__ */ (0,
|
|
5274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: ["gtv-outline", selectedNode && "gtv-outline--panel-open", className].filter(Boolean).join(" "), children: [
|
|
5275
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "gtv-outline-scroll", ref: scrollRef, children: [
|
|
5276
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("ul", { className: "gtv-outline-list gtv-outline-list--roots", children: [model.centerRoot, ...model.ringRoots].map((root) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OutlineNode, { nodeId: root.id, isRoot: true, ...itemProps }, root.id)) }),
|
|
5277
|
+
model.detachedRoots.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("ul", { className: "gtv-outline-list gtv-outline-list--roots gtv-outline-list--detached", children: model.detachedRoots.map((root) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OutlineNode, { nodeId: root.id, isRoot: true, ...itemProps }, root.id)) })
|
|
5354
5278
|
] }),
|
|
5355
|
-
selectedNode && /* @__PURE__ */ (0,
|
|
5279
|
+
selectedNode && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5356
5280
|
InfoPanel,
|
|
5357
5281
|
{
|
|
5358
5282
|
node: selectedNode,
|
|
@@ -5373,10 +5297,6 @@ function GenreTreeOutline(props) {
|
|
|
5373
5297
|
hideTitle: hideInfoPanelTitle,
|
|
5374
5298
|
itemCountLabel,
|
|
5375
5299
|
readOnly,
|
|
5376
|
-
editMode,
|
|
5377
|
-
onEditModeChange,
|
|
5378
|
-
renderTitleEditor,
|
|
5379
|
-
renderParentsEditor,
|
|
5380
5300
|
renderDangerZone,
|
|
5381
5301
|
expanded,
|
|
5382
5302
|
onExpandedChange,
|
|
@@ -5395,13 +5315,13 @@ function GenreTreeOutline(props) {
|
|
|
5395
5315
|
} : void 0
|
|
5396
5316
|
}
|
|
5397
5317
|
),
|
|
5398
|
-
overlayPanel && /* @__PURE__ */ (0,
|
|
5318
|
+
overlayPanel && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(OverlayPanel, { ...overlayPanel })
|
|
5399
5319
|
] });
|
|
5400
5320
|
}
|
|
5401
5321
|
|
|
5402
5322
|
// src/GenreTreeSkeleton.tsx
|
|
5403
5323
|
var import_react15 = require("react");
|
|
5404
|
-
var
|
|
5324
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5405
5325
|
var CARD_FILL = "#F4F4F5";
|
|
5406
5326
|
var CARD_BORDER_COLOR = "#E4E4E7";
|
|
5407
5327
|
var CONNECTOR_COLOR2 = "#D4D4D8";
|
|
@@ -5506,8 +5426,8 @@ function SkeletonCard({
|
|
|
5506
5426
|
card,
|
|
5507
5427
|
rootAccent
|
|
5508
5428
|
}) {
|
|
5509
|
-
return /* @__PURE__ */ (0,
|
|
5510
|
-
/* @__PURE__ */ (0,
|
|
5429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5430
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5511
5431
|
"rect",
|
|
5512
5432
|
{
|
|
5513
5433
|
x: card.x,
|
|
@@ -5521,7 +5441,7 @@ function SkeletonCard({
|
|
|
5521
5441
|
strokeWidth: rootAccent ? 1.5 : 1
|
|
5522
5442
|
}
|
|
5523
5443
|
),
|
|
5524
|
-
rootAccent && /* @__PURE__ */ (0,
|
|
5444
|
+
rootAccent && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5525
5445
|
"circle",
|
|
5526
5446
|
{
|
|
5527
5447
|
cx: card.x + 18,
|
|
@@ -5539,9 +5459,9 @@ function GenreTreeSkeleton() {
|
|
|
5539
5459
|
const animationName = `genre-tree-skeleton-sweep-${uid}`;
|
|
5540
5460
|
const shimmerBandClass = `genre-tree-skeleton-shimmer-band-${uid}`;
|
|
5541
5461
|
const sweepDistance = VIEWBOX_WIDTH + SHIMMER_BAND_WIDTH;
|
|
5542
|
-
return /* @__PURE__ */ (0,
|
|
5543
|
-
/* @__PURE__ */ (0,
|
|
5544
|
-
/* @__PURE__ */ (0,
|
|
5462
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "gtv-skeleton", children: [
|
|
5463
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "gtv-skeleton-sr-only", children: "Loading genre tree\u2026" }),
|
|
5464
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5545
5465
|
"svg",
|
|
5546
5466
|
{
|
|
5547
5467
|
viewBox: `0 0 ${VIEWBOX_WIDTH} ${VIEWBOX_HEIGHT}`,
|
|
@@ -5550,7 +5470,7 @@ function GenreTreeSkeleton() {
|
|
|
5550
5470
|
className: "gtv-skeleton-svg",
|
|
5551
5471
|
"aria-hidden": "true",
|
|
5552
5472
|
children: [
|
|
5553
|
-
/* @__PURE__ */ (0,
|
|
5473
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("style", { children: `
|
|
5554
5474
|
@keyframes ${animationName} {
|
|
5555
5475
|
from { transform: translateX(0); }
|
|
5556
5476
|
to { transform: translateX(${sweepDistance}px); }
|
|
@@ -5564,9 +5484,9 @@ function GenreTreeSkeleton() {
|
|
|
5564
5484
|
}
|
|
5565
5485
|
}
|
|
5566
5486
|
` }),
|
|
5567
|
-
/* @__PURE__ */ (0,
|
|
5568
|
-
/* @__PURE__ */ (0,
|
|
5569
|
-
/* @__PURE__ */ (0,
|
|
5487
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("defs", { children: [
|
|
5488
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "1", y2: "0", children: [
|
|
5489
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5570
5490
|
"stop",
|
|
5571
5491
|
{
|
|
5572
5492
|
offset: "0%",
|
|
@@ -5574,7 +5494,7 @@ function GenreTreeSkeleton() {
|
|
|
5574
5494
|
stopOpacity: 0
|
|
5575
5495
|
}
|
|
5576
5496
|
),
|
|
5577
|
-
/* @__PURE__ */ (0,
|
|
5497
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5578
5498
|
"stop",
|
|
5579
5499
|
{
|
|
5580
5500
|
offset: "50%",
|
|
@@ -5582,7 +5502,7 @@ function GenreTreeSkeleton() {
|
|
|
5582
5502
|
stopOpacity: 0.9
|
|
5583
5503
|
}
|
|
5584
5504
|
),
|
|
5585
|
-
/* @__PURE__ */ (0,
|
|
5505
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5586
5506
|
"stop",
|
|
5587
5507
|
{
|
|
5588
5508
|
offset: "100%",
|
|
@@ -5591,8 +5511,8 @@ function GenreTreeSkeleton() {
|
|
|
5591
5511
|
}
|
|
5592
5512
|
)
|
|
5593
5513
|
] }),
|
|
5594
|
-
/* @__PURE__ */ (0,
|
|
5595
|
-
ALL_LINKS.map((link, i) => /* @__PURE__ */ (0,
|
|
5514
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("mask", { id: maskId, children: [
|
|
5515
|
+
ALL_LINKS.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5596
5516
|
"path",
|
|
5597
5517
|
{
|
|
5598
5518
|
d: connectorPath(link.from, link.to),
|
|
@@ -5602,7 +5522,7 @@ function GenreTreeSkeleton() {
|
|
|
5602
5522
|
},
|
|
5603
5523
|
`link-mask-${i}`
|
|
5604
5524
|
)),
|
|
5605
|
-
ALL_CARDS.map(({ card }, i) => /* @__PURE__ */ (0,
|
|
5525
|
+
ALL_CARDS.map(({ card }, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5606
5526
|
"rect",
|
|
5607
5527
|
{
|
|
5608
5528
|
x: card.x,
|
|
@@ -5617,7 +5537,7 @@ function GenreTreeSkeleton() {
|
|
|
5617
5537
|
))
|
|
5618
5538
|
] })
|
|
5619
5539
|
] }),
|
|
5620
|
-
ALL_LINKS.map((link, i) => /* @__PURE__ */ (0,
|
|
5540
|
+
ALL_LINKS.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5621
5541
|
"path",
|
|
5622
5542
|
{
|
|
5623
5543
|
d: connectorPath(link.from, link.to),
|
|
@@ -5627,8 +5547,8 @@ function GenreTreeSkeleton() {
|
|
|
5627
5547
|
},
|
|
5628
5548
|
`link-${i}`
|
|
5629
5549
|
)),
|
|
5630
|
-
ALL_CARDS.map(({ card, rootAccent }, i) => /* @__PURE__ */ (0,
|
|
5631
|
-
/* @__PURE__ */ (0,
|
|
5550
|
+
ALL_CARDS.map(({ card, rootAccent }, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SkeletonCard, { card, rootAccent }, `card-${i}`)),
|
|
5551
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("g", { mask: `url(#${maskId})`, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5632
5552
|
"rect",
|
|
5633
5553
|
{
|
|
5634
5554
|
className: shimmerBandClass,
|
|
@@ -5647,7 +5567,7 @@ function GenreTreeSkeleton() {
|
|
|
5647
5567
|
|
|
5648
5568
|
// src/GenreTreeWheelSkeleton.tsx
|
|
5649
5569
|
var import_react16 = require("react");
|
|
5650
|
-
var
|
|
5570
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5651
5571
|
var SHAPE_COLOR = "#D4D4D8";
|
|
5652
5572
|
var SECTOR_FILL_OPACITY = 0.22;
|
|
5653
5573
|
var INNER_TINT_OPACITY = 0.55;
|
|
@@ -5792,8 +5712,8 @@ function GenreTreeWheelSkeleton() {
|
|
|
5792
5712
|
sharedStartTime ??= animation.startTime ?? document.timeline.currentTime;
|
|
5793
5713
|
animation.startTime = sharedStartTime;
|
|
5794
5714
|
}, []);
|
|
5795
|
-
return /* @__PURE__ */ (0,
|
|
5796
|
-
/* @__PURE__ */ (0,
|
|
5715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "gtv-wheel-skeleton", children: [
|
|
5716
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5797
5717
|
"div",
|
|
5798
5718
|
{
|
|
5799
5719
|
className: "gtv-wheel-skeleton-sector-layer",
|
|
@@ -5801,8 +5721,8 @@ function GenreTreeWheelSkeleton() {
|
|
|
5801
5721
|
"aria-hidden": "true"
|
|
5802
5722
|
}
|
|
5803
5723
|
),
|
|
5804
|
-
/* @__PURE__ */ (0,
|
|
5805
|
-
/* @__PURE__ */ (0,
|
|
5724
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "gtv-skeleton-sr-only", children: "Loading genre tree\u2026" }),
|
|
5725
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
5806
5726
|
"svg",
|
|
5807
5727
|
{
|
|
5808
5728
|
viewBox: `${CANVAS_ORIGIN} ${CANVAS_ORIGIN} ${CANVAS_SIZE} ${CANVAS_SIZE}`,
|
|
@@ -5810,14 +5730,14 @@ function GenreTreeWheelSkeleton() {
|
|
|
5810
5730
|
className: "gtv-wheel-skeleton-svg",
|
|
5811
5731
|
"aria-hidden": "true",
|
|
5812
5732
|
children: [
|
|
5813
|
-
/* @__PURE__ */ (0,
|
|
5814
|
-
/* @__PURE__ */ (0,
|
|
5815
|
-
/* @__PURE__ */ (0,
|
|
5816
|
-
/* @__PURE__ */ (0,
|
|
5817
|
-
/* @__PURE__ */ (0,
|
|
5733
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("defs", { children: [
|
|
5734
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("radialGradient", { id: mainstreamId, children: [
|
|
5735
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("stop", { offset: "0%", stopColor: "#FFFFFF", stopOpacity: 0.45 }),
|
|
5736
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("stop", { offset: "65%", stopColor: "#FFFFFF", stopOpacity: 0.15 }),
|
|
5737
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("stop", { offset: "100%", stopColor: "#FFFFFF", stopOpacity: 0 })
|
|
5818
5738
|
] }),
|
|
5819
|
-
/* @__PURE__ */ (0,
|
|
5820
|
-
LINKS.map((link, i) => /* @__PURE__ */ (0,
|
|
5739
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("g", { id: shapesId, children: [
|
|
5740
|
+
LINKS.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5821
5741
|
"path",
|
|
5822
5742
|
{
|
|
5823
5743
|
d: link.d,
|
|
@@ -5829,21 +5749,21 @@ function GenreTreeWheelSkeleton() {
|
|
|
5829
5749
|
},
|
|
5830
5750
|
`link-${i}`
|
|
5831
5751
|
)),
|
|
5832
|
-
DOTS.map((dot, i) => /* @__PURE__ */ (0,
|
|
5752
|
+
DOTS.map((dot, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: dot.point.x, cy: dot.point.y, r: dot.r, fill: "currentColor" }, `dot-${i}`))
|
|
5833
5753
|
] })
|
|
5834
5754
|
] }),
|
|
5835
|
-
/* @__PURE__ */ (0,
|
|
5836
|
-
/* @__PURE__ */ (0,
|
|
5837
|
-
/* @__PURE__ */ (0,
|
|
5755
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: 0, cy: 0, r: RING_RADIUS, fill: "#FFFFFF", fillOpacity: INNER_TINT_OPACITY }),
|
|
5756
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: 0, cy: 0, r: MAINSTREAM_RADIUS, fill: `url(#${mainstreamId})` }),
|
|
5757
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("use", { href: `#${shapesId}`, color: SHAPE_COLOR })
|
|
5838
5758
|
]
|
|
5839
5759
|
}
|
|
5840
5760
|
),
|
|
5841
|
-
/* @__PURE__ */ (0,
|
|
5761
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "gtv-wheel-skeleton-shimmer", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { ref: wedgeRef, className: "gtv-wheel-skeleton-shimmer-wedge" }) })
|
|
5842
5762
|
] });
|
|
5843
5763
|
}
|
|
5844
5764
|
|
|
5845
5765
|
// src/GenreTreeOutlineSkeleton.tsx
|
|
5846
|
-
var
|
|
5766
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5847
5767
|
var ROWS = [
|
|
5848
5768
|
{ depth: 0, width: 38 },
|
|
5849
5769
|
{ depth: 0, width: 26 },
|
|
@@ -5855,9 +5775,9 @@ var ROWS = [
|
|
|
5855
5775
|
{ depth: 0, width: 22 }
|
|
5856
5776
|
];
|
|
5857
5777
|
function GenreTreeOutlineSkeleton() {
|
|
5858
|
-
return /* @__PURE__ */ (0,
|
|
5859
|
-
/* @__PURE__ */ (0,
|
|
5860
|
-
ROWS.map((row, i) => /* @__PURE__ */ (0,
|
|
5778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "gtv-skeleton gtv-outline-skeleton", children: [
|
|
5779
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "gtv-skeleton-sr-only", children: "Loading genre tree\u2026" }),
|
|
5780
|
+
ROWS.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5861
5781
|
"div",
|
|
5862
5782
|
{
|
|
5863
5783
|
className: "gtv-outline-skeleton-row",
|
|
@@ -5870,13 +5790,13 @@ function GenreTreeOutlineSkeleton() {
|
|
|
5870
5790
|
}
|
|
5871
5791
|
|
|
5872
5792
|
// src/GenreTreeViewSkeleton.tsx
|
|
5873
|
-
var
|
|
5793
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5874
5794
|
function GenreTreeViewSkeleton({ viewMode }) {
|
|
5875
5795
|
if (viewMode === "wheel" || viewMode === "pop-core") {
|
|
5876
|
-
return /* @__PURE__ */ (0,
|
|
5796
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "gtv-view-skeleton-wheel-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GenreTreeWheelSkeleton, {}) });
|
|
5877
5797
|
}
|
|
5878
|
-
if (viewMode === "outline") return /* @__PURE__ */ (0,
|
|
5879
|
-
return /* @__PURE__ */ (0,
|
|
5798
|
+
if (viewMode === "outline") return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GenreTreeOutlineSkeleton, {});
|
|
5799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GenreTreeSkeleton, {});
|
|
5880
5800
|
}
|
|
5881
5801
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5882
5802
|
0 && (module.exports = {
|