diff --git a/packages/web-components/src/components/fluid-dropdown/fluid-dropdown-skeleton.ts b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown-skeleton.ts new file mode 100644 index 000000000000..69dbc7105e3a --- /dev/null +++ b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown-skeleton.ts @@ -0,0 +1,34 @@ +/** + * Copyright IBM Corp.2025 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { prefix } from '../../globals/settings'; +import { html } from 'lit'; +import { carbonElement as customElement } from '../../globals/decorators/carbon-element'; +import styles from './fluid-dropdown.scss?lit'; +import CDSDropdownSkeleton from '../dropdown/dropdown-skeleton'; + +/** + * Fluid dropdown skeleton. + * + * @element cds-fluid-dropdown-skeleton + */ +@customElement(`${prefix}-fluid-dropdown-skeleton`) +class CDSFluidDropdownSkeleton extends CDSDropdownSkeleton { + render() { + return html` +
+
+ +
+
+
+ `; + } + static styles = styles; +} + +export default CDSFluidDropdownSkeleton; diff --git a/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.mdx b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.mdx new file mode 100644 index 000000000000..3cae5e3e8335 --- /dev/null +++ b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.mdx @@ -0,0 +1,49 @@ +import { ArgTypes, Canvas, Markdown, Meta } from '@storybook/addon-docs/blocks'; +import { cdnJs } from '../../globals/internal/storybook-cdn'; +import * as FluidDropdownStories from './fluid-dropdown.stories'; + + + +# Fluid Dropdown + +[Source code](https://github.com/carbon-design-system/carbon/tree/main/packages/web-components/src/components/fluid-dropdown) + +## Table of Contents + +- [Overview](#overview) +- [Skeleton](#skeleton) +- [With Toggletip](#with-toggletip) +- [With AI Label](#with-ai-label) +- [Component API](#component-api) +- [CDN](#cdn) +- [Feedback](#feedback) + +## Overview + + + +## Skeleton + + + +## With Toggletip + + + +## With AI Label + + + +## Component API + +## `cds-fluid-dropdown` + + + +{`${cdnJs({ components: ['fluid-dropdown'] })}`} + +## Feedback + +Help us improve this component by providing feedback, asking questions on Slack, +or updating this file on +[GitHub](https://github.com/carbon-design-system/carbon/edit/main/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.mdx). \ No newline at end of file diff --git a/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.scss b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.scss new file mode 100644 index 000000000000..db0a7dcb6d3d --- /dev/null +++ b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.scss @@ -0,0 +1,34 @@ +/** + * Copyright IBM Corp.2025 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +$css--plex: true !default; +@use '@carbon/styles/scss/config' as *; +@use '@carbon/styles/scss/components/fluid-dropdown/index'; +@use '@carbon/styles/scss/components/list-box'; +@use '@carbon/styles/scss/layout' as *; +@use '@carbon/styles/scss/spacing' as *; +@use '@carbon/styles/scss/theme'; +@use '@carbon/styles/scss/type' as *; +@use '@carbon/styles/scss/utilities/skeleton' as *; + +:host(#{$prefix}-fluid-dropdown) { + @extend .#{$prefix}--list-box__wrapper--fluid; + + @include emit-layout-tokens(); + ::slotted(#{$prefix}-ai-label), + ::slotted(#{$prefix}-slug) { + position: absolute; + inset-block-start: 70%; + inset-inline-end: $spacing-09; + } + + // Transform for non-revert-active elements + ::slotted(#{$prefix}-ai-label:not([revert-active])), + ::slotted(#{$prefix}-slug:not([revert-active])) { + transform: translateY(-70%); + } +} diff --git a/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.stories.ts b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.stories.ts new file mode 100644 index 000000000000..4b9ad4af1d7c --- /dev/null +++ b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.stories.ts @@ -0,0 +1,270 @@ +/** + * Copyright IBM Corp. 2025 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import './index'; +import View16 from '@carbon/icons/es/view/16.js'; +import FolderOpen16 from '@carbon/icons/es/folder--open/16.js'; +import Folders16 from '@carbon/icons/es/folders/16.js'; +import '../dropdown/dropdown-item'; +import '../ai-label'; +import '../icon-button'; +import { iconLoader } from '../../globals/internal/icon-loader'; +import '../toggle-tip/toggletip'; + +const content = html` +
+

AI Explained

+

84%

+

Confidence score

+

+ Lorem ipsum dolor sit amet, di os consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut fsil labore et dolore magna aliqua. +

+
+

Model type

+

Foundation model

+
+`; + +const actions = html` + + ${iconLoader(View16, { slot: 'icon' })} + View + + + ${iconLoader(FolderOpen16, { slot: 'icon' })} + Open folder + + + ${iconLoader(Folders16, { slot: 'icon' })} + Folders + + View details +`; + +const items = [ + { + value: 'option-0', + text: 'Lorem, ipsum dolor sit amet consectetur adipisicing elit.', + }, + { + value: 'option-1', + text: 'Option 1', + }, + { + value: 'option-2', + text: 'Option 2', + }, + { + value: 'option-3', + text: 'Option 3 - a disabled item', + disabled: true, + }, + { + value: 'option-4', + text: 'Option 4', + }, +]; + +const args = { + defaultWidth: 400, + disabled: false, + helperText: '', + invalid: false, + invalidText: + 'Error message that is really long can wrap to more lines but should not be excessively long', + label: 'This is an example label', + readOnly: false, + titleText: 'This is an example title', + warn: false, + warnText: + 'Warning message that is really long can wrap to more lines but should not be excessively long.', +}; + +const argTypes = { + defaultWidth: { + control: { type: 'range', min: 300, max: 800, step: 50 }, + }, + disabled: { + control: 'boolean', + description: 'Specify whether the control is disabled.', + }, + helperText: { + control: 'text', + description: + 'Provide helper text that is used alongside the control label for additional help.', + }, + invalid: { + control: 'boolean', + description: 'Specify if the currently value is invalid.', + }, + invalidText: { + control: 'text', + description: 'Message which is displayed if the value is invalid.', + }, + label: { + control: 'text', + description: 'The default content of the trigger button.', + }, + readOnly: { + control: 'boolean', + description: 'Whether or not the Dropdown is readonly.', + }, + titleText: { + control: 'text', + description: + 'Provide the title text that will be read by a screen reader when visiting this control.', + }, + warn: { + control: 'boolean', + description: 'Specify whether the control is currently in warning state.', + }, + warnText: { + control: 'text', + description: + 'Provide the text that is displayed when the control is in warning state.', + }, +}; + +export const Default = { + args, + argTypes, + render: ({ + defaultWidth, + disabled, + helperText, + invalid, + invalidText, + label, + readOnly, + titleText, + warn, + warnText, + }) => html` +
+ + ${items.map( + (elem) => html` + ${elem.text} + ` + )} + +
+ `, +}; + +export const WithToggletip = { + render: () => { + return html` +
+ + + Dropdown label +

Additional field information here.

+
+ An example option that is really long to show what should be done + to handle long text + Option 1 + Option 2 + Option 3 + Option 4 +
+
+ `; + }, +}; + +export const Skeleton = { + parameters: { + percy: { + skip: true, + }, + }, + args: { + defaultWidth: 400, + }, + argTypes: { + defaultWidth: { + control: { type: 'range', min: 300, max: 800, step: 50 }, + }, + }, + render: ({ defaultWidth }) => html` +
+ +
+ `, +}; + +export const WithAILabel = { + args, + argTypes: { + ...argTypes, + }, + render: ({ + defaultWidth, + disabled, + helperText, + invalid, + invalidText, + label, + readOnly, + titleText, + warn, + warnText, + }) => { + return html`
+ + + ${content}${actions} + ${items.map( + (elem) => html` + ${elem.text} + ` + )} + +
`; + }, +}; + +const meta = { + decorators: [ + (story) => { + return html`
${story()}
`; + }, + ], + title: 'Components/Fluid Components/FluidDropdown', +}; + +export default meta; diff --git a/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.ts b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.ts new file mode 100644 index 000000000000..59e00abd14e1 --- /dev/null +++ b/packages/web-components/src/components/fluid-dropdown/fluid-dropdown.ts @@ -0,0 +1,53 @@ +/** + * Copyright IBM Corp.2025 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { prefix } from '../../globals/settings'; +import { html } from 'lit'; +import { carbonElement as customElement } from '../../globals/decorators/carbon-element'; +import CDSDropdown from '../dropdown/dropdown'; +import styles from './fluid-dropdown.scss?lit'; +import { classMap } from 'lit/directives/class-map.js'; + +/** + * Fluid dropdown. + * + * @element cds-fluid-dropdown + */ +@customElement(`${prefix}-fluid-dropdown`) +class CDSFluidDropdown extends CDSDropdown { + connectedCallback() { + this.setAttribute('isFluid', 'true'); + super.connectedCallback(); + } + + updated(changedProperties) { + super.updated(changedProperties); + if ( + changedProperties.has('invalid') || + changedProperties.has('disabled') || + changedProperties.has('readOnly') || + changedProperties.has('warn') + ) { + this.requestUpdate(); + } + } + + render() { + const wrapperClasses = classMap({ + [`${prefix}--dropdown`]: true, + [`${prefix}--dropdown--invalid`]: this.invalid, + [`${prefix}--dropdown--warn`]: this.warn && !this.invalid, + [`${prefix}--list-box--disabled`]: this.disabled, + [`${prefix}--dropdown--readonly`]: this.readOnly, + }); + return html`
${super.render()}
`; + } + + static styles = [CDSDropdown.styles, styles]; +} + +export default CDSFluidDropdown; diff --git a/packages/web-components/src/components/fluid-dropdown/index.ts b/packages/web-components/src/components/fluid-dropdown/index.ts new file mode 100644 index 000000000000..05c4e0db5076 --- /dev/null +++ b/packages/web-components/src/components/fluid-dropdown/index.ts @@ -0,0 +1,8 @@ +/** + * Copyright IBM Corp. 2025 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ +import './fluid-dropdown'; +import './fluid-dropdown-skeleton';