refactor se-list and se-list-item (#827)
parent
de9df3871f
commit
f9fe802dcd
|
@ -497,7 +497,7 @@ exports[`use various parts of svg-edit > check tool_text_align_to_page #0`] = `
|
|||
stroke="#000000"
|
||||
stroke-width="0"
|
||||
text-anchor="middle"
|
||||
x="145"
|
||||
x="623.33"
|
||||
xml:space="preserve"
|
||||
y="145"
|
||||
>
|
||||
|
|
|
@ -457,8 +457,8 @@ exports[`use all parts of svg-edit > check tool_line_align_to_page #0`] = `
|
|||
opacity="0.25"
|
||||
stroke="#bf5f00"
|
||||
stroke-width="5"
|
||||
x1="220"
|
||||
x2="470"
|
||||
x1="387.5"
|
||||
x2="637.5"
|
||||
y1="220"
|
||||
y2="470"
|
||||
>
|
||||
|
|
|
@ -377,7 +377,7 @@ exports[`use all parts of svg-edit > check tool_polygon_align_to_page #0`] = `
|
|||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
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"
|
||||
sides="5"
|
||||
stroke="#000000"
|
||||
|
@ -405,7 +405,7 @@ exports[`use all parts of svg-edit > check tool_polygon_change_stroke_width #0`]
|
|||
fill="#FF0000"
|
||||
id="svg_1"
|
||||
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"
|
||||
sides="5"
|
||||
stroke="#000000"
|
||||
|
@ -433,7 +433,7 @@ exports[`use all parts of svg-edit > check tool_polygon_change_stoke_fill_color
|
|||
fill="#bf0000"
|
||||
id="svg_1"
|
||||
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"
|
||||
sides="5"
|
||||
stroke="#0000bf"
|
||||
|
@ -461,7 +461,7 @@ exports[`use all parts of svg-edit > check tool_polygon_change_sides #0`] = `
|
|||
fill="#bf0000"
|
||||
id="svg_1"
|
||||
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"
|
||||
sides="6"
|
||||
stroke="#0000bf"
|
||||
|
|
|
@ -419,7 +419,7 @@ exports[`use all parts of svg-edit > check tool_star_align_to_page #0`] = `
|
|||
id="svg_1"
|
||||
orient="point"
|
||||
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"
|
||||
r2="22.22"
|
||||
radialshift="0"
|
||||
|
@ -450,7 +450,7 @@ exports[`use all parts of svg-edit > check tool_star_change_stroke_width #0`] =
|
|||
id="svg_1"
|
||||
orient="point"
|
||||
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"
|
||||
r2="22.22"
|
||||
radialshift="0"
|
||||
|
@ -481,7 +481,7 @@ exports[`use all parts of svg-edit > check tool_star_change_stoke_fill_color #0`
|
|||
id="svg_1"
|
||||
orient="point"
|
||||
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"
|
||||
r2="22.22"
|
||||
radialshift="0"
|
||||
|
@ -512,7 +512,7 @@ exports[`use all parts of svg-edit > check tool_star_change_sides #0`] = `
|
|||
id="svg_1"
|
||||
orient="point"
|
||||
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"
|
||||
r2="22.22"
|
||||
radialshift="0"
|
||||
|
|
|
@ -125,8 +125,8 @@ describe('use various parts of svg-edit', function () {
|
|||
})
|
||||
it('check tool_text_align_to_page', function () {
|
||||
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').find('se-list-item').eq(2).shadow().find('elix-option').eq(0)
|
||||
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('[aria-label="option"]').eq(0)
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
|
|
|
@ -141,8 +141,8 @@ describe('use all parts of svg-edit', function () {
|
|||
})
|
||||
it('check tool_line_align_to_page', function () {
|
||||
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').find('se-list-item').eq(2).shadow().find('elix-option').eq(0)
|
||||
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('[aria-label="option"]').eq(0)
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
|
|
|
@ -94,8 +94,8 @@ describe('use all parts of svg-edit', function () {
|
|||
})
|
||||
it('check tool_polygon_align_to_page', function () {
|
||||
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').find('se-list-item').eq(0).shadow().find('elix-option').eq(0)
|
||||
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('[aria-label="option"]').eq(0)
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
|
|
|
@ -94,8 +94,8 @@ describe('use all parts of svg-edit', function () {
|
|||
})
|
||||
it('check tool_star_align_to_page', function () {
|
||||
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').find('se-list-item').eq(0).shadow().find('elix-option').eq(0)
|
||||
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('[aria-label="option"]').eq(0)
|
||||
.click({ force: true })
|
||||
testSnapshot()
|
||||
})
|
||||
|
|
|
@ -1,34 +1,46 @@
|
|||
/* globals svgEditor */
|
||||
import 'elix/define/DropdownList.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
elix-dropdown-list {
|
||||
#select-container {
|
||||
margin-top: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
elix-dropdown-list:hover {
|
||||
#select-container:hover {
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
|
||||
elix-dropdown-list::part(value) {
|
||||
#select-container::part(value) {
|
||||
background-color: var(--main-bg-color);
|
||||
}
|
||||
|
||||
elix-dropdown-list::part(popup-toggle) {
|
||||
#select-container::part(popup-toggle) {
|
||||
display: none;
|
||||
}
|
||||
::slotted(*) {
|
||||
padding:0;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.closed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#options-container {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
</style>
|
||||
<label>Label</label>
|
||||
<elix-dropdown-list>
|
||||
<div id="select-container" tabindex="0">
|
||||
<div id="selected-value"></div>
|
||||
<div id="options-container">
|
||||
<slot></slot>
|
||||
</elix-dropdown-list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
`
|
||||
/**
|
||||
|
@ -43,11 +55,47 @@ export class SeList extends HTMLElement {
|
|||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
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.$selection = this.$dropdown.shadowRoot.querySelector('#value')
|
||||
this.$selection = this.$dropdown.querySelector('#selected-value')
|
||||
this.items = this.querySelectorAll('se-list-item')
|
||||
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}
|
||||
*/
|
||||
attributeChangedCallback (name, oldValue, newValue) {
|
||||
const currentObj = this
|
||||
if (oldValue === newValue) return
|
||||
switch (name) {
|
||||
case 'title':
|
||||
|
@ -82,22 +129,7 @@ export class SeList extends HTMLElement {
|
|||
this.$dropdown.style.width = newValue
|
||||
break
|
||||
case 'value':
|
||||
Array.from(this.items).forEach(function (element) {
|
||||
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'))
|
||||
}
|
||||
}
|
||||
})
|
||||
this.updateSelectedValue(newValue)
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
|
@ -169,6 +201,30 @@ export class SeList extends HTMLElement {
|
|||
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
|
||||
* @returns {void}
|
||||
|
@ -176,20 +232,28 @@ export class SeList extends HTMLElement {
|
|||
connectedCallback () {
|
||||
const currentObj = this
|
||||
this.$dropdown.addEventListener('selectedindexchange', (e) => {
|
||||
if (e?.detail?.selectedIndex !== undefined) {
|
||||
const value = this.$dropdown.selectedItem.getAttribute('value')
|
||||
if (e?.detail?.selectedItem !== undefined) {
|
||||
const value = e.detail.selectedItem
|
||||
const closeEvent = new CustomEvent('change', { detail: { value } })
|
||||
currentObj.dispatchEvent(closeEvent)
|
||||
currentObj.value = value
|
||||
currentObj.setAttribute('value', value)
|
||||
}
|
||||
})
|
||||
this.$dropdown.addEventListener('close', (_e) => {
|
||||
/** with Chrome, selectedindexchange does not fire consistently
|
||||
* unless you forec change in this close event
|
||||
*/
|
||||
this.$dropdown.selectedIndex = this.$dropdown.currentIndex
|
||||
|
||||
this.$dropdown.addEventListener('focusout', (e) => {
|
||||
this.closeDropdown()
|
||||
})
|
||||
|
||||
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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,26 @@
|
|||
/* globals svgEditor */
|
||||
import 'elix/define/Option.js'
|
||||
import { t } from '../locale.js'
|
||||
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
elix-option{
|
||||
[aria-label="option"]{
|
||||
padding:0.25rem 0.125rem !important;
|
||||
background-color: var(--icon-bg-color);
|
||||
}
|
||||
elix-option:hover{
|
||||
[aria-label="option"]:hover{
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: var(--icon-bg-color-hover);
|
||||
}
|
||||
|
||||
</style>
|
||||
<elix-option aria-label="option">
|
||||
<div aria-label="option">
|
||||
<img alt="icon" />
|
||||
<slot></slot>
|
||||
</elix-option>
|
||||
</div>
|
||||
`
|
||||
/**
|
||||
* @class SeMenu
|
||||
|
@ -30,12 +34,19 @@ export class SeListItem extends HTMLElement {
|
|||
// create the shadowDom and insert the template
|
||||
this._shadowRoot = this.attachShadow({ mode: 'open' })
|
||||
this._shadowRoot.append(template.content.cloneNode(true))
|
||||
this.$menuitem = this._shadowRoot.querySelector('elix-option')
|
||||
this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark')
|
||||
this.$svg.setAttribute('style', 'display: none;')
|
||||
this.$menuitem = this._shadowRoot.querySelector('[aria-label=option]')
|
||||
// this.$svg = this.$menuitem.shadowRoot.querySelector('#checkmark')
|
||||
// this.$svg.setAttribute('style', 'display: none;')
|
||||
this.$img = this._shadowRoot.querySelector('img')
|
||||
this.$img.setAttribute('style', 'display: none;')
|
||||
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
|
||||
*/
|
||||
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':
|
||||
this.$img.setAttribute('height', newValue)
|
||||
break
|
||||
case 'selected':
|
||||
if (newValue === 'true') {
|
||||
this.$menuitem.classList.add('selected')
|
||||
} else {
|
||||
this.$menuitem.classList.remove('selected')
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.error(`unknown attribute: ${name}`)
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue