Checkbox - JS + CSS
Checkbox
Struktur HTML
Section titled “Struktur HTML”
<label class="ina-checkbox">
<input
type="checkbox"
id="checkbox-1"
class="ina-checkbox__input peer"
/>
<div class="ina-checkbox__box ina-checkbox__box--unchecked"></div>
<div class="ina-checkbox__content">
<span class="ina-checkbox__label">Default checkbox</span>
</div>
</label>
Contoh Penggunaan
Section titled “Contoh Penggunaan”Contoh 1
Section titled “Contoh 1”<div class="p-5 w-full flex items-center justify-center">
<div class="flex flex-col gap-4">
<label for="checkbox-1" class="ina-checkbox">
<input type="checkbox" id="checkbox-1" class="ina-checkbox__input peer" />
<div class="ina-checkbox__box ina-checkbox__box--unchecked"></div>
<div class="ina-checkbox__content">
<span class="ina-checkbox__label">Unchecked</span>
</div>
</label>
<label for="checkbox-2" class="ina-checkbox">
<input type="checkbox" id="checkbox-2" class="ina-checkbox__input peer" checked />
<div class="ina-checkbox__box ina-checkbox__box--checked">
<svg
class="ina-checkbox__icon"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 6L9 17L4 12"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"></path>
</svg>
</div>
<div class="ina-checkbox__content">
<span class="ina-checkbox__label">Checked</span>
</div>
</label>
<label for="checkbox-3" class="ina-checkbox">
<input type="checkbox" id="checkbox-3" class="ina-checkbox__input peer" checked />
<div class="ina-checkbox__box ina-checkbox__box--indeterminate">
<svg
class="ina-checkbox__icon"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5 12H19"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"></path>
</svg>
</div>
<div class="ina-checkbox__content">
<span class="ina-checkbox__label">Indeterminate</span>
</div>
</label>
</div>
</div>
<script>
// Handle checkbox state changes
const checkbox1 = document.querySelector('#checkbox-1');
const checkbox2 = document.querySelector('#checkbox-2');
const checkbox3 = document.querySelector('#checkbox-3');
const box1 = checkbox1?.parentElement?.querySelector('.ina-checkbox__box');
const box2 = checkbox2?.parentElement?.querySelector('.ina-checkbox__box');
const box3 = checkbox3?.parentElement?.querySelector('.ina-checkbox__box');
function updateCheckboxState(input, box) {
if (!input || !box) return;
// Remove all state classes
box.classList.remove(
'ina-checkbox__box--unchecked',
'ina-checkbox__box--checked',
'ina-checkbox__box--indeterminate'
);
// Remove all icons first
const existingIcons = box.querySelectorAll('.ina-checkbox__icon');
existingIcons.forEach((icon) => icon.remove());
if (input.indeterminate) {
box.classList.add('ina-checkbox__box--indeterminate');
// Add minus icon for indeterminate
const minusIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
minusIcon.setAttribute('class', 'ina-checkbox__icon');
minusIcon.setAttribute('width', '14');
minusIcon.setAttribute('height', '14');
minusIcon.setAttribute('viewBox', '0 0 24 24');
minusIcon.setAttribute('fill', 'none');
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M5 12H19');
path.setAttribute('stroke', 'currentColor');
path.setAttribute('stroke-width', '2');
path.setAttribute('stroke-linecap', 'round');
path.setAttribute('stroke-linejoin', 'round');
minusIcon.appendChild(path);
box.appendChild(minusIcon);
} else if (input.checked) {
box.classList.add('ina-checkbox__box--checked');
// Add check icon for checked
const checkIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
checkIcon.setAttribute('class', 'ina-checkbox__icon');
checkIcon.setAttribute('width', '14');
checkIcon.setAttribute('height', '14');
checkIcon.setAttribute('viewBox', '0 0 24 24');
checkIcon.setAttribute('fill', 'none');
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M20 6L9 17L4 12');
path.setAttribute('stroke', 'currentColor');
path.setAttribute('stroke-width', '2');
path.setAttribute('stroke-linecap', 'round');
path.setAttribute('stroke-linejoin', 'round');
checkIcon.appendChild(path);
box.appendChild(checkIcon);
} else {
box.classList.add('ina-checkbox__box--unchecked');
// No icon for unchecked state
}
}
checkbox1?.addEventListener('change', () => {
updateCheckboxState(checkbox1, box1);
});
checkbox2?.addEventListener('change', () => {
updateCheckboxState(checkbox2, box2);
});
checkbox3?.addEventListener('change', (e) => {
const input = e.target;
// Set indeterminate state
input.indeterminate = true;
updateCheckboxState(checkbox3, box3);
});
// Initialize checkbox 3 as indeterminate
if (checkbox3 instanceof HTMLInputElement) {
checkbox3.indeterminate = true;
updateCheckboxState(checkbox3, box3);
}
// Initialize states on load
if (checkbox1) updateCheckboxState(checkbox1, box1);
if (checkbox2) updateCheckboxState(checkbox2, box2);
if (checkbox3) updateCheckboxState(checkbox3, box3);
</script>Contoh 2
Section titled “Contoh 2”<div class="p-5 w-full flex items-center justify-center">
<div class="flex flex-col gap-4">
<label for="checkbox-two-1" class="ina-checkbox">
<input type="checkbox" id="checkbox-two-1" class="ina-checkbox__input peer" />
<div class="ina-checkbox__box ina-checkbox__box--unchecked"></div>
<div class="ina-checkbox__content">
<span class="ina-checkbox__label">With subtext</span>
<span class="ina-checkbox__subtext">This is a helpful description</span>
</div>
</label>
<label for="checkbox-two-2" class="ina-checkbox ina-checkbox--disabled">
<input type="checkbox" id="checkbox-two-2" class="ina-checkbox__input peer" disabled />
<div class="ina-checkbox__box ina-checkbox__box--unchecked"></div>
<div class="ina-checkbox__content">
<span class="ina-checkbox__label">Disabled unchecked</span>
</div>
</label>
<label for="checkbox-two-3" class="ina-checkbox ina-checkbox--disabled">
<input
type="checkbox"
id="checkbox-two-3"
class="ina-checkbox__input peer"
checked
disabled
/>
<div class="ina-checkbox__box ina-checkbox__box--checked">
<svg
class="ina-checkbox__icon"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 6L9 17L4 12"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"></path>
</svg>
</div>
<div class="ina-checkbox__content">
<span class="ina-checkbox__label">Disabled checked</span>
</div>
</label>
</div>
</div>
<script>
// Handle checkbox state changes
const checkbox1 = document.querySelector('#checkbox-two-1');
const checkbox2 = document.querySelector('#checkbox-two-2');
const checkbox3 = document.querySelector('#checkbox-two-3');
const box1 = checkbox1?.parentElement?.querySelector('.ina-checkbox__box');
const box2 = checkbox2?.parentElement?.querySelector('.ina-checkbox__box');
const box3 = checkbox3?.parentElement?.querySelector('.ina-checkbox__box');
function updateCheckboxState(input, box) {
if (!input || !box) return;
// Remove all state classes
box.classList.remove(
'ina-checkbox__box--unchecked',
'ina-checkbox__box--checked',
'ina-checkbox__box--indeterminate'
);
// Remove all icons first
const existingIcons = box.querySelectorAll('.ina-checkbox__icon');
existingIcons.forEach((icon) => icon.remove());
if (input.indeterminate) {
box.classList.add('ina-checkbox__box--indeterminate');
// Add minus icon for indeterminate
const minusIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
minusIcon.setAttribute('class', 'ina-checkbox__icon');
minusIcon.setAttribute('width', '14');
minusIcon.setAttribute('height', '14');
minusIcon.setAttribute('viewBox', '0 0 24 24');
minusIcon.setAttribute('fill', 'none');
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M5 12H19');
path.setAttribute('stroke', 'currentColor');
path.setAttribute('stroke-width', '2');
path.setAttribute('stroke-linecap', 'round');
path.setAttribute('stroke-linejoin', 'round');
minusIcon.appendChild(path);
box.appendChild(minusIcon);
} else if (input.checked) {
box.classList.add('ina-checkbox__box--checked');
// Add check icon for checked
const checkIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
checkIcon.setAttribute('class', 'ina-checkbox__icon');
checkIcon.setAttribute('width', '14');
checkIcon.setAttribute('height', '14');
checkIcon.setAttribute('viewBox', '0 0 24 24');
checkIcon.setAttribute('fill', 'none');
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', 'M20 6L9 17L4 12');
path.setAttribute('stroke', 'currentColor');
path.setAttribute('stroke-width', '2');
path.setAttribute('stroke-linecap', 'round');
path.setAttribute('stroke-linejoin', 'round');
checkIcon.appendChild(path);
box.appendChild(checkIcon);
} else {
box.classList.add('ina-checkbox__box--unchecked');
// No icon for unchecked state
}
}
checkbox1?.addEventListener('change', () => {
updateCheckboxState(checkbox1, box1);
});
// Initialize states on load
if (checkbox1) updateCheckboxState(checkbox1, box1);
if (checkbox2) updateCheckboxState(checkbox2, box2);
if (checkbox3) updateCheckboxState(checkbox3, box3);
</script>