Skip to content

Commit

Permalink
feat(Slug): implement AI Slug (#14998)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
tw15egan and andreancardona authored Oct 26, 2023
1 parent 754056f commit b1c721c
Show file tree
Hide file tree
Showing 28 changed files with 901 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
@@ -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';
9 changes: 9 additions & 0 deletions packages/carbon-components/scss/components/slug/_index.scss
Original file line number Diff line number Diff line change
@@ -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';
9 changes: 9 additions & 0 deletions packages/carbon-components/scss/components/slug/_slug.scss
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,15 @@ Array [
"skeletonElement",
"slow01",
"slow02",
"slugBackground",
"slugBackgroundHover",
"slugCalloutAuraEnd",
"slugCalloutAuraStart",
"slugCalloutGradientBottom",
"slugCalloutGradientTop",
"slugGradient",
"slugGradientHover",
"slugHollowHover",
"spacing",
"spacing01",
"spacing02",
Expand Down
3 changes: 3 additions & 0 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8781,6 +8781,9 @@ Map {
"as": Object {
"type": "elementType",
},
"autoAlign": Object {
"type": "bool",
},
"children": Object {
"type": "node",
},
Expand Down
9 changes: 9 additions & 0 deletions packages/react/scss/components/slug/_index.scss
Original file line number Diff line number Diff line change
@@ -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';
9 changes: 9 additions & 0 deletions packages/react/scss/components/slug/_slug.scss
Original file line number Diff line number Diff line change
@@ -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';
136 changes: 136 additions & 0 deletions packages/react/src/components/Slug/Slug.js
Original file line number Diff line number Diff line change
@@ -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 (
<div className={slugClasses} ref={ref}>
<Toggletip align={align} autoAlign={autoAlign}>
<ToggletipButton className={slugButtonClasses} label="Show information">
<span className={`${prefix}--slug__text`}>{aiText}</span>
{aiTextLabel && (
<span className={`${prefix}--slug__additional-text`}>
{aiTextLabel}
</span>
)}
</ToggletipButton>
<ToggletipContent>
{slugContent}
<ToggletipActions></ToggletipActions>
</ToggletipContent>
</Toggletip>
</div>
);
});

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;
1 change: 1 addition & 0 deletions packages/react/src/components/Slug/Slug.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello
148 changes: 148 additions & 0 deletions packages/react/src/components/Slug/Slug.stories.js
Original file line number Diff line number Diff line change
@@ -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 = (
<div>
<p className="secondary">AI Explained</p>
<h1>84%</h1>
<p className="secondary bold">Confidence score</p>
<p className="secondary">
Lorem ipsum dolor sit amet, di os consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut fsil labore et dolore magna aliqua.
</p>
<hr />
<p className="secondary">Model type</p>
<p className="bold">Foundation model</p>
</div>
);

const content = <span>AI was used to generate this content</span>;

export const Default = () => (
<>
<div className="slug-container">
<Slug autoAlign size="mini" slugContent={aiContent} />
<Slug autoAlign size="2xs" slugContent={aiContent} />
<Slug autoAlign size="xs" slugContent={aiContent} />
<Slug autoAlign size="sm" slugContent={aiContent} />
<Slug autoAlign size="md" slugContent={aiContent} />
<Slug autoAlign size="lg" slugContent={aiContent} />
<Slug autoAlign size="xl" slugContent={aiContent} />
</div>
<div className="slug-container">
<Slug kind="hollow" autoAlign size="mini" slugContent={content} />
<Slug kind="hollow" autoAlign size="2xs" slugContent={content} />
<Slug kind="hollow" autoAlign size="xs" slugContent={content} />
</div>
<div className="slug-container">
<Slug autoAlign kind="inline" size="sm" slugContent={aiContent} />
<Slug autoAlign kind="inline" size="md" slugContent={aiContent} />
<Slug autoAlign kind="inline" size="lg" slugContent={aiContent} />
</div>
<div className="slug-container">
<Slug
autoAlign
kind="inline"
size="sm"
aiTextLabel="Text goes here"
slugContent={aiContent}
/>
<Slug
autoAlign
kind="inline"
size="md"
aiTextLabel="Text goes here"
slugContent={aiContent}
/>
<Slug
autoAlign
kind="inline"
size="lg"
aiTextLabel="Text goes here"
slugContent={aiContent}
/>
</div>
<div className="slug-container">
<Slug
autoAlign
kind="inline"
dotType="hollow"
size="sm"
slugContent={content}
/>
<Slug
autoAlign
kind="inline"
dotType="hollow"
size="md"
slugContent={content}
/>
<Slug
autoAlign
kind="inline"
dotType="hollow"
size="lg"
slugContent={content}
/>
</div>
<div className="slug-container">
<Slug
autoAlign
kind="inline"
dotType="hollow"
size="sm"
aiTextLabel="Text goes here"
slugContent={content}
/>
<Slug
autoAlign
kind="inline"
dotType="hollow"
size="md"
aiTextLabel="Text goes here"
slugContent={content}
/>
<Slug
autoAlign
kind="inline"
dotType="hollow"
size="lg"
aiTextLabel="Text goes here"
slugContent={content}
/>
</div>
</>
);

export const Playground = (args) => (
<>
<div className="slug-container">
<Slug autoAlign slugContent={aiContent} {...args} />
</div>
<Button>Test</Button>
<Button kind="danger">Test</Button>
</>
);
10 changes: 10 additions & 0 deletions packages/react/src/components/Slug/index.js
Original file line number Diff line number Diff line change
@@ -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 };
Loading

0 comments on commit b1c721c

Please sign in to comment.