Skip to content

Commit

Permalink
docs: storybook
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Nov 28, 2024
1 parent 27e95ea commit b06f7da
Show file tree
Hide file tree
Showing 16 changed files with 868 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ coverage/
dist/api/
dist/playground/
dist/shaperone-form/
dist/storybook/
!types/**/*.d.ts
*.log
!*.snap.js
32 changes: 32 additions & 0 deletions demos/storybook/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { join, dirname } from 'node:path'
import { StorybookConfig } from '@storybook/web-components-vite'

/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
const getAbsolutePath = (value: string) => {
return dirname(require.resolve(join(value, 'package.json')))
}

const config: StorybookConfig = {
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],

addons: [
getAbsolutePath('@storybook/addon-links'),
getAbsolutePath('@storybook/addon-essentials'),
],

framework: {
name: getAbsolutePath('@storybook/web-components-vite'),
options: {},
},

staticDirs: [
'../shapes',
'../../../node_modules/@shoelace-style/'
],

docs: {},
}
export default config
2 changes: 2 additions & 0 deletions demos/storybook/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet">
<link rel="stylesheet" href="/shoelace/cdn/themes/light.css" />
68 changes: 68 additions & 0 deletions demos/storybook/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { SyntaxHighlighter } from '@storybook/components'
import turtle from 'react-syntax-highlighter/dist/esm/languages/prism/turtle.js'
import { withActions } from '@storybook/addon-actions/decorator'
import $rdf from '../lib/env.js'
import stringToStream from 'string-to-stream'
import { Description, Stories, Subtitle, Title } from '@storybook/blocks'
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';

SyntaxHighlighter.registerLanguage('turtle', turtle)

setBasePath('/shoelace/dist');

const preview = {
tags: ['autodocs'],
parameters: {
controls: {
disableSaveFromUI: true,
},
actions: {
handles: ['foobar'],
},
docs: {
toc: {
headingSelector: 'h1, h2, h3',
},
page: () => (
<>
<Title/>
<Subtitle/>
<Description/>
<Stories/>
</>
),
},

},
decorators: [
withActions,
],
loaders: [async ({ args }: Record<any, any>) => {
let shapes = $rdf.clownface()
if (args.shapes) {
shapes = $rdf.clownface({
dataset: await $rdf.dataset()
.import($rdf.formats.parsers.import('text/turtle', stringToStream(args.shapes))!),
})

if(args.shape) {
shapes = shapes.namedNode(args.shape)
}
}

let data = $rdf.clownface()
if (args.data) {
data = $rdf.clownface({
dataset: await $rdf.dataset()
.import($rdf.formats.parsers.import('text/turtle', stringToStream(args.data))!),
})
}

return {
shapes,
data,
}
}],
}

export default preview
8 changes: 8 additions & 0 deletions demos/storybook/data/simple/john-doe.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
PREFIX schema: <http://schema.org/>
BASE <http://example.org/>

<john>
a schema:Person ;
schema:givenName "John" ;
schema:familyName "Doe" ;
.
9 changes: 9 additions & 0 deletions demos/storybook/lib/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Environment from '@zazuko/env/Environment.js'
import FetchFactory from '@rdfjs/fetch-lite/Factory.js'
import rdf from '@zazuko/env'
import formats from '@rdfjs-elements/formats-pretty'

const env = new Environment([FetchFactory], { parent: rdf })

env.formats.import(formats)
export default env
36 changes: 36 additions & 0 deletions demos/storybook/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "shaperone-stories",
"version": "0.0.0",
"private": "true",
"type": "module",
"scripts": {
"start": "storybook dev -p 6006 --no-open",
"build": "storybook build -o ../../dist/storybook --docs"
},
"dependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@hydrofoil/shaperone-wc": "^0.8.0",
"@rdfjs/fetch-lite": "^3.3.0",
"@rdfjs-elements/rdf-snippet": "^0.4.5",
"@rdfjs-elements/formats-pretty": "^0.6.7",
"@shoelace-style/shoelace": "^2.15.0",
"@storybook/addon-actions": "^8.4.5",
"@storybook/addon-essentials": "^8.4.5",
"@storybook/addon-links": "^8.4.5",
"@storybook/addon-storysource": "^8.4.5",
"@storybook/blocks": "^8.4.5",
"@storybook/components": "^8.4.5",
"@storybook/web-components": "^8.4.5",
"@storybook/web-components-vite": "^8.4.5",
"@vitejs/plugin-react": "^4.3.3",
"@zazuko/env": "^2",
"lit": "^2.8.0",
"react-syntax-highlighter": "^15.6.1",
"rollup-plugin-polyfill-node": "^0.13.0",
"storybook": "^8.4.5",
"string-to-stream": "^3.0.1"
},
"devDependencies": {
"@types/react-syntax-highlighter": "^15.5.13"
}
}
30 changes: 30 additions & 0 deletions demos/storybook/shapes/simple/datatypes.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX schema: <http://schema.org/>
PREFIX sh: <http://www.w3.org/ns/shacl#>

<>
a sh:NodeShape ;
sh:property
[
sh:name "Name" ;
sh:path schema:name ;
sh:datatype rdf:langString ;
sh:minCount 1 ;
sh:maxCount 1 ;
],
[
sh:name "Base Salary" ;
sh:path schema:baseSalary ;
sh:datatype xsd:decimal ;
sh:minCount 1 ;
sh:maxCount 1 ;
],
[
sh:name "Age" ;
sh:path schema:age ;
sh:datatype xsd:integer ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
.
24 changes: 24 additions & 0 deletions demos/storybook/shapes/simple/first-last.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
PREFIX ex: <http://example.org/>
PREFIX dash: <http://datashapes.org/dash#>
PREFIX schema: <http://schema.org/>
PREFIX sh: <http://www.w3.org/ns/shacl#>

ex:PersonShape
a sh:NodeShape ;
sh:targetClass schema:Person ;
sh:property
[
sh:name "First Name" ;
sh:path schema:givenName ;
dash:editor dash:TextFieldEditor ;
sh:minCount 1 ;
sh:maxCount 1 ;
],
[
sh:name "Last Name" ;
sh:path schema:familyName ;
dash:editor dash:TextFieldEditor ;
sh:minCount 1 ;
sh:maxCount 1 ;
] ;
.
26 changes: 26 additions & 0 deletions demos/storybook/shapes/simple/unrestricted.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
PREFIX ex: <http://example.org/>
PREFIX dash: <http://datashapes.org/dash#>
PREFIX schema: <http://schema.org/>
PREFIX sh: <http://www.w3.org/ns/shacl#>

# Like first-last.ttl, but without the minCount and maxCount constraints
ex:TestShape
a sh:NodeShape ;
sh:targetClass schema:Person ;
sh:property
[
sh:name "First Name" ;
sh:path schema:givenName ;
dash:editor dash:TextFieldEditor ;
],
[
sh:name "Last Name" ;
sh:path schema:familyName ;
dash:editor dash:TextFieldEditor ;
],
[
sh:name "Occupation" ;
sh:path schema:jobTitle ;
dash:editor dash:TextFieldEditor ;
] ;
.
104 changes: 104 additions & 0 deletions demos/storybook/stories/Getting Started.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import env from '../../../packages/core/env.ts?raw'
import { Markdown } from '@storybook/blocks'

# Getting Started

## Preparation

To start using `shaperone`, first install the Web Component library:

```shell
npm install @hydrofoil/shaperone-wc
```

Then, import the library in your project and call the `configure` function:

```javascript
import { configure } from '@hydrofoil/shaperone-wc';

configure()
```

This function registers the custom element `shaperone-form` and set up the necessary [RDF/JS Environment](https://rdf.js.org/).

In later examples, it is used to customise the form's appearance and behaviour.

## Using the form in a page

To render a form and then set its `shapes` and (optionally) `resource` properties.

The `shapes` can be an instance of [`DatasetCore`](https://rdf.js.org/dataset-spec/#datasetcore-interface) or a
[Clownface](https://npm.im/clownface) object.

The `resource` property must be a Clownface pointer to a [specific node in graph](https://zazuko.github.io/clownface/#/context?id=a-single-pointer).

```html
<shaperone-form></shaperone-form>

<script type="module">
import rdf from '@zazuko/env/web.js'
const form = document.querySelector('shaperone-form')
form.shapes = await rdf.fetch('/shapes.ttl').dataset()
form.resource = rdf.clownface().node('http://example.com/resource')
</script>
```

To retrieve the form's data, listen for the `changed` event:

```ts
import type { ShaperoneForm } from '@hydrofoil/shaperone-wc'

let form: ShaperoneForm

form.addEventListener('changed', (event: CustomEvent) => {
// event.detail.focusNode is a pointer to the current focus node

const dataset = event.detail.focusNode.dataset
})
```

# Advanced configuration

## Replace the RDF/JS environment

```javascript
import { configure } from '@hydrofoil/shaperone-wc'
import Environment from '@rdfjs/environment/Environment.js'

const env = new Environment([
//... add your own factories here
])

configure(env)
```

The minimum requirement is to provide an environment that implements the `MinimalEnvironment` type:

<Markdown>
{`
\`\`\`ts
${env.split('\n').slice(env.split('\n').findIndex(line => line.includes('type MinimalEnvironment')), env.split('\n').findIndex((line, index, arr) => index >= arr.findIndex(line => line.includes('type MiminalEnvironment')) && line.includes('>')) + 1).join('\n')}
\`\`\`
`}
</Markdown>

If not provided, the environment `@zazuko/env/web.js` is used.

## Customise the form

The `configure` function is async and its return value can be used to customise the form further.

```javascript
import { configure } from '@hydrofoil/shaperone-wc'

const {
renderer, // Change the form's appearance
components, // Add or repalce editor implementations
editors, // Modify the editors' metadata and priorities
validation // Set up validation
} = await configure()
```

See the in-depth pages on the left for more information on how to customise the form.
Loading

0 comments on commit b06f7da

Please sign in to comment.