📜 ⬆️ ⬇️

Writing a component with “material” buttons for Svelte

Inspired by the SvelteJS articles : Release Two , Disappearing Framework and Re: “Comparing JS Framework: React, Vue and Hyperapp” , about the “disappearing” Svelte framework (read “reduced”, and then you never know ), I wanted to try it. And for a start I decided to write a small component with buttons from Materialize .

Method One: Classic


The Svelte start pattern is available in two versions: with a Webpack or with a Rollup. I used the webpack because it is more familiar to me. Installation, launch - everything is as usual .

Set the Materialize and icons:

npm install materialize-css@next npm install material-design-icons 

Connect all this to src / main.js:
')
 import 'material-design-icons/iconfont/material-icons.css'; import 'materialize-css/dist/css/materialize.min.css'; 

Install the file-loader to handle fonts (and not only):

 npm install file-loader --save-dev 

And add the settings in webpack.config.js:

 { test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, use: [{ loader: 'file-loader', options: { name: '[name].[ext]', outputPath: 'fonts/' } }] } 


Writing a component


Create a file src / components / Buttons.html - in fact, this will be the component. In Materialize, for some reason, the buttons <a> are used for buttons, therefore, for semanticity, it was decided to make two types of buttons: <button> - if there is no link, and <a> - if there is a link.

We write two templates:

 {#if href} //     <a on:click class="{classes}" {href} {title} > {#if icon} //     <i class="material-icons {iconAlign}">{icon}</i> {/if} <slot>button</slot> </a> {:else} <button on:click class="{classes}" {type} {name} {disabled} > {#if icon} <i class="material-icons {iconAlign}">{icon}</i> {/if} <slot>button</slot> </button> {/if} 

Here {classes} is a list of classes, {href}, {title}, {type}, {name}, {disabled} are the corresponding attributes, and {iconAlign} and {icon} are the position and name of the icon. Attributes can be added and others (there, mostly, exotic remained), but for example this should be enough.

And on: click add, then to catch clicks on the buttons. An example will be below.

Further, in the section <script> we describe the data by default and the addition of classes (computed):

  export default { data() { return { color: '', size: '', iconAlign: 'left', floating: false, flat: false, waves: false, wavesColor: 'light', icon: '', //   type: '',//    href: '', name: '', disabled: false, title: '' }; }, computed: { //     classes: ({ //  ,      color, size, floating, flat, disabled, waves, wavesColor }) => { const classes = []; flat ? classes.push(`btn-flat`) : classes.push(`btn`); floating && classes.push(`btn-floating`); disabled && classes.push(`disabled`); waves && classes.push(`waves-effect`); wavesColor && classes.push(`waves-${wavesColor}`); size && classes.push(`btn-${size}`); color && classes.push(`${color}`); return classes.join(' '); } } }; 

In the data () section, we describe the default data, and in computed , an array of classes is populated based on the properties that we will pass when the button is called. And when you change these properties, everything is automatically recalculated. P - reactivity.

Actually, the component is ready. In src / App.html we connect it:

 <script> import Button from './components/Buttons.html'; export default { components: { Button } }; </script> 


We collect / call buttons



  <Button waves></Button> <Button waves icon="cloud" iconAlign="left"></Button> <Button floating waves size="large" color="red" icon="add"></Button> 



Or links:

  <Button href="#foo" waves> Link_0 </Button> <Button href="#bar" waves icon="cloud"> Link_1 </Button> <Button href="#qux" waves flat> Link_2 </Button> <Button href="#baz" waves icon="cloud" iconAlign="right"> Link_3 </Button> <Button href="#foo" waves floating size="large" color="red" icon="add" /> 



Events: catch click


Using on: click, you can catch clicks on the button, for example:

 <Button on:click="set({ count: count + 1 })" waves>Button++</Button> <Button on:click="set({ count: count - 1 })" waves icon="cloud" iconAlign="left">Button--</Button> 

To do this, you need to add the code in the export default:

 data() { return { count: 3 }; }, 

And somewhere this counter to display:

 <p>Count: {count}</p> 

GitHub code and demo .

Method two: REPL - easier and faster


The framework site has a cool sandbox - REPL, in which there are already a few dozen examples. And there you can fork the ready code, add / write something of your own and share.
For example, the above component there looks like this .

Source: https://habr.com/ru/post/418679/


All Articles