Skip to content
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

feat: Calendar and DateTimePicker components #5002

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5d1b88d
feat(calendar): add calendar component (#3327)
paulodetarsofm Mar 6, 2024
dba893a
feat: add input segments + time field (#3464)
paulodetarsofm Mar 6, 2024
9c2afe7
refactor: fix conflicts + bump packages version
paulodetarsofm Mar 6, 2024
c2c4e26
chore: bump packages from 0.39.3 to 0.41.2
paulodetarsofm Mar 6, 2024
a77baab
fix: input segments
paulodetarsofm Nov 29, 2023
c652585
chore: bump packages to 0.41.2
paulodetarsofm Mar 6, 2024
b606e31
chore: bump packages to 0.41.2
paulodetarsofm Mar 6, 2024
e6fe7bc
feat(date-time-picker): add date/time input + picker (#3856)
mirekszot Aug 8, 2024
d187b7a
feat(calendar): keyboard navigation (#4667)
mizgaionutalexandru Aug 28, 2024
9d2e6f6
chore: update versions
mizgaionutalexandru Sep 6, 2024
0f01c5f
feat: new value and constraints API for Calendar and DateTimePicker (…
mizgaionutalexandru Oct 10, 2024
5804e1d
feat(date-time-picker): added precision and value interactions (#4812)
mizgaionutalexandru Oct 21, 2024
dd8cf1d
feat(date-time-picker): events and invalid triggering (#4845)
mizgaionutalexandru Oct 28, 2024
2bc9506
fix(date-time-picker): ux bug fixes and improvements (#4875)
mizgaionutalexandru Oct 31, 2024
e0076cd
test: finish DateTimePicker and Calendar unit tests and VRTs (#4962)
mizgaionutalexandru Dec 4, 2024
9e16e7c
feat: screen reader support for Calendar and DateTimePicker (#4982)
mizgaionutalexandru Dec 13, 2024
8c94e37
chore: rebase fixes and version bumps
mizgaionutalexandru Dec 13, 2024
ba424e0
docs: updated documentation for Calendar and DateTimePicker component…
mizgaionutalexandru Dec 24, 2024
3a91efc
ci: remove golden image hash update
mizgaionutalexandru Dec 24, 2024
32802e5
chore: remove picker format changes
mizgaionutalexandru Dec 24, 2024
3502508
chore: fix typos
mizgaionutalexandru Jan 9, 2025
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
2 changes: 2 additions & 0 deletions packages/calendar/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
stories
test
140 changes: 140 additions & 0 deletions packages/calendar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
## Description

`<sp-calendar>` elements display all the days within a given month, indicating the current day. Users can also see past or future months, and select a specific date via pointer, <kbd>Space</kbd> or <kbd>Enter</kbd>.

### Usage

[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/calendar?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/calendar)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/calendar?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/calendar)

```
yarn add @spectrum-web-components/calendar
```

Import the side effectful registration of `<sp-calendar>` via:

```
import '@spectrum-web-components/calendar/sp-calendar.js';
```

When looking to leverage the `Calendar` base class as a type and/or for extension purposes, do so via:

```
import { Calendar } from '@spectrum-web-components/calendar';
```

## Example

By default, the `<sp-calendar>` element will display the current month with emphasis on the current day and no pre-selected date.

```html
<sp-calendar></sp-calendar>
```

## Value

A pre-selected date value can be provided to the `<sp-calendar>` element and it will dictate the displayed month of the element.
Setting the `value` property requires a `DateValue` type (`DateValue = CalendarDate | CalendarDateTime | ZonedDateTime`).
When reading the value by `element.value`, the consumer will always receive a `CalendarDate` type value.
More about these types and when to use each one can be found on the [`@internationalized/date` page](https://react-spectrum.adobe.com/internationalized/date/index.html).

To clear the element's value, the `clear` method can be used. (`element.clear()`)

```ts
import {CalendarDate} from '@internationalized/date';

<sp-calendar id="min-max-calendar"
.value=${new CalendarDate(2020, 2, 14)}
></sp-calendar>
```

## Minimum and maximum values

The `min` and `max` properties can be used to limit the selected value to a specific range. Ranges can be open, by providing only one of the mentioned properties, or closed, when both `min` and `max` are provided. These properties are also of `DateValue` type, but will always be of `CalendarDate` type when read, similar to `value`.

If the provided closed interval is not a valid one (e.g `min > max`), the assignment of those properties gets ignored. The same way, if a pre-selected value doesn't comply with the interval, it gets ignored and the element will behave as it wouldn't have a `value` provided.

```html-live
<div id="calendar-with-min-max"></div>

<script type="module">
import { CalendarDate } from '@internationalized/date';
import { SpectrumElement } from '@spectrum-web-components/base';
import { html, render } from 'lit';
import '@spectrum-web-components/calendar/sp-calendar.js';

class CalendarWithMinMax extends SpectrumElement {
render(){
return html`
<sp-calendar
.min=${new CalendarDate(2020, 2, 14)}
.max=${new CalendarDate(2020, 2, 19)}
></sp-calendar>`
}
}

customElements.define("calendar-with-min-max", CalendarWithMinMax);

onCodeExamplesLoaded(() => {
const root = document.querySelector('#calendar-with-min-max');
root.innerHTML = '';
render(html`<calendar-with-min-max></calendar-with-min-max>`, root);
})
</script>
```

<script type="module">
window.onCodeExamplesLoaded = (callback) => {
customElements.whenDefined('code-example').then(() => {
Promise.all([...document.querySelectorAll('code-example')].map(example => example.updateComplete)).then(callback);
});
}
</script>

<script type="module">
import { CalendarDate } from '@internationalized/date';
import { SpectrumElement } from '@spectrum-web-components/base';
import { html, render } from 'lit';
import '@spectrum-web-components/calendar/sp-calendar.js';

class CalendarWithMinMax extends SpectrumElement {
render(){
return html`
<sp-calendar
.min=${new CalendarDate(2020, 2, 14)}
.max=${new CalendarDate(2020, 2, 19)}
></sp-calendar>`
}
}

customElements.define("calendar-with-min-max", CalendarWithMinMax);

onCodeExamplesLoaded(() => {
const root = document.querySelector('#calendar-with-min-max');
root.innerHTML = '';
render(html`<calendar-with-min-max></calendar-with-min-max>`, root);
})
</script>

## Events

In order to react to date selection changes, consumers can leverage the `change` event and read the value of the event target in the handler.

```ts
import { CalendarDate } from '@internationalized/date';
import { Calendar } from '@spectrum-web-components/calendar';

const handleCalendarChange = (event: Event) => {
const selectedDate = (event.target as Calendar).value as CalendarDate;
// use the selectedDate...
};
```

## Internationalization

The `<sp-calendar` element supports multiple locales and updates its content accordingly.
mizgaionutalexandru marked this conversation as resolved.
Show resolved Hide resolved
`element.locale` represents the language in which the `<sp-calendar>` element is currently being delivered. By default, the value will represent the language established by the `lang` attribute on the root `<html>` element, with a fallback to `navigator.language`. This can be customized via a language context provider by a parent element that listens for `sp-language-context` event and supplies update language settings to the `callback` function. Applications leveraging the [`<sp-theme>`](./components/theme) element to manage the visual delivery or text direction of their content will also be provided with a reactive context for supplying language information to its descendants.

Currently the `<sp-calendar>` elements supports only the Gregorian calendar and the AD era.

While providing support for screen readers, the element needs some labels to be internationalized by the consumer to offer non-english alternatives. This can be done via the `labels` property.
4 changes: 4 additions & 0 deletions packages/calendar/exports.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"./src/*": "./src/*.js",
"./sp-calendar.js": "./sp-calendar.js"
}
81 changes: 81 additions & 0 deletions packages/calendar/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"name": "@spectrum-web-components/calendar",
"version": "1.0.3",
"publishConfig": {
"access": "public"
},
"description": "Web component implementation of a Spectrum Calendar",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/adobe/spectrum-web-components.git",
"directory": "packages/calendar"
},
"author": "",
"homepage": "https://adobe.github.io/spectrum-web-components/components/calendar",
"bugs": {
"url": "https://github.com/adobe/spectrum-web-components/issues"
},
"main": "./src/index.js",
"module": "./src/index.js",
"type": "module",
"exports": {
".": {
"development": "./src/index.dev.js",
"default": "./src/index.js"
},
"./package.json": "./package.json",
"./src/Calendar.js": {
"development": "./src/Calendar.dev.js",
"default": "./src/Calendar.js"
},
"./src/calendar-overrides.css.js": "./src/calendar-overrides.css.js",
"./src/calendar.css.js": "./src/calendar.css.js",
"./src/index.js": {
"development": "./src/index.dev.js",
"default": "./src/index.js"
},
"./src/types.js": {
"development": "./src/types.dev.js",
"default": "./src/types.js"
},
"./sp-calendar.js": {
"development": "./sp-calendar.dev.js",
"default": "./sp-calendar.js"
}
},
"scripts": {
"test": "echo \"Error: run tests from mono-repo root.\" && exit 1"
},
"files": [
"**/*.d.ts",
"**/*.js",
"**/*.js.map",
"custom-elements.json",
"!stories/",
"!test/"
],
"keywords": [
"spectrum css",
"web components",
"lit-element",
"lit-html"
],
"dependencies": {
"@internationalized/date": "^3.6.0",
"@internationalized/number": "^3.6.0",
"@spectrum-web-components/action-button": "^1.0.3",
"@spectrum-web-components/base": "^1.0.3",
"@spectrum-web-components/icons-workflow": "^1.0.3",
"@spectrum-web-components/reactive-controllers": "^1.0.3"
},
"devDependencies": {
"@spectrum-css/calendar": "^6.0.0-s2-foundations.15"
},
"types": "./src/index.d.ts",
"customElements": "custom-elements.json",
"sideEffects": [
"./sp-*.js",
"./**/*.dev.js"
]
}
20 changes: 20 additions & 0 deletions packages/calendar/sp-calendar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { Calendar } from './src/Calendar.js';

customElements.define('sp-calendar', Calendar);

declare global {
interface HTMLElementTagNameMap {
'sp-calendar': Calendar;
}
}
Loading
Loading