Skip to content

Commit

Permalink
Merge branch 'next' into next-tags-input-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
huntabyte committed Nov 20, 2024
2 parents ae3c13e + 1205e92 commit 7a48a54
Show file tree
Hide file tree
Showing 25 changed files with 761 additions and 492 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-tomatoes-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"bits-ui": patch
---

`DropdownMenu.Trigger` should default to `type="button"` while enabling users to override via the `type` prop
5 changes: 5 additions & 0 deletions .changeset/early-mails-visit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"bits-ui": patch
---

fix: DateField 24 hour cycling
5 changes: 5 additions & 0 deletions .changeset/hot-dolphins-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"bits-ui": patch
---

fix: issue causing labels associated with radio group items not to select the item
5 changes: 5 additions & 0 deletions .changeset/polite-dogs-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"bits-ui": patch
---

DropdownMenu.Trigger `type="button"` by default
6 changes: 6 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"beige-meals-repair",
"big-fishes-double",
"blue-guests-jump",
"brave-tomatoes-dream",
"brown-pillows-hear",
"calm-snails-refuse",
"chatty-mayflies-invite",
Expand All @@ -18,6 +19,7 @@
"cool-cats-compete",
"cool-readers-camp",
"curvy-buttons-check",
"early-mails-visit",
"early-points-study",
"empty-clouds-crash",
"famous-hotels-glow",
Expand All @@ -33,6 +35,7 @@
"green-pumpkins-provide",
"healthy-jeans-dream",
"healthy-ligers-sell",
"hot-dolphins-check",
"hot-donkeys-accept",
"hot-owls-compete",
"itchy-drinks-explode",
Expand All @@ -53,10 +56,12 @@
"olive-ads-enjoy",
"olive-worms-bow",
"pink-eyes-begin",
"polite-dogs-change",
"polite-moons-glow",
"proud-snakes-occur",
"rare-islands-divide",
"rare-waves-lick",
"real-berries-jog",
"red-mails-tease",
"selfish-boxes-cheat",
"serious-shrimps-pump",
Expand All @@ -72,6 +77,7 @@
"soft-comics-sort",
"stale-weeks-ring",
"strong-walls-glow",
"stupid-candles-do",
"tall-deers-cough",
"tame-ads-heal",
"ten-dogs-care",
Expand Down
5 changes: 5 additions & 0 deletions .changeset/real-berries-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"bits-ui": patch
---

fix: `TabTrigger` default tabindex handling
5 changes: 5 additions & 0 deletions .changeset/stupid-candles-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"bits-ui": patch
---

fix: export `Portal` from `Menubar` namespace
28 changes: 28 additions & 0 deletions packages/bits-ui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# bits-ui

## 1.0.0-next.63

### Patch Changes

- fix: export `Portal` from `Menubar` namespace ([#955](https://github.com/huntabyte/bits-ui/pull/955))

## 1.0.0-next.62

### Patch Changes

- DropdownMenu.Trigger `type="button"` by default ([#953](https://github.com/huntabyte/bits-ui/pull/953))

## 1.0.0-next.61

### Patch Changes

- `DropdownMenu.Trigger` should default to `type="button"` while enabling users to override via the `type` prop ([#951](https://github.com/huntabyte/bits-ui/pull/951))

- fix: `TabTrigger` default tabindex handling ([#949](https://github.com/huntabyte/bits-ui/pull/949))

## 1.0.0-next.60

### Patch Changes

- fix: DateField 24 hour cycling ([#945](https://github.com/huntabyte/bits-ui/pull/945))

- fix: issue causing labels associated with radio group items not to select the item ([#943](https://github.com/huntabyte/bits-ui/pull/943))

## 1.0.0-next.59

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/bits-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bits-ui",
"version": "1.0.0-next.59",
"version": "1.0.0-next.63",
"license": "MIT",
"repository": "github:huntabyte/bits-ui",
"funding": "https://github.com/sponsors/huntabyte",
Expand Down
35 changes: 30 additions & 5 deletions packages/bits-ui/src/lib/bits/date-field/date-field.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ export class DateFieldRootState {
this.states.hour.updating = next;
if (next !== null && prev.dayPeriod !== null) {
const dayPeriod = this.formatter.dayPeriod(
toDate(dateRef.set({ hour: Number.parseInt(next) }))
toDate(dateRef.set({ hour: Number.parseInt(next) })),
this.hourCycle.current
);
if (dayPeriod === "AM" || dayPeriod === "PM") {
prev.dayPeriod = dayPeriod;
Expand Down Expand Up @@ -1506,6 +1507,12 @@ class DateFieldHourSegmentState {
this.#announcer.announce("12");
return "12";
}

if (next === 0 && this.#root.hourCycle.current === 24) {
this.#announcer.announce("00");
return "00";
}

this.#announcer.announce(next);
return `${next}`;
});
Expand All @@ -1532,6 +1539,12 @@ class DateFieldHourSegmentState {
this.#announcer.announce("12");
return "12";
}

if (next === 0 && this.#root.hourCycle.current === 24) {
this.#announcer.announce("00");
return "00";
}

this.#announcer.announce(next);
return `${next}`;
});
Expand All @@ -1541,10 +1554,12 @@ class DateFieldHourSegmentState {
if (isNumberString(e.key)) {
const num = Number.parseInt(e.key);
const max =
"dayPeriod" in this.#root.segmentValues &&
this.#root.segmentValues.dayPeriod !== null
? 12
: 23;
this.#root.hourCycle.current === 24
? 23
: "dayPeriod" in this.#root.segmentValues &&
this.#root.segmentValues.dayPeriod !== null
? 12
: 23;
const maxStart = Math.floor(max / 10);
let moveToNext = false;
const numIsZero = num === 0;
Expand Down Expand Up @@ -1628,6 +1643,16 @@ class DateFieldHourSegmentState {
return `0${num}`;
}

/**
* If the new number is 0 and the hour cycle is set to 24, then we move
* to the next segment, returning the new number with a leading 0.
*/
if (num === 0 && this.#root.hourCycle.current === 24) {
moveToNext = true;
this.#root.states.hour.lastKeyZero = false;
return `0${num}`;
}

/**
* If the new number is 0, then we simply return the previous value, since
* they didn't actually type a new number.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
child,
children,
disabled = false,
type = "button",
...restProps
}: MenuTriggerProps = $props();
Expand All @@ -23,7 +24,7 @@
),
});
const mergedProps = $derived(mergeProps(restProps, triggerState.props));
const mergedProps = $derived(mergeProps(restProps, triggerState.props, { type }));
</script>

<FloatingLayerAnchor {id}>
Expand Down
1 change: 1 addition & 0 deletions packages/bits-ui/src/lib/bits/menubar/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { default as SubContentStatic } from "$lib/bits/menu/components/menu-sub-
export { default as SubTrigger } from "$lib/bits/menu/components/menu-sub-trigger.svelte";
export { default as RadioGroup } from "$lib/bits/menu/components/menu-radio-group.svelte";
export { default as CheckboxItem } from "$lib/bits/menu/components/menu-checkbox-item.svelte";
export { default as Portal } from "$lib/bits/utilities/portal/portal.svelte";

export type {
MenubarRootProps as RootProps,
Expand Down
19 changes: 5 additions & 14 deletions packages/bits-ui/src/lib/bits/radio-group/radio-group.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { srOnlyStyles, styleToString, useRefById } from "svelte-toolbelt";
import type { FocusEventHandler, KeyboardEventHandler, MouseEventHandler } from "svelte/elements";
import type { ReadableBoxedValues, WritableBoxedValues } from "$lib/internal/box.svelte.js";
import type { WithRefProps } from "$lib/internal/types.js";
import { getAriaChecked, getAriaRequired, getDataDisabled } from "$lib/internal/attrs.js";
Expand Down Expand Up @@ -113,26 +114,17 @@ class RadioGroupItemState {
});
}

#onpointerdown = (e: PointerEvent) => {
#onclick: MouseEventHandler<HTMLButtonElement> = (e) => {
if (this.#disabled.current) return;
if (e.pointerType === "touch") return e.preventDefault();
this.#root.setValue(this.#value.current);
};

#onpointerup = (e: PointerEvent) => {
if (this.#disabled.current) return;
if (e.pointerType === "touch") {
e.preventDefault();
this.#root.setValue(this.#value.current);
}
};

#onfocus = () => {
#onfocus: FocusEventHandler<HTMLButtonElement> = () => {
if (!this.#root.hasValue) return;
this.#root.setValue(this.#value.current);
};

#onkeydown = (e: KeyboardEvent) => {
#onkeydown: KeyboardEventHandler<HTMLButtonElement> = (e) => {
if (this.#isDisabled) return;
if (e.key === kbd.SPACE) {
e.preventDefault();
Expand Down Expand Up @@ -166,10 +158,9 @@ class RadioGroupItemState {
role: "radio",
tabindex: this.#tabIndex,
//
onpointerdown: this.#onpointerdown,
onpointerup: this.#onpointerup,
onkeydown: this.#onkeydown,
onfocus: this.#onfocus,
onclick: this.#onclick,
}) as const
);
}
Expand Down
37 changes: 14 additions & 23 deletions packages/bits-ui/src/lib/bits/tabs/tabs.svelte.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { untrack } from "svelte";
import { SvelteMap } from "svelte/reactivity";
import { useRefById } from "svelte-toolbelt";
import type { FocusEventHandler, KeyboardEventHandler, MouseEventHandler } from "svelte/elements";
import type { TabsActivationMode } from "./types.js";
import {
getAriaOrientation,
Expand Down Expand Up @@ -189,8 +190,11 @@ class TabsTriggerState {
});

$effect(() => {
if (this.#root.triggerIds.length) {
this.#tabIndex = this.#root.rovingFocusGroup.getTabIndex(this.#ref.current);
this.#root.triggerIds.length;
if (this.#isActive || !this.#root.value.current) {
this.#tabIndex = 0;
} else {
this.#tabIndex = -1;
}
});
}
Expand All @@ -200,29 +204,17 @@ class TabsTriggerState {
this.#root.setValue(this.#value.current);
};

#onfocus = () => {
if (this.#root.activationMode.current !== "automatic" || this.#disabled.current) return;
#onfocus: FocusEventHandler<HTMLButtonElement> = () => {
if (this.#root.activationMode.current !== "automatic" || this.#isDisabled) return;
this.activate();
};

#onpointerdown = (e: PointerEvent) => {
if (this.#disabled.current) return;
if (e.pointerType === "touch" || e.button !== 0) return e.preventDefault();
e.preventDefault();
this.#ref.current?.focus();
#onclick: MouseEventHandler<HTMLButtonElement> = (e) => {
if (this.#isDisabled) return;
this.activate();
};

#onpointerup = (e: PointerEvent) => {
if (this.#disabled.current) return;
if (e.pointerType === "touch") {
e.preventDefault();
this.#ref.current?.focus();
this.activate();
}
};

#onkeydown = (e: KeyboardEvent) => {
#onkeydown: KeyboardEventHandler<HTMLButtonElement> = (e) => {
if (this.#isDisabled) return;
if (e.key === kbd.SPACE || e.key === kbd.ENTER) {
e.preventDefault();
Expand All @@ -240,15 +232,14 @@ class TabsTriggerState {
"data-state": getTabDataState(this.#isActive),
"data-value": this.#value.current,
"data-orientation": getDataOrientation(this.#root.orientation.current),
"data-disabled": getDataDisabled(this.#disabled.current),
"data-disabled": getDataDisabled(this.#isDisabled),
"aria-selected": getAriaSelected(this.#isActive),
"aria-controls": this.#ariaControls,
[TRIGGER_ATTR]: "",
disabled: getDisabled(this.#disabled.current),
disabled: getDisabled(this.#isDisabled),
tabindex: this.#tabIndex,
//
onpointerdown: this.#onpointerdown,
onpointerup: this.#onpointerup,
onclick: this.#onclick,
onfocus: this.#onfocus,
onkeydown: this.#onkeydown,
}) as const
Expand Down
4 changes: 2 additions & 2 deletions packages/bits-ui/src/lib/internal/date-time/field/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function createContentObj(props: CreateContentObjProps) {
return "0";
} else if (!isNull(value) && !isNull(intValue)) {
const formatted = formatter.part(dateRef.set({ [part]: value }), part, {
hourCycle: props.hourCycle === 24 ? "h24" : undefined,
hourCycle: props.hourCycle === 24 ? "h23" : undefined,
});

/**
Expand Down Expand Up @@ -220,7 +220,7 @@ function getOptsByGranularity(granularity: Granularity, hourCycle: HourCycle | u
minute: "2-digit",
second: "2-digit",
timeZoneName: "short",
hourCycle: hourCycle === 24 ? "h24" : undefined,
hourCycle: hourCycle === 24 ? "h23" : undefined,
hour12: hourCycle === 24 ? false : undefined,
};

Expand Down
4 changes: 3 additions & 1 deletion packages/bits-ui/src/lib/internal/date-time/formatter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DateFormatter, type DateValue } from "@internationalized/date";
import { hasTime, isZonedDateTime, toDate } from "./utils.js";
import type { HourCycle } from "$lib/shared/date/types.js";

export type Formatter = ReturnType<typeof createFormatter>;

Expand Down Expand Up @@ -75,10 +76,11 @@ export function createFormatter(initialLocale: string) {
return new DateFormatter(locale, { weekday: length }).format(date);
}

function dayPeriod(date: Date) {
function dayPeriod(date: Date, hourCycle: HourCycle | undefined = undefined) {
const parts = new DateFormatter(locale, {
hour: "numeric",
minute: "numeric",
hourCycle: hourCycle === 24 ? "h23" : undefined,
}).formatToParts(date);
const value = parts.find((p) => p.type === "dayPeriod")?.value;
if (value === "PM") {
Expand Down
Loading

0 comments on commit 7a48a54

Please sign in to comment.