-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DatePicker] Customize day headers #4605
Comments
It is possible using date-io adapter inheritance. Here is a guide https://next.material-ui-pickers.dev/guides/date-io-customization#override-date-logic You need to extend |
Do we have a demo for it? What about we add one? I have included the concern in mui/material-ui#20960. |
@dmtrKovalenko Unfortunately, it looks like the behavior for showing just one character for the weekday is hardcoded: https://github.com/mui-org/material-ui/blob/9b1f6f72b51a72910a5dff1b47b9d351629bda51/packages/material-ui-lab/src/DayPicker/PickersCalendar.tsx#L180 |
@tpeek Thanks for reporting the issue. What I have found during my investigation:
var date = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738));
console.log(new Intl.DateTimeFormat('fr-FR', { weekday: 'short' }).format(date)); // 'dim.' |
Hi! @oliviertassinari is this issue good to take? I would like to give it a try :) This would be my first contribution. |
@marthaerm Mind that this issue isn't straightforward. We recommend issues with the "good first issue" label to get started https://github.com/mui-org/material-ui/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22 |
Hi, is anyone working on this at the moment? If not, what is the intended approach right now? I'd like to work on it if you can guide me in the direction that you would want. |
@brorlarsnicklas Nobody working on it. I think that resolving this issue will involve internalizing |
@oliviertassinari oh, I see. Then it might be better for someone else to work with it hehe! :D |
@oliviertassinari any chance that you could somehow allow to overwrite this behavior? It's the only thing that's blocking us from updating to v5 |
If you're lazy to read through, just jump this code snippet to see a complete working snippet I encourage you to read the following...For anyone struggling to get this done as I did. I came to a hacky workaround to overcome this issue. Since the component is set in stone to always get the first character from the provided weekdays given by the date-io adapter https://github.com/mui-org/material-ui/blob/9b1f6f72b51a72910a5dff1b47b9d351629bda51/packages/material-ui-lab/src/DayPicker/PickersCalendar.tsx#L173-L182 Note
My hack to get it done: Array.prototype.charAt = function(index) {
return this[index];
}; Then by updating the used locale (or providing a custom locale if you need more customization) to override the moment.updateLocale('en-gb', {
// Default value from moment
// weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
// New value
weekdaysShort: [["Sun"], ["Mon"], ["Tue"], ["Wed"], ["Thu"], ["Fri"], ["Sat"]]
}); A complete working snippet can be found here https://codesandbox.io/s/nervous-pike-rv9sn?file=/src/App.js Note
|
Another approachAnother solution inspired by @dmtrKovalenko's comment above Simply, provide a custom DateAdapter with a little tweak to it to make it work with the current implementation of Mui DatePickers. // CustomDateAdapter.js
import DateIOAdapter from "@mui/lab/AdapterMoment";
export default function CustomAdapter(options) {
const adapter = new DateIOAdapter(options);
const constructDayObject = (day) => ({ charAt: () => day });
return {
...adapter,
getWeekdays() {
// Feel free to replace this with your custom value
// e.g const customWeekdays = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
const customWeekdays = adapter.getWeekdays();
return customWeekdays.map((day) => constructDayObject(day));
}
};
} // Your cool component
import React from "react";
import moment from "moment";
import StaticDatePicker from "@mui/lab/StaticDatePicker";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import CustomDateAdapter from "./CustomDateAdapter";
export default function index() {
return (
<LocalizationProvider dateAdapter={CustomDateAdapter}>
{/* This can be replaced by any other DatePicker component */}
<StaticDatePicker
openTo="day"
showToolbar={false}
displayStaticWrapperAs="desktop"
value={moment()}
onChange={() => {}}
renderInput={(params) => <input {...params} />}
/>
</LocalizationProvider>
);
} I prefer this solution over my previous one as it won't mess up the native objects as |
Beautiful hack, i implement another step to showing weekdays without UPPERCASE, much more elegant. import DateIOAdapter from "@mui/lab/AdapterMoment";
export default function CustomDateAdapter(options) {
const adapter = new DateIOAdapter(options);
const constructUpperObject = (text) => ({ toUpperCase: () => text });
const constructDayObject = (day) => ({ charAt: () => constructUpperObject(day) });
return {
...adapter,
getWeekdays() {
// Feel free to replace this with your custom value
// e.g const customWeekdays = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
const customWeekdays = adapter.getWeekdays();
return customWeekdays.map((day) => constructDayObject(day));
}
};
} |
Another solution inspired by @HossamHoussien comment for TypeScript. import AdapterDateFns from '@mui/lab/AdapterDateFns';
class CustomString extends String {
charAt(_: number): string {
return this.valueOf();
}
}
const weekDays = ['пн', 'вт', 'ср', 'чт', 'пт', 'сб', 'вс'];
const customWeekDays = weekDays.map((day) => new CustomString(day) as string);
export class DateAdapter extends AdapterDateFns {
getWeekdays = (): string[] => customWeekDays;
} This solution is safety for using with TypeScript and needs almost no casting. But it needs some changing in CSS to avoid toUppercase effect. |
Thanks @avs-git, that works well. You can avoid the toUppercase effect here too instead of messing with CSS, but it requires using class CustomString extends String {
charAt(_: number): any {
return {
toUpperCase: () => this.valueOf()
}
}
} |
So many hacks needed for something so small. So when the adapter/lib tells me a short weekDay is |
Hello, I've been trying to edit the headers as well by extending the adapter as suggested, however, this line prevents any edit as it always forces the picker to use the first character of the day name to uppercase mui-x/packages/x-date-pickers/src/CalendarPicker/DayPicker.tsx Lines 154 to 158 in 3f9bc69
I know this would be a breaking change, but I really think the |
Hey ghm-salvarado! Thank you for this work around, it does look smooth but when we run it in our app we get the following TypeError: As a clarification this occurs when we use:
I tried to remove the any prop, and the toUpperCase function as well and use avs-git solution as well:
But the same TypeError issue persists. Should also mention that I use: |
if someone else has this issue: my solution is to use a ref that goes from 0 - 7 modulo. const weekdayRef = useRef(0);
const dayOfWeekFormatter = (firstDayLetter: string) => {
const weekday = weekdayRef.current + 1;
weekdayRef.current = weekday % 7;
return <Box>{weekday}</Box>
}
// every time the component re-renders, the ref restarts from 0 to 7 |
@fernandoem88 Which version of |
How can I change color of day headers? using Slot props in datepicker component |
Hey @joaccocaballero, have you checked this playground? 🤔 |
I'm trying to customize the DatePicker designs as close as possible to my requirements. We are using 3 letters(mon - tue - wed...) to describe our week days but I can't see any option where I can customize the default headers(M - T - W...).
The text was updated successfully, but these errors were encountered: