@sebgroup/green-core 2.37.1 → 2.37.3

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.
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Example migration unit — template for creating new units.
3
+ *
4
+ * This file is a documented reference for how to build a migration unit.
5
+ * It has `enabled: false`, so it will not appear in `green-core-context
6
+ * migrate list` or be executed during `migrate run`.
7
+ *
8
+ * ## How to create a new migration unit
9
+ *
10
+ * 1. Create a file under `units/<major>/` (e.g. `units/3/my-migration.ts`)
11
+ * 2. Export a `MigrationUnit` object as `export const unit`
12
+ * 3. The registry auto-discovers it from the directory structure — no
13
+ * manual registration needed
14
+ *
15
+ * ## Multi-framework / multi-syntax coverage
16
+ *
17
+ * A single migration unit should cover ONE semantic change across ALL
18
+ * syntax variants. We cannot determine framework from file extension —
19
+ * an Angular template may live inside a `.ts` file, plain HTML may live
20
+ * in a `.html` file that is not Angular, and React JSX uses `.tsx`.
21
+ *
22
+ * Instead, define variant patterns for every known syntax form of the
23
+ * same attribute/property rename:
24
+ *
25
+ * - HTML attribute: `gds-theme="dark"`
26
+ * - Angular property: `[gdsTheme]="expr"`
27
+ * - Angular attr binding: `[attr.gds-theme]="expr"`
28
+ * - React JSX prop: `gdsTheme="dark"` or `gdsTheme={expr}`
29
+ * - JS property assignment: `.gdsTheme = value`
30
+ * - JS setAttribute call: `setAttribute('gds-theme', value)`
31
+ *
32
+ * All patterns are applied to ALL files. This means the unit will find
33
+ * Angular bindings in a `.tsx` file too — that is intentional and harmless.
34
+ * False positives are better than missed migrations.
35
+ *
36
+ * ## Guidelines
37
+ *
38
+ * - Keep regex patterns simple and well-commented
39
+ * - Use non-capturing groups `(?:...)` unless capture is needed
40
+ * - Reset `lastIndex` before reusing a regex with the `g` flag
41
+ * - In `detect()`, always set `file` to `filePath` — the engine
42
+ * normalises it to a relative path afterwards
43
+ * - In `apply()`, return `null` if nothing changed
44
+ * - Mark matches as `manualReview: true` when auto-fix isn't safe
45
+ * - Prefer line-by-line scanning for readable detect logic
46
+ * - Always provide `exampleBefore` / `exampleAfter` — they are used by
47
+ * coding models as context when applying changes manually
48
+ *
49
+ * @module migrate/units/0/example
50
+ */
51
+ import type { MigrationUnit } from '../../types.js';
52
+ export declare const unit: MigrationUnit;
@@ -0,0 +1,146 @@
1
+ import "../../../../../chunks/chunk.QU3DSPNU.js";
2
+ const VARIANTS = [
3
+ // ----- HTML attribute (plain HTML, web component, Angular template) -----
4
+ {
5
+ label: "HTML attribute",
6
+ pattern: /\bgds-theme\s*=\s*["']([^"']*)["']/g,
7
+ replace: (_match, value) => `gds-mode="${value}"`,
8
+ message: (m) => `Replace gds-theme="${m[1]}" with gds-mode="${m[1]}"`,
9
+ safe: true
10
+ },
11
+ // ----- Angular property binding: [gdsTheme]="expr" -----
12
+ {
13
+ label: "Angular property binding",
14
+ pattern: /\[gdsTheme\]\s*=\s*"([^"]*)"/g,
15
+ replace: (_match, expr) => `[gdsMode]="${expr}"`,
16
+ message: (m) => `Replace [gdsTheme]="${m[1]}" with [gdsMode]="${m[1]}"`,
17
+ safe: true
18
+ },
19
+ // ----- Angular explicit attr binding: [attr.gds-theme]="expr" -----
20
+ {
21
+ label: "Angular attr binding",
22
+ pattern: /\[attr\.gds-theme\]\s*=\s*"([^"]*)"/g,
23
+ replace: (_match, expr) => `[attr.gds-mode]="${expr}"`,
24
+ message: (m) => `Replace [attr.gds-theme]="${m[1]}" with [attr.gds-mode]="${m[1]}"`,
25
+ safe: true
26
+ },
27
+ // ----- React JSX prop: gdsTheme="value" or gdsTheme={expr} -----
28
+ // Negative lookbehind (?<!\.) excludes JS property access like el.gdsTheme
29
+ {
30
+ label: "React JSX prop (string)",
31
+ pattern: /(?<!\.)\bgdsTheme\s*=\s*"([^"]*)"/g,
32
+ replace: (_match, value) => `gdsMode="${value}"`,
33
+ message: (m) => `Replace gdsTheme="${m[1]}" with gdsMode="${m[1]}"`,
34
+ safe: true
35
+ },
36
+ {
37
+ label: "React JSX prop (expression)",
38
+ pattern: /(?<!\.)\bgdsTheme\s*=\s*\{([^}]*)\}/g,
39
+ replace: (_match, expr) => `gdsMode={${expr}}`,
40
+ message: (m) => `Replace gdsTheme={${m[1]}} with gdsMode={${m[1]}}`,
41
+ safe: true
42
+ },
43
+ // ----- JS/TS property assignment: .gdsTheme = value -----
44
+ {
45
+ label: "JS property assignment",
46
+ pattern: /\.gdsTheme\s*=/g,
47
+ replace: ".gdsMode =",
48
+ message: () => `Replace .gdsTheme = with .gdsMode =`,
49
+ safe: true
50
+ },
51
+ // ----- JS/TS setAttribute call: setAttribute('gds-theme', ...) -----
52
+ {
53
+ label: "setAttribute call",
54
+ pattern: /setAttribute\(\s*['"]gds-theme['"]/g,
55
+ replace: `setAttribute('gds-mode'`,
56
+ message: () => `Replace setAttribute('gds-theme', ...) with setAttribute('gds-mode', ...)`,
57
+ safe: true
58
+ }
59
+ ];
60
+ function detectVariants(filePath, content, variants) {
61
+ const matches = [];
62
+ const lines = content.split("\n");
63
+ for (let i = 0; i < lines.length; i++) {
64
+ const line = lines[i];
65
+ for (const variant of variants) {
66
+ variant.pattern.lastIndex = 0;
67
+ let m;
68
+ while ((m = variant.pattern.exec(line)) !== null) {
69
+ matches.push({
70
+ file: filePath,
71
+ line: i + 1,
72
+ match: m[0],
73
+ message: variant.message(m),
74
+ manualReview: !variant.safe
75
+ });
76
+ }
77
+ }
78
+ }
79
+ return matches;
80
+ }
81
+ function applyVariants(content, variants) {
82
+ let result = content;
83
+ for (const variant of variants) {
84
+ if (!variant.safe) continue;
85
+ variant.pattern.lastIndex = 0;
86
+ result = result.replace(variant.pattern, variant.replace);
87
+ }
88
+ return result !== content ? result : null;
89
+ }
90
+ const unit = {
91
+ id: "theme-to-mode",
92
+ enabled: false,
93
+ // Example only — not a real migration
94
+ summary: "[Example] Replace deprecated gds-theme / gdsTheme with gds-mode / gdsMode",
95
+ exampleBefore: [
96
+ "<!-- HTML attribute -->",
97
+ '<div gds-theme="dark"><gds-button>Click</gds-button></div>',
98
+ "",
99
+ "<!-- Angular property binding -->",
100
+ '<gds-card [gdsTheme]="theme"></gds-card>',
101
+ "",
102
+ "<!-- Angular explicit attr binding -->",
103
+ '<gds-card [attr.gds-theme]="theme"></gds-card>',
104
+ "",
105
+ "<!-- React JSX prop -->",
106
+ '<GdsCard gdsTheme="dark" />',
107
+ "<GdsCard gdsTheme={theme} />",
108
+ "",
109
+ "// JS property assignment",
110
+ 'el.gdsTheme = "dark"',
111
+ "",
112
+ "// JS setAttribute",
113
+ "el.setAttribute('gds-theme', 'dark')"
114
+ ].join("\n"),
115
+ exampleAfter: [
116
+ "<!-- HTML attribute -->",
117
+ '<div gds-mode="dark"><gds-button>Click</gds-button></div>',
118
+ "",
119
+ "<!-- Angular property binding -->",
120
+ '<gds-card [gdsMode]="theme"></gds-card>',
121
+ "",
122
+ "<!-- Angular explicit attr binding -->",
123
+ '<gds-card [attr.gds-mode]="theme"></gds-card>',
124
+ "",
125
+ "<!-- React JSX prop -->",
126
+ '<GdsCard gdsMode="dark" />',
127
+ "<GdsCard gdsMode={theme} />",
128
+ "",
129
+ "// JS property assignment",
130
+ 'el.gdsMode = "dark"',
131
+ "",
132
+ "// JS setAttribute",
133
+ "el.setAttribute('gds-mode', 'dark')"
134
+ ].join("\n"),
135
+ fileExtensions: [".html", ".ts", ".tsx"],
136
+ safe: true,
137
+ detect(filePath, content) {
138
+ return detectVariants(filePath, content, VARIANTS);
139
+ },
140
+ apply(_filePath, content) {
141
+ return applyVariants(content, VARIANTS);
142
+ }
143
+ };
144
+ export {
145
+ unit
146
+ };
@@ -88,7 +88,10 @@ let GdsPagination = class extends withMarginProps(
88
88
  this._isMobile = matches;
89
89
  }
90
90
  render() {
91
- if (__privateGet(this, _GdsPagination_instances, pageCount_get) <= 1) return nothing;
91
+ const pageCount = __privateGet(this, _GdsPagination_instances, pageCount_get);
92
+ const showNavigation = pageCount > 1;
93
+ const pageSizeMenu = __privateMethod(this, _GdsPagination_instances, renderPageSizeMenu_fn).call(this);
94
+ if (!showNavigation && !pageSizeMenu) return nothing;
92
95
  return html`
93
96
  <gds-flex
94
97
  align-items="center"
@@ -97,8 +100,16 @@ let GdsPagination = class extends withMarginProps(
97
100
  gap="${__privateGet(this, _GdsPagination_instances, config_get).gap}"
98
101
  >
99
102
  ${__privateMethod(this, _GdsPagination_instances, renderLabel_fn).call(this)}
100
- <gds-flex aling-items="center" gap="${__privateGet(this, _GdsPagination_instances, config_get).gap}" flex="1">
101
- ${[__privateMethod(this, _GdsPagination_instances, renderNavigationControls_fn).call(this), __privateMethod(this, _GdsPagination_instances, renderPageSizeMenu_fn).call(this)]}
103
+ <gds-flex
104
+ aling-items="center"
105
+ gap="${__privateGet(this, _GdsPagination_instances, config_get).gap}"
106
+ flex="1"
107
+ justify-content="${showNavigation ? "space-between" : "flex-end"}"
108
+ >
109
+ ${[
110
+ when(showNavigation, () => __privateMethod(this, _GdsPagination_instances, renderNavigationControls_fn).call(this)),
111
+ pageSizeMenu
112
+ ]}
102
113
  </gds-flex>
103
114
  </gds-flex>
104
115
  `;