Skip to content

Initial RDF forms component#798

Open
timea-solid wants to merge 37 commits into
stagingfrom
rdfComponets
Open

Initial RDF forms component#798
timea-solid wants to merge 37 commits into
stagingfrom
rdfComponets

Conversation

@timea-solid

@timea-solid timea-solid commented Jun 16, 2026

Copy link
Copy Markdown
Member

This is for now:

  • adding an overall RDF forms component to storybook
  • testing its behaviour in Storybook by implementing a first RDF input Web Component

@timea-solid timea-solid marked this pull request as draft June 16, 2026 12:17
Prompt: reading the RDFinput file, pls make suggestions of how to impprve the code to make it easier to follow and read. I beliebe it is difficult to follow the fact that one has a rdf forms subject and a data subject as well and how it is all itertwinded.
Co-Authored-By: GitHub Copilot (raptor-mini) <copilot@github.com>
@timea-solid timea-solid moved this to In progress in SolidOS NLNet UI Jun 22, 2026
@timea-solid timea-solid changed the title RDF forms component Initial RDF forms component Jun 23, 2026
@timea-solid timea-solid self-assigned this Jun 23, 2026
@timea-solid timea-solid requested a review from NoelDeMartin June 23, 2026 08:32

@NoelDeMartin NoelDeMartin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few initial comments, mostly regarding a11y and component architecture.

Comment thread src/types/custom-elements.d.ts
Comment thread src/components/rdf-form/RDForm.stories.ts Outdated
Comment thread src/components/rdf-form/RDFForm.ts Outdated
Comment thread src/components/rdf-form/RDFForm.ts Outdated
Comment thread src/components/rdf-form/RDFForm.ts
Comment thread src/components/rdf-form/RDFForm.ts Outdated
return html` <solid-ui-rdf-input
.store=${store}
.formSubject=${sym(part.value)}
.dataSubject=${me}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all inputs should also have a name attribute. Otherwise, they'll be ignored by the form (again, important for a11y, etc.).

Comment thread src/components/rdf-input/RDFInput.ts Outdated
Comment thread src/components/rdf-input/RDFInput.ts Outdated
Comment on lines +29 to +38
export type FieldParamsObject = {
size?: number, // input element size attribute
type?: InputType, // input element type attribute. Default: 'text' (not for Comment and Heading)
element?: string, // element type to use (Comment and Heading only)
style?: string, // style to use
dt?: string, // xsd data type for the RDF Literal corresponding to the field value. Default: xsd:string
defaultInputValue?: string, // e.g. 'mailto:'. Default value in input field, will be removed when displaying actual value to user.
namedNode?: boolean, // if true, field value corresponds to the URI of an RDF NamedNode. Overrides dt and defaultInputValue.
pattern?: RegExp // for client-side input validation; field will go red if violated, green if ok
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many of these are currently unused, right? I see that this is a WIP, so it's fine. But before merging, I would remove everything that isn't used (you know, YAGNI, removing dead code, etc.).

Also, I'm not sure I like the style config... that goes a bit against the idea of RDF forms, given that different UI libraries may render forms differently, and inline styles are probably not going to work correctly in all of them. But if that was a design decision when creating the RDF forms, ok.

timea-solid and others added 2 commits June 24, 2026 10:03
Prompt: can this #sym:HTMLElementTagNameMap be generated automatically from vite-config/ components.ts for all RDF suffixed components?

Co-Authored-By: GitHub Copilot (raptor-mini) <copilot@github.com>
@timea-solid

Copy link
Copy Markdown
Member Author

RDFInput will make use of the new Input components when it is merged: #815

@timea-solid

timea-solid commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

We need to improve the name property of the generated form and make sure they are unique.
@NoelDeMartin do you have a suggestion for this?

All HTML elements created automatically from the ontology ui file need names but there could be more input fields called input-name. I am not sure I can just use a random id generator.

@NoelDeMartin NoelDeMartin self-requested a review June 30, 2026 07:57
Comment thread src/components/input/Input.styles.css Outdated
Comment thread src/lib/forms/store/RDFFormsStore.ts Outdated
Comment thread src/components/rdf-form/RDFForm.ts
Comment thread src/components/rdf-form/RDFForm.ts Outdated
Comment thread src/components/rdf-form/RDFForm.ts Outdated
Comment thread src/components/rdf-form/RDForm.stories.ts Outdated
Comment thread src/components/rdf-input/RDFInput.ts
Comment thread src/types/custom-elements.d.ts
Comment thread vite.config.ts Outdated
timea-solid and others added 9 commits June 30, 2026 12:35
Co-authored-by: Noel De Martin <noel@noeldemartin.com>
Prompt: I have this accessors rdfURI and subjectURi which should be URIs. I would like to use a lit converter for them instead of my code: https://lit.dev/docs/components/properties/#conversion-converter
Help me with it.
Prompt: I want the converter to only return URL or null

Co-Authored-By: GitHub Copilot (raptor-mini) <copilot@github.com>
@NoelDeMartin

Copy link
Copy Markdown
Member

I just saw this now, here's my thoughts:

We need to improve the name property of the generated form and make sure they are unique.
@NoelDeMartin do you have a suggestion for this?

All HTML elements created automatically from the ontology ui file need names but there could be more input fields called input-name. I am not sure I can just use a random id generator.

It depends on how the form is going to be used by the consumer. If everything is handled in javascript, there's nothing wrong with using names generated by the id generator. However, if the consumer wants to actually submit this form to a server they would need to know the actual names.

I haven't looked at the ui: ontology, but does it have an optional field for the name of the form control? If it doesn't, we should add it.

Basically, the behaviour I would like to see is that by default it generates random input names using the id generator, but if the RDF definitions specify the name of the form control, we'll use that. If those are not unique, I don't think we should do anything about it, that's the responsibility of whoever is defining the RDF (if they want two fields to have the same name, let them do it, although we could throw a helpful warning in the console or something).

That would be useful for different reasons, not just to handle the form submission. For example, the name of an input can influence some browser extensions or autocompletes.

@timea-solid

Copy link
Copy Markdown
Member Author

What we also need to decide is if we take the input size property into consideration.
How is the input length determined in the new Input Web Component?

@NoelDeMartin

NoelDeMartin commented Jul 2, 2026

Copy link
Copy Markdown
Member

I guess this is something to discuss, but personally I don't think the RDF should be able to affect the UI (things like size). That's the whole point of the approach, that the form gets rendered using the RDF definition in a way that works for the current UI/project.

I guess it's fine to have some properties like "primary color" for theming or something like that. But even then, shouldn't the "primary color" be set by the application where the form is rendered in? Maybe it can be useful to change an accent or something, to distinguish a button or input from others... But I'm not sure I like the idea.

As per how the size is determined now, I haven't looked too much into it, but usually inputs have a min-width or take 100% of their container. That's something that should be configured in the form. For now I think it's fine to simply have a max-width in the form and otherwise take up the entire container. We can tweak these things later, possibly with some properties in the component.

@timea-solid timea-solid marked this pull request as ready for review July 2, 2026 09:43
@timea-solid timea-solid requested a review from Copilot July 2, 2026 09:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces an initial RDF Forms implementation for the component library, wiring it into Storybook and adding an RDF-backed input Web Component, alongside supporting infrastructure (store context, helpers, and generated custom-elements typing).

Changes:

  • Add <solid-ui-rdf-form> and <solid-ui-rdf-input> components plus Storybook story/provider/store plumbing for rdflib-backed document loading.
  • Add rdflib form helper utilities and field parameter mappings for selecting appropriate HTML input types.
  • Add a Vite plugin to auto-generate src/types/custom-elements.d.ts, and extend existing form controls with a readonly API surface.

Reviewed changes

Copilot reviewed 18 out of 20 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
vite.config.mts Registers a new Vite plugin to generate custom element typings.
vite-config/components.ts Implements custom element type generation and a Vite plugin hook for it.
src/types/custom-elements.d.ts Updates the (now-generated) HTMLElementTagNameMap entries for custom elements.
src/storybook/store/StorybookStore.ts Adds a Storybook rdflib store wrapper for RDF forms.
src/storybook/components/StorybookProvider.ts Provides the RDF store context in Storybook.
src/lib/forms/store/StoreContext.ts Introduces a Lit context interface for injecting an rdflib LiveStore.
src/lib/forms/store/NoopStore.ts Adds a default “no store” implementation that throws when accessed.
src/lib/forms/rdfFormsHelper.ts Adds document loading, fetching, and RDF form utility helpers.
src/lib/forms/fieldParams.ts Adds field-type → HTML input parameter mappings for RDF form fields.
src/lib/components/traits/InputTrait.ts Extends the input trait target contract to include readonly.
src/components/select/Select.ts Adds a readonly property to <solid-ui-select> and attempts to bind it to the native <select>.
src/components/rdf-input/RDFInput.ts Implements <solid-ui-rdf-input> for reading/writing RDF-backed field values.
src/components/rdf-input/index.ts Exports the RDF input component entrypoint.
src/components/rdf-form/RDForm.stories.ts Adds a Storybook story for <solid-ui-rdf-form>.
src/components/rdf-form/RDFForm.ts Implements <solid-ui-rdf-form> for rendering form parts from RDF.
src/components/rdf-form/index.ts Exports the RDF form component entrypoint.
src/components/input/Input.ts Adds readonly support to <solid-ui-input> and binds it to the native <input>.
src/components/input/Input.styles.css Adds read-only styling rules for the native <input>.
src/components/combobox/Combobox.ts Adds readonly support to <solid-ui-combobox> and binds it to the native <input>.
.gitignore Ignores the generated src/types/custom-elements.d.ts file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/rdf-input/RDFInput.ts Outdated
// for building the HTML input element
const uiPropertyTerm = this.getFormProperty(this.formSubject, ns.ui('property'), document)
const inputLabel = this.getInputLabel(this.formSubject, uiPropertyTerm, document)
const readonly = this.getReadOnly(this.readonly, this.formSubject, document)
Comment on lines +122 to +124
private async updateData (e: CustomEvent) {
const newValue = (e.target as HTMLInputElement).value
this._pendingUpdateValue = newValue
Comment thread src/components/rdf-input/RDFInput.ts Outdated
Comment on lines +148 to +151
if (this.storeContext.store.updater?.editable(this.dataSubject) === false) {
this._updateInFlight = false
return
}
Comment thread src/components/rdf-input/RDFInput.ts Outdated
Comment on lines +176 to +179
toInsertSt = toDeleteSt.map(statement => st(statement.subject, statement.predicate, objectFromNewValue, statement.why))
if (toInsertSt.length === 0) {
toInsertSt = [st(this.formSubject, property as any, objectFromNewValue, this.getDocument(this.dataSubject))]
}
Comment thread src/components/rdf-input/RDFInput.ts
Comment thread src/lib/forms/store/NoopStore.ts Outdated
Comment thread src/components/select/Select.ts Outdated
Comment thread src/storybook/components/StorybookProvider.ts
Comment thread src/components/rdf-form/RDForm.stories.ts
Comment thread src/storybook/store/StorybookStore.ts
@timea-solid

Copy link
Copy Markdown
Member Author

I just saw this now, here's my thoughts:

We need to improve the name property of the generated form and make sure they are unique.
@NoelDeMartin do you have a suggestion for this?
All HTML elements created automatically from the ontology ui file need names but there could be more input fields called input-name. I am not sure I can just use a random id generator.

It depends on how the form is going to be used by the consumer. If everything is handled in javascript, there's nothing wrong with using names generated by the id generator. However, if the consumer wants to actually submit this form to a server they would need to know the actual names.

I haven't looked at the ui: ontology, but does it have an optional field for the name of the form control? If it doesn't, we should add it.

Basically, the behaviour I would like to see is that by default it generates random input names using the id generator, but if the RDF definitions specify the name of the form control, we'll use that. If those are not unique, I don't think we should do anything about it, that's the responsibility of whoever is defining the RDF (if they want two fields to have the same name, let them do it, although we could throw a helpful warning in the console or something).

That would be useful for different reasons, not just to handle the form submission. For example, the name of an input can influence some browser extensions or autocompletes.

I have decided to do a generateId (random id) since we did not have the name attribute at all in the past. A random one is enough for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

Create a starting RDF forms Web Component with an input field example

3 participants