refactor(grid): update to support dynamic number of columns

- adds size, offset, push, and pull (including specific breakpoints) as
properties of ion-col
- removes old css mixins to instead style the element itself
- updates sass variables to use css variables for grid padding and width
This commit is contained in:
Brandy Carney
2018-06-18 11:33:26 -04:00
parent 0f5601b3ae
commit 71faf3681a
11 changed files with 954 additions and 267 deletions

View File

@ -1472,7 +1472,102 @@ declare global {
namespace StencilComponents {
interface IonCol {
/**
* The amount to offset the column, in terms of how many columns it should shift to the right of the total available.
*/
'offset': string;
/**
* The amount to offset the column for lg screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetLg': string;
/**
* The amount to offset the column for md screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetMd': string;
/**
* The amount to offset the column for sm screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetSm': string;
/**
* The amount to offset the column for xl screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetXl': string;
/**
* The amount to offset the column for xs screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetXs': string;
/**
* The amount to pull the column, in terms of how many columns it should shift to the left of the total available.
*/
'pull': string;
/**
* The amount to pull the column for lg screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullLg': string;
/**
* The amount to pull the column for md screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullMd': string;
/**
* The amount to pull the column for sm screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullSm': string;
/**
* The amount to pull the column for xl screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullXl': string;
/**
* The amount to pull the column for xs screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullXs': string;
/**
* The amount to push the column, in terms of how many columns it should shift to the right of the total available.
*/
'push': string;
/**
* The amount to push the column for lg screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushLg': string;
/**
* The amount to push the column for md screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushMd': string;
/**
* The amount to push the column for sm screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushSm': string;
/**
* The amount to push the column for xl screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushXl': string;
/**
* The amount to push the column for xs screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushXs': string;
/**
* The size of the column, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'size': string;
/**
* The size of the column for lg screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeLg': string;
/**
* The size of the column for md screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeMd': string;
/**
* The size of the column for sm screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeSm': string;
/**
* The size of the column for xl screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeXl': string;
/**
* The size of the column for xs screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeXs': string;
}
}
@ -1495,7 +1590,102 @@ declare global {
}
namespace JSXElements {
export interface IonColAttributes extends HTMLAttributes {
/**
* The amount to offset the column, in terms of how many columns it should shift to the right of the total available.
*/
'offset'?: string;
/**
* The amount to offset the column for lg screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetLg'?: string;
/**
* The amount to offset the column for md screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetMd'?: string;
/**
* The amount to offset the column for sm screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetSm'?: string;
/**
* The amount to offset the column for xl screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetXl'?: string;
/**
* The amount to offset the column for xs screens, in terms of how many columns it should shift to the right of the total available.
*/
'offsetXs'?: string;
/**
* The amount to pull the column, in terms of how many columns it should shift to the left of the total available.
*/
'pull'?: string;
/**
* The amount to pull the column for lg screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullLg'?: string;
/**
* The amount to pull the column for md screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullMd'?: string;
/**
* The amount to pull the column for sm screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullSm'?: string;
/**
* The amount to pull the column for xl screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullXl'?: string;
/**
* The amount to pull the column for xs screens, in terms of how many columns it should shift to the left of the total available.
*/
'pullXs'?: string;
/**
* The amount to push the column, in terms of how many columns it should shift to the right of the total available.
*/
'push'?: string;
/**
* The amount to push the column for lg screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushLg'?: string;
/**
* The amount to push the column for md screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushMd'?: string;
/**
* The amount to push the column for sm screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushSm'?: string;
/**
* The amount to push the column for xl screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushXl'?: string;
/**
* The amount to push the column for xs screens, in terms of how many columns it should shift to the right of the total available.
*/
'pushXs'?: string;
/**
* The size of the column, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'size'?: string;
/**
* The size of the column for lg screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeLg'?: string;
/**
* The size of the column for md screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeMd'?: string;
/**
* The size of the column for sm screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeSm'?: string;
/**
* The size of the column for xl screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeXl'?: string;
/**
* The size of the column for xs screens, in terms of how many columns it should take up out of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
'sizeXs'?: string;
}
}
}
@ -2187,7 +2377,10 @@ declare global {
namespace StencilComponents {
interface IonGrid {
/**
* If true, the grid will have a fixed width based on the screen size. Defaults to `false`.
*/
'fixed': boolean;
}
}
@ -2210,7 +2403,10 @@ declare global {
}
namespace JSXElements {
export interface IonGridAttributes extends HTMLAttributes {
/**
* If true, the grid will have a fixed width based on the screen size. Defaults to `false`.
*/
'fixed'?: boolean;
}
}
}
@ -3308,11 +3504,11 @@ declare global {
*/
'leaveAnimation': AnimationBuilder;
/**
* Returns a promise that resolves when the loading did dismiss. It also accepts a callback that is called in the same circustances.
* Returns a promise that resolves when the loading did dismiss. It also accepts a callback that is called in the same circumstances.
*/
'onDidDismiss': (callback?: ((detail: OverlayEventDetail) => void) | undefined) => Promise<OverlayEventDetail>;
/**
* Returns a promise that resolves when the loading will dismiss. It also accepts a callback that is called in the same circustances. ``` const {data, role} = await loading.onWillDismiss(); ```
* Returns a promise that resolves when the loading will dismiss. It also accepts a callback that is called in the same circumstances.
*/
'onWillDismiss': (callback?: ((detail: OverlayEventDetail) => void) | undefined) => Promise<OverlayEventDetail>;
'overlayId': number;

View File

@ -1,7 +1,252 @@
import { Component } from '@stencil/core';
import { Component, Element, Listen, Prop } from '@stencil/core';
import { isMatch } from '../../utils/media';
const SUPPORTS_VARS: boolean = CSS.supports('--a', '0');
const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
@Component({
tag: 'ion-col'
})
export class Col {}
export class Col {
[key: string]: any;
@Element() el!: HTMLStencilElement;
/**
* The amount to offset the column, in terms of how many columns it should shift to the right
* of the total available.
*/
@Prop() offset?: string;
/**
* The amount to offset the column for xs screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() offsetXs?: string;
/**
* The amount to offset the column for sm screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() offsetSm?: string;
/**
* The amount to offset the column for md screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() offsetMd?: string;
/**
* The amount to offset the column for lg screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() offsetLg?: string;
/**
* The amount to offset the column for xl screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() offsetXl?: string;
/**
* The amount to pull the column, in terms of how many columns it should shift to the left of
* the total available.
*/
@Prop() pull?: string;
/**
* The amount to pull the column for xs screens, in terms of how many columns it should shift
* to the left of the total available.
*/
@Prop() pullXs?: string;
/**
* The amount to pull the column for sm screens, in terms of how many columns it should shift
* to the left of the total available.
*/
@Prop() pullSm?: string;
/**
* The amount to pull the column for md screens, in terms of how many columns it should shift
* to the left of the total available.
*/
@Prop() pullMd?: string;
/**
* The amount to pull the column for lg screens, in terms of how many columns it should shift
* to the left of the total available.
*/
@Prop() pullLg?: string;
/**
* The amount to pull the column for xl screens, in terms of how many columns it should shift
* to the left of the total available.
*/
@Prop() pullXl?: string;
/**
* The amount to push the column, in terms of how many columns it should shift to the right
* of the total available.
*/
@Prop() push?: string;
/**
* The amount to push the column for xs screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() pushXs?: string;
/**
* The amount to push the column for sm screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() pushSm?: string;
/**
* The amount to push the column for md screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() pushMd?: string;
/**
* The amount to push the column for lg screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() pushLg?: string;
/**
* The amount to push the column for xl screens, in terms of how many columns it should shift
* to the right of the total available.
*/
@Prop() pushXl?: string;
/**
* The size of the column, in terms of how many columns it should take up out of the total
* available. If `"auto"` is passed, the column will be the size of its content.
*/
@Prop() size?: string;
/**
* The size of the column for xs screens, in terms of how many columns it should take up out
* of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
@Prop() sizeXs?: string;
/**
* The size of the column for sm screens, in terms of how many columns it should take up out
* of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
@Prop() sizeSm?: string;
/**
* The size of the column for md screens, in terms of how many columns it should take up out
* of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
@Prop() sizeMd?: string;
/**
* The size of the column for lg screens, in terms of how many columns it should take up out
* of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
@Prop() sizeLg?: string;
/**
* The size of the column for xl screens, in terms of how many columns it should take up out
* of the total available. If `"auto"` is passed, the column will be the size of its content.
*/
@Prop() sizeXl?: string;
hostData() {
return {
style: {
...this.calculateOffset(),
...this.calculatePull(),
...this.calculatePush(),
...this.calculateSize()
}
};
}
@Listen('window:resize')
onResize() {
this.el.forceUpdate();
}
// Loop through all of the breakpoints to see if the media query
// matches and grab the column value from the relevant prop if so
getColumns(property: string) {
let matched;
for (const breakpoint of BREAKPOINTS) {
const matches = this.isMatch(breakpoint);
// Grab the value of the property, if it exists and our
// media query matches we return the value
const columns = this[property + breakpoint.charAt(0).toUpperCase() + breakpoint.slice(1)];
if (matches && columns !== undefined) {
matched = columns;
}
}
// Return the last matched columns since the breakpoints
// increase in size and we want to return the largest match
return matched;
}
calculateSize() {
let columns = this.getColumns('size');
// If size wasn't set for any breakpoint
// or if the user set the size without a value
// it means we need to stick with the default and return
// e.g. <ion-col size-md>
if (!columns || columns === '') return;
columns = SUPPORTS_VARS
// If CSS supports variables we should use the grid columns var
? `calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
// Convert the columns to a percentage by dividing by the total number
// of columns (12) and then multiplying by 100
: ((columns / 12) * 100) + '%';
return {
'flex': `0 0 ${columns}`,
'width': `${columns}`,
'max-width': `${columns}`
};
}
// Called by push, pull, and offset since they use the same calculations
calculatePosition(property: string, modifier: string) {
const columns = this.getColumns(property);
if (!columns) return;
// If the number of columns passed are greater than 0 and less than
// 12 we can position the column, else default to auto
const amount = SUPPORTS_VARS
// If CSS supports variables we should use the grid columns var
? `calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
// Convert the columns to a percentage by dividing by the total number
// of columns (12) and then multiplying by 100
: (columns > 0 && columns < 12) ? (columns / 12 * 100) + '%' : 'auto';
return {
[`${modifier}`]: amount
};
}
calculateOffset() {
return this.calculatePosition('offset', 'margin-left');
}
calculatePull() {
return this.calculatePosition('pull', 'right');
}
calculatePush() {
return this.calculatePosition('push', 'left');
}
isMatch(bp: string) {
return bp ? isMatch(bp) : true;
}
}

View File

@ -21,6 +21,394 @@ There are several attributes that can be added to a column to customize this beh
<!-- Auto Generated Below -->
## Properties
#### offset
string
The amount to offset the column, in terms of how many columns it should shift to the right
of the total available.
#### offsetLg
string
The amount to offset the column for lg screens, in terms of how many columns it should shift
to the right of the total available.
#### offsetMd
string
The amount to offset the column for md screens, in terms of how many columns it should shift
to the right of the total available.
#### offsetSm
string
The amount to offset the column for sm screens, in terms of how many columns it should shift
to the right of the total available.
#### offsetXl
string
The amount to offset the column for xl screens, in terms of how many columns it should shift
to the right of the total available.
#### offsetXs
string
The amount to offset the column for xs screens, in terms of how many columns it should shift
to the right of the total available.
#### pull
string
The amount to pull the column, in terms of how many columns it should shift to the left of
the total available.
#### pullLg
string
The amount to pull the column for lg screens, in terms of how many columns it should shift
to the left of the total available.
#### pullMd
string
The amount to pull the column for md screens, in terms of how many columns it should shift
to the left of the total available.
#### pullSm
string
The amount to pull the column for sm screens, in terms of how many columns it should shift
to the left of the total available.
#### pullXl
string
The amount to pull the column for xl screens, in terms of how many columns it should shift
to the left of the total available.
#### pullXs
string
The amount to pull the column for xs screens, in terms of how many columns it should shift
to the left of the total available.
#### push
string
The amount to push the column, in terms of how many columns it should shift to the right
of the total available.
#### pushLg
string
The amount to push the column for lg screens, in terms of how many columns it should shift
to the right of the total available.
#### pushMd
string
The amount to push the column for md screens, in terms of how many columns it should shift
to the right of the total available.
#### pushSm
string
The amount to push the column for sm screens, in terms of how many columns it should shift
to the right of the total available.
#### pushXl
string
The amount to push the column for xl screens, in terms of how many columns it should shift
to the right of the total available.
#### pushXs
string
The amount to push the column for xs screens, in terms of how many columns it should shift
to the right of the total available.
#### size
string
The size of the column, in terms of how many columns it should take up out of the total
available. If `"auto"` is passed, the column will be the size of its content.
#### sizeLg
string
The size of the column for lg screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### sizeMd
string
The size of the column for md screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### sizeSm
string
The size of the column for sm screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### sizeXl
string
The size of the column for xl screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### sizeXs
string
The size of the column for xs screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
## Attributes
#### offset
string
The amount to offset the column, in terms of how many columns it should shift to the right
of the total available.
#### offset-lg
string
The amount to offset the column for lg screens, in terms of how many columns it should shift
to the right of the total available.
#### offset-md
string
The amount to offset the column for md screens, in terms of how many columns it should shift
to the right of the total available.
#### offset-sm
string
The amount to offset the column for sm screens, in terms of how many columns it should shift
to the right of the total available.
#### offset-xl
string
The amount to offset the column for xl screens, in terms of how many columns it should shift
to the right of the total available.
#### offset-xs
string
The amount to offset the column for xs screens, in terms of how many columns it should shift
to the right of the total available.
#### pull
string
The amount to pull the column, in terms of how many columns it should shift to the left of
the total available.
#### pull-lg
string
The amount to pull the column for lg screens, in terms of how many columns it should shift
to the left of the total available.
#### pull-md
string
The amount to pull the column for md screens, in terms of how many columns it should shift
to the left of the total available.
#### pull-sm
string
The amount to pull the column for sm screens, in terms of how many columns it should shift
to the left of the total available.
#### pull-xl
string
The amount to pull the column for xl screens, in terms of how many columns it should shift
to the left of the total available.
#### pull-xs
string
The amount to pull the column for xs screens, in terms of how many columns it should shift
to the left of the total available.
#### push
string
The amount to push the column, in terms of how many columns it should shift to the right
of the total available.
#### push-lg
string
The amount to push the column for lg screens, in terms of how many columns it should shift
to the right of the total available.
#### push-md
string
The amount to push the column for md screens, in terms of how many columns it should shift
to the right of the total available.
#### push-sm
string
The amount to push the column for sm screens, in terms of how many columns it should shift
to the right of the total available.
#### push-xl
string
The amount to push the column for xl screens, in terms of how many columns it should shift
to the right of the total available.
#### push-xs
string
The amount to push the column for xs screens, in terms of how many columns it should shift
to the right of the total available.
#### size
string
The size of the column, in terms of how many columns it should take up out of the total
available. If `"auto"` is passed, the column will be the size of its content.
#### size-lg
string
The size of the column for lg screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### size-md
string
The size of the column for md screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### size-sm
string
The size of the column for sm screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### size-xl
string
The size of the column for xl screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
#### size-xs
string
The size of the column for xs screens, in terms of how many columns it should take up out
of the total available. If `"auto"` is passed, the column will be the size of its content.
----------------------------------------------

View File

@ -4,42 +4,38 @@
// Responsive Mixins
// --------------------------------------------------
// Creates a grid with padding
// Creates the shared grid properties
// ---------------------------------------------------------------------------------
@mixin make-grid($padding-width: $grid-padding-width) {
@include padding($padding-width / 2);
@mixin make-grid($paddings: $grid-paddings) {
@include make-breakpoint-padding($paddings);
@include margin-horizontal(auto);
display: flex;
flex-direction: column;
display: block;
width: 100%;
// Remove the padding from the grid and all immediate children columns
&[no-padding] {
// Remove the padding from grid and all immediate children columns
&[no-padding],
&[no-padding] > ion-col {
@include padding(0);
> ion-row > ion-col {
@include padding(0);
}
}
}
// Creates maximum widths for the grid based on screen size
// Creates a fixed width for the grid based on the screen size
// ---------------------------------------------------------------------------------
@mixin make-grid-max-widths($max-widths: $grid-max-widths, $breakpoints: $grid-breakpoints) {
@each $breakpoint, $container-max-width in $max-widths {
@include media-breakpoint-up($breakpoint, $breakpoints) {
width: $container-max-width;
@mixin make-grid-widths($widths: $grid-widths, $breakpoints: $screen-breakpoints) {
max-width: 100%;
@each $breakpoint, $width in $widths {
@include media-breakpoint-up($breakpoint, $breakpoints) {
width: $width;
}
}
}
// Creates a row used to align columns
// Creates a flex row used to align columns
// ---------------------------------------------------------------------------------
@mixin make-row() {
@ -96,12 +92,12 @@
}
// Creates the base column which has shared styles among all columns
// Creates a column
// ---------------------------------------------------------------------------------
@mixin make-column-base($padding-width: $grid-padding-width) {
@mixin make-column($column-paddings: $grid-column-paddings) {
@include make-breakpoint-padding($column-paddings);
@include margin(0);
@include padding($padding-width / 2);
position: relative;
@ -133,126 +129,14 @@
}
// Create an individual column
// Adds padding to the element based on breakpoints
// ---------------------------------------------------------------------------------
@mixin make-column($size, $columns: $grid-columns) {
flex: 0 0 percentage($size / $columns);
width: percentage($size / $columns);
// Add a `max-width` to ensure content within each column does not blow out
// the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
// do not appear to require this.
max-width: percentage($size / $columns);
}
// Adds padding to the column
// ---------------------------------------------------------------------------------
@mixin make-column-padding($padding-widths: $grid-padding-widths) {
@each $breakpoint in map-keys($padding-widths) {
@mixin make-breakpoint-padding($paddings) {
@each $breakpoint in map-keys($paddings) {
@include media-breakpoint-up($breakpoint) {
$padding-width: map-get($padding-widths, $breakpoint);
@include padding($padding-width / 2);
}
}
}
// Offset the column using margin-start
// ---------------------------------------------------------------------------------
@mixin make-column-offset($size, $columns: $grid-columns) {
@include margin-horizontal(percentage($size / $columns), null);
}
// Push the column using left
// ---------------------------------------------------------------------------------
@mixin make-column-push($size, $columns: $grid-columns) {
@include position(null, null, null, if($size > 0, percentage($size / $columns), auto));
}
// Pull the column using right
// ---------------------------------------------------------------------------------
@mixin make-column-pull($size, $columns: $grid-columns) {
@include position(null, if($size > 0, percentage($size / $columns), auto), null, null);
}
// Determine which modifier to add
// ---------------------------------------------------------------------------------
@mixin make-column-modifier($type, $size, $columns) {
// Work around the lack of dynamic mixin @include support (https://github.com/sass/sass/issues/626)
@if $type == push {
@include make-column-push($size, $columns);
} @else if $type == pull {
@include make-column-pull($size, $columns);
} @else if $type == offset {
@include make-column-offset($size, $columns);
}
}
// Create the responsive grid columns
// --------------------------------------------------
@mixin make-grid-columns($columns: $grid-columns, $padding-widths: $grid-padding-widths, $breakpoints: $grid-breakpoints) {
@each $breakpoint in map-keys($breakpoints) {
$infix: breakpoint-infix($breakpoint, $breakpoints);
// Allow columns to stretch full width below their breakpoints
@for $i from 1 through $columns {
[col#{$infix}-#{$i}] {
@include make-column-padding($padding-widths);
}
}
[col#{$infix}] {
@include make-column-padding($padding-widths);
}
@include media-breakpoint-up($breakpoint, $breakpoints) {
// Provide basic `[col-{bp}]` attributes for equal-width flexbox columns
[col#{$infix}] {
flex-basis: 0;
flex-grow: 1;
max-width: 100%;
}
[col#{$infix}-auto] {
flex: 0 0 auto;
width: auto;
}
@for $i from 1 through $columns {
[col#{$infix}-#{$i}] {
@include make-column($i, $columns);
}
}
@each $modifier in (pull, push) {
@for $i from 0 through $columns {
[#{$modifier}#{$infix}-#{$i}] {
@include make-column-modifier($modifier, $i, $columns)
}
}
}
// `$columns - 1` because offsetting by the width of an entire row isn't possible
@for $i from 0 through ($columns - 1) {
@if not ($infix == "" and $i == 0) { // Avoid emitting useless [offset-xs-0]
[offset#{$infix}-#{$i}] {
@include make-column-modifier(offset, $i, $columns)
}
}
}
$padding: map-get($paddings, $breakpoint);
@include padding($padding);
}
}
}

View File

@ -5,24 +5,16 @@
ion-grid {
@include make-grid();
&[fixed] {
@include make-grid-max-widths();
}
}
// Row
// --------------------------------------------------
.grid-fixed {
@include make-grid-widths();
}
ion-row {
@include make-row();
}
// Columns
// --------------------------------------------------
ion-col {
@include make-column-base();
@include make-column();
}
@include make-grid-columns();

View File

@ -1,4 +1,4 @@
import { Component } from '@stencil/core';
import { Component, Prop } from '@stencil/core';
@Component({
@ -11,4 +11,17 @@ import { Component } from '@stencil/core';
theme: 'grid'
}
})
export class Grid {}
export class Grid {
/**
* If true, the grid will have a fixed width based on the screen size. Defaults to `false`.
*/
@Prop() fixed?: boolean;
hostData() {
return {
class: {
'grid-fixed': this.fixed
}
};
}
}

View File

@ -1,64 +1,43 @@
@import "../../themes/ionic.globals";
@import "./grid.mixins";
// Grid
// --------------------------------------------------
// Using flexbox for the grid, originally inspired by Philip Walton:
// http://philipwalton.github.io/solved-by-flexbox/demos/grids/
// Column layout based on the Bootstrap grid system:
// http://v4-alpha.getbootstrap.com/layout/grid/
// Grid Breakpoints
// --------------------------------------------------
/// @prop - The minimum dimensions at which your layout will change,
/// adapting to different screen sizes, for use in media queries
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
/// @prop - Width of the grid for different screen sizes
/// when fixed is enabled
$grid-widths: (
xs: var(--ion-grid-width-xs, var(--ion-grid-width, 100%)),
sm: var(--ion-grid-width-sm, var(--ion-grid-width, 540px)),
md: var(--ion-grid-width-md, var(--ion-grid-width, 720px)),
lg: var(--ion-grid-width-lg, var(--ion-grid-width, 960px)),
xl: var(--ion-grid-width-xl, var(--ion-grid-width, 1140px))
) !default;
/// @prop - The padding for the grid
$grid-padding: var(--ion-grid-padding, 5px) !default;
// Grid Containers
// --------------------------------------------------
/// @prop - Maximum width of the grid for different screen sizes
$grid-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1140px
/// @prop - The padding for the grid at different breakpoints
$grid-paddings: (
xs: var(--ion-grid-padding-xs, $grid-padding),
sm: var(--ion-grid-padding-sm, $grid-padding),
md: var(--ion-grid-padding-md, $grid-padding),
lg: var(--ion-grid-padding-lg, $grid-padding),
xl: var(--ion-grid-padding-xl, $grid-padding)
) !default;
// Grid Columns
// --------------------------------------------------
/// @prop - Number of columns for the grid
$grid-columns: 12 !default;
/// @prop - The padding for the grid column
$grid-column-padding: var(--ion-grid-column-padding, 5px) !default;
/// @prop - Total width of the padding for the grid
$grid-padding-width: 10px !default;
/// @prop - Padding for the columns for different screen sizes
$grid-padding-widths: (
xs: $grid-padding-width,
sm: $grid-padding-width,
md: $grid-padding-width,
lg: $grid-padding-width,
xl: $grid-padding-width
/// @prop - The padding for the column at different breakpoints
$grid-column-paddings: (
xs: var(--ion-grid-column-padding-xs, $grid-column-padding),
sm: var(--ion-grid-column-padding-sm, $grid-column-padding),
md: var(--ion-grid-column-padding-md, $grid-column-padding),
lg: var(--ion-grid-column-padding-lg, $grid-column-padding),
xl: var(--ion-grid-column-padding-xl, $grid-column-padding)
) !default;
// Check that the Sass maps are declared correctly
// --------------------------------------------------
@include assert-ascending($grid-breakpoints, "$grid-breakpoints");
@include assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints");
@include assert-ascending($grid-max-widths, "$grid-max-widths");

View File

@ -32,6 +32,17 @@ $font-path: "/dist/fonts" !default;
$hairlines-width: .55px !default;
// The minimum dimensions at which your layout will change,
// adapting to different screen sizes, for use in media queries
$screen-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
) !default;
// Z-Index
// --------------------------------------------------
// Grouped by elements which would be siblings

View File

@ -45,34 +45,11 @@
}
// Check that the given map values are in ascending order
// ---------------------------------------------------------------------------------
// Get the key from a map based on the index
@function index-to-key($map, $index) {
$keys: map-keys($map);
@mixin assert-ascending($map, $map-name) {
$prev-key: null;
$prev-num: null;
@each $key, $num in $map {
@if $prev-num == null {
// Do nothing
} @else if not comparable($prev-num, $num) {
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
} @else if $prev-num >= $num {
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
}
$prev-key: $key;
$prev-num: $num;
}
}
// Check that the first value in the given map starts at 0
// ---------------------------------------------------------------------------------
@mixin assert-starts-at-zero($map, $map-name) {
$values: map-values($map);
$first-value: nth($values, 1);
@if $first-value != 0 {
@warn "First value in `#{$map-name}` must start at 0, but starts at #{$first-value}.";
}
@return nth($keys, $index);
}
@ -85,7 +62,7 @@
//
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
//
// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
// The map defined in the `$screen-breakpoints` global variable is used as the `$breakpoints` argument by default.
// ---------------------------------------------------------------------------------
@ -93,9 +70,10 @@
//
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 576px
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
@function breakpoint-min($name, $breakpoints: $screen-breakpoints) {
$min: map-get($breakpoints, $name);
@return if($min != 0, $min, null);
@return if($name != index-to-key($breakpoints, 1), $min, null);
}
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
@ -105,13 +83,13 @@
// "" (Returns a blank string)
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// "-sm"
@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
@function breakpoint-infix($name, $breakpoints: $screen-breakpoints) {
@return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
}
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
// Makes the @content apply to the given breakpoint and wider.
@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
@mixin media-breakpoint-up($name, $breakpoints: $screen-breakpoints) {
$min: breakpoint-min($name, $breakpoints);
@if $min {
@media (min-width: $min) {
@ -130,7 +108,7 @@
// md
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
// md
@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
@function breakpoint-next($name, $breakpoints: $screen-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
$n: index($breakpoint-names, $name);
@return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
}
@ -140,14 +118,14 @@
//
// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 767px
@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
@function breakpoint-max($name, $breakpoints: $screen-breakpoints) {
$next: breakpoint-next($name, $breakpoints);
@return if($next, breakpoint-min($next, $breakpoints) - 1px, null);
}
// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
// Makes the @content apply to the given breakpoint and narrower.
@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
@mixin media-breakpoint-down($name, $breakpoints: $screen-breakpoints) {
$max: breakpoint-max($name, $breakpoints);
@if $max {
@media (max-width: $max) {
@ -206,19 +184,6 @@
}
}
// If deprecated variable exists, use it, otherwise, use alternative
// @param {string} $property - property to default
// @param {string} $variable-name - the deprecated variable's name
// @param {string} $variable - the deprecated variable
// ----------------------------------------------------------
@mixin deprecated-variable($property, $variable-name, $variable) {
@if $variable == null {
@content;
} @else {
@warn "you are using a deprecated variable: #{$variable-name}";
#{$property}: $variable;
}
}
// SVG Background Image Mixin
// @param {string} $svg

22
core/src/utils/media.ts Normal file
View File

@ -0,0 +1,22 @@
// Media Query Functions
// -----------------------------------------------------
export const SIZE_TO_MEDIA: any = {
'xs': '(min-width: 0px)',
'sm': '(min-width: 576px)',
'md': '(min-width: 768px)',
'lg': '(min-width: 992px)',
'xl': '(min-width: 1200px)',
};
// Check if the window matches the media query
// at the breakpoint passed
// e.g. isMatch('sm') => true if screen width exceeds 576px
export function isMatch(breakpoint: string) {
const mediaQuery = SIZE_TO_MEDIA[breakpoint];
if (mediaQuery && matchMedia(mediaQuery)) {
const media = matchMedia(mediaQuery);
return media.matches;
}
return false;
}

View File

@ -1,4 +1,5 @@
import { Config, Mode } from '../interface';
import { SIZE_TO_MEDIA } from './media';
import { isAndroid, isCordova, isElectron, isIOS, isIpad, isIphone, isPhablet, isTablet, matchMedia } from './platform';
export function updateTestResults(displayWhen: DisplayWhen) {
@ -84,14 +85,6 @@ export function isPortrait(win: Window): boolean {
}
const SIZE_TO_MEDIA: any = {
'xs': '(min-width: 0px)',
'sm': '(min-width: 576px)',
'md': '(min-width: 768px)',
'lg': '(min-width: 992px)',
'xl': '(min-width: 1200px)',
};
// order from most specifc to least specific
export const PLATFORM_CONFIGS: PlatformConfig[] = [
@ -152,4 +145,3 @@ export interface DisplayWhen {
platform?: string;
size?: string;
}