scoobie 14.3.7 → 14.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/package.json +1 -1
- package/src/components/InternalLink.tsx +8 -1
- package/src/components/ScoobieLinkProvider.tsx +29 -0
- package/src/index.ts +1 -0
- package/src/private/url.ts +8 -15
package/README.md
CHANGED
|
@@ -345,11 +345,12 @@ export const MyFirstInlineCode = () => (
|
|
|
345
345
|
|
|
346
346
|
Render an internal link with the same opinions as our [MdxProvider](#mdxprovider):
|
|
347
347
|
|
|
348
|
-
- Internal links pass through the `v`
|
|
348
|
+
- Internal links pass through the `v` or [ScoobieLinkProvider] URL parameters for UI version switching
|
|
349
349
|
|
|
350
350
|
Unlike [SmartTextLink](#smarttextlink), this is not bound to a parent [Text] as it has no underlying [TextLink].
|
|
351
351
|
It can be used to make complex components navigable rather than just sections of text.
|
|
352
352
|
|
|
353
|
+
[scoobielinkprovider]: #scoobielinkprovider
|
|
353
354
|
[text]: https://seek-oss.github.io/braid-design-system/components/Text/
|
|
354
355
|
[textlink]: https://seek-oss.github.io/braid-design-system/components/TextLink/
|
|
355
356
|
|
|
@@ -398,7 +399,7 @@ export const Component = () => (
|
|
|
398
399
|
|
|
399
400
|
Render all underlying links as follows:
|
|
400
401
|
|
|
401
|
-
- Internal links pass through the `v`
|
|
402
|
+
- Internal links pass through the `v` or [ScoobieLinkProvider] URL parameters for UI version switching
|
|
402
403
|
- External links open in a new tab
|
|
403
404
|
- Links with a [`download` attribute] prompt the user with a file download
|
|
404
405
|
|
|
@@ -421,6 +422,25 @@ export const Component = () => (
|
|
|
421
422
|
|
|
422
423
|
[braidprovider]: https://seek-oss.github.io/braid-design-system/components/BraidProvider
|
|
423
424
|
|
|
425
|
+
### ScoobieLinkProvider
|
|
426
|
+
|
|
427
|
+
Propagate a custom set of URL parameters on internal links.
|
|
428
|
+
|
|
429
|
+
```tsx
|
|
430
|
+
import { BraidProvider, TextLink } from 'braid-design-system';
|
|
431
|
+
import apacTheme from 'braid-design-system/themes/apac';
|
|
432
|
+
import React from 'react';
|
|
433
|
+
import { ScoobieLink } from 'scoobie';
|
|
434
|
+
|
|
435
|
+
export const Component = () => (
|
|
436
|
+
<ScoobieLinkProvider propagateSearchParams={['debug', 'v']}>
|
|
437
|
+
<BraidProvider linkComponent={ScoobieLink} theme={apacTheme}>
|
|
438
|
+
<TextLink href="/root-relative">Internal link</TextLink>
|
|
439
|
+
</BraidProvider>
|
|
440
|
+
</ScoobieLinkProvider>
|
|
441
|
+
);
|
|
442
|
+
```
|
|
443
|
+
|
|
424
444
|
### SmartTextLink
|
|
425
445
|
|
|
426
446
|
Render a text link with the same opinions as our [MdxProvider](#mdxprovider):
|
package/package.json
CHANGED
|
@@ -4,6 +4,8 @@ import { NavLink, useLocation } from 'react-router-dom';
|
|
|
4
4
|
|
|
5
5
|
import { parseInternalHref } from '../private/url';
|
|
6
6
|
|
|
7
|
+
import { useScoobieLink } from './ScoobieLinkProvider';
|
|
8
|
+
|
|
7
9
|
import * as styles from './InternalLink.css';
|
|
8
10
|
|
|
9
11
|
interface Props
|
|
@@ -18,7 +20,12 @@ export const InternalLink = forwardRef<HTMLAnchorElement, Props>(
|
|
|
18
20
|
({ className, href, reset = true, state, ...restProps }, ref) => {
|
|
19
21
|
const location = useLocation();
|
|
20
22
|
|
|
21
|
-
const
|
|
23
|
+
const { propagateSearchParams } = useScoobieLink();
|
|
24
|
+
|
|
25
|
+
const to = {
|
|
26
|
+
...parseInternalHref(href, location, propagateSearchParams),
|
|
27
|
+
state,
|
|
28
|
+
};
|
|
22
29
|
|
|
23
30
|
return (
|
|
24
31
|
<NavLink
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { type ReactNode, createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
interface ScoobieLinkContext {
|
|
4
|
+
propagateSearchParams: string[];
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const ctx = createContext<ScoobieLinkContext>({
|
|
8
|
+
propagateSearchParams: ['v'],
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
interface ScoobieLinkProviderProps {
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The search parameters to propagate on internal links.
|
|
16
|
+
*
|
|
17
|
+
* This defaults to `['v']` in the absence of a `ScoobieLinkProvider`.
|
|
18
|
+
*/
|
|
19
|
+
propagateSearchParams: string[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const ScoobieLinkProvider = ({
|
|
23
|
+
children,
|
|
24
|
+
...value
|
|
25
|
+
}: ScoobieLinkProviderProps) => {
|
|
26
|
+
<ctx.Provider value={value}>{children}</ctx.Provider>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const useScoobieLink = () => useContext(ctx);
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { InlineCode } from './components/InlineCode';
|
|
|
5
5
|
export { InternalLink } from './components/InternalLink';
|
|
6
6
|
export { MdxProvider } from './components/MdxProvider';
|
|
7
7
|
export { ScoobieLink } from './components/ScoobieLink';
|
|
8
|
+
export { ScoobieLinkProvider } from './components/ScoobieLinkProvider';
|
|
8
9
|
export { SmartTextLink } from './components/SmartTextLink';
|
|
9
10
|
export { Table } from './components/Table';
|
|
10
11
|
export { TableRow } from './components/TableRow';
|
package/src/private/url.ts
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
const EXAMPLE_BASE_URL = 'https://example.com';
|
|
2
2
|
|
|
3
|
-
const parseVersionParams = (search: string) => {
|
|
4
|
-
const urlSearchParams = new URLSearchParams(search);
|
|
5
|
-
|
|
6
|
-
return {
|
|
7
|
-
v: urlSearchParams.get('v'),
|
|
8
|
-
vPanel: urlSearchParams.get('v-panel'),
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
|
|
12
3
|
const hrefToUrl = (href: string, pathname: string) => {
|
|
13
4
|
if (href.startsWith('/')) {
|
|
14
5
|
return new URL(`${EXAMPLE_BASE_URL}${href}`);
|
|
@@ -27,16 +18,18 @@ export const parseInternalHref = (
|
|
|
27
18
|
pathname: string;
|
|
28
19
|
search: string;
|
|
29
20
|
},
|
|
21
|
+
propagateSearchParams: string[],
|
|
30
22
|
) => {
|
|
31
23
|
const { hash, pathname, searchParams } = hrefToUrl(href, location.pathname);
|
|
32
24
|
|
|
33
|
-
const
|
|
25
|
+
const priorSearchParams = new URLSearchParams(location.search);
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
for (const key of propagateSearchParams) {
|
|
28
|
+
const value = priorSearchParams.get(key);
|
|
29
|
+
|
|
30
|
+
if (value !== null) {
|
|
31
|
+
searchParams.set(key, value);
|
|
32
|
+
}
|
|
40
33
|
}
|
|
41
34
|
|
|
42
35
|
const search = searchParams.toString();
|