@wordup-md/nuxt-layer-shadcn-unocss 0.2.26 → 0.2.28

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.
@@ -25,41 +25,41 @@ Add `:` before the key to bind the frontmatter value to the component.\
25
25
  Or use the `{{ $doc.key }}` syntax to bind the value of the frontmatter.
26
26
 
27
27
  ::stack
28
- ::div{class="p-4"}
29
- This is the title from the frontmatter: **Title of the page**.
30
-
31
- ::alert
28
+ :::div{.p-4}
29
+ This is the title from the frontmatter: **Title of the page**.
30
+
31
+ ::::alert
32
32
  ---
33
33
  :type: key
34
34
  ---
35
35
  With the property `:type: key`, it displays a **{{ $doc.key }} alert**.
36
- ::
37
-
38
- Or inline:
39
-
40
- :alert[Title of the page]{:type="key" :icon="icon"}
41
- ::
36
+ ::::
37
+
38
+ Or inline:
39
+
40
+ :alert[Title of the page]{:icon="icon" :type="key"}
41
+ :::
42
42
 
43
- ```mdc
44
- ---
45
- title: Title of the page
46
- icon: lucide:file
47
- key: example
48
- ---
43
+ ```mdc
44
+ ---
45
+ title: Title of the page
46
+ icon: lucide:file
47
+ key: example
48
+ ---
49
49
 
50
- This is the title from the frontmatter: **{{ $doc.title }}**.
50
+ This is the title from the frontmatter: **{{ $doc.title }}**.
51
51
 
52
- ::alert
53
- ---
54
- :type: key
55
- ---
56
- With the property `:type: key`, it displays a **{{ $doc.key }} alert**.
57
- ::
52
+ ::alert
53
+ ---
54
+ :type: key
55
+ ---
56
+ With the property `:type: key`, it displays a **{{ $doc.key }} alert**.
57
+ ::
58
58
 
59
- Or inline:
59
+ Or inline:
60
60
 
61
- :alert[{{ $doc.title }}]{:type="key" :icon="icon"}
62
- ```
61
+ :alert[{{ $doc.title }}]{:type="key" :icon="icon"}
62
+ ```
63
63
  ::
64
64
 
65
65
  ## Available Frontmatter Attributes
@@ -98,80 +98,95 @@ authors:
98
98
  ## Showcases
99
99
 
100
100
  ::tabs{variant="line"}
101
- ::stack{label="badges"}
102
- ![badges-showcase](/front-matter-showcase/badges.png){class="w-full"}
103
- ```yml
104
- badges:
105
- - value: 0.8.10
106
- - value: Source
107
- icon: lucide:code
108
- to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss/blob/main/components/content/FileTree.vue
109
- target: _blank
110
- ```
111
- ::
112
-
113
- ::stack{label="authors"}
114
- ![authors-showcase](/front-matter-showcase/authors.png){class="w-full"}
115
- ```yml
116
- authors:
117
- - name: Tony Zhang
118
- username: ZTL-UwU
119
- avatar: https://www.github.com/ZTL-UwU.png
120
- to: https://github.com/ZTL-UwU
121
- target: _blank
122
- ```
123
- ::
124
-
125
- ::stack{label="navBadges"}
126
- ![nav-badges-showcase](/front-matter-showcase/nav-badges.png){class="w-full"}
127
- ```yml
128
- navBadges:
129
- - value: New
130
- type: lime
131
- ```
132
- ::
101
+ :::stack{label="badges"}
102
+ ![badges-showcase](/front-matter-showcase/badges.png){.w-full}
103
+
104
+ ```yml
105
+ badges:
106
+ - value: 0.8.10
107
+ - value: Source
108
+ icon: lucide:code
109
+ to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss/blob/main/components/content/FileTree.vue
110
+ target: _blank
111
+ ```
112
+ :::
113
+
114
+ :::stack{label="authors"}
115
+ ![authors-showcase](/front-matter-showcase/authors.png){.w-full}
116
+
117
+ ```yml
118
+ authors:
119
+ - name: Tony Zhang
120
+ username: ZTL-UwU
121
+ avatar: https://www.github.com/ZTL-UwU.png
122
+ to: https://github.com/ZTL-UwU
123
+ target: _blank
124
+ ```
125
+ :::
126
+
127
+ :::stack{label="navBadges"}
128
+ ![nav-badges-showcase](/front-matter-showcase/nav-badges.png){.w-full}
129
+
130
+ ```yml
131
+ navBadges:
132
+ - value: New
133
+ type: lime
134
+ ```
135
+ :::
133
136
  ::
134
137
 
135
138
  ## Parameters
136
139
 
137
140
  ::field-group
138
- ::field{name="title" type="string"}
141
+ :::field{name="title" type="string"}
139
142
  Title of the page. Defaults to the filename.
140
- ::
141
- ::field{name="description" type="string"}
142
- Description of the page. Defaults to the first `<p>`{lang="html"} of the page.
143
- ::
144
- ::field{name="navigation" type="boolean" default-value="true"}
143
+ :::
144
+
145
+ :::field{name="description" type="string"}
146
+ Description of the page. Defaults to the first `<p>` of the page.
147
+ :::
148
+
149
+ :::field{default-value="true" name="navigation" type="boolean"}
145
150
  Define if the page is included in the sidebar. Set it to `false` in `index.md`.
146
- ::
147
- ::field{name="icon" type="string"}
151
+ :::
152
+
153
+ :::field{name="icon" type="string"}
148
154
  The icon shown in the sidebar for the page.
149
- ::
150
- ::field{name="navBadges" type="[]"}
155
+ :::
156
+
157
+ :::field{name="navBadges" type="[]"}
151
158
  A list of badges appended to the end of the sidebar link.
152
- ::
153
- ::field{name="navTruncate" type="boolean" default-value="true"}
159
+ :::
160
+
161
+ :::field{default-value="true" name="navTruncate" type="boolean"}
154
162
  Whether to truncate the sidebar title.
155
- ::
156
- ::field{name="badges" type="[]"}
163
+ :::
164
+
165
+ :::field{name="badges" type="[]"}
157
166
  A list of badges shown at the bottom of page title.
158
- ::
159
- ::field{name="authors" type="[]"}
167
+ :::
168
+
169
+ :::field{name="authors" type="[]"}
160
170
  A list of authors shown at the bottom of page title.
161
- ::
162
- ::field{name="toc" type="boolean" default-value="true"}
171
+ :::
172
+
173
+ :::field{default-value="true" name="toc" type="boolean"}
163
174
  Whether to show the toc section for this page.
164
- ::
165
- ::field{name="aside" type="boolean" default-value="true"}
175
+ :::
176
+
177
+ :::field{default-value="true" name="aside" type="boolean"}
166
178
  Whether to show the aside section for this page.
167
- ::
168
- ::field{name="editLink" type="boolean" default-value="true"}
179
+ :::
180
+
181
+ :::field{default-value="true" name="editLink" type="boolean"}
169
182
  Whether to show the edit link for this page.
170
- ::
171
- ::field{name="prevNext" type="boolean" default-value="true"}
183
+ :::
184
+
185
+ :::field{default-value="true" name="prevNext" type="boolean"}
172
186
  Whether to show the previous & next page buttons.
173
- ::
174
- ::field{name="breadcrumb" type="boolean" default-value="true"}
187
+ :::
188
+
189
+ :::field{default-value="true" name="breadcrumb" type="boolean"}
175
190
  Whether to show the breadcrumb.
176
- ::
191
+ :::
177
192
  ::
@@ -4,7 +4,7 @@ export default defineNuxtConfig({
4
4
  extends: ['..'],
5
5
  modules: [
6
6
  '@nuxt/eslint',
7
- '@unpress/nuxt-module',
7
+ // '@unpress/nuxt-module',
8
8
  // '../../../unpress/packages/nuxt-module/src/module',
9
9
  ],
10
10
 
@@ -51,7 +51,7 @@ export default defineNuxtConfig({
51
51
  },
52
52
 
53
53
  unpress: {
54
- repo: 'https://github.com/wordup-md/nuxt-layer-shadcn-unocss',
54
+ // repo: 'https://gitlab.com/ManUtopiK/nuxt-layer/-/tree/gitlab',
55
55
  autoMountIfDevMode: true,
56
56
  allowMountWithoutLogin: true,
57
57
  },
@@ -38,7 +38,7 @@
38
38
  }
39
39
 
40
40
  & pre {
41
- --at-apply: "p-3 rounded-lg border bg-muted/30! text-card-foreground shadow-sm overflow-x-auto";
41
+ --at-apply: "my-5! p-3 rounded-lg border bg-muted/30! text-card-foreground shadow-sm overflow-x-auto";
42
42
 
43
43
  & code {
44
44
  --at-apply: "bg-transparent p-0 border-none";
@@ -49,7 +49,7 @@
49
49
  --at-apply: "rounded-none border-b-none border-l-none border-r-none shadow-none";
50
50
  }
51
51
  .FRONTMATTER pre {
52
- --at-apply: "rounded-none border-none shadow-none bg-transparent";
52
+ --at-apply: "my-0! rounded-none border-none shadow-none bg-transparent";
53
53
  }
54
54
 
55
55
  & > div {
@@ -1,14 +1,38 @@
1
1
  <template>
2
2
  <div class="group relative">
3
3
  <UiEditorDropdown
4
- v-model="mdcAttrs.type"
5
4
  chevron
6
5
  tooltip="Type"
7
6
  placement="bottom-start"
8
- :items="types"
9
7
  class="absolute left-3 top--2 z-10 opacity-0 border rounded pl-2 pr-1 transition-opacity group-hover:opacity-100 bg-background"
10
8
  >
11
9
  <span class="text-xs font-mono capitalize">{{ model.type }}</span>
10
+ <template #menu>
11
+ <UiEditorMenuItem
12
+ v-for="item of types"
13
+ :key="item"
14
+ :label="item"
15
+ :pressed="mdcAttrs.type === item"
16
+ class="mb-0.5 last:mb-0"
17
+ @click="mdcAttrs.type = item"
18
+ />
19
+ <hr
20
+ v-if="filteredFrontmatter.length > 0"
21
+ class="my-1"
22
+ >
23
+ <UiEditorMenuItem
24
+ v-for="[key, value] of filteredFrontmatter"
25
+ :key="key"
26
+ :label="`${key}: ${value}`"
27
+ :pressed="mdcAttrs.type === `:${key}`"
28
+ class="mb-0.5 last:mb-0 fmkeys"
29
+ @click="mdcAttrs.type = `:${key}`"
30
+ >
31
+ <template #label>
32
+ {{ key }}: <strong>{{ value }}</strong>
33
+ </template>
34
+ </UiEditorMenuItem>
35
+ </template>
12
36
  </UiEditorDropdown>
13
37
 
14
38
  <Alert
@@ -27,10 +51,12 @@
27
51
  import type { VueNodeViewProps } from 'prosekit/vue'
28
52
 
29
53
  const props = defineProps<VueNodeViewProps>()
30
- const { getComponentProps } = useMdcEditor()
54
+ const { getComponentProps, frontmatter } = useMdcEditor()
31
55
 
32
56
  const types = ['default', 'info', 'success', 'warning', 'danger', 'example', 'secondary']
33
57
 
58
+ const filteredFrontmatter = computed(() => Object.entries(frontmatter.value).filter(([key, value]) => types.includes(value as string)))
59
+
34
60
  const { model, mdcAttrs } = getComponentProps(props, {
35
61
  id: {
36
62
  type: String,
@@ -62,3 +88,13 @@ const { model, mdcAttrs } = getComponentProps(props, {
62
88
  },
63
89
  })
64
90
  </script>
91
+
92
+ <style scoped>
93
+ .fmkeys :deep(div) {
94
+ @apply first-letter:lowercase! font-mono;
95
+ }
96
+ :deep(p) {
97
+ margin-top: 0;
98
+ margin-bottom: 0;
99
+ }
100
+ </style>
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <section
3
3
  :ref="props.contentRef"
4
- v-bind="model"
5
4
  />
6
5
  </template>
7
6
 
@@ -9,14 +8,14 @@
9
8
  import type { VueNodeViewProps } from 'prosekit/vue'
10
9
 
11
10
  const props = defineProps<VueNodeViewProps>()
12
- const { getComponentProps } = useMdcEditor()
13
- const { model } = getComponentProps(props, {
14
- id: {
15
- type: String,
16
- },
17
- class: {
18
- type: String,
19
- default: '',
20
- },
21
- })
11
+ // const { getComponentProps } = useMdcEditor()
12
+ // const { model } = getComponentProps(props, {
13
+ // id: {
14
+ // type: String,
15
+ // },
16
+ // class: {
17
+ // type: String,
18
+ // default: '',
19
+ // },
20
+ // })
22
21
  </script>
@@ -46,14 +46,15 @@
46
46
  v-if="!config.search.inAside && config.search.style === 'button'"
47
47
  />
48
48
 
49
+ <LangSwitcher v-if="i18nEnabled" />
49
50
  <ThemePopover v-if="config.theme.customizable" />
50
51
  <DarkModeToggle v-if="config.header.darkModeToggle" />
51
52
  <A11yModeToggle />
52
53
 
53
- <NuxtLink
54
+ <NuxtLinkLocale
54
55
  v-for="(link, i) in config.header.links"
55
56
  :key="i"
56
- :to="link?.to"
57
+ :to="localePath(link?.to)"
57
58
  :target="link?.target"
58
59
  >
59
60
  <UiButton
@@ -67,7 +68,7 @@
67
68
  :size="18"
68
69
  />
69
70
  </UiButton>
70
- </NuxtLink>
71
+ </NuxtLinkLocale>
71
72
  </div>
72
73
  </div>
73
74
  </div>
@@ -86,6 +87,7 @@ import { useWindowScroll } from '@vueuse/core'
86
87
  import { cn } from '@/lib/utils'
87
88
 
88
89
  const config = useConfig()
90
+ const { i18nEnabled, localePath } = useI18nDocs()
89
91
 
90
92
  const { y } = useWindowScroll()
91
93
 
package/nuxt.config.ts CHANGED
@@ -21,36 +21,36 @@ export default defineNuxtConfig({
21
21
  $env: {
22
22
  development: {
23
23
  modules: [
24
- '@unpress/nuxt-module',
24
+ !process.env.UNPRESS ? '@unpress/nuxt-module' : '../../../unpress/packages/nuxt-module/src/module',
25
25
  ],
26
+
27
+ alias: !process.env.UNPRESS
28
+ ? undefined
29
+ : {
30
+ '@unpress/mdc-editor': r('../../unpress/packages/mdc-editor/src/module'),
31
+ '@unpress/nuxt-module': r('../../unpress/packages/nuxt-module/src/module'),
32
+ },
33
+
34
+ vite: !process.env.UNPRESS
35
+ ? undefined
36
+ : {
37
+ server: {
38
+ fs: {
39
+ allow: [
40
+ // Allow serving files from the project root
41
+ currentDir,
42
+ // Allow serving files from the monorepo root (parent directories)
43
+ resolve(currentDir, '../../..'),
44
+ ],
45
+ },
46
+ },
47
+ },
26
48
  },
27
49
  production: {
28
50
  modules: [
29
51
  '@unpress/nuxt-module',
30
52
  ],
31
53
  },
32
-
33
- unpress: {
34
- modules: [
35
- '../../../unpress/packages/nuxt-module/src/module',
36
- ],
37
- alias: {
38
- '@unpress/mdc-editor': r('../../unpress/packages/mdc-editor/src/module'),
39
- '@unpress/nuxt-module': r('../../unpress/packages/nuxt-module/src/module'),
40
- },
41
- vite: {
42
- server: {
43
- fs: {
44
- allow: [
45
- // Allow serving files from the project root
46
- currentDir,
47
- // Allow serving files from the monorepo root (parent directories)
48
- resolve(currentDir, '../../..'),
49
- ],
50
- },
51
- },
52
- },
53
- },
54
54
  },
55
55
 
56
56
  components: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wordup-md/nuxt-layer-shadcn-unocss",
3
3
  "type": "module",
4
- "version": "0.2.26",
4
+ "version": "0.2.28",
5
5
  "author": "Emmanuel Salomon <emmanuel.salomon@gmail.com>",
6
6
  "main": "./nuxt.config.ts",
7
7
  "repository": {
@@ -16,6 +16,20 @@
16
16
  "wordup-md"
17
17
  ],
18
18
  "license": "MIT",
19
+ "scripts": {
20
+ "dev": "nuxt dev .playground",
21
+ "dev:unpress": "UNPRESS=true nuxt dev .playground",
22
+ "dev:root": "nuxt dev",
23
+ "prepare": "npx nuxt prepare .playground",
24
+ "build": "npx nuxt build .playground",
25
+ "generate": "npx nuxt generate .playground",
26
+ "preview": "npx nuxt preview .playground",
27
+ "lint": "eslint .",
28
+ "build:json-doc": "tsx scripts/buildContentDoc-cli.ts",
29
+ "bump": "pnpm build:json-doc && git add public/content-doc.json && bumpp --skip-install --commit --push --tag",
30
+ "release": "pnpm bump && npm publish",
31
+ "clean": "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' + && find . -name '.nuxt' -type d -prune -exec rm -rf '{}' + && find . -name '.output' -type d -prune -exec rm -rf '{}' + && find . -name 'dist' -prune -exec rm -rf '{}' +"
32
+ },
19
33
  "devDependencies": {
20
34
  "@nuxt/eslint": "latest",
21
35
  "@nuxt/kit": "^3.17.2",
@@ -46,7 +60,7 @@
46
60
  "@nuxtjs/i18n": "^9.5.4",
47
61
  "@nuxtjs/robots": "^5.6.0",
48
62
  "@tanstack/vue-table": "^8.21.3",
49
- "@unpress/nuxt-module": "0.1.13-beta.8",
63
+ "@unpress/nuxt-module": "0.1.14-beta.2",
50
64
  "class-variance-authority": "^0.7.1",
51
65
  "clsx": "^2.1.1",
52
66
  "nuxt": "3.17.2",
@@ -55,16 +69,9 @@
55
69
  "tailwind-merge": "^3.2.0"
56
70
  },
57
71
  "packageManager": "pnpm@10.4.1",
58
- "scripts": {
59
- "dev": "nuxi dev .playground",
60
- "dev:root": "nuxi dev",
61
- "build": "npx nuxt build .playground",
62
- "generate": "npx nuxt generate .playground",
63
- "preview": "npx nuxt preview .playground",
64
- "lint": "eslint .",
65
- "build:json-doc": "tsx scripts/buildContentDoc-cli.ts",
66
- "bump": "pnpm build:json-doc && git add public/content-doc.json && bumpp --skip-install --commit --push --tag",
67
- "release": "pnpm bump && npm publish",
68
- "clean": "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' + && find . -name '.nuxt' -type d -prune -exec rm -rf '{}' + && find . -name '.output' -type d -prune -exec rm -rf '{}' + && find . -name 'dist' -prune -exec rm -rf '{}' +"
72
+ "pnpm": {
73
+ "onlyBuiltDependencies": [
74
+ "sharp"
75
+ ]
69
76
  }
70
- }
77
+ }
package/plugins/wordup.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { TextSelection } from 'prosemirror-state'
2
+ import type { Node } from 'prosemirror-model'
3
+
1
4
  export default defineNuxtPlugin((nuxtApp) => {
2
5
  nuxtApp.hook('mdc-editor:config', ({ config, editor }: { config: any, editor: any }) => {
3
6
  config.components.push({
@@ -16,9 +19,127 @@ export default defineNuxtPlugin((nuxtApp) => {
16
19
  transform() {
17
20
  return { type: 'containerComponent', attrs: { componentName: 'alert' } }
18
21
  },
19
- onSelect: () => editor.commands.insertContainerComponent({
20
- name: 'alert',
21
- }),
22
+ onSelect: async () => {
23
+ const nodes = await config.convertMarkdownToNode(`::alert{type="info"}
24
+ {|}
25
+ ::`)
26
+ // console.log('nodes', nodes, editor, editor.commands, editor.schema.nodeFromJSON(nodes))
27
+
28
+ const { schema, view, state } = editor
29
+ const insertPos = state.selection.anchor - 1
30
+
31
+ // Find and replace {|} cursor placeholder with a paragraph node containing empty text
32
+ const findAndReplaceCursor = (obj: Record<string, unknown>, path: number[] = []): number[] | null => {
33
+ if (typeof obj !== 'object' || obj === null) return null
34
+
35
+ // Check for cursor placeholder in content array
36
+ if (Array.isArray(obj.content)) {
37
+ for (let i = 0; i < obj.content.length; i++) {
38
+ const item = obj.content[i] as Record<string, unknown>
39
+ if (item.type === 'text' && item.text === '{|}') {
40
+ return [...path, i]
41
+ }
42
+ const found = findAndReplaceCursor(item, [...path, i])
43
+ if (found) return found
44
+ }
45
+ }
46
+
47
+ // Check text property directly
48
+ if (obj.text === '{|}') {
49
+ return path
50
+ }
51
+
52
+ return null
53
+ }
54
+
55
+ const cursorPath = findAndReplaceCursor(nodes as Record<string, unknown>)
56
+ console.log(cursorPath)
57
+ if (cursorPath) {
58
+ // Replace cursor placeholder with a paragraph node containing empty text
59
+ let current: Record<string, unknown> = nodes as Record<string, unknown>
60
+ for (let i = 0; i < cursorPath.length - 1; i++) {
61
+ const content = current.content as Record<string, unknown>[]
62
+ if (content) {
63
+ current = content[cursorPath[i]] as Record<string, unknown>
64
+ }
65
+ }
66
+
67
+ if (Array.isArray(current.content)) {
68
+ const cursorIndex = cursorPath[cursorPath.length - 1]
69
+ // Replace {|} with a paragraph node containing a text node with a space
70
+ current.content[cursorIndex] = {
71
+ // type: 'paragraph',
72
+ // content: [
73
+ // {
74
+ type: 'text',
75
+ text: '\u200b',
76
+ // },
77
+ // ],
78
+ }
79
+ }
80
+ }
81
+
82
+ const parsedNodes = schema.nodeFromJSON(nodes)
83
+ console.log('parsedNodes', parsedNodes, cursorPath)
84
+
85
+ // Calculate cursor position offset within the parsed nodes structure
86
+ // The path is an array of indices: [0, 1, 2] means content[0].content[1].content[2]
87
+ const calculateCursorOffset = (node: Node, path: number[]): number | null => {
88
+ if (path.length === 0) {
89
+ return 1 // Base case: position 1 is inside the root node
90
+ }
91
+
92
+ let offset = 1 // Start inside the root node (after opening tag)
93
+ let currentNode = node
94
+
95
+ // Traverse the path, summing up node sizes as we go
96
+ for (let i = 0; i < path.length; i++) {
97
+ const pathIndex = path[i]
98
+ const isLastStep = i === path.length - 1
99
+
100
+ if (!currentNode.content || currentNode.content.childCount <= pathIndex) {
101
+ return null // Invalid path
102
+ }
103
+
104
+ // Sum sizes of all nodes before the target index
105
+ for (let j = 0; j < pathIndex; j++) {
106
+ offset += currentNode.content.child(j).nodeSize
107
+ }
108
+
109
+ if (isLastStep) {
110
+ // For the last step, we want the position at the start of the text node
111
+ // The position is after the opening tag of the parent, plus the sum of previous siblings
112
+ return offset + 1
113
+ }
114
+
115
+ // Move into the target child node (+1 to get inside it)
116
+ offset += 1
117
+ currentNode = currentNode.content.child(pathIndex)
118
+ }
119
+
120
+ return offset
121
+ }
122
+
123
+ let cursorOffset: number | null = null
124
+ if (cursorPath) {
125
+ // Calculate the offset from the root of parsedNodes
126
+ cursorOffset = calculateCursorOffset(parsedNodes, cursorPath)
127
+ // console.log('cursorOffset', cursorOffset, 'cursorPath', cursorPath)
128
+ }
129
+
130
+ const tr = state.tr
131
+ tr.insert(insertPos, parsedNodes)
132
+
133
+ // Set cursor position if we calculated the offset
134
+ if (cursorOffset !== null) {
135
+ const cursorPos = insertPos + cursorOffset
136
+ // console.log('Setting cursor at', cursorPos, 'insertPos', insertPos, 'offset', cursorOffset)
137
+ tr.setSelection(TextSelection.create(tr.doc, cursorPos))
138
+ }
139
+
140
+ view.focus()
141
+ return view.dispatch(tr)
142
+ },
22
143
  })
23
144
 
24
145
  config.components.push({
@@ -89,7 +210,7 @@ export default defineNuxtPlugin((nuxtApp) => {
89
210
  // get next html element with js
90
211
  setTimeout(() => {
91
212
  prevNode.node.nextElementSibling?.querySelector('input.INLINE_MENU_LINK_INPUT')?.focus()
92
- }, 100)
213
+ }, 300)
93
214
  // const node = editor.state.doc.nodeAt(nodePos)
94
215
  // if (node && node.type.name === 'read-more') {
95
216
  // const input = node.firstChild?.firstChild?.firstChild as HTMLInputElement
@@ -133,9 +254,24 @@ export default defineNuxtPlugin((nuxtApp) => {
133
254
  transform() {
134
255
  return { type: 'containerComponent', attrs: { componentName: 'steps' } }
135
256
  },
136
- onSelect: () => editor.commands.insertContainerComponent({
137
- name: 'steps',
138
- }),
257
+ // onSelect: () => editor.commands.insertContainerComponent({
258
+ // name: 'steps',
259
+ // }),
260
+ onSelect: async () => {
261
+ const nodes = await config.convertMarkdownToNode(`::steps
262
+ ###
263
+ ::`)
264
+
265
+ const { schema, view, state } = editor
266
+ const parsedNodes = schema.nodeFromJSON(nodes)
267
+ // console.log('parsedNodes', parsedNodes)
268
+
269
+ const tr = state.tr
270
+ const insertPos = state.selection.anchor - 2
271
+ tr.insert(insertPos, parsedNodes)
272
+
273
+ return view.dispatch(tr)
274
+ },
139
275
  })
140
276
 
141
277
  config.components.push({
@@ -26,7 +26,7 @@
26
26
  "title": "Pages",
27
27
  "_id": "content:1.getting-started:2.writing:2.pages.md",
28
28
  "_path": "getting-started/writing/pages",
29
- "content": "\n\n## `^-` Frontmatter\n\nFront-matter is a convention of Markdown-based CMS to provide metadata to documents, like description or title. Remark MDC uses the YAML syntax with `key: value` pairs.\n\nTo define frontmatter, start your document with `---\\n---` section and put your desired data in YAML format within this section.\n\n```md\n---\ntitle: Title of the page\ndescription: meta description of the page\n---\n\n<!-- Content of the page -->\n```\n\nYou can reuse the same frontmatter attributes in the content or in the components props.\\\nAdd `:` before the key to bind the frontmatter value to the component.\\\nOr use the `{{ $doc.key }}` syntax to bind the value of the frontmatter.\n\n::stack\n ::div{class=\"p-4\"}\n This is the title from the frontmatter: **Title of the page**.\n\n ::alert\n ---\n :type: key\n ---\n With the property `:type: key`, it displays a **{{ $doc.key }} alert**.\n ::\n\n Or inline:\n\n :alert[Title of the page]{:type=\"key\" :icon=\"icon\"}\n ::\n\n ```mdc\n ---\n title: Title of the page\n icon: lucide:file\n key: example\n ---\n\n This is the title from the frontmatter: **{{ $doc.title }}**.\n\n ::alert\n ---\n :type: key\n ---\n With the property `:type: key`, it displays a **{{ $doc.key }} alert**.\n ::\n\n Or inline:\n\n :alert[{{ $doc.title }}]{:type=\"key\" :icon=\"icon\"}\n ```\n::\n\n## Available Frontmatter Attributes\n\n```md\n---\ntitle: Front Matter\ndescription: Front matter attributes used in shadcn-docs-nuxt.\nicon: lucide:book-type\n\nnavTruncate: false\nnavBadges:\n - value: New\n type: lime\n\nbadges:\n - value: Docus\n to: https://docus.dev/api/components#alert\n target: _blank\n - value: Source\n icon: lucide:code\n to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss/blob/main/components/content/Alert.vue\n target: _blank\n\nauthors:\n - name: Tony Zhang\n username: ZTL-UwU\n avatar: https://www.github.com/ZTL-UwU.png\n to: https://github.com/ZTL-UwU\n target: _blank\n---\n\n<!-- Content of the page -->\n```\n\n## Showcases\n\n::tabs{variant=\"line\"}\n::stack{label=\"badges\"}\n![badges-showcase](/front-matter-showcase/badges.png){class=\"w-full\"}\n```yml\nbadges:\n - value: 0.8.10\n - value: Source\n icon: lucide:code\n to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss/blob/main/components/content/FileTree.vue\n target: _blank\n```\n::\n\n::stack{label=\"authors\"}\n![authors-showcase](/front-matter-showcase/authors.png){class=\"w-full\"}\n```yml\nauthors:\n - name: Tony Zhang\n username: ZTL-UwU\n avatar: https://www.github.com/ZTL-UwU.png\n to: https://github.com/ZTL-UwU\n target: _blank\n```\n::\n\n::stack{label=\"navBadges\"}\n![nav-badges-showcase](/front-matter-showcase/nav-badges.png){class=\"w-full\"}\n```yml\nnavBadges:\n - value: New\n type: lime\n```\n::\n::\n\n## Parameters\n\n::field-group\n ::field{name=\"title\" type=\"string\"}\n Title of the page. Defaults to the filename.\n ::\n ::field{name=\"description\" type=\"string\"}\n Description of the page. Defaults to the first `<p>`{lang=\"html\"} of the page.\n ::\n ::field{name=\"navigation\" type=\"boolean\" default-value=\"true\"}\n Define if the page is included in the sidebar. Set it to `false` in `index.md`.\n ::\n ::field{name=\"icon\" type=\"string\"}\n The icon shown in the sidebar for the page.\n ::\n ::field{name=\"navBadges\" type=\"[]\"}\n A list of badges appended to the end of the sidebar link.\n ::\n ::field{name=\"navTruncate\" type=\"boolean\" default-value=\"true\"}\n Whether to truncate the sidebar title.\n ::\n ::field{name=\"badges\" type=\"[]\"}\n A list of badges shown at the bottom of page title.\n ::\n ::field{name=\"authors\" type=\"[]\"}\n A list of authors shown at the bottom of page title.\n ::\n ::field{name=\"toc\" type=\"boolean\" default-value=\"true\"}\n Whether to show the toc section for this page.\n ::\n ::field{name=\"aside\" type=\"boolean\" default-value=\"true\"}\n Whether to show the aside section for this page.\n ::\n ::field{name=\"editLink\" type=\"boolean\" default-value=\"true\"}\n Whether to show the edit link for this page.\n ::\n ::field{name=\"prevNext\" type=\"boolean\" default-value=\"true\"}\n Whether to show the previous & next page buttons.\n ::\n ::field{name=\"breadcrumb\" type=\"boolean\" default-value=\"true\"}\n Whether to show the breadcrumb.\n ::\n::\n",
29
+ "content": "\n\n## `^-` Frontmatter\n\nFront-matter is a convention of Markdown-based CMS to provide metadata to documents, like description or title. Remark MDC uses the YAML syntax with `key: value` pairs.\n\nTo define frontmatter, start your document with `---\\n---` section and put your desired data in YAML format within this section.\n\n```md\n---\ntitle: Title of the page\ndescription: meta description of the page\n---\n\n<!-- Content of the page -->\n```\n\nYou can reuse the same frontmatter attributes in the content or in the components props.\\\nAdd `:` before the key to bind the frontmatter value to the component.\\\nOr use the `{{ $doc.key }}` syntax to bind the value of the frontmatter.\n\n::stack\n :::div{.p-4}\n This is the title from the frontmatter: **Title of the page**.\n \n ::::alert\n ---\n :type: key\n ---\n With the property `:type: key`, it displays a **{{ $doc.key }} alert**.\n ::::\n \n Or inline:\n \n :alert[Title of the page]{:icon=\"icon\" :type=\"key\"}\n :::\n\n```mdc\n---\ntitle: Title of the page\nicon: lucide:file\nkey: example\n---\n\nThis is the title from the frontmatter: **{{ $doc.title }}**.\n\n::alert\n---\n:type: key\n---\nWith the property `:type: key`, it displays a **{{ $doc.key }} alert**.\n::\n\nOr inline:\n\n:alert[{{ $doc.title }}]{:type=\"key\" :icon=\"icon\"}\n```\n::\n\n## Available Frontmatter Attributes\n\n```md\n---\ntitle: Front Matter\ndescription: Front matter attributes used in shadcn-docs-nuxt.\nicon: lucide:book-type\n\nnavTruncate: false\nnavBadges:\n - value: New\n type: lime\n\nbadges:\n - value: Docus\n to: https://docus.dev/api/components#alert\n target: _blank\n - value: Source\n icon: lucide:code\n to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss/blob/main/components/content/Alert.vue\n target: _blank\n\nauthors:\n - name: Tony Zhang\n username: ZTL-UwU\n avatar: https://www.github.com/ZTL-UwU.png\n to: https://github.com/ZTL-UwU\n target: _blank\n---\n\n<!-- Content of the page -->\n```\n\n## Showcases\n\n::tabs{variant=\"line\"}\n :::stack{label=\"badges\"}\n ![badges-showcase](/front-matter-showcase/badges.png){.w-full}\n \n ```yml\n badges:\n - value: 0.8.10\n - value: Source\n icon: lucide:code\n to: https://github.com/wordup-md/nuxt-layer-shadcn-unocss/blob/main/components/content/FileTree.vue\n target: _blank\n ```\n :::\n\n :::stack{label=\"authors\"}\n ![authors-showcase](/front-matter-showcase/authors.png){.w-full}\n \n ```yml\n authors:\n - name: Tony Zhang\n username: ZTL-UwU\n avatar: https://www.github.com/ZTL-UwU.png\n to: https://github.com/ZTL-UwU\n target: _blank\n ```\n :::\n\n :::stack{label=\"navBadges\"}\n ![nav-badges-showcase](/front-matter-showcase/nav-badges.png){.w-full}\n \n ```yml\n navBadges:\n - value: New\n type: lime\n ```\n :::\n::\n\n## Parameters\n\n::field-group\n :::field{name=\"title\" type=\"string\"}\n Title of the page. Defaults to the filename.\n :::\n\n :::field{name=\"description\" type=\"string\"}\n Description of the page. Defaults to the first `<p>` of the page.\n :::\n\n :::field{default-value=\"true\" name=\"navigation\" type=\"boolean\"}\n Define if the page is included in the sidebar. Set it to `false` in `index.md`.\n :::\n\n :::field{name=\"icon\" type=\"string\"}\n The icon shown in the sidebar for the page.\n :::\n\n :::field{name=\"navBadges\" type=\"[]\"}\n A list of badges appended to the end of the sidebar link.\n :::\n\n :::field{default-value=\"true\" name=\"navTruncate\" type=\"boolean\"}\n Whether to truncate the sidebar title.\n :::\n\n :::field{name=\"badges\" type=\"[]\"}\n A list of badges shown at the bottom of page title.\n :::\n\n :::field{name=\"authors\" type=\"[]\"}\n A list of authors shown at the bottom of page title.\n :::\n\n :::field{default-value=\"true\" name=\"toc\" type=\"boolean\"}\n Whether to show the toc section for this page.\n :::\n\n :::field{default-value=\"true\" name=\"aside\" type=\"boolean\"}\n Whether to show the aside section for this page.\n :::\n\n :::field{default-value=\"true\" name=\"editLink\" type=\"boolean\"}\n Whether to show the edit link for this page.\n :::\n\n :::field{default-value=\"true\" name=\"prevNext\" type=\"boolean\"}\n Whether to show the previous & next page buttons.\n :::\n\n :::field{default-value=\"true\" name=\"breadcrumb\" type=\"boolean\"}\n Whether to show the breadcrumb.\n :::\n::\n",
30
30
  "description": "Front matter attributes.",
31
31
  "icon": "lucide:file",
32
32
  "key": "example"