Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"scripts": {
"build": "run-s clean build.* prettier",
"build.files": "tsx scripts/build.ts",
"build.types": "node scripts/types.mjs",
"build.component": "stencil build",
"build.collection": "tsx scripts/collection-copy.ts",
"clean": "rimraf dist components icons www",
Expand Down
54 changes: 54 additions & 0 deletions scripts/types.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env node
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Where Ionicons keeps its JSON catalogue
const IONICONS_JSON_PATH = './dist/ionicons.json';

function findIoniconsJson() {
if (fs.existsSync(IONICONS_JSON_PATH)) return IONICONS_JSON_PATH;
console.error(
'[generate-ionicon-types] Could not find ionicons.json. ' +
'Did you build dist first? Tried:\n' +
IONICONS_JSON_PATH,
);
process.exit(1);
}

const srcPath = findIoniconsJson();
const outDir = path.resolve(__dirname, '../src/types');
const outFile = path.join(outDir, 'iconicons.d.ts');

const parsed = JSON.parse(fs.readFileSync(srcPath, 'utf-8'));
const names = Array.from(new Set((parsed.icons || []).map((i) => i.name).filter(Boolean))).sort();

// Build the union as nicely wrapped lines
const unionLines = names.map((n) => ` | "${n}"`).join('\n');

const banner = `// AUTO-GENERATED FILE. DO NOT EDIT.
// Generated from: ${path.relative(process.cwd(), srcPath)}
// Run: npm run build.types`;

const content = `${banner}
// 1) Strict union of built-in names
export type IoniconName =
${unionLines};

// 2) Flexible sources: prefer union, still allow any string (URLs, data URIs, etc.)
export type IoniconSource = IoniconName | (string & {});
`;

fs.mkdirSync(outDir, { recursive: true });

// Only write if changed (keeps TS server quiet)
const prev = fs.existsSync(outFile) ? fs.readFileSync(outFile, 'utf-8') : '';
if (prev !== content) {
fs.writeFileSync(outFile, content);
console.log(`[generate-ionicon-types] Wrote ${path.relative(process.cwd(), outFile)} with ${names.length} icons.`);
} else {
console.log('[generate-ionicon-types] No changes.');
}
18 changes: 10 additions & 8 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from '@stencil/core/internal';
import { IoniconName, IoniconSource } from './types/iconicons.d';
export { IoniconName, IoniconSource } from './types/iconicons.d';
export namespace Components {
interface IonIcon {
/**
Expand All @@ -18,7 +20,7 @@ export namespace Components {
/**
* A combination of both `name` and `src`. If a `src` url is detected it will set the `src` property. Otherwise it assumes it's a built-in named SVG and set the `name` property.
*/
icon?: any;
icon?: IoniconSource;
/**
* Specifies which icon to use on `ios` mode.
*/
Expand All @@ -34,13 +36,13 @@ export namespace Components {
md?: string;
/**
* The mode determines which platform styles to use.
* @default getIonMode()
* @default getIonMode() as any
*/
mode: string;
mode: any;
/**
* Specifies which icon to use from the built-in set of icons.
*/
name?: string;
name?: IoniconName;
/**
* When set to `false`, SVG content that is HTTP fetched will not be checked if the response SVG content has any `<script>` elements, or any attributes that start with `on`, such as `onclick`.
* @default true
Expand Down Expand Up @@ -79,7 +81,7 @@ declare namespace LocalJSX {
/**
* A combination of both `name` and `src`. If a `src` url is detected it will set the `src` property. Otherwise it assumes it's a built-in named SVG and set the `name` property.
*/
icon?: any;
icon?: IoniconSource;
/**
* Specifies which icon to use on `ios` mode.
*/
Expand All @@ -95,13 +97,13 @@ declare namespace LocalJSX {
md?: string;
/**
* The mode determines which platform styles to use.
* @default getIonMode()
* @default getIonMode() as any
*/
mode?: string;
mode?: any;
/**
* Specifies which icon to use from the built-in set of icons.
*/
name?: string;
name?: IoniconName;
/**
* When set to `false`, SVG content that is HTTP fetched will not be checked if the response SVG content has any `<script>` elements, or any attributes that start with `on`, such as `onclick`.
* @default true
Expand Down
7 changes: 4 additions & 3 deletions src/components/icon/icon.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Build, Component, Element, Host, Prop, State, Watch, h } from '@stencil/core';
import { getSvgContent, ioniconContent } from './request';
import { getName, getUrl, inheritAttributes, isRTL } from './utils';
import { IoniconName, IoniconSource } from 'src/types/iconicons';

@Component({
tag: 'ion-icon',
Expand All @@ -22,7 +23,7 @@ export class Icon {
/**
* The mode determines which platform styles to use.
*/
@Prop({ mutable: true }) mode = getIonMode();
@Prop({ mutable: true }) mode = getIonMode() as any;

/**
* The color to use for the background of the item.
Expand All @@ -47,7 +48,7 @@ export class Icon {
/**
* Specifies which icon to use from the built-in set of icons.
*/
@Prop({ reflect: true }) name?: string;
@Prop({ reflect: true }) name?: IoniconName;

/**
* Specifies the exact `src` of an SVG file to use.
Expand All @@ -59,7 +60,7 @@ export class Icon {
* it will set the `src` property. Otherwise it assumes it's a built-in named
* SVG and set the `name` property.
*/
@Prop() icon?: any;
@Prop() icon?: IoniconSource;

/**
* The size of the icon.
Expand Down
26 changes: 13 additions & 13 deletions src/components/icon/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@

## Properties

| Property | Attribute | Description | Type | Default |
| ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -------------- |
| `color` | `color` | The color to use for the background of the item. | `string \| undefined` | `undefined` |
| `flipRtl` | `flip-rtl` | Specifies whether the icon should horizontally flip when `dir` is `"rtl"`. | `boolean \| undefined` | `undefined` |
| `icon` | `icon` | A combination of both `name` and `src`. If a `src` url is detected it will set the `src` property. Otherwise it assumes it's a built-in named SVG and set the `name` property. | `any` | `undefined` |
| `ios` | `ios` | Specifies which icon to use on `ios` mode. | `string \| undefined` | `undefined` |
| `lazy` | `lazy` | If enabled, ion-icon will be loaded lazily when it's visible in the viewport. Default, `false`. | `boolean` | `false` |
| `md` | `md` | Specifies which icon to use on `md` mode. | `string \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `string` | `getIonMode()` |
| `name` | `name` | Specifies which icon to use from the built-in set of icons. | `string \| undefined` | `undefined` |
| `sanitize` | `sanitize` | When set to `false`, SVG content that is HTTP fetched will not be checked if the response SVG content has any `<script>` elements, or any attributes that start with `on`, such as `onclick`. | `boolean` | `true` |
| `size` | `size` | The size of the icon. Available options are: `"small"` and `"large"`. | `string \| undefined` | `undefined` |
| `src` | `src` | Specifies the exact `src` of an SVG file to use. | `string \| undefined` | `undefined` |
| Property | Attribute | Description | Type | Default |
| ---------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------------- |
| `color` | `color` | The color to use for the background of the item. | `string \| undefined` | `undefined` |
| `flipRtl` | `flip-rtl` | Specifies whether the icon should horizontally flip when `dir` is `"rtl"`. | `boolean \| undefined` | `undefined` |
| `icon` | `icon` | A combination of both `name` and `src`. If a `src` url is detected it will set the `src` property. Otherwise it assumes it's a built-in named SVG and set the `name` property. | `IoniconSource \| undefined` | `undefined` |
| `ios` | `ios` | Specifies which icon to use on `ios` mode. | `string \| undefined` | `undefined` |
| `lazy` | `lazy` | If enabled, ion-icon will be loaded lazily when it's visible in the viewport. Default, `false`. | `boolean` | `false` |
| `md` | `md` | Specifies which icon to use on `md` mode. | `string \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `string` | `getIonMode()` |
| `name` | `name` | Specifies which icon to use from the built-in set of icons. | `IoniconName \| undefined` | `undefined` |
| `sanitize` | `sanitize` | When set to `false`, SVG content that is HTTP fetched will not be checked if the response SVG content has any `<script>` elements, or any attributes that start with `on`, such as `onclick`. | `boolean` | `true` |
| `size` | `size` | The size of the icon. Available options are: `"small"` and `"large"`. | `string \| undefined` | `undefined` |
| `src` | `src` | Specifies the exact `src` of an SVG file to use. | `string \| undefined` | `undefined` |


----------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions src/components/icon/test/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ describe('getUrl', () => {
* @ToDo(@christian-bromann): investigate why this is failing
*/
it.skip('use name prop', () => {
i.name = 'some-name';
expect(getUrl(i)).toBe('/svg/some-name.svg');
i.name = 'add';
expect(getUrl(i)).toBe('/svg/add.svg');
});

it('use src prop', () => {
i.src = './some.svg';
i.name = 'some-name';
i.name = 'add';
i.icon = 'some-icon';
expect(getUrl(i)).toBe('./some.svg');
});
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { setAssetPath } from '@stencil/core';

export type { IoniconName, IoniconSource } from './types/iconicons';
export { addIcons } from './components/icon/utils';
export type { Components, JSX } from './components';
Loading