From b1c721c1c9d802e7a667fc64a0af5596bb7d21a3 Mon Sep 17 00:00:00 2001 From: TJ Egan Date: Thu, 26 Oct 2023 10:44:01 -0400 Subject: [PATCH] feat(Slug): implement AI Slug (#14998) * feat(Slug): scaffold out AI Slug component * feat(slug): add gradient tokens to themes, hover styles * feat(slug): add focus styles, cleanup storybook * fix(Theme): adjust small slug hover tokens * feat(Slug): add hollow slug * feat(Slug): initial inline styles * chore(snapshot): update snapshots * feat(Slug): add inline styles * fix(Slug): refactor inline variant * style(Slug): tweak inline styles * style(Slug): add hover styles to inline variant * style(Slug): add initial callout styles * style(Slug): tokenize gradients * style(Slug): adjust padding * chore: udpate snapshots * style(Slug): adjust padding with hollow dot, fix text colors * fix(Slug): fix hover styles when focused * refactor(Slug): remove ai from prefix --------- Co-authored-by: Andrea N. Cardona --- .../scss/components/slug/_index.scss | 9 + .../scss/components/slug/_slug.scss | 9 + .../scss/components/slug/_index.scss | 9 + .../scss/components/slug/_slug.scss | 9 + .../__snapshots__/PublicAPI-test.js.snap | 9 + .../__snapshots__/PublicAPI-test.js.snap | 3 + .../react/scss/components/slug/_index.scss | 9 + .../react/scss/components/slug/_slug.scss | 9 + packages/react/src/components/Slug/Slug.js | 136 +++++++ packages/react/src/components/Slug/Slug.mdx | 1 + .../react/src/components/Slug/Slug.stories.js | 148 ++++++++ packages/react/src/components/Slug/index.js | 10 + .../react/src/components/Slug/slug-story.scss | 36 ++ .../react/src/components/Toggletip/index.tsx | 10 +- packages/react/src/index.js | 1 + .../__snapshots__/styles-test.js.snap | 10 + packages/styles/files.js | 2 + packages/styles/scss/__tests__/theme-test.js | 9 + packages/styles/scss/components/_index.scss | 1 + .../styles/scss/components/slug/_index.scss | 4 + .../styles/scss/components/slug/_slug.scss | 346 ++++++++++++++++++ packages/themes/src/g10.js | 13 + packages/themes/src/g100.js | 16 +- packages/themes/src/g90.js | 20 +- .../__tests__/__snapshots__/v11-test.js.snap | 9 + .../src/tokens/__tests__/metadata-test.js | 36 ++ packages/themes/src/tokens/v11TokenGroup.js | 17 + packages/themes/src/white.js | 17 +- 28 files changed, 901 insertions(+), 7 deletions(-) create mode 100644 packages/carbon-components-react/scss/components/slug/_index.scss create mode 100644 packages/carbon-components-react/scss/components/slug/_slug.scss create mode 100644 packages/carbon-components/scss/components/slug/_index.scss create mode 100644 packages/carbon-components/scss/components/slug/_slug.scss create mode 100644 packages/react/scss/components/slug/_index.scss create mode 100644 packages/react/scss/components/slug/_slug.scss create mode 100644 packages/react/src/components/Slug/Slug.js create mode 100644 packages/react/src/components/Slug/Slug.mdx create mode 100644 packages/react/src/components/Slug/Slug.stories.js create mode 100644 packages/react/src/components/Slug/index.js create mode 100644 packages/react/src/components/Slug/slug-story.scss create mode 100644 packages/styles/scss/components/slug/_index.scss create mode 100644 packages/styles/scss/components/slug/_slug.scss diff --git a/packages/carbon-components-react/scss/components/slug/_index.scss b/packages/carbon-components-react/scss/components/slug/_index.scss new file mode 100644 index 000000000000..31a8cf757be0 --- /dev/null +++ b/packages/carbon-components-react/scss/components/slug/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/slug'; diff --git a/packages/carbon-components-react/scss/components/slug/_slug.scss b/packages/carbon-components-react/scss/components/slug/_slug.scss new file mode 100644 index 000000000000..d6162f1062ab --- /dev/null +++ b/packages/carbon-components-react/scss/components/slug/_slug.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components-react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/slug/slug'; diff --git a/packages/carbon-components/scss/components/slug/_index.scss b/packages/carbon-components/scss/components/slug/_index.scss new file mode 100644 index 000000000000..4890b6233e19 --- /dev/null +++ b/packages/carbon-components/scss/components/slug/_index.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/slug'; diff --git a/packages/carbon-components/scss/components/slug/_slug.scss b/packages/carbon-components/scss/components/slug/_slug.scss new file mode 100644 index 000000000000..cbb522cf1937 --- /dev/null +++ b/packages/carbon-components/scss/components/slug/_slug.scss @@ -0,0 +1,9 @@ +// Code generated by carbon-components. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/slug/slug'; diff --git a/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap index f7038f43f48c..15e4371eb5ae 100644 --- a/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/elements/src/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -271,6 +271,15 @@ Array [ "skeletonElement", "slow01", "slow02", + "slugBackground", + "slugBackgroundHover", + "slugCalloutAuraEnd", + "slugCalloutAuraStart", + "slugCalloutGradientBottom", + "slugCalloutGradientTop", + "slugGradient", + "slugGradientHover", + "slugHollowHover", "spacing", "spacing01", "spacing02", diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 6ed50979cacb..0e53df0816fd 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -8781,6 +8781,9 @@ Map { "as": Object { "type": "elementType", }, + "autoAlign": Object { + "type": "bool", + }, "children": Object { "type": "node", }, diff --git a/packages/react/scss/components/slug/_index.scss b/packages/react/scss/components/slug/_index.scss new file mode 100644 index 000000000000..aa5abf7f12ed --- /dev/null +++ b/packages/react/scss/components/slug/_index.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/slug'; diff --git a/packages/react/scss/components/slug/_slug.scss b/packages/react/scss/components/slug/_slug.scss new file mode 100644 index 000000000000..fb30c2c834ec --- /dev/null +++ b/packages/react/scss/components/slug/_slug.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2023 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/components/slug/slug'; diff --git a/packages/react/src/components/Slug/Slug.js b/packages/react/src/components/Slug/Slug.js new file mode 100644 index 000000000000..f2ebf4ac5a30 --- /dev/null +++ b/packages/react/src/components/Slug/Slug.js @@ -0,0 +1,136 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * 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 cx from 'classnames'; +import PropTypes from 'prop-types'; +import React from 'react'; + +import { usePrefix } from '../../internal/usePrefix'; +import { + Toggletip, + ToggletipButton, + ToggletipContent, + ToggletipActions, +} from '../Toggletip'; + +const Slug = React.forwardRef(function Slug( + { + aiText = 'AI', + aiTextLabel, + align, + autoAlign = false, + className, + dotType, + kind, + size = 'xs', + slugContent, + }, + ref +) { + const prefix = usePrefix(); + + const slugClasses = cx(className, { + [`${prefix}--slug`]: true, + [`${prefix}--slug--hollow`]: kind === 'hollow' || dotType === 'hollow', + // Need to come up with a better name; explainable? + // Need to be able to target the non-hollow variant another way + // other than using `:not` all over the styles + [`${prefix}--slug--enabled`]: kind !== 'hollow' && dotType !== 'hollow', + }); + + const slugButtonClasses = cx({ + [`${prefix}--slug__button`]: true, + [`${prefix}--slug__button--${size}`]: size, + [`${prefix}--slug__button--${kind}`]: kind, + [`${prefix}--slug__button--inline-with-content`]: + kind === 'inline' && aiTextLabel, + }); + + return ( +
+ + + {aiText} + {aiTextLabel && ( + + {aiTextLabel} + + )} + + + {slugContent} + + + +
+ ); +}); + +Slug.propTypes = { + /** + * Specify the correct translation of the AI text + */ + aiText: PropTypes.string, + + /** + * Specify additional text to be rendered next to the AI label in the inline variant + */ + aiTextLabel: PropTypes.string, + + /** + * Specify how the popover should align with the button + */ + align: PropTypes.oneOf([ + 'top', + 'top-left', + 'top-right', + + 'bottom', + 'bottom-left', + 'bottom-right', + + 'left', + 'left-bottom', + 'left-top', + + 'right', + 'right-bottom', + 'right-top', + ]), + + /** + * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes. + */ + autoAlign: PropTypes.bool, + + /** + * Specify an optional className to be added to the AI slug + */ + className: PropTypes.string, + + /** + * Specify the type of dot that should be rendered in front of the inline variant + */ + dotType: PropTypes.oneOf(['default', 'hollow']), + + /** + * Specify the type of Slug, from the following list of types: + */ + kind: PropTypes.oneOf(['default', 'hollow', 'inline']), + + /** + * Specify the size of the button, from the following list of sizes: + */ + size: PropTypes.oneOf(['mini', '2xs', 'xs', 'sm', 'md', 'lg', 'xl']), + + /** + * Specify the content you want rendered inside the slug ToggleTip + */ + slugContent: PropTypes.node, +}; + +export default Slug; diff --git a/packages/react/src/components/Slug/Slug.mdx b/packages/react/src/components/Slug/Slug.mdx new file mode 100644 index 000000000000..e965047ad7c5 --- /dev/null +++ b/packages/react/src/components/Slug/Slug.mdx @@ -0,0 +1 @@ +Hello diff --git a/packages/react/src/components/Slug/Slug.stories.js b/packages/react/src/components/Slug/Slug.stories.js new file mode 100644 index 000000000000..5c2c7c4722b4 --- /dev/null +++ b/packages/react/src/components/Slug/Slug.stories.js @@ -0,0 +1,148 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +/* eslint-disable no-console */ + +import React from 'react'; + +import Slug from '.'; +import Button from '../Button'; +import mdx from './Slug.mdx'; +import './slug-story.scss'; + +export default { + title: 'Experimental/unstable__Slug', + component: Slug, + parameters: { + docs: { + page: mdx, + }, + }, +}; + +const aiContent = ( +
+

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 content = AI was used to generate this content; + +export const Default = () => ( + <> +
+ + + + + + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+ +); + +export const Playground = (args) => ( + <> +
+ +
+ + + +); diff --git a/packages/react/src/components/Slug/index.js b/packages/react/src/components/Slug/index.js new file mode 100644 index 000000000000..b93fe751c330 --- /dev/null +++ b/packages/react/src/components/Slug/index.js @@ -0,0 +1,10 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * 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 Slug from './Slug'; + +export default Slug; +export { Slug }; diff --git a/packages/react/src/components/Slug/slug-story.scss b/packages/react/src/components/Slug/slug-story.scss new file mode 100644 index 000000000000..51e6c697d200 --- /dev/null +++ b/packages/react/src/components/Slug/slug-story.scss @@ -0,0 +1,36 @@ +@use '@carbon/styles/scss/type'; +@use '@carbon/styles/scss/theme'; + +.slug-container { + display: flex; + margin-bottom: 6rem; + align-items: flex-start; + + & > * { + margin-left: 2rem; + } +} + +.slug-container .cds--toggletip-content p { + @include type.type-style('body-compact-01'); +} + +.slug-container .cds--toggletip-content .bold { + font-weight: 600; +} + +.slug-container .cds--toggletip-content .secondary { + color: theme.$text-secondary; +} + +.slug-container .cds--toggletip-content h1 { + margin-bottom: 1rem; +} + +.slug-container .cds--toggletip-content hr { + border: 0; + height: 1px; + background: theme.$border-subtle; + margin-top: 2rem; + margin-bottom: 2rem; +} diff --git a/packages/react/src/components/Toggletip/index.tsx b/packages/react/src/components/Toggletip/index.tsx index f63c66391c35..83e154064617 100644 --- a/packages/react/src/components/Toggletip/index.tsx +++ b/packages/react/src/components/Toggletip/index.tsx @@ -82,6 +82,7 @@ function useToggletip() { interface ToggletipProps { align?: PopoverAlignment | undefined; as?: E | undefined; + autoAlign?: boolean | undefined; className?: string | undefined; children?: ReactNode; defaultOpen?: boolean | undefined; @@ -95,6 +96,7 @@ interface ToggletipProps { export function Toggletip({ align, as, + autoAlign, className: customClassName, children, defaultOpen = false, @@ -173,7 +175,8 @@ export function Toggletip({ open={open} onKeyDown={onKeyDown} onBlur={handleBlur} - ref={ref}> + ref={ref} + autoAlign={autoAlign}> {children} @@ -208,6 +211,11 @@ Toggletip.propTypes = { */ as: PropTypes.elementType, + /** + * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes. + */ + autoAlign: PropTypes.bool, + /** * Custom children to be rendered as the content of the label */ diff --git a/packages/react/src/index.js b/packages/react/src/index.js index 588ad07ad0ec..14e20ee01f13 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -298,3 +298,4 @@ export { DefinitionTooltip } from './components/Tooltip/DefinitionTooltip'; export { GlobalTheme, Theme, useTheme } from './components/Theme'; export { usePrefix } from './internal/usePrefix'; export { useIdPrefix } from './internal/useIdPrefix'; +export { Slug as unstable__Slug } from './components/Slug'; diff --git a/packages/styles/__tests__/__snapshots__/styles-test.js.snap b/packages/styles/__tests__/__snapshots__/styles-test.js.snap index a617c2aa9aeb..60aebb2849cd 100644 --- a/packages/styles/__tests__/__snapshots__/styles-test.js.snap +++ b/packages/styles/__tests__/__snapshots__/styles-test.js.snap @@ -617,6 +617,16 @@ Array [ "importPath": "@carbon/styles/scss/components/slider/slider", "relativePath": "scss/components/slider/slider", }, + Object { + "filepath": "scss/components/slug/_index.scss", + "importPath": "@carbon/styles/scss/components/slug", + "relativePath": "scss/components/slug", + }, + Object { + "filepath": "scss/components/slug/_slug.scss", + "importPath": "@carbon/styles/scss/components/slug/slug", + "relativePath": "scss/components/slug/slug", + }, Object { "filepath": "scss/components/stack/_index.scss", "importPath": "@carbon/styles/scss/components/stack", diff --git a/packages/styles/files.js b/packages/styles/files.js index 54f7afee4156..54d722c22a6a 100644 --- a/packages/styles/files.js +++ b/packages/styles/files.js @@ -142,6 +142,8 @@ const files = [ 'scss/components/skeleton-styles/_skeleton-styles.scss', 'scss/components/slider/_index.scss', 'scss/components/slider/_slider.scss', + 'scss/components/slug/_index.scss', + 'scss/components/slug/_slug.scss', 'scss/components/stack/_index.scss', 'scss/components/stack/_stack.scss', 'scss/components/structured-list/_index.scss', diff --git a/packages/styles/scss/__tests__/theme-test.js b/packages/styles/scss/__tests__/theme-test.js index 8fc597209eaf..f9641a633e5d 100644 --- a/packages/styles/scss/__tests__/theme-test.js +++ b/packages/styles/scss/__tests__/theme-test.js @@ -127,6 +127,15 @@ describe('@carbon/styles/scss/theme', () => { "support-caution-major", "support-caution-minor", "support-caution-undefined", + "slug-background", + "slug-gradient", + "slug-background-hover", + "slug-gradient-hover", + "slug-hollow-hover", + "slug-callout-gradient-top", + "slug-callout-gradient-bottom", + "slug-callout-aura-start", + "slug-callout-aura-end", "highlight", "overlay", "toggle-off", diff --git a/packages/styles/scss/components/_index.scss b/packages/styles/scss/components/_index.scss index b8ebb05f418a..9d5f88bb42db 100644 --- a/packages/styles/scss/components/_index.scss +++ b/packages/styles/scss/components/_index.scss @@ -58,6 +58,7 @@ @use 'select'; @use 'skeleton-styles'; @use 'slider'; +@use 'slug'; @use 'stack'; @use 'structured-list'; @use 'tabs'; diff --git a/packages/styles/scss/components/slug/_index.scss b/packages/styles/scss/components/slug/_index.scss new file mode 100644 index 000000000000..6cca55ef4a50 --- /dev/null +++ b/packages/styles/scss/components/slug/_index.scss @@ -0,0 +1,4 @@ +@forward 'slug'; +@use 'slug'; + +@include slug.slug; diff --git a/packages/styles/scss/components/slug/_slug.scss b/packages/styles/scss/components/slug/_slug.scss new file mode 100644 index 000000000000..fd625e4a4f0f --- /dev/null +++ b/packages/styles/scss/components/slug/_slug.scss @@ -0,0 +1,346 @@ +@use '../../config' as *; +@use '../../colors' as *; +@use '../../motion' as *; +@use '../../theme' as *; +@use '../../type' as *; +@use '../../utilities/convert'; + +$sizes: ( + mini: ( + height: convert.to-rem(16px), + width: convert.to-rem(16px), + font-size: convert.to-rem(9px), + line-height: convert.to-rem(12px), + background: $slug-background, + ), + 2xs: ( + height: convert.to-rem(20px), + width: convert.to-rem(20px), + font-size: convert.to-rem(12px), + line-height: convert.to-rem(16px), + background: $slug-background, + ), + xs: ( + height: convert.to-rem(24px), + width: convert.to-rem(24px), + font-size: convert.to-rem(12px), + line-height: convert.to-rem(16px), + background: $slug-gradient, + ), + sm: ( + height: convert.to-rem(32px), + width: convert.to-rem(32px), + font-size: convert.to-rem(16px), + line-height: convert.to-rem(21px), + background: $slug-gradient, + ), + md: ( + height: convert.to-rem(40px), + width: convert.to-rem(40px), + font-size: convert.to-rem(16px), + line-height: convert.to-rem(21px), + background: $slug-gradient, + ), + lg: ( + height: convert.to-rem(48px), + width: convert.to-rem(48px), + font-size: convert.to-rem(16px), + line-height: convert.to-rem(21px), + background: $slug-gradient, + ), + xl: ( + height: convert.to-rem(64px), + width: convert.to-rem(64px), + font-size: convert.to-rem(20px), + line-height: convert.to-rem(26px), + background: $slug-gradient, + ), +); + +/// Slug styles +/// @access public +/// @group slider +@mixin slug { + .#{$prefix}--slug { + display: flex; + } + + .#{$prefix}--slug .#{$prefix}--slug__button { + position: relative; + display: flex; + align-items: center; + justify-content: center; + color: $text-inverse; + font-weight: 600; + transition: color $duration-fast-01 motion(entrance, productive), + border-color $duration-fast-01 motion(entrance, productive), + box-shadow $duration-fast-01 motion(entrance, productive); + + @each $group, $size in $sizes { + // Create a class for each size slug + &--#{$group} { + @each $property, $value in $size { + // Set correct properties for each size + #{$property}: $value; + } + } + } + } + + .#{$prefix}--slug .#{$prefix}--slug__button:focus { + box-shadow: inset 0 0 0 2px $focus, inset 0 0 0 3px $focus-inset; + outline: none; + } + + .#{$prefix}--slug__text { + position: relative; + z-index: 1; + } + + // pseudo element to animate the hover transition + .#{$prefix}--slug__button::before { + position: absolute; + background: $slug-gradient-hover; + block-size: 100%; + content: ''; + inline-size: 100%; + opacity: 0; + transition: opacity $duration-fast-01 motion(entrance, productive); + } + + .#{$prefix}--slug__button:hover::before { + opacity: 1; + } + + // Focus styles + .#{$prefix}--slug .#{$prefix}--slug__button:focus::before { + block-size: calc(100% - 6px); + inline-size: calc(100% - 6px); + } + + .#{$prefix}--slug__button.#{$prefix}--slug__button--mini::before, + .#{$prefix}--slug__button.#{$prefix}--slug__button--2xs::before { + background: $slug-background-hover; + } + + .#{$prefix}--slug__button.#{$prefix}--slug__button--mini:focus, + .#{$prefix}--slug__button.#{$prefix}--slug__button--2xs:focus { + box-shadow: inset 0 0 0 1px $focus, inset 0 0 0 2px $focus-inset; + } + + .#{$prefix}--slug__button.#{$prefix}--slug__button--mini:focus::before, + .#{$prefix}--slug__button.#{$prefix}--slug__button--2xs:focus::before { + block-size: calc(100% - 4px); + inline-size: calc(100% - 4px); + } + + // Hollow slug + // Only allow mini, 2xs, and xs sizes + .#{$prefix}--slug__button--hollow.#{$prefix}--slug__button--sm, + .#{$prefix}--slug__button--hollow.#{$prefix}--slug__button--md, + .#{$prefix}--slug__button--hollow.#{$prefix}--slug__button--lg, + .#{$prefix}--slug__button--hollow.#{$prefix}--slug__button--xl { + block-size: convert.to-rem(24px); + font-size: convert.to-rem(12px); + inline-size: convert.to-rem(24px); + line-height: convert.to-rem(16px); + } + + .#{$prefix}--slug__button--hollow::before { + display: none; + } + + .#{$prefix}--slug .#{$prefix}--slug__button--hollow { + border: 1px solid $border-inverse; + background: transparent; + color: $text-primary; + } + + .#{$prefix}--slug__button--hollow:hover { + border-color: $slug-hollow-hover; + color: $slug-hollow-hover; + } + + .#{$prefix}--slug__button--hollow:focus { + border-color: $focus; + box-shadow: inset 0 0 0 1px $focus; + } + + // Inline slug + .#{$prefix}--slug .#{$prefix}--slug__button--inline { + border: 1px solid transparent; + border-radius: convert.to-rem(1px); + background: transparent; + block-size: initial; + color: $text-primary; + font-size: convert.to-rem(14px); + inline-size: initial; + line-height: initial; + padding-inline: convert.to-rem(4px); + } + + .#{$prefix}--slug__button--inline::before { + display: none; + } + + .#{$prefix}--slug .#{$prefix}--slug__button--inline:focus { + border-color: $focus; + box-shadow: none; + } + + .#{$prefix}--slug .#{$prefix}--slug__button--inline:hover { + border-color: $icon-secondary; + color: $text-secondary; + } + + .#{$prefix}--slug .#{$prefix}--slug__button--inline:focus:hover { + border-color: $focus; + } + + .#{$prefix}--slug + .#{$prefix}--slug__button--inline:hover + .#{$prefix}--slug__text::before { + background: $icon-secondary; + } + + .#{$prefix}--slug--hollow + .#{$prefix}--slug__button--inline:hover + .#{$prefix}--slug__text::before { + background: transparent; + box-shadow: inset 0 0 0 1px $icon-secondary; + } + + .#{$prefix}--slug__button--inline .#{$prefix}--slug__text { + padding-inline-start: convert.to-rem(8px); + } + + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--lg + .#{$prefix}--slug__text { + padding-inline-start: convert.to-rem(12px); + } + + .#{$prefix}--slug__button--inline .#{$prefix}--slug__text::before { + position: absolute; + display: inline-block; + background: $icon-primary; + block-size: convert.to-rem(4px); + content: ''; + inline-size: convert.to-rem(4px); + inset-block-start: 50%; + inset-inline-start: 0; + opacity: 1; + transform: translateY(-50%); + transition: background $duration-fast-01 motion(entrance, productive), + box-shadow $duration-fast-01 motion(entrance, productive); + } + + // Inline slug hollow dot + .#{$prefix}--slug--hollow .#{$prefix}--slug__text::before { + background: transparent; + block-size: convert.to-rem(6px); + box-shadow: inset 0 0 0 1px $icon-primary; + inline-size: convert.to-rem(6px); + } + + .#{$prefix}--slug--hollow + .#{$prefix}--slug__button--sm + .#{$prefix}--slug__text, + .#{$prefix}--slug--hollow + .#{$prefix}--slug__button--md + .#{$prefix}--slug__text { + padding-inline-start: convert.to-rem(9px); + } + + .#{$prefix}--slug__button--lg .#{$prefix}--slug__text::before, + .#{$prefix}--slug--hollow + .#{$prefix}--slug__button--lg + .#{$prefix}--slug__text::before { + block-size: convert.to-rem(8px); + inline-size: convert.to-rem(8px); + } + + // Only allow sm, md, and lg sizes + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--mini, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--mini + .#{$prefix}--slug__additional-text, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--2xs, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--2xs + .#{$prefix}--slug__additional-text, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--xs, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--xs + .#{$prefix}--slug__additional-text, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--sm, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--sm + .#{$prefix}--slug__additional-text { + font-size: convert.to-rem(12px); + } + + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--lg, + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--xl { + font-size: convert.to-rem(16px); + } + + // Inline slug with text + .#{$prefix}--slug .#{$prefix}--slug__button--inline-with-content { + border: 1px solid $border-inverse; + padding-block: convert.to-rem(2px); + padding-inline: convert.to-rem(8px); + } + + .#{$prefix}--slug__button--inline-with-content + .#{$prefix}--slug__additional-text { + @include type-style('body-compact-02'); + + padding-inline-start: convert.to-rem(4px); + } + + .#{$prefix}--slug__button--inline.#{$prefix}--slug__button--md + .#{$prefix}--slug__additional-text { + font-size: convert.to-rem(14px); + } + + .#{$prefix}--slug .#{$prefix}--slug__button--inline-with-content:focus { + box-shadow: inset 0 0 0 1px $focus; + } + + // Default callout styles + .#{$prefix}--slug.#{$prefix}--slug--hollow .#{$prefix}--toggletip-content { + row-gap: 0; + } + + // Slug callout styles + .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--popover-content { + border: 1px solid $border-subtle; + border-radius: 16px; + // 84px seems to make this fully opaque? + backdrop-filter: blur(25px); + background: linear-gradient( + 0deg, + $slug-callout-aura-start 0%, + $slug-callout-aura-end 33%, + transparent 100% + ), + linear-gradient( + 180deg, + $slug-callout-gradient-top 0%, + $slug-callout-gradient-bottom 100% + ) + rgba(0, 0, 0, 0.01); + // box-shadow seems to match the spec better + // than the same values plugged into `drop-shadow` + // filter: drop-shadow(-45px 45px 100px rgba(0, 0, 0, 0.2)); + box-shadow: -45px 45px 100px rgba(0, 0, 0, 0.2); + color: $text-primary; + min-inline-size: convert.to-rem(280px); + } + + .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--popover-caret { + background: $border-subtle; + } + + .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--toggletip-content { + padding-block-end: convert.to-rem(80px); + padding-block-start: convert.to-rem(32px); + padding-inline: convert.to-rem(32px); + } +} diff --git a/packages/themes/src/g10.js b/packages/themes/src/g10.js index e4b052420d76..981f780163ad 100644 --- a/packages/themes/src/g10.js +++ b/packages/themes/src/g10.js @@ -7,6 +7,7 @@ import { // Blue + blue10, blue20, blue30, blue40, @@ -40,6 +41,7 @@ import { // Constants white, whiteHover, + rgba, } from '@carbon/colors'; import { adjustAlpha } from './tools'; @@ -200,6 +202,17 @@ export const overlay = 'rgba(22, 22, 22, 0.5)'; export const toggleOff = gray50; export const shadow = 'rgba(0, 0, 0, 0.3)'; +// AI +export const slugBackground = gray70; +export const slugGradient = `${gray100} linear-gradient(135deg, ${gray40} 0%, rgba(${white}, 0) 100%)`; +export const slugBackgroundHover = gray60; +export const slugGradientHover = `${gray100} linear-gradient(135deg, ${gray20Hover} 0%, rgba(${white}, 0) 100%)`; +export const slugHollowHover = gray80Hover; +export const slugCalloutGradientTop = rgba(gray10, 0.85); +export const slugCalloutGradientBottom = rgba(gray20, 0.85); +export const slugCalloutAuraStart = rgba(blue10, 0.6); +export const slugCalloutAuraEnd = rgba(white, 0); + export { // Type caption01, diff --git a/packages/themes/src/g100.js b/packages/themes/src/g100.js index 23d342a6eebc..8e940589c1e6 100644 --- a/packages/themes/src/g100.js +++ b/packages/themes/src/g100.js @@ -7,6 +7,7 @@ import { // Blue + blue20, blue40, blue60, blue70, @@ -14,7 +15,10 @@ import { // Gray gray10, + gray10Hover, + gray20, gray30, + gray30Hover, gray40, gray50, gray60, @@ -46,7 +50,6 @@ import { // Tools rgba, - gray10Hover, } from '@carbon/colors'; import { adjustLightness, adjustAlpha } from './tools'; @@ -207,6 +210,17 @@ export const overlay = rgba(black, 0.65); export const toggleOff = gray60; export const shadow = rgba(black, 0.8); +// AI +export const slugBackground = gray30; +export const slugGradient = `${gray50} linear-gradient(135deg, ${gray10} 0%, rgba(${white}, 0) 100%)`; +export const slugBackgroundHover = gray20; +export const slugGradientHover = `${gray40} linear-gradient(135deg, ${white} 0%, rgba(${white}, 0) 100%)`; +export const slugHollowHover = gray30Hover; +export const slugCalloutGradientTop = rgba(gray100, 0.85); +export const slugCalloutGradientBottom = rgba(gray90, 0.85); +export const slugCalloutAuraStart = rgba(blue20, 0.2); +export const slugCalloutAuraEnd = rgba(gray100, 0); + export { // Type caption01, diff --git a/packages/themes/src/g90.js b/packages/themes/src/g90.js index c980dab52609..3475b9edf253 100644 --- a/packages/themes/src/g90.js +++ b/packages/themes/src/g90.js @@ -7,13 +7,17 @@ import { // Blue + blue20, blue40, blue60, blue70, // Gray gray10, + gray10Hover, + gray20, gray30, + gray30Hover, gray40, gray50, gray50Hover, @@ -22,7 +26,9 @@ import { gray70, gray70Hover, gray80, + gray80Hover, gray90, + gray90Hover, gray100, // Support @@ -44,9 +50,6 @@ import { // Tools rgba, - gray90Hover, - gray10Hover, - gray80Hover, } from '@carbon/colors'; import { adjustAlpha } from './tools'; @@ -207,6 +210,17 @@ export const overlay = rgba(black, 0.65); export const toggleOff = gray50; export const shadow = rgba(black, 0.8); +// AI +export const slugBackground = gray30; +export const slugGradient = `${gray50} linear-gradient(135deg, ${gray10} 0%, rgba(${white}, 0) 100%)`; +export const slugBackgroundHover = gray20; +export const slugGradientHover = `${gray40} linear-gradient(135deg, ${white} 0%, rgba(${white}, 0) 100%)`; +export const slugHollowHover = gray30Hover; +export const slugCalloutGradientTop = rgba(gray100, 0.85); +export const slugCalloutGradientBottom = rgba(gray90, 0.85); +export const slugCalloutAuraStart = rgba(blue20, 0.2); +export const slugCalloutAuraEnd = rgba(gray100, 0); + export { // Type caption01, diff --git a/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap b/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap index 0a0e4b075078..9beb5856cf4b 100644 --- a/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap +++ b/packages/themes/src/tokens/__tests__/__snapshots__/v11-test.js.snap @@ -238,6 +238,15 @@ Array [ "support-caution-major", "support-caution-minor", "support-caution-undefined", + "slug-background", + "slug-gradient", + "slug-background-hover", + "slug-gradient-hover", + "slug-hollow-hover", + "slug-callout-gradient-top", + "slug-callout-gradient-bottom", + "slug-callout-aura-start", + "slug-callout-aura-end", "highlight", "overlay", "toggle-off", diff --git a/packages/themes/src/tokens/__tests__/metadata-test.js b/packages/themes/src/tokens/__tests__/metadata-test.js index cd5790f3602b..2d82f7afdb34 100644 --- a/packages/themes/src/tokens/__tests__/metadata-test.js +++ b/packages/themes/src/tokens/__tests__/metadata-test.js @@ -925,6 +925,42 @@ test('metadata', () => { "name": "support-caution-undefined", "type": "color", }, + Object { + "name": "slug-background", + "type": "color", + }, + Object { + "name": "slug-gradient", + "type": "color", + }, + Object { + "name": "slug-background-hover", + "type": "color", + }, + Object { + "name": "slug-gradient-hover", + "type": "color", + }, + Object { + "name": "slug-hollow-hover", + "type": "color", + }, + Object { + "name": "slug-callout-gradient-top", + "type": "color", + }, + Object { + "name": "slug-callout-gradient-bottom", + "type": "color", + }, + Object { + "name": "slug-callout-aura-start", + "type": "color", + }, + Object { + "name": "slug-callout-aura-end", + "type": "color", + }, Object { "name": "highlight", "type": "color", diff --git a/packages/themes/src/tokens/v11TokenGroup.js b/packages/themes/src/tokens/v11TokenGroup.js index 1793c14eb4bf..dd11e68e3f1c 100644 --- a/packages/themes/src/tokens/v11TokenGroup.js +++ b/packages/themes/src/tokens/v11TokenGroup.js @@ -341,6 +341,22 @@ export const contextual = TokenGroup.create({ ], }); +export const ai = TokenGroup.create({ + name: 'AI', + properties: ['background'], + tokens: [ + 'slug-background', + 'slug-gradient', + 'slug-background-hover', + 'slug-gradient-hover', + 'slug-hollow-hover', + 'slug-callout-gradient-top', + 'slug-callout-gradient-bottom', + 'slug-callout-aura-start', + 'slug-callout-aura-end', + ], +}); + export const group = TokenGroup.create({ name: 'All', tokens: [ @@ -359,6 +375,7 @@ export const group = TokenGroup.create({ link, icon, support, + ai, // Misc { diff --git a/packages/themes/src/white.js b/packages/themes/src/white.js index 4c81a7758835..e4e4b818c879 100644 --- a/packages/themes/src/white.js +++ b/packages/themes/src/white.js @@ -7,6 +7,7 @@ import { // Blue + blue10, blue20, blue30, blue40, @@ -15,6 +16,7 @@ import { // Gray gray10, + gray10Hover, gray20, gray20Hover, gray30, @@ -23,6 +25,7 @@ import { gray60, gray70, gray80, + gray80Hover, gray100, // Support @@ -38,8 +41,7 @@ import { // Constants white, whiteHover, - gray80Hover, - gray10Hover, + rgba, } from '@carbon/colors'; import { adjustAlpha } from './tools'; @@ -200,6 +202,17 @@ export const overlay = 'rgba(22, 22, 22, 0.5)'; export const toggleOff = gray50; export const shadow = 'rgba(0, 0, 0, 0.3)'; +// AI +export const slugBackground = gray70; +export const slugGradient = `${gray100} linear-gradient(135deg, ${gray40} 0%, rgba(${white}, 0) 100%)`; +export const slugBackgroundHover = gray60; +export const slugGradientHover = `${gray100} linear-gradient(135deg, ${gray20Hover} 0%, rgba(${white}, 0) 100%)`; +export const slugHollowHover = gray80Hover; +export const slugCalloutGradientTop = rgba(gray10, 0.85); +export const slugCalloutGradientBottom = rgba(gray20, 0.85); +export const slugCalloutAuraStart = rgba(blue10, 0.6); +export const slugCalloutAuraEnd = rgba(white, 0); + // Type export { caption01,