@vygruppen/spor-react 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -21,9 +21,9 @@
21
21
  "@chakra-ui/theme-tools": "^2.0.12",
22
22
  "@internationalized/date": "^3.0.1",
23
23
  "@leile/lobo-t": "^1.0.5",
24
- "@vygruppen/spor-design-tokens": "latest",
25
- "@vygruppen/spor-icon-react": "latest",
26
- "@vygruppen/spor-loader": "latest",
24
+ "@vygruppen/spor-design-tokens": "*",
25
+ "@vygruppen/spor-icon-react": "*",
26
+ "@vygruppen/spor-loader": "*",
27
27
  "@emotion/react": "^11.10.4",
28
28
  "@emotion/styled": "^11.10.4",
29
29
  "framer-motion": ">6.0.0",
@@ -32,7 +32,9 @@ import { useCurrentLocale } from "./utils";
32
32
  type DateRangePickerProps = AriaDateRangePickerProps<DateValue> &
33
33
  Pick<BoxProps, "minHeight"> & {
34
34
  startLabel?: string;
35
+ startName?: string;
35
36
  endLabel?: string;
37
+ endName?: string;
36
38
  variant: ResponsiveValue<"simple" | "with-trigger">;
37
39
  };
38
40
  /**
@@ -41,12 +43,14 @@ type DateRangePickerProps = AriaDateRangePickerProps<DateValue> &
41
43
  * There are two versions of this component – a simple one, and one with a trigger button for showing the calendar. Use whatever fits your design.
42
44
  *
43
45
  * ```tsx
44
- * <DateRangePicker startLabel="From" endLabel="To" variant="simple" />
46
+ * <DateRangePicker startLabel="From" startName="from" endLabel="To" endName="to" variant="simple" />
45
47
  * ```
46
48
  */
47
49
  export function DateRangePicker({
48
50
  variant,
49
51
  minHeight,
52
+ startName,
53
+ endName,
50
54
  ...props
51
55
  }: DateRangePickerProps) {
52
56
  const formControlProps = useFormControlContext();
@@ -128,6 +132,7 @@ export function DateRangePicker({
128
132
  )}
129
133
  <DateField
130
134
  {...startFieldProps}
135
+ name={startName}
131
136
  label={props.startLabel}
132
137
  labelProps={labelProps}
133
138
  />
@@ -136,6 +141,7 @@ export function DateRangePicker({
136
141
  </Box>
137
142
  <DateField
138
143
  {...endFieldProps}
144
+ name={endName}
139
145
  label={props.endLabel}
140
146
  labelProps={labelProps}
141
147
  />
@@ -31,6 +31,7 @@ export const DateTimeSegment = ({ segment, state }: DateTimeSegmentProps) => {
31
31
  textAlign="end"
32
32
  outline="none"
33
33
  borderRadius="xs"
34
+ fontSize="mobile.md"
34
35
  color={
35
36
  segment.isPlaceholder
36
37
  ? "dimGrey"
@@ -124,7 +124,6 @@ export const TimePicker = ({
124
124
  variant="simple"
125
125
  width="fit-content"
126
126
  paddingX={2}
127
- paddingY={1}
128
127
  alignItems="center"
129
128
  justifyContent="space-between"
130
129
  gap={2}
@@ -0,0 +1,55 @@
1
+ import React from "react";
2
+ import { Flex, FlexProps } from "..";
3
+
4
+ type AttachedInputsProps = FlexProps;
5
+ /**
6
+ * Attaches several inputs together, so that they look like one input.
7
+ *
8
+ * ```tsx
9
+ * <AttachedInputs>
10
+ * <Input />
11
+ * <NativeSelect>
12
+ * <SelectItem />
13
+ * </NativeSelect>
14
+ * </AttachedInputs>
15
+ * ```
16
+ */
17
+ export const AttachedInputs = ({
18
+ flexDirection = "row",
19
+ ...rest
20
+ }: AttachedInputsProps) => {
21
+ const attachedStyles = {
22
+ horizontal: {
23
+ "> *:first-of-type:not(:last-of-type) [data-attachable]": {
24
+ borderEndRadius: 0,
25
+ },
26
+ "> *:not(:first-of-type):not(:last-of-type) [data-attachable]": {
27
+ borderRadius: 0,
28
+ },
29
+ "> *:not(:first-of-type):last-of-type [data-attachable]": {
30
+ borderStartRadius: 0,
31
+ },
32
+ },
33
+ vertical: {
34
+ "> *:first-of-type:not(:last-of-type) [data-attachable]": {
35
+ borderBottomRadius: 0,
36
+ },
37
+ "> *:not(:first-of-type):not(:last-of-type) [data-attachable]": {
38
+ borderRadius: 0,
39
+ },
40
+ "> *:not(:first-of-type):last-of-type [data-attachable]": {
41
+ borderTopRadius: 0,
42
+ },
43
+ },
44
+ };
45
+ const direction = flexDirection === "row" ? "horizontal" : "vertical";
46
+ return (
47
+ <Flex
48
+ role="group"
49
+ __css={attachedStyles[direction]}
50
+ display="flex"
51
+ flexDirection={flexDirection}
52
+ {...rest}
53
+ />
54
+ );
55
+ };
@@ -110,6 +110,7 @@ export const CardSelect = forwardRef<CardSelectProps, "button">(
110
110
  sx={styles.trigger}
111
111
  {...buttonProps}
112
112
  width={width}
113
+ data-attachable
113
114
  >
114
115
  <Flex gap={1.5} alignItems="center">
115
116
  {icon}
@@ -0,0 +1,52 @@
1
+ import React from "react";
2
+ import {
3
+ BoxProps,
4
+ InfoSelect,
5
+ SelectItem,
6
+ createTexts,
7
+ useTranslation,
8
+ } from "..";
9
+
10
+ import { getSupportedCallingCodes } from "awesome-phonenumber";
11
+
12
+ const callingCodes = getSupportedCallingCodes()
13
+ .sort((a, b) => Number(a) - Number(b))
14
+ .map((code) => ({
15
+ key: `+${code}`,
16
+ value: `+${code}`,
17
+ }))
18
+ .filter((code) => code.key !== "+47"); // We're adding Norway to the top
19
+ callingCodes.unshift({ key: "+47", value: "+47" }); // Norway
20
+
21
+ type CountryCodeSelectProps = {
22
+ value: string;
23
+ onChange: (value: string | number) => void;
24
+ name: string;
25
+ width?: BoxProps["width"];
26
+ height?: BoxProps["height"];
27
+ };
28
+ export const CountryCodeSelect = (props: CountryCodeSelectProps) => {
29
+ const { t } = useTranslation();
30
+
31
+ return (
32
+ <InfoSelect
33
+ label={t(texts.countryCode)}
34
+ isLabelSrOnly={true}
35
+ items={callingCodes as any}
36
+ {...props}
37
+ >
38
+ {(item) => <SelectItem key={item.key}>{item.key}</SelectItem>}
39
+ </InfoSelect>
40
+ );
41
+ };
42
+
43
+ export default CountryCodeSelect;
44
+
45
+ const texts = createTexts({
46
+ countryCode: {
47
+ nb: "Landkode",
48
+ nn: "Landskode",
49
+ en: "Country code",
50
+ sv: "Landskod",
51
+ },
52
+ });
@@ -1,7 +1,7 @@
1
1
  import { Box, BoxProps, useFormControlContext } from "@chakra-ui/react";
2
2
  import React from "react";
3
3
 
4
- export type FormErrorMessageProps = {
4
+ export type FormErrorMessageProps = BoxProps & {
5
5
  /**
6
6
  * The error message itself.
7
7
  */
@@ -32,7 +32,10 @@ export type FormErrorMessageProps = {
32
32
  *
33
33
  * @see https://spor.vy.no/komponenter/skjemaelementer
34
34
  */
35
- export const FormErrorMessage = ({ children }: FormErrorMessageProps) => {
35
+ export const FormErrorMessage = ({
36
+ children,
37
+ ...boxProps
38
+ }: FormErrorMessageProps) => {
36
39
  const formControlContext = useFormControlContext();
37
40
  if (!formControlContext) {
38
41
  throw new Error(
@@ -60,6 +63,7 @@ export const FormErrorMessage = ({ children }: FormErrorMessageProps) => {
60
63
  zIndex="popover"
61
64
  maxWidth="50ch"
62
65
  {...errorMessageProps}
66
+ {...boxProps}
63
67
  >
64
68
  <Arrow position="absolute" top="-0.25em" left="1em" />
65
69
  {children}
@@ -2,6 +2,7 @@ import {
2
2
  Box,
3
3
  chakra,
4
4
  ResponsiveValue,
5
+ useFormControlProps,
5
6
  useMultiStyleConfig,
6
7
  } from "@chakra-ui/react";
7
8
  import {
@@ -15,7 +16,7 @@ import { createTexts, useTranslation } from "../";
15
16
  import { ListBox } from "./ListBox";
16
17
  import { Popover } from "./Popover";
17
18
 
18
- type InfoSelectProps = {
19
+ type InfoSelectProps<T> = {
19
20
  /**
20
21
  * Either a render function accepting an item, and returning a <SelectItem />,
21
22
  * or a list of <SelectItem />s.
@@ -43,7 +44,7 @@ type InfoSelectProps = {
43
44
  * </Select>
44
45
  * ```
45
46
  **/
46
- children: any;
47
+ children: React.ReactNode | ((item: T) => React.ReactNode);
47
48
  /**
48
49
  * The items to render
49
50
  *
@@ -57,7 +58,7 @@ type InfoSelectProps = {
57
58
  * </Select>
58
59
  * ```
59
60
  */
60
- items: any[];
61
+ items?: T[];
61
62
  /** Callback for when something is selected */
62
63
  onChange?: (value: string | number) => void;
63
64
  value?: string | number;
@@ -74,6 +75,12 @@ type InfoSelectProps = {
74
75
  onOpenChange?: (isOpen: boolean) => void;
75
76
  /** The label describing the choice */
76
77
  label: string;
78
+ /** Hide the label visually
79
+ *
80
+ * Should be used sparingly, as it makes the component less accessible.
81
+ * Useful for the label is obvious, like a phone number country code select.
82
+ */
83
+ isLabelSrOnly?: boolean;
77
84
  /** The name of the select element */
78
85
  name?: string;
79
86
  /**
@@ -87,6 +94,11 @@ type InfoSelectProps = {
87
94
  * Defaults to the width of the selected content
88
95
  */
89
96
  width?: ResponsiveValue<string | number>;
97
+ /** The height of the select box.
98
+ *
99
+ * Defaults to "auto"
100
+ */
101
+ height?: ResponsiveValue<string | number>;
90
102
  isDisabled?: boolean;
91
103
  /** A list of disabled keys.
92
104
  *
@@ -99,6 +111,8 @@ type InfoSelectProps = {
99
111
  * ```
100
112
  **/
101
113
  disabledKeys?: string[];
114
+ /** Whether or not the input is invalid */
115
+ "aria-invalid"?: boolean;
102
116
  };
103
117
  /**
104
118
  * A styled select component.
@@ -135,21 +149,23 @@ type InfoSelectProps = {
135
149
  *
136
150
  * @see https://spor.vy.no/komponenter/info-select
137
151
  */
138
- export const InfoSelect = ({
152
+ export function InfoSelect<T extends { key: string }>({
139
153
  placeholder,
140
154
  width = "100%",
155
+ height = "auto",
141
156
  onChange,
142
157
  value,
158
+ isLabelSrOnly,
143
159
  defaultValue,
144
160
  ...props
145
- }: InfoSelectProps) => {
161
+ }: InfoSelectProps<T>) {
146
162
  const renamedProps = {
147
163
  onSelectionChange: onChange,
148
164
  selectedKey: value,
149
165
  defaultSelectedKey: defaultValue,
150
166
  ...props,
151
167
  };
152
- const state = useSelectState(renamedProps);
168
+ const state = useSelectState(renamedProps as any);
153
169
  const triggerRef = useRef<HTMLButtonElement>(null);
154
170
  const { labelProps, triggerProps, valueProps, menuProps } = useSelect(
155
171
  renamedProps,
@@ -157,9 +173,13 @@ export const InfoSelect = ({
157
173
  triggerRef
158
174
  );
159
175
 
160
- const styles = useMultiStyleConfig("InfoSelect", { isOpen: state.isOpen });
176
+ const styles = useMultiStyleConfig("InfoSelect", {
177
+ isOpen: state.isOpen,
178
+ isLabelSrOnly,
179
+ });
161
180
  const { buttonProps } = useButton(triggerProps, triggerRef);
162
181
  const { t } = useTranslation();
182
+ const formControl = useFormControlProps(props);
163
183
 
164
184
  return (
165
185
  <Box sx={styles.container}>
@@ -179,6 +199,10 @@ export const InfoSelect = ({
179
199
  sx={styles.button}
180
200
  {...buttonProps}
181
201
  width={width}
202
+ height={height}
203
+ data-attachable
204
+ aria-invalid={formControl.isInvalid}
205
+ aria-describedby={formControl["aria-describedby"]}
182
206
  >
183
207
  <Box {...valueProps}>
184
208
  {state.selectedItem
@@ -192,12 +216,16 @@ export const InfoSelect = ({
192
216
 
193
217
  {state.isOpen && (
194
218
  <Popover state={state} triggerRef={triggerRef}>
195
- <ListBox listBoxOptions={menuProps} state={state} borderBottomRadius="sm" />
219
+ <ListBox
220
+ listBoxOptions={menuProps}
221
+ state={state}
222
+ borderBottomRadius="sm"
223
+ />
196
224
  </Popover>
197
225
  )}
198
226
  </Box>
199
227
  );
200
- };
228
+ }
201
229
 
202
230
  const texts = createTexts({
203
231
  selectAnOption: {
@@ -1,11 +1,11 @@
1
1
  import {
2
- FormLabel,
3
- forwardRef,
4
2
  Input as ChakraInput,
3
+ InputProps as ChakraInputProps,
4
+ FormLabel,
5
5
  InputGroup,
6
6
  InputLeftElement,
7
- InputProps as ChakraInputProps,
8
7
  InputRightElement,
8
+ forwardRef,
9
9
  useFormControlContext,
10
10
  } from "@chakra-ui/react";
11
11
  import React, { useId } from "react";
@@ -42,8 +42,9 @@ export const Input = forwardRef<InputProps, "input">(
42
42
  <InputGroup position="relative">
43
43
  {leftIcon && <InputLeftElement>{leftIcon}</InputLeftElement>}
44
44
  <ChakraInput
45
- pl={leftIcon ? 7 : undefined}
46
- pr={rightIcon ? 7 : undefined}
45
+ data-attachable
46
+ paddingLeft={leftIcon ? 7 : undefined}
47
+ paddingRight={rightIcon ? 7 : undefined}
47
48
  {...props}
48
49
  id={inputId}
49
50
  ref={ref}
@@ -30,7 +30,12 @@ export const NativeSelect = forwardRef<NativeSelectProps, "select">(
30
30
  const styles = useMultiStyleConfig("Select", props);
31
31
  return (
32
32
  <FormControl>
33
- <ChakraSelect {...props} rootProps={{ __css: styles.root }} ref={ref} />
33
+ <ChakraSelect
34
+ data-attachable
35
+ {...props}
36
+ rootProps={{ __css: styles.root }}
37
+ ref={ref}
38
+ />
34
39
  {label && <FormLabel>{label}</FormLabel>}
35
40
  </FormControl>
36
41
  );
@@ -34,6 +34,7 @@ export const PasswordInput = forwardRef<PasswordInputProps, "input">(
34
34
  paddingRight={10}
35
35
  paddingLeft={leftIcon ? 7 : undefined}
36
36
  ref={ref}
37
+ data-attachable
37
38
  />
38
39
  <FormLabel htmlFor={inputId} pointerEvents="none">
39
40
  {label}
@@ -0,0 +1,113 @@
1
+ import {
2
+ As,
3
+ BoxProps,
4
+ forwardRef,
5
+ useControllableState,
6
+ } from "@chakra-ui/react";
7
+ import React, { Suspense } from "react";
8
+ import { InfoSelect, Input, SelectItem, createTexts, useTranslation } from "..";
9
+ import { AttachedInputs } from "./AttachedInputs";
10
+
11
+ type CountryCodeAndPhoneNumber = {
12
+ countryCode: string;
13
+ phoneNumber: string;
14
+ };
15
+ type PhoneNumberInputProps = BoxProps & {
16
+ /** The root name.
17
+ *
18
+ * Please note that when specifying the name, the rendered names will be `${name}-country-code` and `${name}-phone-number`, respectively
19
+ */
20
+ name?: string;
21
+ /** Callback for when the country code or phone number changes */
22
+ onChange?: (change: CountryCodeAndPhoneNumber) => void;
23
+ /** The optional value of the country code and phone number */
24
+ value?: CountryCodeAndPhoneNumber;
25
+ };
26
+ /**
27
+ * A component for entering phone numbers.
28
+ *
29
+ * ```tsx
30
+ * <PhoneNumberInput name="phone" />
31
+ * ```
32
+ *
33
+ * > Please note that when specifying the name, the rendered names will be `${name}-country-code` and `${name}-phone-number`, respectively
34
+ *
35
+ * The field can be controlled as well:
36
+ * ```tsx
37
+ * <PhoneNumberInput
38
+ * value={{ countryCode: '+47', phoneNumber: '81549300' }}
39
+ * onChange={handleChange}
40
+ * />
41
+ * ```
42
+ */
43
+ export const PhoneNumberInput = forwardRef<PhoneNumberInputProps, As>(
44
+ (
45
+ { name, value: externalValue, onChange: externalOnChange, ...boxProps },
46
+ ref
47
+ ) => {
48
+ const { t } = useTranslation();
49
+ const [value, onChange] = useControllableState({
50
+ value: externalValue,
51
+ onChange: externalOnChange,
52
+ defaultValue: {
53
+ countryCode: "+47",
54
+ phoneNumber: "",
55
+ },
56
+ });
57
+ return (
58
+ <AttachedInputs {...boxProps}>
59
+ <Suspense
60
+ fallback={
61
+ <InfoSelect
62
+ isLabelSrOnly
63
+ label=""
64
+ width="6.25rem"
65
+ height="100%"
66
+ value="+47"
67
+ >
68
+ <SelectItem key="+47">+47</SelectItem>
69
+ </InfoSelect>
70
+ }
71
+ >
72
+ <LazyCountryCodeSelect
73
+ value={value.countryCode}
74
+ onChange={(countryCode) =>
75
+ onChange({
76
+ countryCode: countryCode as string,
77
+ phoneNumber: value.phoneNumber,
78
+ })
79
+ }
80
+ name={name ? `${name}-country-code` : "country-code"}
81
+ height="100%"
82
+ width="6.25rem"
83
+ />
84
+ </Suspense>
85
+ <Input
86
+ ref={ref}
87
+ label={t(texts.phoneNumber)}
88
+ value={value.phoneNumber}
89
+ name={name ? `${name}-phone-number` : "phone-number"}
90
+ onChange={(e) =>
91
+ onChange({
92
+ countryCode: value.countryCode,
93
+ phoneNumber: e.target.value,
94
+ })
95
+ }
96
+ position="relative"
97
+ left="-1px" // Makes the borders overlap
98
+ />
99
+ </AttachedInputs>
100
+ );
101
+ }
102
+ );
103
+
104
+ const texts = createTexts({
105
+ phoneNumber: {
106
+ nb: "Telefonnummer",
107
+ nn: "Telefonnummer",
108
+ en: "Phone number",
109
+ sv: "Telefonnummer",
110
+ },
111
+ });
112
+
113
+ const LazyCountryCodeSelect = React.lazy(() => import("./CountryCodeSelect"));
@@ -51,6 +51,7 @@ export const SearchInput = forwardRef<SearchInputProps, "input">(
51
51
  }}
52
52
  ref={ref}
53
53
  placeholder=" " // This is needed to make the label work as expected
54
+ data-attachable
54
55
  />
55
56
  <FormLabel htmlFor={inputId} pointerEvents="none">
56
57
  {label ?? t(texts.label)}
@@ -1,5 +1,6 @@
1
1
  export { FormHelperText, InputGroup } from "@chakra-ui/react";
2
2
  export type { InputGroupProps } from "@chakra-ui/react";
3
+ export * from "./AttachedInputs";
3
4
  export * from "./CardSelect";
4
5
  export * from "./Checkbox";
5
6
  export * from "./CheckboxGroup";
@@ -13,6 +14,7 @@ export * from "./InputElement";
13
14
  export * from "./ListBox";
14
15
  export * from "./NativeSelect";
15
16
  export * from "./PasswordInput";
17
+ export * from "./PhoneNumberInput";
16
18
  export * from "./Radio";
17
19
  export * from "./RadioGroup";
18
20
  export * from "./SearchInput";
@@ -25,7 +25,6 @@ const config = helpers.defineMultiStyleConfig({
25
25
  display: "flex",
26
26
  flex: 1,
27
27
  paddingY: 0.5,
28
- minHeight: 64,
29
28
  alignItems: "center",
30
29
  _hover: {
31
30
  boxShadow: getBoxShadowString({
@@ -1,9 +1,9 @@
1
1
  import { anatomy } from "@chakra-ui/anatomy";
2
2
  import { createMultiStyleConfigHelpers } from "@chakra-ui/react";
3
3
  import { mode } from "@chakra-ui/theme-tools";
4
- import { colors } from "../foundations";
5
4
  import { getBoxShadowString } from "../utils/box-shadow-utils";
6
5
  import { focusVisible } from "../utils/focus-utils";
6
+ import { srOnly } from "../utils/sr-utils";
7
7
 
8
8
  const parts = anatomy("InfoSelect").parts(
9
9
  "container",
@@ -19,6 +19,7 @@ const config = helpers.defineMultiStyleConfig({
19
19
  container: {},
20
20
  label: {
21
21
  position: "relative",
22
+ ...(props.isLabelSrOnly ? srOnly : {}),
22
23
  },
23
24
  button: {
24
25
  appearance: "none",
@@ -29,15 +30,13 @@ const config = helpers.defineMultiStyleConfig({
29
30
  display: "flex",
30
31
  justifyContent: "space-between",
31
32
  alignItems: "center",
33
+ fontSize: "mobile.md",
32
34
  boxShadow: getBoxShadowString({
33
- borderColor: mode(
34
- colors.blackAlpha[400],
35
- colors.whiteAlpha[400]
36
- )(props),
35
+ borderColor: mode("blackAlpha.400", "whiteAlpha.400")(props),
37
36
  }),
38
37
  _hover: {
39
38
  boxShadow: getBoxShadowString({
40
- borderColor: "darkGrey",
39
+ borderColor: mode("darkGrey", "whiteAlpha.600")(props),
41
40
  borderWidth: 2,
42
41
  }),
43
42
  },
@@ -50,7 +49,9 @@ const config = helpers.defineMultiStyleConfig({
50
49
  outline: "none",
51
50
  },
52
51
  notFocus: {
53
- boxShadow: getBoxShadowString({ borderColor: "darkGrey" }),
52
+ boxShadow: getBoxShadowString({
53
+ borderColor: mode("blackAlpha.400", "whiteAlpha.400")(props),
54
+ }),
54
55
  },
55
56
  }),
56
57
  _disabled: {
@@ -1,6 +1,6 @@
1
1
  import { inputAnatomy as parts } from "@chakra-ui/anatomy";
2
2
  import { createMultiStyleConfigHelpers } from "@chakra-ui/react";
3
- import { colors } from "../foundations";
3
+ import { mode } from "@chakra-ui/theme-tools";
4
4
  import { getBoxShadowString } from "../utils/box-shadow-utils";
5
5
  import { focusVisible } from "../utils/focus-utils";
6
6
 
@@ -13,19 +13,21 @@ const config = helpers.defineMultiStyleConfig({
13
13
  width: "100%",
14
14
  outline: "none",
15
15
  border: 0,
16
- backgroundColor: "white",
16
+ backgroundColor: mode("white", "darkGrey")(props),
17
17
  borderRadius: "sm",
18
18
  transitionProperty: "common",
19
19
  transitionDuration: "fast",
20
20
  position: "relative",
21
21
  px: 3,
22
22
  height: "54px",
23
- fontSize: "18px",
23
+ fontSize: "mobile.md",
24
24
 
25
- boxShadow: getBoxShadowString({ borderColor: colors.blackAlpha[400] }),
25
+ boxShadow: getBoxShadowString({
26
+ borderColor: mode("blackAlpha.400", "whiteAlpha.400")(props),
27
+ }),
26
28
  _hover: {
27
29
  boxShadow: getBoxShadowString({
28
- borderColor: "darkGrey",
30
+ borderColor: mode("darkGrey", "whiteAlpha.600")(props),
29
31
  borderWidth: 2,
30
32
  }),
31
33
  },
@@ -84,7 +86,7 @@ const config = helpers.defineMultiStyleConfig({
84
86
  "&:not(:placeholder-shown)": {
85
87
  pt: "16px",
86
88
  "& + label": {
87
- transform: "scale(0.825) translateY(-10px)",
89
+ transform: "scale(0.825) translateY(-10px)",
88
90
  },
89
91
  },
90
92
  },
@@ -29,7 +29,7 @@ const config = helpers.defineMultiStyleConfig({
29
29
  field: {
30
30
  ...Input.baseStyle!(props).field,
31
31
  appearance: "none",
32
- pt: "16px",
32
+ paddingTop: "16px",
33
33
  "option, optgroup": {
34
34
  background: "white",
35
35
  },
@@ -0,0 +1,13 @@
1
+ /** All the styles you need to hide something visually, while still making it available for screen readers */
2
+ export const srOnly = {
3
+ border: "0 !important",
4
+ clip: "rect(1px, 1px, 1px, 1px) !important",
5
+ clipPath: "inset(50%) !important",
6
+ height: "1px !important",
7
+ margin: "-1px !important",
8
+ overflow: "hidden !important",
9
+ padding: "0 !important",
10
+ position: "absolute !important",
11
+ width: "1px !important",
12
+ whiteSpace: "nowrap !important",
13
+ };