Compare commits

..

1 Commits

Author SHA1 Message Date
Pat Buxton
3f4248b4d7 Update sqlachemy-utils to 0.42.0
* Support Python 3.11 through 3.13
2026-02-11 19:15:03 -08:00
1948 changed files with 39074 additions and 151920 deletions

View File

@@ -24,9 +24,7 @@ notifications:
discussions: notifications@superset.apache.org
github:
pull_requests:
del_branch_on_merge: true
allow_update_branch: true
del_branch_on_merge: true
description: "Apache Superset is a Data Visualization and Data Exploration Platform"
homepage: https://superset.apache.org/
labels:

View File

@@ -13,7 +13,7 @@
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"moby": false,
"moby": true,
"dockerDashComposeVersion": "v2"
},
"ghcr.io/devcontainers/features/node:1": {

View File

@@ -16,12 +16,9 @@ updates:
update-types: ["version-update:semver-major", "version-update:semver-minor"]
- dependency-name: "eslint-plugin-storybook"
- dependency-name: "react-error-boundary"
- dependency-name: "@rjsf/*"
# remark-gfm v4+ requires react-markdown v9+, which needs React 18
- dependency-name: "remark-gfm"
- dependency-name: "react-markdown"
# TODO: remove below entries until React >= 19.0.0
- dependency-name: "react-icons"
# JSDOM v30 doesn't play well with Jest v30
# Source: https://jestjs.io/blog#known-issues
# GH thread: https://github.com/jsdom/jsdom/issues/3492
@@ -30,9 +27,6 @@ updates:
# See https://github.com/apache/superset/pull/37384#issuecomment-3793991389
# TODO: remove the plugin once Lodash usage has been migrated to a more readily tree-shakeable alternative
- dependency-name: "@swc/plugin-transform-imports"
# `just-handlerbars-helpers` library in plugin-chart-handlebars requires `currencyformatter`` to be < 2
- dependency-name: "currencyformatter.js"
update-types: ["version-update:semver-major"]
groups:
storybook:
applies-to: version-updates
@@ -71,22 +65,6 @@ updates:
- package-ecosystem: "npm"
directory: "/docs/"
ignore:
# TODO: remove below entries until React >= 18.0.0 in superset-frontend
- dependency-name: "storybook"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
- dependency-name: "@storybook*"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
- dependency-name: "eslint-plugin-storybook"
- dependency-name: "react-error-boundary"
groups:
storybook:
applies-to: version-updates
patterns:
- "@storybook*"
- "storybook"
update-types:
- "patch"
schedule:
interval: "daily"
open-pull-requests-limit: 10
@@ -145,9 +123,6 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-pivot-table/"
ignore:
# TODO: remove below entries until React >= 19.0.0
- dependency-name: "react-icons"
schedule:
interval: "daily"
labels:
@@ -198,9 +173,6 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-table/"
ignore:
# TODO: remove below entries until React >= 19.0.0
- dependency-name: "react-icons"
schedule:
interval: "daily"
labels:
@@ -301,10 +273,6 @@ updates:
- package-ecosystem: "npm"
directory: "/superset-frontend/plugins/plugin-chart-handlebars/"
ignore:
# `just-handlerbars-helpers` library in plugin-chart-handlebars requires `currencyformatter`` to be < 2
- dependency-name: "currencyformatter.js"
update-types: ["version-update:semver-major"]
schedule:
interval: "daily"
labels:

View File

@@ -104,7 +104,7 @@ jobs:
# Scan for vulnerabilities in built container image after pushes to mainline branch.
- name: Run Trivy container image vulnerabity scan
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && (steps.check.outputs.python || steps.check.outputs.frontend || steps.check.outputs.docker) && matrix.build_preset == 'lean'
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1
with:
image-ref: ${{ env.IMAGE_TAG }}
format: 'sarif'

View File

@@ -4,9 +4,6 @@ on:
pull_request:
types: [labeled, unlabeled, opened, reopened, synchronize]
permissions:
pull-requests: read
# cancel previous workflow jobs for PRs
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}

View File

@@ -8,9 +8,6 @@ on:
pull_request:
types: [synchronize, opened, reopened, ready_for_review]
permissions:
contents: read
# cancel previous workflow jobs for PRs
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
@@ -64,17 +61,11 @@ jobs:
restore-keys: |
pre-commit-v2-${{ runner.os }}-py${{ matrix.python-version }}-
- name: Get changed files
id: changed_files
uses: ./.github/actions/file-changes-action
with:
output: ' '
- name: pre-commit
run: |
set +e # Don't exit immediately on failure
export SKIP=type-checking-frontend
pre-commit run --files ${{ steps.changed_files.outputs.files }}
export SKIP=eslint-frontend,type-checking-frontend
pre-commit run --all-files
PRE_COMMIT_EXIT_CODE=$?
git diff --quiet --exit-code
GIT_DIFF_EXIT_CODE=$?

View File

@@ -23,7 +23,7 @@ jobs:
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
services:
postgres:
image: postgres:17-alpine
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset

View File

@@ -68,7 +68,7 @@ jobs:
yarn install --check-cache
- name: Download database diagnostics (if triggered by integration tests)
if: github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success'
uses: dawidd6/action-download-artifact@v16
uses: dawidd6/action-download-artifact@v14
continue-on-error: true
with:
workflow: superset-python-integrationtest.yml
@@ -77,7 +77,7 @@ jobs:
path: docs/src/data/
- name: Try to download latest diagnostics (for push/dispatch triggers)
if: github.event_name != 'workflow_run'
uses: dawidd6/action-download-artifact@v16
uses: dawidd6/action-download-artifact@v14
continue-on-error: true
with:
workflow: superset-python-integrationtest.yml

View File

@@ -27,7 +27,7 @@ jobs:
- uses: actions/checkout@v6
# Do not bump this linkinator-action version without opening
# an ASF Infra ticket to allow the new version first!
- uses: JustinBeckwith/linkinator-action@af984b9f30f63e796ae2ea5be5e07cb587f1bbd9 # v2.3
- uses: JustinBeckwith/linkinator-action@f62ba0c110a76effb2ee6022cc6ce4ab161085e3 # v2.4
continue-on-error: true # This will make the job advisory (non-blocking, no red X)
with:
paths: "**/*.md, **/*.mdx"
@@ -111,7 +111,7 @@ jobs:
run: |
yarn install --check-cache
- name: Download database diagnostics from integration tests
uses: dawidd6/action-download-artifact@v16
uses: dawidd6/action-download-artifact@v14
with:
workflow: superset-python-integrationtest.yml
run_id: ${{ github.event.workflow_run.id }}

View File

@@ -54,7 +54,7 @@ jobs:
USE_DASHBOARD: ${{ github.event.inputs.use_dashboard == 'true' || 'false' }}
services:
postgres:
image: postgres:17-alpine
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset
@@ -146,7 +146,7 @@ jobs:
SAFE_APP_ROOT=${APP_ROOT//\//_}
echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
- name: Upload Artifacts
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v6
if: failure()
with:
path: ${{ github.workspace }}/superset-frontend/cypress-base/cypress/screenshots
@@ -171,7 +171,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}
services:
postgres:
image: postgres:17-alpine
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset
@@ -259,7 +259,7 @@ jobs:
SAFE_APP_ROOT=${APP_ROOT//\//_}
echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
- name: Upload Playwright Artifacts
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v6
if: failure()
with:
path: |

View File

@@ -58,7 +58,7 @@ jobs:
- name: Upload HTML coverage report
if: steps.check.outputs.superset-extensions-cli
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v6
with:
name: superset-extensions-cli-coverage-html
path: htmlcov/

View File

@@ -58,7 +58,7 @@ jobs:
- name: Upload Docker Image Artifact
if: steps.check.outputs.frontend
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v6
with:
name: docker-image
path: docker-image.tar.gz
@@ -73,7 +73,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Download Docker Image Artifact
uses: actions/download-artifact@v8
uses: actions/download-artifact@v7
with:
name: docker-image
@@ -87,10 +87,10 @@ jobs:
-v ${{ github.workspace }}/superset-frontend/coverage:/app/superset-frontend/coverage \
--rm $TAG \
bash -c \
"npm run test -- --coverage --shard=${{ matrix.shard }}/8 --coverageReporters=json"
"npm run test -- --coverage --shard=${{ matrix.shard }}/8 --coverageReporters=json-summary"
- name: Upload Coverage Artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v6
with:
name: coverage-artifacts-${{ matrix.shard }}
path: superset-frontend/coverage
@@ -99,29 +99,15 @@ jobs:
needs: [sharded-jest-tests]
if: needs.frontend-build.outputs.should-run == 'true'
runs-on: ubuntu-24.04
permissions:
id-token: write
steps:
- name: Checkout Code
uses: actions/checkout@v6
with:
persist-credentials: false
fetch-depth: 0
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
- name: Download Coverage Artifacts
uses: actions/download-artifact@v8
uses: actions/download-artifact@v7
with:
pattern: coverage-artifacts-*
path: coverage/
- name: Reorganize test result reports
run: |
find coverage/
for i in {1..8}; do
mv coverage/coverage-artifacts-${i}/coverage-final.json coverage/coverage-shard-${i}.json
done
shell: bash
- name: Show Files
run: find coverage/
- name: Merge Code Coverage
run: npx nyc merge coverage/ merged-output/coverage-summary.json
@@ -130,9 +116,8 @@ jobs:
uses: codecov/codecov-action@v5
with:
flags: javascript
use_oidc: true
token: ${{ secrets.CODECOV_TOKEN }}
verbose: true
disable_search: true
files: merged-output/coverage-summary.json
slug: apache/superset
@@ -142,7 +127,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Download Docker Image Artifact
uses: actions/download-artifact@v8
uses: actions/download-artifact@v7
with:
name: docker-image
@@ -166,7 +151,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Download Docker Image Artifact
uses: actions/download-artifact@v8
uses: actions/download-artifact@v7
with:
name: docker-image
@@ -184,7 +169,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Download Docker Image Artifact
uses: actions/download-artifact@v8
uses: actions/download-artifact@v7
with:
name: docker-image

View File

@@ -45,7 +45,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}
services:
postgres:
image: postgres:17-alpine
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset
@@ -133,7 +133,7 @@ jobs:
SAFE_APP_ROOT=${APP_ROOT//\//_}
echo "safe_app_root=$SAFE_APP_ROOT" >> $GITHUB_OUTPUT
- name: Upload Playwright Artifacts
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v6
if: failure()
with:
path: |

View File

@@ -98,7 +98,7 @@ jobs:
"
- name: Upload database diagnostics artifact
if: steps.check.outputs.python
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v6
with:
name: database-diagnostics
path: databases-diagnostics.json
@@ -115,7 +115,7 @@ jobs:
SUPERSET__SQLALCHEMY_DATABASE_URI: postgresql+psycopg2://superset:superset@127.0.0.1:15432/superset
services:
postgres:
image: postgres:17-alpine
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset

View File

@@ -25,7 +25,7 @@ jobs:
SUPERSET__SQLALCHEMY_EXAMPLES_URI: presto://localhost:15433/memory/default
services:
postgres:
image: postgres:17-alpine
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset
@@ -94,7 +94,7 @@ jobs:
UPLOAD_FOLDER: /tmp/.superset/uploads/
services:
postgres:
image: postgres:17-alpine
image: postgres:16-alpine
env:
POSTGRES_USER: superset
POSTGRES_PASSWORD: superset

View File

@@ -52,7 +52,6 @@ jobs:
SUPERSET_SECRET_KEY: not-a-secret
run: |
pytest --durations-min=0.5 --cov=superset/sql/ ./tests/unit_tests/sql/ --cache-clear --cov-fail-under=100
pytest --durations-min=0.5 --cov=superset/semantic_layers/ ./tests/unit_tests/semantic_layers/ --cache-clear --cov-fail-under=100
- name: Upload code coverage
uses: codecov/codecov-action@v5
with:

View File

@@ -6,9 +6,6 @@ on:
- master
- "[0-9].[0-9]*"
permissions:
contents: read
jobs:
config:
runs-on: ubuntu-24.04

2
.gitignore vendored
View File

@@ -68,11 +68,11 @@ superset-websocket/config.json
*.js.map
node_modules
npm-debug.log*
superset/static/*
superset/static/assets/*
!superset/static/assets/.gitkeep
superset/static/uploads/*
!superset/static/uploads/.gitkeep
superset/static/version_info.json
yarn-error.log
*.map
*.min.js

View File

@@ -83,7 +83,7 @@ repos:
files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$
- id: eslint-docs
name: eslint (docs)
entry: bash -c 'cd docs && FILES=$(printf "%s\n" "$@" | sed "s|^docs/||" | tr "\n" " ") && yarn eslint --fix --quiet $FILES'
entry: bash -c 'cd docs && FILES=$(echo "$@" | sed "s|docs/||g") && yarn eslint --fix --quiet $FILES'
language: system
pass_filenames: true
files: ^docs/.*\.(js|jsx|ts|tsx)$

View File

@@ -48,16 +48,12 @@ under the License.
A modern, enterprise-ready business intelligence web application.
### Documentation
- **[User Guide](https://superset.apache.org/user-docs/)** — For analysts and business users. Explore data, build charts, create dashboards, and connect databases.
- **[Administrator Guide](https://superset.apache.org/admin-docs/)** — Install, configure, and operate Superset. Covers security, scaling, and database drivers.
- **[Developer Guide](https://superset.apache.org/developer-docs/)** — Contribute to Superset or build on its REST API and extension framework.
[**Why Superset?**](#why-superset) |
[**Supported Databases**](#supported-databases) |
[**Installation and Configuration**](#installation-and-configuration) |
[**Release Notes**](https://github.com/apache/superset/blob/master/RELEASING/README.md#release-notes-for-recent-releases) |
[**Get Involved**](#get-involved) |
[**Contributor Guide**](#contributor-guide) |
[**Resources**](#resources) |
[**Organizations Using Superset**](https://superset.apache.org/inTheWild)
@@ -195,7 +191,7 @@ Try out Superset's [quickstart](https://superset.apache.org/docs/quickstart/) gu
## Contributor Guide
Interested in contributing? Check out our
[Developer Guide](https://superset.apache.org/developer-docs/)
[Developer Portal](https://superset.apache.org/developer_portal/)
to find resources around contributing along with a detailed guide on
how to set up a development environment.

View File

@@ -625,9 +625,6 @@ categories:
- name: Stockarea
url: https://stockarea.io
- name: VTG
url: https://www.vtg.de
Sports:
- name: Club 25 de Agosto (Femenino / Women's Team)
url: https://www.instagram.com/25deagosto.basketfemenino/

View File

@@ -24,67 +24,19 @@ assists people when migrating to a new version.
## Next
### Combined datasource list endpoint
### Signal Cache Backend
Added a new combined datasource list endpoint at `GET /api/v1/datasource/` to serve datasets and semantic views in one response.
- The endpoint is available to users with at least one of `can_read` on `Dataset` or `SemanticView`.
- Semantic views are included only when the `SEMANTIC_LAYERS` feature flag is enabled.
- The endpoint enforces strict `order_column` validation and returns `400` for invalid sort columns.
### ClickHouse minimum driver version bump
The minimum required version of `clickhouse-connect` has been raised to `>=0.13.0`. If you are using the ClickHouse connector, please upgrade your `clickhouse-connect` package. The `_mutate_label` workaround that appended hash suffixes to column aliases has also been removed, as it is no longer needed with modern versions of the driver.
### MCP Tool Observability
MCP (Model Context Protocol) tools now include enhanced observability instrumentation for monitoring and debugging:
**Two-layer instrumentation:**
1. **Middleware layer** (`LoggingMiddleware`): Automatically logs all MCP tool calls with `duration_ms` and `success` status in the audit log (Action Log UI, logs table)
2. **Sub-operation tracking**: All 19 MCP tools include granular `event_logger.log_context()` blocks for tracking individual operations like validation, database writes, and query execution
**Action naming convention:**
- Tool-level logs: `mcp_tool_call` (via middleware)
- Sub-operation logs: `mcp.{tool_name}.{operation}` (e.g., `mcp.generate_chart.validation`, `mcp.execute_sql.query_execution`)
**Querying MCP logs:**
```sql
-- Top slowest MCP operations
SELECT action, COUNT(*) as calls, AVG(duration_ms) as avg_ms
FROM logs
WHERE action LIKE 'mcp.%'
GROUP BY action
ORDER BY avg_ms DESC
LIMIT 20;
-- MCP tool success rate
SELECT
json_extract(curated_payload, '$.tool') as tool,
COUNT(*) as total_calls,
SUM(CASE WHEN json_extract(curated_payload, '$.success') = 'true' THEN 1 ELSE 0 END) as successful,
ROUND(100.0 * SUM(CASE WHEN json_extract(curated_payload, '$.success') = 'true' THEN 1 ELSE 0 END) / COUNT(*), 2) as success_rate
FROM logs
WHERE action = 'mcp_tool_call'
GROUP BY tool
ORDER BY total_calls DESC;
```
**Security note:** Sensitive parameters (passwords, API keys, tokens) are automatically redacted in logs as `[REDACTED]`.
### Distributed Coordination Backend
A new `DISTRIBUTED_COORDINATION_CONFIG` configuration provides a unified Redis-based backend for real-time coordination features in Superset. This backend enables:
A new `SIGNAL_CACHE_CONFIG` configuration provides a unified Redis-based backend for real-time coordination features in Superset. This backend enables:
- **Pub/sub messaging** for real-time event notifications between workers
- **Atomic distributed locking** using Redis SET NX EX (more performant than database-backed locks)
- **Event-based coordination** for background task management
The distributed coordination is used by the Global Task Framework (GTF) for abort notifications and task completion signaling, and will eventually replace `GLOBAL_ASYNC_QUERIES_CACHE_BACKEND` as the standard signaling backend. Configuring this is recommended for Redis enabled production deployments.
The signal cache is used by the Global Task Framework (GTF) for abort notifications and task completion signaling, and will eventually replace `GLOBAL_ASYNC_QUERIES_CACHE_BACKEND` as the standard signaling backend. Configuring this is recommended for Redis enabled production deployments.
Example configuration in `superset_config.py`:
```python
DISTRIBUTED_COORDINATION_CONFIG = {
SIGNAL_CACHE_CONFIG = {
"CACHE_TYPE": "RedisCache",
"CACHE_KEY_PREFIX": "signal_",
"CACHE_REDIS_URL": "redis://localhost:6379/1",

View File

@@ -45,7 +45,7 @@ services:
required: true
- path: docker/.env-local # optional override
required: false
image: postgres:17
image: postgres:16
container_name: superset_db
restart: unless-stopped
volumes:

View File

@@ -85,7 +85,7 @@ services:
required: true
- path: docker/.env-local # optional override
required: false
image: postgres:17
image: postgres:16
restart: unless-stopped
volumes:
- db_home_light:/var/lib/postgresql/data

View File

@@ -49,7 +49,7 @@ services:
required: true
- path: docker/.env-local # optional override
required: false
image: postgres:17
image: postgres:16
container_name: superset_db
restart: unless-stopped
volumes:

View File

@@ -76,7 +76,7 @@ services:
required: true
- path: docker/.env-local # optional override
required: false
image: postgres:17
image: postgres:16
restart: unless-stopped
ports:
- "127.0.0.1:${DATABASE_PORT:-5432}:5432"

View File

@@ -111,5 +111,5 @@ InteractiveMenu.parameters = {
- **Generator**: `docs/scripts/generate-superset-components.mjs`
- **Wrapper**: `docs/src/components/StorybookWrapper.jsx`
- **Output**: `docs/developer_docs/components/`
- **Output**: `docs/developer_portal/components/`
- **Stories**: `superset-frontend/packages/superset-ui-core/src/components/*/`

10
docs/.gitignore vendored
View File

@@ -33,14 +33,14 @@ docs/databases/
# Generated API documentation (regenerated at build time from openapi.json)
# Source of truth is static/resources/openapi.json
developer_docs/api/
docs/api/
# Generated component documentation MDX files (regenerated at build time)
# Source of truth is Storybook stories in superset-frontend/packages/superset-ui-core/src/components/
developer_docs/components/
developer_portal/components/
# Generated extension component documentation (regenerated at build time)
developer_portal/extensions/components/
# Note: src/data/databases.json is COMMITTED (not ignored) to preserve feature diagnostics
# that require Flask context to generate. Update it locally with: npm run gen-db-docs
# Generated component metadata JSON (regenerated by generate-superset-components.mjs)
static/data/components.json

View File

@@ -1 +1 @@
v22.22.0
v20.18.3

View File

@@ -416,7 +416,7 @@ If versions don't appear in dropdown:
- [Docusaurus Documentation](https://docusaurus.io/docs)
- [MDX Documentation](https://mdxjs.com/)
- [Superset Developer Docs](https://superset.apache.org/developer-docs/)
- [Superset Developer Portal](https://superset.apache.org/developer_portal/)
- [Main Superset Documentation](https://superset.apache.org/docs/intro)
## 📖 Real Examples and Patterns

View File

@@ -19,16 +19,15 @@ under the License.
This is the public documentation site for Superset, built using
[Docusaurus 3](https://docusaurus.io/). See the
[Developer Docs](https://superset.apache.org/developer-docs/contributing/development-setup#documentation)
[Developer Portal](https://superset.apache.org/developer_portal/contributing/development-setup#documentation)
for documentation on contributing to documentation.
## Version Management
The Superset documentation site uses Docusaurus versioning with four independent sections:
The Superset documentation site uses Docusaurus versioning with three independent versioned sections:
- **User Documentation** (`/user-docs/`) - End-user guides and tutorials
- **Admin Documentation** (`/admin-docs/`) - Installation, configuration, and security
- **Developer Docs** (`/developer-docs/`) - Developer guides, contributing, and extensions
- **Main Documentation** (`/docs/`) - Core Superset documentation
- **Developer Portal** (`/developer_portal/`) - Developer guides and tutorials
- **Component Playground** (`/components/`) - Interactive component examples (currently disabled)
Each section maintains its own version history and can be versioned independently.

View File

@@ -1,42 +0,0 @@
---
title: Admin Documentation
description: Administrator guides for installing, configuring, and managing Apache Superset
---
<!--
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.
-->
# Admin Documentation
This section contains documentation for system administrators and operators who deploy and manage Apache Superset installations.
## What's in this section
- **[Installation](/admin-docs/installation/installation-methods)** - Deploy Superset using Docker, Kubernetes, or PyPI
- **[Configuration](/admin-docs/configuration/configuring-superset)** - Configure authentication, caching, feature flags, and more
- **[Security](/admin-docs/security/)** - Set up roles, permissions, and secure your deployment
## Related
- **[Database Drivers](/user-docs/databases/)** - See User Docs for database connection setup (admins may need to install drivers)
## Looking for something else?
- **[User Documentation](/user-docs/)** - Guides for analysts and business users
- **[Developer Documentation](/developer-docs)** - Contributing, extensions, and development guides

View File

@@ -1,3 +1,4 @@
/* eslint-env node */
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -16,13 +17,16 @@
* specific language governing permissions and limitations
* under the License.
*/
import { isEmpty, isNaN, isNil, isString, trim } from 'lodash';
/**
* Checks if a value is null, undefined, NaN, or a whitespace-only string.
*/
export default function isBlank(value: unknown): boolean {
return (
isNil(value) || isNaN(value) || (isString(value) && isEmpty(trim(value)))
);
}
module.exports = {
presets: [
[
require.resolve('@docusaurus/core/lib/babel/preset'),
{
runtime: 'automatic',
importSource: '@emotion/react',
},
],
],
plugins: ['@emotion/babel-plugin'],
};

View File

@@ -1,71 +0,0 @@
---
title: Components TODO
sidebar_class_name: hidden
---
# Components TODO
These components were found but not yet supported for documentation generation.
Future phases will add support for these sources.
## Summary
- **Total skipped:** 19 story files
- **Reason:** Import path resolution not yet implemented
## Skipped by Source
### App Components
9 components
- [ ] `superset-frontend/src/components/AlteredSliceTag/AlteredSliceTag.stories.tsx`
- [ ] `superset-frontend/src/components/Chart/DrillDetail/DrillDetailTableControls.stories.tsx`
- [ ] `superset-frontend/src/components/CopyToClipboard/CopyToClipboard.stories.tsx`
- [ ] `superset-frontend/src/components/ErrorMessage/ErrorAlert.stories.tsx`
- [ ] `superset-frontend/src/components/FacePile/FacePile.stories.tsx`
- [ ] `superset-frontend/src/components/FilterableTable/FilterableTable.stories.tsx`
- [ ] `superset-frontend/src/components/RowCountLabel/RowCountLabel.stories.tsx`
- [ ] `superset-frontend/src/components/Tag/Tag.stories.tsx`
- [ ] `superset-frontend/src/components/TagsList/TagsList.stories.tsx`
### Dashboard Components
2 components
- [ ] `superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.stories.tsx`
- [ ] `superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterDivider.stories.tsx`
### Explore Components
4 components
- [ ] `superset-frontend/src/explore/components/ControlHeader.stories.tsx`
- [ ] `superset-frontend/src/explore/components/RunQueryButton/RunQueryButton.stories.tsx`
- [ ] `superset-frontend/src/explore/components/controls/BoundsControl.stories.tsx`
- [ ] `superset-frontend/src/explore/components/controls/SliderControl.stories.tsx`
### Feature Components
2 components
- [ ] `superset-frontend/src/features/datasets/AddDataset/DatasetPanel/DatasetPanel.stories.tsx`
- [ ] `superset-frontend/src/features/home/LanguagePicker.stories.tsx`
### Filter Components
2 components
- [ ] `superset-frontend/src/filters/components/Range/RangeFilterPlugin.stories.tsx`
- [ ] `superset-frontend/src/filters/components/Select/SelectFilterPlugin.stories.tsx`
## How to Add Support
1. Determine the correct import path for the source
2. Update `generate-superset-components.mjs` to handle the source
3. Add source to `SUPPORTED_SOURCES` array
4. Re-run the generator
---
*Auto-generated by generate-superset-components.mjs*

View File

@@ -1,167 +0,0 @@
---
title: DropdownContainer
sidebar_label: DropdownContainer
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# DropdownContainer
DropdownContainer arranges items horizontally and moves overflowing items into a dropdown popover. Resize the container to see the overflow behavior.
## Live Example
<StoryWithControls
component="DropdownContainer"
props={{
style: {
maxWidth: 360
},
items: [
{
id: "item-0",
element: {
component: "Tag",
props: {
children: "Region",
color: "blue"
}
}
},
{
id: "item-1",
element: {
component: "Tag",
props: {
children: "Category",
color: "blue"
}
}
},
{
id: "item-2",
element: {
component: "Tag",
props: {
children: "Date Range",
color: "blue"
}
}
},
{
id: "item-3",
element: {
component: "Tag",
props: {
children: "Status",
color: "blue"
}
}
},
{
id: "item-4",
element: {
component: "Tag",
props: {
children: "Owner",
color: "blue"
}
}
},
{
id: "item-5",
element: {
component: "Tag",
props: {
children: "Priority",
color: "blue"
}
}
}
]
}}
controls={[]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const items = Array.from({ length: 6 }, (_, i) => ({
id: 'item-' + i,
element: React.createElement('div', {
style: {
minWidth: 120,
padding: '4px 12px',
background: '#e6f4ff',
border: '1px solid #91caff',
borderRadius: 4,
},
}, 'Filter ' + (i + 1)),
}));
return (
<div style={{ width: 400, resize: 'horizontal', overflow: 'auto', border: '1px solid #e8e8e8', padding: 16 }}>
<DropdownContainer items={items} />
<div style={{ marginTop: 8, color: '#999', fontSize: 12 }}>
Drag the right edge to resize and see items overflow into a dropdown
</div>
</div>
);
}
```
## With Select Filters
```tsx live
function SelectFilters() {
const items = ['Region', 'Category', 'Date Range', 'Status', 'Owner'].map(
(label, i) => ({
id: 'filter-' + i,
element: React.createElement('div', {
style: { minWidth: 150, padding: '4px 12px', background: '#f5f5f5', border: '1px solid #d9d9d9', borderRadius: 4 },
}, label + ': All'),
})
);
return (
<div style={{ width: 500, resize: 'horizontal', overflow: 'auto', border: '1px solid #e8e8e8', padding: 16 }}>
<DropdownContainer items={items} />
</div>
);
}
```
## Import
```tsx
import { DropdownContainer } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.stories.tsx).
:::

View File

@@ -1,197 +0,0 @@
---
title: Flex
sidebar_label: Flex
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Flex
The Flex component from Superset's UI library.
## Live Example
<StoryWithControls
component="Flex"
props={{
vertical: false,
wrap: "nowrap",
justify: "normal",
align: "normal",
flex: "normal",
gap: "small"
}}
controls={[
{
name: "vertical",
label: "Vertical",
type: "boolean"
},
{
name: "wrap",
label: "Wrap",
type: "select",
options: [
"nowrap",
"wrap",
"wrap-reverse"
]
},
{
name: "justify",
label: "Justify",
type: "select",
options: [
"start",
"center",
"space-between",
"space-around",
"space-evenly"
]
},
{
name: "align",
label: "Align",
type: "select",
options: [
"start",
"center",
"end",
"stretch"
]
},
{
name: "flex",
label: "Flex",
type: "string"
},
{
name: "gap",
label: "Gap",
type: "select",
options: [
"small",
"medium",
"large"
]
}
]}
sampleChildren={["Item 1","Item 2","Item 3","Item 4","Item 5"]}
sampleChildrenStyle={{padding:"8px 16px",background:"#e6f4ff",border:"1px solid #91caff",borderRadius:"4px"}}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Flex gap="small" wrap="wrap">
{['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'].map(item => (
<div
key={item}
style={{
padding: '8px 16px',
background: '#e6f4ff',
border: '1px solid #91caff',
borderRadius: 4,
}}
>
{item}
</div>
))}
</Flex>
);
}
```
## Vertical Layout
```tsx live
function VerticalFlex() {
return (
<Flex vertical gap="small">
<Button buttonStyle="primary">Primary</Button>
<Button buttonStyle="dashed">Dashed</Button>
<Button buttonStyle="link">Link</Button>
</Flex>
);
}
```
## Justify and Align
```tsx live
function JustifyAlign() {
const boxStyle = {
width: '100%',
height: 120,
borderRadius: 6,
border: '1px solid #40a9ff',
};
const itemStyle = {
width: 60,
height: 40,
backgroundColor: '#1677ff',
borderRadius: 4,
};
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
{['flex-start', 'center', 'flex-end', 'space-between', 'space-around'].map(justify => (
<div key={justify}>
<span style={{ marginBottom: 4, display: 'block', color: '#666' }}>{justify}</span>
<Flex style={boxStyle} justify={justify} align="center">
<div style={itemStyle} />
<div style={itemStyle} />
<div style={itemStyle} />
</Flex>
</div>
))}
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `vertical` | `boolean` | `false` | - |
| `wrap` | `string` | `"nowrap"` | - |
| `justify` | `string` | `"normal"` | - |
| `align` | `string` | `"normal"` | - |
| `flex` | `string` | `"normal"` | - |
| `gap` | `string` | `"small"` | - |
## Import
```tsx
import { Flex } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Flex/Flex.stories.tsx).
:::

View File

@@ -1,192 +0,0 @@
---
title: Grid
sidebar_label: Grid
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Grid
The Grid system of Ant Design is based on a 24-grid layout. The `Row` and `Col` components are used to create flexible and responsive grid layouts.
## Live Example
<StoryWithControls
component="Grid"
renderComponent="Row"
props={{
align: "top",
justify: "start",
wrap: true,
gutter: 16
}}
controls={[
{
name: "align",
label: "Align",
type: "select",
options: [
"top",
"middle",
"bottom",
"stretch"
],
description: "Vertical alignment of columns within the row."
},
{
name: "justify",
label: "Justify",
type: "select",
options: [
"start",
"end",
"center",
"space-around",
"space-between",
"space-evenly"
],
description: "Horizontal distribution of columns within the row."
},
{
name: "wrap",
label: "Wrap",
type: "boolean",
description: "Whether columns are allowed to wrap to the next line."
},
{
name: "gutter",
label: "Gutter",
type: "number",
description: "Spacing between columns in pixels."
}
]}
sampleChildren={[{"component":"Col","props":{"span":4,"children":"col-4","style":{"background":"#e6f4ff","padding":"8px","border":"1px solid #91caff","textAlign":"center"}}},{"component":"Col","props":{"span":4,"children":"col-4 (tall)","style":{"background":"#e6f4ff","padding":"24px 8px","border":"1px solid #91caff","textAlign":"center"}}},{"component":"Col","props":{"span":4,"children":"col-4","style":{"background":"#e6f4ff","padding":"8px","border":"1px solid #91caff","textAlign":"center"}}}]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Row gutter={[16, 16]}>
<Col span={12}>
<div style={{ background: '#e6f4ff', padding: '8px', border: '1px solid #91caff' }}>col-12</div>
</Col>
<Col span={12}>
<div style={{ background: '#e6f4ff', padding: '8px', border: '1px solid #91caff' }}>col-12</div>
</Col>
<Col span={8}>
<div style={{ background: '#e6f4ff', padding: '8px', border: '1px solid #91caff' }}>col-8</div>
</Col>
<Col span={8}>
<div style={{ background: '#e6f4ff', padding: '8px', border: '1px solid #91caff' }}>col-8</div>
</Col>
<Col span={8}>
<div style={{ background: '#e6f4ff', padding: '8px', border: '1px solid #91caff' }}>col-8</div>
</Col>
</Row>
);
}
```
## Responsive Grid
```tsx live
function ResponsiveGrid() {
return (
<Row gutter={[16, 16]}>
<Col xs={24} sm={12} md={8} lg={6}>
<div style={{ background: '#e6f4ff', padding: '16px', border: '1px solid #91caff', textAlign: 'center' }}>
Responsive
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div style={{ background: '#e6f4ff', padding: '16px', border: '1px solid #91caff', textAlign: 'center' }}>
Responsive
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div style={{ background: '#e6f4ff', padding: '16px', border: '1px solid #91caff', textAlign: 'center' }}>
Responsive
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div style={{ background: '#e6f4ff', padding: '16px', border: '1px solid #91caff', textAlign: 'center' }}>
Responsive
</div>
</Col>
</Row>
);
}
```
## Alignment
```tsx live
function AlignmentDemo() {
const boxStyle = { background: '#e6f4ff', padding: '16px 0', border: '1px solid #91caff', textAlign: 'center' };
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<Row justify="start" gutter={8}>
<Col span={4}><div style={boxStyle}>start</div></Col>
<Col span={4}><div style={boxStyle}>start</div></Col>
</Row>
<Row justify="center" gutter={8}>
<Col span={4}><div style={boxStyle}>center</div></Col>
<Col span={4}><div style={boxStyle}>center</div></Col>
</Row>
<Row justify="end" gutter={8}>
<Col span={4}><div style={boxStyle}>end</div></Col>
<Col span={4}><div style={boxStyle}>end</div></Col>
</Row>
<Row justify="space-between" gutter={8}>
<Col span={4}><div style={boxStyle}>between</div></Col>
<Col span={4}><div style={boxStyle}>between</div></Col>
</Row>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `align` | `string` | `"top"` | Vertical alignment of columns within the row. |
| `justify` | `string` | `"start"` | Horizontal distribution of columns within the row. |
| `wrap` | `boolean` | `true` | Whether columns are allowed to wrap to the next line. |
| `gutter` | `number` | `16` | Spacing between columns in pixels. |
## Import
```tsx
import Grid from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Grid/Grid.stories.tsx).
:::

View File

@@ -1,38 +0,0 @@
---
title: Layout Components
sidebar_label: Layout Components
sidebar_position: 1
---
<!--
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.
-->
# Layout Components
7 components available in this category.
## Components
- [DropdownContainer](./dropdowncontainer)
- [Flex](./flex)
- [Grid](./grid)
- [Layout](./layout)
- [MetadataBar](./metadatabar)
- [Space](./space)
- [Table](./table)

View File

@@ -1,139 +0,0 @@
---
title: Layout
sidebar_label: Layout
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Layout
Ant Design Layout component with configurable Sider, Header, Footer, and Content.
## Live Example
<StoryWithControls
component="Layout"
props={{
hasSider: false,
style: {
minHeight: 200
}
}}
controls={[
{
name: "hasSider",
label: "Has Sider",
type: "boolean",
description: "Whether the layout contains a Sider sub-component."
}
]}
sampleChildren={[{"component":"Layout.Header","props":{"children":"Header","style":{"background":"#001529","color":"#fff","padding":"0 24px","lineHeight":"64px"}}},{"component":"Layout.Content","props":{"children":"Content Area","style":{"padding":"24px","background":"#fff","flex":1}}},{"component":"Layout.Footer","props":{"children":"Footer","style":{"textAlign":"center","background":"#f5f5f5","padding":"12px"}}}]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Layout style={{ minHeight: '300px' }}>
<Layout.Sider theme="dark" width={200}>
<div style={{ color: '#fff', padding: '16px' }}>Sidebar</div>
</Layout.Sider>
<Layout>
<Layout.Header style={{ background: '#fff', padding: '0 16px' }}>
Header
</Layout.Header>
<Layout.Content style={{ margin: '16px', padding: '24px', background: '#fff' }}>
Content
</Layout.Content>
<Layout.Footer style={{ textAlign: 'center' }}>
Footer
</Layout.Footer>
</Layout>
</Layout>
);
}
```
## Content Only
```tsx live
function ContentOnly() {
return (
<Layout>
<Layout.Header style={{ background: '#001529', color: '#fff', padding: '0 24px', lineHeight: '64px' }}>
Application Header
</Layout.Header>
<Layout.Content style={{ padding: '24px', minHeight: '200px', background: '#fff' }}>
Main content area without a sidebar
</Layout.Content>
<Layout.Footer style={{ textAlign: 'center', background: '#f5f5f5' }}>
Footer Content
</Layout.Footer>
</Layout>
);
}
```
## Right Sidebar
```tsx live
function RightSidebar() {
return (
<Layout style={{ minHeight: '300px' }}>
<Layout>
<Layout.Header style={{ background: '#fff', padding: '0 24px' }}>
Header
</Layout.Header>
<Layout.Content style={{ padding: '24px', background: '#fff' }}>
Content with right sidebar
</Layout.Content>
</Layout>
<Layout.Sider theme="light" width={200} style={{ background: '#fafafa' }}>
<div style={{ padding: '16px' }}>Right Sidebar</div>
</Layout.Sider>
</Layout>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `hasSider` | `boolean` | `false` | Whether the layout contains a Sider sub-component. |
| `style` | `any` | `{"minHeight":200}` | - |
## Import
```tsx
import { Layout } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Layout/Layout.stories.tsx).
:::

View File

@@ -1,174 +0,0 @@
---
title: MetadataBar
sidebar_label: MetadataBar
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# MetadataBar
MetadataBar displays a row of metadata items (SQL info, owners, last modified, tags, dashboards, etc.) that collapse responsively based on available width.
## Live Example
<StoryWithControls
component="MetadataBar"
props={{
title: "Added to 3 dashboards",
createdBy: "Jane Smith",
modifiedBy: "Jane Smith",
description: "To preview the list of dashboards go to More settings.",
items: [
{
type: "sql",
title: "Click to view query"
},
{
type: "owner",
createdBy: "Jane Smith",
owners: [
"John Doe",
"Mary Wilson"
],
createdOn: "a week ago"
},
{
type: "lastModified",
value: "a week ago",
modifiedBy: "Jane Smith"
},
{
type: "tags",
values: [
"management",
"research",
"poc"
]
},
{
type: "dashboards",
title: "Added to 3 dashboards",
description: "To preview the list of dashboards go to More settings."
}
]
}}
controls={[
{
name: "title",
label: "Title",
type: "text"
},
{
name: "createdBy",
label: "Created By",
type: "text"
},
{
name: "modifiedBy",
label: "Modified By",
type: "text"
},
{
name: "description",
label: "Description",
type: "text"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const items = [
{ type: 'sql', title: 'Click to view query' },
{
type: 'owner',
createdBy: 'Jane Smith',
owners: ['John Doe', 'Mary Wilson'],
createdOn: 'a week ago',
},
{
type: 'lastModified',
value: 'a week ago',
modifiedBy: 'Jane Smith',
},
{ type: 'tags', values: ['management', 'research', 'poc'] },
];
return <MetadataBar items={items} />;
}
```
## Minimal Metadata
```tsx live
function MinimalMetadata() {
const items = [
{ type: 'owner', createdBy: 'Admin', owners: ['Admin'], createdOn: 'yesterday' },
{ type: 'lastModified', value: '2 hours ago', modifiedBy: 'Admin' },
];
return <MetadataBar items={items} />;
}
```
## Full Metadata
```tsx live
function FullMetadata() {
const items = [
{ type: 'sql', title: 'SELECT * FROM ...' },
{ type: 'owner', createdBy: 'Jane Smith', owners: ['Jane Smith', 'John Doe', 'Bob Wilson'], createdOn: '2 weeks ago' },
{ type: 'lastModified', value: '3 days ago', modifiedBy: 'John Doe' },
{ type: 'tags', values: ['production', 'finance', 'quarterly'] },
{ type: 'dashboards', title: 'Used in 12 dashboards' },
{ type: 'description', value: 'This chart shows quarterly revenue breakdown by region and product line.' },
{ type: 'rows', title: '1.2M rows' },
{ type: 'table', title: 'public.revenue_data' },
];
return <MetadataBar items={items} />;
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | `string` | `"Added to 3 dashboards"` | - |
| `createdBy` | `string` | `"Jane Smith"` | - |
| `modifiedBy` | `string` | `"Jane Smith"` | - |
| `description` | `string` | `"To preview the list of dashboards go to More settings."` | - |
| `items` | `any` | `[{"type":"sql","title":"Click to view query"},{"type":"owner","createdBy":"Jane Smith","owners":["John Doe","Mary Wilson"],"createdOn":"a week ago"},{"type":"lastModified","value":"a week ago","modifiedBy":"Jane Smith"},{"type":"tags","values":["management","research","poc"]},{"type":"dashboards","title":"Added to 3 dashboards","description":"To preview the list of dashboards go to More settings."}]` | - |
## Import
```tsx
import MetadataBar from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/MetadataBar/MetadataBar.stories.tsx).
:::

View File

@@ -1,168 +0,0 @@
---
title: Space
sidebar_label: Space
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Space
The Space component from Superset's UI library.
## Live Example
<StoryWithControls
component="Space"
props={{
direction: "horizontal",
size: "small",
wrap: false
}}
controls={[
{
name: "direction",
label: "Direction",
type: "select",
options: [
"vertical",
"horizontal"
]
},
{
name: "size",
label: "Size",
type: "select",
options: [
"small",
"middle",
"large"
]
},
{
name: "wrap",
label: "Wrap",
type: "boolean"
},
{
name: "align",
label: "Align",
type: "select",
options: [
"start",
"end",
"center",
"baseline"
]
}
]}
sampleChildren={["Item 1","Item 2","Item 3","Item 4","Item 5"]}
sampleChildrenStyle={{padding:"8px 16px",background:"#e6f4ff",border:"1px solid #91caff",borderRadius:"4px"}}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Space size="small">
{['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'].map(item => (
<div
key={item}
style={{
padding: '8px 16px',
background: '#e6f4ff',
border: '1px solid #91caff',
borderRadius: 4,
}}
>
{item}
</div>
))}
</Space>
);
}
```
## Vertical Space
```tsx live
function VerticalSpace() {
return (
<Space direction="vertical" size="middle" style={{ display: 'flex' }}>
<Button buttonStyle="primary">Primary</Button>
<Button buttonStyle="secondary">Secondary</Button>
<Button buttonStyle="dashed">Dashed</Button>
</Space>
);
}
```
## Space Sizes
```tsx live
function SpaceSizes() {
const items = ['Item 1', 'Item 2', 'Item 3'];
const itemStyle = {
padding: '8px 16px',
background: '#e6f4ff',
border: '1px solid #91caff',
borderRadius: 4,
};
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
{['small', 'middle', 'large'].map(size => (
<div key={size}>
<h4>{size}</h4>
<Space size={size}>
{items.map(item => (
<div key={item} style={itemStyle}>{item}</div>
))}
</Space>
</div>
))}
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `direction` | `string` | `"horizontal"` | - |
| `size` | `string` | `"small"` | - |
| `wrap` | `boolean` | `false` | - |
## Import
```tsx
import { Space } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Space/Space.stories.tsx).
:::

View File

@@ -1,311 +0,0 @@
---
title: Table
sidebar_label: Table
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Table
A data table component with sorting, pagination, row selection, resizable columns, reorderable columns, and virtualization for large datasets.
## Live Example
<StoryWithControls
component="Table"
props={{
size: "small",
bordered: false,
loading: false,
sticky: true,
resizable: false,
reorderable: false,
usePagination: false,
key: 5,
name: "1GB USB Flash Drive",
category: "Portable Storage",
price: 9.99,
height: 350,
defaultPageSize: 5,
pageSizeOptions: [
"5",
"10"
],
data: [
{
key: 1,
name: "Floppy Disk 10 pack",
category: "Disk Storage",
price: 9.99
},
{
key: 2,
name: "DVD 100 pack",
category: "Optical Storage",
price: 27.99
},
{
key: 3,
name: "128 GB SSD",
category: "Harddrive",
price: 49.99
},
{
key: 4,
name: "4GB 144mhz",
category: "Memory",
price: 19.99
},
{
key: 5,
name: "1GB USB Flash Drive",
category: "Portable Storage",
price: 9.99
},
{
key: 6,
name: "256 GB SSD",
category: "Harddrive",
price: 89.99
},
{
key: 7,
name: "1 TB SSD",
category: "Harddrive",
price: 349.99
},
{
key: 8,
name: "16 GB DDR4",
category: "Memory",
price: 59.99
},
{
key: 9,
name: "32 GB DDR5",
category: "Memory",
price: 129.99
},
{
key: 10,
name: "Blu-ray 50 pack",
category: "Optical Storage",
price: 34.99
},
{
key: 11,
name: "64 GB USB Drive",
category: "Portable Storage",
price: 14.99
},
{
key: 12,
name: "2 TB HDD",
category: "Harddrive",
price: 59.99
}
],
columns: [
{
title: "Name",
dataIndex: "name",
key: "name",
width: 200
},
{
title: "Category",
dataIndex: "category",
key: "category",
width: 150
},
{
title: "Price",
dataIndex: "price",
key: "price",
width: 100
}
]
}}
controls={[
{
name: "size",
label: "Size",
type: "select",
options: [
"small",
"middle",
"large"
],
description: "Table size."
},
{
name: "bordered",
label: "Bordered",
type: "boolean",
description: "Whether to show all table borders."
},
{
name: "loading",
label: "Loading",
type: "boolean",
description: "Whether the table is in a loading state."
},
{
name: "sticky",
label: "Sticky",
type: "boolean",
description: "Whether the table header is sticky."
},
{
name: "resizable",
label: "Resizable",
type: "boolean",
description: "Whether columns can be resized by dragging column edges."
},
{
name: "reorderable",
label: "Reorderable",
type: "boolean",
description: "EXPERIMENTAL: Whether columns can be reordered by dragging. May not work in all contexts."
},
{
name: "usePagination",
label: "Use Pagination",
type: "boolean",
description: "Whether to enable pagination. When enabled, the table displays 5 rows per page."
},
{
name: "key",
label: "Key",
type: "number"
},
{
name: "name",
label: "Name",
type: "text"
},
{
name: "category",
label: "Category",
type: "text"
},
{
name: "price",
label: "Price",
type: "number"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const data = [
{ key: 1, name: 'PostgreSQL', type: 'Database', status: 'Active' },
{ key: 2, name: 'MySQL', type: 'Database', status: 'Active' },
{ key: 3, name: 'SQLite', type: 'Database', status: 'Inactive' },
{ key: 4, name: 'Presto', type: 'Query Engine', status: 'Active' },
];
const columns = [
{ title: 'Name', dataIndex: 'name', key: 'name', width: 150 },
{ title: 'Type', dataIndex: 'type', key: 'type' },
{ title: 'Status', dataIndex: 'status', key: 'status', width: 100 },
];
return <Table data={data} columns={columns} size="small" />;
}
```
## With Pagination
```tsx live
function PaginatedTable() {
const data = Array.from({ length: 20 }, (_, i) => ({
key: i,
name: 'Record ' + (i + 1),
value: Math.round(Math.random() * 1000),
category: ['A', 'B', 'C'][i % 3],
}));
const columns = [
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Value', dataIndex: 'value', key: 'value', width: 100 },
{ title: 'Category', dataIndex: 'category', key: 'category', width: 100 },
];
return (
<Table
data={data}
columns={columns}
size="small"
pageSizeOptions={['5', '10']}
defaultPageSize={5}
/>
);
}
```
## Loading State
```tsx live
function LoadingTable() {
const columns = [
{ title: 'Name', dataIndex: 'name', key: 'name' },
{ title: 'Status', dataIndex: 'status', key: 'status' },
];
return <Table data={[]} columns={columns} size="small" loading />;
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `size` | `string` | `"small"` | Table size. |
| `bordered` | `boolean` | `false` | Whether to show all table borders. |
| `loading` | `boolean` | `false` | Whether the table is in a loading state. |
| `sticky` | `boolean` | `true` | Whether the table header is sticky. |
| `resizable` | `boolean` | `false` | Whether columns can be resized by dragging column edges. |
| `reorderable` | `boolean` | `false` | EXPERIMENTAL: Whether columns can be reordered by dragging. May not work in all contexts. |
| `usePagination` | `boolean` | `false` | Whether to enable pagination. When enabled, the table displays 5 rows per page. |
| `key` | `number` | `5` | - |
| `name` | `string` | `"1GB USB Flash Drive"` | - |
| `category` | `string` | `"Portable Storage"` | - |
| `price` | `number` | `9.99` | - |
| `height` | `number` | `350` | - |
| `defaultPageSize` | `number` | `5` | - |
| `pageSizeOptions` | `any` | `["5","10"]` | - |
| `data` | `any` | `[{"key":1,"name":"Floppy Disk 10 pack","category":"Disk Storage","price":9.99},{"key":2,"name":"DVD 100 pack","category":"Optical Storage","price":27.99},{"key":3,"name":"128 GB SSD","category":"Harddrive","price":49.99},{"key":4,"name":"4GB 144mhz","category":"Memory","price":19.99},{"key":5,"name":"1GB USB Flash Drive","category":"Portable Storage","price":9.99},{"key":6,"name":"256 GB SSD","category":"Harddrive","price":89.99},{"key":7,"name":"1 TB SSD","category":"Harddrive","price":349.99},{"key":8,"name":"16 GB DDR4","category":"Memory","price":59.99},{"key":9,"name":"32 GB DDR5","category":"Memory","price":129.99},{"key":10,"name":"Blu-ray 50 pack","category":"Optical Storage","price":34.99},{"key":11,"name":"64 GB USB Drive","category":"Portable Storage","price":14.99},{"key":12,"name":"2 TB HDD","category":"Harddrive","price":59.99}]` | - |
| `columns` | `any` | `[{"title":"Name","dataIndex":"name","key":"name","width":200},{"title":"Category","dataIndex":"category","key":"category","width":150},{"title":"Price","dataIndex":"price","key":"price","width":100}]` | - |
## Import
```tsx
import { Table } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Table/Table.stories.tsx).
:::

View File

@@ -1,74 +0,0 @@
---
title: UI Components Overview
sidebar_label: Overview
sidebar_position: 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.
-->
# Superset Design System
A design system is a complete set of standards intended to manage design at scale using reusable components and patterns.
The Superset Design System uses [Atomic Design](https://bradfrost.com/blog/post/atomic-web-design/) principles with adapted terminology:
| Atomic Design | Atoms | Molecules | Organisms | Templates | Pages / Screens |
|---|:---:|:---:|:---:|:---:|:---:|
| **Superset Design** | Foundations | Components | Patterns | Templates | Features |
<img src="/img/atomic-design.png" alt="Atoms = Foundations, Molecules = Components, Organisms = Patterns, Templates = Templates, Pages / Screens = Features" style={{maxWidth: '100%'}} />
---
## Component Library
Interactive documentation for Superset's UI component library. **53 components** documented across 2 categories.
### [Core Components](./ui/)
46 components — Buttons, inputs, modals, selects, and other fundamental UI elements.
### [Layout Components](./design-system/)
7 components — Grid, Layout, Table, Flex, Space, and container components for page structure.
## Usage
All components are exported from `@superset-ui/core/components`:
```tsx
import { Button, Modal, Select } from '@superset-ui/core/components';
```
## Contributing
This documentation is auto-generated from Storybook stories. To add or update component documentation:
1. Create or update the component's `.stories.tsx` file
2. Add a descriptive `title` and `description` in the story meta
3. Export an interactive story with `args` for configurable props
4. Run `yarn generate:superset-components` in the `docs/` directory
:::info Work in Progress
This component library is actively being documented. See the [Components TODO](./TODO) page for a list of components awaiting documentation.
:::
---
*Auto-generated from Storybook stories in the [Design System/Introduction](https://github.com/apache/superset/blob/master/superset-frontend/packages/superset-ui-core/src/components/DesignSystem.stories.tsx) story.*

View File

@@ -1,215 +0,0 @@
---
title: AutoComplete
sidebar_label: AutoComplete
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# AutoComplete
AutoComplete component for search functionality.
## Live Example
<StoryWithControls
component="AutoComplete"
props={{
placeholder: "Type to search...",
options: [
{
value: "Dashboard",
label: "Dashboard"
},
{
value: "Chart",
label: "Chart"
},
{
value: "Dataset",
label: "Dataset"
},
{
value: "Database",
label: "Database"
},
{
value: "Query",
label: "Query"
}
],
style: {
width: 300
},
filterOption: true
}}
controls={[
{
name: "placeholder",
label: "Placeholder",
type: "text",
description: "Placeholder text for AutoComplete"
},
{
name: "style",
label: "Style",
type: "object",
description: "Custom styles for AutoComplete"
},
{
name: "value",
label: "Value",
type: "text",
description: "Selected option"
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Disable the AutoComplete"
},
{
name: "popupMatchSelectWidth",
label: "Popup Match Select Width",
type: "number",
description: "Width of the dropdown"
},
{
name: "allowClear",
label: "Allow Clear",
type: "boolean",
description: "Show clear button"
},
{
name: "autoFocus",
label: "Auto Focus",
type: "boolean",
description: "If get focus when component mounted"
},
{
name: "backfill",
label: "Backfill",
type: "boolean",
description: "If backfill selected item the input when using keyboard"
},
{
name: "popupClassName",
label: "Popup Class Name",
type: "text",
description: "The className of dropdown menu"
},
{
name: "filterOption",
label: "Filter Option",
type: "boolean",
description: "Enable filtering of options based on input"
},
{
name: "notFoundContent",
label: "Not Found Content",
type: "text",
description: "Specify content to show when no result matches."
},
{
name: "open",
label: "Open",
type: "boolean",
description: "Controlled open state of dropdown"
},
{
name: "status",
label: "Status",
type: "select",
options: [
"error",
"warning"
],
description: "Set validation status"
},
{
name: "size",
label: "Size",
type: "select",
options: [
"large",
"middle",
"small"
],
description: "The size of the input box"
},
{
name: "variant",
label: "Variant",
type: "select",
options: [
"outlined",
"borderless",
"filled"
],
description: "Variants of input"
},
{
name: "virtual",
label: "Virtual",
type: "boolean",
description: "Disable virtual scroll when set to false"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<AutoComplete
placeholder="Type to search..."
options={[{"value":"Dashboard","label":"Dashboard"},{"value":"Chart","label":"Chart"},{"value":"Dataset","label":"Dataset"},{"value":"Database","label":"Database"},{"value":"Query","label":"Query"}]}
style={{"width":300}}
filterOption
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `placeholder` | `string` | `"Type to search..."` | Placeholder text for AutoComplete |
| `options` | `any` | `[{"value":"Dashboard","label":"Dashboard"},{"value":"Chart","label":"Chart"},{"value":"Dataset","label":"Dataset"},{"value":"Database","label":"Database"},{"value":"Query","label":"Query"}]` | The dropdown options |
| `style` | `any` | `{"width":300}` | Custom styles for AutoComplete |
| `filterOption` | `boolean` | `true` | Enable filtering of options based on input |
## Import
```tsx
import { AutoComplete } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/AutoComplete/AutoComplete.stories.tsx).
:::

View File

@@ -1,140 +0,0 @@
---
title: Avatar
sidebar_label: Avatar
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Avatar
The Avatar component from Superset's UI library.
## Live Example
<StoryWithControls
component="Avatar"
props={{
children: "AB",
alt: "",
gap: 4,
shape: "circle",
size: "default",
src: "",
draggable: false
}}
controls={[
{
name: "children",
label: "Children",
type: "text",
description: "Text or initials to display inside the avatar."
},
{
name: "alt",
label: "Alt",
type: "text"
},
{
name: "gap",
label: "Gap",
type: "number",
description: "Letter spacing inside the avatar."
},
{
name: "shape",
label: "Shape",
type: "select",
options: [
"circle",
"square"
],
description: "The shape of the avatar."
},
{
name: "size",
label: "Size",
type: "select",
options: [
"small",
"default",
"large"
],
description: "The size of the avatar."
},
{
name: "src",
label: "Src",
type: "text",
description: "Image URL for the avatar. If provided, overrides children."
},
{
name: "draggable",
label: "Draggable",
type: "boolean"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Avatar
alt=""
gap={4}
shape="circle"
size="default"
src=""
>
AB
</Avatar>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `string` | `"AB"` | Text or initials to display inside the avatar. |
| `alt` | `string` | `""` | - |
| `gap` | `number` | `4` | Letter spacing inside the avatar. |
| `shape` | `string` | `"circle"` | The shape of the avatar. |
| `size` | `string` | `"default"` | The size of the avatar. |
| `src` | `string` | `""` | Image URL for the avatar. If provided, overrides children. |
| `draggable` | `boolean` | `false` | - |
## Import
```tsx
import { Avatar } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Avatar/Avatar.stories.tsx).
:::

View File

@@ -1,160 +0,0 @@
---
title: Badge
sidebar_label: Badge
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Badge
The Badge component from Superset's UI library.
## Live Example
<StoryWithControls
component="Badge"
props={{
count: 5,
size: "default",
showZero: false,
overflowCount: 99
}}
controls={[
{
name: "count",
label: "Count",
type: "number",
description: "Number to show in the badge."
},
{
name: "size",
label: "Size",
type: "select",
options: [
"default",
"small"
],
description: "Size of the badge."
},
{
name: "showZero",
label: "Show Zero",
type: "boolean",
description: "Whether to show badge when count is zero."
},
{
name: "overflowCount",
label: "Overflow Count",
type: "number",
description: "Max count to show. Shows count+ when exceeded (e.g., 99+)."
},
{
name: "color",
label: "Color",
type: "select",
options: [
"pink",
"red",
"yellow",
"orange",
"cyan",
"green",
"blue",
"purple",
"geekblue",
"magenta",
"volcano",
"gold",
"lime"
],
description: "Custom background color for the badge."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Badge
count={5}
size="default"
overflowCount={99}
/>
);
}
```
## Status Badge
```tsx live
function StatusBadgeDemo() {
const statuses = ['default', 'success', 'processing', 'warning', 'error'];
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
{statuses.map(status => (
<Badge key={status} status={status} text={`Status: ${status}`} />
))}
</div>
);
}
```
## Color Gallery
```tsx live
function ColorGallery() {
const colors = ['pink', 'red', 'orange', 'green', 'cyan', 'blue', 'purple'];
return (
<div style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
{colors.map(color => (
<Badge key={color} count={9} color={color} />
))}
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `count` | `number` | `5` | Number to show in the badge. |
| `size` | `string` | `"default"` | Size of the badge. |
| `showZero` | `boolean` | `false` | Whether to show badge when count is zero. |
| `overflowCount` | `number` | `99` | Max count to show. Shows count+ when exceeded (e.g., 99+). |
## Import
```tsx
import { Badge } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Badge/Badge.stories.tsx).
:::

View File

@@ -1,93 +0,0 @@
---
title: Breadcrumb
sidebar_label: Breadcrumb
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Breadcrumb
Breadcrumb component for displaying navigation paths.
## Live Example
<StoryWithControls
component="Breadcrumb"
props={{
items: [
{
title: "Home",
href: "/"
},
{
title: "Library",
href: "/library"
},
{
title: "Data"
}
],
separator: "/"
}}
controls={[
{
name: "separator",
label: "Separator",
type: "text",
description: "Custom separator between items"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Breadcrumb
items={[
{ title: 'Home', href: '/' },
{ title: 'Library', href: '/library' },
{ title: 'Data' },
]}
separator="/"
/>
);
}
```
## Import
```tsx
import { Breadcrumb } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Breadcrumb/Breadcrumb.stories.tsx).
:::

View File

@@ -1,142 +0,0 @@
---
title: Button
sidebar_label: Button
---
<!--
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 { StoryWithControls, ComponentGallery } from '../../../src/components/StorybookWrapper';
# Button
The Button component from Superset's UI library.
## All Variants
<ComponentGallery
component="Button"
sizes={["xsmall","small","default"]}
styles={["primary","secondary","dashed","danger","link"]}
sizeProp="buttonSize"
styleProp="buttonStyle"
/>
## Live Example
<StoryWithControls
component="Button"
props={{
buttonStyle: "default",
buttonSize: "default",
children: "Button!"
}}
controls={[
{
name: "buttonStyle",
label: "Button Style",
type: "select",
options: [
"primary",
"secondary",
"dashed",
"danger",
"link"
],
description: "The style variant of the button."
},
{
name: "buttonSize",
label: "Button Size",
type: "select",
options: [
"xsmall",
"small",
"default"
],
description: "The size of the button."
},
{
name: "children",
label: "Children",
type: "text",
description: "The button text or content."
},
{
name: "target",
label: "Target",
type: "select"
},
{
name: "href",
label: "Href",
type: "select"
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Whether the button is disabled."
},
{
name: "loading",
label: "Loading",
type: "boolean",
description: "Whether to show loading spinner."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Button
buttonStyle="default"
buttonSize="default"
>
Button!
</Button>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `buttonStyle` | `string` | `"default"` | The style variant of the button. |
| `buttonSize` | `string` | `"default"` | The size of the button. |
| `children` | `string` | `"Button!"` | The button text or content. |
## Import
```tsx
import { Button } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Button/Button.stories.tsx).
:::

View File

@@ -1,88 +0,0 @@
---
title: ButtonGroup
sidebar_label: ButtonGroup
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# ButtonGroup
ButtonGroup is a container that groups multiple Button components together with consistent spacing and styling.
## Live Example
<StoryWithControls
component="ButtonGroup"
props={{
expand: false
}}
controls={[
{
name: "expand",
label: "Expand",
type: "boolean",
description: "When true, buttons expand to fill available width."
},
{
name: "className",
label: "Class Name",
type: "text",
description: "CSS class name for custom styling."
}
]}
sampleChildren={[{"component":"Button","props":{"buttonStyle":"tertiary","children":"Button 1"}},{"component":"Button","props":{"buttonStyle":"tertiary","children":"Button 2"}},{"component":"Button","props":{"buttonStyle":"tertiary","children":"Button 3"}}]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<ButtonGroup>
<Button buttonStyle="tertiary">Button 1</Button>
<Button buttonStyle="tertiary">Button 2</Button>
<Button buttonStyle="tertiary">Button 3</Button>
</ButtonGroup>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `expand` | `boolean` | `false` | When true, buttons expand to fill available width. |
## Import
```tsx
import { ButtonGroup } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/ButtonGroup/ButtonGroup.stories.tsx).
:::

View File

@@ -1,79 +0,0 @@
---
title: CachedLabel
sidebar_label: CachedLabel
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# CachedLabel
The CachedLabel component from Superset's UI library.
## Live Example
<StoryWithControls
component="CachedLabel"
props={{}}
controls={[
{
name: "cachedTimestamp",
label: "Cached Timestamp",
type: "text",
description: "ISO timestamp of when the data was cached"
},
{
name: "className",
label: "Class Name",
type: "text",
description: "Additional CSS class for the label"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<CachedLabel
// Add props here
/>
);
}
```
## Import
```tsx
import { CachedLabel } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/CachedLabel/CachedLabel.stories.tsx).
:::

View File

@@ -1,142 +0,0 @@
---
title: Card
sidebar_label: Card
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Card
A container component for grouping related content. Supports titles, borders, loading states, and hover effects.
## Live Example
<StoryWithControls
component="Card"
props={{
padded: true,
title: "Dashboard Overview",
children: "This card displays a summary of your dashboard metrics and recent activity.",
bordered: true,
loading: false,
hoverable: false
}}
controls={[
{
name: "padded",
label: "Padded",
type: "boolean",
description: "Whether the card content has padding."
},
{
name: "title",
label: "Title",
type: "text",
description: "Title text displayed at the top of the card."
},
{
name: "children",
label: "Children",
type: "text",
description: "The content inside the card."
},
{
name: "bordered",
label: "Bordered",
type: "boolean",
description: "Whether to show a border around the card."
},
{
name: "loading",
label: "Loading",
type: "boolean",
description: "Whether to show a loading skeleton."
},
{
name: "hoverable",
label: "Hoverable",
type: "boolean",
description: "Whether the card lifts on hover."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Card title="Dashboard Overview" bordered>
This card displays a summary of your dashboard metrics and recent activity.
</Card>
);
}
```
## Card States
```tsx live
function CardStates() {
return (
<div style={{ display: 'flex', gap: 16, flexWrap: 'wrap' }}>
<Card title="Default" bordered style={{ width: 250 }}>
Default card content.
</Card>
<Card title="Hoverable" bordered hoverable style={{ width: 250 }}>
Hover over this card.
</Card>
<Card title="Loading" bordered loading style={{ width: 250 }}>
This content is hidden while loading.
</Card>
<Card title="No Border" style={{ width: 250 }}>
Borderless card.
</Card>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `padded` | `boolean` | `true` | Whether the card content has padding. |
| `title` | `string` | `"Dashboard Overview"` | Title text displayed at the top of the card. |
| `children` | `string` | `"This card displays a summary of your dashboard metrics and recent activity."` | The content inside the card. |
| `bordered` | `boolean` | `true` | Whether to show a border around the card. |
| `loading` | `boolean` | `false` | Whether to show a loading skeleton. |
| `hoverable` | `boolean` | `false` | Whether the card lifts on hover. |
## Import
```tsx
import { Card } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Card/Card.stories.tsx).
:::

View File

@@ -1,141 +0,0 @@
---
title: Checkbox
sidebar_label: Checkbox
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Checkbox
Checkbox component that supports both regular and indeterminate states, built on top of Ant Design v5 Checkbox.
## Live Example
<StoryWithControls
component="Checkbox"
props={{
checked: false,
indeterminate: false
}}
controls={[
{
name: "checked",
label: "Checked",
type: "boolean",
description: "Whether the checkbox is checked."
},
{
name: "indeterminate",
label: "Indeterminate",
type: "boolean",
description: "Whether the checkbox is in indeterminate state (partially selected)."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Checkbox
// Add props here
/>
);
}
```
## All Checkbox States
```tsx live
function AllStates() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
<Checkbox checked={false}>Unchecked</Checkbox>
<Checkbox checked={true}>Checked</Checkbox>
<Checkbox indeterminate={true}>Indeterminate</Checkbox>
<Checkbox disabled>Disabled unchecked</Checkbox>
<Checkbox disabled checked>Disabled checked</Checkbox>
</div>
);
}
```
## Select All Pattern
```tsx live
function SelectAllDemo() {
const [selected, setSelected] = React.useState([]);
const options = ['Option A', 'Option B', 'Option C'];
const allSelected = selected.length === options.length;
const indeterminate = selected.length > 0 && !allSelected;
return (
<div>
<Checkbox
checked={allSelected}
indeterminate={indeterminate}
onChange={(e) => setSelected(e.target.checked ? [...options] : [])}
>
Select All
</Checkbox>
<div style={{ marginLeft: 24, marginTop: 8 }}>
{options.map(opt => (
<div key={opt}>
<Checkbox
checked={selected.includes(opt)}
onChange={() => setSelected(prev =>
prev.includes(opt) ? prev.filter(x => x !== opt) : [...prev, opt]
)}
>
{opt}
</Checkbox>
</div>
))}
</div>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `checked` | `boolean` | `false` | Whether the checkbox is checked. |
| `indeterminate` | `boolean` | `false` | Whether the checkbox is in indeterminate state (partially selected). |
## Import
```tsx
import { Checkbox } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Checkbox/Checkbox.stories.tsx).
:::

View File

@@ -1,106 +0,0 @@
---
title: Collapse
sidebar_label: Collapse
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Collapse
The Collapse component from Superset's UI library.
## Live Example
<StoryWithControls
component="Collapse"
props={{
ghost: false,
bordered: true,
accordion: false,
animateArrows: false,
modalMode: false
}}
controls={[
{
name: "ghost",
label: "Ghost",
type: "boolean"
},
{
name: "bordered",
label: "Bordered",
type: "boolean"
},
{
name: "accordion",
label: "Accordion",
type: "boolean"
},
{
name: "animateArrows",
label: "Animate Arrows",
type: "boolean"
},
{
name: "modalMode",
label: "Modal Mode",
type: "boolean"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Collapse
bordered
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `ghost` | `boolean` | `false` | - |
| `bordered` | `boolean` | `true` | - |
| `accordion` | `boolean` | `false` | - |
| `animateArrows` | `boolean` | `false` | - |
| `modalMode` | `boolean` | `false` | - |
## Import
```tsx
import { Collapse } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Collapse/Collapse.stories.tsx).
:::

View File

@@ -1,110 +0,0 @@
---
title: DatePicker
sidebar_label: DatePicker
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# DatePicker
The DatePicker component from Superset's UI library.
## Live Example
<StoryWithControls
component="DatePicker"
props={{
placeholder: "Select date",
showNow: true,
allowClear: false,
autoFocus: true,
disabled: false,
format: "YYYY-MM-DD hh:mm a",
inputReadOnly: false,
picker: "date",
placement: "bottomLeft",
size: "middle",
showTime: {
format: "hh:mm a",
needConfirm: false
}
}}
controls={[
{
name: "placeholder",
label: "Placeholder",
type: "text"
},
{
name: "showNow",
label: "Show Now",
type: "boolean",
description: "Show \"Now\" button to select current date and time."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<DatePicker
placeholder="Select date"
format="YYYY-MM-DD hh:mm a"
showNow
showTime={{ format: 'hh:mm a', needConfirm: false }}
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `placeholder` | `string` | `"Select date"` | - |
| `showNow` | `boolean` | `true` | Show "Now" button to select current date and time. |
| `allowClear` | `boolean` | `false` | - |
| `autoFocus` | `boolean` | `true` | - |
| `disabled` | `boolean` | `false` | - |
| `format` | `string` | `"YYYY-MM-DD hh:mm a"` | - |
| `inputReadOnly` | `boolean` | `false` | - |
| `picker` | `string` | `"date"` | - |
| `placement` | `string` | `"bottomLeft"` | - |
| `size` | `string` | `"middle"` | - |
| `showTime` | `any` | `{"format":"hh:mm a","needConfirm":false}` | - |
## Import
```tsx
import { DatePicker } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/DatePicker/DatePicker.stories.tsx).
:::

View File

@@ -1,144 +0,0 @@
---
title: Divider
sidebar_label: Divider
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Divider
The Divider component from Superset's UI library.
## Live Example
<StoryWithControls
component="Divider"
props={{
dashed: false,
variant: "solid",
orientation: "center",
orientationMargin: "",
plain: true,
type: "horizontal"
}}
controls={[
{
name: "dashed",
label: "Dashed",
type: "boolean",
description: "Whether line is dashed (deprecated, use variant)."
},
{
name: "variant",
label: "Variant",
type: "select",
options: [
"dashed",
"dotted",
"solid"
],
description: "Line style of the divider."
},
{
name: "orientation",
label: "Orientation",
type: "select",
options: [
"left",
"right",
"center"
],
description: "Position of title inside divider."
},
{
name: "orientationMargin",
label: "Orientation Margin",
type: "text",
description: "Margin from divider edge to title."
},
{
name: "plain",
label: "Plain",
type: "boolean",
description: "Use plain style without bold title."
},
{
name: "type",
label: "Type",
type: "select",
options: [
"horizontal",
"vertical"
],
description: "Direction of the divider."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<>
<p>Horizontal divider with title (orientationMargin applies here):</p>
<Divider orientation="left" orientationMargin={0}>Left Title</Divider>
<Divider orientation="right" orientationMargin={50}>Right Title</Divider>
<Divider>Center Title</Divider>
<p>Vertical divider (use container gap for spacing):</p>
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
<span>Link</span>
<Divider type="vertical" />
<span>Link</span>
<Divider type="vertical" />
<span>Link</span>
</div>
</>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `dashed` | `boolean` | `false` | Whether line is dashed (deprecated, use variant). |
| `variant` | `string` | `"solid"` | Line style of the divider. |
| `orientation` | `string` | `"center"` | Position of title inside divider. |
| `orientationMargin` | `string` | `""` | Margin from divider edge to title. |
| `plain` | `boolean` | `true` | Use plain style without bold title. |
| `type` | `string` | `"horizontal"` | Direction of the divider. |
## Import
```tsx
import { Divider } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Divider/Divider.stories.tsx).
:::

View File

@@ -1,172 +0,0 @@
---
title: EditableTitle
sidebar_label: EditableTitle
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# EditableTitle
The EditableTitle component from Superset's UI library.
## Live Example
<StoryWithControls
component="EditableTitle"
props={{
canEdit: true,
editing: false,
emptyText: "Empty text",
noPermitTooltip: "Not permitted",
showTooltip: true,
title: "Title",
defaultTitle: "Default title",
placeholder: "Placeholder",
certifiedBy: "",
certificationDetails: "",
maxWidth: 100,
autoSize: true
}}
controls={[
{
name: "canEdit",
label: "Can Edit",
type: "boolean",
description: "Whether the title can be edited."
},
{
name: "editing",
label: "Editing",
type: "boolean",
description: "Whether the title is currently in edit mode."
},
{
name: "emptyText",
label: "Empty Text",
type: "text",
description: "Text to display when title is empty."
},
{
name: "noPermitTooltip",
label: "No Permit Tooltip",
type: "text",
description: "Tooltip shown when user lacks edit permission."
},
{
name: "showTooltip",
label: "Show Tooltip",
type: "boolean",
description: "Whether to show tooltip on hover."
},
{
name: "title",
label: "Title",
type: "text",
description: "The title text to display."
},
{
name: "defaultTitle",
label: "Default Title",
type: "text",
description: "Default title when none is provided."
},
{
name: "placeholder",
label: "Placeholder",
type: "text",
description: "Placeholder text when editing."
},
{
name: "certifiedBy",
label: "Certified By",
type: "text",
description: "Name of person/team who certified this item."
},
{
name: "certificationDetails",
label: "Certification Details",
type: "text",
description: "Additional certification details or description."
},
{
name: "maxWidth",
label: "Max Width",
type: "number",
description: "Maximum width of the title in pixels."
},
{
name: "autoSize",
label: "Auto Size",
type: "boolean",
description: "Whether to auto-size based on content."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<EditableTitle
title="My Dashboard"
canEdit
showTooltip
certifiedBy="Data Team"
certificationDetails="Verified Q1 2024"
onSaveTitle={(newTitle) => console.log('Saved:', newTitle)}
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `canEdit` | `boolean` | `true` | Whether the title can be edited. |
| `editing` | `boolean` | `false` | Whether the title is currently in edit mode. |
| `emptyText` | `string` | `"Empty text"` | Text to display when title is empty. |
| `noPermitTooltip` | `string` | `"Not permitted"` | Tooltip shown when user lacks edit permission. |
| `showTooltip` | `boolean` | `true` | Whether to show tooltip on hover. |
| `title` | `string` | `"Title"` | The title text to display. |
| `defaultTitle` | `string` | `"Default title"` | Default title when none is provided. |
| `placeholder` | `string` | `"Placeholder"` | Placeholder text when editing. |
| `certifiedBy` | `string` | `""` | Name of person/team who certified this item. |
| `certificationDetails` | `string` | `""` | Additional certification details or description. |
| `maxWidth` | `number` | `100` | Maximum width of the title in pixels. |
| `autoSize` | `boolean` | `true` | Whether to auto-size based on content. |
## Import
```tsx
import { EditableTitle } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/EditableTitle/EditableTitle.stories.tsx).
:::

View File

@@ -1,147 +0,0 @@
---
title: EmptyState
sidebar_label: EmptyState
---
<!--
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 { StoryWithControls, ComponentGallery } from '../../../src/components/StorybookWrapper';
# EmptyState
The EmptyState component from Superset's UI library.
## All Variants
<ComponentGallery
component="EmptyState"
sizes={["medium"]}
styles={["chart.svg","document.svg","empty-charts.svg","empty-dashboard.svg","empty-dataset.svg","empty-query.svg","empty-table.svg","empty.svg","empty_sql_chart.svg","filter-results.svg","filter.svg","star-circle.svg","union.svg","vector.svg"]}
sizeProp="size"
styleProp="image"
/>
## Live Example
<StoryWithControls
component="EmptyState"
props={{
size: "medium",
title: "No Data Available",
description: "There is no data to display at this time.",
image: "empty.svg",
buttonText: ""
}}
controls={[
{
name: "size",
label: "Size",
type: "select",
options: [
"small",
"medium",
"large"
],
description: "Size of the empty state component."
},
{
name: "title",
label: "Title",
type: "text",
description: "Main title text."
},
{
name: "description",
label: "Description",
type: "text",
description: "Description text below the title."
},
{
name: "image",
label: "Image",
type: "select",
options: [
"chart.svg",
"document.svg",
"empty-charts.svg",
"empty-dashboard.svg",
"empty-dataset.svg",
"empty-query.svg",
"empty-table.svg",
"empty.svg",
"empty_sql_chart.svg",
"filter-results.svg",
"filter.svg",
"star-circle.svg",
"union.svg",
"vector.svg"
],
description: "Predefined image to display."
},
{
name: "buttonText",
label: "Button Text",
type: "text",
description: "Text for optional action button."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<EmptyState
size="medium"
title="No Results Found"
description="Try adjusting your filters or search terms."
image="filter.svg"
buttonText="Clear Filters"
buttonAction={() => alert('Filters cleared!')}
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `size` | `string` | `"medium"` | Size of the empty state component. |
| `title` | `string` | `"No Data Available"` | Main title text. |
| `description` | `string` | `"There is no data to display at this time."` | Description text below the title. |
| `image` | `string` | `"empty.svg"` | Predefined image to display. |
| `buttonText` | `string` | `""` | Text for optional action button. |
## Import
```tsx
import { EmptyState } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/EmptyState/EmptyState.stories.tsx).
:::

View File

@@ -1,96 +0,0 @@
---
title: FaveStar
sidebar_label: FaveStar
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# FaveStar
FaveStar component for marking items as favorites
## Live Example
<StoryWithControls
component="FaveStar"
props={{
itemId: 1,
isStarred: false,
showTooltip: true
}}
controls={[
{
name: "itemId",
label: "Item ID",
type: "number",
description: "Unique identifier for the item"
},
{
name: "isStarred",
label: "Is Starred",
type: "boolean",
description: "Whether the item is currently starred."
},
{
name: "showTooltip",
label: "Show Tooltip",
type: "boolean",
description: "Show tooltip on hover."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<FaveStar
itemId={1}
showTooltip
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `itemId` | `number` | `1` | Unique identifier for the item |
| `isStarred` | `boolean` | `false` | Whether the item is currently starred. |
| `showTooltip` | `boolean` | `true` | Show tooltip on hover. |
## Import
```tsx
import { FaveStar } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/FaveStar/FaveStar.stories.tsx).
:::

View File

@@ -1,106 +0,0 @@
---
title: IconButton
sidebar_label: IconButton
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# IconButton
The IconButton component is a versatile button that allows you to combine an icon with a text label. It is designed for use in situations where you want to display an icon along with some text in a single clickable element.
## Live Example
<StoryWithControls
component="IconButton"
props={{
buttonText: "IconButton",
altText: "Icon button alt text",
padded: true,
icon: "https://superset.apache.org/img/superset-logo-horiz.svg"
}}
controls={[
{
name: "buttonText",
label: "Button Text",
type: "text",
description: "The text inside the button."
},
{
name: "altText",
label: "Alt Text",
type: "text",
description: "The alt text for the button. If not provided, the button text is used as the alt text by default."
},
{
name: "padded",
label: "Padded",
type: "boolean",
description: "Add padding between icon and button text."
},
{
name: "icon",
label: "Icon",
type: "text",
description: "Icon inside the button (URL or path)."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<IconButton
buttonText="IconButton"
altText="Icon button alt text"
padded
icon="https://superset.apache.org/img/superset-logo-horiz.svg"
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `buttonText` | `string` | `"IconButton"` | The text inside the button. |
| `altText` | `string` | `"Icon button alt text"` | The alt text for the button. If not provided, the button text is used as the alt text by default. |
| `padded` | `boolean` | `true` | Add padding between icon and button text. |
| `icon` | `string` | `"https://superset.apache.org/img/superset-logo-horiz.svg"` | Icon inside the button (URL or path). |
## Import
```tsx
import { IconButton } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/IconButton/IconButton.stories.tsx).
:::

View File

@@ -1,252 +0,0 @@
---
title: Icons
sidebar_label: Icons
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Icons
Icon library for Apache Superset. Contains over 200 icons based on Ant Design icons with consistent sizing and theming support.
## Live Example
<StoryWithControls
component="Icons"
renderComponent="Icons.InfoCircleOutlined"
props={{
iconSize: "xl"
}}
controls={[
{
name: "iconSize",
label: "Icon Size",
type: "inline-radio",
options: [
"s",
"m",
"l",
"xl",
"xxl"
],
description: "Size of the icons: s (12px), m (16px), l (20px), xl (24px), xxl (32px)."
},
{
name: "showNames",
label: "Show Names",
type: "boolean"
},
{
name: "iconColor",
label: "Icon Color",
type: "select"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
<Icons.InfoCircleOutlined iconSize="xl" />
<Icons.CheckCircleOutlined iconSize="xl" />
<Icons.WarningOutlined iconSize="xl" />
<Icons.CloseCircleOutlined iconSize="xl" />
</div>
);
}
```
## Icon Sizes
```tsx live
function IconSizes() {
const sizes = ['s', 'm', 'l', 'xl', 'xxl'];
return (
<div style={{ display: 'flex', gap: 24, alignItems: 'end' }}>
{sizes.map(size => (
<div key={size} style={{ textAlign: 'center' }}>
<Icons.DatabaseOutlined iconSize={size} />
<div style={{ fontSize: 12, marginTop: 8, color: '#666' }}>{size}</div>
</div>
))}
</div>
);
}
```
## Icon Gallery
```tsx live
function IconGallery() {
const Section = ({ title, children }) => (
<div style={{ marginBottom: 24 }}>
<div style={{ fontWeight: 600, marginBottom: 8, color: '#666' }}>{title}</div>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 16 }}>{children}</div>
</div>
);
return (
<div>
<Section title="Charts">
<Icons.LineChartOutlined iconSize="xl" />
<Icons.BarChartOutlined iconSize="xl" />
<Icons.PieChartOutlined iconSize="xl" />
<Icons.AreaChartOutlined iconSize="xl" />
<Icons.DashboardOutlined iconSize="xl" />
<Icons.FundProjectionScreenOutlined iconSize="xl" />
</Section>
<Section title="Data">
<Icons.DatabaseOutlined iconSize="xl" />
<Icons.TableOutlined iconSize="xl" />
<Icons.ConsoleSqlOutlined iconSize="xl" />
<Icons.FilterOutlined iconSize="xl" />
<Icons.FieldNumberOutlined iconSize="xl" />
<Icons.FieldTimeOutlined iconSize="xl" />
<Icons.FunctionOutlined iconSize="xl" />
<Icons.CalculatorOutlined iconSize="xl" />
</Section>
<Section title="Actions">
<Icons.PlusOutlined iconSize="xl" />
<Icons.EditOutlined iconSize="xl" />
<Icons.DeleteOutlined iconSize="xl" />
<Icons.CopyOutlined iconSize="xl" />
<Icons.SaveOutlined iconSize="xl" />
<Icons.DownloadOutlined iconSize="xl" />
<Icons.UploadOutlined iconSize="xl" />
<Icons.ReloadOutlined iconSize="xl" />
<Icons.SyncOutlined iconSize="xl" />
<Icons.SearchOutlined iconSize="xl" />
<Icons.ExpandOutlined iconSize="xl" />
<Icons.FullscreenOutlined iconSize="xl" />
<Icons.ShareAltOutlined iconSize="xl" />
<Icons.ExportOutlined iconSize="xl" />
</Section>
<Section title="Status">
<Icons.CheckOutlined iconSize="xl" />
<Icons.CheckCircleOutlined iconSize="xl" />
<Icons.CloseOutlined iconSize="xl" />
<Icons.CloseCircleOutlined iconSize="xl" />
<Icons.InfoCircleOutlined iconSize="xl" />
<Icons.WarningOutlined iconSize="xl" />
<Icons.ExclamationCircleOutlined iconSize="xl" />
<Icons.QuestionCircleOutlined iconSize="xl" />
<Icons.LoadingOutlined iconSize="xl" />
<Icons.StopOutlined iconSize="xl" />
</Section>
<Section title="Navigation">
<Icons.MenuOutlined iconSize="xl" />
<Icons.DownOutlined iconSize="xl" />
<Icons.UpOutlined iconSize="xl" />
<Icons.RightOutlined iconSize="xl" />
<Icons.CaretDownOutlined iconSize="xl" />
<Icons.CaretUpOutlined iconSize="xl" />
<Icons.ArrowRightOutlined iconSize="xl" />
<Icons.MoreOutlined iconSize="xl" />
<Icons.EllipsisOutlined iconSize="xl" />
</Section>
<Section title="Objects">
<Icons.FileOutlined iconSize="xl" />
<Icons.FileTextOutlined iconSize="xl" />
<Icons.FileImageOutlined iconSize="xl" />
<Icons.BookOutlined iconSize="xl" />
<Icons.TagOutlined iconSize="xl" />
<Icons.TagsOutlined iconSize="xl" />
<Icons.StarOutlined iconSize="xl" />
<Icons.BellOutlined iconSize="xl" />
<Icons.CalendarOutlined iconSize="xl" />
<Icons.ClockCircleOutlined iconSize="xl" />
<Icons.MailOutlined iconSize="xl" />
<Icons.LinkOutlined iconSize="xl" />
<Icons.LockOutlined iconSize="xl" />
<Icons.UnlockOutlined iconSize="xl" />
<Icons.KeyOutlined iconSize="xl" />
</Section>
<Section title="Users">
<Icons.UserOutlined iconSize="xl" />
<Icons.UserAddOutlined iconSize="xl" />
<Icons.UsergroupAddOutlined iconSize="xl" />
<Icons.LoginOutlined iconSize="xl" />
</Section>
<Section title="Settings">
<Icons.SettingOutlined iconSize="xl" />
<Icons.BgColorsOutlined iconSize="xl" />
<Icons.FormatPainterOutlined iconSize="xl" />
<Icons.HighlightOutlined iconSize="xl" />
<Icons.EyeOutlined iconSize="xl" />
<Icons.EyeInvisibleOutlined iconSize="xl" />
<Icons.SunOutlined iconSize="xl" />
<Icons.MoonOutlined iconSize="xl" />
</Section>
</div>
);
}
```
## Icon with Text
```tsx live
function IconWithText() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Icons.CheckCircleOutlined iconSize="l" style={{ color: '#52c41a' }} />
<span>Success message</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Icons.InfoCircleOutlined iconSize="l" style={{ color: '#1890ff' }} />
<span>Information message</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Icons.WarningOutlined iconSize="l" style={{ color: '#faad14' }} />
<span>Warning message</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Icons.CloseCircleOutlined iconSize="l" style={{ color: '#ff4d4f' }} />
<span>Error message</span>
</div>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `iconSize` | `string` | `"xl"` | Size of the icons: s (12px), m (16px), l (20px), xl (24px), xxl (32px). |
## Import
```tsx
import { Icons } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Icons/Icons.stories.tsx).
:::

View File

@@ -1,100 +0,0 @@
---
title: IconTooltip
sidebar_label: IconTooltip
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# IconTooltip
The IconTooltip component from Superset's UI library.
## Live Example
<StoryWithControls
component="IconTooltip"
props={{
tooltip: "Tooltip"
}}
controls={[
{
name: "tooltip",
label: "Tooltip",
type: "text",
description: "Text content to display in the tooltip."
},
{
name: "placement",
label: "Placement",
type: "select",
options: [
"bottom",
"bottomLeft",
"bottomRight",
"left",
"leftBottom",
"leftTop",
"right",
"rightBottom",
"rightTop",
"top",
"topLeft",
"topRight"
],
description: "Position of the tooltip relative to the icon."
}
]}
sampleChildren={[{"component":"Icons.InfoCircleOutlined","props":{"iconSize":"l"}}]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<IconTooltip tooltip="Helpful information">
<Icons.InfoCircleOutlined iconSize="l" />
</IconTooltip>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `tooltip` | `string` | `"Tooltip"` | Text content to display in the tooltip. |
## Import
```tsx
import { IconTooltip } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/IconTooltip/IconTooltip.stories.tsx).
:::

View File

@@ -1,77 +0,0 @@
---
title: Core Components
sidebar_label: Core Components
sidebar_position: 1
---
<!--
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.
-->
# Core Components
46 components available in this category.
## Components
- [AutoComplete](./autocomplete)
- [Avatar](./avatar)
- [Badge](./badge)
- [Breadcrumb](./breadcrumb)
- [Button](./button)
- [ButtonGroup](./buttongroup)
- [CachedLabel](./cachedlabel)
- [Card](./card)
- [Checkbox](./checkbox)
- [Collapse](./collapse)
- [DatePicker](./datepicker)
- [Divider](./divider)
- [EditableTitle](./editabletitle)
- [EmptyState](./emptystate)
- [FaveStar](./favestar)
- [IconButton](./iconbutton)
- [Icons](./icons)
- [IconTooltip](./icontooltip)
- [InfoTooltip](./infotooltip)
- [Input](./input)
- [Label](./label)
- [List](./list)
- [ListViewCard](./listviewcard)
- [Loading](./loading)
- [Menu](./menu)
- [Modal](./modal)
- [ModalTrigger](./modaltrigger)
- [Popover](./popover)
- [ProgressBar](./progressbar)
- [Radio](./radio)
- [SafeMarkdown](./safemarkdown)
- [Select](./select)
- [Skeleton](./skeleton)
- [Slider](./slider)
- [Steps](./steps)
- [Switch](./switch)
- [TableCollection](./tablecollection)
- [TableView](./tableview)
- [Tabs](./tabs)
- [Timer](./timer)
- [Tooltip](./tooltip)
- [Tree](./tree)
- [TreeSelect](./treeselect)
- [Typography](./typography)
- [UnsavedChangesModal](./unsavedchangesmodal)
- [Upload](./upload)

View File

@@ -1,106 +0,0 @@
---
title: InfoTooltip
sidebar_label: InfoTooltip
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# InfoTooltip
The InfoTooltip component from Superset's UI library.
## Live Example
<StoryWithControls
component="InfoTooltip"
props={{
tooltip: "This is the text that will display!"
}}
controls={[
{
name: "tooltip",
label: "Tooltip",
type: "text"
},
{
name: "placement",
label: "Placement",
type: "select",
options: [
"bottom",
"left",
"right",
"top",
"topLeft",
"topRight",
"bottomLeft",
"bottomRight",
"leftTop",
"leftBottom",
"rightTop",
"rightBottom"
]
},
{
name: "trigger",
label: "Trigger",
type: "select",
options: [
"hover",
"click"
]
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<InfoTooltip
tooltip="This is the text that will display!"
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `tooltip` | `string` | `"This is the text that will display!"` | - |
## Import
```tsx
import { InfoTooltip } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/InfoTooltip/InfoTooltip.stories.tsx).
:::

View File

@@ -1,162 +0,0 @@
---
title: Input
sidebar_label: Input
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Input
The Input component from Superset's UI library.
## Live Example
<StoryWithControls
component="Input"
props={{
allowClear: false,
disabled: false,
showCount: false,
type: "text",
variant: "outlined"
}}
controls={[
{
name: "allowClear",
label: "Allow Clear",
type: "boolean"
},
{
name: "disabled",
label: "Disabled",
type: "boolean"
},
{
name: "showCount",
label: "Show Count",
type: "boolean"
},
{
name: "type",
label: "Type",
type: "select",
options: [
"text",
"password",
"email",
"number",
"tel",
"url",
"search"
],
description: "HTML input type"
},
{
name: "variant",
label: "Variant",
type: "select",
options: [
"outlined",
"borderless",
"filled"
],
description: "Input style variant"
},
{
name: "defaultValue",
label: "Default Value",
type: "text",
description: "Default input value"
},
{
name: "id",
label: "ID",
type: "text",
description: "HTML id attribute"
},
{
name: "maxLength",
label: "Max Length",
type: "number",
description: "Maximum length of input"
},
{
name: "status",
label: "Status",
type: "select",
options: [
"error",
"warning"
],
description: "Validation status"
},
{
name: "size",
label: "Size",
type: "select",
options: [
"large",
"middle",
"small"
],
description: "Size of the input"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Input
type="text"
variant="outlined"
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `allowClear` | `boolean` | `false` | - |
| `disabled` | `boolean` | `false` | - |
| `showCount` | `boolean` | `false` | - |
| `type` | `string` | `"text"` | HTML input type |
| `variant` | `string` | `"outlined"` | Input style variant |
## Import
```tsx
import { Input } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Input/Input.stories.tsx).
:::

View File

@@ -1,105 +0,0 @@
---
title: Label
sidebar_label: Label
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Label
The Label component from Superset's UI library.
## Live Example
<StoryWithControls
component="Label"
props={{
type: "default",
children: "Label text",
monospace: false
}}
controls={[
{
name: "type",
label: "Type",
type: "select",
options: [
"default",
"info",
"success",
"warning",
"error",
"primary"
],
description: "The visual style of the label."
},
{
name: "children",
label: "Children",
type: "text",
description: "The label text content."
},
{
name: "monospace",
label: "Monospace",
type: "boolean",
description: "Use monospace font."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Label
type="default"
>
Label text
</Label>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `type` | `string` | `"default"` | The visual style of the label. |
| `children` | `string` | `"Label text"` | The label text content. |
| `monospace` | `boolean` | `false` | Use monospace font. |
## Import
```tsx
import { Label } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Label/Label.stories.tsx).
:::

View File

@@ -1,117 +0,0 @@
---
title: List
sidebar_label: List
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# List
The List component from Superset's UI library.
## Live Example
<StoryWithControls
component="List"
props={{
bordered: false,
split: true,
size: "default",
loading: false,
dataSource: [
"Dashboard Analytics",
"User Management",
"Data Sources"
]
}}
controls={[
{
name: "bordered",
label: "Bordered",
type: "boolean",
description: "Whether to show a border around the list."
},
{
name: "split",
label: "Split",
type: "boolean",
description: "Whether to show a divider between items."
},
{
name: "size",
label: "Size",
type: "select",
options: [
"default",
"small",
"large"
],
description: "Size of the list."
},
{
name: "loading",
label: "Loading",
type: "boolean",
description: "Whether to show a loading indicator."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const data = ['Dashboard Analytics', 'User Management', 'Data Sources'];
return (
<List
bordered
dataSource={data}
renderItem={(item) => <List.Item>{item}</List.Item>}
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `bordered` | `boolean` | `false` | Whether to show a border around the list. |
| `split` | `boolean` | `true` | Whether to show a divider between items. |
| `size` | `string` | `"default"` | Size of the list. |
| `loading` | `boolean` | `false` | Whether to show a loading indicator. |
| `dataSource` | `any` | `["Dashboard Analytics","User Management","Data Sources"]` | - |
## Import
```tsx
import { List } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/List/List.stories.tsx).
:::

View File

@@ -1,132 +0,0 @@
---
title: ListViewCard
sidebar_label: ListViewCard
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# ListViewCard
ListViewCard is a card component used to display items in list views with an image, title, description, and optional cover sections.
## Live Example
<StoryWithControls
component="ListViewCard"
props={{
title: "Superset Card Title",
loading: false,
url: "/superset/dashboard/births/",
imgURL: "https://picsum.photos/seed/superset/300/200",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit...",
coverLeft: "Left Section",
coverRight: "Right Section"
}}
controls={[
{
name: "title",
label: "Title",
type: "text",
description: "Title displayed on the card."
},
{
name: "loading",
label: "Loading",
type: "boolean",
description: "Whether the card is in loading state."
},
{
name: "url",
label: "URL",
type: "text",
description: "URL the card links to."
},
{
name: "imgURL",
label: "Image URL",
type: "text",
description: "Primary image URL for the card."
},
{
name: "description",
label: "Description",
type: "text",
description: "Description text displayed on the card."
},
{
name: "coverLeft",
label: "Cover Left",
type: "text",
description: "Content for the left section of the cover."
},
{
name: "coverRight",
label: "Cover Right",
type: "text",
description: "Content for the right section of the cover."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<ListViewCard
title="Superset Card Title"
url="/superset/dashboard/births/"
imgURL="https://picsum.photos/seed/superset/300/200"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit..."
coverLeft="Left Section"
coverRight="Right Section"
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | `string` | `"Superset Card Title"` | Title displayed on the card. |
| `loading` | `boolean` | `false` | Whether the card is in loading state. |
| `url` | `string` | `"/superset/dashboard/births/"` | URL the card links to. |
| `imgURL` | `string` | `"https://picsum.photos/seed/superset/300/200"` | Primary image URL for the card. |
| `description` | `string` | `"Lorem ipsum dolor sit amet, consectetur adipiscing elit..."` | Description text displayed on the card. |
| `coverLeft` | `string` | `"Left Section"` | Content for the left section of the cover. |
| `coverRight` | `string` | `"Right Section"` | Content for the right section of the cover. |
## Import
```tsx
import { ListViewCard } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/ListViewCard/ListViewCard.stories.tsx).
:::

View File

@@ -1,187 +0,0 @@
---
title: Loading
sidebar_label: Loading
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Loading
The Loading component from Superset's UI library.
## Live Example
<StoryWithControls
component="Loading"
props={{
size: "m",
position: "normal",
muted: false
}}
controls={[
{
name: "size",
label: "Size",
type: "select",
options: [
"s",
"m",
"l"
],
description: "Size of the spinner: s (40px), m (70px), or l (100px)."
},
{
name: "position",
label: "Position",
type: "select",
options: [
"normal",
"floating",
"inline"
],
description: "Position style: normal (inline flow), floating (overlay), or inline."
},
{
name: "muted",
label: "Muted",
type: "boolean",
description: "Whether to show a muted/subtle version of the spinner."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<div>
{['normal', 'floating', 'inline'].map(position => (
<div
key={position}
style={{
marginBottom: 40,
padding: 20,
border: '1px solid #eee',
position: 'relative',
minHeight: 80,
}}
>
<h4 style={{ marginTop: 0 }}>{position}</h4>
<Loading position={position} size="m" />
</div>
))}
</div>
);
}
```
## Size and Opacity Showcase
```tsx live
function SizeShowcase() {
const sizes = ['s', 'm', 'l'];
return (
<div style={{ padding: 20 }}>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 20, alignItems: 'center' }}>
<div><strong>Size</strong></div>
<div><strong>Normal</strong></div>
<div><strong>Muted</strong></div>
<div><strong>Usage</strong></div>
{sizes.map(size => (
<React.Fragment key={size}>
<div style={{ fontWeight: 'bold' }}>
{size.toUpperCase()} ({size === 's' ? '40px' : size === 'm' ? '70px' : '100px'})
</div>
<div style={{ textAlign: 'center', padding: 10, border: '1px solid #eee' }}>
<Loading size={size} position="normal" />
</div>
<div style={{ textAlign: 'center', padding: 10, border: '1px solid #eee' }}>
<Loading size={size} muted position="normal" />
</div>
<div style={{ fontSize: 12, color: '#666' }}>
{size === 's' && 'Filter bars, inline'}
{size === 'm' && 'Explore pages'}
{size === 'l' && 'Full page loading'}
</div>
</React.Fragment>
))}
</div>
</div>
);
}
```
## Contextual Examples
```tsx live
function ContextualDemo() {
return (
<div style={{ padding: 20 }}>
<h4>Filter Bar (size="s", muted)</h4>
<div style={{ height: 40, backgroundColor: '#f5f5f5', display: 'flex', alignItems: 'center', padding: '0 10px', gap: 10, marginBottom: 30 }}>
<span>Filter 1:</span>
<Loading size="s" muted position="normal" />
<span>Filter 2:</span>
<Loading size="s" muted position="normal" />
</div>
<h4>Dashboard Grid (size="s", muted)</h4>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10, marginBottom: 30 }}>
{[1, 2, 3].map(i => (
<div key={i} style={{ height: 100, backgroundColor: '#fafafa', border: '1px solid #ddd', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Loading size="s" muted position="normal" />
</div>
))}
</div>
<h4>Main Loading (size="l")</h4>
<div style={{ height: 200, display: 'flex', alignItems: 'center', justifyContent: 'center', border: '2px dashed #ccc' }}>
<Loading size="l" position="normal" />
</div>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `size` | `string` | `"m"` | Size of the spinner: s (40px), m (70px), or l (100px). |
| `position` | `string` | `"normal"` | Position style: normal (inline flow), floating (overlay), or inline. |
| `muted` | `boolean` | `false` | Whether to show a muted/subtle version of the spinner. |
## Import
```tsx
import { Loading } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Loading/Loading.stories.tsx).
:::

View File

@@ -1,174 +0,0 @@
---
title: Menu
sidebar_label: Menu
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Menu
Navigation menu component supporting horizontal, vertical, and inline modes. Based on Ant Design Menu with Superset styling.
## Live Example
<StoryWithControls
component="Menu"
props={{
mode: "horizontal",
selectable: true,
items: [
{
label: "Dashboards",
key: "dashboards"
},
{
label: "Charts",
key: "charts"
},
{
label: "Datasets",
key: "datasets"
},
{
label: "SQL Lab",
key: "sqllab"
}
]
}}
controls={[
{
name: "mode",
label: "Mode",
type: "select",
options: [
"horizontal",
"vertical",
"inline"
],
description: "Menu display mode: horizontal navbar, vertical sidebar, or inline collapsible."
},
{
name: "selectable",
label: "Selectable",
type: "boolean",
description: "Whether menu items can be selected."
},
{
name: "multiple",
label: "Multiple",
type: "boolean",
description: "Allow multiple items to be selected."
},
{
name: "inlineCollapsed",
label: "Inline Collapsed",
type: "boolean",
description: "Whether the inline menu is collapsed (only applies to inline mode)."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Menu
mode="horizontal"
selectable
items={[
{ label: 'Dashboards', key: 'dashboards' },
{ label: 'Charts', key: 'charts' },
{ label: 'Datasets', key: 'datasets' },
{ label: 'SQL Lab', key: 'sqllab' },
]}
/>
);
}
```
## Vertical Menu
```tsx live
function VerticalMenu() {
return (
<Menu
mode="vertical"
style={{ width: 200 }}
items={[
{ label: 'Dashboards', key: 'dashboards' },
{ label: 'Charts', key: 'charts' },
{ label: 'Datasets', key: 'datasets' },
{
label: 'Settings',
key: 'settings',
children: [
{ label: 'Profile', key: 'profile' },
{ label: 'Preferences', key: 'preferences' },
],
},
]}
/>
);
}
```
## Menu with Icons
```tsx live
function MenuWithIcons() {
return (
<Menu
mode="horizontal"
items={[
{ label: <><Icons.DashboardOutlined /> Dashboards</>, key: 'dashboards' },
{ label: <><Icons.LineChartOutlined /> Charts</>, key: 'charts' },
{ label: <><Icons.DatabaseOutlined /> Datasets</>, key: 'datasets' },
{ label: <><Icons.ConsoleSqlOutlined /> SQL Lab</>, key: 'sqllab' },
]}
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `mode` | `string` | `"horizontal"` | Menu display mode: horizontal navbar, vertical sidebar, or inline collapsible. |
| `selectable` | `boolean` | `true` | Whether menu items can be selected. |
| `items` | `any` | `[{"label":"Dashboards","key":"dashboards"},{"label":"Charts","key":"charts"},{"label":"Datasets","key":"datasets"},{"label":"SQL Lab","key":"sqllab"}]` | - |
## Import
```tsx
import { Menu } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Menu/Menu.stories.tsx).
:::

View File

@@ -1,207 +0,0 @@
---
title: Modal
sidebar_label: Modal
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Modal
Modal dialog component for displaying content that requires user attention or interaction. Supports customizable buttons, drag/resize, and confirmation dialogs.
## Live Example
<StoryWithControls
component="Modal"
props={{
disablePrimaryButton: false,
primaryButtonName: "Submit",
primaryButtonStyle: "primary",
show: false,
title: "I'm a modal!",
resizable: false,
draggable: false,
width: 500
}}
controls={[
{
name: "disablePrimaryButton",
label: "Disable Primary Button",
type: "boolean",
description: "Whether the primary button is disabled."
},
{
name: "primaryButtonName",
label: "Primary Button Name",
type: "text",
description: "Text for the primary action button."
},
{
name: "primaryButtonStyle",
label: "Primary Button Style",
type: "select",
options: [
"primary",
"secondary",
"dashed",
"danger",
"link"
],
description: "The style of the primary action button."
},
{
name: "show",
label: "Show",
type: "boolean",
description: "Whether the modal is visible. Use the \"Try It\" example below for a working demo."
},
{
name: "title",
label: "Title",
type: "text",
description: "Title displayed in the modal header."
},
{
name: "resizable",
label: "Resizable",
type: "boolean",
description: "Whether the modal can be resized by dragging corners."
},
{
name: "draggable",
label: "Draggable",
type: "boolean",
description: "Whether the modal can be dragged by its header."
},
{
name: "width",
label: "Width",
type: "number",
description: "Width of the modal in pixels."
}
]}
triggerProp="show"
onHideProp="onHide"
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function ModalDemo() {
const [isOpen, setIsOpen] = React.useState(false);
return (
<>
<Button onClick={() => setIsOpen(true)}>Open Modal</Button>
<Modal
show={isOpen}
onHide={() => setIsOpen(false)}
title="Example Modal"
primaryButtonName="Submit"
onHandledPrimaryAction={() => {
alert('Submitted!');
setIsOpen(false);
}}
>
<p>This is the modal content. Click Submit or close the modal.</p>
</Modal>
</>
);
}
```
## Danger Modal
```tsx live
function DangerModal() {
const [isOpen, setIsOpen] = React.useState(false);
return (
<>
<Button buttonStyle="danger" onClick={() => setIsOpen(true)}>Delete Item</Button>
<Modal
show={isOpen}
onHide={() => setIsOpen(false)}
title="Confirm Delete"
primaryButtonName="Delete"
primaryButtonStyle="danger"
onHandledPrimaryAction={() => {
alert('Deleted!');
setIsOpen(false);
}}
>
<p>Are you sure you want to delete this item? This action cannot be undone.</p>
</Modal>
</>
);
}
```
## Confirmation Dialogs
```tsx live
function ConfirmationDialogs() {
return (
<div style={{ display: 'flex', gap: 8 }}>
<Button onClick={() => Modal.confirm({
title: 'Confirm Action',
content: 'Are you sure you want to proceed?',
okText: 'Yes',
})}>Confirm</Button>
<Button onClick={() => Modal.warning({
title: 'Warning',
content: 'This action may have consequences.',
})}>Warning</Button>
<Button onClick={() => Modal.error({
title: 'Error',
content: 'Something went wrong.',
})}>Error</Button>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `disablePrimaryButton` | `boolean` | `false` | Whether the primary button is disabled. |
| `primaryButtonName` | `string` | `"Submit"` | Text for the primary action button. |
| `primaryButtonStyle` | `string` | `"primary"` | The style of the primary action button. |
| `show` | `boolean` | `false` | Whether the modal is visible. Use the "Try It" example below for a working demo. |
| `title` | `string` | `"I'm a modal!"` | Title displayed in the modal header. |
| `resizable` | `boolean` | `false` | Whether the modal can be resized by dragging corners. |
| `draggable` | `boolean` | `false` | Whether the modal can be dragged by its header. |
| `width` | `number` | `500` | Width of the modal in pixels. |
## Import
```tsx
import { Modal } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.stories.tsx).
:::

View File

@@ -1,192 +0,0 @@
---
title: ModalTrigger
sidebar_label: ModalTrigger
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# ModalTrigger
A component that renders a trigger element which opens a modal when clicked. Useful for actions that need confirmation or additional input.
## Live Example
<StoryWithControls
component="ModalTrigger"
props={{
isButton: true,
modalTitle: "Modal Title",
modalBody: "This is the modal body content.",
tooltip: "Click to open modal",
width: "600px",
maxWidth: "1000px",
responsive: true,
draggable: false,
resizable: false,
triggerNode: "Click to Open Modal"
}}
controls={[
{
name: "isButton",
label: "Is Button",
type: "boolean",
description: "Whether to wrap the trigger in a button element."
},
{
name: "modalTitle",
label: "Modal Title",
type: "text",
description: "Title displayed in the modal header."
},
{
name: "modalBody",
label: "Modal Body",
type: "text",
description: "Content displayed in the modal body."
},
{
name: "tooltip",
label: "Tooltip",
type: "text",
description: "Tooltip text shown on hover over the trigger."
},
{
name: "width",
label: "Width",
type: "text",
description: "Width of the modal (e.g., \"600px\", \"80%\")."
},
{
name: "maxWidth",
label: "Max Width",
type: "text",
description: "Maximum width of the modal."
},
{
name: "responsive",
label: "Responsive",
type: "boolean",
description: "Whether the modal should be responsive."
},
{
name: "draggable",
label: "Draggable",
type: "boolean",
description: "Whether the modal can be dragged by its header."
},
{
name: "resizable",
label: "Resizable",
type: "boolean",
description: "Whether the modal can be resized by dragging corners."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<ModalTrigger
isButton
triggerNode={<span>Click to Open</span>}
modalTitle="Example Modal"
modalBody={<p>This is the modal content. You can put any React elements here.</p>}
width="500px"
responsive
/>
);
}
```
## With Custom Trigger
```tsx live
function CustomTrigger() {
return (
<ModalTrigger
triggerNode={
<Button buttonStyle="primary">
<Icons.PlusOutlined /> Add New Item
</Button>
}
modalTitle="Add New Item"
modalBody={
<div>
<p>Fill out the form to add a new item.</p>
<Input placeholder="Item name" />
</div>
}
width="400px"
/>
);
}
```
## Draggable & Resizable
```tsx live
function DraggableModal() {
return (
<ModalTrigger
isButton
triggerNode={<span>Open Draggable Modal</span>}
modalTitle="Draggable & Resizable"
modalBody={<p>Try dragging the header or resizing from the corners!</p>}
draggable
resizable
width="500px"
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isButton` | `boolean` | `true` | Whether to wrap the trigger in a button element. |
| `modalTitle` | `string` | `"Modal Title"` | Title displayed in the modal header. |
| `modalBody` | `string` | `"This is the modal body content."` | Content displayed in the modal body. |
| `tooltip` | `string` | `"Click to open modal"` | Tooltip text shown on hover over the trigger. |
| `width` | `string` | `"600px"` | Width of the modal (e.g., "600px", "80%"). |
| `maxWidth` | `string` | `"1000px"` | Maximum width of the modal. |
| `responsive` | `boolean` | `true` | Whether the modal should be responsive. |
| `draggable` | `boolean` | `false` | Whether the modal can be dragged by its header. |
| `resizable` | `boolean` | `false` | Whether the modal can be resized by dragging corners. |
| `triggerNode` | `string` | `"Click to Open Modal"` | The clickable element that opens the modal when clicked. |
## Import
```tsx
import { ModalTrigger } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.stories.tsx).
:::

View File

@@ -1,199 +0,0 @@
---
title: Popover
sidebar_label: Popover
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Popover
A floating card that appears when hovering or clicking a trigger element. Supports configurable placement, trigger behavior, and custom content.
## Live Example
<StoryWithControls
component="Popover"
props={{
content: "Popover sample content",
title: "Popover title",
arrow: true,
color: "#fff"
}}
controls={[
{
name: "content",
label: "Content",
type: "text",
description: "Content displayed inside the popover body."
},
{
name: "title",
label: "Title",
type: "text",
description: "Title displayed in the popover header."
},
{
name: "arrow",
label: "Arrow",
type: "boolean",
description: "Whether to show the popover's arrow pointing to the trigger."
},
{
name: "color",
label: "Color",
type: "color",
description: "The background color of the popover."
},
{
name: "placement",
label: "Placement",
type: "select",
options: [
"topLeft",
"top",
"topRight",
"leftTop",
"left",
"leftBottom",
"rightTop",
"right",
"rightBottom",
"bottomLeft",
"bottom",
"bottomRight"
],
description: "Position of the popover relative to the trigger element."
},
{
name: "trigger",
label: "Trigger",
type: "select",
options: [
"hover",
"click",
"focus"
],
description: "Event that triggers the popover to appear."
}
]}
sampleChildren={[{"component":"Button","props":{"children":"Hover me"}}]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Popover
content="Popover sample content"
title="Popover title"
arrow
>
<Button>Hover me</Button>
</Popover>
);
}
```
## Click Trigger
```tsx live
function ClickPopover() {
return (
<Popover
content="This popover appears on click."
title="Click Popover"
trigger="click"
>
<Button>Click me</Button>
</Popover>
);
}
```
## Placements
```tsx live
function PlacementsDemo() {
return (
<div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', justifyContent: 'center', padding: '60px 0' }}>
{['top', 'right', 'bottom', 'left'].map(placement => (
<Popover
key={placement}
content={`This popover is placed on the ${placement}`}
title={placement}
placement={placement}
>
<Button>{placement}</Button>
</Popover>
))}
</div>
);
}
```
## Rich Content
```tsx live
function RichPopover() {
return (
<Popover
title="Dashboard Info"
content={
<div>
<p><strong>Created by:</strong> Admin</p>
<p><strong>Last modified:</strong> Jan 2025</p>
<p><strong>Charts:</strong> 12</p>
</div>
}
>
<Button buttonStyle="primary">
<Icons.InfoCircleOutlined /> View Details
</Button>
</Popover>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `content` | `string` | `"Popover sample content"` | Content displayed inside the popover body. |
| `title` | `string` | `"Popover title"` | Title displayed in the popover header. |
| `arrow` | `boolean` | `true` | Whether to show the popover's arrow pointing to the trigger. |
| `color` | `string` | `"#fff"` | The background color of the popover. |
## Import
```tsx
import { Popover } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Popover/Popover.stories.tsx).
:::

View File

@@ -1,206 +0,0 @@
---
title: ProgressBar
sidebar_label: ProgressBar
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# ProgressBar
Progress bar component for displaying completion status. Supports line, circle, and dashboard display types.
## Live Example
<StoryWithControls
component="ProgressBar"
props={{
percent: 75,
status: "normal",
type: "line",
striped: false,
showInfo: true,
strokeLinecap: "round"
}}
controls={[
{
name: "percent",
label: "Percent",
type: "number",
description: "Completion percentage (0-100)."
},
{
name: "status",
label: "Status",
type: "select",
options: [
"normal",
"success",
"exception",
"active"
],
description: "Current status of the progress bar."
},
{
name: "type",
label: "Type",
type: "select",
options: [
"line",
"circle",
"dashboard"
],
description: "Display type: line, circle, or dashboard gauge."
},
{
name: "striped",
label: "Striped",
type: "boolean",
description: "Whether to show striped animation on the bar."
},
{
name: "showInfo",
label: "Show Info",
type: "boolean",
description: "Whether to show the percentage text."
},
{
name: "strokeLinecap",
label: "Stroke Linecap",
type: "select",
options: [
"round",
"butt",
"square"
],
description: "Shape of the progress bar endpoints."
},
{
name: "strokeColor",
label: "Stroke Color",
type: "color",
description: "Color of the progress bar fill."
},
{
name: "trailColor",
label: "Trail Color",
type: "color",
description: "Color of the unfilled portion."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<ProgressBar
percent={75}
status="normal"
type="line"
showInfo
/>
);
}
```
## All Progress Types
```tsx live
function AllTypesDemo() {
return (
<div style={{ display: 'flex', gap: 40, alignItems: 'center' }}>
<div style={{ flex: 1 }}>
<h4>Line</h4>
<ProgressBar percent={75} type="line" />
</div>
<div>
<h4>Circle</h4>
<ProgressBar percent={75} type="circle" />
</div>
<div>
<h4>Dashboard</h4>
<ProgressBar percent={75} type="dashboard" />
</div>
</div>
);
}
```
## Status Variants
```tsx live
function StatusDemo() {
const statuses = ['normal', 'success', 'exception', 'active'];
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
{statuses.map(status => (
<div key={status} style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
<span style={{ width: 80 }}>{status}</span>
<ProgressBar percent={75} status={status} type="line" style={{ flex: 1 }} />
</div>
))}
</div>
);
}
```
## Custom Colors
```tsx live
function CustomColors() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<ProgressBar percent={50} strokeColor="#1890ff" />
<ProgressBar percent={70} strokeColor="#52c41a" />
<ProgressBar percent={30} strokeColor="#faad14" trailColor="#f0f0f0" />
<ProgressBar percent={90} strokeColor="#ff4d4f" />
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `percent` | `number` | `75` | Completion percentage (0-100). |
| `status` | `string` | `"normal"` | Current status of the progress bar. |
| `type` | `string` | `"line"` | Display type: line, circle, or dashboard gauge. |
| `striped` | `boolean` | `false` | Whether to show striped animation on the bar. |
| `showInfo` | `boolean` | `true` | Whether to show the percentage text. |
| `strokeLinecap` | `string` | `"round"` | Shape of the progress bar endpoints. |
## Import
```tsx
import { ProgressBar } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/ProgressBar/ProgressBar.stories.tsx).
:::

View File

@@ -1,137 +0,0 @@
---
title: Radio
sidebar_label: Radio
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Radio
Radio button component for selecting one option from a set. Supports standalone radio buttons, radio buttons styled as buttons, and grouped radio buttons with layout configuration.
## Live Example
<StoryWithControls
component="Radio"
props={{
value: "radio1",
disabled: false,
checked: false,
children: "Radio"
}}
controls={[
{
name: "value",
label: "Value",
type: "text",
description: "The value associated with this radio button."
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Whether the radio button is disabled."
},
{
name: "checked",
label: "Checked",
type: "boolean",
description: "Whether the radio button is checked (controlled mode)."
},
{
name: "children",
label: "Children",
type: "text",
description: "Label text displayed next to the radio button."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Radio
value="radio1"
>
Radio
</Radio>
);
}
```
## Radio Button Variants
```tsx live
function RadioButtonDemo() {
const [value, setValue] = React.useState('line');
return (
<Radio.Group value={value} onChange={e => setValue(e.target.value)}>
<Radio.Button value="line">Line Chart</Radio.Button>
<Radio.Button value="bar">Bar Chart</Radio.Button>
<Radio.Button value="pie">Pie Chart</Radio.Button>
</Radio.Group>
);
}
```
## Vertical Radio Group
```tsx live
function VerticalDemo() {
const [value, setValue] = React.useState('option1');
return (
<Radio.Group value={value} onChange={e => setValue(e.target.value)}>
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
<Radio value="option1">First option</Radio>
<Radio value="option2">Second option</Radio>
<Radio value="option3">Third option</Radio>
</div>
</Radio.Group>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `string` | `"radio1"` | The value associated with this radio button. |
| `disabled` | `boolean` | `false` | Whether the radio button is disabled. |
| `checked` | `boolean` | `false` | Whether the radio button is checked (controlled mode). |
| `children` | `string` | `"Radio"` | Label text displayed next to the radio button. |
## Import
```tsx
import { Radio } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Radio/Radio.stories.tsx).
:::

View File

@@ -1,85 +0,0 @@
---
title: SafeMarkdown
sidebar_label: SafeMarkdown
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# SafeMarkdown
The SafeMarkdown component from Superset's UI library.
## Live Example
<StoryWithControls
component="SafeMarkdown"
props={{
htmlSanitization: true
}}
controls={[
{
name: "htmlSanitization",
label: "Html Sanitization",
type: "boolean",
description: "Enable HTML sanitization (recommended for user input)"
},
{
name: "source",
label: "Source",
type: "text",
description: "Markdown source string to render"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<SafeMarkdown
htmlSanitization
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `htmlSanitization` | `boolean` | `true` | Enable HTML sanitization (recommended for user input) |
## Import
```tsx
import { SafeMarkdown } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown/SafeMarkdown.stories.tsx).
:::

View File

@@ -1,308 +0,0 @@
---
title: Select
sidebar_label: Select
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Select
A versatile select component supporting single and multi-select modes, search filtering, option creation, and both synchronous and asynchronous data sources.
## Live Example
<StoryWithControls
component="Select"
props={{
mode: "single",
placeholder: "Select ...",
showSearch: true,
allowNewOptions: false,
allowClear: false,
allowSelectAll: true,
disabled: false,
invertSelection: false,
oneLine: false,
maxTagCount: 4,
options: [
{
label: "Such an incredibly awesome long long label",
value: "long-label-1"
},
{
label: "Another incredibly awesome long long label",
value: "long-label-2"
},
{
label: "Option A",
value: "A"
},
{
label: "Option B",
value: "B"
},
{
label: "Option C",
value: "C"
},
{
label: "Option D",
value: "D"
},
{
label: "Option E",
value: "E"
},
{
label: "Option F",
value: "F"
},
{
label: "Option G",
value: "G"
},
{
label: "Option H",
value: "H"
},
{
label: "Option I",
value: "I"
}
]
}}
controls={[
{
name: "mode",
label: "Mode",
type: "inline-radio",
options: [
"single",
"multiple"
],
description: "Whether to allow selection of a single option or multiple."
},
{
name: "placeholder",
label: "Placeholder",
type: "text",
description: "Placeholder text when no option is selected."
},
{
name: "showSearch",
label: "Show Search",
type: "boolean",
description: "Whether to show a search input for filtering."
},
{
name: "allowNewOptions",
label: "Allow New Options",
type: "boolean",
description: "Whether users can create new options by typing a value not in the list."
},
{
name: "allowClear",
label: "Allow Clear",
type: "boolean",
description: "Whether to show a clear button to reset the selection."
},
{
name: "allowSelectAll",
label: "Allow Select All",
type: "boolean",
description: "Whether to show a \"Select All\" option in multiple mode."
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Whether the select is disabled."
},
{
name: "invertSelection",
label: "Invert Selection",
type: "boolean",
description: "Shows a stop icon instead of a checkmark on selected options, indicating deselection on click."
},
{
name: "oneLine",
label: "One Line",
type: "boolean",
description: "Forces tags onto one line with overflow count. Requires multiple mode."
},
{
name: "maxTagCount",
label: "Max Tag Count",
type: "number",
description: "Maximum number of tags to display in multiple mode before showing an overflow count."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<div style={{ width: 300 }}>
<Select
ariaLabel="demo-select"
options={[
{ label: 'Dashboards', value: 'dashboards' },
{ label: 'Charts', value: 'charts' },
{ label: 'Datasets', value: 'datasets' },
{ label: 'SQL Lab', value: 'sqllab' },
{ label: 'Settings', value: 'settings' },
]}
placeholder="Select ..."
showSearch
/>
</div>
);
}
```
## Multi Select
```tsx live
function MultiSelectDemo() {
return (
<div style={{ width: 400 }}>
<Select
ariaLabel="multi-select"
mode="multiple"
options={[
{ label: 'Dashboards', value: 'dashboards' },
{ label: 'Charts', value: 'charts' },
{ label: 'Datasets', value: 'datasets' },
{ label: 'SQL Lab', value: 'sqllab' },
{ label: 'Settings', value: 'settings' },
]}
placeholder="Select items..."
allowSelectAll
maxTagCount={3}
/>
</div>
);
}
```
## Allow New Options
```tsx live
function AllowNewDemo() {
return (
<div style={{ width: 300 }}>
<Select
ariaLabel="allow-new-select"
mode="multiple"
options={[
{ label: 'Red', value: 'red' },
{ label: 'Green', value: 'green' },
{ label: 'Blue', value: 'blue' },
]}
placeholder="Type to add tags..."
allowNewOptions
showSearch
/>
</div>
);
}
```
## Inverted Selection
```tsx live
function InvertedDemo() {
return (
<div style={{ width: 400 }}>
<Select
ariaLabel="inverted-select"
mode="multiple"
options={[
{ label: 'Admin', value: 'admin' },
{ label: 'Editor', value: 'editor' },
{ label: 'Viewer', value: 'viewer' },
{ label: 'Public', value: 'public' },
]}
placeholder="Exclude roles..."
invertSelection
/>
</div>
);
}
```
## One Line Mode
```tsx live
function OneLineDemo() {
return (
<div style={{ width: 300 }}>
<Select
ariaLabel="oneline-select"
mode="multiple"
options={[
{ label: 'Dashboard 1', value: 'd1' },
{ label: 'Dashboard 2', value: 'd2' },
{ label: 'Dashboard 3', value: 'd3' },
{ label: 'Dashboard 4', value: 'd4' },
{ label: 'Dashboard 5', value: 'd5' },
]}
placeholder="Select dashboards..."
oneLine
/>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `mode` | `string` | `"single"` | Whether to allow selection of a single option or multiple. |
| `placeholder` | `string` | `"Select ..."` | Placeholder text when no option is selected. |
| `showSearch` | `boolean` | `true` | Whether to show a search input for filtering. |
| `allowNewOptions` | `boolean` | `false` | Whether users can create new options by typing a value not in the list. |
| `allowClear` | `boolean` | `false` | Whether to show a clear button to reset the selection. |
| `allowSelectAll` | `boolean` | `true` | Whether to show a "Select All" option in multiple mode. |
| `disabled` | `boolean` | `false` | Whether the select is disabled. |
| `invertSelection` | `boolean` | `false` | Shows a stop icon instead of a checkmark on selected options, indicating deselection on click. |
| `oneLine` | `boolean` | `false` | Forces tags onto one line with overflow count. Requires multiple mode. |
| `maxTagCount` | `number` | `4` | Maximum number of tags to display in multiple mode before showing an overflow count. |
| `options` | `any` | `[{"label":"Such an incredibly awesome long long label","value":"long-label-1"},{"label":"Another incredibly awesome long long label","value":"long-label-2"},{"label":"Option A","value":"A"},{"label":"Option B","value":"B"},{"label":"Option C","value":"C"},{"label":"Option D","value":"D"},{"label":"Option E","value":"E"},{"label":"Option F","value":"F"},{"label":"Option G","value":"G"},{"label":"Option H","value":"H"},{"label":"Option I","value":"I"}]` | - |
## Import
```tsx
import { Select } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Select/Select.stories.tsx).
:::

View File

@@ -1,140 +0,0 @@
---
title: Skeleton
sidebar_label: Skeleton
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Skeleton
Skeleton loading component with support for avatar, title, paragraph, button, and input placeholders.
## Live Example
<StoryWithControls
component="Skeleton"
props={{
active: true,
avatar: false,
loading: true,
title: true,
shape: "circle",
size: "default",
block: false
}}
controls={[
{
name: "active",
label: "Active",
type: "boolean",
description: "Show animation effect."
},
{
name: "avatar",
label: "Avatar",
type: "boolean",
description: "Show avatar placeholder."
},
{
name: "loading",
label: "Loading",
type: "boolean",
description: "Display the skeleton when true."
},
{
name: "title",
label: "Title",
type: "boolean",
description: "Show title placeholder."
},
{
name: "shape",
label: "Shape",
type: "select",
options: [
"circle",
"square"
],
description: "Shape of the avatar/button skeleton."
},
{
name: "size",
label: "Size",
type: "select",
options: [
"large",
"small",
"default"
],
description: "Size of the skeleton elements."
},
{
name: "block",
label: "Block",
type: "boolean",
description: "Option to fit button width to its parent width."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Skeleton
active
loading
title
shape="circle"
size="default"
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `active` | `boolean` | `true` | Show animation effect. |
| `avatar` | `boolean` | `false` | Show avatar placeholder. |
| `loading` | `boolean` | `true` | Display the skeleton when true. |
| `title` | `boolean` | `true` | Show title placeholder. |
| `shape` | `string` | `"circle"` | Shape of the avatar/button skeleton. |
| `size` | `string` | `"default"` | Size of the skeleton elements. |
| `block` | `boolean` | `false` | Option to fit button width to its parent width. |
## Import
```tsx
import { Skeleton } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Skeleton/Skeleton.stories.tsx).
:::

View File

@@ -1,253 +0,0 @@
---
title: Slider
sidebar_label: Slider
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Slider
A slider input for selecting a value or range from a continuous or stepped interval. Supports single value, range, vertical orientation, marks, and tooltip display.
## Live Example
<StoryWithControls
component="Slider"
props={{
min: 0,
max: 100,
defaultValue: 70,
step: 1,
disabled: false,
reverse: false,
vertical: false,
keyboard: true,
dots: false,
included: true
}}
controls={[
{
name: "min",
label: "Min",
type: "number",
description: "Minimum value of the slider."
},
{
name: "max",
label: "Max",
type: "number",
description: "Maximum value of the slider."
},
{
name: "defaultValue",
label: "Default Value",
type: "number",
description: "Initial value of the slider."
},
{
name: "step",
label: "Step",
type: "number",
description: "Step increment between values. Use null for marks-only mode."
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Whether the slider is disabled."
},
{
name: "reverse",
label: "Reverse",
type: "boolean",
description: "Whether to reverse the slider direction."
},
{
name: "vertical",
label: "Vertical",
type: "boolean",
description: "Whether to display the slider vertically."
},
{
name: "keyboard",
label: "Keyboard",
type: "boolean",
description: "Whether keyboard arrow keys can control the slider."
},
{
name: "dots",
label: "Dots",
type: "boolean",
description: "Whether to show dots at each step mark."
},
{
name: "included",
label: "Included",
type: "boolean",
description: "Whether to highlight the filled portion of the track."
},
{
name: "tooltipOpen",
label: "Tooltip Open",
type: "boolean",
description: "Whether the value tooltip is always visible."
},
{
name: "tooltipPosition",
label: "Tooltip Position",
type: "select",
options: [
"top",
"left",
"bottom",
"right",
"topLeft",
"topRight",
"bottomLeft",
"bottomRight",
"leftTop",
"leftBottom",
"rightTop",
"rightBottom"
],
description: "Position of the value tooltip relative to the handle."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<div style={{ width: 400, padding: '20px 0' }}>
<Slider
min={0}
max={100}
defaultValue={70}
step={1}
/>
</div>
);
}
```
## Range Slider
```tsx live
function RangeSliderDemo() {
return (
<div style={{ width: 400, padding: '20px 0' }}>
<h4>Basic Range</h4>
<Slider range defaultValue={[20, 70]} min={0} max={100} />
<br />
<h4>Draggable Track</h4>
<Slider range={{ draggableTrack: true }} defaultValue={[30, 60]} min={0} max={100} />
</div>
);
}
```
## With Marks
```tsx live
function MarksDemo() {
return (
<div style={{ width: 400, padding: '20px 0' }}>
<Slider
min={0}
max={100}
defaultValue={37}
marks={{
0: '0°C',
25: '25°C',
50: '50°C',
75: '75°C',
100: '100°C',
}}
/>
</div>
);
}
```
## Stepped and Dots
```tsx live
function SteppedDemo() {
return (
<div style={{ width: 400, padding: '20px 0' }}>
<h4>Step = 10 with Dots</h4>
<Slider min={0} max={100} defaultValue={30} step={10} dots />
<br />
<h4>Step = 25</h4>
<Slider min={0} max={100} defaultValue={50} step={25} dots
marks={{ 0: '0', 25: '25', 50: '50', 75: '75', 100: '100' }} />
</div>
);
}
```
## Vertical Slider
```tsx live
function VerticalDemo() {
return (
<div style={{ height: 300, display: 'flex', gap: 40, padding: '0 40px' }}>
<Slider vertical defaultValue={30} />
<Slider vertical range defaultValue={[20, 60]} />
<Slider vertical defaultValue={50} dots step={10}
marks={{ 0: '0', 50: '50', 100: '100' }} />
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `min` | `number` | `0` | Minimum value of the slider. |
| `max` | `number` | `100` | Maximum value of the slider. |
| `defaultValue` | `number` | `70` | Initial value of the slider. |
| `step` | `number` | `1` | Step increment between values. Use null for marks-only mode. |
| `disabled` | `boolean` | `false` | Whether the slider is disabled. |
| `reverse` | `boolean` | `false` | Whether to reverse the slider direction. |
| `vertical` | `boolean` | `false` | Whether to display the slider vertically. |
| `keyboard` | `boolean` | `true` | Whether keyboard arrow keys can control the slider. |
| `dots` | `boolean` | `false` | Whether to show dots at each step mark. |
| `included` | `boolean` | `true` | Whether to highlight the filled portion of the track. |
## Import
```tsx
import { Slider } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Slider/Slider.stories.tsx).
:::

View File

@@ -1,272 +0,0 @@
---
title: Steps
sidebar_label: Steps
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Steps
A navigation component for guiding users through multi-step workflows. Supports horizontal, vertical, and inline layouts with progress tracking.
## Live Example
<StoryWithControls
component="Steps"
props={{
direction: "horizontal",
current: 1,
labelPlacement: "horizontal",
progressDot: false,
size: "default",
status: "process",
type: "default",
title: "Step 3",
description: "Description 3",
items: [
{
title: "Connect Database",
description: "Configure the connection"
},
{
title: "Create Dataset",
description: "Select tables and columns"
},
{
title: "Build Chart",
description: "Choose visualization type"
}
]
}}
controls={[
{
name: "direction",
label: "Direction",
type: "select",
options: [
"horizontal",
"vertical"
],
description: "Layout direction of the steps."
},
{
name: "current",
label: "Current",
type: "number",
description: "Index of the current step (zero-based)."
},
{
name: "labelPlacement",
label: "Label Placement",
type: "select",
options: [
"horizontal",
"vertical"
],
description: "Position of step labels relative to the step icon."
},
{
name: "progressDot",
label: "Progress Dot",
type: "boolean",
description: "Whether to use a dot style instead of numbered icons."
},
{
name: "size",
label: "Size",
type: "select",
options: [
"default",
"small"
],
description: "Size of the step icons and text."
},
{
name: "status",
label: "Status",
type: "select",
options: [
"wait",
"process",
"finish",
"error"
],
description: "Status of the current step."
},
{
name: "type",
label: "Type",
type: "select",
options: [
"default",
"navigation",
"inline"
],
description: "Visual style: default numbered, navigation breadcrumb, or inline compact."
},
{
name: "title",
label: "Title",
type: "text"
},
{
name: "description",
label: "Description",
type: "text"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Steps
current={1}
items={[
{ title: 'Connect Database', description: 'Configure the connection' },
{ title: 'Create Dataset', description: 'Select tables and columns' },
{ title: 'Build Chart', description: 'Choose visualization type' },
]}
/>
);
}
```
## Vertical Steps
```tsx live
function VerticalSteps() {
return (
<Steps
direction="vertical"
current={1}
items={[
{ title: 'Upload CSV', description: 'Select a file from your computer' },
{ title: 'Configure Columns', description: 'Set data types and names' },
{ title: 'Review', description: 'Verify the data looks correct' },
{ title: 'Import', description: 'Save the dataset' },
]}
/>
);
}
```
## Status Indicators
```tsx live
function StatusSteps() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
<div>
<h4>Error on Step 2</h4>
<Steps
current={1}
status="error"
items={[
{ title: 'Connection', description: 'Configured' },
{ title: 'Validation', description: 'Failed to validate' },
{ title: 'Complete' },
]}
/>
</div>
<div>
<h4>All Complete</h4>
<Steps
current={3}
items={[
{ title: 'Step 1' },
{ title: 'Step 2' },
{ title: 'Step 3' },
]}
/>
</div>
</div>
);
}
```
## Dot Style and Small Size
```tsx live
function DotAndSmall() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
<div>
<h4>Progress Dots</h4>
<Steps
progressDot
current={1}
items={[
{ title: 'Create', description: 'Define the resource' },
{ title: 'Configure', description: 'Set parameters' },
{ title: 'Deploy', description: 'Go live' },
]}
/>
</div>
<div>
<h4>Small Size</h4>
<Steps
size="small"
current={2}
items={[
{ title: 'Login' },
{ title: 'Verify' },
{ title: 'Done' },
]}
/>
</div>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `direction` | `string` | `"horizontal"` | Layout direction of the steps. |
| `current` | `number` | `1` | Index of the current step (zero-based). |
| `labelPlacement` | `string` | `"horizontal"` | Position of step labels relative to the step icon. |
| `progressDot` | `boolean` | `false` | Whether to use a dot style instead of numbered icons. |
| `size` | `string` | `"default"` | Size of the step icons and text. |
| `status` | `string` | `"process"` | Status of the current step. |
| `type` | `string` | `"default"` | Visual style: default numbered, navigation breadcrumb, or inline compact. |
| `title` | `string` | `"Step 3"` | - |
| `description` | `string` | `"Description 3"` | - |
| `items` | `any` | `[{"title":"Connect Database","description":"Configure the connection"},{"title":"Create Dataset","description":"Select tables and columns"},{"title":"Build Chart","description":"Choose visualization type"}]` | - |
## Import
```tsx
import { Steps } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Steps/Steps.stories.tsx).
:::

View File

@@ -1,193 +0,0 @@
---
title: Switch
sidebar_label: Switch
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Switch
A toggle switch for boolean on/off states. Supports loading indicators, sizing, and an HTML title attribute for accessibility tooltips.
## Live Example
<StoryWithControls
component="Switch"
props={{
disabled: false,
loading: false,
title: "Toggle feature"
}}
controls={[
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Whether the switch is disabled."
},
{
name: "loading",
label: "Loading",
type: "boolean",
description: "Whether to show a loading spinner inside the switch."
},
{
name: "title",
label: "Title",
type: "text",
description: "HTML title attribute shown as a browser tooltip on hover. Useful for accessibility."
},
{
name: "checked",
label: "Checked",
type: "boolean",
description: "Whether the switch is on."
},
{
name: "size",
label: "Size",
type: "radio",
options: [
"small",
"default"
],
description: "Size of the switch."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const [checked, setChecked] = React.useState(true);
return (
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch
checked={checked}
onChange={setChecked}
title="Toggle feature"
/>
<span>{checked ? 'On' : 'Off'}</span>
<span style={{ color: '#999', fontSize: 12 }}>(hover the switch to see the title tooltip)</span>
</div>
);
}
```
## Switch States
```tsx live
function SwitchStates() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch defaultChecked title="Enabled switch" />
<span>Checked</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch title="Unchecked switch" />
<span>Unchecked</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch disabled defaultChecked title="Disabled on" />
<span>Disabled (on)</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch disabled title="Disabled off" />
<span>Disabled (off)</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch loading defaultChecked title="Loading switch" />
<span>Loading</span>
</div>
</div>
);
}
```
## Sizes
```tsx live
function SizesDemo() {
return (
<div style={{ display: 'flex', alignItems: 'center', gap: 24 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch size="small" defaultChecked title="Small switch" />
<span>Small</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<Switch size="default" defaultChecked title="Default switch" />
<span>Default</span>
</div>
</div>
);
}
```
## Settings Panel
```tsx live
function SettingsPanel() {
const [notifications, setNotifications] = React.useState(true);
const [darkMode, setDarkMode] = React.useState(false);
const [autoRefresh, setAutoRefresh] = React.useState(true);
return (
<div style={{ maxWidth: 320, border: '1px solid #e8e8e8', borderRadius: 8, padding: 16 }}>
<h4 style={{ marginTop: 0 }}>Dashboard Settings</h4>
{[
{ label: 'Email notifications', checked: notifications, onChange: setNotifications, title: 'Toggle email notifications' },
{ label: 'Dark mode', checked: darkMode, onChange: setDarkMode, title: 'Toggle dark mode' },
{ label: 'Auto-refresh data', checked: autoRefresh, onChange: setAutoRefresh, title: 'Toggle auto-refresh' },
].map(({ label, checked, onChange, title }) => (
<div key={label} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 0', borderBottom: '1px solid #f0f0f0' }}>
<span>{label}</span>
<Switch checked={checked} onChange={onChange} title={title} />
</div>
))}
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `disabled` | `boolean` | `false` | Whether the switch is disabled. |
| `loading` | `boolean` | `false` | Whether to show a loading spinner inside the switch. |
| `title` | `string` | `"Toggle feature"` | HTML title attribute shown as a browser tooltip on hover. Useful for accessibility. |
## Import
```tsx
import { Switch } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Switch/Switch.stories.tsx).
:::

View File

@@ -1,66 +0,0 @@
---
title: TableCollection
sidebar_label: TableCollection
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# TableCollection
The TableCollection component from Superset's UI library.
## Live Example
<StoryWithControls
component="TableCollection"
props={{}}
controls={[]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<TableCollection
// Add props here
/>
);
}
```
## Import
```tsx
import { TableCollection } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/TableCollection/TableCollection.stories.tsx).
:::

View File

@@ -1,294 +0,0 @@
---
title: TableView
sidebar_label: TableView
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# TableView
A data table component with sorting, pagination, text wrapping, and empty state support. Built on react-table.
## Live Example
<StoryWithControls
component="TableView"
props={{
accessor: "summary",
Header: "Summary",
sortable: true,
id: 456,
age: 10,
name: "John Smith",
summary: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam id porta neque, a vehicula orci. Maecenas rhoncus elit sit amet purus convallis placerat in at nunc. Nulla nec viverra augue.",
noDataText: "No data here",
pageSize: 2,
showRowCount: true,
withPagination: true,
scrollTopOnPagination: false,
columns: [
{
accessor: "id",
Header: "ID",
sortable: true,
id: "id"
},
{
accessor: "age",
Header: "Age",
id: "age"
},
{
accessor: "name",
Header: "Name",
id: "name"
},
{
accessor: "summary",
Header: "Summary",
id: "summary"
}
],
data: [
{
id: 123,
age: 27,
name: "Emily",
summary: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
},
{
id: 321,
age: 10,
name: "Kate",
summary: "Nam id porta neque, a vehicula orci."
},
{
id: 456,
age: 10,
name: "John Smith",
summary: "Maecenas rhoncus elit sit amet purus convallis placerat."
}
]
}}
controls={[
{
name: "accessor",
label: "Accessor",
type: "text"
},
{
name: "Header",
label: "Header",
type: "text"
},
{
name: "sortable",
label: "Sortable",
type: "boolean"
},
{
name: "id",
label: "ID",
type: "number"
},
{
name: "age",
label: "Age",
type: "number"
},
{
name: "name",
label: "Name",
type: "text"
},
{
name: "summary",
label: "Summary",
type: "text"
},
{
name: "noDataText",
label: "No Data Text",
type: "text",
description: "Text displayed when the table has no data."
},
{
name: "pageSize",
label: "Page Size",
type: "number",
description: "Number of rows displayed per page."
},
{
name: "showRowCount",
label: "Show Row Count",
type: "boolean",
description: "Whether to display the total row count alongside pagination."
},
{
name: "withPagination",
label: "With Pagination",
type: "boolean",
description: "Whether to show pagination controls below the table."
},
{
name: "scrollTopOnPagination",
label: "Scroll Top On Pagination",
type: "boolean",
description: "Whether to scroll to the top of the table when changing pages."
},
{
name: "emptyWrapperType",
label: "Empty Wrapper Type",
type: "select",
description: "Style of the empty state wrapper."
},
{
name: "initialPageIndex",
label: "Initial Page Index",
type: "number",
description: "Initial page to display (zero-based)."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<TableView
columns={[
{ accessor: 'id', Header: 'ID', sortable: true, id: 'id' },
{ accessor: 'age', Header: 'Age', id: 'age' },
{ accessor: 'name', Header: 'Name', id: 'name' },
{ accessor: 'summary', Header: 'Summary', id: 'summary' },
]}
data={[
{ id: 123, age: 27, name: 'Emily', summary: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' },
{ id: 321, age: 10, name: 'Kate', summary: 'Nam id porta neque, a vehicula orci.' },
{ id: 456, age: 10, name: 'John Smith', summary: 'Maecenas rhoncus elit sit amet purus convallis placerat.' },
]}
initialSortBy={[{ id: 'name', desc: true }]}
pageSize={2}
withPagination
showRowCount
/>
);
}
```
## Without Pagination
```tsx live
function NoPaginationDemo() {
return (
<TableView
columns={[
{ accessor: 'name', Header: 'Name', id: 'name' },
{ accessor: 'email', Header: 'Email', id: 'email' },
{ accessor: 'status', Header: 'Status', id: 'status' },
]}
data={[
{ name: 'Alice', email: 'alice@example.com', status: 'Active' },
{ name: 'Bob', email: 'bob@example.com', status: 'Inactive' },
{ name: 'Charlie', email: 'charlie@example.com', status: 'Active' },
]}
withPagination={false}
/>
);
}
```
## Empty State
```tsx live
function EmptyDemo() {
return (
<TableView
columns={[
{ accessor: 'name', Header: 'Name', id: 'name' },
{ accessor: 'value', Header: 'Value', id: 'value' },
]}
data={[]}
noDataText="No results found"
/>
);
}
```
## With Sorting
```tsx live
function SortingDemo() {
return (
<TableView
columns={[
{ accessor: 'id', Header: 'ID', id: 'id', sortable: true },
{ accessor: 'name', Header: 'Name', id: 'name', sortable: true },
{ accessor: 'score', Header: 'Score', id: 'score', sortable: true },
]}
data={[
{ id: 1, name: 'Dashboard A', score: 95 },
{ id: 2, name: 'Dashboard B', score: 72 },
{ id: 3, name: 'Dashboard C', score: 88 },
{ id: 4, name: 'Dashboard D', score: 64 },
]}
initialSortBy={[{ id: 'score', desc: true }]}
withPagination={false}
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `accessor` | `string` | `"summary"` | - |
| `Header` | `string` | `"Summary"` | - |
| `sortable` | `boolean` | `true` | - |
| `id` | `number` | `456` | - |
| `age` | `number` | `10` | - |
| `name` | `string` | `"John Smith"` | - |
| `summary` | `string` | `"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam id porta neque, a vehicula orci. Maecenas rhoncus elit sit amet purus convallis placerat in at nunc. Nulla nec viverra augue."` | - |
| `noDataText` | `string` | `"No data here"` | Text displayed when the table has no data. |
| `pageSize` | `number` | `2` | Number of rows displayed per page. |
| `showRowCount` | `boolean` | `true` | Whether to display the total row count alongside pagination. |
| `withPagination` | `boolean` | `true` | Whether to show pagination controls below the table. |
| `scrollTopOnPagination` | `boolean` | `false` | Whether to scroll to the top of the table when changing pages. |
| `columns` | `any` | `[{"accessor":"id","Header":"ID","sortable":true,"id":"id"},{"accessor":"age","Header":"Age","id":"age"},{"accessor":"name","Header":"Name","id":"name"},{"accessor":"summary","Header":"Summary","id":"summary"}]` | - |
| `data` | `any` | `[{"id":123,"age":27,"name":"Emily","summary":"Lorem ipsum dolor sit amet, consectetur adipiscing elit."},{"id":321,"age":10,"name":"Kate","summary":"Nam id porta neque, a vehicula orci."},{"id":456,"age":10,"name":"John Smith","summary":"Maecenas rhoncus elit sit amet purus convallis placerat."}]` | - |
## Import
```tsx
import { TableView } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/TableView/TableView.stories.tsx).
:::

View File

@@ -1,223 +0,0 @@
---
title: Tabs
sidebar_label: Tabs
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Tabs
A tabs component for switching between different views or content sections. Supports multiple tab styles, positions, and sizes.
## Live Example
<StoryWithControls
component="Tabs"
props={{
defaultActiveKey: "1",
type: "line",
tabPosition: "top",
size: "middle",
animated: true,
centered: false,
tabBarGutter: 8,
items: [
{
key: "1",
label: "Tab 1",
children: "Content of Tab Pane 1"
},
{
key: "2",
label: "Tab 2",
children: "Content of Tab Pane 2"
},
{
key: "3",
label: "Tab 3",
children: "Content of Tab Pane 3"
}
]
}}
controls={[
{
name: "defaultActiveKey",
label: "Default Active Key",
type: "text"
},
{
name: "type",
label: "Type",
type: "inline-radio",
options: [
"line",
"card",
"editable-card"
],
description: "The style of tabs. Options: line, card, editable-card."
},
{
name: "tabPosition",
label: "Tab Position",
type: "inline-radio",
options: [
"top",
"bottom",
"left",
"right"
],
description: "Position of tabs. Options: top, bottom, left, right."
},
{
name: "size",
label: "Size",
type: "inline-radio",
options: [
"small",
"middle",
"large"
],
description: "Size of the tabs."
},
{
name: "animated",
label: "Animated",
type: "boolean",
description: "Whether to animate tab transitions."
},
{
name: "centered",
label: "Centered",
type: "boolean",
description: "Whether to center the tabs."
},
{
name: "tabBarGutter",
label: "Tab Bar Gutter",
type: "number",
description: "The gap between tabs."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Tabs
defaultActiveKey="1"
items={[
{ key: '1', label: 'Tab 1', children: 'Content of Tab Pane 1' },
{ key: '2', label: 'Tab 2', children: 'Content of Tab Pane 2' },
{ key: '3', label: 'Tab 3', children: 'Content of Tab Pane 3' },
]}
/>
);
}
```
## Card Style
```tsx live
function CardTabs() {
return (
<Tabs
type="card"
defaultActiveKey="1"
items={[
{ key: '1', label: 'Dashboards', children: 'View and manage your dashboards.' },
{ key: '2', label: 'Charts', children: 'Browse all saved charts.' },
{ key: '3', label: 'Datasets', children: 'Explore available datasets.' },
]}
/>
);
}
```
## Tab Positions
```tsx live
function TabPositions() {
const items = [
{ key: '1', label: 'Tab 1', children: 'Content 1' },
{ key: '2', label: 'Tab 2', children: 'Content 2' },
{ key: '3', label: 'Tab 3', children: 'Content 3' },
];
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
{['top', 'bottom', 'left', 'right'].map(pos => (
<div key={pos}>
<h4>{pos}</h4>
<Tabs tabPosition={pos} defaultActiveKey="1" items={items} />
</div>
))}
</div>
);
}
```
## With Icons
```tsx live
function IconTabs() {
return (
<Tabs
defaultActiveKey="1"
items={[
{ key: '1', label: <><Icons.DashboardOutlined /> Dashboards</>, children: 'Dashboard content here.' },
{ key: '2', label: <><Icons.LineChartOutlined /> Charts</>, children: 'Chart content here.' },
{ key: '3', label: <><Icons.DatabaseOutlined /> Datasets</>, children: 'Dataset content here.' },
{ key: '4', label: <><Icons.ConsoleSqlOutlined /> SQL Lab</>, children: 'SQL Lab content here.' },
]}
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `defaultActiveKey` | `string` | `"1"` | - |
| `type` | `string` | `"line"` | The style of tabs. Options: line, card, editable-card. |
| `tabPosition` | `string` | `"top"` | Position of tabs. Options: top, bottom, left, right. |
| `size` | `string` | `"middle"` | Size of the tabs. |
| `animated` | `boolean` | `true` | Whether to animate tab transitions. |
| `centered` | `boolean` | `false` | Whether to center the tabs. |
| `tabBarGutter` | `number` | `8` | The gap between tabs. |
| `items` | `any` | `[{"key":"1","label":"Tab 1","children":"Content of Tab Pane 1"},{"key":"2","label":"Tab 2","children":"Content of Tab Pane 2"},{"key":"3","label":"Tab 3","children":"Content of Tab Pane 3"}]` | - |
## Import
```tsx
import { Tabs } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Tabs/Tabs.stories.tsx).
:::

View File

@@ -1,172 +0,0 @@
---
title: Timer
sidebar_label: Timer
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Timer
A live elapsed-time display that counts up from a given start time. Used to show query and dashboard load durations. Requires a startTime timestamp to function.
## Live Example
<StoryWithControls
component="Timer"
props={{
isRunning: true,
status: "success",
startTime: 1737936000000
}}
controls={[
{
name: "isRunning",
label: "Is Running",
type: "boolean",
description: "Whether the timer is actively counting. Toggle to start/stop."
},
{
name: "status",
label: "Status",
type: "select",
options: [
"success",
"warning",
"danger",
"info",
"default",
"primary",
"secondary"
],
description: "Visual status of the timer badge."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const [isRunning, setIsRunning] = React.useState(true);
const [startTime] = React.useState(Date.now());
return (
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
<Timer
startTime={startTime}
isRunning={isRunning}
status="success"
/>
<Button onClick={() => setIsRunning(r => !r)}>
{isRunning ? 'Stop' : 'Start'}
</Button>
</div>
);
}
```
## Status Variants
```tsx live
function StatusVariants() {
const [startTime] = React.useState(Date.now());
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
{['success', 'warning', 'danger', 'info', 'default', 'primary', 'secondary'].map(status => (
<div key={status} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
<span style={{ width: 80 }}>{status}</span>
<Timer startTime={startTime} isRunning status={status} />
</div>
))}
</div>
);
}
```
## Completed Timer
```tsx live
function CompletedTimer() {
const start = Date.now() - 5230;
const end = Date.now();
return (
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
<Timer
startTime={start}
endTime={end}
isRunning={false}
status="success"
/>
<span style={{ color: '#999' }}>Query completed in ~5.2 seconds</span>
</div>
);
}
```
## Start and Stop
```tsx live
function StartStop() {
const [isRunning, setIsRunning] = React.useState(false);
const [startTime, setStartTime] = React.useState(null);
const handleToggle = () => {
if (!isRunning && !startTime) {
setStartTime(Date.now());
}
setIsRunning(r => !r);
};
return (
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
<Timer
startTime={startTime}
isRunning={isRunning}
status={isRunning ? 'warning' : 'success'}
/>
<Button onClick={handleToggle}>
{isRunning ? 'Pause' : startTime ? 'Resume' : 'Start'}
</Button>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isRunning` | `boolean` | `true` | Whether the timer is actively counting. Toggle to start/stop. |
| `status` | `string` | `"success"` | Visual status of the timer badge. |
| `startTime` | `number` | `1737936000000` | - |
## Import
```tsx
import { Timer } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Timer/Timer.stories.tsx).
:::

View File

@@ -1,171 +0,0 @@
---
title: Tooltip
sidebar_label: Tooltip
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Tooltip
The Tooltip component from Superset's UI library.
## Live Example
<StoryWithControls
component="Tooltip"
props={{
title: "Simple tooltip text",
mouseEnterDelay: 0.1,
mouseLeaveDelay: 0.1
}}
controls={[
{
name: "title",
label: "Title",
type: "text",
description: "Text or content shown in the tooltip."
},
{
name: "mouseEnterDelay",
label: "Mouse Enter Delay",
type: "number",
description: "Delay in seconds before showing the tooltip on hover."
},
{
name: "mouseLeaveDelay",
label: "Mouse Leave Delay",
type: "number",
description: "Delay in seconds before hiding the tooltip after mouse leave."
},
{
name: "placement",
label: "Placement",
type: "select",
options: [
"bottom",
"bottomLeft",
"bottomRight",
"left",
"leftBottom",
"leftTop",
"right",
"rightBottom",
"rightTop",
"top",
"topLeft",
"topRight"
],
description: "Position of the tooltip relative to the trigger element."
},
{
name: "trigger",
label: "Trigger",
type: "select",
options: [
"hover",
"focus",
"click",
"contextMenu"
],
description: "How the tooltip is triggered."
},
{
name: "color",
label: "Color",
type: "color",
description: "Custom background color for the tooltip."
}
]}
sampleChildren={[{"component":"Button","props":{"children":"Hover me"}}]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Tooltip title="This is a helpful tooltip">
<Button>Hover me</Button>
</Tooltip>
);
}
```
## Placements
```tsx live
function Placements() {
const placements = ['top', 'bottom', 'left', 'right', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight'];
return (
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
{placements.map(placement => (
<Tooltip key={placement} title={placement} placement={placement}>
<Button>{placement}</Button>
</Tooltip>
))}
</div>
);
}
```
## Trigger Types
```tsx live
function Triggers() {
return (
<div style={{ display: 'flex', gap: 12 }}>
<Tooltip title="Hover trigger" trigger="hover">
<Button>Hover</Button>
</Tooltip>
<Tooltip title="Click trigger" trigger="click">
<Button>Click</Button>
</Tooltip>
<Tooltip title="Focus trigger" trigger="focus">
<Button>Focus</Button>
</Tooltip>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | `string` | `"Simple tooltip text"` | Text or content shown in the tooltip. |
| `mouseEnterDelay` | `number` | `0.1` | Delay in seconds before showing the tooltip on hover. |
| `mouseLeaveDelay` | `number` | `0.1` | Delay in seconds before hiding the tooltip after mouse leave. |
## Import
```tsx
import { Tooltip } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Tooltip/Tooltip.stories.tsx).
:::

View File

@@ -1,268 +0,0 @@
---
title: Tree
sidebar_label: Tree
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Tree
The Tree component is used to display hierarchical data in a tree structure. It allows for features such as selection, expansion, and drag-and-drop functionality.
## Live Example
<StoryWithControls
component="Tree"
props={{
checkable: false,
defaultExpandAll: false,
disabled: false,
draggable: false,
multiple: false,
selectable: true,
showIcon: false,
showLine: false,
treeData: [
{
title: "parent 1",
key: "0-0",
children: [
{
title: "parent 1-0",
key: "0-0-0",
children: [
{
title: "leaf",
key: "0-0-0-0"
},
{
title: "leaf",
key: "0-0-0-1"
},
{
title: "leaf",
key: "0-0-0-2"
}
]
},
{
title: "parent 1-1",
key: "0-0-1",
children: [
{
title: "leaf",
key: "0-0-1-0"
}
]
},
{
title: "parent 1-2",
key: "0-0-2",
children: [
{
title: "leaf",
key: "0-0-2-0"
},
{
title: "leaf",
key: "0-0-2-1"
}
]
}
]
}
],
defaultExpandedKeys: [
"0-0",
"0-0-0"
]
}}
controls={[
{
name: "checkable",
label: "Checkable",
type: "boolean",
description: "Add a Checkbox before the treeNodes"
},
{
name: "defaultExpandAll",
label: "Default Expand All",
type: "boolean",
description: "Whether to expand all treeNodes by default"
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Whether disabled the tree"
},
{
name: "draggable",
label: "Draggable",
type: "boolean",
description: "Specifies whether this Tree or the node is draggable"
},
{
name: "multiple",
label: "Multiple",
type: "boolean",
description: "Allows selecting multiple treeNodes"
},
{
name: "selectable",
label: "Selectable",
type: "boolean",
description: "Whether can be selected"
},
{
name: "showIcon",
label: "Show Icon",
type: "boolean",
description: "Controls whether to display the icon node"
},
{
name: "showLine",
label: "Show Line",
type: "boolean",
description: "Shows a connecting line"
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const treeData = [
{
title: 'Databases',
key: 'databases',
children: [
{ title: 'PostgreSQL', key: 'postgres' },
{ title: 'MySQL', key: 'mysql' },
{ title: 'SQLite', key: 'sqlite' },
],
},
{
title: 'Charts',
key: 'charts',
children: [
{ title: 'Bar Chart', key: 'bar' },
{ title: 'Line Chart', key: 'line' },
{ title: 'Pie Chart', key: 'pie' },
],
},
];
return <Tree treeData={treeData} defaultExpandAll />;
}
```
## Checkable Tree
```tsx live
function CheckableTree() {
const [checkedKeys, setCheckedKeys] = React.useState(['postgres']);
const treeData = [
{
title: 'Databases',
key: 'databases',
children: [
{ title: 'PostgreSQL', key: 'postgres' },
{ title: 'MySQL', key: 'mysql' },
],
},
{
title: 'Charts',
key: 'charts',
children: [
{ title: 'Bar Chart', key: 'bar' },
{ title: 'Line Chart', key: 'line' },
],
},
];
return (
<Tree
treeData={treeData}
checkable
defaultExpandAll
checkedKeys={checkedKeys}
onCheck={setCheckedKeys}
/>
);
}
```
## With Lines and Icons
```tsx live
function LinesAndIcons() {
const treeData = [
{
title: 'Dashboards',
key: 'dashboards',
children: [
{ title: 'Sales Dashboard', key: 'sales' },
{ title: 'Marketing Dashboard', key: 'marketing' },
],
},
{
title: 'Reports',
key: 'reports',
children: [
{ title: 'Weekly Report', key: 'weekly' },
{ title: 'Monthly Report', key: 'monthly' },
],
},
];
return <Tree treeData={treeData} showLine showIcon defaultExpandAll />;
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `checkable` | `boolean` | `false` | Add a Checkbox before the treeNodes |
| `defaultExpandAll` | `boolean` | `false` | Whether to expand all treeNodes by default |
| `disabled` | `boolean` | `false` | Whether disabled the tree |
| `draggable` | `boolean` | `false` | Specifies whether this Tree or the node is draggable |
| `multiple` | `boolean` | `false` | Allows selecting multiple treeNodes |
| `selectable` | `boolean` | `true` | Whether can be selected |
| `showIcon` | `boolean` | `false` | Controls whether to display the icon node |
| `showLine` | `boolean` | `false` | Shows a connecting line |
| `treeData` | `any` | `[{"title":"parent 1","key":"0-0","children":[{"title":"parent 1-0","key":"0-0-0","children":[{"title":"leaf","key":"0-0-0-0"},{"title":"leaf","key":"0-0-0-1"},{"title":"leaf","key":"0-0-0-2"}]},{"title":"parent 1-1","key":"0-0-1","children":[{"title":"leaf","key":"0-0-1-0"}]},{"title":"parent 1-2","key":"0-0-2","children":[{"title":"leaf","key":"0-0-2-0"},{"title":"leaf","key":"0-0-2-1"}]}]}]` | - |
| `defaultExpandedKeys` | `any` | `["0-0","0-0-0"]` | - |
## Import
```tsx
import { Tree } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Tree/Tree.stories.tsx).
:::

View File

@@ -1,286 +0,0 @@
---
title: TreeSelect
sidebar_label: TreeSelect
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# TreeSelect
TreeSelect is a select component that allows users to select from a tree structure.
## Live Example
<StoryWithControls
component="TreeSelect"
props={{
allowClear: true,
disabled: false,
multiple: false,
placeholder: "Please select",
showSearch: true,
size: "middle",
treeCheckable: false,
treeDefaultExpandAll: true,
treeLine: false,
variant: "outlined",
treeData: [
{
title: "Node1",
value: "0-0",
children: [
{
title: "Child Node1",
value: "0-0-0"
},
{
title: "Child Node2",
value: "0-0-1"
}
]
},
{
title: "Node2",
value: "0-1",
children: [
{
title: "Child Node3",
value: "0-1-0"
}
]
}
]
}}
controls={[
{
name: "allowClear",
label: "Allow Clear",
type: "boolean",
description: "Whether to allow clearing the selected value."
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Whether the component is disabled."
},
{
name: "multiple",
label: "Multiple",
type: "boolean",
description: "Whether to allow multiple selections."
},
{
name: "placeholder",
label: "Placeholder",
type: "text",
description: "Placeholder text for the input field."
},
{
name: "showSearch",
label: "Show Search",
type: "boolean",
description: "Whether to show the search input."
},
{
name: "size",
label: "Size",
type: "select",
options: [
"large",
"middle",
"small"
],
description: "Size of the component."
},
{
name: "treeCheckable",
label: "Tree Checkable",
type: "boolean",
description: "Whether to show checkable tree nodes."
},
{
name: "treeDefaultExpandAll",
label: "Tree Default Expand All",
type: "boolean",
description: "Whether to expand all tree nodes by default."
},
{
name: "treeLine",
label: "Tree Line",
type: "boolean",
description: "Whether to show tree lines."
},
{
name: "variant",
label: "Variant",
type: "select",
options: [
"outlined",
"borderless",
"filled"
],
description: "Variant of the component."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const [value, setValue] = React.useState(undefined);
const treeData = [
{
title: 'Databases',
value: 'databases',
children: [
{ title: 'PostgreSQL', value: 'postgres' },
{ title: 'MySQL', value: 'mysql' },
],
},
{
title: 'Charts',
value: 'charts',
children: [
{ title: 'Bar Chart', value: 'bar' },
{ title: 'Line Chart', value: 'line' },
],
},
];
return (
<TreeSelect
style={{ width: 300 }}
value={value}
onChange={setValue}
treeData={treeData}
placeholder="Select an item"
allowClear
treeDefaultExpandAll
/>
);
}
```
## Multiple Selection with Checkboxes
```tsx live
function MultiSelectTree() {
const [value, setValue] = React.useState([]);
const treeData = [
{
title: 'Databases',
value: 'databases',
children: [
{ title: 'PostgreSQL', value: 'postgres' },
{ title: 'MySQL', value: 'mysql' },
{ title: 'SQLite', value: 'sqlite' },
],
},
{
title: 'File Formats',
value: 'formats',
children: [
{ title: 'CSV', value: 'csv' },
{ title: 'Excel', value: 'excel' },
],
},
];
return (
<TreeSelect
style={{ width: 300 }}
value={value}
onChange={setValue}
treeData={treeData}
treeCheckable
placeholder="Select data sources"
treeDefaultExpandAll
allowClear
/>
);
}
```
## With Tree Lines
```tsx live
function TreeLinesDemo() {
const treeData = [
{
title: 'Dashboards',
value: 'dashboards',
children: [
{ title: 'Sales Dashboard', value: 'sales' },
{ title: 'Marketing Dashboard', value: 'marketing' },
],
},
{
title: 'Charts',
value: 'charts',
children: [
{ title: 'Revenue Chart', value: 'revenue' },
{ title: 'User Growth', value: 'growth' },
],
},
];
return (
<TreeSelect
style={{ width: 300 }}
treeData={treeData}
treeLine
treeDefaultExpandAll
placeholder="Browse items"
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `allowClear` | `boolean` | `true` | Whether to allow clearing the selected value. |
| `disabled` | `boolean` | `false` | Whether the component is disabled. |
| `multiple` | `boolean` | `false` | Whether to allow multiple selections. |
| `placeholder` | `string` | `"Please select"` | Placeholder text for the input field. |
| `showSearch` | `boolean` | `true` | Whether to show the search input. |
| `size` | `string` | `"middle"` | Size of the component. |
| `treeCheckable` | `boolean` | `false` | Whether to show checkable tree nodes. |
| `treeDefaultExpandAll` | `boolean` | `true` | Whether to expand all tree nodes by default. |
| `treeLine` | `boolean` | `false` | Whether to show tree lines. |
| `variant` | `string` | `"outlined"` | Variant of the component. |
| `treeData` | `any` | `[{"title":"Node1","value":"0-0","children":[{"title":"Child Node1","value":"0-0-0"},{"title":"Child Node2","value":"0-0-1"}]},{"title":"Node2","value":"0-1","children":[{"title":"Child Node3","value":"0-1-0"}]}]` | - |
## Import
```tsx
import { TreeSelect } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/TreeSelect/TreeSelect.stories.tsx).
:::

View File

@@ -1,236 +0,0 @@
---
title: Typography
sidebar_label: Typography
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Typography
Typography is a component for displaying text with various styles and formats. It includes subcomponents like Title, Paragraph, and Link.
## Live Example
<StoryWithControls
component="Typography"
renderComponent="Typography.Text"
props={{
children: "Sample Text",
code: false,
copyable: false,
delete: false,
disabled: false,
ellipsis: false,
keyboard: false,
mark: false,
italic: false,
underline: false,
strong: false
}}
controls={[
{
name: "children",
label: "Children",
type: "text",
description: "The text content."
},
{
name: "code",
label: "Code",
type: "boolean",
description: "Code style."
},
{
name: "copyable",
label: "Copyable",
type: "boolean",
description: "Whether the text is copyable."
},
{
name: "delete",
label: "Delete",
type: "boolean",
description: "Deleted line style."
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Disabled content."
},
{
name: "ellipsis",
label: "Ellipsis",
type: "boolean",
description: "Display ellipsis when text overflows."
},
{
name: "keyboard",
label: "Keyboard",
type: "boolean",
description: "Keyboard style."
},
{
name: "mark",
label: "Mark",
type: "boolean",
description: "Marked/highlighted style."
},
{
name: "italic",
label: "Italic",
type: "boolean",
description: "Italic style."
},
{
name: "underline",
label: "Underline",
type: "boolean",
description: "Underlined style."
},
{
name: "strong",
label: "Strong",
type: "boolean",
description: "Bold style."
},
{
name: "type",
label: "Type",
type: "select",
options: [
"secondary",
"success",
"warning",
"danger"
],
description: "Text type for semantic coloring."
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<div>
<Typography.Text>Default Text</Typography.Text>
<br />
<Typography.Text type="secondary">Secondary</Typography.Text>
<br />
<Typography.Text type="success">Success</Typography.Text>
<br />
<Typography.Text type="warning">Warning</Typography.Text>
<br />
<Typography.Text type="danger">Danger</Typography.Text>
<br />
<Typography.Text code>Code</Typography.Text>
<br />
<Typography.Text keyboard>Keyboard</Typography.Text>
<br />
<Typography.Text mark>Marked</Typography.Text>
<br />
<Typography.Text underline>Underline</Typography.Text>
<br />
<Typography.Text delete>Deleted</Typography.Text>
<br />
<Typography.Text strong>Strong</Typography.Text>
<br />
<Typography.Text italic>Italic</Typography.Text>
</div>
);
}
```
## All Subcomponents
```tsx live
function AllSubcomponents() {
return (
<div>
<Typography.Title level={2}>Typography Components</Typography.Title>
<Typography.Paragraph>
The Typography component includes several subcomponents for different text needs.
Use <Typography.Text strong>Title</Typography.Text> for headings,
<Typography.Text code>Text</Typography.Text> for inline text styling,
and <Typography.Text mark>Paragraph</Typography.Text> for block content.
</Typography.Paragraph>
<Typography.Link href="https://superset.apache.org" target="_blank">
Learn more about Apache Superset
</Typography.Link>
</div>
);
}
```
## Text Styling Options
```tsx live
function TextStyles() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
<Typography.Text code>Code style</Typography.Text>
<Typography.Text keyboard>Keyboard style</Typography.Text>
<Typography.Text mark>Highlighted text</Typography.Text>
<Typography.Text underline>Underlined text</Typography.Text>
<Typography.Text delete>Deleted text</Typography.Text>
<Typography.Text strong>Bold text</Typography.Text>
<Typography.Text italic>Italic text</Typography.Text>
<Typography.Text type="success">Success type</Typography.Text>
<Typography.Text type="warning">Warning type</Typography.Text>
<Typography.Text type="danger">Danger type</Typography.Text>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `string` | `"Sample Text"` | The text content. |
| `code` | `boolean` | `false` | Code style. |
| `copyable` | `boolean` | `false` | Whether the text is copyable. |
| `delete` | `boolean` | `false` | Deleted line style. |
| `disabled` | `boolean` | `false` | Disabled content. |
| `ellipsis` | `boolean` | `false` | Display ellipsis when text overflows. |
| `keyboard` | `boolean` | `false` | Keyboard style. |
| `mark` | `boolean` | `false` | Marked/highlighted style. |
| `italic` | `boolean` | `false` | Italic style. |
| `underline` | `boolean` | `false` | Underlined style. |
| `strong` | `boolean` | `false` | Bold style. |
## Import
```tsx
import { Typography } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Typography/Typography.stories.tsx).
:::

View File

@@ -1,126 +0,0 @@
---
title: UnsavedChangesModal
sidebar_label: UnsavedChangesModal
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# UnsavedChangesModal
The UnsavedChangesModal component from Superset's UI library.
## Live Example
<StoryWithControls
component="UnsavedChangesModal"
props={{
showModal: false,
title: "Unsaved Changes"
}}
controls={[
{
name: "showModal",
label: "Show Modal",
type: "boolean",
description: "Whether the modal is visible."
},
{
name: "title",
label: "Title",
type: "text",
description: "Title text displayed in the modal header."
}
]}
triggerProp="showModal"
onHideProp="onHide,handleSave,onConfirmNavigation"
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
const [show, setShow] = React.useState(false);
return (
<div>
<Button onClick={() => setShow(true)}>
Navigate Away (Unsaved Changes)
</Button>
<UnsavedChangesModal
showModal={show}
onHide={() => setShow(false)}
handleSave={() => { alert('Saved!'); setShow(false); }}
onConfirmNavigation={() => { alert('Discarded changes'); setShow(false); }}
title="Unsaved Changes"
>
If you don&apos;t save, changes will be lost.
</UnsavedChangesModal>
</div>
);
}
```
## Custom Title
```tsx live
function CustomTitle() {
const [show, setShow] = React.useState(false);
return (
<div>
<Button onClick={() => setShow(true)}>
Close Without Saving
</Button>
<UnsavedChangesModal
showModal={show}
onHide={() => setShow(false)}
handleSave={() => setShow(false)}
onConfirmNavigation={() => setShow(false)}
title="You have unsaved dashboard changes"
>
Your dashboard layout and filter changes have not been saved.
Do you want to save before leaving?
</UnsavedChangesModal>
</div>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `showModal` | `boolean` | `false` | Whether the modal is visible. |
| `title` | `string` | `"Unsaved Changes"` | Title text displayed in the modal header. |
## Import
```tsx
import { UnsavedChangesModal } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/UnsavedChangesModal/UnsavedChangesModal.stories.tsx).
:::

View File

@@ -1,136 +0,0 @@
---
title: Upload
sidebar_label: Upload
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
# Upload
Upload component for file selection and uploading. Supports drag-and-drop, multiple files, and different list display styles.
## Live Example
<StoryWithControls
component="Upload"
props={{
multiple: false,
disabled: false,
listType: "text",
showUploadList: true
}}
controls={[
{
name: "multiple",
label: "Multiple",
type: "boolean",
description: "Support multiple file selection."
},
{
name: "disabled",
label: "Disabled",
type: "boolean",
description: "Disable the upload button."
},
{
name: "listType",
label: "List Type",
type: "select",
options: [
"text",
"picture",
"picture-card",
"picture-circle"
],
description: "Built-in style for the file list display."
},
{
name: "showUploadList",
label: "Show Upload List",
type: "boolean",
description: "Whether to show the upload file list."
}
]}
sampleChildren={[{"component":"Button","props":{"children":"Click to Upload"}}]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Upload>
<Button>Click to Upload</Button>
</Upload>
);
}
```
## Picture Card Style
```tsx live
function PictureCard() {
return (
<Upload listType="picture-card">
+ Upload
</Upload>
);
}
```
## Drag and Drop
```tsx live
function DragDrop() {
return (
<Upload.Dragger>
<p style={{ fontSize: 48, color: '#999', margin: 0 }}>+</p>
<p>Click or drag file to this area to upload</p>
<p style={{ color: '#999' }}>Support for single or bulk upload.</p>
</Upload.Dragger>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `multiple` | `boolean` | `false` | Support multiple file selection. |
| `disabled` | `boolean` | `false` | Disable the upload button. |
| `listType` | `string` | `"text"` | Built-in style for the file list display. |
| `showUploadList` | `boolean` | `true` | Whether to show the upload file list. |
## Import
```tsx
import { Upload } from '@superset/components';
```
---
:::tip[Improve this page]
This documentation is auto-generated from the component's Storybook story.
Help improve it by [editing the story file](https://github.com/apache/superset/edit/master/superset-frontend/packages/superset-ui-core/src/components/Upload/Upload.stories.tsx).
:::

View File

@@ -1,131 +0,0 @@
---
title: Alert
sidebar_label: Alert
---
<!--
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 { StoryWithControls } from '../../../src/components/StorybookWrapper';
import { Alert } from '@apache-superset/core/components';
# Alert
Alert component for displaying important messages to users. Wraps Ant Design Alert with sensible defaults and improved accessibility.
## Live Example
<StoryWithControls
component={Alert}
props={{
closable: true,
type: 'info',
message: 'This is a sample alert message.',
description: 'Sample description for additional context.',
showIcon: true
}}
controls={[
{
name: 'type',
label: 'Type',
type: 'select',
options: [
'info',
'error',
'warning',
'success'
]
},
{
name: 'closable',
label: 'Closable',
type: 'boolean'
},
{
name: 'showIcon',
label: 'Show Icon',
type: 'boolean'
},
{
name: 'message',
label: 'Message',
type: 'text'
},
{
name: 'description',
label: 'Description',
type: 'text'
}
]}
/>
## Try It
Edit the code below to experiment with the component:
```tsx live
function Demo() {
return (
<Alert
closable
type="info"
message="This is a sample alert message."
description="Sample description for additional context."
showIcon
/>
);
}
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `closable` | `boolean` | `true` | Whether the Alert can be closed with a close button. |
| `type` | `string` | `"info"` | Type of the alert (e.g., info, error, warning, success). |
| `message` | `string` | `"This is a sample alert message."` | Message |
| `description` | `string` | `"Sample description for additional context."` | Description |
| `showIcon` | `boolean` | `true` | Whether to display an icon in the Alert. |
## Usage in Extensions
This component is available in the `@apache-superset/core/components` package, which is automatically available to Superset extensions.
```tsx
import { Alert } from '@apache-superset/core/components';
function MyExtension() {
return (
<Alert
closable
type="info"
message="This is a sample alert message."
/>
);
}
```
## Source Links
- [Story file](https://github.com/apache/superset/blob/master/superset-frontend/packages/superset-core/src/ui/components/Alert/Alert.stories.tsx)
- [Component source](https://github.com/apache/superset/blob/master/superset-frontend/packages/superset-core/src/ui/components/Alert/index.tsx)
---
*This page was auto-generated from the component's Storybook story.*

View File

@@ -1,93 +0,0 @@
---
title: Extension Components
sidebar_label: Overview
sidebar_position: 1
---
<!--
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.
-->
# Extension Components
These UI components are available to Superset extension developers through the `@apache-superset/core/components` package. They provide a consistent look and feel with the rest of Superset and are designed to be used in extension panels, views, and other UI elements.
## Available Components
- [Alert](./alert)
## Usage
All components are exported from the `@apache-superset/core/components` package:
```tsx
import { Alert } from '@apache-superset/core/components';
export function MyExtensionPanel() {
return (
<Alert type="info">
Welcome to my extension!
</Alert>
);
}
```
## Adding New Components
Components in `@apache-superset/core/components` are automatically documented here. To add a new extension component:
1. Add the component to `superset-frontend/packages/superset-core/src/ui/components/`
2. Export it from `superset-frontend/packages/superset-core/src/ui/components/index.ts`
3. Create a Storybook story with an `Interactive` export:
```tsx
export default {
title: 'Extension Components/MyComponent',
component: MyComponent,
parameters: {
docs: {
description: {
component: 'Description of the component...',
},
},
},
};
export const InteractiveMyComponent = (args) => <MyComponent {...args} />;
InteractiveMyComponent.args = {
variant: 'primary',
disabled: false,
};
InteractiveMyComponent.argTypes = {
variant: {
control: { type: 'select' },
options: ['primary', 'secondary'],
},
disabled: {
control: { type: 'boolean' },
},
};
```
4. Run `yarn start` in `docs/` - the page generates automatically!
## Interactive Documentation
For interactive examples with controls, visit the [Storybook](/storybook/?path=/docs/extension-components--docs).

View File

@@ -1,275 +0,0 @@
---
title: Contribution Types
sidebar_position: 5
---
<!--
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.
-->
# Contribution Types
To facilitate the development of extensions, we define a set of well-defined contribution types that extensions can implement. These contribution types serve as the building blocks for extensions, allowing them to interact with the host application and provide new functionality.
## Frontend
Frontend contribution types allow extensions to extend Superset's user interface with new views, commands, and menu items. Frontend contributions are registered directly in code from your extension's `index.tsx` entry point.
### Views
Extensions can add new views or panels to the host application, such as custom SQL Lab panels, dashboards, or other UI components. Contribution areas are uniquely identified (e.g., `sqllab.panels` for SQL Lab panels), enabling seamless integration into specific parts of the application.
```tsx
import React from 'react';
import { views } from '@apache-superset/core';
import MyPanel from './MyPanel';
views.registerView(
{ id: 'my-extension.main', name: 'My Panel Name' },
'sqllab.panels',
() => <MyPanel />,
);
```
### Commands
Extensions can define custom commands that can be executed within the host application, such as context-aware actions or menu options. Each command specifies a unique identifier, a title, an optional icon, and a description. Commands can be invoked by users through menus, keyboard shortcuts, or other UI elements.
```typescript
import { commands } from '@apache-superset/core';
commands.registerCommand(
{
id: 'my-extension.copy-query',
title: 'Copy Query',
icon: 'CopyOutlined',
description: 'Copy the current query to clipboard',
},
() => {
// Command implementation
},
);
```
### Menus
Extensions can contribute new menu items or context menus to the host application, providing users with additional actions and options. Each menu item specifies the view and command to execute, the target area, and the location (`primary`, `secondary`, or `context`). Menu contribution areas are uniquely identified (e.g., `sqllab.editor` for the SQL Lab editor).
```typescript
import { menus } from '@apache-superset/core';
menus.registerMenuItem(
{ view: 'sqllab.editor', command: 'my-extension.copy-query' },
'sqllab.editor',
'primary',
);
menus.registerMenuItem(
{ view: 'sqllab.editor', command: 'my-extension.prettify' },
'sqllab.editor',
'secondary',
);
menus.registerMenuItem(
{ view: 'sqllab.editor', command: 'my-extension.clear' },
'sqllab.editor',
'context',
);
```
### Editors
Extensions can replace Superset's default text editors with custom implementations. This enables enhanced editing experiences using alternative editor frameworks like Monaco, CodeMirror, or custom solutions. When an extension registers an editor for a language, it replaces the default editor in all locations that use that language (SQL Lab, Dashboard Properties, CSS editors, etc.).
```typescript
import { editors } from '@apache-superset/core';
import MonacoSQLEditor from './MonacoSQLEditor';
editors.registerEditor(
{
id: 'my-extension.monaco-sql',
name: 'Monaco SQL Editor',
languages: ['sql'],
},
MonacoSQLEditor,
);
```
See [Editors Extension Point](./extension-points/editors) for implementation details.
## Backend
Backend contribution types allow extensions to extend Superset's server-side capabilities. Backend contributions are registered at startup via classes and functions imported from the auto-discovered `entrypoint.py` file.
### REST API Endpoints
Extensions can register custom REST API endpoints under the `/extensions/` namespace. This dedicated namespace prevents conflicts with built-in endpoints and provides a clear separation between core and extension functionality.
```python
from flask import Response
from flask_appbuilder.api import expose, permission_name, protect, safe
from superset_core.rest_api.api import RestApi
from superset_core.rest_api.decorators import api
@api(
id="my_extension_api",
name="My Extension API",
description="Custom API endpoints for my extension",
)
class MyExtensionAPI(RestApi):
openapi_spec_tag = "My Extension"
class_permission_name = "my_extension_api"
@expose("/hello", methods=("GET",))
@protect()
@safe
@permission_name("read")
def hello(self) -> Response:
return self.response(200, result={"message": "Hello from extension!"})
# Import the class in entrypoint.py to register it
from .api import MyExtensionAPI
```
**Note**: The [`@api`](superset-core/src/superset_core/rest_api/decorators.py) decorator automatically detects context and generates appropriate paths:
- **Extension context**: `/extensions/{publisher}/{name}/` with ID prefixed as `extensions.{publisher}.{name}.{id}`
- **Host context**: `/api/v1/` with original ID
For an extension with publisher `my-org` and name `dataset-tools`, the endpoint above would be accessible at:
```
/extensions/my-org/dataset-tools/hello
```
You can also specify a `resource_name` parameter to add an additional path segment:
```python
@api(
id="analytics_api",
name="Analytics API",
resource_name="analytics", # Adds /analytics to the path
)
class AnalyticsAPI(RestApi):
@expose("/insights", methods=("GET",))
@protect()
@safe
@permission_name("read")
def insights(self) -> Response:
# This endpoint will be available at:
# /extensions/my-org/dataset-tools/analytics/insights
return self.response(200, result={"insights": []})
```
### MCP Tools
Extensions can register Python functions as MCP tools that AI agents can discover and call. Tools provide executable functionality such as data processing, custom analytics, or integration with external services. Each tool specifies a unique name and an optional description that helps AI agents decide when to use it.
```python
from superset_core.mcp.decorators import tool
@tool(
name="my-extension.get_summary",
description="Get a summary of recent query activity",
tags=["analytics", "queries"],
)
def get_summary() -> dict:
"""Returns a summary of recent query activity."""
return {"status": "success", "result": {"queries_today": 42}}
```
See [MCP Integration](./mcp) for implementation details.
### MCP Prompts
Extensions can register MCP prompts that provide interactive guidance and context to AI agents. Prompts help agents understand domain-specific workflows, best practices, or troubleshooting steps for your extension's use cases.
```python
from superset_core.mcp.decorators import prompt
from fastmcp import Context
@prompt(
"my-extension.analysis_guide",
title="Analysis Guide",
description="Step-by-step guidance for data analysis workflows",
)
async def analysis_guide(ctx: Context) -> str:
"""Provides guidance for data analysis workflows."""
return """
# Data Analysis Guide
Follow these steps for effective analysis:
1. **Explore your data** - Review available datasets and schema
2. **Build your query** - Use SQL Lab to craft and test queries
3. **Visualize results** - Choose the right chart type for your data
What would you like to analyze today?
"""
```
See [MCP Integration](./mcp) for implementation details.
### Semantic Layers
Extensions can register custom semantic layer implementations that allow Superset to connect to external data modeling frameworks. Each semantic layer defines how to authenticate, discover semantic views (tables/metrics/dimensions), and execute queries against the external system.
```python
from superset_core.semantic_layers.decorators import semantic_layer
from superset_core.semantic_layers.layer import SemanticLayer
from my_extension.config import MyConfig
from my_extension.view import MySemanticView
@semantic_layer(
id="my_platform",
name="My Data Platform",
description="Connect to My Data Platform's semantic layer",
)
class MySemanticLayer(SemanticLayer[MyConfig, MySemanticView]):
configuration_class = MyConfig
@classmethod
def from_configuration(cls, configuration: dict) -> "MySemanticLayer":
config = MyConfig.model_validate(configuration)
return cls(config)
@classmethod
def get_configuration_schema(cls, configuration=None) -> dict:
return MyConfig.model_json_schema()
@classmethod
def get_runtime_schema(cls, configuration=None, runtime_data=None) -> dict:
return {"type": "object", "properties": {}}
def get_semantic_views(self, runtime_configuration: dict) -> set[MySemanticView]:
# Return available views from the external platform
...
def get_semantic_view(self, name: str, additional_configuration: dict) -> MySemanticView:
# Return a specific view by name
...
```
**Note**: The `@semantic_layer` decorator automatically detects context and applies appropriate ID prefixing:
- **Extension context**: ID prefixed as `extensions.{publisher}.{name}.{id}`
- **Host context**: Original ID used as-is
The decorator registers the class in the semantic layers registry, making it available in the UI for users to create connections. The `configuration_class` should be a Pydantic model that defines the fields needed to connect (credentials, project, database, etc.). Superset uses the model's JSON schema to render the configuration form dynamically.

View File

@@ -1,679 +0,0 @@
---
title: MCP Server Deployment & Authentication
hide_title: true
sidebar_position: 9
version: 1
---
<!--
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.
-->
# MCP Server Deployment & Authentication
Superset includes a built-in [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that lets AI assistants -- Claude, ChatGPT, and other MCP-compatible clients -- interact with your Superset instance. Through MCP, clients can list dashboards, query datasets, execute SQL, create charts, and more.
This guide covers how to run, secure, and deploy the MCP server.
```mermaid
flowchart LR
A["AI Client<br/>(Claude, ChatGPT, etc.)"] -- "MCP protocol<br/>(HTTP + JSON-RPC)" --> B["MCP Server<br/>(:5008/mcp)"]
B -- "Superset context<br/>(app, db, RBAC)" --> C["Superset<br/>(:8088)"]
C --> D[("Database<br/>(Postgres)")]
```
---
## Quick Start
Get the MCP server running locally and connect an AI client in three steps.
### 1. Start the MCP server
The MCP server runs as a separate process alongside Superset:
```bash
superset mcp run --host 127.0.0.1 --port 5008
```
| Flag | Default | Description |
|------|---------|-------------|
| `--host` | `127.0.0.1` | Host to bind to |
| `--port` | `5008` | Port to bind to |
| `--debug` | off | Enable debug logging |
The endpoint is available at `http://<host>:<port>/mcp`.
### 2. Set a development user
For local development, tell the MCP server which Superset user to impersonate (the user must already exist in your database):
```python
# superset_config.py
MCP_DEV_USERNAME = "admin"
```
### 3. Connect an AI client
Point your MCP client at the server. For **Claude Desktop**, edit the config file:
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"superset": {
"url": "http://localhost:5008/mcp"
}
}
}
```
Restart Claude Desktop. The hammer icon in the chat bar confirms the connection.
See [Connecting AI Clients](#connecting-ai-clients) for Claude Code, Claude Web, ChatGPT, and raw HTTP examples.
---
## Prerequisites
- Apache Superset 5.0+ running and accessible
- Python 3.10+
- The `fastmcp` package (`pip install fastmcp`)
---
## Authentication
The MCP server supports multiple authentication methods depending on your deployment scenario.
```mermaid
flowchart TD
R["Incoming MCP Request"] --> F{"MCP_AUTH_FACTORY<br/>set?"}
F -- Yes --> CF["Custom Auth Provider"]
F -- No --> AE{"MCP_AUTH_ENABLED?"}
AE -- "True" --> JWT["JWT Validation"]
AE -- "False" --> DU["Dev Mode<br/>(MCP_DEV_USERNAME)"]
JWT --> ALG{"MCP_JWT_ALGORITHM"}
ALG -- "RS256 + JWKS" --> JWKS["Fetch keys from<br/>MCP_JWKS_URI"]
ALG -- "RS256 + static" --> PK["Use<br/>MCP_JWT_PUBLIC_KEY"]
ALG -- "HS256" --> SEC["Use<br/>MCP_JWT_SECRET"]
JWKS --> V["Validate token<br/>(exp, iss, aud, scopes)"]
PK --> V
SEC --> V
V --> UR["Resolve Superset user<br/>from token claims"]
UR --> OK["Authenticated request"]
CF --> OK
DU --> OK
```
### Development Mode (No Auth)
Disable authentication and use a fixed user:
```python
# superset_config.py
MCP_AUTH_ENABLED = False
MCP_DEV_USERNAME = "admin"
```
All operations run as the configured user.
:::warning
Never use development mode in production. Always enable authentication for any internet-facing deployment.
:::
### JWT Authentication
For production, enable JWT-based authentication. The MCP server validates a Bearer token on every request.
#### Option A: RS256 with JWKS endpoint
The most common setup for OAuth 2.0 / OIDC providers that publish a JWKS (JSON Web Key Set) endpoint:
```python
# superset_config.py
MCP_AUTH_ENABLED = True
MCP_JWT_ALGORITHM = "RS256"
MCP_JWKS_URI = "https://your-identity-provider.com/.well-known/jwks.json"
MCP_JWT_ISSUER = "https://your-identity-provider.com/"
MCP_JWT_AUDIENCE = "your-superset-instance"
```
#### Option B: RS256 with static public key
Use this when you have a fixed RSA key pair (e.g., self-signed tokens):
```python
# superset_config.py
MCP_AUTH_ENABLED = True
MCP_JWT_ALGORITHM = "RS256"
MCP_JWT_PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----"""
MCP_JWT_ISSUER = "your-issuer"
MCP_JWT_AUDIENCE = "your-audience"
```
#### Option C: HS256 with shared secret
Use this when both the token issuer and the MCP server share a symmetric secret:
```python
# superset_config.py
MCP_AUTH_ENABLED = True
MCP_JWT_ALGORITHM = "HS256"
MCP_JWT_SECRET = "your-shared-secret-key"
MCP_JWT_ISSUER = "your-issuer"
MCP_JWT_AUDIENCE = "your-audience"
```
:::warning
Store `MCP_JWT_SECRET` securely. Never commit it to version control. Use environment variables:
```python
import os
MCP_JWT_SECRET = os.environ.get("MCP_JWT_SECRET")
```
:::
#### JWT claims
The MCP server validates these standard claims:
| Claim | Config Key | Description |
|-------|-----------|-------------|
| `exp` | -- | Expiration time (always validated) |
| `iss` | `MCP_JWT_ISSUER` | Token issuer (optional but recommended) |
| `aud` | `MCP_JWT_AUDIENCE` | Token audience (optional but recommended) |
| `sub` | -- | Subject -- primary claim used to resolve the Superset user |
#### User resolution
After validating the token, the MCP server resolves a Superset username from the claims. It checks these in order, using the first non-empty value:
1. `subject` -- the standard `sub` claim (via the access token object)
2. `client_id` -- for machine-to-machine tokens
3. `payload["sub"]` -- fallback to raw payload
4. `payload["email"]` -- email-based lookup
5. `payload["username"]` -- explicit username claim
The resolved value must match a `username` in the Superset `ab_user` table.
#### Scoped access
Require specific scopes in the JWT to limit what MCP operations a token can perform:
```python
# superset_config.py
MCP_REQUIRED_SCOPES = ["mcp:read", "mcp:write"]
```
Only tokens that include **all** required scopes are accepted.
### Custom Auth Provider
For advanced scenarios (e.g., a proprietary auth system), provide a factory function. This takes precedence over all built-in JWT configuration:
```python
# superset_config.py
def my_custom_auth_factory(app):
"""Return a FastMCP auth provider instance."""
from fastmcp.server.auth.providers.jwt import JWTVerifier
return JWTVerifier(
jwks_uri="https://my-auth.example.com/.well-known/jwks.json",
issuer="https://my-auth.example.com/",
audience="superset-mcp",
)
MCP_AUTH_FACTORY = my_custom_auth_factory
```
---
## Connecting AI Clients
### Claude Desktop
**Local development (no auth):**
```json
{
"mcpServers": {
"superset": {
"url": "http://localhost:5008/mcp"
}
}
}
```
**With JWT authentication:**
```json
{
"mcpServers": {
"superset": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"http://your-superset-host:5008/mcp",
"--header",
"Authorization: Bearer YOUR_TOKEN"
]
}
}
}
```
### Claude Code (CLI)
Add to your project's `.mcp.json`:
```json
{
"mcpServers": {
"superset": {
"type": "url",
"url": "http://localhost:5008/mcp"
}
}
}
```
With authentication:
```json
{
"mcpServers": {
"superset": {
"type": "url",
"url": "http://localhost:5008/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
```
### Claude Web (claude.ai)
1. Open [claude.ai](https://claude.ai)
2. Click the **+** button (or your profile icon)
3. Select **Connectors**
4. Click **Manage Connectors** > **Add custom connector**
5. Enter a name and your MCP URL (e.g., `https://your-superset-host/mcp`)
6. Click **Add**
:::info
Custom connectors on Claude Web require a Pro, Max, Team, or Enterprise plan.
:::
### ChatGPT
1. Click your profile icon > **Settings** > **Apps and Connectors**
2. Enable **Developer Mode** in Advanced Settings
3. In the chat composer, press **+** > **Add sources** > **App** > **Connect more** > **Create app**
4. Enter a name and your MCP server URL
5. Click **I understand and continue**
:::info
ChatGPT MCP connectors require a Pro, Team, Enterprise, or Edu plan.
:::
### Direct HTTP requests
Call the MCP server directly with any HTTP client:
```bash
curl -X POST http://localhost:5008/mcp \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
```
---
## Deployment
### Single Process
The simplest setup: run the MCP server alongside Superset on the same host.
```mermaid
flowchart TD
subgraph host["Host / VM"]
direction TB
S["Superset<br/>:8088"] --> DB[("Postgres")]
M["MCP Server<br/>:5008"] --> DB
end
C["AI Client"] -- "HTTPS" --> P["Reverse Proxy<br/>(Nginx / Caddy)"]
U["Browser"] -- "HTTPS" --> P
P -- ":8088" --> S
P -- ":5008/mcp" --> M
```
**superset_config.py:**
```python
MCP_SERVICE_HOST = "0.0.0.0"
MCP_SERVICE_PORT = 5008
MCP_DEV_USERNAME = "admin" # or enable JWT auth
# If behind a reverse proxy, set the public-facing URL so
# MCP-generated links (chart previews, SQL Lab URLs) resolve correctly:
MCP_SERVICE_URL = "https://superset.example.com"
```
**Start both processes:**
```bash
# Terminal 1 -- Superset web server
superset run -h 0.0.0.0 -p 8088
# Terminal 2 -- MCP server
superset mcp run --host 0.0.0.0 --port 5008
```
**Nginx reverse proxy with TLS:**
```nginx
server {
listen 443 ssl;
server_name superset.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Superset web UI
location / {
proxy_pass http://127.0.0.1:8088;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# MCP endpoint
location /mcp {
proxy_pass http://127.0.0.1:5008/mcp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Authorization $http_authorization;
}
}
```
### Docker Compose
Run Superset and the MCP server as separate containers sharing the same config:
```yaml
# docker-compose.yml
services:
superset:
image: apache/superset:latest
ports:
- "8088:8088"
volumes:
- ./superset_config.py:/app/superset_config.py
environment:
- SUPERSET_CONFIG_PATH=/app/superset_config.py
mcp:
image: apache/superset:latest
command: ["superset", "mcp", "run", "--host", "0.0.0.0", "--port", "5008"]
ports:
- "5008:5008"
volumes:
- ./superset_config.py:/app/superset_config.py
environment:
- SUPERSET_CONFIG_PATH=/app/superset_config.py
depends_on:
- superset
```
Both containers share the same `superset_config.py`, so authentication settings, database connections, and feature flags stay in sync.
### Multi-Pod (Kubernetes)
For high-availability deployments, configure Redis so that replicas share session state:
```mermaid
flowchart TD
LB["Load Balancer"] --> M1["MCP Pod 1"]
LB --> M2["MCP Pod 2"]
LB --> M3["MCP Pod 3"]
M1 --> R[("Redis<br/>(session store)")]
M2 --> R
M3 --> R
M1 --> DB[("Postgres")]
M2 --> DB
M3 --> DB
```
**superset_config.py:**
```python
MCP_STORE_CONFIG = {
"enabled": True,
"CACHE_REDIS_URL": "redis://redis-host:6379/0",
"event_store_max_events": 100,
"event_store_ttl": 3600,
}
```
When `CACHE_REDIS_URL` is set, the MCP server uses a Redis-backed EventStore for session management, allowing replicas to share state. Without Redis, each pod manages its own in-memory sessions and stateful MCP interactions may fail when requests hit different replicas.
---
## Configuration Reference
All MCP settings go in `superset_config.py`. Defaults are defined in `superset/mcp_service/mcp_config.py`.
### Core
| Setting | Default | Description |
|---------|---------|-------------|
| `MCP_SERVICE_HOST` | `"localhost"` | Host the MCP server binds to |
| `MCP_SERVICE_PORT` | `5008` | Port the MCP server binds to |
| `MCP_SERVICE_URL` | `None` | Public base URL for MCP-generated links (set this when behind a reverse proxy) |
| `MCP_DEBUG` | `False` | Enable debug logging |
| `MCP_DEV_USERNAME` | -- | Superset username for development mode (no auth) |
### Authentication
| Setting | Default | Description |
|---------|---------|-------------|
| `MCP_AUTH_ENABLED` | `False` | Enable JWT authentication |
| `MCP_JWT_ALGORITHM` | `"RS256"` | JWT signing algorithm (`RS256` or `HS256`) |
| `MCP_JWKS_URI` | `None` | JWKS endpoint URL (RS256) |
| `MCP_JWT_PUBLIC_KEY` | `None` | Static RSA public key string (RS256) |
| `MCP_JWT_SECRET` | `None` | Shared secret string (HS256) |
| `MCP_JWT_ISSUER` | `None` | Expected `iss` claim |
| `MCP_JWT_AUDIENCE` | `None` | Expected `aud` claim |
| `MCP_REQUIRED_SCOPES` | `[]` | Required JWT scopes |
| `MCP_JWT_DEBUG_ERRORS` | `False` | Log detailed JWT errors server-side (never exposed in HTTP responses per RFC 6750) |
| `MCP_AUTH_FACTORY` | `None` | Custom auth provider factory `(flask_app) -> auth_provider`. Takes precedence over built-in JWT |
### Response Size Guard
Limits response sizes to prevent exceeding LLM context windows:
```python
MCP_RESPONSE_SIZE_CONFIG = {
"enabled": True,
"token_limit": 25000,
"warn_threshold_pct": 80,
"excluded_tools": [
"health_check",
"get_chart_preview",
"generate_explore_link",
"open_sql_lab_with_context",
],
}
```
| Key | Default | Description |
|-----|---------|-------------|
| `enabled` | `True` | Enable response size checking |
| `token_limit` | `25000` | Maximum estimated token count per response |
| `warn_threshold_pct` | `80` | Warn when response exceeds this percentage of the limit |
| `excluded_tools` | See above | Tools exempt from size checking (e.g., tools that return URLs, not data) |
### Caching
Optional response caching for read-heavy workloads. Requires Redis when used with multiple replicas.
```python
MCP_CACHE_CONFIG = {
"enabled": False,
"CACHE_KEY_PREFIX": None,
"list_tools_ttl": 300, # 5 min
"list_resources_ttl": 300,
"list_prompts_ttl": 300,
"read_resource_ttl": 3600, # 1 hour
"get_prompt_ttl": 3600,
"call_tool_ttl": 3600,
"max_item_size": 1048576, # 1 MB
"excluded_tools": [
"execute_sql",
"generate_dashboard",
"generate_chart",
"update_chart",
],
}
```
| Key | Default | Description |
|-----|---------|-------------|
| `enabled` | `False` | Enable response caching |
| `CACHE_KEY_PREFIX` | `None` | Optional prefix for cache keys (useful for shared Redis) |
| `list_tools_ttl` | `300` | Cache TTL in seconds for `tools/list` |
| `list_resources_ttl` | `300` | Cache TTL for `resources/list` |
| `list_prompts_ttl` | `300` | Cache TTL for `prompts/list` |
| `read_resource_ttl` | `3600` | Cache TTL for `resources/read` |
| `get_prompt_ttl` | `3600` | Cache TTL for `prompts/get` |
| `call_tool_ttl` | `3600` | Cache TTL for `tools/call` |
| `max_item_size` | `1048576` | Maximum cached item size in bytes (1 MB) |
| `excluded_tools` | See above | Tools that are never cached (mutating or non-deterministic) |
### Redis Store (Multi-Pod)
Enables Redis-backed session and event storage for multi-replica deployments:
```python
MCP_STORE_CONFIG = {
"enabled": False,
"CACHE_REDIS_URL": None,
"event_store_max_events": 100,
"event_store_ttl": 3600,
}
```
| Key | Default | Description |
|-----|---------|-------------|
| `enabled` | `False` | Enable Redis-backed store |
| `CACHE_REDIS_URL` | `None` | Redis connection URL (e.g., `redis://redis-host:6379/0`) |
| `event_store_max_events` | `100` | Maximum events retained per session |
| `event_store_ttl` | `3600` | Event TTL in seconds |
### Session & CSRF
These values are flat-merged into the Flask app config used by the MCP server process:
```python
MCP_SESSION_CONFIG = {
"SESSION_COOKIE_HTTPONLY": True,
"SESSION_COOKIE_SECURE": False,
"SESSION_COOKIE_SAMESITE": "Lax",
"SESSION_COOKIE_NAME": "superset_session",
"PERMANENT_SESSION_LIFETIME": 86400,
}
MCP_CSRF_CONFIG = {
"WTF_CSRF_ENABLED": True,
"WTF_CSRF_TIME_LIMIT": None,
}
```
---
## Troubleshooting
### Server won't start
- Verify `fastmcp` is installed: `pip install fastmcp`
- Check that `MCP_DEV_USERNAME` is set if auth is disabled -- the server requires a user identity
- Confirm the port is not already in use: `lsof -i :5008`
### 401 Unauthorized
- Verify your JWT token has not expired (`exp` claim)
- Check that `MCP_JWT_ISSUER` and `MCP_JWT_AUDIENCE` match the token's `iss` and `aud` claims exactly
- For RS256 with JWKS: confirm the JWKS URI is reachable from the MCP server
- For RS256 with static key: confirm the public key string includes the `BEGIN`/`END` markers
- For HS256: confirm the secret matches between the token issuer and `MCP_JWT_SECRET`
- Enable `MCP_JWT_DEBUG_ERRORS = True` for detailed server-side logging (errors are never leaked to the client)
### Tool not found
- Ensure the MCP server and Superset share the same `superset_config.py`
- Check server logs at startup -- tool registration errors are logged with the tool name and reason
### Client can't connect
- Verify the MCP server URL is reachable from the client machine
- For Claude Desktop: fully quit the app (not just close the window) and restart after config changes
- For remote access: ensure your firewall and reverse proxy allow traffic to the MCP port
- Confirm the URL path ends with `/mcp` (e.g., `http://localhost:5008/mcp`)
### Permission errors on tool calls
- The MCP server enforces Superset's RBAC permissions -- the authenticated user must have the required roles
- In development mode, ensure `MCP_DEV_USERNAME` maps to a user with appropriate roles (e.g., Admin)
- Check `superset/security/manager.py` for the specific permission tuples required by each tool domain (e.g., `("can_execute_sql_query", "SQLLab")`)
### Response too large
- If a tool call returns an error about exceeding token limits, the response size guard is blocking an oversized result
- Reduce `page_size` or `limit` parameters, use `select_columns` to exclude large fields, or add filters to narrow results
- To adjust the threshold, change `token_limit` in `MCP_RESPONSE_SIZE_CONFIG`
- To disable the guard entirely, set `MCP_RESPONSE_SIZE_CONFIG = {"enabled": False}`
---
## Security Best Practices
- **Use TLS** for all production MCP endpoints -- place the server behind a reverse proxy with HTTPS
- **Enable JWT authentication** for any internet-facing deployment
- **RBAC enforcement** -- The MCP server respects Superset's role-based access control. Users can only access data their roles permit
- **Secrets management** -- Store `MCP_JWT_SECRET`, database credentials, and API keys in environment variables or a secrets manager, never in config files committed to version control
- **Scoped tokens** -- Use `MCP_REQUIRED_SCOPES` to limit what operations a token can perform
- **Network isolation** -- In Kubernetes, restrict MCP pod network policies to only allow traffic from your AI client endpoints
- Review the **[Security documentation](./security)** for additional extension security guidance
---
## Next Steps
- **[MCP Integration](./mcp)** -- Build custom MCP tools and prompts via Superset extensions
- **[Security](./security)** -- Security best practices for extensions
- **[Deployment](./deployment)** -- Package and deploy Superset extensions

View File

@@ -653,7 +653,7 @@ export enum FeatureFlag {
those specified under FEATURE_FLAGS in `superset_config.py`. For example, `DEFAULT_FEATURE_FLAGS = { 'FOO': True, 'BAR': False }` in `superset/config.py` and `FEATURE_FLAGS = { 'BAR': True, 'BAZ': True }` in `superset_config.py` will result
in combined feature flags of `{ 'FOO': True, 'BAR': True, 'BAZ': True }`.
The current status of the usability of each flag (stable vs testing, etc) can be found in the [Feature Flags](/admin-docs/configuration/feature-flags) documentation.
The current status of the usability of each flag (stable vs testing, etc) can be found in the [Feature Flags](/docs/configuration/feature-flags) documentation.
## Git Hooks
@@ -1012,7 +1012,7 @@ When contributing new React components to Superset, please try to add a Story al
The topic of authoring new plugins, whether you'd like to contribute
it back or not has been well documented in the
[the documentation](/developer-docs/contributing/howtos#creating-visualization-plugins), and in [this blog post](https://preset.io/blog/building-custom-viz-plugins-in-superset-v2).
[the documentation](https://superset.apache.org/docs/contributing/creating-viz-plugins), and in [this blog post](https://preset.io/blog/building-custom-viz-plugins-in-superset-v2).
To contribute a plugin to Superset, your plugin must meet the following criteria:

View File

@@ -256,30 +256,6 @@ For debugging the Flask backend:
2. Set breakpoints and press F5 to debug
### Debugging Server App in Kubernetes Environment
To debug Flask running in a POD inside a kubernetes cluster, you'll need to make sure the pod runs as root and is granted the `SYS_PTRACE` capability. These settings should not be used in production environments.
```yaml
securityContext:
capabilities:
add: ["SYS_PTRACE"]
```
See [set capabilities for a container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container) for more details.
Once the pod is running as root and has the `SYS_PTRACE` capability it will be able to debug the Flask app.
You can follow the same instructions as in `docker compose`. Enter the pod and install the required library and packages: gdb, netstat and debugpy.
Often in a Kubernetes environment nodes are not addressable from outside the cluster. VSCode will thus be unable to remotely connect to port 5678 on a Kubernetes node. In order to do this you need to create a tunnel that port forwards 5678 to your local machine.
```bash
kubectl port-forward pod/superset-<some random id> 5678:5678
```
You can now launch your VSCode debugger with the same config as above. VSCode will connect to 127.0.0.1:5678 which is forwarded by kubectl to your remote kubernetes POD.
### Storybook
See the dedicated [Storybook documentation](../testing/storybook) for information on running Storybook locally and adding new stories.

Some files were not shown because too many files have changed in this diff Show More