Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text inside of DocPage stories can be selected but can not be copied. #18611

Closed
andyford opened this issue Jun 30, 2022 · 9 comments
Closed

Text inside of DocPage stories can be selected but can not be copied. #18611

andyford opened this issue Jun 30, 2022 · 9 comments

Comments

@andyford
Copy link

andyford commented Jun 30, 2022

Describe the bug
Text inside of DocPage stories can be selected but can not be copied.

To Reproduce
Can be seen here:

I asked on Discord if this was a known issue and @kylegach discovered the issue exists on the above 3 instances.

I first noticed this in a private storybook instance running on @storybook/react v6.5.4 but it appears the the above 3 instances as well.

Additional context
Tested on Mac in Chrome, Firefox, and Safari.
Text cannot be copied through conventional means (cmd+c or right click and select "Copy" from context menu) but I noticed it's still possible to use navigator.clipboard.writeText()

EDIT (2022-08-09)
Just to clarify. Rendered text/code inside of code preview blocks appears to be manually selectable and copy-able (in addition to the Copy button still functioning fine. This bug report is about the text content within the rendered stories themselves. This also appears to only affect the Docs tab and not the Canvas tab.

Here's a video:
https://user-images.githubusercontent.com/49811/183597174-c04353ba-54a0-4ea2-b617-1c45e7533484.mp4

@petdud
Copy link

petdud commented Jul 25, 2022

+1, facing the same issue here: https://react.fluentui.dev/?path=/docs/theme-color--page
The storybook contains an indication that the item is copied, so I assume the problem might be somewhere there?

Screenshot 2022-07-25 at 2 23 12 PM

@pocka
Copy link
Contributor

pocka commented Aug 8, 2022

It seems this behavior is intentional... see #15559.

I feel that "feature" is both unintuitive and surprising. In my opinion, it's should be an opt-in feature or be assigned to a safe and unused shortcut key.

@jphawk
Copy link

jphawk commented Aug 8, 2022

Agree with @pocka. I'm taking care of a design system done in storybook and I'm getting plenty of complaints from developers who can't copy e.g. color codes or spacing values from DocPages 😬 It would be great to make this optional, as it just doesn't suit some use cases

@andyford
Copy link
Author

andyford commented Aug 9, 2022

I'm taking care of a design system done in storybook and I'm getting plenty of complaints from developers who can't copy e.g. color codes or spacing values from DocPages

That's exactly how I discovered this issue! In this case we implemented our own copy-to-clipboard functionality, but we shouldn't have to do this.

@andyford
Copy link
Author

andyford commented Aug 9, 2022

It seems this behavior is intentional... see #15559.

I'm not 100% sure... You can still manually select and copy rendered text inside of the code blocks. But you can't copy text in the rendered stories. Maybe it is somehow related... but maybe not? 🤷

EDIT:
After making a video (which I've added to the original post) and watching it back, I noticed that when I copy text from the rendered story (around 0:13 to 0:17), the UI temporarily says Copied in the bottom right corner. So this is could indicate that this bug is somehow tied to the source code copying functionality as @pocka suggested.

pocka added a commit that referenced this issue Nov 9, 2022
#18611

This patch introduces skip conditional for the "copy code snippet
by shortcut key" feature.

this condition would not work when the preview is iframe (user sets
`docs: { inlineStories: false }`), but that does not matter as the
event handler won't run in the first place.
@pocka pocka added the ui label Nov 10, 2022
@shilman
Copy link
Member

shilman commented Jan 14, 2023

Yo-ho-ho!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-beta.27 containing PR #19788 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb@next upgrade --prerelease

Closing this issue. Please re-open if you think there's still more to do.

@James-Wilkinson-git
Copy link

Can we get a fix for this in non storybook 7? for those who can't upgrade?

@riotrah
Copy link

riotrah commented Sep 4, 2024

Just want to echo the prior poster's request.

Upgrading for us is not tenable in the near future, largely due to lack of developer resources available to migrate our bespoke clojurescript -> js -> storybook build setup.

It would be lovely to have this fixed in v6. Any guidance as to how to maybe monkeypatch this ourselves would also be appreciated if anyone has any!

@pocka
Copy link
Contributor

pocka commented Sep 5, 2024

I'm willing to send a patch to v6 release but that release channel seems to be unmaintained?
I see release-6-5 branch got some updates, however there are no v6 releases since v6.5.16 (2 years ago).

So here is a workaround: a patch for v6.5.16 generated using patch-package. Copyright and license are same to the ones of Storybook repo code (for ease and simplicity).

  • Save the snippet as patches/@storybook+components+6.5.16.patch.
  • Works only with @storybook/[email protected].
  • I don't guarantee anything: use at your own risk.
  • It patches ESM file. If your setup is importing the CJS one somehow, this patch won't have any effect.
  • In order to support ES5 UAs, replace the first const to var.
  • Since this is a patch, this might conflict with other patches for @storybook/components.
# Unofficial patch for https://github.com/storybookjs/storybook/issues/18611
# SPDX-FileCopyrightText: Copyright (c) 2024 Storybook
# SPDX-License-Identifier: MIT
diff --git a/node_modules/@storybook/components/dist/esm/index-681e4b07.js b/node_modules/@storybook/components/dist/esm/index-681e4b07.js
index 1fe1e2d..68f43f2 100644
--- a/node_modules/@storybook/components/dist/esm/index-681e4b07.js
+++ b/node_modules/@storybook/components/dist/esm/index-681e4b07.js
@@ -351,7 +351,12 @@ if(CONFIG_TYPE!=='DEVELOPMENT'||!EventSource)return undefined;var eventSource=ne
  * items. The preview also shows the source for the component
  * as a drop-down.
  */var Preview=function Preview(_a){var isLoading=_a.isLoading,isColumn=_a.isColumn,columns=_a.columns,children=_a.children,withSource=_a.withSource,_a$withToolbar=_a.withToolbar,withToolbar=_a$withToolbar===void 0?false:_a$withToolbar,_a$isExpanded=_a.isExpanded,isExpanded=_a$isExpanded===void 0?false:_a$isExpanded,additionalActions=_a.additionalActions,className=_a.className,props=__rest(_a,["isLoading","isColumn","columns","children","withSource","withToolbar","isExpanded","additionalActions","className"]);var _useState7=useState(isExpanded),_useState8=_slicedToArray(_useState7,2),expanded=_useState8[0],setExpanded=_useState8[1];var _getSource=getSource(withSource,expanded,setExpanded),source=_getSource.source,actionItem=_getSource.actionItem;var _useState9=useState(1),_useState10=_slicedToArray(_useState9,2),scale=_useState10[0],setScale=_useState10[1];var previewClasses=[className].concat(['sbdocs','sbdocs-preview']);var defaultActionItems=withSource?[actionItem]:[];var _useState11=useState(additionalActions?_toConsumableArray(additionalActions):[]),_useState12=_slicedToArray(_useState11,2),additionalActionItems=_useState12[0],setAdditionalActionItems=_useState12[1];var actionItems=[].concat(defaultActionItems,_toConsumableArray(additionalActionItems));// @ts-ignore
-var layout=getLayout(Children.count(children)===1?[children]:children);var globalWindow=window_1.window;var copyToClipboard=useCallback(function(text){return __awaiter(void 0,void 0,void 0,/*#__PURE__*/regeneratorRuntime.mark(function _callee2(){var _yield$import,createCopyToClipboardFunction;return regeneratorRuntime.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:_context2.next=2;return import('./syntaxhighlighter-b07b042a.js');case 2:_yield$import=_context2.sent;createCopyToClipboardFunction=_yield$import.createCopyToClipboardFunction;createCopyToClipboardFunction();case 5:case"end":return _context2.stop();}}},_callee2);}));},[]);var onCopyCapture=function onCopyCapture(e){e.preventDefault();if(additionalActionItems.filter(function(item){return item.title==='Copied';}).length===0){copyToClipboard(source.props.code).then(function(){setAdditionalActionItems([].concat(_toConsumableArray(additionalActionItems),[{title:'Copied',onClick:function onClick(){}}]));globalWindow.setTimeout(function(){return setAdditionalActionItems(additionalActionItems.filter(function(item){return item.title!=='Copied';}));},1500);});}};return React__default.createElement(PreviewContainer,Object.assign({},{withSource:withSource,withToolbar:withToolbar},props,{className:previewClasses.join(' ')}),withToolbar&&React__default.createElement(PositionedToolbar,{isLoading:isLoading,border:true,zoom:function zoom(z){return setScale(scale*z);},resetZoom:function resetZoom(){return setScale(1);},storyId:getStoryId(children),baseUrl:"./iframe.html"}),React__default.createElement(ZoomContext.Provider,{value:{scale:scale}},React__default.createElement(Relative,{className:"docs-story",onCopyCapture:withSource&&onCopyCapture},React__default.createElement(ChildrenContainer,{isColumn:isColumn||!Array.isArray(children),columns:columns,layout:layout},React__default.createElement(Zoom$1.Element,{scale:scale},Array.isArray(children)?// eslint-disable-next-line react/no-array-index-key
+var layout=getLayout(Children.count(children)===1?[children]:children);var globalWindow=window_1.window;var copyToClipboard=useCallback(function(text){return __awaiter(void 0,void 0,void 0,/*#__PURE__*/regeneratorRuntime.mark(function _callee2(){var _yield$import,createCopyToClipboardFunction;return regeneratorRuntime.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:_context2.next=2;return import('./syntaxhighlighter-b07b042a.js');case 2:_yield$import=_context2.sent;createCopyToClipboardFunction=_yield$import.createCopyToClipboardFunction;createCopyToClipboardFunction();case 5:case"end":return _context2.stop();}}},_callee2);}));},[]);var onCopyCapture=function onCopyCapture(e){
+  const selection = globalWindow.getSelection();
+  if (selection && selection.type === 'Range') {
+    return;
+  }
+  e.preventDefault();if(additionalActionItems.filter(function(item){return item.title==='Copied';}).length===0){copyToClipboard(source.props.code).then(function(){setAdditionalActionItems([].concat(_toConsumableArray(additionalActionItems),[{title:'Copied',onClick:function onClick(){}}]));globalWindow.setTimeout(function(){return setAdditionalActionItems(additionalActionItems.filter(function(item){return item.title!=='Copied';}));},1500);});}};return React__default.createElement(PreviewContainer,Object.assign({},{withSource:withSource,withToolbar:withToolbar},props,{className:previewClasses.join(' ')}),withToolbar&&React__default.createElement(PositionedToolbar,{isLoading:isLoading,border:true,zoom:function zoom(z){return setScale(scale*z);},resetZoom:function resetZoom(){return setScale(1);},storyId:getStoryId(children),baseUrl:"./iframe.html"}),React__default.createElement(ZoomContext.Provider,{value:{scale:scale}},React__default.createElement(Relative,{className:"docs-story",onCopyCapture:withSource&&onCopyCapture},React__default.createElement(ChildrenContainer,{isColumn:isColumn||!Array.isArray(children),columns:columns,layout:layout},React__default.createElement(Zoom$1.Element,{scale:scale},Array.isArray(children)?// eslint-disable-next-line react/no-array-index-key
 children.map(function(child,i){return React__default.createElement("div",{key:i},child);}):React__default.createElement("div",null,children))),React__default.createElement(ActionBar,{actionItems:actionItems}))),withSource&&expanded&&source);};var StyledPreview=styled(Preview)(function(){return{'.docs-story':{paddingTop:32,paddingBottom:40}};});var PreviewSkeleton=function PreviewSkeleton(){return React__default.createElement(StyledPreview,{isLoading:true,withToolbar:true},React__default.createElement(StorySkeleton,null));};/**
  * A specialized version of `_.map` for arrays without support for iteratee
  * shorthands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants