Sign In

@erplora/outfitkit

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@erplora/outfitkit - npm Package Compare versions

Comparing version
0.1.33
to
0.1.34
+11
-0
dist/components/ok-file-manager/ok-file-manager.d.ts

@@ -14,2 +14,4 @@ import { LitElement } from 'lit';

children?: OkFmFolder[];
/** Solo lectura (carpeta reservada del hub o de un módulo): no se arrastra ni recibe drops. */
readOnly?: boolean;
}

@@ -132,3 +134,5 @@ /** Archivo del contenido de la carpeta actual. Lo aporta el host vía `.files`. */

private dragging;
private dropTarget;
private seeded;
private static readonly MOVE_MIME;
private fileInput;

@@ -154,5 +158,12 @@ private searchTimer?;

private toggle;
private isMoveDrag;
private onItemDragStart;
private onDragOver;
private onDragLeave;
private onDrop;
private onFolderDragOver;
private onFolderDragLeave;
private onFolderDrop;
/** Decodifica el payload de movimiento del evento y emite `ok-move` hacia `to`. */
private emitMoveIfAny;
private extOf;

@@ -159,0 +170,0 @@ private variant;

+110
-27

@@ -30,3 +30,3 @@ import { LitElement, css, html } from "lit";

};
class OkFileManager extends LitElement {
const _OkFileManager = class _OkFileManager2 extends LitElement {
constructor() {

@@ -46,2 +46,3 @@ super(...arguments);

this.dragging = false;
this.dropTarget = null;
this.seeded = false;

@@ -145,2 +146,8 @@ }

}
/* Carpeta que recibe un drop mientras se arrastra sobre ella. */
.trow.drop {
background: color-mix(in srgb, var(--brand) 10%, transparent);
outline: 2px dashed var(--brand);
outline-offset: -2px;
}
.caret {

@@ -665,2 +672,5 @@ flex: 0 0 auto;

}
static {
this.MOVE_MIME = "application/x-ok-file-manager-move";
}
// Siembra: expande todas las carpetas con hijos la primera vez.

@@ -737,20 +747,76 @@ seedExpanded(folders) {

}
// ---- Drag & drop sobre el main ----
// ---- Drag & drop ----
//
// Hay DOS flujos:
// 1. Subida: arrastrar ficheros del SO sobre el área main → `ok-upload`.
// 2. Reubicación: arrastrar un fichero o carpeta del gestor a otra carpeta (o a la raíz) →
// `ok-move`. Las carpetas de solo lectura nunca se arrastran ni reciben drops; el backend
// revalida, así que esto es solo UX (evita ofrecer un movimiento que dará 403).
isMoveDrag(e) {
return !!e.dataTransfer?.types.includes(_OkFileManager2.MOVE_MIME);
}
// Comienza a arrastrar un fichero o carpeta del gestor. Las carpetas readOnly no se arrastran:
// el atributo `draggable` de su fila lo impide, pero esto es un cinturón extra.
onItemDragStart(e, id, kind) {
if (!e.dataTransfer) return;
e.dataTransfer.setData(_OkFileManager2.MOVE_MIME, JSON.stringify({ id, kind }));
e.dataTransfer.effectAllowed = "move";
}
// Soltar sobre el área main equivale a soltar en la raíz (`''`).
onDragOver(e) {
if (!this.uploadable) return;
e.preventDefault();
this.dragging = true;
const externalFiles = !!e.dataTransfer?.types.includes("Files");
if (externalFiles) {
if (!this.uploadable || !this.can("upload")) return;
e.preventDefault();
this.dragging = true;
return;
}
if (this.isMoveDrag(e)) {
e.preventDefault();
this.dragging = true;
}
}
onDragLeave(e) {
if (!this.uploadable) return;
e.preventDefault();
this.dragging = false;
if (!e.currentTarget.contains(e.relatedTarget)) {
this.dragging = false;
}
}
onDrop(e) {
if (!this.uploadable) return;
e.preventDefault();
this.dragging = false;
const files = e.dataTransfer?.files ? Array.from(e.dataTransfer.files) : [];
if (files.length) this.emit("ok-upload", { files });
if (files.length) {
if (this.uploadable && this.can("upload")) this.emit("ok-upload", { files });
return;
}
this.emitMoveIfAny(e, "");
}
// ---- Drag & drop sobre filas de carpeta del árbol ----
onFolderDragOver(e, folder) {
if (!this.isMoveDrag(e)) return;
if (folder.readOnly) return;
e.preventDefault();
this.dropTarget = folder.id;
e.dataTransfer.dropEffect = "move";
}
onFolderDragLeave(folder) {
if (this.dropTarget === folder.id) this.dropTarget = null;
}
onFolderDrop(e, folder) {
if (!this.isMoveDrag(e) || folder.readOnly) return;
e.preventDefault();
e.stopPropagation();
this.dropTarget = null;
this.emitMoveIfAny(e, folder.id);
}
/** Decodifica el payload de movimiento del evento y emite `ok-move` hacia `to`. */
emitMoveIfAny(e, to) {
const raw = e.dataTransfer?.getData(_OkFileManager2.MOVE_MIME);
if (!raw) return;
try {
const { id } = JSON.parse(raw);
if (id) this.emit("ok-move", { from: id, to });
} catch {
}
}
// Deriva la extensión: usa `ext` o la cola del nombre.

@@ -791,4 +857,13 @@ extOf(file) {

const active = folder.id === this.selected;
const over = this.dropTarget === folder.id;
return html`<li role="treeitem" aria-selected=${active ? "true" : "false"} aria-expanded=${hasChildren ? String(expanded) : ""}>
<div class=${`trow ${active ? "active" : ""}`.trim()} @click=${() => this.navigate(folder.id)}>
<div
class=${`trow ${active ? "active" : ""} ${over ? "drop" : ""}`.trim()}
draggable=${folder.readOnly ? "false" : "true"}
@click=${() => this.navigate(folder.id)}
@dragstart=${(e) => this.onItemDragStart(e, folder.id, "folder")}
@dragover=${(e) => this.onFolderDragOver(e, folder)}
@dragleave=${() => this.onFolderDragLeave(folder)}
@drop=${(e) => this.onFolderDrop(e, folder)}
>
<button

@@ -1067,2 +1142,3 @@ type="button"

tabindex="0"
draggable="true"
@dblclick=${() => this.open(file.id)}

@@ -1072,2 +1148,3 @@ @keydown=${(e) => {

}}
@dragstart=${(e) => this.onItemDragStart(e, file.id, "file")}
>

@@ -1091,2 +1168,3 @@ <div class="card-actions">${this.fileActions(file)}</div>

tabindex="0"
draggable="true"
@dblclick=${() => this.open(file.id)}

@@ -1096,2 +1174,3 @@ @keydown=${(e) => {

}}
@dragstart=${(e) => this.onItemDragStart(e, file.id, "file")}
>

@@ -1153,48 +1232,52 @@ ${this.renderBadge(file)}

}
}
};
__decorateClass([
property({ attribute: false })
], OkFileManager.prototype, "folders");
], _OkFileManager.prototype, "folders");
__decorateClass([
property({ attribute: false })
], OkFileManager.prototype, "files");
], _OkFileManager.prototype, "files");
__decorateClass([
property({ attribute: false })
], OkFileManager.prototype, "path");
], _OkFileManager.prototype, "path");
__decorateClass([
property()
], OkFileManager.prototype, "selected");
], _OkFileManager.prototype, "selected");
__decorateClass([
property()
], OkFileManager.prototype, "view");
], _OkFileManager.prototype, "view");
__decorateClass([
property({ attribute: false })
], OkFileManager.prototype, "quota");
], _OkFileManager.prototype, "quota");
__decorateClass([
property()
], OkFileManager.prototype, "title");
], _OkFileManager.prototype, "title");
__decorateClass([
property({ type: Boolean })
], OkFileManager.prototype, "searchable");
], _OkFileManager.prototype, "searchable");
__decorateClass([
property({ type: Boolean })
], OkFileManager.prototype, "uploadable");
], _OkFileManager.prototype, "uploadable");
__decorateClass([
property({ attribute: false })
], OkFileManager.prototype, "policy");
], _OkFileManager.prototype, "policy");
__decorateClass([
property({ type: Boolean })
], OkFileManager.prototype, "loading");
], _OkFileManager.prototype, "loading");
__decorateClass([
property({ attribute: false })
], OkFileManager.prototype, "labels");
], _OkFileManager.prototype, "labels");
__decorateClass([
state()
], OkFileManager.prototype, "expandedIds");
], _OkFileManager.prototype, "expandedIds");
__decorateClass([
state()
], OkFileManager.prototype, "dragging");
], _OkFileManager.prototype, "dragging");
__decorateClass([
state()
], _OkFileManager.prototype, "dropTarget");
__decorateClass([
query('input[type="file"]')
], OkFileManager.prototype, "fileInput");
], _OkFileManager.prototype, "fileInput");
let OkFileManager = _OkFileManager;
define("ok-file-manager", OkFileManager);

@@ -1201,0 +1284,0 @@ export {

+1
-1
{
"name": "@erplora/outfitkit",
"version": "0.1.33",
"version": "0.1.34",
"description": "OutfitKit — librería de Web Components (Lit) que CONSTRUYE lo que Ionic no tiene (tree, data-table rica, inline-feedback, kpi/stat, stepper/wizard, calendar, kanban…) sobre primitivos de Ionic. Ionic es la base; OutfitKit cubre los huecos. npm + CDN, imports individuales, CSP-safe. Tema vía tokens --ok-* (fallback a --ion-*).",

@@ -5,0 +5,0 @@ "type": "module",

Sorry, the diff of this file is too big to display