diff --git a/changelog/unreleased/enhancement-replace-custom-datepicker-with-native-element b/changelog/unreleased/enhancement-replace-custom-datepicker-with-native-element
new file mode 100644
index 00000000000..97ed508bdd0
--- /dev/null
+++ b/changelog/unreleased/enhancement-replace-custom-datepicker-with-native-element
@@ -0,0 +1,7 @@
+Enhancement: Replace custom datepicker with native html element
+
+We've replaced the custom datepicker with a native html date input element.
+This change will improve the user experience and accessibility of the datepicker.
+
+https://github.com/owncloud/web/pull/11377
+https://github.com/owncloud/web/issues/11374
diff --git a/packages/design-system/package.json b/packages/design-system/package.json
index 6cf9a8b165c..ce63c7b3f31 100644
--- a/packages/design-system/package.json
+++ b/packages/design-system/package.json
@@ -103,7 +103,6 @@
"typescript": "5.5.3",
"url": "^0.11.3",
"url-loader": "^4.1.1",
- "v-calendar": "github:dschmidt/v-calendar#3ce6e3b8afd5491cb53ee811281d5fa8a45b044d",
"vue": "3.4.21",
"vue-inline-svg": "3.1.2",
"vue-loader": "^17.4.2",
@@ -129,11 +128,11 @@
"focus-trap-vue": "^4.0.1",
"postcss-import": "^16.0.0",
"tippy.js": "^6.3.7",
- "v-calendar": "github:dschmidt/v-calendar#3ce6e3b8afd5491cb53ee811281d5fa8a45b044d",
"vue": "3.4.21",
"vue-inline-svg": "3.1.2",
"vue-select": "^3.12.0",
- "webfontloader": "^1.6.28"
+ "webfontloader": "^1.6.28",
+ "luxon": "3.2.1"
},
"engines": {
"node": ">= 14.0.0",
diff --git a/packages/design-system/src/components/OcDatepicker/OcDatepicker.spec.ts b/packages/design-system/src/components/OcDatepicker/OcDatepicker.spec.ts
index 639187f1e3f..ae6e9549235 100644
--- a/packages/design-system/src/components/OcDatepicker/OcDatepicker.spec.ts
+++ b/packages/design-system/src/components/OcDatepicker/OcDatepicker.spec.ts
@@ -1,23 +1,41 @@
-import { defineComponent } from 'vue'
import Datepicker from './OcDatepicker.vue'
-import { mount } from 'web-test-helpers'
+import { ComponentProps, defaultPlugins, shallowMount } from 'web-test-helpers'
+import { DateTime } from 'luxon'
+import { nextTick } from 'vue'
-const DatePickerComponent = defineComponent({
- template: '
'
+describe('OcDatePicker', () => {
+ it('renders', () => {
+ const wrapper = getWrapper({ label: 'Datepicker label' })
+ expect(wrapper.html()).toMatchSnapshot()
+ })
+ it('sets the initial date correctly', async () => {
+ const wrapper = getWrapper({ label: 'Datepicker label', currentDate: DateTime.now() })
+ await nextTick()
+ const inputEl = wrapper.find('.oc-text-input').element as HTMLInputElement
+ expect(inputEl.value).toEqual(DateTime.now().toISODate())
+ })
+ it('sets the minimum date correctly', async () => {
+ const wrapper = getWrapper({ label: 'Datepicker label', minDate: DateTime.now() })
+ await nextTick()
+ const inputEl = wrapper.find('.oc-text-input')
+ expect(inputEl.attributes('min')).toEqual(DateTime.now().toISODate())
+ })
+ it('emits event on date change', async () => {
+ const wrapper = getWrapper({ label: 'Datepicker label' })
+ const inputEl = wrapper.find('.oc-text-input')
+ await inputEl.setValue(DateTime.now().toISODate())
+ expect(wrapper.emitted('dateChanged')).toBeTruthy()
+ })
})
-describe('OcDatePicker', () => {
- it('renders default scoped slot', () => {
- const slotDefault = ""
- const wrapper = mount(Datepicker, {
- slots: { default: slotDefault },
- props: { value: null },
- global: {
- renderStubDefaultSlot: true,
- stubs: { DatePicker: DatePickerComponent }
+function getWrapper(props: ComponentProps) {
+ return shallowMount(Datepicker, {
+ props,
+ global: {
+ plugins: [...defaultPlugins()],
+ stubs: {
+ OcTextInput: false
}
- })
-
- expect(wrapper.find('#default-slot').exists()).toBeTruthy()
+ }
})
-})
+}
diff --git a/packages/design-system/src/components/OcDatepicker/OcDatepicker.vue b/packages/design-system/src/components/OcDatepicker/OcDatepicker.vue
index e6bd8a3b239..e7cecc22afc 100644
--- a/packages/design-system/src/components/OcDatepicker/OcDatepicker.vue
+++ b/packages/design-system/src/components/OcDatepicker/OcDatepicker.vue
@@ -1,145 +1,113 @@
-
-
-
-
-
-
-
+
-
```js
-
-
-
- Open datepicker
-
-
-
-
+
```
diff --git a/packages/design-system/src/components/OcDatepicker/__snapshots__/OcDatepicker.spec.ts.snap b/packages/design-system/src/components/OcDatepicker/__snapshots__/OcDatepicker.spec.ts.snap
new file mode 100644
index 00000000000..606ae88f560
--- /dev/null
+++ b/packages/design-system/src/components/OcDatepicker/__snapshots__/OcDatepicker.spec.ts.snap
@@ -0,0 +1,14 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`OcDatePicker > renders 1`] = `
+"
+
+
+
+
+
+
+
+
+
"
+`;
diff --git a/packages/design-system/src/components/OcTextInput/OcTextInput.vue b/packages/design-system/src/components/OcTextInput/OcTextInput.vue
index c07a37ce4a1..bbbff38a19f 100644
--- a/packages/design-system/src/components/OcTextInput/OcTextInput.vue
+++ b/packages/design-system/src/components/OcTextInput/OcTextInput.vue
@@ -36,6 +36,7 @@
v-if="showClearButton"
:aria-label="clearButtonAccessibleLabelValue"
class="oc-pr-s oc-position-center-right oc-text-input-btn-clear"
+ :class="{ 'oc-mr-l': type === 'date' }"
appearance="raw"
@click="onClear"
>
diff --git a/packages/design-system/src/styles/theme/helper.scss b/packages/design-system/src/styles/theme/helper.scss
index 2bded768fde..dec68546488 100644
--- a/packages/design-system/src/styles/theme/helper.scss
+++ b/packages/design-system/src/styles/theme/helper.scss
@@ -114,7 +114,7 @@ hr {
}
// outline for visible focus (via tab)
-*:focus-visible:not(input[type=text]):not(input[type=textarea]):not(input[type=search]):not(input[type=password]):not(input[type=email]) {
+*:focus-visible:not(input[type=text]):not(input[type=textarea]):not(input[type=search]):not(input[type=password]):not(input[type=email]):not(input[type=date]) {
outline: 2px var(--oc-color-swatch-passive-contrast) solid;
outline-offset: 0;
box-shadow: 0 0 0 4px var(--oc-color-swatch-passive-default);
diff --git a/packages/web-app-files/src/components/Modals/DatePickerModal.vue b/packages/web-app-files/src/components/Modals/DatePickerModal.vue
new file mode 100644
index 00000000000..4ace3be2e6f
--- /dev/null
+++ b/packages/web-app-files/src/components/Modals/DatePickerModal.vue
@@ -0,0 +1,59 @@
+
+
+
+
+ {{ $gettext('Cancel') }}
+
+ {{ $gettext('Confirm') }}
+
+
+
+
+
diff --git a/packages/web-app-files/src/components/SideBar/Shares/Collaborators/EditDropdown.vue b/packages/web-app-files/src/components/SideBar/Shares/Collaborators/EditDropdown.vue
index cd2327d25c5..335bb069b46 100644
--- a/packages/web-app-files/src/components/SideBar/Shares/Collaborators/EditDropdown.vue
+++ b/packages/web-app-files/src/components/SideBar/Shares/Collaborators/EditDropdown.vue
@@ -20,43 +20,36 @@
padding-size="small"
>
-