Skip to content

Commit 95d4d49

Browse files
committed
feat: add component option to Button to allow other elements/components
1 parent baac41b commit 95d4d49

File tree

4 files changed

+45
-52
lines changed

4 files changed

+45
-52
lines changed

packages/button/Button.svelte

Lines changed: 26 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,34 @@
1-
{#if href}
2-
<a
3-
use:useActions={use}
4-
use:forwardEvents
5-
class="
6-
mdc-button
7-
{className}
8-
{variant === 'raised' ? 'mdc-button--raised' : ''}
9-
{variant === 'unelevated' ? 'mdc-button--unelevated' : ''}
10-
{variant === 'outlined' ? 'mdc-button--outlined' : ''}
11-
{dense ? 'mdc-button--dense' : ''}
12-
{color === 'secondary' ? 'smui-button--color-secondary' : ''}
13-
{context === 'card:action' ? 'mdc-card__action' : ''}
14-
{context === 'card:action' ? 'mdc-card__action--button' : ''}
15-
{context === 'dialog:action' ? 'mdc-dialog__button' : ''}
16-
{context === 'top-app-bar:navigation' ? 'mdc-top-app-bar__navigation-icon' : ''}
17-
{context === 'top-app-bar:action' ? 'mdc-top-app-bar__action-item' : ''}
18-
{context === 'snackbar' ? 'mdc-snackbar__action' : ''}
19-
"
20-
use:Ripple={[ripple, {unbounded: false}]}
21-
{href}
22-
{...actionProp}
23-
{...defaultProp}
24-
{...props}
25-
><slot></slot></a>
26-
{:else}
27-
<button
28-
use:useActions={use}
29-
use:forwardEvents
30-
class="
31-
mdc-button
32-
{className}
33-
{variant === 'raised' ? 'mdc-button--raised' : ''}
34-
{variant === 'unelevated' ? 'mdc-button--unelevated' : ''}
35-
{variant === 'outlined' ? 'mdc-button--outlined' : ''}
36-
{dense ? 'mdc-button--dense' : ''}
37-
{color === 'secondary' ? 'smui-button--color-secondary' : ''}
38-
{context === 'card:action' ? 'mdc-card__action' : ''}
39-
{context === 'card:action' ? 'mdc-card__action--button' : ''}
40-
{context === 'dialog:action' ? 'mdc-dialog__button' : ''}
41-
{context === 'top-app-bar:navigation' ? 'mdc-top-app-bar__navigation-icon' : ''}
42-
{context === 'top-app-bar:action' ? 'mdc-top-app-bar__action-item' : ''}
43-
{context === 'snackbar' ? 'mdc-snackbar__action' : ''}
44-
"
45-
use:Ripple={[ripple, {unbounded: false}]}
46-
{...actionProp}
47-
{...defaultProp}
48-
{...props}
49-
><slot></slot></button>
50-
{/if}
1+
<svelte:component
2+
this={component}
3+
use={[forwardEvents, [Ripple, [ripple, {unbounded: false}]], ...use]}
4+
class="
5+
mdc-button
6+
{className}
7+
{variant === 'raised' ? 'mdc-button--raised' : ''}
8+
{variant === 'unelevated' ? 'mdc-button--unelevated' : ''}
9+
{variant === 'outlined' ? 'mdc-button--outlined' : ''}
10+
{dense ? 'mdc-button--dense' : ''}
11+
{color === 'secondary' ? 'smui-button--color-secondary' : ''}
12+
{context === 'card:action' ? 'mdc-card__action' : ''}
13+
{context === 'card:action' ? 'mdc-card__action--button' : ''}
14+
{context === 'dialog:action' ? 'mdc-dialog__button' : ''}
15+
{context === 'top-app-bar:navigation' ? 'mdc-top-app-bar__navigation-icon' : ''}
16+
{context === 'top-app-bar:action' ? 'mdc-top-app-bar__action-item' : ''}
17+
{context === 'snackbar' ? 'mdc-snackbar__action' : ''}
18+
"
19+
{...actionProp}
20+
{...defaultProp}
21+
{...exclude($$props, ['use', 'class', 'ripple', 'color', 'variant', 'dense', ...dialogExcludes])}
22+
><slot></slot></svelte:component>
5123

5224
<script>
5325
import {setContext, getContext} from 'svelte';
5426
import {current_component} from 'svelte/internal';
5527
import {forwardEventsBuilder} from '@smui/common/forwardEvents.js';
5628
import {exclude} from '@smui/common/exclude.js';
5729
import {useActions} from '@smui/common/useActions.js';
30+
import A from '@smui/common/A.svelte';
31+
import Button from '@smui/common/Button.svelte';
5832
import Ripple from '@smui/ripple/bare.js';
5933
6034
const forwardEvents = forwardEventsBuilder(current_component);
@@ -66,17 +40,17 @@
6640
export let color = 'primary';
6741
export let variant = 'text';
6842
export let dense = false;
43+
// Purposely left out of props exclude.
6944
export let href = null;
7045
export let action = 'close';
7146
let defaultAction = false;
7247
export {defaultAction as default};
48+
export let component = href == null ? Button : A;
7349
7450
let context = getContext('SMUI:button:context');
7551
7652
$: dialogExcludes = (context === 'dialog:action') ? ['action', 'default'] : [];
7753
78-
$: props = exclude($$props, ['use', 'class', 'ripple', 'color', 'variant', 'dense', 'href', ...dialogExcludes]);
79-
8054
$: actionProp = (context === 'dialog:action' && action !== null) ? {'data-mdc-dialog-action': action} : {};
8155
$: defaultProp = (context === 'dialog:action' && defaultAction) ? {'data-mdc-dialog-button-default': ''} : {};
8256

packages/button/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ A button.
4242

4343
### Options / Defaults
4444

45+
* `component`: `href == null ? Button : A` - A component to use as the root element.
4546
* `use`: `[]` - An array of actions and/or action/property arrays.
4647
* `class`: `''` - A CSS class string.
4748
* `ripple`: `true` - Whether to implement a ripple for when the component is interacted with.

packages/common/Button.svelte

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<button
2+
use:useActions={use}
3+
use:forwardEvents
4+
{...exclude($$props, ['use'])}
5+
><slot></slot></button>
6+
7+
<script>
8+
import {current_component} from 'svelte/internal';
9+
import {forwardEventsBuilder} from './forwardEvents.js';
10+
import {exclude} from './exclude.js';
11+
import {useActions} from './useActions.js';
12+
13+
const forwardEvents = forwardEventsBuilder(current_component);
14+
15+
export let use = [];
16+
</script>

site/src/routes/demo/button.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<Button on:click={() => clicked++} variant="outlined"><Label>Outlined</Label></Button>
1515
<Button on:click={() => clicked++} dense><Label>Dense</Label></Button>
1616
<Button on:click={() => clicked++} class="myClass"><Label>With a Class</Label></Button>
17+
<Button on:click={() => clicked++} href="http://example.com" target="_blank"><Label>Link Button</Label></Button>
1718
</div>
1819

1920
<div>
@@ -31,6 +32,7 @@
3132
<Button color="secondary" on:click={() => clicked++} variant="outlined"><Label>Outlined</Label></Button>
3233
<Button color="secondary" on:click={() => clicked++} dense><Label>Dense</Label></Button>
3334
<Button color="secondary" on:click={() => clicked++} class="myClass"><Label>With a Class</Label></Button>
35+
<Button color="secondary" on:click={() => clicked++} href="http://example.com" target="_blank"><Label>Link Button</Label></Button>
3436
</div>
3537

3638
<div>

0 commit comments

Comments
 (0)