design wip
This commit is contained in:
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)
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user