@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
package/lang/ui.pl.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "ui.breadcrumb": {
3
- "defaultMessage": "Breadcrumb",
3
+ "defaultMessage": "Ścieżka nawigacji",
4
4
  "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
5
  },
6
6
  "ui.close-action": {
@@ -12,11 +12,11 @@
12
12
  "description": "Accessible label for a ComboBox's dropdown list of suggestions"
13
13
  },
14
14
  "ui.combobox-trigger": {
15
- "defaultMessage": "Wyświetlaj sugestie",
15
+ "defaultMessage": "Pokaż sugestie",
16
16
  "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
17
  },
18
18
  "ui.loading": {
19
- "defaultMessage": "Loading",
19
+ "defaultMessage": "Ładowanie",
20
20
  "description": "Announced by screen readers for a button showing a loading spinner"
21
21
  },
22
22
  "ui.numberfield-decrease": {
@@ -32,7 +32,7 @@
32
32
  "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
33
33
  },
34
34
  "ui.select-row-action": {
35
- "defaultMessage": "Zaznacz",
35
+ "defaultMessage": "Wybierz",
36
36
  "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
37
37
  },
38
38
  "ui.toast-region": {
@@ -40,19 +40,19 @@
40
40
  "description": "Accessible label for the notifications area; count is the number of notifications showing"
41
41
  },
42
42
  "ui.toast-status-error": {
43
- "defaultMessage": "Error",
43
+ "defaultMessage": "Błąd",
44
44
  "description": "Announced by screen readers before an error notification"
45
45
  },
46
46
  "ui.toast-status-info": {
47
- "defaultMessage": "Information",
47
+ "defaultMessage": "Informacja",
48
48
  "description": "Announced by screen readers before an informational notification"
49
49
  },
50
50
  "ui.toast-status-success": {
51
- "defaultMessage": "Success",
51
+ "defaultMessage": "Sukces",
52
52
  "description": "Announced by screen readers before a success notification"
53
53
  },
54
54
  "ui.toast-status-warning": {
55
- "defaultMessage": "Warning",
55
+ "defaultMessage": "Ostrzeżenie",
56
56
  "description": "Announced by screen readers before a warning notification"
57
57
  }
58
58
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "ui.breadcrumb": {
3
- "defaultMessage": "Breadcrumb",
3
+ "defaultMessage": "Trilha de navegação",
4
4
  "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
5
  },
6
6
  "ui.close-action": {
@@ -16,7 +16,7 @@
16
16
  "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
17
  },
18
18
  "ui.loading": {
19
- "defaultMessage": "Loading",
19
+ "defaultMessage": "Carregando",
20
20
  "description": "Announced by screen readers for a button showing a loading spinner"
21
21
  },
22
22
  "ui.numberfield-decrease": {
@@ -32,7 +32,7 @@
32
32
  "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
33
33
  },
34
34
  "ui.select-row-action": {
35
- "defaultMessage": "Selecionar",
35
+ "defaultMessage": "Seleciona",
36
36
  "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
37
37
  },
38
38
  "ui.toast-region": {
@@ -40,19 +40,19 @@
40
40
  "description": "Accessible label for the notifications area; count is the number of notifications showing"
41
41
  },
42
42
  "ui.toast-status-error": {
43
- "defaultMessage": "Error",
43
+ "defaultMessage": "Erro",
44
44
  "description": "Announced by screen readers before an error notification"
45
45
  },
46
46
  "ui.toast-status-info": {
47
- "defaultMessage": "Information",
47
+ "defaultMessage": "Informações",
48
48
  "description": "Announced by screen readers before an informational notification"
49
49
  },
50
50
  "ui.toast-status-success": {
51
- "defaultMessage": "Success",
51
+ "defaultMessage": "Sucesso",
52
52
  "description": "Announced by screen readers before a success notification"
53
53
  },
54
54
  "ui.toast-status-warning": {
55
- "defaultMessage": "Warning",
55
+ "defaultMessage": "Atenção",
56
56
  "description": "Announced by screen readers before a warning notification"
57
57
  }
58
58
  }
@@ -0,0 +1,58 @@
1
+ {
2
+ "ui.breadcrumb": {
3
+ "defaultMessage": "Đường dẫn",
4
+ "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
+ },
6
+ "ui.close-action": {
7
+ "defaultMessage": "Đóng",
8
+ "description": "Close button text or label"
9
+ },
10
+ "ui.combobox-listbox": {
11
+ "defaultMessage": "Gợi ý",
12
+ "description": "Accessible label for a ComboBox's dropdown list of suggestions"
13
+ },
14
+ "ui.combobox-trigger": {
15
+ "defaultMessage": "Hiển thị gợi ý",
16
+ "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
+ },
18
+ "ui.loading": {
19
+ "defaultMessage": "Đang tải",
20
+ "description": "Announced by screen readers for a button showing a loading spinner"
21
+ },
22
+ "ui.numberfield-decrease": {
23
+ "defaultMessage": "Giảm {fieldLabel}",
24
+ "description": "Accessible label for a number field's decrement stepper; fieldLabel is the field's label and may be empty"
25
+ },
26
+ "ui.numberfield-increase": {
27
+ "defaultMessage": "Tăng {fieldLabel}",
28
+ "description": "Accessible label for a number field's increment stepper; fieldLabel is the field's label and may be empty"
29
+ },
30
+ "ui.select-placeholder": {
31
+ "defaultMessage": "Chọn một mục",
32
+ "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
33
+ },
34
+ "ui.select-row-action": {
35
+ "defaultMessage": "Lựa chọn",
36
+ "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
37
+ },
38
+ "ui.toast-region": {
39
+ "defaultMessage": "{count, plural, other {# thông báo}}.",
40
+ "description": "Accessible label for the notifications area; count is the number of notifications showing"
41
+ },
42
+ "ui.toast-status-error": {
43
+ "defaultMessage": "Lỗi",
44
+ "description": "Announced by screen readers before an error notification"
45
+ },
46
+ "ui.toast-status-info": {
47
+ "defaultMessage": "Thông tin",
48
+ "description": "Announced by screen readers before an informational notification"
49
+ },
50
+ "ui.toast-status-success": {
51
+ "defaultMessage": "Thành công",
52
+ "description": "Announced by screen readers before a success notification"
53
+ },
54
+ "ui.toast-status-warning": {
55
+ "defaultMessage": "Cảnh báo",
56
+ "description": "Announced by screen readers before a warning notification"
57
+ }
58
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "ui.breadcrumb": {
3
- "defaultMessage": "Breadcrumb",
3
+ "defaultMessage": "痕迹导航",
4
4
  "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
5
  },
6
6
  "ui.close-action": {
@@ -16,7 +16,7 @@
16
16
  "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
17
  },
18
18
  "ui.loading": {
19
- "defaultMessage": "Loading",
19
+ "defaultMessage": "正在加载",
20
20
  "description": "Announced by screen readers for a button showing a loading spinner"
21
21
  },
22
22
  "ui.numberfield-decrease": {
@@ -40,19 +40,19 @@
40
40
  "description": "Accessible label for the notifications area; count is the number of notifications showing"
41
41
  },
42
42
  "ui.toast-status-error": {
43
- "defaultMessage": "Error",
43
+ "defaultMessage": "错误",
44
44
  "description": "Announced by screen readers before an error notification"
45
45
  },
46
46
  "ui.toast-status-info": {
47
- "defaultMessage": "Information",
47
+ "defaultMessage": "信息",
48
48
  "description": "Announced by screen readers before an informational notification"
49
49
  },
50
50
  "ui.toast-status-success": {
51
- "defaultMessage": "Success",
51
+ "defaultMessage": "成功",
52
52
  "description": "Announced by screen readers before a success notification"
53
53
  },
54
54
  "ui.toast-status-warning": {
55
- "defaultMessage": "Warning",
55
+ "defaultMessage": "警告",
56
56
  "description": "Announced by screen readers before a warning notification"
57
57
  }
58
58
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "ui.breadcrumb": {
3
- "defaultMessage": "Breadcrumb",
3
+ "defaultMessage": "巡覽路徑",
4
4
  "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
5
  },
6
6
  "ui.close-action": {
@@ -16,7 +16,7 @@
16
16
  "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
17
  },
18
18
  "ui.loading": {
19
- "defaultMessage": "Loading",
19
+ "defaultMessage": "正在載入",
20
20
  "description": "Announced by screen readers for a button showing a loading spinner"
21
21
  },
22
22
  "ui.numberfield-decrease": {
@@ -32,7 +32,7 @@
32
32
  "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
33
33
  },
34
34
  "ui.select-row-action": {
35
- "defaultMessage": "選取",
35
+ "defaultMessage": "選擇",
36
36
  "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
37
37
  },
38
38
  "ui.toast-region": {
@@ -40,19 +40,19 @@
40
40
  "description": "Accessible label for the notifications area; count is the number of notifications showing"
41
41
  },
42
42
  "ui.toast-status-error": {
43
- "defaultMessage": "Error",
43
+ "defaultMessage": "錯誤",
44
44
  "description": "Announced by screen readers before an error notification"
45
45
  },
46
46
  "ui.toast-status-info": {
47
- "defaultMessage": "Information",
47
+ "defaultMessage": "資訊",
48
48
  "description": "Announced by screen readers before an informational notification"
49
49
  },
50
50
  "ui.toast-status-success": {
51
- "defaultMessage": "Success",
51
+ "defaultMessage": "成功",
52
52
  "description": "Announced by screen readers before a success notification"
53
53
  },
54
54
  "ui.toast-status-warning": {
55
- "defaultMessage": "Warning",
55
+ "defaultMessage": "警告",
56
56
  "description": "Announced by screen readers before a warning notification"
57
57
  }
58
58
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microbit/ui",
3
- "version": "0.1.0-alpha.22",
3
+ "version": "0.1.0-alpha.24",
4
4
  "description": "micro:bit design-system primitives: react-aria-components + Panda CSS with a design language ported from Chakra UI v2. Ships as source; see README for the consumption setup.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -6,24 +6,20 @@
6
6
  import { defineSlotRecipe } from "@pandacss/dev";
7
7
 
8
8
  /**
9
- * Avatar slot recipe — Chakra's avatar: a circle showing an image, the
10
- * initials of a name, or a generic person glyph, optionally with a badge
11
- * pinned to one corner.
9
+ * Avatar slot recipe — a circle showing an image, the initials of a name, or
10
+ * a generic person glyph, optionally with a badge pinned to one corner.
12
11
  *
13
12
  * The background and text colour come from `var(--avatar-bg)` and
14
13
  * `var(--avatar-color)` rather than being flat values, because the component
15
14
  * derives them from the name (see Avatar.tsx) and writes them as inline custom
16
- * properties — exactly as Chakra did. Two reasons, both about letting a call
17
- * site win with a plain `css={{ bg: …, color: … }}`: an inline *property*
18
- * would beat any class, where an inline *variable* only feeds this
19
- * declaration; and both must stay single-class selectors, since a state
20
- * selector like `&[data-light-bg]` outranks the call site's utility class on
21
- * specificity wherever cascade layers aren't in play — which is every app
22
- * still coexisting with Chakra (playbook gotcha #40).
15
+ * properties. Two reasons, both about letting a call site win with a plain
16
+ * `css={{ bg: …, color: … }}`: an inline *property* would beat any class,
17
+ * where an inline *variable* only feeds this declaration; and both must stay
18
+ * single-class selectors, since a state selector like `&[data-light-bg]`
19
+ * would outrank the call site's utility class on specificity.
23
20
  *
24
- * Sizes are Chakra's, with its `calc(size / 2.5)` font size resolved per size
25
- * so an app preset can restate either independently (classroom's avatars are
26
- * a grade larger than Chakra's).
21
+ * The `calc(size / 2.5)` font size is resolved per size so an app preset can
22
+ * restate either independently (classroom's avatars are a grade larger).
27
23
  *
28
24
  * Registered in the base preset (base-preset.ts), which also has the
29
25
  * `staticCss` entry that keeps the runtime-prop variants generated.
@@ -43,7 +39,7 @@ export const avatar = defineSlotRecipe({
43
39
  textTransform: "uppercase",
44
40
  fontWeight: "medium",
45
41
  borderRadius: "full",
46
- // Chakra's no-name defaults; the name-derived pair arrives inline.
42
+ // The no-name defaults; the name-derived pair arrives inline.
47
43
  // gray.350 is the decorative-fill stop — 400+ are reserved for
48
44
  // accessible outlines and text (see the ramp in base-preset.ts).
49
45
  background: "var(--avatar-bg, token(colors.gray.350))",
@@ -72,12 +68,12 @@ export const avatar = defineSlotRecipe({
72
68
  },
73
69
  },
74
70
  variants: {
75
- // Chakra's scale: the container size, and Chakra's `calc(size / 2.5)`
76
- // font size kept as a calc over the same token so both track a preset
77
- // that rescales `sizes` (the dense preset does, by 0.88).
71
+ // The container size, and the `calc(size / 2.5)` font size kept as a
72
+ // calc over the same token so both track a preset that rescales `sizes`
73
+ // (the dense preset does, by 0.88).
78
74
  //
79
- // The font size lands on the root *and* the label, as Chakra's did
80
- // (through one variable). They are separate declarations so an app can
75
+ // The font size lands on the root *and* the label. They are separate
76
+ // declarations so an app can
81
77
  // move one without the other: the root's is the em basis for a badge,
82
78
  // the label's is how big the initials are, and the two are not always
83
79
  // the same wish.
@@ -139,7 +135,7 @@ export const avatar = defineSlotRecipe({
139
135
  label: { fontSize: "calc(token(sizes.32) / 2.5)" },
140
136
  },
141
137
  },
142
- /** Which corner the badge sits in. Chakra's placements, same offsets. */
138
+ /** Which corner the badge sits in. */
143
139
  placement: {
144
140
  "top-start": {
145
141
  badge: {
package/src/Avatar.tsx CHANGED
@@ -20,10 +20,10 @@ import { token } from "styled-system/tokens";
20
20
  import { SystemStyleObject } from "styled-system/types";
21
21
 
22
22
  /**
23
- * Chakra's `randomColor({ string })`, reproduced exactly: a djb2-style hash of
24
- * the name, its low three bytes read as a colour. Not random despite the name
25
- * the same name is always the same colour, which is the point, and
26
- * reproducing the hash means avatars keep the colours they had under Chakra.
23
+ * A djb2-style hash of the name, its low three bytes read as a colour. The
24
+ * same name is always the same colour, and the exact hash is a compatibility
25
+ * contract: apps' existing avatar rosters keep the colours they have always
26
+ * had, so don't change it.
27
27
  */
28
28
  const colorFromName = (name: string): string => {
29
29
  let hash = 0;
@@ -40,8 +40,8 @@ const colorFromName = (name: string): string => {
40
40
  };
41
41
 
42
42
  /**
43
- * Chakra's contrast rule for the generated background: perceived brightness
44
- * (the classic 299/587/114 weighting) below 128 counts as dark, and dark
43
+ * Contrast rule for the generated background: perceived brightness (the
44
+ * classic 299/587/114 weighting) below 128 counts as dark, and dark
45
45
  * backgrounds take white text.
46
46
  */
47
47
  const isLight = (hex: string): boolean => {
@@ -52,9 +52,9 @@ const isLight = (hex: string): boolean => {
52
52
  };
53
53
 
54
54
  /**
55
- * Chakra's `initials`: first letter of the first and last words. Prefixed
56
- * because it is exported from the package root, where a bare `initials`
57
- * would be a broad name to claim.
55
+ * First letter of the first and last words. Prefixed because it is exported
56
+ * from the package root, where a bare `initials` would be a broad name to
57
+ * claim.
58
58
  */
59
59
  export const avatarInitials = (name: string): string => {
60
60
  const names = name.trim().split(" ");
@@ -66,9 +66,12 @@ export const avatarInitials = (name: string): string => {
66
66
  };
67
67
 
68
68
  /**
69
- * Chakra's generic person glyph, the fallback when there is no name. Chakra
70
- * hardcoded it white; here it inherits `currentColor`, which is the same white
71
- * on the no-name grey background and stays visible if a call site recolours.
69
+ * The generic person glyph, the fallback when there is no name. It inherits
70
+ * `currentColor` white on the no-name grey background so it stays visible
71
+ * if a call site recolours.
72
+ *
73
+ * The paths are Chakra UI's avatar glyph, inlined for visual parity with the
74
+ * apps' original look (see the notice in LICENSE.md).
72
75
  */
73
76
  export const GenericAvatarIcon = (props: SVGProps<SVGSVGElement>) => (
74
77
  <svg viewBox="0 0 128 128" width="100%" height="100%" {...props}>
@@ -86,9 +89,9 @@ export const GenericAvatarIcon = (props: SVGProps<SVGSVGElement>) => (
86
89
  type ImageStatus = "pending" | "loading" | "loaded" | "failed";
87
90
 
88
91
  /**
89
- * Chakra's `useImage`: load the photo out of band and report how it went, so
90
- * the avatar can show the initials or the icon meanwhile and keep showing
91
- * them if it never arrives.
92
+ * Load the photo out of band and report how it went, so the avatar can show
93
+ * the initials or the icon meanwhile and keep showing them if it never
94
+ * arrives.
92
95
  *
93
96
  * The <img> element is only mounted once this says "loaded", which is what
94
97
  * keeps a broken URL from leaving the browser's broken-image glyph inside the
@@ -147,13 +150,13 @@ export interface AvatarProps
147
150
  */
148
151
  src?: string;
149
152
  srcSet?: string;
150
- /** Shown when there is no name. Defaults to Chakra's person glyph. */
153
+ /** Shown when there is no name. Defaults to the generic person glyph. */
151
154
  icon?: ReactNode;
152
- /** Accessible name for the icon fallback. Chakra's default was " avatar". */
155
+ /** Accessible name for the icon fallback. Defaults to " avatar". */
153
156
  iconLabel?: string;
154
157
  /** Override how a name becomes initials. */
155
158
  getInitials?: (name: string) => string;
156
- /** Chakra's `showBorder`: a 2px ring in the avatar's border colour. */
159
+ /** A 2px ring in the avatar's border colour. */
157
160
  showBorder?: boolean;
158
161
  /** An `AvatarBadge`. */
159
162
  children?: ReactNode;
@@ -163,11 +166,11 @@ export interface AvatarProps
163
166
  }
164
167
 
165
168
  /**
166
- * Avatar — Chakra's <Avatar>: a circular identity marker showing a photo, the
167
- * initials of a name, or a generic glyph, in a colour derived from the name.
169
+ * Avatar — a circular identity marker showing a photo, the initials of a
170
+ * name, or a generic glyph, in a colour derived from the name.
168
171
  *
169
172
  * Decorative in most designs — pass `aria-hidden` where the name is already
170
- * beside it, as Chakra's call sites did.
173
+ * beside it.
171
174
  */
172
175
  export const Avatar = ({
173
176
  name,
@@ -187,7 +190,7 @@ export const Avatar = ({
187
190
  const status = useImageStatus(src, srcSet);
188
191
  const isLoaded = status === "loaded";
189
192
  const slots = avatar({ size });
190
- // Only while the image isn't showing, matching Chakra's `:not([data-loaded])`.
193
+ // Only while the image isn't showing.
191
194
  const bg = name && !isLoaded ? colorFromName(name) : undefined;
192
195
  return (
193
196
  <span
@@ -204,7 +207,7 @@ export const Avatar = ({
204
207
  ? ({
205
208
  ...style,
206
209
  "--avatar-bg": bg,
207
- // Chakra's contrast rule, as a variable rather than a state
210
+ // The contrast rule, as a variable rather than a state
208
211
  // selector so a call site's `css` colour still wins (see the
209
212
  // recipe).
210
213
  "--avatar-color": isLight(bg)
@@ -225,9 +228,9 @@ export const Avatar = ({
225
228
  <span role="img" aria-label={name} className={slots.label}>
226
229
  {getInitials(name)}
227
230
  </span>
228
- ) : // The icon is labelled in place rather than wrapped, as Chakra did:
229
- // a wrapper would make it an inline child with a line box of its own,
230
- // where directly in the flex container it is a flex item and centres
231
+ ) : // The icon is labelled in place rather than wrapped: a wrapper
232
+ // would make it an inline child with a line box of its own, where
233
+ // directly in the flex container it is a flex item and centres
231
234
  // exactly.
232
235
  isValidElement(icon) ? (
233
236
  cloneElement(icon as ReactElement<Record<string, unknown>>, {
@@ -247,9 +250,8 @@ export interface AvatarBadgeProps
247
250
  Pick<AvatarVariantProps, "placement"> {
248
251
  children?: ReactNode;
249
252
  /**
250
- * Per-instance style overrides. The badge has no size of its own — Chakra's
251
- * didn't either, so call sites set one (`boxSize: "1.5em"` scales with the
252
- * avatar).
253
+ * Per-instance style overrides. The badge has no size of its own — call
254
+ * sites set one (`boxSize: "1.5em"` scales with the avatar).
253
255
  */
254
256
  css?: SystemStyleObject;
255
257
  className?: string;
@@ -6,10 +6,9 @@
6
6
  import { defineSlotRecipe } from "@pandacss/dev";
7
7
 
8
8
  /**
9
- * Breadcrumb slot recipe — Chakra's Breadcrumb layout: a flex list with a
10
- * separator between items. The links themselves are the shared `Link`
11
- * (Chakra's BreadcrumbLink base was identical to its Link base), so there is
12
- * no link slot; the current page renders as a plain span.
9
+ * Breadcrumb slot recipe — a flex list with a separator between items. The
10
+ * links themselves are the shared `Link`, so there is no link slot; the
11
+ * current page renders as a plain span.
13
12
  *
14
13
  * Registered in the base preset (base-preset.ts). No variants, so it needs
15
14
  * no `staticCss` entry.
@@ -34,9 +33,6 @@ export const breadcrumb = defineSlotRecipe({
34
33
  "&:last-of-type [data-separator]": { display: "none" },
35
34
  },
36
35
  separator: {
37
- // Chakra's default `spacing` was a literal 0.5rem; the token follows
38
- // the library's existing lean (the button icon gap made the same
39
- // call — see the playbook's open token-vs-literal spacing decision).
40
36
  mx: "2",
41
37
  },
42
38
  },
@@ -14,12 +14,12 @@ import { uiMessage } from "./messages";
14
14
 
15
15
  // The separator is declared once on the Breadcrumb and rendered by every
16
16
  // item; the current-page flag hops from BreadcrumbItem to the BreadcrumbLink
17
- // inside it (Chakra did both with cloneElement).
17
+ // inside it.
18
18
  const SeparatorContext = createContext<ReactNode>("/");
19
19
  const CurrentPageContext = createContext(false);
20
20
 
21
21
  export interface BreadcrumbProps {
22
- /** Between items; an element or string. Chakra's default "/". */
22
+ /** Between items; an element or string. Default "/". */
23
23
  separator?: ReactNode;
24
24
  /** Per-instance style overrides for the nav (e.g. fontSize). */
25
25
  css?: SystemStyleObject;
@@ -29,9 +29,8 @@ export interface BreadcrumbProps {
29
29
  }
30
30
 
31
31
  /**
32
- * Breadcrumb — navigation trail matching Chakra's: nav > ol > li with a
33
- * separator between items and the current page as plain text with
34
- * `aria-current="page"`.
32
+ * Breadcrumb — a navigation trail: nav > ol > li with a separator between
33
+ * items and the current page as plain text with `aria-current="page"`.
35
34
  */
36
35
  export const Breadcrumb = ({
37
36
  separator = "/",
@@ -98,9 +97,8 @@ export type BreadcrumbLinkProps = HTMLStyledProps<"a">;
98
97
  const CurrentPageText = styled("span");
99
98
 
100
99
  /**
101
- * The trail's link: the shared `Link` (Chakra's BreadcrumbLink base was its
102
- * Link base), or a plain span with `aria-current="page"` inside an item
103
- * marked `isCurrentPage`.
100
+ * The trail's link: the shared `Link`, or a plain span with
101
+ * `aria-current="page"` inside an item marked `isCurrentPage`.
104
102
  */
105
103
  export const BreadcrumbLink = (props: BreadcrumbLinkProps) => {
106
104
  const isCurrentPage = useContext(CurrentPageContext);
@@ -5,23 +5,22 @@
5
5
  */
6
6
  import { defineRecipe } from "@pandacss/dev";
7
7
 
8
- // Chakra's transition.property.common, inlined (Panda has no transitionProperty
9
- // token category). Matches Chakra's Button base transition.
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
 
13
13
  /**
14
- * Button recipe — Chakra's default Button base + sizes, with this app's
15
- * borderRadius (`button` = 2rem) and variant set ported from
16
- * `components/button.ts`. Interaction conditions (`_hover`/`_active`/
14
+ * Button recipe — the family button base + sizes, with the house
15
+ * borderRadius (`button` = 2rem). Interaction conditions (`_hover`/`_active`/
17
16
  * `_disabled`/`_focusVisible`) are widened in the preset to also match
18
- * react-aria-components' data attributes, so these Chakra-shaped variant
19
- * objects work unchanged on RAC's <Button>.
17
+ * react-aria-components' data attributes, so these variant objects work
18
+ * unchanged on RAC's <Button>.
20
19
  *
21
20
  * A config recipe (not a component cva): styles land in the `recipes` layer so
22
21
  * call sites can override with plain style props, and presets extend the
23
22
  * variants. This file holds the brand-independent variant set — the core
24
- * Chakra variants plus the family-wide `language`/`toolbar` variants; a
23
+ * variants plus the family-wide `language`/`toolbar` variants; a
25
24
  * consuming app's preset extends it with app vocabulary (e.g. ml-trainer's
26
25
  * `led`/`record*`/`secondary-disabled`). Brand divergence within a variant is
27
26
  * token-driven (see the `button.*` and `languageText` semantic tokens).
@@ -68,7 +67,7 @@ export const button = defineRecipe({
68
67
  xs: { h: "6", minW: "6", fontSize: "xs", px: "2" },
69
68
  },
70
69
  variant: {
71
- // Chakra's unstyled reset + this app's border-radius removal.
70
+ // A full reset: the button renders as plain inline content.
72
71
  unstyled: {
73
72
  bg: "none",
74
73
  color: "inherit",
@@ -78,7 +77,7 @@ export const button = defineRecipe({
78
77
  p: "0",
79
78
  borderRadius: "unset",
80
79
  },
81
- // Chakra's link layout (no padding/height) + this app's colours.
80
+ // Link-shaped button: no padding/height, underline on hover.
82
81
  link: {
83
82
  padding: 0,
84
83
  height: "auto",
@@ -115,10 +114,9 @@ export const button = defineRecipe({
115
114
  _hover: { bg: "blackAlpha.50" },
116
115
  _active: { bg: "blackAlpha.100" },
117
116
  },
118
- // Chakra had no `plain` variant, so `variant="plain"` fell through to
119
- // base-only styling: a transparent, colour-inheriting button. Used for the
120
- // action-bar icon-button menu triggers (settings/help), which supply their
121
- // own colour and shape via instance styles.
117
+ // Base-only styling: a transparent, colour-inheriting button. Used for
118
+ // the action-bar icon-button menu triggers (settings/help), which supply
119
+ // their own colour and shape via instance styles.
122
120
  plain: {
123
121
  bg: "transparent",
124
122
  color: "inherit",
@@ -132,21 +130,12 @@ export const button = defineRecipe({
132
130
  },
133
131
  _active: { bg: "button.primaryActiveBg" },
134
132
  },
135
- // 600/700, matching what python-editor's Chakra outline + red
136
- // colorScheme resolved to. (Extracted from ml-trainer at 500/600, but
137
- // its one warning button tolerates the darkening; python-editor's
138
- // "Reset project" was visibly lighter than its Chakra self.)
139
- // NOTE (2026-08-02, from classroom): two Chakra `outline` shapes have
140
- // no home here and are currently restated per call site in that app —
141
- // worth considering as variants once a second consumer wants them.
142
- // - a neutral outline (transparent, 1px gray.200, inherited text,
143
- // gray.50/gray.100 hover/press): Chakra's default-colorScheme
144
- // `outline`, and python-editor's *default* variant per the
145
- // playbook's cross-app vocabulary, so likely already a 2-app shape.
146
- // - an on-colour outline (white 2px + white text over a coloured bar,
147
- // whiteAlpha hover/press): Chakra's `outline` + `whiteAlpha`.
148
- // `warning` below is the *destructive* outline and is not a substitute
149
- // for either; `warningSolid` did map exactly onto Chakra solid+red.
133
+ // The *destructive* outline (text darker than 500 for contrast).
134
+ // Two other outline shapes are currently restated per call site in
135
+ // classroom a neutral outline (1px gray.200, inherited text,
136
+ // gray.50/gray.100 hover/press) and an on-colour outline (white 2px +
137
+ // white text over a coloured bar, whiteAlpha hover/press) — worth
138
+ // considering as variants if a second consumer wants them.
150
139
  warning: {
151
140
  borderWidth: "2px",
152
141
  borderColor: "danger.600",
@@ -155,10 +144,10 @@ export const button = defineRecipe({
155
144
  _hover: { borderColor: "danger.700", color: "danger.700" },
156
145
  _active: { bg: "danger.50" },
157
146
  },
158
- // Chakra's built-in solid + red colorScheme (destructive confirm
159
- // buttons). Same values as `record` today, but a separate variant so
160
- // recording UI and destructive actions can diverge - hence danger
161
- // tokens here, red.* literals there.
147
+ // The destructive solid (confirm buttons). Same values as ml-trainer's
148
+ // `record` today, but a separate variant so recording UI and
149
+ // destructive actions can diverge - hence danger tokens here, red.*
150
+ // literals there.
162
151
  warningSolid: {
163
152
  color: "white",
164
153
  bg: "danger.500",