Skip to content

Commit

Permalink
feat(dropdowns): migrate react-dropdowns to Typescript (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
Austin Green authored Jun 26, 2019
1 parent 8209fe2 commit 3c38586
Show file tree
Hide file tree
Showing 110 changed files with 4,567 additions and 3,719 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
packages/notifications/index.d.ts
33 changes: 29 additions & 4 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{
"parser": "@typescript-eslint/parser",
"extends": [
"@zendeskgarden",
"@zendeskgarden/eslint-config/plugins/notice.js",
"plugin:react/recommended",
"plugin:jest/recommended",
"plugin:jsx-a11y/recommended",
"prettier"
"plugin:@typescript-eslint/recommended",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"settings": {
"react": {
Expand All @@ -18,7 +21,7 @@
"PACKAGE_VERSION": true,
"COMPONENT_IDS": true
},
"plugins": ["prettier", "react", "jest", "jsx-a11y", "react-hooks"],
"plugins": ["prettier", "react", "jest", "jsx-a11y", "react-hooks", "@typescript-eslint"],
"env": {
"es6": true,
"browser": true,
Expand All @@ -30,13 +33,35 @@
"valid-jsdoc": "off",
"no-invalid-this": "off",
"no-unused-expressions": ["error", { "allowShortCircuit": true }],
"no-irregular-whitespace": ["error", { "skipTemplates": true }],
"prefer-named-capture-group": "off",
"react/jsx-key": "off",
"react/display-name": "off",
"react/no-unsafe": ["error", { "checkAliases": true }],
"react/prop-types": ["error", { "ignore": ["children"] }],
"jsx-a11y/label-has-for": "off",
"jest/no-disabled-tests": "off",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
"react-hooks/exhaustive-deps": "warn",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/interface-name-prefix": ["error", "always"],
"@typescript-eslint/no-non-null-assertion": "off"
},
"overrides": [{ "files": ["*.spec.js"], "rules": { "react/prop-types": "off" } }]
"overrides": [
{
"files": ["*.{ts,tsx}", "*.spec.{js,ts,tsx}"],
"rules": {
"react/prop-types": "off"
}
},
{
"files": ["*.js"],
"rules": {
"@typescript-eslint/no-unused-vars": "off"
}
}
]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
node_modules
*.log
.changelog
.vscode

# Package specific
packages/**/dist
Expand Down
7 changes: 7 additions & 0 deletions .lintstagedrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
"prettier --write",
"git add"
],
"*.{ts,tsx}": [
"stylelint",
"eslint",
"jest --config=utils/test/jest.config.js --findRelatedTests",
"prettier --write",
"git add"
],
"*.md": [
"markdownlint",
"prettier --write",
Expand Down
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ before_install:
install: yarn --frozen-lockfile --ignore-scripts

script:
- yarn lerna bootstrap --ignore-scripts
- yarn lint
- yarn tsc
- yarn format
- yarn lerna bootstrap --ignore-scripts
- yarn test:all --coverage --runInBand

after_success: yarn coveralls < demo/coverage/lcov.info
Expand Down
1 change: 1 addition & 0 deletions .yarnclean
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@types/react-native
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
plugins: [
'@babel/plugin-transform-object-assign',
'@babel/plugin-proposal-class-properties',
'@babel/proposal-object-rest-spread',
'babel-plugin-styled-components'
]
};
6 changes: 3 additions & 3 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"version": "6.0.3",
"npmClient": "yarn",
"npmClientArgs": [
"--no-lockfile"
],
"npmClientArgs": ["--no-lockfile"],
"changelog": {
"repo": "zendeskgarden/react-components",
"cacheDir": ".changelog",
Expand All @@ -18,6 +16,8 @@
"ignoreChanges": [
"*.md",
"*.spec.js",
"*.spec.ts",
"*.spec.tsx",
"**/__snapshots__/**",
"styleguide.config.js"
],
Expand Down
20 changes: 18 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
"build:analyze": "ANALYZE_BUNDLE=true yarn build:single",
"build:demo": "yarn build && lerna run build:demo --stream",
"build:single": "utils/scripts/scoped-npm-command.js --script build",
"format": "yarn format:package_json && yarn format:js && yarn format:markdown",
"format": "yarn format:package_json && yarn format:js && yarn format:ts && yarn format:markdown",
"format:js": "prettier --loglevel warn --write 'packages/**/!(dist|umd)/*.js' && prettier --loglevel warn --write utils/**/*.js",
"format:markdown": "prettier --loglevel warn --write 'packages/**/!(dist)/!(CHANGELOG)*.md'",
"format:package_json": "prettier-package-json --write && lerna exec -- prettier-package-json --write",
"format:ts": "prettier --loglevel warn --write 'packages/**/!(dist|umd)/*.{ts,tsx}' && prettier --loglevel warn --write utils/**/*.{ts,tsx}",
"postinstall": "lerna bootstrap",
"lint": "yarn lint:css && yarn lint:js && yarn lint:markdown",
"lint:css": "stylelint \"packages/*/src/**/*.js\" && stylelint \"utils/**/*.js\"",
"lint:js": "eslint packages/*/src/ utils/ --max-warnings 0",
"lint:js": "eslint packages/*/src/ utils/ --ext js,ts,tsx --max-warnings 0",
"lint:markdown": "markdownlint API.md DEVELOPMENT.md README.md VERSIONING.md packages/*/src/**/*.md packages/*/src/*.md packages/*/README.md",
"new": "utils/scripts/create-package.js",
"prepare": "yarn build",
Expand All @@ -28,13 +29,23 @@
"@babel/cli": "7.4.4",
"@babel/core": "7.4.5",
"@babel/plugin-proposal-class-properties": "7.4.4",
"@babel/plugin-proposal-object-rest-spread": "7.4.4",
"@babel/plugin-transform-object-assign": "7.2.0",
"@babel/polyfill": "7.4.4",
"@babel/preset-env": "7.4.5",
"@babel/preset-react": "7.0.0",
"@svgr/webpack": "4.3.0",
"@testing-library/react": "8.0.1",
"@types/classnames": "2.2.8",
"@types/jest": "24.0.13",
"@types/prop-types": "15.7.1",
"@types/react": "16.8.19",
"@types/react-dom": "16.8.4",
"@types/styled-components": "4.1.16",
"@types/webpack": "4.4.32",
"@typescript-eslint/eslint-plugin": "1.10.2",
"@typescript-eslint/parser": "1.10.2",
"@zendeskgarden/css-bedrock": "7.0.26",
"@zendeskgarden/css-variables": "6.3.4",
"@zendeskgarden/eslint-config": "7.2.1",
"@zendeskgarden/stylelint-config": "10.0.0",
Expand All @@ -54,6 +65,7 @@
"enzyme-to-json": "3.3.5",
"eslint": "5.16.0",
"eslint-config-prettier": "4.3.0",
"eslint-loader": "2.1.2",
"eslint-plugin-jest": "22.6.4",
"eslint-plugin-jsx-a11y": "6.2.1",
"eslint-plugin-notice": "0.7.8",
Expand Down Expand Up @@ -89,6 +101,7 @@
"prettier": "1.18.2",
"prettier-package-json": "2.1.0",
"react": "16.8.6",
"react-docgen-typescript": "1.12.5",
"react-dom": "16.8.6",
"react-styleguidist": "8.0.6",
"regenerator-runtime": "0.13.2",
Expand All @@ -100,6 +113,9 @@
"stylelint-config-styled-components": "0.1.1",
"stylelint-order": "3.0.0",
"stylelint-processor-styled-components": "1.8.0",
"ts-jest": "24.0.2",
"ts-loader": "6.0.2",
"typescript": "3.5.1",
"uglifyjs-webpack-plugin": "2.1.3",
"webpack": "4.33.0",
"webpack-bundle-analyzer": "3.3.2",
Expand Down
4 changes: 3 additions & 1 deletion packages/dropdowns/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"build:demo": "../../utils/scripts/build-demo.sh",
"start": "../../utils/scripts/start.sh"
},
"types": "./dist/typings/index.d.ts",
"dependencies": {
"@zendeskgarden/container-selection": "^0.2.3",
"classnames": "^2.2.5",
Expand All @@ -32,6 +33,7 @@
"styled-components": "^4.2.0"
},
"devDependencies": {
"@types/lodash.debounce": "^4.0.6",
"@zendeskgarden/css-arrows": "3.1.1",
"@zendeskgarden/css-forms": "7.0.10",
"@zendeskgarden/css-menus": "9.0.10",
Expand All @@ -49,5 +51,5 @@
"access": "public"
},
"zendeskgarden:library": "GardenDropdowns",
"zendeskgarden:src": "src/index.js"
"zendeskgarden:src": "src/index.ts"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import React from 'react';
import { render, fireEvent } from 'garden-test-utils';
import { Dropdown, Autocomplete, Field, Menu, Item, Label } from '../';
import { Dropdown, Autocomplete, Field, Menu, Item, Label } from '..';

const ExampleAutocomplete = () => (
<Dropdown>
Expand All @@ -34,7 +34,7 @@ describe('Autocomplete', () => {

fireEvent.click(getByTestId('autocomplete'));

expect(document.activeElement.nodeName).toBe('INPUT');
expect(document.activeElement!.nodeName).toBe('INPUT');
});

it('closes on input blur', () => {
Expand All @@ -43,9 +43,9 @@ describe('Autocomplete', () => {
const autocomplete = getByTestId('autocomplete');
const input = autocomplete.querySelector('input');

fireEvent.focus(input);
fireEvent.focus(input!);
expect(autocomplete).toHaveClass('is-focused');
fireEvent.blur(input);
fireEvent.blur(input!);
expect(autocomplete).not.toHaveClass('is-focused');
});

Expand Down Expand Up @@ -122,7 +122,7 @@ describe('Autocomplete', () => {
fireEvent.click(autocomplete);
expect(autocomplete).toHaveClass('is-open');

fireEvent.keyDown(autocomplete.querySelector('input'), { key: 'Escape', keyCode: 27 });
fireEvent.keyDown(autocomplete.querySelector('input')!, { key: 'Escape', keyCode: 27 });
expect(autocomplete).not.toHaveClass('is-open');
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,40 @@
import React, { useRef, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Reference } from 'react-popper';
import { StyledInput, StyledSelect } from '../styled';
import { StyledInput, StyledSelect, VALIDATION } from '../styled';
import useDropdownContext from '../utils/useDropdownContext';
import useFieldContext from '../utils/useFieldContext';

const VALIDATION = {
SUCCESS: 'success',
WARNING: 'warning',
ERROR: 'error'
};
interface IAutocompleteProps {
/** Allows flush spacing of Tab elements */
tagLayout?: boolean;
/** Applies flex layout to support MediaFigure components */
mediaLayout?: boolean;
small?: boolean;
/** Removes all borders and styling */
bare?: boolean;
disabled?: boolean;
focused?: boolean;
/** Applies inset `box-shadow` styling on focus */
focusInset?: boolean;
hovered?: boolean;
/** Displays select open state */
open?: boolean;
validation?: VALIDATION;
}

/**
* Applies state and a11y attributes to its children. Must be nested within a `<Field>` component.
*/
const Autocomplete = ({ children, ...props }) => {
const Autocomplete: React.FunctionComponent<IAutocompleteProps> = ({ children, ...props }) => {
const {
popperReferenceElementRef,
downshift: { getToggleButtonProps, getInputProps, isOpen }
} = useDropdownContext();
const { isLabelHovered } = useFieldContext();
const inputRef = useRef(null);
const triggerRef = useRef(null);
const previousIsOpenRef = useRef(undefined);
const inputRef = useRef<HTMLInputElement>(null);
const triggerRef = useRef<HTMLElement>(null);
const previousIsOpenRef = useRef<boolean | undefined>(undefined);
const [isFocused, setIsFocused] = useState(false);

useEffect(() => {
Expand All @@ -48,7 +60,7 @@ const Autocomplete = ({ children, ...props }) => {
const selectProps = getToggleButtonProps({
onKeyDown: e => {
if (isOpen) {
e.nativeEvent.preventDownshiftDefault = true;
(e.nativeEvent as any).preventDownshiftDefault = true;
}
},
...props
Expand All @@ -66,7 +78,7 @@ const Autocomplete = ({ children, ...props }) => {
popperReference(selectRef);

// Store ref locally to return focus on close
triggerRef.current = selectRef;
(triggerRef as any).current = selectRef;

// Apply Select ref to global Dropdown context
popperReferenceElementRef.current = selectRef;
Expand All @@ -85,7 +97,7 @@ const Autocomplete = ({ children, ...props }) => {
setIsFocused(false);
},
ref: inputRef
})}
} as any)}
/>
</StyledSelect>
)}
Expand All @@ -94,7 +106,6 @@ const Autocomplete = ({ children, ...props }) => {
};

Autocomplete.propTypes = {
children: PropTypes.node,
/** Allows flush spacing of Tab elements */
tagLayout: PropTypes.bool,
/** Applies flex layout to support MediaFigure components */
Expand Down
Loading

0 comments on commit 3c38586

Please sign in to comment.