Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor to vanilla JS core #119

Merged
merged 23 commits into from
Nov 27, 2022
Merged
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
build
23 changes: 23 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
root: true,
extends: [
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:jsx-a11y/recommended',
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'jsx-a11y'],
settings: {
react: {
version: 'detect',
},
},
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'react/prop-types': 'off',
'prefer-const': 'off',
},
}
65 changes: 65 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Tests

on:
push:
branches:
- main
- next
pull_request:

jobs:
main:
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: './.nvmrc'

- name: Install Dependencies
uses: bahmutov/npm-install@v1

- name: Build
run: yarn build

- name: Lint
run: yarn lint

- name: Test
run: yarn test

- name: Cypress run
uses: cypress-io/github-action@v4.2.1
with:
browser: chrome
component: true

release:
name: Publish to NPM
needs: main
# publish only when merged in master on original repo, not on PR
if: github.repository == 'roginfarrer/react-collapsed' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/next')
runs-on: ubuntu-latest
steps:
- name: ⬇️ Checkout repo
uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: './nvmrc'

- name: Install Dependencies
uses: bahmutov/npm-install@v1

- name: Build
run: yarn build

- name: 🚀 Release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
45 changes: 0 additions & 45 deletions .github/workflows/release.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
14.18.0
v16
10 changes: 10 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from "cypress";

export default defineConfig({
component: {
devServer: {
framework: "react",
bundler: "vite",
},
},
});
50 changes: 50 additions & 0 deletions cypress/component/Controlled.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react'
import useCollapse from '../../src'

const Collapse = React.forwardRef<
HTMLDivElement,
React.ComponentPropsWithoutRef<'div'>
>(function Collapse(props, ref) {
return (
<div {...props} ref={ref} data-testid="collapse">
<div
style={{
height: 300,
border: '2px solid red',
backgroundColor: 'lightblue',
}}
>
helloooo
</div>
</div>
)
})

const Controlled = () => {
const [isExpanded, setOpen] = React.useState<boolean>(true)
const { getToggleProps, getCollapseProps } = useCollapse({
isExpanded,
})

return (
<div>
<button {...getToggleProps({ onClick: () => setOpen((x) => !x) })}>
{isExpanded ? 'Close' : 'Open'}
</button>
<Collapse {...getCollapseProps()} />
</div>
)
}

describe('Controlled', () => {
it('playground', () => {
cy.mount(<Controlled />)

// getToggleProps
cy.get('button').should('have.text', 'Close')
cy.get('[data-testid="collapse"]').should('be.visible')
cy.get('button').click()
cy.get('button').should('have.text', 'Open')
cy.get('[data-testid="collapse"]').should('not.be.visible')
})
})
57 changes: 57 additions & 0 deletions cypress/component/Uncontrolled.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import * as React from 'react'
import useCollapse from '../../src'

const Collapse = React.forwardRef<
HTMLDivElement,
React.ComponentPropsWithoutRef<'div'>
>(function Collapse(props, ref) {
return (
<div {...props} ref={ref} data-testid="collapse">
<div
style={{
height: 300,
border: '2px solid red',
backgroundColor: 'lightblue',
}}
>
helloooo
</div>
</div>
)
})

const Uncontrolled = () => {
const { getToggleProps, getCollapseProps, isExpanded, setExpanded } =
useCollapse()

return (
<div>
<button {...getToggleProps()}>{isExpanded ? 'Close' : 'Open'}</button>
<div onClick={() => setExpanded((n) => !n)} data-testid="alt">
Alt
</div>
<Collapse {...getCollapseProps()} />
</div>
)
}

describe('Uncontrolled', () => {
it('opens and closes', () => {
cy.mount(<Uncontrolled />)

// getToggleProps
cy.get('button').should('have.text', 'Open')
cy.get('[data-testid="collapse"]').should('not.be.visible')
cy.get('button').click()
cy.get('button').should('have.text', 'Close')
cy.get('[data-testid="collapse"]').should('be.visible')

// setExpanded
cy.get('[data-testid="alt"]').click()
cy.get('[data-testid="collapse"]').should('not.be.visible')
cy.get('[data-testid="alt"]').click()
cy.get('[data-testid="collapse"]').should('be.visible')
})
})
5 changes: 5 additions & 0 deletions cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
38 changes: 38 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
import '@testing-library/cypress/add-commands'
12 changes: 12 additions & 0 deletions cypress/support/component-index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Components App</title>
</head>
<body>
<div data-cy-root></div>
</body>
</html>
40 changes: 40 additions & 0 deletions cypress/support/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* eslint-disable @typescript-eslint/no-namespace */
// ***********************************************************
// This example support/component.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')

import { mount } from 'cypress/react18'

// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount
}
}
}

Cypress.Commands.add('mount', mount)

// Example use:
// cy.mount(<MyComponent />)
8 changes: 8 additions & 0 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": true,
"types": ["cypress"]
},
"include": ["../node_modules/cypress", "./**/*.ts"]
}
File renamed without changes.
9 changes: 9 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],
globals: {
__DEV__: true,
},
testMatch: ['<rootDir>/**/*.(spec|test).{ts,tsx,js,jsx}'],
}
Loading