⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Draft
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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions src/library/GithubPermalink/GithubPermalink.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,33 @@ export const SingleLine: Story = {
<GithubPermalink permalink="https://github.com/dwjohnston/blacksheepcode/blob/72ee472bfa896df255ae42ef017ad0cca96b2333/app/components/PostComments/PostComments.tsx#L28" />
),
};

export const InitiallyCollapsed: Story = {
render: () => (
<div>
<p>This permalink starts collapsed (minimal variant):</p>
<GithubPermalink
permalink="https://github.com/dwjohnston/react-github-permalink/blob/5b15aa07e60af4e317086f391b28cadf9aae8e1b/sample_files/sample1.go#L1-L5"
isInitiallyExpanded={false}
/>
<p>This permalink starts expanded (default):</p>
<GithubPermalink
permalink="https://github.com/dwjohnston/react-github-permalink/blob/5b15aa07e60af4e317086f391b28cadf9aae8e1b/sample_files/sample1.go#L1-L5"
isInitiallyExpanded={true}
/>
</div>
),
};

export const GlobalConfigCollapsed: Story = {
render: () => (
<div>
<p>Using global configuration to set default to collapsed:</p>
<GithubPermalinkProvider initiallyExpandGithubPermalinks={false}>
<GithubPermalink permalink="https://github.com/dwjohnston/react-github-permalink/blob/5b15aa07e60af4e317086f391b28cadf9aae8e1b/sample_files/sample1.go#L1-L5" />
<p style={{ marginTop: '1em' }}>Second permalink also collapsed by default:</p>
<GithubPermalink permalink="https://github.com/dwjohnston/react-github-permalink/blob/bc75e8fe2d1c0395c9443afe1837f453c05a7698/sample_files/sample1.js#L3-L17" />
</GithubPermalinkProvider>
</div>
),
};
7 changes: 5 additions & 2 deletions src/library/GithubPermalink/GithubPermalink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function GithubPermalink(props: GithubPermalinkProps) {

const { permalink } = props;
const [data, setData] = useState(null as null | GithubPermalinkDataResponse)
const { getDataFn, githubToken, onError } = useContext(GithubPermalinkContext);
const { getDataFn, githubToken, onError, initiallyExpandGithubPermalinks } = useContext(GithubPermalinkContext);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
Expand All @@ -27,7 +27,10 @@ export function GithubPermalink(props: GithubPermalinkProps) {
}


return <GithubPermalinkBase data={data} {...props} />
return <GithubPermalinkBase
data={data}
isInitiallyExpanded={props.isInitiallyExpanded ?? initiallyExpandGithubPermalinks}
{...props} />
}


34 changes: 24 additions & 10 deletions src/library/GithubPermalink/GithubPermalinkBase.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { GithubPermalinkDataResponse, } from "../config/GithubPermalinkContext";
import { ErrorMessages } from "../ErrorMessages/ErrorMessages";
import { GithubSvg } from "../GithubSvg/GithubSvg";
import { PropsWithChildren } from "react";
import { PropsWithChildren, useState } from "react";
import { SyntaxHighlight } from "../SyntaxHighlight/SyntaxHighlight";
import { formatForLineExclusions } from "./formatLineExclusions";
import { CopyButton } from "../common/CopyButton/CopyButton";
import { getLanguageFromPath } from "../utils/getLanguageFromPath";
import { AvailableLanguagesPrism } from "../SyntaxHighlight/availableLanguagesPrism";
import { ChevronDownSvg, ChevronRightSvg } from "../images/ChevronSvg";

export type GithubPermalinkBaseProps = {
className?: string;
Expand All @@ -15,6 +16,12 @@ export type GithubPermalinkBaseProps = {
excludeText?: string;
data: GithubPermalinkDataResponse;
language?: AvailableLanguagesPrism;
/**
* Whether the permalink should be initially expanded to show the full header.
* When false, only the code block is shown with a subtle GitHub icon link.
* Default is controlled by the global configuration `initiallyExpandGithubPermalinks`.
*/
isInitiallyExpanded?: boolean;
}


Expand Down Expand Up @@ -67,20 +74,27 @@ function GithubPermalinkInner(props: PropsWithChildren<{
clipboard?: string;
} & GithubPermalinkBaseProps>) {

const { clipboard } = props;
const { clipboard, isInitiallyExpanded = true } = props;
const [isExpanded, setIsExpanded] = useState(isInitiallyExpanded);


return <div className={`rgp-base react-github-permalink ${props.className ?? ''}`}>
return <div className={`rgp-base react-github-permalink ${props.className ?? ''} ${isExpanded ? 'expanded' : 'collapsed'}`}>
<div className="header">
<div>

<GithubSvg />
<button
className="expand-button"
onClick={() => setIsExpanded(!isExpanded)}
aria-label={isExpanded ? "Collapse details" : "Expand details"}
title={isExpanded ? "Collapse details" : "Expand details"}
>
{isExpanded ? <ChevronDownSvg /> : <ChevronRightSvg />}
</button>
<div className={isExpanded ? "" : "github-icon-link"}>
{isExpanded ? <GithubSvg /> : <a href={props.permalink} aria-label="View on GitHub" title="View on GitHub"><GithubSvg /></a>}
</div>
<div className="link-wrapper">
{isExpanded && <div className="link-wrapper">
{props.header ?? <a href={props.permalink} className="file-link">{props.permalink}</a>}
</div>
</div>}

{clipboard && <div className="copy-button-container">
{clipboard && isExpanded && <div className="copy-button-container">
<CopyButton clipboard={clipboard} />
</div>}
</div>
Expand Down
6 changes: 5 additions & 1 deletion src/library/GithubPermalink/GithubPermalinkRsc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ export async function GithubPermalinkRsc(props: GithubPermalinkRscProps) {
const dataFn = githubPermalinkRscConfig.getPermalinkFn();
const token = githubPermalinkRscConfig.getGithubToken();
const onError = githubPermalinkRscConfig.getOnError();
const initiallyExpandGithubPermalinks = githubPermalinkRscConfig.getInitiallyExpandGithubPermalinks();

const data = await dataFn(permalink, token, onError);
return <GithubPermalinkBase data={data} {...props}/>
return <GithubPermalinkBase
data={data}
isInitiallyExpanded={props.isInitiallyExpanded ?? initiallyExpandGithubPermalinks}
{...props}/>
}
43 changes: 43 additions & 0 deletions src/library/GithubPermalink/github-permalink.css
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,49 @@ svg.github-logo {
align-items: center;
}

.react-github-permalink .expand-button {
all: unset;
cursor: pointer;
display: flex;
align-items: center;
padding: 0;
margin: 0;
border: none;
background: none;
color: var(--rgp-color-text-frame);
transition: color 0.2s ease;
}

.react-github-permalink .expand-button:hover {
color: var(--rgp-color-file-link);
}

.react-github-permalink .expand-button svg {
fill: currentColor;
}

.react-github-permalink.collapsed .header {
background-color: transparent;
border: none;
padding: 0;
}

.react-github-permalink.collapsed {
border: none;
margin: 0;
}

.react-github-permalink .github-icon-link a {
display: flex;
align-items: center;
opacity: 0.6;
transition: opacity 0.2s ease;
}

.react-github-permalink .github-icon-link a:hover {
opacity: 1;
}

.copy-button-container {

.tooltip-container {
Expand Down
7 changes: 7 additions & 0 deletions src/library/config/BaseConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ export type BaseConfiguration = {
* @returns
*/
onError?: (e: unknown) => void;

/**
* Default value for whether GitHub permalinks should be initially expanded.
* When false, permalinks will be collapsed by default showing only the code block.
* Default: true
*/
initiallyExpandGithubPermalinks?: boolean;
};


2 changes: 2 additions & 0 deletions src/library/config/GithubPermalinkContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export type GithubIssueLinkDataResponse = {
export const GithubPermalinkContext = createContext<BaseConfiguration>({
getDataFn: defaultGetPermalinkFn,
getIssueFn: defaultGetIssueFn,
initiallyExpandGithubPermalinks: true,
});

export function GithubPermalinkProvider(props: PropsWithChildren<Partial<BaseConfiguration>>) {
Expand All @@ -71,6 +72,7 @@ export function GithubPermalinkProvider(props: PropsWithChildren<Partial<BaseCon
getIssueFn: props.getIssueFn ?? defaultGetIssueFn,
githubToken: props.githubToken,
onError: props.onError,
initiallyExpandGithubPermalinks: props.initiallyExpandGithubPermalinks ?? true,
}}>
{props.children}
</GithubPermalinkContext.Provider>
Expand Down
4 changes: 4 additions & 0 deletions src/library/config/GithubPermalinkRscConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class GithubPermalinkRscConfig {
public getOnError() {
return this.baseConfiguration.onError;
}

public getInitiallyExpandGithubPermalinks() {
return this.baseConfiguration.initiallyExpandGithubPermalinks ?? true;
}
}

export const githubPermalinkRscConfig = new GithubPermalinkRscConfig();
19 changes: 19 additions & 0 deletions src/library/images/ChevronSvg.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export function ChevronDownSvg(props: {
size?: number
}) {
const size = props.size ?? 16;

return <svg className="chevron-icon" height={`${size}`} width={`${size}`} aria-hidden="true" viewBox="0 0 16 16" version="1.1">
<path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path>
</svg>
}

export function ChevronRightSvg(props: {
size?: number
}) {
const size = props.size ?? 16;

return <svg className="chevron-icon" height={`${size}`} width={`${size}`} aria-hidden="true" viewBox="0 0 16 16" version="1.1">
<path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path>
</svg>
}