Skip to content

Commit 3410cb8

Browse files
committed
Add initial support for mv-list/mv-list-item, and rewrite mv-multiple to it (#735)
Closes #72
1 parent 6df3092 commit 3410cb8

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, []);
@@ -26,29 +27,27 @@ var _ = Mavo.Collection = class Collection extends Mavo.Node {
2627
}
2728

2829
if (!this.fromTemplate("templateElement", "accepts", "initialItems")) {
29-
this.accepts = this.templateElement.getAttribute("mv-accepts");
30+
this.accepts = this.element.getAttribute("mv-accepts");
3031
this.accepts = new Set(this.accepts?.split(/\s+/));
3132

32-
this.initialItems = +(this.templateElement.getAttribute("mv-initial-items") || 1);
33+
this.initialItems = +(this.element.getAttribute("mv-initial-items") || 1);
3334

3435
// Must clone because otherwise once expressions are parsed on the template element
3536
// we will not be able to pick them up from subsequent items
37+
3638
this.templateElement = this.templateElement.cloneNode(true);
3739
}
3840

39-
if (this.initialItems > 0 || !this.template) {
40-
var item = this.createItem(this.element);
41-
this.add(item, undefined, {silent: true});
42-
}
41+
let item = this.add(this.firstItemElement, undefined, {silent: true});
4342

4443
this.mavo.treeBuilt.then(() => {
45-
if (!this.initialItems) {
44+
if (this.initialItems === 0) {
4645
if (item) {
4746
this.delete(item, {silent: true});
4847
}
4948
else {
5049
// No item to delete
51-
this.element.remove();
50+
this.firstItemElement.remove();
5251
}
5352
}
5453
else if (this.initialItems > 1) {
@@ -70,7 +69,7 @@ var _ = Mavo.Collection = class Collection extends Mavo.Node {
7069
var group = this.parentGroup.element;
7170

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

@@ -343,12 +342,9 @@ var _ = Mavo.Collection = class Collection extends Mavo.Node {
343342

344343
// Insert the add button if it's not already in the DOM
345344
if (!this.addButton.parentNode) {
346-
var tag = this.element.tagName.toLowerCase();
347-
348-
if (tag in Mavo.selectors.container) {
349-
var rel = this.marker.parentNode.closest(Mavo.selectors.container[tag]);
350-
}
351-
else if (this.bottomUp && this.children[0]) {
345+
// In bottom up collections, button goes before first item
346+
// otherwise, it goes after the marker
347+
if (this.bottomUp && this.children[0]) {
352348
var rel = this.children[0].element;
353349
}
354350

@@ -599,7 +595,7 @@ $.Class(_, {
599595
* Add new items at the top or bottom?
600596
*/
601597

602-
return /^desc\b/i.test(this.templateElement.getAttribute("mv-order"));
598+
return /^desc\b/i.test(this.element.getAttribute("mv-order"));
603599
}
604600
},
605601

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)