@brightlocal/icons 2.1.1 → 2.2.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/dist/dynamic.cjs +1 -1
- package/dist/dynamic.d.ts +2 -0
- package/dist/dynamic.d.ts.map +1 -1
- package/dist/dynamic.js +8 -6
- package/dist/flag/flag-icon.cjs +1 -0
- package/dist/flag/flag-icon.d.ts +13 -0
- package/dist/flag/flag-icon.d.ts.map +1 -0
- package/dist/flag/flag-icon.js +56 -0
- package/dist/icons/dynamic-icon.cjs +1 -1
- package/dist/icons/dynamic-icon.d.ts +5 -1
- package/dist/icons/dynamic-icon.d.ts.map +1 -1
- package/dist/icons/dynamic-icon.js +32 -21
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +790 -788
- package/package.json +1 -1
- package/src/dynamic.ts +4 -0
- package/src/flag/flag-icon.tsx +70 -0
- package/src/icons/dynamic-icon.tsx +22 -3
- package/src/index.ts +4 -0
package/package.json
CHANGED
package/src/dynamic.ts
CHANGED
|
@@ -28,3 +28,7 @@ export type { FlagIconName } from "./flag/dynamic-imports.js";
|
|
|
28
28
|
|
|
29
29
|
export { socialMediaIconNames } from "./social-media/dynamic-imports.js";
|
|
30
30
|
export type { SocialMediaIconName } from "./social-media/dynamic-imports.js";
|
|
31
|
+
|
|
32
|
+
// Higher-level flag wrapper with unknown-country fallback and loading skeleton
|
|
33
|
+
export { DynamicFlagIcon } from "./flag/flag-icon.js";
|
|
34
|
+
export type { DynamicFlagIconProps } from "./flag/flag-icon.js";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { DynamicIcon } from "../icons/dynamic-icon.js";
|
|
4
|
+
import { flagIconNames, type FlagIconName } from "./dynamic-imports.js";
|
|
5
|
+
import { Globe } from "../icons/lucide-exports.js";
|
|
6
|
+
|
|
7
|
+
export interface DynamicFlagIconProps
|
|
8
|
+
extends React.ComponentProps<"span"> {
|
|
9
|
+
/** ISO 3166-1 alpha-3 country code (e.g. "USA", "GBR") */
|
|
10
|
+
country: string;
|
|
11
|
+
/**
|
|
12
|
+
* Icon size in pixels (width and height)
|
|
13
|
+
* @default 20
|
|
14
|
+
*/
|
|
15
|
+
size?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const flagIconNameSet = new Set<string>(flagIconNames);
|
|
19
|
+
|
|
20
|
+
const DynamicFlagIcon = React.forwardRef<HTMLSpanElement, DynamicFlagIconProps>(
|
|
21
|
+
({ country, size = 20, className, style, ...props }, ref) => {
|
|
22
|
+
const isKnown = flagIconNameSet.has(country);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<span
|
|
26
|
+
ref={ref}
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
className={className}
|
|
29
|
+
data-slot="flag-icon"
|
|
30
|
+
style={{
|
|
31
|
+
display: "inline-flex",
|
|
32
|
+
alignItems: "center",
|
|
33
|
+
justifyContent: "center",
|
|
34
|
+
flexShrink: 0,
|
|
35
|
+
width: size,
|
|
36
|
+
height: size,
|
|
37
|
+
...style,
|
|
38
|
+
}}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{isKnown ? (
|
|
42
|
+
<DynamicIcon
|
|
43
|
+
name={country as FlagIconName}
|
|
44
|
+
size={size}
|
|
45
|
+
/>
|
|
46
|
+
) : (
|
|
47
|
+
<span
|
|
48
|
+
data-slot="flag-icon-fallback"
|
|
49
|
+
style={{
|
|
50
|
+
display: "inline-flex",
|
|
51
|
+
alignItems: "center",
|
|
52
|
+
justifyContent: "center",
|
|
53
|
+
width: size,
|
|
54
|
+
height: size,
|
|
55
|
+
borderRadius: "9999px",
|
|
56
|
+
backgroundColor: "var(--color-muted, #f3f4f6)",
|
|
57
|
+
color: "var(--color-muted-foreground, #6b7280)",
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
<Globe size={Math.round(size * 0.65)} />
|
|
61
|
+
</span>
|
|
62
|
+
)}
|
|
63
|
+
</span>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
DynamicFlagIcon.displayName = "DynamicFlagIcon";
|
|
69
|
+
|
|
70
|
+
export { DynamicFlagIcon };
|
|
@@ -37,7 +37,7 @@ export interface DynamicIconProps extends React.ComponentProps<"svg"> {
|
|
|
37
37
|
absoluteStrokeWidth?: boolean;
|
|
38
38
|
/**
|
|
39
39
|
* Fallback content displayed while the icon is loading.
|
|
40
|
-
*
|
|
40
|
+
* Defaults to an invisible placeholder that matches the icon's dimensions to prevent layout shift.
|
|
41
41
|
*/
|
|
42
42
|
fallback?: React.ReactNode;
|
|
43
43
|
}
|
|
@@ -85,6 +85,10 @@ for (const [name, loader] of Object.entries(iconImports)) {
|
|
|
85
85
|
* <DynamicIcon name="camera" size={24} fallback={<Skeleton />} />
|
|
86
86
|
*
|
|
87
87
|
* @example
|
|
88
|
+
* // Opt out of default placeholder
|
|
89
|
+
* <DynamicIcon name="camera" size={24} fallback={null} />
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
88
92
|
* // Database-driven
|
|
89
93
|
* <DynamicIcon name={country.iso} size={16} />
|
|
90
94
|
*/
|
|
@@ -95,7 +99,7 @@ export const DynamicIcon = React.forwardRef<SVGSVGElement, DynamicIconProps>(
|
|
|
95
99
|
size = 16,
|
|
96
100
|
strokeWidth = 1.33,
|
|
97
101
|
absoluteStrokeWidth = true,
|
|
98
|
-
fallback
|
|
102
|
+
fallback,
|
|
99
103
|
...props
|
|
100
104
|
},
|
|
101
105
|
ref
|
|
@@ -114,8 +118,23 @@ export const DynamicIcon = React.forwardRef<SVGSVGElement, DynamicIconProps>(
|
|
|
114
118
|
? { ref, size, strokeWidth, absoluteStrokeWidth, ...props }
|
|
115
119
|
: { ref, size, ...props };
|
|
116
120
|
|
|
121
|
+
const placeholder =
|
|
122
|
+
fallback !== undefined ? (
|
|
123
|
+
fallback
|
|
124
|
+
) : (
|
|
125
|
+
<span
|
|
126
|
+
aria-hidden="true"
|
|
127
|
+
style={{
|
|
128
|
+
display: "inline-block",
|
|
129
|
+
width: size,
|
|
130
|
+
height: size,
|
|
131
|
+
flexShrink: 0,
|
|
132
|
+
}}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
|
|
117
136
|
return (
|
|
118
|
-
<React.Suspense fallback={
|
|
137
|
+
<React.Suspense fallback={placeholder}>
|
|
119
138
|
<Icon {...iconProps} />
|
|
120
139
|
</React.Suspense>
|
|
121
140
|
);
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,10 @@ export * from "./icons/lucide-exports.js";
|
|
|
11
11
|
export { createLucideIcon } from "lucide-react";
|
|
12
12
|
export type { IconNode, LucideProps } from "lucide-react";
|
|
13
13
|
|
|
14
|
+
// Higher-level flag wrapper with unknown-country fallback and loading skeleton
|
|
15
|
+
export { DynamicFlagIcon } from "./flag/flag-icon.js";
|
|
16
|
+
export type { DynamicFlagIconProps } from "./flag/flag-icon.js";
|
|
17
|
+
|
|
14
18
|
// Flag icons - Full list available via barrel exports
|
|
15
19
|
// All icons are React SVG components with proper fill colors
|
|
16
20
|
export * from "./flag/index.js";
|