@asteby/storefront-react 0.26.1 → 0.28.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.
package/README.md CHANGED
@@ -607,7 +607,7 @@ Tarifa vencida o cambiada: si guardar la entrega falla con `isQuoteChange(err)`
607
607
 
608
608
  Piezas del formulario de pago iguales en todas las tiendas (también en `@asteby/storefront-react/checkout`):
609
609
 
610
- - `ContactFields` y `AddressFields`: correo (`type="email"`, `inputMode="email"`), teléfono (`tel`), nombre (`given-name`) y apellidos (`family-name`); dirección en el orden en que se llena en México: código postal primero, estado, ciudad o municipio, colonia (`address-level3`, campo propio `neighborhood` de la API), calle y número, número interior (opcional) y referencias (opcional, `reference`). Sin país escrito en el código: el formato del código postal (`postalCode={{ pattern, maxLength, inputMode, title }}`), la lista de estados (`provinces`, de la configuración de la región) y la consulta por código postal (`lookupPostalCode`, una ruta propia sobre un catálogo) los pone la tienda. Con la consulta, estado y ciudad se llenan solos (nunca sobre lo que el comprador escribió) y las colonias salen como sugerencias (`<datalist>`). Sin ella, son campos de texto normales.
610
+ - `ContactFields` y `AddressFields`: correo (`type="email"`, `inputMode="email"`), teléfono (`tel`), nombre (`given-name`) y apellidos (`family-name`); dirección en el orden en que se llena en México: código postal primero, estado, ciudad o municipio, colonia (`address-level3`, campo propio `neighborhood` de la API), calle y número, número interior (opcional) y referencias (opcional, `reference`). Sin país escrito en el código: el formato del código postal (`postalCode={{ pattern, maxLength, inputMode, title }}`), la lista de estados (`provinces`, de la configuración de la región) y la consulta por código postal (`lookupPostalCode`, una ruta propia sobre un catálogo) los pone la tienda. Con la consulta, estado y ciudad se llenan solos (nunca sobre lo que el comprador escribió) y las colonias salen como sugerencias (`<datalist>`). Sin ella, son campos de texto normales. Con `hideResolvedFields` (por omisión activo), si la consulta resuelve estado y ciudad/municipio no se muestran como campos: una línea «Miguel Hidalgo, Ciudad de México» (`aria-live`) con «Cambiar código postal» bajo el código, y `province`, `province_code` y `city` viajan ocultos (el servidor sigue validando estado ↔ código postal). Si no resuelve, el municipio es ambiguo (`PostalCodeInfo.cities`) o el servidor reporta error en esos campos, vuelven los campos editables; `hideResolvedFields={false}` conserva el comportamiento anterior.
611
611
  - `useFieldErrors(formRef)` + `CheckoutField` + `ErrorSummary`: validación en línea con las reglas del propio HTML (`required`, `type`, `pattern`…). Al salir de un campo con un valor inválido aparece el texto debajo del campo (`aria-invalid`, `aria-describedby`); se borra al corregirlo. Al enviar (o con `reportValidity()`, que usa `PaymentMethodSection`) los globos del navegador se reemplazan por los textos en línea y un resumen enfocable con enlaces a cada campo (WCAG 3.3.1). Los campos que rechace el servidor (`serverFields`) salen igual. Sin JavaScript, el navegador valida como siempre.
612
612
  - `OrderSummary`: líneas y totales de `cart.cost` tal cual (subtotal, descuentos por código, envío «Al elegir la entrega» / «Actualizando…» / «Gratis», impuestos aparte o «Incluye $X de impuestos», total con `aria-live`). `OrderSummaryDisclosure` lo envuelve para teléfono: barra plegada arriba con el total («Ver resumen del pedido · $857.82»), `<details>` nativo, sin salto al hidratar. La tienda la muestra solo en pantallas angostas y el resumen fijo (`sticky`) en escritorio.
613
613
 
@@ -885,9 +885,14 @@ Rutas recurso de la tienda (`@asteby/storefront-react/account/server`), cada una
885
885
  // account.order.$id.invoice.$doc.$kind.ts
886
886
  export const loader = async ({ request, params }) => invoiceFileResponse({ storefront: await sfFor(request), orderId: params.id, invoiceId: params.doc, kind: params.kind })
887
887
  // account.pending.$id.ficha.ts
888
- export const loader = async ({ request, params }) => pendingVoucherResponse({ storefront: await sfFor(request), id: params.id, download: new URL(request.url).searchParams.get('descargar') === '1', shopName: 'Mi tienda' })
888
+ export const loader = async ({ request, params }) => {
889
+ const q = new URL(request.url).searchParams
890
+ return pendingVoucherResponse({ storefront: await sfFor(request), id: params.id, download: q.get('descargar') === '1', format: q.get('formato') === 'pdf' ? 'pdf' : 'html', shopName: 'Mi tienda' })
891
+ }
889
892
  ```
890
893
 
894
+ La ficha es por método: OXXO/efectivo imprime referencia y código de barras (solo si el servidor manda `payment.barcode { format: 'code128' | 'code39', value }`; sin él, solo la referencia), SPEI/transferencia imprime beneficiario, banco, CLABE y referencia con instrucciones de transferencia. Las instrucciones salen de `payment.instructions_key` / método / `payment.kind` (es/en, con fallback genérico). `format: 'pdf'` entrega `ficha-de-pago.pdf` (`application/pdf`, attachment, no-store, solo del dueño) generado sin navegador; la página HTML trae «Descargar PDF» (enlace, sin JS; `pdfHref` por omisión `?formato=pdf`) e «Imprimir». Para `PendingPaymentList`/`Card`, `voucherHref(payment, { download, format })` pide `html` para ver/imprimir y `pdf` para descargar.
895
+
891
896
  `invoiceFileResponse` sirve `attachment` con `Cache-Control: private, no-store`, `nosniff` y CSP `sandbox` (también en cada respuesta de error); el tipo sale de `kind`, no de lo que diga la API, y un archivo de más de `maxBytes` (10 MB por defecto) es un 502 genérico sin decodificarlo. `pendingVoucherResponse` solo entrega una ficha que está en la lista del comprador (si no, 404) con CSP cerrada y nonce por respuesta. Accesibilidad: WCAG 2.2 AA verificada con axe en las pruebas (contraste lo decide cada tienda con sus tokens), objetivos ≥ 44 px en el CSS opcional, `prefers-reduced-motion`. Presupuesto: todas las pantallas ≈ 13 KB gzip (prueba `size-budget`).
892
897
 
893
898
  ## Facturación y constancia fiscal (`/fiscal`)