diff --git a/src/js/data.js b/src/js/data.js index fef877b71..4b1f0f06b 100644 --- a/src/js/data.js +++ b/src/js/data.js @@ -13,7 +13,6 @@ export class Data { constructor(formID) { this.formData = {} this.formID = formID - this.layout = '' instanceData[formID] = this } } diff --git a/src/js/form-builder.js b/src/js/form-builder.js index 34a423a54..a0eba09c8 100644 --- a/src/js/form-builder.js +++ b/src/js/form-builder.js @@ -81,8 +81,7 @@ function FormBuilder(opts, element, $) { const h = new Helpers(formID, layoutEngine, formBuilder) const m = markup opts = h.processOptions(opts) - data.layout = h.editorLayout(opts.controlPosition) - h.editorUI(formID) + h.editorUI(formID, opts.controlPosition) data.formID = formID data.lastID = `${data.formID}-fld-0` const controls = new Controls(opts, d) @@ -205,9 +204,29 @@ function FormBuilder(opts, element, $) { $('
').appendTo($editorWrap) + // If option set, controls will remain in view in editor + let cbClasses = 'cb-wrap' + let cbStyle = '' + if (opts.stickyControls.enable) { + cbClasses += ' sticky-controls' + const offsetDefaults = { + top: 0, + bottom: 'auto', + right: 'auto', + left: 'auto', + } + + const offset = Object.assign({}, offsetDefaults, config.opts.stickyControls.offset) + + if (offset.top !== 0) { + cbStyle = `top: ${offset.top}px` + } + } + const cbWrap = m('div', d.controls, { id: `${data.formID}-cb-wrap`, - className: `cb-wrap ${data.layout.controls}`, + className: cbClasses, + style: cbStyle, }) if (opts.showActionButtons) { @@ -1312,6 +1331,7 @@ function FormBuilder(opts, element, $) { cursor: 'move', opacity: 0.9, revert: 150, + distance: 3, tolerance: 'pointer', helper: function (e, el) { //Shrink the control a little while dragging so it's not in the way as much @@ -2465,10 +2485,6 @@ function FormBuilder(opts, element, $) { // Ensure style has loaded const onRenderTimeout = setTimeout(() => { d.stage.style.minHeight = `${d.controls.clientHeight}px` - // If option set, controls will remain in view in editor - if (opts.stickyControls.enable) { - h.stickyControls($stage) - } clearTimeout(onRenderTimeout) }, 0) }) diff --git a/src/js/helpers.js b/src/js/helpers.js index c135ae2b9..5228c23fd 100644 --- a/src/js/helpers.js +++ b/src/js/helpers.js @@ -537,26 +537,6 @@ export default class Helpers { } } - /** - * Returns the layout data based on controlPosition option - * @param {string} controlPosition 'left' or 'right' - * @return {Object} layout object - */ - editorLayout(controlPosition) { - const layoutMap = { - left: { - stage: 'pull-right', - controls: 'pull-left', - }, - right: { - stage: 'pull-left', - controls: 'pull-right', - }, - } - - return layoutMap[controlPosition] || '' - } - /** * Adds overlay to the page. Used for modals. * @return {HTMLElement} DOM Object @@ -959,59 +939,6 @@ export default class Helpers { return property ? style[property] : style } - /** - * Controls follow scroll to the bottom of the editor - */ - stickyControls() { - const config = this.config - const { controls, stage } = this.d - const $cbWrap = $(controls).parent() - const cbPosition = controls.getBoundingClientRect() - const { top: stageTop } = stage.getBoundingClientRect() - - $(window).scroll(function (evt) { - const scrollTop = $(evt.target).scrollTop() - const offsetDefaults = { - top: 5, - bottom: 'auto', - right: 'auto', - left: cbPosition.left, - } - - const offset = Object.assign({}, offsetDefaults, config.opts.stickyControls.offset) - - if (scrollTop > stageTop) { - const style = { - position: 'sticky', - } - - const cbStyle = Object.assign(style, offset) - - const cbPosition = controls.getBoundingClientRect() - const stagePosition = stage.getBoundingClientRect() - const cbBottom = cbPosition.top + cbPosition.height - const stageBottom = stagePosition.top + stagePosition.height - const atBottom = cbBottom === stageBottom && cbPosition.top > scrollTop - - if (cbBottom > stageBottom && cbPosition.top !== stagePosition.top) { - $cbWrap.css({ - position: 'absolute', - top: 'auto', - bottom: 0, - right: 0, - left: 'auto', - }) - } - - if (cbBottom < stageBottom || atBottom) { - $cbWrap.css(cbStyle) - } - } else { - controls.parentElement.removeAttribute('style') - } - }) - } - /** * Open a dialog with the form's data */ @@ -1177,20 +1104,23 @@ export default class Helpers { /** * Generate stage and controls dom elements * @param {string} formID + * @param {string} controlPosition */ - editorUI(formID) { + editorUI(formID, controlPosition) { const d = this.d const data = this.data const id = formID || data.formID + const controlPositionClass = (controlPosition || '') === 'left' ? 'controls-left' : 'controls-right' + d.editorWrap = m('div', null, { id: `${data.formID}-form-wrap`, - className: `form-wrap form-builder formbuilder-embedded-bootstrap ${mobileClass()}`, + className: `form-wrap form-builder formbuilder-embedded-bootstrap ${mobileClass()} ${controlPositionClass}`, }) d.stage = m('ul', null, { id, - className: `frmb stage-wrap ${data.layout.stage}`, + className: 'frmb stage-wrap', }) // Create container for controls diff --git a/src/sass/_controls.scss b/src/sass/_controls.scss index 4ccb912d4..cc8b417e2 100644 --- a/src/sass/_controls.scss +++ b/src/sass/_controls.scss @@ -1,11 +1,12 @@ .cb-wrap { width: 26%; + max-width: fit-content; transition: transform 250ms; - &.pull-left { - .form-actions { - float: left; - } + &.sticky-controls { + position: sticky; + align-self: flex-start; + top: 0; } h4 { @@ -20,6 +21,15 @@ display: none; } } + + .form-actions { + float: right; + margin-top: 5px; + + button { + border: 0 none; + } + } } .frmb-control { @@ -138,6 +148,12 @@ } } +@at-root #{selector-append(".controls-left", &)} { + .form-actions { + float: left; + } +} + @at-root #{selector-append(".formbuilder-mobile", &)} { .form-actions { width: 100%; @@ -162,12 +178,3 @@ } } } - -.form-actions { - float: right; - margin-top: 5px; - - button { - border: 0 none; - } -} diff --git a/src/sass/_stage.scss b/src/sass/_stage.scss index 6966b83df..abe31b2c1 100644 --- a/src/sass/_stage.scss +++ b/src/sass/_stage.scss @@ -1,4 +1,5 @@ .stage-wrap { + flex-grow: 1; display: flex; flex-direction: column; position: relative; @@ -174,6 +175,28 @@ } } + &.header-field { + h1, + h2, + h3, + h4, + h5, + h6 { + word-break: break-word; + } + } + + &.paragraph-field { + p { + word-break: break-word; + } + } + + .field-label { + display: block; + overflow-wrap: break-word; + } + &.button-field, &.header-field, &.paragraph-field { diff --git a/src/sass/form-builder.scss b/src/sass/form-builder.scss index e144965c3..189172f12 100644 --- a/src/sass/form-builder.scss +++ b/src/sass/form-builder.scss @@ -18,6 +18,13 @@ @import 'kc-toggle'; position: relative; + display: flex; + flex-direction: row; + + &.controls-left { + flex-direction: row-reverse; + } + &::after { content: ''; display: table; @@ -27,14 +34,6 @@ .cb-wrap, .stage-wrap { vertical-align: top; - - &.pull-right { - float: right; - } - - &.pull-left { - float: left; - } } .form-elements,