GithubHelp home page GithubHelp logo

huntabyte / bits-ui Goto Github PK

View Code? Open in Web Editor NEW
834.0 834.0 62.0 3.67 MB

The headless components for Svelte.

Home Page: https://bits-ui.com

License: MIT License

JavaScript 1.12% TypeScript 58.71% HTML 0.11% Svelte 39.46% CSS 0.61%

bits-ui's Introduction

bits-ui's People

Contributors

adriangonz97 avatar amr3k avatar azukiazusa1 avatar brucewayyn avatar cdebotton avatar drahmedshaheen avatar fbbdev avatar fong avatar github-actions[bot] avatar huntabyte avatar jordigagomerino avatar kalos-s avatar multiplehats avatar ndoy3m4n avatar ollema avatar oskar-gmerek avatar pavelstianko avatar redphoenixq avatar saturnonearth avatar sebasmaltese avatar shyakadavis avatar stordahl avatar tbdrz avatar tglide avatar thisislvca avatar tmarnet avatar waynetee avatar wysher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bits-ui's Issues

Select: Meta/Alt/Control keys used as filter

When a Select menu is open/active, you can type x to jump to the first x___ items in the list. This is great.

However, if you press CMD (and presumably Control), it jumps to the first Meta___ item in the list.
This is because ev.key === "Meta" and there's likely a filter somewhere in Bits/Melt that is using that value.

This also happens with Alt (verified) and Control keys.

Solution is to ignore the event if ev.metaKey, ev.altKey or ev.ctrlKey are true.

bug: calendar date builder not compatible with type `Builder` for render delegation

mentioned here: #184 (comment)

will take a look at the builder attrs, its likely because the attributes are as const which should be a simple fix.

...
{#each weekDates as date}
  <Calendar.Cell {date} class="!important p-0">
    <Calendar.Date asChild let:builder let:disabled {date} month={month.value}>
      <LaundryDate
        {date}
        {disabled}
        reservations={data.reservations[date.toString()]}
        apartment={data.apartment}
        builders={[builder]}
      />
    </Calendar.Date>
  </Calendar.Cell>
{/each}
...

where:

<!-- LaundryDate.svelte -->
<script lang="ts">
	import Timeslot from './Timeslot.svelte';
	import { isToday, type DateValue } from '@internationalized/date';
	import { timeslots } from './timeslots';
	import type { SerializableReservationMap } from './types';
	import { builderActions, getAttrs, type Builder } from 'bits-ui';

	export let date: DateValue;
	export let disabled: boolean;
	export let reservations: SerializableReservationMap | undefined;
	export let apartment: string | undefined;
	export let builders: Builder[] = [];

	$: today = isToday(date, 'Europe/Stockholm');
</script>
...

gives:

❯ pnpm check

> [email protected] check /Users/s0001325/repos/skiftesgatan
> svelte-kit sync && svelte-check --tsconfig ./tsconfig.json


====================================
Loading svelte-check in workspace: /Users/s0001325/repos/skiftesgatan
Getting Svelte diagnostics...


 (x2)
 (x3)
 (x4)
/Users/s0001325/repos/skiftesgatan/src/routes/laundry/calendar/+page.svelte:88:22
Error: Type '((cellValue: DateValue, monthValue: DateValue) => { readonly role: "button"; readonly 'aria-label': string; readonly 'aria-selected': true | undefined; readonly 'aria-disabled': true | undefined; ... 8 more ...; readonly tabindex: 0 | ... 1 more ... | undefined; }) & { ...; } & { ...; }' is not assignable to type 'Builder'.
  Index signature for type 'string' is missing in type '((cellValue: DateValue, monthValue: DateValue) => { readonly role: "button"; readonly 'aria-label': string; readonly 'aria-selected': true | undefined; readonly 'aria-disabled': true | undefined; ... 8 more ...; readonly tabindex: 0 | ... 1 more ... | undefined; }) & { ...; } & { ...; }'. (ts)
                                                                                apartment={data.apartment}
                                                                                builders={[builder]}
                                                                        />


====================================
svelte-check found 1 error and 0 warnings in 1 file
 ELIFECYCLE  Command failed with exit code 1.

How to prevent outer element closed when click nested popover element?

Current Behavior

When I render nested popover element for example there is a Select component inside a Popover component, when click on the item of select items, the popover will be closed due to closeOnOutsideClick is true be default.

Expected Behavior

When popover components are nested, don't close outer one when click nested element that rendered in portal

Steps To Reproduce

  1. create modal or popover
  2. create a select in modal or popover
  3. select some item
  4. the modal or popover will be closed
iShot_2023-08-25_21.53.30.mp4

Link to Reproduction / Stackblitz

No response

More Information

No response

export meltui

plz export melt Ui if we ever want to use melt Ui natively, i can download melt Ui as another lib but not sure if it is right if bits already have included.

Heavy stuttering without hardware acceleration

Context

I've been using Melt for my latest project, and Bits with shadcn-svelte seems to be a good alternative to not have to work with builders all the time and have some extra components that aren't available in Melt.

Issue

I have hardware acceleration disabled on Chrome because of YouTube, and noticed heavy stuttering when comparing dialogs between Melt and Bits. Melt's animations (even if I would have to add them myself in my project) are smooth and don't seem to have any issues without acceleration, while Bits' animations are slow and essentially display 3-4 frames of said animation.

It's not so much of an issue, but the tool I'm working on will most of the time run on really underpowered PCs (i3 without GPUs), and the performance hit will most likely be visible considering I have a Ryzen 5 in my dev workstation.

TLDR

Some performance improvements would be more than welcomed for our "toaster" users

Change Dialog focus behavior on open?

Change Type

Addition

Proposed Changes

When a Dialog is opened, it automatically focuses on the first input element. On mobile, this causes the virtual keyboard to open immediately.
Is there a way to change the focus behavior for Dialogs?
I've tried passing openFocus={null} to the root of the Dialog but it did not work. I am not sure if I'm using it correctly.

Library is not completely tree-shakable

Thank you for your hard work.

I have this component:

<script lang="ts">
  import { Button } from 'bits-ui';

  export { cls as class };

  let cls = '';
</script>

<Button.Root class={cls} on:click on:change on:keydown on:keyup on:mouseenter on:mouseleave>
  <slot />
</Button.Root>

Using the component results in the createBitAttrs function being bundled although it is not used. Well, at least not by the button component.

See the screenshot:
image

It is even bundled and called at the client (data-${ is used in this function):
image

After removing the exports field in the package.json and importing from 'bits-ui/dist/bits/button/index.js' the function is gone. So, I guess it is related to star-exporting all components.

This also happens for many other functions.

Controlled `DropdownMenuSub` is not working

Current Behavior

I'm trying to control the DropdownMenuSub component, so that the secondary dropdown is opened on click, not on hover. Setting the controlled props open and onOpenChange does not seem to have any effect.

Expected Behavior

I'd expect either <DropdownMenuSub onOpenChange={() => false}> and/or <DropdownMenuSub open={false}> to prevent the secondary menu from opening.

(As a next step, I'd like to make the secondary menu open on click events, not on hover events. Guidance on the best way to do that would also be appreciated.)

Steps To Reproduce

The following does not prevent the secondary dropdown menu from opening:

<DropdownMenu>
    <DropdownMenuTrigger>Open menu</DropdownMenuTrigger>
    <DropdownMenuContent>
      <DropdownMenuSub open={false} onOpenChange={() => false}>
        <DropdownMenuSubTrigger>Option 1</DropdownMenuSubTrigger>
        <DropdownMenuSubContent>
          <DropdownMenuItem>Submenu option 1</DropdownMenuItem>
          <DropdownMenuItem>Submenu option 2</DropdownMenuItem>
        </DropdownMenuSubContent>
      </DropdownMenuSub>
      <DropdownMenuItem>Option 2</DropdownMenuItem>
    </DropdownMenuContent>
  </DropdownMenu>

Link to Reproduction / Stackblitz (reproduction template)

No response

More Information

No response

Checkbox 'disabled' attribute not applied to button

When the checkbox component is disabled, you can still focus it with the keyboard because the 'disabled' attribute is not applied to the button element. You can observe this on the shadcn-svelte docs by selecting the disabled checkbox example by pressing the tab key (the 'focus' ring around the checkbox becomes visible).

Feature: Combox

Melt introduced a builder for Combox and it is also available in shadcn /-svelte but I can't find it on bits-ui

I have a project that relies on it and created it multiple times using melt but would like to modify the code and reuse it from bits-ui

I'm excited to contribute to bits-ui by integrating the Melt builder. I've already forked the code, analyzed the patterns, and reviewed the types. Since this feature is crucial for my projects, I'd like to make it available for the bits-ui community.

If the task isn't assigned yet, please assign it to me. I'll keep the communication clear and concise throughout the process.

Looking forward to being part of the bits-ui development!

Feature Request: Expose `el` prop to access the underlying element

We should provide a way for users to access the underlying DOM element directly via a prop for all the components.

This would allow users to do something like:

<script lang="ts">
	import { Button } from "bits-ui";

	let el: HTMLButtonElement;
</script>

<Button.Root bind:el />

Feature request: Popover overlay

Describe the feature in detail (code, mocks, or screenshots encouraged)

It would be nice to have the option to add an overlay to the Popover component like done in, for example, headless UI (https://headlessui.com/react/popover#adding-an-overlay).

Maybe this falls under bits ui or meltui.

Thanks!

What type of pull request would this be?

None

Provide relevant links or additional information.

No response

<Menubar.Item /> missing `on:click` event

Current Behavior

<Menubar.Item on:click={() => {}} />
Argument of type '"click"' is not assignable to parameter of type 'keyof ItemEvents'.
type ItemEvents<T extends Element = HTMLDivElement> = {
    focusin: CustomEventHandler<FocusEvent, T>;
    focusout: CustomEventHandler<FocusEvent, T>;
    keydown: CustomEventHandler<KeyboardEvent, T>;
    pointerdown: CustomEventHandler<PointerEvent, T>;
    pointerleave: CustomEventHandler<PointerEvent, T>;
    pointermove: CustomEventHandler<PointerEvent, T>;
};

Expected Behavior

I'm expecting it to work just like in dropdowns, the following currently works:

<DropdownMenu.Item on:click={() => {}} />

Steps To Reproduce

Use any <Menubar.Item /> component.

Link to Reproduction / Stackblitz

No response

More Information

No response

Add target attribute to menu items

Describe the feature in detail (code, mocks, or screenshots encouraged)

TypeScript gives the following error if you try to add a target attribute to a DropdownMenu.Item component if it's a link (adding the href attribute):
Type '{ target: string; href: string; }' is not assignable to type '$$Props'. Object literal may only specify known properties, and '"target"' does not exist in type '$$Props'. ts(2322)

An a element should have support for the target attribute

What type of pull request would this be?

Enhancement

Provide relevant links or additional information.

No response

Dialog.Root's onOpenChange callback is not called when dialog open

Discussed in huntabyte/shadcn-svelte#308

Originally posted by pseriesadmin September 20, 2023
Dialog.Root's onOpenChange callback is not called when dialog open, is this a bug?

<script lang="ts">
  ...
  
  export let open = false;

  const onOpenChange = (state: boolean | undefined) => {
     console.log(state); // <---- not called when state is true
  };


</script>

<Dialog.Root
  bind:open
  {onOpenChange}
  closeOnEscape={false}
  closeOnOutsideClick={false}
>
...
</Dialog.Root>

@huntabyte Hello, I spent a few hours trying to figure out what I'm doing wrong but found that I'm not alone. It's impossible for me to continue my work because I can't subscribe to the event and do some functions inside it. If we add
$: console.log(open); to track the state, it works fine, but I can not do some of my functionality inside of it unfortunately as a temporal solution.

Request to add the ability to pass "href" to DropdownMenu.Item

I find that for some of the dropdown menus I want to use an href instead of just a div that I can add event listeners to.

You may ask, why not just put an Anchor tag inside the DropdownMenu.Item slot - well, it can't be pressed via keyboard-navigation, and also does not fill the DropdownMenu.Item entirely due to padding of the parent wrapper.

But couldn't you just wrap the DropdownMenu.Item in an anchor tag? Well...I don't want to mess with the indexing that is already there (plus it doesn't look as clean).

It would be awesome to just be able to pass an href prop to the DropdownMenu.Item component and turn the div into an Anchor tag, in the same way you can do this with the Button component.

An example being...

<Dropdown.Item>Clickable button as normal</Dropdown.Item> <!-- The normal -->
<Dropdown.Item href="/settings">Settings</Dropdown.Item> <!-- This would turn into <a href="/settings"></a> -->

What do you think?

Checkbox `onCheckedChange` fires immediately

Noticed specifically within a Dropdown context, but happens on its own too.

The onCheckedChange fires immediately when the component renders (is visible, in this case). The expectation is that it only fires on change.

<Dropdown.Root positioning={{ placement: 'bottom-end' }}>
	<Dropdown.Trigger asChild let:builder>
		<Button variant="outline" builders={[builder]} size="sm" class="ml-auto hidden h-8 lg:flex">
			<Settings2 class="mr-2 h-4 w-4" /> View
		</Button>
	</Dropdown.Trigger>

	<Dropdown.Content class="w-[150px]">
		<Dropdown.Label>Toggle columns</Dropdown.Label>
		<Dropdown.Separator />

		{#each columns as col,idx (idx)}
			<Dropdown.CheckboxItem checked={col.visible} onCheckedChange={console.log}>
				{col.label}
			</Dropdown.CheckboxItem>
		{/each}
	</Dropdown.Content>
</Dropdown.Root>

In the above, all 6 columns are visible, so clicking on the Dropdown.Trigger will log true 6 times.
However, then unchecking an item will log false twice – expect once.

Screen Shot 2023-12-01 at 12 40 54 PM

Transitions

Hey there,
Can we please have transition and transitionConfig props on the content elements?
It'd be nice like to have some animated Dialog Content.

Weird Select behavior

Description

The Select component acts weardly when using the multiple property. If I try to save the selected value to a variable, the variable doesn't seem to react to the changes.

Steps to reproduce

Use the following code snippet:

<script lang="ts">
  import { Select } from "bits-ui";

  let selected = [];

  $: console.log(selected);
</script>

<Select.Root multiple bind:selected>
  <Select.Trigger>
    <Select.Label>Label</Select.Label>
    <Select.Value placeholder="Choose..." />
  </Select.Trigger>
  <Select.Content>
    <Select.Group>
      <Select.Item value="apple">Apple</Select.Item>
      <Select.Item value="peach">Peach</Select.Item>
      <Select.Item value="banana">Banana</Select.Item>
      <Select.Item value="blueberry">Blueberry</Select.Item>
    </Select.Group>
  </Select.Content>
</Select.Root>

When multiple values are selected, the selected variable doesn't update.

Expected behavior

The selected variable should update each time a value is selected, populating an array.

Actual behavior

The selected variable doesn't update at all.

Remove `role=button` in Button

Thanks a lot for your efforts on this Hunter! Svelte desperately needs a proper UI library and I'm looking forward using it in my projects.

I noticed role=button is used in the Button component which incorrectly tells screen readers that the link is a button, but it's merely displayed as a button. It doesn't have the same functionality.

See mdn and this picocss issue.

When omitting the href param it actually is a button which should make role=button unnecessary.

Prevent Select onValueChange from firing on init

I have onValueChange on the Select.Root so I can monitor when a Select's value has changed, much like a native Select HTML element. The issue is, that it fires when the component is mounted.

<Select.Root onValueChange={handleChange} bind:value={itemId}>

My solution was to check whether the initial value that is bound was the same as the "changed" value, and return if it is.

let itemId;

function handleChange(id: string) {
    if (id === itemId) return;
    ....
}

It would be great if the Select onValueChange did not call when mounted.

ContextMenu items are not clickable

Description

Clicking on context menu items closes the menu without triggering the item action.

Steps to reproduce

  1. Use the ContextMenu component as shown in docs
  2. Right click to open the context menu
  3. Click on any menu item
  4. The menu closes without the item action occurring

Expected behavior

Clicking a menu item should trigger its associated action.

Actual behavior

Clicking any menu item closes the context menu without triggering the action.

Additional information

The Overlay component from bits-ui/dist/internal/overlay.svelte overlaps the context menu. This prevents the menu items from receiving click events.

`data-` attributes are correctly forwarded, but are not included in typescript types.

Current Behavior

When attempting to apply any data attribute that's not explicitly a sveltekit attribute (data-testid for example), typescript is reporting that it is not a valid prop. However, that attribute is correctly present in the DOM.

image

Expected Behavior

Typescript is happy with data-testid and other data attributes.

Steps To Reproduce

  1. Import Avatar component from bits-ui
  2. Apply data-testid="avatar" to Avatar Root component
  3. See typescript error

Link to Reproduction / Stackblitz (reproduction template)

No response

More Information

I have attempted to extend the props on the Avatar component doing something like this:

import 'bits-ui';

declare module 'bits-ui' {
	interface Avatar {
		props: {
			[key: `data-${string}`]: any;
		};
	}
}

But this doesn't appear to work.

feature: select year easily with Date Picker

Common use case for using date picker is for picking date of birth.

For some reason, many users (especially non-technical) wants to click everything, instead of simply write it into input.
I don't understand that, but it is what it is.

More background: Few of my clients asks for this feature. I also watched users trying to use native Chrome date picker, trying to change year. Even if the feature is there, they end up clicking down arrow hundreds times for few minutes. It makes me nuts!
I also think there must a reason why native Chrome, Material UI and other libraries implemented this.

Possible solution:
add simple way to change year.
Easiest solution, will be add two more buttons "<<" ">>" for this.
Other, but IMHO more user friendly solution is to have Select/Autocomplete, or tiles of years to pick (like MUI did: https://mui.com/x/react-date-pickers/date-picker/).

PS. It will be awesome to have same thing in shadcn/svelte, or have easy way to extend it. I know that shadcn-ui don't have it yet, but i found this issue: shadcn-ui/ui#1996

I'll be happy to implement this feature, but first I'd like to get your feedback.

Sveltev5 date range picker to many updates

Hello, I faced an issue related to sveltev5 when I try to change the dates it just throws too many updates.

I found you're PR with the preview with the preview of the new svelte and there on the tab date range picker you can check the reproduction of this bug https://bits-ui-git-svelte-5-huntabyte.vercel.app/docs/components/date-range-picker

P.S. I understand that the work is still in progress, but I just wanted to point to the problem. Thanks in advance

feature: Pagination

Describe the feature in detail (code, mocks, or screenshots encouraged)

Melt includes a pagination builder: https://www.melt-ui.com/docs/builders/pagination
https://github.com/shadcn-ui/ui doesn't have a pagination component yet, but what I did for my current project was: taking the Melt builder as a base and to use the pagination buttons as displayed on https://ui.shadcn.com/examples/tasks as a style guide.

Is this something that you'd be comfortable with adding, as far as breaking feature-parity with https://github.com/shadcn-ui/ui goes? If it's a welcome addition, I'm willing to contribute in the form of the required primitives and components ofc.

What type of pull request would this be?

New Feature

Provide relevant links or additional information.

No response

Avatar.Image component not updating src when user logs out

Current Behavior

When using the Avatar.Image component to display a user's profile image, the src attribute is not updated when the user logs out and userAvatarUrl is set to undefined. The fallback updates properly, but the image does not get set to display: none. A page refresh is required for the Avatar.Image src to render with an empty src.

Expected Behavior

The Avatar.Image src attribute should be updated when the user logs out and userAvatarUrl is set to undefined, without requiring a page refresh.

Steps To Reproduce

  1. Use the Avatar.Image component to display a user's profile image.
  2. Log out, causing userAvatarUrl to be set to undefined.
  3. Observe that the Avatar.Image src attribute is not updated and the image does not get set to display: none.
  4. Refresh the page and observe that the Avatar.Image src now renders with an empty src.

Link to Reproduction / Stackblitz

No response

More Information

A current workaround for this issue is to use an if conditional to check if userAvatarUrl is defined before rendering the Avatar.Image component.

Here is the full code with the workaround the and original code with the issue included

<script>
	import { userProfileStore } from '$dashboardStores/userProfileAndSupabaseStores';

	import * as Avatar from '$globalComponents/ui/avatar';
	import * as Popover from '$globalComponents/ui/popover';
	import AccountPopUpMenuItems from './AccountPopUpMenuItems.svelte';

	$: userAvatarUrl = $userProfileStore?.avatarUrl;
	$: emailInitial = $userProfileStore?.email?.charAt(0).toUpperCase();
	$: fullNameInitial = $userProfileStore?.fullName?.split(' ')[0]?.[0];
</script>

<Popover.Root>
	<Popover.Trigger type="button" class="rounded-full">
		<!-- fix for avatar image still showing after logout -->
		<Avatar.Root>
			{#if userAvatarUrl}
				<Avatar.Image src={userAvatarUrl} alt="Profile avatar" />
			{:else}
				<Avatar.Fallback class="bg-gradient-to-b from-blue-500 to-purple-500" style="display:block">
					{fullNameInitial ?? emailInitial ?? ''}
				</Avatar.Fallback>
			{/if}
		</Avatar.Root>

		<!-- this is the original code with the issue -->
		<Avatar.Root>
			<Avatar.Image src={userAvatarUrl ?? ''} alt="Profile avatar" />
			<Avatar.Fallback class="bg-gradient-to-b from-blue-500 to-purple-500">
				{fullNameInitial ?? emailInitial ?? ''}
			</Avatar.Fallback>
		</Avatar.Root>
	</Popover.Trigger>

	<Popover.Content class="p-2 mt-2 w-fit">
		<menu class="grid gap-2">
			<AccountPopUpMenuItems />
		</menu>
	</Popover.Content>
</Popover.Root>

Select's "multiple" typing is incorrect as it doesn't allow true

I think the Multiple generic needs to be passed into the CreateSelectProps from melt-ui.

From a very quick initial exploration, changing the Props definition to pass in whether the Select is multiple solves the issue.

type Props<Value = unknown, Multiple extends boolean = false> = Expand<OmitOpen<Omit<CreateSelectProps<Value, Multiple>, "selected" | "defaultSelected" | "onSelectedChange">> & {
    selected?: CreateSelectProps["defaultSelected"] & {};
    onSelectedChange?: OnChangeFn<CreateSelectProps["defaultSelected"]>;
    open?: boolean & {};
    onOpenChange?: OnChangeFn<boolean>;
}>;

select list is not scrollable

Current Behavior

When creating a select component with bits-ui and it has more options than the height of the screen / select list can display, the configured height of the list component is not honored, nor is the height of the screen. The list is not scrollable.

Expected Behavior

A select component with more options to display within the defined list height or screen height should be scrollable.
A set height for Select.Content should be honored and should be scrollable

Steps to Reproduce

  1. create a select component with a list of like 100 options
  2. set the height for the select to something like h-32
  3. klick on the select component to display the list
  4. try to scroll

More Information

  1. I found this when trying to use the select component in shadcn-svelte. Then reproduced it in a vanilla svelte project using bits-ui directly.
  2. I could not reproduce it in a project using melt-ui
  3. using arrow keys works

snippet:

<script lang="ts">
  import {Select}from "bits-ui";
  const array = Array.from({ length: 100 });
  
  </script>
  <Select.Root >
      <Select.Trigger class="w-[180px]">
        <Select.Value placeholder="Select an option" />
      </Select.Trigger>
      <Select.Content class="bg-black h-32">
        <Select.Group>
          <Select.Label>Fruits</Select.Label>
          {#each array as option}
          <Select.Item value={option}
            >{option}</Select.Item
          >
          {/each}
        </Select.Group>
      </Select.Content>
      <Select.Input name="optionSelect" />
  </Select.Root>

<Checkbox.Input> is not a valid SSR component

Description

When using the <Checkbox.Input> component from the bits-ui library, an error is thrown stating that <Checkbox.Input> is not a valid SSR component. The error message suggests reviewing the build configuration to ensure that dependencies are compiled, rather than imported as pre-compiled modules.

Steps to reproduce

  1. Import the Checkbox component from the bits-ui library.
  2. Attempt to use the <Checkbox.Input> component in your code.
  3. Observe the error message: Error: <Checkbox.Input> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules. Otherwise you may need to fix a <Checkbox.Input>.

Expected behavior

The <Checkbox.Input> component should be available for use without throwing any errors.

Actual behavior

An error is thrown when attempting to use the <Checkbox.Input> component.

Select: Rework?

The selected approach is awkward, tbh. In practice, it prevents users from binding to a real value. Instead, theyre forced to construct a selected and then use onSelectedChange to manually update the original value + the selected {value,label}

IMO something like the below should be offered as default implementation. Would PR but it breaks away from the standard export signature of the rest of the components; eg export { Root as Select } would likely be replaced by export { Below as Select } which then means the <X.Root/> === <X> aliasing pattern is broken.

<script lang="ts" context="module">
  export type Option<T=string|number> = {
    value: T;
    label: string;
  };
</script>

<script lang="ts">
  import { Select as Primitive } from 'bits-ui';
  import type { HTMLButtonAttributes } from 'svelte/elements';
  import * as Select from '.';

  import { find } from '@/utils';

  type T = $$Generic<string | number>;

  type $$Props = HTMLButtonAttributes & {
    open?: boolean;
    disabled?: boolean;
    required?: boolean;
    id?: string;
    name?: string;
    value?: T | null;
    placeholder?: string;
    options: Option<T>[];
  }

  export let open = false;
  export let disabled = false;
  export let required = false;

  export let id: string | undefined = undefined;
  export let name: string | undefined = undefined;

  export let options: Option<T>[];
  export let value: T | null | undefined = undefined;
  export let placeholder = 'Select option';

  $: selected = value != null ? find(options, x => x.value === value) : undefined;
  $: display = selected ? selected.label : placeholder;

  function onChange(option: unknown) {
    let o = option as Option<T>;
    if (o) value = o.value;
  }
</script>

<Primitive.Root
  loop bind:open
  {disabled} {required} {name}
  {selected} onSelectedChange={onChange}
>
  <Select.Trigger {id} {...$$restProps}>
    <Select.Value
      placeholder={display}
      class={ !value && "text-muted-foreground" || "" }
    />
  </Select.Trigger>

  <Select.Input />

  <Select.Content class="p-0 w-[400px] max-h-96 overflow-y-auto overscroll-y-contain">
    {#each options as o (o.value)}
      <Select.Item value={o.value}>{o.label}</Select.Item>
    {/each}
  </Select.Content>
</Primitive.Root>

Either the Select.Content or the Select.Item loop could be slotted w/ the above parts as default markup

DropdownMenu.Item as a link/button

Hello,

I would like to use the DropdownMenu with links, maybe I didn't notice how to achieve that correctly.

For the moment I have to put a a element inside which don't cover the whole element so when hovering the borders of the item we can't click:

<DropdownMenu.Root>
    <DropdownMenu.Trigger class="relative flex rounded-full bg-white text-sm ring-2 ring-white ring-opacity-20 focus:outline-none focus:ring-opacity-100">
        <Avatar.Root class="h-9 w-9">
            <span class="absolute -inset-1.5"></span>
            <Avatar.Image src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" />
        </Avatar.Root>
    </DropdownMenu.Trigger>
    <DropdownMenu.Content class="mt-2">
        <DropdownMenu.Group>
            <DropdownMenu.Label>@username</DropdownMenu.Label>
            <DropdownMenu.Separator />
            <DropdownMenu.Item>
                <a href="#" class="flex items-center w-full">
                    <Contact class="h-4 w-4 mr-1" />
                    Profile
                </a>
            </DropdownMenu.Item>
            <DropdownMenu.Item>
                <a href="#" class="flex items-center w-full">
                    <LogOut class="h-4 w-4 mr-1" />
                    Logout
                </a>
            </DropdownMenu.Item>
        </DropdownMenu.Group>
    </DropdownMenu.Content>
</DropdownMenu.Root>

Did I missed something or is it a missing feature ?

Thanks for the library, very cool ! I'm using it with your work-in-progress of shadcn-svelte with melt-ui :)

cannot install the package

npm install bits-ui
npm ERR! code EBADENGINE
npm ERR! engine Unsupported engine
npm ERR! engine Not compatible with your version of node/npm: [email protected]
npm ERR! notsup Not compatible with your version of node/npm: [email protected]
npm ERR! notsup Required: {"node":"^18 || >=20"}
npm ERR! notsup Actual: {"npm":"9.8.1","node":"v19.0.1"}

preventScroll on Sheet/Dialog

My dialogs and sheets allow the background to scroll no matter what I try, even with redeclaring the preventScroll default.

I may be missing something, but I'm not sure what after diffing my React port w/ the original React markup & the Svelte/bits-ui examples.

The only real differences I see are that bits doesn't apply pointer-events: none to the body, the Dialog markups live inside a <div> portal wrapper, and the overlay doesn't have pointer-events: auto applied.... but even when manually fixing all that in DevTools/Elements, I'm still able to scroll the underlying content.

Ideas?

CheckboxInput component is not exported

Description

The Checkbox structure on the docs shows that the Checkbox component exports Checkbox, Indicator, and Input. However, the Input component doesn't seem to be exported.

Steps to reproduce

  1. Import the Checkbox component from bits-ui.
  2. Attempt to use the <Checkbox.Input> component.
  3. Observe the error: Property 'Input' does not exist on type 'typeof import("/project-path/node_modules/bits-ui/dist/bits/checkbox/index")'.

Additional information

  • The Checkbox.InputProps is exported correctly.
  • The error message suggests that the Input component is not being exported from the bits-ui/dist/bits/checkbox/index file.

Expected behavior

The Input component should be exported and available for use as described in the docs.

Actual behavior

The Input component is not exported and attempting to use it results in an error.

Avatar.Image crossorigin does not work as expected

crossorigin="anonymous" does not work on Image.

Set this attribute and set the top level headers in the handle hook in hooks.server.ts:

const response = await resolve(event);

response.headers.set('Cross-Origin-Embedder-Policy', 'require-corp');
response.headers.set('Cross-Origin-Opener-Policy', 'same-origin');

return response;

You get this error:
Access to image at 'https://github.com/shadcn.png' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.