Dynamic number of columns Ionic 2 - responsive-design

I am building a mobile app using Ionic 2 and one of the requirements I have is to display 4 cards in one row if displayed in tablet and only 2 cards in a row if displayed in a mobile. I was wondering what would be the best way to achieve this?

You could essentially just give them a width with a min-width and let them reposition themselves. Something like
.card {
width: calc(100%/4);
min-width: calc(356px/2); // most minimum width of your container on a phone.
}
Probably your best bet though would be to go the responsive route. Just use a #media screen and (max-width="768px") or whatever you need to set it at and change the values there.
.card {
width: calc(100%/4);
}
#media screen and (max-width:768px){
.card {
width: calc(100%/2);
}
}
and you could do this with an *ngStyle if you wished to apply it via angular. Just create a string to match the value with and run an *ngIf statement to apply the separate values.

I have not tried this but you probably want to use ionic platform somewhere you could try something like on the <ion-col> element you can add [attr.width-50] for the iphone and [attr.width-25] for the ipad.
<ion-col [attr.width-50]="isIphoneOrIpad" [attr.width-25]="!isIphoneOrIpad">
You can then write the logic for the return boolean in the corresponding .ts file using Platform.
import { Platform } from 'ionic-angular';
#Component({...})
export MyPage {
isIphoneOrIpad:boolean;
constructor(public platform: Platform) {
this.isIphoneOrIpad = this.platform.is('iphone') || this.platform.is('ipad');
}
}
Which will return true or false and then display the attribute accordingly.
For more information check out the Ionic 2 Platform Documentation

Related

How do I display the value of a theme object on the front end (e.g. #141414) vs the token name (e.g. bgPrimary)?

I've styled my website using a theme.js file utilizing emotion and styled-system and want to show the value (e.g #141414) on the front end vs the token name (e.g bgPrimary).
Obviously when I use the token in practice, my website's background is the correct value but I want to showcase the token name and value on the front end as well (for documentation purposes).
An example of how I regularly use it is like so:
background-color: ${props => props.theme.colors.bgPrimary)
But if I wanted to show the value of bgPrimary on the front-end inside a Text component, like so:
<Text value={___} />
how would I have that return the value #141414 without actually hardcoding the HEX value?
Here's how the color object in theme file currently looks:
const colors = {
accent: '#8548FF',
actionPrimary: '#12A55C',
actionPrimaryInteractive: '#0C6E3D',
actionSecondary: '#292929',
actionSecondaryInteractive: '#1F1F1F',
bgPrimary: '#141414',
bgSecondary: '#0A0A0A',
contentPrimary: '#F5F5F5',
contentSecondary: '#8F8F8F',
modes: {
light: {
accent: '#691FFF',
actionPrimary: '#16CA70',
actionPrimaryInteractive: '#109351',
actionSecondary: '#E0E0E0',
actionSecondaryInteractive: '#CCCCCC',
bgPrimary: '#EBEBEB',
bgSecondary: '#F5F5F5',
contentPrimary: '#0A0A0A',
contentSecondary: '#707070',
},
}
}
As you can see, I have two color modes and bgPrimary is different depending on which mode you have set. This is why it's important for the value to be pulled from the theme vs hardcoded.

How to use styled-system responsive props

Can I use the styled-system to achieve something like this?
<MyComponent
backgroundImage={{
default: "https://placekitten.com/380/80",
sm: "https://placekitten.com/340/80"
}}
/>
or this (because I know it can be done this way too with other "style props" such as width, but I prefer to use an object with keys):
<MyComponent
backgroundImage={[
"https://placekitten.com/300/80",
"https://placekitten.com/500/80"
]}
/>
I think the code examples above are self-descriptive and they follow the library's pattern but just to be clear, I'm mapping the values (image sources) to the breakpoints (default and next one up).
For example, this works out of the box:
<Box
width={[
default: 1,
sm: 1/3,
]}
/>
The output is something like this:
.QWojd {
width: 100%;
}
#media screen and (min-width: 24em) {
.QWojd {
width: 33.33333333333333%;
}
}
I've been looking into the source code and this part here makes me think it should work with backgroundImage too:
Sadly, it doesn't work, and the result is a stringified object (or concatenated array values) in the CSS output.
I can't think of how the variant function would be useful here as people have suggested. I've tried to use the system function but I just can't understand the documentation. The ResponsiveValue type gives me a hint but I feel like crawling in the dark when I try to understand the internals.
Ultimately, I'd like to use the "breakpoints object" (or array) with whatever custom prop I feel like, like this:
<Box
myProp={[
default: 'foo',
sm: 'bar',
]}
/>
Note: I've learned (from experience) that you can just use the "breakpoints array" version (without setting breakpoints in a theme and passing it to a provider) and that will map the value to the first 2 default breakpoints (not sure where they come from) but if you want to use an object with keys you need to use a ThemeProvider with a theme object with your own breakpoints.
Note 2: I can understand the styled-system documentation up to this point: https://styled-system.com/custom-props. When I arrive here I feel like this is what I'm looking for but I can't understand the example, the explanation confuses me even more and I can't find any examples on the web.
Note 3: Spectrum Chat has a styled-system channel and the library author is in there but sadly I haven't been able to send any messages there (constant network error)
Examples
Ok, so according to the docs (https://styled-system.com/custom-props/), in order to create a custom prop (or in this case, replace the existing one) you should use the system utility. Since I'm not a user of this library (styled-system), I'm not 100% sure that this is correct approach, but I tested on top of your example code and it seems to work as you wanted.
The component declaration (it also works with objects like you wanted) with an array:
<ResponsiveImageBox
color="white"
backgroundImage={[
"https://placekitten.com/300/80",
"https://placekitten.com/500/80"
]}
>
Box 8
</ResponsiveImageBox>
with objects:
<ResponsiveImageBox
color="white"
backgroundImage={{
default: "https://placekitten.com/300/80",
sm: "https://placekitten.com/500/80"
}}
>
Box 8
</ResponsiveImageBox>
And this is the component code:
export const ResponsiveImageBox = styled(Box)(
({ myCustomProp }) => {
return css`
${system({
backgroundImage: {
property: "backgroundImage",
transform: value => `url(${value})`
}
})}
`
});
As you can see on examples 4, 5 and 8 (https://stackblitz.com/edit/styled-system-mccqje?file=Examples.tsx), I also did it for the border-radius attribute with a simple prop renaming and just specifying what css attribute I wanted to change (property), so no need to add transform as the value will remain the same.
export const ExtendedBox2 = styled(Box)<ExtendedBoxProps>`
background-position: center;
${system({
myCustomProp: {
property: "border-radius"
}
})}
`;
Have a look and see if this is what you were looking for! :)
I know you already marked it as solved, and Eduardo's approach definitely works. However another way you can do it "out of the box" is to use aliases so that you can use objects instead of arrays (source: https://styled-system.com/responsive-styles/):
// theme.js
const breakpoints = ['40em', '52em', '64em', '80em']
// aliases
breakpoints.sm = breakpoints[0]
breakpoints.md = breakpoints[1]
breakpoints.lg = breakpoints[2]
breakpoints.xl = breakpoints[3]
export default {
breakpoints,
}
// ResponsiveImageBox.js
<ResponsiveImageBox
color="white"
backgroundImage={{
md: "https://placekitten.com/300/80",
sm: "https://placekitten.com/500/80"
}}
>
Box 8
</ResponsiveImageBox>

Customization of the Height of a Pivot Item Link Line in Fluent UI

I'm trying to increase the height of the line on the selected Pivot item link in Microsoft's Fluent UI using React.
Here's a screenshot for the purposes of clarification:
The orange arrow is pointing to the blue line of which I would like to increase the height.
I have tried setting the styles attribute of the Pivot component but thus far have been unsuccessful. Here's some code
const pivotStyles: Partial<IStyleSet<IPivotStyles>> = {
link: { ? },
linkContent: { ? }
};
<Pivot styles={pivotStyles} linkSize={PivotLinkSize.large}>
<PivotItem headerText="Zane"></PivotItem>
<PivotItem headerText="Kai"></PivotItem>
<PivotItem headerText="Jay"></PivotItem>
</Pivot>
I have experimented with different attributes of both link and linkContent but haven't found a way yet. I believe what I'm trying to do is manipulate the IStyle interface but I can't find details of the attributes of it. The link there is very vague. For example, what are all the available attributes of link, linkContent, etc.?
Any thoughts on this would be most appreciated!
Thank you.
Turns out I was on the right track and just needed the exact fields. Here's what ended up working:
const pivotStyles = {
linkIsSelected: {
selectors: {
':before': {
height: '6px', // was previously defaulted at 2px
}
}
}
};
I scoured about 4.24 million sites to find this answer but here are some of the most helpful in case they are of interest:
the actual source code of Pivot.styles.ts
the Microsoft Fluent UI Pivot Documentation
A deep examination of the classes using Chrome Dev Tools also helped. ;)
Here's a picture of the end result:

width and height doesnt change after rotating the screen in react native

I am working on a RN app and I have an issue regarding the rotation and dimensions of the screen. I have a gallery application where I show three images in a row if the screen is vertical. I adjust it by dividing the width by the size of the image, I think this way of specifying the number of images in a row makes it consistent and changeable for different devices. However, after I rotate the screen, I was expecting to see more images in a row, but I didn't. I realized the width didn't change, so I saw three images again instead of 5 or 6. I am not sure if the way I am doing this is right or wrong. Any suggestions regarding this?? Also, how can I change the width and height dynamically, so that I can change the aligning of my gallery after rotation?
here is a part of my code
...var {height, width} = Dimensions.get('window');
var imageSize = 120;
// number : number of images in a row
var number = Math.round(width/imageSize);
console.log(number);
var CameraRollView = React.createClass({
propTypes: propTypes,
getDefaultProps: function(): Object {
return {
groupTypes: 'SavedPhotos',
batchSize: 5,
imagesPerRow: number,
assetType: 'Photos',
renderImage: function(asset) {
//var imageSize = 120;
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
return (
<TouchableHighlight onPress={
()=>{
/**fire gallery action selectImage*/
this.selectImage(asset.node.image.uri, this.images);
}
} key={asset.node.image.uri}>
<Image
source={asset.node.image}
style={imageStyle}
/>
</TouchableHighlight>
);
},
};
},
...
here what important is -imagesPerRow- I want it to be dynamic, as I rotate the device.
I would recommend against using the Dimensions module if you need to respond to screen size changes.
The View component provides an onLayout property that is called each time that View's layout has to be recalculated (e.g. on device rotation). I don't know anything about the architecture of your app, so I will just say the easiest way to use it in my opinion is to set it to a function on the root View in your app that writes the new parameters to state (or to your flux/redux stores if you use that).
You can then pass that information through your app and use it as you see fit.

How to use gridfilters Plugin AND programmatically clear/set the filters?

In my app (ExtJS 5.0.1) I'm trying to use a grid with the gridfilters Plugin AND shortcut buttons (and also from a tree) with custom/hardcoded fiters.
I was able to partially mimic the set and clear of the filters, but I'm having the following problems:
1- When I set a filter via grid.filters.store.addFilter(..) the style of the column title doesn't change to bold, and the grid filter checkbox stays unchecked.
2- Same as 1 but reversed... first I set the filter on the column, when I clear the filter the column stays bold, but in this case the checkbox is cleared (as it should).
3- When I'm using summary feature 'sometimes' the total is not updated
So, my question is:
Is there a proper way to programmatically set/clear filters mimicking the gridfilter Plugin ?
I've put a minimal Fiddle to simulate this.
https://fiddle.sencha.com/#fiddle/akh
Best Regards,
Ricardo Seixas
Just use filter instance on column:
var column = grid.columnManager.getColumns()[0];
column.filter.setValue('J');
column.filter.enable();
Working sample: http://jsfiddle.net/3be0s3d8/7/
For List Filters use the following override to enable the setValue method:
//Enable setting filter values in list filters
Ext.define('Ext.ux.fixed.ListFilter', {
override: 'Ext.grid.filters.filter.List',
setValue: function(values) {
var me = this, len = values.length;
if(!values) {
me.callParent();
return;
}
if(!me.menu){
me.createMenu();
}
me.filter.setValue(values);
if (len && me.active) {
me.updateStoreFilter(me.filter);
} else {
me.setActive(!!len);
}
}
});
You can directly change the styles in the GridFilter.css file :
<link rel="stylesheet" type="text/css" href="js/lib/ext-4.2.1.883/ux/grid/css/GridFilters.css" />
By changing this element :
.ux-filtered-column {
font-style: italic;
font-weight: bold;
background: #56b8ff;
}
Hope this helps.
In the latest release (5.1) Ext's ChainedStore worked well for me.

Resources