@duffel/components 3.0.0-canary → 3.0.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.
Files changed (164) hide show
  1. package/.eslintrc.js +14 -1
  2. package/.github/workflows/release.yml +4 -1
  3. package/.storybook/__snapshots__/Storyshots.test.js.snap +185 -0
  4. package/CONTRIBUTING.md +83 -0
  5. package/README.md +34 -109
  6. package/config/esbuild.base.config.js +7 -3
  7. package/config/esbuild.cdn.config.js +4 -3
  8. package/config/esbuild.dev.config.js +4 -3
  9. package/config/esbuild.react.config.js +3 -3
  10. package/package.json +16 -5
  11. package/react-dist/components/{Card.d.ts → DuffelAncillaries/Card.d.ts} +1 -1
  12. package/react-dist/components/{DuffelAncillaries.d.ts → DuffelAncillaries/DuffelAncillaries.d.ts} +1 -1
  13. package/react-dist/components/{DuffelAncillariesCustomElement.d.ts → DuffelAncillaries/DuffelAncillariesCustomElement.d.ts} +1 -1
  14. package/react-dist/components/{bags → DuffelAncillaries/bags}/BaggageSelectionCard.d.ts +2 -2
  15. package/react-dist/components/{bags → DuffelAncillaries/bags}/BaggageSelectionController.d.ts +2 -2
  16. package/react-dist/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModal.d.ts +2 -2
  17. package/react-dist/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalBody.d.ts +2 -2
  18. package/react-dist/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalBodyPassenger.d.ts +2 -2
  19. package/react-dist/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalFooter.d.ts +1 -1
  20. package/react-dist/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalHeader.d.ts +1 -1
  21. package/react-dist/components/{bags → DuffelAncillaries/bags}/IncludedBaggageBanner.d.ts +1 -1
  22. package/react-dist/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionCard.d.ts +2 -2
  23. package/react-dist/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModal.d.ts +2 -2
  24. package/react-dist/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalBody.d.ts +1 -1
  25. package/react-dist/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalFooter.d.ts +2 -2
  26. package/react-dist/components/{seats → DuffelAncillaries/seats}/Amenity.d.ts +1 -1
  27. package/react-dist/components/{seats → DuffelAncillaries/seats}/Element.d.ts +2 -2
  28. package/react-dist/components/{seats → DuffelAncillaries/seats}/Legend.d.ts +1 -1
  29. package/react-dist/components/{seats → DuffelAncillaries/seats}/Row.d.ts +2 -2
  30. package/react-dist/components/{seats → DuffelAncillaries/seats}/RowSection.d.ts +2 -2
  31. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatElement.d.ts +2 -2
  32. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatInfo.d.ts +1 -1
  33. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatMap.d.ts +2 -2
  34. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatSelectionCard.d.ts +3 -3
  35. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatSelectionModal.d.ts +3 -3
  36. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatSelectionModalFooter.d.ts +2 -2
  37. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatSelectionModalHeader.d.ts +1 -1
  38. package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatUnavailable.d.ts +1 -1
  39. package/react-dist/components/DuffelPayments/DuffelPayments.d.ts +11 -0
  40. package/react-dist/components/DuffelPayments/DuffelPaymentsCustomElement.d.ts +14 -0
  41. package/react-dist/components/{Button.d.ts → shared/Button.d.ts} +2 -2
  42. package/react-dist/components/{ErrorBoundary.d.ts → shared/ErrorBoundary.d.ts} +1 -1
  43. package/react-dist/components/{IconButton.d.ts → shared/IconButton.d.ts} +1 -1
  44. package/react-dist/components/{NonIdealState.d.ts → shared/NonIdealState.d.ts} +1 -1
  45. package/react-dist/custom-elements.d.ts +6 -0
  46. package/react-dist/custom-elements.js +37 -0
  47. package/react-dist/custom-elements.js.map +7 -0
  48. package/react-dist/index.d.ts +4 -5
  49. package/react-dist/index.js +21 -20
  50. package/react-dist/index.js.map +4 -4
  51. package/react-dist/lib/captureErrorInSentry.d.ts +1 -1
  52. package/react-dist/lib/fetchFromDuffelAPI.d.ts +7 -0
  53. package/react-dist/lib/logging.d.ts +7 -14
  54. package/react-dist/lib/retrieveSeatMaps.d.ts +1 -1
  55. package/react-dist/types/DuffelAncillariesProps.d.ts +1 -1
  56. package/scripts/generate-fixture.ts +13 -8
  57. package/scripts/upload-to-cdn.sh +4 -9
  58. package/src/components/{Card.tsx → DuffelAncillaries/Card.tsx} +1 -1
  59. package/src/components/{Counter.tsx → DuffelAncillaries/Counter.tsx} +1 -1
  60. package/src/components/{DuffelAncillaries.tsx → DuffelAncillaries/DuffelAncillaries.tsx} +61 -63
  61. package/src/components/{DuffelAncillariesCustomElement.tsx → DuffelAncillaries/DuffelAncillariesCustomElement.tsx} +2 -2
  62. package/src/components/{bags → DuffelAncillaries/bags}/BaggageSelectionCard.tsx +4 -4
  63. package/src/components/{bags → DuffelAncillaries/bags}/BaggageSelectionController.tsx +2 -2
  64. package/src/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModal.tsx +3 -3
  65. package/src/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalBody.tsx +3 -3
  66. package/src/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalBodyPassenger.tsx +2 -2
  67. package/src/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalFooter.tsx +2 -2
  68. package/src/components/{bags → DuffelAncillaries/bags}/BaggageSelectionModalHeader.tsx +1 -1
  69. package/src/components/{bags → DuffelAncillaries/bags}/IncludedBaggageBanner.tsx +1 -1
  70. package/src/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionCard.tsx +4 -4
  71. package/src/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModal.tsx +3 -3
  72. package/src/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalBody.tsx +3 -3
  73. package/src/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalBodyListItem.tsx +1 -1
  74. package/src/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalFooter.tsx +4 -4
  75. package/src/components/{seats → DuffelAncillaries/seats}/Amenity.tsx +2 -2
  76. package/src/components/{seats → DuffelAncillaries/seats}/DeckSelect.tsx +1 -1
  77. package/src/components/{seats → DuffelAncillaries/seats}/Element.tsx +2 -2
  78. package/src/components/{seats → DuffelAncillaries/seats}/ExitElement.tsx +1 -1
  79. package/src/components/{seats → DuffelAncillaries/seats}/Legend.tsx +2 -2
  80. package/src/components/{seats → DuffelAncillaries/seats}/Row.tsx +2 -2
  81. package/src/components/{seats → DuffelAncillaries/seats}/RowSection.tsx +5 -2
  82. package/src/components/{seats → DuffelAncillaries/seats}/SeatElement.tsx +3 -3
  83. package/src/components/{seats → DuffelAncillaries/seats}/SeatInfo.tsx +1 -1
  84. package/src/components/{seats → DuffelAncillaries/seats}/SeatMap.tsx +2 -2
  85. package/src/components/{seats → DuffelAncillaries/seats}/SeatMapUnavailable.tsx +1 -1
  86. package/src/components/{seats → DuffelAncillaries/seats}/SeatSelectionCard.tsx +5 -5
  87. package/src/components/{seats → DuffelAncillaries/seats}/SeatSelectionModal.tsx +4 -4
  88. package/src/components/{seats → DuffelAncillaries/seats}/SeatSelectionModalBody.tsx +1 -1
  89. package/src/components/{seats → DuffelAncillaries/seats}/SeatSelectionModalFooter.tsx +3 -3
  90. package/src/components/{seats → DuffelAncillaries/seats}/SeatSelectionModalHeader.tsx +1 -1
  91. package/src/components/{seats → DuffelAncillaries/seats}/SeatUnavailable.tsx +2 -2
  92. package/src/components/DuffelPayments/DuffelPayments.tsx +218 -0
  93. package/src/components/DuffelPayments/DuffelPaymentsCustomElement.tsx +130 -0
  94. package/src/components/{Button.tsx → shared/Button.tsx} +4 -3
  95. package/src/components/{ErrorBoundary.tsx → shared/ErrorBoundary.tsx} +2 -2
  96. package/src/components/{Icon.tsx → shared/Icon.tsx} +2 -1
  97. package/src/components/{IconButton.tsx → shared/IconButton.tsx} +1 -1
  98. package/src/components/{Modal.tsx → shared/Modal.tsx} +5 -1
  99. package/src/components/{NonIdealState.tsx → shared/NonIdealState.tsx} +1 -1
  100. package/src/custom-elements.ts +13 -0
  101. package/src/examples/client-side/README.md +30 -0
  102. package/src/examples/client-side/index.html +1 -1
  103. package/src/examples/full-stack/README.md +34 -0
  104. package/src/examples/full-stack/index.html +1 -1
  105. package/src/examples/full-stack/server.mjs +1 -0
  106. package/src/examples/just-typescript/src/index.html +2 -2
  107. package/src/examples/just-typescript/src/index.ts +2 -1
  108. package/src/examples/payments-custom-element/README.md +17 -0
  109. package/src/examples/payments-custom-element/index.html +43 -0
  110. package/src/examples/payments-just-typescript/README.md +37 -0
  111. package/src/examples/payments-just-typescript/package.json +16 -0
  112. package/src/examples/payments-just-typescript/src/index.html +23 -0
  113. package/src/examples/payments-just-typescript/src/index.ts +18 -0
  114. package/src/examples/payments-just-typescript/yarn.lock +154 -0
  115. package/src/examples/react-app/src/index.tsx +11 -6
  116. package/src/index.ts +4 -5
  117. package/src/lib/captureErrorInSentry.ts +2 -20
  118. package/src/lib/fetchFromDuffelAPI.ts +36 -6
  119. package/src/lib/formatDate.ts +3 -4
  120. package/src/lib/getBaggageServiceDescription.ts +2 -4
  121. package/src/lib/getTotalAmountForServices.ts +1 -1
  122. package/src/lib/logging.ts +52 -32
  123. package/src/lib/retrieveOffer.ts +11 -6
  124. package/src/lib/retrieveSeatMaps.ts +13 -8
  125. package/src/stories/BaggageSelectionModalHeader.stories.tsx +1 -1
  126. package/src/stories/Button.stories.tsx +12 -3
  127. package/src/stories/DuffelAncillaries.stories.tsx +1 -1
  128. package/src/stories/DuffelPayments.stories.tsx +34 -0
  129. package/src/stories/Icon.stories.tsx +3 -2
  130. package/src/stories/IconButton.stories.tsx +1 -1
  131. package/src/styles/components/DuffelPayments.css +42 -0
  132. package/src/styles/components/Modal.css +2 -1
  133. package/src/styles/global.css +1 -0
  134. package/src/tests/components/DuffelAncillaries.test.tsx +1 -1
  135. package/src/tests/lib/createPriceFormatters.test.tsx +1 -1
  136. package/src/tests/lib/formatAvailableServices.test.tsx +1 -1
  137. package/src/tests/lib/formatSeatMaps.test.tsx +2 -2
  138. package/src/tests/lib/getCurrencyForServices.test.tsx +1 -1
  139. package/src/tests/lib/hasServiceOfSameMetadataTypeAlreadyBeenSelected.test.ts +1 -1
  140. package/src/tests/lib/logging.test.tsx +14 -14
  141. package/src/tests/lib/moneyStringFormatter.test.tsx +1 -1
  142. package/src/tests/lib/validateProps.test.tsx +1 -1
  143. package/src/types/DuffelAncillariesProps.ts +1 -1
  144. package/tsconfig.json +1 -1
  145. /package/react-dist/components/{Counter.d.ts → DuffelAncillaries/Counter.d.ts} +0 -0
  146. /package/react-dist/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalBodyListItem.d.ts +0 -0
  147. /package/react-dist/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalHeader.d.ts +0 -0
  148. /package/react-dist/components/{seats → DuffelAncillaries/seats}/DeckSelect.d.ts +0 -0
  149. /package/react-dist/components/{seats → DuffelAncillaries/seats}/EmptyElement.d.ts +0 -0
  150. /package/react-dist/components/{seats → DuffelAncillaries/seats}/ExitElement.d.ts +0 -0
  151. /package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatMapUnavailable.d.ts +0 -0
  152. /package/react-dist/components/{seats → DuffelAncillaries/seats}/SeatSelectionModalBody.d.ts +0 -0
  153. /package/react-dist/components/{AnimatedLoaderEllipsis.d.ts → shared/AnimatedLoaderEllipsis.d.ts} +0 -0
  154. /package/react-dist/components/{FetchOfferErrorState.d.ts → shared/FetchOfferErrorState.d.ts} +0 -0
  155. /package/react-dist/components/{Icon.d.ts → shared/Icon.d.ts} +0 -0
  156. /package/react-dist/components/{Modal.d.ts → shared/Modal.d.ts} +0 -0
  157. /package/react-dist/components/{Stamp.d.ts → shared/Stamp.d.ts} +0 -0
  158. /package/react-dist/components/{Tabs.d.ts → shared/Tabs.d.ts} +0 -0
  159. /package/src/components/{cancel_for_any_reason → DuffelAncillaries/cancel_for_any_reason}/CfarSelectionModalHeader.tsx +0 -0
  160. /package/src/components/{seats → DuffelAncillaries/seats}/EmptyElement.tsx +0 -0
  161. /package/src/components/{AnimatedLoaderEllipsis.tsx → shared/AnimatedLoaderEllipsis.tsx} +0 -0
  162. /package/src/components/{FetchOfferErrorState.tsx → shared/FetchOfferErrorState.tsx} +0 -0
  163. /package/src/components/{Stamp.tsx → shared/Stamp.tsx} +0 -0
  164. /package/src/components/{Tabs.tsx → shared/Tabs.tsx} +0 -0
package/.eslintrc.js CHANGED
@@ -9,7 +9,12 @@ module.exports = {
9
9
  node: true,
10
10
  jest: true,
11
11
  },
12
- ignorePatterns: ["**/dist/**", "react-dist/**", "__generated__**"],
12
+ ignorePatterns: [
13
+ "**/dist/**",
14
+ "**/cdn-dist/**",
15
+ "**/react-dist/**",
16
+ "__generated__**",
17
+ ],
13
18
  parser: "@typescript-eslint/parser",
14
19
  extends: [
15
20
  "eslint:recommended",
@@ -30,5 +35,13 @@ module.exports = {
30
35
  "react/react-in-jsx-scope": 0,
31
36
  "react/prop-types": 0,
32
37
  "react-hooks/exhaustive-deps": 0,
38
+ "no-restricted-syntax": [
39
+ "error",
40
+ {
41
+ selector: "CallExpression[callee.object.name='console']",
42
+ message:
43
+ "Prefer 'log' or 'logGroup' from 'src/lib/logging.ts' instead of 'console'.",
44
+ },
45
+ ],
33
46
  },
34
47
  };
@@ -45,6 +45,9 @@ jobs:
45
45
  GIT_AUTHOR_EMAIL: duffel-bot-read-write@duffel.com
46
46
  GIT_COMMITTER_NAME: duffel-bot
47
47
  GIT_COMMITTER_EMAIL: duffel-bot-read-write@duffel.com
48
+ DUFFEL_API_URL: https://api.duffel.com
49
+ COMPONENT_CDN: https://assets.duffel.com/components
50
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
48
51
  run: yarn release
49
52
 
50
53
  - name: Get version from package.json after release step
@@ -62,7 +65,7 @@ jobs:
62
65
  if: steps.initversion.outputs.version != steps.extractver.outputs.extractver
63
66
  uses: peter-evans/create-pull-request@v3.10.0
64
67
  with:
65
- token: ${{ secrets.PAT }}
68
+ token: ${{ secrets.PAT }} # You can fin this on https://duffel.1password.com/vaults/all/allitems/m3heg3y3ijclli4tmmp4bsyxna
66
69
  commit-message: "chore(release): ${{ steps.extractver.outputs.extractver }}"
67
70
  committer: duffel-bot <duffel-bot-read-write@duffel.com>
68
71
  author: duffel-bot <duffel-bot-read-write@duffel.com>
@@ -360,6 +360,11 @@ exports[`Storyshots DuffelAncillaries All Services 1`] = `
360
360
  </button>
361
361
  <div
362
362
  className="modal"
363
+ style={
364
+ {
365
+ "opacity": 0,
366
+ }
367
+ }
363
368
  >
364
369
  <div
365
370
  className="modal--content"
@@ -735,6 +740,11 @@ exports[`Storyshots DuffelAncillaries All Services 1`] = `
735
740
  </button>
736
741
  <div
737
742
  className="modal"
743
+ style={
744
+ {
745
+ "opacity": 0,
746
+ }
747
+ }
738
748
  >
739
749
  <div
740
750
  className="modal--content"
@@ -6718,6 +6728,11 @@ exports[`Storyshots DuffelAncillaries All Services 1`] = `
6718
6728
  </button>
6719
6729
  <div
6720
6730
  className="modal"
6731
+ style={
6732
+ {
6733
+ "opacity": 0,
6734
+ }
6735
+ }
6721
6736
  >
6722
6737
  <div
6723
6738
  className="modal--content"
@@ -7046,6 +7061,11 @@ exports[`Storyshots DuffelAncillaries Expired Offer 1`] = `
7046
7061
  </button>
7047
7062
  <div
7048
7063
  className="modal"
7064
+ style={
7065
+ {
7066
+ "opacity": 0,
7067
+ }
7068
+ }
7049
7069
  >
7050
7070
  <div
7051
7071
  className="modal--content"
@@ -7421,6 +7441,11 @@ exports[`Storyshots DuffelAncillaries Expired Offer 1`] = `
7421
7441
  </button>
7422
7442
  <div
7423
7443
  className="modal"
7444
+ style={
7445
+ {
7446
+ "opacity": 0,
7447
+ }
7448
+ }
7424
7449
  >
7425
7450
  <div
7426
7451
  className="modal--content"
@@ -13404,6 +13429,11 @@ exports[`Storyshots DuffelAncillaries Expired Offer 1`] = `
13404
13429
  </button>
13405
13430
  <div
13406
13431
  className="modal"
13432
+ style={
13433
+ {
13434
+ "opacity": 0,
13435
+ }
13436
+ }
13407
13437
  >
13408
13438
  <div
13409
13439
  className="modal--content"
@@ -13732,6 +13762,11 @@ exports[`Storyshots DuffelAncillaries Just Bags 1`] = `
13732
13762
  </button>
13733
13763
  <div
13734
13764
  className="modal"
13765
+ style={
13766
+ {
13767
+ "opacity": 0,
13768
+ }
13769
+ }
13735
13770
  >
13736
13771
  <div
13737
13772
  className="modal--content"
@@ -14128,6 +14163,11 @@ exports[`Storyshots DuffelAncillaries Just CFAR 1`] = `
14128
14163
  </button>
14129
14164
  <div
14130
14165
  className="modal"
14166
+ style={
14167
+ {
14168
+ "opacity": 0,
14169
+ }
14170
+ }
14131
14171
  >
14132
14172
  <div
14133
14173
  className="modal--content"
@@ -14456,6 +14496,11 @@ exports[`Storyshots DuffelAncillaries Just Seats 1`] = `
14456
14496
  </button>
14457
14497
  <div
14458
14498
  className="modal"
14499
+ style={
14500
+ {
14501
+ "opacity": 0,
14502
+ }
14503
+ }
14459
14504
  >
14460
14505
  <div
14461
14506
  className="modal--content"
@@ -20460,6 +20505,11 @@ exports[`Storyshots DuffelAncillaries Markup 1`] = `
20460
20505
  </button>
20461
20506
  <div
20462
20507
  className="modal"
20508
+ style={
20509
+ {
20510
+ "opacity": 0,
20511
+ }
20512
+ }
20463
20513
  >
20464
20514
  <div
20465
20515
  className="modal--content"
@@ -20835,6 +20885,11 @@ exports[`Storyshots DuffelAncillaries Markup 1`] = `
20835
20885
  </button>
20836
20886
  <div
20837
20887
  className="modal"
20888
+ style={
20889
+ {
20890
+ "opacity": 0,
20891
+ }
20892
+ }
20838
20893
  >
20839
20894
  <div
20840
20895
  className="modal--content"
@@ -26818,6 +26873,11 @@ exports[`Storyshots DuffelAncillaries Markup 1`] = `
26818
26873
  </button>
26819
26874
  <div
26820
26875
  className="modal"
26876
+ style={
26877
+ {
26878
+ "opacity": 0,
26879
+ }
26880
+ }
26821
26881
  >
26822
26882
  <div
26823
26883
  className="modal--content"
@@ -27146,6 +27206,11 @@ exports[`Storyshots DuffelAncillaries Markup Using Price Formatters 1`] = `
27146
27206
  </button>
27147
27207
  <div
27148
27208
  className="modal"
27209
+ style={
27210
+ {
27211
+ "opacity": 0,
27212
+ }
27213
+ }
27149
27214
  >
27150
27215
  <div
27151
27216
  className="modal--content"
@@ -27521,6 +27586,11 @@ exports[`Storyshots DuffelAncillaries Markup Using Price Formatters 1`] = `
27521
27586
  </button>
27522
27587
  <div
27523
27588
  className="modal"
27589
+ style={
27590
+ {
27591
+ "opacity": 0,
27592
+ }
27593
+ }
27524
27594
  >
27525
27595
  <div
27526
27596
  className="modal--content"
@@ -33504,6 +33574,11 @@ exports[`Storyshots DuffelAncillaries Markup Using Price Formatters 1`] = `
33504
33574
  </button>
33505
33575
  <div
33506
33576
  className="modal"
33577
+ style={
33578
+ {
33579
+ "opacity": 0,
33580
+ }
33581
+ }
33507
33582
  >
33508
33583
  <div
33509
33584
  className="modal--content"
@@ -33832,6 +33907,11 @@ exports[`Storyshots DuffelAncillaries Markup Using Price Formatters With Custom
33832
33907
  </button>
33833
33908
  <div
33834
33909
  className="modal"
33910
+ style={
33911
+ {
33912
+ "opacity": 0,
33913
+ }
33914
+ }
33835
33915
  >
33836
33916
  <div
33837
33917
  className="modal--content"
@@ -34207,6 +34287,11 @@ exports[`Storyshots DuffelAncillaries Markup Using Price Formatters With Custom
34207
34287
  </button>
34208
34288
  <div
34209
34289
  className="modal"
34290
+ style={
34291
+ {
34292
+ "opacity": 0,
34293
+ }
34294
+ }
34210
34295
  >
34211
34296
  <div
34212
34297
  className="modal--content"
@@ -40190,6 +40275,11 @@ exports[`Storyshots DuffelAncillaries Markup Using Price Formatters With Custom
40190
40275
  </button>
40191
40276
  <div
40192
40277
  className="modal"
40278
+ style={
40279
+ {
40280
+ "opacity": 0,
40281
+ }
40282
+ }
40193
40283
  >
40194
40284
  <div
40195
40285
  className="modal--content"
@@ -40521,6 +40611,11 @@ exports[`Storyshots DuffelAncillaries With Custom Styles 1`] = `
40521
40611
  </button>
40522
40612
  <div
40523
40613
  className="modal"
40614
+ style={
40615
+ {
40616
+ "opacity": 0,
40617
+ }
40618
+ }
40524
40619
  >
40525
40620
  <div
40526
40621
  className="modal--content"
@@ -40896,6 +40991,11 @@ exports[`Storyshots DuffelAncillaries With Custom Styles 1`] = `
40896
40991
  </button>
40897
40992
  <div
40898
40993
  className="modal"
40994
+ style={
40995
+ {
40996
+ "opacity": 0,
40997
+ }
40998
+ }
40899
40999
  >
40900
41000
  <div
40901
41001
  className="modal--content"
@@ -46879,6 +46979,11 @@ exports[`Storyshots DuffelAncillaries With Custom Styles 1`] = `
46879
46979
  </button>
46880
46980
  <div
46881
46981
  className="modal"
46982
+ style={
46983
+ {
46984
+ "opacity": 0,
46985
+ }
46986
+ }
46882
46987
  >
46883
46988
  <div
46884
46989
  className="modal--content"
@@ -47070,6 +47175,86 @@ exports[`Storyshots DuffelAncillaries With Custom Styles 1`] = `
47070
47175
  ]
47071
47176
  `;
47072
47177
 
47178
+ exports[`Storyshots DuffelPayments Default 1`] = `
47179
+ [
47180
+ <link
47181
+ href="/global.css"
47182
+ rel="stylesheet"
47183
+ />,
47184
+ <div
47185
+ className="duffel-components"
47186
+ style={{}}
47187
+ >
47188
+ <div
47189
+ className="card-payment__container"
47190
+ >
47191
+ <form
47192
+ onSubmit={[Function]}
47193
+ >
47194
+ <div
47195
+ className="card-details"
47196
+ />
47197
+ <div
47198
+ className="card-payment__container--invalid"
47199
+ role="alert"
47200
+ />
47201
+ <button
47202
+ aria-label="Pay"
47203
+ className="button button--primary button--40 card-payment__pay-button"
47204
+ disabled={true}
47205
+ type="submit"
47206
+ >
47207
+ Pay
47208
+ </button>
47209
+ </form>
47210
+ </div>
47211
+ </div>,
47212
+ ]
47213
+ `;
47214
+
47215
+ exports[`Storyshots DuffelPayments With Custom Styles 1`] = `
47216
+ [
47217
+ <link
47218
+ href="/global.css"
47219
+ rel="stylesheet"
47220
+ />,
47221
+ <div
47222
+ className="duffel-components"
47223
+ style={
47224
+ {
47225
+ "--ACCENT": "29, 78, 216",
47226
+ "--BUTTON-RADIUS": "15px",
47227
+ "--FONT-FAMILY": "monospace",
47228
+ }
47229
+ }
47230
+ >
47231
+ <div
47232
+ className="card-payment__container"
47233
+ >
47234
+ <form
47235
+ onSubmit={[Function]}
47236
+ >
47237
+ <div
47238
+ className="card-details"
47239
+ />
47240
+ <div
47241
+ className="card-payment__container--invalid"
47242
+ role="alert"
47243
+ />
47244
+ <button
47245
+ aria-label="Pay"
47246
+ className="button button--primary button--40 card-payment__pay-button"
47247
+ disabled={true}
47248
+ type="submit"
47249
+ >
47250
+ Pay
47251
+ </button>
47252
+ </form>
47253
+ </div>
47254
+ </div>,
47255
+ ]
47256
+ `;
47257
+
47073
47258
  exports[`Storyshots Icon Full List 1`] = `
47074
47259
  <div
47075
47260
  style={
@@ -0,0 +1,83 @@
1
+ ## Debug mode
2
+
3
+ The component takes a `debug` boolean prop. When enabled, debug output is logged to the console, with useful info like the props that were passed in. This is intended both for our internal use and for users integrating it.
4
+
5
+ Debug mode is enabled by default in all of this repository's local environments (e.g. Storybook).
6
+
7
+ Debug mode makes use of a logger, which selectively outputs to the console based on whether or not debug mode is enabled. When it makes sense, make use of the logger to output useful information. See `@lib/logging` for how to use it.
8
+
9
+ ## How to upload new changes to our CDN
10
+
11
+ ### Setup `gcloud`
12
+
13
+ Our CDN is [hosted on Google Cloud Platform](<https://console.cloud.google.com/storage/browser/duffel-assets/components/ancillaries?pageState=(%22StorageObjectListTable%22:(%22f%22:%22%255B%255D%22))&project=duffel-prod-fda1bc52&prefix=&forceOnObjectsSortingFiltering=false>). To upload new changes you'll need to have `gcloud` intalled and authenticate with GCP. You can do this by running `gcloud auth login` and following the instructions.
14
+
15
+ ### Setup environment
16
+
17
+ Make sure you have an up-to-date version of `.env.build`:
18
+
19
+ ```sh
20
+ # .env.build
21
+
22
+ # Include the base url for the Duffel API.
23
+ # This variable is here to give us the ability to build a dist version that points to a local environment.
24
+ # If no value is provided, the default `https://api.duffel.com` will be used.
25
+ DUFFEL_API_URL=https://api.duffel.com
26
+
27
+ # This is needed so the component knows the url base to use for its stylesheet
28
+ # This variable is here so we can release component versions that may point to local environments or bypass the cache.
29
+ # If no value is provided, the default `https://assets.duffel.com/ancillaries-component` will be used.
30
+ COMPONENT_CDN=https://assets.duffel.com/components
31
+
32
+ # The auth token is so we send data
33
+ # to sentry during the build.
34
+ # This is helpful when CI is
35
+ # building releases, locally not as much.
36
+ # You can get it here: https://duffel.sentry.io/settings/account/api/auth-tokens
37
+ SENTRY_AUTH_TOKEN=
38
+ ```
39
+
40
+ ### Upload to CDN
41
+
42
+ To upload the latest version of the component to the CDN, run:
43
+
44
+ ```sh
45
+ yarn upload-to-cdn
46
+ ```
47
+
48
+ This command will:
49
+
50
+ 1. Build the component. the output will be in the `dist` folder.
51
+
52
+ 2. Upload the build to the version folder on GCP storage.
53
+
54
+ - The build version is defined in [`package.json`](/package.json) under the `version` attribute.
55
+ - [You can find uploaded versions here](<https://console.cloud.google.com/storage/browser/duffel-assets/components/ancillaries?pageState=(%22StorageObjectListTable%22:(%22f%22:%22%255B%255D%22))&project=duffel-prod-fda1bc52&prefix=&forceOnObjectsSortingFiltering=false>)
56
+ - A version folder will be created if it doesn't exist.
57
+ - The version folder will be overwritten if it already exists.
58
+
59
+ 3. Upload the sourcemaps for that version to Sentry
60
+
61
+ ### Build component
62
+
63
+ #### Build for CDN upload
64
+
65
+ ```sh
66
+ yarn cdn-build # Build will output to ./cdn-dist
67
+ ```
68
+
69
+ You can see this build referenced on:
70
+
71
+ - `src/examples/client-side`
72
+ - `src/examples/full-stack`
73
+
74
+ #### Build for npm publishing
75
+
76
+ ```sh
77
+ yarn react-build # Build will output to ./react-dist
78
+ ```
79
+
80
+ You can see this build referenced on:
81
+
82
+ - `src/examples/react-app`
83
+ - `src/examples/just-typescript`
package/README.md CHANGED
@@ -1,139 +1,64 @@
1
- # duffel-ancillaries
1
+ # @duffel/components
2
2
 
3
- ## What is this?
3
+ This package is a component library to help you build your travel product using the [Duffel API](https://duffel.com/docs).
4
4
 
5
- The ancillaries component is a JavaScript component you can use to allow your customers to add ancillaries to their order. It's simple to add to your website and can be customised to fit your brand.
5
+ ## Get started
6
6
 
7
- > [See live demo here](https://codesandbox.io/s/duffel-ancillaries-example-1nxuu7)
8
-
9
- ## How do I integrate this into my website?
10
-
11
- 1. Please start by reading our integration guide on https://duffel.com/docs/guides/ancillaries-component
12
- 2. You can also find examples code in the `example` folder (see below).
13
-
14
- ## Integration examples
15
-
16
- We have two ways to run the example.
17
-
18
- ### 1. Full stack
19
-
20
- This example has a server that will reach out to the Duffel API to search and retrieve an offer.
21
- To talk to the API we'll define the url to the API environment we want and .
22
- Please add the following to `.env.local`:
7
+ ### Installing
23
8
 
24
9
  ```sh
25
- # .env.local
26
-
27
- # Used to authenticate our
28
- # example server to talk to Duffel
29
- DUFFEL_API_TOKEN=test_duffel_dev_rw
30
-
31
- # The Duffel API environment we want
32
- # to talk. Remember to update the key
33
- # if this value changes.
34
- DUFFEL_API_URL=https://localhost:4000;
10
+ yarn add @duffel/components
11
+ # -- or --
12
+ npm i @duffel/components
35
13
  ```
36
14
 
37
- This is a 'real life' example, where it uses a real offer ID and client key retrieved from the Duffel API. To run this, use `yarn run-example:full-stack`. This command will:
38
-
39
- 1. Serve the Duffel component bundle and watch for changes to rebuild on port `8000`. This can also be done with `yarn dev`
40
- 2. Run the full stack server using node. The example page will be ready on port `6262`. This can be done with `yarn run-full-stack-server`
41
-
42
- ### What do I need to do to use the component with a local version of the Duffel API?
43
-
44
- - Make sure you visit https://localhost:4000 to allow your browser to make requests to it.
45
- - Make sure the org your are using has the [flags enabled](http://localhost:4242/features):
46
- - `ancillaries_component_enable_client_key`
47
- - `ancillaries_component_enable_client_key_endpoints`
48
-
49
- ### 2. Client side with fixtures
50
-
51
- For a more basic example that doesn't rely on the Duffel API, use `yarn run-example:client-side`.
52
-
53
- This command will:
15
+ ### (alternative) Load from CDN:
54
16
 
55
- 1. Serve the Duffel component bundle and watch for changes to rebuild on port `8000`. This can also be done with `yarn dev`
56
- 2. Host a basic `index.html` with `http-server`. The example page will be ready on port `6262`. This can be done with `yarn run-client-side-server`
17
+ ```html
18
+ <script src="https://assets.duffel.com/components/VERSION/duffel-ancillaries.js"></script>
19
+ <script src="https://assets.duffel.com/components/VERSION/duffel-payments.js"></script>
20
+ ```
57
21
 
58
- ## Debug mode
22
+ ## How do I integrate this into my website?
59
23
 
60
- The component takes a `debug` boolean prop. When enabled, debug output is logged to the console, with useful info like the props that were passed in. This is intended both for our internal use and for users integrating it.
24
+ 1. Please start by reading our integration guide on https://duffel.com/docs/guides/ancillaries-component
61
25
 
62
- Debug mode is enabled by default in all of this repository's local environments (e.g. Storybook).
26
+ ## Integration examples
63
27
 
64
- Debug mode makes use of a logger, which selectively outputs to the console based on whether or not debug mode is enabled. When it makes sense, make use of the logger to output useful information. See `@lib/logging` for how to use it.
28
+ 1. **client-side** | This example loads a local version of the components using a `script` tag. It uses a fixture for the offer and seat maps.
65
29
 
66
- ## How to upload new changes to our CDN
30
+ - [Find it on src/examples/client-side](src/examples/client-side)
67
31
 
68
- ### Setup `gcloud`
32
+ 2. **full-stack** | This example loads a local version of the components using a `script` tag. It will search and retrieve an offer from the Duffel API and render the ancillaries component custom element with its `offer_id` and `client_key`. As soon as a service modal is closed it will create a test order with the given payload.
69
33
 
70
- Our CDN is [hosted on Google Cloud Platform](<https://console.cloud.google.com/storage/browser/duffel-assets/components/ancillaries?pageState=(%22StorageObjectListTable%22:(%22f%22:%22%255B%255D%22))&project=duffel-prod-fda1bc52&prefix=&forceOnObjectsSortingFiltering=false>). To upload new changes you'll need to have `gcloud` intalled and authenticate with GCP. You can do this by running `gcloud auth login` and following the instructions.
34
+ - [Find it on src/examples/full-stack](src/examples/full-stack)
71
35
 
72
- ### Setup env variables under `.env.local`:
36
+ 3. **just-typescript** | This example imports a local version of `@duffel/components` and renders the custom element with an offer fixture once the page loads.
73
37
 
74
- Make sure you have an up-to-date version of `.env.build`
38
+ - [Find it on src/examples/just-typescript](src/examples/just-typescript)
75
39
 
76
- ```sh
77
- # .env.build
78
-
79
- # Include the base url for the Duffel API.
80
- # This variable is here to give us the ability to build a dist version that points to a local environment.
81
- # If no value is provided, the default `https://api.duffel.com` will be used.
82
- DUFFEL_API_URL=https://api.duffel.com
83
-
84
- # This is needed so the component knows the url base to use for its stylesheet
85
- # This variable is here so we can release component versions that may point to local environments or bypass the cache.
86
- # If no value is provided, the default `https://assets.duffel.com/ancillaries-component` will be used.
87
- COMPONENT_CDN=https://assets.duffel.com/components/ancillaries
88
-
89
- # The auth token is so we send data
90
- # to sentry during the build.
91
- # This is helpful when CI is
92
- # building releases, locally not as much.
93
- # You can get it here: https://duffel.sentry.io/settings/account/api/auth-tokens
94
- SENTRY_AUTH_TOKEN=
95
- ```
96
-
97
- ### Upload to CDN
40
+ 4. **react-app** | This example imports a local version of `@duffel/components` and renders the a react element with an offer fixture.
98
41
 
99
- To upload the latest version of the component to the CDN, run:
42
+ - [Find it on src/examples/react-app](src/examples/react-app)
100
43
 
101
- ```sh
102
- yarn upload-to-cdn
103
- ```
44
+ 5. **payments-custom-element** | This example demonstrates the use of the payments component loaded through a script tag
104
45
 
105
- This command will:
46
+ - [Find it on src/examples/payments-custom-element](src/examples/payments-custom-element)
106
47
 
107
- 1. Build the component. the output will be in the `dist` folder.
48
+ 6. **payments-just-typescript** | This example imports a local version of `@duffel/components` and renders the payments custom element with a fixture of the payment intent.
108
49
 
109
- 2. Upload the build to the version folder on GCP storage.
50
+ - [Find it on src/examples/payments-just-typescript](src/examples/payments-just-typescript)
110
51
 
111
- - The build version is defined in [`package.json`](/package.json) under the `version` attribute.
112
- - [You can find uploaded versions here](<https://console.cloud.google.com/storage/browser/duffel-assets/components/ancillaries?pageState=(%22StorageObjectListTable%22:(%22f%22:%22%255B%255D%22))&project=duffel-prod-fda1bc52&prefix=&forceOnObjectsSortingFiltering=false>)
113
- - A version folder will be created if it doesn't exist.
114
- - The version folder will be overwritten if it already exists.
52
+ ## What components are available?
115
53
 
116
- 3. Upload the sourcemaps for that version to Sentry
54
+ ### Ancillaries component
117
55
 
118
- ### Build component
56
+ The ancillaries component allows your customers to add ancillaries to their order. It's simple to add to your website and can be customised to fit your brand. This component is avaiable through npm and our cdn.
119
57
 
120
- #### Build html custom element
58
+ - [Find live demo on codesandbox.io&nbsp;&nbsp;↗](https://codesandbox.io/s/duffel-ancillaries-example-1nxuu7)
121
59
 
122
- ```sh
123
- yarn cdn-build # Build will output to ./cdn-dist
124
- ```
125
-
126
- You can see this build referenced on:
127
-
128
- - `src/examples/client-side`
129
- - `src/examples/full-stack`
130
-
131
- #### Build react component
132
-
133
- ```sh
134
- yarn react-build # Build will output to ./react-dist
135
- ```
60
+ ### Payments component
136
61
 
137
- You can see this build referenced on:
62
+ The payments component provides a [PCI-compliant](https://help.duffel.com/hc/en-gb/articles/4409049543058) way for you to collect card payments for online bookings from your customers. To learn more about how to work with Duffel payments please visit the [Collecting customer card payments guide](https://duffel.com/docs/guides/collecting-customer-card-payments).
138
63
 
139
- - `src/examples/react-app`
64
+ #### more coming soon...
@@ -1,8 +1,12 @@
1
1
  module.exports = {
2
2
  entryPoints: [
3
3
  {
4
- out: "index",
5
- in: "src/components/DuffelAncillariesCustomElement.tsx",
4
+ out: "duffel-ancillaries",
5
+ in: "src/components/DuffelAncillaries/DuffelAncillariesCustomElement.tsx",
6
+ },
7
+ {
8
+ out: "duffel-payments",
9
+ in: "src/components/DuffelPayments/DuffelPaymentsCustomElement.tsx",
6
10
  },
7
11
  { out: "global", in: "src/styles/global.css" },
8
12
  ],
@@ -10,5 +14,5 @@ module.exports = {
10
14
  minify: true,
11
15
  sourcemap: true,
12
16
  treeShaking: true,
13
- outdir: "dist/ancillaries",
17
+ outdir: "cdn-dist",
14
18
  };
@@ -6,6 +6,7 @@ const esbuildCopyStaticFiles = require("esbuild-copy-static-files");
6
6
 
7
7
  dotenv.config({ path: ".env.build" });
8
8
  if (process.env.SENTRY_AUTH_TOKEN === undefined) {
9
+ // eslint-disable-next-line
9
10
  console.error(
10
11
  "'process.env.SENTRY_AUTH_TOKEN' is required but missing." +
11
12
  "Make sure it's included in your .env.build file."
@@ -34,14 +35,14 @@ esbuild
34
35
  org: "duffel",
35
36
  project: "ancillaries-component",
36
37
  // Specify the directory containing build artifacts
37
- include: "./dist",
38
+ include: "./cdn-dist",
38
39
  authToken: process.env.SENTRY_AUTH_TOKEN,
39
40
  logLevel: "info",
40
- release: `element-${VERSION}`,
41
+ release: VERSION,
41
42
  }),
42
43
  esbuildCopyStaticFiles({
43
44
  src: "src/fixtures",
44
- dest: "dist/ancillaries/fixtures",
45
+ dest: "cdn-dist/fixtures",
45
46
  dereference: true,
46
47
  recursive: true,
47
48
  }),