From 2e1be95e1aa9828d1d3aeebd32ee15d9cdff9fa4 Mon Sep 17 00:00:00 2001 From: Angelo Veltens Date: Wed, 8 Feb 2023 17:21:15 +0100 Subject: [PATCH] feat: pos-value element to render any predicate value --- docs/elements/components/pos-value/readme.md | 24 ++++++++++++++ elements/CHANGELOG.md | 3 +- elements/src/components.d.ts | 26 +++++++++++++++ .../components/pos-value/pos-value.spec.tsx | 32 +++++++++++++++++++ .../src/components/pos-value/pos-value.tsx | 30 +++++++++++++++++ .../stories/values/1_pos-value.stories.mdx | 30 +++++++++++++++++ .../{ => values}/2_pos-label.stories.mdx | 2 +- .../3_pos-description.stories.mdx | 2 +- 8 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 docs/elements/components/pos-value/readme.md create mode 100644 elements/src/components/pos-value/pos-value.spec.tsx create mode 100644 elements/src/components/pos-value/pos-value.tsx create mode 100644 storybook/stories/values/1_pos-value.stories.mdx rename storybook/stories/{ => values}/2_pos-label.stories.mdx (96%) rename storybook/stories/{ => values}/3_pos-description.stories.mdx (96%) diff --git a/docs/elements/components/pos-value/readme.md b/docs/elements/components/pos-value/readme.md new file mode 100644 index 0000000..9e8f378 --- /dev/null +++ b/docs/elements/components/pos-value/readme.md @@ -0,0 +1,24 @@ +# pos-value + +Render a value for a given predicate + + + + +## Properties + +| Property | Attribute | Description | Type | Default | +| ----------- | ----------- | ------------------------------------------ | -------- | ----------- | +| `predicate` | `predicate` | URI of the predicate to get the value from | `string` | `undefined` | + + +## Events + +| Event | Description | Type | +| ----------------- | ----------- | ------------------ | +| `pod-os:resource` | | `CustomEvent` | + + +---------------------------------------------- + +*Built with [StencilJS](https://stenciljs.com/)* diff --git a/elements/CHANGELOG.md b/elements/CHANGELOG.md index 608541a..4616cb0 100644 --- a/elements/CHANGELOG.md +++ b/elements/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - New event `pod-os:resource-loaded` is fired after `pos-resource`, `pos-image` or `pos-document` finished loading the requested resource. +- [pos-value](../docs/elements/components/pos-value): A component to render a value for a given predicate ## 0.10.0 @@ -38,7 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - [pos-app-pdf-viewer](../docs/elements/apps/pos-app-pdf-viewer): A viewer for pdf document resources - [pos-pdf](../docs/elements/components/pos-pdf): A component to render a PDF document -- + ### Changed - [pos-type-router](../docs/elements/components/pos-type-router): Route to pos-app-pdf-viewer for pdf resources diff --git a/elements/src/components.d.ts b/elements/src/components.d.ts index 3164555..3c88c37 100644 --- a/elements/src/components.d.ts +++ b/elements/src/components.d.ts @@ -65,6 +65,12 @@ export namespace Components { } interface PosTypeRouter { } + interface PosValue { + /** + * URI of the predicate to get the value from + */ + "predicate": string; + } } export interface PosAppDocumentViewerCustomEvent extends CustomEvent { detail: T; @@ -142,6 +148,10 @@ export interface PosTypeRouterCustomEvent extends CustomEvent { detail: T; target: HTMLPosTypeRouterElement; } +export interface PosValueCustomEvent extends CustomEvent { + detail: T; + target: HTMLPosValueElement; +} declare global { interface HTMLPosAppElement extends Components.PosApp, HTMLStencilElement { } @@ -293,6 +303,12 @@ declare global { prototype: HTMLPosTypeRouterElement; new (): HTMLPosTypeRouterElement; }; + interface HTMLPosValueElement extends Components.PosValue, HTMLStencilElement { + } + var HTMLPosValueElement: { + prototype: HTMLPosValueElement; + new (): HTMLPosValueElement; + }; interface HTMLElementTagNameMap { "pos-app": HTMLPosAppElement; "pos-app-browser": HTMLPosAppBrowserElement; @@ -319,6 +335,7 @@ declare global { "pos-subjects": HTMLPosSubjectsElement; "pos-type-badges": HTMLPosTypeBadgesElement; "pos-type-router": HTMLPosTypeRouterElement; + "pos-value": HTMLPosValueElement; } } declare namespace LocalJSX { @@ -412,6 +429,13 @@ declare namespace LocalJSX { interface PosTypeRouter { "onPod-os:resource"?: (event: PosTypeRouterCustomEvent) => void; } + interface PosValue { + "onPod-os:resource"?: (event: PosValueCustomEvent) => void; + /** + * URI of the predicate to get the value from + */ + "predicate"?: string; + } interface IntrinsicElements { "pos-app": PosApp; "pos-app-browser": PosAppBrowser; @@ -438,6 +462,7 @@ declare namespace LocalJSX { "pos-subjects": PosSubjects; "pos-type-badges": PosTypeBadges; "pos-type-router": PosTypeRouter; + "pos-value": PosValue; } } export { LocalJSX as JSX }; @@ -469,6 +494,7 @@ declare module "@stencil/core" { "pos-subjects": LocalJSX.PosSubjects & JSXBase.HTMLAttributes; "pos-type-badges": LocalJSX.PosTypeBadges & JSXBase.HTMLAttributes; "pos-type-router": LocalJSX.PosTypeRouter & JSXBase.HTMLAttributes; + "pos-value": LocalJSX.PosValue & JSXBase.HTMLAttributes; } } } diff --git a/elements/src/components/pos-value/pos-value.spec.tsx b/elements/src/components/pos-value/pos-value.spec.tsx new file mode 100644 index 0000000..c233454 --- /dev/null +++ b/elements/src/components/pos-value/pos-value.spec.tsx @@ -0,0 +1,32 @@ +import { newSpecPage } from '@stencil/core/testing'; +import { PosValue } from './pos-value'; + +describe('pos-value', () => { + it('is empty initially', async () => { + const page = await newSpecPage({ + components: [PosValue], + html: ``, + }); + expect(page.root).toEqualHtml(` + + + + `); + }); + + it('renders property value from resource', async () => { + const page = await newSpecPage({ + components: [PosValue], + html: ``, + }); + await page.rootInstance.receiveResource({ + anyValue: uri => `value of ${uri}`, + }); + await page.waitForChanges(); + expect(page.root).toEqualHtml(` + + value of https://vocab.example/#term + + `); + }); +}); diff --git a/elements/src/components/pos-value/pos-value.tsx b/elements/src/components/pos-value/pos-value.tsx new file mode 100644 index 0000000..d885957 --- /dev/null +++ b/elements/src/components/pos-value/pos-value.tsx @@ -0,0 +1,30 @@ +import { Thing } from '@pod-os/core'; +import { Component, Event, Prop, State } from '@stencil/core'; +import { ResourceAware, ResourceEventEmitter, subscribeResource } from '../events/ResourceAware'; + +@Component({ + tag: 'pos-value', + shadow: true, +}) +export class PosValue implements ResourceAware { + /** + * URI of the predicate to get the value from + */ + @Prop() predicate: string; + @State() resource: Thing; + + @Event({ eventName: 'pod-os:resource' }) + subscribeResource: ResourceEventEmitter; + + componentWillLoad() { + subscribeResource(this); + } + + receiveResource = (resource: Thing) => { + this.resource = resource; + }; + + render() { + return this.resource ? this.resource.anyValue(this.predicate) : null; + } +} diff --git a/storybook/stories/values/1_pos-value.stories.mdx b/storybook/stories/values/1_pos-value.stories.mdx new file mode 100644 index 0000000..5db9bf6 --- /dev/null +++ b/storybook/stories/values/1_pos-value.stories.mdx @@ -0,0 +1,30 @@ +import {html} from "lit-html"; + +import { + Canvas, + Meta, + Story +} from '@storybook/addon-docs/blocks'; + + + + +## pos-value + +Renders any value for the given predicate of the resource. + + + + {({subject, predicate}) => html` + + + + `} + + diff --git a/storybook/stories/2_pos-label.stories.mdx b/storybook/stories/values/2_pos-label.stories.mdx similarity index 96% rename from storybook/stories/2_pos-label.stories.mdx rename to storybook/stories/values/2_pos-label.stories.mdx index 056152a..d448c1e 100644 --- a/storybook/stories/2_pos-label.stories.mdx +++ b/storybook/stories/values/2_pos-label.stories.mdx @@ -7,7 +7,7 @@ import { } from '@storybook/addon-docs/blocks'; diff --git a/storybook/stories/3_pos-description.stories.mdx b/storybook/stories/values/3_pos-description.stories.mdx similarity index 96% rename from storybook/stories/3_pos-description.stories.mdx rename to storybook/stories/values/3_pos-description.stories.mdx index 7e85f56..1214bcf 100644 --- a/storybook/stories/3_pos-description.stories.mdx +++ b/storybook/stories/values/3_pos-description.stories.mdx @@ -7,7 +7,7 @@ import { } from '@storybook/addon-docs/blocks';