@react-spectrum/s2 3.0.0-nightly-c81a23ccd-250409 → 3.0.0-nightly-9723225d6-250412

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 (201) hide show
  1. package/dist/ActionButton.cjs +1 -0
  2. package/dist/ActionButton.cjs.map +1 -1
  3. package/dist/ActionButton.css.map +1 -1
  4. package/dist/ActionButton.mjs +1 -0
  5. package/dist/ActionButton.mjs.map +1 -1
  6. package/dist/Card.cjs +1 -1
  7. package/dist/Card.cjs.map +1 -1
  8. package/dist/Card.css.map +1 -1
  9. package/dist/Card.mjs +1 -1
  10. package/dist/Card.mjs.map +1 -1
  11. package/dist/ColorSwatchPicker.cjs +2 -2
  12. package/dist/ColorSwatchPicker.cjs.map +1 -1
  13. package/dist/ColorSwatchPicker.css.map +1 -1
  14. package/dist/ColorSwatchPicker.mjs +2 -2
  15. package/dist/ColorSwatchPicker.mjs.map +1 -1
  16. package/dist/Content.cjs +6 -6
  17. package/dist/Content.cjs.map +1 -1
  18. package/dist/Content.mjs +6 -6
  19. package/dist/Content.mjs.map +1 -1
  20. package/dist/Disclosure.cjs +24 -21
  21. package/dist/Disclosure.cjs.map +1 -1
  22. package/dist/Disclosure.css +12 -20
  23. package/dist/Disclosure.css.map +1 -1
  24. package/dist/Disclosure.mjs +24 -21
  25. package/dist/Disclosure.mjs.map +1 -1
  26. package/dist/NotificationBadge.cjs +15 -9
  27. package/dist/NotificationBadge.cjs.map +1 -1
  28. package/dist/NotificationBadge.css +22 -10
  29. package/dist/NotificationBadge.css.map +1 -1
  30. package/dist/NotificationBadge.mjs +15 -9
  31. package/dist/NotificationBadge.mjs.map +1 -1
  32. package/dist/TableView.cjs +28 -16
  33. package/dist/TableView.cjs.map +1 -1
  34. package/dist/TableView.css.map +1 -1
  35. package/dist/TableView.mjs +29 -17
  36. package/dist/TableView.mjs.map +1 -1
  37. package/dist/Toast.cjs +557 -0
  38. package/dist/Toast.cjs.map +1 -0
  39. package/dist/Toast.css +461 -0
  40. package/dist/Toast.css.map +1 -0
  41. package/dist/Toast.mjs +551 -0
  42. package/dist/Toast.mjs.map +1 -0
  43. package/dist/Toast_module.cjs +70 -0
  44. package/dist/Toast_module.cjs.map +1 -0
  45. package/dist/Toast_module.css +119 -0
  46. package/dist/Toast_module.css.map +1 -0
  47. package/dist/Toast_module.mjs +72 -0
  48. package/dist/Toast_module.mjs.map +1 -0
  49. package/dist/ar-AE.cjs +6 -1
  50. package/dist/ar-AE.cjs.map +1 -1
  51. package/dist/ar-AE.mjs +6 -1
  52. package/dist/ar-AE.mjs.map +1 -1
  53. package/dist/bg-BG.cjs +6 -1
  54. package/dist/bg-BG.cjs.map +1 -1
  55. package/dist/bg-BG.mjs +6 -1
  56. package/dist/bg-BG.mjs.map +1 -1
  57. package/dist/cs-CZ.cjs +10 -2
  58. package/dist/cs-CZ.cjs.map +1 -1
  59. package/dist/cs-CZ.mjs +10 -2
  60. package/dist/cs-CZ.mjs.map +1 -1
  61. package/dist/da-DK.cjs +8 -3
  62. package/dist/da-DK.cjs.map +1 -1
  63. package/dist/da-DK.mjs +8 -3
  64. package/dist/da-DK.mjs.map +1 -1
  65. package/dist/de-DE.cjs +7 -3
  66. package/dist/de-DE.cjs.map +1 -1
  67. package/dist/de-DE.mjs +7 -3
  68. package/dist/de-DE.mjs.map +1 -1
  69. package/dist/el-GR.cjs +6 -1
  70. package/dist/el-GR.cjs.map +1 -1
  71. package/dist/el-GR.mjs +6 -1
  72. package/dist/el-GR.mjs.map +1 -1
  73. package/dist/en-US.cjs +5 -1
  74. package/dist/en-US.cjs.map +1 -1
  75. package/dist/en-US.mjs +5 -1
  76. package/dist/en-US.mjs.map +1 -1
  77. package/dist/es-ES.cjs +10 -6
  78. package/dist/es-ES.cjs.map +1 -1
  79. package/dist/es-ES.mjs +10 -6
  80. package/dist/es-ES.mjs.map +1 -1
  81. package/dist/et-EE.cjs +6 -1
  82. package/dist/et-EE.cjs.map +1 -1
  83. package/dist/et-EE.mjs +6 -1
  84. package/dist/et-EE.mjs.map +1 -1
  85. package/dist/fi-FI.cjs +7 -2
  86. package/dist/fi-FI.cjs.map +1 -1
  87. package/dist/fi-FI.mjs +7 -2
  88. package/dist/fi-FI.mjs.map +1 -1
  89. package/dist/fr-FR.cjs +7 -3
  90. package/dist/fr-FR.cjs.map +1 -1
  91. package/dist/fr-FR.mjs +7 -3
  92. package/dist/fr-FR.mjs.map +1 -1
  93. package/dist/he-IL.cjs +9 -5
  94. package/dist/he-IL.cjs.map +1 -1
  95. package/dist/he-IL.mjs +9 -5
  96. package/dist/he-IL.mjs.map +1 -1
  97. package/dist/hr-HR.cjs +11 -3
  98. package/dist/hr-HR.cjs.map +1 -1
  99. package/dist/hr-HR.mjs +11 -3
  100. package/dist/hr-HR.mjs.map +1 -1
  101. package/dist/hu-HU.cjs +6 -1
  102. package/dist/hu-HU.cjs.map +1 -1
  103. package/dist/hu-HU.mjs +6 -1
  104. package/dist/hu-HU.mjs.map +1 -1
  105. package/dist/it-IT.cjs +6 -2
  106. package/dist/it-IT.cjs.map +1 -1
  107. package/dist/it-IT.mjs +6 -2
  108. package/dist/it-IT.mjs.map +1 -1
  109. package/dist/ja-JP.cjs +7 -2
  110. package/dist/ja-JP.cjs.map +1 -1
  111. package/dist/ja-JP.mjs +7 -2
  112. package/dist/ja-JP.mjs.map +1 -1
  113. package/dist/ko-KR.cjs +8 -3
  114. package/dist/ko-KR.cjs.map +1 -1
  115. package/dist/ko-KR.mjs +8 -3
  116. package/dist/ko-KR.mjs.map +1 -1
  117. package/dist/lt-LT.cjs +8 -3
  118. package/dist/lt-LT.cjs.map +1 -1
  119. package/dist/lt-LT.mjs +8 -3
  120. package/dist/lt-LT.mjs.map +1 -1
  121. package/dist/lv-LV.cjs +9 -4
  122. package/dist/lv-LV.cjs.map +1 -1
  123. package/dist/lv-LV.mjs +9 -4
  124. package/dist/lv-LV.mjs.map +1 -1
  125. package/dist/main.cjs +4 -2
  126. package/dist/main.cjs.map +1 -1
  127. package/dist/module.mjs +4 -2
  128. package/dist/module.mjs.map +1 -1
  129. package/dist/nb-NO.cjs +12 -4
  130. package/dist/nb-NO.cjs.map +1 -1
  131. package/dist/nb-NO.mjs +12 -4
  132. package/dist/nb-NO.mjs.map +1 -1
  133. package/dist/nl-NL.cjs +6 -1
  134. package/dist/nl-NL.cjs.map +1 -1
  135. package/dist/nl-NL.mjs +6 -1
  136. package/dist/nl-NL.mjs.map +1 -1
  137. package/dist/pl-PL.cjs +11 -3
  138. package/dist/pl-PL.cjs.map +1 -1
  139. package/dist/pl-PL.mjs +11 -3
  140. package/dist/pl-PL.mjs.map +1 -1
  141. package/dist/pt-BR.cjs +6 -1
  142. package/dist/pt-BR.cjs.map +1 -1
  143. package/dist/pt-BR.mjs +6 -1
  144. package/dist/pt-BR.mjs.map +1 -1
  145. package/dist/pt-PT.cjs +6 -1
  146. package/dist/pt-PT.cjs.map +1 -1
  147. package/dist/pt-PT.mjs +6 -1
  148. package/dist/pt-PT.mjs.map +1 -1
  149. package/dist/ro-RO.cjs +8 -4
  150. package/dist/ro-RO.cjs.map +1 -1
  151. package/dist/ro-RO.mjs +8 -4
  152. package/dist/ro-RO.mjs.map +1 -1
  153. package/dist/ru-RU.cjs +11 -3
  154. package/dist/ru-RU.cjs.map +1 -1
  155. package/dist/ru-RU.mjs +11 -3
  156. package/dist/ru-RU.mjs.map +1 -1
  157. package/dist/sk-SK.cjs +10 -2
  158. package/dist/sk-SK.cjs.map +1 -1
  159. package/dist/sk-SK.mjs +10 -2
  160. package/dist/sk-SK.mjs.map +1 -1
  161. package/dist/sl-SI.cjs +11 -3
  162. package/dist/sl-SI.cjs.map +1 -1
  163. package/dist/sl-SI.mjs +11 -3
  164. package/dist/sl-SI.mjs.map +1 -1
  165. package/dist/sr-SP.cjs +10 -2
  166. package/dist/sr-SP.cjs.map +1 -1
  167. package/dist/sr-SP.mjs +10 -2
  168. package/dist/sr-SP.mjs.map +1 -1
  169. package/dist/sv-SE.cjs +6 -2
  170. package/dist/sv-SE.cjs.map +1 -1
  171. package/dist/sv-SE.mjs +6 -2
  172. package/dist/sv-SE.mjs.map +1 -1
  173. package/dist/tr-TR.cjs +7 -2
  174. package/dist/tr-TR.cjs.map +1 -1
  175. package/dist/tr-TR.mjs +7 -2
  176. package/dist/tr-TR.mjs.map +1 -1
  177. package/dist/types.d.ts +49 -2
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/uk-UA.cjs +10 -2
  180. package/dist/uk-UA.cjs.map +1 -1
  181. package/dist/uk-UA.mjs +10 -2
  182. package/dist/uk-UA.mjs.map +1 -1
  183. package/dist/zh-CN.cjs +6 -1
  184. package/dist/zh-CN.cjs.map +1 -1
  185. package/dist/zh-CN.mjs +6 -1
  186. package/dist/zh-CN.mjs.map +1 -1
  187. package/dist/zh-TW.cjs +6 -1
  188. package/dist/zh-TW.cjs.map +1 -1
  189. package/dist/zh-TW.mjs +6 -1
  190. package/dist/zh-TW.mjs.map +1 -1
  191. package/package.json +20 -19
  192. package/src/ActionButton.tsx +1 -0
  193. package/src/Card.tsx +1 -1
  194. package/src/ColorSwatchPicker.tsx +2 -1
  195. package/src/Content.tsx +6 -6
  196. package/src/Disclosure.tsx +18 -24
  197. package/src/NotificationBadge.tsx +7 -3
  198. package/src/TableView.tsx +45 -29
  199. package/src/Toast.module.css +153 -0
  200. package/src/Toast.tsx +579 -0
  201. package/src/index.ts +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-spectrum/s2",
3
- "version": "3.0.0-nightly-c81a23ccd-250409",
3
+ "version": "3.0.0-nightly-9723225d6-250412",
4
4
  "description": "Spectrum 2 UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -57,25 +57,26 @@
57
57
  "src"
58
58
  ],
59
59
  "dependencies": {
60
- "@internationalized/number": "3.0.0-nightly-c81a23ccd-250409",
61
- "@react-aria/collections": "3.0.0-nightly-c81a23ccd-250409",
62
- "@react-aria/focus": "3.0.0-nightly-c81a23ccd-250409",
63
- "@react-aria/i18n": "3.0.0-nightly-c81a23ccd-250409",
64
- "@react-aria/interactions": "3.0.0-nightly-c81a23ccd-250409",
65
- "@react-aria/live-announcer": "3.0.0-nightly-c81a23ccd-250409",
66
- "@react-aria/utils": "3.0.0-nightly-c81a23ccd-250409",
67
- "@react-spectrum/utils": "3.0.0-nightly-c81a23ccd-250409",
68
- "@react-stately/layout": "3.0.0-nightly-c81a23ccd-250409",
69
- "@react-stately/utils": "3.0.0-nightly-c81a23ccd-250409",
70
- "@react-types/dialog": "3.0.0-nightly-c81a23ccd-250409",
71
- "@react-types/grid": "3.0.0-nightly-c81a23ccd-250409",
72
- "@react-types/provider": "3.0.0-nightly-c81a23ccd-250409",
73
- "@react-types/shared": "3.0.0-nightly-c81a23ccd-250409",
74
- "@react-types/table": "3.0.0-nightly-c81a23ccd-250409",
75
- "@react-types/textfield": "3.0.0-nightly-c81a23ccd-250409",
60
+ "@internationalized/number": "3.0.0-nightly-9723225d6-250412",
61
+ "@react-aria/collections": "3.0.0-nightly-9723225d6-250412",
62
+ "@react-aria/focus": "3.0.0-nightly-9723225d6-250412",
63
+ "@react-aria/i18n": "3.0.0-nightly-9723225d6-250412",
64
+ "@react-aria/interactions": "3.0.0-nightly-9723225d6-250412",
65
+ "@react-aria/live-announcer": "3.0.0-nightly-9723225d6-250412",
66
+ "@react-aria/utils": "3.0.0-nightly-9723225d6-250412",
67
+ "@react-spectrum/utils": "3.0.0-nightly-9723225d6-250412",
68
+ "@react-stately/layout": "3.0.0-nightly-9723225d6-250412",
69
+ "@react-stately/utils": "3.0.0-nightly-9723225d6-250412",
70
+ "@react-types/dialog": "3.0.0-nightly-9723225d6-250412",
71
+ "@react-types/grid": "3.0.0-nightly-9723225d6-250412",
72
+ "@react-types/provider": "3.0.0-nightly-9723225d6-250412",
73
+ "@react-types/shared": "3.0.0-nightly-9723225d6-250412",
74
+ "@react-types/table": "3.0.0-nightly-9723225d6-250412",
75
+ "@react-types/textfield": "3.0.0-nightly-9723225d6-250412",
76
76
  "csstype": "^3.0.2",
77
- "react-aria": "3.0.0-nightly-c81a23ccd-250409",
78
- "react-aria-components": "3.0.0-nightly-c81a23ccd-250409"
77
+ "react-aria": "3.0.0-nightly-9723225d6-250412",
78
+ "react-aria-components": "3.0.0-nightly-9723225d6-250412",
79
+ "react-stately": "3.0.0-nightly-9723225d6-250412"
79
80
  },
80
81
  "peerDependencies": {
81
82
  "react": "^18.0.0 || ^19.0.0-rc.1",
@@ -312,6 +312,7 @@ export const ActionButton = forwardRef(function ActionButton(props: ActionButton
312
312
  styles: style({marginStart: '--iconMargin', flexShrink: 0, order: 0})
313
313
  }],
314
314
  [NotificationBadgeContext, {
315
+ staticColor: staticColor,
315
316
  size: props.size === 'XS' ? undefined : props.size,
316
317
  isDisabled: props.isDisabled,
317
318
  styles: style({position: 'absolute', top: '--badgeTop', insetStart: '[var(--badgePosition)]', marginTop: '[calc((self(height) * -1)/2)]', marginStart: '[calc((self(height) * -1)/2)]'})
package/src/Card.tsx CHANGED
@@ -501,7 +501,7 @@ export interface CardPreviewProps extends UnsafeStyles, DOMProps {
501
501
 
502
502
  export const CardPreview = forwardRef(function CardPreview(props: CardPreviewProps, ref: DOMRef<HTMLDivElement>) {
503
503
  let {size, isQuiet, isHovered, isFocusVisible, isSelected, isPressed, isCheckboxSelection} = useContext(InternalCardContext);
504
- let {UNSAFE_className, UNSAFE_style} = props;
504
+ let {UNSAFE_className = '', UNSAFE_style} = props;
505
505
  let domRef = useDOMRef(ref);
506
506
  return (
507
507
  <div
@@ -50,6 +50,7 @@ export const ColorSwatchPicker = forwardRef(function ColorSwatchPicker(props: Co
50
50
  density = 'regular',
51
51
  size = 'M',
52
52
  rounding = 'none',
53
+ UNSAFE_className = '',
53
54
  ...otherProps
54
55
  } = props;
55
56
  let domRef = useDOMRef(ref);
@@ -58,7 +59,7 @@ export const ColorSwatchPicker = forwardRef(function ColorSwatchPicker(props: Co
58
59
  <AriaColorSwatchPicker
59
60
  {...otherProps}
60
61
  ref={domRef}
61
- className={props.UNSAFE_className + style({
62
+ className={UNSAFE_className + style({
62
63
  display: 'flex',
63
64
  flexWrap: 'wrap',
64
65
  gap: {
package/src/Content.tsx CHANGED
@@ -37,7 +37,7 @@ export const Heading = forwardRef(// Wrapper around RAC Heading to unmount when
37
37
  function Heading(props: HeadingProps, ref: DOMRef<HTMLHeadingElement>) {
38
38
  [props, ref] = useSpectrumContextProps(props, ref, HeadingContext);
39
39
  let domRef = useDOMRef(ref);
40
- let {UNSAFE_className = '', UNSAFE_style, styles, isHidden, slot, ...otherProps} = props;
40
+ let {UNSAFE_className = '', UNSAFE_style, styles = '', isHidden, slot, ...otherProps} = props;
41
41
  if (isHidden) {
42
42
  return null;
43
43
  }
@@ -57,7 +57,7 @@ export const HeaderContext = createContext<ContextValue<Partial<ContentProps>, D
57
57
  export const Header = forwardRef(function Header(props: ContentProps, ref: DOMRef) {
58
58
  [props, ref] = useSpectrumContextProps(props, ref, HeaderContext);
59
59
  let domRef = useDOMRef(ref);
60
- let {UNSAFE_className = '', UNSAFE_style, styles, isHidden, slot, ...otherProps} = props;
60
+ let {UNSAFE_className = '', UNSAFE_style, styles = '', isHidden, slot, ...otherProps} = props;
61
61
  if (isHidden) {
62
62
  return null;
63
63
  }
@@ -77,7 +77,7 @@ export const ContentContext = createContext<ContextValue<Partial<ContentProps>,
77
77
  export const Content = forwardRef(function Content(props: ContentProps, ref: DOMRef<HTMLDivElement>) {
78
78
  [props, ref] = useSpectrumContextProps(props, ref, ContentContext);
79
79
  let domRef = useDOMRef(ref);
80
- let {UNSAFE_className = '', UNSAFE_style, styles, isHidden, slot, ...otherProps} = props;
80
+ let {UNSAFE_className = '', UNSAFE_style, styles = '', isHidden, slot, ...otherProps} = props;
81
81
  if (isHidden) {
82
82
  return null;
83
83
  }
@@ -96,7 +96,7 @@ export const TextContext = createContext<ContextValue<Partial<ContentProps>, DOM
96
96
  export const Text = forwardRef(function Text(props: ContentProps, ref: DOMRef) {
97
97
  [props, ref] = useSpectrumContextProps(props, ref, TextContext);
98
98
  let domRef = useDOMRef(ref);
99
- let {UNSAFE_className = '', UNSAFE_style, styles, isHidden, slot, children, ...otherProps} = props;
99
+ let {UNSAFE_className = '', UNSAFE_style, styles = '', isHidden, slot, children, ...otherProps} = props;
100
100
  let racContext = useContext(RACTextContext);
101
101
  let isSkeleton = useIsSkeleton();
102
102
  [children, UNSAFE_style] = useSkeletonText(children, UNSAFE_style);
@@ -130,7 +130,7 @@ export const KeyboardContext = createContext<ContextValue<Partial<ContentProps>,
130
130
  export const Keyboard = forwardRef(function Keyboard(props: ContentProps, ref: DOMRef) {
131
131
  [props, ref] = useSpectrumContextProps(props, ref, KeyboardContext);
132
132
  let domRef = useDOMRef(ref);
133
- let {UNSAFE_className = '', UNSAFE_style, styles, isHidden, slot, ...otherProps} = props;
133
+ let {UNSAFE_className = '', UNSAFE_style, styles = '', isHidden, slot, ...otherProps} = props;
134
134
  if (isHidden) {
135
135
  return null;
136
136
  }
@@ -149,7 +149,7 @@ export const FooterContext = createContext<ContextValue<Partial<ContentProps>, D
149
149
  export const Footer = forwardRef(function Footer(props: ContentProps, ref: DOMRef) {
150
150
  [props, ref] = useSpectrumContextProps(props, ref, FooterContext);
151
151
  let domRef = useDOMRef(ref);
152
- let {UNSAFE_className = '', UNSAFE_style, styles, isHidden, slot, ...otherProps} = props;
152
+ let {UNSAFE_className = '', UNSAFE_style, styles = '', isHidden, slot, ...otherProps} = props;
153
153
  if (isHidden) {
154
154
  return null;
155
155
  }
@@ -130,10 +130,10 @@ const buttonStyles = style({
130
130
  fontWeight: 'bold',
131
131
  fontSize: {
132
132
  size: {
133
- S: 'heading-xs',
134
- M: 'heading-sm',
135
- L: 'heading',
136
- XL: 'heading-lg'
133
+ S: 'title-sm',
134
+ M: 'title',
135
+ L: 'title-lg',
136
+ XL: 'title-xl'
137
137
  }
138
138
  },
139
139
  lineHeight: 'ui',
@@ -147,32 +147,32 @@ const buttonStyles = style({
147
147
  // compact is equivalent to 'control', but other densities have more padding.
148
148
  size: {
149
149
  S: {
150
+ density: {
151
+ compact: 18,
152
+ regular: 24,
153
+ spacious: 32
154
+ }
155
+ },
156
+ M: {
150
157
  density: {
151
158
  compact: 24,
152
159
  regular: 32,
153
160
  spacious: 40
154
161
  }
155
162
  },
156
- M: {
163
+ L: {
157
164
  density: {
158
165
  compact: 32,
159
166
  regular: 40,
160
167
  spacious: 48
161
168
  }
162
169
  },
163
- L: {
170
+ XL: {
164
171
  density: {
165
172
  compact: 40,
166
173
  regular: 48,
167
174
  spacious: 56
168
175
  }
169
- },
170
- XL: {
171
- density: {
172
- compact: 48,
173
- regular: 56,
174
- spacious: 64
175
- }
176
176
  }
177
177
  }
178
178
  },
@@ -219,18 +219,12 @@ function DisclosureHeaderWithForwardRef(props: DisclosureHeaderProps, ref: DOMRe
219
219
  let domRef = useDOMRef(ref);
220
220
  let {size, isQuiet, density} = useSlottedContext(DisclosureContext)!;
221
221
 
222
- let mapSize = {
223
- S: 'XS',
224
- M: 'S',
225
- L: 'M',
226
- XL: 'L'
227
- };
228
-
229
- // maps to one size smaller in the compact density to ensure there is space between the top and bottom of the action button and container
222
+ // Shift button size down by 2 for compact density, 1 for regular/spacious to ensure there is space between the top and bottom of the action button and container
230
223
  let newSize : 'XS' | 'S' | 'M' | 'L' | 'XL' | undefined = size;
231
- if (density === 'compact') {
232
- newSize = mapSize[size ?? 'M'] as 'XS' | 'S' | 'M' | 'L';
233
- }
224
+ const sizes = ['XS', 'S', 'M', 'L', 'XL'];
225
+ const currentIndex = sizes.indexOf(size ?? 'M');
226
+ const shift = density === 'compact' ? 2 : 1;
227
+ newSize = sizes[Math.max(0, currentIndex - shift)] as 'XS' | 'S' | 'M' | 'L' | 'XL';
234
228
 
235
229
  return (
236
230
  <Provider
@@ -40,7 +40,8 @@ export interface NotificationBadgeProps extends DOMProps, AriaLabelingProps, Sty
40
40
  }
41
41
 
42
42
  interface NotificationBadgeContextProps extends Partial<NotificationBadgeProps> {
43
- isDisabled?: boolean
43
+ isDisabled?: boolean,
44
+ staticColor?: 'black' | 'white' | 'auto'
44
45
  }
45
46
 
46
47
  export const NotificationBadgeContext = createContext<ContextValue<Partial<NotificationBadgeContextProps>, DOMRefValue<HTMLDivElement>>>(null);
@@ -53,6 +54,7 @@ const badge = style({
53
54
  font: 'control',
54
55
  color: {
55
56
  default: 'white',
57
+ isStaticColor: 'auto',
56
58
  forcedColors: 'ButtonText'
57
59
  },
58
60
  fontSize: {
@@ -76,6 +78,7 @@ const badge = style({
76
78
  alignItems: 'center',
77
79
  backgroundColor: {
78
80
  default: 'accent',
81
+ isStaticColor: 'transparent-overlay-1000',
79
82
  forcedColors: 'ButtonFace'
80
83
  },
81
84
  height: {
@@ -102,7 +105,7 @@ const badge = style({
102
105
  isIndicatorOnly: 'square',
103
106
  isSingleDigit: 'square'
104
107
  },
105
- width: 'fit',
108
+ width: 'max',
106
109
  paddingX: {
107
110
  isDoubleDigit: 'edge-to-text'
108
111
  },
@@ -119,6 +122,7 @@ export const NotificationBadge = forwardRef(function Badge(props: NotificationBa
119
122
  size = 'S',
120
123
  value,
121
124
  isDisabled = false,
125
+ staticColor,
122
126
  ...otherProps
123
127
  } = props as NotificationBadgeContextProps;
124
128
  let domRef = useDOMRef(ref);
@@ -159,7 +163,7 @@ export const NotificationBadge = forwardRef(function Badge(props: NotificationBa
159
163
  {...filterDOMProps(otherProps, {labelable: true})}
160
164
  role={ariaLabel && 'img'}
161
165
  aria-label={ariaLabel}
162
- className={(props.UNSAFE_className || '') + badge({size, isIndicatorOnly, isSingleDigit, isDoubleDigit, isDisabled}, props.styles)}
166
+ className={(props.UNSAFE_className || '') + badge({size, isIndicatorOnly, isSingleDigit, isDoubleDigit, isDisabled, isStaticColor: !!staticColor}, props.styles)}
163
167
  style={props.UNSAFE_style}
164
168
  ref={domRef}>
165
169
  {formattedValue}
package/src/TableView.tsx CHANGED
@@ -54,7 +54,7 @@ import {IconContext} from './Icon';
54
54
  // @ts-ignore
55
55
  import intlMessages from '../intl/*.json';
56
56
  import {LayoutNode} from '@react-stately/layout';
57
- import {Menu, MenuItem, MenuTrigger} from './Menu';
57
+ import {Menu, MenuItem, MenuSection, MenuTrigger} from './Menu';
58
58
  import {mergeStyles} from '../style/runtime';
59
59
  import Nubbin from '../ui-icons/S2_MoveHorizontalTableWidget.svg';
60
60
  import {ProgressCircle} from './ProgressCircle';
@@ -466,7 +466,7 @@ const columnStyles = style({
466
466
  },
467
467
  paddingX: {
468
468
  default: 16,
469
- isColumnResizable: 0
469
+ isMenu: 0
470
470
  },
471
471
  textAlign: {
472
472
  align: {
@@ -493,7 +493,7 @@ const columnStyles = style({
493
493
  borderStartWidth: 0,
494
494
  borderEndWidth: {
495
495
  default: 0,
496
- isColumnResizable: 1
496
+ isMenu: 1
497
497
  },
498
498
  borderStyle: 'solid',
499
499
  forcedColorAdjust: 'none'
@@ -510,7 +510,9 @@ export interface ColumnProps extends RACColumnProps {
510
510
  */
511
511
  align?: 'start' | 'center' | 'end',
512
512
  /** The content to render as the column header. */
513
- children: ReactNode
513
+ children: ReactNode,
514
+ /** Menu fragment to be rendered inside the column header's menu. */
515
+ UNSTABLE_menuItems?: ReactNode
514
516
  }
515
517
 
516
518
  /**
@@ -520,21 +522,22 @@ export const Column = forwardRef(function Column(props: ColumnProps, ref: DOMRef
520
522
  let {isQuiet} = useContext(InternalTableContext);
521
523
  let {allowsResizing, children, align = 'start'} = props;
522
524
  let domRef = useDOMRef(ref);
523
- let isColumnResizable = allowsResizing;
525
+ let isMenu = allowsResizing || !!props.UNSTABLE_menuItems;
526
+
524
527
 
525
528
  return (
526
- <RACColumn {...props} ref={domRef} style={{borderInlineEndColor: 'transparent'}} className={renderProps => columnStyles({...renderProps, isColumnResizable, align, isQuiet})}>
529
+ <RACColumn {...props} ref={domRef} style={{borderInlineEndColor: 'transparent'}} className={renderProps => columnStyles({...renderProps, isMenu, align, isQuiet})}>
527
530
  {({allowsSorting, sortDirection, isFocusVisible, sort, startResize}) => (
528
531
  <>
529
532
  {/* Note this is mainly for column's without a dropdown menu. If there is a dropdown menu, the button is styled to have a focus ring for simplicity
530
533
  (no need to juggle showing this focus ring if focus is on the menu button and not if it is on the resizer) */}
531
534
  {/* Separate absolutely positioned element because appyling the ring on the column directly via outline means the ring's required borderRadius will cause the bottom gray border to curve as well */}
532
535
  {isFocusVisible && <CellFocusRing />}
533
- {isColumnResizable ?
536
+ {isMenu ?
534
537
  (
535
- <ResizableColumnContents allowsSorting={allowsSorting} sortDirection={sortDirection} sort={sort} startResize={startResize} align={align}>
538
+ <ColumnWithMenu isColumnResizable={allowsResizing} menuItems={props.UNSTABLE_menuItems} allowsSorting={allowsSorting} sortDirection={sortDirection} sort={sort} startResize={startResize} align={align}>
536
539
  {children}
537
- </ResizableColumnContents>
540
+ </ColumnWithMenu>
538
541
  ) : (
539
542
  <ColumnContents allowsSorting={allowsSorting} sortDirection={sortDirection}>
540
543
  {children}
@@ -704,10 +707,13 @@ const nubbin = style({
704
707
  }
705
708
  });
706
709
 
707
- interface ResizableColumnContentProps extends Pick<ColumnRenderProps, 'allowsSorting' | 'sort' | 'sortDirection' | 'startResize'>, Pick<ColumnProps, 'align' | 'children'> {}
710
+ interface ColumnWithMenuProps extends Pick<ColumnRenderProps, 'allowsSorting' | 'sort' | 'sortDirection' | 'startResize'>, Pick<ColumnProps, 'align' | 'children'> {
711
+ isColumnResizable?: boolean,
712
+ menuItems?: ReactNode
713
+ }
708
714
 
709
- function ResizableColumnContents(props: ResizableColumnContentProps) {
710
- let {allowsSorting, sortDirection, sort, startResize, children, align} = props;
715
+ function ColumnWithMenu(props: ColumnWithMenuProps) {
716
+ let {allowsSorting, sortDirection, sort, startResize, children, align, isColumnResizable, menuItems} = props;
711
717
  let {setIsInResizeMode, isInResizeMode} = useContext(InternalTableContext);
712
718
  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/s2');
713
719
  const onMenuSelect = (key) => {
@@ -726,12 +732,13 @@ function ResizableColumnContents(props: ResizableColumnContentProps) {
726
732
  };
727
733
 
728
734
  let items = useMemo(() => {
729
- let options = [
730
- {
735
+ let options: Array<{label: string, id: string}> = [];
736
+ if (isColumnResizable) {
737
+ options = [{
731
738
  label: stringFormatter.format('table.resizeColumn'),
732
739
  id: 'resize'
733
- }
734
- ];
740
+ }];
741
+ }
735
742
  if (allowsSorting) {
736
743
  options = [
737
744
  {
@@ -747,7 +754,7 @@ function ResizableColumnContents(props: ResizableColumnContentProps) {
747
754
  }
748
755
  return options;
749
756
  // eslint-disable-next-line react-hooks/exhaustive-deps
750
- }, [allowsSorting]);
757
+ }, [allowsSorting, isColumnResizable]);
751
758
 
752
759
  let buttonAlignment = 'start';
753
760
  let menuAlign = 'start' as 'start' | 'end';
@@ -779,20 +786,29 @@ function ResizableColumnContents(props: ResizableColumnContentProps) {
779
786
  </div>
780
787
  <Chevron size="M" className={chevronIcon} />
781
788
  </Button>
782
- <Menu onAction={onMenuSelect} items={items} styles={style({minWidth: 128})}>
783
- {(item) => <MenuItem>{item?.label}</MenuItem>}
789
+ <Menu onAction={onMenuSelect} styles={style({minWidth: 128})}>
790
+ {items.length > 0 && (
791
+ <MenuSection aria-label={stringFormatter.format('table.standardColumnMenu')}>
792
+ <Collection items={items}>
793
+ {(item) => <MenuItem>{item?.label}</MenuItem>}
794
+ </Collection>
795
+ </MenuSection>
796
+ )}
797
+ {menuItems}
784
798
  </Menu>
785
799
  </MenuTrigger>
786
- <div data-react-aria-prevent-focus="true">
787
- <ColumnResizer data-react-aria-prevent-focus="true" className={({resizableDirection, isResizing}) => resizerHandleContainer({resizableDirection, isResizing, isInResizeMode})}>
788
- {({isFocusVisible, isResizing}) => (
789
- <>
790
- <ResizerIndicator isInResizeMode={isInResizeMode} isFocusVisible={isFocusVisible} isResizing={isResizing} />
791
- {(isFocusVisible || isInResizeMode) && isResizing && <div className={nubbin}><Nubbin /></div>}
792
- </>
793
- )}
794
- </ColumnResizer>
795
- </div>
800
+ {isColumnResizable && (
801
+ <div data-react-aria-prevent-focus="true">
802
+ <ColumnResizer data-react-aria-prevent-focus="true" className={({resizableDirection, isResizing}) => resizerHandleContainer({resizableDirection, isResizing, isInResizeMode})}>
803
+ {({isFocusVisible, isResizing}) => (
804
+ <>
805
+ <ResizerIndicator isInResizeMode={isInResizeMode} isFocusVisible={isFocusVisible} isResizing={isResizing} />
806
+ {(isFocusVisible || isInResizeMode) && isResizing && <div className={nubbin}><Nubbin /></div>}
807
+ </>
808
+ )}
809
+ </ColumnResizer>
810
+ </div>
811
+ )}
796
812
  </>
797
813
  );
798
814
  }
@@ -0,0 +1,153 @@
1
+ /* Safari doesn't support :active-view-transition-type() yet, so we fall back to a class on the html element */
2
+ html.toast-add,
3
+ html.toast-remove,
4
+ html.toast-expand,
5
+ html.toast-collapse,
6
+ html.toast-clear,
7
+ html:active-view-transition-type(toast-add, toast-remove, toast-expand, toast-collapse, toast-clear) {
8
+ view-transition-name: none;
9
+
10
+ .toast-controls {
11
+ view-transition-name: toast-controls;
12
+ }
13
+
14
+ .toast-background {
15
+ view-transition-name: toast-background;
16
+ }
17
+
18
+ &::view-transition-group(toast-background) {
19
+ z-index: -1;
20
+ }
21
+
22
+ &::view-transition-group(*) {
23
+ animation-duration: 400ms;
24
+ }
25
+ }
26
+
27
+ html.toast-add,
28
+ html.toast-remove,
29
+ html:active-view-transition-type(toast-add, toast-remove) {
30
+ /* The new toast should slide in and out. With reduce motion enabled, it fades by default. */
31
+ @media (prefers-reduced-motion: no-preference) {
32
+ &::view-transition-new(.toast):only-child {
33
+ animation-name: slide-in;
34
+ }
35
+
36
+ &::view-transition-old(.toast):only-child {
37
+ animation-name: slide-out;
38
+ }
39
+ }
40
+
41
+ &::view-transition-group(.toast.bottom) {
42
+ --slideX: 0;
43
+ --slideY: calc(100% + 12px);
44
+ }
45
+
46
+ &::view-transition-group(.toast.top) {
47
+ --slideX: 0;
48
+ --slideY: calc(-100% - 12px);
49
+ }
50
+
51
+ &::view-transition-group(.toast.start) {
52
+ --slideX: calc(-100% - 12px);
53
+ --slideY: 0;
54
+ }
55
+
56
+ &::view-transition-group(.toast.end) {
57
+ --slideX: calc(100% + 12px);
58
+ --slideY: 0;
59
+ }
60
+ }
61
+
62
+ /* Make the "Show all" button animate slightly faster/slower than other components when expanding/collapsing.
63
+ * This prevents it from appearing to overlap the text when it fades out and the text repositions. */
64
+ html.toast-expand,
65
+ html:active-view-transition-type(toast-expand) {
66
+ &::view-transition-group(toast-expand) {
67
+ animation-duration: 300ms;
68
+ }
69
+ }
70
+
71
+ html.toast-collapse,
72
+ html:active-view-transition-type(toast-collapse) {
73
+ &::view-transition-group(toast-expand) {
74
+ animation-duration: 600ms;
75
+ }
76
+ }
77
+
78
+ html.toast-expand,
79
+ html.toast-collapse,
80
+ html:active-view-transition-type(toast-expand, toast-collapse) {
81
+ @media (prefers-reduced-motion: no-preference) {
82
+ /* When expanding/collapsing, animate the components of the main toast individually. */
83
+ .toast-content {
84
+ view-transition-name: toast-content;
85
+ }
86
+
87
+ .toast-expand {
88
+ view-transition-name: toast-expand;
89
+ }
90
+
91
+ .toast-action {
92
+ view-transition-name: toast-action;
93
+ }
94
+
95
+ .toast-close {
96
+ view-transition-name: toast-close;
97
+ }
98
+
99
+ /* Force toast controls to be visible during the animation */
100
+ .toast-controls {
101
+ display: flex;
102
+ }
103
+
104
+ /* Smoothly transition the size of toasts. */
105
+ &::view-transition-old(.toast),
106
+ &::view-transition-new(.toast) {
107
+ /* Make the old and new images fill the size of the parent group. */
108
+ height: 100%;
109
+ width: 100%;
110
+ }
111
+
112
+ /* Background toasts don't have their components split apart in separate view transitions.
113
+ * This means we need to do some tricks to get the aspect ratio to transition smoothly.
114
+ * Clipping messes up the shadows a bit, but it's less noticeable on the background toasts. */
115
+ &::view-transition-old(.background-toast),
116
+ &::view-transition-new(.background-toast) {
117
+ /* Cover all of the available space without stretching the aspect ratio */
118
+ object-fit: cover;
119
+ object-position: top center;
120
+ /* Clip to retain rounded corners */
121
+ clip-path: inset(0px round 10px);
122
+ }
123
+ }
124
+
125
+ @media (prefers-reduced-motion) {
126
+ /* Do not animate individual toasts in reduced motion. The whole list cross-fades instead. */
127
+ .toast {
128
+ view-transition-name: none !important;
129
+ }
130
+
131
+ .toast-list-expanded {
132
+ view-transition-name: toast-list-expanded;
133
+ }
134
+
135
+ .toast-list-collapsed {
136
+ view-transition-name: toast-list-collapsed;
137
+ }
138
+ }
139
+ }
140
+
141
+ @keyframes slide-in {
142
+ from {
143
+ translate: var(--slideX) var(--slideY);
144
+ opacity: 0;
145
+ }
146
+ }
147
+
148
+ @keyframes slide-out {
149
+ to {
150
+ translate: var(--slideX) var(--slideY);
151
+ opacity: 0;
152
+ }
153
+ }