@nextrap/ntl-hero 2.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 +205 -0
- package/index.css +1 -0
- package/index.d.ts +1 -0
- package/index.js +65 -0
- package/package.json +22 -0
- package/src/components/ntl-hero/ntl-hero.d.ts +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# ntl-hero
|
|
2
|
+
|
|
3
|
+
A layout-focused hero web component with support for:
|
|
4
|
+
|
|
5
|
+
- a **background layer** (e.g. parallax image),
|
|
6
|
+
- a **top navigation bar**,
|
|
7
|
+
- **centered headline/content**, and
|
|
8
|
+
- a **framed slider card** that is bottom‑aligned and can visually overlap the page below.
|
|
9
|
+
|
|
10
|
+
It is implemented with Lit and the Shadow DOM, and is designed to be reusable across different hero designs by composing content via slots and CSS custom properties.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Slot-based architecture**: `nav`, `bg`, default, and `slider` slots for flexible composition.
|
|
15
|
+
- **Layered layout**: Background, content, and slider are stacked with proper z‑index handling.
|
|
16
|
+
- **Viewport-aware height**: Defaults to `100vh` and can be reduced via a height offset.
|
|
17
|
+
- **Themed via CSS variables**: Adjust spacing, radii, heights, and offsets without touching the component code.
|
|
18
|
+
- **Responsive**: Adapts padding and slider sizing on smaller screens.
|
|
19
|
+
|
|
20
|
+
## Slots
|
|
21
|
+
|
|
22
|
+
| Slot name | Required | Description | Typical content |
|
|
23
|
+
| ----------- | -------- | ---------------------------------------------------------------------------------------- | ------------------------------------ |
|
|
24
|
+
| `nav` | no | Navigation bar at the very top of the hero. | Navigation component, logo + menu |
|
|
25
|
+
| `bg` | no | Background layer behind everything else. If omitted, the hero falls back to `--nt-body`. | `nte-parallax-bg`, decorative images |
|
|
26
|
+
| _(default)_ | no | Main hero content, centered between nav and slider. | Headings, copy, buttons, badges |
|
|
27
|
+
| `slider` | no | Slider/card content in the framed area at the bottom of the hero. | Carousel / slideshow components |
|
|
28
|
+
|
|
29
|
+
> The component is resilient: you can use just a background + content, content + slider, or all four slots together.
|
|
30
|
+
|
|
31
|
+
## Layout behavior
|
|
32
|
+
|
|
33
|
+
- The hero height is `min-height: calc(100vh - var(--ntl-hero-height-offset))`, so by default it fills the viewport.
|
|
34
|
+
- The **nav** (if present) sits at the top, the **slider** is bottom‑aligned, and the **content** is vertically centered in the remaining space between them.
|
|
35
|
+
- The slider is wrapped in a **card frame** with its own background and border radius; it can be moved further down using `--ntl-hero-slider-offset` so that it visually overlaps the section that follows.
|
|
36
|
+
- If no `bg` slot is provided, the hero uses `--nt-body` (or `--ntl-hero-bg-color`) as its background color.
|
|
37
|
+
|
|
38
|
+
## Example: Hero with nav, parallax background, centered content and slider
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<ntl-hero
|
|
42
|
+
style="
|
|
43
|
+
--ntl-hero-height-offset: 10vh;
|
|
44
|
+
--ntl-hero-bg-color: #E4E6EF;
|
|
45
|
+
--ntl-hero-slider-offset: 3rem;
|
|
46
|
+
"
|
|
47
|
+
>
|
|
48
|
+
<!-- Top navigation bar -->
|
|
49
|
+
<div slot="nav">
|
|
50
|
+
<nte-nav
|
|
51
|
+
class="nav-horizontal"
|
|
52
|
+
mode="master"
|
|
53
|
+
data-group-name="nav1"
|
|
54
|
+
breakpoint="1008px"
|
|
55
|
+
transfer-to="#navSidebar"
|
|
56
|
+
>
|
|
57
|
+
<span slot="menu-text">Menü</span>
|
|
58
|
+
<ul>
|
|
59
|
+
<li><a href="#" class="active">Home</a></li>
|
|
60
|
+
<li><a href="#">Magazin</a></li>
|
|
61
|
+
<li><a href="#">Über uns</a></li>
|
|
62
|
+
<li><a href="#">Kontakt</a></li>
|
|
63
|
+
</ul>
|
|
64
|
+
</nte-nav>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- Background layer (optional). If omitted, bg color comes from --ntl-hero-bg-color / --nt-body -->
|
|
68
|
+
<div slot="bg">
|
|
69
|
+
<nte-parallax-bg image="header-bg.svg"></nte-parallax-bg>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<!-- Centered hero text -->
|
|
73
|
+
<div>
|
|
74
|
+
<h6>
|
|
75
|
+
<span style="color: var(--nt-primary); text-transform: uppercase;">EPRAXIS.DIGITAL</span>
|
|
76
|
+
– DAS MAGAZIN FÜR DIE DIGITALISIERUNG IN DER GESUNDHEITSBRANCHE
|
|
77
|
+
</h6>
|
|
78
|
+
<h1>Digitale Transformation im Gesundheitswesen – verständlich, unabhängig, praxisnah.</h1>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<!-- Slider in framed card at the bottom -->
|
|
82
|
+
<div slot="slider">
|
|
83
|
+
<nte-image data-features="slideshow arrows indicators fullsize round-borders" interval="4000">
|
|
84
|
+
<img src="slide1.jpg" alt="Slide 1" />
|
|
85
|
+
<img src="slide2.jpg" alt="Slide 2" />
|
|
86
|
+
<img src="slide3.jpg" alt="Slide 3" />
|
|
87
|
+
</nte-image>
|
|
88
|
+
</div>
|
|
89
|
+
</ntl-hero>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Simpler variants
|
|
93
|
+
|
|
94
|
+
### Only background + content
|
|
95
|
+
|
|
96
|
+
```html
|
|
97
|
+
<ntl-hero>
|
|
98
|
+
<nte-parallax-bg slot="bg" image="hero-background.jpg"></nte-parallax-bg>
|
|
99
|
+
|
|
100
|
+
<div>
|
|
101
|
+
<h1>Your Headline Here</h1>
|
|
102
|
+
<p>Your description text</p>
|
|
103
|
+
</div>
|
|
104
|
+
</ntl-hero>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Background + content + slider (no nav)
|
|
108
|
+
|
|
109
|
+
```html
|
|
110
|
+
<ntl-hero style="--ntl-hero-bg-color: #f0f0f5;">
|
|
111
|
+
<div slot="bg" style="background: #f0f0f5; width: 100%; height: 100%;"></div>
|
|
112
|
+
|
|
113
|
+
<div>
|
|
114
|
+
<h2>Digital Transformation</h2>
|
|
115
|
+
<p>Effizient, präzise, patientenorientiert</p>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div slot="slider">
|
|
119
|
+
<!-- Your slider implementation -->
|
|
120
|
+
</div>
|
|
121
|
+
</ntl-hero>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## CSS custom properties
|
|
125
|
+
|
|
126
|
+
You can tune the layout and visual appearance using CSS variables on the host element:
|
|
127
|
+
|
|
128
|
+
| Property | Default | Description |
|
|
129
|
+
| ------------------------------ | ------------------------------------ | --------------------------------------------------------------------------------- |
|
|
130
|
+
| `--ntl-hero-bg-color` | `var(--nt-body, #e4e6ef)` | Background color when no `bg` slot content is provided. |
|
|
131
|
+
| `--ntl-hero-max-height` | `950px` | Maximum height of the hero container. |
|
|
132
|
+
| `--ntl-hero-shell-max-width` | `1200px` | Max width of the inner shell (nav + content + slider). |
|
|
133
|
+
| `--ntl-hero-content-max-width` | `940px` | Max width of the centered content block. |
|
|
134
|
+
| `--ntl-hero-slider-max-height` | `auto` (overridden in media queries) | Max height of the slider frame. |
|
|
135
|
+
| `--ntl-hero-outer-radius` | `30px` | Border radius of the outer slider wrapper/card. |
|
|
136
|
+
| `--ntl-hero-inner-radius` | `20px` | Border radius of the inner slider frame. |
|
|
137
|
+
| `--ntl-hero-height-offset` | `0px` | Value subtracted from `100vh` to reduce hero height (e.g. `80px`, `10vh`). |
|
|
138
|
+
| `--ntl-hero-slider-offset` | `3rem` | Vertical translation applied to the slider card from its bottom‑aligned position. |
|
|
139
|
+
| `--ntl-hero-padding-inline` | `1.5rem` | Horizontal padding of the hero root. |
|
|
140
|
+
| `--ntl-hero-padding-top` | `3rem` | Top padding of the hero root. |
|
|
141
|
+
| `--ntl-hero-padding-bottom` | `0rem` | Bottom padding of the hero root. |
|
|
142
|
+
| `--ntl-hero-gap` | `0rem` | Vertical gap between content and slider inside the shell. |
|
|
143
|
+
|
|
144
|
+
Example customization:
|
|
145
|
+
|
|
146
|
+
```css
|
|
147
|
+
ntl-hero.hero-large {
|
|
148
|
+
--ntl-hero-height-offset: 8vh;
|
|
149
|
+
--ntl-hero-slider-offset: 4rem;
|
|
150
|
+
--ntl-hero-content-max-width: 880px;
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Parts
|
|
155
|
+
|
|
156
|
+
You can style internal parts using `::part()`:
|
|
157
|
+
|
|
158
|
+
| Part | Description |
|
|
159
|
+
| -------------- | --------------------------------------- |
|
|
160
|
+
| `section` | Root `<section>` element of the hero |
|
|
161
|
+
| `nav` | Wrapper around the navigation slot |
|
|
162
|
+
| `content` | Wrapper around the default content slot |
|
|
163
|
+
| `slider-frame` | Outer card frame around the slider |
|
|
164
|
+
| `slider` | Inner slider container |
|
|
165
|
+
|
|
166
|
+
```css
|
|
167
|
+
ntl-hero::part(content) {
|
|
168
|
+
padding: 0 2rem;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
ntl-hero::part(slider-frame) {
|
|
172
|
+
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.15);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Styling slotted content
|
|
177
|
+
|
|
178
|
+
Slotted elements (`nav`, `bg`, default, `slider`) are authored in the light DOM, so you can style them normally:
|
|
179
|
+
|
|
180
|
+
```css
|
|
181
|
+
.hero-heading h1 {
|
|
182
|
+
font-size: clamp(2.2rem, 3vw, 3.2rem);
|
|
183
|
+
margin-bottom: 0.75rem;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.hero-heading p {
|
|
187
|
+
margin: 0;
|
|
188
|
+
color: var(--nt-text-muted);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Browser support
|
|
193
|
+
|
|
194
|
+
Works in all modern browsers that support:
|
|
195
|
+
|
|
196
|
+
- Web Components
|
|
197
|
+
- Shadow DOM
|
|
198
|
+
- CSS Custom Properties
|
|
199
|
+
|
|
200
|
+
## Accessibility
|
|
201
|
+
|
|
202
|
+
- Ensure headings in the default slot follow a proper hierarchy (`<h1>`, `<h2>`, …).
|
|
203
|
+
- Provide visible focus styles and appropriate ARIA labels inside the `nav` and `slider` content.
|
|
204
|
+
- Ensure sufficient color contrast for text over images.
|
|
205
|
+
- Provide `alt` text for all images in the `bg` and `slider` slots.
|
package/index.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ntl-hero p[slot=bg]{width:100%;height:100%;display:block}ntl-hero p[slot=bg]>img{width:100%;height:100%;object-position:center;object-fit:cover}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './src/components/ntl-hero/ntl-hero';
|
package/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { nextrap_element as z } from "@nextrap/nt-core";
|
|
2
|
+
import { waitForReady as P } from "@trunkjs/browser-utils";
|
|
3
|
+
import { unsafeCSS as g, html as O } from "lit";
|
|
4
|
+
import { customElement as E } from "lit/decorators.js";
|
|
5
|
+
import { resetStyle as j } from "@nextrap/style-reset";
|
|
6
|
+
const F = ":host{--bg-color: var(--nt-body-teritary, #e4e6ef);--container-width: var(--nt-container-width, 100%);--height-offset: 0px;--min-height: 600px;--max-height: 1800px;--breakpoint: xl}#root{width:100%;isolation:isolate;min-height:var(--min-height);display:grid;position:relative;height:calc(100vh - var(--height-offset, 0px));max-height:var(--max-height);grid-template-rows:1fr;grid-template-columns:1fr}#wrapper{padding-top:var(--top-offset);width:var(--container-width);margin:0 auto;grid-row:1;grid-column:1;z-index:1;display:flex;flex-direction:column;align-items:center}#wrapper #title,#wrapper #top-title{text-align:center}#wrapper>#title,#wrapper #content{flex-grow:1;justify-content:center}#wrapper>*{display:flex;flex-direction:column;align-items:center}#wrapper>:has(.slot-empty){display:none!important}#background{position:absolute;background-color:var(--bg-color);z-index:0;height:100%;top:0;right:0;bottom:0;left:0}.background::slotted(*){pointer-events:auto}";
|
|
7
|
+
var I = Object.create, c = Object.defineProperty, A = Object.getOwnPropertyDescriptor, x = (t, e) => (e = Symbol[t]) ? e : Symbol.for("Symbol." + t), w = (t) => {
|
|
8
|
+
throw TypeError(t);
|
|
9
|
+
}, C = (t, e, o) => e in t ? c(t, e, { enumerable: !0, configurable: !0, writable: !0, value: o }) : t[e] = o, D = (t, e) => c(t, "name", { value: e, configurable: !0 }), T = (t) => [, , , I((t == null ? void 0 : t[x("metadata")]) ?? null)], B = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], y = (t) => t !== void 0 && typeof t != "function" ? w("Function expected") : t, L = (t, e, o, a, r) => ({ kind: B[t], name: e, metadata: a, addInitializer: (i) => o._ ? w("Already initialized") : r.push(y(i || null)) }), M = (t, e) => C(e, x("metadata"), t[3]), N = (t, e, o, a) => {
|
|
10
|
+
for (var r = 0, i = t[e >> 1], n = i && i.length; r < n; r++) i[r].call(o);
|
|
11
|
+
return a;
|
|
12
|
+
}, R = (t, e, o, a, r, i) => {
|
|
13
|
+
var n, h, u, l = e & 7, f = !1, _ = 0, k = t[_] || (t[_] = []), d = l && (r = r.prototype, l < 5 && (l > 3 || !f) && A(r, o));
|
|
14
|
+
D(r, o);
|
|
15
|
+
for (var s = a.length - 1; s >= 0; s--)
|
|
16
|
+
u = L(l, o, h = {}, t[3], k), n = (0, a[s])(r, u), h._ = 1, y(n) && (r = n);
|
|
17
|
+
return M(t, r), d && c(r, o, d), f ? l ^ 4 ? i : d : r;
|
|
18
|
+
}, b, v, S;
|
|
19
|
+
const V = {
|
|
20
|
+
breakpoints: !0,
|
|
21
|
+
subLayoutApply: !0,
|
|
22
|
+
slotVisibility: !0,
|
|
23
|
+
eventBinding: !0
|
|
24
|
+
};
|
|
25
|
+
b = [E("ntl-hero")];
|
|
26
|
+
const m = class m extends (S = z(V)) {
|
|
27
|
+
async updated(e) {
|
|
28
|
+
super.updated(e), await P(), this.style.setProperty("--height-offset", `${this.offsetTop}px`);
|
|
29
|
+
}
|
|
30
|
+
render() {
|
|
31
|
+
return O`
|
|
32
|
+
<div part="root" id="root">
|
|
33
|
+
<div id="background" part="background">
|
|
34
|
+
<slot name="bg"></slot>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div id="wrapper" part="wrapper">
|
|
38
|
+
<div id="top-title" part="top-title">
|
|
39
|
+
<slot name="top-title"></slot>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div id="title" part="title">
|
|
43
|
+
<slot name="title"></slot>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div id="content" part="content">
|
|
47
|
+
<slot></slot>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div id="footer" part="footer">
|
|
51
|
+
<slot name="footer"></slot>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
m.styles = [g(F), g(j)];
|
|
59
|
+
let p = m;
|
|
60
|
+
v = T(S);
|
|
61
|
+
p = R(v, 0, "NtlHero", b, p);
|
|
62
|
+
N(v, 1, p);
|
|
63
|
+
export {
|
|
64
|
+
p as NtlHero
|
|
65
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nextrap/ntl-hero",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"main": "./index.js",
|
|
5
|
+
"repository": {
|
|
6
|
+
"directory": "nextrap-layout/ntl-hero",
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/nextrap/nextrap-monorepo"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@nextrap/style-reset": "^2.0.0",
|
|
12
|
+
"@trunkjs/browser-utils": "^1.0.28",
|
|
13
|
+
"lit": "^3.3.1"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@nextrap/style-base": "^2.0.0",
|
|
17
|
+
"@nextrap/style-utils": "^2.0.0"
|
|
18
|
+
},
|
|
19
|
+
"type": "module",
|
|
20
|
+
"types": "./index.d.ts",
|
|
21
|
+
"web-types": "./web-types.json"
|
|
22
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PropertyValues } from 'lit';
|
|
2
|
+
declare const NtlHero_base: import('@nextrap/nt-core').InternalNextrapElementType;
|
|
3
|
+
export declare class NtlHero extends NtlHero_base {
|
|
4
|
+
static styles: import('lit').CSSResult[];
|
|
5
|
+
protected updated(changedProperties: PropertyValues): Promise<void>;
|
|
6
|
+
protected render(): unknown;
|
|
7
|
+
}
|
|
8
|
+
export {};
|