@vygruppen/spor-react 9.16.0 → 10.0.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 +10 -10
- package/CHANGELOG.md +28 -0
- package/dist/{CountryCodeSelect-2DASZ3PQ.mjs → CountryCodeSelect-PWHXKGPJ.mjs} +1 -1
- package/dist/{chunk-MDMLROK2.mjs → chunk-FQLXMFMW.mjs} +1031 -1187
- package/dist/index.d.mts +184 -689
- package/dist/index.d.ts +184 -689
- package/dist/index.js +1399 -1584
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/accordion/Accordion.tsx +8 -12
- package/src/accordion/Expandable.tsx +8 -26
- package/src/alert/ExpandableAlert.tsx +2 -2
- package/src/datepicker/CalendarTriggerButton.tsx +17 -13
- package/src/datepicker/DateField.tsx +50 -7
- package/src/datepicker/DatePicker.tsx +15 -4
- package/src/datepicker/DateTimeSegment.tsx +5 -1
- package/src/datepicker/StyledField.tsx +7 -1
- package/src/index.tsx +0 -1
- package/src/input/ChoiceChip.tsx +66 -55
- package/src/input/Input.tsx +5 -2
- package/src/input/NumericStepper.tsx +8 -6
- package/src/layout/StaticCard.tsx +0 -1
- package/src/linjetag/LineIcon.tsx +3 -8
- package/src/linjetag/TravelTag.tsx +11 -2
- package/src/linjetag/{types.d.ts → types.ts} +1 -1
- package/src/theme/components/accordion.ts +7 -40
- package/src/theme/components/datepicker.ts +2 -15
- package/src/theme/components/index.ts +0 -1
- package/src/accordion/AccordionContext.tsx +0 -27
- package/src/card/Card.tsx +0 -73
- package/src/card/index.tsx +0 -1
- package/src/theme/components/card.ts +0 -171
package/dist/index.mjs
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AttachedInputs, Badge, Box, Brand, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Button, ButtonGroup,
|
1
|
+
export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AttachedInputs, Badge, Box, Brand, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Button, ButtonGroup, CardSelect, CargonetLogo, Center, Checkbox, CheckboxGroup, ChoiceChip, ClosableAlert, CloseButton, Code, Collapse, ColorInlineLoader, ColorSpinner, Combobox, Container, ContentLoader, DarkFullScreenLoader, DarkInlineLoader, DarkMode, DarkSpinner, DatePicker, DateRangePicker, Divider, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerFooter, ModalHeader as DrawerHeader, DrawerOverlay, Expandable, ExpandableAlert, ExpandableItem, Fade, Flex, FloatingActionButton, FormControl, FormErrorMessage, FormHelperText, FormLabel, FullScreenDrawer, Grid, GridItem, HStack, Heading, IconButton, Image, Img, InfoSelect, InfoTag, Input, InputGroup, InputLeftElement, InputRightElement, Item, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightMode, LightSpinner, LineIcon, ListBox, ListItem, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, NativeSelect, Nudge, NumericStepper, OrderedList, Pagination, PasswordInput, PhoneNumberInput, PlayPauseButton, Portal, PressableCard, ProgressBar, ProgressIndicator, ProgressLoader, Radio, RadioCard, RadioCardGroup, RadioCardGroupContext, RadioGroup, ScaleFade, SearchInput, Section, SimpleDrawer, SimpleGrid, Skeleton, SkeletonCircle, SkeletonText, SkipButton, Slide, SlideFade, Spacer, SporProvider, Stack, StaticAlert, StaticCard, Stepper, StepperStep, Switch, Tab, TabList, TabPanel, TabPanels, Table, TableCaption, Tabs, Tbody, Td, Text, TextLink, Textarea, Tfoot, Th, Thead, Time, TimePicker, Tooltip, Tr, TravelTag, UnorderedList, VStack, VyLogo, VyLogoPride, WizardNudge, Wrap, WrapItem, brandTheme, createTexts, defineStyleConfig, extendTheme, fontFaces, slugify, theme, tokens, useBreakpointValue, useClipboard, useColorMode, useColorModePreference, useColorModeValue, useControllableProp, useDisclosure, useMediaQuery, useMergeRefs, useOutsideClick, usePrefersReducedMotion, useSize, useTheme, useToast, useToken, useTranslation } from './chunk-FQLXMFMW.mjs';
|
package/package.json
CHANGED
@@ -5,7 +5,6 @@ import {
|
|
5
5
|
} from "@chakra-ui/react";
|
6
6
|
import React from "react";
|
7
7
|
import { Stack, StackProps } from "../layout";
|
8
|
-
import { AccordionProvider } from "./AccordionContext";
|
9
8
|
export {
|
10
9
|
AccordionButton,
|
11
10
|
AccordionIcon,
|
@@ -27,7 +26,6 @@ export type AccordionProps = Omit<ChakraAccordionProps, "variant" | "size"> & {
|
|
27
26
|
* - `floating` renders a version with a drop shadow
|
28
27
|
*/
|
29
28
|
variant?: "ghost" | "base" | "floating";
|
30
|
-
size?: "sm" | "md" | "lg";
|
31
29
|
/** The margin between accordion items */
|
32
30
|
spacing?: StackProps["spacing"];
|
33
31
|
};
|
@@ -35,7 +33,7 @@ export type AccordionProps = Omit<ChakraAccordionProps, "variant" | "size"> & {
|
|
35
33
|
* Wraps a set of ExpandableItem or AccordionItem components.
|
36
34
|
*
|
37
35
|
* ```tsx
|
38
|
-
* <Accordion variant="ghost"
|
36
|
+
* <Accordion variant="ghost">
|
39
37
|
* <ExpandableItem title="Is Spor easy?" headingLevel="h3">
|
40
38
|
* Yes
|
41
39
|
* </ExpandableItem>
|
@@ -54,15 +52,13 @@ export const Accordion = forwardRef<AccordionProps, "div">(
|
|
54
52
|
? [props.defaultIndex]
|
55
53
|
: props.defaultIndex;
|
56
54
|
return (
|
57
|
-
<
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
>
|
63
|
-
|
64
|
-
</ChakraAccordion>
|
65
|
-
</AccordionProvider>
|
55
|
+
<ChakraAccordion
|
56
|
+
{...props}
|
57
|
+
ref={ref}
|
58
|
+
defaultIndex={defaultIndex as number[] | undefined}
|
59
|
+
>
|
60
|
+
<Stack spacing={spacing}>{children}</Stack>
|
61
|
+
</ChakraAccordion>
|
66
62
|
);
|
67
63
|
},
|
68
64
|
);
|
@@ -9,7 +9,6 @@ import {
|
|
9
9
|
} from "@chakra-ui/react";
|
10
10
|
import React from "react";
|
11
11
|
import { Accordion, AccordionProps } from "./Accordion";
|
12
|
-
import { useAccordionContext } from "./AccordionContext";
|
13
12
|
|
14
13
|
type HeadingLevel = "h2" | "h3" | "h4" | "h5" | "h6";
|
15
14
|
type ExpandableProps = Omit<
|
@@ -25,10 +24,7 @@ type ExpandableProps = Omit<
|
|
25
24
|
/**
|
26
25
|
* Icon shown to the left of the title
|
27
26
|
*
|
28
|
-
* Make sure it's the outlined version of the icon
|
29
|
-
*
|
30
|
-
* If the size is set to `sm` or `md` the icon should be 24px.
|
31
|
-
* If the size is set to `lg`, the icon should be 30px.
|
27
|
+
* Make sure it's the 24px outlined version of the icon
|
32
28
|
*/
|
33
29
|
leftIcon?: React.ReactNode;
|
34
30
|
|
@@ -46,7 +42,7 @@ type ExpandableProps = Omit<
|
|
46
42
|
* If you want several expandables in a row, use the `Accordion` and `ExpandableItem` components instead.
|
47
43
|
*
|
48
44
|
* ```tsx
|
49
|
-
* <Expandable title="Click for more" variant="base"
|
45
|
+
* <Expandable title="Click for more" variant="base">
|
50
46
|
* <Text>MORE! 🎉</Text>
|
51
47
|
* </Expandable>
|
52
48
|
* ```
|
@@ -56,7 +52,6 @@ export const Expandable = ({
|
|
56
52
|
headingLevel,
|
57
53
|
title,
|
58
54
|
leftIcon,
|
59
|
-
size = "md",
|
60
55
|
defaultOpen,
|
61
56
|
isOpen,
|
62
57
|
onChange = () => {},
|
@@ -67,8 +62,6 @@ export const Expandable = ({
|
|
67
62
|
{...rest}
|
68
63
|
index={isOpen ? 0 : undefined}
|
69
64
|
defaultIndex={defaultOpen ? 0 : undefined}
|
70
|
-
allowMultiple={true}
|
71
|
-
size={size}
|
72
65
|
onChange={(expandedIndex) => onChange(expandedIndex === 0)}
|
73
66
|
>
|
74
67
|
<ExpandableItem
|
@@ -92,7 +85,7 @@ export type ExpandableItemProps = Omit<AccordionItemProps, "title"> & {
|
|
92
85
|
/**
|
93
86
|
* Icon shown to the left of the title
|
94
87
|
*
|
95
|
-
* Make sure it's the
|
88
|
+
* Make sure it's the 24px outlined version of the icon
|
96
89
|
*/
|
97
90
|
leftIcon?: React.ReactNode;
|
98
91
|
};
|
@@ -100,7 +93,7 @@ export type ExpandableItemProps = Omit<AccordionItemProps, "title"> & {
|
|
100
93
|
* An item in a set of Expandables. Must be wrapped in an `<Accordion>` component.
|
101
94
|
*
|
102
95
|
* ```tsx
|
103
|
-
* <Accordion variant="ghost"
|
96
|
+
* <Accordion variant="ghost">
|
104
97
|
* <ExpandableItem title="Is Spor easy?" headingLevel="h3">
|
105
98
|
* Yes
|
106
99
|
* </ExpandableItem>
|
@@ -119,8 +112,7 @@ export const ExpandableItem = ({
|
|
119
112
|
leftIcon,
|
120
113
|
...rest
|
121
114
|
}: ExpandableItemProps) => {
|
122
|
-
|
123
|
-
warnAboutMismatchingIcon({ icon: leftIcon, size });
|
115
|
+
warnAboutMismatchingIcon({ icon: leftIcon });
|
124
116
|
return (
|
125
117
|
<AccordionItem {...rest}>
|
126
118
|
<Box as={headingLevel}>
|
@@ -139,9 +131,8 @@ export const ExpandableItem = ({
|
|
139
131
|
|
140
132
|
type WarnAboutMismatchingIcon = {
|
141
133
|
icon: any;
|
142
|
-
size: AccordionProps["size"];
|
143
134
|
};
|
144
|
-
const warnAboutMismatchingIcon = ({ icon
|
135
|
+
const warnAboutMismatchingIcon = ({ icon }: WarnAboutMismatchingIcon) => {
|
145
136
|
if (process.env.NODE_ENV !== "production") {
|
146
137
|
const displayName = icon?.type?.render?.displayName;
|
147
138
|
if (!displayName) {
|
@@ -156,18 +147,9 @@ const warnAboutMismatchingIcon = ({ icon, size }: WarnAboutMismatchingIcon) => {
|
|
156
147
|
);
|
157
148
|
return;
|
158
149
|
}
|
159
|
-
if (
|
160
|
-
console.warn(
|
161
|
-
`The icon you passed was of the wrong size for the lg size. You passed ${displayName}, replace it with ${displayName.replace(
|
162
|
-
/(\d{2})Icon/,
|
163
|
-
"30Icon",
|
164
|
-
)}.`,
|
165
|
-
);
|
166
|
-
return;
|
167
|
-
}
|
168
|
-
if (["md" || "sm"].includes(size!) && !displayName.includes("24Icon")) {
|
150
|
+
if (!displayName.includes("24Icon")) {
|
169
151
|
console.warn(
|
170
|
-
`The icon you passed was of the wrong size
|
152
|
+
`The icon you passed was of the wrong size. You passed ${displayName}, replace it with ${displayName.replace(
|
171
153
|
/(\d{2})Icon/,
|
172
154
|
"24Icon",
|
173
155
|
)}.`,
|
@@ -70,8 +70,8 @@ export const ExpandableAlert = ({
|
|
70
70
|
// Truncate the title to one line
|
71
71
|
display: "-webkit-box",
|
72
72
|
overflow: "hidden",
|
73
|
-
|
74
|
-
|
73
|
+
WebkitLineClamp: "1",
|
74
|
+
WebkitBoxOrient: "vertical",
|
75
75
|
}}
|
76
76
|
color="darkGrey"
|
77
77
|
>
|
@@ -7,39 +7,43 @@ import {
|
|
7
7
|
ResponsiveValue,
|
8
8
|
} from "@chakra-ui/react";
|
9
9
|
import { CalendarOutline24Icon } from "@vygruppen/spor-icon-react";
|
10
|
-
import React from "react";
|
10
|
+
import React, { KeyboardEventHandler } from "react";
|
11
11
|
import { AriaButtonProps } from "react-aria";
|
12
|
-
import { createTexts, useTranslation } from "..";
|
12
|
+
import { IconButton, createTexts, useTranslation } from "..";
|
13
13
|
|
14
14
|
type CalendarTriggerButtonProps = AriaButtonProps<"button"> & {
|
15
15
|
variant: ResponsiveValue<"base" | "floating" | "ghost">;
|
16
|
+
isDisabled?: boolean;
|
17
|
+
ariaLabelledby?: string;
|
16
18
|
};
|
17
19
|
export const CalendarTriggerButton = forwardRef<CalendarTriggerButtonProps, As>(
|
18
|
-
({ variant, ...buttonProps }, ref) => {
|
20
|
+
({ variant, isDisabled, ariaLabelledby, ...buttonProps }, ref) => {
|
19
21
|
const { t } = useTranslation();
|
20
22
|
const styles = useMultiStyleConfig("Datepicker", { variant });
|
21
23
|
|
22
24
|
const { onPress, ...filteredButtonProps } = buttonProps;
|
23
25
|
|
24
|
-
const
|
25
|
-
if (
|
26
|
-
|
26
|
+
const handleCommand: KeyboardEventHandler = (event) => {
|
27
|
+
if (event.key === "Enter" || event.key === " ") {
|
28
|
+
event.preventDefault();
|
29
|
+
onPress?.(event as any);
|
27
30
|
}
|
28
31
|
};
|
29
32
|
|
30
33
|
return (
|
31
34
|
<PopoverAnchor>
|
32
|
-
<
|
35
|
+
<IconButton
|
33
36
|
ref={ref}
|
34
|
-
|
35
|
-
|
37
|
+
role="button"
|
38
|
+
icon={<CalendarOutline24Icon />}
|
36
39
|
aria-label={t(texts.openCalendar)}
|
37
40
|
sx={styles.calendarTriggerButton}
|
41
|
+
variant="ghost"
|
38
42
|
{...filteredButtonProps}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
isDisabled={isDisabled}
|
44
|
+
onKeyDown={handleCommand}
|
45
|
+
aria-labelledby={ariaLabelledby}
|
46
|
+
/>
|
43
47
|
</PopoverAnchor>
|
44
48
|
);
|
45
49
|
},
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import { Box, Flex, FormLabel, useMultiStyleConfig } from "@chakra-ui/react";
|
2
2
|
import { DateValue, GregorianCalendar } from "@internationalized/date";
|
3
3
|
import { DOMAttributes, FocusableElement } from "@react-types/shared";
|
4
|
-
import React, { RefObject, forwardRef, useRef } from "react";
|
4
|
+
import React, { RefObject, forwardRef, useId, useRef } from "react";
|
5
5
|
import { AriaDateFieldProps, useDateField } from "react-aria";
|
6
|
-
import { useDateFieldState } from "react-stately";
|
6
|
+
import { DateSegment, useDateFieldState } from "react-stately";
|
7
7
|
import { DateTimeSegment } from "./DateTimeSegment";
|
8
8
|
import { useCurrentLocale } from "./utils";
|
9
|
+
import { createTexts, useTranslation } from "../i18n";
|
9
10
|
|
10
11
|
function createCalendar(identifier: string) {
|
11
12
|
switch (identifier) {
|
@@ -20,9 +21,10 @@ type DateFieldProps = AriaDateFieldProps<DateValue> & {
|
|
20
21
|
label?: React.ReactNode;
|
21
22
|
labelProps?: DOMAttributes<FocusableElement>;
|
22
23
|
name?: string;
|
24
|
+
labelId?: string;
|
23
25
|
};
|
24
26
|
export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
|
25
|
-
(props, externalRef) => {
|
27
|
+
({ labelId, ...props }, externalRef) => {
|
26
28
|
const locale = useCurrentLocale();
|
27
29
|
const styles = useMultiStyleConfig("Datepicker", {});
|
28
30
|
const state = useDateFieldState({
|
@@ -31,9 +33,11 @@ export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
|
|
31
33
|
createCalendar,
|
32
34
|
});
|
33
35
|
|
36
|
+
const { t } = useTranslation();
|
37
|
+
|
34
38
|
const internalRef = useRef(null);
|
35
39
|
const ref = externalRef ?? internalRef;
|
36
|
-
const { fieldProps
|
40
|
+
const { fieldProps } = useDateField(
|
37
41
|
props,
|
38
42
|
state,
|
39
43
|
ref as RefObject<HTMLDivElement>,
|
@@ -43,18 +47,23 @@ export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
|
|
43
47
|
<Box minWidth="6rem" width="100%">
|
44
48
|
{props.label && (
|
45
49
|
<FormLabel
|
46
|
-
{...props.labelProps}
|
47
|
-
{...labelProps}
|
48
50
|
sx={styles.inputLabel}
|
49
51
|
position="absolute"
|
50
52
|
paddingTop="2px"
|
53
|
+
id={labelId}
|
51
54
|
>
|
52
55
|
{props.label}
|
53
56
|
</FormLabel>
|
54
57
|
)}
|
55
58
|
<Flex {...fieldProps} ref={ref} paddingTop="3" paddingBottom="0.5">
|
56
59
|
{state.segments.map((segment, i) => (
|
57
|
-
<DateTimeSegment
|
60
|
+
<DateTimeSegment
|
61
|
+
key={i}
|
62
|
+
segment={segment}
|
63
|
+
ariaDescription={t(getAriaLabel(segment.type))}
|
64
|
+
ariaLabel={labelId}
|
65
|
+
state={state}
|
66
|
+
/>
|
58
67
|
))}
|
59
68
|
</Flex>
|
60
69
|
<input
|
@@ -66,3 +75,37 @@ export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
|
|
66
75
|
);
|
67
76
|
},
|
68
77
|
);
|
78
|
+
|
79
|
+
const texts = createTexts({
|
80
|
+
day: {
|
81
|
+
nb: "Velg dag",
|
82
|
+
nn: "Vel dag",
|
83
|
+
sv: "Välj dag",
|
84
|
+
en: "Choose day",
|
85
|
+
},
|
86
|
+
month: {
|
87
|
+
nb: "Velg måned",
|
88
|
+
nn: "Vel månad",
|
89
|
+
sv: "Välj månad",
|
90
|
+
en: "Choose month",
|
91
|
+
},
|
92
|
+
year: {
|
93
|
+
nb: "Velg år",
|
94
|
+
nn: "Vel år",
|
95
|
+
sv: "Välj år",
|
96
|
+
en: "Choose year",
|
97
|
+
},
|
98
|
+
});
|
99
|
+
|
100
|
+
const getAriaLabel = (segmentType: DateSegment["type"]) => {
|
101
|
+
switch (segmentType) {
|
102
|
+
case "day":
|
103
|
+
return texts.day;
|
104
|
+
case "month":
|
105
|
+
return texts.month;
|
106
|
+
case "year":
|
107
|
+
return texts.year;
|
108
|
+
default:
|
109
|
+
return texts.day;
|
110
|
+
}
|
111
|
+
};
|
@@ -2,7 +2,6 @@ import {
|
|
2
2
|
Box,
|
3
3
|
BoxProps,
|
4
4
|
FocusLock,
|
5
|
-
InputGroup,
|
6
5
|
Popover,
|
7
6
|
PopoverAnchor,
|
8
7
|
PopoverArrow,
|
@@ -10,12 +9,13 @@ import {
|
|
10
9
|
PopoverContent,
|
11
10
|
PopoverTrigger,
|
12
11
|
Portal,
|
12
|
+
InputGroup,
|
13
13
|
ResponsiveValue,
|
14
14
|
useFormControlContext,
|
15
15
|
useMultiStyleConfig,
|
16
16
|
} from "@chakra-ui/react";
|
17
17
|
import { DateValue } from "@internationalized/date";
|
18
|
-
import React, { ReactNode, forwardRef, useRef } from "react";
|
18
|
+
import React, { ReactNode, forwardRef, useId, useRef } from "react";
|
19
19
|
import { AriaDatePickerProps, I18nProvider, useDatePicker } from "react-aria";
|
20
20
|
import { useDatePickerState } from "react-stately";
|
21
21
|
import { FormErrorMessage } from "..";
|
@@ -68,7 +68,6 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
|
68
68
|
const internalRef = useRef<HTMLDivElement>(null);
|
69
69
|
const ref = externalRef ?? internalRef;
|
70
70
|
const {
|
71
|
-
groupProps,
|
72
71
|
labelProps,
|
73
72
|
fieldProps,
|
74
73
|
buttonProps,
|
@@ -81,6 +80,9 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
|
81
80
|
ref as React.MutableRefObject<HTMLDivElement>,
|
82
81
|
);
|
83
82
|
|
83
|
+
const labelId = `label-${useId()}`;
|
84
|
+
const inputGroupId = `input-group-${useId()}`;
|
85
|
+
|
84
86
|
const styles = useMultiStyleConfig("Datepicker", { variant });
|
85
87
|
const locale = useCurrentLocale();
|
86
88
|
|
@@ -118,24 +120,33 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
|
118
120
|
onClose={state.close}
|
119
121
|
flip={false}
|
120
122
|
>
|
121
|
-
<InputGroup
|
123
|
+
<InputGroup
|
124
|
+
display="inline-flex"
|
125
|
+
id={inputGroupId}
|
126
|
+
aria-labelledby={labelId}
|
127
|
+
>
|
122
128
|
<PopoverAnchor>
|
123
129
|
<StyledField
|
124
130
|
variant={variant}
|
125
131
|
onClick={onFieldClick}
|
126
132
|
paddingX={3}
|
127
133
|
minHeight={minHeight}
|
134
|
+
isDisabled={props.isDisabled}
|
135
|
+
ariaLabelledby={labelId}
|
128
136
|
>
|
129
137
|
<PopoverTrigger>
|
130
138
|
<CalendarTriggerButton
|
131
139
|
variant={variant}
|
132
140
|
ref={ref}
|
141
|
+
isDisabled={props.isDisabled}
|
142
|
+
ariaLabelledby={labelId}
|
133
143
|
{...buttonProps}
|
134
144
|
/>
|
135
145
|
</PopoverTrigger>
|
136
146
|
<DateField
|
137
147
|
label={props.label}
|
138
148
|
labelProps={labelProps}
|
149
|
+
labelId={labelId}
|
139
150
|
name={props.name}
|
140
151
|
{...fieldProps}
|
141
152
|
/>
|
@@ -6,6 +6,8 @@ import { DateFieldState, DateSegment } from "react-stately";
|
|
6
6
|
type DateTimeSegmentProps = {
|
7
7
|
segment: DateSegment;
|
8
8
|
state: DateFieldState;
|
9
|
+
ariaLabel?: string;
|
10
|
+
ariaDescription?: string;
|
9
11
|
};
|
10
12
|
/**
|
11
13
|
* A date time segment is a part of a date or a time stamp.
|
@@ -15,7 +17,7 @@ type DateTimeSegmentProps = {
|
|
15
17
|
* This component should be used with the react-aria library, and is not meant to be used directly.
|
16
18
|
* */
|
17
19
|
export const DateTimeSegment = forwardRef<HTMLDivElement, DateTimeSegmentProps>(
|
18
|
-
({ segment, state }, externalRef) => {
|
20
|
+
({ segment, state, ariaLabel, ariaDescription }, externalRef) => {
|
19
21
|
const internalRef = useRef(null);
|
20
22
|
const ref = externalRef ?? internalRef;
|
21
23
|
|
@@ -42,6 +44,8 @@ export const DateTimeSegment = forwardRef<HTMLDivElement, DateTimeSegmentProps>(
|
|
42
44
|
borderRadius="xs"
|
43
45
|
fontSize={["mobile.sm", "desktop.sm"]}
|
44
46
|
sx={styles.dateTimeSegment}
|
47
|
+
aria-description={ariaDescription}
|
48
|
+
aria-labelledby={ariaLabel}
|
45
49
|
>
|
46
50
|
{isPaddable(segment.type)
|
47
51
|
? segment.text.padStart(2, "0")
|
@@ -11,19 +11,25 @@ import React from "react";
|
|
11
11
|
|
12
12
|
type StyledFieldProps = BoxProps & {
|
13
13
|
variant: ResponsiveValue<"base" | "floating" | "ghost">;
|
14
|
+
isDisabled?: boolean;
|
15
|
+
ariaLabelledby?: string;
|
14
16
|
};
|
15
17
|
export const StyledField = forwardRef<StyledFieldProps, As>(
|
16
|
-
({ children, variant, ...otherProps }, ref) => {
|
18
|
+
({ children, variant, isDisabled, ariaLabelledby, ...otherProps }, ref) => {
|
17
19
|
const { isInvalid } = useFormControlContext() ?? {
|
18
20
|
isInvalid: false,
|
19
21
|
};
|
22
|
+
|
20
23
|
const styles = useMultiStyleConfig("Datepicker", { variant });
|
24
|
+
|
21
25
|
return (
|
22
26
|
<Box
|
23
27
|
{...otherProps}
|
24
28
|
__css={styles.wrapper}
|
25
29
|
ref={ref}
|
26
30
|
aria-invalid={isInvalid}
|
31
|
+
aria-disabled={isDisabled}
|
32
|
+
aria-labelledby={ariaLabelledby}
|
27
33
|
>
|
28
34
|
{children}
|
29
35
|
</Box>
|
package/src/index.tsx
CHANGED
package/src/input/ChoiceChip.tsx
CHANGED
@@ -54,62 +54,73 @@ export type ChoiceChipProps = {
|
|
54
54
|
* </Stack>
|
55
55
|
* ```
|
56
56
|
*/
|
57
|
-
export const ChoiceChip = forwardRef(
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
57
|
+
export const ChoiceChip = forwardRef(
|
58
|
+
(
|
59
|
+
{
|
60
|
+
children,
|
61
|
+
icon,
|
62
|
+
isChecked,
|
63
|
+
isDisabled,
|
64
|
+
size = "sm",
|
65
|
+
chipType = "choice",
|
66
|
+
variant = "base",
|
67
|
+
...props
|
68
|
+
}: ChoiceChipProps,
|
69
|
+
ref,
|
70
|
+
) => {
|
71
|
+
const {
|
72
|
+
state,
|
73
|
+
getInputProps,
|
74
|
+
getCheckboxProps,
|
75
|
+
getRootProps,
|
76
|
+
getLabelProps,
|
77
|
+
} = useCheckbox(props);
|
78
|
+
const styles = useMultiStyleConfig("ChoiceChip", {
|
79
|
+
size,
|
80
|
+
chipType,
|
81
|
+
variant,
|
82
|
+
icon,
|
83
|
+
hasLabel: chipType !== "icon",
|
84
|
+
});
|
66
85
|
|
67
|
-
|
68
|
-
state,
|
69
|
-
getInputProps,
|
70
|
-
getCheckboxProps,
|
71
|
-
getRootProps,
|
72
|
-
getLabelProps,
|
73
|
-
} = useCheckbox(props);
|
74
|
-
const styles = useMultiStyleConfig("ChoiceChip", {
|
75
|
-
size,
|
76
|
-
chipType,
|
77
|
-
variant,
|
78
|
-
icon,
|
79
|
-
hasLabel: Boolean(children),
|
80
|
-
});
|
86
|
+
const id = `choice-chip-${useId()}`;
|
81
87
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
{...getRootProps()}
|
88
|
-
aria-label={String(children)}
|
89
|
-
>
|
90
|
-
<chakra.input {...getInputProps({}, ref)} id={id} disabled={isDisabled} />
|
91
|
-
<chakra.div
|
92
|
-
{...getLabelProps()}
|
93
|
-
__css={styles.container}
|
94
|
-
data-checked={dataAttr(state.isChecked)}
|
95
|
-
data-hover={dataAttr(state.isHovered)}
|
96
|
-
data-focus={dataAttr(state.isFocused)}
|
97
|
-
data-active={dataAttr(state.isActive)}
|
98
|
-
data-disabled={dataAttr(state.isDisabled)}
|
88
|
+
return (
|
89
|
+
<chakra.label
|
90
|
+
htmlFor={id}
|
91
|
+
{...getRootProps()}
|
92
|
+
aria-label={String(children)}
|
99
93
|
>
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
94
|
+
<chakra.input
|
95
|
+
{...getInputProps({}, ref)}
|
96
|
+
id={id}
|
97
|
+
disabled={isDisabled}
|
98
|
+
/>
|
99
|
+
<chakra.div
|
100
|
+
{...getLabelProps()}
|
101
|
+
__css={styles.container}
|
102
|
+
data-checked={dataAttr(state.isChecked)}
|
103
|
+
data-hover={dataAttr(state.isHovered)}
|
104
|
+
data-focus={dataAttr(state.isFocused)}
|
105
|
+
data-active={dataAttr(state.isActive)}
|
106
|
+
data-disabled={dataAttr(state.isDisabled)}
|
107
|
+
>
|
108
|
+
{icon && (
|
109
|
+
<chakra.span __css={styles.icon}>
|
110
|
+
{state.isChecked ? icon.checked : icon.default}
|
111
|
+
</chakra.span>
|
112
|
+
)}
|
113
|
+
{chipType !== "icon" && (
|
114
|
+
<chakra.span __css={styles.label} {...getCheckboxProps()}>
|
115
|
+
{children}
|
116
|
+
</chakra.span>
|
117
|
+
)}
|
105
118
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
);
|
115
|
-
});
|
119
|
+
{chipType === "filter" && state.isChecked && (
|
120
|
+
<CloseOutline24Icon marginLeft={1.5} />
|
121
|
+
)}
|
122
|
+
</chakra.div>
|
123
|
+
</chakra.label>
|
124
|
+
);
|
125
|
+
},
|
126
|
+
);
|
package/src/input/Input.tsx
CHANGED
@@ -38,6 +38,7 @@ export const Input = forwardRef<InputProps, "input">(
|
|
38
38
|
const formControlProps = useFormControlContext();
|
39
39
|
const fallbackId = `input-${useId()}`;
|
40
40
|
const inputId = id ?? formControlProps?.id ?? fallbackId;
|
41
|
+
const labelId = `${useId()}-label`;
|
41
42
|
return (
|
42
43
|
<InputGroup position="relative">
|
43
44
|
{leftIcon && (
|
@@ -49,11 +50,13 @@ export const Input = forwardRef<InputProps, "input">(
|
|
49
50
|
paddingRight={rightIcon ? 7 : undefined}
|
50
51
|
{...props}
|
51
52
|
id={inputId}
|
52
|
-
aria-labelledby={
|
53
|
+
aria-labelledby={labelId}
|
53
54
|
ref={ref}
|
54
55
|
placeholder=" " // This is needed to make the label work as expected
|
55
56
|
/>
|
56
|
-
<FormLabel htmlFor={inputId}
|
57
|
+
<FormLabel htmlFor={inputId} id={labelId}>
|
58
|
+
{label}
|
59
|
+
</FormLabel>
|
57
60
|
{rightIcon && (
|
58
61
|
<InputRightElement pointerEvents="none">
|
59
62
|
{rightIcon}
|
@@ -159,7 +159,9 @@ const VerySmallButton = (props: VerySmallButtonProps) => {
|
|
159
159
|
);
|
160
160
|
};
|
161
161
|
|
162
|
-
|
162
|
+
type IconPropTypes = BoxProps & { stepLabel: number };
|
163
|
+
|
164
|
+
const SubtractIcon = ({ stepLabel, ...props }: IconPropTypes) => (
|
163
165
|
<>
|
164
166
|
<Box
|
165
167
|
as="svg"
|
@@ -178,13 +180,13 @@ const SubtractIcon = (props: BoxProps & { stepLabel: number }) => (
|
|
178
180
|
strokeLinecap="round"
|
179
181
|
/>
|
180
182
|
</Box>
|
181
|
-
{
|
182
|
-
<chakra.span paddingRight="1">{
|
183
|
+
{stepLabel > 1 && (
|
184
|
+
<chakra.span paddingRight="1">{stepLabel.toString()}</chakra.span>
|
183
185
|
)}
|
184
186
|
</>
|
185
187
|
);
|
186
188
|
|
187
|
-
const AddIcon = (
|
189
|
+
const AddIcon = ({ stepLabel, ...props }: IconPropTypes) => (
|
188
190
|
<>
|
189
191
|
<Box
|
190
192
|
as="svg"
|
@@ -212,8 +214,8 @@ const AddIcon = (props: BoxProps & { stepLabel: number }) => (
|
|
212
214
|
/>
|
213
215
|
</Box>
|
214
216
|
|
215
|
-
{
|
216
|
-
<chakra.span paddingRight="1">{
|
217
|
+
{stepLabel > 1 && (
|
218
|
+
<chakra.span paddingRight="1">{stepLabel.toString()}</chakra.span>
|
217
219
|
)}
|
218
220
|
</>
|
219
221
|
);
|