treeselectjs 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/list.css +2 -2
- package/dist/list.js +1 -1
- package/dist/treeselect-js.css +1 -1
- package/dist/treeselect-js.js +1 -1
- package/package.json +1 -1
- package/src/list.css +4 -0
- package/src/list.js +25 -1
- package/src/treeselect-js.css +1 -1
- package/src/treeselect-js.js +36 -64
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ Name | Type (default) | Discription
|
|
|
97
97
|
------------- | ------------- | -------------
|
|
98
98
|
parentHtmlContainer | HTMLElement | It sould be a HTML element (div), it will be changed to the list container.
|
|
99
99
|
value | Array[String] ([]) | It is an array with ids.
|
|
100
|
-
options | Array[Object] ([]) | It is an array of objects { name: String, value: String, children: [] }, where children are the same array of objects.
|
|
100
|
+
options | Array[Object] ([]) | It is an array of objects { name: String, value: String, children: [] }, where children are the same array of objects. Do not use duplicated values.
|
|
101
101
|
openLevel | Number (0) | All groups will be opened to this level.
|
|
102
102
|
appendToBody | Boolean (false) | List will be appended to the body instead of the input container.
|
|
103
103
|
alwaysOpen | Boolean (false) | List will be always opened.
|
|
@@ -119,11 +119,13 @@ input | Array[String] | Returns selected ids without groups, only leafs.
|
|
|
119
119
|
Name | Params | Discription
|
|
120
120
|
------------- | ------------- | -------------
|
|
121
121
|
updateValue | Array[String] | Update selected values.
|
|
122
|
-
mount | None | Helps to remount and update settings.
|
|
123
|
-
destroy | None | Deletes elements from the DOM
|
|
122
|
+
mount | None | Helps to remount and update settings. Change settings that you need (treeselect.appendToBody = true), then call mount().
|
|
123
|
+
destroy | None | Deletes elements from the DOM. Call mount() to add treeselect to the DOM with previously saved internal data. If you need to recreate treeselect with default params - call **new Treeselect(options)**.
|
|
124
124
|
|
|
125
125
|
### Notes
|
|
126
126
|
1) If you want to change the padding of the element you can use CSS selector. I've added **'group'** and **'level'** attributes, but you have to use **!important**.
|
|
127
127
|
2) If you want to update props, set props to the entity of the class and then call **mount()** method.
|
|
128
128
|
3) Use **updateValue()** method to update only the value.
|
|
129
|
-
4) If you need to delete List from the DOM when you don't need treeselect anymore - call **destroy()**.
|
|
129
|
+
4) If you need to delete List from the DOM when you don't need treeselect anymore - call **destroy()**.
|
|
130
|
+
5) Do not use **duplicated** values for the options. You will see a error with duplicated values.
|
|
131
|
+
6) **Value** inside the **options** prop should be a **String**.
|
package/dist/list.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.treeselect-list{width:100%;box-sizing:border-box;border:1px solid #d7dde4;overflow-y:auto;background-color:#fff;max-height:300px}
|
|
2
2
|
.treeselect-list__group-container{box-sizing:border-box}.treeselect-list__item{display:flex;align-items:center;box-sizing:border-box;cursor:pointer;height:30px}
|
|
3
|
-
.treeselect-list__item--focused{background-color:#f0ffff !important}
|
|
4
|
-
.treeselect-list__item-icon{display:flex;align-items:center;cursor:pointer;height:20px;width:20px;min-width:20px}
|
|
3
|
+
.treeselect-list__item:focus{outline:0}.treeselect-list__item--focused{background-color:#f0ffff !important}
|
|
4
|
+
.treeselect-list__item--hidden{display:none}.treeselect-list__item-icon{display:flex;align-items:center;cursor:pointer;height:20px;width:20px;min-width:20px}
|
|
5
5
|
.treeselect-list__item-icon svg{pointer-events:none;width:100%;height:100%;stroke:#c5c7cb}
|
|
6
6
|
.treeselect-list__item-icon:hover svg{stroke:#838790}.treeselect-list__item-checkbox-container{width:20px;height:20px;min-width:20px;border:1px solid #d7dde4;border-radius:3px;position:relative;background-color:#fff;pointer-events:none;box-sizing:border-box}
|
|
7
7
|
.treeselect-list__item-checkbox-container svg{position:absolute;height:100%;width:100%}
|
package/dist/list.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import svg from"./svgIcons.js";const getFlatOptons=(e,i,l=0,c=0)=>e.reduce((e,t)=>{var s=!!t.children?.length;return e.push({id:t.value,name:t.name,childOf:l,isGroup:s,checked:!1,level:c,isClosed:i<=c&&s,hidden:i<c}),s&&(s=getFlatOptons(t.children,i,t.value,c+1),e.push(...s)),e},[]),checkAllChildrenInputs=({id:t,checked:s},i)=>{i.forEach(e=>{e.childOf===t&&(e.checked=s,e.isGroup&&checkAllChildrenInputs(e,i))})},checkAllParentInputs=(t,e)=>{const s=e.find(e=>e.id===t),i=e.filter(e=>e.childOf===s.id);var l=i.every(e=>e.checked),c=i.some(e=>e.isPartialChecked||e.checked)&&!l,r=!l&&!c;l&&(s.checked=!0,s.isPartialChecked=!1),c&&(s.checked=!1,s.isPartialChecked=!0),r&&(s.checked=!1,s.isPartialChecked=!1),s.childOf&&checkAllParentInputs(s.childOf,e)},checkInput=({id:e,isGroup:t,childOf:s,checked:i},l)=>{t&&checkAllChildrenInputs({id:e,checked:i},l),s&&checkAllParentInputs(s,l)},updateValue=(t,s,e)=>{s.forEach(e=>e.checked=!1);const i=s.filter(e=>t.includes(e.id));i.forEach(e=>{e.checked=!0,e.isPartialChecked=!1,checkInput(e,s)}),updateDOM(s,e)},hideShowChildren=(t,{id:s,isClosed:i})=>{const e=t.filter(e=>e.childOf===s);e.forEach(e=>{e.hidden=i,e.isGroup&&!e.isClosed&&hideShowChildren(t,{id:e.id,isClosed:i})})},updateDOM=(l,c)=>{l.forEach(e=>{const t=c.querySelector(`[input-id="${e.id}"]`),s=getListItemByCheckbox(t);if(t.checked=e.checked,e.checked?s.classList.add("treeselect-list__item--checked"):s.classList.remove("treeselect-list__item--checked"),e.isPartialChecked?s.classList.add("treeselect-list__item--partial-checked"):s.classList.remove("treeselect-list__item--partial-checked"),e.isGroup){const i=s.querySelector(".treeselect-list__item-icon");e.isClosed?(s.classList.add("treeselect-list__item--closed"),i.innerHTML=svg.arrowRight):(s.classList.remove("treeselect-list__item--closed"),i.innerHTML=svg.arrowDown)}e.hidden?s.classList.add("treeselect-list__item--hidden"):s.classList.remove("treeselect-list__item--hidden"),updateLeftPaddingItems(e,s,l),updateCheckboxClasses(e,t)});var e=l.some(e=>!e.hidden);const t=c.querySelector(".treeselect-list__empty");e?t.classList.add("treeselect-list__empty--hidden"):t.classList.remove("treeselect-list__empty--hidden")},updateLeftPaddingItems=(t,e,s)=>{0===t.level?(s=s.some(e=>e.isGroup&&e.level===t.level),s=!t.isGroup&&s?"20px":"5px",e.style.paddingLeft=t.isGroup?"0":s):e.style.paddingLeft=t.isGroup?20*t.level+"px":20*t.level+20+"px",e.setAttribute("level",t.level),e.setAttribute("group",t.isGroup)},updateCheckboxClasses=(e,t)=>{const s=t.parentNode,i=s.querySelector(".treeselect-list__item-checkbox-icon");e.checked?i.innerHTML=svg.check:e.isPartialChecked?i.innerHTML=svg.partialCheck:i.innerHTML=""},getAllFlattedChildren=(s,i)=>i.reduce((e,t)=>(t.childOf===s&&(e.push(t),t.isGroup&&e.push(...getAllFlattedChildren(t.id,i))),e),[]),getAllFlattendParents=(s,i)=>i.reduce((e,t)=>(t.id===s&&(e.push(t),t.childOf&&e.push(...getAllFlattendParents(t.childOf,i))),e),[]),getGroupedValues=e=>{const{onlyGroupsIds:t,allItems:s}=e.reduce((e,t)=>(t.checked&&(t.isGroup&&e.onlyGroupsIds.push(t.id),e.allItems.push(t)),e),{onlyGroupsIds:[],allItems:[]});return s.filter(e=>!t.includes(e.childOf))},getCheckedValues=e=>e.filter(e=>e.checked&&!e.isGroup),getListItemByCheckbox=e=>{return e.parentNode.parentNode};class TreeselectList{#lastFocusedItem=null;#isMouseActionsAvailable=!0;constructor({options:e,value:t,openLevel:s,listSlotHtmlComponent:i,emptyText:l}){this.options=e,this.value=t,this.searchText="",this.openLevel=s??0,this.listSlotHtmlComponent=i,this.emptyText=l??"No results found...",this.flattedOptions=getFlatOptons(this.options,this.openLevel),this.flattedOptionsBeforeSearch=this.flattedOptions,this.selectedNodes={ids:[],groupedIds:[]},this.srcElement=this.#createList(),this.updateValue(this.value)}updateValue(e){updateValue(e,this.flattedOptions,this.srcElement),this.#updateSelectedNodes()}updateSearchValue(i){var e=""===this.searchText&&""!==i;if(this.searchText=i,e&&(this.flattedOptionsBeforeSearch=JSON.parse(JSON.stringify(this.flattedOptions))),""===this.searchText)return this.flattedOptions=this.flattedOptionsBeforeSearch.map(t=>{const e=this.flattedOptions.find(e=>e.id===t.id);return e.isClosed=t.isClosed,e.hidden=t.hidden,e}),this.flattedOptionsBeforeSearch=[],updateDOM(this.flattedOptions,this.srcElement),void this.focusFirstListElement();const s=this.flattedOptions.reduce((e,t)=>{var s;return t.name.toLowerCase().includes(i.toLowerCase())&&(e.push(t),t.isGroup&&(s=getAllFlattedChildren(t.id,this.flattedOptions),e.push(...s)),t.childOf&&(s=getAllFlattendParents(t.childOf,this.flattedOptions),e.push(...s))),e},[]);this.flattedOptions.forEach(t=>{s.some(e=>e.id===t.id)?(t.isGroup&&(t.isClosed=!1,hideShowChildren(this.flattedOptions,t)),t.hidden=!1):t.hidden=!0}),updateDOM(this.flattedOptions,this.srcElement),this.focusFirstListElement()}callKeyAction(e){this.#isMouseActionsAvailable=!1;const t=this.srcElement.querySelector(".treeselect-list__item--focused");if("Enter"===e&&t&&t.dispatchEvent(new Event("mousedown")),"ArrowLeft"===e||"ArrowRight"===e){if(!t)return;const c=t.querySelector(".treeselect-list__item-checkbox"),r=c.getAttribute("input-id");var s=this.flattedOptions.find(e=>e.id===r);const o=t.querySelector(".treeselect-list__item-icon");"ArrowLeft"!==e||s.isClosed||o.dispatchEvent(new Event("mousedown")),"ArrowRight"===e&&s.isClosed&&o.dispatchEvent(new Event("mousedown"))}if("ArrowDown"===e||"ArrowUp"===e){const d=Array.from(this.srcElement.querySelectorAll(".treeselect-list__item-checkbox")).filter(e=>"none"!==window.getComputedStyle(getListItemByCheckbox(e)).display);if(d.length)if(t){s=d.findIndex(e=>getListItemByCheckbox(e).classList.contains("treeselect-list__item--focused"));const n=getListItemByCheckbox(d[s]);n.classList.remove("treeselect-list__item--focused");var s="ArrowDown"===e?s+1:s-1,i="ArrowDown"===e?0:d.length-1,i=d[s]??d[i],s=!d[s];const a=getListItemByCheckbox(i);a.classList.add("treeselect-list__item--focused");var i=this.srcElement.getBoundingClientRect(),l=a.getBoundingClientRect();s&&"ArrowDown"===e?this.srcElement.scroll(0,0):s&&"ArrowUp"===e?this.srcElement.scroll(0,this.srcElement.scrollHeight):i.y+i.height<l.y+l.height?this.srcElement.scroll(0,this.srcElement.scrollTop+l.height):i.y>l.y&&this.srcElement.scroll(0,this.srcElement.scrollTop-l.height)}else{const h=getListItemByCheckbox(d[0]);h.classList.add("treeselect-list__item--focused")}}}focusFirstListElement(){var e="treeselect-list__item--focused";const t=this.srcElement.querySelector("."+e);var s=Array.from(this.srcElement.querySelectorAll(".treeselect-list__item-checkbox")).filter(e=>"none"!==window.getComputedStyle(getListItemByCheckbox(e)).display);if(s.length){t&&t.classList.remove(e);const i=getListItemByCheckbox(s[0]);i.classList.add(e)}}#createList(){const e=[],t=document.createElement("div");t.classList.add("treeselect-list");var s=this.#getListHTML(this.options);if(e.push(...s),this.listSlotHtmlComponent){const i=document.createElement("div");i.classList.add("treeselect-list__slot"),i.appendChild(this.listSlotHtmlComponent),e.push(i)}s=this.#createEmptyList();return e.push(s),t.addEventListener("mouseout",e=>{e.stopPropagation(),this.#lastFocusedItem&&this.#isMouseActionsAvailable&&this.#lastFocusedItem.classList.add("treeselect-list__item--focused")}),t.addEventListener("mousemove",()=>{this.#isMouseActionsAvailable=!0}),t.append(...e),t}#getListHTML(e){return e.reduce((e,t)=>{if(t.children?.length){const i=this.#createGroupContainer(t);var s=this.#getListHTML(t.children);return i.append(...s),e.push(i),e}s=this.#createGroupItem(t,!1);return e.push(s),e},[])}#createGroupContainer(e){const t=document.createElement("div");t.setAttribute("group-container-id",e.value),t.classList.add("treeselect-list__group-container");e=this.#createGroupItem(e,!0);return t.appendChild(e),t}#createGroupItem(s,e){const t=document.createElement("div");t.setAttribute("tabindex","-1"),t.setAttribute("title",s.name),t.classList.add("treeselect-list__item"),e&&(e=this.#createArrow(),t.appendChild(e)),t.addEventListener("mouseover",()=>{this.#isMouseActionsAvailable&&this.#groupMouseAction(!0,t)},!0),t.addEventListener("mouseout",()=>{this.#isMouseActionsAvailable&&(this.#groupMouseAction(!1,t),this.#lastFocusedItem=t)},!0),t.addEventListener("mousedown",e=>{e.stopPropagation();const t=e.target.querySelector(".treeselect-list__item-checkbox");t.checked=!t.checked,this.#checkboxClickEvent(t,s)});var e=this.#createCheckbox(s),i=this.#createCheckboxLabel(s);return t.append(e,i),t}#createArrow(){const e=document.createElement("span");return e.setAttribute("tabindex","-1"),e.classList.add("treeselect-list__item-icon"),e.innerHTML=svg.arrowDown,e.addEventListener("mousedown",e=>{e.stopPropagation(),this.#arrowClickEvent(e)}),e}#createCheckbox(e){const t=document.createElement("div"),s=(t.classList.add("treeselect-list__item-checkbox-container"),document.createElement("span")),i=(s.classList.add("treeselect-list__item-checkbox-icon"),s.innerHTML="",document.createElement("input"));return i.setAttribute("tabindex","-1"),i.setAttribute("type","checkbox"),i.setAttribute("input-id",e.value),i.classList.add("treeselect-list__item-checkbox"),t.append(s,i),t}#createCheckboxLabel(e){const t=document.createElement("label");return t.innerHTML=e.name,t.classList.add("treeselect-list__item-label"),t}#createEmptyList(){const e=document.createElement("div"),t=(e.classList.add("treeselect-list__empty"),e.setAttribute("title",this.emptyText),document.createElement("span")),s=(t.classList.add("treeselect-list__empty-icon"),t.innerHTML=svg.attention,document.createElement("span"));return s.classList.add("treeselect-list__empty-text"),s.innerHTML=this.emptyText,e.append(t,s),e}#checkboxClickEvent(e,t){const s=this.flattedOptions.find(e=>e.id===t.value);s.checked=e.checked,s.isPartialChecked=!1,checkInput(s,this.flattedOptions),updateDOM(this.flattedOptions,this.srcElement),this.#emitInput()}#arrowClickEvent(e){const t=e.target.parentNode.querySelector("[input-id]"),s=t.getAttribute("input-id"),i=this.flattedOptions.find(e=>e.id===s);i.isClosed=!i.isClosed,hideShowChildren(this.flattedOptions,i),updateDOM(this.flattedOptions,this.srcElement),this.#emitArrrowClick()}#groupMouseAction(e,t){const s="treeselect-list__item--focused";if(e){const i=Array.from(this.srcElement.querySelectorAll("."+s));i.length&&i.forEach(e=>e.classList.remove(s)),t.classList.add(s)}else t.classList.remove(s)}#updateSelectedNodes(){this.selectedNodes={ids:getCheckedValues(this.flattedOptions),groupedIds:getGroupedValues(this.flattedOptions)}}#emitArrrowClick(){this.srcElement.dispatchEvent(new CustomEvent("arrow-click"))}#emitInput(){this.#updateSelectedNodes(),this.srcElement.dispatchEvent(new CustomEvent("input",{detail:this.selectedNodes}))}}export default TreeselectList;
|
|
1
|
+
import svg from"./svgIcons.js";const getFlatOptons=(e,i,l=0,c=0)=>e.reduce((e,t)=>{var s=!!t.children?.length;return e.push({id:t.value,name:t.name,childOf:l,isGroup:s,checked:!1,level:c,isClosed:i<=c&&s,hidden:i<c}),s&&(s=getFlatOptons(t.children,i,t.value,c+1),e.push(...s)),e},[]),checkAllChildrenInputs=({id:t,checked:s},i)=>{i.forEach(e=>{e.childOf===t&&(e.checked=s,e.isGroup&&checkAllChildrenInputs(e,i))})},checkAllParentInputs=(t,e)=>{const s=e.find(e=>e.id===t),i=e.filter(e=>e.childOf===s.id);var l=i.every(e=>e.checked),c=i.some(e=>e.isPartialChecked||e.checked)&&!l,r=!l&&!c;l&&(s.checked=!0,s.isPartialChecked=!1),c&&(s.checked=!1,s.isPartialChecked=!0),r&&(s.checked=!1,s.isPartialChecked=!1),s.childOf&&checkAllParentInputs(s.childOf,e)},checkInput=({id:e,isGroup:t,childOf:s,checked:i},l)=>{t&&checkAllChildrenInputs({id:e,checked:i},l),s&&checkAllParentInputs(s,l)},updateValue=(t,s,e)=>{s.forEach(e=>{e.checked=!1,e.isPartialChecked=!1});const i=s.filter(e=>t.includes(e.id));i.forEach(e=>{e.checked=!0,e.isPartialChecked=!1,checkInput(e,s)}),updateDOM(s,e)},hideShowChildren=(t,{id:s,isClosed:i})=>{const e=t.filter(e=>e.childOf===s);e.forEach(e=>{e.hidden=i,e.isGroup&&!e.isClosed&&hideShowChildren(t,{id:e.id,isClosed:i})})},updateDOM=(l,c)=>{l.forEach(e=>{const t=c.querySelector(`[input-id="${e.id}"]`),s=getListItemByCheckbox(t);if(t.checked=e.checked,e.checked?s.classList.add("treeselect-list__item--checked"):s.classList.remove("treeselect-list__item--checked"),e.isPartialChecked?s.classList.add("treeselect-list__item--partial-checked"):s.classList.remove("treeselect-list__item--partial-checked"),e.isGroup){const i=s.querySelector(".treeselect-list__item-icon");e.isClosed?(s.classList.add("treeselect-list__item--closed"),i.innerHTML=svg.arrowRight):(s.classList.remove("treeselect-list__item--closed"),i.innerHTML=svg.arrowDown)}e.hidden?s.classList.add("treeselect-list__item--hidden"):s.classList.remove("treeselect-list__item--hidden"),updateLeftPaddingItems(e,s,l),updateCheckboxClasses(e,t)});var e=l.some(e=>!e.hidden);const t=c.querySelector(".treeselect-list__empty");e?t.classList.add("treeselect-list__empty--hidden"):t.classList.remove("treeselect-list__empty--hidden")},updateLeftPaddingItems=(t,e,s)=>{0===t.level?(s=s.some(e=>e.isGroup&&e.level===t.level),s=!t.isGroup&&s?"20px":"5px",e.style.paddingLeft=t.isGroup?"0":s):e.style.paddingLeft=t.isGroup?20*t.level+"px":20*t.level+20+"px",e.setAttribute("level",t.level),e.setAttribute("group",t.isGroup)},updateCheckboxClasses=(e,t)=>{const s=t.parentNode,i=s.querySelector(".treeselect-list__item-checkbox-icon");e.checked?i.innerHTML=svg.check:e.isPartialChecked?i.innerHTML=svg.partialCheck:i.innerHTML=""},getAllFlattedChildren=(s,i)=>i.reduce((e,t)=>(t.childOf===s&&(e.push(t),t.isGroup&&e.push(...getAllFlattedChildren(t.id,i))),e),[]),getAllFlattendParents=(s,i)=>i.reduce((e,t)=>(t.id===s&&(e.push(t),t.childOf&&e.push(...getAllFlattendParents(t.childOf,i))),e),[]),getGroupedValues=e=>{const{onlyGroupsIds:t,allItems:s}=e.reduce((e,t)=>(t.checked&&(t.isGroup&&e.onlyGroupsIds.push(t.id),e.allItems.push(t)),e),{onlyGroupsIds:[],allItems:[]});return s.filter(e=>!t.includes(e.childOf))},getCheckedValues=e=>e.filter(e=>e.checked&&!e.isGroup),getListItemByCheckbox=e=>{return e.parentNode.parentNode},validateOptions=e=>{const t=e.reduce((e,t)=>(e.allItems.includes(t.id)&&e.duplications.push(t.id),e.allItems.push(t.id),e),{duplications:[],allItems:[]})["duplications"];t.length&&console.error(`You have duplicated values: ${t.join(", ")}! You should use unique values.`)};class TreeselectList{#lastFocusedItem=null;#isMouseActionsAvailable=!0;constructor({options:e,value:t,openLevel:s,listSlotHtmlComponent:i,emptyText:l}){this.options=e,this.value=t,this.searchText="",this.openLevel=s??0,this.listSlotHtmlComponent=i,this.emptyText=l??"No results found...",this.flattedOptions=getFlatOptons(this.options,this.openLevel),this.flattedOptionsBeforeSearch=this.flattedOptions,this.selectedNodes={ids:[],groupedIds:[]},this.srcElement=this.#createList(),this.updateValue(this.value),validateOptions(this.flattedOptions)}updateValue(e){updateValue(e,this.flattedOptions,this.srcElement),this.#updateSelectedNodes()}updateSearchValue(i){var e=""===this.searchText&&""!==i;if(this.searchText=i,e&&(this.flattedOptionsBeforeSearch=JSON.parse(JSON.stringify(this.flattedOptions))),""===this.searchText)return this.flattedOptions=this.flattedOptionsBeforeSearch.map(t=>{const e=this.flattedOptions.find(e=>e.id===t.id);return e.isClosed=t.isClosed,e.hidden=t.hidden,e}),this.flattedOptionsBeforeSearch=[],updateDOM(this.flattedOptions,this.srcElement),void this.focusFirstListElement();const s=this.flattedOptions.reduce((e,t)=>{var s;return t.name.toLowerCase().includes(i.toLowerCase())&&(e.push(t),t.isGroup&&(s=getAllFlattedChildren(t.id,this.flattedOptions),e.push(...s)),t.childOf&&(s=getAllFlattendParents(t.childOf,this.flattedOptions),e.push(...s))),e},[]);this.flattedOptions.forEach(t=>{s.some(e=>e.id===t.id)?(t.isGroup&&(t.isClosed=!1,hideShowChildren(this.flattedOptions,t)),t.hidden=!1):t.hidden=!0}),updateDOM(this.flattedOptions,this.srcElement),this.focusFirstListElement()}callKeyAction(e){this.#isMouseActionsAvailable=!1;const t=this.srcElement.querySelector(".treeselect-list__item--focused");if("Enter"===e&&t&&t.dispatchEvent(new Event("mousedown")),"ArrowLeft"===e||"ArrowRight"===e){if(!t)return;const c=t.querySelector(".treeselect-list__item-checkbox"),r=c.getAttribute("input-id");var s=this.flattedOptions.find(e=>e.id===r);const o=t.querySelector(".treeselect-list__item-icon");"ArrowLeft"!==e||s.isClosed||o.dispatchEvent(new Event("mousedown")),"ArrowRight"===e&&s.isClosed&&o.dispatchEvent(new Event("mousedown"))}if("ArrowDown"===e||"ArrowUp"===e){const d=Array.from(this.srcElement.querySelectorAll(".treeselect-list__item-checkbox")).filter(e=>"none"!==window.getComputedStyle(getListItemByCheckbox(e)).display);if(d.length)if(t){s=d.findIndex(e=>getListItemByCheckbox(e).classList.contains("treeselect-list__item--focused"));const n=getListItemByCheckbox(d[s]);n.classList.remove("treeselect-list__item--focused");var s="ArrowDown"===e?s+1:s-1,i="ArrowDown"===e?0:d.length-1,i=d[s]??d[i],s=!d[s];const a=getListItemByCheckbox(i);a.classList.add("treeselect-list__item--focused");var i=this.srcElement.getBoundingClientRect(),l=a.getBoundingClientRect();s&&"ArrowDown"===e?this.srcElement.scroll(0,0):s&&"ArrowUp"===e?this.srcElement.scroll(0,this.srcElement.scrollHeight):i.y+i.height<l.y+l.height?this.srcElement.scroll(0,this.srcElement.scrollTop+l.height):i.y>l.y&&this.srcElement.scroll(0,this.srcElement.scrollTop-l.height)}else{const h=getListItemByCheckbox(d[0]);h.classList.add("treeselect-list__item--focused")}}}focusFirstListElement(){var e="treeselect-list__item--focused";const t=this.srcElement.querySelector("."+e);var s=Array.from(this.srcElement.querySelectorAll(".treeselect-list__item-checkbox")).filter(e=>"none"!==window.getComputedStyle(getListItemByCheckbox(e)).display);if(s.length){t&&t.classList.remove(e);const i=getListItemByCheckbox(s[0]);i.classList.add(e)}}#createList(){const e=[],t=document.createElement("div");t.classList.add("treeselect-list");var s=this.#getListHTML(this.options);if(e.push(...s),this.listSlotHtmlComponent){const i=document.createElement("div");i.classList.add("treeselect-list__slot"),i.appendChild(this.listSlotHtmlComponent),e.push(i)}s=this.#createEmptyList();return e.push(s),t.addEventListener("mouseout",e=>{e.stopPropagation(),this.#lastFocusedItem&&this.#isMouseActionsAvailable&&this.#lastFocusedItem.classList.add("treeselect-list__item--focused")}),t.addEventListener("mousemove",()=>{this.#isMouseActionsAvailable=!0}),t.append(...e),t}#getListHTML(e){return e.reduce((e,t)=>{if(t.children?.length){const i=this.#createGroupContainer(t);var s=this.#getListHTML(t.children);return i.append(...s),e.push(i),e}s=this.#createGroupItem(t,!1);return e.push(s),e},[])}#createGroupContainer(e){const t=document.createElement("div");t.setAttribute("group-container-id",e.value),t.classList.add("treeselect-list__group-container");e=this.#createGroupItem(e,!0);return t.appendChild(e),t}#createGroupItem(s,e){const t=document.createElement("div");t.setAttribute("tabindex","-1"),t.setAttribute("title",s.name),t.classList.add("treeselect-list__item"),e&&(e=this.#createArrow(),t.appendChild(e)),t.addEventListener("mouseover",()=>{this.#isMouseActionsAvailable&&this.#groupMouseAction(!0,t)},!0),t.addEventListener("mouseout",()=>{this.#isMouseActionsAvailable&&(this.#groupMouseAction(!1,t),this.#lastFocusedItem=t)},!0),t.addEventListener("mousedown",e=>{e.stopPropagation();const t=e.target.querySelector(".treeselect-list__item-checkbox");t.checked=!t.checked,this.#checkboxClickEvent(t,s)});var e=this.#createCheckbox(s),i=this.#createCheckboxLabel(s);return t.append(e,i),t}#createArrow(){const e=document.createElement("span");return e.setAttribute("tabindex","-1"),e.classList.add("treeselect-list__item-icon"),e.innerHTML=svg.arrowDown,e.addEventListener("mousedown",e=>{e.stopPropagation(),this.#arrowClickEvent(e)}),e}#createCheckbox(e){const t=document.createElement("div"),s=(t.classList.add("treeselect-list__item-checkbox-container"),document.createElement("span")),i=(s.classList.add("treeselect-list__item-checkbox-icon"),s.innerHTML="",document.createElement("input"));return i.setAttribute("tabindex","-1"),i.setAttribute("type","checkbox"),i.setAttribute("input-id",e.value),i.classList.add("treeselect-list__item-checkbox"),t.append(s,i),t}#createCheckboxLabel(e){const t=document.createElement("label");return t.innerHTML=e.name,t.classList.add("treeselect-list__item-label"),t}#createEmptyList(){const e=document.createElement("div"),t=(e.classList.add("treeselect-list__empty"),e.setAttribute("title",this.emptyText),document.createElement("span")),s=(t.classList.add("treeselect-list__empty-icon"),t.innerHTML=svg.attention,document.createElement("span"));return s.classList.add("treeselect-list__empty-text"),s.innerHTML=this.emptyText,e.append(t,s),e}#checkboxClickEvent(e,t){const s=this.flattedOptions.find(e=>e.id===t.value);s.checked=e.checked,s.isPartialChecked=!1,checkInput(s,this.flattedOptions),updateDOM(this.flattedOptions,this.srcElement),this.#emitInput()}#arrowClickEvent(e){const t=e.target.parentNode.querySelector("[input-id]"),s=t.getAttribute("input-id"),i=this.flattedOptions.find(e=>e.id===s);i.isClosed=!i.isClosed,hideShowChildren(this.flattedOptions,i),updateDOM(this.flattedOptions,this.srcElement),this.#emitArrrowClick()}#groupMouseAction(e,t){const s="treeselect-list__item--focused";if(e){const i=Array.from(this.srcElement.querySelectorAll("."+s));i.length&&i.forEach(e=>e.classList.remove(s)),t.classList.add(s)}else t.classList.remove(s)}#updateSelectedNodes(){this.selectedNodes={ids:getCheckedValues(this.flattedOptions),groupedIds:getGroupedValues(this.flattedOptions)}}#emitArrrowClick(){this.srcElement.dispatchEvent(new CustomEvent("arrow-click"))}#emitInput(){this.#updateSelectedNodes(),this.srcElement.dispatchEvent(new CustomEvent("input",{detail:this.selectedNodes}))}}export default TreeselectList;
|
package/dist/treeselect-js.css
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
.treeselect-input--opened.treeselect-input--top{border-top-color:transparent;border-top-left-radius:0;border-top-right-radius:0}
|
|
5
5
|
.treeselect-input--opened.treeselect-input--bottom{border-bottom-color:transparent;border-bottom-left-radius:0;border-bottom-right-radius:0}
|
|
6
6
|
.treeselect-list--focused{border-color:#101010}.treeselect-list--top,.treeselect-list--top-to-body{border-bottom-color:#d7dde4;border-bottom-left-radius:0;border-bottom-right-radius:0}
|
|
7
|
-
.treeselect-list--bottom,.treeselect-list--bottom-to-body{border-top-color
|
|
7
|
+
.treeselect-list--bottom,.treeselect-list--bottom-to-body{border-top-color:#d7dde4;border-top-left-radius:0;border-top-right-radius:0}
|
|
8
8
|
.treeselect-list--top{left:0;bottom:100%}.treeselect-list--bottom{left:0;top:100%}
|
package/dist/treeselect-js.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import TreeselectInput from"./input.js";import TreeselectList from"./list.js";class Treeselect{#htmlContainer=null;#treeselectList=null;#treeselectInput=null;#
|
|
1
|
+
import TreeselectInput from"./input.js";import TreeselectList from"./list.js";class Treeselect{#htmlContainer=null;#treeselectList=null;#treeselectInput=null;#containerResizer=null;#scrollEvent=null;#focusEvent=null;#blurEvent=null;constructor({parentHtmlContainer:e,value:t,options:s,openLevel:i,appendToBody:l,alwaysOpen:n,showTags:r,clearable:o,searchable:c,placeholder:a,grouped:d,listSlotHtmlComponent:h,disabled:u,emptyText:p}){this.parentHtmlContainer=e,this.value=t??[],this.options=s??[],this.openLevel=i??0,this.appendToBody=l??!0,this.alwaysOpen=n&&!u,this.showTags=r??!0,this.clearable=o??!0,this.searchable=c??!0,this.placeholder=a??"Search...",this.grouped=d??!0,this.listSlotHtmlComponent=h??null,this.disabled=u??!1,this.emptyText=p??"No results found...",this.srcElement=null,this.mount()}mount(){this.destroy(),this.srcElement=this.#createTreeselect(),this.#scrollEvent=this.scrollWindowHandler.bind(this),this.#focusEvent=this.focusWindowHandler.bind(this),this.#blurEvent=this.blurWindowHandler.bind(this),this.alwaysOpen&&this.#treeselectInput.openClose(),this.disabled&&this.srcElement.classList.add("treeselect--disabled")}updateValue(e){const t=this.#treeselectList;t.updateValue(e);var{groupedIds:e,ids:s}=t.selectedNodes,e=this.grouped?e:s;this.#treeselectInput.updateValue(e)}destroy(){this.srcElement&&(this.#closeList(),this.srcElement.innerHTML="",this.srcElement=null,this.#removeOutsideListeners(!0))}#createTreeselect(){const e=this.parentHtmlContainer,t=(e.classList.add("treeselect"),new TreeselectList({options:this.options,value:this.value,openLevel:this.openLevel,listSlotHtmlComponent:this.listSlotHtmlComponent,emptyText:this.emptyText}));var{groupedIds:s,ids:i}=t.selectedNodes;const l=new TreeselectInput({value:this.grouped?s:i,showTags:this.showTags,clearable:this.clearable,isAlwaysOpened:this.alwaysOpen,searchable:this.searchable,placeholder:this.placeholder,disabled:this.disabled});return this.appendToBody&&(this.#containerResizer=new ResizeObserver(()=>{this.updateListPosition()})),l.srcElement.addEventListener("input",e=>{e=e.detail.map(({id:e})=>e);this.value=e,t.updateValue(e),this.#emitInput()}),l.srcElement.addEventListener("open",()=>this.#openList()),l.srcElement.addEventListener("keydown",e=>t.callKeyAction(e.key)),l.srcElement.addEventListener("search",e=>{t.updateSearchValue(e.detail),this.updateListPosition()}),l.srcElement.addEventListener("focus",()=>{this.#updateFocusClasses(!0),document.addEventListener("mousedown",this.#focusEvent,!0),document.addEventListener("focus",this.#focusEvent,!0),window.addEventListener("blur",this.#blurEvent)},!0),this.alwaysOpen||l.srcElement.addEventListener("close",()=>{this.#closeList()}),t.srcElement.addEventListener("mouseup",()=>{l.focus()},!0),t.srcElement.addEventListener("input",e=>{const{groupedIds:t,ids:s}=e.detail;e=this.grouped?t:s;l.updateValue(e),this.value=s.map(({id:e})=>e),l.focus(),this.#emitInput()}),t.srcElement.addEventListener("arrow-click",()=>{l.focus(),this.updateListPosition()}),this.#htmlContainer=e,this.#treeselectList=t,this.#treeselectInput=l,e.append(l.srcElement),e}#openList(){window.addEventListener("scroll",this.#scrollEvent,!0),this.appendToBody?(document.body.appendChild(this.#treeselectList.srcElement),this.#containerResizer.observe(this.#htmlContainer)):this.#htmlContainer.appendChild(this.#treeselectList.srcElement),this.updateListPosition(),this.#updateOpenCloseClasses(!0),this.#treeselectList.focusFirstListElement()}#closeList(){window.removeEventListener("scroll",this.#scrollEvent,!0),(this.appendToBody?document.body:this.#htmlContainer).contains(this.#treeselectList.srcElement)&&(this.appendToBody?(document.body.removeChild(this.#treeselectList.srcElement),this.#containerResizer?.disconnect()):this.#htmlContainer.removeChild(this.#treeselectList.srcElement),this.#updateOpenCloseClasses(!1))}#updateDirectionClasses(e,t){var s=t?"treeselect-list--top-to-body":"treeselect-list--top",t=t?"treeselect-list--bottom-to-body":"treeselect-list--bottom";e?(this.#treeselectList.srcElement.classList.add(s),this.#treeselectList.srcElement.classList.remove(t),this.#treeselectInput.srcElement.classList.add("treeselect-input--top"),this.#treeselectInput.srcElement.classList.remove("treeselect-input--bottom")):(this.#treeselectList.srcElement.classList.remove(s),this.#treeselectList.srcElement.classList.add(t),this.#treeselectInput.srcElement.classList.remove("treeselect-input--top"),this.#treeselectInput.srcElement.classList.add("treeselect-input--bottom"))}#updateFocusClasses(e){e?(this.#treeselectInput.srcElement.classList.add("treeselect-input--focused"),this.#treeselectList.srcElement.classList.add("treeselect-list--focused")):(this.#treeselectInput.srcElement.classList.remove("treeselect-input--focused"),this.#treeselectList.srcElement.classList.remove("treeselect-list--focused"))}#updateOpenCloseClasses(e){e?this.#treeselectInput.srcElement.classList.add("treeselect-input--opened"):this.#treeselectInput.srcElement.classList.remove("treeselect-input--opened")}#removeOutsideListeners(e){this.alwaysOpen&&!e||window.removeEventListener("scroll",this.#scrollEvent,!0),document.removeEventListener("click",this.#focusEvent,!0),document.removeEventListener("focus",this.#focusEvent,!0),window.removeEventListener("blur",this.#blurEvent)}scrollWindowHandler(){this.updateListPosition()}focusWindowHandler(e){this.#htmlContainer.contains(e.target)||this.#treeselectList.srcElement.contains(e.target)||(this.#treeselectInput.blur(),this.#removeOutsideListeners(),this.#updateFocusClasses(!1))}blurWindowHandler(){this.#treeselectInput.blur(),this.#removeOutsideListeners(),this.#updateFocusClasses(!1)}updateListPosition(){const e=this.#treeselectList.srcElement,t=(e.style.transform=null,this.#htmlContainer);var{y:s,height:i}=e.getBoundingClientRect(),{x:l,y:n,height:r,width:o}=t.getBoundingClientRect(),c=window.innerHeight-n-r,c=c<n&&i<=n&&c<i,i=(this.appendToBody&&(e.style.transform=c?`translateY(${n-s-i}px)`:`translateY(${n+r-s}px)`,e.style.width=o+"px",e.style.left=l+"px"),c?"top":"buttom");e.getAttribute("direction")!==i&&(e.setAttribute("direction",i),this.#updateDirectionClasses(c,this.appendToBody))}#emitInput(){this.srcElement.dispatchEvent(new CustomEvent("input",{detail:this.value}))}}export default Treeselect;
|
package/package.json
CHANGED
package/src/list.css
CHANGED
package/src/list.js
CHANGED
|
@@ -67,7 +67,10 @@ const checkInput = ({ id, isGroup, childOf, checked }, flatOptions) => {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const updateValue = (newValue, flatOptions, srcElement) => {
|
|
70
|
-
flatOptions.forEach(option =>
|
|
70
|
+
flatOptions.forEach(option => {
|
|
71
|
+
option.checked = false
|
|
72
|
+
option.isPartialChecked = false
|
|
73
|
+
})
|
|
71
74
|
const toCheck = flatOptions.filter(option => newValue.includes(option.id))
|
|
72
75
|
toCheck.forEach(option => {
|
|
73
76
|
option.checked = true
|
|
@@ -233,6 +236,26 @@ const getListItemByCheckbox = (checkbox) => {
|
|
|
233
236
|
return listItem
|
|
234
237
|
}
|
|
235
238
|
|
|
239
|
+
const validateOptions = (flattedOption) => {
|
|
240
|
+
const { duplications } = flattedOption.reduce((acc, curr) => {
|
|
241
|
+
if (acc.allItems.includes(curr.id)) {
|
|
242
|
+
acc.duplications.push(curr.id)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
acc.allItems.push(curr.id)
|
|
246
|
+
|
|
247
|
+
return acc
|
|
248
|
+
}, {
|
|
249
|
+
duplications: [],
|
|
250
|
+
allItems: []
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
if (duplications.length) {
|
|
255
|
+
console.error(`You have duplicated values: ${duplications.join(', ')}! You should use unique values.`)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
236
259
|
class TreeselectList {
|
|
237
260
|
#lastFocusedItem = null
|
|
238
261
|
#isMouseActionsAvailable = true
|
|
@@ -257,6 +280,7 @@ class TreeselectList {
|
|
|
257
280
|
this.srcElement = this.#createList()
|
|
258
281
|
|
|
259
282
|
this.updateValue(this.value)
|
|
283
|
+
validateOptions(this.flattedOptions)
|
|
260
284
|
}
|
|
261
285
|
|
|
262
286
|
// Public methods
|
package/src/treeselect-js.css
CHANGED
package/src/treeselect-js.js
CHANGED
|
@@ -8,10 +8,7 @@ class Treeselect {
|
|
|
8
8
|
#treeselectInput = null
|
|
9
9
|
|
|
10
10
|
// Resize props
|
|
11
|
-
#transform = { top: null, bottom: null }
|
|
12
|
-
#treeselectInitPosition = null
|
|
13
11
|
#containerResizer = null
|
|
14
|
-
#containerWidth = 0
|
|
15
12
|
|
|
16
13
|
// Outside listeners
|
|
17
14
|
#scrollEvent = null
|
|
@@ -56,12 +53,7 @@ class Treeselect {
|
|
|
56
53
|
|
|
57
54
|
// Public methods
|
|
58
55
|
mount () {
|
|
59
|
-
|
|
60
|
-
this.#closeList()
|
|
61
|
-
this.srcElement.innerHTML = ''
|
|
62
|
-
this.srcElement = null
|
|
63
|
-
this.#removeOutsideListeners()
|
|
64
|
-
}
|
|
56
|
+
this.destroy()
|
|
65
57
|
|
|
66
58
|
this.srcElement = this.#createTreeselect()
|
|
67
59
|
|
|
@@ -91,7 +83,7 @@ class Treeselect {
|
|
|
91
83
|
this.#closeList()
|
|
92
84
|
this.srcElement.innerHTML = ''
|
|
93
85
|
this.srcElement = null
|
|
94
|
-
this.#removeOutsideListeners()
|
|
86
|
+
this.#removeOutsideListeners(true)
|
|
95
87
|
}
|
|
96
88
|
}
|
|
97
89
|
|
|
@@ -120,9 +112,7 @@ class Treeselect {
|
|
|
120
112
|
|
|
121
113
|
if (this.appendToBody) {
|
|
122
114
|
this.#containerResizer = new ResizeObserver(() => {
|
|
123
|
-
|
|
124
|
-
this.#containerWidth = width
|
|
125
|
-
this.updateListPosition(container, list.srcElement, true)
|
|
115
|
+
this.updateListPosition()
|
|
126
116
|
})
|
|
127
117
|
}
|
|
128
118
|
|
|
@@ -137,7 +127,7 @@ class Treeselect {
|
|
|
137
127
|
input.srcElement.addEventListener('keydown', (e) => list.callKeyAction(e.key))
|
|
138
128
|
input.srcElement.addEventListener('search', (e) => {
|
|
139
129
|
list.updateSearchValue(e.detail)
|
|
140
|
-
this.updateListPosition(
|
|
130
|
+
this.updateListPosition()
|
|
141
131
|
})
|
|
142
132
|
input.srcElement.addEventListener('focus', () => {
|
|
143
133
|
this.#updateFocusClasses(true)
|
|
@@ -166,7 +156,7 @@ class Treeselect {
|
|
|
166
156
|
})
|
|
167
157
|
list.srcElement.addEventListener('arrow-click', () => {
|
|
168
158
|
input.focus()
|
|
169
|
-
this.updateListPosition(
|
|
159
|
+
this.updateListPosition()
|
|
170
160
|
})
|
|
171
161
|
|
|
172
162
|
this.#htmlContainer = container
|
|
@@ -188,7 +178,7 @@ class Treeselect {
|
|
|
188
178
|
this.#htmlContainer.appendChild(this.#treeselectList.srcElement)
|
|
189
179
|
}
|
|
190
180
|
|
|
191
|
-
this.updateListPosition(
|
|
181
|
+
this.updateListPosition()
|
|
192
182
|
this.#updateOpenCloseClasses(true)
|
|
193
183
|
this.#treeselectList.focusFirstListElement()
|
|
194
184
|
}
|
|
@@ -248,8 +238,10 @@ class Treeselect {
|
|
|
248
238
|
}
|
|
249
239
|
}
|
|
250
240
|
|
|
251
|
-
#removeOutsideListeners () {
|
|
252
|
-
|
|
241
|
+
#removeOutsideListeners (isDestroy) {
|
|
242
|
+
if (!this.alwaysOpen || isDestroy) {
|
|
243
|
+
window.removeEventListener('scroll', this.#scrollEvent, true)
|
|
244
|
+
}
|
|
253
245
|
|
|
254
246
|
document.removeEventListener('click', this.#focusEvent, true)
|
|
255
247
|
document.removeEventListener('focus', this.#focusEvent, true)
|
|
@@ -258,7 +250,7 @@ class Treeselect {
|
|
|
258
250
|
|
|
259
251
|
// Outside Listeners
|
|
260
252
|
scrollWindowHandler () {
|
|
261
|
-
this.updateListPosition(
|
|
253
|
+
this.updateListPosition()
|
|
262
254
|
}
|
|
263
255
|
|
|
264
256
|
focusWindowHandler (e) {
|
|
@@ -278,55 +270,35 @@ class Treeselect {
|
|
|
278
270
|
}
|
|
279
271
|
|
|
280
272
|
// Update direction of the list. Support appendToBody and standart mode with absolute
|
|
281
|
-
updateListPosition (
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Append to body handler
|
|
306
|
-
if (!this.#treeselectInitPosition || isNeedForceUpdate) {
|
|
307
|
-
list.style.transform = null
|
|
308
|
-
|
|
309
|
-
const { x: listX, y: listY } = list.getBoundingClientRect()
|
|
310
|
-
const { x: containerX, y: containerY } = container.getBoundingClientRect()
|
|
311
|
-
|
|
312
|
-
this.#treeselectInitPosition = { containerX, containerY, listX, listY }
|
|
273
|
+
updateListPosition () {
|
|
274
|
+
const list = this.#treeselectList.srcElement
|
|
275
|
+
// We need to reset position
|
|
276
|
+
list.style.transform = null
|
|
277
|
+
const container = this.#htmlContainer
|
|
278
|
+
|
|
279
|
+
const { y: listY, height: listHeight } = list.getBoundingClientRect()
|
|
280
|
+
const { x: containerX, y: containerY, height: containerHeight, width: containerWidth } = container.getBoundingClientRect()
|
|
281
|
+
const windowHeight = window.innerHeight
|
|
282
|
+
|
|
283
|
+
const spaceTop = containerY
|
|
284
|
+
const spaceBottom = windowHeight - containerY - containerHeight
|
|
285
|
+
const isTopDirection = spaceTop > spaceBottom && spaceTop >= listHeight && spaceBottom < listHeight
|
|
286
|
+
|
|
287
|
+
if (this.appendToBody) {
|
|
288
|
+
list.style.transform = isTopDirection
|
|
289
|
+
? `translateY(${containerY - listY - listHeight}px)`
|
|
290
|
+
: `translateY(${containerY + containerHeight - listY}px)`
|
|
291
|
+
list.style.width = `${containerWidth}px`
|
|
292
|
+
list.style.left = `${containerX}px`
|
|
313
293
|
}
|
|
314
294
|
|
|
315
|
-
const
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
// TODO you should use css max-height
|
|
319
|
-
// list.style.maxHeight = `${window.innerHeight - containerHeight}px`
|
|
295
|
+
const attributeToAdd = isTopDirection ? 'top' : 'buttom'
|
|
296
|
+
const currentAttr = list.getAttribute('direction')
|
|
320
297
|
|
|
321
|
-
if (
|
|
322
|
-
|
|
323
|
-
this.#
|
|
298
|
+
if (currentAttr !== attributeToAdd) {
|
|
299
|
+
list.setAttribute('direction', attributeToAdd)
|
|
300
|
+
this.#updateDirectionClasses(isTopDirection, this.appendToBody)
|
|
324
301
|
}
|
|
325
|
-
|
|
326
|
-
list.style.transform = isTopDirection ? this.#transform.top : this.#transform.bottom
|
|
327
|
-
this.#updateDirectionClasses(isTopDirection, true)
|
|
328
|
-
list.style.width = `${this.#containerWidth}px`
|
|
329
|
-
list.style.left = `${containerX}px`
|
|
330
302
|
}
|
|
331
303
|
|
|
332
304
|
// Emits
|