@vygruppen/spor-react 13.7.2 → 13.8.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,7 +1,7 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
3
  "type": "module",
4
- "version": "13.7.2",
4
+ "version": "13.8.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -47,7 +47,7 @@
47
47
  "react-swipeable": "^7.0.1",
48
48
  "usehooks-ts": "^3.1.0",
49
49
  "@vygruppen/spor-design-tokens": "5.1.1",
50
- "@vygruppen/spor-icon-react": "5.0.3",
50
+ "@vygruppen/spor-icon-react": "5.0.4",
51
51
  "@vygruppen/spor-loader": "0.7.0"
52
52
  },
53
53
  "devDependencies": {
@@ -34,10 +34,10 @@ export const Radio = ({
34
34
  }: RadioProps & {
35
35
  ref?: React.Ref<HTMLInputElement>;
36
36
  }) => {
37
- const { children, inputProps, rootRef, ...rest } = props;
37
+ const { children, inputProps, rootRef, invalid, ...rest } = props;
38
38
 
39
39
  return (
40
- <ChakraRadioGroup.Item ref={rootRef} {...rest}>
40
+ <ChakraRadioGroup.Item ref={rootRef} {...rest} aria-invalid={invalid}>
41
41
  <ChakraRadioGroup.ItemHiddenInput ref={ref} {...inputProps} />
42
42
  <ChakraRadioGroup.ItemIndicator />
43
43
  {children && (
@@ -138,7 +138,7 @@ export const SelectItem = ({
138
138
  {multiple && (
139
139
  <ChakraCheckbox.Root checked={isSelected} pointerEvents="none">
140
140
  <ChakraCheckbox.Control>
141
- <ChakraCheckbox.Indicator />
141
+ <ChakraCheckbox.Indicator marginLeft="1px" />
142
142
  </ChakraCheckbox.Control>
143
143
  </ChakraCheckbox.Root>
144
144
  )}
@@ -47,7 +47,7 @@ export const RadioCard = ({
47
47
  }: RadioCardItemProps & {
48
48
  ref?: React.Ref<HTMLInputElement>;
49
49
  }) => {
50
- const { inputProps, children } = props;
50
+ const { inputProps, children, invalid } = props;
51
51
  const uniqueId = useId();
52
52
  const itemControlId = `radio-card-item-control-${uniqueId}`;
53
53
 
@@ -55,7 +55,7 @@ export const RadioCard = ({
55
55
  inputProps?.["aria-labelledby"] || inputProps?.["aria-label"];
56
56
 
57
57
  return (
58
- <ChakraRadioCard.Item {...props}>
58
+ <ChakraRadioCard.Item {...props} aria-invalid={invalid}>
59
59
  <ChakraRadioCard.ItemHiddenInput
60
60
  aria-labelledby={
61
61
  inputHasAriaLabel ? inputProps?.["aria-labelledby"] : itemControlId
@@ -30,6 +30,25 @@ export const radioCardSlotRecipe = defineSlotRecipe({
30
30
  background: "surface.disabled",
31
31
  color: "text.disabled",
32
32
  },
33
+ _invalid: {
34
+ outlineColor: "outline.error",
35
+ "& .dot": {
36
+ backgroundColor: "outline.error",
37
+ },
38
+ _hover: {
39
+ outlineColor: "outline.error",
40
+ "& .dot": {
41
+ backgroundColor: "outline.error",
42
+ },
43
+ _active: {
44
+ backgroundColor: "surface.critical",
45
+ },
46
+ },
47
+ _checked: {
48
+ outlineColor: "outline.error",
49
+ backgroundColor: "surface.critical",
50
+ },
51
+ },
33
52
  },
34
53
  label: {
35
54
  userSelect: "none",
@@ -60,6 +60,18 @@ export const radioGroupSlotRecipe = defineSlotRecipe({
60
60
  backgroundColor: "outline.disabled",
61
61
  },
62
62
  },
63
+ _invalid: {
64
+ borderColor: "outline.error",
65
+ "& .dot": {
66
+ backgroundColor: "outline.error",
67
+ },
68
+ _hover: {
69
+ borderColor: "outline.error",
70
+ "& .dot": {
71
+ backgroundColor: "outline.error",
72
+ },
73
+ },
74
+ },
63
75
  _focusVisible: {
64
76
  outlineWidth: "2px",
65
77
  outlineColor: "outline.focus",
@@ -101,10 +101,9 @@ export const selectSlotRecipe = defineSlotRecipe({
101
101
  },
102
102
  },
103
103
  item: {
104
- paddingX: 2,
105
- paddingY: 2,
106
- marginY: 1,
107
- marginX: 1,
104
+ px: 2,
105
+ py: 1,
106
+ margin: 1,
108
107
  display: "flex",
109
108
  alignItems: "center",
110
109
  justifyContent: "space-between",
@@ -113,38 +112,28 @@ export const selectSlotRecipe = defineSlotRecipe({
113
112
  color: "text.ghost",
114
113
  cursor: "pointer",
115
114
  outline: "none",
116
- "&[data-highlighted]:hover": {
117
- outlineOffset: "2px",
118
- outline: "2px solid",
119
- outlineColor: "outline.focus",
115
+ _hover: {
120
116
  backgroundColor: "surface.accent.hover",
121
- },
122
- "&[data-highlighted]": {
123
- outlineOffset: "2px",
124
- outline: "2px solid",
125
- outlineColor: "outline.focus",
126
- },
127
- _active: {
128
- backgroundColor: "surface.accent.active",
129
- },
130
- _highlighted: {
131
117
  _active: {
132
- color: "text",
118
+ backgroundColor: "surface.accent.active",
133
119
  },
134
120
  },
135
- _hover: {
136
- backgroundColor: "surface.accent.hover",
137
- },
138
121
  _selected: {
139
122
  backgroundColor: "surface.accent",
140
123
  },
124
+ _highlighted: {
125
+ backgroundColor: "surface.ghost.active",
126
+ _selected: {
127
+ backgroundColor: "surface.accent",
128
+ },
129
+ },
141
130
  _icon: {
142
131
  width: 3,
143
132
  height: 3,
144
133
  },
145
134
  "& [data-part='item-description']": {
146
135
  fontSize: ["mobile.xs", "desktop.xs"],
147
- color: "text.ghost",
136
+ color: "text.subtle",
148
137
  },
149
138
  },
150
139
  control: {
@@ -269,9 +258,7 @@ export const selectSlotRecipe = defineSlotRecipe({
269
258
  },
270
259
  },
271
260
  item: {
272
- paddingX: 2,
273
- paddingY: 1,
274
- fontSize: "xs",
261
+ fontSize: ["mobile.xs", "desktop.xs"],
275
262
  "& [data-part='item-description']": {
276
263
  fontSize: ["mobile.2xs", "desktop.2xs"],
277
264
  },
@@ -16,6 +16,8 @@ export const tabsSlotRecipe = defineSlotRecipe({
16
16
  gap: 0.5,
17
17
  borderRadius: "xl",
18
18
  width: "fit-content",
19
+ position: "relative",
20
+ overflow: "hidden",
19
21
  },
20
22
  trigger: {
21
23
  display: "flex",
@@ -27,6 +29,31 @@ export const tabsSlotRecipe = defineSlotRecipe({
27
29
  height: "100%",
28
30
  whiteSpace: "nowrap",
29
31
  borderRadius: "xl",
32
+ position: "relative",
33
+ ".spor-tabs__list:has(.spor-tabs__indicator) &": {
34
+ transition: "color 0.2s ease",
35
+ },
36
+ _selected: {
37
+ color: "text.brand",
38
+ // @ts-expect-error — valid CSS selector, not recognized by Chakra's types
39
+ ".spor-tabs__list:not(:has(.spor-tabs__indicator)) &[data-selected]": {
40
+ backgroundColor: "surface.brand",
41
+ _hover: {
42
+ backgroundColor: "surface.brand",
43
+ },
44
+ },
45
+ },
46
+ },
47
+ indicator: {
48
+ position: "absolute",
49
+ top: "2.5px",
50
+ left: 0,
51
+ width: "var(--width)",
52
+ height: "var(--height)",
53
+ transform: "translate(var(--x), var(--y))",
54
+ transition: "transform 0.2s ease, width 0.2s ease",
55
+ borderRadius: "xl",
56
+ backgroundColor: "surface.brand",
30
57
  },
31
58
  },
32
59
  variants: {
@@ -65,37 +92,31 @@ export const tabsSlotRecipe = defineSlotRecipe({
65
92
  list: {
66
93
  color: "text.core",
67
94
  border: "sm",
95
+ borderColor: "outline",
68
96
  },
69
97
  trigger: {
70
98
  color: "text.core",
71
99
  border: "md",
72
100
  borderColor: "transparent",
73
- _hover: {
74
- outline: "2px solid",
75
- outlineColor: "outline.core.hover",
76
- outlineOffset: "-2px",
77
- },
78
- _active: {
79
- backgroundColor: "surface.brand.active",
80
- color: "text.brand",
81
- outline: "none",
82
- },
83
- _selected: {
84
- backgroundColor: "surface.brand",
85
- color: "text.brand",
101
+ "&:not([data-selected])": {
86
102
  _hover: {
87
- outline: "none",
103
+ backgroundColor: "surface.ghost.hover",
104
+ _active: {
105
+ backgroundColor: "surface.ghost.active",
106
+ outline: "none",
107
+ outlineColor: "transparent",
108
+ },
88
109
  },
89
110
  },
90
- _disabled: {
91
- backgroundColor: "surface.disabled",
92
- color: "surface.disabled",
93
- },
111
+ },
112
+ _disabled: {
113
+ backgroundColor: "surface.disabled",
114
+ color: "surface.disabled",
94
115
  },
95
116
  },
96
117
  accent: {
97
118
  list: {
98
- backgroundColor: "bg.accent",
119
+ backgroundColor: "surface.accent",
99
120
  color: "text.accent",
100
121
  },
101
122
  trigger: {
@@ -105,23 +126,18 @@ export const tabsSlotRecipe = defineSlotRecipe({
105
126
  backgroundColor: "surface.disabled",
106
127
  color: "icon.disabled",
107
128
  },
108
- _hover: {
109
- backgroundColor: "surface.accent.hover",
110
- _active: {
111
- backgroundColor: "surface.brand.active",
112
- color: "text.brand",
113
- },
114
- },
115
- _selected: {
116
- backgroundColor: "surface.brand",
117
- color: "text.brand",
129
+ "&:not([data-selected])": {
118
130
  _hover: {
119
- backgroundColor: "surface.brand.hover",
120
- color: "text.brand",
121
- outline: "none",
131
+ backgroundColor: "surface.accent.hover",
132
+ _active: {
133
+ backgroundColor: "surface.accent.active",
134
+ },
122
135
  },
123
136
  },
124
137
  },
138
+ indicator: {
139
+ backgroundColor: "surface.brand",
140
+ },
125
141
  },
126
142
  },
127
143
  size: {
@@ -134,6 +150,9 @@ export const tabsSlotRecipe = defineSlotRecipe({
134
150
  paddingX: 2,
135
151
  paddingY: 0,
136
152
  },
153
+ indicator: {
154
+ top: "1px",
155
+ },
137
156
  },
138
157
  sm: {
139
158
  list: {
@@ -163,10 +182,6 @@ export const tabsSlotRecipe = defineSlotRecipe({
163
182
  fontWeight: "bold",
164
183
  fontSize: "sm",
165
184
  paddingX: 3,
166
- _focus: {
167
- border: "md",
168
- borderColor: "surface.accent",
169
- },
170
185
  },
171
186
  },
172
187
  },