feat(datetime): add showDefaultTimeLabel property and time-label slot (#23577)

resolves #23555
This commit is contained in:
Hans Krywalsky
2021-07-07 15:21:13 +02:00
committed by GitHub
parent 55bd1f749b
commit 7ac010943b
8 changed files with 137 additions and 28 deletions

View File

@ -244,8 +244,8 @@ export class IonContent {
} }
export declare interface IonDatetime extends Components.IonDatetime { export declare interface IonDatetime extends Components.IonDatetime {
} }
@ProxyCmp({ inputs: ["cancelText", "color", "dayValues", "disabled", "doneText", "hourValues", "locale", "max", "min", "minuteValues", "mode", "monthValues", "name", "presentation", "readonly", "showDefaultButtons", "showDefaultTitle", "value", "yearValues"], "methods": ["confirm", "reset", "cancel"] }) @ProxyCmp({ inputs: ["cancelText", "color", "dayValues", "disabled", "doneText", "hourValues", "locale", "max", "min", "minuteValues", "mode", "monthValues", "name", "presentation", "readonly", "showDefaultButtons", "showDefaultTimeLabel", "showDefaultTitle", "value", "yearValues"], "methods": ["confirm", "reset", "cancel"] })
@Component({ selector: "ion-datetime", changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>", inputs: ["cancelText", "color", "dayValues", "disabled", "doneText", "hourValues", "locale", "max", "min", "minuteValues", "mode", "monthValues", "name", "presentation", "readonly", "showDefaultButtons", "showDefaultTitle", "value", "yearValues"] }) @Component({ selector: "ion-datetime", changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content></ng-content>", inputs: ["cancelText", "color", "dayValues", "disabled", "doneText", "hourValues", "locale", "max", "min", "minuteValues", "mode", "monthValues", "name", "presentation", "readonly", "showDefaultButtons", "showDefaultTimeLabel", "showDefaultTitle", "value", "yearValues"] })
export class IonDatetime { export class IonDatetime {
ionCancel!: EventEmitter<CustomEvent>; ionCancel!: EventEmitter<CustomEvent>;
ionChange!: EventEmitter<CustomEvent>; ionChange!: EventEmitter<CustomEvent>;

View File

@ -385,6 +385,7 @@ ion-datetime,prop,name,string,this.inputId,false,false
ion-datetime,prop,presentation,"date" | "date-time" | "time" | "time-date",'date-time',false,false ion-datetime,prop,presentation,"date" | "date-time" | "time" | "time-date",'date-time',false,false
ion-datetime,prop,readonly,boolean,false,false,false ion-datetime,prop,readonly,boolean,false,false,false
ion-datetime,prop,showDefaultButtons,boolean,false,false,false ion-datetime,prop,showDefaultButtons,boolean,false,false,false
ion-datetime,prop,showDefaultTimeLabel,boolean,true,false,false
ion-datetime,prop,showDefaultTitle,boolean,false,false,false ion-datetime,prop,showDefaultTitle,boolean,false,false,false
ion-datetime,prop,value,null | string | undefined,undefined,false,false ion-datetime,prop,value,null | string | undefined,undefined,false,false
ion-datetime,prop,yearValues,number | number[] | string | undefined,undefined,false,false ion-datetime,prop,yearValues,number | number[] | string | undefined,undefined,false,false

View File

@ -774,6 +774,10 @@ export namespace Components {
* If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. * If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered.
*/ */
"showDefaultButtons": boolean; "showDefaultButtons": boolean;
/**
* If `true`, the default "Time" label will be rendered for the time selector of the `ion-datetime` component. Developers can also use the `time-label` slot if they want to customize this label. If a custom label is set in the `time-label` slot then the default label will not be rendered.
*/
"showDefaultTimeLabel": boolean;
/** /**
* If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date. * If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date.
*/ */
@ -4330,6 +4334,10 @@ declare namespace LocalJSX {
* If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. * If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered.
*/ */
"showDefaultButtons"?: boolean; "showDefaultButtons"?: boolean;
/**
* If `true`, the default "Time" label will be rendered for the time selector of the `ion-datetime` component. Developers can also use the `time-label` slot if they want to customize this label. If a custom label is set in the `time-label` slot then the default label will not be rendered.
*/
"showDefaultTimeLabel"?: boolean;
/** /**
* If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date. * If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date.
*/ */

View File

@ -62,6 +62,7 @@ import {
* *
* @slot title - The title of the datetime. * @slot title - The title of the datetime.
* @slot buttons - The buttons in the datetime. * @slot buttons - The buttons in the datetime.
* @slot time-label - The label for the time selector in the datetime.
*/ */
@Component({ @Component({
tag: 'ion-datetime', tag: 'ion-datetime',
@ -307,6 +308,16 @@ export class Datetime implements ComponentInterface {
*/ */
@Prop() showDefaultButtons = false; @Prop() showDefaultButtons = false;
/**
* If `true`, the default "Time" label will be rendered
* for the time selector of the `ion-datetime` component.
* Developers can also use the `time-label` slot
* if they want to customize this label. If a custom
* label is set in the `time-label` slot then the
* default label will not be rendered.
*/
@Prop() showDefaultTimeLabel = true;
/** /**
* Emitted when the datetime selection was cancelled. * Emitted when the datetime selection was cancelled.
*/ */
@ -1363,6 +1374,15 @@ export class Datetime implements ComponentInterface {
) )
} }
private renderTimeLabel() {
const hasSlottedTimeLabel = this.el.querySelector('[slot="time-label"]') !== null;
if (!hasSlottedTimeLabel && !this.showDefaultTimeLabel) { return; }
return (
<slot name="time-label">Time</slot>
);
}
/** /**
* Render time picker inside of datetime. * Render time picker inside of datetime.
* Do not pass color prop to segment on * Do not pass color prop to segment on
@ -1376,7 +1396,9 @@ export class Datetime implements ComponentInterface {
const { hours, minutes, am, pm } = generateTime(this.locale, this.workingParts, this.minParts, this.maxParts, this.parsedHourValues, this.parsedMinuteValues); const { hours, minutes, am, pm } = generateTime(this.locale, this.workingParts, this.minParts, this.maxParts, this.parsedHourValues, this.parsedMinuteValues);
return ( return (
<div class="datetime-time"> <div class="datetime-time">
<div class="time-header">Time</div> <div class="time-header">
{this.renderTimeLabel()}
</div>
<div class="time-body"> <div class="time-body">
<div class="time-base" ref={el => this.timeBaseRef = el}> <div class="time-base" ref={el => this.timeBaseRef = el}>
<div class="time-wrapper"> <div class="time-wrapper">

View File

@ -536,27 +536,28 @@ export class DatetimeExample {
## Properties ## Properties
| Property | Attribute | Description | Type | Default | | Property | Attribute | Description | Type | Default |
| -------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -------------- | | ---------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -------------- |
| `cancelText` | `cancel-text` | The text to display on the picker's cancel button. | `string` | `'Cancel'` | | `cancelText` | `cancel-text` | The text to display on the picker's cancel button. | `string` | `'Cancel'` |
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `'primary'` | | `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `'primary'` |
| `dayValues` | `day-values` | Values used to create the list of selectable days. By default every day is shown for the given month. However, to control exactly which days of the month to display, the `dayValues` input can take a number, an array of numbers, or a string of comma separated numbers. Note that even if the array days have an invalid number for the selected month, like `31` in February, it will correctly not show days which are not valid for the selected month. | `number \| number[] \| string \| undefined` | `undefined` | | `dayValues` | `day-values` | Values used to create the list of selectable days. By default every day is shown for the given month. However, to control exactly which days of the month to display, the `dayValues` input can take a number, an array of numbers, or a string of comma separated numbers. Note that even if the array days have an invalid number for the selected month, like `31` in February, it will correctly not show days which are not valid for the selected month. | `number \| number[] \| string \| undefined` | `undefined` |
| `disabled` | `disabled` | If `true`, the user cannot interact with the datetime. | `boolean` | `false` | | `disabled` | `disabled` | If `true`, the user cannot interact with the datetime. | `boolean` | `false` |
| `doneText` | `done-text` | The text to display on the picker's "Done" button. | `string` | `'Done'` | | `doneText` | `done-text` | The text to display on the picker's "Done" button. | `string` | `'Done'` |
| `hourValues` | `hour-values` | Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers. | `number \| number[] \| string \| undefined` | `undefined` | | `hourValues` | `hour-values` | Values used to create the list of selectable hours. By default the hour values range from `0` to `23` for 24-hour, or `1` to `12` for 12-hour. However, to control exactly which hours to display, the `hourValues` input can take a number, an array of numbers, or a string of comma separated numbers. | `number \| number[] \| string \| undefined` | `undefined` |
| `locale` | `locale` | The locale to use for `ion-datetime`. This impacts month and day name formatting. The `'default'` value refers to the default locale set by your device. | `string` | `'default'` | | `locale` | `locale` | The locale to use for `ion-datetime`. This impacts month and day name formatting. The `'default'` value refers to the default locale set by your device. | `string` | `'default'` |
| `max` | `max` | The maximum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the maximum could just be the year, such as `1994`. Defaults to the end of this year. | `string \| undefined` | `undefined` | | `max` | `max` | The maximum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the maximum could just be the year, such as `1994`. Defaults to the end of this year. | `string \| undefined` | `undefined` |
| `min` | `min` | The minimum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), such as `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the minimum could just be the year, such as `1994`. Defaults to the beginning of the year, 100 years ago from today. | `string \| undefined` | `undefined` | | `min` | `min` | The minimum datetime allowed. Value must be a date string following the [ISO 8601 datetime format standard](https://www.w3.org/TR/NOTE-datetime), such as `1996-12-19`. The format does not have to be specific to an exact datetime. For example, the minimum could just be the year, such as `1994`. Defaults to the beginning of the year, 100 years ago from today. | `string \| undefined` | `undefined` |
| `minuteValues` | `minute-values` | Values used to create the list of selectable minutes. By default the minutes range from `0` to `59`. However, to control exactly which minutes to display, the `minuteValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if the minute selections should only be every 15 minutes, then this input value would be `minuteValues="0,15,30,45"`. | `number \| number[] \| string \| undefined` | `undefined` | | `minuteValues` | `minute-values` | Values used to create the list of selectable minutes. By default the minutes range from `0` to `59`. However, to control exactly which minutes to display, the `minuteValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if the minute selections should only be every 15 minutes, then this input value would be `minuteValues="0,15,30,45"`. | `number \| number[] \| string \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | | `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| `monthValues` | `month-values` | Values used to create the list of selectable months. By default the month values range from `1` to `12`. However, to control exactly which months to display, the `monthValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if only summer months should be shown, then this input value would be `monthValues="6,7,8"`. Note that month numbers do *not* have a zero-based index, meaning January's value is `1`, and December's is `12`. | `number \| number[] \| string \| undefined` | `undefined` | | `monthValues` | `month-values` | Values used to create the list of selectable months. By default the month values range from `1` to `12`. However, to control exactly which months to display, the `monthValues` input can take a number, an array of numbers, or a string of comma separated numbers. For example, if only summer months should be shown, then this input value would be `monthValues="6,7,8"`. Note that month numbers do *not* have a zero-based index, meaning January's value is `1`, and December's is `12`. | `number \| number[] \| string \| undefined` | `undefined` |
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` | `this.inputId` | | `name` | `name` | The name of the control, which is submitted with the form data. | `string` | `this.inputId` |
| `presentation` | `presentation` | Which values you want to select. `'date'` will show a calendar picker to select the month, day, and year. `'time'` will show a time picker to select the hour, minute, and (optionally) AM/PM. `'date-time'` will show the date picker first and time picker second. `'time-date'` will show the time picker first and date picker second. | `"date" \| "date-time" \| "time" \| "time-date"` | `'date-time'` | | `presentation` | `presentation` | Which values you want to select. `'date'` will show a calendar picker to select the month, day, and year. `'time'` will show a time picker to select the hour, minute, and (optionally) AM/PM. `'date-time'` will show the date picker first and time picker second. `'time-date'` will show the time picker first and date picker second. | `"date" \| "date-time" \| "time" \| "time-date"` | `'date-time'` |
| `readonly` | `readonly` | If `true`, the datetime appears normal but is not interactive. | `boolean` | `false` | | `readonly` | `readonly` | If `true`, the datetime appears normal but is not interactive. | `boolean` | `false` |
| `showDefaultButtons` | `show-default-buttons` | If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. | `boolean` | `false` | | `showDefaultButtons` | `show-default-buttons` | If `true`, the default "Cancel" and "OK" buttons will be rendered at the bottom of the `ion-datetime` component. Developers can also use the `button` slot if they want to customize these buttons. If custom buttons are set in the `button` slot then the default buttons will not be rendered. | `boolean` | `false` |
| `showDefaultTitle` | `show-default-title` | If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date. | `boolean` | `false` | | `showDefaultTimeLabel` | `show-default-time-label` | If `true`, the default "Time" label will be rendered for the time selector of the `ion-datetime` component. Developers can also use the `time-label` slot if they want to customize this label. If a custom label is set in the `time-label` slot then the default label will not be rendered. | `boolean` | `true` |
| `value` | `value` | The value of the datetime as a valid ISO 8601 datetime string. | `null \| string \| undefined` | `undefined` | | `showDefaultTitle` | `show-default-title` | If `true`, a header will be shown above the calendar picker. On `ios` mode this will include the slotted title, and on `md` mode this will include the slotted title and the selected date. | `boolean` | `false` |
| `yearValues` | `year-values` | Values used to create the list of selectable years. By default the year values range between the `min` and `max` datetime inputs. However, to control exactly which years to display, the `yearValues` input can take a number, an array of numbers, or string of comma separated numbers. For example, to show upcoming and recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`. | `number \| number[] \| string \| undefined` | `undefined` | | `value` | `value` | The value of the datetime as a valid ISO 8601 datetime string. | `null \| string \| undefined` | `undefined` |
| `yearValues` | `year-values` | Values used to create the list of selectable years. By default the year values range between the `min` and `max` datetime inputs. However, to control exactly which years to display, the `yearValues` input can take a number, an array of numbers, or string of comma separated numbers. For example, to show upcoming and recent leap years, then this input's value would be `yearValues="2024,2020,2016,2012,2008"`. | `number \| number[] \| string \| undefined` | `undefined` |
## Events ## Events
@ -612,10 +613,11 @@ Type: `Promise<void>`
## Slots ## Slots
| Slot | Description | | Slot | Description |
| ----------- | ---------------------------- | | -------------- | ------------------------------------------------ |
| `"buttons"` | The buttons in the datetime. | | `"buttons"` | The buttons in the datetime. |
| `"title"` | The title of the datetime. | | `"time-label"` | The label for the time selector in the datetime. |
| `"title"` | The title of the datetime. |
## CSS Custom Properties ## CSS Custom Properties

View File

@ -0,0 +1,15 @@
import { newE2EPage } from '@stencil/core/testing';
test('time-label', async () => {
const page = await newE2EPage({
url: '/src/components/datetime/test/time-label?ionic:_testing=true'
});
const screenshotCompares = [];
screenshotCompares.push(await page.compareScreenshot());
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
});

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Datetime - Time label</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<style>
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(250px, 1fr));
grid-gap: 20px;
}
h2 {
font-size: 12px;
font-weight: normal;
color: #6f7378;
margin-top: 10px;
margin-left: 5px;
}
ion-datetime {
box-shadow: 0px 16px 32px rgba(0, 0, 0, 0.25), 0px 8px 16px rgba(0, 0, 0, 0.25);
border-radius: 8px;
}
</style>
</head>
<body>
<ion-app>
<ion-header translucent="true">
<ion-toolbar>
<ion-title>Datetime - Time Label</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div class="grid">
<div class="grid-item">
<h2>Default Time Label</h2>
<ion-datetime show-default-time-label="true"></ion-datetime>
</div>
<div class="grid-item">
<h2>No Default Time Label</h2>
<ion-datetime show-default-time-label="false"></ion-datetime>
</div>
<div class="grid-item">
<h2>Custom Time Label</h2>
<ion-datetime>
<div slot="time-label">Custom Time</div>
</ion-datetime>
</div>
</div>
</ion-content>
</ion-app>
</body>
</html>

View File

@ -284,6 +284,7 @@ export const IonDatetime = /*@__PURE__*/ defineContainer<JSX.IonDatetime>('ion-d
'value', 'value',
'showDefaultTitle', 'showDefaultTitle',
'showDefaultButtons', 'showDefaultButtons',
'showDefaultTimeLabel',
'ionCancel', 'ionCancel',
'ionChange', 'ionChange',
'ionFocus', 'ionFocus',