@api7/ui-components 0.1.0 → 0.1.1
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 +137 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,48 +1,157 @@
|
|
|
1
1
|
# @api7/ui-components
|
|
2
2
|
|
|
3
|
-
API7 component library built on Base UI and Tailwind CSS v4.
|
|
3
|
+
API7 React component library built on [Base UI](https://base-ui.com) and Tailwind CSS v4. It ships a precompiled stylesheet, so an application does not need Tailwind CSS to use it.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```sh
|
|
8
|
+
npm install @api7/ui-components react-day-picker lucide-react
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @api7/ui-components react-day-picker lucide-react
|
|
11
|
+
# or
|
|
12
|
+
yarn add @api7/ui-components react-day-picker lucide-react
|
|
13
|
+
```
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
The package expects these peer dependencies in the application:
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
| Package | Version | Needed for |
|
|
18
|
+
| ----------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
19
|
+
| `react`, `react-dom` | `^19` | Everything |
|
|
20
|
+
| `lucide-react` | `^1` | Icons used inside components |
|
|
21
|
+
| `react-day-picker` | `^10.0.1` | Required. `Calendar`, `DatePicker` and `DateRangePicker` import it, and the package declares it as a required peer, so install it even if you do not use them |
|
|
22
|
+
| `@tanstack/react-form` | `^1.33.0` | `@api7/ui-components/form` (optional) |
|
|
23
|
+
| `@tanstack/react-table` | `^9.0.0` | `@api7/ui-components/data-table` (optional) |
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
Add the optional ones only if you import those entry points.
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
## Quick start
|
|
16
28
|
|
|
17
|
-
|
|
29
|
+
1. Import the stylesheet once, in the entry file of the application, before your own styles:
|
|
18
30
|
|
|
19
|
-
|
|
31
|
+
```ts
|
|
32
|
+
import '@api7/ui-components/styles.css';
|
|
33
|
+
```
|
|
20
34
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- `@api7/ui-components`: components, hooks and `ConfigProvider`.
|
|
24
|
-
- `@api7/ui-components/form`: form components built on TanStack Form. Needs the optional peer dependency `@tanstack/react-form`.
|
|
25
|
-
- `@api7/ui-components/data-table`: the data table built on TanStack Table. Needs the optional peer dependency `@tanstack/react-table`.
|
|
26
|
-
- `@api7/ui-components/tokens`: the design token data (`palette`, `themes`, `FAMILIES`, `STEPS` and the contrast helpers `AA`, `semanticPairs`, `badgePairs`) for documentation pages. The CSS generators stay internal.
|
|
27
|
-
- `@api7/ui-components/styles.css`: the precompiled stylesheet.
|
|
35
|
+
2. Load a font for `--asu-font-sans`. It is Inter by default. For example, install `@fontsource-variable/inter` (`npm install @fontsource-variable/inter`) and import it in the same entry file:
|
|
28
36
|
|
|
29
|
-
|
|
37
|
+
```ts
|
|
38
|
+
import '@fontsource-variable/inter';
|
|
39
|
+
```
|
|
30
40
|
|
|
31
|
-
|
|
41
|
+
To use another font, override the variable:
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
```css
|
|
44
|
+
:root {
|
|
45
|
+
--asu-font-sans: 'Your Font', sans-serif;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
3. Use the components. Render `Toaster` once if you use `toast`, and wrap the application in `ConfigProvider` if you need a locale other than `en-US`:
|
|
36
50
|
|
|
37
|
-
|
|
51
|
+
```tsx
|
|
52
|
+
import { Button, ConfigProvider, Toaster, toast } from '@api7/ui-components';
|
|
38
53
|
|
|
39
|
-
|
|
54
|
+
export function App() {
|
|
55
|
+
return (
|
|
56
|
+
<ConfigProvider locale="zh-CN">
|
|
57
|
+
<Button onClick={() => toast.success('Saved', { description: 'Your changes were stored.' })}>Save</Button>
|
|
58
|
+
<Toaster />
|
|
59
|
+
</ConfigProvider>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
40
63
|
|
|
41
|
-
|
|
64
|
+
`ConfigProvider` accepts `locale` (`en-US` or `zh-CN`) and `messages`, an object that overrides the built-in texts, such as the loading label of a button, the close buttons, the empty state of the data table and the pagination labels. Define `messages` at module scope or memoize it.
|
|
42
65
|
|
|
43
|
-
|
|
44
|
-
- A test that takes seconds on a workstation can fail on a slower runner. Check the slowest tests with `--reporter=verbose` after adding one, a good browser test finishes in well under a second, and only fuzz style tests run for a few seconds.
|
|
45
|
-
|
|
46
|
-
## Releasing
|
|
66
|
+
## Entry points
|
|
47
67
|
|
|
48
|
-
|
|
68
|
+
| Import | Contents |
|
|
69
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| `@api7/ui-components` | Components, `toast` and `Toaster`, `ConfigProvider`, `useLocale` and `useMessages` |
|
|
71
|
+
| `@api7/ui-components/form` | Form components built on TanStack Form |
|
|
72
|
+
| `@api7/ui-components/data-table` | The data table built on TanStack Table |
|
|
73
|
+
| `@api7/ui-components/tokens` | Design token data (`palette`, `themes`, `FAMILIES`, `STEPS` and the contrast helpers) for documentation pages |
|
|
74
|
+
| `@api7/ui-components/styles.css` | The precompiled stylesheet |
|
|
75
|
+
|
|
76
|
+
The package is ESM only. Component modules keep their `"use client"` directive, so the components work in a React Server Components setup such as the Next.js app router.
|
|
77
|
+
|
|
78
|
+
## Buttons
|
|
79
|
+
|
|
80
|
+
`Button` takes a `variant`: `primary` (the default), `secondary`, `outline`, `ghost`, `destructive` or `link`. It takes a `size`: `sm`, `md` (the default), `lg` or `icon`. `loading` disables the button and shows a spinner, and `loadingLabel` sets the text that screen readers announce.
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
import { Button } from '@api7/ui-components';
|
|
84
|
+
|
|
85
|
+
export function Actions() {
|
|
86
|
+
return (
|
|
87
|
+
<>
|
|
88
|
+
<Button>Save</Button>
|
|
89
|
+
<Button variant="outline" size="sm">
|
|
90
|
+
Cancel
|
|
91
|
+
</Button>
|
|
92
|
+
<Button variant="destructive" loading loadingLabel="Deleting">
|
|
93
|
+
Delete
|
|
94
|
+
</Button>
|
|
95
|
+
</>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
A link that looks like a button is an ordinary anchor or router link styled with `buttonVariants`. Give it `data-slot="button"` so the library's CSS reset applies to it:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { buttonVariants } from '@api7/ui-components';
|
|
104
|
+
|
|
105
|
+
export function DocsLink() {
|
|
106
|
+
return (
|
|
107
|
+
<a href="/docs" data-slot="button" className={buttonVariants({ variant: 'outline' })}>
|
|
108
|
+
Docs
|
|
109
|
+
</a>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Forms
|
|
115
|
+
|
|
116
|
+
`@api7/ui-components/form` wraps TanStack Form. `useAppForm` returns a form whose `AppField` hands you ready made fields: `TextField`, `TextareaField`, `NumberField`, `SelectField`, `ComboboxField`, `DatePickerField`, `DateRangePickerField`, `CheckboxField`, `SwitchField` and `RadioGroupField`:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
import { Button } from '@api7/ui-components';
|
|
120
|
+
import { useAppForm } from '@api7/ui-components/form';
|
|
121
|
+
|
|
122
|
+
export function NameForm({ onSave }: { onSave: (name: string) => void }) {
|
|
123
|
+
const form = useAppForm({
|
|
124
|
+
defaultValues: { name: '' },
|
|
125
|
+
onSubmit: ({ value }) => onSave(value.name),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<form
|
|
130
|
+
noValidate
|
|
131
|
+
onSubmit={(event) => {
|
|
132
|
+
event.preventDefault();
|
|
133
|
+
void form.handleSubmit();
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
<form.AppField name="name" validators={{ onChange: ({ value }) => (value ? undefined : 'Name is required') }}>
|
|
137
|
+
{(field) => <field.TextField label="Name" />}
|
|
138
|
+
</form.AppField>
|
|
139
|
+
<Button type="submit">Save</Button>
|
|
140
|
+
</form>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Validators are the ones of TanStack Form, so a function or a Standard Schema such as a zod schema both work. A string returned by a validator is shown under the field.
|
|
146
|
+
|
|
147
|
+
## Theming
|
|
148
|
+
|
|
149
|
+
Theme colors, radii and the font are CSS variables with the `--asu-` prefix, for example `--asu-primary`. Override them on `:root` to change the palette. Only a light theme ships. The stylesheet also reads `[data-theme=dark]`, so a dark palette can be supplied by an application that sets those variables on that selector.
|
|
150
|
+
|
|
151
|
+
`className` on a component is passed to its element for your own classes. The library's component rules are not placed in a cascade layer, so styles of yours that are in a layer, such as the utilities of Tailwind CSS, cannot override what a component already sets. Your own rules that are not in a layer compete by specificity and source order as usual, so import the library stylesheet first, as the quick start says, and use a selector that is specific enough.
|
|
152
|
+
|
|
153
|
+
### Using it next to Tailwind CSS
|
|
154
|
+
|
|
155
|
+
Every utility class in the library carries the `asu:` prefix and every variable the `--asu-` prefix, so an application that uses Tailwind itself can load both without clashes.
|
|
156
|
+
|
|
157
|
+
The CSS reset applies only inside library components (`[data-slot]` elements and their descendants), so the rest of the page keeps its own styles.
|