5bfc736b61
* add new docs * Add styling * Move files * Add active selection * improve grid overview * improve grid * Add icon detail page * Minor changes * Fix icon preview * optimize home card * Add code examples * Add gitignore * correct temp directory * Add first cusotmizer * Add customizer * fix images paths * Add reset function * Adjust category rendering * Add packages section * Some fixes * Fix vercel build icon * Small code adjustment * move file * Try this * Add code groups with syntax highlighting * Add search icon * Cleanup * update lockfile * turnoff 404 * remove docs/iconMetaData.ts * fix build * Fix build 2 * cleanup * Add icon customizer * Fix build * Add steps * Add Button menu * A lot off fixes! * cleanup * Fix build * Css fixes * Override menu icon * try this to improve preformance * minor improvements * add comment * add readme * Add title * minor fixes * Fixes sliders + removes random backticks from index * Added package list base, still WIP * Added Guide+Source buttons to package list items * Responsive support for XS screens * Map categories count * Adjust tooltip hover position * Add see in action icon * Add download options * Aligns category list items to baseline and decreases category count weight * Fixes event target error for categorylistitems * Added icon release metadata builder * Adds version badges to hero + icon detail overlay * Added contributors. Added Copy Angular. Added release info to icon page. * Centres contributor tooltip * Fixed stroke step + added reset button * Extracted reset button as a separate component for reusability * Makes HomeIconCustomizerIcons less dense * Fixes Button menu * adjust versions and contributors styling on detail page * Fix build? * Fix build 2? * Fix build 3 * Fix build 4 * Fix build 5? * Add latest gh-icon changes * Add comment * Try fetch tags to retrieve release data * try fetch all tags * Add related icons * Add stikcy search bar * Add no results components * Try to fix animation * Try optimizing for categories * Hide buggy animated icon * minor fixes * Add footer * Add contributute link in footer * Add copy name * Add 100% preview icons * remove site directory * clean up * Add redirects * Fix build? * fix redirect? * minor improvements * Fix icons preview on mobile * Small preformance improvement * Dark mode fixes for package icons * Sort related icons by similarity + somewhat better name similarity matching * Replace icon design guide images with uniform SVGs * update lockfile * Adds git clone to manually fetch the main repository for creating release metadata * Remove initial v0.0.0 from release metadata * Add extra CTA to no results behaviour * Remove tags, as they are too overused * Revert "Remove tags, as they are too overused" This reverts commit 909b7563c0c5d98d7eb6e1fa2708d20fc9ecfbf7. * Checkout icons from main * Add absoluteStrokeWidth switch * Add absolute strokewidth to home customizer * Add absolute strokewidth to copy code button * remove unused import * compare build time * improve build speed * Try new release meta data script * add fetch tags * try with branch and remote * try with url * try without ssh * Fix fetch tags in build file * Cleanup * Fix fallback * improve release data * delete relatedIcons.json, because it should be gitignored * Add icon details * Fix import * minor fixes * Try running script parallel * Revert icon details * include aliases in release meta data * Final fixes * Final fixes 2 * minor code adjustment * Fix build * test * Revert concurrent build flow * switch back to concurrent build strategy * revert icon changes * update package.json * update package.json * dedube packages --------- Co-authored-by: Karsa <karsa@karsa.org>
266 lines
7.3 KiB
TypeScript
266 lines
7.3 KiB
TypeScript
import React from 'react';
|
|
import { PathProps, Path } from './types';
|
|
import { getPaths, assert } from './utils';
|
|
|
|
const Grid = ({
|
|
radius,
|
|
fill,
|
|
...props
|
|
}: {
|
|
strokeWidth: number;
|
|
radius: number;
|
|
} & PathProps<'stroke', 'strokeWidth'>) => (
|
|
<g className="svg-preview-grid-group" strokeLinecap="butt" {...props}>
|
|
<rect
|
|
width={24 - props.strokeWidth}
|
|
height={24 - props.strokeWidth}
|
|
x={props.strokeWidth / 2}
|
|
y={props.strokeWidth / 2}
|
|
rx={radius}
|
|
fill={fill}
|
|
/>
|
|
<path
|
|
d={
|
|
props.d ||
|
|
new Array(Math.floor(24 - 1))
|
|
.fill(null)
|
|
.flatMap((_, i) => [
|
|
`M${props.strokeWidth} ${i + 1}h${24 - props.strokeWidth * 2}`,
|
|
`M${i + 1} ${props.strokeWidth}v${24 - props.strokeWidth * 2}`,
|
|
])
|
|
.join('')
|
|
}
|
|
/>
|
|
</g>
|
|
);
|
|
|
|
const Shadow = ({
|
|
radius,
|
|
paths,
|
|
...props
|
|
}: {
|
|
radius: number;
|
|
paths: Path[];
|
|
} & PathProps<'stroke' | 'strokeWidth' | 'strokeOpacity', 'd'>) => {
|
|
const groupedPaths = Object.entries(
|
|
paths.reduce((groups, val) => {
|
|
const key = val.c.id;
|
|
groups[key] = [...(groups[key] || []), val];
|
|
return groups;
|
|
}, {} as Record<number, Path[]>)
|
|
);
|
|
return (
|
|
<>
|
|
<g className="svg-preview-shadow-mask-group" {...props}>
|
|
{groupedPaths.map(([id, paths]) => (
|
|
<mask
|
|
id={`svg-preview-shadow-mask-${id}`}
|
|
maskUnits="userSpaceOnUse"
|
|
strokeOpacity="1"
|
|
strokeWidth={props.strokeWidth}
|
|
stroke="#000"
|
|
>
|
|
<rect x={0} y={0} width={24} height={24} fill="#fff" stroke="none" rx={radius} />
|
|
<path
|
|
d={paths
|
|
.flatMap(({ prev, next }) => [
|
|
`M${prev.x} ${prev.y}h.01`,
|
|
`M${next.x} ${next.y}h.01`,
|
|
])
|
|
.filter((val, idx, arr) => arr.indexOf(val) === idx)
|
|
.join('')}
|
|
/>
|
|
</mask>
|
|
))}
|
|
</g>
|
|
<g className="svg-preview-shadow-group" {...props}>
|
|
{paths.map(({ d, c: { id } }, i) => (
|
|
<path key={i} mask={`url(#svg-preview-shadow-mask-${id})`} d={d} />
|
|
))}
|
|
<path
|
|
d={paths
|
|
.flatMap(({ prev, next }) => [`M${prev.x} ${prev.y}h.01`, `M${next.x} ${next.y}h.01`])
|
|
.filter((val, idx, arr) => arr.indexOf(val) === idx)
|
|
.join('')}
|
|
/>
|
|
</g>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const ColoredPath = ({
|
|
colors,
|
|
paths,
|
|
...props
|
|
}: { paths: Path[]; colors: string[] } & PathProps<never, 'd' | 'stroke'>) => (
|
|
<g className="svg-preview-colored-path-group" {...props}>
|
|
{paths.map(({ d, c }, i) => (
|
|
<path key={i} d={d} stroke={colors[(c.name === 'path' ? i : c.id) % colors.length]} />
|
|
))}
|
|
</g>
|
|
);
|
|
|
|
const ControlPath = ({
|
|
paths,
|
|
radius,
|
|
pointSize,
|
|
...props
|
|
}: { pointSize: number; paths: Path[]; radius: number } & PathProps<
|
|
'stroke' | 'strokeWidth',
|
|
'd'
|
|
>) => {
|
|
const controlPaths = paths.map((path, i) => {
|
|
const element = paths.filter((p) => p.c.id === path.c.id);
|
|
const lastElement = element.at(-1)?.next;
|
|
assert(lastElement);
|
|
const isClosed = element[0].prev.x === lastElement.x && element[0].prev.y === lastElement.y;
|
|
const showMarker = !['rect', 'circle', 'ellipse'].includes(path.c.name);
|
|
return {
|
|
...path,
|
|
showMarker,
|
|
startMarker: showMarker && path.isStart && !isClosed,
|
|
endMarker: showMarker && paths[i + 1]?.isStart !== false && !isClosed,
|
|
};
|
|
});
|
|
return (
|
|
<>
|
|
<g
|
|
className="svg-preview-control-path-marker-mask-group"
|
|
strokeWidth={pointSize}
|
|
stroke="#000"
|
|
>
|
|
{controlPaths.map(({ prev, next, showMarker }, i) => {
|
|
return (
|
|
showMarker && (
|
|
<mask
|
|
id={`svg-preview-control-path-marker-mask-${i}`}
|
|
key={i}
|
|
maskUnits="userSpaceOnUse"
|
|
>
|
|
<rect x="0" y="0" width="24" height="24" fill="#fff" stroke="none" rx={radius} />
|
|
<path d={`M${prev.x} ${prev.y}h.01`} />
|
|
<path d={`M${next.x} ${next.y}h.01`} />
|
|
</mask>
|
|
)
|
|
);
|
|
})}
|
|
</g>
|
|
<g className="svg-preview-control-path-group" {...props}>
|
|
{controlPaths.map(({ d, showMarker }, i) => (
|
|
<path
|
|
key={i}
|
|
mask={showMarker ? `url(#svg-preview-control-path-marker-mask-${i})` : undefined}
|
|
d={d}
|
|
/>
|
|
))}
|
|
</g>
|
|
<g className="svg-preview-control-path-marker-group" {...props}>
|
|
<path
|
|
d={controlPaths
|
|
.flatMap(({ prev, next, showMarker }) =>
|
|
showMarker ? [`M${prev.x} ${prev.y}h.01`, `M${next.x} ${next.y}h.01`] : []
|
|
)
|
|
.join('')}
|
|
/>
|
|
{controlPaths.map(({ d, prev, next, startMarker, endMarker }, i) => (
|
|
<React.Fragment key={i}>
|
|
{startMarker && <circle cx={prev.x} cy={prev.y} r={pointSize / 2} />}
|
|
{endMarker && <circle cx={next.x} cy={next.y} r={pointSize / 2} />}
|
|
</React.Fragment>
|
|
))}
|
|
</g>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const Radii = ({
|
|
paths,
|
|
...props
|
|
}: { paths: Path[] } & PathProps<
|
|
'strokeWidth' | 'stroke' | 'strokeDasharray' | 'strokeOpacity',
|
|
any
|
|
>) => {
|
|
return (
|
|
<g className="svg-preview-radii-group" {...props}>
|
|
{paths
|
|
.filter(({ circle }) => circle)
|
|
.map(({ c, prev, next, circle: { x, y, r } }) =>
|
|
c.name === 'circle' ? (
|
|
<path d={`M${x} ${y}h.01`} />
|
|
) : (
|
|
<>
|
|
<path d={`M${prev.x} ${prev.y} ${x} ${y} ${next.x} ${next.y}`} />
|
|
<circle cy={y} cx={x} r={r} />
|
|
</>
|
|
)
|
|
)}
|
|
</g>
|
|
);
|
|
};
|
|
|
|
const SvgPreview = React.forwardRef<
|
|
SVGSVGElement,
|
|
{
|
|
src: string | ReturnType<typeof getPaths>;
|
|
showGrid?: boolean;
|
|
} & React.SVGProps<SVGSVGElement>
|
|
>(({ src, children, showGrid = false, ...props }, ref) => {
|
|
const paths = typeof src === 'string' ? getPaths(src) : src;
|
|
|
|
const darkModeCss = `@media screen and (prefers-color-scheme: dark) {
|
|
.svg-preview-grid-group,
|
|
.svg-preview-radii-group,
|
|
.svg-preview-shadow-mask-group,
|
|
.svg-preview-shadow-group {
|
|
stroke: #fff;
|
|
}
|
|
}`;
|
|
return (
|
|
<svg
|
|
ref={ref}
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width={24}
|
|
height={24}
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth={2}
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
{...props}
|
|
>
|
|
<style>{darkModeCss}</style>
|
|
{showGrid && <Grid strokeWidth={0.1} stroke="#777" strokeOpacity={0.3} radius={1} />}
|
|
<Shadow paths={paths} strokeWidth={4} stroke="#777" radius={1} strokeOpacity={0.15} />
|
|
<ColoredPath
|
|
paths={paths}
|
|
colors={[
|
|
'#1982c4',
|
|
'#4267AC',
|
|
'#6a4c93',
|
|
'#B55379',
|
|
'#FF595E',
|
|
'#FF7655',
|
|
'#ff924c',
|
|
'#FFAE43',
|
|
'#ffca3a',
|
|
'#C5CA30',
|
|
'#8ac926',
|
|
'#52A675',
|
|
]}
|
|
/>
|
|
<Radii
|
|
paths={paths}
|
|
strokeWidth={0.12}
|
|
strokeDasharray="0 0.25 0.25"
|
|
stroke="#777"
|
|
strokeOpacity={0.3}
|
|
/>
|
|
<ControlPath radius={1} paths={paths} pointSize={1} stroke="#fff" strokeWidth={0.125} />
|
|
{children}
|
|
</svg>
|
|
);
|
|
});
|
|
|
|
export default SvgPreview;
|