@sebgroup/green-core 3.17.0 → 3.17.1

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.
@@ -240,7 +240,7 @@ const Users = {
240
240
  (row) => String(row.status) === "Active"
241
241
  ).length;
242
242
  const activeRate = Math.round(activeCount / rows.length * 100);
243
- const departments = new Set(rows.map((row) => row.department)).size;
243
+ const departments2 = new Set(rows.map((row) => row.department)).size;
244
244
  return html`
245
245
  <!-- tfoot: name row count -->
246
246
  <span slot="tfoot:name">${rows.length} Users</span>
@@ -256,7 +256,7 @@ const Users = {
256
256
 
257
257
  <!-- tfoot: department count -->
258
258
  <gds-badge slot="tfoot:department" variant="information" size="small">
259
- ${departments} depts
259
+ ${departments2} depts
260
260
  </gds-badge>
261
261
 
262
262
  <!-- tfoot: amount sum -->
@@ -1095,9 +1095,488 @@ const ExpandableFinance = {
1095
1095
  `;
1096
1096
  }
1097
1097
  };
1098
+ const departments = [
1099
+ "Engineering",
1100
+ "Finance",
1101
+ "Legal",
1102
+ "Marketing",
1103
+ "Operations",
1104
+ "HR",
1105
+ "Sales",
1106
+ "Support",
1107
+ "Design",
1108
+ "Product"
1109
+ ];
1110
+ const statuses = ["Active", "Inactive", "Pending", "Review", "Archived"];
1111
+ const currencies = ["SEK", "EUR", "USD", "NOK", "DKK"];
1112
+ const regions = [
1113
+ "Stockholm",
1114
+ "Gothenburg",
1115
+ "Malmo",
1116
+ "Oslo",
1117
+ "Copenhagen",
1118
+ "Helsinki",
1119
+ "London",
1120
+ "Berlin"
1121
+ ];
1122
+ const priorities = ["Critical", "High", "Medium", "Low"];
1123
+ const generatePerformanceRows = (count) => Array.from({ length: count }, (_, i) => {
1124
+ const id = i + 1;
1125
+ const dept = departments[i % departments.length];
1126
+ const statusVal = statuses[i % statuses.length];
1127
+ const currency = currencies[i % currencies.length];
1128
+ const region = regions[i % regions.length];
1129
+ const priority = priorities[i % priorities.length];
1130
+ const nameVal = `User ${id}`;
1131
+ const accountVal = `5001 ${String(10 + i % 90).padStart(2, "0")} ${String(
1132
+ 100 + i
1133
+ ).slice(-3)} ${String(10 + i % 90).padStart(2, "0")}`;
1134
+ const joinedVal = `2024-${String(i % 12 + 1).padStart(2, "0")}-${String(i % 28 + 1).padStart(2, "0")}`;
1135
+ const lastLoginVal = `2026-${String(i % 12 + 1).padStart(2, "0")}-${String(i % 28 + 1).padStart(2, "0")}`;
1136
+ const managerVal = `Manager ${i % 20 + 1}`;
1137
+ const teamVal = `Team ${String.fromCharCode(65 + i % 8)}`;
1138
+ const buildingVal = `Building ${i % 5 + 1}`;
1139
+ const projectVal = `Project ${String.fromCharCode(65 + i % 12)}-${Math.floor(i / 12) + 1}`;
1140
+ const isSubRowType = i % 5 === 0;
1141
+ const isFullContentType = i % 5 === 2;
1142
+ const baseRow = {
1143
+ id,
1144
+ name: Slot(nameVal, ["avatar", "value"]),
1145
+ email: Slot(`user${id}@example.com`, ["value", "copy-button"]),
1146
+ department: dept,
1147
+ status: Slot(statusVal, ["status"]),
1148
+ region,
1149
+ priority,
1150
+ currency,
1151
+ amount: Slot(Math.round(Math.random() * 5e5 + 1e3), [
1152
+ "amount",
1153
+ "currency"
1154
+ ]),
1155
+ balance: Math.round(Math.random() * 1e6),
1156
+ score: Math.round(Math.random() * 100),
1157
+ rating: (Math.random() * 5).toFixed(1),
1158
+ tasks: Math.floor(Math.random() * 50),
1159
+ completed: Math.floor(Math.random() * 40),
1160
+ account: accountVal,
1161
+ joined: joinedVal,
1162
+ lastLogin: lastLoginVal,
1163
+ manager: managerVal,
1164
+ team: teamVal,
1165
+ building: buildingVal,
1166
+ floor: i % 10 + 1,
1167
+ extension: 1e3 + i,
1168
+ costCenter: `CC-${String(100 + i % 50)}`,
1169
+ project: projectVal,
1170
+ hours: Math.round(Math.random() * 160 + 20),
1171
+ actions: Slot(void 0, ["main"])
1172
+ };
1173
+ if (isSubRowType) {
1174
+ return {
1175
+ ...baseRow,
1176
+ isExpandable: true,
1177
+ subRowCount: 2,
1178
+ subRows: async () => {
1179
+ return [
1180
+ {
1181
+ id: `${id}-r1`,
1182
+ name: `${nameVal} - Sub A`,
1183
+ email: `sub.a.${id}@example.com`,
1184
+ department: dept,
1185
+ status: statuses[(i + 1) % statuses.length],
1186
+ region,
1187
+ priority,
1188
+ currency,
1189
+ amount: id * 1234 % 1e5 + 500,
1190
+ balance: id * 5678 % 2e5,
1191
+ score: id * 91 % 100,
1192
+ rating: (id * 13 % 50 / 10).toFixed(1),
1193
+ tasks: id * 3 % 10,
1194
+ completed: id * 2 % 10,
1195
+ account: `${accountVal}-A`,
1196
+ joined: joinedVal,
1197
+ lastLogin: lastLoginVal,
1198
+ manager: managerVal,
1199
+ team: teamVal,
1200
+ building: buildingVal,
1201
+ floor: baseRow.floor,
1202
+ extension: baseRow.extension + 1,
1203
+ costCenter: baseRow.costCenter,
1204
+ project: `${projectVal}-A`,
1205
+ hours: id * 7 % 80 + 10,
1206
+ actions: Slot(void 0, ["main"])
1207
+ },
1208
+ {
1209
+ id: `${id}-r2`,
1210
+ name: `${nameVal} - Sub B`,
1211
+ email: `sub.b.${id}@example.com`,
1212
+ department: dept,
1213
+ status: statuses[(i + 2) % statuses.length],
1214
+ region,
1215
+ priority,
1216
+ currency,
1217
+ amount: id * 2345 % 1e5 + 500,
1218
+ balance: id * 6789 % 2e5,
1219
+ score: id * 47 % 100,
1220
+ rating: (id * 17 % 50 / 10).toFixed(1),
1221
+ tasks: id * 5 % 10,
1222
+ completed: id * 4 % 10,
1223
+ account: `${accountVal}-B`,
1224
+ joined: joinedVal,
1225
+ lastLogin: lastLoginVal,
1226
+ manager: managerVal,
1227
+ team: teamVal,
1228
+ building: buildingVal,
1229
+ floor: baseRow.floor,
1230
+ extension: baseRow.extension + 2,
1231
+ costCenter: baseRow.costCenter,
1232
+ project: `${projectVal}-B`,
1233
+ hours: id * 11 % 80 + 10,
1234
+ actions: Slot(void 0, ["main"])
1235
+ }
1236
+ ];
1237
+ }
1238
+ };
1239
+ }
1240
+ if (isFullContentType) {
1241
+ return {
1242
+ ...baseRow,
1243
+ isExpandable: true,
1244
+ subRowCount: 1,
1245
+ fullContent: async () => {
1246
+ return true;
1247
+ }
1248
+ };
1249
+ }
1250
+ return {
1251
+ ...baseRow,
1252
+ isExpandable: false
1253
+ };
1254
+ });
1255
+ const performanceCaches = {};
1256
+ const getPerformanceRows = (count) => {
1257
+ if (!performanceCaches[count])
1258
+ performanceCaches[count] = generatePerformanceRows(count);
1259
+ return performanceCaches[count];
1260
+ };
1261
+ const performanceDataProvider = (rowCount) => async (request) => {
1262
+ let data = getPerformanceRows(rowCount);
1263
+ if (request.searchQuery) {
1264
+ const q = request.searchQuery.toLowerCase();
1265
+ data = data.filter(
1266
+ (row) => Object.values(row).some((v) => v?.toString().toLowerCase().includes(q))
1267
+ );
1268
+ }
1269
+ if (request.sortColumn && data.length > 0) {
1270
+ const key = request.sortColumn;
1271
+ data = [...data].sort((a, b) => {
1272
+ const aVal = a[key]?.toString() ?? "";
1273
+ const bVal = b[key]?.toString() ?? "";
1274
+ return request.sortDirection === "asc" ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
1275
+ });
1276
+ }
1277
+ const start = (request.page - 1) * request.rows;
1278
+ return {
1279
+ rows: data.slice(start, start + request.rows),
1280
+ total: data.length
1281
+ };
1282
+ };
1283
+ const Performance = {
1284
+ Columns: [
1285
+ {
1286
+ key: "id",
1287
+ label: "ID",
1288
+ sortable: true,
1289
+ width: "6ch",
1290
+ sticky: "left"
1291
+ },
1292
+ {
1293
+ key: "name",
1294
+ label: "Name",
1295
+ sortable: true,
1296
+ width: "20ch",
1297
+ sticky: "left"
1298
+ },
1299
+ {
1300
+ key: "email",
1301
+ label: "Email",
1302
+ sortable: true,
1303
+ width: "24ch",
1304
+ justify: "space-between"
1305
+ },
1306
+ {
1307
+ key: "department",
1308
+ label: "Department",
1309
+ sortable: true
1310
+ },
1311
+ {
1312
+ key: "status",
1313
+ label: "Status",
1314
+ sortable: true
1315
+ },
1316
+ {
1317
+ key: "region",
1318
+ label: "Region",
1319
+ sortable: true
1320
+ },
1321
+ {
1322
+ key: "priority",
1323
+ label: "Priority",
1324
+ sortable: true
1325
+ },
1326
+ {
1327
+ key: "currency",
1328
+ label: "Currency",
1329
+ sortable: true,
1330
+ width: "10ch"
1331
+ },
1332
+ {
1333
+ key: "amount",
1334
+ label: "Amount",
1335
+ sortable: true,
1336
+ justify: "end"
1337
+ },
1338
+ {
1339
+ key: "balance",
1340
+ label: "Balance",
1341
+ sortable: true,
1342
+ justify: "end"
1343
+ },
1344
+ {
1345
+ key: "score",
1346
+ label: "Score",
1347
+ sortable: true,
1348
+ justify: "end",
1349
+ width: "8ch"
1350
+ },
1351
+ {
1352
+ key: "rating",
1353
+ label: "Rating",
1354
+ sortable: true,
1355
+ justify: "end",
1356
+ width: "8ch"
1357
+ },
1358
+ {
1359
+ key: "tasks",
1360
+ label: "Tasks",
1361
+ sortable: true,
1362
+ justify: "end",
1363
+ width: "8ch"
1364
+ },
1365
+ {
1366
+ key: "completed",
1367
+ label: "Completed",
1368
+ sortable: true,
1369
+ justify: "end",
1370
+ width: "10ch"
1371
+ },
1372
+ {
1373
+ key: "account",
1374
+ label: "Account",
1375
+ sortable: true,
1376
+ width: "20ch"
1377
+ },
1378
+ {
1379
+ key: "joined",
1380
+ label: "Joined",
1381
+ sortable: true
1382
+ },
1383
+ {
1384
+ key: "lastLogin",
1385
+ label: "Last Login",
1386
+ sortable: true
1387
+ },
1388
+ {
1389
+ key: "manager",
1390
+ label: "Manager",
1391
+ sortable: true
1392
+ },
1393
+ {
1394
+ key: "team",
1395
+ label: "Team",
1396
+ sortable: true,
1397
+ width: "10ch"
1398
+ },
1399
+ {
1400
+ key: "building",
1401
+ label: "Building",
1402
+ sortable: true,
1403
+ width: "12ch"
1404
+ },
1405
+ {
1406
+ key: "floor",
1407
+ label: "Floor",
1408
+ sortable: true,
1409
+ justify: "end",
1410
+ width: "8ch"
1411
+ },
1412
+ {
1413
+ key: "extension",
1414
+ label: "Ext.",
1415
+ sortable: true,
1416
+ justify: "end",
1417
+ width: "8ch"
1418
+ },
1419
+ {
1420
+ key: "costCenter",
1421
+ label: "Cost Center",
1422
+ sortable: true
1423
+ },
1424
+ {
1425
+ key: "project",
1426
+ label: "Project",
1427
+ sortable: true
1428
+ },
1429
+ {
1430
+ key: "hours",
1431
+ label: "Hours",
1432
+ sortable: false,
1433
+ justify: "end",
1434
+ sticky: "right"
1435
+ },
1436
+ {
1437
+ key: "actions",
1438
+ label: "Actions",
1439
+ justify: "end",
1440
+ sticky: "right",
1441
+ sortable: true
1442
+ }
1443
+ ],
1444
+ Data: performanceDataProvider,
1445
+ SlotContent: (rows) => html`
1446
+ ${rows.map(
1447
+ (row) => html`
1448
+ <gds-img
1449
+ src="https://api.dicebear.com/9.x/notionists/svg?seed=${row.id}"
1450
+ alt="${String(row.name)}"
1451
+ slot="name:${row.id}:avatar"
1452
+ width="xl"
1453
+ height="xl"
1454
+ ></gds-img>
1455
+
1456
+ <gds-button
1457
+ slot="email:${row.id}:copy-button"
1458
+ rank="tertiary"
1459
+ size="small"
1460
+ >
1461
+ <gds-icon-copy></gds-icon-copy>
1462
+ </gds-button>
1463
+
1464
+ <gds-badge
1465
+ slot="status:${row.id}:status"
1466
+ size="small"
1467
+ variant="${String(row.status) === "Active" ? "positive" : String(row.status) === "Inactive" ? "negative" : String(row.status) === "Pending" ? "warning" : "information"}"
1468
+ >
1469
+ ${String(row.status)}
1470
+ </gds-badge>
1471
+
1472
+ <gds-formatted-number
1473
+ slot="amount:${row.id}:amount"
1474
+ .value=${Number(row.amount)}
1475
+ ></gds-formatted-number>
1476
+ <gds-badge slot="amount:${row.id}:currency" size="small">
1477
+ ${String(row.currency)}
1478
+ </gds-badge>
1479
+
1480
+ <gds-context-menu slot="actions:${row.id}:main">
1481
+ <gds-button slot="trigger" rank="tertiary" size="small">
1482
+ <gds-icon-dot-grid-one-horizontal></gds-icon-dot-grid-one-horizontal>
1483
+ </gds-button>
1484
+ <gds-menu-item>View</gds-menu-item>
1485
+ <gds-menu-item>Edit</gds-menu-item>
1486
+ </gds-context-menu>
1487
+
1488
+ ${typeof row.fullContent === "function" ? row.id === 8 ? html`
1489
+ <gds-table
1490
+ plain
1491
+ slot="expand:${row.id}:full"
1492
+ .columns=${Users.Columns}
1493
+ .data=${Users.Data}
1494
+ @gds-table-data-loaded=${(e) => e.stopPropagation()}
1495
+ ></gds-table>
1496
+ ` : html`
1497
+ <gds-card
1498
+ slot="expand:${row.id}:full"
1499
+ variant="neutral-02-outlined"
1500
+ >
1501
+ <gds-flex flex-direction="column" gap="m" padding="m">
1502
+ <gds-flex
1503
+ justify-content="space-between"
1504
+ align-items="center"
1505
+ flex-wrap="wrap"
1506
+ gap="s"
1507
+ >
1508
+ <gds-flex flex-direction="column" gap="2xs">
1509
+ <gds-text font="heading-xs">
1510
+ ${String(row.name)} - Extended Details
1511
+ </gds-text>
1512
+ <gds-text font="detail-s-book">
1513
+ ${String(row.department)} · ${String(row.region)} ·
1514
+ ${String(row.priority)} priority
1515
+ </gds-text>
1516
+ </gds-flex>
1517
+ <gds-badge
1518
+ variant="${String(row.status) === "Active" ? "positive" : String(row.status) === "Inactive" ? "negative" : String(row.status) === "Pending" ? "warning" : "information"}"
1519
+ size="small"
1520
+ >
1521
+ ${String(row.status)}
1522
+ </gds-badge>
1523
+ </gds-flex>
1524
+
1525
+ <gds-grid columns="1; s{1}; m{2}; l{4}" gap="s">
1526
+ <gds-card variant="neutral-02-outlined" padding="s">
1527
+ <gds-flex flex-direction="column" gap="2xs">
1528
+ <gds-text font="detail-s-book">Manager</gds-text>
1529
+ <gds-text font="detail-s-bold">
1530
+ ${String(row.manager)}
1531
+ </gds-text>
1532
+ </gds-flex>
1533
+ </gds-card>
1534
+ <gds-card variant="neutral-02-outlined" padding="s">
1535
+ <gds-flex flex-direction="column" gap="2xs">
1536
+ <gds-text font="detail-s-book">Team</gds-text>
1537
+ <gds-text font="detail-s-bold">
1538
+ ${String(row.team)}
1539
+ </gds-text>
1540
+ </gds-flex>
1541
+ </gds-card>
1542
+ <gds-card variant="neutral-02-outlined" padding="s">
1543
+ <gds-flex flex-direction="column" gap="2xs">
1544
+ <gds-text font="detail-s-book">Cost Center</gds-text>
1545
+ <gds-text font="detail-s-bold">
1546
+ ${String(row.costCenter)}
1547
+ </gds-text>
1548
+ </gds-flex>
1549
+ </gds-card>
1550
+ <gds-card variant="neutral-02-outlined" padding="s">
1551
+ <gds-flex flex-direction="column" gap="2xs">
1552
+ <gds-text font="detail-s-book">Project</gds-text>
1553
+ <gds-text font="detail-s-bold">
1554
+ ${String(row.project)}
1555
+ </gds-text>
1556
+ </gds-flex>
1557
+ </gds-card>
1558
+ </gds-grid>
1559
+
1560
+ <gds-flex gap="s" flex-wrap="wrap">
1561
+ <gds-button size="small">View profile</gds-button>
1562
+ <gds-button rank="secondary" size="small"
1563
+ >Edit</gds-button
1564
+ >
1565
+ <gds-button rank="tertiary" size="small"
1566
+ >Export</gds-button
1567
+ >
1568
+ </gds-flex>
1569
+ </gds-flex>
1570
+ </gds-card>
1571
+ ` : null}
1572
+ `
1573
+ )}
1574
+ `
1575
+ };
1098
1576
  export {
1099
1577
  Actions,
1100
1578
  ExpandableFinance,
1101
1579
  Feedback,
1580
+ Performance,
1102
1581
  Users
1103
1582
  };
@@ -338,6 +338,7 @@ const TableStyles = css`
338
338
  position: sticky;
339
339
  left: 0;
340
340
  z-index: 4;
341
+ user-select: none;
341
342
  }
342
343
 
343
344
  .cell-center {
@@ -633,11 +634,6 @@ const TableStyles = css`
633
634
  display: flex;
634
635
  align-items: center;
635
636
  gap: 10px;
636
- transition: all 420ms;
637
-
638
- @starting-style {
639
- opacity: 0;
640
- }
641
637
  }
642
638
 
643
639
  /* Wrapping utilities */
@@ -1162,36 +1158,6 @@ const TableStyles = css`
1162
1158
  }
1163
1159
  }
1164
1160
 
1165
- /* Scrollbar */
1166
- .data {
1167
- --_scrollbar-color-thumb: var(--gds-sys-color-content-neutral-02);
1168
- --_scrollbar-color-track: var(--gds-sys-color-l3-neutral-02);
1169
- --_scrollbar-width: var(--gds-sys-space-2xs);
1170
- }
1171
-
1172
- @supports (scrollbar-width: auto) {
1173
- .data {
1174
- scrollbar-color: var(--_scrollbar-color-thumb) transparent;
1175
- scrollbar-width: var(--_scrollbar-width);
1176
- }
1177
- }
1178
-
1179
- @supports selector(::-webkit-scrollbar) {
1180
- .data::-webkit-scrollbar {
1181
- width: var(--_scrollbar-width);
1182
- height: var(--_scrollbar-width);
1183
- }
1184
-
1185
- .data::-webkit-scrollbar-track {
1186
- background: transparent;
1187
- }
1188
-
1189
- .data::-webkit-scrollbar-thumb {
1190
- background: var(--_scrollbar-color-thumb);
1191
- border-radius: var(--gds-sys-radius-max);
1192
- }
1193
- }
1194
-
1195
1161
  /* Reduced motion */
1196
1162
  @media (prefers-reduced-motion: reduce) {
1197
1163
  tbody tr,