From 97da31fb63c51e2f8216c0afa199d6240aa98106 Mon Sep 17 00:00:00 2001
From: Conor_Mack <36074859+Conor-Mack@users.noreply.github.com>
Date: Mon, 10 Feb 2020 10:04:20 +0000
Subject: [PATCH] New feature and refactor of Classbuilder along with some bug
fixes (#85)
---
.../src/Button/Button.svelte | 66 +++++++-------
.../src/ClassBuilder.js | 87 ++++++++++++-------
.../src/Test/props.js | 9 +-
.../src/Textfield/Textfield.svelte | 26 +++---
.../src/Textfield/_mixins.scss | 5 +-
5 files changed, 111 insertions(+), 82 deletions(-)
diff --git a/packages/materialdesign-components/src/Button/Button.svelte b/packages/materialdesign-components/src/Button/Button.svelte
index eee93cac6d..c0c9ceb7e2 100644
--- a/packages/materialdesign-components/src/Button/Button.svelte
+++ b/packages/materialdesign-components/src/Button/Button.svelte
@@ -1,40 +1,50 @@
-
+
+
{#if href}
- {text}
+ {text}
{:else}
{/if}
- {text}
+ {text}
{#if renderTrailingIcon}
{/if}
{/if}
-
-
diff --git a/packages/materialdesign-components/src/ClassBuilder.js b/packages/materialdesign-components/src/ClassBuilder.js
index 2f11edd49b..6b54666559 100644
--- a/packages/materialdesign-components/src/ClassBuilder.js
+++ b/packages/materialdesign-components/src/ClassBuilder.js
@@ -1,43 +1,70 @@
export default class ClassBuilder {
- constructor(block, customDefaults) {
+ constructor(block, defaultIgnoreList) {
this.block = `mdc-${block}`;
- this.customDefaults = customDefaults; //will be ignored when building custom classes
+ this.defaultIgnoreList = defaultIgnoreList; //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);
+ /*
+ handles both blocks and elementss (BEM MD Notation)
+ params = {elementName: string, props: {modifiers{}, customs:{}, extras: []}}
+ All are optional
+ */
+ build(params) {
+ if (!params) return this.block; //return block if nothing passed
+ const { props, elementName } = params;
+ let base = !!elementName ? `${this.block}__${elementName}` : this.block;
+ if (!props) return base;
+ return this._handleProps(base, props);
}
- //elementName: string, classParams: {}
- elements(elementName, classParams) {
- let base = `${this.block}__${elementName}`;
- if (classParams == undefined) return base;
- return this.buildClass(base, classParams);
+ //Easily grab a simple element class
+ elem(elementName) {
+ return this.build({ elementName });
}
- //TODO: Classparams modifier and custom could take an object. Booleans or numbers use key value for classes, strings use property value for classes. Extras to stay as is
- buildClass(base, classParams) {
+ //use if a different base is needed than whats defined by this.block
+ debase(base, elementProps) {
+ if (!elementProps) return base;
+ return this._handleProps(base, elementProps);
+ }
+
+ //proxies bindProps and checks for which elementProps exist before binding
+ _handleProps(base, elementProps) {
let cls = base;
- const { modifiers, customs, extras } = classParams;
- if (!!modifiers)
- cls += modifiers.map(m => (!!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 || !this.customDefaults.includes(value))
- ) {
- //custom scss name convention = bbmd-[block | element]--[property]-[value]
- return ` bbmd-${base}--${property}-${value}`;
- }
- })
- .join("");
+ const { modifiers, customs, extras } = elementProps;
+ if (!!modifiers) cls += this._bindProps(modifiers, base);
+ if (!!customs) cls += this._bindProps(customs, base, true);
if (!!extras) cls += ` ${extras.join(" ")}`;
return cls.trim();
}
+
+ /*
+ Handles both modifiers and customs. Use property, value or both depending
+ on whether it is passsed props for custom or modifiers
+ if custom uses the following convention for scss mixins:
+ bbmd-{this.block}--{property}-{value}
+ bbmd-mdc-button--size-large
+ */
+ _bindProps(elementProps, base, isCustom = false) {
+ return Object.entries(elementProps)
+ .map(([property, value]) => {
+ //disregard falsy and values set by defaultIgnoreList constructor param
+ if (
+ !!value &&
+ (!this.defaultIgnoreList || !this.defaultIgnoreList.includes(value))
+ ) {
+ let classBase = isCustom ? `bbmd-${base}` : `${base}`;
+ let valueType = typeof value;
+
+ if (valueType == "string" || valueType == "number") {
+ return isCustom
+ ? ` ${classBase}--${property}-${value}`
+ : ` ${classBase}--${value}`;
+ } else if (valueType == "boolean") {
+ return ` ${classBase}--${property}`;
+ }
+ }
+ })
+ .join("");
+ }
}
diff --git a/packages/materialdesign-components/src/Test/props.js b/packages/materialdesign-components/src/Test/props.js
index 700f611694..70145635ec 100644
--- a/packages/materialdesign-components/src/Test/props.js
+++ b/packages/materialdesign-components/src/Test/props.js
@@ -1,5 +1,6 @@
const getComponent = comp => `@budibase//materialdesign-components/${comp}`;
+
export const props = {
justAnH1: {
_component: "@budibase/materialdesign-components/h1",
@@ -27,11 +28,11 @@ export const props = {
textfield: {
_component: "@budibase/materialdesign-components/textfield",
_children: [],
- label: "Surname",
- icon: "alarm_on",
- variant: "outlined",
- helperText: "Add Surname",
+ label: "First",
+ colour: "secondary",
textarea: true,
+ fullwidth:true,
+ helperText: "Add Surname",
useCharCounter: true
}
};
diff --git a/packages/materialdesign-components/src/Textfield/Textfield.svelte b/packages/materialdesign-components/src/Textfield/Textfield.svelte
index fd03dca37f..54a207c33d 100644
--- a/packages/materialdesign-components/src/Textfield/Textfield.svelte
+++ b/packages/materialdesign-components/src/Textfield/Textfield.svelte
@@ -44,15 +44,14 @@
export let persistent = false
let id = `${label}-${variant}`
- let helperClasses = `${cb.block}-helper-text`
- let modifiers = []
+ let modifiers = { fullwidth, disabled, textarea }
let customs = { colour }
if (variant == "standard" || fullwidth) {
customs = { ...customs, variant }
} else {
- modifiers.push(variant)
+ modifiers = { ...modifiers, variant }
}
if (!textarea && size !== "medium") {
@@ -60,15 +59,12 @@
}
if (!label || fullwidth) {
- modifiers.push("no-label")
+ modifiers = { ...modifiers, noLabel: "no-label" }
}
- //TODO: Refactor - this could be handled better using an object as modifier instead of an array
- if (fullwidth) modifiers.push("fullwidth")
- if (disabled) modifiers.push("disabled")
- if (textarea) modifiers.push("textarea")
- if (persistent) helperClasses += ` ${cb.block}-helper-text--persistent`
- if (validation) helperClasses += ` ${cb.block}-helper-text--validation`
+ let helperClasses = cb.debase(`${cb.block}-helper-text`, {
+ modifiers: { persistent, validation },
+ })
let useLabel = !!label && (!fullwidth || (fullwidth && textarea))
let useIcon = !!icon && (!textarea && !fullwidth)
@@ -77,16 +73,16 @@
if (useIcon) {
setContext("BBMD:icon:context", "text-field")
- trailingIcon
- ? modifiers.push("with-trailing-icon")
- : modifiers.push("with-leading-icon")
+ let iconClass = trailingIcon ? "with-trailing-icon" : "with-leading-icon"
+ modifiers = { ...modifiers, iconClass }
}
$: renderLeadingIcon = useIcon && !trailingIcon
$: renderTrailingIcon = useIcon && trailingIcon
- const blockClasses = cb.blocks({ modifiers, customs })
- const inputClasses = cb.elements("input")
+ let props = { modifiers, customs }
+ const blockClasses = cb.build({ props })
+ const inputClasses = cb.elem("input")
let renderMaxLength = !!maxLength ? `0 / ${maxLength}` : "0"
diff --git a/packages/materialdesign-components/src/Textfield/_mixins.scss b/packages/materialdesign-components/src/Textfield/_mixins.scss
index b9ddfdc662..e589d9d2c9 100644
--- a/packages/materialdesign-components/src/Textfield/_mixins.scss
+++ b/packages/materialdesign-components/src/Textfield/_mixins.scss
@@ -16,11 +16,12 @@
&.bbmd-mdc-text-field--colour-secondary {
&.mdc-text-field--focused {
.mdc-floating-label--float-above {
- color: var(--mdc-theme-secondary);
+ @include mdc-floating-label-ink-color(secondary)
+
}
}
.mdc-line-ripple--active {
- background-color: var(--mdc-theme-secondary);
+ @include mdc-line-ripple-color(secondary);
}
&.mdc-text-field--outlined,