UX: Add Styling step to wizard (#14132)

UX: Add Styling step to wizard (#14132)

Refactors three wizard steps (colors, fonts, homepage style) into one new step called Styling.

diff --git a/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js b/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js
index 4819db6..df52f73 100644
--- a/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js
+++ b/app/assets/javascripts/select-kit/addon/components/color-palettes/color-palettes-row.js
@@ -1,6 +1,5 @@
 import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
 import { computed } from "@ember/object";
-import { escapeExpression } from "discourse/lib/utilities";
 import layout from "select-kit/templates/components/color-palettes/color-palettes-row";
 
 export default SelectKitRowComponent.extend({
@@ -10,7 +9,7 @@ export default SelectKitRowComponent.extend({
   palettes: computed("item.colors.[]", function () {
     return (this.item.colors || [])
       .filter((color) => color.name !== "secondary")
-      .map((color) => `#${escapeExpression(color.hex)}`)
+      .map((color) => `#${escape(color.hex)}`)
       .map(
         (hex) => `<span class="palette" style="background-color:${hex}"></span>`
       )
@@ -22,7 +21,7 @@ export default SelectKitRowComponent.extend({
     const secondary = (this.item.colors || []).findBy("name", "secondary");
 
     if (secondary && secondary.hex) {
-      return `background-color:#${escapeExpression(secondary.hex)}`.htmlSafe();
+      return `background-color:#${escape(secondary.hex)}`.htmlSafe();
     } else {
       return "";
     }
diff --git a/app/assets/javascripts/wizard/components/font-preview.js b/app/assets/javascripts/wizard/components/font-preview.js
deleted file mode 100644
index ef2f73f..0000000
--- a/app/assets/javascripts/wizard/components/font-preview.js
+++ /dev/null
@@ -1,127 +0,0 @@
-import {
-  chooseDarker,
-  createPreviewComponent,
-  darkLightDiff,
-} from "wizard/lib/preview";
-import I18n from "I18n";
-import { observes } from "discourse-common/utils/decorators";
-
-const LOREM = `
-Lorem ipsum dolor sit amet, consectetur adipiscing.
-Nullam eget sem non elit tincidunt rhoncus. Fusce
-velit nisl, porttitor sed nisl ac, consectetur interdum
-metus. Fusce in consequat augue, vel facilisis felis.`;
-
-export default createPreviewComponent(659, 320, {
-  logo: null,
-  avatar: null,
-
-  @observes(
-    "step.fieldsById.body_font.value",
-    "step.fieldsById.heading_font.value"
-  )
-  fontChanged() {
-    this.triggerRepaint();
-  },
-
-  images() {
-    return {
-      logo: this.wizard.getLogoUrl(),
-      avatar: "/images/wizard/trout.png",
-    };
-  },
-
-  paint({ ctx, colors, font, headingFont, width, height }) {
-    const headerHeight = height * 0.3;
-
-    if (this.logo) {
-      this.drawFullHeader(colors, headingFont, this.logo);
-    }
-
-    const margin = 20;
-    const avatarSize = height * 0.2;
-    const lineHeight = height / 11;
-
-    // Draw a fake topic
-    this.scaleImage(
-      this.avatar,
-      margin,
-      headerHeight + height * 0.11,
-      avatarSize,
-      avatarSize
-    );
-
-    const titleFontSize = headerHeight / 55;
-
-    ctx.beginPath();
-    ctx.fillStyle = colors.primary;
-    ctx.font = `bold ${titleFontSize}em '${headingFont}'`;
-    ctx.fillText(I18n.t("wizard.previews.topic_title"), margin, height * 0.3);
-
-    const bodyFontSize = height / 330.0;
-    ctx.font = `${bodyFontSize}em '${font}'`;
-
-    let line = 0;
-    const lines = LOREM.split("\n");
-    for (let i = 0; i < 5; i++) {
-      line = height * 0.35 + i * lineHeight;
-      ctx.fillText(lines[i], margin + avatarSize + margin, line);
-    }
-
-    // Share Button
-    const shareButtonWidth = I18n.t("wizard.previews.share_button").length * 11;
-
-    ctx.beginPath();
-    ctx.rect(margin, line + lineHeight, shareButtonWidth, height * 0.1);
-    ctx.fillStyle = darkLightDiff(colors.primary, colors.secondary, 90, 65);
-    ctx.fill();
-    ctx.fillStyle = chooseDarker(colors.primary, colors.secondary);
-    ctx.font = `${bodyFontSize}em '${font}'`;
-    ctx.fillText(
-      I18n.t("wizard.previews.share_button"),
-      margin + 10,
-      line + lineHeight * 1.7
-    );
-
-    // Reply Button
-    const replyButtonWidth = I18n.t("wizard.previews.reply_button").length * 11;
-
-    ctx.beginPath();
-    ctx.rect(
-      shareButtonWidth + margin + 10,
-      line + lineHeight,
-      replyButtonWidth,
-      height * 0.1
-    );
-    ctx.fillStyle = colors.tertiary;
-    ctx.fill();
-    ctx.fillStyle = colors.secondary;
-    ctx.font = `${bodyFontSize}em '${font}'`;
-    ctx.fillText(
-      I18n.t("wizard.previews.reply_button"),
-      shareButtonWidth + margin + 20,
-      line + lineHeight * 1.7
-    );
-
-    // Draw Timeline
-    const timelineX = width * 0.86;
-    ctx.beginPath();
-    ctx.strokeStyle = colors.tertiary;
-    ctx.lineWidth = 0.5;
-    ctx.moveTo(timelineX, height * 0.3);
-    ctx.lineTo(timelineX, height * 0.7);
-    ctx.stroke();
-
-    // Timeline
-    ctx.beginPath();
-    ctx.strokeStyle = colors.tertiary;
-    ctx.lineWidth = 2;
-    ctx.moveTo(timelineX, height * 0.3);
-    ctx.lineTo(timelineX, height * 0.4);
-    ctx.stroke();
-
-    ctx.font = `Bold ${bodyFontSize}em ${font}`;
-    ctx.fillStyle = colors.primary;
-    ctx.fillText("1 / 20", timelineX + margin, height * 0.3 + margin * 1.5);
-  },
-});
diff --git a/app/assets/javascripts/wizard/components/homepage-preview.js b/app/assets/javascripts/wizard/components/homepage-preview.js
index 0e61f60..b080007 100644
--- a/app/assets/javascripts/wizard/components/homepage-preview.js
+++ b/app/assets/javascripts/wizard/components/homepage-preview.js
@@ -3,14 +3,14 @@ import {
   createPreviewComponent,
   darkLightDiff,
 } from "wizard/lib/preview";
-import { observes } from "discourse-common/utils/decorators";
 
 export default createPreviewComponent(659, 320, {
   logo: null,
   avatar: null,
 
-  @observes("step.fieldsById.homepage_style.value")
-  styleChanged() {
+  didUpdateAttrs() {
+    this._super(...arguments);
+
     this.triggerRepaint();
   },
 
@@ -22,7 +22,9 @@ export default createPreviewComponent(659, 320, {
   },
 
   paint({ ctx, colors, font, width, height }) {
-    this.drawFullHeader(colors, font, this.logo);
+    if (this.logo) {
+      this.drawFullHeader(colors, font, this.logo);
+    }
 
     if (this.get("step.fieldsById.homepage_style.value") === "latest") {
       this.drawPills(colors, font, height * 0.15);
diff --git a/app/assets/javascripts/wizard/components/styling-preview.js b/app/assets/javascripts/wizard/components/styling-preview.js
new file mode 100644
index 0000000..a45d1ef
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/styling-preview.js
@@ -0,0 +1,190 @@
+import {
+  chooseDarker,
+  createPreviewComponent,
+  darkLightDiff,
+} from "wizard/lib/preview";
+import I18n from "I18n";
+import { observes } from "discourse-common/utils/decorators";
+
+const LOREM = `
+Lorem ipsum dolor sit amet, consectetur adipiscing.
+Nullam eget sem non elit tincidunt rhoncus. Fusce
+velit nisl, porttitor sed nisl ac, consectetur interdum
+metus. Fusce in consequat augue, vel facilisis felis.`;
+
+export default createPreviewComponent(659, 320, {
+  logo: null,
+  avatar: null,
+  previewTopic: true,
+  draggingActive: false,
+  startX: 0,
+  scrollLeft: 0,
+
+  mouseDown(e) {
+    const slider = this.element.querySelector(".previews");
+    this.setProperties({
+      draggingActive: true,
+      startX: e.pageX - slider.offsetLeft,
+      scrollLeft: slider.scrollLeft,
+    });
+  },
+
+  mouseLeave() {
+    this.set("draggingActive", false);
+  },
+
+  mouseUp() {
+    this.set("draggingActive", false);
+  },
+
+  mouseMove(e) {
+    if (!this.draggingActive) {
+      return;
+    }
+    e.preventDefault();
+
+    const slider = this.element.querySelector(".previews"),
+      x = e.pageX - slider.offsetLeft,
+      walk = (x - this.startX) * 1.5;
+
+    slider.scrollLeft = this.scrollLeft - walk;
+

[... diff too long, it was truncated ...]

GitHub sha: 85b8fea26210dbb1af3ebb8e3efdb48957da8586

This commit appears in #14132 which was approved by eviltrout. It was merged by pmusaraj.