From 2167c9c8dc9be73b3b7b35997116e52530425200 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Fri, 20 Dec 2024 09:12:55 -0800 Subject: [PATCH 01/52] feat: messing with the theme --- superset-frontend/.eslintrc.js | 2 +- superset-frontend/.prettierignore | 2 + superset-frontend/.storybook/preview.jsx | 8 +- superset-frontend/.storybook/storybook.css | 1 - superset-frontend/package.json | 3 + .../plugin-chart/templates/src/MyChart.erb | 2 +- .../chart/components/FallbackComponent.tsx | 2 +- .../chart/components/NoResultsComponent.tsx | 2 +- .../packages/superset-ui-core/src/index.ts | 2 +- .../superset-ui-core/src/style/index.tsx | 173 ---- .../superset-ui-core/src/theme/Theme.ts | 448 +++++++++ .../superset-ui-core/src/theme/index.tsx | 69 ++ .../components/FallbackComponent.test.tsx | 2 +- .../components/NoResultsComponent.test.tsx | 2 +- .../test/style/index.test.tsx | 8 - .../superset-ui-theme/Theme.stories.tsx | 268 ++++++ .../BigNumberPeriodOverPeriod/PopKPI.tsx | 4 +- .../src/chart/WordCloud.tsx | 2 +- superset-frontend/scripts/compileLess.ts | 69 ++ .../components/AceEditorWrapper/index.tsx | 30 +- .../src/SqlLab/components/App/index.tsx | 2 +- .../src/SqlLab/components/SqlEditor/index.tsx | 2 +- .../src/assets/stylesheets/antd/index.less | 102 ++- .../assets/stylesheets/antd/index.less.hbs | 121 +++ .../less/cosmo/bootswatch.less.hbs | 509 +++++++++++ .../stylesheets/less/cosmo/variables.less | 6 +- .../stylesheets/less/cosmo/variables.less.hbs | 851 ++++++++++++++++++ .../assets/stylesheets/less/fonts.less.hbs} | 40 +- .../stylesheets/less/index.less.hbs} | 34 +- .../assets/stylesheets/less/variables.less | 106 +-- .../stylesheets/less/variables.less.hbs | 212 +++++ .../stylesheets/reactable-pagination.less.hbs | 61 ++ .../src/assets/stylesheets/superset.less.hbs | 552 ++++++++++++ .../DatePicker/DatePicker.stories.tsx | 8 +- .../src/components/Form/FormLabel.tsx | 4 +- .../src/components/Icons/Icons.stories.tsx | 8 +- .../src/components/Input/Input.stories.tsx | 15 +- .../src/components/Layout/index.tsx | 2 + .../src/components/ListViewCard/index.tsx | 3 +- .../src/components/Menu/index.tsx | 5 +- .../src/components/Modal/Modal.tsx | 1 + .../PageHeaderWithActions/index.tsx | 2 +- .../src/components/TableCollection/index.tsx | 4 +- .../src/components/Tabs/Tabs.tsx | 4 - .../src/components/Tooltip/Tooltip.test.tsx | 13 - .../DashboardBuilder/DashboardBuilder.tsx | 6 +- .../DashboardBuilder/DashboardWrapper.tsx | 4 +- .../components/gridComponents/Tabs.jsx | 2 +- .../DataTablesPane/DataTablesPane.tsx | 2 +- .../components/DatasourcePanel/index.tsx | 1 - .../components/ExploreViewContainer/index.jsx | 5 +- .../RowCountLabel/RowCountLabel.test.tsx | 1 - .../controls/DatasourceControl/index.jsx | 1 - .../controls/OptionControls/index.tsx | 5 +- .../features/annotations/AnnotationModal.tsx | 3 +- superset-frontend/src/features/home/Menu.tsx | 5 +- .../src/features/home/SubMenu.tsx | 2 +- superset-frontend/src/preamble.ts | 8 +- superset-frontend/src/theme/light.ts | 119 --- superset-frontend/src/views/App.tsx | 25 +- .../src/views/RootContextProviders.tsx | 6 +- superset-frontend/src/views/menu.tsx | 2 +- superset-frontend/tsconfig.json | 1 + superset-frontend/webpack.config.js | 1 + 64 files changed, 3463 insertions(+), 502 deletions(-) delete mode 100644 superset-frontend/packages/superset-ui-core/src/style/index.tsx create mode 100644 superset-frontend/packages/superset-ui-core/src/theme/Theme.ts create mode 100644 superset-frontend/packages/superset-ui-core/src/theme/index.tsx create mode 100644 superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-theme/Theme.stories.tsx create mode 100644 superset-frontend/scripts/compileLess.ts create mode 100644 superset-frontend/src/assets/stylesheets/antd/index.less.hbs create mode 100644 superset-frontend/src/assets/stylesheets/less/cosmo/bootswatch.less.hbs create mode 100644 superset-frontend/src/assets/stylesheets/less/cosmo/variables.less.hbs rename superset-frontend/{packages/superset-ui-demo/storybook/stories/superset-ui-style/Theme.stories.tsx => src/assets/stylesheets/less/fonts.less.hbs} (53%) rename superset-frontend/src/{components/AntdThemeProvider/index.tsx => assets/stylesheets/less/index.less.hbs} (62%) create mode 100644 superset-frontend/src/assets/stylesheets/less/variables.less.hbs create mode 100644 superset-frontend/src/assets/stylesheets/reactable-pagination.less.hbs create mode 100644 superset-frontend/src/assets/stylesheets/superset.less.hbs create mode 100644 superset-frontend/src/components/Layout/index.tsx delete mode 100644 superset-frontend/src/theme/light.ts diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js index 9777651427545..72f09d1c0ad38 100644 --- a/superset-frontend/.eslintrc.js +++ b/superset-frontend/.eslintrc.js @@ -274,7 +274,7 @@ module.exports = { 'fixtures.*', 'cypress-base/cypress/**/*', 'Stories.tsx', - 'packages/superset-ui-core/src/style/index.tsx', + 'packages/superset-ui-core/src/theme/index.tsx', ], rules: { 'theme-colors/no-literal-colors': 0, diff --git a/superset-frontend/.prettierignore b/superset-frontend/.prettierignore index 790231eb298cb..4fe6cf6c11c82 100644 --- a/superset-frontend/.prettierignore +++ b/superset-frontend/.prettierignore @@ -26,5 +26,7 @@ CHANGELOG/ *-topo.json storybook-static/ *.snap +**/*.less +**/*.less.hbs /.nx/workspace-data diff --git a/superset-frontend/.storybook/preview.jsx b/superset-frontend/.storybook/preview.jsx index ef27f3591e806..5e3e11fae1a89 100644 --- a/superset-frontend/.storybook/preview.jsx +++ b/superset-frontend/.storybook/preview.jsx @@ -17,8 +17,8 @@ * under the License. */ import { withJsx } from '@mihkeleidast/storybook-addon-source'; -import { supersetTheme, ThemeProvider } from '@superset-ui/core'; -import { AntdThemeProvider } from '../src/components/AntdThemeProvider'; +import { AntdThemeProvider, ThemeProvider } from '@superset-ui/core'; +import { theme } from 'src/preamble'; import { combineReducers, createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; import { Provider } from 'react-redux'; @@ -35,8 +35,8 @@ const store = createStore( ); const themeDecorator = Story => ( - - + + diff --git a/superset-frontend/.storybook/storybook.css b/superset-frontend/.storybook/storybook.css index b4e2fce55b7df..25fa51c5a8bd9 100644 --- a/superset-frontend/.storybook/storybook.css +++ b/superset-frontend/.storybook/storybook.css @@ -1,3 +1,2 @@ body { - background: transparent; } diff --git a/superset-frontend/package.json b/superset-frontend/package.json index bc2d833468789..c040e5eb379c6 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -44,6 +44,7 @@ "build-storybook": "storybook build", "build-translation": "scripts/po2json.sh", "bundle-stats": "cross-env BUNDLE_ANALYZER=true npm run build && npx open-cli ../superset/static/stats/statistics.html", + "compile-less": "tsx ./scripts/compileLess.ts", "core:cover": "cross-env NODE_ENV=test NODE_OPTIONS=\"--max-old-space-size=4096\" jest --coverage --coverageThreshold='{\"global\":{\"statements\":100,\"branches\":100,\"functions\":100,\"lines\":100}}' --collectCoverageFrom='[\"packages/**/src/**/*.{js,ts}\", \"!packages/superset-ui-demo/**/*\"]' packages", "cover": "cross-env NODE_ENV=test NODE_OPTIONS=\"--max-old-space-size=4096\" jest --coverage", "dev": "webpack --mode=development --color --watch", @@ -153,6 +154,7 @@ "geostyler-wfs-parser": "^2.0.3", "googleapis": "^130.0.0", "html-webpack-plugin": "^5.6.3", + "handlebars": "^4.7.8", "immer": "^10.1.1", "interweave": "^13.1.0", "jquery": "^3.7.1", @@ -360,6 +362,7 @@ "style-loader": "^4.0.0", "thread-loader": "^4.0.4", "ts-loader": "^9.5.1", + "tsx": "^4.19.2", "typescript": "^4.8.4", "vm-browserify": "^1.1.2", "webpack": "^5.97.1", diff --git a/superset-frontend/packages/generator-superset/generators/plugin-chart/templates/src/MyChart.erb b/superset-frontend/packages/generator-superset/generators/plugin-chart/templates/src/MyChart.erb index c5b8583de134b..7ed05b3f216c0 100644 --- a/superset-frontend/packages/generator-superset/generators/plugin-chart/templates/src/MyChart.erb +++ b/superset-frontend/packages/generator-superset/generators/plugin-chart/templates/src/MyChart.erb @@ -25,7 +25,7 @@ import { <%= packageLabel %>Props, <%= packageLabel %>StylesProps } from './type // Theming variables are provided for your use via a ThemeProvider // imported from @superset-ui/core. For variables available, please visit -// https://github.com/apache-superset/superset-ui/blob/master/packages/superset-ui-core/src/style/index.ts +// https://github.com/apache-superset/superset-ui/blob/master/packages/superset-ui-core/src/theme/index.ts const Styles = styled.div<<%= packageLabel %>StylesProps>` background-color: ${({ theme }) => theme.colors.secondary.light2}; diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/FallbackComponent.tsx b/superset-frontend/packages/superset-ui-core/src/chart/components/FallbackComponent.tsx index 60f6848f882f2..4e124cfb0933e 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/components/FallbackComponent.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart/components/FallbackComponent.tsx @@ -18,7 +18,7 @@ */ import { t } from '@superset-ui/core'; -import { SupersetTheme } from '../../style'; +import { SupersetTheme } from '../../'; import { FallbackPropsWithDimension } from './SuperChart'; export type Props = FallbackPropsWithDimension; diff --git a/superset-frontend/packages/superset-ui-core/src/chart/components/NoResultsComponent.tsx b/superset-frontend/packages/superset-ui-core/src/chart/components/NoResultsComponent.tsx index 73e8df625843e..31993d9d6c9b4 100644 --- a/superset-frontend/packages/superset-ui-core/src/chart/components/NoResultsComponent.tsx +++ b/superset-frontend/packages/superset-ui-core/src/chart/components/NoResultsComponent.tsx @@ -18,7 +18,7 @@ */ import { CSSProperties } from 'react'; -import { css, styled } from '../../style'; +import { css, styled } from '@superset-ui/core'; import { t } from '../../translation'; const MESSAGE_STYLES: CSSProperties = { maxWidth: 800 }; diff --git a/superset-frontend/packages/superset-ui-core/src/index.ts b/superset-frontend/packages/superset-ui-core/src/index.ts index 7258a3b648286..99e9b5184333b 100644 --- a/superset-frontend/packages/superset-ui-core/src/index.ts +++ b/superset-frontend/packages/superset-ui-core/src/index.ts @@ -28,7 +28,7 @@ export * from './number-format'; export * from './time-format'; export * from './dimension'; export * from './color'; -export * from './style'; +export * from './theme'; export * from './validator'; export * from './chart'; export * from './chart-composition'; diff --git a/superset-frontend/packages/superset-ui-core/src/style/index.tsx b/superset-frontend/packages/superset-ui-core/src/style/index.tsx deleted file mode 100644 index ee0b6e10ac419..0000000000000 --- a/superset-frontend/packages/superset-ui-core/src/style/index.tsx +++ /dev/null @@ -1,173 +0,0 @@ -/** - * 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 emotionStyled from '@emotion/styled'; -import { useTheme as useThemeBasic } from '@emotion/react'; -import createCache from '@emotion/cache'; - -export { - css, - keyframes, - jsx, - ThemeProvider, - CacheProvider as EmotionCacheProvider, - withTheme, -} from '@emotion/react'; -export { default as createEmotionCache } from '@emotion/cache'; - -declare module '@emotion/react' { - // eslint-disable-next-line @typescript-eslint/no-empty-interface - export interface Theme extends SupersetTheme {} -} - -export function useTheme() { - const theme = useThemeBasic(); - // in the case there is no theme, useTheme returns an empty object - if (Object.keys(theme).length === 0 && theme.constructor === Object) { - throw new Error( - 'useTheme() could not find a ThemeContext. The component is likely missing from the app.', - ); - } - return theme; -} - -export const emotionCache = createCache({ - key: 'superset', -}); - -export const styled = emotionStyled; - -const defaultTheme = { - borderRadius: 4, - colors: { - text: { - label: '#879399', - help: '#737373', - }, - primary: { - base: '#20A7C9', - dark1: '#1A85A0', - dark2: '#156378', - light1: '#79CADE', - light2: '#A5DAE9', - light3: '#D2EDF4', - light4: '#E9F6F9', - light5: '#F3F8FA', - }, - secondary: { - base: '#444E7C', - dark1: '#363E63', - dark2: '#282E4A', - dark3: '#1B1F31', - light1: '#8E94B0', - light2: '#B4B8CA', - light3: '#D9DBE4', - light4: '#ECEEF2', - light5: '#F5F5F8', - }, - grayscale: { - base: '#666666', - dark1: '#323232', - dark2: '#000000', - light1: '#B2B2B2', - light2: '#E0E0E0', - light3: '#F0F0F0', - light4: '#F7F7F7', - light5: '#FFFFFF', - }, - error: { - base: '#E04355', - dark1: '#A7323F', - dark2: '#6F212A', - light1: '#EFA1AA', - light2: '#FAEDEE', - }, - warning: { - base: '#FF7F44', - dark1: '#BF5E33', - dark2: '#7F3F21', - light1: '#FEC0A1', - light2: '#FFF2EC', - }, - alert: { - base: '#FCC700', - dark1: '#BC9501', - dark2: '#7D6300', - light1: '#FDE380', - light2: '#FEF9E6', - }, - success: { - base: '#5AC189', - dark1: '#439066', - dark2: '#2B6144', - light1: '#ACE1C4', - light2: '#EEF8F3', - }, - info: { - base: '#66BCFE', - dark1: '#4D8CBE', - dark2: '#315E7E', - light1: '#B3DEFE', - light2: '#EFF8FE', - }, - }, - opacity: { - light: '10%', - mediumLight: '35%', - mediumHeavy: '60%', - heavy: '80%', - }, - typography: { - families: { - sansSerif: `'Inter', Helvetica, Arial`, - serif: `Georgia, 'Times New Roman', Times, serif`, - monospace: `'Fira Code', 'Courier New', monospace`, - }, - weights: { - light: 200, - normal: 400, - medium: 500, - bold: 600, - }, - sizes: { - xxs: 9, - xs: 10, - s: 12, - m: 14, - l: 16, - xl: 21, - xxl: 28, - }, - }, - zIndex: { - aboveDashboardCharts: 10, - dropdown: 11, - max: 3000, - }, - transitionTiming: 0.3, - gridUnit: 4, - brandIconMaxWidth: 37, -}; - -export type SupersetTheme = typeof defaultTheme; - -export interface SupersetThemeProps { - theme: SupersetTheme; -} - -export const supersetTheme = defaultTheme; diff --git a/superset-frontend/packages/superset-ui-core/src/theme/Theme.ts b/superset-frontend/packages/superset-ui-core/src/theme/Theme.ts new file mode 100644 index 0000000000000..a5721ff2b9ece --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/theme/Theme.ts @@ -0,0 +1,448 @@ +/** + * 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 { theme as antdThemeImport } from 'antd-v5'; +import tinycolor from 'tinycolor2'; +import type { ThemeConfig } from 'antd-v5'; + +interface SystemColors { + primary: string; + secondary: string; + error: string; + warning: string; + alert: string; + success: string; + info: string; + grayscale: string; +} + +interface ThemeColors { + base: string; + light1: string; + light2: string; + light3: string; + light4: string; + light5: string; + dark1: string; + dark2: string; + dark3: string; + dark4: string; + dark5: string; +} + +interface SupersetTheme { + borderRadius: number; + body: { + backgroundColor: string; + color: string; + }; + colors: { + darkest: string; + lightest: string; + text: { + label: string; + help: string; + }; + primary: ThemeColors; + secondary: ThemeColors; + error: ThemeColors; + warning: ThemeColors; + alert: ThemeColors; + success: ThemeColors; + info: ThemeColors; + grayscale: ThemeColors; + }; + opacity: { + light: string; + mediumLight: string; + mediumHeavy: string; + heavy: string; + }; + typography: { + families: { + sansSerif: string; + serif: string; + monospace: string; + }; + weights: { + light: number; + normal: number; + medium: number; + bold: number; + }; + sizes: { + xxs: number; + xs: number; + s: number; + m: number; + l: number; + xl: number; + xxl: number; + }; + }; + zIndex: { + aboveDashboardCharts: number; + dropdown: number; + max: number; + }; + transitionTiming: number; + gridUnit: number; + brandIconMaxWidth: number; +} + +type DenyList = string[]; + +export default class Theme { + private readonly systemColors: SystemColors; + private readonly isDarkMode: boolean; + private theme: SupersetTheme | null = null; + private antdTheme: Record | null = null; + public antdConfig: ThemeConfig | undefined = undefined; + + private static readonly denyList: DenyList = [ + 'purple.*', + 'dragon.*', + 'geekblue.*', + 'magenta.*', + 'volcano.*', + 'gold.*', + 'lime.*', + 'cyan.*', + 'blue.*', + 'green.*', + 'red.*', + 'yellow.*', + 'pink.*', + 'orange.*', + ]; + + constructor( + systemColors?: Partial, + isDarkMode: boolean = false, + ) { + this.isDarkMode = isDarkMode; + this.systemColors = { + primary: '#20a7c9', + secondary: '#444e7c', + error: '#e04355', + warning: '#fcc700', + alert: '#fcc700', + success: '#5ac189', + info: '#66bcfe', + grayscale: '#666666', + ...systemColors, + }; + + this.setThemeWithSystemColors(this.systemColors, this.isDarkMode); + this.setAntdThemeFromTheme(); + } + + getTheme(): Record { + return { + ...this.theme, + antd: this.getFilteredAntdTheme(), + }; + } + + private adjustColor( + color: string, + percentage: number, + target: string = 'white', + ): string { + return tinycolor.mix(color, target, percentage).toHexString(); + } + + private generateColorVariations(color: string): ThemeColors { + return { + base: color, + light1: this.adjustColor(color, 20, 'white'), + light2: this.adjustColor(color, 45, 'white'), + light3: this.adjustColor(color, 70, 'white'), + light4: this.adjustColor(color, 90, 'white'), + light5: this.adjustColor(color, 95, 'white'), + dark1: this.adjustColor(color, 10, 'black'), + dark2: this.adjustColor(color, 20, 'black'), + dark3: this.adjustColor(color, 40, 'black'), + dark4: this.adjustColor(color, 60, 'black'), + dark5: this.adjustColor(color, 80, 'black'), + }; + } + + private makeThemeDark(theme: SupersetTheme): SupersetTheme { + const darkTheme = { ...theme }; + darkTheme.colors = { ...theme.colors }; + + Object.keys(darkTheme.colors).forEach(key => { + if (key !== 'text') { + darkTheme.colors[key] = this.swapLightAndDark(theme.colors[key]); + } + }); + + // Update text-specific colors + darkTheme.colors.text = { + ...darkTheme.colors.text, + label: '#D3D3D3', + help: '#D3D3D3', + }; + darkTheme.colors.darkest = '#FFF'; + darkTheme.colors.lightest = '#000'; + return darkTheme; + } + + private swapLightAndDark(colorVariations: ThemeColors): ThemeColors { + return { + ...colorVariations, + light1: colorVariations.dark1, + light2: colorVariations.dark2, + light3: colorVariations.dark3, + light4: colorVariations.dark4, + light5: colorVariations.dark5, + dark1: colorVariations.light1, + dark2: colorVariations.light2, + dark3: colorVariations.light3, + dark4: colorVariations.light4, + dark5: colorVariations.light5, + }; + } + + private generateColors(): Record { + const colors: Record = {}; + Object.entries(this.systemColors).forEach(([key, value]) => { + colors[key] = this.generateColorVariations(value); + }); + return colors; + } + + private getSupersetTheme( + systemColors: SystemColors, + isDarkTheme: boolean = false, + ): SupersetTheme { + const colors = this.generateColors(); + let theme: SupersetTheme = { + borderRadius: 4, + body: { + backgroundColor: '#FFF', + color: '#000', + }, + colors: { + darkest: '#000', + lightest: '#FFF', + text: { + label: '#879399', + help: '#737373', + }, + primary: colors.primary, + secondary: colors.secondary, + error: colors.error, + warning: colors.warning, + alert: colors.alert, + success: colors.success, + info: colors.info, + grayscale: colors.grayscale, + }, + opacity: { + light: '10%', + mediumLight: '35%', + mediumHeavy: '60%', + heavy: '80%', + }, + typography: { + families: { + sansSerif: `'Inter', Helvetica, Arial`, + serif: `Georgia, 'Times New Roman', Times, serif`, + monospace: `'Fira Code', 'Courier New', monospace`, + }, + weights: { + light: 200, + normal: 400, + medium: 500, + bold: 600, + }, + sizes: { + xxs: 9, + xs: 10, + s: 12, + m: 14, + l: 16, + xl: 21, + xxl: 28, + }, + }, + zIndex: { + aboveDashboardCharts: 10, + dropdown: 11, + max: 3000, + }, + transitionTiming: 0.3, + gridUnit: 4, + brandIconMaxWidth: 37, + }; + + if (isDarkTheme) { + theme = this.makeThemeDark(theme); + } + + return theme; + } + + private getAntdSeed(): Record { + const theme = this.theme!; + return { + ...antdThemeImport.defaultSeed, + + borderRadius: theme.borderRadius, + + colorPrimary: theme.colors.primary.base, + colorError: theme.colors.error.base, + colorInfo: theme.colors.info.base, + colorSuccess: theme.colors.success.base, + colorWarning: theme.colors.warning.base, + colorBgLayout: theme.colors.grayscale.light5, + + colorLink: theme.colors.primary.dark1, + + controlHeight: 32, + fontFamily: theme.typography.families.sansSerif, + fontFamilyCode: theme.typography.families.monospace, + fontSize: theme.typography.sizes.m, + lineType: 'solid', + lineWidth: 1, + sizeStep: theme.gridUnit, + sizeUnit: theme.gridUnit, + zIndexBase: 0, + zIndexPopupBase: theme.zIndex.max, + /* + components: { + Alert: { + borderRadius: theme.borderRadius, + fontSize: theme.typography.sizes.m, + fontSizeLG: theme.typography.sizes.m, + fontSizeIcon: theme.typography.sizes.l, + colorText: theme.colors.grayscale.dark4, + colorTextHeading: theme.colors.grayscale.dark4, + }, + Avatar: { + containerSize: 32, + fontSize: theme.typography.sizes.s, + lineHeight: 32, + }, + Badge: { + paddingXS: theme.gridUnit * 2, + }, + Card: { + paddingLG: theme.gridUnit * 6, + fontWeightStrong: theme.typography.weights.medium, + colorBgContainer: theme.colors.grayscale.light4, + }, + Divider: { + colorSplit: supersetTheme.colors.grayscale.light3, + }, + Input: { + colorBorder: theme.colors.secondary.light3, + colorBgContainer: theme.colors.grayscale.light5, + activeShadow: `0 0 0 ${theme.gridUnit / 2}px ${ + theme.colors.primary.light3 + }`, + }, + InputNumber: { + colorBorder: theme.colors.secondary.light3, + colorBgContainer: theme.colors.grayscale.light5, + activeShadow: `0 0 0 ${theme.gridUnit / 2}px ${ + theme.colors.primary.light3 + }`, + }, + List: { + itemPadding: `${theme.gridUnit + 2}px ${theme.gridUnit * 3}px`, + paddingLG: theme.gridUnit * 3, + colorSplit: theme.colors.grayscale.light3, + colorText: theme.colors.grayscale.dark1, + }, + Modal: { + colorBgMask: `${theme.colors.grayscale.dark2}73`, + contentBg: theme.colors.grayscale.light5, + titleFontSize: theme.gridUnit * 4, + titleColor: `${theme.colors.grayscale.dark2}D9`, + headerBg: theme.colors.grayscale.light4, + }, + Tag: { + borderRadiusSM: 2, + defaultBg: theme.colors.grayscale.light4, + }, + Progress: { + fontSize: theme.typography.sizes.s, + colorText: theme.colors.text.label, + remainingColor: theme.colors.grayscale.light4, + }, + Popover: { + colorBgElevated: theme.colors.grayscale.light5, + }, + Slider: { + trackBgDisabled: theme.colors.grayscale.light1, + colorBgElevated: theme.colors.grayscale.light5, + handleSizeHover: 10, + handleLineWidthHover: 2, + }, + Switch: { + colorPrimaryHover: theme.colors.primary.base, + colorTextTertiary: theme.colors.grayscale.light1, + }, + Tooltip: { + fontSize: theme.typography.sizes.s, + lineHeight: 1.6, + }, + }, + } + */ + }; + } + + private getFilteredAntdTheme(): Record { + const theme = this.antdTheme!; + const filteredTheme: Record = {}; + + Object.entries(theme).forEach(([key, value]) => { + if (!Theme.denyList.some(deny => new RegExp(deny).test(key))) { + filteredTheme[key] = value; + } + }); + + return filteredTheme; + } + + private setThemeWithSystemColors( + systemColors: SystemColors, + isDarkMode: boolean, + ): void { + this.theme = this.getSupersetTheme(systemColors, isDarkMode); + } + + private setAntdThemeFromTheme(): void { + const seed = this.getAntdSeed(); + const algorithm = this.isDarkMode + ? antdThemeImport.darkAlgorithm + : antdThemeImport.defaultAlgorithm; + + this.antdConfig = { + token: seed, + algorithm, + }; + + this.antdTheme = algorithm(seed as any); + } +} diff --git a/superset-frontend/packages/superset-ui-core/src/theme/index.tsx b/superset-frontend/packages/superset-ui-core/src/theme/index.tsx new file mode 100644 index 0000000000000..e988829756e57 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/theme/index.tsx @@ -0,0 +1,69 @@ +/** + * 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 emotionStyled from '@emotion/styled'; +import { useTheme as useThemeBasic } from '@emotion/react'; +import createCache from '@emotion/cache'; +import SupersetThemeClass from './Theme'; +import { ConfigProvider, type ConfigProviderProps } from 'antd-v5'; + +export { + css, + keyframes, + jsx, + ThemeProvider, + CacheProvider as EmotionCacheProvider, + withTheme, +} from '@emotion/react'; +export { default as createEmotionCache } from '@emotion/cache'; + +declare module '@emotion/react' { + // eslint-disable-next-line @typescript-eslint/no-empty-interface + export interface Theme extends SupersetTheme {} +} + +export function useTheme() { + const theme = useThemeBasic(); + // in the case there is no theme, useTheme returns an empty object + if (Object.keys(theme).length === 0 && theme.constructor === Object) { + throw new Error( + 'useTheme() could not find a ThemeContext. The component is likely missing from the app.', + ); + } + return theme; +} + +export const emotionCache = createCache({ + key: 'superset', +}); + +export const styled = emotionStyled; +const themeObject = new SupersetThemeClass({}, true); + +export const theme = themeObject.getTheme(); +export const supersetTheme = theme; + +export const AntdThemeProvider = ({ theme, children }: ConfigProviderProps) => ( + + {children} + +); +export type SupersetTheme = typeof supersetTheme; +export interface SupersetThemeProps { + theme: SupersetTheme; +} diff --git a/superset-frontend/packages/superset-ui-core/test/chart/components/FallbackComponent.test.tsx b/superset-frontend/packages/superset-ui-core/test/chart/components/FallbackComponent.test.tsx index 2a52c62e5e8ec..dcbaeee56361a 100644 --- a/superset-frontend/packages/superset-ui-core/test/chart/components/FallbackComponent.test.tsx +++ b/superset-frontend/packages/superset-ui-core/test/chart/components/FallbackComponent.test.tsx @@ -20,7 +20,7 @@ import { render } from '@testing-library/react'; import '@testing-library/jest-dom'; import { FallbackProps } from 'react-error-boundary'; -import { ThemeProvider, supersetTheme } from '../../../src/style'; +import { ThemeProvider, supersetTheme } from '../../../src/theme'; import FallbackComponent from '../../../src/chart/components/FallbackComponent'; diff --git a/superset-frontend/packages/superset-ui-core/test/chart/components/NoResultsComponent.test.tsx b/superset-frontend/packages/superset-ui-core/test/chart/components/NoResultsComponent.test.tsx index f736d44b99578..5a38c8c98e394 100644 --- a/superset-frontend/packages/superset-ui-core/test/chart/components/NoResultsComponent.test.tsx +++ b/superset-frontend/packages/superset-ui-core/test/chart/components/NoResultsComponent.test.tsx @@ -19,7 +19,7 @@ import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; -import { ThemeProvider, supersetTheme } from '../../../src/style'; +import { ThemeProvider, supersetTheme } from '../../../src/theme'; import NoResultsComponent from '../../../src/chart/components/NoResultsComponent'; const renderNoResultsComponent = () => diff --git a/superset-frontend/packages/superset-ui-core/test/style/index.test.tsx b/superset-frontend/packages/superset-ui-core/test/style/index.test.tsx index 352ea4b6a01e9..7c10c14488f99 100644 --- a/superset-frontend/packages/superset-ui-core/test/style/index.test.tsx +++ b/superset-frontend/packages/superset-ui-core/test/style/index.test.tsx @@ -20,7 +20,6 @@ import { styled, supersetTheme, - SupersetThemeProps, useTheme, ThemeProvider, EmotionCacheProvider, @@ -37,13 +36,6 @@ describe('@superset-ui/style package', () => { expect(typeof styled.div).toBe('function'); }); - it('exports SupersetThemeProps', () => { - const props: SupersetThemeProps = { - theme: supersetTheme, - }; - expect(typeof props).toBe('object'); - }); - describe('useTheme()', () => { it('returns the theme', () => { function ThemeUser() { diff --git a/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-theme/Theme.stories.tsx b/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-theme/Theme.stories.tsx new file mode 100644 index 0000000000000..579f5f438b5a3 --- /dev/null +++ b/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-theme/Theme.stories.tsx @@ -0,0 +1,268 @@ +/* + * 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 { supersetTheme } from '@superset-ui/core'; + +const AntDFunctionalColors = ({ antdTheme }) => { + const { antd } = supersetTheme; + + // Define color types and variations dynamically + const colorTypes = ['Primary', 'Success', 'Error', 'Warning', 'Info']; + const variations = [ + 'Active', + 'TextActive', + 'Text', + 'TextHover', + 'Hover', + 'BorderHover', + 'Border', + 'BgHover', + 'Bg', + ]; + + return ( + + + + + {variations.map(variation => ( + + ))} + + + + {colorTypes.map(type => { + const typeKey = `color${type}`; + return ( + + + {variations.map(variation => { + const tokenKey = `${typeKey}${variation}`; + const color = antd[tokenKey]; + return ( + + ); + })} + + ); + })} + +
Type + {variation} +
+ {type} + + {color ? {color} : '-'} +
+ ); +}; + +const AntDSystemColors = ({ antdTheme }) => { + const { antd } = supersetTheme; + + // Define color types and variations dynamically + const colorTypes = [ + 'blue', + 'purple', + 'cyan', + 'green', + 'magenta', + 'pink', + 'red', + 'orange', + 'yellow', + 'volcano', + 'geekblue', + 'gold', + 'lime', + ]; + const variations = ['', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']; + + return ( + + + + + {variations.map(variation => ( + + ))} + + + + {colorTypes.map(type => { + const typeKey = `color${type}`; + return ( + + + {variations.map(variation => { + const tokenKey = `${typeKey}${variation}`; + const color = antd[tokenKey]; + return ( + + ); + })} + + ); + })} + +
Type + {variation} +
+ {type} + + {color ? {color} : '-'} +
+ ); +}; + +export const ThemeColors = () => { + const { colors } = supersetTheme; + + // Define tones to be displayed in columns + const tones = [ + 'dark5', + 'dark4', + 'dark3', + 'dark1', + 'base', + 'light1', + 'light2', + 'light3', + 'light4', + 'light5', + ]; + const colorTypes = [ + 'primary', + 'secondary', + 'grayscale', + 'error', + 'warning', + 'alert', + 'success', + 'info', + ]; + return ( +
+

Theme Colors

+

Color Palette

+ + + + + {tones.map(tone => ( + + ))} + + + + {colorTypes.map(category => ( + + + {tones.map(tone => { + const color = colors[category][tone]; + return ( + + ); + })} + + ))} + +
+ Category + + {tone} +
+ {category} + + {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. +
+

Ant Design Theme Colors

+

Functional Colors

+ +

System Colors

+ +

The supersetTheme object

+ +
{JSON.stringify(supersetTheme, null, 2)}
+
+
+ ); +}; +/* + * */ +export default { + title: 'Core Packages/@superset-ui-theme', +}; + +export const Default = () => ; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberPeriodOverPeriod/PopKPI.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberPeriodOverPeriod/PopKPI.tsx index a4736c89c2058..91903cad1ddb2 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberPeriodOverPeriod/PopKPI.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberPeriodOverPeriod/PopKPI.tsx @@ -50,7 +50,7 @@ const ComparisonValue = styled.div` font-weight: ${theme.typography.weights.light}; display: flex; justify-content: center; - font-size: ${subheaderFontSize || 20}px; + font-size: ${String(subheaderFontSize) || 20}px; flex: 1 1 0px; `} `; @@ -134,7 +134,7 @@ export default function PopKPI(props: PopKPIProps) { `; const bigValueContainerStyles = css` - font-size: ${headerFontSize || 60}px; + font-size: ${String(headerFontSize) || 60}px; font-weight: ${theme.typography.weights.normal}; text-align: center; margin-bottom: ${theme.gridUnit * 4}px; diff --git a/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx b/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx index 0e91e93f12619..55aa4a3979133 100644 --- a/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx +++ b/superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx @@ -196,7 +196,7 @@ class WordCloud extends PureComponent { cloudLayout() .size([width * scaleFactor, height * scaleFactor]) // clone the data because cloudLayout mutates input - .words(data.map(d => ({ ...d }))) + .words(data.map((d: Word) => ({ ...d }))) .padding(5) .rotate(ROTATION[rotation] || ROTATION.flat) .text((d: PlainObject) => encoder.channels.text.getValueFromDatum(d)) diff --git a/superset-frontend/scripts/compileLess.ts b/superset-frontend/scripts/compileLess.ts new file mode 100644 index 0000000000000..a775f27ce2d14 --- /dev/null +++ b/superset-frontend/scripts/compileLess.ts @@ -0,0 +1,69 @@ +/* + * 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 * as fs from 'fs'; +import * as path from 'path'; +import Handlebars from 'handlebars'; +import { theme } from 'packages/superset-ui-core/src/theme'; // Adjust the path as needed + +Handlebars.escapeExpression = (value: string) => value; + +// Function to apply a template and generate the output +function applyTemplate(filePath: string): void { + try { + // Read the .less.hbs template + const templateContent = fs.readFileSync(filePath, 'utf-8'); + + // Compile the template + const template = Handlebars.compile(templateContent, { noEscape: true }); + + // Generate the final .less file + const result = template({ theme }); + + // Write the output to a .less file + const outputFilePath = filePath.replace('.hbs', ''); // Remove .hbs for output + fs.writeFileSync(outputFilePath, result, 'utf-8'); + + console.log(`Themed .less file generated: ${outputFilePath}`); + } catch (error) { + console.error(`Failed to process template: ${filePath}`, error); + } +} + +function findHbsFiles(dir: string): string[] { + const files = fs.readdirSync(dir); + return files + .map((file: string) => { + const fullPath = path.join(dir, file); + if (fs.statSync(fullPath).isDirectory()) { + return findHbsFiles(fullPath); + } + if (fullPath.endsWith('.less.hbs')) { + return fullPath; + } + return null; + }) + .flat() + .filter((filePath: string | null): filePath is string => filePath !== null); +} + +// Find all `.less.hbs` files in the directory +const hbsFiles = findHbsFiles('src/assets/stylesheets/'); + +// Apply templates to all `.less.hbs` files found +hbsFiles.forEach((filePath: string) => applyTemplate(filePath)); diff --git a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx index 06e67fb40433d..7a5b9f9acf370 100644 --- a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx +++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx @@ -50,12 +50,40 @@ type AceEditorWrapperProps = { const StyledAceEditor = styled(AceEditor)` ${({ theme }) => css` + color: ${theme.antd.colorText}; && { // double class is better than !important - border: 1px solid ${theme.colors.grayscale.light2}; + border: 1px solid ${theme.antd.colorBorder}; font-feature-settings: 'liga' off, 'calt' off; + + .ace_editor { + font-family: 'Roboto Mono', monospace; + font-size: 14px; + background-color: ${theme.antd.colorBgContainer}; + color: ${theme.antd.colorText}; + } + .ace-github { + color: ${theme.antd.colorText}; + } + + .ace_gutter { + background: ${theme.antd.colorBgElevated}; + color: ${theme.antd.colorText}; + } + + .ace_cursor { + color: ${theme.antd.colorPrimary}; + } + + .ace_marker-layer .ace_active-line { + background: ${theme.antd.colorFillTertiary}; + } + + .ace_marker-layer .ace_selection { + background: ${theme.antd.colorPrimaryHover}; + } } `} `; diff --git a/superset-frontend/src/SqlLab/components/App/index.tsx b/superset-frontend/src/SqlLab/components/App/index.tsx index 7da80d8e9c965..e69a198c72965 100644 --- a/superset-frontend/src/SqlLab/components/App/index.tsx +++ b/superset-frontend/src/SqlLab/components/App/index.tsx @@ -76,7 +76,7 @@ const SqlLabStyles = styled.div` .ant-tabs-content { height: 100%; position: relative; - background-color: ${theme.colors.grayscale.light5}; + background-color: ${theme.antd.colorBgBase}; overflow-x: auto; overflow-y: auto; diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx index cab82cd02f5c2..8d1993d05eccc 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.tsx @@ -137,7 +137,7 @@ const StyledToolbar = styled.div` background: ${({ theme }) => theme.colors.grayscale.light5}; display: flex; justify-content: space-between; - border: 1px solid ${({ theme }) => theme.colors.grayscale.light2}; + border: 1px solid ${({ theme }) => theme.antd.colorBorder}; border-top: 0; column-gap: ${({ theme }) => theme.gridUnit}px; diff --git a/superset-frontend/src/assets/stylesheets/antd/index.less b/superset-frontend/src/assets/stylesheets/antd/index.less index cf51b165eb998..d422bbd1920b5 100644 --- a/superset-frontend/src/assets/stylesheets/antd/index.less +++ b/superset-frontend/src/assets/stylesheets/antd/index.less @@ -10,11 +10,11 @@ * 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. + * 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 '~antd/lib/style/themes/index'; @@ -25,15 +25,97 @@ @import '~antd/lib/style/core/motion'; @import '~antd/lib/style/components.less'; +//@import '~antd/lib/style/core'; +//@import '~antd/lib/checkbox/style'; +//@import '~antd/lib/checkbox'; + + /* Theme variables here: https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less */ +/* Core Colors */ @primary-color: #20a7c9; @info-color: #66bcfe; -@success-color: #59c189; -@processing-color: #66bcfe; +@success-color: #5ac189; @error-color: #e04355; @highlight-color: #e04355; -@normal-color: #d9d9d9; -@white: #fff; -@black: #000; +@normal-color: #000; + +// Menu-related +@menu-highlight-color: #1e91ae; +//@menu-item-active-bg: #84cfe1; +@menu-item-color: #bce5ef; +@menu-popup-bg: #000; +@menu-bg: #000; + +@tabs-card-head-background: #1f1f1f; +@component-background: #000; +@select-item-selected-bg: #121f24; +@select-item-active-bg: #121f24; +@select-item-hover-bg: #121f24; + +// GPT generated: + +/* Backgrounds */ +@layout-body-background: #000000; +@layout-header-background: #000; +@layout-footer-background: #000; +@layout-sider-background: #000; +@background-color-light: #141414; +@background-color-base: #000; +@background-elevated: #1f1f1f; + +/* Text */ +@text-color: rgba(255, 255, 255, 0.85); +@text-color-secondary: rgba(255, 255, 255, 0.65); +@text-color-tertiary: rgba(255, 255, 255, 0.45); +@text-color-quaternary: rgba(255, 255, 255, 0.25); +@heading-color: #000; +//@disabled-color: ; +//@input-placeholder-color: ; + +/* Borders */ +@border-color-base: #424242; +@border-color-split: #303030; +@border-radius-base: 4; +@border-radius-sm: 4; +@border-radius-lg: 4; + +/* Buttons */ +@btn-primary-bg: #1e91ae; +@btn-default-bg: #141414; +@btn-default-border: #424242; +@btn-danger-bg: #c13c4b; +@btn-danger-border: #c13c4b; + +/* Inputs */ +//@input-bg: ; +@input-border-color: #424242; +@input-hover-border-color: #195665; + +/* Menus */ +@menu-highlight-color: #1e91ae; +@menu-item-color: rgba(255, 255, 255, 0.85); +@menu-bg: #141414; + +/* Typography */ +@font-family: 'Inter', Helvetica, Arial; +@font-family-code: 'Fira Code', 'Courier New', monospace; +@font-size-base: 14; +@font-size-sm: 12; +@font-size-lg: 16; +@line-height-base: 1.5714285714285714; +@line-height-sm: 1.6666666666666667; +@line-height-lg: 1.5; + +/* Tables */ +@table-header-bg: #141414; +@table-row-hover-bg: #1f1f1f; +@table-selected-row-bg: #121f24; + +/* Motion */ +@motion-duration-fast: 0.1s; +@motion-duration-mid: 0.2s; +@motion-duration-slow: 0.3s; +@motion-ease-out: cubic-bezier(0.215, 0.61, 0.355, 1); +@motion-ease-in-out: cubic-bezier(0.645, 0.045, 0.355, 1); diff --git a/superset-frontend/src/assets/stylesheets/antd/index.less.hbs b/superset-frontend/src/assets/stylesheets/antd/index.less.hbs new file mode 100644 index 0000000000000..b11d455ac3954 --- /dev/null +++ b/superset-frontend/src/assets/stylesheets/antd/index.less.hbs @@ -0,0 +1,121 @@ +/** + * 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, + * 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 '~antd/lib/style/themes/index'; +@import '~antd/lib/style/mixins/index'; +@import '~antd/lib/style/core/base'; + +@import '~antd/lib/style/core/iconfont'; +@import '~antd/lib/style/core/motion'; +@import '~antd/lib/style/components.less'; + +//@import '~antd/lib/style/core'; +//@import '~antd/lib/checkbox/style'; +//@import '~antd/lib/checkbox'; + + +/* + Theme variables here: https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less +*/ +/* Core Colors */ +@primary-color: {{theme.colors.primary.base}}; +@info-color: {{theme.colors.info.base}}; +@success-color: {{theme.colors.success.base}}; +@error-color: {{theme.colors.error.base}}; +@highlight-color: {{theme.colors.error.base}}; +@normal-color: {{theme.antd.colorBgBase}}; + +// Menu-related +@menu-highlight-color: {{theme.antd.colorPrimary}}; +//@menu-item-active-bg: {{theme.colors.primary.dark2}}; +@menu-item-color: {{theme.colors.primary.dark3}}; +@menu-popup-bg: {{theme.antd.colorBgBase}}; +@menu-bg: {{theme.antd.colorBgBase}}; + +@tabs-card-head-background: {{theme.antd.colorBgElevated}}; +@component-background: {{theme.antd.colorBgBase}}; +@select-item-selected-bg: {{theme.antd.colorPrimaryBg}}; +@select-item-active-bg: {{theme.antd.colorPrimaryBg}}; +@select-item-hover-bg: {{theme.antd.colorPrimaryBg}}; + +// GPT generated: + +/* Backgrounds */ +@layout-body-background: {{theme.antd.colorBgLayout}}; +@layout-header-background: {{theme.antd.colorBgBase}}; +@layout-footer-background: {{theme.antd.colorBgBase}}; +@layout-sider-background: {{theme.antd.colorBgBase}}; +@background-color-light: {{theme.antd.colorBgContainer}}; +@background-color-base: {{theme.antd.colorBgBase}}; +@background-elevated: {{theme.antd.colorBgElevated}}; + +/* Text */ +@text-color: {{theme.antd.colorText}}; +@text-color-secondary: {{theme.antd.colorTextSecondary}}; +@text-color-tertiary: {{theme.antd.colorTextTertiary}}; +@text-color-quaternary: {{theme.antd.colorTextQuaternary}}; +@heading-color: {{theme.antd.colorBgBase}}; +//@disabled-color: {{theme.antd.colorTextDisabled}}; +//@input-placeholder-color: {{theme.antd.colorTextPlaceholder}}; + +/* Borders */ +@border-color-base: {{theme.antd.colorBorder}}; +@border-color-split: {{theme.antd.colorBorderSecondary}}; +@border-radius-base: {{theme.antd.borderRadius}}; +@border-radius-sm: {{theme.antd.borderRadiusSM}}; +@border-radius-lg: {{theme.antd.borderRadiusLG}}; + +/* Buttons */ +@btn-primary-bg: {{theme.antd.colorPrimary}}; +@btn-default-bg: {{theme.antd.colorBgContainer}}; +@btn-default-border: {{theme.antd.colorBorder}}; +@btn-danger-bg: {{theme.antd.colorError}}; +@btn-danger-border: {{theme.antd.colorError}}; + +/* Inputs */ +//@input-bg: {{theme.antd.colorBgInput}}; +@input-border-color: {{theme.antd.colorBorder}}; +@input-hover-border-color: {{theme.antd.colorPrimaryBorderHover}}; + +/* Menus */ +@menu-highlight-color: {{theme.antd.colorPrimary}}; +@menu-item-color: {{theme.antd.colorText}}; +@menu-bg: {{theme.antd.colorBgContainer}}; + +/* Typography */ +@font-family: {{theme.antd.fontFamily}}; +@font-family-code: {{theme.antd.fontFamilyCode}}; +@font-size-base: {{theme.antd.fontSize}}; +@font-size-sm: {{theme.antd.fontSizeSM}}; +@font-size-lg: {{theme.antd.fontSizeLG}}; +@line-height-base: {{theme.antd.lineHeight}}; +@line-height-sm: {{theme.antd.lineHeightSM}}; +@line-height-lg: {{theme.antd.lineHeightLG}}; + +/* Tables */ +@table-header-bg: {{theme.antd.colorBgContainer}}; +@table-row-hover-bg: {{theme.antd.colorBgElevated}}; +@table-selected-row-bg: {{theme.antd.colorPrimaryBg}}; + +/* Motion */ +@motion-duration-fast: {{theme.antd.motionDurationFast}}; +@motion-duration-mid: {{theme.antd.motionDurationMid}}; +@motion-duration-slow: {{theme.antd.motionDurationSlow}}; +@motion-ease-out: {{theme.antd.motionEaseOut}}; +@motion-ease-in-out: {{theme.antd.motionEaseInOut}}; diff --git a/superset-frontend/src/assets/stylesheets/less/cosmo/bootswatch.less.hbs b/superset-frontend/src/assets/stylesheets/less/cosmo/bootswatch.less.hbs new file mode 100644 index 0000000000000..c9ece15bb6639 --- /dev/null +++ b/superset-frontend/src/assets/stylesheets/less/cosmo/bootswatch.less.hbs @@ -0,0 +1,509 @@ +/** + * 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. + */ +// Forked Cosmo 3.3.7 +// Bootswatch +// ----------------------------------------------------- + +// Navbar ===================================================================== + +.navbar { + border: none; + + li > a:focus { + outline: 0; + } + + &-inverse { + .badge { + background-color: @lightest; + color: @brand-primary; + } + } + + .caret { + display: inline-block; + padding: 0 5px 18px 5px; + } +} + +.navbar-inverse { + border: none; +} + +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + background: transparent; +} + +.navbar-nav > li > a { + padding-top: 18px; +} + +// Buttons ==================================================================== + +.btn:focus, +.btn:active:focus { + outline: none; +} + +.nav-tabs { + .dropdown-toggle.btn, + .btn-group.open .dropdown-toggle.btn { + &, + &:hover, + &:active, + &:focus { + border-color: transparent; + background-color: transparent; + box-shadow: none; + } + } +} + +.caret { + border: none; + color: @gray; + + &:hover { + color: @gray-darker; + } + + &:before { + font-family: 'FontAwesome'; + font-size: @font-size-xs; + content: '\f078'; + } +} + +// Typography ================================================================= + +body { + -webkit-font-smoothing: antialiased; +} + +.text-primary, +.text-primary:hover { + color: @brand-primary; +} + +.text-success, +.text-success:hover { + color: @success; +} + +.text-danger, +.text-danger:hover { + color: @brand-danger; +} + +.text-warning, +.text-warning:hover { + color: @brand-warning; +} + +.text-info, +.text-info:hover { + color: @brand-info; +} + +// Tables ===================================================================== + +table, +.table { + .dropdown-menu a { + text-decoration: none; + } + + .success, + .warning, + .danger, + .info { + color: @lightest; + + a { + color: @lightest; + } + + .btn-default { + color: @gray; + } + } +} + +// Forms ====================================================================== + +.form-control { + box-shadow: none; +} + +.has-warning { + .help-block, + .control-label, + .radio, + .checkbox, + .radio-inline, + .checkbox-inline, + &.radio label, + &.checkbox label, + &.radio-inline label, + &.checkbox-inline label, + .form-control-feedback { + color: @brand-warning; + } + + .form-control, + .form-control:focus, + .input-group-addon { + border: 1px solid @brand-warning; + } +} + +.has-error { + .help-block, + .control-label, + .radio, + .checkbox, + .radio-inline, + .checkbox-inline, + &.radio label, + &.checkbox label, + &.radio-inline label, + &.checkbox-inline label, + .form-control-feedback { + color: @brand-danger; + } + + .form-control, + .form-control:focus, + .input-group-addon { + border: 1px solid @brand-danger; + } +} + +.has-success { + .help-block, + .control-label, + .radio, + .checkbox, + .radio-inline, + .checkbox-inline, + &.radio label, + &.checkbox label, + &.radio-inline label, + &.checkbox-inline label, + .form-control-feedback { + color: @brand-success; + } + + .form-control, + .form-control:focus, + .input-group-addon { + border: 1px solid @brand-success; + } +} + +// Navs ======================================================================= + +.nav-pills { + & > li > a { + border-radius: @border-radius-normal; + } +} + +.dropdown-menu { + & > li > a:hover, + & > li > a:focus { + background-image: none; + text-decoration: none; + } +} + +// Indicators ================================================================= + +.close { + text-decoration: none; + text-shadow: none; + opacity: 0.4; + + &:hover, + &:focus { + opacity: 1; + } +} + +.alert { + border: none; +} + +.alert-link { + text-decoration: underline; +} + +.alert-info .alert-link { + color: @alert-info-text; +} + +.alert-danger .alert-link { + color: @alert-danger-text; +} + +.alert-warning .alert-link { + color: @alert-warning-text; +} + +.alert-success .alert-link { + color: @alert-success-text; +} + +.label { + border-radius: 21px; + padding: 0.35em 0.8em 0.35em; + font-weight: @font-weight-normal; + font-size: @font-size-s; +} +.label-default:hover { + background-color: darken(@label-default-bg, 5%); +} +.label-warning:hover { + background-color: darken(@label-warning-bg, 5%); +} +.label-danger:hover { + background-color: darken(@label-danger-bg, 5%); +} +.label-primary:hover { + background-color: darken(@label-primary-bg, 5%); +} + +label { + font-weight: @font-weight-normal; + font-size: @font-size-s; +} + +// Progress bars ============================================================== + +.progress { + height: 14px; + .box-shadow(none); + + .progress-bar { + font-size: @font-size-s; + line-height: @line-height-tight; + padding-top: 2px; + } +} + +// Containers ================================================================= + +.panel { + border: none; + + &-heading, + &-footer { + border-top-right-radius: 0; + border-top-left-radius: 0; + } + + &-default { + .panel-heading { + padding: 15px 15px 0 15px; + background-color: transparent; + } + + .panel-title { + color: @text-color; + padding-bottom: 5px; + border-bottom: 1px solid @gray-light; + + h1, + h2, + h3, + h4, + h5, + h6 { + margin: 10px 0 0 0; + font-weight: @font-weight-bold; + } + } + + .close { + color: @text-color; + } + } + + &-primary { + .panel-heading { + padding: 15px 15px 0 15px; + background-color: transparent; + } + + .panel-title { + color: @text-color; + padding-bottom: 5px; + border-bottom: 1px solid @gray-light; + + h1, + h2, + h3, + h4, + h5, + h6 { + margin: 10px 0 0 0; + font-weight: @font-weight-bold; + } + } + + .close { + color: @text-color; + } + } + + .accordion-toggle { + display: flex; + align-items: center; + text-decoration: none; + + &:hover { + text-decoration: none; + } + + .caret { + display: flex; + width: auto; + height: auto; + margin-left: 5px; + + &:hover { + color: @gray; + } + } + } +} + +.panel-title-large { + font-size: 24px; +} + +.list-group-item { + padding-top: 5px; + padding-bottom: 5px; +} + +a.list-group-item { + &-success { + &.active { + background-color: @state-success-bg; + } + + &.active:hover, + &.active:focus { + background-color: darken(@state-success-bg, 5%); + } + } + + &-warning { + &.active { + background-color: @state-warning-bg; + } + + &.active:hover, + &.active:focus { + background-color: darken(@state-warning-bg, 5%); + } + } + + &-danger { + &.active { + background-color: @state-danger-bg; + } + + &.active:hover, + &.active:focus { + background-color: darken(@state-danger-bg, 5%); + } + } +} + +.modal { + .close { + color: @text-color; + } +} + +.popover { + color: @text-color; +} + +// Tabs ============================================================== + +.nav-tabs > li > a { + border-top: 3px solid transparent; + color: @text-color; +} + +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + background-color: @lightest; + font-weight: @font-weight-bold; + border-top: 3px solid @brand-primary; +} + +// Tables ============================================================== + +.table { + .info { + color: @state-info-text; + } + + .danger { + color: @state-danger-text; + } + + .warning { + color: @state-warning-text; + } + + .success { + color: @state-success-text; + } +} + +// Utils ============================================================== +hr { + margin: 10px 0; +} + +// generate space-n classes for vertical spacing +.space-loop(@counter) when (@counter > 0) { + .space-loop((@counter - 1)); // next iteration + .space-@{counter} { + margin-bottom: (10px * @counter); // code for each iteration + } +} +.space-loop(6); + +a { + cursor: pointer; +} + +.control-label { + color: @gray; + font-size: @font-size-s; +} diff --git a/superset-frontend/src/assets/stylesheets/less/cosmo/variables.less b/superset-frontend/src/assets/stylesheets/less/cosmo/variables.less index a3c74f712cb0a..b0d24238d6980 100644 --- a/superset-frontend/src/assets/stylesheets/less/cosmo/variables.less +++ b/superset-frontend/src/assets/stylesheets/less/cosmo/variables.less @@ -42,9 +42,9 @@ // ## Settings for some of the most global styles. // ** Background color for ``. -@body-bg: @gray-bg; // superset-var +@body-bg: #000; // ** Global text color on ``. -@text-color: @gray-dark; +@text-color: #d1d1d1; // ** Global textual link color. @link-color: @link; @@ -812,7 +812,7 @@ // // ## -@code-color: darken(@info, @colorstop-one); +@code-color: darken(@info, 10%); @code-bg: @gray-bg; // superset-var @kbd-color: @lightest; // superset-var diff --git a/superset-frontend/src/assets/stylesheets/less/cosmo/variables.less.hbs b/superset-frontend/src/assets/stylesheets/less/cosmo/variables.less.hbs new file mode 100644 index 0000000000000..ffecf926a5032 --- /dev/null +++ b/superset-frontend/src/assets/stylesheets/less/cosmo/variables.less.hbs @@ -0,0 +1,851 @@ +/** + * 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. + */ +// Forked Cosmo 3.3.7 +// Variables +// -------------------------------------------------- + +// == Colors +// +// ## Gray and brand colors for use across Bootstrap. + +@gray-base: @darkest; // superset-var +@gray-darker: lighten(@gray-base, 13.5%); +@gray-dark: lighten(@gray-base, 20%); +@bs-gray: lighten(@gray-base, 33.5%); +@bs-gray-light: lighten(@gray-base, 60%); +@gray-lighter: lighten(@gray-base, 95%); + +@brand-primary: @primary-color; // superset-var +@brand-success: @success; // superset-var +@brand-info: @info; // superset-var +@brand-warning: @warning; // superset-var +@brand-danger: @danger; // superset-var + +// == Scaffolding +// +// ## Settings for some of the most global styles. + +// ** Background color for ``. +@body-bg: {{theme.antd.colorBgBase}}; +// ** Global text color on ``. +@text-color: {{theme.colors.grayscale.dark3}}; + +// ** Global textual link color. +@link-color: @link; +// ** Link hover color set via `darken()` function. +@link-hover-color: @link-hover; +// ** Link hover decoration. +@link-hover-decoration: underline; + +// == Typography +// +// ## Font, line-height, and color for body text, headings, and more. + +@font-size-large: ceil((@font-size-base * 1.25)); // ~18px +@font-size-small: ceil((@font-size-base * 0.85)); // ~12px + +@font-size-h1: floor((@font-size-base * 2.6)); // ~36px +@font-size-h2: floor((@font-size-base * 2.15)); // ~30px +@font-size-h3: ceil((@font-size-base * 1.7)); // ~24px +@font-size-h4: ceil((@font-size-base * 1.25)); // ~18px +@font-size-h5: @font-size-base; +@font-size-h6: ceil((@font-size-base * 0.85)); // ~12px + +// ** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc. +@line-height-computed: floor((@font-size-base * @line-height-base)); + +// ** By default, this inherits from the ``. +@headings-font-family: @font-family-base; +@headings-font-weight: @font-weight-normal; // superset-var +@headings-line-height: @line-height-tight; +@headings-color: inherit; + +// == Iconography +// +// ## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower. + +// ** Load fonts from this directory. +@icon-font-path: '../fonts/'; +// ** File name for all font files. +@icon-font-name: 'glyphicons-halflings-regular'; +// ** Element ID within SVG icon file. +@icon-font-svg-id: 'glyphicons_halflingsregular'; + +// == Components +// +// ## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start). + +@padding-base-vertical: 6.5px; +@padding-base-horizontal: 18px; + +@padding-large-vertical: 18px; +@padding-large-horizontal: 30px; + +@padding-small-vertical: 5px; +@padding-small-horizontal: 10px; + +@padding-xs-vertical: 1px; +@padding-xs-horizontal: 5px; + +@line-height-large: 1.3333333; // extra decimals for Win 8.1 Chrome +@line-height-small: 1.5; + +@border-radius-base: @border-radius-normal; +@border-radius-large: 4px; +@border-radius-small: 4px; + +// ** Global color for active items (e.g., navs or dropdowns). +@component-active-color: @lightest; // superset-var +// ** Global background color for active items (e.g., navs or dropdowns). +@component-active-bg: @brand-primary; + +// ** Width of the `border` for generating carets that indicate dropdowns. +@caret-width-base: 4px; +// ** Carets increase slightly in size for larger components. +@caret-width-large: 5px; + +// == Tables +// +// ## Customizes the `.table` component with basic values, each used across all table variations. + +// ** Padding for ``s and ``s. +@table-cell-padding: 8px; +// ** Padding for cells in `.table-condensed`. +@table-condensed-cell-padding: 5px; + +// ** Default background color used for all tables. +@table-bg: transparent; +// ** Background color used for `.table-striped`. +@table-bg-accent: fade(@gray-bg, @opacity-medium-light); // superset-var +// ** Background color used for `.table-hover`. +@table-bg-hover: @gray-bg; // superset-var +@table-bg-active: @table-bg-hover; + +// ** Border color for table and cell borders. +@table-border-color: @gray-light; // superset-var + +// == Buttons +// +// ## For each of Bootstrap's buttons, define text, background and border color. + +@btn-font-weight: normal; + +@btn-primary-color: @lightest; +@btn-primary-bg: @brand-primary; +@btn-primary-border: @brand-primary; + +@btn-default-color: @bs-gray; +@btn-default-bg: @lightest; +@btn-default-border: @gray-light; + +@btn-success-color: @btn-primary-color; +@btn-success-bg: @brand-success; +@btn-success-border: @btn-success-bg; + +@btn-info-color: @btn-primary-color; +@btn-info-bg: @brand-info; +@btn-info-border: @btn-info-bg; + +@btn-warning-color: @btn-primary-color; +@btn-warning-bg: @brand-warning; +@btn-warning-border: @btn-warning-bg; + +@btn-danger-color: @btn-primary-color; +@btn-danger-bg: @brand-danger; +@btn-danger-border: @btn-danger-bg; + +@btn-link-disabled-color: @bs-gray-light; + +// Allows for customizing button radius independently from global border radius +@btn-border-radius-base: @border-radius-base; +@btn-border-radius-large: @border-radius-large; +@btn-border-radius-small: @border-radius-small; + +// == Forms +// +// ## + +// ** `` background color +@input-bg: @lightest; // superset-var +// ** `` background color +@input-bg-disabled: @gray-lighter; + +// ** Text color for ``s +@input-color: @text-color; +// ** `` border color +@input-border: @gray-light; // superset-var + +// TODO: Rename `@input-border-radius` to `@input-border-radius-base` in v4 +// ** Default `.form-control` border radius +// This has no effect on ``s in CSS. +@input-border-radius: @border-radius-base; +// ** Large `.form-control` border radius +@input-border-radius-large: @border-radius-large; +// ** Small `.form-control` border radius +@input-border-radius-small: @border-radius-small; + +// ** Border color for inputs on focus +@input-border-focus: @indicator-color; // superset-var + +// ** Placeholder text color +@input-color-placeholder: @bs-gray-light; + +// ** Default `.form-control` height +@input-height-base: (@line-height-computed + (@padding-base-vertical * 2) + 2); +// ** Large `.form-control` height +@input-height-large: ( + ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + + 2 +); +// ** Small `.form-control` height +@input-height-small: ( + floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + + 2 +); + +// ** `.form-group` margin +@form-group-margin-bottom: 16px; + +@legend-color: @text-color; +@legend-border-color: @gray-bg; + +// ** Background color for textual input addons +@input-group-addon-bg: @gray-lighter; +// ** Border color for textual input addons +@input-group-addon-border-color: @input-border; + +// ** Disabled cursor for form controls and buttons. +@cursor-disabled: not-allowed; + +// == Dropdowns +// +// ## Dropdown menu container and contents. + +// ** Background for the dropdown menu. +@dropdown-bg: @lightest; // superset-var +// ** Dropdown menu `border-color`. +@dropdown-border: fade(@darkest, @opacity-light); // superset-var +// ** Dropdown menu `border-color` **for IE8**. +@dropdown-fallback-border: @gray-light; // superset-var +// ** Divider color for between dropdown items. +@dropdown-divider-bg: @gray-bg; // superset-var + +// ** Dropdown link text color. +@dropdown-link-color: @gray-dark; +// ** Hover color for dropdown links. +@dropdown-link-hover-color: @lightest; // superset-var +// ** Hover background for dropdown links. +@dropdown-link-hover-bg: @component-active-bg; + +// ** Active dropdown menu item text color. +@dropdown-link-active-color: @lightest; // superset-var +// ** Active dropdown menu item background color. +@dropdown-link-active-bg: @component-active-bg; + +// ** Disabled dropdown menu item background color. +@dropdown-link-disabled-color: @bs-gray-light; + +// ** Text color for headers within dropdown menus. +@dropdown-header-color: @bs-gray-light; + +// ** Deprecated `@dropdown-caret-color` as of v3.1.0 +@dropdown-caret-color: @darkest; // superset-var + +//-- Z-index master list +// +// Warning: Avoid customizing these values. They're used for a bird's eye view +// of components dependent on the z-axis and are designed to all work together. +// +// Note: These variables are not generated into the Customizer. + +@zindex-navbar: 1000; +@zindex-dropdown: 1000; +@zindex-popover: 1060; +@zindex-tooltip: 1070; +@zindex-navbar-fixed: 1030; +@zindex-modal-background: 1040; +@zindex-modal: 1050; + +// == Media queries breakpoints +// +// ## Define the breakpoints at which your layout will change, adapting to different screen sizes. + +// Extra small screen / phone +// ** Deprecated `@screen-xs` as of v3.0.1 +@screen-xs: 480px; +// ** Deprecated `@screen-xs-min` as of v3.2.0 +@screen-xs-min: @screen-xs; +// ** Deprecated `@screen-phone` as of v3.0.1 +@screen-phone: @screen-xs-min; + +// Small screen / tablet +// ** Deprecated `@screen-sm` as of v3.0.1 +@screen-sm: 768px; +@screen-sm-min: @screen-sm; +// ** Deprecated `@screen-tablet` as of v3.0.1 +@screen-tablet: @screen-sm-min; + +// Medium screen / desktop +// ** Deprecated `@screen-md` as of v3.0.1 +@screen-md: 992px; +@screen-md-min: @screen-md; +// ** Deprecated `@screen-desktop` as of v3.0.1 +@screen-desktop: @screen-md-min; + +// Large screen / wide desktop +// ** Deprecated `@screen-lg` as of v3.0.1 +@screen-lg: 1200px; +@screen-lg-min: @screen-lg; +// ** Deprecated `@screen-lg-desktop` as of v3.0.1 +@screen-lg-desktop: @screen-lg-min; + +// So media queries don't overlap when required, provide a maximum +@screen-xs-max: (@screen-sm-min - 1); +@screen-sm-max: (@screen-md-min - 1); +@screen-md-max: (@screen-lg-min - 1); + +// == Grid system +// +// ## Define your custom responsive grid. + +// ** Number of columns in the grid. +@grid-columns: 12; +// ** Padding between columns. Gets divided in half for the left and right. +@grid-gutter-width: 20px; +// Navbar collapse +// ** Point at which the navbar becomes uncollapsed. +@grid-float-breakpoint: @screen-sm-min; +// ** Point at which the navbar begins collapsing. +@grid-float-breakpoint-max: (@grid-float-breakpoint - 1); + +// == Container sizes +// +// ## Define the maximum width of `.container` for different screen sizes. + +// Small screen / tablet +@container-tablet: (720px + @grid-gutter-width); +// ** For `@screen-sm-min` and up. +@container-sm: @container-tablet; + +// Medium screen / desktop +@container-desktop: (940px + @grid-gutter-width); +// ** For `@screen-md-min` and up. +@container-md: @container-desktop; + +// Large screen / wide desktop +@container-large-desktop: (1140px + @grid-gutter-width); +// ** For `@screen-lg-min` and up. +@container-lg: @container-large-desktop; + +// == Navbar +// +// ## + +// Basics of a navbar +@navbar-height: 50px; +@navbar-margin-bottom: @line-height-computed; +@navbar-border-radius: @border-radius-base; +@navbar-padding-horizontal: floor((@grid-gutter-width / 2)); +@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2); +@navbar-collapse-max-height: 340px; + +@navbar-default-color: @lightest; // superset-var +@navbar-default-bg: @gray-darker; +@navbar-default-border: darken(@navbar-default-bg, 6.5%); + +// Navbar links +@navbar-default-link-color: @lightest; // superset-var +@navbar-default-link-hover-color: @lightest; // superset-var +@navbar-default-link-hover-bg: darken(@navbar-default-bg, 10%); +@navbar-default-link-active-color: @navbar-default-link-hover-color; +@navbar-default-link-active-bg: @navbar-default-link-hover-bg; +@navbar-default-link-disabled-color: @gray-light; // superset-var +@navbar-default-link-disabled-bg: transparent; + +// Navbar brand label +@navbar-default-brand-color: @navbar-default-link-color; +@navbar-default-brand-hover-color: @lightest; // superset-var +@navbar-default-brand-hover-bg: none; + +// Navbar toggle +@navbar-default-toggle-hover-bg: @navbar-default-link-hover-bg; +@navbar-default-toggle-icon-bar-bg: @lightest; // superset-var +@navbar-default-toggle-border-color: transparent; + +// === Inverted navbar +// Reset inverted navbar basics +@navbar-inverse-color: @gray-dark; +@navbar-inverse-bg: @lightest; // superset-var +@navbar-inverse-border: transparent; + +// Inverted navbar links +@navbar-inverse-link-color: @gray-dark; +@navbar-inverse-link-hover-color: @gray-dark; +@navbar-inverse-link-hover-bg: darken(@navbar-inverse-bg, 10%); +@navbar-inverse-link-active-color: @navbar-inverse-link-hover-color; +@navbar-inverse-link-active-bg: @navbar-inverse-link-hover-bg; +@navbar-inverse-link-disabled-color: @gray-lighter; +@navbar-inverse-link-disabled-bg: transparent; + +// Inverted navbar brand label +@navbar-inverse-brand-color: @navbar-inverse-link-color; +@navbar-inverse-brand-hover-color: @gray-darker; +@navbar-inverse-brand-hover-bg: none; + +// Inverted navbar toggle +@navbar-inverse-toggle-hover-bg: @navbar-inverse-link-hover-bg; +@navbar-inverse-toggle-icon-bar-bg: @lightest; // superset-var +@navbar-inverse-toggle-border-color: transparent; + +// == Navs +// +// ## + +// === Shared nav styles +@nav-link-padding: 10px 15px; +@nav-link-hover-bg: @gray-lighter; + +@nav-disabled-link-color: @bs-gray-light; +@nav-disabled-link-hover-color: @bs-gray-light; + +// == Tabs +@nav-tabs-border-color: @gray-light; // superset-var + +@nav-tabs-link-hover-border-color: @gray-lighter; + +@nav-tabs-active-link-hover-bg: @body-bg; +@nav-tabs-active-link-hover-color: @bs-gray; +@nav-tabs-active-link-hover-border-color: @gray-light; // superset-var + +@nav-tabs-justified-link-border-color: @gray-light; // superset-var +@nav-tabs-justified-active-link-border-color: @body-bg; + +// == Pills +@nav-pills-border-radius: @border-radius-base; +@nav-pills-active-link-hover-bg: @component-active-bg; +@nav-pills-active-link-hover-color: @component-active-color; + +// == Pagination +// +// ## + +@pagination-color: @link-color; +@pagination-bg: @lightest; // superset-var +@pagination-border: @gray-light; // superset-var + +@pagination-hover-color: @link-hover-color; +@pagination-hover-bg: @gray-lighter; +@pagination-hover-border: @gray-light; // superset-var + +@pagination-active-color: @bs-gray-light; +@pagination-active-bg: @gray-bg; // superset-var +@pagination-active-border: @gray-light; // superset-var + +@pagination-disabled-color: @bs-gray-light; +@pagination-disabled-bg: @lightest; // superset-var +@pagination-disabled-border: @gray-light; // superset-var + +// == Pager +// +// ## + +@pager-bg: @pagination-bg; +@pager-border: @pagination-border; +@pager-border-radius: @border-radius-base; + +@pager-hover-bg: @pagination-hover-bg; + +@pager-active-bg: @pagination-active-bg; +@pager-active-color: @pagination-active-color; + +@pager-disabled-color: @bs-gray-light; + +// == Jumbotron +// +// ## + +@jumbotron-padding: 30px; +@jumbotron-color: inherit; +@jumbotron-bg: @gray-lighter; +@jumbotron-heading-color: inherit; +@jumbotron-font-size: ceil((@font-size-base * 1.5)); +@jumbotron-heading-font-size: ceil((@font-size-base * 4.5)); + +// == Form states and alerts +// +// ## Define colors for form feedback states and, by default, alerts. + +@state-success-text: @success-dark2; +@state-success-bg: @success-light2; +@state-success-border: @success-light2; + +@state-info-text: @info-dark2; +@state-info-bg: @info-light2; +@state-info-border: @info-light2; + +@state-warning-text: @warning-dark2; +@state-warning-bg: @warning-light2; +@state-warning-border: @warning-light2; + +@state-danger-text: @danger-dark2; +@state-danger-bg: @danger-light2; +@state-danger-border: @danger-light2; + +// == Tooltips +// +// ## + +// ** Tooltip max width +@tooltip-max-width: 200px; +// ** Tooltip text color +@tooltip-color: @lightest; // superset-var +// ** Tooltip background color +@tooltip-bg: @darkest; // superset-var +@tooltip-opacity: 0.9; + +// ** Tooltip arrow width +@tooltip-arrow-width: 5px; +// ** Tooltip arrow color +@tooltip-arrow-color: @tooltip-bg; + +// == Popovers +// +// ## + +// ** Popover body background color +@popover-bg: @lightest; // superset-var +// ** Popover maximum width +@popover-max-width: 276px; +// ** Popover border color +@popover-border-color: fade(@darkest, @opacity-light); // superset-var +// ** Popover fallback border color +@popover-fallback-border-color: @gray-light; // superset-var + +// ** Popover title background color +@popover-title-bg: darken(@popover-bg, 3%); + +// ** Popover arrow width +@popover-arrow-width: 10px; +// ** Popover arrow color +@popover-arrow-color: @popover-bg; + +// ** Popover outer arrow width +@popover-arrow-outer-width: (@popover-arrow-width + 1); +// ** Popover outer arrow color +@popover-arrow-outer-color: fadein(@popover-border-color, 5%); +// ** Popover outer arrow fallback color +@popover-arrow-outer-fallback-color: darken( + @popover-fallback-border-color, + 20% +); + +// == Labels +// +// ## + +// ** Default label background color +@label-default-bg: @bs-gray-light; +// ** Primary label background color +@label-primary-bg: @brand-primary; +// ** Success label background color +@label-success-bg: @brand-success; +// ** Info label background color +@label-info-bg: @brand-info; +// ** Warning label background color +@label-warning-bg: darken(@brand-warning, 6%); +// ** Danger label background color +@label-danger-bg: @brand-danger; + +// ** Default label text color +@label-color: @lightest; // superset-var +// ** Default text color of a linked label +@label-link-hover-color: @lightest; // superset-var + +// == Modals +// +// ## + +// ** Padding applied to the modal body +@modal-inner-padding: 20px; + +// ** Padding applied to the modal title +@modal-title-padding: 15px; +// ** Modal title line-height +@modal-title-line-height: @line-height-base; + +// ** Background color of modal content area +@modal-content-bg: @lightest; // superset-var +// ** Modal content border color +@modal-content-border-color: transparent; +// ** Modal content border color **for IE8** +@modal-content-fallback-border-color: @gray; // superset-var + +// ** Modal backdrop background color +@modal-backdrop-bg: @darkest; // superset-var +// ** Modal backdrop opacity +@modal-backdrop-opacity: 0.5; +// ** Modal header border color +@modal-header-border-color: @gray-bg; // superset-var +// ** Modal footer border color +@modal-footer-border-color: @modal-header-border-color; + +@modal-lg: 900px; +@modal-md: 600px; +@modal-sm: 300px; + +// == Alerts +// +// ## Define alert colors, border radius, and padding. + +@alert-padding: 15px; +@alert-border-radius: @border-radius-base; +@alert-link-font-weight: @font-weight-bold; + +@alert-success-bg: @state-success-bg; +@alert-success-text: @state-success-text; +@alert-success-border: @state-success-border; + +@alert-info-bg: @state-info-bg; +@alert-info-text: @state-info-text; +@alert-info-border: @state-info-border; + +@alert-warning-bg: @state-warning-bg; +@alert-warning-text: @state-warning-text; +@alert-warning-border: @state-warning-border; + +@alert-danger-bg: @state-danger-bg; +@alert-danger-text: @state-danger-text; +@alert-danger-border: @state-danger-border; + +// == Progress bars +// +// ## + +// ** Background color of the whole progress component +@progress-bg: @gray-light; // superset-var +// ** Progress bar text color +@progress-bar-color: @lightest; // superset-var +// ** Variable for setting rounded corners on progress bar. +@progress-border-radius: @border-radius-base; + +// ** Default progress bar color +@progress-bar-bg: @brand-primary; +// ** Success progress bar color +@progress-bar-success-bg: @brand-success; +// ** Warning progress bar color +@progress-bar-warning-bg: @brand-warning; +// ** Danger progress bar color +@progress-bar-danger-bg: @brand-danger; +// ** Info progress bar color +@progress-bar-info-bg: @brand-info; + +// == List group +// +// ## + +// ** Background color on `.list-group-item` +@list-group-bg: @lightest; // superset-var +// ** `.list-group-item` border color +@list-group-border: @gray-light; // superset-var +// ** List group border radius +@list-group-border-radius: @border-radius-base; + +// ** Background color of single list items on hover +@list-group-hover-bg: @gray-bg; // superset-var +// ** Text color of active list items +@list-group-active-color: @component-active-color; +// ** Background color of active list items +@list-group-active-bg: @component-active-bg; +// ** Border color of active list elements +@list-group-active-border: @list-group-border; +// ** Text color for content within active list items +@list-group-active-text-color: lighten(@list-group-active-bg, 40%); + +// ** Text color of disabled list items +@list-group-disabled-color: @bs-gray-light; +// ** Background color of disabled list items +@list-group-disabled-bg: @gray-lighter; +// ** Text color for content within disabled list items +@list-group-disabled-text-color: @list-group-disabled-color; + +@list-group-link-color: #555; +@list-group-link-hover-color: @list-group-link-color; +@list-group-link-heading-color: @almost-black; // superset-var + +// == Panels +// +// ## + +@panel-bg: @lightest; // superset-var +@panel-body-padding: 15px; +@panel-heading-padding: 10px 15px; +@panel-footer-padding: @panel-heading-padding; +@panel-border-radius: @border-radius-base; + +// ** Border color for elements within panels +@panel-inner-border: @gray-light; // superset-var +@panel-footer-bg: @gray-bg; // superset-var + +@panel-default-text: @gray-dark; +@panel-default-border: transparent; +@panel-default-heading-bg: @lightest; // superset-var + +@panel-primary-text: @lightest; // superset-var +@panel-primary-border: transparent; +@panel-primary-heading-bg: @brand-primary; + +@panel-success-text: @state-success-text; +@panel-success-border: transparent; +@panel-success-heading-bg: @state-success-bg; + +@panel-info-text: @state-info-text; +@panel-info-border: transparent; +@panel-info-heading-bg: @state-info-bg; + +@panel-warning-text: @state-warning-text; +@panel-warning-border: transparent; +@panel-warning-heading-bg: @state-warning-bg; + +@panel-danger-text: @state-danger-text; +@panel-danger-border: transparent; +@panel-danger-heading-bg: @state-danger-bg; + +// == Thumbnails +// +// ## + +// ** Padding around the thumbnail image +@thumbnail-padding: 4px; +// ** Thumbnail background color +@thumbnail-bg: @body-bg; +// ** Thumbnail border color +@thumbnail-border: @gray-light; // superset-var +// ** Thumbnail border radius +@thumbnail-border-radius: @border-radius-base; + +// ** Custom text color for thumbnail captions +@thumbnail-caption-color: @text-color; +// ** Padding around the thumbnail caption +@thumbnail-caption-padding: 9px; + +// == Wells +// +// ## + +@well-bg: @gray-bg; // superset-var +@well-border: darken(@well-bg, 7%); + +// == Badges +// +// ## + +@badge-color: @lightest; // superset-var +// ** Linked badge text color on hover +@badge-link-hover-color: @lightest; // superset-var +@badge-bg: @brand-primary; + +// ** Badge text color in active nav link +@badge-active-color: @link-color; +// ** Badge background color in active nav link +@badge-active-bg: @lightest; // superset-var + +@badge-font-weight: @font-weight-bold; +@badge-line-height: 1; +@badge-border-radius: 10px; + +// == Breadcrumbs +// +// ## + +@breadcrumb-padding-vertical: 8px; +@breadcrumb-padding-horizontal: 15px; +// ** Breadcrumb background color +@breadcrumb-bg: @gray-bg; // superset-var +// ** Breadcrumb text color +@breadcrumb-color: @gray-light; // superset-var +// ** Text color of current page in the breadcrumb +@breadcrumb-active-color: @bs-gray-light; +// ** Textual separator for between breadcrumb elements +@breadcrumb-separator: '/'; + +// == Carousel +// +// ## + +@carousel-text-shadow: 0 1px 2px fade(@darkest, @opacity-light); // superset-var + +@carousel-control-color: @lightest; // superset-var +@carousel-control-width: 15%; +@carousel-control-opacity: 0.5; +@carousel-control-font-size: 20px; + +@carousel-indicator-active-bg: @lightest; // superset-var +@carousel-indicator-border-color: @lightest; // superset-var + +@carousel-caption-color: @lightest; // superset-var + +// == Close +// +// ## + +@close-font-weight: @font-weight-bold; +@close-color: @lightest; // superset-var +@close-text-shadow: 0 1px 0 @lightest; // superset-var + +// == Code +// +// ## + +@code-color: darken(@info, 10%); +@code-bg: @gray-bg; // superset-var + +@kbd-color: @lightest; // superset-var +@kbd-bg: @almost-black; // superset-var + +@pre-bg: @gray-bg; // superset-var +@pre-color: @gray-dark; +@pre-border-color: @gray-light; // superset-var +@pre-scrollable-max-height: 340px; + +// == Type +// +// ## + +// ** Horizontal offset for forms and lists. +@component-offset-horizontal: 180px; +// ** Text muted color +@text-muted: @bs-gray-light; +// ** Abbreviations and acronyms border color +@abbr-border-color: @bs-gray-light; +// ** Headings small color +@headings-small-color: @bs-gray-light; +// ** Blockquote small color +@blockquote-small-color: @bs-gray-light; +// ** Blockquote font size +@blockquote-font-size: (@font-size-base * 1.25); +// ** Blockquote border color +@blockquote-border-color: @gray-lighter; +// ** Page header border color +@page-header-border-color: @gray-lighter; +// ** Width of horizontal description list titles +@dl-horizontal-offset: @component-offset-horizontal; +// ** Point at which .dl-horizontal becomes horizontal +@dl-horizontal-breakpoint: @grid-float-breakpoint; +// ** Horizontal line color. +@hr-border: @gray-lighter; diff --git a/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-style/Theme.stories.tsx b/superset-frontend/src/assets/stylesheets/less/fonts.less.hbs similarity index 53% rename from superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-style/Theme.stories.tsx rename to superset-frontend/src/assets/stylesheets/less/fonts.less.hbs index 63ede4a8a7c36..5fb41d832ae02 100644 --- a/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-style/Theme.stories.tsx +++ b/superset-frontend/src/assets/stylesheets/less/fonts.less.hbs @@ -1,4 +1,4 @@ -/* +/** * 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 @@ -17,31 +17,17 @@ * under the License. */ -import { supersetTheme } from '@superset-ui/core'; +/*************************************************************************/ +/* USAGE NOTES : Add font all licenses to LICENSE.text */ +/*************************************************************************/ -export default { - title: 'Core Packages/@superset-ui-style', -}; +/******************************* Inter UI ********************************/ +@import '~@fontsource/inter/200.css'; +@import '~@fontsource/inter/400.css'; +@import '~@fontsource/inter/500.css'; +@import '~@fontsource/inter/600.css'; -export const ThemeColors = () => { - const { colors } = supersetTheme; - return Object.keys(colors).map(collection => ( -
-

{collection}

- - {Object.keys(colors[collection]).map(k => { - const hex = colors[collection][k]; - return ( - - - - - ); - })} -
{k} - {hex} - -
-
- )); -}; +/******************************* Fira Code ********************************/ +@import '~@fontsource/fira-code/400.css'; +@import '~@fontsource/fira-code/500.css'; +@import '~@fontsource/fira-code/600.css'; diff --git a/superset-frontend/src/components/AntdThemeProvider/index.tsx b/superset-frontend/src/assets/stylesheets/less/index.less.hbs similarity index 62% rename from superset-frontend/src/components/AntdThemeProvider/index.tsx rename to superset-frontend/src/assets/stylesheets/less/index.less.hbs index 03cc8e2c488a3..fc91c477dbeb5 100644 --- a/superset-frontend/src/components/AntdThemeProvider/index.tsx +++ b/superset-frontend/src/assets/stylesheets/less/index.less.hbs @@ -16,12 +16,32 @@ * specific language governing permissions and limitations * under the License. */ +// Index .less, any imports here will be included in the final css build -import { ConfigProvider, type ConfigProviderProps } from 'antd-v5'; -import { getTheme, ThemeType } from 'src/theme/index'; +@import '~bootstrap/less/bootstrap.less'; +@import './fonts.less'; +@import './variables.less'; +@import './cosmo/bootswatch.less'; -export const AntdThemeProvider = ({ theme, children }: ConfigProviderProps) => ( - - {children} - -); +html, +body { + font-size: @font-size-base; + line-height: @line-height-base; +} + +body { + min-height: 100vh; + display: flex; + flex-direction: column; +} + +header { + flex: 0 1 auto; +} + +#app { + flex: 1 1 auto; + position: relative; + display: flex; + flex-direction: column; +} diff --git a/superset-frontend/src/assets/stylesheets/less/variables.less b/superset-frontend/src/assets/stylesheets/less/variables.less index fe9b8987fd041..d567e20ec3211 100644 --- a/superset-frontend/src/assets/stylesheets/less/variables.less +++ b/superset-frontend/src/assets/stylesheets/less/variables.less @@ -19,71 +19,73 @@ /************************************************************************/ /* COLORS */ -/* Please attempt to use and standardize on these colors, */ -/* rather than including specific color values in */ -/* component styles. This will allow us to more easily adjust theming */ /************************************************************************/ @primary-color: #20a7c9; @indicator-color: @primary-color; -@brand-primary-dark1: #1a85a0; -@brand-primary-dark2: #156378; -@brand-primary-light1: #79cade; -@brand-primary-light2: #a5dae9; -@brand-primary-light3: #d2edf4; -@brand-primary-light4: #e9f6f9; -@brand-primary-light5: #f3f8fa; +@brand-primary-dark1: #4db9d4; +@brand-primary-dark2: #84cfe1; +@brand-primary-light1: #1d96b5; +@brand-primary-light2: #1a86a1; +@brand-primary-light3: #136479; +@brand-primary-light4: #0d4350; +@brand-primary-light5: #062128; @brand-secondary: #444e7c; -@brand-secondary-dark1: #363e63; -@brand-secondary-dark2: #282e4a; -@brand-secondary-dark3: #1b1f31; -@brand-secondary-light1: #8e94b0; -@brand-secondary-light2: #b4b8ca; -@brand-secondary-light3: #d9dbe4; -@brand-secondary-light4: #eceef2; -@brand-secondary-light5: #f5f5f8; - -@almost-black: #263238; -@gray-dark: #484848; -@gray-light: #e0e0e0; -@gray-light5: #666666; -@gray: #879399; -@gray-bg: #f7f7f7; -@gray-heading: #a3a3a3; -@menu-hover: #f2f3f5; -@lightest: #ffffff; -@darkest: #000000; +@brand-secondary-dark1: #697196; +@brand-secondary-dark2: #989eb7; +@brand-secondary-dark3: #c7cad8; +@brand-secondary-light1: #3d4670; +@brand-secondary-light2: #363e63; +@brand-secondary-light3: #292f4a; +@brand-secondary-light4: #1b1f32; +@brand-secondary-light5: #0e1019; + +// TODO line up with theme +@almost-black: #f7f7f7; +@gray-dark: #d1d1d1; +@gray-light: #292929; +@gray-light5: #FFF; +@gray: #20a7c9; +@gray-bg: #292929; +@gray-heading: #858585; +@menu-hover: ; +@lightest: #000; +@darkest: #FFF; + +@body-bg: #000; /**************************** text-specific *****************************/ -@link: #1985a0; -@link-hover: darken(@link, @colorstop-one); +@text-color: #fff; +@heading-color: #fff; +@link: #4db9d4; +@link-hover: #84cfe1; /***************************** status colors ****************************/ @info: #66bcfe; -@info-dark1: #4d8cbe; -@info-dark2: #315e7e; -@info-light1: #b3defe; -@info-light2: #eff8fe; +@info-dark1: #85c9fe; +@info-dark2: #abdafe; +@info-light1: #5ca9e5; +@info-light2: #5296cb; @danger: #e04355; -@danger-dark1: #a7323f; -@danger-dark2: #6f212a; -@danger-light1: #efa1aa; -@danger-light2: #faedee; +@danger-dark1: #e66977; +@danger-dark2: #ee98a2; +@danger-light1: #ca3c4d; +@danger-light2: #b33644; @success: #5ac189; -@success-dark1: #439066; -@success-dark2: #2b6144; -@success-light1: #ace1c4; -@success-light2: #eef8f3; +@success-dark1: #7bcda1; +@success-dark2: #a4ddbe; +@success-light1: #51ae7b; +@success-light2: #489a6e; @warning: #fcc700; -@warning-dark1: #bc9501; -@warning-dark2: #7d6300; -@warning-light1: #fde380; -@warning-light2: #fef9e6; +@warning-dark1: #fdd233; +@warning-dark2: #fde073; +@warning-light1: #e3b300; +@warning-light2: #ca9f00; /* general component effects */ @shadow-highlight: @primary-color; @@ -141,19 +143,16 @@ /* Commonly used font weights, line heights, etc. These should be the */ /* core values used to build more complex styles for headers, etc. */ /************************************************************************/ +@font-size-base: 14px; // Base `rem` units on this, as needed. -// *************************** Weights ********************************** @font-weight-light: 200; @font-weight-normal: 400; @font-weight-bold: 600; -// ***************************** Font Sizes ***************************** -@font-size-base: 14px; // Base `rem` units on this, as needed. - @font-size-xxs: 9px; @font-size-xs: 10px; @font-size-s: 12px; -@font-size-m: @font-size-base; +@font-size-m: 14px; @font-size-l: 16px; @font-size-xl: 21px; @font-size-xxl: 28px; @@ -184,14 +183,15 @@ } // ****************************** Families ****************************** + @font-family-sans-serif: 'Inter', Helvetica, Arial; @font-family-serif: Georgia, 'Times New Roman', Times, serif; @font-family-monospace: 'Fira Code', 'Courier New', monospace; @font-family-base: @font-family-sans-serif; +@line-height-tight: 1; /************************************************************************/ /* TRANSITIONS */ -/* Timing and easings presets used in CSS transitions */ /************************************************************************/ @timing-normal: 0.3s; diff --git a/superset-frontend/src/assets/stylesheets/less/variables.less.hbs b/superset-frontend/src/assets/stylesheets/less/variables.less.hbs new file mode 100644 index 0000000000000..b811d776e353f --- /dev/null +++ b/superset-frontend/src/assets/stylesheets/less/variables.less.hbs @@ -0,0 +1,212 @@ +/** + * 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. + */ + +/************************************************************************/ +/* COLORS */ +/************************************************************************/ + +@primary-color: {{theme.colors.primary.base}}; +@indicator-color: @primary-color; + +@brand-primary-dark1: {{theme.colors.primary.dark1}}; +@brand-primary-dark2: {{theme.colors.primary.dark2}}; +@brand-primary-light1: {{theme.colors.primary.light1}}; +@brand-primary-light2: {{theme.colors.primary.light2}}; +@brand-primary-light3: {{theme.colors.primary.light3}}; +@brand-primary-light4: {{theme.colors.primary.light4}}; +@brand-primary-light5: {{theme.colors.primary.light5}}; + +@brand-secondary: {{theme.colors.secondary.base}}; +@brand-secondary-dark1: {{theme.colors.secondary.dark1}}; +@brand-secondary-dark2: {{theme.colors.secondary.dark2}}; +@brand-secondary-dark3: {{theme.colors.secondary.dark3}}; +@brand-secondary-light1: {{theme.colors.secondary.light1}}; +@brand-secondary-light2: {{theme.colors.secondary.light2}}; +@brand-secondary-light3: {{theme.colors.secondary.light3}}; +@brand-secondary-light4: {{theme.colors.secondary.light4}}; +@brand-secondary-light5: {{theme.colors.secondary.light5}}; + +// TODO line up with theme +@almost-black: {{theme.colors.grayscale.dark5}}; +@gray-dark: {{theme.colors.grayscale.dark3}}; +@gray-light: {{theme.colors.grayscale.light4}}; +@gray-light5: {{theme.colors.darkest}}; +@gray: {{theme.colors.primary.base}}; +@gray-bg: {{theme.colors.grayscale.light4}}; +@gray-heading: {{theme.colors.grayscale.dark1}}; +@menu-hover: {{theme.colors.base.dark1}}; +@lightest: {{theme.colors.lightest}}; +@darkest: {{theme.colors.darkest}}; + +@body-bg: {{theme.colors.lightest}}; + +/**************************** text-specific *****************************/ +@text-color: {{theme.antd.colorTextBase}}; +@heading-color: {{theme.antd.colorTextBase}}; +@link: {{theme.colors.primary.dark1}}; +@link-hover: {{theme.colors.primary.dark2}}; + +/***************************** status colors ****************************/ +@info: {{theme.colors.info.base}}; +@info-dark1: {{theme.colors.info.dark1}}; +@info-dark2: {{theme.colors.info.dark2}}; +@info-light1: {{theme.colors.info.light1}}; +@info-light2: {{theme.colors.info.light2}}; + +@danger: {{theme.colors.error.base}}; +@danger-dark1: {{theme.colors.error.dark1}}; +@danger-dark2: {{theme.colors.error.dark2}}; +@danger-light1: {{theme.colors.error.light1}}; +@danger-light2: {{theme.colors.error.light2}}; + +@success: {{theme.colors.success.base}}; +@success-dark1: {{theme.colors.success.dark1}}; +@success-dark2: {{theme.colors.success.dark2}}; +@success-light1: {{theme.colors.success.light1}}; +@success-light2: {{theme.colors.success.light2}}; + +@warning: {{theme.colors.warning.base}}; +@warning-dark1: {{theme.colors.warning.dark1}}; +@warning-dark2: {{theme.colors.warning.dark2}}; +@warning-light1: {{theme.colors.warning.light1}}; +@warning-light2: {{theme.colors.warning.light2}}; + +/* general component effects */ +@shadow-highlight: @primary-color; + +/************************************************************************/ +/* OPACITIES */ +/* Used in LESS filters, e.g. fade(@someColorVar, @someOpacityBelow) */ +/************************************************************************/ +@opacity-light: {{theme.opacity.light}}; +@opacity-medium-light: {{theme.opacity.mediumLight}}; +@opacity-medium-heavy: {{theme.opacity.mediumHeavy}}; +@opacity-heavy: {{theme.opacity.heavy}}; + +/************************************************************************/ +/* SHADES & TINTS */ +/* Used in LESS filters for shadint/tinting, */ +/* e.g. shade(@someColorVar, @colorstop-one) to darken */ +/* or tint(@someColorVar, @colorstop-one) to lighten */ +/************************************************************************/ +@colorstop-one: 20%; +@colorstop-two: 40%; +@colorstop-three: 60%; +@colorstop-four: 80%; + +/************************************************************************/ +/* LAYOUT */ +/* Widths and heights of things, that might be referred to often */ +/************************************************************************/ + +/* builder component pane */ +@builder-pane-width: 374px; + +/************************************************************************/ +/* Z-INDEX */ +/* Think of the site as "layers" rather than an arms race of numbers */ +/* Keep these to a minimum */ +/* Label semantic "layers" and add comments for usage notes */ +/* Use double dash modifiers to step up/down from a base layer */ +/* e.g. z-whatever--modifier */ +/************************************************************************/ + +/************************ toast messages, popovers **********************/ +@z-index-max: 3000; + +/***** filters, dashboard editor widgets, Explore reloading overlay *****/ +@z-index-dropdown: @z-index-above-dashboard-charts + 1; +@z-index-above-dashboard-charts: 10; + +/******************************** charts ********************************/ +@z-index-chart--dragging: @z-index-chart + 1; +@z-index-chart: 1; + +/************************************************************************/ +/* TYPOGRAPHY */ +/* Commonly used font weights, line heights, etc. These should be the */ +/* core values used to build more complex styles for headers, etc. */ +/************************************************************************/ +@font-size-base: 14px; // Base `rem` units on this, as needed. + +@font-weight-light: {{theme.typography.weights.light}}; +@font-weight-normal: {{theme.typography.weights.normal}}; +@font-weight-bold: {{theme.typography.weights.bold}}; + +@font-size-xxs: {{theme.typography.sizes.xxs}}px; +@font-size-xs: {{theme.typography.sizes.xs}}px; +@font-size-s: {{theme.typography.sizes.s}}px; +@font-size-m: {{theme.typography.sizes.m}}px; +@font-size-l: {{theme.typography.sizes.l}}px; +@font-size-xl: {{theme.typography.sizes.xl}}px; +@font-size-xxl: {{theme.typography.sizes.xxl}}px; + +// **************************** Line Heights **************************** +@line-height-base: 1.4; +// Ranged Sizes +@line-height-tight: 1; +@line-height-normal: @line-height-base; +@line-height-loose: 2; + +// ****************************** Features ******************************* +@use-ligatures: false; + +// setting up OTF settings based on @use-ligatures: +.set-otf-options(@use-ligatures); + +.set-otf-options(true) { + @font-feature-settings: + 'liga' on, + 'calt' on; +} + +.set-otf-options(false) { + @font-feature-settings: + 'liga' off, + 'calt' off; +} + +// ****************************** Families ****************************** + +@font-family-sans-serif: {{theme.typography.families.sansSerif}}; +@font-family-serif: {{theme.typography.families.serif}}; +@font-family-monospace: {{theme.typography.families.monospace}}; +@font-family-base: @font-family-sans-serif; +@line-height-tight: 1; + +/************************************************************************/ +/* TRANSITIONS */ +/************************************************************************/ +@timing-normal: {{theme.transitionTiming}}s; + +/************************************************************************/ +/* BORDER RADII */ +/* Standard border-radius settings */ +/************************************************************************/ +@border-radius-normal: 4px; +@border-radius-large: (@border-radius-normal * 2); + +/************************************************************************/ +/* BOOTSTRAP/BOOTSWATCH/COSMO */ +/* These are the legacy Cosmo theme overrides to Bootswatch's */ +/* overrides to Bootstrap. We should consolidate/deprecate these */ +/* in favor of custom/reusable CSS wherever possible */ +/************************************************************************/ + +@import '../less/cosmo/variables.less'; diff --git a/superset-frontend/src/assets/stylesheets/reactable-pagination.less.hbs b/superset-frontend/src/assets/stylesheets/reactable-pagination.less.hbs new file mode 100644 index 0000000000000..9b48d2143ab8f --- /dev/null +++ b/superset-frontend/src/assets/stylesheets/reactable-pagination.less.hbs @@ -0,0 +1,61 @@ +/** + * 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 './less/variables.less'; + +.reactable-pagination td { + padding: 15px 0 0 0 !important; +} + +.reactable-pagination a:focus { + text-decoration: none; + color: @gray-dark; + outline: 1; +} + +.reactable-page-button, +.reactable-next-page, +.reactable-previous-page { + background: @lightest; + border-radius: @border-radius-normal; + border: 1px solid @gray-light; + color: @gray-dark; + display: inline-block; + font-size: @font-size-s; + margin-right: 5px; + padding: 5px 10px; + text-align: center; + text-decoration: none; + vertical-align: middle; + white-space: nowrap; + + &:hover { + background-color: @gray-bg; + border-color: @gray; + color: @gray-dark; + text-decoration: none; + } +} + +.reactable-current-page { + border: 1px solid @gray-light; + color: @gray-dark; + font-weight: @font-weight-bold; + pointer-events: none; + opacity: 0.65; +} diff --git a/superset-frontend/src/assets/stylesheets/superset.less.hbs b/superset-frontend/src/assets/stylesheets/superset.less.hbs new file mode 100644 index 0000000000000..7bf8c27fff60e --- /dev/null +++ b/superset-frontend/src/assets/stylesheets/superset.less.hbs @@ -0,0 +1,552 @@ +/** + * 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 './less/index.less'; +@import './less/variables.less'; +@import './less/index.less'; + +@datasource-sql-expression-width: 315px; + +span, +div, +i { + &:focus { + outline: none; + } +} + +.alert.alert-danger > .debugger { + color: @danger; +} + +.no-wrap { + white-space: nowrap; +} + +input.form-control { + background-color: @lightest; +} + +.disabledButton { + pointer-events: none; +} + +.col-left-fixed { + width: 350px; + position: absolute; + float: left; +} + +.col-offset { + margin-left: 365px; +} + +.slice_description { + padding: 8px; + margin: 5px 0; + border: 1px solid @gray-light; + background-color: @gray-bg; + border-radius: @border-radius-large; + font-size: @font-size-s; +} + +.slice_info { + cursor: pointer; +} + +.padded { + padding: 10px; +} + +.intable-longtext { + max-height: 200px; + overflow: auto; +} + +.container-fluid { + text-align: left; + padding-left: 16px; + padding-right: 16px; +} + +input[type='checkbox'] { + display: inline-block; + width: 16px; + height: 16px; +} + +.widget-is-cached { + display: none; +} + +.header span.label { + margin-left: 5px; + margin-right: 5px; +} + +.notbtn { + cursor: default; + box-shadow: none; + border: 1px solid @gray; +} + +hr { + margin-top: 15px; + margin-bottom: 15px; +} + +span.title-block { + background-color: @gray-bg; + border-radius: @border-radius-large; + padding: 6px 12px; + margin: 0px 10px; + font-size: @font-size-xl; +} + +.nvtooltip { + table td { + font-size: @font-size-s !important; + } +} + +div.navbar { + .dropdown-menu .fineprint { + line-height: 1.5rem; + padding: 10px 20px 5px 20px; + color: @gray-light; + font-size: @font-size-m; + + div { + white-space: nowrap; + } + } +} + +.datasource { + form { + div.form-control, + input.form-control { + margin-bottom: 5px !important; + } + } + + .tooltip-inner { + max-width: 350px; + } +} + +img.viz-thumb-option { + width: 100px; + border: 1px solid @gray; + margin-right: 5px; + border-radius: @border-radius-large; +} + +.select2-drop.bigdrop .select2-results { + max-height: 700px; +} + +#is_cached { + display: none; +} + +.slice_container.faded { + opacity: 0.2; +} + +.navbar .alert { + padding: 5px 10px; + margin-top: 8px; + margin-bottom: 0; +} + +.table-condensed { + font-size: @font-size-s; +} + +.table-condensed input[type='checkbox'] { + float: left; +} + +table.table-no-hover tr:hover { + background-color: initial; +} + +.editable-title input { + outline: none; + background: transparent; + border: none; + box-shadow: none; + padding: 0; + cursor: initial; +} + +.editable-title textarea { + outline: none; + background: transparent; + box-shadow: none; + cursor: initial; + border: 1px solid @gray; + border-radius: @border-radius-normal; +} + +.editable-title input[type='text'] { + border: 1px solid @gray; + border-radius: @border-radius-normal; + padding: 2px; +} + +.editable-title.datasource-sql-expression { + font-feature-settings: @font-feature-settings; + font-family: @font-family-monospace; + display: inline-block; + min-width: @datasource-sql-expression-width; + width: 100%; +} + +.editable-title.datasource-sql-expression input { + width: 95%; + padding-bottom: 5px; +} + +.editable-title.datasource-sql-expression textarea { + min-height: 100px; + width: 95%; +} + +.editable-title input[type='button'] { + border-color: transparent; + background: transparent; + font-size: inherit; + white-space: normal; + text-align: left; + cursor: initial; +} + +.editable-title.editable-title--editable input[type='button'] { + cursor: pointer; +} + +.editable-title.editable-title--editing input[type='button'] { + cursor: text; +} + +.anchor-link-container { + position: absolute; + + .btn.btn-sm, + .btn.btn-sm:active { + border: none; + padding-top: 0; + padding-bottom: 0; + background: none; + box-shadow: none; + } + + .fa.fa-link { + position: relative; + top: 2px; + right: 0; + visibility: hidden; + font-size: @font-size-s; + text-align: center; + vertical-align: middle; + } +} + +.dashboard-component.dashboard-component-header .anchor-link-container { + .fa.fa-link { + font-size: @font-size-l; + } +} + +.dashboard-component.dashboard-component-header:hover { + .anchor-link-container { + cursor: pointer; + + .fa.fa-link { + visibility: visible; + } + } +} + +.m-r-5 { + margin-right: 5px; +} + +.m-r-3 { + margin-right: 3px; +} + +.m-t-4 { + margin-top: 4px; +} + +.m-t-5 { + margin-top: 5px; +} + +.m-t-10 { + margin-top: 10px; +} + +.m-t-20 { + margin-top: 20px; +} + +.m-b-10 { + margin-bottom: 10px; +} + +.m-l-2 { + margin-left: 2px; +} + +.m-l-4 { + margin-left: 4px; +} + +.m-l-5 { + margin-left: 5px; +} + +.m-l-10 { + margin-left: 10px; +} + +.m-l-25 { + margin-left: 25px; +} + +.p-l-0 { + padding-left: 0; +} + +.p-t-8 { + padding-top: 8; +} + +.p-r-2 { + padding-right: 2; +} + +.list-container { + position: relative; +} + +.list-search-container { + position: relative; +} + +.list-search-container .dropdown-toggle { + position: absolute; + top: -43px; + right: 25px; + border: 0; + padding: 0 18px; +} + +.list-search-container .fa-filter { + position: relative; + left: -8px; +} + +.list-search-container .dropdown-menu { + top: -19px; + right: 0; + left: auto; + float: none; +} + +.list-container .pagination-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + align-items: center; + padding-bottom: 20px; +} + +.list-container .pagination-container .pagination { + margin: 0 15px; +} + +.list-container .pagination-container strong { + margin-right: 5px; +} + +.list-container .list-add-action { + position: absolute; + top: -30px; + right: 15px; +} + +.list-container .form-actions-container { + padding: 0 0 20px 10px; + display: inline; +} + +.form-actions-container button { + display: flex; + + .caret { + margin: 0 8px; + } +} + +.list-container .filter-action { + margin: 10px 10px 0 10px; + padding-bottom: 15px; +} + +.list-add-action .btn.btn-sm { + padding: 6px 6px; + font-size: @font-size-xs; + line-height: 2px; + border-radius: 50%; + box-shadow: 2px 2px 4px -1px fade(@darkest, @opacity-light); + i { + width: 10px; + } +} + +iframe { + border: none; + width: 100%; +} + +.text-transparent { + color: transparent; +} + +.pointer { + cursor: pointer; +} + +.popover { + max-width: 500px; +} + +.float-left { + float: left; +} + +.float-right { + float: right; +} + +g.annotation-container { + line { + stroke: @brand-primary; + } + + rect.annotation { + stroke: @brand-primary; + fill-opacity: 0.1; + stroke-width: 1; + } +} + +.stroke-primary { + stroke: @brand-primary; +} + +.reactable-header-sortable { + position: relative; + padding-right: 40px; + + &::after { + font: normal normal normal 14px/1 FontAwesome; + content: '\f0dc'; + margin-left: 10px; + color: @brand-primary; + } +} + +.reactable-header-sort-asc::after { + content: '\f0de'; + color: @brand-primary; +} + +.reactable-header-sort-desc::after { + content: '\f0dd'; + color: @brand-primary; +} + +tr.reactable-column-header th.reactable-header-sortable { + padding-right: 17px; +} + +.align-right { + text-align: right; +} + +td.filtered { + background-color: lighten(desaturate(@brand-primary, 50%), 50%); +} + +.table-name { + font-size: @font-size-l; +} +.select2-container-multi { + width: 100% !important; +} + +/* +Hides the logo while loading the page. +Emotion styles will take care of the correct styling +*/ +.navbar-brand { + display: none; +} + +// Making native radio buttons use brand color +input[type='radio']:after { + width: 15px; + height: 15px; + border-radius: 15px; + top: -2px; + left: -1px; + position: relative; + background-color: #fff; + content: ''; + display: inline-block; + visibility: visible; + border: 2px solid @gray; +} + +input[type='radio']:checked:after { + width: 15px; + height: 15px; + border-radius: 15px; + top: -2px; + left: -1px; + position: relative; + background-color: #fff; + content: ''; + display: inline-block; + visibility: visible; + border: 5px solid @brand-primary; +} +hr { + border-top: 1px solid @gray-light; +} +.ace_gutter-cell.ace_error { + background-image: url('../images/icons/error_solid_small_red.svg') !important; + background-position: -2px center !important; +} diff --git a/superset-frontend/src/components/DatePicker/DatePicker.stories.tsx b/superset-frontend/src/components/DatePicker/DatePicker.stories.tsx index 69a2b689aebd2..f74c146d8f575 100644 --- a/superset-frontend/src/components/DatePicker/DatePicker.stories.tsx +++ b/superset-frontend/src/components/DatePicker/DatePicker.stories.tsx @@ -64,9 +64,11 @@ InteractiveDatePicker.args = { InteractiveDatePicker.argTypes = interactiveTypes; -export const InteractiveRangePicker = (args: RangePickerProps) => ( - -); +export const InteractiveRangePicker = ( + args: Omit & { + picker?: 'date'; + }, +) => ; InteractiveRangePicker.args = { ...commonArgs, diff --git a/superset-frontend/src/components/Form/FormLabel.tsx b/superset-frontend/src/components/Form/FormLabel.tsx index bf52dacb82bd1..3400dda46e7cd 100644 --- a/superset-frontend/src/components/Form/FormLabel.tsx +++ b/superset-frontend/src/components/Form/FormLabel.tsx @@ -28,13 +28,13 @@ export type FormLabelProps = { const Label = styled.label` font-size: ${({ theme }) => theme.typography.sizes.s}px; - color: ${({ theme }) => theme.colors.grayscale.base}; + color: ${({ theme }) => theme.colors.grayscale.dark2}; margin-bottom: ${({ theme }) => theme.gridUnit}px; `; const RequiredLabel = styled.label` font-size: ${({ theme }) => theme.typography.sizes.s}px; - color: ${({ theme }) => theme.colors.grayscale.base}; + color: ${({ theme }) => theme.colors.grayscale.dark2}; margin-bottom: ${({ theme }) => theme.gridUnit}px; &::after { display: inline-block; diff --git a/superset-frontend/src/components/Icons/Icons.stories.tsx b/superset-frontend/src/components/Icons/Icons.stories.tsx index 5a21daf5fb7b7..f352abd55feff 100644 --- a/superset-frontend/src/components/Icons/Icons.stories.tsx +++ b/superset-frontend/src/components/Icons/Icons.stories.tsx @@ -28,9 +28,11 @@ export default { const palette = { Default: null }; Object.entries(supersetTheme.colors).forEach(([familyName, family]) => { - Object.entries(family).forEach(([colorName, colorValue]) => { - palette[`${familyName} / ${colorName}`] = colorValue; - }); + Object.entries(family as Record).forEach( + ([colorName, colorValue]) => { + palette[`${familyName} / ${colorName}`] = colorValue; + }, + ); }); const IconSet = styled.div` diff --git a/superset-frontend/src/components/Input/Input.stories.tsx b/superset-frontend/src/components/Input/Input.stories.tsx index 4023c53d97e0f..737c1a859cb76 100644 --- a/superset-frontend/src/components/Input/Input.stories.tsx +++ b/superset-frontend/src/components/Input/Input.stories.tsx @@ -19,7 +19,6 @@ import { InputProps, TextAreaProps } from 'antd-v5/lib/input'; import { InputNumberProps } from 'antd-v5/lib/input-number'; -import { AntdThemeProvider } from 'src/components/AntdThemeProvider'; import { Input, TextArea, InputNumber } from '.'; export default { @@ -27,22 +26,14 @@ export default { component: Input, }; -export const InteractiveInput = (args: InputProps) => ( - - - -); +export const InteractiveInput = (args: InputProps) => ; export const InteractiveInputNumber = (args: InputNumberProps) => ( - - - + ); export const InteractiveTextArea = (args: TextAreaProps) => ( - -