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 {
}
@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"] })
@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"] })
@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", "showDefaultTimeLabel", "showDefaultTitle", "value", "yearValues"] })
export class IonDatetime {
ionCancel!: 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,readonly,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,value,null | 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.
*/
"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.
*/
@ -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.
*/
"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.
*/

View File

@ -62,6 +62,7 @@ import {
*
* @slot title - The title of the datetime.
* @slot buttons - The buttons in the datetime.
* @slot time-label - The label for the time selector in the datetime.
*/
@Component({
tag: 'ion-datetime',
@ -307,6 +308,16 @@ export class Datetime implements ComponentInterface {
*/
@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.
*/
@ -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.
* 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);
return (
<div class="datetime-time">
<div class="time-header">Time</div>
<div class="time-header">
{this.renderTimeLabel()}
</div>
<div class="time-body">
<div class="time-base" ref={el => this.timeBaseRef = el}>
<div class="time-wrapper">

View File

@ -537,7 +537,7 @@ export class DatetimeExample {
## Properties
| Property | Attribute | Description | Type | Default |
| -------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -------------- |
| ---------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | -------------- |
| `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'` |
| `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` |
@ -554,6 +554,7 @@ export class DatetimeExample {
| `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` |
| `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` |
| `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` |
| `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` |
| `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` |
@ -613,8 +614,9 @@ Type: `Promise<void>`
## Slots
| Slot | Description |
| ----------- | ---------------------------- |
| -------------- | ------------------------------------------------ |
| `"buttons"` | The buttons in the datetime. |
| `"time-label"` | The label for the time selector in the datetime. |
| `"title"` | The title of the datetime. |

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',
'showDefaultTitle',
'showDefaultButtons',
'showDefaultTimeLabel',
'ionCancel',
'ionChange',
'ionFocus',