@docsector/docsector-reader 3.6.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 (47) hide show
  1. package/README.md +10 -11
  2. package/bin/docsector.js +1 -283
  3. package/package.json +1 -1
  4. package/src/components/{DPageBlockquote.vue → DBlockBlockquote.vue} +4 -0
  5. package/src/components/{DBlockCard.vue → DBlockCards.vue} +1 -1
  6. package/src/components/{DPageEmbeddedUrl.vue → DBlockEmbeddedUrl.vue} +1 -1
  7. package/src/components/{DPageExpandable.vue → DBlockExpandable.vue} +4 -0
  8. package/src/components/{DPageFile.vue → DBlockFile.vue} +1 -1
  9. package/src/components/{DPageImage.vue → DBlockImage.vue} +1 -1
  10. package/src/components/{DMermaidDiagram.vue → DBlockMermaidDiagram.vue} +4 -0
  11. package/src/components/{DQuickLinks.vue → DBlockQuickLinks.vue} +4 -0
  12. package/src/components/{DPageSourceCode.vue → DBlockSourceCode.vue} +6 -1
  13. package/src/components/DBlockStepper.vue +210 -0
  14. package/src/components/DBlockTimeline.vue +319 -0
  15. package/src/components/DPageTokens.vue +46 -20
  16. package/src/components/page-section-tokens.js +273 -10
  17. package/src/i18n/languages/en-US.hjson +5 -0
  18. package/src/i18n/languages/pt-BR.hjson +5 -0
  19. package/src/pages/guide/i18n-and-markdown.overview.en-US.md +6 -6
  20. package/src/pages/guide/i18n-and-markdown.overview.pt-BR.md +6 -6
  21. package/src/pages/guide/theming.overview.en-US.md +1 -1
  22. package/src/pages/guide/theming.overview.pt-BR.md +1 -1
  23. package/src/pages/manual/content/blocks/embedded-urls.overview.en-US.md +3 -3
  24. package/src/pages/manual/content/blocks/embedded-urls.overview.pt-BR.md +3 -3
  25. package/src/pages/manual/content/blocks/embedded-urls.showcase.en-US.md +8 -8
  26. package/src/pages/manual/content/blocks/embedded-urls.showcase.pt-BR.md +8 -8
  27. package/src/pages/manual/content/blocks/expandable.overview.en-US.md +8 -8
  28. package/src/pages/manual/content/blocks/expandable.overview.pt-BR.md +8 -8
  29. package/src/pages/manual/content/blocks/expandable.showcase.en-US.md +6 -6
  30. package/src/pages/manual/content/blocks/expandable.showcase.pt-BR.md +6 -6
  31. package/src/pages/manual/content/blocks/files.overview.en-US.md +3 -3
  32. package/src/pages/manual/content/blocks/files.overview.pt-BR.md +3 -3
  33. package/src/pages/manual/content/blocks/files.showcase.en-US.md +5 -5
  34. package/src/pages/manual/content/blocks/files.showcase.pt-BR.md +5 -5
  35. package/src/pages/manual/content/blocks/quick-links.overview.en-US.md +4 -4
  36. package/src/pages/manual/content/blocks/quick-links.overview.pt-BR.md +4 -4
  37. package/src/pages/manual/content/blocks/quick-links.showcase.en-US.md +9 -9
  38. package/src/pages/manual/content/blocks/quick-links.showcase.pt-BR.md +9 -9
  39. package/src/pages/manual/content/blocks/stepper.overview.en-US.md +59 -0
  40. package/src/pages/manual/content/blocks/stepper.overview.pt-BR.md +59 -0
  41. package/src/pages/manual/content/blocks/stepper.showcase.en-US.md +115 -0
  42. package/src/pages/manual/content/blocks/stepper.showcase.pt-BR.md +115 -0
  43. package/src/pages/manual/content/blocks/timeline.overview.en-US.md +47 -0
  44. package/src/pages/manual/content/blocks/timeline.overview.pt-BR.md +47 -0
  45. package/src/pages/manual/content/blocks/timeline.showcase.en-US.md +170 -0
  46. package/src/pages/manual/content/blocks/timeline.showcase.pt-BR.md +170 -0
  47. package/src/pages/manual.index.js +56 -0
@@ -15,6 +15,8 @@ const ALERT_MESSAGE_TYPES = new Set([
15
15
 
16
16
  const CARDS_MARKER_PREFIX = '@@DOCSECTOR_CARDS_'
17
17
  const QUICK_LINKS_MARKER_PREFIX = '@@DOCSECTOR_QUICK_LINKS_'
18
+ const TIMELINE_MARKER_PREFIX = '@@DOCSECTOR_TIMELINE_'
19
+ const STEPPER_MARKER_PREFIX = '@@DOCSECTOR_STEPPER_'
18
20
  const EXPANDABLE_MARKER_PREFIX = '@@DOCSECTOR_EXPANDABLE_'
19
21
  const FILE_MARKER_PREFIX = '@@DOCSECTOR_FILE_'
20
22
  const EMBEDDED_URL_MARKER_PREFIX = '@@DOCSECTOR_EMBEDDED_URL_'
@@ -147,11 +149,11 @@ const extractQuickLinksBlocks = (source = '') => {
147
149
  const map = new Map()
148
150
  let index = 0
149
151
 
150
- 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
151
153
  const replaced = String(source).replace(blockPattern, (_, blockAttrsRaw, inner) => {
152
154
  const blockAttrs = parseCustomTagAttributes(blockAttrsRaw)
153
155
  const items = []
154
- const itemPattern = /<d-quick-link\b([^>]*)\/?\s*>/gi
156
+ const itemPattern = /<d-block-quick-link\b([^>]*)\/?\s*>/gi
155
157
 
156
158
  let itemMatch = itemPattern.exec(inner)
157
159
  while (itemMatch !== null) {
@@ -195,11 +197,11 @@ const extractCardsBlocks = (source = '') => {
195
197
  const map = new Map()
196
198
  let index = 0
197
199
 
198
- const blockPattern = /<d-(?:block-)?cards\b([^>]*)>([\s\S]*?)<\/d-(?:block-)?cards>/gi
200
+ const blockPattern = /<d-block-cards\b([^>]*)>([\s\S]*?)<\/d-block-cards>/gi
199
201
  const replaced = String(source).replace(blockPattern, (_, blockAttrsRaw, inner) => {
200
202
  const blockAttrs = parseCustomTagAttributes(blockAttrsRaw)
201
203
  const items = []
202
- const itemPattern = /<d-(?:block-)?card\b([^>]*)\/?\s*>/gi
204
+ const itemPattern = /<d-block-card\b([^>]*)\/?\s*>/gi
203
205
 
204
206
  let itemMatch = itemPattern.exec(inner)
205
207
  while (itemMatch !== null) {
@@ -244,11 +246,166 @@ const parseExpandableOpenState = (raw = '') => {
244
246
  return ['1', 'true', 'yes', 'on'].includes(String(raw).trim().toLowerCase())
245
247
  }
246
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
+
247
404
  const extractExpandableBlocks = (source = '') => {
248
405
  const map = new Map()
249
406
  let index = 0
250
407
 
251
- const blockPattern = /<d-expandable\b([^>]*)>([\s\S]*?)<\/d-expandable>/gi
408
+ const blockPattern = /<d-block-expandable\b([^>]*)>([\s\S]*?)<\/d-block-expandable>/gi
252
409
  const replaced = String(source).replace(blockPattern, (_, rawAttrs, inner) => {
253
410
  const attrs = parseCustomTagAttributes(rawAttrs)
254
411
  const marker = `${EXPANDABLE_MARKER_PREFIX}${index}@@`
@@ -314,10 +471,10 @@ const extractFileBlocks = (source = '') => {
314
471
  return `\n${marker}\n`
315
472
  }
316
473
 
317
- 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) => {
318
475
  return replaceBlock(match, rawAttrs)
319
476
  })
320
- 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)
321
478
 
322
479
  return {
323
480
  source: replaced,
@@ -349,10 +506,10 @@ const extractEmbeddedUrlBlocks = (source = '') => {
349
506
  return `\n${marker}\n`
350
507
  }
351
508
 
352
- 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) => {
353
510
  return replaceBlock(match, rawAttrs)
354
511
  })
355
- 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)
356
513
 
357
514
  return {
358
515
  source: replaced,
@@ -403,6 +560,12 @@ const escapeHtml = (value = '') => {
403
560
  .replace(/'/g, '&#39;')
404
561
  }
405
562
 
563
+ const stripHtmlTags = (value = '') => {
564
+ return decodeHtmlEntities(String(value).replace(/<[^>]+>/g, ' '))
565
+ .replace(/\s+/g, ' ')
566
+ .trim()
567
+ }
568
+
406
569
  const extractTagAttributes = (html = '', tagName = '') => {
407
570
  const match = String(html).match(new RegExp(`<${tagName}\\b([^>]*)\\/?>(?![\\s\\S]*<${tagName}\\b)`, 'i'))
408
571
 
@@ -635,6 +798,35 @@ const getHeadingAnchorId = (markdown, currentTag, element, env, parserState) =>
635
798
  return parserState.headingSlugger.slug(headingText)
636
799
  }
637
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
+
638
830
  export const tokenizePageSectionSource = (source = '', options = {}) => {
639
831
  const {
640
832
  allowHeadingTokens = true,
@@ -642,7 +834,31 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
642
834
  } = options
643
835
  const normalizedSource = normalizePageSectionSource(source)
644
836
  const { source: sourceWithShieldedCode, codeSegmentsMap } = shieldMarkdownCodeSegments(normalizedSource)
645
- 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)
646
862
 
647
863
  expandableMap.forEach((data, marker) => {
648
864
  expandableMap.set(marker, {
@@ -815,6 +1031,53 @@ export const tokenizePageSectionSource = (source = '', options = {}) => {
815
1031
  case 'inline': {
816
1032
  const anchorId = getHeadingAnchorId(markdown, tag, element, markdownEnv, parserState)
817
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
+
818
1081
  if (expandableMap.has(element.content.trim())) {
819
1082
  const data = expandableMap.get(element.content.trim())
820
1083
 
@@ -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
 
@@ -7,15 +7,15 @@ This block is a higher-level alternative to raw iframe markup when the source is
7
7
  ## Markdown Syntax
8
8
 
9
9
  ```html
10
- <d-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE" title="YouTube player demo">
10
+ <d-block-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE" title="YouTube player demo">
11
11
  Optional caption rendered as inline Markdown.
12
- </d-embedded-url>
12
+ </d-block-embedded-url>
13
13
  ```
14
14
 
15
15
  You can also omit the caption body when the provider preview already gives enough context:
16
16
 
17
17
  ```html
18
- <d-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P" />
18
+ <d-block-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P" />
19
19
  ```
20
20
 
21
21
  ## Supported Providers
@@ -7,15 +7,15 @@ Este block é uma alternativa de nível mais alto ao uso manual de iframe quando
7
7
  ## Sintaxe Markdown
8
8
 
9
9
  ```html
10
- <d-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE" title="Demo do player do YouTube">
10
+ <d-block-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE" title="Demo do player do YouTube">
11
11
  Legenda opcional renderizada como Markdown inline.
12
- </d-embedded-url>
12
+ </d-block-embedded-url>
13
13
  ```
14
14
 
15
15
  Você também pode omitir o corpo quando o preview do provider já entrega contexto suficiente:
16
16
 
17
17
  ```html
18
- <d-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P" />
18
+ <d-block-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P" />
19
19
  ```
20
20
 
21
21
  ## Providers suportados
@@ -2,24 +2,24 @@
2
2
 
3
3
  ### YouTube Video
4
4
 
5
- <d-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE&autoplay=1&loop=1" title="YouTube player demo">
5
+ <d-block-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE&autoplay=1&loop=1" title="YouTube player demo">
6
6
  The original playback query parameters stay attached to the provider URL.
7
- </d-embedded-url>
7
+ </d-block-embedded-url>
8
8
 
9
9
  ### Spotify Track
10
10
 
11
- <d-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P?si=1234">
11
+ <d-block-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P?si=1234">
12
12
  Spotify links render with the provider-specific compact player height.
13
- </d-embedded-url>
13
+ </d-block-embedded-url>
14
14
 
15
15
  ### CodePen Demo
16
16
 
17
- <d-embedded-url url="https://codepen.io/team/codepen/pen/PNaGbb?default-tab=result" title="Interactive demo">
17
+ <d-block-embedded-url url="https://codepen.io/team/codepen/pen/PNaGbb?default-tab=result" title="Interactive demo">
18
18
  Use the same block for live front-end demos without dropping to raw HTML.
19
- </d-embedded-url>
19
+ </d-block-embedded-url>
20
20
 
21
21
  ### Unsupported URL Fallback
22
22
 
23
- <d-embedded-url url="https://example.com/docs/embed-me" title="External API docs">
23
+ <d-block-embedded-url url="https://example.com/docs/embed-me" title="External API docs">
24
24
  Unsupported providers render a safe link card so the reading flow still keeps the URL visible and actionable.
25
- </d-embedded-url>
25
+ </d-block-embedded-url>
@@ -2,24 +2,24 @@
2
2
 
3
3
  ### Vídeo do YouTube
4
4
 
5
- <d-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE&autoplay=1&loop=1" title="Demo do player do YouTube">
5
+ <d-block-embedded-url url="https://www.youtube.com/watch?v=M7lc1UVf-VE&autoplay=1&loop=1" title="Demo do player do YouTube">
6
6
  Os parâmetros originais de reprodução continuam anexados à URL do provider.
7
- </d-embedded-url>
7
+ </d-block-embedded-url>
8
8
 
9
9
  ### Faixa do Spotify
10
10
 
11
- <d-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P?si=1234">
11
+ <d-block-embedded-url url="https://open.spotify.com/track/7ouMYWpwJ422jRcDASZB7P?si=1234">
12
12
  Links do Spotify renderizam com a altura compacta específica do provider.
13
- </d-embedded-url>
13
+ </d-block-embedded-url>
14
14
 
15
15
  ### Demo no CodePen
16
16
 
17
- <d-embedded-url url="https://codepen.io/team/codepen/pen/PNaGbb?default-tab=result" title="Demo interativa">
17
+ <d-block-embedded-url url="https://codepen.io/team/codepen/pen/PNaGbb?default-tab=result" title="Demo interativa">
18
18
  Use o mesmo block para demos front-end ao vivo sem cair para HTML bruto.
19
- </d-embedded-url>
19
+ </d-block-embedded-url>
20
20
 
21
21
  ### Fallback para URL não suportada
22
22
 
23
- <d-embedded-url url="https://example.com/docs/embed-me" title="Documentação externa da API">
23
+ <d-block-embedded-url url="https://example.com/docs/embed-me" title="Documentação externa da API">
24
24
  Providers não suportados renderizam um card seguro com link externo, mantendo a URL visível e acionável no fluxo de leitura.
25
- </d-embedded-url>
25
+ </d-block-embedded-url>
@@ -4,32 +4,32 @@ Expandable blocks collapse secondary content behind a clickable title.
4
4
 
5
5
  They are a good fit when the main section should stay short, but readers may still need optional details, checklists, appendix material, or longer examples.
6
6
 
7
- The block is authored with the custom Markdown element `<d-expandable>`.
7
+ The block is authored with the custom Markdown element `<d-block-expandable>`.
8
8
 
9
9
  ## HTML Example
10
10
 
11
11
  The custom element can be authored directly in page Markdown:
12
12
 
13
13
  ````html
14
- <d-expandable title="Why hide this content?">
14
+ <d-block-expandable title="Why hide this content?">
15
15
 
16
16
  Use expandable blocks when the main section should stay concise but readers may still need more detail.
17
17
 
18
- </d-expandable>
18
+ </d-block-expandable>
19
19
 
20
20
  ### Open by Default
21
21
 
22
- <d-expandable title="Release checklist" open="true">
22
+ <d-block-expandable title="Release checklist" open="true">
23
23
 
24
24
  - Review breaking changes
25
25
  - Update screenshots
26
26
  - Run smoke tests
27
27
 
28
- </d-expandable>
28
+ </d-block-expandable>
29
29
 
30
30
  ### Rich Content
31
31
 
32
- <d-expandable title="Deployment appendix">
32
+ <d-block-expandable title="Deployment appendix">
33
33
 
34
34
  > [!TIP]
35
35
  > Keep the primary flow in the main section and move optional details here.
@@ -39,11 +39,11 @@ npm install
39
39
  npm run build
40
40
  ```
41
41
 
42
- </d-expandable>
42
+ </d-block-expandable>
43
43
  ````
44
44
 
45
45
  ## Notes
46
46
 
47
47
  - Use `open="true"` when the section should start expanded.
48
48
  - Keep page headings outside the expandable block. Headings inside the body are flattened to regular paragraphs so the page ToC stays stable.
49
- - Avoid nesting one `<d-expandable>` inside another in this first version.
49
+ - Avoid nesting one `<d-block-expandable>` inside another in this first version.