@vygruppen/spor-react 9.16.0 → 10.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/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AttachedInputs, Badge, Box, Brand, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Button, ButtonGroup, Card, 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-MDMLROK2.mjs';
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-MLRF67YM.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
- "version": "9.16.0",
3
+ "version": "10.1.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -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" size="md">
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
- <AccordionProvider size={props.size}>
58
- <ChakraAccordion
59
- {...props}
60
- ref={ref}
61
- defaultIndex={defaultIndex as number[] | undefined}
62
- >
63
- <Stack spacing={spacing}>{children}</Stack>
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" size="lg">
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 30px outlined version of the icon
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" size="md">
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
- const { size } = useAccordionContext();
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, size }: WarnAboutMismatchingIcon) => {
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 (size === "lg" && !displayName.includes("30Icon")) {
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 for the ${size} size. You passed ${displayName}, replace it with ${displayName.replace(
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
- "-webkit-line-clamp": "1",
74
- "-webkit-box-orient": "vertical",
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 handleOnPress = (event: KeyboardEvent) => {
25
- if (onPress) {
26
- if (event.key == "Enter" || event.key == " ") onPress(event as any);
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
- <Box
35
+ <IconButton
33
36
  ref={ref}
34
- as="button"
35
- type="button"
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
- onKeyUp={handleOnPress}
40
- >
41
- <CalendarOutline24Icon />
42
- </Box>
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, labelProps } = useDateField(
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 key={i} segment={segment} state={state} />
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 {...groupProps} display="inline-flex">
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
@@ -3,7 +3,6 @@ export * from "./accordion";
3
3
  export * from "./alert";
4
4
  export * from "./breadcrumb";
5
5
  export * from "./button";
6
- export * from "./card";
7
6
  export * from "./datepicker";
8
7
  export * from "./i18n";
9
8
  export * from "./image";
@@ -54,62 +54,72 @@ export type ChoiceChipProps = {
54
54
  * </Stack>
55
55
  * ```
56
56
  */
57
- export const ChoiceChip = forwardRef((props: ChoiceChipProps, ref) => {
58
- const {
59
- children,
60
- icon,
61
- isDisabled,
62
- size = "sm",
63
- chipType = "choice",
64
- variant = "base",
65
- } = props;
57
+ export const ChoiceChip = forwardRef(
58
+ (
59
+ {
60
+ children,
61
+ icon,
62
+ isDisabled,
63
+ size = "sm",
64
+ chipType = "choice",
65
+ variant = "base",
66
+ ...props
67
+ }: ChoiceChipProps,
68
+ ref,
69
+ ) => {
70
+ const {
71
+ state,
72
+ getInputProps,
73
+ getCheckboxProps,
74
+ getRootProps,
75
+ getLabelProps,
76
+ } = useCheckbox(props);
77
+ const styles = useMultiStyleConfig("ChoiceChip", {
78
+ size,
79
+ chipType,
80
+ variant,
81
+ icon,
82
+ hasLabel: chipType !== "icon",
83
+ });
66
84
 
67
- const {
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
- });
85
+ const id = `choice-chip-${useId()}`;
81
86
 
82
- const id = `choice-chip-${useId()}`;
83
-
84
- return (
85
- <chakra.label
86
- htmlFor={id}
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)}
87
+ return (
88
+ <chakra.label
89
+ htmlFor={id}
90
+ {...getRootProps()}
91
+ aria-label={String(children)}
99
92
  >
100
- {icon && (
101
- <chakra.span __css={styles.icon}>
102
- {state.isChecked ? icon.checked : icon.default}
103
- </chakra.span>
104
- )}
93
+ <chakra.input
94
+ {...getInputProps({}, ref)}
95
+ id={id}
96
+ disabled={isDisabled}
97
+ />
98
+ <chakra.div
99
+ {...getLabelProps()}
100
+ __css={styles.container}
101
+ data-checked={dataAttr(state.isChecked)}
102
+ data-hover={dataAttr(state.isHovered)}
103
+ data-focus={dataAttr(state.isFocused)}
104
+ data-active={dataAttr(state.isActive)}
105
+ data-disabled={dataAttr(state.isDisabled)}
106
+ >
107
+ {icon && (
108
+ <chakra.span __css={styles.icon}>
109
+ {state.isChecked ? icon.checked : icon.default}
110
+ </chakra.span>
111
+ )}
112
+ {chipType !== "icon" && (
113
+ <chakra.span __css={styles.label} {...getCheckboxProps()}>
114
+ {children}
115
+ </chakra.span>
116
+ )}
105
117
 
106
- <chakra.span __css={styles.label} {...getCheckboxProps()}>
107
- {chipType !== "icon" && children}
108
- </chakra.span>
109
- {chipType === "filter" && state.isChecked && (
110
- <CloseOutline24Icon marginLeft={1.5} />
111
- )}
112
- </chakra.div>
113
- </chakra.label>
114
- );
115
- });
118
+ {chipType === "filter" && state.isChecked && (
119
+ <CloseOutline24Icon marginLeft={1.5} />
120
+ )}
121
+ </chakra.div>
122
+ </chakra.label>
123
+ );
124
+ },
125
+ );
@@ -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={inputId}
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}>{label}</FormLabel>
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
- const SubtractIcon = (props: BoxProps & { stepLabel: number }) => (
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
- {props.stepLabel > 1 && (
182
- <chakra.span paddingRight="1">{props.stepLabel.toString()}</chakra.span>
183
+ {stepLabel > 1 && (
184
+ <chakra.span paddingRight="1">{stepLabel.toString()}</chakra.span>
183
185
  )}
184
186
  </>
185
187
  );
186
188
 
187
- const AddIcon = (props: BoxProps & { stepLabel: number }) => (
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
- {props.stepLabel > 1 && (
216
- <chakra.span paddingRight="1">{props.stepLabel.toString()}</chakra.span>
217
+ {stepLabel > 1 && (
218
+ <chakra.span paddingRight="1">{stepLabel.toString()}</chakra.span>
217
219
  )}
218
220
  </>
219
221
  );