From 2cad21afb1aa34e829deca2e3e714bfdcc74b867 Mon Sep 17 00:00:00 2001 From: Diana Petcheva Date: Tue, 2 Sep 2025 15:10:53 +0300 Subject: [PATCH 1/2] docs(ui5-dynamic-date-range): add custom option sample --- packages/main/src/bundle.esm.ts | 1 + .../dynamic-date-range-options/TodayFromTo.ts | 96 +++++++++++++++++++ .../TodayFromToTemplate.tsx | 55 +++++++++++ .../main/test/pages/DynamicDateRange.html | 2 +- .../main/DynamicDateRange.mdx | 6 +- .../CustomOption/CustomOption.md | 4 + .../CustomOption/TodayFromTo.ts | 96 +++++++++++++++++++ .../CustomOption/TodayFromToTemplate.tsx | 55 +++++++++++ .../DynamicDateRange/CustomOption/main.js | 6 ++ .../DynamicDateRange/CustomOption/sample.html | 22 +++++ 10 files changed, 341 insertions(+), 2 deletions(-) create mode 100644 packages/main/src/dynamic-date-range-options/TodayFromTo.ts create mode 100644 packages/main/src/dynamic-date-range-options/TodayFromToTemplate.tsx create mode 100644 packages/website/docs/_samples/main/DynamicDateRange/CustomOption/CustomOption.md create mode 100644 packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromTo.ts create mode 100644 packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromToTemplate.tsx create mode 100644 packages/website/docs/_samples/main/DynamicDateRange/CustomOption/main.js create mode 100644 packages/website/docs/_samples/main/DynamicDateRange/CustomOption/sample.html diff --git a/packages/main/src/bundle.esm.ts b/packages/main/src/bundle.esm.ts index 7b3688bd8d82..cda14faafb94 100644 --- a/packages/main/src/bundle.esm.ts +++ b/packages/main/src/bundle.esm.ts @@ -52,6 +52,7 @@ import DateTimePicker from "./DateTimePicker.js"; import Dialog from "./Dialog.js"; import DynamicDateRange from "./DynamicDateRange.js"; import Today from "./dynamic-date-range-options/Today.js"; +import TodayFromTo from "./dynamic-date-range-options/TodayFromTo.js"; import Yesterday from "./dynamic-date-range-options/Yesterday.js"; import Tomorrow from "./dynamic-date-range-options/Tomorrow.js"; import SingleDate from "./dynamic-date-range-options/SingleDate.js"; diff --git a/packages/main/src/dynamic-date-range-options/TodayFromTo.ts b/packages/main/src/dynamic-date-range-options/TodayFromTo.ts new file mode 100644 index 000000000000..a0cbc5175794 --- /dev/null +++ b/packages/main/src/dynamic-date-range-options/TodayFromTo.ts @@ -0,0 +1,96 @@ +import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; +import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; +import type { DynamicDateRangeValue, IDynamicDateRangeOption } from "../DynamicDateRange.js"; +import DynamicDateRange from "../DynamicDateRange.js"; +import TodayFromToTemplate from "./TodayFromToTemplate.js"; +import type { JsxTemplate } from "@ui5/webcomponents-base/dist/index.js"; + +/** + * @class + * @constructor + * @public + */ +class TodayFromToDays implements IDynamicDateRangeOption { + template: JsxTemplate; + + constructor() { + this.template = TodayFromToTemplate; + } + + parse(value: string): DynamicDateRangeValue { + const match = value.match(/Today -(\d+)\/\+(\d+) days/); + + if (match) { + const x = parseInt(match[1]); + const y = parseInt(match[2]); + return { operator: this.operator, values: [x, y] }; + } + + return { operator: this.operator, values: [0, 0] }; + } + + format(value: DynamicDateRangeValue) { + if (!value.values || value.values.length !== 2) { + value.values = [0, 0]; + } + + // Format values in a date range + if (value.values[0] instanceof Date) { + const dateValues = value.values as Array; + return this.getFormat().format(dateValues); + } + + // Format values in the pattern "Today -X/+Y days" + const x = value.values[0]; + const y = value.values[1] as number; + + return `Today -${x}/+${y} days`; + } + + toDates(value: DynamicDateRangeValue): Array { + if (!value.values || value.values.length !== 2) { + return []; + } + const x = value.values[0] as number; + const y = value.values[1] as number; + const today = UI5Date.getInstance(); + + const startDate = x ? UI5Date.getInstance(today.getFullYear(), today.getMonth(), today.getDate() - x) : UI5Date.getInstance(); + const endDate = y ? UI5Date.getInstance(today.getFullYear(), today.getMonth(), today.getDate() + y) : UI5Date.getInstance(); + + startDate?.setHours(0, 0, 0, 0); + endDate?.setHours(23, 59, 59, 999); + + return [startDate, endDate]; + } + + isValidString(value: string): boolean { + const pattern = this.text.replace(/[.*+?^${}()|[\]\\/-]/g, "\\$&").replace("X", "\\d+").replace("Y", "\\d+"); + const regex = new RegExp(`^${pattern}$`, "i"); + return regex.test(value); + } + + get text() { + return "Today -X/+Y days"; + } + + get operator() { + return "TODAYFROMTO"; + } + + get icon() { + return "check-availability"; + } + + getFormat(): DateFormat { + return DateFormat.getDateInstance({ + strictParsing: true, + interval: true, + intervalDelimiter: " - ", + }); + } +} + +DynamicDateRange.register("TODAYFROMTO", TodayFromToDays); + +export default TodayFromToDays; diff --git a/packages/main/src/dynamic-date-range-options/TodayFromToTemplate.tsx b/packages/main/src/dynamic-date-range-options/TodayFromToTemplate.tsx new file mode 100644 index 000000000000..5feb2f6947fe --- /dev/null +++ b/packages/main/src/dynamic-date-range-options/TodayFromToTemplate.tsx @@ -0,0 +1,55 @@ +import type DynamicDateRange from "../DynamicDateRange.js"; +import Label from "../Label.js"; +import StepInput from "../StepInput.js"; + +export default function TodayFromToTemplate(this: DynamicDateRange) { + const currentValues = this.currentValue?.values; + + const xValue = currentValues ? currentValues[0] as number : 0; + const yValue = currentValues ? currentValues[1] as number : 0; + + const handleNumberChange = (e: CustomEvent) => { + const target = e.target as StepInput; + const input = target.id; + const newValue = Number(target.value); + + // Get current values, defaulting to existing values or 0 + let newXValue = xValue; + let newYValue = yValue; + + // Update the appropriate value based on which input changed + if (input === "x-input") { + newXValue = newValue; + } else if (input === "y-input") { + newYValue = newValue; + } + + // Update currentValue with both values + this.currentValue = { + operator: "TODAYFROMTO", + values: [newXValue, newYValue], + }; + }; + return ( +
+
+ + + + +
+
+ ); +} diff --git a/packages/main/test/pages/DynamicDateRange.html b/packages/main/test/pages/DynamicDateRange.html index 91bb340c456c..7f11a5945fa6 100644 --- a/packages/main/test/pages/DynamicDateRange.html +++ b/packages/main/test/pages/DynamicDateRange.html @@ -26,7 +26,7 @@

Basic Options

diff --git a/packages/website/docs/_components_pages/main/DynamicDateRange.mdx b/packages/website/docs/_components_pages/main/DynamicDateRange.mdx index 338287cdc0e5..3a22f3619edc 100644 --- a/packages/website/docs/_components_pages/main/DynamicDateRange.mdx +++ b/packages/website/docs/_components_pages/main/DynamicDateRange.mdx @@ -3,6 +3,7 @@ sidebar_class_name: newComponentBadge --- import Basic from "../../_samples/main/DynamicDateRange/Basic/Basic.md"; +import DynamicDateRangeCustomSample from "../../_samples/main/DynamicDateRange/CustomOption/CustomOption.md"; import DynamicDateRangeValueSample from "../../_samples/main/DynamicDateRange/DynamicDateRangeValueSample/DynamicDateRangeValueSample.md"; <%COMPONENT_OVERVIEW%> @@ -15,4 +16,7 @@ import DynamicDateRangeValueSample from "../../_samples/main/DynamicDateRange/Dy ## More Samples ### DynamicDateRangeValueSample - \ No newline at end of file + + +### CustomOption + \ No newline at end of file diff --git a/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/CustomOption.md b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/CustomOption.md new file mode 100644 index 000000000000..17798ecc59ab --- /dev/null +++ b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/CustomOption.md @@ -0,0 +1,4 @@ +import html from '!!raw-loader!./sample.html'; +import js from '!!raw-loader!./main.js'; + + diff --git a/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromTo.ts b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromTo.ts new file mode 100644 index 000000000000..669244a75363 --- /dev/null +++ b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromTo.ts @@ -0,0 +1,96 @@ +import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; +import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; +import type { DynamicDateRangeValue, IDynamicDateRangeOption } from "@ui5/webcomponents/dist/DynamicDateRange.js"; +import DynamicDateRange from "@ui5/webcomponents/dist/DynamicDateRange.js"; +import TodayFromToTemplate from "./TodayFromToTemplate.js"; +import type { JsxTemplate } from "@ui5/webcomponents-base/dist/index.js"; + +/** + * @class + * @constructor + * @public + */ +class TodayFromToDays implements IDynamicDateRangeOption { + template: JsxTemplate; + + constructor() { + this.template = TodayFromToTemplate; + } + + parse(value: string): DynamicDateRangeValue { + const match = value.match(/Today -(\d+)\/\+(\d+) days/); + + if (match) { + const x = parseInt(match[1]); + const y = parseInt(match[2]); + return { operator: this.operator, values: [x, y] }; + } + + return { operator: this.operator, values: [0, 0] }; + } + + format(value: DynamicDateRangeValue) { + if (!value.values || value.values.length !== 2) { + value.values = [0, 0]; + } + + // Format values in a date range + if (value.values[0] instanceof Date) { + const dateValues = value.values as Array; + return this.getFormat().format(dateValues); + } + + // Format values in the pattern "Today -X/+Y days" + const x = value.values[0]; + const y = value.values[1] as number; + + return `Today -${x}/+${y} days`; + } + + toDates(value: DynamicDateRangeValue): Array { + if (!value.values || value.values.length !== 2) { + return []; + } + const x = value.values[0] as number; + const y = value.values[1] as number; + const today = UI5Date.getInstance(); + + const startDate = x ? UI5Date.getInstance(today.getFullYear(), today.getMonth(), today.getDate() - x) : UI5Date.getInstance(); + const endDate = y ? UI5Date.getInstance(today.getFullYear(), today.getMonth(), today.getDate() + y) : UI5Date.getInstance(); + + startDate?.setHours(0, 0, 0, 0); + endDate?.setHours(23, 59, 59, 999); + + return [startDate, endDate]; + } + + isValidString(value: string): boolean { + const pattern = this.text.replace(/[.*+?^${}()|[\]\\/-]/g, "\\$&").replace("X", "\\d+").replace("Y", "\\d+"); + const regex = new RegExp(`^${pattern}$`, "i"); + return regex.test(value); + } + + get text() { + return "Today -X/+Y days"; + } + + get operator() { + return "TODAYFROMTO"; + } + + get icon() { + return "check-availability"; + } + + getFormat(): DateFormat { + return DateFormat.getDateInstance({ + strictParsing: true, + interval: true, + intervalDelimiter: " - ", + }); + } +} + +DynamicDateRange.register("TODAYFROMTO", TodayFromToDays); + +export default TodayFromToDays; diff --git a/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromToTemplate.tsx b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromToTemplate.tsx new file mode 100644 index 000000000000..914a2e0d5956 --- /dev/null +++ b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/TodayFromToTemplate.tsx @@ -0,0 +1,55 @@ +import type DynamicDateRange from "@ui5/webcomponents/dist/DynamicDateRange.js"; +import Label from "@ui5/webcomponents/dist/Label.js"; +import StepInput from "@ui5/webcomponents/dist/StepInput.js"; + +export default function TodayFromToTemplate(this: DynamicDateRange) { + const currentValues = this.currentValue?.values; + + const xValue = currentValues ? currentValues[0] as number : 0; + const yValue = currentValues ? currentValues[1] as number : 0; + + const handleNumberChange = (e: CustomEvent) => { + const target = e.target as StepInput; + const input = target.id; + const newValue = Number(target.value); + + // Get current values, defaulting to existing values or 0 + let newXValue = xValue; + let newYValue = yValue; + + // Update the appropriate value based on which input changed + if (input === "x-input") { + newXValue = newValue; + } else if (input === "y-input") { + newYValue = newValue; + } + + // Update currentValue with both values + this.currentValue = { + operator: "TODAYFROMTO", + values: [newXValue, newYValue], + }; + }; + return ( +
+
+ + + + +
+
+ ); +} diff --git a/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/main.js b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/main.js new file mode 100644 index 000000000000..a1cd6e0f45d5 --- /dev/null +++ b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/main.js @@ -0,0 +1,6 @@ +import "@ui5/webcomponents/dist/DynamicDateRange.js"; +import "@ui5/webcomponents/dist/dynamic-date-range-options/Today.js"; +import "@ui5/webcomponents/dist/dynamic-date-range-options/SingleDate.js"; +import "@ui5/webcomponents/dist/dynamic-date-range-options/DateRange.js"; +import "./TodayFromTo.js"; +import "./TodayFromToTemplate.tsx"; \ No newline at end of file diff --git a/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/sample.html b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/sample.html new file mode 100644 index 000000000000..e0597d307c86 --- /dev/null +++ b/packages/website/docs/_samples/main/DynamicDateRange/CustomOption/sample.html @@ -0,0 +1,22 @@ + + + + + + + + Dynamic Date Range Sample + + + + + + + + + + + + + \ No newline at end of file From 30bbbd25a15e6124e9f55d2f62889667e68fd186 Mon Sep 17 00:00:00 2001 From: Diana Petcheva Date: Tue, 2 Sep 2025 17:15:45 +0300 Subject: [PATCH 2/2] docs: correct option name --- .../website/docs/_components_pages/main/DynamicDateRange.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/docs/_components_pages/main/DynamicDateRange.mdx b/packages/website/docs/_components_pages/main/DynamicDateRange.mdx index 3a22f3619edc..99e14bdff5a1 100644 --- a/packages/website/docs/_components_pages/main/DynamicDateRange.mdx +++ b/packages/website/docs/_components_pages/main/DynamicDateRange.mdx @@ -3,7 +3,7 @@ sidebar_class_name: newComponentBadge --- import Basic from "../../_samples/main/DynamicDateRange/Basic/Basic.md"; -import DynamicDateRangeCustomSample from "../../_samples/main/DynamicDateRange/CustomOption/CustomOption.md"; +import CustomOption from "../../_samples/main/DynamicDateRange/CustomOption/CustomOption.md"; import DynamicDateRangeValueSample from "../../_samples/main/DynamicDateRange/DynamicDateRangeValueSample/DynamicDateRangeValueSample.md"; <%COMPONENT_OVERVIEW%>