ESLINT is holy crap

This commit is contained in:
doryan04 2024-02-01 01:58:19 +04:00
parent 7cdc259fb3
commit 26584d5482
151 changed files with 26811 additions and 47 deletions

95
.eslintrc.js Normal file
View File

@ -0,0 +1,95 @@
const prettierConfig = require('./.prettierrc.js');
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:prettier/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'next/core-web-vitals',
],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: 'module',
},
plugins: ['react'],
rules: {
// Possible errors
'no-console': 'warn',
// Best practices
'dot-notation': 'error',
'no-else-return': 'error',
'no-floating-decimal': 'error',
'no-sequences': 'error',
// Stylistic
'array-bracket-spacing': 'error',
'computed-property-spacing': ['error', 'never'],
curly: 'error',
'no-lonely-if': 'error',
'no-unneeded-ternary': 'error',
'one-var-declaration-per-line': 'error',
quotes: [
'error',
'single',
{
allowTemplateLiterals: false,
avoidEscape: true,
},
],
// ES6
'array-callback-return': 'off',
'prefer-const': 'error',
// Imports
'import/prefer-default-export': 'off',
'sort-imports': [
'error',
{
ignoreCase: true,
ignoreDeclarationSort: true,
},
],
'no-unused-expressions': 'off',
'no-prototype-builtins': 'off',
// REACT
'react/jsx-uses-react': 'off',
'react/react-in-jsx-scope': 'off',
'jsx-a11y/href-no-hash': [0],
'react/display-name': 0,
'react/no-deprecated': 'error',
'react/no-unsafe': [
'error',
{
checkAliases: true,
},
],
'react/jsx-sort-props': [
'error',
{
ignoreCase: true,
},
],
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 0,
// Prettier
// eslint looks for the prettier config at the top level of the package/app
// but the config lives in the `config/` directory. Passing the config here
// to get around this.
'prettier/prettier': ['error', prettierConfig],
},
settings: {
react: {
version: 'detect',
},
},
};

5
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EslintConfiguration">
<option name="fix-on-save" value="true" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/google-material-you-ui.iml" filepath="$PROJECT_DIR$/.idea/google-material-you-ui.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

7
.prettierrc.js Normal file
View File

@ -0,0 +1,7 @@
module.exports = {
arrowParens: 'avoid',
singleQuote: true,
trailingComma: 'all',
tabWidth: 4,
endOfLine: 'auto',
};

View File

@ -1,25 +1,49 @@
# Next.js + Turbopack
# React/Next.js Material You UI kit (pre-alpha)
This example allows you to get started with `next dev --turbo` quicky.
This repository is including and will be including components, enumerates in table:
## Deploy your own
- [x] Buttons
- [x] Default
- [x] Icon
- [x] FAB
- [x] Radio
- [ ] Segmented
- [x] Checkbox
- [x] Text fields
- [x] Switches
- [ ] Chips
- [x] Icon
- [x] Ripple Effect
- [x] Dividers
- [x] Badges
- [ ] Select field
- [ ] Bottom sheets
- [ ] Cards
- [ ] Menus
- [ ] Navigation
- [ ] Bars
- [ ] Drawer
- [ ] Rail
- [ ] Sliders
- [ ] Snackbar
- [ ] Tabs
- [ ] Bottom sheets
- [ ] Bottom app bars
~~and including preview page for test.~~
Preview page on stage WIP.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-turbopack&project-name=with-turbopack&repository-name=with-turbopack)
# Status
## How to use
Nowadays, this UI kit have base kinds of components and you could make everything. For example - general forms (without select field and etc.)
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:
# Roadmap
```bash
npx create-next-app --example with-turbopack with-turbopack-app
```
1. Full implementation components;
2. Release NPM package;
3. Custom theaming.
```bash
yarn create next-app --example with-turbopack with-turbopack-app
```
## Did you find the bug? Make sure to [leave an issue](https://github.com/doryan04/DSS/issues/new) in case of any problems.
```bash
pnpm create next-app --example with-turbopack with-turbopack-app
```
## If you want help to the project, please, advise your idea in Pull request and don't forget [send issue](https://github.com/doryan04/DSS/issues/new)
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
### Check out actual news on Telegram. [https://t.me/doryanProjects](https://t.me/doryanProjects)

136
app/components/badges.tsx Normal file
View File

@ -0,0 +1,136 @@
import React from 'react';
import { Badge } from '../../src/primitive-components/badge/badge';
import { Divider } from '../../src/primitive-components/divider/divider';
export default function Badges() {
return (
<div
className={'m3 m3-wrapper'}
style={{ display: 'flex', flexDirection: 'row' }}
>
<div>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '0.5em',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge />
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge disableValue />
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge disableValue>3487</Badge>
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge>5</Badge>
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge>32</Badge>
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge>322342</Badge>
</div>
</div>
</div>
{/*<Divider orientation={"vertical"} variant={"full-width"}/>*/}
{/*<div>*/}
{/* <div style={{*/}
{/* display: "flex",*/}
{/* flexDirection: "column",*/}
{/* gap: "0.5em",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <div style={{*/}
{/* width: "24px",*/}
{/* aspectRatio: 1,*/}
{/* display: "flex",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <Badge/>*/}
{/* </div>*/}
{/* <Divider variant={"inset"}/>*/}
{/* <div style={{*/}
{/* width: "24px",*/}
{/* aspectRatio: 1,*/}
{/* display: "flex",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <Badge>5</Badge>*/}
{/* </div>*/}
{/* <Divider/>*/}
{/* <div style={{*/}
{/* width: "24px",*/}
{/* aspectRatio: 1,*/}
{/* display: "flex",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <Badge>32</Badge>*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
</div>
);
}

View File

@ -0,0 +1,71 @@
'use client';
import React, { useCallback, useState } from 'react';
import { Button } from '../../src/primitive-components/material-you-components';
export default function Buttons() {
const [state, setState] = useState(1);
const callback = useCallback(
() => setState(prevState => prevState + 1),
[state],
);
return (
<div className={'m3 m3-wrapper'}>
<h1> Buttons </h1>
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div>
<h2> Default buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '150px',
gap: '0.5em',
}}
>
<Button
centralRipple
onClick={callback}
variant={'filled'}
>
Label + {state}
</Button>
<Button variant={'outlined'}>Label</Button>
<Button variant={'tonal'}>Label</Button>
<Button variant={'elevated'}>Label</Button>
<Button variant={'text'}>Label</Button>
</div>
</div>
<div>
<h2> Buttons with icon </h2>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '150px',
gap: '0.5em',
}}
>
<Button icon={'add'} variant={'filled'}>
Label
</Button>
<Button icon={'add'} variant={'outlined'}>
Label
</Button>
<Button icon={'add'} variant={'tonal'}>
Label
</Button>
<Button icon={'add'} variant={'elevated'}>
Label
</Button>
<Button icon={'add'} variant={'text'}>
Label
</Button>
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,90 @@
'use client';
import React from 'react';
import {
Button,
Checkbox,
} from '../../src/primitive-components/material-you-components';
export default function Checkboxes() {
return (
<div className={'m3 m3-wrapper'}>
<h1> Checkboxes </h1>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '5em',
justifyContent: 'center',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Checkbox centralRipple />
<Checkbox defaultChecked />
<Checkbox indeterminate={true} />
</div>
</div>
<div>
<h2> Disabled </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Checkbox disabled />
<Checkbox defaultChecked disabled />
</div>
</div>
</div>
<div>
<h2> Errored </h2>
<form
style={{
display: 'flex',
gap: '2em',
flexDirection: 'column',
}}
>
<div
style={{
display: 'flex',
gap: '2em',
flexDirection: 'row',
}}
>
<Checkbox required />
<Checkbox defaultChecked required />
<Checkbox indeterminate={true} required />
</div>
<div
style={{
display: 'flex',
gap: '2em',
flexDirection: 'row',
}}
>
<Checkbox className={'m3-error'} required />
<Checkbox
className={'m3-error'}
defaultChecked
required
/>
<Checkbox
className={'m3-error'}
indeterminate={true}
required
/>
</div>
<Button type={'submit'}>Send</Button>
</form>
</div>
</div>
</div>
);
}

221
app/components/fabs.tsx Normal file
View File

@ -0,0 +1,221 @@
import React from 'react';
import { FAB } from '../../src/primitive-components/material-you-components';
export default function Fabs() {
return (
<div className={'m3 m3-wrapper'}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div>
<h1> FABs with elevation</h1>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Small </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB
centralRipple
elevated
icon={'edit'}
size={'small'}
/>
<FAB
elevated
icon={'edit'}
size={'small'}
variant={'primary'}
/>
<FAB
elevated
icon={'edit'}
size={'small'}
variant={'secondary'}
/>
<FAB
elevated
icon={'edit'}
size={'small'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB elevated icon={'edit'} />
<FAB
elevated
icon={'edit'}
variant={'primary'}
/>
<FAB
elevated
icon={'edit'}
variant={'secondary'}
/>
<FAB
elevated
icon={'edit'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Large </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB elevated icon={'edit'} size={'large'} />
<FAB
elevated
icon={'edit'}
size={'large'}
variant={'primary'}
/>
<FAB
elevated
icon={'edit'}
size={'large'}
variant={'secondary'}
/>
<FAB
elevated
icon={'edit'}
size={'large'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Extended </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB elevated icon={'edit'} size={'extended'}>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
elevated
icon={'edit'}
size={'extended'}
variant={'primary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
elevated
icon={'edit'}
size={'extended'}
variant={'secondary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
elevated
icon={'edit'}
size={'extended'}
variant={'tertiary'}
>
<span className={'label-large'}>Label</span>
</FAB>
</div>
</div>
</div>
</div>
<div>
<h1> FABs without elevation</h1>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Small </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} size={'small'} />
<FAB
icon={'edit'}
size={'small'}
variant={'primary'}
/>
<FAB
icon={'edit'}
size={'small'}
variant={'secondary'}
/>
<FAB
icon={'edit'}
size={'small'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} />
<FAB icon={'edit'} variant={'primary'} />
<FAB icon={'edit'} variant={'secondary'} />
<FAB icon={'edit'} variant={'tertiary'} />
</div>
</div>
<div>
<h2> Large </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} size={'large'} />
<FAB
icon={'edit'}
size={'large'}
variant={'primary'}
/>
<FAB
icon={'edit'}
size={'large'}
variant={'secondary'}
/>
<FAB
icon={'edit'}
size={'large'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Extended </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} size={'extended'}>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
icon={'edit'}
size={'extended'}
variant={'primary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
icon={'edit'}
size={'extended'}
variant={'secondary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
icon={'edit'}
size={'extended'}
variant={'tertiary'}
>
<span className={'label-large'}>Label</span>
</FAB>
</div>
</div>
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,190 @@
'use client';
import React from 'react';
import { IconButton } from '../../src/primitive-components/material-you-components';
function IconButtons() {
return (
<div className={'m3 m3-wrapper'}>
<h1> Icon buttons </h1>
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div>
<h2> Default buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton centralRipple icon={'settings'} />
<IconButton icon={'settings'} variant={'filled'} />
<IconButton icon={'settings'} variant={'tonal'} />
<IconButton icon={'settings'} variant={'outlined'} />
</div>
<h2> Disabled default buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton disabled icon={'settings'} />
<IconButton
disabled
icon={'settings'}
variant={'filled'}
/>
<IconButton
disabled
icon={'settings'}
variant={'tonal'}
/>
<IconButton
disabled
icon={'settings'}
variant={'outlined'}
/>
</div>
</div>
<div>
<h2> Toggle buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
/>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'filled'}
/>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'tonal'}
/>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'outlined'}
/>
</div>
<h2> Disabled toggle buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
/>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'filled'}
/>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'tonal'}
/>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'outlined'}
/>
</div>
<h2> Disabled selected toggle buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
/>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'filled'}
/>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'tonal'}
/>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'outlined'}
/>
</div>
</div>
</div>
</div>
);
}
export default IconButtons;

34
app/components/radios.tsx Normal file
View File

@ -0,0 +1,34 @@
import React from 'react';
import { Radio } from '../../src/primitive-components/material-you-components';
export default function Radios() {
return (
<div className={'m3 m3-wrapper'}>
<h1> Radio </h1>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '5em',
justifyContent: 'center',
}}
>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Radio centralRipple />
<Radio defaultChecked />
</div>
</div>
<div>
<h2> Disabled </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Radio disabled />
<Radio defaultChecked disabled />
</div>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,83 @@
'use client';
import React from 'react';
import { Switch } from '../../src/primitive-components/material-you-components';
export default function Switches() {
return (
<div
className={'m3 m3-wrapper'}
style={{ display: 'flex', flexDirection: 'column', gap: '1.5em' }}
>
<h1> Switches </h1>
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2 style={{ margin: 0 }}> Without icon </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<Switch />
<Switch defaultChecked />
</div>
<div>
<h2> Disabled </h2>
<Switch disabled />
<Switch defaultChecked disabled />
</div>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2 style={{ margin: 0 }}> With icon (both)</h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<Switch icon />
<Switch defaultChecked icon />
</div>
<div>
<h2> Disabled </h2>
<Switch disabled icon />
<Switch defaultChecked disabled icon />
</div>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2 style={{ margin: 0 }}> With icon (selected)</h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<Switch icon selected />
<Switch defaultChecked icon selected />
</div>
<div>
<h2> Disabled </h2>
<Switch disabled icon selected />
<Switch defaultChecked disabled icon selected />
</div>
</div>
</div>
</div>
</div>
);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,26 @@
import '../src/styles/generics.css';
import { Metadata, Viewport } from 'next';
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
userScalable: false,
};
export default function RootLayout({
children,
children,
}: {
children: React.ReactNode;
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
return (
<html lang="en">
<body>{children}</body>
</html>
);
}

View File

@ -1,3 +1,46 @@
import { Fragment } from 'react';
import Fabs from './components/fabs';
import Badges from './components/badges';
import IconButtons from './components/icon-buttons';
import Buttons from './components/buttons';
import Switches from './components/switches';
import Checkboxes from './components/checkboxes';
import Radios from './components/radios';
import { TextFields } from './components/text-fields';
export default function Page() {
return <h1>Hello, Next.js!</h1>;
return (
<Fragment>
<div
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
overflowX: 'auto',
gap: '0em',
}}
>
<h1>Google Material You UI kit</h1>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '0.5em',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Buttons />
<IconButtons />
<Switches />
<Checkboxes />
<Radios />
<TextFields />
<Fabs />
<Badges />
</div>
</div>
</Fragment>
);
}

6554
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,17 +3,39 @@
"scripts": {
"dev": "next dev --turbo",
"build": "next build",
"start": "next start"
"start": "next start",
"lint": "lint",
"compile": "tsc",
"prepare": "npm run compile",
"pretest": "npm run compile",
"posttest": "npm run lint"
},
"dependencies": {
"eslint-plugin-prettier": "^5.1.3",
"install": "^0.13.0",
"next": "latest",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "20.8.10",
"@next/eslint-plugin-next": "^14.1.0",
"@types/node": "20.8.2",
"@types/react": "18.2.33",
"@types/react-dom": "18.2.14",
"typescript": "^5.2.2"
"@typescript-eslint/eslint-plugin": "^6.20.0",
"eslint": "^8.56.0",
"eslint-config-next": "^14.1.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard-with-typescript": "^43.0.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"i": "^0.3.7",
"npm": "^10.4.0",
"prettier": "3.2.4",
"typescript": "~5.2.0"
}
}

View File

@ -0,0 +1,37 @@
import { BadgeProps } from './badges.types';
import { bool, number, string } from 'prop-types';
import React, { forwardRef } from 'react';
const Badge = forwardRef<SVGSVGElement, BadgeProps>(function Badge(
{ disableValue = false, ...props },
ref,
) {
const digitLength = props.children
? 16 + (props.children.length - 1) * 6
: 6,
disableValueClassName =
disableValue || (!props.children ?? true) ? 'disable-value' : '';
return (
<svg
{...props}
className={`m3 m3-badge ${'' ?? props.className}${disableValueClassName}`.trimEnd()}
ref={ref}
width={`${digitLength}px`}
>
{props.children && (
<text x={'50%'} y={'50%'}>
{props.children}
</text>
)}
</svg>
);
});
Badge.propTypes = {
children: number,
className: string,
disableValue: bool,
};
export { Badge };

View File

@ -0,0 +1,5 @@
import { PropsWithChildren } from 'react';
export interface BadgeProps extends PropsWithChildren<any> {
disableValue?: boolean;
}

View File

@ -0,0 +1,48 @@
'use client';
import { RippleArea } from '../ripple/ripple-area';
import { IRippleProps } from '../ripple/ripple.types';
import useRippleEffect from '../ripple/hooks/useRippleEffect';
import React, {
forwardRef,
PropsWithChildren,
useId,
useRef,
useState,
} from 'react';
const ButtonLayout = forwardRef<
HTMLButtonElement,
PropsWithChildren<any> & IRippleProps
>(function ButtonBase({ centralRipple = false, ...props }, ref) {
const [isActive, setIsActive] = useState<boolean>(false),
ripplesRef = useRef(null),
buttonId = useId(),
events = useRippleEffect(ripplesRef, setIsActive);
const { variant, disabled, className } = props;
const classes = className
? `m3 ${className} ${variant}${isActive ? ' is-active' : ''}`
: `m3 ${variant}${isActive ? ' is-active' : ''}`;
return (
<button
{...props}
{...events}
className={classes}
disabled={disabled}
id={buttonId}
ref={ref}
>
{props.children}
<RippleArea
callback={setIsActive}
central={centralRipple}
ref={ripplesRef}
/>
</button>
);
});
export { ButtonLayout };

View File

@ -0,0 +1,25 @@
import { PropsWithChildren } from 'react';
type ToggleButtonType = {
selected: string;
unselected: string;
};
export interface ButtonMainProps extends PropsWithChildren<any> {
disabled?: boolean;
variant?: 'filled' | 'outlined' | 'elevated' | 'tonal' | 'text';
}
export interface FABMainProps extends PropsWithChildren<any> {
icon: string;
disabled?: boolean;
size?: 'small' | 'default' | 'large' | 'extended';
variant?: 'surface' | 'primary' | 'secondary' | 'tertiary';
}
export interface IconButtonMainProps extends PropsWithChildren<any> {
icon: string;
toggled?: false | ToggleButtonType;
disabled?: boolean;
variant?: 'default' | 'filled' | 'tonal' | 'outlined';
}

View File

@ -0,0 +1,33 @@
'use client';
import { forwardRef } from 'react';
import { Icon } from '../material-you-components';
import { IRippleProps } from '../ripple/ripple.types';
import { ButtonLayout } from '../button-layout/button-layout';
import { ButtonMainProps } from '../button-layout/button.types';
/**
* Button component
** description
*/
export const Button = forwardRef<
HTMLButtonElement,
ButtonMainProps & IRippleProps
>(
(
{ centralRipple = false, variant, disabled = false, icon, ...props },
ref,
) => (
<ButtonLayout
{...props}
centralRipple={centralRipple}
disabled={disabled}
ref={ref}
variant={variant ? variant : 'filled'}
>
{icon ? <Icon iconSize={20}>{icon}</Icon> : <></>}
<span className={'label-large'}>{props.children}</span>
</ButtonLayout>
),
);

View File

@ -0,0 +1,38 @@
'use client';
import React, {
forwardRef,
useEffect,
useImperativeHandle,
useRef,
} from 'react';
import { CheckboxLayoutProps } from './checkbox-layout.types';
export const CheckBoxLayout = forwardRef(function CheckBoxBase(
{ indeterminate, typeInput, type, ...props }: CheckboxLayoutProps,
ref,
): JSX.Element {
const checkboxRef = useRef<any>(null);
useEffect(() => {
checkboxRef.current.indeterminate = indeterminate === true;
}, []);
useImperativeHandle(ref, () => checkboxRef.current);
const classesType = typeInput || type;
const classes =
props.className !== undefined
? `m3 m3-${type} ${props.className}`
: `m3 m3-${classesType}`;
return (
<input
ref={checkboxRef}
{...props}
className={classes.trimEnd()}
type={type}
/>
);
});

View File

@ -0,0 +1,7 @@
import { PropsWithChildren } from 'react';
export interface CheckboxLayoutProps extends PropsWithChildren<any> {
indeterminate?: boolean;
typeInput?: string;
type?: string;
}

View File

@ -0,0 +1,59 @@
'use client';
import { RippleArea } from '../ripple/ripple-area';
import { IRippleProps } from '../ripple/ripple.types';
import useRippleEffect from '../ripple/hooks/useRippleEffect';
import { CheckBoxLayout } from '../checkbox-layout/check-box-layout';
import {
forwardRef,
PropsWithChildren,
useEffect,
useImperativeHandle,
useRef,
useState,
} from 'react';
/**
* Checkbox component
** description
*/
export const Checkbox = forwardRef<
HTMLInputElement,
PropsWithChildren<any> & IRippleProps
>(({ centralRipple, ...props }, ref) => {
const [isActive, setIsActive] = useState<boolean>(false),
[checked, setChecked] = useState<boolean>(props.checked ?? false),
ripplesRef = useRef(null),
checkboxRef = useRef(null),
events = useRippleEffect(ripplesRef, setIsActive);
const classes =
`m3 m3-checkbox-label ${isActive === true ? 'visible' : ''}`.trimEnd();
const indeterminate = (props.indeterminate === true).toString();
useImperativeHandle(ref, () => checkboxRef.current);
useEffect(() => {
setChecked(!checked);
}, [checkboxRef.current?.checked]);
return (