Preface#
Some small modifications have been made to the current theme, recording the changes in hopes of helping everyone || If there are any mistakes, please feel free to discuss, I am a newbie ||
Warning
Tip
The modifications are based on personal preference; if you have different ideas, feel free to discuss in the comments.
Modify the Display of Information in the Top Navigation Bar#
The relevant file path is src\components\layout\header\config.ts
The display and order of the navigation bar are defined in headerMenuConfig, which can be modified as needed.
For example, the friend links have been moved out of the secondary level.


Optimize the Page Effect When Displaying Images with Excessive Height#
If the image height is too long, it will occupy the entire page, which may result in the entire page being filled with the image during browsing. The display effect for excessively tall images is not good. We can limit the height of the element using max-height in CSS.
Find the following part in src\components\ui\image\ZoomedImage.tsx and add max-height max-h-[70vh] w-auto object-contain to ensure that the maximum height of the image does not exceed 70% (parameters can be adjusted as needed), while the width remains adaptive, allowing the image to be fully displayed without being cropped.
const styles = tv({
base: 'rounded-xl overflow-hidden text-center inline-flex items-center justify-center duration-200 max-height max-h-[70vh] w-auto object-contain',
variants: {
status: {
loading: 'hidden opacity-0',
loaded: 'opacity-100 block',
error: 'hidden opacity-0',
},
},
})
::: grid {cols=2, rows=1, gap=4, type=images}


:::
Enhance the Alert Component to Support Custom Titles#
The markdown syntax extended by Shiro includes GitHub alerts, but it restricts the display of titles to only NOTE, IMPORTANT, WARNING, TIP, CAUTION.
Since I use Obsidian to edit Markdown files, the alerts can support custom title styles, with the syntax as follows:
> [!WARNING] Any title text
> Other text content
Updated on 2025.7.8, innei has updated the handling of blockquotes and alerts, rendering the original method obsolete!
So I used Claude to help modify the file to achieve the same effect.
src\components\ui\markdown\parsers\blockquote.tsx
import React, { Children, cloneElement, useMemo, type FC, type ReactNode } from 'react';
import { GitAlert } from './alert';
const getNodeText = (node: ReactNode): string =>
node == null
? ''
: typeof node === 'string' || typeof node === 'number'
? node.toString()
: Array.isArray(node)
? node.map(getNodeText).join('')
: React.isValidElement<{ children?: ReactNode }>(node)
? getNodeText(node.props.children)
: '';
export const MBlockQuote: FC<{ className?: string; children: ReactNode; alert?: string }> = ({
className,
children,
alert,
}) => {
if (alert) return <GitAlert type={alert}>{children}</GitAlert>;
const { isAlert, alertType, title, content } = useMemo(() => {
const childrenArray = Children.toArray(children);
const firstText = getNodeText(childrenArray[0]).trim();
const alertMatch = firstText.match(/^\[!(\w+)\](?:\s(.*))?/);
if (!alertMatch) return { isAlert: false, alertType: '', title: undefined, content: childrenArray };
const [_, type, customTitle] = alertMatch;
const contentNodes = childrenArray.map((child, i) => {
if (i === 0 && React.isValidElement<{ children?: ReactNode }>(child)) {
const internalChildren = Children.toArray(child.props.children);
if (typeof internalChildren[0] === 'string') {
const text = internalChildren[0].replace(/^\s*\[!(\w+)\]\s*[^\n]*\n?/, '');
return cloneElement(child, { key: 'first-child-content' }, text, ...internalChildren.slice(1));
}
}
return child;
});
return { isAlert: true, alertType: type.toUpperCase(), title: customTitle?.trim(), content: contentNodes };
}, [children]);
return isAlert ? (
<GitAlert type={alertType} title={title}>
{content}
</GitAlert>
) : (
<blockquote className={className}>{children}</blockquote>
);
};
src\components\ui\markdown\parsers\alert.tsx
CAUTION: FluentShieldError20Regular,
}
const AlertIcon: FC<{
type: keyof typeof typedIconMap
title?: string
}> = ({ type, title }) => {
const finalType = type || 'NOTE'
const Icon = typedIconMap[finalType] || typedIconMap.NOTE
const typePrefix = title || (finalType[0] + finalType.toLowerCase().slice(1));
return (
<span
@@ -57,9 +58,8 @@ export const AlertIcon: FC<{
)
}
export const GitAlert: FC<{ type: string; title?: string; children: React.ReactNode }> = (props) => {
const { type, title, children } = props
const upperType = type.toUpperCase() as keyof typeof borderColorMap
return (
<blockquote
@@ -71,10 +71,10 @@ export const GitAlert = (props: { type: string; text: string }) => {
'not-italic',
)}
>
<AlertIcon type={upperType as any} title={title} />
<br />
{children}
</blockquote>
)
}
Collapsed content for historical processing methods
```tsx import clsx from 'clsx' import type { MarkdownToJSX } from 'markdown-to-jsx' import { blockRegex, Priority } from 'markdown-to-jsx' import type { FC } from 'react'import {
FluentShieldError 20 Regular,
FluentWarning 28 Regular,
IonInformation,
} from '~/components/icons/status'
import { Markdown } from '../Markdown'
const textColorMap = {
NOTE: 'text-blue-500 dark: text-blue-400',
IMPORTANT: 'text-accent',
WARNING: 'text-amber-500 dark: text-amber-400',
TIP: 'text-green-500 dark: text-green-400',
CAUTION: 'text-red-500 dark: text-red-400',
} as any
const borderColorMap = {
NOTE: 'before: bg-blue-500 before: bg-blue-400',
IMPORTANT: 'before: bg-accent',
WARNING: 'before: bg-amber-500 dark:before: bg-amber-400',
TIP: 'before: bg-green-500 dark:before: bg-green-400',
CAUTION: 'before: bg-red-500 dark:before: bg-red-400',
} as any
const typedIconMap = {
NOTE: IonInformation,
IMPORTANT: FluentWarning 28 Regular,
WARNING: FluentShieldError 20 Regular,
TIP: IonInformation,
CAUTION: FluentShieldError 20 Regular,
}
export const AlertIcon: FC<{
type: keyof typeof typedIconMap
title?: string // Define title
}> = ({ type, title }) => { // Add title
const finalType = type || 'NOTE'
const Icon = typedIconMap[finalType] || typedIconMap.NOTE
const typePrefix = title || (finalType[0] + finalType.toLowerCase().slice(1)) // If title has value, get title, otherwise keep the same as before
return (
<span
className={clsx('mb-1 inline-flex items-center', textColorMap[finalType])}
>
<Icon
className={clsx(
shrink-0 text-3 xl md: mr-2 md: self-start md: text-left,
typedIconMap[finalType] || typedIconMap.NOTE,
)}
/>
{typePrefix}
</span>
)
}
/**
-
[!NOTE]
-
Highlights information that users should take into account, even when skimming.
/
const ALERT_BLOCKQUOTE_R =
/^(> \ [!(?NOTE|IMPORTANT|WARNING|TIP|CAUTION)](?.?)) (?<body>(?:\n >.)*)(?=\n{2,}|$)/ // Modify regular expression to include title retrieval
export const AlertsRule: MarkdownToJSX.Rule = {
match: blockRegex(ALERT_BLOCKQUOTE_R),
order: Priority.HIGH,
parse(capture) {
return {
raw: capture[0],
parsed: {
… capture.groups,
},
} as any
},
react(node, output, state) {
const { type, body, title } = node.parsed // Add title
let first = true // Control the replacement logic for replace, the first line removes >, the rest lines replace with
const bodyClean = body.replace(/^> */gm, (match: string) => first ? (first = false, '') : '
').trim() // Replacement logic modification
return (
<blockquote
className={clsx(borderColorMap[type], 'not-italic')}
key={state.key}
>
<!-- Add title parsing, adjust line break logic -->
<AlertIcon type={type as any} title={title} />
<Markdown
allowsScript
className="not-prose w-full [&>p:first-child]:mt-0"
>
{bodyClean}
</Markdown>
</blockquote>
)
},
}
</details>
After modification, the following effects can be achieved:
```text
<div />Type 1
> [!WARNING] Any title text
> Other text content
<div />Type 2
> [!NOTE] Any title text
> Other text content
<div />Type 3
> [!NOTE]
> Original method
Warning
Any title text
Other text content
Note
Any title text
Other text content
Note
Original method
This article was synchronized and updated to xLog by Mix Space
The original link is https://blog.lolita.best/posts/blog/ShiroModifySumika