├── .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 | [](https://www.npmjs.com/package/@tigdevs/gazinui) [](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 |
--------------------------------------------------------------------------------