Skip to content

Commit 94267ac

Browse files
author
Ibrahim Haizel
committed
feat: add custom template callback for colored circles in selected items
1 parent 8574ff6 commit 94267ac

File tree

1 file changed

+93
-1
lines changed

1 file changed

+93
-1
lines changed

src/lib/components/ui/MultiSelectSearchAutocomplete.svelte

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,71 @@
515515
ignoreLocation: true,
516516
threshold: 0,
517517
},
518+
// Add the custom template callback to preserve colored circles
519+
callbackOnCreateTemplates: function (strToEl: any) {
520+
// public class names exposed by Choices
521+
const cn = this.config.classNames;
522+
const isMulti = this.passedElement?.element?.multiple === true;
523+
524+
// small escape for when allowHTML=false
525+
const esc = (s: string) =>
526+
String(s)
527+
.replace(/&/g, "&")
528+
.replace(/</g, "&lt;")
529+
.replace(/>/g, "&gt;");
530+
531+
// try to keep any existing templates if your build exposes them
532+
const base = (this as any)._templates ?? {};
533+
534+
return {
535+
...base,
536+
537+
// Custom item template for chips (selected items), not dropdown choices
538+
item: (_classNames: any, data: any) => {
539+
const classes = [
540+
cn.item,
541+
data.highlighted ? cn.highlightedState : cn.itemSelectable,
542+
data.placeholder ? cn.placeholder : "",
543+
]
544+
.filter(Boolean)
545+
.join(" ");
546+
547+
// ✅ Decide if this chip should be deletable
548+
const showRemove =
549+
isMulti && this.config.removeItemButton && !data.disabled;
550+
551+
// Circle
552+
let circle = "";
553+
if (enableSelectedItemCircles && isMulti && data.active) {
554+
const color = colorForValue(data.value); // ✅ value-only, stable
555+
circle = `<span class="choices__item-circle" style="background:${color}"></span>`;
556+
}
557+
558+
// Label
559+
const labelHtml = allowHTML ? data.label : esc(data.label);
560+
561+
// Remove button (same markup Choices normally generates)
562+
const removeBtn = showRemove
563+
? `<button type="button"
564+
class="${cn.button}"
565+
data-button
566+
aria-label="Remove ${esc(String(data.value))}"></button>`
567+
: "";
568+
569+
return strToEl(
570+
`<div class="${classes}"
571+
data-item
572+
data-id="${data.id}"
573+
data-value="${String(data.value)}"
574+
${showRemove ? "data-deletable" : ""}
575+
${data.active ? 'aria-selected="true"' : ""}
576+
${data.disabled ? 'aria-disabled="true"' : ""}>
577+
${circle}${labelHtml}${removeBtn}
578+
</div>`,
579+
);
580+
},
581+
};
582+
},
518583
...choicesOptions,
519584
});
520585
@@ -576,6 +641,9 @@
576641
"label",
577642
true,
578643
);
644+
645+
// Custom templates are automatically applied when setChoices is called
646+
// No need for additional refresh calls
579647
}
580648
}
581649
@@ -826,6 +894,18 @@
826894
827895
// Custom item template for chips (selected items), not dropdown choices
828896
item: (_classNames: any, data: any) => {
897+
// Debug: Log template data to understand what we're working with
898+
console.log("🎨 Template data for item:", {
899+
value: data.value,
900+
label: data.label,
901+
active: data.active,
902+
highlighted: data.highlighted,
903+
placeholder: data.placeholder,
904+
disabled: data.disabled,
905+
isMulti,
906+
enableSelectedItemCircles,
907+
});
908+
829909
const classes = [
830910
cn.item,
831911
data.highlighted ? cn.highlightedState : cn.itemSelectable,
@@ -840,9 +920,13 @@
840920
841921
// Circle
842922
let circle = "";
843-
if (enableSelectedItemCircles && isMulti && data.active) {
923+
if (enableSelectedItemCircles && isMulti) {
844924
const color = colorForValue(data.value); // ✅ value-only, stable
845925
circle = `<span class="choices__item-circle" style="background:${color}"></span>`;
926+
console.log("🎨 Adding circle with color:", {
927+
value: data.value,
928+
color,
929+
});
846930
}
847931
848932
// Label
@@ -1104,6 +1188,10 @@
11041188
"label",
11051189
true,
11061190
);
1191+
1192+
// Custom templates are automatically applied when setChoices is called
1193+
// No need for additional refresh calls
1194+
11071195
console.log(
11081196
"✅ Set new API choices:",
11091197
filteredApiChoices.length,
@@ -1212,6 +1300,10 @@
12121300
"label",
12131301
true,
12141302
);
1303+
1304+
// Custom templates are automatically applied when setChoices is called
1305+
// No need for additional refresh calls
1306+
12151307
console.log(
12161308
"✅ Set filtered static choices:",
12171309
filteredStaticChoices.length,

0 commit comments

Comments
 (0)