diff --git a/libs/react-components/.storybook/preview.ts b/libs/react-components/.storybook/preview.ts index caec680..eb7c788 100644 --- a/libs/react-components/.storybook/preview.ts +++ b/libs/react-components/.storybook/preview.ts @@ -10,6 +10,11 @@ const preview: Preview = { date: /Date$/i, }, }, + docs: { + source: { + type: 'dynamic', + }, + }, }, }; diff --git a/libs/react-components/src/lib/components/Banner/Banner.stories.tsx b/libs/react-components/src/lib/components/Banner/Banner.stories.tsx index 5542a0b..843f574 100644 --- a/libs/react-components/src/lib/components/Banner/Banner.stories.tsx +++ b/libs/react-components/src/lib/components/Banner/Banner.stories.tsx @@ -33,6 +33,7 @@ const meta = { imageSrc: 'https://www.teradata.com/getmedia/46d83f57-61b3-43aa-84a4-4cfbd408a1fa/roles-business_leader.svg?origin=fd', title: 'Train ML models in Vantage', + isHero: false, }, } satisfies Meta; @@ -40,3 +41,14 @@ export default meta; type Story = StoryObj; export const Basic: Story = {}; + +export const Hero: Story = { + args: { + title: 'Welcome to the Teradata Developers Portal', + content: + 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequa.', + isHero: true, + imageSrc: + 'https://s3-alpha-sig.figma.com/img/07ea/17f4/495f02efa84e03a9d184758288dce2f0?Expires=1719187200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=FNLOp0rxTclfS4rHH5J0Yg42soFr1apjc9FvPr1T2qAMIBQE5vR3fdyikaiJOXb1oW2jWsXZXHWLjXO4smprKq0Lq~Z8vwZXio5IY-1~ss3ptWNM-EqVRaM6w-XOXcTeJLfE4NlV2b2F5f8bGTcTrmwY9ZKr6-hnQPbIXvdc85ApLPGNe3XawzMxxDf90~yEgkTD9zsgfV70vcLfxk7zhTVZpqdwrRXTZIvHStOh-VgYLUFahZTUEAazIQ67nfT9lDyrjP2x9~dD~uy6pj-PE~ox00ZlwFB5eKMUa3ZQeRY9GuRdBmysY8fFUXcqTynBdMBGj8OazN54WySG~sPw8Q__', + }, +}; diff --git a/libs/react-components/src/lib/components/Banner/index.tsx b/libs/react-components/src/lib/components/Banner/index.tsx index d2ac0c8..5050667 100644 --- a/libs/react-components/src/lib/components/Banner/index.tsx +++ b/libs/react-components/src/lib/components/Banner/index.tsx @@ -1,5 +1,6 @@ import React, { ReactNode } from 'react'; import styles from './styles.module.scss'; +import Typography from '../Typography'; interface BannerProps { /** @@ -14,6 +15,10 @@ interface BannerProps { * Alt text for the banner image. */ imageAltText?: string; + /** + * Whether it is a hero banner. + */ + isHero?: boolean; /** * Title of the banner. */ @@ -24,13 +29,18 @@ const Banner: React.FC = ({ content = '', imageSrc = '', imageAltText = 'Banner Image', + isHero = false, title = '', }) => { return ( -
+
-

{title}

-
{content}
+ + {title} + + +
{content}
+
{imageAltText}
diff --git a/libs/react-components/src/lib/components/Banner/styles.module.scss b/libs/react-components/src/lib/components/Banner/styles.module.scss index 991e026..abfaee7 100644 --- a/libs/react-components/src/lib/components/Banner/styles.module.scss +++ b/libs/react-components/src/lib/components/Banner/styles.module.scss @@ -9,31 +9,44 @@ justify-content: space-between; margin: 0 auto; max-width: 1440px; - min-width: 100%; -} - -.bannerTitle { - color: var(--td-web-primary-navy); - font-size: var(--mdc-typography-headline5-font-size); - font-weight: var(--mdc-typography-headline3-font-weight); - letter-spacing: -0.24px; - line-height: var(--mdc-typography-headline4-font-size); - margin: 0; + width: 100%; } .bannerContent { - color: var(--td-web-gray-700); - font-size: 1.125rem; margin-top: 1rem; } .bannerInfo, .bannerImage { + box-sizing: border-box; flex: 1 0 100%; max-width: 100%; width: 100%; } +.bannerHero { + gap: 0; + + .bannerInfo, + .bannerImage { + border-radius: 12px; + } + + .bannerInfo { + background-color: var(--cv-theme-surface-container-lowest); + border: 1px solid var(--td-web-gray-100); + margin-top: -28px; + padding: 40px; + width: 90%; + } +} + +@media only screen and (min-width: 600px) { + .bannerHero .bannerInfo { + margin-top: -82px; + } +} + @media screen and (min-width: 768px) { .banner { flex-direction: row; @@ -44,6 +57,19 @@ max-width: calc(47.5% - 50px); } + .bannerHero { + .bannerImage { + max-width: calc(85.5% - 50px); + margin-left: auto; + } + + .bannerInfo { + margin-top: 0; + margin-right: -50%; + z-index: 1; + } + } + .bannerInfo { flex: 1 0 50%; max-width: 50%; diff --git a/libs/react-components/src/lib/components/Typography/Typography.stories.tsx b/libs/react-components/src/lib/components/Typography/Typography.stories.tsx new file mode 100644 index 0000000..d0c6b5b --- /dev/null +++ b/libs/react-components/src/lib/components/Typography/Typography.stories.tsx @@ -0,0 +1,38 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import Typography from './index'; + +const meta = { + title: 'Components/Typography', + component: Typography, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs + tags: ['autodocs'], + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout + layout: 'fullscreen', + }, + argTypes: { + scale: { + options: [ + 'body1', + 'body2', + 'body3', + 'headline1', + 'headline2', + 'headline3', + 'caption', + 'eyebrow', + ], + control: { type: 'select' }, + }, + }, + args: { scale: 'headline1' }, + render: (args) => { + return Change the scale value.; + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Basic: Story = {}; diff --git a/libs/react-components/src/lib/components/Typography/index.tsx b/libs/react-components/src/lib/components/Typography/index.tsx new file mode 100644 index 0000000..f94e5f9 --- /dev/null +++ b/libs/react-components/src/lib/components/Typography/index.tsx @@ -0,0 +1,29 @@ +import React, { ReactNode } from 'react'; +import styles from './styles.module.scss'; + +interface TypographyProps { + /** + * Scale or type of the text. + */ + scale: + | 'body1' + | 'body2' + | 'body3' + | 'headline1' + | 'headline2' + | 'headline3' + | 'caption' + | 'eyebrow'; + children?: ReactNode; +} + +const Typography: React.FC = ({ + scale = 'body1', + children, +}) => { + return ( + {children} + ); +}; + +export default Typography; diff --git a/libs/react-components/src/lib/components/Typography/styles.module.scss b/libs/react-components/src/lib/components/Typography/styles.module.scss new file mode 100644 index 0000000..83ff437 --- /dev/null +++ b/libs/react-components/src/lib/components/Typography/styles.module.scss @@ -0,0 +1,136 @@ +%headline-styles { + font-style: normal; // Common style + color: var(--td-web-primary-navy); +} + +%body-styles { + font-style: normal; // Common style + color: var(--td-web-gray-700); +} + +.typography { + display: block; +} + +.headline1 { + @extend %headline-styles; + /* Desktop/H1 */ + font-family: var(--td-web-typography-headline1-font-family); + font-size: var(--td-web-typography-headline1-font-size); + font-weight: var(--td-web-typography-headline1-font-weight); + line-height: var(--td-web-typography-headline1-line-height); + letter-spacing: var(--td-web-typography-headline1-letter-spacing); +} + +.headline2 { + @extend %headline-styles; + /* Desktop/H2 */ + font-family: var(--td-web-typography-headline2-font-family); + font-size: var(--td-web-typography-headline2-font-size); + font-weight: var(--td-web-typography-headline2-font-weight); + line-height: var(--td-web-typography-headline2-line-height); + letter-spacing: var(--td-web-typography-headline2-letter-spacing); +} + +.headline3 { + @extend %headline-styles; + /* Desktop/H2 */ + font-family: var(--td-web-typography-headline3-font-family); + font-size: var(--td-web-typography-headline3-font-size); + font-weight: var(--td-web-typography-headline3-font-weight); + line-height: var(--td-web-typography-headline3-line-height); + letter-spacing: var(--td-web-typography-headline3-letter-spacing); +} + +.body1 { + @extend %body-styles; + /* Desktop/Body 1 - Regular */ + font-family: var(--td-web-typography-body-font-family); + font-size: var(--td-web-typography-body1-font-size); + font-weight: var(--td-web-typography-body-font-weight); + line-height: var(--td-web-typography-body1-line-height); +} + +.body2 { + @extend %body-styles; + /* Desktop/Body 2 - Regular */ + font-family: var(--td-web-typography-body-font-family); + font-size: var(--td-web-typography-body2-font-size); + font-weight: var(--td-web-typography-body-font-weight); + line-height: var(--td-web-typography-body2-line-height); +} + +.body3 { + color: var(--td-web-foreground-icon); + /* Desktop/Body 3 - Regular */ + font-family: var(--td-web-typography-body-font-family); + font-size: var(--td-web-typography-body3-font-size); + font-weight: var(--td-web-typography-body-font-weight); + line-height: var(--td-web-typography-body3-line-height); +} + +.caption, +.eyebrow { + @extend %headline-styles; + /* Desktop/Caption/Bold */ + font-family: var(--td-web-typography-caption-font-family); + font-size: var(--td-web-typography-caption-font-size); + font-weight: var(--td-web-typography-caption-font-weight); + line-height: var(--td-web-typography-caption-line-height); +} + +.eyebrow { + align-items: center; + display: flex; + flex-direction: column; + gap: 8px; + + &::after { + background-color: var(--cv-theme-tertiary); + border-radius: 2px; + content: ''; + height: 2px; + width: 20px; + } +} + +/* Mobile styles */ +@media only screen and (max-width: 767px) { + .headline1 { + font-size: var(--td-web-typography-headline1-mb-font-size); + line-height: var(--td-web-typography-headline1-mb-line-height); + letter-spacing: var(--td-web-typography-headline1-mb-letter-spacing); + } + + .headline2 { + font-size: calc(var(--td-web-typography-headline3-font-size) + 2px); + line-height: calc(var(--td-web-typography-headline3-line-height) + 2px); + letter-spacing: var(--td-web-typography-headline2-mb-letter-spacing); + } + + .headline3 { + font-size: var(--td-web-typography-body2-font-size); + line-height: var(--td-web-typography-body1-line-height); + } + + .body1 { + font-size: var(--td-web-typography-body2-font-size); + line-height: var(--td-web-typography-body2-line-height); + } + + .body2 { + font-size: var(--td-web-typography-body3-font-size); + line-height: var(--td-web-typography-body3-line-height); + } + + .body3 { + font-size: calc(var(--td-web-typography-body3-font-size) - 2px); + line-height: calc(var(--td-web-typography-body3-line-height) - 2px); + } + + .caption, + .eyebrow { + font-size: calc(var(--td-web-typography-caption-font-size) - 1px); + line-height: calc(var(--td-web-typography-caption-line-height) - 1px); + } +} diff --git a/libs/react-components/src/lib/styles.scss b/libs/react-components/src/lib/styles.scss index 12e8715..4e8c09b 100644 --- a/libs/react-components/src/lib/styles.scss +++ b/libs/react-components/src/lib/styles.scss @@ -33,12 +33,61 @@ $dark-colors: map-merge($dark-colors, map-get(covalent-tokens.$tokens, 'dark')); @include covalent-theme.components-theme($light-colors, $typography); @include code-tokens($typography); - // Color tokens which are not part of covalent + // Tokens which are not part of covalent + --td-web-foreground-icon: #00000099; --td-web-gray-25: #f6f7fb; --td-web-gray-100: #ced3da; --td-web-gray-300: #b2b9c0; --td-web-gray-700: #333a3e; --td-web-primary-navy: #00233c; + + // Typography tokens + --td-web-typography-body-font-family: Inter; + --td-web-typography-body-font-weight: 400; + + --td-web-typography-body1-font-size: 20px; + --td-web-typography-body1-line-height: 28px; + + --td-web-typography-body2-font-size: calc( + var(--td-web-typography-body1-font-size) - 2px + ); + --td-web-typography-body2-line-height: calc( + var(--td-web-typography-body1-line-height) - 2px + ); + + --td-web-typography-body3-font-size: calc( + var(--td-web-typography-body1-font-size) - 4px + ); + --td-web-typography-body3-line-height: calc( + var(--td-web-typography-body1-line-height) - 4px + ); + + --td-web-typography-caption-font-family: Inter; + --td-web-typography-caption-font-size: 16px; + --td-web-typography-caption-font-weight: 600; + --td-web-typography-caption-line-height: 20px; + + --td-web-typography-headline1-font-family: Inter; + --td-web-typography-headline1-font-size: 54px; + --td-web-typography-headline1-font-weight: 300; + --td-web-typography-headline1-letter-spacing: -1.62px; + --td-web-typography-headline1-line-height: 64px; + --td-web-typography-headline1-mb-font-size: 32px; + --td-web-typography-headline1-mb-letter-spacing: -0.96px; + --td-web-typography-headline1-mb-line-height: 42px; + + --td-web-typography-headline2-font-family: Inter; + --td-web-typography-headline2-font-size: 42px; + --td-web-typography-headline2-font-weight: 300; + --td-web-typography-headline2-letter-spacing: -1.26px; + --td-web-typography-headline2-line-height: 52px; + --td-web-typography-headline2-mb-letter-spacing: -0.78px; + + --td-web-typography-headline3-font-family: Inter; + --td-web-typography-headline3-font-size: 24px; + --td-web-typography-headline3-font-weight: 600; + --td-web-typography-headline3-letter-spacing: -0.24px; + --td-web-typography-headline3-line-height: 34px; } // Dark theme class