@octane-xplat/icons 0.0.0-stage → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +170 -2
- package/dist/macos/Icon.macos.js +71 -0
- package/dist/macos/index.js +4 -0
- package/dist/macos/octane-client-build.json +8 -0
- package/dist/macos/registry.js +45 -0
- package/dist/macos/svg.js +37 -0
- package/dist/native/Icon.js +79 -0
- package/dist/native/index.js +4 -0
- package/dist/native/octane-client-build.json +8 -0
- package/dist/native/registry.js +45 -0
- package/dist/native/svg.js +37 -0
- package/dist/web/Icon.web.js +75 -0
- package/dist/web/index.js +4 -0
- package/dist/web/octane-client-build.json +8 -0
- package/dist/web/registry.js +45 -0
- package/dist/web/svg.js +37 -0
- package/package.json +88 -3
- package/types/generated/.tsrx-typegen-manifest.json +14 -0
- package/types/generated/Icon.d.ts +3 -0
- package/types/generated/Icon.macos.d.ts +3 -0
- package/types/generated/Icon.web.d.ts +3 -0
- package/types/generated/index.d.ts +5 -0
- package/types/generated/index.macos.d.ts +5 -0
- package/types/generated/index.web.d.ts +5 -0
- package/types/generated/props.d.ts +25 -0
- package/types/generated/registry.d.ts +14 -0
- package/types/generated/svg.d.ts +10 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alec Larson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,171 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @octane-xplat/icons
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Render bundled Iconify icons on web, iOS, Android, and experimental AppKit macOS. Apps choose their sets;
|
|
4
|
+
this package ships no icon data, default collection, or Iconify API client.
|
|
5
|
+
|
|
6
|
+
## Install and register
|
|
7
|
+
|
|
8
|
+
In an Octane-xplat app with `@octane-xplat/ui` already configured:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
pnpm add @octane-xplat/icons @iconify-json/heroicons
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Register bundled JSON before mounting the app, then use `prefix:name`:
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import { icons as heroicons } from '@iconify-json/heroicons'
|
|
18
|
+
import { addCollection, Icon } from '@octane-xplat/icons'
|
|
19
|
+
|
|
20
|
+
addCollection(heroicons)
|
|
21
|
+
|
|
22
|
+
export function NextAction() {
|
|
23
|
+
return <Icon name="heroicons:arrow-right" size={24} color="#2563eb" label="Next" />
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Heroicons is the Astryx-parity choice: Astryx's Icon is heroicons-based.
|
|
28
|
+
It is an example, not a default. Register any number of `@iconify-json/*`
|
|
29
|
+
collections the same way. A collection's `prefix` determines its namespace;
|
|
30
|
+
there is no automatic package discovery, fetching, or fallback set.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
// heroicons and addCollection are imported above.
|
|
34
|
+
addCollection(heroicons)
|
|
35
|
+
console.log(heroicons.prefix) // The prefix is used before the colon in name.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Importing a whole collection bundles that collection. To keep a small bundle,
|
|
39
|
+
provide equivalent Iconify JSON containing only the icons you use:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
addCollection({
|
|
43
|
+
prefix: 'app',
|
|
44
|
+
width: 24,
|
|
45
|
+
height: 24,
|
|
46
|
+
icons: {
|
|
47
|
+
next: {
|
|
48
|
+
body: '<path fill="none" d="M4 12h16m-6-6 6 6-6 6" stroke="currentColor" stroke-width="2"/>',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Keep collection dimensions and any parent icons needed by aliases when pruning
|
|
55
|
+
an existing set. Use only trusted bundled SVG data; conversion does not sanitize
|
|
56
|
+
SVG bodies. Treat registered JSON as immutable.
|
|
57
|
+
|
|
58
|
+
## Rendering and updates
|
|
59
|
+
|
|
60
|
+
Import `Icon` from **this package**. It owns a collection registry separate from
|
|
61
|
+
UI's glyph registry: `addCollection` does not populate UI's `registerIcons` seam.
|
|
62
|
+
That seam has no change subscription and shares stored definition IDs across
|
|
63
|
+
instances. This component subscribes to registration changes and makes SVG IDs
|
|
64
|
+
unique for each instance. Re-registering a prefix replaces its whole collection
|
|
65
|
+
and updates mounted icons, including a previously missing icon.
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { addCollection, Icon } from '@octane-xplat/icons'
|
|
69
|
+
|
|
70
|
+
addCollection({ prefix: 'trip', icons: { next: { body: '<path d="M0 0h16v16H0z" />' } } })
|
|
71
|
+
export function TripIcon() {
|
|
72
|
+
return <Icon name="trip:next" />
|
|
73
|
+
}
|
|
74
|
+
// Replacing this collection notifies already-mounted TripIcon components.
|
|
75
|
+
addCollection({ prefix: 'trip', icons: { next: { body: '<circle cx="8" cy="8" r="8" />' } } })
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`resolveIcon('prefix:name')` returns normalized Iconify data, including collection
|
|
79
|
+
dimensions and alias transforms, or `undefined` for a missing/invalid name.
|
|
80
|
+
`Icon` renders nothing in that case. Alias cycles and missing parents also resolve
|
|
81
|
+
to nothing. No network request is made.
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { resolveIcon } from '@octane-xplat/icons'
|
|
85
|
+
|
|
86
|
+
const icon = resolveIcon('heroicons:arrow-right')
|
|
87
|
+
if (!icon) console.log('Register this icon collection before rendering')
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
| Prop | Behavior |
|
|
91
|
+
| ----------------- | ------------------------------------------------------------------------------------------------ |
|
|
92
|
+
| `name` | Required `prefix:name` |
|
|
93
|
+
| `size` | Positive finite height in logical pixels, default 24; width follows the transformed aspect ratio |
|
|
94
|
+
| `color` | Replaces `currentColor` and supplies default fill; explicit multicolor fills remain intact |
|
|
95
|
+
| `rotate` | Quarter turns; applied after the icon's own transforms |
|
|
96
|
+
| `hFlip`, `vFlip` | Additional horizontal/vertical flips |
|
|
97
|
+
| `id`, `className` | Passed to the rendered host |
|
|
98
|
+
| `label` | Accessible description; omit for decorative icons |
|
|
99
|
+
|
|
100
|
+
Web uses inline `<svg>` and inherits `currentColor` when `color` is omitted.
|
|
101
|
+
Native defaults to black; pass a concrete color to match app/theme text. It sends
|
|
102
|
+
DOM-free SVG markup through UI's `Image` SVG path to the vendored ui-svg SVGView
|
|
103
|
+
(SVGKit on iOS, androidsvg on Android). No extra native plugin setup is needed
|
|
104
|
+
beyond UI's setup. All leaves have the same props and exports. The package uses
|
|
105
|
+
style objects and ships no CSS pipeline. Native compatibility follows those SVG
|
|
106
|
+
engines; browser-only SVG features such as filters/animation are not guaranteed.
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
// Icon is imported from this package above.
|
|
110
|
+
export function Direction() {
|
|
111
|
+
return <Icon name="heroicons:arrow-right" color="#2563eb" rotate={1} hFlip label="Continue" />
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
AppKit uses UI's macOS `Image` to encode inline SVG with Foundation and load it
|
|
116
|
+
into `NSImageView` through public `NSImage` APIs. This path was runtime-tested
|
|
117
|
+
on macOS 27.0.1; SVG decoding on the app deployment minimum macOS 13.5 remains
|
|
118
|
+
unverified. An OS that cannot decode the SVG produces an empty image; there is
|
|
119
|
+
no fallback renderer. macOS forwards `id`/`className`, but the image host does
|
|
120
|
+
not apply class-based styling. Labels map to the native accessibility label;
|
|
121
|
+
unlabeled images are marked decorative. Pixel fidelity and OS accessibility
|
|
122
|
+
traversal remain unverified. See [AppKit SVG notes](../../docs/notes/icon-svg-notes.md).
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
// Direction.macos.tsx
|
|
126
|
+
import { Icon } from '@octane-xplat/icons'
|
|
127
|
+
|
|
128
|
+
export function Direction() {
|
|
129
|
+
return <Icon id="next" name="heroicons:arrow-right" size={24} label="Next" />
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`iconToSvg(icon, options?)` exposes the shared DOM-free conversion. It returns
|
|
134
|
+
`body`, `viewBox`, numeric `width`/`height`, and complete `markup`. It resolves
|
|
135
|
+
transforms and rewrites definition references. For native markup, supply a
|
|
136
|
+
concrete `color`; the helper otherwise retains `currentColor`.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { iconToSvg, resolveIcon } from '@octane-xplat/icons'
|
|
140
|
+
|
|
141
|
+
const icon = resolveIcon('heroicons:arrow-right')
|
|
142
|
+
if (icon) {
|
|
143
|
+
const svg = iconToSvg(icon, { color: '#2563eb' })
|
|
144
|
+
console.log(svg.viewBox, svg.width, svg.height, svg.markup)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Licenses
|
|
149
|
+
|
|
150
|
+
This package and Iconify's utilities are MIT. Icon sets retain their own licenses;
|
|
151
|
+
Iconify JSON does not grant a common license across sets. Heroicons is MIT.
|
|
152
|
+
Check each set's `info.json`, license files, and upstream license, and retain
|
|
153
|
+
required attribution/notices when bundling or pruning its data. Apps own that
|
|
154
|
+
license handling; this leaf distributes no set data.
|
|
155
|
+
|
|
156
|
+
## Verification and example
|
|
157
|
+
|
|
158
|
+
The maintained [icon probe](../../examples/probes/icons.tsrx) exercises multiple
|
|
159
|
+
sets, sizing, aliases, missing names, and mounted registration/prop updates:
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
pnpm probe doctor
|
|
163
|
+
pnpm probe run examples/probes/icons.macos.tsrx --target macos --deps @octane-xplat/icons
|
|
164
|
+
pnpm probe run examples/probes/icons.tsrx --target web --deps @octane-xplat/icons
|
|
165
|
+
pnpm probe run examples/probes/icons.tsrx --target ios --device SIMULATOR_UDID --deps @octane-xplat/icons
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
For package checks, run `pnpm --filter @octane-xplat/icons build`, `typecheck`,
|
|
169
|
+
`test`, and `pack:check`. Runtime evidence is recorded separately from builds;
|
|
170
|
+
The probe proves host/source updates, not pixel parity or OS accessibility
|
|
171
|
+
traversal. Run it on each target you ship. This package owns the maintained probe.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { registry, resolveIcon } from "./registry.js";
|
|
2
|
+
import { iconToSvg } from "./svg.js";
|
|
3
|
+
import { defineUniversalComponent, hookSlots, universalComponent, universalPlan, universalProps, universalValue, useMemo, withSlot } from "@nativescript-community/octane";
|
|
4
|
+
import { Image, useStore } from "@octane-xplat/ui";
|
|
5
|
+
//#region src/Icon.macos.tsrx
|
|
6
|
+
var _hs$ = /* @__PURE__ */ hookSlots(2);
|
|
7
|
+
var _h$0 = /* @__PURE__ */ Symbol(_hs$);
|
|
8
|
+
var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
|
|
9
|
+
var __octaneUniversalPlan0 = universalPlan("macos", {
|
|
10
|
+
"kind": "slot",
|
|
11
|
+
"slot": 0
|
|
12
|
+
});
|
|
13
|
+
var Icon = defineUniversalComponent("macos", function Icon(props) {
|
|
14
|
+
withSlot(_h$0, useStore, registry);
|
|
15
|
+
const icon = resolveIcon(props.name);
|
|
16
|
+
const image = useMemo(() => {
|
|
17
|
+
if (!icon) return void 0;
|
|
18
|
+
const svg = iconToSvg(icon, {
|
|
19
|
+
size: props.size,
|
|
20
|
+
color: props.color ?? "#000000",
|
|
21
|
+
rotate: props.rotate,
|
|
22
|
+
hFlip: props.hFlip,
|
|
23
|
+
vFlip: props.vFlip
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
src: svg.markup,
|
|
27
|
+
width: svg.width,
|
|
28
|
+
height: svg.height
|
|
29
|
+
};
|
|
30
|
+
}, [
|
|
31
|
+
icon,
|
|
32
|
+
props.size,
|
|
33
|
+
props.color,
|
|
34
|
+
props.rotate,
|
|
35
|
+
props.hFlip,
|
|
36
|
+
props.vFlip
|
|
37
|
+
], _h$1);
|
|
38
|
+
if (!image) return null;
|
|
39
|
+
return universalValue(__octaneUniversalPlan0, [universalComponent("macos", Image, universalProps([
|
|
40
|
+
[
|
|
41
|
+
"set",
|
|
42
|
+
"id",
|
|
43
|
+
props.id
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
"set",
|
|
47
|
+
"className",
|
|
48
|
+
props.className
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
"set",
|
|
52
|
+
"src",
|
|
53
|
+
image.src
|
|
54
|
+
],
|
|
55
|
+
[
|
|
56
|
+
"set",
|
|
57
|
+
"alt",
|
|
58
|
+
props.label ?? ""
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"set",
|
|
62
|
+
"style",
|
|
63
|
+
{
|
|
64
|
+
width: image.width,
|
|
65
|
+
height: image.height
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
]))]);
|
|
69
|
+
}, { "module": "@octane-xplat/macos-renderer" });
|
|
70
|
+
//#endregion
|
|
71
|
+
export { Icon };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getIconData } from "@iconify/utils/lib/icon-set/get-icon";
|
|
2
|
+
//#region src/registry.ts
|
|
3
|
+
var collections = /* @__PURE__ */ new Map();
|
|
4
|
+
var cache = /* @__PURE__ */ new Map();
|
|
5
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
var revision = 0;
|
|
7
|
+
var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
8
|
+
var registry = {
|
|
9
|
+
get: () => revision,
|
|
10
|
+
subscribe(notify) {
|
|
11
|
+
listeners.add(notify);
|
|
12
|
+
return () => {
|
|
13
|
+
listeners.delete(notify);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Register trusted, bundled Iconify JSON. Replaces the collection with the same
|
|
19
|
+
* prefix and updates mounted Icons. No fetching or default set is provided.
|
|
20
|
+
* Treat the supplied JSON as immutable after registration.
|
|
21
|
+
* @throws TypeError if the prefix or icons dictionary is missing/invalid.
|
|
22
|
+
*/
|
|
23
|
+
function addCollection(collection) {
|
|
24
|
+
if (!collection || typeof collection.prefix !== "string" || !identifier.test(collection.prefix) || !collection.icons || typeof collection.icons !== "object" || Array.isArray(collection.icons)) throw new TypeError("Expected Iconify JSON with a non-empty prefix and icons dictionary");
|
|
25
|
+
collections.set(collection.prefix, {
|
|
26
|
+
...collection,
|
|
27
|
+
icons: Object.assign(Object.create(null), collection.icons),
|
|
28
|
+
aliases: Object.assign(Object.create(null), collection.aliases)
|
|
29
|
+
});
|
|
30
|
+
cache.clear();
|
|
31
|
+
revision++;
|
|
32
|
+
for (const notify of [...listeners]) notify();
|
|
33
|
+
}
|
|
34
|
+
/** Resolve `prefix:name`, including aliases and collection dimensions; missing/invalid names return undefined. */
|
|
35
|
+
function resolveIcon(name) {
|
|
36
|
+
if (cache.has(name)) return cache.get(name);
|
|
37
|
+
const parts = name.split(":");
|
|
38
|
+
if (parts.length !== 2 || !parts.every((part) => identifier.test(part))) return;
|
|
39
|
+
const collection = collections.get(parts[0]);
|
|
40
|
+
const icon = collection ? getIconData(collection, parts[1]) ?? void 0 : void 0;
|
|
41
|
+
cache.set(name, icon);
|
|
42
|
+
return icon;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { addCollection, registry, resolveIcon };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { iconToSVG } from "@iconify/utils/lib/svg/build";
|
|
2
|
+
import { replaceIDs } from "@iconify/utils/lib/svg/id";
|
|
3
|
+
//#region src/svg.ts
|
|
4
|
+
function escapeAttribute(value) {
|
|
5
|
+
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Convert trusted icon data to SVG without DOM APIs. Applies transforms, keeps
|
|
9
|
+
* multicolor fills, and gives definitions unique IDs on every invocation.
|
|
10
|
+
* Without a color, markup uses currentColor; native callers should supply a
|
|
11
|
+
* concrete tint. This is a converter, not an SVG sanitizer.
|
|
12
|
+
* @throws RangeError if size is not finite and positive.
|
|
13
|
+
*/
|
|
14
|
+
function iconToSvg(icon, options = {}) {
|
|
15
|
+
const size = options.size ?? 24;
|
|
16
|
+
if (!Number.isFinite(size) || size <= 0) throw new RangeError("Icon size must be finite and positive");
|
|
17
|
+
const result = iconToSVG(icon, {
|
|
18
|
+
height: size,
|
|
19
|
+
rotate: options.rotate ?? 0,
|
|
20
|
+
hFlip: options.hFlip ?? false,
|
|
21
|
+
vFlip: options.vFlip ?? false
|
|
22
|
+
});
|
|
23
|
+
const color = escapeAttribute(options.color ?? "currentColor");
|
|
24
|
+
const body = replaceIDs(result.body).replace(/currentColor/g, () => color);
|
|
25
|
+
const viewBox = result.attributes.viewBox;
|
|
26
|
+
const width = Number(result.attributes.width);
|
|
27
|
+
const height = Number(result.attributes.height);
|
|
28
|
+
return {
|
|
29
|
+
body,
|
|
30
|
+
viewBox,
|
|
31
|
+
width,
|
|
32
|
+
height,
|
|
33
|
+
markup: `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="${viewBox}" width="${width}" height="${height}" color="${color}" fill="${color}">${body}</svg>`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { iconToSvg };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { registry, resolveIcon } from "./registry.js";
|
|
2
|
+
import { iconToSvg } from "./svg.js";
|
|
3
|
+
import { defineUniversalComponent, hookSlots, universalComponent, universalPlan, universalProps, universalValue, useMemo, withSlot } from "@nativescript-community/octane";
|
|
4
|
+
import { Image, useStore } from "@octane-xplat/ui";
|
|
5
|
+
//#region src/Icon.tsrx
|
|
6
|
+
var _hs$ = /* @__PURE__ */ hookSlots(2);
|
|
7
|
+
var _h$0 = /* @__PURE__ */ Symbol(_hs$);
|
|
8
|
+
var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
|
|
9
|
+
var __octaneUniversalPlan0 = universalPlan("nativescript", {
|
|
10
|
+
"kind": "slot",
|
|
11
|
+
"slot": 0
|
|
12
|
+
});
|
|
13
|
+
var Icon = defineUniversalComponent("nativescript", function Icon(props) {
|
|
14
|
+
withSlot(_h$0, useStore, registry);
|
|
15
|
+
const icon = resolveIcon(props.name);
|
|
16
|
+
const svg = useMemo(() => icon ? iconToSvg(icon, {
|
|
17
|
+
size: props.size,
|
|
18
|
+
color: props.color ?? "#000000",
|
|
19
|
+
rotate: props.rotate,
|
|
20
|
+
hFlip: props.hFlip,
|
|
21
|
+
vFlip: props.vFlip
|
|
22
|
+
}) : void 0, [
|
|
23
|
+
icon,
|
|
24
|
+
props.size,
|
|
25
|
+
props.color,
|
|
26
|
+
props.rotate,
|
|
27
|
+
props.hFlip,
|
|
28
|
+
props.vFlip
|
|
29
|
+
], _h$1);
|
|
30
|
+
if (!svg) return null;
|
|
31
|
+
return universalValue(__octaneUniversalPlan0, [universalComponent("nativescript", Image, universalProps([
|
|
32
|
+
[
|
|
33
|
+
"set",
|
|
34
|
+
"id",
|
|
35
|
+
props.id
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
"set",
|
|
39
|
+
"className",
|
|
40
|
+
props.className
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
"set",
|
|
44
|
+
"src",
|
|
45
|
+
svg.markup
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
"set",
|
|
49
|
+
"alt",
|
|
50
|
+
props.label
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
"set",
|
|
54
|
+
"ios",
|
|
55
|
+
{
|
|
56
|
+
accessible: !!props.label,
|
|
57
|
+
accessibilityRole: "image"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"set",
|
|
62
|
+
"android",
|
|
63
|
+
{
|
|
64
|
+
accessible: !!props.label,
|
|
65
|
+
accessibilityRole: "image"
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
"set",
|
|
70
|
+
"style",
|
|
71
|
+
{
|
|
72
|
+
width: svg.width,
|
|
73
|
+
height: svg.height
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
]))]);
|
|
77
|
+
}, { "module": "@nativescript-community/octane" });
|
|
78
|
+
//#endregion
|
|
79
|
+
export { Icon };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getIconData } from "@iconify/utils/lib/icon-set/get-icon";
|
|
2
|
+
//#region src/registry.ts
|
|
3
|
+
var collections = /* @__PURE__ */ new Map();
|
|
4
|
+
var cache = /* @__PURE__ */ new Map();
|
|
5
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
var revision = 0;
|
|
7
|
+
var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
8
|
+
var registry = {
|
|
9
|
+
get: () => revision,
|
|
10
|
+
subscribe(notify) {
|
|
11
|
+
listeners.add(notify);
|
|
12
|
+
return () => {
|
|
13
|
+
listeners.delete(notify);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Register trusted, bundled Iconify JSON. Replaces the collection with the same
|
|
19
|
+
* prefix and updates mounted Icons. No fetching or default set is provided.
|
|
20
|
+
* Treat the supplied JSON as immutable after registration.
|
|
21
|
+
* @throws TypeError if the prefix or icons dictionary is missing/invalid.
|
|
22
|
+
*/
|
|
23
|
+
function addCollection(collection) {
|
|
24
|
+
if (!collection || typeof collection.prefix !== "string" || !identifier.test(collection.prefix) || !collection.icons || typeof collection.icons !== "object" || Array.isArray(collection.icons)) throw new TypeError("Expected Iconify JSON with a non-empty prefix and icons dictionary");
|
|
25
|
+
collections.set(collection.prefix, {
|
|
26
|
+
...collection,
|
|
27
|
+
icons: Object.assign(Object.create(null), collection.icons),
|
|
28
|
+
aliases: Object.assign(Object.create(null), collection.aliases)
|
|
29
|
+
});
|
|
30
|
+
cache.clear();
|
|
31
|
+
revision++;
|
|
32
|
+
for (const notify of [...listeners]) notify();
|
|
33
|
+
}
|
|
34
|
+
/** Resolve `prefix:name`, including aliases and collection dimensions; missing/invalid names return undefined. */
|
|
35
|
+
function resolveIcon(name) {
|
|
36
|
+
if (cache.has(name)) return cache.get(name);
|
|
37
|
+
const parts = name.split(":");
|
|
38
|
+
if (parts.length !== 2 || !parts.every((part) => identifier.test(part))) return;
|
|
39
|
+
const collection = collections.get(parts[0]);
|
|
40
|
+
const icon = collection ? getIconData(collection, parts[1]) ?? void 0 : void 0;
|
|
41
|
+
cache.set(name, icon);
|
|
42
|
+
return icon;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { addCollection, registry, resolveIcon };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { iconToSVG } from "@iconify/utils/lib/svg/build";
|
|
2
|
+
import { replaceIDs } from "@iconify/utils/lib/svg/id";
|
|
3
|
+
//#region src/svg.ts
|
|
4
|
+
function escapeAttribute(value) {
|
|
5
|
+
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Convert trusted icon data to SVG without DOM APIs. Applies transforms, keeps
|
|
9
|
+
* multicolor fills, and gives definitions unique IDs on every invocation.
|
|
10
|
+
* Without a color, markup uses currentColor; native callers should supply a
|
|
11
|
+
* concrete tint. This is a converter, not an SVG sanitizer.
|
|
12
|
+
* @throws RangeError if size is not finite and positive.
|
|
13
|
+
*/
|
|
14
|
+
function iconToSvg(icon, options = {}) {
|
|
15
|
+
const size = options.size ?? 24;
|
|
16
|
+
if (!Number.isFinite(size) || size <= 0) throw new RangeError("Icon size must be finite and positive");
|
|
17
|
+
const result = iconToSVG(icon, {
|
|
18
|
+
height: size,
|
|
19
|
+
rotate: options.rotate ?? 0,
|
|
20
|
+
hFlip: options.hFlip ?? false,
|
|
21
|
+
vFlip: options.vFlip ?? false
|
|
22
|
+
});
|
|
23
|
+
const color = escapeAttribute(options.color ?? "currentColor");
|
|
24
|
+
const body = replaceIDs(result.body).replace(/currentColor/g, () => color);
|
|
25
|
+
const viewBox = result.attributes.viewBox;
|
|
26
|
+
const width = Number(result.attributes.width);
|
|
27
|
+
const height = Number(result.attributes.height);
|
|
28
|
+
return {
|
|
29
|
+
body,
|
|
30
|
+
viewBox,
|
|
31
|
+
width,
|
|
32
|
+
height,
|
|
33
|
+
markup: `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="${viewBox}" width="${width}" height="${height}" color="${color}" fill="${color}">${body}</svg>`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { iconToSvg };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { registry, resolveIcon } from "./registry.js";
|
|
2
|
+
import { iconToSvg } from "./svg.js";
|
|
3
|
+
import { bag12, clone, hookSlots, ifBlock, queueRefAttach, queueRefDetach, setAriaAttribute, setStyleProperty, template, withSlot } from "octane";
|
|
4
|
+
import { bindSignalAttribute, compilerMemoRegion, enableSignalBindings, hookMemoCreate, hookMemoEqual, hookMemoPublish, replaceRef, setPlainAttribute } from "octane/internal/client";
|
|
5
|
+
import { useStore } from "@octane-xplat/ui";
|
|
6
|
+
//#region src/Icon.web.tsrx
|
|
7
|
+
enableSignalBindings(1, true);
|
|
8
|
+
var _t$0 = /* @__PURE__ */ template("<svg style=\"display: inline-block; flex-shrink: 0;\"></svg>", 1);
|
|
9
|
+
var _hs$ = /* @__PURE__ */ hookSlots(2);
|
|
10
|
+
var _h$0 = /* @__PURE__ */ Symbol(_hs$);
|
|
11
|
+
var _rm$1 = [
|
|
12
|
+
"r",
|
|
13
|
+
"l",
|
|
14
|
+
"b"
|
|
15
|
+
];
|
|
16
|
+
function __then$0(__props, __s, __extra) {
|
|
17
|
+
const props = __extra[0];
|
|
18
|
+
const svg = __extra[1];
|
|
19
|
+
let _b = __s.slots[0];
|
|
20
|
+
if (_b === void 0) {
|
|
21
|
+
let _m1, _m11;
|
|
22
|
+
const _root = clone(_t$0, void 0, "||");
|
|
23
|
+
_m1 = _root;
|
|
24
|
+
queueRefAttach(__s, _m11 = (element) => {
|
|
25
|
+
if (element) element.innerHTML = svg.body;
|
|
26
|
+
}, _m1);
|
|
27
|
+
(__s.cleanups ??= []).push(() => _b && queueRefDetach(_b.l, _b.b));
|
|
28
|
+
_b = bag12(__s, _root, void 0, _m1, void 0, void 0, void 0, void 0, void 0, __s, void 0, void 0, void 0, _m11);
|
|
29
|
+
__s.refFields = _rm$1;
|
|
30
|
+
} else {
|
|
31
|
+
const _r = (element) => {
|
|
32
|
+
if (element) element.innerHTML = svg.body;
|
|
33
|
+
};
|
|
34
|
+
if (_r !== _b.l) _b.l = replaceRef(__s, _b.l, _r, _b.b);
|
|
35
|
+
}
|
|
36
|
+
_b.a = bindSignalAttribute(__s, _b.a, _b.b, "id", props.id, "b:5e515cc8", setPlainAttribute);
|
|
37
|
+
_b.c = bindSignalAttribute(__s, _b.c, _b.b, "class", props.className, "b:55ac2a96", "class");
|
|
38
|
+
_b.d = bindSignalAttribute(__s, _b.d, _b.b, "viewBox", svg.viewBox, "b:056826c3", setPlainAttribute);
|
|
39
|
+
_b.e = bindSignalAttribute(__s, _b.e, _b.b, "width", svg.width, "b:73d5f188", setPlainAttribute);
|
|
40
|
+
_b.f = bindSignalAttribute(__s, _b.f, _b.b, "height", svg.height, "b:3b5779f4", setPlainAttribute);
|
|
41
|
+
_b.g = bindSignalAttribute(__s, _b.g, _b.b, "fill", props.color ?? "currentColor", "b:13d0b8b1", setPlainAttribute);
|
|
42
|
+
{
|
|
43
|
+
const _v = props.color;
|
|
44
|
+
if (_b.h !== _v) {
|
|
45
|
+
setStyleProperty(_b.b, "color", _v, "display: inline-block; flex-shrink: 0;", _b.h);
|
|
46
|
+
_b.h = _v;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
_b.i = bindSignalAttribute(__s, _b.i, _b.b, "role", props.label ? "img" : void 0, "b:23c7db75", setPlainAttribute);
|
|
50
|
+
_b.j = bindSignalAttribute(__s, _b.j, _b.b, "aria-label", props.label, "b:359cbba3", setAriaAttribute);
|
|
51
|
+
_b.k = bindSignalAttribute(__s, _b.k, _b.b, "aria-hidden", props.label ? void 0 : "true", "b:7db4983a", setAriaAttribute);
|
|
52
|
+
}
|
|
53
|
+
var Icon = function Icon(props, __s, __extra) {
|
|
54
|
+
const __block = __s.block;
|
|
55
|
+
const __memoRegion = compilerMemoRegion(__s, _hs$ + 0);
|
|
56
|
+
let __hk = __memoRegion.hooks;
|
|
57
|
+
if (__hk === void 0) __memoRegion.hooks = __hk = hookMemoCreate(8);
|
|
58
|
+
let __hkd0, __hkd1, __hkd2, __hkd3, __hkd4, __hkd5;
|
|
59
|
+
withSlot(_h$0, useStore, registry);
|
|
60
|
+
const icon = resolveIcon(props.name);
|
|
61
|
+
const svg = (__hkd0 = icon, __hkd1 = props.size, __hkd2 = props.color, __hkd3 = props.rotate, __hkd4 = props.hFlip, __hkd5 = props.vFlip, __hk[0] !== true || !hookMemoEqual(__hk[1], __hkd0) || !hookMemoEqual(__hk[2], __hkd1) || !hookMemoEqual(__hk[3], __hkd2) || !hookMemoEqual(__hk[4], __hkd3) || !hookMemoEqual(__hk[5], __hkd4) || !hookMemoEqual(__hk[6], __hkd5) ? hookMemoPublish(__hk, 0, icon ? iconToSvg(icon, {
|
|
62
|
+
size: props.size,
|
|
63
|
+
color: props.color,
|
|
64
|
+
rotate: props.rotate,
|
|
65
|
+
hFlip: props.hFlip,
|
|
66
|
+
vFlip: props.vFlip
|
|
67
|
+
}) : void 0, __hkd0, __hkd1, __hkd2, __hkd3, __hkd4, __hkd5) : __hk[7]);
|
|
68
|
+
if (__s.block.pending && !__s.block.crossRenderUpdate) return;
|
|
69
|
+
{
|
|
70
|
+
const __ifCondition = !!svg;
|
|
71
|
+
ifBlock(__s, 0, __block.parentNode, __ifCondition, __then$0, null, __block.endMarker, __ifCondition ? [props, svg] : void 0);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
//#endregion
|
|
75
|
+
export { Icon };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getIconData } from "@iconify/utils/lib/icon-set/get-icon";
|
|
2
|
+
//#region src/registry.ts
|
|
3
|
+
var collections = /* @__PURE__ */ new Map();
|
|
4
|
+
var cache = /* @__PURE__ */ new Map();
|
|
5
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
var revision = 0;
|
|
7
|
+
var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
8
|
+
var registry = {
|
|
9
|
+
get: () => revision,
|
|
10
|
+
subscribe(notify) {
|
|
11
|
+
listeners.add(notify);
|
|
12
|
+
return () => {
|
|
13
|
+
listeners.delete(notify);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Register trusted, bundled Iconify JSON. Replaces the collection with the same
|
|
19
|
+
* prefix and updates mounted Icons. No fetching or default set is provided.
|
|
20
|
+
* Treat the supplied JSON as immutable after registration.
|
|
21
|
+
* @throws TypeError if the prefix or icons dictionary is missing/invalid.
|
|
22
|
+
*/
|
|
23
|
+
function addCollection(collection) {
|
|
24
|
+
if (!collection || typeof collection.prefix !== "string" || !identifier.test(collection.prefix) || !collection.icons || typeof collection.icons !== "object" || Array.isArray(collection.icons)) throw new TypeError("Expected Iconify JSON with a non-empty prefix and icons dictionary");
|
|
25
|
+
collections.set(collection.prefix, {
|
|
26
|
+
...collection,
|
|
27
|
+
icons: Object.assign(Object.create(null), collection.icons),
|
|
28
|
+
aliases: Object.assign(Object.create(null), collection.aliases)
|
|
29
|
+
});
|
|
30
|
+
cache.clear();
|
|
31
|
+
revision++;
|
|
32
|
+
for (const notify of [...listeners]) notify();
|
|
33
|
+
}
|
|
34
|
+
/** Resolve `prefix:name`, including aliases and collection dimensions; missing/invalid names return undefined. */
|
|
35
|
+
function resolveIcon(name) {
|
|
36
|
+
if (cache.has(name)) return cache.get(name);
|
|
37
|
+
const parts = name.split(":");
|
|
38
|
+
if (parts.length !== 2 || !parts.every((part) => identifier.test(part))) return;
|
|
39
|
+
const collection = collections.get(parts[0]);
|
|
40
|
+
const icon = collection ? getIconData(collection, parts[1]) ?? void 0 : void 0;
|
|
41
|
+
cache.set(name, icon);
|
|
42
|
+
return icon;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { addCollection, registry, resolveIcon };
|
package/dist/web/svg.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { iconToSVG } from "@iconify/utils/lib/svg/build";
|
|
2
|
+
import { replaceIDs } from "@iconify/utils/lib/svg/id";
|
|
3
|
+
//#region src/svg.ts
|
|
4
|
+
function escapeAttribute(value) {
|
|
5
|
+
return value.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Convert trusted icon data to SVG without DOM APIs. Applies transforms, keeps
|
|
9
|
+
* multicolor fills, and gives definitions unique IDs on every invocation.
|
|
10
|
+
* Without a color, markup uses currentColor; native callers should supply a
|
|
11
|
+
* concrete tint. This is a converter, not an SVG sanitizer.
|
|
12
|
+
* @throws RangeError if size is not finite and positive.
|
|
13
|
+
*/
|
|
14
|
+
function iconToSvg(icon, options = {}) {
|
|
15
|
+
const size = options.size ?? 24;
|
|
16
|
+
if (!Number.isFinite(size) || size <= 0) throw new RangeError("Icon size must be finite and positive");
|
|
17
|
+
const result = iconToSVG(icon, {
|
|
18
|
+
height: size,
|
|
19
|
+
rotate: options.rotate ?? 0,
|
|
20
|
+
hFlip: options.hFlip ?? false,
|
|
21
|
+
vFlip: options.vFlip ?? false
|
|
22
|
+
});
|
|
23
|
+
const color = escapeAttribute(options.color ?? "currentColor");
|
|
24
|
+
const body = replaceIDs(result.body).replace(/currentColor/g, () => color);
|
|
25
|
+
const viewBox = result.attributes.viewBox;
|
|
26
|
+
const width = Number(result.attributes.width);
|
|
27
|
+
const height = Number(result.attributes.height);
|
|
28
|
+
return {
|
|
29
|
+
body,
|
|
30
|
+
viewBox,
|
|
31
|
+
width,
|
|
32
|
+
height,
|
|
33
|
+
markup: `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="${viewBox}" width="${width}" height="${height}" color="${color}" fill="${color}">${body}</svg>`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { iconToSvg };
|
package/package.json
CHANGED
|
@@ -1,6 +1,91 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octane-xplat/icons",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Bundled, set-agnostic Iconify icons for Octane web and NativeScript",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cross-platform",
|
|
7
|
+
"iconify",
|
|
8
|
+
"icons",
|
|
9
|
+
"nativescript",
|
|
10
|
+
"octane"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/octane-xplat/octane-xplat/tree/main/packages/icons",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/octane-xplat/octane-xplat",
|
|
17
|
+
"directory": "packages/icons"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"types/generated"
|
|
22
|
+
],
|
|
23
|
+
"type": "module",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"macos": {
|
|
27
|
+
"types": "./types/generated/index.macos.d.ts",
|
|
28
|
+
"default": "./dist/macos/index.js"
|
|
29
|
+
},
|
|
30
|
+
"web": {
|
|
31
|
+
"types": "./types/generated/index.web.d.ts",
|
|
32
|
+
"default": "./dist/web/index.js"
|
|
33
|
+
},
|
|
34
|
+
"native": {
|
|
35
|
+
"types": "./types/generated/index.d.ts",
|
|
36
|
+
"default": "./dist/native/index.js"
|
|
37
|
+
},
|
|
38
|
+
"types": "./types/generated/index.d.ts",
|
|
39
|
+
"default": "./dist/native/index.js"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@iconify/types": "2.0.0",
|
|
47
|
+
"@iconify/utils": "3.1.7",
|
|
48
|
+
"@octane-xplat/ui": "0.10.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@nativescript-community/octane": "0.2.4",
|
|
52
|
+
"@nativescript/core": "9.1.2",
|
|
53
|
+
"@octane-xplat/macos-renderer": "0.10.0",
|
|
54
|
+
"@octanejs/vite-plugin": "0.1.61",
|
|
55
|
+
"@tsrx/typescript-plugin": "0.4.11",
|
|
56
|
+
"octane": "0.6.3",
|
|
57
|
+
"tsrx-typegen": "0.2.2",
|
|
58
|
+
"typescript": "5.9.3",
|
|
59
|
+
"vite": "8.3.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"@nativescript-community/octane": ">=0.2.1 <1",
|
|
63
|
+
"@nativescript/core": ">=9.1.0 <10",
|
|
64
|
+
"octane": ">=0.6.3 <1"
|
|
65
|
+
},
|
|
66
|
+
"peerDependenciesMeta": {
|
|
67
|
+
"@nativescript-community/octane": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"@nativescript/core": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"octane": {
|
|
74
|
+
"optional": true
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"nativescript": {
|
|
78
|
+
"platforms": {
|
|
79
|
+
"android": "9.1.0",
|
|
80
|
+
"ios": "9.1.0"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "vite build && vite build --mode native && vite build --mode macos && pnpm typegen && node ../../scripts/check-native-dist.mjs",
|
|
85
|
+
"typegen": "tsrx-typegen --target icons",
|
|
86
|
+
"typecheck": "tsrx-tsc --noEmit -p tsconfig.web.json && tsrx-tsc --noEmit -p tsconfig.native.json && tsrx-tsc --noEmit -p tsconfig.macos.json",
|
|
87
|
+
"test": "pnpm build && node --test tests/*.test.mjs",
|
|
88
|
+
"pack:check": "tsrx-typegen --pack-check",
|
|
89
|
+
"test:packed": "node tests/packed-consumer.mjs"
|
|
90
|
+
}
|
|
6
91
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { Icon } from './Icon.macos.js';
|
|
2
|
+
export { addCollection, resolveIcon } from './registry.js';
|
|
3
|
+
export { iconToSvg } from './svg.js';
|
|
4
|
+
export type { IconProps, IconOptions, IconSvg } from './props.js';
|
|
5
|
+
export type { IconifyIcon, IconifyJSON } from '@iconify/types';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { Icon } from './Icon.web.js';
|
|
2
|
+
export { addCollection, resolveIcon } from './registry.js';
|
|
3
|
+
export { iconToSvg } from './svg.js';
|
|
4
|
+
export type { IconProps, IconOptions, IconSvg } from './props.js';
|
|
5
|
+
export type { IconifyIcon, IconifyJSON } from '@iconify/types';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IconifyTransformations } from '@iconify/types';
|
|
2
|
+
/** SVG sizing, tint, and transforms shared by every target. */
|
|
3
|
+
export interface IconOptions extends IconifyTransformations {
|
|
4
|
+
/** Height in logical pixels; width follows the transformed aspect ratio. Default: 24. */
|
|
5
|
+
size?: number;
|
|
6
|
+
/** Monochrome tint. Explicit fills in multicolor icons remain intact. */
|
|
7
|
+
color?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Props for a bundled Iconify icon. */
|
|
10
|
+
export interface IconProps extends IconOptions {
|
|
11
|
+
/** Registered collection prefix and icon name, such as `heroicons:arrow-right`. */
|
|
12
|
+
name: string;
|
|
13
|
+
id?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Accessible description. Omit for a decorative icon. */
|
|
16
|
+
label?: string;
|
|
17
|
+
}
|
|
18
|
+
/** DOM-free SVG output, ready for an inline SVG or native SVGView. */
|
|
19
|
+
export interface IconSvg {
|
|
20
|
+
body: string;
|
|
21
|
+
viewBox: string;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
markup: string;
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IconifyIcon, IconifyJSON } from '@iconify/types';
|
|
2
|
+
export declare const registry: {
|
|
3
|
+
get: () => number;
|
|
4
|
+
subscribe(notify: () => void): () => void;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Register trusted, bundled Iconify JSON. Replaces the collection with the same
|
|
8
|
+
* prefix and updates mounted Icons. No fetching or default set is provided.
|
|
9
|
+
* Treat the supplied JSON as immutable after registration.
|
|
10
|
+
* @throws TypeError if the prefix or icons dictionary is missing/invalid.
|
|
11
|
+
*/
|
|
12
|
+
export declare function addCollection(collection: IconifyJSON): void;
|
|
13
|
+
/** Resolve `prefix:name`, including aliases and collection dimensions; missing/invalid names return undefined. */
|
|
14
|
+
export declare function resolveIcon(name: string): IconifyIcon | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IconifyIcon } from '@iconify/types';
|
|
2
|
+
import type { IconOptions, IconSvg } from './props.js';
|
|
3
|
+
/**
|
|
4
|
+
* Convert trusted icon data to SVG without DOM APIs. Applies transforms, keeps
|
|
5
|
+
* multicolor fills, and gives definitions unique IDs on every invocation.
|
|
6
|
+
* Without a color, markup uses currentColor; native callers should supply a
|
|
7
|
+
* concrete tint. This is a converter, not an SVG sanitizer.
|
|
8
|
+
* @throws RangeError if size is not finite and positive.
|
|
9
|
+
*/
|
|
10
|
+
export declare function iconToSvg(icon: IconifyIcon, options?: IconOptions): IconSvg;
|