Skip to content

Commit

Permalink
Merge pull request #43 from indaco/fix-42
Browse files Browse the repository at this point in the history
Fix 42
  • Loading branch information
indaco authored Nov 2, 2023
2 parents 9ef9daa + f5980ef commit 8af1dfb
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 90 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ build
$RECYCLE.BIN/

# Directories
src/lib/
src/lib/icons

# Files

src/lib/index.ts
packages/iconoir
package-lock.json
Expand Down
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,27 +123,25 @@ You can apply your own styles to the icon components in different ways:
import { SunLightIcon } from '@indaco/svelte-iconoir/sun-light';
</script>

<SunLightIcon class="p-1 rounded-full border-2 bg-green-400" size="2xl" />
<SunLightIcon class="p-1 rounded-full border-2 bg-green-400" size="xl" />
```

## Properties

Each icon component can take any property of a normal SVG Element, for example:
Each icon component can take any attribute of a normal SVG Element, for example:

| Property | Type | Default | Description |
| :---------- | :--------- | :-------- | :---------------------------------------------------- |
| color | `string` | `none` | Set the fill colour to be applied to the icon |
| strokeWidth | `number` | `1.5` | Set the width of the stroke to be applied to the icon |
| style | `string` | | Set the `style` attribute on the rendered svg |
| class | `string` | | Set the `class` attribute on the rendered svg |
| ... |
```html
<ZoomOutIcon fill="red" stroke-width="3" />
```

In addition to these, each component can take the following properties:

| Property | Type | Default | Description |
| :---------- | :--------- | :-------- | :---------------------------------------------------- |
| size | `IconSize` | `base` | Set the attributes `width` and `height` |
| size | `IconSize` | `base` | Set the attributes `width` and `height` |
| altText | `string` | icon name | Set the `aria-labelledby` attribute on the svg |
| style | `string` | | Set the `style` attribute on the rendered svg |
| class | `string` | | Set the `class` attribute on the rendered svg |

The underlying properties can also be set and overriden manually, e.g. setting `width` explicitly takes precedence over `size`.

Expand All @@ -156,11 +154,11 @@ The underlying properties can also be set and overriden manually, e.g. setting `

| Size | Value |
| :--- | --------: |
| xs | `1rem` |
| sm | `1.25rem` |
| base | `1.5rem` |
| lg | `1.75rem` |
| xl | `2rem` |
| xs | `1em` |
| sm | `1.25em` |
| base | `1.5em` |
| lg | `1.75em` |
| xl | `2em` |

## Event Forwarding

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"prettier-plugin-svelte": "^3.0.3",
"publint": "^0.2.5",
"rimraf": "^5.0.5",
"scule": "^1.0.0",
"svelte-check": "^3.5.2",
"svg-parser": "^2.0.4",
"tslib": "^2.6.2",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 8 additions & 42 deletions scripts/buildIconsDataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
mkDir,
makeComponentFilename,
makeComponentName,
capitalizeFirstLetter,
generateIconComponentIndex,
generateExportEntryString
} from './utils.js';
Expand Down Expand Up @@ -150,60 +149,27 @@ async function generateIconsDataset(
*/
async function makeIconComponent(outputFolder: string, iconObj: Icon): Promise<void> {
const txt = `<script lang="ts">
import type { SVGAttributes } from 'svelte/elements';
import type { IconSize } from '../../../Icon.d.ts';
import IconBase from '../../../IconBase.svelte';
const sizeMap = {
xs: '1rem',
sm: '1.25rem',
base: '1.5rem',
lg: '1.75rem',
xl: '2rem',
};
type IconSize = keyof typeof sizeMap;
interface $$Props extends SVGAttributes<SVGElement> {
size?: IconSize | string | number;
altText?: string;
}
export let altText = $$props.altText ?? '${capitalizeFirstLetter(iconObj.name)} icon';
const defaultSize = sizeMap['base'];
let _size: string;
$: _size =
$$props.size in sizeMap
? sizeMap[$$props.size as unknown as IconSize]
: typeof $$props.size === 'number' || typeof $$props.size === 'string'
? $$props.size
: defaultSize;
export let name: string = 'zoom-out';
export let altText: string | undefined = undefined;
export let size: IconSize | string | number = 'base';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
width={_size}
height={_size}
fill="none"
stroke-width="1.5"
viewBox="0 0 24 24"
aria-hidden="true"
aria-labelledby={altText}
<IconBase {name} {altText} {size}
on:click
on:dblclick
on:keydown
on:keyup
on:mouseenter
on:mouseleave
{...$$restProps}
>
{...$$restProps}>
${iconObj.data}
</svg>`;
</IconBase>`;

await fsp.writeFile(join(outputFolder, iconObj.componentFolder, iconObj.componentFile), txt);
}

/**
* It takes an icon object, and appends an export entry to the file.
*
Expand Down
3 changes: 2 additions & 1 deletion scripts/cleanAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import pc from 'picocolors';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const LIB_FOLDER = join(__dirname, '..', '..', 'src', 'lib');
const ICONS_FOLDER = join(LIB_FOLDER, 'icons');

// ----------------------------------------------------------------

const removeLibFolder = async () => {
try {
await fs.rm(LIB_FOLDER, { recursive: true, force: true });
await fs.rm(ICONS_FOLDER, { recursive: true, force: true });
console.log(pc.blue('* Successfully removed previously generated components.'));
} catch (err) {
console.error(err);
Expand Down
21 changes: 3 additions & 18 deletions scripts/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import type { Icon } from './index.d.ts';
import { join } from 'node:path';
import { promises as fsp } from 'node:fs';

export function capitalizeFirstLetter(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
import { camelCase, pascalCase } from 'scule';

export async function mkDir(pathToDir: string, recursive = true) {
await fsp.mkdir(pathToDir, { recursive });
Expand All @@ -24,8 +21,8 @@ export function makeComponentName(filename: string) {
youtube: 'YouTubeIcon'
};

const specialCase = specialCases[toCamelCase(filename)];
return specialCase ? specialCase : `${toPascalCase(filename)}Icon`;
const specialCase = specialCases[camelCase(filename)];
return specialCase ? specialCase : `${pascalCase(filename)}Icon`;
}

export function makeComponentFilename(component: string): string {
Expand Down Expand Up @@ -54,15 +51,3 @@ export async function generateIconComponentIndex(
export function generateExportEntryString(iconObj: Icon): string {
return `export { ${iconObj.component} } from './${iconObj.componentFolder}/index.js';\n`;
}

// ----------------------------------------------------------------

function toPascalCase(str: string) {
const text = str.replace(/(?:^|-)([a-z0-9])/g, (_, char) => char.toUpperCase());
return text.replace(/ /g, '');
}

function toCamelCase(str: string) {
const text = str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase());
return text.replaceAll(/ /g, '');
}
14 changes: 14 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
main {
padding: 1rem 0.5rem;
}

.header {
text-align: center;
}

.roundedColor {
padding: 4px;
background-color: yellow;
border: 1px solid #d1d5db;
border-radius: 1rem;
}
31 changes: 31 additions & 0 deletions src/lib/Icon.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Nodes } from 'hast-util-to-html/lib/index.js';
import type { SvelteHTMLElements } from 'svelte/elements';

type IconSizeMap = {
xs: string;
sm: string;
base: string;
lg: string;
xl: string;
};

type IconSize = keyof IconSizeMap;

export type IconVariant = 'regular' | 'solid';

export type Icon = {
svgFile: string;
name: string;
variant: IconVariant;
data?: Nodes;
};

type SVGRestProps = SvelteHTMLElements['svg'];

interface SVGPropsInternal extends SVGRestProps {
name: string;
size: IconSize | string | number;
altText?: string;
}

export type SVGProps = SVGPropsInternal & SvelteHTMLElements['svg'];
48 changes: 48 additions & 0 deletions src/lib/IconBase.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script lang="ts">
import type { IconSize, IconSizeMap, SVGProps } from './Icon.d.ts';
const sizeMap = {
xs: '1em',
sm: '1.25em',
base: '1.5em',
lg: '1.75em',
xl: '2em'
} satisfies IconSizeMap;
interface $$Props extends SVGProps {}
export let name: $$Props['name'];
export let altText: $$Props['altText'] = undefined;
export let size: $$Props['size'] = 'base';
const defaultSize = sizeMap['base'];
let _altText = altText ?? `${name} icon`;
let _size =
size in sizeMap
? sizeMap[size as unknown as IconSize]
: typeof size === 'number' || typeof size === 'string'
? size
: defaultSize;
</script>

<svg
xmlns="http://www.w3.org/2000/svg"
width={_size}
height={_size}
fill="none"
stroke-width="1.5"
viewBox="0 0 24 24"
aria-hidden="true"
aria-labelledby={_altText}
{...$$restProps}
on:click
on:dblclick
on:keydown
on:keyup
on:mouseenter
on:mouseleave
>
<slot />
</svg>
7 changes: 7 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
import '../app.css';
</script>

<main>
<slot />
</main>
Loading

0 comments on commit 8af1dfb

Please sign in to comment.