@underverse-ui/underverse 1.0.24 → 1.0.26

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
@@ -174,9 +174,11 @@ __export(index_exports, {
174
174
  Watermark: () => Watermark_default,
175
175
  cn: () => cn,
176
176
  cnLocal: () => cn2,
177
+ extractImageSrcsFromHtml: () => extractImageSrcsFromHtml,
177
178
  getAnimationStyles: () => getAnimationStyles,
178
179
  getUnderverseMessages: () => getUnderverseMessages,
179
180
  injectAnimationStyles: () => injectAnimationStyles,
181
+ normalizeImageUrl: () => normalizeImageUrl,
180
182
  prepareUEditorContentForSave: () => prepareUEditorContentForSave,
181
183
  shadcnAnimationStyles: () => shadcnAnimationStyles2,
182
184
  underverseMessages: () => underverseMessages,
@@ -346,25 +348,39 @@ var Button_default = Button;
346
348
  // ../../components/ui/Badge.tsx
347
349
  var import_jsx_runtime2 = require("react/jsx-runtime");
348
350
  var variantStyles = {
349
- default: "bg-muted text-muted-foreground border-border/50 hover:bg-muted/80",
350
- primary: "bg-primary text-primary-foreground border-primary/20 hover:bg-primary/90",
351
- secondary: "bg-secondary text-secondary-foreground border-secondary/20 hover:bg-secondary/90",
352
- success: "bg-success text-success-foreground border-success/20 hover:bg-success/90",
353
- warning: "bg-warning text-warning-foreground border-warning/20 hover:bg-warning/90",
354
- danger: "bg-destructive text-destructive-foreground border-destructive/20 hover:bg-destructive/90",
355
- destructive: "bg-destructive text-destructive-foreground border-destructive/20 hover:bg-destructive/90",
356
- info: "bg-info text-info-foreground border-info/20 hover:bg-info/90",
357
- outline: "bg-transparent text-foreground border-border hover:bg-accent/50",
358
- ghost: "bg-transparent hover:bg-accent/20 hover:text-accent-foreground border-transparent transition-colors",
359
- transparent: "bg-transparent text-foreground border-transparent hover:bg-accent/30",
360
- gradient: "bg-linear-to-r from-primary to-secondary text-primary-foreground border-transparent hover:from-primary/90 hover:to-secondary/90"
351
+ default: "bg-muted text-muted-foreground border-border/50",
352
+ primary: "bg-primary text-primary-foreground border-primary/20",
353
+ secondary: "bg-secondary text-secondary-foreground border-secondary/20",
354
+ success: "bg-success text-success-foreground border-success/20",
355
+ warning: "bg-warning text-warning-foreground border-warning/20",
356
+ danger: "bg-destructive text-destructive-foreground border-destructive/20",
357
+ destructive: "bg-destructive text-destructive-foreground border-destructive/20",
358
+ info: "bg-info text-info-foreground border-info/20",
359
+ outline: "bg-transparent text-foreground border-border",
360
+ ghost: "bg-transparent text-foreground border-transparent",
361
+ transparent: "bg-transparent text-foreground border-transparent",
362
+ gradient: "bg-linear-to-r from-primary to-secondary text-primary-foreground border-transparent"
363
+ };
364
+ var clickableVariantStyles = {
365
+ default: "hover:bg-muted/80",
366
+ primary: "hover:bg-primary/90",
367
+ secondary: "hover:bg-secondary/90",
368
+ success: "hover:bg-success/90",
369
+ warning: "hover:bg-warning/90",
370
+ danger: "hover:bg-destructive/90",
371
+ destructive: "hover:bg-destructive/90",
372
+ info: "hover:bg-info/90",
373
+ outline: "hover:bg-accent/50",
374
+ ghost: "hover:bg-accent/20 hover:text-accent-foreground",
375
+ transparent: "hover:bg-accent/30",
376
+ gradient: "hover:from-primary/90 hover:to-secondary/90"
361
377
  };
362
378
  var sizeStyles = {
363
379
  xs: "px-1.5 py-0.5 text-xs font-medium min-h-4.5",
364
380
  sm: "px-2 py-0.5 text-xs font-medium min-h-5",
365
381
  md: "px-2.5 py-1 text-xs font-medium min-h-6",
366
- lg: "px-3 py-1.5 text-sm font-medium min-h-7",
367
- xl: "px-4 py-2 text-sm font-semibold min-h-8"
382
+ lg: "px-3 py-1 text-xs font-medium min-h-6.5",
383
+ xl: "px-3.5 py-1.5 text-sm font-medium min-h-7"
368
384
  };
369
385
  var dotSizeStyles = {
370
386
  xs: "w-1.5 h-1.5",
@@ -407,11 +423,12 @@ var Badge = ({
407
423
  const baseClasses = cn(
408
424
  "inline-flex items-center border transition-all duration-200",
409
425
  "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1",
426
+ variantStyles[variant],
427
+ clickable && clickableVariantStyles[variant],
410
428
  clickable && "cursor-pointer hover:shadow-sm active:scale-95",
411
429
  pulse && "animate-pulse",
412
- "relative z-0",
430
+ "relative z-0"
413
431
  // Ensure badges stay below sticky headers (z-20, z-50)
414
- variantStyles[variant]
415
432
  );
416
433
  if (dot) {
417
434
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -24425,6 +24442,34 @@ function getErrorReason(error) {
24425
24442
  if (typeof error === "string" && error.trim()) return error;
24426
24443
  return "Unknown upload error.";
24427
24444
  }
24445
+ function decodeHtmlEntities(value) {
24446
+ return value.replace(/&quot;/gi, '"').replace(/&#39;/gi, "'").replace(/&amp;/gi, "&").replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/&nbsp;/gi, " ");
24447
+ }
24448
+ function normalizeImageUrl(url) {
24449
+ const input = decodeHtmlEntities(url.trim());
24450
+ if (!input) return "";
24451
+ if (isDataImageUrl(input)) return input;
24452
+ const isAbsolute = /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(input);
24453
+ if (!isAbsolute) {
24454
+ return input.split("#")[0] ?? input;
24455
+ }
24456
+ try {
24457
+ const parsed = new URL(input);
24458
+ parsed.hash = "";
24459
+ if (parsed.protocol === "http:" || parsed.protocol === "https:") {
24460
+ parsed.hostname = parsed.hostname.toLowerCase();
24461
+ if (parsed.protocol === "http:" && parsed.port === "80" || parsed.protocol === "https:" && parsed.port === "443") {
24462
+ parsed.port = "";
24463
+ }
24464
+ if (parsed.pathname.length > 1 && parsed.pathname.endsWith("/")) {
24465
+ parsed.pathname = parsed.pathname.slice(0, -1);
24466
+ }
24467
+ }
24468
+ return parsed.toString();
24469
+ } catch {
24470
+ return input.split("#")[0] ?? input;
24471
+ }
24472
+ }
24428
24473
  function replaceSrcInTag(match, nextSrc) {
24429
24474
  if (!match.srcAttr) return match.tag;
24430
24475
  const { start, end, quote } = match.srcAttr;
@@ -24458,6 +24503,24 @@ function collectImgTagMatches(html) {
24458
24503
  }
24459
24504
  return matches;
24460
24505
  }
24506
+ function extractImageSrcsFromHtml(html) {
24507
+ if (!html || !html.includes("<img")) return [];
24508
+ return collectImgTagMatches(html).map((match) => decodeHtmlEntities(match.srcAttr?.value.trim() ?? "")).filter(Boolean);
24509
+ }
24510
+ function createResult({
24511
+ html,
24512
+ uploaded,
24513
+ inlineUploaded,
24514
+ errors
24515
+ }) {
24516
+ return {
24517
+ html,
24518
+ uploaded,
24519
+ inlineImageUrls: extractImageSrcsFromHtml(html),
24520
+ inlineUploaded,
24521
+ errors
24522
+ };
24523
+ }
24461
24524
  var UEditorPrepareContentForSaveError = class extends Error {
24462
24525
  constructor(result) {
24463
24526
  super(
@@ -24472,11 +24535,11 @@ async function prepareUEditorContentForSave({
24472
24535
  uploadImageForSave
24473
24536
  }) {
24474
24537
  if (!html || !html.includes("<img")) {
24475
- return { html, uploaded: [], errors: [] };
24538
+ return createResult({ html, uploaded: [], inlineUploaded: [], errors: [] });
24476
24539
  }
24477
24540
  const imgMatches = collectImgTagMatches(html);
24478
24541
  if (imgMatches.length === 0) {
24479
- return { html, uploaded: [], errors: [] };
24542
+ return createResult({ html, uploaded: [], inlineUploaded: [], errors: [] });
24480
24543
  }
24481
24544
  const base64Candidates = [];
24482
24545
  for (const match of imgMatches) {
@@ -24491,19 +24554,21 @@ async function prepareUEditorContentForSave({
24491
24554
  });
24492
24555
  }
24493
24556
  if (base64Candidates.length === 0) {
24494
- return { html, uploaded: [], errors: [] };
24557
+ return createResult({ html, uploaded: [], inlineUploaded: [], errors: [] });
24495
24558
  }
24496
24559
  if (!uploadImageForSave) {
24497
- return {
24560
+ return createResult({
24498
24561
  html,
24499
24562
  uploaded: [],
24563
+ inlineUploaded: [],
24500
24564
  errors: base64Candidates.map((item) => ({
24501
24565
  index: item.index,
24502
24566
  reason: "`uploadImageForSave` is required to transform base64 images before save."
24503
24567
  }))
24504
- };
24568
+ });
24505
24569
  }
24506
24570
  const uploaded = [];
24571
+ const inlineUploaded = [];
24507
24572
  const errors = [];
24508
24573
  const replacements = /* @__PURE__ */ new Map();
24509
24574
  const uploadResults = await Promise.all(
@@ -24532,9 +24597,15 @@ async function prepareUEditorContentForSave({
24532
24597
  file: item.file,
24533
24598
  meta: item.meta
24534
24599
  });
24600
+ inlineUploaded.push({
24601
+ index: item.candidate.index,
24602
+ url: item.url,
24603
+ file: item.file,
24604
+ meta: item.meta
24605
+ });
24535
24606
  }
24536
24607
  if (replacements.size === 0) {
24537
- return { html, uploaded, errors };
24608
+ return createResult({ html, uploaded, inlineUploaded, errors });
24538
24609
  }
24539
24610
  let transformed = "";
24540
24611
  let cursor = 0;
@@ -24546,7 +24617,7 @@ async function prepareUEditorContentForSave({
24546
24617
  cursor = match.end;
24547
24618
  }
24548
24619
  transformed += html.slice(cursor);
24549
- return { html: transformed, uploaded, errors };
24620
+ return createResult({ html: transformed, uploaded, inlineUploaded, errors });
24550
24621
  }
24551
24622
 
24552
24623
  // ../../components/ui/UEditor/UEditor.tsx
@@ -24908,9 +24979,11 @@ function getUnderverseMessages(locale = "en") {
24908
24979
  Watermark,
24909
24980
  cn,
24910
24981
  cnLocal,
24982
+ extractImageSrcsFromHtml,
24911
24983
  getAnimationStyles,
24912
24984
  getUnderverseMessages,
24913
24985
  injectAnimationStyles,
24986
+ normalizeImageUrl,
24914
24987
  prepareUEditorContentForSave,
24915
24988
  shadcnAnimationStyles,
24916
24989
  underverseMessages,