Skip to content

Commit 51ed8ce

Browse files
authored
Merge pull request #109 from svelteplot/feat/reuse-link-wrapper
Feat/reuse link wrapper
2 parents 8459546 + 3bcaf10 commit 51ed8ce

37 files changed

+428
-117
lines changed

src/lib/marks/Area.svelte

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import { maybeCurve } from '$lib/helpers/curves.js';
3030
import { isValid } from '$lib/helpers/index.js';
3131
import AreaCanvas from './helpers/AreaCanvas.svelte';
32+
import Anchor from './helpers/Anchor.svelte';
3233
3334
import type {
3435
CurveName,
@@ -37,7 +38,6 @@
3738
BaseMarkProps,
3839
ConstantAccessor,
3940
ChannelAccessor,
40-
FacetContext,
4141
ScaledDataRecord,
4242
LinkableMarkProps
4343
} from '../types.js';
@@ -113,32 +113,24 @@
113113
{:else}
114114
<GroupMultiple length={grouped.length}>
115115
{#each grouped as areaData, i (i)}
116-
{#snippet el(datum: ScaledDataRecord)}
117-
{@const title = resolveProp(options.title, datum.datum, '')}
118-
{@const [style, styleClass] = resolveStyles(
119-
plot,
120-
datum,
121-
options,
122-
'fill',
123-
usedScales
124-
)}
125-
<path
126-
class={['svelteplot-area', className, styleClass]}
127-
clip-path={options.clipPath}
128-
d={areaPath(areaData)}
129-
{style}
130-
>{#if title}<title>{title}</title>{/if}</path>
131-
{/snippet}
116+
{@const datum = areaData[0]}
132117
{#if areaData.length > 0}
133-
{#if options.href}
134-
<a
135-
href={resolveProp(options.href, areaData[0].datum, '')}
136-
target={resolveProp(options.target, areaData[0].datum, '_self')}>
137-
{@render el(areaData[0])}
138-
</a>
139-
{:else}
140-
{@render el(areaData[0])}
141-
{/if}
118+
<Anchor {options} {datum}>
119+
{@const title = resolveProp(options.title, datum.datum, '')}
120+
{@const [style, styleClass] = resolveStyles(
121+
plot,
122+
datum,
123+
options,
124+
'fill',
125+
usedScales
126+
)}
127+
<path
128+
class={['svelteplot-area', className, styleClass]}
129+
clip-path={options.clipPath}
130+
d={areaPath(areaData)}
131+
{style}
132+
>{#if title}<title>{title}</title>{/if}</path>
133+
</Anchor>
142134
{/if}
143135
{/each}
144136
</GroupMultiple>

src/lib/marks/BarX.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
PlotContext,
88
BaseMarkProps,
99
BaseRectMarkProps,
10-
ChannelAccessor
10+
ChannelAccessor,
11+
LinkableMarkProps
1112
} from '../types.js';
1213
1314
export type BarXMarkProps = BaseMarkProps &
15+
LinkableMarkProps &
1416
BaseRectMarkProps & {
1517
data: DataRow[];
1618
x?: ChannelAccessor;

src/lib/marks/BarY.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
} from '../types.js';
1313
1414
export type BarYMarkProps = BaseMarkProps &
15+
LinkableMarkProps &
1516
BaseRectMarkProps & {
1617
data: DataRow[];
1718
x?: ChannelAccessor;

src/lib/marks/Cell.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
} from '../types.js';
1313
1414
export type CellMarkProps = BaseMarkProps &
15+
LinkableMarkProps &
1516
BaseRectMarkProps & {
1617
data: DataRecord[];
1718
x?: ChannelAccessor;

src/lib/marks/Dot.svelte

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
symbol?: ChannelAccessor | Snippet<[number, string]>;
1111
canvas?: boolean;
1212
dotClass?: ConstantAccessor<string>;
13-
};
13+
} & LinkableMarkProps;
1414
</script>
1515

1616
<script lang="ts">
@@ -21,8 +21,8 @@
2121
BaseMarkProps,
2222
ConstantAccessor,
2323
ChannelAccessor,
24-
FacetContext,
25-
PlotDefaults
24+
PlotDefaults,
25+
LinkableMarkProps
2626
} from '../types.js';
2727
import { resolveProp, resolveStyles } from '../helpers/resolve.js';
2828
import { maybeSymbol } from '$lib/helpers/symbols.js';
@@ -33,6 +33,7 @@
3333
import { maybeData, isValid } from '$lib/helpers/index.js';
3434
import { recordizeXY } from '$lib/transforms/recordize.js';
3535
import { addEventHandlers } from './helpers/events.js';
36+
import Anchor from './helpers/Anchor.svelte';
3637
3738
let {
3839
data = [{}],
@@ -95,19 +96,21 @@
9596
'stroke',
9697
usedScales
9798
)}
98-
<path
99-
transform="translate({d.x}, {d.y})"
100-
d={getSymbolPath(d.symbol, d.r ** 2 * Math.PI)}
101-
class={[
102-
dotClass ? resolveProp(dotClass, d.datum, null) : null,
103-
styleClass
104-
]}
105-
{style}
106-
use:addEventHandlers={{
107-
getPlotState,
108-
options: args,
109-
datum: d.datum
110-
}} />
99+
<Anchor {options} datum={d.datum}>
100+
<path
101+
transform="translate({d.x}, {d.y})"
102+
d={getSymbolPath(d.symbol, d.r ** 2 * Math.PI)}
103+
class={[
104+
dotClass ? resolveProp(dotClass, d.datum, null) : null,
105+
styleClass
106+
]}
107+
{style}
108+
use:addEventHandlers={{
109+
getPlotState,
110+
options: args,
111+
datum: d.datum
112+
}} />
113+
</Anchor>
111114
{/if}
112115
{/each}
113116
{/if}

src/lib/marks/Frame.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
BaseMarkProps,
88
'fill' | 'stroke' | 'fillOpacity' | 'strokeOpacity'
99
> &
10+
LinkableMarkProps &
1011
Omit<
1112
BaseRectMarkProps,
1213
'inset' | 'insetLeft' | 'insetRight' | 'insetTop' | 'insetBottom'
@@ -27,7 +28,7 @@
2728
<script lang="ts">
2829
import Mark from '../Mark.svelte';
2930
import { getContext } from 'svelte';
30-
import type { PlotContext, BaseRectMarkProps } from '../types.js';
31+
import type { PlotContext, BaseRectMarkProps, LinkableMarkProps } from '../types.js';
3132
import type { BaseMarkProps } from '../types.js';
3233
import RectPath from './helpers/RectPath.svelte';
3334

src/lib/marks/Geo.svelte

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
geoType?: 'sphere' | 'graticule';
88
dragRotate: boolean;
99
canvas: boolean;
10-
href: ConstantAccessor<string>;
11-
target: ConstantAccessor<string>;
10+
/**
11+
* simple browser tooltip to be displayed on mouseover
12+
*/
13+
title: ConstantAccessor<string>;
1214
} & BaseMarkProps &
1315
LinkableMarkProps;
1416
</script>
@@ -31,6 +33,7 @@
3133
import GeoCanvas from './helpers/GeoCanvas.svelte';
3234
import { recordize } from '$lib/transforms/recordize.js';
3335
import { GEOJSON_PREFER_STROKE } from '$lib/helpers/index.js';
36+
import Anchor from './helpers/Anchor.svelte';
3437
3538
const { getPlotState } = getContext<PlotContext>('svelteplot');
3639
const plot = $derived(getPlotState());
@@ -68,28 +71,6 @@
6871
channels={['fill', 'stroke', 'opacity', 'fillOpacity', 'strokeOpacity', 'r']}
6972
{...args}>
7073
{#snippet children({ mark, scaledData, usedScales })}
71-
{#snippet el(d)}
72-
{@const title = resolveProp(args.title, d.datum, '')}
73-
{@const geometry = resolveProp(args.geometry, d.datum, d.datum)}
74-
{@const [style, styleClass] = resolveStyles(
75-
plot,
76-
d,
77-
args,
78-
GEOJSON_PREFER_STROKE.has(geometry.type) ? 'stroke' : 'fill',
79-
usedScales
80-
)}
81-
<path
82-
d={path(geometry)}
83-
{style}
84-
class={[styleClass]}
85-
use:addEventHandlers={{
86-
getPlotState,
87-
options: args,
88-
datum: d.datum
89-
}}>
90-
{#if title}<title>{title}</title>{/if}
91-
</path>
92-
{/snippet}
9374
<g
9475
aria-label="geo"
9576
class={['geo', geoType && `geo-${geoType}`, className]}
@@ -99,15 +80,28 @@
9980
{:else}
10081
{#each scaledData as d, i (i)}
10182
{#if d.valid}
102-
{#if options.href}
103-
<a
104-
href={resolveProp(args.href, d.datum, '')}
105-
target={resolveProp(args.target, d.datum, '_self')}>
106-
{@render el(d)}
107-
</a>
108-
{:else}
109-
{@render el(d)}
110-
{/if}
83+
<Anchor {options} datum={d.datum}>
84+
{@const title = resolveProp(args.title, d.datum, '')}
85+
{@const geometry = resolveProp(args.geometry, d.datum, d.datum)}
86+
{@const [style, styleClass] = resolveStyles(
87+
plot,
88+
d,
89+
args,
90+
GEOJSON_PREFER_STROKE.has(geometry.type) ? 'stroke' : 'fill',
91+
usedScales
92+
)}
93+
<path
94+
d={path(geometry)}
95+
{style}
96+
class={[styleClass]}
97+
use:addEventHandlers={{
98+
getPlotState,
99+
options: args,
100+
datum: d.datum
101+
}}>
102+
{#if title}<title>{title}</title>{/if}
103+
</path>
104+
</Anchor>
111105
{/if}
112106
{/each}
113107
{/if}

src/lib/marks/Rect.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
y2?: ChannelAccessor;
1414
interval?: number | string;
1515
} & BaseMarkProps &
16+
LinkableMarkProps &
1617
BaseRectMarkProps;
1718
</script>
1819

src/lib/marks/Sphere.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
Geo mark with Sphere geometry object -->
33

44
<script module lang="ts">
5-
import { type BaseMarkProps } from '$lib/types.js';
6-
export type SphereMarkProps = BaseMarkProps;
5+
import { type BaseMarkProps, type LinkableMarkProps } from '$lib/types.js';
6+
export type SphereMarkProps = BaseMarkProps & LinkableMarkProps;
77
</script>
88

99
<script lang="ts">

src/lib/marks/helpers/Anchor.svelte

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script>
2+
import { resolveProp } from '$lib/helpers/resolve';
3+
4+
let { datum = {}, options = {}, children } = $props();
5+
6+
const href = $derived(resolveProp(options.href, datum, null));
7+
const target = $derived(resolveProp(options.target, datum, null));
8+
const rel = $derived(resolveProp(options.rel, datum, null));
9+
const type = $derived(resolveProp(options.type, datum, null));
10+
const download = $derived(resolveProp(options.download, datum, null));
11+
12+
// filter data attributes from options
13+
const dataAttributes = $derived(
14+
Object.fromEntries(
15+
Object.entries(options).filter(([key]) => key.startsWith('data-sveltekit-'))
16+
)
17+
);
18+
</script>
19+
20+
{#if href}
21+
<!-- we can't use <a> directly here because Svelte confuses it with the
22+
HTMLAElement which breaks the rendering -->
23+
<svelte:element
24+
this={'a'}
25+
{href}
26+
{target}
27+
{rel}
28+
{type}
29+
{download}
30+
{...dataAttributes}
31+
aria-label="link"
32+
xmlns="http://www.w3.org/2000/svg">
33+
{@render children?.()}
34+
</svelte:element>
35+
{:else}
36+
{@render children?.()}
37+
{/if}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy