diff --git a/src/components.d.ts b/src/components.d.ts index 22f9cd9c92aed79a70b1deb50cbe74777957f420..40953f94d873d8aa019c8331688976b186f0f8ca 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -263,6 +263,12 @@ export namespace Components { courseTeachingLanguage?: string; variant: CourseVariants; } + interface HyCrisisBanner { + bannerDescription?: string; + bannerTitle: string; + linkTitle?: string; + linkUrl?: string; + } interface HyCtaButton { headerstyle: string; isExternal: boolean; @@ -917,6 +923,11 @@ declare global { prototype: HTMLHyContentListItemElement; new (): HTMLHyContentListItemElement; }; + interface HTMLHyCrisisBannerElement extends Components.HyCrisisBanner, HTMLStencilElement {} + var HTMLHyCrisisBannerElement: { + prototype: HTMLHyCrisisBannerElement; + new (): HTMLHyCrisisBannerElement; + }; interface HTMLHyCtaButtonElement extends Components.HyCtaButton, HTMLStencilElement {} var HTMLHyCtaButtonElement: { prototype: HTMLHyCtaButtonElement; @@ -1284,6 +1295,7 @@ declare global { 'hy-checkbox': HTMLHyCheckboxElement; 'hy-content-list': HTMLHyContentListElement; 'hy-content-list-item': HTMLHyContentListItemElement; + 'hy-crisis-banner': HTMLHyCrisisBannerElement; 'hy-cta-button': HTMLHyCtaButtonElement; 'hy-cta-link': HTMLHyCtaLinkElement; 'hy-desktop-menu-links': HTMLHyDesktopMenuLinksElement; @@ -1564,6 +1576,12 @@ declare namespace LocalJSX { courseTeachingLanguage?: string; variant?: CourseVariants; } + interface HyCrisisBanner { + bannerDescription?: string; + bannerTitle?: string; + linkTitle?: string; + linkUrl?: string; + } interface HyCtaButton { headerstyle?: string; isExternal?: boolean; @@ -2176,6 +2194,7 @@ declare namespace LocalJSX { 'hy-checkbox': HyCheckbox; 'hy-content-list': HyContentList; 'hy-content-list-item': HyContentListItem; + 'hy-crisis-banner': HyCrisisBanner; 'hy-cta-button': HyCtaButton; 'hy-cta-link': HyCtaLink; 'hy-desktop-menu-links': HyDesktopMenuLinks; @@ -2266,6 +2285,7 @@ declare module '@stencil/core' { 'hy-checkbox': LocalJSX.HyCheckbox & JSXBase.HTMLAttributes<HTMLHyCheckboxElement>; 'hy-content-list': LocalJSX.HyContentList & JSXBase.HTMLAttributes<HTMLHyContentListElement>; 'hy-content-list-item': LocalJSX.HyContentListItem & JSXBase.HTMLAttributes<HTMLHyContentListItemElement>; + 'hy-crisis-banner': LocalJSX.HyCrisisBanner & JSXBase.HTMLAttributes<HTMLHyCrisisBannerElement>; 'hy-cta-button': LocalJSX.HyCtaButton & JSXBase.HTMLAttributes<HTMLHyCtaButtonElement>; 'hy-cta-link': LocalJSX.HyCtaLink & JSXBase.HTMLAttributes<HTMLHyCtaLinkElement>; 'hy-desktop-menu-links': LocalJSX.HyDesktopMenuLinks & JSXBase.HTMLAttributes<HTMLHyDesktopMenuLinksElement>; diff --git a/src/components/hy-crisis-banner/hy-crisis-banner.scss b/src/components/hy-crisis-banner/hy-crisis-banner.scss new file mode 100644 index 0000000000000000000000000000000000000000..29d375deed40ffcddc9f4668099851860bfb432d --- /dev/null +++ b/src/components/hy-crisis-banner/hy-crisis-banner.scss @@ -0,0 +1,195 @@ +:host { + box-shadow: inset 0 -20px 20px -20px rgba(14, 104, 139, 0.1); + display: block; +} + +.hy-crisis-banner__container { + display: flex; + margin: 0 auto; + max-width: 1216px; +} + +.hy-crisis-banner__indicator { + background-color: var(--additional-yellow); + flex-shrink: 0; + + @include breakpoint($narrow) { + align-items: center; + display: flex; + justify-content: center; + } +} + +.hy-crisis-banner__indicator-icon { + margin-left: 8px; + margin-right: 8px; + margin-top: 10px; + + @include breakpoint($narrow) { + margin-left: 10px; + margin-right: 10px; + margin-top: 0; + } + + svg { + height: 22px; + width: 22px; + + circle { + fill: var(--grayscale-white); + } + + path { + fill: var(--additional-yellow); + } + } +} + +.hy-crisis-banner__content-wrapper { + align-items: baseline; + display: flex; + flex-direction: column; + flex-grow: 1; + padding: 12px 0 12px 12px; + + @include breakpoint($narrow) { + align-items: center; + flex-direction: row; + justify-content: space-between; + padding: 14px 0 14px 14px; + } + + @include breakpoint($wide) { + padding: 20px 0 20px 20px; + } +} + +.hy-crisis-banner__content { + @include breakpoint($narrow) { + max-width: 61.22%; + width: 100%; + } + + @include breakpoint($wide) { + max-width: 65.83%; + } + + @include breakpoint($extrawide) { + max-width: 65.79%; + } +} + +.hy-crisis-banner__title { + @include font-size(14px, 16px); + color: var(--grayscale-black); + font-family: var(--main-font-family); + font-weight: 600; + letter-spacing: -0.07px; + margin: 0; + + @include breakpoint($narrow) { + @include font-size(16px, 20px); + letter-spacing: -0.08px; + } + + @include breakpoint($wide) { + @include font-size(20px, 26px); + letter-spacing: -0.1px; + } +} + +.hy-crisis-banner__description { + @include font-size(14px, 16px); + color: var(--grayscale-black); + font-family: var(--main-font-family); + font-weight: 600; + letter-spacing: -0.07px; + margin: 0; + + @include breakpoint($narrow) { + @include font-size(16px, 20px); + letter-spacing: -0.08px; + } + + @include breakpoint($wide) { + @include font-size(20px, 26px); + letter-spacing: -0.1px; + } + + p { + margin-top: 0; + + &:last-of-type { + margin-bottom: 0; + } + } +} + +.hy-crisis-banner__link { + @include font-size(14px, 19px); + align-items: center; + color: var(--brand-main-light); + display: inline-flex; + font-family: var(--main-font-family); + font-weight: 600; + letter-spacing: -0.07px; + margin-left: auto; + margin-top: 12px; + text-decoration: none; + + @include breakpoint($narrow) { + @include font-size(16px, 22px); + flex-shrink: 0; + letter-spacing: -0.08px; + margin-left: 24px; + margin-top: 0; + text-align: right; + } + + @include breakpoint($wide) { + @include font-size(20px, 32px); + letter-spacing: -0.1px; + } + + @include breakpoint($extrawide) { + margin-left: 32px; + } + + &:hover, + &:focus { + color: var(--brand-main); + text-decoration: underline; + + .hy-crisis-banner__link-icon svg { + fill: var(--brand-main); + } + } +} + +.hy-crisis-banner__link-icon { + margin-left: 4px; + + @include breakpoint($narrow) { + margin-left: 8px; + } + + @include breakpoint($extrawide) { + margin-left: 12px; + } + + svg { + fill: var(--brand-main-light); + height: 12px; + width: 11px; + + @include breakpoint($narrow) { + height: 14px; + width: 13px; + } + + @include breakpoint($wide) { + height: 16px; + width: 16px; + } + } +} diff --git a/src/components/hy-crisis-banner/hy-crisis-banner.tsx b/src/components/hy-crisis-banner/hy-crisis-banner.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ab3a678b0f05509eddcc41c5b54ed7ccff2ad663 --- /dev/null +++ b/src/components/hy-crisis-banner/hy-crisis-banner.tsx @@ -0,0 +1,39 @@ +import {Component, Host, h, Prop} from '@stencil/core'; + +@Component({ + tag: 'hy-crisis-banner', + styleUrl: 'hy-crisis-banner.scss', + shadow: true, +}) +export class HyCrisisBanner { + @Prop() bannerTitle: string; + @Prop() bannerDescription?: string; + @Prop() linkTitle?: string; + @Prop() linkUrl?: string; + + render() { + return ( + <Host class="hy-crisis-banner" role="alert"> + <div class="hy-crisis-banner__container"> + <div class="hy-crisis-banner__indicator"> + <hy-icon class={'hy-crisis-banner__indicator-icon'} icon={'hy-icon-alert'} /> + </div> + <div class="hy-crisis-banner__content-wrapper"> + <div class="hy-crisis-banner__content"> + <h3 class="hy-crisis-banner__title">{this.bannerTitle}</h3> + {this.bannerDescription && ( + <div class="hy-crisis-banner__description" innerHTML={this.bannerDescription}></div> + )} + </div> + {this.linkUrl && ( + <a class="hy-crisis-banner__link" href={this.linkUrl}> + {this.linkTitle} + <hy-icon class={'hy-crisis-banner__link-icon'} icon={'hy-icon-arrow-to-right'} /> + </a> + )} + </div> + </div> + </Host> + ); + } +} diff --git a/src/components/hy-crisis-banner/readme.md b/src/components/hy-crisis-banner/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..0424953fb08c6360de9202075df34e2d566173f9 --- /dev/null +++ b/src/components/hy-crisis-banner/readme.md @@ -0,0 +1,30 @@ +# hy-crisis-banner + +<!-- Auto Generated Below --> + +## Properties + +| Property | Attribute | Description | Type | Default | +| ------------------- | -------------------- | ----------- | -------- | ----------- | +| `bannerDescription` | `banner-description` | | `string` | `undefined` | +| `bannerTitle` | `banner-title` | | `string` | `undefined` | +| `linkTitle` | `link-title` | | `string` | `undefined` | +| `linkUrl` | `link-url` | | `string` | `undefined` | + +## Dependencies + +### Depends on + +- [hy-icon](../icon) + +### Graph + +```mermaid +graph TD; + hy-crisis-banner --> hy-icon + style hy-crisis-banner fill:#f9f,stroke:#333,stroke-width:4px +``` + +--- + +Helsinki University Design System diff --git a/src/components/hy-hero/hy-hero.scss b/src/components/hy-hero/hy-hero.scss index 92dc54c76328fd630644a41b713d69212706bd52..afbd0450a51a762b7ae2fc22afe634addbae1f3c 100644 --- a/src/components/hy-hero/hy-hero.scss +++ b/src/components/hy-hero/hy-hero.scss @@ -270,6 +270,18 @@ @include breakpoint($xlarge) { padding-left: 0; } + + @include breakpoint(1280px) { + padding-left: 0; + } + + @include breakpoint(1440px) { + min-height: 540px; + } + + @include breakpoint(1920px) { + min-height: 720px; + } } .hy-hero__image-container { @@ -391,8 +403,11 @@ min-height: 450px; } - @include breakpoint($xlarge) { + @include breakpoint(1280px) { max-width: 1216px; + } + + @include breakpoint($xlarge) { min-height: 500px; padding: 80px 0; } diff --git a/src/components/icon/Alert.tsx b/src/components/icon/Alert.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8e7ff4e25445f6c28d4f439f85ad21c89269c297 --- /dev/null +++ b/src/components/icon/Alert.tsx @@ -0,0 +1,12 @@ +import {h} from '@stencil/core'; + +function SvgAlert(props) { + return ( + <svg viewBox="0 0 32 32" {...props}> + <circle cx="16" cy="16" r="16" /> + <path d="M17.6,18.79H15l-.55-10.5h3.72Zm-3.21,3.67a1.8,1.8,0,0,1,.48-1.36,2,2,0,0,1,1.41-.46,1.94,1.94,0,0,1,1.38.47,1.83,1.83,0,0,1,.49,1.35,1.79,1.79,0,0,1-.5,1.34,1.84,1.84,0,0,1-1.37.49,1.93,1.93,0,0,1-1.4-.48A1.79,1.79,0,0,1,14.39,22.46Z" /> + </svg> + ); +} + +export default SvgAlert; diff --git a/src/components/icon/icon.tsx b/src/components/icon/icon.tsx index 677abac7edc74c38da891eb265ec69143cd9cb3b..7923a25d264b38a63ff35af1d9b14cf2c28a7a46 100644 --- a/src/components/icon/icon.tsx +++ b/src/components/icon/icon.tsx @@ -8,6 +8,7 @@ const iconNames: IconName = { 'hy-icon-arrow-left': (p) => <icons.IconArrowLeft {...p} />, 'hy-icon-arrow-right': (p) => <icons.IconArrowRight {...p} />, 'hy-icon-arrow-to-right': (p) => <icons.IconArrowToRight {...p} />, + 'hy-icon-alert': (p) => <icons.Alert {...p} />, 'hy-icon-arrow-up': (p) => <icons.ArrowUp {...p} />, 'hy-icon-camera': (p) => <icons.Camera {...p} />, 'hy-icon-caret-down': (p) => <icons.CaretDown {...p} />, diff --git a/src/components/icon/icons.tsx b/src/components/icon/icons.tsx index ca109255a218e9772cc352bfcabca7d2afef1698..3e7fbf85bf2e309480f9140182d034fb42bf0855 100644 --- a/src/components/icon/icons.tsx +++ b/src/components/icon/icons.tsx @@ -55,6 +55,7 @@ export const IconQuote: FunctionalComponent = (props: any) => { }; export {default as AddToTodoList} from './AddToTodoList'; +export {default as Alert} from './Alert'; export {default as ArrowDown} from './ArrowDown'; export {default as ArrowUp} from './ArrowUp'; export {default as Arrow} from './Arrow'; diff --git a/src/components/icon/readme.md b/src/components/icon/readme.md index ccd10150fd514cf1f8657e311293101c7c0f7513..26a9d79ddd4cd58a379350ea11e06f459780c13b 100644 --- a/src/components/icon/readme.md +++ b/src/components/icon/readme.md @@ -19,6 +19,7 @@ - [hy-button](../button) - [hy-checkbox](../hy-checkbox) - [hy-content-list-item](../courses/hy-content-list-item) +- [hy-crisis-banner](../hy-crisis-banner) - [hy-cta-button](../cta-button) - [hy-cta-link](../cta-link) - [hy-desktop-menu-links](../site-header/hy-desktop-menu-links) @@ -59,6 +60,7 @@ graph TD; hy-button --> hy-icon hy-checkbox --> hy-icon hy-content-list-item --> hy-icon + hy-crisis-banner --> hy-icon hy-cta-button --> hy-icon hy-cta-link --> hy-icon hy-desktop-menu-links --> hy-icon