Skip to content

Commit

Permalink
Feature/site detail page (lucide-icons#99)
Browse files Browse the repository at this point in the history
* site: pull data from "icons" dir

* site: display icons

* site: remove redundant code

* site: colour mode support

* site: header

* site: order imports

* site: search

* site: add toast when copying icon

* site: styling

* site: hero

* fix: disable theme toggle transitions

* feat: Use Yarn Workspaces

* refactor: Update site deploy scripts

* refactor: Remove dark mode for now

* feat: Add site title

* refactor: Fix warning and format

* feat: Add dark mode back 👀

* feat: Escape key to reset query

* Fix by aelfric

* Add Github link

* Fix lucide-icons#40

* Add site overlay

* sort categories

* Add detail page

* Add first categories

* add box

* move site to root directory

* fix merge issues

* Fix routing issues

* Fix icon overlay

* Add copy and download icon

* Fix style issues

* Add text

* update chakra UI

* remove import

* update dependecies

* add lucide react

* Fix bugs

* delete stats files

* update charkra version

Co-authored-by: John Letey <[email protected]>
Co-authored-by: appmachine <[email protected]>
  • Loading branch information
3 people authored Oct 26, 2020
1 parent 2c38fac commit 5c96b8d
Show file tree
Hide file tree
Showing 22 changed files with 1,228 additions and 713 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json → .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
module.exports = {
"env": {
"browser": true,
"node": true
Expand Down
19 changes: 19 additions & 0 deletions categories.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"arrows": [],
"brands": [],
"code": [],
"connectivity": ["airplay"],
"cursors": [],
"development": [],
"devices": ["alarm-clock"],
"file-system": [],
"layout": [],
"maths": ["activity"],
"multimedia": [],
"notifications": ["alert-circle", "alert-octagon", "alert-triangle"],
"nature": [],
"shopping": [],
"shapes": [],
"sports": [],
"text-edit": ["align-center","align-right","align-left","align-justify" ]
}
3 changes: 0 additions & 3 deletions site/.babelrc

This file was deleted.

4 changes: 4 additions & 0 deletions site/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const { builtinModules } = require('module')
const rootConfig = require('../.eslintrc.js')

module.exports = rootConfig;
3 changes: 3 additions & 0 deletions site/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ['next/babel'],
};
2 changes: 1 addition & 1 deletion site/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module.exports = {
testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/../../node_modules/babel-jest',
'^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest',
},
};
11 changes: 6 additions & 5 deletions site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
"test": "jest"
},
"dependencies": {
"@chakra-ui/core": "^0.8.0",
"@emotion/core": "^10.0.28",
"@emotion/styled": "^10.0.27",
"@chakra-ui/core": "next",
"downloadjs": "^1.4.7",
"emotion-theming": "^10.0.27",
"framer-motion": "^2.9.4",
"fuse.js": "^6.0.4",
"jszip": "^3.4.0",
"lodash": "^4.17.20",
"lucide-react": "^0.1.2-beta.1",
"next": "^9.5.4",
"react": "^16.13.1",
"react-dom": "^16.13.1"
"react-dom": "^16.13.1",
"react-spring": "^8.0.27"
},
"devDependencies": {
"@testing-library/dom": "^7.24.4",
Expand Down
19 changes: 19 additions & 0 deletions site/src/assets/styling.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.icon-large svg {
width: 100%;
height: 100%;
position: relative;
z-index: 1;
}

.icon-grid {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}

body {
min-height: 100%;
padding-bottom: 80px;
}
62 changes: 62 additions & 0 deletions site/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
Button,
Flex,
Stack,
Text,
Link,
} from "@chakra-ui/core";
import download from "downloadjs";
import JSZip from "jszip";
import { Download, GitHub } from 'lucide-react';
import theme from "../lib/theme";

function generateZip(icons) {
const zip = new JSZip();
Object.values(icons).forEach((icon) =>
// @ts-ignore
zip.file(`${icon.name}.svg`, icon.src)
);
return zip.generateAsync({ type: 'blob' });
}

const Header = ({ data }) => {
const downloadAllIcons = async () => {

const zip = await generateZip(data);
download(zip, 'feather.zip');
};

const repositoryUrl = 'https://github.com/lucide-icons/lucide';

return (
<Flex direction="column" align="center" justify="center">
<Text fontSize="3xl" as="b" mb="4" textAlign="center">
Simply beautiful open source icons, community-sourced
</Text>
<Text fontSize="lg" as="p" textAlign="center" mb="8">
An open-source icon library, a fork of <Link href="https://github.com/feathericons/feather" isExternal>Feather Icons</Link>. <br/>We're expanding the icon set as much as possible while keeping it nice-looking - <Link href={repositoryUrl} isExternal>join us</Link>!
</Text>
<Stack isInline marginTop={3} marginBottom={10}>
<Button
leftIcon={<Download/>}
size="lg"
onClick={downloadAllIcons}
>
Download all
</Button>
<Button
as="a"
leftIcon={<GitHub/>}
size="lg"
href={repositoryUrl}
target="__blank"
onClick={downloadAllIcons}
>
Github
</Button>
</Stack>
</Flex>
)
};

export default Header;
192 changes: 192 additions & 0 deletions site/src/components/IconDetailOverlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { useSpring, animated } from "react-spring";
import { Box, Text, IconButton, useColorMode, Flex, ButtonGroup, Button, useToast } from "@chakra-ui/core";
import theme from "../lib/theme";
import download from 'downloadjs';
import copy from "copy-to-clipboard";
import { X as Close } from 'lucide-react';

const IconDetailOverlay = ({ isOpen = true, onClose, icon }) => {
const toast = useToast();
const { colorMode } = useColorMode();
const { tags = [], name } = icon;

const { transform, opacity } = useSpring({
opacity: isOpen ? 1 : 0,
transform: `translateY(${isOpen ? -120 : 0}%)`,
config: { mass: 5, tension: 500, friction: 80 },
});

const handleClose = () => {
onClose();
};

const panelStyling = {
transform: transform.interpolate(t => t),
opacity: opacity.interpolate(o => o),
width: "100%",
willChange: "transform"
}

const iconStyling = (isLight) => ({
height: "25vw",
width: "25vw",
minHeight: "160px",
minWidth: "160px",
maxHeight: "240px",
maxWidth: "240px",
color: (isLight ? theme.colors.gray[800] : theme.colors.white),
});

const downloadIcon = ({src, name}) => download(src, `${name}.svg`, 'image/svg+xml');

const copyIcon = ({src, name}) => {
copy(src);
toast({
title: "Copied!",
description: `Icon "${name}" copied to clipboard.`,
status: "success",
duration: 1500,
});
}

const donwloadPNG = ({src, name}) => {
const canvas = document.createElement('canvas');
canvas.width = 24;
canvas.height = 24;
const ctx = canvas.getContext("2d");

const image = new Image();
image.src = `data:image/svg+xml;base64,${btoa(src)}`;
image.onload = function() {
ctx.drawImage(image, 0, 0);

const link = document.createElement('a');
link.download = `${name}.png`;
link.href = canvas.toDataURL('image/png')
link.click();
}
}

return (
<Box
position="fixed"
bottom={0}
zIndex={2}
width="100%"
left={0}
height={0}
key={name}
>
<Flex
alignItems="center"
justifyContent="space-between"
pt={4}
pb={4}
maxW="850px"
margin="0 auto"
w="full"
px={8}
>
<animated.div
style={panelStyling}
>
<Box
borderWidth="1px"
rounded="lg"
width="full"
boxShadow={theme.shadows.xl}
position="relative"
bg={
colorMode == "light"
? theme.colors.white
: theme.colors.gray[700]
}
padding={8}
>
<IconButton
size="sm"
aria-label="Close overlay"
variant="ghost"
color="current"
ml="3"
position="absolute"
top={4}
right={4}
onClick={handleClose}
icon={<Close />}
/>
<Flex direction={['column', 'row']} alignItems={['center', 'flex-start']}>
<Flex>
<Box
borderWidth="1px"
rounded="md"
position="relative"
bg={
colorMode == "light"
? theme.colors.whiteAlpha[800]
: theme.colors.blackAlpha[500]
}
padding={0}
>
<div
dangerouslySetInnerHTML={{ __html: icon.src }}
style={iconStyling(colorMode == "light")}
className="icon-large"
/>

<svg className="icon-grid" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke={colorMode == "light" ? '#E2E8F0' : theme.colors.gray[600]} strokeWidth="0.1" xmlns="http://www.w3.org/2000/svg">
{ Array.from({ length:23 }, (_, i) => (
<g key={`grid-${i}`}>
<line key={`horizontal-${i}`} x1={0} y1={i + 1} x2={24} y2={i + 1} />
<line key={`vertical-${i}`} x1={i + 1} y1={0} x2={i + 1} y2={24} />
</g>
)) }
</svg>
</Box>
</Flex>
<Flex marginLeft={[0, 8]}>
<Box>
<Text fontSize="3xl" style={{ cursor: "pointer" }} mb={1}>
{icon.name}
</Text>
<Box mb={4}>
{ tags?.length ? (
<Text
fontSize="xl"
fontWeight="bold"
color={
colorMode === "light"
? 'gray.600'
: 'gray.500'
}
>
{ tags.join(' • ') }
</Text>
) : ''}

{/* <Button size="sm" fontSize="md" variant="ghost" onClick={() => downloadIcon(icon)}>
Edit Tags
</Button> */}
</Box>
<ButtonGroup spacing={4}>
<Button variant="solid" onClick={() => downloadIcon(icon)} mb={1}>
Download SVG
</Button>
<Button variant="solid" onClick={() => copyIcon(icon)} mb={1}>
Copy SVG
</Button>
<Button variant="solid" onClick={() => donwloadPNG(icon)} mb={1}>
Download PNG
</Button>
</ButtonGroup>
</Box>
</Flex>
</Flex>
</Box>
</animated.div>
</Flex>
</Box>
);
};

export default IconDetailOverlay;
Loading

0 comments on commit 5c96b8d

Please sign in to comment.