Skip to content

Commit 89bc317

Browse files
PatrikH-01Patrik Hrabcaktyler-dane
authored andcommitted
feat(web): Improve accessibility and styles for event form when editing with keyboard (#1088)
* feature(web): Added :hover and :focus effects to - StyledTitle, PrioritySection, DateControlSection, RecurrenceSection in EventForm * feature(web): Added :hover and :focus effects to: RecurrenceSection, StyledDescription * feature(web): Added :focus and :hover effects to EventForm components * feature(web): Added scrollbar styling for StyledDescription * feature(web): removed unnecessary underlineColor prop, replaced hardcoded colors with theme colors, changed scroll cursor to default * refactor(core): remove hslToSpaceFormat function from color utilities This was adding maintenance burden and wasn't adding any value, as the DatePicker is currenly falling back to the `grayGradient` from `getGradient()` anyway. Better approach would be to refactor that function so that it renders a different gradient based on the priority as expected. --------- Co-authored-by: Patrik Hrabcak <[email protected]> Co-authored-by: Tyler Dane <[email protected]>
1 parent 60a9b4a commit 89bc317

File tree

11 files changed

+128
-29
lines changed

11 files changed

+128
-29
lines changed

packages/web/src/components/ContextMenu/styled.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import styled from "styled-components";
2+
import { darken } from "@core/util/color.utils";
23

34
export const PriorityContainer = styled.div`
45
display: flex;
@@ -46,7 +47,19 @@ export const PriorityCircle = styled.div<{ color: string; selected: boolean }>`
4647
background-color: ${({ selected, color }) =>
4748
selected ? color : "transparent"};
4849
cursor: pointer;
49-
transition: all 0.2s ease-in-out;
50+
transition: ${({ theme }) => theme.transition.default};
51+
52+
&:hover {
53+
${({ selected, theme }) =>
54+
selected
55+
? `filter: brightness(85%);`
56+
: `background-color: ${theme.color.border.primary};`}
57+
}
58+
59+
&:focus {
60+
outline: none;
61+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
62+
}
5063
`;
5164

5265
export const MenuItem = styled.li`

packages/web/src/components/DatePicker/DatePicker.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import classNames from "classnames";
22
import React, { useEffect, useRef } from "react";
33
import ReactDatePicker, { ReactDatePickerProps } from "react-datepicker";
44
import "react-datepicker/dist/react-datepicker.css";
5-
import { isDark } from "@core/util/color.utils";
5+
import { darken, isDark } from "@core/util/color.utils";
66
import dayjs from "@core/util/date/dayjs";
77
import { theme } from "@web/common/styles/theme";
88
import {
@@ -16,6 +16,7 @@ import { Flex } from "@web/components/Flex";
1616
import { AlignItems, JustifyContent } from "@web/components/Flex/styled";
1717
import { StyledInput } from "@web/components/Input/styled";
1818
import { Text } from "@web/components/Text";
19+
import { Focusable } from "../Focusable/Focusable";
1920

2021
export interface Props extends ReactDatePickerProps {
2122
animationOnToggle?: boolean;
@@ -80,7 +81,14 @@ export const DatePicker: React.FC<Props> = ({
8081
view={view}
8182
/>
8283
)}
83-
customInput={<StyledInput bgColor={inputColor} />}
84+
customInput={
85+
<Focusable
86+
Component={StyledInput}
87+
underlineColor={darken(bgColor, -15)}
88+
bgColor={inputColor}
89+
withUnderline
90+
/>
91+
}
8492
dateFormat={"M-d-yyyy"}
8593
formatWeekDay={(day) => day[0]}
8694
open={isOpen}

packages/web/src/components/IconButton/styled.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,14 @@ export const StyledIconButton = styled.button<IconButtonProps>`
2828
display: flex;
2929
align-items: center;
3030
justify-content: center;
31-
transition:
32-
background-color 0.3s ease,
33-
transform 0.2s ease,
34-
border-color 0.2s ease;
31+
border-radius: ${({ theme }) => theme.shape.borderRadius};
32+
transition: ${({ theme }) => theme.transition.default};
3533
font-size: ${({ size = "medium" }) => sizeMap[size]}px;
3634
border: 2px solid transparent;
3735
3836
&:hover {
3937
transform: scale(1.05);
38+
background-color: ${({ theme }) => theme.color.border.primary};
4039
}
4140
4241
&:active {
@@ -49,6 +48,6 @@ export const StyledIconButton = styled.button<IconButtonProps>`
4948
}
5049
5150
&:focus-visible {
52-
border-color: ${({ theme }) => theme.color.border.primary};
51+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
5352
}
5453
`;

packages/web/src/components/Input/styled.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ export const StyledInput = styled.input<Props>`
88
background-color: ${({ bgColor }) => bgColor};
99
border: none;
1010
height: 34px;
11+
padding: 0 8px;
1112
font-size: ${({ theme }) => theme.text.size.l};
1213
outline: none;
1314
width: 100%;
15+
transition: ${({ theme }) => theme.transition.default};
1416
1517
::placeholder {
1618
color: ${({ theme }) => theme.color.text.darkPlaceholder};
1719
}
1820
1921
&:hover {
20-
filter: brightness(87%);
22+
background-color: ${({ theme }) => theme.color.border.primary};
2123
}
2224
`;

packages/web/src/views/Forms/EventForm/DateControlsSection/DateTimeSection/TimePicker/TimePicker.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import ReactSelect, { Props as RSProps } from "react-select";
33
import { Key } from "ts-key-enum";
44
import { SelectOption } from "@web/common/types/component.types";
55
import { Option_Time } from "@web/common/types/util.types";
6-
import { StyledDivider, StyledTimePicker } from "./styled";
6+
import { StyledTimePicker } from "./styled";
77

88
export interface Props extends Omit<RSProps, "onChange" | "value"> {
99
bgColor: string;
@@ -78,7 +78,6 @@ export const TimePicker = ({
7878
options={options}
7979
tabSelectsValue={false}
8080
/>
81-
{isMenuOpen && <StyledDivider width="calc(100% - 16px)" />}
8281
</StyledTimePicker>
8382
);
8483
};

packages/web/src/views/Forms/EventForm/DateControlsSection/DateTimeSection/TimePicker/styled.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,15 @@ export const StyledTimePicker = styled.div<Props>`
2828
&__control {
2929
border: none;
3030
${({ bgColor }) => bgColor && `background: ${bgColor}`};
31+
border-radius: ${({ theme }) => theme.shape.borderRadius};
3132
box-shadow: none;
32-
border-radius: 0;
33-
min-height: 100%;
33+
min-height: 38px;
34+
transition: ${({ theme }) => theme.transition.default};
3435
&:hover {
35-
filter: brightness(87%);
36+
filter: brightness(90%);
37+
}
38+
&--is-focused {
39+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
3640
}
3741
}
3842
&__value-container {
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import styled from "styled-components";
22
import { Flex } from "@web/components/Flex";
33

4-
export const StyledDateTimeFlex = styled(Flex)``;
4+
export const StyledDateTimeFlex = styled(Flex)`
5+
gap: ${({ theme }) => theme.spacing.s};
6+
`;
57

68
export const StyledTimeFlex = styled(Flex)``;

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/components/FreqSelect.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,24 @@ export const FreqSelect = ({
4242
theme={(selectTheme) => ({
4343
...selectTheme,
4444
borderRadius: 4,
45+
primary: theme.color.border.primaryDark, // focus border color
46+
primary25: darken(bgColor), // hover color
47+
primary50: brighten(bgColor), // selected color
4548
})}
4649
styles={{
47-
control: (baseStyles) => ({
50+
control: (baseStyles, state) => ({
4851
...baseStyles,
4952
backgroundColor: bgColor,
5053
borderRadius: theme.shape.borderRadius,
54+
border: "none",
55+
transition: theme.transition.default,
5156
fontSize,
57+
"&:hover": {
58+
filter: `brightness(95%)`,
59+
},
60+
boxShadow: state.isFocused
61+
? `0 0 0 2px ${theme.color.border.primaryDark}`
62+
: "none",
5263
}),
5364
indicatorSeparator: () => ({
5465
visibility: "hidden",

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/styled.ts

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,31 @@ export const StyledRepeatText = styled.span<{
2929
padding: 2px 8px;
3030
color: ${({ hasRepeat, theme }) =>
3131
hasRepeat ? theme.color.text.dark : theme.color.text.darkPlaceholder};
32+
transition: ${({ theme }) => theme.transition.default};
3233
3334
svg {
3435
color: inherit;
36+
margin-right: ${({ theme }) => theme.spacing.xs};
3537
}
3638
37-
&:focus,
3839
&:hover {
3940
cursor: pointer;
4041
color: ${({ theme }) => theme.color.text.dark};
41-
filter: brightness(110%);
42+
background-color: ${({ theme }) => theme.color.border.primary};
43+
}
44+
&:focus {
45+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
4246
}
4347
`;
4448

4549
export const StyledRepeatTextContainer = styled(Flex)`
4650
align-items: center;
4751
border-radius: ${({ theme }) => theme.shape.borderRadius};
48-
gap: 6px;
52+
gap: ${({ theme }) => theme.spacing.xs};
53+
border: 1px solid transparent;
4954
justify-content: center;
5055
margin-right: 8px;
51-
padding: 2px 0;
56+
padding: 2px 8px;
5257
color: ${({ theme }) => theme.color.text.darkPlaceholder};
5358
font-size: ${({ theme }) => theme.text.size.m};
5459
cursor: pointer;
@@ -62,10 +67,13 @@ export const StyledRepeatTextContainer = styled(Flex)`
6267
transition: inherit;
6368
}
6469
65-
&:focus,
6670
&:hover {
6771
color: ${({ theme }) => theme.color.text.dark};
68-
filter: brightness(110%);
72+
background-color: ${({ theme }) => theme.color.border.primary};
73+
}
74+
75+
&:focus {
76+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
6977
}
7078
`;
7179

@@ -76,8 +84,10 @@ export const StyledWeekDay = styled.button<{
7684
width: 24px;
7785
height: 24px;
7886
border-radius: 50%;
79-
border: 1px solid ${({ theme }) => theme.color.bg.primary};
87+
border: 1px solid ${({ theme }) => theme.color.border.primaryDark};
8088
background-color: ${({ bgColor }) => bgColor};
89+
transition: ${({ theme }) => theme.transition.default};
90+
8191
cursor: pointer;
8292
${({ selected, theme }) =>
8393
!selected &&
@@ -94,17 +104,24 @@ export const StyledWeekDay = styled.button<{
94104
background-color: ${darken(bgColor, 30)};
95105
color: ${theme.getContrastText(bgColor)};
96106
`}
107+
108+
&:focus {
109+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
110+
}
97111
`;
98112

99113
export const StyledIntervalInput = styled.input<{
100114
bgColor: string;
101115
}>`
102-
width: 32;
103-
height: 24px;
104-
border: 1px solid ${({ theme }) => theme.color.bg.primary};
116+
width: 32px;
117+
height: 38px;
118+
border: 1px solid transparent;
119+
text-align: center;
120+
border-radius: ${({ theme }) => theme.shape.borderRadius};
105121
padding: 0 4px;
106122
background-color: ${({ bgColor }) => bgColor};
107123
margin-left: ${({ theme }) => theme.spacing.xs};
124+
transition: ${({ theme }) => theme.transition.default};
108125
109126
/* Hide arrows/spinners */
110127
&::-webkit-outer-spin-button,
@@ -117,6 +134,14 @@ export const StyledIntervalInput = styled.input<{
117134
&[type="number"] {
118135
-moz-appearance: textfield;
119136
}
137+
138+
&:hover {
139+
filter: brightness(90%);
140+
}
141+
142+
&:focus {
143+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
144+
}
120145
`;
121146

122147
export const StyledCaretInputContainer = styled.div`
@@ -130,17 +155,23 @@ export const StyledCaretButton = styled.button`
130155
background: none;
131156
color: inherit;
132157
border: none;
158+
border-radius: ${({ theme }) => theme.shape.borderRadius};
133159
padding: 0;
134160
font: inherit;
135161
cursor: pointer;
136162
outline: inherit;
137-
height: 16px;
138-
width: 16px;
163+
height: 19px;
164+
width: 19px;
139165
display: flex;
140166
align-items: center;
141167
justify-content: center;
168+
transition: ${({ theme }) => theme.transition.default};
169+
142170
&:hover {
143171
background-color: ${({ theme }) => theme.color.bg.primary};
144172
color: ${({ theme }) => theme.color.text.light};
145173
}
174+
&:focus {
175+
box-shadow: 0 0 0 2px ${({ theme }) => theme.color.border.primaryDark};
176+
}
146177
`;

packages/web/src/views/Forms/EventForm/EventForm.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Priorities } from "@core/constants/core.constants";
1212
import { darken } from "@core/util/color.utils";
1313
import dayjs from "@core/util/date/dayjs";
1414
import { ID_EVENT_FORM } from "@web/common/constants/web.constants";
15+
import { theme } from "@web/common/styles/theme";
1516
import {
1617
colorByPriority,
1718
hoverColorByPriority,

0 commit comments

Comments
 (0)