You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/morfo/components/range-calendar.ts

326 lines
8.0 KiB

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 `<tr>` 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;

Powered by TurnKey Linux.