bootstrap: swap BS4 (alexwine) CSS for bootstrap@5 npm

Completes the Bootstrap 4->5 migration now that every jQuery/BS4 widget is React
(navbar, carousel, dropdowns) — plus the feedback toggle here (Feedback.js:
global `$('#feedback-form').toggle()` -> React state).

- Load Bootstrap 5 CSS from the `bootstrap` npm package in client/index.js
  (imported first so app + component styles and react-bootstrap override it).
- Remove the `alexwine:bootstrap-4` meteor package (BS4 CSS + jQuery + BS4 JS).
  jQuery for jquery-validation still comes from the npm `jquery` dep.
- Utility renames to BS5: ml-auto->ms-auto, float-right->float-end,
  btn-block->w-100, data-toggle->data-bs-toggle (FromNow tooltip).
- forms.scss `.form-label` is no longer a shim (BS5 ships it); comment updated.

Full-app build boots clean; server suite 36 passing. Needs a visual staging pass
across all pages (BS4->5 shifts grid gutters/typography); forms should improve
since react-bootstrap v2 already emitted BS5 markup.
This commit is contained in:
vjrj 2026-07-22 05:55:34 +02:00
parent 9ff9abacc3
commit bddfb392c1
12 changed files with 63 additions and 38 deletions

View file

@ -30,7 +30,6 @@ audit-argument-checks@1.0.8
ddp-rate-limiter@1.2.2
dynamic-import@0.7.4
static-html@1.4.0
alexwine:bootstrap-4
gadicc:blaze-react-component # Add braze to react
255kb:meteor-status # Connect status
@ -45,6 +44,10 @@ ostrio:meteor-root
aldeed:schema-deny
dburles:collection-helpers
reywood:publish-composite
# Bootstrap CSS/JS now comes from the `bootstrap` npm package (BS5), imported in
# imports/startup/client/index.js. The old alexwine:bootstrap-4 package (BS4 CSS +
# jQuery + BS4 JS) was removed after the navbar/carousel/dropdown/feedback widgets
# were migrated off jQuery.
facts-base@1.0.2
nspangler:autoreconnect
quave:synced-cron

View file

@ -8,7 +8,6 @@ accounts-password@3.0.3
aldeed:collection2@4.2.0
aldeed:schema-deny@4.0.2
aldeed:simple-schema@1.13.1
alexwine:bootstrap-4@4.1.0
allow-deny@2.0.0
audit-argument-checks@1.0.8
autoupdate@2.0.0

View file

@ -65,25 +65,27 @@ React 19: el `<Blaze serverFacts>` de Status.js (`findDOMNode`), solo en `/statu
- ✅ **`meteor-accounts-t9n` actualizado** a `^2.6.0` (es/en OK). El paquete sigue
sin build gallego (`gl`), así que se mantiene el fallback gl→es documentado en
`i18n.js`. Traducción gallega de la app (`gl/common.json`): 0 claves faltantes.
- **Salto Bootstrap 4→5 (CSS/JS) pendiente:** react-bootstrap ya está en v2 y
corre sobre el CSS Bootstrap 4 actual (`alexwine:bootstrap-4`) con un único
shim `.form-label` en `forms.scss`. **Ya no quedan dependencias del JS jQuery de
BS4** — los dos blockers se migraron a React:
- ✅ **Collapse del navbar** (`Navigation.js` + `NavItem.js`): `data-toggle=
"collapse"` jQuery → estado React (`useState` que alterna `.show`).
*Verificar en staging el menú móvil (<lg): abrir/cerrar y cierre al pulsar un
enlace.*
- ✅ **Carrusel del home** (`Index.js`): `bootstrap-carousel-swipe` (jQuery) +
`$(...).carousel()``<Carousel>` de react-bootstrap con swipe nativo; se
conserva el mecanismo `.lazy` de fondos (blur→full) vía `onSlide`. Dep
`bootstrap-carousel-swipe` eliminada. Ports de CSS en `Index-custom.scss`:
indicadores `li``button` (markup BS5) y shim `.visually-hidden`.
*Verificar en staging el home: transiciones, swipe, indicadores, prev/next y
carga progresiva de las imágenes de fondo.*
- Falta (el salto de CSS en sí, ya sin bloqueos de JS): importar `bootstrap@5`
SCSS+JS, `ml-auto``ms-auto` (y demás utilidades direccionales), revisar
`new-age.scss`/`custom.scss`/`bootstrap-overrides.scss` y retirar
`alexwine:bootstrap-4`.
- ✅ **Salto Bootstrap 4→5 (CSS/JS) hecho** — react-bootstrap v2 ahora corre sobre
su CSS nativo (BS5). **Compila y arranca; falta SOLO verificación visual en
staging** (BS4→5 cambia sutilezas de grid/gutters/tipografía en todas las páginas).
- Widgets jQuery/BS4 migrados a React (los blockers): navbar collapse
(`Navigation.js`/`NavItem.js`), carrusel del home (`Index.js``<Carousel>`,
conserva `.lazy` vía `onSlide`), dropdowns de idioma/tipo (`Profile.js`/
`Fires.js``<Dropdown>`), y toggle del feedback (`Feedback.js` → estado React).
Deps `bootstrap-carousel-swipe` y `alexwine:bootstrap-4` eliminadas; jQuery
global ya no se usa (solo `jquery`+`jquery-validation` vía npm en `validate.js`).
- CSS: `bootstrap@5` npm importado en `imports/startup/client/index.js` (antes
que `app.scss`, para que los overrides ganen). Renombres de utilidades:
`ml-auto``ms-auto`, `float-right``float-end`, `btn-block``w-100`,
`data-toggle``data-bs-toggle`, `sr-only``.visually-hidden` (shim).
- **QA visual pendiente en staging (todas las páginas):** formularios (react-
bootstrap ya emite markup BS5 → deberían mejorar), navbar, botones, modales,
cards, grid/gutters, y los widgets migrados (menú móvil, carrusel, dropdowns,
feedback). Alertas de `themeteorchef:bert` (comprobar que siguen bien sin el
jQuery de alexwine).
- Menor: `popper.js@1` en `package.json` es legacy sin uso (react-bootstrap trae
`@popperjs/core@2`) → se puede quitar. El bloque `.form-label` de `forms.scss`
ya es redundante (BS5 lo trae) salvo por el `display:block` explícito.
- **Limpieza menor:** migración 217 `// TODO remove falsepositives lowercase
collection`; `prerender.js` gating comentado; sección per-fire del sitemap
eliminada (era código muerto tras `firesMapEnabled=false`).

View file

@ -1,4 +1,8 @@
/* global */
// Bootstrap 5 CSS (npm) replaces the old `alexwine:bootstrap-4` meteor package.
// Import it first so the app + component stylesheets below (and react-bootstrap,
// which targets BS5) override it.
import 'bootstrap/dist/css/bootstrap.css';
import React from 'react';
import { createRoot } from 'react-dom/client';
import { HelmetProvider } from 'react-helmet-async';

View file

@ -18,6 +18,7 @@ import './Feedback.scss';
class Feedback extends Component {
constructor(props) {
super(props);
this.state = { open: false };
this.handleSubmit = this.handleSubmit.bind(this);
this.onTabClick = this.onTabClick.bind(this);
}
@ -50,7 +51,9 @@ class Feedback extends Component {
}
onTabClick() {
$('#feedback-form').toggle('slide');
// Was `$('#feedback-form').toggle('slide')` — global jQuery from the BS4
// meteor package. React state instead, so nothing depends on that global.
this.setState(s => ({ open: !s.open }));
}
handleSubmit() {
@ -76,7 +79,7 @@ class Feedback extends Component {
<div>
{ !this.props.isHome &&
<div id="feedback">
<div id="feedback-form" ref={formdiv => (this.formdiv = formdiv)} style={{ display: 'none' }} className="card">
<div id="feedback-form" ref={formdiv => (this.formdiv = formdiv)} style={{ display: this.state.open ? 'block' : 'none' }} className="card">
<form
ref={form => (this.form = form)}
className="form card-body"
@ -109,7 +112,7 @@ class Feedback extends Component {
/>
<Form.Control.Feedback />
</Form.Group>
<Button type="submit" variant="success" className="float-right" id={testId('sendFeedbackBtn')} >
<Button type="submit" variant="success" className="float-end" id={testId('sendFeedbackBtn')} >
{t('Enviar')}
</Button>
</form>

View file

@ -33,7 +33,7 @@ class FromNow extends Component {
render() {
return (
<span data-toggle="tooltip" className="from-now" title={this.thatIs()}>{this.state.when}</span>
<span data-bs-toggle="tooltip" className="from-now" title={this.thatIs()}>{this.state.when}</span>
);
}
}

View file

@ -37,7 +37,7 @@ const Navigation = ({ name = '', ...props }) => {
</button>
<div className={`collapse navbar-collapse${open ? ' show' : ''}`} id="navbarNavDropdown">
{/* onClick closes the mobile menu when a main nav link is tapped */}
<ul className="navbar-nav ml-auto " onClick={close}>
<ul className="navbar-nav ms-auto " onClick={close}>
{/* <LinkContainer className="nav-item" anchorClassName="nav-link" to="/sandbox">
<NavItem eventKey={1.1} href="/sandbox">Sandbox</NavItem>
</LinkContainer> */}

View file

@ -45,7 +45,7 @@ const defaultCallback = (error) => {
const OAuthLoginButton = ({ service, callback = defaultCallback }) => (
<button
className={`btn btn-block btn-raised btn-danger OAuthLoginButton OAuthLoginButton-${service}`}
className={`btn w-100 btn-raised btn-danger OAuthLoginButton OAuthLoginButton-${service}`}
type="button"
onClick={() => handleLogin(service, callback)}
>

View file

@ -132,7 +132,7 @@ class Signup extends React.Component {
{ Meteor.settings.public.telegramAuth &&
<Col xs={12}>
<button
className="btn btn-block btn-raised btn-primary OAuthLoginButtonDis OAuthLoginButton-telegram"
className="btn w-100 btn-raised btn-primary OAuthLoginButtonDis OAuthLoginButton-telegram"
type="button"
onClick={this.onTelegramAuth}
>

View file

@ -1,11 +1,10 @@
@use './mixins' as *;
@use './colors' as *;
// react-bootstrap v2 emits Bootstrap 5 form markup (`.form-label`) while we
// still ship the Bootstrap 4 stylesheet (alexwine:bootstrap-4), which has no
// `.form-label`. Shim it until the Bootstrap 4 -> 5 CSS jump lands (tracked as
// debt in UPGRADE.md). v2's Form.Group is a plain div, so restore the old
// per-field bottom margin the removed `.form-group` used to give.
// Bootstrap 5 now provides `.form-label` natively, so this is no longer a shim
// we keep it only for the explicit `display: block` (v2's Form.Group is a plain
// div and some fields render the label inline otherwise). The bottom margin
// matches BS5's own `.form-label`.
.form-label {
display: block;
margin-bottom: 0.5rem;

24
package-lock.json generated
View file

@ -13,7 +13,7 @@
"@turf/buffer": "^5.1.5",
"babel-runtime": "^6.26.0",
"bcrypt": "^5.1.1",
"bootstrap-carousel-swipe": "0.0.6",
"bootstrap": "^5.3.8",
"commonmark": "^0.28.1",
"core-js": "^2.5.1",
"crypto-random-hex": "^1.0.0",
@ -2699,10 +2699,24 @@
"node": ">=4.0.0"
}
},
"node_modules/bootstrap-carousel-swipe": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/bootstrap-carousel-swipe/-/bootstrap-carousel-swipe-0.0.6.tgz",
"integrity": "sha1-FTn+656kduHRDRwwnWWb0WJZ/wo="
"node_modules/bootstrap": {
"version": "5.3.8",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz",
"integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"license": "MIT",
"peerDependencies": {
"@popperjs/core": "^2.11.8"
}
},
"node_modules/brace-expansion": {
"version": "1.1.7",

View file

@ -14,6 +14,7 @@
"@turf/buffer": "^5.1.5",
"babel-runtime": "^6.26.0",
"bcrypt": "^5.1.1",
"bootstrap": "^5.3.8",
"commonmark": "^0.28.1",
"core-js": "^2.5.1",
"crypto-random-hex": "^1.0.0",