@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,259 @@
1
+ <template>
2
+ <div>
3
+ <component
4
+ :is="rootElement"
5
+ id="generic-header"
6
+ data-turbolinks-permanent
7
+ class="navbar navbar-expand-lg navbar-light generic-header"
8
+ :offset="100"
9
+ :z-index="1020"
10
+ :on-unpin="closeFollowUsPopover"
11
+ :class="{ 'headroom--frozen': !collapseNavbar, 'generic-header--collapsed': collapseNavbar }"
12
+ :style="{ position: position }"
13
+ >
14
+ <!-- @slot Redefines brand -->
15
+ <slot name="brand">
16
+ <a :href="homeUrl" class="navbar-brand generic-header__brand">
17
+ <brand-expansion :size="45" :mode="shortMode" class="d-inline-block d-sm-none" />
18
+ <brand-expansion :size="45" :mode="longMode" class="d-none d-sm-inline-block" />
19
+ <span class="sr-only">International Consortium of Investigative Journalists</span>
20
+ </a>
21
+ </slot>
22
+ <button class="navbar-toggler border-0" type="button" aria-label="Toggle navigation" @click="toggleNavbar">
23
+ <fa icon="bars" size="xl" class="text-primary" />
24
+ </button>
25
+ <div class="navbar-collapse" :class="{ collapse: collapseNavbar }">
26
+ <ul class="navbar-nav ms-auto">
27
+ <li class="nav-item">
28
+ <a href="https://www.icij.org/investigations/" target="_blank" class="nav-link text-uppercase">
29
+ {{ t('generic-header.navbar.investigations') }}
30
+ </a>
31
+ </li>
32
+ <li class="nav-item">
33
+ <a href="https://www.icij.org/leak/" target="_blank" class="nav-link text-uppercase">
34
+ {{ t('generic-header.navbar.leak') }}
35
+ </a>
36
+ </li>
37
+ <li class="nav-item">
38
+ <a id="follow-us-toggler" class="nav-link text-uppercase" @mouseenter="showFollowUsPopover=true">
39
+ {{ t('generic-header.navbar.follow') }}
40
+ </a>
41
+ </li>
42
+ <li class="nav-item me-lg-3">
43
+ <slot name="donate-link">
44
+ <a class="text-uppercase btn btn-primary fw-bold" target="_blank" :href="donateUrl">
45
+ {{ t('generic-header.navbar.support') }}
46
+ </a>
47
+ </slot>
48
+ </li>
49
+ </ul>
50
+ <b-popover
51
+ v-model="showFollowUsPopover"
52
+ target="follow-us-toggler"
53
+ placement="bottom-start"
54
+ ref="followUsPopover"
55
+ click
56
+ >
57
+ <follow-us-popover @update:close="closeFollowUsPopover" @keydown.esc="closeFollowUsPopover" />
58
+ </b-popover>
59
+ </div>
60
+ </component>
61
+ </div>
62
+ </template>
63
+
64
+ <script lang="ts">
65
+ import { faBars } from '@fortawesome/free-solid-svg-icons/faBars'
66
+ import headroom from 'vue-headroom/src/headroom.vue';
67
+ import {
68
+ computed,
69
+ defineComponent,
70
+ type PropType,
71
+ ref,
72
+ onBeforeMount,
73
+ watch,
74
+ ComponentPublicInstance
75
+ } from 'vue'
76
+
77
+ import config from '@/config'
78
+ import Fa, { library } from '@/components/Fa'
79
+ import BrandExpansion from '@/components/BrandExpansion.vue'
80
+ import FollowUsPopover from '@/components/FollowUsPopover.vue'
81
+ import {BrandMode} from '@/enums'
82
+ import {useI18n} from "vue-i18n";
83
+ import {BPopover} from "bootstrap-vue-next";
84
+
85
+ type BrandOptions = {
86
+ noBorder: boolean
87
+ size: number
88
+ color: string
89
+ background: string
90
+ }
91
+
92
+ /**
93
+ * GenericHeader
94
+ */
95
+ export default defineComponent({
96
+ name: 'GenericHeader',
97
+ components: {
98
+ BPopover,
99
+ BrandExpansion,
100
+ Fa,
101
+ FollowUsPopover,
102
+ headroom
103
+ },
104
+ props: {
105
+ /**
106
+ * CSS position of the header. Can be <em>absolute</em>, <em>relative</em>, <em>static</em> or <em>fixed</em> (default).
107
+ */
108
+ position: {
109
+ type: String,
110
+ default: 'fixed'
111
+ },
112
+ /**
113
+ * Disable Headroom for hiding header until needed.
114
+ */
115
+ noHeadroom: {
116
+ type: Boolean,
117
+ default:false
118
+ },
119
+ /**
120
+ * Target link of the ICIJ logo and project name.
121
+ */
122
+ homeUrl: {
123
+ type: String,
124
+ default: () => config.get('app.home')
125
+ },
126
+ /**
127
+ * Default options to pass to the brand component
128
+ */
129
+ brandOptions: {
130
+ type: Object as PropType<BrandOptions>,
131
+ default: () => ({})
132
+ },
133
+ /**
134
+ * Target link of the donate button.
135
+ */
136
+ donateUrl: {
137
+ type: String,
138
+ default: () => config.get('app.donate-url')
139
+ }
140
+ },
141
+ setup(props) {
142
+
143
+ onBeforeMount((): void =>{
144
+ library.add(faBars)
145
+ })
146
+
147
+ const {t}= useI18n()
148
+ const followUsPopover = ref<ComponentPublicInstance<typeof BPopover>|null>(null)
149
+ const closable = ref(false)
150
+ const showFollowUsPopover = ref<boolean>(false)
151
+ const collapseNavbar = ref(true)
152
+ const shortMode = ref(BrandMode.Short)
153
+ const longMode = ref(BrandMode.Long)
154
+ const rootElement = computed((): string => {
155
+ return props.noHeadroom ? 'div' : 'headroom'
156
+ })
157
+ const appliedBrandOptions = computed((): BrandOptions => {
158
+ return {...defaultBrandOptions.value,... props.brandOptions}
159
+ })
160
+ const defaultBrandOptions = computed((): BrandOptions => {
161
+ return {
162
+ noBorder: true,
163
+ size: 50,
164
+ color: 'white',
165
+ background: '#A10207'
166
+ }
167
+ })
168
+ function closeFollowUsPopover() {
169
+ if(followUsPopover.value?.hide){
170
+ followUsPopover.value?.hide(new Event('forceHide'))
171
+ }
172
+ showFollowUsPopover.value=false
173
+ }
174
+ function toggleNavbar(): void {
175
+ collapseNavbar.value = !collapseNavbar.value
176
+ closeFollowUsPopover()
177
+ }
178
+
179
+ return {
180
+ t,
181
+ rootElement,
182
+ showFollowUsPopover,
183
+ followUsPopover,
184
+ collapseNavbar,
185
+ shortMode,
186
+ longMode,
187
+ appliedBrandOptions,
188
+ closable,
189
+ closeFollowUsPopover,
190
+ toggleNavbar
191
+ }
192
+ }
193
+ })
194
+ </script>
195
+
196
+ <style lang="scss">
197
+ @import '../styles/lib';
198
+
199
+ .generic-header {
200
+ background: white;
201
+ position: relative;
202
+ top: 0;
203
+ width: 100%;
204
+ z-index: $zindex-sticky;
205
+
206
+
207
+ .popover {
208
+ width: 100%;
209
+ }
210
+
211
+ & .headroom {
212
+ will-change: transform;
213
+ transition: transform 200ms linear;
214
+ @include media-breakpoint-up(lg) {
215
+ display: flex;
216
+ }
217
+ flex-grow: 1;
218
+
219
+ &--unpinned {
220
+ transform: translateY(-100%) !important;
221
+ }
222
+
223
+ &--pinned {
224
+ transform: translateY(0%);
225
+ }
226
+
227
+ &--frozen {
228
+ transform: translateY(0%) !important;
229
+ }
230
+ }
231
+
232
+ &__brand {
233
+ position: relative;
234
+ font-weight: bolder;
235
+ padding: $spacer;
236
+ font-size: 1rem;
237
+ display: inline-block;
238
+ }
239
+
240
+ .navbar-toggler {
241
+ position: absolute;
242
+ right: $spacer;
243
+ top: $spacer;
244
+ margin: 1px 0 0;
245
+ }
246
+
247
+ .nav-item {
248
+ margin: 0 $spacer * 0.5;
249
+ font-weight: bold;
250
+ text-transform: uppercase;
251
+ color: black;
252
+
253
+ .nav-link {
254
+ color: inherit;
255
+ cursor: pointer;
256
+ }
257
+ }
258
+ }
259
+ </style>
@@ -0,0 +1,256 @@
1
+ <script lang="ts">
2
+ import {FontAwesomeLayers} from '@fortawesome/vue-fontawesome'
3
+ import {faClipboard} from '@fortawesome/free-solid-svg-icons/faClipboard'
4
+ import {faClipboardCheck} from '@fortawesome/free-solid-svg-icons/faClipboardCheck'
5
+ import {BTooltip, PopoverPlacement} from 'bootstrap-vue-next'
6
+
7
+ import noop from 'lodash/noop'
8
+ import {
9
+ ComponentPublicInstance,
10
+ computed,
11
+ defineComponent,
12
+ nextTick,
13
+ onBeforeMount,
14
+ onUnmounted,
15
+ PropType,
16
+ ref
17
+ } from 'vue'
18
+ import {TranslateResult, useI18n} from 'vue-i18n'
19
+
20
+ import {default as Fa, library} from './Fa'
21
+
22
+ import {copyHtml, copyText} from '@/utils/clipboard'
23
+
24
+ type HapticCopyData = {
25
+ mounted: boolean
26
+ succeed: boolean
27
+ tooltipContent: TranslateResult | string
28
+ tooltipTimeout: ReturnType<typeof setTimeout> | undefined
29
+ }
30
+ export default defineComponent({
31
+ name: 'HapticCopy',
32
+ components: {
33
+ BTooltip,
34
+ FontAwesomeLayers,
35
+ Fa
36
+ },
37
+ props: {
38
+ /**
39
+ * Text to copy to the clipboard
40
+ */
41
+ text: {
42
+ type: String,
43
+ default: null
44
+ },
45
+ /**
46
+ * Plain text to use as an alternative text for HTML copy (uses `text` by default)
47
+ */
48
+ plain: {
49
+ type: String,
50
+ default: null
51
+ },
52
+ /**
53
+ * Hide the button label (still visible for screen reader)
54
+ */
55
+ hideLabel: {
56
+ type: Boolean
57
+ },
58
+ /**
59
+ * Button label
60
+ */
61
+ label: {
62
+ type: String,
63
+ default: null
64
+ },
65
+ /**
66
+ * Delay after which we hide the tooltip
67
+ */
68
+ tooltipHideDelay: {
69
+ type: Number,
70
+ default: 1e3
71
+ },
72
+ /**
73
+ * Placement of the tooltip. Can be: top, topleft, topright, right,<br />
74
+ * righttop, rightbottom, bottom, bottomleft, bottomright, left, lefttop,
75
+ * and leftbottom.
76
+ */
77
+ tooltipPlacement: {
78
+ type: String as PropType<PopoverPlacement>,
79
+ default: 'top'
80
+ },
81
+ /**
82
+ * Copy HTML content
83
+ */
84
+ html: {
85
+ type: Boolean
86
+ },
87
+ /**
88
+ * Deactivate haptic tooltip display
89
+ */
90
+ noTooltip: {
91
+ type: Boolean
92
+ }
93
+ },
94
+ emits: ['attempt', 'success', 'error', 'hideClipboardTooltip'],
95
+ setup(props, {emit, expose}) {
96
+ const {t, te} = useI18n()
97
+ const tooltip = ref<ComponentPublicInstance | null>(null)
98
+ const el = ref<ComponentPublicInstance<HTMLElement> | null>(null)
99
+ const tooltipContent = ref<string>('')
100
+ const tooltipTimeout = ref<NodeJS.Timeout | undefined>(undefined)
101
+ const showClipboardTooltip = ref(false)
102
+ onBeforeMount(() => {
103
+ library.add(faClipboard)
104
+ library.add(faClipboardCheck)
105
+ })
106
+ const tooltipContainer = computed((): string | null => {
107
+ // By default we append the tooltip in the root container using its
108
+ // id (if any) because BootstrapVue doesn't like HTMLElement for some
109
+ // reasons.
110
+
111
+ return el.value?.id.length ? `#${el.value.id}` : null;
112
+ })
113
+
114
+ function copyTextToClipboard(): Promise<void> {
115
+ return el.value ? copyText(props.text, el.value) : Promise.resolve()
116
+ }
117
+
118
+ function copyHtmlToClipboard(): void {
119
+ return copyHtml(props.text, props.plain || props.text)
120
+ }
121
+
122
+ function copyTextOrHtml() {
123
+ return props.html ? copyHtmlToClipboard() : copyTextToClipboard()
124
+ }
125
+
126
+ async function copy(): Promise<void> {
127
+ try {
128
+ /**
129
+ * Emitted when an attempt to copy text is made
130
+ *
131
+ * @event attempt
132
+ */
133
+ emit('attempt')
134
+ // Use clipboard.js internally
135
+ await copyTextOrHtml()
136
+ // Then option the tooltip in case of success
137
+ await openTooltip('haptic-copy.tooltip.succeed')
138
+ /**
139
+ * Emitted when the text has been copied successfully
140
+ *
141
+ * @event success
142
+ */
143
+ emit('success')
144
+ } catch (error) {
145
+ await openTooltip('haptic-copy.tooltip.failed')
146
+ /**
147
+ * Emitted when the text couldn't be copied
148
+ *
149
+ * @event error
150
+ */
151
+ emit('error', error)
152
+ }
153
+ // And close the tooltip after a short delay
154
+ nextTimeout(closeTooltip, props.tooltipHideDelay)
155
+ }
156
+
157
+ function getTooltipContent(msg: string) {
158
+ return te(msg) ? t(msg) : msg
159
+ }
160
+
161
+ async function openTooltip(msg = 'haptic-copy.tooltip.succeed') {
162
+ tooltipContent.value = getTooltipContent(msg)
163
+ showClipboardTooltip.value = true
164
+ }
165
+
166
+ async function closeTooltip() {
167
+ showClipboardTooltip.value = false
168
+ tooltipTimeout.value = undefined
169
+ emit('hideClipboardTooltip')
170
+
171
+ }
172
+
173
+ function nextTimeout(fn = noop, delay = 0) {
174
+ clearTimeout(tooltipTimeout.value)
175
+ return new Promise((resolve) => {
176
+ tooltipTimeout.value = setTimeout(resolve, delay)
177
+ })
178
+ .finally(nextTick)
179
+ .then(fn)
180
+ }
181
+
182
+ onUnmounted(() => {
183
+ closeTooltip()
184
+ })
185
+ expose({
186
+ hide: closeTooltip,
187
+ })
188
+ return {
189
+ t,
190
+ tooltip,
191
+ el,
192
+ showClipboardTooltip,
193
+ tooltipContainer,
194
+ tooltipContent,
195
+ tooltipTimeout,
196
+ copy,
197
+ closeTooltip,
198
+ openTooltip,
199
+ nextTimeout,
200
+ }
201
+ },
202
+ })
203
+ </script>
204
+
205
+ <template>
206
+ <button id="hapticCopy" ref="el" class="btn haptic-copy" @mouseleave="closeTooltip" @click.stop="copy">
207
+ <!-- @slot Main content of the button (including the icon) -->
208
+ <slot>
209
+ <font-awesome-layers>
210
+ <transition name="spin">
211
+ <fa v-if="!tooltipTimeout" class="haptic-copy__icon" icon="clipboard"/>
212
+ </transition>
213
+ <transition name="spin">
214
+ <fa v-if="tooltipTimeout" class="haptic-copy__icon" icon="clipboard-check"/>
215
+ </transition>
216
+ </font-awesome-layers>
217
+ <span :class="{ 'sr-only': hideLabel }" class="ms-1 haptic-copy__label">
218
+ {{ label || t('haptic-copy.label') }}
219
+ </span>
220
+ </slot>
221
+ <b-tooltip
222
+ v-if="!noTooltip"
223
+ ref="tooltip"
224
+ :model-value="showClipboardTooltip"
225
+ :placement="tooltipPlacement"
226
+ manual
227
+ noninteractive
228
+ target="hapticCopy"
229
+ >
230
+ {{ tooltipContent }}
231
+ </b-tooltip>
232
+ </button>
233
+
234
+ </template>
235
+ <style lang="scss">
236
+ .haptic-copy {
237
+ &__icon {
238
+ transform: rotate(0deg);
239
+
240
+ &.spin-enter-active,
241
+ &.spin-leave-active {
242
+ transition: all 0.2s;
243
+ }
244
+
245
+ &.spin-enter-from {
246
+ transform: rotate(-180deg);
247
+ opacity: 0;
248
+ }
249
+
250
+ &.spin-leave-to {
251
+ transform: rotate(180deg);
252
+ opacity: 0;
253
+ }
254
+ }
255
+ }
256
+ </style>