Browse Source

initial

master
ChiefRed 3 years ago
parent
commit
910b1c7082
39 changed files with 105007 additions and 104 deletions
  1. +15
    -3
      package.json
  2. +7
    -0
      postcss.config.js
  3. +0
    -38
      src/App.css
  4. +0
    -26
      src/App.js
  5. +47
    -0
      src/App.jsx
  6. +46
    -0
      src/Popup.jsx
  7. BIN
      src/assets/fonts/Gilroy-ExtraBold.eot
  8. BIN
      src/assets/fonts/Gilroy-ExtraBold.ttf
  9. BIN
      src/assets/fonts/Gilroy-ExtraBold.woff
  10. BIN
      src/assets/fonts/Gilroy-ExtraBold.woff2
  11. BIN
      src/assets/fonts/Gilroy-Medium.eot
  12. BIN
      src/assets/fonts/Gilroy-Medium.ttf
  13. BIN
      src/assets/fonts/Gilroy-Medium.woff
  14. BIN
      src/assets/fonts/Gilroy-Medium.woff2
  15. BIN
      src/assets/fonts/Gilroy-Regular.eot
  16. BIN
      src/assets/fonts/Gilroy-Regular.ttf
  17. BIN
      src/assets/fonts/Gilroy-Regular.woff
  18. BIN
      src/assets/fonts/Gilroy-Regular.woff2
  19. BIN
      src/assets/fonts/Gilroy-SemiBold.eot
  20. BIN
      src/assets/fonts/Gilroy-SemiBold.ttf
  21. BIN
      src/assets/fonts/Gilroy-SemiBold.woff
  22. BIN
      src/assets/fonts/Gilroy-SemiBold.woff2
  23. +103099
    -0
      src/assets/styles/.index.css
  24. +45
    -0
      src/assets/styles/index.tailwind.css
  25. +7
    -0
      src/components/FormikControls/FormikControlErrorMessage.jsx
  26. +26
    -0
      src/components/FormikControls/FormikControlTypes/FormikControlCheckbox.jsx
  27. +20
    -0
      src/components/FormikControls/FormikControlTypes/FormikControlPassword.jsx
  28. +20
    -0
      src/components/FormikControls/FormikControlTypes/FormikControlString.jsx
  29. +32
    -0
      src/components/FormikControls/index.js
  30. +40
    -0
      src/components/controls/ButtonPrimary.jsx
  31. +41
    -0
      src/components/controls/ButtonSecondary.jsx
  32. +11
    -0
      src/components/controls/Link.jsx
  33. +76
    -0
      src/components/forms/FormLogin.jsx
  34. +0
    -13
      src/index.css
  35. +1
    -1
      src/index.js
  36. +0
    -7
      src/logo.svg
  37. +6
    -0
      src/utils/newId.js
  38. +798
    -0
      tailwind.js
  39. +670
    -16
      yarn.lock

+ 15
- 3
package.json View File

@@ -2,19 +2,24 @@
"name": "react-formik-tailwind-labwork",
"version": "0.1.0",
"private": true,
"homepage": ".",
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"autoprefixer": "9.8.6",
"postcss-cli": "^8.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"start": "yarn build:css && react-scripts start",
"build": "export NODE_ENV=production && yarn build:css && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"build:css": "postcss src/assets/styles/index.tailwind.css -o src/assets/styles/.index.css",
"watch:css": "postcss -w src/assets/styles/index.tailwind.css -o src/assets/styles/.index.css"
},
"eslintConfig": {
"extends": "react-app"
@@ -30,5 +35,12 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@tailwindcss/custom-forms": "^0.2.1",
"formik": "^2.1.7",
"framer-motion": "^2.7.7",
"tailwindcss": "^1.8.10",
"yup": "^0.29.3"
}
}

+ 7
- 0
postcss.config.js View File

@@ -0,0 +1,7 @@
const tailwindcss = require('tailwindcss');
module.exports = {
plugins: [
tailwindcss('./tailwind.js'),
require('autoprefixer'),
],
};

+ 0
- 38
src/App.css View File

@@ -1,38 +0,0 @@
.App {
text-align: center;
}

.App-logo {
height: 40vmin;
pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}

.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}

.App-link {
color: #61dafb;
}

@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

+ 0
- 26
src/App.js View File

@@ -1,26 +0,0 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}

export default App;

+ 47
- 0
src/App.jsx View File

@@ -0,0 +1,47 @@
import React, { useState } from 'react'

import ButtonPrimary from './components/controls/ButtonPrimary'
import Popup from './Popup';

import { FormLogin, FormLoginTitle } from './components/forms/FormLogin'


const App = () => {
const [popup, setPopup] = useState('')
const [popupOpened, setPopupOpened] = useState(false)

const openPopup = (popupCode) => {
setPopup(popupCode)
setPopupOpened(true)
}

const closePopup = () => {
setPopupOpened(false)
}

let popupForm = null
let popupTitle = null

switch (popup) {
case 'login':
popupTitle = FormLoginTitle
popupForm = <FormLogin closePopup={closePopup} />
break
default:
popupTitle = null
popupForm = null
}

return (
<>
<div className="w-full h-full min-h-screen bg-blue-900">
<div className="max-w-lg mx-auto py-8">
<ButtonPrimary text="Login" action={() => openPopup('login')} />
</div>
</div>
<Popup opened={popupOpened} title={popupTitle} close={closePopup}>{popupForm}</Popup>
</>
)
}

export default App;

+ 46
- 0
src/Popup.jsx View File

@@ -0,0 +1,46 @@
import React from 'react';
import { motion, AnimatePresence } from "framer-motion"

export function Popup({ opened, title, close, children }) {

const popupMotionVariants = {
hidden: { opacity: 0, scale: .9 },
visible: { opacity: 1, scale: 1 },
}

//document.body.style.overflow='hidden';
// Если надо закрывать по клику за попапом, то в первый див надо добавить onClick={close}
return <>
<AnimatePresence>
{opened &&
<div className="modal z-50 fixed w-full min-h-screen top-0 left-0 flex items-center justify-center">
<div className="modal-overlay absolute top-0 left-0 w-full h-full bg-gray-100 opacity-75"></div>
<div className="modal-wrapper relative w-full">
<div className="max-w-full max-h-screen sm:max-w-lg mx-auto">
<motion.div
variants={popupMotionVariants}
initial="hidden"
animate="visible"
exit="hidden"
transition={{ duration: .1 }}
>
<div className="ma-0 bg-white shadow-lg border-gray-500 border-t-2 border-b-2 sm:border-2 sm:mx-4 sm:rounded-lg transition-opacity duration-300" onClick={e => e.stopPropagation()}>
<div className="px-3 h-12 border-b border-gray-400 font-semibold relative flex items-center">
<div className="w-full text-xl">{title}</div>
<div className="absolute top-0 right-0 w-12 h-12 pb-1 text-3xl leading-none cursor-pointer flex items-center justify-center" onClick={close}>&times;</div>
</div>
<div className="">
{children}
</div>
</div>
</motion.div>
</div>
</div>
</div>
}
</AnimatePresence>

</>
}

export default Popup;

BIN
src/assets/fonts/Gilroy-ExtraBold.eot View File


BIN
src/assets/fonts/Gilroy-ExtraBold.ttf View File


BIN
src/assets/fonts/Gilroy-ExtraBold.woff View File


BIN
src/assets/fonts/Gilroy-ExtraBold.woff2 View File


BIN
src/assets/fonts/Gilroy-Medium.eot View File


BIN
src/assets/fonts/Gilroy-Medium.ttf View File


BIN
src/assets/fonts/Gilroy-Medium.woff View File


BIN
src/assets/fonts/Gilroy-Medium.woff2 View File


BIN
src/assets/fonts/Gilroy-Regular.eot View File


BIN
src/assets/fonts/Gilroy-Regular.ttf View File


BIN
src/assets/fonts/Gilroy-Regular.woff View File


BIN
src/assets/fonts/Gilroy-Regular.woff2 View File


BIN
src/assets/fonts/Gilroy-SemiBold.eot View File


BIN
src/assets/fonts/Gilroy-SemiBold.ttf View File


BIN
src/assets/fonts/Gilroy-SemiBold.woff View File


BIN
src/assets/fonts/Gilroy-SemiBold.woff2 View File


+ 103099
- 0
src/assets/styles/.index.css
File diff suppressed because it is too large
View File


+ 45
- 0
src/assets/styles/index.tailwind.css View File

@@ -0,0 +1,45 @@
/* purgecss start ignore */
@tailwind base;
@tailwind components;
/* purgecss end ignore */

@tailwind utilities;


/***** FONTS *****/

@font-face {
font-family: 'Gilroy';
src: url('../fonts/Gilroy-Regular.eot');
src: url('../fonts/Gilroy-Regular.eot?#iefix') format('embedded-opentype'), url('../fonts/Gilroy-Regular.woff2') format('woff2'), url('../fonts/Gilroy-Regular.woff') format('woff'), url('../fonts/Gilroy-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: 'Gilroy';
src: url('../fonts/Gilroy-Medium.eot');
src: url('../fonts/Gilroy-Medium.eot?#iefix') format('embedded-opentype'), url('../fonts/Gilroy-Medium.woff2') format('woff2'), url('../fonts/Gilroy-Medium.woff') format('woff'), url('../fonts/Gilroy-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: 'Gilroy';
src: url('../fonts/Gilroy-SemiBold.eot');
src: url('../fonts/Gilroy-SemiBold.eot?#iefix') format('embedded-opentype'), url('../fonts/Gilroy-SemiBold.woff2') format('woff2'), url('../fonts/Gilroy-SemiBold.woff') format('woff'), url('../fonts/Gilroy-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}

@font-face {
font-family: 'Gilroy';
src: url('../fonts/Gilroy-ExtraBold.eot');
src: url('../fonts/Gilroy-ExtraBold.eot?#iefix') format('embedded-opentype'), url('../fonts/Gilroy-ExtraBold.woff2') format('woff2'), url('../fonts/Gilroy-ExtraBold.woff') format('woff'), url('../fonts/Gilroy-ExtraBold.ttf') format('truetype');
font-weight: 800;
font-style: normal;
font-display: swap;
}

+ 7
- 0
src/components/FormikControls/FormikControlErrorMessage.jsx View File

@@ -0,0 +1,7 @@
import React from 'react'

function FormikControlErrorMessage(props) {
return <div className='error text-sm text-secondary-dark mt-1'>{props.children}</div>
}

export default FormikControlErrorMessage

+ 26
- 0
src/components/FormikControls/FormikControlTypes/FormikControlCheckbox.jsx View File

@@ -0,0 +1,26 @@
import React from 'react'
import { Field, ErrorMessage } from 'formik'
import FormikControlErrorMessage from '../FormikControlErrorMessage'
import newId from '../../../utils/newId';

function FormikControlCheckbox(props) {
const { name, label, ...rest } = props
return (
<div className="form-control mt-6 mb-4">
<Field name={name}>
{({ field }) => {
const htmlId = newId()
return <>
<label htmlFor={htmlId} className="inline-flex items-center py-1">
<input type="checkbox" id={htmlId} name={name} {...rest} className="form-checkbox text-primary-dark" {...field} checked={field.value} />
<span className="ml-4 text-base sm:text-lg ">{label}</span>
</label>
</>
}}
</Field>
<ErrorMessage component={FormikControlErrorMessage} name={name} />
</div>
)
}

export default FormikControlCheckbox

+ 20
- 0
src/components/FormikControls/FormikControlTypes/FormikControlPassword.jsx View File

@@ -0,0 +1,20 @@
import React from 'react'
import { Field, ErrorMessage } from 'formik'
import FormikControlErrorMessage from '../FormikControlErrorMessage'
import newId from '../../../utils/newId';

function FormikControlPassword(props) {
const { label, name, ...rest } = props
const htmlId = newId()
return (
<div className="mt-4 mb-2">
<label htmlFor={htmlId} className="form-control block text-lg text-gray-800 py-1">
<span className="text-gray-700">{label}</span>
<Field type="password" id={htmlId} name={name} {...rest} className="form-input mt-1 block w-full text-center tracking-widest" />
<ErrorMessage component={FormikControlErrorMessage} name={name} />
</label>
</div>
)
}

export default FormikControlPassword

+ 20
- 0
src/components/FormikControls/FormikControlTypes/FormikControlString.jsx View File

@@ -0,0 +1,20 @@
import React from 'react'
import { Field, ErrorMessage } from 'formik'
import FormikControlErrorMessage from '../FormikControlErrorMessage'
import newId from '../../../utils/newId';

function FormikControlString(props) {
const { label, name, ...rest } = props
const htmlId = newId()
return (
<div className="mt-4 mb-2">
<label htmlFor={htmlId} className="form-control block text-lg text-gray-800 py-1">
<span className="text-gray-700">{label}</span>
<Field type="text" id={htmlId} name={name} {...rest} className="form-input mt-1 block w-full text-center tracking-widest" />
<ErrorMessage component={FormikControlErrorMessage} name={name} />
</label>
</div>
)
}

export default FormikControlString

+ 32
- 0
src/components/FormikControls/index.js View File

@@ -0,0 +1,32 @@
import React from 'react'
import FormikControlString from './FormikControlTypes/FormikControlString'
import FormikControlPassword from './FormikControlTypes/FormikControlPassword'


export function FormikControl(props) {
const { control, ...rest } = props
switch (control) {
case 'string':
return <FormikControlString {...rest} />
case 'password':
return <FormikControlPassword {...rest} />
// case 'textarea':
// return <FormikInputTextarea {...rest} />
// case 'select':
// return <FormikInputSelect {...rest} />
// case 'radio':
// return <FormikInputRadioGroup {...rest} />
// case 'checkbox':
// return <FormikInputCheckbox {...rest} />
// case 'checkboxs':
// return <FormikInputCheckboxGroup {...rest} />
// case 'userconsent':
// return <FormikInputUserConsent {...rest} />
// case 'phone':
// return <FormikInputPhone {...rest} />
default:
return null
}
}

export default FormikControl

+ 40
- 0
src/components/controls/ButtonPrimary.jsx View File

@@ -0,0 +1,40 @@
import React from 'react'

function PrimaryButton({type, text, action, disabled}) {
return <>
<button
type={type||'button'}
className="
appearance-none
flex
relative
w-full
p-3
border-0
rounded-md
border-primary-dark
bg-primary-dark
text-white
cursor-pointer
shadow-md
hover:bg-primary-light
focus:bg-primary-light
focus:outline-none
active:shadow-inner
active:bg-primary-dark
active:transform
active:translate-y-px
disabled:bg-primary-dark
disabled:opacity-50
disabled:shadow-md
disabled:translate-y-0
disabled:cursor-not-allowed
"
onClick={action}
disabled={disabled}
>
<div className="sm:text-lg flex-grow text-center px-6">{text||'Primary Button'}</div>
</button>
</>
}
export default PrimaryButton

+ 41
- 0
src/components/controls/ButtonSecondary.jsx View File

@@ -0,0 +1,41 @@
import React from 'react'

function Buttonprimary({type, text, action, disabled}) {
return <>
<button
type={type||'button'}
className="
appearance-none
flex
relative
w-full
p-3
border-2
rounded-md
border-primary-dark
bg-white
text-primary-dark
cursor-pointer
shadow-md
hover:bg-primary-light
hover:text-white
focus:bg-primary-light
focus:outline-none
active:shadow-inner
active:bg-primary-light
active:transform
active:translate-y-px
disabled:bg-white
disabled:opacity-50
disabled:shadow-md
disabled:translate-y-0
disabled:cursor-not-allowed
"
onClick={action}
disabled={disabled}
>
<div className="sm:text-lg flex-grow text-center px-6">{text||'primary Button'}</div>
</button>
</>
}
export default Buttonprimary

+ 11
- 0
src/components/controls/Link.jsx View File

@@ -0,0 +1,11 @@
import React from 'react'

function Link(props) {
const { action, children, className, ...rest } = props
const classNames = ['text-primary-dark cursor-pointer hover:underline', className].join(' ');
return (
<span onClick={action} className={classNames} {...rest}>{children}</span>
)
}

export default Link

+ 76
- 0
src/components/forms/FormLogin.jsx View File

@@ -0,0 +1,76 @@
import React from 'react'
import { Formik, Form } from 'formik'
import * as Yup from 'yup'
import FormikControl from '../FormikControls'
import ButtonPrimary from '../controls/ButtonPrimary'
import ButtonSecondary from '../controls/ButtonSecondary'

export const FormLoginTitle = 'Authentication'

export const FormLogin = () => {

const initialValues = {
login: '',
password: '',
remember_me: false,
}

const validationSchema = Yup.object({
login: Yup.string()
.required('Required'),
password: Yup.string()
.required('Required'),
})

const onSubmit = async values => {
console.log('Form data', values)
}

const goRegistration = () => {
console.log('goRegistration')
}

return (
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
{formik => {
return (
<Form>
<div className="overflow-y-auto max-screen--mt-12 p-3">
<FormikControl
control='string'
name='login'
label='Login'
placeholder='Enter Login'
/>
<FormikControl
control='password'
name='password'
label='Password'
placeholder='Enter Password'
/>
<div className="flex flex-col xs:flex-row justify-between items-center xs:items-start">
<div>
<FormikControl
control='checkbox'
name='remember_me'
label='Remember Me'
/>
</div>
</div>
</div>
<div className="p-3 border-t border-gray-400">
<ButtonPrimary type="submit" text="LogIn" disabled={!formik.isValid || !formik.dirty} />
<div className="my-3">
<ButtonSecondary type="button" text="SignIn" action={goRegistration} />
</div>
</div>
</Form>
)
}}
</Formik>
)
}

+ 0
- 13
src/index.css View File

@@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

+ 1
- 1
src/index.js View File

@@ -1,6 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import './assets/styles/.index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';


+ 0
- 7
src/logo.svg View File

@@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

+ 6
- 0
src/utils/newId.js View File

@@ -0,0 +1,6 @@
let lastId = 0;

export default function(prefix='id') {
lastId++;
return `${prefix}${lastId}`;
}

+ 798
- 0
tailwind.js View File

@@ -0,0 +1,798 @@
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
purgeLayersByDefault: true,
},
purge: [
'./src/**/*.jsx',
],
target: 'relaxed',
prefix: '',
important: false,
separator: ':',
theme: {
screens: {
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
},
colors: {
transparent: 'transparent',
current: 'currentColor',

primary: {
semitransparent: "#EF303D1F",
light: "#EF303D",
dark: "#94070C",
},

secondary: {
light: "#FFE9C6",
dark: "#EBB35C",
},

black: '#000',
white: '#fff',

gray: {
100: '#f7fafc',
200: '#edf2f7',
300: '#e2e8f0',
400: '#cbd5e0',
500: '#a0aec0',
600: '#718096',
700: '#4a5568',
800: '#2d3748',
900: '#1a202c',
},
red: {
100: '#fff5f5',
200: '#fed7d7',
300: '#feb2b2',
400: '#fc8181',
500: '#f56565',
600: '#e53e3e',
700: '#c53030',
800: '#9b2c2c',
900: '#742a2a',
},
orange: {
100: '#fffaf0',
200: '#feebc8',
300: '#fbd38d',
400: '#f6ad55',
500: '#ed8936',
600: '#dd6b20',
700: '#c05621',
800: '#9c4221',
900: '#7b341e',
},
yellow: {
100: '#fffff0',
200: '#fefcbf',
300: '#faf089',
400: '#f6e05e',
500: '#ecc94b',
600: '#d69e2e',
700: '#b7791f',
800: '#975a16',
900: '#744210',
},
green: {
100: '#f0fff4',
200: '#c6f6d5',
300: '#9ae6b4',
400: '#68d391',
500: '#48bb78',
600: '#38a169',
700: '#2f855a',
800: '#276749',
900: '#22543d',
},
teal: {
100: '#e6fffa',
200: '#b2f5ea',
300: '#81e6d9',
400: '#4fd1c5',
500: '#38b2ac',
600: '#319795',
700: '#2c7a7b',
800: '#285e61',
900: '#234e52',
},
blue: {
100: '#ebf8ff',
200: '#bee3f8',
300: '#90cdf4',
400: '#63b3ed',
500: '#4299e1',
600: '#3182ce',
700: '#2b6cb0',
800: '#2c5282',
900: '#2a4365',
},
indigo: {
100: '#ebf4ff',
200: '#c3dafe',
300: '#a3bffa',
400: '#7f9cf5',
500: '#667eea',
600: '#5a67d8',
700: '#4c51bf',
800: '#434190',
900: '#3c366b',
},
purple: {
100: '#faf5ff',
200: '#e9d8fd',
300: '#d6bcfa',
400: '#b794f4',
500: '#9f7aea',
600: '#805ad5',
700: '#6b46c1',
800: '#553c9a',
900: '#44337a',
},
pink: {
100: '#fff5f7',
200: '#fed7e2',
300: '#fbb6ce',
400: '#f687b3',
500: '#ed64a6',
600: '#d53f8c',
700: '#b83280',
800: '#97266d',
900: '#702459',
},
},
spacing: {
px: '1px',
'0': '0',
'1': '0.25rem',
'2': '0.5rem',
'3': '0.75rem',
'4': '1rem',
'5': '1.25rem',
'6': '1.5rem',
'8': '2rem',
'10': '2.5rem',
'12': '3rem',
'16': '4rem',
'20': '5rem',
'24': '6rem',
'32': '8rem',
'40': '10rem',
'48': '12rem',
'56': '14rem',
'64': '16rem',
},
backgroundColor: theme => theme('colors'),
backgroundImage: {
none: 'none',
'gradient-to-t': 'linear-gradient(to top, var(--gradient-color-stops))',
'gradient-to-tr': 'linear-gradient(to top right, var(--gradient-color-stops))',
'gradient-to-r': 'linear-gradient(to right, var(--gradient-color-stops))',
'gradient-to-br': 'linear-gradient(to bottom right, var(--gradient-color-stops))',
'gradient-to-b': 'linear-gradient(to bottom, var(--gradient-color-stops))',
'gradient-to-bl': 'linear-gradient(to bottom left, var(--gradient-color-stops))',
'gradient-to-l': 'linear-gradient(to left, var(--gradient-color-stops))',
'gradient-to-tl': 'linear-gradient(to top left, var(--gradient-color-stops))',
},
gradientColorStops: theme => theme('colors'),
backgroundOpacity: theme => theme('opacity'),
backgroundPosition: {
bottom: 'bottom',
center: 'center',
left: 'left',
'left-bottom': 'left bottom',
'left-top': 'left top',
right: 'right',
'right-bottom': 'right bottom',
'right-top': 'right top',
top: 'top',
},
backgroundSize: {
auto: 'auto',
cover: 'cover',
contain: 'contain',
},
borderColor: theme => ({
...theme('colors'),
default: theme('colors.gray.300', 'currentColor'),
}),
borderOpacity: theme => theme('opacity'),
borderRadius: {
none: '0',
sm: '0.125rem',
default: '0.25rem',
md: '0.375rem',
lg: '0.5rem',
full: '9999px',
},
borderWidth: {
default: '1px',
'0': '0',
'2': '2px',
'4': '4px',
'8': '8px',
},
boxShadow: {
xs: '0 0 0 1px rgba(0, 0, 0, 0.05)',
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
default: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
outline: '0 0 0 3px rgba(148, 7, 12, 0.5)',
none: 'none',
},
container: {},
cursor: {
auto: 'auto',
default: 'default',
pointer: 'pointer',
wait: 'wait',
text: 'text',
move: 'move',
'not-allowed': 'not-allowed',
},
divideColor: theme => theme('borderColor'),
divideOpacity: theme => theme('borderOpacity'),
divideWidth: theme => theme('borderWidth'),
fill: {
current: 'currentColor',
},
flex: {
'1': '1 1 0%',
auto: '1 1 auto',
initial: '0 1 auto',
none: 'none',
},
flexGrow: {
'0': '0',
default: '1',
},
flexShrink: {
'0': '0',
default: '1',
},
fontFamily: {
gilroy: ['"Gilroy"'],
sans: [
'system-ui',
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'"Noto Sans"',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
'"Noto Color Emoji"',
],
serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'],
mono: ['Menlo', 'Monaco', 'Consolas', '"Liberation Mono"', '"Courier New"', 'monospace'],
},
fontSize: {
xs: '0.75rem',
sm: '0.875rem',
base: '1rem',
lg: '1.125rem',
xl: '1.25rem',
'2xl': '1.5rem',
'3xl': '1.875rem',
'4xl': '2.25rem',
'5xl': '3rem',
'6xl': '4rem',
},
fontWeight: {
hairline: '100',
thin: '200',
light: '300',
normal: '400',
medium: '500',
semibold: '600',
bold: '700',
extrabold: '800',
black: '900',
},
height: theme => ({
auto: 'auto',
...theme('spacing'),
full: '100%',
screen: '100vh',
}),
inset: {
'0': '0',
auto: 'auto',
},
letterSpacing: {
tighter: '-0.05em',
tight: '-0.025em',
normal: '0',
wide: '0.025em',
wider: '0.05em',
widest: '0.1em',
},
lineHeight: {
none: '1',
tight: '1.25',
snug: '1.375',
normal: '1.5',
relaxed: '1.625',
loose: '2',
'3': '.75rem',
'4': '1rem',
'5': '1.25rem',
'6': '1.5rem',
'7': '1.75rem',
'8': '2rem',
'9': '2.25rem',
'10': '2.5rem',
},
listStyleType: {
none: 'none',
disc: 'disc',
decimal: 'decimal',
},
margin: (theme, { negative }) => ({
auto: 'auto',
...theme('spacing'),
...negative(theme('spacing')),
}),
maxHeight: {
full: '100%',
screen: '100vh',
},
maxWidth: (theme, { breakpoints }) => ({
none: 'none',
xs: '20rem',
sm: '24rem',
md: '28rem',
lg: '32rem',
xl: '36rem',
'2xl': '42rem',
'3xl': '48rem',
'4xl': '56rem',
'5xl': '64rem',
'6xl': '72rem',
full: '100%',
...breakpoints(theme('screens')),
}),
minHeight: {
'0': '0',
full: '100%',
screen: '100vh',
},
minWidth: {
'0': '0',
full: '100%',
},
objectPosition: {
bottom: 'bottom',
center: 'center',
left: 'left',
'left-bottom': 'left bottom',
'left-top': 'left top',
right: 'right',
'right-bottom': 'right bottom',
'right-top': 'right top',
top: 'top',
},
opacity: {
'0': '0',
'25': '0.25',
'50': '0.5',
'75': '0.75',
'100': '1',
},
order: {
first: '-9999',
last: '9999',
none: '0',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
},
padding: theme => theme('spacing'),
placeholderColor: theme => theme('colors'),
placeholderOpacity: theme => theme('opacity'),
space: (theme, { negative }) => ({
...theme('spacing'),
...negative(theme('spacing')),
}),
stroke: {
current: 'currentColor',
},
strokeWidth: {
'0': '0',
'1': '1',
'2': '2',
},
textColor: theme => theme('colors'),
textOpacity: theme => theme('opacity'),
width: theme => ({
auto: 'auto',
...theme('spacing'),
'1/2': '50%',
'1/3': '33.333333%',
'2/3': '66.666667%',
'1/4': '25%',
'2/4': '50%',
'3/4': '75%',
'1/5': '20%',
'2/5': '40%',
'3/5': '60%',
'4/5': '80%',
'1/6': '16.666667%',
'2/6': '33.333333%',
'3/6': '50%',
'4/6': '66.666667%',
'5/6': '83.333333%',
'1/12': '8.333333%',
'2/12': '16.666667%',
'3/12': '25%',
'4/12': '33.333333%',
'5/12': '41.666667%',
'6/12': '50%',
'7/12': '58.333333%',
'8/12': '66.666667%',
'9/12': '75%',
'10/12': '83.333333%',
'11/12': '91.666667%',
full: '100%',
screen: '100vw',
}),
zIndex: {
auto: 'auto',
'0': '0',
'10': '10',
'20': '20',
'30': '30',
'40': '40',
'50': '50',
},
gap: theme => theme('spacing'),
gridTemplateColumns: {
none: 'none',
'1': 'repeat(1, minmax(0, 1fr))',
'2': 'repeat(2, minmax(0, 1fr))',
'3': 'repeat(3, minmax(0, 1fr))',
'4': 'repeat(4, minmax(0, 1fr))',
'5': 'repeat(5, minmax(0, 1fr))',
'6': 'repeat(6, minmax(0, 1fr))',
'7': 'repeat(7, minmax(0, 1fr))',
'8': 'repeat(8, minmax(0, 1fr))',
'9': 'repeat(9, minmax(0, 1fr))',
'10': 'repeat(10, minmax(0, 1fr))',
'11': 'repeat(11, minmax(0, 1fr))',
'12': 'repeat(12, minmax(0, 1fr))',
},
gridColumn: {
auto: 'auto',
'span-1': 'span 1 / span 1',
'span-2': 'span 2 / span 2',
'span-3': 'span 3 / span 3',
'span-4': 'span 4 / span 4',
'span-5': 'span 5 / span 5',
'span-6': 'span 6 / span 6',
'span-7': 'span 7 / span 7',
'span-8': 'span 8 / span 8',
'span-9': 'span 9 / span 9',
'span-10': 'span 10 / span 10',
'span-11': 'span 11 / span 11',
'span-12': 'span 12 / span 12',
},
gridColumnStart: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
'13': '13',
},
gridColumnEnd: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
'13': '13',
},
gridTemplateRows: {
none: 'none',
'1': 'repeat(1, minmax(0, 1fr))',
'2': 'repeat(2, minmax(0, 1fr))',
'3': 'repeat(3, minmax(0, 1fr))',
'4': 'repeat(4, minmax(0, 1fr))',
'5': 'repeat(5, minmax(0, 1fr))',
'6': 'repeat(6, minmax(0, 1fr))',
},
gridRow: {
auto: 'auto',
'span-1': 'span 1 / span 1',
'span-2': 'span 2 / span 2',
'span-3': 'span 3 / span 3',
'span-4': 'span 4 / span 4',
'span-5': 'span 5 / span 5',
'span-6': 'span 6 / span 6',
},
gridRowStart: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
},
gridRowEnd: {
auto: 'auto',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
},
transformOrigin: {
center: 'center',
top: 'top',
'top-right': 'top right',
right: 'right',
'bottom-right': 'bottom right',
bottom: 'bottom',
'bottom-left': 'bottom left',
left: 'left',
'top-left': 'top left',
},
scale: {
'0': '0',
'50': '.5',
'75': '.75',
'90': '.9',
'95': '.95',
'100': '1',
'105': '1.05',
'110': '1.1',
'125': '1.25',
'150': '1.5',
},
rotate: {
'-180': '-180deg',
'-90': '-90deg',
'-45': '-45deg',
'0': '0',
'45': '45deg',
'90': '90deg',
'180': '180deg',
},
translate: (theme, { negative }) => ({
...theme('spacing'),
...negative(theme('spacing')),
'-full': '-100%',
'-1/2': '-50%',
'1/2': '50%',
full: '100%',
}),
skew: {
'-12': '-12deg',
'-6': '-6deg',
'-3': '-3deg',
'0': '0',
'3': '3deg',
'6': '6deg',
'12': '12deg',
},
transitionProperty: {
none: 'none',
all: 'all',
default: 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform',
colors: 'background-color, border-color, color, fill, stroke',
opacity: 'opacity',
shadow: 'box-shadow',
transform: 'transform',
},
transitionTimingFunction: {
linear: 'linear',
in: 'cubic-bezier(0.4, 0, 1, 1)',
out: 'cubic-bezier(0, 0, 0.2, 1)',
'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
},
transitionDuration: {
'75': '75ms',
'100': '100ms',
'150': '150ms',
'200': '200ms',
'300': '300ms',
'500': '500ms',
'700': '700ms',
'1000': '1000ms',
},
transitionDelay: {
'75': '75ms',
'100': '100ms',
'150': '150ms',
'200': '200ms',
'300': '300ms',
'500': '500ms',
'700': '700ms',
'1000': '1000ms',
},
animation: {
none: 'none',
spin: 'spin 1s linear infinite',
ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite',
pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
bounce: 'bounce 1s infinite',
},
keyframes: {
spin: {
to: { transform: 'rotate(360deg)' },
},
ping: {
'75%, 100%': { transform: 'scale(2)', opacity: '0' },
},
pulse: {
'50%': { opacity: '.5' },
},
bounce: {
'0%, 100%': {
transform: 'translateY(-25%)',
animationTimingFunction: 'cubic-bezier(0.8,0,1,1)',
},
'50%': {
transform: 'none',
animationTimingFunction: 'cubic-bezier(0,0,0.2,1)',
},
},
},
},
variants: {
accessibility: ['responsive', 'focus'],
alignContent: ['responsive'],
alignItems: ['responsive'],
alignSelf: ['responsive'],
appearance: ['responsive'],
backgroundAttachment: ['responsive'],
backgroundClip: ['responsive'],
backgroundColor: ['responsive', 'hover', 'focus', 'active', 'disabled'],
backgroundImage: ['responsive'],
gradientColorStops: ['responsive', 'hover', 'focus'],
backgroundOpacity: ['responsive', 'hover', 'focus'],
backgroundPosition: ['responsive'],
backgroundRepeat: ['responsive'],
backgroundSize: ['responsive'],
borderCollapse: ['responsive'],
borderColor: ['responsive', 'hover', 'focus'],
borderOpacity: ['responsive', 'hover', 'focus'],
borderRadius: ['responsive'],
borderStyle: ['responsive'],
borderWidth: ['responsive'],
boxShadow: ['responsive', 'hover', 'focus', 'active', 'disabled'],
boxSizing: ['responsive'],
container: ['responsive'],
cursor: ['responsive'],
display: ['responsive'],
divideColor: ['responsive'],
divideOpacity: ['responsive'],
divideStyle: ['responsive'],
divideWidth: ['responsive'],
fill: ['responsive'],
flex: ['responsive'],
flexDirection: ['responsive'],
flexGrow: ['responsive'],
flexShrink: ['responsive'],
flexWrap: ['responsive'],
float: ['responsive'],
clear: ['responsive'],
fontFamily: ['responsive'],
fontSize: ['responsive'],
fontSmoothing: ['responsive'],
fontVariantNumeric: ['responsive'],
fontStyle: ['responsive'],
fontWeight: ['responsive', 'hover', 'focus'],
height: ['responsive'],
inset: ['responsive'],
justifyContent: ['responsive'],
justifyItems: ['responsive'],
justifySelf: ['responsive'],
letterSpacing: ['responsive'],
lineHeight: ['responsive'],
listStylePosition: ['responsive'],
listStyleType: ['responsive'],
margin: ['responsive'],
maxHeight: ['responsive'],
maxWidth: ['responsive'],
minHeight: ['responsive'],
minWidth: ['responsive'],
objectFit: ['responsive'],
objectPosition: ['responsive'],
opacity: ['responsive', 'hover', 'focus', 'disabled'],
order: ['responsive'],
outline: ['responsive', 'focus'],
overflow: ['responsive'],
overscrollBehavior: ['responsive'],
padding: ['responsive'],
placeContent: ['responsive'],
placeItems: ['responsive'],
placeSelf: ['responsive'],
placeholderColor: ['responsive', 'focus'],
placeholderOpacity: ['responsive', 'focus'],
pointerEvents: ['responsive'],
position: ['responsive'],
resize: ['responsive'],
space: ['responsive'],
stroke: ['responsive'],
strokeWidth: ['responsive'],
tableLayout: ['responsive'],
textAlign: ['responsive'],
textColor: ['responsive', 'hover', 'focus'],
textOpacity: ['responsive', 'hover', 'focus'],
textDecoration: ['responsive', 'hover', 'focus'],
textTransform: ['responsive'],
userSelect: ['responsive'],
verticalAlign: ['responsive'],
visibility: ['responsive'],
whitespace: ['responsive'],
width: ['responsive'],
wordBreak: ['responsive'],
zIndex: ['responsive'],
gap: ['responsive'],
gridAutoFlow: ['responsive'],
gridTemplateColumns: ['responsive'],
gridColumn: ['responsive'],
gridColumnStart: ['responsive'],
gridColumnEnd: ['responsive'],
gridTemplateRows: ['responsive'],
gridRow: ['responsive'],
gridRowStart: ['responsive'],
gridRowEnd: ['responsive'],
transform: ['responsive'],
transformOrigin: ['responsive'],
scale: ['responsive', 'hover', 'focus'],
rotate: ['responsive', 'hover', 'focus'],
translate: ['responsive', 'hover', 'focus', 'active', 'disabled'],
skew: ['responsive', 'hover', 'focus'],
transitionProperty: ['responsive'],
transitionTimingFunction: ['responsive'],
transitionDuration: ['responsive'],
transitionDelay: ['responsive'],
animation: ['responsive'],
},
corePlugins: {},
plugins: [],
}

+ 670
- 16
yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save