Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,9 @@ function createAlertComponent(
.filter(Boolean)
.join(' ')

// For component mode, we need to include raw HTML as an html node type
const iconChildren = config.iconElementHtml
? [{ type: 'text', value: config.iconElementHtml }]
? [{ type: 'html', value: config.iconElementHtml }]
: []

return {
Expand Down
80 changes: 78 additions & 2 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,13 +556,89 @@ describe('remarkGitHubAlerts', () => {
mode: 'component',
alerts: {
tip: {
iconElementHtml: '<svg>tip-icon</svg>',
iconElementHtml:
'<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 16 16"><path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.5-10a.5.5 0 0 0-1 0v4a.5.5 0 0 0 1 0V6zm0 6a.5.5 0 0 0-1 0v1a.5.5 0 0 0 1 0v-1z"/></svg>',
},
},
}
const result = await processMarkdown(markdown, options)

expect(result).toContain('tip-icon')
expect(result).toContain('<svg class="w-4 h-4"')
expect(result).toContain('fill="currentColor"')
expect(result).toContain('viewBox="0 0 16 16"')
expect(result).toContain(
'<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.5-10a.5.5 0 0 0-1 0v4a.5.5 0 0 0 1 0V6zm0 6a.5.5 0 0 0-1 0v1a.5.5 0 0 0 1 0v-1z"/>'
)
expect(result).toContain('</svg>')
})

it('should handle complex SVG icons in both modes', async () => {
const complexSvg =
'<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>'
const markdown = `> [!WARNING]
> Complex SVG test.`

// Test HTML mode
const htmlResult = await processMarkdown(markdown, {
mode: 'html',
alerts: {
warning: {
iconElementHtml: complexSvg,
},
},
})

expect(htmlResult).toContain(complexSvg)
expect(htmlResult).not.toContain('&lt;svg')
expect(htmlResult).not.toContain('data-alert-type')

// Test component mode
const componentResult = await processMarkdown(markdown, {
mode: 'component',
alerts: {
warning: {
iconElementHtml: complexSvg,
},
},
})

expect(componentResult).toContain('<svg class="w-4 h-4"')
expect(componentResult).toContain('stroke="currentColor"')
expect(componentResult).toContain('stroke-linecap="round"')
expect(componentResult).toContain('data-alert-type="warning"')
expect(componentResult).not.toContain('&lt;svg')
})

it('should handle emoji and text icons correctly in both modes', async () => {
const emojiIcon = '⚠️'
const markdown = `> [!CAUTION]
> Emoji icon test.`

// Test HTML mode
const htmlResult = await processMarkdown(markdown, {
mode: 'html',
alerts: {
caution: {
iconElementHtml: emojiIcon,
},
},
})

expect(htmlResult).toContain(emojiIcon)
expect(htmlResult).not.toContain('data-alert-type')

// Test component mode
const componentResult = await processMarkdown(markdown, {
mode: 'component',
alerts: {
caution: {
iconElementHtml: emojiIcon,
},
},
})

expect(componentResult).toContain(emojiIcon)
expect(componentResult).toContain('data-alert-type="caution"')
})
})

Expand Down