@vygruppen/spor-react 13.3.2 → 13.4.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.3.2",
4
+ "version": "13.4.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -53,16 +53,22 @@
53
53
  "devDependencies": {
54
54
  "@react-types/datepicker": "^3.10.0",
55
55
  "@react-types/shared": "^3.27.0",
56
+ "@testing-library/jest-dom": "^6.9.1",
57
+ "@testing-library/react": "^16.3.2",
58
+ "@testing-library/user-event": "^14.6.1",
56
59
  "@types/node": "^22.13.4",
57
60
  "@types/react": "19.2.3",
58
61
  "@types/react-dom": "19.2.3",
62
+ "@vitejs/plugin-react": "^6.0.2",
59
63
  "clsx": "^2.1.1",
60
64
  "concurrently": "^9.1.2",
61
65
  "eslint": "^9.39.1",
66
+ "jsdom": "^29.1.1",
62
67
  "react": "19.2.3",
63
68
  "react-dom": "19.2.3",
64
69
  "tsup": "^7.2.0",
65
70
  "typescript": "^5.7.3",
71
+ "vitest": "^4.1.8",
66
72
  "@vygruppen/eslint-config": "2.2.0",
67
73
  "@vygruppen/tsconfig": "0.1.1"
68
74
  },
@@ -77,6 +83,7 @@
77
83
  "typegen": "npx @chakra-ui/cli typegen src/theme/index.ts",
78
84
  "typegen:watch": "npx @chakra-ui/cli typegen src/theme/index.ts --watch",
79
85
  "typegen:strict": "npx @chakra-ui/cli typegen /src/theme/index.ts --strict",
80
- "lint": "eslint ."
86
+ "lint": "eslint .",
87
+ "test": "vitest run"
81
88
  }
82
89
  }
package/setupTests.ts ADDED
@@ -0,0 +1,84 @@
1
+ import "@testing-library/jest-dom";
2
+
3
+ // jsdom doesn't implement window.matchMedia, which is required by next-themes.
4
+ Object.defineProperty(globalThis, "matchMedia", {
5
+ writable: true,
6
+ value: (query: string) => ({
7
+ matches: false,
8
+ media: query,
9
+ onchange: null,
10
+ addListener: () => {},
11
+ removeListener: () => {},
12
+ addEventListener: () => {},
13
+ removeEventListener: () => {},
14
+ dispatchEvent: () => false,
15
+ }),
16
+ });
17
+
18
+ // jsdom doesn't implement HTMLCanvasElement.getContext(), which causes lottie-web to crash.
19
+ // Return a no-op mock context so canvas-based animations are silently skipped in tests.
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ (HTMLCanvasElement.prototype as any).getContext = () =>
22
+ ({
23
+ fillStyle: "",
24
+ strokeStyle: "",
25
+ lineWidth: 0,
26
+ lineCap: "",
27
+ lineJoin: "",
28
+ globalAlpha: 1,
29
+ globalCompositeOperation: "",
30
+ shadowBlur: 0,
31
+ shadowColor: "",
32
+ shadowOffsetX: 0,
33
+ shadowOffsetY: 0,
34
+ font: "",
35
+ textAlign: "",
36
+ textBaseline: "",
37
+ canvas: document.createElement("canvas"),
38
+ save: () => {},
39
+ restore: () => {},
40
+ scale: () => {},
41
+ rotate: () => {},
42
+ translate: () => {},
43
+ transform: () => {},
44
+ setTransform: () => {},
45
+ resetTransform: () => {},
46
+ clearRect: () => {},
47
+ fillRect: () => {},
48
+ strokeRect: () => {},
49
+ beginPath: () => {},
50
+ closePath: () => {},
51
+ moveTo: () => {},
52
+ lineTo: () => {},
53
+ bezierCurveTo: () => {},
54
+ quadraticCurveTo: () => {},
55
+ arc: () => {},
56
+ arcTo: () => {},
57
+ ellipse: () => {},
58
+ rect: () => {},
59
+ fill: () => {},
60
+ stroke: () => {},
61
+ clip: () => {},
62
+ drawImage: () => {},
63
+ createLinearGradient: () => ({ addColorStop: () => {} }),
64
+ createRadialGradient: () => ({ addColorStop: () => {} }),
65
+ createPattern: () => null,
66
+ measureText: () => ({ width: 0 }),
67
+ fillText: () => {},
68
+ strokeText: () => {},
69
+ getImageData: () => ({
70
+ data: new Uint8ClampedArray(0),
71
+ width: 0,
72
+ height: 0,
73
+ }),
74
+ putImageData: () => {},
75
+ createImageData: () => ({
76
+ data: new Uint8ClampedArray(0),
77
+ width: 0,
78
+ height: 0,
79
+ }),
80
+ setLineDash: () => {},
81
+ getLineDash: () => [],
82
+ isPointInPath: () => false,
83
+ isPointInStroke: () => false,
84
+ }) as unknown as CanvasRenderingContext2D;
@@ -207,6 +207,7 @@ export const Combobox = (props: ComboboxProps<object>) => {
207
207
  }
208
208
  placeholder=""
209
209
  data-attachable
210
+ size="md"
210
211
  />
211
212
  <span aria-hidden="true" data-trigger="multiselect"></span>
212
213
  {state.isOpen && !loading && (
@@ -64,6 +64,7 @@ export const CountryCodeSelect = ({
64
64
  lazyMount
65
65
  aria-label={t(texts.countryCode)}
66
66
  sideRadiusVariant="rightSideSquare"
67
+ size={props.size}
67
68
  role="combobox"
68
69
  >
69
70
  {filteredCallingCodes.items.map((code) => (
@@ -4,12 +4,11 @@ import {
4
4
  Field as ChakraField,
5
5
  RecipeVariantProps,
6
6
  Stack,
7
+ Text as ChakraText,
7
8
  useSlotRecipe,
8
9
  } from "@chakra-ui/react";
9
10
  import * as React from "react";
10
11
 
11
- import { Text } from "@/typography";
12
-
13
12
  import { fieldSlotRecipe } from "../theme/slot-recipes/field";
14
13
  import { FloatingLabel } from "./FloatingLabel";
15
14
  import { Label } from "./Label";
@@ -55,6 +54,7 @@ export type FieldBaseProps = {
55
54
  shouldFloat?: boolean;
56
55
  labelAsChild?: boolean;
57
56
  gap?: string | number;
57
+ size?: "sm" | "md";
58
58
  };
59
59
 
60
60
  export type FieldProps = Omit<
@@ -102,10 +102,11 @@ export const Field = ({
102
102
  shouldFloat,
103
103
  labelAsChild,
104
104
  gap,
105
+ size = "md",
105
106
  ...rest
106
107
  } = props;
107
108
  const recipe = useSlotRecipe({ key: "field" });
108
- const styles = recipe();
109
+ const styles = recipe({ size });
109
110
 
110
111
  return (
111
112
  <Stack ref={ref} width="100%" {...rest}>
@@ -120,7 +121,7 @@ export const Field = ({
120
121
  gap={gap}
121
122
  >
122
123
  {label && !floatingLabel && (
123
- <Label asChild={labelAsChild} aria-hidden>
124
+ <Label asChild={labelAsChild} aria-hidden css={styles.label}>
124
125
  {renderLabelWithIndicator(label, labelAsChild)}
125
126
  </Label>
126
127
  )}
@@ -132,6 +133,7 @@ export const Field = ({
132
133
  data-float={shouldFloat ? true : undefined}
133
134
  asChild={labelAsChild}
134
135
  aria-hidden
136
+ css={styles.label}
135
137
  >
136
138
  {renderLabelWithIndicator(label, labelAsChild)}
137
139
  </FloatingLabel>
@@ -143,9 +145,9 @@ export const Field = ({
143
145
  )}
144
146
  </ChakraField.Root>
145
147
  {helperText && (
146
- <Text variant="sm" color="text.subtle">
148
+ <ChakraText data-part="helperText" css={styles.helperText}>
147
149
  {helperText}
148
- </Text>
150
+ </ChakraText>
149
151
  )}
150
152
  </Stack>
151
153
  );
@@ -2,30 +2,19 @@ import { defineStyle, Field, FieldLabelProps } from "@chakra-ui/react";
2
2
 
3
3
  export const FloatingLabel = ({
4
4
  ref,
5
+ css,
5
6
  ...props
6
7
  }: FieldLabelProps & {
7
8
  ref?: React.Ref<HTMLLabelElement | null>;
8
- }) => <Field.Label ref={ref} {...props} css={floatingLabelStyles} />;
9
+ }) => <Field.Label ref={ref} {...props} css={[floatingLabelStyles, css]} />;
9
10
 
10
11
  const floatingLabelStyles = defineStyle({
11
- paddingX: 3,
12
12
  fontWeight: "normal",
13
13
  pointerEvents: "none",
14
14
  zIndex: "docked",
15
15
  _disabled: {
16
16
  opacity: 0.4,
17
17
  },
18
-
19
18
  pos: "absolute",
20
19
  transition: "top 160ms ease, font-size 160ms ease",
21
-
22
- top: "0.9rem",
23
- color: "text",
24
- fontSize: ["mobile.sm", "desktop.sm"],
25
-
26
- "&[data-float]": {
27
- fontSize: ["mobile.2xs", "desktop.2xs"],
28
- color: "text",
29
- top: "0.3rem",
30
- },
31
20
  });
@@ -21,17 +21,17 @@ import { Field, FieldProps } from "./Field";
21
21
  import { useFloatingInputState } from "./useFLoatingInputState";
22
22
 
23
23
  export type InputProps = FieldProps &
24
- Exclude<
25
- ChakraInputProps,
26
- "size" | "label" | "colorPalette" | "placeholder"
27
- > & {
24
+ Exclude<ChakraInputProps, "label" | "colorPalette" | "placeholder"> & {
28
25
  /** The input's label */
29
26
  label?: ReactNode;
30
27
  /** Element that shows up to the left */
31
28
  startElement?: React.ReactNode;
32
29
  /** Element that shows up to the right */
33
30
  endElement?: React.ReactNode;
31
+ /** Override the font size of the start and end elements */
34
32
  fontSize?: string;
33
+
34
+ //size?: "sm" | "md";
35
35
  };
36
36
  /**
37
37
  * Inputs let you enter text or other data.
@@ -75,12 +75,13 @@ export const Input = ({
75
75
  hidden,
76
76
  fontSize,
77
77
  labelAsChild,
78
+ size = "md",
78
79
  ...props
79
80
  }: InputProps & {
80
81
  ref?: React.Ref<HTMLInputElement | null>;
81
82
  }) => {
82
83
  const recipe = useRecipe({ key: "input" });
83
- const [recipeProps, restProps] = recipe.splitVariantProps(props);
84
+ const [recipeProps, restProps] = recipe.splitVariantProps({ size, ...props });
84
85
  const styles = recipe(recipeProps);
85
86
 
86
87
  const labelId = useId();
@@ -98,6 +99,19 @@ export const Input = ({
98
99
  inputRef: inputRef as React.RefObject<HTMLInputElement>,
99
100
  });
100
101
 
102
+ const fontSizeBySize: Record<string, string> = {
103
+ sm: "xs",
104
+ md: "mobile.md",
105
+ };
106
+
107
+ const elementPaddingBySize: Record<string, string> = {
108
+ sm: "2.3rem",
109
+ md: "2.6rem",
110
+ };
111
+ const elementPadding = elementPaddingBySize[size as string] ?? "2.6rem";
112
+ const paddingLeft = elementPadding;
113
+ const paddingRight = elementPadding;
114
+
101
115
  return (
102
116
  <Field
103
117
  invalid={invalid}
@@ -108,21 +122,24 @@ export const Input = ({
108
122
  id={props.id}
109
123
  labelAsChild={labelAsChild}
110
124
  label={
111
- <Flex id={labelId}>
125
+ <Flex
126
+ id={labelId}
127
+ paddingX={startElement && size === "sm" ? 1 : undefined}
128
+ >
112
129
  <Box visibility="hidden">{startElement}</Box>
113
130
  {label}
114
131
  </Flex>
115
132
  }
116
133
  floatingLabel={true}
117
134
  shouldFloat={shouldFloat}
135
+ size={size}
118
136
  >
119
137
  {startElement && (
120
138
  <InputElement
121
- pointerEvents="none"
122
- paddingX={2}
123
139
  aria-hidden="true"
124
- fontSize={fontSize ?? "mobile.md"}
125
140
  aria-labelledby={labelId}
141
+ paddingX={2}
142
+ fontSize={fontSize ?? fontSizeBySize[size as string]}
126
143
  >
127
144
  {startElement}
128
145
  </InputElement>
@@ -132,23 +149,23 @@ export const Input = ({
132
149
  ref={inputRef}
133
150
  focusVisibleRing="outside"
134
151
  overflow="hidden"
135
- paddingLeft={startElement ? "2.6rem" : undefined}
136
- paddingRight={endElement ? "2.6rem" : undefined}
137
152
  {...restProps}
153
+ css={styles}
154
+ paddingLeft={startElement ? paddingLeft : undefined}
155
+ paddingRight={endElement ? paddingRight : undefined}
138
156
  className={`peer ${props.className || ""}`}
139
157
  value={isControlled ? props.value : undefined}
140
158
  onFocus={handleFocus}
141
159
  onBlur={handleBlur}
142
160
  onChange={handleChange}
143
161
  placeholder=""
144
- css={styles}
145
- fontSize={fontSize ?? "mobile.md"}
162
+ fontSize={fontSize}
146
163
  />
147
164
  {endElement && (
148
165
  <InputElement
149
- placement="end"
150
166
  paddingX={2}
151
- fontSize={fontSize ?? "mobile.md"}
167
+ placement="end"
168
+ fontSize={fontSize ?? fontSizeBySize[size as string]}
152
169
  >
153
170
  {endElement}
154
171
  </InputElement>
@@ -1,14 +1,13 @@
1
1
  import { defineStyle, Field, FieldLabelProps } from "@chakra-ui/react";
2
2
 
3
- export const Label = (props: FieldLabelProps) => (
4
- <Field.Label {...props} css={labelStyles} />
3
+ export const Label = ({ css, ...props }: FieldLabelProps) => (
4
+ <Field.Label {...props} css={[labelStyles, css]} />
5
5
  );
6
6
 
7
7
  const labelStyles = defineStyle({
8
8
  fontWeight: "normal",
9
9
  paddingBottom: 1,
10
10
  paddingX: 1,
11
- fontSize: ["mobile.xs", "desktop.xs"],
12
11
  color: "text",
13
12
  pointerEvents: "none",
14
13
  zIndex: "docked",
@@ -55,6 +55,7 @@ export const PasswordInput = ({
55
55
  onVisibleChange,
56
56
  label,
57
57
  startElement,
58
+ size = "md",
58
59
  ...rest
59
60
  } = props;
60
61
 
@@ -82,10 +83,12 @@ export const PasswordInput = ({
82
83
  event.preventDefault();
83
84
  setVisible(!visible);
84
85
  }}
86
+ size={size}
85
87
  >
86
88
  {visible ? t(texts.hidePassword) : t(texts.showPassword)}
87
89
  </VisibilityTrigger>
88
90
  }
91
+ size={size}
89
92
  {...rest}
90
93
  />
91
94
  );
@@ -102,7 +105,6 @@ const VisibilityTrigger = ({
102
105
  ref={ref}
103
106
  type="button"
104
107
  fontWeight="normal"
105
- size="sm"
106
108
  borderRadius="sm"
107
109
  marginRight={1}
108
110
  {...props}
@@ -56,6 +56,7 @@ export const PhoneNumberInput = ({
56
56
  allowedCountryCodes,
57
57
  invalid,
58
58
  errorText,
59
+ size = "md",
59
60
  } = props;
60
61
 
61
62
  const { t } = useTranslation();
@@ -91,11 +92,12 @@ export const PhoneNumberInput = ({
91
92
  variant={variant}
92
93
  allowedCountryCodes={allowedCountryCodes}
93
94
  data-state="on"
94
- invalid={invalid}
95
+ size={size}
95
96
  />
96
97
  <Input
97
98
  ref={ref}
98
99
  type="tel"
100
+ size={size}
99
101
  {...props}
100
102
  value={value.nationalNumber}
101
103
  invalid={invalid}
@@ -1,7 +1,9 @@
1
1
  "use client";
2
2
 
3
3
  import {
4
+ CloseOutline18Icon,
4
5
  CloseOutline24Icon,
6
+ SearchOutline18Icon,
5
7
  SearchOutline24Icon,
6
8
  } from "@vygruppen/spor-icon-react";
7
9
 
@@ -25,7 +27,7 @@ export const SearchInput = ({
25
27
  ref?: React.Ref<HTMLInputElement>;
26
28
  }) => {
27
29
  const { t } = useTranslation();
28
- const { variant = "core", onReset, label, value } = props;
30
+ const { variant = "core", onReset, label, value, size = "md" } = props;
29
31
  const clearButton = onReset && value;
30
32
 
31
33
  return (
@@ -33,8 +35,15 @@ export const SearchInput = ({
33
35
  ref={ref}
34
36
  type="search"
35
37
  variant={variant}
38
+ size={size}
36
39
  {...props}
37
- startElement={<SearchOutline24Icon color="icon" />}
40
+ startElement={
41
+ size == "md" ? (
42
+ <SearchOutline24Icon color="icon" />
43
+ ) : (
44
+ <SearchOutline18Icon color="icon" />
45
+ )
46
+ }
38
47
  endElement={
39
48
  clearButton && (
40
49
  <IconButton
@@ -42,7 +51,9 @@ export const SearchInput = ({
42
51
  type="button"
43
52
  size="sm"
44
53
  aria-label={t(texts.reset)}
45
- icon={<CloseOutline24Icon />}
54
+ icon={
55
+ size == "md" ? <CloseOutline24Icon /> : <CloseOutline18Icon />
56
+ }
46
57
  onClick={onReset}
47
58
  />
48
59
  )
@@ -3,7 +3,7 @@
3
3
  import type {
4
4
  CollectionItem,
5
5
  SelectLabelProps,
6
- SelectRootProps as ChakraSelectRootProps,
6
+ SelectRootProps,
7
7
  SystemStyleObject,
8
8
  } from "@chakra-ui/react";
9
9
  import {
@@ -13,10 +13,10 @@ import {
13
13
  Portal,
14
14
  Select as ChakraSelect,
15
15
  useSelectContext,
16
- useSlotRecipe,
17
16
  } from "@chakra-ui/react";
18
17
  import {
19
18
  CheckmarkFill18Icon,
19
+ DropdownDownFill18Icon,
20
20
  DropdownDownFill24Icon,
21
21
  } from "@vygruppen/spor-icon-react";
22
22
  import * as React from "react";
@@ -26,7 +26,7 @@ import { CloseButton } from "@/button";
26
26
  import { Badge } from "..";
27
27
  import { Field, FieldProps } from "./Field";
28
28
 
29
- export type SelectProps = ChakraSelectRootProps &
29
+ export type SelectProps = SelectRootProps &
30
30
  FieldProps & {
31
31
  label?: string;
32
32
  };
@@ -68,6 +68,7 @@ export const Select = ({
68
68
  }) => {
69
69
  const {
70
70
  variant = "core",
71
+ size = "md",
71
72
  children,
72
73
  positioning,
73
74
  label,
@@ -77,8 +78,6 @@ export const Select = ({
77
78
  css,
78
79
  ...rest
79
80
  } = props;
80
- const recipe = useSlotRecipe({ key: "select" });
81
- const styles = recipe({ variant });
82
81
 
83
82
  return (
84
83
  <Field
@@ -94,16 +93,14 @@ export const Select = ({
94
93
  ref={ref}
95
94
  positioning={{ sameWidth: true, ...positioning }}
96
95
  variant={variant}
97
- css={styles.root}
96
+ size={size}
98
97
  position="relative"
99
98
  >
100
- <SelectTrigger data-attachable>
99
+ <SelectTrigger data-attachable size={size}>
101
100
  <SelectValueText withPlaceholder={!!label} />
102
101
  </SelectTrigger>
103
- {label && <SelectLabel css={styles.label}>{label}</SelectLabel>}
104
- <SelectContent css={styles.selectContent} baseStyle={css}>
105
- {children}
106
- </SelectContent>
102
+ {label && <SelectLabel>{label}</SelectLabel>}
103
+ <SelectContent baseStyle={css}>{children}</SelectContent>
107
104
  </ChakraSelect.Root>
108
105
  </Field>
109
106
  );
@@ -132,14 +129,12 @@ export const SelectItem = ({
132
129
  ref?: React.Ref<HTMLDivElement>;
133
130
  }) => {
134
131
  const { item, children, description, ...rest } = props;
135
- const recipe = useSlotRecipe({ key: "select" });
136
- const styles = recipe();
137
132
  const selectContext = useSelectContext();
138
133
  const multiple = selectContext.multiple;
139
134
  const isSelected = selectContext.value.includes(item.value);
140
135
 
141
136
  return (
142
- <ChakraSelect.Item item={item} {...rest} ref={ref} css={styles.item}>
137
+ <ChakraSelect.Item item={item} {...rest} ref={ref}>
143
138
  {multiple && (
144
139
  <ChakraCheckbox.Root checked={isSelected} pointerEvents="none">
145
140
  <ChakraCheckbox.Control>
@@ -149,11 +144,7 @@ export const SelectItem = ({
149
144
  )}
150
145
  <Box width="100%">
151
146
  <ChakraSelect.ItemText display="flex">{children}</ChakraSelect.ItemText>
152
- {description && (
153
- <Box data-part="item-description" css={styles.itemDescription}>
154
- {description}
155
- </Box>
156
- )}
147
+ {description && <Box data-part="item-description">{description}</Box>}
157
148
  </Box>
158
149
 
159
150
  {!multiple && (
@@ -189,29 +180,28 @@ export const SelectItemGroup = function SelectItemGroup({
189
180
  type SelectTriggerProps = ChakraSelect.ControlProps & {
190
181
  clearable?: boolean;
191
182
  children?: React.ReactNode;
183
+ size: "sm" | "md";
192
184
  };
193
185
 
194
186
  export const SelectTrigger = function SelectTrigger({
195
187
  ref,
188
+ size = "md",
196
189
  ...props
197
190
  }: SelectTriggerProps & {
198
191
  ref?: React.Ref<HTMLButtonElement>;
199
192
  }) {
200
193
  const { children, clearable, ...rest } = props;
201
- const recipe = useSlotRecipe({ key: "select" });
202
- const styles = recipe();
203
194
  return (
204
- <ChakraSelect.Control {...rest} css={styles.control}>
205
- <ChakraSelect.Trigger ref={ref} css={styles.trigger}>
206
- {children}
207
- </ChakraSelect.Trigger>
208
- <ChakraSelect.IndicatorGroup
209
- css={styles.indicatorGroup}
210
- data-part="indicator-group"
211
- >
195
+ <ChakraSelect.Control {...rest}>
196
+ <ChakraSelect.Trigger ref={ref}>{children}</ChakraSelect.Trigger>
197
+ <ChakraSelect.IndicatorGroup data-part="indicator-group">
212
198
  {clearable && <SelectClearTrigger />}
213
- <Box css={styles.indicator} data-part="indicator">
214
- <DropdownDownFill24Icon />
199
+ <Box data-part="indicator">
200
+ {size == "md" ? (
201
+ <DropdownDownFill24Icon />
202
+ ) : (
203
+ <DropdownDownFill18Icon />
204
+ )}
215
205
  </Box>
216
206
  </ChakraSelect.IndicatorGroup>
217
207
  </ChakraSelect.Control>
@@ -285,7 +275,7 @@ export const SelectValueText = function SelectValueText({
285
275
  {...rest}
286
276
  ref={ref}
287
277
  placeholder={placeholder}
288
- paddingTop={withPlaceholder ? "4" : "0"}
278
+ data-with-placeholder={withPlaceholder || undefined}
289
279
  >
290
280
  <ChakraSelect.Context>
291
281
  {(select: {
@@ -301,7 +291,7 @@ export const SelectValueText = function SelectValueText({
301
291
  if (children) return children(items);
302
292
  if (multiple) {
303
293
  return (
304
- <Flex gap={0.5} marginBottom={1}>
294
+ <Flex gap={0.5}>
305
295
  {items.map((item) => (
306
296
  <Badge
307
297
  key={select.collection.stringifyItem(item)}
@@ -13,10 +13,6 @@ export const inputRecipe = defineRecipe({
13
13
  transitionDuration: "fast",
14
14
  color: "text",
15
15
  position: "relative",
16
- paddingX: 3,
17
- paddingTop: 3,
18
- height: 8,
19
- fontSize: "mobile.md",
20
16
 
21
17
  _disabled: {
22
18
  backgroundColor: "surface.disabled",
@@ -83,8 +79,23 @@ export const inputRecipe = defineRecipe({
83
79
  },
84
80
  },
85
81
  },
82
+ size: {
83
+ sm: {
84
+ paddingTop: 2,
85
+ height: 7,
86
+ fontSize: "xs",
87
+ paddingX: 2,
88
+ },
89
+ md: {
90
+ paddingX: 3,
91
+ paddingTop: 3,
92
+ height: 8,
93
+ fontSize: "mobile.md",
94
+ },
95
+ },
86
96
  },
87
97
  defaultVariants: {
88
98
  variant: "core",
99
+ size: "md",
89
100
  },
90
101
  });
@@ -201,12 +201,10 @@ export const selectAnatomy = createAnatomy("select").parts(
201
201
  "root",
202
202
  "trigger",
203
203
  "indicatorGroup",
204
- "indicator",
205
- "selectContent",
204
+ "content",
206
205
  "item",
207
206
  "control",
208
207
  "itemText",
209
- "itemDescription",
210
208
  "itemGroup",
211
209
  "itemGroupLabel",
212
210
  "label",
@@ -14,7 +14,6 @@ export const breadcrumbSlotRecipe = defineSlotRecipe({
14
14
  },
15
15
  link: {
16
16
  cursor: "pointer",
17
- padding: 0.5,
18
17
  borderRadius: "xs",
19
18
  },
20
19
  currentLink: {