@icij/murmur-next 4.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 (296) hide show
  1. package/.github/workflows/deploy-github-pages.yaml +50 -0
  2. package/.storybook/app.scss +14 -0
  3. package/.storybook/doc_variables.scss +20 -0
  4. package/.storybook/main.ts +35 -0
  5. package/.storybook/preview-head.html +2 -0
  6. package/.storybook/preview.ts +32 -0
  7. package/README.md +71 -0
  8. package/deploy.js +15 -0
  9. package/docs/components/ApiTable.vue +171 -0
  10. package/docs/components/App.vue +146 -0
  11. package/docs/components/CollapsibleBlock.vue +122 -0
  12. package/docs/components/DocsHeader.vue +68 -0
  13. package/docs/components/DocsMenu.vue +201 -0
  14. package/docs/components/DocsMenuSection.vue +109 -0
  15. package/docs/components/EditLink.vue +49 -0
  16. package/docs/components/OutboundLink.vue +13 -0
  17. package/docs/components/PalettePresenter.vue +96 -0
  18. package/docs/components/RepositoryLink.vue +28 -0
  19. package/docs/components/SampleCard.vue +119 -0
  20. package/docs/main.js +42 -0
  21. package/docs/pages/components/accordion/doc.md +96 -0
  22. package/docs/pages/components/active-text-truncate/doc.md +44 -0
  23. package/docs/pages/components/advanced-link-form/doc.md +105 -0
  24. package/docs/pages/components/brand/doc.md +30 -0
  25. package/docs/pages/components/brand-expansion/doc.md +70 -0
  26. package/docs/pages/components/confirm-button/doc.md +91 -0
  27. package/docs/pages/components/content-placeholder/doc.md +16 -0
  28. package/docs/pages/components/custom-pagination/doc.md +61 -0
  29. package/docs/pages/components/digits-input/doc.md +28 -0
  30. package/docs/pages/components/donate-form/doc.md +20 -0
  31. package/docs/pages/components/embed-form/doc.md +22 -0
  32. package/docs/pages/components/embeddable-footer/doc.md +60 -0
  33. package/docs/pages/components/follow-us-popover/doc.md +5 -0
  34. package/docs/pages/components/generic-footer/doc.md +21 -0
  35. package/docs/pages/components/generic-header/doc.md +24 -0
  36. package/docs/pages/components/haptic-copy/doc.md +27 -0
  37. package/docs/pages/components/imddb-header/doc.md +23 -0
  38. package/docs/pages/components/ordinal-legend/doc.md +44 -0
  39. package/docs/pages/components/range-picker/doc.md +86 -0
  40. package/docs/pages/components/responsive-iframe/doc.md +13 -0
  41. package/docs/pages/components/scale-legend/doc.md +65 -0
  42. package/docs/pages/components/secret-input/doc.md +12 -0
  43. package/docs/pages/components/selectable-dropdown/doc.md +156 -0
  44. package/docs/pages/components/sharing-options/doc.md +13 -0
  45. package/docs/pages/components/sharing-options-link/doc.md +36 -0
  46. package/docs/pages/components/sign-up-form/doc.md +13 -0
  47. package/docs/pages/components/slide-up-down/doc.md +28 -0
  48. package/docs/pages/components/textured-deck/doc.md +78 -0
  49. package/docs/pages/components/tiny-pagination/doc.md +92 -0
  50. package/docs/pages/datavisualisation/bars/doc.md +110 -0
  51. package/docs/pages/datavisualisation/columns/doc.md +165 -0
  52. package/docs/pages/datavisualisation/lines/doc.md +139 -0
  53. package/docs/pages/datavisualisation/stacked-bar/doc.md +160 -0
  54. package/docs/pages/datavisualisation/stacked-column/doc.md +191 -0
  55. package/docs/pages/getting-started/about-icij/doc.md +13 -0
  56. package/docs/pages/getting-started/custom-bootstrap/doc.md +36 -0
  57. package/docs/pages/getting-started/installation-guide/doc.md +59 -0
  58. package/docs/pages/getting-started/internationalization/doc.md +74 -0
  59. package/docs/pages/maps/choropleth-map/doc.md +420 -0
  60. package/docs/pages/maps/choropleth-map-annotation/doc.md +373 -0
  61. package/docs/pages/maps/symbol-map/doc.md +203 -0
  62. package/docs/pages/structure/breakpoints/doc.md +3 -0
  63. package/docs/pages/structure/grid/doc.md +3 -0
  64. package/docs/pages/utilities/assets/doc.md +138 -0
  65. package/docs/pages/utilities/config/doc.md +52 -0
  66. package/docs/pages/utilities/iframes/doc.md +3 -0
  67. package/docs/pages/visual/colors/doc.md +31 -0
  68. package/docs/pages/visual/iconography/doc.md +56 -0
  69. package/docs/pages/visual/states/doc.md +77 -0
  70. package/docs/pages/visual/themes/doc.md +3 -0
  71. package/docs/pages/visual/typography/doc.md +71 -0
  72. package/docs/routes.js +25 -0
  73. package/docs/store/index.js +21 -0
  74. package/docs/styles/app.scss +36 -0
  75. package/docs/styles/variables.scss +20 -0
  76. package/lib/assets/images/icij-full-white.svg +6 -0
  77. package/lib/assets/images/icij-full.svg +6 -0
  78. package/lib/assets/images/icij.png +0 -0
  79. package/lib/assets/images/icij.svg +46 -0
  80. package/lib/assets/images/icij@2x.png +0 -0
  81. package/lib/assets/images/murmur-dark.png +0 -0
  82. package/lib/assets/images/murmur-dark.svg +79 -0
  83. package/lib/assets/images/murmur-white.png +0 -0
  84. package/lib/assets/images/murmur-white.svg +68 -0
  85. package/lib/components/AccordionStep.vue +128 -0
  86. package/lib/components/AccordionWrapper.vue +138 -0
  87. package/lib/components/ActiveTextTruncate.vue +258 -0
  88. package/lib/components/AdvancedLinkForm.vue +273 -0
  89. package/lib/components/Brand.vue +150 -0
  90. package/lib/components/BrandExpansion.vue +237 -0
  91. package/lib/components/ConfirmButton.vue +204 -0
  92. package/lib/components/ContentPlaceholder.vue +100 -0
  93. package/lib/components/CustomPagination.vue +225 -0
  94. package/lib/components/DigitsInput.vue +180 -0
  95. package/lib/components/DonateForm.vue +367 -0
  96. package/lib/components/EmbedForm.vue +173 -0
  97. package/lib/components/EmbeddableFooter.vue +201 -0
  98. package/lib/components/Fa.js +3 -0
  99. package/lib/components/FollowUsPopover.vue +117 -0
  100. package/lib/components/GenericFooter.vue +218 -0
  101. package/lib/components/GenericHeader.vue +259 -0
  102. package/lib/components/HapticCopy.vue +256 -0
  103. package/lib/components/ImddbHeader.vue +336 -0
  104. package/lib/components/OrdinalLegend.vue +164 -0
  105. package/lib/components/RangePicker.vue +430 -0
  106. package/lib/components/ResponsiveIframe.vue +48 -0
  107. package/lib/components/ScaleLegend.vue +230 -0
  108. package/lib/components/SecretInput.vue +132 -0
  109. package/lib/components/SelectableDropdown.vue +368 -0
  110. package/lib/components/SharingOptions.vue +230 -0
  111. package/lib/components/SharingOptionsLink.vue +259 -0
  112. package/lib/components/SignUpForm.vue +181 -0
  113. package/lib/components/SlideUpDown.vue +131 -0
  114. package/lib/components/TexturedDeck.vue +101 -0
  115. package/lib/components/TinyPagination.vue +268 -0
  116. package/lib/components/index.js +31 -0
  117. package/lib/composables/chart.ts +182 -0
  118. package/lib/composables/resizeObserver.ts +37 -0
  119. package/lib/composables/sendEmail.ts +50 -0
  120. package/lib/config.default.ts +33 -0
  121. package/lib/config.ts +70 -0
  122. package/lib/d3-geo-projection.d.ts +1 -0
  123. package/lib/datavisualisations/BarChart.vue +275 -0
  124. package/lib/datavisualisations/ColumnChart.vue +527 -0
  125. package/lib/datavisualisations/LineChart.vue +274 -0
  126. package/lib/datavisualisations/StackedBarChart.vue +614 -0
  127. package/lib/datavisualisations/StackedColumnChart.vue +640 -0
  128. package/lib/datavisualisations/index.js +5 -0
  129. package/lib/enums.ts +25 -0
  130. package/lib/i18n.ts +16 -0
  131. package/lib/keys.ts +2 -0
  132. package/lib/locales/en.json +140 -0
  133. package/lib/locales/fr.json +117 -0
  134. package/lib/locales/locales/en.json +140 -0
  135. package/lib/locales/locales/fr.json +117 -0
  136. package/lib/main.ts +87 -0
  137. package/lib/maps/ChoroplethMap.vue +825 -0
  138. package/lib/maps/ChoroplethMapAnnotation.vue +336 -0
  139. package/lib/maps/SymbolMap.vue +628 -0
  140. package/lib/maps/index.js +3 -0
  141. package/lib/querystring-es3.d.ts +1 -0
  142. package/lib/shims-bootstrap-vue.d.ts +5 -0
  143. package/lib/shims-tsx.d.ts +11 -0
  144. package/lib/shims-vue.d.ts +14 -0
  145. package/lib/styles/functions.scss +20 -0
  146. package/lib/styles/lib.scss +19 -0
  147. package/lib/styles/mixins.scss +37 -0
  148. package/lib/styles/utilities.scss +18 -0
  149. package/lib/styles/variables.scss +94 -0
  150. package/lib/styles/variables_dark.scss +1 -0
  151. package/lib/types.ts +46 -0
  152. package/lib/utils/animation.ts +24 -0
  153. package/lib/utils/assets.ts +46 -0
  154. package/lib/utils/clipboard.ts +41 -0
  155. package/lib/utils/iframe-resizer.ts +49 -0
  156. package/lib/utils/placeholder.ts +66 -0
  157. package/lib/utils/placeholderTypes.ts +21 -0
  158. package/lib/utils/strings.ts +8 -0
  159. package/loaders/highlight-loader.js +13 -0
  160. package/loaders/markdown-loader.js +91 -0
  161. package/loaders/metadata-loader.js +18 -0
  162. package/loaders/sass-extract-loader.js +14 -0
  163. package/loaders/vue-docgen-loader.js +14 -0
  164. package/package.json +96 -0
  165. package/plugins/MdPluginTypes.ts +10 -0
  166. package/plugins/docs.ts +50 -0
  167. package/plugins/front-matter.ts +36 -0
  168. package/plugins/highlight.ts +27 -0
  169. package/plugins/markdown-it/api-table.ts +25 -0
  170. package/plugins/markdown-it/sample-card.ts +31 -0
  171. package/plugins/plugin-delete.ts +47 -0
  172. package/plugins/plugin-docgen.ts +23 -0
  173. package/plugins/sass-vars.ts +25 -0
  174. package/plugins/vue-docgen.ts +29 -0
  175. package/public/android-chrome-192x192.png +0 -0
  176. package/public/android-chrome-512x512.png +0 -0
  177. package/public/apple-touch-icon.png +0 -0
  178. package/public/assets/img/arrow-bottom.svg +3 -0
  179. package/public/assets/img/texture-brick-black.jpg +0 -0
  180. package/public/assets/img/texture-brick.jpg +0 -0
  181. package/public/assets/img/texture-carbon-black.jpg +0 -0
  182. package/public/assets/img/texture-carbon.jpg +0 -0
  183. package/public/assets/img/texture-crack-black.jpg +0 -0
  184. package/public/assets/img/texture-crack.jpg +0 -0
  185. package/public/assets/img/texture-rock-black.jpg +0 -0
  186. package/public/assets/img/texture-rock.jpg +0 -0
  187. package/public/assets/img/texture-sand-black.jpg +0 -0
  188. package/public/assets/img/texture-sand.jpg +0 -0
  189. package/public/assets/img/texture-silk-black.jpg +0 -0
  190. package/public/assets/img/texture-silk.jpg +0 -0
  191. package/public/assets/topojson/france-departments.json +1 -0
  192. package/public/assets/topojson/paris-arrondissements.json +1 -0
  193. package/public/assets/topojson/world-countries-sans-antarctica.json +1 -0
  194. package/public/favicon-16x16.png +0 -0
  195. package/public/favicon-32x32.png +0 -0
  196. package/public/favicon.ico +0 -0
  197. package/public/site.webmanifest +1 -0
  198. package/stories/assets/code-brackets.svg +1 -0
  199. package/stories/assets/colors.svg +1 -0
  200. package/stories/assets/comments.svg +1 -0
  201. package/stories/assets/direction.svg +1 -0
  202. package/stories/assets/flow.svg +1 -0
  203. package/stories/assets/plugin.svg +1 -0
  204. package/stories/assets/repo.svg +1 -0
  205. package/stories/assets/stackalt.svg +1 -0
  206. package/stories/getting-started/about-icij.mdx +14 -0
  207. package/stories/getting-started/custom-bootstrap.mdx +23 -0
  208. package/stories/getting-started/installation-guide.mdx +62 -0
  209. package/stories/getting-started/internationalization.mdx +63 -0
  210. package/stories/murmur/components/AccordionStep.stories.ts +33 -0
  211. package/stories/murmur/components/AccordionWrapper.stories.ts +69 -0
  212. package/stories/murmur/components/ActiveTextTruncate.stories.ts +32 -0
  213. package/stories/murmur/components/AdvancedLinkForm.stories.ts +77 -0
  214. package/stories/murmur/components/Brand.stories.ts +30 -0
  215. package/stories/murmur/components/BrandExpansion.stories.ts +41 -0
  216. package/stories/murmur/components/ConfirmButton.stories.ts +40 -0
  217. package/stories/murmur/components/ContentPlaceholder.stories.ts +41 -0
  218. package/stories/murmur/components/CustomPagination.stories.ts +42 -0
  219. package/stories/murmur/components/DigitsInput.stories.ts +29 -0
  220. package/stories/murmur/components/DonateForm.stories.ts +29 -0
  221. package/stories/murmur/components/EmbedForm.stories.ts +35 -0
  222. package/stories/murmur/components/EmbeddableFooter.stories.ts +59 -0
  223. package/stories/murmur/components/FollowUsPopover.stories.ts +24 -0
  224. package/stories/murmur/components/GenericFooter.stories.ts +27 -0
  225. package/stories/murmur/components/GenericHeader.stories.ts +27 -0
  226. package/stories/murmur/components/HapticCopy.stories.ts +40 -0
  227. package/stories/murmur/components/ImddbHeader.stories.ts +27 -0
  228. package/stories/murmur/components/OrdinalLegend.stories.ts +49 -0
  229. package/stories/murmur/components/RangePicker.stories.ts +98 -0
  230. package/stories/murmur/components/ResponsiveIframe.stories.ts +24 -0
  231. package/stories/murmur/components/ScaleLegend.stories.ts +65 -0
  232. package/stories/murmur/components/SecretInput.stories.ts +60 -0
  233. package/stories/murmur/components/SelectableDropdown.stories.ts +143 -0
  234. package/stories/murmur/components/SharingOptions.stories.ts +32 -0
  235. package/stories/murmur/components/SharingOptionsLink.stories.ts +53 -0
  236. package/stories/murmur/components/SignUpForm.stories.ts +51 -0
  237. package/stories/murmur/components/SlideUpDown.stories.ts +32 -0
  238. package/stories/murmur/components/TexturedDeck.stories.ts +83 -0
  239. package/stories/murmur/components/TinyPagination.stories.ts +65 -0
  240. package/stories/murmur/datavisualisations/BarChart.stories.ts +54 -0
  241. package/stories/murmur/datavisualisations/ColumnChart.stories.ts +88 -0
  242. package/stories/murmur/datavisualisations/LineChart.stories.ts +139 -0
  243. package/stories/murmur/datavisualisations/StackedBarChart.stories.ts +199 -0
  244. package/stories/murmur/datavisualisations/StackedColumnChart.stories.ts +136 -0
  245. package/stories/murmur/decorators.ts +108 -0
  246. package/stories/murmur/maps/ChoroplethMap.stories.ts +440 -0
  247. package/stories/murmur/maps/ChoroplethMapAnnotation.stories.ts +26 -0
  248. package/stories/murmur/maps/SymbolMap.stories.ts +24 -0
  249. package/stories/murmur/utils.ts +7 -0
  250. package/tests/unit/components/AccordionStep.spec.ts +157 -0
  251. package/tests/unit/components/AccordionWrapper.spec.ts +57 -0
  252. package/tests/unit/components/ActiveTextTruncate.spec.js +30 -0
  253. package/tests/unit/components/AdvancedLinkForm.spec.js +124 -0
  254. package/tests/unit/components/Brand.spec.js +50 -0
  255. package/tests/unit/components/ContentPlaceholder.spec.js +29 -0
  256. package/tests/unit/components/CustomPagination.spec.js +72 -0
  257. package/tests/unit/components/DigitsInput.spec.ts +157 -0
  258. package/tests/unit/components/DonateForm.spec.js +149 -0
  259. package/tests/unit/components/EmbedForm.spec.js +108 -0
  260. package/tests/unit/components/EmbeddableFooter.spec.js +11 -0
  261. package/tests/unit/components/Fa.spec.js +18 -0
  262. package/tests/unit/components/FollowUsPopover.spec.js +29 -0
  263. package/tests/unit/components/GenericFooter.spec.js +29 -0
  264. package/tests/unit/components/GenericHeader.spec.js +104 -0
  265. package/tests/unit/components/HapticCopy.spec.js +123 -0
  266. package/tests/unit/components/ImddbHeader.spec.js +96 -0
  267. package/tests/unit/components/OrdinalLegend.spec.js +120 -0
  268. package/tests/unit/components/RangePicker.spec.ts +87 -0
  269. package/tests/unit/components/ResponsiveIframe.spec.js +20 -0
  270. package/tests/unit/components/ScaleLegend.spec.js +139 -0
  271. package/tests/unit/components/SecretInput.spec.js +81 -0
  272. package/tests/unit/components/SelectableDropdown.spec.js +160 -0
  273. package/tests/unit/components/SharingOptions.spec.js +125 -0
  274. package/tests/unit/components/SharingOptionsLink.spec.js +184 -0
  275. package/tests/unit/components/SignUpForm.spec.js +145 -0
  276. package/tests/unit/components/SlideUpDown.spec.js +59 -0
  277. package/tests/unit/components/TinyPagination.spec.js +46 -0
  278. package/tests/unit/config.spec.js +136 -0
  279. package/tests/unit/datavisualisations/BarChart.spec.js +63 -0
  280. package/tests/unit/datavisualisations/ColumnChart.spec.js +344 -0
  281. package/tests/unit/datavisualisations/LineChart.spec.js +155 -0
  282. package/tests/unit/datavisualisations/StackedBarChart.spec.js +294 -0
  283. package/tests/unit/datavisualisations/StackedColumnChart.spec.js +443 -0
  284. package/tests/unit/i18n.spec.ts +19 -0
  285. package/tests/unit/main.spec.js +82 -0
  286. package/tests/unit/maps/ChoroplethMap.spec.js +214 -0
  287. package/tests/unit/maps/ChoroplethMapAnnotation.spec.ts +186 -0
  288. package/tests/unit/maps/SymbolMap.spec.js +92 -0
  289. package/tests/unit/require.spec.js +22 -0
  290. package/tests/unit/setup.js +13 -0
  291. package/tests/unit/utils/assets.spec.js +61 -0
  292. package/tests/unit/utils/clipboard.spec.js +18 -0
  293. package/tests/unit/utils/iframe-resizer.spec.js +71 -0
  294. package/tsconfig.json +35 -0
  295. package/vite.config.ts +79 -0
  296. package/vitest.config.ts +19 -0
@@ -0,0 +1,367 @@
1
+ <script>
2
+ import keys from 'lodash/keys'
3
+ import map from 'lodash/map'
4
+ import sortBy from 'lodash/sortBy'
5
+ import forEach from 'lodash/forEach'
6
+
7
+ import config from '../config'
8
+ import {useI18n} from "vue-i18n";
9
+ import {computed, ref, watch} from "vue";
10
+
11
+ /**
12
+ * A form to encourage donations. We usually put this form inside a modal
13
+ */
14
+ export default {
15
+ name: 'DonateForm',
16
+ props: {
17
+ /**
18
+ * Title of the form.
19
+ */
20
+ noTitle: {
21
+ type: Boolean
22
+ }
23
+ },
24
+ setup(){
25
+ const {t, locale, messages} = useI18n()
26
+ const amount = ref(10)
27
+ // True if the amount wasn't changed by the user yet
28
+ const amountIsPristine = ref(true)
29
+ const installmentPeriod = ref('monthly')
30
+ const level = ref('conversation')
31
+ const campaign = ref(config.get('donate-form.tracker'))
32
+ const labelForChange = ref({
33
+ monthly: {
34
+ 1: t('donate-form.result.conversation'),
35
+ 15: t('donate-form.result.rules'),
36
+ 50: t('donate-form.result.world')
37
+ },
38
+ yearly: {
39
+ 1: t('donate-form.result.conversation'),
40
+ 180: t('donate-form.result.rules'),
41
+ 600: t('donate-form.result.world')
42
+ }
43
+ })
44
+
45
+ const suggestedAmount = ref(messages.value[locale.value]['donate-form']["suggesteddonation"])
46
+ const listBenefits = ref(messages.value[locale.value]['donate-form']["benefits"]["list"])
47
+ const ranges = computed(()=> {
48
+ if(installmentPeriod.value==='onetime'){
49
+ return labelForChange.value['yearly']
50
+ }
51
+ return labelForChange.value[installmentPeriod.value]
52
+ })
53
+ const firstRange = computed(()=> {
54
+ const key = keys(ranges.value)[0]
55
+ return ranges.value[key]
56
+ })
57
+ const changeThe = computed(()=> {
58
+ // Final label
59
+ let label = null
60
+ forEach(sortBy(map(keys(ranges.value), Number)), (amountV) => {
61
+ label = amount.value >= amountV ? ranges.value[amountV] : label
62
+ })
63
+ return label
64
+ }
65
+
66
+ )
67
+ watch(installmentPeriod,() => {
68
+ if (!amountIsPristine.value) {
69
+ return
70
+ }
71
+
72
+ // Set suggested amount
73
+ amount.value = getSuggestedAmount()
74
+ })
75
+ watch(()=>amount.value,(v) => {
76
+ level.value = changeThe.value
77
+
78
+ // Set manual amount
79
+ return (amount.value = v)
80
+ }
81
+ )
82
+ function getSuggestedAmount() {
83
+ if (!amountIsPristine.value) {
84
+ return
85
+ }
86
+
87
+ if (!level.value) {
88
+ level.value = firstRange.value
89
+ }
90
+
91
+ // Return suggested amount
92
+ return suggestedAmount.value[level.value][installmentPeriod.value]
93
+ }
94
+ function selectLevel(levelSelected) {
95
+ // Set chose level
96
+ level.value = levelSelected
97
+
98
+ // Set suggested amount
99
+ amount.value = getSuggestedAmount()
100
+ }
101
+ function amountIsNotPristine(){
102
+ amountIsPristine.value = false
103
+ }
104
+
105
+ return {
106
+ t,
107
+ amount,
108
+ level,
109
+ campaign,
110
+ labelForChange,
111
+ installmentPeriod,
112
+ changeThe,
113
+ listBenefits,
114
+ selectLevel,
115
+ amountIsNotPristine
116
+ }
117
+
118
+ },
119
+
120
+ }
121
+ </script>
122
+
123
+ <template>
124
+ <div class="donate-form container-fluid py-2">
125
+ <h2 v-if="!noTitle" class="donate-form__title text-uppercase fw-bold text-primary h5">
126
+ {{ t('donate-form.support') }}
127
+ </h2>
128
+ <!-- @slot Description of the form (bellow the title). -->
129
+ <slot name="introduction">
130
+ <!-- eslint-disable vue/no-v-html -->
131
+ <p class="donate-form__introduction" v-html="t('donate-form.introduction')" />
132
+ <!-- eslint-enable -->
133
+ </slot>
134
+
135
+ <div class="donate-form__payment mb-4 text-center">
136
+ <form
137
+ action="//checkout.fundjournalism.org/memberform"
138
+ method="get"
139
+ target="_blank"
140
+ class="donate-form__payment__form bg-light p-4"
141
+ >
142
+ <div class="donate-form__payment__levels row">
143
+ <div
144
+ class="col donate-form__payment__level"
145
+ :class="{ active: level === 'conversation' }"
146
+ @click="selectLevel('conversation')"
147
+ >
148
+ <h3 class="donate-form__payment__heading text-uppercase fw-bold text-primary h5">
149
+ {{ t('donate-form.benefits.impacts.conversation.heading') }}
150
+ </h3>
151
+ <div class="Article">
152
+ <div>
153
+ <!-- eslint-disable vue/no-v-html -->
154
+ <p
155
+ class="donate-form__payment__highlight text-icij fw-bold"
156
+ v-html="t('donate-form.benefits.impacts.conversation.highlight')"
157
+ />
158
+ <!-- eslint-enable -->
159
+ </div>
160
+ </div>
161
+ </div>
162
+ <div
163
+ class="col donate-form__payment__level"
164
+ :class="{ active: level === 'rules' }"
165
+ @click="selectLevel('rules')"
166
+ >
167
+ <h3 class="donate-form__payment__heading text-uppercase fw-bold text-primary h5">
168
+ {{ t('donate-form.benefits.impacts.rules.heading') }}
169
+ </h3>
170
+ <div class="Article">
171
+ <div>
172
+ <!-- eslint-disable vue/no-v-html -->
173
+ <p
174
+ class="donate-form__payment__highlight text-icij fw-bold"
175
+ v-html="t('donate-form.benefits.impacts.rules.highlight')"
176
+ />
177
+ <!-- eslint-enable -->
178
+ </div>
179
+ </div>
180
+ </div>
181
+ <div
182
+ class="col donate-form__payment__level"
183
+ :class="{ active: level === 'world' }"
184
+ @click="selectLevel('world')"
185
+ >
186
+ <h3 class="donate-form__payment__heading text-uppercase fw-bold text-primary h5">
187
+ {{ t('donate-form.benefits.impacts.world.heading') }}
188
+ </h3>
189
+ <div class="Article">
190
+ <div>
191
+ <!-- eslint-disable vue/no-v-html -->
192
+ <p
193
+ class="donate-form__payment__highlight text-icij fw-bold"
194
+ v-html="t('donate-form.benefits.impacts.world.highlight')"
195
+ />
196
+ <!-- eslint-enable -->
197
+ </div>
198
+ </div>
199
+ </div>
200
+ </div>
201
+
202
+ <div>
203
+ <div class="mt-5">
204
+ <span class="donate-form__payment__buttons">
205
+ <button
206
+ type="button"
207
+ class="btn btn-sm frequency-monthly"
208
+ :class="{ 'btn-primary': installmentPeriod === 'monthly' }"
209
+ @click="installmentPeriod = 'monthly'"
210
+ >
211
+ {{ t('donate-form.frequency.monthly') }}
212
+ </button>
213
+ <button
214
+ type="button"
215
+ class="btn btn-sm frequency-yearly"
216
+ :class="{ 'btn-primary': installmentPeriod === 'yearly' }"
217
+ @click="installmentPeriod = 'yearly'"
218
+ >
219
+ {{ t('donate-form.frequency.yearly') }}
220
+ </button>
221
+ <button
222
+ type="button"
223
+ class="btn btn-sm frequency-onetime"
224
+ :class="{ 'btn-primary': installmentPeriod === null }"
225
+ @click="installmentPeriod = 'onetime'"
226
+ >
227
+ {{ t('donate-form.frequency.onetime') }}
228
+ </button>
229
+ </span>
230
+ </div>
231
+ <div class="mt-4">
232
+ <span>{{ t('donate-form.label') }}&nbsp;</span>
233
+ <label class="donate-form__payment__unit input-group input-group-sm d-inline-flex">
234
+ <span class="input-group-prepend">
235
+ <span class="input-group-text">$</span>
236
+ </span>
237
+ <input
238
+ v-model="amount"
239
+ class="donate-form__payment__input form-control"
240
+ name="amount"
241
+ type="number"
242
+ min="0"
243
+ @change="amountIsNotPristine"
244
+ />
245
+ </label>
246
+ </div>
247
+ <div class="mt-4">
248
+ <input name="org_id" value="icij" type="hidden" />
249
+ <input v-model="campaign" name="campaign" type="hidden" />
250
+ <input v-model="installmentPeriod" name="installmentPeriod" type="hidden" />
251
+ <button type="submit" class="btn btn-primary rounded-pill text-uppercase fw-bold">
252
+ {{ t('donate-form.submit') }}
253
+ </button>
254
+ <a target="_blank" href="https://icij.org/donate" class="donate-form__payment__image" />
255
+ </div>
256
+ </div>
257
+ </form>
258
+ </div>
259
+
260
+ <div class="donate-form__insider">
261
+ <h2 class="donate-form__insider__title">
262
+ {{ t('donate-form.benefits.heading') }}
263
+ </h2>
264
+ <p>
265
+ {{ t('donate-form.benefits.introduction') }}
266
+ </p>
267
+ <div>
268
+ <ul class="donate-form__insider__list">
269
+ <li
270
+ v-for="(benefit, index) in listBenefits"
271
+ :key="index"
272
+ class="donate-form__insider__list-item"
273
+ v-html="benefit"
274
+ />
275
+ </ul>
276
+ </div>
277
+ <div>
278
+ <hr class="donate-form__insider__separator" />
279
+ <div class="donate-form__insider__more text-center">
280
+ <a
281
+ target="_blank"
282
+ href="https://icij.org/donate"
283
+ class="btn btn-primary rounded-pill text-uppercase fw-bold py-2"
284
+ >
285
+ {{ t('donate-form.benefits.more') }}
286
+ </a>
287
+ </div>
288
+ </div>
289
+ </div>
290
+ </div>
291
+ </template>
292
+
293
+ <style lang="scss">
294
+ @import '../styles/lib';
295
+
296
+ .donate-form {
297
+ font-size: 0.9rem;
298
+
299
+ &__payment {
300
+ & &__unit {
301
+ width: 120px;
302
+ margin-right: $spacer;
303
+
304
+ @media screen and (max-width: $modal-lg) {
305
+ width: 100%;
306
+ flex: 0 0 100%;
307
+ }
308
+ }
309
+
310
+ &__buttons {
311
+ button {
312
+ margin: 0 5px;
313
+ border: solid 1px var(--primary);
314
+ }
315
+ }
316
+
317
+ &__level {
318
+ border-bottom: solid 3px $light;
319
+ cursor: pointer;
320
+
321
+ &.active {
322
+ border-bottom: solid 3px var(--primary);
323
+ }
324
+ }
325
+
326
+ &__highlight {
327
+ font-size: 17px;
328
+
329
+ .monthly {
330
+ display: block;
331
+ font-size: 14px;
332
+ font-weight: 400;
333
+ }
334
+ }
335
+ }
336
+
337
+ &__insider {
338
+ &__list {
339
+ padding-left: 20px;
340
+
341
+ &-item {
342
+ position: relative;
343
+ margin: 3px 0;
344
+ font-size: 15px;
345
+ list-style: none;
346
+
347
+ &:before {
348
+ content: '\2713';
349
+ position: absolute;
350
+ left: -16px;
351
+ font-size: 14px;
352
+ font-weight: 700;
353
+ color: #333;
354
+ font-family: $font-family-sans-serif;
355
+ }
356
+ }
357
+ }
358
+
359
+ &__modal__container .col {
360
+ @media screen and (max-width: $modal-lg) {
361
+ width: 100%;
362
+ flex: 0 0 100%;
363
+ }
364
+ }
365
+ }
366
+ }
367
+ </style>
@@ -0,0 +1,173 @@
1
+ <template>
2
+ <div class="embed-form">
3
+ <div class="container-fluid">
4
+ <h4 v-if="!noTitle" class="embed-form__heading">
5
+ {{ t('embed-form.heading') }}
6
+ </h4>
7
+ <div class="row">
8
+ <div class="col">
9
+ <p>
10
+ {{ t('embed-form.introduction') }}
11
+ </p>
12
+ <textarea ref='embed-form__code' class="form-control embed-form__code mb-2" readonly :value="embedCode()" @click="selectCode" />
13
+
14
+ <div class="d-flex justify-content-between">
15
+ <div class="form-check align-self-end">
16
+ <input type="checkbox" class="form-check-input" id="responsiveOptin" v-model="responsiveCheck" />
17
+ <label class="form-check-label fw-bold" for="responsiveOptin">
18
+ {{ t('embed-form.responsive-optin') }}
19
+ </label>
20
+ </div>
21
+
22
+ <haptic-copy
23
+ class="btn-link btn-sm text-uppercase fw-bold"
24
+ :text="embedCode()"
25
+ :label="t('embed-form.copy').toString()"
26
+ @attempt="selectCode()"
27
+ />
28
+ </div>
29
+ </div>
30
+ <div v-if="!noPreview" class="col-7 d-none d-lg-block embed-form__preview">
31
+ <!-- eslint-disable vue/no-v-html -->
32
+ <span v-html="embedCode(false)" />
33
+ <!-- eslint-enable -->
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </template>
39
+
40
+ <script lang="ts">
41
+ import {computed, defineComponent, ref} from 'vue'
42
+
43
+ import {useI18n} from "vue-i18n";
44
+ import HapticCopy from '@/components/HapticCopy.vue'
45
+ import IframeResizer from '@/utils/iframe-resizer'
46
+
47
+ interface ComponentInterface {
48
+ currentUrl: string
49
+ responsiveCheck: boolean
50
+ width: string
51
+ minWidth: number
52
+ height: number
53
+ minHeight: number
54
+ iframeCodeFor: Function
55
+ pymCodeFor: Function
56
+ }
57
+ /**
58
+ * Embed Form
59
+ */
60
+ export default defineComponent({
61
+ name: 'EmbedForm',
62
+ components: {
63
+ HapticCopy
64
+ },
65
+ props: {
66
+ /**
67
+ * Hide the form title
68
+ */
69
+ noTitle: {
70
+ type: Boolean
71
+ },
72
+ /**
73
+ * Hide the preview panel
74
+ */
75
+ noPreview: {
76
+ type: Boolean
77
+ },
78
+ /**
79
+ * Default width of the iframe code
80
+ */
81
+ width: {
82
+ type: [Number, String],
83
+ default: '100%'
84
+ },
85
+ /**
86
+ * Default height of the iframe code
87
+ */
88
+ height: {
89
+ type: Number,
90
+ default: () => window.innerHeight
91
+ },
92
+ /**
93
+ * Default minimal width of the iframe code (if extract from window\'s size)
94
+ */
95
+ minWidth: {
96
+ type: Number,
97
+ default: 0
98
+ },
99
+ /**
100
+ * Default minimal height of the iframe code (if extract from window\'s size)
101
+ */
102
+ minHeight: {
103
+ type: Number,
104
+ default: 0
105
+ },
106
+ /**
107
+ * URL of the iframe code
108
+ */
109
+ url: {
110
+ type: String,
111
+ default: null
112
+ }
113
+ },
114
+ setup(props)
115
+ {
116
+ const {t} = useI18n()
117
+
118
+ const responsiveCheck = ref(false)
119
+ const embedFormCode = ref<HTMLTextAreaElement|null>(null)
120
+ const currentUrl = computed(()=> {
121
+ return props.url || window.location.href
122
+ })
123
+ function iframeCodeFor(_url = currentUrl, width: string, height: string) {
124
+ return `<iframe width="${width}" height="${height}" src="${IframeResizer.deletePymParams(
125
+ props.url
126
+ )}" frameborder="0" allowfullscreen></iframe>`
127
+ }
128
+ function pymCodeFor(url = currentUrl): string {
129
+ return IframeResizer.template(url.value)
130
+ }
131
+ function selectCode(): void {
132
+ embedFormCode.value?.select()
133
+ }
134
+ function embedCode(withPym = responsiveCheck.value): string {
135
+ const width = typeof props.width === 'string' ? props.width : Math.max(props.width, props.minWidth).toString()
136
+ const height = Math.max(props.height, props.minHeight).toString()
137
+ return withPym ? pymCodeFor(currentUrl) : iframeCodeFor(currentUrl, width, height)
138
+ }
139
+
140
+ return {
141
+ t,
142
+ responsiveCheck,
143
+ embedFormCode,
144
+ selectCode,
145
+ embedCode
146
+ }
147
+ }
148
+ })
149
+ </script>
150
+
151
+ <style lang="scss" scoped>
152
+ @import '../styles/lib';
153
+
154
+ .embed-form {
155
+ font-size: 0.9rem;
156
+ overflow: auto;
157
+
158
+
159
+
160
+ &__heading {
161
+ font-size: 1.1em;
162
+ text-transform: uppercase;
163
+ }
164
+
165
+ &__code {
166
+ height: 80px;
167
+ }
168
+
169
+ &__preview {
170
+ border-left: 1px $gray-400 dashed;
171
+ }
172
+ }
173
+ </style>