Add Bootstrap button styles to default Gutenberg Button block in WordPress - wordpress

I want to use the default button styles from the Bootstrap framework with the default button block of Gutenberg.
I found a solution to remove the default styles from WordPress and add some own styles. Here's the link: https://www.billerickson.net/block-styles-in-gutenberg/
I'm using the code from Bill Erickson to remove the default styles and add a new one. In my case, the .btn-primary style from Bootstrap:
wp.domReady( () => {
wp.blocks.unregisterBlockStyle( 'core/button', 'default' );
wp.blocks.unregisterBlockStyle( 'core/button', 'outline' );
wp.blocks.unregisterBlockStyle( 'core/button', 'squared' );
wp.blocks.registerBlockStyle( 'core/button', {
name: 'btn',
label: 'Default',
isDefault: true,
});
wp.blocks.registerBlockStyle( 'core/button', {
name: 'btn-primary',
label: 'Primary',
} );
} );
There a two problems here:
WordPress adds the class in the wrong way
It just adds one class but Bootstrap needs two at least
This is the button code after adding the class:
<div class="wp-block-button aligncenter is-style-btn-primary">
<a class="wp-block-button__link" href="#">Button</a>
</div>
As you can see, WordPress adds the new class two the div around the button.
And it adds is-style- to the class.
To use the button block with Bootstrap styles. I need a code like this:
<div class="wp-block-button aligncenter is-style-btn-primary">
<a class="btn btn-primary" href="#">Button</a>
</div>
The class has to be inside the <a> tag and I need the second class .btn as well.
Is there any way to add these two classes to the <a> tag?

Another way you can take care of this is using SCSS #extend
First register block styles that will show up in the buttons block editor:
wp.domReady ( function() {
wp.blocks.unregisterBlockStyle( 'core/button', 'outline');
wp.blocks.unregisterBlockStyle( 'core/button', 'fill');
wp.blocks.registerBlockStyle( 'core/button', {
name: 'bootstrap-default',
label: 'Bootstrap Default',
isDefault: true
});
wp.blocks.registerBlockStyle( 'core/button', {
name: 'bootstrap-primary',
label: 'Bootstrap Primary',
});
wp.blocks.registerBlockStyle( 'core/button', {
name: 'bootstrap-success',
label: 'Bootstrap Success',
});
wp.blocks.registerBlockStyle( 'core/button', {
name: 'bootstrap-default-lg',
label: 'Bootstrap Default Large',
});
wp.blocks.registerBlockStyle( 'core/button', {
name: 'bootstrap-primary-lg',
label: 'Bootstrap Primary Large',
});
wp.blocks.registerBlockStyle( 'core/button', {
name: 'bootstrap-success-lg',
label: 'Bootstrap Success Large',
});
});
Then I created a _wordpress.scss that gets included and compiled with the rules from each block style and what Bootstrap rules they extend:
.is-style-bootstrap-default > a {
#extend .btn;
#extend .btn-default;
}
.is-style-bootstrap-primary > a {
#extend .btn;
#extend .btn-primary;
}
.is-style-bootstrap-success > a {
#extend .btn;
#extend .btn-success;
}
.is-style-bootstrap-default-lg > a {
#extend .btn;
#extend .btn-default;
#extend .btn-lg;
}
.is-style-bootstrap-primary-lg > a {
#extend .btn;
#extend .btn-primary;
#extend .btn-lg;
}
.is-style-bootstrap-success-lg > a {
#extend .btn;
#extend .btn-success;
#extend .btn-lg;
}

I think you will find it is less complicated to write your own button than override existing component. If you really want to override the core button block you will probably need to apply the appropriate block filters.
If you are looking for an immediate solution, the source of the button component inside the Advanced Bootstrap Blocks plugin may get you started, or you can install through the plugin directory.
(Full disclosure: I am the author of this plugin.)

You can either install this plugin:
https://wordpress.org/plugins/wp-bootstrap-blocks/
Or read the plugin code and create your own block, then you can also create your own custom styles for buttons.

Related

Use bootstrap css and other global css in Vue.js custom elements

No fancy webpack, simple Vue custom element with some global css and some inline css for overrides.
I would like to use some styling library, like from getbootstrap.com and have it change styles inside custom element.
https://jsfiddle.net/Deele/6xk1atrn/25/
<div class="btn bg-info">Zero</div>
<test-widget id="One"></test-widget>
<test-widget id="Two"></test-widget>
const TestWidget = Vue.defineCustomElement({
props: {
id: String
},
data: () => {
return {
message: 'Test'
}
},
emits: {},
template: `<div class="btn bg-info">{{id}} {{message}}</div>`,
styles: [`div { color: green; }`]
})
customElements.define('test-widget', TestWidget)
.bg-info {
background-color: red!important;
}
Was expecting divs inside rendered elements would be styled as buttons, but it does not work!?
From what I have found in the internet, it has something to do with Shadow DOM not inheriting any global styles.
Please, tell me if there is a solution to this approach? I would like to create small widgets for my website using Vue.js, but this hurdle creates fatal limitation.
Custom elements defined using the Vue API always use a shadow DOM, so they are isolated from the parent document and any global styles in the app.
So to make it happen, You can inject the bootstrap styles or any global style url's in the styles option by using #import statement.
Live Demo :
const TestWidget = Vue.defineCustomElement({
props: {
id: String
},
data: () => {
return {
message: 'Test'
}
},
template: `<div class="btn bg-info">{{id}} {{message}}</div>`,
styles: [`#import url("https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css"); div { color: green; }`]
});
customElements.define('test-widget', TestWidget);
<script src="https://unpkg.com/vue#next"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css"/>
<div class="btn bg-info">Zero</div>
<test-widget id="One"></test-widget>
<test-widget id="Two"></test-widget>

Add styles of class of external css file to Block props to use as attributes

Is it possible to use styles of a class in an external css file ( which is added to the block.json) as props to use these as attributes in the InspectorControls Component, if so, how?
I know that I can use inline styles as attributes for the InspectorControls Component. But dont know any way to use certain parts of classes in the external css files.
My css file added to the blocks.json:
"editorScript": "file:./index.js",
"editorStyle": "file:./editor.css",
"style": "file:./style.css"
I want to use Method 2 from this wordpress docs page for my classes and then use parts of the classes as attributes.
Yes, by importing the class names from a CSS module as the options for a UI control (eg <SelectControl>) the class can be applied to the block with useBlockProps().
In the example below, I used create block to setup a simple block that renders a paragraph which the user can choose the color "theme" of. It's best to use a CSS file containing only the classes you wish to load into the UI component, eg:
theme.scss (or an external css file)
.red{
color:red;
border-color: red;
}
.blue{
color:blue;
border-color: blue;
}
Create a new SCSS file with CSS modules in block/src to import the external styles:
classes.module.scss
#import './theme.scss';
Import the same external CSS in the blocks main style so it will be compiled into style.css, eg:
style.scss (main block styles)
#import './theme.scss';
.wp-block-gutenberg-default-block{
/* all custom styles for the block */
padding: 1em;
border:2px solid;
}
Alternatively, you could enqueue the stylesheet separately via PHP or via the theme..
Add a new string attribute to store the name of the class selected from the UI/SelectControl, eg:
block.json
{
...
"attributes": {
"customClassName": {
"type": "string",
"default": ""
}
},
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
By naming the importing the CSS module in edit(), we can have access an Object containing all the classes from theme.scss. Before displaying in the UI, the class names are formatted as options for a <SelectControl>. The selected class name is saved to the blocks attributes and applied by useBlockProps(), eg:
edit.js
import { InspectorControls, useBlockProps } from '#wordpress/block-editor';
import { PanelBody, SelectControl } from '#wordpress/components';
import styleClasses from './classes.module.scss';
export default function Edit({ attributes, setAttributes }) {
const { customClassName } = attributes;
const myClasses = [{ label: 'none', value: '' }]; // Default option for SelectControl
// Add each classname in styleClasses to myClasses
for (const key in styleClasses) {
myClasses.push({ label: key, value: key })
}
return (
<>
<InspectorControls>
<PanelBody>
<SelectControl
label="Custom Class"
value={customClassName}
options={myClasses}
onChange={(value) => setAttributes({ customClassName: value })}
/>
</PanelBody>
</InspectorControls>
<p {...useBlockProps({ className: customClassName })}>Hello World</p>
</>
);
}
Finally, useBlockProps.save() wraps the selected classname into the blocks markup on save.
save.js
import { useBlockProps } from '#wordpress/block-editor';
export default function save({ attributes }) {
const { customClassName } = attributes;
return (
<p {...useBlockProps.save({ className: customClassName })}>Hello World</p >
);
}
End result:
Hopefully this will give you some ideas for what's possible in your own block with CSS and attributes.

Styling Mailchimp sign up form in React

I am trying to use the NPM React module for Mailchimp: https://www.npmjs.com/package/react-mailchimp-form. It works great and gives you all the forms that you may need but I am struggling to style it.
It says that you can add a personalized class for CSS styling, but how will that contain styles for all elements on the form?
Currently the form looks like this:
function MailchimpForm() {
return (
<div>
<Mailchimp
action=
fields={[
{
name: 'EMAIL',
placeholder: 'Email',
type: 'email',
required: true
},
{
name: 'COMPANY',
placeholder: 'name',
type: 'text',
required: true
}
]}
// Change predetermined language
messages={
{
sending: "Sending...",
success: "Thank you for subscribing!",
error: "An unexpected internal error has occurred.",
empty: "You must write an e-mail.",
duplicate: "Too many subscribe attempts for this email address",
button: "Subscribe!"
}
}
// Add a personalized class
className='MailchimpStyle'
/>
</div>
)
}
Where MailchimpStyle is my CSS style class. Is there a way to have multiple CSS styles in a class?
The current class looks like:
.MailchimpStyle {
clear: left;
font: 200px Helvetica, Arial, sans-serif;
}
You should be able to access the elements by specifying the elements after the className in the css sheet. Example for button:
.MailchimpStyle button {
clear: left;
color: black;
background-color: white;
margin: 2px;
}

Vue.js stylus and scoped css is not working

I'm using stylus and scoped css styles with vuetify. I tried using deep nested selector ::v-deep or >>> but none of them had worked for me (eventhough i rebuild the project because hot reload sometimes is not working) Whenever i click on textbox, this class is being applied to it (i believe coming from vuetify
.v-application --primary-text{
color:white !important
}
Now I tried changing and overriding this style via but none of them had worked.
<style lang="stylus" scoped>
.v-application
&.primary--text
color:black !important
.sample
color:red !important
.v-application >>> .primary--text
color:black !important
.v-application /deep/ .primary--text
color:black !important
.v-application::v-deep .primary--text{
color:black !important
}
</style>
Template part
<template>
<div>
<v-text-field
v-model="name"
label="Regular"
counter="25"
hint="This field uses counter prop"
#input="updateFilter"
#keyup.enter="onEnter"
clearable
:class="sample"
>
<v-icon small #click="submit">fas fa-search</v-icon>
</v-text-field>
</div>
</template>
<script>
import Vue from 'vue'
export default Vue.extend({
name: 'MultiSearch',
data() {
return {
name: '',
// title: 'Preliminary report',
// description: 'California is a state in the western United States',
// rules: [(v) => v.length <= 25 || 'Max 25 characters'],
// wordsRules: [(v) => v.trim().split(' ').length <= 5 || 'Max 5 words'],
}
},
methods: {
updateFilter(event) {
console.log('event is', event)
console.log('this name', this.name)
},
submit(event) {
console.log('event is', event)
console.log('clicked', this.name)
this.$emit('updateFilter', this.name)
},
onEnter(event) {
console.log('entered is ', event)
},
},
})
</script>
Did you installed stylus at first before trying any CSS ?
yarn add -D stylus stylus-loader
https://vue-loader.vuejs.org/guide/pre-processors.html#stylus
As of the selector, this should be ::v-deep indeed.
Reference for the selectors: https://stackoverflow.com/a/55368933/8816585
I solved this problem by adding
options: { styleIsolation: 'shared' }, // add this
methods: {
yourFunc1 () {
}
}
.
Config this in the components like the methods, it's the same level like methods.

Angular 2 RouterLinkActive class for child routes

I have a nav component with a sub nav associated to it. The data structure is as follows:
{
title: 'Layout', routerLink: 'layout', // main nav
subNav: // sub nav
{
title: 'Layout',
items: [
{ title: 'Layout', routerLink: 'layout' },
{ title: 'Page Layout', routerLink: 'page-layout' },
]
}
}
I would like to create a link between the main nav and the sub nav so that when page-layout is navigated to, the active class is still set. My current parent HTML is:
<div [routerLink]="[item.routerLink]"
[routerLinkActive]="['active']"
[routerLinkActiveOptions]="{ exact: true }" #navitem>
// navigation specific html
</div>
I have attempted to add multiple routerlinks options and provide an array of routerlink options such as
[routerLink]="['/layout', '/page-layout']"
but this doesn't work.
Thanks

Resources