motimeline 2.7.3 → 2.7.5
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/README.md +11 -1
- package/dist/moTimeline.cjs +3 -3
- package/dist/moTimeline.css +2 -2
- package/dist/moTimeline.js +55 -53
- package/dist/moTimeline.umd.js +3 -3
- package/package.json +1 -1
- package/src/moTimeline.css +3 -3
- package/src/moTimeline.js +8 -2
package/README.md
CHANGED
|
@@ -105,6 +105,8 @@ import 'motimeline/dist/moTimeline.css';
|
|
|
105
105
|
| `showCounterStyle` | string | `'counter'` | `'counter'` — sequential item number (1, 2, 3…). `'image'` — image from `data-mo-icon` on the `<li>`; falls back to a built-in flat SVG dot if the attribute is absent. `'none'` — badge element is created (preserving center-line spacing) but rendered with `opacity: 0`. |
|
|
106
106
|
| `cardBorderRadius` | string | `'8px'` | Border radius of the themed card and its banner image top corners. Sets `--mo-card-border-radius` on the container. Any valid CSS length is accepted (e.g. `'0'`, `'16px'`, `'1rem'`). |
|
|
107
107
|
| `avatarSize` | string | `'50px'` | Width and height of the circular avatar image. Sets `--mo-avatar-size` on the container. Any valid CSS length is accepted (e.g. `'40px'`, `'4rem'`). |
|
|
108
|
+
| `cardMargin` | string | `'0.5rem 1.25rem 0.5rem 0.5rem'` | Margin of left-column themed cards. The larger right value creates space toward the center line. Sets `--mo-card-margin` on the container. |
|
|
109
|
+
| `cardMarginInverted` | string | `'0.5rem 0.5rem 0.5rem 1.25rem'` | Margin of right-column (inverted) themed cards. The larger left value creates space toward the center line. Sets `--mo-card-margin-inverted` on the container. |
|
|
108
110
|
|
|
109
111
|
---
|
|
110
112
|
|
|
@@ -327,7 +329,9 @@ async function fetchPage(page) {
|
|
|
327
329
|
--mo-badge-font-size: 12px;
|
|
328
330
|
--mo-arrow-color: #dde1e7;
|
|
329
331
|
--mo-card-border-radius: 8px;
|
|
330
|
-
--mo-avatar-size:
|
|
332
|
+
--mo-avatar-size: 50px;
|
|
333
|
+
--mo-card-margin: 0.5rem 1.25rem 0.5rem 0.5rem;
|
|
334
|
+
--mo-card-margin-inverted: 0.5rem 0.5rem 0.5rem 1.25rem;
|
|
331
335
|
}
|
|
332
336
|
```
|
|
333
337
|
|
|
@@ -357,6 +361,12 @@ No framework option needed. Wrap the `<ul>` inside a Bootstrap `.container`:
|
|
|
357
361
|
|
|
358
362
|
## Changelog
|
|
359
363
|
|
|
364
|
+
### v2.7.5
|
|
365
|
+
- New options `cardMargin` (default `'0.5rem 1.25rem 0.5rem 0.5rem'`) and `cardMarginInverted` (default `'0.5rem 0.5rem 0.5rem 1.25rem'`) — control themed card margins via `--mo-card-margin` and `--mo-card-margin-inverted`
|
|
366
|
+
|
|
367
|
+
### v2.7.4
|
|
368
|
+
- Fix: wrong column placement when adjacent left and right items share the same bottom y-coordinate ([#3](https://github.com/MattOpen/moTimeline/issues/3)) — adds a 1 px tolerance to the column algorithm to absorb `offsetHeight`/`offsetTop` rounding mismatches
|
|
369
|
+
|
|
360
370
|
### v2.7.3
|
|
361
371
|
- Fix: cards misaligned on first load when items contain images ([#2](https://github.com/MattOpen/moTimeline/issues/2)) — layout now re-runs automatically after each unloaded image fires its `load` event, so column placement is correct once images are rendered
|
|
362
372
|
|
package/dist/moTimeline.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
* moTimeline v2.7.
|
|
1
|
+
"use strict";var E=Object.defineProperty;var _=(n,e,t)=>e in n?E(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var p=(n,e,t)=>_(n,typeof e!="symbol"?e+"":e,t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});/*!
|
|
2
|
+
* moTimeline v2.7.5
|
|
3
3
|
* Responsive two-column timeline layout library
|
|
4
4
|
* https://github.com/MattOpen/moTimeline
|
|
5
5
|
* MIT License
|
|
6
|
-
*/const c=new WeakMap,v={columnCount:{xs:1,sm:2,md:2,lg:2},showBadge:!1,showArrow:!1,theme:!1,showCounterStyle:"counter",cardBorderRadius:"8px",avatarSize:"50px"},b="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%234f46e5'/><circle cx='12' cy='12' r='4.5' fill='white'/></svg>";function w(){const
|
|
6
|
+
*/const c=new WeakMap,v={columnCount:{xs:1,sm:2,md:2,lg:2},showBadge:!1,showArrow:!1,theme:!1,showCounterStyle:"counter",cardBorderRadius:"8px",avatarSize:"50px",cardMargin:"0.5rem 1.25rem 0.5rem 0.5rem",cardMarginInverted:"0.5rem 0.5rem 0.5rem 1.25rem"},b="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%234f46e5'/><circle cx='12' cy='12' r='4.5' fill='white'/></svg>";function w(){const n=window.innerWidth;return n<600?"xs":n<992?"sm":n<1200?"md":"lg"}function C(n,e=100){let t;return(...s)=>{clearTimeout(t),t=setTimeout(()=>n(...s),e)}}function m(n){return n?{o:n.offsetTop,h:n.offsetHeight,gppu:n.offsetTop+n.offsetHeight}:{o:0,h:0,gppu:0}}function y(n,e){const t=[];let s=n.previousElementSibling;for(;s;)(!e||s.matches(e))&&t.push(s),s=s.previousElementSibling;return t}const l=class l{constructor(e,t={}){if(typeof e=="string"&&(e=document.querySelector(e)),!e)throw new Error("moTimeline: element not found");this.element=e,this.settings=Object.assign({},v,t),this.settings.columnCount=Object.assign({},v.columnCount,t.columnCount),this._resizeHandler=C(()=>this.refresh(),100),this._initialized=!1,this.init()}init(){const e=this.element;if(c.has(e)){this.refresh();return}const t=Object.assign({},this.settings,{lastItemIdx:0});c.set(e,t),l.instances.add(this),e.classList.add("mo-timeline"),t.theme&&e.classList.add("mo-theme"),e.style.setProperty("--mo-card-border-radius",t.cardBorderRadius),e.style.setProperty("--mo-avatar-size",t.avatarSize),e.style.setProperty("--mo-card-margin",t.cardMargin),e.style.setProperty("--mo-card-margin-inverted",t.cardMarginInverted),this._initialized=!0,window.addEventListener("resize",this._resizeHandler),Array.from(e.children).length>0&&this._initItems()}refresh(){l.instances.forEach(e=>{const t=e.element,s=c.get(t);s&&(s.col=s.columnCount[w()],e._setDivider(),Array.from(t.children).forEach(o=>{e._setPostPosition(o)}))})}initNewItems(){this._initItems()}addItems(e){typeof e=="string"&&(e=JSON.parse(e)),e.forEach(t=>this.element.appendChild(this._createItemElement(t))),this._initItems()}destroy(){window.removeEventListener("resize",this._resizeHandler),c.delete(this.element),l.instances.delete(this),this.element.style.removeProperty("--mo-card-border-radius"),this.element.style.removeProperty("--mo-avatar-size"),this.element.style.removeProperty("--mo-card-margin"),this.element.style.removeProperty("--mo-card-margin-inverted"),this.element.classList.remove("mo-timeline","mo-theme","mo-twocol"),Array.from(this.element.children).forEach(e=>{e.classList.remove("mo-item","js-mo-item","mo-inverted","js-mo-inverted","mo-offset"),e.querySelectorAll(".js-mo-badge, .js-mo-arrow").forEach(t=>t.remove())})}_getData(){return c.get(this.element)}_setDivider(){const e=this._getData();e&&(e.col=e.columnCount[w()],this.element.classList.toggle("mo-twocol",e.col>1))}_initItems(){const e=this.element,t=this._getData();if(!t)return;const s=t.lastItemIdx,o=Array.from(e.children),r=o.slice(s);r.length!==0&&(r.forEach((a,i)=>{a.id||(a.id="moT"+crypto.randomUUID()+"_"+(i+s)),a.classList.add("mo-item","js-mo-item")}),this._setDivider(),r.forEach((a,i)=>{t.showBadge&&this._createBadge(a,i+s+1),t.showArrow&&this._createArrow(a)}),t.lastItemIdx=o.length,c.set(e,t),this.refresh(),r.forEach(a=>{a.querySelectorAll("img").forEach(i=>{i.complete||i.addEventListener("load",this._resizeHandler,{once:!0})})}))}_setPostPosition(e){const t=this._getLeftOrRight(e);t&&(e.classList.toggle("mo-inverted",t.lr>0),e.classList.toggle("js-mo-inverted",t.lr>0),e.classList.toggle("mo-offset",t.badge_offset>0))}_getLeftOrRight(e){if(!e)return null;const t=this._getData();if(!t)return null;const s=t.col,o=y(e,".js-mo-inverted")[0]||null,r=y(e,".js-mo-item:not(.js-mo-inverted)")[0]||null,a=m(r),i=m(o),u=m(e);let h=0,f=0;if(s>1){a.gppu>u.o+1&&(h=1),i.gppu>a.gppu&&(h=0);const g=e.previousElementSibling;g&&Math.abs(u.o-m(g).o)<40&&(f=1)}return{lr:h,badge_offset:f}}_createBadge(e,t){const s=this._getData(),o=document.createElement("span");if(o.className="mo-badge js-mo-badge",s.showCounterStyle==="none")o.style.opacity="0";else if(s.showCounterStyle==="image"){const r=document.createElement("img");r.className="mo-badge-icon",r.alt="",r.src=e.dataset.moIcon||b,o.appendChild(r)}else o.textContent=t;e.prepend(o)}_createItemElement(e){const t=document.createElement("li");e.icon&&(t.dataset.moIcon=e.icon);const s=document.createElement("div");if(s.className="mo-card",e.banner){const r=document.createElement("div");r.className="mo-card-image";const a=document.createElement("img");if(a.className="mo-banner",a.src=e.banner,a.alt="",r.appendChild(a),e.avatar){const i=document.createElement("img");i.className="mo-avatar",i.src=e.avatar,i.alt="",r.appendChild(i)}s.appendChild(r)}const o=document.createElement("div");if(o.className="mo-card-body",e.title){const r=document.createElement("h3");r.textContent=e.title,o.appendChild(r)}if(e.meta){const r=document.createElement("p");r.className="mo-meta",r.textContent=e.meta,o.appendChild(r)}if(e.text){const r=document.createElement("p");r.textContent=e.text,o.appendChild(r)}return s.appendChild(o),t.appendChild(s),t}_createArrow(e){const t=document.createElement("span");t.className="mo-arrow js-mo-arrow",e.prepend(t)}};p(l,"instances",new Set);let d=l;exports.MoTimeline=d;exports.default=d;
|
package/dist/moTimeline.css
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* moTimeline v2.7.
|
|
3
|
-
*/:root{--mo-line-color: #dde1e7;--mo-badge-bg: #4f46e5;--mo-badge-color: #fff;--mo-badge-size: 26px;--mo-badge-font-size: 12px;--mo-arrow-color: #dde1e7}.mo-timeline{display:block;list-style:none;margin:0;padding:0;position:relative;width:100%}.mo-timeline:after{content:"";display:table;clear:both}.mo-timeline.mo-twocol:before{background-color:var(--mo-line-color);bottom:0;content:"";left:50%;margin-left:-1.5px;position:absolute;top:0;width:3px;z-index:0}.mo-timeline>.mo-item{box-sizing:border-box;display:block;float:left;position:relative;width:50%}.mo-timeline:not(.mo-twocol)>.mo-item{float:none;width:100%}.mo-timeline>.mo-item.mo-inverted{float:right}.mo-badge{align-items:center;background:var(--mo-badge-bg);border-radius:50%;color:var(--mo-badge-color);display:flex;font-size:var(--mo-badge-font-size);font-weight:700;height:var(--mo-badge-size);justify-content:center;min-width:var(--mo-badge-size);overflow:hidden;position:absolute;top:18px;z-index:2}.mo-badge .mo-badge-icon{border-radius:50%;height:100%;object-fit:cover;width:100%}.mo-timeline.mo-twocol>.mo-item:not(.mo-inverted) .mo-badge{left:auto;right:calc(var(--mo-badge-size) / -2)}.mo-timeline.mo-twocol>.mo-item.mo-inverted .mo-badge{left:calc(var(--mo-badge-size) / -2);right:auto}.mo-timeline.mo-twocol>.mo-item.mo-offset .mo-badge{top:calc(18px + var(--mo-badge-size) + 10px)}.mo-timeline.mo-twocol>.mo-item.mo-offset .mo-arrow{top:calc(26px + var(--mo-badge-size) + 10px)}.mo-timeline:not(.mo-twocol)>.mo-item .mo-badge{display:none}.mo-arrow{border:8px solid transparent;display:block;height:0;position:absolute;top:26px;width:0;z-index:1}.mo-timeline.mo-twocol>.mo-item:not(.mo-inverted) .mo-arrow{border-left:8px solid var(--mo-arrow-color);border-right:none;left:auto;right:0}.mo-timeline.mo-twocol>.mo-item.mo-inverted .mo-arrow{border-right:8px solid var(--mo-arrow-color);border-left:none;left:0;right:auto}.mo-timeline:not(.mo-twocol)>.mo-item .mo-arrow{display:none}.mo-theme{--mo-arrow-color: #fff}.mo-theme>.mo-item .mo-card{background:#fff;border-radius:var(--mo-card-border-radius, 8px);box-shadow:0 2px 14px #0000001a;margin
|
|
2
|
+
* moTimeline v2.7.5 — CSS
|
|
3
|
+
*/:root{--mo-line-color: #dde1e7;--mo-badge-bg: #4f46e5;--mo-badge-color: #fff;--mo-badge-size: 26px;--mo-badge-font-size: 12px;--mo-arrow-color: #dde1e7}.mo-timeline{display:block;list-style:none;margin:0;padding:0;position:relative;width:100%}.mo-timeline:after{content:"";display:table;clear:both}.mo-timeline.mo-twocol:before{background-color:var(--mo-line-color);bottom:0;content:"";left:50%;margin-left:-1.5px;position:absolute;top:0;width:3px;z-index:0}.mo-timeline>.mo-item{box-sizing:border-box;display:block;float:left;position:relative;width:50%}.mo-timeline:not(.mo-twocol)>.mo-item{float:none;width:100%}.mo-timeline>.mo-item.mo-inverted{float:right}.mo-badge{align-items:center;background:var(--mo-badge-bg);border-radius:50%;color:var(--mo-badge-color);display:flex;font-size:var(--mo-badge-font-size);font-weight:700;height:var(--mo-badge-size);justify-content:center;min-width:var(--mo-badge-size);overflow:hidden;position:absolute;top:18px;z-index:2}.mo-badge .mo-badge-icon{border-radius:50%;height:100%;object-fit:cover;width:100%}.mo-timeline.mo-twocol>.mo-item:not(.mo-inverted) .mo-badge{left:auto;right:calc(var(--mo-badge-size) / -2)}.mo-timeline.mo-twocol>.mo-item.mo-inverted .mo-badge{left:calc(var(--mo-badge-size) / -2);right:auto}.mo-timeline.mo-twocol>.mo-item.mo-offset .mo-badge{top:calc(18px + var(--mo-badge-size) + 10px)}.mo-timeline.mo-twocol>.mo-item.mo-offset .mo-arrow{top:calc(26px + var(--mo-badge-size) + 10px)}.mo-timeline:not(.mo-twocol)>.mo-item .mo-badge{display:none}.mo-arrow{border:8px solid transparent;display:block;height:0;position:absolute;top:26px;width:0;z-index:1}.mo-timeline.mo-twocol>.mo-item:not(.mo-inverted) .mo-arrow{border-left:8px solid var(--mo-arrow-color);border-right:none;left:auto;right:0}.mo-timeline.mo-twocol>.mo-item.mo-inverted .mo-arrow{border-right:8px solid var(--mo-arrow-color);border-left:none;left:0;right:auto}.mo-timeline:not(.mo-twocol)>.mo-item .mo-arrow{display:none}.mo-theme{--mo-arrow-color: #fff}.mo-theme>.mo-item .mo-card{background:#fff;border-radius:var(--mo-card-border-radius, 8px);box-shadow:0 2px 14px #0000001a;margin:var(--mo-card-margin, .5rem 1.25rem .5rem .5rem);position:relative}.mo-theme>.mo-item.mo-inverted .mo-card{margin:var(--mo-card-margin-inverted, .5rem .5rem .5rem 1.25rem)}.mo-theme>.mo-item .mo-banner{border-radius:var(--mo-card-border-radius, 8px) var(--mo-card-border-radius, 8px) 0 0;display:block;max-height:240px;object-fit:cover;width:100%}.mo-theme>.mo-item .mo-card-image{overflow:visible;position:relative}.mo-theme>.mo-item .mo-avatar{border:3px solid #fff;border-radius:50%;bottom:calc(var(--mo-avatar-size, 50px) * -.44);box-shadow:0 2px 8px #0000002e;height:var(--mo-avatar-size, 50px);object-fit:cover;position:absolute;right:14px;width:var(--mo-avatar-size, 50px);z-index:1}.mo-theme>.mo-item .mo-card-body{padding:1.75rem 1rem 1rem}.mo-theme>.mo-item .mo-card-body h3{font-size:1rem;font-weight:700;margin:0 0 .3rem}.mo-theme>.mo-item .mo-card-body .mo-meta{color:#9ca3af;font-size:.75rem;margin-bottom:.5rem}.mo-theme>.mo-item .mo-card-body p{color:#6b7280;font-size:.875rem;line-height:1.55;margin:0}.mo-theme.mo-twocol>.mo-item:not(.mo-inverted) .mo-arrow{border-left-color:var(--mo-arrow-color);right:12px}.mo-theme.mo-twocol>.mo-item.mo-inverted .mo-arrow{border-right-color:var(--mo-arrow-color);left:12px}.mo-theme .mo-badge{background:#fff;border:2px solid var(--mo-line-color);box-shadow:0 2px 6px #0000001a;color:#374151}
|
package/dist/moTimeline.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
1
|
+
var E = Object.defineProperty;
|
|
2
|
+
var _ = (n, e, t) => e in n ? E(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
|
+
var g = (n, e, t) => _(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
4
|
/*!
|
|
5
|
-
* moTimeline v2.7.
|
|
5
|
+
* moTimeline v2.7.5
|
|
6
6
|
* Responsive two-column timeline layout library
|
|
7
7
|
* https://github.com/MattOpen/moTimeline
|
|
8
8
|
* MIT License
|
|
9
9
|
*/
|
|
10
|
-
const c = /* @__PURE__ */ new WeakMap(),
|
|
10
|
+
const c = /* @__PURE__ */ new WeakMap(), p = {
|
|
11
11
|
columnCount: { xs: 1, sm: 2, md: 2, lg: 2 },
|
|
12
12
|
showBadge: !1,
|
|
13
13
|
showArrow: !1,
|
|
@@ -15,36 +15,38 @@ const c = /* @__PURE__ */ new WeakMap(), g = {
|
|
|
15
15
|
showCounterStyle: "counter",
|
|
16
16
|
// 'counter' | 'image' | 'none'
|
|
17
17
|
cardBorderRadius: "8px",
|
|
18
|
-
avatarSize: "50px"
|
|
18
|
+
avatarSize: "50px",
|
|
19
|
+
cardMargin: "0.5rem 1.25rem 0.5rem 0.5rem",
|
|
20
|
+
cardMarginInverted: "0.5rem 0.5rem 0.5rem 1.25rem"
|
|
19
21
|
}, C = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%234f46e5'/><circle cx='12' cy='12' r='4.5' fill='white'/></svg>";
|
|
20
22
|
function v() {
|
|
21
|
-
const
|
|
22
|
-
return
|
|
23
|
+
const n = window.innerWidth;
|
|
24
|
+
return n < 600 ? "xs" : n < 992 ? "sm" : n < 1200 ? "md" : "lg";
|
|
23
25
|
}
|
|
24
|
-
function b(
|
|
26
|
+
function b(n, e = 100) {
|
|
25
27
|
let t;
|
|
26
|
-
return (...
|
|
27
|
-
clearTimeout(t), t = setTimeout(() =>
|
|
28
|
+
return (...r) => {
|
|
29
|
+
clearTimeout(t), t = setTimeout(() => n(...r), e);
|
|
28
30
|
};
|
|
29
31
|
}
|
|
30
|
-
function m(
|
|
31
|
-
return
|
|
32
|
-
o:
|
|
33
|
-
h:
|
|
34
|
-
gppu:
|
|
32
|
+
function m(n) {
|
|
33
|
+
return n ? {
|
|
34
|
+
o: n.offsetTop,
|
|
35
|
+
h: n.offsetHeight,
|
|
36
|
+
gppu: n.offsetTop + n.offsetHeight
|
|
35
37
|
} : { o: 0, h: 0, gppu: 0 };
|
|
36
38
|
}
|
|
37
|
-
function w(
|
|
39
|
+
function w(n, e) {
|
|
38
40
|
const t = [];
|
|
39
|
-
let
|
|
40
|
-
for (;
|
|
41
|
-
(!e ||
|
|
41
|
+
let r = n.previousElementSibling;
|
|
42
|
+
for (; r; )
|
|
43
|
+
(!e || r.matches(e)) && t.push(r), r = r.previousElementSibling;
|
|
42
44
|
return t;
|
|
43
45
|
}
|
|
44
46
|
const l = class l {
|
|
45
47
|
constructor(e, t = {}) {
|
|
46
48
|
if (typeof e == "string" && (e = document.querySelector(e)), !e) throw new Error("moTimeline: element not found");
|
|
47
|
-
this.element = e, this.settings = Object.assign({},
|
|
49
|
+
this.element = e, this.settings = Object.assign({}, p, t), this.settings.columnCount = Object.assign({}, p.columnCount, t.columnCount), this._resizeHandler = b(() => this.refresh(), 100), this._initialized = !1, this.init();
|
|
48
50
|
}
|
|
49
51
|
init() {
|
|
50
52
|
const e = this.element;
|
|
@@ -53,13 +55,13 @@ const l = class l {
|
|
|
53
55
|
return;
|
|
54
56
|
}
|
|
55
57
|
const t = Object.assign({}, this.settings, { lastItemIdx: 0 });
|
|
56
|
-
c.set(e, t), l.instances.add(this), e.classList.add("mo-timeline"), t.theme && e.classList.add("mo-theme"), e.style.setProperty("--mo-card-border-radius", t.cardBorderRadius), e.style.setProperty("--mo-avatar-size", t.avatarSize), this._initialized = !0, window.addEventListener("resize", this._resizeHandler), Array.from(e.children).length > 0 && this._initItems();
|
|
58
|
+
c.set(e, t), l.instances.add(this), e.classList.add("mo-timeline"), t.theme && e.classList.add("mo-theme"), e.style.setProperty("--mo-card-border-radius", t.cardBorderRadius), e.style.setProperty("--mo-avatar-size", t.avatarSize), e.style.setProperty("--mo-card-margin", t.cardMargin), e.style.setProperty("--mo-card-margin-inverted", t.cardMarginInverted), this._initialized = !0, window.addEventListener("resize", this._resizeHandler), Array.from(e.children).length > 0 && this._initItems();
|
|
57
59
|
}
|
|
58
60
|
refresh() {
|
|
59
61
|
l.instances.forEach((e) => {
|
|
60
|
-
const t = e.element,
|
|
61
|
-
|
|
62
|
-
e._setPostPosition(
|
|
62
|
+
const t = e.element, r = c.get(t);
|
|
63
|
+
r && (r.col = r.columnCount[v()], e._setDivider(), Array.from(t.children).forEach((o) => {
|
|
64
|
+
e._setPostPosition(o);
|
|
63
65
|
}));
|
|
64
66
|
});
|
|
65
67
|
}
|
|
@@ -79,7 +81,7 @@ const l = class l {
|
|
|
79
81
|
typeof e == "string" && (e = JSON.parse(e)), e.forEach((t) => this.element.appendChild(this._createItemElement(t))), this._initItems();
|
|
80
82
|
}
|
|
81
83
|
destroy() {
|
|
82
|
-
window.removeEventListener("resize", this._resizeHandler), c.delete(this.element), l.instances.delete(this), this.element.style.removeProperty("--mo-card-border-radius"), this.element.style.removeProperty("--mo-avatar-size"), this.element.classList.remove("mo-timeline", "mo-theme", "mo-twocol"), Array.from(this.element.children).forEach((e) => {
|
|
84
|
+
window.removeEventListener("resize", this._resizeHandler), c.delete(this.element), l.instances.delete(this), this.element.style.removeProperty("--mo-card-border-radius"), this.element.style.removeProperty("--mo-avatar-size"), this.element.style.removeProperty("--mo-card-margin"), this.element.style.removeProperty("--mo-card-margin-inverted"), this.element.classList.remove("mo-timeline", "mo-theme", "mo-twocol"), Array.from(this.element.children).forEach((e) => {
|
|
83
85
|
e.classList.remove("mo-item", "js-mo-item", "mo-inverted", "js-mo-inverted", "mo-offset"), e.querySelectorAll(".js-mo-badge, .js-mo-arrow").forEach((t) => t.remove());
|
|
84
86
|
});
|
|
85
87
|
}
|
|
@@ -94,12 +96,12 @@ const l = class l {
|
|
|
94
96
|
_initItems() {
|
|
95
97
|
const e = this.element, t = this._getData();
|
|
96
98
|
if (!t) return;
|
|
97
|
-
const
|
|
99
|
+
const r = t.lastItemIdx, o = Array.from(e.children), s = o.slice(r);
|
|
98
100
|
s.length !== 0 && (s.forEach((a, i) => {
|
|
99
|
-
a.id || (a.id = "moT" + crypto.randomUUID() + "_" + (i +
|
|
101
|
+
a.id || (a.id = "moT" + crypto.randomUUID() + "_" + (i + r)), a.classList.add("mo-item", "js-mo-item");
|
|
100
102
|
}), this._setDivider(), s.forEach((a, i) => {
|
|
101
|
-
t.showBadge && this._createBadge(a, i +
|
|
102
|
-
}), t.lastItemIdx =
|
|
103
|
+
t.showBadge && this._createBadge(a, i + r + 1), t.showArrow && this._createArrow(a);
|
|
104
|
+
}), t.lastItemIdx = o.length, c.set(e, t), this.refresh(), s.forEach((a) => {
|
|
103
105
|
a.querySelectorAll("img").forEach((i) => {
|
|
104
106
|
i.complete || i.addEventListener("load", this._resizeHandler, { once: !0 });
|
|
105
107
|
});
|
|
@@ -113,31 +115,31 @@ const l = class l {
|
|
|
113
115
|
if (!e) return null;
|
|
114
116
|
const t = this._getData();
|
|
115
117
|
if (!t) return null;
|
|
116
|
-
const
|
|
118
|
+
const r = t.col, o = w(e, ".js-mo-inverted")[0] || null, s = w(e, ".js-mo-item:not(.js-mo-inverted)")[0] || null, a = m(s), i = m(o), h = m(e);
|
|
117
119
|
let d = 0, f = 0;
|
|
118
|
-
if (
|
|
119
|
-
a.gppu > h.o && (d = 1), i.gppu > a.gppu && (d = 0);
|
|
120
|
+
if (r > 1) {
|
|
121
|
+
a.gppu > h.o + 1 && (d = 1), i.gppu > a.gppu && (d = 0);
|
|
120
122
|
const u = e.previousElementSibling;
|
|
121
123
|
u && Math.abs(h.o - m(u).o) < 40 && (f = 1);
|
|
122
124
|
}
|
|
123
125
|
return { lr: d, badge_offset: f };
|
|
124
126
|
}
|
|
125
127
|
_createBadge(e, t) {
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
else if (
|
|
128
|
+
const r = this._getData(), o = document.createElement("span");
|
|
129
|
+
if (o.className = "mo-badge js-mo-badge", r.showCounterStyle === "none")
|
|
130
|
+
o.style.opacity = "0";
|
|
131
|
+
else if (r.showCounterStyle === "image") {
|
|
130
132
|
const s = document.createElement("img");
|
|
131
|
-
s.className = "mo-badge-icon", s.alt = "", s.src = e.dataset.moIcon || C,
|
|
133
|
+
s.className = "mo-badge-icon", s.alt = "", s.src = e.dataset.moIcon || C, o.appendChild(s);
|
|
132
134
|
} else
|
|
133
|
-
|
|
134
|
-
e.prepend(
|
|
135
|
+
o.textContent = t;
|
|
136
|
+
e.prepend(o);
|
|
135
137
|
}
|
|
136
138
|
_createItemElement(e) {
|
|
137
139
|
const t = document.createElement("li");
|
|
138
140
|
e.icon && (t.dataset.moIcon = e.icon);
|
|
139
|
-
const
|
|
140
|
-
if (
|
|
141
|
+
const r = document.createElement("div");
|
|
142
|
+
if (r.className = "mo-card", e.banner) {
|
|
141
143
|
const s = document.createElement("div");
|
|
142
144
|
s.className = "mo-card-image";
|
|
143
145
|
const a = document.createElement("img");
|
|
@@ -145,31 +147,31 @@ const l = class l {
|
|
|
145
147
|
const i = document.createElement("img");
|
|
146
148
|
i.className = "mo-avatar", i.src = e.avatar, i.alt = "", s.appendChild(i);
|
|
147
149
|
}
|
|
148
|
-
|
|
150
|
+
r.appendChild(s);
|
|
149
151
|
}
|
|
150
|
-
const
|
|
151
|
-
if (
|
|
152
|
+
const o = document.createElement("div");
|
|
153
|
+
if (o.className = "mo-card-body", e.title) {
|
|
152
154
|
const s = document.createElement("h3");
|
|
153
|
-
s.textContent = e.title,
|
|
155
|
+
s.textContent = e.title, o.appendChild(s);
|
|
154
156
|
}
|
|
155
157
|
if (e.meta) {
|
|
156
158
|
const s = document.createElement("p");
|
|
157
|
-
s.className = "mo-meta", s.textContent = e.meta,
|
|
159
|
+
s.className = "mo-meta", s.textContent = e.meta, o.appendChild(s);
|
|
158
160
|
}
|
|
159
161
|
if (e.text) {
|
|
160
162
|
const s = document.createElement("p");
|
|
161
|
-
s.textContent = e.text,
|
|
163
|
+
s.textContent = e.text, o.appendChild(s);
|
|
162
164
|
}
|
|
163
|
-
return
|
|
165
|
+
return r.appendChild(o), t.appendChild(r), t;
|
|
164
166
|
}
|
|
165
167
|
_createArrow(e) {
|
|
166
168
|
const t = document.createElement("span");
|
|
167
169
|
t.className = "mo-arrow js-mo-arrow", e.prepend(t);
|
|
168
170
|
}
|
|
169
171
|
};
|
|
170
|
-
|
|
171
|
-
let
|
|
172
|
+
g(l, "instances", /* @__PURE__ */ new Set());
|
|
173
|
+
let y = l;
|
|
172
174
|
export {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
+
y as MoTimeline,
|
|
176
|
+
y as default
|
|
175
177
|
};
|
package/dist/moTimeline.umd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(a,
|
|
2
|
-
* moTimeline v2.7.
|
|
1
|
+
(function(a,r){typeof exports=="object"&&typeof module<"u"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):(a=typeof globalThis<"u"?globalThis:a||self,r(a.MoTimeline={}))})(this,function(a){"use strict";var C=Object.defineProperty;var I=(a,r,m)=>r in a?C(a,r,{enumerable:!0,configurable:!0,writable:!0,value:m}):a[r]=m;var E=(a,r,m)=>I(a,typeof r!="symbol"?r+"":r,m);/*!
|
|
2
|
+
* moTimeline v2.7.5
|
|
3
3
|
* Responsive two-column timeline layout library
|
|
4
4
|
* https://github.com/MattOpen/moTimeline
|
|
5
5
|
* MIT License
|
|
6
|
-
*/const
|
|
6
|
+
*/const r=new WeakMap,m={columnCount:{xs:1,sm:2,md:2,lg:2},showBadge:!1,showArrow:!1,theme:!1,showCounterStyle:"counter",cardBorderRadius:"8px",avatarSize:"50px",cardMargin:"0.5rem 1.25rem 0.5rem 0.5rem",cardMarginInverted:"0.5rem 0.5rem 0.5rem 1.25rem"},_="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%234f46e5'/><circle cx='12' cy='12' r='4.5' fill='white'/></svg>";function g(){const c=window.innerWidth;return c<600?"xs":c<992?"sm":c<1200?"md":"lg"}function b(c,e=100){let t;return(...n)=>{clearTimeout(t),t=setTimeout(()=>c(...n),e)}}function h(c){return c?{o:c.offsetTop,h:c.offsetHeight,gppu:c.offsetTop+c.offsetHeight}:{o:0,h:0,gppu:0}}function p(c,e){const t=[];let n=c.previousElementSibling;for(;n;)(!e||n.matches(e))&&t.push(n),n=n.previousElementSibling;return t}const d=class d{constructor(e,t={}){if(typeof e=="string"&&(e=document.querySelector(e)),!e)throw new Error("moTimeline: element not found");this.element=e,this.settings=Object.assign({},m,t),this.settings.columnCount=Object.assign({},m.columnCount,t.columnCount),this._resizeHandler=b(()=>this.refresh(),100),this._initialized=!1,this.init()}init(){const e=this.element;if(r.has(e)){this.refresh();return}const t=Object.assign({},this.settings,{lastItemIdx:0});r.set(e,t),d.instances.add(this),e.classList.add("mo-timeline"),t.theme&&e.classList.add("mo-theme"),e.style.setProperty("--mo-card-border-radius",t.cardBorderRadius),e.style.setProperty("--mo-avatar-size",t.avatarSize),e.style.setProperty("--mo-card-margin",t.cardMargin),e.style.setProperty("--mo-card-margin-inverted",t.cardMarginInverted),this._initialized=!0,window.addEventListener("resize",this._resizeHandler),Array.from(e.children).length>0&&this._initItems()}refresh(){d.instances.forEach(e=>{const t=e.element,n=r.get(t);n&&(n.col=n.columnCount[g()],e._setDivider(),Array.from(t.children).forEach(o=>{e._setPostPosition(o)}))})}initNewItems(){this._initItems()}addItems(e){typeof e=="string"&&(e=JSON.parse(e)),e.forEach(t=>this.element.appendChild(this._createItemElement(t))),this._initItems()}destroy(){window.removeEventListener("resize",this._resizeHandler),r.delete(this.element),d.instances.delete(this),this.element.style.removeProperty("--mo-card-border-radius"),this.element.style.removeProperty("--mo-avatar-size"),this.element.style.removeProperty("--mo-card-margin"),this.element.style.removeProperty("--mo-card-margin-inverted"),this.element.classList.remove("mo-timeline","mo-theme","mo-twocol"),Array.from(this.element.children).forEach(e=>{e.classList.remove("mo-item","js-mo-item","mo-inverted","js-mo-inverted","mo-offset"),e.querySelectorAll(".js-mo-badge, .js-mo-arrow").forEach(t=>t.remove())})}_getData(){return r.get(this.element)}_setDivider(){const e=this._getData();e&&(e.col=e.columnCount[g()],this.element.classList.toggle("mo-twocol",e.col>1))}_initItems(){const e=this.element,t=this._getData();if(!t)return;const n=t.lastItemIdx,o=Array.from(e.children),s=o.slice(n);s.length!==0&&(s.forEach((i,l)=>{i.id||(i.id="moT"+crypto.randomUUID()+"_"+(l+n)),i.classList.add("mo-item","js-mo-item")}),this._setDivider(),s.forEach((i,l)=>{t.showBadge&&this._createBadge(i,l+n+1),t.showArrow&&this._createArrow(i)}),t.lastItemIdx=o.length,r.set(e,t),this.refresh(),s.forEach(i=>{i.querySelectorAll("img").forEach(l=>{l.complete||l.addEventListener("load",this._resizeHandler,{once:!0})})}))}_setPostPosition(e){const t=this._getLeftOrRight(e);t&&(e.classList.toggle("mo-inverted",t.lr>0),e.classList.toggle("js-mo-inverted",t.lr>0),e.classList.toggle("mo-offset",t.badge_offset>0))}_getLeftOrRight(e){if(!e)return null;const t=this._getData();if(!t)return null;const n=t.col,o=p(e,".js-mo-inverted")[0]||null,s=p(e,".js-mo-item:not(.js-mo-inverted)")[0]||null,i=h(s),l=h(o),v=h(e);let u=0,y=0;if(n>1){i.gppu>v.o+1&&(u=1),l.gppu>i.gppu&&(u=0);const w=e.previousElementSibling;w&&Math.abs(v.o-h(w).o)<40&&(y=1)}return{lr:u,badge_offset:y}}_createBadge(e,t){const n=this._getData(),o=document.createElement("span");if(o.className="mo-badge js-mo-badge",n.showCounterStyle==="none")o.style.opacity="0";else if(n.showCounterStyle==="image"){const s=document.createElement("img");s.className="mo-badge-icon",s.alt="",s.src=e.dataset.moIcon||_,o.appendChild(s)}else o.textContent=t;e.prepend(o)}_createItemElement(e){const t=document.createElement("li");e.icon&&(t.dataset.moIcon=e.icon);const n=document.createElement("div");if(n.className="mo-card",e.banner){const s=document.createElement("div");s.className="mo-card-image";const i=document.createElement("img");if(i.className="mo-banner",i.src=e.banner,i.alt="",s.appendChild(i),e.avatar){const l=document.createElement("img");l.className="mo-avatar",l.src=e.avatar,l.alt="",s.appendChild(l)}n.appendChild(s)}const o=document.createElement("div");if(o.className="mo-card-body",e.title){const s=document.createElement("h3");s.textContent=e.title,o.appendChild(s)}if(e.meta){const s=document.createElement("p");s.className="mo-meta",s.textContent=e.meta,o.appendChild(s)}if(e.text){const s=document.createElement("p");s.textContent=e.text,o.appendChild(s)}return n.appendChild(o),t.appendChild(n),t}_createArrow(e){const t=document.createElement("span");t.className="mo-arrow js-mo-arrow",e.prepend(t)}};E(d,"instances",new Set);let f=d;a.MoTimeline=f,a.default=f,Object.defineProperties(a,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/package.json
CHANGED
package/src/moTimeline.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* moTimeline v2.7.
|
|
2
|
+
* moTimeline v2.7.5 — CSS
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
/* ── CSS custom properties (easy override) ─────────────────── */
|
|
@@ -165,12 +165,12 @@
|
|
|
165
165
|
background: #fff;
|
|
166
166
|
border-radius: var(--mo-card-border-radius, 8px);
|
|
167
167
|
box-shadow: 0 2px 14px rgba(0, 0, 0, .10);
|
|
168
|
-
margin: 0.5rem 1.25rem 0.5rem 0.5rem;
|
|
168
|
+
margin: var(--mo-card-margin, 0.5rem 1.25rem 0.5rem 0.5rem);
|
|
169
169
|
position: relative;
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
.mo-theme > .mo-item.mo-inverted .mo-card {
|
|
173
|
-
margin: 0.5rem 0.5rem 0.5rem 1.25rem;
|
|
173
|
+
margin: var(--mo-card-margin-inverted, 0.5rem 0.5rem 0.5rem 1.25rem);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
/* Banner image — top corners rounded to match card, no overflow:hidden needed on card */
|
package/src/moTimeline.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* moTimeline v2.7.
|
|
2
|
+
* moTimeline v2.7.5
|
|
3
3
|
* Responsive two-column timeline layout library
|
|
4
4
|
* https://github.com/MattOpen/moTimeline
|
|
5
5
|
* MIT License
|
|
@@ -18,6 +18,8 @@ const DEFAULTS = {
|
|
|
18
18
|
showCounterStyle: 'counter', // 'counter' | 'image' | 'none'
|
|
19
19
|
cardBorderRadius: '8px',
|
|
20
20
|
avatarSize: '50px',
|
|
21
|
+
cardMargin: '0.5rem 1.25rem 0.5rem 0.5rem',
|
|
22
|
+
cardMarginInverted: '0.5rem 0.5rem 0.5rem 1.25rem',
|
|
21
23
|
};
|
|
22
24
|
|
|
23
25
|
const DEFAULT_BADGE_ICON = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><circle cx='12' cy='12' r='11' fill='%234f46e5'/><circle cx='12' cy='12' r='4.5' fill='white'/></svg>";
|
|
@@ -92,6 +94,8 @@ export class MoTimeline {
|
|
|
92
94
|
if (data.theme) el.classList.add('mo-theme');
|
|
93
95
|
el.style.setProperty('--mo-card-border-radius', data.cardBorderRadius);
|
|
94
96
|
el.style.setProperty('--mo-avatar-size', data.avatarSize);
|
|
97
|
+
el.style.setProperty('--mo-card-margin', data.cardMargin);
|
|
98
|
+
el.style.setProperty('--mo-card-margin-inverted', data.cardMarginInverted);
|
|
95
99
|
|
|
96
100
|
this._initialized = true;
|
|
97
101
|
window.addEventListener('resize', this._resizeHandler);
|
|
@@ -141,6 +145,8 @@ export class MoTimeline {
|
|
|
141
145
|
MoTimeline.instances.delete(this);
|
|
142
146
|
this.element.style.removeProperty('--mo-card-border-radius');
|
|
143
147
|
this.element.style.removeProperty('--mo-avatar-size');
|
|
148
|
+
this.element.style.removeProperty('--mo-card-margin');
|
|
149
|
+
this.element.style.removeProperty('--mo-card-margin-inverted');
|
|
144
150
|
this.element.classList.remove('mo-timeline', 'mo-theme', 'mo-twocol');
|
|
145
151
|
Array.from(this.element.children).forEach((child) => {
|
|
146
152
|
child.classList.remove('mo-item', 'js-mo-item', 'mo-inverted', 'js-mo-inverted', 'mo-offset');
|
|
@@ -236,7 +242,7 @@ export class MoTimeline {
|
|
|
236
242
|
let bo = 0;
|
|
237
243
|
|
|
238
244
|
if (col > 1) {
|
|
239
|
-
if (l.gppu > e.o) pos = 1;
|
|
245
|
+
if (l.gppu > e.o + 1) pos = 1; // +1px tolerance for offsetHeight/offsetTop rounding mismatch
|
|
240
246
|
if (r.gppu > l.gppu) pos = 0;
|
|
241
247
|
|
|
242
248
|
const prev = el.previousElementSibling;
|