@coding-blocks/vmc-web-components 0.1.0 → 0.1.2
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
|
@@ -5,8 +5,17 @@ inside, plain custom elements on the outside — a host page only needs one
|
|
|
5
5
|
`<script>` tag and the element.
|
|
6
6
|
|
|
7
7
|
Every component in this repo ships in **one bundle**: `dist/vmc-web-components.js`
|
|
8
|
-
|
|
9
|
-
network requests
|
|
8
|
+
— 37.8 kB, ~14 kB gzipped over the wire, with the runtime and the CSS inlined.
|
|
9
|
+
No peer dependencies, no extra network requests.
|
|
10
|
+
|
|
11
|
+
The source is written against React, but the build aliases `react`/`react-dom`
|
|
12
|
+
to `preact/compat`, which is what actually ships — same JSX and hooks, ~5x
|
|
13
|
+
smaller for a script that loads on other people's pages. Nothing in `src/`
|
|
14
|
+
imports Preact directly, so the alias in `vite.config.ts` is the only place that
|
|
15
|
+
knows. Two build notes worth keeping: the published bundle carries **no
|
|
16
|
+
sourcemap** (it was 4.5x the size of the code), and terser's `unsafe_*` /
|
|
17
|
+
`booleans_as_integers` options are deliberately off — they saved ~2 kB and broke
|
|
18
|
+
Preact's event proxy at runtime.
|
|
10
19
|
|
|
11
20
|
## Usage
|
|
12
21
|
|
|
@@ -34,14 +43,26 @@ can't leak in and the component's CSS can't leak out.
|
|
|
34
43
|
### `<vmc-online-lead>`
|
|
35
44
|
|
|
36
45
|
The "Want a call back?" lead form. Fields posted to the backend:
|
|
37
|
-
`name`, `email`, `dial_code`, `mobile`, `
|
|
38
|
-
`city_id`.
|
|
46
|
+
`name`, `email`, `dial_code`, `mobile`, `form_class_id`, `form_course_id`,
|
|
47
|
+
`state_id`, `city_id`.
|
|
48
|
+
|
|
49
|
+
All eight visible fields are mandatory — name, email, mobile, class, course,
|
|
50
|
+
state and city are validated on submit, each showing its own message under the
|
|
51
|
+
field (`Please select a class.`) and a red border, plus `required` /
|
|
52
|
+
`aria-required` on the control itself. Course stays disabled until a class is
|
|
53
|
+
picked and city until a state is picked, and each resets when its parent
|
|
54
|
+
changes, so an orphaned pair can't be submitted.
|
|
39
55
|
|
|
40
56
|
Mobile verification is mandatory: **Submit stays disabled until the number is
|
|
41
57
|
OTP-verified** and the consent box is ticked. Editing the number after
|
|
42
58
|
verification drops it back to unverified, so a submission can never carry an OTP
|
|
43
59
|
that belongs to a different number.
|
|
44
60
|
|
|
61
|
+
Once verified, the dial code and mobile inputs are disabled, and the verified
|
|
62
|
+
number is held in verification state. The submit payload is built from that
|
|
63
|
+
stored value rather than from the inputs, so re-enabling the fields through
|
|
64
|
+
devtools cannot put an unverified number on the wire.
|
|
65
|
+
|
|
45
66
|
| Attribute | Default | Purpose |
|
|
46
67
|
| --- | --- | --- |
|
|
47
68
|
| `api-base` | build-time `VITE_API_URL` | Override the compiled-in base (testing only) |
|
|
@@ -51,7 +72,6 @@ that belongs to a different number.
|
|
|
51
72
|
| `submit-label` | `Submit` | Submit button label |
|
|
52
73
|
| `success-title` | `Thank you!` | Heading after a successful submit |
|
|
53
74
|
| `success-message` | counsellor call-back copy | Body after a successful submit |
|
|
54
|
-
| `source` | `website` | Sent through as `source` in the payload |
|
|
55
75
|
| `extra-payload` | — | JSON object merged into the submit payload |
|
|
56
76
|
|
|
57
77
|
Events (bubbling and composed, so they cross the shadow boundary):
|
|
@@ -120,18 +140,23 @@ POST {otp-verify-path} { mobile_number, dial_code, otp_id, otp } -> 2xx
|
|
|
120
140
|
"email": "…",
|
|
121
141
|
"dial_code": "+91",
|
|
122
142
|
"mobile": "9999999999",
|
|
123
|
-
"
|
|
124
|
-
"
|
|
143
|
+
"form_class_id": 6,
|
|
144
|
+
"form_course_id": 61,
|
|
125
145
|
"state_id": 2,
|
|
126
146
|
"city_id": 21,
|
|
147
|
+
"admission_test_id": 2147483647,
|
|
127
148
|
"otp_id": "…",
|
|
128
149
|
"mobile_verified": true,
|
|
129
150
|
"consent": true,
|
|
130
|
-
"source": "
|
|
151
|
+
"source": "vmc-online-lead-form",
|
|
131
152
|
"page_url": "https://…"
|
|
132
153
|
}
|
|
133
154
|
```
|
|
134
155
|
|
|
156
|
+
`source` is always `vmc-online-lead-form`, and `admission_test_id` is always
|
|
157
|
+
`2147483647` — the fixed placeholder row for leads
|
|
158
|
+
that arrive without a test assigned.
|
|
159
|
+
|
|
135
160
|
Errors are read from `{ error }` (falling back to `{ message }`) on any non-2xx
|
|
136
161
|
response, so backend validation messages surface directly in the form.
|
|
137
162
|
|
|
@@ -10,8 +10,10 @@ type InputProps = {
|
|
|
10
10
|
autoComplete?: string;
|
|
11
11
|
disabled?: boolean;
|
|
12
12
|
invalid?: boolean;
|
|
13
|
+
required?: boolean;
|
|
14
|
+
error?: string;
|
|
13
15
|
};
|
|
14
|
-
export declare const Input: ({ name, placeholder, value, onChange, type, inputMode, maxLength, autoComplete, disabled, invalid, }: InputProps) => import("react").JSX.Element;
|
|
16
|
+
export declare const Input: ({ name, placeholder, value, onChange, type, inputMode, maxLength, autoComplete, disabled, invalid, required, error, }: InputProps) => import("react").JSX.Element;
|
|
15
17
|
type SelectProps = {
|
|
16
18
|
name: string;
|
|
17
19
|
placeholder: string;
|
|
@@ -20,9 +22,11 @@ type SelectProps = {
|
|
|
20
22
|
options: LookupItem[];
|
|
21
23
|
disabled?: boolean;
|
|
22
24
|
invalid?: boolean;
|
|
25
|
+
required?: boolean;
|
|
26
|
+
error?: string;
|
|
23
27
|
className?: string;
|
|
24
28
|
};
|
|
25
|
-
export declare const Select: ({ name, placeholder, value, onChange, options, disabled, invalid, className, }: SelectProps) => import("react").JSX.Element;
|
|
29
|
+
export declare const Select: ({ name, placeholder, value, onChange, options, disabled, invalid, required, error, className, }: SelectProps) => import("react").JSX.Element;
|
|
26
30
|
type OtpInputProps = {
|
|
27
31
|
length: number;
|
|
28
32
|
value: string;
|
|
@@ -19,6 +19,11 @@ type Options = {
|
|
|
19
19
|
*/
|
|
20
20
|
export declare const useMobileVerification: ({ api, sendPath, verifyPath, dialCode, mobile, resendSeconds, }: Options) => {
|
|
21
21
|
status: VerificationStatus;
|
|
22
|
+
/** Non-null only while `isVerified` — the exact number the OTP was issued for. */
|
|
23
|
+
verified: {
|
|
24
|
+
dialCode: string;
|
|
25
|
+
mobile: string;
|
|
26
|
+
} | null;
|
|
22
27
|
otp: string;
|
|
23
28
|
setOtp: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
24
29
|
otpId: string;
|