SumikaNya

SumikaNya

Some modifications to the Shiro theme

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.
image
image

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}
The image fills the entire page
Added a limit of 70% effect
:::

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
Type 1

Warning

Any title text
Other text content

Type 2

Note

Any title text
Other text content

Type 3

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


Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.