@vtex/faststore 0.0.4 → 0.0.6
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/CHANGELOG.md +67 -0
- package/dist/actions.json +181 -0
- package/dist/catalog.json +1595 -481
- package/dist/client.d.ts +2 -1
- package/dist/client.js +2 -1
- package/dist/components.d.ts +31 -7
- package/dist/components.js +35 -13
- package/dist/content-types.json +73 -0
- package/dist/docs/access-code-sign-in.md +1 -1
- package/dist/docs/account-access-gate.md +153 -0
- package/dist/docs/account-entry-point.md +1 -2
- package/dist/docs/account-menu.md +164 -0
- package/dist/docs/address-summary.md +24 -3
- package/dist/docs/alert-dialog.md +204 -0
- package/dist/docs/billing-address.md +284 -0
- package/dist/docs/buy-button.md +1 -1
- package/dist/docs/card-entry.md +250 -0
- package/dist/docs/cardholder-document.md +142 -0
- package/dist/docs/cart.md +1 -1
- package/dist/docs/client-preferences-fieldset.md +148 -0
- package/dist/docs/client-preferences.md +2 -1
- package/dist/docs/client-profile-fieldset.md +184 -0
- package/dist/docs/client-profile.md +1 -1
- package/dist/docs/document-field.md +58 -4
- package/dist/docs/field.md +317 -0
- package/dist/docs/form.md +307 -0
- package/dist/docs/identity-edit.md +6 -6
- package/dist/docs/identity-summary.md +5 -5
- package/dist/docs/installments.md +248 -0
- package/dist/docs/my-account-profile.md +1 -0
- package/dist/docs/order-placed-payment-summary.md +138 -0
- package/dist/docs/payment-method-badges.md +232 -0
- package/dist/docs/payment-methods.md +1 -0
- package/dist/docs/payment.md +218 -0
- package/dist/docs/phone-field.md +58 -4
- package/dist/docs/place-order.md +157 -0
- package/dist/docs/save-card.md +186 -0
- package/dist/docs/saved-cards.md +218 -0
- package/dist/docs/select.md +465 -0
- package/dist/docs/session.md +1 -1
- package/dist/docs/shipping-address.md +110 -258
- package/dist/docs/sign-in-redirect.md +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/internal/client.d.ts +3 -1
- package/dist/internal/client.js +3 -1
- package/dist/matter/access-code-sign-in/access-code-sign-in.js +9 -8
- package/dist/matter/access-code-sign-in/access-code-sign-in.js.map +1 -1
- package/dist/matter/account-access-gate/account-access-gate.d.ts +86 -0
- package/dist/matter/account-access-gate/account-access-gate.js +283 -0
- package/dist/matter/account-access-gate/account-access-gate.js.map +1 -0
- package/dist/matter/account-access-gate/sign-out-intent.d.ts +17 -0
- package/dist/matter/account-access-gate/sign-out-intent.js +62 -0
- package/dist/matter/account-access-gate/sign-out-intent.js.map +1 -0
- package/dist/matter/account-entry-point/account-entry-point.js +2 -2
- package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
- package/dist/matter/account-menu/account-menu.d.ts +88 -0
- package/dist/matter/account-menu/account-menu.js +246 -0
- package/dist/matter/account-menu/account-menu.js.map +1 -0
- package/dist/matter/billing-address/billing-address.d.ts +165 -0
- package/dist/matter/billing-address/billing-address.js +408 -0
- package/dist/matter/billing-address/billing-address.js.map +1 -0
- package/dist/matter/card-entry/card-capture.d.ts +25 -0
- package/dist/matter/card-entry/card-capture.js +25 -0
- package/dist/matter/card-entry/card-capture.js.map +1 -0
- package/dist/matter/card-entry/card-entry.d.ts +120 -0
- package/dist/matter/card-entry/card-entry.js +832 -0
- package/dist/matter/card-entry/card-entry.js.map +1 -0
- package/dist/matter/cardholder-document/cardholder-document.d.ts +45 -0
- package/dist/matter/cardholder-document/cardholder-document.js +70 -0
- package/dist/matter/cardholder-document/cardholder-document.js.map +1 -0
- package/dist/matter/cart/cart.d.ts +1 -1
- package/dist/matter/cart/cart.js +2 -2
- package/dist/matter/cart/cart.js.map +1 -1
- package/dist/matter/client-preferences/client-preferences-fieldset.d.ts +77 -0
- package/dist/matter/client-preferences/client-preferences-fieldset.js +299 -0
- package/dist/matter/client-preferences/client-preferences-fieldset.js.map +1 -0
- package/dist/matter/client-preferences/client-preferences.d.ts +3 -5
- package/dist/matter/client-preferences/client-preferences.js +6 -6
- package/dist/matter/client-preferences/client-preferences.js.map +1 -1
- package/dist/matter/client-profile/client-profile.d.ts +4 -6
- package/dist/matter/client-profile/client-profile.js +9 -6
- package/dist/matter/client-profile/client-profile.js.map +1 -1
- package/dist/matter/client-profile-form/client-profile-fieldset.d.ts +119 -0
- package/dist/matter/client-profile-form/client-profile-fieldset.js +488 -0
- package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -0
- package/dist/matter/delivery-options/delivery-options.js.map +1 -1
- package/dist/matter/identity-edit/identity-edit.js +2 -2
- package/dist/matter/identity-edit/identity-edit.js.map +1 -1
- package/dist/matter/identity-summary/identity-summary.js +2 -2
- package/dist/matter/identity-summary/identity-summary.js.map +1 -1
- package/dist/matter/installments/installments-select.d.ts +42 -0
- package/dist/matter/installments/installments-select.js +167 -0
- package/dist/matter/installments/installments-select.js.map +1 -0
- package/dist/matter/installments/installments.d.ts +58 -0
- package/dist/matter/installments/installments.js +176 -0
- package/dist/matter/installments/installments.js.map +1 -0
- package/dist/matter/installments/use-installments-selection.d.ts +29 -0
- package/dist/matter/installments/use-installments-selection.js +95 -0
- package/dist/matter/installments/use-installments-selection.js.map +1 -0
- package/dist/matter/my-account-profile/my-account-profile.js +5 -5
- package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +63 -0
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +305 -0
- package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -0
- package/dist/matter/payment/payment-card-capture.d.ts +19 -0
- package/dist/matter/payment/payment-card-capture.js +129 -0
- package/dist/matter/payment/payment-card-capture.js.map +1 -0
- package/dist/matter/payment/payment-controller.d.ts +24 -0
- package/dist/matter/payment/payment-controller.js +107 -0
- package/dist/matter/payment/payment-controller.js.map +1 -0
- package/dist/matter/payment/payment-method-badges.d.ts +57 -0
- package/dist/matter/payment/payment-method-badges.js +192 -0
- package/dist/matter/payment/payment-method-badges.js.map +1 -0
- package/dist/matter/payment/payment.d.ts +89 -0
- package/dist/matter/payment/payment.js +263 -0
- package/dist/matter/payment/payment.js.map +1 -0
- package/dist/matter/payment/use-payment-method-selection.d.ts +302 -0
- package/dist/matter/payment/use-payment-method-selection.js +458 -0
- package/dist/matter/payment/use-payment-method-selection.js.map +1 -0
- package/dist/matter/payment/use-payment-submit-gate.d.ts +111 -0
- package/dist/matter/payment/use-payment-submit-gate.js +144 -0
- package/dist/matter/payment/use-payment-submit-gate.js.map +1 -0
- package/dist/matter/place-order/place-order.d.ts +74 -0
- package/dist/matter/place-order/place-order.js +379 -0
- package/dist/matter/place-order/place-order.js.map +1 -0
- package/dist/matter/product-list/product-list.d.ts +1 -0
- package/dist/matter/product-list/product-list.js.map +1 -1
- package/dist/matter/product-shelf/product-shelf.d.ts +1 -0
- package/dist/matter/product-shelf/product-shelf.js +2 -0
- package/dist/matter/product-shelf/product-shelf.js.map +1 -1
- package/dist/matter/region/region.js +1 -1
- package/dist/matter/region/region.js.map +1 -1
- package/dist/matter/save-card/save-card.d.ts +49 -0
- package/dist/matter/save-card/save-card.js +188 -0
- package/dist/matter/save-card/save-card.js.map +1 -0
- package/dist/matter/saved-cards/saved-cards.d.ts +79 -0
- package/dist/matter/saved-cards/saved-cards.js +387 -0
- package/dist/matter/saved-cards/saved-cards.js.map +1 -0
- package/dist/matter/shipping-address/country-descriptors.js +20 -10
- package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
- package/dist/matter/shipping-address/shipping-address.d.ts +113 -174
- package/dist/matter/shipping-address/shipping-address.js +481 -792
- package/dist/matter/shipping-address/shipping-address.js.map +1 -1
- package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
- package/dist/matter/variant-selector/variant-selector.js +1 -1
- package/dist/particles/address-summary/address-summary.d.ts +24 -0
- package/dist/particles/address-summary/address-summary.js +83 -2
- package/dist/particles/address-summary/address-summary.js.map +1 -1
- package/dist/particles/alert-dialog/alert-dialog.d.ts +68 -0
- package/dist/particles/alert-dialog/alert-dialog.js +187 -0
- package/dist/particles/alert-dialog/alert-dialog.js.map +1 -0
- package/dist/particles/checkbox/checkbox.d.ts +7 -3
- package/dist/particles/checkbox/checkbox.js +4 -1
- package/dist/particles/checkbox/checkbox.js.map +1 -1
- package/dist/particles/document-field/document-field.d.ts +48 -5
- package/dist/particles/document-field/document-field.js +189 -32
- package/dist/particles/document-field/document-field.js.map +1 -1
- package/dist/particles/field/bound-field-registry.js +52 -0
- package/dist/particles/field/bound-field-registry.js.map +1 -0
- package/dist/particles/field/field.d.ts +116 -0
- package/dist/particles/field/field.js +497 -6
- package/dist/particles/field/field.js.map +1 -1
- package/dist/particles/fieldset/fieldset.js +2 -2
- package/dist/particles/fieldset/fieldset.js.map +1 -1
- package/dist/particles/footer-social/footer-social.js +1 -1
- package/dist/particles/form/form.d.ts +104 -0
- package/dist/particles/form/form.js +485 -0
- package/dist/particles/form/form.js.map +1 -0
- package/dist/particles/incentives/incentives.js +1 -1
- package/dist/particles/phone-field/phone-field.d.ts +38 -10
- package/dist/particles/phone-field/phone-field.js +183 -39
- package/dist/particles/phone-field/phone-field.js.map +1 -1
- package/dist/particles/postal-code-field/postal-code-field.js +2 -2
- package/dist/particles/postal-code-field/postal-code-field.js.map +1 -1
- package/dist/particles/select/field-select.d.ts +43 -0
- package/dist/particles/select/field-select.js +150 -0
- package/dist/particles/select/field-select.js.map +1 -0
- package/dist/particles/select/select.d.ts +2 -0
- package/dist/particles/select/select.js.map +1 -1
- package/dist/particles/shared/compose-refs.js +21 -0
- package/dist/particles/shared/compose-refs.js.map +1 -0
- package/dist/schema.graphql +701 -2
- package/dist/sdk/actions/analytics-action-provider.d.ts +15 -0
- package/dist/sdk/actions/analytics-action-provider.js +19 -0
- package/dist/sdk/actions/analytics-action-provider.js.map +1 -0
- package/dist/sdk/actions/cart-action-provider.d.ts +1 -1
- package/dist/sdk/actions/cart-action-provider.js +1 -1
- package/dist/sdk/actions/cart-action-provider.js.map +1 -1
- package/dist/sdk/actions/index.d.ts +3 -1
- package/dist/sdk/actions/index.js +3 -1
- package/dist/sdk/actions/payment-action-provider.d.ts +22 -0
- package/dist/sdk/actions/payment-action-provider.js +26 -0
- package/dist/sdk/actions/payment-action-provider.js.map +1 -0
- package/dist/sdk/actions/session-action-provider.d.ts +1 -1
- package/dist/sdk/actions/session-action-provider.js +1 -1
- package/dist/sdk/actions/session-action-provider.js.map +1 -1
- package/dist/sdk/actions/shipping-action-provider.d.ts +1 -1
- package/dist/sdk/actions/shipping-action-provider.js +1 -1
- package/dist/sdk/actions/shipping-action-provider.js.map +1 -1
- package/dist/sdk/actions/types.d.ts +6 -2
- package/dist/sdk/analytics/analytics-destination.d.ts +43 -0
- package/dist/sdk/analytics/analytics-destination.js +90 -0
- package/dist/sdk/analytics/analytics-destination.js.map +1 -0
- package/dist/sdk/analytics/use-analytics-actions.d.ts +57 -0
- package/dist/sdk/analytics/use-analytics-actions.js +108 -0
- package/dist/sdk/analytics/use-analytics-actions.js.map +1 -0
- package/dist/sdk/cache/storefront-cache.js +1 -1
- package/dist/sdk/cache/storefront-cache.js.map +1 -1
- package/dist/sdk/cart/operations.d.ts +4 -4
- package/dist/sdk/cart/operations.js +1 -1
- package/dist/sdk/cart/operations.js.map +1 -1
- package/dist/sdk/cart/optimistic.js +1 -1
- package/dist/sdk/cart/optimistic.js.map +1 -1
- package/dist/sdk/cart/use-cart-actions.d.ts +1 -1
- package/dist/sdk/cart/use-cart-actions.js +4 -4
- package/dist/sdk/cart/use-cart-actions.js.map +1 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js +1 -1
- package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
- package/dist/sdk/cart/write-gate.js +1 -1
- package/dist/sdk/cart/write-gate.js.map +1 -1
- package/dist/sdk/data/entity-resolution-context.js +31 -0
- package/dist/sdk/data/entity-resolution-context.js.map +1 -0
- package/dist/sdk/data/entity-subscriber.js +18 -8
- package/dist/sdk/data/entity-subscriber.js.map +1 -1
- package/dist/sdk/data/index.js +1 -0
- package/dist/sdk/data/page-reactive-data-root.d.ts +38 -2
- package/dist/sdk/data/page-reactive-data-root.js +4 -2
- package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
- package/dist/sdk/data/reactive-data-provider.d.ts +1 -1
- package/dist/sdk/data/reactive-data-provider.js +8 -4
- package/dist/sdk/data/reactive-data-provider.js.map +1 -1
- package/dist/sdk/data/reactive-list-item-data-provider.d.ts +1 -1
- package/dist/sdk/data/reactive-list-item-data-provider.js +13 -5
- package/dist/sdk/data/reactive-list-item-data-provider.js.map +1 -1
- package/dist/sdk/data/use-reactive-data-settled.js +39 -0
- package/dist/sdk/data/use-reactive-data-settled.js.map +1 -0
- package/dist/sdk/data/use-reactive-entity.js +6 -2
- package/dist/sdk/data/use-reactive-entity.js.map +1 -1
- package/dist/sdk/generated/fragment-types.js +2 -0
- package/dist/sdk/generated/fragment-types.js.map +1 -1
- package/dist/sdk/generated/gql.js +2 -1
- package/dist/sdk/generated/gql.js.map +1 -1
- package/dist/sdk/generated/graphql.js +85 -1
- package/dist/sdk/generated/graphql.js.map +1 -1
- package/dist/sdk/i18n/messages/en-US.js +3 -0
- package/dist/sdk/i18n/messages/en-US.json +3 -0
- package/dist/sdk/i18n/messages/en-US.json.d.ts +3 -0
- package/dist/sdk/i18n/messages/es-ES.js +3 -0
- package/dist/sdk/i18n/messages/es-ES.json +3 -0
- package/dist/sdk/i18n/messages/pt-BR.js +3 -0
- package/dist/sdk/i18n/messages/pt-BR.json +3 -0
- package/dist/sdk/identity/operations.js.map +1 -1
- package/dist/sdk/identity/use-identity-actions.d.ts +1 -1
- package/dist/sdk/identity/use-identity-actions.js +3 -2
- package/dist/sdk/identity/use-identity-actions.js.map +1 -1
- package/dist/sdk/payment/gateway-origin.js +35 -0
- package/dist/sdk/payment/gateway-origin.js.map +1 -0
- package/dist/sdk/payment/gateway.d.ts +85 -0
- package/dist/sdk/payment/gateway.js +183 -0
- package/dist/sdk/payment/gateway.js.map +1 -0
- package/dist/sdk/payment/operations.d.ts +52 -0
- package/dist/sdk/payment/operations.js +223 -0
- package/dist/sdk/payment/operations.js.map +1 -0
- package/dist/sdk/payment/security-code-mask.js +71 -0
- package/dist/sdk/payment/security-code-mask.js.map +1 -0
- package/dist/sdk/payment/submission-registry.d.ts +33 -0
- package/dist/sdk/payment/submission-registry.js +58 -0
- package/dist/sdk/payment/submission-registry.js.map +1 -0
- package/dist/sdk/payment/use-payment-actions.d.ts +78 -0
- package/dist/sdk/payment/use-payment-actions.js +276 -0
- package/dist/sdk/payment/use-payment-actions.js.map +1 -0
- package/dist/sdk/payment/use-place-order.d.ts +65 -0
- package/dist/sdk/payment/use-place-order.js +640 -0
- package/dist/sdk/payment/use-place-order.js.map +1 -0
- package/dist/sdk/session/auth-operations.d.ts +1 -1
- package/dist/sdk/session/auth-operations.js.map +1 -1
- package/dist/sdk/session/use-session-actions.d.ts +1 -1
- package/dist/sdk/session/use-session-actions.js.map +1 -1
- package/dist/sdk/session/use-session-revalidation.js +65 -0
- package/dist/sdk/session/use-session-revalidation.js.map +1 -0
- package/dist/sdk/shipping/option-select-operations.d.ts +1 -1
- package/dist/sdk/shipping/option-select-operations.js.map +1 -1
- package/dist/sdk/shipping/request-timeout.js +1 -1
- package/dist/sdk/shipping/request-timeout.js.map +1 -1
- package/dist/sdk/shipping/shipping-operations.d.ts +1 -1
- package/dist/sdk/shipping/shipping-operations.js.map +1 -1
- package/dist/sdk/shipping/use-shipping-actions.d.ts +2 -2
- package/dist/sdk/shipping/use-shipping-actions.js +1 -1
- package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
- package/dist/sdk/state/cart.d.ts +3 -4
- package/dist/sdk/state/cart.js +6 -7
- package/dist/sdk/state/cart.js.map +1 -1
- package/dist/utils/loggable-error-name.js +49 -0
- package/dist/utils/loggable-error-name.js.map +1 -0
- package/dist/utils/resolve-authored-copy.js +18 -0
- package/dist/utils/resolve-authored-copy.js.map +1 -0
- package/dist/utils/safe-href.js +3 -3
- package/dist/utils/safe-href.js.map +1 -1
- package/dist/utils/substitute-template.js +33 -0
- package/dist/utils/substitute-template.js.map +1 -0
- package/package.json +2 -1
- package/src/styles/tailwind.css +34 -0
- package/dist/docs/client-profile-form.md +0 -192
- package/dist/matter/client-profile-form/client-profile-form.d.ts +0 -126
- package/dist/matter/client-profile-form/client-profile-form.js +0 -662
- package/dist/matter/client-profile-form/client-profile-form.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-profile.js","names":[],"sources":["../../../src/matter/client-profile/client-profile.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { createContext, type ReactNode, useContext, useMemo, useRef, useState } from 'react';\nimport type { PhoneCountry } from '../../particles/phone-field/phone-field.js';\nimport { PhoneField, toE164, validatePhoneNumber } from '../../particles/phone-field/phone-field.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { useSession } from '../session/session.js';\n\n/**\n * The `client-profile` section matter (per ADR-0011: a matter is decomposed by DATA OWNERSHIP, not\n * per field). The shopper-profile fields recorded on the cart's `clientProfileData` live on the User\n * Identity `ClientProfile` entity — a SIBLING of `Cart`, not nested under it. They are read through\n * `Query.clientProfile` and written through the shared `$actions.identity.clientProfileUpdate`\n * action, which performs a partial write that leaves the fields it is not given untouched.\n *\n * This matter wires only `phone`: a `ClientProfilePhoneControl` that composes the reusable,\n * business-agnostic `PhoneField` particle (reused later in MyAccount / extensions; the binding here\n * owns the data source and persistence). Room is kept for future profile Controls on the same Root.\n * Reads follow the colocated-fragment Root pattern (ADR-0006, fetchStrategy 'reactive'), mirroring\n * `EmailIdentificationControl`; writes flow through `$actions.identity` (ADR-0010). The write is\n * pessimistic (awaits the mutation) and is dispatched on blur — form-bound saving via the profile-form\n * CTA is a follow-up, not implemented here.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — colocated on the ClientProfile sibling entity (ADR-0011)\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment ClientProfilePhoneData on Query {\n clientProfile {\n __typename\n id\n phone\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Raw data shape of the section fragment\n// ---------------------------------------------------------------------------\n\n/** The `$data` slice forwarded by the reactive runtime — the `ClientProfile` sibling entity. */\nexport type ClientProfileData = {\n clientProfile?: {\n phone?: string | null;\n } | null;\n} | null;\n\n// ---------------------------------------------------------------------------\n// Context — the Root publishes the seeded profile values to its Controls\n// ---------------------------------------------------------------------------\n\nexport type ClientProfileContextValue = Readonly<{\n /** Current value of each profile field, seeded from the ClientProfile entity (null → empty). */\n phone: string;\n}>;\n\nconst CLIENT_PROFILE_UNSET = Symbol('ClientProfileContextUnset');\n\nconst ClientProfileContext = createContext<ClientProfileContextValue | typeof CLIENT_PROFILE_UNSET>(\n CLIENT_PROFILE_UNSET,\n);\n\nfunction useClientProfileContext(): ClientProfileContextValue {\n const ctx = useContext(ClientProfileContext);\n if (ctx === CLIENT_PROFILE_UNSET) {\n throw new Error('A client-profile Control must be used inside a ClientProfileRoot.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\nexport type ClientProfileRootProps = {\n /** ClientProfile entity slice forwarded by the reactive runtime (value of the section fragment). */\n $data?: ClientProfileData;\n className?: string;\n children?: ReactNode;\n};\n\nexport const ClientProfileRootDefinition = defineComponent<ClientProfileRootProps>({\n name: 'ClientProfileRoot',\n importPath: '@vtex/faststore/components',\n component: ClientProfileRoot,\n fragment,\n fetchStrategy: 'reactive',\n providesContext: 'client-profile',\n requiresContext: 'session',\n editor: { label: 'Client Profile Root', category: 'identity' },\n schema: {},\n guideline:\n 'Binding provider for the shopper-profile section; reads the profile fields (today: phone) from the ClientProfile entity (Query.clientProfile) and exposes them to its Controls. Writes flow through $actions.identity.clientProfileUpdate. Must be inside SessionRoot. Wrap a ClientProfilePhoneControl.',\n});\n\n/**\n * Renders the client-profile section Root: reads `$data` (the `ClientProfile` sibling entity), seeds\n * the profile values from the colocated fragment, and publishes a section context. It also reads\n * `useSession()` — which enforces the `SessionRoot` ancestor. Writes are owned by the Control's\n * `$actions.identity` (ADR-0010); the Root only supplies the pre-fill.\n */\nexport function ClientProfileRoot({ $data: $dataProp, className, children }: ClientProfileRootProps) {\n const $data = useDataOverride($dataProp);\n // Reads identification state and, as a side effect, throws when rendered outside <SessionRoot>.\n useSession();\n\n const phone = $data?.clientProfile?.phone ?? '';\n\n const contextValue = useMemo<ClientProfileContextValue>(() => ({ phone }), [phone]);\n\n return (\n <ClientProfileContext value={contextValue}>\n <div className={className} data-fs-client-profile-root=\"\">\n {children}\n </div>\n </ClientProfileContext>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Phone Control\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldRequirement = 'mandatory' | 'optional' | 'hidden';\n\nexport type ClientProfilePhoneControlProps = {\n /** Visible field label. */\n label?: string;\n /** Selects the phone mask and validation rule. */\n country?: PhoneCountry;\n /** Controls field visibility and required validation. */\n requirement?: PhoneFieldRequirement;\n /** Error string shown when the input format is invalid. */\n errorInvalid?: string;\n /** Error string shown when the mandatory field is left empty. */\n errorRequired?: string;\n className?: string;\n /** Injected by the compiler from `actions: { identity: ['clientProfileUpdate'] }`; the write surface. */\n $actions?: ComponentActions;\n};\n\nexport const ClientProfilePhoneControlDefinition = defineComponent<ClientProfilePhoneControlProps>({\n name: 'ClientProfilePhoneControl',\n importPath: '@vtex/faststore/components',\n component: ClientProfilePhoneControl,\n requiresContext: 'client-profile',\n actions: { identity: ['clientProfileUpdate'] },\n editor: { label: 'Client Profile Phone Control', category: 'identity' },\n schema: {\n label: { type: 'string', default: 'Phone', label: 'Label' },\n country: { type: 'string', default: 'US', label: 'Country (US or BR)' },\n requirement: { type: 'string', default: 'mandatory', label: 'Requirement' },\n errorInvalid: { type: 'string', default: 'Invalid phone number', label: 'Invalid error message' },\n errorRequired: { type: 'string', default: 'Phone number is required', label: 'Required error message' },\n },\n guideline:\n 'The bound phone field; must be a descendant of ClientProfileRoot. Reads the saved phone from the ClientProfile entity and persists it on blur via $actions.identity.clientProfileUpdate({ phone }). Composes the reusable PhoneField particle.',\n});\n\n/**\n * Renders the bound phone field by composing the reusable `PhoneField` particle. Reads the saved\n * phone from the section context, and on a **changed** value persists only `phone` — normalized to\n * E.164 — through `$actions.identity.clientProfileUpdate({ phone })` on blur (pessimistic,\n * mirroring `EmailIdentificationControl`). While the write is in flight the field is disabled and\n * `data-fs-client-profile-phone-pending` is present so a checkout-CTA guard can block. When the\n * session reports `canEditData: false` the field renders disabled with\n * `data-fs-client-profile-phone-readonly`. Server `userErrors` are surfaced inline.\n */\nexport function ClientProfilePhoneControl({\n label = 'Phone',\n country = 'US',\n requirement = 'mandatory',\n errorInvalid = 'Invalid phone number',\n errorRequired = 'Phone number is required',\n className,\n $actions: $actionsProp,\n}: Readonly<ClientProfilePhoneControlProps>) {\n const $actions = useActionsOverride($actionsProp);\n const { phone: savedPhone } = useClientProfileContext();\n // VTEX refuses profile edits for an identified-but-unauthenticated claimed profile; render the\n // field read-only instead of accepting a write that is doomed server-side (mirrors\n // EmailIdentificationControl).\n const { canEditData } = useSession();\n const readOnly = !canEditData;\n const [draft, setDraft] = useState(savedPhone);\n const [pending, setPending] = useState(false);\n const [serverError, setServerError] = useState<string | null>(null);\n\n // Re-seed the local draft when the saved value changes (e.g. cache update after a write, or a\n // logged-in shopper's profile resolving). Like the email control's pre-fill sync, this overwrites\n // any in-progress draft — the profile is the source of truth when it changes.\n const prevSavedRef = useRef(savedPhone);\n if (prevSavedRef.current !== savedPhone) {\n // react-doctor-disable-next-line no-ref-current-in-render -- paired with the setDraft call right below, both replay together\n prevSavedRef.current = savedPhone;\n setDraft(savedPhone);\n }\n\n function handleValueChange(next: string) {\n setDraft(next);\n if (serverError) setServerError(null);\n }\n\n async function handleBlur() {\n const clientProfileUpdate = $actions?.identity?.clientProfileUpdate;\n if (!clientProfileUpdate) return;\n // Untouched → nothing to persist.\n if (draft === savedPhone) return;\n // Client-side invalid → skip the write and let the PhoneField's inline error stand; don't\n // rely on server userErrors for a value the mask/validator already rejects. Mirrors the\n // validity the PhoneField particle computes on blur (mandatory-empty or bad format).\n const isEmpty = !draft.trim();\n if (requirement === 'mandatory' && isEmpty) return;\n if (!isEmpty && !validatePhoneNumber(draft, country)) return;\n const phone = isEmpty ? '' : toE164(draft, country);\n // Unchanged after normalization (e.g. the saved \"+12015551234\" re-typed as \"2015551234\") →\n // nothing to persist either.\n if (phone === savedPhone) return;\n\n setPending(true);\n setServerError(null);\n try {\n const errors = (await clientProfileUpdate({ phone })) ?? [];\n if (errors.length > 0) setServerError(errors[0]?.message ?? null);\n } finally {\n setPending(false);\n }\n }\n\n return (\n <div\n className={className}\n data-fs-client-profile-phone-control=\"\"\n {...(pending ? { 'data-fs-client-profile-phone-pending': '' } : {})}\n {...(readOnly ? { 'data-fs-client-profile-phone-readonly': '' } : {})}\n >\n <PhoneField\n label={label}\n country={country}\n requirement={requirement}\n errorInvalid={errorInvalid}\n errorRequired={errorRequired}\n value={draft}\n onValueChange={handleValueChange}\n onBlur={handleBlur}\n isDisabled={pending || readOnly}\n invalid={serverError != null || undefined}\n error={serverError ?? undefined}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Namespace export\n// ---------------------------------------------------------------------------\n\nexport const ClientProfile = {\n Root: ClientProfileRoot,\n PhoneControl: ClientProfilePhoneControl,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client-profile.js","names":[],"sources":["../../../src/matter/client-profile/client-profile.tsx"],"sourcesContent":["'use client';\n\nimport { defineComponent } from '@vtex/fs-core';\nimport { createContext, type ReactNode, useContext, useMemo, useRef, useState } from 'react';\nimport type { PhoneCountry } from '../../particles/phone-field/phone-field.js';\nimport { PhoneField, toE164, validatePhoneNumber } from '../../particles/phone-field/phone-field.js';\nimport { useActionsOverride } from '../../sdk/actions/actions-override-context.js';\nimport type { ComponentActions } from '../../sdk/actions/types.js';\nimport { useDataOverride } from '../../sdk/data/data-override-context.js';\nimport { useSession } from '../session/session.js';\n\n/**\n * The `client-profile` section matter (per ADR-0011: a matter is decomposed by DATA OWNERSHIP, not\n * per field). The shopper-profile fields recorded on the cart's `clientProfileData` live on the User\n * Identity `ClientProfile` entity — a SIBLING of `Cart`, not nested under it. They are read through\n * `Query.clientProfile` and written through the shared `$actions.identity.clientProfileUpdate`\n * action, which performs a partial write that leaves the fields it is not given untouched.\n *\n * This matter wires only `phone`: a `ClientProfilePhoneControl` that composes the reusable,\n * business-agnostic `PhoneField` particle (reused later in MyAccount / extensions; the binding here\n * owns the data source and persistence). Room is kept for future profile Controls on the same Root.\n * Reads follow the colocated-fragment Root pattern (ADR-0006, fetchStrategy 'reactive'), mirroring\n * `EmailIdentificationControl`; writes flow through `$actions.identity` (ADR-0010). The write is\n * pessimistic (awaits the mutation) and is dispatched on blur — form-bound saving via the profile-form\n * CTA is a follow-up, not implemented here.\n */\n\n// ---------------------------------------------------------------------------\n// GraphQL Fragment — colocated on the ClientProfile sibling entity (ADR-0011)\n// ---------------------------------------------------------------------------\n\nconst fragment = /* GraphQL */ `\n fragment ClientProfilePhoneData on Query {\n clientProfile {\n __typename\n id\n phone\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Raw data shape of the section fragment\n// ---------------------------------------------------------------------------\n\n/** The `$data` slice forwarded by the reactive runtime — the `ClientProfile` sibling entity, unwrapped. */\nexport type ClientProfileData = {\n phone?: string | null;\n} | null;\n\n// ---------------------------------------------------------------------------\n// Context — the Root publishes the seeded profile values to its Controls\n// ---------------------------------------------------------------------------\n\nexport type ClientProfileContextValue = Readonly<{\n /** Current value of each profile field, seeded from the ClientProfile entity (null → empty). */\n phone: string;\n}>;\n\nconst CLIENT_PROFILE_UNSET = Symbol('ClientProfileContextUnset');\n\nconst ClientProfileContext = createContext<ClientProfileContextValue | typeof CLIENT_PROFILE_UNSET>(\n CLIENT_PROFILE_UNSET,\n);\n\nfunction useClientProfileContext(): ClientProfileContextValue {\n const ctx = useContext(ClientProfileContext);\n if (ctx === CLIENT_PROFILE_UNSET) {\n throw new Error('A client-profile Control must be used inside a ClientProfileRoot.');\n }\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\nexport type ClientProfileRootProps = {\n /** ClientProfile entity slice forwarded by the reactive runtime (value of the section fragment). */\n $data?: ClientProfileData;\n className?: string;\n children?: ReactNode;\n};\n\nexport const ClientProfileRootDefinition = defineComponent<ClientProfileRootProps>({\n name: 'ClientProfileRoot',\n importPath: '@vtex/faststore/components',\n component: ClientProfileRoot,\n fragment,\n fetchStrategy: 'reactive',\n providesContext: 'client-profile',\n requiresContext: 'session',\n editor: { label: 'Client Profile Root', category: 'identity' },\n schema: {},\n guideline:\n 'Binding provider for the shopper-profile section; reads the profile fields (today: phone) from the ClientProfile entity (Query.clientProfile) and exposes them to its Controls. Writes flow through $actions.identity.clientProfileUpdate. Must be inside SessionRoot. Wrap a ClientProfilePhoneControl.',\n});\n\n/**\n * Renders the client-profile section Root: reads `$data` (the `ClientProfile` sibling entity), seeds\n * the profile values from the colocated fragment, and publishes a section context. It also reads\n * `useSession()` — which enforces the `SessionRoot` ancestor. Writes are owned by the Control's\n * `$actions.identity` (ADR-0010); the Root only supplies the pre-fill.\n */\nexport function ClientProfileRoot({ $data: $dataProp, className, children }: ClientProfileRootProps) {\n const $data = useDataOverride($dataProp);\n // Reads identification state and, as a side effect, throws when rendered outside <SessionRoot>.\n useSession();\n\n const phone = $data?.phone ?? '';\n\n const contextValue = useMemo<ClientProfileContextValue>(() => ({ phone }), [phone]);\n\n return (\n <ClientProfileContext value={contextValue}>\n <div className={className} data-fs-client-profile-root=\"\">\n {children}\n </div>\n </ClientProfileContext>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Phone Control\n// ---------------------------------------------------------------------------\n\ntype PhoneFieldRequirement = 'mandatory' | 'optional';\n\nexport type ClientProfilePhoneControlProps = {\n /** Visible field label. */\n label?: string;\n /** Selects the phone mask and validation rule. */\n country?: PhoneCountry;\n /** Controls required validation. */\n requirement?: PhoneFieldRequirement;\n /** Error string shown when the input format is invalid. */\n errorInvalid?: string;\n /** Error string shown when the mandatory field is left empty. */\n errorRequired?: string;\n className?: string;\n /** Injected by the compiler from `actions: { identity: ['clientProfileUpdate'] }`; the write surface. */\n $actions?: ComponentActions;\n};\n\nexport const ClientProfilePhoneControlDefinition = defineComponent<ClientProfilePhoneControlProps>({\n name: 'ClientProfilePhoneControl',\n importPath: '@vtex/faststore/components',\n component: ClientProfilePhoneControl,\n requiresContext: 'client-profile',\n actions: { identity: ['clientProfileUpdate'] },\n editor: { label: 'Client Profile Phone Control', category: 'identity' },\n schema: {\n label: { type: 'string', default: 'Phone', label: 'Label' },\n country: { type: 'string', default: 'US', label: 'Country (US or BR)' },\n requirement: { type: ['mandatory', 'optional'] as const, default: 'mandatory', label: 'Requirement' },\n errorInvalid: { type: 'string', default: 'Invalid phone number', label: 'Invalid error message' },\n errorRequired: { type: 'string', default: 'Phone number is required', label: 'Required error message' },\n },\n guideline:\n 'The bound phone field; must be a descendant of ClientProfileRoot. Reads the saved phone from the ClientProfile entity and persists it on blur via $actions.identity.clientProfileUpdate({ phone }). Composes the reusable PhoneField particle.',\n});\n\n/**\n * Renders the bound phone field by composing the reusable `PhoneField` particle. Reads the saved\n * phone from the section context, and on a **changed** value persists only `phone` — normalized to\n * E.164 — through `$actions.identity.clientProfileUpdate({ phone })` on blur (pessimistic,\n * mirroring `EmailIdentificationControl`). While the write is in flight the field is disabled and\n * `data-fs-client-profile-phone-pending` is present so a checkout-CTA guard can block. When the\n * session reports `canEditData: false` the field renders disabled with\n * `data-fs-client-profile-phone-readonly`. Server `userErrors` are surfaced inline.\n */\nexport function ClientProfilePhoneControl({\n label = 'Phone',\n country = 'US',\n requirement = 'mandatory',\n errorInvalid = 'Invalid phone number',\n errorRequired = 'Phone number is required',\n className,\n $actions: $actionsProp,\n}: Readonly<ClientProfilePhoneControlProps>) {\n const $actions = useActionsOverride($actionsProp);\n const { phone: savedPhone } = useClientProfileContext();\n // VTEX refuses profile edits for an identified-but-unauthenticated claimed profile; render the\n // field read-only instead of accepting a write that is doomed server-side (mirrors\n // EmailIdentificationControl).\n const { canEditData } = useSession();\n const readOnly = !canEditData;\n const [draft, setDraft] = useState(savedPhone);\n // A plain ref, not state: set only from handlers (never during render), and read only inside the\n // render-body re-seed comparison below — nothing here needs its own re-render, since every call\n // site that sets it already triggers one via a sibling state setter in the same tick.\n const dirtyRef = useRef(false);\n const [pending, setPending] = useState(false);\n const [serverError, setServerError] = useState<string | null>(null);\n\n // Re-seed the local draft when the saved value changes (e.g. cache update after a write, or a\n // logged-in shopper's profile resolving) — but never while an edit is in progress. A render-phase\n // compare-and-set, not a ref: the comparison baseline lives in state, and the compare-and-set runs\n // during render, so a render React abandons without committing — a suspended transition, a\n // Suspense retry — never leaves a stale baseline behind the way a ref write would, and a reactive\n // fetch landing mid-keystroke still can't silently replace what the shopper just typed.\n const [prevSaved, setPrevSaved] = useState(savedPhone);\n if (prevSaved !== savedPhone) {\n setPrevSaved(savedPhone);\n if (!dirtyRef.current) setDraft(savedPhone);\n }\n\n function handleValueChange(next: string) {\n setDraft(next);\n dirtyRef.current = true;\n if (serverError) setServerError(null);\n }\n\n async function handleBlur() {\n const clientProfileUpdate = $actions?.identity?.clientProfileUpdate;\n if (!clientProfileUpdate) return;\n // Untouched → nothing to persist.\n if (draft === savedPhone) return;\n // Client-side invalid → skip the write and let the PhoneField's inline error stand; don't\n // rely on server userErrors for a value the mask/validator already rejects. Mirrors the\n // validity the PhoneField particle computes on blur (mandatory-empty or bad format).\n const isEmpty = !draft.trim();\n if (requirement === 'mandatory' && isEmpty) return;\n if (!isEmpty && !validatePhoneNumber(draft, country)) return;\n const phone = isEmpty ? '' : toE164(draft, country);\n // Unchanged after normalization (e.g. the saved \"+12015551234\" re-typed as \"2015551234\") →\n // nothing to persist either.\n if (phone === savedPhone) return;\n\n setPending(true);\n setServerError(null);\n try {\n const errors = (await clientProfileUpdate({ phone })) ?? [];\n if (errors.length > 0) {\n setServerError(errors[0]?.message ?? null);\n } else {\n // The edit is now committed — clear the guard so a later external change (another tab,\n // a cache refresh) can re-seed the draft again.\n dirtyRef.current = false;\n }\n } finally {\n setPending(false);\n }\n }\n\n return (\n <div\n className={className}\n data-fs-client-profile-phone-control=\"\"\n {...(pending ? { 'data-fs-client-profile-phone-pending': '' } : {})}\n {...(readOnly ? { 'data-fs-client-profile-phone-readonly': '' } : {})}\n >\n <PhoneField\n label={label}\n country={country}\n requirement={requirement}\n errorInvalid={errorInvalid}\n errorRequired={errorRequired}\n value={draft}\n onValueChange={handleValueChange}\n onBlur={handleBlur}\n isDisabled={pending || readOnly}\n invalid={serverError != null || undefined}\n error={serverError ?? undefined}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Namespace export\n// ---------------------------------------------------------------------------\n\nexport const ClientProfile = {\n Root: ClientProfileRoot,\n PhoneControl: ClientProfilePhoneControl,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { ComponentDefinition } from "../../core/dist/define-component.js";
|
|
2
|
+
import "../../core/dist/index.js";
|
|
3
|
+
import { ComponentActions } from "../../sdk/actions/types.js";
|
|
4
|
+
import { PhoneCountry } from "../../particles/phone-field/phone-field.js";
|
|
5
|
+
import { ComponentPropsWithRef, ReactNode } from "react";
|
|
6
|
+
//#region src/matter/client-profile-form/client-profile-fieldset.d.ts
|
|
7
|
+
/** The `$data` slice forwarded by the reactive runtime — the ClientProfile sibling entity, unwrapped. */
|
|
8
|
+
export type ClientProfileFieldsetData = {
|
|
9
|
+
firstName?: string | null;
|
|
10
|
+
lastName?: string | null;
|
|
11
|
+
phone?: string | null;
|
|
12
|
+
document?: string | null;
|
|
13
|
+
} | null;
|
|
14
|
+
export type ClientProfileFieldsetProps = {
|
|
15
|
+
/** Phone mask/validation country, provided to the phone control via context. */
|
|
16
|
+
country?: PhoneCountry;
|
|
17
|
+
/** Locale document type; the document control renders only when supported. */
|
|
18
|
+
documentType?: string;
|
|
19
|
+
/** Placeholder rows the loading skeleton draws. Set it to the number of controls composed here. */
|
|
20
|
+
skeletonCount?: number;
|
|
21
|
+
/** Announced politely while the profile resolves. Blank means no announcement. */
|
|
22
|
+
loadingLabel?: string;
|
|
23
|
+
/** Announced politely once the controls mount. Blank means no announcement. */
|
|
24
|
+
loadedLabel?: string;
|
|
25
|
+
/** Accessible name of the `<fieldset>` group. Blank means no name is exposed. */
|
|
26
|
+
groupLabel?: string;
|
|
27
|
+
className?: string;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
/** `ClientProfileFieldsetData` slice forwarded by the reactive runtime. */
|
|
30
|
+
$data?: ClientProfileFieldsetData;
|
|
31
|
+
/** Compiler-injected; carries `identity.clientProfileUpdate`. */
|
|
32
|
+
$actions?: ComponentActions;
|
|
33
|
+
};
|
|
34
|
+
type ProfileTextControlProps = {
|
|
35
|
+
label?: string;
|
|
36
|
+
placeholder?: string;
|
|
37
|
+
className?: string;
|
|
38
|
+
children?: ReactNode;
|
|
39
|
+
};
|
|
40
|
+
export type ClientProfileFirstNameControlProps = ProfileTextControlProps;
|
|
41
|
+
export type ClientProfileLastNameControlProps = ProfileTextControlProps;
|
|
42
|
+
export type ClientProfileFieldsetPhoneControlProps = {
|
|
43
|
+
label?: string;
|
|
44
|
+
placeholder?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Raises the field to required. The composite owns it; the contract carries no rule (Decision 6),
|
|
47
|
+
* so here the raise is the whole of the resolution. Unset is no opinion, which leaves the phone
|
|
48
|
+
* optional.
|
|
49
|
+
*/
|
|
50
|
+
requirement?: 'mandatory' | 'optional';
|
|
51
|
+
errorInvalid?: string;
|
|
52
|
+
errorRequired?: string;
|
|
53
|
+
className?: string;
|
|
54
|
+
/** Given, replaces PhoneField's default Field.Label + PhoneFieldInput + Field.Error anatomy. */
|
|
55
|
+
children?: ReactNode;
|
|
56
|
+
};
|
|
57
|
+
export type ClientProfileDocumentControlProps = {
|
|
58
|
+
label?: string;
|
|
59
|
+
placeholder?: string;
|
|
60
|
+
errorMessage?: string;
|
|
61
|
+
className?: string;
|
|
62
|
+
/** Given, replaces DocumentField's default Field.Label + DocumentFieldInput + Field.Error anatomy. */
|
|
63
|
+
children?: ReactNode;
|
|
64
|
+
};
|
|
65
|
+
export declare const ClientProfileFieldsetDefinition: ComponentDefinition<ClientProfileFieldsetProps>;
|
|
66
|
+
export declare const ClientProfileFirstNameControlDefinition: ComponentDefinition<ProfileTextControlProps>;
|
|
67
|
+
export declare const ClientProfileLastNameControlDefinition: ComponentDefinition<ProfileTextControlProps>;
|
|
68
|
+
export declare const ClientProfileFieldsetPhoneControlDefinition: ComponentDefinition<ClientProfileFieldsetPhoneControlProps>;
|
|
69
|
+
export declare const ClientProfileDocumentControlDefinition: ComponentDefinition<ClientProfileDocumentControlProps>;
|
|
70
|
+
/**
|
|
71
|
+
* Registers a batched write of the `ClientProfile` entity with the enclosing `FormRoot`
|
|
72
|
+
* (`registerFieldset`, namespace `clientProfile`) on mount, unconditionally — so this fieldset keeps its
|
|
73
|
+
* original dispatch slot even while its own query is still resolving. Its children — the seed values and
|
|
74
|
+
* the field-name registry its controls need — render only once the entity has resolved; until then the
|
|
75
|
+
* `Fieldset.Root` carries `-pending` and renders `ClientProfileFieldsetSkeleton` (Decision 5).
|
|
76
|
+
* `dispatch` and `toPayload` are `useCallback([])`-stable and read `$actions`/`country`/`documentType`
|
|
77
|
+
* through a ref, so the registration effect runs exactly once per mount regardless of how often the
|
|
78
|
+
* parent re-renders.
|
|
79
|
+
*
|
|
80
|
+
* "Resolved" is two conditions, because `$data` alone cannot answer it. Under the reactive runtime the
|
|
81
|
+
* slice is defined from the first render — `useReactiveEntity` hands down `fallbackData` while the cache
|
|
82
|
+
* read is incomplete — so an empty server answer looks exactly like a resolved one, and the controls
|
|
83
|
+
* would mount and seed `''` before the shopper's real profile arrives. `useSeedAdoption` re-seeds a
|
|
84
|
+
* clean field with `defaultValue` on every render, but once the field turns dirty no later seed
|
|
85
|
+
* ever reaches it again: a shopper who starts typing before the real profile arrives locks that
|
|
86
|
+
* empty seed in for good, and even a shopper who does not type sees the field flash from `''` to
|
|
87
|
+
* the real data. `useReactiveDataSettled` supplies the missing half: the page query's own
|
|
88
|
+
* in-flight state, latched so it only ever goes pending → settled. The `$data === undefined` half still
|
|
89
|
+
* carries trees with no reactive root above them, where the slice arrives as a plain prop.
|
|
90
|
+
*
|
|
91
|
+
* Both ends of that wait are spoken: the fieldset carries `aria-busy` while it lasts and holds a polite
|
|
92
|
+
* live region that announces `loadingLabel` and then `loadedLabel`. Style the region `sr-only` — it is
|
|
93
|
+
* text meant for a screen reader, not for the page.
|
|
94
|
+
*/
|
|
95
|
+
export declare function ClientProfileFieldset({ country, documentType, skeletonCount, loadingLabel, loadedLabel, groupLabel, className, children, $data: $dataProp, $actions: $actionsProp }: ClientProfileFieldsetProps): import("react/jsx-runtime").JSX.Element;
|
|
96
|
+
export declare namespace ClientProfileFieldset {
|
|
97
|
+
var Skeleton: typeof ClientProfileFieldsetSkeleton;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The loading state of the fieldset, rendered in place of the controls until the entity resolves and
|
|
101
|
+
* declared as the definition's `skeleton`. Purely visual: the wait is spoken by the fieldset's own live
|
|
102
|
+
* region, so this is hidden from assistive technology rather than announced twice.
|
|
103
|
+
*/
|
|
104
|
+
export declare function ClientProfileFieldsetSkeleton({ count, className, ...props }: ComponentPropsWithRef<'div'> & {
|
|
105
|
+
count?: number;
|
|
106
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
107
|
+
export declare function ClientProfileFirstNameControl({ label, placeholder, className, children }: ClientProfileFirstNameControlProps): import("react/jsx-runtime").JSX.Element;
|
|
108
|
+
export declare function ClientProfileLastNameControl({ label, placeholder, className, children }: ClientProfileLastNameControlProps): import("react/jsx-runtime").JSX.Element;
|
|
109
|
+
/**
|
|
110
|
+
* Composes `PhoneField` inside a `FieldBinding`, wrapped in a `data-fs-client-profile-fieldset-field="phone"`
|
|
111
|
+
* node — the same styling hook attribute the text controls carry on their own `Field.Root`.
|
|
112
|
+
* `useFieldsetField` runs unconditionally, before `requirement` is even read — there is no suppressed
|
|
113
|
+
* state for this control to second-guess; `requirement` only ever raises the field to required,
|
|
114
|
+
* and left unset it raises nothing.
|
|
115
|
+
*/
|
|
116
|
+
export declare function ClientProfileFieldsetPhoneControl({ label, placeholder, requirement, errorInvalid, errorRequired, className, children }: ClientProfileFieldsetPhoneControlProps): import("react/jsx-runtime").JSX.Element;
|
|
117
|
+
export declare function ClientProfileDocumentControl({ label, placeholder, errorMessage, className, children }: ClientProfileDocumentControlProps): import("react/jsx-runtime").JSX.Element | null;
|
|
118
|
+
//#endregion
|
|
119
|
+
//# sourceMappingURL=client-profile-fieldset.d.ts.map
|