diff --git a/base.scss b/base.scss
index 3f052653a..aa8d98db7 100644
--- a/base.scss
+++ b/base.scss
@@ -23,7 +23,8 @@
@import "./src/stories/Library/cover/cover";
@import "./src/stories/Library/Forms/input/input";
@import "./src/stories/Library/Forms/date-picker/date-picker";
-@import "./src/stories/Library/date-calendar/date-calendar";
+@import "./src/stories/Library/date-range/flatpickr";
+@import "./src/stories/Library/date-range/date-range";
@import "./src/stories/Library/list-buttons/list-buttons";
@import "./src/stories/Library/progress-bar/progress-bar";
@import "./src/stories/Library/missing-story/missing-story";
diff --git a/src/stories/Blocks/content-list-page/ContentListPage.tsx b/src/stories/Blocks/content-list-page/ContentListPage.tsx
index 955fab030..fcdb115de 100644
--- a/src/stories/Blocks/content-list-page/ContentListPage.tsx
+++ b/src/stories/Blocks/content-list-page/ContentListPage.tsx
@@ -3,6 +3,7 @@ import ContentList from "../../Library/content-list/ContentList";
import contentListData from "../../Library/content-list/ContentListData";
import { InputLabel } from "../../Library/input-label/InputLabel";
import { Dropdown } from "../../Library/dropdown/Dropdown";
+import DateRange from "../../Library/date-range/DateRange";
const filters = [
{
@@ -50,6 +51,10 @@ const ContentListPage: React.FC = () => {
);
})}
+
+
+
+
diff --git a/src/stories/Blocks/content-list-page/content-list-page.scss b/src/stories/Blocks/content-list-page/content-list-page.scss
index 83f3abe16..a360b7777 100644
--- a/src/stories/Blocks/content-list-page/content-list-page.scss
+++ b/src/stories/Blocks/content-list-page/content-list-page.scss
@@ -21,3 +21,19 @@
flex-direction: row;
}
}
+
+.content-list-page__filter--right {
+ @include media-query__small {
+ margin-left: auto;
+ }
+}
+
+.content-list-page__filter--date {
+ @include media-query__small {
+ // Use the same width as allocated for dropdowns. This should be wide
+ // enough to show all elements when using the j. M Y format e.g.
+ // 01. jan 2024
+ // @see src/stories/Library/dropdown/dropdown.scss
+ width: 230px;
+ }
+}
diff --git a/src/stories/Library/Modals/modal-pause/modal-pause.scss b/src/stories/Library/Modals/modal-pause/modal-pause.scss
index 65a2d3bd6..ece57a367 100644
--- a/src/stories/Library/Modals/modal-pause/modal-pause.scss
+++ b/src/stories/Library/Modals/modal-pause/modal-pause.scss
@@ -31,23 +31,3 @@
display: grid;
justify-content: center;
}
-
-.date-range {
- input {
- border: 1px solid $color__global-tertiary-1;
- box-sizing: border-box;
- background-color: $color__global-primary;
- min-width: 100%;
- height: 50px;
- padding: 0 10px;
- color: $color__text-secondary-gray;
- @include typography($typo__button);
- }
-
- .date-range__input {
- display: flex;
- flex-direction: column;
- width: 100%;
- margin-bottom: $s-lg;
- }
-}
diff --git a/src/stories/Library/date-calendar/DateCalendar.stories.tsx b/src/stories/Library/date-calendar/DateCalendar.stories.tsx
deleted file mode 100644
index c0a7006d6..000000000
--- a/src/stories/Library/date-calendar/DateCalendar.stories.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ComponentStory, ComponentMeta } from "@storybook/react";
-import { withDesign } from "storybook-addon-designs";
-import DateCalendar from "./DateCalendar";
-
-export default {
- title: "Library / DateCalendar",
- component: DateCalendar,
- decorators: [withDesign],
- argTypes: {},
- parameters: {
- design: {
- type: "figma",
- url: "https://www.figma.com/file/Zx9GrkFA3l4ISvyZD2q0Qi/Designsystem?type=design&node-id=7605%3A54868&mode=design&t=MoXpQuI4TAXRxRDe-1",
- },
- layout: "padded",
- },
-} as ComponentMeta;
-
-const Template: ComponentStory = () => ;
-
-export const Default = Template.bind({});
diff --git a/src/stories/Library/date-calendar/DateCalendar.tsx b/src/stories/Library/date-calendar/DateCalendar.tsx
deleted file mode 100644
index 1f3ebddd1..000000000
--- a/src/stories/Library/date-calendar/DateCalendar.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-// Import default styling
-import "flatpickr/dist/flatpickr.css";
-
-import flatpickr from "flatpickr";
-import { Instance } from "flatpickr/dist/types/instance";
-import { MutableRefObject, useCallback, useRef } from "react";
-import { BaseOptions } from "flatpickr/dist/types/options";
-
-const DateCalendar = () => {
- const picker = useRef() as MutableRefObject;
-
- const calendar = useCallback((node: Node | null) => {
- const options: Partial = {
- inline: true,
- animate: false,
- mode: "range",
- defaultDate: ["2024-01-01", "2024-01-10"],
- now: "2024-01-19",
- };
-
- if (node !== null) {
- picker.current = flatpickr(node, options);
- }
- }, []);
-
- // An input is required for flatpickr to work, but we don't want to show it in the story
- return (
-
- );
-};
-
-export default DateCalendar;
diff --git a/src/stories/Library/date-range/DateRange.stories.tsx b/src/stories/Library/date-range/DateRange.stories.tsx
new file mode 100644
index 000000000..3967f6167
--- /dev/null
+++ b/src/stories/Library/date-range/DateRange.stories.tsx
@@ -0,0 +1,39 @@
+import { ComponentStory, ComponentMeta } from "@storybook/react";
+import { withDesign } from "storybook-addon-designs";
+import DateRange, { DateRangeProps } from "./DateRange";
+
+export default {
+ title: "Library / Date range",
+ component: DateRange,
+ decorators: [withDesign],
+ argTypes: {
+ open: {
+ name: "Open calendar",
+ defaultValue: false,
+ control: { type: "boolean" },
+ },
+ },
+ parameters: {
+ design: {
+ type: "figma",
+ url: "https://www.figma.com/file/Zx9GrkFA3l4ISvyZD2q0Qi/Designsystem?type=design&node-id=7605%3A54868&mode=design&t=MoXpQuI4TAXRxRDe-1",
+ },
+ layout: "padded",
+ },
+} as ComponentMeta;
+
+const Template: ComponentStory = (args: DateRangeProps) => (
+
+);
+
+export const Closed = Template.bind({});
+
+export const Open = Template.bind({});
+Open.args = {
+ open: true,
+};
+
+export const Filter = Template.bind({});
+Filter.args = {
+ modifiers: ["filter"],
+};
diff --git a/src/stories/Library/date-range/DateRange.tsx b/src/stories/Library/date-range/DateRange.tsx
new file mode 100644
index 000000000..d59b776a6
--- /dev/null
+++ b/src/stories/Library/date-range/DateRange.tsx
@@ -0,0 +1,94 @@
+/* eslint-disable import/no-extraneous-dependencies */
+// Import default styling
+import "flatpickr/dist/flatpickr.css";
+
+import React, { useEffect } from "react";
+import { Helmet } from "react-helmet";
+import { BaseOptions } from "flatpickr/dist/types/options";
+import clsx from "clsx";
+
+declare global {
+ interface Window {
+ // Allow attachment of global Flatpickr configuration options.
+ flatpickrOptions: Partial;
+ }
+}
+
+type Modifiers = "filter";
+
+export type DateRangeProps = {
+ open?: boolean;
+ modifiers?: Modifiers[];
+};
+
+const DateRange: React.FC = ({ open, modifiers }) => {
+ // Use a set of static values for testing.
+ const now = "2024-01-19";
+ const from = "2024-01-01";
+ const to = "2024-01-10";
+
+ useEffect(() => {
+ window.flatpickrOptions = {
+ now,
+ animate: false,
+ altInput: true,
+ altFormat: "j. M Y",
+ // For whatever reason we cannot load the Danish translation properly
+ // in Storybook.
+ // locale: da
+ locale: {
+ firstDayOfWeek: 1,
+ },
+ };
+ require("./date-range");
+ require("./init-date-range");
+ }, []);
+
+ useEffect(() => {
+ if (open) {
+ // Wait a bit for the calendar to load. Then click the input field to
+ // open it.
+ window.setTimeout(() => {
+ const elements = document.querySelectorAll(
+ ".date-range__input"
+ ) as NodeListOf;
+
+ elements.forEach((e) => {
+ e.click();
+ });
+ }, 250);
+ }
+ }, [open]);
+
+ const classNames = clsx(
+ "date-range",
+ modifiers?.map((modifier) => `date-range--${modifier}`)
+ );
+
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default DateRange;
diff --git a/src/stories/Library/date-range/date-range.js b/src/stories/Library/date-range/date-range.js
new file mode 100644
index 000000000..e6ce12ffa
--- /dev/null
+++ b/src/stories/Library/date-range/date-range.js
@@ -0,0 +1,41 @@
+/* global flatpickr */
+window.DateRange = {
+ init(element, config) {
+ const dateRange = element.querySelectorAll(".date-range");
+
+ dateRange.forEach((e) => {
+ const dateFrom = e.querySelector(".date-range__from");
+ const dateTo = e.querySelector(".date-range__to");
+ const fromToElements = !!dateFrom && !!dateTo;
+
+ const flatPickrConfig = {
+ ...{
+ mode: "range",
+ defaultDate: fromToElements ? [dateFrom.value, dateTo.value] : [],
+ onClose: (selectedDates) => {
+ if (!fromToElements) {
+ return;
+ }
+
+ const formattedDates = selectedDates.map((date) => {
+ // The en-CA date format uses the YYYY-MM-DD date format used by
+ // date type input elements.
+ return date.toLocaleDateString("en-CA", {
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ });
+ });
+ [dateFrom.value, dateTo.value] = formattedDates;
+ // Dispatch a change event to allow others to react to the change.
+ // This will not happen by default.
+ dateFrom.dispatchEvent(new Event("change"));
+ },
+ },
+ ...config,
+ };
+
+ flatpickr(e.querySelector(".date-range__input"), flatPickrConfig);
+ });
+ },
+};
diff --git a/src/stories/Library/date-range/date-range.scss b/src/stories/Library/date-range/date-range.scss
new file mode 100644
index 000000000..052202dd0
--- /dev/null
+++ b/src/stories/Library/date-range/date-range.scss
@@ -0,0 +1,32 @@
+.date-range {
+ input {
+ border: 1px solid $color__global-tertiary-1;
+ box-sizing: border-box;
+ background-color: $color__global-primary;
+ min-width: 100%;
+ height: 50px;
+ padding: 0 10px;
+ color: $color__text-secondary-gray;
+ @include typography($typo__button);
+ }
+}
+
+.date-range__input {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ margin-bottom: $s-lg;
+}
+
+.date-range__values {
+ // If the date range uses individual form inputs for managing from and to
+ // dates then hide these values in favour of the input field.
+ display: none;
+}
+
+.date-range--filter {
+ input {
+ border-color: $color__global-black;
+ margin-bottom: 0;
+ }
+}
diff --git a/src/stories/Library/date-calendar/date-calendar.scss b/src/stories/Library/date-range/flatpickr.scss
similarity index 100%
rename from src/stories/Library/date-calendar/date-calendar.scss
rename to src/stories/Library/date-range/flatpickr.scss
diff --git a/src/stories/Library/date-range/init-date-range.js b/src/stories/Library/date-range/init-date-range.js
new file mode 100644
index 000000000..5d53923b5
--- /dev/null
+++ b/src/stories/Library/date-range/init-date-range.js
@@ -0,0 +1,3 @@
+window.addEventListener("load", () => {
+ window.DateRange.init(document, window.flatpickrOptions);
+});