docus 3.0.0-beta.1 → 3.0.0-beta.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 (145) hide show
  1. package/package.json +12 -19
  2. package/{app → theme/app}/router.options.ts +0 -0
  3. package/{assets → theme/assets}/css/fonts.css +0 -0
  4. package/theme/assets/css/main.css +104 -0
  5. package/{components → theme/components}/app/Container.vue +2 -0
  6. package/{components → theme/components}/app/Footer.vue +5 -3
  7. package/theme/components/app/MobileNav.vue +85 -0
  8. package/theme/components/app/Navbar.vue +37 -0
  9. package/{components → theme/components}/app/NavbarLogo.vue +5 -3
  10. package/{components → theme/components}/app/Page.vue +0 -0
  11. package/{components → theme/components}/app/PoweredByDocus.vue +0 -0
  12. package/{components → theme/components}/content/Alert.vue +0 -0
  13. package/{components → theme/components}/content/BlockHero.vue +0 -0
  14. package/{components → theme/components}/content/ButtonLink.vue +2 -1
  15. package/{components → theme/components}/content/Card.vue +0 -0
  16. package/{components → theme/components}/content/CardGrid.vue +0 -0
  17. package/{components → theme/components}/content/CodeBlock.vue +0 -0
  18. package/{components → theme/components}/content/CodeGroup.vue +7 -6
  19. package/{components → theme/components}/content/CopyButton.vue +1 -0
  20. package/{components → theme/components}/content/List.vue +0 -0
  21. package/{components → theme/components}/content/NeedContribution.vue +0 -0
  22. package/{components → theme/components}/content/ReadMore.vue +1 -0
  23. package/{components → theme/components}/content/Sandbox.vue +4 -2
  24. package/{components → theme/components}/content/TabsHeader.vue +2 -2
  25. package/{components → theme/components}/content/Terminal.vue +22 -28
  26. package/{components → theme/components}/content/VideoPlayer.vue +2 -0
  27. package/theme/components/dev/Debug.vue +65 -0
  28. package/{components → theme/components}/docs/DocsAside.vue +3 -1
  29. package/{components → theme/components}/docs/DocsAsideTree.vue +9 -6
  30. package/{components → theme/components}/docs/DocsHero.vue +0 -0
  31. package/{components → theme/components}/docs/DocsPage.vue +0 -1
  32. package/theme/components/docs/DocsPageContent.vue +32 -0
  33. package/{components → theme/components}/docs/DocsToc.vue +16 -11
  34. package/{components → theme/components}/globals/Icon.vue +2 -2
  35. package/{components → theme/components}/globals/Logo.vue +0 -0
  36. package/{components → theme/components}/globals/NuxtImg.vue +2 -0
  37. package/{components → theme/components}/globals/SocialIcons.vue +3 -1
  38. package/{components → theme/components}/globals/ThemeSelect.vue +3 -3
  39. package/{components → theme/components}/icons/IconAlgolia.vue +0 -0
  40. package/{components → theme/components}/icons/IconArrowLeft.vue +0 -0
  41. package/{components → theme/components}/icons/IconArrowRight.vue +0 -0
  42. package/{components → theme/components}/icons/IconBadgeCheck.vue +0 -0
  43. package/{components → theme/components}/icons/IconCheck.vue +0 -0
  44. package/{components → theme/components}/icons/IconCheckCircle.vue +0 -0
  45. package/{components → theme/components}/icons/IconChevronRight.vue +0 -0
  46. package/{components → theme/components}/icons/IconClipboardCheck.vue +0 -0
  47. package/{components → theme/components}/icons/IconClipboardCopy.vue +0 -0
  48. package/{components → theme/components}/icons/IconCodeSandbox.vue +0 -0
  49. package/{components → theme/components}/icons/IconCopy.vue +0 -0
  50. package/{components → theme/components}/icons/IconDots.vue +0 -0
  51. package/{components → theme/components}/icons/IconEdit.vue +0 -0
  52. package/{components → theme/components}/icons/IconExclamationCircle.vue +0 -0
  53. package/{components → theme/components}/icons/IconExclamationTriangle.vue +0 -0
  54. package/{components → theme/components}/icons/IconExternalLink.vue +0 -0
  55. package/{components → theme/components}/icons/IconGit.vue +0 -0
  56. package/{components → theme/components}/icons/IconGitHub.vue +0 -0
  57. package/{components → theme/components}/icons/IconHeart.vue +0 -0
  58. package/{components → theme/components}/icons/IconInformationCircle.vue +0 -0
  59. package/{components → theme/components}/icons/IconLighthouse.vue +0 -0
  60. package/{components → theme/components}/icons/IconLine.vue +0 -0
  61. package/{components → theme/components}/icons/IconMarkdown.vue +0 -0
  62. package/{components → theme/components}/icons/IconMenu.vue +0 -0
  63. package/{components → theme/components}/icons/IconMenuAlt.vue +0 -0
  64. package/{components → theme/components}/icons/IconMinus.vue +0 -0
  65. package/{components → theme/components}/icons/IconMoon.vue +0 -0
  66. package/{components → theme/components}/icons/IconNuxt.vue +0 -0
  67. package/{components → theme/components}/icons/IconNuxtContent.vue +0 -0
  68. package/{components → theme/components}/icons/IconNuxtLabs.vue +0 -0
  69. package/{components → theme/components}/icons/IconPlus.vue +0 -0
  70. package/{components → theme/components}/icons/IconPuzzle.vue +0 -0
  71. package/{components → theme/components}/icons/IconSSG.vue +0 -0
  72. package/{components → theme/components}/icons/IconSearch.vue +0 -0
  73. package/{components → theme/components}/icons/IconSun.vue +0 -0
  74. package/theme/components/icons/IconTailwind.vue +3 -0
  75. package/{components → theme/components}/icons/IconTocBack.vue +0 -0
  76. package/{components → theme/components}/icons/IconTocCurrent.vue +0 -0
  77. package/{components → theme/components}/icons/IconTocNext.vue +0 -0
  78. package/{components → theme/components}/icons/IconTranslate.vue +0 -0
  79. package/{components → theme/components}/icons/IconTwitter.vue +0 -0
  80. package/{components → theme/components}/icons/IconVite.vue +0 -0
  81. package/{components → theme/components}/icons/IconVue.vue +0 -0
  82. package/{components → theme/components}/icons/IconVueTelescope.vue +0 -0
  83. package/{components → theme/components}/icons/IconWindi.vue +0 -0
  84. package/{components → theme/components}/icons/IconX.vue +0 -0
  85. package/{components → theme/components}/icons/IconXCircle.vue +0 -0
  86. package/{components → theme/components}/icons/IconZap.vue +0 -0
  87. package/{components → theme/components}/prose/ProseA.vue +3 -3
  88. package/{components → theme/components}/prose/ProseBlockquote.vue +1 -1
  89. package/{components → theme/components}/prose/ProseCode.vue +3 -4
  90. package/{components → theme/components}/prose/ProseCodeInline.vue +2 -2
  91. package/{components → theme/components}/prose/ProseEm.vue +0 -0
  92. package/{components → theme/components}/prose/ProseH1.vue +0 -0
  93. package/{components → theme/components}/prose/ProseH2.vue +0 -0
  94. package/{components → theme/components}/prose/ProseH3.vue +0 -0
  95. package/{components → theme/components}/prose/ProseH4.vue +0 -0
  96. package/{components → theme/components}/prose/ProseHr.vue +2 -2
  97. package/theme/components/prose/ProseImg.vue +30 -0
  98. package/{components → theme/components}/prose/ProseLi.vue +2 -2
  99. package/{components → theme/components}/prose/ProseOl.vue +0 -0
  100. package/{components → theme/components}/prose/ProseP.vue +0 -0
  101. package/{components → theme/components}/prose/ProseStrong.vue +0 -0
  102. package/{components → theme/components}/prose/ProseTable.vue +0 -0
  103. package/{components → theme/components}/prose/ProseTbody.vue +0 -0
  104. package/{components → theme/components}/prose/ProseTd.vue +0 -0
  105. package/{components → theme/components}/prose/ProseTh.vue +1 -1
  106. package/{components → theme/components}/prose/ProseThead.vue +1 -1
  107. package/{components → theme/components}/prose/ProseTr.vue +1 -1
  108. package/{components → theme/components}/prose/ProseUl.vue +0 -0
  109. package/theme/composables/useDocus.ts +43 -0
  110. package/theme/composables/useMenu.ts +7 -0
  111. package/{composables → theme/composables}/useScrollToHeading.ts +0 -0
  112. package/{composables → theme/composables}/useScrollspy.ts +1 -0
  113. package/theme/composables/useUserAgent.ts +7 -0
  114. package/{composables/useTheme.ts → theme/composables/utils.ts} +0 -6
  115. package/{layouts → theme/layouts}/default.vue +7 -5
  116. package/{layouts → theme/layouts}/page.vue +9 -1
  117. package/theme/middleware/components.ts +26 -0
  118. package/theme/middleware/navigation.global.ts +12 -0
  119. package/theme/middleware/page.ts +8 -0
  120. package/theme/middleware/theme.global.ts +12 -0
  121. package/{nuxt.config.ts → theme/nuxt.config.ts} +84 -64
  122. package/theme/pages/[...slug].vue +64 -0
  123. package/theme/plugins/menu.ts +67 -0
  124. package/theme/plugins/user-agent.ts +27 -0
  125. package/theme/utils/components.ts +25 -0
  126. package/theme/utils/navigation.ts +49 -0
  127. package/theme/utils/plugin.ts +21 -0
  128. package/theme/utils/queries.ts +68 -0
  129. package/theme/utils/state.ts +33 -0
  130. package/theme/utils/theme.ts +66 -0
  131. package/assets/css/main.css +0 -11
  132. package/assets/css/tailwind.css +0 -282
  133. package/components/app/Navbar.vue +0 -26
  134. package/components/docs/DocsPageContent.vue +0 -29
  135. package/components/prose/ProseImg.vue +0 -32
  136. package/composables/useContent.ts +0 -155
  137. package/composables/useMenu.ts +0 -20
  138. package/pages/[...slug].vue +0 -24
  139. package/public/android-chrome-192x192.png +0 -0
  140. package/public/android-chrome-512x512.png +0 -0
  141. package/public/apple-touch-icon.png +0 -0
  142. package/public/favicon-16x16.png +0 -0
  143. package/public/favicon-32x32.png +0 -0
  144. package/public/favicon.ico +0 -0
  145. package/public/site.webmanifest +0 -1
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.0.0-beta.1",
2
+ "version": "3.0.0-beta.10",
3
3
  "name": "docus",
4
4
  "scripts": {
5
5
  "build": "nuxi build",
@@ -8,12 +8,13 @@
8
8
  "lint": "eslint --ext .ts,.js,.vue,.css ."
9
9
  },
10
10
  "devDependencies": {
11
- "@antfu/eslint-config": "^0.20.6",
11
+ "@antfu/eslint-config": "^0.21.1",
12
12
  "@nuxtjs/eslint-config-typescript": "^9.0.0",
13
- "eslint": "^8.13.0",
14
- "nuxt": "^3.0.0-rc.1",
13
+ "eslint": "^8.14.0",
14
+ "jiti": "^1.13.0",
15
+ "nuxt": "npm:nuxt3@latest",
15
16
  "parse-entities": "^4.0.0",
16
- "typescript": "^4.6.3"
17
+ "typescript": "^4.6.4"
17
18
  },
18
19
  "dependencies": {
19
20
  "@iconify/vue": "^3.2.1",
@@ -23,10 +24,11 @@
23
24
  "@nuxtjs/tailwindcss": "^5.0.3",
24
25
  "@tailwindcss/aspect-ratio": "^0.4.0",
25
26
  "@tailwindcss/forms": "^0.5.0",
26
- "@tailwindcss/line-clamp": "^0.3.1",
27
+ "@tailwindcss/line-clamp": "^0.4.0",
27
28
  "@tailwindcss/typography": "^0.5.2",
28
- "@vueuse/core": "^8.3.0",
29
+ "@vueuse/core": "^8.3.1",
29
30
  "@vueuse/motion": "2.0.0-beta.12",
31
+ "@vueuse/nuxt": "^8.3.1",
30
32
  "clipboard": "^2.0.10",
31
33
  "defu": "^6.0.0",
32
34
  "lodash-es": "^4.17.21",
@@ -35,20 +37,11 @@
35
37
  },
36
38
  "main": "./nuxt.config.ts",
37
39
  "exports": {
38
- ".": {
39
- "require": "./nuxt.config.ts",
40
- "import": "./nuxt.config.ts"
41
- }
40
+ "./theme": "./theme/nuxt.config.ts",
41
+ "./theme/*": "./theme/*/*.*"
42
42
  },
43
43
  "files": [
44
44
  "README.md",
45
- "app",
46
- "assets",
47
- "components",
48
- "composables",
49
- "layouts",
50
- "pages",
51
- "public",
52
- "nuxt.config.ts"
45
+ "theme"
53
46
  ]
54
47
  }
File without changes
File without changes
@@ -0,0 +1,104 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /* Variables */
6
+ :root {
7
+ --header-height: 4rem;
8
+ --codeblocks-background: theme('colors.gray.900');
9
+ }
10
+
11
+ @layer components {
12
+ /* Text primary */
13
+
14
+ .text-primary {
15
+ @apply text-gray-900 dark:text-gray-50;
16
+ }
17
+
18
+ /* Text secondary */
19
+
20
+ .text-secondary {
21
+ @apply text-gray-500 dark:text-gray-400;
22
+ }
23
+
24
+ .text-secondary-active {
25
+ @apply text-primary-500 dark:text-primary-400;
26
+ }
27
+
28
+ .text-secondary-hover {
29
+ @apply hover:text-primary-500 hover:dark:text-primary-400;
30
+ }
31
+
32
+ .text-secondary-group-hover {
33
+ @apply group-hover:dark:text-primary-400 group-hover:text-primary-500;
34
+ }
35
+
36
+ /* Transitions */
37
+
38
+ .transition-base {
39
+ @apply transition-colors transition-opacity duration-100 ease-in-out;
40
+ }
41
+
42
+ /* Surface */
43
+
44
+ .surface {
45
+ @apply dark:bg-gray-900 bg-white;
46
+ }
47
+
48
+ .surface-secondary {
49
+ @apply bg-gray-500 dark:bg-gray-400;
50
+ }
51
+
52
+ .blurry-surface {
53
+ @apply backdrop-blur bg-white/95 dark:bg-gray-900/95;
54
+ }
55
+
56
+ /* Borders */
57
+
58
+ .surface-border {
59
+ @apply border-gray-200 dark:border-gray-800;
60
+ }
61
+
62
+ .surface-border-hover {
63
+ @apply border-primary-200 dark:border-gray-700;
64
+ }
65
+
66
+ .surface-border-header {
67
+ @apply border-b border-gray-200 dark:border-gray-800 border-opacity-50;
68
+ }
69
+
70
+ /* Icons */
71
+
72
+ .icon-base {
73
+ @apply transition-base text-secondary text-secondary-hover;
74
+ }
75
+
76
+ /* Code blocks */
77
+
78
+ .code-background {
79
+ /* background-color: var(--codeblocks-background); */
80
+ @apply bg-gray-800;
81
+ }
82
+
83
+ /* Images */
84
+
85
+ .light-img {
86
+ @apply dark:hidden;
87
+ }
88
+
89
+ .dark-img {
90
+ @apply hidden;
91
+ }
92
+ }
93
+
94
+ html {
95
+ @apply text-primary bg-white overflow-y-scroll;
96
+
97
+ &.dark {
98
+ @apply bg-gray-900;
99
+ }
100
+ }
101
+
102
+ body {
103
+ @apply antialiased font-sans text-gray-700 dark:text-gray-200;
104
+ }
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ import { classNames, computed } from '#imports'
3
+
2
4
  const props = defineProps({
3
5
  padded: {
4
6
  type: Boolean,
@@ -1,14 +1,16 @@
1
1
  <script setup lang="ts">
2
- const { footer } = useTheme()
2
+ import { computed, useDocus } from '#imports'
3
3
 
4
- const icons = computed(() => footer?.icons || [])
4
+ const { theme } = useDocus()
5
+
6
+ const icons = computed(() => theme.value?.footer?.icons || [])
5
7
  </script>
6
8
 
7
9
  <template>
8
10
  <footer class="py-6 sm:py-0 bg-gray-50 dark:bg-gray-800 dark:bg-opacity-25 h-[8rem] sm:h-[4rem]">
9
11
  <Container class="flex h-full flex-col gap-y-4 sm:flex-row justify-between items-center">
10
12
  <a
11
- v-if="footer.credits"
13
+ v-if="theme.footer.credits"
12
14
  href="https://nuxtlabs.com"
13
15
  rel="noopener"
14
16
  target="_blank"
@@ -0,0 +1,85 @@
1
+ <script setup lang="ts">
2
+ import { computed, useDocus, useMenu, useUserAgent, watch } from '#imports'
3
+
4
+ const { navigation } = useDocus()
5
+
6
+ const tree = computed(() => {
7
+ return navigation.value.filter(
8
+ (item) => {
9
+ if (item.slug === '/' || item.slug === '/templates')
10
+ return false
11
+ return true
12
+ },
13
+ )
14
+ })
15
+
16
+ const { scrollBarGap, visible, open, close, toggle } = useMenu()
17
+
18
+ const { isDesktopSafari, isDesktopFirefox } = useUserAgent()
19
+
20
+ const buttonStyles = 'w-12 h-8 focus:outline-none bg-warmgray-50 hover:bg-warmgray-100 dark:bg-warmgray-800 rounded-xl'
21
+
22
+ watch(visible, v => (v ? open() : close()))
23
+
24
+ // Necessary because of body lock layout shift
25
+ const buttonBodyLockHack = computed(
26
+ () => `top: 1rem; right: calc(1.5rem + ${isDesktopSafari.value || isDesktopFirefox.value ? scrollBarGap.value : 0}px);`,
27
+ )
28
+
29
+ const surfaceBodyLockHack = computed(
30
+ () => `top: 0.5rem; right: calc(1rem + ${isDesktopSafari.value || isDesktopFirefox.value ? scrollBarGap.value : 0}px); bottom: 0.5rem; max-height: calc(100vh- 2rem); min-width: calc(320px - 2rem);`,
31
+ )
32
+ </script>
33
+
34
+ <template>
35
+ <div class="relative">
36
+ <button :class="[buttonStyles]" class="z-10 relative" @click="toggle">
37
+ <IconDots class="w-6 h-6 icon-base h-full mx-auto" />
38
+ </button>
39
+
40
+ <ClientOnly>
41
+ <teleport to="body">
42
+ <!-- Scrim overlay -->
43
+ <div
44
+ :class="[visible ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none']"
45
+ class="xl:hidden fixed top-0 left-0 z-10 w-full h-full bg-warmgray-100 bg-opacity-50 dark:bg-warmgray-800 dark:bg-opacity-50 backdrop-blur transition"
46
+ @click="toggle"
47
+ />
48
+
49
+ <!-- clone AppHeader button, due to stacking context limitations -->
50
+ <button
51
+ :style="buttonBodyLockHack"
52
+ :class="[
53
+ buttonStyles,
54
+ visible
55
+ ? 'opacity-100 pointer-events-auto'
56
+ : `opacity-0 transition ${
57
+ isDesktopSafari || isDesktopFirefox ? 'duration-0' : 'duration-400'
58
+ } pointer-events-none`
59
+ ]"
60
+ class="xl:hidden z-30 fixed"
61
+ @click="toggle"
62
+ >
63
+ <IconLine class="w-6 h-6 icon-base h-full mx-auto" />
64
+ </button>
65
+
66
+ <!-- Nav menu surface -->
67
+ <div
68
+ :style="surfaceBodyLockHack"
69
+ :class="[visible ? 'opacity-100 scale-100 pointer-events-auto' : 'opacity-0 scale-95 pointer-events-none']"
70
+ class="fixed z-20 w-[calc(100%-3rem)] md:w-auto min-w-full md:min-w-[calc(320px-2rem)] transform origin-top-right transition-transform ease-out"
71
+ >
72
+ <div
73
+ class="lg:hidden pl-8 pr-0 overflow-y-auto mb-2 surface pb-6 pt-12 rounded-2xl shadow-xl border-2 surface-border max-h-full"
74
+ >
75
+ <DocsAsideTree :tree="tree" />
76
+
77
+ <div class="flex items-center justify-end px-6">
78
+ <ThemeSelect class="block" />
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </teleport>
83
+ </ClientOnly>
84
+ </div>
85
+ </template>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, onUnmounted, ref } from '#imports'
3
+
4
+ const onTop = ref(true)
5
+
6
+ function setOnTop(): void {
7
+ if (window.pageYOffset <= 0)
8
+ onTop.value = true
9
+ else onTop.value = false
10
+ }
11
+
12
+ onMounted(() => {
13
+ setOnTop()
14
+ document.addEventListener('scroll', setOnTop)
15
+ })
16
+
17
+ onUnmounted(() => document.removeEventListener('scroll', setOnTop))
18
+ </script>
19
+
20
+ <template>
21
+ <header class="sticky w-full top-0 surface surface-blurry border-b border-gray-200 dark:border-gray-800 border-opacity-50 h-header surface surface-blurry z-10">
22
+ <Container class="grid grid-cols-12 items-center h-full">
23
+ <div class="col-span-6 lg:col-span-3">
24
+ <NavbarLogo />
25
+ </div>
26
+
27
+ <div class="hidden lg:block lg:col-span-6">
28
+ <!-- <HeaderNavigation /> -->
29
+ </div>
30
+
31
+ <div class="col-span-6 lg:col-span-3 flex justify-end">
32
+ <MobileNav class="flex lg:hidden" />
33
+ <ThemeSelect class="hidden lg:block" />
34
+ </div>
35
+ </Container>
36
+ </header>
37
+ </template>
@@ -1,7 +1,9 @@
1
1
  <script setup lang="ts">
2
- const theme = useTheme()
3
- const hasLogo = computed(() => theme.header.logo)
4
- const hasTitle = computed(() => theme.header.title)
2
+ import { computed, useDocus } from '#imports'
3
+
4
+ const { theme } = useDocus()
5
+ const hasLogo = computed(() => theme.value?.header?.logo)
6
+ const hasTitle = computed(() => theme.value?.header?.title)
5
7
  </script>
6
8
 
7
9
  <template>
File without changes
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { hasProtocol } from 'ufo'
3
+ import { computed } from '#imports'
3
4
 
4
5
  const props = defineProps({
5
6
  href: {
@@ -31,7 +32,7 @@ const isExternal = computed(
31
32
 
32
33
  <style lang="postcss" scoped>
33
34
  a.button-link {
34
- @apply inline-flex items-center flex-none rounded-md px-3 py-1.5 text-sm leading-4 text-white transition-colors duration-200 border border-transparent bg-primary-500 hover:bg-primary-600 focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900 focus:ring-primary-600 focus:outline-none;
35
+ @apply inline-flex items-center flex-none rounded-lg px-3 py-1.5 text-sm leading-4 text-white transition-colors duration-200 border border-transparent bg-primary-500 hover:bg-primary-600 focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900 focus:ring-primary-600 focus:outline-none;
35
36
 
36
37
  &.medium {
37
38
  @apply px-4 py-2 text-base leading-4;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import TabsHeader from './TabsHeader.vue'
3
+ import { defineComponent } from '#imports'
3
4
 
4
5
  const isTag = (slot: any, tag: string) => {
5
6
  return slot.type && slot.type.tag && slot.type.tag === tag
@@ -90,18 +91,16 @@ export default defineComponent({
90
91
  </script>
91
92
 
92
93
  <style lang="postcss">
93
- .prose {
94
- li {
95
- .code-group {
94
+ li {
95
+ .code-group {
96
96
  @apply my-4;
97
- }
98
97
  }
99
98
  }
100
99
 
101
100
  html.dark {
102
101
  .code-group-content {
103
102
  .preview-canvas {
104
- @apply p-4 my-0 overflow-x-auto leading-normal bg-gray-900 rounded-lg rounded-tl-none rounded-tr-none z-0;
103
+ @apply p-4 my-0 overflow-x-auto leading-normal bg-gray-900 rounded-bl-lg rounded-br-lg rounded-tl-none rounded-tr-none z-0;
105
104
  }
106
105
  }
107
106
  }
@@ -109,8 +108,10 @@ html.dark {
109
108
 
110
109
  <style scoped lang="postcss">
111
110
  .code-group {
111
+ @apply rounded-lg overflow-hidden border-2 surface-border;
112
+
112
113
  :deep(.prose-code) {
113
- @apply mt-0 rounded-tl-none rounded-tr-none !important;
114
+ @apply mt-0 mb-0 rounded-none !important;
114
115
  }
115
116
 
116
117
  :deep(pre) {
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import Clipboard from 'clipboard'
3
+ import { onMounted, ref } from '#imports'
3
4
 
4
5
  const copy = ref()
5
6
  const state = ref('init')
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import { splitByCase, upperFirst } from 'scule'
3
+ import { computed } from '#imports'
3
4
 
4
5
  const props = defineProps({
5
6
  link: {
@@ -1,4 +1,6 @@
1
1
  <script setup lang="ts">
2
+ import { computed, onMounted, ref, useColorMode } from '#imports'
3
+
2
4
  const props = defineProps({
3
5
  src: {
4
6
  type: String,
@@ -62,7 +64,7 @@ onMounted(() => {
62
64
  </script>
63
65
 
64
66
  <template>
65
- <div class="w-full min-h-[500px] mx-auto mb-6 overflow-hidden text-3xl rounded-md sandbox mt-4">
67
+ <div class="w-full min-h-[500px] mx-auto mb-6 overflow-hidden text-3xl rounded-lg sandbox mt-4">
66
68
  <TabsHeader
67
69
  v-if="!src"
68
70
  ref="tabs"
@@ -94,7 +96,7 @@ onMounted(() => {
94
96
  <style lang="postcss" scoped>
95
97
  .sandbox,
96
98
  .sandbox iframe {
97
- @apply w-full rounded-md rounded-tl-none rounded-tr-none overflow-hidden h-64;
99
+ @apply w-full rounded-lg rounded-tl-none rounded-tr-none overflow-hidden h-64;
98
100
  height: 700px;
99
101
  }
100
102
  </style>
@@ -16,7 +16,7 @@ defineEmits(['update:activeTabIndex'])
16
16
  </script>
17
17
 
18
18
  <template>
19
- <div class="relative text-white rounded-t-lg bg-gray-200 dark:bg-gray-700">
19
+ <div class="relative text-white bg-gray-200 dark:bg-gray-700">
20
20
  <div v-if="tabs" class="relative z-0 px-2">
21
21
  <button
22
22
  v-for="({ label }, i) in tabs"
@@ -29,7 +29,7 @@ defineEmits(['update:activeTabIndex'])
29
29
  {{ label }}
30
30
  </button>
31
31
  <span ref="highlight-underline" class="absolute -z-[1] highlight-underline h-full xs:py-1.5">
32
- <span class="flex w-full h-full bg-gray-300 dark:bg-gray-600 rounded-md" />
32
+ <span class="flex w-full h-full bg-gray-300 dark:bg-gray-600 rounded-lg" />
33
33
  </span>
34
34
  </div>
35
35
  </div>
@@ -1,40 +1,34 @@
1
- <script>
1
+ <script setup lang="ts">
2
2
  import Clipboard from 'clipboard'
3
+ import { nextTick, onMounted, ref } from '#imports'
3
4
 
4
- export default defineComponent({
5
- props: {
6
- snippet: {
7
- type: String,
8
- required: true,
9
- },
5
+ const props = defineProps({
6
+ snippet: {
7
+ type: String,
8
+ required: true,
10
9
  },
11
- setup() {
12
- const copyInstall = ref()
13
- const copied = ref(false)
10
+ })
14
11
 
15
- const setupCopyInstall = () => {
16
- if (!copyInstall.value)
17
- return nextTick(setupCopyInstall)
12
+ const copyInstall = ref()
13
+ const copied = ref(false)
18
14
 
19
- const instance = new Clipboard(copyInstall.value)
15
+ const setupCopyInstall = () => {
16
+ if (!copyInstall.value)
17
+ return nextTick(setupCopyInstall)
20
18
 
21
- instance.on('success', () => {
22
- copied.value = true
19
+ const instance = new Clipboard(copyInstall.value)
23
20
 
24
- setTimeout(() => {
25
- copied.value = false
26
- }, 1000)
27
- })
28
- }
21
+ instance.on('success', () => {
22
+ copied.value = true
29
23
 
30
- onMounted(() => setupCopyInstall())
24
+ setTimeout(() => {
25
+ copied.value = false
26
+ }, 1000)
27
+ })
28
+ }
29
+
30
+ onMounted(() => setupCopyInstall())
31
31
 
32
- return {
33
- copyInstall,
34
- copied,
35
- }
36
- },
37
- })
38
32
  </script>
39
33
 
40
34
  <template>
@@ -1,4 +1,6 @@
1
1
  <script lang="ts" setup>
2
+ import { ref } from '#imports'
3
+
2
4
  const props = defineProps({
3
5
  poster: {
4
6
  type: String,
@@ -0,0 +1,65 @@
1
+ <script setup lang="ts">
2
+ import type { ParsedContent } from '@nuxt/content/dist/runtime/types'
3
+ import type { ThemeDebugConfig } from '../../utils/theme'
4
+ import { computed, useDocus } from '#imports'
5
+
6
+ const { page, navigation, theme } = useDocus()
7
+
8
+ const defaultConfig: ThemeDebugConfig = {
9
+ page: true,
10
+ navigation: true,
11
+ theme: true,
12
+ }
13
+
14
+ const config = computed(
15
+ () => {
16
+ const _config = theme.value?.debug
17
+
18
+ if (typeof _config === 'object')
19
+ return Object.assign(defaultConfig, _config)
20
+
21
+ if (_config === true)
22
+ return defaultConfig
23
+
24
+ if (_config === false)
25
+ return _config
26
+ },
27
+ )
28
+
29
+ const icons = {
30
+ page: '📃',
31
+ navigation: '🔖',
32
+ theme: '🎨',
33
+ }
34
+
35
+ Object.entries({
36
+ page,
37
+ navigation,
38
+ theme,
39
+ }).forEach(([key, reference]) => {
40
+ if (!config.value || !config.value?.[key])
41
+ return
42
+
43
+ watchDebounced(
44
+ reference,
45
+ () => {
46
+ if (key === 'page')
47
+ // eslint-disable-next-line no-console
48
+ console.log(`[${icons[key]}] Page updates detected! ${`(${(reference.value as ParsedContent)?.title})` || `(${(reference.value as ParsedContent)?.id})` || ''}`)
49
+ else
50
+ // eslint-disable-next-line no-console
51
+ console.log(`[${icons[key]}] ${key[0].toUpperCase() + key.slice(1, key.length)} updates detected!`)
52
+
53
+ // eslint-disable-next-line no-console
54
+ console.dir({ ...reference.value })
55
+ },
56
+ {
57
+ debounce: 100,
58
+ },
59
+ )
60
+ })
61
+ </script>
62
+
63
+ <template>
64
+ <div class="hidden" />
65
+ </template>
@@ -1,5 +1,7 @@
1
1
  <script setup lang="ts">
2
- const { navigation } = useContent()
2
+ import { computed, useDocus } from '#imports'
3
+
4
+ const { navigation } = useDocus()
3
5
 
4
6
  const tree = computed(() => {
5
7
  return navigation.value.filter(
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { PropType } from 'vue'
3
+ import { reactive, useRoute, useRouter, watch } from '#imports'
3
4
 
4
5
  const props = defineProps({
5
6
  tree: {
@@ -29,7 +30,7 @@ function isActive(link) {
29
30
  function onClick(link) {
30
31
  if (link.children?.length) {
31
32
  // Open dir when element is collapsible
32
- openDir(link.slug)
33
+ toggleDir(link.slug)
33
34
 
34
35
  // Select element for mobile nav
35
36
  if (props.max !== null && props.level + 1 === props.max)
@@ -41,7 +42,7 @@ function onClick(link) {
41
42
  }
42
43
  }
43
44
 
44
- function openDir(slug, force?) {
45
+ function toggleDir(slug, force?) {
45
46
  isChildOpen[slug] = force ? true : !isChildOpen[slug]
46
47
  }
47
48
 
@@ -49,10 +50,12 @@ watch(
49
50
  () => route.path,
50
51
  () => {
51
52
  const paths = route.path.split('/')
52
- for (let i = paths.length - 1; i > 1; i--) {
53
+ for (let i = paths.length; i > 1; i--) {
53
54
  paths.pop()
54
- openDir(paths.join('/'), true)
55
+ toggleDir(paths.join('/'), true)
55
56
  }
57
+
58
+ toggleDir(route.path, true)
56
59
  },
57
60
  { immediate: true },
58
61
  )
@@ -70,11 +73,11 @@ watch(
70
73
  }"
71
74
  >
72
75
  <NuxtLink
73
- class="block py-1.5 flex items-center justify-between focus:outline-none cursor-pointer font-semibold"
76
+ class="block py-1.5 flex items-center justify-between focus:outline-none cursor-pointer"
74
77
  :exact="link.exact"
75
78
  :class="{
76
79
  'pl-4': level > 0,
77
- 'text-xl !text-primary': level === 0,
80
+ 'text-xl !text-primary font-bold': level === 0,
78
81
  '!pt-0': level === 0 && index === 0,
79
82
  'text-secondary-active': isActive(link),
80
83
  'text-secondary text-secondary-hover': !isActive(link)