select2-premium
Style Select2 dropdowns with premium design in KLASSCI Laravel/Blade project. Use when adding or styling Select2 selects, creating searchable dropdowns, rendering custom items with avatars/badges, or
SKILL.md.claude/skills/select2-premium/SKILL.md
GitHubSelect2 Premium — KLASSCI Design System
Style Select2 4.1.0-rc.0 dropdowns to match the KLASSCI premium design system (Bootstrap 5 theme).
Quick Init
$('#mySelect').select2({
theme: 'bootstrap-5',
language: 'fr',
placeholder: 'Rechercher...',
allowClear: true,
dropdownParent: $('#myModal'), // REQUIRED inside Bootstrap modals
width: 'resolve'
});
KLASSCI Design Rules
- Use
--primary: #0453cbgradient for highlighted options - Border-radius: 10-14px on dropdowns, 8px on items
- No harsh borders — use subtle
#e2e8f0or borderless with background - Shadow:
0 12px 40px rgba(0,0,0,0.14)on dropdowns - Font-weight: 500 on options, 600 on selected
- Padding:
6pxinside dropdown for rounded item spacing
Custom Rendering with Avatars
Use templateResult (dropdown items) and templateSelection (selected display).
Security: Return jQuery objects with .text() for user data — never concatenate HTML strings.
function formatWithAvatar(data) {
if (!data.id) return data.text;
var $el = $('<div class="d-flex align-items-center gap-2"></div>');
var initial = (data.text || '?')[0].toUpperCase();
var $avatar = $('<div></div>').text(initial).css({
width: '32px', height: '32px', borderRadius: '8px',
background: 'linear-gradient(135deg, #0453cb, #5e91de)',
color: 'white', display: 'flex', alignItems: 'center',
justifyContent: 'center', fontWeight: '700', fontSize: '0.8rem'
});
var $info = $('<div class="flex-grow-1 min-w-0"></div>');
$info.append($('<div class="fw-semibold text-truncate"></div>').text(data.text));
if (data.subtitle) {
$info.append($('<div class="small text-muted text-truncate"></div>').text(data.subtitle));
}
$el.append($avatar, $info);
return $el;
}
$('#mySelect').select2({ templateResult: formatWithAvatar });
Modal Integration (CRITICAL)
Bootstrap .modal has overflow-y: auto which clips any absolutely-positioned child. Setting dropdownParent to the modal element does NOT work — the dropdown renders inside the modal but is still clipped by its overflow.
The working solution: dropdownParent on .modal-content + overflow: visible !important on all parent layers.
$('#mySelect').select2({
dropdownParent: $('#myModal .modal-content'),
theme: 'bootstrap-5',
width: '100%'
});
/* Override Bootstrap overflow on ALL modal layers */
#myModal.modal { overflow: visible !important; }
#myModal .modal-dialog { overflow: visible !important; }
#myModal .modal-content { overflow: visible !important; }
Why this works: The dropdown renders inside .modal-content (proper alignment), and overflow: visible !important on .modal, .modal-dialog, and .modal-content prevents clipping at every layer.
Why dropdownParent: $(document.body) is worse: z-index wars, dropdown misaligned with the select, and visual disconnect from the modal.
Alternative: Use Choices.js instead of Select2 in modals (see annonces/create.blade.php for example — Choices.js renders inline with position: 'bottom' and overflow: visible).
Key Gotchas
- Modal overflow clips Select2: Always use
dropdownParent: $(document.body)+ z-index 1075+ - Init after visible: Use
shown.bs.modalevent, notshow.bs.modal - Width 100%: Set
width: 100%on<select>CSS +width: 'resolve'in config - Re-init after AJAX DOM replace:
$('#sel').select2('destroy').select2({...}) - Event namespace: Use
change.select2to avoid conflicts with other listeners - String returns are auto-escaped: Only jQuery objects render HTML
- Choices.js alternative: For modals, consider Choices.js which renders inline without overflow issues
Reference
For full CSS selectors, AJAX patterns, events, and programmatic control: