@leuffen/themejs1 1.0.0
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 +17 -0
- package/dist/core/templates.d.ts +0 -0
- package/dist/core/templates.js +0 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +5 -0
- package/dist/index.module.js +3 -0
- package/dist/template/hero/hero1.d.ts +20 -0
- package/dist/template/hero/hero1.js +77 -0
- package/dist/template/navbar/navbar.d.ts +16 -0
- package/dist/template/navbar/navbar.js +122 -0
- package/package.json +42 -0
- package/src/core/templates.ts +3 -0
- package/src/index.ts +6 -0
- package/src/template/_variables.scss +29 -0
- package/src/template/hero/hero1.scss +73 -0
- package/src/template/hero/hero1.ts +78 -0
- package/src/template/navbar/navbar.scss +133 -0
- package/src/template/navbar/navbar.ts +137 -0
- package/style.scss +4 -0
- package/style_embed.scss +1 -0
- package/style_late.scss +2 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# themejs1
|
|
2
|
+
ThemeJS Version 1
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## Templating using CSS Styles
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Browser Compat
|
|
10
|
+
|
|
11
|
+
| Browser | Version | Support |
|
|
12
|
+
|---------|---------|---------|
|
|
13
|
+
| Chrome | 92 | |
|
|
14
|
+
| Firefox | 90 | |
|
|
15
|
+
| Safari | >10 | Yes |
|
|
16
|
+
| Edge | 92 | |
|
|
17
|
+
| IE | 11 | |
|
|
File without changes
|
|
File without changes
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DefaultLayout } from "@leuffen/jodastyle";
|
|
2
|
+
export declare class HeroLayout extends DefaultLayout {
|
|
3
|
+
/**
|
|
4
|
+
* Columns of the content overlay
|
|
5
|
+
*/
|
|
6
|
+
content_cols: number;
|
|
7
|
+
content_space: string;
|
|
8
|
+
/**
|
|
9
|
+
* set Classes of the content div
|
|
10
|
+
*/
|
|
11
|
+
content_classes: string;
|
|
12
|
+
/**
|
|
13
|
+
* Size of the image in Background
|
|
14
|
+
*/
|
|
15
|
+
image_cols: number;
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
image_content: string;
|
|
20
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.HeroLayout = void 0;
|
|
10
|
+
const embed_1 = require("@kasimirjs/embed");
|
|
11
|
+
const jodastyle_1 = require("@leuffen/jodastyle");
|
|
12
|
+
const QTemplate_1 = require("@leuffen/jodastyle/src/helper/QTemplate");
|
|
13
|
+
// language=HTML
|
|
14
|
+
const tpl = (0, embed_1.ka_html)(`
|
|
15
|
+
<div class="autosection as__hero1 position-relative" style="isolation: isolate">
|
|
16
|
+
<div class="as__hero1_image-mobile :: d-block :[[layout.break1]]: d-none col-[[12 - layout.content_cols]] " data-ref="image-mobile"></div>
|
|
17
|
+
|
|
18
|
+
<div class="[[layout.container]] ">
|
|
19
|
+
<div class="as__hero1_content-row row :: mobile :[[layout.break1]]: full_height align-items-center">
|
|
20
|
+
|
|
21
|
+
<div class="as__hero1_content [[layout.content_classes]] [[layout.content_space]] :: col-12 :[[layout.break1]]: col-[[layout.content_cols]] " data-ref="main"></div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="position-absolute top-0 bottom-0 w-100" style="z-index: -1">
|
|
25
|
+
<div class="container-fluid p-0 h-100 :: d-none :[[layout.break1]]: d-block">
|
|
26
|
+
<div class="row g-0 flex-lg-row-reverse h-100">
|
|
27
|
+
<div class="col-[[layout.image_cols]] position-relative as__hero1_image h-100" data-ref="image">
|
|
28
|
+
<div class="position-absolute image-overlay [[ layout.content_cols-layout.image_cols < 0 ? 'overlay-fade' : '']]"></div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
`);
|
|
37
|
+
class HeroLayout extends jodastyle_1.DefaultLayout {
|
|
38
|
+
constructor() {
|
|
39
|
+
super(...arguments);
|
|
40
|
+
/**
|
|
41
|
+
* Columns of the content overlay
|
|
42
|
+
*/
|
|
43
|
+
this.content_cols = 6;
|
|
44
|
+
this.content_space = "my-5";
|
|
45
|
+
/**
|
|
46
|
+
* set Classes of the content div
|
|
47
|
+
*/
|
|
48
|
+
this.content_classes = "";
|
|
49
|
+
/**
|
|
50
|
+
* Size of the image in Background
|
|
51
|
+
*/
|
|
52
|
+
this.image_cols = 6;
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
this.image_content = "contentSelector(img)";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.HeroLayout = HeroLayout;
|
|
60
|
+
let Hero1 = class Hero1 {
|
|
61
|
+
render(element, layout) {
|
|
62
|
+
let main = new QTemplate_1.QTemplate(tpl);
|
|
63
|
+
main.parse({ layout });
|
|
64
|
+
Array.from(element.querySelectorAll(".background img, img.background")).forEach((el) => {
|
|
65
|
+
main.select("image").append(el.cloneNode(true));
|
|
66
|
+
main.select("image-mobile").append(el);
|
|
67
|
+
});
|
|
68
|
+
console.log("hero1");
|
|
69
|
+
main.select("main").append(element.querySelector("*"));
|
|
70
|
+
element.innerHTML = "";
|
|
71
|
+
element.append(main.content);
|
|
72
|
+
return main.content;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
Hero1 = __decorate([
|
|
76
|
+
(0, jodastyle_1.jodaRenderer)("hero1", HeroLayout)
|
|
77
|
+
], Hero1);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DefaultLayout } from "@leuffen/jodastyle";
|
|
2
|
+
export declare class NavbarLayout extends DefaultLayout {
|
|
3
|
+
/**
|
|
4
|
+
* a additional class name added to the main element
|
|
5
|
+
* to allow for custom styling. Defaults to "default" (see as-navbar.scss for details)
|
|
6
|
+
*/
|
|
7
|
+
style_class: string;
|
|
8
|
+
/**
|
|
9
|
+
* default position: Fixed on top
|
|
10
|
+
*/
|
|
11
|
+
position: string;
|
|
12
|
+
/**
|
|
13
|
+
* Show fixed navbar if scrolled down more than this distance
|
|
14
|
+
*/
|
|
15
|
+
fixed_scroll_distance: number;
|
|
16
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.NavbarLayout = void 0;
|
|
10
|
+
const embed_1 = require("@kasimirjs/embed");
|
|
11
|
+
const jodastyle_1 = require("@leuffen/jodastyle");
|
|
12
|
+
const QTemplate_1 = require("@leuffen/jodastyle/src/helper/QTemplate");
|
|
13
|
+
// language=HTML
|
|
14
|
+
const tpl = (0, embed_1.ka_html)(`
|
|
15
|
+
<nav class="as__navbar [[layout.position]]" style="z-index: 999">
|
|
16
|
+
|
|
17
|
+
<div id="as__minibar" class="as__minibar top" >
|
|
18
|
+
<div class="[[layout.container]]" data-ref="minibar"></div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div class="as__mainbar navbar navbar-expand-lg w-100">
|
|
22
|
+
<div class="[[layout.container]]" data-ref="main">
|
|
23
|
+
|
|
24
|
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
25
|
+
<span class="navbar-toggler-icon"></span>
|
|
26
|
+
</button>
|
|
27
|
+
<div data-ref="navbar" class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
</nav>
|
|
35
|
+
`);
|
|
36
|
+
class NavbarLayout extends jodastyle_1.DefaultLayout {
|
|
37
|
+
constructor() {
|
|
38
|
+
super(...arguments);
|
|
39
|
+
/**
|
|
40
|
+
* a additional class name added to the main element
|
|
41
|
+
* to allow for custom styling. Defaults to "default" (see as-navbar.scss for details)
|
|
42
|
+
*/
|
|
43
|
+
this.style_class = "default";
|
|
44
|
+
/**
|
|
45
|
+
* default position: Fixed on top
|
|
46
|
+
*/
|
|
47
|
+
this.position = "fixed";
|
|
48
|
+
/**
|
|
49
|
+
* Show fixed navbar if scrolled down more than this distance
|
|
50
|
+
*/
|
|
51
|
+
this.fixed_scroll_distance = 10;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.NavbarLayout = NavbarLayout;
|
|
55
|
+
let Navbar = class Navbar {
|
|
56
|
+
render(element, layout) {
|
|
57
|
+
console.log(layout);
|
|
58
|
+
let original = element.cloneNode(true);
|
|
59
|
+
let template = new QTemplate_1.QTemplate(tpl);
|
|
60
|
+
element.innerHTML = "";
|
|
61
|
+
element.appendChild(template.content);
|
|
62
|
+
template.parse({ layout });
|
|
63
|
+
let result = template.content;
|
|
64
|
+
let mainDiv = template.with("main");
|
|
65
|
+
let navbar = template.with("navbar");
|
|
66
|
+
let minibar = template.with("minibar");
|
|
67
|
+
let navbarBrand = original.querySelector(".navbar-brand");
|
|
68
|
+
if (navbarBrand === null) {
|
|
69
|
+
navbarBrand = (0, embed_1.ka_create_element)("a", { href: "/" }, "No class='navbar-brand' element");
|
|
70
|
+
}
|
|
71
|
+
mainDiv.selected.insertBefore(navbarBrand, mainDiv.selected.firstElementChild);
|
|
72
|
+
let mainUl = original.querySelector("ul.mainbar");
|
|
73
|
+
if (mainUl === null) {
|
|
74
|
+
mainUl = (0, embed_1.ka_create_element)("ul", {}, "Missing ul.mainbar element");
|
|
75
|
+
}
|
|
76
|
+
mainUl = mainUl.cloneNode(true);
|
|
77
|
+
navbar.append(mainUl);
|
|
78
|
+
let miniUl = original.querySelector("ul.minibar");
|
|
79
|
+
if (miniUl.firstElementChild === null) {
|
|
80
|
+
miniUl = null;
|
|
81
|
+
}
|
|
82
|
+
minibar.append(miniUl);
|
|
83
|
+
mainUl.classList.add(..."navbar-nav navbar-nav-scroll ms-auto my-2 my-lg-0".split(" "));
|
|
84
|
+
if (layout.fixed_scroll_distance !== null)
|
|
85
|
+
result.firstElementChild.classList.add("auto-fixed");
|
|
86
|
+
result.firstElementChild.classList.add(layout.style_class);
|
|
87
|
+
let scolled = false;
|
|
88
|
+
let fixed = false;
|
|
89
|
+
window.setInterval(() => {
|
|
90
|
+
if (window.scrollY > 0 && !scolled) {
|
|
91
|
+
result.classList.add("scrolled");
|
|
92
|
+
scolled = true;
|
|
93
|
+
}
|
|
94
|
+
else if (window.scrollY === 0 && scolled) {
|
|
95
|
+
result.classList.remove("scrolled");
|
|
96
|
+
scolled = false;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// nothing
|
|
100
|
+
}
|
|
101
|
+
if (layout.fixed_scroll_distance === null)
|
|
102
|
+
return;
|
|
103
|
+
if (window.scrollY > layout.fixed_scroll_distance && !fixed) {
|
|
104
|
+
result.classList.add("fixed");
|
|
105
|
+
fixed = true;
|
|
106
|
+
}
|
|
107
|
+
else if (window.scrollY <= layout.fixed_scroll_distance && fixed) {
|
|
108
|
+
result.classList.remove("fixed");
|
|
109
|
+
fixed = false;
|
|
110
|
+
}
|
|
111
|
+
}, 300);
|
|
112
|
+
mainUl.querySelectorAll("li").forEach(e => e.classList.add("nav-item"));
|
|
113
|
+
mainUl.querySelectorAll("li a").forEach(e => e.classList.add("nav-link"));
|
|
114
|
+
mainUl.querySelectorAll("li.dropdown ul").forEach(e => e.classList.add("dropdown-menu"));
|
|
115
|
+
mainUl.querySelectorAll("li.dropdown ul li").forEach(e => e.classList.add("dropdown-item"));
|
|
116
|
+
element.replaceWith(template.content);
|
|
117
|
+
return template.content;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
Navbar = __decorate([
|
|
121
|
+
(0, jodastyle_1.jodaRenderer)("navbar", NavbarLayout)
|
|
122
|
+
], Navbar);
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@leuffen/themejs1",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.module.js",
|
|
7
|
+
"directories": {
|
|
8
|
+
"doc": "docs",
|
|
9
|
+
"lib": "lib"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"/dist",
|
|
13
|
+
"/src",
|
|
14
|
+
"*.scss"
|
|
15
|
+
],
|
|
16
|
+
"workspaces": [
|
|
17
|
+
"workspaces/*"
|
|
18
|
+
],
|
|
19
|
+
"author": "",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@leuffen/jodastyle": "^1.0.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"dart-sass": "^1.25.0",
|
|
25
|
+
"sass": "^1.56.1",
|
|
26
|
+
"css-loader": "^6.7.1",
|
|
27
|
+
"esbuild-loader": "^2.20.0",
|
|
28
|
+
"mini-css-extract-plugin": "^2.6.1",
|
|
29
|
+
"raw-loader": "^4.0.2",
|
|
30
|
+
"sass-loader": "^13.0.2",
|
|
31
|
+
"style-loader": "^3.3.1",
|
|
32
|
+
"webpack": "^5.75.0",
|
|
33
|
+
"webpack-cli": "^5.0.1",
|
|
34
|
+
"webpack-dev-server": "^4.11.1"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"make.mjs": "tsc -d && mv dist/index.js dist/index.module.js",
|
|
38
|
+
"make.cjs": "tsc -m commonjs",
|
|
39
|
+
"build": "npm run make.mjs && npm run make.cjs",
|
|
40
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
$primary: #007bff !default;
|
|
3
|
+
$secondary: #6c757d !default;
|
|
4
|
+
$light: #f8f9fa !default;
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
$as-mainbar-color: white !default;
|
|
8
|
+
$as-minibar-color: $primary !default;
|
|
9
|
+
|
|
10
|
+
$content-height-adjustment: 0px !default;
|
|
11
|
+
$min-page-height: 600px !default;
|
|
12
|
+
|
|
13
|
+
.row {
|
|
14
|
+
& > div {
|
|
15
|
+
--joda-class: 'col';
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
:root {
|
|
22
|
+
--as-minibar-color: #007bff;
|
|
23
|
+
--as-mainbar-color: $as-mainbar-color;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
joda-content {
|
|
28
|
+
--joda-init: true;
|
|
29
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
.hc-section .section-1 {
|
|
4
|
+
background-color: $primary;
|
|
5
|
+
}
|
|
6
|
+
.hc-section .odd {
|
|
7
|
+
background-color: $primary;
|
|
8
|
+
}
|
|
9
|
+
.hc-section .even {
|
|
10
|
+
background-color: $primary;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
.as__hero1 {
|
|
17
|
+
.full_height {
|
|
18
|
+
min-height: max(calc(100vh - $content-height-adjustment), $min-page-height);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
.v-hide {
|
|
25
|
+
visibility: hidden;
|
|
26
|
+
}
|
|
27
|
+
.as__hero1_content-row {
|
|
28
|
+
&.mobile {
|
|
29
|
+
min-height: 66vh;
|
|
30
|
+
align-content: center;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.as__hero1_image-mobile {
|
|
35
|
+
img {
|
|
36
|
+
max-height: 60vh;
|
|
37
|
+
height: 100%;
|
|
38
|
+
width: 100%;
|
|
39
|
+
min-height: 33vh;
|
|
40
|
+
min-width: inherit;
|
|
41
|
+
object-fit: cover;
|
|
42
|
+
object-position: center center;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
.as__hero1_image {
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
img {
|
|
48
|
+
// Object-fit requires a height to be set on the image
|
|
49
|
+
height: 100%;
|
|
50
|
+
width: 100%;
|
|
51
|
+
min-height: inherit;
|
|
52
|
+
min-width: inherit;
|
|
53
|
+
object-fit: cover;
|
|
54
|
+
object-position: center center;
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
.image-overlay {
|
|
59
|
+
background-color: var(--as-image-overlay-color);
|
|
60
|
+
top: 0;
|
|
61
|
+
z-index: 999;
|
|
62
|
+
bottom: 0;
|
|
63
|
+
left: 0;
|
|
64
|
+
right: 0;
|
|
65
|
+
&.overlay-fade {
|
|
66
|
+
background-color: unset;
|
|
67
|
+
background-image: linear-gradient(to left, rgba(0, 0, 0, 0.0), rgba(255, 255, 255, 1));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {ka_html, KaTemplate} from "@kasimirjs/embed";
|
|
2
|
+
import {DefaultLayout, jodaRenderer, JodaRendererInterface, JodaUseRenderer} from "@leuffen/jodastyle";
|
|
3
|
+
import {QTemplate} from "@leuffen/jodastyle/src/helper/QTemplate";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// language=HTML
|
|
7
|
+
const tpl = ka_html(`
|
|
8
|
+
<div class="autosection as__hero1 position-relative" style="isolation: isolate">
|
|
9
|
+
<div class="as__hero1_image-mobile :: d-block :[[layout.break1]]: d-none col-[[12 - layout.content_cols]] " data-ref="image-mobile"></div>
|
|
10
|
+
|
|
11
|
+
<div class="[[layout.container]] ">
|
|
12
|
+
<div class="as__hero1_content-row row :: mobile :[[layout.break1]]: full_height align-items-center">
|
|
13
|
+
|
|
14
|
+
<div class="as__hero1_content [[layout.content_classes]] [[layout.content_space]] :: col-12 :[[layout.break1]]: col-[[layout.content_cols]] " data-ref="main"></div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="position-absolute top-0 bottom-0 w-100" style="z-index: -1">
|
|
18
|
+
<div class="container-fluid p-0 h-100 :: d-none :[[layout.break1]]: d-block">
|
|
19
|
+
<div class="row g-0 flex-lg-row-reverse h-100">
|
|
20
|
+
<div class="col-[[layout.image_cols]] position-relative as__hero1_image h-100" data-ref="image">
|
|
21
|
+
<div class="position-absolute image-overlay [[ layout.content_cols-layout.image_cols < 0 ? 'overlay-fade' : '']]"></div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
`);
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
export class HeroLayout extends DefaultLayout {
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Columns of the content overlay
|
|
36
|
+
*/
|
|
37
|
+
content_cols : number = 6
|
|
38
|
+
|
|
39
|
+
content_space : string = "my-5"
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* set Classes of the content div
|
|
43
|
+
*/
|
|
44
|
+
content_classes : string = ""
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Size of the image in Background
|
|
48
|
+
*/
|
|
49
|
+
image_cols : number = 6
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
*/
|
|
54
|
+
image_content: string = "contentSelector(img)"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@jodaRenderer("hero1", HeroLayout)
|
|
58
|
+
class Hero1 implements JodaRendererInterface {
|
|
59
|
+
render(element: HTMLElement, layout: HeroLayout): HTMLElement {
|
|
60
|
+
let main = new QTemplate(tpl);
|
|
61
|
+
main.parse({layout});
|
|
62
|
+
|
|
63
|
+
Array.from(element.querySelectorAll(".background img, img.background")).forEach((el: HTMLElement) => {
|
|
64
|
+
main.select("image").append(el.cloneNode(true));
|
|
65
|
+
main.select("image-mobile").append(el);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
console.log("hero1");
|
|
69
|
+
|
|
70
|
+
main.select("main").append(element.querySelector("*"))
|
|
71
|
+
element.innerHTML = "";
|
|
72
|
+
element.append(main.content);
|
|
73
|
+
return main.content;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
.as__navbar {
|
|
5
|
+
height: auto;
|
|
6
|
+
top: 0;
|
|
7
|
+
width: 100%;
|
|
8
|
+
|
|
9
|
+
&.fixed {
|
|
10
|
+
position: fixed;
|
|
11
|
+
top: 0;
|
|
12
|
+
width: 100%;
|
|
13
|
+
}
|
|
14
|
+
&.absolute {
|
|
15
|
+
position: absolute;
|
|
16
|
+
top: 0;
|
|
17
|
+
width: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
transition: opacity 1s ease-in-out;
|
|
21
|
+
position: fixed;
|
|
22
|
+
z-index: 999;
|
|
23
|
+
isolation: isolate;
|
|
24
|
+
opacity: 1;
|
|
25
|
+
|
|
26
|
+
&.auto-fixed {
|
|
27
|
+
&.scrolled {
|
|
28
|
+
&.fixed {
|
|
29
|
+
opacity: 1;
|
|
30
|
+
position: fixed;
|
|
31
|
+
}
|
|
32
|
+
opacity: 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
.as__minibar {
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
background-color: var(--as-minibar-color);
|
|
40
|
+
height: var(--as-minibar-height, 24px);
|
|
41
|
+
transition: height 0.3s ease-in-out;
|
|
42
|
+
z-index: 9999;
|
|
43
|
+
ul {
|
|
44
|
+
text-align: right;
|
|
45
|
+
text-decoration: none;
|
|
46
|
+
list-style-type: none;
|
|
47
|
+
li {
|
|
48
|
+
display: inline-block;
|
|
49
|
+
margin: 0 0.5rem;
|
|
50
|
+
a {
|
|
51
|
+
text-decoration: none;
|
|
52
|
+
color: var(--as-minibar-text-color);
|
|
53
|
+
&:hover {
|
|
54
|
+
|
|
55
|
+
text-decoration: underline;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.as__mainbar {
|
|
63
|
+
.nav-link {
|
|
64
|
+
padding-right: 0.8rem;
|
|
65
|
+
padding-left: 0.8rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.navbar-collapse.show {
|
|
69
|
+
background-color: var(--as-mainbar-bg, white);
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
.navbar-toggler {
|
|
73
|
+
background-color: rgba(255, 255,255, 0.5);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.as__navbar.scrolled {
|
|
79
|
+
.as__minibar {
|
|
80
|
+
height: 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* Theme specific styles */
|
|
85
|
+
.as__navbar.default {
|
|
86
|
+
|
|
87
|
+
.as__mainbar {
|
|
88
|
+
background-color: var(--as-mainbar-bg, white);
|
|
89
|
+
border-bottom: 1px solid $primary;
|
|
90
|
+
box-shadow: 2px 2px 2px 2px rgba(0, 0, 0, 0.2);
|
|
91
|
+
}
|
|
92
|
+
.as__minibar {
|
|
93
|
+
font-size: 13px;
|
|
94
|
+
line-height: 24px;
|
|
95
|
+
background-color: var(--as-minibar-bg, $primary);
|
|
96
|
+
a {
|
|
97
|
+
color: white;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.as__navbar.transparent {
|
|
103
|
+
.as__minibar{
|
|
104
|
+
border: 0;
|
|
105
|
+
font-size: 13px;
|
|
106
|
+
line-height: 24px;
|
|
107
|
+
}
|
|
108
|
+
.as__mainbar {
|
|
109
|
+
background-color: transparent !important;
|
|
110
|
+
transition: all 0.3s ease-in-out;
|
|
111
|
+
border: 0;
|
|
112
|
+
|
|
113
|
+
a {
|
|
114
|
+
font-weight: bolder;
|
|
115
|
+
// text-frame outset in white to read text better on background
|
|
116
|
+
text-shadow: 1px 1px 1px $light, -1px -1px 1px $light, 1px -1px 1px $light, -1px 1px 1px $light;
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
}
|
|
123
|
+
.as__navbar.transparent.scrolled {
|
|
124
|
+
.as__mainbar {
|
|
125
|
+
background-color: var(--as-mainbar-bg, white) !important;
|
|
126
|
+
border-bottom: 1px solid $primary;
|
|
127
|
+
box-shadow: 2px 2px 2px 2px rgba(0, 0, 0, 0.2);
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
.as__minibar {
|
|
131
|
+
height: 0;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {ka_create_element, ka_html, KaTemplate} from "@kasimirjs/embed";
|
|
2
|
+
import {DefaultLayout, jodaRenderer, JodaRendererInterface} from "@leuffen/jodastyle";
|
|
3
|
+
import {QTemplate} from "@leuffen/jodastyle/src/helper/QTemplate";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// language=HTML
|
|
8
|
+
const tpl = ka_html(`
|
|
9
|
+
<nav class="as__navbar [[layout.position]]" style="z-index: 999">
|
|
10
|
+
|
|
11
|
+
<div id="as__minibar" class="as__minibar top" >
|
|
12
|
+
<div class="[[layout.container]]" data-ref="minibar"></div>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="as__mainbar navbar navbar-expand-lg w-100">
|
|
16
|
+
<div class="[[layout.container]]" data-ref="main">
|
|
17
|
+
|
|
18
|
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
19
|
+
<span class="navbar-toggler-icon"></span>
|
|
20
|
+
</button>
|
|
21
|
+
<div data-ref="navbar" class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
</nav>
|
|
29
|
+
`);
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
export class NavbarLayout extends DefaultLayout {
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* a additional class name added to the main element
|
|
36
|
+
* to allow for custom styling. Defaults to "default" (see as-navbar.scss for details)
|
|
37
|
+
*/
|
|
38
|
+
style_class = "default";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* default position: Fixed on top
|
|
42
|
+
*/
|
|
43
|
+
position = "fixed";
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Show fixed navbar if scrolled down more than this distance
|
|
47
|
+
*/
|
|
48
|
+
fixed_scroll_distance = 10;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@jodaRenderer("navbar", NavbarLayout)
|
|
53
|
+
class Navbar implements JodaRendererInterface {
|
|
54
|
+
|
|
55
|
+
public render(element: HTMLElement, layout: NavbarLayout) {
|
|
56
|
+
console.log(layout);
|
|
57
|
+
|
|
58
|
+
let original = element.cloneNode(true) as HTMLElement;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
let template = new QTemplate(tpl);
|
|
62
|
+
element.innerHTML = "";
|
|
63
|
+
element.appendChild(template.content);
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
template.parse({layout});
|
|
67
|
+
|
|
68
|
+
let result = template.content;
|
|
69
|
+
let mainDiv = template.with("main");
|
|
70
|
+
let navbar = template.with("navbar");
|
|
71
|
+
let minibar = template.with("minibar");
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
let navbarBrand = original.querySelector(".navbar-brand");
|
|
76
|
+
if (navbarBrand === null) {
|
|
77
|
+
navbarBrand = ka_create_element("a", {href: "/"}, "No class='navbar-brand' element")
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
mainDiv.selected.insertBefore(navbarBrand, mainDiv.selected.firstElementChild);
|
|
81
|
+
|
|
82
|
+
let mainUl = original.querySelector("ul.mainbar") as HTMLDivElement | null;
|
|
83
|
+
if (mainUl === null) {
|
|
84
|
+
mainUl = ka_create_element("ul", {}, "Missing ul.mainbar element") as HTMLDivElement
|
|
85
|
+
}
|
|
86
|
+
mainUl = mainUl.cloneNode(true) as HTMLDivElement;
|
|
87
|
+
navbar.append(mainUl);
|
|
88
|
+
|
|
89
|
+
let miniUl = original.querySelector("ul.minibar") as HTMLDivElement | null;
|
|
90
|
+
if (miniUl.firstElementChild === null) {
|
|
91
|
+
miniUl = null;
|
|
92
|
+
}
|
|
93
|
+
minibar.append(miniUl);
|
|
94
|
+
|
|
95
|
+
mainUl.classList.add(..."navbar-nav navbar-nav-scroll ms-auto my-2 my-lg-0".split(" "));
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if (layout.fixed_scroll_distance !== null)
|
|
99
|
+
result.firstElementChild.classList.add("auto-fixed");
|
|
100
|
+
|
|
101
|
+
result.firstElementChild.classList.add(layout.style_class);
|
|
102
|
+
let scolled = false;
|
|
103
|
+
let fixed = false;
|
|
104
|
+
|
|
105
|
+
window.setInterval(() => {
|
|
106
|
+
if (window.scrollY > 0 && !scolled) {
|
|
107
|
+
result.classList.add("scrolled");
|
|
108
|
+
scolled = true;
|
|
109
|
+
} else if (window.scrollY === 0 && scolled) {
|
|
110
|
+
result.classList.remove("scrolled");
|
|
111
|
+
scolled = false;
|
|
112
|
+
} else {
|
|
113
|
+
// nothing
|
|
114
|
+
}
|
|
115
|
+
if (layout.fixed_scroll_distance === null)
|
|
116
|
+
return;
|
|
117
|
+
if (window.scrollY > layout.fixed_scroll_distance && !fixed) {
|
|
118
|
+
result.classList.add("fixed");
|
|
119
|
+
fixed = true;
|
|
120
|
+
} else if (window.scrollY <= layout.fixed_scroll_distance && fixed) {
|
|
121
|
+
result.classList.remove("fixed");
|
|
122
|
+
fixed = false;
|
|
123
|
+
}
|
|
124
|
+
}, 300)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
mainUl.querySelectorAll("li").forEach(e => e.classList.add("nav-item"))
|
|
128
|
+
mainUl.querySelectorAll("li a").forEach(e => e.classList.add("nav-link"))
|
|
129
|
+
mainUl.querySelectorAll("li.dropdown ul").forEach(e => e.classList.add("dropdown-menu"))
|
|
130
|
+
mainUl.querySelectorAll("li.dropdown ul li").forEach(e => e.classList.add("dropdown-item"))
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
element.replaceWith(template.content);
|
|
134
|
+
return template.content;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
package/style.scss
ADDED
package/style_embed.scss
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/style_late.scss
ADDED