form validation styling (very hard!)
This commit is contained in:
parent
6a68f81e59
commit
f590936b2c
@ -191,3 +191,63 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
}
|
||||
|
||||
/* End Guild Header */
|
||||
|
||||
/* Form Controls */
|
||||
|
||||
.text-input-label {
|
||||
@apply block text-sm font-medium mb-2 dark:text-white
|
||||
}
|
||||
|
||||
.text-input {
|
||||
@apply
|
||||
py-3
|
||||
px-4
|
||||
block
|
||||
w-full
|
||||
rounded-md
|
||||
text-sm
|
||||
disabled:opacity-50
|
||||
disabled:pointer-events-none
|
||||
border-gray-200
|
||||
focus:border-blue-500
|
||||
focus:ring-blue-500
|
||||
dark:bg-neutral-900
|
||||
dark:border-neutral-700
|
||||
dark:text-neutral-400
|
||||
dark:placeholder-neutral-500
|
||||
dark:focus:ring-neutral-600
|
||||
}
|
||||
|
||||
.text-input-help {
|
||||
@apply mt-2 text-sm text-gray-500 dark:text-neutral-500
|
||||
}
|
||||
|
||||
.select-input {
|
||||
@apply
|
||||
relative
|
||||
py-3
|
||||
ps-4
|
||||
pe-9
|
||||
flex
|
||||
gap-x-2
|
||||
text-nowrap
|
||||
w-full
|
||||
cursor-pointer
|
||||
bg-white
|
||||
border
|
||||
border-gray-200
|
||||
rounded-md
|
||||
text-start
|
||||
text-sm
|
||||
focus:outline-none
|
||||
focus:ring-2
|
||||
focus:ring-blue-500
|
||||
dark:bg-neutral-900
|
||||
dark:border-neutral-700
|
||||
dark:text-neutral-400
|
||||
dark:focus:outline-none
|
||||
dark:focus:ring-1
|
||||
dark:focus:ring-neutral-600
|
||||
}
|
||||
|
||||
/* End Form Controls */
|
@ -1576,10 +1576,6 @@ video {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.rounded-2xl {
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
@ -2487,6 +2483,138 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
|
||||
/* End Guild Header */
|
||||
|
||||
/* Form Controls */
|
||||
|
||||
.text-input-label {
|
||||
margin-bottom: 0.5rem;
|
||||
display: block;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.text-input-label:where(.dark, .dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.text-input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 0.375rem;
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.text-input:focus {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
|
||||
}
|
||||
|
||||
.text-input:disabled {
|
||||
pointer-events: none;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.text-input:where(.dark, .dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(64 64 64 / var(--tw-border-opacity, 1));
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1));
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(163 163 163 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.text-input:where(.dark, .dark *)::-moz-placeholder {
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(115 115 115 / var(--tw-placeholder-opacity, 1));
|
||||
}
|
||||
|
||||
.text-input:where(.dark, .dark *)::placeholder {
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(115 115 115 / var(--tw-placeholder-opacity, 1));
|
||||
}
|
||||
|
||||
.text-input:focus:where(.dark, .dark *) {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(82 82 82 / var(--tw-ring-opacity, 1));
|
||||
}
|
||||
|
||||
.text-input-help {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(107 114 128 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.text-input-help:where(.dark, .dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(115 115 115 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.select-input {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
-moz-column-gap: 0.5rem;
|
||||
column-gap: 0.5rem;
|
||||
text-wrap: nowrap;
|
||||
border-radius: 0.375rem;
|
||||
border-width: 1px;
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(229 231 235 / var(--tw-border-opacity, 1));
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
padding-inline-start: 1rem;
|
||||
padding-inline-end: 2.25rem;
|
||||
text-align: start;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.select-input:focus {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1));
|
||||
}
|
||||
|
||||
.select-input:where(.dark, .dark *) {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(64 64 64 / var(--tw-border-opacity, 1));
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(23 23 23 / var(--tw-bg-opacity, 1));
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(163 163 163 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.select-input:focus:where(.dark, .dark *) {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(82 82 82 / var(--tw-ring-opacity, 1));
|
||||
}
|
||||
|
||||
/* End Form Controls */
|
||||
|
||||
.before\:absolute::before {
|
||||
content: var(--tw-content);
|
||||
position: absolute;
|
||||
@ -2792,6 +2920,50 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.group:invalid .group-invalid\:pointer-events-none {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.group:invalid .group-invalid\:opacity-30 {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.group.submitted .group-\[\.submitted\]\:invalid\:border-red-500:invalid {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
|
||||
}
|
||||
|
||||
.group.submitted .group-\[\.submitted\]\:invalid\:ring-red-500:invalid {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1));
|
||||
}
|
||||
|
||||
.group.submitted .peer:invalid ~ .group-\[\.submitted\]\:peer-\[\:invalid\]\:block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.group.submitted .peer:invalid ~ .group-\[\.submitted\]\:peer-\[\:invalid\]\:hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.group.submitted .peer:invalid ~ .group-\[\.submitted\]\:peer-\[\:invalid\]\:border-red-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(239 68 68 / var(--tw-border-opacity, 1));
|
||||
}
|
||||
|
||||
.group.submitted .peer:invalid ~ .group-\[\.submitted\]\:peer-\[\:invalid\]\:ring-red-500 {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity, 1));
|
||||
}
|
||||
|
||||
.group.submitted .peer:has(:invalid) ~ .group-\[\.submitted\]\:peer-has-\[\:invalid\]\:block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.group.submitted .peer:has(:invalid) ~ .group-\[\.submitted\]\:peer-has-\[\:invalid\]\:hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hs-dropdown.open > .hs-dropdown-open\:block {
|
||||
display: block;
|
||||
}
|
||||
@ -3082,11 +3254,6 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:gap-x-10 {
|
||||
-moz-column-gap: 2.5rem;
|
||||
column-gap: 2.5rem;
|
||||
}
|
||||
|
||||
.sm\:gap-x-3 {
|
||||
-moz-column-gap: 0.75rem;
|
||||
column-gap: 0.75rem;
|
||||
@ -3107,8 +3274,8 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.sm\:rounded-3xl {
|
||||
border-radius: 1.5rem;
|
||||
.sm\:rounded-lg {
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.sm\:p-5 {
|
||||
@ -3185,6 +3352,11 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.md\:gap-x-10 {
|
||||
-moz-column-gap: 2.5rem;
|
||||
column-gap: 2.5rem;
|
||||
}
|
||||
|
||||
.md\:gap-x-3 {
|
||||
-moz-column-gap: 0.75rem;
|
||||
column-gap: 0.75rem;
|
||||
@ -3543,17 +3715,6 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
color: rgb(115 115 115 / var(--tw-text-opacity, 1));
|
||||
}
|
||||
|
||||
.dark\:focus\:outline-none:focus:where(.dark, .dark *) {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.dark\:focus\:ring-1:focus:where(.dark, .dark *) {
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
}
|
||||
|
||||
.dark\:focus\:ring-neutral-600:focus:where(.dark, .dark *) {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(82 82 82 / var(--tw-ring-opacity, 1));
|
||||
@ -3613,4 +3774,4 @@ hs-accordion-toggle w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 te
|
||||
|
||||
.\[\&\:\:-webkit-scrollbar\]\:w-2::-webkit-scrollbar {
|
||||
width: 0.5rem;
|
||||
}
|
||||
}
|
@ -274,6 +274,7 @@ $("input[name='filterActive']").on("change", () => {
|
||||
})
|
||||
|
||||
const openSubForm = async () => {
|
||||
$("#subForm").removeClass("submitted");
|
||||
HSOverlay.open($("#subModal").get(0))
|
||||
}
|
||||
|
||||
@ -282,6 +283,14 @@ $(document).on("click", ".openSubModal-js", openSubForm);
|
||||
const submitForm = async event => {
|
||||
event.preventDefault();
|
||||
|
||||
const form = $("#subForm").get(0);
|
||||
$(form).addClass("submitted");
|
||||
|
||||
if (!form.checkValidity()) {
|
||||
alert("form invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
await $.ajax({
|
||||
url: `/guild/${guildId}/subscriptions/api`,
|
||||
method: "post",
|
||||
|
@ -250,38 +250,48 @@
|
||||
</svg>
|
||||
</button>
|
||||
</div> -->
|
||||
<form id="subForm" class="grid sm:grid-cols-2 gap-y-4 sm:gap-y-6 md:gap-y-8 gap-x-6 sm:gap-x-8 sm:gap-x-10">
|
||||
<form id="subForm" novalidate class="group grid sm:grid-cols-2 gap-y-4 sm:gap-y-6 md:gap-y-8 gap-x-6 sm:gap-x-8 md:gap-x-10">
|
||||
<div>
|
||||
<label for="formName" class="block text-sm font-medium mb-2 dark:text-white">Name</label>
|
||||
<input type="text" id="formName" name="name" class="form-input py-3 px-4 block w-full border-gray-200 rounded-md 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">
|
||||
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
|
||||
<label for="formName" class="text-input-label">Name</label>
|
||||
<input type="text" id="formName" name="name" class="form-input text-input peer group-[.submitted]:invalid:border-red-500 group-[.submitted]:invalid:ring-red-500" required>
|
||||
<p class="text-input-help block group-[.submitted]:peer-[:invalid]:hidden">
|
||||
Human-readable name for this entry.
|
||||
</p>
|
||||
<p class="mt-2 text-sm text-red-500 hidden group-[.submitted]:peer-[:invalid]:block">
|
||||
Please enter a name.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="formUrl" class="block text-sm font-medium mb-2 dark:text-white">URL</label>
|
||||
<input type="url" id="formUrl" name="url" class="form-input py-3 px-4 block w-full border-gray-200 rounded-md 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">
|
||||
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
|
||||
<label for="formUrl" class="text-input-label">URL</label>
|
||||
<input type="url" id="formUrl" name="url" class="form-input text-input peer group-[.submitted]:invalid:border-red-500 group-[.submitted]:invalid:ring-red-500" required>
|
||||
<p class="text-input-help block group-[.submitted]:peer-[:invalid]:hidden">
|
||||
Source of RSS content.
|
||||
</p>
|
||||
<p class="mt-2 text-sm text-red-500 hidden group-[.submitted]:peer-[:invalid]:block">
|
||||
Please enter a valid URL.
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<label for="formStyle" class="block text-sm font-medium mb-2 dark:text-white">Message Style</label>
|
||||
<select id="formStyle" name="message_style" data-hs-select='{
|
||||
<label for="formStyle" class="text-input-label">Message Style</label>
|
||||
<select id="formStyle" name="message_style" class="peer" data-hs-select='{
|
||||
"placeholder": "Select option...",
|
||||
"toggleTag": "<button type=\"button\" aria-expanded=\"false\"></button>",
|
||||
"toggleClasses": "form-select hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 relative py-3 ps-4 pe-9 flex gap-x-2 text-nowrap w-full cursor-pointer bg-white border border-gray-200 rounded-md text-start text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-neutral-600",
|
||||
"toggleClasses": "form-select hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 select-input group-[.submitted]:peer-[:invalid]:border-red-500 group-[.submitted]:peer-[:invalid]:ring-red-500",
|
||||
"dropdownScope": "window",
|
||||
"wrapperClasses": "peer",
|
||||
"dropdownClasses": "z-[80] w-full max-h-72 p-1 space-y-0.5 bg-white border border-gray-200 rounded-md 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",
|
||||
"optionClasses": "py-2 px-4 w-full text-sm text-gray-800 cursor-pointer hover:bg-gray-100 rounded-md focus:outline-none focus:bg-gray-100 hs-select-disabled:pointer-events-none hs-select-disabled:opacity-50 dark:bg-neutral-900 dark:hover:bg-neutral-800 dark:text-neutral-200 dark:focus:bg-neutral-800",
|
||||
"optionTemplate": "<div class=\"flex justify-between items-center w-full\"><span data-title></span><span class=\"hidden hs-selected:block\"><svg class=\"shrink-0 size-3.5 text-blue-600 dark:text-blue-500 \" xmlns=\"http:.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg></span></div>"
|
||||
}' class="hidden">
|
||||
}' class="hidden" required>
|
||||
<option value="">Choose</option>
|
||||
<option>Default style</option>
|
||||
</select>
|
||||
<p class="mt-2 text-sm text-gray-500 dark:text-neutral-500">
|
||||
<p class="text-input-help block group-[.submitted]:peer-has-[:invalid]:hidden">
|
||||
Appearance of delivered content.
|
||||
</p>
|
||||
<p class="mt-2 text-sm text-red-500 hidden group-[.submitted]:peer-has-[:invalid]:block">
|
||||
Please select an option.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="formPublishedThreshold" class="block text-sm font-medium mb-2 dark:text-white">Published Threshold</label>
|
||||
@ -363,7 +373,7 @@
|
||||
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-md border border-gray-200 bg-white text-gray-800 shadow-sm hover:bg-gray-50 focus:outline-none focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700" data-hs-overlay="#subModal">
|
||||
Close
|
||||
</button>
|
||||
<button type="submit" form="subForm" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-md border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
|
||||
<button type="submit" form="subForm" class="group-invalid:pointer-events-none group-invalid:opacity-30 py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-md border border-transparent bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none">
|
||||
Save changes
|
||||
</button>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user