@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/.turbo/turbo-build.log +11 -9
- package/CHANGELOG.md +18 -0
- package/dist/CountryCodeSelect-AH34A2N4.mjs +6629 -0
- package/dist/chunk-XYGGYJ2I.mjs +13978 -0
- package/dist/index.d.ts +127 -52
- package/dist/index.js +19796 -11362
- package/dist/index.mjs +1 -13818
- package/package.json +4 -4
- package/src/datepicker/DateRangePicker.tsx +7 -1
- package/src/datepicker/DateTimeSegment.tsx +1 -0
- package/src/datepicker/TimePicker.tsx +0 -1
- package/src/input/AttachedInputs.tsx +55 -0
- package/src/input/CardSelect.tsx +1 -0
- package/src/input/CountryCodeSelect.tsx +52 -0
- package/src/input/FormErrorMessage.tsx +6 -2
- package/src/input/InfoSelect.tsx +37 -9
- package/src/input/Input.tsx +6 -5
- package/src/input/NativeSelect.tsx +6 -1
- package/src/input/PasswordInput.tsx +1 -0
- package/src/input/PhoneNumberInput.tsx +113 -0
- package/src/input/SearchInput.tsx +1 -0
- package/src/input/index.tsx +2 -0
- package/src/theme/components/datepicker.ts +0 -1
- package/src/theme/components/info-select.ts +8 -7
- package/src/theme/components/input.ts +8 -6
- package/src/theme/components/select.ts +1 -1
- package/src/theme/utils/sr-utils.ts +13 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vygruppen/spor-react",
|
3
|
-
"version": "2.
|
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": "
|
25
|
-
"@vygruppen/spor-icon-react": "
|
26
|
-
"@vygruppen/spor-loader": "
|
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
|
/>
|
@@ -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
|
+
};
|
package/src/input/CardSelect.tsx
CHANGED
@@ -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 = ({
|
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}
|
package/src/input/InfoSelect.tsx
CHANGED
@@ -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:
|
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
|
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
|
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", {
|
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
|
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: {
|
package/src/input/Input.tsx
CHANGED
@@ -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
|
-
|
46
|
-
|
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
|
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
|
);
|
@@ -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)}
|
package/src/input/index.tsx
CHANGED
@@ -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";
|
@@ -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({
|
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 {
|
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: "
|
23
|
+
fontSize: "mobile.md",
|
24
24
|
|
25
|
-
boxShadow: getBoxShadowString({
|
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
|
},
|
@@ -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
|
+
};
|