@12-apps/ui 6.96.2 → 6.97.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/dist/_internal/components/form/CepField/CepField.js +1 -1
- package/dist/_internal/components/form/index.js +1 -1
- package/dist/_internal/components/form/total-form/Fields/CepField.js +2 -2
- package/dist/_internal/components/form/total-form/Fields/index.js +3 -3
- package/dist/_internal/components/index.js +1 -1
- package/dist/{chunk-UTWEHMAP.js → chunk-LYVVXC3J.js} +11 -3
- package/dist/chunk-LYVVXC3J.js.map +1 -0
- package/dist/{chunk-BRFL7OWI.js → chunk-N2J24TJ3.js} +2 -2
- package/dist/{chunk-KXVWH3JM.js → chunk-QZRWOF4R.js} +2 -2
- package/dist/form/CepField.js +1 -1
- package/dist/form/total-form.js +3 -3
- package/dist/types/components/form/CepField/CepField.d.ts +1 -1
- package/dist/types/components/form/CepField/CepField.d.ts.map +1 -1
- package/dist/types/components/form/CepField/CepField.types.d.ts +9 -0
- package/dist/types/components/form/CepField/CepField.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/form/CepField/CepField.md +4 -0
- package/src/components/form/CepField/CepField.tsx +14 -1
- package/src/components/form/CepField/CepField.types.ts +9 -0
- package/dist/chunk-UTWEHMAP.js.map +0 -1
- /package/dist/{chunk-BRFL7OWI.js.map → chunk-N2J24TJ3.js.map} +0 -0
- /package/dist/{chunk-KXVWH3JM.js.map → chunk-QZRWOF4R.js.map} +0 -0
|
@@ -116,7 +116,7 @@ import "../../../chunk-JXS56EW5.js";
|
|
|
116
116
|
import "../../../chunk-6XLMTOJ3.js";
|
|
117
117
|
import {
|
|
118
118
|
CepField
|
|
119
|
-
} from "../../../chunk-
|
|
119
|
+
} from "../../../chunk-LYVVXC3J.js";
|
|
120
120
|
import "../../../chunk-WGKBZ7DN.js";
|
|
121
121
|
import "../../../chunk-IDMG332I.js";
|
|
122
122
|
import {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
CepField
|
|
4
|
-
} from "../../../../../chunk-
|
|
4
|
+
} from "../../../../../chunk-QZRWOF4R.js";
|
|
5
5
|
import "../../../../../chunk-4XK6JQ4D.js";
|
|
6
6
|
import "../../../../../chunk-6XLMTOJ3.js";
|
|
7
|
-
import "../../../../../chunk-
|
|
7
|
+
import "../../../../../chunk-LYVVXC3J.js";
|
|
8
8
|
import "../../../../../chunk-WGKBZ7DN.js";
|
|
9
9
|
import "../../../../../chunk-ASBFGGJB.js";
|
|
10
10
|
import "../../../../../chunk-PD7MKJCM.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "../../../../../chunk-
|
|
1
|
+
import "../../../../../chunk-N2J24TJ3.js";
|
|
2
2
|
import {
|
|
3
3
|
ToggleField
|
|
4
4
|
} from "../../../../../chunk-RLTYBV4N.js";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "../../../../../chunk-6YSGP2WS.js";
|
|
11
11
|
import {
|
|
12
12
|
CepField
|
|
13
|
-
} from "../../../../../chunk-
|
|
13
|
+
} from "../../../../../chunk-QZRWOF4R.js";
|
|
14
14
|
import {
|
|
15
15
|
CategoryField
|
|
16
16
|
} from "../../../../../chunk-6AKDAQSS.js";
|
|
@@ -24,7 +24,7 @@ import "../../../../../chunk-OQW4OERS.js";
|
|
|
24
24
|
import "../../../../../chunk-6VTOGR36.js";
|
|
25
25
|
import "../../../../../chunk-IYC7NPX7.js";
|
|
26
26
|
import "../../../../../chunk-6XLMTOJ3.js";
|
|
27
|
-
import "../../../../../chunk-
|
|
27
|
+
import "../../../../../chunk-LYVVXC3J.js";
|
|
28
28
|
import "../../../../../chunk-WGKBZ7DN.js";
|
|
29
29
|
import "../../../../../chunk-QYKDY4EI.js";
|
|
30
30
|
import "../../../../../chunk-ZJY7OK6H.js";
|
|
@@ -346,7 +346,7 @@ import "../../chunk-JXS56EW5.js";
|
|
|
346
346
|
import "../../chunk-6XLMTOJ3.js";
|
|
347
347
|
import {
|
|
348
348
|
CepField
|
|
349
|
-
} from "../../chunk-
|
|
349
|
+
} from "../../chunk-LYVVXC3J.js";
|
|
350
350
|
import "../../chunk-WGKBZ7DN.js";
|
|
351
351
|
import "../../chunk-IDMG332I.js";
|
|
352
352
|
import {
|
|
@@ -63,6 +63,13 @@ function CepStatus({
|
|
|
63
63
|
return /* @__PURE__ */ jsx("span", { id: `${testId}-status`, role: "status", "aria-live": "polite", children: visible && /* @__PURE__ */ jsx(FormMessage, { error: status === "notfound", dataTestId: `${testId}-${status}`, children: copy[status] }) });
|
|
64
64
|
}
|
|
65
65
|
var CEP_INPUT_PROPS = { inputMode: "numeric" };
|
|
66
|
+
var CEP_INPUT_PROPS_NO_MANAGERS = {
|
|
67
|
+
...CEP_INPUT_PROPS,
|
|
68
|
+
"data-lpignore": "true",
|
|
69
|
+
"data-1p-ignore": "true",
|
|
70
|
+
"data-bwignore": "true"
|
|
71
|
+
};
|
|
72
|
+
var inputPropsOf = (passwordManagers) => passwordManagers === "ignore" ? CEP_INPUT_PROPS_NO_MANAGERS : CEP_INPUT_PROPS;
|
|
66
73
|
var autoCompleteOf = (autoComplete) => autoComplete ?? "postal-code";
|
|
67
74
|
function AboveLabel({
|
|
68
75
|
name,
|
|
@@ -92,7 +99,8 @@ function CepField({
|
|
|
92
99
|
size,
|
|
93
100
|
// undefined reaches `Input`, whose own default is `md`
|
|
94
101
|
labelPlacement = "above",
|
|
95
|
-
autoComplete
|
|
102
|
+
autoComplete,
|
|
103
|
+
passwordManagers
|
|
96
104
|
}) {
|
|
97
105
|
const testId = dataTestId ?? `cep-field-${name}`;
|
|
98
106
|
const status = useCepLookup({
|
|
@@ -116,7 +124,7 @@ function CepField({
|
|
|
116
124
|
id: name,
|
|
117
125
|
name,
|
|
118
126
|
type: "text",
|
|
119
|
-
inputProps:
|
|
127
|
+
inputProps: inputPropsOf(passwordManagers),
|
|
120
128
|
autoComplete: autoCompleteOf(autoComplete),
|
|
121
129
|
size,
|
|
122
130
|
label: insideLabel(label, labelPlacement),
|
|
@@ -141,4 +149,4 @@ export {
|
|
|
141
149
|
CepField,
|
|
142
150
|
CepField_default
|
|
143
151
|
};
|
|
144
|
-
//# sourceMappingURL=chunk-
|
|
152
|
+
//# sourceMappingURL=chunk-LYVVXC3J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/form/CepField/CepField.tsx"],"sourcesContent":["'use client';\n\nimport type { CepFieldCopy } from \"../../../copy\";\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { cepDigits, formatCep, isValidCep } from '@12-apps/forms-core';\n\nimport { FormControl, FormLabel, FormMessage } from '../Form';\n// The outlined entry: CepField renders no variant, and the generic one would\n// ship MUI's FilledInput and Input to every screen with a CEP field (FUT-1054).\nimport { Input } from '../Input/outlined';\nimport type { CepAddress, CepFieldProps, CepLookupStatus } from './CepField.types';\n\n/** Everything {@link useCepLookup} needs, so the hook signature stays flat. */\ninterface LookupOptions {\n digits: string;\n complete: boolean;\n disabled: boolean;\n debounceMs: number;\n onLookup?: (cep: string) => Promise<CepAddress | null>;\n onResolved?: (address: CepAddress) => void;\n onNotFound?: () => void;\n}\n\n/**\n * Debounced, race-safe CEP resolution.\n *\n * Two guards earn their keep here: a monotonic sequence id, bumped\n * synchronously on every new query, so a slow response for a since-edited CEP\n * can never land; and a \"last queried\" marker, so re-rendering (or the caller\n * re-masking the same value) never re-hits the provider.\n */\nfunction useCepLookup({\n digits,\n complete,\n disabled,\n debounceMs,\n onLookup,\n onResolved,\n onNotFound,\n}: LookupOptions): CepLookupStatus {\n const [status, setStatus] = useState<CepLookupStatus>('idle');\n const lastQueriedRef = useRef('');\n const seqRef = useRef(0);\n // Latest callbacks, read at call time — keeps them out of the effect deps so\n // an inline arrow from the caller doesn't re-trigger the lookup every render.\n const lookupRef = useRef(onLookup);\n const resolvedRef = useRef(onResolved);\n const notFoundRef = useRef(onNotFound);\n lookupRef.current = onLookup;\n resolvedRef.current = onResolved;\n notFoundRef.current = onNotFound;\n\n useEffect(() => {\n if (!complete || disabled || !lookupRef.current) {\n // Editing away from a complete CEP drops any stale status and forgets the\n // last query, so re-typing the same CEP resolves again.\n seqRef.current += 1;\n setStatus('idle');\n lastQueriedRef.current = '';\n return;\n }\n if (lastQueriedRef.current === digits) return;\n\n const mySeq = (seqRef.current += 1);\n const handle = setTimeout(() => {\n lastQueriedRef.current = digits;\n setStatus('loading');\n void (async () => {\n // A failing lookup is treated exactly like \"not found\" — the user types\n // the address instead. Never surfaced as a crash. Going through\n // `Promise.resolve().then` rather than calling directly covers the two\n // failure modes an `await … .catch()` misses: a lookup that throws\n // SYNCHRONOUSLY, and one that returns something other than a promise.\n const address = await Promise.resolve()\n .then(() => lookupRef.current?.(digits))\n .catch(() => null);\n if (seqRef.current !== mySeq) return;\n setStatus(address ? 'found' : 'notfound');\n // A miss is reported too, so a caller that filled from a PREVIOUS CEP\n // can undo it rather than leaving that address under this CEP.\n if (address) resolvedRef.current?.(address);\n else notFoundRef.current?.();\n })();\n }, debounceMs);\n\n return () => clearTimeout(handle);\n }, [digits, complete, disabled, debounceMs]);\n\n return status;\n}\n\n/**\n * The lookup outcome as a live region, so screen readers announce it without\n * stealing focus. Silent while idle, and while the caller is showing its own\n * validation error (which would otherwise stack two messages).\n */\nfunction CepStatus({\n status,\n testId,\n suppressed,\n copy,\n}: {\n status: CepLookupStatus;\n testId: string;\n suppressed: boolean;\n copy: CepFieldCopy;\n}): React.ReactElement {\n const visible = !suppressed && status !== 'idle';\n return (\n <span id={`${testId}-status`} role=\"status\" aria-live=\"polite\">\n {visible && (\n <FormMessage error={status === 'notfound'} dataTestId={`${testId}-${status}`}>\n {copy[status as Exclude<CepLookupStatus, 'idle'>]}\n </FormMessage>\n )}\n </span>\n );\n}\n\n/** What only the `<input>` can act on. Hoisted: one object for every render. */\nconst CEP_INPUT_PROPS = { inputMode: 'numeric' } as const;\n\n/** The same, plus each password manager's own \"not mine\" flag (`passwordManagers=\"ignore\"`, FUT-4444). */\nconst CEP_INPUT_PROPS_NO_MANAGERS = {\n ...CEP_INPUT_PROPS,\n 'data-lpignore': 'true',\n 'data-1p-ignore': 'true',\n 'data-bwignore': 'true',\n} as const;\n\n/** The `<input>`'s own props: the keypad always, the managers' flags only when asked (`offer` is the default). */\nconst inputPropsOf = (passwordManagers: 'offer' | 'ignore' | undefined) =>\n passwordManagers === 'ignore' ? CEP_INPUT_PROPS_NO_MANAGERS : CEP_INPUT_PROPS;\n\n/** `postal-code` unless the caller said otherwise (`off` for somebody else's address). */\nconst autoCompleteOf = (autoComplete: string | undefined): string => autoComplete ?? 'postal-code';\n\n/** The stacked label over the box (`labelPlacement=\"above\"`), or nothing when there is no label. */\nfunction AboveLabel({\n name,\n label,\n error,\n}: {\n name: string;\n label?: string;\n error?: string;\n}): React.ReactElement | null {\n if (!label) return null;\n return (\n <FormLabel htmlFor={name} error={Boolean(error)}>\n {label}\n </FormLabel>\n );\n}\n\n/** The label handed to the `Input`, which draws it in the box: only for `inside`. */\nfunction insideLabel(label: string | undefined, placement: 'above' | 'inside'): string | undefined {\n return placement === 'inside' ? label : undefined;\n}\n\n/**\n * A CEP input that fills the rest of the address in.\n *\n * The pattern every Brazilian form has used for twenty years: type eight\n * digits, and logradouro/bairro/cidade/UF arrive on their own. This is the\n * reusable half — masking, validation, debouncing, race-safety and status —\n * with the actual lookup injected via `onLookup`, so the same component serves\n * a supplier form, a store-location form or a delivery checkout without\n * knowing anything about providers or auth.\n *\n * Resolution is best-effort by design. A provider outage, an unknown CEP or a\n * timeout leaves the field exactly as usable as a plain text input — the user\n * types the address themselves. Autofill never blocks.\n *\n * @example\n * ```tsx\n * <CepField\n * value={cep}\n * onChange={setCep}\n * onLookup={(c) => fetch(`/api/…/lookup/cep/${c}`).then((r) => r.json()).then((b) => b.data)}\n * onResolved={(a) => { setStreet(a.street ?? ''); setCity(a.city ?? ''); }}\n * />\n * ```\n */\nexport function CepField({\n value,\n onChange,\n onLookup,\n onResolved,\n onNotFound,\n label = 'CEP',\n placeholder = '00000-000',\n error,\n disabled = false,\n debounceMs = 500,\n name = 'postalCode',\n dataTestId,\n copy,\n size, // undefined reaches `Input`, whose own default is `md`\n labelPlacement = 'above',\n autoComplete,\n passwordManagers,\n}: CepFieldProps): React.ReactElement {\n const testId = dataTestId ?? `cep-field-${name}`;\n\n const status = useCepLookup({\n digits: cepDigits(value),\n complete: isValidCep(value),\n disabled,\n debounceMs,\n onLookup,\n onResolved,\n onNotFound,\n });\n\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => onChange(formatCep(event.target.value)),\n [onChange],\n );\n\n return (\n <FormControl fullWidth>\n {labelPlacement === 'above' && <AboveLabel name={name} label={label} error={error} />}\n <Input\n id={name}\n name={name}\n type=\"text\"\n // On the `<input>`, through `inputProps`: a top-level `inputMode` is a\n // prop `Input` does not recognise, so it landed on the wrapper `div`\n // and the phone kept opening the letter keyboard for eight digits\n // (FUT-1440's CepField row).\n inputProps={inputPropsOf(passwordManagers)}\n autoComplete={autoCompleteOf(autoComplete)}\n size={size}\n // `inside`: the label is the Input's own, drawn in the box and floating\n // up on focus or a value — what every other `Input` in the form does.\n // `above` keeps the stacked `FormLabel`, for callers that never opted in.\n label={insideLabel(label, labelPlacement)}\n placeholder={placeholder}\n value={value}\n error={Boolean(error)}\n disabled={disabled}\n loading={status === 'loading'}\n onChange={handleChange}\n data-testid={testId}\n aria-describedby={`${testId}-status`}\n aria-busy={status === 'loading'}\n />\n {error && (\n <FormMessage error dataTestId={`${testId}-message`}>\n {error}\n </FormMessage>\n )}\n <CepStatus status={status} testId={testId} suppressed={Boolean(error)} copy={copy} />\n </FormControl>\n );\n}\n\nexport default CepField;\n"],"mappings":"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","names":[]}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "./chunk-6YSGP2WS.js";
|
|
10
10
|
import {
|
|
11
11
|
CepField
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-QZRWOF4R.js";
|
|
13
13
|
import {
|
|
14
14
|
CategoryField
|
|
15
15
|
} from "./chunk-6AKDAQSS.js";
|
|
@@ -30,4 +30,4 @@ __export(Fields_exports, {
|
|
|
30
30
|
export {
|
|
31
31
|
Fields_exports
|
|
32
32
|
};
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
33
|
+
//# sourceMappingURL=chunk-N2J24TJ3.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-4XK6JQ4D.js";
|
|
4
4
|
import {
|
|
5
5
|
CepField
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-LYVVXC3J.js";
|
|
7
7
|
|
|
8
8
|
// src/components/form/total-form/Fields/CepField.tsx
|
|
9
9
|
import { useCallback, useMemo, useRef } from "react";
|
|
@@ -86,4 +86,4 @@ function CepField2({
|
|
|
86
86
|
export {
|
|
87
87
|
CepField2 as CepField
|
|
88
88
|
};
|
|
89
|
-
//# sourceMappingURL=chunk-
|
|
89
|
+
//# sourceMappingURL=chunk-QZRWOF4R.js.map
|
package/dist/form/CepField.js
CHANGED
package/dist/form/total-form.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "../chunk-CPAJYJUD.js";
|
|
10
10
|
import {
|
|
11
11
|
Fields_exports
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-N2J24TJ3.js";
|
|
13
13
|
import "../chunk-RLTYBV4N.js";
|
|
14
14
|
import {
|
|
15
15
|
TextField
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
SelectField
|
|
19
19
|
} from "../chunk-6YSGP2WS.js";
|
|
20
|
-
import "../chunk-
|
|
20
|
+
import "../chunk-QZRWOF4R.js";
|
|
21
21
|
import {
|
|
22
22
|
CategoryField
|
|
23
23
|
} from "../chunk-6AKDAQSS.js";
|
|
@@ -34,7 +34,7 @@ import "../chunk-OQW4OERS.js";
|
|
|
34
34
|
import "../chunk-6VTOGR36.js";
|
|
35
35
|
import "../chunk-IYC7NPX7.js";
|
|
36
36
|
import "../chunk-6XLMTOJ3.js";
|
|
37
|
-
import "../chunk-
|
|
37
|
+
import "../chunk-LYVVXC3J.js";
|
|
38
38
|
import "../chunk-WGKBZ7DN.js";
|
|
39
39
|
import "../chunk-JD5BVIM7.js";
|
|
40
40
|
import "../chunk-T77OVQEO.js";
|
|
@@ -25,6 +25,6 @@ import type { CepFieldProps } from './CepField.types';
|
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
export declare function CepField({ value, onChange, onLookup, onResolved, onNotFound, label, placeholder, error, disabled, debounceMs, name, dataTestId, copy, size, // undefined reaches `Input`, whose own default is `md`
|
|
28
|
-
labelPlacement, autoComplete, }: CepFieldProps): React.ReactElement;
|
|
28
|
+
labelPlacement, autoComplete, passwordManagers, }: CepFieldProps): React.ReactElement;
|
|
29
29
|
export default CepField;
|
|
30
30
|
//# sourceMappingURL=CepField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CepField.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/CepField/CepField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAQxE,OAAO,KAAK,EAAc,aAAa,EAAmB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"CepField.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/CepField/CepField.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAQxE,OAAO,KAAK,EAAc,aAAa,EAAmB,MAAM,kBAAkB,CAAC;AAsJnF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,UAAU,EACV,KAAa,EACb,WAAyB,EACzB,KAAK,EACL,QAAgB,EAChB,UAAgB,EAChB,IAAmB,EACnB,UAAU,EACV,IAAI,EACJ,IAAI,EAAE,uDAAuD;AAC7D,cAAwB,EACxB,YAAY,EACZ,gBAAgB,GACjB,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CAsDpC;AAED,eAAe,QAAQ,CAAC"}
|
|
@@ -94,5 +94,14 @@ export interface CepFieldProps {
|
|
|
94
94
|
* (FUT-4140).
|
|
95
95
|
*/
|
|
96
96
|
autoComplete?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Whether password managers may treat the box as theirs. `offer` (default)
|
|
99
|
+
* leaves them alone, as the field always has. `ignore` marks the `<input>`
|
|
100
|
+
* with `data-lpignore`, `data-1p-ignore` and `data-bwignore`, so LastPass,
|
|
101
|
+
* 1Password and Bitwarden keep their icon and fill out of a lone CEP box that
|
|
102
|
+
* their heuristics read as a login field (FUT-4444). The browser's own
|
|
103
|
+
* `autocomplete` is untouched: a saved CEP is still offered.
|
|
104
|
+
*/
|
|
105
|
+
passwordManagers?: 'offer' | 'ignore';
|
|
97
106
|
}
|
|
98
107
|
//# sourceMappingURL=CepField.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CepField.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/CepField/CepField.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD;;GAEG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc;IACd,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU;IACV,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,oEAAoE;AACpE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAExE,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,IAAI,EAAE,YAAY,CAAC;IACnB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACvD;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACpC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"CepField.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/CepField/CepField.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD;;GAEG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,2CAA2C;IAC3C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,cAAc;IACd,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU;IACV,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,oEAAoE;AACpE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAExE,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,IAAI,EAAE,YAAY,CAAC;IACnB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACvD;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACpC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CACvC"}
|
package/package.json
CHANGED
|
@@ -52,6 +52,10 @@ serves a supplier form, a store-location form or a delivery checkout.
|
|
|
52
52
|
form for somebody else's address (a supplier), or the browser offers the signed-in
|
|
53
53
|
person's own CEP and the lookup then fills their street (FUT-4140). Same prop on
|
|
54
54
|
`Fields.CepField`
|
|
55
|
+
- `passwordManagers`: `offer` (default) or `ignore`. `ignore` puts `data-lpignore`,
|
|
56
|
+
`data-1p-ignore` and `data-bwignore` on the `<input>`, so LastPass, 1Password and
|
|
57
|
+
Bitwarden stop drawing their icon in a lone CEP box they read as a login field
|
|
58
|
+
(FUT-4444). The browser's own `autocomplete` still offers a saved CEP
|
|
55
59
|
|
|
56
60
|
### State Props
|
|
57
61
|
|
|
@@ -121,6 +121,18 @@ function CepStatus({
|
|
|
121
121
|
/** What only the `<input>` can act on. Hoisted: one object for every render. */
|
|
122
122
|
const CEP_INPUT_PROPS = { inputMode: 'numeric' } as const;
|
|
123
123
|
|
|
124
|
+
/** The same, plus each password manager's own "not mine" flag (`passwordManagers="ignore"`, FUT-4444). */
|
|
125
|
+
const CEP_INPUT_PROPS_NO_MANAGERS = {
|
|
126
|
+
...CEP_INPUT_PROPS,
|
|
127
|
+
'data-lpignore': 'true',
|
|
128
|
+
'data-1p-ignore': 'true',
|
|
129
|
+
'data-bwignore': 'true',
|
|
130
|
+
} as const;
|
|
131
|
+
|
|
132
|
+
/** The `<input>`'s own props: the keypad always, the managers' flags only when asked (`offer` is the default). */
|
|
133
|
+
const inputPropsOf = (passwordManagers: 'offer' | 'ignore' | undefined) =>
|
|
134
|
+
passwordManagers === 'ignore' ? CEP_INPUT_PROPS_NO_MANAGERS : CEP_INPUT_PROPS;
|
|
135
|
+
|
|
124
136
|
/** `postal-code` unless the caller said otherwise (`off` for somebody else's address). */
|
|
125
137
|
const autoCompleteOf = (autoComplete: string | undefined): string => autoComplete ?? 'postal-code';
|
|
126
138
|
|
|
@@ -188,6 +200,7 @@ export function CepField({
|
|
|
188
200
|
size, // undefined reaches `Input`, whose own default is `md`
|
|
189
201
|
labelPlacement = 'above',
|
|
190
202
|
autoComplete,
|
|
203
|
+
passwordManagers,
|
|
191
204
|
}: CepFieldProps): React.ReactElement {
|
|
192
205
|
const testId = dataTestId ?? `cep-field-${name}`;
|
|
193
206
|
|
|
@@ -217,7 +230,7 @@ export function CepField({
|
|
|
217
230
|
// prop `Input` does not recognise, so it landed on the wrapper `div`
|
|
218
231
|
// and the phone kept opening the letter keyboard for eight digits
|
|
219
232
|
// (FUT-1440's CepField row).
|
|
220
|
-
inputProps={
|
|
233
|
+
inputProps={inputPropsOf(passwordManagers)}
|
|
221
234
|
autoComplete={autoCompleteOf(autoComplete)}
|
|
222
235
|
size={size}
|
|
223
236
|
// `inside`: the label is the Input's own, drawn in the box and floating
|
|
@@ -97,4 +97,13 @@ export interface CepFieldProps {
|
|
|
97
97
|
* (FUT-4140).
|
|
98
98
|
*/
|
|
99
99
|
autoComplete?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Whether password managers may treat the box as theirs. `offer` (default)
|
|
102
|
+
* leaves them alone, as the field always has. `ignore` marks the `<input>`
|
|
103
|
+
* with `data-lpignore`, `data-1p-ignore` and `data-bwignore`, so LastPass,
|
|
104
|
+
* 1Password and Bitwarden keep their icon and fill out of a lone CEP box that
|
|
105
|
+
* their heuristics read as a login field (FUT-4444). The browser's own
|
|
106
|
+
* `autocomplete` is untouched: a saved CEP is still offered.
|
|
107
|
+
*/
|
|
108
|
+
passwordManagers?: 'offer' | 'ignore';
|
|
100
109
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/form/CepField/CepField.tsx"],"sourcesContent":["'use client';\n\nimport type { CepFieldCopy } from \"../../../copy\";\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { cepDigits, formatCep, isValidCep } from '@12-apps/forms-core';\n\nimport { FormControl, FormLabel, FormMessage } from '../Form';\n// The outlined entry: CepField renders no variant, and the generic one would\n// ship MUI's FilledInput and Input to every screen with a CEP field (FUT-1054).\nimport { Input } from '../Input/outlined';\nimport type { CepAddress, CepFieldProps, CepLookupStatus } from './CepField.types';\n\n/** Everything {@link useCepLookup} needs, so the hook signature stays flat. */\ninterface LookupOptions {\n digits: string;\n complete: boolean;\n disabled: boolean;\n debounceMs: number;\n onLookup?: (cep: string) => Promise<CepAddress | null>;\n onResolved?: (address: CepAddress) => void;\n onNotFound?: () => void;\n}\n\n/**\n * Debounced, race-safe CEP resolution.\n *\n * Two guards earn their keep here: a monotonic sequence id, bumped\n * synchronously on every new query, so a slow response for a since-edited CEP\n * can never land; and a \"last queried\" marker, so re-rendering (or the caller\n * re-masking the same value) never re-hits the provider.\n */\nfunction useCepLookup({\n digits,\n complete,\n disabled,\n debounceMs,\n onLookup,\n onResolved,\n onNotFound,\n}: LookupOptions): CepLookupStatus {\n const [status, setStatus] = useState<CepLookupStatus>('idle');\n const lastQueriedRef = useRef('');\n const seqRef = useRef(0);\n // Latest callbacks, read at call time — keeps them out of the effect deps so\n // an inline arrow from the caller doesn't re-trigger the lookup every render.\n const lookupRef = useRef(onLookup);\n const resolvedRef = useRef(onResolved);\n const notFoundRef = useRef(onNotFound);\n lookupRef.current = onLookup;\n resolvedRef.current = onResolved;\n notFoundRef.current = onNotFound;\n\n useEffect(() => {\n if (!complete || disabled || !lookupRef.current) {\n // Editing away from a complete CEP drops any stale status and forgets the\n // last query, so re-typing the same CEP resolves again.\n seqRef.current += 1;\n setStatus('idle');\n lastQueriedRef.current = '';\n return;\n }\n if (lastQueriedRef.current === digits) return;\n\n const mySeq = (seqRef.current += 1);\n const handle = setTimeout(() => {\n lastQueriedRef.current = digits;\n setStatus('loading');\n void (async () => {\n // A failing lookup is treated exactly like \"not found\" — the user types\n // the address instead. Never surfaced as a crash. Going through\n // `Promise.resolve().then` rather than calling directly covers the two\n // failure modes an `await … .catch()` misses: a lookup that throws\n // SYNCHRONOUSLY, and one that returns something other than a promise.\n const address = await Promise.resolve()\n .then(() => lookupRef.current?.(digits))\n .catch(() => null);\n if (seqRef.current !== mySeq) return;\n setStatus(address ? 'found' : 'notfound');\n // A miss is reported too, so a caller that filled from a PREVIOUS CEP\n // can undo it rather than leaving that address under this CEP.\n if (address) resolvedRef.current?.(address);\n else notFoundRef.current?.();\n })();\n }, debounceMs);\n\n return () => clearTimeout(handle);\n }, [digits, complete, disabled, debounceMs]);\n\n return status;\n}\n\n/**\n * The lookup outcome as a live region, so screen readers announce it without\n * stealing focus. Silent while idle, and while the caller is showing its own\n * validation error (which would otherwise stack two messages).\n */\nfunction CepStatus({\n status,\n testId,\n suppressed,\n copy,\n}: {\n status: CepLookupStatus;\n testId: string;\n suppressed: boolean;\n copy: CepFieldCopy;\n}): React.ReactElement {\n const visible = !suppressed && status !== 'idle';\n return (\n <span id={`${testId}-status`} role=\"status\" aria-live=\"polite\">\n {visible && (\n <FormMessage error={status === 'notfound'} dataTestId={`${testId}-${status}`}>\n {copy[status as Exclude<CepLookupStatus, 'idle'>]}\n </FormMessage>\n )}\n </span>\n );\n}\n\n/** What only the `<input>` can act on. Hoisted: one object for every render. */\nconst CEP_INPUT_PROPS = { inputMode: 'numeric' } as const;\n\n/** `postal-code` unless the caller said otherwise (`off` for somebody else's address). */\nconst autoCompleteOf = (autoComplete: string | undefined): string => autoComplete ?? 'postal-code';\n\n/** The stacked label over the box (`labelPlacement=\"above\"`), or nothing when there is no label. */\nfunction AboveLabel({\n name,\n label,\n error,\n}: {\n name: string;\n label?: string;\n error?: string;\n}): React.ReactElement | null {\n if (!label) return null;\n return (\n <FormLabel htmlFor={name} error={Boolean(error)}>\n {label}\n </FormLabel>\n );\n}\n\n/** The label handed to the `Input`, which draws it in the box: only for `inside`. */\nfunction insideLabel(label: string | undefined, placement: 'above' | 'inside'): string | undefined {\n return placement === 'inside' ? label : undefined;\n}\n\n/**\n * A CEP input that fills the rest of the address in.\n *\n * The pattern every Brazilian form has used for twenty years: type eight\n * digits, and logradouro/bairro/cidade/UF arrive on their own. This is the\n * reusable half — masking, validation, debouncing, race-safety and status —\n * with the actual lookup injected via `onLookup`, so the same component serves\n * a supplier form, a store-location form or a delivery checkout without\n * knowing anything about providers or auth.\n *\n * Resolution is best-effort by design. A provider outage, an unknown CEP or a\n * timeout leaves the field exactly as usable as a plain text input — the user\n * types the address themselves. Autofill never blocks.\n *\n * @example\n * ```tsx\n * <CepField\n * value={cep}\n * onChange={setCep}\n * onLookup={(c) => fetch(`/api/…/lookup/cep/${c}`).then((r) => r.json()).then((b) => b.data)}\n * onResolved={(a) => { setStreet(a.street ?? ''); setCity(a.city ?? ''); }}\n * />\n * ```\n */\nexport function CepField({\n value,\n onChange,\n onLookup,\n onResolved,\n onNotFound,\n label = 'CEP',\n placeholder = '00000-000',\n error,\n disabled = false,\n debounceMs = 500,\n name = 'postalCode',\n dataTestId,\n copy,\n size, // undefined reaches `Input`, whose own default is `md`\n labelPlacement = 'above',\n autoComplete,\n}: CepFieldProps): React.ReactElement {\n const testId = dataTestId ?? `cep-field-${name}`;\n\n const status = useCepLookup({\n digits: cepDigits(value),\n complete: isValidCep(value),\n disabled,\n debounceMs,\n onLookup,\n onResolved,\n onNotFound,\n });\n\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => onChange(formatCep(event.target.value)),\n [onChange],\n );\n\n return (\n <FormControl fullWidth>\n {labelPlacement === 'above' && <AboveLabel name={name} label={label} error={error} />}\n <Input\n id={name}\n name={name}\n type=\"text\"\n // On the `<input>`, through `inputProps`: a top-level `inputMode` is a\n // prop `Input` does not recognise, so it landed on the wrapper `div`\n // and the phone kept opening the letter keyboard for eight digits\n // (FUT-1440's CepField row).\n inputProps={CEP_INPUT_PROPS}\n autoComplete={autoCompleteOf(autoComplete)}\n size={size}\n // `inside`: the label is the Input's own, drawn in the box and floating\n // up on focus or a value — what every other `Input` in the form does.\n // `above` keeps the stacked `FormLabel`, for callers that never opted in.\n label={insideLabel(label, labelPlacement)}\n placeholder={placeholder}\n value={value}\n error={Boolean(error)}\n disabled={disabled}\n loading={status === 'loading'}\n onChange={handleChange}\n data-testid={testId}\n aria-describedby={`${testId}-status`}\n aria-busy={status === 'loading'}\n />\n {error && (\n <FormMessage error dataTestId={`${testId}-message`}>\n {error}\n </FormMessage>\n )}\n <CepStatus status={status} testId={testId} suppressed={Boolean(error)} copy={copy} />\n </FormControl>\n );\n}\n\nexport default CepField;\n"],"mappings":"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","names":[]}
|
|
File without changes
|
|
File without changes
|