diff --git a/packages/ffe-datepicker-react/src/calendar/Calendar.spec.tsx b/packages/ffe-datepicker-react/src/calendar/Calendar.spec.tsx index 6131c3d2ea..b4a56158d2 100644 --- a/packages/ffe-datepicker-react/src/calendar/Calendar.spec.tsx +++ b/packages/ffe-datepicker-react/src/calendar/Calendar.spec.tsx @@ -177,4 +177,27 @@ describe('Calendar', () => { const inRange = screen.getByRole('button', { name: '12. januar 2025' }); expect(inRange).toHaveAttribute('aria-disabled', 'false'); }); -}); \ No newline at end of file + + it('disables dates in disable dates', () => { + render( + , + ); + + const disabled1 = screen.getByRole('button', { + name: '14. januar 2025', + }); + expect(disabled1).toHaveAttribute('aria-disabled', 'true'); + + const disabled2 = screen.getByRole('button', { + name: '17. januar 2025', + }); + expect(disabled2).toHaveAttribute('aria-disabled', 'true'); + + const inRange = screen.getByRole('button', { name: '12. januar 2025' }); + expect(inRange).toHaveAttribute('aria-disabled', 'false'); + }); +}); diff --git a/packages/ffe-datepicker-react/src/calendar/Calendar.stories.tsx b/packages/ffe-datepicker-react/src/calendar/Calendar.stories.tsx index 51c646968f..8107276b36 100644 --- a/packages/ffe-datepicker-react/src/calendar/Calendar.stories.tsx +++ b/packages/ffe-datepicker-react/src/calendar/Calendar.stories.tsx @@ -47,19 +47,21 @@ export const WithDropdownCaption: Story = { const [selectedDate, setSelectedDate] = useState< string | null | undefined >(args.selectedDate); - + return (

Kalender med nedtrekksliste for måned og år

- Denne kalenderen viser måned og år som nedtrekkslister, slik at brukeren enkelt kan navigere til ønsket dato - uten å klikke gjennom flere måneder. Spesielt nyttig når man ønsker å velge datoer langt frem eller tilbake i tid. + Denne kalenderen viser måned og år som nedtrekkslister, slik + at brukeren enkelt kan navigere til ønsket dato uten å + klikke gjennom flere måneder. Spesielt nyttig når man ønsker + å velge datoer langt frem eller tilbake i tid.

{ + onDatePicked={date => { setSelectedDate(date); console.log('Valgt dato:', date); }} @@ -74,3 +76,29 @@ export const WithDropdownCaption: Story = { ); }, }; + +export const WithDisabledDates: Story = { + args: { + calendarClassName: undefined, + escKeyHandler: () => null, + locale: 'nb', + onDatePicked: (date: string) => null, + selectedDate: '18.12.2025', + focusOnMount: false, + minDate: '10.11.2025', + maxDate: '15.01.2026', + disabledDates: ['24.12.2025', '25.12.2025', '31.12.2025'], + }, + render: function Render(args) { + const [selectedDate, setSelectedDate] = useState< + string | null | undefined + >(args.selectedDate); + return ( + + ); + }, +}; diff --git a/packages/ffe-datepicker-react/src/calendar/Calendar.tsx b/packages/ffe-datepicker-react/src/calendar/Calendar.tsx index c624e22870..a542cae320 100644 --- a/packages/ffe-datepicker-react/src/calendar/Calendar.tsx +++ b/packages/ffe-datepicker-react/src/calendar/Calendar.tsx @@ -23,6 +23,8 @@ export interface CalendarProps { minDate?: string | null; /** Seneste tillatte dato (format: 'dd.mm.yyyy') - brukes kun til å bestemme år-intervall i dropdown */ maxDate?: string | null; + /** Array av datoer i format 'dd.mm.yyyy' som skal være deaktivert */ + disabledDates?: string[]; } interface State { @@ -41,6 +43,7 @@ export class Calendar extends Component { getSimpleDateFromString(props?.selectedDate), props.minDate, props.maxDate, + props.disabledDates, props.locale, ), isFocusingHeader: false, @@ -72,6 +75,7 @@ export class Calendar extends Component { getSimpleDateFromString(this.props.selectedDate), this.props.minDate, this.props.maxDate, + this.props.disabledDates, this.props.locale, ), }, @@ -316,7 +320,9 @@ export class Calendar extends Component { monthNumber={calendar.focusedDate.month + 1} // Convert to 1-indexed month locale={this.props.locale} dropdownCaption={this.props.dropdownCaption} - onMonthYearChange={(month, year) => this.navigateToMonthYear(month, year)} + onMonthYearChange={(month, year) => + this.navigateToMonthYear(month, year) + } minDate={this.props.minDate} maxDate={this.props.maxDate} /> diff --git a/packages/ffe-datepicker-react/src/datelogic/simplecalendar.ts b/packages/ffe-datepicker-react/src/datelogic/simplecalendar.ts index 35a8da63ee..7f511623f6 100644 --- a/packages/ffe-datepicker-react/src/datelogic/simplecalendar.ts +++ b/packages/ffe-datepicker-react/src/datelogic/simplecalendar.ts @@ -55,11 +55,13 @@ export class SimpleCalendar { firstDay: number; minDate: SimpleDate | null; maxDate: SimpleDate | null; + disabledDates: string[] = []; constructor( initialDate?: SimpleDate | null, minDate?: string | null, maxDate?: string | null, + disabledDates?: string[], locale: Locale = 'nb', ) { this.locale = locale; @@ -69,6 +71,7 @@ export class SimpleCalendar { this.selectedDate = initialDate ? initialDate.clone() : initialDate; this.minDate = minDate ? getSimpleDateFromString(minDate) : null; this.maxDate = maxDate ? getSimpleDateFromString(maxDate) : null; + this.disabledDates = disabledDates ? disabledDates : []; // Settings this.firstDay = i18n[locale].FIRST_DAY_OF_WEEK; @@ -196,6 +199,7 @@ export class SimpleCalendar { result.push(week); for (let dayx = 0; dayx < 7; dayx++) { + console.log(this.disabledDates, currentDate.format()); const date: CalendarButtonState = { dayInMonth: currentDate.date, timestamp: currentDate.timestamp, @@ -206,11 +210,15 @@ export class SimpleCalendar { isSelected: !!this.selectedDate && currentDate.equal(this.selectedDate), - isEnabled: isDateWithinMinMax( - currentDate, - this.minDate, - this.maxDate, - ), + isEnabled: + isDateWithinMinMax( + currentDate, + this.minDate, + this.maxDate, + ) && + (this.disabledDates + ? !this.disabledDates.includes(currentDate.format()) + : true), }; week.dates.push(date); currentDate.adjust({ period: 'D', offset: 1 }); diff --git a/packages/ffe-datepicker-react/src/datepicker/Datepicker.stories.tsx b/packages/ffe-datepicker-react/src/datepicker/Datepicker.stories.tsx index 8c04422772..0bdc67dfc2 100644 --- a/packages/ffe-datepicker-react/src/datepicker/Datepicker.stories.tsx +++ b/packages/ffe-datepicker-react/src/datepicker/Datepicker.stories.tsx @@ -10,7 +10,7 @@ const meta: Meta = { argTypes: { minDate: { control: 'text' }, maxDate: { control: 'text' }, - } + }, }; export default meta; @@ -114,7 +114,10 @@ export const WithDropdownCaption: Story = { const [date, setDate] = useState('01.12.2024'); return ( - + { @@ -231,9 +234,34 @@ export const WithDescription: Story = { const [date, setDate] = useState('01.12.2024'); return ( - + description="Dette er en beskrivelse av Datepicker-komponenten. Den gir ekstra informasjon om hvordan den skal brukes." + > + { + setDate(date); + console.log('Datepicker value:', date); + }} + {...args} + /> + + ); + }, +}; + +export const WithDisabledDates: Story = { + args: { + ...Standard.args, + disabledDates: ['24.12.2024', '25.12.2024', '31.12.2024'], + }, + render: function Render({ value, onChange, ...args }: DatepickerProps) { + const [date, setDate] = useState('01.12.2024'); + + return ( + { diff --git a/packages/ffe-datepicker-react/src/datepicker/DatepickerComp.tsx b/packages/ffe-datepicker-react/src/datepicker/DatepickerComp.tsx index 6839699f72..2168d3ada6 100644 --- a/packages/ffe-datepicker-react/src/datepicker/DatepickerComp.tsx +++ b/packages/ffe-datepicker-react/src/datepicker/DatepickerComp.tsx @@ -32,17 +32,17 @@ export interface DatepickerCompProps { onBlur?: (evt: React.FocusEvent) => void; calendarAbove?: boolean; id?: string; - /** + /** * Seneste tillatte dato. Format: 'dd.mm.yyyy' - * + * * Merk: For å holde år-dropdownen håndterbar, begrenses årsintervallet automatisk til * maksimalt 10 år bakover eller fremover fra inneværende år, selv om minDate/maxDate * tillater et bredere intervall. */ maxDate?: string | null; - /** + /** * Tidligste tillatte dato. Format: 'dd.mm.yyyy' - * + * * Merk: For å holde år-dropdownen håndterbar, begrenses årsintervallet automatisk til * maksimalt 10 år bakover eller fremover fra inneværende år, selv om minDate/maxDate * tillater et bredere intervall. @@ -55,6 +55,8 @@ export interface DatepickerCompProps { labelId: string; /** Om måned- og år-dropdown skal vises i kalenderen */ dropdownCaption?: boolean; + /** Liste over datoer som skal deaktiveres i kalenderen */ + disabledDates?: string[]; } export const DatepickerComp: React.FC = ({ @@ -72,6 +74,7 @@ export const DatepickerComp: React.FC = ({ fieldMessage, labelId, dropdownCaption, + disabledDates, }) => { const { day, @@ -431,6 +434,7 @@ export const DatepickerComp: React.FC = ({ dropdownCaption={dropdownCaption} minDate={minDate} maxDate={maxDate} + disabledDates={disabledDates} /> )}