refactor se-list and se-list-item (#827)

master
Thakur Karthik 2022-08-08 04:35:22 +05:30 committed by GitHub
parent de9df3871f
commit f9fe802dcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 144 additions and 62 deletions

View File

@ -497,7 +497,7 @@ exports[`use various parts of svg-edit > check tool_text_align_to_page #0`] = `
stroke="#000000" stroke="#000000"
stroke-width="0" stroke-width="0"
text-anchor="middle" text-anchor="middle"
x="145" x="623.33"
xml:space="preserve" xml:space="preserve"
y="145" y="145"
> >

View File

@ -457,8 +457,8 @@ exports[`use all parts of svg-edit > check tool_line_align_to_page #0`] = `
opacity="0.25" opacity="0.25"
stroke="#bf5f00" stroke="#bf5f00"
stroke-width="5" stroke-width="5"
x1="220" x1="387.5"
x2="470" x2="637.5"
y1="220" y1="220"
y2="470" y2="470"
> >

View File

@ -377,7 +377,7 @@ exports[`use all parts of svg-edit > check tool_polygon_align_to_page #0`] = `
fill="#FF0000" fill="#FF0000"
id="svg_1" id="svg_1"
orient="x" orient="x"
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 " points="637.5,250 600.2736206054688,301.23773193359375 540.0400390625,281.6666564941406 540.0400390625,218.3333282470703 600.2736206054688,198.7622528076172 637.5,250 "
shape="regularPoly" shape="regularPoly"
sides="5" sides="5"
stroke="#000000" stroke="#000000"
@ -405,7 +405,7 @@ exports[`use all parts of svg-edit > check tool_polygon_change_stroke_width #0`]
fill="#FF0000" fill="#FF0000"
id="svg_1" id="svg_1"
orient="x" orient="x"
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 " points="637.5,250 600.2736206054688,301.23773193359375 540.0400390625,281.6666564941406 540.0400390625,218.3333282470703 600.2736206054688,198.7622528076172 637.5,250 "
shape="regularPoly" shape="regularPoly"
sides="5" sides="5"
stroke="#000000" stroke="#000000"
@ -433,7 +433,7 @@ exports[`use all parts of svg-edit > check tool_polygon_change_stoke_fill_color
fill="#bf0000" fill="#bf0000"
id="svg_1" id="svg_1"
orient="x" orient="x"
points="378.87455119562924,250 341.6481518837726,301.23774297708 281.41457251841285,281.6666666666667 281.4145725184128,218.33333333333334 341.6481518837726,198.76225702291998 378.87455119562924,250 " points="637.5,250 600.2736206054688,301.23773193359375 540.0400390625,281.6666564941406 540.0400390625,218.3333282470703 600.2736206054688,198.7622528076172 637.5,250 "
shape="regularPoly" shape="regularPoly"
sides="5" sides="5"
stroke="#0000bf" stroke="#0000bf"
@ -461,7 +461,7 @@ exports[`use all parts of svg-edit > check tool_polygon_change_sides #0`] = `
fill="#bf0000" fill="#bf0000"
id="svg_1" id="svg_1"
orient="x" orient="x"
points="406.36004929315476,249.999995640346 374.69338262648813,304.8482712133604 311.3600492931548,304.8482712133604 279.69338262648813,249.999995640346 311.36004929315476,195.15172006733155 374.69338262648813,195.15172006733155 406.36004929315476,249.99999564034596 " points="664.9855026971727,249.999995640346 633.318836030506,304.8482712133604 569.9855026971727,304.8482712133604 538.318836030506,249.999995640346 569.9855026971726,195.15172006733155 633.318836030506,195.15172006733155 664.9855026971727,249.99999564034596 "
shape="regularPoly" shape="regularPoly"
sides="6" sides="6"
stroke="#0000bf" stroke="#0000bf"

View File

@ -419,7 +419,7 @@ exports[`use all parts of svg-edit > check tool_star_align_to_page #0`] = `
id="svg_1" id="svg_1"
orient="point" orient="point"
point="5" point="5"
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 " points="574.0962219238281,83.33333587646484 587.1581115722656,132.0218505859375 637.5,129.39886474609375 595.2308044433594,156.86705017089844 613.2818908691406,203.93446350097656 574.0962219238281,172.22222900390625 534.9105529785156,203.93446350097656 552.9616394042969,156.86705017089844 510.6924591064453,129.39886474609375 561.0343322753906,132.0218505859375 574.0962219238281,83.33333587646484 587.1581115722656,132.0218505859375 "
r="66.67" r="66.67"
r2="22.22" r2="22.22"
radialshift="0" radialshift="0"
@ -450,7 +450,7 @@ exports[`use all parts of svg-edit > check tool_star_change_stroke_width #0`] =
id="svg_1" id="svg_1"
orient="point" orient="point"
point="5" point="5"
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 " points="574.0962219238281,83.33333587646484 587.1581115722656,132.0218505859375 637.5,129.39886474609375 595.2308044433594,156.86705017089844 613.2818908691406,203.93446350097656 574.0962219238281,172.22222900390625 534.9105529785156,203.93446350097656 552.9616394042969,156.86705017089844 510.6924591064453,129.39886474609375 561.0343322753906,132.0218505859375 574.0962219238281,83.33333587646484 587.1581115722656,132.0218505859375 "
r="66.67" r="66.67"
r2="22.22" r2="22.22"
radialshift="0" radialshift="0"
@ -481,7 +481,7 @@ exports[`use all parts of svg-edit > check tool_star_change_stoke_fill_color #0`
id="svg_1" id="svg_1"
orient="point" orient="point"
point="5" point="5"
points="300,83.33333333333333 313.0618944953883,132.02184456944562 363.40376775301024,129.39886704167017 321.13458925100343,156.86704431944327 339.18568348616486,203.93446629166317 300,172.22222222222223 260.81431651383514,203.93446629166317 278.86541074899657,156.86704431944327 236.59623224698976,129.39886704167017 286.9381055046117,132.02184456944562 300,83.33333333333333 313.0618944953883,132.02184456944562 " points="574.0962219238281,83.33333587646484 587.1581115722656,132.0218505859375 637.5,129.39886474609375 595.2308044433594,156.86705017089844 613.2818908691406,203.93446350097656 574.0962219238281,172.22222900390625 534.9105529785156,203.93446350097656 552.9616394042969,156.86705017089844 510.6924591064453,129.39886474609375 561.0343322753906,132.0218505859375 574.0962219238281,83.33333587646484 587.1581115722656,132.0218505859375 "
r="66.67" r="66.67"
r2="22.22" r2="22.22"
radialshift="0" radialshift="0"
@ -512,7 +512,7 @@ exports[`use all parts of svg-edit > check tool_star_change_sides #0`] = `
id="svg_1" id="svg_1"
orient="point" orient="point"
point="6" point="6"
points="301.8821476527623,70.14305132911319 312.99325876387337,117.56470902279233 359.61717457172483,103.47638466244652 324.1043698749845,136.80971799577986 359.6171745717249,170.14305132911318 312.9932587638734,156.0547269687674 301.8821476527623,203.47638466244655 290.7710365416512,156.0547269687674 244.1471207337997,170.14305132911323 279.65992543054006,136.80971799577986 244.1471207337997,103.47638466244652 290.7710365416512,117.56470902279233 301.8821476527623,70.14305132911319 312.9932587638734,117.56470902279233 " points="575.9783673967634,70.14305132911319 587.0894785078744,117.56470902279233 633.713394315726,103.47638466244652 598.2005896189855,136.80971799577986 633.713394315726,170.14305132911318 587.0894785078744,156.0547269687674 575.9783673967634,203.47638466244655 564.8672562856523,156.0547269687674 518.2433404778008,170.14305132911323 553.7561451745412,136.80971799577986 518.2433404778008,103.47638466244652 564.8672562856523,117.56470902279233 575.9783673967634,70.14305132911319 587.0894785078744,117.56470902279233 "
r="66.67" r="66.67"
r2="22.22" r2="22.22"
radialshift="0" radialshift="0"

View File

@ -125,8 +125,8 @@ describe('use various parts of svg-edit', function () {
}) })
it('check tool_text_align_to_page', function () { it('check tool_text_align_to_page', function () {
cy.get('#svg_2').click({ force: true }) cy.get('#svg_2').click({ force: true })
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened') cy.get('#tool_position').shadow().find('#select-container').eq(0).click({ force: true })
cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('elix-option').eq(0) cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('[aria-label="option"]').eq(0)
.click({ force: true }) .click({ force: true })
testSnapshot() testSnapshot()
}) })

View File

@ -141,8 +141,8 @@ describe('use all parts of svg-edit', function () {
}) })
it('check tool_line_align_to_page', function () { it('check tool_line_align_to_page', function () {
cy.get('#svg_3').click({ force: true }) cy.get('#svg_3').click({ force: true })
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened') cy.get('#tool_position').shadow().find('#select-container').eq(0).click({ force: true })
cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('elix-option').eq(0) cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('[aria-label="option"]').eq(0)
.click({ force: true }) .click({ force: true })
testSnapshot() testSnapshot()
}) })

View File

@ -94,8 +94,8 @@ describe('use all parts of svg-edit', function () {
}) })
it('check tool_polygon_align_to_page', function () { it('check tool_polygon_align_to_page', function () {
cy.get('#svg_1').click({ force: true }) cy.get('#svg_1').click({ force: true })
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened') cy.get('#tool_position').shadow().find('#select-container').eq(0).click({ force: true })
cy.get('#tool_position').find('se-list-item').eq(0).shadow().find('elix-option').eq(0) cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('[aria-label="option"]').eq(0)
.click({ force: true }) .click({ force: true })
testSnapshot() testSnapshot()
}) })

View File

@ -94,8 +94,8 @@ describe('use all parts of svg-edit', function () {
}) })
it('check tool_star_align_to_page', function () { it('check tool_star_align_to_page', function () {
cy.get('#svg_1').click({ force: true }) cy.get('#svg_1').click({ force: true })
cy.get('#tool_position').shadow().find('elix-dropdown-list').eq(0).invoke('attr', 'opened', 'opened') cy.get('#tool_position').shadow().find('#select-container').eq(0).click({ force: true })
cy.get('#tool_position').find('se-list-item').eq(0).shadow().find('elix-option').eq(0) cy.get('#tool_position').find('se-list-item').eq(2).shadow().find('[aria-label="option"]').eq(0)
.click({ force: true }) .click({ force: true })
testSnapshot() testSnapshot()
}) })

View File

@ -1,34 +1,46 @@
/* globals svgEditor */ /* globals svgEditor */
import 'elix/define/DropdownList.js'
import { t } from '../locale.js' import { t } from '../locale.js'
const template = document.createElement('template') const template = document.createElement('template')
template.innerHTML = ` template.innerHTML = `
<style> <style>
elix-dropdown-list { #select-container {
margin-top: 10px; margin-top: 10px;
display: inline-block;
} }
elix-dropdown-list:hover { #select-container:hover {
background-color: var(--icon-bg-color-hover); background-color: var(--icon-bg-color-hover);
} }
elix-dropdown-list::part(value) { #select-container::part(value) {
background-color: var(--main-bg-color); background-color: var(--main-bg-color);
} }
elix-dropdown-list::part(popup-toggle) { #select-container::part(popup-toggle) {
display: none; display: none;
} }
::slotted(*) { ::slotted(*) {
padding:0; padding:0;
width:100%; width:100%;
} }
.closed {
display: none;
}
#options-container {
position: fixed;
}
</style> </style>
<label>Label</label> <label>Label</label>
<elix-dropdown-list> <div id="select-container" tabindex="0">
<slot></slot> <div id="selected-value"></div>
</elix-dropdown-list> <div id="options-container">
<slot></slot>
</div>
</div>
` `
/** /**
@ -43,11 +55,47 @@ export class SeList extends HTMLElement {
// create the shadowDom and insert the template // create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' }) this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true)) this._shadowRoot.append(template.content.cloneNode(true))
this.$dropdown = this._shadowRoot.querySelector('elix-dropdown-list') this.$dropdown = this._shadowRoot.querySelector('#select-container')
this.$label = this._shadowRoot.querySelector('label') this.$label = this._shadowRoot.querySelector('label')
this.$selection = this.$dropdown.shadowRoot.querySelector('#value') this.$selection = this.$dropdown.querySelector('#selected-value')
this.items = this.querySelectorAll('se-list-item') this.items = this.querySelectorAll('se-list-item')
this.imgPath = svgEditor.configObj.curConfig.imgPath this.imgPath = svgEditor.configObj.curConfig.imgPath
this.$optionsContainer = this._shadowRoot.querySelector('#options-container')
this.$optionsContainer.classList.add('closed')
this.$selection.addEventListener('click', this.toggleList)
this.updateSelectedValue(this.items[0].getAttribute('value'))
this.isDropdownOpen = false
}
toggleList = (e) => {
if (!this.isDropdownOpen) {
this.openDropdown()
this.setDropdownListPosition()
} else {
this.closeDropdown()
}
}
updateSelectedValue = (newValue) => {
Array.from(this.items).forEach((element) => {
if (element.getAttribute('value') === newValue) {
element.setAttribute('selected', true)
if (element.hasAttribute('src')) {
// empty current selection children
while (this.$selection.firstChild) { this.$selection.removeChild(this.$selection.firstChild) }
// replace selection child with image of new value
const img = document.createElement('img')
img.src = this.imgPath + '/' + element.getAttribute('src')
img.style.height = element.getAttribute('img-height')
img.setAttribute('title', t(element.getAttribute('title')))
this.$selection.append(img)
} else {
this.$selection.textContent = t(element.getAttribute('option'))
}
} else {
element.setAttribute('selected', false)
}
})
} }
/** /**
@ -66,7 +114,6 @@ export class SeList extends HTMLElement {
* @returns {void} * @returns {void}
*/ */
attributeChangedCallback (name, oldValue, newValue) { attributeChangedCallback (name, oldValue, newValue) {
const currentObj = this
if (oldValue === newValue) return if (oldValue === newValue) return
switch (name) { switch (name) {
case 'title': case 'title':
@ -82,22 +129,7 @@ export class SeList extends HTMLElement {
this.$dropdown.style.width = newValue this.$dropdown.style.width = newValue
break break
case 'value': case 'value':
Array.from(this.items).forEach(function (element) { this.updateSelectedValue(newValue)
if (element.getAttribute('value') === newValue) {
if (element.hasAttribute('src')) {
// empty current selection children
while (currentObj.$selection.firstChild) { currentObj.$selection.removeChild(currentObj.$selection.firstChild) }
// replace selection child with image of new value
const img = document.createElement('img')
img.src = currentObj.imgPath + '/' + element.getAttribute('src')
img.style.height = element.getAttribute('img-height')
img.setAttribute('title', t(element.getAttribute('title')))
currentObj.$selection.append(img)
} else {
currentObj.$selection.textContent = t(element.getAttribute('option'))
}
}
})
break break
default: default:
console.error(`unknown attribute: ${name}`) console.error(`unknown attribute: ${name}`)
@ -169,6 +201,30 @@ export class SeList extends HTMLElement {
this.setAttribute('height', value) this.setAttribute('height', value)
} }
openDropdown = () => {
this.isDropdownOpen = true
this.$optionsContainer.classList.remove('closed')
}
closeDropdown = () => {
this.isDropdownOpen = false
this.$optionsContainer.classList.add('closed')
}
setDropdownListPosition = () => {
const windowHeight = window.innerHeight
const selectedContainerPosition = this.$selection.getBoundingClientRect()
const optionsContainerPosition = this.$optionsContainer.getBoundingClientRect()
// list is bottom of frame - needs to open from above
if (selectedContainerPosition.bottom + optionsContainerPosition.height > windowHeight) {
this.$optionsContainer.style.top = selectedContainerPosition.top - optionsContainerPosition.height + 'px'
this.$optionsContainer.style.left = selectedContainerPosition.left + 'px'
} else {
this.$optionsContainer.style.top = selectedContainerPosition.bottom + 'px'
this.$optionsContainer.style.left = selectedContainerPosition.left + 'px'
}
}
/** /**
* @function connectedCallback * @function connectedCallback
* @returns {void} * @returns {void}
@ -176,20 +232,28 @@ export class SeList extends HTMLElement {
connectedCallback () { connectedCallback () {
const currentObj = this const currentObj = this
this.$dropdown.addEventListener('selectedindexchange', (e) => { this.$dropdown.addEventListener('selectedindexchange', (e) => {
if (e?.detail?.selectedIndex !== undefined) { if (e?.detail?.selectedItem !== undefined) {
const value = this.$dropdown.selectedItem.getAttribute('value') const value = e.detail.selectedItem
const closeEvent = new CustomEvent('change', { detail: { value } }) const closeEvent = new CustomEvent('change', { detail: { value } })
currentObj.dispatchEvent(closeEvent) currentObj.dispatchEvent(closeEvent)
currentObj.value = value currentObj.value = value
currentObj.setAttribute('value', value) currentObj.setAttribute('value', value)
} }
}) })
this.$dropdown.addEventListener('close', (_e) => {
/** with Chrome, selectedindexchange does not fire consistently this.$dropdown.addEventListener('focusout', (e) => {
* unless you forec change in this close event this.closeDropdown()
*/
this.$dropdown.selectedIndex = this.$dropdown.currentIndex
}) })
window.addEventListener('mousedown', e => {
// When we click on the canvas and if the dropdown is open, then just close the dropdown and stop the event
if (this.isDropdownOpen) {
if (!e.target.closest('se-list')) {
e.stopPropagation()
this.closeDropdown()
}
}
}, { capture: true })
} }
} }

View File

@ -1,22 +1,26 @@
/* globals svgEditor */ /* globals svgEditor */
import 'elix/define/Option.js'
import { t } from '../locale.js' import { t } from '../locale.js'
const template = document.createElement('template') const template = document.createElement('template')
template.innerHTML = ` template.innerHTML = `
<style> <style>
elix-option{ [aria-label="option"]{
padding:0.25rem 0.125rem !important; padding:0.25rem 0.125rem !important;
background-color: var(--icon-bg-color); background-color: var(--icon-bg-color);
} }
elix-option:hover{ [aria-label="option"]:hover{
background-color: var(--icon-bg-color-hover); background-color: var(--icon-bg-color-hover);
} }
.selected {
background-color: var(--icon-bg-color-hover);
}
</style> </style>
<elix-option aria-label="option"> <div aria-label="option">
<img alt="icon" /> <img alt="icon" />
<slot></slot> <slot></slot>
</elix-option> </div>
` `
/** /**
* @class SeMenu * @class SeMenu
@ -30,12 +34,19 @@ export class SeListItem extends HTMLElement {
// create the shadowDom and insert the template // create the shadowDom and insert the template
this._shadowRoot = this.attachShadow({ mode: 'open' }) this._shadowRoot = this.attachShadow({ mode: 'open' })
this._shadowRoot.append(template.content.cloneNode(true)) this._shadowRoot.append(template.content.cloneNode(true))
this.$menuitem = this._shadowRoot.querySelector('elix-option') this.$menuitem = this._shadowRoot.querySelector('[aria-label=option]')
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark') // this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark')
this.$svg.setAttribute('style', 'display: none;') // this.$svg.setAttribute('style', 'display: none;')
this.$img = this._shadowRoot.querySelector('img') this.$img = this._shadowRoot.querySelector('img')
this.$img.setAttribute('style', 'display: none;') this.$img.setAttribute('style', 'display: none;')
this.imgPath = svgEditor.configObj.curConfig.imgPath this.imgPath = svgEditor.configObj.curConfig.imgPath
this.$menuitem.addEventListener('mousedown', e => {
this.$menuitem.dispatchEvent(new CustomEvent('selectedindexchange', {
bubbles: true,
composed: true,
detail: { selectedItem: this.getAttribute('value') }
}))
})
} }
/** /**
@ -43,7 +54,7 @@ export class SeListItem extends HTMLElement {
* @returns {any} observed * @returns {any} observed
*/ */
static get observedAttributes () { static get observedAttributes () {
return ['option', 'src', 'title', 'img-height'] return ['option', 'src', 'title', 'img-height', 'selected']
} }
/** /**
@ -70,6 +81,13 @@ export class SeListItem extends HTMLElement {
case 'img-height': case 'img-height':
this.$img.setAttribute('height', newValue) this.$img.setAttribute('height', newValue)
break break
case 'selected':
if (newValue === 'true') {
this.$menuitem.classList.add('selected')
} else {
this.$menuitem.classList.remove('selected')
}
break
default: default:
console.error(`unknown attribute: ${name}`) console.error(`unknown attribute: ${name}`)
break break