Skip to content

Commit

Permalink
Fix: Allow isolated components with duplicate names (fixes styleguidi…
Browse files Browse the repository at this point in the history
…st#1454)

If you have more than one component with the same name, the isolated mode will incorrectly show all of the components of the same name (instead of just the one you clicked on).

This fix solves the issue by prepending the existing hash path from the page the user came from. By prepending this hash path, Styleguidist correctly scopes the isolated example to just the desired component.
  • Loading branch information
chrisdopuch authored and sapegin committed Oct 31, 2019
1 parent c171330 commit aaf0471
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 14 deletions.
8 changes: 8 additions & 0 deletions examples/sections/src/components/MyLabel/Label.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';

/**
* Simple text label.
*/
export default function Label() {
return <span>I am a duplicate Label component!</span>;
}
5 changes: 5 additions & 0 deletions examples/sections/src/components/MyLabel/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Should use the `fantasy` font inherited from `body`:

```jsx
<Label />
```
1 change: 1 addition & 0 deletions examples/sections/src/components/MyLabel/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Label';
6 changes: 6 additions & 0 deletions examples/sections/styleguide.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ module.exports = {
exampleMode: 'expand', // 'hide' | 'collapse' | 'expand'
usageMode: 'expand', // 'hide' | 'collapse' | 'expand'
},
{
name: 'Labels',
components: () => ['./src/components/MyLabel/Label.js'],
exampleMode: 'expand', // 'hide' | 'collapse' | 'expand'
usageMode: 'expand', // 'hide' | 'collapse' | 'expand'
},
{
name: 'Others',
components: () => ['./src/components/RandomButton/RandomButton.js'],
Expand Down
14 changes: 7 additions & 7 deletions src/client/utils/__tests__/getUrl.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,37 @@ describe('getUrl', () => {

it('should return an isolated URL', () => {
const result = getUrl({ name, slug, isolated: true }, loc);
expect(result).toBe('/styleguide/#!/FooBar');
expect(result).toBe('/styleguide/#!/Components/FooBar');
});

it('should return an absolute isolated URL', () => {
const result = getUrl({ name, slug, isolated: true, absolute: true }, loc);
expect(result).toBe('http://example.com/styleguide/#!/FooBar');
expect(result).toBe('http://example.com/styleguide/#!/Components/FooBar');
});

it('should return an isolated example URL', () => {
const result = getUrl({ name, slug, example: 3, isolated: true }, loc);
expect(result).toBe('/styleguide/#!/FooBar/3');
expect(result).toBe('/styleguide/#!/Components/FooBar/3');
});

it('should return an isolated example=0 URL', () => {
const result = getUrl({ name, slug, example: 0, isolated: true }, loc);
expect(result).toBe('/styleguide/#!/FooBar/0');
expect(result).toBe('/styleguide/#!/Components/FooBar/0');
});

it('should return an absolute isolated example URL', () => {
const result = getUrl({ name, slug, example: 3, isolated: true, absolute: true }, loc);
expect(result).toBe('http://example.com/styleguide/#!/FooBar/3');
expect(result).toBe('http://example.com/styleguide/#!/Components/FooBar/3');
});

it('should return a nochrome URL', () => {
const result = getUrl({ name, slug, nochrome: true }, loc);
expect(result).toBe('/styleguide/?nochrome#!/FooBar');
expect(result).toBe('/styleguide/?nochrome#!/Components/FooBar');
});

it('should return an absolute nochrome URL', () => {
const result = getUrl({ name, slug, nochrome: true, absolute: true }, loc);
expect(result).toBe('http://example.com/styleguide/?nochrome#!/FooBar');
expect(result).toBe('http://example.com/styleguide/?nochrome#!/Components/FooBar');
});

it('should return a route path', () => {
Expand Down
30 changes: 23 additions & 7 deletions src/client/utils/getUrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@
*/
export default function getUrl(
{ name, slug, example, anchor, isolated, nochrome, absolute, hashPath, id, takeHash } = {},
{ origin, pathname, hash } = window.location
{ origin, pathname, hash = '' } = window.location
) {
let url = pathname;

const currentHash = hash.indexOf('?') > -1 ? hash.substring(0, hash.indexOf('?')) : hash;

if (takeHash) {
if (hash.indexOf('?') > -1) {
url += hash.substring(0, hash.indexOf('?'));
} else {
url += hash;
}
url += currentHash;
}

if (nochrome) {
Expand All @@ -34,7 +32,7 @@ export default function getUrl(
if (anchor) {
url += `#${slug}`;
} else if (isolated || nochrome) {
url += `#!/${encodedName}`;
url += buildIsolatedOrNoChromeFragment({ currentHash, encodedName });
}

if (hashPath) {
Expand All @@ -59,3 +57,21 @@ export default function getUrl(

return url;
}

/**
* Gets the URL fragment for an isolated or nochrome link.
*
* @param {string} $.currentHash The current hash fragment of the page
* @param {string} $.encodedName The URL encoded name of the component
* @return {string}
*/
function buildIsolatedOrNoChromeFragment({ currentHash, encodedName }) {
const stripFragment = /^#\/?/;
const stripTrailingSlash = /\/$/;
const currentHashPath =
// skip if we are already using `#!/`
currentHash && !currentHash.includes('#!/')
? currentHash.replace(stripFragment, '').replace(stripTrailingSlash, '') + '/'
: '';
return `#!/${currentHashPath}${encodedName}`;
}

0 comments on commit aaf0471

Please sign in to comment.