diff --git a/app/javascript/application.js b/app/javascript/application.js
index 6ff4b401..af363801 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -36,6 +36,7 @@ import IndeterminateCheckbox from './elements/indeterminate_checkbox'
import AppTour from './elements/app_tour'
import DashboardDropzone from './elements/dashboard_dropzone'
import RequiredCheckboxGroup from './elements/required_checkbox_group'
+import PageContainer from './elements/page_container'
import * as TurboInstantClick from './lib/turbo_instant_click'
@@ -107,6 +108,7 @@ safeRegisterElement('app-tour', AppTour)
safeRegisterElement('dashboard-dropzone', DashboardDropzone)
safeRegisterElement('check-on-click', CheckOnClick)
safeRegisterElement('required-checkbox-group', RequiredCheckboxGroup)
+safeRegisterElement('page-container', PageContainer)
safeRegisterElement('template-builder', class extends HTMLElement {
connectedCallback () {
diff --git a/app/javascript/application.scss b/app/javascript/application.scss
index 61d3f645..1ab92498 100644
--- a/app/javascript/application.scss
+++ b/app/javascript/application.scss
@@ -147,3 +147,11 @@ button[disabled] .enabled {
outline-offset: 3px;
outline-color: hsl(var(--bc) / 0.2);
}
+
+.font-times {
+ font-family: "Times New Roman", Times, ui-serif, serif, Cambria, Georgia;
+}
+
+.font-courier {
+ font-family: "Courier New", Consolas, "Liberation Mono", monospace, ui-monospace, SFMono-Regular, Menlo, Monaco;
+}
diff --git a/app/javascript/elements/page_container.js b/app/javascript/elements/page_container.js
new file mode 100644
index 00000000..d909ae7f
--- /dev/null
+++ b/app/javascript/elements/page_container.js
@@ -0,0 +1,14 @@
+export default class extends HTMLElement {
+ connectedCallback () {
+ this.image.addEventListener('load', (e) => {
+ this.image.setAttribute('width', e.target.naturalWidth)
+ this.image.setAttribute('height', e.target.naturalHeight)
+
+ this.style.aspectRatio = `${e.target.naturalWidth} / ${e.target.naturalHeight}`
+ })
+ }
+
+ get image () {
+ return this.querySelector('img')
+ }
+}
diff --git a/app/javascript/form.js b/app/javascript/form.js
index 45b3b3d2..ac49174d 100644
--- a/app/javascript/form.js
+++ b/app/javascript/form.js
@@ -5,6 +5,7 @@ import DownloadButton from './elements/download_button'
import ToggleSubmit from './elements/toggle_submit'
import FetchForm from './elements/fetch_form'
import ScrollButtons from './elements/scroll_buttons'
+import PageContainer from './elements/page_container'
const safeRegisterElement = (name, element, options = {}) => !window.customElements.get(name) && window.customElements.define(name, element, options)
@@ -12,6 +13,7 @@ safeRegisterElement('download-button', DownloadButton)
safeRegisterElement('toggle-submit', ToggleSubmit)
safeRegisterElement('fetch-form', FetchForm)
safeRegisterElement('scroll-buttons', ScrollButtons)
+safeRegisterElement('page-container', PageContainer)
safeRegisterElement('submission-form', class extends HTMLElement {
connectedCallback () {
this.appElem = document.createElement('div')
diff --git a/app/javascript/form.scss b/app/javascript/form.scss
index fb651155..f0d26baf 100644
--- a/app/javascript/form.scss
+++ b/app/javascript/form.scss
@@ -70,3 +70,11 @@ button[disabled] .enabled {
.base-radio {
@apply radio bg-white radio-sm;
}
+
+.font-times {
+ font-family: "Times New Roman", Times, ui-serif, serif, Cambria, Georgia;
+}
+
+.font-courier {
+ font-family: "Courier New", Consolas, "Liberation Mono", monospace, ui-monospace, SFMono-Regular, Menlo, Monaco;
+}
diff --git a/app/javascript/submission_form/area.vue b/app/javascript/submission_form/area.vue
index 5aed2a7a..bc5c255b 100644
--- a/app/javascript/submission_form/area.vue
+++ b/app/javascript/submission_form/area.vue
@@ -2,8 +2,8 @@
{
if (['date', 'text', 'number'].includes(this.field.type) && this.$refs.textContainer && (this.textOverflowChars === 0 || (this.textOverflowChars - 4) > `${this.modelValue}`.length)) {
- this.textOverflowChars = this.$refs.textContainer.scrollHeight > this.$refs.textContainer.clientHeight ? `${this.modelValue || (this.withFieldPlaceholder ? this.field.name : '')}`.length : 0
+ this.textOverflowChars = this.$refs.textContainer.scrollHeight > (this.$refs.textContainer.clientHeight + 1) ? `${this.modelValue || (this.withFieldPlaceholder ? this.field.name : '')}`.length : 0
}
})
}
@@ -464,7 +495,7 @@ export default {
mounted () {
this.$nextTick(() => {
if (['date', 'text', 'number'].includes(this.field.type) && this.$refs.textContainer) {
- this.textOverflowChars = this.$refs.textContainer.scrollHeight > this.$refs.textContainer.clientHeight ? `${this.modelValue || (this.withFieldPlaceholder ? this.field.name : '')}`.length : 0
+ this.textOverflowChars = this.$refs.textContainer.scrollHeight > (this.$refs.textContainer.clientHeight + 1) ? `${this.modelValue || (this.withFieldPlaceholder ? this.field.name : '')}`.length : 0
}
})
},
diff --git a/app/javascript/submission_form/areas.vue b/app/javascript/submission_form/areas.vue
index 67ac0bdd..e14087ec 100644
--- a/app/javascript/submission_form/areas.vue
+++ b/app/javascript/submission_form/areas.vue
@@ -23,6 +23,7 @@
:area="area"
:submittable="submittable"
:field-index="fieldIndex"
+ :is-inline-size="isInlineSize"
:scroll-padding="scrollPadding"
:submitter="submitter"
:with-field-placeholder="withFieldPlaceholder"
@@ -110,6 +111,9 @@ export default {
}
},
computed: {
+ isInlineSize () {
+ return CSS.supports('container-type: size')
+ },
isMobileContainer () {
const root = this.$root.$el.parentNode.getRootNode()
const container = root.body || root.querySelector('div')
diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue
index 358c0396..d9d9e176 100644
--- a/app/javascript/submission_form/form.vue
+++ b/app/javascript/submission_form/form.vue
@@ -67,7 +67,7 @@