@astroapps/aria-base 1.3.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Select.tsx ADDED
@@ -0,0 +1,90 @@
1
+ import React from "react";
2
+ import {
3
+ Select as AriaSelect,
4
+ SelectProps as AriaSelectProps,
5
+ Button,
6
+ ListBox,
7
+ ListBoxItemProps,
8
+ SelectValue,
9
+ ValidationResult,
10
+ } from "react-aria-components";
11
+ import { tv } from "tailwind-variants";
12
+ import { Description, FieldError, Label } from "./Field";
13
+ import { DropdownItem, DropdownSection, DropdownSectionProps } from "./ListBox";
14
+ import { Popover } from "./Popover";
15
+ import { composeTailwindRenderProps, focusRing } from "./utils";
16
+
17
+ const styles = tv({
18
+ extend: focusRing,
19
+ base: "flex items-center text-start gap-4 w-full font-sans border border-black/10 dark:border-white/10 cursor-default rounded-lg pl-3 pr-2 h-9 min-w-[64px] transition bg-neutral-50 dark:bg-neutral-700 [-webkit-tap-highlight-color:transparent]",
20
+ variants: {
21
+ isDisabled: {
22
+ false:
23
+ "text-neutral-800 dark:text-neutral-300 hover:bg-neutral-100 pressed:bg-neutral-200 dark:hover:bg-neutral-600 dark:pressed:bg-neutral-500 group-invalid:outline group-invalid:outline-red-600 forced-colors:group-invalid:outline-[Mark]",
24
+ true: "border-transparent dark:border-transparent text-neutral-200 dark:text-neutral-600 forced-colors:text-[GrayText] bg-neutral-100 dark:bg-neutral-800",
25
+ },
26
+ },
27
+ });
28
+
29
+ export interface SelectProps<T extends object>
30
+ extends Omit<AriaSelectProps<T>, "children"> {
31
+ label?: string;
32
+ description?: string;
33
+ errorMessage?: string | ((validation: ValidationResult) => string);
34
+ items?: Iterable<T>;
35
+ children: React.ReactNode | ((item: T) => React.ReactNode);
36
+ }
37
+
38
+ export function Select<T extends object>({
39
+ label,
40
+ description,
41
+ errorMessage,
42
+ children,
43
+ items,
44
+ ...props
45
+ }: SelectProps<T>) {
46
+ return (
47
+ <AriaSelect
48
+ {...props}
49
+ className={composeTailwindRenderProps(
50
+ props.className,
51
+ "group flex flex-col gap-1 relative font-sans",
52
+ )}
53
+ >
54
+ {label && <Label>{label}</Label>}
55
+ <Button className={styles}>
56
+ <SelectValue className="flex-1 text-sm">
57
+ {({ selectedText, defaultChildren }) =>
58
+ selectedText || defaultChildren
59
+ }
60
+ </SelectValue>
61
+ <i
62
+ aria-hidden
63
+ className={
64
+ "w-4 h-4 fa fa-chevron-down text-neutral-600 dark:text-neutral-400 forced-colors:text-[ButtonText] group-disabled:text-neutral-200 dark:group-disabled:text-neutral-600 forced-colors:group-disabled:text-[GrayText]"
65
+ }
66
+ />
67
+ </Button>
68
+ {description && <Description>{description}</Description>}
69
+ <FieldError>{errorMessage}</FieldError>
70
+ <Popover className="min-w-(--trigger-width)">
71
+ <ListBox
72
+ items={items}
73
+ className="outline-hidden box-border p-1 max-h-[inherit] overflow-auto [clip-path:inset(0_0_0_0_round_.75rem)]"
74
+ >
75
+ {children}
76
+ </ListBox>
77
+ </Popover>
78
+ </AriaSelect>
79
+ );
80
+ }
81
+
82
+ export function SelectItem(props: ListBoxItemProps) {
83
+ return <DropdownItem {...props} />;
84
+ }
85
+
86
+ export function SelectSection<T extends object>(
87
+ props: DropdownSectionProps<T>,
88
+ ) {
89
+ return <DropdownSection {...props} />;
90
+ }
package/src/index.ts CHANGED
@@ -2,3 +2,6 @@ export * from "./Button";
2
2
  export * from "./Dialog";
3
3
  export * from "./Popover";
4
4
  export * from "./Modal";
5
+ export * from "./Select";
6
+ export * from "./utils";
7
+ export * from "./Field";
package/src/utils.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { composeRenderProps } from "react-aria-components";
2
+ import { twMerge } from "tailwind-merge";
3
+ import { tv } from "tailwind-variants";
4
+
5
+ export const focusRing = tv({
6
+ base: "outline outline-secondary-600 dark:outline-secondary-500 forced-colors:outline-[Highlight] outline-offset-2",
7
+ variants: {
8
+ isFocusVisible: {
9
+ false: "outline-0",
10
+ true: "outline-2",
11
+ },
12
+ },
13
+ });
14
+
15
+ export function composeTailwindRenderProps<T>(
16
+ className: string | ((v: T) => string) | undefined,
17
+ tw: string,
18
+ ): string | ((v: T) => string) {
19
+ return composeRenderProps(className, (className) => twMerge(tw, className));
20
+ }