- {k}
-
- {hex}
+ Theme Colors
+
+
+
+
+ Category
+
+ {tones.map(tone => (
+
+ {tone}
+
+ ))}
+
+
+
+ {colorTypes.map(category => (
+
+
+ {category}
-
+ {tones.map(tone => {
+ const color = colors[category][tone];
+ return (
+
+ {color ? {color} : '-'}
+
+ );
+ })}
- );
- })}
+ ))}
+
+
+ text.label: {colors.text.label}
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat.
+
+
+ text.help: {colors.text.help}
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat.
+
+ The supersetTheme object
+
+ {JSON.stringify(supersetTheme, null, 2)}
+
- ));
+ );
};
diff --git a/superset-frontend/src/components/AlteredSliceTag/index.tsx b/superset-frontend/src/components/AlteredSliceTag/index.tsx
index bd16d1c28..9aca6b46b 100644
--- a/superset-frontend/src/components/AlteredSliceTag/index.tsx
+++ b/superset-frontend/src/components/AlteredSliceTag/index.tsx
@@ -19,9 +19,11 @@
import { useCallback, useEffect, useMemo, useState, FC } from 'react';
import { isEqual, isEmpty } from 'lodash';
-import { QueryFormData, styled, t } from '@superset-ui/core';
+import { QueryFormData, t } from '@superset-ui/core';
import { sanitizeFormData } from 'src/explore/exploreUtils/formData';
import getControlsForVizType from 'src/utils/getControlsForVizType';
+import Label from 'src/components/Label';
+import Icons from 'src/components/Icons';
import { safeStringify } from 'src/utils/safeStringify';
import { Tooltip } from 'src/components/Tooltip';
import ModalTrigger from '../ModalTrigger';
@@ -68,18 +70,6 @@ export type RowType = {
control: string;
};
-const StyledLabel = styled.span`
- ${({ theme }) => `
- font-size: ${theme.typography.sizes.s}px;
- color: ${theme.colors.grayscale.dark1};
- background-color: ${theme.colors.alert.base};
-
- &:hover {
- background-color: ${theme.colors.alert.dark1};
- }
- `}
-`;
-
export const alterForComparison = (
value?: string | null | [],
): string | null => {
@@ -228,7 +218,14 @@ const AlteredSliceTag: FC = props => {
const triggerNode = useMemo(
() => (
- {t('Altered')}
+ }
+ className="label"
+ type="alert"
+ onClick={() => {}}
+ >
+ {t('Altered')}
+
),
[],
diff --git a/superset-frontend/src/components/Icons/Icon.tsx b/superset-frontend/src/components/Icons/Icon.tsx
index b2e7dbfdc..39e562723 100644
--- a/superset-frontend/src/components/Icons/Icon.tsx
+++ b/superset-frontend/src/components/Icons/Icon.tsx
@@ -36,6 +36,10 @@ const AntdIconComponent = ({
export const StyledIcon = styled(AntdIconComponent)`
${({ iconColor }) => iconColor && `color: ${iconColor};`};
+ span {
+ // Fixing alignement on some of the icons
+ line-height: 0px;
+ }
font-size: ${({ iconSize, theme }) =>
iconSize
? `${theme.typography.sizes[iconSize] || theme.typography.sizes.m}px`
diff --git a/superset-frontend/src/components/Label/Label.stories.tsx b/superset-frontend/src/components/Label/Label.stories.tsx
index 5c4618246..20225811d 100644
--- a/superset-frontend/src/components/Label/Label.stories.tsx
+++ b/superset-frontend/src/components/Label/Label.stories.tsx
@@ -17,14 +17,17 @@
* under the License.
*/
import { action } from '@storybook/addon-actions';
-import Label, { Type } from './index';
+import { Meta, StoryFn } from '@storybook/react';
+import Label, { Type, DatasetTypeLabel, PublishedLabel } from './index';
+// Define the default export with Storybook configuration
export default {
title: 'Label',
component: Label,
- excludeStories: 'options',
-};
+ excludeStories: ['options'],
+} as Meta;
+// Explicitly type the options array as an array of `Type`
export const options: Type[] = [
'default',
'alert',
@@ -36,39 +39,60 @@ export const options: Type[] = [
'secondary',
];
-export const LabelGallery = () => (
- <>
- Non-interactive
- {Object.values(options).map((opt: Type) => (
-
- {`style: "${opt}"`}
-
- ))}
-
- Interactive
- {Object.values(options).map((opt: Type) => (
-
- {`style: "${opt}"`}
-
- ))}
- >
-);
+// Define the props for the `LabelGallery` component
+interface LabelGalleryProps {
+ hasOnClick?: boolean;
+ monospace?: boolean;
+}
+
+// Use the `StoryFn` type for LabelGallery
+export const LabelGallery: StoryFn = (
+ props: LabelGalleryProps,
+) => {
+ const onClick = props.hasOnClick ? action('clicked') : undefined;
-export const InteractiveLabel = (args: any) => {
- const { hasOnClick, label, monospace, ...rest } = args;
return (
-
- {label}
-
+ <>
+ Non-interactive
+ {options.map((opt: Type) => (
+
+ {`style: "${opt}"`}
+
+ ))}
+
+ Interactive
+ {options.map((opt: Type) => (
+
+ {`style: "${opt}"`}
+
+ ))}
+ Reusable Labels
+ DatasetType
+
+
+
+
+ PublishedLabel
+
+
+ >
);
};
-InteractiveLabel.args = {
+// Define default arguments for Storybook
+LabelGallery.args = {
hasOnClick: true,
- label: 'Example',
- monospace: true,
+ monospace: false,
+};
+
+// Define argument types for Storybook controls
+LabelGallery.argTypes = {
+ monospace: {
+ name: 'monospace',
+ control: { type: 'boolean' },
+ },
+ hasOnClick: {
+ name: 'hasOnClick',
+ control: { type: 'boolean' },
+ },
};
diff --git a/superset-frontend/src/components/Label/Label.test.tsx b/superset-frontend/src/components/Label/Label.test.tsx
index fdf85b9c9..ac57250bc 100644
--- a/superset-frontend/src/components/Label/Label.test.tsx
+++ b/superset-frontend/src/components/Label/Label.test.tsx
@@ -37,7 +37,9 @@ test('works with an onClick handler', () => {
// test stories from the storybook!
test('renders all the storybook gallery variants', () => {
const { container } = render( );
+ const nonInteractiveLabelCount = 4;
+ const renderedLabelCount = options.length * 2 + nonInteractiveLabelCount;
expect(container.querySelectorAll('.ant-tag')).toHaveLength(
- options.length * 2,
+ renderedLabelCount,
);
});
diff --git a/superset-frontend/src/components/Label/index.tsx b/superset-frontend/src/components/Label/index.tsx
index d904a445b..b74508407 100644
--- a/superset-frontend/src/components/Label/index.tsx
+++ b/superset-frontend/src/components/Label/index.tsx
@@ -25,6 +25,8 @@ import {
import { Tag } from 'src/components';
import { useTheme } from '@superset-ui/core';
+import DatasetTypeLabel from 'src/components/Label/reusable/DatasetTypeLabel';
+import PublishedLabel from 'src/components/Label/reusable/PublishedLabel';
export type OnClickHandler = MouseEventHandler;
@@ -47,6 +49,7 @@ export interface LabelProps extends HTMLAttributes {
children?: ReactNode;
role?: string;
monospace?: boolean;
+ icon?: ReactNode;
}
export default function Label(props: LabelProps) {
@@ -58,6 +61,7 @@ export default function Label(props: LabelProps) {
style,
onClick,
children,
+ icon,
...rest
} = props;
const {
@@ -71,37 +75,44 @@ export default function Label(props: LabelProps) {
info,
} = colors;
- let backgroundColor = grayscale.light3;
- let backgroundColorHover = onClick ? primary.light2 : grayscale.light3;
- let borderColor = onClick ? grayscale.light2 : 'transparent';
- let borderColorHover = onClick ? primary.light1 : 'transparent';
- let color = grayscale.dark1;
-
- if (type !== 'default') {
- color = grayscale.light4;
-
- let baseColor;
- if (type === 'alert') {
- color = grayscale.dark1;
- baseColor = alert;
- } else if (type === 'success') {
- baseColor = success;
- } else if (type === 'warning') {
- baseColor = warning;
- } else if (type === 'danger') {
- baseColor = error;
- } else if (type === 'info') {
- baseColor = info;
- } else if (type === 'secondary') {
- baseColor = secondary;
- } else {
- baseColor = primary;
- }
- backgroundColor = baseColor.base;
- backgroundColorHover = onClick ? baseColor.dark1 : baseColor.base;
- borderColor = onClick ? baseColor.dark1 : 'transparent';
- borderColorHover = onClick ? baseColor.dark2 : 'transparent';
+ let baseColor;
+ if (type === 'primary') {
+ baseColor = primary;
+ } else if (type === 'secondary') {
+ baseColor = secondary;
+ } else if (type === 'success') {
+ baseColor = success;
+ } else if (type === 'alert') {
+ baseColor = alert;
+ } else if (type === 'warning') {
+ baseColor = warning;
+ } else if (type === 'danger') {
+ baseColor = error;
+ } else if (type === 'info') {
+ baseColor = info;
+ } else {
+ baseColor = grayscale;
}
+ const color = baseColor.dark2;
+ let borderColor = baseColor.light1;
+ let backgroundColor = baseColor.light2;
+
+ // TODO - REMOVE IF BLOCK LOGIC WHEN shades are fixed to be aligned in terms of brightness
+ // currently shades for >=light2 are not aligned for primary, default and secondary
+ if (['default', 'primary', 'secondary'].includes(type)) {
+ // @ts-ignore
+ backgroundColor = baseColor.light4;
+ borderColor = baseColor.light2;
+ }
+
+ const backgroundColorHover = onClick ? baseColor.light1 : backgroundColor;
+ const borderColorHover = onClick ? baseColor.base : borderColor;
+
+ if (type === 'default') {
+ // Lighter for default
+ backgroundColor = grayscale.light3;
+ }
+
const css = {
transition: `background-color ${transitionTiming}s`,
whiteSpace: 'nowrap',
@@ -109,11 +120,14 @@ export default function Label(props: LabelProps) {
overflow: 'hidden',
textOverflow: 'ellipsis',
backgroundColor,
+ borderRadius: 8,
borderColor,
- borderRadius: 21,
padding: '0.35em 0.8em',
lineHeight: 1,
color,
+ display: 'inline-flex',
+ verticalAlign: 'middle',
+ alignItems: 'center',
maxWidth: '100%',
'&:hover': {
backgroundColor: backgroundColorHover,
@@ -124,12 +138,12 @@ export default function Label(props: LabelProps) {
if (monospace) {
css['font-family'] = theme.typography.families.monospace;
}
-
return (
@@ -137,3 +151,4 @@ export default function Label(props: LabelProps) {
);
}
+export { DatasetTypeLabel, PublishedLabel };
diff --git a/superset-frontend/src/components/Label/reusable/DatasetTypeLabel.tsx b/superset-frontend/src/components/Label/reusable/DatasetTypeLabel.tsx
new file mode 100644
index 000000000..737966558
--- /dev/null
+++ b/superset-frontend/src/components/Label/reusable/DatasetTypeLabel.tsx
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import Icons from 'src/components/Icons';
+import Label from 'src/components/Label';
+import { t } from '@superset-ui/core';
+
+// Define the prop types for DatasetTypeLabel
+interface DatasetTypeLabelProps {
+ datasetType: 'physical' | 'virtual'; // Accepts only 'physical' or 'virtual'
+}
+
+const SIZE = 's'; // Define the size as a constant
+
+const DatasetTypeLabel: React.FC = ({ datasetType }) => {
+ const label: string =
+ datasetType === 'physical' ? t('Physical') : t('Virtual');
+ const icon =
+ datasetType === 'physical' ? (
+
+ ) : (
+
+ );
+ const labelType: 'primary' | 'secondary' =
+ datasetType === 'physical' ? 'primary' : 'secondary';
+
+ return (
+
+ {label}
+
+ );
+};
+
+export default DatasetTypeLabel;
diff --git a/superset-frontend/src/components/Label/reusable/PublishedLabel.tsx b/superset-frontend/src/components/Label/reusable/PublishedLabel.tsx
new file mode 100644
index 000000000..a73be8609
--- /dev/null
+++ b/superset-frontend/src/components/Label/reusable/PublishedLabel.tsx
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import Icons from 'src/components/Icons';
+import Label from 'src/components/Label';
+import { t } from '@superset-ui/core';
+
+// Define props for the PublishedLabel component
+interface PublishedLabelProps {
+ isPublished: boolean; // Whether the item is published
+ onClick?: () => void; // Optional click handler
+}
+
+const PublishedLabel: React.FC = ({
+ isPublished,
+ onClick,
+}) => {
+ const label = isPublished ? t('Published') : t('Draft');
+ const icon = isPublished ? (
+
+ ) : (
+
+ );
+ const labelType = isPublished ? 'primary' : 'secondary';
+
+ return (
+
+ {label}
+
+ );
+};
+
+export default PublishedLabel;
diff --git a/superset-frontend/src/components/Timer/index.tsx b/superset-frontend/src/components/Timer/index.tsx
index 4237c9f1e..f0ae3cf05 100644
--- a/superset-frontend/src/components/Timer/index.tsx
+++ b/superset-frontend/src/components/Timer/index.tsx
@@ -19,6 +19,7 @@
import { useEffect, useRef, useState } from 'react';
import { styled } from '@superset-ui/core';
import Label, { Type } from 'src/components/Label';
+import Icons from 'src/components/Icons';
import { now, fDuration } from 'src/utils/dates';
@@ -68,7 +69,7 @@ export default function Timer({
}, [endTime, isRunning, startTime]);
return (
-
+ } type={status} role="timer">
{clockStr}
);
diff --git a/superset-frontend/src/dashboard/components/PublishedStatus/index.tsx b/superset-frontend/src/dashboard/components/PublishedStatus/index.tsx
index 3fdb0de11..29fb30484 100644
--- a/superset-frontend/src/dashboard/components/PublishedStatus/index.tsx
+++ b/superset-frontend/src/dashboard/components/PublishedStatus/index.tsx
@@ -19,7 +19,7 @@
import { Component } from 'react';
import { t } from '@superset-ui/core';
import { Tooltip } from 'src/components/Tooltip';
-import Label from 'src/components/Label';
+import { PublishedLabel } from 'src/components/Label';
import { HeaderProps, HeaderDropdownProps } from '../Header/types';
export type DashboardPublishedStatusType = {
@@ -67,13 +67,12 @@ export default class PublishedStatus extends Component
- {
- this.togglePublished();
- }}
- >
- {t('Draft')}
-
+
);
}
@@ -83,7 +82,9 @@ export default class PublishedStatus extends Component
- {t('Draft')}
+
);
}
@@ -96,13 +97,12 @@ export default class PublishedStatus extends Component
- {
- this.togglePublished();
- }}
- >
- {t('Published')}
-
+
);
}
diff --git a/superset-frontend/src/pages/DashboardList/index.tsx b/superset-frontend/src/pages/DashboardList/index.tsx
index 361168f41..93d290408 100644
--- a/superset-frontend/src/pages/DashboardList/index.tsx
+++ b/superset-frontend/src/pages/DashboardList/index.tsx
@@ -34,6 +34,7 @@ import {
} from 'src/views/CRUD/utils';
import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks';
import ConfirmStatusChange from 'src/components/ConfirmStatusChange';
+import { PublishedLabel } from 'src/components/Label';
import { TagsList } from 'src/components/Tags';
import handleResourceExport from 'src/utils/export';
import Loading from 'src/components/Loading';
@@ -343,8 +344,9 @@ function DashboardList(props: DashboardListProps) {
row: {
original: { status },
},
- }: any) =>
- status === DashboardStatus.PUBLISHED ? t('Published') : t('Draft'),
+ }: any) => (
+
+ ),
Header: t('Status'),
accessor: 'published',
size: 'xl',
diff --git a/superset-frontend/src/pages/DatasetList/index.tsx b/superset-frontend/src/pages/DatasetList/index.tsx
index d90f60c59..49af61753 100644
--- a/superset-frontend/src/pages/DatasetList/index.tsx
+++ b/superset-frontend/src/pages/DatasetList/index.tsx
@@ -41,6 +41,7 @@ import ListView, {
Filters,
FilterOperator,
} from 'src/components/ListView';
+import { DatasetTypeLabel } from 'src/components/Label';
import Loading from 'src/components/Loading';
import SubMenu, { SubMenuProps, ButtonProps } from 'src/features/home/SubMenu';
import Owner from 'src/types/Owner';
@@ -279,24 +280,7 @@ const DatasetList: FunctionComponent = ({
row: {
original: { kind },
},
- }: any) => {
- if (kind === 'physical') {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
- );
- },
+ }: any) => null,
accessor: 'kind_icon',
disableSortBy: true,
size: 'xs',
@@ -360,7 +344,7 @@ const DatasetList: FunctionComponent = ({
row: {
original: { kind },
},
- }: any) => (kind === 'physical' ? t('Physical') : t('Virtual')),
+ }: any) => ,
Header: t('Type'),
accessor: 'kind',
disableSortBy: true,