@procaaso/alphinity-ui-components 1.0.10 → 1.0.11

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 CHANGED
@@ -1004,6 +1004,7 @@ function DeviceControlPanel({
1004
1004
  fontScale = 1,
1005
1005
  maxHeight,
1006
1006
  maxWidth,
1007
+ toastDuration = 3e3,
1007
1008
  onModeChange,
1008
1009
  onParameterChange,
1009
1010
  onStart,
@@ -1011,6 +1012,7 @@ function DeviceControlPanel({
1011
1012
  onCustomAction
1012
1013
  }) {
1013
1014
  const [localParameterValues, setLocalParameterValues] = (0, import_react5.useState)({});
1015
+ const [showToast, setShowToast] = (0, import_react5.useState)(true);
1014
1016
  (0, import_react5.useEffect)(() => {
1015
1017
  if (binding) {
1016
1018
  const currentParams2 = binding.parameters[binding.state.currentMode] || [];
@@ -1021,6 +1023,15 @@ function DeviceControlPanel({
1021
1023
  setLocalParameterValues(values);
1022
1024
  }
1023
1025
  }, [binding, binding?.state.currentMode]);
1026
+ (0, import_react5.useEffect)(() => {
1027
+ if (binding?.state.lastCommandResult) {
1028
+ setShowToast(true);
1029
+ const timer = setTimeout(() => {
1030
+ setShowToast(false);
1031
+ }, toastDuration);
1032
+ return () => clearTimeout(timer);
1033
+ }
1034
+ }, [binding?.state.lastCommandResult, toastDuration]);
1024
1035
  if (!binding) return null;
1025
1036
  const currentMode = binding.state.currentMode;
1026
1037
  const currentParams = binding.parameters[currentMode] || [];
@@ -1099,442 +1110,488 @@ function DeviceControlPanel({
1099
1110
  ...binding.display?.style
1100
1111
  };
1101
1112
  const titleText = binding.display?.title || binding.deviceName || binding.tag || binding.nodeId;
1102
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
1103
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1104
- "div",
1105
- {
1106
- style: {
1107
- display: "flex",
1108
- justifyContent: "space-between",
1109
- alignItems: "center",
1110
- marginBottom: "16px",
1111
- paddingBottom: "12px",
1112
- borderBottom: `2px solid ${borderColor}`
1113
- },
1114
- children: [
1115
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1116
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1117
- "h3",
1118
- {
1119
- style: {
1120
- margin: 0,
1121
- fontSize: `${fontSize.title}px`,
1122
- fontWeight: 600,
1123
- fontFamily: "Arial, sans-serif",
1124
- letterSpacing: "0.5px",
1125
- textTransform: "uppercase",
1126
- color: textColor
1127
- },
1128
- children: titleText
1129
- }
1130
- ),
1131
- binding.deviceType && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1132
- "div",
1133
- {
1134
- style: {
1135
- fontSize: "11px",
1136
- color: mutedTextColor,
1137
- marginTop: "4px",
1138
- fontFamily: "Arial, sans-serif"
1139
- },
1140
- children: binding.deviceType
1141
- }
1142
- )
1143
- ] }),
1144
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1145
- "button",
1146
- {
1147
- onClick: onClose,
1148
- style: {
1149
- width: touchSize * 0.7,
1150
- height: touchSize * 0.7,
1151
- backgroundColor: surfaceColor,
1152
- color: textColor,
1153
- border: `2px solid ${borderColor}`,
1154
- borderRadius: "2px",
1155
- fontSize: "18px",
1156
- cursor: "pointer",
1157
- fontWeight: "bold",
1158
- fontFamily: "Arial, sans-serif"
1159
- },
1160
- children: "\xD7"
1161
- }
1162
- )
1163
- ]
1164
- }
1165
- ),
1166
- binding.state.status && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1167
- "div",
1168
- {
1169
- style: {
1170
- display: "flex",
1171
- alignItems: "center",
1172
- gap: "12px",
1173
- padding: spacing.itemPadding,
1174
- backgroundColor: surfaceColor,
1175
- border: `1px solid ${borderColor}`,
1176
- borderRadius: "6px",
1177
- marginBottom: spacing.marginBottom
1178
- },
1179
- children: [
1180
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1181
- "div",
1182
- {
1183
- style: {
1184
- width: "10px",
1185
- height: "10px",
1186
- borderRadius: "50%",
1187
- backgroundColor: statusColor,
1188
- border: "1px solid #333"
1189
- }
1190
- }
1191
- ),
1192
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { flex: 1 }, children: [
1113
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1114
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: panelStyle, className: binding.display?.className, children: [
1115
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1116
+ "div",
1117
+ {
1118
+ style: {
1119
+ display: "flex",
1120
+ justifyContent: "space-between",
1121
+ alignItems: "center",
1122
+ marginBottom: "16px",
1123
+ paddingBottom: "12px",
1124
+ borderBottom: `2px solid ${borderColor}`
1125
+ },
1126
+ children: [
1127
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1128
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1129
+ "h3",
1130
+ {
1131
+ style: {
1132
+ margin: 0,
1133
+ fontSize: `${fontSize.title}px`,
1134
+ fontWeight: 600,
1135
+ fontFamily: "Arial, sans-serif",
1136
+ letterSpacing: "0.5px",
1137
+ textTransform: "uppercase",
1138
+ color: textColor
1139
+ },
1140
+ children: titleText
1141
+ }
1142
+ ),
1143
+ binding.deviceType && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1144
+ "div",
1145
+ {
1146
+ style: {
1147
+ fontSize: "11px",
1148
+ color: mutedTextColor,
1149
+ marginTop: "4px",
1150
+ fontFamily: "Arial, sans-serif"
1151
+ },
1152
+ children: binding.deviceType
1153
+ }
1154
+ )
1155
+ ] }),
1193
1156
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1194
- "div",
1195
- {
1196
- style: {
1197
- fontWeight: 600,
1198
- textTransform: "uppercase",
1199
- fontSize: `${fontSize.label}px`,
1200
- fontFamily: "Arial, sans-serif",
1201
- letterSpacing: "0.5px",
1202
- color: textColor
1203
- },
1204
- children: binding.state.status
1205
- }
1206
- ),
1207
- binding.state.statusMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1208
- "div",
1157
+ "button",
1209
1158
  {
1159
+ onClick: onClose,
1210
1160
  style: {
1211
- fontSize: "10px",
1212
- color: mutedTextColor,
1213
- marginTop: "2px",
1161
+ width: touchSize * 0.7,
1162
+ height: touchSize * 0.7,
1163
+ backgroundColor: surfaceColor,
1164
+ color: textColor,
1165
+ border: `2px solid ${borderColor}`,
1166
+ borderRadius: "2px",
1167
+ fontSize: "18px",
1168
+ cursor: "pointer",
1169
+ fontWeight: "bold",
1214
1170
  fontFamily: "Arial, sans-serif"
1215
1171
  },
1216
- children: binding.state.statusMessage
1172
+ children: "\xD7"
1217
1173
  }
1218
1174
  )
1219
- ] }),
1220
- binding.state.isRunning !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1221
- "div",
1222
- {
1223
- style: {
1224
- padding: "4px 10px",
1225
- backgroundColor: binding.state.isRunning ? selectedColor : surfaceColor,
1226
- border: `1px solid ${borderColor}`,
1227
- borderRadius: "2px",
1228
- fontSize: "10px",
1229
- fontWeight: 600,
1230
- fontFamily: "Arial, sans-serif",
1231
- letterSpacing: "0.5px",
1232
- color: textColor
1233
- },
1234
- children: binding.state.isRunning ? "RUNNING" : "STOPPED"
1235
- }
1236
- )
1237
- ]
1238
- }
1239
- ),
1240
- binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginBottom: "16px" }, children: [
1241
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1242
- "label",
1243
- {
1244
- style: {
1245
- display: "block",
1246
- marginBottom: "8px",
1247
- fontSize: "11px",
1248
- fontWeight: 600,
1249
- textTransform: "uppercase",
1250
- letterSpacing: "0.5px",
1251
- fontFamily: "Arial, sans-serif",
1252
- color: mutedTextColor
1253
- },
1254
- children: "Mode"
1255
- }
1256
- ),
1257
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", gap: spacing.gap, flexWrap: "wrap" }, children: binding.modes.map((mode) => {
1258
- const isSelected = mode.value === currentMode;
1259
- const isEnabled = mode.enabled !== false;
1260
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1261
- "button",
1262
- {
1263
- onClick: () => isEnabled && handleModeChange(mode.value),
1264
- disabled: !isEnabled,
1265
- style: {
1266
- flex: 1,
1267
- minWidth: "80px",
1268
- height: touchSize,
1269
- backgroundColor: isSelected ? selectedColor : surfaceColor,
1270
- color: isSelected ? "#000000" : textColor,
1271
- border: `1px solid ${isSelected ? "#b4d0fe" : borderColor}`,
1272
- borderRadius: "6px",
1273
- fontSize: `${fontSize.label}px`,
1274
- fontWeight: 600,
1275
- fontFamily: "Arial, sans-serif",
1276
- letterSpacing: "0.5px",
1277
- textTransform: "uppercase",
1278
- cursor: isEnabled ? "pointer" : "not-allowed",
1279
- opacity: isEnabled ? 1 : 0.4
1280
- },
1281
- children: mode.label
1282
- },
1283
- mode.value
1284
- );
1285
- }) })
1286
- ] }),
1287
- currentParams.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginBottom: spacing.marginBottom }, children: [
1288
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1289
- "label",
1290
- {
1291
- style: {
1292
- display: "block",
1293
- marginBottom: spacing.gap,
1294
- fontSize: `${fontSize.label}px`,
1295
- fontWeight: 600,
1296
- textTransform: "uppercase",
1297
- letterSpacing: "0.5px",
1298
- fontFamily: "Arial, sans-serif",
1299
- color: mutedTextColor
1300
- },
1301
- children: "Parameters"
1175
+ ]
1302
1176
  }
1303
1177
  ),
1304
- currentParams.map((param) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1178
+ binding.state.status && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1305
1179
  "div",
1306
1180
  {
1307
1181
  style: {
1308
- marginBottom: spacing.gap,
1182
+ display: "flex",
1183
+ alignItems: "center",
1184
+ gap: "12px",
1309
1185
  padding: spacing.itemPadding,
1310
1186
  backgroundColor: surfaceColor,
1311
1187
  border: `1px solid ${borderColor}`,
1312
- borderRadius: "6px"
1188
+ borderRadius: "6px",
1189
+ marginBottom: spacing.marginBottom
1313
1190
  },
1314
1191
  children: [
1315
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1192
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1316
1193
  "div",
1317
1194
  {
1318
1195
  style: {
1319
- display: "flex",
1320
- justifyContent: "space-between",
1321
- marginBottom: spacing.gap
1322
- },
1323
- children: [
1324
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1325
- "span",
1326
- {
1327
- style: {
1328
- fontSize: `${fontSize.label}px`,
1329
- fontWeight: 600,
1330
- textTransform: "uppercase",
1331
- letterSpacing: "0.5px",
1332
- fontFamily: "Arial, sans-serif",
1333
- color: mutedTextColor
1334
- },
1335
- children: param.label
1336
- }
1337
- ),
1338
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1339
- "span",
1340
- {
1341
- style: {
1342
- fontSize: `${fontSize.value}px`,
1343
- fontWeight: 700,
1344
- fontFamily: "Arial, sans-serif",
1345
- color: textColor
1346
- },
1347
- children: [
1348
- localParameterValues[param.id] ?? param.value,
1349
- " ",
1350
- param.unit && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: mutedTextColor, fontSize: "10px", fontWeight: 600 }, children: param.unit })
1351
- ]
1352
- }
1353
- )
1354
- ]
1196
+ width: "10px",
1197
+ height: "10px",
1198
+ borderRadius: "50%",
1199
+ backgroundColor: statusColor,
1200
+ border: "1px solid #333"
1201
+ }
1355
1202
  }
1356
1203
  ),
1357
- param.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1358
- "button",
1204
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { flex: 1 }, children: [
1205
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1206
+ "div",
1207
+ {
1208
+ style: {
1209
+ fontWeight: 600,
1210
+ textTransform: "uppercase",
1211
+ fontSize: `${fontSize.label}px`,
1212
+ fontFamily: "Arial, sans-serif",
1213
+ letterSpacing: "0.5px",
1214
+ color: textColor
1215
+ },
1216
+ children: binding.state.status
1217
+ }
1218
+ ),
1219
+ binding.state.statusMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1220
+ "div",
1221
+ {
1222
+ style: {
1223
+ fontSize: "10px",
1224
+ color: mutedTextColor,
1225
+ marginTop: "2px",
1226
+ fontFamily: "Arial, sans-serif"
1227
+ },
1228
+ children: binding.state.statusMessage
1229
+ }
1230
+ )
1231
+ ] }),
1232
+ binding.state.isRunning !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1233
+ "div",
1359
1234
  {
1360
- onClick: () => {
1361
- const newValue = !localParameterValues[param.id];
1362
- handleParameterInput(param.id, newValue);
1363
- handleParameterCommit(param.id, newValue);
1364
- },
1365
- disabled: param.readOnly,
1366
1235
  style: {
1367
- width: "100%",
1368
- height: touchSize,
1369
- backgroundColor: localParameterValues[param.id] ? "#3f3f46" : surfaceColor,
1370
- color: localParameterValues[param.id] ? textColor : mutedTextColor,
1371
- border: `1px solid ${localParameterValues[param.id] ? "#52525b" : borderColor}`,
1372
- borderRadius: "4px",
1373
- fontSize: "12px",
1236
+ padding: "4px 10px",
1237
+ backgroundColor: binding.state.isRunning ? selectedColor : surfaceColor,
1238
+ border: `1px solid ${borderColor}`,
1239
+ borderRadius: "2px",
1240
+ fontSize: "10px",
1374
1241
  fontWeight: 600,
1375
- fontFamily: "monospace",
1242
+ fontFamily: "Arial, sans-serif",
1376
1243
  letterSpacing: "0.5px",
1377
- cursor: param.readOnly ? "not-allowed" : "pointer",
1378
- transition: "all 0.15s"
1379
- },
1380
- children: localParameterValues[param.id] ? "ON" : "OFF"
1381
- }
1382
- ) : param.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1383
- "select",
1384
- {
1385
- value: localParameterValues[param.id] || param.value,
1386
- onChange: (e) => {
1387
- handleParameterInput(param.id, e.target.value);
1388
- handleParameterCommit(param.id, e.target.value);
1389
- },
1390
- disabled: param.readOnly,
1391
- style: {
1392
- width: "100%",
1393
- height: touchSize,
1394
- backgroundColor: surfaceColor,
1395
- color: textColor,
1396
- border: `1px solid ${borderColor}`,
1397
- borderRadius: "4px",
1398
- padding: "0 12px",
1399
- fontSize: "12px",
1400
- fontFamily: "monospace",
1401
- cursor: "pointer"
1244
+ color: textColor
1402
1245
  },
1403
- children: param.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1404
- }
1405
- ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1406
- "input",
1407
- {
1408
- type: param.type === "number" ? "number" : "text",
1409
- value: localParameterValues[param.id] ?? param.value,
1410
- onChange: (e) => handleParameterInput(
1411
- param.id,
1412
- param.type === "number" ? +e.target.value : e.target.value
1413
- ),
1414
- onBlur: () => handleParameterCommit(param.id, localParameterValues[param.id]),
1415
- disabled: param.readOnly,
1416
- min: param.min,
1417
- max: param.max,
1418
- step: param.step,
1419
- style: {
1420
- width: "100%",
1421
- height: touchSize,
1422
- backgroundColor: "#ffffff",
1423
- color: textColor,
1424
- border: `1px solid ${borderColor}`,
1425
- borderRadius: "6px",
1426
- padding: "0 12px",
1427
- fontSize: `${fontSize.input}px`,
1428
- fontFamily: "Arial, sans-serif",
1429
- fontWeight: 600
1430
- }
1246
+ children: binding.state.isRunning ? "RUNNING" : "STOPPED"
1431
1247
  }
1432
1248
  )
1433
1249
  ]
1434
- },
1435
- param.id
1436
- ))
1437
- ] }),
1438
- binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", gap: spacing.gap, marginBottom: spacing.marginBottom }, children: [
1439
- activeCapabilities?.canStart && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1440
- "button",
1441
- {
1442
- onClick: onStart,
1443
- disabled: binding.state.isRunning,
1444
- style: {
1445
- flex: 1,
1446
- height: touchSize,
1447
- backgroundColor: binding.state.isRunning ? "#a3a3a3" : "#10b981",
1448
- color: "#ffffff",
1449
- border: "none",
1450
- borderRadius: "6px",
1451
- fontSize: "12px",
1452
- fontWeight: 700,
1453
- fontFamily: "Arial, sans-serif",
1454
- letterSpacing: "0.5px",
1455
- cursor: binding.state.isRunning ? "not-allowed" : "pointer",
1456
- opacity: binding.state.isRunning ? 0.5 : 1
1457
- },
1458
- children: "START"
1459
1250
  }
1460
1251
  ),
1461
- activeCapabilities?.canStop && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1252
+ binding.display?.showModeSelector !== false && binding.modes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginBottom: "16px" }, children: [
1253
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1254
+ "label",
1255
+ {
1256
+ style: {
1257
+ display: "block",
1258
+ marginBottom: "8px",
1259
+ fontSize: "11px",
1260
+ fontWeight: 600,
1261
+ textTransform: "uppercase",
1262
+ letterSpacing: "0.5px",
1263
+ fontFamily: "Arial, sans-serif",
1264
+ color: mutedTextColor
1265
+ },
1266
+ children: "Mode"
1267
+ }
1268
+ ),
1269
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1270
+ "div",
1271
+ {
1272
+ style: {
1273
+ display: "flex",
1274
+ gap: spacing.gap,
1275
+ overflowX: "auto",
1276
+ overflowY: "hidden",
1277
+ scrollbarWidth: "thin",
1278
+ scrollbarColor: `${borderColor} transparent`,
1279
+ paddingBottom: "4px",
1280
+ marginBottom: "-4px"
1281
+ },
1282
+ children: binding.modes.map((mode) => {
1283
+ const isSelected = mode.value === currentMode;
1284
+ const isEnabled = mode.enabled !== false;
1285
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1286
+ "button",
1287
+ {
1288
+ onClick: () => isEnabled && handleModeChange(mode.value),
1289
+ disabled: !isEnabled,
1290
+ style: {
1291
+ flex: "0 0 auto",
1292
+ minWidth: "90px",
1293
+ height: touchSize,
1294
+ backgroundColor: isSelected ? selectedColor : surfaceColor,
1295
+ color: isSelected ? "#000000" : textColor,
1296
+ border: `1px solid ${isSelected ? "#b4d0fe" : borderColor}`,
1297
+ borderRadius: "6px",
1298
+ fontSize: `${fontSize.label}px`,
1299
+ fontWeight: 600,
1300
+ fontFamily: "Arial, sans-serif",
1301
+ letterSpacing: "0.5px",
1302
+ textTransform: "uppercase",
1303
+ cursor: isEnabled ? "pointer" : "not-allowed",
1304
+ opacity: isEnabled ? 1 : 0.4,
1305
+ whiteSpace: "nowrap"
1306
+ },
1307
+ children: mode.label
1308
+ },
1309
+ mode.value
1310
+ );
1311
+ })
1312
+ }
1313
+ )
1314
+ ] }),
1315
+ currentParams.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { marginBottom: spacing.marginBottom }, children: [
1316
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1317
+ "label",
1318
+ {
1319
+ style: {
1320
+ display: "block",
1321
+ marginBottom: spacing.gap,
1322
+ fontSize: `${fontSize.label}px`,
1323
+ fontWeight: 600,
1324
+ textTransform: "uppercase",
1325
+ letterSpacing: "0.5px",
1326
+ fontFamily: "Arial, sans-serif",
1327
+ color: mutedTextColor
1328
+ },
1329
+ children: "Parameters"
1330
+ }
1331
+ ),
1332
+ currentParams.map((param) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1333
+ "div",
1334
+ {
1335
+ style: {
1336
+ marginBottom: spacing.gap,
1337
+ padding: spacing.itemPadding,
1338
+ backgroundColor: surfaceColor,
1339
+ border: `1px solid ${borderColor}`,
1340
+ borderRadius: "6px"
1341
+ },
1342
+ children: [
1343
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1344
+ "div",
1345
+ {
1346
+ style: {
1347
+ display: "flex",
1348
+ justifyContent: "space-between",
1349
+ marginBottom: spacing.gap
1350
+ },
1351
+ children: [
1352
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1353
+ "span",
1354
+ {
1355
+ style: {
1356
+ fontSize: `${fontSize.label}px`,
1357
+ fontWeight: 600,
1358
+ textTransform: "uppercase",
1359
+ letterSpacing: "0.5px",
1360
+ fontFamily: "Arial, sans-serif",
1361
+ color: mutedTextColor
1362
+ },
1363
+ children: param.label
1364
+ }
1365
+ ),
1366
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1367
+ "span",
1368
+ {
1369
+ style: {
1370
+ fontSize: `${fontSize.value}px`,
1371
+ fontWeight: 700,
1372
+ fontFamily: "Arial, sans-serif",
1373
+ color: textColor
1374
+ },
1375
+ children: [
1376
+ localParameterValues[param.id] ?? param.value,
1377
+ " ",
1378
+ param.unit && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { color: mutedTextColor, fontSize: "10px", fontWeight: 600 }, children: param.unit })
1379
+ ]
1380
+ }
1381
+ )
1382
+ ]
1383
+ }
1384
+ ),
1385
+ param.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1386
+ "button",
1387
+ {
1388
+ onClick: () => {
1389
+ const newValue = !localParameterValues[param.id];
1390
+ handleParameterInput(param.id, newValue);
1391
+ handleParameterCommit(param.id, newValue);
1392
+ },
1393
+ disabled: param.readOnly,
1394
+ style: {
1395
+ width: "100%",
1396
+ height: touchSize,
1397
+ backgroundColor: localParameterValues[param.id] ? "#3f3f46" : surfaceColor,
1398
+ color: localParameterValues[param.id] ? textColor : mutedTextColor,
1399
+ border: `1px solid ${localParameterValues[param.id] ? "#52525b" : borderColor}`,
1400
+ borderRadius: "4px",
1401
+ fontSize: "12px",
1402
+ fontWeight: 600,
1403
+ fontFamily: "monospace",
1404
+ letterSpacing: "0.5px",
1405
+ cursor: param.readOnly ? "not-allowed" : "pointer",
1406
+ transition: "all 0.15s"
1407
+ },
1408
+ children: localParameterValues[param.id] ? "ON" : "OFF"
1409
+ }
1410
+ ) : param.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1411
+ "select",
1412
+ {
1413
+ value: localParameterValues[param.id] || param.value,
1414
+ onChange: (e) => {
1415
+ handleParameterInput(param.id, e.target.value);
1416
+ handleParameterCommit(param.id, e.target.value);
1417
+ },
1418
+ disabled: param.readOnly,
1419
+ style: {
1420
+ width: "100%",
1421
+ height: touchSize,
1422
+ backgroundColor: surfaceColor,
1423
+ color: textColor,
1424
+ border: `1px solid ${borderColor}`,
1425
+ borderRadius: "4px",
1426
+ padding: "0 12px",
1427
+ fontSize: "12px",
1428
+ fontFamily: "monospace",
1429
+ cursor: "pointer"
1430
+ },
1431
+ children: param.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: opt.value, children: opt.label }, opt.value))
1432
+ }
1433
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1434
+ "input",
1435
+ {
1436
+ type: param.type === "number" ? "number" : "text",
1437
+ value: localParameterValues[param.id] ?? param.value,
1438
+ onChange: (e) => handleParameterInput(
1439
+ param.id,
1440
+ param.type === "number" ? +e.target.value : e.target.value
1441
+ ),
1442
+ onBlur: () => handleParameterCommit(param.id, localParameterValues[param.id]),
1443
+ disabled: param.readOnly,
1444
+ min: param.min,
1445
+ max: param.max,
1446
+ step: param.step,
1447
+ style: {
1448
+ width: "100%",
1449
+ height: touchSize,
1450
+ backgroundColor: "#ffffff",
1451
+ color: textColor,
1452
+ border: `1px solid ${borderColor}`,
1453
+ borderRadius: "6px",
1454
+ padding: "0 12px",
1455
+ fontSize: `${fontSize.input}px`,
1456
+ fontFamily: "Arial, sans-serif",
1457
+ fontWeight: 600
1458
+ }
1459
+ }
1460
+ )
1461
+ ]
1462
+ },
1463
+ param.id
1464
+ ))
1465
+ ] }),
1466
+ binding.display?.showStartStop !== false && (activeCapabilities?.canStart || activeCapabilities?.canStop) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { display: "flex", gap: spacing.gap, marginBottom: spacing.marginBottom }, children: [
1467
+ activeCapabilities?.canStart && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1468
+ "button",
1469
+ {
1470
+ onClick: onStart,
1471
+ disabled: binding.state.isRunning,
1472
+ style: {
1473
+ flex: 1,
1474
+ height: touchSize,
1475
+ backgroundColor: binding.state.isRunning ? "#a3a3a3" : "#10b981",
1476
+ color: "#ffffff",
1477
+ border: "none",
1478
+ borderRadius: "6px",
1479
+ fontSize: "12px",
1480
+ fontWeight: 700,
1481
+ fontFamily: "Arial, sans-serif",
1482
+ letterSpacing: "0.5px",
1483
+ cursor: binding.state.isRunning ? "not-allowed" : "pointer",
1484
+ opacity: binding.state.isRunning ? 0.5 : 1
1485
+ },
1486
+ children: "START"
1487
+ }
1488
+ ),
1489
+ activeCapabilities?.canStop && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1490
+ "button",
1491
+ {
1492
+ onClick: onStop,
1493
+ disabled: !binding.state.isRunning,
1494
+ style: {
1495
+ flex: 1,
1496
+ height: touchSize,
1497
+ backgroundColor: !binding.state.isRunning ? "#a3a3a3" : "#ef4444",
1498
+ color: "#ffffff",
1499
+ border: "none",
1500
+ borderRadius: "6px",
1501
+ fontSize: "12px",
1502
+ fontWeight: 700,
1503
+ fontFamily: "Arial, sans-serif",
1504
+ letterSpacing: "0.5px",
1505
+ cursor: !binding.state.isRunning ? "not-allowed" : "pointer",
1506
+ opacity: !binding.state.isRunning ? 0.5 : 1
1507
+ },
1508
+ children: "STOP"
1509
+ }
1510
+ )
1511
+ ] }),
1512
+ activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: activeCapabilities.customActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1462
1513
  "button",
1463
1514
  {
1464
- onClick: onStop,
1465
- disabled: !binding.state.isRunning,
1515
+ onClick: () => onCustomAction?.(action.id),
1466
1516
  style: {
1467
1517
  flex: 1,
1518
+ minWidth: "120px",
1468
1519
  height: touchSize,
1469
- backgroundColor: !binding.state.isRunning ? "#a3a3a3" : "#ef4444",
1470
- color: "#ffffff",
1471
- border: "none",
1520
+ backgroundColor: surfaceColor,
1521
+ color: textColor,
1522
+ border: `1px solid ${borderColor}`,
1472
1523
  borderRadius: "6px",
1473
- fontSize: "12px",
1474
- fontWeight: 700,
1475
- fontFamily: "Arial, sans-serif",
1524
+ fontSize: "11px",
1525
+ fontWeight: 600,
1526
+ fontFamily: "monospace",
1476
1527
  letterSpacing: "0.5px",
1477
- cursor: !binding.state.isRunning ? "not-allowed" : "pointer",
1478
- opacity: !binding.state.isRunning ? 0.5 : 1
1528
+ textTransform: "uppercase",
1529
+ cursor: "pointer",
1530
+ transition: "all 0.15s"
1479
1531
  },
1480
- children: "STOP"
1481
- }
1482
- )
1483
- ] }),
1484
- activeCapabilities?.customActions && activeCapabilities.customActions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "8px" }, children: activeCapabilities.customActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1485
- "button",
1486
- {
1487
- onClick: () => onCustomAction?.(action.id),
1488
- style: {
1489
- flex: 1,
1490
- minWidth: "120px",
1491
- height: touchSize,
1492
- backgroundColor: surfaceColor,
1493
- color: textColor,
1494
- border: `1px solid ${borderColor}`,
1495
- borderRadius: "6px",
1496
- fontSize: "11px",
1497
- fontWeight: 600,
1498
- fontFamily: "monospace",
1499
- letterSpacing: "0.5px",
1500
- textTransform: "uppercase",
1501
- cursor: "pointer",
1502
- transition: "all 0.15s"
1532
+ children: [
1533
+ action.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { marginRight: "6px" }, children: action.icon }),
1534
+ action.label
1535
+ ]
1503
1536
  },
1504
- children: [
1505
- action.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: { marginRight: "6px" }, children: action.icon }),
1506
- action.label
1507
- ]
1508
- },
1509
- action.id
1510
- )) }),
1511
- binding.state.lastCommandResult && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1537
+ action.id
1538
+ )) })
1539
+ ] }),
1540
+ binding.state.lastCommandResult && showToast && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1512
1541
  "div",
1513
1542
  {
1514
1543
  style: {
1515
- marginTop: "16px",
1516
- padding: "10px 12px",
1517
- backgroundColor: surfaceColor,
1518
- border: `1px solid ${binding.state.lastCommandResult.success ? "#52525b" : borderColor}`,
1519
- borderRadius: "4px",
1520
- fontSize: "11px",
1521
- fontFamily: "monospace",
1522
- color: binding.state.lastCommandResult.success ? textColor : mutedTextColor
1544
+ position: "fixed",
1545
+ bottom: "20px",
1546
+ ...position === "bottom" && align === "right" ? { left: "20px", right: "auto" } : { right: "20px", left: "auto" },
1547
+ // Default to right
1548
+ maxWidth: "400px",
1549
+ padding: "12px 16px",
1550
+ backgroundColor: binding.state.lastCommandResult.success ? "#10b981" : "#ef4444",
1551
+ color: "#ffffff",
1552
+ border: "none",
1553
+ borderRadius: "8px",
1554
+ fontSize: `${fontSize.label}px`,
1555
+ fontFamily: "Arial, sans-serif",
1556
+ fontWeight: 600,
1557
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
1558
+ zIndex: 1e4,
1559
+ animation: position === "bottom" && align === "right" ? "slideInToastLeft 0.3s ease-out" : "slideInToast 0.3s ease-out"
1523
1560
  },
1524
1561
  children: binding.state.lastCommandResult.message
1525
1562
  }
1526
1563
  ),
1527
1564
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `
1528
- @keyframes slideUp {
1529
- from { transform: translateY(100%); }
1530
- to { transform: translateY(0); }
1565
+ @keyframes slideInToast {
1566
+ from {
1567
+ opacity: 0;
1568
+ transform: translateX(20px);
1569
+ }
1570
+ to {
1571
+ opacity: 1;
1572
+ transform: translateX(0);
1573
+ }
1574
+ }
1575
+ @keyframes slideInToastLeft {
1576
+ from {
1577
+ opacity: 0;
1578
+ transform: translateX(-20px);
1531
1579
  }
1532
- @keyframes slideIn {
1533
- from { transform: translateX(100%); }
1534
- to { transform: translateX(0); }
1580
+ to {
1581
+ opacity: 1;
1582
+ transform: translateX(0);
1535
1583
  }
1536
- ` })
1537
- ] }) });
1584
+ }
1585
+ @keyframes slideUp {
1586
+ from { transform: translateY(100%); }
1587
+ to { transform: translateY(0); }
1588
+ }
1589
+ @keyframes slideIn {
1590
+ from { transform: translateX(100%); }
1591
+ to { transform: translateX(0); }
1592
+ }
1593
+ ` })
1594
+ ] });
1538
1595
  }
1539
1596
 
1540
1597
  // src/components/layout/FullscreenWorkspace/FullscreenWorkspace.tsx