Skip to content

Commit

Permalink
Merge branch 'strict-mode-fixes' of github.com:adobe/react-spectrum i…
Browse files Browse the repository at this point in the history
…nto focusscope_strict_mode_fix
  • Loading branch information
LFDanLu committed Jan 5, 2023
2 parents 1de38ac + ee03365 commit a68b999
Show file tree
Hide file tree
Showing 35 changed files with 543 additions and 365 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ node_modules
packages/*/*/dist
packages/react-aria/dist
packages/react-stately/dist
packages/dev/storybook-builder-preview/preview.js
packages/dev/storybook-builder-parcel/preview.js
37 changes: 37 additions & 0 deletions .storybook/custom-addons/strictmode/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {addons, makeDecorator} from '@storybook/addons';
import {getQueryParams} from '@storybook/client-api';
import React, {StrictMode, useEffect, useState} from 'react';

function StrictModeDecorator(props) {
let {children} = props;
let [isStrict, setStrict] = useState(getQueryParams()?.strict === 'true' || false);

useEffect(() => {
let channel = addons.getChannel();
let updateStrict = (val) => {
setStrict(val);
};
channel.on('strict/updated', updateStrict);
return () => {
channel.removeListener('strict/updated', updateStrict);
};
}, []);

return isStrict ? (
<StrictMode>
{children}
</StrictMode>
) : children;
}

export const withStrictModeSwitcher = makeDecorator({
name: 'withStrictModeSwitcher',
parameterName: 'strictModeSwitcher',
wrapper: (getStory, context) => {
return (
<StrictModeDecorator>
{getStory(context)}
</StrictModeDecorator>
);
}
});
40 changes: 40 additions & 0 deletions .storybook/custom-addons/strictmode/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {addons, types} from '@storybook/addons';
import {getQueryParams} from '@storybook/client-api';
import React, {useEffect, useState} from 'react';

const StrictModeToolBar = ({api}) => {
let channel = addons.getChannel();
let [isStrict, setStrict] = useState(getQueryParams()?.strict === 'true' || false);
let onChange = () => {
setStrict((old) => {
channel.emit('strict/updated', !old);
return !old;
})
};

useEffect(() => {
api.setQueryParams({
'strict': isStrict
});
});

return (
<div style={{display: 'flex', alignItems: 'center', fontSize: '12px'}}>
<div style={{marginRight: '10px'}}>
<label htmlFor="strictmode">StrictMode:
<input type="checkbox" id="strictmode" name="strictmode" checked={isStrict} onChange={onChange} />
</label>
</div>
</div>
);
};

addons.register('StrictModeSwitcher', (api) => {
addons.add('StrictModeSwitcher', {
title: 'Strict mode switcher',
type: types.TOOL,
//👇 Shows the Toolbar UI element if either the Canvas or Docs tab is active
match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)),
render: () => <StrictModeToolBar api={api} />
});
});
8 changes: 3 additions & 5 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ module.exports = {
'storybook-dark-mode',
'./custom-addons/provider/register',
'./custom-addons/descriptions/register',
'./custom-addons/theme/register'
'./custom-addons/theme/register',
'./custom-addons/strictmode/register'
],
typescript: {
check: false,
reactDocgen: false
},
reactOptions: {
strictMode: process.env.STRICT_MODE
},
}
};
2 changes: 2 additions & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {configureActions} from '@storybook/addon-actions';
import React from 'react';
import {VerticalCenter} from './layout';
import {withProviderSwitcher} from './custom-addons/provider';
import {withStrictModeSwitcher} from './custom-addons/strictmode';

// decorator order matters, the last one will be the outer most

Expand Down Expand Up @@ -29,5 +30,6 @@ export const decorators = [
<Story />
</VerticalCenter>
),
withStrictModeSwitcher,
withProviderSwitcher
];
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"install-16": "yarn add -W react@^16.8.0 react-dom@^16.8.0 @testing-library/react@^12 @testing-library/react-hooks@^8",
"install-17": "yarn add -W react@^17 react-dom@^17 @testing-library/react@^12 @testing-library/react-hooks@^8",
"start": "cross-env NODE_ENV=storybook start-storybook -p 9003 --ci -c '.storybook'",
"start-strict": "cross-env NODE_ENV=storybook STRICT_MODE=1 start-storybook -p 9003 --ci -c '.storybook'",
"build:storybook": "build-storybook -c .storybook -o dist/$(git rev-parse HEAD)/storybook",
"build:storybook-16": "build-storybook -c .storybook -o dist/$(git rev-parse HEAD)/storybook-16",
"build:storybook-17": "build-storybook -c .storybook -o dist/$(git rev-parse HEAD)/storybook-17",
Expand Down
52 changes: 30 additions & 22 deletions packages/@adobe/spectrum-css-temp/components/tags/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ governing permissions and limitations under the License.
@import '../commons/index.css';

.spectrum-Tags {
display: inline-flex;
display: flex;
flex-wrap: wrap;

margin: 0;
Expand All @@ -27,7 +27,7 @@ governing permissions and limitations under the License.
--spectrum-focus-ring-border-size: var(--spectrum-tag-border-size);

display: grid;
grid-template-columns: 1fr auto;
grid-template-columns: auto 1fr auto;
grid-template-areas: "icon content action";
align-items: center;
box-sizing: border-box;
Expand Down Expand Up @@ -58,28 +58,36 @@ governing permissions and limitations under the License.
height: calc(var(--spectrum-tag-height) - (2 * var(--spectrum-tag-border-size)));
width: var(--spectrum-global-dimension-size-300);
}
}

.spectrum-Tag-icon {
grid-area: icon;
margin-inline-end: var(--spectrum-global-dimension-size-100);
}
.spectrum-Tag-cell {
overflow: hidden;
text-overflow: ellipsis;
display: flex;
align-items: center;
}

.spectrum-Tag-content {
grid-area: content;
block-size: 100%;
line-height: calc(var(--spectrum-tag-height) - calc(var(--spectrum-tag-border-size) * 2));
margin-inline-end: var(--spectrum-tag-padding-x);
flex: 1 1 auto;
font-size: var(--spectrum-tag-text-size);
cursor: default;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
outline: none;
}
.spectrum-Tag-icon {
grid-area: icon;
margin-inline-end: var(--spectrum-global-dimension-size-100);
}

.spectrum-Tag-content {
grid-area: content;
line-height: calc(var(--spectrum-tag-height) - calc(var(--spectrum-tag-border-size) * 2));
margin-inline-end: var(--spectrum-tag-padding-x);
flex: 1 1 auto;
font-size: var(--spectrum-tag-text-size);
cursor: default;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
outline: none;
}

.tags-removable {
margin-inline-end: 0;
&.is-removable {
.spectrum-Tag-content {
margin-inline-end: 0;
}
}
}

13 changes: 1 addition & 12 deletions packages/@react-aria/table/src/useTableColumnResize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import {ChangeEvent, Key, RefObject, useCallback, useRef} from 'react';
import {ColumnSize} from '@react-types/table';
import {DOMAttributes, MoveEndEvent, MoveMoveEvent} from '@react-types/shared';
import {DOMAttributes} from '@react-types/shared';
import {focusSafely} from '@react-aria/focus';
import {focusWithoutScrolling, mergeProps, useId} from '@react-aria/utils';
import {getColumnHeaderId} from './utils';
Expand Down Expand Up @@ -40,13 +40,6 @@ export interface AriaTableColumnResizeProps<T> {
triggerRef?: RefObject<HTMLDivElement>,
/** If resizing is disabled. */
isDisabled?: boolean,
/** If the resizer was moved. Different from onResize because it is always called. */
onMove?: (e: MoveMoveEvent) => void,
/**
* If the resizer was moved. Different from onResizeEnd because it is always called.
* It also carries the interaction details in the object.
* */
onMoveEnd?: (e: MoveEndEvent) => void,
/** Called when resizing starts. */
onResizeStart?: (widths: Map<Key, number | string>) => void,
/** Called for every resize event that results in new column sizes. */
Expand Down Expand Up @@ -138,7 +131,6 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
}
deltaX *= 10;
}
props.onMove?.(e);
// if moving up/down only, no need to resize
if (deltaX !== 0) {
columnResizeWidthRef.current += deltaX;
Expand All @@ -148,7 +140,6 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
onMoveEnd(e) {
let {pointerType} = e;
columnResizeWidthRef.current = 0;
props.onMoveEnd?.(e);
if (pointerType === 'mouse') {
endResize(item);
}
Expand Down Expand Up @@ -186,8 +177,6 @@ export function useTableColumnResize<T>(props: AriaTableColumnResizeProps<T>, st
} else {
nextValue = currentWidth - 10;
}
props.onMove({pointerType: 'virtual'} as MoveMoveEvent);
props.onMoveEnd({pointerType: 'virtual'} as MoveEndEvent);
resize(item, nextValue);
};

Expand Down
2 changes: 1 addition & 1 deletion packages/@react-aria/tag/intl/en-US.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"remove": "Remove"
"remove": "Press Space or Delete to remove tag."
}
6 changes: 3 additions & 3 deletions packages/@react-aria/tag/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
"url": "https://github.com/adobe/react-spectrum"
},
"dependencies": {
"@react-aria/grid": "^3.5.2",
"@react-aria/gridlist": "^3.1.1",
"@react-aria/i18n": "^3.6.3",
"@react-aria/interactions": "^3.13.1",
"@react-aria/utils": "^3.14.2",
"@react-stately/grid": "^3.4.2",
"@react-types/grid": "^3.1.5",
"@react-stately/tag": "3.0.0-alpha.1",
"@react-types/button": "^3.7.0",
"@react-types/shared": "^3.16.0",
"@react-types/tag": "3.0.0-beta.1",
"@swc/helpers": "^0.4.14"
Expand Down
66 changes: 19 additions & 47 deletions packages/@react-aria/tag/src/TagKeyboardDelegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,26 @@
* governing permissions and limitations under the License.
*/

import {GridCollection} from '@react-types/grid';
import {GridKeyboardDelegate} from '@react-aria/grid';
import {Collection, Direction, KeyboardDelegate} from '@react-types/shared';
import {Key} from 'react';

export class TagKeyboardDelegate<T> extends GridKeyboardDelegate<T, GridCollection<T>> {
getFirstKey() {
let key = this.collection.getFirstKey();
let item = this.collection.getItem(key);
export class TagKeyboardDelegate<T> implements KeyboardDelegate {
private collection: Collection<T>;
private direction: Direction;

return [...item.childNodes][0].key;
constructor(collection: Collection<T>, direction: Direction) {
this.collection = collection;
this.direction = direction;
}

getLastKey() {
let key = this.collection.getLastKey();
let item = this.collection.getItem(key);

return [...item.childNodes][0].key;
getFirstKey() {
return this.collection.getFirstKey();
}

getLastKey() {
return this.collection.getLastKey();
}

getKeyRightOf(key: Key) {
return this.direction === 'rtl' ? this.getKeyAbove(key) : this.getKeyBelow(key);
}
Expand All @@ -43,27 +44,12 @@ export class TagKeyboardDelegate<T> extends GridKeyboardDelegate<T, GridCollecti
return;
}

// If focus was on a cell, start searching from the parent row
if (this.isCell(startItem)) {
key = startItem.parentKey;
}

// Find the next item
key = this.findNextKey(key);
key = this.collection.getKeyAfter(key);
if (key != null) {
// If focus was on a cell, focus the cell with the same index in the next row.
if (this.isCell(startItem)) {
let item = this.collection.getItem(key);

return [...item.childNodes][startItem.index].key;
}

// Otherwise, focus the next row
if (this.focusMode === 'row') {
return key;
}
return key;
} else {
return this.getFirstKey();
return this.collection.getFirstKey();
}
}

Expand All @@ -73,26 +59,12 @@ export class TagKeyboardDelegate<T> extends GridKeyboardDelegate<T, GridCollecti
return;
}

// If focus is on a cell, start searching from the parent row
if (this.isCell(startItem)) {
key = startItem.parentKey;
}

// Find the previous item
key = this.findPreviousKey(key);
key = this.collection.getKeyBefore(key);
if (key != null) {
// If focus was on a cell, focus the cell with the same index in the previous row.
if (this.isCell(startItem)) {
let item = this.collection.getItem(key);
return [...item.childNodes][startItem.index].key;
}

// Otherwise, focus the previous row
if (this.focusMode === 'row') {
return key;
}
return key;
} else {
return this.getLastKey();
return this.collection.getLastKey();
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/@react-aria/tag/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ export {useTag} from './useTag';
export {useTagGroup} from './useTagGroup';

export type {TagProps} from '@react-types/tag';
export type {AriaTagGroupProps, TagGroupAria} from './useTagGroup';
export type {TagGroupAria} from './useTagGroup';
export type {TagAria} from './useTag';
Loading

0 comments on commit a68b999

Please sign in to comment.