Compare commits

...

7 Commits

Author SHA1 Message Date
Brandy Carney
bd1f207db5 comment 2019-02-20 11:36:23 -05:00
Brandy Carney
cc91da867e 4.0.2 2019-02-20 11:36:03 -05:00
Liam DeBeasi
3a9b679962 fix(button): show proper shade for activated button on ios (#17508)
fixes #17436
2019-02-20 10:22:29 -06:00
Brandy Carney
2bdaadddfb docs(process): update process documentation 2019-02-20 10:22:15 -06:00
Liam DeBeasi
644f9f4627 fix(datetime): default to current date when no value given (#17443)
* fix(datetime): default to current date when no value given

* test(datetime): add spec test

* move getDateValue to utils
2019-02-20 10:21:56 -06:00
Liam DeBeasi
e27bb2e862 fix(item-sliding): Sliding no longer breaks after removing an item (#17492)
* fix(item-sliding): Sliding no longer breaks after removing an item

* run linter
2019-02-20 10:21:31 -06:00
Liam DeBeasi
f9f1775241 fix(select): Account for when options are not loaded immediately (#17405)
* Added logging to begin debugging issue

* identify potential fix, add test

* fix(select): render when options are loaded after a delay

* fix linter issues

* fix e2e test

* fix edge case with if statement
2019-02-20 10:20:23 -06:00
17 changed files with 254 additions and 20 deletions

17
.github/PROCESS.md vendored
View File

@@ -35,26 +35,27 @@ Issues and pull requests that need review. Pull requests will automatically move
Issues and pull requests that are completed. Issues will automatically move here when they are closed. Pull requests will automatically moved here when they are merged or closed with unmerged commits.
## Managing Issues
### Issues to Triage
The issues that need to be triaged all have the `triage` label. In many cases the issue can be automatically processed by the Ionic Issue Bot by applying a specific label.
Once another label is applied to the issue, the `triage` label is automatically be removed by the bot.
Once another label is applied to the issue, the `triage` label is automatically removed by the bot.
### Wrong Repo
### Wrong Repository
If an issue does not pertain to the Ionic Framework but does pertain to another repo, it should be moved to that repo. The bot has been set up to automatically create the issue in other repositories while closing and locking the issue in this repository. Use one of the following labels to perform that action:
If an issue does not pertain to the Ionic Framework but does pertain to another repository, it should be moved to that repository. The bot has been set up to automatically create the issue in other repositories while closing and locking the issue in this repository. Use one of the following labels to perform that action:
- ionitron: cli
- ionitron: docs
- ionitron: stencil
- ionitron: native
### Ionic Pro Issues
### Ionic Appflow Issues
If the issue is associated with Ionic Pro the submitter should be told to use the [Ionic Pro Support Forum](https://ionic.zendesk.com/hc/en-us/requests/new). The issue should be closed and locked. Use the `ionitron: ionic pro` label to accomplish this.
If the issue is associated with Ionic Appflow the submitter should be told to use the [Ionic Appflow Support Forum](https://ionic.zendesk.com/hc/en-us/requests/new). The issue should be closed and locked. Use the `ionitron: ionic appflow` label to accomplish this.
### Support Questions
@@ -68,12 +69,12 @@ If the issue template has not been filled out completely, the issue should be cl
In many cases, the template is mostly filled out but just missing a thing or two or you may have a question or need clarification. In such a case, the submitter should be asked to supply that information.
1. create a comment requesting the additional information or clarification
1. add the `needs reply` label to the task
1. add a comment requesting the additional information or clarification
1. add the `needs: reply` label to the task
NOTE: be sure to perform those actions in the order stated. If you add the comment second it will trigger the removal of the label.
If there is a response to the question, the bot will remove the `needs reply` and apply the `triage` label. The issue will then go through the triage handling again.
If there is a response to the question, the bot will remove the `needs: reply` and apply the `triage` label. The issue will then go through the triage handling again.
if there is no response within 30 days, the issue will be closed and locked.

View File

@@ -37,9 +37,9 @@ function checkGit(tasks) {
{
title: 'Check current branch',
task: () => execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']).then(branch => {
if (branch !== 'master') {
throw new Error(`Not on "master" branch`);
}
// if (branch !== 'master') {
// throw new Error(`Not on "master" branch`);
// }
})
},
{

View File

@@ -1,3 +1,19 @@
## [4.0.2](https://github.com/ionic-team/ionic/compare/v4.0.1...v4.0.2) (2019-02-20)
### Bug Fixes
* **button:** show proper shade for activated button on ios ([#17508](https://github.com/ionic-team/ionic/issues/17508)) ([3a9b679](https://github.com/ionic-team/ionic/commit/3a9b679)), closes [#17436](https://github.com/ionic-team/ionic/issues/17436)
* **config:** update types for scrollPadding, inputBlurring and hideCaretOnScroll to boolean ([#17302](https://github.com/ionic-team/ionic/issues/17302)) ([39fbc32](https://github.com/ionic-team/ionic/commit/39fbc32))
* **datetime:** default to current date when no value given ([#17443](https://github.com/ionic-team/ionic/issues/17443)) ([644f9f4](https://github.com/ionic-team/ionic/commit/644f9f4))
* **item-sliding:** Sliding no longer breaks after removing an item ([#17492](https://github.com/ionic-team/ionic/issues/17492)) ([e27bb2e](https://github.com/ionic-team/ionic/commit/e27bb2e))
* **range:** implement RTL (from PR 17157) ([#17384](https://github.com/ionic-team/ionic/issues/17384)) ([4f203bc](https://github.com/ionic-team/ionic/commit/4f203bc)), closes [#17012](https://github.com/ionic-team/ionic/issues/17012)
* **searchbar:** allow setting of toolbar color and searchbar color ([#17474](https://github.com/ionic-team/ionic/issues/17474)) ([ba4e117](https://github.com/ionic-team/ionic/commit/ba4e117))
* **select:** Account for when options are not loaded immediately ([#17405](https://github.com/ionic-team/ionic/issues/17405)) ([f9f1775](https://github.com/ionic-team/ionic/commit/f9f1775))
* **tab-bar:** add translucent tab-bar styles back ([#17376](https://github.com/ionic-team/ionic/issues/17376)) ([374bd77](https://github.com/ionic-team/ionic/commit/374bd77))
## [4.0.1](https://github.com/ionic-team/ionic/compare/v4.0.0...v4.0.1) (2019-02-06)

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "4.0.1",
"version": "4.0.2",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -45,7 +45,7 @@
"css/"
],
"dependencies": {
"@ionic/core": "4.0.1",
"@ionic/core": "4.0.2",
"tslib": "^1.9.3"
},
"peerDependencies": {

View File

@@ -23,8 +23,8 @@ The Ionic Core package contains the Web Components that make up the reusable UI
Easiest way to start using Ionic Core is by adding a script tag to the CDN:
```html
<link href="https://unpkg.com/@ionic/core@4.0.1/css/ionic.bundle.css" rel="stylesheet">
<script src="https://unpkg.com/@ionic/core@4.0.1/dist/ionic.js"></script>
<link href="https://unpkg.com/@ionic/core@4.0.2/css/ionic.bundle.css" rel="stylesheet">
<script src="https://unpkg.com/@ionic/core@4.0.2/dist/ionic.js"></script>
```
Any Ionic component added to the webpage will automatically load. This includes writing the component tag directly in HTML, or using JavaScript such as `document.createElement('ion-toggle')`.

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "4.0.1",
"version": "4.0.2",
"description": "Base components for Ionic",
"keywords": [
"ionic",

View File

@@ -34,6 +34,10 @@
--opacity: #{$button-ios-opacity-activated};
}
:host(.button-solid.activated.ion-color) .button-native {
background: current-color(shade);
}
// iOS Outline Button
// --------------------------------------------------

View File

@@ -1,3 +1,16 @@
/**
* Gets a date value given a format
* Defaults to the current date if
* no date given
*/
export function getDateValue(date: DatetimeData, format: string): number {
const getValue = getValueFromFormat(date, format);
if (getValue) { return getValue; }
const defaultDate = parseDate(new Date().toISOString());
return getValueFromFormat((defaultDate as DatetimeData), format);
}
export function renderDatetime(template: string, value: DatetimeData | undefined, locale: LocaleData): string | undefined {
if (value === undefined) {

View File

@@ -4,7 +4,7 @@ import { DatetimeChangeEventDetail, DatetimeOptions, Mode, PickerColumn, PickerC
import { clamp, findItemLabel, renderHiddenInput } from '../../utils/helpers';
import { hostContext } from '../../utils/theme';
import { DatetimeData, LocaleData, convertDataToISO, convertFormatToKey, convertToArrayOfNumbers, convertToArrayOfStrings, dateDataSortValue, dateSortValue, dateValueRange, daysInMonth, getValueFromFormat, parseDate, parseTemplate, renderDatetime, renderTextFormat, updateDate } from './datetime-util';
import { DatetimeData, LocaleData, convertDataToISO, convertFormatToKey, convertToArrayOfNumbers, convertToArrayOfStrings, dateDataSortValue, dateSortValue, dateValueRange, daysInMonth, getDateValue, parseDate, parseTemplate, renderDatetime, renderTextFormat, updateDate } from './datetime-util';
@Component({
tag: 'ion-datetime',
@@ -359,7 +359,7 @@ export class Datetime implements ComponentInterface {
// cool, we've loaded up the columns with options
// preselect the option for this column
const optValue = getValueFromFormat(this.datetimeValue, format);
const optValue = getDateValue(this.datetimeValue, format);
const selectedIndex = colOptions.findIndex(opt => opt.value === optValue);
return {

View File

@@ -0,0 +1,35 @@
import { DatetimeOptions } from '../datetime-interface';
import { DatetimeData, getDateValue } from '../datetime-util';
describe('Datetime', () => {
describe('getDateValue()', () => {
it('it should return the date value for the current day', () => {
const today = new Date();
const dayValue = getDateValue({}, 'DD');
const monthvalue = getDateValue({}, 'MM');
const yearValue = getDateValue({}, 'YYYY');
expect(dayValue).toEqual(today.getDate());
expect(monthvalue).toEqual(today.getMonth() + 1);
expect(yearValue).toEqual(today.getFullYear());
});
it('it should return the date value for a given day', () => {
const date = new Date('15 October 1995');
const dateTimeData: DatetimeData = {
year: date.getFullYear(),
month: date.getMonth() + 1,
day: date.getDate()
}
const dayValue = getDateValue(dateTimeData, 'DD');
const monthvalue = getDateValue(dateTimeData, 'MM');
const yearValue = getDateValue(dateTimeData, 'YYYY');
expect(dayValue).toEqual(date.getDate());
expect(monthvalue).toEqual(date.getMonth() + 1);
expect(yearValue).toEqual(date.getFullYear());
});
});
});

View File

@@ -66,7 +66,6 @@ export class ItemSliding implements ComponentInterface {
async componentDidLoad() {
this.item = this.el.querySelector('ion-item');
await this.updateOptions();
this.gesture = (await import('../../utils/gesture')).createGesture({
@@ -91,6 +90,7 @@ export class ItemSliding implements ComponentInterface {
this.item = null;
this.leftOptions = this.rightOptions = undefined;
this.closeOpened();
}
/**
@@ -128,6 +128,7 @@ export class ItemSliding implements ComponentInterface {
async closeOpened(): Promise<boolean> {
if (openSlidingItem !== undefined) {
openSlidingItem.close();
openSlidingItem = undefined;
return true;
}
return false;
@@ -162,6 +163,7 @@ export class ItemSliding implements ComponentInterface {
this.closeOpened();
return false;
}
return !!(this.rightOptions || this.leftOptions);
}

View File

@@ -0,0 +1,49 @@
import { newE2EPage } from '@stencil/core/testing';
test('item-sliding: interactive', async () => {
const page = await newE2EPage({
url: '/src/components/item-sliding/test/interactive?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
const items = await page.$$('ion-item-sliding');
expect(items.length).toEqual(3);
await slideAndDelete(items[0], page);
const itemsAfterFirstSlide = await page.$$('ion-item-sliding');
expect(itemsAfterFirstSlide.length).toEqual(2);
await slideAndDelete(items[1], page);
const itemsAfterSecondSlide = await page.$$('ion-item-sliding');
expect(itemsAfterSecondSlide.length).toEqual(1);
});
async function slideAndDelete(item: any, page: any) {
try {
// Get the element's ID
const id = await(await item.getProperty('id')).jsonValue();
// Simulate a drag
const boundingBox = await item.boundingBox();
const centerX = parseFloat(boundingBox.x + boundingBox.width / 2);
const centerY = parseFloat(boundingBox.y + boundingBox.height / 2);
await page.mouse.move(centerX, centerY);
await page.mouse.down();
await page.mouse.move(0, centerY);
await page.mouse.up();
// Click the "delete" option
const options = await item.$$('ion-item-option');
await options[0].click();
// Wait for element to be removed from DOM
await page.waitForSelector(id, { hidden: true });
} catch (err) {
throw err;
}
}

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Item Sliding - Standalone</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../../../../../css/core.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script src="../../../../../dist/ionic.js"></script>
</head>
<body>
<ion-list></ion-list>
<script>
let lists = document.getElementsByTagName('ion-list');
for (var i = 0; i < lists.length; i++) {
for (var j = 0; j < 3; j++) {
addSlidingItem(lists[i]);
}
}
function addSlidingItem(list) {
const slidingItem = document.createElement('ion-item-sliding');
slidingItem.innerHTML = `
<ion-item>
<ion-label>
<h2>Item Options Both Sides</h2>
</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="danger" expandable onclick="remove(this)">
<ion-icon name="trash"></ion-icon>
Delete
</ion-item-option>
</ion-item-options>
`;
slidingItem.id = `item-${list.childElementCount}`;
list.appendChild(slidingItem);
}
function remove(optionElement) {
const slidingElement = optionElement.parentNode.parentNode;
lists[0].removeChild(slidingElement);
}
</script>
</body>
</html>

View File

@@ -133,8 +133,21 @@ export class Select implements ComponentInterface {
@Listen('ionSelectOptionDidUnload')
async selectOptionChanged() {
await this.loadOptions();
if (this.didInit) {
this.updateOptions();
/**
* In the event that options
* are not loaded at component load
* this ensures that any value that is
* set is properly rendered once
* options have been loaded
*/
if (this.value !== undefined) {
this.el.forceUpdate();
}
}
}

View File

@@ -0,0 +1,10 @@
import { newE2EPage } from '@stencil/core/testing';
test('select: async', async () => {
const page = await newE2EPage({
url: '/src/components/select/test/async?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Select - Async</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../../../../../css/core.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script src="../../../../../dist/ionic.js"></script>
</head>
<body>
<ion-select id="animals" placeholder="Select One"></ion-select>
<script>
let select = document.getElementById('animals');
const options = ['bird', 'dog', 'shark', 'lizard'];
setTimeout(() => {
options.forEach(option => {
let o = document.createElement('ion-select-option');
o.value = option;
o.textContent = option;
select.appendChild(o);
});
select.value = options[0];
}, 500);
</script>
</body>
</html>

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/docs",
"version": "4.0.1",
"version": "4.0.2",
"description": "Pre-packaged API documentation for the Ionic docs.",
"main": "core.json",
"files": [