Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ v3:
- all:
- changed-files:
- all-globs-to-any-file: ['**/@react-spectrum/**', '!**/*.stories.*', '!**/*.test.*']
- all-globs-to-all-files: '!**/@react-spectrum/s2/**'
- all-globs-to-all-files: ['!**/@react-spectrum/s2/**', '!**/@react-spectrum/ai/**']

Accordion:
- changed-files:
Expand Down
2 changes: 2 additions & 0 deletions .storybook/.parcelrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"resolvers": ["@parcel/resolver-glob", "..."],
"transformers": {
"packages/**/intl/**/*.json": ["parcel-transformer-intl"],
"starters/**/*.css": ["@parcel/transformer-css"],
"packages/react-aria-components/stories/styles.global.css": ["@parcel/transformer-css"],
"raw:*": ["@parcel/transformer-raw"]
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"start:mcp": "yarn workspace @react-spectrum/s2-docs generate:md && yarn build:mcp && node packages/dev/mcp/s2/dist/index.js && node packages/dev/mcp/react-aria/dist/index.js",
"test:mcp": "yarn build:s2-docs && yarn build:mcp && node packages/dev/mcp/scripts/smoke-list-pages.mjs",
"test": "cross-env STRICT_MODE=1 VIRT_ON=1 yarn jest",
"test:browser": " yarn playwright install && vitest --config=vitest.browser.config.ts",
"test:browser": "yarn playwright install && vitest run --config=vitest.browser.config.ts",
"test:browser:watch": "yarn playwright install && vitest --config=vitest.browser.config.ts",
"test:lint": "ls packages/**/*.test-lint.js | xargs -n 1 node",
"test-loose": "cross-env VIRT_ON=1 yarn jest",
"test-storybook": "test-storybook --url http://localhost:9003 --browsers chromium --no-cache",
Expand Down
5 changes: 3 additions & 2 deletions packages/@adobe/react-spectrum/src/actionbar/ActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ function ActionBarInner<T>(props: ActionBarInnerProps<T>, ref: Ref<HTMLDivElemen
}

let {keyboardProps} = useKeyboard({
shortcuts: {
Escape: () => {
onKeyDown(e) {
if (e.key === 'Escape') {
e.preventDefault();
onClearSelection();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export const ActionGroup = forwardRef(function ActionGroup<T extends object>(
<ActionGroupMenu
{...menuProps}
items={menuChildren}
onAction={onAction}
onAction={key => onAction?.(key)}
isDisabled={isDisabled}
isEmphasized={isEmphasized}
staticColor={staticColor}
Expand Down
4 changes: 2 additions & 2 deletions packages/@adobe/react-spectrum/src/card/BaseLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@ export class BaseLayout<T>

getFirstKey(): Node<T> | undefined {
let firstRow = this.collection.getItem(this.collection.getFirstKey());
return getFirstItem(getChildNodes(firstRow, this.collection))?.key;
return firstRow ? getFirstItem(getChildNodes(firstRow, this.collection))?.key : null;
}

getLastKey(): Node<T> | undefined {
let lastRow = this.collection.getItem(this.collection.getLastKey());
return getFirstItem(getChildNodes(lastRow, this.collection))?.key;
return lastRow ? getFirstItem(getChildNodes(lastRow, this.collection))?.key : null;
}

// TODO: pretty unwieldy because it needs to bounce back and forth between the parent key and the child key
Expand Down
12 changes: 6 additions & 6 deletions packages/@adobe/react-spectrum/test/menu/Menu.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -659,15 +659,15 @@ describe('Menu', function () {
];

await user.click(item1);
expect(onAction).toHaveBeenCalledWith('One');
expect(onAction).toHaveBeenCalledWith('One', null);
expect(onSelectionChange).toHaveBeenCalledTimes(0);

await user.click(item2);
expect(onAction).toHaveBeenCalledWith('Two');
expect(onAction).toHaveBeenCalledWith('Two', null);
expect(onSelectionChange).toHaveBeenCalledTimes(0);

await user.click(item3);
expect(onAction).toHaveBeenCalledWith('Three');
expect(onAction).toHaveBeenCalledWith('Three', null);
expect(onSelectionChange).toHaveBeenCalledTimes(0);
});

Expand Down Expand Up @@ -701,15 +701,15 @@ describe('Menu', function () {
];

await user.click(item1);
expect(onAction).toHaveBeenCalledWith('One');
expect(onAction).toHaveBeenCalledWith('One', {name: 'One'});
expect(onSelectionChange).toHaveBeenCalledTimes(0);

await user.click(item2);
expect(onAction).toHaveBeenCalledWith('Two');
expect(onAction).toHaveBeenCalledWith('Two', {name: 'Two'});
expect(onSelectionChange).toHaveBeenCalledTimes(0);

await user.click(item3);
expect(onAction).toHaveBeenCalledWith('Three');
expect(onAction).toHaveBeenCalledWith('Three', {name: 'Three'});
expect(onSelectionChange).toHaveBeenCalledTimes(0);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ describe('Submenu', function () {
expect(onAction).not.toHaveBeenCalled();
expect(onClose).not.toHaveBeenCalled();
expect(submenuOnAction).toHaveBeenCalledTimes(1);
expect(submenuOnAction).toHaveBeenLastCalledWith('Lvl 2 Item 2');
expect(submenuOnAction).toHaveBeenLastCalledWith('Lvl 2 Item 2', null);
expect(submenuOnClose).toHaveBeenCalledTimes(1);
expect(onOpenChange).toHaveBeenCalledTimes(4);
expect(onOpenChange).toHaveBeenLastCalledWith(false);
Expand Down Expand Up @@ -725,7 +725,7 @@ describe('Submenu', function () {
menus = tree.queryAllByRole('menu');
expect(menus).toHaveLength(0);
expect(onAction).toHaveBeenCalledTimes(1);
expect(onAction).toHaveBeenLastCalledWith('Lvl 1 Item 1');
expect(onAction).toHaveBeenLastCalledWith('Lvl 1 Item 1', null);
});

it('supports selectionMode and onSelectionChange on submenus', async function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ governing permissions and limitations under the License.
align-items: flex-start;
/* necessary so that offsetLeft on button children is correct */
position: relative;
max-width: 100%;

.spectrum-ButtonGroup-Button {
flex-shrink: 0;
Expand Down
70 changes: 64 additions & 6 deletions packages/@react-spectrum/ai/src/AttachmentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@
* governing permissions and limitations under the License.
*/

import {AriaLabelingProps, DOMRef} from '@react-types/shared';
import {AriaLabelingProps, DOMRef, forwardRefType} from '@react-types/shared';
import {baseColor, focusRing, style} from '@react-spectrum/s2/style' with {type: 'macro'};
import {BasicHorizontalCard} from './HorizontalCard';
import {Button} from 'react-aria-components/Button';
import {CardProps} from '@react-spectrum/s2/Card';
import Close from '@react-spectrum/s2/icons/Close';
import {forwardRef, useRef} from 'react';
import {iconStyle} from '@react-spectrum/s2/style' with {type: 'macro'};
import {ImageContext} from '@react-spectrum/s2/Image';
import {mergeStyles} from '@react-spectrum/s2/mergeStyles';
import {pressScale} from '@react-spectrum/s2/pressScale';
import {Tag, TagGroup, TagList} from 'react-aria-components/TagGroup';
import {ProgressCircle} from '@react-spectrum/s2/ProgressCircle';
import {StyleProps, TagProps} from '@react-spectrum/s2';
import {Tag, TagGroup, TagGroupProps, TagList, TagListProps} from 'react-aria-components/TagGroup';
import {useDOMRef} from './useDOMRef';

const controlSizeM = {
Expand Down Expand Up @@ -103,14 +106,22 @@ const CloseButton = function CloseButton(props) {
);
};

export const AttachmentList = forwardRef(function AttachmentList(
props: any,
export interface AttachmentListProps<T>
extends
Omit<TagGroupProps, 'children'>,
StyleProps,
Pick<TagListProps<T>, 'items' | 'children' | 'dependencies'> {}

export const AttachmentList = (forwardRef as forwardRefType)(function AttachmentList<T>(
props: AttachmentListProps<T>,
ref: DOMRef<HTMLDivElement>
) {
let domRef = useDOMRef(ref);
return (
<TagGroup {...props} className={props.styles} ref={domRef}>
<TagList
items={props.items}
dependencies={props.dependencies}
className={style({
display: 'flex',
flexDirection: 'row',
Expand All @@ -125,11 +136,17 @@ export const AttachmentList = forwardRef(function AttachmentList(
);
});

export interface AttachmentProps
extends CardProps, AriaLabelingProps, Pick<TagProps, 'id' | 'textValue'> {
uploadProgress?: number;
}

export const Attachment = forwardRef(function Attachment(
props: CardProps & AriaLabelingProps,
props: AttachmentProps,
ref: DOMRef<HTMLDivElement>
) {
let {
id,
textValue,
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledby,
Expand All @@ -139,6 +156,7 @@ export const Attachment = forwardRef(function Attachment(
let domRef = useDOMRef(ref);
return (
<Tag
id={id}
textValue={textValue}
aria-label={ariaLabel}
aria-labelledby={ariaLabelledby}
Expand All @@ -151,7 +169,47 @@ export const Attachment = forwardRef(function Attachment(
...focusRing(),
borderRadius: 'default'
})}>
<BasicHorizontalCard {...otherProps}>{props.children}</BasicHorizontalCard>
<BasicHorizontalCard {...otherProps}>
{props.uploadProgress != null && props.uploadProgress < 100 && (
<div
className={style({
position: 'absolute',
top: '50%',
insetStart: {
default: '50%',
':has(~ [data-slot=content])': 32
},
transform: 'translate(-50%, -50%)'
})}>
<ProgressCircle aria-label="Uploading" value={props.uploadProgress} size="S" />
</div>
)}
{/* Reduce opacity of the thumbnail if upload is in progress */}
<ImageContext.Consumer>
{ctx => (
<ImageContext.Provider
value={{
...ctx,
slots: {
thumbnail: {
...(ctx && 'slots' in ctx ? ctx.slots?.thumbnail : {}),
styles: mergeStyles(
ctx && 'slots' in ctx ? ctx.slots?.thumbnail?.styles : undefined,
style({
opacity: {default: 1, isUploading: 0.15},
transition: 'default'
})({isUploading: props.uploadProgress != null && props.uploadProgress < 100})
)
}
}
}}>
{typeof props.children === 'function'
? props.children({size: otherProps.size || 'M'})
: props.children}
</ImageContext.Provider>
)}
</ImageContext.Consumer>
</BasicHorizontalCard>
{/** Definitely not a close button, though looks like one. */}
<div
className={style({
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-spectrum/ai/src/MessageSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export const SourceListItem = (forwardRef as forwardRefType)(function SourceList

return (
<li ref={itemRef} className={mergeStyles(itemStyles, props.styles)}>
<NumberBadge value={index} />
<NumberBadge value={index} size={size} />
<Link {...otherProps} className={renderProps => linkStyles({size, ...renderProps})}>
{children}
</Link>
Expand Down Expand Up @@ -244,7 +244,7 @@ export const NumberBadge = forwardRef(function NumberBadge(
props: NumberBadgeProps,
ref: DOMRef<HTMLSpanElement>
) {
let {size = 'S', value, ...otherProps} = props;
let {size = 'M', value, ...otherProps} = props;
let domRef = useDOMRef(ref);
let {locale} = useLocale();
let formattedValue = '';
Expand Down
14 changes: 8 additions & 6 deletions packages/@react-spectrum/ai/src/MessageSuggestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@

import {AriaLabelingProps, DOMProps, DOMRef} from '@react-types/shared';
import ArrowCurved from '@react-spectrum/s2/icons/ArrowCurved';
import {
baseColor,
centerPadding,
focusRing,
style
} from '@react-spectrum/s2/style' with {type: 'macro'};
import {ButtonProps, Button as RACButton} from 'react-aria-components/Button';
import {CenterBaseline} from '@react-spectrum/s2/CenterBaseline';
import {centerPadding, focusRing, style} from '@react-spectrum/s2/style' with {type: 'macro'};
import {createContext, forwardRef, ReactNode, useContext} from 'react';
import {filterDOMProps} from 'react-aria/filterDOMProps';
import {IconContext} from '@react-spectrum/s2/Icon';
Expand Down Expand Up @@ -79,14 +84,11 @@ const suggestionStyles = style<{
XL: 'body-xl'
}
},
backgroundColor: {
default: 'gray-100',
isHovered: 'gray-200',
isPressed: 'gray-300'
},
backgroundColor: baseColor('gray-100'),
color: 'neutral',
borderStyle: 'none',
disableTapHighlight: true,
transition: 'default',
...focusRing()
});

Expand Down
Loading
Loading