@vygruppen/spor-react 13.4.2 → 13.4.4

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,7 +1,7 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
3
  "type": "module",
4
- "version": "13.4.2",
4
+ "version": "13.4.4",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -46,8 +46,8 @@
46
46
  "react-stately": "^3.31.1",
47
47
  "react-swipeable": "^7.0.1",
48
48
  "usehooks-ts": "^3.1.0",
49
- "@vygruppen/spor-design-tokens": "5.0.4",
50
- "@vygruppen/spor-icon-react": "5.0.0",
49
+ "@vygruppen/spor-design-tokens": "5.0.5",
50
+ "@vygruppen/spor-icon-react": "5.0.1",
51
51
  "@vygruppen/spor-loader": "0.7.0"
52
52
  },
53
53
  "devDependencies": {
@@ -46,42 +46,33 @@ export const BaseAlertIcon = ({
46
46
  }: {
47
47
  variant: AlertProps["variant"];
48
48
  }) => {
49
- const css = {
50
- "& path:first-of-type": {
51
- fill: `icon.${variant}`,
52
- },
53
- "& path:not(:first-of-type)": {
54
- fill: `surface.${variant}`,
55
- },
56
- };
57
-
58
49
  switch (variant) {
59
50
  case "info": {
60
- return <InformationFill24Icon css={css} />;
51
+ return <InformationFill24Icon />;
61
52
  }
62
53
  case "success": {
63
- return <SuccessFill24Icon css={css} />;
54
+ return <SuccessFill24Icon />;
64
55
  }
65
56
  case "important": {
66
57
  return <WarningFill24Icon />;
67
58
  }
68
59
  case "alt": {
69
- return <AltTransportFill24Icon css={css} />;
60
+ return <AltTransportFill24Icon />;
70
61
  }
71
62
  case "error": {
72
- return <ErrorFill24Icon css={css} />;
63
+ return <ErrorFill24Icon />;
73
64
  }
74
65
  case "error-secondary": {
75
- return <ErrorOutline24Icon css={css} />;
66
+ return <ErrorOutline24Icon />;
76
67
  }
77
68
  case "neutral": {
78
- return <QuestionFill24Icon css={css} />;
69
+ return <QuestionFill24Icon />;
79
70
  }
80
71
  case "service": {
81
72
  return <ServiceFill24Icon />;
82
73
  }
83
74
  default: {
84
- return <InformationFill24Icon css={css} />;
75
+ return <InformationFill24Icon />;
85
76
  }
86
77
  }
87
78
  };
@@ -72,7 +72,7 @@ export const DateField = ({
72
72
  <DateTimeSegment
73
73
  key={index}
74
74
  segment={segment}
75
- ariaDescription={t(getAriaLabel(segment.type))}
75
+ ariaLabel={t(getAriaLabel(segment.type))}
76
76
  state={state}
77
77
  />
78
78
  ))}
@@ -115,7 +115,7 @@ export const DatePicker = ({
115
115
  const popoverContent = (
116
116
  <ChakraPopover.Positioner>
117
117
  <ChakraPopover.Content css={styles.calendarPopover}>
118
- <ChakraPopover.Body minWidth="20rem">
118
+ <ChakraPopover.Body minWidth="18rem">
119
119
  <Calendar
120
120
  {...calendarProps}
121
121
  variant={variant}
@@ -10,7 +10,7 @@ type DateTimeSegmentProps = PropsWithChildren<DatePickerVariantProps> & {
10
10
  segment: DateSegment;
11
11
  state: DateFieldState;
12
12
  ariaLabel?: string;
13
- ariaDescription?: string;
13
+ ariaLabelledby?: string;
14
14
  };
15
15
  /**
16
16
  * A date time segment is a part of a date or a time stamp.
@@ -24,7 +24,7 @@ export const DateTimeSegment = ({
24
24
  segment,
25
25
  state,
26
26
  ariaLabel,
27
- ariaDescription,
27
+ ariaLabelledby,
28
28
  variant,
29
29
  }: DateTimeSegmentProps & {
30
30
  ref?: React.Ref<HTMLDivElement>;
@@ -59,8 +59,8 @@ export const DateTimeSegment = ({
59
59
  borderRadius="xs"
60
60
  fontSize={["mobile.sm", "desktop.sm"]}
61
61
  css={styles.dateTimeSegment}
62
- aria-label={ariaDescription}
63
- aria-labelledby={ariaLabel}
62
+ aria-label={ariaLabel}
63
+ aria-labelledby={ariaLabelledby}
64
64
  >
65
65
  {isPaddable(segment.type) ? segment.text.padStart(2, "0") : segment.text}
66
66
  </Box>
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { Box, Flex } from "@chakra-ui/react";
2
+ import { Box, Field as ChakraField, Flex } from "@chakra-ui/react";
3
3
  import { CalendarDateTime, Time } from "@internationalized/date";
4
4
  import { useRef } from "react";
5
5
  import { AriaTimeFieldProps, useTimeField } from "react-aria";
@@ -7,6 +7,7 @@ import { DateSegment, TimeFieldState } from "react-stately";
7
7
 
8
8
  import { spor } from "@/util";
9
9
 
10
+ import { createTexts, useTranslation } from "../i18n";
10
11
  import { DateTimeSegment } from "./DateTimeSegment";
11
12
  import { getTimestampFromTime } from "./utils";
12
13
 
@@ -23,6 +24,7 @@ type TimeFieldProps = AriaTimeFieldProps<Time> & {
23
24
  export const TimeField = ({ state, ...props }: TimeFieldProps) => {
24
25
  const ref = useRef<HTMLDivElement>(null);
25
26
  const { labelProps, fieldProps } = useTimeField(props, state, ref);
27
+ const { t } = useTranslation();
26
28
 
27
29
  return (
28
30
  <Box>
@@ -43,10 +45,16 @@ export const TimeField = ({ state, ...props }: TimeFieldProps) => {
43
45
  maxWidth="80%"
44
46
  >
45
47
  {props.label}
48
+ <ChakraField.RequiredIndicator />
46
49
  </spor.label>
47
50
  <Flex {...fieldProps} ref={ref} paddingTop="3" paddingBottom="0.5">
48
51
  {state.segments.map((segment: DateSegment, index) => (
49
- <DateTimeSegment key={index} segment={segment} state={state} />
52
+ <DateTimeSegment
53
+ key={index}
54
+ segment={segment}
55
+ state={state}
56
+ ariaLabel={t(getAriaLabel(segment.type))}
57
+ />
50
58
  ))}
51
59
  </Flex>
52
60
  <input
@@ -57,3 +65,47 @@ export const TimeField = ({ state, ...props }: TimeFieldProps) => {
57
65
  </Box>
58
66
  );
59
67
  };
68
+
69
+ const getAriaLabel = (segmentType: DateSegment["type"]) => {
70
+ switch (segmentType) {
71
+ case "hour": {
72
+ return texts.hour;
73
+ }
74
+ case "minute": {
75
+ return texts.minute;
76
+ }
77
+ case "second": {
78
+ return texts.second;
79
+ }
80
+ default: {
81
+ return texts.default;
82
+ }
83
+ }
84
+ };
85
+
86
+ const texts = createTexts({
87
+ hour: {
88
+ nb: "Velg time",
89
+ nn: "Vel time",
90
+ sv: "Välj timme",
91
+ en: "Choose hour",
92
+ },
93
+ minute: {
94
+ nb: "Velg minutt",
95
+ nn: "Vel minutt",
96
+ sv: "Välj minut",
97
+ en: "Choose minute",
98
+ },
99
+ second: {
100
+ nb: "Velg sekund",
101
+ nn: "Vel sekund",
102
+ sv: "Välj sekund",
103
+ en: "Choose second",
104
+ },
105
+ default: {
106
+ nb: "Velg tid",
107
+ nn: "Vel tid",
108
+ sv: "Välj tid",
109
+ en: "Choose time",
110
+ },
111
+ });
@@ -144,7 +144,6 @@ export const TimePicker = ({
144
144
  opacity={isDisabled ? 0.5 : 1}
145
145
  pointerEvents={isDisabled ? "none" : "auto"}
146
146
  aria-disabled={isDisabled}
147
- aria-live="assertive"
148
147
  aria-label={ariaLabel}
149
148
  position="relative"
150
149
  {...boxProps}
@@ -37,17 +37,7 @@ export const ErrorSummary = ({
37
37
  >
38
38
  {heading && (
39
39
  <Flex css={styles.heading}>
40
- <ErrorFill24Icon
41
- css={{
42
- flexShrink: 0,
43
- "& path:first-of-type": {
44
- fill: `icon.critical`,
45
- },
46
- "& path:not(:first-of-type)": {
47
- fill: `surface.critical`,
48
- },
49
- }}
50
- />
40
+ <ErrorFill24Icon />
51
41
  <Heading as={headingLevel} variant="md" autoId ref={headingRef}>
52
42
  {heading}
53
43
  </Heading>
@@ -14,6 +14,8 @@ export const textareaRecipe = defineRecipe({
14
14
  "&:focus-visible, &:not(:placeholder-shown)": {
15
15
  borderTop: "var(--label-height) solid transparent",
16
16
  },
17
+ fontSize: "mobile.md",
18
+ paddingLeft: 3,
17
19
  },
18
20
  variants: {
19
21
  variant: {
@@ -80,6 +80,7 @@ export const datePickerSlotRecipe = defineSlotRecipe({
80
80
  boxShadow: "md",
81
81
  backgroundColor: "surface.floating",
82
82
  minHeight: "min-content",
83
+ maxWidth: "100vw",
83
84
  },
84
85
  rangeCalendarPopover: {
85
86
  width: "43rem",