@xingxingmofashu/ui 0.1.8 → 0.1.10
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/README.md +8 -7
- package/dist/components/button.d.ts +1 -1
- package/dist/components/button.mjs +7 -2
- package/dist/components/card.d.ts +1 -1
- package/dist/components/checkbox-group.d.ts +41 -0
- package/dist/components/checkbox-group.mjs +223 -0
- package/dist/components/checkbox.d.ts +1 -1
- package/dist/components/checkbox.mjs +4 -0
- package/dist/components/field.d.ts +23 -0
- package/dist/components/field.mjs +62 -0
- package/dist/components/fieldset.d.ts +18 -0
- package/dist/components/fieldset.mjs +45 -0
- package/dist/components/form.d.ts +14 -0
- package/dist/components/form.mjs +21 -0
- package/dist/components/input.d.ts +1 -5
- package/dist/components/input.mjs +5 -35
- package/dist/components/menu.d.ts +8 -23
- package/dist/components/menu.mjs +11 -2
- package/dist/components/popover.d.ts +1 -12
- package/dist/components/radio-group.d.ts +1 -1
- package/dist/components/radio-group.mjs +7 -1
- package/dist/components/select.d.ts +1 -14
- package/dist/components/select.mjs +5 -3
- package/dist/components/slider.d.ts +2 -6
- package/dist/components/slider.mjs +4 -0
- package/dist/components/switch.mjs +3 -1
- package/dist/components/tabs.d.ts +1 -5
- package/dist/components/toggle-group.d.ts +1 -1
- package/dist/components/toggle-group.mjs +4 -0
- package/dist/components/toggle.d.ts +1 -1
- package/dist/components/toggle.mjs +4 -0
- package/dist/components/tooltip.d.ts +3 -18
- package/dist/components/tooltip.mjs +2 -2
- package/dist/index.d.ts +5 -1
- package/dist/index.mjs +6 -0
- package/dist/internal/fieldset.d.ts +8 -0
- package/dist/internal/fieldset.mjs +13 -0
- package/dist/theme/alert-dialog.mjs +2 -2
- package/dist/theme/card.mjs +1 -1
- package/dist/theme/checkbox-group.d.ts +41 -0
- package/dist/theme/checkbox-group.mjs +111 -0
- package/dist/theme/dialog.mjs +2 -2
- package/dist/theme/field.d.ts +25 -0
- package/dist/theme/field.mjs +66 -0
- package/dist/theme/fieldset.d.ts +5 -0
- package/dist/theme/fieldset.mjs +14 -0
- package/dist/theme/form.d.ts +4 -0
- package/dist/theme/form.mjs +6 -0
- package/dist/theme/input.d.ts +0 -2
- package/dist/theme/input.mjs +10 -10
- package/dist/theme/tabs.mjs +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<picture>
|
|
2
|
-
<source media="(prefers-color-scheme: dark)" srcset=".github/assets/surface-lab-dark.png">
|
|
3
|
-
<source media="(prefers-color-scheme: light)" srcset=".github/assets/surface-lab-light.png">
|
|
4
|
-
<img alt="The Liquid Glass Surface Lab panel showing glass components over the default image background in light mode." width="1024" src=".github/assets/surface-lab-light.png">
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/xingxingmofashu/ui/main/.github/assets/surface-lab-dark.png">
|
|
3
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/xingxingmofashu/ui/main/.github/assets/surface-lab-light.png">
|
|
4
|
+
<img alt="The Liquid Glass Surface Lab panel showing glass components over the default image background in light mode." width="1024" src="https://raw.githubusercontent.com/xingxingmofashu/ui/main/.github/assets/surface-lab-light.png">
|
|
5
5
|
</picture>
|
|
6
6
|
|
|
7
7
|
<div align="center">
|
|
@@ -14,15 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
|
-
`@xingxingmofashu/ui` is a collection of
|
|
17
|
+
`@xingxingmofashu/ui` is a collection of typed [React](https://react.dev)
|
|
18
18
|
components with a Liquid Glass visual style, built with
|
|
19
19
|
[Tailwind CSS](https://tailwindcss.com) and
|
|
20
20
|
[Tailwind Variants](https://www.tailwind-variants.org). Glass surfaces, rim
|
|
21
21
|
highlights, and inner shadows are drawn entirely with CSS.
|
|
22
22
|
|
|
23
|
-
The package ships twenty-
|
|
24
|
-
Checkbox, Dialog, Drawer,
|
|
25
|
-
|
|
23
|
+
The package ships twenty-five components: Accordion, Alert Dialog, Button,
|
|
24
|
+
Card, Checkbox, Checkbox Group, Dialog, Drawer, Field, Fieldset, Form, Input,
|
|
25
|
+
Menu, Popover, Progress, Radio Group, Scroll Area, Select, Slider, Switch, Tabs,
|
|
26
|
+
Toast, Toggle, Toggle Group, and Tooltip.
|
|
26
27
|
|
|
27
28
|
> [!NOTE]
|
|
28
29
|
> Requires React 19, React DOM 19, Tailwind CSS 4, Node.js 22+, and an
|
|
@@ -18,6 +18,6 @@ interface ButtonProps extends Omit<UIButtonProps, "ref" | "style" | "className">
|
|
|
18
18
|
/** Icon rendered after the label. */
|
|
19
19
|
trailingIcon?: React.ReactNode;
|
|
20
20
|
}
|
|
21
|
-
declare function Button({ className, ui, children, label, leadingIcon, trailingIcon, size, ...props }: ButtonProps): React.JSX.Element;
|
|
21
|
+
declare function Button({ className, ui, children, label, leadingIcon, trailingIcon, size, disabled, ...props }: ButtonProps): React.JSX.Element;
|
|
22
22
|
export { Button };
|
|
23
23
|
export type { ButtonProps };
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
} from "@base-ui/react/button";
|
|
5
5
|
import { cn } from "cn";
|
|
6
6
|
import * as React from "react";
|
|
7
|
+
import { useFieldsetDisabled } from "../internal/fieldset.mjs";
|
|
7
8
|
import theme from "../theme/button.mjs";
|
|
8
9
|
function Button({
|
|
9
10
|
className,
|
|
@@ -13,15 +14,19 @@ function Button({
|
|
|
13
14
|
leadingIcon,
|
|
14
15
|
trailingIcon,
|
|
15
16
|
size,
|
|
17
|
+
disabled,
|
|
16
18
|
...props
|
|
17
19
|
}) {
|
|
18
20
|
const styles = theme({ size });
|
|
21
|
+
const fieldsetDisabled = useFieldsetDisabled(disabled);
|
|
22
|
+
const content = label || children;
|
|
19
23
|
return /* @__PURE__ */ React.createElement(
|
|
20
24
|
UIButton,
|
|
21
25
|
{
|
|
22
26
|
"data-slot": "root",
|
|
23
27
|
className: cn(styles.root(), ui?.root, className),
|
|
24
|
-
...props
|
|
28
|
+
...props,
|
|
29
|
+
disabled: fieldsetDisabled
|
|
25
30
|
},
|
|
26
31
|
/* @__PURE__ */ React.createElement("span", { "data-slot": "base", className: cn(styles.base(), ui?.base) }, /* @__PURE__ */ React.createElement(
|
|
27
32
|
"span",
|
|
@@ -46,7 +51,7 @@ function Button({
|
|
|
46
51
|
"aria-hidden": "true"
|
|
47
52
|
},
|
|
48
53
|
leadingIcon
|
|
49
|
-
) : null, /* @__PURE__ */ React.createElement("span", { "data-slot": "label", className: cn(styles.label(), ui?.label) },
|
|
54
|
+
) : null, content ? /* @__PURE__ */ React.createElement("span", { "data-slot": "label", className: cn(styles.label(), ui?.label) }, content) : null, trailingIcon ? /* @__PURE__ */ React.createElement(
|
|
50
55
|
"span",
|
|
51
56
|
{
|
|
52
57
|
"data-slot": "trailing-icon",
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { type ComponentConfig } from "../internal/tv";
|
|
3
3
|
import theme from "../theme/card";
|
|
4
4
|
type Card = ComponentConfig<typeof theme>;
|
|
5
|
-
type CardProps = Omit<React.ComponentProps<"div">, "title"> & {
|
|
5
|
+
type CardProps = Omit<React.ComponentProps<"div">, "style" | "title"> & {
|
|
6
6
|
/** Classes merged into the root element. */
|
|
7
7
|
className?: string;
|
|
8
8
|
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Checkbox as UICheckbox } from "@base-ui/react/checkbox";
|
|
2
|
+
import { CheckboxGroup as UICheckboxGroup } from "@base-ui/react/checkbox-group";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { type VariantProps } from "tailwind-variants";
|
|
5
|
+
import { type ComponentConfig } from "../internal/tv";
|
|
6
|
+
import theme from "../theme/checkbox-group";
|
|
7
|
+
type CheckboxGroup = ComponentConfig<typeof theme>;
|
|
8
|
+
/** One entry in the group. */
|
|
9
|
+
type CheckboxGroupItemProps<Value extends string = string> = Omit<UICheckbox.Root.Props, "checked" | "defaultChecked" | "children" | "className" | "onCheckedChange" | "parent" | "style" | "value"> & {
|
|
10
|
+
/** Value that identifies the option in the group value. */
|
|
11
|
+
value: Value;
|
|
12
|
+
/** Visible label rendered next to the control. */
|
|
13
|
+
label?: React.ReactNode;
|
|
14
|
+
/** Supporting text rendered under the label. */
|
|
15
|
+
description?: React.ReactNode;
|
|
16
|
+
/** Tailwind classes merged into the entry root. */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Tailwind classes for control slots, keyed by `data-slot`. */
|
|
19
|
+
ui?: Partial<Pick<CheckboxGroup["slots"], "item" | "box" | "fill" | "glass" | "overlay" | "indicator" | "indicatorIcon" | "wrapper" | "itemLabel" | "itemDescription">>;
|
|
20
|
+
};
|
|
21
|
+
type CheckboxGroupProps<Value extends string = string> = Omit<UICheckboxGroup.Props, "allValues" | "children" | "className" | "defaultValue" | "onValueChange" | "style" | "value"> & VariantProps<typeof theme> & Pick<UICheckbox.Root.Props, "name" | "form" | "readOnly"> & {
|
|
22
|
+
/** Entries rendered by the group. */
|
|
23
|
+
items: readonly CheckboxGroupItemProps<Value>[];
|
|
24
|
+
/** Visible label for the group. */
|
|
25
|
+
label?: React.ReactNode;
|
|
26
|
+
/** Supporting text rendered under the group label. */
|
|
27
|
+
description?: React.ReactNode;
|
|
28
|
+
/** Controlled checked values. */
|
|
29
|
+
value?: readonly Value[];
|
|
30
|
+
/** Initial checked values when uncontrolled. */
|
|
31
|
+
defaultValue?: readonly Value[];
|
|
32
|
+
/** Called when a checkbox in the group is ticked or unticked. */
|
|
33
|
+
onValueChange?: (value: Value[], details: UICheckboxGroup.ChangeEventDetails) => void;
|
|
34
|
+
/** Tailwind classes merged into the group root. */
|
|
35
|
+
className?: string;
|
|
36
|
+
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
37
|
+
ui?: CheckboxGroup["slots"];
|
|
38
|
+
};
|
|
39
|
+
declare function CheckboxGroup<Value extends string = string>({ className, ui, size, items, label, description, name, form, readOnly, disabled, value, defaultValue, onValueChange, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }: CheckboxGroupProps<Value>): React.JSX.Element;
|
|
40
|
+
export { CheckboxGroup };
|
|
41
|
+
export type { CheckboxGroupItemProps, CheckboxGroupProps };
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Checkbox as UICheckbox } from "@base-ui/react/checkbox";
|
|
3
|
+
import { CheckboxGroup as UICheckboxGroup } from "@base-ui/react/checkbox-group";
|
|
4
|
+
import { cn } from "cn";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { mergeIds } from "../internal/aria.mjs";
|
|
7
|
+
import { useFieldsetDisabled } from "../internal/fieldset.mjs";
|
|
8
|
+
import theme from "../theme/checkbox-group.mjs";
|
|
9
|
+
import { CheckIcon } from "./icons/check.mjs";
|
|
10
|
+
import { DashIcon } from "./icons/dash.mjs";
|
|
11
|
+
function CheckboxGroup({
|
|
12
|
+
className,
|
|
13
|
+
ui,
|
|
14
|
+
size,
|
|
15
|
+
items,
|
|
16
|
+
label,
|
|
17
|
+
description,
|
|
18
|
+
name,
|
|
19
|
+
form,
|
|
20
|
+
readOnly,
|
|
21
|
+
disabled,
|
|
22
|
+
value,
|
|
23
|
+
defaultValue,
|
|
24
|
+
onValueChange,
|
|
25
|
+
"aria-describedby": ariaDescribedBy,
|
|
26
|
+
"aria-label": ariaLabel,
|
|
27
|
+
"aria-labelledby": ariaLabelledBy,
|
|
28
|
+
...props
|
|
29
|
+
}) {
|
|
30
|
+
const styles = theme({ size });
|
|
31
|
+
const fieldsetDisabled = useFieldsetDisabled(disabled);
|
|
32
|
+
const labelId = React.useId();
|
|
33
|
+
const descriptionId = React.useId();
|
|
34
|
+
const labelledBy = ariaLabelledBy || (label && !ariaLabel ? labelId : void 0);
|
|
35
|
+
const hasName = Boolean(label || ariaLabel || labelledBy);
|
|
36
|
+
const describedBy = mergeIds(
|
|
37
|
+
ariaDescribedBy,
|
|
38
|
+
description && hasName ? descriptionId : void 0
|
|
39
|
+
);
|
|
40
|
+
function handleValueChange(next, details) {
|
|
41
|
+
onValueChange?.(next, details);
|
|
42
|
+
}
|
|
43
|
+
return /* @__PURE__ */ React.createElement(
|
|
44
|
+
UICheckboxGroup,
|
|
45
|
+
{
|
|
46
|
+
...props,
|
|
47
|
+
"aria-describedby": describedBy,
|
|
48
|
+
"aria-label": ariaLabel,
|
|
49
|
+
...labelledBy ? { "aria-labelledby": labelledBy } : {},
|
|
50
|
+
disabled: fieldsetDisabled,
|
|
51
|
+
value,
|
|
52
|
+
defaultValue,
|
|
53
|
+
onValueChange: handleValueChange,
|
|
54
|
+
"data-slot": "root",
|
|
55
|
+
className: cn(styles.root(), ui?.root, className)
|
|
56
|
+
},
|
|
57
|
+
label || description ? /* @__PURE__ */ React.createElement("div", { "data-slot": "header", className: cn(styles.header(), ui?.header) }, label ? /* @__PURE__ */ React.createElement(
|
|
58
|
+
"span",
|
|
59
|
+
{
|
|
60
|
+
id: labelId,
|
|
61
|
+
"data-slot": "label",
|
|
62
|
+
className: cn(styles.label(), ui?.label)
|
|
63
|
+
},
|
|
64
|
+
label
|
|
65
|
+
) : null, description ? /* @__PURE__ */ React.createElement(
|
|
66
|
+
"span",
|
|
67
|
+
{
|
|
68
|
+
id: descriptionId,
|
|
69
|
+
"data-slot": "description",
|
|
70
|
+
className: cn(styles.description(), ui?.description)
|
|
71
|
+
},
|
|
72
|
+
description
|
|
73
|
+
) : null) : null,
|
|
74
|
+
/* @__PURE__ */ React.createElement("div", { "data-slot": "items", className: cn(styles.items(), ui?.items) }, items.map((item) => /* @__PURE__ */ React.createElement(
|
|
75
|
+
CheckboxGroupItem,
|
|
76
|
+
{
|
|
77
|
+
key: item.value,
|
|
78
|
+
...item,
|
|
79
|
+
name: item.name ?? name,
|
|
80
|
+
form: item.form ?? form,
|
|
81
|
+
readOnly: item.readOnly ?? readOnly,
|
|
82
|
+
ui: {
|
|
83
|
+
item: cn(ui?.item, item.ui?.item),
|
|
84
|
+
box: cn(ui?.box, item.ui?.box),
|
|
85
|
+
fill: cn(ui?.fill, item.ui?.fill),
|
|
86
|
+
glass: cn(ui?.glass, item.ui?.glass),
|
|
87
|
+
overlay: cn(ui?.overlay, item.ui?.overlay),
|
|
88
|
+
indicator: cn(ui?.indicator, item.ui?.indicator),
|
|
89
|
+
indicatorIcon: cn(
|
|
90
|
+
ui?.indicatorIcon,
|
|
91
|
+
item.ui?.indicatorIcon
|
|
92
|
+
),
|
|
93
|
+
wrapper: cn(
|
|
94
|
+
styles.wrapper(),
|
|
95
|
+
ui?.wrapper,
|
|
96
|
+
item.ui?.wrapper
|
|
97
|
+
),
|
|
98
|
+
itemLabel: cn(ui?.itemLabel, item.ui?.itemLabel),
|
|
99
|
+
itemDescription: cn(
|
|
100
|
+
ui?.itemDescription,
|
|
101
|
+
item.ui?.itemDescription
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
)))
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
function CheckboxGroupItem({
|
|
109
|
+
className,
|
|
110
|
+
ui,
|
|
111
|
+
label,
|
|
112
|
+
description,
|
|
113
|
+
value,
|
|
114
|
+
name,
|
|
115
|
+
form,
|
|
116
|
+
readOnly,
|
|
117
|
+
"aria-describedby": ariaDescribedBy,
|
|
118
|
+
"aria-label": ariaLabel,
|
|
119
|
+
"aria-labelledby": ariaLabelledBy,
|
|
120
|
+
...props
|
|
121
|
+
}) {
|
|
122
|
+
const styles = theme();
|
|
123
|
+
const labelId = React.useId();
|
|
124
|
+
const descriptionId = React.useId();
|
|
125
|
+
const hasName = Boolean(label || ariaLabel || ariaLabelledBy);
|
|
126
|
+
const labelledBy = ariaLabelledBy || (label && !ariaLabel ? labelId : void 0);
|
|
127
|
+
const describedBy = mergeIds(
|
|
128
|
+
ariaDescribedBy,
|
|
129
|
+
description && hasName ? descriptionId : void 0
|
|
130
|
+
);
|
|
131
|
+
return /* @__PURE__ */ React.createElement(
|
|
132
|
+
UICheckbox.Root,
|
|
133
|
+
{
|
|
134
|
+
...props,
|
|
135
|
+
value,
|
|
136
|
+
name,
|
|
137
|
+
form,
|
|
138
|
+
readOnly,
|
|
139
|
+
"aria-describedby": describedBy,
|
|
140
|
+
"aria-label": ariaLabel,
|
|
141
|
+
"aria-labelledby": labelledBy,
|
|
142
|
+
"data-slot": "item",
|
|
143
|
+
className: cn(styles.item(), ui?.item, className)
|
|
144
|
+
},
|
|
145
|
+
/* @__PURE__ */ React.createElement(
|
|
146
|
+
"span",
|
|
147
|
+
{
|
|
148
|
+
"data-slot": "box",
|
|
149
|
+
className: cn(styles.box(), ui?.box)
|
|
150
|
+
},
|
|
151
|
+
/* @__PURE__ */ React.createElement(
|
|
152
|
+
"span",
|
|
153
|
+
{
|
|
154
|
+
"aria-hidden": "true",
|
|
155
|
+
"data-slot": "fill",
|
|
156
|
+
className: cn(styles.fill(), ui?.fill)
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
/* @__PURE__ */ React.createElement(
|
|
160
|
+
"span",
|
|
161
|
+
{
|
|
162
|
+
"aria-hidden": "true",
|
|
163
|
+
"data-slot": "glass",
|
|
164
|
+
className: cn(styles.glass(), ui?.glass)
|
|
165
|
+
},
|
|
166
|
+
/* @__PURE__ */ React.createElement(
|
|
167
|
+
"span",
|
|
168
|
+
{
|
|
169
|
+
"aria-hidden": "true",
|
|
170
|
+
"data-slot": "overlay",
|
|
171
|
+
className: cn(styles.overlay(), ui?.overlay)
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ React.createElement(
|
|
176
|
+
UICheckbox.Indicator,
|
|
177
|
+
{
|
|
178
|
+
keepMounted: true,
|
|
179
|
+
"aria-hidden": "true",
|
|
180
|
+
"data-slot": "indicator",
|
|
181
|
+
className: cn(styles.indicator(), ui?.indicator),
|
|
182
|
+
render: (indicatorProps, state) => /* @__PURE__ */ React.createElement("span", { ...indicatorProps }, /* @__PURE__ */ React.createElement(
|
|
183
|
+
"span",
|
|
184
|
+
{
|
|
185
|
+
"data-slot": "indicator-icon",
|
|
186
|
+
className: cn(styles.indicatorIcon(), ui?.indicatorIcon)
|
|
187
|
+
},
|
|
188
|
+
state.indeterminate ? /* @__PURE__ */ React.createElement(DashIcon, null) : /* @__PURE__ */ React.createElement(CheckIcon, null)
|
|
189
|
+
))
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
),
|
|
193
|
+
label || description ? /* @__PURE__ */ React.createElement(
|
|
194
|
+
"span",
|
|
195
|
+
{
|
|
196
|
+
"data-slot": "wrapper",
|
|
197
|
+
className: cn(styles.wrapper(), ui?.wrapper)
|
|
198
|
+
},
|
|
199
|
+
label ? /* @__PURE__ */ React.createElement(
|
|
200
|
+
"span",
|
|
201
|
+
{
|
|
202
|
+
id: labelId,
|
|
203
|
+
"data-slot": "item-label",
|
|
204
|
+
className: cn(styles.itemLabel(), ui?.itemLabel)
|
|
205
|
+
},
|
|
206
|
+
label
|
|
207
|
+
) : null,
|
|
208
|
+
description ? /* @__PURE__ */ React.createElement(
|
|
209
|
+
"span",
|
|
210
|
+
{
|
|
211
|
+
id: descriptionId,
|
|
212
|
+
"data-slot": "item-description",
|
|
213
|
+
className: cn(
|
|
214
|
+
styles.itemDescription(),
|
|
215
|
+
ui?.itemDescription
|
|
216
|
+
)
|
|
217
|
+
},
|
|
218
|
+
description
|
|
219
|
+
) : null
|
|
220
|
+
) : null
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
export { CheckboxGroup };
|
|
@@ -16,6 +16,6 @@ interface CheckboxProps extends Omit<UICheckbox.Root.Props, "className" | "child
|
|
|
16
16
|
/** Optional supporting text. */
|
|
17
17
|
description?: React.ReactNode;
|
|
18
18
|
}
|
|
19
|
-
declare function Checkbox({ className, ui, label, description, size, indeterminate, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }: CheckboxProps): React.JSX.Element;
|
|
19
|
+
declare function Checkbox({ className, ui, label, description, size, disabled, indeterminate, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }: CheckboxProps): React.JSX.Element;
|
|
20
20
|
export { Checkbox };
|
|
21
21
|
export type { CheckboxProps };
|
|
@@ -3,6 +3,7 @@ import { Checkbox as UICheckbox } from "@base-ui/react/checkbox";
|
|
|
3
3
|
import { cn } from "cn";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { mergeIds } from "../internal/aria.mjs";
|
|
6
|
+
import { useFieldsetDisabled } from "../internal/fieldset.mjs";
|
|
6
7
|
import theme from "../theme/checkbox.mjs";
|
|
7
8
|
import { CheckIcon } from "./icons/check.mjs";
|
|
8
9
|
import { DashIcon } from "./icons/dash.mjs";
|
|
@@ -12,6 +13,7 @@ function Checkbox({
|
|
|
12
13
|
label,
|
|
13
14
|
description,
|
|
14
15
|
size,
|
|
16
|
+
disabled,
|
|
15
17
|
indeterminate = false,
|
|
16
18
|
"aria-describedby": ariaDescribedBy,
|
|
17
19
|
"aria-label": ariaLabel,
|
|
@@ -19,6 +21,7 @@ function Checkbox({
|
|
|
19
21
|
...props
|
|
20
22
|
}) {
|
|
21
23
|
const styles = theme({ size });
|
|
24
|
+
const fieldsetDisabled = useFieldsetDisabled(disabled);
|
|
22
25
|
const labelId = React.useId();
|
|
23
26
|
const descriptionId = React.useId();
|
|
24
27
|
const hasName = Boolean(label || ariaLabel || ariaLabelledBy);
|
|
@@ -34,6 +37,7 @@ function Checkbox({
|
|
|
34
37
|
"aria-describedby": describedBy,
|
|
35
38
|
"aria-label": ariaLabel,
|
|
36
39
|
"aria-labelledby": labelledBy,
|
|
40
|
+
disabled: fieldsetDisabled,
|
|
37
41
|
indeterminate,
|
|
38
42
|
"data-slot": "root",
|
|
39
43
|
className: cn(styles.root(), ui?.root, className)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Field as UIField } from "@base-ui/react/field";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { type VariantProps } from "tailwind-variants";
|
|
4
|
+
import { type ComponentConfig } from "../internal/tv";
|
|
5
|
+
import theme from "../theme/field";
|
|
6
|
+
type Field = ComponentConfig<typeof theme>;
|
|
7
|
+
interface FieldProps extends Omit<UIField.Root.Props, "children" | "className" | "style">, VariantProps<typeof theme> {
|
|
8
|
+
/** Single Base UI control labelled and validated by the field. */
|
|
9
|
+
children: React.ReactElement;
|
|
10
|
+
/** Visible label associated with the control. */
|
|
11
|
+
label?: React.ReactNode;
|
|
12
|
+
/** Supporting text rendered under the control. */
|
|
13
|
+
description?: React.ReactNode;
|
|
14
|
+
/** Error message shown under the control. Accepts any React node. */
|
|
15
|
+
error?: React.ReactNode;
|
|
16
|
+
/** Tailwind classes merged into the field root. */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
19
|
+
ui?: Field["slots"];
|
|
20
|
+
}
|
|
21
|
+
declare function Field({ children, className, ui, size, label, description, error, invalid, disabled, ...props }: FieldProps): React.JSX.Element;
|
|
22
|
+
export { Field };
|
|
23
|
+
export type { FieldProps };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Field as UIField } from "@base-ui/react/field";
|
|
3
|
+
import { cn } from "cn";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import theme from "../theme/field.mjs";
|
|
6
|
+
function FieldError({
|
|
7
|
+
error,
|
|
8
|
+
ui
|
|
9
|
+
}) {
|
|
10
|
+
const styles = theme();
|
|
11
|
+
return /* @__PURE__ */ React.createElement(
|
|
12
|
+
UIField.Error,
|
|
13
|
+
{
|
|
14
|
+
...error ? { match: true, children: error } : {},
|
|
15
|
+
"data-slot": "error",
|
|
16
|
+
className: cn(styles.error(), ui?.error)
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
function Field({
|
|
21
|
+
children,
|
|
22
|
+
className,
|
|
23
|
+
ui,
|
|
24
|
+
size,
|
|
25
|
+
label,
|
|
26
|
+
description,
|
|
27
|
+
error,
|
|
28
|
+
invalid,
|
|
29
|
+
disabled,
|
|
30
|
+
...props
|
|
31
|
+
}) {
|
|
32
|
+
const styles = theme({ size });
|
|
33
|
+
return /* @__PURE__ */ React.createElement(
|
|
34
|
+
UIField.Root,
|
|
35
|
+
{
|
|
36
|
+
...props,
|
|
37
|
+
disabled,
|
|
38
|
+
invalid: invalid || (error ? true : void 0),
|
|
39
|
+
"data-slot": "root",
|
|
40
|
+
className: cn(styles.root(), ui?.root, className)
|
|
41
|
+
},
|
|
42
|
+
label ? /* @__PURE__ */ React.createElement(
|
|
43
|
+
UIField.Label,
|
|
44
|
+
{
|
|
45
|
+
"data-slot": "label",
|
|
46
|
+
className: cn(styles.label(), ui?.label)
|
|
47
|
+
},
|
|
48
|
+
label
|
|
49
|
+
) : null,
|
|
50
|
+
children,
|
|
51
|
+
/* @__PURE__ */ React.createElement(FieldError, { error, ui }),
|
|
52
|
+
description ? /* @__PURE__ */ React.createElement(
|
|
53
|
+
UIField.Description,
|
|
54
|
+
{
|
|
55
|
+
"data-slot": "description",
|
|
56
|
+
className: cn(styles.description(), ui?.description)
|
|
57
|
+
},
|
|
58
|
+
description
|
|
59
|
+
) : null
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
export { Field };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Fieldset as UIFieldset } from "@base-ui/react/fieldset";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { type ComponentConfig } from "../internal/tv";
|
|
4
|
+
import theme from "../theme/fieldset";
|
|
5
|
+
type Fieldset = ComponentConfig<typeof theme>;
|
|
6
|
+
interface FieldsetProps extends Omit<UIFieldset.Root.Props, "children" | "className" | "style"> {
|
|
7
|
+
/** Visible legend naming the group. */
|
|
8
|
+
legend?: React.ReactNode;
|
|
9
|
+
/** Fields and controls grouped by the fieldset. */
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
/** Tailwind classes merged into the fieldset root. */
|
|
12
|
+
className?: string;
|
|
13
|
+
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
14
|
+
ui?: Fieldset["slots"];
|
|
15
|
+
}
|
|
16
|
+
declare function Fieldset({ children, legend, disabled, className, ui, "aria-labelledby": ariaLabelledBy, ...props }: FieldsetProps): React.JSX.Element;
|
|
17
|
+
export { Fieldset };
|
|
18
|
+
export type { FieldsetProps };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fieldset as UIFieldset } from "@base-ui/react/fieldset";
|
|
3
|
+
import { cn } from "cn";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import {
|
|
6
|
+
FieldsetDisabledProvider,
|
|
7
|
+
useFieldsetDisabled
|
|
8
|
+
} from "../internal/fieldset.mjs";
|
|
9
|
+
import theme from "../theme/fieldset.mjs";
|
|
10
|
+
function Fieldset({
|
|
11
|
+
children,
|
|
12
|
+
legend,
|
|
13
|
+
disabled = false,
|
|
14
|
+
className,
|
|
15
|
+
ui,
|
|
16
|
+
"aria-labelledby": ariaLabelledBy,
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
const styles = theme();
|
|
20
|
+
const legendId = React.useId();
|
|
21
|
+
const inheritedDisabled = useFieldsetDisabled();
|
|
22
|
+
const isDisabled = inheritedDisabled || disabled;
|
|
23
|
+
const labelledBy = ariaLabelledBy ?? (legend ? legendId : void 0);
|
|
24
|
+
return /* @__PURE__ */ React.createElement(FieldsetDisabledProvider, { disabled: isDisabled }, /* @__PURE__ */ React.createElement(
|
|
25
|
+
UIFieldset.Root,
|
|
26
|
+
{
|
|
27
|
+
...props,
|
|
28
|
+
disabled: isDisabled,
|
|
29
|
+
...labelledBy ? { "aria-labelledby": labelledBy } : {},
|
|
30
|
+
"data-slot": "root",
|
|
31
|
+
className: cn(styles.root(), ui?.root, className)
|
|
32
|
+
},
|
|
33
|
+
legend ? /* @__PURE__ */ React.createElement(
|
|
34
|
+
UIFieldset.Legend,
|
|
35
|
+
{
|
|
36
|
+
id: legendId,
|
|
37
|
+
"data-slot": "legend",
|
|
38
|
+
className: cn(styles.legend(), ui?.legend)
|
|
39
|
+
},
|
|
40
|
+
legend
|
|
41
|
+
) : null,
|
|
42
|
+
children
|
|
43
|
+
));
|
|
44
|
+
}
|
|
45
|
+
export { Fieldset };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Form as UIForm } from "@base-ui/react/form";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { type ComponentConfig } from "../internal/tv";
|
|
4
|
+
import theme from "../theme/form";
|
|
5
|
+
type Form = ComponentConfig<typeof theme>;
|
|
6
|
+
type FormProps<FormValues extends Record<string, any> = Record<string, any>> = Omit<UIForm.Props<FormValues>, "className" | "style"> & {
|
|
7
|
+
/** Tailwind classes merged into the form element. */
|
|
8
|
+
className?: string;
|
|
9
|
+
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
10
|
+
ui?: Form["slots"];
|
|
11
|
+
};
|
|
12
|
+
declare function Form<FormValues extends Record<string, any> = Record<string, any>>({ className, ui, ...props }: FormProps<FormValues>): React.JSX.Element;
|
|
13
|
+
export { Form };
|
|
14
|
+
export type { FormProps };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Form as UIForm } from "@base-ui/react/form";
|
|
3
|
+
import { cn } from "cn";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import theme from "../theme/form.mjs";
|
|
6
|
+
function Form({
|
|
7
|
+
className,
|
|
8
|
+
ui,
|
|
9
|
+
...props
|
|
10
|
+
}) {
|
|
11
|
+
const styles = theme();
|
|
12
|
+
return /* @__PURE__ */ React.createElement(
|
|
13
|
+
UIForm,
|
|
14
|
+
{
|
|
15
|
+
...props,
|
|
16
|
+
"data-slot": "root",
|
|
17
|
+
className: cn(styles.root(), ui?.root, className)
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
export { Form };
|
|
@@ -9,15 +9,11 @@ interface InputProps extends Omit<UIInput.Props, "className" | "children" | "siz
|
|
|
9
9
|
className?: string;
|
|
10
10
|
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
11
11
|
ui?: Input["slots"];
|
|
12
|
-
/** Visible label associated with the input. */
|
|
13
|
-
label?: React.ReactNode;
|
|
14
|
-
/** Optional supporting text under the field. */
|
|
15
|
-
description?: React.ReactNode;
|
|
16
12
|
/** Icon rendered before the input. */
|
|
17
13
|
leadingIcon?: React.ReactNode;
|
|
18
14
|
/** Icon rendered after the input. */
|
|
19
15
|
trailingIcon?: React.ReactNode;
|
|
20
16
|
}
|
|
21
|
-
declare function Input({ className, ui,
|
|
17
|
+
declare function Input({ className, ui, leadingIcon, trailingIcon, size, disabled, ...props }: InputProps): React.JSX.Element;
|
|
22
18
|
export { Input };
|
|
23
19
|
export type { InputProps };
|