mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 13:32:54 +08:00
Merge branch 'mono-refactor' into core/overlay
This commit is contained in:
38
packages/core/package-lock.json
generated
38
packages/core/package-lock.json
generated
@ -1,34 +1,34 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "0.0.2-3",
|
||||
"version": "0.0.2-4",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@stencil/core": {
|
||||
"version": "0.0.4-4",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.0.4-4.tgz",
|
||||
"integrity": "sha512-fcFq1gNxrpIvZu1M7J+9E8mT7Rd2LW2nhKdVkJCxYdQs7UErVyn5ksY0Ckqgvsn0wOPaymUoeNkYAcG/L7sTRQ==",
|
||||
"version": "0.0.4-11",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.0.4-11.tgz",
|
||||
"integrity": "sha512-CJo2o3RAnzA84AZ0GXMH0TANZR/z6JH1EKd+hnXwnu62CH+KZ37zjEXrMy5tsRCJ1nfqSwS6BOwAJtV1+xoeVA==",
|
||||
"requires": {
|
||||
"chalk": "1.1.3",
|
||||
"chokidar": "1.7.0",
|
||||
"clean-css": "4.1.7",
|
||||
"jsdom": "11.1.0",
|
||||
"node-fetch": "1.7.1",
|
||||
"node-fetch": "1.7.2",
|
||||
"node-sass": "4.5.3",
|
||||
"rollup": "0.41.4",
|
||||
"rollup-plugin-commonjs": "8.1.0",
|
||||
"rollup-plugin-node-resolve": "3.0.0",
|
||||
"typescript": "2.4.0",
|
||||
"typescript": "2.5.0-dev.20170808",
|
||||
"uglify-es": "3.0.27"
|
||||
}
|
||||
},
|
||||
"@stencil/dev-server": {
|
||||
"version": "0.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/dev-server/-/dev-server-0.0.11.tgz",
|
||||
"integrity": "sha512-ZNPsLAxhP5e5SUdEpPZm/mlcRTDHSGctY9CsChncisMm0zjYeKNQFqel+ZKAO8sIdmikQDyCDuZwq2JEMneTwg==",
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/dev-server/-/dev-server-0.0.14.tgz",
|
||||
"integrity": "sha512-sdnuZ1Tgg1I8DsXhkzyZjrwdFkQvI0HrXQXcHARZYeV6CeIJS51+q9EbvoMBHsUBuqPxgTgR8GHySw/DfZY5UQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "2.0.1",
|
||||
"chalk": "2.1.0",
|
||||
"chokidar": "1.7.0",
|
||||
"ecstatic": "2.2.1",
|
||||
"lodash.debounce": "4.0.8",
|
||||
@ -46,9 +46,9 @@
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz",
|
||||
"integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
|
||||
"integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.0",
|
||||
@ -2141,9 +2141,9 @@
|
||||
"integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz",
|
||||
"integrity": "sha512-j8XsFGCLw79vWXkZtMSmmLaOk9z5SQ9bV/tkbZVCqvgwzrjAGq66igobLofHtF63NvMTp2WjytpsNTGKa+XRIQ==",
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.2.tgz",
|
||||
"integrity": "sha512-xZZUq2yDhKMIn/UgG5q//IZSNLJIwW2QxS14CNH5spuiXkITM2pUitjdq58yLSaU7m4M0wBNaM2Gh/ggY4YJig==",
|
||||
"requires": {
|
||||
"encoding": "0.1.12",
|
||||
"is-stream": "1.1.0"
|
||||
@ -2959,9 +2959,9 @@
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.0.tgz",
|
||||
"integrity": "sha1-rvWo1AS+ujatM5q/B53d3/+6ht0="
|
||||
"version": "2.5.0-dev.20170808",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.0-dev.20170808.tgz",
|
||||
"integrity": "sha512-Gb+2vCDs47CMtRzpoc41Uia4UDV4biDYZo9Z5nTwINftcI96FecFCQgJQAMLF8G4bKR4pwKmOuiSN1JyGInN3A=="
|
||||
},
|
||||
"uglify-es": {
|
||||
"version": "3.0.27",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "0.0.2-3",
|
||||
"version": "0.0.2-4",
|
||||
"description": "Base components for Ionic",
|
||||
"main": "dist/collection/index.js",
|
||||
"types": "dist/collection/index.d.ts",
|
||||
@ -10,16 +10,16 @@
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"@stencil/core": "^0.0.4-3"
|
||||
"@stencil/core": "0.0.4-14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@stencil/dev-server": "^0.0.11",
|
||||
"@stencil/utils": "^0.0.4"
|
||||
"@stencil/dev-server": "latest",
|
||||
"@stencil/utils": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "stencil build",
|
||||
"dev": "sd concurrent \"stencil build --dev --watch\" \"stencil-dev-server\"",
|
||||
"publish": "../../node_modules/.bin/np --any-branch",
|
||||
"publish": "npm run build && node scripts/publish.js && node scripts/publish.js && ../../node_modules/.bin/np --any-branch",
|
||||
"test": "(jest --no-cache || true)"
|
||||
},
|
||||
"author": "Ionic Team",
|
||||
|
17
packages/core/scripts/publish.js
Normal file
17
packages/core/scripts/publish.js
Normal file
@ -0,0 +1,17 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
|
||||
var DIST = path.join(__dirname, '../dist/collection');
|
||||
var SRC = path.join(__dirname, '../src');
|
||||
var INDEX_JS_DIST = path.join(DIST, 'index.js');
|
||||
var INDEX_DTS_SRC = path.join(SRC, 'index.d.ts');
|
||||
var INDEX_DTS_DIST = path.join(DIST, 'index.d.ts');
|
||||
|
||||
console.log('publish: create', INDEX_JS_DIST);
|
||||
fs.writeFileSync(INDEX_JS_DIST, '');
|
||||
|
||||
|
||||
console.log('publish: create', INDEX_DTS_DIST);
|
||||
var srcIndexDTS = fs.readFileSync(INDEX_DTS_SRC, 'utf-8');
|
||||
fs.writeFileSync(INDEX_DTS_DIST, srcIndexDTS);
|
@ -1,5 +1,7 @@
|
||||
import { Component, Element, Prop, CssClassMap } from '@stencil/core';
|
||||
|
||||
import { getElementClassObject } from '../../utils/theme';
|
||||
|
||||
/**
|
||||
* @name Button
|
||||
* @module ionic
|
||||
@ -178,7 +180,9 @@ export class Button {
|
||||
|
||||
const decorator = (this.strong ? 'strong' : null);
|
||||
|
||||
const buttonClasses: CssClassMap = []
|
||||
const hostClasses = getElementClassObject(this.el.classList);
|
||||
|
||||
const elementClasses: CssClassMap = []
|
||||
.concat(
|
||||
getButtonClassList(buttonType, mode),
|
||||
getClassList(buttonType, shape, mode),
|
||||
@ -186,8 +190,7 @@ export class Button {
|
||||
getClassList(buttonType, size, mode),
|
||||
getClassList(buttonType, decorator, mode),
|
||||
getStyleClassList(mode, this.color, buttonType, this.outline, this.clear, this.solid),
|
||||
getItemClassList(this.itemButton, size),
|
||||
getElementClassList(this.el.classList)
|
||||
getItemClassList(this.itemButton, size)
|
||||
)
|
||||
.reduce((prevValue, cssClass) => {
|
||||
prevValue[cssClass] = true;
|
||||
@ -196,6 +199,11 @@ export class Button {
|
||||
|
||||
const TagType = this.href ? 'a' : 'button';
|
||||
|
||||
const buttonClasses = {
|
||||
...hostClasses,
|
||||
...elementClasses
|
||||
}
|
||||
|
||||
return (
|
||||
<TagType class={buttonClasses} disabled={this.disabled}>
|
||||
<span class='button-inner'>
|
||||
@ -292,14 +300,3 @@ function getStyleClassList(mode: string, color: string, buttonType: string, outl
|
||||
function getItemClassList(itemButton: boolean, size: string) {
|
||||
return itemButton && !size ? ['item-button'] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element classes to add to the child element
|
||||
*/
|
||||
function getElementClassList(elmClassList: DOMTokenList) {
|
||||
const classList: string[] = [];
|
||||
for (var i = 0; i < elmClassList.length; i++) {
|
||||
classList.push(elmClassList.item(i));
|
||||
}
|
||||
return classList;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Component, CssClassMap, Element, Prop } from '@stencil/core';
|
||||
|
||||
import { getElementClassObject } from '../../utils/theme';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-chip-button',
|
||||
@ -71,25 +72,14 @@ export class ChipButton {
|
||||
return classList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
* Get the element classes to add to the child element
|
||||
*/
|
||||
private getElementClassList() {
|
||||
let classList = [].concat(
|
||||
this.el.className.length ? this.el.className.split(' ') : []
|
||||
);
|
||||
|
||||
return classList;
|
||||
}
|
||||
|
||||
render() {
|
||||
const buttonType = 'chip-button';
|
||||
|
||||
var buttonClasses: CssClassMap = []
|
||||
const hostClasses = getElementClassObject(this.el.classList);
|
||||
|
||||
const elementClasses: CssClassMap = []
|
||||
.concat(
|
||||
this.getButtonClassList(buttonType, this.mode),
|
||||
this.getElementClassList(),
|
||||
this.getStyleClassList(buttonType)
|
||||
)
|
||||
.reduce((prevValue, cssClass) => {
|
||||
@ -99,6 +89,11 @@ export class ChipButton {
|
||||
|
||||
const TagType = this.href ? 'a' : 'button';
|
||||
|
||||
const buttonClasses = {
|
||||
...hostClasses,
|
||||
...elementClasses
|
||||
}
|
||||
|
||||
return (
|
||||
<TagType class={buttonClasses} disabled={this.disabled}>
|
||||
<span class='button-inner'>
|
||||
|
@ -76,7 +76,7 @@
|
||||
|
||||
<ion-chip id="chip1">
|
||||
<ion-label>Default</ion-label>
|
||||
<ion-chip-button clear onclick="del('chip1')">
|
||||
<ion-chip-button clear onclick="del('chip1')" class="my-custom-chip">
|
||||
<ion-icon name="close-circle"></ion-icon>
|
||||
</ion-chip-button>
|
||||
</ion-chip>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Component, Element, Prop } from '@stencil/core';
|
||||
import { Config, Scroll, ScrollDetail } from '../../index';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
import { createThemedClasses, getElementClassObject } from '../../utils/theme';
|
||||
import { getParentElement, getToolbarHeight } from '../../utils/helpers';
|
||||
|
||||
|
||||
@ -103,11 +103,18 @@ export class Content {
|
||||
if (this.ionScrollEnd) {
|
||||
props['ionScrollEnd'] = this.ionScrollEnd.bind(this);
|
||||
}
|
||||
|
||||
const themedClasses = createThemedClasses(this.mode, this.color, 'content');
|
||||
themedClasses['statusbar-padding'] = this.config.getBoolean('statusbarPadding');
|
||||
const hostClasses = getElementClassObject(this.el.classList);
|
||||
|
||||
const scrollClasses = {
|
||||
...themedClasses,
|
||||
...hostClasses,
|
||||
'statusbar-padding': this.config.getBoolean('statusbarPadding')
|
||||
}
|
||||
|
||||
return (
|
||||
<ion-scroll style={scrollStyle} props={props} class={themedClasses}>
|
||||
<ion-scroll style={scrollStyle} props={props} class={scrollClasses}>
|
||||
<slot></slot>
|
||||
</ion-scroll>
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, Element, CssClassMap, Method, Prop, State } from '@stencil/core';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
import { createThemedClasses, getElementClassObject } from '../../utils/theme';
|
||||
|
||||
|
||||
/**
|
||||
@ -110,18 +110,6 @@ export class FabButton {
|
||||
this.setActiveLists(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
* Get the element classes to add to the child element
|
||||
*/
|
||||
getElementClassList() {
|
||||
let classList = [].concat(
|
||||
this.el.className.length ? this.el.className.split(' ') : []
|
||||
);
|
||||
|
||||
return classList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
* Get the classes for fab buttons in lists
|
||||
@ -164,10 +152,10 @@ export class FabButton {
|
||||
|
||||
render() {
|
||||
const themedClasses = createThemedClasses(this.mode, this.color, 'fab');
|
||||
const hostClasses = getElementClassObject(this.el.classList);
|
||||
|
||||
var fabClasses: CssClassMap = []
|
||||
const elementClasses: CssClassMap = []
|
||||
.concat(
|
||||
this.getElementClassList(),
|
||||
this.getFabListClassList(),
|
||||
this.getFabActiveClassList(),
|
||||
this.getFabShowClassList()
|
||||
@ -179,7 +167,11 @@ export class FabButton {
|
||||
|
||||
const TagType = this.href ? 'a' : 'button';
|
||||
|
||||
fabClasses = Object.assign(fabClasses, themedClasses);
|
||||
const fabClasses = {
|
||||
...themedClasses,
|
||||
...hostClasses,
|
||||
...elementClasses
|
||||
}
|
||||
|
||||
return (
|
||||
<TagType class={fabClasses} onClick={this.clickedFab.bind(this)} disabled={this.disabled}>
|
||||
|
@ -19,7 +19,7 @@ export class Icon {
|
||||
/**
|
||||
* @input {string} Specifies the label to use for accessibility. Defaults to the icon name.
|
||||
*/
|
||||
@State() ariaLabel: string = '';
|
||||
@Prop() ariaLabel: string = '';
|
||||
|
||||
/**
|
||||
* @input {string} Specifies which icon to use. The appropriate icon will be used based on the mode.
|
||||
@ -38,20 +38,13 @@ export class Icon {
|
||||
@Prop() md: string = '';
|
||||
|
||||
|
||||
@State() svgContent: string = null;
|
||||
@Prop({ context: 'isServer'}) private isServer: boolean;
|
||||
|
||||
|
||||
getSvgUrl() {
|
||||
const iconName = this.iconName;
|
||||
if (iconName !== null) {
|
||||
return `${publicPath}svg/${iconName}.svg`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@State() private svgContent: string = null;
|
||||
|
||||
|
||||
get iconName() {
|
||||
private get iconName() {
|
||||
// if no name was passed set iconName to null
|
||||
if (!this.name) {
|
||||
return null;
|
||||
@ -117,21 +110,63 @@ export class Icon {
|
||||
}
|
||||
|
||||
|
||||
static loadSvgContent(svgUrl: string, callback: {(loadedSvgContent: string): void}) {
|
||||
render() {
|
||||
if (this.isServer) {
|
||||
return <div class="icon-inner">{/* ssr */}</div>;
|
||||
}
|
||||
|
||||
const svgUrl = getSvgUrl(this.iconName);
|
||||
if (!svgUrl) {
|
||||
// we don't have good data
|
||||
return <div class="icon-inner">{/* invalid svg */}</div>;
|
||||
}
|
||||
|
||||
const svgContent = svgContents[svgUrl];
|
||||
if (svgContent === this.svgContent) {
|
||||
// we've already loaded up this svg at one point
|
||||
// and the svg content we've loaded and assigned checks out
|
||||
// render this svg!!
|
||||
return <div class="icon-inner" innerHTML={svgContent}></div>;
|
||||
}
|
||||
|
||||
// haven't loaded this svg yet
|
||||
// start the request
|
||||
loadSvgContent(svgUrl, loadedSvgContent => {
|
||||
// we're finished loading the svg content!
|
||||
// set to this.svgContent so we do another render
|
||||
this.svgContent = loadedSvgContent;
|
||||
});
|
||||
|
||||
// actively requesting the svg, so let's just render a div for now
|
||||
return <div class="icon-inner">{/* loading svg */}</div>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function getSvgUrl(iconName: string) {
|
||||
if (iconName !== null) {
|
||||
return `${publicPath}svg/${iconName}.svg`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function loadSvgContent(svgUrl: string, callback: {(loadedSvgContent: string): void}) {
|
||||
// static since all IonIcons use this same function and pointing at global/shared data
|
||||
// passed in callback will have instance info
|
||||
|
||||
// add to the list of callbacks to fiure when this url is finished loading
|
||||
IonIcon.loadCallbacks[svgUrl] = IonIcon.loadCallbacks[svgUrl] || [];
|
||||
IonIcon.loadCallbacks[svgUrl].push(callback);
|
||||
loadCallbacks[svgUrl] = loadCallbacks[svgUrl] || [];
|
||||
loadCallbacks[svgUrl].push(callback);
|
||||
|
||||
if (IonIcon.activeRequests[svgUrl]) {
|
||||
if (activeRequests[svgUrl]) {
|
||||
// already requesting this url, don't bother again kicking off another
|
||||
return;
|
||||
}
|
||||
|
||||
// add this url to our list of active requests
|
||||
IonIcon.activeRequests[svgUrl] = true;
|
||||
activeRequests[svgUrl] = true;
|
||||
|
||||
// kick off the request for the external svg file
|
||||
const xhr = new XMLHttpRequest();
|
||||
@ -139,7 +174,7 @@ export class Icon {
|
||||
// awesome, we've finished loading the svg file
|
||||
|
||||
// remove this url from the active requests
|
||||
delete IonIcon.activeRequests[svgUrl];
|
||||
delete activeRequests[svgUrl];
|
||||
|
||||
// this response is the content of the svg file we're looking for
|
||||
let svgContent = this.responseText;
|
||||
@ -151,17 +186,17 @@ export class Icon {
|
||||
}
|
||||
|
||||
// cache the svg content in the global IonIcon constant
|
||||
IonIcon.svgContents[svgUrl] = svgContent;
|
||||
svgContents[svgUrl] = svgContent;
|
||||
|
||||
// find any callbacks waiting on this url
|
||||
const svgLoadCallbacks = IonIcon.loadCallbacks[svgUrl];
|
||||
const svgLoadCallbacks = loadCallbacks[svgUrl];
|
||||
if (svgLoadCallbacks) {
|
||||
// loop through all the callbacks that are waiting on the svg content
|
||||
for (var i = 0; i < svgLoadCallbacks.length; i++) {
|
||||
svgLoadCallbacks.forEach(cb => {
|
||||
// fire off this callback which was provided by an instance
|
||||
svgLoadCallbacks[i](svgContent);
|
||||
}
|
||||
delete IonIcon.loadCallbacks[svgUrl];
|
||||
cb(svgContent);
|
||||
});
|
||||
delete loadCallbacks[svgUrl];
|
||||
}
|
||||
});
|
||||
|
||||
@ -176,45 +211,6 @@ export class Icon {
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const svgUrl = this.getSvgUrl();
|
||||
if (!svgUrl) {
|
||||
// we don't have good data
|
||||
return <div class="icon-inner">{/* invalid svg */}</div>;
|
||||
}
|
||||
|
||||
const svgContent = IonIcon.svgContents[svgUrl];
|
||||
if (svgContent === this.svgContent) {
|
||||
// we've already loaded up this svg at one point
|
||||
// and the svg content we've loaded and assigned checks out
|
||||
// render this svg!!
|
||||
return <div class="icon-inner" innerHTML={svgContent}></div>;
|
||||
}
|
||||
|
||||
// haven't loaded this svg yet
|
||||
// start the request
|
||||
Icon.loadSvgContent(svgUrl, loadedSvgContent => {
|
||||
// we're finished loading the svg content!
|
||||
// set to this.svgContent so we do another render
|
||||
this.svgContent = loadedSvgContent;
|
||||
});
|
||||
|
||||
// actively requesting the svg, so let's just render a div for now
|
||||
return <div class="icon-inner">{/* loading svg */}</div>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
const IonIcon: GlobalIonIcon = {
|
||||
activeRequests: {},
|
||||
loadCallbacks: [] as any,
|
||||
svgContents: {}
|
||||
};
|
||||
|
||||
|
||||
interface GlobalIonIcon {
|
||||
activeRequests: {[url: string]: boolean};
|
||||
loadCallbacks: {[url: string]: {(loadedSvgContent: string): void}[]};
|
||||
svgContents: {[url: string]: string};
|
||||
}
|
||||
const activeRequests: {[url: string]: boolean} = {};
|
||||
const loadCallbacks: {[url: string]: {(loadedSvgContent: string): void}[]} = [] as any;
|
||||
const svgContents: {[url: string]: string} = {};
|
||||
|
@ -47,15 +47,6 @@ $item-ios-detail-push-color: $list-ios-border-color !default;
|
||||
/// @prop - Icon for the detail arrow
|
||||
$item-ios-detail-push-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'><path d='M2,20l-2-2l8-8L0,2l2-2l10,10L2,20z' fill='#{$item-ios-detail-push-color}'/></svg>" !default;
|
||||
|
||||
/// @prop - Background for the divider
|
||||
$item-ios-divider-background: #f7f7f7 !default;
|
||||
|
||||
/// @prop - Color for the divider
|
||||
$item-ios-divider-color: #222 !default;
|
||||
|
||||
/// @prop - Padding for the divider
|
||||
$item-ios-divider-padding: 5px 15px !default;
|
||||
|
||||
|
||||
// iOS Item
|
||||
// --------------------------------------------------
|
||||
|
@ -35,21 +35,6 @@ $item-md-detail-push-color: $list-md-border-color !default;
|
||||
/// @prop - Icon for the detail arrow
|
||||
$item-md-detail-push-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'><path d='M2,20l-2-2l8-8L0,2l2-2l10,10L2,20z' fill='#{$item-md-detail-push-color}'/></svg>" !default;
|
||||
|
||||
/// @prop - Color for the divider
|
||||
$item-md-divider-color: #858585 !default;
|
||||
|
||||
/// @prop - Background for the divider
|
||||
$item-md-divider-background: #fff !default;
|
||||
|
||||
/// @prop - Font size for the divider
|
||||
$item-md-divider-font-size: $item-md-body-text-font-size !default;
|
||||
|
||||
/// @prop - Border bottom for the divider
|
||||
$item-md-divider-border-bottom: 1px solid $list-md-border-color !default;
|
||||
|
||||
/// @prop - Padding for the divider
|
||||
$item-md-divider-padding: 5px 15px !default;
|
||||
|
||||
|
||||
.item-md {
|
||||
@include padding-horizontal($item-md-padding-start, 0);
|
||||
|
@ -86,3 +86,14 @@ ion-input.item {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.item-cover {
|
||||
@include position(0, null, null, 0);
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -41,21 +41,6 @@ $item-wp-detail-push-color: $input-wp-border-color !default;
|
||||
/// @prop - Icon for the detail arrow
|
||||
$item-wp-detail-push-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20'><path d='M2,20l-2-2l8-8L0,2l2-2l10,10L2,20z' fill='#{$item-wp-detail-push-color}'/></svg>" !default;
|
||||
|
||||
/// @prop - Color for the divider
|
||||
$item-wp-divider-color: $list-wp-text-color !default;
|
||||
|
||||
/// @prop - Background for the divider
|
||||
$item-wp-divider-background: #fff !default;
|
||||
|
||||
/// @prop - Bodrer bottom for the divider
|
||||
$item-wp-divider-border-bottom: 1px solid $list-wp-border-color !default;
|
||||
|
||||
/// @prop - Font size for the divider
|
||||
$item-wp-divider-font-size: 2rem !default;
|
||||
|
||||
/// @prop - Padding for the divider
|
||||
$item-wp-divider-padding: 5px 15px !default;
|
||||
|
||||
|
||||
.item-wp {
|
||||
@include padding-horizontal($item-wp-padding-start, 0);
|
||||
|
@ -5,10 +5,8 @@
|
||||
// iOS List Header
|
||||
// --------------------------------------------------
|
||||
|
||||
// deprecated
|
||||
$list-ios-header-padding-left: $item-ios-padding-start !default;
|
||||
/// @prop - Padding start of the header in a list
|
||||
$list-ios-header-padding-start: $list-ios-header-padding-left !default;
|
||||
$list-ios-header-padding-start: $item-ios-padding-start !default;
|
||||
|
||||
/// @prop - Border bottom of the header in a list
|
||||
$list-ios-header-border-bottom: $hairlines-width solid $list-ios-border-color !default;
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import "../../themes/ionic.globals.ios";
|
||||
@import "../../themes/ionic.globals.md";
|
||||
@import "./list-header";
|
||||
|
||||
// Material Design List Header
|
||||
@ -7,10 +7,8 @@
|
||||
/// @prop - Margin bottom of the header in a list
|
||||
$list-md-header-margin-bottom: 13px !default;
|
||||
|
||||
// deprecated
|
||||
$list-md-header-padding-left: $item-md-padding-start !default;
|
||||
/// @prop - Padding start of the header in a list
|
||||
$list-md-header-padding-start: $list-md-header-padding-left !default;
|
||||
$list-md-header-padding-start: $item-md-padding-start !default;
|
||||
|
||||
/// @prop - Minimum height of the header in a list
|
||||
$list-md-header-min-height: 4.5rem !default;
|
||||
|
@ -3,6 +3,11 @@ import { Component } from '@stencil/core';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-list-header',
|
||||
styleUrls: {
|
||||
ios: 'list-header.ios.scss',
|
||||
md: 'list-header.md.scss',
|
||||
wp: 'list-header.wp.scss'
|
||||
},
|
||||
host: {
|
||||
theme: 'list-header'
|
||||
}
|
||||
|
@ -4,10 +4,8 @@
|
||||
// Windows List Header
|
||||
// --------------------------------------------------
|
||||
|
||||
// deprecated
|
||||
$list-wp-header-padding-left: $item-wp-padding-start !default;
|
||||
/// @prop - Padding start of the header in a list
|
||||
$list-wp-header-padding-start: $list-wp-header-padding-left !default;
|
||||
$list-wp-header-padding-start: $item-wp-padding-start !default;
|
||||
|
||||
/// @prop - Border bottom of the header in a list
|
||||
$list-wp-header-border-bottom: 1px solid $list-wp-border-color !default;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, Event, EventEmitter, Prop, State } from '@stencil/core';
|
||||
import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core';
|
||||
|
||||
import { CssClassMap } from '../../index';
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
import { createThemedClasses, getElementClassObject } from '../../utils/theme';
|
||||
|
||||
|
||||
/**
|
||||
@ -49,6 +49,8 @@ export class SegmentButton {
|
||||
mode: string;
|
||||
color: string;
|
||||
|
||||
@Element() el: HTMLElement;
|
||||
|
||||
@Event() ionClick: EventEmitter;
|
||||
|
||||
@State() activated: boolean = false;
|
||||
@ -92,7 +94,7 @@ export class SegmentButton {
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
* Get the element classes to add to the child element
|
||||
* Get the classes for the segment button state
|
||||
*/
|
||||
getElementClassList() {
|
||||
let classList = [].concat(
|
||||
@ -104,9 +106,10 @@ export class SegmentButton {
|
||||
}
|
||||
|
||||
render() {
|
||||
const segmentButtonCss = createThemedClasses(this.mode, this.color, 'segment-button');
|
||||
const themedClasses = createThemedClasses(this.mode, this.color, 'segment-button');
|
||||
const hostClasses = getElementClassObject(this.el.classList);
|
||||
|
||||
var segmentButtonClasses: CssClassMap = []
|
||||
const elementClasses: CssClassMap = []
|
||||
.concat(
|
||||
this.getElementClassList()
|
||||
)
|
||||
@ -115,10 +118,14 @@ export class SegmentButton {
|
||||
return prevValue;
|
||||
}, {});
|
||||
|
||||
segmentButtonClasses = Object.assign(segmentButtonClasses, segmentButtonCss);
|
||||
const buttonClasses = {
|
||||
...themedClasses,
|
||||
...hostClasses,
|
||||
...elementClasses
|
||||
};
|
||||
|
||||
return [
|
||||
<button onClick={this.segmentButtonClick.bind(this)} class={segmentButtonClasses} aria-pressed={this.activated}>
|
||||
<button onClick={this.segmentButtonClick.bind(this)} class={buttonClasses} aria-pressed={this.activated}>
|
||||
<slot></slot>
|
||||
</button>
|
||||
];
|
||||
|
16
packages/core/src/components/select/option.tsx
Normal file
16
packages/core/src/components/select/option.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { Component } from '@stencil/core';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-option',
|
||||
host: {
|
||||
theme: 'option'
|
||||
}
|
||||
})
|
||||
export class option {
|
||||
|
||||
render() {
|
||||
return <div class="my-option"></div>;
|
||||
}
|
||||
|
||||
}
|
56
packages/core/src/components/select/select.ios.scss
Normal file
56
packages/core/src/components/select/select.ios.scss
Normal file
@ -0,0 +1,56 @@
|
||||
@import "../../themes/ionic.globals.ios";
|
||||
@import "./select";
|
||||
|
||||
// iOS Select
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Padding top of the select
|
||||
$select-ios-padding-top: $item-ios-padding-top !default;
|
||||
|
||||
/// @prop - Padding end of the select
|
||||
$select-ios-padding-end: ($item-ios-padding-end / 2) !default;
|
||||
|
||||
/// @prop - Padding bottom of the select
|
||||
$select-ios-padding-bottom: $item-ios-padding-bottom !default;
|
||||
|
||||
/// @prop - Padding start of the select
|
||||
$select-ios-padding-start: $item-ios-padding-start !default;
|
||||
|
||||
/// @prop - Color of the select icon
|
||||
$select-ios-icon-color: #999 !default;
|
||||
|
||||
/// @prop - Color of the select placeholder
|
||||
$select-ios-placeholder-color: $select-ios-icon-color !default;
|
||||
|
||||
|
||||
.select-ios {
|
||||
@include padding($select-ios-padding-top, $select-ios-padding-end, $select-ios-padding-bottom, $select-ios-padding-start);
|
||||
}
|
||||
|
||||
.select-ios .select-placeholder {
|
||||
color: $select-ios-placeholder-color;
|
||||
}
|
||||
|
||||
.select-ios .select-icon {
|
||||
position: relative;
|
||||
|
||||
width: 12px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.select-ios .select-icon .select-icon-inner {
|
||||
@include position(50%, null, null, 5px);
|
||||
@include margin(-2px, null, null, null);
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
||||
border-top: 5px solid;
|
||||
border-right: 5px solid transparent;
|
||||
border-left: 5px solid transparent;
|
||||
color: $select-ios-icon-color;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
60
packages/core/src/components/select/select.md.scss
Normal file
60
packages/core/src/components/select/select.md.scss
Normal file
@ -0,0 +1,60 @@
|
||||
@import "../../themes/ionic.globals.md";
|
||||
@import "./select";
|
||||
|
||||
// Material Design Select
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Padding top of the select
|
||||
$select-md-padding-top: $item-md-padding-top !default;
|
||||
|
||||
/// @prop - Padding end of the select
|
||||
$select-md-padding-end: ($item-md-padding-end / 2) !default;
|
||||
|
||||
/// @prop - Padding bottom of the select
|
||||
$select-md-padding-bottom: $item-md-padding-bottom !default;
|
||||
|
||||
/// @prop - Padding start of the select
|
||||
$select-md-padding-start: $item-md-padding-start !default;
|
||||
|
||||
/// @prop - Color of the select icon
|
||||
$select-md-icon-color: #999 !default;
|
||||
|
||||
/// @prop - Color of the select placeholder
|
||||
$select-md-placeholder-color: $select-md-icon-color !default;
|
||||
|
||||
|
||||
.select-md {
|
||||
@include padding($select-md-padding-top, $select-md-padding-end, $select-md-padding-bottom, $select-md-padding-start);
|
||||
}
|
||||
|
||||
.select-md .select-placeholder {
|
||||
color: $select-md-placeholder-color;
|
||||
}
|
||||
|
||||
.select-md .item-select ion-label {
|
||||
@include margin-horizontal(0, null);
|
||||
}
|
||||
|
||||
.select-md .select-icon {
|
||||
position: relative;
|
||||
|
||||
width: 12px;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
.select-md .select-icon .select-icon-inner {
|
||||
@include position(50%, null, null, 5px);
|
||||
@include margin(-3px, null, null, null);
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
||||
border-top: 5px solid;
|
||||
border-right: 5px solid transparent;
|
||||
border-left: 5px solid transparent;
|
||||
color: $select-md-icon-color;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
56
packages/core/src/components/select/select.scss
Normal file
56
packages/core/src/components/select/select.scss
Normal file
@ -0,0 +1,56 @@
|
||||
@import "../../themes/ionic.globals";
|
||||
|
||||
// Select
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Margin top of the select popover list
|
||||
$select-popover-list-margin-top: -1px !default;
|
||||
|
||||
/// @prop - Margin end of the select popover list
|
||||
$select-popover-list-margin-end: 0 !default;
|
||||
|
||||
/// @prop - Margin bottom of the select popover list
|
||||
$select-popover-list-margin-bottom: -1px !default;
|
||||
|
||||
/// @prop - Margin start of the select popover list
|
||||
$select-popover-list-margin-start: 0 !default;
|
||||
|
||||
|
||||
ion-select {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
max-width: 45%;
|
||||
}
|
||||
|
||||
.select-text {
|
||||
overflow: hidden;
|
||||
|
||||
flex: 1;
|
||||
|
||||
min-width: 16px;
|
||||
|
||||
font-size: inherit;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.item-multiple-inputs ion-select {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.select-disabled,
|
||||
.item-select-disabled ion-label {
|
||||
opacity: .4;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.select-popover ion-list {
|
||||
@include margin($select-popover-list-margin-top, $select-popover-list-margin-end, $select-popover-list-margin-bottom, $select-popover-list-margin-start);
|
||||
}
|
||||
|
||||
// TODO remove
|
||||
.select .option {
|
||||
display: none;
|
||||
}
|
365
packages/core/src/components/select/select.tsx
Normal file
365
packages/core/src/components/select/select.tsx
Normal file
@ -0,0 +1,365 @@
|
||||
import { Component, CssClassMap, Event, EventEmitter, Prop } from '@stencil/core';
|
||||
|
||||
|
||||
@Component({
|
||||
tag: 'ion-select',
|
||||
styleUrls: {
|
||||
ios: 'select.ios.scss',
|
||||
md: 'select.md.scss',
|
||||
wp: 'select.wp.scss'
|
||||
},
|
||||
host: {
|
||||
theme: 'select'
|
||||
}
|
||||
})
|
||||
export class Select {
|
||||
text: any;
|
||||
id: any;
|
||||
labelId: any;
|
||||
|
||||
/**
|
||||
* @input {boolean} If true, the user cannot interact with this element. Defaults to `false`.
|
||||
*/
|
||||
@Prop() disabled: boolean = false;
|
||||
|
||||
/**
|
||||
* @input {string} The text to display on the cancel button. Default: `Cancel`.
|
||||
*/
|
||||
@Prop() cancelText: string = 'Cancel';
|
||||
|
||||
/**
|
||||
* @input {string} The text to display on the ok button. Default: `OK`.
|
||||
*/
|
||||
@Prop() okText: string = 'OK';
|
||||
|
||||
/**
|
||||
* @input {string} The text to display when the select is empty.
|
||||
*/
|
||||
@Prop() placeholder: string;
|
||||
|
||||
/**
|
||||
* @input {any} Any additional options that the `alert` or `action-sheet` interface can take.
|
||||
* See the [AlertController API docs](../../alert/AlertController/#create) and the
|
||||
* [ActionSheetController API docs](../../action-sheet/ActionSheetController/#create) for the
|
||||
* create options for each interface.
|
||||
*/
|
||||
@Prop() selectOptions: any = {};
|
||||
|
||||
/**
|
||||
* @input {string} The interface the select should use: `action-sheet`, `popover` or `alert`. Default: `alert`.
|
||||
*/
|
||||
@Prop() interface: string = '';
|
||||
|
||||
/**
|
||||
* @input {string} The text to display instead of the selected option's value.
|
||||
*/
|
||||
@Prop() selectedText: string;
|
||||
|
||||
/**
|
||||
* @input {boolean} If true, the element can accept multiple values.
|
||||
*/
|
||||
@Prop() multiple: boolean;
|
||||
|
||||
/**
|
||||
* @output {EventEmitter} Emitted when the selection is cancelled.
|
||||
*/
|
||||
@Event() ionCancel: EventEmitter;
|
||||
|
||||
|
||||
hostData() {
|
||||
return {
|
||||
class: {
|
||||
'select-disabled': this.disabled
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
let addPlaceholderClass = false
|
||||
|
||||
let selectText = this.selectedText || this.text;
|
||||
if (!selectText && this.placeholder) {
|
||||
selectText = this.placeholder;
|
||||
addPlaceholderClass = true;
|
||||
}
|
||||
|
||||
const selectTextClasses: CssClassMap = {
|
||||
'select-text': true,
|
||||
'select-placeholder': addPlaceholderClass
|
||||
};
|
||||
|
||||
return [
|
||||
// add placeholder class
|
||||
<div class={selectTextClasses}>{ selectText }</div>,
|
||||
<div class="select-icon">
|
||||
<div class="select-icon-inner"></div>
|
||||
</div>,
|
||||
<button
|
||||
aria-haspopup="true"
|
||||
id={this.id}
|
||||
aria-labelledby={this.labelId}
|
||||
aria-disabled={this.disabled ? "true" : false}
|
||||
class="item-cover">
|
||||
</button>
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// export class Select extends BaseInput<any> implements OnDestroy {
|
||||
|
||||
// _options: QueryList<Option>;
|
||||
// _overlay: ActionSheet | Alert | Popover;
|
||||
// _texts: string[] = [];
|
||||
// _text: string = '';
|
||||
|
||||
|
||||
// @HostListener('click', ['$event'])
|
||||
// _click(ev: UIEvent) {
|
||||
// if (ev.detail === 0) {
|
||||
// // do not continue if the click event came from a form submit
|
||||
// return;
|
||||
// }
|
||||
// ev.preventDefault();
|
||||
// ev.stopPropagation();
|
||||
// this.open(ev);
|
||||
// }
|
||||
|
||||
// @HostListener('keyup.space')
|
||||
// _keyup() {
|
||||
// this.open();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @hidden
|
||||
// */
|
||||
// getValues(): any[] {
|
||||
// const values = Array.isArray(this._value) ? this._value : [this._value];
|
||||
// assert(this._multi || values.length <= 1, 'single only can have one value');
|
||||
// return values;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Open the select interface.
|
||||
// */
|
||||
// open(ev?: UIEvent) {
|
||||
// if (this.isFocus() || this._disabled) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// console.debug('select, open alert');
|
||||
|
||||
// // the user may have assigned some options specifically for the alert
|
||||
// const selectOptions = deepCopy(this.selectOptions);
|
||||
|
||||
// // make sure their buttons array is removed from the options
|
||||
// // and we create a new array for the alert's two buttons
|
||||
// selectOptions.buttons = [{
|
||||
// text: this.cancelText,
|
||||
// role: 'cancel',
|
||||
// handler: () => {
|
||||
// this.ionCancel.emit(this);
|
||||
// }
|
||||
// }];
|
||||
|
||||
// // if the selectOptions didn't provide a title then use the label's text
|
||||
// if (!selectOptions.title && this._item) {
|
||||
// selectOptions.title = this._item.getLabelText();
|
||||
// }
|
||||
|
||||
// let options = this._options.toArray();
|
||||
// if (this.interface === 'action-sheet' && options.length > 6) {
|
||||
// console.warn('Interface cannot be "action-sheet" with more than 6 options. Using the "alert" interface.');
|
||||
// this.interface = 'alert';
|
||||
// }
|
||||
|
||||
// if ((this.interface === 'action-sheet' || this.interface === 'popover') && this._multi) {
|
||||
// console.warn('Interface cannot be "' + this.interface + '" with a multi-value select. Using the "alert" interface.');
|
||||
// this.interface = 'alert';
|
||||
// }
|
||||
|
||||
// if (this.interface === 'popover' && !ev) {
|
||||
// console.warn('Interface cannot be "popover" without UIEvent.');
|
||||
// this.interface = 'alert';
|
||||
// }
|
||||
|
||||
// let overlay: ActionSheet | Alert | Popover;
|
||||
|
||||
// if (this.interface === 'action-sheet') {
|
||||
// selectOptions.buttons = selectOptions.buttons.concat(options.map(input => {
|
||||
// return {
|
||||
// role: (input.selected ? 'selected' : ''),
|
||||
// text: input.text,
|
||||
// handler: () => {
|
||||
// this.value = input.value;
|
||||
// input.ionSelect.emit(input.value);
|
||||
// }
|
||||
// };
|
||||
// }));
|
||||
// var selectCssClass = 'select-action-sheet';
|
||||
|
||||
// // If the user passed a cssClass for the select, add it
|
||||
// selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
|
||||
|
||||
// selectOptions.cssClass = selectCssClass;
|
||||
// overlay = new ActionSheet(this._app, selectOptions, this.config);
|
||||
|
||||
// } else if (this.interface === 'popover') {
|
||||
// let popoverOptions: SelectPopoverOption[] = options.map(input => ({
|
||||
// text: input.text,
|
||||
// checked: input.selected,
|
||||
// disabled: input.disabled,
|
||||
// value: input.value,
|
||||
// handler: () => {
|
||||
// this.value = input.value;
|
||||
// input.ionSelect.emit(input.value);
|
||||
// }
|
||||
// }));
|
||||
|
||||
// var popoverCssClass = 'select-popover';
|
||||
|
||||
// // If the user passed a cssClass for the select, add it
|
||||
// popoverCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
|
||||
|
||||
// overlay = new Popover(this._app, SelectPopover, {
|
||||
// options: popoverOptions
|
||||
// }, {
|
||||
// cssClass: popoverCssClass
|
||||
// }, this.config, this.deepLinker);
|
||||
|
||||
// // ev.target is readonly.
|
||||
// // place popover regarding to ion-select instead of .button-inner
|
||||
// Object.defineProperty(ev, 'target', { value: ev.currentTarget });
|
||||
// selectOptions.ev = ev;
|
||||
|
||||
// } else {
|
||||
// // default to use the alert interface
|
||||
// this.interface = 'alert';
|
||||
|
||||
// // user cannot provide inputs from selectOptions
|
||||
// // alert inputs must be created by ionic from ion-options
|
||||
// selectOptions.inputs = this._options.map(input => {
|
||||
// return {
|
||||
// type: (this._multi ? 'checkbox' : 'radio'),
|
||||
// label: input.text,
|
||||
// value: input.value,
|
||||
// checked: input.selected,
|
||||
// disabled: input.disabled,
|
||||
// handler: (selectedOption: any) => {
|
||||
// // Only emit the select event if it is being checked
|
||||
// // For multi selects this won't emit when unchecking
|
||||
// if (selectedOption.checked) {
|
||||
// input.ionSelect.emit(input.value);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// });
|
||||
|
||||
// var selectCssClass = 'select-alert';
|
||||
|
||||
// // create the alert instance from our built up selectOptions
|
||||
// overlay = new Alert(this._app, selectOptions, this.config);
|
||||
|
||||
// if (this._multi) {
|
||||
// // use checkboxes
|
||||
// selectCssClass += ' multiple-select-alert';
|
||||
// } else {
|
||||
// // use radio buttons
|
||||
// selectCssClass += ' single-select-alert';
|
||||
// }
|
||||
|
||||
// // If the user passed a cssClass for the select, add it
|
||||
// selectCssClass += selectOptions.cssClass ? ' ' + selectOptions.cssClass : '';
|
||||
// overlay.setCssClass(selectCssClass);
|
||||
|
||||
// overlay.addButton({
|
||||
// text: this.okText,
|
||||
// handler: (selectedValues) => this.value = selectedValues
|
||||
// });
|
||||
|
||||
// }
|
||||
|
||||
// overlay.present(selectOptions);
|
||||
|
||||
// this._fireFocus();
|
||||
|
||||
// overlay.onDidDismiss(() => {
|
||||
// this._fireBlur();
|
||||
// this._overlay = undefined;
|
||||
// });
|
||||
|
||||
// this._overlay = overlay;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Close the select interface.
|
||||
// */
|
||||
// close(): Promise<any> {
|
||||
// if (!this._overlay || !this.isFocus()) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// return this._overlay.dismiss();
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * @hidden
|
||||
// */
|
||||
// get text() {
|
||||
// return (this._multi ? this._texts : this._texts.join());
|
||||
// }
|
||||
|
||||
|
||||
// /**
|
||||
// * @private
|
||||
// */
|
||||
// @ContentChildren(Option)
|
||||
// set options(val: QueryList<Option>) {
|
||||
// this._options = val;
|
||||
// const values = this.getValues();
|
||||
// if (values.length === 0) {
|
||||
// // there are no values set at this point
|
||||
// // so check to see who should be selected
|
||||
// // we use writeValue() because we don't want to update ngModel
|
||||
// this.writeValue(val.filter(o => o.selected).map(o => o.value));
|
||||
// } else {
|
||||
// this._inputUpdated();
|
||||
// }
|
||||
// }
|
||||
|
||||
// _inputShouldChange(val: string[]|string): boolean {
|
||||
// return !deepEqual(this._value, val);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * TODO: REMOVE THIS
|
||||
// * @hidden
|
||||
// */
|
||||
// _inputChangeEvent(): any {
|
||||
// return this.value;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @hidden
|
||||
// */
|
||||
// _inputUpdated() {
|
||||
// this._texts.length = 0;
|
||||
|
||||
// if (this._options) {
|
||||
// this._options.forEach(option => {
|
||||
// // check this option if the option's value is in the values array
|
||||
// option.selected = this.getValues().some(selectValue => {
|
||||
// return isCheckedProperty(selectValue, option.value);
|
||||
// });
|
||||
|
||||
// if (option.selected) {
|
||||
// this._texts.push(option.text);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// this._text = this._texts.join(', ');
|
||||
// }
|
||||
|
||||
// }
|
93
packages/core/src/components/select/select.wp.scss
Normal file
93
packages/core/src/components/select/select.wp.scss
Normal file
@ -0,0 +1,93 @@
|
||||
@import "../../themes/ionic.globals.wp";
|
||||
@import "./select";
|
||||
|
||||
// Windows Select
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Padding top and bottom of the select
|
||||
$select-wp-padding-vertical: 0 !default;
|
||||
|
||||
/// @prop - Padding start/end of the select
|
||||
$select-wp-padding-horizontal: ($item-wp-padding-end / 2) !default;
|
||||
|
||||
/// @prop - Margin top of the select
|
||||
$select-wp-margin-top: $item-wp-padding-top !default;
|
||||
|
||||
/// @prop - Margin end of the select
|
||||
$select-wp-margin-end: ($item-wp-padding-end / 2) !default;
|
||||
|
||||
/// @prop - Margin bottom of the select
|
||||
$select-wp-margin-bottom: $item-wp-padding-bottom !default;
|
||||
|
||||
/// @prop - Margin start of the select
|
||||
$select-wp-margin-start: ($item-wp-padding-start / 2) !default;
|
||||
|
||||
/// @prop - Border width of the select
|
||||
$select-wp-border-width: 2px !default;
|
||||
|
||||
/// @prop - Border color of the select
|
||||
$select-wp-border-color: $input-wp-border-color !default;
|
||||
|
||||
/// @prop - Width of the select icon
|
||||
$select-wp-icon-width: 18px !default;
|
||||
|
||||
/// @prop - Width of the select icon arrow
|
||||
$select-wp-icon-arrow-width: 2px !default;
|
||||
|
||||
/// @prop - Color of the select icon
|
||||
$select-wp-icon-color: $select-wp-border-color !default;
|
||||
|
||||
/// @prop - Color of the select placeholder
|
||||
$select-wp-placeholder-color: $select-wp-icon-color !default;
|
||||
|
||||
|
||||
.select-wp {
|
||||
@include margin($select-wp-margin-top, $select-wp-margin-end, $select-wp-margin-bottom, $select-wp-margin-start);
|
||||
@include padding($select-wp-padding-vertical, $select-wp-padding-horizontal);
|
||||
|
||||
flex: 1;
|
||||
|
||||
max-width: 100%;
|
||||
|
||||
border: $select-wp-border-width solid $select-wp-border-color;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.select-wp .select-placeholder {
|
||||
color: $select-wp-placeholder-color;
|
||||
}
|
||||
|
||||
.item-wp.item-select ion-label {
|
||||
@include margin-horizontal(0, null);
|
||||
}
|
||||
|
||||
.select-wp .select-icon {
|
||||
position: relative;
|
||||
|
||||
align-self: center;
|
||||
|
||||
width: $select-wp-icon-width;
|
||||
height: $select-wp-icon-width;
|
||||
}
|
||||
|
||||
.select-wp .select-icon .select-icon-inner {
|
||||
@include position(3px, null, null, 5px);
|
||||
|
||||
position: absolute;
|
||||
|
||||
display: block;
|
||||
|
||||
width: ($select-wp-icon-width / 2);
|
||||
height: ($select-wp-icon-width / 2);
|
||||
|
||||
border-top: $select-wp-icon-arrow-width solid $select-wp-icon-color;
|
||||
border-right: $select-wp-icon-arrow-width solid $select-wp-icon-color;
|
||||
|
||||
transform: rotate(135deg);
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.select-wp .select-text {
|
||||
min-height: 3rem;
|
||||
}
|
237
packages/core/src/components/select/test/basic.html
Normal file
237
packages/core/src/components/select/test/basic.html
Normal file
@ -0,0 +1,237 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Ionic Select</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<script src="/dist/ionic.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Select</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="outer-content test-content">
|
||||
<ion-list>
|
||||
<ion-list-header>Single Value Select</ion-list-header>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Gender</ion-label>
|
||||
<ion-select name="gender" placeholder="Select One">
|
||||
<ion-option value="f">Female</ion-option>
|
||||
<ion-option value="m">Male</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Hair Color</ion-label>
|
||||
<ion-select name="hairColor" ok-text="Okay" cancel-text="Dismiss">
|
||||
<ion-option value="brown">Brown</ion-option>
|
||||
<ion-option value="blonde">Blonde</ion-option>
|
||||
<ion-option value="black">Black</ion-option>
|
||||
<ion-option value="red">Red</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Gaming</ion-label>
|
||||
<ion-select name="gaming" ok-text="Okay" cancel-text="Dismiss">
|
||||
<ion-option value="nes">NES</ion-option>
|
||||
<ion-option value="n64">Nintendo64</ion-option>
|
||||
<ion-option value="ps">PlayStation</ion-option>
|
||||
<ion-option value="genesis">Sega Genesis</ion-option>
|
||||
<ion-option value="saturn">Sega Saturn</ion-option>
|
||||
<ion-option value="snes">SNES</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Date</ion-label>
|
||||
<ion-select (ionChange)="monthChange($event)" placeholder="Month">
|
||||
<ion-option value="01">January</ion-option>
|
||||
<ion-option value="02">February</ion-option>
|
||||
<ion-option value="03" selected="true">March</ion-option>
|
||||
<ion-option value="04">April</ion-option>
|
||||
<ion-option value="05">May</ion-option>
|
||||
<ion-option value="06">June</ion-option>
|
||||
<ion-option value="07">July</ion-option>
|
||||
<ion-option value="08">August</ion-option>
|
||||
<ion-option value="09">September</ion-option>
|
||||
<ion-option value="10">October</ion-option>
|
||||
<ion-option value="11">November</ion-option>
|
||||
<ion-option value="12">December</ion-option>
|
||||
</ion-select>
|
||||
<ion-select (ionChange)="yearChange($event)" placeholder="Year">
|
||||
<ion-option>1989</ion-option>
|
||||
<ion-option>1990</ion-option>
|
||||
<ion-option>1991</ion-option>
|
||||
<ion-option>1992</ion-option>
|
||||
<ion-option>1993</ion-option>
|
||||
<ion-option selected="true">1994</ion-option>
|
||||
<ion-option>1995</ion-option>
|
||||
<ion-option>1996</ion-option>
|
||||
<ion-option>1997</ion-option>
|
||||
<ion-option>1998</ion-option>
|
||||
<ion-option>1999</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-list-header>Popover Interface Select</ion-list-header>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Gender</ion-label>
|
||||
<ion-select name="gender" interface="popover">
|
||||
<ion-option value="f">Female</ion-option>
|
||||
<ion-option value="m">Male</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Gaming</ion-label>
|
||||
<ion-select name="gaming" ok-text="Okay" cancel-text="Dismiss" selected-text="Nintendo 64" interface="popover">
|
||||
<ion-option value="nes">NES</ion-option>
|
||||
<ion-option value="n64">Nintendo64</ion-option>
|
||||
<ion-option value="ps">PlayStation</ion-option>
|
||||
<ion-option value="genesis">Sega Genesis</ion-option>
|
||||
<ion-option value="saturn">Sega Saturn</ion-option>
|
||||
<ion-option value="snes">SNES</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Date</ion-label>
|
||||
<ion-select (ionChange)="monthChange($event)" placeholder="Month" interface="popover">
|
||||
<ion-option value="01">January</ion-option>
|
||||
<ion-option value="02">February</ion-option>
|
||||
<ion-option value="03" selected="true">March</ion-option>
|
||||
<ion-option value="04">April</ion-option>
|
||||
<ion-option value="05">May</ion-option>
|
||||
<ion-option value="06">June</ion-option>
|
||||
<ion-option value="07">July</ion-option>
|
||||
<ion-option value="08">August</ion-option>
|
||||
<ion-option value="09">September</ion-option>
|
||||
<ion-option value="10">October</ion-option>
|
||||
<ion-option value="11">November</ion-option>
|
||||
<ion-option value="12">December</ion-option>
|
||||
</ion-select>
|
||||
<ion-select (ionChange)="yearChange($event)" placeholder="Year" interface="popover">
|
||||
<ion-option>1989</ion-option>
|
||||
<ion-option>1990</ion-option>
|
||||
<ion-option>1991</ion-option>
|
||||
<ion-option>1992</ion-option>
|
||||
<ion-option>1993</ion-option>
|
||||
<ion-option selected="true">1994</ion-option>
|
||||
<ion-option>1995</ion-option>
|
||||
<ion-option>1996</ion-option>
|
||||
<ion-option>1997</ion-option>
|
||||
<ion-option>1998</ion-option>
|
||||
<ion-option>1999</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-list-header>Multiple Value Select</ion-list-header>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toppings</ion-label>
|
||||
<ion-select name="toppings" multiple="true" cancel-text="Nah" ok-text="Okay!">
|
||||
<ion-option value="bacon">Bacon</ion-option>
|
||||
<ion-option value="olives">Black Olives</ion-option>
|
||||
<ion-option value="xcheese">Extra Cheese</ion-option>
|
||||
<ion-option value="peppers">Green Peppers</ion-option>
|
||||
<ion-option value="mushrooms">Mushrooms</ion-option>
|
||||
<ion-option value="onions">Onions</ion-option>
|
||||
<ion-option value="pepperoni">Pepperoni</ion-option>
|
||||
<ion-option value="pineapple">Pineapple</ion-option>
|
||||
<ion-option value="sausage">Sausage</ion-option>
|
||||
<ion-option value="Spinach">Spinach</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Pets</ion-label>
|
||||
<ion-select name="pets" multiple="true">
|
||||
<ion-option value="bird">Bird</ion-option>
|
||||
<ion-option value="cat">Cat</ion-option>
|
||||
<ion-option value="dog">Dog</ion-option>
|
||||
<ion-option value="honeybadger">Honey Badger</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Skittles</ion-label>
|
||||
<ion-select name="skittles" multiple="true" ok-text="Okay" cancel-text="Dismiss">
|
||||
<ion-option value="red">Red</ion-option>
|
||||
<ion-option value="purple">Purple</ion-option>
|
||||
<ion-option value="yellow">Yellow</ion-option>
|
||||
<ion-option value="orange">Orange</ion-option>
|
||||
<ion-option value="green">Green</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Disabled</ion-label>
|
||||
<ion-select multiple disabled="true">
|
||||
<ion-option checked="true">Selected Text</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<ion-list>
|
||||
<ion-list-header>Action Sheet Interface Select</ion-list-header>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Mute Notifications</ion-label>
|
||||
<ion-select name="notifications" interface="action-sheet">
|
||||
<ion-option value="mute_15">For 15 Minutes</ion-option>
|
||||
<ion-option value="mute_1">For 1 Hour</ion-option>
|
||||
<ion-option value="mute_23">For 24 Hours</ion-option>
|
||||
<ion-option value="mute_inf">Until I turn it back on</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Rating</ion-label>
|
||||
<ion-select name="rating" interface="action-sheet">
|
||||
<ion-option value="1">1 Star</ion-option>
|
||||
<ion-option value="2">2 Stars</ion-option>
|
||||
<ion-option value="3">3 Stars</ion-option>
|
||||
<ion-option value="4">4 Stars</ion-option>
|
||||
<ion-option value="5">5 Stars</ion-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<div text-center>
|
||||
<ion-button onclick="toggleBoolean('dynamicDisabled', 'disabled')">
|
||||
Toggle Disabled
|
||||
</ion-button>
|
||||
</div>
|
||||
|
||||
</ion-content>
|
||||
|
||||
<script>
|
||||
function toggleBoolean(id, prop) {
|
||||
var ele = document.getElementById(id);
|
||||
|
||||
var isTrue = ele[prop] ? false : true;
|
||||
ele[prop] = isTrue;
|
||||
console.log('in toggleBoolean, setting', prop, 'to', isTrue);
|
||||
}
|
||||
</script>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
@ -37,11 +37,11 @@ export class Spinner {
|
||||
}
|
||||
|
||||
hostData() {
|
||||
const spinnerThemedClasses = createThemedClasses(this.mode, this.color, `spinner spinner-${this.name}`);
|
||||
spinnerThemedClasses['spinner-paused'] = true;
|
||||
const themedClasses = createThemedClasses(this.mode, this.color, `spinner spinner-${this.name}`);
|
||||
themedClasses['spinner-paused'] = true;
|
||||
|
||||
return {
|
||||
class: spinnerThemedClasses
|
||||
class: themedClasses
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,6 @@
|
||||
<script src="/dist/ionic.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<ion-spinner></ion-spinner>
|
||||
<ion-spinner name="bubbles"></ion-spinner>
|
||||
</body>
|
||||
</html>
|
@ -53,10 +53,10 @@ export class ToolbarTitle {
|
||||
color: string;
|
||||
|
||||
render() {
|
||||
const titleClasses = createThemedClasses(this.mode, this.color, 'toolbar-title');
|
||||
const themedClasses = createThemedClasses(this.mode, this.color, 'toolbar-title');
|
||||
|
||||
return [
|
||||
<div class={titleClasses}>
|
||||
<div class={themedClasses}>
|
||||
<slot></slot>
|
||||
</div>
|
||||
];
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
export function isDef(v: any): boolean { return v !== undefined && v !== null; }
|
||||
|
||||
export function isUndef(v: any): boolean { return v === undefined || v === null; }
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { CssClassMap } from '@stencil/core';
|
||||
|
||||
/**
|
||||
* Create the mode and color classes for the component based on the classes passed in
|
||||
*/
|
||||
export function createThemedClasses(mode: string, color: string, classes: string): CssClassMap {
|
||||
let classObj: CssClassMap = {};
|
||||
|
||||
export function createThemedClasses(mode: string, color: string, classList: string): CssClassMap {
|
||||
let allClassObj: CssClassMap = {};
|
||||
|
||||
return classList.split(' ')
|
||||
return classes.split(' ')
|
||||
.reduce((classObj: CssClassMap, classString: string): CssClassMap => {
|
||||
classObj[classString] = true;
|
||||
|
||||
@ -18,5 +20,18 @@ export function createThemedClasses(mode: string, color: string, classList: stri
|
||||
}
|
||||
|
||||
return classObj;
|
||||
}, allClassObj);
|
||||
}, classObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the classes from a class list and return them as an object
|
||||
*/
|
||||
export function getElementClassObject(classList: DOMTokenList): CssClassMap {
|
||||
let classObj: CssClassMap = {};
|
||||
|
||||
for (var i = 0; i < classList.length; i++) {
|
||||
classObj[classList.item(i)] = true;
|
||||
}
|
||||
|
||||
return classObj;
|
||||
}
|
Reference in New Issue
Block a user