svecosystem/formsnap

Add a docs section for common bits-ui form components

wesharper opened this issue · 5 comments

I love what you're doing with the new v2 (I've been checking it out on the preview site). In addition to the new guides section you've added, you might consider adding a bits-ui/shadcn integration section with a quickstarts for some common form elements like:

  • Checkbox
  • Combobox
  • Date (Field/Picker/Range Field/Range Picker)
  • PIN Input
  • Select
  • Slider
  • Switch

In fact, it might also be a good idea to rebrand the bits-ui docsite with the same treatment as the new formsnap and cross-promote. Would be more than happy to help anywhere I can.

Bits UI docs won't change in that aspect but good idea on the integrations for Formsnap!

I added a guide for Bits UI select & multiple select. Once it merges I'll happily accept some guide contributions for whatever you see fit!

I see that the shadcn-svelte docs have already been updated. Should be a pretty simple copy/paste/check.

Now that I'm thinking on it though, it seems like bits, shadcn, and formsnap could all benefit from cross-promotion, and while I know that bits and shadcn aren't 1:1 clones of each other, the bones are mostly the same when it comes to raw functionality. Additionally, maintaining similar or even identical examples on docs pages across all 3 seems like an unnecessary burden considering the tight integration.

Does it make sense to have one docs page be sort of a source of truth for integrating formsnap with the custom builders with the others linking out? I could see any/all of them referencing each other and could make an argument for any of them being the source of truth.

My initial thought would be having a section on formsnap and bits that just links out to shadcn, which is the most opinionated. Would like to know how others feel about this.

hey y'all! i'm new to svelte/kit, and i really appreciate all the contributions you've made to the ecosystem. i've had my eye on svelte for a while, but it was projects like melt and bits-ui that convinced me to give it a try.

i was hoping you could provide some guidance RE integrating bits-ui range fields with formsnap (or superforms directly). my first implementation used a proxy, but i wasn't able to figure out client-side validation. i've since enabled client-side validation by refactoring into a derived store that is shared by two date pickers (that also share a range calendar), allowing me to pass the constraints to distinct inputs, but that feels sort of off.

i've included a representation of my current implementation below. i've looked through the docs and discussions for all three libraries, but i don't have a really good sense of how constraints interplay with client-side validation, or how multi-part form values are meant to be handled.

<script lang="ts" context="module">
  function deriveFieldState(form: SuperForm<{ startOn: string; endOn: string; }>) {

    const {
      value: startFieldValue,
      errors: startFieldErrors,
      constraints: startFieldConstraints,
    } = formFieldProxy(form, 'startOn');

    const {
      value: endFieldValue,
      errors: endFieldErrors,
      constraints: endFieldConstraints,
    } = formFieldProxy(form, 'endOn');

    const value = derived([startFieldValue, endFieldValue], ([start, end]) => {
      return {
        start: start ? parseDate(start) : undefined,
        end: end ? parseDate(end) : undefined,
      };
    });

    const setStart = (value: DateValue | undefined) => {
      if (value) {
        startFieldValue.set(value.toString());
      }
    };

    const setEnd = (value: DateValue | undefined) => {
      if (value) {
        endFieldValue.set(value.toString());
      }
    };

    return {
      value,
      setStart,
      setEnd,
      setRange: (value: DateRange) => {
        if (value.start && value.end) {
          setStart(value.start);
          setEnd(value.end);
        }
      },
      errors: {
        startFieldErrors,
        endFieldErrors,
      },
      constraints: {
        startFieldConstraints,
        endFieldConstraints,
      },
    };

  }
</script>

<Popover.Root openFocus bind:open={$open}>
  <Popover.Trigger asChild let:builder>
    <Form.Field {form} name="startOn">
      <Form.Control let:attrs>
        <DateField.Root value={$value.start} onValueChange={setStart}>
          <DateField.Input {...$startFieldConstraints} let:segments>
            {#each segments as { part, value }}
              <DateFieldPrimitive.Segment {part}>
                {value}
              </DateFieldPrimitive.Segment>
            {/each}
            <Button builders={[builder]} {...attrs}>
              <CalendarIcon />
            </Button>
          </DateField.Input>
        </DateField.Root>
      </Form.Control>
    </Form.Field>
    <!-- repeat for endOn -->
  </Popover.Trigger>
  <Popover.Content>
    <RangeCalendar
      value={$value}
      onValueChange={(dateRange) => {
        if (dateRange.start && dateRange.end) {
          setRange(dateRange);
          close();
        }
      }}
      initialFocus
      numberOfMonths={2}
      minValue={today(getLocalTimeZone())}
    />
  </Popover.Content>
</Popover.Root>

@ambergristle. I would recommend checking out the shadcn-svelte repo and some of the source-code examples using the "view component source" buttons. Personally, I think they are pretty well done and I've learned a lot about some of the patterns they employ. Also, I'd encourage you to join Huntabyte's discord (if you see this before the link expires), which is a good channel for general support-related questions like this one. I'd also recommend spinning up a minimal repro in something like stackblitz or codesandbox with your code so someone can jump in and help you more easily. I don't want to discourage your questions, but I think you'd have more luck and support on a different channel for queries like this one.

@huntabyte I think this could probably get closed unless there's wide-scale community confusion or a more specific set of goals for what needs to be added. When I had initially asked, I wasn't really using shad-cn. We've since migrated a lot of our stuff to shad and adopted a lot of those patterns. Adding additional docs feels like a maintenance burden unless for some reason the average bits consumer is hitting some particular snags.

I don't personally know who the average bits consumer is and I assume that a majority of folks are either reaching for shad or will be reaching out for more specific issues.