Skip to content

Commit f2c1845

Browse files
feat(datetime): add shadow parts and CSS variables for styling wheel pickers (#27529)
Issue number: resolves #25945 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> Datetime wheel pickers cannot be styled. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> Adds styling APIs in accordance with the Wheel Pickers and Time Picker sections of [this design doc](https://github.com/ionic-team/ionic-framework-design-documents/blob/main/projects/ionic-framework/components/datetime/datetime-styling.md). Shadow parts added: - `wheel-item` - `wheel-item active` - `time-button` - `time-button active` CSS properties added: - `--wheel-highlight-background` - `--wheel-fade-background-rgb` ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev build: `7.0.7-dev.11685554390.10c2ca9b` Docs PR: ionic-team/ionic-docs#2982
1 parent ea817a5 commit f2c1845

File tree

40 files changed

+206
-14
lines changed

40 files changed

+206
-14
lines changed

core/api.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,12 @@ ion-datetime,event,ionFocus,void,true
425425
ion-datetime,css-prop,--background
426426
ion-datetime,css-prop,--background-rgb
427427
ion-datetime,css-prop,--title-color
428+
ion-datetime,css-prop,--wheel-fade-background-rgb
429+
ion-datetime,css-prop,--wheel-highlight-background
430+
ion-datetime,part,time-button
431+
ion-datetime,part,time-button active
432+
ion-datetime,part,wheel-item
433+
ion-datetime,part,wheel-item active
428434

429435
ion-datetime-button,shadow
430436
ion-datetime-button,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,'primary',false,true

core/src/components/datetime/datetime.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
* @prop --background: The primary background of the datetime component.
99
* @prop --background-rgb: The primary background of the datetime component in RGB format.
1010
* @prop --title-color: The text color of the title.
11+
*
12+
* @prop --wheel-highlight-background: The background of the highlight under the selected
13+
* item when using a wheel style layout, or in the month/year picker for grid style layouts.
14+
* @prop --wheel-fade-background-rgb: The color of the gradient covering non-selected items
15+
* when using a wheel style layout, or in the month/year picker for grid style layouts. Must
16+
* be in RGB format, e.g. `255, 255, 255`.
1117
*/
1218

1319
display: flex;

core/src/components/datetime/datetime.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ import {
7474
* @slot title - The title of the datetime.
7575
* @slot buttons - The buttons in the datetime.
7676
* @slot time-label - The label for the time selector in the datetime.
77+
*
78+
* @part wheel-item - The individual items when using a wheel style layout, or in the
79+
* month/year picker when using a grid style layout.
80+
* @part wheel-item active - The currently selected wheel-item.
81+
*
82+
* @part time-button - The button that opens the time picker when using a grid style
83+
* layout with `presentation="date-time"` or `"time-date"`.
84+
* @part time-button active - The time picker button when the picker is open.
7785
*/
7886
@Component({
7987
tag: 'ion-datetime',
@@ -2167,16 +2175,18 @@ export class Datetime implements ComponentInterface {
21672175
}
21682176

21692177
private renderTimeOverlay() {
2170-
const use24Hour = is24Hour(this.locale, this.hourCycle);
2178+
const { hourCycle, isTimePopoverOpen, locale } = this;
2179+
const use24Hour = is24Hour(locale, hourCycle);
21712180
const activePart = this.getActivePartsWithFallback();
21722181

21732182
return [
21742183
<div class="time-header">{this.renderTimeLabel()}</div>,
21752184
<button
21762185
class={{
21772186
'time-body': true,
2178-
'time-body-active': this.isTimePopoverOpen,
2187+
'time-body-active': isTimePopoverOpen,
21792188
}}
2189+
part={`time-button${isTimePopoverOpen ? ' active' : ''}`}
21802190
aria-expanded="false"
21812191
aria-haspopup="true"
21822192
onClick={async (ev) => {
@@ -2199,7 +2209,7 @@ export class Datetime implements ComponentInterface {
21992209
}
22002210
}}
22012211
>
2202-
{getLocalizedTime(this.locale, activePart, use24Hour)}
2212+
{getLocalizedTime(locale, activePart, use24Hour)}
22032213
</button>,
22042214
<ion-popover
22052215
alignment="center"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { expect } from '@playwright/test';
2+
import { configs, test } from '@utils/test/playwright';
3+
4+
configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
5+
test.describe(title('datetime: custom'), () => {
6+
test.beforeEach(async ({ page }) => {
7+
await page.goto(`/src/components/datetime/test/custom`, config);
8+
});
9+
10+
test('should allow styling wheel style datetimes', async ({ page }) => {
11+
const datetime = page.locator('#custom-wheel');
12+
13+
await expect(datetime).toHaveScreenshot(screenshot(`datetime-custom-wheel`));
14+
});
15+
16+
test('should allow styling month/year picker in grid style datetimes', async ({ page }) => {
17+
const datetime = page.locator('#custom-grid');
18+
const monthYearToggle = datetime.locator('.calendar-month-year');
19+
20+
await monthYearToggle.click();
21+
await page.waitForChanges();
22+
23+
await expect(datetime).toHaveScreenshot(screenshot(`datetime-custom-month-year`));
24+
});
25+
26+
test('should allow styling time picker in grid style datetimes', async ({ page }) => {
27+
const timeButton = page.locator('ion-datetime .time-body');
28+
const popover = page.locator('.popover-viewport');
29+
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
30+
31+
await expect(timeButton).toHaveScreenshot(screenshot(`datetime-custom-time-button`));
32+
33+
await timeButton.click();
34+
await ionPopoverDidPresent.next();
35+
36+
await expect(popover).toHaveScreenshot(screenshot(`datetime-custom-time-picker`));
37+
await expect(timeButton).toHaveScreenshot(screenshot(`datetime-custom-time-button-active`));
38+
});
39+
});
40+
});
14.6 KB
Loading
16.7 KB
Loading
11.7 KB
Loading
16 KB
Loading
18.6 KB
Loading
12.6 KB
Loading

0 commit comments

Comments
 (0)