@microbit/ui 0.1.0-alpha.22 → 0.1.0-alpha.24

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.
Files changed (97) hide show
  1. package/LICENSE.md +5 -5
  2. package/README.md +40 -13
  3. package/lang/ui.ca.json +12 -12
  4. package/lang/ui.cy.json +4 -4
  5. package/lang/ui.de.json +6 -6
  6. package/lang/ui.es-es.json +5 -5
  7. package/lang/ui.fr.json +6 -6
  8. package/lang/ui.ga-ie.json +6 -6
  9. package/lang/ui.it.json +4 -4
  10. package/lang/ui.ja.json +7 -7
  11. package/lang/ui.ko.json +6 -6
  12. package/lang/ui.lo.json +58 -0
  13. package/lang/ui.nl.json +9 -9
  14. package/lang/ui.pl.json +8 -8
  15. package/lang/ui.pt-br.json +7 -7
  16. package/lang/ui.vi.json +58 -0
  17. package/lang/ui.zh-cn.json +6 -6
  18. package/lang/ui.zh-tw.json +7 -7
  19. package/package.json +1 -1
  20. package/src/Avatar.recipe.ts +16 -20
  21. package/src/Avatar.tsx +31 -29
  22. package/src/Breadcrumb.recipe.ts +3 -7
  23. package/src/Breadcrumb.tsx +6 -8
  24. package/src/Button.recipe.ts +22 -33
  25. package/src/Button.tsx +10 -12
  26. package/src/ButtonGroup.tsx +10 -9
  27. package/src/Card.recipe.ts +1 -2
  28. package/src/Card.tsx +2 -1
  29. package/src/Checkbox.recipe.ts +7 -9
  30. package/src/Checkbox.tsx +2 -3
  31. package/src/CheckboxGroup.tsx +5 -7
  32. package/src/CloseButton.tsx +2 -2
  33. package/src/CloseIcon.tsx +6 -4
  34. package/src/Code.tsx +1 -1
  35. package/src/Collapse.tsx +13 -14
  36. package/src/Divider.tsx +3 -3
  37. package/src/Drawer.recipe.ts +4 -5
  38. package/src/Drawer.tsx +3 -4
  39. package/src/Fade.tsx +6 -10
  40. package/src/Field.recipe.ts +9 -12
  41. package/src/Field.tsx +16 -18
  42. package/src/GridList.recipe.ts +1 -2
  43. package/src/Heading.recipe.ts +5 -5
  44. package/src/Heading.tsx +3 -3
  45. package/src/Icon.tsx +7 -11
  46. package/src/IconButton.tsx +1 -1
  47. package/src/Image.tsx +1 -1
  48. package/src/Input.recipe.ts +5 -6
  49. package/src/Input.tsx +4 -4
  50. package/src/InputGroup.tsx +4 -5
  51. package/src/Kbd.tsx +1 -1
  52. package/src/Link.tsx +2 -2
  53. package/src/LinkBox.tsx +2 -3
  54. package/src/LinkButton.tsx +4 -4
  55. package/src/List.tsx +5 -7
  56. package/src/Menu.recipe.ts +15 -16
  57. package/src/Menu.tsx +9 -13
  58. package/src/Modal.recipe.ts +7 -8
  59. package/src/Modal.tsx +19 -24
  60. package/src/NativeSelect.tsx +16 -16
  61. package/src/NumberField.recipe.ts +8 -10
  62. package/src/NumberField.tsx +4 -4
  63. package/src/PopoverArrow.tsx +1 -2
  64. package/src/ProgressBar.tsx +2 -3
  65. package/src/Radio.recipe.ts +8 -9
  66. package/src/Radio.tsx +2 -2
  67. package/src/RadioGroup.tsx +4 -5
  68. package/src/Select.recipe.ts +9 -9
  69. package/src/Select.tsx +8 -9
  70. package/src/Skeleton.tsx +13 -15
  71. package/src/Slide.tsx +2 -2
  72. package/src/Slider.recipe.ts +11 -14
  73. package/src/Slider.tsx +3 -7
  74. package/src/Spinner.tsx +6 -9
  75. package/src/Svg.tsx +2 -3
  76. package/src/Switch.recipe.ts +4 -5
  77. package/src/Switch.tsx +3 -4
  78. package/src/Text.recipe.ts +4 -7
  79. package/src/Text.tsx +2 -2
  80. package/src/TextField.tsx +3 -4
  81. package/src/Toast.recipe.ts +43 -11
  82. package/src/Toast.tsx +29 -28
  83. package/src/Tooltip.recipe.ts +4 -9
  84. package/src/Tooltip.tsx +9 -11
  85. package/src/TooltipButton.tsx +1 -2
  86. package/src/UnmountCallback.tsx +2 -2
  87. package/src/VisuallyHidden.tsx +1 -1
  88. package/src/base-preset.ts +40 -44
  89. package/src/button-icon.ts +2 -3
  90. package/src/dense-preset.ts +6 -7
  91. package/src/hooks/useBreakpointValue.ts +4 -4
  92. package/src/hooks/useClipboard.ts +5 -6
  93. package/src/hooks/useDisclosure.ts +4 -5
  94. package/src/hooks/useMediaQuery.ts +3 -4
  95. package/src/hooks/usePrevious.ts +1 -4
  96. package/src/index.ts +3 -3
  97. package/src/system.ts +2 -2
@@ -6,11 +6,10 @@
6
6
  import { defineSlotRecipe } from "@pandacss/dev";
7
7
 
8
8
  /**
9
- * Radio slot recipe — Chakra's radio with the default blue colorScheme
10
- * (light mode) and its sm/md/lg size scale: the checkbox control rounded
11
- * fully, with a 50% `currentColor` dot when selected instead of the check
12
- * glyph. As with the checkbox, `borderColor: inherit` picks up a
13
- * `borderColor` set on the root.
9
+ * Radio slot recipe — the checkbox control rounded fully, with a 50%
10
+ * `currentColor` dot when selected instead of the check glyph, across the
11
+ * same sm/md/lg size scale. As with the checkbox, `borderColor: inherit`
12
+ * picks up a `borderColor` set on the root.
14
13
  *
15
14
  * State styling keys off data attributes stamped by the shared-ui Radio
16
15
  * (react-aria provides the state via render props).
@@ -55,7 +54,7 @@ export const radio = defineSlotRecipe({
55
54
  bg: "controlCheckedHoverBg",
56
55
  borderColor: "controlCheckedHoverBg",
57
56
  },
58
- // Chakra's radio dot.
57
+ // The radio dot.
59
58
  _before: {
60
59
  content: '""',
61
60
  display: "inline-block",
@@ -66,8 +65,8 @@ export const radio = defineSlotRecipe({
66
65
  bg: "currentColor",
67
66
  },
68
67
  },
69
- // Chakra's disabled greys; the selected block restates _hover so the
70
- // widened native-:hover condition can't re-tint a disabled control.
68
+ // Disabled greys; the selected block restates _hover so the widened
69
+ // native-:hover condition can't re-tint a disabled control.
71
70
  "&[data-disabled]": {
72
71
  bg: "gray.100",
73
72
  borderColor: "gray.100",
@@ -89,7 +88,7 @@ export const radio = defineSlotRecipe({
89
88
  },
90
89
  },
91
90
  variants: {
92
- // Chakra's Radio size scale (the Checkbox control scale).
91
+ // The sm/md/lg size scale; control dimensions match the checkbox's.
93
92
  size: {
94
93
  sm: {
95
94
  control: { width: "3", height: "3" },
package/src/Radio.tsx CHANGED
@@ -22,8 +22,8 @@ export interface RadioProps
22
22
  }
23
23
 
24
24
  /**
25
- * Radio — react-aria-components <Radio> styled like Chakra's radio. Must be
26
- * rendered inside a RadioGroup. Children render as the label.
25
+ * Radio — a styled react-aria-components <Radio>. Must be rendered inside a
26
+ * RadioGroup. Children render as the label.
27
27
  */
28
28
  export const Radio = ({
29
29
  size,
@@ -16,8 +16,8 @@ export interface RadioGroupProps
16
16
  extends Omit<RACRadioGroupProps, "className" | "style">,
17
17
  FieldSupportProps {
18
18
  /**
19
- * Visible label for the group (Chakra's FormLabel above it). Use
20
- * `aria-label` instead where the design has none.
19
+ * Visible label for the group. Use `aria-label` instead where the design
20
+ * has none.
21
21
  */
22
22
  label?: ReactNode;
23
23
  /** Label style overrides. */
@@ -29,9 +29,8 @@ export interface RadioGroupProps
29
29
 
30
30
  /**
31
31
  * RadioGroup — react-aria-components <RadioGroup> for a set of Radios. Beyond
32
- * the optional field chrome (label/helperText/errorMessage Chakra's
33
- * FormControl parts) it carries no styling of its own: compose with Stack for
34
- * layout, as Chakra call sites did.
32
+ * the optional field chrome (label/helperText/errorMessage) it carries no
33
+ * styling of its own: compose with Stack for layout.
35
34
  */
36
35
  export const RadioGroup = ({
37
36
  label,
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import { defineSlotRecipe } from "@pandacss/dev";
7
7
 
8
- // Chakra's transition.property.common, inlined (Panda has no transitionProperty
9
- // token category).
8
+ // The common transition-property list, inlined (Panda has no
9
+ // transitionProperty token category).
10
10
  const transitionCommon =
11
11
  "background-color, border-color, color, fill, stroke, opacity, box-shadow, transform";
12
12
 
@@ -16,9 +16,9 @@ const transitionCommon =
16
16
  * the two differ only in what the control is: keeping them together is what
17
17
  * stops a searchable and a non-searchable picker drifting apart visually.
18
18
  *
19
- * `trigger` is styled from the Chakra outline Input field so a select sits
20
- * level with a TextField beside it; `content` matches the `menu` recipe's card
21
- * so every dropdown surface in the family agrees.
19
+ * `trigger` matches the `input` recipe's outline field so a select sits level
20
+ * with a TextField beside it; `content` matches the `menu` recipe's card so
21
+ * every dropdown surface in the family agrees.
22
22
  *
23
23
  * Apps restyle it through the `variant` group — classroom's `classroom`
24
24
  * variant is the rounded pill its join form uses.
@@ -144,10 +144,10 @@ export const select = defineSlotRecipe({
144
144
  outline: "none",
145
145
  },
146
146
  content: {
147
- // Line the card up with the control, as a select should and as
148
- // react-select did. `Select` gets this from RAC, whose trigger is the
149
- // button it measures; `ComboBox` measures its own control and sets the
150
- // width inline, because RAC's var is the *input's* width there.
147
+ // Line the card up with the control, as a select should. `Select` gets
148
+ // this from RAC, whose trigger is the button it measures; `ComboBox`
149
+ // measures its own control and sets the width inline, because RAC's var
150
+ // is the *input's* width there.
151
151
  minWidth: "var(--trigger-width)",
152
152
  display: "flex",
153
153
  flexDirection: "column",
package/src/Select.tsx CHANGED
@@ -52,8 +52,8 @@ export interface SelectProps<T extends object>
52
52
  /** Label style overrides. */
53
53
  labelCss?: SystemStyleObject;
54
54
  /**
55
- * Shown in the trigger while nothing is chosen (Chakra's placeholder).
56
- * Defaults to a translated "Select an item".
55
+ * Shown in the trigger while nothing is chosen. Defaults to a translated
56
+ * "Select an item".
57
57
  */
58
58
  placeholder?: string;
59
59
  /** `SelectOption`s. */
@@ -68,9 +68,9 @@ export interface SelectProps<T extends object>
68
68
  /** Placement of the dropdown relative to the trigger. */
69
69
  placement?: PopoverProps["placement"];
70
70
  /**
71
- * Cap the dropdown's height (react-select's `maxMenuHeight`). A prop rather
72
- * than a `contentCss` rule because RAC writes its own max-height inline
73
- * while positioning, which beats any class.
71
+ * Cap the dropdown's height. A prop rather than a `contentCss` rule because
72
+ * RAC writes its own max-height inline while positioning, which beats any
73
+ * class.
74
74
  */
75
75
  maxHeight?: number;
76
76
  /** Per-instance overrides for the trigger (the button the value sits in). */
@@ -81,9 +81,8 @@ export interface SelectProps<T extends object>
81
81
  }
82
82
 
83
83
  /**
84
- * Select — a listbox behind a button, for choosing one of a known set.
85
- * Replaces Chakra-era react-select at non-searchable call sites; use ComboBox
86
- * where the user should be able to type to filter.
84
+ * Select — a listbox behind a button, for choosing one of a known set. Use
85
+ * ComboBox where the user should be able to type to filter.
87
86
  */
88
87
  export const Select = <T extends object>({
89
88
  label,
@@ -103,7 +102,7 @@ export const Select = <T extends object>({
103
102
  ...props
104
103
  }: SelectProps<T>) => {
105
104
  // splitVariantProps, not a hand-picked list: an app preset can add variant
106
- // groups to the recipe and they have to reach it (playbook gotcha #37).
105
+ // groups to the recipe and they have to reach it.
107
106
  const [variantProps, rest] = select.splitVariantProps(props);
108
107
  const intl = useIntl();
109
108
  const slots = select(variantProps);
package/src/Skeleton.tsx CHANGED
@@ -9,12 +9,10 @@ import { SystemStyleObject } from "styled-system/types";
9
9
 
10
10
  /**
11
11
  * The placeholder block, as an object rather than a precomputed class so a
12
- * caller's `css` is merged into one `css()` call and its overrides win
13
- * (playbook gotcha #8).
12
+ * caller's `css` is merged into one `css()` call and its overrides win.
14
13
  *
15
- * The colours flow through the same pair of custom properties Chakra used,
16
- * so a call site can retint one skeleton without knowing how the animation
17
- * works.
14
+ * The colours flow through a pair of custom properties, so a call site can
15
+ * retint one skeleton without knowing how the animation works.
18
16
  */
19
17
  const skeletonBase: SystemStyleObject = {
20
18
  "--skeleton-start-color": "token(colors.gray.100)",
@@ -30,8 +28,8 @@ const skeletonBase: SystemStyleObject = {
30
28
  color: "transparent",
31
29
  pointerEvents: "none",
32
30
  userSelect: "none",
33
- // Chakra hid the content rather than unmounting it, so a skeleton sized
34
- // from real children keeps their dimensions.
31
+ // The content is hidden rather than unmounted, so a skeleton sized from
32
+ // real children keeps their dimensions.
35
33
  "&::before, &::after, *": { visibility: "hidden" },
36
34
  animation:
37
35
  "skeletonFade var(--skeleton-speed, 0.8s) linear infinite alternate",
@@ -42,7 +40,7 @@ export interface SkeletonProps
42
40
  extends Omit<HTMLAttributes<HTMLDivElement>, "color"> {
43
41
  /** Show the children instead of the placeholder. */
44
42
  isLoaded?: boolean;
45
- /** Seconds per pulse (Chakra's `speed`, default 0.8). */
43
+ /** Seconds per pulse (default 0.8). */
46
44
  speed?: number;
47
45
  children?: ReactNode;
48
46
  /** Per-instance style overrides, merged after the base. */
@@ -51,11 +49,11 @@ export interface SkeletonProps
51
49
  }
52
50
 
53
51
  /**
54
- * Skeleton — Chakra's loading placeholder: a block pulsing between two greys
55
- * until its content is ready.
52
+ * Skeleton — a loading placeholder: a block pulsing between two greys until
53
+ * its content is ready.
56
54
  *
57
- * Chakra faded the real content in over 0.4s when `isLoaded` turned true;
58
- * here it simply appears. Wrap in `Fade` where that transition matters.
55
+ * Content simply appears when `isLoaded` turns true; wrap in `Fade` where a
56
+ * transition matters.
59
57
  */
60
58
  export const Skeleton = ({
61
59
  isLoaded,
@@ -93,7 +91,7 @@ export const Skeleton = ({
93
91
  };
94
92
 
95
93
  export interface SkeletonTextProps extends SkeletonProps {
96
- /** How many lines to draw (Chakra's default is 3). */
94
+ /** How many lines to draw (default 3). */
97
95
  noOfLines?: number;
98
96
  /** Gap between the lines. Any CSS length. */
99
97
  spacing?: string;
@@ -103,7 +101,7 @@ export interface SkeletonTextProps extends SkeletonProps {
103
101
 
104
102
  /**
105
103
  * SkeletonText — a paragraph-shaped `Skeleton`: evenly spaced lines, the last
106
- * one short, as Chakra drew them.
104
+ * one short.
107
105
  */
108
106
  export const SkeletonText = ({
109
107
  noOfLines = 3,
@@ -137,7 +135,7 @@ export const SkeletonText = ({
137
135
  speed={speed}
138
136
  style={{
139
137
  height: skeletonHeight,
140
- // Chakra's shape: a last line at 80%, and no gap after it.
138
+ // The last line is drawn at 80%, with no gap after it.
141
139
  width: noOfLines > 1 && index === noOfLines - 1 ? "80%" : "100%",
142
140
  marginBottom: index === noOfLines - 1 ? "0" : spacing,
143
141
  }}
package/src/Slide.tsx CHANGED
@@ -17,8 +17,8 @@ export interface SlideProps {
17
17
  }
18
18
 
19
19
  /**
20
- * Slide — Chakra's Slide transition, bottom edge only (add other directions
21
- * when a use appears): a full-width panel pinned to the viewport bottom,
20
+ * Slide — a slide-in transition, bottom edge only (add other directions when
21
+ * a use appears): a full-width panel pinned to the viewport bottom,
22
22
  * translated offscreen when closed. Content stays mounted throughout, so
23
23
  * closing doesn't drop in-flight state and the exit animates.
24
24
  */
@@ -6,21 +6,18 @@
6
6
  import { defineSlotRecipe } from "@pandacss/dev";
7
7
 
8
8
  /**
9
- * Slider slot recipe — Chakra's horizontal md slider (3.5-token thumb, 1-token
10
- * gray.200 track, blue filled track; light mode). Consumed by the shared-ui
11
- * Slider, which maps the slots onto react-aria-components'
12
- * Slider/SliderTrack/SliderThumb.
9
+ * Slider slot recipe — a horizontal slider (3.5-token thumb, 1-token gray.200
10
+ * track, blue filled track). Consumed by the shared-ui Slider, which maps the
11
+ * slots onto react-aria-components' Slider/SliderTrack/SliderThumb.
13
12
  *
14
- * Geometry matches Chakra's DOM: the root is thumb-height with NO horizontal
15
- * padding, the track is absolutely centred inside it at full width, and the
16
- * thumb overhangs the track ends at 0%/100%. Call sites position overlays
17
- * (marks, value labels) against that root box, so Chakra-era offsets work
18
- * unchanged. Sizes are tokens, not px, so apps with resized scales (e.g.
19
- * python-editor's ×0.88) get their Chakra-equivalent geometry.
13
+ * Geometry: the root is thumb-height with NO horizontal padding, the track is
14
+ * absolutely centred inside it at full width, and the thumb overhangs the
15
+ * track ends at 0%/100%. Call sites position overlays (marks, value labels)
16
+ * against that root box. Sizes are tokens, not px, so apps with resized
17
+ * scales (e.g. python-editor's ×0.88) keep proportional geometry.
20
18
  *
21
- * The `mark` slot is hidden until the slider has focus (Chakra call sites did
22
- * this with `_focusWithin` + a class); the reveal lives here so call sites
23
- * only style the mark's look.
19
+ * The `mark` slot is hidden until the slider has focus; the reveal lives here
20
+ * so call sites only style the mark's look.
24
21
  *
25
22
  * Registered in the base preset (base-preset.ts). No variants, so it
26
23
  * needs no `staticCss` entry.
@@ -33,7 +30,7 @@ export const slider = defineSlotRecipe({
33
30
  position: "relative",
34
31
  display: "block",
35
32
  width: "100%",
36
- // Thumb-height, like Chakra's container; the track centres inside.
33
+ // Thumb-height; the track centres inside.
37
34
  height: "3.5",
38
35
  touchAction: "none",
39
36
  "&:focus-within [data-part='mark']": {
package/src/Slider.tsx CHANGED
@@ -33,7 +33,7 @@ export interface SliderProps {
33
33
  thumbCss?: SystemStyleObject;
34
34
  /**
35
35
  * Positioned at the current value along the track and shown while the
36
- * slider has focus (Chakra's SliderMark usage).
36
+ * slider has focus.
37
37
  */
38
38
  mark?: ReactNode;
39
39
  markCss?: SystemStyleObject;
@@ -45,8 +45,7 @@ export interface SliderProps {
45
45
  */
46
46
  children?: ReactNode;
47
47
  /**
48
- * Tooltip-styled bubble anchored above the thumb (Chakra's
49
- * Tooltip-around-SliderThumb pattern). Rendered only while
48
+ * Tooltip-styled bubble anchored above the thumb. Rendered only while
50
49
  * `isThumbTooltipOpen`; drive it from hover/focus, e.g. via
51
50
  * `onThumbFocusChange` and mouse handlers on an enclosing element.
52
51
  */
@@ -56,10 +55,7 @@ export interface SliderProps {
56
55
  onThumbFocusChange?: (isFocused: boolean) => void;
57
56
  }
58
57
 
59
- /**
60
- * Slider — react-aria-components <Slider> styled like Chakra's horizontal md
61
- * slider.
62
- */
58
+ /** Slider — a styled horizontal react-aria-components <Slider>. */
63
59
  export const Slider = ({
64
60
  value,
65
61
  onChange,
package/src/Spinner.tsx CHANGED
@@ -9,28 +9,25 @@ import { dataAttrs } from "./data-attrs";
9
9
  import { SystemStyleObject } from "styled-system/types";
10
10
 
11
11
  export interface SpinnerProps {
12
- /** Chakra Spinner sizes: sm 1rem, md 1.5rem (default). */
12
+ /** sm is 1rem, md 1.5rem (default). */
13
13
  size?: "sm" | "md";
14
14
  /**
15
- * Revolution time (Chakra's `speed`, default 0.45s). Under
16
- * prefers-reduced-motion the spin is slowed to ~3x this value.
15
+ * Revolution time (default 0.45s). Under prefers-reduced-motion the spin is
16
+ * slowed to ~3x this value.
17
17
  */
18
18
  speed?: string;
19
19
  /** Per-instance style overrides, merged after the base. */
20
20
  css?: SystemStyleObject;
21
21
  className?: string;
22
- /**
23
- * Accessible name. Required: Chakra's Spinner announced a visually hidden
24
- * "Loading..." by default, so a nameless spinner would regress on it.
25
- */
22
+ /** Accessible name. Required: a spinner must announce what is loading. */
26
23
  "aria-label": string;
27
24
  /** `data-*` attributes land on the spinner, for tests that wait on it. */
28
25
  [key: `data-${string}`]: unknown;
29
26
  }
30
27
 
31
28
  /**
32
- * Spinner — Chakra's border-based spinner (currentColor with transparent
33
- * bottom/left quadrants).
29
+ * Spinner — a border-based spinner (currentColor with transparent bottom/left
30
+ * quadrants).
34
31
  */
35
32
  export const Spinner = ({
36
33
  size = "md",
package/src/Svg.tsx CHANGED
@@ -6,10 +6,9 @@
6
6
  import { styled } from "styled-system/jsx";
7
7
 
8
8
  /**
9
- * Svg — a Panda-styled svg element with Chakra Icon's base sizing (1em,
9
+ * Svg — a Panda-styled svg element with Icon's base sizing (1em,
10
10
  * inline-block). For custom-path icons; react-icons glyphs use `Icon`.
11
- * As a styled-factory component its call-site style props are extracted
12
- * (unlike style props forwarded through a plain wrapper — gotcha #9).
11
+ * As a styled-factory component its call-site style props are extracted.
13
12
  */
14
13
  export const Svg = styled("svg", {
15
14
  base: {
@@ -6,9 +6,8 @@
6
6
  import { defineSlotRecipe } from "@pandacss/dev";
7
7
 
8
8
  /**
9
- * Switch slot recipe Chakra's switch with the default blue colorScheme
10
- * (light mode) and its sm/md/lg size scale. The track has a 2px inset; the
11
- * thumb matches the track height and slides by the track width/height
9
+ * Switch slot recipe with an sm/md/lg size scale. The track has a 2px inset;
10
+ * the thumb matches the track height and slides by the track width/height
12
11
  * difference when selected.
13
12
  *
14
13
  * State styling keys off data attributes stamped by the shared-ui Switch
@@ -90,8 +89,8 @@ export const switchRecipe = defineSlotRecipe({
90
89
  label: { marginStart: "0", marginEnd: "3" },
91
90
  },
92
91
  },
93
- // Chakra's Switch size scale (track width x height; the selected-thumb
94
- // translate is the difference between them).
92
+ // Track width x height per size; the selected-thumb translate is the
93
+ // difference between them.
95
94
  size: {
96
95
  sm: {
97
96
  track: { width: "1.375rem", height: "3" },
package/src/Switch.tsx CHANGED
@@ -31,10 +31,9 @@ export interface SwitchProps
31
31
  }
32
32
 
33
33
  /**
34
- * Switch — react-aria-components <Switch> styled like Chakra's switch.
35
- * Children render as the label; pass `aria-label` for label-less switches.
36
- * `labelPosition="start"` is the settings-row layout: label first, switch at
37
- * the row's end.
34
+ * Switch — a styled react-aria-components <Switch>. Children render as the
35
+ * label; pass `aria-label` for label-less switches. `labelPosition="start"`
36
+ * is the settings-row layout: label first, switch at the row's end.
38
37
  */
39
38
  export const Switch = ({
40
39
  size,
@@ -6,13 +6,10 @@
6
6
  import { defineRecipe } from "@pandacss/dev";
7
7
 
8
8
  /**
9
- * Text recipe — Chakra's <Text> had no styles of its own, but an app theme
10
- * could give it sizes and a default size via `components.Text`
11
- * (python-editor's did: sm/md with a default of md, which its shrunken
12
- * fontSize scale renders at 0.9rem). A config recipe so an app preset can
13
- * restore that: extend `defaultVariants` to set an app-wide default size.
14
- * No default here — with no `size`, Text inherits like Chakra's default,
15
- * which is what the other family apps expect.
9
+ * Text recipe — sizes only, no default: with no `size`, Text inherits, which
10
+ * is what most family apps expect. A config recipe so an app preset can set
11
+ * an app-wide default size by extending `defaultVariants` (python-editor
12
+ * defaults to md, which its shrunken fontSize scale renders at 0.9rem).
16
13
  *
17
14
  * Registered in the base preset (base-preset.ts).
18
15
  */
package/src/Text.tsx CHANGED
@@ -8,9 +8,9 @@ import { text } from "styled-system/recipes";
8
8
 
9
9
  /**
10
10
  * Text — a paragraph that accepts Panda style props. Use `as` to render a
11
- * different element (`span`, `div`, `h2`). Replaces Chakra's <Text>.
11
+ * different element (`span`, `div`, `h2`).
12
12
  * Backed by the `text` config recipe: `size` picks a type-scale size, and an
13
13
  * app preset can extend the recipe's `defaultVariants` to give all its Text
14
- * a default size (Chakra `components.Text` parity — see Text.recipe.ts).
14
+ * a default size (see Text.recipe.ts).
15
15
  */
16
16
  export const Text = styled("p", text);
package/src/TextField.tsx CHANGED
@@ -26,7 +26,7 @@ export interface TextFieldProps
26
26
  InputVariantProps,
27
27
  FieldSupportProps,
28
28
  FieldLayoutProps {
29
- /** Visible label (Chakra's FormLabel; asterisk added when `isRequired`). */
29
+ /** Visible label (asterisk added when `isRequired`). */
30
30
  label: ReactNode;
31
31
  /** Label style overrides. */
32
32
  labelCss?: SystemStyleObject;
@@ -36,9 +36,8 @@ export interface TextFieldProps
36
36
  }
37
37
 
38
38
  /**
39
- * TextField — a labelled single-line text input, collapsing Chakra's
40
- * FormControl/FormLabel/Input/FormHelperText/FormErrorMessage. The ref is
41
- * forwarded to the input element.
39
+ * TextField — a labelled single-line text input with optional help and error
40
+ * text. The ref is forwarded to the input element.
42
41
  */
43
42
  export const TextField = forwardRef<HTMLInputElement, TextFieldProps>(
44
43
  function TextField(
@@ -6,10 +6,9 @@
6
6
  import { defineSlotRecipe } from "@pandacss/dev";
7
7
 
8
8
  /**
9
- * Toast slot recipe — the Chakra-era solid Alert restyled as a toast (white
10
- * text, teal for every status except error). Status colours come from the
11
- * `toast*Bg` semantic tokens so brand presets can retune them without
12
- * touching the recipe.
9
+ * Toast slot recipe — a solid alert card with white text, teal for every
10
+ * status except error. Status colours come from the `toast*Bg` semantic
11
+ * tokens so brand presets can retune them without touching the recipe.
13
12
  *
14
13
  * Registered in the base preset (base-preset.ts). The status variant
15
14
  * is chosen at runtime from the toast content, so it needs the preset's
@@ -17,13 +16,36 @@ import { defineSlotRecipe } from "@pandacss/dev";
17
16
  */
18
17
  export const toast = defineSlotRecipe({
19
18
  className: "toast",
20
- slots: ["region", "root", "icon", "title", "description", "closeButton"],
19
+ slots: [
20
+ "region",
21
+ "root",
22
+ "content",
23
+ "body",
24
+ "icon",
25
+ "title",
26
+ "description",
27
+ "closeButton",
28
+ ],
21
29
  base: {
22
30
  region: {
23
31
  position: "fixed",
24
32
  top: "4",
25
33
  left: "50%",
26
34
  transform: "translateX(-50%)",
35
+ // Percentage centring of a text-width region lands the toasts on a
36
+ // fractional pixel. Chrome floors ::view-transition-group's transform to
37
+ // a whole CSS pixel, so the snapshot the enter/exit animation displays
38
+ // sits up to 1px left of the element it stands in for, and every toast
39
+ // jumps right as the transition hands back to the real DOM (visible
40
+ // above 1x, where the two no longer round to the same device pixel).
41
+ // Rounding the region's own offsets keeps it on whole pixels so the two
42
+ // agree. round() postdates view transitions in Chrome (130 vs 111), so
43
+ // the guard keeps the plain centring for the versions in between rather
44
+ // than dropping the declarations and losing it altogether.
45
+ "@supports (left: round(50%, 1px))": {
46
+ left: "round(50%, 1px)",
47
+ transform: "translateX(round(-50%, 1px))",
48
+ },
27
49
  zIndex: "toast",
28
50
  display: "flex",
29
51
  flexDirection: "column",
@@ -34,7 +56,6 @@ export const toast = defineSlotRecipe({
34
56
  position: "relative",
35
57
  display: "flex",
36
58
  alignItems: "flex-start",
37
- gap: "3",
38
59
  p: "4",
39
60
  // Leave room for the absolutely-positioned close button plus breathing
40
61
  // space so its hover area never overlaps the title text (24px button at
@@ -47,6 +68,19 @@ export const toast = defineSlotRecipe({
47
68
  maxW: "sm",
48
69
  pointerEvents: "auto",
49
70
  },
71
+ // The icon has to be inside the alert region to be announced with the
72
+ // message, so this row — not the root — is what lays the two out.
73
+ content: {
74
+ display: "flex",
75
+ alignItems: "flex-start",
76
+ gap: "3",
77
+ // Let the text shrink below its content width so long words wrap
78
+ // instead of pushing past the toast's maxW.
79
+ minWidth: 0,
80
+ },
81
+ body: {
82
+ minWidth: 0,
83
+ },
50
84
  icon: {
51
85
  fontSize: "1.25rem",
52
86
  flexShrink: 0,
@@ -58,9 +92,8 @@ export const toast = defineSlotRecipe({
58
92
  mt: "1",
59
93
  },
60
94
  closeButton: {
61
- // A sized box with the glyph centred (like Chakra's CloseButton size
62
- // "sm": 24px box, 2xs glyph) gives padding around the X and a hover
63
- // affordance.
95
+ // A sized box with the glyph centred (24px box, 2xs glyph) gives
96
+ // padding around the X and a hover affordance.
64
97
  position: "absolute",
65
98
  top: "1",
66
99
  insetEnd: "1",
@@ -79,8 +112,7 @@ export const toast = defineSlotRecipe({
79
112
  outline: "none",
80
113
  transitionProperty: "background-color, box-shadow",
81
114
  transitionDuration: "normal",
82
- // Chakra's CloseButton hover is a subtle dark overlay (blackAlpha) in
83
- // light mode, not a bright highlight.
115
+ // Hover is a subtle dark overlay (blackAlpha), not a bright highlight.
84
116
  _hover: { bg: "blackAlpha.100" },
85
117
  _active: { bg: "blackAlpha.200" },
86
118
  _focusVisible: { focusShadow: "outline" },