Tailwind.css — How to implement the last-child using Tailwind? - javascript

I have tried without success to implement the prefix last: as shown in the Tailwind.css documentation. Can anyone point out what I am doing wrong? I cannot make this work.
Thank you in advance.
React Component
{items.map((item, i) => {
return (
<li
key={i.toString()}
v-for="(item, i) in items"
className="pb-sm xl:pb-md last:pb-0" // This is the problematic fellow!
>
<div className="grid grid-cols-12">
<div className="col-start-2 col-span-10 md:col-start-2 md:col-span-8 pb-2 sm:pb-xs md:pb-xs lg:pb-xs xl:pb-0">
<div className="serif text-h5 xl:text-h4 lg:text-h4 md:text-h4 leading-snug xl:leading-tight lg:leading-tight md:leading-snug">
{item}
</div>
</div>
<div className="col-start-2 col-span-10 sm:col-start-5 sm:col-span-6 md:col-start-5 md:col-span-6 lg:col-start-5 lg:col-span-6 xl:col-start-5 xl:col-span-3 pb-xs sm:pb-xs">
<div className="text-p sm:text-p">{description[i]}</div>
</div>
</div>
</li>
)
})}

As of April 2022 (v 3.0.24)
According to Tailwind's doc:
Style an element when it is the first-child or last-child using the first and last modifiers
Just use last:${yourClassName} to target the last child in your case.
Source: https://tailwindcss.com/docs/hover-focus-and-other-states#last

Not sure if you're using Tailwind v2.X or v1.X but you need to activate the variant for last. Here is a quote from the official v2 docs related page
By default, the last-child variant is not enabled for any core plugins.
I've tried to make an example for you on https://play.tailwindcss.com/ but it doesn't work there. Meanwhile, I spin a Vite VueJS repo with the latest version of TW and it's working perfectly.
So, this in your tailwind.config.js should do the trick
module.exports = {
...
variants: {
extend: {
padding: ['last'],
}
},
...
}
v2's documentation is here and v1's is here.
Beware, the variants >> extend is only available in the v2. If you're using v1, you can still override the whole padding variant manually, not a big deal.
PS: Tailwind's team fixed the issue already, damn !

Related

React-router pages with arrows

I want to change menu-pages (in react-router) with to icons ("back", "forward")...
export const ArrowNav = () => {
const menu = useContext(menuContext);
return <div className="lmpixels-arrows-nav">
<NavLink to={"/about"}>
<div className="lmpixels-arrow-right">
<i className="lnr lnr-chevron-right"/>
</div>
</NavLink>
<NavLink to="/resume">
<div className="lmpixels-arrow-left">
<i className="lnr lnr-chevron-left"/>
</div>
</NavLink>
</div>
}
Instead of using html css styles to show the icons you might like to try the package React Icons:
https://react-icons.github.io/
I, particularly, avoid using old CSS style names for icons like you are trying to do. In fact, I prefer to do all I can do to avoid the use of CSS files with React. Because React uses a lot js objects I believe it is better practice the use of some kind of CSS objects:
https://www.w3schools.com/react/react_css.asp
The error you are getting might depend on how are you importing the needed css information.
More info you might find useful:
https://medium.com/swlh/using-react-router-navlink-to-specify-the-active-element-in-a-navigation-bar-38700ffd4900
Hope this will help you

AngularJS Expression breaks with StencilJS

I have a custom select web component created with StencilJS and I am using it in AngularJS like this:
<my-select>
<my-option ng-repeat="item in items">
{{item.value}}
</my-option>
</my-select>
The problem is that whenever I push a new item on the items array (items.push({key: 'some', value: 'Some Value'})), the expression seems to print also it's own syntax in the DOM like this:
This is the <my-option> StencilJS component structure:
render() {
return (
<div class="option-container" onClick={this.selectOption(this)}>
<slot />
</div>
);
}
Any help would be so much appreciated. Thank you.
Did you tried some newer Browser like the newest Firefox or Chrome? I faced some really stupid issues because Edge Browser for example does render the <slot tag as an String initially and just renders the innerHTML once. The other Browser will keep the slot as an DOM Element so its more dynamic.

How to Use css selectors in jest unit testing while using css modules

I'm using css modules in my react project and using web pack for bundling. While using Jest for testing, as the jest will try to import css files like normal JS files got the below error,
SyntaxError: Unexpected token .
The solution that I found is to use "identity-obj-proxy" to mock scss/css files.But now I cannot use css selectors to test components.For example
Test
it('renders 2 children', () => {
expect(component.find('.mockyApp').children().length).toBe(2);
});
render method
render() {
if (this.state.host) {
return (
<div className={style.mockyApp}>
<div className={style.sidePage}>
<SideBar clickHandler={this.setPage} selected={this.state.page}/>
</div>
<div className={style.mainPage}>
{this.renderComponent()}
</div>
</div>
);
}
// ... .. rest of render method
}
I'm using import style from './mocky.scss'; to import styles and using the style object for class names. Before using css-modules the above test used to work.Now my question is how will I be able to test using css selectors and what change needs to be done to make this work?. Googling didn't help
I don't think there exists a good solution for this problem yet.
Few ways you can still test it:
1) Add a static class name just for testing:
<div className={`${style.mockyApp} mockyApp`}>
<div className={style.sidePage}>
<SideBar clickHandler={this.setPage} selected={this.state.page}/>
</div>
<div className={style.mainPage}>
{this.renderComponent()}
</div>
</div>
2) Use a data attribute to target that element.
Component
<div className={`${style.mockyApp} mockyApp`} data-jest="mockyApp">
<div className={style.sidePage}>
<SideBar clickHandler={this.setPage} selected={this.state.page}/>
</div>
<div className={style.mainPage}>
{this.renderComponent()}
</div>
</div>
Render
it('renders 2 children', () => {
expect(component.find('[data-jest=mockyApp]').children().length).toBe(2);
});
Both ways work but they include adding stuff to the DOM which gets shipped to production, which means more bytes being sent to your users.
If you are going with the second approach, you can consider writing a Babel plugin that strips out all data-jest attributes from the DOM in the transpilation process.

Angular bootstrap pagination force-ellipses

This plnkr I created shows the problem: http://plnkr.co/edit/YQAUCg5vjcgS1BEGB4nY?p=preview
shortly, I've got many pages and i set this attribute: force-ellipses = true to show the dots instead 200 pages. But doesn't work. I use angular bootstrap 2.3.1 and I think this is the problem. But I can't use another version so, is there any way to fix it?
<pagination
num-pages="noOfPages"
current-page="currentPage"
max-size="maxSize"
boundary-link-numbers="true"
rotate="true"
force-ellipses="true">
</pagination>
Actually, implementation of uib-pagination is not correct. In the recent version, the syntax is
<div uib-pagination total-items="total_items" max-size="maxSize" class="pagination-sm" boundary-link-numbers="true" rotate="false"></div>
Check this plunker for implementation
Apart from this. I use dir-pagination i feel that more convenient and easy.
Check this angularUtils repo
and Plunker for dir-pagination

In Vue.js, is there a way to keep component templates out of JavaScript strings?

I just worked through the Guide on Vue.js's website, and I have a bad feeling about templates for components. It seems strange to me that they are specified in strings; sure, maybe this works for very short templates, but once you get to multiline templates, you need to start escaping your new lines and it just feels wrong to have html in javascript strings to begin with. Not to mention that syntax highlighting or any other nice IDE features are useless with HTML in JS strings.
Two alternatives that are detailed in the docs are using inline templates, or X-templates, but both of these options are discouraged.
The only other alternative seems to be Single File Components, which seems like a good option, but they are in the Advanced section and in the docs, it is said that for small and medium sized apps, simply using Vue.component should be enough. Furthermore, Single File Components look like they're more difficult to integrate into a project, requiring tapping into the project's build system (the docs talk about Webpack and Browserify).
So I'm confused. Do I just need to accept that my component code is going to look as messy as this example, pulled straight from the docs?
Vue.component('currency-input', {
template: '\
<span>\
$\
<input\
ref="input"\
v-bind:value="value"\
v-on:input="updateValue($event.target.value)"\
>\
</span>\
',
......
Given that you are starting a new project, you can use vue-hackernews-2.0 as boilerplate, where you see lot of components already coded with webpack integration for both dev and prod env. This is also developed by core vue team and recommended in official docs.
You can see there are different files for each component and one component looks like following having clear separation of HTML, JS and CSS part:
<template>
<li v-if="comment" class="comment">
<div class="by">
<router-link :to="'/user/' + comment.by">{{ comment.by }}</router-link>
{{ comment.time | timeAgo }} ago
</div>
<div class="text" v-html="comment.text"></div>
<div class="toggle" :class="{ open }" v-if="comment.kids && comment.kids.length">
<a #click="open = !open">{{
open
? '[-]'
: '[+] ' + pluralize(comment.kids.length) + ' collapsed'
}}</a>
</div>
<ul class="comment-children" v-show="open">
<comment v-for="id in comment.kids" :id="id"></comment>
</ul>
</li>
</template>
<script>
export default {
name: 'comment',
props: ['id'],
data () {
return {
open: true
}
},
computed: {
comment () {
return this.$store.state.items[this.id]
}
},
methods: {
pluralize: n => n + (n === 1 ? ' reply' : ' replies')
}
}
</script>
<style lang="stylus">
.comment-children
.comment-children
margin-left 1.5em
.comment
border-top 1px solid #eee
position relative
.by, .text, .toggle
font-size .9em
margin 1em 0
.by
color #999
a
color #999
text-decoration underline
.text
overflow-wrap break-word
a:hover
color #ff6600
pre
white-space pre-wrap
.toggle
background-color #fffbf2
padding .3em .5em
border-radius 4px
a
color #999
cursor pointer
&.open
padding 0
background-color transparent
margin-bottom -0.5em
</style>
This uses webpack for build and adds working config as well which I myself am using in production without any issue.
You can use <template>...</template> or <script type="text/x-template">...</script>, and specify the selector in template attribute for that.
<template id="myComponent">
<div>
<h1>Hello!</h1>
<p><slot></slot></p>
</div>
</template>
Vue.component('myComponent', {
template: '#myComponent'
})
Simple working example here: http://codepen.io/anon/pen/dNWrZG?editors=1010
Also, the build process of single file components is not that difficult. You can check the webpack-simple template: https://github.com/vuejs-templates/webpack-simple, the vue-loader will do everything for you.
Once you feel comfortable with webpack, you can take a look at the full webpack template: https://github.com/vuejs-templates/webpack
From my experiences, if the template is very short, use inline mode is OK. If not, x-template also allows you to get rid of escaping line breaks. I don't see why you think these approaches are discouraged. Can you provide more information?
However, if you insist to embed long template inline, you can still do that without escaping. The answer is ES6 template literals - string wrapped within ``:
template: `
<span>
$
<input
ref="input"
v-bind:value="value"
v-on:input="updateValue($event.target.value)"
>
</span>
`,
On the other hand, I really think vue-cli is a great tool. Webpack is something worth learning.
This is not really a direct answer (It's editor Specific) but i just thought i should share, but if you're using Visual Studio Code as your editor, Then you can keep your templates as part of your component and still get Syntax highlighting.
Thanks to this awesome extension
angular-2-inline
It was Originally meant for Angular 2, but it works for all ES6 Template strings (Provided the key of Template String is "template").
Single File components are the Recommended way, but they can become a burden when you're not building a Full-fledged SPA and you're just using Vue to enhance some HTML templates Here and there, and you don't want to get Involved with Webpack.
Don't believe it? I'm currently using it.
Thanks to #danidee answer I was able to track an Atom extension to properly do syntax highlighting for "backticked" HTML strings. However as he indicates it will only work when the template is declared inside the very component definition (and I want to separate template in another .js file). So I did this and it's a more ellegant solution, I think:
COMPONENT DEFINITION
/* template definition */
import { csFooterView } from './csfooter-view.js?v6';
/* component definition */
const csfooter = {
name: 'csfooter',
props: ['projectName'],
data: function() {
return {
copyrightCompany: 'CSDev'
}
},
template: csFooterView.template
};
/* exports */
export { csfooter };
TEMPLATE DEFINITION
/**
* VUE Footer Component
* Template
*/
/* template definition */
const csFooterView = {
template: `
<footer class="footer bg-warning p-4 m-auto">
<p>{{ copyrightCompany }} (c) 2020 - {{ projectName }}</p>
</footer>
`
};
export { csFooterView }
ATOM SCREENSHOT WITH HTML SYNTAX HIGHLIGHTING IN THE .JS FILE
Link to Atom extension

Categories

Resources