Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
SPWizard01 authored Oct 24, 2024
2 parents 7a07db9 + 348c46d commit 128afec
Show file tree
Hide file tree
Showing 53 changed files with 514 additions and 350 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,72 @@ import { FocusTrapZone } from '@fluentui/react';
import { useUncontrolledFocus, Field, Switch, Button, makeStyles, tokens } from '@fluentui/react-components';

const useStyles = makeStyles({
container: {
display: 'flex',
flexDirection: 'column',
gap: '10px',
placeItems: 'start',
},
focusTrapZone: {
display: 'flex',
columnGap: '10px',
gap: '20px',
padding: '20px 10px 10px 10px',
position: 'relative',
maxWidth: '400px',
width: '400px',
border: `2px solid ${tokens.colorBrandBackground}`,

'::after': {
content: `'FocusTrapZone'`,
position: 'absolute',
padding: '1px 4px 1px',
padding: '4px',
top: '-2px',
left: '-2px',
fontFamily: 'monospace',
fontSize: '15px',
fontSize: '14px',
fontWeight: 900,
lineHeight: 1,
letterSpacing: '1px',
color: tokens.colorNeutralForegroundOnBrand,
backgroundColor: tokens.colorBrandBackground,
},
},
controls: {
flex: 1,
display: 'flex',
gap: '10px',
alignItems: 'end',
justifyContent: 'end',
},
});

export const Default = () => {
const attr = useUncontrolledFocus();
const [uncontrolled, setUncontrolled] = React.useState(false);
const styles = useStyles();

const [enabled, setEnabled] = React.useState(true);

return (
<>
<div className={styles.container}>
<Button>Outside</Button>

<FocusTrapZone
{...attr}
className={styles.focusTrapZone}
{...(uncontrolled && attr)}
disabled={!enabled}
isClickableOutsideFocusTrap
forceFocusInsideTrap={false}
>
<Field label="Uncontrolled tabster">
<Switch checked={uncontrolled} onChange={(e, data) => setUncontrolled(data.checked)} />
<Field label="Enable focus trap">
<Switch checked={enabled} onChange={(e, data) => setEnabled(data.checked)} />
</Field>
<Button>{uncontrolled ? 'Trapped' : 'Not trapped'}</Button>
<Button>{uncontrolled ? 'Trapped' : 'Not trapped'}</Button>

<div className={styles.controls}>
<Button>{enabled ? 'Trapped' : 'Not trapped'}</Button>
<Button>{enabled ? 'Trapped' : 'Not trapped'}</Button>
</div>
</FocusTrapZone>

<Button>Outside</Button>
</>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ only focus management framework in an application. However, it's understandable
other focus management frameworks. In these cases, the `useUncontrolledFocus` hook can be used to explicitly
remove explicit focus controlling for a region of DOM.

This is particularly useful to support legacy v8 focus management components such as `FocusZone` and `FocusTrapZone`
This is particularly useful to support legacy v8 focus management components such as `FocusZone` and `FocusTrapZone`.
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import * as React from 'react';
import type { Meta } from '@storybook/react';
import { Table } from '@fluentui/react-table';
import { Table, tableHeaderClassNames } from '@fluentui/react-table';
import { Steps } from 'storywright';
import { withStoryWrightSteps } from '../../utilities';
import { SubtleSelection } from './utils';
import { SubtleSelection, SubtleSelectionEmpty } from './utils';

export default {
title: 'Table table - subtle selection',
decorators: [
story =>
withStoryWrightSteps({ story, steps: new Steps().hover('.not-selected').snapshot('hover unselected row').end() }),
withStoryWrightSteps({
story,
steps: new Steps()
.hover('.not-selected')
.snapshot('hover unselected row')
.hover(`.${tableHeaderClassNames.root}`)
.snapshot('hover header row')
.end(),
}),
],
} satisfies Meta<typeof Table>;

export const Rest = () => <SubtleSelection noNativeElements={false} />;
Rest.storyName = 'rest';

export const NoSelection = () => <SubtleSelectionEmpty noNativeElements={false} />;
35 changes: 35 additions & 0 deletions apps/vr-tests-react-components/src/stories/Table/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,41 @@ export const SubtleSelection: React.FC<SharedVrTestArgs> = ({ noNativeElements }
</Table>
);

export const SubtleSelectionEmpty: React.FC<SharedVrTestArgs> = ({ noNativeElements }) => (
<Table noNativeElements={noNativeElements}>
<TableHeader>
<TableRow>
<TableSelectionCell type="checkbox" hidden />
{columns.map(column => (
<TableHeaderCell key={column.columnKey}>{column.label}</TableHeaderCell>
))}
</TableRow>
</TableHeader>
<TableBody>
{items.map((item, i) => (
<TableRow key={item.file.label}>
<TableSelectionCell subtle type="checkbox" className="not-selected" />
<TableCell>
<TableCellLayout media={item.file.icon}>{item.file.label}</TableCellLayout>
</TableCell>

<TableCell>
<TableCellLayout
media={<Avatar name={item.author.label} badge={{ status: item.author.status as PresenceBadgeStatus }} />}
>
{item.author.label}
</TableCellLayout>
</TableCell>
<TableCell>{item.lastUpdated.label}</TableCell>
<TableCell>
<TableCellLayout media={item.lastUpdate.icon}>{item.lastUpdate.label}</TableCellLayout>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);

export const Truncate: React.FC<SharedVrTestArgs & { truncate?: boolean }> = ({ noNativeElements, truncate }) => (
<Table noNativeElements={noNativeElements} style={{ width: '400px' }}>
<TableHeader>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix: bump minimal typescript version to 4.8.4",
"packageName": "@fluentui/eslint-plugin",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "fix: subtle selection should apply correctly to header rows",
"packageName": "@fluentui/react-table",
"email": "[email protected]",
"dependentChangeType": "patch"
}
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
"@phenomnomnominal/tsquery": "6.1.3",
"@playwright/test": "1.44.0",
"@react-native/babel-preset": "0.73.21",
"@rnx-kit/eslint-plugin": "0.7.2",
"@rnx-kit/eslint-plugin": "0.8.2",
"@rollup/plugin-node-resolve": "13.3.0",
"@storybook/addon-a11y": "7.6.20",
"@storybook/addon-actions": "7.6.20",
Expand Down Expand Up @@ -173,10 +173,10 @@
"@types/webpack-hot-middleware": "2.25.9",
"@types/yargs": "13.0.11",
"@types/yargs-unparser": "2.0.1",
"@typescript-eslint/eslint-plugin": "7.18.0",
"@typescript-eslint/parser": "7.18.0",
"@typescript-eslint/rule-tester": "7.18.0",
"@typescript-eslint/utils": "7.18.0",
"@typescript-eslint/eslint-plugin": "8.8.1",
"@typescript-eslint/parser": "8.8.1",
"@typescript-eslint/rule-tester": "8.8.1",
"@typescript-eslint/utils": "8.8.1",
"@wojtekmaj/enzyme-adapter-react-17": "0.6.7",
"ajv": "8.4.0",
"autoprefixer": "10.2.1",
Expand Down Expand Up @@ -233,7 +233,7 @@
"eslint-plugin-deprecation": "3.0.0",
"eslint-plugin-es": "4.1.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jest": "28.6.0",
"eslint-plugin-jest": "28.8.0",
"eslint-plugin-jsdoc": "48.7.0",
"eslint-plugin-jsx-a11y": "6.9.0",
"eslint-plugin-playwright": "0.15.3",
Expand Down
14 changes: 7 additions & 7 deletions packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
},
"dependencies": {
"@griffel/eslint-plugin": "^1.6.4",
"@rnx-kit/eslint-plugin": "^0.7.2",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/utils": "^7.18.0",
"@typescript-eslint/rule-tester": "7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@typescript-eslint/type-utils": "^7.18.0",
"@rnx-kit/eslint-plugin": "^0.8.2",
"@typescript-eslint/eslint-plugin": "^8.8.1",
"@typescript-eslint/utils": "^8.8.1",
"@typescript-eslint/rule-tester": "8.8.1",
"@typescript-eslint/parser": "^8.8.1",
"@typescript-eslint/type-utils": "^8.8.1",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-typescript": "^3.6.1",
Expand All @@ -37,7 +37,7 @@
},
"peerDependencies": {
"eslint": "^8.0.0",
"typescript": "^4.7.5"
"typescript": "^4.8.4"
},
"files": [
"src"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ module.exports = createRule({
type: 'problem',
docs: {
description: 'Ban export of React context or context selector objects',
recommended: 'recommended',
},
messages: {
nativeContext: '{{exportName}} should not be exported directly',
Expand Down
33 changes: 15 additions & 18 deletions packages/eslint-plugin/src/rules/ban-context-export/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,40 @@ const { RuleTester } = require('@typescript-eslint/rule-tester');
const path = require('path');
const rule = require('./index');

const ruleTester = new RuleTester({
parser: '@typescript-eslint/parser',
parserOptions: {
project: path.resolve(__dirname, './fixtures/ban-context-export/tsconfig.json'),
tsconfigRootDir: path.resolve(__dirname, './fixtures/ban-context-export'),
},
});
const ruleTester = new RuleTester();

/**
* @param {string} fixtureName
*/
function getParserOptions(fixtureName) {
function getLanguageOptions(fixtureName) {
return {
project: path.resolve(__dirname, `./fixtures/${fixtureName}/tsconfig.json`),
tsconfigRootDir: path.resolve(__dirname, `./fixtures/${fixtureName}`),
parserOptions: {
parser: '@typescript-eslint/parser',
project: path.resolve(__dirname, `./fixtures/${fixtureName}/tsconfig.json`),
tsconfigRootDir: path.resolve(__dirname, `./fixtures/${fixtureName}`),
},
};
}

ruleTester.run('ban-context-export', rule, {
valid: [
{
parserOptions: getParserOptions('internal-export'),
languageOptions: getLanguageOptions('internal-export'),
code: `
export { MyContext } from './context'
`,
filename: 'src/internal/index.ts',
},
{
parserOptions: getParserOptions('not-a-context'),
languageOptions: getLanguageOptions('not-a-context'),
code: `
export { MyContext } from './context'
`,
filename: 'src/index.ts',
},
{
options: [{ exclude: ['**/special-path/**/*'] }],
parserOptions: getParserOptions('exclude'),
languageOptions: getLanguageOptions('exclude'),
code: `
import * as React from 'react';
export const MyContext = React.createContext({});
Expand All @@ -50,23 +47,23 @@ ruleTester.run('ban-context-export', rule, {
invalid: [
{
errors: [{ messageId: 'nativeContext' }],
parserOptions: getParserOptions('export-specifier'),
languageOptions: getLanguageOptions('export-specifier'),
code: `
export { MyContext } from './context'
`,
filename: 'src/index.ts',
},
{
errors: [{ messageId: 'contextSelector' }],
parserOptions: getParserOptions('context-selector'),
languageOptions: getLanguageOptions('context-selector'),
code: `
export { MyContext } from './context'
`,
filename: 'src/index.ts',
},
{
errors: [{ messageId: 'nativeContext' }],
parserOptions: getParserOptions('named-export'),
languageOptions: getLanguageOptions('named-export'),
code: `
import * as React from 'react';
export const MyContext = React.createContext({});
Expand All @@ -75,7 +72,7 @@ ruleTester.run('ban-context-export', rule, {
},
{
errors: [{ messageId: 'contextSelector' }],
parserOptions: getParserOptions('named-export'),
languageOptions: getLanguageOptions('named-export'),
code: `
import { createContext } from '@proj/react-context-selector';
export const MyContext = createContext({});
Expand All @@ -85,7 +82,7 @@ ruleTester.run('ban-context-export', rule, {
{
errors: [{ messageId: 'nativeContext' }],
options: [{ exclude: ['**/wrong-path/**/*'] }],
parserOptions: getParserOptions('exclude'),
languageOptions: getLanguageOptions('exclude'),
code: `
import * as React from 'react';
export const MyContext = React.createContext({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const createRule = require('../../utils/createRule');

/**
* @typedef {import('./types').HTMLElementConstructorName} HTMLElementConstructorName
*
*/

module.exports = createRule({
Expand All @@ -13,7 +12,6 @@ module.exports = createRule({
type: 'problem',
docs: {
description: 'Ban usage of instanceof HTMLElement comparison',
recommended: 'recommended',
},
messages: {
invalidBinaryExpression: 'instanceof {{right}} should be avoided, use isHTMLElement instead.',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
const { RuleTester } = require('@typescript-eslint/rule-tester');
const rule = require('./index');

const ruleTester = new RuleTester({
parser: '@typescript-eslint/parser',
});
const ruleTester = new RuleTester();

ruleTester.run('ban-instanceof-htmlelement', rule, {
valid: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
const createRule = require('../utils/createRule');
const { ESLintUtils } = require('@typescript-eslint/utils');

/**
* @typedef { import('@typescript-eslint/utils').TSESLint.RuleMetaDataDocs} RuleMetaDataDocs
*/

module.exports = createRule({
name: 'deprecated-keyboard-event-props',
meta: {
type: 'problem',
docs: {
docs: /** @type {RuleMetaDataDocs} */ ({
description: 'Forbid use of deprecated KeyboardEvent props "which" and "keyCode".',
recommended: 'recommended',
requiresTypeChecking: true,
},
}),
messages: {
deprecatedProp: 'KeyboardEvent prop "{{name}}" is deprecated (consider using @fluentui/keyboard-key instead)',
},
Expand Down
Loading

0 comments on commit 128afec

Please sign in to comment.