Merge 37b131a902f1ad0c3e9d97081b40b1be2a363dde into 12b3f76cc497ea59c471b9eeb89f9bbb58991dba

This commit is contained in:
Hannah Issermann 2025-11-01 01:39:42 +01:00 committed by GitHub
commit d40e12d382
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 23 deletions

View File

@ -38,9 +38,16 @@ interface Props {
* @default false * @default false
*/ */
nestedInExample?: boolean nestedInExample?: boolean
/**
* Defines label to complete 'Edit code on Stackblitz' and/or 'Copy code to clipboard' buttons aria-labels.
*/
buttonLabel?: string
} }
const { class: className, code, containerClass, fileMatch, filePath, lang, nestedInExample = false } = Astro.props const { class: className, code, containerClass, fileMatch, filePath, lang, nestedInExample = false, buttonLabel } = Astro.props
const clipboardLabel = buttonLabel ? `Copy ${buttonLabel} code to clipboard` : filePath ?
`Copy ${filePath} code to clipboard` : 'Copy code to clipboard'
let codeToDisplay = filePath let codeToDisplay = filePath
? fs.readFileSync(path.join(process.cwd(), filePath), 'utf8') ? fs.readFileSync(path.join(process.cwd(), filePath), 'utf8')
@ -62,17 +69,15 @@ if (filePath && fileMatch && codeToDisplay) {
<script> <script>
import ClipboardJS from 'clipboard' import ClipboardJS from 'clipboard'
const btnTitle = 'Copy to clipboard' function snippetButtonTooltip(selector: string, tooltipLabel: string) {
const btnEdit = 'Edit on StackBlitz'
function snippetButtonTooltip(selector: string, title: string) {
document.querySelectorAll(selector).forEach((btn) => { document.querySelectorAll(selector).forEach((btn) => {
bootstrap.Tooltip.getOrCreateInstance(btn, { title }) bootstrap.Tooltip.getOrCreateInstance(btn, { title: tooltipLabel })
}) })
} }
snippetButtonTooltip('.btn-clipboard', btnTitle) const clipboardTooltip = 'Copy to clipboard'
snippetButtonTooltip('.btn-edit', btnEdit) snippetButtonTooltip('.btn-clipboard', clipboardTooltip)
snippetButtonTooltip('.btn-edit', 'Edit on StackBlitz')
const clipboard = new ClipboardJS('.btn-clipboard', { const clipboard = new ClipboardJS('.btn-clipboard', {
target: (trigger) => trigger.closest('.bd-code-snippet')?.querySelector('.highlight')!, target: (trigger) => trigger.closest('.bd-code-snippet')?.querySelector('.highlight')!,
@ -100,7 +105,7 @@ if (filePath && fileMatch && codeToDisplay) {
event.trigger.addEventListener( event.trigger.addEventListener(
'hidden.bs.tooltip', 'hidden.bs.tooltip',
() => { () => {
tooltipBtn?.setContent({ '.tooltip-inner': btnTitle }) tooltipBtn?.setContent({ '.tooltip-inner': clipboardTooltip })
}, },
{ once: true } { once: true }
) )
@ -128,7 +133,7 @@ if (filePath && fileMatch && codeToDisplay) {
event.trigger.addEventListener( event.trigger.addEventListener(
'hidden.bs.tooltip', 'hidden.bs.tooltip',
() => { () => {
tooltipBtn?.setContent({ '.tooltip-inner': btnTitle }) tooltipBtn?.setContent({ '.tooltip-inner': clipboardTooltip })
}, },
{ once: true } { once: true }
) )
@ -145,8 +150,8 @@ if (filePath && fileMatch && codeToDisplay) {
) )
: ( : (
<div class="bd-clipboard"> <div class="bd-clipboard">
<button type="button" class="btn-clipboard"> <button type="button" class="btn-clipboard" title={clipboardLabel}>
<svg class="bi" role="img" aria-label="Copy"> <svg class="bi" aria-hidden="true">
<use xlink:href="#clipboard" /> <use xlink:href="#clipboard" />
</svg> </svg>
</button> </button>

View File

@ -36,6 +36,10 @@ interface Props {
* @default true * @default true
*/ */
showPreview?: boolean showPreview?: boolean
/**
* Defines label to complete 'Edit code on Stackblitz' and/or 'Copy code to clipboard' buttons aria-labels.
*/
buttonLabel?: string
} }
const { const {
@ -45,12 +49,16 @@ const {
id, id,
lang = 'html', lang = 'html',
showMarkup = true, showMarkup = true,
showPreview = true showPreview = true,
buttonLabel
} = Astro.props } = Astro.props
let markup = Array.isArray(code) ? code.join('\n') : code let markup = Array.isArray(code) ? code.join('\n') : code
markup = replacePlaceholdersInHtml(markup) markup = replacePlaceholdersInHtml(markup)
const stackblitzLabel = buttonLabel ? `Edit ${buttonLabel} code on StackBlitz` : 'Edit code on StackBlitz'
const clipboardLabel = buttonLabel ? `Copy ${buttonLabel} code to clipboard` : 'Copy code to clipboard'
const simplifiedMarkup = markup const simplifiedMarkup = markup
.replace( .replace(
/<svg.*class="bd-placeholder-img(?:-lg)?(?: *?bd-placeholder-img-lg)? ?(.*?)".*?<\/svg>/g, /<svg.*class="bd-placeholder-img(?:-lg)?(?: *?bd-placeholder-img-lg)? ?(.*?)".*?<\/svg>/g,
@ -81,14 +89,14 @@ const simplifiedMarkup = markup
<button <button
type="button" type="button"
class="btn-edit text-nowrap" class="btn-edit text-nowrap"
title="Try it on StackBlitz" title={stackblitzLabel}
data-sb-js-snippet={addStackblitzJs ? true : undefined} data-sb-js-snippet={addStackblitzJs ? true : undefined}
> >
<svg class="bi" aria-hidden="true"> <svg class="bi" aria-hidden="true">
<use xlink:href="#lightning-charge-fill" /> <use xlink:href="#lightning-charge-fill" />
</svg> </svg>
</button> </button>
<button type="button" class="btn-clipboard mt-0 me-0" title="Copy to clipboard"> <button type="button" class="btn-clipboard mt-0 me-0" title={clipboardLabel}>
<svg class="bi" aria-hidden="true"> <svg class="bi" aria-hidden="true">
<use xlink:href="#clipboard" /> <use xlink:href="#clipboard" />
</svg> </svg>
@ -96,7 +104,7 @@ const simplifiedMarkup = markup
</div> </div>
</div> </div>
)} )}
<Code code={simplifiedMarkup} lang={lang} nestedInExample={true} /> <Code code={simplifiedMarkup} lang={lang} nestedInExample={true} buttonLabel={buttonLabel} />
</> </>
) )
} }

View File

@ -15,9 +15,13 @@ interface Props {
* File path that contains the content to display relative to the root of the repository. * File path that contains the content to display relative to the root of the repository.
*/ */
file: string file: string
/**
* Defines label to complete 'Copy JS to clipboard' button aria-label.
*/
buttonLabel?: string
} }
const { name, file } = Astro.props const { name, file, buttonLabel } = Astro.props
if (!name || !file) { if (!name || !file) {
throw new Error( throw new Error(
@ -25,6 +29,8 @@ if (!name || !file) {
) )
} }
const clipboardLabel = buttonLabel ? `Copy ${buttonLabel} JS to clipboard` : `Copy ${name} JS to clipboard`
let content: string let content: string
try { try {
@ -52,7 +58,7 @@ try {
} }
--- ---
<Code containerClass="bd-example-snippet bd-code-snippet bd-file-ref" code={content} lang="js"> <Code containerClass="bd-example-snippet bd-code-snippet bd-file-ref" code={content} lang="js" buttonLabel={buttonLabel}>
<div slot="pre" class="d-flex align-items-center highlight-toolbar ps-3 pe-2 py-1 border-bottom"> <div slot="pre" class="d-flex align-items-center highlight-toolbar ps-3 pe-2 py-1 border-bottom">
<a <a
class="font-monospace link-secondary link-underline-secondary link-underline-opacity-0 link-underline-opacity-100-hover small" class="font-monospace link-secondary link-underline-secondary link-underline-opacity-0 link-underline-opacity-100-hover small"
@ -61,7 +67,7 @@ try {
{file} {file}
</a> </a>
<div class="d-flex ms-auto"> <div class="d-flex ms-auto">
<button type="button" class="btn-clipboard mt-0 me-0" title="Copy to clipboard"> <button type="button" class="btn-clipboard mt-0 me-0" title={clipboardLabel}>
<svg class="bi" aria-hidden="true"><use xlink:href="#clipboard"></use></svg> <svg class="bi" aria-hidden="true"><use xlink:href="#clipboard"></use></svg>
</button> </button>
</div> </div>

View File

@ -15,9 +15,13 @@ interface Props {
* File path that contains the content to display relative to the root of the repository. * File path that contains the content to display relative to the root of the repository.
*/ */
file: string file: string
/**
* Defines label to complete 'Copy SCSS to clipboard' button aria-label.
*/
buttonLabel?: string
} }
const { name, file } = Astro.props const { name, file, buttonLabel } = Astro.props
if (!name || !file) { if (!name || !file) {
throw new Error( throw new Error(
@ -25,6 +29,8 @@ if (!name || !file) {
) )
} }
const clipboardLabel = buttonLabel ? `Copy ${buttonLabel} SCSS to clipboard` : `Copy ${name} SCSS to clipboard`
let content: string let content: string
try { try {
@ -54,7 +60,7 @@ try {
} }
--- ---
<Code containerClass="bd-example-snippet bd-file-ref" code={content} lang="scss"> <Code containerClass="bd-example-snippet bd-file-ref" code={content} lang="scss" buttonLabel={buttonLabel}>
<div slot="pre" class="d-flex align-items-center highlight-toolbar ps-3 pe-2 py-1 border-bottom"> <div slot="pre" class="d-flex align-items-center highlight-toolbar ps-3 pe-2 py-1 border-bottom">
<a <a
class="font-monospace link-secondary link-underline-secondary link-underline-opacity-0 link-underline-opacity-100-hover small" class="font-monospace link-secondary link-underline-secondary link-underline-opacity-0 link-underline-opacity-100-hover small"
@ -63,7 +69,7 @@ try {
{file} {file}
</a> </a>
<div class="d-flex ms-auto"> <div class="d-flex ms-auto">
<button type="button" class="btn-clipboard mt-0 me-0" title="Copy to clipboard"> <button type="button" class="btn-clipboard mt-0 me-0" title={clipboardLabel}>
<svg class="bi" aria-hidden="true"><use xlink:href="#clipboard"></use></svg> <svg class="bi" aria-hidden="true"><use xlink:href="#clipboard"></use></svg>
</button> </button>
</div> </div>

View File

@ -36,7 +36,7 @@ robots: noindex,follow
<Example showMarkup={false} code={`The <abbr title="HyperText Markup Language">HTML</abbr> abbreviation element.`} /> <Example showMarkup={false} code={`The <abbr title="HyperText Markup Language">HTML</abbr> abbreviation element.`} />
<Example code={`<div class="test">This is a test.</div>`} /> <Example buttLabel="test" code={`<div class="test">This is a test.</div>`} />
<ScssDocs name="variable-gradient" file="scss/_variables.scss" /> <ScssDocs name="variable-gradient" file="scss/_variables.scss" />