@microbit/ui 0.1.0-alpha.15 → 0.1.0-alpha.16
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 +1 -1
- package/src/GridList.recipe.ts +13 -1
- package/src/Select.recipe.ts +35 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microbit/ui",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.16",
|
|
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",
|
package/src/GridList.recipe.ts
CHANGED
|
@@ -38,7 +38,19 @@ export const gridList = defineSlotRecipe({
|
|
|
38
38
|
transitionDuration: "ultra-fast",
|
|
39
39
|
transitionTimingFunction: "ease-in",
|
|
40
40
|
_hover: { bg: "gray.50" },
|
|
41
|
-
|
|
41
|
+
// A row holding an open menu (or any other popover) keeps the hover
|
|
42
|
+
// grey, so the row an open menu belongs to stays visible. Hover state
|
|
43
|
+
// cannot do this on its own: a Popover lays a fixed full-viewport
|
|
44
|
+
// underlay over the page while open, which takes the pointer off the
|
|
45
|
+
// row — `:hover` and RAC's own `data-hovered` both drop the moment the
|
|
46
|
+
// menu appears. A trigger carries `aria-expanded` (useOverlayTrigger),
|
|
47
|
+
// so the row can see its own open overlay.
|
|
48
|
+
"&:has([aria-expanded=true])": { bg: "gray.50" },
|
|
49
|
+
"&[data-selected]": {
|
|
50
|
+
bg: "gray.100",
|
|
51
|
+
_hover: { bg: "gray.100" },
|
|
52
|
+
"&:has([aria-expanded=true])": { bg: "gray.100" },
|
|
53
|
+
},
|
|
42
54
|
"&[data-focus-visible]": { focusShadow: "outline" },
|
|
43
55
|
"&[data-disabled]": { opacity: 0.4, cursor: "not-allowed" },
|
|
44
56
|
},
|
package/src/Select.recipe.ts
CHANGED
|
@@ -72,14 +72,38 @@ export const select = defineSlotRecipe({
|
|
|
72
72
|
color: "inherit",
|
|
73
73
|
h: "10",
|
|
74
74
|
px: "4",
|
|
75
|
+
// As the input recipe, so a Select, a NativeSelect and a TextField in one
|
|
76
|
+
// form all tint together on hover. (react-aria's TextField has no hover
|
|
77
|
+
// effect, but matching the family beats matching their docs.)
|
|
75
78
|
_hover: { borderColor: "gray.300" },
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
// `data-invalid` lands on the root — and, in a ComboBox, on the input —
|
|
80
|
+
// but never on the trigger: a RAC Button has no validity state, and our
|
|
81
|
+
// ComboBox control is a plain div. So it comes down from the parent.
|
|
82
|
+
// `> &` rather than a descendant selector, so an app's own invalid form
|
|
83
|
+
// wrapper cannot paint every control inside it red.
|
|
84
|
+
//
|
|
85
|
+
// Declared after hover and before focus so red beats a hover tint and
|
|
86
|
+
// the focus ring beats red, as in the input recipe.
|
|
87
|
+
"[data-invalid] > &": {
|
|
88
|
+
borderColor: "danger.500",
|
|
89
|
+
boxShadow: "0 0 0 1px token(colors.danger.500)",
|
|
90
|
+
},
|
|
91
|
+
// Two focus cases. `data-focus-visible` is Select's button on keyboard
|
|
92
|
+
// focus only (RAC leaves it unset for mouse, matching the react-aria
|
|
93
|
+
// docs' Select). The `:has()` arm is ComboBox: its control is a plain
|
|
94
|
+
// div wrapping an input, so it gets no RAC attributes itself, and as a
|
|
95
|
+
// text field it should show focus on any modality. That arm watches
|
|
96
|
+
// native `:focus` rather than the input's `data-focused`, because
|
|
97
|
+
// react-aria dispatches a synthetic blur at the input whenever virtual
|
|
98
|
+
// focus moves to an option (aria-activedescendant) — which strips RAC's
|
|
99
|
+
// attribute for as long as the list has an active option, real focus
|
|
100
|
+
// never having left. Select's trigger holds no input, so it can't match.
|
|
101
|
+
"&[data-focus-visible], &:has(input:focus)": {
|
|
102
|
+
boxShadow: "0 0 0 1px token(colors.focusBorder)",
|
|
78
103
|
borderColor: "focusBorder",
|
|
104
|
+
outline: "2px solid transparent",
|
|
105
|
+
outlineOffset: "2px",
|
|
79
106
|
},
|
|
80
|
-
// A ComboBox's control is an input, which is focused whenever it is open.
|
|
81
|
-
"&[data-focused]": { focusShadow: "outline", borderColor: "focusBorder" },
|
|
82
|
-
"&[data-invalid]": { borderColor: "danger.500" },
|
|
83
107
|
"&[data-disabled]": { opacity: 0.4, cursor: "not-allowed" },
|
|
84
108
|
},
|
|
85
109
|
// Whatever shows the current value: Select's SelectValue, ComboBox's
|
|
@@ -113,8 +137,11 @@ export const select = defineSlotRecipe({
|
|
|
113
137
|
background: "transparent",
|
|
114
138
|
border: "none",
|
|
115
139
|
cursor: "pointer",
|
|
140
|
+
// No focus styling, deliberately: react-aria keeps a ComboBox's toggle
|
|
141
|
+
// button out of the tab order (the input owns the keyboard), so a ring
|
|
142
|
+
// here would only ever be reachable programmatically, and would suggest
|
|
143
|
+
// the chevron is a tab stop. The whole control shows focus instead.
|
|
116
144
|
outline: "none",
|
|
117
|
-
"&[data-focus-visible]": { focusShadow: "outline" },
|
|
118
145
|
},
|
|
119
146
|
content: {
|
|
120
147
|
// Line the card up with the control, as a select should and as
|
|
@@ -122,6 +149,8 @@ export const select = defineSlotRecipe({
|
|
|
122
149
|
// button it measures; `ComboBox` measures its own control and sets the
|
|
123
150
|
// width inline, because RAC's var is the *input's* width there.
|
|
124
151
|
minWidth: "var(--trigger-width)",
|
|
152
|
+
display: "flex",
|
|
153
|
+
flexDirection: "column",
|
|
125
154
|
bg: "white",
|
|
126
155
|
color: "inherit",
|
|
127
156
|
py: "2",
|
|
@@ -141,7 +170,6 @@ export const select = defineSlotRecipe({
|
|
|
141
170
|
},
|
|
142
171
|
list: {
|
|
143
172
|
outline: "none",
|
|
144
|
-
maxHeight: "inherit",
|
|
145
173
|
overflowY: "auto",
|
|
146
174
|
},
|
|
147
175
|
option: {
|