@triptease/tt-calendar 6.0.2 → 6.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @triptease/tt-calendar
2
+
3
+ ## 6.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 3262c7c: Various tweaks due to running a refreshed ESLint config and better Typescript usage
package/README.md CHANGED
@@ -46,7 +46,6 @@ To run the tests in interactive watch mode run:
46
46
  npm run test:watch
47
47
  ```
48
48
 
49
-
50
49
  ## Tooling configs
51
50
 
52
51
  For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
@@ -155,7 +155,7 @@
155
155
  {
156
156
  "kind": "variable",
157
157
  "name": "styles",
158
- "default": "css` :host { display: block; } button { appearance: none; padding: 0; border-width: 0; background-color: transparent; border-radius: var(--space-scale-1); padding-block: var(--space-scale-1); padding-inline: var(--space-scale-2); &.compact { padding-block: 0; padding-inline: 0; } &:hover { cursor: pointer; box-shadow: 0px 2px 5px 0px rgba(60, 66, 87, 0.08), 0px 1px 1px 0px rgba(0, 0, 0, 0.12); } &:focus { outline: 1px solid var(--color-primary-400); } svg { display: block; } &.right svg { transform: rotate(180deg); } } h2 { font-weight: var(--font-weight-semibold); color: var(--color-text-500); font-size: var(--font-size-400); display: contents; } .calendar-header { display: flex; justify-content: space-between; align-items: center; padding: 24px 24px 16px 24px; } .calendar-grid { text-align: center; border-top: var(--color-border-200) 1px solid; padding: 0 24px; table { width: 100%; border-collapse: collapse; } tbody { display: grid; row-gap: 4px; } tr { display: grid; grid-template-columns: repeat(7, 48px); } th { color: var(--color-text-400); font-size: var(--font-size-100); font-weight: var(--font-weight-normal); line-height: 20px; padding: 16px 0; } td { font-size: var(--font-size-100); font-weight: var(--font-weight-normal); } } .calendar-footer { display: flex; flex-direction: column; //gap: var(--space-scale-2); svg { vertical-align: middle; } .actions { display: flex; flex: 1 0 auto; padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3); button { background-color: var(--color-surface-200); border-color: var(--color-primary-400); border-width: 1px; border-style: solid; color: var(--color-primary-400); font-weight: var(--font-weight-semibold); width: 100%; height: 40px; } } } .day { aspect-ratio: 1; cursor: pointer; position: relative; // For focus outline box-sizing: border-box; height: auto; display: flex; align-items: center; justify-content: center; } .day.in-range { background: var(--color-primary-300); &:first-child { border-top-left-radius: var(--space-scale-1); border-bottom-left-radius: var(--space-scale-1); } &:last-child { border-top-right-radius: var(--space-scale-1); border-bottom-right-radius: var(--space-scale-1); } } .day[aria-disabled=\"true\"] { opacity: 0.7; background-color: var(--color-surface-300); cursor: not-allowed; pointer-events: none; } .day.start-date:has(+ .in-range):after { content: \" \"; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--color-primary-300); z-index: -1; border-radius: var(--space-scale-1); border-bottom-right-radius: 0; border-top-right-radius: 0; } .day.in-range + :is(.day:hover, .day:not(.in-range)):before { content: \" \"; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--color-primary-300); z-index: -1; border-radius: var(--space-scale-1); border-bottom-left-radius: 0; border-top-left-radius: 0; } .day[aria-selected='true']:not(.in-range), .day:hover { background: var(--color-primary-400); color: var(--color-text-100); border-radius: var(--space-scale-1); font-weight: var(--font-weight-semibold); &.in-range { &:before { content: \" \"; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--color-primary-300); z-index: -1; border-radius: var(--bg-border-radius, 0); } &:first-child { --bg-border-radius: var(--space-scale-1) 0 0 var(--space-scale-1); } &:last-child { --bg-border-radius: 0 var(--space-scale-1) var(--space-scale-1) 0; } } } .side-panel-wrapper { border-right: 1px solid var(--color-border-200, var(--color-surface-300)); display: flex; align-items: start; } .side-panel { padding: var(--space-scale-3); grid-template-columns: 1fr; display: grid; gap: var(--space-scale-3); button { font-size: var(--font-size-200); text-wrap: nowrap; line-height: var(--space-scale-3); padding-block: 0; padding-inline: 0; &:hover { color: var(--color-primary-400); box-shadow: none; } &[aria-selected='true'] { color: var(--color-primary-400); } } } details { border-top: 1px solid var(--color-border-200); font-size: var(--font-size-100); font-weight: var(--font-weight-normal); padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3); summary { font-weight: var(--font-weight-semibold); position: relative; display: flex; align-items: center; gap: var(--space-scale-1); &::marker { content: \"\"; } svg.chevron-down { margin-left: var(--space-scale-1); transform: rotate(-90deg); } } &[open] svg.chevron-down { transform: rotate(0deg); } } `"
158
+ "default": "css` :host { display: block; } button { appearance: none; padding: 0; border-width: 0; background-color: transparent; border-radius: var(--space-scale-1); padding-block: var(--space-scale-1); padding-inline: var(--space-scale-2); &.compact { padding-block: 0; padding-inline: 0; } &:hover { cursor: pointer; box-shadow: 0px 2px 5px 0px rgba(60, 66, 87, 0.08), 0px 1px 1px 0px rgba(0, 0, 0, 0.12); } &:focus { outline: 1px solid var(--color-primary-400); } svg { display: block; } &.right svg { transform: rotate(180deg); } } h2 { font-weight: var(--font-weight-semibold); color: var(--color-text-500); font-size: var(--font-size-400); display: contents; } .calendar-header { display: flex; justify-content: space-between; align-items: center; padding: 24px 24px 16px 24px; } .calendar-grid { text-align: center; border-top: var(--color-border-200) 1px solid; padding: 0 24px; table { width: 100%; border-collapse: collapse; } tbody { display: grid; row-gap: 4px; } tr { display: grid; grid-template-columns: repeat(7, 48px); } th { color: var(--color-text-400); font-size: var(--font-size-100); font-weight: var(--font-weight-normal); line-height: 20px; padding: 16px 0; } td { font-size: var(--font-size-100); font-weight: var(--font-weight-normal); } } .calendar-footer { display: flex; flex-direction: column; //gap: var(--space-scale-2); svg { vertical-align: middle; } .actions { display: flex; flex: 1 0 auto; padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3); button { background-color: var(--color-surface-200); border-color: var(--color-primary-400); border-width: 1px; border-style: solid; color: var(--color-primary-400); font-weight: var(--font-weight-semibold); width: 100%; height: 40px; } } } .day { aspect-ratio: 1; cursor: pointer; position: relative; // For focus outline box-sizing: border-box; height: auto; display: flex; align-items: center; justify-content: center; } .day.in-range { background: var(--color-primary-300); &:first-child { border-top-left-radius: var(--space-scale-1); border-bottom-left-radius: var(--space-scale-1); } &:last-child { border-top-right-radius: var(--space-scale-1); border-bottom-right-radius: var(--space-scale-1); } } .day[aria-disabled='true'] { opacity: 0.7; background-color: var(--color-surface-300); cursor: not-allowed; pointer-events: none; } .day.start-date:has(+ .in-range):after { content: ' '; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--color-primary-300); z-index: -1; border-radius: var(--space-scale-1); border-bottom-right-radius: 0; border-top-right-radius: 0; } .day.in-range + :is(.day:hover, .day:not(.in-range)):before { content: ' '; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--color-primary-300); z-index: -1; border-radius: var(--space-scale-1); border-bottom-left-radius: 0; border-top-left-radius: 0; } .day[aria-selected='true']:not(.in-range), .day:hover { background: var(--color-primary-400); color: var(--color-text-100); border-radius: var(--space-scale-1); font-weight: var(--font-weight-semibold); &.in-range { &:before { content: ' '; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--color-primary-300); z-index: -1; border-radius: var(--bg-border-radius, 0); } &:first-child { --bg-border-radius: var(--space-scale-1) 0 0 var(--space-scale-1); } &:last-child { --bg-border-radius: 0 var(--space-scale-1) var(--space-scale-1) 0; } } } .side-panel-wrapper { border-right: 1px solid var(--color-border-200, var(--color-surface-300)); display: flex; align-items: start; } .side-panel { padding: var(--space-scale-3); grid-template-columns: 1fr; display: grid; gap: var(--space-scale-3); button { font-size: var(--font-size-200); text-wrap: nowrap; line-height: var(--space-scale-3); padding-block: 0; padding-inline: 0; &:hover { color: var(--color-primary-400); box-shadow: none; } &[aria-selected='true'] { color: var(--color-primary-400); } } } details { border-top: 1px solid var(--color-border-200); font-size: var(--font-size-100); font-weight: var(--font-weight-normal); padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3); summary { font-weight: var(--font-weight-semibold); position: relative; display: flex; align-items: center; gap: var(--space-scale-1); &::marker { content: ''; } svg.chevron-down { margin-left: var(--space-scale-1); transform: rotate(-90deg); } } &[open] svg.chevron-down { transform: rotate(0deg); } } `"
159
159
  }
160
160
  ],
161
161
  "exports": [
@@ -185,7 +185,7 @@
185
185
  "text": "object"
186
186
  },
187
187
  "static": true,
188
- "default": "{ ...LitElement.shadowRootOptions, delegatesFocus: true }"
188
+ "default": "{ ...LitElement.shadowRootOptions, delegatesFocus: true, }"
189
189
  },
190
190
  {
191
191
  "kind": "field",
@@ -284,7 +284,7 @@
284
284
  "kind": "field",
285
285
  "name": "visible",
286
286
  "type": {
287
- "text": "Boolean"
287
+ "text": "boolean"
288
288
  },
289
289
  "privacy": "private",
290
290
  "default": "false"
package/demo/index.html CHANGED
@@ -1,30 +1,23 @@
1
1
  <!doctype html>
2
2
  <html lang="en-GB">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
- <style>
7
- body {
8
- background: #fafafa;
9
- }
10
- </style>
11
- </head>
12
- <body>
13
- <div id="demo"></div>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <style>
7
+ body {
8
+ background: #fafafa;
9
+ }
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <div id="demo"></div>
14
14
 
15
- <script type="module">
16
- import { html, render } from 'lit';
17
- import '../dist/src/tt-calendar.js';
15
+ <script type="module">
16
+ import { html, render } from 'lit';
17
+ import '../dist/src/tt-calendar.js';
18
18
 
19
- const header = 'Hello owc World!';
20
- render(
21
- html`
22
- <tt-calendar .header=${header}>
23
- some light-dom
24
- </tt-calendar>
25
- `,
26
- document.querySelector('#demo')
27
- );
28
- </script>
29
- </body>
19
+ const header = 'Hello owc World!';
20
+ render(html` <tt-calendar .header=${header}> some light-dom </tt-calendar> `, document.querySelector('#demo'));
21
+ </script>
22
+ </body>
30
23
  </html>
@@ -1 +1 @@
1
- {"version":3,"file":"DateSelectionContext.js","sourceRoot":"","sources":["../../src/DateSelectionContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAwB7C,MAAM,OAAO,kBAAmB,SAAQ,WAAmB;IACzD,YAAY,aAAqB;QAC/B,KAAK,CAAC,gBAAgB,EAAE;YACtB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,aAAa;SACtB,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,EAAE,CAAC,KAAY;QAC3B,OAAO,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC;IACzC,CAAC;CACF;AAID,MAAM,OAAO,uBAAwB,SAAQ,WAAsB;IACjE,YAAY,kBAA6B;QACvC,KAAK,CAAC,sBAAsB,EAAE;YAC5B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,kBAAkB;SAC3B,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,EAAE,CAAC,KAAY;QAC3B,OAAO,KAAK,CAAC,IAAI,KAAK,sBAAsB,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAgB,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;AAEnG,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,SAAwB,EAAoC,EAAE;IAClG,OAAO,cAAc,IAAI,SAAS,CAAC;AACrC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAwB,EAAmC,EAAE;IAChG,OAAO,OAAO,IAAI,SAAS,CAAC;AAC9B,CAAC,CAAA","sourcesContent":["import { createContext } from '@lit/context';\n\n\nexport interface SingleDateSelection {\n selectedDate: Date | null;\n minDate?: Date;\n maxDate?: Date;\n timezone?: string;\n}\n\nexport interface DateRange {\n startDate?: string;\n endDate?: string;\n}\n\nexport interface DateRangeSelection {\n range: DateRange;\n minDate?: Date;\n maxDate?: Date;\n timezone?: string;\n}\n\nexport type DateSelection = SingleDateSelection | DateRangeSelection;\n\nexport class DateSelectionEvent extends CustomEvent<string> {\n constructor(dateSelection: string) {\n super('date-selection', {\n bubbles: true,\n composed: true,\n detail: dateSelection,\n });\n }\n\n public static is(event: Event): event is DateSelectionEvent {\n return event.type === 'date-selection';\n }\n}\n\n\n\nexport class DateRangeSelectionEvent extends CustomEvent<DateRange> {\n constructor(dateRangeSelection: DateRange) {\n super('date-range-selection', {\n bubbles: true,\n composed: true,\n detail: dateRangeSelection,\n });\n }\n\n public static is(event: Event): event is DateRangeSelectionEvent {\n return event.type === 'date-range-selection';\n }\n}\n\nexport const DateSelectionContext = createContext<DateSelection>(Symbol('date-selection-context'));\n\nexport const isSingleDateSelection = (selection: DateSelection): selection is SingleDateSelection => {\n return 'selectedDate' in selection;\n}\n\nexport const isDateRangeSelection = (selection: DateSelection): selection is DateRangeSelection => {\n return 'range' in selection;\n}\n\n"]}
1
+ {"version":3,"file":"DateSelectionContext.js","sourceRoot":"","sources":["../../src/DateSelectionContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAuB7C,MAAM,OAAO,kBAAmB,SAAQ,WAAmB;IACzD,YAAY,aAAqB;QAC/B,KAAK,CAAC,gBAAgB,EAAE;YACtB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,aAAa;SACtB,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,EAAE,CAAC,KAAY;QAC3B,OAAO,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC;IACzC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,WAAsB;IACjE,YAAY,kBAA6B;QACvC,KAAK,CAAC,sBAAsB,EAAE;YAC5B,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,kBAAkB;SAC3B,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,EAAE,CAAC,KAAY;QAC3B,OAAO,KAAK,CAAC,IAAI,KAAK,sBAAsB,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAgB,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;AAEnG,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,SAAwB,EAAoC,EAAE;IAClG,OAAO,cAAc,IAAI,SAAS,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,SAAwB,EAAmC,EAAE;IAChG,OAAO,OAAO,IAAI,SAAS,CAAC;AAC9B,CAAC,CAAC","sourcesContent":["import { createContext } from '@lit/context';\n\nexport interface SingleDateSelection {\n selectedDate: Date | null;\n minDate?: Date;\n maxDate?: Date;\n timezone?: string;\n}\n\nexport interface DateRange {\n startDate?: string;\n endDate?: string;\n}\n\nexport interface DateRangeSelection {\n range: DateRange;\n minDate?: Date;\n maxDate?: Date;\n timezone?: string;\n}\n\nexport type DateSelection = SingleDateSelection | DateRangeSelection;\n\nexport class DateSelectionEvent extends CustomEvent<string> {\n constructor(dateSelection: string) {\n super('date-selection', {\n bubbles: true,\n composed: true,\n detail: dateSelection,\n });\n }\n\n public static is(event: Event): event is DateSelectionEvent {\n return event.type === 'date-selection';\n }\n}\n\nexport class DateRangeSelectionEvent extends CustomEvent<DateRange> {\n constructor(dateRangeSelection: DateRange) {\n super('date-range-selection', {\n bubbles: true,\n composed: true,\n detail: dateRangeSelection,\n });\n }\n\n public static is(event: Event): event is DateRangeSelectionEvent {\n return event.type === 'date-range-selection';\n }\n}\n\nexport const DateSelectionContext = createContext<DateSelection>(Symbol('date-selection-context'));\n\nexport const isSingleDateSelection = (selection: DateSelection): selection is SingleDateSelection => {\n return 'selectedDate' in selection;\n};\n\nexport const isDateRangeSelection = (selection: DateSelection): selection is DateRangeSelection => {\n return 'range' in selection;\n};\n"]}
@@ -20,7 +20,9 @@ export const styles = css `
20
20
 
21
21
  &:hover {
22
22
  cursor: pointer;
23
- box-shadow: 0px 2px 5px 0px rgba(60, 66, 87, 0.08), 0px 1px 1px 0px rgba(0, 0, 0, 0.12);
23
+ box-shadow:
24
+ 0px 2px 5px 0px rgba(60, 66, 87, 0.08),
25
+ 0px 1px 1px 0px rgba(0, 0, 0, 0.12);
24
26
  }
25
27
 
26
28
  &:focus {
@@ -60,7 +62,6 @@ export const styles = css `
60
62
  border-collapse: collapse;
61
63
  }
62
64
 
63
-
64
65
  tbody {
65
66
  display: grid;
66
67
  row-gap: 4px;
@@ -99,7 +100,6 @@ export const styles = css `
99
100
  flex: 1 0 auto;
100
101
  padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3);
101
102
 
102
-
103
103
  button {
104
104
  background-color: var(--color-surface-200);
105
105
  border-color: var(--color-primary-400);
@@ -138,7 +138,7 @@ export const styles = css `
138
138
  }
139
139
  }
140
140
 
141
- .day[aria-disabled="true"] {
141
+ .day[aria-disabled='true'] {
142
142
  opacity: 0.7;
143
143
  background-color: var(--color-surface-300);
144
144
  cursor: not-allowed;
@@ -146,7 +146,7 @@ export const styles = css `
146
146
  }
147
147
 
148
148
  .day.start-date:has(+ .in-range):after {
149
- content: " ";
149
+ content: ' ';
150
150
  position: absolute;
151
151
  top: 0;
152
152
  left: 0;
@@ -160,7 +160,7 @@ export const styles = css `
160
160
  }
161
161
 
162
162
  .day.in-range + :is(.day:hover, .day:not(.in-range)):before {
163
- content: " ";
163
+ content: ' ';
164
164
  position: absolute;
165
165
  top: 0;
166
166
  left: 0;
@@ -182,7 +182,7 @@ export const styles = css `
182
182
 
183
183
  &.in-range {
184
184
  &:before {
185
- content: " ";
185
+ content: ' ';
186
186
  position: absolute;
187
187
  top: 0;
188
188
  left: 0;
@@ -227,7 +227,6 @@ export const styles = css `
227
227
  box-shadow: none;
228
228
  }
229
229
 
230
-
231
230
  &[aria-selected='true'] {
232
231
  color: var(--color-primary-400);
233
232
  }
@@ -248,7 +247,7 @@ export const styles = css `
248
247
  gap: var(--space-scale-1);
249
248
 
250
249
  &::marker {
251
- content: "";
250
+ content: '';
252
251
  }
253
252
 
254
253
  svg.chevron-down {
@@ -1 +1 @@
1
- {"version":3,"file":"Styles.js","sourceRoot":"","sources":["../../src/Styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsQxB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const styles = css`\n :host {\n display: block;\n }\n\n button {\n appearance: none;\n padding: 0;\n border-width: 0;\n background-color: transparent;\n border-radius: var(--space-scale-1);\n padding-block: var(--space-scale-1);\n padding-inline: var(--space-scale-2);\n\n &.compact {\n padding-block: 0;\n padding-inline: 0;\n }\n\n &:hover {\n cursor: pointer;\n box-shadow: 0px 2px 5px 0px rgba(60, 66, 87, 0.08), 0px 1px 1px 0px rgba(0, 0, 0, 0.12);\n }\n\n &:focus {\n outline: 1px solid var(--color-primary-400);\n }\n\n svg {\n display: block;\n }\n\n &.right svg {\n transform: rotate(180deg);\n }\n }\n\n h2 {\n font-weight: var(--font-weight-semibold);\n color: var(--color-text-500);\n font-size: var(--font-size-400);\n display: contents;\n }\n\n .calendar-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px 24px 16px 24px;\n }\n\n .calendar-grid {\n text-align: center;\n border-top: var(--color-border-200) 1px solid;\n padding: 0 24px;\n\n table {\n width: 100%;\n border-collapse: collapse;\n }\n\n\n tbody {\n display: grid;\n row-gap: 4px;\n }\n\n tr {\n display: grid;\n grid-template-columns: repeat(7, 48px);\n }\n\n th {\n color: var(--color-text-400);\n font-size: var(--font-size-100);\n font-weight: var(--font-weight-normal);\n line-height: 20px;\n padding: 16px 0;\n }\n\n td {\n font-size: var(--font-size-100);\n font-weight: var(--font-weight-normal);\n }\n }\n\n .calendar-footer {\n display: flex;\n flex-direction: column;\n //gap: var(--space-scale-2);\n\n svg {\n vertical-align: middle;\n }\n\n .actions {\n display: flex;\n flex: 1 0 auto;\n padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3);\n\n\n button {\n background-color: var(--color-surface-200);\n border-color: var(--color-primary-400);\n border-width: 1px;\n border-style: solid;\n color: var(--color-primary-400);\n font-weight: var(--font-weight-semibold);\n width: 100%;\n height: 40px;\n }\n }\n }\n\n .day {\n aspect-ratio: 1;\n cursor: pointer;\n position: relative; // For focus outline\n box-sizing: border-box;\n height: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .day.in-range {\n background: var(--color-primary-300);\n\n &:first-child {\n border-top-left-radius: var(--space-scale-1);\n border-bottom-left-radius: var(--space-scale-1);\n }\n\n &:last-child {\n border-top-right-radius: var(--space-scale-1);\n border-bottom-right-radius: var(--space-scale-1);\n }\n }\n\n .day[aria-disabled=\"true\"] {\n opacity: 0.7;\n background-color: var(--color-surface-300);\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .day.start-date:has(+ .in-range):after {\n content: \" \";\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--color-primary-300);\n z-index: -1;\n border-radius: var(--space-scale-1);\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n }\n\n .day.in-range + :is(.day:hover, .day:not(.in-range)):before {\n content: \" \";\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--color-primary-300);\n z-index: -1;\n border-radius: var(--space-scale-1);\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n }\n\n .day[aria-selected='true']:not(.in-range),\n .day:hover {\n background: var(--color-primary-400);\n color: var(--color-text-100);\n border-radius: var(--space-scale-1);\n font-weight: var(--font-weight-semibold);\n\n &.in-range {\n &:before {\n content: \" \";\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--color-primary-300);\n z-index: -1;\n border-radius: var(--bg-border-radius, 0);\n }\n\n &:first-child {\n --bg-border-radius: var(--space-scale-1) 0 0 var(--space-scale-1);\n }\n\n &:last-child {\n --bg-border-radius: 0 var(--space-scale-1) var(--space-scale-1) 0;\n }\n }\n }\n\n .side-panel-wrapper {\n border-right: 1px solid var(--color-border-200, var(--color-surface-300));\n display: flex;\n align-items: start;\n }\n\n .side-panel {\n padding: var(--space-scale-3);\n grid-template-columns: 1fr;\n display: grid;\n gap: var(--space-scale-3);\n\n button {\n font-size: var(--font-size-200);\n text-wrap: nowrap;\n line-height: var(--space-scale-3);\n padding-block: 0;\n padding-inline: 0;\n\n &:hover {\n color: var(--color-primary-400);\n box-shadow: none;\n }\n\n\n &[aria-selected='true'] {\n color: var(--color-primary-400);\n }\n }\n }\n\n details {\n border-top: 1px solid var(--color-border-200);\n font-size: var(--font-size-100);\n font-weight: var(--font-weight-normal);\n padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3);\n\n summary {\n font-weight: var(--font-weight-semibold);\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--space-scale-1);\n\n &::marker {\n content: \"\";\n }\n\n svg.chevron-down {\n margin-left: var(--space-scale-1);\n transform: rotate(-90deg);\n }\n }\n\n &[open] svg.chevron-down {\n transform: rotate(0deg);\n }\n }\n`;\n"]}
1
+ {"version":3,"file":"Styles.js","sourceRoot":"","sources":["../../src/Styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqQxB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const styles = css`\n :host {\n display: block;\n }\n\n button {\n appearance: none;\n padding: 0;\n border-width: 0;\n background-color: transparent;\n border-radius: var(--space-scale-1);\n padding-block: var(--space-scale-1);\n padding-inline: var(--space-scale-2);\n\n &.compact {\n padding-block: 0;\n padding-inline: 0;\n }\n\n &:hover {\n cursor: pointer;\n box-shadow:\n 0px 2px 5px 0px rgba(60, 66, 87, 0.08),\n 0px 1px 1px 0px rgba(0, 0, 0, 0.12);\n }\n\n &:focus {\n outline: 1px solid var(--color-primary-400);\n }\n\n svg {\n display: block;\n }\n\n &.right svg {\n transform: rotate(180deg);\n }\n }\n\n h2 {\n font-weight: var(--font-weight-semibold);\n color: var(--color-text-500);\n font-size: var(--font-size-400);\n display: contents;\n }\n\n .calendar-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px 24px 16px 24px;\n }\n\n .calendar-grid {\n text-align: center;\n border-top: var(--color-border-200) 1px solid;\n padding: 0 24px;\n\n table {\n width: 100%;\n border-collapse: collapse;\n }\n\n tbody {\n display: grid;\n row-gap: 4px;\n }\n\n tr {\n display: grid;\n grid-template-columns: repeat(7, 48px);\n }\n\n th {\n color: var(--color-text-400);\n font-size: var(--font-size-100);\n font-weight: var(--font-weight-normal);\n line-height: 20px;\n padding: 16px 0;\n }\n\n td {\n font-size: var(--font-size-100);\n font-weight: var(--font-weight-normal);\n }\n }\n\n .calendar-footer {\n display: flex;\n flex-direction: column;\n //gap: var(--space-scale-2);\n\n svg {\n vertical-align: middle;\n }\n\n .actions {\n display: flex;\n flex: 1 0 auto;\n padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3);\n\n button {\n background-color: var(--color-surface-200);\n border-color: var(--color-primary-400);\n border-width: 1px;\n border-style: solid;\n color: var(--color-primary-400);\n font-weight: var(--font-weight-semibold);\n width: 100%;\n height: 40px;\n }\n }\n }\n\n .day {\n aspect-ratio: 1;\n cursor: pointer;\n position: relative; // For focus outline\n box-sizing: border-box;\n height: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .day.in-range {\n background: var(--color-primary-300);\n\n &:first-child {\n border-top-left-radius: var(--space-scale-1);\n border-bottom-left-radius: var(--space-scale-1);\n }\n\n &:last-child {\n border-top-right-radius: var(--space-scale-1);\n border-bottom-right-radius: var(--space-scale-1);\n }\n }\n\n .day[aria-disabled='true'] {\n opacity: 0.7;\n background-color: var(--color-surface-300);\n cursor: not-allowed;\n pointer-events: none;\n }\n\n .day.start-date:has(+ .in-range):after {\n content: ' ';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--color-primary-300);\n z-index: -1;\n border-radius: var(--space-scale-1);\n border-bottom-right-radius: 0;\n border-top-right-radius: 0;\n }\n\n .day.in-range + :is(.day:hover, .day:not(.in-range)):before {\n content: ' ';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--color-primary-300);\n z-index: -1;\n border-radius: var(--space-scale-1);\n border-bottom-left-radius: 0;\n border-top-left-radius: 0;\n }\n\n .day[aria-selected='true']:not(.in-range),\n .day:hover {\n background: var(--color-primary-400);\n color: var(--color-text-100);\n border-radius: var(--space-scale-1);\n font-weight: var(--font-weight-semibold);\n\n &.in-range {\n &:before {\n content: ' ';\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: var(--color-primary-300);\n z-index: -1;\n border-radius: var(--bg-border-radius, 0);\n }\n\n &:first-child {\n --bg-border-radius: var(--space-scale-1) 0 0 var(--space-scale-1);\n }\n\n &:last-child {\n --bg-border-radius: 0 var(--space-scale-1) var(--space-scale-1) 0;\n }\n }\n }\n\n .side-panel-wrapper {\n border-right: 1px solid var(--color-border-200, var(--color-surface-300));\n display: flex;\n align-items: start;\n }\n\n .side-panel {\n padding: var(--space-scale-3);\n grid-template-columns: 1fr;\n display: grid;\n gap: var(--space-scale-3);\n\n button {\n font-size: var(--font-size-200);\n text-wrap: nowrap;\n line-height: var(--space-scale-3);\n padding-block: 0;\n padding-inline: 0;\n\n &:hover {\n color: var(--color-primary-400);\n box-shadow: none;\n }\n\n &[aria-selected='true'] {\n color: var(--color-primary-400);\n }\n }\n }\n\n details {\n border-top: 1px solid var(--color-border-200);\n font-size: var(--font-size-100);\n font-weight: var(--font-weight-normal);\n padding: var(--space-scale-2) var(--space-scale-3) var(--space-scale-3);\n\n summary {\n font-weight: var(--font-weight-semibold);\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--space-scale-1);\n\n &::marker {\n content: '';\n }\n\n svg.chevron-down {\n margin-left: var(--space-scale-1);\n transform: rotate(-90deg);\n }\n }\n\n &[open] svg.chevron-down {\n transform: rotate(0deg);\n }\n }\n`;\n"]}
@@ -35,8 +35,12 @@ export class Calendar extends LitElement {
35
35
  }
36
36
  get internalRangeValue() {
37
37
  if (this.range && this.value) {
38
- const startDate = this.value?.startDate ? DateTime.fromISO(this.value.startDate) : undefined;
39
- const endDate = this.value?.endDate ? DateTime.fromISO(this.value.endDate) : undefined;
38
+ const startDate = this.value?.startDate
39
+ ? DateTime.fromISO(this.value.startDate)
40
+ : undefined;
41
+ const endDate = this.value?.endDate
42
+ ? DateTime.fromISO(this.value.endDate)
43
+ : undefined;
40
44
  return { startDate, endDate };
41
45
  }
42
46
  return { startDate: undefined, endDate: undefined };
@@ -55,7 +59,7 @@ export class Calendar extends LitElement {
55
59
  this.focusedDate = parsedDate.isValid ? parsedDate : this.today;
56
60
  }
57
61
  else {
58
- this.focusedDate = (this.internalRangeValue?.startDate || this.today);
62
+ this.focusedDate = this.internalRangeValue?.startDate || this.today;
59
63
  }
60
64
  });
61
65
  }
@@ -71,7 +75,7 @@ export class Calendar extends LitElement {
71
75
  this.calendarDiv.focus();
72
76
  this.calendarDiv.scrollIntoView({
73
77
  behavior: 'smooth',
74
- block: 'nearest'
78
+ block: 'nearest',
75
79
  });
76
80
  });
77
81
  if (!this.range) {
@@ -80,7 +84,9 @@ export class Calendar extends LitElement {
80
84
  this.focusedDate = parsedDate.isValid ? parsedDate : this.today;
81
85
  }
82
86
  else {
83
- this.focusedDate = this.value?.startDate ? DateTime.fromISO(this.value.startDate) : this.today;
87
+ this.focusedDate = this.value?.startDate
88
+ ? DateTime.fromISO(this.value.startDate)
89
+ : this.today;
84
90
  }
85
91
  }
86
92
  }
@@ -252,7 +258,7 @@ export class Calendar extends LitElement {
252
258
  if (details.open) {
253
259
  details.scrollIntoView({
254
260
  behavior: 'smooth',
255
- block: 'nearest'
261
+ block: 'nearest',
256
262
  });
257
263
  }
258
264
  }
@@ -260,13 +266,17 @@ export class Calendar extends LitElement {
260
266
  const weeks = this.getDaysInMonth(this.focusedDate);
261
267
  const monthYear = this.focusedDate.toLocaleString({
262
268
  month: 'long',
263
- year: 'numeric'
269
+ year: 'numeric',
264
270
  });
265
271
  return html `
266
272
  <div class="calendar-panel" @keydown=${this.handleKeyDown} role="application" aria-label="${monthYear}">
267
273
  <div class="calendar-header">
268
- <button @click=${this.previousYear} @keydown=${this.handleButtonKeyDown} aria-label="Previous year"
269
- class="compact">
274
+ <button
275
+ @click=${this.previousYear}
276
+ @keydown=${this.handleButtonKeyDown}
277
+ aria-label="Previous year"
278
+ class="compact"
279
+ >
270
280
  ${unsafeSVG(doubleChevron)}
271
281
  </button>
272
282
  <button
@@ -285,66 +295,69 @@ export class Calendar extends LitElement {
285
295
  class="compact right"
286
296
  >
287
297
  ${unsafeSVG(chevron)}
288
-
289
298
  </button>
290
- <button @click=${this.nextYear} @keydown=${this.handleButtonKeyDown} aria-label="Next year"
291
- class="compact right">
299
+ <button
300
+ @click=${this.nextYear}
301
+ @keydown=${this.handleButtonKeyDown}
302
+ aria-label="Next year"
303
+ class="compact right"
304
+ >
292
305
  ${unsafeSVG(doubleChevron)}
293
306
  </button>
294
307
  </div>
295
308
  <div class="calendar-grid">
296
- <table role="grid" aria-labelledby="month-year" data-range="${this.range}"
297
- class="${this.isSelectingRange ? 'selecting' : ''}">
309
+ <table
310
+ role="grid"
311
+ aria-labelledby="month-year"
312
+ data-range="${this.range}"
313
+ class="${this.isSelectingRange ? 'selecting' : ''}"
314
+ >
298
315
  <thead>
299
- <tr>
300
- ${this.getWeekdayLabels().map(label => html `
301
- <th>${label}</th>`)}
302
- </tr>
316
+ <tr>
317
+ ${this.getWeekdayLabels().map((label) => html ` <th>${label}</th>`)}
318
+ </tr>
303
319
  </thead>
304
320
 
305
321
  <tbody>
306
- ${weeks.map(week => html `
307
- <tr>
308
- ${week.map(day => {
322
+ ${weeks.map((week) => html ` <tr>
323
+ ${week.map((day) => {
309
324
  if (!day) {
310
- return html `
311
- <td></td>`;
325
+ return html ` <td></td>`;
312
326
  }
313
327
  const isDisabled = this.dayIsDisabled(day);
314
- return html `
315
- <td
316
- class="${classMap({
317
- 'day': true,
328
+ return html ` <td
329
+ class="${classMap({
330
+ day: true,
318
331
  'in-range': this.isInRange(day),
319
332
  'start-date': this.isStartDate(day),
320
- 'end-date': this.isEndDate(day)
333
+ 'end-date': this.isEndDate(day),
321
334
  })}"
322
- @click=${() => this.handleDayClick(day)}
323
- role="gridcell"
324
- data-date="${day.toISODate()}"
325
- aria-label="${day.toLocaleString({ dateStyle: 'long' })}"
326
- aria-selected="${this.isSelected(day)}"
327
- aria-disabled="${isDisabled}"
328
- tabindex="-1"
329
- @mouseenter="${this.onDayHover}"
330
- >
331
- ${day.day}
332
- </td>`;
335
+ @click=${() => this.handleDayClick(day)}
336
+ role="gridcell"
337
+ data-date="${day.toISODate()}"
338
+ aria-label="${day.toLocaleString({ dateStyle: 'long' })}"
339
+ aria-selected="${this.isSelected(day)}"
340
+ aria-disabled="${isDisabled}"
341
+ tabindex="-1"
342
+ @mouseenter="${this.onDayHover}"
343
+ >
344
+ ${day.day}
345
+ </td>`;
333
346
  })}
334
- </tr>`)}
347
+ </tr>`)}
335
348
  </tbody>
336
349
  </table>
337
350
  </div>
338
351
 
339
352
  <div class="calendar-footer">
340
353
  <div class="actions" @keydown="${this.handleButtonKeyDown}">
341
- ${this.isRange() ? html `
342
- <button @click=${() => this.handleClearSelection()} data-theme="secondary" id="clear-selection">Clear
343
- selection
344
- </button>
345
- ` : html `
346
- <button @click=${() => this.handleDayClick(this.today)} data-theme="secondary">Today</button>
347
- `}
354
+ ${this.isRange()
355
+ ? html `
356
+ <button @click=${() => this.handleClearSelection()} data-theme="secondary" id="clear-selection">
357
+ Clear selection
358
+ </button>
359
+ `
360
+ : html ` <button @click=${() => this.handleDayClick(this.today)} data-theme="secondary">Today</button> `}
348
361
  </div>
349
362
  <div>
350
363
  <details @keydown=${this.handleButtonKeyDown} @toggle=${this.handleToggle}>
@@ -370,10 +383,10 @@ export class Calendar extends LitElement {
370
383
  return true;
371
384
  if (this.minDate && day < this.minDate)
372
385
  return true;
373
- if (this.range && this.isSelectingRange) {
374
- if (day < this.internalRangeValue?.startDate)
386
+ if (this.range && this.isSelectingRange && this.internalRangeValue?.startDate) {
387
+ if (day < this.internalRangeValue.startDate)
375
388
  return true;
376
- if (this.maxDays && day > this.internalRangeValue?.startDate.plus({ days: this.maxDays }))
389
+ if (this.maxDays && day > this.internalRangeValue.startDate.plus({ days: this.maxDays }))
377
390
  return true;
378
391
  }
379
392
  return false;
@@ -382,7 +395,7 @@ export class Calendar extends LitElement {
382
395
  Calendar.styles = styles;
383
396
  Calendar.shadowRootOptions = {
384
397
  ...LitElement.shadowRootOptions,
385
- delegatesFocus: true
398
+ delegatesFocus: true,
386
399
  };
387
400
  __decorate([
388
401
  property({ type: String })
@@ -1 +1 @@
1
- {"version":3,"file":"TtCalendar.js","sourceRoot":"","sources":["../../src/TtCalendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { DateTime, Interval } from 'luxon';\nimport { DateRange, DateRangeSelectionEvent, DateSelectionEvent } from './DateSelectionContext.js';\nimport { chevron, chevronDown, doubleChevron, keyboard } from '@triptease/icons';\nimport { styles } from './Styles.js';\nimport { dateConverter, dateTimeConverter } from './helpers.js';\n\ntype WeekdayList = [\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n];\n\ninterface CalendarWithRange {\n value?: DateRange;\n range: true;\n}\n\ninterface InternalDateRange {\n startDate?: DateTime;\n endDate?: DateTime;\n}\n\nexport class Calendar extends LitElement {\n static styles = styles;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true\n };\n\n\n // Start public properties\n\n @property({ type: String })\n public value?: string | DateRange;\n\n @property({ type: Boolean })\n public range = false;\n\n @property({ attribute: 'max-date', converter: dateTimeConverter })\n public maxDate?: DateTime;\n\n @property({ type: Number, attribute: 'max-days' })\n public maxDays?: number;\n\n @property({ attribute: 'min-date', converter: dateTimeConverter })\n public minDate?: DateTime;\n\n @property({ type: Number, attribute: 'min-days' })\n public minDays?: number;\n\n get internalRangeValue(): InternalDateRange {\n if (this.range && this.value) {\n const startDate = (this.value as DateRange)?.startDate ? DateTime.fromISO((this.value as DateRange).startDate!) : undefined;\n const endDate = (this.value as DateRange)?.endDate ? DateTime.fromISO((this.value as DateRange).endDate!) : undefined;\n return { startDate, endDate };\n }\n return { startDate: undefined, endDate: undefined };\n }\n\n getRange(): Interval {\n if (this.range && this.internalRangeValue.startDate && this.internalRangeValue.endDate) {\n return Interval.fromDateTimes(this.internalRangeValue.startDate, this.internalRangeValue.endDate.plus({ days: 1 }));\n }\n return Interval.invalid('Invalid range');\n }\n\n public updated(changedProperties: PropertyValues) {\n if (changedProperties.has('value') && this.value) {\n super.updateComplete.then(() => {\n if (!this.range) {\n const parsedDate = DateTime.fromISO(this.value as string);\n this.focusedDate = parsedDate.isValid ? parsedDate : this.today;\n } else {\n this.focusedDate = (this.internalRangeValue?.startDate || this.today);\n }\n });\n }\n super.updated(changedProperties);\n }\n\n public toggleVisibility() {\n if (this.visible) {\n this.visible = false;\n } else {\n this.visible = true;\n this.updateComplete.then(() => {\n this.calendarDiv.focus();\n this.calendarDiv.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest'\n });\n });\n if (!this.range) {\n console.log('received value' ,this.value)\n\n const parsedDate = DateTime.fromISO(this.value as string ?? this.today);\n this.focusedDate = parsedDate.isValid ? parsedDate : this.today;\n } else {\n this.focusedDate = (this.value as DateRange)?.startDate ? DateTime.fromISO((this.value as DateRange).startDate!) : this.today;\n }\n }\n }\n\n // end public properties\n\n @query('.calendar-panel')\n private calendarDiv!: HTMLElement;\n\n @state()\n private focusedDate: DateTime = this.today;\n\n @state()\n private visible: Boolean = false;\n\n private handleKeyDown(event: KeyboardEvent) {\n const currentDate = this.focusedDate;\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n this.focusDay(currentDate.minus({ day: 1 }));\n break;\n case 'ArrowRight':\n event.preventDefault();\n this.focusDay(currentDate.plus({ day: 1 }));\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusDay(currentDate.minus({ week: 1 }));\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.focusDay(currentDate.plus({ week: 1 }));\n break;\n case 'Home':\n event.preventDefault();\n // Move to first day of week\n this.focusDay(currentDate.startOf('week'));\n break;\n case 'End':\n event.preventDefault();\n // Move to last day of week\n this.focusDay(currentDate.endOf('week'));\n break;\n case 'PageUp':\n event.preventDefault();\n if (event.shiftKey) {\n // Previous year\n this.focusDay(currentDate.minus({ year: 1 }));\n } else {\n // Previous month\n this.focusDay(currentDate.minus({ month: 1 }));\n }\n break;\n case 'PageDown':\n event.preventDefault();\n if (event.shiftKey) {\n // Next year\n this.focusDay(currentDate.plus({ year: 1 }));\n } else {\n // Next month\n this.focusDay(currentDate.plus({ month: 1 }));\n }\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.handleDayClick(this.focusedDate);\n return;\n\n default:\n return;\n }\n\n event.preventDefault();\n }\n\n private focusDay(date: DateTime) {\n this.focusedDate = date;\n this.updateComplete.then(() => {\n const dayElement = <HTMLElement | undefined>this.shadowRoot?.querySelector(\n `.day[data-date=\"${date.toISO()}\"]`\n );\n if (dayElement) {\n dayElement.focus();\n }\n });\n }\n\n private newWeek = () => new Array(7).fill(null) as WeekdayList;\n\n private getDaysInMonth(date: DateTime): WeekdayList[] {\n\n const startOfMonth = date.startOf('month');\n const endOfMonth = date.endOf('month');\n\n const weeks: WeekdayList[] = [];\n let currentWeek: WeekdayList = this.newWeek();\n\n let currentDay = startOfMonth;\n\n while (currentDay <= endOfMonth) {\n // Get the day of week (0-6, Sunday=0, Saturday=6)\n const dayOfWeek = currentDay.weekday === 7 ? 0 : currentDay.weekday;\n\n currentWeek[dayOfWeek] = currentDay;\n\n const isWeekComplete = dayOfWeek === 6; // Saturday (last day of week)\n const isLastDayOfMonth = currentDay.hasSame(endOfMonth, 'day');\n\n if (isWeekComplete || isLastDayOfMonth) {\n weeks.push(currentWeek);\n\n if (!isLastDayOfMonth) {\n currentWeek = this.newWeek();\n }\n }\n\n currentDay = currentDay.plus({ days: 1 });\n }\n\n return weeks;\n }\n\n private previousYear() {\n this.focusedDate = this.focusedDate.minus({ year: 1 });\n }\n\n private previousMonth() {\n this.focusedDate = this.focusedDate.minus({ month: 1 });\n }\n\n private nextMonth() {\n this.focusedDate = this.focusedDate.plus({ month: 1 });\n }\n\n private nextYear() {\n this.focusedDate = this.focusedDate.plus({ year: 1 });\n }\n\n private get today(): DateTime {\n return DateTime.local();\n }\n\n private handleDayClick(day: DateTime) {\n if (this.isRange()) {\n if (!this.value?.startDate || this.value?.endDate) {\n this.value = { startDate: day.toISODate()! };\n this.focusedDate = day;\n return;\n }\n\n if (!this.value.endDate) {\n this.value = { ...this.value as DateRange, endDate: day.toISODate()! };\n this.focusedDate = day;\n this.dispatchEvent(new DateRangeSelectionEvent(this.value));\n return;\n }\n }\n\n if (day.isValid) {\n this.dispatchEvent(new DateSelectionEvent(day.toISODate()!));\n }\n\n }\n\n private handleButtonKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.stopPropagation();\n }\n };\n\n private getWeekdayLabels(): string[] {\n const monday = DateTime.fromISO('2024-06-02T00:00:00Z').startOf('week'); //Weeks start on Monday in Luxon https://moment.github.io/luxon/api-docs/index.html#datetimestartof\n const sunday = monday.plus({ days: 6 });\n return Array.from({ length: 7 }, (_, i) => {\n const date = sunday.plus({ days: i });\n return date.toLocaleString({ weekday: 'short' });\n });\n }\n\n private isSelected(date: DateTime): boolean {\n if (date.equals(this.focusedDate)) return true;\n\n if (this.isRange() && this.internalRangeValue.startDate) {\n if (!this.internalRangeValue.endDate) {\n const range = Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate.plus({ days: 1 }));\n return range.contains(date);\n }\n\n const range = this.getRange();\n return range.contains(date);\n }\n\n return false;\n }\n\n private isInRange(date: DateTime): boolean {\n if (!this.isRange() || !this.internalRangeValue?.startDate) {\n return false;\n }\n\n if (!this.internalRangeValue?.endDate) {\n const range = Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate);\n return range.contains(date) && !this.isStartDate(date) && !date.equals(this.focusedDate);\n }\n\n const range = this.getRange();\n return range.contains(date) && !this.isStartDate(date) && !this.isEndDate(date);\n }\n\n private isRange(): this is CalendarWithRange {\n return this.range;\n }\n\n private get isSelectingRange(): boolean {\n return Boolean(this.isRange() && this.value?.startDate && !this.value?.endDate);\n }\n\n private onDayHover = (event: MouseEvent) => {\n const day = (event.target as HTMLElement).dataset.date;\n if (!day) return;\n\n this.focusedDate = DateTime.fromISO(day);\n };\n\n private isStartDate = (date: DateTime): boolean => Boolean(this.isRange() && this.internalRangeValue?.startDate && this.internalRangeValue.startDate.equals(date));\n\n private isEndDate = (date: DateTime): boolean => Boolean(this.isRange() && this.internalRangeValue?.endDate && this.internalRangeValue.endDate.equals(date));\n\n private handleClearSelection = () => {\n this.value = { startDate: undefined, endDate: undefined };\n this.dispatchEvent(new DateRangeSelectionEvent({ startDate: undefined, endDate: undefined }));\n };\n\n private handleToggle(e: Event) {\n const details = e.target as HTMLDetailsElement;\n if (details.open) {\n details.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest'\n });\n }\n }\n\n render() {\n const weeks = this.getDaysInMonth(this.focusedDate);\n const monthYear = this.focusedDate.toLocaleString({\n month: 'long',\n year: 'numeric'\n });\n\n return html`\n <div class=\"calendar-panel\" @keydown=${this.handleKeyDown} role=\"application\" aria-label=\"${monthYear}\">\n <div class=\"calendar-header\">\n <button @click=${this.previousYear} @keydown=${this.handleButtonKeyDown} aria-label=\"Previous year\"\n class=\"compact\">\n ${unsafeSVG(doubleChevron)}\n </button>\n <button\n @click=${this.previousMonth}\n @keydown=\"${this.handleButtonKeyDown}\"\n aria-label=\"Previous month\"\n class=\"compact\"\n >\n ${unsafeSVG(chevron)}\n </button>\n <h2>${monthYear}</h2>\n <button\n @click=${this.nextMonth}\n @keydown=\"${this.handleButtonKeyDown}\"\n aria-label=\"Next month\"\n class=\"compact right\"\n >\n ${unsafeSVG(chevron)}\n\n </button>\n <button @click=${this.nextYear} @keydown=${this.handleButtonKeyDown} aria-label=\"Next year\"\n class=\"compact right\">\n ${unsafeSVG(doubleChevron)}\n </button>\n </div>\n <div class=\"calendar-grid\">\n <table role=\"grid\" aria-labelledby=\"month-year\" data-range=\"${this.range}\"\n class=\"${this.isSelectingRange ? 'selecting' : ''}\">\n <thead>\n <tr>\n ${this.getWeekdayLabels().map(\n label => html`\n <th>${label}</th>`\n )}\n </tr>\n </thead>\n\n <tbody>\n ${weeks.map(week => html`\n <tr>\n ${week.map(day => {\n if (!day) {\n return html`\n <td></td>`;\n }\n\n const isDisabled = this.dayIsDisabled(day);\n\n return html`\n <td\n class=\"${classMap({\n 'day': true,\n 'in-range': this.isInRange(day),\n 'start-date': this.isStartDate(day),\n 'end-date': this.isEndDate(day)\n })}\"\n @click=${() => this.handleDayClick(day)}\n role=\"gridcell\"\n data-date=\"${day.toISODate()}\"\n aria-label=\"${day.toLocaleString({ dateStyle: 'long' })}\"\n aria-selected=\"${this.isSelected(day)}\"\n aria-disabled=\"${isDisabled}\"\n tabindex=\"-1\"\n @mouseenter=\"${this.onDayHover}\"\n >\n ${day.day}\n </td>`;\n })}\n </tr>`)}\n </tbody>\n </table>\n </div>\n\n <div class=\"calendar-footer\">\n <div class=\"actions\" @keydown=\"${this.handleButtonKeyDown}\">\n ${this.isRange() ? html`\n <button @click=${() => this.handleClearSelection()} data-theme=\"secondary\" id=\"clear-selection\">Clear\n selection\n </button>\n ` : html`\n <button @click=${() => this.handleDayClick(this.today)} data-theme=\"secondary\">Today</button>\n `}\n </div>\n <div>\n <details @keydown=${this.handleButtonKeyDown} @toggle=${this.handleToggle}>\n <summary>${unsafeSVG(keyboard)} Keyboard commands ${unsafeSVG(chevronDown)}</summary>\n <p>Arrow keys: navigate the calendar</p>\n <p>Enter or Space: select the date</p>\n <p>Escape: close the calendar without selecting a date</p>\n <p>Tab: navigate between the calendar and the presets</p>\n <p>Home: move to first day of week</p>\n <p>End: move to last day of week</p>\n <p>Page Up: move to previous month</p>\n <p>Page Down: move to next month</p>\n <p>Shift + Page Up: move to next year</p>\n <p>Shift + Page Down: move to previous year</p>\n </details>\n </div>\n </div>\n </div>\n `;\n }\n\n private dayIsDisabled(day: DateTime) {\n if (this.maxDate && day > this.maxDate) return true;\n\n if (this.minDate && day < this.minDate) return true;\n\n if (this.range && this.isSelectingRange) {\n if (day < this.internalRangeValue?.startDate!) return true;\n\n if (this.maxDays && day > this.internalRangeValue?.startDate!.plus({ days: this.maxDays })) return true;\n }\n\n return false;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-calendar': Calendar;\n }\n}\n"]}
1
+ {"version":3,"file":"TtCalendar.js","sourceRoot":"","sources":["../../src/TtCalendar.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { DateTime, Interval } from 'luxon';\nimport { DateRange, DateRangeSelectionEvent, DateSelectionEvent } from './DateSelectionContext.js';\nimport { chevron, chevronDown, doubleChevron, keyboard } from '@triptease/icons';\nimport { styles } from './Styles.js';\nimport { dateTimeConverter } from './helpers.js';\n\ntype WeekdayList = [\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n DateTime | null,\n];\n\ninterface CalendarWithRange {\n value?: DateRange;\n range: true;\n}\n\ninterface InternalDateRange {\n startDate?: DateTime;\n endDate?: DateTime;\n}\n\nexport class Calendar extends LitElement {\n static styles = styles;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n // Start public properties\n\n @property({ type: String })\n public value?: string | DateRange;\n\n @property({ type: Boolean })\n public range = false;\n\n @property({ attribute: 'max-date', converter: dateTimeConverter })\n public maxDate?: DateTime;\n\n @property({ type: Number, attribute: 'max-days' })\n public maxDays?: number;\n\n @property({ attribute: 'min-date', converter: dateTimeConverter })\n public minDate?: DateTime;\n\n @property({ type: Number, attribute: 'min-days' })\n public minDays?: number;\n\n get internalRangeValue(): InternalDateRange {\n if (this.range && this.value) {\n const startDate = (this.value as DateRange)?.startDate\n ? DateTime.fromISO((this.value as DateRange).startDate!)\n : undefined;\n const endDate = (this.value as DateRange)?.endDate\n ? DateTime.fromISO((this.value as DateRange).endDate!)\n : undefined;\n return { startDate, endDate };\n }\n return { startDate: undefined, endDate: undefined };\n }\n\n getRange(): Interval {\n if (this.range && this.internalRangeValue.startDate && this.internalRangeValue.endDate) {\n return Interval.fromDateTimes(\n this.internalRangeValue.startDate,\n this.internalRangeValue.endDate.plus({ days: 1 })\n );\n }\n return Interval.invalid('Invalid range');\n }\n\n public updated(changedProperties: PropertyValues) {\n if (changedProperties.has('value') && this.value) {\n super.updateComplete.then(() => {\n if (!this.range) {\n const parsedDate = DateTime.fromISO(this.value as string);\n this.focusedDate = parsedDate.isValid ? parsedDate : this.today;\n } else {\n this.focusedDate = this.internalRangeValue?.startDate || this.today;\n }\n });\n }\n super.updated(changedProperties);\n }\n\n public toggleVisibility() {\n if (this.visible) {\n this.visible = false;\n } else {\n this.visible = true;\n this.updateComplete.then(() => {\n this.calendarDiv.focus();\n this.calendarDiv.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n });\n });\n if (!this.range) {\n console.log('received value', this.value);\n\n const parsedDate = DateTime.fromISO((this.value as string) ?? this.today);\n this.focusedDate = parsedDate.isValid ? parsedDate : this.today;\n } else {\n this.focusedDate = (this.value as DateRange)?.startDate\n ? DateTime.fromISO((this.value as DateRange).startDate!)\n : this.today;\n }\n }\n }\n\n // end public properties\n\n @query('.calendar-panel')\n private calendarDiv!: HTMLElement;\n\n @state()\n private focusedDate: DateTime = this.today;\n\n @state()\n private visible: boolean = false;\n\n private handleKeyDown(event: KeyboardEvent) {\n const currentDate = this.focusedDate;\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n this.focusDay(currentDate.minus({ day: 1 }));\n break;\n case 'ArrowRight':\n event.preventDefault();\n this.focusDay(currentDate.plus({ day: 1 }));\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.focusDay(currentDate.minus({ week: 1 }));\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.focusDay(currentDate.plus({ week: 1 }));\n break;\n case 'Home':\n event.preventDefault();\n // Move to first day of week\n this.focusDay(currentDate.startOf('week'));\n break;\n case 'End':\n event.preventDefault();\n // Move to last day of week\n this.focusDay(currentDate.endOf('week'));\n break;\n case 'PageUp':\n event.preventDefault();\n if (event.shiftKey) {\n // Previous year\n this.focusDay(currentDate.minus({ year: 1 }));\n } else {\n // Previous month\n this.focusDay(currentDate.minus({ month: 1 }));\n }\n break;\n case 'PageDown':\n event.preventDefault();\n if (event.shiftKey) {\n // Next year\n this.focusDay(currentDate.plus({ year: 1 }));\n } else {\n // Next month\n this.focusDay(currentDate.plus({ month: 1 }));\n }\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.handleDayClick(this.focusedDate);\n return;\n\n default:\n return;\n }\n\n event.preventDefault();\n }\n\n private focusDay(date: DateTime) {\n this.focusedDate = date;\n this.updateComplete.then(() => {\n const dayElement = <HTMLElement | undefined>this.shadowRoot?.querySelector(`.day[data-date=\"${date.toISO()}\"]`);\n if (dayElement) {\n dayElement.focus();\n }\n });\n }\n\n private newWeek = () => new Array(7).fill(null) as WeekdayList;\n\n private getDaysInMonth(date: DateTime): WeekdayList[] {\n const startOfMonth = date.startOf('month');\n const endOfMonth = date.endOf('month');\n\n const weeks: WeekdayList[] = [];\n let currentWeek: WeekdayList = this.newWeek();\n\n let currentDay = startOfMonth;\n\n while (currentDay <= endOfMonth) {\n // Get the day of week (0-6, Sunday=0, Saturday=6)\n const dayOfWeek = currentDay.weekday === 7 ? 0 : currentDay.weekday;\n\n currentWeek[dayOfWeek] = currentDay;\n\n const isWeekComplete = dayOfWeek === 6; // Saturday (last day of week)\n const isLastDayOfMonth = currentDay.hasSame(endOfMonth, 'day');\n\n if (isWeekComplete || isLastDayOfMonth) {\n weeks.push(currentWeek);\n\n if (!isLastDayOfMonth) {\n currentWeek = this.newWeek();\n }\n }\n\n currentDay = currentDay.plus({ days: 1 });\n }\n\n return weeks;\n }\n\n private previousYear() {\n this.focusedDate = this.focusedDate.minus({ year: 1 });\n }\n\n private previousMonth() {\n this.focusedDate = this.focusedDate.minus({ month: 1 });\n }\n\n private nextMonth() {\n this.focusedDate = this.focusedDate.plus({ month: 1 });\n }\n\n private nextYear() {\n this.focusedDate = this.focusedDate.plus({ year: 1 });\n }\n\n private get today(): DateTime {\n return DateTime.local();\n }\n\n private handleDayClick(day: DateTime) {\n if (this.isRange()) {\n if (!this.value?.startDate || this.value?.endDate) {\n this.value = { startDate: day.toISODate()! };\n this.focusedDate = day;\n return;\n }\n\n if (!this.value.endDate) {\n this.value = { ...(this.value as DateRange), endDate: day.toISODate()! };\n this.focusedDate = day;\n this.dispatchEvent(new DateRangeSelectionEvent(this.value));\n return;\n }\n }\n\n if (day.isValid) {\n this.dispatchEvent(new DateSelectionEvent(day.toISODate()!));\n }\n }\n\n private handleButtonKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.stopPropagation();\n }\n };\n\n private getWeekdayLabels(): string[] {\n const monday = DateTime.fromISO('2024-06-02T00:00:00Z').startOf('week'); //Weeks start on Monday in Luxon https://moment.github.io/luxon/api-docs/index.html#datetimestartof\n const sunday = monday.plus({ days: 6 });\n return Array.from({ length: 7 }, (_, i) => {\n const date = sunday.plus({ days: i });\n return date.toLocaleString({ weekday: 'short' });\n });\n }\n\n private isSelected(date: DateTime): boolean {\n if (date.equals(this.focusedDate)) return true;\n\n if (this.isRange() && this.internalRangeValue.startDate) {\n if (!this.internalRangeValue.endDate) {\n const range = Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate.plus({ days: 1 }));\n return range.contains(date);\n }\n\n const range = this.getRange();\n return range.contains(date);\n }\n\n return false;\n }\n\n private isInRange(date: DateTime): boolean {\n if (!this.isRange() || !this.internalRangeValue?.startDate) {\n return false;\n }\n\n if (!this.internalRangeValue?.endDate) {\n const range = Interval.fromDateTimes(this.internalRangeValue.startDate, this.focusedDate);\n return range.contains(date) && !this.isStartDate(date) && !date.equals(this.focusedDate);\n }\n\n const range = this.getRange();\n return range.contains(date) && !this.isStartDate(date) && !this.isEndDate(date);\n }\n\n private isRange(): this is CalendarWithRange {\n return this.range;\n }\n\n private get isSelectingRange(): boolean {\n return Boolean(this.isRange() && this.value?.startDate && !this.value?.endDate);\n }\n\n private onDayHover = (event: MouseEvent) => {\n const day = (event.target as HTMLElement).dataset.date;\n if (!day) return;\n\n this.focusedDate = DateTime.fromISO(day);\n };\n\n private isStartDate = (date: DateTime): boolean =>\n Boolean(this.isRange() && this.internalRangeValue?.startDate && this.internalRangeValue.startDate.equals(date));\n\n private isEndDate = (date: DateTime): boolean =>\n Boolean(this.isRange() && this.internalRangeValue?.endDate && this.internalRangeValue.endDate.equals(date));\n\n private handleClearSelection = () => {\n this.value = { startDate: undefined, endDate: undefined };\n this.dispatchEvent(new DateRangeSelectionEvent({ startDate: undefined, endDate: undefined }));\n };\n\n private handleToggle(e: Event) {\n const details = e.target as HTMLDetailsElement;\n if (details.open) {\n details.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n });\n }\n }\n\n render() {\n const weeks = this.getDaysInMonth(this.focusedDate);\n const monthYear = this.focusedDate.toLocaleString({\n month: 'long',\n year: 'numeric',\n });\n\n return html`\n <div class=\"calendar-panel\" @keydown=${this.handleKeyDown} role=\"application\" aria-label=\"${monthYear}\">\n <div class=\"calendar-header\">\n <button\n @click=${this.previousYear}\n @keydown=${this.handleButtonKeyDown}\n aria-label=\"Previous year\"\n class=\"compact\"\n >\n ${unsafeSVG(doubleChevron)}\n </button>\n <button\n @click=${this.previousMonth}\n @keydown=\"${this.handleButtonKeyDown}\"\n aria-label=\"Previous month\"\n class=\"compact\"\n >\n ${unsafeSVG(chevron)}\n </button>\n <h2>${monthYear}</h2>\n <button\n @click=${this.nextMonth}\n @keydown=\"${this.handleButtonKeyDown}\"\n aria-label=\"Next month\"\n class=\"compact right\"\n >\n ${unsafeSVG(chevron)}\n </button>\n <button\n @click=${this.nextYear}\n @keydown=${this.handleButtonKeyDown}\n aria-label=\"Next year\"\n class=\"compact right\"\n >\n ${unsafeSVG(doubleChevron)}\n </button>\n </div>\n <div class=\"calendar-grid\">\n <table\n role=\"grid\"\n aria-labelledby=\"month-year\"\n data-range=\"${this.range}\"\n class=\"${this.isSelectingRange ? 'selecting' : ''}\"\n >\n <thead>\n <tr>\n ${this.getWeekdayLabels().map((label) => html` <th>${label}</th>`)}\n </tr>\n </thead>\n\n <tbody>\n ${weeks.map(\n (week) =>\n html` <tr>\n ${week.map((day) => {\n if (!day) {\n return html` <td></td>`;\n }\n\n const isDisabled = this.dayIsDisabled(day);\n\n return html` <td\n class=\"${classMap({\n day: true,\n 'in-range': this.isInRange(day),\n 'start-date': this.isStartDate(day),\n 'end-date': this.isEndDate(day),\n })}\"\n @click=${() => this.handleDayClick(day)}\n role=\"gridcell\"\n data-date=\"${day.toISODate()}\"\n aria-label=\"${day.toLocaleString({ dateStyle: 'long' })}\"\n aria-selected=\"${this.isSelected(day)}\"\n aria-disabled=\"${isDisabled}\"\n tabindex=\"-1\"\n @mouseenter=\"${this.onDayHover}\"\n >\n ${day.day}\n </td>`;\n })}\n </tr>`\n )}\n </tbody>\n </table>\n </div>\n\n <div class=\"calendar-footer\">\n <div class=\"actions\" @keydown=\"${this.handleButtonKeyDown}\">\n ${this.isRange()\n ? html`\n <button @click=${() => this.handleClearSelection()} data-theme=\"secondary\" id=\"clear-selection\">\n Clear selection\n </button>\n `\n : html` <button @click=${() => this.handleDayClick(this.today)} data-theme=\"secondary\">Today</button> `}\n </div>\n <div>\n <details @keydown=${this.handleButtonKeyDown} @toggle=${this.handleToggle}>\n <summary>${unsafeSVG(keyboard)} Keyboard commands ${unsafeSVG(chevronDown)}</summary>\n <p>Arrow keys: navigate the calendar</p>\n <p>Enter or Space: select the date</p>\n <p>Escape: close the calendar without selecting a date</p>\n <p>Tab: navigate between the calendar and the presets</p>\n <p>Home: move to first day of week</p>\n <p>End: move to last day of week</p>\n <p>Page Up: move to previous month</p>\n <p>Page Down: move to next month</p>\n <p>Shift + Page Up: move to next year</p>\n <p>Shift + Page Down: move to previous year</p>\n </details>\n </div>\n </div>\n </div>\n `;\n }\n\n private dayIsDisabled(day: DateTime) {\n if (this.maxDate && day > this.maxDate) return true;\n\n if (this.minDate && day < this.minDate) return true;\n\n if (this.range && this.isSelectingRange && this.internalRangeValue?.startDate) {\n if (day < this.internalRangeValue.startDate) return true;\n\n if (this.maxDays && day > this.internalRangeValue.startDate.plus({ days: this.maxDays })) return true;\n }\n\n return false;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-calendar': Calendar;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAoB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAEhI,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAoB,EAAwB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC","sourcesContent":["import { DateTime } from 'luxon';\n\nexport const dateConverter = (value: string | null): Date | undefined => value ? DateTime.fromISO(value).toJSDate() : undefined;\n\nexport const dateTimeConverter = (value: string | null): DateTime | undefined => value ? DateTime.fromISO(value) : undefined;\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAoB,EAAE,CACtE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAEzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAoB,EAAwB,EAAE,CAC9E,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC","sourcesContent":["import { DateTime } from 'luxon';\n\nexport const dateConverter = (value: string | null): Date | undefined =>\n value ? DateTime.fromISO(value).toJSDate() : undefined;\n\nexport const dateTimeConverter = (value: string | null): DateTime | undefined =>\n value ? DateTime.fromISO(value) : undefined;\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent tt-calendar following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "@triptease",
6
- "version": "6.0.2",
6
+ "version": "6.0.4",
7
7
  "type": "module",
8
8
  "main": "dist/src/index.js",
9
9
  "module": "dist/src/index.js",
@@ -18,16 +18,14 @@
18
18
  "build": "yarn build:node && yarn build:web",
19
19
  "build:web": "node ../../scripts/esbuild.mjs",
20
20
  "build:node": "tsc && npm run analyze -- --exclude dist",
21
+ "build:node:watch": "tsc --watch",
21
22
  "prepublish": "tsc && npm run analyze -- --exclude dist",
22
- "lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
23
- "format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
24
- "prepare": "husky",
25
23
  "test": "tsc && wtr",
26
24
  "test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\""
27
25
  },
28
26
  "dependencies": {
29
27
  "@lit/context": "^1.1.5",
30
- "@triptease/icons": "^1.2.1",
28
+ "@triptease/icons": "workspace:*",
31
29
  "@types/luxon": "^3.6.2",
32
30
  "lit": "^3.1.4",
33
31
  "luxon": "^3.6.1"
@@ -42,47 +40,11 @@
42
40
  "@web/dev-server": "^0.4.6",
43
41
  "@web/test-runner": "^0.18.2",
44
42
  "concurrently": "^8.2.2",
45
- "eslint": "^8.57.0",
46
- "eslint-config-prettier": "^9.1.0",
47
- "husky": "^9.0.11",
48
- "lint-staged": "^15.2.7",
49
- "prettier": "^3.3.2",
50
43
  "tslib": "^2.6.3",
51
44
  "typescript": "^5.5.3"
52
45
  },
53
46
  "customElements": "custom-elements.json",
54
- "eslintConfig": {
55
- "parser": "@typescript-eslint/parser",
56
- "extends": [
57
- "@open-wc",
58
- "prettier"
59
- ],
60
- "plugins": [
61
- "@typescript-eslint"
62
- ],
63
- "rules": {
64
- "no-unused-vars": "off",
65
- "@typescript-eslint/no-unused-vars": [
66
- "error"
67
- ],
68
- "import/no-unresolved": "off",
69
- "import/extensions": [
70
- "error",
71
- "always",
72
- {
73
- "ignorePackages": true
74
- }
75
- ]
76
- }
77
- },
78
- "prettier": {
79
- "singleQuote": true,
80
- "arrowParens": "avoid"
81
- },
82
- "lint-staged": {
83
- "*.ts": [
84
- "eslint --fix",
85
- "prettier --write"
86
- ]
47
+ "publishConfig": {
48
+ "access": "public"
87
49
  }
88
50
  }
@@ -3,38 +3,29 @@ import { DateTime, Settings } from 'luxon';
3
3
  import '../src/tt-calendar.js'; // This handles the registration
4
4
  import { Calendar } from '../src/TtCalendar.js';
5
5
 
6
-
7
6
  describe('Calendar', () => {
8
7
  describe('initialization', () => {
9
- const originalNow = DateTime.now().toMillis()
8
+ const originalNow = DateTime.now().toMillis();
10
9
 
11
10
  afterEach(() => {
12
11
  Settings.defaultZone = 'system';
13
- Settings.now = () => originalNow
12
+ Settings.now = () => originalNow;
14
13
  });
15
14
 
16
15
  it('should render with default props', async () => {
17
- const el = await fixture<Calendar>(html`
18
- <tt-calendar></tt-calendar>`);
16
+ const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);
19
17
  expect(el).to.exist;
20
18
  expect(el.range).to.be.false;
21
19
  expect(el.value).to.be.undefined;
22
20
  });
23
21
 
24
- [
25
- 'Australia/Brisbane',
26
- 'America/New_York',
27
- 'Europe/London',
28
- 'Asia/Tokyo',
29
- 'Etc/UTC'
30
- ].forEach((timezone) => {
22
+ ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {
31
23
  it(`should render the correct days of the week in ${timezone} timezone`, async () => {
32
24
  Settings.defaultZone = timezone;
33
- const now = DateTime.local(2025,6,4,22,0,0).toMillis();
25
+ const now = DateTime.local(2025, 6, 4, 22, 0, 0).toMillis();
34
26
  Settings.now = () => now;
35
27
  const today = DateTime.now().toISO()!;
36
- const el = await fixture<Calendar>(html`
37
- <tt-calendar value="${today}"></tt-calendar>`);
28
+ const el = await fixture<Calendar>(html` <tt-calendar value="${today}"></tt-calendar>`);
38
29
 
39
30
  const sunday = DateTime.fromISO(today).startOf('week').plus({ days: 6 }).toFormat('ccc');
40
31
 
@@ -51,8 +42,7 @@ describe('Calendar', () => {
51
42
 
52
43
  describe('visibility', () => {
53
44
  xit('should toggle visibility when calling toggleVisibility', async () => {
54
- const el = await fixture<Calendar>(html`
55
- <tt-calendar></tt-calendar>`);
45
+ const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);
56
46
 
57
47
  expect(el).to.be.instanceOf(Calendar);
58
48
 
@@ -67,13 +57,12 @@ describe('Calendar', () => {
67
57
  });
68
58
 
69
59
  xit('should close on outside click', async () => {
70
- const el = await fixture<Calendar>(html`
71
- <tt-calendar></tt-calendar>`);
60
+ const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);
72
61
  el.toggleVisibility();
73
62
  await elementUpdated(el);
74
63
 
75
64
  const focusOutEvent = new FocusEvent('focusout', {
76
- relatedTarget: document.body
65
+ relatedTarget: document.body,
77
66
  });
78
67
  el.shadowRoot!.querySelector('[part="calendar"]')?.dispatchEvent(focusOutEvent);
79
68
  await elementUpdated(el);
@@ -82,8 +71,7 @@ describe('Calendar', () => {
82
71
  });
83
72
 
84
73
  xit('should focus calendar div when opened', async () => {
85
- const el = await fixture<Calendar>(html`
86
- <tt-calendar></tt-calendar>`);
74
+ const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);
87
75
  el.toggleVisibility();
88
76
 
89
77
  await elementUpdated(el);
@@ -94,19 +82,13 @@ describe('Calendar', () => {
94
82
  });
95
83
  });
96
84
 
97
- [
98
- 'Australia/Brisbane',
99
- 'America/New_York',
100
- 'Europe/London',
101
- 'Asia/Tokyo',
102
- 'Etc/UTC'
103
- ].forEach((timezone) => {
85
+ ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {
104
86
  describe(`single date selection in ${timezone} timezone`, () => {
105
- const originalNow = DateTime.now().toMillis()
87
+ const originalNow = DateTime.now().toMillis();
106
88
 
107
89
  afterEach(() => {
108
90
  Settings.defaultZone = 'system';
109
- Settings.now = () => originalNow
91
+ Settings.now = () => originalNow;
110
92
  });
111
93
 
112
94
  const selectDay = (day: string, el: HTMLElement): void => {
@@ -115,16 +97,13 @@ describe('Calendar', () => {
115
97
  }
116
98
 
117
99
  const allCells = el.shadowRoot.querySelectorAll('td[role="gridcell"]');
118
- const dayCell = Array.from(allCells).filter(
119
- (cell) => cell.textContent?.trim() === day
120
- )[0] as HTMLElement;
100
+ const dayCell = Array.from(allCells).filter((cell) => cell.textContent?.trim() === day)[0] as HTMLElement;
121
101
  dayCell.click();
122
102
  };
123
103
 
124
104
  it('should emit date-selection event when selecting a date', async () => {
125
105
  Settings.defaultZone = timezone;
126
- const el = await fixture<Calendar>(html`
127
- <tt-calendar value="2025-01-09"></tt-calendar>`);
106
+ const el = await fixture<Calendar>(html` <tt-calendar value="2025-01-09"></tt-calendar>`);
128
107
  const listener = oneEvent(el, 'date-selection');
129
108
  await elementUpdated(el);
130
109
  selectDay('4', el);
@@ -133,25 +112,17 @@ describe('Calendar', () => {
133
112
 
134
113
  const { detail } = await listener;
135
114
  const actual = detail as Date;
136
- const expected = "2025-01-04";
115
+ const expected = '2025-01-04';
137
116
  expect(actual).to.equal(expected);
138
117
  });
139
118
  });
140
119
  });
141
- [
142
- 'Australia/Brisbane',
143
- 'America/New_York',
144
- 'Europe/London',
145
- 'Asia/Tokyo',
146
- 'Etc/UTC'
147
- ].forEach((timezone) => {
120
+ ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {
148
121
  describe('date range selection', () => {
149
-
150
122
  it(`should emit date-range-selection event when selecting range in ${timezone} timezone`, async () => {
151
123
  Settings.defaultZone = timezone;
152
124
  Settings.now = () => DateTime.local(2025, 7, 1, 22, 0, 0).toMillis();
153
- const el = await fixture<Calendar>(html`
154
- <tt-calendar range></tt-calendar>`);
125
+ const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);
155
126
  const listener = oneEvent(el, 'date-range-selection');
156
127
 
157
128
  el.toggleVisibility();
@@ -172,16 +143,15 @@ describe('Calendar', () => {
172
143
  expect(detail).to.have.property('endDate');
173
144
 
174
145
  const { startDate, endDate } = detail;
175
- const expectedStartDate = "2025-07-01";
176
- const expectedEndDate = "2025-07-06";
146
+ const expectedStartDate = '2025-07-01';
147
+ const expectedEndDate = '2025-07-06';
177
148
  await expect(startDate).to.equal(expectedStartDate);
178
149
  await expect(endDate).to.equal(expectedEndDate);
179
150
  });
180
151
 
181
152
  it('should disable dates before the start of the range when selecting', async () => {
182
153
  Settings.defaultZone = timezone;
183
- const el = await fixture<Calendar>(html`
184
- <tt-calendar range></tt-calendar>`);
154
+ const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);
185
155
  el.toggleVisibility();
186
156
  await elementUpdated(el);
187
157
 
@@ -194,11 +164,9 @@ describe('Calendar', () => {
194
164
  });
195
165
  });
196
166
 
197
-
198
167
  describe('clear selection', () => {
199
168
  it('should clear selection', async () => {
200
- const el = await fixture<Calendar>(html`
201
- <tt-calendar range></tt-calendar>`);
169
+ const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);
202
170
  const listener = oneEvent(el, 'date-range-selection');
203
171
 
204
172
  el.toggleVisibility();
@@ -216,21 +184,19 @@ describe('Calendar', () => {
216
184
 
217
185
  describe('a11y', () => {
218
186
  it('should have proper ARIA attributes', async () => {
219
- const el = await fixture<Calendar>(html`
220
- <tt-calendar></tt-calendar>`);
187
+ const el = await fixture<Calendar>(html` <tt-calendar></tt-calendar>`);
221
188
  el.toggleVisibility();
222
189
  await elementUpdated(el);
223
190
 
224
191
  const days = el.shadowRoot!.querySelectorAll('.day');
225
- days.forEach(day => {
192
+ days.forEach((day) => {
226
193
  expect(day.getAttribute('role')).to.equal('gridcell');
227
194
  expect(day.getAttribute('aria-label')).to.exist;
228
195
  });
229
196
  });
230
197
 
231
198
  it('should have proper ARIA selected states', async () => {
232
- const el = await fixture<Calendar>(html`
233
- <tt-calendar range></tt-calendar>`);
199
+ const el = await fixture<Calendar>(html` <tt-calendar range></tt-calendar>`);
234
200
  el.toggleVisibility();
235
201
  await elementUpdated(el);
236
202
 
@@ -243,4 +209,3 @@ describe('Calendar', () => {
243
209
  });
244
210
  });
245
211
  });
246
-
package/tsconfig.json CHANGED
@@ -18,5 +18,5 @@
18
18
  "incremental": true,
19
19
  "skipLibCheck": true
20
20
  },
21
- "include": ["src/**/*.ts", "stories/**/*.ts", "test/**/*.ts"],
21
+ "include": ["src/**/*.ts", "stories/**/*.ts", "test/**/*.ts"]
22
22
  }