Skip to content

Commit 26fb47b

Browse files
committed
added copy code button functionality in code blocks
1 parent 6fe2314 commit 26fb47b

File tree

13 files changed

+20807
-14407
lines changed

13 files changed

+20807
-14407
lines changed

.yarn/install-state.gz

1.9 MB
Binary file not shown.

.yarnrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodeLinker: node-modules

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,6 @@
169169
"ini": "1.3.7",
170170
"eval": "^0.1.5",
171171
"markdownlint-cli/markdownlint": "^0.37.4"
172-
}
172+
},
173+
"packageManager": "[email protected]+sha512.4e54aeace9141df2f0177c266b05ec50dc044638157dae128c471ba65994ac802122d7ab35bcd9e81641228b7dcf24867d28e750e0bcae8a05277d600008ad54"
173174
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useState } from 'react';
2+
import PropTypes from 'prop-types';
3+
import './CopyCodeButton.scss';
4+
5+
export default function CopyCodeButton({ text }) {
6+
const [copied, setCopied] = useState(false);
7+
8+
const handleCopy = async () => {
9+
try {
10+
await navigator.clipboard.writeText(text);
11+
setCopied(true);
12+
setTimeout(() => setCopied(false), 2000);
13+
} catch (err) {
14+
console.error('Failed to copy code:', err);
15+
}
16+
};
17+
18+
return (
19+
<button
20+
className="copy-code-button"
21+
onClick={handleCopy}
22+
title="Copy code to clipboard"
23+
aria-label="Copy code to clipboard"
24+
>
25+
{copied ? '✓ Copied!' : 'Copy'}
26+
</button>
27+
);
28+
}
29+
30+
CopyCodeButton.propTypes = {
31+
text: PropTypes.string.isRequired,
32+
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
.copy-code-button {
2+
position: absolute;
3+
top: 8px;
4+
right: 8px;
5+
padding: 6px 12px;
6+
font-size: 12px;
7+
font-weight: 500;
8+
color: #666;
9+
background-color: #f5f5f5;
10+
border: 1px solid #d0d0d0;
11+
border-radius: 4px;
12+
cursor: pointer;
13+
transition: all 0.2s ease;
14+
z-index: 10;
15+
font-family: inherit;
16+
white-space: nowrap;
17+
18+
&:hover {
19+
background-color: #e8e8e8;
20+
border-color: #999;
21+
color: #333;
22+
}
23+
24+
&:active {
25+
transform: scale(0.95);
26+
}
27+
28+
&:focus {
29+
outline: 2px solid #0066cc;
30+
outline-offset: 2px;
31+
}
32+
33+
/* Dark mode support */
34+
@media (prefers-color-scheme: dark) {
35+
color: #999;
36+
background-color: #2a2a2a;
37+
border-color: #444;
38+
39+
&:hover {
40+
background-color: #3a3a3a;
41+
border-color: #666;
42+
color: #ccc;
43+
}
44+
}
45+
}

src/components/Page/Page.jsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Import External Dependencies
22
import { useEffect, useState } from 'react';
3+
import ReactDOM from 'react-dom';
34
import PropTypes from 'prop-types';
45
import { useLocation } from 'react-router-dom';
56

@@ -9,6 +10,7 @@ import Markdown from '../Markdown/Markdown';
910
import Contributors from '../Contributors/Contributors';
1011
import { PlaceholderString } from '../Placeholder/Placeholder';
1112
import AdjacentPages from './AdjacentPages';
13+
import CopyCodeButton from '../CopyCodeButton/CopyCodeButton';
1214

1315
// Load Styling
1416
import './Page.scss';
@@ -81,6 +83,48 @@ export default function Page(props) {
8183
};
8284
}, [contentLoaded, pathname, hash]);
8385

86+
// Enhance code blocks with copy buttons for /concepts routes
87+
useEffect(() => {
88+
if (contentLoaded && pathname.startsWith('/concepts')) {
89+
const enhanceCodeBlocks = () => {
90+
const allPreBlocks = document.querySelectorAll('pre');
91+
92+
allPreBlocks.forEach((pre) => {
93+
if (pre.dataset.copyButtonAdded) {
94+
return;
95+
}
96+
97+
pre.style.position = 'relative';
98+
99+
const codeText = pre.textContent || pre.innerText;
100+
101+
const buttonWrapper = document.createElement('div');
102+
buttonWrapper.className = 'copy-button-wrapper';
103+
buttonWrapper.style.position = 'absolute';
104+
buttonWrapper.style.top = '8px';
105+
buttonWrapper.style.right = '8px';
106+
buttonWrapper.style.zIndex = '10';
107+
buttonWrapper.style.pointerEvents = 'auto';
108+
109+
ReactDOM.render(<CopyCodeButton text={codeText} />, buttonWrapper);
110+
111+
pre.appendChild(buttonWrapper);
112+
pre.dataset.copyButtonAdded = 'true';
113+
});
114+
};
115+
116+
// Run immediately and after delays to catch dynamically rendered content
117+
enhanceCodeBlocks();
118+
const timer1 = setTimeout(() => enhanceCodeBlocks(), 300);
119+
const timer2 = setTimeout(() => enhanceCodeBlocks(), 1000);
120+
121+
return () => {
122+
clearTimeout(timer1);
123+
clearTimeout(timer2);
124+
};
125+
}
126+
}, [contentLoaded, pathname]);
127+
84128
const numberOfContributors = contributors.length;
85129
const loadRelated = contentLoaded && related && related.length !== 0;
86130
const loadContributors =
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
title: Governance Overview
3+
group: Contribute
4+
sort: 0
5+
source: https://github.com/webpack/governance/blob/main/README.md
6+
edit: https://github.com/webpack/governance/edit/main/README.md
7+
---
8+
# webpack Project Governance
9+
10+
webpack is an open source project that depends on contributions from the community. Anyone may contribute to the project at any time by submitting code, participating in discussions, making suggestions, or any other contribution they see fit. This document describes how various types of contributors work within the webpack project.
11+
12+
* [Roles and Responsibilities](#roles-and-responsibilities)
13+
* [Contributors](#contributors)
14+
* [Committers](#committers)
15+
* [Reviewers](#reviewers)
16+
* [Technical steering committee](#technical-steering-committee)
17+
* [TSC meetings](#tsc-meetings)
18+
* [Consensus seeking process](#consensus-seeking-process)
19+
20+
## Roles and Responsibilities
21+
22+
### Contributors
23+
24+
Contributors are community members who contribute in concrete ways to the project, most often in the form of code and/or documentation. Anyone can become a Contributor, and contributions can take many forms. There is no expectation of commitment to the project, no specific skill requirements, and no selection process.
25+
26+
Contributors have read-only access to source code and so submit changes via pull requests. Contributor pull requests have their contribution reviewed and merged by a TSC member. TSC members and Committers work with Contributors to review their code and prepare it for merging.
27+
28+
As Contributors gain experience and familiarity with the project, their profile within, and commitment to, the community will increase. At some stage, they may find themselves being nominated as either a Website Team Member or Committer by an existing Website Team Member or Committer.
29+
30+
### Committers
31+
32+
Committers are community members who have shown that they are committed to the continued development of the project through ongoing engagement with the community. Committers are given push access to the project's GitHub repos and must abide by the project's [Contribution Guidelines](https://github.com/webpack/webpack/blob/main/CONTRIBUTING.md)
33+
34+
To become a Committer:
35+
36+
* One must have shown a willingness and ability to participate in the project as a team player. Typically, a potential Committer will need to show that they have an understanding of and alignment with the project, its objectives, and its strategy.
37+
* Committers are expected to be respectful of every community member and to work collaboratively in the spirit of inclusion.
38+
39+
New Committers can be nominated by any existing Committer. Once they have been nominated, there will be a vote by the TSC members.
40+
41+
It is important to recognize that committership is a privilege, not a right. That privilege must be earned and once earned it can be removed by the TSC members by a standard TSC motion. However, under normal circumstances committership exists for as long as the Committer wishes to continue engaging with the project.
42+
43+
A Committer who shows an above-average level of contribution to the project, particularly with respect to its strategic direction and long-term health, may be nominated to become a reviewer, described below.
44+
45+
### Reviewers
46+
47+
Reviewers are community members who have contributed a significant amount of time to the project through triaging of issues, fixing bugs, implementing enhancements/features, and are trusted community leaders.
48+
49+
Reviewers may perform all of the duties of Committers, and also:
50+
51+
* May merge external pull requests for accepted issues upon reviewing and approving the changes.
52+
* May merge their own pull requests once they have collected the feedback they deem necessary. (No pull request should be merged without at least one Committer/Reviewer/TSC member comment stating they've looked at the code.)
53+
54+
To become a Reviewer:
55+
56+
* Work in a helpful and collaborative way with the community.
57+
* Have given good feedback on others' submissions and displayed an overall understanding of the code quality standards for the project.
58+
* Commit to being a part of the community for the long-term.
59+
60+
A Committer is invited to become a Reviewer by existing Reviewers and TSC members. A nomination will result in discussion and then a decision by the TSC.
61+
62+
## Technical Steering Committee
63+
64+
A subset of the collaborators forms the Technical Steering Committee (TSC).
65+
The TSC has final authority over this project, including:
66+
67+
* Technical direction
68+
* Project governance and process (including this policy)
69+
* Contribution policy
70+
* GitHub repository hosting
71+
* Conduct guidelines
72+
* Maintaining the list of collaborators
73+
74+
The current list of TSC members is in
75+
[the project README](https://github.com/webpack/webpack/blob/main/README.md#current-project-members).
76+
77+
The [TSC Charter][] governs the operations of the TSC. All changes to the
78+
Charter need approval by the OpenJS Foundation Cross-Project Council (CPC).
79+
80+
### TSC meetings
81+
82+
The TSC meets in a Discord conference call or Discord thread. Each year,
83+
the TSC elects a chair to run the meetings.
84+
85+
Any community member can create a GitHub issue asking that the TSC review
86+
something.
87+
88+
The TSC may invite people to take part in a non-voting capacity.
89+
90+
During the meeting, the TSC chair ensures that someone takes minutes. After the
91+
meeting, the TSC chair ensures that someone opens a pull request with the
92+
minutes.
93+
94+
The TSC seeks to resolve as many issues as possible outside meetings using
95+
[the webpack's governance repository issue tracker](https://github.com/webpack/governance/issues).
96+
97+
The process in the issue tracker is:
98+
99+
* A TSC member opens an issue explaining the proposal/issue and @-mentions
100+
@webpack/tsc.
101+
* The proposal passes if, after 72 hours, there are two or more TSC voting
102+
member approvals and no TSC voting member opposition.
103+
* If there is an extended impasse, a TSC member may make a motion for a vote.
104+
105+
## Consensus Seeking Process
106+
107+
The TSC follows a
108+
[Consensus Seeking](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making)
109+
decision making model.
110+
111+
When an agenda item has appeared to reach a consensus, the moderator
112+
will ask "Does anyone object?" as a final call for dissent from the
113+
consensus.
114+
115+
If an agenda item cannot reach a consensus, a TSC member can call for
116+
either a closing vote or a vote to table the issue to the next
117+
meeting. The call for a vote must be approved by a majority of the TSC
118+
or else the discussion will continue. Simple majority wins.
119+
120+
----
121+
122+
_This document is an adaption of the [Node.js project Governance Model](https://github.com/nodejs/node/blob/main/GOVERNANCE.md) and the [ESlint project Governance Model](https://github.com/eslint/eslint/blob/main/docs/src/contribute/governance.md)_
123+
124+
[TSC Charter]: https://github.com/nodejs/TSC/blob/HEAD/TSC-Charter.md

0 commit comments

Comments
 (0)