Skip to content

Commit 00fe69b

Browse files
authored
Add initial support for mv-list/mv-list-item, and rewrite mv-multiple to it (#735)
Closes #72
1 parent 23a6e72 commit 00fe69b

File tree

9 files changed

+259
-78
lines changed

9 files changed

+259
-78
lines changed

src-css/mavo.scss

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
right: 0;
2828
margin: .2em 0;
2929

30-
tr[mv-multiple] > & { // Table rows cannot be relative, hack to fix that
30+
tr[mv-list-item] > & { // Table rows cannot be relative, hack to fix that
3131
bottom: auto;
3232
right: auto;
3333
}
@@ -145,7 +145,7 @@
145145
}
146146
}
147147

148-
[mv-multiple] {
148+
[mv-list-item] {
149149
position: relative;
150150

151151
&.mv-highlight { // basically &:has(> .mv-item-bar:hover)
@@ -234,7 +234,7 @@ button.mv-close {
234234
}
235235
}
236236

237-
[mv-progress="Loading"]:not(.mv-no-hiding-during-loading) [mv-multiple] {
237+
[mv-progress="Loading"]:not(.mv-no-hiding-during-loading) [mv-list-item] {
238238
display: none;
239239
}
240240

@@ -269,15 +269,15 @@ button.mv-close {
269269
[mv-mode=""] { --mv-mode: initial; }
270270

271271
// Primitives
272-
[property][mv-mode="edit"]:not([typeof]):not([mv-group]) {
272+
[property][mv-mode="edit"]:not([typeof], [mv-group], [mv-list]) {
273273
input.mv-editor,
274274
select.mv-editor,
275275
textarea.mv-editor {
276276
all: unset;
277277
cursor: auto;
278278
}
279279

280-
&:not(input):not(select):not(textarea):hover {
280+
&:not(input, select, textarea):hover {
281281
@include highlight(hsla(58, 100%, 50%, .2));
282282
}
283283

@@ -581,4 +581,41 @@ img[property]:where([mv-mode="edit"]:not([alt], [alt=""])) {
581581
}
582582
}
583583

584+
@property --mv-length {
585+
syntax: "<length>";
586+
initial-value: 0;
587+
inherits: true;
588+
}
589+
590+
.mv-container {
591+
display: contents !important;
592+
}
593+
594+
select,
595+
datalist {
596+
--mv-length: 1em;
597+
}
598+
599+
optgroup:where(.mv-container) {
600+
& > option {
601+
padding-inline-start: 2px; /* Remove Firefox gap */
602+
603+
/* Remove Chrome gap */
604+
&::before {
605+
content: none;
606+
}
607+
}
608+
609+
:where(:root.mv-supports-atproperty) & {
610+
font-size: 0;
611+
--mv-length: inherit;
612+
613+
& > * {
614+
--mv-length: inherit;
615+
font-size: var(--mv-length);
616+
}
617+
}
618+
}
619+
620+
584621
@import 'bar';

src/collection.js

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(function($, $$) {
22

3-
Mavo.attributes.push("mv-multiple", "mv-order", "mv-accepts", "mv-initial-items");
3+
Mavo.attributes.push("mv-list", "mv-list-item", "mv-order", "mv-accepts", "mv-initial-items");
44

55
var _ = Mavo.Collection = class Collection extends Mavo.Node {
66
constructor (element, mavo, o) {
@@ -9,7 +9,8 @@ var _ = Mavo.Collection = class Collection extends Mavo.Node {
99
/*
1010
* Create the template, remove it from the DOM and store it
1111
*/
12-
this.templateElement = this.element;
12+
13+
this.firstItemElement = this.templateElement = $(Mavo.selectors.multiple, this.element);
1314

1415
this.children = [];
1516
this.liveData = new Mavo.Data(this, []);
@@ -22,29 +23,27 @@ var _ = Mavo.Collection = class Collection extends Mavo.Node {
2223
this.addButton = this.createAddButton();
2324

2425
if (!this.fromTemplate("templateElement", "accepts", "initialItems")) {
25-
this.accepts = this.templateElement.getAttribute("mv-accepts");
26+
this.accepts = this.element.getAttribute("mv-accepts");
2627
this.accepts = new Set(this.accepts?.split(/\s+/));
2728

28-
this.initialItems = +(this.templateElement.getAttribute("mv-initial-items") || 1);
29+
this.initialItems = +(this.element.getAttribute("mv-initial-items") || 1);
2930

3031
// Must clone because otherwise once expressions are parsed on the template element
3132
// we will not be able to pick them up from subsequent items
33+
3234
this.templateElement = this.templateElement.cloneNode(true);
3335
}
3436

35-
if (this.initialItems > 0 || !this.template) {
36-
var item = this.createItem(this.element);
37-
this.add(item, undefined, {silent: true});
38-
}
37+
let item = this.add(this.firstItemElement, undefined, {silent: true});
3938

4039
this.mavo.treeBuilt.then(() => {
41-
if (!this.initialItems) {
40+
if (this.initialItems === 0) {
4241
if (item) {
4342
this.delete(item, {silent: true});
4443
}
4544
else {
4645
// No item to delete
47-
this.element.remove();
46+
this.firstItemElement.remove();
4847
}
4948
}
5049
else if (this.initialItems > 1) {
@@ -66,7 +65,7 @@ var _ = Mavo.Collection = class Collection extends Mavo.Node {
6665
var group = this.parentGroup.element;
6766

6867
var button = $$(selector, group).filter(button => {
69-
return !this.templateElement.contains(button) // is outside the template element
68+
return !this.element.contains(button) // is outside the list element
7069
&& !Mavo.data(button, "collection"); // and does not belong to another collection
7170
})[0];
7271

@@ -339,12 +338,9 @@ var _ = Mavo.Collection = class Collection extends Mavo.Node {
339338

340339
// Insert the add button if it's not already in the DOM
341340
if (!this.addButton.parentNode) {
342-
var tag = this.element.tagName.toLowerCase();
343-
344-
if (tag in Mavo.selectors.container) {
345-
var rel = this.marker.parentNode.closest(Mavo.selectors.container[tag]);
346-
}
347-
else if (this.bottomUp && this.children[0]) {
341+
// In bottom up collections, button goes before first item
342+
// otherwise, it goes after the marker
343+
if (this.bottomUp && this.children[0]) {
348344
var rel = this.children[0].element;
349345
}
350346

@@ -595,7 +591,7 @@ $.Class(_, {
595591
* Add new items at the top or bottom?
596592
*/
597593

598-
return /^desc\b/i.test(this.templateElement.getAttribute("mv-order"));
594+
return /^desc\b/i.test(this.element.getAttribute("mv-order"));
599595
}
600596
},
601597

src/data.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ var _ = Mavo.Data = $.Class(class Data {
185185
return Array.isArray(data?.[Mavo.parent]);
186186
},
187187

188+
isCollection (data) {
189+
return Array.isArray(data) && data?.[Mavo.toNode] instanceof Mavo.Collection;
190+
},
191+
188192
closest (obj, test) {
189193
var path = [];
190194
do {
@@ -326,6 +330,10 @@ var _ = Mavo.Data = $.Class(class Data {
326330
if (property in data) {
327331
ret = data[property];
328332
}
333+
else if (_.isCollection(data) && data[Mavo.property] === property) {
334+
// On collections we want their property name to return the entire collection
335+
return data;
336+
}
329337
else if (!propertyIsNumeric) {
330338
// Property does not exist on data, if non-numeric, look for it elsewhere
331339
if (property in _.special) { // $special properties
@@ -383,6 +391,10 @@ var _ = Mavo.Data = $.Class(class Data {
383391
return Reflect.has(data, property);
384392
}
385393

394+
if (_.getProperty(data) === property) {
395+
return true;
396+
}
397+
386398
var objects = [data, Mavo.all, _.special];
387399

388400
if (objects.some(obj => property in obj)) {

0 commit comments

Comments
 (0)