Skip to content

Commit d2cdbe4

Browse files
committed
Various updates.
1 parent be0296d commit d2cdbe4

File tree

9 files changed

+143
-37
lines changed

9 files changed

+143
-37
lines changed

src/pg/scroll/__examples__/basic/basic.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default class XPgScrollBasic extends HTMLElement {
7070
}
7171
this.$scrollList.style.transform = `translateY(${-1 * offsetY % 44}px)`;
7272
});
73-
function overflow(overflowText) {
73+
const overflow = (overflowText) => {
7474
if (overflowText === 'auto') {
7575
this.$overflowContainer.style.overflow = 'auto';
7676
this.$overflowContainer.style.height = '300px';

src/pg/tabs/tabs.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ export default class PgTabs extends HTMLElement {
1515
@Part() $tabset: HTMLUListElement;
1616
@Part() $slot: HTMLSlotElement;
1717

18-
@Prop()
19-
#tabs: any[] = [];
18+
@Prop() tabs: any[] = [];
2019

2120
#selectedTab: number = 0;
2221
#focusedTab: number = 0;
@@ -26,11 +25,10 @@ export default class PgTabs extends HTMLElement {
2625
this.$slot.addEventListener('slotchange', this.handleSlotChange.bind(this));
2726
forEach({
2827
container: this.$tabset,
29-
items: this.#tabs,
30-
type: (tab: any) => {
28+
items: this.tabs,
29+
type(tab: any) {
3130
return PgPartialTab;
3231
},
33-
// @ts-ignore
3432
connect: ($tab, tab, $tabs: PgPartialTab[]) => {
3533
$tab.addEventListener('select', (e: any) => {
3634
const { index } = e.detail;
@@ -43,9 +41,9 @@ export default class PgTabs extends HTMLElement {
4341
});
4442
$tab.addEventListener('arrowleft', (e: any) => {
4543
const { index } = e.detail;
46-
if (this.#tabs.length > 1) {
44+
if (this.tabs.length > 1) {
4745
if (index === 0) {
48-
this.#focusedTab = this.#tabs.length - 1;
46+
this.#focusedTab = this.tabs.length - 1;
4947
} else {
5048
this.#focusedTab = index - 1;
5149
}
@@ -54,8 +52,8 @@ export default class PgTabs extends HTMLElement {
5452
});
5553
$tab.addEventListener('arrowright', (e: any) => {
5654
const { index } = e.detail;
57-
if (this.#tabs.length > 1) {
58-
if (index === this.#tabs.length - 1) {
55+
if (this.tabs.length > 1) {
56+
if (index === this.tabs.length - 1) {
5957
this.#focusedTab = 0;
6058
} else {
6159
this.#focusedTab++;
@@ -69,7 +67,7 @@ export default class PgTabs extends HTMLElement {
6967

7068
#handleTab(e: CustomEvent) {
7169
const { detail } = e;
72-
this.#tabs.push(detail);
70+
this.tabs.push(detail);
7371
e.stopPropagation();
7472
}
7573

src/pg/toast/__examples__/basic/basic.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
<button part="toastWarning">Warning</button>
44
<button part="toastError">Error</button>
55
<button part="toastLoading">Loading (mock 3 seconds)</button>
6-
<button part="toggleToast">Toggle Toast</button>
6+
<button part="toastToggle">Toggle Toast</button>
77
</div>

src/pg/tree/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
# Tree
22

3-
The `pg-tree` is used to render a tree list of items.
3+
The `pg-tree` is used to render a tree list of items.
4+
5+
## Usage
6+

src/pg/tree/__examples__/basic/basic.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import template from './basic.html';
55
import PgTreeButtonIcon from '../../../treeButtonIcon/treeButtonIcon';
66

77
const IconAccount = 'M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z';
8+
const IconFile = 'M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z';
9+
const IconFolder = 'M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z';
810
const IconEye = 'M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z';
911
const IconEyeOff = 'M2,5.27L3.28,4L20,20.72L18.73,22L15.65,18.92C14.5,19.3 13.28,19.5 12,19.5C7,19.5 2.73,16.39 1,12C1.69,10.24 2.79,8.69 4.19,7.46L2,5.27M12,9A3,3 0 0,1 15,12C15,12.35 14.94,12.69 14.83,13L11,9.17C11.31,9.06 11.65,9 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.18,14.08 20.79,15.88 19,17.19L17.58,15.76C18.94,14.82 20.06,13.54 20.82,12C19.17,8.64 15.76,6.5 12,6.5C10.91,6.5 9.84,6.68 8.84,7L7.3,5.47C8.74,4.85 10.33,4.5 12,4.5M3.18,12C4.83,15.36 8.24,17.5 12,17.5C12.69,17.5 13.37,17.43 14,17.29L11.72,15C10.29,14.85 9.15,13.71 9,12.28L5.6,8.87C4.61,9.72 3.78,10.78 3.18,12Z';
1012
const IconLock = 'M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z';
@@ -29,14 +31,18 @@ function createItem(label, expanded = false) {
2931
enabled: false
3032
}],
3133
items: [{
32-
label: 'Sub Item 1'
34+
label: 'Sub Item 1',
35+
icon: { path: IconFile },
3336
}, {
3437
label: 'Sub Item 2',
38+
icon: { path: IconFolder },
3539
items: [{
3640
label: 'Sub Item ?',
41+
icon: { path: IconFile },
3742
}]
3843
}, {
39-
label: 'Sub Item 3'
44+
label: 'Sub Item 3',
45+
icon: { path: IconFile },
4046
}]
4147
};
4248
}
@@ -51,6 +57,8 @@ export default class XPgTreeBasic extends HTMLElement {
5157
@Part() $removeItem: HTMLButtonElement;
5258
@Part() $updateItem: HTMLButtonElement;
5359

60+
#selectedItems = [];
61+
5462
connectedCallback() {
5563
this.$tree.addEventListener('action', (e: any) => {
5664
// action clicked
@@ -77,20 +85,13 @@ export default class XPgTreeBasic extends HTMLElement {
7785
const item = this.#getItem(indexes);
7886
item.label = label;
7987
});
80-
let previousIndexes = null;
81-
this.$tree.addEventListener('select', (e: any) => {
82-
const { indexes } = e.detail;
83-
const item = this.#getItem(indexes);
84-
item.selected = true;
85-
if (previousIndexes) {
86-
const previousItem = this.#getItem(previousIndexes);
87-
previousItem.selected = false;
88-
}
89-
previousIndexes = indexes;
90-
});
9188
this.$tree.addEventListener('menu', (e: any) => {
9289
// action clicked
9390
});
91+
this.$tree.addEventListener('select', (e: any) => {
92+
console.log(e.detail.items.size);
93+
this.#selectedItems = Array.from(e.detail.items);
94+
});
9495
this.$tree.items = [
9596
createItem('Item 1', true),
9697
createItem('Item 2')
@@ -108,7 +109,10 @@ export default class XPgTreeBasic extends HTMLElement {
108109

109110
let updatedTimes = 0;
110111
this.$updateItem.addEventListener('click', () => {
111-
this.$tree.items[1].label = `Updated ${updatedTimes++}`;
112+
this.#selectedItems.forEach((selected) => {
113+
const item = this.#getItem(selected);
114+
item.label = `Updated ${updatedTimes++}`;
115+
});
112116
});
113117
}
114118

src/pg/tree/tree.ts

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { Component, Prop, Part, forEach } from '@pictogrammers/element';
1+
import { Component, Prop, Part, forEach, getProxyValue } from '@pictogrammers/element';
2+
3+
import PgTreeItem from '../treeItem/treeItem';
24

35
import template from './tree.html';
46
import style from './tree.css';
5-
import PgTreeItem from '../treeItem/treeItem';
67

78
@Component({
89
selector: 'pg-tree',
@@ -14,6 +15,9 @@ export default class PgTree extends HTMLElement {
1415

1516
@Part() $items: HTMLDivElement;
1617

18+
#selected = new Set();
19+
#selectedIndexes = new Map();
20+
1721
connectedCallback() {
1822
forEach({
1923
container: this.$items,
@@ -22,11 +26,54 @@ export default class PgTree extends HTMLElement {
2226
return PgTreeItem;
2327
}
2428
});
25-
this.addEventListener('toggle', (e: any) => {
29+
this.$items.addEventListener('toggle', (e: any) => {
2630
const { indexes } = e.detail;
2731
let item = this.#getItem(indexes);
2832
item.expanded = !item.expanded;
29-
})
33+
});
34+
this.$items.addEventListener('select', (e: any) => {
35+
e.stopPropagation();
36+
const { indexes, type, ctrlKey, shiftKey } = e.detail;
37+
const item = this.#getItem(indexes);
38+
const selectedCount = this.#selected.size;
39+
const unproxyItem = getProxyValue(item);
40+
if (!ctrlKey && selectedCount && !this.#selected.has(unproxyItem)) {
41+
this.#selected.forEach((x: any) => x.selected = false);
42+
this.#selected.clear();
43+
this.#selectedIndexes.clear();
44+
}
45+
item.selected = type === 'rename' ? true : !item.selected;
46+
if (item.selected) {
47+
this.#selected.add(item);
48+
this.#selectedIndexes.set(unproxyItem, indexes);
49+
} else {
50+
this.#selected.delete(item);
51+
this.#selectedIndexes.delete(unproxyItem);
52+
}
53+
// Dispatch Event
54+
this.dispatchEvent(new CustomEvent('select', {
55+
detail: {
56+
items: this.#selected
57+
}
58+
}));
59+
});
60+
this.$items.addEventListener('keydown', (e: any) => {
61+
if (e.key === 'Delete') {
62+
this.items[0].items.pop();
63+
/*this.#selected.forEach((item: any) => {
64+
const ind = this.#selectedIndexes.get(item);
65+
ind.reduce((item: any, index, i) => {
66+
console.log(item.item, index, i, ind.length, arguments);
67+
if (i === ind.length - 1) {
68+
item.items.pop();
69+
//item.items.slice(index, 1);
70+
return;
71+
}
72+
return item.items[index];
73+
}, this);
74+
});*/
75+
}
76+
});
3077
}
3178

3279
#getItem(indexes: number[]) {
@@ -40,4 +87,8 @@ export default class PgTree extends HTMLElement {
4087
console.log('yay', this.items.map(x => x));
4188
}
4289
}
90+
91+
unselect(indexes: number[]) {
92+
93+
}
4394
}

src/pg/treeItem/treeItem.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@
2323
background: transparent;
2424
border: 0;
2525
color: var(--pg-tree-item-color, #453C4F);
26-
padding: 0;
2726
--pg-icon-color: var(--pg-tree-item-color, #453C4F);
2827
flex: 1;
2928
align-items: center;
3029
font-family: var(--pg-font-family);
3130
font-size: var(--pg-tree-item-font-size, 1rem);
31+
margin: -0.25rem -0.75rem -0.25rem -0.25rem;
32+
padding: 0 0.75rem 0 0.25rem;
3233
}
3334

3435
[part=input] {
@@ -55,7 +56,8 @@
5556

5657
[part=item] {
5758
user-select: none;
58-
padding-left: calc((var(--x) * 0.5rem) + 0.25rem)
59+
padding-left: calc((var(--x) * 0.5rem) + 0.25rem);
60+
transition: background-color 0.1s ease-out;
5961
}
6062

6163
[part=item]:hover {

src/pg/treeItem/treeItem.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</button>
66
<input part="input" type="input" class="hide" />
77
<button part="labelButton">
8-
<div part="label"></div>
8+
<span part="label"></span>
99
</button>
1010
<div part="actions"></div>
1111
</div>

src/pg/treeItem/treeItem.ts

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ export default class PgTreeItem extends HTMLElement {
3535
connectedCallback() {
3636
this.$toggle.addEventListener('click', this.#handleToggleClick.bind(this));
3737
this.$item.addEventListener('action', this.#handleAction.bind(this));
38+
this.$item.addEventListener('pointerenter', this.#handlePointerEnter.bind(this));
39+
this.$item.addEventListener('pointerleave', this.#handlePointerLeave.bind(this));
3840
this.$labelButton.addEventListener('dblclick', this.#handleDoubleClick.bind(this));
3941
this.$labelButton.addEventListener('click', this.#handleClick.bind(this));
4042
this.$iconButton.addEventListener('dblclick', this.#handleIconDoubleClick.bind(this));
4143
this.$iconButton.addEventListener('click', this.#handleIconClick.bind(this));
44+
this.$iconButton.addEventListener('keydown', this.#handleIconKeyDown.bind(this));
4245
this.$item.addEventListener('contextmenu', this.#handleContextMenu.bind(this));
4346
this.$input.addEventListener('blur', this.#handleBlur.bind(this));
4447
this.$input.addEventListener('keydown', this.#handleInputKeyDown.bind(this));
@@ -105,7 +108,11 @@ export default class PgTreeItem extends HTMLElement {
105108
}));
106109
}
107110

108-
#handleIconDoubleClick() {
111+
#handleIconDoubleClick(e: MouseEvent) {
112+
const { ctrlKey, shiftKey } = e;
113+
if (ctrlKey || shiftKey) {
114+
return;
115+
}
109116
this.dispatchEvent(new CustomEvent('select', {
110117
bubbles: true,
111118
composed: true,
@@ -127,12 +134,39 @@ export default class PgTreeItem extends HTMLElement {
127134
}));
128135
}
129136

130-
#handleClick() {
137+
#handleClick(e: MouseEvent) {
138+
if (this.#ignoreNextClick) {
139+
this.#ignoreNextClick = false;
140+
return;
141+
}
142+
const { ctrlKey, shiftKey } = e;
131143
this.dispatchEvent(new CustomEvent('select', {
132144
bubbles: true,
133145
composed: true,
134146
detail: {
135147
type: 'label',
148+
indexes: [this.index],
149+
ctrlKey,
150+
shiftKey
151+
}
152+
}));
153+
}
154+
155+
#handlePointerEnter() {
156+
this.dispatchEvent(new CustomEvent('enter', {
157+
bubbles: true,
158+
composed: true,
159+
detail: {
160+
indexes: [this.index]
161+
}
162+
}));
163+
}
164+
165+
#handlePointerLeave() {
166+
this.dispatchEvent(new CustomEvent('leave', {
167+
bubbles: true,
168+
composed: true,
169+
detail: {
136170
indexes: [this.index]
137171
}
138172
}));
@@ -174,12 +208,26 @@ export default class PgTreeItem extends HTMLElement {
174208
e.preventDefault();
175209
}
176210

177-
#handleDoubleClick(e) {
211+
#ignoreNextClick = false;
212+
#handleDoubleClick(e: MouseEvent) {
213+
const { ctrlKey, shiftKey } = e;
214+
if (ctrlKey || shiftKey) {
215+
return;
216+
}
178217
this.$labelButton.classList.add('hide');
179218
this.$actions.classList.add('hide');
180219
this.$input.classList.remove('hide');
181220
this.$input.value = this.label;
182221
this.$input.select();
222+
this.#ignoreNextClick = true;
223+
this.dispatchEvent(new CustomEvent('select', {
224+
bubbles: true,
225+
composed: true,
226+
detail: {
227+
type: 'rename',
228+
indexes: [this.index]
229+
}
230+
}));
183231
e.preventDefault();
184232
}
185233

0 commit comments

Comments
 (0)