node-red-contrib-s2 0.1.2 → 0.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-s2",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Node-RED nodes for S2 energy management protocol (EN 50491-12-2)",
5
5
  "author": "Victron Energy BV",
6
6
  "repository": {
@@ -10,6 +10,7 @@
10
10
  "main": "dist/lib/index.js",
11
11
  "files": [
12
12
  "dist/",
13
+ "resources/",
13
14
  "README.md",
14
15
  "LICENSE",
15
16
  "CHANGELOG.md"
@@ -24,10 +25,11 @@
24
25
  }
25
26
  },
26
27
  "scripts": {
27
- "prepublishOnly": "npm run build",
28
+ "prepublishOnly": "npm run build && npm run check-package-files",
28
29
  "build": "tsc && npm run copy-html",
29
30
  "clean": "rm -rf dist",
30
- "copy-html": "mkdir -p dist/nodes/s2-rm dist/nodes/s2-websocket dist/nodes/s2-rm-config dist/nodes/s2-cem-config dist/nodes/s2-rm/icons dist/nodes/s2-websocket/icons && cp src/nodes/s2-rm/index.html dist/nodes/s2-rm/ && cp src/nodes/s2-websocket/index.html dist/nodes/s2-websocket/ && cp src/nodes/s2-rm-config/index.html dist/nodes/s2-rm-config/ && cp src/nodes/s2-cem-config/index.html dist/nodes/s2-cem-config/ && cp icons/s2-logo.svg dist/nodes/s2-rm/icons/ && cp icons/s2-logo.svg dist/nodes/s2-websocket/icons/",
31
+ "copy-html": "node scripts/copy-html.js",
32
+ "check-package-files": "node scripts/check-package-files.js",
31
33
  "test": "npm run lint && npm run test:unit",
32
34
  "test:unit": "jest",
33
35
  "test:watch": "jest --watch",
@@ -0,0 +1,37 @@
1
+ /* global $ */
2
+
3
+ window.__s2Common = window.__s2Common || {}
4
+
5
+ window.__s2Common.initializeTooltips = function () {
6
+ $('.s2-tooltip-container').remove()
7
+ $('.s2-form .tooltip-icon').off('mouseenter.s2 mouseleave.s2')
8
+
9
+ $('.s2-form .tooltip-icon').on('mouseenter.s2', function () {
10
+ const $icon = $(this)
11
+ const tooltipText = $icon.attr('data-tooltip')
12
+ if (!tooltipText) return
13
+
14
+ const $tooltip = $('<div class="s2-tooltip-container"></div>').text(tooltipText)
15
+ $('body').append($tooltip)
16
+
17
+ const iconOffset = $icon.offset()
18
+ const tooltipHeight = $tooltip.outerHeight()
19
+ const tooltipWidth = $tooltip.outerWidth()
20
+
21
+ $tooltip.css({
22
+ top: iconOffset.top - tooltipHeight - 8,
23
+ left: iconOffset.left - (tooltipWidth / 2) + ($icon.outerWidth() / 2)
24
+ })
25
+
26
+ $icon.data('s2-tooltip', $tooltip)
27
+ })
28
+
29
+ $('.s2-form .tooltip-icon').on('mouseleave.s2', function () {
30
+ const $icon = $(this)
31
+ const $tooltip = $icon.data('s2-tooltip')
32
+ if ($tooltip) {
33
+ $tooltip.remove()
34
+ $icon.removeData('s2-tooltip')
35
+ }
36
+ })
37
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * S2 Node-RED Nodes - Stylesheet
3
+ *
4
+ * All selectors MUST be scoped under .s2-form to prevent
5
+ * affecting other Node-RED nodes.
6
+ *
7
+ * Label and input sizing intentionally defers to Node-RED defaults so that
8
+ * config node selectors (red-ui-search-container) lay out correctly inline.
9
+ */
10
+
11
+ /* ============================================================================
12
+ FORM LAYOUT
13
+ ============================================================================ */
14
+
15
+ .s2-form {
16
+ overflow-x: hidden;
17
+ }
18
+
19
+ /* Keep icon + text vertically centred inside labels without overriding the
20
+ width - Node-RED's default ~110px label width is used instead. */
21
+ /* Label width slightly wider than NR default (110px) to accommodate the
22
+ field icon + text. The tooltip icon is absolutely positioned inside the
23
+ label so it never pushes the input - all inputs align consistently. */
24
+ .s2-form .form-row label {
25
+ display: inline-flex;
26
+ align-items: center;
27
+ gap: 4px;
28
+ white-space: nowrap;
29
+ width: 120px !important;
30
+ position: relative;
31
+ padding-right: 20px;
32
+ box-sizing: border-box;
33
+ }
34
+
35
+ .s2-form .form-row input[type="checkbox"] {
36
+ width: auto !important;
37
+ }
38
+
39
+ /* Tooltip icon - absolutely positioned at the right edge of the label. */
40
+ .s2-form .tooltip-icon {
41
+ position: absolute;
42
+ right: 2px;
43
+ top: 50%;
44
+ transform: translateY(-50%);
45
+ font-size: 0.8em;
46
+ color: #00BCFF;
47
+ cursor: help;
48
+ }
49
+
50
+ /* Tooltip container - appended to <body> by s2-common.js so it is never
51
+ clipped by a parent overflow or panel boundary. */
52
+ .s2-tooltip-container {
53
+ position: absolute;
54
+ background: #fff;
55
+ color: #444;
56
+ padding: 8px 12px;
57
+ border: 1px solid #ccc;
58
+ border-radius: 3px;
59
+ font-size: 13px;
60
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
61
+ line-height: 1.4;
62
+ max-width: 280px;
63
+ z-index: 10000;
64
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
65
+ pointer-events: none;
66
+ }
67
+
68
+ /* ============================================================================
69
+ CONTROL TYPES / ROLES - Checkbox Grid
70
+ ============================================================================ */
71
+
72
+ /* Section labels (Roles, Control Types) span the full row. */
73
+ .s2-form .s2-section-label {
74
+ width: 100% !important;
75
+ display: inline-block;
76
+ }
77
+
78
+ /* Indent checkbox grid to align with inputs (matches Node-RED default label width). */
79
+ .s2-form .s2-full-row {
80
+ display: block;
81
+ margin-left: 110px;
82
+ }
83
+
84
+ .s2-form .s2-control-types-container {
85
+ display: grid;
86
+ grid-template-columns: 116px 116px;
87
+ gap: 6px 8px;
88
+ }
89
+
90
+ .s2-form .s2-checkbox-label {
91
+ display: flex;
92
+ align-items: center;
93
+ gap: 6px;
94
+ width: auto !important;
95
+ font-weight: normal;
96
+ cursor: pointer;
97
+ }
98
+
99
+ .s2-form .s2-checkbox-label input[type="checkbox"] {
100
+ width: auto;
101
+ margin: 0;
102
+ flex-shrink: 0;
103
+ }
104
+
105
+ /* ============================================================================
106
+ UNIT LABELS AND BATTERY LIMIT ROWS
107
+ ============================================================================ */
108
+
109
+ /* Unit suffix (W, ms) displayed after a number input */
110
+ .s2-form .s2-unit-label {
111
+ margin-left: 6px;
112
+ white-space: nowrap;
113
+ color: #555;
114
+ flex-shrink: 0;
115
+ }
116
+
117
+ /* Battery limit rows use flex so the unit label stays on the same line as
118
+ the input, and are indented to visually nest them under the section header. */
119
+ .s2-form .s2-battery-row {
120
+ display: flex;
121
+ align-items: center;
122
+ padding-left: 20px;
123
+ }
124
+
125
+ .s2-form .s2-battery-row label {
126
+ flex-shrink: 0;
127
+ }
128
+
129
+ .s2-form .s2-battery-row input[type="number"] {
130
+ flex: 1;
131
+ min-width: 0;
132
+ width: auto !important;
133
+ }
134
+
135
+ /* Advanced section rows use flex to keep unit labels inline. */
136
+ .s2-form .s2-advanced-row {
137
+ display: flex;
138
+ align-items: center;
139
+ }
140
+
141
+ .s2-form .s2-advanced-row label {
142
+ flex-shrink: 0;
143
+ }
144
+
145
+ .s2-form .s2-advanced-row input[type="number"] {
146
+ flex: 1;
147
+ min-width: 0;
148
+ width: auto !important;
149
+ }
150
+
151
+ /* Advanced toggle link */
152
+ .s2-form .s2-advanced-toggle {
153
+ color: #666;
154
+ font-size: 0.9em;
155
+ text-decoration: none;
156
+ display: inline-flex;
157
+ align-items: center;
158
+ gap: 5px;
159
+ }
160
+
161
+ .s2-form .s2-advanced-toggle:hover {
162
+ color: #333;
163
+ text-decoration: none;
164
+ }