@usgb/forms 1.0.2 → 1.0.4

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.
Files changed (43) hide show
  1. package/README.md +131 -142
  2. package/dist/forms-manifest.1.0.4.json +439 -0
  3. package/dist/forms-manifest.json +218 -84
  4. package/dist/index.js +636 -559
  5. package/dist/src/contract/createIdempotencyKey.d.ts +2 -0
  6. package/dist/src/contract/createIdempotencyKey.d.ts.map +1 -0
  7. package/dist/src/contract/createStubAdapter.d.ts.map +1 -1
  8. package/dist/src/contract/types.d.ts +15 -15
  9. package/dist/src/contract/types.d.ts.map +1 -1
  10. package/dist/src/definitions/consents.d.ts +15 -0
  11. package/dist/src/definitions/consents.d.ts.map +1 -1
  12. package/dist/src/definitions/index.d.ts +4 -3
  13. package/dist/src/definitions/index.d.ts.map +1 -1
  14. package/dist/src/definitions/manifest.d.ts +14 -1
  15. package/dist/src/definitions/manifest.d.ts.map +1 -1
  16. package/dist/src/definitions/types.d.ts +35 -5
  17. package/dist/src/definitions/types.d.ts.map +1 -1
  18. package/dist/src/form/FormShell.d.ts +2 -1
  19. package/dist/src/form/FormShell.d.ts.map +1 -1
  20. package/dist/src/form/UsgbForm.d.ts +5 -4
  21. package/dist/src/form/UsgbForm.d.ts.map +1 -1
  22. package/dist/src/form/chunkFields.d.ts +1 -1
  23. package/dist/src/form/kinds/LeadKindForm.d.ts +1 -1
  24. package/dist/src/form/kinds/LeadKindForm.d.ts.map +1 -1
  25. package/dist/src/form/kinds/NewsletterKindForm.d.ts +1 -1
  26. package/dist/src/form/kinds/NewsletterKindForm.d.ts.map +1 -1
  27. package/dist/src/form/kinds/types.d.ts +3 -1
  28. package/dist/src/form/kinds/types.d.ts.map +1 -1
  29. package/dist/src/form/useUsgbFormSession.d.ts +3 -4
  30. package/dist/src/form/useUsgbFormSession.d.ts.map +1 -1
  31. package/dist/src/index.d.ts +5 -5
  32. package/dist/src/index.d.ts.map +1 -1
  33. package/dist/src/ui/Button.d.ts.map +1 -1
  34. package/dist/src/ui/ConsentField.d.ts.map +1 -1
  35. package/dist/usgb-forms.1.0.4.js +44 -0
  36. package/dist/usgb-forms.css +141 -45
  37. package/dist/usgb-forms.js +11 -11
  38. package/forms-manifest.json +218 -84
  39. package/package.json +1 -1
  40. package/dist/forms-manifest.1.0.2.json +0 -305
  41. package/dist/src/contract/collectContext.d.ts +0 -9
  42. package/dist/src/contract/collectContext.d.ts.map +0 -1
  43. package/dist/usgb-forms.1.0.2.js +0 -44
@@ -2,6 +2,14 @@
2
2
  styles/variables.css. Hosts override semantic --usgb-* vars or classes
3
3
  on .usgb-form (see README). */
4
4
 
5
+ /* Custom elements default to `display: inline`; the <usgb-form> host must
6
+ be a full-width block so the form fills the space the page gives it. */
7
+ usgb-form {
8
+ display: block;
9
+ width: 100%;
10
+ min-width: 0;
11
+ }
12
+
5
13
  .usgb-form {
6
14
  --usgb-primary: #ffffff;
7
15
  --usgb-secondary: #000000;
@@ -21,9 +29,13 @@
21
29
  --usgb-hover: #5caad6;
22
30
  --usgb-sidebar-field-text: #333333;
23
31
  --usgb-sidebar-link: #275582;
24
- --usgb-font-primary: 'Montserrat', -apple-system, BlinkMacSystemFont,
25
- 'Helvetica Neue', Helvetica, sans-serif;
26
- --usgb-font-secondary: 'Kameron', Georgia, 'Times New Roman', serif;
32
+ /* Body copy inherits the host font (see font-family below), so it follows
33
+ WordPress ("Montserrat") and the PWA (next/font's hashed
34
+ "__Montserrat_…") alike. Set --usgb-font-primary to opt into an
35
+ explicit stack instead. The heading cannot inherit: it prefers the
36
+ PWA's next/font variable and falls back to the WordPress family name. */
37
+ --usgb-font-secondary: var(--font-kameron, 'Kameron'), Georgia,
38
+ 'Times New Roman', serif;
27
39
  --usgb-outline-focused: 2px solid var(--usgb-gold-1);
28
40
 
29
41
  --usgb-form-content: var(--usgb-text-base);
@@ -32,7 +44,7 @@
32
44
  --usgb-field-background: var(--usgb-primary);
33
45
  --usgb-field-border: var(--usgb-secondary);
34
46
  --usgb-field-text: var(--usgb-secondary);
35
- --usgb-field-placeholder: var(--usgb-grey-3);
47
+ --usgb-field-placeholder: var(--usgb-grey-2);
36
48
  --usgb-link: var(--usgb-blue-1);
37
49
  --usgb-link-hover: var(--usgb-hover);
38
50
  --usgb-checkbox-background: var(--usgb-primary);
@@ -45,16 +57,18 @@
45
57
  --usgb-button-disabled-text: var(--usgb-primary);
46
58
  --usgb-newsletter-underline: var(--usgb-blue-1);
47
59
 
48
- --usgb-group-gap: 1.5rem;
49
- --usgb-grid-gap: 1rem;
50
- --usgb-grid-margin-bottom: 0;
51
- --usgb-heading-font-size: 1.75rem;
60
+ --usgb-group-gap: 1.25rem;
61
+ /* Column gap in the name row. Variants inherit the field rhythm and
62
+ override this only when the columns should sit tighter. */
63
+ --usgb-grid-gap: var(--usgb-group-gap);
64
+ --usgb-heading-font-size: 2rem;
52
65
  --usgb-heading-font-weight: 700;
53
- --usgb-heading-line-height: 1.2;
66
+ --usgb-heading-line-height: 2.75rem;
54
67
  --usgb-heading-letter-spacing: 0;
55
68
  --usgb-heading-transform: none;
56
69
  --usgb-heading-margin: 0 0 0.75rem;
57
70
  --usgb-subheading-font-size: 0.875rem;
71
+ --usgb-subheading-font-weight: 400;
58
72
  --usgb-subheading-line-height: 1.5rem;
59
73
  --usgb-subheading-margin: 0 0 1.25rem;
60
74
  --usgb-label-margin-bottom: 0.375rem;
@@ -86,6 +100,7 @@
86
100
  --usgb-consent-color: var(--usgb-form-content);
87
101
  --usgb-consent-transform: none;
88
102
  --usgb-button-padding: 0.625rem 1.875rem;
103
+ --usgb-button-margin-top: 0;
89
104
  --usgb-button-min-height: 2.1875rem;
90
105
  --usgb-button-radius: 3.125rem;
91
106
  --usgb-button-font-size: 0.75rem;
@@ -95,13 +110,20 @@
95
110
  --usgb-button-width: 100%;
96
111
 
97
112
  box-sizing: border-box;
98
- font-family: var(--usgb-font-primary);
113
+ font-family: var(--usgb-font-primary, inherit);
99
114
  color: var(--usgb-form-content);
100
115
  width: 100%;
116
+ /* Lets the form shrink next to siblings when it is a flex/grid item. */
117
+ min-width: 0;
118
+ }
101
119
 
102
- /* Hosts drop this form into sidebars and multi-column blocks, so its own
103
- width — not the viewport's — decides how many fields fit per row. */
104
- container: usgb-form / inline-size;
120
+ /* Landing-page heading steps up on desktop; sidebar and newsletter set
121
+ their own sizes and are unaffected. */
122
+ @media (min-width: 768px) {
123
+ .usgb-form {
124
+ --usgb-heading-font-size: 2.5rem;
125
+ --usgb-heading-line-height: 3.25rem;
126
+ }
105
127
  }
106
128
 
107
129
  .usgb-form *,
@@ -113,6 +135,7 @@
113
135
  /* Layout */
114
136
 
115
137
  .usgb-form .usgb-form-group {
138
+ position: relative;
116
139
  margin-bottom: var(--usgb-group-gap);
117
140
  }
118
141
 
@@ -120,7 +143,7 @@
120
143
  display: grid;
121
144
  grid-template-columns: 1fr;
122
145
  gap: var(--usgb-grid-gap);
123
- margin-bottom: var(--usgb-grid-margin-bottom);
146
+ margin-bottom: var(--usgb-group-gap);
124
147
  }
125
148
 
126
149
  /* Name row only — do not stack form-group margin on top of grid gap. */
@@ -128,20 +151,15 @@
128
151
  margin-bottom: 0;
129
152
  }
130
153
 
131
- @container usgb-form (min-width: 20rem) {
132
- .usgb-form[data-variant~='two-column'] .usgb-form-grid {
133
- grid-template-columns: 1fr 1fr;
134
- }
135
- }
136
-
137
- /* Safari < 16 / Firefox < 110 have no container queries; fall back to the
138
- viewport so those browsers still get a two-up name row on desktop. */
139
- @supports not (container-type: inline-size) {
140
- @media (min-width: 768px) {
141
- .usgb-form[data-variant~='two-column'] .usgb-form-grid {
142
- grid-template-columns: 1fr 1fr;
143
- }
144
- }
154
+ /* Two-up when the row has room for two ~10rem fields, one column otherwise.
155
+ Sized from the grid's own width, so it works in sidebars and flex rows
156
+ without a container query (and the inline-size containment it imposes,
157
+ which would zero the form's natural width inside content-sized parents). */
158
+ .usgb-form[data-layout='two-column'] .usgb-form-grid {
159
+ grid-template-columns: repeat(
160
+ auto-fit,
161
+ minmax(min(100%, var(--usgb-grid-column-min, 10rem)), 1fr)
162
+ );
145
163
  }
146
164
 
147
165
  /* Heading, subheading, status */
@@ -159,6 +177,7 @@
159
177
 
160
178
  .usgb-form .usgb-form-subheading {
161
179
  font-size: var(--usgb-subheading-font-size);
180
+ font-weight: var(--usgb-subheading-font-weight);
162
181
  line-height: var(--usgb-subheading-line-height);
163
182
  margin: var(--usgb-subheading-margin);
164
183
  color: var(--usgb-form-muted);
@@ -205,6 +224,7 @@
205
224
  margin: -1px;
206
225
  overflow: hidden;
207
226
  clip: rect(0, 0, 0, 0);
227
+ clip-path: inset(50%);
208
228
  white-space: nowrap;
209
229
  border: 0;
210
230
  }
@@ -254,6 +274,13 @@
254
274
  outline: none;
255
275
  }
256
276
 
277
+ /* Focus must stay visible when the field is also invalid (2.4.7). */
278
+ .usgb-form .usgb-field-control.usgb-field-invalid:focus {
279
+ border-color: var(--usgb-alert-danger);
280
+ box-shadow: inset 0 0 0 1px var(--usgb-gold-1);
281
+ outline: none;
282
+ }
283
+
257
284
  .usgb-form .usgb-field-control:disabled {
258
285
  outline: none;
259
286
  border-color: var(--usgb-grey-9);
@@ -310,6 +337,15 @@
310
337
  flex-shrink: 0;
311
338
  }
312
339
 
340
+ .usgb-form .usgb-form-checkbox:focus {
341
+ outline: none;
342
+ }
343
+
344
+ .usgb-form .usgb-form-checkbox:focus-visible {
345
+ outline: var(--usgb-outline-focused);
346
+ outline-offset: 2px;
347
+ }
348
+
313
349
  .usgb-form .usgb-form-checkbox-mark {
314
350
  position: absolute;
315
351
  inset: 0;
@@ -335,10 +371,12 @@
335
371
 
336
372
  .usgb-form .usgb-consent-notice {
337
373
  margin: 0 0 var(--usgb-consent-margin-bottom);
374
+ cursor: default;
338
375
  }
339
376
 
340
377
  .usgb-form .usgb-consent-copy a {
341
378
  color: var(--usgb-link);
379
+ font-weight: var(--usgb-consent-link-font-weight, inherit);
342
380
  text-decoration: underline;
343
381
  }
344
382
 
@@ -352,6 +390,7 @@
352
390
  cursor: pointer;
353
391
  display: inline-flex;
354
392
  padding: var(--usgb-button-padding);
393
+ margin-top: var(--usgb-button-margin-top);
355
394
  min-height: var(--usgb-button-min-height);
356
395
  border-radius: var(--usgb-button-radius);
357
396
  line-height: var(--usgb-button-line-height);
@@ -375,7 +414,7 @@
375
414
  border-color: var(--usgb-button-background);
376
415
  }
377
416
 
378
- .usgb-form .usgb-btn-primary:hover:not(:disabled) {
417
+ .usgb-form .usgb-btn-primary:hover:not(:disabled):not([aria-disabled='true']) {
379
418
  background: var(--usgb-button-hover-background);
380
419
  color: var(--usgb-button-text);
381
420
  border-color: var(--usgb-button-hover-background);
@@ -389,12 +428,17 @@
389
428
  outline: var(--usgb-outline-focused);
390
429
  }
391
430
 
392
- .usgb-form .usgb-btn:disabled {
431
+ .usgb-form .usgb-btn:disabled,
432
+ .usgb-form .usgb-btn[aria-disabled='true'] {
393
433
  cursor: not-allowed;
434
+ }
435
+
436
+ .usgb-form .usgb-btn:disabled {
394
437
  pointer-events: none;
395
438
  }
396
439
 
397
- .usgb-form .usgb-btn-primary:disabled {
440
+ .usgb-form .usgb-btn-primary:disabled,
441
+ .usgb-form .usgb-btn-primary[aria-disabled='true'] {
398
442
  background: var(--usgb-button-disabled-background);
399
443
  color: var(--usgb-button-disabled-text);
400
444
  border-color: var(--usgb-button-disabled-background);
@@ -423,29 +467,52 @@
423
467
  /* Inverse hover keeps the white fill and gains a 3px ring. Two of those
424
468
  pixels are an inset shadow over the 1px border so the button does not
425
469
  change size between rest and hover. */
426
- .usgb-form[data-appearance='on-dark'] .usgb-btn-primary:hover:not(:disabled) {
470
+ .usgb-form[data-appearance='on-dark']
471
+ .usgb-btn-primary:hover:not(:disabled):not([aria-disabled='true']) {
427
472
  border-color: var(--usgb-hover);
428
473
  box-shadow: inset 0 0 0 2px var(--usgb-hover);
429
474
  }
430
475
 
431
476
  /* Variants */
432
477
 
478
+ /* Dense shares the landing-page type scale with large; spacing stays dense. */
433
479
  .usgb-form[data-variant~='dense'] {
434
- --usgb-group-gap: 1.25rem;
435
- --usgb-grid-gap: 1rem;
436
- --usgb-grid-margin-bottom: 1.25rem;
480
+ --usgb-group-gap: 1.125rem;
481
+ --usgb-subheading-font-size: 1.125rem;
482
+ --usgb-subheading-font-weight: 500;
483
+ --usgb-subheading-line-height: 1.75rem;
437
484
  --usgb-consent-font-size: 0.75rem;
438
485
  --usgb-consent-font-weight: 400;
439
486
  --usgb-consent-line-height: 1.4;
440
487
  --usgb-consent-transform: none;
488
+ /* The row's own margin would stack on the group margin. */
489
+ --usgb-consent-margin-bottom: 0;
490
+ --usgb-button-font-size: 1.125rem;
491
+ --usgb-button-line-height: 1.125rem;
492
+ }
493
+
494
+ /* 6px between consents. A trailing notice has no field-group margin of its
495
+ own, so it keeps the field gap above the button. */
496
+ .usgb-form[data-variant~='dense'] .usgb-consent-notice {
497
+ margin-bottom: var(--usgb-group-gap);
498
+ }
499
+
500
+ .usgb-form[data-variant~='dense'] .usgb-consent:has(+ .usgb-consent) {
501
+ margin-bottom: 0.375rem;
502
+ }
503
+
504
+ @media (min-width: 768px) {
505
+ .usgb-form[data-variant~='dense'] {
506
+ --usgb-subheading-line-height: 1.8125rem;
507
+ --usgb-button-font-size: 1.25rem;
508
+ --usgb-button-line-height: 0.875rem;
509
+ }
441
510
  }
442
511
 
443
512
  /* Compact blog/sidebar kit — match live HubSpot density, design-sheet tokens. */
444
513
  .usgb-form[data-variant~='sidebar'] {
445
514
  --usgb-field-text: var(--usgb-sidebar-field-text);
446
515
  --usgb-group-gap: 0.625rem;
447
- --usgb-grid-gap: 0.625rem;
448
- --usgb-grid-margin-bottom: 0.625rem;
449
516
  --usgb-heading-font-size: 1.25rem;
450
517
  --usgb-heading-line-height: 1.25;
451
518
  --usgb-heading-margin: 0 0 0.5rem;
@@ -474,6 +541,7 @@
474
541
 
475
542
  .usgb-form[data-variant~='sidebar'][data-appearance='on-light'] {
476
543
  --usgb-field-border: var(--usgb-grey-4);
544
+ --usgb-checkbox-border: var(--usgb-grey-1);
477
545
  --usgb-link: var(--usgb-sidebar-link);
478
546
  }
479
547
 
@@ -488,22 +556,29 @@
488
556
  float: none;
489
557
  }
490
558
 
559
+ /* Large: landing-page form. Figma draws the 1px field and button strokes
560
+ inside the box, so paddings below are the design values minus 1px and
561
+ the rendered boxes land on the designed 53px field / 50px (62px desktop)
562
+ button. */
491
563
  .usgb-form[data-variant~='large'] {
492
564
  --usgb-group-gap: 1.25rem;
493
- --usgb-grid-gap: 1.25rem;
494
- --usgb-grid-margin-bottom: 1.25rem;
495
565
  --usgb-heading-font-size: 2rem;
496
566
  --usgb-heading-font-weight: 700;
497
- --usgb-heading-line-height: 3rem;
567
+ --usgb-heading-line-height: 2.75rem;
498
568
  --usgb-heading-letter-spacing: -0.03125rem;
499
569
  --usgb-heading-transform: uppercase;
570
+ --usgb-heading-margin: 0 0 0.875rem;
571
+ --usgb-subheading-font-size: 1.125rem;
572
+ --usgb-subheading-font-weight: 500;
573
+ --usgb-subheading-line-height: 1.75rem;
574
+ --usgb-subheading-margin: 0 0 1.5rem;
500
575
  --usgb-label-margin-bottom: 0.125rem;
501
576
  --usgb-label-font-size: 1rem;
502
577
  --usgb-label-font-weight: 400;
503
578
  --usgb-label-letter-spacing: 0;
504
579
  --usgb-label-line-height: 1.32;
505
580
  --usgb-label-transform: none;
506
- --usgb-field-padding: 1rem 1.25rem;
581
+ --usgb-field-padding: 0.9375rem 1.0625rem 0.9375rem 1.1875rem;
507
582
  --usgb-field-font-size: 1rem;
508
583
  --usgb-field-font-weight: 400;
509
584
  --usgb-field-line-height: 1.32;
@@ -514,8 +589,29 @@
514
589
  --usgb-checkbox-margin: 0;
515
590
  --usgb-consent-font-size: 1.125rem;
516
591
  --usgb-consent-line-height: 1.75rem;
517
- --usgb-button-min-height: 3.4375rem;
518
- --usgb-button-font-size: 1rem;
592
+ --usgb-consent-link-font-weight: 600;
593
+ /* Preceding field already contributes the 20px group gap; this tops it
594
+ up to the designed 24px (32px desktop) between last field and CTA. */
595
+ --usgb-button-margin-top: 0.25rem;
596
+ --usgb-button-padding: 0.9375rem 3.4375rem;
597
+ --usgb-button-min-height: 3.125rem;
598
+ --usgb-button-font-size: 1.125rem;
599
+ --usgb-button-line-height: 1.125rem;
600
+ }
601
+
602
+ @media (min-width: 768px) {
603
+ .usgb-form[data-variant~='large'] {
604
+ --usgb-heading-font-size: 2.5rem;
605
+ --usgb-heading-line-height: 3.25rem;
606
+ --usgb-subheading-line-height: 1.8125rem;
607
+ --usgb-subheading-margin: 0 0 1.6875rem;
608
+ --usgb-button-margin-top: 0.75rem;
609
+ --usgb-button-padding: 1.4375rem 3.4375rem;
610
+ --usgb-button-min-height: 3.875rem;
611
+ --usgb-button-font-size: 1.25rem;
612
+ --usgb-button-line-height: 0.875rem;
613
+ --usgb-button-width: auto;
614
+ }
519
615
  }
520
616
 
521
617
  /* Newsletter kind: underline email + side CTA */
@@ -565,13 +661,13 @@
565
661
  margin-bottom: 0;
566
662
  box-shadow: none;
567
663
  }
568
-
664
+ /*
569
665
  .usgb-form[data-kind='newsletter']
570
666
  .usgb-form-inline
571
667
  .usgb-field-control::placeholder {
572
668
  color: var(--usgb-grey-9);
573
669
  text-transform: none;
574
- }
670
+ } */
575
671
 
576
672
  .usgb-form[data-kind='newsletter'] .usgb-form-inline .usgb-field-control:focus {
577
673
  border-color: var(--usgb-gold-1);