shadcn.io is not affiliated with official shadcn/ui
Text Input with Address Preview Form Block for Solid
A form panel with one required project-name field that shows the web address it will get as you type, flags a name that is taken or past 50 characters, and offers the next free address.
Installation
Overview
Give a single text field more to say than a title, with this text input form for Solid with Ark UI. A compact header sits over a hairline frame with a plus mark on each corner: a label-and-field row (the label and its rule at the start, the Input at the end) and an action foot. Under the field an Input Group shows the address the name will get, built by a pure slugify helper (accents removed, words joined by dashes) after a fixed host, and one reserved line below it stays quiet until something matters: the characters to go when the edge is near, a name past 50, or an address that is already taken, with a button that fills the field with the next free address and puts focus back in it. Too short or empty is said when you leave the field or press Create, which moves focus to the field. The one Shine Button creates the project. It's built from Field, Input, Input Group, Button, Shine Button and Guides, with a CSS entrance only. For a project, a workspace, a site or any record that needs a name and an address.
FAQ
How do I change the rules, the host and the taken names?
Edit the constants at the top. MIN and MAX are the length rule, NEAR is how close to the end the characters to go start to show, HOST is the fixed part of every address and SEED_TAKEN lists the addresses that are already in use. slugify and issueOf are pure functions: the first turns a name into its address, the second returns the first rule a name breaks and whether it is said while typing or only after the field is left. Nothing is typed twice, so the address line, the counter and the problem all follow from the one name.
When does it check, and why not on every key?
Different problems have different timing. A name past 50 characters and an address that is taken are said as you type, because they are certain and the visitor can act on them. A name that is empty or under three characters is only said when the field is left or Create is pressed, since nobody is wrong halfway through a word; after that the field re-checks as it changes. The message line is always there, so a message appearing never moves the button, and the field points to it with aria-describedby and is marked aria-invalid while a problem shows.
What does the Use button do?
When the address is taken, the button names the next free one (q3-launch-plan-2, then -3 if that is taken too), fills the field with it and puts focus back in the field, so the keyboard user stays where they were. The line is spoken by the status message in the foot. The button is only there while the problem is.
Why is Create not disabled when the name is empty?
A disabled button gives no reason and drops out of the tab order. Here Create stays pressable: pressing it with a problem says what is wrong, in the foot and under the field, and moves focus to the field. Nothing is created until the name passes.
What stays local, and how do I connect it for real?
Nothing is created or sent. The taken names are four typed ones plus every name you create here, kept in the page's state, so creating the same name twice is refused. For a real app, check the address on your server when the field settles (and again when you create, since two people can pick the same name at once), show the server's answer in the same line, and keep the Use button for the suggestion it returns. The status line says what happened and the foot never changes size.
How do I connect it to react-hook-form or TanStack Form?
The block keeps its state in plain useState so it ports to Vue, Svelte and Solid. react-hook-form is a React library, so use TanStack Form's adapter for your framework: a field with onBlur and onChange validators maps to the same timing, and the field's errors replace the message line's text. With TanStack Form, give the field validators for blur and change and read field.state.meta.errors for the line under the input.