How create a grid layout with paper-card - css

I am trying to mix the template repeater and the paper-card tutorial in the Polymer Starter Kit.
My aim is to copy that kind of grid :
(source: instantshift.com)
I created two custom elements :
A list of employees
An employee
Employee List:
<style is="custom-style">
#board {
#apply(--layout-vertical); <<= HERE ARE DEFINED THE LAYOUT OF THE GRID
#apply(--layout-wrap);
height: 344px;
width: 384px;
}
#board > paper-card {
box-sizing: border-box;
max-width: 184px;
margin: 4px;
flex: 0 0 auto;
}
</style>
<template>
<div id="board">
<template is="dom-repeat" items="{{employeesArray}}">
<employee-element name="{{item.title}}"
preview="{{item.preview}}"
width={{item.width}} height={{item.height}}>
</employee-element>
</template>
</div>
</template>
Employee :
<paper-card
heading="{{name}}"
image="{{preview}}"
style="max-width:{{width}}px;
max-height:{{height}}px;"
>
<div class="card-actions">
<paper-icon-button class="favorite" icon="favorite"></paper-icon-button>
<paper-icon-button class="bookmark" icon="bookmark"></paper-icon-button>
<paper-icon-button class="share" icon="social:share"></paper-icon-button>
</div>
</paper-card>
Here is what I get :
How can I approach the result expected ? Is there a setting making the card arranging themselves automatically ?
How can I get a "carriage return"-like behaviour ?
Answer results (thanks to #Snekw) :
Steps :
Add the following line where you import your elements (elements/elements.html in my case)
<link rel="import" href="../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
My Employee list element now looks like :
<style is="custom-style" include="iron-flex">
.flex-wrap {
#apply(--layout-horizontal);
#apply(--layout-wrap);
}
</style>
<template>
<div class="container flex-wrap">
<template is="dom-repeat" items="{{employeesArray}}">
<employee-element name="{{item.title}}"
preview="{{item.preview}}"
width={{item.width}} height={{item.height}}>
</employee-element>
</template>
</div>
</template>
And I get this result :
I still have to fix the problem with the paper-card action panel.

You need to include the iron-flex class on your style tag.
<style is="custom-style" include="iron-flex">
//your styling
</style>
You will need to load the iron-flex-layout-classes.html element. Iron-flex-layout element contains the --layout-vertical and --layout-wrap properties.
More on iron-flex-layout here: iron-flex-layout-classes GitHub

Related

Vue 3 slot styles from child component

Summary: I need to style the contents of a <slot>, from the child component. I'm using scoped css and the styles don't apply:
I have the following two components:
<!-- Parent.vue -->
<template>
<h1>{{ msg }} from Parent</h1>
<Child>
<h1>{{ msg }} from Child</h1>
</Child>
</template>
...
<style scoped>
h1 {
color: green;
}
</style>
<!-- Child.vue -->
<template>
<slot></slot>
</template>
...
<style scoped>
h1 {
color: red;
}
</style>
I want the 2nd <h1> to be red, but it's green, since the component is rendered with something like:
<h1 data-v-452d6c4c data-v-2dcc19c8-s>Hello from Child</h1>
<style>
h1[data-v-452d6c4c] {
color: green;
}
h1[data-v-2dcc19c8] {
color: red;
}
</style>
data-v-452d6c4c comes from Parent, and data-v-2dcc19c8-s from Child
If the second attribute, in the <h1> tag, was just data-v-2dcc19c8 the style I wanted would be applied, but since it has that -s suffix (slot?), it doesn't.
I could probably find some other solution with a class or something, but I rarely use <slot> and I want to understand the inner workings. That -s tells me that what I'm trying to do can be dealt with the help of the framework, what am I missing?
A working sample:
https://codesandbox.io/s/condescending-brown-ilfwn
Use the new :slotted selector in Vue 3:
Child.vue
<template>
<slot></slot>
</template>
<script>
export default {
name: "Child",
};
</script>
<style scoped>
:slotted(h1) {
color: red !important;
}
</style>
In Vue 3, child scoped styles don't affect slotted content by default.
In your particular example, the !important modifier is also necessary because the parent also defined an h1 style which would take precedence otherwise

CSS works but SASS can't change style of component

I'm trying to override min-height property of a class named application--wrap but the code only works when declared into CSS style:
Code that works:
<style lang="css" scoped>
.application--wrap{
min-height: 0px;
}
</style>
Code that doesn't works:
<style lang="sass" scoped>
.application--wrap
min-height: 0px;
</style>
"Full" code:
<v-app>
<div class="container-fluid centerTable">
<v-data-table
v-bind:headers="headers"
:items="listLayers"
:rows-per-page-items= "[5, 10]"
:custom-sort="customSort"
:loading="loading"
v-bind:pagination.sync="pagination"
class="elevation-1 layersTable"
>
</v-app>
The class that i'm trying to override it's created on render by the Vuetify.

:first-child styles not beeing applied in Vue Component

Problem:
Normally the first <User> should have margin-left: 0px and should align to the left with the other elements but this doesn't work as you can see in the screenshot below. Anyone got an idea how to fix this properly?
sidebar.scss Code:
.user {
margin-left: -8px;
&:first-child {
margin-left: 0;
}
}
Sidebar.vue Code
<template>
<section class="sidebar">
<slot></slot>
</section>
</template>
<script>
export default {
name: "Sidebar"
}
</script>
<style scoped lang="scss">
#import 'sidebar';
</style>
Profile.vue Code
<template>
<main>
<Sidebar>
<Header text="Members" :button="{text: 'Edit'}" hasBorder="true"></Header>
<User img="..."></User>
<User img="..."></User>
<User img="..."></User>
<User img="..."></User>
<Button color="grey" isRounded="true" isIconOnly="true"></Button>
</Sidebar>
</main>
</template>
User.vue code:
<template>
<div class="user">
<img v-if="this.img" :src="this.img" :alt="this.name">
<div v-if="!this.img"></div>
<h6 v-if="this.name">{{this.name}}</h6>
<slot></slot>
</div>
</template>
Not too sure if this is at all the problem here, but note that :first-child does not pick the first occurrence by the mere class name, but by the tag within a parent element. In other words: you cannot use a class name to apply :first-child to. Instead, use something more semantic like
<ul class="users">
<li class="user"></li> <!-- there is your component -->
<li class="user"></li>
<li class="user"></li>
</ul>
Use ::v-deep to change scoped css.
I answered this already but I have an old and more descriptive answer available which might be a help to you to understand the usage https://stackoverflow.com/a/56698470/7358308
https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors
Note: Don not use /deep/ because it's deprecated and also >>> combinator will not work too as you are using sass preprocessor
::v-deep {
.user {
margin-left: -8px;
&:first-child {
margin-left: 0;
}
}
}
Scoped style is not shared between parent and child components. You have several options:
Make style global by removing scoped attribute from style section in parent.
Import style into the target component (User).
Use the deep combinator in scoped style.
>>>.user {
...
}
or
/deep/ .user {
...
}
or
::v-deep .user {
...
}

Polymer Styling Child Components

I am trying to style my child components. Isit wrong to put the style in a parent component? It appears that does not work.
I put the style for .card-page in the top level element (containing expenses-module where I use it)
<dom-module id="expenses-app">
<template>
<style>
...
.card-page {
display: block;
width: 100%;
}
</style>
<app-drawer-layout>
<app-header-layout>
...
<iron-pages selected="{{routeData.view}}" attr-for-selected="name">
<dashboard-module name="dashboard" route="{{subroute}}"></dashboard-module>
<expenses-module name="expenses" route="{{subroute}}"></expenses-module>
<settings-module name="settings" route="{{subroute}}"></settings-module>
</iron-pages>
</app-header-layout>
</app-drawer-layout>
</template>
In expenses module,
<paper-card heading="Expenses" class="card-page">...
</paper-card>
Seems like if I move the styles into expenses-module it works.
You cannot directly style elements inside custom element from their parents like that, because Polymer processes the style within <dom-module> and will apply styles only to direct child members. It will not descend into child custom elements.
In other words, standard CSS selectors will only work within the scope of the declaring component. Both in Shadow and Shady DOM.
For your styles to work with nested elements, you should use CSS mixins and properties. All PolymerElements and many 3rd party elements will come with such styling extension points. The naming usually follow the convention, where the main mixin is called same as the element itself. Additionally, there may be more specific mixins and properties, which style only parts of the element. <paper-card> docs for example lists --paper-card mixin, --paper-card-content mixin, --paper-card-header-color and more.
If you want to better control the styling of elements you use, you would want to create your own CSS mixins/properties and #apply() them to selected elements. See how in the example below --my-elem-card-page applies only to one of the two paper cards.
<!DOCTYPE html>
<html>
<head>
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import"/>
<link href="paper-card/paper-card.html" rel="import"/>
</head>
<body>
<my-wrapper></my-wrapper>
<dom-module id="my-elem">
<template>
<style>
.card-page {
#apply(--my-elem-card-page);
}
</style>
<paper-card heading="my-elem specific style" class="card-page">
<div class="card-content">
Content here
</div>
</paper-card>
<paper-card heading="Default style" class="unstyled-page">
<div class="card-content">
Content here
</div>
</paper-card>
</template>
</dom-module>
<dom-module id="my-wrapper">
<template>
<style>
# will be ignored
paper-card {
width: 200px;
}
my-elem{
--paper-card: {
color: blue;
display: block;
}
}
my-elem {
--my-elem-card-page: {
color: red;
}
}
</style>
<my-elem></my-elem>
</template>
</dom-module>
<script>
Polymer({
is: 'my-elem'
});
Polymer({
is: 'my-wrapper'
});
</script>
</body>
</html>

How can I style the <paper-card> used in my polymer-element

Hi I am creating my polymer element in which i am using < paper-card >. I want to change the height & width of my paper-card so that it occupies the entire space. Also i want to make few more changes but I am finding it difficult. I can do it with inline styling like this :
<template>
<div >
<paper-card heading="OTS Task" animatedShadow="true" style="width: 100%">
<div class="card-content" >
<iron-label >Label 1 </iron-label>
<iron-label> Label 2</iron-label>
</div>
<div class="card-actions">
<paper-button>Share</paper-button>
<paper-button>Explore!</paper-button>
</div>
</paper-card>
</div>
If you see here i have done style="width : 100%" to make it span the entire width. Can anyone tell me how can i write the same in < style > tag. I read few docs on this but found it very difficult * New to polymer *. Thanks in advance :)
Don't think that setting the paper-card element to 100% will work.
I believe that the correct way would be to use mixing as this is the way you style Polymer elements.
The correct way in this case would be:
paper-card {
--paper-card: {
width: 100%;
};
}
The alignment of the text would be in this case handled with:
paper-card {
--paper-card-header-text: {
text-align: center;
};
}
paper-card {
--paper-card-content: {
text-align: center;
};
}
A full list of the different selectors can be found in the element description here.
The equivalent CSS for <paper-card style="width: 100%"> would be:
<style>
paper-card {
width: 100%;
}
</style>
Here's a working demo:
<head>
<base href="https://polygit.org/polymer+1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-card/paper-card.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<style>
paper-card {
width: 100%;
}
</style>
<template>
<div>
<paper-card heading="OTS Task" animated-shadow="true">
<div class="card-content" >
<iron-label >Label 1 </iron-label>
<iron-label> Label 2</iron-label>
</div>
<div class="card-actions">
<paper-button>Share</paper-button>
<paper-button>Explore!</paper-button>
</div>
</paper-card>
</div>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo'
});
});
</script>
</dom-module>
</body>
codepen
You can use is="custom-style" in your style tag and then use paper-card properties as described on elements page or standard CSS properties

Resources