@profitlich/template-toolkit 3.0.1 → 4.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.
@@ -17,7 +17,7 @@ $color--dev-grid-center: rgba(0, 0, 0, 0.2);
17
17
  // the grid is made through repition
18
18
  // 'important' because background settings are more specific than the grid settings
19
19
  background-size: calc((100% - ($columns * $gutter)) * calc(1 / $columns) + $gutter) 1px !important;
20
- margin: 0 ($margin-right - calc($gutter / 2)) 0 ($margin-left - calc($gutter / 2));
20
+ margin: 0 calc($margin-right - calc($gutter / 2)) 0 calc($margin-left - calc($gutter / 2));
21
21
  // The grid is calculated starting from the middle
22
22
  // Thats why its necessary to add the half of the column gap to the left and right side
23
23
  width: calc(100% - $margin-right + calc($gutter / 2) - $margin-left + calc($gutter / 2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profitlich/template-toolkit",
3
- "version": "3.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "Shared SCSS layout system, JS utilities, components and build scripts for profitlich template repos",
5
5
  "type": "module",
6
6
  "exports": {
@@ -16,10 +16,12 @@
16
16
  "./utils/MailAdresses": "./utils/MailAdresses.js",
17
17
  "./utils/MediaQueries": "./utils/MediaQueries.js",
18
18
  "./utils/Vh100": "./utils/Vh100.js",
19
+ "./utils/VwBody": "./utils/VwBody.js",
19
20
  "./utils/ImagesLoaded": "./utils/images-loaded/ImagesLoaded.js",
20
21
  "./scripts/copy-files": "./scripts/copy-files.js",
21
22
  "./scripts/deploy": "./scripts/deploy.js",
22
- "./vite/jsonToScss": "./vite/jsonToScss.js"
23
+ "./vite/jsonToScss": "./vite/jsonToScss.js",
24
+ "./vite/capsizeSassFunctions": "./vite/capsizeSassFunctions.js"
23
25
  },
24
26
  "files": [
25
27
  "components/",
@@ -39,9 +41,17 @@
39
41
  "lil-gui": "^0.21.0"
40
42
  },
41
43
  "peerDependencies": {
44
+ "@capsizecss/core": ">=4.0.0",
45
+ "@capsizecss/unpack": ">=2.0.0",
42
46
  "@mux/mux-player": ">=3.0.0"
43
47
  },
44
48
  "peerDependenciesMeta": {
49
+ "@capsizecss/core": {
50
+ "optional": true
51
+ },
52
+ "@capsizecss/unpack": {
53
+ "optional": true
54
+ },
45
55
  "@mux/mux-player": {
46
56
  "optional": true
47
57
  }
@@ -4,6 +4,21 @@
4
4
  @use "sass:meta";
5
5
  @use "sass:math";
6
6
 
7
+ // capsize-trims wird ggf. von Vite via preprocessorOptions.scss.functions bereitgestellt
8
+ // (siehe createCapsizeFunctions in vite/capsizeSassFunctions.js).
9
+
10
+ // Liest das optionale Top-Level Feld `vwBasis` aus der Konsumenten-config.
11
+ // Default 'viewport' = bisheriges Verhalten (raw vw).
12
+ // 'body' = calc(var(--vw-body, 1vw) * X) — skaliert mit scrollbar-freier Body-Breite.
13
+ @function _vw-basis() {
14
+ $vars: meta.module-variables('config');
15
+ $value: map.get($vars, 'vwBasis');
16
+ @if $value {
17
+ @return $value;
18
+ }
19
+ @return 'viewport';
20
+ }
21
+
7
22
  // Media queries get the breakpoints
8
23
  // Breakpints get the layouts
9
24
  // Depending on the project, only a part of the layout names are used,
@@ -69,13 +84,24 @@ $mediaqueries: (
69
84
 
70
85
 
71
86
  // Font
72
- @mixin font($layout, $fontSize, $lineHeight, $bold:'false') {
87
+ @mixin font($layout, $fontSize, $lineHeight, $capsize: null) {
73
88
 
74
89
  font-size: size($layout, $fontSize);
75
90
  line-height: size($layout, $lineHeight);
76
91
 
77
- @if ($bold != 'false') {
78
- font-weight: $bold;
92
+ @if ($capsize != null) {
93
+ // capsize-pseudo-elements() ist eine Sass-Custom-Function aus dem Toolkit-Vite-Plugin.
94
+ // Ruft intern @capsizecss/core.createStyleObject auf und gibt eine Sass-Map
95
+ // mit allen Pseudo-Element-Stilen zurück. Inhalte (welche Pseudo-Elemente,
96
+ // welche Properties) kommen vollständig aus Capsize.
97
+ $pseudo: capsize-pseudo-elements($capsize, $fontSize, $lineHeight);
98
+ @each $selector-suffix, $props in $pseudo {
99
+ &#{$selector-suffix} {
100
+ @each $prop, $val in $props {
101
+ #{$prop}: $val;
102
+ }
103
+ }
104
+ }
79
105
  }
80
106
 
81
107
  }
@@ -187,7 +213,12 @@ $mediaqueries: (
187
213
  @if ($unit-type == 'px') {
188
214
  @return $number * 1px;
189
215
  } @else if ($unit-type == 'vw') {
190
- @return _decimal-round(math.div($number, $width) * 100, 2) * 1vw;
216
+ $factor: math.div($number, $width) * 100;
217
+ @if (_vw-basis() == 'body') {
218
+ @return calc(var(--vw-body, 1vw) * #{$factor});
219
+ } @else {
220
+ @return _decimal-round($factor, 2) * 1vw;
221
+ }
191
222
  } @else {
192
223
  @error "Nicht unterstützter Einheitstyp '#{$unit-type}' für Layout '#{$layout}'. Nur 'px' oder 'vw' werden unterstützt.";
193
224
  }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Setzt --vw-body als 1% der scrollbar-freien Body-Breite.
3
+ * Wird benötigt, wenn config.json vwBasis: "body" gesetzt hat.
4
+ */
5
+ export class VwBody {
6
+ static #instance;
7
+ vw = 0;
8
+
9
+ constructor() {
10
+ this.#calculate();
11
+ window.addEventListener('resize', () => {
12
+ this.#calculate();
13
+ });
14
+ }
15
+
16
+ #calculate() {
17
+ this.vw = document.documentElement.clientWidth * 0.01;
18
+ document.documentElement.style.setProperty('--vw-body', `${this.vw}px`);
19
+ }
20
+
21
+ static getInstance() {
22
+ if (!VwBody.#instance) {
23
+ VwBody.#instance = new VwBody();
24
+ }
25
+ return VwBody.#instance;
26
+ }
27
+ }
@@ -0,0 +1,92 @@
1
+ import { fromFile } from '@capsizecss/unpack';
2
+ import { createStyleObject } from '@capsizecss/core';
3
+ import * as sass from 'sass';
4
+ import { OrderedMap } from 'immutable';
5
+ import path from 'path';
6
+
7
+ /**
8
+ * Erzeugt ein Sass-functions-Objekt, das die Custom-Function
9
+ * `capsize-pseudo-elements($name, $fontSize, $lineHeight)` bereitstellt.
10
+ *
11
+ * Die Funktion ruft intern @capsizecss/core.createStyleObject auf und gibt
12
+ * eine Sass-Map mit allen Pseudo-Element-Stilen zurück. Beispiel-Struktur:
13
+ *
14
+ * (
15
+ * '::before': (content: '', margin-bottom: -0.123em, display: table),
16
+ * '::after': (content: '', margin-top: -0.456em, display: table),
17
+ * )
18
+ *
19
+ * SCSS iteriert die Map und emittiert die Pseudo-Element-Regeln. Damit
20
+ * kommt das CSS-Schema (welche Properties, welche Pseudo-Elemente) komplett
21
+ * aus Capsize — Updates fliessen direkt durch.
22
+ *
23
+ * @param {Object<string,string>} fontFiles - Map: Font-Name → Pfad zur Font-Datei
24
+ * @returns {Promise<Object>} - functions-Objekt für preprocessorOptions.scss.functions
25
+ */
26
+ export async function createCapsizeFunctions(fontFiles) {
27
+ const metrics = {};
28
+ for (const [name, file] of Object.entries(fontFiles)) {
29
+ metrics[name] = await fromFile(path.resolve(file));
30
+ }
31
+
32
+ return {
33
+ 'capsize-pseudo-elements($name, $fontSize, $lineHeight)': (args) => {
34
+ const name = args[0].assertString('name').text;
35
+ const fontSize = args[1].assertNumber('fontSize').value;
36
+ const lineHeight = args[2].assertNumber('lineHeight').value;
37
+
38
+ const fontMetrics = metrics[name];
39
+ if (!fontMetrics) {
40
+ throw new Error(
41
+ `capsize-pseudo-elements: Keine Metriken für Font "${name}" geladen. ` +
42
+ `Verfügbar: ${Object.keys(metrics).join(', ') || '(keine)'}.`
43
+ );
44
+ }
45
+
46
+ // createStyleObject liefert font-size, line-height, ::before, ::after.
47
+ // Wir nehmen nur die Pseudo-Elemente — font-size/line-height
48
+ // werden im SCSS via size() aus vwBody erzeugt.
49
+ const styles = createStyleObject({ fontSize, leading: lineHeight, fontMetrics });
50
+
51
+ const entries = [];
52
+ for (const [key, val] of Object.entries(styles)) {
53
+ if (key.startsWith('::')) {
54
+ entries.push([
55
+ new sass.SassString(key, { quotes: false }),
56
+ _objToSassMap(val),
57
+ ]);
58
+ }
59
+ }
60
+ return new sass.SassMap(OrderedMap(entries));
61
+ }
62
+ };
63
+ }
64
+
65
+ // camelCase → kebab-case
66
+ function _toKebab(s) {
67
+ return s.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase());
68
+ }
69
+
70
+ // JS-Wert (number | string) → Sass-Wert (SassNumber | SassString)
71
+ function _jsValueToSass(value) {
72
+ if (typeof value === 'number') {
73
+ return new sass.SassNumber(value);
74
+ }
75
+ if (typeof value === 'string') {
76
+ const m = value.match(/^(-?\d*\.?\d+)([a-z%]+)$/);
77
+ if (m) {
78
+ return new sass.SassNumber(parseFloat(m[1]), m[2]);
79
+ }
80
+ return new sass.SassString(value, { quotes: false });
81
+ }
82
+ throw new Error(`capsize-pseudo-elements: unerwarteter Wert-Typ ${typeof value}`);
83
+ }
84
+
85
+ // JS-Objekt {camelCaseKey: value} → Sass-Map (kebab-case-key, SassValue)
86
+ function _objToSassMap(obj) {
87
+ const entries = Object.entries(obj).map(([key, val]) => [
88
+ new sass.SassString(_toKebab(key), { quotes: false }),
89
+ _jsValueToSass(val),
90
+ ]);
91
+ return new sass.SassMap(OrderedMap(entries));
92
+ }