├── .travis.yml ├── src ├── g-extend-theme │ ├── index.tsx │ ├── g-extend-theme.tsx │ └── g-extend-theme.test.tsx ├── react-app-env.d.ts ├── .eslintrc ├── g-input │ ├── index.tsx │ ├── g-input.test.tsx │ ├── g-input.types.tsx │ └── g-input.tsx ├── g-button │ ├── index.tsx │ ├── g-button.types.tsx │ ├── g-button.tsx │ └── g-button.test.tsx ├── g-option │ ├── index.ts │ ├── g-option.types.tsx │ └── g-option.tsx ├── g-select │ ├── index.tsx │ ├── g-select.test.tsx │ ├── g-select.types.tsx │ └── g-select.tsx ├── with-children.ts ├── gazin-provider │ ├── index.tsx │ ├── gazin-provider.types.ts │ └── gazin-provider.tsx ├── index.tsx └── theme.ts ├── .eslintignore ├── example ├── src │ ├── react-app-env.d.ts │ ├── App.tsx │ ├── setupTests.ts │ ├── index.tsx │ └── App.test.tsx ├── public │ ├── favicon.ico │ ├── manifest.json │ └── index.html ├── README.md ├── tsconfig.json └── package.json ├── tsconfig.test.json ├── .editorconfig ├── .prettierrc ├── .gitignore ├── tsconfig.json ├── .github └── workflows │ └── npm-publish.yml ├── README.md ├── .eslintrc └── package.json /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 12 4 | - 10 5 | -------------------------------------------------------------------------------- /src/g-extend-theme/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './g-extend-theme' 2 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "jest": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | node_modules/ 4 | .snapshots/ 5 | *.min.js -------------------------------------------------------------------------------- /example/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/g-input/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './g-input' 2 | export * from './g-input.types' 3 | -------------------------------------------------------------------------------- /src/g-button/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './g-button' 2 | export * from './g-button.types' 3 | -------------------------------------------------------------------------------- /src/g-option/index.ts: -------------------------------------------------------------------------------- 1 | export * from './g-option' 2 | export * from './g-option.types' 3 | -------------------------------------------------------------------------------- /src/g-select/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './g-select' 2 | export * from './g-select.types' 3 | -------------------------------------------------------------------------------- /src/with-children.ts: -------------------------------------------------------------------------------- 1 | export type WithChildren = T & { children?: React.ReactNode } 2 | -------------------------------------------------------------------------------- /example/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigdevs/gazinui/HEAD/example/public/favicon.ico -------------------------------------------------------------------------------- /src/gazin-provider/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './gazin-provider' 2 | export * from './gazin-provider.types' 3 | -------------------------------------------------------------------------------- /tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | } 6 | } -------------------------------------------------------------------------------- /src/g-button/g-button.types.tsx: -------------------------------------------------------------------------------- 1 | import { ButtonProps } from '@chakra-ui/react' 2 | import { WithChildren } from '../with-children' 3 | 4 | export type GButtonProps = WithChildren<{}> & ButtonProps 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { GButton } from '@tigdevs/gazinui' 4 | 5 | const App = () => { 6 | return Testando 7 | } 8 | 9 | export default App 10 | -------------------------------------------------------------------------------- /src/gazin-provider/gazin-provider.types.ts: -------------------------------------------------------------------------------- 1 | import { ChakraProviderProps } from '@chakra-ui/react' 2 | import { WithChildren } from '../with-children' 3 | 4 | export type GazinProviderProps = WithChildren<{}> & ChakraProviderProps 5 | -------------------------------------------------------------------------------- /src/g-option/g-option.types.tsx: -------------------------------------------------------------------------------- 1 | import { FlexProps } from '@chakra-ui/layout' 2 | import { WithChildren } from '../with-children' 3 | 4 | export type GOptionProps = WithChildren<{ 5 | value: string | number 6 | }> & 7 | Partial 8 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | export * from '@chakra-ui/react' 2 | export * from './g-button' 3 | export * from './g-extend-theme' 4 | export * from './gazin-provider' 5 | export * from './g-select' 6 | export * from './g-option' 7 | export * from './g-input' 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "jsxSingleQuote": true, 4 | "semi": false, 5 | "tabWidth": 2, 6 | "bracketSpacing": true, 7 | "jsxBracketSameLine": false, 8 | "arrowParens": "always", 9 | "trailingComma": "none" 10 | } 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This example was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | It is linked to the gazinui package in the parent directory for development purposes. 4 | 5 | You can run `yarn install` and then `yarn start` to test your package. 6 | -------------------------------------------------------------------------------- /example/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /example/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './App' 4 | import { GazinProvider } from '@tigdevs/gazinui' 5 | 6 | ReactDOM.render(( 7 | 8 | 9 | 10 | ), document.getElementById('root')) 11 | -------------------------------------------------------------------------------- /example/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './App' 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div') 7 | ReactDOM.render(, div) 8 | ReactDOM.unmountComponentAtNode(div) 9 | }) 10 | -------------------------------------------------------------------------------- /src/g-extend-theme/g-extend-theme.tsx: -------------------------------------------------------------------------------- 1 | import { extendTheme } from '@chakra-ui/react' 2 | import { theme } from '../theme' 3 | import merge from 'lodash.merge' 4 | 5 | export const GExtendTheme = (extendedTheme: object) => { 6 | const mergedTheme = merge(theme, extendedTheme) 7 | 8 | return extendTheme({ ...mergedTheme }) 9 | } 10 | -------------------------------------------------------------------------------- /src/g-button/g-button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Button } from '@chakra-ui/react' 3 | import { GButtonProps } from './g-button.types' 4 | 5 | export const GButton = ({ children, colorScheme, ...rest }: GButtonProps) => { 6 | return ( 7 | 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /example/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "gazinui", 3 | "name": "gazinui", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/g-extend-theme/g-extend-theme.test.tsx: -------------------------------------------------------------------------------- 1 | import { GExtendTheme } from './g-extend-theme' 2 | 3 | describe('GExtendTheme', () => { 4 | it('should executed correctly', () => { 5 | const theme = { 6 | colors: { 7 | test: '#00000' 8 | } 9 | } 10 | 11 | const extendedTheme = GExtendTheme(theme) 12 | 13 | expect(extendedTheme).toMatchObject(theme) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /src/gazin-provider/gazin-provider.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ChakraProvider, extendTheme } from '@chakra-ui/react' 3 | import { GazinProviderProps } from './gazin-provider.types' 4 | import { theme } from '../theme' 5 | 6 | export const GazinProvider = ({ children, ...rest }: GazinProviderProps) => { 7 | return ( 8 | 9 | {children} 10 | 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # IDE Stuff 4 | /.idea 5 | /.vscode 6 | 7 | # dependencies 8 | node_modules 9 | 10 | # testing 11 | /coverage 12 | 13 | # builds 14 | build 15 | dist 16 | .rpt2_cache 17 | 18 | # misc 19 | .DS_Store 20 | .env 21 | .env.local 22 | .env.development.local 23 | .env.test.local 24 | .env.production.local 25 | 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | -------------------------------------------------------------------------------- /src/g-input/g-input.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from '@testing-library/react' 3 | import { GazinProvider } from '../gazin-provider' 4 | import { GInput } from './g-input' 5 | 6 | describe('GInput', () => { 7 | it('should render standard input', () => { 8 | const { getByTestId } = render( 9 | 10 | 11 | 12 | ) 13 | 14 | expect(getByTestId('__input')).toBeTruthy() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /src/g-input/g-input.types.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { InputProps } from '@chakra-ui/input/dist/types/input' 3 | import { InputGroupProps } from '@chakra-ui/input/dist/types/input-group' 4 | import { jsx } from '@emotion/react' 5 | 6 | export type Element = 7 | | ((...props: unknown[]) => jsx.JSX.Element) 8 | | jsx.JSX.Element 9 | | React.Component 10 | 11 | export type TGInput = { 12 | leftElement?: Element 13 | rightElement?: Element 14 | wrapperProps?: InputGroupProps 15 | } & Partial 16 | -------------------------------------------------------------------------------- /src/g-button/g-button.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from '@testing-library/react' 3 | import { GButton } from './g-button' 4 | import { GazinProvider } from '../gazin-provider' 5 | 6 | describe('GButton', () => { 7 | it('should renders with primary color', () => { 8 | const { queryByText } = render( 9 | 10 | Teste 11 | 12 | ) 13 | 14 | const button = queryByText('Teste') 15 | 16 | expect(button).toBeTruthy() 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /src/g-option/g-option.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Flex } from '@chakra-ui/layout' 3 | import { GOptionProps } from './g-option.types' 4 | 5 | export const GOption = ({ children, ...props }: GOptionProps) => { 6 | return ( 7 | 21 | {children} 22 | 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /src/g-select/g-select.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render, RenderResult } from '@testing-library/react' 3 | import { GazinProvider } from '../gazin-provider' 4 | import { GSelect } from './g-select' 5 | import { GOption } from '../g-option' 6 | 7 | describe('GSelect', () => { 8 | it('should renders with primary color', () => { 9 | const { getByTestId } = render( 10 | 11 | 12 | Opt1 13 | Opt2 14 | 15 | 16 | ) as RenderResult 17 | 18 | const select = getByTestId('__select') 19 | 20 | expect(select.childNodes).toHaveLength(3) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /src/g-select/g-select.types.tsx: -------------------------------------------------------------------------------- 1 | import React, { RefObject } from 'react' 2 | import { FlexProps } from '@chakra-ui/layout' 3 | import { WithChildren } from '../with-children' 4 | 5 | export type InputType = RefObject & 6 | HTMLInputElement & 7 | EventTarget & 8 | ValueTracker 9 | 10 | export type GSelectProps = WithChildren<{ 11 | value?: string 12 | placeholder?: string | null 13 | onChange?: (value: string | number | null) => void 14 | inputProps?: React.DetailedHTMLProps< 15 | React.InputHTMLAttributes, 16 | HTMLInputElement 17 | > 18 | }> & 19 | Partial 20 | 21 | export type ValueTracker = { 22 | _valueTracker: { 23 | getValue(): string 24 | setValue(value: string): void 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "esnext", 5 | "lib": ["dom", "esnext"], 6 | "moduleResolution": "node", 7 | "jsx": "react", 8 | "sourceMap": true, 9 | "declaration": true, 10 | "esModuleInterop": true, 11 | "noImplicitReturns": true, 12 | "noImplicitThis": true, 13 | "noImplicitAny": true, 14 | "strictNullChecks": true, 15 | "suppressImplicitAnyIndexErrors": true, 16 | "noUnusedLocals": true, 17 | "noUnusedParameters": true, 18 | "allowSyntheticDefaultImports": true, 19 | "target": "es5", 20 | "allowJs": true, 21 | "skipLibCheck": true, 22 | "strict": true, 23 | "forceConsistentCasingInFileNames": true, 24 | "resolveJsonModule": true, 25 | "isolatedModules": true, 26 | "noEmit": true 27 | }, 28 | "include": ["src"], 29 | "exclude": ["node_modules", "dist", "example"] 30 | } 31 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "esnext", 5 | "lib": [ 6 | "dom", 7 | "esnext" 8 | ], 9 | "moduleResolution": "node", 10 | "jsx": "react", 11 | "sourceMap": true, 12 | "declaration": true, 13 | "esModuleInterop": true, 14 | "noImplicitReturns": true, 15 | "noImplicitThis": true, 16 | "noImplicitAny": true, 17 | "strictNullChecks": true, 18 | "suppressImplicitAnyIndexErrors": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "allowSyntheticDefaultImports": true, 22 | "target": "es5", 23 | "allowJs": true, 24 | "skipLibCheck": true, 25 | "strict": true, 26 | "forceConsistentCasingInFileNames": true, 27 | "resolveJsonModule": true, 28 | "isolatedModules": true, 29 | "noEmit": true 30 | }, 31 | "include": [ 32 | "src" 33 | ], 34 | "exclude": [ 35 | "node_modules", 36 | "build" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: NPM Publish on Release 2 | on: 3 | release: 4 | types: [created] 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | # Setup .npmrc file to publish to npm 11 | - uses: actions/setup-node@v1 12 | with: 13 | node-version: 12 14 | registry-url: 'https://registry.npmjs.org' 15 | - run: yarn install 16 | # Publish to npm 17 | - run: git config --global user.name "Gazin" 18 | - run: git config --global user.email "gazin@gazin.com.br" 19 | - run: yarn publish --new-version ${{ github.event.release.tag_name }} --access public 20 | env: 21 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 22 | # Setup .npmrc file to publish to GitHub Packages 23 | - uses: actions/setup-node@v1 24 | with: 25 | registry-url: 'https://npm.pkg.github.com' 26 | # Defaults to the user or organization that owns the workflow file 27 | scope: '@tigdevs' 28 | # Publish to GitHub Packages 29 | - run: yarn publish --new-version ${{ github.event.release.tag_name }} 30 | env: 31 | NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GazinUI 2 | 3 | > Interface based on Gazin's design system to React Applications. 4 | 5 | [![NPM](https://img.shields.io/npm/v/@tigdevs/gazinui.svg)](https://www.npmjs.com/package/@tigdevs/gazinui) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) 6 | 7 | ## Install 8 | 9 | ```bash 10 | npm install @tigdevs/gazinui 11 | ``` 12 | 13 | ```bash 14 | yarn add @tigdevs/gazinui 15 | ``` 16 | 17 | ## Usage 18 | 19 | First you need to wrap application in `GazinProvider` component. 20 | 21 | ```tsx 22 | import React from 'react' 23 | import ReactDOM from 'react-dom' 24 | 25 | import { GazinProvider } from '@tigdevs/gazinui' 26 | import { App } from './App' 27 | 28 | ReactDOM.render(( 29 | 30 | 31 | 32 | ), document.getElementById('root')) 33 | ``` 34 | 35 | Then use all components available. 36 | 37 | ```tsx 38 | import React from 'react' 39 | 40 | import { GButton } from '@tigdevs/gazinui' 41 | 42 | export const App = () => { 43 | return Testando 44 | } 45 | ``` 46 | 47 | ## Components 48 | 49 | Our interface is a wrapper of [ChakraUI](https://chakra-ui.com/), you an use all components available in its [docs](https://chakra-ui.com/docs/getting-started). 50 | 51 | ## License 52 | 53 | MIT © [Gazin](https://github.com/tigdevs) 54 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "eslint:recommended", 5 | "plugin:react/recommended", 6 | "plugin:@typescript-eslint/recommended", 7 | "plugin:prettier/recommended" 8 | ], 9 | "env": { 10 | "node": true 11 | }, 12 | "parserOptions": { 13 | "ecmaVersion": 2020, 14 | "ecmaFeatures": { 15 | "legacyDecorators": true, 16 | "jsx": true 17 | } 18 | }, 19 | "settings": { 20 | "react": { 21 | "version": "16" 22 | } 23 | }, 24 | "plugins": [ 25 | "react", 26 | "react-hooks", 27 | "@typescript-eslint", 28 | "prettier" 29 | ], 30 | "rules": { 31 | "space-before-function-paren": 0, 32 | "react/prop-types": 0, 33 | "react/jsx-handler-names": 0, 34 | "react/jsx-fragments": 0, 35 | "react/no-unused-prop-types": 0, 36 | "import/export": 0, 37 | "react-hooks/rules-of-hooks": "error", 38 | "react-hooks/exhaustive-deps": "warn", 39 | "@typescript-eslint/explicit-module-boundary-types": "off", 40 | "@typescript-eslint/explicit-function-return-type": "off", 41 | "prettier/prettier": "error", 42 | "@typescript-eslint/member-delimiter-style": [ 43 | "error", { 44 | "multiline": { 45 | "delimiter": "none", 46 | "requireLast": true 47 | }, 48 | "singleline": { 49 | "delimiter": "semi", 50 | "requireLast": false 51 | } 52 | } 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/g-input/g-input.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Input, 4 | InputGroup, 5 | InputLeftElement, 6 | InputRightElement 7 | } from '@chakra-ui/react' 8 | import { TGInput, Element } from './g-input.types' 9 | 10 | export const GInput = ({ 11 | leftElement, 12 | rightElement, 13 | wrapperProps, 14 | ...props 15 | }: TGInput) => { 16 | const renderElement = (_element: Element): React.ReactNode => { 17 | if (typeof _element === 'object') { 18 | if (typeof (_element as React.Component).render !== 'undefined') { 19 | return (_element as React.Component).render() 20 | } else { 21 | return _element as React.ReactNode 22 | } 23 | } 24 | 25 | return (_element as React.FC)({}) 26 | } 27 | 28 | return ( 29 | 30 | {leftElement ? ( 31 | 35 | {renderElement(leftElement)} 36 | 37 | ) : null} 38 | 46 | {rightElement ? ( 47 | 48 | {renderElement(rightElement)} 49 | 50 | ) : null} 51 | 52 | ) 53 | } 54 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gazinui-example", 3 | "homepage": ".", 4 | "version": "0.0.0", 5 | "private": true, 6 | "scripts": { 7 | "start": "node ../node_modules/react-scripts/bin/react-scripts.js start", 8 | "build": "node ../node_modules/react-scripts/bin/react-scripts.js build", 9 | "test": "node ../node_modules/react-scripts/bin/react-scripts.js test", 10 | "eject": "node ../node_modules/react-scripts/bin/react-scripts.js eject" 11 | }, 12 | "dependencies": { 13 | "@testing-library/jest-dom": "link:../node_modules/@testing-library/jest-dom", 14 | "@testing-library/react": "link:../node_modules/@testing-library/react", 15 | "@testing-library/user-event": "link:../node_modules/@testing-library/user-event", 16 | "@types/jest": "link:../node_modules/@types/jest", 17 | "@types/node": "link:../node_modules/@types/node", 18 | "@types/react": "link:../node_modules/@types/react", 19 | "@types/react-dom": "link:../node_modules/@types/react-dom", 20 | "react": "link:../node_modules/react", 21 | "react-dom": "link:../node_modules/react-dom", 22 | "react-scripts": "link:../node_modules/react-scripts", 23 | "typescript": "link:../node_modules/typescript", 24 | "@tigdevs/gazinui": "link:.." 25 | }, 26 | "devDependencies": { 27 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3" 28 | }, 29 | "eslintConfig": { 30 | "extends": "react-app" 31 | }, 32 | "browserslist": { 33 | "production": [ 34 | ">0.2%", 35 | "not dead", 36 | "not op_mini all" 37 | ], 38 | "development": [ 39 | "last 1 chrome version", 40 | "last 1 firefox version", 41 | "last 1 safari version" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /example/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 16 | 17 | 18 | 27 | gazinui 28 | 29 | 30 | 31 | 34 | 35 |
36 | 37 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/theme.ts: -------------------------------------------------------------------------------- 1 | export const theme = { 2 | colors: { 3 | primary: { 4 | 50: '#f2f7fc', 5 | 100: '#eef4fc', 6 | 200: '#d4e4f7', 7 | 300: '#b2cef0', 8 | 400: '#88b3e7', 9 | 500: '#5592dd', 10 | 600: '#2975d1', 11 | 700: '#205aa2', 12 | 800: '#1a4a84', 13 | 900: '#18457b' 14 | }, 15 | secondary: { 16 | 50: '#fff6f0', 17 | 100: '#ffeee0', 18 | 200: '#ffdcc2', 19 | 300: '#ffba85', 20 | 400: '#ff8e38', 21 | 500: '#e66300', 22 | 600: '#b85000', 23 | 700: '#8f3e00', 24 | 800: '#753300', 25 | 900: '#6b2e00' 26 | }, 27 | auxiliary: { 28 | 50: '#fcf3f7', 29 | 100: '#faeff5', 30 | 200: '#f5dbe8', 31 | 300: '#ebbcd4', 32 | 400: '#e094ba', 33 | 500: '#d2659c', 34 | 600: '#c63980', 35 | 700: '#962c61', 36 | 800: '#7b244f', 37 | 900: '#73214a' 38 | }, 39 | neutral: { 40 | 50: '#f7f7f8', 41 | 100: '#f1f1f4', 42 | 200: '#e3e4e8', 43 | 300: '#ebbcd4', 44 | 400: '#abadba', 45 | 500: '#898d9f', 46 | 600: '#6c7084', 47 | 700: '#535665', 48 | 800: '#454754', 49 | 900: '#40434f' 50 | }, 51 | danger: { 52 | 50: '#FEF2F2', 53 | 100: '#FEE2E2', 54 | 200: '#FECACA', 55 | 300: '#FCA5A5', 56 | 400: '#F87171', 57 | 500: '#EF4444', 58 | 600: '#DC2626', 59 | 700: '#B91C1C', 60 | 800: '#991B1B', 61 | 900: '#7F1D1D' 62 | }, 63 | warning: { 64 | 50: '#FFFBEB', 65 | 100: '#FEF3C7', 66 | 200: '#FDE68A', 67 | 300: '#FCD34D', 68 | 400: '#FBBF24', 69 | 500: '#F59E0B', 70 | 600: '#D97706', 71 | 700: '#D97706', 72 | 800: '#92400E', 73 | 900: '#78350F' 74 | }, 75 | success: { 76 | 50: '#ECFDF5', 77 | 100: '#D1FAE5', 78 | 200: '#A7F3D0', 79 | 300: '#6EE7B7', 80 | 400: '#34D399', 81 | 500: '#10B981', 82 | 600: '#059669', 83 | 700: '#047857', 84 | 800: '#065F46', 85 | 900: '#064E3B' 86 | }, 87 | info: { 88 | 50: '#EFF6FF', 89 | 100: '#DBEAFE', 90 | 200: '#BFDBFE', 91 | 300: '#93C5FD', 92 | 400: '#60A5FA', 93 | 500: '#3B82F6', 94 | 600: '#2563EB', 95 | 700: '#1D4ED8', 96 | 800: '#1E40AF', 97 | 900: '#1E3A8A' 98 | } 99 | }, 100 | fonts: { 101 | body: 'Inter, sans-serif', 102 | heading: 'Inter, sans-serif', 103 | mono: 'Menlo, monospace' 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tigdevs/gazinui", 3 | "version": "0.1.1", 4 | "description": "Interface based on Gazin's design system to React Applications.", 5 | "author": "tigdevs", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/tigdevs/gazinui.git" 10 | }, 11 | "main": "dist/index.js", 12 | "module": "dist/index.modern.js", 13 | "source": "src/index.tsx", 14 | "engines": { 15 | "node": ">=10" 16 | }, 17 | "scripts": { 18 | "build": "microbundle-crl --no-compress --format modern,cjs", 19 | "start": "microbundle-crl watch --no-compress --format modern,cjs", 20 | "prepare": "run-s build", 21 | "test": "run-s test:unit test:lint test:build", 22 | "test:build": "run-s build", 23 | "test:lint": "eslint ./src/*/*.{tsx,ts}", 24 | "test:unit": "cross-env CI=1 react-scripts test --env=jsdom", 25 | "test:watch": "react-scripts test --env=jsdom", 26 | "predeploy": "cd example && yarn install && yarn run build", 27 | "deploy": "gh-pages -d example/build" 28 | }, 29 | "peerDependencies": { 30 | "react": "^16.0.0" 31 | }, 32 | "devDependencies": { 33 | "@testing-library/jest-dom": "^4.2.4", 34 | "@testing-library/react": "^9.5.0", 35 | "@testing-library/user-event": "^7.2.1", 36 | "@types/jest": "^25.1.4", 37 | "@types/lodash.merge": "^4.6.6", 38 | "@types/node": "^12.12.38", 39 | "@types/react": "^16.9.27", 40 | "@types/react-dom": "^16.9.7", 41 | "@typescript-eslint/eslint-plugin": "^2.26.0", 42 | "@typescript-eslint/parser": "^2.26.0", 43 | "babel-eslint": "^10.0.3", 44 | "cross-env": "^7.0.2", 45 | "eslint": "^6.8.0", 46 | "eslint-config-prettier": "^6.7.0", 47 | "eslint-config-standard": "^14.1.0", 48 | "eslint-config-standard-react": "^9.2.0", 49 | "eslint-plugin-import": "^2.18.2", 50 | "eslint-plugin-node": "^11.0.0", 51 | "eslint-plugin-prettier": "^3.1.1", 52 | "eslint-plugin-promise": "^4.2.1", 53 | "eslint-plugin-react": "^7.17.0", 54 | "eslint-plugin-standard": "^4.0.1", 55 | "gh-pages": "^2.2.0", 56 | "lodash.merge": "^4.6.2", 57 | "microbundle-crl": "^0.13.10", 58 | "npm-run-all": "^4.1.5", 59 | "prettier": "^2.0.4", 60 | "react": "^16.13.1", 61 | "react-dom": "^16.13.1", 62 | "react-scripts": "^3.4.1", 63 | "typescript": "^3.7.5" 64 | }, 65 | "files": [ 66 | "dist" 67 | ], 68 | "dependencies": { 69 | "@chakra-ui/icons": "^1.0.6", 70 | "@chakra-ui/react": "^1.3.3", 71 | "@emotion/react": "^11.1.5", 72 | "@emotion/styled": "^11.1.5", 73 | "framer-motion": "^3.10.0" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/g-select/g-select.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | BaseSyntheticEvent, 3 | JSXElementConstructor, 4 | useEffect, 5 | useRef, 6 | useState 7 | } from 'react' 8 | import { jsx } from '@emotion/react' 9 | import { Flex } from '@chakra-ui/layout' 10 | import { ChevronDownIcon, ChevronUpIcon } from '@chakra-ui/icons' 11 | import { GSelectProps, InputType } from './g-select.types' 12 | import { GOption } from '../g-option' 13 | import { GOptionProps } from '../g-option' 14 | 15 | type JSXElementConstructorEx = JSXElementConstructor & { 16 | prototype: { 17 | constructor: (...props: T[]) => JSXElementConstructor 18 | } 19 | } 20 | 21 | export const GSelect = ({ 22 | children, 23 | value, 24 | placeholder, 25 | inputProps, 26 | ...props 27 | }: GSelectProps) => { 28 | const DEFAULT_PLACEHOLDER = 'Selecione' 29 | const [open, setOpen] = useState(false) 30 | const [_placeholder, _setPlaceholder] = useState( 31 | placeholder ?? DEFAULT_PLACEHOLDER 32 | ) 33 | const [_currentOption, _setCurrentOption] = useState(null) 34 | const selectRef = useRef(null) 35 | const inputRef = useRef(null) 36 | 37 | useEffect(() => { 38 | const handleClickOutside = (e: Event & MouseEvent) => { 39 | if ( 40 | selectRef?.current && 41 | ((selectRef?.current as unknown) as Node).contains( 42 | (e.target as unknown) as Node 43 | ) 44 | ) { 45 | return 46 | } 47 | 48 | setOpen(false) 49 | } 50 | 51 | document.addEventListener('mousedown', handleClickOutside) 52 | 53 | return () => { 54 | document.removeEventListener('mousedown', handleClickOutside) 55 | } 56 | }) 57 | 58 | useEffect(() => { 59 | if (placeholder === undefined) { 60 | _setPlaceholder(DEFAULT_PLACEHOLDER) 61 | } else { 62 | _setPlaceholder(placeholder) 63 | } 64 | }, [placeholder]) 65 | 66 | useEffect(() => { 67 | let optionFound = false 68 | 69 | if (value !== null && value !== undefined) { 70 | for (const _children of children as React.ReactElement[]) { 71 | if (_children.props.value === value) { 72 | _setCurrentOption( 73 | 74 | {_children.props.children} 75 | 76 | ) 77 | optionFound = true 78 | 79 | break 80 | } 81 | } 82 | } 83 | 84 | if (!optionFound) { 85 | _setCurrentOption( 86 | 87 | {_placeholder} 88 | 89 | ) 90 | } 91 | }, [value, _placeholder, children]) 92 | 93 | const toggle = () => { 94 | setOpen(!open) 95 | } 96 | 97 | const inputDispatchEvent = (eventName: string) => { 98 | const input = inputRef.current 99 | 100 | if (!input) { 101 | return 102 | } 103 | 104 | const eventNameSanitized = eventName.toLowerCase() 105 | const bufferName = 106 | eventNameSanitized.charAt(0).toUpperCase() + eventNameSanitized.slice(1) 107 | 108 | if (eventNameSanitized === 'change') { 109 | input.value = input._valueTracker.getValue() 110 | input._valueTracker.setValue('__placeholder__') 111 | } 112 | 113 | if (typeof input[eventNameSanitized] === 'function') { 114 | input[eventNameSanitized]() 115 | } else { 116 | let ev: Event 117 | 118 | if (window[`${bufferName}Event`]) { 119 | ev = new window[`${bufferName}Event`](eventNameSanitized) 120 | } else { 121 | ev = new Event(eventNameSanitized) 122 | } 123 | 124 | ev.initEvent(eventNameSanitized, true) 125 | input.dispatchEvent(ev) 126 | } 127 | } 128 | 129 | useEffect(() => { 130 | if (open) { 131 | inputDispatchEvent('focus') 132 | } else { 133 | inputDispatchEvent('blur') 134 | } 135 | }, [open]) 136 | 137 | const changeValue = (newValue: string) => { 138 | if (newValue !== value && inputRef.current) { 139 | inputRef.current._valueTracker.setValue(newValue) 140 | 141 | inputDispatchEvent('change') 142 | inputDispatchEvent('input') 143 | } 144 | 145 | setOpen(false) 146 | } 147 | 148 | return ( 149 | 162 | {_currentOption} 163 | {open ? ( 164 | 165 | ) : ( 166 | 167 | )} 168 | {open ? ( 169 | 180 | {(children as React.ReactElement[]).map( 181 | (option: jsx.JSX.Element, index) => { 182 | const props = { ...option.props } 183 | 184 | props.key = index 185 | props.onClick = (event: BaseSyntheticEvent) => { 186 | event.stopPropagation() 187 | 188 | changeValue(props.value) 189 | } 190 | 191 | return (option.type as JSXElementConstructorEx).prototype.constructor( 192 | props 193 | ) 194 | } 195 | )} 196 | 197 | ) : null} 198 | 199 | { 200 | (( 201 | 202 | ) as unknown) as InputType 203 | } 204 | 205 | 206 | ) 207 | } 208 | --------------------------------------------------------------------------------