import type { Morfo } from '../types'; import { v } from '../types'; export const rangeCalendarMorfo = { name: 'RangeCalendar', kebab: 'range-calendar', scope: ['soma', 'sema', 'eidos'], expression: 'family-default', apg: 'https://www.w3.org/WAI/ARIA/apg/patterns/grid/', texts: { label: '#?components.range-calendar.label|Range calendar', 'range-start': '#?components.range-calendar.range-start|range start', 'range-end': '#?components.range-calendar.range-end|range end', 'in-range': '#?components.range-calendar.in-range|in range' }, events: [ { name: 'commit-select-start', semantic: { family: 'commit', verb: 'select', target: v.partRef('day'), intent: 'affirm', sequence: 'post' } }, { name: 'commit-select-range', semantic: { family: 'commit', verb: 'select', target: v.partRef('day'), intent: 'fulfill', sequence: 'post' } }, { name: 'commit-reset', semantic: { family: 'commit', verb: 'reset', target: v.partRef('day'), intent: 'neutral', sequence: 'post' } }, { name: 'shift-navigate', semantic: { family: 'shift', verb: 'navigate', target: v.partRef('provider'), sequence: 'post' } } ], parts: [ { name: 'Provider', kebab: 'provider', archetype: 'provider', kind: 'public', defaultElement: 'div', role: 'application', optional: false, data: [ { attr: 'data-readonly', severity: 'optional' }, { attr: 'data-disabled', severity: 'optional' }, { attr: 'data-invalid', severity: 'optional' }, { attr: 'data-selecting', severity: 'optional' } ], aria: [ { attr: 'aria-label', value: v.propRef('ariaLabel'), severity: 'recommended' }, { attr: 'aria-disabled', value: v.propRef('disabled'), severity: 'optional', ariaBoolean: true } ], keyboard: [ { key: 'ArrowRight', action: 'next-day' }, { key: 'ArrowLeft', action: 'prev-day' }, { key: 'ArrowDown', action: 'next-week' }, { key: 'ArrowUp', action: 'prev-week' }, { key: 'PageUp', action: 'prev-month' }, { key: 'PageDown', action: 'next-month' }, { key: 'Home', action: 'first-day-of-week' }, { key: 'End', action: 'last-day-of-week' }, { key: 'Enter', action: 'select' }, { key: ' ', action: 'select' }, { key: 'Escape', action: 'cancel-selection' } ] }, { name: 'Header', kebab: 'header', archetype: 'header', kind: 'public', defaultElement: 'div', optional: true, data: [], aria: [{ attr: 'aria-hidden', value: v.literal('true') }] }, { name: 'Heading', kebab: 'heading', archetype: 'header', kind: 'public', defaultElement: 'div', optional: true, data: [], aria: [] }, { name: 'PrevButton', kebab: 'prev-button', archetype: 'trigger', kind: 'public', defaultElement: 'button', role: 'button', optional: true, data: [{ attr: 'data-disabled', severity: 'optional' }], aria: [ { attr: 'type', value: v.literal('button') }, { attr: 'aria-label', value: v.commonRef('calendar.prev-month', 'Previous month'), severity: 'recommended' } ] }, { name: 'NextButton', kebab: 'next-button', archetype: 'trigger', kind: 'public', defaultElement: 'button', role: 'button', optional: true, data: [{ attr: 'data-disabled', severity: 'optional' }], aria: [ { attr: 'type', value: v.literal('button') }, { attr: 'aria-label', value: v.commonRef('calendar.next-month', 'Next month'), severity: 'recommended' } ] }, { name: 'MonthSelect', kebab: 'month-select', archetype: 'input', kind: 'public', defaultElement: 'select', optional: true, data: [{ attr: 'data-disabled', severity: 'optional' }], aria: [] }, { name: 'YearSelect', kebab: 'year-select', archetype: 'input', kind: 'public', defaultElement: 'select', optional: true, data: [{ attr: 'data-disabled', severity: 'optional' }], aria: [] }, { name: 'Grid', kebab: 'grid', kind: 'public', defaultElement: 'table', role: 'grid', optional: false, data: [], aria: [ { attr: 'aria-labelledby', value: v.partRef('heading'), condition: { when: 'part-present', part: 'heading' }, severity: 'recommended' }, { attr: 'aria-readonly', value: v.propRef('readonly'), severity: 'optional', ariaBoolean: true }, { attr: 'aria-disabled', value: v.propRef('disabled'), severity: 'optional', ariaBoolean: true } ] }, { name: 'GridHead', kebab: 'grid-head', archetype: 'header', kind: 'public', defaultElement: 'thead', optional: false, data: [], aria: [] }, { name: 'GridBody', kebab: 'grid-body', kind: 'public', defaultElement: 'tbody', optional: false, data: [], aria: [] }, { name: 'GridRow', kebab: 'grid-row', // No archetype: structural `` row, not a menu `item` (would tint the // whole week on hover). kind: 'public', defaultElement: 'tr', role: 'row', optional: false, data: [], aria: [] }, { name: 'HeadCell', kebab: 'head-cell', archetype: 'header', kind: 'public', defaultElement: 'th', optional: false, data: [], aria: [] }, { name: 'Cell', kebab: 'cell', // No archetype: display `gridcell` container, not a menu `item` (would // add the listbox-row padding + hover band). The Day inside is the item. kind: 'public', defaultElement: 'td', role: 'gridcell', optional: false, data: [ { attr: 'data-value' }, { attr: 'data-selected', severity: 'optional' }, { attr: 'data-range-start', severity: 'optional' }, { attr: 'data-range-end', severity: 'optional' }, { attr: 'data-in-range', severity: 'optional' }, { attr: 'data-preview-start', severity: 'optional' }, { attr: 'data-preview-end', severity: 'optional' }, { attr: 'data-in-preview-range', severity: 'optional' }, { attr: 'data-disabled', severity: 'optional' }, { attr: 'data-unavailable', severity: 'optional' }, { attr: 'data-today', severity: 'optional' }, { attr: 'data-weekend', severity: 'optional' }, { attr: 'data-holiday', severity: 'optional' }, { attr: 'data-outside-month', severity: 'optional' } ], aria: [ { attr: 'aria-selected', value: v.propRef('selected'), severity: 'optional', ariaBoolean: true }, { attr: 'aria-disabled', value: v.propRef('disabled'), severity: 'optional', ariaBoolean: true } ] }, { name: 'Day', kebab: 'day', // No archetype: bespoke `[data-range-calendar-day]` styling owns hover / // selected / range. `data-archetype='item'` would let generic listbox-item // rules override the selected fill (showed the menu tint, not the accent). kind: 'public', defaultElement: 'div', role: 'button', optional: false, data: [ { attr: 'data-value' }, { attr: 'data-selected', severity: 'optional' }, { attr: 'data-range-start', severity: 'optional' }, { attr: 'data-range-end', severity: 'optional' }, { attr: 'data-in-range', severity: 'optional' }, { attr: 'data-preview-start', severity: 'optional' }, { attr: 'data-preview-end', severity: 'optional' }, { attr: 'data-in-preview-range', severity: 'optional' }, { attr: 'data-disabled', severity: 'optional' }, { attr: 'data-unavailable', severity: 'optional' }, { attr: 'data-today', severity: 'optional' }, { attr: 'data-weekend', severity: 'optional' }, { attr: 'data-holiday', severity: 'optional' }, { attr: 'data-outside-month', severity: 'optional' }, { attr: 'data-focused', severity: 'optional' } ], aria: [ { attr: 'aria-label', value: v.propRef('dateLabel'), severity: 'recommended' }, { attr: 'aria-disabled', value: v.propRef('disabled'), severity: 'optional', ariaBoolean: true }, { attr: 'aria-selected', value: v.propRef('selected'), severity: 'optional', ariaBoolean: true } ] } ] } as const satisfies Morfo;