Skip to content

Commit ddb9aa9

Browse files
docs(datetime): adds playground for styling calendar days using shadow parts (#3101)
1 parent 56a8060 commit ddb9aa9

File tree

12 files changed

+482
-5
lines changed

12 files changed

+482
-5
lines changed

docs/api/datetime.md

+16-5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import HighlightedDatesCallback from '@site/static/usage/v7/datetime/highlighted
3737
import MultipleDateSelection from '@site/static/usage/v7/datetime/multiple/index.md';
3838

3939
import GlobalTheming from '@site/static/usage/v7/datetime/styling/global-theming/index.md';
40+
import CalendarDaysStyling from '@site/static/usage/v7/datetime/styling/calendar-days/index.md';
4041
import WheelStyling from '@site/static/usage/v7/datetime/styling/wheel-styling/index.md';
4142

4243
<head>
@@ -50,7 +51,7 @@ import EncapsulationPill from '@components/page/api/EncapsulationPill';
5051

5152
Datetimes present a calendar interface and time wheel, making it easy for users to select dates and times. Datetimes are similar to the native `input` elements of `datetime-local`, however, Ionic Framework's Datetime component makes it easy to display the date and time in the preferred format, and manage the datetime values.
5253

53-
## Overview
54+
## Overview
5455

5556
Historically, handling datetime values within JavaScript, or even within HTML
5657
inputs, has always been a challenge. Specifically, JavaScript's `Date` object is
@@ -100,15 +101,15 @@ If you need to present a datetime in an overlay such as a modal or a popover, we
100101

101102
## Setting Values Asynchronously
102103

103-
If its `value` is updated programmatically after a datetime has already been created, the datetime will automatically jump to the new date. However, it is recommended to avoid updating the `value` in this way when users are able to interact with the datetime, as this could be disorienting for those currently trying to select a date. For example, if a datetime's `value` is loaded by an asyncronous process, it is recommended to hide the datetime with CSS until the value has finished updating.
104+
If its `value` is updated programmatically after a datetime has already been created, the datetime will automatically jump to the new date. However, it is recommended to avoid updating the `value` in this way when users are able to interact with the datetime, as this could be disorienting for those currently trying to select a date. For example, if a datetime's `value` is loaded by an asynchronous process, it is recommended to hide the datetime with CSS until the value has finished updating.
104105

105106
## Date Constraints
106107

107108
### Max and Min Dates
108109

109110
To customize the minimum and maximum datetime values, the `min` and `max` component properties can be provided which may make more sense for the app's use-case. Following the same IS0 8601 format listed in the table above, each component can restrict which dates can be selected by the user.
110111

111-
The following example restricts date selection to March 2022 through May 2022 only.
112+
The following example restricts date selection to March 2022 through May 2022 only.
112113

113114
<MaxMin />
114115

@@ -122,7 +123,7 @@ The following example allows minutes to be selected in increments of 15. It also
122123

123124
### Advanced Date Constraints
124125

125-
With the `isDateEnabled` property, developers can customize the `ion-datetime` to disable a specific day, range of dates, weekends or any custom rule using an ISO 8601 date string.
126+
With the `isDateEnabled` property, developers can customize the `ion-datetime` to disable a specific day, range of dates, weekends or any custom rule using an ISO 8601 date string.
126127
The `isDateEnabled` property accepts a function returning a boolean, indicating if a date is enabled. The function is called for each rendered calendar day, for the previous, current and next month. Custom implementations should be optimized for performance to avoid jank.
127128

128129
The following example shows how to disable all weekend dates. For more advanced date manipulation, we recommend using a date utility such as `date-fns`.
@@ -325,6 +326,16 @@ The benefit of this approach is that every component, not just `ion-datetime`, c
325326

326327
<GlobalTheming />
327328

329+
### Calendar Days
330+
331+
The calendar days in a grid-style `ion-datetime` can be styled using CSS shadow parts.
332+
333+
:::note
334+
The example below selects the day 2 days ago, unless that day is in the previous month, then it selects a day 2 days in the future. This is done for demo purposes in order to show how to apply custom styling to all days, the current day, and the selected day.
335+
:::
336+
337+
<CalendarDaysStyling />
338+
328339
### Wheel Pickers
329340

330341
The wheels used in `ion-datetime` can be styled through a combination of shadow parts and CSS variables. This applies to both the columns in wheel-style datetimes, and the month/year picker in grid-style datetimes.
@@ -367,7 +378,7 @@ import { format, parseISO } from 'date-fns';
367378
/**
368379
* This is provided in the event
369380
* payload from the `ionChange` event.
370-
*
381+
*
371382
* The value is an ISO-8601 date string.
372383
*/
373384
const dateFromIonDatetime = '2021-06-04T14:23:00-04:00';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
```css
2+
/*
3+
* Custom Datetime Day Parts
4+
* -------------------------------------------
5+
*/
6+
7+
ion-datetime::part(calendar-day) {
8+
color: #da5296;
9+
}
10+
11+
ion-datetime::part(calendar-day today) {
12+
color: #8462d1;
13+
}
14+
15+
ion-datetime::part(calendar-day):focus {
16+
background-color: rgb(154 209 98 / 0.2);
17+
box-shadow: 0px 0px 0px 4px rgb(154 209 98 / 0.2);
18+
}
19+
20+
/*
21+
* Custom Material Design Datetime Day Parts
22+
* -------------------------------------------
23+
*/
24+
25+
ion-datetime.md::part(calendar-day active),
26+
ion-datetime.md::part(calendar-day active):focus {
27+
background-color: #9ad162;
28+
border-color: #9ad162;
29+
color: #fff;
30+
}
31+
32+
ion-datetime.md::part(calendar-day today) {
33+
border-color: #8462d1;
34+
}
35+
36+
/*
37+
* Custom iOS Datetime Day Parts
38+
* -------------------------------------------
39+
*/
40+
41+
ion-datetime.ios::part(calendar-day active),
42+
ion-datetime.ios::part(calendar-day active):focus {
43+
background-color: rgb(154 209 98 / 0.2);
44+
color: #9ad162;
45+
}
46+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```html
2+
<ion-datetime presentation="date" [(ngModel)]="datetime"></ion-datetime>
3+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
```ts
2+
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
3+
4+
// ViewEncapsulation is turned off for this demo due to
5+
// a lack of support for styling multiple css shadow parts
6+
// See https://github.com/angular/angular/issues/22515
7+
@Component({
8+
selector: 'app-example',
9+
templateUrl: 'example.component.html',
10+
styleUrls: ['example.component.css'],
11+
encapsulation: ViewEncapsulation.None,
12+
})
13+
export class ExampleComponent implements OnInit {
14+
public datetime;
15+
16+
ngOnInit() {
17+
const date = new Date();
18+
19+
// Set the value of the datetime to 2 days
20+
// before the current day
21+
let dayChange = -2;
22+
23+
// If the day we are going to set the value to
24+
// is in the previous month then set the day 2 days
25+
// later instead so it remains in the same month
26+
if (date.getDate() + dayChange <= 0) {
27+
dayChange = -dayChange;
28+
}
29+
30+
// Set the value of the datetime to the day
31+
// calculated above
32+
date.setDate(date.getDate() + dayChange);
33+
this.datetime = date.toISOString();
34+
}
35+
}
36+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Datetime</title>
7+
<link rel="stylesheet" href="../../../../common.css" />
8+
<script src="../../../../common.js"></script>
9+
<script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@7/dist/ionic/ionic.esm.js"></script>
10+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@7/css/ionic.bundle.css" />
11+
12+
<style>
13+
/*
14+
* Custom Datetime Day Parts
15+
* -------------------------------------------
16+
*/
17+
18+
ion-datetime::part(calendar-day) {
19+
color: #da5296;
20+
}
21+
22+
ion-datetime::part(calendar-day today) {
23+
color: #8462d1;
24+
}
25+
26+
ion-datetime::part(calendar-day):focus {
27+
background-color: rgb(154 209 98 / 0.2);
28+
box-shadow: 0px 0px 0px 4px rgb(154 209 98 / 0.2);
29+
}
30+
31+
/*
32+
* Custom Material Design Datetime Day Parts
33+
* -------------------------------------------
34+
*/
35+
36+
ion-datetime.md::part(calendar-day active),
37+
ion-datetime.md::part(calendar-day active):focus {
38+
background-color: #9ad162;
39+
border-color: #9ad162;
40+
color: #fff;
41+
}
42+
43+
ion-datetime.md::part(calendar-day today) {
44+
border-color: #8462d1;
45+
}
46+
47+
/*
48+
* Custom iOS Datetime Day Parts
49+
* -------------------------------------------
50+
*/
51+
52+
ion-datetime.ios::part(calendar-day active),
53+
ion-datetime.ios::part(calendar-day active):focus {
54+
background-color: rgb(154 209 98 / 0.2);
55+
color: #9ad162;
56+
}
57+
</style>
58+
</head>
59+
60+
<body>
61+
<ion-app>
62+
<ion-content>
63+
<div class="container">
64+
<ion-datetime presentation="date"></ion-datetime>
65+
</div>
66+
</ion-content>
67+
</ion-app>
68+
69+
<script>
70+
const datetime = document.querySelector('ion-datetime');
71+
72+
const date = new Date();
73+
74+
// Set the value of the datetime to 2 days
75+
// before the current day
76+
let dayChange = -2;
77+
78+
// If the day we are going to set the value to
79+
// is in the previous month then set the day 2 days
80+
// later instead so it remains in the same month
81+
if (date.getDate() + dayChange <= 0) {
82+
dayChange = -dayChange;
83+
}
84+
85+
// Set the value of the datetime to the day
86+
// calculated above
87+
date.setDate(date.getDate() + dayChange);
88+
datetime.value = date.toISOString();
89+
</script>
90+
</body>
91+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import Playground from '@site/src/components/global/Playground';
2+
3+
import javascript from './javascript.md';
4+
5+
import react_main_tsx from './react/main_tsx.md';
6+
import react_main_css from './react/main_css.md';
7+
8+
import vue from './vue.md';
9+
10+
import angular_example_component_html from './angular/example_component_html.md';
11+
import angular_example_component_css from './angular/example_component_css.md';
12+
import angular_example_component_ts from './angular/example_component_ts.md';
13+
14+
<Playground
15+
version="7"
16+
code={{
17+
javascript,
18+
react: {
19+
files: {
20+
'src/main.tsx': react_main_tsx,
21+
'src/main.css': react_main_css,
22+
},
23+
},
24+
vue,
25+
angular: {
26+
files: {
27+
'src/app/example.component.html': angular_example_component_html,
28+
'src/app/example.component.css': angular_example_component_css,
29+
'src/app/example.component.ts': angular_example_component_ts,
30+
},
31+
},
32+
}}
33+
src="usage/v7/datetime/styling/calendar-days/demo.html"
34+
size="medium"
35+
/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
```html
2+
<ion-datetime presentation="date"></ion-datetime>
3+
4+
<script>
5+
const datetime = document.querySelector('ion-datetime');
6+
7+
const date = new Date();
8+
9+
// Set the value of the datetime to 2 days
10+
// before the current day
11+
let dayChange = -2;
12+
13+
// If the day we are going to set the value to
14+
// is in the previous month then set the day 2 days
15+
// later instead so it remains in the same month
16+
if (date.getDate() + dayChange <= 0) {
17+
dayChange = -dayChange;
18+
}
19+
20+
// Set the value of the datetime to the day
21+
// calculated above
22+
date.setDate(date.getDate() + dayChange);
23+
datetime.value = date.toISOString();
24+
</script>
25+
26+
<style>
27+
/*
28+
* Custom Datetime Day Parts
29+
* -------------------------------------------
30+
*/
31+
32+
ion-datetime::part(calendar-day) {
33+
color: #da5296;
34+
}
35+
36+
ion-datetime::part(calendar-day today) {
37+
color: #8462d1;
38+
}
39+
40+
ion-datetime::part(calendar-day):focus {
41+
background-color: rgb(154 209 98 / 0.2);
42+
box-shadow: 0px 0px 0px 4px rgb(154 209 98 / 0.2);
43+
}
44+
45+
/*
46+
* Custom Material Design Datetime Day Parts
47+
* -------------------------------------------
48+
*/
49+
50+
ion-datetime.md::part(calendar-day active),
51+
ion-datetime.md::part(calendar-day active):focus {
52+
background-color: #9ad162;
53+
border-color: #9ad162;
54+
color: #fff;
55+
}
56+
57+
ion-datetime.md::part(calendar-day today) {
58+
border-color: #8462d1;
59+
}
60+
61+
/*
62+
* Custom iOS Datetime Day Parts
63+
* -------------------------------------------
64+
*/
65+
66+
ion-datetime.ios::part(calendar-day active),
67+
ion-datetime.ios::part(calendar-day active):focus {
68+
background-color: rgb(154 209 98 / 0.2);
69+
color: #9ad162;
70+
}
71+
</style>
72+
```

0 commit comments

Comments
 (0)