This commit is contained in:
Pete Matsyburka
2025-09-24 12:07:54 +03:00
parent f4426a8ee0
commit b64a84a362
51 changed files with 725 additions and 147 deletions
+16
View File
@@ -34,11 +34,19 @@ import MaskedInput from './elements/masked_input'
import SetDateButton from './elements/set_date_button'
import IndeterminateCheckbox from './elements/indeterminate_checkbox'
import AppTour from './elements/app_tour'
import AppTourStart from './elements/app_tour_start'
import DashboardDropzone from './elements/dashboard_dropzone'
import RequiredCheckboxGroup from './elements/required_checkbox_group'
import PageContainer from './elements/page_container'
import EmailEditor from './elements/email_editor'
import MountOnClick from './elements/mount_on_click'
import RemoveOnEvent from './elements/remove_on_event'
import ScrollTo from './elements/scroll_to'
import SetValue from './elements/set_value'
import ReviewForm from './elements/review_form'
import ShowOnValue from './elements/show_on_value'
import CustomValidation from './elements/custom_validation'
import ToggleClasses from './elements/toggle_classes'
import * as TurboInstantClick from './lib/turbo_instant_click'
@@ -107,12 +115,20 @@ safeRegisterElement('masked-input', MaskedInput)
safeRegisterElement('set-date-button', SetDateButton)
safeRegisterElement('indeterminate-checkbox', IndeterminateCheckbox)
safeRegisterElement('app-tour', AppTour)
safeRegisterElement('app-tour-start', AppTourStart)
safeRegisterElement('dashboard-dropzone', DashboardDropzone)
safeRegisterElement('check-on-click', CheckOnClick)
safeRegisterElement('required-checkbox-group', RequiredCheckboxGroup)
safeRegisterElement('page-container', PageContainer)
safeRegisterElement('email-editor', EmailEditor)
safeRegisterElement('mount-on-click', MountOnClick)
safeRegisterElement('remove-on-event', RemoveOnEvent)
safeRegisterElement('scroll-to', ScrollTo)
safeRegisterElement('set-value', SetValue)
safeRegisterElement('review-form', ReviewForm)
safeRegisterElement('show-on-value', ShowOnValue)
safeRegisterElement('custom-validation', CustomValidation)
safeRegisterElement('toggle-classes', ToggleClasses)
safeRegisterElement('template-builder', class extends HTMLElement {
connectedCallback () {
+2 -2
View File
@@ -19,7 +19,7 @@ button .disabled {
display: none;
}
button[disabled] .disabled {
button[disabled] .disabled, button.btn-disabled .disabled {
display: initial;
}
@@ -27,7 +27,7 @@ button .enabled {
display: initial;
}
button[disabled] .enabled {
button[disabled] .enabled, button.btn-disabled .enabled {
display: none;
}
@@ -0,0 +1,7 @@
export default class extends HTMLElement {
connectedCallback () {
this.querySelector('form').addEventListener('submit', () => {
window.app_tour.start()
})
}
}
@@ -0,0 +1,14 @@
export default class extends HTMLElement {
connectedCallback () {
const input = this.querySelector('input')
const invalidMessage = this.dataset.invalidMessage || ''
input.addEventListener('invalid', () => {
input.setCustomValidity(input.value ? invalidMessage : '')
})
input.addEventListener('input', () => {
input.setCustomValidity('')
})
}
}
@@ -0,0 +1,15 @@
export default class extends HTMLElement {
connectedCallback () {
const eventType = this.dataset.on || 'click'
const selector = document.getElementById(this.dataset.selectorId) || this
const eventElement = eventType === 'submit' ? this.querySelector('form') : this
eventElement.addEventListener(eventType, (event) => {
if (eventType === 'click') {
event.preventDefault()
}
selector.remove()
})
}
}
+19
View File
@@ -0,0 +1,19 @@
export default class extends HTMLElement {
connectedCallback () {
this.querySelectorAll('input[type="radio"]').forEach(radio => {
radio.addEventListener('change', (event) => {
const rating = parseInt(event.target.value)
if (rating === 10) {
window.review_comment.value = ''
window.review_comment.classList.add('hidden')
window.review_submit.classList.add('hidden')
event.target.form.submit()
} else {
window.review_comment.classList.remove('hidden')
window.review_submit.classList.remove('hidden')
}
})
})
}
}
+10
View File
@@ -0,0 +1,10 @@
export default class extends HTMLElement {
connectedCallback () {
this.selector = document.getElementById(this.dataset.selectorId)
this.addEventListener('click', () => {
this.selector.scrollIntoView({ behavior: 'smooth', block: 'start' })
history.replaceState(null, null, `#${this.dataset.selectorId}`)
})
}
}
+14
View File
@@ -13,6 +13,16 @@ export default class extends HTMLElement {
this.input.classList.remove('w-60')
}
})
this.button.addEventListener('click', (event) => {
event.preventDefault()
if (this.input.value || document.activeElement === this.input) {
return
}
this.input.focus()
})
}
get input () {
@@ -22,4 +32,8 @@ export default class extends HTMLElement {
get title () {
return document.querySelector(this.dataset.title)
}
get button () {
return this.querySelector('button')
}
}
+11
View File
@@ -0,0 +1,11 @@
export default class extends HTMLElement {
connectedCallback () {
const input = this.dataset.inputId ? document.getElementById(this.dataset.inputId) : this.querySelector('input')
this.firstElementChild.addEventListener(this.dataset.on || 'click', () => {
if (this.dataset.emptyOnly !== 'true' || !input.value) {
input.value = this.dataset.value
}
})
}
}
+17
View File
@@ -0,0 +1,17 @@
export default class extends HTMLElement {
connectedCallback () {
this.addEventListener('change', (event) => {
const targetValue = this.dataset.value
const selectorId = this.dataset.selectorId
const targetElement = document.getElementById(selectorId)
if (event.target.value === targetValue) {
targetElement.classList.remove('hidden')
} else {
targetElement.classList.add('hidden')
targetElement.value = ''
event.target.form.requestSubmit()
}
})
}
}
+16 -4
View File
@@ -1,15 +1,27 @@
export default class extends HTMLElement {
connectedCallback () {
const form = this.querySelector('form') || (this.querySelector('input, button, select') || this.lastElementChild).form
if (this.dataset.interval) {
this.interval = setInterval(() => {
this.querySelector('form').requestSubmit()
form.requestSubmit()
}, parseInt(this.dataset.interval))
} else if (this.dataset.on) {
this.lastElementChild.addEventListener(this.dataset.on, () => {
this.lastElementChild.form.requestSubmit()
this.lastElementChild.addEventListener(this.dataset.on, (event) => {
if (this.dataset.disable === 'true') {
form.querySelector('[type="submit"]')?.setAttribute('disabled', true)
}
if (this.dataset.submitIfValue === 'true') {
if (event.target.value) {
form.requestSubmit()
}
} else {
form.requestSubmit()
}
})
} else {
this.querySelector('form').requestSubmit()
form.requestSubmit()
}
}
+11
View File
@@ -0,0 +1,11 @@
export default class extends HTMLElement {
connectedCallback () {
const button = this.querySelector('a, button')
button.addEventListener('click', () => {
this.dataset.classes.split(' ').forEach((cls) => {
button.classList.toggle(cls)
})
})
}
}
+9 -3
View File
@@ -4,9 +4,15 @@ export default actionable(class extends HTMLElement {
trigger (event) {
const elementIds = JSON.parse(this.dataset.elementIds)
elementIds.forEach((elementId) => {
document.getElementById(elementId).classList.toggle('hidden', (event.target.dataset.toggleId || event.target.value) !== elementId)
})
if (event.target.type === 'checkbox') {
elementIds.forEach((elementId) => {
document.getElementById(elementId)?.classList.toggle('hidden')
})
} else {
elementIds.forEach((elementId) => {
document.getElementById(elementId).classList.toggle('hidden', (event.target.dataset.toggleId || event.target.value) !== elementId)
})
}
if (this.dataset.focusId) {
document.getElementById(this.dataset.focusId)?.focus()
+2
View File
@@ -6,6 +6,7 @@ import ToggleSubmit from './elements/toggle_submit'
import FetchForm from './elements/fetch_form'
import ScrollButtons from './elements/scroll_buttons'
import PageContainer from './elements/page_container'
import SubmitForm from './elements/submit_form'
const safeRegisterElement = (name, element, options = {}) => !window.customElements.get(name) && window.customElements.define(name, element, options)
@@ -14,6 +15,7 @@ safeRegisterElement('toggle-submit', ToggleSubmit)
safeRegisterElement('fetch-form', FetchForm)
safeRegisterElement('scroll-buttons', ScrollButtons)
safeRegisterElement('page-container', PageContainer)
safeRegisterElement('submit-form', SubmitForm)
safeRegisterElement('submission-form', class extends HTMLElement {
connectedCallback () {
this.appElem = document.createElement('div')
+2 -2
View File
@@ -19,7 +19,7 @@ button .disabled {
display: none;
}
button[disabled] .disabled {
button[disabled] .disabled, button.btn-disabled .disabled {
display: initial;
}
@@ -27,7 +27,7 @@ button .enabled {
display: initial;
}
button[disabled] .enabled {
button[disabled] .enabled, button.btn-disabled .enabled {
display: none;
}
+2 -2
View File
@@ -349,10 +349,10 @@
:id="field.uuid"
type="checkbox"
class="base-checkbox !h-7 !w-7"
:oninvalid="`this.setCustomValidity('${t('please_check_the_box_to_continue')}')`"
:onchange="`this.setCustomValidity(validity.valueMissing ? '${t('please_check_the_box_to_continue')}' : '');`"
:required="field.required"
:checked="!!values[field.uuid]"
@invalid="$event.target.setCustomValidity(t('please_check_the_box_to_continue'))"
@change="$event.target.setCustomValidity($event.target.validity.valueMissing ? t('please_check_the_box_to_continue') : '')"
@click="[scrollIntoField(field), values[field.uuid] = !values[field.uuid]]"
>
<span