kempo-ui 0.0.70 → 0.0.72
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/.github/ISSUE_TEMPLATE/change-request.md +3 -3
- package/.github/workflows/publish.yml +4 -0
- package/.github/workflows/test.yml +23 -0
- package/dist/components/Dropdown.js +3 -1
- package/dist/components/Tree.js +1 -1
- package/dist/utils/formatTimestamp.js +1 -1
- package/docs/components/dropdown.html +5 -0
- package/docs/src/components/Dropdown.js +3 -1
- package/docs/src/components/Tree.js +1 -1
- package/docs/src/utils/formatTimestamp.js +1 -1
- package/package.json +1 -1
- package/src/components/Dropdown.js +2 -31
- package/src/components/Tree.js +11 -4
- package/src/utils/formatTimestamp.js +1 -1
- package/tests/components/Dropdown.browser-test.js +22 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Run Unit Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: '20.x'
|
|
19
|
+
|
|
20
|
+
- run: npm ci
|
|
21
|
+
|
|
22
|
+
- name: Run Unit Tests
|
|
23
|
+
run: npm test
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import{boolTrueFalse}from"../utils/propConverters.js";const openDropdowns=new Set;export default class Dropdown extends ShadowComponent{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:boolTrueFalse},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:boolTrueFalse}};
|
|
1
|
+
import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import{boolTrueFalse}from"../utils/propConverters.js";const openDropdowns=new Set;export default class Dropdown extends ShadowComponent{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:boolTrueFalse},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:boolTrueFalse}};constructor(){super(),this.opened=!1,this.openDirection="down left",this.closeOnSelect=!0,this.closeOnClickOutside=!0}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.handleDocumentClick),document.addEventListener("keydown",this.handleKeydown)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.handleDocumentClick),document.removeEventListener("keydown",this.handleKeydown),openDropdowns.delete(this)}updated(t){super.updated(t),t.has("opened")&&(this.opened?openDropdowns.add(this):openDropdowns.delete(this),this.dispatchEvent(new CustomEvent(this.opened?"opened":"closed",{bubbles:!0})))}handleDocumentClick=t=>{const e=t.target.closest("k-dropdown"),o=t.target.closest('[slot="trigger"]');if(e&&e!==this&&o)return void(this.opened&&this.close());if(!this.opened)return;if(e!==this)return void(this.closeOnClickOutside&&this.close());if(o)return;t.target.closest("a, button")&&this.closeOnSelect&&this.close()};handleTriggerClick=t=>{t.stopPropagation(),this.opened||openDropdowns.forEach(t=>{t!==this&&t.close()}),this.toggle()};handleMenuClick=t=>{const e=t.target.closest("a, button");if(e&&!e.hasAttribute("disabled")){const t=e.dataset?.value||e.textContent.trim();this.dispatchEvent(new CustomEvent("select",{detail:{value:t,item:e},bubbles:!0}))}};handleKeydown=t=>{if(this.opened)if("Escape"===t.key)t.preventDefault(),this.close(),this.focusTrigger();else if("ArrowDown"===t.key)t.preventDefault(),this.focusNextItem();else if("ArrowUp"===t.key)t.preventDefault(),this.focusPreviousItem();else if("Enter"===t.key||" "===t.key){const e=this.querySelector("a:focus, button:focus");e&&(t.preventDefault(),e.click())}};open(){return openDropdowns.forEach(t=>{t!==this&&t.close()}),this.opened=!0,requestAnimationFrame(()=>this.focusFirstItem()),this}close(){return this.opened=!1,this}toggle(){return this.opened?this.close():this.open()}focusTrigger(){const t=this.querySelector('[slot="trigger"]');t&&t.focus()}getMenuItems(){return[...this.querySelectorAll("a, button")].filter(t=>!t.hasAttribute("disabled")&&!t.closest('[slot="trigger"]'))}focusFirstItem(){const t=this.getMenuItems();t.length>0&&t[0].focus()}focusNextItem(){const t=this.getMenuItems(),e=document.activeElement,o=t.indexOf(e),n=t[o+1]||t[0];n&&n.focus()}focusPreviousItem(){const t=this.getMenuItems(),e=document.activeElement,o=t.indexOf(e),n=t[o-1]||t[t.length-1];n&&n.focus()}static styles=css`
|
|
2
2
|
:host {
|
|
3
3
|
display: inline-block;
|
|
4
4
|
position: relative;
|
|
@@ -15,8 +15,10 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
|
|
|
15
15
|
min-width: anchor-size(width);
|
|
16
16
|
background: var(--c_bg);
|
|
17
17
|
border: 1px solid var(--c_border);
|
|
18
|
+
border-radius: var(--radius);
|
|
18
19
|
box-shadow: var(--drop_shadow);
|
|
19
20
|
margin: 0.25rem;
|
|
21
|
+
overflow: hidden;
|
|
20
22
|
}
|
|
21
23
|
:host([opened]) #menu {
|
|
22
24
|
display: block;
|
package/dist/components/Tree.js
CHANGED
|
@@ -6,7 +6,7 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-al
|
|
|
6
6
|
<div class="tree-root">
|
|
7
7
|
${e?e.map(([e,t])=>Tree.renderValue(t,e,1,this.depth)):Tree.renderValue(this.data,null,0,this.depth)}
|
|
8
8
|
</div>
|
|
9
|
-
`}static nodes=[];static addNode=(...e)=>{[...e].reverse().forEach(e=>{Object.prototype.hasOwnProperty.call(e,"nodeTag")||(e.nodeTag="k-tree-node-"+nodeTagCounter++,window.customElements.define(e.nodeTag,e)),Tree.nodes.unshift(e)})};static renderValue(e,t=null,s=0,
|
|
9
|
+
`}static nodes=[];static addNode=(...e)=>{[...e].reverse().forEach(e=>{Object.prototype.hasOwnProperty.call(e,"nodeTag")||(e.nodeTag="k-tree-node-"+nodeTagCounter++,window.customElements.define(e.nodeTag,e)),Tree.nodes.unshift(e)})};static renderValue(e,t=null,s=0,n=0){const r=Tree.nodes.find(t=>t.detect(e));if(r){const s=new r(e),n=null!==t?html`<span class="${"number"==typeof t?"tc-muted":""}">${t}: </span>`:"";return html`<span class="d-b">${n}${s.renderLabel()}</span>`}const a=document.createElement(TreeNode.nodeTag);return a.value=e,a.key=t,a.depth=s,a.maxDepth=n,a}}window.customElements.define("k-tree",Tree);export class TreeNode extends ShadowComponent{static nodeTag="k-tree-node";static properties={value:{type:Object},key:{attribute:!1},depth:{type:Number},maxDepth:{type:Number},opened:{type:Boolean,converter:boolExists,reflect:!0},icon:{type:String}};constructor(e){super(),this.value=void 0!==e?e:null,this.key=null,this.depth=0,this.maxDepth=0,this.opened=!1,this.icon=null}connectedCallback(){super.connectedCallback(),this.depth<=this.maxDepth&&(this.opened=!0)}get tree(){return this.closest("k-tree")}toggle=()=>{this.opened=!this.opened};renderLabel(){return"object"==typeof this.value&&null!==this.value?html`${Array.isArray(this.value)?"Array":"Object"}`:html`${this.value}`}getChildren(){return"object"!=typeof this.value||null===this.value?null:Array.isArray(this.value)?this.value.map((e,t)=>[t,e]):Object.entries(this.value)}renderIcon(){return this.icon?html`<k-icon name="${this.icon}"></k-icon>`:html`<k-icon name="chevron" class="toggle-icon" direction="${this.opened?"down":"right"}"></k-icon>`}render(){const e=this.getChildren(),t=null!==this.key?html`<span class="${"number"==typeof this.key?"tc-muted":""}">${this.key}: </span>`:"";return e?html`
|
|
10
10
|
<div>
|
|
11
11
|
<button class="branch-label no-btn" @click=${this.toggle} aria-expanded="${this.opened}">
|
|
12
12
|
${this.renderIcon()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default(e,i,t)=>{const s=new Date(parseInt(e));if(i){const e=(e,i)=>("000"+e).slice(-1*i),t={YYYY:s.getFullYear(),YY:String(s.getFullYear()).slice(-2),MM:e(s.getMonth()+1,2),M:s.getMonth()+1,DD:e(s.getDate(),2),D:s.getDate(),hh:e(s.getHours(),2),h:s.getHours(),mm:e(s.getMinutes(),2),m:s.getMinutes(),ss:e(s.getSeconds(),2),s:s.getSeconds(),iiii:e(s.getMilliseconds(),3),iii:e(s.getMilliseconds(),3),ii:e(s.getMilliseconds(),2),i:s.getMilliseconds()};return i.replace(/YYYY|YY|MM|M|DD|D|hh|h|mm|m|ss|s|iiii|iii|ii|i/g,e=>t[e])}return s.toLocaleString(t||
|
|
1
|
+
export default(e,i,t)=>{const s=new Date(parseInt(e));if(i){const e=(e,i)=>("000"+e).slice(-1*i),t={YYYY:s.getFullYear(),YY:String(s.getFullYear()).slice(-2),MM:e(s.getMonth()+1,2),M:s.getMonth()+1,DD:e(s.getDate(),2),D:s.getDate(),hh:e(s.getHours(),2),h:s.getHours(),mm:e(s.getMinutes(),2),m:s.getMinutes(),ss:e(s.getSeconds(),2),s:s.getSeconds(),iiii:e(s.getMilliseconds(),3),iii:e(s.getMilliseconds(),3),ii:e(s.getMilliseconds(),2),i:s.getMilliseconds()};return i.replace(/YYYY|YY|MM|M|DD|D|hh|h|mm|m|ss|s|iiii|iii|ii|i/g,e=>t[e])}return s.toLocaleString(t||Intl.DateTimeFormat().resolvedOptions().locale)};
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
<a href="#attributes">Attributes</a><br />
|
|
36
36
|
<a href="#methods">Methods</a><br />
|
|
37
37
|
<a href="#eventsRef">Events</a><br />
|
|
38
|
+
<a href="#cssVars">CSS Custom Properties</a><br />
|
|
38
39
|
</div>
|
|
39
40
|
</k-accordion-panel>
|
|
40
41
|
</k-accordion>
|
|
@@ -270,6 +271,10 @@
|
|
|
270
271
|
<li><code>Escape</code> - Close the dropdown</li>
|
|
271
272
|
</ul>
|
|
272
273
|
|
|
274
|
+
<h3 id="cssVars"><a href="#cssVars" class="no-link">CSS Custom Properties</a></h3>
|
|
275
|
+
<h5><code>--radius</code></h5>
|
|
276
|
+
<p>Controls the border radius of the dropdown menu. Defaults to the global <code>--radius</code> value.</p>
|
|
277
|
+
|
|
273
278
|
</main>
|
|
274
279
|
<div style="height:33vh"></div>
|
|
275
280
|
<script type="module" src="../src/components/Dropdown.js"></script>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import{boolTrueFalse}from"../utils/propConverters.js";const openDropdowns=new Set;export default class Dropdown extends ShadowComponent{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:boolTrueFalse},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:boolTrueFalse}};
|
|
1
|
+
import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import{boolTrueFalse}from"../utils/propConverters.js";const openDropdowns=new Set;export default class Dropdown extends ShadowComponent{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:boolTrueFalse},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:boolTrueFalse}};constructor(){super(),this.opened=!1,this.openDirection="down left",this.closeOnSelect=!0,this.closeOnClickOutside=!0}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.handleDocumentClick),document.addEventListener("keydown",this.handleKeydown)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.handleDocumentClick),document.removeEventListener("keydown",this.handleKeydown),openDropdowns.delete(this)}updated(t){super.updated(t),t.has("opened")&&(this.opened?openDropdowns.add(this):openDropdowns.delete(this),this.dispatchEvent(new CustomEvent(this.opened?"opened":"closed",{bubbles:!0})))}handleDocumentClick=t=>{const e=t.target.closest("k-dropdown"),o=t.target.closest('[slot="trigger"]');if(e&&e!==this&&o)return void(this.opened&&this.close());if(!this.opened)return;if(e!==this)return void(this.closeOnClickOutside&&this.close());if(o)return;t.target.closest("a, button")&&this.closeOnSelect&&this.close()};handleTriggerClick=t=>{t.stopPropagation(),this.opened||openDropdowns.forEach(t=>{t!==this&&t.close()}),this.toggle()};handleMenuClick=t=>{const e=t.target.closest("a, button");if(e&&!e.hasAttribute("disabled")){const t=e.dataset?.value||e.textContent.trim();this.dispatchEvent(new CustomEvent("select",{detail:{value:t,item:e},bubbles:!0}))}};handleKeydown=t=>{if(this.opened)if("Escape"===t.key)t.preventDefault(),this.close(),this.focusTrigger();else if("ArrowDown"===t.key)t.preventDefault(),this.focusNextItem();else if("ArrowUp"===t.key)t.preventDefault(),this.focusPreviousItem();else if("Enter"===t.key||" "===t.key){const e=this.querySelector("a:focus, button:focus");e&&(t.preventDefault(),e.click())}};open(){return openDropdowns.forEach(t=>{t!==this&&t.close()}),this.opened=!0,requestAnimationFrame(()=>this.focusFirstItem()),this}close(){return this.opened=!1,this}toggle(){return this.opened?this.close():this.open()}focusTrigger(){const t=this.querySelector('[slot="trigger"]');t&&t.focus()}getMenuItems(){return[...this.querySelectorAll("a, button")].filter(t=>!t.hasAttribute("disabled")&&!t.closest('[slot="trigger"]'))}focusFirstItem(){const t=this.getMenuItems();t.length>0&&t[0].focus()}focusNextItem(){const t=this.getMenuItems(),e=document.activeElement,o=t.indexOf(e),n=t[o+1]||t[0];n&&n.focus()}focusPreviousItem(){const t=this.getMenuItems(),e=document.activeElement,o=t.indexOf(e),n=t[o-1]||t[t.length-1];n&&n.focus()}static styles=css`
|
|
2
2
|
:host {
|
|
3
3
|
display: inline-block;
|
|
4
4
|
position: relative;
|
|
@@ -15,8 +15,10 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
|
|
|
15
15
|
min-width: anchor-size(width);
|
|
16
16
|
background: var(--c_bg);
|
|
17
17
|
border: 1px solid var(--c_border);
|
|
18
|
+
border-radius: var(--radius);
|
|
18
19
|
box-shadow: var(--drop_shadow);
|
|
19
20
|
margin: 0.25rem;
|
|
21
|
+
overflow: hidden;
|
|
20
22
|
}
|
|
21
23
|
:host([opened]) #menu {
|
|
22
24
|
display: block;
|
|
@@ -6,7 +6,7 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-al
|
|
|
6
6
|
<div class="tree-root">
|
|
7
7
|
${e?e.map(([e,t])=>Tree.renderValue(t,e,1,this.depth)):Tree.renderValue(this.data,null,0,this.depth)}
|
|
8
8
|
</div>
|
|
9
|
-
`}static nodes=[];static addNode=(...e)=>{[...e].reverse().forEach(e=>{Object.prototype.hasOwnProperty.call(e,"nodeTag")||(e.nodeTag="k-tree-node-"+nodeTagCounter++,window.customElements.define(e.nodeTag,e)),Tree.nodes.unshift(e)})};static renderValue(e,t=null,s=0,
|
|
9
|
+
`}static nodes=[];static addNode=(...e)=>{[...e].reverse().forEach(e=>{Object.prototype.hasOwnProperty.call(e,"nodeTag")||(e.nodeTag="k-tree-node-"+nodeTagCounter++,window.customElements.define(e.nodeTag,e)),Tree.nodes.unshift(e)})};static renderValue(e,t=null,s=0,n=0){const r=Tree.nodes.find(t=>t.detect(e));if(r){const s=new r(e),n=null!==t?html`<span class="${"number"==typeof t?"tc-muted":""}">${t}: </span>`:"";return html`<span class="d-b">${n}${s.renderLabel()}</span>`}const a=document.createElement(TreeNode.nodeTag);return a.value=e,a.key=t,a.depth=s,a.maxDepth=n,a}}window.customElements.define("k-tree",Tree);export class TreeNode extends ShadowComponent{static nodeTag="k-tree-node";static properties={value:{type:Object},key:{attribute:!1},depth:{type:Number},maxDepth:{type:Number},opened:{type:Boolean,converter:boolExists,reflect:!0},icon:{type:String}};constructor(e){super(),this.value=void 0!==e?e:null,this.key=null,this.depth=0,this.maxDepth=0,this.opened=!1,this.icon=null}connectedCallback(){super.connectedCallback(),this.depth<=this.maxDepth&&(this.opened=!0)}get tree(){return this.closest("k-tree")}toggle=()=>{this.opened=!this.opened};renderLabel(){return"object"==typeof this.value&&null!==this.value?html`${Array.isArray(this.value)?"Array":"Object"}`:html`${this.value}`}getChildren(){return"object"!=typeof this.value||null===this.value?null:Array.isArray(this.value)?this.value.map((e,t)=>[t,e]):Object.entries(this.value)}renderIcon(){return this.icon?html`<k-icon name="${this.icon}"></k-icon>`:html`<k-icon name="chevron" class="toggle-icon" direction="${this.opened?"down":"right"}"></k-icon>`}render(){const e=this.getChildren(),t=null!==this.key?html`<span class="${"number"==typeof this.key?"tc-muted":""}">${this.key}: </span>`:"";return e?html`
|
|
10
10
|
<div>
|
|
11
11
|
<button class="branch-label no-btn" @click=${this.toggle} aria-expanded="${this.opened}">
|
|
12
12
|
${this.renderIcon()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default(e,i,t)=>{const s=new Date(parseInt(e));if(i){const e=(e,i)=>("000"+e).slice(-1*i),t={YYYY:s.getFullYear(),YY:String(s.getFullYear()).slice(-2),MM:e(s.getMonth()+1,2),M:s.getMonth()+1,DD:e(s.getDate(),2),D:s.getDate(),hh:e(s.getHours(),2),h:s.getHours(),mm:e(s.getMinutes(),2),m:s.getMinutes(),ss:e(s.getSeconds(),2),s:s.getSeconds(),iiii:e(s.getMilliseconds(),3),iii:e(s.getMilliseconds(),3),ii:e(s.getMilliseconds(),2),i:s.getMilliseconds()};return i.replace(/YYYY|YY|MM|M|DD|D|hh|h|mm|m|ss|s|iiii|iii|ii|i/g,e=>t[e])}return s.toLocaleString(t||
|
|
1
|
+
export default(e,i,t)=>{const s=new Date(parseInt(e));if(i){const e=(e,i)=>("000"+e).slice(-1*i),t={YYYY:s.getFullYear(),YY:String(s.getFullYear()).slice(-2),MM:e(s.getMonth()+1,2),M:s.getMonth()+1,DD:e(s.getDate(),2),D:s.getDate(),hh:e(s.getHours(),2),h:s.getHours(),mm:e(s.getMinutes(),2),m:s.getMinutes(),ss:e(s.getSeconds(),2),s:s.getSeconds(),iiii:e(s.getMilliseconds(),3),iii:e(s.getMilliseconds(),3),ii:e(s.getMilliseconds(),2),i:s.getMilliseconds()};return i.replace(/YYYY|YY|MM|M|DD|D|hh|h|mm|m|ss|s|iiii|iii|ii|i/g,e=>t[e])}return s.toLocaleString(t||Intl.DateTimeFormat().resolvedOptions().locale)};
|
package/package.json
CHANGED
|
@@ -13,8 +13,6 @@ export default class Dropdown extends ShadowComponent {
|
|
|
13
13
|
closeOnClickOutside: { type: Boolean, reflect: true, attribute: 'close-on-click-outside', converter: boolTrueFalse }
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
anchorId = `dropdown-anchor-${Math.random().toString(36).slice(2, 11)}`;
|
|
17
|
-
|
|
18
16
|
constructor() {
|
|
19
17
|
super();
|
|
20
18
|
this.opened = false;
|
|
@@ -182,35 +180,6 @@ export default class Dropdown extends ShadowComponent {
|
|
|
182
180
|
if(prev) prev.focus();
|
|
183
181
|
}
|
|
184
182
|
|
|
185
|
-
getPositionArea() {
|
|
186
|
-
const dir = this.openDirection.toLowerCase().trim();
|
|
187
|
-
const parts = dir.split(/\s+/);
|
|
188
|
-
// Map friendly names to position-area values
|
|
189
|
-
const mapping = {
|
|
190
|
-
'down': 'bottom',
|
|
191
|
-
'up': 'top',
|
|
192
|
-
'left': 'left',
|
|
193
|
-
'right': 'right',
|
|
194
|
-
'center': 'center'
|
|
195
|
-
};
|
|
196
|
-
const mapped = parts.map(p => mapping[p] || p);
|
|
197
|
-
// position-area expects: row column (e.g., "bottom left")
|
|
198
|
-
// "down left" -> "bottom left", "up right" -> "top right"
|
|
199
|
-
return mapped.join(' ');
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
getFallbacks() {
|
|
203
|
-
const primary = this.getPositionArea();
|
|
204
|
-
const parts = primary.split(' ');
|
|
205
|
-
// Generate sensible fallbacks
|
|
206
|
-
const fallbacks = [];
|
|
207
|
-
// flip-block flips vertical, flip-inline flips horizontal
|
|
208
|
-
fallbacks.push('flip-block');
|
|
209
|
-
fallbacks.push('flip-inline');
|
|
210
|
-
fallbacks.push('flip-block flip-inline');
|
|
211
|
-
return fallbacks.join(', ');
|
|
212
|
-
}
|
|
213
|
-
|
|
214
183
|
/*
|
|
215
184
|
Styles
|
|
216
185
|
*/
|
|
@@ -231,8 +200,10 @@ export default class Dropdown extends ShadowComponent {
|
|
|
231
200
|
min-width: anchor-size(width);
|
|
232
201
|
background: var(--c_bg);
|
|
233
202
|
border: 1px solid var(--c_border);
|
|
203
|
+
border-radius: var(--radius);
|
|
234
204
|
box-shadow: var(--drop_shadow);
|
|
235
205
|
margin: 0.25rem;
|
|
206
|
+
overflow: hidden;
|
|
236
207
|
}
|
|
237
208
|
:host([opened]) #menu {
|
|
238
209
|
display: block;
|
package/src/components/Tree.js
CHANGED
|
@@ -59,8 +59,15 @@ export default class Tree extends ShadowComponent {
|
|
|
59
59
|
|
|
60
60
|
/* Static Methods */
|
|
61
61
|
static renderValue(value, key = null, depth = 0, maxDepth = 0){
|
|
62
|
-
const
|
|
63
|
-
|
|
62
|
+
const LeafClass = Tree.nodes.find(n => n.detect(value));
|
|
63
|
+
if(LeafClass){
|
|
64
|
+
const instance = new LeafClass(value);
|
|
65
|
+
const keyLabel = key !== null
|
|
66
|
+
? html`<span class="${typeof key === 'number' ? 'tc-muted' : ''}">${key}: </span>`
|
|
67
|
+
: '';
|
|
68
|
+
return html`<span class="d-b">${keyLabel}${instance.renderLabel()}</span>`;
|
|
69
|
+
}
|
|
70
|
+
const el = document.createElement(TreeNode.nodeTag);
|
|
64
71
|
el.value = value;
|
|
65
72
|
el.key = key;
|
|
66
73
|
el.depth = depth;
|
|
@@ -84,9 +91,9 @@ export class TreeNode extends ShadowComponent {
|
|
|
84
91
|
icon: { type: String }
|
|
85
92
|
};
|
|
86
93
|
|
|
87
|
-
constructor(){
|
|
94
|
+
constructor(value){
|
|
88
95
|
super();
|
|
89
|
-
this.value = null;
|
|
96
|
+
this.value = value !== undefined ? value : null;
|
|
90
97
|
this.key = null;
|
|
91
98
|
this.depth = 0;
|
|
92
99
|
this.maxDepth = 0;
|
|
@@ -22,6 +22,6 @@ export default (timestamp, format, forceLocale) => {
|
|
|
22
22
|
};
|
|
23
23
|
return format.replace(/YYYY|YY|MM|M|DD|D|hh|h|mm|m|ss|s|iiii|iii|ii|i/g, (matched) => tokens[matched]);
|
|
24
24
|
} else {
|
|
25
|
-
return date.toLocaleString(forceLocale ||
|
|
25
|
+
return date.toLocaleString(forceLocale || Intl.DateTimeFormat().resolvedOptions().locale);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -537,6 +537,28 @@ export default {
|
|
|
537
537
|
pass('All open-direction values accepted');
|
|
538
538
|
},
|
|
539
539
|
|
|
540
|
+
/*
|
|
541
|
+
Styles
|
|
542
|
+
*/
|
|
543
|
+
'menu should have border-radius using --radius': async ({pass, fail}) => {
|
|
544
|
+
const { container, dropdown } = await createDropdown();
|
|
545
|
+
const menu = dropdown.shadowRoot.querySelector('#menu');
|
|
546
|
+
if(!menu) {
|
|
547
|
+
cleanup(container);
|
|
548
|
+
return fail('Menu element should exist');
|
|
549
|
+
}
|
|
550
|
+
document.documentElement.style.setProperty('--radius', '8px');
|
|
551
|
+
const styles = window.getComputedStyle(menu);
|
|
552
|
+
const borderRadius = styles.borderRadius;
|
|
553
|
+
document.documentElement.style.removeProperty('--radius');
|
|
554
|
+
if(borderRadius !== '8px') {
|
|
555
|
+
cleanup(container);
|
|
556
|
+
return fail(`Expected menu border-radius to use --radius (8px), got ${borderRadius}`);
|
|
557
|
+
}
|
|
558
|
+
cleanup(container);
|
|
559
|
+
pass('Menu has border-radius applied using --radius');
|
|
560
|
+
},
|
|
561
|
+
|
|
540
562
|
/*
|
|
541
563
|
Disabled Items
|
|
542
564
|
*/
|