diff --git a/packages/core/src/components/show-when/readme.md b/packages/core/src/components/show-when/readme.md new file mode 100644 index 0000000000..55cc543fad --- /dev/null +++ b/packages/core/src/components/show-when/readme.md @@ -0,0 +1,65 @@ +# ion-show-when + + + + + + +## Properties + +#### mediaQuery + +string + + +#### mode + +string + + +#### or + +boolean + + +#### platform + +string + + +#### size + +string + + +## Attributes + +#### media-query + +string + + +#### mode + +string + + +#### or + +boolean + + +#### platform + +string + + +#### size + +string + + + +---------------------------------------------- + +*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/core/src/components/show-when/show-when.scss b/packages/core/src/components/show-when/show-when.scss new file mode 100644 index 0000000000..15b3bd1d65 --- /dev/null +++ b/packages/core/src/components/show-when/show-when.scss @@ -0,0 +1,7 @@ +ion-show-when.show-content { + display: block; +} + +ion-show-when.hide-content { + display: none !important; +} \ No newline at end of file diff --git a/packages/core/src/components/show-when/show-when.tsx b/packages/core/src/components/show-when/show-when.tsx new file mode 100644 index 0000000000..4f674e7b34 --- /dev/null +++ b/packages/core/src/components/show-when/show-when.tsx @@ -0,0 +1,46 @@ +import { Component, Element, Prop } from '@stencil/core'; +import { Config, PlatformConfig } from '../../index'; + +import { + DisplayWhen, + componentWillLoadImpl, +} from '../../utils/show-hide-when-utils'; + +@Component({ + tag: 'ion-show-when', + styleUrl: './show-when.scss' +}) +export class ShowWhen implements DisplayWhen { + + @Element() element: HTMLElement; + @Prop({ context: 'config' }) config: Config; + @Prop({ context: 'platforms' }) calculatedPlatforms: PlatformConfig[]; + + @Prop() mediaQuery: string = null; + @Prop() size: string = null; + @Prop() mode: string = null; + @Prop() platform: string = null; + @Prop() or = false; + + passesTest = false; + + componentWillLoad() { + return componentWillLoadImpl(this); + } + + hostData() { + return { + class: { + 'show-content': this.passesTest, + 'hide-content': !this.passesTest + } + }; + } + + render() { + return + } +} + + + diff --git a/packages/core/src/components/show-when/test/basic/index.html b/packages/core/src/components/show-when/test/basic/index.html new file mode 100644 index 0000000000..35fa1b4c0a --- /dev/null +++ b/packages/core/src/components/show-when/test/basic/index.html @@ -0,0 +1,96 @@ + + + + + + Show When - Basic + + + + + + + + + + Show when - Basic + + + + + +

Mode Tests

+ +
Shows on MD, iOS
+
+ + +
Shows on MD only
+
+ + +
Shows on iOS only
+
+ +

Platform Tests

+ + +
Render on Android and iOS
+
+ + +
Only render on iOS
+
+ + +
Only render on Android
+
+ + +
Only render on ipad
+
+ + +
Only render on phablet
+
+ + +
Only render on phone
+
+ +

Size Tests

+ +
Only render on xs
+
+ + +
Only render on sm
+
+ + +
Only render on md
+
+ + +
Only render on lg
+
+ + +
Only render on xl
+
+ + +
Only render on XS or m
+
+ +
+ +
+
+ + + + + diff --git a/packages/core/src/utils/show-hide-when-utils.ts b/packages/core/src/utils/show-hide-when-utils.ts new file mode 100644 index 0000000000..e0f6d2b3b4 --- /dev/null +++ b/packages/core/src/utils/show-hide-when-utils.ts @@ -0,0 +1,95 @@ +import { Config, PlatformConfig } from '../index'; + +export function componentWillLoadImpl(displayWhen: DisplayWhen) { + displayWhen.passesTest = getTestResult(displayWhen); +} + +export function isPlatformMatch(platforms: string[], multiPlatformString: string) { + const userProvidedPlatforms = multiPlatformString.replace(/\s/g, '').split(','); + for (const userProvidedPlatform of userProvidedPlatforms) { + for (const platform of platforms) { + if (userProvidedPlatform === platform) { + return true; + } + } + } + return false; +} + +export function isModeMatch(config: Config, multiModeString: string) { + // you can only ever be in one mode, so if an entry from the list matches, return true + const modes = multiModeString.replace(/\s/g, '').split(','); + for (const mode of modes) { + if (config.get('mode') === mode) { + return true; + } + } + return false; +} + + +export function isMediaQueryMatch(mediaQuery: string) { + return window.matchMedia(mediaQuery).matches; +} + +export function isSizeMatch(multiSizeString: string) { + const sizes = multiSizeString.replace(/\s/g, '').split(','); + + const booleans = sizes.map(size => { + const mediaQuery = sizeToMediaQueryMap.get(size); + if (!mediaQuery) { + return false; + } + + return window.matchMedia(mediaQuery).matches; + }); + return booleans.reduce((prev, current) => prev || current); +} + +export function getTestResult(displayWhen: DisplayWhen) { + const resultsToConsider: boolean[] = []; + if (displayWhen.mediaQuery) { + resultsToConsider.push(isMediaQueryMatch(displayWhen.mediaQuery)); + } + if (displayWhen.size) { + resultsToConsider.push(isSizeMatch(displayWhen.size)); + } + if (displayWhen.mode) { + resultsToConsider.push(isModeMatch(displayWhen.config, displayWhen.mode)); + } + if (displayWhen.platform) { + const platformNames = displayWhen.calculatedPlatforms.map(platformConfig => platformConfig.name); + resultsToConsider.push(isPlatformMatch(platformNames, displayWhen.platform)); + } + + if (!resultsToConsider.length) { + return true; + } + if (resultsToConsider.length === 1) { + return resultsToConsider[0]; + } + return resultsToConsider.reduce((prev: boolean, current: boolean) => { + if (displayWhen.or) { + return prev || current; + } + return prev && current; + }); +} + +const sizeToMediaQueryMap = new Map(); +sizeToMediaQueryMap.set('xs', '(min-width: 0px)'); +sizeToMediaQueryMap.set('sm', '(min-width: 576px)'); +sizeToMediaQueryMap.set('md', '(min-width: 768px)'); +sizeToMediaQueryMap.set('lg', '(min-width: 992px)'); +sizeToMediaQueryMap.set('xl', '(min-width: 1200px)'); + +export interface DisplayWhen { + calculatedPlatforms: PlatformConfig[]; + config: Config; + mediaQuery: string; + mode: string; + or: boolean; + passesTest: boolean; + platform: string; + size: string; +} \ No newline at end of file