@ulb-darmstadt/shacl-form 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,5 @@
1
1
  # SHACL Form Generator
2
-
3
- ```console
4
- npm i @ulb-darmstadt/shacl-form
5
- ```
6
-
7
- HTML5 web component for editing/viewing [RDF](https://www.w3.org/RDF/) data that conform to [SHACL shapes](https://www.w3.org/TR/shacl/).
2
+ An HTML5 web component to edit and view [RDF](https://www.w3.org/RDF/) data that conform to [SHACL shapes](https://www.w3.org/TR/shacl/).
8
3
 
9
4
  ## [See demo here](https://ulb-darmstadt.github.io/shacl-form/)
10
5
 
@@ -13,13 +8,13 @@ HTML5 web component for editing/viewing [RDF](https://www.w3.org/RDF/) data that
13
8
  ```html
14
9
  <html>
15
10
  <head>
16
- <!-- load bundled web component (or when developing your own app, just do "npm i @ulb-darmstadt/shacl-form") -->
11
+ <!-- load the bundled web component (for app development, use: npm i @ulb-darmstadt/shacl-form) -->
17
12
  <script src="https://cdn.jsdelivr.net/npm/@ulb-darmstadt/shacl-form/dist/bundle.js" type="module"></script>
18
13
  </head>
19
14
  <body>
20
15
  <!--
21
- SHACL shapes can be defined on the attribute 'data-shapes'
22
- or can be loaded by setting attribute 'data-shapes-url'
16
+ Provide SHACL shapes via the data-shapes attribute
17
+ or load them from a URL with data-shapes-url.
23
18
  -->
24
19
  <shacl-form data-shapes="
25
20
  @prefix sh: <http://www.w3.org/ns/shacl#> .
@@ -40,9 +35,8 @@ HTML5 web component for editing/viewing [RDF](https://www.w3.org/RDF/) data that
40
35
  form.addEventListener('change', event => {
41
36
  // check if form data validates according to the SHACL shapes
42
37
  if (event.detail?.valid) {
43
- // get data graph as RDF triples and
44
- // log them to the browser console
45
- const triples = form.serialize()
38
+ // serialize the RDF graph and log it
39
+ const triples = form.serialize()
46
40
  console.log('entered form data', triples)
47
41
  // store the data somewhere, e.g. in a triple store
48
42
  }
@@ -51,33 +45,63 @@ HTML5 web component for editing/viewing [RDF](https://www.w3.org/RDF/) data that
51
45
  </body>
52
46
  </html>
53
47
  ```
48
+ ## Install and use in your project
49
+
50
+ Install the package:
51
+
52
+ ```console
53
+ npm i @ulb-darmstadt/shacl-form
54
+ ```
55
+
56
+ This package has peer dependencies; install them in your app as well:
57
+
58
+ ```console
59
+ npm i @ro-kit/ui-widgets jsonld leaflet leaflet-editable leaflet.fullscreen n3 rdfxml-streaming-parser shacl-engine uuid
60
+ ```
61
+
62
+ Load the web component in your app. For a Vite/webpack-style project, import it once at startup:
63
+
64
+ ```ts
65
+ import '@ulb-darmstadt/shacl-form'
66
+ ```
67
+
68
+ Then use the element in your HTML:
69
+
70
+ ```html
71
+ <shacl-form data-shapes="..."></shacl-form>
72
+ ```
73
+
74
+ Alternatively, load the prebuilt bundle directly in a plain HTML page, as shown above:
75
+
76
+ ```html
77
+ <script src="https://cdn.jsdelivr.net/npm/@ulb-darmstadt/shacl-form/dist/bundle.js" type="module"></script>
78
+ ```
54
79
 
55
80
  ### Element attributes
56
81
 
57
82
  Attribute | Description
58
83
  ---|---
59
- data-shapes | SHACL shape definitions (e.g. a turtle string) to generate the form from
60
- data-shapes-url | When `data-shapes` is not set, the SHACL shapes are loaded from this URL
61
- data-shape-subject | Optional subject (id) of the SHACL node shape to use as root for the form. If not set, the first found node shape will be used
62
- data-values | RDF triples (e.g. a turtle string) to use as existing data graph to fill the form
63
- data-values-url | When `data-values` is not set, the data graph triples are loaded from this URL
64
- data-values-subject | The subject (id) of the generated data. If this is not set, a blank node with a new UUID is created. If `data-values` or `data-values-url` is set, this id is also used to find the root node in the data graph to fill the form
65
- data-values-namespace | RDF namespace to use when generating new RDF subjects. Default is empty, so that subjects will be blank nodes.
66
- data-values-graph | If set, serializing the form will create a named graph with the given IRI.
67
- data-language | Language to use if shapes contain langStrings, e.g. in `sh:name` or `rdfs:label`. Default is [`navigator.language`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language) with fallback to [`navigator.languages`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/languages)
68
- data-loading | Text to display while the web component is initializing. Default: `"Loading..."`
69
- data&#x2011;ignore&#x2011;owl&#x2011;imports | By default, `owl:imports` URLs are fetched and the resulting RDF triples are added to the shapes graph. Setting this attribute to any value disables this feature
70
- data-view | When set, turns the web component into a viewer that displays the given data graph without editing functionality
71
- data-collapse | When set, `sh:group`s and properties with `sh:node` and `sh:maxCount` != 1 are displayed in a collapsible accordion-like widget to reduce visual complexity of the form. The collapsible element is initially shown closed, except when this attribute's value is `"open"`
72
- data-submit-button | [Ignored when `data-view` attribute is set] Whether to add a submit button to the form. The value of this attribute is used as the button label. `submit` events get emitted only when the form data validates
73
- data-generate-node-shape-reference | When generating the RDF data graph, &lt;shacl-form&gt; by default creates a triple that references the root `sh:NodeShape` of the data. Default value of this attribute is `http://purl.org/dc/terms/conformsTo`. Set this to the empty string to disable generating such a triple.
74
- data-show-node-ids | When this attribute is set, shacl node shapes will have their subject id shown in the form
75
- data-show-root-shape-label | If this is set and the root SHACL shape has `rdfs:label` or `dcterms:title` properties, &lt;shacl-form&gt; displays a heading with that value on top of the form
76
- data-proxy | URL of a proxy to use when fetching resources (e.g. `owl:imports`). This can help loading resources from the web that are not [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) enabled. The URL of the resource to fetch will be appended to the value of this attribute. Example value for this attribute: `http://you-proxy.org/?url=`.
77
- data-dense | Boolean indicating to render a compact form with small paddings and margins. Default: true
78
- data-hierarchy-colors | If set, a colored vertical bar is displayed on the right side of the form for each nested hierarchy level with the intention of easing orientation in complex nested forms. The value of this attribute can be a list of comma separated CSS color definitions. If no value is given, a default color palette is used.
79
- data-use-shadow-root | Boolean string indicating whether `<shacl-form>` renders its contents inside a shadow root. Default: 'true'. Set to 'false' to render into the light DOM.
80
-
84
+ data-shapes | SHACL shape definitions (e.g. Turtle) used to generate the form
85
+ data-shapes-url | When `data-shapes` is not set, load SHACL shapes from this URL
86
+ data-shape-subject | Optional subject IRI for the root node shape. If not set, the first node shape is used
87
+ data-values | RDF triples (e.g. Turtle) used to prefill the form
88
+ data-values-url | When `data-values` is not set, load RDF triples from this URL
89
+ data-values-subject | Subject (IRI or blank node id) for generated data. If not set, a blank node with a new UUID is created. If `data-values` or `data-values-url` is set, this id is used to find the root node in the data graph
90
+ data-values-namespace | RDF namespace used when generating new RDF subjects. Default is empty, which yields blank nodes
91
+ data-values-graph | If set, serialization creates a named graph with this IRI
92
+ data-language | Language for `langString` values (e.g. in `sh:name` or `rdfs:label`). Default is [`navigator.language`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language) with fallback to [`navigator.languages`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/languages)
93
+ data-loading | Text displayed while the component initializes. Default is `"Loading..."`
94
+ data-ignore-owl-imports | By default, `owl:imports` URLs are fetched and merged into the shapes graph. Set this attribute to disable that behavior
95
+ data-view | When set, turns the component into a viewer that displays the data graph without editing
96
+ data-collapse | When set, `sh:group`s and properties with `sh:node` and `sh:maxCount` != 1 are rendered in a collapsible accordion. Use value `"open"` to start expanded
97
+ data-submit-button | [Ignored when `data-view` is set] Adds a submit button. The attribute value is used as the label. `submit` events fire only when the data validates
98
+ data-generate-node-shape-reference | When generating RDF data, adds a triple that references the root `sh:NodeShape`. Default predicate is `http://purl.org/dc/terms/conformsTo`. Set to an empty string to disable
99
+ data-show-node-ids | Show node shape subject ids in the form
100
+ data-show-root-shape-label | If set and the root shape has `rdfs:label` or `dcterms:title`, display that value as a heading
101
+ data-proxy | Proxy URL used when fetching resources (e.g. `owl:imports`). The resource URL is appended to the proxy value, e.g. `http://your-proxy.org/?url=`
102
+ data-dense | Boolean to render a compact form with smaller paddings and margins. Default is true
103
+ data-hierarchy-colors | Comma-separated list of CSS colors for nested hierarchy bars. If unset, a default palette is used
104
+ data-use-shadow-root | Boolean string indicating whether `<shacl-form>` renders into a shadow root. Default is `"true"`. Set to `"false"` to render into light DOM
81
105
 
82
106
  ### Element functions
83
107
 
@@ -85,101 +109,103 @@ data-use-shadow-root | Boolean string indicating whether `<shacl-form>` renders
85
109
  ```typescript
86
110
  toRDF(graph?: Store): Store
87
111
  ```
88
- Adds the form values as RDF triples to the given graph. If no graph object is provided, creates a new [N3 Store](https://github.com/rdfjs/N3.js#storing).
112
+ Adds the form values as RDF triples to the given graph. If no graph is provided, creates a new [N3 Store](https://github.com/rdfjs/N3.js#storing).
89
113
 
90
114
  ```typescript
91
115
  serialize(format?: string, graph?: Store): string
92
116
  ```
93
- Serializes the given RDF graph to the given format. If no graph object is provided, this function calls toRDF() (see above) to construct the form data graph in one of the supported [output formats](#output-formats) (default is `text/turtle`).
117
+ Serializes the given RDF graph to the given format. If no graph is provided, this calls `toRDF()` to construct the form data graph in one of the supported [output formats](#output-formats) (default is `text/turtle`).
94
118
 
95
119
  ```typescript
96
120
  validate(ignoreEmptyValues: boolean): Promise<boolean>
97
121
  ```
98
- Validates the form data against the SHACL shapes graph and displays validation results as icons next to the respective input fields. If `ignoreEmptyValues` is true, empty form fields will not be marked as invalid. This function is also internally called on `change` and `submit` events.
122
+ Validates form data against the SHACL shapes graph and displays validation results as icons next to the respective input fields. If `ignoreEmptyValues` is true, empty fields will not be marked invalid. This function is also invoked on `change` and `submit` events.
99
123
 
100
124
  ```typescript
101
125
  registerPlugin(plugin: Plugin)
102
126
  ```
103
- Register a [plugin](./src/plugin.ts) to customize editing/viewing certain property values. Plugins handle specific RDF predicates or `xsd:datatype`s or both. Example: [Leaflet](./src/plugins/leaflet.ts)
127
+ Registers a [plugin](./src/plugin.ts) to customize editing/viewing of certain values. Plugins handle specific RDF predicates, `xsd:datatype`s, or both. Example: [Leaflet](./src/plugins/leaflet.ts)
104
128
 
105
129
  ```typescript
106
130
  setTheme(theme: Theme)
107
131
  ```
108
- Set a design theme to use for rendering. See section [Theming](#Theming).
132
+ Sets the design theme used for rendering. See [Theming](#theming).
109
133
 
110
134
  ```typescript
111
135
  setClassInstanceProvider((className: string) => Promise<string>)
112
136
  ```
113
- Sets a callback function that is invoked when a SHACL property has an `sh:class` definition to retrieve class instances. See [below](#classInstanceProvider) for more information.
137
+ Sets a callback that is invoked when a SHACL property has an `sh:class` definition to retrieve class instances. See [below](#classInstanceProvider) for details.
114
138
 
115
139
  ```typescript
116
140
  setResourceLinkProvider(provider: ResourceLinkProvider)
117
141
  ```
118
- Registers a callback provider that supplies existing resources for linking. The provider is used to list resources that conform to the node shapes of a property and to load RDF data for selected resources. See [below](#resourceLinkProvider) for details.
142
+ Registers a callback provider that supplies existing resources for linking. The provider lists resources that conform to a node shape and loads RDF data for selected resources. See [below](#resourcelinkprovider).
119
143
 
120
144
  ## Features
121
145
 
122
146
  ### Validation
123
147
 
124
- In edit mode, `<shacl-form>` validates the constructed data graph using the library [shacl-engine](https://github.com/rdf-ext/shacl-engine) and displays validation results as icons next to the respective form fields.
148
+ In edit mode, `<shacl-form>` validates the constructed data graph using [shacl-engine](https://github.com/rdf-ext/shacl-engine) and displays validation results as icons next to the relevant fields.
125
149
 
126
150
  ### Data graph binding
127
151
 
128
- `<shacl-form>` requires only a shapes graph as input via the attribute `data-shapes` (or `data-shapes-url`) to generate an empty form and create new RDF data from the form input fields. Using the attributes `data-values` (or `data-values-url`) and `data-values-subject`, you can also bind an existing data graph to the form. The given data graph is then used to fill the form input fields.
152
+ `<shacl-form>` requires only a shapes graph as input via `data-shapes` (or `data-shapes-url`) to generate an empty form and create new RDF data from user input. Using `data-values` (or `data-values-url`) and `data-values-subject`, you can also bind an existing data graph to the form and prefill the fields.
129
153
 
130
154
  ### Viewer mode
131
155
 
132
- `<shacl-form>` not only is an RDF data editor, but can also be used as a viewer by setting attribute `data-view` and binding both, a shapes and a data graph. See the [demo](https://ulb-darmstadt.github.io/shacl-form/#viewer-mode) for an example.
156
+ `<shacl-form>` is both an editor and a viewer. Set `data-view` and bind a shapes graph and a data graph to render a read-only view. See the [demo](https://ulb-darmstadt.github.io/shacl-form/#viewer-mode).
133
157
 
134
158
  ### Providing additional data to the shapes graph
135
159
 
136
- Apart from setting the element attributes `data-shapes` or `data-shapes-url`, there are two ways of adding RDF data to the shapes graph:
137
- 1. While parsing the triples of the shapes graph, any encountered `owl:imports` predicate that has a valid HTTP URL is fetched with the HTTP Accept header set to all of the [supported](#formats) MIME types. A successful response is parsed and added to a named graph. This graph is scoped (i.e. available) only to the node where the `owl:import` statement is defined on and all its sub nodes.
138
-
139
- The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#example) contains the following triples:
140
-
141
- ```
142
- example:Attribution
143
- sh:property [
144
- owl:imports <https://w3id.org/nfdi4ing/metadata4ing/> ;
145
- sh:name "Role" ;
146
- sh:path dcat:hadRole ;
147
- sh:class prov:Role ;
148
- ] .
149
- ```
150
- In this case, the URL references an ontology which among other things defines instances of class `prov:Role` that are then used to populate the "Role" dropdown in the form. The imported ontology is available only for rendering and validating this specific property.
151
-
152
- 2. <a id="classInstanceProvider"></a>The `<shacl-form>` element has a function `setClassInstanceProvider((className: string) => Promise<string>)` that registers a callback function which is invoked when a SHACL property has
153
- an `sh:class` predicate. The expected return value is a (promise of a) string (e.g. in format `text/turtle`) that contains RDF class instance definitions of the given class.
154
-
155
- In [this example](https://ulb-darmstadt.github.io/shacl-form/#example), the code:
156
-
157
- ```typescript
158
- form.setClassInstanceProvider((clazz) => {
159
- if (clazz === 'http://example.org/Material') {
160
- return `
161
- <http://example.org/steel> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Steel".
162
- <http://example.org/wood> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Wood".
163
- <http://example.org/alloy> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Alloy".
164
- <http://example.org/plaster> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Plaster".
165
- `
166
- }}
167
- )
168
- ```
169
- returns instances of the class `http://example.org/Material` that are then used to populate the "Artwork material" dropdown in the form.
160
+ Besides `data-shapes` and `data-shapes-url`, there are two ways to add RDF data to the shapes graph:
161
+
162
+ 1. While parsing the shapes graph, any `owl:imports` predicate with a valid HTTP URL is fetched. The response is parsed (using one of the [supported](#formats) MIME types) and added to a named graph. This graph is scoped to the node where the `owl:import` is defined and its sub nodes.
163
+
164
+ The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#example) contains the following triples:
165
+
166
+ ```
167
+ example:Attribution
168
+ sh:property [
169
+ owl:imports <https://w3id.org/nfdi4ing/metadata4ing/> ;
170
+ sh:name "Role" ;
171
+ sh:path dcat:hadRole ;
172
+ sh:class prov:Role ;
173
+ ] .
174
+ ```
170
175
 
171
- A more realistic use case of this feature is calling some API endpoint to fetch class instance definitions from existing ontologies.
176
+ In this case, the URL references an ontology that defines instances of `prov:Role`. These instances populate the "Role" dropdown. The imported ontology is available only for rendering and validating this specific property.
177
+
178
+ 2. <a id="classInstanceProvider"></a>The `<shacl-form>` element exposes `setClassInstanceProvider((className: string) => Promise<string>)`, a callback invoked when a property has `sh:class`. The return value is a string (e.g. `text/turtle`) containing instance definitions of the given class.
179
+
180
+ In [this example](https://ulb-darmstadt.github.io/shacl-form/#example), the code:
181
+
182
+ ```typescript
183
+ form.setClassInstanceProvider((clazz) => {
184
+ if (clazz === 'http://example.org/Material') {
185
+ return `
186
+ <http://example.org/steel> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Steel".
187
+ <http://example.org/wood> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Wood".
188
+ <http://example.org/alloy> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Alloy".
189
+ <http://example.org/plaster> a <http://example.org/Material>; <http://www.w3.org/2000/01/rdf-schema#label> "Plaster".
190
+ `
191
+ }
192
+ })
193
+ ```
194
+
195
+ returns instances of `http://example.org/Material`, which populate the "Artwork material" dropdown.
196
+
197
+ A more realistic use case is calling an API endpoint to fetch class instances from existing ontologies.
172
198
 
173
199
  ### Use of SHACL sh:class
174
200
 
175
- In case a property shape has a `sh:class`, all available graphs are scanned for instances of the given class to let the user choose from. `rdfs:subClassOf` is also considered when building the list of class instances.
201
+ When a property shape has an `sh:class`, all available graphs are scanned for instances of that class so users can choose from them. `rdfs:subClassOf` is also considered when building the list of class instances.
176
202
 
177
203
  `shacl-form` also supports class instance hierarchies modelled with `skos:broader` and/or `skos:narrower`. This is illustrated by the "Subject classification" property in the [example](https://ulb-darmstadt.github.io/shacl-form/#example).
178
204
 
179
205
  ### SHACL constraints sh:or and sh:xone
180
206
 
181
- `<shacl-form>` supports using [sh:or](https://www.w3.org/TR/shacl/#OrConstraintComponent) and [sh:xone](https://www.w3.org/TR/shacl/#XoneConstraintComponent) to let users select between different options on nodes or properties.
182
- The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#example) has the following triples:
207
+ `<shacl-form>` supports [sh:or](https://www.w3.org/TR/shacl/#OrConstraintComponent) and [sh:xone](https://www.w3.org/TR/shacl/#XoneConstraintComponent) to let users choose between different options on nodes or properties. The [example shapes graph](https://ulb-darmstadt.github.io/shacl-form/#example) includes:
208
+
183
209
  ```
184
210
  example:Attribution
185
211
  a sh:NodeShape ;
@@ -193,34 +219,34 @@ example:Attribution
193
219
  )
194
220
  ] .
195
221
  ```
196
- When adding a new attribution, `<shacl-form>` renders a dropdown to let the user select between the two options Person/Organisation. After selecting one of the options, the dropdown is replaced by the input fields of the selected node shape.
197
222
 
198
- When binding an existing data graph to the form, the constraint is tried to be resolved depending on the respective data value:
223
+ When adding a new attribution, `<shacl-form>` renders a dropdown to select Person/Organisation. After selection, the dropdown is replaced by the input fields of the chosen node shape.
224
+
225
+ When binding an existing data graph to the form, the constraint is resolved based on the data value:
199
226
  - For RDF literals, an `sh:or` option with a matching `sh:datatype` is chosen
200
- - For blank nodes or named nodes, the `rdf:type` of the value is tried to be matched with a node shape having a corresponding `sh:targetClass` or with a property shape having a corresponding `sh:class`. If there is no `rdf:type` but a `sh:nodeKind` of `sh:IRI`, the id of the the node is used as the value.
227
+ - For blank nodes or named nodes, the `rdf:type` is matched with a node shape having a corresponding `sh:targetClass` or with a property shape having a corresponding `sh:class`. If there is no `rdf:type` but a `sh:nodeKind` of `sh:IRI`, the node id is used as the value
201
228
 
202
229
  ### Linking existing data
203
230
 
204
- In case a node shape has a `sh:targetClass` and any graph, i.e.
231
+ When a node shape has a `sh:targetClass` and any graph contains instances of that class, those instances can be linked in the respective SHACL property. The generated data graph will then contain only a reference to the instance, not its full triples.
232
+
233
+ Graphs considered are:
205
234
  - the shapes graph
206
235
  - the data graph
207
- - any graph loaded by `owl:imports`
236
+ - any graph loaded via `owl:imports`
208
237
  - triples provided by [classInstanceProvider](#classInstanceProvider)
209
238
 
210
- contains instances of that class, those can be linked in the respective SHACL property. The generated data graph will then just contain a reference to the instance, but not the triples that the instance consists of.
211
-
212
239
  <a id="resourceLinkProvider"></a>
213
- If your graphs only contain the resource identifiers (IRIs) and not the full triples for linked resources, you can use `setResourceLinkProvider` to supply them on demand. The `ResourceLinkProvider` lets you:
240
+ If your graphs only contain resource identifiers (IRIs) and not the full triples for linked resources, you can use `setResourceLinkProvider` to supply them on demand. The `ResourceLinkProvider` lets you:
214
241
 
215
242
  * List resources that conform to a node shape so they can appear in the "Link existing ..." dialog.
216
- * Load RDF data for selected resource IRIs so the `shacl-form` can resolve, display and validate linked resources.
243
+ * Load RDF data for selected resource IRIs so the `shacl-form` can resolve, display, and validate linked resources.
217
244
 
218
- The provider supports eager loading (resolve resources during initialization) or lazy loading (resolve when the user opens the link dialog).
245
+ The provider supports eager loading (resolve resources during initialization) or lazy loading (resolve when the user opens the link dialog). See [here](https://github.com/ULB-Darmstadt/rdf-store/blob/main/frontend/src/editor.ts#L10) for an example implementation.
219
246
 
220
247
  ### SHACL shape inheritance
221
248
 
222
- SHACL defines two ways of inheriting shapes: [sh:and](https://www.w3.org/TR/shacl/#AndConstraintComponent)
223
- and [sh:node](https://www.w3.org/TR/shacl/#NodeConstraintComponent). `<shacl-form>` supports both. In [this example](https://ulb-darmstadt.github.io/shacl-form/#example), node shape `example:ArchitectureModelDataset` extends `example:Dataset` by defining the following RDF triple:
249
+ SHACL defines two ways of inheriting shapes: [sh:and](https://www.w3.org/TR/shacl/#AndConstraintComponent) and [sh:node](https://www.w3.org/TR/shacl/#NodeConstraintComponent). `<shacl-form>` supports both. In [this example](https://ulb-darmstadt.github.io/shacl-form/#example), node shape `example:ArchitectureModelDataset` extends `example:Dataset` by defining:
224
250
 
225
251
  ```
226
252
  example:ArchitectureModelDataset sh:node example:Dataset .
@@ -230,42 +256,94 @@ Properties of inherited shapes are displayed first.
230
256
 
231
257
  ### Plugins
232
258
 
233
- Plugins can modify rendering of the form and add functionality to edit and view certain RDF datatypes or predicates (or a combination of both). As an example, the JavaScript of [this page](https://ulb-darmstadt.github.io/shacl-form/#example) contains the following code:
259
+ Plugins can modify rendering and add edit/view functionality for specific RDF datatypes or predicates (or both). For example, the JavaScript on [this page](https://ulb-darmstadt.github.io/shacl-form/#example) includes:
260
+
234
261
  ```typescript
235
262
  import { LeafletPlugin } from '@ulb-darmstadt/shacl-form/plugins/leaflet.js'
236
263
  const form = document.getElementById("shacl-form")
237
264
  form.registerPlugin(new LeafletPlugin({ datatype: 'http://www.opengis.net/ont/geosparql#wktLiteral' }))
238
265
  ```
239
- In effect, whenever a SHACL property has an `sh:datatype` of `http://www.opengis.net/ont/geosparql#wktLiteral`, the plugin is called to create the editor and/or viewer HTML elements. This specific plugin uses [Leaflet](https://leafletjs.com/) to edit or view geometry in format [well known text](http://giswiki.org/wiki/Well_Known_Text) on a map.
240
- Custom plugins can be built by extending class [Plugin](https://github.com/ULB-Darmstadt/shacl-form/blob/main/src/plugin.ts#L40).
266
+
267
+ When a SHACL property has datatype `http://www.opengis.net/ont/geosparql#wktLiteral`, the plugin renders the editor/viewer elements. This plugin uses [Leaflet](https://leafletjs.com/) to edit or view geometry in [well known text](http://giswiki.org/wiki/Well_Known_Text) on a map.
268
+
269
+ Custom plugins can be built by extending [Plugin](https://github.com/ULB-Darmstadt/shacl-form/blob/main/src/plugin.ts#L40).
241
270
 
242
271
  ### Property grouping and collapsing
243
272
 
244
273
  Properties can be grouped using [sh:group](https://www.w3.org/TR/shacl/#group) in the shapes graph. [This example](https://ulb-darmstadt.github.io/shacl-form/#example) defines a group "Physical properties" and assigns certain properties to it.
245
274
 
246
- When the element attribute `data-collapse` is set, `<shacl-form>` creates an accordion-like widget that toggles the visibility of grouped properties in order to reduce the visual complexity of the form. If the grouped properties should initially be shown, set `data-collapse="open"`.
275
+ When `data-collapse` is set, `<shacl-form>` creates an accordion-like widget that toggles grouped properties to reduce visual complexity. If the grouped properties should start open, set `data-collapse="open"`.
247
276
 
248
- Apart from grouped properties, all properties having an `sh:node` predicate and `sh:maxCount` != 1 are collapsed.
277
+ In addition, all properties with `sh:node` and `sh:maxCount` != 1 are collapsed.
249
278
 
250
279
  ### Supported RDF formats
280
+ <a id="formats"></a>
251
281
 
252
282
  #### Input formats
253
- * text/turtle, application/n-triples, application/n-quads, application/trig using [N3 parser](https://github.com/rdfjs/N3.js?tab=readme-ov-file#parsing)
254
- * application/ld+json using [jsonld](https://github.com/digitalbazaar/jsonld.js)
255
- * application/rdf+xml using [rdfxml-streaming-parser](https://github.com/rdfjs/rdfxml-streaming-parser.js)
283
+ - text/turtle, application/n-triples, application/n-quads, application/trig using the [N3 parser](https://github.com/rdfjs/N3.js?tab=readme-ov-file#parsing)
284
+ - application/ld+json using [jsonld](https://github.com/digitalbazaar/jsonld.js)
285
+ - application/rdf+xml using [rdfxml-streaming-parser](https://github.com/rdfjs/rdfxml-streaming-parser.js)
256
286
 
257
287
  #### Output formats
258
288
  <a id="output-formats"></a>
259
289
 
260
- * text/turtle, application/n-triples, application/n-quads, application/trig using [N3 writer](https://github.com/rdfjs/N3.js?tab=readme-ov-file#writing)
261
- * application/ld+json using [jsonld](https://github.com/digitalbazaar/jsonld.js)
290
+ - text/turtle, application/n-triples, application/n-quads, application/trig using the [N3 writer](https://github.com/rdfjs/N3.js?tab=readme-ov-file#writing)
291
+ - application/ld+json using [jsonld](https://github.com/digitalbazaar/jsonld.js)
292
+
293
+ ### Theming
294
+
295
+ `<shacl-form>` has a built-in abstraction layer for theming the form controls. To use another theme (e.g. Bootstrap or Material Design), extend [Theme](./src/theme.ts) and call `setTheme()` on the element.
296
+
297
+ If you only want to restyle the existing widgets (without re-implementing internal behavior), you can use CSS in two ways:
298
+
299
+ 1) Render into light DOM for global CSS:
300
+
301
+ ```html
302
+ <shacl-form data-use-shadow-root="false"></shacl-form>
303
+ ```
304
+
305
+ 2) Use CSS variables and parts (works with Shadow DOM too). The following CSS variables are supported:
306
+
307
+ ```css
308
+ shacl-form {
309
+ --shacl-font-family: system-ui, sans-serif;
310
+ --shacl-font-size: 14px;
311
+ --shacl-text-color: #333;
312
+ --shacl-muted-color: #555;
313
+ --shacl-border-color: #ddd;
314
+ --shacl-bg: #fff;
315
+ --shacl-row-alt-bg: #f8f8f8;
316
+ --shacl-error-color: #c00;
317
+ --shacl-label-width: 10em;
318
+ }
319
+ ```
320
+
321
+ And these parts are exposed for styling:
322
+
323
+ ```css
324
+ shacl-form::part(form) { padding: 8px; }
325
+ shacl-form::part(field) { gap: 6px; }
326
+ shacl-form::part(label) { font-weight: 600; }
327
+ shacl-form::part(editor) { border-radius: 6px; }
328
+ shacl-form::part(button) { min-height: 32px; }
329
+ shacl-form::part(primary) { font-weight: 700; }
330
+ shacl-form::part(add-button) { }
331
+ shacl-form::part(remove-button) { }
332
+ shacl-form::part(link-button) { }
333
+ shacl-form::part(submit-button) { }
334
+ ```
335
+
336
+ Available parts:
337
+ `form`, `node`, `linked-node`, `node-title`, `group`, `group-title`, `collapsible`, `property`, `property-instance`, `field`, `label`, `editor`, `lang-chooser`, `constraint`, `constraint-editor`, `add-controls`, `remove-controls`, `add-button`, `remove-button`, `link-button`, `submit-button`, `button`, `primary`.
338
+
339
+ Note: the [default widgets](https://gitlab.ulb.tu-darmstadt.de/rokit/ui-widgets) are provided by ULB Darmstadt. Those components expose their own `part` names; you can style them via `::part(...)` selectors on the respective elements. See the [README](https://gitlab.ulb.tu-darmstadt.de/rokit/ui-widgets) for documentation.
262
340
 
263
341
  ### Use with Solid Pods
264
342
 
265
- `<shacl-form>` can easily be integrated with [Solid Pods](https://solidproject.org/about). The output of `toRDF()` being a RDF/JS N3 Store, as explained [above](#toRDF), it can be presented to `solid-client`s `fromRdfJsDataset()` function, which converts the RDF graph into a Solid Dataset. The following example, based on Inrupt's basic [Solid Pod example](https://docs.inrupt.com/sdk/javascript-sdk/tutorial) shows how to merge data from a `<shacl-form>` with a Solid data resource at `readingListDataResourceURI`:
266
-
343
+ `<shacl-form>` can be integrated with [Solid Pods](https://solidproject.org/about). Because `toRDF()` returns an RDF/JS N3 Store (see [above](#toRDF)), it can be passed to the Solid client `fromRdfJsDataset()` function to convert it into a Solid Dataset. The example below (based on Inrupt's [Solid Pod tutorial](https://docs.inrupt.com/sdk/javascript-sdk/tutorial)) shows how to merge data from a `<shacl-form>` with a Solid data resource at `readingListDataResourceURI`:
344
+
267
345
  ```js
268
- // Authentication is assumed, resulting in a fetch able to read and write into the Pod
346
+ // Authentication is assumed, resulting in a fetch function able to read and write into the Pod
269
347
  try {
270
348
  // Get data out of the shacl-form
271
349
  const form = document.querySelector('shacl-form')
@@ -296,7 +374,3 @@ Apart from grouped properties, all properties having an `sh:node` predicate and
296
374
  console.error(`Storing SHACL data from Form failed with error ${err}!`)
297
375
  }
298
376
  ```
299
-
300
- ### Theming
301
-
302
- `<shacl-form>` has a built-in abstraction layer for theming, i.e. the look and feel of the form elements. If you would like to employ a different theme like e.g. `bootstrap` or `material design`, then extend class [Theme](./src/theme.ts) and call function `setTheme()` on the `<shacl-form>` element.