|
| 1 | +// swizzled component from a standard Admonition |
| 2 | +import React from 'react'; |
| 3 | +import clsx from 'clsx'; |
| 4 | +import {ThemeClassNames} from '@docusaurus/theme-common'; |
| 5 | +import Translate from '@docusaurus/Translate'; |
| 6 | +import styles from './styles.module.css'; |
| 7 | +function NoteIcon() { |
| 8 | + return ( |
| 9 | + <svg viewBox="0 0 14 16"> |
| 10 | + <path |
| 11 | + fillRule="evenodd" |
| 12 | + d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z" |
| 13 | + /> |
| 14 | + </svg> |
| 15 | + ); |
| 16 | +} |
| 17 | +function TipIcon() { |
| 18 | + return ( |
| 19 | + <svg viewBox="0 0 12 16"> |
| 20 | + <path |
| 21 | + fillRule="evenodd" |
| 22 | + d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z" |
| 23 | + /> |
| 24 | + </svg> |
| 25 | + ); |
| 26 | +} |
| 27 | +function DangerIcon() { |
| 28 | + return ( |
| 29 | + <svg viewBox="0 0 12 16"> |
| 30 | + <path |
| 31 | + fillRule="evenodd" |
| 32 | + d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z" |
| 33 | + /> |
| 34 | + </svg> |
| 35 | + ); |
| 36 | +} |
| 37 | +function InfoIcon() { |
| 38 | + return ( |
| 39 | + <svg viewBox="0 0 14 16"> |
| 40 | + <path |
| 41 | + fillRule="evenodd" |
| 42 | + d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z" |
| 43 | + /> |
| 44 | + </svg> |
| 45 | + ); |
| 46 | +} |
| 47 | +function CautionIcon() { |
| 48 | + return ( |
| 49 | + <svg viewBox="0 0 16 16"> |
| 50 | + <path |
| 51 | + fillRule="evenodd" |
| 52 | + d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z" |
| 53 | + /> |
| 54 | + </svg> |
| 55 | + ); |
| 56 | +} |
| 57 | +// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style |
| 58 | +const AdmonitionConfigs = { |
| 59 | + note: { |
| 60 | + infimaClassName: 'secondary', |
| 61 | + iconComponent: NoteIcon, |
| 62 | + label: ( |
| 63 | + <Translate |
| 64 | + id="theme.admonition.note" |
| 65 | + description="The default label used for the Note admonition (:::note)"> |
| 66 | + note |
| 67 | + </Translate> |
| 68 | + ), |
| 69 | + }, |
| 70 | + tip: { |
| 71 | + infimaClassName: 'success', |
| 72 | + iconComponent: TipIcon, |
| 73 | + label: ( |
| 74 | + <Translate |
| 75 | + id="theme.admonition.tip" |
| 76 | + description="The default label used for the Tip admonition (:::tip)"> |
| 77 | + tip |
| 78 | + </Translate> |
| 79 | + ), |
| 80 | + }, |
| 81 | + danger: { |
| 82 | + infimaClassName: 'danger', |
| 83 | + iconComponent: DangerIcon, |
| 84 | + label: ( |
| 85 | + <Translate |
| 86 | + id="theme.admonition.danger" |
| 87 | + description="The default label used for the Danger admonition (:::danger)"> |
| 88 | + danger |
| 89 | + </Translate> |
| 90 | + ), |
| 91 | + }, |
| 92 | + info: { |
| 93 | + infimaClassName: 'info', |
| 94 | + iconComponent: InfoIcon, |
| 95 | + label: ( |
| 96 | + <Translate |
| 97 | + id="theme.admonition.info" |
| 98 | + description="The default label used for the Info admonition (:::info)"> |
| 99 | + info |
| 100 | + </Translate> |
| 101 | + ), |
| 102 | + }, |
| 103 | + caution: { |
| 104 | + infimaClassName: 'warning', |
| 105 | + iconComponent: CautionIcon, |
| 106 | + label: ( |
| 107 | + <Translate |
| 108 | + id="theme.admonition.caution" |
| 109 | + description="The default label used for the Caution admonition (:::caution)"> |
| 110 | + caution |
| 111 | + </Translate> |
| 112 | + ), |
| 113 | + }, |
| 114 | + // custom backcompatible type |
| 115 | + warning: { |
| 116 | + infimaClassName: 'warning', |
| 117 | + iconComponent: CautionIcon, |
| 118 | + label: ( |
| 119 | + <Translate |
| 120 | + id="theme.admonition.caution" |
| 121 | + description="The default label used for the Caution admonition (:::caution)"> |
| 122 | + warning |
| 123 | + </Translate> |
| 124 | + ), |
| 125 | + }, |
| 126 | +}; |
| 127 | +// Legacy aliases, undocumented but kept for retro-compatibility |
| 128 | +const aliases = { |
| 129 | + secondary: 'note', |
| 130 | + important: 'info', |
| 131 | + success: 'tip', |
| 132 | + // warning: 'danger', // use custom type instead |
| 133 | +}; |
| 134 | +function getAdmonitionConfig(unsafeType) { |
| 135 | + const type = aliases[unsafeType] ?? unsafeType; |
| 136 | + const config = AdmonitionConfigs[type]; |
| 137 | + if (config) { |
| 138 | + return config; |
| 139 | + } |
| 140 | + console.warn( |
| 141 | + `No admonition config found for admonition type "${type}". Using Info as fallback.`, |
| 142 | + ); |
| 143 | + return AdmonitionConfigs.info; |
| 144 | +} |
| 145 | +// Workaround because it's difficult in MDX v1 to provide a MDX title as props |
| 146 | +// See https://github.com/facebook/docusaurus/pull/7152#issuecomment-1145779682 |
| 147 | +function extractMDXAdmonitionTitle(children) { |
| 148 | + const items = React.Children.toArray(children); |
| 149 | + const mdxAdmonitionTitle = items.find( |
| 150 | + (item) => |
| 151 | + React.isValidElement(item) && |
| 152 | + item.props?.mdxType === 'mdxAdmonitionTitle', |
| 153 | + ); |
| 154 | + const rest = <>{items.filter((item) => item !== mdxAdmonitionTitle)}</>; |
| 155 | + return { |
| 156 | + mdxAdmonitionTitle, |
| 157 | + rest, |
| 158 | + }; |
| 159 | +} |
| 160 | +function processAdmonitionProps(props) { |
| 161 | + const {mdxAdmonitionTitle, rest} = extractMDXAdmonitionTitle(props.children); |
| 162 | + return { |
| 163 | + ...props, |
| 164 | + title: props.title ?? mdxAdmonitionTitle, |
| 165 | + children: rest, |
| 166 | + }; |
| 167 | +} |
| 168 | +export default function Admonition(props) { |
| 169 | + const {children, type, title, icon: iconProp} = processAdmonitionProps(props); |
| 170 | + const typeConfig = getAdmonitionConfig(type); |
| 171 | + const titleLabel = title ?? typeConfig.label; |
| 172 | + const {iconComponent: IconComponent} = typeConfig; |
| 173 | + const icon = iconProp ?? <IconComponent />; |
| 174 | + return ( |
| 175 | + <div |
| 176 | + className={clsx( |
| 177 | + ThemeClassNames.common.admonition, |
| 178 | + ThemeClassNames.common.admonitionType(props.type), |
| 179 | + 'alert', |
| 180 | + `alert--${typeConfig.infimaClassName}`, |
| 181 | + styles.admonition, |
| 182 | + )}> |
| 183 | + <div className={styles.admonitionHeading}> |
| 184 | + <span className={styles.admonitionIcon}>{icon}</span> |
| 185 | + {titleLabel} |
| 186 | + </div> |
| 187 | + <div className={styles.admonitionContent}>{children}</div> |
| 188 | + </div> |
| 189 | + ); |
| 190 | +} |
0 commit comments