diff --git a/.changeset/cool-shoes-hide.md b/.changeset/cool-shoes-hide.md new file mode 100644 index 0000000000..ef7da1597c --- /dev/null +++ b/.changeset/cool-shoes-hide.md @@ -0,0 +1,7 @@ +--- +'@backstage/ui': patch +--- + +Added RangeSlider component for selecting numeric ranges. + +**Affected components:** RangeSlider diff --git a/docs-ui/src/app/components/slider/components.tsx b/docs-ui/src/app/components/slider/components.tsx new file mode 100644 index 0000000000..55da7279c1 --- /dev/null +++ b/docs-ui/src/app/components/slider/components.tsx @@ -0,0 +1,85 @@ +'use client'; + +import { Slider } from '../../../../../packages/ui/src/components/Slider'; + +export const SingleValue = () => { + return ( + + ); +}; + +export const Default = () => { + return ( + + ); +}; + +export const WithCustomRange = () => { + return ( + + ); +}; + +export const WithFormattedValues = () => { + return ( + + ); +}; + +export const WithDescription = () => { + return ( + + ); +}; + +export const Required = () => { + return ( + + ); +}; + +export const Disabled = () => { + return ( + + ); +}; diff --git a/docs-ui/src/app/components/slider/page.mdx b/docs-ui/src/app/components/slider/page.mdx new file mode 100644 index 0000000000..c46185f9f6 --- /dev/null +++ b/docs-ui/src/app/components/slider/page.mdx @@ -0,0 +1,109 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { ReactAriaLink } from '@/components/ReactAriaLink'; +import { sliderPropDefs } from './props-definition'; +import { + snippetUsage, + singleValueSnippet, + defaultSnippet, + withCustomRangeSnippet, + withFormattedValuesSnippet, + withDescriptionSnippet, + requiredSnippet, + disabledSnippet, +} from './snippets'; +import { + SingleValue, + Default, + WithCustomRange, + WithFormattedValues, + WithDescription, + Required, + Disabled, +} from './components'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { SliderDefinition } from '../../../utils/definitions'; + +export const reactAriaUrls = { + slider: 'https://react-spectrum.adobe.com/react-aria/Slider.html', +}; + + + +} code={defaultSnippet} /> + +## Usage + + + +## API reference + + + + + +## Examples + +### Single value + +Use a single number as the default value to create a single-thumb slider. + +} + code={singleValueSnippet} +/> + +### Custom range + +Define custom minimum, maximum, and step values for specific use cases. + +} + code={withCustomRangeSnippet} +/> + +### Formatted values + +Use the `formatOptions` prop with standard Intl.NumberFormat options to customize how values are displayed. + +} + code={withFormattedValuesSnippet} +/> + +### With description + +Add helpful context with a description below the label. + +} + code={withDescriptionSnippet} +/> + +### Required + +Mark a field as required to show a "Required" indicator in the label. + +} code={requiredSnippet} /> + +### Disabled + +} code={disabledSnippet} /> + + + + diff --git a/docs-ui/src/app/components/slider/props-definition.ts b/docs-ui/src/app/components/slider/props-definition.ts new file mode 100644 index 0000000000..98bddc3bf9 --- /dev/null +++ b/docs-ui/src/app/components/slider/props-definition.ts @@ -0,0 +1,92 @@ +import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; +import type { PropDef } from '@/utils/propDefs'; + +export const sliderPropDefs: Record = { + label: { + type: 'string', + description: 'The label text for the slider.', + }, + description: { + type: 'string', + description: 'Additional description text displayed below the label.', + }, + secondaryLabel: { + type: 'string', + description: + 'Optional secondary label displayed next to the main label (e.g., "Optional").', + }, + isRequired: { + type: 'boolean', + description: + 'Whether the field is required. Displays "Required" in the label if true.', + }, + minValue: { + type: 'number', + description: 'The minimum value of the slider.', + default: '0', + }, + maxValue: { + type: 'number', + description: 'The maximum value of the slider.', + default: '100', + }, + step: { + type: 'number', + description: 'The step increment for slider values.', + default: '1', + }, + value: { + type: 'enum', + values: ['number', '[number, number]'], + description: + 'Controlled value. Use a single number for a single-thumb slider, or an array [min, max] for a range slider. Use with onChange for controlled behavior.', + }, + defaultValue: { + type: 'enum', + values: ['number', '[number, number]'], + description: + 'Initial value for uncontrolled usage. Use a single number for a single-thumb slider, or an array [min, max] for a range slider.', + default: 'minValue or [minValue, maxValue]', + }, + onChange: { + type: 'enum', + values: ['(value: number | [number, number]) => void'], + description: 'Called when the slider value changes.', + }, + onChangeEnd: { + type: 'enum', + values: ['(value: number | [number, number]) => void'], + description: + 'Called when the user stops dragging, useful for triggering actions only on final values.', + }, + formatOptions: { + type: 'object', + description: + 'Intl.NumberFormat options for formatting the displayed value (e.g., { style: "currency", currency: "USD" }).', + }, + isDisabled: { + type: 'boolean', + description: 'Prevents user interaction when true.', + }, + orientation: { + type: 'enum', + values: ['horizontal', 'vertical'], + description: 'The orientation of the slider.', + default: 'horizontal', + }, + name: { + type: 'string', + description: 'Form field name for form submission.', + }, + 'aria-label': { + type: 'string', + description: + 'Accessible label for screen readers when no visible label is provided.', + }, + 'aria-labelledby': { + type: 'string', + description: 'ID of an element that labels the slider for accessibility.', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; diff --git a/docs-ui/src/app/components/slider/snippets.ts b/docs-ui/src/app/components/slider/snippets.ts new file mode 100644 index 0000000000..02a4271bd7 --- /dev/null +++ b/docs-ui/src/app/components/slider/snippets.ts @@ -0,0 +1,67 @@ +export const snippetUsage = `import { Slider } from '@backstage/ui'; + +`; + +export const singleValueSnippet = ``; + +export const defaultSnippet = ``; + +export const withCustomRangeSnippet = ``; + +export const withFormattedValuesSnippet = ``; + +export const withDescriptionSnippet = ``; + +export const requiredSnippet = ``; + +export const disabledSnippet = ``; diff --git a/docs-ui/src/utils/data.ts b/docs-ui/src/utils/data.ts index 3431563835..c7472bc3d9 100644 --- a/docs-ui/src/utils/data.ts +++ b/docs-ui/src/utils/data.ts @@ -105,6 +105,18 @@ export const components: Page[] = [ title: 'Skeleton', slug: 'skeleton', }, + { + title: 'Slider', + slug: 'slider', + }, + { + title: 'Select', + slug: 'select', + }, + { + title: 'Skeleton', + slug: 'skeleton', + }, { title: 'Switch', slug: 'switch', diff --git a/packages/ui/report.api.md b/packages/ui/report.api.md index 0ba2d175bf..b8a0f121de 100644 --- a/packages/ui/report.api.md +++ b/packages/ui/report.api.md @@ -42,6 +42,7 @@ import { RowProps as RowProps_2 } from 'react-aria-components'; import type { SearchFieldProps as SearchFieldProps_2 } from 'react-aria-components'; import type { SelectProps as SelectProps_2 } from 'react-aria-components'; import type { SeparatorProps } from 'react-aria-components'; +import type { SliderProps as SliderProps_2 } from 'react-aria-components'; import type { SortDescriptor as SortDescriptor_2 } from 'react-stately'; import type { SubmenuTriggerProps as SubmenuTriggerProps_2 } from 'react-aria-components'; import type { SwitchProps as SwitchProps_2 } from 'react-aria-components'; @@ -1154,6 +1155,7 @@ export const FieldLabelDefinition: { readonly description: {}; readonly htmlFor: {}; readonly id: {}; + readonly descriptionId: {}; readonly className: {}; }; }; @@ -1165,6 +1167,7 @@ export type FieldLabelOwnProps = { description?: string | null; htmlFor?: string; id?: string; + descriptionId?: string; className?: string; }; @@ -2459,6 +2462,56 @@ export interface SkeletonProps extends Omit, 'children' | 'className' | 'style'>, SkeletonOwnProps {} +// @public (undocumented) +export const Slider: (( + props: SliderProps & { + ref?: React.ForwardedRef; + }, +) => JSX.Element) & { + displayName: string; +}; + +// @public +export const SliderDefinition: { + readonly styles: { + readonly [key: string]: string; + }; + readonly classNames: { + readonly root: 'bui-Slider'; + readonly header: 'bui-SliderHeader'; + readonly track: 'bui-SliderTrack'; + readonly trackFill: 'bui-SliderTrackFill'; + readonly thumb: 'bui-SliderThumb'; + readonly output: 'bui-SliderOutput'; + }; + readonly propDefs: { + readonly className: {}; + readonly label: {}; + readonly secondaryLabel: {}; + readonly description: {}; + readonly isRequired: {}; + }; +}; + +// @public (undocumented) +export interface SliderOwnProps { + // (undocumented) + className?: string; + // (undocumented) + description?: FieldLabelProps['description']; + // (undocumented) + isRequired?: boolean; + // (undocumented) + label?: FieldLabelProps['label']; + // (undocumented) + secondaryLabel?: FieldLabelProps['secondaryLabel']; +} + +// @public (undocumented) +export interface SliderProps + extends Omit, 'children' | 'className'>, + SliderOwnProps {} + // @public (undocumented) export type SortDescriptor = SortDescriptor_2; diff --git a/packages/ui/src/components/FieldLabel/FieldLabel.tsx b/packages/ui/src/components/FieldLabel/FieldLabel.tsx index 924ac29464..7656cacc5e 100644 --- a/packages/ui/src/components/FieldLabel/FieldLabel.tsx +++ b/packages/ui/src/components/FieldLabel/FieldLabel.tsx @@ -23,8 +23,15 @@ import { FieldLabelDefinition } from './definition'; export const FieldLabel = forwardRef( (props: FieldLabelProps, ref) => { const { ownProps, restProps } = useDefinition(FieldLabelDefinition, props); - const { classes, label, secondaryLabel, description, htmlFor, id } = - ownProps; + const { + classes, + label, + secondaryLabel, + description, + htmlFor, + id, + descriptionId, + } = ownProps; if (!label) return null; @@ -41,7 +48,9 @@ export const FieldLabel = forwardRef( )} {description && ( -
{description}
+
+ {description} +
)} ); diff --git a/packages/ui/src/components/FieldLabel/definition.ts b/packages/ui/src/components/FieldLabel/definition.ts index dc55c4f2af..399ea9e54d 100644 --- a/packages/ui/src/components/FieldLabel/definition.ts +++ b/packages/ui/src/components/FieldLabel/definition.ts @@ -36,6 +36,7 @@ export const FieldLabelDefinition = defineComponent()({ description: {}, htmlFor: {}, id: {}, + descriptionId: {}, className: {}, }, }); diff --git a/packages/ui/src/components/FieldLabel/types.ts b/packages/ui/src/components/FieldLabel/types.ts index f1d2857e06..ca18c6c8c1 100644 --- a/packages/ui/src/components/FieldLabel/types.ts +++ b/packages/ui/src/components/FieldLabel/types.ts @@ -41,6 +41,11 @@ export type FieldLabelOwnProps = { */ id?: string; + /** + * The id to apply to the description element for aria-describedby + */ + descriptionId?: string; + className?: string; }; diff --git a/packages/ui/src/components/Slider/Slider.module.css b/packages/ui/src/components/Slider/Slider.module.css new file mode 100644 index 0000000000..69fc8784f9 --- /dev/null +++ b/packages/ui/src/components/Slider/Slider.module.css @@ -0,0 +1,135 @@ +/* + * Copyright 2026 The Backstage Authors + * + * Licensed 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. + */ + +@layer tokens, base, components, utilities; + +@layer components { + .bui-Slider { + display: flex; + flex-direction: column; + gap: var(--bui-space-2); + width: 100%; + color: var(--bui-fg-primary); + + &[data-orientation='vertical'] { + height: 200px; + width: auto; + } + } + + .bui-SliderHeader { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: var(--bui-space-3); + } + + .bui-SliderOutput { + font-size: var(--bui-font-size-2); + font-weight: var(--bui-font-weight-medium); + color: var(--bui-fg-secondary); + white-space: nowrap; + } + + .bui-SliderTrack { + position: relative; + height: 4px; + width: 100%; + background: var(--bui-bg-neutral-3); + border-radius: var(--bui-radius-sm); + cursor: pointer; + + &[data-disabled] { + cursor: not-allowed; + } + + /* Vertical orientation */ + [data-orientation='vertical'] & { + width: 4px; + height: 100%; + } + } + + .bui-SliderTrackFill { + position: absolute; + top: 0; + height: 100%; + background: var(--bui-bg-solid); + border-radius: var(--bui-radius-sm); + pointer-events: none; + + /* Vertical orientation */ + [data-orientation='vertical'] & { + width: 100%; + height: auto; + left: 0; + right: 0; + top: auto; + } + } + + .bui-SliderThumb { + width: 20px; + height: 20px; + border-radius: 50%; + background: var(--bui-bg-solid); + border: 2px solid var(--bui-bg-solid); + box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + cursor: grab; + transition: transform 200ms; + + /* Fix: Ensure thumb is vertically centered on track */ + top: 50%; + transform: translateY(-50%); + + &[data-focus-visible] { + outline: 2px solid var(--bui-ring); + outline-offset: 2px; + } + + &[data-dragging] { + cursor: grabbing; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), + 0 2px 4px -2px rgb(0 0 0 / 0.1); + transform: translateY(-50%) scale(1.1); + } + + /* Hover effect */ + &:hover:not([data-disabled]) { + transform: translateY(-50%) scale(1.1); + } + } + + /* Improved disabled state */ + .bui-Slider[data-disabled] { + opacity: 0.6; + cursor: not-allowed; + + & .bui-SliderTrack { + background: var(--bui-bg-neutral-2); + } + + & .bui-SliderTrackFill { + background: var(--bui-bg-neutral-4); + } + + & .bui-SliderThumb { + cursor: not-allowed; + background: var(--bui-bg-neutral-4); + border-color: var(--bui-border-neutral); + } + } +} diff --git a/packages/ui/src/components/Slider/Slider.stories.tsx b/packages/ui/src/components/Slider/Slider.stories.tsx new file mode 100644 index 0000000000..7ac48b877b --- /dev/null +++ b/packages/ui/src/components/Slider/Slider.stories.tsx @@ -0,0 +1,122 @@ +/* + * Copyright 2026 The Backstage Authors + * + * Licensed 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 preview from '../../../../../.storybook/preview'; +import { Slider } from './Slider'; + +const meta = preview.meta({ + title: 'Backstage UI/Slider', + component: Slider, +}); + +export const SingleThumb = meta.story({ + args: { + label: 'Volume', + defaultValue: 50, + }, +}); + +export const SingleThumbWithRange = meta.story({ + args: { + label: 'Brightness', + minValue: 0, + maxValue: 100, + defaultValue: 75, + step: 5, + }, +}); + +export const RangeSlider = meta.story({ + args: { + label: 'Price Range', + defaultValue: [25, 75], + }, +}); + +export const WithCustomRange = meta.story({ + args: { + label: 'Temperature (°C)', + minValue: -20, + maxValue: 40, + defaultValue: [0, 20], + step: 5, + }, +}); + +export const WithFormattedValues = meta.story({ + args: { + label: 'Budget', + minValue: 0, + maxValue: 10000, + defaultValue: [2000, 8000], + step: 100, + formatOptions: { + style: 'currency', + currency: 'USD', + maximumFractionDigits: 0, + }, + }, +}); + +export const WithDescription = meta.story({ + args: { + label: 'Age Range', + description: 'Select the age range for your target audience', + minValue: 0, + maxValue: 100, + defaultValue: [18, 65], + }, +}); + +export const Required = meta.story({ + args: { + label: 'Score Range', + defaultValue: [20, 80], + isRequired: true, + }, +}); + +export const Disabled = meta.story({ + args: { + label: 'Disabled Range', + defaultValue: [30, 70], + isDisabled: true, + }, +}); + +export const WithSteps = meta.story({ + args: { + label: 'Rating', + minValue: 0, + maxValue: 5, + step: 0.5, + defaultValue: 3.5, + }, +}); + +export const Percentage = meta.story({ + args: { + label: 'Completion', + minValue: 0, + maxValue: 1, + step: 0.01, + defaultValue: 0.65, + formatOptions: { + style: 'percent', + minimumFractionDigits: 0, + maximumFractionDigits: 0, + }, + }, +}); diff --git a/packages/ui/src/components/Slider/Slider.tsx b/packages/ui/src/components/Slider/Slider.tsx new file mode 100644 index 0000000000..9aa2d73beb --- /dev/null +++ b/packages/ui/src/components/Slider/Slider.tsx @@ -0,0 +1,123 @@ +/* + * Copyright 2026 The Backstage Authors + * + * Licensed 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 { forwardRef, useEffect, useId } from 'react'; +import { + Slider as AriaSlider, + SliderTrack, + SliderThumb, + SliderOutput, +} from 'react-aria-components'; +import clsx from 'clsx'; +import { FieldLabel } from '../FieldLabel'; +import { FieldError } from '../FieldError'; +import type { SliderProps } from './types'; +import { useDefinition } from '../../hooks/useDefinition'; +import { SliderDefinition } from './definition'; + +function SliderImpl( + props: SliderProps, + ref: React.ForwardedRef, +) { + const { ownProps, restProps } = useDefinition(SliderDefinition, props); + const { classes, className, label, secondaryLabel, description, isRequired } = + ownProps; + + const labelId = useId(); + const descriptionId = useId(); + + useEffect(() => { + if (!label && !restProps['aria-label'] && !restProps['aria-labelledby']) { + console.warn( + 'Slider requires either a visible label, aria-label, or aria-labelledby for accessibility', + ); + } + }, [label, restProps]); + + const secondaryLabelText = secondaryLabel || (isRequired ? 'Required' : null); + + return ( + + {label && ( +
+ + + {({ state }) => + state.values + .map((_, i) => state.getThumbValueLabel(i)) + .join(' – ') + } + +
+ )} + + {({ state }) => { + const numThumbs = state.values.length; + + // Calculate track fill + let trackFillStyle: React.CSSProperties; + if (numThumbs === 1) { + // Single thumb: fill from start to thumb + const percent = state.getThumbPercent(0); + const isVertical = state.orientation === 'vertical'; + trackFillStyle = isVertical + ? { bottom: 0, height: `${percent * 100}%` } + : { left: 0, width: `${percent * 100}%` }; + } else { + // Range: fill between thumbs + const start = state.getThumbPercent(0); + const end = state.getThumbPercent(1); + const rangePercent = (end - start) * 100; + const isVertical = state.orientation === 'vertical'; + trackFillStyle = isVertical + ? { bottom: `${start * 100}%`, height: `${rangePercent}%` } + : { left: `${start * 100}%`, width: `${rangePercent}%` }; + } + + return ( + <> +
+ + {numThumbs > 1 && ( + + )} + + ); + }} + + + + ); +} + +/** @public */ +export const Slider = forwardRef(SliderImpl) as (( + props: SliderProps & { ref?: React.ForwardedRef }, +) => JSX.Element) & { displayName: string }; + +Slider.displayName = 'Slider'; diff --git a/packages/ui/src/components/Slider/definition.ts b/packages/ui/src/components/Slider/definition.ts new file mode 100644 index 0000000000..fdfd19939f --- /dev/null +++ b/packages/ui/src/components/Slider/definition.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2026 The Backstage Authors + * + * Licensed 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 { defineComponent } from '../../hooks/useDefinition'; +import type { SliderOwnProps } from './types'; +import styles from './Slider.module.css'; + +/** + * Component definition for Slider + * @public + */ +export const SliderDefinition = defineComponent()({ + styles, + classNames: { + root: 'bui-Slider', + header: 'bui-SliderHeader', + track: 'bui-SliderTrack', + trackFill: 'bui-SliderTrackFill', + thumb: 'bui-SliderThumb', + output: 'bui-SliderOutput', + }, + propDefs: { + className: {}, + label: {}, + secondaryLabel: {}, + description: {}, + isRequired: {}, + }, +}); diff --git a/packages/ui/src/components/Slider/index.ts b/packages/ui/src/components/Slider/index.ts new file mode 100644 index 0000000000..232f999bb1 --- /dev/null +++ b/packages/ui/src/components/Slider/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2026 The Backstage Authors + * + * Licensed 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. + */ + +export { Slider } from './Slider'; +export * from './types'; +export { SliderDefinition } from './definition'; diff --git a/packages/ui/src/components/Slider/types.ts b/packages/ui/src/components/Slider/types.ts new file mode 100644 index 0000000000..b254519fce --- /dev/null +++ b/packages/ui/src/components/Slider/types.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2026 The Backstage Authors + * + * Licensed 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 type { SliderProps as AriaSliderProps } from 'react-aria-components'; +import type { FieldLabelProps } from '../FieldLabel/types'; + +/** @public */ +export interface SliderOwnProps { + className?: string; + label?: FieldLabelProps['label']; + secondaryLabel?: FieldLabelProps['secondaryLabel']; + description?: FieldLabelProps['description']; + isRequired?: boolean; +} + +/** @public */ +export interface SliderProps + extends Omit, 'children' | 'className'>, + SliderOwnProps {} diff --git a/packages/ui/src/definitions.ts b/packages/ui/src/definitions.ts index 5aeac8de5a..d90437376e 100644 --- a/packages/ui/src/definitions.ts +++ b/packages/ui/src/definitions.ts @@ -63,6 +63,7 @@ export { export { SearchFieldDefinition } from './components/SearchField/definition'; export { SelectDefinition } from './components/Select/definition'; export { SkeletonDefinition } from './components/Skeleton/definition'; +export { SliderDefinition } from './components/Slider/definition'; export { SwitchDefinition } from './components/Switch/definition'; export { ToggleButtonDefinition } from './components/ToggleButton/definition'; export { ToggleButtonGroupDefinition } from './components/ToggleButtonGroup/definition'; diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 4cb1d323c7..abf4b4accb 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -41,6 +41,7 @@ export * from './components/ButtonIcon'; export * from './components/ButtonLink'; export * from './components/Checkbox'; export * from './components/RadioGroup'; +export * from './components/Slider'; export * from './components/Table'; export * from './components/TablePagination'; export * from './components/Tabs';