diff --git a/.changeset/datepicker-week-numbers.md b/.changeset/datepicker-week-numbers.md new file mode 100644 index 000000000..c1329bbf6 --- /dev/null +++ b/.changeset/datepicker-week-numbers.md @@ -0,0 +1,7 @@ +--- +"@tabler/core": minor +"@tabler/preview": patch +"@tabler/docs": patch +--- + +Added the `weekNumbers` option to `Datepicker` to show the week number in front of each row. diff --git a/core/js/src/datepicker.ts b/core/js/src/datepicker.ts index 903487190..8e7ae8e0b 100644 --- a/core/js/src/datepicker.ts +++ b/core/js/src/datepicker.ts @@ -100,6 +100,8 @@ type ComponentConfig = { selectedDates: string[] selectionMode: DateMode placement: PositionToInput + /** show the ISO week number in front of each row */ + weekNumbers: boolean /** pass-through for any Vanilla Calendar Pro option */ vcpOptions: object } @@ -122,6 +124,7 @@ const Default: ComponentConfig = { selectedDates: [], selectionMode: 'single', placement: 'left', + weekNumbers: false, vcpOptions: {}, } @@ -139,6 +142,7 @@ const DefaultType: Record = { selectedDates: 'array', selectionMode: 'string', placement: 'string', + weekNumbers: 'boolean', vcpOptions: 'object', } @@ -605,6 +609,7 @@ class Datepicker extends BaseComponent { selectionDatesMode: this._config.selectionMode, selectedDates: this._config.selectedDates, displayMonthsCount: this._config.displayMonthsCount, + enableWeekNumbers: this._config.weekNumbers || Boolean(vcpOptions.enableWeekNumbers), type: this._config.displayMonthsCount > 1 ? 'multiple' : 'default', selectedTheme: vcpTheme, themeAttrDetect: '[data-bs-theme]', diff --git a/core/js/tests/unit/datepicker.spec.ts b/core/js/tests/unit/datepicker.spec.ts index 3078bdbcc..4cb64ccb1 100644 --- a/core/js/tests/unit/datepicker.spec.ts +++ b/core/js/tests/unit/datepicker.spec.ts @@ -115,6 +115,24 @@ describe('Datepicker', () => { expect(instance._config.firstWeekday).toBe(0) }) + it('should turn week numbers on from a data attribute', () => { + fixtureEl.innerHTML = '' + + const instance = new Datepicker(input()) + + expect(Datepicker.Default.weekNumbers).toBe(false) + expect(instance._config.weekNumbers).toBe(true) + expect(instance._buildCalendarOptions().enableWeekNumbers).toBe(true) + }) + + it('should keep week numbers enabled through vcpOptions', () => { + fixtureEl.innerHTML = '' + + const instance = new Datepicker(input(), { vcpOptions: { enableWeekNumbers: true } }) + + expect(instance._buildCalendarOptions().enableWeekNumbers).toBe(true) + }) + it('should let a passed config win over data attributes', () => { fixtureEl.innerHTML = '' diff --git a/core/scss/ui/_datepicker.scss b/core/scss/ui/_datepicker.scss index 21345d705..ff51931e0 100644 --- a/core/scss/ui/_datepicker.scss +++ b/core/scss/ui/_datepicker.scss @@ -19,6 +19,8 @@ --calendar-font-size: #{$datepicker-calendar-font-size}; --calendar-header-font-weight: #{$datepicker-calendar-header-font-weight}; --calendar-weekday-color: var(--secondary); + --calendar-week-number-color: var(--secondary); + --calendar-week-number-border-color: var(--border-color); --calendar-day-hover-bg: var(--hover-bg); --calendar-day-selected-bg: var(--primary); --calendar-day-selected-color: var(--primary-fg); @@ -151,6 +153,12 @@ } } +// Holds the week numbers column, when enabled, next to the month +[data-vc='wrapper'] { + display: flex; + flex-grow: 1; +} + [data-vc='content'] { display: flex; flex-grow: 1; @@ -252,6 +260,46 @@ button[data-vc-week-day] { cursor: pointer; } +// Week numbers: a column in front of the month, with a title that lines up +// with the weekday header and one number for each row of dates. +[data-vc-week='numbers'] { + display: flex; + flex-direction: column; + padding-inline-end: 0.5rem; + margin-inline-end: 0.5rem; + border-inline-end: var(--border-width) solid var(--calendar-week-number-border-color); +} + +[data-vc-week-numbers='title'] { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 0.5rem; + font-size: var(--calendar-day-font-size); + font-weight: var(--calendar-header-font-weight); + line-height: 1rem; + color: var(--calendar-week-number-color); +} + +[data-vc-week-numbers='content'] { + display: grid; + grid-auto-rows: calc(var(--calendar-day-size) + 0.25rem); + align-items: center; + justify-items: center; +} + +[data-vc-week-number] { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + min-width: var(--calendar-day-size); + font-size: var(--calendar-day-font-size); + font-weight: $font-weight-normal; + line-height: 1rem; + color: var(--calendar-week-number-color); +} + // Dates grid [data-vc='dates'] { pointer-events: none; diff --git a/docs/content/ui/plugins/date-picker.mdx b/docs/content/ui/plugins/date-picker.mdx index 150bd2c37..b17a14933 100644 --- a/docs/content/ui/plugins/date-picker.mdx +++ b/docs/content/ui/plugins/date-picker.mdx @@ -131,6 +131,15 @@ The week starts on Monday. Set `data-bs-first-weekday="0"` to start it on Sunday +### Week numbers + +Add `data-bs-week-numbers="true"` to show the week number in front of each row. Use it where people plan by week, for example delivery dates or sprints. + + + + + + ### Placement The popup lines up with the left edge of the field. Set `data-bs-placement` to `center`, `right` or `auto` to change that. @@ -224,6 +233,7 @@ const datepicker = new tabler.Datepicker(document.getElementById('my-date'), { | `selectedDates` | array | `[]` | Preselected dates as `YYYY-MM-DD`. | | `selectionMode` | string | `'single'` | `'single'`, `'multiple'` or `'multiple-ranged'`. | | `placement` | string | `'left'` | Where the popup lines up with the field: `'left'`, `'center'`, `'right'` or `'auto'`. | +| `weekNumbers` | boolean | `false` | Show the week number in front of each row. | | `datepickerTheme` | string | `null` | Force the popup's theme to `'light'`, `'dark'` or `'auto'`. By default it follows the nearest `[data-bs-theme]`. | | `vcpOptions` | object | `{}` | Any [Vanilla Calendar Pro option](https://vanilla-calendar.pro/docs/reference/settings), passed straight through. | diff --git a/preview/pages/datepicker.astro b/preview/pages/datepicker.astro index e20f0f42a..e7d38c5ce 100644 --- a/preview/pages/datepicker.astro +++ b/preview/pages/datepicker.astro @@ -108,6 +108,17 @@ const rangeEnd = `${year}-06-18` +
+ + + Week numbers + Add data-bs-week-numbers="true" to show the week number in front of each row. + + + + +
+
@@ -187,6 +198,16 @@ const rangeEnd = `${year}-06-18`
+
+ + + Inline with week numbers + Week numbers work in an inline calendar too, and with every selection mode. + + + +
+
diff --git a/shared/ui/Datepicker.astro b/shared/ui/Datepicker.astro index 56fd5fed4..7d6618138 100644 --- a/shared/ui/Datepicker.astro +++ b/shared/ui/Datepicker.astro @@ -25,6 +25,8 @@ interface Props { /** 0 = Sunday, 1 = Monday */ firstWeekday?: 0 | 1 | 2 | 3 | 4 | 5 | 6 placement?: 'left' | 'center' | 'right' | 'auto' + /** show the week number in front of each row */ + weekNumbers?: boolean /** name of the hidden input an inline calendar submits with a form */ name?: string } @@ -43,6 +45,7 @@ const { dateMax, firstWeekday, placement, + weekNumbers = false, name, } = Astro.props @@ -58,6 +61,7 @@ const dataAttributes = { 'data-bs-date-max': dateMax, 'data-bs-first-weekday': firstWeekday, 'data-bs-placement': placement, + 'data-bs-week-numbers': weekNumbers ? 'true' : undefined, } ---