Add components
parent
62ad620846
commit
748642949c
@ -0,0 +1,88 @@
|
||||
export class FileGroup extends HTMLElement {
|
||||
textEn = {
|
||||
addFile: 'Add File',
|
||||
}
|
||||
|
||||
textEs = {
|
||||
addFile: 'Añadir archivo',
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.language = navigator.language
|
||||
this.attachShadow({mode: 'open'})
|
||||
this.headerEl = document.createElement('div')
|
||||
this.headerEl.classList.add('header')
|
||||
this.contentEl = document.createElement('div')
|
||||
this.contentEl.classList.add('content')
|
||||
this.shadowRoot.appendChild(this.headerEl)
|
||||
this.shadowRoot.appendChild(this.contentEl)
|
||||
const bGroup = document.createElement(
|
||||
'm-forms-button-group'
|
||||
)
|
||||
bGroup.addPrimary(this.text.addFile, () => {
|
||||
this.addFile()
|
||||
const btn = bGroup.primary
|
||||
if (btn.scrollIntoViewIfNeeded) {
|
||||
btn.scrollIntoViewIfNeeded()
|
||||
} else {
|
||||
btn.scrollIntoView()
|
||||
}
|
||||
})
|
||||
this.shadowRoot.appendChild(bGroup)
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const style = document.createElement('style')
|
||||
style.textContent = `
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
div.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
div.files {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
`
|
||||
this.shadowRoot.appendChild(style)
|
||||
if (this.contentEl.childNodes.length === 0) {
|
||||
this.addFile()
|
||||
}
|
||||
}
|
||||
|
||||
addFile({name, data} = {}) {
|
||||
const el = document.createElement('m-editor-file-view')
|
||||
if (name !== undefined) {
|
||||
el.name = name
|
||||
}
|
||||
if (data !== undefined) {
|
||||
el.data = data
|
||||
}
|
||||
this.contentEl.appendChild(el)
|
||||
return el
|
||||
}
|
||||
|
||||
get language() {
|
||||
return this._language
|
||||
}
|
||||
|
||||
set language(language) {
|
||||
this._language = language
|
||||
this.text = this.langEs ? this.textEs : this.textEn
|
||||
}
|
||||
|
||||
get langEs() {
|
||||
return /^es\b/.test(this.language)
|
||||
}
|
||||
|
||||
get files() {
|
||||
return [...this.contentEl.children]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
export class FileView extends HTMLElement {
|
||||
icons = {
|
||||
menu: `
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
|
||||
<path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
|
||||
</svg>
|
||||
`,
|
||||
}
|
||||
|
||||
textEn = {
|
||||
delete: 'Delete',
|
||||
}
|
||||
|
||||
textEs = {
|
||||
delete: 'Borrar',
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.language = navigator.language
|
||||
this.attachShadow({mode: 'open'})
|
||||
this.headerEl = document.createElement('div')
|
||||
this.headerEl.classList.add('header')
|
||||
this.contentEl = document.createElement('div')
|
||||
this.contentEl.classList.add('content')
|
||||
this.shadowRoot.appendChild(this.headerEl)
|
||||
this.shadowRoot.appendChild(this.contentEl)
|
||||
this.nameEl = document.createElement('input')
|
||||
this.nameEl.classList.add('name')
|
||||
this.headerEl.appendChild(this.nameEl)
|
||||
this.editEl = document.createElement('m-editor-text-edit')
|
||||
this.contentEl.appendChild(this.editEl)
|
||||
this.menuBtn = document.createElement('button')
|
||||
this.menuBtn.innerHTML = this.icons.menu
|
||||
this.menuBtn.addEventListener('click', () => {
|
||||
this.menu.open(this.menuBtn)
|
||||
})
|
||||
this.headerEl.appendChild(this.menuBtn)
|
||||
this.menu = document.createElement(
|
||||
'm-menu-dropdown'
|
||||
)
|
||||
this.menu.add('Borrar', () => {
|
||||
this.remove()
|
||||
})
|
||||
this.shadowRoot.appendChild(this.menu)
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const style = document.createElement('style')
|
||||
style.textContent = `
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
div.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
background-color: #111;
|
||||
color: #ddd;
|
||||
padding: 3px 0;
|
||||
}
|
||||
div.header > * {
|
||||
background: inherit;
|
||||
color: inherit;
|
||||
border: none;
|
||||
}
|
||||
.name {
|
||||
flex-grow: 1;
|
||||
padding: 0 5px;
|
||||
font: inherit;
|
||||
font-family: monospace;
|
||||
outline: none;
|
||||
}
|
||||
div.header button svg {
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
div.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
svg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
`
|
||||
this.shadowRoot.appendChild(style)
|
||||
}
|
||||
|
||||
set name(name) {
|
||||
this.nameEl.value = name
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.nameEl.value
|
||||
}
|
||||
|
||||
set data(data) {
|
||||
this.editEl.value = data
|
||||
}
|
||||
|
||||
get data() {
|
||||
return this.editEl.value
|
||||
}
|
||||
|
||||
get language() {
|
||||
return this._language
|
||||
}
|
||||
|
||||
set language(language) {
|
||||
this._language = language
|
||||
this.text = this.langEs ? this.textEs : this.textEn
|
||||
}
|
||||
|
||||
get langEs() {
|
||||
return /^es\b/.test(this.language)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
export class TextEdit extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({mode: 'open'})
|
||||
this.stackEl = document.createElement('div')
|
||||
this.stackEl.classList.add('stack')
|
||||
this.textEl = document.createElement('textarea')
|
||||
this.textEl.classList.add('text')
|
||||
this.textEl.rows = 1
|
||||
this.stackEl.appendChild(this.textEl)
|
||||
this.shadowRoot.appendChild(this.stackEl)
|
||||
this.textEl.addEventListener('input', () => {
|
||||
this.stackEl.dataset.copy = this.textEl.value
|
||||
})
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas/
|
||||
const style = document.createElement('style')
|
||||
style.textContent = `
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
margin: 5px 0;
|
||||
}
|
||||
div.stack {
|
||||
display: grid;
|
||||
}
|
||||
div.stack::after {
|
||||
content: attr(data-copy) " ";
|
||||
visibility: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
div.stack::after, div.stack > textarea {
|
||||
white-space: pre-wrap;
|
||||
border: 1px solid #888;
|
||||
padding: 3px;
|
||||
font: inherit;
|
||||
font-family: monospace;
|
||||
grid-area: 1 / 1 / 2 / 2;
|
||||
min-height: 1em;
|
||||
border-radius: 2px;
|
||||
resize: none;
|
||||
}
|
||||
`
|
||||
this.shadowRoot.appendChild(style)
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
this.textEl.value = value
|
||||
this.stackEl.dataset.copy = this.textEl.value
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.textEl.value
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue