@xingxingmofashu/ui 0.1.3 → 0.1.5
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 -69
- package/dist/components/accordion.d.ts +1 -1
- package/dist/components/radio-group.d.ts +35 -0
- package/dist/components/radio-group.mjs +156 -0
- package/dist/components/tabs.d.ts +46 -0
- package/dist/components/tabs.mjs +136 -0
- package/dist/composables/use-toast.d.ts +5 -1
- package/dist/composables/use-toast.mjs +2 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +5 -1
- package/dist/internal/tv.d.ts +0 -4
- package/dist/theme/accordion.d.ts +1 -63
- package/dist/theme/alert-dialog.d.ts +2 -69
- package/dist/theme/button.d.ts +1 -73
- package/dist/theme/card.d.ts +2 -64
- package/dist/theme/checkbox.d.ts +1 -69
- package/dist/theme/dialog.d.ts +2 -69
- package/dist/theme/drawer.d.ts +1 -65
- package/dist/theme/input.d.ts +1 -87
- package/dist/theme/popover.d.ts +2 -69
- package/dist/theme/progress.d.ts +1 -53
- package/dist/theme/radio-group.d.ts +40 -0
- package/dist/theme/radio-group.mjs +106 -0
- package/dist/theme/scroll-area.d.ts +2 -59
- package/dist/theme/slider.d.ts +2 -44
- package/dist/theme/switch.d.ts +1 -63
- package/dist/theme/tabs.d.ts +32 -0
- package/dist/theme/tabs.mjs +80 -0
- package/dist/theme/toast.d.ts +1 -57
- package/dist/theme/toggle-group.d.ts +1 -53
- package/dist/theme/toggle.d.ts +1 -63
- package/package.json +7 -4
- package/dist/composables/create-toast-manager.d.ts +0 -6
- package/dist/composables/create-toast-manager.mjs +0 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<picture>
|
|
2
|
-
<source media="(prefers-color-scheme: dark)" srcset=".github/assets/
|
|
3
|
-
<source media="(prefers-color-scheme: light)" srcset=".github/assets/
|
|
4
|
-
<img alt="
|
|
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">
|
|
5
5
|
</picture>
|
|
6
6
|
|
|
7
7
|
<div align="center">
|
|
@@ -20,27 +20,15 @@ components with a Liquid Glass visual style, built with
|
|
|
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
|
|
24
|
-
Checkbox, Dialog, Drawer, Input, Popover, Progress,
|
|
25
|
-
Toast, Toggle, and Toggle Group.
|
|
23
|
+
The package ships eighteen components: Accordion, Alert Dialog, Button, Card,
|
|
24
|
+
Checkbox, Dialog, Drawer, Input, Popover, Progress, Radio Group, Scroll Area,
|
|
25
|
+
Slider, Switch, Tabs, Toast, Toggle, and Toggle Group.
|
|
26
26
|
|
|
27
27
|
> [!NOTE]
|
|
28
28
|
> Requires React 19, React DOM 19, Tailwind CSS 4, Node.js 22+, and an
|
|
29
29
|
> ESM-capable bundler. `Card` is server-safe; the interactive components are
|
|
30
30
|
> client components.
|
|
31
31
|
|
|
32
|
-
## Preview
|
|
33
|
-
|
|
34
|
-
<picture>
|
|
35
|
-
<source media="(prefers-color-scheme: dark)" srcset=".github/assets/playground-dark.png">
|
|
36
|
-
<source media="(prefers-color-scheme: light)" srcset=".github/assets/playground-light.png">
|
|
37
|
-
<img alt="The Liquid Glass playground showing live component previews in light mode." width="1440" src=".github/assets/playground-light.png">
|
|
38
|
-
</picture>
|
|
39
|
-
|
|
40
|
-
Every component is rendered live in the local playground. Run
|
|
41
|
-
`pnpm playground:dev`, open <http://localhost:3002>, and switch between light and
|
|
42
|
-
dark to compare the same previews in both themes.
|
|
43
|
-
|
|
44
32
|
## Documentation
|
|
45
33
|
|
|
46
34
|
- [English](https://xingxingmofashu.github.io/ui/docs/en/get-started/introduction)
|
|
@@ -106,57 +94,6 @@ import buttonTheme from "@xingxingmofashu/ui/theme/button";
|
|
|
106
94
|
|
|
107
95
|
Toast hooks live under `@xingxingmofashu/ui/composables`.
|
|
108
96
|
|
|
109
|
-
## Components
|
|
110
|
-
|
|
111
|
-
### Element
|
|
112
|
-
|
|
113
|
-
- Accordion
|
|
114
|
-
- Button
|
|
115
|
-
- Card
|
|
116
|
-
- Scroll Area
|
|
117
|
-
- Toggle
|
|
118
|
-
- Toggle Group
|
|
119
|
-
|
|
120
|
-
### Form
|
|
121
|
-
|
|
122
|
-
- Checkbox
|
|
123
|
-
- Input
|
|
124
|
-
- Slider
|
|
125
|
-
- Switch
|
|
126
|
-
|
|
127
|
-
### Overlay
|
|
128
|
-
|
|
129
|
-
- Alert Dialog
|
|
130
|
-
- Dialog
|
|
131
|
-
- Drawer
|
|
132
|
-
- Popover
|
|
133
|
-
- Toast
|
|
134
|
-
|
|
135
|
-
## Theming
|
|
136
|
-
|
|
137
|
-
Light and dark tokens are selected by `.light` / `.dark`, or by
|
|
138
|
-
`data-theme="light"` / `data-theme="dark"`:
|
|
139
|
-
|
|
140
|
-
```html
|
|
141
|
-
<html class="dark">
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
or:
|
|
145
|
-
|
|
146
|
-
```html
|
|
147
|
-
<html data-theme="dark">
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
A nested `.light` / `[data-theme="light"]` subtree can switch back to light
|
|
151
|
-
tokens. Shared colors and glass parameters live in the `--ui-*` tokens; override
|
|
152
|
-
them in your own theme layer. Tailwind aliases use the `ui-` prefix
|
|
153
|
-
(`text-ui-ink`, `outline-ui-glass-focus`, and so on) to avoid colliding with
|
|
154
|
-
host tokens.
|
|
155
|
-
|
|
156
|
-
The components inherit the host font. The visual material relies on modern CSS:
|
|
157
|
-
`backdrop-filter`, `color-mix`, container units, individual `translate` /
|
|
158
|
-
`scale` properties, and `:has`. Use a current evergreen browser.
|
|
159
|
-
|
|
160
97
|
## Development
|
|
161
98
|
|
|
162
99
|
```bash
|
|
@@ -164,6 +101,8 @@ pnpm install
|
|
|
164
101
|
pnpm build # build dist with unbuild
|
|
165
102
|
pnpm lint # lint with oxlint
|
|
166
103
|
pnpm test # run the Vitest suite
|
|
104
|
+
pnpm test:visual # run the Playwright visual regression suite
|
|
105
|
+
pnpm test:visual:update # refresh the Surface Lab screenshots
|
|
167
106
|
pnpm typecheck # typecheck the package
|
|
168
107
|
pnpm docs:dev # docs site on http://localhost:3001
|
|
169
108
|
pnpm playground:dev # component playground on http://localhost:3002
|
|
@@ -5,7 +5,7 @@ import { type ComponentConfig } from "../internal/tv";
|
|
|
5
5
|
import theme from "../theme/accordion";
|
|
6
6
|
type Accordion = ComponentConfig<typeof theme>;
|
|
7
7
|
/** One panel managed by the accordion. */
|
|
8
|
-
type AccordionItemProps<Value extends string = string> = Omit<UIAccordion.Item.Props, "children" | "className" | "style" | "title" | "value"> & {
|
|
8
|
+
type AccordionItemProps<Value extends string = string> = Omit<UIAccordion.Item.Props, "children" | "className" | "content" | "style" | "title" | "value"> & {
|
|
9
9
|
/** Value that identifies the item in the accordion value. */
|
|
10
10
|
value: Value;
|
|
11
11
|
/** Visible heading inside the trigger. */
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Radio as UIRadio } from "@base-ui/react/radio";
|
|
2
|
+
import { RadioGroup as UIRadioGroup } from "@base-ui/react/radio-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/radio-group";
|
|
7
|
+
type RadioGroup = ComponentConfig<typeof theme>;
|
|
8
|
+
/** One option managed by the radio group. */
|
|
9
|
+
type RadioGroupItemProps<Value extends string = string> = Omit<UIRadio.Root.Props<Value>, "className" | "children" | "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 item root. */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Tailwind classes for this item's internal slots, keyed by `data-slot`. */
|
|
19
|
+
ui?: Partial<Pick<RadioGroup["slots"], "item" | "box" | "glass" | "overlay" | "indicator" | "dot" | "wrapper" | "itemLabel" | "itemDescription">>;
|
|
20
|
+
};
|
|
21
|
+
type RadioGroupProps<Value extends string = string> = Omit<UIRadioGroup.Props<Value>, "className" | "style" | "children"> & VariantProps<typeof theme> & {
|
|
22
|
+
/** Options rendered by the radio group. */
|
|
23
|
+
items: readonly RadioGroupItemProps<Value>[];
|
|
24
|
+
/** Visible label for the group. */
|
|
25
|
+
label?: React.ReactNode;
|
|
26
|
+
/** Supporting text rendered under the group label. */
|
|
27
|
+
description?: React.ReactNode;
|
|
28
|
+
/** Tailwind classes merged into the group root. */
|
|
29
|
+
className?: string;
|
|
30
|
+
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
31
|
+
ui?: RadioGroup["slots"];
|
|
32
|
+
};
|
|
33
|
+
declare function RadioGroup<Value extends string = string>({ className, ui, size, items, label, description, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...props }: RadioGroupProps<Value>): React.JSX.Element;
|
|
34
|
+
export { RadioGroup };
|
|
35
|
+
export type { RadioGroupItemProps, RadioGroupProps };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Radio as UIRadio } from "@base-ui/react/radio";
|
|
3
|
+
import { RadioGroup as UIRadioGroup } from "@base-ui/react/radio-group";
|
|
4
|
+
import { cn } from "cn";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { mergeIds } from "../internal/aria.mjs";
|
|
7
|
+
import theme from "../theme/radio-group.mjs";
|
|
8
|
+
function RadioGroup({
|
|
9
|
+
className,
|
|
10
|
+
ui,
|
|
11
|
+
size,
|
|
12
|
+
items,
|
|
13
|
+
label,
|
|
14
|
+
description,
|
|
15
|
+
"aria-label": ariaLabel,
|
|
16
|
+
"aria-labelledby": ariaLabelledBy,
|
|
17
|
+
"aria-describedby": ariaDescribedBy,
|
|
18
|
+
...props
|
|
19
|
+
}) {
|
|
20
|
+
const styles = theme({ size });
|
|
21
|
+
const labelId = React.useId();
|
|
22
|
+
const descriptionId = React.useId();
|
|
23
|
+
const hasName = Boolean(label || ariaLabel || ariaLabelledBy);
|
|
24
|
+
const labelledBy = ariaLabelledBy || (label && !ariaLabel ? labelId : void 0);
|
|
25
|
+
const describedBy = mergeIds(
|
|
26
|
+
ariaDescribedBy,
|
|
27
|
+
description && hasName ? descriptionId : void 0
|
|
28
|
+
);
|
|
29
|
+
return /* @__PURE__ */ React.createElement(
|
|
30
|
+
UIRadioGroup,
|
|
31
|
+
{
|
|
32
|
+
...props,
|
|
33
|
+
"aria-describedby": describedBy,
|
|
34
|
+
"aria-label": ariaLabel,
|
|
35
|
+
"aria-labelledby": labelledBy,
|
|
36
|
+
"data-slot": "root",
|
|
37
|
+
className: cn(styles.root(), ui?.root, className)
|
|
38
|
+
},
|
|
39
|
+
label || description ? /* @__PURE__ */ React.createElement("div", { "data-slot": "header", className: cn(styles.header(), ui?.header) }, label ? /* @__PURE__ */ React.createElement(
|
|
40
|
+
"span",
|
|
41
|
+
{
|
|
42
|
+
id: labelId,
|
|
43
|
+
"data-slot": "label",
|
|
44
|
+
className: cn(styles.label(), ui?.label)
|
|
45
|
+
},
|
|
46
|
+
label
|
|
47
|
+
) : null, description ? /* @__PURE__ */ React.createElement(
|
|
48
|
+
"span",
|
|
49
|
+
{
|
|
50
|
+
id: descriptionId,
|
|
51
|
+
"data-slot": "description",
|
|
52
|
+
className: cn(styles.description(), ui?.description)
|
|
53
|
+
},
|
|
54
|
+
description
|
|
55
|
+
) : null) : null,
|
|
56
|
+
/* @__PURE__ */ React.createElement("div", { "data-slot": "items", className: cn(styles.items(), ui?.items) }, items.map((item) => /* @__PURE__ */ React.createElement(
|
|
57
|
+
RadioGroupItem,
|
|
58
|
+
{
|
|
59
|
+
key: item.value,
|
|
60
|
+
...item,
|
|
61
|
+
ui: {
|
|
62
|
+
item: cn(ui?.item, item.ui?.item),
|
|
63
|
+
box: cn(ui?.box, item.ui?.box),
|
|
64
|
+
glass: cn(ui?.glass, item.ui?.glass),
|
|
65
|
+
overlay: cn(ui?.overlay, item.ui?.overlay),
|
|
66
|
+
indicator: cn(ui?.indicator, item.ui?.indicator),
|
|
67
|
+
dot: cn(ui?.dot, item.ui?.dot),
|
|
68
|
+
wrapper: cn(
|
|
69
|
+
styles.wrapper(),
|
|
70
|
+
ui?.wrapper,
|
|
71
|
+
item.ui?.wrapper
|
|
72
|
+
),
|
|
73
|
+
itemLabel: cn(ui?.itemLabel, item.ui?.itemLabel),
|
|
74
|
+
itemDescription: cn(
|
|
75
|
+
ui?.itemDescription,
|
|
76
|
+
item.ui?.itemDescription
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
)))
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function RadioGroupItem({
|
|
84
|
+
className,
|
|
85
|
+
ui,
|
|
86
|
+
label,
|
|
87
|
+
description,
|
|
88
|
+
"aria-label": ariaLabel,
|
|
89
|
+
"aria-labelledby": ariaLabelledBy,
|
|
90
|
+
"aria-describedby": ariaDescribedBy,
|
|
91
|
+
...props
|
|
92
|
+
}) {
|
|
93
|
+
const styles = theme();
|
|
94
|
+
const labelId = React.useId();
|
|
95
|
+
const descriptionId = React.useId();
|
|
96
|
+
const hasName = Boolean(label || ariaLabel || ariaLabelledBy);
|
|
97
|
+
const labelledBy = ariaLabelledBy || (label && !ariaLabel ? labelId : void 0);
|
|
98
|
+
const describedBy = mergeIds(
|
|
99
|
+
ariaDescribedBy,
|
|
100
|
+
description && hasName ? descriptionId : void 0
|
|
101
|
+
);
|
|
102
|
+
return /* @__PURE__ */ React.createElement(
|
|
103
|
+
UIRadio.Root,
|
|
104
|
+
{
|
|
105
|
+
...props,
|
|
106
|
+
"aria-describedby": describedBy,
|
|
107
|
+
"aria-label": ariaLabel,
|
|
108
|
+
"aria-labelledby": labelledBy,
|
|
109
|
+
"data-slot": "item",
|
|
110
|
+
className: cn(styles.item(), ui?.item, className)
|
|
111
|
+
},
|
|
112
|
+
/* @__PURE__ */ React.createElement("span", { "data-slot": "box", className: cn(styles.box(), ui?.box) }, /* @__PURE__ */ React.createElement(
|
|
113
|
+
"span",
|
|
114
|
+
{
|
|
115
|
+
"aria-hidden": "true",
|
|
116
|
+
"data-slot": "glass",
|
|
117
|
+
className: cn(styles.glass(), ui?.glass)
|
|
118
|
+
},
|
|
119
|
+
/* @__PURE__ */ React.createElement(
|
|
120
|
+
"span",
|
|
121
|
+
{
|
|
122
|
+
"aria-hidden": "true",
|
|
123
|
+
"data-slot": "overlay",
|
|
124
|
+
className: cn(styles.overlay(), ui?.overlay)
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
), /* @__PURE__ */ React.createElement(
|
|
128
|
+
UIRadio.Indicator,
|
|
129
|
+
{
|
|
130
|
+
keepMounted: true,
|
|
131
|
+
"aria-hidden": "true",
|
|
132
|
+
"data-slot": "indicator",
|
|
133
|
+
className: cn(styles.indicator(), ui?.indicator)
|
|
134
|
+
},
|
|
135
|
+
/* @__PURE__ */ React.createElement("span", { "data-slot": "dot", className: cn(styles.dot(), ui?.dot) })
|
|
136
|
+
)),
|
|
137
|
+
label || description ? /* @__PURE__ */ React.createElement("span", { "data-slot": "wrapper", className: cn(styles.wrapper(), ui?.wrapper) }, label ? /* @__PURE__ */ React.createElement(
|
|
138
|
+
"span",
|
|
139
|
+
{
|
|
140
|
+
id: labelId,
|
|
141
|
+
"data-slot": "item-label",
|
|
142
|
+
className: cn(styles.itemLabel(), ui?.itemLabel)
|
|
143
|
+
},
|
|
144
|
+
label
|
|
145
|
+
) : null, description ? /* @__PURE__ */ React.createElement(
|
|
146
|
+
"span",
|
|
147
|
+
{
|
|
148
|
+
id: descriptionId,
|
|
149
|
+
"data-slot": "item-description",
|
|
150
|
+
className: cn(styles.itemDescription(), ui?.itemDescription)
|
|
151
|
+
},
|
|
152
|
+
description
|
|
153
|
+
) : null) : null
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
export { RadioGroup };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Tabs as UITabs } from "@base-ui/react/tabs";
|
|
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/tabs";
|
|
6
|
+
type Tabs = ComponentConfig<typeof theme>;
|
|
7
|
+
/** One tab and its related panel. */
|
|
8
|
+
type TabsItemProps<Value extends string = string> = Omit<UITabs.Tab.Props, "children" | "className" | "content" | "style" | "value"> & {
|
|
9
|
+
/** Value that identifies the tab and its panel. */
|
|
10
|
+
value: Value;
|
|
11
|
+
/** Visible label inside the tab. */
|
|
12
|
+
label?: React.ReactNode;
|
|
13
|
+
/** Decorative icon rendered before the label. */
|
|
14
|
+
icon?: React.ReactNode;
|
|
15
|
+
/** Panel content shown while the tab is active. */
|
|
16
|
+
content?: React.ReactNode;
|
|
17
|
+
/** Whether to keep the panel mounted while another tab is active. */
|
|
18
|
+
keepMounted?: boolean;
|
|
19
|
+
/** Tailwind classes merged into the tab button. */
|
|
20
|
+
className?: string;
|
|
21
|
+
/** Tailwind classes for this item's internal slots, keyed by `data-slot`. */
|
|
22
|
+
ui?: Partial<Pick<Tabs["slots"], "tab" | "icon" | "label" | "panel" | "panelContent">>;
|
|
23
|
+
};
|
|
24
|
+
type TabsProps<Value extends string = string> = Omit<UITabs.Root.Props, "children" | "className" | "style" | "value" | "defaultValue" | "onValueChange"> & VariantProps<typeof theme> & {
|
|
25
|
+
/** Tabs and panels rendered by the component. */
|
|
26
|
+
items: readonly TabsItemProps<Value>[];
|
|
27
|
+
/** Controlled active value. Use `null` to render no active tab. */
|
|
28
|
+
value?: Value | null;
|
|
29
|
+
/** Initial active value when uncontrolled. */
|
|
30
|
+
defaultValue?: Value | null;
|
|
31
|
+
/** Called when the active value changes. */
|
|
32
|
+
onValueChange?: (value: Value, details: UITabs.Root.ChangeEventDetails) => void;
|
|
33
|
+
/** Whether arrow keys activate a tab as focus moves. */
|
|
34
|
+
activateOnFocus?: boolean;
|
|
35
|
+
/** Whether keyboard focus loops back to the first tab. */
|
|
36
|
+
loopFocus?: boolean;
|
|
37
|
+
/** Disables every tab. */
|
|
38
|
+
disabled?: boolean;
|
|
39
|
+
/** Tailwind classes merged into the root. */
|
|
40
|
+
className?: string;
|
|
41
|
+
/** Tailwind classes for internal slots, keyed by `data-slot`. */
|
|
42
|
+
ui?: Tabs["slots"];
|
|
43
|
+
};
|
|
44
|
+
declare function Tabs<Value extends string = string>({ className, ui, size, items, value, defaultValue, onValueChange, activateOnFocus, loopFocus, disabled, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...props }: TabsProps<Value>): React.JSX.Element;
|
|
45
|
+
export { Tabs };
|
|
46
|
+
export type { TabsItemProps, TabsProps };
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Tabs as UITabs } from "@base-ui/react/tabs";
|
|
3
|
+
import { cn } from "cn";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import theme from "../theme/tabs.mjs";
|
|
6
|
+
function Tabs({
|
|
7
|
+
className,
|
|
8
|
+
ui,
|
|
9
|
+
size,
|
|
10
|
+
items,
|
|
11
|
+
value,
|
|
12
|
+
defaultValue,
|
|
13
|
+
onValueChange,
|
|
14
|
+
activateOnFocus,
|
|
15
|
+
loopFocus,
|
|
16
|
+
disabled,
|
|
17
|
+
"aria-label": ariaLabel,
|
|
18
|
+
"aria-labelledby": ariaLabelledBy,
|
|
19
|
+
"aria-describedby": ariaDescribedBy,
|
|
20
|
+
...props
|
|
21
|
+
}) {
|
|
22
|
+
const styles = theme({ size });
|
|
23
|
+
const initialValue = defaultValue !== void 0 ? defaultValue : items.find((item) => !item.disabled)?.value;
|
|
24
|
+
return /* @__PURE__ */ React.createElement(
|
|
25
|
+
UITabs.Root,
|
|
26
|
+
{
|
|
27
|
+
...props,
|
|
28
|
+
value,
|
|
29
|
+
defaultValue: initialValue,
|
|
30
|
+
onValueChange,
|
|
31
|
+
"data-slot": "root",
|
|
32
|
+
"data-disabled": disabled || void 0,
|
|
33
|
+
className: cn(styles.root(), ui?.root, className)
|
|
34
|
+
},
|
|
35
|
+
/* @__PURE__ */ React.createElement(
|
|
36
|
+
UITabs.List,
|
|
37
|
+
{
|
|
38
|
+
activateOnFocus,
|
|
39
|
+
loopFocus,
|
|
40
|
+
"aria-label": ariaLabel,
|
|
41
|
+
"aria-labelledby": ariaLabelledBy,
|
|
42
|
+
"aria-describedby": ariaDescribedBy,
|
|
43
|
+
"data-slot": "list",
|
|
44
|
+
className: cn(styles.list(), ui?.list)
|
|
45
|
+
},
|
|
46
|
+
/* @__PURE__ */ React.createElement(
|
|
47
|
+
"span",
|
|
48
|
+
{
|
|
49
|
+
"aria-hidden": "true",
|
|
50
|
+
"data-slot": "glass",
|
|
51
|
+
className: cn(styles.glass(), ui?.glass)
|
|
52
|
+
},
|
|
53
|
+
/* @__PURE__ */ React.createElement(
|
|
54
|
+
"span",
|
|
55
|
+
{
|
|
56
|
+
"aria-hidden": "true",
|
|
57
|
+
"data-slot": "overlay",
|
|
58
|
+
className: cn(styles.overlay(), ui?.overlay)
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
),
|
|
62
|
+
/* @__PURE__ */ React.createElement(
|
|
63
|
+
UITabs.Indicator,
|
|
64
|
+
{
|
|
65
|
+
"data-slot": "indicator",
|
|
66
|
+
className: cn(styles.indicator(), ui?.indicator)
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
items.map(
|
|
70
|
+
({ content: _content, keepMounted: _keepMounted, ui: itemUi, ...item }) => /* @__PURE__ */ React.createElement(
|
|
71
|
+
TabsItem,
|
|
72
|
+
{
|
|
73
|
+
key: item.value,
|
|
74
|
+
...item,
|
|
75
|
+
disabled: disabled || item.disabled,
|
|
76
|
+
ui: {
|
|
77
|
+
tab: cn(ui?.tab, itemUi?.tab),
|
|
78
|
+
icon: cn(ui?.icon, itemUi?.icon),
|
|
79
|
+
label: cn(ui?.label, itemUi?.label)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ React.createElement("div", { "data-slot": "panels", className: cn(styles.panels(), ui?.panels) }, items.map((item) => /* @__PURE__ */ React.createElement(
|
|
86
|
+
UITabs.Panel,
|
|
87
|
+
{
|
|
88
|
+
key: item.value,
|
|
89
|
+
value: item.value,
|
|
90
|
+
keepMounted: item.keepMounted,
|
|
91
|
+
"data-slot": "panel",
|
|
92
|
+
className: cn(styles.panel(), ui?.panel, item.ui?.panel)
|
|
93
|
+
},
|
|
94
|
+
/* @__PURE__ */ React.createElement(
|
|
95
|
+
"div",
|
|
96
|
+
{
|
|
97
|
+
"data-slot": "panel-content",
|
|
98
|
+
className: cn(
|
|
99
|
+
styles.panelContent(),
|
|
100
|
+
ui?.panelContent,
|
|
101
|
+
item.ui?.panelContent
|
|
102
|
+
)
|
|
103
|
+
},
|
|
104
|
+
item.content
|
|
105
|
+
)
|
|
106
|
+
)))
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
function TabsItem({
|
|
110
|
+
className,
|
|
111
|
+
ui,
|
|
112
|
+
label,
|
|
113
|
+
icon,
|
|
114
|
+
...props
|
|
115
|
+
}) {
|
|
116
|
+
const styles = theme();
|
|
117
|
+
return /* @__PURE__ */ React.createElement(
|
|
118
|
+
UITabs.Tab,
|
|
119
|
+
{
|
|
120
|
+
...props,
|
|
121
|
+
"data-slot": "tab",
|
|
122
|
+
className: cn(styles.tab(), ui?.tab, className)
|
|
123
|
+
},
|
|
124
|
+
icon ? /* @__PURE__ */ React.createElement(
|
|
125
|
+
"span",
|
|
126
|
+
{
|
|
127
|
+
"aria-hidden": "true",
|
|
128
|
+
"data-slot": "icon",
|
|
129
|
+
className: cn(styles.icon(), ui?.icon)
|
|
130
|
+
},
|
|
131
|
+
icon
|
|
132
|
+
) : null,
|
|
133
|
+
label !== void 0 && label !== null ? /* @__PURE__ */ React.createElement("span", { "data-slot": "label", className: cn(styles.label(), ui?.label) }, label) : null
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
export { Tabs };
|
|
@@ -3,5 +3,9 @@ import { Toast as UIToast } from "@base-ui/react/toast";
|
|
|
3
3
|
* Returns the toast manager connected to the nearest `ToastProvider`.
|
|
4
4
|
*/
|
|
5
5
|
declare const useToast: typeof UIToast.useToastManager;
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Creates a toast manager for adding notifications outside the React tree.
|
|
8
|
+
*/
|
|
9
|
+
declare const createToastManager: typeof UIToast.createToastManager;
|
|
10
|
+
export { createToastManager, useToast };
|
|
7
11
|
export type { ToastManager, ToastManagerAddOptions, ToastManagerPromiseOptions, ToastManagerUpdateOptions, ToastObject, } from "@base-ui/react/toast";
|
package/dist/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import "./keyframes.css";@source "./**/*.mjs";@source "./**/*.{ts,tsx}";@custom-variant ui-light (&:where(.light, .light *, [data-theme="light"], [data-theme="light"] *));@custom-variant ui-dark (&:where(.dark, .dark *, [data-theme="dark"], [data-theme="dark"] *));@layer theme{:host,:root{--ui-ink:#1f1f1f;--ui-ink-active:#000;--ui-surface:#fff;--ui-glass-surface:
|
|
1
|
+
@import "./keyframes.css";@source "./**/*.mjs";@source "./**/*.{ts,tsx}";@custom-variant ui-light (&:where(.light, .light *, [data-theme="light"], [data-theme="light"] *));@custom-variant ui-dark (&:where(.dark, .dark *, [data-theme="dark"], [data-theme="dark"] *));@layer theme{:host,:root{--ui-ink:#1f1f1f;--ui-ink-active:#000;--ui-surface:#fff;--ui-glass-surface:hsla(0,0%,100%,.2);--ui-glass-border:rgba(31,31,31,.16);--ui-glass-focus:rgba(0,0,0,.6);--ui-glass-inner-border:rgba(0,0,0,.9);--ui-glass-rim:hsla(0,0%,100%,.2);--ui-glass-highlight:hsla(0,0%,100%,.8);--ui-glass-glare-stop:15%;--ui-glass-tone:brightness(0.98);--ui-glass-contrast:1.05;--ui-drop-shadow-label:drop-shadow(0 25px 3px hsla(0,0%,40%,.15));--ui-shadow-glass:inset 2px -2px 1px -1px hsla(0,0%,100%,.9),inset -2px 2px 1px -1px hsla(0,0%,100%,.9),inset 6px -6px 1px -6px hsla(0,0%,100%,.55),inset -6px 6px 1px -6px hsla(0,0%,100%,.55),inset 0 0 2px rgba(0,0,0,.8),0 4px 8px rgba(0,0,0,.2)}.dark,[data-theme=dark]{--ui-ink:#f5f5f5;--ui-ink-active:#fff;--ui-surface:#141414;--ui-glass-surface:hsla(0,0%,8%,.62);--ui-glass-border:hsla(0,0%,100%,.2);--ui-glass-focus:hsla(0,0%,100%,.7);--ui-glass-inner-border:hsla(0,0%,100%,.4);--ui-glass-rim:hsla(0,0%,100%,.25);--ui-glass-highlight:hsla(0,0%,100%,.45);--ui-glass-tone:brightness(0.95);--ui-glass-contrast:1;--ui-drop-shadow-label:drop-shadow(0 25px 3px rgba(0,0,0,.45));--ui-shadow-glass:inset 2px -2px 1px -1px hsla(0,0%,100%,.35),inset -2px 2px 1px -1px hsla(0,0%,100%,.35),inset 6px -6px 1px -6px hsla(0,0%,100%,.2),inset -6px 6px 1px -6px hsla(0,0%,100%,.2),inset 0 0 2px rgba(0,0,0,.9),0 4px 8px rgba(0,0,0,.35)}.light,[data-theme=light]{--ui-ink:#1f1f1f;--ui-ink-active:#000;--ui-surface:#fff;--ui-glass-surface:hsla(0,0%,100%,.2);--ui-glass-border:rgba(31,31,31,.16);--ui-glass-focus:rgba(0,0,0,.6);--ui-glass-inner-border:rgba(0,0,0,.9);--ui-glass-rim:hsla(0,0%,100%,.2);--ui-glass-highlight:hsla(0,0%,100%,.8);--ui-glass-glare-stop:15%;--ui-glass-tone:brightness(0.98);--ui-glass-contrast:1.05;--ui-drop-shadow-label:drop-shadow(0 25px 3px hsla(0,0%,40%,.15));--ui-shadow-glass:inset 2px -2px 1px -1px hsla(0,0%,100%,.9),inset -2px 2px 1px -1px hsla(0,0%,100%,.9),inset 6px -6px 1px -6px hsla(0,0%,100%,.55),inset -6px 6px 1px -6px hsla(0,0%,100%,.55),inset 0 0 2px rgba(0,0,0,.8),0 4px 8px rgba(0,0,0,.2)}:host,:root{--ui-glass-blur:4px;--ui-glass-saturate:150%;--ui-glass-chip-blur:8px;--ui-glass-inner-inset:8px;--ui-glass-inner-offset:1px;--ui-glass-inner-blur:8px;--ui-glass-highlight-blur:7px;--ui-glass-rim-inset:9px;--ui-glass-rim-blur:1px}}@theme inline{--color-ui-ink:var(--ui-ink);--color-ui-ink-active:var(--ui-ink-active);--color-ui-surface:var(--ui-surface);--color-ui-glass-surface:var(--ui-glass-surface);--color-ui-glass-border:var(--ui-glass-border);--color-ui-glass-focus:var(--ui-glass-focus);--color-ui-glass-inner-border:var(--ui-glass-inner-border);--color-ui-glass-rim:var(--ui-glass-rim);--color-ui-glass-highlight:var(--ui-glass-highlight)}@layer components{.ui-glass{backdrop-filter:blur(var(--ui-glass-blur,4px)) saturate(var(--ui-glass-saturate,150%));background-color:var(--ui-glass-surface);border:1px double var(--ui-glass-border);box-shadow:var(--ui-shadow-glass);filter:var(--ui-glass-tone,brightness(.98)) contrast(var(--ui-glass-contrast,1.05));position:relative}.ui-glass-inner:before{border:1px solid var(--ui-glass-inner-border);bottom:calc(var(--ui-glass-inner-inset, 8px) - var(--ui-glass-inner-offset, 1px));filter:blur(var(--ui-glass-inner-blur,8px));left:var(--ui-glass-inner-inset,8px);right:var(--ui-glass-inner-inset,8px);top:calc(var(--ui-glass-inner-inset, 8px) + var(--ui-glass-inner-offset, 1px));z-index:1}.ui-glass-highlight:after,.ui-glass-inner:before{border-radius:inherit;content:"";pointer-events:none;position:absolute}.ui-glass-highlight:after{background:linear-gradient(45deg,var(--ui-glass-highlight) 0,transparent var(--ui-glass-glare-stop),transparent calc(100% - var(--ui-glass-glare-stop)),var(--ui-glass-highlight) 100%);filter:blur(var(--ui-glass-highlight-blur,7px));inset:0;z-index:3}.ui-glass-rim{border:1px solid var(--ui-glass-rim);border-radius:inherit;filter:blur(var(--ui-glass-rim-blur,1px));height:calc(100% - var(--ui-glass-rim-inset, 9px));left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:calc(100% - var(--ui-glass-rim-inset, 9px));z-index:2}.ui-glass-chip{backdrop-filter:blur(var(--ui-glass-chip-blur,8px)) saturate(var(--ui-glass-saturate,150%));background-color:var(--ui-glass-surface);border:1px solid var(--ui-glass-border);box-shadow:inset 0 1px 0 var(--ui-glass-highlight)}}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,11 +8,12 @@ export { Drawer, type DrawerProps } from "./components/drawer";
|
|
|
8
8
|
export { Input, type InputProps } from "./components/input";
|
|
9
9
|
export { Popover, type PopoverProps } from "./components/popover";
|
|
10
10
|
export { Progress, type ProgressProps } from "./components/progress";
|
|
11
|
+
export { RadioGroup, type RadioGroupItemProps, type RadioGroupProps, } from "./components/radio-group";
|
|
11
12
|
export { ScrollArea, type ScrollAreaOrientation, type ScrollAreaProps, } from "./components/scroll-area";
|
|
12
13
|
export { Slider, type SliderProps } from "./components/slider";
|
|
13
14
|
export { Switch, type SwitchProps } from "./components/switch";
|
|
15
|
+
export { Tabs, type TabsItemProps, type TabsProps } from "./components/tabs";
|
|
14
16
|
export { Toast, ToastProvider, type ToastPosition, type ToastProps, type ToastProviderProps, } from "./components/toast";
|
|
15
|
-
export { createToastManager } from "./composables/
|
|
16
|
-
export { useToast, type ToastManager, type ToastManagerAddOptions, type ToastManagerPromiseOptions, type ToastManagerUpdateOptions, type ToastObject, } from "./composables/use-toast";
|
|
17
|
+
export { createToastManager, useToast, type ToastManager, type ToastManagerAddOptions, type ToastManagerPromiseOptions, type ToastManagerUpdateOptions, type ToastObject, } from "./composables/use-toast";
|
|
17
18
|
export { Toggle, type ToggleProps } from "./components/toggle";
|
|
18
19
|
export { ToggleGroup, type ToggleGroupItemProps, type ToggleGroupProps, } from "./components/toggle-group";
|
package/dist/index.mjs
CHANGED
|
@@ -10,17 +10,21 @@ export { Drawer } from "./components/drawer.mjs";
|
|
|
10
10
|
export { Input } from "./components/input.mjs";
|
|
11
11
|
export { Popover } from "./components/popover.mjs";
|
|
12
12
|
export { Progress } from "./components/progress.mjs";
|
|
13
|
+
export {
|
|
14
|
+
RadioGroup
|
|
15
|
+
} from "./components/radio-group.mjs";
|
|
13
16
|
export {
|
|
14
17
|
ScrollArea
|
|
15
18
|
} from "./components/scroll-area.mjs";
|
|
16
19
|
export { Slider } from "./components/slider.mjs";
|
|
17
20
|
export { Switch } from "./components/switch.mjs";
|
|
21
|
+
export { Tabs } from "./components/tabs.mjs";
|
|
18
22
|
export {
|
|
19
23
|
Toast,
|
|
20
24
|
ToastProvider
|
|
21
25
|
} from "./components/toast.mjs";
|
|
22
|
-
export { createToastManager } from "./composables/create-toast-manager.mjs";
|
|
23
26
|
export {
|
|
27
|
+
createToastManager,
|
|
24
28
|
useToast
|
|
25
29
|
} from "./composables/use-toast.mjs";
|
|
26
30
|
export { Toggle } from "./components/toggle.mjs";
|
package/dist/internal/tv.d.ts
CHANGED
|
@@ -7,10 +7,6 @@ type ComponentSlots<T extends {
|
|
|
7
7
|
}> = Id<{
|
|
8
8
|
[K in keyof T["slots"]]?: ClassValue;
|
|
9
9
|
}>;
|
|
10
|
-
/**
|
|
11
|
-
* Minimal tailwind-variants component config used to derive prop types from a
|
|
12
|
-
* theme recipe. Mirrors Nuxt UI's `ComponentConfig` slot mapping.
|
|
13
|
-
*/
|
|
14
10
|
export type ComponentConfig<T extends Record<string, any>> = {
|
|
15
11
|
slots: ComponentSlots<T>;
|
|
16
12
|
};
|
|
@@ -29,67 +29,5 @@ declare const _default: import("tailwind-variants").TVReturnType<{
|
|
|
29
29
|
indicatorIcon: string;
|
|
30
30
|
panel: string[];
|
|
31
31
|
panelContent: string[];
|
|
32
|
-
}, undefined,
|
|
33
|
-
size: {
|
|
34
|
-
xs: {
|
|
35
|
-
root: string;
|
|
36
|
-
};
|
|
37
|
-
sm: {
|
|
38
|
-
root: string;
|
|
39
|
-
};
|
|
40
|
-
md: {
|
|
41
|
-
root: string;
|
|
42
|
-
};
|
|
43
|
-
lg: {
|
|
44
|
-
root: string;
|
|
45
|
-
};
|
|
46
|
-
xl: {
|
|
47
|
-
root: string;
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
}, {
|
|
51
|
-
root: string[];
|
|
52
|
-
glass: string[];
|
|
53
|
-
overlay: string;
|
|
54
|
-
content: string;
|
|
55
|
-
item: string[];
|
|
56
|
-
header: string;
|
|
57
|
-
trigger: string[];
|
|
58
|
-
title: string[];
|
|
59
|
-
indicator: string[];
|
|
60
|
-
indicatorIcon: string;
|
|
61
|
-
panel: string[];
|
|
62
|
-
panelContent: string[];
|
|
63
|
-
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
64
|
-
size: {
|
|
65
|
-
xs: {
|
|
66
|
-
root: string;
|
|
67
|
-
};
|
|
68
|
-
sm: {
|
|
69
|
-
root: string;
|
|
70
|
-
};
|
|
71
|
-
md: {
|
|
72
|
-
root: string;
|
|
73
|
-
};
|
|
74
|
-
lg: {
|
|
75
|
-
root: string;
|
|
76
|
-
};
|
|
77
|
-
xl: {
|
|
78
|
-
root: string;
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
}, {
|
|
82
|
-
root: string[];
|
|
83
|
-
glass: string[];
|
|
84
|
-
overlay: string;
|
|
85
|
-
content: string;
|
|
86
|
-
item: string[];
|
|
87
|
-
header: string;
|
|
88
|
-
trigger: string[];
|
|
89
|
-
title: string[];
|
|
90
|
-
indicator: string[];
|
|
91
|
-
indicatorIcon: string;
|
|
92
|
-
panel: string[];
|
|
93
|
-
panelContent: string[];
|
|
94
|
-
}>>;
|
|
32
|
+
}, undefined, undefined, undefined, undefined>;
|
|
95
33
|
export default _default;
|