#tilos archives
Explore tagged Tumblr posts
Text
youtube
Cadik - d'n'b, aztán Odin nu-school, minimal és a vége valszeg Palotai. Valszeg 1999-ből.
#odin#palotai#tilos archive#tilos archives#tape recording#tilos radio#tilos#casette#tape#minimal#d&b#dnb#Youtube#Cadik
9 notes
·
View notes
Text
youtube
Ντοκιμαντέρ του Παναγιώτη Ευαγγελίδη για τους πρώτους ομόφυλους γάμους στην Ελλάδα, που τελέστηκαν στην Τήλο το 2008 από ακτιβιστές της ΟΛΚΕ.
#προτείνω!!!#είναι footage που τράβαγε ο σκηνοθέτης από τους φίλους του εκείνες τις μέρες του ‘08#και το ξέθαψε το 2020#something something personal archives of historical moments in queer history#είχα την τιμή να είμαι παρόν σε μία προβολή πρόσφατα που συζητήσαμε τη σημασία των αρχείων με τον σκηνοθέτη. και το πόσα έχουν χαθεί#από γενιά σε γενιά γιατί δεν είχαν καταγραφτεί#lgbt greece#greek tumblr#marriage equality#tilos weddings#οι γάμοι της τήλου
39 notes
·
View notes
Text
Na egy régi barát kérésére a régi tilos felvételekbol elkezdtem feltøltøgetni, nem tudom, hogy meddig bírom majd cérnával.. de a téma egy tematikus blog után kiált: @tilos-archives
46 notes
·
View notes
Photo
King Constantine of Greece and his wife Anne Marie, who is wearing a traditional local costume from Tilos island, Dodecanese, visiting the Dodecanese Islands, October 19th 1965. (Photo by Keystone/Hulton Archive/Getty Images)
#greece#europe#greek royals#european royalty#traditional clothing#historical fashion#folk dress#traditional dress#folk clothing#greek people#greek royal family#anne-marie of the hellenes#ex king Constantine ii of Greece#tilos#dodecanese#greek islands
55 notes
·
View notes
Note
I read your fanfiction, but through a translator, you have really interesting headcanons, I love it. and I also really love Snorl, haha. Do you have any hc about him? I'm interested in your point of view!
oooh haha
° actually Snorl is quite soft and helpful, just swears a lot
° and knows muridean language, not very well, but most local rats know (hello-goodbye-please-fuck off)
° he likes to work with ouma Rezzia in the kitchen (because of apples and warmth)
° actually Snorl KNEW that he must open Tilo's door and leave it opened, because Silas asked him to help this minstrel
° lol okay, Silas had to give him some money, so that he agrees
° but Silas didn't ask him to hide green apple for minstrel in small cage, Snorl did this JUST because of great lulz
° I wrote this too, yesss
1 note
·
View note
Text
i need to listen to more radio acktually tilos is right in my browser w a million archives too...
1 note
·
View note
Text
Japan-funded water project benefits 300 families in SoCot village
#PHnews: Japan-funded water project benefits 300 families in SoCot village
GENERAL SANTOS CITY – Around 300 families from three sitios in Tupi, South Cotabato will soon enjoy a stable supply of potable water, with the completion of a PHP4.25-million water system project funded by the government of Japan.
Kenelynn Ariño, project development officer of the South Cotabato Provincial Planning and Development Office, said Friday the project is now about 99-percent complete and readied for turnover to the beneficiaries.
She said the project, which was commissioned by the Embassy of Japan through the provincial government in early 2019, will mainly benefit residents of sitios Taluban, Tukaycalon, and Latil in Barangay Kablon.
The local government made sure that the original plan of the project was followed and any alteration to the scheme was referred to the Embassy of Japan, she said.
A project briefer said the Level II Water Supply System was built through a counterpart scheme between the Embassy of Japan and the provincial government of South Cotabato.
It was funded under Japan’s Grant Assistance for Grassroots Human Security Projects, which support small-scale projects that directly benefit the grassroots level and contribute to socio-economic development.
Casimero Padilla Jr., lower valley area chief of the Provincial Engineering Office, said the project’s construction initially faced challenges over the road right-of-way for the piping but the residents eventually relented.
He said some pipelines turned out not suitable for embedding but were eventually corrected to prevent possible illegal tapping.
Osting Tilo Jr., chairman of Barangay Kablon, said the completion and upcoming operationalization of the water supply system is a realization of a long-time dream for the area’s residents.
Local residents have long been drawing water supply for their daily needs from spring water resources and water systems in neighboring sitios.
He thanked the Embassy of Japan and the provincial government for choosing their barangay as a recipient of the project.
“Our people in the three sitios will finally enjoy having clean water and stable supply that they longed for,” he said.
Tilo assured that the barangay council will properly manage the new water system to ensure that it will last long. (PNA)
***
References:
* Philippine News Agency. "Japan-funded water project benefits 300 families in SoCot village." Philippine News Agency. https://www.pna.gov.ph/articles/1119488 (accessed October 23, 2020 at 09:11PM UTC+14).
* Philippine News Agency. "Japan-funded water project benefits 300 families in SoCot village." Archive Today. https://archive.ph/?run=1&url=https://www.pna.gov.ph/articles/1119488 (archived).
0 notes
Text
For the Love of the MP5: Roller-Locked 9mm Clones
The PTR 9KT, a semi-auto send-up of the HK MP5K. What’s not to love? (Photo: Chris Eger/Guns.com)
The Heckler & Koch MP5 is a thing of enduring beauty but their rarity on the consumer market has left a void quickly filled by dozens of clones.
Developed in the 1960s as HKs Maschinenpistole 5 by a team led by Tilo Möller, the team essentially started with the company’s proven G3 battle rifle and, in many ways, just downsized the 9-pound 7.62x51mm weapon to a much smaller 5.5-pound, creating a 9x19mm chambered squirt gun.
Both guns share the same basic roller-delayed blowback action. The roller lock design, invented by Dr. Werner Gruner and used in WWII on the very successful MG42 machine gun, creates a durable and effective lock-up that is as efficient as it is reliable. The blowback action fundamentally treats the cartridge case itself like a piston to work the closed bolt, with the gas of the recoil being transferred through a fluted chamber.
A staple of military special ops types and counter-terror teams for decades, the MP5 today evokes the same sort of old-school cool common in Cold War-era SEAL teams.
SEAL Team 8 wielding the iconic H&K MP5 submachine gun in 1991 (Photo: U.S. Navy via National Archives)
Although a few pre-1986 transferrable select-fire MP5s are floating around, and others are hopefully headed to the market as LE teams are increasingly replacing their HK room brooms with M4-ish guns, their cost is upwards of $25K — not including stamps. Semi-auto variants produced by the German gunmaker — the SP89, and the SP5 — are more affordable but almost as rarely encountered at affordable prices. This opens the field for clones.
PTR
South Carolina-based PTR has continued to expand their MP5-style offerings in recent years by introducing the very handy 9KT earlier this year.
youtube
SEE AT GUNS.COM FROM $1,681
The American-manufactured semi-auto pistol is an NFA-compliant version of the classic HK MP5K (Kurz = short), a storied SMG that was a favorite of various international balaclava-clad SF types in the Tom Clancy-era. Announced just prior to SHOT Show 2019, the 9KT runs just 13.38-inches overall, largely due to the 5.16-inch, three-lug barrel.
The company splashed into the MP5 clone market in 2018 with the 9C series pistol and 9R series rifle.
The 9C sports an M-LOK compatible aluminum handguard and 8.86-inch 3-lug barrel with push-button and paddle-style magazine release while the rifle has a stock and a 16.2-inch barrel. (Photo: Chris Eger/Guns.com)
SEE AT GUNS.COM FROM $1,681
Zenith
Zenith markets over a dozen ZP5 series pistols and rifles (Photo: Chris Eger/Guns.com)
SEE AT GUNS.COM FROM $1.999
Located in Virginia, Zenith Firearms imports a wide array of roller-locked designs produced in Turkey by MKE-K, a company set up in cooperation with HK decades ago to make such guns for the Turkish military. One of their cooler new offerings is the Z-5RS, a braced pistol with an 8.9-inch barrel and a classic style forearm and the Z-5RS SBM4 which sports a Picatinny rail and slimline forearm.
Our very own Chase Welch recently reviewed another one of Zenith’s pistols, the Z-5P.
youtube
Other makers
Besides PTR and Zenith, who account for a huge market share when it comes to MP5 clones, there are a host of smaller shops that specialize in the platform. These include Pennsylvania’s Black Ops Defense, Brethren Arms in Utah, Dakota Tactical in Michigan, and TPM Outfitters in the Lone Star State. Like the MKE-K guns brought in by Zenith, the Pakistani Ordnance Factory (POF) ships semi-auto MP5ish clones to the states which are brought in by several importers. Finally, Palmetto State Armory has been promising their own domestically made model for the past couple years, so that is on the horizon.
And of course, HK still makes them for the LE and military market, the restriction in place due to the Hughes Amendment. In short, the platform that its original maker describes as “the most popular series of submachine guns in the world,” has a lot of life left in it.
The post For the Love of the MP5: Roller-Locked 9mm Clones appeared first on Guns.com.
from Guns.com https://ift.tt/2Z4uEyO from Blogger https://ift.tt/2YXD4bf
0 notes
Text
Tilos Rádió -
Index a Csonkamagyarországban :)
0 notes
Text
youtube
1 note
·
View note
Text
Building Reusable React Components Using Tailwind
About The Author
Tilo Mitra studied Engineering at the University of Waterloo. He is an Engineering Manager and a Software Engineer. He’s been writing in JavaScript … More about Tilo …
Tailwind is a popular utility-first CSS framework that provides low-level class names to web developers. It does not have any JavaScript and works well with existing frameworks such as React, Vue, Angular, Ember, and others. Whilst this is positive, it can be confusing for new developers to understand how to integrate Tailwind in their applications. In this article, we’ll explore ways to build reusable React components using Tailwind.
In this post, we’ll look at several different ways you can build reusable React components that leverage Tailwind under the hood while exposing a nice interface to other components. This will improve your code by moving from long lists of class names to semantic props that are easier to read and maintain.
You will need to have worked with React in order to get a good understanding of this post.
Tailwind is a very popular CSS framework that provides low-level utility classes to help developers build custom designs. It’s grown in popularity over the last few years because it solves two problems really well:
Tailwind makes it easy to make iterative changes to HTML without digging through stylesheets to find matching CSS selectors.
Tailwind has sane conventions and defaults. This makes it easy for people to get started without writing CSS from scratch.
Add the comprehensive documentation and it’s no surprise why Tailwind is so popular.
These methods will help you transform code that looks like this:
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Enable</button>
To code that looks like this:
<Button size="sm" textColor="white" bgColor="blue-500"> Enable</Button>
The difference between both snippets is that in the first we made use of a standard HTML button tag, while the second used a <Button> component. The <Button> component had been built for reusability and is easier to read since it has better semantics. Instead of a long list of class names, it uses properties to set various attributes such as size, textColor, and bgColor.
Let’s get started.
Method 1: Controlling Classes With The Classnames Module
A simple way to adapt Tailwind into a React application is to embrace the class names and toggle them programmatically.
The classnames npm module makes it easy to toggle classes in React. To demonstrate how you may use this, let’s take a use case where you have <Button> components in your React application.
// This could be hard to read.<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Enable</button> // This is more conventional React.<Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Let’s see how to separate Tailwind classes so people using this <Button> component can use React props such as size, textColor, and bgColor.
Pass props such as bgColor and textColor directly into the class name string template.
Use objects to programmatically switch class names (as we have done with the size prop)
In the example code below, we’ll take a look at both approaches.
// Button.jsximport classnames from 'classnames'; function Button ({size, bgColor, textColor, children}) { return ( <button className={classnames("bg-${bgColor} text-${textColor} font-bold py-2 px-4 rounded", { "text-xs": size === 'sm' "text-xl": size === 'lg', })}> {children} </button> )}; export default Button;
In the code above, we define a Button component that takes the following props:
size Defines the size of the button and applies the Tailwind classes text-xs or text-xl
bgColor Defines the background color of the button and applies the Tailwind bg-* classes.
textColor Defines the text color of the button and applies the Tailwind text-* classes.
children Any subcomponents will be passed through here. It will usually contain the text within the <Button>.
By defining Button.jsx, we can now import it in and use React props instead of class names. This makes our code easier to read and reuse.
import Button from './Button';<Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Using Class Names For Interactive Components
A Button is a very simple use-case. What about something more complicated? Well, you can take this further to make interactive components.
For example, let’s look at a dropdown that is made using Tailwind.
Your browser does not support the video tag.
An interactive dropdown built using Tailwind and class name toggling.
For this example, we create the HTML component using Tailwind CSS classnames but we expose a React component that looks like this:
<Dropdown options={\["Edit", "Duplicate", "Archive", "Move", "Delete"\]} onOptionSelect={(option) => { console.log("Selected Option", option)} } />
Looking at the code above, you’ll notice that we don’t have any Tailwind classes. They are all hidden inside the implementation code of <Dropdown/>. The user of this Dropdown component just has to provide a list of options and a click handler, onOptionSelect when an option is clicked.
Let’s see how this component can be built using Tailwind.
Removing some of the unrelated code, here’s the crUX of the logic. You can view this Codepen for a complete example.
import classNames from 'classnames'; function Dropdown({ options, onOptionSelect }) { // Keep track of whether the dropdown is open or not. const [isActive, setActive] = useState(false); const buttonClasses = `inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-blue-500 active:text-gray-200 transition ease-in-out duration-150`; return ( // Toggle the dropdown if the button is clicked <button onClick={() => setActive(!isActive)} className={buttonClasses}> Options </button> // Use the classnames module to toggle the Tailwind .block and .hidden classes <div class={classNames("origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg", { block: isActive, hidden: !isActive })}> // List items are rendered here. {options.map((option) => <div key={option} onClick={(e) => onOptionSelect(option)}>{option}</div>)} </div> )} export default Dropdown;
The dropdown is made interactive by selectively showing or hiding it using the .hidden and .block classes. Whenever the <button> is pressed, we fire the onClick handler that toggles the isActive state. If the button is active (isActive === true), we set the block class. Otherwise, we set the hidden class. These are both Tailwind classes for toggling display behavior.
In summary, the classnames module is a simple and effective way to programmatically control class names for Tailwind. It makes it easier to separate logic into React props, which makes your components easier to reuse. It works for simple and interactive components.
Method 2: Using Constants To Define A Design System
Another way of using Tailwind and React together is by using constants and mapping props to a specific constant. This is effective for building design systems. Let’s demonstrate with an example.
Start with a theme.js file where you list out your design system.
// theme.js (you can call it whatever you want)export const ButtonType = { primary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", secondary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", basic: "bg-white hover:bg-gray-700 text-gray-700 font-bold rounded", delete: "bg-red-300 hover:bg-red-500 text-white font-bold rounded"}; export const ButtonSize = { sm: "py-2 px-4 text-xs", lg: "py-3 px-6 text-lg"}
In this case, we have two sets of constants:
ButtonType defines how buttons are styled in our app.
ButtonSizes defines the sizes of buttons in our app.
Now, let’s write our <Button> component:
import {ButtonType, ButtonSize} from './theme'; function Button({size, type, children}) { // This can be improved. I’m keeping it simple here by joining two strings. const classNames = ButtonType[type] + " " + ButtonSize[size]; return ( <button className={classNames}>{children}</button> )}export default Button;
We use the ButtonType and ButtonSize constants to create a list of class names. This makes the interface of our <Button> much nicer. It lets us use size and type props instead of putting everything in a class name string.
// Cleaner and well defined props.<Button size="xs" type="primary">Enable</Button>
Versus the prior approach:
// Exposing class names<button className="py-2 px-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Enable</button>
If you need to redefine how buttons look in your application, just edit the theme.js file and all buttons in your app will automatically update. This can be easier than searching for class names in various components.
Method 3: Composing Utilities With @apply
A third way to improve the legibility of your React components is using CSS and the @apply pattern available in PostCSS to extract repeated classes. This pattern involves using stylesheets and post-processors.
Let’s demonstrate how this works through an example. Suppose you have a Button group that has a Primary and a Secondary Button.
A Button Group consisting of a primary and secondary button. (Large preview)
<button className="py-2 px-4 mr-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Update Now</button> <button className="py-2 px-4 text-xs mr-4 hover:bg-gray-100 text-gray-700 border-gray-300 border font-bold rounded">Later</button>
Using the @apply pattern, you can write this HTML as:
<button className="btn btn-primary btn-xs">Update Now</button><button className="btn btn-secondary btn-xs">Later</button>
Which can then be adopted to React to become:
import classnames from "classnames"; function Button ({size, type, children}) { const bSize = "btn-" + size; const bType = "btn-" + type; return ( <button className={classnames("btn", bSize, bType)}>{children}</button> )} Button.propTypes = { size: PropTypes.oneOf(['xs, xl']), type: PropTypes.oneOf(['primary', 'secondary'])}; // Using the Button component.<Button type="primary" size="xs">Update Now</Button><Button type="secondary" size="xs">Later</Button>
Here’s how you would create these BEM-style classnames such as .btn, .btn-primary, and others. Start by creating a button.css file:
/\* button.css \*/ @tailwind base;@tailwind components; .btn { @apply py-2 px-4 mr-4 font-bold rounded;}.btn-primary { @apply bg-blue-500 hover:bg-blue-700 text-white;}.btn-secondary { @apply hover:bg-gray-700 text-gray-700 border-gray-300 border;}.btn-xs { @apply text-xs;}.btn-xl { @apply text-xl;} @tailwind utilities;
The code above isn’t real CSS but it will get compiled by PostCSS. There’s a GitHub repository available here which shows how to setup PostCSS and Tailwind for a JavaScript project.
There’s also a short video that demonstrates how to set it up here.
Disadvantages Of Using @apply
The concept of extracting Tailwind utility classes into higher-level CSS classes seems like it makes sense, but it has some disadvantages which you should be aware of. Let’s highlight these with another example.
First, by extracting these class names out, we lose some information. For example, we need to be aware that .btn-primary has to be added to a component that already has .btn applied to it. Also, .btn-primary and .btn-secondary can’t be applied together. This information is not evident by just looking at the classes.
If this component was something more complicated, you would also need to understand the parent-child relationship between the classes. In a way, this is the problem that Tailwind was designed to solve, and by using @apply, we are bringing the problems back, in a different way.
Here’s a video where Adam Wathan — the creator of Tailwind — dives into the pros and cons of using @apply.
Summary
In this article, we looked at three ways that you can integrate Tailwind into a React application to build reusable components. These methods help you to build React components that have a cleaner interface using props.
Use the classnames module to programmatically toggle classes.
Define a constants file where you define a list of classes per component state.
Use @apply to extract higher-level CSS classes.
If you have any questions, send me a message on Twitter at @tilomitra.
Recommended Reading on SmashingMag:
(ks, ra, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
Via http://www.scpie.org/building-reusable-react-components-using-tailwind/
source https://scpie.weebly.com/blog/building-reusable-react-components-using-tailwind
0 notes
Text
Building Reusable React Components Using Tailwind
About The Author
Tilo Mitra studied Engineering at the University of Waterloo. He is an Engineering Manager and a Software Engineer. He’s been writing in JavaScript … More about Tilo …
Tailwind is a popular utility-first CSS framework that provides low-level class names to web developers. It does not have any JavaScript and works well with existing frameworks such as React, Vue, Angular, Ember, and others. Whilst this is positive, it can be confusing for new developers to understand how to integrate Tailwind in their applications. In this article, we’ll explore ways to build reusable React components using Tailwind.
In this post, we’ll look at several different ways you can build reusable React components that leverage Tailwind under the hood while exposing a nice interface to other components. This will improve your code by moving from long lists of class names to semantic props that are easier to read and maintain.
You will need to have worked with React in order to get a good understanding of this post.
Tailwind is a very popular CSS framework that provides low-level utility classes to help developers build custom designs. It’s grown in popularity over the last few years because it solves two problems really well:
Tailwind makes it easy to make iterative changes to HTML without digging through stylesheets to find matching CSS selectors.
Tailwind has sane conventions and defaults. This makes it easy for people to get started without writing CSS from scratch.
Add the comprehensive documentation and it’s no surprise why Tailwind is so popular.
These methods will help you transform code that looks like this:
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Enable </button>
To code that looks like this:
<Button size="sm" textColor="white" bgColor="blue-500"> Enable </Button>
The difference between both snippets is that in the first we made use of a standard HTML button tag, while the second used a <Button> component. The <Button> component had been built for reusability and is easier to read since it has better semantics. Instead of a long list of class names, it uses properties to set various attributes such as size, textColor, and bgColor.
Let’s get started.
Method 1: Controlling Classes With The Classnames Module
A simple way to adapt Tailwind into a React application is to embrace the class names and toggle them programmatically.
The classnames npm module makes it easy to toggle classes in React. To demonstrate how you may use this, let’s take a use case where you have <Button> components in your React application.
// This could be hard to read. <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Enable</button> // This is more conventional React. <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Let’s see how to separate Tailwind classes so people using this <Button> component can use React props such as size, textColor, and bgColor.
Pass props such as bgColor and textColor directly into the class name string template.
Use objects to programmatically switch class names (as we have done with the size prop)
In the example code below, we’ll take a look at both approaches.
// Button.jsx import classnames from 'classnames'; function Button ({size, bgColor, textColor, children}) { return ( <button className={classnames("bg-${bgColor} text-${textColor} font-bold py-2 px-4 rounded", { "text-xs": size === 'sm' "text-xl": size === 'lg', })}> {children} </button> ) }; export default Button;
In the code above, we define a Button component that takes the following props:
size Defines the size of the button and applies the Tailwind classes text-xs or text-xl
bgColor Defines the background color of the button and applies the Tailwind bg-* classes.
textColor Defines the text color of the button and applies the Tailwind text-* classes.
children Any subcomponents will be passed through here. It will usually contain the text within the <Button>.
By defining Button.jsx, we can now import it in and use React props instead of class names. This makes our code easier to read and reuse.
import Button from './Button'; <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Using Class Names For Interactive Components
A Button is a very simple use-case. What about something more complicated? Well, you can take this further to make interactive components.
For example, let’s look at a dropdown that is made using Tailwind.
Your browser does not support the video tag.
An interactive dropdown built using Tailwind and class name toggling.
For this example, we create the HTML component using Tailwind CSS classnames but we expose a React component that looks like this:
<Dropdown options={\["Edit", "Duplicate", "Archive", "Move", "Delete"\]} onOptionSelect={(option) => { console.log("Selected Option", option)} } />
Looking at the code above, you’ll notice that we don’t have any Tailwind classes. They are all hidden inside the implementation code of <Dropdown/>. The user of this Dropdown component just has to provide a list of options and a click handler, onOptionSelect when an option is clicked.
Let’s see how this component can be built using Tailwind.
Removing some of the unrelated code, here’s the crUX of the logic. You can view this Codepen for a complete example.
import classNames from 'classnames'; function Dropdown({ options, onOptionSelect }) { // Keep track of whether the dropdown is open or not. const [isActive, setActive] = useState(false); const buttonClasses = `inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-blue-500 active:text-gray-200 transition ease-in-out duration-150`; return ( // Toggle the dropdown if the button is clicked <button onClick={() => setActive(!isActive)} className={buttonClasses}> Options </button> // Use the classnames module to toggle the Tailwind .block and .hidden classes <div class={classNames("origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg", { block: isActive, hidden: !isActive })}> // List items are rendered here. {options.map((option) => <div key={option} onClick={(e) => onOptionSelect(option)}>{option}</div>)} </div> ) } export default Dropdown;
The dropdown is made interactive by selectively showing or hiding it using the .hidden and .block classes. Whenever the <button> is pressed, we fire the onClick handler that toggles the isActive state. If the button is active (isActive === true), we set the block class. Otherwise, we set the hidden class. These are both Tailwind classes for toggling display behavior.
In summary, the classnames module is a simple and effective way to programmatically control class names for Tailwind. It makes it easier to separate logic into React props, which makes your components easier to reuse. It works for simple and interactive components.
Method 2: Using Constants To Define A Design System
Another way of using Tailwind and React together is by using constants and mapping props to a specific constant. This is effective for building design systems. Let’s demonstrate with an example.
Start with a theme.js file where you list out your design system.
// theme.js (you can call it whatever you want) export const ButtonType = { primary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", secondary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", basic: "bg-white hover:bg-gray-700 text-gray-700 font-bold rounded", delete: "bg-red-300 hover:bg-red-500 text-white font-bold rounded" }; export const ButtonSize = { sm: "py-2 px-4 text-xs", lg: "py-3 px-6 text-lg" }
In this case, we have two sets of constants:
ButtonType defines how buttons are styled in our app.
ButtonSizes defines the sizes of buttons in our app.
Now, let’s write our <Button> component:
import {ButtonType, ButtonSize} from './theme'; function Button({size, type, children}) { // This can be improved. I’m keeping it simple here by joining two strings. const classNames = ButtonType[type] + " " + ButtonSize[size]; return ( <button className={classNames}>{children}</button> ) } export default Button;
We use the ButtonType and ButtonSize constants to create a list of class names. This makes the interface of our <Button> much nicer. It lets us use size and type props instead of putting everything in a class name string.
// Cleaner and well defined props. <Button size="xs" type="primary">Enable</Button>
Versus the prior approach:
// Exposing class names <button className="py-2 px-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Enable</button>
If you need to redefine how buttons look in your application, just edit the theme.js file and all buttons in your app will automatically update. This can be easier than searching for class names in various components.
Method 3: Composing Utilities With @apply
A third way to improve the legibility of your React components is using CSS and the @apply pattern available in PostCSS to extract repeated classes. This pattern involves using stylesheets and post-processors.
Let’s demonstrate how this works through an example. Suppose you have a Button group that has a Primary and a Secondary Button.
A Button Group consisting of a primary and secondary button. (Large preview)
<button className="py-2 px-4 mr-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Update Now</button> <button className="py-2 px-4 text-xs mr-4 hover:bg-gray-100 text-gray-700 border-gray-300 border font-bold rounded">Later</button>
Using the @apply pattern, you can write this HTML as:
<button className="btn btn-primary btn-xs">Update Now</button> <button className="btn btn-secondary btn-xs">Later</button>
Which can then be adopted to React to become:
import classnames from "classnames"; function Button ({size, type, children}) { const bSize = "btn-" + size; const bType = "btn-" + type; return ( <button className={classnames("btn", bSize, bType)}>{children}</button> ) } Button.propTypes = { size: PropTypes.oneOf(['xs, xl']), type: PropTypes.oneOf(['primary', 'secondary']) }; // Using the Button component. <Button type="primary" size="xs">Update Now</Button> <Button type="secondary" size="xs">Later</Button>
Here’s how you would create these BEM-style classnames such as .btn, .btn-primary, and others. Start by creating a button.css file:
/\* button.css \*/ @tailwind base; @tailwind components; .btn { @apply py-2 px-4 mr-4 font-bold rounded; } .btn-primary { @apply bg-blue-500 hover:bg-blue-700 text-white; } .btn-secondary { @apply hover:bg-gray-700 text-gray-700 border-gray-300 border; } .btn-xs { @apply text-xs; } .btn-xl { @apply text-xl; } @tailwind utilities;
The code above isn’t real CSS but it will get compiled by PostCSS. There’s a GitHub repository available here which shows how to setup PostCSS and Tailwind for a JavaScript project.
There’s also a short video that demonstrates how to set it up here.
Disadvantages Of Using @apply
The concept of extracting Tailwind utility classes into higher-level CSS classes seems like it makes sense, but it has some disadvantages which you should be aware of. Let’s highlight these with another example.
First, by extracting these class names out, we lose some information. For example, we need to be aware that .btn-primary has to be added to a component that already has .btn applied to it. Also, .btn-primary and .btn-secondary can’t be applied together. This information is not evident by just looking at the classes.
If this component was something more complicated, you would also need to understand the parent-child relationship between the classes. In a way, this is the problem that Tailwind was designed to solve, and by using @apply, we are bringing the problems back, in a different way.
Here’s a video where Adam Wathan — the creator of Tailwind — dives into the pros and cons of using @apply.
Summary
In this article, we looked at three ways that you can integrate Tailwind into a React application to build reusable components. These methods help you to build React components that have a cleaner interface using props.
Use the classnames module to programmatically toggle classes.
Define a constants file where you define a list of classes per component state.
Use @apply to extract higher-level CSS classes.
If you have any questions, send me a message on Twitter at @tilomitra.
Recommended Reading on SmashingMag:
(ks, ra, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/building-reusable-react-components-using-tailwind/ source https://scpie1.blogspot.com/2020/05/building-reusable-react-components.html
0 notes
Text
Building Reusable React Components Using Tailwind
About The Author
Tilo Mitra studied Engineering at the University of Waterloo. He is an Engineering Manager and a Software Engineer. He’s been writing in JavaScript … More about Tilo …
Tailwind is a popular utility-first CSS framework that provides low-level class names to web developers. It does not have any JavaScript and works well with existing frameworks such as React, Vue, Angular, Ember, and others. Whilst this is positive, it can be confusing for new developers to understand how to integrate Tailwind in their applications. In this article, we’ll explore ways to build reusable React components using Tailwind.
In this post, we’ll look at several different ways you can build reusable React components that leverage Tailwind under the hood while exposing a nice interface to other components. This will improve your code by moving from long lists of class names to semantic props that are easier to read and maintain.
You will need to have worked with React in order to get a good understanding of this post.
Tailwind is a very popular CSS framework that provides low-level utility classes to help developers build custom designs. It’s grown in popularity over the last few years because it solves two problems really well:
Tailwind makes it easy to make iterative changes to HTML without digging through stylesheets to find matching CSS selectors.
Tailwind has sane conventions and defaults. This makes it easy for people to get started without writing CSS from scratch.
Add the comprehensive documentation and it’s no surprise why Tailwind is so popular.
These methods will help you transform code that looks like this:
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Enable </button>
To code that looks like this:
<Button size="sm" textColor="white" bgColor="blue-500"> Enable </Button>
The difference between both snippets is that in the first we made use of a standard HTML button tag, while the second used a <Button> component. The <Button> component had been built for reusability and is easier to read since it has better semantics. Instead of a long list of class names, it uses properties to set various attributes such as size, textColor, and bgColor.
Let’s get started.
Method 1: Controlling Classes With The Classnames Module
A simple way to adapt Tailwind into a React application is to embrace the class names and toggle them programmatically.
The classnames npm module makes it easy to toggle classes in React. To demonstrate how you may use this, let’s take a use case where you have <Button> components in your React application.
// This could be hard to read. <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Enable</button> // This is more conventional React. <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Let’s see how to separate Tailwind classes so people using this <Button> component can use React props such as size, textColor, and bgColor.
Pass props such as bgColor and textColor directly into the class name string template.
Use objects to programmatically switch class names (as we have done with the size prop)
In the example code below, we’ll take a look at both approaches.
// Button.jsx import classnames from 'classnames'; function Button ({size, bgColor, textColor, children}) { return ( <button className={classnames("bg-${bgColor} text-${textColor} font-bold py-2 px-4 rounded", { "text-xs": size === 'sm' "text-xl": size === 'lg', })}> {children} </button> ) }; export default Button;
In the code above, we define a Button component that takes the following props:
size Defines the size of the button and applies the Tailwind classes text-xs or text-xl
bgColor Defines the background color of the button and applies the Tailwind bg-* classes.
textColor Defines the text color of the button and applies the Tailwind text-* classes.
children Any subcomponents will be passed through here. It will usually contain the text within the <Button>.
By defining Button.jsx, we can now import it in and use React props instead of class names. This makes our code easier to read and reuse.
import Button from './Button'; <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Using Class Names For Interactive Components
A Button is a very simple use-case. What about something more complicated? Well, you can take this further to make interactive components.
For example, let’s look at a dropdown that is made using Tailwind.
Your browser does not support the video tag.
An interactive dropdown built using Tailwind and class name toggling.
For this example, we create the HTML component using Tailwind CSS classnames but we expose a React component that looks like this:
<Dropdown options={\["Edit", "Duplicate", "Archive", "Move", "Delete"\]} onOptionSelect={(option) => { console.log("Selected Option", option)} } />
Looking at the code above, you’ll notice that we don’t have any Tailwind classes. They are all hidden inside the implementation code of <Dropdown/>. The user of this Dropdown component just has to provide a list of options and a click handler, onOptionSelect when an option is clicked.
Let’s see how this component can be built using Tailwind.
Removing some of the unrelated code, here’s the crUX of the logic. You can view this Codepen for a complete example.
import classNames from 'classnames'; function Dropdown({ options, onOptionSelect }) { // Keep track of whether the dropdown is open or not. const [isActive, setActive] = useState(false); const buttonClasses = `inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-blue-500 active:text-gray-200 transition ease-in-out duration-150`; return ( // Toggle the dropdown if the button is clicked <button onClick={() => setActive(!isActive)} className={buttonClasses}> Options </button> // Use the classnames module to toggle the Tailwind .block and .hidden classes <div class={classNames("origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg", { block: isActive, hidden: !isActive })}> // List items are rendered here. {options.map((option) => <div key={option} onClick={(e) => onOptionSelect(option)}>{option}</div>)} </div> ) } export default Dropdown;
The dropdown is made interactive by selectively showing or hiding it using the .hidden and .block classes. Whenever the <button> is pressed, we fire the onClick handler that toggles the isActive state. If the button is active (isActive === true), we set the block class. Otherwise, we set the hidden class. These are both Tailwind classes for toggling display behavior.
In summary, the classnames module is a simple and effective way to programmatically control class names for Tailwind. It makes it easier to separate logic into React props, which makes your components easier to reuse. It works for simple and interactive components.
Method 2: Using Constants To Define A Design System
Another way of using Tailwind and React together is by using constants and mapping props to a specific constant. This is effective for building design systems. Let’s demonstrate with an example.
Start with a theme.js file where you list out your design system.
// theme.js (you can call it whatever you want) export const ButtonType = { primary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", secondary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", basic: "bg-white hover:bg-gray-700 text-gray-700 font-bold rounded", delete: "bg-red-300 hover:bg-red-500 text-white font-bold rounded" }; export const ButtonSize = { sm: "py-2 px-4 text-xs", lg: "py-3 px-6 text-lg" }
In this case, we have two sets of constants:
ButtonType defines how buttons are styled in our app.
ButtonSizes defines the sizes of buttons in our app.
Now, let’s write our <Button> component:
import {ButtonType, ButtonSize} from './theme'; function Button({size, type, children}) { // This can be improved. I’m keeping it simple here by joining two strings. const classNames = ButtonType[type] + " " + ButtonSize[size]; return ( <button className={classNames}>{children}</button> ) } export default Button;
We use the ButtonType and ButtonSize constants to create a list of class names. This makes the interface of our <Button> much nicer. It lets us use size and type props instead of putting everything in a class name string.
// Cleaner and well defined props. <Button size="xs" type="primary">Enable</Button>
Versus the prior approach:
// Exposing class names <button className="py-2 px-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Enable</button>
If you need to redefine how buttons look in your application, just edit the theme.js file and all buttons in your app will automatically update. This can be easier than searching for class names in various components.
Method 3: Composing Utilities With @apply
A third way to improve the legibility of your React components is using CSS and the @apply pattern available in PostCSS to extract repeated classes. This pattern involves using stylesheets and post-processors.
Let’s demonstrate how this works through an example. Suppose you have a Button group that has a Primary and a Secondary Button.
A Button Group consisting of a primary and secondary button. (Large preview)
<button className="py-2 px-4 mr-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Update Now</button> <button className="py-2 px-4 text-xs mr-4 hover:bg-gray-100 text-gray-700 border-gray-300 border font-bold rounded">Later</button>
Using the @apply pattern, you can write this HTML as:
<button className="btn btn-primary btn-xs">Update Now</button> <button className="btn btn-secondary btn-xs">Later</button>
Which can then be adopted to React to become:
import classnames from "classnames"; function Button ({size, type, children}) { const bSize = "btn-" + size; const bType = "btn-" + type; return ( <button className={classnames("btn", bSize, bType)}>{children}</button> ) } Button.propTypes = { size: PropTypes.oneOf(['xs, xl']), type: PropTypes.oneOf(['primary', 'secondary']) }; // Using the Button component. <Button type="primary" size="xs">Update Now</Button> <Button type="secondary" size="xs">Later</Button>
Here’s how you would create these BEM-style classnames such as .btn, .btn-primary, and others. Start by creating a button.css file:
/\* button.css \*/ @tailwind base; @tailwind components; .btn { @apply py-2 px-4 mr-4 font-bold rounded; } .btn-primary { @apply bg-blue-500 hover:bg-blue-700 text-white; } .btn-secondary { @apply hover:bg-gray-700 text-gray-700 border-gray-300 border; } .btn-xs { @apply text-xs; } .btn-xl { @apply text-xl; } @tailwind utilities;
The code above isn’t real CSS but it will get compiled by PostCSS. There’s a GitHub repository available here which shows how to setup PostCSS and Tailwind for a JavaScript project.
There’s also a short video that demonstrates how to set it up here.
Disadvantages Of Using @apply
The concept of extracting Tailwind utility classes into higher-level CSS classes seems like it makes sense, but it has some disadvantages which you should be aware of. Let’s highlight these with another example.
First, by extracting these class names out, we lose some information. For example, we need to be aware that .btn-primary has to be added to a component that already has .btn applied to it. Also, .btn-primary and .btn-secondary can’t be applied together. This information is not evident by just looking at the classes.
If this component was something more complicated, you would also need to understand the parent-child relationship between the classes. In a way, this is the problem that Tailwind was designed to solve, and by using @apply, we are bringing the problems back, in a different way.
Here’s a video where Adam Wathan — the creator of Tailwind — dives into the pros and cons of using @apply.
Summary
In this article, we looked at three ways that you can integrate Tailwind into a React application to build reusable components. These methods help you to build React components that have a cleaner interface using props.
Use the classnames module to programmatically toggle classes.
Define a constants file where you define a list of classes per component state.
Use @apply to extract higher-level CSS classes.
If you have any questions, send me a message on Twitter at @tilomitra.
Recommended Reading on SmashingMag:
(ks, ra, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/building-reusable-react-components-using-tailwind/ source https://scpie.tumblr.com/post/619137817668452352
0 notes
Text
Building Reusable React Components Using Tailwind
About The Author
Tilo Mitra studied Engineering at the University of Waterloo. He is an Engineering Manager and a Software Engineer. He’s been writing in JavaScript … More about Tilo …
Tailwind is a popular utility-first CSS framework that provides low-level class names to web developers. It does not have any JavaScript and works well with existing frameworks such as React, Vue, Angular, Ember, and others. Whilst this is positive, it can be confusing for new developers to understand how to integrate Tailwind in their applications. In this article, we’ll explore ways to build reusable React components using Tailwind.
In this post, we’ll look at several different ways you can build reusable React components that leverage Tailwind under the hood while exposing a nice interface to other components. This will improve your code by moving from long lists of class names to semantic props that are easier to read and maintain.
You will need to have worked with React in order to get a good understanding of this post.
Tailwind is a very popular CSS framework that provides low-level utility classes to help developers build custom designs. It’s grown in popularity over the last few years because it solves two problems really well:
Tailwind makes it easy to make iterative changes to HTML without digging through stylesheets to find matching CSS selectors.
Tailwind has sane conventions and defaults. This makes it easy for people to get started without writing CSS from scratch.
Add the comprehensive documentation and it’s no surprise why Tailwind is so popular.
These methods will help you transform code that looks like this:
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Enable </button>
To code that looks like this:
<Button size="sm" textColor="white" bgColor="blue-500"> Enable </Button>
The difference between both snippets is that in the first we made use of a standard HTML button tag, while the second used a <Button> component. The <Button> component had been built for reusability and is easier to read since it has better semantics. Instead of a long list of class names, it uses properties to set various attributes such as size, textColor, and bgColor.
Let’s get started.
Method 1: Controlling Classes With The Classnames Module
A simple way to adapt Tailwind into a React application is to embrace the class names and toggle them programmatically.
The classnames npm module makes it easy to toggle classes in React. To demonstrate how you may use this, let’s take a use case where you have <Button> components in your React application.
// This could be hard to read. <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Enable</button> // This is more conventional React. <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Let’s see how to separate Tailwind classes so people using this <Button> component can use React props such as size, textColor, and bgColor.
Pass props such as bgColor and textColor directly into the class name string template.
Use objects to programmatically switch class names (as we have done with the size prop)
In the example code below, we’ll take a look at both approaches.
// Button.jsx import classnames from 'classnames'; function Button ({size, bgColor, textColor, children}) { return ( <button className={classnames("bg-${bgColor} text-${textColor} font-bold py-2 px-4 rounded", { "text-xs": size === 'sm' "text-xl": size === 'lg', })}> {children} </button> ) }; export default Button;
In the code above, we define a Button component that takes the following props:
size Defines the size of the button and applies the Tailwind classes text-xs or text-xl
bgColor Defines the background color of the button and applies the Tailwind bg-* classes.
textColor Defines the text color of the button and applies the Tailwind text-* classes.
children Any subcomponents will be passed through here. It will usually contain the text within the <Button>.
By defining Button.jsx, we can now import it in and use React props instead of class names. This makes our code easier to read and reuse.
import Button from './Button'; <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Using Class Names For Interactive Components
A Button is a very simple use-case. What about something more complicated? Well, you can take this further to make interactive components.
For example, let’s look at a dropdown that is made using Tailwind.
Your browser does not support the video tag.
An interactive dropdown built using Tailwind and class name toggling.
For this example, we create the HTML component using Tailwind CSS classnames but we expose a React component that looks like this:
<Dropdown options={\["Edit", "Duplicate", "Archive", "Move", "Delete"\]} onOptionSelect={(option) => { console.log("Selected Option", option)} } />
Looking at the code above, you’ll notice that we don’t have any Tailwind classes. They are all hidden inside the implementation code of <Dropdown/>. The user of this Dropdown component just has to provide a list of options and a click handler, onOptionSelect when an option is clicked.
Let’s see how this component can be built using Tailwind.
Removing some of the unrelated code, here’s the crUX of the logic. You can view this Codepen for a complete example.
import classNames from 'classnames'; function Dropdown({ options, onOptionSelect }) { // Keep track of whether the dropdown is open or not. const [isActive, setActive] = useState(false); const buttonClasses = `inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-blue-500 active:text-gray-200 transition ease-in-out duration-150`; return ( // Toggle the dropdown if the button is clicked <button onClick={() => setActive(!isActive)} className={buttonClasses}> Options </button> // Use the classnames module to toggle the Tailwind .block and .hidden classes <div class={classNames("origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg", { block: isActive, hidden: !isActive })}> // List items are rendered here. {options.map((option) => <div key={option} onClick={(e) => onOptionSelect(option)}>{option}</div>)} </div> ) } export default Dropdown;
The dropdown is made interactive by selectively showing or hiding it using the .hidden and .block classes. Whenever the <button> is pressed, we fire the onClick handler that toggles the isActive state. If the button is active (isActive === true), we set the block class. Otherwise, we set the hidden class. These are both Tailwind classes for toggling display behavior.
In summary, the classnames module is a simple and effective way to programmatically control class names for Tailwind. It makes it easier to separate logic into React props, which makes your components easier to reuse. It works for simple and interactive components.
Method 2: Using Constants To Define A Design System
Another way of using Tailwind and React together is by using constants and mapping props to a specific constant. This is effective for building design systems. Let’s demonstrate with an example.
Start with a theme.js file where you list out your design system.
// theme.js (you can call it whatever you want) export const ButtonType = { primary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", secondary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", basic: "bg-white hover:bg-gray-700 text-gray-700 font-bold rounded", delete: "bg-red-300 hover:bg-red-500 text-white font-bold rounded" }; export const ButtonSize = { sm: "py-2 px-4 text-xs", lg: "py-3 px-6 text-lg" }
In this case, we have two sets of constants:
ButtonType defines how buttons are styled in our app.
ButtonSizes defines the sizes of buttons in our app.
Now, let’s write our <Button> component:
import {ButtonType, ButtonSize} from './theme'; function Button({size, type, children}) { // This can be improved. I’m keeping it simple here by joining two strings. const classNames = ButtonType[type] + " " + ButtonSize[size]; return ( <button className={classNames}>{children}</button> ) } export default Button;
We use the ButtonType and ButtonSize constants to create a list of class names. This makes the interface of our <Button> much nicer. It lets us use size and type props instead of putting everything in a class name string.
// Cleaner and well defined props. <Button size="xs" type="primary">Enable</Button>
Versus the prior approach:
// Exposing class names <button className="py-2 px-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Enable</button>
If you need to redefine how buttons look in your application, just edit the theme.js file and all buttons in your app will automatically update. This can be easier than searching for class names in various components.
Method 3: Composing Utilities With @apply
A third way to improve the legibility of your React components is using CSS and the @apply pattern available in PostCSS to extract repeated classes. This pattern involves using stylesheets and post-processors.
Let’s demonstrate how this works through an example. Suppose you have a Button group that has a Primary and a Secondary Button.
A Button Group consisting of a primary and secondary button. (Large preview)
<button className="py-2 px-4 mr-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Update Now</button> <button className="py-2 px-4 text-xs mr-4 hover:bg-gray-100 text-gray-700 border-gray-300 border font-bold rounded">Later</button>
Using the @apply pattern, you can write this HTML as:
<button className="btn btn-primary btn-xs">Update Now</button> <button className="btn btn-secondary btn-xs">Later</button>
Which can then be adopted to React to become:
import classnames from "classnames"; function Button ({size, type, children}) { const bSize = "btn-" + size; const bType = "btn-" + type; return ( <button className={classnames("btn", bSize, bType)}>{children}</button> ) } Button.propTypes = { size: PropTypes.oneOf(['xs, xl']), type: PropTypes.oneOf(['primary', 'secondary']) }; // Using the Button component. <Button type="primary" size="xs">Update Now</Button> <Button type="secondary" size="xs">Later</Button>
Here’s how you would create these BEM-style classnames such as .btn, .btn-primary, and others. Start by creating a button.css file:
/\* button.css \*/ @tailwind base; @tailwind components; .btn { @apply py-2 px-4 mr-4 font-bold rounded; } .btn-primary { @apply bg-blue-500 hover:bg-blue-700 text-white; } .btn-secondary { @apply hover:bg-gray-700 text-gray-700 border-gray-300 border; } .btn-xs { @apply text-xs; } .btn-xl { @apply text-xl; } @tailwind utilities;
The code above isn’t real CSS but it will get compiled by PostCSS. There’s a GitHub repository available here which shows how to setup PostCSS and Tailwind for a JavaScript project.
There’s also a short video that demonstrates how to set it up here.
Disadvantages Of Using @apply
The concept of extracting Tailwind utility classes into higher-level CSS classes seems like it makes sense, but it has some disadvantages which you should be aware of. Let’s highlight these with another example.
First, by extracting these class names out, we lose some information. For example, we need to be aware that .btn-primary has to be added to a component that already has .btn applied to it. Also, .btn-primary and .btn-secondary can’t be applied together. This information is not evident by just looking at the classes.
If this component was something more complicated, you would also need to understand the parent-child relationship between the classes. In a way, this is the problem that Tailwind was designed to solve, and by using @apply, we are bringing the problems back, in a different way.
Here’s a video where Adam Wathan — the creator of Tailwind — dives into the pros and cons of using @apply.
Summary
In this article, we looked at three ways that you can integrate Tailwind into a React application to build reusable components. These methods help you to build React components that have a cleaner interface using props.
Use the classnames module to programmatically toggle classes.
Define a constants file where you define a list of classes per component state.
Use @apply to extract higher-level CSS classes.
If you have any questions, send me a message on Twitter at @tilomitra.
Recommended Reading on SmashingMag:
(ks, ra, il)
Website Design & SEO Delray Beach by DBL07.co
Delray Beach SEO
source http://www.scpie.org/building-reusable-react-components-using-tailwind/
0 notes
Text
tilo
by orphan_account
...
Words: 3, Chapters: 1/1, Language: English
Fandoms: Yuri!!! on Ice (Anime)
Rating: Not Rated
Warnings: Creator Chose Not To Use Archive Warnings
Categories: M/M
Relationships: Katsuki Yuuri/Victor Nikiforov
source http://archiveofourown.org/works/18536902
0 notes
Text
Anti-insurgency task force launched in NegOr town
#PHnews: Anti-insurgency task force launched in NegOr town
DUMAGUETE CITY – The Task Force to End Local Communist Armed Conflict (TF-ELCAC) was launched in the municipality of Mabinay, Negros Oriental as more barangays have been included in the government’s efforts to end the insurgency.
Gov. Roel Degamo, represented by Capitol spokesperson and Public Information Officer (PIO) Bimbo Miraflor, during Wednesday’s launch cited the need to coordinate efforts to fight communist insurgency.
The attendees were led by Mayor Joeterry Uy and Vice Mayor Ernesto "Jango" Uy.
“We need to synergize our efforts with respective timelines to address the main issues of the insurgency problem in the province, kay nagtoo si Gov. Degamo nga kon walay kalinaw, walay klaro ug insaktong kalamboan ang atong makab-ot (because Gov. Degamo believes that development cannot be attained in the absence of peace),” Miraflor said.
The provincial government has laid out programs and projects, alongside the Negros Oriental Task Force (NOTF)-ELCAC, as part of “local government interventions” to address the insurgency problems in the province, he said.
The Office of the Governor is always open to recommendations and requests for the development of your community, he added in the Cebuano dialect.
Uniformed personnel of the Armed Forces of the Philippines (AFP), the Philippine National Police (PNP) and other branches of government, and other members of the Mabinay TF-ELCAC were present during the launching, a prelude to the holding of the Dagyawan barangay consultation in a still undetermined date this month.
The Mabinay TF-ELCAC is expected to lead in the efforts to curb insurgency in that town through the so-called Re-Tooled Community Support Program of the AFP, with the Dagyawan consultation expected late this month.
During the launching, the municipal TF-ELCAC issued a resolution declaring the New People’s Army “persona non grata”.
Meanwhile, the NOTF-ELCAC has listed additional barangays for the said program which aims to address the insurgency problem through the Whole-of-Nation approach of President Rodrigo Duterte as cited in Executive Order No. 70.
The additional barangays are Budlasan in Canlaon City; Balugo, Nagsaha, Plagatasanon, Poblacion, and Villegas in Guihulngan City; Bagtic, Luyang, and Samac in Mabinay; and Panciao in Manjuyod, said Jennifer Tilos, InfoCen Manager of the Philippine Information Agency here and head of the NOTF-ELCAC’s Strategic Communication cluster.
Initially, 16 barangays in six towns and cities in the province were identified last year as priority areas by the NOTF-ELCAC, as follows: Barangays Bayog and Lumapao in Canlaon City; Trinidad, Binobohan, Sandayao, Tacpao, Imelda, Hinakpan, Humay-humay, and Planas in Guihulngan City; Dobdob in Valencia; San Pedro and Talalak in Sta. Catalina; Tayak in Siaton; and Calango and Mayabon in Zamboanguita. (PNA)
***
References:
* Philippine News Agency. "Anti-insurgency task force launched in NegOr town." Philippine News Agency. https://www.pna.gov.ph/articles/1117852 (accessed October 08, 2020 at 05:52PM UTC+14).
* Philippine News Agency. "Anti-insurgency task force launched in NegOr town." Archive Today. https://archive.ph/?run=1&url=https://www.pna.gov.ph/articles/1117852 (archived).
0 notes