-
+
diff --git a/app/portainer/oauth/components/oauth-providers-selector/oauth-options.tsx b/app/portainer/oauth/components/oauth-providers-selector/oauth-options.tsx
index 38f9a5197..8bfc61df8 100644
--- a/app/portainer/oauth/components/oauth-providers-selector/oauth-options.tsx
+++ b/app/portainer/oauth/components/oauth-providers-selector/oauth-options.tsx
@@ -5,7 +5,7 @@ import Microsoft from '@/assets/ico/vendor/microsoft.svg?c';
import Google from '@/assets/ico/vendor/google.svg?c';
import Github from '@/assets/ico/vendor/github.svg?c';
-import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
export const options = [
{
diff --git a/app/portainer/react/components/index.ts b/app/portainer/react/components/index.ts
index 17e28fd3e..fd11fb321 100644
--- a/app/portainer/react/components/index.ts
+++ b/app/portainer/react/components/index.ts
@@ -30,7 +30,7 @@ import { TableColumnHeaderAngular } from '@@/datatables/TableHeaderCell';
import { DashboardItem } from '@@/DashboardItem';
import { SearchBar } from '@@/datatables/SearchBar';
import { FallbackImage } from '@@/FallbackImage';
-import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
import { TeamsSelector } from '@@/TeamsSelector';
import { PortainerSelect } from '@@/form-components/PortainerSelect';
@@ -88,8 +88,6 @@ export const componentsModule = angular
'alt',
'size',
'className',
- 'fallbackMode',
- 'fallbackClassName',
'feather',
])
)
@@ -106,7 +104,7 @@ export const componentsModule = angular
'datatableSearchbar',
r2a(SearchBar, ['data-cy', 'onChange', 'value', 'placeholder'])
)
- .component('boxSelectorBadgeIcon', r2a(BadgeIcon, ['featherIcon', 'icon']))
+ .component('badgeIcon', r2a(BadgeIcon, ['featherIcon', 'icon', 'size']))
.component(
'accessControlPanel',
r2a(withUIRouter(withReactQuery(withCurrentUser(AccessControlPanel))), [
diff --git a/app/portainer/settings/authentication/ldap/ldap-settings/ldap-options.tsx b/app/portainer/settings/authentication/ldap/ldap-settings/ldap-options.tsx
index 9b381bda3..6b44625f6 100644
--- a/app/portainer/settings/authentication/ldap/ldap-settings/ldap-options.tsx
+++ b/app/portainer/settings/authentication/ldap/ldap-settings/ldap-options.tsx
@@ -3,7 +3,7 @@ import { Edit } from 'react-feather';
import { FeatureId } from '@/portainer/feature-flags/enums';
import Openldap from '@/assets/ico/vendor/openldap.svg?c';
-import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
const SERVER_TYPES = {
CUSTOM: 0,
diff --git a/app/portainer/views/registries/create/options.tsx b/app/portainer/views/registries/create/options.tsx
index e1045c0db..ddf7bd9b5 100644
--- a/app/portainer/views/registries/create/options.tsx
+++ b/app/portainer/views/registries/create/options.tsx
@@ -7,7 +7,7 @@ import Proget from '@/assets/ico/vendor/proget.svg?c';
import Azure from '@/assets/ico/vendor/azure.svg?c';
import Gitlab from '@/assets/ico/vendor/gitlab.svg?c';
-import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
export const options = [
{
diff --git a/app/portainer/views/settings/authentication/options.tsx b/app/portainer/views/settings/authentication/options.tsx
index 08f024cd9..01141cf2e 100644
--- a/app/portainer/views/settings/authentication/options.tsx
+++ b/app/portainer/views/settings/authentication/options.tsx
@@ -5,7 +5,7 @@ import Microsoft from '@/assets/ico/vendor/microsoft.svg?c';
import Ldap from '@/assets/ico/ldap.svg?c';
import OAuth from '@/assets/ico/oauth.svg?c';
-import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
export const options = [
{
diff --git a/app/portainer/views/settings/options.tsx b/app/portainer/views/settings/options.tsx
index 6cf2c413d..45fc6e3b7 100644
--- a/app/portainer/views/settings/options.tsx
+++ b/app/portainer/views/settings/options.tsx
@@ -2,7 +2,7 @@ import { DownloadCloud, UploadCloud } from 'react-feather';
import { FeatureId } from '@/portainer/feature-flags/enums';
-import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
export const options = [
{
diff --git a/app/react/components/BadgeIcon/Badge.stories.tsx b/app/react/components/BadgeIcon/Badge.stories.tsx
new file mode 100644
index 000000000..4a1b428d5
--- /dev/null
+++ b/app/react/components/BadgeIcon/Badge.stories.tsx
@@ -0,0 +1,35 @@
+import { Meta } from '@storybook/react';
+
+import { BadgeIcon, BadgeSize, Props } from './BadgeIcon';
+
+export default {
+ component: BadgeIcon,
+ title: 'Components/BadgeIcon',
+ argTypes: {
+ size: {
+ control: {
+ type: 'select',
+ options: ['md', 'lg', 'xl', '2xl', '3xl'],
+ },
+ },
+ icon: {
+ control: {
+ type: 'select',
+ options: ['edit', 'info', 'smile', 'users'],
+ },
+ },
+ },
+} as Meta
;
+
+// : JSX.IntrinsicAttributes & PropsWithChildren
+function Template({
+ size = '3xl',
+ icon = 'edit',
+}: {
+ size?: BadgeSize;
+ icon: string;
+}) {
+ return ;
+}
+
+export const Example = Template.bind({});
diff --git a/app/react/components/BadgeIcon/BadgeIcon.tsx b/app/react/components/BadgeIcon/BadgeIcon.tsx
new file mode 100644
index 000000000..83b198bcc
--- /dev/null
+++ b/app/react/components/BadgeIcon/BadgeIcon.tsx
@@ -0,0 +1,45 @@
+import clsx from 'clsx';
+
+import { Icon, IconProps } from '@@/Icon';
+
+export type BadgeSize = 'md' | 'lg' | 'xl' | '2xl' | '3xl';
+
+export interface Props extends IconProps {
+ size?: BadgeSize;
+}
+
+export function BadgeIcon({ icon, featherIcon, size = '3xl' }: Props) {
+ const sizeClasses = iconSizeToClasses(size);
+ return (
+
+
+
+ );
+}
+
+function iconSizeToClasses(size: BadgeSize) {
+ switch (size) {
+ case 'md':
+ return 'h-6 w-6 text-md';
+ case 'lg':
+ return 'h-8 w-8 text-lg';
+ case 'xl':
+ return 'h-10 w-10 text-xl';
+ case '2xl':
+ return 'h-12 w-12 text-2xl';
+ case '3xl':
+ return 'h-14 w-14 text-3xl';
+ default:
+ return 'h-14 w-14 text-3xl';
+ }
+}
diff --git a/app/react/components/BadgeIcon/index.ts b/app/react/components/BadgeIcon/index.ts
new file mode 100644
index 000000000..e0138de42
--- /dev/null
+++ b/app/react/components/BadgeIcon/index.ts
@@ -0,0 +1 @@
+export { BadgeIcon } from './BadgeIcon';
diff --git a/app/react/components/BoxSelector/BadgeIcon.tsx b/app/react/components/BoxSelector/BadgeIcon.tsx
deleted file mode 100644
index 1e3818964..000000000
--- a/app/react/components/BoxSelector/BadgeIcon.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Icon, IconProps } from '@@/Icon';
-
-type Props = IconProps;
-
-export function BadgeIcon({ icon, featherIcon }: Props) {
- return (
-
-
-
- );
-}
diff --git a/app/react/components/BoxSelector/common-options/build-methods.tsx b/app/react/components/BoxSelector/common-options/build-methods.tsx
index 7c6f267d7..4b3dc96d3 100644
--- a/app/react/components/BoxSelector/common-options/build-methods.tsx
+++ b/app/react/components/BoxSelector/common-options/build-methods.tsx
@@ -2,7 +2,8 @@ import { Edit, FileText, Globe, Upload } from 'react-feather';
import GitIcon from '@/assets/ico/git.svg?c';
-import { BadgeIcon } from '../BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
+
import { BoxSelectorOption } from '../types';
export const editor: BoxSelectorOption<'editor'> = {
diff --git a/app/react/components/FallbackImage.tsx b/app/react/components/FallbackImage.tsx
index 1e11c294d..a48cd491b 100644
--- a/app/react/components/FallbackImage.tsx
+++ b/app/react/components/FallbackImage.tsx
@@ -1,18 +1,15 @@
-import clsx from 'clsx';
import { useEffect, useState } from 'react';
-import { Icon, IconMode, IconSize } from './Icon';
+import { BadgeIcon, BadgeSize } from './BadgeIcon/BadgeIcon';
interface Props {
// props for the image to load
src: string; // a link to an external image
fallbackIcon: string;
alt?: string;
- size?: IconSize;
+ size?: BadgeSize;
className?: string;
- // additional fallback icon props
- fallbackMode?: IconMode;
- fallbackClassName?: string;
+ // additional fallback badge props
feather?: boolean;
}
@@ -22,22 +19,18 @@ export function FallbackImage({
alt,
size,
className,
- fallbackMode,
- fallbackClassName,
feather,
}: Props) {
const [error, setError] = useState(false);
- const classes = clsx(className, { [`icon-${size}`]: size });
-
useEffect(() => {
setError(false);
}, [src]);
- if (!error) {
+ if (!error && src) {
return (
setError(true)}
@@ -46,13 +39,5 @@ export function FallbackImage({
}
// fallback icon if there is an error loading the image
- return (
-
- );
+ return ;
}
diff --git a/app/react/portainer/access-control/EditDetails/useOptions.tsx b/app/react/portainer/access-control/EditDetails/useOptions.tsx
index 3f8289fdc..5a04c618a 100644
--- a/app/react/portainer/access-control/EditDetails/useOptions.tsx
+++ b/app/react/portainer/access-control/EditDetails/useOptions.tsx
@@ -6,7 +6,7 @@ import { ownershipIcon } from '@/portainer/filters/filters';
import { Team } from '@/react/portainer/users/teams/types';
import { BoxSelectorOption } from '@@/BoxSelector/types';
-import { BadgeIcon } from '@@/BoxSelector/BadgeIcon';
+import { BadgeIcon } from '@@/BadgeIcon';
import { ResourceControlOwnership } from '../types';