@docsector/docsector-reader 3.5.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +11 -11
  2. package/bin/docsector.js +1 -283
  3. package/package.json +1 -1
  4. package/public/images/cards/getting-started-cover.svg +60 -0
  5. package/public/images/cards/quick-links-cover.svg +71 -0
  6. package/src/components/{DPageBlockquote.vue → DBlockBlockquote.vue} +4 -0
  7. package/src/components/DBlockCards.vue +223 -0
  8. package/src/components/{DPageEmbeddedUrl.vue → DBlockEmbeddedUrl.vue} +1 -1
  9. package/src/components/{DPageExpandable.vue → DBlockExpandable.vue} +4 -0
  10. package/src/components/{DPageFile.vue → DBlockFile.vue} +1 -1
  11. package/src/components/{DPageImage.vue → DBlockImage.vue} +1 -1
  12. package/src/components/{DMermaidDiagram.vue → DBlockMermaidDiagram.vue} +4 -0
  13. package/src/components/{DQuickLinks.vue → DBlockQuickLinks.vue} +4 -0
  14. package/src/components/{DPageSourceCode.vue → DBlockSourceCode.vue} +6 -1
  15. package/src/components/DBlockStepper.vue +210 -0
  16. package/src/components/DBlockTimeline.vue +319 -0
  17. package/src/components/DPageTokens.vue +51 -18
  18. package/src/components/page-section-tokens.js +334 -9
  19. package/src/i18n/languages/en-US.hjson +5 -0
  20. package/src/i18n/languages/pt-BR.hjson +5 -0
  21. package/src/pages/guide/i18n-and-markdown.overview.en-US.md +6 -6
  22. package/src/pages/guide/i18n-and-markdown.overview.pt-BR.md +6 -6
  23. package/src/pages/guide/theming.overview.en-US.md +1 -1
  24. package/src/pages/guide/theming.overview.pt-BR.md +1 -1
  25. package/src/pages/manual/content/blocks/cards.overview.en-US.md +32 -0
  26. package/src/pages/manual/content/blocks/cards.overview.pt-BR.md +32 -0
  27. package/src/pages/manual/content/blocks/cards.showcase.en-US.md +39 -0
  28. package/src/pages/manual/content/blocks/cards.showcase.pt-BR.md +39 -0
  29. package/src/pages/manual/content/blocks/embedded-urls.overview.en-US.md +3 -3
  30. package/src/pages/manual/content/blocks/embedded-urls.overview.pt-BR.md +3 -3
  31. package/src/pages/manual/content/blocks/embedded-urls.showcase.en-US.md +8 -8
  32. package/src/pages/manual/content/blocks/embedded-urls.showcase.pt-BR.md +8 -8
  33. package/src/pages/manual/content/blocks/expandable.overview.en-US.md +8 -8
  34. package/src/pages/manual/content/blocks/expandable.overview.pt-BR.md +8 -8
  35. package/src/pages/manual/content/blocks/expandable.showcase.en-US.md +6 -6
  36. package/src/pages/manual/content/blocks/expandable.showcase.pt-BR.md +6 -6
  37. package/src/pages/manual/content/blocks/files.overview.en-US.md +3 -3
  38. package/src/pages/manual/content/blocks/files.overview.pt-BR.md +3 -3
  39. package/src/pages/manual/content/blocks/files.showcase.en-US.md +5 -5
  40. package/src/pages/manual/content/blocks/files.showcase.pt-BR.md +5 -5
  41. package/src/pages/manual/content/blocks/quick-links.overview.en-US.md +4 -4
  42. package/src/pages/manual/content/blocks/quick-links.overview.pt-BR.md +4 -4
  43. package/src/pages/manual/content/blocks/quick-links.showcase.en-US.md +9 -9
  44. package/src/pages/manual/content/blocks/quick-links.showcase.pt-BR.md +9 -9
  45. package/src/pages/manual/content/blocks/stepper.overview.en-US.md +59 -0
  46. package/src/pages/manual/content/blocks/stepper.overview.pt-BR.md +59 -0
  47. package/src/pages/manual/content/blocks/stepper.showcase.en-US.md +115 -0
  48. package/src/pages/manual/content/blocks/stepper.showcase.pt-BR.md +115 -0
  49. package/src/pages/manual/content/blocks/timeline.overview.en-US.md +47 -0
  50. package/src/pages/manual/content/blocks/timeline.overview.pt-BR.md +47 -0
  51. package/src/pages/manual/content/blocks/timeline.showcase.en-US.md +170 -0
  52. package/src/pages/manual/content/blocks/timeline.showcase.pt-BR.md +170 -0
  53. package/src/pages/manual.index.js +84 -0
@@ -13,7 +13,10 @@ const ALERT_MESSAGE_TYPES = new Set([
13
13
  'caution'
14
14
  ])
15
15
 
16
+ const CARDS_MARKER_PREFIX = '@@DOCSECTOR_CARDS_'
16
17
  const QUICK_LINKS_MARKER_PREFIX = '@@DOCSECTOR_QUICK_LINKS_'
18
+ const TIMELINE_MARKER_PREFIX = '@@DOCSECTOR_TIMELINE_'
19
+ const STEPPER_MARKER_PREFIX = '@@DOCSECTOR_STEPPER_'
17
20
  const EXPANDABLE_MARKER_PREFIX = '@@DOCSECTOR_EXPANDABLE_'
18
21
  const FILE_MARKER_PREFIX = '@@DOCSECTOR_FILE_'
19
22
  const EMBEDDED_URL_MARKER_PREFIX = '@@DOCSECTOR_EMBEDDED_URL_'
@@ -146,11 +149,11 @@ const extractQuickLinksBlocks = (source = '') => {
146
149
  const map = new Map()
147
150
  let index = 0
148
151
 
149
- const blockPattern = /<d-quick-links\b([^>]*)>([\s\S]*?)<\/d-quick-links>/gi
152
+ const blockPattern = /<d-block-quick-links\b([^>]*)>([\s\S]*?)<\/d-block-quick-links>/gi
150
153
  const replaced = String(source).replace(blockPattern, (_, blockAttrsRaw, inner) => {
151
154
  const blockAttrs = parseCustomTagAttributes(blockAttrsRaw)
152
155
  const items = []
153
- const itemPattern = /<d-quick-link\b([^>]*)\/?\s*>/gi
156
+ const itemPattern = /<d-block-quick-link\b([^>]*)\/?\s*>/gi
154
157
 
155
158
  let itemMatch = itemPattern.exec(inner)
156
159
  while (itemMatch !== null) {
@@ -190,15 +193,219 @@ const extractQuickLinksBlocks = (source = '') => {
190
193
  }
191
194
  }
192
195
 
196
+ const extractCardsBlocks = (source = '') => {
197
+ const map = new Map()
198
+ let index = 0
199
+
200
+ const blockPattern = /<d-block-cards\b([^>]*)>([\s\S]*?)<\/d-block-cards>/gi
201
+ const replaced = String(source).replace(blockPattern, (_, blockAttrsRaw, inner) => {
202
+ const blockAttrs = parseCustomTagAttributes(blockAttrsRaw)
203
+ const items = []
204
+ const itemPattern = /<d-block-card\b([^>]*)\/?\s*>/gi
205
+
206
+ let itemMatch = itemPattern.exec(inner)
207
+ while (itemMatch !== null) {
208
+ const itemAttrs = parseCustomTagAttributes(itemMatch[1])
209
+ const title = itemAttrs.title || ''
210
+ const description = itemAttrs.description || ''
211
+ const to = itemAttrs.to || ''
212
+ const href = itemAttrs.href || ''
213
+
214
+ if (title && description && (to || href)) {
215
+ items.push({
216
+ title,
217
+ description,
218
+ to,
219
+ href,
220
+ image: itemAttrs.image || '',
221
+ icon: itemAttrs.icon || ''
222
+ })
223
+ }
224
+
225
+ itemMatch = itemPattern.exec(inner)
226
+ }
227
+
228
+ const marker = `${CARDS_MARKER_PREFIX}${index}@@`
229
+ index++
230
+
231
+ map.set(marker, {
232
+ title: blockAttrs.title || '',
233
+ items
234
+ })
235
+
236
+ return `\n${marker}\n`
237
+ })
238
+
239
+ return {
240
+ source: replaced,
241
+ cardsMap: map
242
+ }
243
+ }
244
+
193
245
  const parseExpandableOpenState = (raw = '') => {
194
246
  return ['1', 'true', 'yes', 'on'].includes(String(raw).trim().toLowerCase())
195
247
  }
196
248
 
249
+ const parseTimelineTags = (raw = '') => {
250
+ return decodeHtmlEntities(raw)
251
+ .split(',')
252
+ .map((value) => value.trim())
253
+ .filter(Boolean)
254
+ .map((label) => ({
255
+ label,
256
+ color: '',
257
+ textColor: '',
258
+ icon: ''
259
+ }))
260
+ }
261
+
262
+ const parseTimelineTagLabel = (raw = '') => {
263
+ return decodeHtmlEntities(String(raw).replace(/<[^>]+>/g, ' '))
264
+ .replace(/\s+/g, ' ')
265
+ .trim()
266
+ }
267
+
268
+ const createTimelineTag = (rawAttrs = '', rawLabel = '') => {
269
+ const attrs = parseCustomTagAttributes(rawAttrs)
270
+ const label = parseTimelineTagLabel(attrs.label || rawLabel)
271
+
272
+ if (label === '') {
273
+ return null
274
+ }
275
+
276
+ return {
277
+ label,
278
+ color: decodeHtmlEntities(attrs.color || '').trim(),
279
+ textColor: decodeHtmlEntities(attrs['text-color'] || attrs.textColor || '').trim(),
280
+ icon: decodeHtmlEntities(attrs.icon || '').trim()
281
+ }
282
+ }
283
+
284
+ const extractTimelineItemTags = (source = '') => {
285
+ const tags = []
286
+
287
+ const replaceBlock = (match, rawAttrs, rawLabel = '') => {
288
+ const tag = createTimelineTag(rawAttrs, rawLabel)
289
+
290
+ if (tag !== null) {
291
+ tags.push(tag)
292
+ return '\n'
293
+ }
294
+
295
+ return match
296
+ }
297
+
298
+ const replaced = String(source).replace(
299
+ /<d-block-timeline-tag\b([^>]*?)(?:\/\s*>|>([\s\S]*?)<\/d-block-timeline-tag>)/gi,
300
+ replaceBlock
301
+ )
302
+
303
+ return {
304
+ content: replaced,
305
+ tags
306
+ }
307
+ }
308
+
309
+ const extractTimelineBlocks = (source = '') => {
310
+ const map = new Map()
311
+ let index = 0
312
+
313
+ const blockPattern = /<d-block-timeline\b([^>]*)>([\s\S]*?)<\/d-block-timeline>/gi
314
+ const replaced = String(source).replace(blockPattern, (match, _rawAttrs, inner) => {
315
+ const items = []
316
+ const itemPattern = /<d-block-timeline-item\b([^>]*)>([\s\S]*?)<\/d-block-timeline-item>/gi
317
+
318
+ let itemMatch = itemPattern.exec(inner)
319
+ while (itemMatch !== null) {
320
+ const attrs = parseCustomTagAttributes(itemMatch[1])
321
+ const date = decodeHtmlEntities(attrs.date || '').trim()
322
+ const { content: itemContent, tags } = extractTimelineItemTags(itemMatch[2])
323
+
324
+ if (date) {
325
+ items.push({
326
+ date,
327
+ tags: [...parseTimelineTags(attrs.tags || ''), ...tags],
328
+ anchor: decodeHtmlEntities(attrs.anchor || attrs.id || '').trim(),
329
+ content: itemContent
330
+ })
331
+ }
332
+
333
+ itemMatch = itemPattern.exec(inner)
334
+ }
335
+
336
+ if (items.length === 0) {
337
+ return match
338
+ }
339
+
340
+ const marker = `${TIMELINE_MARKER_PREFIX}${index}@@`
341
+ index++
342
+
343
+ map.set(marker, {
344
+ items
345
+ })
346
+
347
+ return `\n${marker}\n`
348
+ })
349
+
350
+ return {
351
+ source: replaced,
352
+ timelineMap: map
353
+ }
354
+ }
355
+
356
+ const extractStepperBlocks = (source = '') => {
357
+ const map = new Map()
358
+ let index = 0
359
+
360
+ const blockPattern = /<d-block-stepper\b([^>]*)>([\s\S]*?)<\/d-block-stepper>/gi
361
+ const replaced = String(source).replace(blockPattern, (match, _rawAttrs, inner) => {
362
+ const steps = []
363
+ const stepPattern = /<d-block-step\b([^>]*)>([\s\S]*?)<\/d-block-step>/gi
364
+
365
+ let stepMatch = stepPattern.exec(inner)
366
+ while (stepMatch !== null) {
367
+ const attrs = parseCustomTagAttributes(stepMatch[1])
368
+ const title = attrs.title || ''
369
+
370
+ if (title) {
371
+ steps.push({
372
+ title,
373
+ icon: attrs.icon || '',
374
+ activeIcon: attrs['active-icon'] || '',
375
+ doneIcon: attrs['done-icon'] || '',
376
+ errorIcon: attrs['error-icon'] || '',
377
+ content: stepMatch[2]
378
+ })
379
+ }
380
+
381
+ stepMatch = stepPattern.exec(inner)
382
+ }
383
+
384
+ if (steps.length === 0) {
385
+ return match
386
+ }
387
+
388
+ const marker = `${STEPPER_MARKER_PREFIX}${index}@@`
389
+ index++
390
+
391
+ map.set(marker, {
392
+ steps
393
+ })
394
+
395
+ return `\n${marker}\n`
396
+ })
397
+
398
+ return {
399
+ source: replaced,
400
+ stepperMap: map
401
+ }
402
+ }
403
+
197
404
  const extractExpandableBlocks = (source = '') => {
198
405
  const map = new Map()
199
406
  let index = 0
200
407
 
201
- const blockPattern = /<d-expandable\b([^>]*)>([\s\S]*?)<\/d-expandable>/gi
408
+ const blockPattern = /<d-block-expandable\b([^>]*)>([\s\S]*?)<\/d-block-expandable>/gi
202
409
  const replaced = String(source).replace(blockPattern, (_, rawAttrs, inner) => {
203
410
  const attrs = parseCustomTagAttributes(rawAttrs)
204
411
  const marker = `${EXPANDABLE_MARKER_PREFIX}${index}@@`
@@ -264,10 +471,10 @@ const extractFileBlocks = (source = '') => {
264
471
  return `\n${marker}\n`
265
472
  }
266
473
 
267
- const replacedSelfClosing = String(source).replace(/<d-file\b([^>]*)\/\s*>/gi, (match, rawAttrs) => {
474
+ const replacedSelfClosing = String(source).replace(/<d-block-file\b([^>]*)\/\s*>/gi, (match, rawAttrs) => {
268
475
  return replaceBlock(match, rawAttrs)
269
476
  })
270
- const replaced = replacedSelfClosing.replace(/<d-file\b([^>]*)>([\s\S]*?)<\/d-file>/gi, replaceBlock)
477
+ const replaced = replacedSelfClosing.replace(/<d-block-file\b([^>]*)>([\s\S]*?)<\/d-block-file>/gi, replaceBlock)
271
478
 
272
479
  return {
273
480
  source: replaced,
@@ -299,10 +506,10 @@ const extractEmbeddedUrlBlocks = (source = '') => {
299
506
  return `\n${marker}\n`
300
507
  }
301
508
 
302
- const replacedSelfClosing = String(source).replace(/<d-embedded-url\b([^>]*)\/\s*>/gi, (match, rawAttrs) => {
509
+ const replacedSelfClosing = String(source).replace(/<d-block-embedded-url\b([^>]*)\/\s*>/gi, (match, rawAttrs) => {
303
510
  return replaceBlock(match, rawAttrs)
304
511
  })
305
- const replaced = replacedSelfClosing.replace(/<d-embedded-url\b([^>]*)>([\s\S]*?)<\/d-embedded-url>/gi, replaceBlock)
512
+ const replaced = replacedSelfClosing.replace(/<d-block-embedded-url\b([^>]*)>([\s\S]*?)<\/d-block-embedded-url>/gi, replaceBlock)
306
513
 
307
514
  return {
308
515
  source: replaced,
@@ -353,6 +560,12 @@ const escapeHtml = (value = '') => {
353
560
  .replace(/'/g, '&#39;')
354
561
  }
355
562
 
563
+ const stripHtmlTags = (value = '') => {
564
+ return decodeHtmlEntities(String(value).replace(/<[^>]+>/g, ' '))
565
+ .replace(/\s+/g, ' ')
566
+ .trim()
567
+ }
568
+
356
569
  const extractTagAttributes = (html = '', tagName = '') => {
357
570
  const match = String(html).match(new RegExp(`<${tagName}\\b([^>]*)\\/?>(?![\\s\\S]*<${tagName}\\b)`, 'i'))
358
571
 
@@ -585,6 +798,35 @@ const getHeadingAnchorId = (markdown, currentTag, element, env, parserState) =>
585
798
  return parserState.headingSlugger.slug(headingText)
586
799
  }
587
800
 
801
+ const getTimelineItemTitle = (tokens = []) => {
802
+ for (const token of tokens) {
803
+ if (typeof token?.content !== 'string') {
804
+ continue
805
+ }
806
+
807
+ const text = stripHtmlTags(token.content)
808
+ if (text !== '') {
809
+ return text
810
+ }
811
+ }
812
+
813
+ return ''
814
+ }
815
+
816
+ const getTimelineItemAnchorId = ({ item, itemTokens, itemIndex, parserState }) => {
817
+ const explicitAnchor = decodeHtmlEntities(item.anchor || '').trim()
818
+
819
+ if (explicitAnchor !== '') {
820
+ return parserState.headingSlugger.slug(explicitAnchor)
821
+ }
822
+
823
+ const title = getTimelineItemTitle(itemTokens)
824
+ const fallbackTitle = title || `item-${itemIndex + 1}`
825
+ const seed = [item.date, fallbackTitle].filter(Boolean).join(' ')
826
+
827
+ return parserState.headingSlugger.slug(seed)
828
+ }
829
+
588
830
  export const tokenizePageSectionSource = (source = '', options = {}) => {
589
831
  const {
590
832
  allowHeadingTokens = true,
@@ -592,7 +834,31 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
592
834
  } = options
593
835
  const normalizedSource = normalizePageSectionSource(source)
594
836
  const { source: sourceWithShieldedCode, codeSegmentsMap } = shieldMarkdownCodeSegments(normalizedSource)
595
- const { source: sourceWithExpandables, expandableMap } = extractExpandableBlocks(sourceWithShieldedCode)
837
+ const { source: sourceWithTimelines, timelineMap } = extractTimelineBlocks(sourceWithShieldedCode)
838
+
839
+ timelineMap.forEach((data, marker) => {
840
+ timelineMap.set(marker, {
841
+ ...data,
842
+ items: data.items.map((item) => ({
843
+ ...item,
844
+ content: restoreShieldedCodeSegments(item.content, codeSegmentsMap)
845
+ }))
846
+ })
847
+ })
848
+
849
+ const { source: sourceWithSteppers, stepperMap } = extractStepperBlocks(sourceWithTimelines)
850
+
851
+ stepperMap.forEach((data, marker) => {
852
+ stepperMap.set(marker, {
853
+ ...data,
854
+ steps: data.steps.map((step) => ({
855
+ ...step,
856
+ content: restoreShieldedCodeSegments(step.content, codeSegmentsMap)
857
+ }))
858
+ })
859
+ })
860
+
861
+ const { source: sourceWithExpandables, expandableMap } = extractExpandableBlocks(sourceWithSteppers)
596
862
 
597
863
  expandableMap.forEach((data, marker) => {
598
864
  expandableMap.set(marker, {
@@ -601,7 +867,8 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
601
867
  })
602
868
  })
603
869
 
604
- const { source: sourceWithQuickLinks, quickLinksMap } = extractQuickLinksBlocks(sourceWithExpandables)
870
+ const { source: sourceWithCards, cardsMap } = extractCardsBlocks(sourceWithExpandables)
871
+ const { source: sourceWithQuickLinks, quickLinksMap } = extractQuickLinksBlocks(sourceWithCards)
605
872
  const { source: sourceWithFiles, fileMap } = extractFileBlocks(sourceWithQuickLinks)
606
873
  const { source: sourceWithEmbeddedUrls, embeddedUrlMap } = extractEmbeddedUrlBlocks(sourceWithFiles)
607
874
 
@@ -764,6 +1031,53 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
764
1031
  case 'inline': {
765
1032
  const anchorId = getHeadingAnchorId(markdown, tag, element, markdownEnv, parserState)
766
1033
 
1034
+ if (timelineMap.has(element.content.trim())) {
1035
+ const data = timelineMap.get(element.content.trim())
1036
+
1037
+ tokens.push({
1038
+ tag: 'timeline',
1039
+ items: data.items.map((item, itemIndex) => {
1040
+ const itemTokens = tokenizePageSectionSource(item.content, {
1041
+ allowHeadingTokens: false,
1042
+ parserState
1043
+ })
1044
+
1045
+ return {
1046
+ date: item.date,
1047
+ tags: item.tags,
1048
+ anchorId: getTimelineItemAnchorId({
1049
+ item,
1050
+ itemTokens,
1051
+ itemIndex,
1052
+ parserState
1053
+ }),
1054
+ tokens: itemTokens
1055
+ }
1056
+ })
1057
+ })
1058
+ break
1059
+ }
1060
+
1061
+ if (stepperMap.has(element.content.trim())) {
1062
+ const data = stepperMap.get(element.content.trim())
1063
+
1064
+ tokens.push({
1065
+ tag: 'stepper',
1066
+ steps: data.steps.map((step) => ({
1067
+ title: step.title,
1068
+ icon: step.icon,
1069
+ activeIcon: step.activeIcon,
1070
+ doneIcon: step.doneIcon,
1071
+ errorIcon: step.errorIcon,
1072
+ tokens: tokenizePageSectionSource(step.content, {
1073
+ allowHeadingTokens: false,
1074
+ parserState
1075
+ })
1076
+ }))
1077
+ })
1078
+ break
1079
+ }
1080
+
767
1081
  if (expandableMap.has(element.content.trim())) {
768
1082
  const data = expandableMap.get(element.content.trim())
769
1083
 
@@ -779,6 +1093,17 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
779
1093
  break
780
1094
  }
781
1095
 
1096
+ if (cardsMap.has(element.content.trim())) {
1097
+ const data = cardsMap.get(element.content.trim())
1098
+
1099
+ tokens.push({
1100
+ tag: 'cards',
1101
+ title: data.title,
1102
+ items: data.items
1103
+ })
1104
+ break
1105
+ }
1106
+
782
1107
  if (quickLinksMap.has(element.content.trim())) {
783
1108
  const data = quickLinksMap.get(element.content.trim())
784
1109
 
@@ -45,6 +45,11 @@
45
45
  download: 'Download',
46
46
  open: 'Open'
47
47
  },
48
+ stepper: {
49
+ continue: 'Continue',
50
+ back: 'Back',
51
+ finish: 'Finish'
52
+ },
48
53
  openInChatGPT: 'Open in ChatGPT',
49
54
  openInChatGPTCaption: 'Ask ChatGPT about this page',
50
55
  openInClaude: 'Open in Claude',
@@ -44,6 +44,11 @@
44
44
  download: 'Baixar',
45
45
  open: 'Abrir'
46
46
  },
47
+ stepper: {
48
+ continue: 'Continuar',
49
+ back: 'Voltar',
50
+ finish: 'Finalizar'
51
+ },
47
52
  openInChatGPT: 'Abrir no ChatGPT',
48
53
  openInChatGPTCaption: 'Pergunte ao ChatGPT sobre esta página',
49
54
  openInClaude: 'Abrir no Claude',
@@ -118,14 +118,14 @@ echo "Example"
118
118
 
119
119
  ### Expandable Content
120
120
 
121
- Use `<d-expandable>` to hide secondary content without removing rich Markdown features from the page:
121
+ Use `<d-block-expandable>` to hide secondary content without removing rich Markdown features from the page:
122
122
 
123
123
  ```markdown
124
- <d-expandable title="More details">
124
+ <d-block-expandable title="More details">
125
125
 
126
126
  Optional explanations, operational notes, or longer examples.
127
127
 
128
- </d-expandable>
128
+ </d-block-expandable>
129
129
  ```
130
130
 
131
131
  Set `open="true"` when the block should start expanded.
@@ -134,12 +134,12 @@ The expandable body supports paragraphs, lists, alerts, code blocks, Mermaid dia
134
134
 
135
135
  ### File Blocks
136
136
 
137
- Use `<d-file>` to publish downloadable attachments from repo-tracked files or external storage without leaving Markdown:
137
+ Use `<d-block-file>` to publish downloadable attachments from repo-tracked files or external storage without leaving Markdown:
138
138
 
139
139
  ```html
140
- <d-file src="/files/manual/release-checklist.txt" title="Release checklist" size="1 KB">
140
+ <d-block-file src="/files/manual/release-checklist.txt" title="Release checklist" size="1 KB">
141
141
  Download the example attachment used in this manual.
142
- </d-file>
142
+ </d-block-file>
143
143
  ```
144
144
 
145
145
  Store repo-tracked files under `public/files/` and prefer absolute site paths such as `/files/...`.
@@ -118,14 +118,14 @@ echo "Exemplo"
118
118
 
119
119
  ### Conteúdo Expansível
120
120
 
121
- Use `<d-expandable>` para esconder conteúdo secundário sem perder os recursos ricos de Markdown da página:
121
+ Use `<d-block-expandable>` para esconder conteúdo secundário sem perder os recursos ricos de Markdown da página:
122
122
 
123
123
  ```markdown
124
- <d-expandable title="Mais detalhes">
124
+ <d-block-expandable title="Mais detalhes">
125
125
 
126
126
  Explicações opcionais, notas operacionais ou exemplos maiores.
127
127
 
128
- </d-expandable>
128
+ </d-block-expandable>
129
129
  ```
130
130
 
131
131
  Defina `open="true"` quando o bloco precisar começar aberto.
@@ -134,12 +134,12 @@ O corpo do expansível suporta parágrafos, listas, alertas, blocos de código,
134
134
 
135
135
  ### Blocos de Arquivo
136
136
 
137
- Use `<d-file>` para publicar anexos baixáveis a partir de arquivos versionados no repositório ou de storage externo sem sair do Markdown:
137
+ Use `<d-block-file>` para publicar anexos baixáveis a partir de arquivos versionados no repositório ou de storage externo sem sair do Markdown:
138
138
 
139
139
  ```html
140
- <d-file src="/files/manual/release-checklist.txt" title="Checklist de release" size="1 KB">
140
+ <d-block-file src="/files/manual/release-checklist.txt" title="Checklist de release" size="1 KB">
141
141
  Baixe o anexo de exemplo usado neste manual.
142
- </d-file>
142
+ </d-block-file>
143
143
  ```
144
144
 
145
145
  Guarde arquivos versionados no repositório em `public/files/` e prefira caminhos absolutos do site, como `/files/...`.
@@ -48,7 +48,7 @@ Components use CSS custom properties for theme-aware styling:
48
48
 
49
49
  ## Customizing Code Block Colors
50
50
 
51
- The `DPageSourceCode` component has separate color schemes for light and dark modes, using Prism.js token classes. Override `token.*` classes in the `.source-code` SASS block to customize syntax highlighting colors.
51
+ The `DBlockSourceCode` component has separate color schemes for light and dark modes, using Prism.js token classes. Override `token.*` classes in the `.source-code` SASS block to customize syntax highlighting colors.
52
52
 
53
53
  ## Font Families
54
54
 
@@ -48,7 +48,7 @@ Os componentes usam propriedades CSS customizadas para estilização consciente
48
48
 
49
49
  ## Customizando Cores dos Blocos de Código
50
50
 
51
- O componente `DPageSourceCode` tem esquemas de cores separados para modos claro e escuro, usando classes de token do Prism.js. Sobrescreva as classes `token.*` no bloco SASS `.source-code` para customizar as cores de syntax highlighting.
51
+ O componente `DBlockSourceCode` tem esquemas de cores separados para modos claro e escuro, usando classes de token do Prism.js. Sobrescreva as classes `token.*` no bloco SASS `.source-code` para customizar as cores de syntax highlighting.
52
52
 
53
53
  ## Famílias de Fontes
54
54
 
@@ -0,0 +1,32 @@
1
+ ## Overview
2
+
3
+ Cards render a responsive grid of linked content blocks directly inside Markdown.
4
+
5
+ They are useful for landing sections, curated resource lists, and any place where a plain list of links feels too flat.
6
+
7
+ ## Markdown Syntax
8
+
9
+ ```html
10
+ <d-block-cards title="Explore more">
11
+ <d-block-card
12
+ title="Install"
13
+ description="Set up the project"
14
+ to="/guide/getting-started"
15
+ image="/images/cards/getting-started-cover.svg"
16
+ />
17
+ <d-block-card
18
+ title="GitHub"
19
+ description="Open the repository"
20
+ href="https://github.com/docsector/docsector-reader"
21
+ icon="launch"
22
+ />
23
+ </d-block-cards>
24
+ ```
25
+
26
+ ## Notes
27
+
28
+ - Use `to` for internal navigation and `href` for external URLs.
29
+ - Add `image` when the card should feel more like a landing-page tile.
30
+ - Add `icon` when the card has no image but still needs a stronger visual cue.
31
+ - Short descriptions scan better than paragraph-sized copy.
32
+ - Cover images look best in a wide format such as 16:9.
@@ -0,0 +1,32 @@
1
+ ## Visão geral
2
+
3
+ Cards renderizam uma grade responsiva de blocos com link diretamente dentro do Markdown.
4
+
5
+ Eles são úteis para seções de entrada, listas curadas de recursos e qualquer lugar em que uma lista simples de links fique visualmente pobre.
6
+
7
+ ## Sintaxe Markdown
8
+
9
+ ```html
10
+ <d-block-cards title="Explore mais">
11
+ <d-block-card
12
+ title="Instalação"
13
+ description="Configure o projeto"
14
+ to="/guide/getting-started"
15
+ image="/images/cards/getting-started-cover.svg"
16
+ />
17
+ <d-block-card
18
+ title="GitHub"
19
+ description="Abra o repositório"
20
+ href="https://github.com/docsector/docsector-reader"
21
+ icon="launch"
22
+ />
23
+ </d-block-cards>
24
+ ```
25
+
26
+ ## Notas
27
+
28
+ - Use `to` para navegação interna e `href` para URLs externas.
29
+ - Adicione `image` quando o card precisar se comportar mais como um bloco de landing page.
30
+ - Adicione `icon` quando o card não tiver imagem, mas ainda precisar de uma pista visual mais forte.
31
+ - Descrições curtas funcionam melhor do que textos longos.
32
+ - Imagens de capa ficam melhores em formatos largos, como 16:9.
@@ -0,0 +1,39 @@
1
+ ## Showcase
2
+
3
+ <d-block-cards title="Start here">
4
+ <d-block-card
5
+ title="Getting Started"
6
+ description="Install and run the project"
7
+ to="/guide/getting-started"
8
+ image="/images/cards/getting-started-cover.svg"
9
+ />
10
+ <d-block-card
11
+ title="Quick Links"
12
+ description="Open another navigation-focused block"
13
+ to="/manual/content/blocks/quick-links"
14
+ image="/images/cards/quick-links-cover.svg"
15
+ />
16
+ <d-block-card
17
+ title="GitHub"
18
+ description="Open the repository"
19
+ href="https://github.com/docsector/docsector-reader"
20
+ icon="launch"
21
+ />
22
+ </d-block-cards>
23
+
24
+ ## Without Cover Images
25
+
26
+ <d-block-cards title="Continue reading">
27
+ <d-block-card
28
+ title="Expandable"
29
+ description="Read the collapsible content block overview"
30
+ to="/manual/content/blocks/expandable"
31
+ icon="unfold_more"
32
+ />
33
+ <d-block-card
34
+ title="Page structure"
35
+ description="Review the main page container structure"
36
+ to="/manual/content/structures/page"
37
+ icon="view_quilt"
38
+ />
39
+ </d-block-cards>
@@ -0,0 +1,39 @@
1
+ ## Showcase
2
+
3
+ <d-block-cards title="Comece por aqui">
4
+ <d-block-card
5
+ title="Primeiros passos"
6
+ description="Instale e execute o projeto"
7
+ to="/guide/getting-started"
8
+ image="/images/cards/getting-started-cover.svg"
9
+ />
10
+ <d-block-card
11
+ title="Quick Links"
12
+ description="Abra outro block focado em navegação"
13
+ to="/manual/content/blocks/quick-links"
14
+ image="/images/cards/quick-links-cover.svg"
15
+ />
16
+ <d-block-card
17
+ title="GitHub"
18
+ description="Abra o repositório"
19
+ href="https://github.com/docsector/docsector-reader"
20
+ icon="launch"
21
+ />
22
+ </d-block-cards>
23
+
24
+ ## Sem imagens de capa
25
+
26
+ <d-block-cards title="Continue lendo">
27
+ <d-block-card
28
+ title="Expandable"
29
+ description="Leia a visão geral do block colapsável"
30
+ to="/manual/content/blocks/expandable"
31
+ icon="unfold_more"
32
+ />
33
+ <d-block-card
34
+ title="Estrutura de página"
35
+ description="Revise a estrutura principal do container de página"
36
+ to="/manual/content/structures/page"
37
+ icon="view_quilt"
38
+ />
39
+ </d-block-cards>