@jjlmoya/utils-babies 1.2.0 → 1.3.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.
Files changed (27) hide show
  1. package/package.json +1 -1
  2. package/src/tool/baby-feeding-calculator/bibliography.astro +8 -4
  3. package/src/tool/baby-feeding-calculator/component.astro +208 -177
  4. package/src/tool/baby-feeding-calculator/style.css +317 -229
  5. package/src/tool/baby-percentile-calculator/bibliography.astro +8 -4
  6. package/src/tool/baby-percentile-calculator/component.astro +98 -240
  7. package/src/tool/baby-percentile-calculator/i18n/en.ts +1 -0
  8. package/src/tool/baby-percentile-calculator/i18n/es.ts +1 -0
  9. package/src/tool/baby-percentile-calculator/i18n/fr.ts +1 -0
  10. package/src/tool/baby-percentile-calculator/index.ts +1 -0
  11. package/src/tool/baby-percentile-calculator/style.css +342 -268
  12. package/src/tool/baby-size-converter/bibliography.astro +8 -4
  13. package/src/tool/baby-size-converter/component.astro +221 -212
  14. package/src/tool/baby-size-converter/style.css +433 -263
  15. package/src/tool/fertile-days-estimator/bibliography.astro +8 -4
  16. package/src/tool/fertile-days-estimator/component.astro +202 -200
  17. package/src/tool/fertile-days-estimator/style.css +408 -270
  18. package/src/tool/pregnancy-calculator/bibliography.astro +8 -4
  19. package/src/tool/pregnancy-calculator/component.astro +50 -8
  20. package/src/tool/pregnancy-calculator/i18n/en.ts +8 -0
  21. package/src/tool/pregnancy-calculator/i18n/es.ts +8 -0
  22. package/src/tool/pregnancy-calculator/i18n/fr.ts +8 -0
  23. package/src/tool/pregnancy-calculator/index.ts +8 -0
  24. package/src/tool/pregnancy-calculator/style.css +351 -134
  25. package/src/tool/vaccination-calendar/bibliography.astro +8 -4
  26. package/src/tool/vaccination-calendar/component.astro +120 -124
  27. package/src/tool/vaccination-calendar/style.css +296 -209
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-babies",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -1,7 +1,11 @@
1
1
  ---
2
2
  import { Bibliography as BibliographyUI } from '@jjlmoya/utils-shared';
3
- import type { BibliographyEntry } from '../../types';
4
- interface Props { links?: BibliographyEntry[]; title: string; }
5
- const { links = [], title } = Astro.props;
3
+ import { babyFeedingCalculator } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props { locale?: KnownLocale; }
7
+ const { locale = 'es' } = Astro.props;
8
+ const content = await babyFeedingCalculator.i18n[locale]?.();
9
+ if (!content) return null;
6
10
  ---
7
- <BibliographyUI links={links} title={title} />
11
+ <BibliographyUI links={content.bibliography} title={content.bibliographyTitle ?? ''} />
@@ -4,207 +4,238 @@ import type { BabyFeedingCalculatorUI } from './index';
4
4
  interface Props { ui: BabyFeedingCalculatorUI; }
5
5
  const { ui } = Astro.props;
6
6
  ---
7
- <div id="baby-feeding-calculator-root" class="baby-feeding-calculator" data-ui={JSON.stringify(ui)}>
8
- <div class="baby-feeding-calculator-card">
9
- <div class="baby-feeding-calculator-card-main">
10
- <div class="baby-feeding-calculator-card-left">
11
- <div class="baby-feeding-calculator-section-marker">{ui.labelConfig}</div>
12
-
13
- <div class="baby-feeding-calculator-input-group">
14
- <div class="baby-feeding-calculator-input-label">Edad del bebé</div>
15
- <div class="baby-feeding-calculator-unit-nav">
16
- <button class="baby-feeding-calculator-unit-tab active" data-unit="days">{ui.unitDays}</button>
17
- <button class="baby-feeding-calculator-unit-tab" data-unit="weeks">{ui.unitWeeks}</button>
18
- <button class="baby-feeding-calculator-unit-tab" data-unit="months">{ui.unitMonths}</button>
19
- </div>
20
- <div class="baby-feeding-calculator-stepper-box">
21
- <button class="baby-feeding-calculator-btn-step" id="bfc-age-dec" aria-label="Reducir edad">−</button>
22
- <div class="baby-feeding-calculator-val-view">
23
- <span class="baby-feeding-calculator-val-big" id="bfc-age-val">7</span>
24
- <span class="baby-feeding-calculator-val-sub" id="bfc-age-unit">{ui.unitDays}</span>
25
- </div>
26
- <button class="baby-feeding-calculator-btn-step" id="bfc-age-inc" aria-label="Aumentar edad">+</button>
7
+ <div id="bfc-root" class="bfc-card" data-ui={JSON.stringify(ui)}>
8
+ <div class="bfc-main">
9
+ <div class="bfc-left">
10
+ <span class="bfc-section-marker">{ui.labelConfig}</span>
11
+
12
+ <div class="bfc-input-group">
13
+ <div class="bfc-unit-nav">
14
+ <button class="bfc-unit-tab bfc-unit-active" data-unit="days">{ui.unitDays}</button>
15
+ <button class="bfc-unit-tab" data-unit="weeks">{ui.unitWeeks}</button>
16
+ <button class="bfc-unit-tab" data-unit="months">{ui.unitMonths}</button>
17
+ </div>
18
+ <div class="bfc-stepper-box">
19
+ <button class="bfc-btn-step" data-action="dec" data-target="bfc-age-slider" aria-label="Reducir edad">-</button>
20
+ <div class="bfc-val-view">
21
+ <span class="bfc-val-big" id="bfc-age-val">7</span>
22
+ <span class="bfc-val-sub" id="bfc-age-unit">{ui.unitDays}</span>
27
23
  </div>
28
- <input class="baby-feeding-calculator-slider-line" type="range" id="bfc-age-slider" min="0" max="30" value="7" />
24
+ <button class="bfc-btn-step" data-action="inc" data-target="bfc-age-slider" aria-label="Aumentar edad">+</button>
29
25
  </div>
26
+ <div class="bfc-slider-wrap">
27
+ <input type="range" id="bfc-age-slider" min="1" max="30" step="1" value="7" class="bfc-slider" />
28
+ </div>
29
+ </div>
30
30
 
31
- <div class="baby-feeding-calculator-input-group">
32
- <div class="baby-feeding-calculator-input-label">{ui.labelWeight}</div>
33
- <div class="baby-feeding-calculator-stepper-box">
34
- <button class="baby-feeding-calculator-btn-step" id="bfc-weight-dec" aria-label="Reducir peso">−</button>
35
- <div class="baby-feeding-calculator-val-view">
36
- <span class="baby-feeding-calculator-val-big" id="bfc-weight-val">3.5</span>
37
- <span class="baby-feeding-calculator-val-sub">kg</span>
38
- </div>
39
- <button class="baby-feeding-calculator-btn-step" id="bfc-weight-inc" aria-label="Aumentar peso">+</button>
31
+ <div class="bfc-input-group">
32
+ <label class="bfc-input-label">{ui.labelWeight}</label>
33
+ <div class="bfc-stepper-box">
34
+ <button class="bfc-btn-step" data-action="dec" data-target="bfc-weight-slider" aria-label="Reducir peso">-</button>
35
+ <div class="bfc-val-view">
36
+ <span class="bfc-val-big" id="bfc-weight-val">3.5</span>
37
+ <span class="bfc-val-sub">kg</span>
40
38
  </div>
41
- <input class="baby-feeding-calculator-slider-line" type="range" id="bfc-weight-slider" min="1" max="15" step="0.1" value="3.5" />
39
+ <button class="bfc-btn-step" data-action="inc" data-target="bfc-weight-slider" aria-label="Aumentar peso">+</button>
42
40
  </div>
41
+ <div class="bfc-slider-wrap">
42
+ <input type="range" id="bfc-weight-slider" min="2.5" max="12" step="0.1" value="3.5" class="bfc-slider" />
43
+ </div>
44
+ </div>
43
45
 
44
- <div class="baby-feeding-calculator-input-group">
45
- <div class="baby-feeding-calculator-input-label">{ui.labelFeedType}</div>
46
- <div class="baby-feeding-calculator-type-rack">
47
- <button class="baby-feeding-calculator-type-tile active" data-type="breast">{ui.feedBreast}</button>
48
- <button class="baby-feeding-calculator-type-tile" data-type="mixed">{ui.feedMixed}</button>
49
- <button class="baby-feeding-calculator-type-tile" data-type="formula">{ui.feedFormula}</button>
50
- </div>
46
+ <div class="bfc-input-group">
47
+ <label class="bfc-input-label">{ui.labelFeedType}</label>
48
+ <div class="bfc-type-rack">
49
+ <button class="bfc-type-tile" data-type="breast">{ui.feedBreast}</button>
50
+ <button class="bfc-type-tile" data-type="mixed">{ui.feedMixed}</button>
51
+ <button class="bfc-type-tile bfc-type-active" data-type="formula">{ui.feedFormula}</button>
51
52
  </div>
53
+ </div>
52
54
 
53
- <div class="baby-feeding-calculator-gauge-area">
54
- <div class="baby-feeding-calculator-gauge-viz">
55
- <div class="baby-feeding-calculator-stomach-bubble" id="bfc-stomach-bubble">
56
- <span class="baby-feeding-calculator-visual-hint" id="bfc-stomach-hint">Huevo</span>
57
- </div>
58
- </div>
55
+ <div class="bfc-gauge-area">
56
+ <div class="bfc-gauge-viz">
57
+ <div class="bfc-stomach-bubble" id="bfc-stomach-bubble"></div>
58
+ <p class="bfc-visual-hint" id="bfc-stomach-text"></p>
59
59
  </div>
60
60
  </div>
61
+ </div>
61
62
 
62
- <div class="baby-feeding-calculator-card-right">
63
- <div class="baby-feeding-calculator-section-marker">{ui.labelPlan}</div>
63
+ <div class="bfc-right">
64
+ <span class="bfc-section-marker">{ui.labelPlan}</span>
64
65
 
65
- <div class="baby-feeding-calculator-res-card-box baby-feeding-calculator-res-free-demand">
66
- <div class="baby-feeding-calculator-res-label">{ui.labelFreeDemand}</div>
67
- <div class="baby-feeding-calculator-res-main-val" id="bfc-res-demand">Libre demanda</div>
66
+ <div class="bfc-res-card-box">
67
+ <div id="bfc-output-breast" class="bfc-hidden">
68
+ <span class="bfc-res-main-val">{ui.labelFreeDemand}</span>
69
+ <span class="bfc-res-label">{ui.labelFreeDemand}</span>
68
70
  </div>
71
+ <div id="bfc-output-formula">
72
+ <span class="bfc-res-main-val" id="bfc-ml-per-feed">90-120</span>
73
+ <span class="bfc-res-label">{ui.labelMlPerFeed}</span>
74
+ </div>
75
+ </div>
69
76
 
70
- <div class="baby-feeding-calculator-stats-grid">
71
- <div class="baby-feeding-calculator-stat-item">
72
- <div class="baby-feeding-calculator-stat-value" id="bfc-stat-feeds">8</div>
73
- <div class="baby-feeding-calculator-stat-label">{ui.labelFeedsCount}</div>
74
- </div>
75
- <div class="baby-feeding-calculator-stat-item">
76
- <div class="baby-feeding-calculator-stat-value" id="bfc-stat-per-feed">30–60 ml</div>
77
- <div class="baby-feeding-calculator-stat-label">{ui.labelMlPerFeed}</div>
78
- </div>
79
- <div class="baby-feeding-calculator-stat-item">
80
- <div class="baby-feeding-calculator-stat-value" id="bfc-stat-daily">360–480 ml</div>
81
- <div class="baby-feeding-calculator-stat-label">{ui.labelDailyTotal}</div>
82
- </div>
77
+ <div class="bfc-stats-grid">
78
+ <div class="bfc-stat-item">
79
+ <span class="bfc-stat-label">{ui.labelFeedsCount}</span>
80
+ <span class="bfc-stat-value" id="bfc-feeds-count">8 tomas</span>
81
+ </div>
82
+ <div class="bfc-stat-item">
83
+ <span class="bfc-stat-label">{ui.labelDailyTotal}</span>
84
+ <span class="bfc-stat-value" id="bfc-daily-total">650-780 ml</span>
83
85
  </div>
86
+ </div>
84
87
 
85
- <div class="baby-feeding-calculator-behavior-sec">
86
- <div class="baby-feeding-calculator-input-label">{ui.labelHunger}</div>
87
- <div class="baby-feeding-calculator-pills-container" id="bfc-hunger-pills">
88
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-hambre">Busca el pecho</span>
89
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-hambre">Llanto</span>
90
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-hambre">Chupa los puños</span>
91
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-hambre">Movimientos de succión</span>
92
- </div>
88
+ <div class="bfc-behavior-sec">
89
+ <span class="bfc-input-label">{ui.labelHunger}</span>
90
+ <div class="bfc-pills-container">
91
+ <span class="bfc-pill bfc-pill-hunger">Busca con la cabeza</span>
92
+ <span class="bfc-pill bfc-pill-hunger">Puños a la boca</span>
93
+ <span class="bfc-pill bfc-pill-hunger">Ruidos de succión</span>
94
+ <span class="bfc-pill bfc-pill-hunger">Chasquidos</span>
93
95
  </div>
96
+ </div>
94
97
 
95
- <div class="baby-feeding-calculator-behavior-sec">
96
- <div class="baby-feeding-calculator-input-label">{ui.labelFullness}</div>
97
- <div class="baby-feeding-calculator-pills-container" id="bfc-fullness-pills">
98
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-saciedad">Suelta el pecho</span>
99
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-saciedad">Se queda dormido</span>
100
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-saciedad">Manos relajadas</span>
101
- <span class="baby-feeding-calculator-pill baby-feeding-calculator-pill-saciedad">Cara relajada</span>
102
- </div>
98
+ <div class="bfc-behavior-sec">
99
+ <span class="bfc-input-label">{ui.labelFullness}</span>
100
+ <div class="bfc-pills-container">
101
+ <span class="bfc-pill bfc-pill-fullness">Relaja manos</span>
102
+ <span class="bfc-pill bfc-pill-fullness">Suelta tetina</span>
103
+ <span class="bfc-pill bfc-pill-fullness">Sueño profundo</span>
104
+ <span class="bfc-pill bfc-pill-fullness">Cuerpo blando</span>
103
105
  </div>
104
106
  </div>
105
107
  </div>
106
108
  </div>
107
109
  </div>
108
110
 
109
- <script>
110
- import { toAgeInDays, calculateFeeding } from './logic';
111
- import type { AgeUnit, FeedType } from './logic';
112
-
113
- const root = document.getElementById('baby-feeding-calculator-root') as HTMLElement;
114
- const ui = JSON.parse(root.dataset.ui as string) as Record<string, string>;
115
-
116
- let ageValue = 7;
117
- let ageUnit: AgeUnit = 'days';
118
- let weight = 3.5;
119
- let feedType: FeedType = 'breast';
120
-
121
- const ageSlider = root.querySelector('#bfc-age-slider') as HTMLInputElement;
122
- const ageValEl = root.querySelector('#bfc-age-val') as HTMLElement;
123
- const ageUnitEl = root.querySelector('#bfc-age-unit') as HTMLElement;
124
- const weightSlider = root.querySelector('#bfc-weight-slider') as HTMLInputElement;
125
- const weightValEl = root.querySelector('#bfc-weight-val') as HTMLElement;
126
- const stomachBubble = root.querySelector('#bfc-stomach-bubble') as HTMLElement;
127
- const stomachHint = root.querySelector('#bfc-stomach-hint') as HTMLElement;
128
- const statFeeds = root.querySelector('#bfc-stat-feeds') as HTMLElement;
129
- const statPerFeed = root.querySelector('#bfc-stat-per-feed') as HTMLElement;
130
- const statDaily = root.querySelector('#bfc-stat-daily') as HTMLElement;
131
-
132
- const AGE_LIMITS: Record<AgeUnit, { min: number; max: number }> = {
133
- days: { min: 0, max: 30 },
134
- weeks: { min: 0, max: 52 },
135
- months: { min: 0, max: 24 },
136
- };
137
-
138
- function getUnitLabel(unit: AgeUnit): string {
139
- if (unit === 'days') return ui['unitDays'] ?? '';
140
- if (unit === 'weeks') return ui['unitWeeks'] ?? '';
141
- return ui['unitMonths'] ?? '';
142
- }
143
-
144
- function updateDisplay(): void {
145
- root.dataset['feedType'] = feedType;
146
- const ageInDays = toAgeInDays(ageValue, ageUnit);
147
- const result = calculateFeeding(ageInDays, weight);
148
-
149
- stomachBubble.style.transform = `scale(${result.scale})`;
150
- stomachHint.textContent = result.hint;
151
-
152
- statFeeds.textContent = String(result.numFeeds);
153
- statPerFeed.textContent = `${result.perFeedMin}–${result.perFeedMax} ml`;
154
- statDaily.textContent = `${result.totalMin}–${result.totalMax} ml`;
155
-
156
- const limits = AGE_LIMITS[ageUnit];
157
- ageSlider.min = String(limits.min);
158
- ageSlider.max = String(limits.max);
159
- ageSlider.value = String(ageValue);
160
- ageValEl.textContent = String(ageValue);
161
- ageUnitEl.textContent = getUnitLabel(ageUnit);
162
- weightValEl.textContent = weight.toFixed(1);
163
- weightSlider.value = String(weight);
164
- }
165
-
166
- root.querySelectorAll('.baby-feeding-calculator-unit-tab').forEach((btn) => {
167
- btn.addEventListener('click', () => {
168
- ageUnit = (btn as HTMLElement).dataset.unit as AgeUnit;
169
- ageValue = AGE_LIMITS[ageUnit].min;
170
- root.querySelectorAll('.baby-feeding-calculator-unit-tab').forEach((b) => b.classList.remove('active'));
171
- btn.classList.add('active');
172
- updateDisplay();
111
+ <script is:inline>
112
+ (function () {
113
+ const root = document.getElementById('bfc-root');
114
+ if (!root) return;
115
+ const ui = JSON.parse(root.dataset.ui);
116
+
117
+ const config = { age: 7, ageUnit: 'days', weight: 3.5, feedType: 'formula' };
118
+
119
+ const ageSlider = document.getElementById('bfc-age-slider');
120
+ const ageVal = document.getElementById('bfc-age-val');
121
+ const ageUnitEl = document.getElementById('bfc-age-unit');
122
+ const weightSlider = document.getElementById('bfc-weight-slider');
123
+ const weightVal = document.getElementById('bfc-weight-val');
124
+ const stomachBubble = document.getElementById('bfc-stomach-bubble');
125
+ const stomachText = document.getElementById('bfc-stomach-text');
126
+ const outputBreast = document.getElementById('bfc-output-breast');
127
+ const outputFormula = document.getElementById('bfc-output-formula');
128
+ const mlPerFeed = document.getElementById('bfc-ml-per-feed');
129
+ const feedsCount = document.getElementById('bfc-feeds-count');
130
+ const dailyTotal = document.getElementById('bfc-daily-total');
131
+
132
+ const AGE_LIMITS = { days: { min: 1, max: 30 }, weeks: { min: 1, max: 52 }, months: { min: 1, max: 24 } };
133
+
134
+ function getUnitLabel(unit) {
135
+ if (unit === 'days') return ui.unitDays || 'días';
136
+ if (unit === 'weeks') return ui.unitWeeks || 'semanas';
137
+ return ui.unitMonths || 'meses';
138
+ }
139
+
140
+ function update() {
141
+ const { age, ageUnit, weight, feedType } = config;
142
+ let ageInDays = age;
143
+ if (ageUnit === 'weeks') ageInDays = age * 7;
144
+ if (ageUnit === 'months') ageInDays = age * 30.44;
145
+
146
+ let scale = 0.4;
147
+ let hint = '';
148
+ if (ageInDays <= 1) { scale = 0.25; hint = 'Estómago como una <strong>cereza</strong>'; }
149
+ else if (ageInDays <= 4) { scale = 0.5; hint = 'Estómago como una <strong>nuez</strong>'; }
150
+ else if (ageInDays <= 30) { scale = 0.8; hint = 'Estómago como un <strong>huevo</strong>'; }
151
+ else { scale = 1.0; hint = 'Máxima capacidad gástrica distendida'; }
152
+
153
+ if (stomachBubble) stomachBubble.style.transform = 'scale(' + scale + ')';
154
+ if (stomachText) stomachText.innerHTML = hint;
155
+
156
+ let numFeeds = 8;
157
+ if (ageInDays < 30) numFeeds = 8;
158
+ else if (ageInDays < 90) numFeeds = 7;
159
+ else if (ageInDays < 180) numFeeds = 5;
160
+ else numFeeds = 4;
161
+
162
+ let baseRatio = 150;
163
+ if (ageInDays > 180) baseRatio = 100;
164
+ if (ageInDays > 300) baseRatio = 80;
165
+
166
+ let totalMin = weight * baseRatio;
167
+ let totalMax = weight * (baseRatio + 20);
168
+ if (ageInDays >= 180) { totalMin = Math.min(totalMin, 800); totalMax = Math.min(totalMax, 950); }
169
+
170
+ if (ageInDays < 10) {
171
+ const factor = Math.max(0.15, ageInDays / 10);
172
+ totalMin *= factor; totalMax *= factor;
173
+ if (ageInDays < 2) { totalMin = weight * 15; totalMax = weight * 25; }
174
+ }
175
+
176
+ let perMin = Math.round((totalMin / numFeeds) / 5) * 5;
177
+ let perMax = Math.round((totalMax / numFeeds) / 5) * 5;
178
+ if (ageInDays <= 1) { perMin = 5; perMax = 10; totalMin = perMin * numFeeds; totalMax = perMax * numFeeds; }
179
+ perMin = Math.min(perMin, 240); perMax = Math.min(perMax, 270);
180
+
181
+ if (feedType === 'breast') {
182
+ if (outputBreast) outputBreast.classList.remove('bfc-hidden');
183
+ if (outputFormula) outputFormula.classList.add('bfc-hidden');
184
+ if (feedsCount) feedsCount.textContent = ageInDays > 180 ? '3-5 tomas' : '8-12 tomas';
185
+ if (dailyTotal) dailyTotal.textContent = 'Sin restricción';
186
+ } else {
187
+ if (outputBreast) outputBreast.classList.add('bfc-hidden');
188
+ if (outputFormula) outputFormula.classList.remove('bfc-hidden');
189
+ if (mlPerFeed) mlPerFeed.textContent = perMin + '-' + perMax + ' ml';
190
+ if (feedsCount) feedsCount.textContent = numFeeds + ' tomas';
191
+ if (dailyTotal) dailyTotal.textContent = Math.round(totalMin) + '-' + Math.round(totalMax) + ' ml';
192
+ }
193
+
194
+ if (ageVal) ageVal.textContent = String(age);
195
+ if (ageUnitEl) ageUnitEl.textContent = getUnitLabel(ageUnit);
196
+ if (weightVal) weightVal.textContent = weight.toFixed(1);
197
+ }
198
+
199
+ root.querySelectorAll('.bfc-unit-tab').forEach(function (btn) {
200
+ btn.addEventListener('click', function () {
201
+ config.ageUnit = btn.dataset.unit;
202
+ const lim = AGE_LIMITS[config.ageUnit];
203
+ config.age = lim.min;
204
+ if (ageSlider) { ageSlider.min = String(lim.min); ageSlider.max = String(lim.max); ageSlider.value = String(lim.min); }
205
+ root.querySelectorAll('.bfc-unit-tab').forEach(function (b) { b.classList.remove('bfc-unit-active'); });
206
+ btn.classList.add('bfc-unit-active');
207
+ update();
208
+ });
209
+ });
210
+
211
+ root.querySelectorAll('.bfc-type-tile').forEach(function (btn) {
212
+ btn.addEventListener('click', function () {
213
+ config.feedType = btn.dataset.type;
214
+ root.querySelectorAll('.bfc-type-tile').forEach(function (b) { b.classList.remove('bfc-type-active'); });
215
+ btn.classList.add('bfc-type-active');
216
+ update();
217
+ });
173
218
  });
174
- });
175
-
176
- root.querySelectorAll('.baby-feeding-calculator-type-tile').forEach((btn) => {
177
- btn.addEventListener('click', () => {
178
- feedType = (btn as HTMLElement).dataset.type as FeedType;
179
- root.querySelectorAll('.baby-feeding-calculator-type-tile').forEach((b) => b.classList.remove('active'));
180
- btn.classList.add('active');
181
- updateDisplay();
219
+
220
+ root.querySelectorAll('.bfc-btn-step').forEach(function (btn) {
221
+ btn.addEventListener('click', function () {
222
+ const slider = document.getElementById(btn.dataset.target);
223
+ if (!slider) return;
224
+ const val = parseFloat(slider.value);
225
+ const step = parseFloat(slider.step || '1');
226
+ const newVal = btn.dataset.action === 'inc' ? val + step : val - step;
227
+ const min = parseFloat(slider.min); const max = parseFloat(slider.max);
228
+ if (newVal < min || newVal > max) return;
229
+ slider.value = newVal.toFixed(slider.step && slider.step.includes('.') ? 1 : 0);
230
+ if (btn.dataset.target === 'bfc-age-slider') config.age = parseInt(slider.value);
231
+ else config.weight = parseFloat(slider.value);
232
+ update();
233
+ });
182
234
  });
183
- });
184
-
185
- root.querySelector('#bfc-age-dec')?.addEventListener('click', () => {
186
- const limits = AGE_LIMITS[ageUnit];
187
- if (ageValue > limits.min) { ageValue -= 1; updateDisplay(); }
188
- });
189
- root.querySelector('#bfc-age-inc')?.addEventListener('click', () => {
190
- const limits = AGE_LIMITS[ageUnit];
191
- if (ageValue < limits.max) { ageValue += 1; updateDisplay(); }
192
- });
193
- ageSlider.addEventListener('input', () => {
194
- ageValue = Number(ageSlider.value);
195
- updateDisplay();
196
- });
197
-
198
- root.querySelector('#bfc-weight-dec')?.addEventListener('click', () => {
199
- if (weight > 1) { weight = Math.round((weight - 0.1) * 10) / 10; updateDisplay(); }
200
- });
201
- root.querySelector('#bfc-weight-inc')?.addEventListener('click', () => {
202
- if (weight < 15) { weight = Math.round((weight + 0.1) * 10) / 10; updateDisplay(); }
203
- });
204
- weightSlider.addEventListener('input', () => {
205
- weight = Number(weightSlider.value);
206
- updateDisplay();
207
- });
208
-
209
- updateDisplay();
235
+
236
+ if (ageSlider) ageSlider.addEventListener('input', function () { config.age = parseInt(ageSlider.value); update(); });
237
+ if (weightSlider) weightSlider.addEventListener('input', function () { config.weight = parseFloat(weightSlider.value); update(); });
238
+
239
+ update();
240
+ })();
210
241
  </script>