@frontmcp/ui 0.8.1 → 0.10.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.
@@ -652,6 +652,7 @@ function registerFmcpButton() {
652
652
  }
653
653
 
654
654
  // libs/ui/src/components/card.ts
655
+ var import_runtime = require("@frontmcp/uipack/runtime");
655
656
  function getVariantClasses2(variant) {
656
657
  const variants = {
657
658
  default: "bg-white border border-border rounded-xl shadow-sm",
@@ -686,33 +687,38 @@ function card(content, options = {}) {
686
687
  id,
687
688
  data,
688
689
  clickable = false,
689
- href
690
+ href,
691
+ sanitize = false
690
692
  } = options;
693
+ const safeContent = sanitize ? (0, import_runtime.sanitizeHtmlContent)(content) : content;
694
+ const safeHeaderActions = sanitize && headerActions ? (0, import_runtime.sanitizeHtmlContent)(headerActions) : headerActions;
695
+ const safeFooter = sanitize && footer ? (0, import_runtime.sanitizeHtmlContent)(footer) : footer;
691
696
  const variantClasses = getVariantClasses2(variant);
692
697
  const sizeClasses = getSizeClasses2(size);
693
698
  const clickableClasses = clickable ? "cursor-pointer hover:shadow-md transition-shadow" : "";
694
- const allClasses = [variantClasses, sizeClasses, clickableClasses, className].filter(Boolean).join(" ");
699
+ const safeClassName = className ? (0, import_utils2.escapeHtml)(className) : "";
700
+ const allClasses = [variantClasses, sizeClasses, clickableClasses, safeClassName].filter(Boolean).join(" ");
695
701
  const dataAttrs = buildDataAttrs(data);
696
702
  const idAttr = id ? `id="${(0, import_utils2.escapeHtml)(id)}"` : "";
697
- const hasHeader = title || subtitle || headerActions;
703
+ const hasHeader = title || subtitle || safeHeaderActions;
698
704
  const headerHtml = hasHeader ? `<div class="flex items-start justify-between mb-4">
699
705
  <div>
700
706
  ${title ? `<h3 class="text-lg font-semibold text-text-primary">${(0, import_utils2.escapeHtml)(title)}</h3>` : ""}
701
707
  ${subtitle ? `<p class="text-sm text-text-secondary mt-1">${(0, import_utils2.escapeHtml)(subtitle)}</p>` : ""}
702
708
  </div>
703
- ${headerActions ? `<div class="flex items-center gap-2">${headerActions}</div>` : ""}
709
+ ${safeHeaderActions ? `<div class="flex items-center gap-2">${safeHeaderActions}</div>` : ""}
704
710
  </div>` : "";
705
- const footerHtml = footer ? `<div class="mt-4 pt-4 border-t border-divider">${footer}</div>` : "";
711
+ const footerHtml = safeFooter ? `<div class="mt-4 pt-4 border-t border-divider">${safeFooter}</div>` : "";
706
712
  if (href) {
707
713
  return `<a href="${(0, import_utils2.escapeHtml)(href)}" class="${allClasses}" ${idAttr} ${dataAttrs}>
708
714
  ${headerHtml}
709
- ${content}
715
+ ${safeContent}
710
716
  ${footerHtml}
711
717
  </a>`;
712
718
  }
713
719
  return `<div class="${allClasses}" ${idAttr} ${dataAttrs}>
714
720
  ${headerHtml}
715
- ${content}
721
+ ${safeContent}
716
722
  ${footerHtml}
717
723
  </div>`;
718
724
  }
@@ -835,6 +841,7 @@ function registerFmcpCard() {
835
841
  }
836
842
 
837
843
  // libs/ui/src/components/alert.ts
844
+ var import_runtime2 = require("@frontmcp/uipack/runtime");
838
845
  var alertIcons = {
839
846
  info: `<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
840
847
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
@@ -878,11 +885,24 @@ function getVariantClasses3(variant) {
878
885
  return variants[variant];
879
886
  }
880
887
  function alert(message, options = {}) {
881
- const { variant = "info", title, showIcon = true, icon, dismissible = false, className = "", id, actions } = options;
888
+ const {
889
+ variant = "info",
890
+ title,
891
+ showIcon = true,
892
+ icon,
893
+ dismissible = false,
894
+ className = "",
895
+ id,
896
+ actions,
897
+ sanitize = false
898
+ } = options;
899
+ const safeIcon = sanitize && icon ? (0, import_runtime2.sanitizeHtmlContent)(icon) : icon;
900
+ const safeActions = sanitize && actions ? (0, import_runtime2.sanitizeHtmlContent)(actions) : actions;
882
901
  const variantClasses = getVariantClasses3(variant);
883
- const baseClasses = ["rounded-lg border p-4", variantClasses.container, className].filter(Boolean).join(" ");
902
+ const safeClassName = className ? (0, import_utils2.escapeHtml)(className) : "";
903
+ const baseClasses = ["rounded-lg border p-4", variantClasses.container, safeClassName].filter(Boolean).join(" ");
884
904
  const iconHtml = showIcon ? `<div class="flex-shrink-0 ${variantClasses.icon}">
885
- ${icon || alertIcons[variant]}
905
+ ${safeIcon || alertIcons[variant]}
886
906
  </div>` : "";
887
907
  const titleHtml = title ? `<h3 class="font-semibold">${(0, import_utils2.escapeHtml)(title)}</h3>` : "";
888
908
  const dismissHtml = dismissible ? `<button
@@ -895,7 +915,7 @@ function alert(message, options = {}) {
895
915
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
896
916
  </svg>
897
917
  </button>` : "";
898
- const actionsHtml = actions ? `<div class="mt-3">${actions}</div>` : "";
918
+ const actionsHtml = safeActions ? `<div class="mt-3">${safeActions}</div>` : "";
899
919
  const idAttr = id ? `id="${(0, import_utils2.escapeHtml)(id)}"` : "";
900
920
  return `<div class="alert ${baseClasses}" role="alert" ${idAttr}>
901
921
  <div class="flex gap-3">
@@ -1012,6 +1032,7 @@ function registerFmcpAlert() {
1012
1032
  }
1013
1033
 
1014
1034
  // libs/ui/src/components/badge.ts
1035
+ var import_runtime3 = require("@frontmcp/uipack/runtime");
1015
1036
  function getVariantClasses4(variant) {
1016
1037
  const variants = {
1017
1038
  default: "bg-gray-100 text-gray-800",
@@ -1049,8 +1070,11 @@ function badge(text, options = {}) {
1049
1070
  icon,
1050
1071
  dot = false,
1051
1072
  className = "",
1052
- removable = false
1073
+ removable = false,
1074
+ sanitize = false
1053
1075
  } = options;
1076
+ const safeIcon = sanitize && icon ? (0, import_runtime3.sanitizeHtmlContent)(icon) : icon;
1077
+ const safeClassName = className ? (0, import_utils2.escapeHtml)(className) : "";
1054
1078
  if (dot) {
1055
1079
  const dotVariants = {
1056
1080
  default: "bg-gray-400",
@@ -1062,7 +1086,7 @@ function badge(text, options = {}) {
1062
1086
  info: "bg-blue-500",
1063
1087
  outline: "border border-current"
1064
1088
  };
1065
- const dotClasses = ["inline-block rounded-full", getSizeClasses3(size, true), dotVariants[variant], className].filter(Boolean).join(" ");
1089
+ const dotClasses = ["inline-block rounded-full", getSizeClasses3(size, true), dotVariants[variant], safeClassName].filter(Boolean).join(" ");
1066
1090
  return `<span class="${dotClasses}" aria-label="${(0, import_utils2.escapeHtml)(text)}" title="${(0, import_utils2.escapeHtml)(text)}"></span>`;
1067
1091
  }
1068
1092
  const variantClasses = getVariantClasses4(variant);
@@ -1072,9 +1096,9 @@ function badge(text, options = {}) {
1072
1096
  pill ? "rounded-full" : "rounded-md",
1073
1097
  variantClasses,
1074
1098
  sizeClasses,
1075
- className
1099
+ safeClassName
1076
1100
  ].filter(Boolean).join(" ");
1077
- const iconHtml = icon ? `<span class="mr-1">${icon}</span>` : "";
1101
+ const iconHtml = safeIcon ? `<span class="mr-1">${safeIcon}</span>` : "";
1078
1102
  const removeHtml = removable ? `<button
1079
1103
  type="button"
1080
1104
  class="ml-1.5 -mr-1 hover:opacity-70 transition-opacity"
@@ -1193,6 +1217,7 @@ function registerFmcpBadge() {
1193
1217
  }
1194
1218
 
1195
1219
  // libs/ui/src/components/form.ts
1220
+ var import_runtime4 = require("@frontmcp/uipack/runtime");
1196
1221
  function getInputSizeClasses(size) {
1197
1222
  const sizes = {
1198
1223
  sm: "px-3 py-1.5 text-sm",
@@ -1237,11 +1262,15 @@ function input(options) {
1237
1262
  className = "",
1238
1263
  data,
1239
1264
  iconBefore,
1240
- iconAfter
1265
+ iconAfter,
1266
+ sanitize = false
1241
1267
  } = options;
1268
+ const safeIconBefore = sanitize && iconBefore ? (0, import_runtime4.sanitizeHtmlContent)(iconBefore) : iconBefore;
1269
+ const safeIconAfter = sanitize && iconAfter ? (0, import_runtime4.sanitizeHtmlContent)(iconAfter) : iconAfter;
1242
1270
  const sizeClasses = getInputSizeClasses(size);
1243
1271
  const stateClasses = getInputStateClasses(state);
1244
- const hasIcon = iconBefore || iconAfter;
1272
+ const hasIcon = safeIconBefore || safeIconAfter;
1273
+ const safeClassName = className ? (0, import_utils2.escapeHtml)(className) : "";
1245
1274
  const baseClasses = [
1246
1275
  "w-full rounded-lg border bg-white",
1247
1276
  "transition-colors duration-200",
@@ -1249,8 +1278,8 @@ function input(options) {
1249
1278
  disabled ? "opacity-50 cursor-not-allowed bg-gray-50" : "",
1250
1279
  sizeClasses,
1251
1280
  stateClasses,
1252
- hasIcon ? (iconBefore ? "pl-10" : "") + (iconAfter ? " pr-10" : "") : "",
1253
- className
1281
+ hasIcon ? (safeIconBefore ? "pl-10" : "") + (safeIconAfter ? " pr-10" : "") : "",
1282
+ safeClassName
1254
1283
  ].filter(Boolean).join(" ");
1255
1284
  const dataAttrs = buildDataAttrs2(data);
1256
1285
  const inputAttrs = [
@@ -1275,8 +1304,8 @@ function input(options) {
1275
1304
  </label>` : "";
1276
1305
  const helperHtml = helper && !error ? `<p class="mt-1.5 text-sm text-text-secondary">${(0, import_utils2.escapeHtml)(helper)}</p>` : "";
1277
1306
  const errorHtml = error ? `<p class="mt-1.5 text-sm text-danger">${(0, import_utils2.escapeHtml)(error)}</p>` : "";
1278
- const iconBeforeHtml = iconBefore ? `<span class="absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary">${iconBefore}</span>` : "";
1279
- const iconAfterHtml = iconAfter ? `<span class="absolute right-3 top-1/2 -translate-y-1/2 text-text-secondary">${iconAfter}</span>` : "";
1307
+ const iconBeforeHtml = safeIconBefore ? `<span class="absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary">${safeIconBefore}</span>` : "";
1308
+ const iconAfterHtml = safeIconAfter ? `<span class="absolute right-3 top-1/2 -translate-y-1/2 text-text-secondary">${safeIconAfter}</span>` : "";
1280
1309
  const inputHtml = hasIcon ? `<div class="relative">
1281
1310
  ${iconBeforeHtml}
1282
1311
  <input ${inputAttrs}>
@@ -1308,6 +1337,7 @@ function select(options) {
1308
1337
  } = options;
1309
1338
  const sizeClasses = getInputSizeClasses(size);
1310
1339
  const stateClasses = getInputStateClasses(state);
1340
+ const safeClassName = className ? (0, import_utils2.escapeHtml)(className) : "";
1311
1341
  const baseClasses = [
1312
1342
  "w-full rounded-lg border bg-white",
1313
1343
  "transition-colors duration-200",
@@ -1315,7 +1345,7 @@ function select(options) {
1315
1345
  disabled ? "opacity-50 cursor-not-allowed bg-gray-50" : "",
1316
1346
  sizeClasses,
1317
1347
  stateClasses,
1318
- className
1348
+ safeClassName
1319
1349
  ].filter(Boolean).join(" ");
1320
1350
  const dataAttrs = buildDataAttrs2(data);
1321
1351
  const optionsHtml = selectOptions.map((opt) => {