Danny Spangenberg's Avatar

Danny Spangenberg

@ds.twiceware.de

DRY-er, more accessible shadcn/ui-inspired React Aria components, optimized for Inertia.js with Laravel's Precogintion build in. https://github.com/dspangenberg/twc-ui #shadcn #inertiajs #reactjs #laravel #typescript #tailwind

17
Followers
128
Following
4
Posts
04.06.2025
Joined
Posts Following

Latest posts by Danny Spangenberg @ds.twiceware.de

Screenshot of the PdfContainer

Screenshot of the PdfContainer

Screenshot of the PdfViewer (Promise)

Screenshot of the PdfViewer (Promise)

import { PdfViewer } from '@/components/twc-ui/pdf-viewer'
const doSomething = async () => {
    await PdfViewer.call({
      file: '/compressed.tracemonkey-pldi-09.pdf'
  })
}

import { PdfViewer } from '@/components/twc-ui/pdf-viewer' const doSomething = async () => { await PdfViewer.call({ file: '/compressed.tracemonkey-pldi-09.pdf' }) }

import { PdfContainer } from '@/components/twc-ui/pdf-container'

export const Demo = () => {
  return (
    <PdfContainer file="/compressed.tracemonkey-pldi-09.pdf" />
  )
}

export default Demo

import { PdfContainer } from '@/components/twc-ui/pdf-container' export const Demo = () => { return ( <PdfContainer file="/compressed.tracemonkey-pldi-09.pdf" /> ) } export default Demo

PDF-Container / PDF-Viewer

React Shadcn
#react #shadcn

18.12.2025 20:44 ๐Ÿ‘ 3 ๐Ÿ” 0 ๐Ÿ’ฌ 0 ๐Ÿ“Œ 0
import { AlertDialog } from "@/components/twc-ui/alert-dialog";
const doSomething = async () => {
  const confirmed = await AlertDialog.call({
    title: "Are you absolutely sure?",
    message:
      "This action cannot be undone. This will permanently delete your account and remove your data from our servers.",
    buttonTitle: "Delete Account",
    variant: "destructive"
  });
};

import { AlertDialog } from "@/components/twc-ui/alert-dialog"; const doSomething = async () => { const confirmed = await AlertDialog.call({ title: "Are you absolutely sure?", message: "This action cannot be undone. This will permanently delete your account and remove your data from our servers.", buttonTitle: "Delete Account", variant: "destructive" }); };

18.12.2025 20:34 ๐Ÿ‘ 1 ๐Ÿ” 0 ๐Ÿ’ฌ 0 ๐Ÿ“Œ 0
Video thumbnail

Alert dialog with promise
#react #shadcn

18.12.2025 20:34 ๐Ÿ‘ 3 ๐Ÿ” 1 ๐Ÿ’ฌ 1 ๐Ÿ“Œ 0
import { DemoContainer } from '@/components/docs/DemoContainer'
import { Button } from '@/components/twc-ui/button'
import { Form, useForm } from '@/components/twc-ui/form'
import { FormGroup } from '@/components/twc-ui/form-group'
import { TextField } from '@/components/twc-ui/textfield'
import { Head } from '@inertiajs/react'

interface Props {
  contact: App.Data.ContactData
}

export default function FormDemo ({ contact }: Props) {
  const form = useForm<App.Data.ContactData>(
    'contact-form',
    'post',
    route('contact.store'),
    contact
  )

  return (
    <DemoContainer>
      <Head title="Form Demo" />
      <Form form={form} errorVariant="field">
        <FormGroup>
          <div className="col-span-12">
            <TextField
              label="First name"
              {...form.register('first_name')}
            />
          </div>
          <div className="col-span-12">
            <TextField
              label="Last name"
              {...form.register('last_name')}
            />
          </div>
          <div className="col-span-12">
            <TextField
              label="E-Mail"
              {...form.register('email')}
            />
          </div>
          <div className="col-span-12">
            <Button title="Save" type="submit" />
          </div>
        </FormGroup>
      </Form>
    </DemoContainer>
  )
}

import { DemoContainer } from '@/components/docs/DemoContainer' import { Button } from '@/components/twc-ui/button' import { Form, useForm } from '@/components/twc-ui/form' import { FormGroup } from '@/components/twc-ui/form-group' import { TextField } from '@/components/twc-ui/textfield' import { Head } from '@inertiajs/react' interface Props { contact: App.Data.ContactData } export default function FormDemo ({ contact }: Props) { const form = useForm<App.Data.ContactData>( 'contact-form', 'post', route('contact.store'), contact ) return ( <DemoContainer> <Head title="Form Demo" /> <Form form={form} errorVariant="field"> <FormGroup> <div className="col-span-12"> <TextField label="First name" {...form.register('first_name')} /> </div> <div className="col-span-12"> <TextField label="Last name" {...form.register('last_name')} /> </div> <div className="col-span-12"> <TextField label="E-Mail" {...form.register('email')} /> </div> <div className="col-span-12"> <Button title="Save" type="submit" /> </div> </FormGroup> </Form> </DemoContainer> ) }

Sneak preview: A DRYer form with precognition. #reactjs #shadcn #intertiajs #laravel

17.06.2025 15:01 ๐Ÿ‘ 4 ๐Ÿ” 0 ๐Ÿ’ฌ 0 ๐Ÿ“Œ 0