Show popout on click or down key

It looks like a select drop-down, so it can behave like one too.
This commit is contained in:
David Cook
2023-11-22 13:20:47 +11:00
parent 735b5789cc
commit 4560e3728c
4 changed files with 78 additions and 4 deletions

View File

@@ -85,10 +85,10 @@
%td.field
= variant_form.text_field :price, 'aria-label': t('admin.products_page.columns.price'), value: number_to_currency(variant.price, unit: '')&.strip # TODO: add a spec to prove that this formatting is necessary. If so, it should be in a shared form helper for currency inputs
= error_message_on variant, :price
%td.field.on-hand__wrapper
%button.on-hand__button
%td.field.on-hand__wrapper{'data-controller': "popout"}
%button.on-hand__button{'data-popout-target': "button"}
= variant.on_demand ? t(:on_demand) : variant.on_hand
%div.on-hand__popout
%div.on-hand__popout{ style: 'display: none;', 'data-popout-target': "dialog"}
.field
= variant_form.number_field :on_hand, 'aria-label': t('admin.products_page.columns.on_hand')
= error_message_on variant, :on_hand

View File

@@ -0,0 +1,26 @@
import { Controller } from "stimulus";
// Allows a form section to "pop out" and show additional options
export default class PopoutController extends Controller {
static targets = ["button", "dialog"];
connect() {
this.first_input = this.dialogTarget.querySelector("input");
// Show when click or down-arrow on button
this.buttonTarget.addEventListener("click", this.show.bind(this));
this.buttonTarget.addEventListener("keydown", this.showIfDownArrow.bind(this));
}
show(e) {
this.dialogTarget.style.display = "block";
this.first_input.focus();
e.preventDefault();
}
showIfDownArrow(e) {
if (e.keyCode == 40) {
this.show(e);
}
}
}

View File

@@ -327,7 +327,6 @@
}
&__popout {
display: none;
position: absolute;
top: -1em;
left: -1em;

View File

@@ -0,0 +1,49 @@
/**
* @jest-environment jsdom
*/
import { Application } from "stimulus";
import popout_controller from "../../../app/webpacker/controllers/popout_controller";
describe("PopoutController", () => {
beforeAll(() => {
const application = Application.start();
application.register("popout", popout_controller);
});
beforeEach(() => {
document.body.innerHTML = `
<div data-controller="popout">
<button id="button" data-popout-target="button">On demand</button>
<div id="dialog" data-popout-target="dialog" style="display: none;">
<input id="input1">
<input id="input2">
</div>
</div>
`;
const button = document.getElementById("button");
const input1 = document.getElementById("input1");
const input2 = document.getElementById("input2");
});
describe("Show", () => {
it("shows the dialog on click", () => {
button.click();
expect(dialog.style.display).toBe("block"); // visible
});
it("shows the dialog on keyboard down arrow", () => {
button.dispatchEvent(new KeyboardEvent("keydown", { keyCode: 40 }));
expect(dialog.style.display).toBe("block"); // visible
});
it("doesn't show the dialog on other key press (tab)", () => {
button.dispatchEvent(new KeyboardEvent("keydown", { keyCode: 9 }));
expect(dialog.style.display).toBe("none"); // not visible
});
});
});