@copilotz/chat-ui 0.9.3 → 0.9.4

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.js CHANGED
@@ -2461,14 +2461,6 @@ var ThreadInitialsIcon = ({ title }) => {
2461
2461
  const initials = title?.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase() || "?";
2462
2462
  return /* @__PURE__ */ jsx18("div", { className: "flex h-5 w-5 shrink-0 items-center justify-center rounded bg-muted text-[10px] font-medium text-muted-foreground", children: initials });
2463
2463
  };
2464
- var TAG_COLOR_CLASSES = [
2465
- "bg-sky-500",
2466
- "bg-emerald-500",
2467
- "bg-violet-500",
2468
- "bg-amber-500",
2469
- "bg-rose-500",
2470
- "bg-cyan-500"
2471
- ];
2472
2464
  function slugTagName(name) {
2473
2465
  const slug = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
2474
2466
  return slug || "tag";
@@ -2500,31 +2492,125 @@ function collectThreadTags(threads) {
2500
2492
  }
2501
2493
  return tags.sort((a, b) => a.name.localeCompare(b.name));
2502
2494
  }
2503
- function tagColorIndex(tag) {
2495
+ function normalizeTagColorKey(tag) {
2496
+ return (tag.name || tag.id || "tag").trim().toLowerCase().normalize("NFKD").replace(/[\u0300-\u036f]/g, "");
2497
+ }
2498
+ function hashTagColorKey(value) {
2504
2499
  let hash = 0;
2505
- for (const char of tag.id || tag.name) {
2500
+ for (const char of value) {
2506
2501
  hash = hash * 31 + char.charCodeAt(0) >>> 0;
2507
2502
  }
2508
- return hash % TAG_COLOR_CLASSES.length;
2503
+ return hash;
2509
2504
  }
2510
- var TagDot = ({ tag }) => /* @__PURE__ */ jsx18(
2511
- "span",
2512
- {
2513
- "aria-hidden": "true",
2514
- className: `h-2 w-2 shrink-0 rounded-full ${TAG_COLOR_CLASSES[tagColorIndex(tag)]}`
2505
+ function hslToRgb(hue, saturation, lightness) {
2506
+ const chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;
2507
+ const x = chroma * (1 - Math.abs(hue / 60 % 2 - 1));
2508
+ const match = lightness - chroma / 2;
2509
+ let red = 0;
2510
+ let green = 0;
2511
+ let blue = 0;
2512
+ if (hue < 60) {
2513
+ red = chroma;
2514
+ green = x;
2515
+ } else if (hue < 120) {
2516
+ red = x;
2517
+ green = chroma;
2518
+ } else if (hue < 180) {
2519
+ green = chroma;
2520
+ blue = x;
2521
+ } else if (hue < 240) {
2522
+ green = x;
2523
+ blue = chroma;
2524
+ } else if (hue < 300) {
2525
+ red = x;
2526
+ blue = chroma;
2527
+ } else {
2528
+ red = chroma;
2529
+ blue = x;
2515
2530
  }
2516
- );
2517
- var ThreadTagBadge = ({ tag }) => /* @__PURE__ */ jsxs11(
2518
- Badge,
2519
- {
2520
- variant: "secondary",
2521
- className: "h-4 max-w-24 gap-1 rounded px-1.5 py-0 text-[10px] font-normal text-muted-foreground",
2522
- children: [
2523
- /* @__PURE__ */ jsx18(TagDot, { tag }),
2524
- /* @__PURE__ */ jsx18("span", { className: "truncate", children: tag.name })
2525
- ]
2531
+ return {
2532
+ red: Math.round((red + match) * 255),
2533
+ green: Math.round((green + match) * 255),
2534
+ blue: Math.round((blue + match) * 255)
2535
+ };
2536
+ }
2537
+ function tagColor(tag) {
2538
+ if (tag.color) {
2539
+ return {
2540
+ accent: tag.color,
2541
+ background: `color-mix(in srgb, ${tag.color} 12%, transparent)`,
2542
+ border: `color-mix(in srgb, ${tag.color} 24%, transparent)`
2543
+ };
2526
2544
  }
2527
- );
2545
+ const hue = hashTagColorKey(normalizeTagColorKey(tag)) % 360;
2546
+ const { red, green, blue } = hslToRgb(hue, 0.68, 0.48);
2547
+ return {
2548
+ accent: `rgb(${red} ${green} ${blue})`,
2549
+ background: `rgb(${red} ${green} ${blue} / 0.12)`,
2550
+ border: `rgb(${red} ${green} ${blue} / 0.24)`
2551
+ };
2552
+ }
2553
+ var TagDot = ({ tag }) => {
2554
+ const color = tagColor(tag);
2555
+ return /* @__PURE__ */ jsx18(
2556
+ "span",
2557
+ {
2558
+ "aria-hidden": "true",
2559
+ className: "h-2 w-2 shrink-0 rounded-full",
2560
+ style: { backgroundColor: color.accent }
2561
+ }
2562
+ );
2563
+ };
2564
+ var ThreadTagBadge = ({ tag }) => {
2565
+ const color = tagColor(tag);
2566
+ return /* @__PURE__ */ jsxs11(
2567
+ Badge,
2568
+ {
2569
+ variant: "secondary",
2570
+ className: "h-4 max-w-24 gap-1 rounded border px-1.5 py-0 text-[10px] font-normal text-muted-foreground",
2571
+ style: {
2572
+ backgroundColor: color.background,
2573
+ borderColor: color.border
2574
+ },
2575
+ children: [
2576
+ /* @__PURE__ */ jsx18(TagDot, { tag }),
2577
+ /* @__PURE__ */ jsx18("span", { className: "truncate", children: tag.name })
2578
+ ]
2579
+ }
2580
+ );
2581
+ };
2582
+ var ThreadTagEditorBadge = ({
2583
+ tag,
2584
+ removeLabel,
2585
+ onRemove
2586
+ }) => {
2587
+ const color = tagColor(tag);
2588
+ return /* @__PURE__ */ jsxs11(
2589
+ Badge,
2590
+ {
2591
+ variant: "secondary",
2592
+ className: "gap-1 rounded-md border py-1 text-sm font-normal",
2593
+ style: {
2594
+ backgroundColor: color.background,
2595
+ borderColor: color.border
2596
+ },
2597
+ children: [
2598
+ /* @__PURE__ */ jsx18(TagDot, { tag }),
2599
+ tag.name,
2600
+ /* @__PURE__ */ jsx18(
2601
+ "button",
2602
+ {
2603
+ type: "button",
2604
+ className: "rounded-sm hover:bg-background/80",
2605
+ onClick: onRemove,
2606
+ "aria-label": removeLabel,
2607
+ children: /* @__PURE__ */ jsx18(X2, { className: "h-3 w-3" })
2608
+ }
2609
+ )
2610
+ ]
2611
+ }
2612
+ );
2613
+ };
2528
2614
  var Sidebar2 = ({
2529
2615
  threads,
2530
2616
  currentThreadId,
@@ -2991,25 +3077,12 @@ var Sidebar2 = ({
2991
3077
  /* @__PURE__ */ jsxs11("div", { className: "space-y-4", children: [
2992
3078
  /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
2993
3079
  /* @__PURE__ */ jsx18("div", { className: "text-sm font-medium", children: config.labels?.tags || "Tags" }),
2994
- (tagDialogThread.tags ?? []).length === 0 ? /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: config.labels?.untagged || "Untagged" }) : /* @__PURE__ */ jsx18("div", { className: "flex flex-wrap gap-2", children: (tagDialogThread.tags ?? []).map((tag) => /* @__PURE__ */ jsxs11(
2995
- Badge,
3080
+ (tagDialogThread.tags ?? []).length === 0 ? /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: config.labels?.untagged || "Untagged" }) : /* @__PURE__ */ jsx18("div", { className: "flex flex-wrap gap-2", children: (tagDialogThread.tags ?? []).map((tag) => /* @__PURE__ */ jsx18(
3081
+ ThreadTagEditorBadge,
2996
3082
  {
2997
- variant: "secondary",
2998
- className: "gap-1 rounded-md py-1 text-sm font-normal",
2999
- children: [
3000
- /* @__PURE__ */ jsx18(TagDot, { tag }),
3001
- tag.name,
3002
- /* @__PURE__ */ jsx18(
3003
- "button",
3004
- {
3005
- type: "button",
3006
- className: "rounded-sm hover:bg-background/80",
3007
- onClick: () => removeTagFromThread(tagDialogThread, tag.id),
3008
- "aria-label": config.labels?.removeTag || "Remove tag",
3009
- children: /* @__PURE__ */ jsx18(X2, { className: "h-3 w-3" })
3010
- }
3011
- )
3012
- ]
3083
+ tag,
3084
+ removeLabel: config.labels?.removeTag || "Remove tag",
3085
+ onRemove: () => removeTagFromThread(tagDialogThread, tag.id)
3013
3086
  },
3014
3087
  tag.id
3015
3088
  )) })