انتقل إلى المحتوى
uiify

File upload

منطقة إسقاط وقائمة ملفات.

المتصفحات
Chrome 123+Firefox 121+Safari 17.5+
الفئة
1
الحجم المضغوط
2.27 kB
ميزانية التخطيط القسري
0 ms
ميزانية axe
0
متوافق مع SSR
نعم
العقد المنشور
بيئة الاختبار

المختبر

File upload

Attachments

Drop files here, or choose files above.

    Up to 3 files · 5 MB each

    "use client";
    import { FileUpload } from "@gunkin/uiify";
    
    export default function Example() {
      return (
        <FileUpload.Root multiple maxFiles={3} maxSize={5000000} className="">
          <FileUpload.HiddenInput name="attachments" aria-label="Attachments" />
          <FileUpload.Trigger as="button" className="">
            Choose files
          </FileUpload.Trigger>
          <FileUpload.Dropzone className="">Drop files here</FileUpload.Dropzone>
          <FileUpload.List className="">
            {(files) =>
              files.map((file, index) => (
                <FileUpload.Item key={file.name} index={index} className="">
                  <span>
                    {file.name} · {(file.size / 1024).toFixed(1)} KB
                  </span>
                  <FileUpload.ItemRemove index={index} aria-label={"Remove " + file.name}>
                    ×
                  </FileUpload.ItemRemove>
                </FileUpload.Item>
              ))
            }
          </FileUpload.List>
        </FileUpload.Root>
      );
    }
    /* File upload — trigger button with dashed dropzone. */
    
    @layer components {
      [data-uiify-file-upload] {
        display: grid;
        gap: var(--space-md);
        inline-size: 100%;
        max-inline-size: 24rem;
      }
    
      [data-uiify-file-upload] [data-part="dropzone"] {
        display: flex;
        align-items: center;
        justify-content: center;
        min-block-size: 8rem;
        padding: var(--space-lg);
        border: 2px dashed var(--input);
        border-radius: var(--radius-xl);
        corner-shape: squircle;
        background-color: var(--secondary);
        color: var(--muted-foreground);
        font-size: var(--text-sm);
        text-align: center;
        transition: var(--transition-colors);
      }
    
      [data-uiify-file-upload] [data-part="dropzone"]:hover,
      [data-uiify-file-upload] [data-part="dropzone"][data-dragging] {
        border-color: var(--primary);
        background-color: color-mix(in oklch, var(--primary) 8%, transparent);
        color: var(--foreground);
      }
    
      [data-uiify-file-upload] [data-part="dropzone"][data-disabled] {
        opacity: 0.5;
        cursor: not-allowed;
      }
    
      [data-uiify-file-upload] [data-part="list"] {
        display: grid;
        gap: var(--space-xs);
        margin: 0;
        padding: 0;
        list-style: none;
      }
    
      [data-uiify-file-upload] [data-part="item"] {
        display: flex;
        align-items: center;
        gap: var(--space-sm);
        padding: var(--space-sm) var(--space-md);
        border: var(--border-width) solid var(--border);
        border-radius: var(--radius-lg);
        corner-shape: squircle;
        background-color: var(--card);
        font-size: var(--text-sm);
      }
    }
    
    @layer components {
      [data-uiify-file-upload] [data-part="file-info"] {
        display: grid;
        gap: 0.25rem;
        min-inline-size: 0;
        flex: 1;
        overflow-wrap: anywhere;
      }
      [data-uiify-file-upload] small {
        color: var(--muted-foreground);
      }
      [data-uiify-file-upload] [data-part="remove"] {
        display: grid;
        place-items: center;
        flex: none;
        inline-size: 2rem;
        block-size: 2rem;
        margin-inline-start: auto;
        border: 0;
        border-radius: 50%;
        background: var(--secondary);
        color: var(--foreground);
        font-size: 1.25rem;
        line-height: 1;
        cursor: pointer;
      }
      [data-uiify-file-upload] [data-part="remove"]:hover {
        background: var(--accent);
      }
      [data-uiify-file-upload] [data-part="remove"]:focus-visible {
        outline: 2px solid var(--ring);
        outline-offset: 2px;
      }
    }
    "use client";
    import { FileUpload } from "@gunkin/uiify";
    
    export default function Example() {
      return (
        <FileUpload.Root
          multiple
          maxFiles={3}
          maxSize={5000000}
          className="
            grid gap-md [inline-size:100%] [max-inline-size:24rem] [&_[data-part=dropzone]]:flex
            [&_[data-part=dropzone]]:items-center [&_[data-part=dropzone]]:justify-center
            [&_[data-part=dropzone]]:[min-block-size:8rem] [&_[data-part=dropzone]]:p-lg
            [&_[data-part=dropzone]]:[border-width:2px] [&_[data-part=dropzone]]:[border-style:dashed]
            [&_[data-part=dropzone]]:border-input [&_[data-part=dropzone]]:rounded-xl
            [&_[data-part=dropzone]]:[corner-shape:squircle] [&_[data-part=dropzone]]:bg-secondary
            [&_[data-part=dropzone]]:text-muted-foreground [&_[data-part=dropzone]]:text-sm
            [&_[data-part=dropzone]]:text-center [&_[data-part=dropzone]]:[transition:var(--transition-colors)]
            [&_[data-part=dropzone]:hover]:border-primary
            [&_[data-part=dropzone]:hover]:[background-color:color-mix(in_oklch,_var(--primary)_8%,_transparent)]
            [&_[data-part=dropzone]:hover]:text-foreground [&_[data-part=dropzone][data-dragging]]:border-primary
            [&_[data-part=dropzone][data-dragging]]:[background-color:color-mix(in_oklch,_var(--primary)_8%,_transparent)]
            [&_[data-part=dropzone][data-dragging]]:text-foreground [&_[data-part=dropzone][data-disabled]]:opacity-50
            [&_[data-part=dropzone][data-disabled]]:cursor-not-allowed [&_[data-part=list]]:grid [&_[data-part=list]]:gap-xs
            [&_[data-part=list]]:m-0 [&_[data-part=list]]:p-0 [&_[data-part=list]]:list-none [&_[data-part=item]]:flex
            [&_[data-part=item]]:items-center [&_[data-part=item]]:gap-sm
            [&_[data-part=item]]:[padding:var(--space-sm)_var(--space-md)]
            [&_[data-part=item]]:border-[length:var(--border-width)] [&_[data-part=item]]:border-solid
            [&_[data-part=item]]:border-border [&_[data-part=item]]:rounded-lg [&_[data-part=item]]:[corner-shape:squircle]
            [&_[data-part=item]]:bg-card [&_[data-part=item]]:text-sm [&_[data-part=file-info]]:grid
            [&_[data-part=file-info]]:[gap:0.25rem] [&_[data-part=file-info]]:[min-inline-size:0]
            [&_[data-part=file-info]]:[flex:1] [&_[data-part=file-info]]:[overflow-wrap:anywhere]
            [&_small]:text-muted-foreground [&_[data-part=remove]]:grid [&_[data-part=remove]]:place-items-center
            [&_[data-part=remove]]:flex-none [&_[data-part=remove]]:[inline-size:2rem]
            [&_[data-part=remove]]:[block-size:2rem] [&_[data-part=remove]]:[margin-inline-start:auto]
            [&_[data-part=remove]]:border-0 [&_[data-part=remove]]:border-current [&_[data-part=remove]]:border-none
            [&_[data-part=remove]]:rounded-[50%] [&_[data-part=remove]]:bg-secondary [&_[data-part=remove]]:text-foreground
            [&_[data-part=remove]]:[font-size:1.25rem] [&_[data-part=remove]]:leading-none
            [&_[data-part=remove]]:cursor-pointer [&_[data-part=remove]:hover]:bg-accent
            [&_[data-part=remove]:focus-visible]:[outline:2px_solid_var(--ring)]
            [&_[data-part=remove]:focus-visible]:[outline-offset:2px]
          "
        >
          <FileUpload.HiddenInput name="attachments" aria-label="Attachments" />
          <FileUpload.Trigger
            as="button"
            className={
              "focus-visible:[outline:none] focus-visible:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--" +
              "ring)_16%,_transparent)] [--uiify-button-rim:rgb(255_255_255_/_20%)] [--uiify-button-wash:light-dark(rgb(" +
              "255_255_255_/_15%),_rgb(255_255_255_/_30%))] relative isolate inline-flex items-center justify-center [ga" +
              "p:0.375rem] [min-block-size:44px] [min-inline-size:44px] py-0 [padding-inline:1.25rem] border-[length:var" +
              "(--border-width)] border-solid border-transparent rounded-[var(--radius-full)] bg-foreground bg-clip-padd" +
              "ing text-background text-base font-[number:var(--weight-medium)] leading-6 no-underline cursor-pointer [t" +
              "ransition:var(--transition-colors)] before:content-[''] before:absolute before:inset-0 before:z-[-1] befo" +
              "re:[border-radius:inherit] before:pointer-events-none after:content-[''] after:absolute after:inset-0 aft" +
              "er:z-[-1] after:[border-radius:inherit] after:pointer-events-none before:[background-color:var(--uiify-bu" +
              "tton-wash)] before:[filter:blur(10px)] before:[translate:0_-50%] before:[clip-path:inset(50%_0_-50%_0_rou" +
              "nd_var(--radius-full))] after:[padding:0.5px] after:[background-image:linear-gradient(to_bottom,_var(--ui" +
              "ify-button-rim),_transparent_75%)] after:[mask:linear-gradient(#fff_0_0)_content-box_exclude,_linear-grad" +
              "ient(#fff_0_0)] [&:is([data-size=sm],[data-size=icon-sm])]:[min-block-size:32px] [&:is([data-size=sm],[da" +
              "ta-size=icon-sm])]:[min-inline-size:32px] [&:is([data-size=sm],[data-size=icon-sm])]:[padding-inline:0.75" +
              "rem] [&:is([data-size=sm],[data-size=icon-sm])]:[gap:0.25rem] [&:is([data-size=sm],[data-size=icon-sm])]:" +
              "text-sm [&:is([data-size=sm],[data-size=icon-sm])]:leading-5 [&:is([data-size=lg],[data-size=icon-lg])]:[" +
              "min-block-size:56px] [&:is([data-size=lg],[data-size=icon-lg])]:[min-inline-size:56px] [&:is([data-size=l" +
              "g],[data-size=icon-lg])]:[padding-inline:1.75rem] [&:is([data-size=lg],[data-size=icon-lg])]:text-lg [&:i" +
              "s([data-size=lg],[data-size=icon-lg])]:leading-7 [&[data-size^=icon]]:px-0 [@media_(any-hover:_hover)_and" +
              "_(any-pointer:_fine)]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(" +
              "--foreground)_90%,_var(--background))] active:[&:not(:disabled,[data-disabled])]:[background-color:color-" +
              "mix(in_oklch,_var(--foreground)_80%,_var(--background))] disabled:opacity-50 disabled:cursor-not-allowed " +
              "data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed data-[variant=secondary]:[&:where(:not(:che" +
              "cked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-rim:light-dark(rgb(0_0_" +
              "0_/_5%),_rgb(255_255_255_/_10%))] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria" +
              "-pressed=true],[aria-current=page]))]:[--uiify-button-wash:light-dark(rgb(255_255_255_/_20%),_rgb(255_255" +
              "_255_/_5%))] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-" +
              "current=page]))]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] data-[variant" +
              "=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-fore" +
              "ground data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=" +
              "page]))]:[--uiify-button-rim:color-mix(in_oklch,_var(--foreground)_25%,_transparent)] data-[variant=outli" +
              "ne]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[border-color:col" +
              "or-mix(in_oklch,_var(--foreground)_20%,_transparent)] data-[variant=outline]:[&:where(:not(:checked+*,[da" +
              "ta-selected],[aria-pressed=true],[aria-current=page]))]:bg-transparent data-[variant=outline]:[&:where(:n" +
              "ot(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[variant=ou" +
              "tline]:before:content-none data-[variant=outline]:after:[inset:calc(-1_*_var(--border-width))] data-[vari" +
              "ant=outline]:after:[padding:var(--border-width)] data-[variant=outline]:[&:where(:not(:checked+*,[data-se" +
              "lected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-" +
              "color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data-[variant=ghost]:[&:where(:not(:checke" +
              "d+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-transparent data-[variant=ghost]:[&:whe" +
              "re(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[varia" +
              "nt=ghost]:before:content-none data-[variant=ghost]:after:content-none data-[variant=ghost]:[&:where(:not(" +
              ":checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disab" +
              "led])]:[background-color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data-[variant=secondary" +
              "]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disa" +
              "bled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_26%,_transparent)] data-[v" +
              "ariant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[" +
              "--uiify-button-wash:rgb(255_255_255_/_15%)] data-[variant=destructive]:[&:where(:not(:checked+*,[data-sel" +
              "ected],[aria-pressed=true],[aria-current=page]))]:bg-destructive data-[variant=destructive]:text-destruct" +
              "ive-foreground data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[a" +
              "ria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(" +
              "--destructive),_black_20%)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=outline]:[&" +
              ":where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled," +
              "[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] [@media_(any" +
              "-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[ar" +
              "ia-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-" +
              "mix(in_oklch,_var(--foreground)_10%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:da" +
              "ta-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))" +
              "]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_20%,_t" +
              "ransparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=destructive]:[&:where(:not" +
              "(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disab" +
              "led])]:[background-color:color-mix(in_oklch,_var(--destructive),_black_12%)] [&:is([data-selected],[aria-" +
              "pressed=true],[aria-current=page])]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [&:is([data-selected],[ar" +
              "ia-pressed=true],[aria-current=page])]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [&:is([data-selected]" +
              ",[aria-pressed=true],[aria-current=page])]:border-transparent [&:is([data-selected],[aria-pressed=true],[" +
              "aria-current=page])]:bg-primary [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:text-prim" +
              "ary-foreground [:checked+&]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [:checked+&]:[--uiify-button-wash" +
              ":rgb(255_255_255_/_15%)] [:checked+&]:border-transparent [:checked+&]:bg-primary [:checked+&]:text-primar" +
              "y-foreground [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[&:is([data-selected],[aria-pressed=true" +
              "],[aria-current=page]):hover:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--" +
              "primary)_88%,_var(--primary-foreground))] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[:checked:n" +
              "ot(:disabled)+&:hover]:[background-color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground" +
              "))] [:disabled+&]:opacity-50 [:disabled+&]:cursor-not-allowed [&[hidden]]:hidden data-[variant=link]:px-0" +
              " data-[variant=link]:border-0 data-[variant=link]:border-current data-[variant=link]:border-none data-[va" +
              "riant=link]:rounded-none data-[variant=link]:bg-transparent data-[variant=link]:text-primary data-[varian" +
              "t=link]:underline data-[variant=link]:[text-underline-offset:0.2em] data-[variant=link]:active:px-0 data-" +
              "[variant=link]:active:border-0 data-[variant=link]:active:border-current data-[variant=link]:active:borde" +
              "r-none data-[variant=link]:active:rounded-none data-[variant=link]:active:bg-transparent data-[variant=li" +
              "nk]:active:text-primary data-[variant=link]:active:underline data-[variant=link]:active:[text-underline-o" +
              "ffset:0.2em] data-[variant=link]:[min-inline-size:0] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:" +
              "data-[variant=link]:hover:px-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:ho" +
              "ver:border-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-current" +
              " [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-none [@media_(any-h" +
              "over:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:rounded-none [@media_(any-hover:_hover)_a" +
              "nd_(any-pointer:_fine)]:data-[variant=link]:hover:bg-transparent [@media_(any-hover:_hover)_and_(any-poin" +
              "ter:_fine)]:data-[variant=link]:hover:text-primary [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:da" +
              "ta-[variant=link]:hover:underline [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]" +
              ":hover:[text-underline-offset:0.2em] data-[variant=link]:before:content-none data-[variant=link]:after:co" +
              "ntent-none data-[variant=link]:focus-visible:[outline:2px_solid_var(--ring)] data-[variant=link]:focus-vi" +
              "sible:[outline-offset:3px] [[data-uiify-toggle]>input:focus-visible+&]:[box-shadow:0_0_0_var(--ring-width" +
              ")_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [[data-uiify-toggle-group]_[data-part=item]>input:fo" +
              "cus-visible+&]:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [[d" +
              "ata-uiify-modal][data-part=close]&]:border-transparent [[data-uiify-modal][data-part=close]&]:[background" +
              "-color:color-mix(in_oklch,_var(--foreground)_8%,_transparent)] [[data-uiify-modal][data-part=close]&]:tex" +
              "t-foreground [[data-uiify-modal][data-part=close]&:hover]:[background-color:color-mix(in_oklch,_var(--for" +
              "eground)_14%,_transparent)] [[data-uiify-modal][data-part=close]&:active]:[background-color:color-mix(in_" +
              "oklch,_var(--foreground)_20%,_transparent)] [[data-uiify-pagination]_span&:not([data-disabled])]:cursor-d" +
              "efault [[data-uiify-input-group]>[data-part=addon]>&]:[min-inline-size:0] [[data-uiify-input-group]>[data" +
              "-part=addon]>&]:[max-inline-size:100%] [[data-uiify-input-group]>[data-part=addon]>&]:whitespace-normal [" +
              "[data-uiify-input-group]>[data-part=addon]>&]:[overflow-wrap:anywhere] [[data-uiify-item-content]>&]:[jus" +
              "tify-self:start]"
            }
          >
            Choose files
          </FileUpload.Trigger>
          <FileUpload.Dropzone className="">Drop files here</FileUpload.Dropzone>
          <FileUpload.List className="">
            {(files) =>
              files.map((file, index) => (
                <FileUpload.Item key={file.name} index={index} className="">
                  <span>
                    {file.name} · {(file.size / 1024).toFixed(1)} KB
                  </span>
                  <FileUpload.ItemRemove index={index} aria-label={"Remove " + file.name}>
                    ×
                  </FileUpload.ItemRemove>
                </FileUpload.Item>
              ))
            }
          </FileUpload.List>
        </FileUpload.Root>
      );
    }
    /* app.css */
    
    @layer reset, ui, app, tokens, base, demo, components, utilities, theme;
    
    @import "@gunkin/uiify/styles/reset";
    
    @import "@gunkin/uiify/components/behavior.css";
    
    @import "@gunkin/uiify/styles/tokens";
    
    @import "@gunkin/uiify/styles/tailwind";
    
    @import "tailwindcss/utilities.css";
    
    @theme { --spacing: 0.25rem; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; }
    
    @source inline('grid gap-md [inline-size:100%] [max-inline-size:24rem] [&_[data-part=dropzone]]:flex [&_[data-part=dropzone]]:items-center [&_[data-part=dropzone]]:justify-center [&_[data-part=dropzone]]:[min-block-size:8rem] [&_[data-part=dropzone]]:p-lg [&_[data-part=dropzone]]:[border-width:2px] [&_[data-part=dropzone]]:[border-style:dashed] [&_[data-part=dropzone]]:border-input [&_[data-part=dropzone]]:rounded-xl [&_[data-part=dropzone]]:[corner-shape:squircle] [&_[data-part=dropzone]]:bg-secondary [&_[data-part=dropzone]]:text-muted-foreground [&_[data-part=dropzone]]:text-sm [&_[data-part=dropzone]]:text-center [&_[data-part=dropzone]]:[transition:var(--transition-colors)] [&_[data-part=dropzone]:hover]:border-primary [&_[data-part=dropzone]:hover]:[background-color:color-mix(in_oklch,_var(--primary)_8%,_transparent)] [&_[data-part=dropzone]:hover]:text-foreground [&_[data-part=dropzone][data-dragging]]:border-primary [&_[data-part=dropzone][data-dragging]]:[background-color:color-mix(in_oklch,_var(--primary)_8%,_transparent)] [&_[data-part=dropzone][data-dragging]]:text-foreground [&_[data-part=dropzone][data-disabled]]:opacity-50 [&_[data-part=dropzone][data-disabled]]:cursor-not-allowed [&_[data-part=list]]:grid [&_[data-part=list]]:gap-xs [&_[data-part=list]]:m-0 [&_[data-part=list]]:p-0 [&_[data-part=list]]:list-none [&_[data-part=item]]:flex [&_[data-part=item]]:items-center [&_[data-part=item]]:gap-sm [&_[data-part=item]]:[padding:var(--space-sm)_var(--space-md)] [&_[data-part=item]]:border-[length:var(--border-width)] [&_[data-part=item]]:border-solid [&_[data-part=item]]:border-border [&_[data-part=item]]:rounded-lg [&_[data-part=item]]:[corner-shape:squircle] [&_[data-part=item]]:bg-card [&_[data-part=item]]:text-sm [&_[data-part=file-info]]:grid [&_[data-part=file-info]]:[gap:0.25rem] [&_[data-part=file-info]]:[min-inline-size:0] [&_[data-part=file-info]]:[flex:1] [&_[data-part=file-info]]:[overflow-wrap:anywhere] [&_small]:text-muted-foreground [&_[data-part=remove]]:grid [&_[data-part=remove]]:place-items-center [&_[data-part=remove]]:flex-none [&_[data-part=remove]]:[inline-size:2rem] [&_[data-part=remove]]:[block-size:2rem] [&_[data-part=remove]]:[margin-inline-start:auto] [&_[data-part=remove]]:border-0 [&_[data-part=remove]]:border-current [&_[data-part=remove]]:border-none [&_[data-part=remove]]:rounded-[50%] [&_[data-part=remove]]:bg-secondary [&_[data-part=remove]]:text-foreground [&_[data-part=remove]]:[font-size:1.25rem] [&_[data-part=remove]]:leading-none [&_[data-part=remove]]:cursor-pointer [&_[data-part=remove]:hover]:bg-accent [&_[data-part=remove]:focus-visible]:[outline:2px_solid_var(--ring)] [&_[data-part=remove]:focus-visible]:[outline-offset:2px] focus-visible:[outline:none] focus-visible:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [--uiify-button-rim:rgb(255_255_255_/_20%)] [--uiify-button-wash:light-dark(rgb(255_255_255_/_15%),_rgb(255_255_255_/_30%))] relative isolate inline-flex items-center justify-center [gap:0.375rem] [min-block-size:44px] [min-inline-size:44px] py-0 [padding-inline:1.25rem] border-[length:var(--border-width)] border-solid border-transparent rounded-[var(--radius-full)] bg-foreground bg-clip-padding text-background text-base font-[number:var(--weight-medium)] leading-6 no-underline cursor-pointer [transition:var(--transition-colors)] before:absolute before:inset-0 before:z-[-1] before:[border-radius:inherit] before:pointer-events-none after:absolute after:inset-0 after:z-[-1] after:[border-radius:inherit] after:pointer-events-none before:[background-color:var(--uiify-button-wash)] before:[filter:blur(10px)] before:[translate:0_-50%] before:[clip-path:inset(50%_0_-50%_0_round_var(--radius-full))] after:[padding:0.5px] after:[background-image:linear-gradient(to_bottom,_var(--uiify-button-rim),_transparent_75%)] after:[mask:linear-gradient(#fff_0_0)_content-box_exclude,_linear-gradient(#fff_0_0)] [&:is([data-size=sm],[data-size=icon-sm])]:[min-block-size:32px] [&:is([data-size=sm],[data-size=icon-sm])]:[min-inline-size:32px] [&:is([data-size=sm],[data-size=icon-sm])]:[padding-inline:0.75rem] [&:is([data-size=sm],[data-size=icon-sm])]:[gap:0.25rem] [&:is([data-size=sm],[data-size=icon-sm])]:text-sm [&:is([data-size=sm],[data-size=icon-sm])]:leading-5 [&:is([data-size=lg],[data-size=icon-lg])]:[min-block-size:56px] [&:is([data-size=lg],[data-size=icon-lg])]:[min-inline-size:56px] [&:is([data-size=lg],[data-size=icon-lg])]:[padding-inline:1.75rem] [&:is([data-size=lg],[data-size=icon-lg])]:text-lg [&:is([data-size=lg],[data-size=icon-lg])]:leading-7 [&[data-size^=icon]]:px-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_90%,_var(--background))] active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_80%,_var(--background))] disabled:opacity-50 disabled:cursor-not-allowed data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-rim:light-dark(rgb(0_0_0_/_5%),_rgb(255_255_255_/_10%))] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-wash:light-dark(rgb(255_255_255_/_20%),_rgb(255_255_255_/_5%))] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-rim:color-mix(in_oklch,_var(--foreground)_25%,_transparent)] data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[border-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-transparent data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[variant=outline]:before:content-none data-[variant=outline]:after:[inset:calc(-1_*_var(--border-width))] data-[variant=outline]:after:[padding:var(--border-width)] data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-transparent data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:text-foreground data-[variant=ghost]:before:content-none data-[variant=ghost]:after:content-none data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_16%,_transparent)] data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_26%,_transparent)] data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:[--uiify-button-wash:rgb(255_255_255_/_15%)] data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:bg-destructive data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:active:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--destructive),_black_20%)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=outline]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=ghost]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_10%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=secondary]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=destructive]:[&:where(:not(:checked+*,[data-selected],[aria-pressed=true],[aria-current=page]))]:hover:[&:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--destructive),_black_12%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:border-transparent [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:bg-primary [&:is([data-selected],[aria-pressed=true],[aria-current=page])]:text-primary-foreground [:checked+&]:[--uiify-button-rim:rgb(255_255_255_/_20%)] [:checked+&]:[--uiify-button-wash:rgb(255_255_255_/_15%)] [:checked+&]:border-transparent [:checked+&]:bg-primary [:checked+&]:text-primary-foreground [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[&:is([data-selected],[aria-pressed=true],[aria-current=page]):hover:not(:disabled,[data-disabled])]:[background-color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:[:checked:not(:disabled)+&:hover]:[background-color:color-mix(in_oklch,_var(--primary)_88%,_var(--primary-foreground))] [:disabled+&]:opacity-50 [:disabled+&]:cursor-not-allowed [&[hidden]]:hidden data-[variant=link]:px-0 data-[variant=link]:border-0 data-[variant=link]:border-current data-[variant=link]:border-none data-[variant=link]:rounded-none data-[variant=link]:bg-transparent data-[variant=link]:text-primary data-[variant=link]:underline data-[variant=link]:[text-underline-offset:0.2em] data-[variant=link]:active:px-0 data-[variant=link]:active:border-0 data-[variant=link]:active:border-current data-[variant=link]:active:border-none data-[variant=link]:active:rounded-none data-[variant=link]:active:bg-transparent data-[variant=link]:active:text-primary data-[variant=link]:active:underline data-[variant=link]:active:[text-underline-offset:0.2em] data-[variant=link]:[min-inline-size:0] [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:px-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-0 [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-current [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:border-none [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:rounded-none [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:bg-transparent [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:text-primary [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:underline [@media_(any-hover:_hover)_and_(any-pointer:_fine)]:data-[variant=link]:hover:[text-underline-offset:0.2em] data-[variant=link]:before:content-none data-[variant=link]:after:content-none data-[variant=link]:focus-visible:[outline:2px_solid_var(--ring)] data-[variant=link]:focus-visible:[outline-offset:3px] [[data-uiify-toggle]>input:focus-visible+&]:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [[data-uiify-toggle-group]_[data-part=item]>input:focus-visible+&]:[box-shadow:0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_16%,_transparent)] [[data-uiify-modal][data-part=close]&]:border-transparent [[data-uiify-modal][data-part=close]&]:[background-color:color-mix(in_oklch,_var(--foreground)_8%,_transparent)] [[data-uiify-modal][data-part=close]&]:text-foreground [[data-uiify-modal][data-part=close]&:hover]:[background-color:color-mix(in_oklch,_var(--foreground)_14%,_transparent)] [[data-uiify-modal][data-part=close]&:active]:[background-color:color-mix(in_oklch,_var(--foreground)_20%,_transparent)] [[data-uiify-pagination]_span&:not([data-disabled])]:cursor-default [[data-uiify-input-group]>[data-part=addon]>&]:[min-inline-size:0] [[data-uiify-input-group]>[data-part=addon]>&]:[max-inline-size:100%] [[data-uiify-input-group]>[data-part=addon]>&]:whitespace-normal [[data-uiify-input-group]>[data-part=addon]>&]:[overflow-wrap:anywhere] [[data-uiify-item-content]>&]:[justify-self:start]');
    
    @source inline("before:content-[''] after:content-['']");
    
    @layer base { :root { --uiify-control-text: var(--text-sm); } @media (pointer: coarse) { :root { --uiify-control-text: var(--text-base); } } }
    
    /* Authored animation and registered properties used by the Tailwind skin.
     * Visual rules belong in utility recipes; only at-rule definitions live here. */
    @layer components {
      @keyframes uiify-presence-in {
        from {
          opacity: 0;
          scale: var(--presence-scale);
        }
      }
    }
    
    @layer components {
      @keyframes uiify-presence-out {
        to {
          opacity: 0;
          scale: var(--presence-scale);
        }
      }
    }
    
    @property --uiify-spinner-tail {
      syntax: "<angle>";
      inherits: false;
      initial-value: 0deg;
    }
    
    @property --uiify-spinner-length {
      syntax: "<angle>";
      inherits: false;
      initial-value: 36deg;
    }
    
    @layer components {
      @keyframes uiify-spinner-rotate {
        to {
          transform: rotate(360deg);
        }
      }
    }
    
    @layer components {
      @keyframes uiify-spinner-orbit {
        0% {
          --uiify-spinner-tail: 0deg;
          --uiify-spinner-length: 36deg;
        }
    
        50% {
          --uiify-spinner-tail: 90deg;
          --uiify-spinner-length: 324deg;
        }
    
        100% {
          --uiify-spinner-tail: 360deg;
          --uiify-spinner-length: 36deg;
        }
      }
    }
    
    @layer components {
      @keyframes uiify-skeleton-pulse {
        50% {
          opacity: 0.45;
        }
      }
    }
    
    @layer components {
      @keyframes uiify-skeleton-shimmer {
        to {
          background-position: -200% 0;
        }
      }
    }
    
    @layer components {
      @keyframes uiify-skeleton-reveal {
        from {
          opacity: 0;
        }
        to {
          opacity: 1;
        }
      }
    }
    
    @property --candle-body-height {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 0%;
    }
    
    @property --candle-body-top {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 50%;
    }
    
    @property --candle-slot {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 100%;
    }
    
    @property --candle-wick-height {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 0%;
    }
    
    @property --candle-wick-top {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 50%;
    }
    
    @property --candle-x {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 0%;
    }
    
    @property --candle-scale {
      syntax: "<number>";
      inherits: true;
      initial-value: 1;
    }
    
    @property --line-y {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 50%;
    }
    
    @property --line-prev-y {
      syntax: "<percentage>";
      inherits: true;
      initial-value: 50%;
    }
    
    @property --line-count {
      syntax: "<integer>";
      inherits: false;
      initial-value: 1;
    }
    
    @property --line-scale {
      syntax: "<number>";
      inherits: true;
      initial-value: 1;
    }
    
    @layer components {
      @keyframes uiify-otp-input-caret-blink {
        50% {
          opacity: 0;
        }
      }
    }

    API

    FileUpload.Root

    الخاصيةالنوعافتراضيالوصف
    childrenReactNode—أجزاء رفع الملفات: المدخل المخفي وزر التفعيل ومنطقة الإسقاط والقائمة.
    valuereadonly File[]—الملفات الحالية، وتجعل المكوّن متحكّمًا به.
    defaultValuereadonly File[][]الملفات الأولية للمكوّن غير المتحكّم به.
    onValueChange(files: File[]) => void—تُستدعى بالملفات المقبولة كلما تغيّر التحديد.
    onReject(rejections: FileRejection[]) => void—تُستدعى بالملفات التي أخفقت في التحقق وأسباب الإخفاق.
    acceptstring[][]أنواع الملفات المقبولة، كامتدادات أو أنواع MIME.
    maxFilesnumber—أقصى عدد ملفات يمكن الاحتفاظ بها في الوقت نفسه.
    maxSizenumber—أقصى حجم مقبول للملف بالبايت.
    minSizenumber—أدنى حجم مقبول للملف بالبايت.
    multiplebooleanfalseيتيح للمنتقي تحديد أكثر من ملف واحد.
    disabledbooleanfalseيعطّل المنتقي ومنطقة الإسقاط وأزرار الإزالة.

    FileUpload.HiddenInput

    الخاصيةالنوعافتراضيالوصف
    classNamestring—الفئة المطبّقة على مدخل الملف الأصلي.

    FileUpload.Trigger

    الخاصيةالنوعافتراضيالوصف
    childrenReactNode—محتوى عنصر التحكم الذي يفتح منتقي الملفات.
    classNamestring—الفئة المطبّقة على عنصر التفعيل.
    renderReactElement | ((props, state) => ReactElement)—استبدل العنصر المعروض مع الحفاظ على توصيلات السلوك وإمكانية الوصول.

    FileUpload.Dropzone

    الخاصيةالنوعافتراضيالوصف
    childrenReactNode—محتوى هدف الإسقاط.
    classNamestring—الفئة المطبّقة على عنصر منطقة الإسقاط.
    renderReactElement | ((props, state) => ReactElement)—استبدل العنصر المعروض مع الحفاظ على توصيلات السلوك وإمكانية الوصول.

    FileUpload.List

    الخاصيةالنوعافتراضيالوصف
    childrenReactNode | ((files: readonly File[]) => ReactNode)—اعرض الملفات المقبولة من القائمة الحية. تنعكس تغييرات القيمة المتحكّم بها وإعادة الضبط الخارجية فورًا.
    classNamestring—الفئة المطبّقة على عنصر القائمة.

    FileUpload.Item

    الخاصيةالنوعافتراضيالوصف
    childrenReactNode—محتوى يصف الملف، مثل اسمه وحجمه.
    classNamestring—الفئة المطبّقة على العنصر.
    index*number—موضع الملف الذي يمثّله هذا العنصر.
    renderReactElement | ((props, state) => ReactElement)—استبدل العنصر المعروض مع الحفاظ على توصيلات السلوك وإمكانية الوصول.

    FileUpload.ItemRemove

    الخاصيةالنوعافتراضيالوصف
    classNamestring—الفئة المطبّقة على زر الإزالة.
    index*number—موضع الملف الذي يزيله هذا الزر.

    FileRejection

    الخاصيةالنوعافتراضيالوصف
    file*File—الملف الذي لم يُقبل.
    reason*"accept" | "max-size" | "max-files"—القاعدة التي أخفق الملف في استيفائها.

    لوحة المفاتيح

    المفتاحالإجراء
    Enter / Spaceفتح منتقي الملفات من Trigger أو إزالة ملف مركّز
    Tabالتنقل بين زر تفعيل المنتقي وعناصر تحكم إزالة الملفات

    إمكانية الوصول

    وفّر لـ HiddenInput تسمية للتقنيات المساعدة. تتلقى List الملفات المقبولة وتعرض أسماءها وأحجامها وأزرار إزالتها ذات التسميات. يدعم Root قيمة متحكّمًا بها والتحقق التراكمي من maxFiles وmaxSize وaccept؛ ويبلّغ onReject عن الملفات المرفوضة. تمنع الجذور المعطّلة إجراءات المنتقي والإسقاط والإزالة. تتطلب معالجة الملفات الإماهة.

    نقاط التنسيق

    data-uiify-file-uploaddata-partdata-disableddata-state