Skip to content

Commit

Permalink
docs(svg): extend svg-vite example with calculating an aspect-ratio…
Browse files Browse the repository at this point in the history
… type from size
  • Loading branch information
secundant committed Jul 24, 2023
1 parent 4a817c9 commit 311c3a7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
36 changes: 30 additions & 6 deletions examples/svg-vite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ export default defineConfig(({ command }) => ({
}));
```

## Create Icon component and describe basic styles
## Create an Icon component and describe basic styles

[shared/ui/icon/icon.tsx](./src/shared/ui/icon/icon.tsx):

```tsx
import clsx from 'clsx';
import type { SVGProps } from 'react';
import type { SpritesMap } from './sprite.gen';
import { SPRITES_META, type SpritesMap } from './sprite.gen';

// Merging all icons as `SPRITE_NAME/ICON_NAME`
export type SpriteKey = {
Expand All @@ -72,12 +72,24 @@ export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'name' | 'type'
}

export function Icon({ name, className, viewBox, ...props }: IconProps) {
const [spriteName, iconName] = name.split('/');
const [spriteName, iconName] = name.split('/') as [
keyof SpritesMap,
SpritesMap[keyof SpritesMap]
];
const { filePath, items } = SPRITES_META[spriteName];
// @ts-expect-error mixed structures are confusing TS
const { viewBox, width, height } = items[iconName];
const rect = width === height ? 'xy' : width > height ? 'x' : 'y';

return (
<svg
// We recommend to use specific component class for avoid collisions with other styles and simple override it
className={clsx('icon', className)}
/**
* this prop is used by the "icon" class to set the icon's scaled size
* @see https://github.com/secundant/neodx/issues/92 - Issue with original motivation
*/
data-icon-aspect-ratio={rect}
viewBox={viewBox}
focusable="false"
aria-hidden
Expand Down Expand Up @@ -106,7 +118,19 @@ export function Icon({ name, className, viewBox, ...props }: IconProps) {
@layer components {
/* Our base class for all icons */
.icon {
@apply select-none fill-current w-[1em] h-[1em] inline-block text-inherit box-content;
@apply select-none fill-current inline-block text-inherit box-content;
}

.icon[data-icon-aspect-ratio='xy'] {
@apply w-[1em] h-[1em];
}

.icon[data-icon-aspect-ratio='x'] {
@apply w-[1em];
}

.icon[data-icon-aspect-ratio='y'] {
@apply h-[1em];
}
}
```
Expand All @@ -131,8 +155,8 @@ Under this example I want to cover all planned features of `@neodx/svg`, you can
- [x] Colors: replace known to CSS variables
- [x] Colors: exclude specific icons
- [x] Colors: exclude specific colors
- [ ] Non-standard sizes: generate `viewBox` and `width`/`height` attributes
- [ ] Non-standard sizes: example of enhanced `Icon` component
- [x] Non-standard sizes: generate `viewBox` and `width`/`height` attributes
- [x] Non-standard sizes: example of enhanced `Icon` component
- [ ] Inline SVG: auto-detection of internal references
- [ ] Inline SVG: injection into HTML
- [ ] Remove unnecessary attributes
Expand Down
8 changes: 7 additions & 1 deletion examples/svg-vite/src/shared/ui/icon/icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ export function Icon({ name, className, ...props }: IconProps) {
];
const { filePath, items } = SPRITES_META[spriteName];
// TODO Fix types
const { viewBox } = (items as any)[iconName] as { viewBox: string };
const { viewBox, width, height } = (items as any)[iconName] as any;
const rect = width === height ? 'xy' : width > height ? 'x' : 'y';

return (
<svg
className={clsx('icon', className)}
/**
* this prop is used by the "icon" class to set the icon's scaled size
* @see https://github.com/secundant/neodx/issues/92
*/
data-icon-aspect-ratio={rect}
viewBox={viewBox}
focusable="false"
aria-hidden
Expand Down
14 changes: 13 additions & 1 deletion examples/svg-vite/src/shared/ui/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@

@layer components {
.icon {
@apply select-none fill-current w-[1em] h-[1em] inline-block text-inherit box-content;
@apply select-none fill-current inline-block text-inherit box-content;
}

.icon[data-icon-aspect-ratio='xy'] {
@apply w-[1em] h-[1em];
}

.icon[data-icon-aspect-ratio='x'] {
@apply w-[1em];
}

.icon[data-icon-aspect-ratio='y'] {
@apply h-[1em];
}
}

0 comments on commit 311c3a7

Please sign in to comment.