mtrl-addons 0.1.2 → 0.2.1
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/build.js +139 -86
- package/package.json +13 -4
- package/scripts/debug/vlist-selection.ts +121 -0
- package/src/components/index.ts +5 -41
- package/src/components/{list → vlist}/config.ts +66 -95
- package/src/components/vlist/constants.ts +23 -0
- package/src/components/vlist/features/api.ts +322 -0
- package/src/components/vlist/features/index.ts +10 -0
- package/src/components/vlist/features/selection.ts +444 -0
- package/src/components/vlist/features/viewport.ts +65 -0
- package/src/components/vlist/index.ts +16 -0
- package/src/components/{list → vlist}/types.ts +104 -26
- package/src/components/vlist/vlist.ts +92 -0
- package/src/core/compose/features/gestures/index.ts +227 -0
- package/src/core/compose/features/gestures/longpress.ts +383 -0
- package/src/core/compose/features/gestures/pan.ts +424 -0
- package/src/core/compose/features/gestures/pinch.ts +475 -0
- package/src/core/compose/features/gestures/rotate.ts +485 -0
- package/src/core/compose/features/gestures/swipe.ts +492 -0
- package/src/core/compose/features/gestures/tap.ts +334 -0
- package/src/core/compose/features/index.ts +2 -38
- package/src/core/compose/index.ts +13 -29
- package/src/core/gestures/index.ts +31 -0
- package/src/core/gestures/longpress.ts +68 -0
- package/src/core/gestures/manager.ts +418 -0
- package/src/core/gestures/pan.ts +48 -0
- package/src/core/gestures/pinch.ts +58 -0
- package/src/core/gestures/rotate.ts +58 -0
- package/src/core/gestures/swipe.ts +66 -0
- package/src/core/gestures/tap.ts +45 -0
- package/src/core/gestures/types.ts +387 -0
- package/src/core/gestures/utils.ts +128 -0
- package/src/core/index.ts +27 -151
- package/src/core/layout/schema.ts +73 -35
- package/src/core/layout/types.ts +5 -2
- package/src/core/viewport/constants.ts +140 -0
- package/src/core/viewport/features/base.ts +73 -0
- package/src/core/viewport/features/collection.ts +882 -0
- package/src/core/viewport/features/events.ts +130 -0
- package/src/core/viewport/features/index.ts +20 -0
- package/src/core/{list-manager/features/viewport → viewport/features}/item-size.ts +27 -30
- package/src/core/{list-manager/features/viewport → viewport/features}/loading.ts +4 -4
- package/src/core/viewport/features/momentum.ts +260 -0
- package/src/core/viewport/features/placeholders.ts +335 -0
- package/src/core/viewport/features/rendering.ts +568 -0
- package/src/core/viewport/features/scrollbar.ts +434 -0
- package/src/core/viewport/features/scrolling.ts +618 -0
- package/src/core/viewport/features/utils.ts +88 -0
- package/src/core/viewport/features/virtual.ts +384 -0
- package/src/core/viewport/index.ts +31 -0
- package/src/core/viewport/types.ts +133 -0
- package/src/core/viewport/utils/speed-tracker.ts +79 -0
- package/src/core/viewport/viewport.ts +246 -0
- package/src/index.ts +0 -7
- package/src/styles/components/_vlist.scss +331 -0
- package/src/styles/index.scss +1 -1
- package/test/components/vlist-selection.test.ts +240 -0
- package/test/components/vlist.test.ts +63 -0
- package/test/core/collection/adapter.test.ts +161 -0
- package/bun.lock +0 -792
- package/src/components/list/api.ts +0 -314
- package/src/components/list/constants.ts +0 -56
- package/src/components/list/features/api.ts +0 -428
- package/src/components/list/features/index.ts +0 -31
- package/src/components/list/features/list-manager.ts +0 -502
- package/src/components/list/index.ts +0 -39
- package/src/components/list/list.ts +0 -234
- package/src/core/collection/base-collection.ts +0 -100
- package/src/core/collection/collection-composer.ts +0 -178
- package/src/core/collection/collection.ts +0 -745
- package/src/core/collection/constants.ts +0 -172
- package/src/core/collection/events.ts +0 -428
- package/src/core/collection/features/api/loading.ts +0 -279
- package/src/core/collection/features/operations/data-operations.ts +0 -147
- package/src/core/collection/index.ts +0 -104
- package/src/core/collection/state.ts +0 -497
- package/src/core/collection/types.ts +0 -404
- package/src/core/compose/features/collection.ts +0 -119
- package/src/core/compose/features/selection.ts +0 -213
- package/src/core/compose/features/styling.ts +0 -108
- package/src/core/list-manager/api.ts +0 -599
- package/src/core/list-manager/config.ts +0 -593
- package/src/core/list-manager/constants.ts +0 -268
- package/src/core/list-manager/features/api.ts +0 -58
- package/src/core/list-manager/features/collection/collection.ts +0 -705
- package/src/core/list-manager/features/collection/index.ts +0 -17
- package/src/core/list-manager/features/viewport/constants.ts +0 -42
- package/src/core/list-manager/features/viewport/index.ts +0 -16
- package/src/core/list-manager/features/viewport/placeholders.ts +0 -281
- package/src/core/list-manager/features/viewport/rendering.ts +0 -575
- package/src/core/list-manager/features/viewport/scrollbar.ts +0 -495
- package/src/core/list-manager/features/viewport/scrolling.ts +0 -795
- package/src/core/list-manager/features/viewport/template.ts +0 -220
- package/src/core/list-manager/features/viewport/viewport.ts +0 -654
- package/src/core/list-manager/features/viewport/virtual.ts +0 -309
- package/src/core/list-manager/index.ts +0 -279
- package/src/core/list-manager/list-manager.ts +0 -206
- package/src/core/list-manager/types.ts +0 -439
- package/src/core/list-manager/utils/calculations.ts +0 -290
- package/src/core/list-manager/utils/range-calculator.ts +0 -349
- package/src/core/list-manager/utils/speed-tracker.ts +0 -273
- package/src/styles/components/_list.scss +0 -244
- package/src/types/mtrl.d.ts +0 -6
- package/test/components/list.test.ts +0 -256
- package/test/core/collection/failed-ranges.test.ts +0 -270
- package/test/core/compose/features.test.ts +0 -183
- package/test/core/list-manager/features/collection.test.ts +0 -704
- package/test/core/list-manager/features/viewport.test.ts +0 -698
- package/test/core/list-manager/list-manager.test.ts +0 -593
- package/test/core/list-manager/utils/calculations.test.ts +0 -433
- package/test/core/list-manager/utils/range-calculator.test.ts +0 -569
- package/test/core/list-manager/utils/speed-tracker.test.ts +0 -530
- package/tsconfig.build.json +0 -23
- /package/src/components/{list → vlist}/features.ts +0 -0
- /package/src/core/{compose → viewport}/features/performance.ts +0 -0
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/compose/features
|
|
3
|
-
* @description Selection feature for components
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Basic item interface for selection
|
|
8
|
-
*/
|
|
9
|
-
export interface SelectableItem {
|
|
10
|
-
id: string;
|
|
11
|
-
[key: string]: any;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Selection configuration
|
|
16
|
-
*/
|
|
17
|
-
export interface SelectionConfig<T extends SelectableItem = SelectableItem> {
|
|
18
|
-
enabled?: boolean;
|
|
19
|
-
multiple?: boolean;
|
|
20
|
-
selectableFilter?: (item: T) => boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Component with selection capabilities
|
|
25
|
-
*/
|
|
26
|
-
export interface SelectionComponent<T extends SelectableItem = SelectableItem> {
|
|
27
|
-
selectItem: (id: string) => any;
|
|
28
|
-
deselectItem: (id: string) => any;
|
|
29
|
-
selectAll: () => any;
|
|
30
|
-
deselectAll: () => any;
|
|
31
|
-
getSelectedItems: () => T[];
|
|
32
|
-
getSelectedIds: () => string[];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Adds selection capabilities to a component
|
|
37
|
-
*
|
|
38
|
-
* @param config - Selection configuration
|
|
39
|
-
* @returns Component enhancer that adds selection capabilities
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```typescript
|
|
43
|
-
* const component = pipe(
|
|
44
|
-
* createBase,
|
|
45
|
-
* withElement(),
|
|
46
|
-
* withEvents(),
|
|
47
|
-
* withSelection({
|
|
48
|
-
* enabled: true,
|
|
49
|
-
* multiple: true,
|
|
50
|
-
* selectableFilter: (item) => item.status === 'active'
|
|
51
|
-
* })
|
|
52
|
-
* )(config);
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export function withSelection<T extends SelectableItem = SelectableItem>(
|
|
56
|
-
config: SelectionConfig<T>
|
|
57
|
-
) {
|
|
58
|
-
return (component: any): any & SelectionComponent<T> => {
|
|
59
|
-
console.log("✅ [MTRL-ADDONS] Adding selection capabilities");
|
|
60
|
-
|
|
61
|
-
if (!config.enabled) return component;
|
|
62
|
-
|
|
63
|
-
let selectedIds = new Set<string>();
|
|
64
|
-
|
|
65
|
-
// Selection helper functions
|
|
66
|
-
const isSelectable = (item: T): boolean => {
|
|
67
|
-
if (config.selectableFilter) {
|
|
68
|
-
return config.selectableFilter(item);
|
|
69
|
-
}
|
|
70
|
-
return true;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const updateItemSelection = (id: string, selected: boolean): void => {
|
|
74
|
-
const element = component.element.querySelector(
|
|
75
|
-
`[data-id="${id}"]`
|
|
76
|
-
) as HTMLElement;
|
|
77
|
-
if (element) {
|
|
78
|
-
element.classList.toggle(
|
|
79
|
-
component.getModifierClass
|
|
80
|
-
? component.getModifierClass("item", "selected")
|
|
81
|
-
: "mtrl-item--selected",
|
|
82
|
-
selected
|
|
83
|
-
);
|
|
84
|
-
element.setAttribute("aria-selected", selected.toString());
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
// Use component's event system for selection if available
|
|
89
|
-
if (component.on) {
|
|
90
|
-
component.on("click", (event: Event) => {
|
|
91
|
-
const target = event.target as HTMLElement;
|
|
92
|
-
const selectableItem = target.closest("[data-id]") as HTMLElement;
|
|
93
|
-
if (!selectableItem) return;
|
|
94
|
-
|
|
95
|
-
const itemId = selectableItem.getAttribute("data-id");
|
|
96
|
-
if (!itemId) return;
|
|
97
|
-
|
|
98
|
-
const item = component.getItem ? component.getItem(itemId) : null;
|
|
99
|
-
if (!item || !isSelectable(item)) return;
|
|
100
|
-
|
|
101
|
-
// Handle selection logic
|
|
102
|
-
if (config.multiple) {
|
|
103
|
-
if (selectedIds.has(itemId)) {
|
|
104
|
-
component.deselectItem(itemId);
|
|
105
|
-
} else {
|
|
106
|
-
component.selectItem(itemId);
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
// Single selection - clear others first
|
|
110
|
-
component.deselectAll();
|
|
111
|
-
component.selectItem(itemId);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Emit selection events using component's event system
|
|
115
|
-
if (component.emit) {
|
|
116
|
-
component.emit("selection:change", {
|
|
117
|
-
itemId,
|
|
118
|
-
selected: selectedIds.has(itemId),
|
|
119
|
-
selectedIds: Array.from(selectedIds),
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Selection methods
|
|
126
|
-
return {
|
|
127
|
-
...component,
|
|
128
|
-
|
|
129
|
-
selectItem(id: string) {
|
|
130
|
-
const item = component.getItem ? component.getItem(id) : null;
|
|
131
|
-
if (!item || !isSelectable(item)) return component;
|
|
132
|
-
|
|
133
|
-
selectedIds.add(id);
|
|
134
|
-
updateItemSelection(id, true);
|
|
135
|
-
console.log(`✅ [MTRL-ADDONS] Selected item: ${id}`);
|
|
136
|
-
|
|
137
|
-
// Emit event using component's event system
|
|
138
|
-
if (component.emit) {
|
|
139
|
-
component.emit("item:select", { itemId: id, item });
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return component;
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
deselectItem(id: string) {
|
|
146
|
-
selectedIds.delete(id);
|
|
147
|
-
updateItemSelection(id, false);
|
|
148
|
-
console.log(`❌ [MTRL-ADDONS] Deselected item: ${id}`);
|
|
149
|
-
|
|
150
|
-
// Emit event using component's event system
|
|
151
|
-
if (component.emit) {
|
|
152
|
-
component.emit("item:deselect", { itemId: id });
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return component;
|
|
156
|
-
},
|
|
157
|
-
|
|
158
|
-
selectAll() {
|
|
159
|
-
if (!config.multiple) return component;
|
|
160
|
-
|
|
161
|
-
if (component.getItems) {
|
|
162
|
-
component.getItems().forEach((item: T) => {
|
|
163
|
-
if (isSelectable(item)) {
|
|
164
|
-
selectedIds.add(item.id);
|
|
165
|
-
updateItemSelection(item.id, true);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
console.log(
|
|
171
|
-
`✅ [MTRL-ADDONS] Selected all items (${selectedIds.size})`
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
// Emit event using component's event system
|
|
175
|
-
if (component.emit) {
|
|
176
|
-
component.emit("selection:all", {
|
|
177
|
-
selectedIds: Array.from(selectedIds),
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return component;
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
deselectAll() {
|
|
185
|
-
selectedIds.forEach((id) => {
|
|
186
|
-
updateItemSelection(id, false);
|
|
187
|
-
});
|
|
188
|
-
selectedIds.clear();
|
|
189
|
-
|
|
190
|
-
console.log(`❌ [MTRL-ADDONS] Deselected all items`);
|
|
191
|
-
|
|
192
|
-
// Emit event using component's event system
|
|
193
|
-
if (component.emit) {
|
|
194
|
-
component.emit("selection:clear", {});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return component;
|
|
198
|
-
},
|
|
199
|
-
|
|
200
|
-
getSelectedItems(): T[] {
|
|
201
|
-
if (!component.getItem) return [];
|
|
202
|
-
|
|
203
|
-
return Array.from(selectedIds)
|
|
204
|
-
.map((id) => component.getItem(id))
|
|
205
|
-
.filter(Boolean) as T[];
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
getSelectedIds(): string[] {
|
|
209
|
-
return Array.from(selectedIds);
|
|
210
|
-
},
|
|
211
|
-
};
|
|
212
|
-
};
|
|
213
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/compose/features
|
|
3
|
-
* @description Styling feature for components
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Style configuration for components
|
|
8
|
-
*/
|
|
9
|
-
export interface StylingConfig {
|
|
10
|
-
itemHeight?: number | "auto";
|
|
11
|
-
gap?: number;
|
|
12
|
-
padding?: number;
|
|
13
|
-
striped?: boolean;
|
|
14
|
-
hoverable?: boolean;
|
|
15
|
-
bordered?: boolean;
|
|
16
|
-
componentName?: string; // For component-specific CSS properties
|
|
17
|
-
[key: string]: any;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Component with styling capabilities
|
|
22
|
-
*/
|
|
23
|
-
export interface StylingComponent {
|
|
24
|
-
setStyle: (style: Partial<StylingConfig>) => any;
|
|
25
|
-
getStyle: () => StylingConfig | undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Applies styling to an element using CSS custom properties
|
|
30
|
-
*
|
|
31
|
-
* @param element - The element to style
|
|
32
|
-
* @param style - Style configuration
|
|
33
|
-
*/
|
|
34
|
-
function applyElementStyling(element: HTMLElement, style: StylingConfig): void {
|
|
35
|
-
const componentName = style.componentName || "component";
|
|
36
|
-
|
|
37
|
-
if (style.gap !== undefined) {
|
|
38
|
-
element.style.setProperty(`--mtrl-${componentName}-gap`, `${style.gap}px`);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (style.padding !== undefined) {
|
|
42
|
-
element.style.setProperty(
|
|
43
|
-
`--mtrl-${componentName}-padding`,
|
|
44
|
-
`${style.padding}px`
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (style.itemHeight !== undefined && style.itemHeight !== "auto") {
|
|
49
|
-
element.style.setProperty(
|
|
50
|
-
`--mtrl-${componentName}-item-height`,
|
|
51
|
-
`${style.itemHeight}px`
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
element.classList.toggle(`mtrl-${componentName}--striped`, !!style.striped);
|
|
56
|
-
element.classList.toggle(
|
|
57
|
-
`mtrl-${componentName}--hoverable`,
|
|
58
|
-
!!style.hoverable
|
|
59
|
-
);
|
|
60
|
-
element.classList.toggle(`mtrl-${componentName}--bordered`, !!style.bordered);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Adds styling capabilities to a component
|
|
65
|
-
*
|
|
66
|
-
* @param initialStyle - Initial style configuration
|
|
67
|
-
* @returns Component enhancer that adds styling capabilities
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```typescript
|
|
71
|
-
* const component = pipe(
|
|
72
|
-
* createBase,
|
|
73
|
-
* withElement(),
|
|
74
|
-
* withStyling({
|
|
75
|
-
* gap: 8,
|
|
76
|
-
* padding: 16,
|
|
77
|
-
* striped: true,
|
|
78
|
-
* hoverable: true
|
|
79
|
-
* })
|
|
80
|
-
* )(config);
|
|
81
|
-
* ```
|
|
82
|
-
*/
|
|
83
|
-
export function withStyling(initialStyle?: StylingConfig) {
|
|
84
|
-
return (component: any): any & StylingComponent => {
|
|
85
|
-
console.log("🎨 [MTRL-ADDONS] Adding styling capabilities");
|
|
86
|
-
|
|
87
|
-
// Apply initial styling
|
|
88
|
-
if (initialStyle) {
|
|
89
|
-
applyElementStyling(component.element, initialStyle);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Add styling methods
|
|
93
|
-
return {
|
|
94
|
-
...component,
|
|
95
|
-
|
|
96
|
-
setStyle(style: Partial<StylingConfig>) {
|
|
97
|
-
if (style) {
|
|
98
|
-
applyElementStyling(component.element, style);
|
|
99
|
-
}
|
|
100
|
-
return component; // Enable chaining
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
getStyle() {
|
|
104
|
-
return initialStyle;
|
|
105
|
-
},
|
|
106
|
-
};
|
|
107
|
-
};
|
|
108
|
-
}
|