design wip

This commit is contained in:
salam committed 2026-02-03 10:57:50 +01:00
1 parent 70a443db6b
commit eb11298d24
22 files changed
+418 -81

No files matched your search

@@ -0,0 +1 @@
/*! tailwindcss v4.1.15 | MIT License | https://tailwindcss.com */@layer theme, base, components, utilities;@layer theme{:host,:root{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-300:oklch(80.8% 0.114 19.571);--color-red-500:oklch(63.7% 0.237 25.331);--color-sky-400:oklch(74.6% 0.16 232.661);--color-gray-50:oklch(98.5% 0.002 247.839);--color-gray-100:oklch(96.7% 0.003 264.542);--color-gray-200:oklch(92.8% 0.006 264.531);--color-gray-300:oklch(87.2% 0.01 258.338);--color-gray-400:oklch(70.7% 0.022 261.325);--color-gray-500:oklch(55.1% 0.027 264.364);--color-gray-600:oklch(44.6% 0.03 256.802);--color-gray-700:oklch(37.3% 0.034 259.733);--color-gray-800:oklch(27.8% 0.033 256.848);--color-gray-900:oklch(21% 0.034 264.665);--color-gray-950:oklch(13% 0.028 261.692);--color-black:#000;--color-white:#fff;--spacing:0.25rem;--breakpoint-sm:40rem;--breakpoint-md:48rem;--breakpoint-lg:64rem;--breakpoint-xl:80rem;--breakpoint-2xl:96rem;--container-3xs:16rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--container-7xl:80rem;--text-xs:0.75rem;--text-xs--line-height:calc(1 / 0.75);--text-sm:0.875rem;--text-sm--line-height:calc(1.25 / 0.875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-thin:100;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--tracking-tighter:-0.05em;--tracking-tight:-0.025em;--leading-loose:2;--radius-md:0.375rem;--radius-lg:0.5rem;--radius-xl:0.75rem;--ease-in:cubic-bezier(0.4,0,1,1);--ease-out:cubic-bezier(0,0,0.2,1);--ease-in-out:cubic-bezier(0.4,0,0.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(0.4,0,0.6,1) infinite;--default-transition-duration:150ms;--default-transition-timing-function:cubic-bezier(0.4,0,0.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-primary-50:var(--color-primary-50);--color-primary-100:var(--color-primary-100);--color-primary-200:var(--color-primary-200);--color-primary-300:var(--color-primary-300);--color-primary-400:var(--color-primary-400);--color-primary-500:var(--color-primary-500);--color-primary-600:var(--color-primary-600);--color-primary-700:var(--color-primary-700);--color-primary-800:var(--color-primary-800);--color-primary-900:var(--color-primary-900);--color-primary-950:var(--color-primary-950)}}@layer base{*,::backdrop,::file-selector-button,:after,:before{border:0 solid;box-sizing:border-box;margin:0;padding:0}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);tab-size:4;-webkit-tap-highlight-color:transparent}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-size:1em;font-variation-settings:var(--default-mono-font-variation-settings,normal)}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}menu,ol,ul{list-style:none}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}::file-selector-button,button,input,optgroup,select,textarea{background-color:transparent;border-radius:0;color:inherit;font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;opacity:1}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inLine truncated
@@ -0,0 +1,140 @@
export default function checkboxListFormComponent({ livewireId }) {
return {
areAllCheckboxesChecked: false,
checkboxListOptions: [],
search: "",
visibleCheckboxListOptions: [],
// Cache selectors for better performance
selectors: {
option: ".fi-fo-checkbox-option",
label: ".fi-fo-checkbox-option__label",
description: ".fi-fo-checkbox-option__description",
checkbox: "input[type=checkbox]",
checkedOrDisabled:
"input[type=checkbox]:checked, input[type=checkbox]:disabled",
},
init() {
this.cacheElements();
this.bindEvents();
this.$nextTick(() => {
this.checkIfAllCheckboxesAreChecked();
});
},
cacheElements() {
this.checkboxListOptions = Array.from(
this.$root.querySelectorAll(this.selectors.option)
);
this.updateVisibleCheckboxListOptions();
},
bindEvents() {
// Livewire hook for updates
Livewire.hook("commit", ({ component, succeed }) => {
succeed(() => {
this.$nextTick(() => {
if (component.id !== livewireId) {
return;
}
this.cacheElements();
this.checkIfAllCheckboxesAreChecked();
});
});
});
// Debounced search watcher
this.$watch(
"search",
this.debounce(() => {
this.updateVisibleCheckboxListOptions();
this.checkIfAllCheckboxesAreChecked();
}, 150)
);
},
// Simple debounce implementation
debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
},
isFoundInSearch(checkboxItem) {
if (!this.search || this.search.trim() === "") {
return true;
}
const searchTerm = this.search.toLowerCase();
// Cache elements to avoid repeated queries
const labelElement = checkboxItem.querySelector(this.selectors.label);
const descriptionElement = checkboxItem.querySelector(
this.selectors.description
);
const labelText = labelElement?.innerText?.toLowerCase() || "";
const descriptionText =
descriptionElement?.innerText?.toLowerCase() || "";
return (
labelText.includes(searchTerm) || descriptionText.includes(searchTerm)
);
},
checkIfAllCheckboxesAreChecked() {
if (this.visibleCheckboxListOptions.length === 0) {
this.areAllCheckboxesChecked = false;
return;
}
this.areAllCheckboxesChecked =
this.visibleCheckboxListOptions.length ===
this.visibleCheckboxListOptions.filter((checkboxLabel) =>
checkboxLabel.querySelector(this.selectors.checkedOrDisabled)
).length;
},
toggleAllCheckboxes() {
this.checkIfAllCheckboxesAreChecked();
const shouldCheck = !this.areAllCheckboxesChecked;
// Batch DOM operations for better performance
const checkboxesToUpdate = [];
this.visibleCheckboxListOptions.forEach((checkboxLabel) => {
const checkbox = checkboxLabel.querySelector(this.selectors.checkbox);
if (checkbox && !checkbox.disabled) {
checkboxesToUpdate.push(checkbox);
}
});
// Update all checkboxes at once
checkboxesToUpdate.forEach((checkbox) => {
checkbox.checked = shouldCheck;
checkbox.dispatchEvent(new Event("change"));
});
this.areAllCheckboxesChecked = shouldCheck;
},
updateVisibleCheckboxListOptions() {
if (!this.search || this.search.trim() === "") {
this.visibleCheckboxListOptions = [...this.checkboxListOptions];
return;
}
this.visibleCheckboxListOptions = this.checkboxListOptions.filter(
(checkboxListItem) => this.isFoundInSearch(checkboxListItem)
);
},
};
}