@nextrap/ntl-2col 0.1.4 → 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/index.scss ADDED
@@ -0,0 +1,11 @@
1
+ @forward 'src/scss/default-style';
2
+ @forward 'src/scss/with-alternating';
3
+ @forward 'src/scss/with-background-and-divider';
4
+ @forward 'src/scss/with-breakout-end';
5
+ @forward 'src/scss/with-breakout-start';
6
+ @forward 'src/scss/with-image-auto-objectfit';
7
+ @forward 'src/scss/with-justify';
8
+ @forward 'src/scss/with-main-sticky-top';
9
+ @forward 'src/scss/with-modifier-classes';
10
+ @forward 'src/scss/with-reverse';
11
+ @forward 'src/scss/with-wrapper-bg-color';
package/package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "name": "@nextrap/ntl-2col",
3
- "version": "0.1.4",
3
+ "version": "2.0.0",
4
+ "files": [
5
+ "*.*",
6
+ "src",
7
+ ".agents"
8
+ ],
4
9
  "main": "./index.js",
5
- "dependencies": {},
10
+ "repository": {
11
+ "directory": "nextrap-layout/ntl-2col",
12
+ "type": "git",
13
+ "url": "https://github.com/nextrap/nextrap-monorepo"
14
+ },
15
+ "dependencies": {
16
+ "@nextrap/nt-core": "^2.0.0"
17
+ },
6
18
  "type": "module",
7
- "types": "./index.d.ts"
19
+ "types": "./index.d.ts",
20
+ "web-types": "./web-types.json"
8
21
  }
@@ -0,0 +1,7 @@
1
+ declare const Ntl2Col_base: import('@nextrap/nt-core').InternalNextrapElementType;
2
+ export declare class Ntl2Col extends Ntl2Col_base {
3
+ static styles: import('lit').CSSResult[];
4
+ connectedCallback(): void;
5
+ protected render(): unknown;
6
+ }
7
+ export {};
@@ -0,0 +1,133 @@
1
+ :host {
2
+ --gap: var(--nt-spacing-layout);
3
+ --container-width: var(--nt-container-width, 100%);
4
+ --inner-padding: var(--nt-space-3);
5
+ --section-bg: transparent; // The main background
6
+
7
+ --cols: 6;
8
+ --breakpoint: md;
9
+
10
+ background: var(--section-bg);
11
+ display: block;
12
+ }
13
+
14
+ #container {
15
+ margin-left: var(--container-margin-left, auto);
16
+ margin-right: var(--container-margin-right, auto);
17
+ width: var(--container-render-width, var(--container-width));
18
+
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ #wrapper {
23
+ box-sizing: border-box;
24
+ --aside-width: 100%;
25
+ display: flex;
26
+ flex-direction: column;
27
+ flex-wrap: wrap;
28
+ gap: var(--gap);
29
+ align-items: stretch;
30
+ }
31
+
32
+ #header,
33
+ #footer,
34
+ #top,
35
+ #bottom {
36
+ width: 100%;
37
+ box-sizing: border-box;
38
+
39
+ &:has(.slot-empty) {
40
+ display: none;
41
+ }
42
+ }
43
+
44
+ #top {
45
+ order: 0;
46
+ flex: 0 0 auto;
47
+ }
48
+
49
+ #main {
50
+ box-sizing: border-box;
51
+ order: 1;
52
+ min-width: 0;
53
+ }
54
+
55
+ #aside {
56
+ box-sizing: border-box;
57
+ order: 2;
58
+ min-width: 0;
59
+ }
60
+
61
+ #bottom {
62
+ order: 3;
63
+ flex: 0 0 auto;
64
+ }
65
+
66
+ :host([mode='mobile']) {
67
+ #container {
68
+ margin-left: 0;
69
+ margin-right: 0;
70
+ width: 100%;
71
+ }
72
+
73
+ // Ensures both mobile content regions always span the complete available width.
74
+ #main,
75
+ #aside {
76
+ width: 100%;
77
+ flex: 0 0 100%;
78
+ }
79
+ }
80
+
81
+ :host([mode='mobile'].mobile-reverse) {
82
+ #aside {
83
+ order: 1;
84
+ }
85
+
86
+ #main {
87
+ order: 2;
88
+ }
89
+ }
90
+
91
+ :host([mode='desktop'].desktop-reverse) {
92
+ #wrapper {
93
+ flex-direction: row-reverse;
94
+ }
95
+ }
96
+
97
+ :host([mode='desktop']) {
98
+ #wrapper {
99
+ flex-direction: row;
100
+ --main-width: calc(100% * var(--cols, 1) / 12);
101
+ &:has(#aside > .slot-empty) {
102
+ flex-direction: column;
103
+
104
+ #main {
105
+ width: 100%;
106
+ flex-basis: 100%;
107
+ }
108
+ }
109
+ #main {
110
+ width: var(--main-width);
111
+ flex: 0 0 var(--main-width);
112
+ box-sizing: border-box;
113
+ display: flex;
114
+ flex-direction: column;
115
+ justify-content: flex-start;
116
+ }
117
+ #aside {
118
+ flex: 1 1 0;
119
+ box-sizing: border-box;
120
+ }
121
+ }
122
+
123
+ #aside {
124
+ width: auto;
125
+ min-width: 0;
126
+ flex: 1 1 0;
127
+ box-sizing: border-box;
128
+
129
+ &:has(.slot-empty) {
130
+ display: none;
131
+ }
132
+ }
133
+ }
@@ -0,0 +1,78 @@
1
+ @use 'with-image-auto-objectfit' as image-auto-objectfit;
2
+ @use 'with-justify' as justify;
3
+ @use 'with-modifier-classes' as modifier-classes;
4
+ @use 'with-wrapper-bg-color' as wrapper-bg;
5
+
6
+ @mixin default-style(
7
+ $innerPadding: var(--nt-space-3),
8
+ $gap: var(--nt-spacing-layout),
9
+ $background: transparent,
10
+ $border: 1px solid var(--nt-dark),
11
+ $border-radius: var(--nt-border-radius),
12
+ $objectFit: cover,
13
+ $aspectRatio: none,
14
+ $modifierClasses: true,
15
+ $wrapper-bg-color: transparent,
16
+ $justify: center
17
+ ) {
18
+ --background: #{$background};
19
+ --border: #{$border};
20
+ --border-radius: #{$border-radius};
21
+ --inner-padding: #{$innerPadding};
22
+ --gap: #{$gap};
23
+
24
+ @include wrapper-bg.with-wrapper-bg-color($wrapper-bg-color);
25
+
26
+ @if ($justify != none) {
27
+ @include justify.with-justify($justify);
28
+ }
29
+
30
+ @if ($aspectRatio != none) {
31
+ --aspectRatio: #{$aspectRatio};
32
+ &::part(aside) {
33
+ aspect-ratio: #{$aspectRatio};
34
+ }
35
+ }
36
+
37
+ @if ($objectFit != none) {
38
+ // Object-Fit für Bilder, die automatisch in den Aside Bereich geladen werden
39
+
40
+ @include image-auto-objectfit.with-image-auto-objectfit($objectFit);
41
+ }
42
+
43
+ @if ($modifierClasses != false and $modifierClasses != none) {
44
+ @include modifier-classes.with-modifier-classes();
45
+ }
46
+
47
+ // Getestete, verbindliche Abstandslogik: Der innere Padding-Wert ist der gemeinsame Gap für alle Regionen. Nicht ändern, ohne alle Slot-Kombinationen erneut zu prüfen.
48
+ &::part(wrapper) {
49
+ border: var(--border);
50
+ border-radius: var(--border-radius);
51
+ overflow: hidden;
52
+ gap: var(--inner-padding);
53
+ }
54
+
55
+ // Getestete, verbindliche Main-Abstände: nur horizontales Padding, weil die vertikale Trennung über den gemeinsamen Gap erfolgt. Nicht ändern, ohne alle Slot-Kombinationen erneut zu prüfen.
56
+ &::part(main) {
57
+ padding-inline: var(--inner-padding);
58
+ }
59
+
60
+ // Getestete, verbindliche Top-Abstände: der äußere vertikale Rand bleibt, die innere Kante nutzt den gemeinsamen Gap. Nicht ändern, ohne alle Slot-Kombinationen erneut zu prüfen.
61
+ &::part(top) {
62
+ padding: var(--inner-padding);
63
+ padding-block-end: 0;
64
+ }
65
+
66
+ // Getestete, verbindliche Bottom-Abstände: der äußere vertikale Rand bleibt, die innere Kante nutzt den gemeinsamen Gap. Nicht ändern, ohne alle Slot-Kombinationen erneut zu prüfen.
67
+ &::part(bottom) {
68
+ padding: var(--inner-padding);
69
+ padding-block-start: 0;
70
+ }
71
+
72
+ // Fügt dem Aside-Bereich nur bei explizit zugewiesenen Aside-Inhalten Innenabstand hinzu.
73
+ &:has(.aside:not(.p-0)) {
74
+ &::part(aside) {
75
+ padding-inline: var(--inner-padding);
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,10 @@
1
+ @mixin with-alternating {
2
+ &[mode='desktop']:nth-of-type(even) {
3
+ &::part(main) {
4
+ order: 2;
5
+ }
6
+ &::part(aside) {
7
+ order: 1;
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,25 @@
1
+ @mixin with-background-and-divider($gap: 2rem, $background: var(--nt-primary), $divider-color: var(--nt-light)) {
2
+ --section-bg: #{$background};
3
+ --border: none;
4
+ --gap: #{$gap};
5
+
6
+ &[mode='desktop'] {
7
+ &::part(aside) {
8
+ position: relative;
9
+ }
10
+
11
+ &::part(aside)::after {
12
+ content: '';
13
+ position: absolute;
14
+ top: 25%;
15
+ bottom: 25%;
16
+ left: calc(var(--gap) / -2);
17
+ border-left: 1px solid #{$divider-color};
18
+ }
19
+
20
+ &.desktop-reverse::part(aside)::after {
21
+ right: calc(var(--gap) / -2);
22
+ left: auto;
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,28 @@
1
+ @mixin with-breakout-end {
2
+ &[mode='mobile'] {
3
+ }
4
+
5
+ &[mode='desktop'] {
6
+ --breakout-container-width: var(--container-width, var(--nt-container-width, 100%));
7
+ --breakout-space: max(0px, calc((100vw - var(--breakout-container-width)) / 2));
8
+ --container-render-width: calc(var(--breakout-container-width) + var(--breakout-space));
9
+ --container-margin-left: auto;
10
+ --container-margin-right: 0;
11
+
12
+ &::part(header),
13
+ &::part(footer) {
14
+ width: var(--breakout-container-width);
15
+ box-sizing: border-box;
16
+ }
17
+
18
+ &::part(main) {
19
+ width: calc(var(--breakout-container-width) * var(--cols) / 12);
20
+ flex-basis: calc(var(--breakout-container-width) * var(--cols) / 12);
21
+ }
22
+
23
+ &::part(aside) {
24
+ width: auto;
25
+ flex: 1 1 0;
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,30 @@
1
+ @mixin with-breakout-start {
2
+ &[mode='desktop'] {
3
+ --breakout-container-width: var(--container-width, var(--nt-container-width, 100%));
4
+ --breakout-space: max(0px, calc((100vw - var(--breakout-container-width)) / 2));
5
+ --container-render-width: calc(var(--breakout-container-width) + var(--breakout-space));
6
+ --container-margin-left: 0;
7
+ --container-margin-right: auto;
8
+
9
+ &::part(header),
10
+ &::part(footer) {
11
+ width: var(--breakout-container-width);
12
+ margin-left: auto;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ &::part(wrapper) {
17
+ flex-direction: row-reverse;
18
+ }
19
+
20
+ &::part(main) {
21
+ width: calc(var(--breakout-container-width) * var(--cols) / 12);
22
+ flex-basis: calc(var(--breakout-container-width) * var(--cols) / 12);
23
+ }
24
+
25
+ &::part(aside) {
26
+ width: auto;
27
+ flex: 1 1 0;
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,28 @@
1
+ @mixin with-image-auto-objectfit($objectFit: cover) {
2
+ &:has(> p[slot='aside'].auto)::part(aside) {
3
+ padding: 0; // remove padding for auto aside
4
+ }
5
+
6
+ p[slot='aside'].auto {
7
+ height: 100%;
8
+ width: 100%;
9
+ display: block;
10
+ & > img {
11
+ width: 100%;
12
+ height: 100%;
13
+ object-fit: #{$objectFit};
14
+ object-position: center center;
15
+ }
16
+ }
17
+
18
+ &[mode='mobile']:has(> p[slot='aside'].auto) {
19
+ // Always set the image top
20
+ &::part(main) {
21
+ order: 2;
22
+ }
23
+
24
+ &::part(aside) {
25
+ order: 1;
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,10 @@
1
+ @mixin with-justify($justify: center) {
2
+ &[mode='desktop'] {
3
+ &::part(main),
4
+ &::part(aside) {
5
+ display: flex;
6
+ flex-direction: column;
7
+ justify-content: $justify;
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,13 @@
1
+ @mixin with-main-sticky-top($top: var(--main-sticky-top, var(--nt-spacing-layout))) {
2
+ &[mode='desktop'] {
3
+ &::part(wrapper) {
4
+ overflow: clip;
5
+ }
6
+
7
+ &::part(main) {
8
+ position: sticky;
9
+ top: $top;
10
+ align-self: flex-start;
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,52 @@
1
+ @use 'with-breakout-end' as breakout-end;
2
+ @use 'with-breakout-start' as breakout-start;
3
+ @use 'with-justify' as justify;
4
+ @use 'with-main-sticky-top' as main-sticky-top;
5
+
6
+ @mixin with-modifier-classes {
7
+ &.reverse {
8
+ &[mode='mobile'] {
9
+ &::part(aside) {
10
+ order: 1;
11
+ }
12
+
13
+ &::part(main) {
14
+ order: 2;
15
+ }
16
+ }
17
+
18
+ &[mode='desktop']::part(wrapper) {
19
+ flex-direction: row-reverse;
20
+ }
21
+ }
22
+
23
+ &.reverse-desktop {
24
+ &[mode='desktop']::part(wrapper) {
25
+ flex-direction: row-reverse;
26
+ }
27
+ }
28
+
29
+ &.breakout-start {
30
+ @include breakout-start.with-breakout-start;
31
+ }
32
+
33
+ &.breakout-end {
34
+ @include breakout-end.with-breakout-end;
35
+ }
36
+
37
+ &.with-justify-top {
38
+ @include justify.with-justify(flex-start);
39
+ }
40
+
41
+ &.with-justify-center {
42
+ @include justify.with-justify(center);
43
+ }
44
+
45
+ &.with-justify-bottom {
46
+ @include justify.with-justify(flex-end);
47
+ }
48
+
49
+ &.with-main-sticky-top {
50
+ @include main-sticky-top.with-main-sticky-top();
51
+ }
52
+ }
@@ -0,0 +1,5 @@
1
+ @mixin with-reverse {
2
+ &::part(wrapper) {
3
+ flex-direction: row-reverse;
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ @mixin with-wrapper-bg-color($background: transparent) {
2
+ &::part(wrapper) {
3
+ background: #{$background};
4
+ }
5
+ }