diff --git a/src/components.d.ts b/src/components.d.ts index 41ef26cacb6d8dac7f25de89c32520b025811784..4af49c5a5d3712be32738a6051f3d72b204ef90a 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -43,6 +43,7 @@ import {IDropdownItem} from './components/hy-dropdown/hy-dropdown'; import {IFilterGroupFilter} from './components/hy-filter-group/hy-filter-group'; import {FooterBaseLinks, FooterBaseSome} from './components/footer/hy-footer-base/hy-footer-base'; import {FooterInfoLinks} from './components/footer/hy-footer-info/hy-footer-info'; +import {ListItemValue} from './components/hy-general-list/hy-general-list'; import {KeyFigureValue} from './components/hy-key-figure-group/hy-key-figure-group'; import {KeyHighlightValue} from './components/hy-key-highlight-group/hy-key-highlight-group'; import {ProcessFlowValue} from './components/hy-large-process-flow/hy-large-process-flow'; @@ -391,6 +392,18 @@ export namespace Components { url: string; variant: FooterLinkVariants; } + interface HyGeneralList { + dataItems: ListItemValue[] | string; + } + interface HyGeneralListItem { + description?: string; + imageAlt: string; + imageUrl: string; + itemTitle?: string; + label?: string; + type?: string; + url?: string; + } interface HyGridContainer {} interface HyGridItem { columns: GridColumns; @@ -1029,6 +1042,16 @@ declare global { prototype: HTMLHyFooterLinkItemElement; new (): HTMLHyFooterLinkItemElement; }; + interface HTMLHyGeneralListElement extends Components.HyGeneralList, HTMLStencilElement {} + var HTMLHyGeneralListElement: { + prototype: HTMLHyGeneralListElement; + new (): HTMLHyGeneralListElement; + }; + interface HTMLHyGeneralListItemElement extends Components.HyGeneralListItem, HTMLStencilElement {} + var HTMLHyGeneralListItemElement: { + prototype: HTMLHyGeneralListItemElement; + new (): HTMLHyGeneralListItemElement; + }; interface HTMLHyGridContainerElement extends Components.HyGridContainer, HTMLStencilElement {} var HTMLHyGridContainerElement: { prototype: HTMLHyGridContainerElement; @@ -1327,6 +1350,8 @@ declare global { 'hy-footer-base': HTMLHyFooterBaseElement; 'hy-footer-info': HTMLHyFooterInfoElement; 'hy-footer-link-item': HTMLHyFooterLinkItemElement; + 'hy-general-list': HTMLHyGeneralListElement; + 'hy-general-list-item': HTMLHyGeneralListItemElement; 'hy-grid-container': HTMLHyGridContainerElement; 'hy-grid-item': HTMLHyGridItemElement; 'hy-grid-row': HTMLHyGridRowElement; @@ -1719,6 +1744,18 @@ declare namespace LocalJSX { url?: string; variant?: FooterLinkVariants; } + interface HyGeneralList { + dataItems?: ListItemValue[] | string; + } + interface HyGeneralListItem { + description?: string; + imageAlt?: string; + imageUrl?: string; + itemTitle?: string; + label?: string; + type?: string; + url?: string; + } interface HyGridContainer {} interface HyGridItem { columns?: GridColumns; @@ -2241,6 +2278,8 @@ declare namespace LocalJSX { 'hy-footer-base': HyFooterBase; 'hy-footer-info': HyFooterInfo; 'hy-footer-link-item': HyFooterLinkItem; + 'hy-general-list': HyGeneralList; + 'hy-general-list-item': HyGeneralListItem; 'hy-grid-container': HyGridContainer; 'hy-grid-item': HyGridItem; 'hy-grid-row': HyGridRow; @@ -2335,6 +2374,8 @@ declare module '@stencil/core' { 'hy-footer-base': LocalJSX.HyFooterBase & JSXBase.HTMLAttributes<HTMLHyFooterBaseElement>; 'hy-footer-info': LocalJSX.HyFooterInfo & JSXBase.HTMLAttributes<HTMLHyFooterInfoElement>; 'hy-footer-link-item': LocalJSX.HyFooterLinkItem & JSXBase.HTMLAttributes<HTMLHyFooterLinkItemElement>; + 'hy-general-list': LocalJSX.HyGeneralList & JSXBase.HTMLAttributes<HTMLHyGeneralListElement>; + 'hy-general-list-item': LocalJSX.HyGeneralListItem & JSXBase.HTMLAttributes<HTMLHyGeneralListItemElement>; 'hy-grid-container': LocalJSX.HyGridContainer & JSXBase.HTMLAttributes<HTMLHyGridContainerElement>; 'hy-grid-item': LocalJSX.HyGridItem & JSXBase.HTMLAttributes<HTMLHyGridItemElement>; 'hy-grid-row': LocalJSX.HyGridRow & JSXBase.HTMLAttributes<HTMLHyGridRowElement>; diff --git a/src/components/hy-general-list-item/hy-general-list-item.scss b/src/components/hy-general-list-item/hy-general-list-item.scss new file mode 100644 index 0000000000000000000000000000000000000000..e4a5525dcd72c5e5d2c30f3c45b978485e13c89e --- /dev/null +++ b/src/components/hy-general-list-item/hy-general-list-item.scss @@ -0,0 +1,147 @@ +:host { + display: block; +} + +.hy-general-list-item { + font-family: var(--main-font-family); + margin-bottom: 1rem; +} + +.hy-general-list-item__link { + display: flex; + flex-direction: column; + position: relative; + text-decoration: none; + + @include breakpoint($narrow) { + flex-direction: row; + } + + &:hover { + cursor: pointer; + } + + &:hover, + &:focus { + .hy-general-list-item__type span { + background-color: var(--brand-main); + } + + .hy-general-list-item__title { + color: var(--brand-main); + text-decoration: underline; + } + } +} + +.hy-general-list-item__image-container { + display: flex; + justify-content: stretch; + margin: 0; + position: relative; + width: 100%; + + @include breakpoint(max-width 479px) { + display: none; + } + + @include breakpoint($narrow) { + max-width: 35.7%; + } + + @include breakpoint($wide) { + max-width: 23.13%; + } + + @include breakpoint($extrawide) { + max-width: 23.03%; + } + + img { + height: 100%; + object-fit: cover; + width: 100%; + } +} + +.hy-general-list-item__image { + background-color: #ececec; + width: 100%; + height: 100%; +} + +.hy-general-list-item__type { + background-color: var(--grayscale-background-box); + padding-top: 16px; + z-index: 10; + + @include breakpoint($narrow) { + background-color: transparent; + left: -8px; + padding-top: 0; + position: absolute; + top: 16px; + } + + span { + @include font-size(12px, 14px); + @include font-weight($bold); + background-color: var(--grayscale-black); + color: #ffffff; + letter-spacing: -0.1px; + padding: 5px 8px; + text-transform: uppercase; + align-self: baseline; + margin-left: -8px; + + @include breakpoint($narrow) { + margin-left: 0; + } + } +} + +.hy-general-list-item__text-container { + background-color: var(--grayscale-background-box); + display: flex; + flex-direction: column; + flex-grow: 1; + padding: 16px 12px; + + @include breakpoint($wide) { + padding: 14px 32px 24px 24px; + } + + @include breakpoint($extrawide) { + padding: 20px 104px 32px 32px; + } +} + +.hy-general-list-item__title { + @include font-size(18px, 22px); + @include font-weight($bold); + color: var(--brand-main-nearly-black); + letter-spacing: -0.45px; + margin-bottom: 8px; + margin-top: 0; + + @include breakpoint($extrawide) { + @include font-size(20px, 24px); + letter-spacing: -0.5px; + } +} + +.hy-general-list-item__description { + @include font-size(15px, 20px); + color: var(--grayscale-dark); + letter-spacing: -0.09px; + margin: 0; + + @include breakpoint($narrow) { + @include font-size(14px, 18px); + letter-spacing: -0.08px; + } + + @include breakpoint($extrawide) { + @include font-size(14px, 20px); + } +} diff --git a/src/components/hy-general-list-item/hy-general-list-item.tsx b/src/components/hy-general-list-item/hy-general-list-item.tsx new file mode 100644 index 0000000000000000000000000000000000000000..9b99f9e9ca2d649bbf59fc19a108c193d8f26770 --- /dev/null +++ b/src/components/hy-general-list-item/hy-general-list-item.tsx @@ -0,0 +1,48 @@ +import {Component, Element, h, Prop} from '@stencil/core'; + +@Component({ + tag: 'hy-general-list-item', + styleUrl: 'hy-general-list-item.scss', + shadow: true, +}) +export class HyGeneralListItem { + @Prop() description?: string; + @Prop() imageAlt: string = ''; + @Prop() imageUrl: string = null; + @Prop() itemTitle?: string; + @Prop() label?: string; + @Prop() type?: string; + @Prop() url?: string; + + @Element() el: HTMLElement; + + render() { + const classAttributes = ['hy-general-list-item'].join(' '); + const contentClassAttributes = ['hy-general-list-item__text-container'].join(' '); + const imageClassAttributes = ['hy-general-list-item__image-container'].join(' '); + + const aspectRatioWidth = 16; + const aspectRatioHeight = 10; + const aspect = (aspectRatioHeight / aspectRatioWidth) * 100; + const aspectRatio = { + '--aspectRatio': `${aspect}%` as 'aspectRatio', + }; + + return ( + <article class={classAttributes}> + <a class="hy-general-list-item__link" href={this.url} target="_blank"> + <div class="hy-general-list-item__type"> + <span>{this.label}</span> + </div> + <figure class={imageClassAttributes} style={aspectRatio}> + <img alt={this.imageAlt} class="hy-general-list-item__image" src={this.imageUrl} /> + </figure> + <div class={contentClassAttributes}> + <h3 class="hy-general-list-item__title">{this.itemTitle}</h3> + <p class="hy-general-list-item__description">{this.description}</p> + </div> + </a> + </article> + ); + } +} diff --git a/src/components/hy-general-list-item/readme.md b/src/components/hy-general-list-item/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..1727f9869c4280d2ff6bc2997060d06fe621cae7 --- /dev/null +++ b/src/components/hy-general-list-item/readme.md @@ -0,0 +1,33 @@ +# hy-general-list-item + +<!-- Auto Generated Below --> + +## Properties + +| Property | Attribute | Description | Type | Default | +| ------------- | ------------- | ----------- | -------- | ----------- | +| `description` | `description` | | `string` | `undefined` | +| `imageAlt` | `image-alt` | | `string` | `''` | +| `imageUrl` | `image-url` | | `string` | `null` | +| `itemTitle` | `item-title` | | `string` | `undefined` | +| `label` | `label` | | `string` | `undefined` | +| `type` | `type` | | `string` | `undefined` | +| `url` | `url` | | `string` | `undefined` | + +## Dependencies + +### Used by + +- [hy-general-list](../hy-general-list) + +### Graph + +```mermaid +graph TD; + hy-general-list --> hy-general-list-item + style hy-general-list-item fill:#f9f,stroke:#333,stroke-width:4px +``` + +--- + +Helsinki University Design System diff --git a/src/components/hy-general-list/hy-general-list.scss b/src/components/hy-general-list/hy-general-list.scss new file mode 100644 index 0000000000000000000000000000000000000000..cd22a3a3e08ad8b986aeac89b2fb62c8d1fa456e --- /dev/null +++ b/src/components/hy-general-list/hy-general-list.scss @@ -0,0 +1,9 @@ +:host { + display: block; +} + +.hy-general-list { + list-style: none; + margin: 0; + padding: 0; +} diff --git a/src/components/hy-general-list/hy-general-list.tsx b/src/components/hy-general-list/hy-general-list.tsx new file mode 100644 index 0000000000000000000000000000000000000000..037bf9b5af9f798715f17b45d17fb12da9f11885 --- /dev/null +++ b/src/components/hy-general-list/hy-general-list.tsx @@ -0,0 +1,60 @@ +export interface ListItemValue { + description: string; + id: string; + imageAlt: string; + imageUrl: string; + label: string; + title: string; + type: string; + url: string; +} + +import {Component, Element, h, Prop, Watch} from '@stencil/core'; + +@Component({ + tag: 'hy-general-list', + styleUrl: 'hy-general-list.scss', + shadow: true, +}) +export class HyGeneralList { + @Prop() dataItems: ListItemValue[] | string; + private _dataItems: ListItemValue[]; + @Element() el: HTMLElement; + + @Watch('dataItems') + arrayDataWatcher(newValue: ListItemValue[] | string) { + if (typeof newValue === 'string') { + this._dataItems = JSON.parse(newValue); + } else { + this._dataItems = newValue; + } + } + + componentWillLoad() { + this.arrayDataWatcher(this.dataItems); + } + + render() { + const classAttributes = ['hy-general-list'].join(' '); + + return ( + <ul class={classAttributes}> + {this._dataItems.map((item) => ( + <li> + <hy-general-list-item + data-location={item.url} + description={item.description} + id={item.id} + imageAlt={item.imageAlt} + imageUrl={item.imageUrl} + item-title={item.title} + label={item.label} + type={item.type} + url={item.url} + ></hy-general-list-item> + </li> + ))} + </ul> + ); + } +} diff --git a/src/components/hy-general-list/readme.md b/src/components/hy-general-list/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..c36a4fa0f295562a8858aa977e25d0c2102038c1 --- /dev/null +++ b/src/components/hy-general-list/readme.md @@ -0,0 +1,27 @@ +# hy-general-list + +<!-- Auto Generated Below --> + +## Properties + +| Property | Attribute | Description | Type | Default | +| ----------- | ------------ | ----------- | --------------------------- | ----------- | +| `dataItems` | `data-items` | | `ListItemValue[] \| string` | `undefined` | + +## Dependencies + +### Depends on + +- [hy-general-list-item](../hy-general-list-item) + +### Graph + +```mermaid +graph TD; + hy-general-list --> hy-general-list-item + style hy-general-list fill:#f9f,stroke:#333,stroke-width:4px +``` + +--- + +Helsinki University Design System