huspy-icons 0.1.0 → 0.1.2
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/README.md +180 -125
- package/dist/fonts/HuspyIcons.css +28 -0
- package/dist/fonts/HuspyIcons.d.ts +9 -0
- package/dist/fonts/HuspyIcons.eot +0 -0
- package/dist/fonts/HuspyIcons.json +5 -0
- package/dist/fonts/HuspyIcons.svg +21 -0
- package/dist/fonts/HuspyIcons.symbol.svg +1 -0
- package/dist/fonts/HuspyIcons.ts +16 -0
- package/dist/fonts/HuspyIcons.ttf +0 -0
- package/dist/fonts/HuspyIcons.woff +0 -0
- package/dist/fonts/HuspyIcons.woff2 +0 -0
- package/dist/native/index.d.ts +34 -28
- package/dist/native/index.js +44 -84
- package/dist/native/index.js.map +1 -1
- package/dist/react/index.d.mts +23 -1
- package/dist/react/index.d.ts +23 -1
- package/dist/react/index.js +162 -74
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +158 -61
- package/dist/react/index.mjs.map +1 -1
- package/package.json +7 -8
- package/src/native/Icon.tsx +73 -0
- package/src/native/glyphMap.ts +22 -0
- package/src/native/index.ts +17 -12
- package/src/react/Icon.tsx +87 -0
- package/src/react/index.ts +5 -1
- package/src/native/ArrowLeft.tsx +0 -27
- package/src/native/ArrowUpRight.tsx +0 -27
- package/src/native/IconSlot.tsx +0 -19
- package/src/native/index.tsx +0 -3
package/dist/react/index.mjs
CHANGED
|
@@ -1,85 +1,182 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
3
10
|
|
|
4
11
|
// src/shared/types.ts
|
|
5
|
-
var ICON_SIZES = {
|
|
6
|
-
xs: 8,
|
|
7
|
-
sm: 12,
|
|
8
|
-
md: 16,
|
|
9
|
-
lg: 20,
|
|
10
|
-
xl: 24
|
|
11
|
-
};
|
|
12
12
|
function resolveSize(size = "lg") {
|
|
13
13
|
if (typeof size === "number") {
|
|
14
14
|
return size;
|
|
15
15
|
}
|
|
16
16
|
return ICON_SIZES[size] ?? ICON_SIZES.lg;
|
|
17
17
|
}
|
|
18
|
+
var ICON_SIZES;
|
|
19
|
+
var init_types = __esm({
|
|
20
|
+
"src/shared/types.ts"() {
|
|
21
|
+
"use strict";
|
|
22
|
+
ICON_SIZES = {
|
|
23
|
+
xs: 8,
|
|
24
|
+
sm: 12,
|
|
25
|
+
md: 16,
|
|
26
|
+
lg: 20,
|
|
27
|
+
xl: 24
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
});
|
|
18
31
|
|
|
19
32
|
// src/react/ArrowLeft.tsx
|
|
20
|
-
var
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
33
|
+
var ArrowLeft_exports = {};
|
|
34
|
+
__export(ArrowLeft_exports, {
|
|
35
|
+
default: () => ArrowLeft_default
|
|
36
|
+
});
|
|
37
|
+
import * as React from "react";
|
|
38
|
+
var SvgArrowLeft, ArrowLeft_default;
|
|
39
|
+
var init_ArrowLeft = __esm({
|
|
40
|
+
"src/react/ArrowLeft.tsx"() {
|
|
41
|
+
"use strict";
|
|
42
|
+
init_types();
|
|
43
|
+
SvgArrowLeft = ({ size = 16, ...props }) => {
|
|
44
|
+
const sizeValue = resolveSize(size);
|
|
45
|
+
return /* @__PURE__ */ React.createElement("svg", { width: sizeValue, height: sizeValue, viewBox: "0 0 24 24", fill: "none", ...props }, /* @__PURE__ */ React.createElement(
|
|
46
|
+
"path",
|
|
47
|
+
{
|
|
48
|
+
fillRule: "evenodd",
|
|
49
|
+
clipRule: "evenodd",
|
|
50
|
+
d: "M12.7071 4.29289C13.0976 4.68342 13.0976 5.31658 12.7071 5.70711L6.41421 12L12.7071 18.2929C13.0976 18.6834 13.0976 19.3166 12.7071 19.7071C12.3166 20.0976 11.6834 20.0976 11.2929 19.7071L4.29289 12.7071C3.90237 12.3166 3.90237 11.6834 4.29289 11.2929L11.2929 4.29289C11.6834 3.90237 12.3166 3.90237 12.7071 4.29289Z",
|
|
51
|
+
fill: "currentColor"
|
|
52
|
+
}
|
|
53
|
+
), /* @__PURE__ */ React.createElement(
|
|
54
|
+
"path",
|
|
55
|
+
{
|
|
56
|
+
fillRule: "evenodd",
|
|
57
|
+
clipRule: "evenodd",
|
|
58
|
+
d: "M4 12C4 11.4477 4.44772 11 5 11H19C19.5523 11 20 11.4477 20 12C20 12.5523 19.5523 13 19 13H5C4.44772 13 4 12.5523 4 12Z",
|
|
59
|
+
fill: "currentColor"
|
|
60
|
+
}
|
|
61
|
+
));
|
|
62
|
+
};
|
|
63
|
+
ArrowLeft_default = SvgArrowLeft;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
41
66
|
|
|
42
67
|
// src/react/ArrowUpRight.tsx
|
|
68
|
+
var ArrowUpRight_exports = {};
|
|
69
|
+
__export(ArrowUpRight_exports, {
|
|
70
|
+
default: () => ArrowUpRight_default
|
|
71
|
+
});
|
|
43
72
|
import * as React2 from "react";
|
|
44
|
-
var SvgArrowUpRight
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
var SvgArrowUpRight, ArrowUpRight_default;
|
|
74
|
+
var init_ArrowUpRight = __esm({
|
|
75
|
+
"src/react/ArrowUpRight.tsx"() {
|
|
76
|
+
"use strict";
|
|
77
|
+
init_types();
|
|
78
|
+
SvgArrowUpRight = ({ size = 16, ...props }) => {
|
|
79
|
+
const sizeValue = resolveSize(size);
|
|
80
|
+
return /* @__PURE__ */ React2.createElement("svg", { width: sizeValue, height: sizeValue, viewBox: "0 0 24 24", fill: "none", ...props }, /* @__PURE__ */ React2.createElement(
|
|
81
|
+
"path",
|
|
82
|
+
{
|
|
83
|
+
fillRule: "evenodd",
|
|
84
|
+
clipRule: "evenodd",
|
|
85
|
+
d: "M6 7C6 6.44772 6.44772 6 7 6H17C17.5523 6 18 6.44772 18 7V17C18 17.5523 17.5523 18 17 18C16.4477 18 16 17.5523 16 17V8H7C6.44772 8 6 7.55228 6 7Z",
|
|
86
|
+
fill: "currentColor"
|
|
87
|
+
}
|
|
88
|
+
), /* @__PURE__ */ React2.createElement(
|
|
89
|
+
"path",
|
|
90
|
+
{
|
|
91
|
+
fillRule: "evenodd",
|
|
92
|
+
clipRule: "evenodd",
|
|
93
|
+
d: "M17.7071 6.29289C18.0976 6.68342 18.0976 7.31658 17.7071 7.70711L7.70711 17.7071C7.31658 18.0976 6.68342 18.0976 6.29289 17.7071C5.90237 17.3166 5.90237 16.6834 6.29289 16.2929L16.2929 6.29289C16.6834 5.90237 17.3166 5.90237 17.7071 6.29289Z",
|
|
94
|
+
fill: "currentColor"
|
|
95
|
+
}
|
|
96
|
+
));
|
|
97
|
+
};
|
|
98
|
+
ArrowUpRight_default = SvgArrowUpRight;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
65
101
|
|
|
66
102
|
// src/react/IconSlot.tsx
|
|
103
|
+
var IconSlot_exports = {};
|
|
104
|
+
__export(IconSlot_exports, {
|
|
105
|
+
default: () => IconSlot_default
|
|
106
|
+
});
|
|
67
107
|
import * as React3 from "react";
|
|
68
|
-
var SvgIconSlot
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
108
|
+
var SvgIconSlot, IconSlot_default;
|
|
109
|
+
var init_IconSlot = __esm({
|
|
110
|
+
"src/react/IconSlot.tsx"() {
|
|
111
|
+
"use strict";
|
|
112
|
+
init_types();
|
|
113
|
+
SvgIconSlot = ({ size = 16, ...props }) => {
|
|
114
|
+
const sizeValue = resolveSize(size);
|
|
115
|
+
return /* @__PURE__ */ React3.createElement("svg", { width: sizeValue, height: sizeValue, viewBox: "0 0 15 15", fill: "none", ...props }, /* @__PURE__ */ React3.createElement(
|
|
116
|
+
"path",
|
|
117
|
+
{
|
|
118
|
+
d: "M13.3333 7.33333C13.3333 4.01962 10.647 1.33333 7.33333 1.33333C4.01962 1.33333 1.33333 4.01962 1.33333 7.33333C1.33333 10.647 4.01962 13.3333 7.33333 13.3333C10.647 13.3333 13.3333 10.647 13.3333 7.33333ZM14.6667 7.33333C14.6667 11.3834 11.3834 14.6667 7.33333 14.6667C3.28325 14.6667 0 11.3834 0 7.33333C0 3.28325 3.28325 0 7.33333 0C11.3834 0 14.6667 3.28325 14.6667 7.33333Z",
|
|
119
|
+
fill: "currentColor"
|
|
120
|
+
}
|
|
121
|
+
));
|
|
122
|
+
};
|
|
123
|
+
IconSlot_default = SvgIconSlot;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// src/react/index.ts
|
|
128
|
+
init_ArrowLeft();
|
|
129
|
+
init_ArrowUpRight();
|
|
130
|
+
init_IconSlot();
|
|
131
|
+
|
|
132
|
+
// src/react/Icon.tsx
|
|
133
|
+
import * as React4 from "react";
|
|
134
|
+
function loadIcon(name) {
|
|
135
|
+
switch (name) {
|
|
136
|
+
case "arrow-left":
|
|
137
|
+
return Promise.resolve().then(() => (init_ArrowLeft(), ArrowLeft_exports)).then((m) => m.default);
|
|
138
|
+
case "arrow-up-right":
|
|
139
|
+
return Promise.resolve().then(() => (init_ArrowUpRight(), ArrowUpRight_exports)).then((m) => m.default);
|
|
140
|
+
case "icon-slot":
|
|
141
|
+
return Promise.resolve().then(() => (init_IconSlot(), IconSlot_exports)).then((m) => m.default);
|
|
142
|
+
default:
|
|
143
|
+
return Promise.reject(new Error(`Icon "${name}" not found`));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
var Icon = ({ name, size = 16, color, ...props }) => {
|
|
147
|
+
const [IconComponent, setIconComponent] = React4.useState(null);
|
|
148
|
+
const [loading, setLoading] = React4.useState(true);
|
|
149
|
+
const [error, setError] = React4.useState(null);
|
|
150
|
+
React4.useEffect(() => {
|
|
151
|
+
setLoading(true);
|
|
152
|
+
setError(null);
|
|
153
|
+
loadIcon(name).then((Component) => {
|
|
154
|
+
setIconComponent(() => Component);
|
|
155
|
+
setLoading(false);
|
|
156
|
+
}).catch((err) => {
|
|
157
|
+
console.warn(err.message);
|
|
158
|
+
setError(err.message);
|
|
159
|
+
setLoading(false);
|
|
160
|
+
});
|
|
161
|
+
}, [name]);
|
|
162
|
+
if (loading) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
if (error || !IconComponent) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const style = color ? { ...props.style, color } : props.style;
|
|
169
|
+
return /* @__PURE__ */ React4.createElement(IconComponent, { size, ...props, style });
|
|
77
170
|
};
|
|
78
|
-
var
|
|
171
|
+
var Icon_default = Icon;
|
|
172
|
+
|
|
173
|
+
// src/react/index.ts
|
|
174
|
+
init_types();
|
|
79
175
|
export {
|
|
80
176
|
ArrowLeft_default as ArrowLeft,
|
|
81
177
|
ArrowUpRight_default as ArrowUpRight,
|
|
82
178
|
ICON_SIZES,
|
|
179
|
+
Icon_default as Icon,
|
|
83
180
|
IconSlot_default as IconSlot,
|
|
84
181
|
resolveSize
|
|
85
182
|
};
|
package/dist/react/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/ArrowLeft.tsx","../../src/
|
|
1
|
+
{"version":3,"sources":["../../src/shared/types.ts","../../src/react/ArrowLeft.tsx","../../src/react/ArrowUpRight.tsx","../../src/react/IconSlot.tsx","../../src/react/index.ts","../../src/react/Icon.tsx"],"sourcesContent":["export type IconSize = number | 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Icon size presets\n */\nexport const ICON_SIZES = {\n xs: 8,\n sm: 12,\n md: 16,\n lg: 20,\n xl: 24,\n} as const;\n\n/**\n * Icon size token type\n */\nexport type IconSizeToken = keyof typeof ICON_SIZES;\n\n/**\n * Props for React (web) icons\n */\nexport interface ReactIconProps extends React.SVGProps<SVGSVGElement> {\n size?: IconSize;\n}\n\n/**\n * Props for React Native icons\n */\nexport interface NativeIconProps {\n size?: IconSize;\n width?: number;\n height?: number;\n color?: string;\n style?: any;\n}\n\n/**\n * Resolves an icon size to a numeric value\n * @param size - Size value or token\n * @returns Numeric size in pixels\n */\nexport function resolveSize(size: IconSize = 'lg'): number {\n if (typeof size === 'number') {\n return size;\n }\n \n return ICON_SIZES[size] ?? ICON_SIZES.lg;\n}\n","import * as React from 'react';\nimport type { ReactIconProps } from '../shared/types';\nimport { resolveSize } from '../shared/types';\n\nconst SvgArrowLeft = ({ size = 16, ...props }: ReactIconProps) => {\n const sizeValue = resolveSize(size);\n \n return (\n <svg width={sizeValue} height={sizeValue} viewBox=\"0 0 24 24\" fill=\"none\" {...props}>\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12.7071 4.29289C13.0976 4.68342 13.0976 5.31658 12.7071 5.70711L6.41421 12L12.7071 18.2929C13.0976 18.6834 13.0976 19.3166 12.7071 19.7071C12.3166 20.0976 11.6834 20.0976 11.2929 19.7071L4.29289 12.7071C3.90237 12.3166 3.90237 11.6834 4.29289 11.2929L11.2929 4.29289C11.6834 3.90237 12.3166 3.90237 12.7071 4.29289Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M4 12C4 11.4477 4.44772 11 5 11H19C19.5523 11 20 11.4477 20 12C20 12.5523 19.5523 13 19 13H5C4.44772 13 4 12.5523 4 12Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n};\n\nexport default SvgArrowLeft;\n","import * as React from 'react';\nimport type { ReactIconProps } from '../shared/types';\nimport { resolveSize } from '../shared/types';\n\nconst SvgArrowUpRight = ({ size = 16, ...props }: ReactIconProps) => {\n const sizeValue = resolveSize(size);\n \n return (\n <svg width={sizeValue} height={sizeValue} viewBox=\"0 0 24 24\" fill=\"none\" {...props}>\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M6 7C6 6.44772 6.44772 6 7 6H17C17.5523 6 18 6.44772 18 7V17C18 17.5523 17.5523 18 17 18C16.4477 18 16 17.5523 16 17V8H7C6.44772 8 6 7.55228 6 7Z\"\n fill=\"currentColor\"\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M17.7071 6.29289C18.0976 6.68342 18.0976 7.31658 17.7071 7.70711L7.70711 17.7071C7.31658 18.0976 6.68342 18.0976 6.29289 17.7071C5.90237 17.3166 5.90237 16.6834 6.29289 16.2929L16.2929 6.29289C16.6834 5.90237 17.3166 5.90237 17.7071 6.29289Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n};\n\nexport default SvgArrowUpRight;\n","import * as React from 'react';\nimport type { ReactIconProps } from '../shared/types';\nimport { resolveSize } from '../shared/types';\n\nconst SvgIconSlot = ({ size = 16, ...props }: ReactIconProps) => {\n const sizeValue = resolveSize(size);\n \n return (\n <svg width={sizeValue} height={sizeValue} viewBox=\"0 0 15 15\" fill=\"none\" {...props}>\n <path\n d=\"M13.3333 7.33333C13.3333 4.01962 10.647 1.33333 7.33333 1.33333C4.01962 1.33333 1.33333 4.01962 1.33333 7.33333C1.33333 10.647 4.01962 13.3333 7.33333 13.3333C10.647 13.3333 13.3333 10.647 13.3333 7.33333ZM14.6667 7.33333C14.6667 11.3834 11.3834 14.6667 7.33333 14.6667C3.28325 14.6667 0 11.3834 0 7.33333C0 3.28325 3.28325 0 7.33333 0C11.3834 0 14.6667 3.28325 14.6667 7.33333Z\"\n fill=\"currentColor\"\n />\n </svg>\n );\n};\n\nexport default SvgIconSlot;\n","// Auto-generated exports\nexport { default as ArrowLeft } from './ArrowLeft';\nexport { default as ArrowUpRight } from './ArrowUpRight';\nexport { default as IconSlot } from './IconSlot';\n\n// Unified Icon component\nexport { default as Icon } from './Icon';\nexport type { IconName, IconProps } from './Icon';\n\n // Export types\nexport type {\n IconSize,\n IconSizeToken,\n ReactIconProps,\n} from '../shared/types';\n\nexport { ICON_SIZES, resolveSize } from '../shared/types';\n","import * as React from 'react';\nimport type { ReactIconProps } from '../shared/types';\n\n/**\n * Icon imports - using dynamic imports for tree-shaking\n * Auto-generated - do not edit manually\n */\n// Icon: arrow-left\n// Icon: arrow-up-right\n// Icon: icon-slot\n\n/**\n * Available icon names\n */\nexport type IconName = 'arrow-left' | 'arrow-up-right' | 'icon-slot';\n\n/**\n * Props for the unified Icon component\n */\nexport interface IconProps extends Omit<ReactIconProps, 'size'> {\n name: IconName;\n size?: ReactIconProps['size'];\n color?: string;\n}\n\n/**\n * Loads an icon component dynamically\n * This pattern allows bundlers to tree-shake unused icons\n * \n * Icons use default exports (export default SvgIconName),\n * so we access .default from the dynamic import result\n */\nfunction loadIcon(name: IconName): Promise<React.ComponentType<any>> {\n switch (name) {\n case 'arrow-left':\n return import('./ArrowLeft').then(m => m.default);\n case 'arrow-up-right':\n return import('./ArrowUpRight').then(m => m.default);\n case 'icon-slot':\n return import('./IconSlot').then(m => m.default);\n default:\n return Promise.reject(new Error(`Icon \"${name}\" not found`));\n }\n}\n\n/**\n * Unified Icon component that renders icons by name\n * Uses dynamic imports for tree-shaking support\n */\nconst Icon = ({ name, size = 16, color, ...props }: IconProps) => {\n const [IconComponent, setIconComponent] = React.useState<React.ComponentType<any> | null>(null);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n setLoading(true);\n setError(null);\n \n loadIcon(name)\n .then((Component) => {\n setIconComponent(() => Component);\n setLoading(false);\n })\n .catch((err) => {\n console.warn(err.message);\n setError(err.message);\n setLoading(false);\n });\n }, [name]);\n\n if (loading) {\n return null; // Consider showing a placeholder\n }\n\n if (error || !IconComponent) {\n return null;\n }\n\n // Apply color via style prop if provided (SVGs use fill=\"currentColor\")\n const style = color \n ? { ...props.style, color } \n : props.style;\n\n return <IconComponent size={size} {...props} style={style} />;\n};\n\nexport default Icon;"],"mappings":"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","names":["React","React","React"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huspy-icons",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Cross-platform icon package for Huspy - React and React Native compatible",
|
|
5
5
|
"author": "Huspy",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,12 +32,14 @@
|
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
34
|
"dist",
|
|
35
|
-
"src"
|
|
35
|
+
"src",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
36
38
|
],
|
|
37
39
|
"scripts": {
|
|
38
40
|
"svgo": "svgo -f icons-src -o icons-src --config=svgo.config.js",
|
|
39
41
|
"gen:react": "svgr icons-src -d src/react --ext tsx --typescript --icon && node scripts/add-size-prop.js --react",
|
|
40
|
-
"gen:native": "
|
|
42
|
+
"gen:native": "node scripts/generate-font.js",
|
|
41
43
|
"gen:types": "node scripts/generate-types.js",
|
|
42
44
|
"gen": "npm run svgo && npm run gen:react && npm run gen:native && npm run gen:types",
|
|
43
45
|
"build": "tsup",
|
|
@@ -51,21 +53,18 @@
|
|
|
51
53
|
"@types/react": "^18.2.48",
|
|
52
54
|
"@types/react-native": "^0.73.0",
|
|
53
55
|
"esbuild": "^0.19.11",
|
|
56
|
+
"fantasticon": "^3.0.0",
|
|
54
57
|
"svgo": "^3.3.2",
|
|
55
58
|
"tsup": "^8.0.1",
|
|
56
59
|
"typescript": "^5.3.3"
|
|
57
60
|
},
|
|
58
61
|
"peerDependencies": {
|
|
59
62
|
"react": ">=16.8.0",
|
|
60
|
-
"react-native": ">=0.73.0"
|
|
61
|
-
"react-native-svg": "^15.14.0"
|
|
63
|
+
"react-native": ">=0.73.0"
|
|
62
64
|
},
|
|
63
65
|
"peerDependenciesMeta": {
|
|
64
66
|
"react-native": {
|
|
65
67
|
"optional": true
|
|
66
|
-
},
|
|
67
|
-
"react-native-svg": {
|
|
68
|
-
"optional": true
|
|
69
68
|
}
|
|
70
69
|
},
|
|
71
70
|
"publishConfig": {
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Text, TextProps, Platform } from 'react-native';
|
|
3
|
+
import { glyphMap, fontFamily, IconName } from './glyphMap';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Props for the Icon component (React Native)
|
|
7
|
+
*/
|
|
8
|
+
export interface IconProps extends Omit<TextProps, 'children'> {
|
|
9
|
+
/**
|
|
10
|
+
* Name of the icon to display
|
|
11
|
+
*/
|
|
12
|
+
name: IconName;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Size of the icon (default: 16)
|
|
16
|
+
*/
|
|
17
|
+
size?: number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Color of the icon (default: inherits from parent or 'black')
|
|
21
|
+
*/
|
|
22
|
+
color?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Icon component for React Native
|
|
27
|
+
*
|
|
28
|
+
* Renders icons using a custom font (HuspyIcons)
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <Icon name="arrow-left" size={24} color="#000" />
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
const Icon = ({ name, size = 16, color = '#000', style, ...props }: IconProps) => {
|
|
36
|
+
const codepoint = glyphMap[name];
|
|
37
|
+
|
|
38
|
+
if (!codepoint) {
|
|
39
|
+
if (__DEV__) {
|
|
40
|
+
console.warn(`Icon "${name}" not found in HuspyIcons font`);
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Convert codepoint to character
|
|
46
|
+
const glyph = String.fromCharCode(codepoint);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Text
|
|
50
|
+
{...props}
|
|
51
|
+
style={[
|
|
52
|
+
{
|
|
53
|
+
fontFamily: fontFamily,
|
|
54
|
+
fontSize: size,
|
|
55
|
+
color: color,
|
|
56
|
+
// Ensure icon doesn't inherit text styles
|
|
57
|
+
fontWeight: 'normal',
|
|
58
|
+
fontStyle: 'normal',
|
|
59
|
+
},
|
|
60
|
+
style,
|
|
61
|
+
]}
|
|
62
|
+
// Accessibility
|
|
63
|
+
accessible
|
|
64
|
+
accessibilityLabel={props.accessibilityLabel || name}
|
|
65
|
+
accessibilityRole="image"
|
|
66
|
+
>
|
|
67
|
+
{glyph}
|
|
68
|
+
</Text>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default Icon;
|
|
73
|
+
export type { IconName };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Auto-generated by generate-font.js - do not edit manually
|
|
2
|
+
// Source: icons-src/*.svg → dist/fonts/HuspyIcons.*
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Available icon names in the HuspyIcons font
|
|
6
|
+
*/
|
|
7
|
+
export type IconName = 'icon-slot' | 'arrow-up-right' | 'arrow-left';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Mapping of icon names to unicode codepoints
|
|
11
|
+
* Used by the Icon component to render the correct glyph
|
|
12
|
+
*/
|
|
13
|
+
export const glyphMap: Record<IconName, number> = {
|
|
14
|
+
"icon-slot": 61697,
|
|
15
|
+
"arrow-up-right": 61698,
|
|
16
|
+
"arrow-left": 61699
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Font family name for React Native
|
|
21
|
+
*/
|
|
22
|
+
export const fontFamily = 'HuspyIcons';
|
package/src/native/index.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Huspy Icons - React Native (Font-based)
|
|
3
|
+
*
|
|
4
|
+
* This package provides icon components for React Native using a custom font.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { Icon } from 'huspy-icons/native';
|
|
9
|
+
*
|
|
10
|
+
* function MyComponent() {
|
|
11
|
+
* return <Icon name="arrow-left" size={24} color="#000" />;
|
|
12
|
+
* }
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
5
15
|
|
|
6
|
-
|
|
7
|
-
export type {
|
|
8
|
-
|
|
9
|
-
IconSizeToken,
|
|
10
|
-
NativeIconProps,
|
|
11
|
-
} from '../shared/types';
|
|
12
|
-
|
|
13
|
-
export { ICON_SIZES, resolveSize } from '../shared/types';
|
|
16
|
+
export { default as Icon } from './Icon';
|
|
17
|
+
export type { IconProps, IconName } from './Icon';
|
|
18
|
+
export { glyphMap, fontFamily } from './glyphMap';
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ReactIconProps } from '../shared/types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Icon imports - using dynamic imports for tree-shaking
|
|
6
|
+
* Auto-generated - do not edit manually
|
|
7
|
+
*/
|
|
8
|
+
// Icon: arrow-left
|
|
9
|
+
// Icon: arrow-up-right
|
|
10
|
+
// Icon: icon-slot
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Available icon names
|
|
14
|
+
*/
|
|
15
|
+
export type IconName = 'arrow-left' | 'arrow-up-right' | 'icon-slot';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Props for the unified Icon component
|
|
19
|
+
*/
|
|
20
|
+
export interface IconProps extends Omit<ReactIconProps, 'size'> {
|
|
21
|
+
name: IconName;
|
|
22
|
+
size?: ReactIconProps['size'];
|
|
23
|
+
color?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Loads an icon component dynamically
|
|
28
|
+
* This pattern allows bundlers to tree-shake unused icons
|
|
29
|
+
*
|
|
30
|
+
* Icons use default exports (export default SvgIconName),
|
|
31
|
+
* so we access .default from the dynamic import result
|
|
32
|
+
*/
|
|
33
|
+
function loadIcon(name: IconName): Promise<React.ComponentType<any>> {
|
|
34
|
+
switch (name) {
|
|
35
|
+
case 'arrow-left':
|
|
36
|
+
return import('./ArrowLeft').then(m => m.default);
|
|
37
|
+
case 'arrow-up-right':
|
|
38
|
+
return import('./ArrowUpRight').then(m => m.default);
|
|
39
|
+
case 'icon-slot':
|
|
40
|
+
return import('./IconSlot').then(m => m.default);
|
|
41
|
+
default:
|
|
42
|
+
return Promise.reject(new Error(`Icon "${name}" not found`));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Unified Icon component that renders icons by name
|
|
48
|
+
* Uses dynamic imports for tree-shaking support
|
|
49
|
+
*/
|
|
50
|
+
const Icon = ({ name, size = 16, color, ...props }: IconProps) => {
|
|
51
|
+
const [IconComponent, setIconComponent] = React.useState<React.ComponentType<any> | null>(null);
|
|
52
|
+
const [loading, setLoading] = React.useState(true);
|
|
53
|
+
const [error, setError] = React.useState<string | null>(null);
|
|
54
|
+
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
setLoading(true);
|
|
57
|
+
setError(null);
|
|
58
|
+
|
|
59
|
+
loadIcon(name)
|
|
60
|
+
.then((Component) => {
|
|
61
|
+
setIconComponent(() => Component);
|
|
62
|
+
setLoading(false);
|
|
63
|
+
})
|
|
64
|
+
.catch((err) => {
|
|
65
|
+
console.warn(err.message);
|
|
66
|
+
setError(err.message);
|
|
67
|
+
setLoading(false);
|
|
68
|
+
});
|
|
69
|
+
}, [name]);
|
|
70
|
+
|
|
71
|
+
if (loading) {
|
|
72
|
+
return null; // Consider showing a placeholder
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (error || !IconComponent) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Apply color via style prop if provided (SVGs use fill="currentColor")
|
|
80
|
+
const style = color
|
|
81
|
+
? { ...props.style, color }
|
|
82
|
+
: props.style;
|
|
83
|
+
|
|
84
|
+
return <IconComponent size={size} {...props} style={style} />;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default Icon;
|
package/src/react/index.ts
CHANGED
|
@@ -3,7 +3,11 @@ export { default as ArrowLeft } from './ArrowLeft';
|
|
|
3
3
|
export { default as ArrowUpRight } from './ArrowUpRight';
|
|
4
4
|
export { default as IconSlot } from './IconSlot';
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// Unified Icon component
|
|
7
|
+
export { default as Icon } from './Icon';
|
|
8
|
+
export type { IconName, IconProps } from './Icon';
|
|
9
|
+
|
|
10
|
+
// Export types
|
|
7
11
|
export type {
|
|
8
12
|
IconSize,
|
|
9
13
|
IconSizeToken,
|
package/src/native/ArrowLeft.tsx
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import Svg, { Path } from 'react-native-svg';
|
|
3
|
-
import type { NativeIconProps } from '../shared/types';
|
|
4
|
-
import { resolveSize } from '../shared/types';
|
|
5
|
-
|
|
6
|
-
const SvgArrowLeft = ({ size = 16, ...props }: NativeIconProps) => {
|
|
7
|
-
const sizeValue = resolveSize(size);
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<Svg width={sizeValue} height={sizeValue} viewBox="0 0 24 24" fill="none" {...props}>
|
|
11
|
-
<Path
|
|
12
|
-
fillRule="evenodd"
|
|
13
|
-
clipRule="evenodd"
|
|
14
|
-
d="M12.7071 4.29289C13.0976 4.68342 13.0976 5.31658 12.7071 5.70711L6.41421 12L12.7071 18.2929C13.0976 18.6834 13.0976 19.3166 12.7071 19.7071C12.3166 20.0976 11.6834 20.0976 11.2929 19.7071L4.29289 12.7071C3.90237 12.3166 3.90237 11.6834 4.29289 11.2929L11.2929 4.29289C11.6834 3.90237 12.3166 3.90237 12.7071 4.29289Z"
|
|
15
|
-
fill="currentColor"
|
|
16
|
-
/>
|
|
17
|
-
<Path
|
|
18
|
-
fillRule="evenodd"
|
|
19
|
-
clipRule="evenodd"
|
|
20
|
-
d="M4 12C4 11.4477 4.44772 11 5 11H19C19.5523 11 20 11.4477 20 12C20 12.5523 19.5523 13 19 13H5C4.44772 13 4 12.5523 4 12Z"
|
|
21
|
-
fill="currentColor"
|
|
22
|
-
/>
|
|
23
|
-
</Svg>
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default SvgArrowLeft;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import Svg, { Path } from 'react-native-svg';
|
|
3
|
-
import type { NativeIconProps } from '../shared/types';
|
|
4
|
-
import { resolveSize } from '../shared/types';
|
|
5
|
-
|
|
6
|
-
const SvgArrowUpRight = ({ size = 16, ...props }: NativeIconProps) => {
|
|
7
|
-
const sizeValue = resolveSize(size);
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<Svg width={sizeValue} height={sizeValue} viewBox="0 0 24 24" fill="none" {...props}>
|
|
11
|
-
<Path
|
|
12
|
-
fillRule="evenodd"
|
|
13
|
-
clipRule="evenodd"
|
|
14
|
-
d="M6 7C6 6.44772 6.44772 6 7 6H17C17.5523 6 18 6.44772 18 7V17C18 17.5523 17.5523 18 17 18C16.4477 18 16 17.5523 16 17V8H7C6.44772 8 6 7.55228 6 7Z"
|
|
15
|
-
fill="currentColor"
|
|
16
|
-
/>
|
|
17
|
-
<Path
|
|
18
|
-
fillRule="evenodd"
|
|
19
|
-
clipRule="evenodd"
|
|
20
|
-
d="M17.7071 6.29289C18.0976 6.68342 18.0976 7.31658 17.7071 7.70711L7.70711 17.7071C7.31658 18.0976 6.68342 18.0976 6.29289 17.7071C5.90237 17.3166 5.90237 16.6834 6.29289 16.2929L16.2929 6.29289C16.6834 5.90237 17.3166 5.90237 17.7071 6.29289Z"
|
|
21
|
-
fill="currentColor"
|
|
22
|
-
/>
|
|
23
|
-
</Svg>
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default SvgArrowUpRight;
|
package/src/native/IconSlot.tsx
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import Svg, { Path } from 'react-native-svg';
|
|
3
|
-
import type { NativeIconProps } from '../shared/types';
|
|
4
|
-
import { resolveSize } from '../shared/types';
|
|
5
|
-
|
|
6
|
-
const SvgIconSlot = ({ size = 16, ...props }: NativeIconProps) => {
|
|
7
|
-
const sizeValue = resolveSize(size);
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<Svg width={sizeValue} height={sizeValue} viewBox="0 0 15 15" fill="none" {...props}>
|
|
11
|
-
<Path
|
|
12
|
-
d="M13.3333 7.33333C13.3333 4.01962 10.647 1.33333 7.33333 1.33333C4.01962 1.33333 1.33333 4.01962 1.33333 7.33333C1.33333 10.647 4.01962 13.3333 7.33333 13.3333C10.647 13.3333 13.3333 10.647 13.3333 7.33333ZM14.6667 7.33333C14.6667 11.3834 11.3834 14.6667 7.33333 14.6667C3.28325 14.6667 0 11.3834 0 7.33333C0 3.28325 3.28325 0 7.33333 0C11.3834 0 14.6667 3.28325 14.6667 7.33333Z"
|
|
13
|
-
fill="currentColor"
|
|
14
|
-
/>
|
|
15
|
-
</Svg>
|
|
16
|
-
);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default SvgIconSlot;
|
package/src/native/index.tsx
DELETED