@md-plugins/quasar-app-extension-q-press 0.1.0-beta.10 → 0.1.0-beta.12
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.
- package/README.md +4 -2
- package/dist/templates/init/src/_q-press/components/MarkdownApi.vue +128 -83
- package/dist/templates/init/src/_q-press/components/MarkdownCodepen.vue +115 -20
- package/dist/templates/init/src/_q-press/components/MarkdownExample.vue +1 -1
- package/dist/templates/init/src/_q-press/components/MarkdownLink.vue +1 -1
- package/dist/templates/init/src/_q-press/components/MarkdownTree.vue +1 -1
- package/dist/templates/init/src/components/LandingPage/LandingPage.vue +1 -1
- package/dist/templates/init/src/markdown/guides/faq.md +1 -1
- package/dist/templates/init/src/markdown/guides/upgrade-guide.md +3 -3
- package/dist/templates/init/src/markdown/md-plugins/blockquote/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/codeblocks/overview.md +7 -1
- package/dist/templates/init/src/markdown/md-plugins/containers/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/frontmatter/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/headers/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/image/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/imports/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/inline-code/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/link/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/table/overview.md +3 -1
- package/dist/templates/init/src/markdown/md-plugins/title/overview.md +3 -1
- package/dist/templates/init/src/markdown/quasar-app-extensions/qpress/advanced.md +3 -1
- package/dist/templates/init/src/markdown/quasar-app-extensions/qpress/overview.md +5 -1
- package/dist/templates/init/src/markdown/quasar-app-extensions/vite-md-plugin-app-ext/overview.md +1 -1
- package/dist/templates/init/src/markdown/vite-plugins/vite-examples-plugin/overview.md +3 -1
- package/dist/templates/init/src/markdown/vite-plugins/vite-md-plugin/overview.md +3 -1
- package/dist/templates/init/src/siteConfig/index.ts +6 -1
- package/dist/templates/update/src/_q-press/components/MarkdownApi.vue +128 -83
- package/dist/templates/update/src/_q-press/components/MarkdownCodepen.vue +115 -20
- package/dist/templates/update/src/_q-press/components/MarkdownExample.vue +1 -1
- package/dist/templates/update/src/_q-press/components/MarkdownLink.vue +1 -1
- package/dist/templates/update/src/_q-press/components/MarkdownTree.vue +1 -1
- package/package.json +16 -16
- package/src/templates/init/src/_q-press/components/MarkdownApi.vue +128 -83
- package/src/templates/init/src/_q-press/components/MarkdownCodepen.vue +115 -20
- package/src/templates/init/src/_q-press/components/MarkdownExample.vue +1 -1
- package/src/templates/init/src/_q-press/components/MarkdownLink.vue +1 -1
- package/src/templates/init/src/_q-press/components/MarkdownTree.vue +1 -1
- package/src/templates/init/src/components/LandingPage/LandingPage.vue +1 -1
- package/src/templates/init/src/markdown/guides/faq.md +1 -1
- package/src/templates/init/src/markdown/guides/upgrade-guide.md +3 -3
- package/src/templates/init/src/markdown/md-plugins/blockquote/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/codeblocks/overview.md +7 -1
- package/src/templates/init/src/markdown/md-plugins/containers/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/frontmatter/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/headers/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/image/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/imports/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/inline-code/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/link/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/table/overview.md +3 -1
- package/src/templates/init/src/markdown/md-plugins/title/overview.md +3 -1
- package/src/templates/init/src/markdown/quasar-app-extensions/qpress/advanced.md +3 -1
- package/src/templates/init/src/markdown/quasar-app-extensions/qpress/overview.md +5 -1
- package/src/templates/init/src/markdown/quasar-app-extensions/vite-md-plugin-app-ext/overview.md +1 -1
- package/src/templates/init/src/markdown/vite-plugins/vite-examples-plugin/overview.md +3 -1
- package/src/templates/init/src/markdown/vite-plugins/vite-md-plugin/overview.md +3 -1
- package/src/templates/init/src/siteConfig/index.ts +6 -1
- package/src/templates/update/src/_q-press/components/MarkdownApi.vue +128 -83
- package/src/templates/update/src/_q-press/components/MarkdownCodepen.vue +115 -20
- package/src/templates/update/src/_q-press/components/MarkdownExample.vue +1 -1
- package/src/templates/update/src/_q-press/components/MarkdownLink.vue +1 -1
- package/src/templates/update/src/_q-press/components/MarkdownTree.vue +1 -1
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@ The Ultimate Markdown Solution for the Quasar Framework.
|
|
|
4
4
|
|
|
5
5
|
See the [documentation](https://md-plugins.netlify.app/quasar-app-extensions/qpress/overview) for more information.
|
|
6
6
|
|
|
7
|
-
> Current beta release: `0.1.0-beta.
|
|
7
|
+
> Current beta release: `0.1.0-beta.12`.
|
|
8
8
|
>
|
|
9
|
-
> Q-Press currently targets Quasar Vite projects using `@quasar/app-vite` `>=3.0.0-beta.
|
|
9
|
+
> Q-Press currently targets Quasar Vite projects using `@quasar/app-vite` `>=3.0.0-beta.30`. TypeScript processing is required.
|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
@@ -38,12 +38,14 @@ See the [documentation](https://md-plugins.netlify.app/quasar-app-extensions/qpr
|
|
|
38
38
|
- `npm i -D markdown-it @types/markdown-it`
|
|
39
39
|
- `yarn add -D markdown-it @types/markdown-it`
|
|
40
40
|
- `pnpm i -D markdown-it @types/markdown-it`
|
|
41
|
+
- `bun add -d markdown-it @types/markdown-it`
|
|
41
42
|
|
|
42
43
|
3. Add `prismjs` to your project dependencies
|
|
43
44
|
|
|
44
45
|
- `npm i prismjs`
|
|
45
46
|
- `yarn add prismjs`
|
|
46
47
|
- `pnpm add prismjs`
|
|
48
|
+
- `bun add prismjs`
|
|
47
49
|
|
|
48
50
|
## Modifications
|
|
49
51
|
|
|
@@ -55,7 +55,10 @@
|
|
|
55
55
|
<q-tab v-for="tab in tabsList" :key="`api-tab-${tab}`" :name="tab" class="header-btn">
|
|
56
56
|
<div class="row no-wrap items-center">
|
|
57
57
|
<span class="q-mr-xs text-capitalize">{{ tab }}</span>
|
|
58
|
-
<q-badge
|
|
58
|
+
<q-badge
|
|
59
|
+
v-if="filteredApiCount[tab]?.overall"
|
|
60
|
+
:label="filteredApiCount[tab]?.overall"
|
|
61
|
+
/>
|
|
59
62
|
</div>
|
|
60
63
|
</q-tab>
|
|
61
64
|
</q-tabs>
|
|
@@ -64,7 +67,10 @@
|
|
|
64
67
|
|
|
65
68
|
<q-tab-panels v-model="currentTab" animated>
|
|
66
69
|
<q-tab-panel v-for="tab in tabsList" :key="tab" class="q-pa-none" :name="tab">
|
|
67
|
-
<div
|
|
70
|
+
<div
|
|
71
|
+
v-if="innerTabsList[tab]?.length !== 1"
|
|
72
|
+
class="markdown-api__container row no-wrap"
|
|
73
|
+
>
|
|
68
74
|
<div class="col-auto">
|
|
69
75
|
<q-tabs
|
|
70
76
|
v-model="currentInnerTab"
|
|
@@ -86,8 +92,8 @@
|
|
|
86
92
|
<span class="q-mr-xs text-capitalize">{{ innerTab }}</span>
|
|
87
93
|
<div class="col" />
|
|
88
94
|
<q-badge
|
|
89
|
-
v-if="filteredApiCount[tab]
|
|
90
|
-
:label="filteredApiCount[tab]
|
|
95
|
+
v-if="filteredApiCount[tab]?.category[innerTab]"
|
|
96
|
+
:label="filteredApiCount[tab]?.category[innerTab]"
|
|
91
97
|
/>
|
|
92
98
|
</div>
|
|
93
99
|
</q-tab>
|
|
@@ -109,12 +115,12 @@
|
|
|
109
115
|
class="q-pa-none"
|
|
110
116
|
:name="innerTab"
|
|
111
117
|
>
|
|
112
|
-
<MarkdownApiEntry :type="tab" :definition="filteredApi[tab][innerTab]" />
|
|
118
|
+
<MarkdownApiEntry :type="tab" :definition="filteredApi[tab]?.[innerTab]" />
|
|
113
119
|
</q-tab-panel>
|
|
114
120
|
</q-tab-panels>
|
|
115
121
|
</div>
|
|
116
122
|
<div v-else class="markdown-api__container">
|
|
117
|
-
<MarkdownApiEntry :type="tab" :definition="filteredApi[tab][defaultInnerTabName]" />
|
|
123
|
+
<MarkdownApiEntry :type="tab" :definition="filteredApi[tab]?.[defaultInnerTabName]" />
|
|
118
124
|
</div>
|
|
119
125
|
</q-tab-panel>
|
|
120
126
|
</q-tab-panels>
|
|
@@ -131,20 +137,57 @@ import MarkdownApiEntry from './MarkdownApiEntry'
|
|
|
131
137
|
|
|
132
138
|
const defaultInnerTabName = '__default'
|
|
133
139
|
|
|
140
|
+
type ApiEntry = Record<string, any> & {
|
|
141
|
+
category?: string
|
|
142
|
+
definition?: Record<string, ApiEntry>
|
|
143
|
+
desc?: string
|
|
144
|
+
propName?: string
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
type ApiDefinition = Record<string, ApiEntry>
|
|
148
|
+
type ParsedApi = Record<string, Record<string, any>>
|
|
149
|
+
type InnerTabsMap = Record<string, string[]>
|
|
150
|
+
type ApiCount = Record<string, { overall: number; category: Record<string, number> }>
|
|
151
|
+
|
|
152
|
+
type ApiFile = Record<string, any> & {
|
|
153
|
+
addedIn?: string
|
|
154
|
+
behavior?: unknown
|
|
155
|
+
internal?: unknown
|
|
156
|
+
meta?: {
|
|
157
|
+
docsUrl?: string
|
|
158
|
+
}
|
|
159
|
+
type?: string
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
type MarkdownApiProps = {
|
|
163
|
+
api?: ApiFile | null
|
|
164
|
+
file?: string
|
|
165
|
+
name?: string
|
|
166
|
+
pageLink?: boolean
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
type QPressEnv = {
|
|
170
|
+
QCLI_FS_QUASAR_FOLDER?: string
|
|
171
|
+
QUASAR_CLIENT?: boolean
|
|
172
|
+
QUASAR_DEV?: boolean
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const qPressEnv = (import.meta as ImportMeta & { env: QPressEnv }).env
|
|
176
|
+
|
|
134
177
|
/**
|
|
135
178
|
* Extracts and categorizes properties based on their categories.
|
|
136
179
|
*
|
|
137
180
|
* @param {Object} props - The properties object where each key is a property name and each value is an object containing a `category` string.
|
|
138
181
|
* @returns {Array<string>} - An array of unique category names sorted alphabetically. If there is only one unique category, returns an array with a default inner tab name.
|
|
139
182
|
*/
|
|
140
|
-
function getPropsCategories(props) {
|
|
141
|
-
const acc = new Set()
|
|
183
|
+
function getPropsCategories(props: ApiDefinition | undefined): string[] {
|
|
184
|
+
const acc = new Set<string>()
|
|
142
185
|
|
|
143
|
-
for (const key in props) {
|
|
186
|
+
for (const key in props ?? {}) {
|
|
144
187
|
if (props[key] !== void 0) {
|
|
145
188
|
const value = props[key]
|
|
146
189
|
|
|
147
|
-
value.category.split('|').forEach((groupKey) => {
|
|
190
|
+
;(value.category ?? defaultInnerTabName).split('|').forEach((groupKey: string) => {
|
|
148
191
|
acc.add(groupKey)
|
|
149
192
|
})
|
|
150
193
|
}
|
|
@@ -161,10 +204,10 @@ function getPropsCategories(props) {
|
|
|
161
204
|
* @param {string} apiType - The type of the API.
|
|
162
205
|
* @returns {Array} - The array of inner tabs.
|
|
163
206
|
*/
|
|
164
|
-
function getInnerTabs(api, tabs, apiType) {
|
|
165
|
-
const acc = {}
|
|
207
|
+
function getInnerTabs(api: ApiFile, tabs: string[], apiType?: string): InnerTabsMap {
|
|
208
|
+
const acc: InnerTabsMap = {}
|
|
166
209
|
|
|
167
|
-
tabs.forEach((tab) => {
|
|
210
|
+
tabs.forEach((tab: string) => {
|
|
168
211
|
acc[tab] =
|
|
169
212
|
apiType === 'component' && tab === 'props'
|
|
170
213
|
? getPropsCategories(api[tab])
|
|
@@ -181,16 +224,17 @@ function getInnerTabs(api, tabs, apiType) {
|
|
|
181
224
|
* @param {Array} tabs - The array to store the main tabs.
|
|
182
225
|
* @param {Array} innerTabs - The array to store the inner tabs.
|
|
183
226
|
*/
|
|
184
|
-
function parseApi(api, tabs, innerTabs) {
|
|
185
|
-
const acc = {}
|
|
227
|
+
function parseApi(api: ApiFile, tabs: string[], innerTabs: InnerTabsMap): ParsedApi {
|
|
228
|
+
const acc: ParsedApi = {}
|
|
186
229
|
|
|
187
|
-
tabs.forEach((tab) => {
|
|
230
|
+
tabs.forEach((tab: string) => {
|
|
188
231
|
const apiValue = api[tab]
|
|
232
|
+
const tabInnerTabs = innerTabs[tab] ?? [defaultInnerTabName]
|
|
189
233
|
|
|
190
|
-
if (
|
|
191
|
-
const inner = {}
|
|
234
|
+
if (tabInnerTabs.length > 1) {
|
|
235
|
+
const inner: Record<string, ApiDefinition> = {}
|
|
192
236
|
|
|
193
|
-
|
|
237
|
+
tabInnerTabs.forEach((subTab: string) => {
|
|
194
238
|
inner[subTab] = {}
|
|
195
239
|
})
|
|
196
240
|
|
|
@@ -198,8 +242,10 @@ function parseApi(api, tabs, innerTabs) {
|
|
|
198
242
|
if (apiValue[key] !== void 0) {
|
|
199
243
|
const value = apiValue[key]
|
|
200
244
|
|
|
201
|
-
value.category.split('|').forEach((groupKey) => {
|
|
202
|
-
inner[groupKey]
|
|
245
|
+
;(value.category ?? defaultInnerTabName).split('|').forEach((groupKey: string) => {
|
|
246
|
+
if (inner[groupKey] !== undefined) {
|
|
247
|
+
inner[groupKey][key] = value
|
|
248
|
+
}
|
|
203
249
|
})
|
|
204
250
|
}
|
|
205
251
|
}
|
|
@@ -222,7 +268,7 @@ function parseApi(api, tabs, innerTabs) {
|
|
|
222
268
|
* @param {string} desc - The description of the item to check.
|
|
223
269
|
* @returns {boolean} - Returns true if the item passes the filter, otherwise false.
|
|
224
270
|
*/
|
|
225
|
-
function passesFilter(filter, name, desc) {
|
|
271
|
+
function passesFilter(filter: string, name: string, desc?: string): boolean {
|
|
226
272
|
return (
|
|
227
273
|
name.toLowerCase().indexOf(filter) > -1 ||
|
|
228
274
|
(desc !== void 0 && desc.toLowerCase().indexOf(filter) > -1)
|
|
@@ -238,23 +284,29 @@ function passesFilter(filter, name, desc) {
|
|
|
238
284
|
* @param {Array} innerTabs - The list of inner tabs to consider while filtering.
|
|
239
285
|
* @returns {Object} - The filtered API data.
|
|
240
286
|
*/
|
|
241
|
-
function getFilteredApi(
|
|
287
|
+
function getFilteredApi(
|
|
288
|
+
parsedApi: ParsedApi,
|
|
289
|
+
filter: string,
|
|
290
|
+
tabs: string[],
|
|
291
|
+
innerTabs: InnerTabsMap,
|
|
292
|
+
): ParsedApi {
|
|
242
293
|
if (filter === '') {
|
|
243
294
|
return parsedApi
|
|
244
295
|
}
|
|
245
296
|
|
|
246
|
-
const acc = {}
|
|
297
|
+
const acc: ParsedApi = {}
|
|
247
298
|
|
|
248
|
-
tabs.forEach((tab) => {
|
|
299
|
+
tabs.forEach((tab: string) => {
|
|
249
300
|
if (tab === 'injection') {
|
|
250
|
-
const name = parsedApi[tab][defaultInnerTabName]
|
|
301
|
+
const name = parsedApi[tab]?.[defaultInnerTabName]
|
|
251
302
|
acc[tab] = {}
|
|
252
|
-
acc[tab][defaultInnerTabName] =
|
|
303
|
+
acc[tab][defaultInnerTabName] =
|
|
304
|
+
typeof name === 'string' && passesFilter(filter, name, '') === true ? name : {}
|
|
253
305
|
return
|
|
254
306
|
}
|
|
255
307
|
|
|
256
308
|
if (tab === 'quasarConfOptions') {
|
|
257
|
-
const api = parsedApi[tab][defaultInnerTabName]
|
|
309
|
+
const api = (parsedApi[tab]?.[defaultInnerTabName] ?? {}) as ApiEntry
|
|
258
310
|
acc[tab] = {}
|
|
259
311
|
acc[tab][defaultInnerTabName] = {
|
|
260
312
|
...api,
|
|
@@ -262,8 +314,8 @@ function getFilteredApi(parsedApi, filter, tabs, innerTabs) {
|
|
|
262
314
|
}
|
|
263
315
|
const result = acc[tab][defaultInnerTabName]
|
|
264
316
|
|
|
265
|
-
for (const name in api.definition
|
|
266
|
-
const entry = api.definition[name]
|
|
317
|
+
for (const name in api.definition ?? {}) {
|
|
318
|
+
const entry = api.definition[name]!
|
|
267
319
|
if (passesFilter(filter, name, entry.desc) === true) {
|
|
268
320
|
result.definition[name] = entry
|
|
269
321
|
}
|
|
@@ -279,17 +331,17 @@ function getFilteredApi(parsedApi, filter, tabs, innerTabs) {
|
|
|
279
331
|
return
|
|
280
332
|
}
|
|
281
333
|
|
|
282
|
-
const tabApi = parsedApi[tab]
|
|
283
|
-
const tabCategories = innerTabs[tab]
|
|
334
|
+
const tabApi = parsedApi[tab] ?? {}
|
|
335
|
+
const tabCategories = innerTabs[tab] ?? [defaultInnerTabName]
|
|
284
336
|
|
|
285
337
|
acc[tab] = {}
|
|
286
|
-
tabCategories.forEach((categ) => {
|
|
287
|
-
const subTabs = {}
|
|
288
|
-
const categoryEntries = tabApi[categ]
|
|
338
|
+
tabCategories.forEach((categ: string) => {
|
|
339
|
+
const subTabs: ApiDefinition = {}
|
|
340
|
+
const categoryEntries = (tabApi[categ] ?? {}) as ApiDefinition
|
|
289
341
|
|
|
290
342
|
for (const name in categoryEntries) {
|
|
291
343
|
const entry = categoryEntries[name]
|
|
292
|
-
if (passesFilter(filter, name, entry.desc) === true) {
|
|
344
|
+
if (entry !== undefined && passesFilter(filter, name, entry.desc) === true) {
|
|
293
345
|
subTabs[name] = entry
|
|
294
346
|
}
|
|
295
347
|
}
|
|
@@ -309,22 +361,24 @@ function getFilteredApi(parsedApi, filter, tabs, innerTabs) {
|
|
|
309
361
|
* @param {Array} innerTabs - The array of inner tab configurations.
|
|
310
362
|
* @returns {number} - The count of API entries.
|
|
311
363
|
*/
|
|
312
|
-
function getApiCount(parsedApi, tabs, innerTabs) {
|
|
313
|
-
const acc = {}
|
|
364
|
+
function getApiCount(parsedApi: ParsedApi, tabs: string[], innerTabs: InnerTabsMap): ApiCount {
|
|
365
|
+
const acc: ApiCount = {}
|
|
314
366
|
|
|
315
|
-
tabs.forEach((tab) => {
|
|
316
|
-
const tabApi = parsedApi[tab]
|
|
317
|
-
const tabCategories = innerTabs[tab]
|
|
367
|
+
tabs.forEach((tab: string) => {
|
|
368
|
+
const tabApi = parsedApi[tab] ?? {}
|
|
369
|
+
const tabCategories = innerTabs[tab] ?? [defaultInnerTabName]
|
|
370
|
+
const firstCategory = tabCategories[0] ?? defaultInnerTabName
|
|
318
371
|
|
|
319
372
|
if (['value', 'arg', 'injection'].includes(tab)) {
|
|
320
373
|
acc[tab] = {
|
|
321
|
-
overall: Object.keys(tabApi[
|
|
374
|
+
overall: Object.keys(tabApi[firstCategory] ?? {}).length === 0 ? 0 : 1,
|
|
375
|
+
category: {},
|
|
322
376
|
}
|
|
323
377
|
return
|
|
324
378
|
}
|
|
325
379
|
|
|
326
380
|
if (tab === 'quasarConfOptions') {
|
|
327
|
-
const api = tabApi[
|
|
381
|
+
const api = (tabApi[firstCategory] ?? {}) as ApiEntry
|
|
328
382
|
acc[tab] = {
|
|
329
383
|
overall:
|
|
330
384
|
Object.keys(api).length === 0
|
|
@@ -332,25 +386,24 @@ function getApiCount(parsedApi, tabs, innerTabs) {
|
|
|
332
386
|
: api.definition === void 0
|
|
333
387
|
? 1
|
|
334
388
|
: Object.keys(api.definition).length,
|
|
389
|
+
category: {},
|
|
335
390
|
}
|
|
336
391
|
return
|
|
337
392
|
}
|
|
338
393
|
|
|
339
|
-
acc[tab] = { overall: 0 }
|
|
394
|
+
acc[tab] = { overall: 0, category: {} }
|
|
340
395
|
|
|
341
396
|
if (tabCategories.length === 1) {
|
|
342
|
-
const categ = tabCategories[0]
|
|
343
|
-
const count = Object.keys(tabApi[categ]).length
|
|
397
|
+
const categ = tabCategories[0] ?? defaultInnerTabName
|
|
398
|
+
const count = Object.keys(tabApi[categ] ?? {}).length
|
|
344
399
|
|
|
345
400
|
acc[tab] = {
|
|
346
401
|
overall: count,
|
|
347
402
|
category: { [categ]: count },
|
|
348
403
|
}
|
|
349
404
|
} else {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
tabCategories.forEach((categ) => {
|
|
353
|
-
const count = Object.keys(tabApi[categ]).length
|
|
405
|
+
tabCategories.forEach((categ: string) => {
|
|
406
|
+
const count = Object.keys(tabApi[categ] ?? {}).length
|
|
354
407
|
acc[tab].category[categ] = count
|
|
355
408
|
acc[tab].overall += count
|
|
356
409
|
})
|
|
@@ -361,29 +414,18 @@ function getApiCount(parsedApi, tabs, innerTabs) {
|
|
|
361
414
|
}
|
|
362
415
|
|
|
363
416
|
const getJsonUrl =
|
|
364
|
-
|
|
365
|
-
? (file) => `/@fs/${
|
|
366
|
-
: (file) => `/quasar-api/${file}.json`
|
|
367
|
-
|
|
368
|
-
const props = defineProps({
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
},
|
|
374
|
-
api: {
|
|
375
|
-
type: Object,
|
|
376
|
-
required: false,
|
|
377
|
-
default: null,
|
|
378
|
-
},
|
|
379
|
-
name: {
|
|
380
|
-
type: String,
|
|
381
|
-
default: 'API Documentation',
|
|
382
|
-
},
|
|
383
|
-
pageLink: Boolean,
|
|
417
|
+
qPressEnv.QUASAR_DEV === true
|
|
418
|
+
? (file: string) => `/@fs/${qPressEnv.QCLI_FS_QUASAR_FOLDER ?? ''}/dist/api/${file}.json`
|
|
419
|
+
: (file: string) => `/quasar-api/${file}.json`
|
|
420
|
+
|
|
421
|
+
const props = withDefaults(defineProps<MarkdownApiProps>(), {
|
|
422
|
+
api: null,
|
|
423
|
+
file: '',
|
|
424
|
+
name: 'API Documentation',
|
|
425
|
+
pageLink: false,
|
|
384
426
|
})
|
|
385
427
|
|
|
386
|
-
const inputRef = ref(null)
|
|
428
|
+
const inputRef = ref<HTMLInputElement | null>(null)
|
|
387
429
|
|
|
388
430
|
const loading = ref(true)
|
|
389
431
|
const nameBanner = ref(`Loading ${props.file || props.name} API...`)
|
|
@@ -392,16 +434,16 @@ const nothingToShow = ref(false)
|
|
|
392
434
|
const apiPath = ref('')
|
|
393
435
|
|
|
394
436
|
const filter = ref('')
|
|
395
|
-
const apiDef = ref({})
|
|
437
|
+
const apiDef = ref<ParsedApi>({})
|
|
396
438
|
|
|
397
|
-
const tabsList = ref([])
|
|
398
|
-
const innerTabsList = ref({})
|
|
439
|
+
const tabsList = ref<string[]>([])
|
|
440
|
+
const innerTabsList = ref<InnerTabsMap>({})
|
|
399
441
|
|
|
400
|
-
const currentTab = ref(
|
|
401
|
-
const currentInnerTab = ref(
|
|
442
|
+
const currentTab = ref('')
|
|
443
|
+
const currentInnerTab = ref('')
|
|
402
444
|
|
|
403
445
|
watch(currentTab, (val) => {
|
|
404
|
-
currentInnerTab.value = innerTabsList.value[val][0]
|
|
446
|
+
currentInnerTab.value = innerTabsList.value[val]?.[0] ?? defaultInnerTabName
|
|
405
447
|
})
|
|
406
448
|
|
|
407
449
|
const inputIcon = computed(() => (filter.value !== '' ? mdiClose : mdiMagnify))
|
|
@@ -436,11 +478,14 @@ const filteredApiCount = computed(() =>
|
|
|
436
478
|
* @param {Object} api - Additional API properties.
|
|
437
479
|
* @returns {Object} The parsed API information.
|
|
438
480
|
*/
|
|
439
|
-
function parseApiFile(
|
|
481
|
+
function parseApiFile(
|
|
482
|
+
name: string,
|
|
483
|
+
{ type, behavior: _behavior, meta, addedIn: _addedIn, ...api }: ApiFile,
|
|
484
|
+
) {
|
|
440
485
|
nameBanner.value = `${name} API`
|
|
441
|
-
apiPath.value = meta
|
|
486
|
+
apiPath.value = meta?.docsUrl ?? ''
|
|
442
487
|
|
|
443
|
-
const { internal:
|
|
488
|
+
const { internal: _internal, ...apiSections } = api
|
|
444
489
|
const tabs = Object.keys(apiSections)
|
|
445
490
|
|
|
446
491
|
if (tabs.length === 0) {
|
|
@@ -457,7 +502,7 @@ function parseApiFile(name, { type, behavior, meta, addedIn, ...api }) {
|
|
|
457
502
|
}
|
|
458
503
|
|
|
459
504
|
function onSearchFieldClick() {
|
|
460
|
-
inputRef.value
|
|
505
|
+
inputRef.value?.focus()
|
|
461
506
|
}
|
|
462
507
|
|
|
463
508
|
function onFilterClick() {
|
|
@@ -466,12 +511,12 @@ function onFilterClick() {
|
|
|
466
511
|
}
|
|
467
512
|
}
|
|
468
513
|
|
|
469
|
-
if (
|
|
514
|
+
if (qPressEnv.QUASAR_CLIENT === true) {
|
|
470
515
|
onMounted(() => {
|
|
471
516
|
if (props.file) {
|
|
472
517
|
fetch(getJsonUrl(props.file))
|
|
473
518
|
.then((response) => response.json())
|
|
474
|
-
.then((json) => {
|
|
519
|
+
.then((json: ApiFile) => {
|
|
475
520
|
parseApiFile(props.file, json)
|
|
476
521
|
loading.value = false
|
|
477
522
|
})
|
|
@@ -26,6 +26,11 @@ type CodepenParts = {
|
|
|
26
26
|
[key: string]: string | undefined
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
type CodepenGlobalPackage = {
|
|
30
|
+
packageName: string
|
|
31
|
+
globalName: string
|
|
32
|
+
}
|
|
33
|
+
|
|
29
34
|
const defaultCssResources = [
|
|
30
35
|
'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons',
|
|
31
36
|
`https://cdn.jsdelivr.net/npm/quasar@${Quasar.version}/dist/quasar.min.css`,
|
|
@@ -44,22 +49,59 @@ function indent(code: string, spaces = 2) {
|
|
|
44
49
|
.join('\n')
|
|
45
50
|
}
|
|
46
51
|
|
|
47
|
-
function
|
|
48
|
-
const
|
|
49
|
-
const
|
|
52
|
+
function getImportParts(content: string, packageName: string) {
|
|
53
|
+
const parts: { importName: string; bindingName: string }[] = []
|
|
54
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
55
|
+
const importRe = new RegExp(
|
|
56
|
+
`import\\s+(?!type\\b){([^}]*)}\\s+from\\s+['"]${escapedPackageName}['"];?`,
|
|
57
|
+
'g',
|
|
58
|
+
)
|
|
50
59
|
let match: RegExpExecArray | null
|
|
51
60
|
|
|
52
61
|
while ((match = importRe.exec(content)) !== null) {
|
|
53
|
-
for (const part of match[1].split(',')) {
|
|
54
|
-
const
|
|
62
|
+
for (const part of (match[1] ?? '').split(',')) {
|
|
63
|
+
const rawName = part.trim()
|
|
55
64
|
|
|
56
|
-
if (
|
|
57
|
-
|
|
65
|
+
if (rawName.length === 0 || rawName.startsWith('type ')) {
|
|
66
|
+
continue
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const [importName, bindingName = importName] = rawName.split(/\s+as\s+/)
|
|
70
|
+
|
|
71
|
+
if (importName !== undefined && importName.length > 0) {
|
|
72
|
+
parts.push({
|
|
73
|
+
importName,
|
|
74
|
+
bindingName,
|
|
75
|
+
})
|
|
58
76
|
}
|
|
59
77
|
}
|
|
60
78
|
}
|
|
61
79
|
|
|
62
|
-
return
|
|
80
|
+
return parts
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getImportNames(content: string, packageName: string) {
|
|
84
|
+
return [
|
|
85
|
+
...new Set(
|
|
86
|
+
getImportParts(content, packageName).map(({ importName, bindingName }) =>
|
|
87
|
+
importName === bindingName ? importName : `${importName}: ${bindingName}`,
|
|
88
|
+
),
|
|
89
|
+
),
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getImportBindingNames(content: string, packageName: string) {
|
|
94
|
+
return [...new Set(getImportParts(content, packageName).map(({ bindingName }) => bindingName))]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getGlobalPackageImportLines(content: string) {
|
|
98
|
+
return (siteConfig.codepen?.globalPackages ?? [])
|
|
99
|
+
.map(({ packageName, globalName }: CodepenGlobalPackage) => {
|
|
100
|
+
const imports = getImportNames(content, packageName)
|
|
101
|
+
|
|
102
|
+
return imports.length > 0 ? `const { ${imports.join(', ')} } = ${globalName}` : ''
|
|
103
|
+
})
|
|
104
|
+
.filter((line) => line.length > 0)
|
|
63
105
|
}
|
|
64
106
|
|
|
65
107
|
function getGlobalImportLines(content: string) {
|
|
@@ -69,9 +111,20 @@ function getGlobalImportLines(content: string) {
|
|
|
69
111
|
return [
|
|
70
112
|
vueImports.length > 0 ? `const { ${vueImports.join(', ')} } = Vue` : '',
|
|
71
113
|
quasarImports.length > 0 ? `const { ${quasarImports.join(', ')} } = Quasar` : '',
|
|
114
|
+
...getGlobalPackageImportLines(content),
|
|
72
115
|
].filter((line) => line.length > 0)
|
|
73
116
|
}
|
|
74
117
|
|
|
118
|
+
function getGlobalImportBindingNames(content: string) {
|
|
119
|
+
return [
|
|
120
|
+
...getImportBindingNames(content, 'vue'),
|
|
121
|
+
...getImportBindingNames(content, 'quasar'),
|
|
122
|
+
...(siteConfig.codepen?.globalPackages ?? []).flatMap(({ packageName }: CodepenGlobalPackage) =>
|
|
123
|
+
getImportBindingNames(content, packageName),
|
|
124
|
+
),
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
|
|
75
128
|
function stripImports(content: string) {
|
|
76
129
|
return content
|
|
77
130
|
.replace(/^\s*import\s+type\s+[\s\S]*?\s+from\s+['"][^'"]+['"];?\s*$/gm, '')
|
|
@@ -101,21 +154,53 @@ function getScriptBlock(script: string, setup: boolean) {
|
|
|
101
154
|
|
|
102
155
|
function getSetupReturnNames(content: string) {
|
|
103
156
|
const names = new Set<string>()
|
|
104
|
-
const
|
|
157
|
+
const topLevelContent = getTopLevelContent(content)
|
|
158
|
+
const declarationRe =
|
|
159
|
+
/(?:^|\n)\s*(?:const|let|var)\s+([\s\S]*?)(?=\n\s*(?:const|let|var|function|interface|type|class)\s+|\s*$)/g
|
|
160
|
+
const variableNameRe = /(?:^|\n)\s*([A-Za-z_$][\w$]*)\s*(?:[:=,]|$)/g
|
|
105
161
|
const functionRe = /(?:^|\n)\s*function\s+([A-Za-z_$][\w$]*)/g
|
|
106
162
|
let match: RegExpExecArray | null
|
|
107
163
|
|
|
108
|
-
while ((match = declarationRe.exec(
|
|
109
|
-
|
|
164
|
+
while ((match = declarationRe.exec(topLevelContent)) !== null) {
|
|
165
|
+
let variableMatch: RegExpExecArray | null
|
|
166
|
+
|
|
167
|
+
while ((variableMatch = variableNameRe.exec(match[1] ?? '')) !== null) {
|
|
168
|
+
if (variableMatch[1] !== undefined) {
|
|
169
|
+
names.add(variableMatch[1])
|
|
170
|
+
}
|
|
171
|
+
}
|
|
110
172
|
}
|
|
111
173
|
|
|
112
|
-
while ((match = functionRe.exec(
|
|
113
|
-
|
|
174
|
+
while ((match = functionRe.exec(topLevelContent)) !== null) {
|
|
175
|
+
if (match[1] !== undefined) {
|
|
176
|
+
names.add(match[1])
|
|
177
|
+
}
|
|
114
178
|
}
|
|
115
179
|
|
|
116
180
|
return [...names]
|
|
117
181
|
}
|
|
118
182
|
|
|
183
|
+
function getTopLevelContent(content: string) {
|
|
184
|
+
let depth = 0
|
|
185
|
+
let output = ''
|
|
186
|
+
|
|
187
|
+
for (const char of content) {
|
|
188
|
+
if (depth === 0 || char === '\n') {
|
|
189
|
+
output += char
|
|
190
|
+
} else {
|
|
191
|
+
output += ' '
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (char === '{') {
|
|
195
|
+
depth++
|
|
196
|
+
} else if (char === '}') {
|
|
197
|
+
depth = Math.max(0, depth - 1)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return output
|
|
202
|
+
}
|
|
203
|
+
|
|
119
204
|
function getAppSetup() {
|
|
120
205
|
return ['app.use(Quasar, { config: {} })', siteConfig.codepen?.jsSetup ?? '']
|
|
121
206
|
.map((line) => line.trim())
|
|
@@ -127,7 +212,9 @@ function createSetupScript(script: string) {
|
|
|
127
212
|
const { content } = getScriptBlock(script, true)
|
|
128
213
|
const globalImports = getGlobalImportLines(content)
|
|
129
214
|
const setupContent = stripCompilerMacros(stripImports(content))
|
|
130
|
-
const returnNames =
|
|
215
|
+
const returnNames = [
|
|
216
|
+
...new Set([...getGlobalImportBindingNames(content), ...getSetupReturnNames(setupContent)]),
|
|
217
|
+
]
|
|
131
218
|
const setupBody = [
|
|
132
219
|
setupContent.length > 0 ? indent(setupContent, 4) : '',
|
|
133
220
|
returnNames.length > 0 ? ` return { ${returnNames.join(', ')} }` : '',
|
|
@@ -172,7 +259,7 @@ function createOptionsScript(script: string) {
|
|
|
172
259
|
const props = defineProps({ title: { type: String, required: true } })
|
|
173
260
|
|
|
174
261
|
const active = ref(false)
|
|
175
|
-
const formRef = ref(null)
|
|
262
|
+
const formRef = ref<HTMLFormElement | null>(null)
|
|
176
263
|
const def = reactive<{ parts: CodepenParts }>({ parts: {} })
|
|
177
264
|
|
|
178
265
|
const cssResources = computed(() => {
|
|
@@ -216,7 +303,10 @@ const html = computed(() => {
|
|
|
216
303
|
.replace(/([\w]+=")([^"]*?)(")/g, function (match, p1, p2, p3) {
|
|
217
304
|
return p1 + p2.replace(/>/g, '___TEMP_REPLACEMENT___') + p3
|
|
218
305
|
})
|
|
219
|
-
.replace(
|
|
306
|
+
.replace(
|
|
307
|
+
/<([A-Z][\w-]*|[a-z][\w]*-[\w-]+|div)([^>]*?)\s*?([\n\r][\t ]+)?\/>/gs,
|
|
308
|
+
'<$1$2$3></$1>',
|
|
309
|
+
)
|
|
220
310
|
.replace(
|
|
221
311
|
/(<template[^>]*>)(\s*?(?:[\n\r][\t ]+)?)<(thead|tbody|tfoot)/gs,
|
|
222
312
|
'$1$2<___PREVENT_TEMPLATE___$3',
|
|
@@ -244,15 +334,20 @@ const html = computed(() => {
|
|
|
244
334
|
})
|
|
245
335
|
|
|
246
336
|
const editors = computed(() => {
|
|
247
|
-
const flag =
|
|
337
|
+
const flag =
|
|
338
|
+
(html.value.length > 0 ? 0b100 : 0) |
|
|
339
|
+
(css.value.length > 0 ? 0b010 : 0) |
|
|
340
|
+
(js.value.length > 0 ? 0b001 : 0)
|
|
248
341
|
return flag.toString(2)
|
|
249
342
|
})
|
|
250
343
|
|
|
251
344
|
const computedTitle = computed(() => {
|
|
345
|
+
const titleSuffix = siteConfig.codepen?.titleSuffix ?? `Quasar v${Quasar.version}`
|
|
346
|
+
|
|
252
347
|
return (
|
|
253
348
|
(typeof document !== 'undefined' ? document.title.split(' | ')[0] + ': ' : '') +
|
|
254
349
|
(props.title ? props.title + ' - ' : '') +
|
|
255
|
-
|
|
350
|
+
titleSuffix
|
|
256
351
|
)
|
|
257
352
|
})
|
|
258
353
|
|
|
@@ -298,14 +393,14 @@ function open(whichParts: CodepenParts) {
|
|
|
298
393
|
def.parts = whichParts
|
|
299
394
|
|
|
300
395
|
if (active.value) {
|
|
301
|
-
formRef.value
|
|
396
|
+
formRef.value?.submit()
|
|
302
397
|
return
|
|
303
398
|
}
|
|
304
399
|
|
|
305
400
|
active.value = true
|
|
306
401
|
|
|
307
402
|
nextTick(() => {
|
|
308
|
-
formRef.value
|
|
403
|
+
formRef.value?.submit()
|
|
309
404
|
})
|
|
310
405
|
}
|
|
311
406
|
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
import { computed, inject, markRaw, ref, reactive, onBeforeUnmount, onMounted } from 'vue'
|
|
97
97
|
import { openURL } from 'quasar'
|
|
98
98
|
|
|
99
|
-
import { fabGithub, fabCodepen } from '@quasar/extras/fontawesome-
|
|
99
|
+
import { fabGithub, fabCodepen } from '@quasar/extras/fontawesome-v7'
|
|
100
100
|
// import { mdiCompare } from '@quasar/extras/mdi-v7'
|
|
101
101
|
|
|
102
102
|
import MarkdownCode from './MarkdownCode.vue'
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<script setup lang="ts">
|
|
12
12
|
import { computed } from 'vue'
|
|
13
|
-
import { mdiLaunch } from '@quasar/extras/mdi-
|
|
13
|
+
import { mdiLaunch } from '@quasar/extras/mdi-v7'
|
|
14
14
|
|
|
15
15
|
const props = defineProps({ to: { type: String, required: true } })
|
|
16
16
|
const internal = computed(
|