Skip to content

Commit

Permalink
Merge pull request #15112 from craftcms/feature/cms-704-elementeditor…
Browse files Browse the repository at this point in the history
…-powered-live-preview

ElementEditor-powered Live Preview
  • Loading branch information
brandonkelly authored Jun 3, 2024
2 parents 340a67e + 4663f35 commit 5b901b5
Show file tree
Hide file tree
Showing 14 changed files with 808 additions and 544 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Release Notes for Craft CMS 5.2 (WIP)

### Content Management
- Live Preview now supports tabs, UI elements, and tab/field conditions. ([#15112](https://github.com/craftcms/cms/pull/15112))
- Live Preview now has a dedicated “Save” button. ([#15112](https://github.com/craftcms/cms/pull/15112))
- It’s now possible to edit assets’ alternative text from the Assets index page. ([#14893](https://github.com/craftcms/cms/discussions/14893))
- Double-clicking anywhere within a table row on an element index page will now open the element’s editor slideout. ([#14379](https://github.com/craftcms/cms/discussions/14379))
- Element index checkboxes no longer have a lag when deselected, except within element selection modals. ([#14896](https://github.com/craftcms/cms/issues/14896))
Expand Down
34 changes: 29 additions & 5 deletions src/controllers/ElementsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class ElementsController extends Controller
private bool $_addAnother;
private array $_visibleLayoutElements;
private ?string $_selectedTab = null;
private bool $_applyParams;
private bool $_prevalidate;

/**
Expand Down Expand Up @@ -125,6 +126,7 @@ public function beforeAction($action): bool
$this->_addAnother = (bool)$this->_param('addAnother');
$this->_visibleLayoutElements = $this->_param('visibleLayoutElements') ?? [];
$this->_selectedTab = $this->_param('selectedTab');
$this->_applyParams = (bool)$this->_param('applyParams', true);
$this->_prevalidate = (bool)$this->_param('prevalidate');

unset($this->_attributes['failMessage']);
Expand Down Expand Up @@ -842,7 +844,6 @@ private function _additionalButtons(
],
]) .
Html::tag('span', Craft::t('app', 'Preview'), ['class' => 'label']) .
Html::tag('span', options: ['class' => ['spinner', 'spinner-absolute']]) .
Html::endTag('button')
: '') .
Html::endTag('div');
Expand Down Expand Up @@ -967,11 +968,24 @@ private function _prepareEditor(
$behavior->contentHtml($contentHtml);
$behavior->metaSidebarHtml($sidebarHtml);

$this->view->registerJsWithVars(fn($settingsJs) => <<<JS
new Craft.ElementEditor($('#$containerId'), $settingsJs);
$settings = $jsSettingsFn($form);

$isSlideout = Craft::$app->getRequest()->getHeaders()->has('X-Craft-Container-Id');
if ($isSlideout) {
$this->view->registerJsWithVars(fn($settings) => <<<JS
$('#$containerId').data('elementEditorSettings', $settings);
JS, [
$jsSettingsFn($form),
]);
$settings,
]);
} else {
$this->view->registerJsWithVars(fn($settings) => <<<JS
new Craft.ElementEditor($('#$containerId'), $settings);
JS, [
$settings,
]);
}



// Give the element a chance to do things here too
$element->prepareEditScreen($response, $containerId);
Expand Down Expand Up @@ -1857,6 +1871,12 @@ public function actionUpdateFieldLayout(): ?Response
$element = $this->_createElement();
}

// Prevalidate?
if ($this->_prevalidate && $element->enabled && $element->getEnabledForSite()) {
$element->setScenario(Element::SCENARIO_LIVE);
$element->validate();
}

/** @var Element|DraftBehavior|null $element */
if (!$element || $element->getIsRevision()) {
throw new BadRequestHttpException('No element was identified by the request.');
Expand Down Expand Up @@ -2229,6 +2249,10 @@ private function _validateElementType(string $elementType): void
*/
private function _applyParamsToElement(ElementInterface $element): void
{
if (!$this->_applyParams) {
return;
}

if (isset($this->_enabledForSite)) {
if (is_array($this->_enabledForSite)) {
// Make sure they are allowed to edit all of the posted site IDs
Expand Down
36 changes: 19 additions & 17 deletions src/templates/_includes/forms/customSelect.twig
Original file line number Diff line number Diff line change
Expand Up @@ -94,23 +94,25 @@
const menubtn = $button
.menubtn()
.data('menubtn');
menubtn
.on('optionSelect', (ev) => {
const $option = $(ev.option);
const $icon = $option.find('.icon');
const $label = $option.find('.label');
let labelHtml = '';
if ($icon.length) {
labelHtml += $icon.clone().removeClass('icon').addClass('cp-icon').prop('outerHTML');
}
labelHtml += `<div class="label">${$label.html()}</div>`;
$buttonFlex.html(labelHtml);
$input.val($option.data('value'));
menubtn.menu.$options.removeClass('sel');
$option.addClass('sel');
$container.data('value', $option.data('value'));
$container.trigger('change');
});
if (menubtn) {
menubtn
.on('optionSelect', (ev) => {
const $option = $(ev.option);
const $icon = $option.find('.icon');
const $label = $option.find('.label');
let labelHtml = '';
if ($icon.length) {
labelHtml += $icon.clone().removeClass('icon').addClass('cp-icon').prop('outerHTML');
}
labelHtml += `<div class="label">${$label.html()}</div>`;
$buttonFlex.html(labelHtml);
$input.val($option.data('value'));
menubtn.menu.$options.removeClass('sel');
$option.addClass('sel');
$container.data('value', $option.data('value'));
$container.trigger('change');
});
}
})();
{% endjs %}
{% endif %}
2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/cp.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/css/cp.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/cp/dist/css/cp.css.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/web/assets/cp/src/css/_cp.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,7 @@ li.breadcrumb-toggle-wrapper {
#content :not(.meta) > .flex-fields,
#content > .flex-fields,
.so-content .flex-fields,
.lp-content .flex-fields,
.draghelper .flex-fields {
--row-gap: var(--xl);
display: flex;
Expand Down Expand Up @@ -1833,6 +1834,7 @@ li.breadcrumb-toggle-wrapper {
}

.so-content .flex-fields,
.lp-content .flex-fields,
.draghelper.drag-in-slideout .flex-fields {
& > :not(h2):not(hr):not(.line-break) {
&,
Expand Down
79 changes: 67 additions & 12 deletions src/web/assets/cp/src/css/_preview.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
z-index: 100;

& > header {
padding: 5px 24px;
padding: 5px var(--pane-padding, var(--xl));
background-color: var(--gray-100);
box-shadow: 0 1px 0 transparentize($grey700, 0.8);
box-sizing: border-box;
position: relative;
z-index: 1;
height: 44px;

@supports (backdrop-filter: blur(10px)) {
& {
Expand All @@ -27,7 +28,7 @@
background-color: transparentize($grey100, 0.25);
backdrop-filter: blur(10px);

& + .lp-editor {
& + .lp-content {
padding-top: #{44 + 24}px;
}
}
Expand All @@ -38,31 +39,77 @@
.checkmark-icon {
margin-bottom: 0;
}

.btn[data-icon='xmark'] {
margin-inline-start: calc(-12rem / 16);
margin-inline-end: calc(var(--s) * -1);
&:not(:hover):not(:active):not([aria-expanded='true']) {
background-color: transparent;
}
}

.lp-toolbar {
min-width: 0;
margin-inline-end: -1rem;

.pane-tabs {
margin-inline: 0 !important;

[role='tablist'] {
padding: 0 12px;

&.scrollable {
mask-image: linear-gradient(
to right,
rgba(0, 0, 0, 0),
rgba(0, 0, 0) 12px,
rgba(0, 0, 0) calc(100% - 12px),
rgba(0, 0, 0, 0) 100%
);
}

[role='tab'] {
background-color: transparent;
}
}

.menubtn:not(.action-btn) {
--focus-ring: var(--inner-focus-ring);
margin-inline: 0;

&:not(:empty):not(.btn-empty)::after {
margin-inline-start: 0;
}
}
}
}
}
}

.lp-editor-container {
display: flex;
flex-direction: column;

.lp-editor {
.lp-content {
flex: 1;
padding: 24px;
padding: var(--pane-padding, var(--xl));
overflow: auto;
box-sizing: border-box;
position: relative;

& > .field {
&:last-child {
margin-bottom: 24px !important;
}
&:not(.loading) > .spinner {
display: none;
}

& > .status-badge {
@include left(-24px);
}
&.loading > .spinner {
position: absolute;
inset-block-start: calc(50% - 17px);
inset-inline-start: calc(50% - 12px);
color: var(--ui-control-color);
}

.matrixblock > .fields > .flex-fields > .field > .status-badge {
@include left(calc(var(--m) * -1));
inset-inline-start: calc(var(--m) * -1);
}
}

Expand All @@ -75,6 +122,14 @@
height: 100%;
cursor: col-resize;
}

& > footer {
padding: 5px var(--pane-padding, var(--xl));
box-shadow: inset 0 1px 0 var(--hairline-color);
background-color: var(--gray-100);
justify-content: end;
height: 44px;
}
}

.lp-preview-container {
Expand Down
Loading

0 comments on commit 5b901b5

Please sign in to comment.