forked from tsai/budibase
11 changed files with 199 additions and 46 deletions
@ -1,39 +0,0 @@ |
|||||
<script> |
|
||||
import "@material/button/mdc-button.scss"; |
|
||||
import "@material/button/_mixins.scss"; |
|
||||
|
|
||||
//TODO: How does theme color work for this? |
|
||||
//TODO: Add action for ripple |
|
||||
//TODO: Create class builder class or fn |
|
||||
|
|
||||
/* |
|
||||
==BLOCK MODIFIERS== |
|
||||
raised = via variant prop |
|
||||
outlined = via variant prop |
|
||||
unelevated = via variant prop |
|
||||
touch = needs accessibility wrapper div |
|
||||
*/ |
|
||||
|
|
||||
export let text = ""; |
|
||||
|
|
||||
//Either raised,outlined or unelevated |
|
||||
export let variant = "raised"; |
|
||||
export let colour = "primary"; |
|
||||
export let disabled = false; //added directly to button element (not in class) |
|
||||
export let icon = ""; |
|
||||
export let trailingIcon = false; |
|
||||
|
|
||||
$: renderLeadingIcon = !!icon && !trailingIcon; |
|
||||
$: renderTrailingIcon = !!icon && trailingIcon; |
|
||||
</script> |
|
||||
|
|
||||
<button class="mdc-button" {disabled}> |
|
||||
<div class="mdc-button__ripple" /> |
|
||||
{#if renderLeadingIcon} |
|
||||
<i class="material-icons mdc-button__icon" aria-hidden="true">{icon}</i> |
|
||||
{/if} |
|
||||
<span class="mdc-button__label">{text}</span> |
|
||||
{#if renderTrailingIcon} |
|
||||
<i class="material-icons mdc-button__icon" aria-hidden="true">{icon}</i> |
|
||||
{/if} |
|
||||
</button> |
|
||||
@ -0,0 +1,60 @@ |
|||||
|
<script> |
||||
|
import { setContext, getContext } from "svelte"; |
||||
|
import Icon from "../Icon.svelte"; |
||||
|
import ripple from "../Ripple.js"; |
||||
|
import ClassBuilder from "../ClassBuilder.js"; |
||||
|
|
||||
|
const cb = new ClassBuilder("button", ["primary", "medium"]); |
||||
|
|
||||
|
export let variant = "raised"; |
||||
|
export let colour = "primary"; |
||||
|
export let size = "medium"; |
||||
|
|
||||
|
export let href = ""; |
||||
|
export let icon = ""; |
||||
|
export let trailingIcon = false; |
||||
|
export let fullBleed = false; |
||||
|
|
||||
|
export let text = ""; |
||||
|
export let disabled = false; |
||||
|
|
||||
|
$: if (!!icon) { |
||||
|
setContext("BBMD:icon:context", "button"); |
||||
|
} |
||||
|
|
||||
|
$: renderLeadingIcon = !!icon && !trailingIcon; |
||||
|
$: renderTrailingIcon = !!icon && trailingIcon; |
||||
|
|
||||
|
let blockClasses = cb.blocks({ |
||||
|
modifiers: !href ? [variant] : null, |
||||
|
customs: { size, colour } |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.fullBleed { |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<!-- TODO: Activated colour on primary elevated buttons seems to be rendering weird --> |
||||
|
{#if href} |
||||
|
<a class={blockClasses} {href} on:click> |
||||
|
<span class={cb.elements('label')}>{text}</span> |
||||
|
</a> |
||||
|
{:else} |
||||
|
<button |
||||
|
use:ripple={{ colour }} |
||||
|
class={blockClasses} |
||||
|
class:fullBleed |
||||
|
{disabled} |
||||
|
on:click> |
||||
|
{#if renderLeadingIcon} |
||||
|
<Icon {icon} /> |
||||
|
{/if} |
||||
|
<span class={cb.elements('label')}>{text}</span> |
||||
|
{#if renderTrailingIcon} |
||||
|
<Icon {icon} /> |
||||
|
{/if} |
||||
|
</button> |
||||
|
{/if} |
||||
@ -0,0 +1,5 @@ |
|||||
|
@import "@material/button/mdc-button.scss"; |
||||
|
@import "@material/ripple/mdc-ripple.scss"; |
||||
|
@import "./mixins.scss"; |
||||
|
|
||||
|
@include bbmd-button-styles(); |
||||
@ -0,0 +1,39 @@ |
|||||
|
@import "@material/feature-targeting/functions"; |
||||
|
@import "@material/feature-targeting/mixins"; |
||||
|
|
||||
|
@mixin bbmd-button-styles($query: mdc-feature-all()) { |
||||
|
$feat-structure: mdc-feature-create-target($query, structure); |
||||
|
|
||||
|
.bbmd-mdc-button--size-large { |
||||
|
@include button-sizing($feat-structure, 21px, 40px, 15px); |
||||
|
} |
||||
|
|
||||
|
.bbmd-mdc-button--size-small { |
||||
|
@include button-sizing($feat-structure, 9px, 32px, 13px); |
||||
|
} |
||||
|
|
||||
|
.bbmd-mdc-button--colour-secondary { |
||||
|
//no feature target as relying on theme variable custom property |
||||
|
@include mdc-button-ink-color(secondary); |
||||
|
|
||||
|
&.mdc-button--raised, |
||||
|
&.mdc-button--unelevated { |
||||
|
@include mdc-button-container-fill-color(secondary); |
||||
|
@include mdc-button-ink-color(on-secondary); |
||||
|
} |
||||
|
|
||||
|
&.mdc-button--outlined { |
||||
|
@include mdc-button-outline-color(secondary); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@mixin button-sizing($feat, $padding, $height, $fontSize) { |
||||
|
@include mdc-feature-targets($feat) { |
||||
|
padding: 0px $padding; |
||||
|
height: $height; |
||||
|
} |
||||
|
> .mdc-button__label { |
||||
|
font-size: $fontSize; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
import "./_index.scss"; |
||||
|
export { default as button } from "./Button.svelte"; |
||||
@ -1,6 +1,38 @@ |
|||||
export default class ClassBuilder { |
export default class ClassBuilder { |
||||
block = ""; |
constructor(block, customDefaults) { |
||||
constructor(block) { |
|
||||
this.block = `mdc-${block}`; |
this.block = `mdc-${block}`; |
||||
|
this.customDefaults = customDefaults; //will be ignored when building custom classes
|
||||
|
} |
||||
|
|
||||
|
// classParams: {modifiers:[] (mdc), custom:[] (bbmd), extra:[] (any)}
|
||||
|
blocks(classParams) { |
||||
|
let base = this.block; |
||||
|
if (classParams == undefined) return base; |
||||
|
return this.buildClass(base, classParams); |
||||
|
} |
||||
|
|
||||
|
//elementName: string, classParams: {}
|
||||
|
elements(elementName, classParams) { |
||||
|
let base = `${this.block}__${elementName}`; |
||||
|
if (classParams == undefined) return base; |
||||
|
return this.buildClass(base, classParams); |
||||
|
} |
||||
|
|
||||
|
buildClass(base, classParams) { |
||||
|
let cls = base; |
||||
|
const { modifiers, customs, extras } = classParams; |
||||
|
if (!!modifiers) cls += modifiers.map(m => ` ${base}--${m}`).join(" "); |
||||
|
if (!!customs) |
||||
|
cls += Object.entries(customs) |
||||
|
.map(([property, value]) => { |
||||
|
//disregard falsy and values set by customDefaults constructor param
|
||||
|
if (!!value && !this.customDefaults.includes(value)) { |
||||
|
//custom scss name convention = bbmd-[block | element]--[property]-[value]
|
||||
|
return ` bbmd-${base}--${property}-${value}`; |
||||
|
} |
||||
|
}) |
||||
|
.join(""); |
||||
|
if (!!extras) cls += ` ${extras.join(" ")}`; |
||||
|
return cls.trim(); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,13 @@ |
|||||
|
<script> |
||||
|
import { getContext } from "svelte"; |
||||
|
|
||||
|
export let icon = ""; |
||||
|
|
||||
|
let iconContext = getContext("BBMD:icon:context"); |
||||
|
let cls = |
||||
|
iconContext == "button" |
||||
|
? "material-icons mdc-button__icon" |
||||
|
: "material-icons"; |
||||
|
</script> |
||||
|
|
||||
|
<i class={cls}>{icon}</i> |
||||
@ -0,0 +1,28 @@ |
|||||
|
import { MDCRipple } from "@material/ripple"; |
||||
|
|
||||
|
export default function ripple( |
||||
|
node, |
||||
|
props = { colour: "primary", unbounded: false } |
||||
|
) { |
||||
|
node.classList.add("mdc-ripple-surface"); |
||||
|
const component = new MDCRipple(node); |
||||
|
component.unbounded = props.unbounded; |
||||
|
|
||||
|
if (props.colour === "secondary") { |
||||
|
node.classList.remove("mdc-ripple-surface--primary"); |
||||
|
node.classList.add("mdc-ripple-surface--accent"); |
||||
|
} else { |
||||
|
node.classList.add("mdc-ripple-surface--primary"); |
||||
|
node.classList.remove("mdc-ripple-surface--accent"); |
||||
|
} |
||||
|
|
||||
|
return { |
||||
|
destroy() { |
||||
|
component.destroy(); |
||||
|
node.classList.remove("mdc-ripple-surface"); |
||||
|
node.classList.remove("mdc-ripple-surface--primary"); |
||||
|
node.classList.remove("mdc-ripple-surface--accent"); |
||||
|
component = null; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
@ -1,4 +1,4 @@ |
|||||
import h1 from "../H1.svelte"; |
import h1 from "../H1.svelte"; |
||||
import { button } from "@BBMD"; |
import { button, icon } from "@BBMD"; |
||||
|
|
||||
export default { h1, button }; |
export default { h1, button, icon }; |
||||
|
|||||
@ -1,3 +1,3 @@ |
|||||
export { default as h1 } from "./H1.svelte"; |
export { default as h1 } from "./H1.svelte"; |
||||
export { default as button } from "./Button.svelte"; |
export { default as icon } from "./Icon.svelte"; |
||||
|
export { button } from "./Button"; |
||||
|
|||||
Loading…
Reference in new issue