Updated Complete Tailwindcss Classes
This commit is contained in:
@@ -43,36 +43,36 @@ const summarySSR = selected.size
|
||||
|
||||
const sizeCls =
|
||||
p.size === "sm"
|
||||
? "h-9 px-3 text-sm"
|
||||
? "wr:h-9 wr:px-3 wr:text-sm"
|
||||
: p.size === "lg"
|
||||
? "h-11 px-4 text-base"
|
||||
: "h-10 px-3 text-sm";
|
||||
? "wr:h-11 wr:px-4 wr:text-base"
|
||||
: "wr:h-10 wr:px-3 wr:text-sm";
|
||||
|
||||
const controlCls =
|
||||
"py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg sm:text-sm " +
|
||||
"focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none " +
|
||||
"dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600";
|
||||
"wr:py-2.5 wr:sm:py-3 wr:px-4 wr:block wr:w-full wr:border-gray-200 wr:rounded-lg wr:sm:text-sm " +
|
||||
"wr:focus:border-blue-500 wr:focus:ring-blue-500 wr:disabled:opacity-50 wr:disabled:pointer-events-none " +
|
||||
"wr:dark:bg-neutral-900 wr:dark:border-neutral-700 wr:dark:text-neutral-400 wr:dark:placeholder-neutral-500 wr:dark:focus:ring-neutral-600";
|
||||
|
||||
const chipBase =
|
||||
"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs bg-muted text-foreground";
|
||||
"wr:inline-flex wr:items-center wr:gap-1 wr:rounded-full wr:px-2 wr:py-0.5 wr:text-xs wr:bg-muted wr:text-foreground";
|
||||
|
||||
const containerId = `ms-${Math.random().toString(36).slice(2)}`;
|
||||
const displayMode = p.display ?? "text";
|
||||
---
|
||||
|
||||
<div class={cn("space-y-1.5", p.class)} data-field={p.name} id={containerId}>
|
||||
<div class={cn("wr:space-y-1.5", p.class)} data-field={p.name} id={containerId}>
|
||||
{
|
||||
p.label && (
|
||||
<label
|
||||
for={fieldId}
|
||||
class="mb-1.5 block text-sm font-medium text-foreground"
|
||||
class="wr:mb-1.5 wr:block wr:text-sm wr:font-medium wr:text-foreground"
|
||||
>
|
||||
{p.label} {p.required && <span class="text-danger">*</span>}
|
||||
{p.label} {p.required && <span class="wr:text-danger">*</span>}
|
||||
</label>
|
||||
)
|
||||
}
|
||||
|
||||
<div class="relative">
|
||||
<div class="wr:relative">
|
||||
<input
|
||||
id={fieldId}
|
||||
type="text"
|
||||
@@ -85,8 +85,8 @@ const displayMode = p.display ?? "text";
|
||||
class={cn(
|
||||
controlCls,
|
||||
sizeCls,
|
||||
"pr-10 cursor-pointer",
|
||||
displayMode === "chips" && "pl-3",
|
||||
"wr:pr-10 wr:cursor-pointer",
|
||||
displayMode === "chips" && "wr:pl-3",
|
||||
)}
|
||||
placeholder={p.placeholder ?? "Select..."}
|
||||
value={displayMode === "text" ? summarySSR : ""}
|
||||
@@ -95,58 +95,60 @@ const displayMode = p.display ?? "text";
|
||||
{...p.disabled ? { disabled: true } : {}}
|
||||
/>
|
||||
|
||||
<div class="absolute inset-y-0 right-0 flex items-center gap-1 pr-2">
|
||||
<div
|
||||
class="wr:absolute wr:inset-y-0 wr:right-0 wr:flex wr:items-center wr:gap-1 wr:pr-2"
|
||||
>
|
||||
{
|
||||
p.clearable !== false && !p.disabled && (
|
||||
<button
|
||||
type="button"
|
||||
class={cn(
|
||||
"p-1 rounded hover:bg-muted",
|
||||
selected.size === 0 && "hidden",
|
||||
"wr:p-1 wr:rounded wr:hover:bg-muted",
|
||||
selected.size === 0 && "wr:hidden",
|
||||
)}
|
||||
data-ms-clear
|
||||
aria-label="Clear selection"
|
||||
>
|
||||
<Icon name="mdi:close" class="size-4" />
|
||||
<Icon name="mdi:close" class="wr:size-4" />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
<button
|
||||
type="button"
|
||||
class="p-1 rounded hover:bg-muted"
|
||||
class="wr:p-1 wr:rounded wr:hover:bg-muted"
|
||||
data-ms-toggle
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
<Icon name="mdi:chevron-down" class="size-5" />
|
||||
<Icon name="mdi:chevron-down" class="wr:size-5" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
data-ms-chips
|
||||
class={cn(
|
||||
"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 flex flex-wrap gap-1 pr-14",
|
||||
displayMode === "chips" ? "" : "hidden",
|
||||
"wr:pointer-events-none wr:absolute wr:left-3 wr:top-1/2 wr:-translate-y-1/2 wr:flex wr:flex-wrap wr:gap-1 wr:pr-14",
|
||||
displayMode === "chips" ? "" : "wr:hidden",
|
||||
)}
|
||||
>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute border-border bg-popover text-popover-foreground shadow-lg hidden mt-2 z-50 w-full max-h-72 p-1 space-y-0.5 bg-white border border-gray-200 rounded-lg overflow-hidden overflow-y-auto [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-gray-100 [&::-webkit-scrollbar-thumb]:bg-gray-300 dark:[&::-webkit-scrollbar-track]:bg-neutral-700 dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 dark:bg-neutral-900 dark:border-neutral-700"
|
||||
class="wr:absolute wr:border-border wr:bg-popover wr:text-popover-foreground wr:shadow-lg wr:hidden wr:mt-2 wr:z-50 wr:w-full wr:max-h-72 wr:p-1 wr:space-y-0.5 wr:bg-white wr:border wr:border-gray-200 wr:rounded-lg wr:overflow-hidden wr:overflow-y-auto wr:[&::-webkit-scrollbar]:w-2 wr:[&::-webkit-scrollbar-thumb]:rounded-full wr:[&::-webkit-scrollbar-track]:bg-gray-100 wr:[&::-webkit-scrollbar-thumb]:bg-gray-300 wr:dark:[&::-webkit-scrollbar-track]:bg-neutral-700 wr:dark:[&::-webkit-scrollbar-thumb]:bg-neutral-500 wr:dark:bg-neutral-900 wr:dark:border-neutral-700"
|
||||
id={`${containerId}-panel`}
|
||||
>
|
||||
{
|
||||
p.searchable !== false && (
|
||||
<div class="p-2 border-b border-border">
|
||||
<div class="relative">
|
||||
<div class="wr:p-2 wr:border-b wr:border-border">
|
||||
<div class="wr:relative">
|
||||
<Icon
|
||||
name="mdi:magnify"
|
||||
class="absolute left-2 top-1/2 -translate-y-1/2 size-4 text-muted-foreground"
|
||||
class="wr:absolute wr:left-2 wr:top-1/2 wr:-translate-y-1/2 wr:size-4 wr:text-muted-foreground"
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
class={cn(
|
||||
"py-2.5 sm:py-3 px-4 block w-full border-gray-200 rounded-lg sm:text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600",
|
||||
"h-9 pl-8 pr-2 text-sm",
|
||||
"wr:py-2.5 wr:sm:py-3 wr:px-4 wr:block wr:w-full wr:border-gray-200 wr:rounded-lg wr:sm:text-sm wr:focus:border-blue-500 wr:focus:ring-blue-500 wr:disabled:opacity-50 wr:disabled:pointer-events-none wr:dark:bg-neutral-900 wr:dark:border-neutral-700 wr:dark:text-neutral-400 wr:dark:placeholder-neutral-500 wr:dark:focus:ring-neutral-600",
|
||||
"wr:h-9 wr:pl-8 wr:pr-2 wr:text-sm",
|
||||
)}
|
||||
placeholder="Search…"
|
||||
data-ms-search
|
||||
@@ -161,15 +163,16 @@ const displayMode = p.display ?? "text";
|
||||
role="listbox"
|
||||
aria-multiselectable="true"
|
||||
id={`${containerId}-listbox`}
|
||||
class="max-h-56 overflow-auto p-1"
|
||||
class="wr:max-h-56 wr:overflow-auto wr:p-1"
|
||||
data-ms-list
|
||||
>
|
||||
{
|
||||
p.options.map((opt) => (
|
||||
<li
|
||||
class={cn(
|
||||
"flex items-center gap-2 px-2 py-2 rounded hover:bg-muted",
|
||||
opt.disabled && "opacity-60 cursor-not-allowed",
|
||||
"wr:flex wr:items-center wr:gap-2 wr:px-2 wr:py-2 wr:rounded wr:hover:bg-muted",
|
||||
opt.disabled &&
|
||||
"wr:opacity-60 wr:cursor-not-allowed",
|
||||
)}
|
||||
data-ms-item
|
||||
data-label={opt.label.toLowerCase()}
|
||||
@@ -180,36 +183,36 @@ const displayMode = p.display ?? "text";
|
||||
value={opt.value}
|
||||
checked={selected.has(opt.value)}
|
||||
disabled={p.disabled || opt.disabled}
|
||||
class="size-4 rounded border-border text-primary accent-primary focus:ring-primary/40"
|
||||
class="wr:size-4 wr:rounded wr:border-border wr:text-primary wr:accent-primary wr:focus:ring-primary/40"
|
||||
data-control
|
||||
/>
|
||||
<span class="text-sm">{opt.label}</span>
|
||||
<span class="wr:text-sm">{opt.label}</span>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
|
||||
<div
|
||||
class="flex items-center justify-between gap-2 p-2 border-t border-border"
|
||||
class="wr:flex wr:items-center wr:justify-between wr:gap-2 wr:p-2 wr:border-t wr:border-border"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="text-sm text-primary hover:underline disabled:opacity-50"
|
||||
class="wr:text-sm wr:text-primary wr:hover:underline wr:disabled:opacity-50"
|
||||
data-ms-select-all
|
||||
>
|
||||
Select all
|
||||
</button>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="wr:flex wr:items-center wr:gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="text-sm text-muted-foreground hover:underline"
|
||||
class="wr:text-sm wr:text-muted-foreground wr:hover:underline"
|
||||
data-ms-cancel
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="text-sm text-primary hover:underline"
|
||||
class="wr:text-sm wr:text-primary wr:hover:underline"
|
||||
data-ms-apply
|
||||
>
|
||||
Apply
|
||||
@@ -223,13 +226,15 @@ const displayMode = p.display ?? "text";
|
||||
p.description && (
|
||||
<p
|
||||
id={descId}
|
||||
class="mt-2 text-sm text-gray-500 dark:text-neutral-500"
|
||||
class="wr:mt-2 wr:text-sm wr:text-gray-500 wr:dark:text-neutral-500"
|
||||
>
|
||||
{p.description}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
<p id={errId} class="mt-1 text-xs text-danger" hidden>{p.error ?? ""}</p>
|
||||
<p id={errId} class="wr:mt-1 wr:text-xs wr:text-danger" hidden>
|
||||
{p.error ?? ""}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script
|
||||
@@ -265,21 +270,21 @@ const displayMode = p.display ?? "text";
|
||||
function setExpanded(v, { focusSearch = false } = {}) {
|
||||
open = v;
|
||||
input.setAttribute("aria-expanded", String(open));
|
||||
panel.classList.toggle("hidden", !open);
|
||||
panel.classList.toggle("wr:hidden", !open);
|
||||
if (open && focusSearch) sch?.focus();
|
||||
}
|
||||
|
||||
function makeChip(label) {
|
||||
const span = document.createElement("span");
|
||||
span.className =
|
||||
"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs bg-muted text-foreground";
|
||||
"wr:inline-flex wr:items-center wr:gap-1 wr:rounded-full wr:px-2 wr:py-0.5 wr:text-xs wr:bg-muted wr:text-foreground";
|
||||
span.textContent = label;
|
||||
return span;
|
||||
}
|
||||
|
||||
function toggleClear(show) {
|
||||
if (!btnClr) return;
|
||||
btnClr.classList.toggle("hidden", !show);
|
||||
btnClr.classList.toggle("wr:hidden", !show);
|
||||
}
|
||||
|
||||
function updateSummary() {
|
||||
@@ -301,7 +306,7 @@ const displayMode = p.display ?? "text";
|
||||
input.placeholder = labels.length ? "" : origPlaceholder;
|
||||
if (chips) {
|
||||
chips.innerHTML = "";
|
||||
chips.classList.add("hidden");
|
||||
chips.classList.add("wr:hidden");
|
||||
}
|
||||
} else {
|
||||
input.value = "";
|
||||
@@ -314,7 +319,7 @@ const displayMode = p.display ?? "text";
|
||||
.forEach((lab) => chips.appendChild(makeChip(lab)));
|
||||
const extra = labels.length - max;
|
||||
if (extra > 0) chips.appendChild(makeChip(`+${extra}`));
|
||||
chips.classList.toggle("hidden", labels.length === 0);
|
||||
chips.classList.toggle("wr:hidden", labels.length === 0);
|
||||
}
|
||||
|
||||
toggleClear(labels.length > 0);
|
||||
@@ -376,7 +381,7 @@ const displayMode = p.display ?? "text";
|
||||
const q = sch.value.trim().toLowerCase();
|
||||
root.querySelectorAll("[data-ms-item]").forEach((li) => {
|
||||
const m = (li.getAttribute("data-label") || "").includes(q);
|
||||
li.classList.toggle("hidden", !m);
|
||||
li.classList.toggle("wr:hidden", !m);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user