@md-plugins/quasar-app-extension-q-press 0.1.0-alpha.10

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 (200) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +230 -0
  3. package/old/prompts.js +44 -0
  4. package/old/uninstall.js +9 -0
  5. package/package.json +60 -0
  6. package/scripts/build.js +33 -0
  7. package/src/index.js +63 -0
  8. package/src/install.js +49 -0
  9. package/src/templates/.gitkeep +0 -0
  10. package/src/templates/init/src/_q-press/.gitkeep +0 -0
  11. package/src/templates/init/src/_q-press/api/components/DarkModeToggle.json +37 -0
  12. package/src/templates/init/src/_q-press/api/components/MarkdownApi.json +67 -0
  13. package/src/templates/init/src/_q-press/api/components/MarkdownApiEntry.json +76 -0
  14. package/src/templates/init/src/_q-press/api/components/MarkdownCardLink.json +28 -0
  15. package/src/templates/init/src/_q-press/api/components/MarkdownCardTitle.json +48 -0
  16. package/src/templates/init/src/_q-press/api/components/MarkdownCode.json +37 -0
  17. package/src/templates/init/src/_q-press/api/components/MarkdownCodePrism.json +29 -0
  18. package/src/templates/init/src/_q-press/api/components/MarkdownCodepen.json +21 -0
  19. package/src/templates/init/src/_q-press/api/components/MarkdownCopyButton.json +36 -0
  20. package/src/templates/init/src/_q-press/api/components/MarkdownDrawerSidebar.json +17 -0
  21. package/src/templates/init/src/_q-press/api/components/MarkdownDrawerToc.json +17 -0
  22. package/src/templates/init/src/_q-press/api/components/MarkdownExample.json +22 -0
  23. package/src/templates/init/src/_q-press/api/components/MarkdownHeader.json +28 -0
  24. package/src/templates/init/src/_q-press/api/components/MarkdownHeaderIconLinks.json +16 -0
  25. package/src/templates/init/src/_q-press/api/components/MarkdownHeaderMenu.json +77 -0
  26. package/src/templates/init/src/_q-press/api/components/MarkdownHeaderTextLinks.json +33 -0
  27. package/src/templates/init/src/_q-press/api/components/MarkdownInstallation.json +33 -0
  28. package/src/templates/init/src/_q-press/api/components/MarkdownLayout.json +52 -0
  29. package/src/templates/init/src/_q-press/api/components/MarkdownLink.json +23 -0
  30. package/src/templates/init/src/_q-press/api/components/MarkdownPage.json +71 -0
  31. package/src/templates/init/src/_q-press/api/components/MarkdownPageFooter.json +21 -0
  32. package/src/templates/init/src/_q-press/api/components/MarkdownPageSidebar.json +56 -0
  33. package/src/templates/init/src/_q-press/api/components/MarkdownPageToc.json +17 -0
  34. package/src/templates/init/src/_q-press/api/components/MarkdownPrerender.json +25 -0
  35. package/src/templates/init/src/_q-press/api/components/MarkdownTree.json +27 -0
  36. package/src/templates/init/src/_q-press/api/composables/dark.json +29 -0
  37. package/src/templates/init/src/_q-press/api/composables/scroll.json +34 -0
  38. package/src/templates/init/src/_q-press/assets/get-meta.ts +29 -0
  39. package/src/templates/init/src/_q-press/components/DarkModeToggle.vue +105 -0
  40. package/src/templates/init/src/_q-press/components/MarkdownApi.vue +588 -0
  41. package/src/templates/init/src/_q-press/components/MarkdownApiEntry.ts +594 -0
  42. package/src/templates/init/src/_q-press/components/MarkdownCardLink.vue +25 -0
  43. package/src/templates/init/src/_q-press/components/MarkdownCardTitle.vue +21 -0
  44. package/src/templates/init/src/_q-press/components/MarkdownCode.vue +25 -0
  45. package/src/templates/init/src/_q-press/components/MarkdownCodePrism.ts +36 -0
  46. package/src/templates/init/src/_q-press/components/MarkdownCodepen.vue +183 -0
  47. package/src/templates/init/src/_q-press/components/MarkdownCopyButton.vue +104 -0
  48. package/src/templates/init/src/_q-press/components/MarkdownExample.vue +221 -0
  49. package/src/templates/init/src/_q-press/components/MarkdownInstallation.vue +166 -0
  50. package/src/templates/init/src/_q-press/components/MarkdownLink.vue +38 -0
  51. package/src/templates/init/src/_q-press/components/MarkdownPrerender.ts +82 -0
  52. package/src/templates/init/src/_q-press/components/MarkdownTree.vue +105 -0
  53. package/src/templates/init/src/_q-press/components/markdown-utils.ts +105 -0
  54. package/src/templates/init/src/_q-press/composables/dark.ts +39 -0
  55. package/src/templates/init/src/_q-press/composables/scroll.ts +115 -0
  56. package/src/templates/init/src/_q-press/css/app.scss +662 -0
  57. package/src/templates/init/src/_q-press/css/fonts.scss +100 -0
  58. package/src/templates/init/src/_q-press/css/prism-theme.scss +298 -0
  59. package/src/templates/init/src/_q-press/css/themes/default.scss +68 -0
  60. package/src/templates/init/src/_q-press/css/themes/newspaper.scss +69 -0
  61. package/src/templates/init/src/_q-press/css/themes/sunrise.scss +67 -0
  62. package/src/templates/init/src/_q-press/css/themes/tawny.scss +69 -0
  63. package/src/templates/init/src/_q-press/layouts/MarkdownDrawerSidebar.vue +32 -0
  64. package/src/templates/init/src/_q-press/layouts/MarkdownDrawerToc.vue +37 -0
  65. package/src/templates/init/src/_q-press/layouts/MarkdownHeader.vue +412 -0
  66. package/src/templates/init/src/_q-press/layouts/MarkdownHeaderIconLinks.vue +31 -0
  67. package/src/templates/init/src/_q-press/layouts/MarkdownHeaderMenu.ts +93 -0
  68. package/src/templates/init/src/_q-press/layouts/MarkdownHeaderTextLinks.vue +37 -0
  69. package/src/templates/init/src/_q-press/layouts/MarkdownLayout.vue +239 -0
  70. package/src/templates/init/src/_q-press/layouts/MarkdownPage.vue +307 -0
  71. package/src/templates/init/src/_q-press/layouts/MarkdownPageFooter.vue +187 -0
  72. package/src/templates/init/src/_q-press/layouts/MarkdownPageSidebar.scss +54 -0
  73. package/src/templates/init/src/_q-press/layouts/MarkdownPageSidebar.ts +218 -0
  74. package/src/templates/init/src/_q-press/layouts/MarkdownPageToc.vue +23 -0
  75. package/src/templates/init/src/_q-press/layouts/MarkdownSearch.vue +449 -0
  76. package/src/templates/init/src/_q-press/stores/markdown.ts +101 -0
  77. package/src/templates/init/src/components/LandingPage/LandingPage.vue +341 -0
  78. package/src/templates/init/src/components/Releases/PackageReleases.vue +164 -0
  79. package/src/templates/init/src/components/Releases/PublicReleases.vue +149 -0
  80. package/src/templates/init/src/components/Releases/ReleasesAvailable.vue +74 -0
  81. package/src/templates/init/src/examples/QAvatar/BasicExample.vue +11 -0
  82. package/src/templates/init/src/markdown/__elements.md +548 -0
  83. package/src/templates/init/src/markdown/__elements2.md +347 -0
  84. package/src/templates/init/src/markdown/faq/best-practices.md +0 -0
  85. package/src/templates/init/src/markdown/faq/general.md +0 -0
  86. package/src/templates/init/src/markdown/faq/troubleshooting.md +0 -0
  87. package/src/templates/init/src/markdown/getting-started/introduction.md +67 -0
  88. package/src/templates/init/src/markdown/guides/contributing.md +101 -0
  89. package/src/templates/init/src/markdown/guides/faq.md +115 -0
  90. package/src/templates/init/src/markdown/guides/release-notes.md +0 -0
  91. package/src/templates/init/src/markdown/guides/style-guide.md +0 -0
  92. package/src/templates/init/src/markdown/landing-page.md +11 -0
  93. package/src/templates/init/src/markdown/listing.ts +3 -0
  94. package/src/templates/init/src/markdown/md-plugins/blockquote/advanced.md +83 -0
  95. package/src/templates/init/src/markdown/md-plugins/blockquote/overview.md +183 -0
  96. package/src/templates/init/src/markdown/md-plugins/codeblocks/advanced.md +210 -0
  97. package/src/templates/init/src/markdown/md-plugins/codeblocks/overview.md +616 -0
  98. package/src/templates/init/src/markdown/md-plugins/containers/advanced.md +301 -0
  99. package/src/templates/init/src/markdown/md-plugins/containers/overview.md +206 -0
  100. package/src/templates/init/src/markdown/md-plugins/frontmatter/advanced.md +164 -0
  101. package/src/templates/init/src/markdown/md-plugins/frontmatter/overview.md +131 -0
  102. package/src/templates/init/src/markdown/md-plugins/headers/advanced.md +236 -0
  103. package/src/templates/init/src/markdown/md-plugins/headers/overview.md +134 -0
  104. package/src/templates/init/src/markdown/md-plugins/image/advanced.md +114 -0
  105. package/src/templates/init/src/markdown/md-plugins/image/overview.md +124 -0
  106. package/src/templates/init/src/markdown/md-plugins/imports/advanced.md +105 -0
  107. package/src/templates/init/src/markdown/md-plugins/imports/overview.md +80 -0
  108. package/src/templates/init/src/markdown/md-plugins/inline-code/advanced.md +133 -0
  109. package/src/templates/init/src/markdown/md-plugins/inline-code/overview.md +101 -0
  110. package/src/templates/init/src/markdown/md-plugins/link/advanced.md +157 -0
  111. package/src/templates/init/src/markdown/md-plugins/link/overview.md +126 -0
  112. package/src/templates/init/src/markdown/md-plugins/shared/overview.md +175 -0
  113. package/src/templates/init/src/markdown/md-plugins/table/advanced.md +190 -0
  114. package/src/templates/init/src/markdown/md-plugins/table/overview.md +186 -0
  115. package/src/templates/init/src/markdown/md-plugins/title/advanced.md +88 -0
  116. package/src/templates/init/src/markdown/md-plugins/title/overview.md +99 -0
  117. package/src/templates/init/src/markdown/other/release-notes.md +12 -0
  118. package/src/templates/init/src/markdown/privacy-policy.md +12 -0
  119. package/src/templates/init/src/markdown/quasar-app-extensions/qpress/advanced.md +101 -0
  120. package/src/templates/init/src/markdown/quasar-app-extensions/qpress/components.md +69 -0
  121. package/src/templates/init/src/markdown/quasar-app-extensions/qpress/overview.md +254 -0
  122. package/src/templates/init/src/markdown/quasar-app-extensions/qpress/themes.md +4 -0
  123. package/src/templates/init/src/markdown/quasar-app-extensions/vitemdpluginappext/advanced.md +4 -0
  124. package/src/templates/init/src/markdown/quasar-app-extensions/vitemdpluginappext/overview.md +103 -0
  125. package/src/templates/init/src/markdown/vite-plugins/index.md +6 -0
  126. package/src/templates/init/src/markdown/vite-plugins/viteexamplesplugin/advanced.md +138 -0
  127. package/src/templates/init/src/markdown/vite-plugins/viteexamplesplugin/overview.md +88 -0
  128. package/src/templates/init/src/markdown/vite-plugins/vitemdplugin/advanced.md +226 -0
  129. package/src/templates/init/src/markdown/vite-plugins/vitemdplugin/index.md +6 -0
  130. package/src/templates/init/src/markdown/vite-plugins/vitemdplugin/overview.md +166 -0
  131. package/src/templates/init/src/q-press.globals.d.ts +36 -0
  132. package/src/templates/init/src/siteConfig/index.ts +440 -0
  133. package/src/templates/update/src/_q-press/.gitkeep +0 -0
  134. package/src/templates/update/src/_q-press/api/components/DarkModeToggle.json +37 -0
  135. package/src/templates/update/src/_q-press/api/components/MarkdownApi.json +67 -0
  136. package/src/templates/update/src/_q-press/api/components/MarkdownApiEntry.json +76 -0
  137. package/src/templates/update/src/_q-press/api/components/MarkdownCardLink.json +28 -0
  138. package/src/templates/update/src/_q-press/api/components/MarkdownCardTitle.json +48 -0
  139. package/src/templates/update/src/_q-press/api/components/MarkdownCode.json +37 -0
  140. package/src/templates/update/src/_q-press/api/components/MarkdownCodePrism.json +29 -0
  141. package/src/templates/update/src/_q-press/api/components/MarkdownCodepen.json +21 -0
  142. package/src/templates/update/src/_q-press/api/components/MarkdownCopyButton.json +36 -0
  143. package/src/templates/update/src/_q-press/api/components/MarkdownDrawerSidebar.json +17 -0
  144. package/src/templates/update/src/_q-press/api/components/MarkdownDrawerToc.json +17 -0
  145. package/src/templates/update/src/_q-press/api/components/MarkdownExample.json +22 -0
  146. package/src/templates/update/src/_q-press/api/components/MarkdownHeader.json +28 -0
  147. package/src/templates/update/src/_q-press/api/components/MarkdownHeaderIconLinks.json +16 -0
  148. package/src/templates/update/src/_q-press/api/components/MarkdownHeaderMenu.json +77 -0
  149. package/src/templates/update/src/_q-press/api/components/MarkdownHeaderTextLinks.json +33 -0
  150. package/src/templates/update/src/_q-press/api/components/MarkdownInstallation.json +33 -0
  151. package/src/templates/update/src/_q-press/api/components/MarkdownLayout.json +52 -0
  152. package/src/templates/update/src/_q-press/api/components/MarkdownLink.json +23 -0
  153. package/src/templates/update/src/_q-press/api/components/MarkdownPage.json +71 -0
  154. package/src/templates/update/src/_q-press/api/components/MarkdownPageFooter.json +21 -0
  155. package/src/templates/update/src/_q-press/api/components/MarkdownPageSidebar.json +56 -0
  156. package/src/templates/update/src/_q-press/api/components/MarkdownPageToc.json +17 -0
  157. package/src/templates/update/src/_q-press/api/components/MarkdownPrerender.json +25 -0
  158. package/src/templates/update/src/_q-press/api/components/MarkdownTree.json +27 -0
  159. package/src/templates/update/src/_q-press/api/composables/dark.json +29 -0
  160. package/src/templates/update/src/_q-press/api/composables/scroll.json +34 -0
  161. package/src/templates/update/src/_q-press/assets/get-meta.ts +29 -0
  162. package/src/templates/update/src/_q-press/components/DarkModeToggle.vue +105 -0
  163. package/src/templates/update/src/_q-press/components/MarkdownApi.vue +588 -0
  164. package/src/templates/update/src/_q-press/components/MarkdownApiEntry.ts +594 -0
  165. package/src/templates/update/src/_q-press/components/MarkdownCardLink.vue +25 -0
  166. package/src/templates/update/src/_q-press/components/MarkdownCardTitle.vue +21 -0
  167. package/src/templates/update/src/_q-press/components/MarkdownCode.vue +25 -0
  168. package/src/templates/update/src/_q-press/components/MarkdownCodePrism.ts +36 -0
  169. package/src/templates/update/src/_q-press/components/MarkdownCodepen.vue +183 -0
  170. package/src/templates/update/src/_q-press/components/MarkdownCopyButton.vue +104 -0
  171. package/src/templates/update/src/_q-press/components/MarkdownExample.vue +221 -0
  172. package/src/templates/update/src/_q-press/components/MarkdownInstallation.vue +166 -0
  173. package/src/templates/update/src/_q-press/components/MarkdownLink.vue +38 -0
  174. package/src/templates/update/src/_q-press/components/MarkdownPrerender.ts +82 -0
  175. package/src/templates/update/src/_q-press/components/MarkdownTree.vue +105 -0
  176. package/src/templates/update/src/_q-press/components/markdown-utils.ts +105 -0
  177. package/src/templates/update/src/_q-press/composables/dark.ts +39 -0
  178. package/src/templates/update/src/_q-press/composables/scroll.ts +115 -0
  179. package/src/templates/update/src/_q-press/css/app.scss +662 -0
  180. package/src/templates/update/src/_q-press/css/fonts.scss +100 -0
  181. package/src/templates/update/src/_q-press/css/prism-theme.scss +298 -0
  182. package/src/templates/update/src/_q-press/css/themes/default.scss +68 -0
  183. package/src/templates/update/src/_q-press/css/themes/newspaper.scss +69 -0
  184. package/src/templates/update/src/_q-press/css/themes/sunrise.scss +67 -0
  185. package/src/templates/update/src/_q-press/css/themes/tawny.scss +69 -0
  186. package/src/templates/update/src/_q-press/layouts/MarkdownDrawerSidebar.vue +32 -0
  187. package/src/templates/update/src/_q-press/layouts/MarkdownDrawerToc.vue +37 -0
  188. package/src/templates/update/src/_q-press/layouts/MarkdownHeader.vue +412 -0
  189. package/src/templates/update/src/_q-press/layouts/MarkdownHeaderIconLinks.vue +31 -0
  190. package/src/templates/update/src/_q-press/layouts/MarkdownHeaderMenu.ts +93 -0
  191. package/src/templates/update/src/_q-press/layouts/MarkdownHeaderTextLinks.vue +37 -0
  192. package/src/templates/update/src/_q-press/layouts/MarkdownLayout.vue +239 -0
  193. package/src/templates/update/src/_q-press/layouts/MarkdownPage.vue +307 -0
  194. package/src/templates/update/src/_q-press/layouts/MarkdownPageFooter.vue +187 -0
  195. package/src/templates/update/src/_q-press/layouts/MarkdownPageSidebar.scss +54 -0
  196. package/src/templates/update/src/_q-press/layouts/MarkdownPageSidebar.ts +218 -0
  197. package/src/templates/update/src/_q-press/layouts/MarkdownPageToc.vue +23 -0
  198. package/src/templates/update/src/_q-press/layouts/MarkdownSearch.vue +449 -0
  199. package/src/templates/update/src/_q-press/stores/markdown.ts +101 -0
  200. package/src/templates/update/src/q-press.globals.d.ts +36 -0
@@ -0,0 +1,82 @@
1
+ import { h, ref, computed, defineComponent, type PropType } from 'vue'
2
+ import { QCard, QTabs, QTab, QTabPanels, QSeparator } from 'quasar'
3
+
4
+ export default defineComponent({
5
+ name: 'MarkdownPrerender',
6
+
7
+ props: {
8
+ title: {
9
+ type: String as PropType<string>,
10
+ required: false,
11
+ },
12
+ tabs: {
13
+ type: Array as PropType<string[]>,
14
+ required: false,
15
+ },
16
+ },
17
+
18
+ setup(props, { slots }) {
19
+ const currentTab = ref(props.tabs !== undefined ? props.tabs[0] : null)
20
+
21
+ const hasHeader = computed(() => props.title !== undefined || props.tabs !== undefined)
22
+
23
+ function getContent() {
24
+ const acc: ReturnType<typeof h>[] = []
25
+
26
+ if (props.title !== undefined) {
27
+ acc.push(
28
+ h('div', { class: 'header-toolbar row items-center' }, [
29
+ h('div', { class: 'markdown-card-title q-my-xs q-mr-sm' }, props.title),
30
+ ]),
31
+ )
32
+ }
33
+
34
+ if (props.tabs !== undefined) {
35
+ acc.push(
36
+ h(
37
+ QTabs,
38
+ {
39
+ class: 'header-tabs',
40
+ align: 'left',
41
+ activeColor: 'brand-primary',
42
+ indicatorColor: 'brand-primary',
43
+ dense: true,
44
+ breakpoint: 0,
45
+ shrink: true,
46
+ modelValue: currentTab.value,
47
+ 'onUpdate:modelValue': (v: string) => {
48
+ currentTab.value = v
49
+ },
50
+ },
51
+ () =>
52
+ props.tabs!.map((tab) =>
53
+ h(QTab, { name: tab, class: 'header-btn', noCaps: true }, () => tab),
54
+ ),
55
+ ),
56
+ )
57
+ }
58
+
59
+ if (hasHeader.value) {
60
+ acc.push(h(QSeparator))
61
+ }
62
+
63
+ acc.push(
64
+ props.tabs !== undefined
65
+ ? h(
66
+ QTabPanels,
67
+ {
68
+ class: 'markdown-copybtn-hover',
69
+ animated: true,
70
+ modelValue: currentTab.value,
71
+ },
72
+ slots.default,
73
+ )
74
+ : h('div', { class: 'markdown-copybtn-hover relative-position' }, slots.default?.()),
75
+ )
76
+
77
+ return acc
78
+ }
79
+
80
+ return () => h(QCard, { flat: true, bordered: true }, getContent)
81
+ },
82
+ })
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <q-tree class="markdown-tree" :nodes="nodes" node-key="id" children-key="c" default-expand-all>
3
+ <template #default-header="prop">
4
+ <div class="markdown-tree__label text-no-wrap">{{ prop.node.l }}</div>
5
+
6
+ <q-btn
7
+ v-if="prop.node.url"
8
+ class="markdown-tree__btn q-ml-sm"
9
+ padding="0"
10
+ color="brand-accent"
11
+ flat
12
+ :icon="mdiLaunch"
13
+ :href="prop.node.url"
14
+ target="_blank"
15
+ @click.stop
16
+ />
17
+
18
+ <template v-if="prop.node.e">
19
+ <q-icon
20
+ :name="mdiInformationOutline"
21
+ class="q-ml-sm lt-sm"
22
+ v-if="prop.node.e"
23
+ color="grey"
24
+ @click.stop
25
+ @touchstart.stop
26
+ >
27
+ <q-tooltip>{{ prop.node.e }}</q-tooltip>
28
+ </q-icon>
29
+ <div class="markdown-tree__explanation text-grey q-ml-sm gt-xs" v-if="prop.node.e">
30
+ # {{ prop.node.e }}
31
+ </div>
32
+ </template>
33
+ </template>
34
+ </q-tree>
35
+ </template>
36
+
37
+ <script setup>
38
+ import { mdiLaunch, mdiInformationOutline } from '@quasar/extras/mdi-v6'
39
+
40
+ const props = defineProps({
41
+ def: Object,
42
+ })
43
+
44
+ let id = 0
45
+ const addId = (node) => {
46
+ node.id = id++
47
+ if (node.c !== void 0) {
48
+ node.l += '/'
49
+ node.c.forEach(addId)
50
+ }
51
+ return node
52
+ }
53
+
54
+ const nodes = [addId(props.def)]
55
+ </script>
56
+
57
+ <style lang="scss">
58
+ .markdown-tree {
59
+ &__label {
60
+ font-size: ($font-size - 1px);
61
+ }
62
+
63
+ &__btn .q-icon {
64
+ font-size: 17px;
65
+ }
66
+
67
+ &__explanation {
68
+ font-size: ($font-size - 3px);
69
+ letter-spacing: 0.2px;
70
+ }
71
+
72
+ .q-tree__node {
73
+ padding: 0 0 3px 11px;
74
+
75
+ &:after {
76
+ left: -9px;
77
+ }
78
+ }
79
+
80
+ .q-tree__children {
81
+ padding-left: 19px;
82
+ }
83
+
84
+ .q-tree__node--parent {
85
+ padding-left: 4px;
86
+ }
87
+
88
+ .q-tree__node-header {
89
+ padding: 0 3px;
90
+
91
+ &:before {
92
+ left: -13px;
93
+ }
94
+ }
95
+
96
+ .q-tree__node--child {
97
+ padding-left: 10px;
98
+
99
+ > .q-tree__node-header:before {
100
+ left: -19px;
101
+ width: 15px;
102
+ }
103
+ }
104
+ }
105
+ </style>
@@ -0,0 +1,105 @@
1
+ import { Notify } from 'quasar'
2
+ import { slugify } from '@md-plugins/shared'
3
+
4
+ /**
5
+ * Fallback function to copy text to clipboard when the Clipboard API is not available.
6
+ * This function creates a temporary textarea element, selects its content, and uses the
7
+ * deprecated execCommand('copy') method to copy the text.
8
+ *
9
+ * @param text - The string to be copied to the clipboard.
10
+ * @returns A boolean indicating whether the copy operation was successful (true) or not (false).
11
+ */
12
+ function copyToClipboardFallback(text: string): boolean {
13
+ const textArea = document.createElement('textarea')
14
+ textArea.value = text
15
+ textArea.style.position = 'fixed' // avoid scrolling to bottom
16
+ document.body.appendChild(textArea)
17
+ textArea.focus()
18
+ textArea.select()
19
+
20
+ let res = false
21
+ try {
22
+ res = document.execCommand('copy')
23
+ } catch (err) {
24
+ console.error('Unable to copy to clipboard', err)
25
+ } finally {
26
+ document.body.removeChild(textArea)
27
+ }
28
+ return res
29
+ }
30
+
31
+ /**
32
+ * Copies the provided text to the clipboard using the Clipboard API if available,
33
+ * or falls back to a manual method if the API is not supported.
34
+ *
35
+ * @param text - The string to be copied to the clipboard.
36
+ * @returns A Promise that resolves when the text has been successfully copied,
37
+ * or rejects if the copy operation fails.
38
+ * @throws Will throw an error if the Clipboard API fails or if the fallback method fails.
39
+ */
40
+ export async function copyToClipboard(text: string): Promise<void> {
41
+ if (navigator.clipboard) {
42
+ try {
43
+ await navigator.clipboard.writeText(text)
44
+ } catch (err) {
45
+ console.error('Failed to copy text to clipboard using Clipboard API', err)
46
+ throw err
47
+ }
48
+ } else {
49
+ return new Promise((resolve, reject) => {
50
+ const res = copyToClipboardFallback(text)
51
+ if (res) {
52
+ resolve()
53
+ } else {
54
+ const error = new Error('Failed to copy text to clipboard using fallback method')
55
+ console.error(error)
56
+ reject(error)
57
+ }
58
+ })
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Copies a heading's anchor link to the clipboard and updates the URL hash.
64
+ * This function performs the following actions:
65
+ * 1. Constructs the full URL with the anchor.
66
+ * 2. Temporarily removes the element's ID to prevent page jumping.
67
+ * 3. Updates the URL hash using history API or fallback method.
68
+ * 4. Restores the element's ID after a short delay.
69
+ * 5. Copies the constructed URL to the clipboard.
70
+ * 6. Displays a notification to confirm the copy action.
71
+ *
72
+ * @param id - The ID of the heading element to be copied.
73
+ * @returns void This function doesn't return a value.
74
+ */
75
+ export function copyHeading(id: string): void {
76
+ const text = `${location.origin}${location.pathname}#${id}`
77
+ const el = document.getElementById(id)
78
+
79
+ if (el) {
80
+ el.id = '' // Temporarily clear the ID to avoid jumping
81
+ }
82
+
83
+ if ('replaceState' in history) {
84
+ history.replaceState(history.state, '', `${location.pathname}#${id}`)
85
+ } else {
86
+ location.hash = `#${id}`
87
+ }
88
+
89
+ if (el) {
90
+ setTimeout(() => {
91
+ el.id = id // Restore the ID
92
+ }, 300)
93
+ }
94
+
95
+ copyToClipboard(text)
96
+
97
+ Notify.create({
98
+ message: 'Anchor has been copied to clipboard.',
99
+ position: 'top',
100
+ actions: [{ icon: 'cancel', color: 'white', dense: true, round: true }],
101
+ timeout: 2000,
102
+ })
103
+ }
104
+
105
+ export { slugify }
@@ -0,0 +1,39 @@
1
+ import { useQuasar } from 'quasar'
2
+ import { useMarkdownStore } from '../stores/markdown'
3
+ import { computed, watch } from 'vue'
4
+
5
+ export function useDark() {
6
+ const $q = useQuasar()
7
+ const markdownStore = useMarkdownStore()
8
+
9
+ const isDark = computed(() => markdownStore.dark)
10
+
11
+ function initDark() {
12
+ markdownStore.dark = $q.cookies.get('theme') !== 'light'
13
+ $q.dark.set(markdownStore.dark)
14
+ }
15
+
16
+ function toggleDark() {
17
+ $q.dark.toggle()
18
+ markdownStore.dark = $q.dark.isActive
19
+
20
+ $q.cookies.set('theme', markdownStore.dark ? 'dark' : 'light', {
21
+ path: '/',
22
+ sameSite: 'Strict',
23
+ expires: 400,
24
+ })
25
+ }
26
+
27
+ watch(
28
+ () => markdownStore.dark,
29
+ (val) => {
30
+ $q.dark.set(val)
31
+ },
32
+ )
33
+
34
+ return {
35
+ isDark,
36
+ initDark,
37
+ toggleDark,
38
+ }
39
+ }
@@ -0,0 +1,115 @@
1
+ import { scroll } from 'quasar'
2
+ import { watch, onMounted, onBeforeUnmount } from 'vue'
3
+ import { useRoute, useRouter } from 'vue-router'
4
+ import { useMarkdownStore } from '../stores/markdown'
5
+ const { setVerticalScrollPosition, getVerticalScrollPosition } = scroll
6
+
7
+ export function useScroll() {
8
+ let scrollTimer: ReturnType<typeof setTimeout> | undefined
9
+ const scrollDuration = 500
10
+ const route = useRoute()
11
+ const router = useRouter()
12
+ const markdownStore = useMarkdownStore()
13
+
14
+ let preventTocUpdate = route.hash.length > 1
15
+
16
+ // Watch for route changes
17
+ watch(
18
+ () => route.fullPath,
19
+ (newRoute, oldRoute) => {
20
+ setTimeout(() => {
21
+ scrollToCurrentAnchor(newRoute !== oldRoute)
22
+ })
23
+ },
24
+ )
25
+
26
+ function changeRouterHash(hash: string) {
27
+ if (route.hash !== hash) {
28
+ router.replace({ hash }).catch(() => {})
29
+ } else {
30
+ scrollToCurrentAnchor()
31
+ }
32
+ }
33
+
34
+ function scrollPage(el: HTMLElement, delay: number) {
35
+ const { top } = el.getBoundingClientRect()
36
+ const offset = Math.max(
37
+ 0,
38
+ top + getVerticalScrollPosition(window) - 166, // TODO: dynamic header offset
39
+ )
40
+
41
+ clearTimeout(scrollTimer)
42
+
43
+ preventTocUpdate = true
44
+ setVerticalScrollPosition(window, offset, delay)
45
+
46
+ scrollTimer = setTimeout(() => {
47
+ preventTocUpdate = false
48
+ }, delay + 10)
49
+ }
50
+
51
+ function scrollTo(id: string) {
52
+ clearTimeout(scrollTimer)
53
+ changeRouterHash('#' + id)
54
+
55
+ setTimeout(() => {
56
+ markdownStore.setActiveToc(getVerticalScrollPosition(window))
57
+ }, scrollDuration + 50)
58
+ }
59
+
60
+ function onPageScroll({ position }: { position: number }) {
61
+ // @ts-expect-error Jeff - fix later when I can figure this one out
62
+ if (preventTocUpdate !== true && document.qScrollPrevented !== true) {
63
+ markdownStore.setActiveToc(position)
64
+ }
65
+ }
66
+
67
+ function scrollToCurrentAnchor(immediate?: boolean) {
68
+ const hash = location.hash
69
+ const el = hash.length > 1 ? document.getElementById(hash.substring(1)) : null
70
+
71
+ if (el !== null) {
72
+ if (immediate === true) {
73
+ let anchorEl: HTMLElement | null = el
74
+ while (
75
+ anchorEl?.parentElement !== null &&
76
+ !anchorEl.parentElement.classList.contains('q-page')
77
+ ) {
78
+ anchorEl = anchorEl.parentElement
79
+ }
80
+
81
+ if (anchorEl) {
82
+ document.body.classList.add('q-scroll--lock')
83
+ anchorEl.classList.add('q-scroll--anchor')
84
+
85
+ setTimeout(() => {
86
+ document.body.classList.remove('q-scroll--lock')
87
+ if (anchorEl) {
88
+ anchorEl.classList.remove('q-scroll--anchor')
89
+ }
90
+ }, 2000)
91
+ }
92
+ }
93
+
94
+ scrollPage(el, immediate === true ? 0 : scrollDuration)
95
+ } else {
96
+ preventTocUpdate = false
97
+ markdownStore.setActiveToc()
98
+ }
99
+ }
100
+
101
+ onMounted(() => {
102
+ setTimeout(() => {
103
+ scrollToCurrentAnchor(true)
104
+ })
105
+ })
106
+
107
+ onBeforeUnmount(() => {
108
+ clearTimeout(scrollTimer)
109
+ })
110
+
111
+ return {
112
+ scrollTo,
113
+ onPageScroll,
114
+ }
115
+ }