Skip to content

feat(datetime-button): add base styles and examples #25618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { AccordionGroupChangeEventDetail, ActionSheetAttributes, ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, BreadcrumbCollapsedClickEventDetail, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, LoadingAttributes, MenuChangeEventDetail, ModalAttributes, ModalBreakpointChangeEventDetail, ModalHandleBehavior, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerAttributes, PickerButton, PickerColumn, PopoverAttributes, PopoverSize, PositionAlign, PositionReference, PositionSide, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, TriggerAction, ViewController } from "./interface";
import { AccordionGroupChangeEventDetail, ActionSheetAttributes, ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, BreadcrumbCollapsedClickEventDetail, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DatetimePresentation, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, LoadingAttributes, MenuChangeEventDetail, ModalAttributes, ModalBreakpointChangeEventDetail, ModalHandleBehavior, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerAttributes, PickerButton, PickerColumn, PopoverAttributes, PopoverSize, PositionAlign, PositionReference, PositionSide, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeKnobMoveEndEventDetail, RangeKnobMoveStartEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, TriggerAction, ViewController } from "./interface";
import { IonicSafeString } from "./utils/sanitization";
import { AlertAttributes } from "./components/alert/alert-interface";
import { CounterFormatter } from "./components/item/item-interface";
Expand Down Expand Up @@ -796,7 +796,7 @@ export namespace Components {
/**
* 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.
*/
"presentation": 'date-time' | 'time-date' | 'date' | 'time' | 'month' | 'year' | 'month-year';
"presentation": DatetimePresentation;
/**
* If `true`, the datetime appears normal but is not interactive.
*/
Expand Down Expand Up @@ -4764,7 +4764,7 @@ declare namespace LocalJSX {
/**
* 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.
*/
"presentation"?: 'date-time' | 'time-date' | 'date' | 'time' | 'month' | 'year' | 'month-year';
"presentation"?: DatetimePresentation;
/**
* If `true`, the datetime appears normal but is not interactive.
*/
Expand Down
33 changes: 33 additions & 0 deletions core/src/components/datetime-button/datetime-button.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@import "../../themes/ionic.globals";

// Datetime Button
// --------------------------------------------------

:host {
display: flex;

align-items: center;

justify-content: center;
}

:host button {
@include border-radius(8px);
@include padding(6px, 12px, 6px, 12px);
@include margin(0px, 2px, 0px, 2px);

transition: 150ms color ease-in-out;

border: none;

background: var(--ion-color-step-300, #edeef0);

color: $text-color;

font-family: inherit;
font-size: inherit;

cursor: pointer;

appearance: none;
}
51 changes: 48 additions & 3 deletions core/src/components/datetime-button/datetime-button.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Host, Prop, h } from '@stencil/core';
import { Component, Host, Prop, State, h } from '@stencil/core';

import type { Color } from '../../interface';
import { getIonMode } from '../../global/ionic-global';
import type { Color, DatetimePresentation } from '../../interface';
import { createColorClasses } from '../../utils/theme';

/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*
* @slot date-target - Content displayed inside of the date button.
* @slot time-target - Content displayed inside of the time button.
*/
@Component({
tag: 'ion-datetime-button',
styleUrl: 'datetime-button.scss',
shadow: true,
})
export class DatetimeButton implements ComponentInterface {
// STUBs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few questions in this area:

  1. What does the // STUBs comment signify?
  2. Do these state values get set to undefined at some point in execution/configuration?
  3. Should these variables have default values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"stub" means that the values are placeholders. It allows me to focus on getting the styles working first without having to worry about implementation details. The implementation is here: #25620 (note that the stubs are removed and replaced with actual values)

@State() datetimePresentation?: DatetimePresentation = 'date-time';
@State() dateText?: string = 'May 1, 2022';
@State() timeText?: string = '12:30 PM';

/**
* The color to use from your application's color palette.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
Expand All @@ -31,6 +41,41 @@ export class DatetimeButton implements ComponentInterface {
@Prop() datetime?: string;

render() {
return <Host></Host>;
const { color, dateText, timeText, datetimePresentation } = this;

const showDateTarget =
!datetimePresentation ||
['date-time', 'time-date', 'date', 'month', 'year', 'month-year'].includes(datetimePresentation);
const showTimeTarget = !datetimePresentation || ['date-time', 'time-date', 'time'].includes(datetimePresentation);
const mode = getIonMode(this);

return (
<Host
class={createColorClasses(color, {
[mode]: true,
})}
>
{showDateTarget && (
<div class="date-target-container">
<slot name="date-target">
{/*
The button is added inside of the <slot> so that
devs do not create nested interactives if they
decide to add in a custom ion-button.
*/}
<button id="date-button">{dateText}</button>
</slot>
</div>
)}

{showTimeTarget && (
<div class="time-target-container">
<slot name="time-target">
<button id="time-button">{timeText}</button>
</slot>
</div>
)}
</Host>
);
}
}
72 changes: 72 additions & 0 deletions core/src/components/datetime-button/test/accordion/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Datetime Button - Accordion</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(auto-fill, minmax(250px, 1fr));
grid-row-gap: 20px;
grid-column-gap: 20px;
}
h2 {
font-size: 12px;
font-weight: normal;

color: #6f7378;

margin-top: 10px;
margin-left: 5px;
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Datetime Button - Accordion</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-accordion-group>
<ion-accordion value="starts">
<ion-item slot="header">
<ion-label>Starts</ion-label>
<ion-datetime-button slot="end" datetime="starts-datetime"></ion-datetime-button>
</ion-item>

<ion-datetime slot="content" id="starts-datetime"></ion-datetime>
</ion-accordion>

<ion-accordion value="ends">
<ion-item slot="header">
<ion-label>Ends</ion-label>
<ion-datetime-button slot="end" datetime="ends-datetime"></ion-datetime-button>
</ion-item>

<ion-datetime slot="content" id="ends-datetime"></ion-datetime>
</ion-accordion>
</ion-accordion-group>
</ion-content>

<script>
const datetimeButtons = document.querySelectorAll('ion-datetime-button');
const accordionGroup = document.querySelector('ion-accordion-group');
datetimeButtons.forEach((el) => {
const accordion = el.closest('ion-accordion');

el.onclick = (ev) => {
accordionGroup.value = accordion.value;
ev.stopPropagation();
};
});
</script>
</ion-app>
</body>
</html>
Loading