Skip to content

Commit

Permalink
feat: polish UI, responsive
Browse files Browse the repository at this point in the history
fixes #6
  • Loading branch information
apvarun committed Oct 26, 2023
1 parent 50b5c65 commit 3910e5e
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 75 deletions.
18 changes: 11 additions & 7 deletions app/src/components/Categories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ import ClassnameInfo from '../../../src/types/classnameInfo';
import Category from './Category';

export default function Categories({ data }: { data: ClassnameInfo[] }) {
const [groups, setGroups] = useState<Record<string, any>>({});
const [groups, setGroups] = useState<Record<string, ClassnameInfo[]>>({});

useEffect(() => {
let newGroups: Record<string, any> = {};
let newGroups: Record<string, ClassnameInfo[]> = {};

data.forEach(item => {
if (item.category === 'unknown' || item.category === 'variable') {
data.forEach((item) => {
if (item.category === 'Unknown' || item.category === 'Variable') {
return;
}

if (newGroups[item.category]) {
newGroups[item.category].push(item);
if (
!newGroups[item.category].find((exItem) => exItem.name === item.name)
) {
newGroups[item.category].push(item);
}
} else {
newGroups[item.category] = [item];
}
Expand All @@ -29,9 +33,9 @@ export default function Categories({ data }: { data: ClassnameInfo[] }) {
<h2 className="mb-4 text-2xl font-medium">
Class names based on categories
</h2>
<div className="grid grid-cols-3 gap-4">
<div className="grid md:grid-cols-3 gap-4 px-4">
{Object.entries(groups).map(([groupName, items]) => (
<Category name={groupName} items={items} />
<Category key={groupName} name={groupName} items={items} />
))}
</div>
</div>
Expand Down
13 changes: 9 additions & 4 deletions app/src/components/Category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ export default function Category({
items: ClassnameInfo[];
}) {
return (
<div className="p-4 rounded bg-gray-100">
<div className="text-xl font-semibold mb-2">{name}</div>
<div className="rounded-lg border bg-card text-card-foreground shadow-sm px-6 py-4 group hover:shadow-md transition-shadow">
<h2 className="mb-4 text-lg font-bold leading-none tracking-tight">
{name}
</h2>
<div className="flex flex-wrap gap-2">
{items.map(item => (
<span className="px-2 py-0.5 bg-gray-600 rounded text-white">
{items.map((item) => (
<span
key={item.name}
className="rounded-full px-2.5 py-0.5 text-white text-md font-semibold bg-black/60 group-hover:bg-black/80 transition-colors cursor-default"
>
{item.name.replaceAll('\\', '')}
</span>
))}
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/Colors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ClassnameInfo from '../../../src/types/classnameInfo'
export const Colors = ({ data }: { data: ClassnameInfo[] }) => {

const colors = useMemo(() => {
const textAndBg = data.filter(item => item.category === 'text' || item.category === 'background')
const textAndBg = data.filter(item => item.category === 'Text' || item.category === 'Background')
const allTags = textAndBg.map(item => item.name);

const colorTags = allTags.filter(tag => {
Expand All @@ -24,8 +24,8 @@ export const Colors = ({ data }: { data: ClassnameInfo[] }) => {
<h2 className='mb-4 text-2xl font-medium'>
Colors
</h2>
<div className='flex flex-wrap gap-5'>
{colors.map(color => <div className='flex flex-col items-center'>
<div className='flex flex-wrap gap-5 px-4'>
{colors.map(color => <div key={color} className='flex flex-col items-center'>
<div className={`w-16 h-16 rounded border ${color.replace('text', 'bg')}`}>&nbsp;</div>
<p>{color.replaceAll('\\', '')}</p>
</div>)}
Expand Down
11 changes: 7 additions & 4 deletions app/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import logo from '../assets/analysis-300px.png';

export default function Header() {
return (
<div className="transition duration-500 ease-in-out transform bg-white border rounded-lg flex flex-col flex-wrap p-5 mx-auto md:items-center md:flex-row justify-between">
<a href="/" className="pr-2 lg:pr-8 lg:px-6 focus:outline-none">
<div className="bg-white border border-neutral-200/60 rounded-md flex flex-col flex-wrap justify-center px-4 py-2 mx-auto md:items-center md:flex-row md:justify-between my-4">
<a
href="/"
className="pr-2 lg:pr-8 lg:px-6 focus:outline-none text-center md:text-left"
>
<div className="inline-flex items-center">
<img className="w-12 h-12 mr-2" src={logo} />
<h2 className="block p-2 text-xl transition duration-500 ease-in-out transform cursor-pointer lg:text-x lg:mr-8">
<h2 className="block p-2 text-xl cursor-pointer lg:text-x lg:mr-8">
TailwindCSS Analysis
</h2>
</div>
</a>
<a
href="https://github.com/apvarun/tailwindcss-analysis"
target="_blank"
className="w-auto px-8 py-2 my-2 text-base font-medium text-white transition duration-500 ease-in-out transform bg-gray-600 border-gray-600 rounded-md focus:shadow-outline focus:outline-none focus:ring-2 ring-offset-current ring-offset-2 hover:b-gblue-700 "
className="inline-flex items-center justify-center px-4 py-2 text-sm font-medium tracking-wide text-white transition-colors duration-200 rounded-md bg-neutral-950 hover:bg-neutral-700 focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900 focus:shadow-outline focus:outline-none"
>
GitHub
</a>
Expand Down
69 changes: 30 additions & 39 deletions app/src/components/OverviewStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,21 @@ const keyNames: { [key: string]: string } = {
};

export default function OverviewStats({ data }: { data: Metrics }) {
const secondaryStats: Array<keyof Metrics> = [
'selectorsByAttribute',
'selectorsByClass',
'selectorsById',
'selectorsByPseudo',
'selectorsByTag',
];

const tertiaryStats: Array<keyof Metrics> = ['rules', 'declarations'];

return (
<div className="my-8">
<h2 className="mb-4 text-2xl font-medium">Overall Stats</h2>
<h2 className="mb-4 text-2xl font-bold">Overall Stats</h2>

<div className="flex gap-2 mb-8">
<div className="flex flex-wrap gap-2 mb-8">
<div className="px-16 pt-4 pb-2 border-r-2 -skew-x-12">
<div className="skew-x-12 flex gap-2 items-end">
<div className="text-6xl font-extralight">{data.colors}</div>
Expand All @@ -40,46 +50,27 @@ export default function OverviewStats({ data }: { data: Metrics }) {
</div>
</div>

<div className="grid grid-cols-5 gap-4 my-2">
<div className="shadow px-8 pt-4 pb-2 rounded border">
<div className="text-6xl font-extralight">
{data.selectorsByAttribute}
<div className="grid grid-cols-2 md:grid-cols-5 gap-4 my-2">
{secondaryStats.map((stat) => (
<div
key={stat}
className="relative w-full rounded-lg border bg-white p-4 text-neutral-900 flex flex-col"
>
<div className="mb-2 text-gray-500 text-sm flex-1">
{keyNames[stat]}
</div>
<div className="text-4xl font-medium text-right">{data[stat]}</div>
</div>
<div className="mb-2 text-gray-400">
{keyNames.selectorsByAttribute}
</div>
</div>
<div className="shadow px-8 pt-4 pb-2 rounded border">
<div className="text-6xl font-extralight">
{data.selectorsByClass}
</div>
<div className="mb-2 text-gray-400">{keyNames.selectorsByClass}</div>
</div>
<div className="shadow px-8 pt-4 pb-2 rounded border">
<div className="text-6xl font-extralight">{data.selectorsById}</div>
<div className="mb-2 text-gray-400">{keyNames.selectorsById}</div>
</div>
<div className="shadow px-8 pt-4 pb-2 rounded border">
<div className="text-6xl font-extralight">
{data.selectorsByPseudo}
</div>
<div className="mb-2 text-gray-400">{keyNames.selectorsByPseudo}</div>
</div>
<div className="shadow px-8 pt-4 pb-2 rounded border">
<div className="text-6xl font-extralight">{data.selectorsByTag}</div>
<div className="mb-2 text-gray-400">{keyNames.selectorsByTag}</div>
</div>
))}
</div>

<div className="flex flex-wrap gap-10 justify-start">
<div className="px-8 pt-4 pb-2 flex gap-2 items-center">
<div className="text-gray-400">{keyNames.rules}</div>
<div className="text-xl font-bold">{data.rules}</div>
</div>
<div className="px-8 pt-4 pb-2 flex gap-2 items-center">
<div className="text-gray-400">{keyNames.declarations}</div>
<div className="text-xl font-bold">{data.declarations}</div>
</div>
<div className="flex flex-col gap-2 justify-start py-4">
{tertiaryStats.map((stat) => (
<div key={stat} className="pb-2 flex gap-2 items-center">
<div className="text-gray-400">{keyNames[stat]}</div>
<div className="text-xl font-bold">{data[stat]}</div>
</div>
))}
</div>
</div>
);
Expand Down
18 changes: 10 additions & 8 deletions app/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react'
import ReactDOM from 'react-dom'
import './assets/index.css'
import App from './App'
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

ReactDOM.render(
import './assets/index.css';

const root = createRoot(document.getElementById('root')!);

root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)
</React.StrictMode>
);
24 changes: 14 additions & 10 deletions app/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ export default function Home() {
const { data, error } = useSWR('/api/stats', fetcher);

return (
<div className="container mx-auto px-6">
<div className="container mx-auto px-4">
<Header />
{error && <p className='text-[#ff0000]'>Error Loading data. Try again.</p>}
{!data && <p className='text-green-500'>Loading data. Please wait.</p>}
{!error && data && (
<>
<OverviewStats data={data.metrics} />
<Colors data={data.categories} />
<Categories data={data.categories} />
</>
)}
<main className='px-4'>
{error && (
<p className="text-[#ff0000]">Error Loading data. Try again.</p>
)}
{!data && <p className="text-green-500">Loading data. Please wait.</p>}
{!error && data && (
<>
<OverviewStats data={data.metrics} />
<Colors data={data.categories} />
<Categories data={data.categories} />
</>
)}
</main>
</div>
);
}
6 changes: 6 additions & 0 deletions src/helpers/camelToTitleCase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const camelToTitleCase = (str: string) =>
str.replace(/([A-Z])/g, ' $1').replace(/^./, function (s) {
return s.toUpperCase();
});

export default camelToTitleCase;
3 changes: 3 additions & 0 deletions src/parse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { toJSON } from 'cssjson';
import { dynamicUtilities, staticUtilities } from '../helpers/categories';
import ClassnameInfo from '../types/classnameInfo';
import camelToTitleCase from '../helpers/camelToTitleCase';

export default function parseCSS(cssString: string) {
const json = toJSON(cssString) as Record<string, any>;
Expand Down Expand Up @@ -44,6 +45,8 @@ export default function parseCSS(cssString: string) {

info.category = info.category || 'unknown';

info.category = camelToTitleCase(info.category);

categorizedCSS.push(info as ClassnameInfo);

})
Expand Down

0 comments on commit 3910e5e

Please sign in to comment.