mirror of
https://0xacab.org/sutty/sutty
synced 2024-05-15 22:10:48 +00:00
Compare commits
8 commits
bf52d0de59
...
13df36d0c9
Author | SHA1 | Date | |
---|---|---|---|
13df36d0c9 | |||
92e7ecada0 | |||
044b14c355 | |||
7d5a8f8d48 | |||
14c5530b50 | |||
fauno | 0ca6689b53 | ||
11660bc688 | |||
58ee39828a |
106
app/javascript/controllers/dropdown_controller.js
Normal file
106
app/javascript/controllers/dropdown_controller.js
Normal file
|
@ -0,0 +1,106 @@
|
|||
import { Controller } from "stimulus";
|
||||
|
||||
// https://getbootstrap.com/docs/4.6/components/dropdowns/#single-button
|
||||
export default class extends Controller {
|
||||
static targets = ["dropdown", "button", "item"];
|
||||
|
||||
// Al iniciar el controlador
|
||||
connect() {
|
||||
// Llevar la cuenta del item con foco
|
||||
this.data.set("item", -1);
|
||||
|
||||
// Gestionar las teclas
|
||||
this.keydownEvent = this.keydown.bind(this);
|
||||
this.element.addEventListener("keydown", this.keydownEvent);
|
||||
|
||||
// Gestionar el foco
|
||||
this.focusinEvent = this.focusin.bind(this);
|
||||
}
|
||||
|
||||
// Al eliminar el controlador (al pasar a otra página)
|
||||
disconnect() {
|
||||
// Eliminar la gestión de teclas
|
||||
this.element.removeEventListener("keydown", this.keydownEvent);
|
||||
// Eliminar la gestión del foco
|
||||
document.removeEventListener("focusin", this.focusinEvent);
|
||||
}
|
||||
|
||||
// Mostrar u ocultar
|
||||
toggle(event) {
|
||||
(this.buttonTarget.ariaExpanded === "false") ? this.show() : this.hide();
|
||||
}
|
||||
|
||||
// Mostrar
|
||||
show() {
|
||||
this.buttonTarget.ariaExpanded = "true";
|
||||
this.element.classList.add("show");
|
||||
this.dropdownTarget.classList.add("show");
|
||||
|
||||
// Activar la gestión del foco
|
||||
document.addEventListener("focusin", this.focusinEvent);
|
||||
}
|
||||
|
||||
// Ocultar
|
||||
hide() {
|
||||
this.buttonTarget.ariaExpanded = "false";
|
||||
this.element.classList.remove("show");
|
||||
this.dropdownTarget.classList.remove("show");
|
||||
// Volver al inicio el foco de items
|
||||
this.data.set("item", -1);
|
||||
|
||||
// Desactivar la gestión del foco
|
||||
document.removeEventListener("focusin", this.focusinEvent);
|
||||
}
|
||||
|
||||
// Gestionar el foco
|
||||
focusin(event) {
|
||||
const item = this.itemTargets.find(x => x === event.target);
|
||||
|
||||
// Si el foco se coloca sobre elementos del controlador, no hacer
|
||||
// nada
|
||||
if (event.target === this.buttonTarget || item) {
|
||||
// Si es un item, el comportamiento de las flechas verticales y el
|
||||
// Tab tiene que ser igual
|
||||
if (item) this.data.set("item", this.itemTargets.indexOf(item));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// De lo contrario, ocultar
|
||||
this.hide();
|
||||
}
|
||||
|
||||
// Gestionar las teclas
|
||||
keydown(event) {
|
||||
const initial = parseInt(this.data.get("item"));
|
||||
let item = initial;
|
||||
|
||||
switch (event.keyCode) {
|
||||
case 27:
|
||||
// Esc cierra el menú y devuelve el foco
|
||||
this.hide();
|
||||
this.buttonTarget.focus();
|
||||
break;
|
||||
case 38:
|
||||
// Moverse hacia arriba con tope en el primer item
|
||||
if (item > -1) item--;
|
||||
|
||||
break;
|
||||
case 40:
|
||||
// Moverse hacia abajo con tope en el último ítem, si el
|
||||
// dropdown estaba cerrado, abrirlo.
|
||||
if (item === -1) this.show();
|
||||
if (item <= this.itemTargets.length) item++;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Si cambió la posición del ítem, darle foco y actualizar el
|
||||
// contador.
|
||||
if (initial !== item) {
|
||||
this.itemTargets[item]?.focus();
|
||||
|
||||
this.data.set("item", item);
|
||||
}
|
||||
}
|
||||
}
|
34
app/views/components/_dropdown.haml
Normal file
34
app/views/components/_dropdown.haml
Normal file
|
@ -0,0 +1,34 @@
|
|||
-#
|
||||
@param :text [String] Contenido del botón
|
||||
@param :button_classes [Array] Clases para el botón
|
||||
@param :dropdown_classes [Array] Clases para el listado
|
||||
@yield Un bloque que renderiza components/dropdown_item
|
||||
- button_classes = local_assigns[:button_classes]&.join(' ')
|
||||
- dropdown_classes = local_assigns[:dropdown_classes]&.join(' ')
|
||||
|
||||
.btn-group{
|
||||
data: {
|
||||
controller: 'dropdown'
|
||||
}
|
||||
}
|
||||
%button.btn.dropdown-toggle{
|
||||
type: 'button',
|
||||
class: button_classes,
|
||||
data: {
|
||||
toggle: 'true',
|
||||
display: 'static',
|
||||
action: 'dropdown#toggle',
|
||||
target: 'dropdown.button'
|
||||
},
|
||||
aria: {
|
||||
expanded: 'false'
|
||||
}
|
||||
}
|
||||
= text
|
||||
.dropdown-menu{
|
||||
class: dropdown_classes,
|
||||
data: {
|
||||
target: 'dropdown.dropdown'
|
||||
}
|
||||
}
|
||||
= yield
|
4
app/views/components/_dropdown_item.haml
Normal file
4
app/views/components/_dropdown_item.haml
Normal file
|
@ -0,0 +1,4 @@
|
|||
-#
|
||||
@param :text [String] Contenido del link
|
||||
@param :path [String] Link
|
||||
= link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' }
|
|
@ -1,5 +1,6 @@
|
|||
.form-group
|
||||
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
||||
.label
|
||||
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
||||
- if metadata.static_file
|
||||
- case metadata.static_file.blob.content_type
|
||||
- when %r{\Avideo/}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.form-group
|
||||
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
||||
.label
|
||||
= label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post)
|
||||
- if metadata.static_file
|
||||
= image_tag url_for(metadata.static_file),
|
||||
alt: metadata.value['description'],
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"@rails/activestorage": "^6.1.3-1",
|
||||
"@rails/ujs": "^6.1.3-1",
|
||||
"@rails/webpacker": "5.4.4",
|
||||
"@suttyweb/editor": "^0.1.25",
|
||||
"@suttyweb/editor": "^0.1.27",
|
||||
"babel-loader": "^8.2.2",
|
||||
"chart.js": "^3.5.1",
|
||||
"chartkick": "^4.0.5",
|
||||
|
|
35
yarn.lock
35
yarn.lock
|
@ -1821,6 +1821,26 @@
|
|||
resolved "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz"
|
||||
integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==
|
||||
|
||||
"@floating-ui/core@^1.0.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1"
|
||||
integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==
|
||||
dependencies:
|
||||
"@floating-ui/utils" "^0.2.1"
|
||||
|
||||
"@floating-ui/dom@^1.5.1":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef"
|
||||
integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==
|
||||
dependencies:
|
||||
"@floating-ui/core" "^1.0.0"
|
||||
"@floating-ui/utils" "^0.2.0"
|
||||
|
||||
"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2"
|
||||
integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==
|
||||
|
||||
"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
|
||||
|
@ -1955,11 +1975,13 @@
|
|||
resolved "https://registry.npmjs.org/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz"
|
||||
integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A==
|
||||
|
||||
"@suttyweb/editor@^0.1.25":
|
||||
version "0.1.25"
|
||||
resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.25.tgz#37b38560642a49b24383473543c28be943695f9f"
|
||||
integrity sha512-fxOO9LpdntWzgNZch4cZB6QL0u+jEw0NqsNahKcGBbiJaS0GNGLRrT2LUd/Djc6O8HWkQguPLcquVT5eHq2h9g==
|
||||
"@suttyweb/editor@^0.1.27":
|
||||
version "0.1.27"
|
||||
resolved "https://registry.yarnpkg.com/@suttyweb/editor/-/editor-0.1.27.tgz#9415a0b767e72dbe4fbf42ce87e62fb8f5125c31"
|
||||
integrity sha512-Ts9TZtGiRIaHm+ffVBRl+/nuVcANWZNtFsrGacoajgEsagaIyA1cq8qjiNpPoM5ne9vTba3cAaLP04V/uEIhBw==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "^1.5.1"
|
||||
linkifyjs "^4.1.1"
|
||||
prosemirror-svelte-nodeview "^1.0.2"
|
||||
|
||||
"@types/caseless@*":
|
||||
|
@ -5190,6 +5212,11 @@ linkify-it@^2.0.0:
|
|||
dependencies:
|
||||
uc.micro "^1.0.1"
|
||||
|
||||
linkifyjs@^4.1.1:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.3.tgz#0edbc346428a7390a23ea2e5939f76112c9ae07f"
|
||||
integrity sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==
|
||||
|
||||
loader-runner@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz"
|
||||
|
|
Loading…
Reference in a new issue